From 623952ad31a13cdb8b4ea486517684eedc9b4a90 Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@c-s.fr>
Date: Wed, 7 Mar 2007 13:27:33 +0000
Subject: [PATCH] Ajout de OSSIM dans l'arborescence.

---
 Utilities/CMakeLists.txt                      |    2 +-
 Utilities/OSSIM/.CMakeLists.txt.swp           |  Bin 0 -> 12288 bytes
 Utilities/OSSIM/CMakeLists.txt                |   16 +
 Utilities/OSSIM/ossimConfig.h.in              |  125 +
 Utilities/OSSIM/ossim_core/.cvsignore         |    2 +
 Utilities/OSSIM/ossim_core/CMakeLists.txt     |   72 +
 .../OSSIM/ossim_core/base/CMakeLists.txt      |    6 +
 .../OSSIM/ossim_core/base/common/.cvsignore   |    3 +
 .../ossim_core/base/common/events/.cvsignore  |    1 +
 .../ossimConnectableDisplayListener.cpp       |  179 +
 .../events/ossimConnectableDisplayListener.h  |  109 +
 .../events/ossimConnectableObjectListener.cpp |  102 +
 .../events/ossimConnectableObjectListener.h   |   75 +
 .../common/events/ossimConnectionEvent.cpp    |  127 +
 .../base/common/events/ossimConnectionEvent.h |   76 +
 .../common/events/ossimContainerEvent.cpp     |   38 +
 .../base/common/events/ossimContainerEvent.h  |   41 +
 .../events/ossimDisplayEventListener.cpp      |   62 +
 .../common/events/ossimDisplayEventListener.h |   43 +
 .../common/events/ossimDisplayListEvent.cpp   |   44 +
 .../common/events/ossimDisplayListEvent.h     |   32 +
 .../events/ossimDisplayRefreshEvent.cpp       |    2 +
 .../common/events/ossimDisplayRefreshEvent.h  |   16 +
 .../events/ossimElevationManagerEvent.cpp     |    3 +
 .../events/ossimElevationManagerEvent.h       |   28 +
 .../ossimElevationManagerEventListener.cpp    |   31 +
 .../ossimElevationManagerEventListener.h      |   18 +
 .../base/common/events/ossimEvent.cpp         |   86 +
 .../base/common/events/ossimEvent.h           |   64 +
 .../base/common/events/ossimEventIds.h        |   86 +
 .../common/events/ossimImageAoiListener.cpp   |   50 +
 .../common/events/ossimImageAoiListener.h     |   43 +
 .../common/events/ossimImageGeometryEvent.cpp |   29 +
 .../common/events/ossimImageGeometryEvent.h   |   82 +
 .../ossimImageGeometryEventListener.cpp       |   45 +
 .../events/ossimImageGeometryEventListener.h  |   43 +
 .../common/events/ossimImagePolygonEvent.h    |   65 +
 .../common/events/ossimImageRectangleEvent.h  |   57 +
 .../base/common/events/ossimListener.cpp      |   51 +
 .../base/common/events/ossimListener.h        |   51 +
 .../common/events/ossimListenerManager.cpp    |  155 +
 .../base/common/events/ossimListenerManager.h |  138 +
 .../base/common/events/ossimMouseEvent.cpp    |   27 +
 .../base/common/events/ossimMouseEvent.h      |   97 +
 .../base/common/events/ossimMouseListener.cpp |   54 +
 .../base/common/events/ossimMouseListener.h   |   44 +
 .../events/ossimObjectDestructingEvent.cpp    |    3 +
 .../events/ossimObjectDestructingEvent.h      |   18 +
 .../base/common/events/ossimObjectEvents.h    |   10 +
 .../common/events/ossimProcessListener.cpp    |   44 +
 .../base/common/events/ossimProcessListener.h |   28 +
 .../events/ossimProcessProgressEvent.cpp      |   68 +
 .../common/events/ossimProcessProgressEvent.h |   51 +
 .../base/common/events/ossimPropertyEvent.h   |   14 +
 .../base/common/events/ossimROIEvent.cpp      |  124 +
 .../base/common/events/ossimROIEvent.h        |   74 +
 .../common/events/ossimROIEventListener.cpp   |   49 +
 .../common/events/ossimROIEventListener.h     |   22 +
 .../base/common/events/ossimRefreshEvent.cpp  |   27 +
 .../base/common/events/ossimRefreshEvent.h    |   48 +
 .../common/events/ossimStateChangedEvent.cpp  |   38 +
 .../common/events/ossimStateChangedEvent.h    |   31 +
 .../base/common/events/ossimViewEvent.cpp     |   27 +
 .../base/common/events/ossimViewEvent.h       |  169 +
 .../base/common/events/ossimViewListener.cpp  |   59 +
 .../base/common/events/ossimViewListener.h    |   51 +
 .../base/common/ossimApplicationUsage.cpp     |  206 +
 .../base/common/ossimApplicationUsage.h       |   85 +
 .../base/common/ossimArgumentParser.cpp       |  468 ++
 .../base/common/ossimArgumentParser.h         |  187 +
 .../ossim_core/base/common/ossimCommon.cpp    |  325 +
 .../ossim_core/base/common/ossimCommon.h      |  282 +
 .../base/common/ossimConnectableContainer.cpp |  772 +++
 .../base/common/ossimConnectableContainer.h   |  184 +
 .../ossimConnectableContainerInterface.cpp    |   27 +
 .../ossimConnectableContainerInterface.h      |  131 +
 .../base/common/ossimConnectableObject.cpp    | 1903 ++++++
 .../base/common/ossimConnectableObject.h      |  470 ++
 .../ossim_core/base/common/ossimConstants.h   |  514 ++
 .../ossim_core/base/common/ossimCplUtil.cpp   |  297 +
 .../ossim_core/base/common/ossimCplUtil.h     |   58 +
 .../base/common/ossimCustomEditorWindow.cpp   |   26 +
 .../base/common/ossimCustomEditorWindow.h     |   71 +
 .../base/common/ossimDataObject.cpp           |  154 +
 .../ossim_core/base/common/ossimDataObject.h  |  126 +
 .../ossim_core/base/common/ossimDate.cpp      |  536 ++
 .../OSSIM/ossim_core/base/common/ossimDate.h  |  241 +
 .../base/common/ossimDisplayInterface.cpp     |   31 +
 .../base/common/ossimDisplayInterface.h       |   40 +
 .../base/common/ossimErrorCodes.cpp           |  318 +
 .../ossim_core/base/common/ossimErrorCodes.h  |  102 +
 .../base/common/ossimErrorStatusInterface.cpp |   79 +
 .../base/common/ossimErrorStatusInterface.h   |   84 +
 .../base/common/ossimFactoryBaseTemplate.cpp  |   34 +
 .../base/common/ossimFactoryBaseTemplate.h    |  128 +
 .../base/common/ossimFontInformation.cpp      |  221 +
 .../base/common/ossimFontInformation.h        |  163 +
 .../ossim_core/base/common/ossimGzStream.cpp  |  280 +
 .../ossim_core/base/common/ossimGzStream.h    |  163 +
 .../base/common/ossimHistogramSource.cpp      |  120 +
 .../base/common/ossimHistogramSource.h        |   58 +
 .../OSSIM/ossim_core/base/common/ossimId.cpp  |    3 +
 .../OSSIM/ossim_core/base/common/ossimId.h    |  109 +
 .../ossim_core/base/common/ossimIdManager.cpp |   64 +
 .../ossim_core/base/common/ossimIdManager.h   |   25 +
 .../ossim_core/base/common/ossimIoStream.cpp  |  169 +
 .../ossim_core/base/common/ossimIoStream.h    |  342 +
 .../base/common/ossimKeywordNames.cpp         |  173 +
 .../base/common/ossimKeywordNames.h           |  181 +
 .../base/common/ossimLeastSquaresBilin.cpp    |  151 +
 .../base/common/ossimLeastSquaresBilin.h      |  146 +
 .../ossim_core/base/common/ossimMutex.cpp     |   54 +
 .../OSSIM/ossim_core/base/common/ossimMutex.h |   77 +
 .../base/common/ossimNBandLutDataObject.cpp   |  342 +
 .../base/common/ossimNBandLutDataObject.h     |  456 ++
 .../ossim_core/base/common/ossimObject.cpp    |  117 +
 .../ossim_core/base/common/ossimObject.h      |   88 +
 .../base/common/ossimOutputSource.cpp         |   15 +
 .../base/common/ossimOutputSource.h           |  107 +
 .../OSSIM/ossim_core/base/common/ossimPool.h  |  151 +
 .../ossim_core/base/common/ossimPoolObject.h  |   49 +
 .../base/common/ossimPreferences.cpp          |  241 +
 .../ossim_core/base/common/ossimPreferences.h |  116 +
 .../base/common/ossimProcessInterface.cpp     |  143 +
 .../base/common/ossimProcessInterface.h       |   88 +
 .../base/common/ossimPropertyInterface.cpp    |   77 +
 .../base/common/ossimPropertyInterface.h      |   40 +
 .../base/common/ossimProtocolStream.h         |   32 +
 .../base/common/ossimQuadrilateralMap.cpp     |   95 +
 .../base/common/ossimQuadrilateralMap.h       |   55 +
 .../common/ossimRectilinearDataObject.cpp     |  312 +
 .../base/common/ossimRectilinearDataObject.h  |  156 +
 .../ossim_core/base/common/ossimRefPtr.h      |   88 +
 .../base/common/ossimReferenced.cpp           |   14 +
 .../ossim_core/base/common/ossimReferenced.h  |   59 +
 .../base/common/ossimRgbLutDataObject.cpp     |  279 +
 .../base/common/ossimRgbLutDataObject.h       |   99 +
 .../ossim_core/base/common/ossimRtti.cpp      |  134 +
 .../OSSIM/ossim_core/base/common/ossimRtti.h  |  509 ++
 .../ossim_core/base/common/ossimScopedLock.h  |   40 +
 .../ossim_core/base/common/ossimSource.cpp    |  167 +
 .../ossim_core/base/common/ossimSource.h      |   83 +
 .../base/common/ossimStdOutProgress.cpp       |   58 +
 .../base/common/ossimStdOutProgress.h         |   33 +
 .../base/common/ossimStreamBase.cpp           |    3 +
 .../ossim_core/base/common/ossimStreamBase.h  |   29 +
 .../ossim_core/base/common/ossimTrace.cpp     |   40 +
 .../OSSIM/ossim_core/base/common/ossimTrace.h |   72 +
 .../base/common/ossimTraceManager.cpp         |  105 +
 .../base/common/ossimTraceManager.h           |   69 +
 .../base/common/ossimViewController.cpp       |  173 +
 .../base/common/ossimViewController.h         |   65 +
 .../base/common/ossimViewInterface.cpp        |   22 +
 .../base/common/ossimViewInterface.h          |   59 +
 .../OSSIM/ossim_core/base/context/.cvsignore  |    2 +
 .../base/context/ossimErrorContext.h          |   31 +
 .../base/context/ossimNotifyContext.cpp       |  403 ++
 .../base/context/ossimNotifyContext.h         |  119 +
 .../ossim_core/base/data_types/.cvsignore     |    1 +
 .../base/data_types/color_space/.cvsignore    |    1 +
 .../data_types/color_space/ossimCmyVector.cpp |   41 +
 .../data_types/color_space/ossimCmyVector.h   |   68 +
 .../data_types/color_space/ossimHsiVector.cpp |   97 +
 .../data_types/color_space/ossimHsiVector.h   |   84 +
 .../data_types/color_space/ossimHsvVector.cpp |  107 +
 .../data_types/color_space/ossimHsvVector.h   |   86 +
 .../color_space/ossimJpegYCbCrVector.cpp      |   37 +
 .../color_space/ossimJpegYCbCrVector.h        |   84 +
 .../color_space/ossimNormRgbVector.cpp        |  183 +
 .../color_space/ossimNormRgbVector.h          |  109 +
 .../data_types/color_space/ossimRgbVector.cpp |  296 +
 .../data_types/color_space/ossimRgbVector.h   |  123 +
 .../base/data_types/datum/.cvsignore          |    1 +
 .../ossim_core/base/data_types/datum/datum.h  |  528 ++
 .../base/data_types/datum/ossimDatum.cpp      |  124 +
 .../base/data_types/datum/ossimDatum.h        |  160 +
 .../data_types/datum/ossimNadconGridDatum.cpp |  128 +
 .../data_types/datum/ossimNadconGridDatum.h   |   44 +
 .../data_types/datum/ossimNadconGridFile.cpp  |  100 +
 .../data_types/datum/ossimNadconGridFile.h    |   54 +
 .../datum/ossimNadconGridHeader.cpp           |   60 +
 .../data_types/datum/ossimNadconGridHeader.h  |   89 +
 .../data_types/datum/ossimNadconNarDatum.cpp  |   66 +
 .../data_types/datum/ossimNadconNarDatum.h    |   21 +
 .../data_types/datum/ossimNadconNasDatum.cpp  |  106 +
 .../data_types/datum/ossimNadconNasDatum.h    |   19 +
 .../data_types/datum/ossimSevenParamDatum.cpp |  172 +
 .../data_types/datum/ossimSevenParamDatum.h   |   91 +
 .../data_types/datum/ossimThreeParamDatum.cpp |  138 +
 .../data_types/datum/ossimThreeParamDatum.h   |   81 +
 .../base/data_types/datum/ossimWgs72Datum.cpp |  223 +
 .../base/data_types/datum/ossimWgs72Datum.h   |   45 +
 .../base/data_types/datum/ossimWgs84Datum.cpp |   79 +
 .../base/data_types/datum/ossimWgs84Datum.h   |   48 +
 .../base/data_types/ellipse/.cvsignore        |    1 +
 .../base/data_types/ellipse/ellips.dat        |   23 +
 .../base/data_types/ellipse/ossimEllipse.c    |  663 ++
 .../base/data_types/ellipse/ossimEllipse.h    |  308 +
 .../base/data_types/ellipse/ossimEllipse.hpp  |   28 +
 .../data_types/ellipse/ossimEllipsoid.cpp     |  453 ++
 .../base/data_types/ellipse/ossimEllipsoid.h  |  159 +
 .../base/data_types/geoid/.cvsignore          |    3 +
 .../base/data_types/geoid/ossimGeoid.cpp      |   42 +
 .../base/data_types/geoid/ossimGeoid.h        |   61 +
 .../base/data_types/geoid/ossimGeoidEgm96.cpp |  328 +
 .../base/data_types/geoid/ossimGeoidEgm96.h   |   78 +
 .../data_types/geoid/ossimGeoidManager.cpp    |  239 +
 .../base/data_types/geoid/ossimGeoidManager.h |  101 +
 .../base/data_types/geoid/ossimGeoidNgs.cpp   |  272 +
 .../base/data_types/geoid/ossimGeoidNgs.h     |   70 +
 .../data_types/geoid/ossimGeoidNgsHeader.cpp  |  173 +
 .../data_types/geoid/ossimGeoidNgsHeader.h    |   97 +
 .../base/data_types/ossimActiveEdgeTable.cpp  |  227 +
 .../base/data_types/ossimActiveEdgeTable.h    |  146 +
 .../ossim_core/base/data_types/ossimAxes.h    |  110 +
 .../base/data_types/ossimColumnVector3d.h     |  258 +
 .../base/data_types/ossimColumnVector4d.h     |  213 +
 .../base/data_types/ossimDblGrid.cpp          | 1127 ++++
 .../ossim_core/base/data_types/ossimDblGrid.h |  214 +
 .../base/data_types/ossimDirectory.cpp        |  275 +
 .../base/data_types/ossimDirectory.h          |   83 +
 .../base/data_types/ossimDirectoryData.cpp    |  168 +
 .../base/data_types/ossimDirectoryData.h      |   57 +
 .../base/data_types/ossimDirectoryTree.cpp    |  169 +
 .../base/data_types/ossimDirectoryTree.h      |   87 +
 .../ossim_core/base/data_types/ossimDms.cpp   |  941 +++
 .../ossim_core/base/data_types/ossimDms.h     |  209 +
 .../ossim_core/base/data_types/ossimDpt.cpp   |  232 +
 .../ossim_core/base/data_types/ossimDpt.h     |  153 +
 .../ossim_core/base/data_types/ossimDpt3d.cpp |   26 +
 .../ossim_core/base/data_types/ossimDpt3d.h   |  113 +
 .../ossim_core/base/data_types/ossimDrect.cpp |  736 +++
 .../ossim_core/base/data_types/ossimDrect.h   |  766 +++
 .../base/data_types/ossimEcefPoint.cpp        |   89 +
 .../base/data_types/ossimEcefPoint.h          |  192 +
 .../base/data_types/ossimEcefRay.cpp          |  108 +
 .../ossim_core/base/data_types/ossimEcefRay.h |  198 +
 .../base/data_types/ossimEcefVector.h         |  300 +
 .../base/data_types/ossimFilename.cpp         |  665 ++
 .../base/data_types/ossimFilename.h           |  179 +
 .../ossim_core/base/data_types/ossimFpt.cpp   |  107 +
 .../ossim_core/base/data_types/ossimFpt.h     |  100 +
 .../ossim_core/base/data_types/ossimFpt3d.cpp |   59 +
 .../ossim_core/base/data_types/ossimFpt3d.h   |   63 +
 .../base/data_types/ossimGeoPolygon.cpp       |  356 ++
 .../base/data_types/ossimGeoPolygon.h         |  170 +
 .../ossim_core/base/data_types/ossimGeocent.c |  384 ++
 .../ossim_core/base/data_types/ossimGeocent.h |  162 +
 .../base/data_types/ossimGeoref.cpp           |  375 ++
 .../ossim_core/base/data_types/ossimGeoref.h  |   70 +
 .../ossim_core/base/data_types/ossimGpt.cpp   |  341 +
 .../ossim_core/base/data_types/ossimGpt.h     |  259 +
 .../ossim_core/base/data_types/ossimGrect.cpp |  234 +
 .../ossim_core/base/data_types/ossimGrect.h   |  329 +
 .../base/data_types/ossimHexString.cpp        |  248 +
 .../base/data_types/ossimHexString.h          |  152 +
 .../base/data_types/ossimHistogram.cpp        | 1378 ++++
 .../base/data_types/ossimHistogram.h          |  206 +
 .../ossim_core/base/data_types/ossimIpt.cpp   |  204 +
 .../ossim_core/base/data_types/ossimIpt.h     |  142 +
 .../ossim_core/base/data_types/ossimIrect.cpp |  451 ++
 .../ossim_core/base/data_types/ossimIrect.h   |  684 ++
 .../base/data_types/ossimKeyword.cpp          |  136 +
 .../ossim_core/base/data_types/ossimKeyword.h |   64 +
 .../base/data_types/ossimKeywordlist.cpp      | 1244 ++++
 .../base/data_types/ossimKeywordlist.h        |  387 ++
 .../ossim_core/base/data_types/ossimLine.cpp  |  176 +
 .../ossim_core/base/data_types/ossimLine.h    |   94 +
 .../base/data_types/ossimLsrPoint.cpp         |  124 +
 .../base/data_types/ossimLsrPoint.h           |  194 +
 .../base/data_types/ossimLsrRay.cpp           |  109 +
 .../ossim_core/base/data_types/ossimLsrRay.h  |  169 +
 .../base/data_types/ossimLsrSpace.cpp         |  236 +
 .../base/data_types/ossimLsrSpace.h           |  147 +
 .../base/data_types/ossimLsrVector.cpp        |  119 +
 .../base/data_types/ossimLsrVector.h          |  303 +
 .../base/data_types/ossimMatrix3x3.cpp        |  289 +
 .../base/data_types/ossimMatrix3x3.h          |   96 +
 .../base/data_types/ossimMatrix4x4.cpp        |  298 +
 .../base/data_types/ossimMatrix4x4.h          |  283 +
 .../data_types/ossimMultiBandHistogram.cpp    |  400 ++
 .../base/data_types/ossimMultiBandHistogram.h |  101 +
 .../ossimMultiResLevelHistogram.cpp           |  500 ++
 .../data_types/ossimMultiResLevelHistogram.h  |  115 +
 .../base/data_types/ossimPolyArea2d.cpp       |  949 +++
 .../base/data_types/ossimPolyArea2d.h         |  196 +
 .../base/data_types/ossimPolyLine.cpp         |  573 ++
 .../base/data_types/ossimPolyLine.h           |  257 +
 .../base/data_types/ossimPolygon.cpp          |  992 +++
 .../ossim_core/base/data_types/ossimPolygon.h |  209 +
 .../base/data_types/ossimRationalNumber.cpp   |  233 +
 .../base/data_types/ossimRationalNumber.h     |  210 +
 .../base/data_types/ossimRegExp.cpp           | 1276 ++++
 .../ossim_core/base/data_types/ossimRegExp.h  |  223 +
 .../base/data_types/ossimString.cpp           |  743 +++
 .../ossim_core/base/data_types/ossimString.h  |  307 +
 .../base/data_types/ossimTempFilename.cpp     |  114 +
 .../base/data_types/ossimTempFilename.h       |   42 +
 .../ossim_core/base/data_types/ossimVrect.cpp |   41 +
 .../ossim_core/base/data_types/ossimVrect.h   |  162 +
 .../base/data_types/ossimXmlAttribute.cpp     |  236 +
 .../base/data_types/ossimXmlAttribute.h       |   52 +
 .../base/data_types/ossimXmlDocument.cpp      |  409 ++
 .../base/data_types/ossimXmlDocument.h        |   74 +
 .../base/data_types/ossimXmlNode.cpp          |  840 +++
 .../ossim_core/base/data_types/ossimXmlNode.h |  103 +
 .../base/data_types/ossimXmlString.cpp        |   72 +
 .../base/data_types/ossimXmlString.h          |   79 +
 .../OSSIM/ossim_core/base/factory/.cvsignore  |    1 +
 .../base/factory/ossimBaseObjectFactory.cpp   |   74 +
 .../base/factory/ossimBaseObjectFactory.h     |   49 +
 .../ossimCustomEditorWindowFactoryBase.cpp    |   25 +
 .../ossimCustomEditorWindowFactoryBase.h      |   52 +
 .../ossimCustomEditorWindowRegistry.cpp       |  168 +
 .../factory/ossimCustomEditorWindowRegistry.h |   78 +
 .../base/factory/ossimDatumFactory.cpp        |  340 +
 .../base/factory/ossimDatumFactory.h          |   67 +
 .../base/factory/ossimDatumFactory.inc        |  299 +
 .../base/factory/ossimEllipsoidFactory.cpp    |  187 +
 .../base/factory/ossimEllipsoidFactory.h      |   58 +
 .../base/factory/ossimObjectFactory.cpp       |    4 +
 .../base/factory/ossimObjectFactory.h         |   58 +
 .../factory/ossimObjectFactoryRegistry.cpp    |  187 +
 .../base/factory/ossimObjectFactoryRegistry.h |   90 +
 .../factory/ossimPropertyInterfaceFactory.cpp |    5 +
 .../factory/ossimPropertyInterfaceFactory.h   |   48 +
 .../ossimPropertyInterfaceRegistry.cpp        |  112 +
 .../factory/ossimPropertyInterfaceRegistry.h  |   62 +
 .../base/factory/ossimStreamFactory.cpp       |   82 +
 .../base/factory/ossimStreamFactory.h         |   35 +
 .../base/factory/ossimStreamFactoryBase.h     |   32 +
 .../factory/ossimStreamFactoryRegistry.cpp    |   71 +
 .../base/factory/ossimStreamFactoryRegistry.h |   38 +
 .../OSSIM/ossim_core/base/misc/.cvsignore     |    1 +
 .../OSSIM/ossim_core/base/misc/FlexLexer.h    |  188 +
 .../ossim_core/base/misc/hash/.cvsignore      |    1 +
 .../base/misc/hash/ossimPointHash.h           |   28 +
 .../base/misc/hash/ossimTileHash.cpp          |  123 +
 .../ossim_core/base/misc/hash/ossimTileHash.h |   46 +
 .../base/misc/hash/ossimTiledImageHash.cpp    |  140 +
 .../base/misc/hash/ossimTiledImageHash.h      |   40 +
 .../base/misc/lookup_tables/.cvsignore        |    1 +
 .../ossimGeoTiffCoordTransformsLut.cpp        |   97 +
 .../ossimGeoTiffCoordTransformsLut.h          |   81 +
 .../lookup_tables/ossimGeoTiffDatumLut.cpp    |  116 +
 .../misc/lookup_tables/ossimGeoTiffDatumLut.h |   74 +
 .../misc/lookup_tables/ossimImageTypeLut.cpp  |   68 +
 .../misc/lookup_tables/ossimImageTypeLut.h    |   47 +
 .../lookup_tables/ossimInterleaveTypeLut.cpp  |   50 +
 .../lookup_tables/ossimInterleaveTypeLut.h    |   45 +
 .../misc/lookup_tables/ossimLookUpTable.cpp   |  147 +
 .../misc/lookup_tables/ossimLookUpTable.h     |  116 +
 .../misc/lookup_tables/ossimScalarTypeLut.cpp |  126 +
 .../misc/lookup_tables/ossimScalarTypeLut.h   |   53 +
 .../misc/lookup_tables/ossimUnitTypeLut.cpp   |   54 +
 .../misc/lookup_tables/ossimUnitTypeLut.h     |   80 +
 .../base/misc/ossim2dLinearRegression.cpp     |   73 +
 .../base/misc/ossim2dLinearRegression.h       |   89 +
 .../base/misc/ossim2dTo2dTransform.cpp        |  242 +
 .../base/misc/ossim2dTo2dTransform.h          |   62 +
 .../misc/ossimAdjustableParameterInfo.cpp     |  126 +
 .../base/misc/ossimAdjustableParameterInfo.h  |   97 +
 .../ossimAdjustableParameterInterface.cpp     |  617 ++
 .../misc/ossimAdjustableParameterInterface.h  |  121 +
 .../base/misc/ossimAdjustmentInfo.cpp         |  188 +
 .../base/misc/ossimAdjustmentInfo.h           |   62 +
 .../ossim_core/base/misc/ossimAdrData.cpp     |  422 ++
 .../OSSIM/ossim_core/base/misc/ossimAdrData.h |   63 +
 .../base/misc/ossimAffineTransform.cpp        |  219 +
 .../base/misc/ossimAffineTransform.h          |  110 +
 .../ossim_core/base/misc/ossimBilSplitter.cpp |  184 +
 .../ossim_core/base/misc/ossimBilSplitter.h   |   74 +
 .../ossim_core/base/misc/ossimEndian.cpp      |  213 +
 .../OSSIM/ossim_core/base/misc/ossimEndian.h  |   77 +
 .../base/misc/ossimEquTokenDefines.h          |   54 +
 .../base/misc/ossimEquTokenizer.cpp           | 1795 ++++++
 .../ossim_core/base/misc/ossimEquTokenizer.h  |    9 +
 .../ossim_core/base/misc/ossimEquTokenizer.l  |  179 +
 .../base/misc/ossimQuadTreeWarp.cpp           | 1426 +++++
 .../ossim_core/base/misc/ossimQuadTreeWarp.h  |  461 ++
 .../base/misc/ossimRectanglePartitioner.cpp   |  248 +
 .../base/misc/ossimRectanglePartitioner.h     |  147 +
 .../base/misc/ossimUnitConversionTool.cpp     |  349 +
 .../base/misc/ossimUnitConversionTool.h       |   93 +
 .../ossim_core/base/misc/ossimUsgsQuad.cpp    |  730 +++
 .../ossim_core/base/misc/ossimUsgsQuad.h      |  118 +
 .../OSSIM/ossim_core/base/property/.cvsignore |    7 +
 .../base/property/ossimBooleanProperty.cpp    |   82 +
 .../base/property/ossimBooleanProperty.h      |   47 +
 .../base/property/ossimColorProperty.cpp      |  128 +
 .../base/property/ossimColorProperty.h        |   54 +
 .../base/property/ossimContainerProperty.cpp  |  172 +
 .../base/property/ossimContainerProperty.h    |   56 +
 .../base/property/ossimDateProperty.cpp       |  142 +
 .../base/property/ossimDateProperty.h         |   29 +
 .../base/property/ossimDoubleGridProperty.cpp |  159 +
 .../base/property/ossimDoubleGridProperty.h   |   79 +
 .../base/property/ossimFilenameProperty.cpp   |  168 +
 .../base/property/ossimFilenameProperty.h     |   75 +
 .../base/property/ossimFontProperty.cpp       |  103 +
 .../base/property/ossimFontProperty.h         |   48 +
 .../base/property/ossimMatrixProperty.cpp     |  331 +
 .../base/property/ossimMatrixProperty.h       |   96 +
 .../base/property/ossimNumericProperty.cpp    |  224 +
 .../base/property/ossimNumericProperty.h      |   78 +
 .../base/property/ossimProperty.cpp           |  168 +
 .../ossim_core/base/property/ossimProperty.h  |   89 +
 .../base/property/ossimStringListProperty.cpp |  272 +
 .../base/property/ossimStringListProperty.h   |   80 +
 .../base/property/ossimStringProperty.cpp     |  127 +
 .../base/property/ossimStringProperty.h       |   73 +
 .../base/property/ossimTextProperty.cpp       |   76 +
 .../base/property/ossimTextProperty.h         |   50 +
 Utilities/OSSIM/ossim_core/dll_main/Makefile  |   10 +
 .../ossim_core/dll_main/ossimDllMain.cpp      |   13 +
 .../OSSIM/ossim_core/dll_main/ossimDllMain.h  |    7 +
 .../OSSIM/ossim_core/elevation/.cvsignore     |    1 +
 .../OSSIM/ossim_core/elevation/CMakeLists.txt |    6 +
 .../ossim_core/elevation/formats/.cvsignore   |    1 +
 .../elevation/formats/dted_cell/.cvsignore    |    1 +
 .../formats/dted_cell/ossimDtedFactory.cpp    |  168 +
 .../formats/dted_cell/ossimDtedFactory.h      |   38 +
 .../formats/dted_cell/ossimDtedHandler.cpp    |  460 ++
 .../formats/dted_cell/ossimDtedHandler.h      |  156 +
 .../formats/ossimElevCellHandler.cpp          |   88 +
 .../elevation/formats/ossimElevCellHandler.h  |  115 +
 .../formats/ossimElevCellHandlerFactory.cpp   |  130 +
 .../formats/ossimElevCellHandlerFactory.h     |   63 +
 .../elevation/formats/srtm/.cvsignore         |    2 +
 .../formats/srtm/ossimSrtmFactory.cpp         |  228 +
 .../elevation/formats/srtm/ossimSrtmFactory.h |   59 +
 .../formats/srtm/ossimSrtmHandler.cpp         |  364 ++
 .../elevation/formats/srtm/ossimSrtmHandler.h |  100 +
 .../ossim_core/elevation/ossimElevLess.h      |   45 +
 .../ossim_core/elevation/ossimElevManager.cpp | 1538 +++++
 .../ossim_core/elevation/ossimElevManager.h   |  331 +
 .../ossim_core/elevation/ossimElevSource.cpp  |  265 +
 .../ossim_core/elevation/ossimElevSource.h    |  184 +
 .../elevation/ossimElevSourceFactory.cpp      |   43 +
 .../elevation/ossimElevSourceFactory.h        |   76 +
 .../elevation/ossimElevationShapeIdx.cpp      |  274 +
 .../elevation/ossimElevationShapeIdx.h        |   41 +
 Utilities/OSSIM/ossim_core/fonts/.cvsignore   |    1 +
 .../OSSIM/ossim_core/fonts/CMakeLists.txt     |    6 +
 .../OSSIM/ossim_core/fonts/factory/.cvsignore |    1 +
 .../fonts/factory/ossimFontFactoryBase.h      |   41 +
 .../factory/ossimFontFactoryRegistry.cpp      |  191 +
 .../fonts/factory/ossimFontFactoryRegistry.h  |   82 +
 .../factory/ossimFreeTypeFontFactory.cpp      |  237 +
 .../fonts/factory/ossimFreeTypeFontFactory.h  |   64 +
 .../OSSIM/ossim_core/fonts/ossimFont.cpp      |   83 +
 Utilities/OSSIM/ossim_core/fonts/ossimFont.h  |  336 +
 .../ossim_core/fonts/ossimFreeTypeFont.cpp    |  646 ++
 .../ossim_core/fonts/ossimFreeTypeFont.h      |  199 +
 .../ossim_core/fonts/ossimGdBitmapFont.cpp    |  263 +
 .../ossim_core/fonts/ossimGdBitmapFont.h      |  101 +
 .../ossim_core/fonts/ossimGdSansBold.inc      | 4383 +++++++++++++
 Utilities/OSSIM/ossim_core/imaging/.cvsignore |    1 +
 .../OSSIM/ossim_core/imaging/CMakeLists.txt   |    6 +
 .../ossim_core/imaging/annotation/.cvsignore  |    1 +
 .../ossim_core/imaging/annotation/gdfontg.inc | 4384 +++++++++++++
 .../ossim_core/imaging/annotation/gdfontl.inc | 4641 ++++++++++++++
 .../imaging/annotation/gdfontmb.inc           | 3870 +++++++++++
 .../ossim_core/imaging/annotation/gdfonts.inc | 3871 +++++++++++
 .../ossim_core/imaging/annotation/gdfontt.inc | 2589 ++++++++
 .../ossimAnnotationEllipseObject.cpp          |  180 +
 .../annotation/ossimAnnotationEllipseObject.h |   75 +
 .../annotation/ossimAnnotationFontObject.cpp  |  397 ++
 .../annotation/ossimAnnotationFontObject.h    |   85 +
 .../ossimAnnotationGdBitmapFont.cpp           |  195 +
 .../annotation/ossimAnnotationGdBitmapFont.h  |  137 +
 .../annotation/ossimAnnotationLineObject.cpp  |  183 +
 .../annotation/ossimAnnotationLineObject.h    |   76 +
 .../annotation/ossimAnnotationMapGridSource.h |   14 +
 .../ossimAnnotationMultiEllipseObject.cpp     |  237 +
 .../ossimAnnotationMultiEllipseObject.h       |   80 +
 .../ossimAnnotationMultiLineObject.cpp        |  191 +
 .../ossimAnnotationMultiLineObject.h          |  102 +
 .../ossimAnnotationMultiPolyLineObject.cpp    |  268 +
 .../ossimAnnotationMultiPolyLineObject.h      |   70 +
 .../ossimAnnotationMultiPolyObject.cpp        |  322 +
 .../ossimAnnotationMultiPolyObject.h          |   97 +
 .../annotation/ossimAnnotationObject.cpp      |  161 +
 .../annotation/ossimAnnotationObject.h        |  105 +
 .../annotation/ossimAnnotationPolyObject.cpp  |  283 +
 .../annotation/ossimAnnotationPolyObject.h    |   80 +
 .../annotation/ossimAnnotationSource.cpp      |  457 ++
 .../annotation/ossimAnnotationSource.h        |  140 +
 .../annotation/ossimEsriShapeFileFilter.cpp   |  813 +++
 .../annotation/ossimEsriShapeFileFilter.h     |  270 +
 .../imaging/annotation/ossimGdFont.h          |   54 +
 .../imaging/annotation/ossimGdFontExterns.h   |   33 +
 .../annotation/ossimGeoAnnotationBitmap.cpp   |  168 +
 .../annotation/ossimGeoAnnotationBitmap.h     |   71 +
 .../ossimGeoAnnotationEllipseObject.cpp       |  307 +
 .../ossimGeoAnnotationEllipseObject.h         |   86 +
 .../ossimGeoAnnotationFontObject.cpp          |  290 +
 .../annotation/ossimGeoAnnotationFontObject.h |  128 +
 .../ossimGeoAnnotationGdBitmapFont.cpp        |  139 +
 .../ossimGeoAnnotationGdBitmapFont.h          |   74 +
 .../ossimGeoAnnotationLineObject.cpp          |  141 +
 .../annotation/ossimGeoAnnotationLineObject.h |   65 +
 .../ossimGeoAnnotationMultiEllipseObject.cpp  |  186 +
 .../ossimGeoAnnotationMultiEllipseObject.h    |   83 +
 .../ossimGeoAnnotationMultiPolyLineObject.cpp |  354 ++
 .../ossimGeoAnnotationMultiPolyLineObject.h   |   90 +
 .../ossimGeoAnnotationMultiPolyObject.cpp     |  199 +
 .../ossimGeoAnnotationMultiPolyObject.h       |  118 +
 .../annotation/ossimGeoAnnotationObject.cpp   |   46 +
 .../annotation/ossimGeoAnnotationObject.h     |   51 +
 .../ossimGeoAnnotationPolyLineObject.cpp      |  178 +
 .../ossimGeoAnnotationPolyLineObject.h        |   69 +
 .../ossimGeoAnnotationPolyObject.cpp          |  302 +
 .../annotation/ossimGeoAnnotationPolyObject.h |   88 +
 .../annotation/ossimGeoAnnotationSource.cpp   |  207 +
 .../annotation/ossimGeoAnnotationSource.h     |   75 +
 .../ossimGeographicAnnotationGrid.cpp         |  283 +
 .../ossimGeographicAnnotationGrid.h           |   52 +
 .../annotation/ossimMapCompositionSource.cpp  | 4032 ++++++++++++
 .../annotation/ossimMapCompositionSource.h    |  339 +
 .../imaging/atmospheric_correction/.cvsignore |    5 +
 .../atmospheric_correction/ossimAOD.cpp       |  238 +
 .../imaging/atmospheric_correction/ossimAOD.h |   66 +
 .../ossimAtCorrGridRemapper.cpp               |  351 +
 .../ossimAtCorrGridRemapper.h                 |  154 +
 .../ossimAtCorrKeywords.h                     |   35 +
 .../ossimAtCorrRemapper.cpp                   |  729 +++
 .../ossimAtCorrRemapper.h                     |   88 +
 .../ossimGammaRemapper.cpp                    |  433 ++
 .../ossimGammaRemapper.h                      |   71 +
 .../OSSIM/ossim_core/imaging/cache/.cvsignore |    1 +
 .../imaging/cache/ossimAppFixedTileCache.cpp  |  383 ++
 .../imaging/cache/ossimAppFixedTileCache.h    |  118 +
 .../imaging/cache/ossimAppTileCache.cpp       |  307 +
 .../imaging/cache/ossimAppTileCache.h         |  169 +
 .../imaging/cache/ossimFixedTileCache.cpp     |  282 +
 .../imaging/cache/ossimFixedTileCache.h       |  143 +
 .../imaging/cache/ossimTileCache.cpp          |  189 +
 .../ossim_core/imaging/cache/ossimTileCache.h |  114 +
 .../ossim_core/imaging/elevation/.cvsignore   |    2 +
 .../elevation/ossimElevImageSource.cpp        |  821 +++
 .../imaging/elevation/ossimElevImageSource.h  |  146 +
 .../ossim_core/imaging/factory/.cvsignore     |    2 +
 .../factory/ossimAnnotationObjectFactory.cpp  |  102 +
 .../factory/ossimAnnotationObjectFactory.h    |   57 +
 .../imaging/factory/ossimImageDataFactory.cpp |  254 +
 .../imaging/factory/ossimImageDataFactory.h   |   62 +
 .../factory/ossimImageHandlerFactory.cpp      |  633 ++
 .../factory/ossimImageHandlerFactory.h        |   76 +
 .../factory/ossimImageHandlerFactoryBase.cpp  |   25 +
 .../factory/ossimImageHandlerFactoryBase.h    |   44 +
 .../factory/ossimImageHandlerRegistry.cpp     |  193 +
 .../factory/ossimImageHandlerRegistry.h       |   98 +
 .../ossimImageMetaDataWriterFactory.cpp       |  206 +
 .../factory/ossimImageMetaDataWriterFactory.h |   87 +
 .../ossimImageMetaDataWriterFactoryBase.cpp   |   28 +
 .../ossimImageMetaDataWriterFactoryBase.h     |   67 +
 .../ossimImageMetaDataWriterRegistry.cpp      |  176 +
 .../ossimImageMetaDataWriterRegistry.h        |   98 +
 .../ossimImageReconstructionFilterFactory.cpp |   86 +
 .../ossimImageReconstructionFilterFactory.h   |   47 +
 ...ossimImageReconstructionFilterRegistry.cpp |  126 +
 .../ossimImageReconstructionFilterRegistry.h  |   51 +
 .../factory/ossimImageSourceFactory.cpp       |  551 ++
 .../imaging/factory/ossimImageSourceFactory.h |   46 +
 .../factory/ossimImageSourceFactoryBase.cpp   |   74 +
 .../factory/ossimImageSourceFactoryBase.h     |   46 +
 .../ossimImageSourceFactoryRegistry.cpp       |  144 +
 .../factory/ossimImageSourceFactoryRegistry.h |   55 +
 .../factory/ossimImageWriterFactory.cpp       |  226 +
 .../imaging/factory/ossimImageWriterFactory.h |   59 +
 .../factory/ossimImageWriterFactoryBase.cpp   |   26 +
 .../factory/ossimImageWriterFactoryBase.h     |   55 +
 .../ossimImageWriterFactoryRegistry.cpp       |  220 +
 .../factory/ossimImageWriterFactoryRegistry.h |   73 +
 .../ossim_core/imaging/filters/.cvsignore     |    1 +
 .../filters/ossimDiscrete3x3HatFilter.cpp     |  289 +
 .../filters/ossimDiscrete3x3HatFilter.h       |   64 +
 .../ossimDiscreteConvolutionKernel.cpp        |  557 ++
 .../filters/ossimDiscreteConvolutionKernel.h  |  151 +
 .../filters/ossimDiscreteNearestNeighbor.h    |  123 +
 .../imaging/filters/ossimFilter.cpp           |  333 +
 .../ossim_core/imaging/filters/ossimFilter.h  |  486 ++
 .../imaging/filters/ossimFilterTable.cpp      |  149 +
 .../imaging/filters/ossimFilterTable.h        |   97 +
 .../ossim_core/imaging/formats/.cvsignore     |    1 +
 .../imaging/formats/adrg/.cvsignore           |    1 +
 .../imaging/formats/adrg/ossimAdrgHeader.cpp  |  499 ++
 .../imaging/formats/adrg/ossimAdrgHeader.h    |  130 +
 .../formats/adrg/ossimAdrgTileSource.cpp      |  782 +++
 .../formats/adrg/ossimAdrgTileSource.h        |  175 +
 .../imaging/formats/adrg/ossimDdffield.cpp    |  336 +
 .../formats/adrg/ossimDdffielddefn.cpp        |  865 +++
 .../imaging/formats/adrg/ossimDdfmodule.cpp   |  709 +++
 .../imaging/formats/adrg/ossimDdfrecord.cpp   | 1850 ++++++
 .../formats/adrg/ossimDdfsubfielddefn.cpp     |  950 +++
 .../imaging/formats/adrg/ossimDdfutils.cpp    |  101 +
 .../imaging/formats/adrg/ossimIso8211.h       |  527 ++
 .../imaging/formats/aigrid/.cvsignore         |    1 +
 .../formats/aigrid/ossimArcInfoGridWriter.cpp |  367 ++
 .../formats/aigrid/ossimArcInfoGridWriter.h   |   59 +
 .../ossim_core/imaging/formats/ccf/.cvsignore |    1 +
 .../imaging/formats/ccf/ossimCcfHead.cpp      |  767 +++
 .../imaging/formats/ccf/ossimCcfHead.h        |  202 +
 .../formats/ccf/ossimCcfTileSource.cpp        |  847 +++
 .../imaging/formats/ccf/ossimCcfTileSource.h  |  202 +
 .../imaging/formats/cibcadrg/.cvsignore       |    1 +
 .../cibcadrg/ossimCibCadrgTileSource.cpp      | 1423 +++++
 .../cibcadrg/ossimCibCadrgTileSource.h        |  574 ++
 .../imaging/formats/doqq/.cvsignore           |    1 +
 .../formats/doqq/ossimDoqqTileSource.cpp      |  222 +
 .../formats/doqq/ossimDoqqTileSource.h        |   43 +
 .../imaging/formats/dted/.cvsignore           |    1 +
 .../dted/ossimDtedElevationImageSource.cpp    |  719 +++
 .../dted/ossimDtedElevationImageSource.h      |  226 +
 .../formats/dted/ossimDtedTileSource.cpp      |  739 +++
 .../formats/dted/ossimDtedTileSource.h        |  209 +
 .../formats/ers/ossimERSTileSource.cpp        |  199 +
 .../imaging/formats/ers/ossimERSTileSource.h  |   59 +
 .../imaging/formats/general_raster/.cvsignore |    1 +
 .../general_raster/ossimGeneralRasterInfo.cpp |  611 ++
 .../general_raster/ossimGeneralRasterInfo.h   |  367 ++
 .../ossimGeneralRasterTileSource.cpp          | 1192 ++++
 .../ossimGeneralRasterTileSource.h            |  168 +
 .../ossimGeneralRasterWriter.cpp              |  829 +++
 .../general_raster/ossimGeneralRasterWriter.h |  120 +
 .../imaging/formats/jpeg/.cvsignore           |    1 +
 .../formats/jpeg/ossimJpegTileSource.cpp      |  606 ++
 .../formats/jpeg/ossimJpegTileSource.h        |  198 +
 .../imaging/formats/jpeg/ossimJpegWriter.cpp  |  469 ++
 .../imaging/formats/jpeg/ossimJpegWriter.h    |  110 +
 .../imaging/formats/landsat/.cvsignore        |    1 +
 .../landsat/ossimLandsatTileSource.cpp        |  450 ++
 .../formats/landsat/ossimLandsatTileSource.h  |   83 +
 .../imaging/formats/nitf/.cvsignore           |    2 +
 .../formats/nitf/ossimNitfTileSource.cpp      | 2175 +++++++
 .../formats/nitf/ossimNitfTileSource.h        |  416 ++
 .../imaging/formats/nitf/ossimNitfWriter.cpp  | 1045 +++
 .../imaging/formats/nitf/ossimNitfWriter.h    |  166 +
 .../nitf/ossimQuickbirdNitfTileSource.cpp     |  187 +
 .../nitf/ossimQuickbirdNitfTileSource.h       |   27 +
 .../imaging/formats/ossimImageFileWriter.cpp  | 1123 ++++
 .../imaging/formats/ossimImageFileWriter.h    |  319 +
 .../imaging/formats/ossimImageHandler.cpp     | 1228 ++++
 .../imaging/formats/ossimImageHandler.h       |  564 ++
 .../formats/srtm/ossimSrtmTileSource.cpp      |  145 +
 .../formats/srtm/ossimSrtmTileSource.h        |   72 +
 .../imaging/formats/tiff/.cvsignore           |    1 +
 .../tiff/ossimQuickbirdTiffTileSource.cpp     |   88 +
 .../tiff/ossimQuickbirdTiffTileSource.h       |   33 +
 .../formats/tiff/ossimTiffOverviewBuilder.cpp | 1580 +++++
 .../formats/tiff/ossimTiffOverviewBuilder.h   |  208 +
 .../formats/tiff/ossimTiffTileSource.cpp      | 1825 ++++++
 .../formats/tiff/ossimTiffTileSource.h        |  268 +
 .../imaging/formats/tiff/ossimTiffWriter.cpp  | 2316 +++++++
 .../imaging/formats/tiff/ossimTiffWriter.h    |  257 +
 .../imaging/formats/usgs_dem/.cvsignore       |    1 +
 .../usgs_dem/ossimUsgsDemTileSource.cpp       |  648 ++
 .../formats/usgs_dem/ossimUsgsDemTileSource.h |  173 +
 .../ossim_core/imaging/formats/vpf/.cvsignore |    3 +
 .../vpf/ossimVpfAnnotationCoverageInfo.cpp    |  217 +
 .../vpf/ossimVpfAnnotationCoverageInfo.h      |   77 +
 .../vpf/ossimVpfAnnotationFeatureInfo.cpp     | 1451 +++++
 .../vpf/ossimVpfAnnotationFeatureInfo.h       |  218 +
 .../vpf/ossimVpfAnnotationLibraryInfo.cpp     |  260 +
 .../vpf/ossimVpfAnnotationLibraryInfo.h       |   52 +
 .../formats/vpf/ossimVpfAnnotationSource.cpp  |  267 +
 .../formats/vpf/ossimVpfAnnotationSource.h    |   45 +
 .../formats/vpf/ossimVpfTileSource.cpp        |  217 +
 .../imaging/formats/vpf/ossimVpfTileSource.h  |  168 +
 .../ossim_core/imaging/histogram/.cvsignore   |    1 +
 .../histogram/ossimHistogramWriter.cpp        |  154 +
 .../imaging/histogram/ossimHistogramWriter.h  |  178 +
 .../histogram/ossimImageHistogramSource.cpp   |  373 ++
 .../histogram/ossimImageHistogramSource.h     |  101 +
 .../ossim_core/imaging/metadata/.cvsignore    |    3 +
 .../metadata/ossimEnviHeaderFileWriter.cpp    |  107 +
 .../metadata/ossimEnviHeaderFileWriter.h      |   77 +
 .../imaging/metadata/ossimFgdcFileWriter.cpp  |  972 +++
 .../imaging/metadata/ossimFgdcFileWriter.h    |  157 +
 .../imaging/metadata/ossimGeomFileWriter.cpp  |   96 +
 .../imaging/metadata/ossimGeomFileWriter.h    |   57 +
 .../metadata/ossimJpegWorldFileWriter.cpp     |  119 +
 .../metadata/ossimJpegWorldFileWriter.h       |   57 +
 .../metadata/ossimMetadataFileWriter.cpp      |  240 +
 .../metadata/ossimMetadataFileWriter.h        |  149 +
 .../metadata/ossimReadmeFileWriter.cpp        |  476 ++
 .../imaging/metadata/ossimReadmeFileWriter.h  |   57 +
 .../metadata/ossimTiffWorldFileWriter.cpp     |  121 +
 .../metadata/ossimTiffWorldFileWriter.h       |   56 +
 .../OSSIM/ossim_core/imaging/misc/.cvsignore  |    1 +
 .../imaging/misc/ossimPixelFlipper.cpp        | 1216 ++++
 .../imaging/misc/ossimPixelFlipper.h          |  246 +
 .../imaging/misc/ossimVertexExtractor.cpp     | 1962 ++++++
 .../imaging/misc/ossimVertexExtractor.h       |  173 +
 .../ossim_core/imaging/ossimIgenGenerator.cpp |  703 ++
 .../ossim_core/imaging/ossimIgenGenerator.h   |  319 +
 .../ossim_core/imaging/ossimImageChain.cpp    | 1809 ++++++
 .../ossim_core/imaging/ossimImageChain.h      |  358 ++
 .../ossim_core/imaging/ossimImageData.cpp     | 5662 +++++++++++++++++
 .../OSSIM/ossim_core/imaging/ossimImageData.h |  930 +++
 .../imaging/ossimImageDataHelper.cpp          |  604 ++
 .../ossim_core/imaging/ossimImageDataHelper.h |  115 +
 .../imaging/ossimImageDisplayWriter.cpp       |   52 +
 .../imaging/ossimImageDisplayWriter.h         |   90 +
 .../ossim_core/imaging/ossimImageMetaData.cpp |  476 ++
 .../ossim_core/imaging/ossimImageMetaData.h   |  102 +
 .../imaging/ossimImageShapeFileIndex.cpp      |  197 +
 .../imaging/ossimImageShapeFileIndex.h        |   61 +
 .../ossim_core/imaging/ossimImageSource.cpp   |  336 +
 .../ossim_core/imaging/ossimImageSource.h     |  202 +
 .../imaging/ossimImageSourceInterface.cpp     |   18 +
 .../imaging/ossimImageSourceInterface.h       |  109 +
 .../imaging/ossimImageSourceSequencer.cpp     |  424 ++
 .../imaging/ossimImageSourceSequencer.h       |  160 +
 .../imaging/ossimImageStatisticsSource.cpp    |  180 +
 .../imaging/ossimImageStatisticsSource.h      |   32 +
 .../ossim_core/imaging/ossimImageWriter.cpp   |   81 +
 .../ossim_core/imaging/ossimImageWriter.h     |   71 +
 .../ossim_core/imaging/ossimRgbImage.cpp      | 1910 ++++++
 .../OSSIM/ossim_core/imaging/ossimRgbImage.h  |  370 ++
 .../ossim_core/imaging/ossimS16ImageData.cpp  |  716 +++
 .../ossim_core/imaging/ossimS16ImageData.h    |  195 +
 .../OSSIM/ossim_core/imaging/ossimTiling.cpp  |  854 +++
 .../OSSIM/ossim_core/imaging/ossimTiling.h    |  161 +
 .../ossim_core/imaging/ossimU11ImageData.cpp  |  724 +++
 .../ossim_core/imaging/ossimU11ImageData.h    |  204 +
 .../ossim_core/imaging/ossimU16ImageData.cpp  |  695 ++
 .../ossim_core/imaging/ossimU16ImageData.h    |  208 +
 .../ossim_core/imaging/ossimU8ImageData.cpp   |  738 +++
 .../ossim_core/imaging/ossimU8ImageData.h     |  189 +
 .../OSSIM/ossim_core/imaging/patch/.cvsignore |    1 +
 .../imaging/patch/ossimTilePatch.cpp          |  518 ++
 .../ossim_core/imaging/patch/ossimTilePatch.h |  135 +
 .../reconstruction/ossimMeanMedianFilter.cpp  |  929 +++
 .../reconstruction/ossimMeanMedianFilter.h    |  129 +
 .../imaging/remap_tables/.cvsignore           |    1 +
 .../ossimNormalizedRemapTable.cpp             |   29 +
 .../remap_tables/ossimNormalizedRemapTable.h  |   68 +
 .../ossimNormalizedU11RemapTable.cpp          |   45 +
 .../ossimNormalizedU11RemapTable.h            |  102 +
 .../ossimNormalizedU16RemapTable.cpp          |   45 +
 .../ossimNormalizedU16RemapTable.h            |  101 +
 .../ossimNormalizedU8RemapTable.cpp           |   45 +
 .../ossimNormalizedU8RemapTable.h             |  104 +
 .../ossim_core/imaging/resample/.cvsignore    |    1 +
 .../imaging/resample/ossimFilterResampler.cpp |  921 +++
 .../imaging/resample/ossimFilterResampler.h   |  151 +
 .../imaging/resample/ossimResampler.cpp       | 1259 ++++
 .../imaging/resample/ossimResampler.h         |  240 +
 .../imaging/tile_sources/.cvsignore           |    1 +
 .../ossim3x3ConvolutionFilter.cpp             |  632 ++
 .../tile_sources/ossim3x3ConvolutionFilter.h  |   97 +
 .../tile_sources/ossimBandAverageFilter.cpp   |  394 ++
 .../tile_sources/ossimBandAverageFilter.h     |  109 +
 .../tile_sources/ossimBandClipFilter.cpp      |  697 ++
 .../tile_sources/ossimBandClipFilter.h        |   92 +
 .../tile_sources/ossimBandMergeSource.cpp     |  274 +
 .../tile_sources/ossimBandMergeSource.h       |   62 +
 .../tile_sources/ossimBandSelector.cpp        |  428 ++
 .../imaging/tile_sources/ossimBandSelector.h  |  119 +
 .../imaging/tile_sources/ossimBlendMosaic.cpp |  624 ++
 .../imaging/tile_sources/ossimBlendMosaic.h   |   78 +
 .../ossimBrightnessContrastSource.cpp         |  314 +
 .../ossimBrightnessContrastSource.h           |  132 +
 .../tile_sources/ossimBrightnessMatch.cpp     |  247 +
 .../tile_sources/ossimBrightnessMatch.h       |   56 +
 .../tile_sources/ossimBumpShadeTileSource.cpp |  507 ++
 .../tile_sources/ossimBumpShadeTileSource.h   |  271 +
 .../tile_sources/ossimCacheTileSource.cpp     |  357 ++
 .../tile_sources/ossimCacheTileSource.h       |   75 +
 .../ossimCastTileSourceFilter.cpp             |  688 ++
 .../tile_sources/ossimCastTileSourceFilter.h  |   93 +
 .../ossimClosestToCenterCombiner.cpp          |  141 +
 .../ossimClosestToCenterCombiner.h            |   60 +
 .../ossimColorNormalizedFusion.cpp            |  144 +
 .../tile_sources/ossimColorNormalizedFusion.h |   32 +
 .../tile_sources/ossimConvolutionFilter1D.cpp |  638 ++
 .../tile_sources/ossimConvolutionFilter1D.h   |  102 +
 .../tile_sources/ossimConvolutionSource.cpp   |  525 ++
 .../tile_sources/ossimConvolutionSource.h     |   72 +
 .../ossimEastingNorthingCutter.cpp            |  209 +
 .../tile_sources/ossimEastingNorthingCutter.h |   45 +
 .../imaging/tile_sources/ossimEdgeFilter.cpp  |  545 ++
 .../imaging/tile_sources/ossimEdgeFilter.h    |   77 +
 .../tile_sources/ossimEquationCombiner.cpp    | 3555 +++++++++++
 .../tile_sources/ossimEquationCombiner.h      |  311 +
 .../tile_sources/ossimEsriShapeFileCutter.cpp |  323 +
 .../tile_sources/ossimEsriShapeFileCutter.h   |  200 +
 .../tile_sources/ossimFeatherMosaic.cpp       |  474 ++
 .../imaging/tile_sources/ossimFeatherMosaic.h |   87 +
 .../imaging/tile_sources/ossimFftFilter.cpp   |  472 ++
 .../imaging/tile_sources/ossimFftFilter.h     |   86 +
 .../tile_sources/ossimFusionCombiner.cpp      |  191 +
 .../tile_sources/ossimFusionCombiner.h        |   47 +
 .../tile_sources/ossimGeoPolyCutter.cpp       |  353 +
 .../imaging/tile_sources/ossimGeoPolyCutter.h |  251 +
 .../tile_sources/ossimHistoMatchRemapper.cpp  |  349 +
 .../tile_sources/ossimHistoMatchRemapper.h    |   95 +
 .../ossimHistogramEqualization.cpp            |  537 ++
 .../tile_sources/ossimHistogramEqualization.h |   99 +
 .../ossimHistogramMatchFilter.cpp             |  248 +
 .../tile_sources/ossimHistogramMatchFilter.h  |  173 +
 .../tile_sources/ossimHistogramRemapper.cpp   | 1694 +++++
 .../tile_sources/ossimHistogramRemapper.h     |  529 ++
 .../ossimHistogramThreshholdFilter.cpp        |  259 +
 .../ossimHistogramThreshholdFilter.h          |   51 +
 .../imaging/tile_sources/ossimHsiRemapper.cpp | 2751 ++++++++
 .../imaging/tile_sources/ossimHsiRemapper.h   |  251 +
 .../tile_sources/ossimHsiToRgbSource.cpp      |  147 +
 .../tile_sources/ossimHsiToRgbSource.h        |   49 +
 .../tile_sources/ossimHsvToRgbSource.cpp      |  159 +
 .../tile_sources/ossimHsvToRgbSource.h        |   42 +
 .../tile_sources/ossimImageCombiner.cpp       |  689 ++
 .../imaging/tile_sources/ossimImageCombiner.h |  132 +
 .../tile_sources/ossimImageGaussianFilter.cpp |  198 +
 .../tile_sources/ossimImageGaussianFilter.h   |   54 +
 .../imaging/tile_sources/ossimImageMosaic.cpp |  532 ++
 .../imaging/tile_sources/ossimImageMosaic.h   |   73 +
 .../tile_sources/ossimImageRenderer.cpp       | 1866 ++++++
 .../imaging/tile_sources/ossimImageRenderer.h |  402 ++
 .../tile_sources/ossimImageSharpenFilter.cpp  |  368 ++
 .../tile_sources/ossimImageSharpenFilter.h    |   60 +
 .../tile_sources/ossimImageSourceFilter.cpp   |  340 +
 .../tile_sources/ossimImageSourceFilter.h     |  115 +
 .../ossimImageSourceHistogramFilter.cpp       |  238 +
 .../ossimImageSourceHistogramFilter.h         |   65 +
 .../ossimImageToPlaneNormalFilter.cpp         |  432 ++
 .../ossimImageToPlaneNormalFilter.h           |   67 +
 .../tile_sources/ossimIndexToRgbLutFilter.cpp |  626 ++
 .../tile_sources/ossimIndexToRgbLutFilter.h   |  205 +
 .../ossimIntensityAdjustmentFilter.cpp        |  287 +
 .../ossimIntensityAdjustmentFilter.h          |   74 +
 .../ossimJpegYCbCrToRgbSource.cpp             |  114 +
 .../tile_sources/ossimJpegYCbCrToRgbSource.h  |   37 +
 .../ossimLandsatTopoCorrectionFilter.cpp      |  361 ++
 .../ossimLandsatTopoCorrectionFilter.h        |   54 +
 .../ossimLocalCorrelationFusion.cpp           |  432 ++
 .../ossimLocalCorrelationFusion.h             |   88 +
 .../imaging/tile_sources/ossimMaskFilter.cpp  |  798 +++
 .../imaging/tile_sources/ossimMaskFilter.h    |  234 +
 .../imaging/tile_sources/ossimMaxMosaic.cpp   |  547 ++
 .../imaging/tile_sources/ossimMaxMosaic.h     |   79 +
 .../ossimMultiBandHistogramTileSource.cpp     |  371 ++
 .../ossimMultiBandHistogramTileSource.h       |  103 +
 .../tile_sources/ossimNBandToIndexFilter.cpp  |  551 ++
 .../tile_sources/ossimNBandToIndexFilter.h    |  129 +
 .../tile_sources/ossimOrthoImageMosaic.cpp    |  416 ++
 .../tile_sources/ossimOrthoImageMosaic.h      |   65 +
 .../imaging/tile_sources/ossimPolyCutter.cpp  |  373 ++
 .../imaging/tile_sources/ossimPolyCutter.h    |   96 +
 .../tile_sources/ossimRLevelFilter.cpp        |  265 +
 .../imaging/tile_sources/ossimRLevelFilter.h  |   84 +
 .../tile_sources/ossimRectangleCutFilter.cpp  |  295 +
 .../tile_sources/ossimRectangleCutFilter.h    |   57 +
 .../tile_sources/ossimRgbToGreyFilter.cpp     |  249 +
 .../tile_sources/ossimRgbToGreyFilter.h       |   70 +
 .../tile_sources/ossimRgbToHsiSource.cpp      |  162 +
 .../tile_sources/ossimRgbToHsiSource.h        |   47 +
 .../tile_sources/ossimRgbToHsvSource.cpp      |  155 +
 .../tile_sources/ossimRgbToHsvSource.h        |   47 +
 .../tile_sources/ossimRgbToIndexFilter.cpp    |  227 +
 .../tile_sources/ossimRgbToIndexFilter.h      |   96 +
 .../ossimRgbToJpegYCbCrSource.cpp             |   93 +
 .../tile_sources/ossimRgbToJpegYCbCrSource.h  |   32 +
 .../imaging/tile_sources/ossimSFIMFusion.cpp  |  285 +
 .../imaging/tile_sources/ossimSFIMFusion.h    |   76 +
 .../tile_sources/ossimScalarRemapper.cpp      |  554 ++
 .../tile_sources/ossimScalarRemapper.h        |  108 +
 .../imaging/tile_sources/ossimScaleFilter.cpp |  908 +++
 .../imaging/tile_sources/ossimScaleFilter.h   |  179 +
 .../tile_sources/ossimSubImageTileSource.cpp  |  224 +
 .../tile_sources/ossimSubImageTileSource.h    |   89 +
 .../tile_sources/ossimTableRemapper.cpp       |  610 ++
 .../imaging/tile_sources/ossimTableRemapper.h |  154 +
 .../ossimTopographicCorrectionFilter.cpp      | 1297 ++++
 .../ossimTopographicCorrectionFilter.h        |  225 +
 .../imaging/tile_sources/ossimTrimFilter.cpp  |  352 +
 .../imaging/tile_sources/ossimTrimFilter.h    |   70 +
 .../ossimValueAssignImageSourceFilter.cpp     |  377 ++
 .../ossimValueAssignImageSourceFilter.h       |  102 +
 .../tile_sources/ossimVectorRenderer.cpp      |  148 +
 .../tile_sources/ossimVectorRenderer.h        |  133 +
 .../tile_sources/ossimWatermarkFilter.cpp     | 1167 ++++
 .../tile_sources/ossimWatermarkFilter.h       |  351 +
 .../imaging/tonal_balance/.cvsignore          |    1 +
 .../tonal_balance/ossimAtbController.cpp      |  594 ++
 .../tonal_balance/ossimAtbController.h        |  162 +
 .../tonal_balance/ossimAtbMatchPoint.cpp      |  169 +
 .../tonal_balance/ossimAtbMatchPoint.h        |  104 +
 .../tonal_balance/ossimAtbPointSource.cpp     |  206 +
 .../tonal_balance/ossimAtbPointSource.h       |  108 +
 .../tonal_balance/ossimGridRemapEngine.cpp    |   32 +
 .../tonal_balance/ossimGridRemapEngine.h      |   69 +
 .../ossimGridRemapEngineFactory.cpp           |   44 +
 .../ossimGridRemapEngineFactory.h             |   53 +
 .../tonal_balance/ossimGridRemapSource.cpp    |  368 ++
 .../tonal_balance/ossimGridRemapSource.h      |  144 +
 .../tonal_balance/ossimHsvGridRemapEngine.cpp |  276 +
 .../tonal_balance/ossimHsvGridRemapEngine.h   |   54 +
 .../ossimMonoGridRemapEngine.cpp              |  368 ++
 .../tonal_balance/ossimMonoGridRemapEngine.h  |   54 +
 .../tonal_balance/ossimRgbGridRemapEngine.cpp |  271 +
 .../tonal_balance/ossimRgbGridRemapEngine.h   |   54 +
 Utilities/OSSIM/ossim_core/init/.cvsignore    |    1 +
 .../OSSIM/ossim_core/init/CMakeLists.txt      |    6 +
 Utilities/OSSIM/ossim_core/init/ossimInit.cpp |  551 ++
 Utilities/OSSIM/ossim_core/init/ossimInit.h   |  125 +
 .../OSSIM/ossim_core/libpolyclip/.cvsignore   |    1 +
 .../ossim_core/libpolyclip/CMakeLists.txt     |    6 +
 .../OSSIM/ossim_core/libpolyclip/polyarea.h   |  336 +
 .../OSSIM/ossim_core/libpolyclip/polygon0.c   | 1234 ++++
 .../OSSIM/ossim_core/libpolyclip/polygon1.c   | 1482 +++++
 .../OSSIM/ossim_core/libpolyclip/polyio.c     |  306 +
 .../OSSIM/ossim_core/libpolyclip/polyio.h     |   40 +
 .../OSSIM/ossim_core/libpolyclip/vectmatr.c   |  823 +++
 .../OSSIM/ossim_core/libpolyclip/vectmatr.h   |  190 +
 Utilities/OSSIM/ossim_core/matrix/.cvsignore  |    1 +
 .../OSSIM/ossim_core/matrix/CMakeLists.txt    |    6 +
 Utilities/OSSIM/ossim_core/matrix/bandmat.cpp |  569 ++
 Utilities/OSSIM/ossim_core/matrix/bc.mak      |  202 +
 Utilities/OSSIM/ossim_core/matrix/bc32.mak    |  200 +
 Utilities/OSSIM/ossim_core/matrix/boolean.h   |   40 +
 Utilities/OSSIM/ossim_core/matrix/cc.mak      |  160 +
 .../OSSIM/ossim_core/matrix/cholesky.cpp      |  280 +
 Utilities/OSSIM/ossim_core/matrix/controlw.h  |   48 +
 Utilities/OSSIM/ossim_core/matrix/evalue.cpp  |  297 +
 Utilities/OSSIM/ossim_core/matrix/example.txt |  123 +
 Utilities/OSSIM/ossim_core/matrix/fft.cpp     |  474 ++
 Utilities/OSSIM/ossim_core/matrix/gnu.mak     |  154 +
 Utilities/OSSIM/ossim_core/matrix/hholder.cpp |  331 +
 Utilities/OSSIM/ossim_core/matrix/include.h   |  313 +
 Utilities/OSSIM/ossim_core/matrix/jacobi.cpp  |  123 +
 Utilities/OSSIM/ossim_core/matrix/ms.mak      |  201 +
 Utilities/OSSIM/ossim_core/matrix/ms_nt.mak   |  151 +
 .../OSSIM/ossim_core/matrix/myexcept.cpp      |  485 ++
 Utilities/OSSIM/ossim_core/matrix/myexcept.h  |  433 ++
 Utilities/OSSIM/ossim_core/matrix/newfft.cpp  | 1059 +++
 Utilities/OSSIM/ossim_core/matrix/newmat.h    | 1805 ++++++
 Utilities/OSSIM/ossim_core/matrix/newmat.txt  | 3235 ++++++++++
 Utilities/OSSIM/ossim_core/matrix/newmat1.cpp |  199 +
 Utilities/OSSIM/ossim_core/matrix/newmat2.cpp |  641 ++
 Utilities/OSSIM/ossim_core/matrix/newmat3.cpp |  842 +++
 Utilities/OSSIM/ossim_core/matrix/newmat4.cpp | 1027 +++
 Utilities/OSSIM/ossim_core/matrix/newmat5.cpp |  485 ++
 Utilities/OSSIM/ossim_core/matrix/newmat6.cpp |  884 +++
 Utilities/OSSIM/ossim_core/matrix/newmat7.cpp | 1037 +++
 Utilities/OSSIM/ossim_core/matrix/newmat8.cpp |  734 +++
 Utilities/OSSIM/ossim_core/matrix/newmat9.cpp |   76 +
 Utilities/OSSIM/ossim_core/matrix/newmatap.h  |  201 +
 .../OSSIM/ossim_core/matrix/newmatex.cpp      |  313 +
 Utilities/OSSIM/ossim_core/matrix/newmatio.h  |   61 +
 .../OSSIM/ossim_core/matrix/newmatnl.cpp      |  260 +
 Utilities/OSSIM/ossim_core/matrix/newmatnl.h  |  322 +
 Utilities/OSSIM/ossim_core/matrix/newmatrc.h  |  171 +
 .../OSSIM/ossim_core/matrix/newmatrm.cpp      |  216 +
 Utilities/OSSIM/ossim_core/matrix/newmatrm.h  |  145 +
 Utilities/OSSIM/ossim_core/matrix/nl_ex.txt   |   42 +
 Utilities/OSSIM/ossim_core/matrix/precisio.h  |  241 +
 Utilities/OSSIM/ossim_core/matrix/sl_ex.txt   |   21 +
 .../OSSIM/ossim_core/matrix/solution.cpp      |  203 +
 Utilities/OSSIM/ossim_core/matrix/solution.h  |   96 +
 Utilities/OSSIM/ossim_core/matrix/sort.cpp    |  272 +
 Utilities/OSSIM/ossim_core/matrix/submat.cpp  |  340 +
 Utilities/OSSIM/ossim_core/matrix/svd.cpp     |  204 +
 .../OSSIM/ossim_core/matrix/test_exc.txt      |  189 +
 .../OSSIM/ossim_core/matrix/watco_nt.mak      |  205 +
 Utilities/OSSIM/ossim_core/matrix/watcom.mak  |  200 +
 .../OSSIM/ossim_core/parallel/.cvsignore      |    4 +
 .../OSSIM/ossim_core/parallel/CMakeLists.txt  |    6 +
 .../OSSIM/ossim_core/parallel/ossimIgen.cpp   |  805 +++
 .../OSSIM/ossim_core/parallel/ossimIgen.h     |   94 +
 ...ossimImageMpiMWriterSequenceConnection.cpp |  290 +
 .../ossimImageMpiMWriterSequenceConnection.h  |   60 +
 ...ossimImageMpiSWriterSequenceConnection.cpp |  355 ++
 .../ossimImageMpiSWriterSequenceConnection.h  |   53 +
 .../OSSIM/ossim_core/parallel/ossimMpi.cpp    |  175 +
 .../OSSIM/ossim_core/parallel/ossimMpi.h      |   59 +
 .../ossim_core/parallel/ossimOrthoIgen.cpp    | 1051 +++
 .../ossim_core/parallel/ossimOrthoIgen.h      |  144 +
 Utilities/OSSIM/ossim_core/plugin/.cvsignore  |    1 +
 .../OSSIM/ossim_core/plugin/CMakeLists.txt    |    6 +
 .../ossim_core/plugin/ossimDynamicLibrary.cpp |  118 +
 .../ossim_core/plugin/ossimDynamicLibrary.h   |   69 +
 .../ossim_core/plugin/ossimPluginLibrary.cpp  |   95 +
 .../ossim_core/plugin/ossimPluginLibrary.h    |   45 +
 .../plugin/ossimSharedObjectBridge.cpp        |   27 +
 .../plugin/ossimSharedObjectBridge.h          |   54 +
 .../plugin/ossimSharedPluginRegistry.cpp      |  181 +
 .../plugin/ossimSharedPluginRegistry.h        |   36 +
 .../OSSIM/ossim_core/projections/.cvsignore   |    3 +
 .../ossim_core/projections/CMakeLists.txt     |    6 +
 .../ossim_core/projections/factory/.cvsignore |    3 +
 .../ossimImageViewTransformFactory.cpp        |   69 +
 .../factory/ossimImageViewTransformFactory.h  |   49 +
 .../factory/ossimMapProjectionFactory.cpp     |  326 +
 .../factory/ossimMapProjectionFactory.h       |   74 +
 .../factory/ossimMiscProjectionFactory.cpp    |  190 +
 .../factory/ossimMiscProjectionFactory.h      |   74 +
 .../factory/ossimNitfProjectionFactory.cpp    |  874 +++
 .../factory/ossimNitfProjectionFactory.h      |  253 +
 .../factory/ossimPcsCodeProjectionFactory.cpp |  327 +
 .../factory/ossimPcsCodeProjectionFactory.h   |   84 +
 .../factory/ossimProjectionFactoryBase.cpp    |   90 +
 .../factory/ossimProjectionFactoryBase.h      |   78 +
 .../ossimProjectionFactoryRegistry.cpp        |  199 +
 .../factory/ossimProjectionFactoryRegistry.h  |   71 +
 .../ossimProjectionViewControllerFactory.cpp  |   90 +
 .../ossimProjectionViewControllerFactory.h    |   54 +
 .../factory/ossimSensorModelFactory.cpp       |  548 ++
 .../factory/ossimSensorModelFactory.h         |   73 +
 .../factory/ossimSrsProjectionFactory.cpp     |  159 +
 .../factory/ossimSrsProjectionFactory.h       |   68 +
 .../ossimStatePlaneProjectionFactory.cpp      |  854 +++
 .../ossimStatePlaneProjectionFactory.h        |   57 +
 .../factory/ossimTiffProjectionFactory.cpp    |  133 +
 .../factory/ossimTiffProjectionFactory.h      |   75 +
 .../projections/map_projections/.cvsignore    |    3 +
 .../map_projections/ossimAlbersProjection.cpp |  660 ++
 .../map_projections/ossimAlbersProjection.h   |  252 +
 .../ossimAzimEquDistProjection.cpp            |  491 ++
 .../ossimAzimEquDistProjection.h              |  197 +
 .../map_projections/ossimBngProjection.cpp    |  761 +++
 .../map_projections/ossimBngProjection.h      |  159 +
 .../map_projections/ossimBonneProjection.cpp  |  541 ++
 .../map_projections/ossimBonneProjection.h    |  215 +
 .../map_projections/ossimCadrgProjection.cpp  |  417 ++
 .../map_projections/ossimCadrgProjection.h    |  101 +
 .../ossimCassiniProjection.cpp                |  546 ++
 .../map_projections/ossimCassiniProjection.h  |  208 +
 .../ossimCylEquAreaProjection.cpp             |  467 ++
 .../ossimCylEquAreaProjection.h               |  211 +
 .../ossimEckert4Projection.cpp                |  462 ++
 .../map_projections/ossimEckert4Projection.h  |  193 +
 .../ossimEckert6Projection.cpp                |  445 ++
 .../map_projections/ossimEckert6Projection.h  |  193 +
 .../ossimEquDistCylProjection.cpp             |  466 ++
 .../ossimEquDistCylProjection.h               |  209 +
 .../ossimGnomonicProjection.cpp               |  459 ++
 .../map_projections/ossimGnomonicProjection.h |  193 +
 .../ossimLambertConformalConicProjection.cpp  |  647 ++
 .../ossimLambertConformalConicProjection.h    |  230 +
 .../map_projections/ossimLlxyProjection.cpp   |  323 +
 .../map_projections/ossimLlxyProjection.h     |  146 +
 .../map_projections/ossimMapProjection.cpp    | 1054 +++
 .../map_projections/ossimMapProjection.h      |  295 +
 .../ossimMapProjectionInfo.cpp                |  548 ++
 .../map_projections/ossimMapProjectionInfo.h  |  277 +
 .../ossimMercatorProjection.cpp               |  462 ++
 .../map_projections/ossimMercatorProjection.h |  224 +
 .../projections/map_projections/ossimMgrs.c   | 1325 ++++
 .../projections/map_projections/ossimMgrs.h   |  252 +
 .../map_projections/ossimMillerProjection.cpp |  411 ++
 .../map_projections/ossimMillerProjection.h   |  186 +
 .../ossimMollweidProjection.cpp               |  453 ++
 .../map_projections/ossimMollweidProjection.h |  188 +
 .../ossimNewZealandMapGridProjection.cpp      |  434 ++
 .../ossimNewZealandMapGridProjection.h        |  135 +
 .../ossimObliqueMercatorProjection.cpp        |  734 +++
 .../ossimObliqueMercatorProjection.h          |  256 +
 .../ossimOrthoGraphicProjection.cpp           |  501 ++
 .../ossimOrthoGraphicProjection.h             |  196 +
 .../ossimPolarStereoProjection.cpp            |  562 ++
 .../ossimPolarStereoProjection.h              |  192 +
 .../map_projections/ossimPolarst.c            |  505 ++
 .../map_projections/ossimPolarst.h            |  202 +
 .../ossimPolyconicProjection.cpp              |  529 ++
 .../ossimPolyconicProjection.h                |  203 +
 .../map_projections/ossimSinusoid.c           |  388 ++
 .../map_projections/ossimSinusoid.h           |  185 +
 .../ossimSinusoidalProjection.cpp             |  455 ++
 .../ossimSinusoidalProjection.h               |  201 +
 .../ossimSpaceObliqueMercatorProjection.cpp   |  408 ++
 .../ossimSpaceObliqueMercatorProjection.h     |  105 +
 .../ossimStereographicProjection.cpp          |  511 ++
 .../ossimStereographicProjection.h            |  193 +
 .../map_projections/ossimTranmerc.c           |  625 ++
 .../map_projections/ossimTranmerc.h           |  209 +
 .../ossimTransCylEquAreaProjection.cpp        |  606 ++
 .../ossimTransCylEquAreaProjection.h          |  230 +
 .../ossimTransMercatorProjection.cpp          |  743 +++
 .../ossimTransMercatorProjection.h            |  220 +
 .../projections/map_projections/ossimUps.c    |  310 +
 .../projections/map_projections/ossimUps.h    |  175 +
 .../map_projections/ossimUpsProjection.cpp    |  335 +
 .../map_projections/ossimUpsProjection.h      |  140 +
 .../map_projections/ossimUpspt.cpp            |   67 +
 .../projections/map_projections/ossimUpspt.h  |   56 +
 .../projections/map_projections/ossimUtm.c    |  337 +
 .../projections/map_projections/ossimUtm.h    |  178 +
 .../map_projections/ossimUtmProjection.cpp    |  892 +++
 .../map_projections/ossimUtmProjection.h      |  209 +
 .../map_projections/ossimUtmpt.cpp            |   88 +
 .../projections/map_projections/ossimUtmpt.h  |   89 +
 .../ossimVanDerGrintenProjection.cpp          |  529 ++
 .../ossimVanDerGrintenProjection.h            |  189 +
 .../projections/ossimAffineProjection.cpp     |  287 +
 .../projections/ossimAffineProjection.h       |  130 +
 .../projections/ossimBilinearProjection.cpp   |  433 ++
 .../projections/ossimBilinearProjection.h     |  108 +
 .../ossimImageViewAffineTransform.cpp         |  352 +
 .../ossimImageViewAffineTransform.h           |  139 +
 .../ossimImageViewProjectionTransform.cpp     |  476 ++
 .../ossimImageViewProjectionTransform.h       |  169 +
 .../projections/ossimImageViewTransform.cpp   |  272 +
 .../projections/ossimImageViewTransform.h     |  134 +
 .../projections/ossimMapViewController.cpp    |  215 +
 .../projections/ossimMapViewController.h      |   72 +
 .../projections/ossimProjection.cpp           |  203 +
 .../ossim_core/projections/ossimProjection.h  |  148 +
 .../projections/ossimQuadProjection.cpp       |  543 ++
 .../projections/ossimQuadProjection.h         |   88 +
 .../projections/ossimRpcProjection.cpp        |  788 +++
 .../projections/ossimRpcProjection.h          |  151 +
 .../ossim_core/projections/ossimRpcSolver.cpp |  792 +++
 .../ossim_core/projections/ossimRpcSolver.h   |  233 +
 .../ossimStatePlaneProjectionInfo.cpp         |  306 +
 .../ossimStatePlaneProjectionInfo.h           |  108 +
 .../projections/ossimWarpProjection.cpp       |  343 +
 .../projections/ossimWarpProjection.h         |  146 +
 .../projections/sensor_modeling/.cvsignore    |    2 +
 .../sensor_modeling/coarse_grid/.cvsignore    |    2 +
 .../coarse_grid/ossimCoarseGridModel.cpp      | 1348 ++++
 .../coarse_grid/ossimCoarseGridModel.h        |  173 +
 .../sensor_modeling/fcsi/.cvsignore           |    2 +
 .../fcsi/ossimApplanixEcefModel.cpp           |  625 ++
 .../fcsi/ossimApplanixEcefModel.h             |   71 +
 .../fcsi/ossimApplanixUtmModel.cpp            |  802 +++
 .../fcsi/ossimApplanixUtmModel.h              |   73 +
 .../sensor_modeling/fcsi/ossimFcsiModel.cpp   | 1064 ++++
 .../sensor_modeling/fcsi/ossimFcsiModel.h     |  249 +
 .../sensor_modeling/landsat/.cvsignore        |    2 +
 .../landsat/ossimLandSatModel.cpp             | 1154 ++++
 .../landsat/ossimLandSatModel.h               |  191 +
 .../sensor_modeling/ossimAdjMapModel.cpp      |  416 ++
 .../sensor_modeling/ossimAdjMapModel.h        |  132 +
 .../sensor_modeling/ossimLensDistortion.cpp   |   48 +
 .../sensor_modeling/ossimLensDistortion.h     |   52 +
 .../ossimMeanRadialLensDistortion.cpp         |  267 +
 .../ossimMeanRadialLensDistortion.h           |  120 +
 .../sensor_modeling/ossimNitfMapModel.cpp     |  680 ++
 .../sensor_modeling/ossimNitfMapModel.h       |   90 +
 .../ossimRadialDecentLensDistortion.cpp       |  207 +
 .../ossimRadialDecentLensDistortion.h         |  174 +
 .../sensor_modeling/ossimSensorModel.cpp      |  962 +++
 .../sensor_modeling/ossimSensorModel.h        |  234 +
 .../sensor_modeling/rpc/.cvsignore            |    2 +
 .../rpc/ossimIkonosRpcModel.cpp               |  601 ++
 .../sensor_modeling/rpc/ossimIkonosRpcModel.h |   68 +
 .../sensor_modeling/rpc/ossimNitfRpcModel.cpp |  466 ++
 .../sensor_modeling/rpc/ossimNitfRpcModel.h   |   53 +
 .../rpc/ossimQuickbirdRpcModel.cpp            |  534 ++
 .../rpc/ossimQuickbirdRpcModel.h              |   55 +
 .../sensor_modeling/rpc/ossimRpcModel.cpp     | 1040 +++
 .../sensor_modeling/rpc/ossimRpcModel.h       |  193 +
 .../sensor_modeling/spot/.cvsignore           |    2 +
 .../sensor_modeling/spot/ossimSpot5Model.cpp  |  593 ++
 .../sensor_modeling/spot/ossimSpot5Model.h    |  163 +
 .../OSSIM/ossim_core/support_data/.cvsignore  |    4 +
 .../ossim_core/support_data/CMakeLists.txt    |    6 +
 .../support_data/doqq/ossimDoqq.cpp           |  393 ++
 .../ossim_core/support_data/doqq/ossimDoqq.h  |  122 +
 .../ossim_core/support_data/dted/.cvsignore   |    2 +
 .../support_data/dted/ossimDtedAcc.cpp        |  248 +
 .../support_data/dted/ossimDtedAcc.h          |  102 +
 .../support_data/dted/ossimDtedDsi.cpp        |  553 ++
 .../support_data/dted/ossimDtedDsi.h          |  207 +
 .../support_data/dted/ossimDtedHdr.cpp        |  234 +
 .../support_data/dted/ossimDtedHdr.h          |   97 +
 .../support_data/dted/ossimDtedRecord.cpp     |  323 +
 .../support_data/dted/ossimDtedRecord.h       |  174 +
 .../support_data/dted/ossimDtedUhl.cpp        |  298 +
 .../support_data/dted/ossimDtedUhl.h          |  100 +
 .../support_data/dted/ossimDtedVol.cpp        |  191 +
 .../support_data/dted/ossimDtedVol.h          |   78 +
 .../ossim_core/support_data/envi/.cvsignore   |    4 +
 .../support_data/envi/ossimEnviHeader.cpp     |  974 +++
 .../support_data/envi/ossimEnviHeader.h       |  339 +
 .../ossim_core/support_data/ers/.cvsignore    |    2 +
 .../ossim_core/support_data/ers/ossimERS.cpp  |  603 ++
 .../ossim_core/support_data/ers/ossimERS.h    |   89 +
 .../ossim_core/support_data/esri/.cvsignore   |    5 +
 .../support_data/esri/ossimAigBounds.cpp      |   58 +
 .../support_data/esri/ossimAigBounds.h        |   59 +
 .../esri/ossimAigDataFileHeader.cpp           |   49 +
 .../esri/ossimAigDataFileHeader.h             |  179 +
 .../support_data/esri/ossimAigHeader.cpp      |   91 +
 .../support_data/esri/ossimAigHeader.h        |  128 +
 .../esri/ossimAigIndexFileHeader.cpp          |   46 +
 .../esri/ossimAigIndexFileHeader.h            |   90 +
 .../support_data/esri/ossimAigStatistics.cpp  |   58 +
 .../support_data/esri/ossimAigStatistics.h    |   51 +
 .../ossim_core/support_data/fcsi/.cvsignore   |    2 +
 .../support_data/fcsi/ossimApplanixEOFile.cpp |  690 ++
 .../support_data/fcsi/ossimApplanixEOFile.h   |  208 +
 .../ossim_core/support_data/ff_l7/.cvsignore  |    3 +
 .../support_data/ff_l7/ossimFfL5.cpp          |  183 +
 .../ossim_core/support_data/ff_l7/ossimFfL5.h |   54 +
 .../support_data/ff_l7/ossimFfL7.cpp          |  564 ++
 .../ossim_core/support_data/ff_l7/ossimFfL7.h |  152 +
 .../support_data/ff_revb/.cvsignore           |    3 +
 .../support_data/ff_revb/ossimFfRevb.cpp      | 1373 ++++
 .../support_data/ff_revb/ossimFfRevb.h        |  303 +
 .../support_data/ff_revc/.cvsignore           |    3 +
 .../support_data/ff_revc/ossimFfRevc.cpp      | 1956 ++++++
 .../support_data/ff_revc/ossimFfRevc.h        |  361 ++
 .../ossim_core/support_data/ikonos/.cvsignore |    2 +
 .../ikonos/ossimIkonosMetaData.cpp            |   46 +
 .../support_data/ikonos/ossimIkonosMetaData.h |   49 +
 .../ikonos/ossimSpaceImagingGeom.cpp          |  286 +
 .../ikonos/ossimSpaceImagingGeom.h            |   74 +
 .../ossim_core/support_data/nitf/.cvsignore   |    5 +
 .../support_data/nitf/ossimNitfBlockaTag.cpp  |  319 +
 .../support_data/nitf/ossimNitfBlockaTag.h    |  341 +
 .../support_data/nitf/ossimNitfCommon.cpp     |  213 +
 .../support_data/nitf/ossimNitfCommon.h       |  106 +
 .../nitf/ossimNitfCompressionHeader.cpp       |   13 +
 .../nitf/ossimNitfCompressionHeader.h         |   24 +
 .../nitf/ossimNitfDataExtensionSegment.cpp    |   34 +
 .../nitf/ossimNitfDataExtensionSegment.h      |   44 +
 .../ossimNitfDataExtensionSegmentV2_0.cpp     |  142 +
 .../nitf/ossimNitfDataExtensionSegmentV2_0.h  |   83 +
 .../nitf/ossimNitfEmbeddedRpfDes.cpp          |   49 +
 .../nitf/ossimNitfEmbeddedRpfDes.h            |   48 +
 .../nitf/ossimNitfEmbeddedRpfHeader.cpp       |   78 +
 .../nitf/ossimNitfEmbeddedRpfHeader.h         |   57 +
 .../support_data/nitf/ossimNitfFile.cpp       |  264 +
 .../support_data/nitf/ossimNitfFile.h         |   72 +
 .../support_data/nitf/ossimNitfFileHeader.cpp |  140 +
 .../support_data/nitf/ossimNitfFileHeader.h   |  179 +
 .../nitf/ossimNitfFileHeaderV2_0.cpp          |  837 +++
 .../nitf/ossimNitfFileHeaderV2_0.h            |  591 ++
 .../nitf/ossimNitfFileHeaderV2_1.cpp          | 1852 ++++++
 .../nitf/ossimNitfFileHeaderV2_1.h            |  678 ++
 .../nitf/ossimNitfGeoPositioningTag.cpp       |  116 +
 .../nitf/ossimNitfGeoPositioningTag.h         |  218 +
 .../support_data/nitf/ossimNitfImageBand.cpp  |   43 +
 .../support_data/nitf/ossimNitfImageBand.h    |   50 +
 .../nitf/ossimNitfImageBandV2_0.cpp           |  154 +
 .../nitf/ossimNitfImageBandV2_0.h             |   72 +
 .../nitf/ossimNitfImageBandV2_1.cpp           |   47 +
 .../nitf/ossimNitfImageBandV2_1.h             |   31 +
 .../nitf/ossimNitfImageHeader.cpp             |  219 +
 .../support_data/nitf/ossimNitfImageHeader.h  |  118 +
 .../nitf/ossimNitfImageHeaderV2_0.cpp         |  760 +++
 .../nitf/ossimNitfImageHeaderV2_0.h           |  540 ++
 .../nitf/ossimNitfImageHeaderV2_1.cpp         | 2222 +++++++
 .../nitf/ossimNitfImageHeaderV2_1.h           | 1097 ++++
 .../support_data/nitf/ossimNitfImageLut.cpp   |   47 +
 .../support_data/nitf/ossimNitfImageLut.h     |   48 +
 .../nitf/ossimNitfImageLutV2_0.cpp            |   74 +
 .../support_data/nitf/ossimNitfImageLutV2_0.h |   48 +
 .../nitf/ossimNitfImageLutV2_1.cpp            |   74 +
 .../support_data/nitf/ossimNitfImageLutV2_1.h |   41 +
 .../nitf/ossimNitfLabelHeader.cpp             |   26 +
 .../support_data/nitf/ossimNitfLabelHeader.h  |   44 +
 .../nitf/ossimNitfLabelHeaderV2_0.cpp         |  164 +
 .../nitf/ossimNitfLabelHeaderV2_0.h           |  173 +
 .../nitf/ossimNitfLocalCartographicTag.cpp    |  146 +
 .../nitf/ossimNitfLocalCartographicTag.h      |   92 +
 .../nitf/ossimNitfLocalGeographicTag.cpp      |  119 +
 .../nitf/ossimNitfLocalGeographicTag.h        |   82 +
 .../nitf/ossimNitfNameConversionTables.cpp    |  161 +
 .../nitf/ossimNitfNameConversionTables.h      |   28 +
 .../support_data/nitf/ossimNitfPackedBits.cpp |   58 +
 .../support_data/nitf/ossimNitfPackedBits.h   |   41 +
 .../nitf/ossimNitfProjectionParameterTag.cpp  |  188 +
 .../nitf/ossimNitfProjectionParameterTag.h    |  324 +
 .../nitf/ossimNitfRegisteredTag.cpp           |   27 +
 .../nitf/ossimNitfRegisteredTag.h             |   51 +
 .../nitf/ossimNitfRegisteredTagFactory.cpp    |  103 +
 .../nitf/ossimNitfRegisteredTagFactory.h      |   29 +
 .../support_data/nitf/ossimNitfRpcATag.cpp    |   28 +
 .../support_data/nitf/ossimNitfRpcATag.h      |   38 +
 .../support_data/nitf/ossimNitfRpcBTag.cpp    |   26 +
 .../support_data/nitf/ossimNitfRpcBTag.h      |   33 +
 .../support_data/nitf/ossimNitfRpcBase.cpp    |  741 +++
 .../support_data/nitf/ossimNitfRpcBase.h      |  546 ++
 .../nitf/ossimNitfRpfTagFactory.cpp           |   57 +
 .../nitf/ossimNitfRpfTagFactory.h             |   39 +
 .../support_data/nitf/ossimNitfSensraTag.cpp  |  414 ++
 .../support_data/nitf/ossimNitfSensraTag.h    |  259 +
 .../support_data/nitf/ossimNitfStdidcTag.cpp  |  326 +
 .../support_data/nitf/ossimNitfStdidcTag.h    |  189 +
 .../nitf/ossimNitfSymbolHeader.cpp            |   26 +
 .../support_data/nitf/ossimNitfSymbolHeader.h |   44 +
 .../nitf/ossimNitfSymbolHeaderV2_0.cpp        |  185 +
 .../nitf/ossimNitfSymbolHeaderV2_0.h          |  236 +
 .../support_data/nitf/ossimNitfTagFactory.cpp |   35 +
 .../support_data/nitf/ossimNitfTagFactory.h   |   36 +
 .../nitf/ossimNitfTagFactoryRegistry.cpp      |   89 +
 .../nitf/ossimNitfTagFactoryRegistry.h        |   57 +
 .../nitf/ossimNitfTagInformation.cpp          |  158 +
 .../nitf/ossimNitfTagInformation.h            |  100 +
 .../support_data/nitf/ossimNitfTextHeader.cpp |   26 +
 .../support_data/nitf/ossimNitfTextHeader.h   |   41 +
 .../nitf/ossimNitfTextHeaderV2_0.cpp          |  127 +
 .../nitf/ossimNitfTextHeaderV2_0.h            |  155 +
 .../support_data/nitf/ossimNitfUse00aTag.cpp  |  415 ++
 .../support_data/nitf/ossimNitfUse00aTag.h    |  260 +
 .../nitf/ossimNitfVqCompressionHeader.cpp     |  267 +
 .../nitf/ossimNitfVqCompressionHeader.h       |   69 +
 .../ossim_core/support_data/qb/.cvsignore     |    2 +
 .../qb/ossimQuickbirdRpcHeader.cpp            |  246 +
 .../support_data/qb/ossimQuickbirdRpcHeader.h |   55 +
 .../support_data/qb/ossimQuickbirdTile.cpp    |  365 ++
 .../support_data/qb/ossimQuickbirdTile.h      |  135 +
 .../ossim_core/support_data/rpf/.cvsignore    |    2 +
 .../rpf/ossimRpfAttributeOffsetRecord.cpp     |   58 +
 .../rpf/ossimRpfAttributeOffsetRecord.h       |  275 +
 .../rpf/ossimRpfAttributeSectionSubheader.cpp |   99 +
 .../rpf/ossimRpfAttributeSectionSubheader.h   |   67 +
 .../support_data/rpf/ossimRpfAttributes.cpp   |  157 +
 .../support_data/rpf/ossimRpfAttributes.h     |  350 +
 .../rpf/ossimRpfBoundaryRectRecord.cpp        |   93 +
 .../rpf/ossimRpfBoundaryRectRecord.h          |   92 +
 .../ossimRpfBoundaryRectSectionSubheader.cpp  |   81 +
 .../ossimRpfBoundaryRectSectionSubheader.h    |   53 +
 .../rpf/ossimRpfBoundaryRectTable.cpp         |   76 +
 .../rpf/ossimRpfBoundaryRectTable.h           |   50 +
 .../ossimRpfColorConverterOffsetRecord.cpp    |   60 +
 .../rpf/ossimRpfColorConverterOffsetRecord.h  |   61 +
 .../rpf/ossimRpfColorConverterSubsection.cpp  |  130 +
 .../rpf/ossimRpfColorConverterSubsection.h    |   52 +
 .../rpf/ossimRpfColorConverterTable.cpp       |   93 +
 .../rpf/ossimRpfColorConverterTable.h         |   45 +
 .../ossimRpfColorGrayscaleOffsetRecord.cpp    |   69 +
 .../rpf/ossimRpfColorGrayscaleOffsetRecord.h  |   44 +
 .../rpf/ossimRpfColorGrayscaleSubheader.cpp   |   59 +
 .../rpf/ossimRpfColorGrayscaleSubheader.h     |   52 +
 .../rpf/ossimRpfColorGrayscaleTable.cpp       |  152 +
 .../rpf/ossimRpfColorGrayscaleTable.h         |   51 +
 .../ossimRpfCompressionLookupOffsetRecord.cpp |   64 +
 .../ossimRpfCompressionLookupOffsetRecord.h   |   48 +
 .../rpf/ossimRpfCompressionSection.cpp        |  202 +
 .../rpf/ossimRpfCompressionSection.h          |   57 +
 .../ossimRpfCompressionSectionSubheader.cpp   |   62 +
 .../rpf/ossimRpfCompressionSectionSubheader.h |   63 +
 .../support_data/rpf/ossimRpfConstants.h      |   59 +
 .../rpf/ossimRpfCoverageSection.cpp           |  115 +
 .../rpf/ossimRpfCoverageSection.h             |  118 +
 .../support_data/rpf/ossimRpfFrame.cpp        | 1022 +++
 .../support_data/rpf/ossimRpfFrame.h          |  176 +
 .../support_data/rpf/ossimRpfFrameEntry.cpp   |   73 +
 .../support_data/rpf/ossimRpfFrameEntry.h     |   59 +
 .../rpf/ossimRpfFrameFileIndexRecord.cpp      |  106 +
 .../rpf/ossimRpfFrameFileIndexRecord.h        |   78 +
 ...ossimRpfFrameFileIndexSectionSubheader.cpp |   85 +
 .../ossimRpfFrameFileIndexSectionSubheader.h  |   57 +
 .../rpf/ossimRpfFrameFileIndexSubsection.cpp  |   98 +
 .../rpf/ossimRpfFrameFileIndexSubsection.h    |   54 +
 .../rpf/ossimRpfFrameFileReader.cpp           |  140 +
 .../rpf/ossimRpfFrameFileReader.h             |   39 +
 .../support_data/rpf/ossimRpfHeader.cpp       |  641 ++
 .../support_data/rpf/ossimRpfHeader.h         |  121 +
 .../rpf/ossimRpfImageDescriptionSubheader.cpp |  111 +
 .../rpf/ossimRpfImageDescriptionSubheader.h   |  126 +
 ...ossimRpfImageDisplayParameterSubheader.cpp |   81 +
 .../ossimRpfImageDisplayParameterSubheader.h  |   74 +
 .../rpf/ossimRpfLocationSection.cpp           |  185 +
 .../rpf/ossimRpfLocationSection.h             |  115 +
 .../rpf/ossimRpfMaskSubheader.cpp             |   90 +
 .../support_data/rpf/ossimRpfMaskSubheader.h  |   39 +
 .../rpf/ossimRpfMaskSubsection.cpp            |   56 +
 .../support_data/rpf/ossimRpfMaskSubsection.h |   51 +
 .../rpf/ossimRpfPathnameRecord.cpp            |   81 +
 .../support_data/rpf/ossimRpfPathnameRecord.h |   49 +
 .../support_data/rpf/ossimRpfToc.cpp          |  338 +
 .../ossim_core/support_data/rpf/ossimRpfToc.h |   81 +
 .../support_data/rpf/ossimRpfTocEntry.cpp     |  133 +
 .../support_data/rpf/ossimRpfTocEntry.h       |   83 +
 .../ossim_core/support_data/spot/.cvsignore   |    2 +
 .../spot/ossimSpotDimapSupportData.cpp        | 2073 ++++++
 .../spot/ossimSpotDimapSupportData.h          |  207 +
 .../ossim_core/support_data/srtm/.cvsignore   |    2 +
 .../support_data/srtm/ossimSrtmFilename.cpp   |  184 +
 .../support_data/srtm/ossimSrtmFilename.h     |   25 +
 .../srtm/ossimSrtmSupportData.cpp             |  807 +++
 .../support_data/srtm/ossimSrtmSupportData.h  |  191 +
 .../ossim_core/support_data/tiff/.cvsignore   |    4 +
 .../support_data/tiff/ossimGeoTiff.cpp        | 2146 +++++++
 .../support_data/tiff/ossimGeoTiff.h          |  272 +
 .../support_data/tiff/ossimTiffWorld.cpp      |  200 +
 .../support_data/tiff/ossimTiffWorld.h        |   66 +
 .../support_data/usgs_dem/.cvsignore          |    2 +
 .../support_data/usgs_dem/ossimDemGrid.cpp    |  235 +
 .../support_data/usgs_dem/ossimDemGrid.h      |  110 +
 .../support_data/usgs_dem/ossimDemHeader.cpp  |  699 ++
 .../support_data/usgs_dem/ossimDemHeader.h    |  356 ++
 .../support_data/usgs_dem/ossimDemPoint.cpp   |   16 +
 .../support_data/usgs_dem/ossimDemPoint.h     |  111 +
 .../support_data/usgs_dem/ossimDemProfile.cpp |  158 +
 .../support_data/usgs_dem/ossimDemProfile.h   |   96 +
 .../support_data/usgs_dem/ossimDemStats.cpp   |  126 +
 .../support_data/usgs_dem/ossimDemStats.h     |   88 +
 .../support_data/usgs_dem/ossimDemUtil.cpp    |   80 +
 .../support_data/usgs_dem/ossimDemUtil.h      |   57 +
 Utilities/OSSIM/ossim_core/vec/CMakeLists.txt |    6 +
 .../OSSIM/ossim_core/vec/shape/.cvsignore     |    2 +
 .../OSSIM/ossim_core/vec/shape/dbfopen.c      | 1549 +++++
 .../vec/shape/ossimShapeDatabase.cpp          |  265 +
 .../ossim_core/vec/shape/ossimShapeDatabase.h |  136 +
 .../ossim_core/vec/shape/ossimShapeFile.cpp   |  232 +
 .../ossim_core/vec/shape/ossimShapeFile.h     |  327 +
 .../OSSIM/ossim_core/vec/shape/shapefil.h     |  528 ++
 .../OSSIM/ossim_core/vec/shape/shpopen.c      | 2018 ++++++
 .../OSSIM/ossim_core/vec/shape/shptree.c      |  983 +++
 Utilities/OSSIM/ossim_core/vec/vpf/.cvsignore |    3 +
 .../vec/vpf/ossimVpfBoundingRecordTable.cpp   |  105 +
 .../vec/vpf/ossimVpfBoundingRecordTable.h     |   18 +
 .../ossim_core/vec/vpf/ossimVpfCoverage.cpp   |  211 +
 .../ossim_core/vec/vpf/ossimVpfCoverage.h     |   67 +
 .../ossim_core/vec/vpf/ossimVpfDatabase.cpp   |  205 +
 .../ossim_core/vec/vpf/ossimVpfDatabase.h     |  103 +
 .../vec/vpf/ossimVpfDatabaseHeader.cpp        |   67 +
 .../vec/vpf/ossimVpfDatabaseHeader.h          |   43 +
 .../ossimVpfDatabaseHeaderTableValidator.cpp  |  132 +
 .../ossimVpfDatabaseHeaderTableValidator.h    |   17 +
 .../ossim_core/vec/vpf/ossimVpfExtent.cpp     |   95 +
 .../OSSIM/ossim_core/vec/vpf/ossimVpfExtent.h |   48 +
 .../vec/vpf/ossimVpfFeatureClass.cpp          |  151 +
 .../ossim_core/vec/vpf/ossimVpfFeatureClass.h |   92 +
 .../vec/vpf/ossimVpfFeatureClassSchema.cpp    |  148 +
 .../vec/vpf/ossimVpfFeatureClassSchema.h      |   83 +
 .../ossim_core/vec/vpf/ossimVpfLibrary.cpp    |  283 +
 .../ossim_core/vec/vpf/ossimVpfLibrary.h      |   73 +
 ...ossimVpfLibraryAttributeTableValidator.cpp |   66 +
 .../ossimVpfLibraryAttributeTableValidator.h  |   12 +
 .../ossim_core/vec/vpf/ossimVpfTable.cpp      |  898 +++
 .../OSSIM/ossim_core/vec/vpf/ossimVpfTable.h  |  103 +
 .../vec/vpf/ossimVpfTableValidator.h          |   18 +
 Utilities/OSSIM/ossim_core/vec/vpf/vpf.h      |   34 +
 .../OSSIM/ossim_core/vpf_util/.cvsignore      |    1 +
 .../OSSIM/ossim_core/vpf_util/CMakeLists.txt  |    6 +
 .../OSSIM/ossim_core/vpf_util/bitarray.c      | 1085 ++++
 .../OSSIM/ossim_core/vpf_util/distance.c      |   86 +
 .../OSSIM/ossim_core/vpf_util/linklist.c      |  710 +++
 .../OSSIM/ossim_core/vpf_util/linklist.h      |   69 +
 Utilities/OSSIM/ossim_core/vpf_util/machine.h |   14 +
 .../OSSIM/ossim_core/vpf_util/mapgraph.h      |   56 +
 Utilities/OSSIM/ossim_core/vpf_util/polygrf.c |  358 ++
 Utilities/OSSIM/ossim_core/vpf_util/polygrf.h |  435 ++
 .../OSSIM/ossim_core/vpf_util/projectn.h      |   41 +
 .../OSSIM/ossim_core/vpf_util/protomas.h      |  123 +
 Utilities/OSSIM/ossim_core/vpf_util/set.c     | 1303 ++++
 Utilities/OSSIM/ossim_core/vpf_util/set.h     |   73 +
 Utilities/OSSIM/ossim_core/vpf_util/system.h  |   59 +
 Utilities/OSSIM/ossim_core/vpf_util/values.h  |   92 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfclip.c |  285 +
 .../OSSIM/ossim_core/vpf_util/vpfcntnt.c      |  510 ++
 Utilities/OSSIM/ossim_core/vpf_util/vpfdict.c |  236 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.c |  505 ++
 Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.h |   31 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.c | 1620 +++++
 Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.h |   64 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfinit.h |   44 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfio.h   |  203 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.c | 1835 ++++++
 Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.h |  108 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfnear.c |  350 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfprim.c | 1135 ++++
 Utilities/OSSIM/ossim_core/vpf_util/vpfprim.h |  122 +
 .../OSSIM/ossim_core/vpf_util/vpfptply.c      |  499 ++
 .../OSSIM/ossim_core/vpf_util/vpfquery.c      |  970 +++
 Utilities/OSSIM/ossim_core/vpf_util/vpfread.c | 1641 +++++
 .../OSSIM/ossim_core/vpf_util/vpfrelat.c      |  902 +++
 .../OSSIM/ossim_core/vpf_util/vpfrelat.h      |   58 +
 .../OSSIM/ossim_core/vpf_util/vpfselec.c      | 1318 ++++
 .../OSSIM/ossim_core/vpf_util/vpfselec.h      |   41 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfspx.c  |  359 ++
 .../OSSIM/ossim_core/vpf_util/vpftable.c      | 1058 +++
 .../OSSIM/ossim_core/vpf_util/vpftable.h      |  320 +
 Utilities/OSSIM/ossim_core/vpf_util/vpftidx.c | 1959 ++++++
 Utilities/OSSIM/ossim_core/vpf_util/vpftidx.h |  145 +
 Utilities/OSSIM/ossim_core/vpf_util/vpfview.h |  206 +
 .../OSSIM/ossim_core/vpf_util/vpfwrite.c      |  835 +++
 Utilities/OSSIM/ossim_core/vpf_util/xmemory.h |   37 +
 otbIncludeDirectories.cmake                   |    2 +
 1478 files changed, 401765 insertions(+), 1 deletion(-)
 create mode 100644 Utilities/OSSIM/.CMakeLists.txt.swp
 create mode 100644 Utilities/OSSIM/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossimConfig.h.in
 create mode 100644 Utilities/OSSIM/ossim_core/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/base/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableDisplayListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableDisplayListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableObjectListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableObjectListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimConnectionEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimConnectionEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimContainerEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimContainerEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayEventListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayEventListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayListEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayListEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayRefreshEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayRefreshEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEventListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEventListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimEventIds.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimImageAoiListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimImageAoiListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEventListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEventListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimImagePolygonEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimImageRectangleEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimListenerManager.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimListenerManager.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimMouseEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimMouseEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimMouseListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimMouseListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimObjectDestructingEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimObjectDestructingEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimObjectEvents.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimProcessListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimProcessListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimProcessProgressEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimProcessProgressEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimPropertyEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimROIEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimROIEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimROIEventListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimROIEventListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimRefreshEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimRefreshEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimStateChangedEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimStateChangedEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimViewEvent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimViewEvent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimViewListener.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/events/ossimViewListener.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimApplicationUsage.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimApplicationUsage.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimArgumentParser.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimArgumentParser.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimCommon.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimCommon.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainer.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainer.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainerInterface.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainerInterface.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimConnectableObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimConnectableObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimConstants.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimCplUtil.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimCplUtil.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimCustomEditorWindow.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimCustomEditorWindow.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimDataObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimDataObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimDate.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimDate.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimDisplayInterface.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimDisplayInterface.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimErrorCodes.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimErrorCodes.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimErrorStatusInterface.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimErrorStatusInterface.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimFactoryBaseTemplate.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimFactoryBaseTemplate.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimFontInformation.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimFontInformation.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimGzStream.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimGzStream.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimHistogramSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimHistogramSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimId.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimId.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimIdManager.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimIdManager.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimIoStream.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimIoStream.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimKeywordNames.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimKeywordNames.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimLeastSquaresBilin.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimLeastSquaresBilin.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimMutex.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimMutex.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimNBandLutDataObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimNBandLutDataObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimOutputSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimOutputSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimPool.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimPoolObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimPreferences.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimPreferences.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimProcessInterface.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimProcessInterface.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimPropertyInterface.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimPropertyInterface.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimProtocolStream.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimQuadrilateralMap.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimQuadrilateralMap.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimRectilinearDataObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimRectilinearDataObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimRefPtr.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimReferenced.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimReferenced.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimRgbLutDataObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimRgbLutDataObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimRtti.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimRtti.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimScopedLock.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimStdOutProgress.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimStdOutProgress.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimStreamBase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimStreamBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimTrace.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimTrace.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimTraceManager.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimTraceManager.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimViewController.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimViewController.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimViewInterface.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/common/ossimViewInterface.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/context/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/context/ossimErrorContext.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/context/ossimNotifyContext.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/context/ossimNotifyContext.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimCmyVector.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimCmyVector.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsiVector.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsiVector.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsvVector.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsvVector.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimJpegYCbCrVector.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimJpegYCbCrVector.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimNormRgbVector.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimNormRgbVector.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimRgbVector.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimRgbVector.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/datum.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimDatum.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimDatum.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridDatum.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridDatum.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridFile.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridFile.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNarDatum.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNarDatum.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNasDatum.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNasDatum.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimSevenParamDatum.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimSevenParamDatum.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimThreeParamDatum.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimThreeParamDatum.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs72Datum.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs72Datum.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs84Datum.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs84Datum.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ellipse/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ellipse/ellips.dat
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.c
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.hpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipsoid.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipsoid.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoid.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoid.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidEgm96.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidEgm96.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidManager.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidManager.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgs.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgs.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgsHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgsHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimActiveEdgeTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimActiveEdgeTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimAxes.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimColumnVector3d.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimColumnVector4d.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDblGrid.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDblGrid.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDirectory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDirectory.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryData.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryTree.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryTree.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDms.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDms.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDpt.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDpt.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDpt3d.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDpt3d.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDrect.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimDrect.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimEcefPoint.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimEcefPoint.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimEcefRay.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimEcefRay.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimEcefVector.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimFilename.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimFilename.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimFpt.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimFpt.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimFpt3d.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimFpt3d.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGeoPolygon.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGeoPolygon.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGeocent.c
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGeocent.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGeoref.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGeoref.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGpt.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGpt.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGrect.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimGrect.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimHexString.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimHexString.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimHistogram.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimHistogram.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimIpt.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimIpt.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimIrect.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimIrect.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimKeyword.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimKeyword.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimKeywordlist.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimKeywordlist.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLine.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLine.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLsrPoint.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLsrPoint.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLsrRay.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLsrRay.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLsrSpace.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLsrSpace.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLsrVector.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimLsrVector.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix3x3.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix3x3.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix4x4.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix4x4.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimMultiBandHistogram.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimMultiBandHistogram.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimMultiResLevelHistogram.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimMultiResLevelHistogram.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimPolyArea2d.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimPolyArea2d.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimPolyLine.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimPolyLine.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimPolygon.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimPolygon.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimRationalNumber.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimRationalNumber.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimRegExp.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimRegExp.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimString.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimString.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimTempFilename.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimTempFilename.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimVrect.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimVrect.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimXmlAttribute.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimXmlAttribute.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimXmlDocument.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimXmlDocument.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimXmlNode.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimXmlNode.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimXmlString.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/data_types/ossimXmlString.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimBaseObjectFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimBaseObjectFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowFactoryBase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowFactoryBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.inc
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimEllipsoidFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimEllipsoidFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactoryRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactoryRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/FlexLexer.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/hash/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/hash/ossimPointHash.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/hash/ossimTileHash.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/hash/ossimTileHash.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/hash/ossimTiledImageHash.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/hash/ossimTiledImageHash.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffCoordTransformsLut.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffCoordTransformsLut.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffDatumLut.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffDatumLut.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimImageTypeLut.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimImageTypeLut.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimInterleaveTypeLut.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimInterleaveTypeLut.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimLookUpTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimLookUpTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimScalarTypeLut.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimScalarTypeLut.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimUnitTypeLut.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimUnitTypeLut.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossim2dLinearRegression.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossim2dLinearRegression.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossim2dTo2dTransform.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossim2dTo2dTransform.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInfo.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInfo.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInterface.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInterface.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAdjustmentInfo.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAdjustmentInfo.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAdrData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAdrData.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAffineTransform.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimAffineTransform.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimBilSplitter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimBilSplitter.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimEndian.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimEndian.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenDefines.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.l
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimQuadTreeWarp.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimQuadTreeWarp.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimRectanglePartitioner.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimRectanglePartitioner.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimUnitConversionTool.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimUnitConversionTool.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimUsgsQuad.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/misc/ossimUsgsQuad.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimBooleanProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimBooleanProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimColorProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimColorProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimContainerProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimContainerProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimDateProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimDateProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimDoubleGridProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimDoubleGridProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimFilenameProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimFilenameProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimFontProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimFontProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimMatrixProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimMatrixProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimNumericProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimNumericProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimStringListProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimStringListProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimStringProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimStringProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimTextProperty.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/base/property/ossimTextProperty.h
 create mode 100644 Utilities/OSSIM/ossim_core/dll_main/Makefile
 create mode 100644 Utilities/OSSIM/ossim_core/dll_main/ossimDllMain.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/dll_main/ossimDllMain.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedHandler.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedHandler.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandler.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandler.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandlerFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandlerFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/srtm/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmHandler.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmHandler.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/ossimElevLess.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/ossimElevManager.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/ossimElevManager.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/ossimElevSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/ossimElevSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/ossimElevSourceFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/ossimElevSourceFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/ossimElevationShapeIdx.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/elevation/ossimElevationShapeIdx.h
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/factory/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/factory/ossimFreeTypeFontFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/factory/ossimFreeTypeFontFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/ossimFont.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/ossimFont.h
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/ossimFreeTypeFont.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/ossimFreeTypeFont.h
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/ossimGdBitmapFont.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/ossimGdBitmapFont.h
 create mode 100644 Utilities/OSSIM/ossim_core/fonts/ossimGdSansBold.inc
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/gdfontg.inc
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/gdfontl.inc
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/gdfontmb.inc
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/gdfonts.inc
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/gdfontt.inc
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationEllipseObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationEllipseObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationFontObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationFontObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationGdBitmapFont.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationGdBitmapFont.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationLineObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationLineObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMapGridSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiEllipseObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiEllipseObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiLineObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiLineObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyLineObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyLineObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationPolyObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationPolyObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimEsriShapeFileFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimEsriShapeFileFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGdFont.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGdFontExterns.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationBitmap.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationBitmap.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationEllipseObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationEllipseObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationFontObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationFontObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationGdBitmapFont.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationGdBitmapFont.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationLineObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationLineObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiEllipseObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiEllipseObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyLineObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyLineObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyObject.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyObject.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeographicAnnotationGrid.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeographicAnnotationGrid.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimMapCompositionSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/annotation/ossimMapCompositionSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAOD.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAOD.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrGridRemapper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrGridRemapper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrKeywords.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrRemapper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrRemapper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimGammaRemapper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimGammaRemapper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/cache/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/cache/ossimAppFixedTileCache.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/cache/ossimAppFixedTileCache.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/cache/ossimAppTileCache.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/cache/ossimAppTileCache.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/cache/ossimFixedTileCache.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/cache/ossimFixedTileCache.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/cache/ossimTileCache.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/cache/ossimTileCache.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/elevation/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/elevation/ossimElevImageSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/elevation/ossimElevImageSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimAnnotationObjectFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimAnnotationObjectFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageDataFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageDataFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactoryBase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactoryBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactoryBase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactoryBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryBase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryBase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscrete3x3HatFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscrete3x3HatFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteConvolutionKernel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteConvolutionKernel.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteNearestNeighbor.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/ossimFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/ossimFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/ossimFilterTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/filters/ossimFilterTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdffield.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdffielddefn.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfmodule.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfrecord.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfsubfielddefn.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfutils.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimIso8211.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/aigrid/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/aigrid/ossimArcInfoGridWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/aigrid/ossimArcInfoGridWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ccf/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfHead.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfHead.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/ossimCibCadrgTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/ossimCibCadrgTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/doqq/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/doqq/ossimDoqqTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/doqq/ossimDoqqTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/dted/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedElevationImageSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedElevationImageSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ers/ossimERSTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ers/ossimERSTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/general_raster/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterInfo.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterInfo.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/jpeg/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/landsat/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/landsat/ossimLandsatTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/landsat/ossimLandsatTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/nitf/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimQuickbirdNitfTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimQuickbirdNitfTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ossimImageFileWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ossimImageFileWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ossimImageHandler.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/ossimImageHandler.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/srtm/ossimSrtmTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/srtm/ossimSrtmTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/tiff/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimQuickbirdTiffTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimQuickbirdTiffTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffOverviewBuilder.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffOverviewBuilder.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/ossimUsgsDemTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/ossimUsgsDemTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationCoverageInfo.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationCoverageInfo.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/histogram/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/histogram/ossimHistogramWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/histogram/ossimHistogramWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/histogram/ossimImageHistogramSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/histogram/ossimImageHistogramSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimEnviHeaderFileWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimEnviHeaderFileWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimFgdcFileWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimFgdcFileWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimGeomFileWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimGeomFileWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimJpegWorldFileWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimJpegWorldFileWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimMetadataFileWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimMetadataFileWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimReadmeFileWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimReadmeFileWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimTiffWorldFileWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/metadata/ossimTiffWorldFileWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/misc/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/misc/ossimPixelFlipper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/misc/ossimPixelFlipper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/misc/ossimVertexExtractor.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/misc/ossimVertexExtractor.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimIgenGenerator.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimIgenGenerator.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageChain.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageChain.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageData.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageDataHelper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageDataHelper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageDisplayWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageDisplayWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageMetaData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageMetaData.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageShapeFileIndex.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageShapeFileIndex.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageSourceInterface.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageSourceInterface.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageSourceSequencer.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageSourceSequencer.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageStatisticsSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageStatisticsSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageWriter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimImageWriter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimRgbImage.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimRgbImage.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimS16ImageData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimS16ImageData.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimTiling.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimTiling.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimU11ImageData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimU11ImageData.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimU16ImageData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimU16ImageData.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimU8ImageData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/ossimU8ImageData.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/patch/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/patch/ossimTilePatch.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/patch/ossimTilePatch.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/reconstruction/ossimMeanMedianFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/reconstruction/ossimMeanMedianFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/remap_tables/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedRemapTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedRemapTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU11RemapTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU11RemapTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU16RemapTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU16RemapTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU8RemapTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU8RemapTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/resample/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/resample/ossimFilterResampler.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/resample/ossimFilterResampler.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/resample/ossimResampler.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/resample/ossimResampler.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossim3x3ConvolutionFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossim3x3ConvolutionFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandAverageFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandAverageFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandClipFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandClipFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandMergeSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandMergeSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandSelector.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandSelector.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBlendMosaic.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBlendMosaic.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessContrastSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessContrastSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessMatch.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessMatch.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBumpShadeTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBumpShadeTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCacheTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCacheTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCastTileSourceFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCastTileSourceFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimClosestToCenterCombiner.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimClosestToCenterCombiner.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimColorNormalizedFusion.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimColorNormalizedFusion.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionFilter1D.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionFilter1D.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEastingNorthingCutter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEastingNorthingCutter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEdgeFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEdgeFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEquationCombiner.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEquationCombiner.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEsriShapeFileCutter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEsriShapeFileCutter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFeatherMosaic.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFeatherMosaic.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFftFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFftFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFusionCombiner.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFusionCombiner.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimGeoPolyCutter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimGeoPolyCutter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistoMatchRemapper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistoMatchRemapper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramEqualization.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramEqualization.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramMatchFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramMatchFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramRemapper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramRemapper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramThreshholdFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramThreshholdFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiRemapper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiRemapper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiToRgbSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiToRgbSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsvToRgbSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsvToRgbSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageCombiner.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageCombiner.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageGaussianFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageGaussianFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageMosaic.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageMosaic.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageRenderer.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageRenderer.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSharpenFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSharpenFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceHistogramFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceHistogramFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageToPlaneNormalFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageToPlaneNormalFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIndexToRgbLutFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIndexToRgbLutFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIntensityAdjustmentFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIntensityAdjustmentFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimJpegYCbCrToRgbSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimJpegYCbCrToRgbSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLandsatTopoCorrectionFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLandsatTopoCorrectionFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLocalCorrelationFusion.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLocalCorrelationFusion.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaskFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaskFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaxMosaic.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaxMosaic.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMultiBandHistogramTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMultiBandHistogramTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimNBandToIndexFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimNBandToIndexFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimOrthoImageMosaic.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimOrthoImageMosaic.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimPolyCutter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimPolyCutter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRLevelFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRLevelFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRectangleCutFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRectangleCutFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToGreyFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToGreyFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsiSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsiSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsvSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsvSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToIndexFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToIndexFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToJpegYCbCrSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToJpegYCbCrSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSFIMFusion.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSFIMFusion.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScalarRemapper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScalarRemapper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScaleFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScaleFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSubImageTileSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSubImageTileSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTableRemapper.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTableRemapper.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTopographicCorrectionFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTopographicCorrectionFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTrimFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTrimFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimValueAssignImageSourceFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimValueAssignImageSourceFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimVectorRenderer.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimVectorRenderer.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimWatermarkFilter.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimWatermarkFilter.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbController.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbController.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbMatchPoint.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbMatchPoint.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbPointSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbPointSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngine.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngine.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngineFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngineFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapSource.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapSource.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimHsvGridRemapEngine.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimHsvGridRemapEngine.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimMonoGridRemapEngine.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimMonoGridRemapEngine.h
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimRgbGridRemapEngine.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimRgbGridRemapEngine.h
 create mode 100644 Utilities/OSSIM/ossim_core/init/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/init/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/init/ossimInit.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/init/ossimInit.h
 create mode 100644 Utilities/OSSIM/ossim_core/libpolyclip/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/libpolyclip/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/libpolyclip/polyarea.h
 create mode 100644 Utilities/OSSIM/ossim_core/libpolyclip/polygon0.c
 create mode 100644 Utilities/OSSIM/ossim_core/libpolyclip/polygon1.c
 create mode 100644 Utilities/OSSIM/ossim_core/libpolyclip/polyio.c
 create mode 100644 Utilities/OSSIM/ossim_core/libpolyclip/polyio.h
 create mode 100644 Utilities/OSSIM/ossim_core/libpolyclip/vectmatr.c
 create mode 100644 Utilities/OSSIM/ossim_core/libpolyclip/vectmatr.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/bandmat.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/bc.mak
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/bc32.mak
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/boolean.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/cc.mak
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/cholesky.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/controlw.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/evalue.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/example.txt
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/fft.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/gnu.mak
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/hholder.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/include.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/jacobi.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/ms.mak
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/ms_nt.mak
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/myexcept.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/myexcept.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newfft.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat.txt
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat1.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat2.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat3.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat4.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat5.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat6.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat7.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat8.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmat9.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmatap.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmatex.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmatio.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmatnl.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmatnl.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmatrc.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmatrm.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/newmatrm.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/nl_ex.txt
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/precisio.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/sl_ex.txt
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/solution.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/solution.h
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/sort.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/submat.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/svd.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/test_exc.txt
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/watco_nt.mak
 create mode 100644 Utilities/OSSIM/ossim_core/matrix/watcom.mak
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimIgen.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimIgen.h
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimImageMpiMWriterSequenceConnection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimImageMpiMWriterSequenceConnection.h
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimImageMpiSWriterSequenceConnection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimImageMpiSWriterSequenceConnection.h
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimMpi.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimMpi.h
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimOrthoIgen.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/parallel/ossimOrthoIgen.h
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/ossimDynamicLibrary.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/ossimDynamicLibrary.h
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/ossimPluginLibrary.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/ossimPluginLibrary.h
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/ossimSharedObjectBridge.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/ossimSharedObjectBridge.h
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/ossimSharedPluginRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/plugin/ossimSharedPluginRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/projections/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimImageViewTransformFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimImageViewTransformFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimMapProjectionFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimMapProjectionFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimMiscProjectionFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimMiscProjectionFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimNitfProjectionFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimNitfProjectionFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimPcsCodeProjectionFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimPcsCodeProjectionFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryBase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionViewControllerFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionViewControllerFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimSensorModelFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimSensorModelFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimSrsProjectionFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimSrsProjectionFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimStatePlaneProjectionFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimStatePlaneProjectionFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimTiffProjectionFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/factory/ossimTiffProjectionFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimAlbersProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimAlbersProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimAzimEquDistProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimAzimEquDistProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimBngProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimBngProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimBonneProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimBonneProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimCadrgProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimCadrgProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimCassiniProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimCassiniProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimCylEquAreaProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimCylEquAreaProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert4Projection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert4Projection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert6Projection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert6Projection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimEquDistCylProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimEquDistCylProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimGnomonicProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimGnomonicProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimLambertConformalConicProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimLambertConformalConicProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimLlxyProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimLlxyProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjectionInfo.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjectionInfo.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMercatorProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMercatorProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMgrs.c
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMgrs.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMillerProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMillerProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMollweidProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimMollweidProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimNewZealandMapGridProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimNewZealandMapGridProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimObliqueMercatorProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimObliqueMercatorProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimOrthoGraphicProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimOrthoGraphicProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarStereoProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarStereoProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarst.c
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarst.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolyconicProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolyconicProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoid.c
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoid.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoidalProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoidalProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimSpaceObliqueMercatorProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimSpaceObliqueMercatorProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimStereographicProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimStereographicProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimTranmerc.c
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimTranmerc.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransCylEquAreaProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransCylEquAreaProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransMercatorProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransMercatorProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUps.c
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUps.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpsProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpsProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpspt.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpspt.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtm.c
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtm.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmpt.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmpt.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimVanDerGrintenProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/map_projections/ossimVanDerGrintenProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimAffineProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimAffineProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimBilinearProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimBilinearProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimImageViewAffineTransform.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimImageViewAffineTransform.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimImageViewProjectionTransform.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimImageViewProjectionTransform.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimImageViewTransform.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimImageViewTransform.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimMapViewController.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimMapViewController.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimQuadProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimQuadProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimRpcProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimRpcProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimRpcSolver.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimRpcSolver.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimStatePlaneProjectionInfo.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimStatePlaneProjectionInfo.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimWarpProjection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/ossimWarpProjection.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixEcefModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixEcefModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixUtmModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixUtmModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimFcsiModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimFcsiModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/ossimLandSatModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/ossimLandSatModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimAdjMapModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimAdjMapModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimLensDistortion.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimLensDistortion.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimMeanRadialLensDistortion.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimMeanRadialLensDistortion.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimNitfMapModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimNitfMapModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimRadialDecentLensDistortion.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimRadialDecentLensDistortion.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimSensorModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimSensorModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimIkonosRpcModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimIkonosRpcModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimNitfRpcModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimNitfRpcModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimRpcModel.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimRpcModel.h
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/ossimSpot5Model.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/ossimSpot5Model.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/doqq/ossimDoqq.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/doqq/ossimDoqq.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedAcc.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedAcc.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedDsi.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedDsi.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedHdr.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedHdr.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedRecord.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedRecord.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedUhl.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedUhl.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedVol.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedVol.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/envi/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/envi/ossimEnviHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/envi/ossimEnviHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ers/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ers/ossimERS.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ers/ossimERS.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigBounds.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigBounds.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigDataFileHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigDataFileHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigIndexFileHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigIndexFileHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigStatistics.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/esri/ossimAigStatistics.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/fcsi/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/fcsi/ossimApplanixEOFile.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/fcsi/ossimApplanixEOFile.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_l7/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL5.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL5.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL7.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL7.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_revb/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_revb/ossimFfRevb.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_revb/ossimFfRevb.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_revc/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_revc/ossimFfRevc.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ff_revc/ossimFfRevc.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ikonos/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ikonos/ossimIkonosMetaData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ikonos/ossimIkonosMetaData.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ikonos/ossimSpaceImagingGeom.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/ikonos/ossimSpaceImagingGeom.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfBlockaTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfBlockaTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCommon.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCommon.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCompressionHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCompressionHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegment.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegment.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegmentV2_0.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegmentV2_0.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfDes.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfDes.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFile.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFile.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_0.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_0.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_1.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_1.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfGeoPositioningTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfGeoPositioningTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBand.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBand.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_0.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_0.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_1.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_1.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_0.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_0.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_1.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_1.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLut.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLut.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_0.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_0.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_1.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_1.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeaderV2_0.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeaderV2_0.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalCartographicTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalCartographicTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalGeographicTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalGeographicTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfNameConversionTables.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfNameConversionTables.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfPackedBits.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfPackedBits.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfProjectionParameterTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfProjectionParameterTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTagFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTagFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcATag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcATag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBase.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpfTagFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpfTagFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSensraTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSensraTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfStdidcTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfStdidcTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeaderV2_0.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeaderV2_0.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactory.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactory.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactoryRegistry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactoryRegistry.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagInformation.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagInformation.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeaderV2_0.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeaderV2_0.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfUse00aTag.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfUse00aTag.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfVqCompressionHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfVqCompressionHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/qb/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdRpcHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdRpcHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdTile.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdTile.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeOffsetRecord.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeOffsetRecord.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeSectionSubheader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeSectionSubheader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributes.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributes.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectRecord.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectRecord.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectSectionSubheader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectSectionSubheader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterOffsetRecord.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterOffsetRecord.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterSubsection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterSubsection.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleOffsetRecord.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleOffsetRecord.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleSubheader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleSubheader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionLookupOffsetRecord.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionLookupOffsetRecord.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSection.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSectionSubheader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSectionSubheader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfConstants.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCoverageSection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCoverageSection.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrame.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrame.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameEntry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameEntry.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexRecord.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexRecord.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSectionSubheader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSectionSubheader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSubsection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSubsection.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileReader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileReader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDescriptionSubheader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDescriptionSubheader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDisplayParameterSubheader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDisplayParameterSubheader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfLocationSection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfLocationSection.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubheader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubheader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubsection.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubsection.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfPathnameRecord.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfPathnameRecord.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfToc.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfToc.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfTocEntry.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfTocEntry.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/spot/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/spot/ossimSpotDimapSupportData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/spot/ossimSpotDimapSupportData.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/srtm/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmFilename.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmFilename.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmSupportData.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmSupportData.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/tiff/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/tiff/ossimGeoTiff.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/tiff/ossimGeoTiff.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/tiff/ossimTiffWorld.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/tiff/ossimTiffWorld.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemGrid.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemGrid.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemPoint.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemPoint.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemProfile.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemProfile.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemStats.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemStats.h
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemUtil.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemUtil.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/vec/shape/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/vec/shape/dbfopen.c
 create mode 100644 Utilities/OSSIM/ossim_core/vec/shape/ossimShapeDatabase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/shape/ossimShapeDatabase.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/shape/ossimShapeFile.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/shape/ossimShapeFile.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/shape/shapefil.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/shape/shpopen.c
 create mode 100644 Utilities/OSSIM/ossim_core/vec/shape/shptree.c
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfBoundingRecordTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfBoundingRecordTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfCoverage.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfCoverage.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabase.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabase.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeader.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeader.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeaderTableValidator.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeaderTableValidator.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfExtent.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfExtent.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClass.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClass.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClassSchema.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClassSchema.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibrary.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibrary.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibraryAttributeTableValidator.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibraryAttributeTableValidator.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTable.cpp
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTable.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTableValidator.h
 create mode 100644 Utilities/OSSIM/ossim_core/vec/vpf/vpf.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/.cvsignore
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/CMakeLists.txt
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/bitarray.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/distance.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/linklist.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/linklist.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/machine.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/mapgraph.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/polygrf.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/polygrf.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/projectn.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/protomas.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/set.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/set.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/system.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/values.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfclip.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfcntnt.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfdict.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfinit.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfio.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfnear.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfprim.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfprim.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfptply.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfquery.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfread.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfrelat.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfrelat.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfselec.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfselec.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfspx.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpftable.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpftable.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpftidx.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpftidx.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfview.h
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/vpfwrite.c
 create mode 100644 Utilities/OSSIM/ossim_core/vpf_util/xmemory.h

diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt
index 696564fbc9..fc5cf89183 100755
--- a/Utilities/CMakeLists.txt
+++ b/Utilities/CMakeLists.txt
@@ -4,7 +4,7 @@ IF(NOT OTB_USE_EXTERNAL_ITK)
 	SUBDIRS( ITK )
 ENDIF(NOT OTB_USE_EXTERNAL_ITK)
 
-SUBDIRS( BGL otbsvm )
+SUBDIRS( BGL otbsvm OSSIM)
 
 IF(BUILD_TESTING)
         SUBDIRS( Dart )
diff --git a/Utilities/OSSIM/.CMakeLists.txt.swp b/Utilities/OSSIM/.CMakeLists.txt.swp
new file mode 100644
index 0000000000000000000000000000000000000000..ab1e1d707a050a51dc937442d53ac7b12159fc25
GIT binary patch
literal 12288
zcmeI2KX21O7{=c+(SbjLFJJ-^&OjWfgb-VDzBDGbFY?(DOjcsM&9#nQH5Um9ff)D(
zEDTJ18@5h-3<N6+yiUS^+oa6Z`$~^2>)z*{^Ut@~x=DNFc*fJ#9$?)D`1<iXfB60v
zjGh4;Epn9=)xh>DvRS#kV>SA2HK8Sf9v6>7A>6KbX_b0niLh%$TIEWsY;FlD9nWIk
z_&9UbT+dtjwf>*^sfP#<fvp6hy(f>`_Z#<&yLY0kjWkFEhyW2F0z`la5CI}U1c<=Z
zBcM-q;5R<jH57jS!_HcGp&|lAfCvx)B0vO)01+SpM1Tko0U|&It_Xo~3edg*@Bvl*
z0I2=}{JaJ51N9B{1y!J)qpqXQZUTHp9ibFzfZ9c!q5so*9$n2vMFfZd5g-CYfCvx)
zB0vO)01+Sp05a;@P9V*4K3B6isoj>RSrZ(exslCd?BgsHfy1Tw;0>OWj=PTE30_qL
zZ_k~XZo;mys>^$q;jAnU)M0Dd1Sb5RvmXUK?l~@BXGswSY`KW@S^xN3ssPDDb9r<-
z?ssG?hTM<Ce!x4nG}=u7*5_;x|9!41M4F8>KS+w!v|%u>GvH_(VVc`xe%!|;UF4XJ
z^Sn%I7O&&Ff^GDqlM7vT_YxnjP3N^JTwCaFOghYTd7^8UeIANoxY4sH@Q{02^F+QQ
tLwlnqRi{}|&#Cr`zsy-vHrX^wj-4XO7ird0IqoYM2I2+osMVWl!XL0Z@uL6$

literal 0
HcmV?d00001

diff --git a/Utilities/OSSIM/CMakeLists.txt b/Utilities/OSSIM/CMakeLists.txt
new file mode 100644
index 0000000000..dd9b42f9e5
--- /dev/null
+++ b/Utilities/OSSIM/CMakeLists.txt
@@ -0,0 +1,16 @@
+PROJECT(OSSIM)
+
+INCLUDE(CheckIncludeFile)
+CHECK_INCLUDE_FILES("dirent.h" CMAKE_HAVE_DIRENT_H)
+CHECK_INCLUDE_FILES("unistd.h" CMAKE_HAVE_UNISTD_H)
+CHECK_INCLUDE_FILES("getopt.h" CMAKE_HAVE_GETOPT_H)
+CHECK_INCLUDE_FILES("fcntl.h" CMAKE_HAVE_FCNTL_H)
+CHECK_INCLUDE_FILES("dbmalloc.h" CMAKE_HAVE_DBMALLOC_H)
+CHECK_INCLUDE_FILES("malloc.h" CMAKE_HAVE_MALLOC_H)
+CHECK_INCLUDE_FILES("dlfcn.h" CMAKE_HAVE_DLFCN_H)
+
+SET(OSSIM_HAS_OPEN_THREADS 0)
+CONFIGURE_FILE(${OTB_SOURCE_DIR}/Utilities/OSSIM/ossimConfig.h.in
+	       ${OTB_BINARY_DIR}/Utilities/OSSIM/ossimConfig.h)
+INCLUDE_DIRECTORIES(${OTB_BINARY_DIR}/Utilities/OSSIM/)
+SUBDIRS(ossim_core)
diff --git a/Utilities/OSSIM/ossimConfig.h.in b/Utilities/OSSIM/ossimConfig.h.in
new file mode 100644
index 0000000000..144748e4a5
--- /dev/null
+++ b/Utilities/OSSIM/ossimConfig.h.in
@@ -0,0 +1,125 @@
+/*  $Id: ossimConfig.h.in,v 1.23 2005/11/09 19:30:09 gpotts Exp $ */
+#ifndef ossimConfig_HEADER
+#define ossimConfig_HEADER
+
+/* Define if you have dirent.h.  */
+#cmakedefine CMAKE_HAVE_DIRENT_H
+#ifdef CMAKE_HAVE_DIRENT_H
+#define HAVE_DIRENT_H 1
+#else
+#define HAVE_DIRENT_H 0
+#endif
+
+/* Define as 1 if you have unistd.h.  */
+#cmakedefine CMAKE_HAVE_UNISTD_H
+#ifdef CMAKE_HAVE_UNISTD_H 
+#define HAVE_UNISTD_H 1
+#else
+#define HAVE_UNISTD_H 0
+#endif
+
+/* Define as 1 if you have getopt.h.  */
+#cmakedefine CMAKE_HAVE_GETOPT_H
+#ifdef CMAKE_HAVE_GETOPT_H 
+#define HAVE_GETOPT_H 1
+#else
+#define HAVE_GETOPT_H 0
+#endif
+
+/* Define as 1 if you have fcntl.h.  */
+#cmakedefine CMAKE_HAVE_FCNTL_H
+#ifdef CMAKE_HAVE_FCNTL_H
+#define HAVE_FCNTL_H 1
+#else
+#define HAVE_FCNTL_H 0
+#endif
+
+/* Define as 1 if you have dbmalloc.h.  */
+#cmakedefine CMAKE_HAVE_DBMALLOC_H
+#ifdef CMAKE_HAVE_DBMALLOC_H
+#define HAVE_DBMALLOC_H 1
+#else
+#define  HAVE_DBMALLOC_H 0
+#endif
+
+/* Define as 1 if you have malloc.h.  */
+#cmakedefine CMAKE_HAVE_MALLOC_H
+#ifdef CMAKE_HAVE_MALLOC_H
+#define HAVE_MALLOC_H 1
+#else
+#define HAVE_MALLOC_H 0
+
+#endif
+
+/* Define as 1 if you have dlfcn.h. */
+#cmakedefine CMAKE_HAVE_DLFCN_H
+#ifdef CMAKE_HAVE_DLFCN_H
+#define HAVE_DLFCN_H 1
+#else 
+#define HAVE_DLFCN_H 0
+#endif
+
+/* Define if you have support for large (64 bit size) files */
+#define HAVE_LARGEFILE_SUPPORT 0
+
+/* Define to "1" if you have libz installed, "0" if not. */
+#define OSSIM_HAS_LIBZ 0
+
+/* Define to "1" if you have MPI(lam/mpi), "0" if not. */
+#define OSSIM_HAS_MPI 0
+
+/* Define to "1" if you have FREETYPE, "0" if not. */
+#define OSSIM_HAS_FREETYPE 0
+
+/* Define to "1" if you have GEOTIFF, "0" if not. */
+#define OSSIM_HAS_GEOTIFF 0
+
+/* Define to "1" if you have OpenThreads for mutex support, "0" if not. */
+#define OSSIM_HAS_OPEN_THREADS 0
+
+/* Enable cvs id strings for use with "ident" application. */
+#define OSSIM_ID_ENABLED 1
+
+/* Enable dynamic library support for plugins.
+ * Usually set to 0 for static applications.
+ */
+#define OSSIM_DYNAMIC_ENABLED 1
+
+/* Define to the correct byte sizes.  
+ * If not available define to 0 so OSSIM uses the defaults
+ */
+#define OSSIM_SIZEOF_FLOAT      0
+#define OSSIM_SIZEOF_DOUBLE     0
+#define OSSIM_SIZEOF_LONG_LONG  0
+#define OSSIM_SIZEOF_LONG_INT   0
+#define OSSIM_SIZEOF_INT        0
+#define OSSIM_SIZEOF_SHORT_INT  0
+
+/* These are OS specific defines */
+#define __OSSIM_LINUX__ 0
+#define __OSSIM_DARWIN__ 0
+#define __OSSIM_ALPHA__ 0
+#define __OSSIM_SGI__ 0
+#define __OSSIM_SUN__ 0
+#define __OSSIM_SUNOS__ 0
+#define __OSSIM_SOLARIS__ 0
+#define __OSSIM_FREEBSD__ 0
+#define __OSSIM_BSD__ 0
+#define __OSSIM_OPENBSD__ 0
+#define __OSSIM_NETBSD__ 0
+#define __OSSIM_OSF__ 0
+#define __OSSIM_SYSV__ 0
+#define __OSSIM_AIX__ 0
+#define __OSSIM_DOS__ 0
+#define __OSSIM_POWERPC__ 0
+#define __OSSIM_BEOS__ 0
+#define __OSSIM_SVR4__ 0
+#define __OSSIM_EMX__ 0
+#define __OSSIM_CYGWIN__ 0
+
+#define OSSIM_MAJOR_VERSION_NUMBER @OSSIM_MAJOR_VERSION_NUMBER@
+#define OSSIM_MINOR_VERSION_NUMBER @OSSIM_MINOR_VERSION_NUMBER@
+#define OSSIM_RELEASE_NUMBER @OSSIM_RELEASE_NUMBER@
+#define OSSIM_VERSION @OSSIM_VERSION@
+
+#endif /* End of "#ifndef ossimConfig_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/.cvsignore b/Utilities/OSSIM/ossim_core/.cvsignore
new file mode 100644
index 0000000000..7761c4d2a3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+ossimConfig.h
diff --git a/Utilities/OSSIM/ossim_core/CMakeLists.txt b/Utilities/OSSIM/ossim_core/CMakeLists.txt
new file mode 100644
index 0000000000..e99ceabf33
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/CMakeLists.txt
@@ -0,0 +1,72 @@
+# Commented since we choosed to build one single library to compile ossim
+#SUBDIRS(base elevation fonts imaging libpolyclip matrix parallel projections support_data vec vpf_util plugin init)
+
+FILE(GLOB_RECURSE ossim_base_SRCS "base/*.cpp" "base/*.c")
+FILE(GLOB_RECURSE ossim_base_HDRS "base/*.h")
+
+FILE(GLOB_RECURSE ossim_elevation_SRCS "elevation/*.cpp" "elevation/*.c")
+FILE(GLOB_RECURSE ossim_elevation_HDRS "elevation/*.h")
+
+FILE(GLOB_RECURSE ossim_fonts_SRCS "fonts/*.cpp" "fonts/*.c")
+FILE(GLOB_RECURSE ossim_fonts_HDRS "fonts/*.h")
+
+FILE(GLOB_RECURSE ossim_imaging_SRCS "imaging/*.cpp" "imaging/*.c")
+FILE(GLOB_RECURSE ossim_imaging_HDRS "imaging/*.h")
+
+FILE(GLOB_RECURSE ossim_libpolyclip_SRCS "libpolyclip/*.cpp" "libpolyclip/*.c")
+FILE(GLOB_RECURSE ossim_libpolyclip_HDRS "libpolyclip/*.h")
+
+FILE(GLOB_RECURSE ossim_matrix_SRCS "matrix/*.cpp" "matrix/*.c")
+FILE(GLOB_RECURSE ossim_matrix_HDRS "matrix/*.h")
+
+FILE(GLOB_RECURSE ossim_parallel_SRCS "parallel/*.cpp" "parallel/*.c")
+FILE(GLOB_RECURSE ossim_parallel_HDRS "parallel/*.h")
+
+FILE(GLOB_RECURSE ossim_projections_SRCS "projections/*.cpp" "projections/*.c")
+FILE(GLOB_RECURSE ossim_projections_HDRS "projections/*.h")
+
+FILE(GLOB_RECURSE ossim_support_data_SRCS "support_data/*.cpp" "support_data/*.c")
+FILE(GLOB_RECURSE ossim_suport_data_HDRS "support_data/*.h")
+
+FILE(GLOB_RECURSE ossim_vec_SRCS "vec/*.cpp" "vec/*.c")
+FILE(GLOB_RECURSE ossim_vec_HDRS "vec/*.h")
+
+FILE(GLOB_RECURSE ossim_vpf_util_SRCS "vpf_util/*.cpp" "vpf_util/*.c")
+FILE(GLOB_RECURSE ossim_vpf_util_HDRS "vpf_util/*.h")
+
+FILE(GLOB_RECURSE ossim_plugin_SRCS "plugin/*.cpp" "plugin/*.c")
+FILE(GLOB_RECURSE ossim_plugin_HDRS "plugin/*.h")
+
+FILE(GLOB_RECURSE ossim_init_SRCS "init/*.cpp" "init/*.c")
+FILE(GLOB_RECURSE ossim_init_HDRS "init/*.h")
+
+ADD_LIBRARY(ossim 
+${ossim_base_SRCS}
+${ossim_elevation_SRCS}
+${ossim_fonts_SRCS}
+${ossim_imaging_SRCS}
+${ossim_libpolyclip_SRCS}
+${ossim_matrix_SRCS}
+${ossim_parallel_SRCS}
+${ossim_projections_SRCS}
+${ossim_support_data_SRCS}
+${ossim_vec_SRCS}
+${ossim_vpf_util_SRCS}
+${ossim_plugin_SRCS}
+${ossim_init_SRCS}
+)
+
+INSTALL_TARGETS(/lib/otb/ ossim)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_base_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_elevation_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_fonts_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_imaging_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_libpolyclip_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_matrix_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_parallel_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_projections_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_support_data_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_vec_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_vpf_util_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_plugin_HRDS})
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_init_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/base/CMakeLists.txt b/Utilities/OSSIM/ossim_core/base/CMakeLists.txt
new file mode 100644
index 0000000000..631a7a4cf0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_base_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_base_HDRS "*.h")
+ADD_LIBRARY(ossim_base ${ossim_base_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_base)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_base_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/base/common/.cvsignore b/Utilities/OSSIM/ossim_core/base/common/.cvsignore
new file mode 100644
index 0000000000..3c14b4e6ae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+*.lo
+.libs
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/.cvsignore b/Utilities/OSSIM/ossim_core/base/common/events/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableDisplayListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableDisplayListener.cpp
new file mode 100644
index 0000000000..9ceeab39ba
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableDisplayListener.cpp
@@ -0,0 +1,179 @@
+
+//----------------------------------------------------------------------------
+// Copyright (c) 2004, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description: 
+//
+//----------------------------------------------------------------------------
+// $Id: ossimConnectableDisplayListener.cpp,v 1.1 2005/09/11 19:57:50 dburken Exp $
+
+#include <base/common/events/ossimConnectableDisplayListener.h>
+#include <base/common/ossimConnectableObject.h>
+#include <base/common/events/ossimObjectEvents.h>
+#include <base/common/events/ossimDisplayListEvent.h>
+#include <base/common/events/ossimDisplayRefreshEvent.h>
+
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimConnectableDisplayListener,
+          "ossimConnectableDisplayListener",
+          ossimListener);
+
+ossimConnectableDisplayListener::ossimConnectableDisplayListener()
+   : ossimListener()
+{}
+
+void ossimConnectableDisplayListener::processEvent(ossimEvent& event)
+{
+   switch(event.getId())
+   {
+      case OSSIM_EVENT_OBJECT_DESTRUCTING_ID:
+      {
+         ossimObjectDestructingEvent* eventCast =
+            static_cast<ossimObjectDestructingEvent*>(&event);
+         objectDestructingEvent(*eventCast);
+         
+         break;
+      }
+      case OSSIM_EVENT_CONNECTION_CONNECT_ID:
+      case OSSIM_EVENT_CONNECTION_DISCONNECT_ID:
+      {
+         ossimConnectionEvent* eventCast =
+            static_cast<ossimConnectionEvent*>(&event);
+         
+         connectionEvent(*eventCast);
+         if(event.getId() == OSSIM_EVENT_CONNECTION_DISCONNECT_ID)
+         {
+            if(eventCast->isInputDirection())
+            {
+               disconnectInputEvent(*eventCast);
+            }
+            else if(eventCast->isOutputDirection())
+            {
+               disconnectOutputEvent(*eventCast);
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "ossimConnectableDisplayListener::processEvent, Direction not set\n";
+            }
+         }
+         else
+         {
+            ossimConnectionEvent* eventCast = static_cast<ossimConnectionEvent*>(&event);
+            
+            if(eventCast->isInputDirection())
+            {
+               connectInputEvent(*eventCast);
+            }
+            else if(eventCast->isOutputDirection())
+            {
+               connectOutputEvent(*eventCast);
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_WARN) << "ossimConnectableDisplayListener::processEvent, Direction not set\n";
+            }
+         }
+         break;
+      }
+      case OSSIM_EVENT_PROPERTY_ID:
+      {
+         ossimPropertyEvent* eventCast = static_cast<ossimPropertyEvent*>(&event);
+         propertyEvent(*eventCast);
+         break;
+      }
+      case OSSIM_EVENT_ADD_OBJECT_ID:
+      {
+         ossimContainerEvent* eventCast = static_cast<ossimContainerEvent*>(&event);
+         addObjectEvent(*eventCast);
+         break;
+      }
+      case OSSIM_EVENT_REMOVE_OBJECT_ID:
+      {
+         ossimContainerEvent* eventCast = static_cast<ossimContainerEvent*>(&event);
+         removeObjectEvent(*eventCast);
+         break;
+      }
+      case OSSIM_EVENT_REFRESH_ID:
+      {
+         ossimRefreshEvent* eventCast = static_cast<ossimRefreshEvent*>(&event);
+         refreshEvent(*eventCast);
+         break;
+      }
+      case OSSIM_EVENT_DISPLAY_LIST_ID:
+      {
+         ossimDisplayListEvent* eventCast =
+            static_cast<ossimDisplayListEvent*>(&event);
+         displayListEvent(*eventCast);
+         break;
+      }
+      case OSSIM_EVENT_DISPLAY_REFRESH_ID:
+      {
+         ossimDisplayRefreshEvent* eventCast =
+            static_cast<ossimDisplayRefreshEvent*>(&event);
+         displayRefreshEvent(*eventCast);
+         break;
+      }
+      default:
+      {
+         ossimListener::processEvent(event);
+         break;
+      }
+   }
+}
+
+void ossimConnectableDisplayListener::objectDestructingEvent(
+   ossimObjectDestructingEvent& /*event*/)
+{
+}
+
+void ossimConnectableDisplayListener::connectionEvent(
+   ossimConnectionEvent& /* event */)
+{}
+
+void ossimConnectableDisplayListener::disconnectInputEvent(
+   ossimConnectionEvent& /* event */)
+{}
+
+void ossimConnectableDisplayListener::disconnectOutputEvent(
+   ossimConnectionEvent& /* event */)
+{}
+
+void ossimConnectableDisplayListener::connectInputEvent(
+   ossimConnectionEvent& /* event */)
+{}
+
+void ossimConnectableDisplayListener::connectOutputEvent(
+   ossimConnectionEvent& /* event */)
+{}
+
+void ossimConnectableDisplayListener::propertyEvent(
+   ossimPropertyEvent& /* event */)
+{}
+
+void ossimConnectableDisplayListener::displayListEvent(ossimDisplayListEvent&)
+{}
+
+void ossimConnectableDisplayListener::displayRefreshEvent(
+   ossimDisplayRefreshEvent&)
+{}
+
+void ossimConnectableDisplayListener::addObjectEvent(
+   ossimContainerEvent& /* event */)
+{}
+
+void ossimConnectableDisplayListener::removeObjectEvent(
+   ossimContainerEvent& /* event */)
+{}
+
+void ossimConnectableDisplayListener::refreshEvent(
+   ossimRefreshEvent& /* event */)
+{}
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableDisplayListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableDisplayListener.h
new file mode 100644
index 0000000000..a4c0741e31
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableDisplayListener.h
@@ -0,0 +1,109 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2004, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description: ossimConnectableDisplayListener
+// 
+// This class is intended for connectable displays that wants to be a
+// ossimConnectableObjectListener and a ossimDisplayEventListener to avoid
+// a triangle inheritance.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimConnectableDisplayListener.h,v 1.1 2005/09/11 19:57:50 dburken Exp $
+
+#ifndef ossimConnectableDisplayListener_HEADER
+#define ossimConnectableDisplayListener_HEADER
+
+#include <base/common/events/ossimListener.h>
+
+class ossimConnectionEvent;
+class ossimObjectDestructingEvent;
+class ossimPropertyEvent;
+class ossimContainerEvent;
+class oossimDisplayListEvent;
+class ossimRefreshEvent;
+class ossimDisplayListEvent;
+class ossimDisplayRefreshEvent;
+
+/**
+ * This class is intended for connectable displays that wants to be a
+ * ossimConnectableObjectListener and a ossimDisplayEventListener to avoid
+ * a triangle inheritance.
+ */
+class OSSIMDLLEXPORT ossimConnectableDisplayListener : public ossimListener
+{
+public:
+
+   /** default constructor */
+   ossimConnectableDisplayListener();
+
+   /**
+    * Method called by listener managers.  This will in turn call the correct
+    * xxxEvent method.
+    *
+    * @param event Event to handle.
+    */
+   virtual void processEvent(ossimEvent& event);
+
+   /** @param event Event to handle signifying an object destroying. */
+   virtual void objectDestructingEvent(ossimObjectDestructingEvent& event);
+
+   /** @param event Event to handle signifying an object connecting. */
+   virtual void connectionEvent(ossimConnectionEvent& event);
+
+   /** @param event Event to handle signifying a disconnect input event. */
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+
+   /** @param event Event to handle signifying an output disconnect event. */
+   virtual void disconnectOutputEvent(ossimConnectionEvent& event);
+
+   /** @param event Event to handle signifying a connect input event. */
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+
+   /** @param event Event to handle signifying a connect  output event. */
+   virtual void connectOutputEvent(ossimConnectionEvent& event);
+
+   /**
+    * @param event Event to handle signifying a property has changed  event.
+    */
+   virtual void propertyEvent(ossimPropertyEvent& event);
+
+   /**
+    * @param event Event to handle signifying a dislay list  has changed
+    * event.
+    */
+   virtual void displayListEvent(ossimDisplayListEvent&);
+
+   /**
+    * @param event Event to handle signifying a dislay refresh
+    * is needed.
+    */
+   virtual void displayRefreshEvent(ossimDisplayRefreshEvent&);
+
+   /**
+    * @param event Event to handle signifying a refresh is needed.
+    */
+   virtual void refreshEvent(ossimRefreshEvent& event);
+
+   /**
+    * Container Events:
+    * Typically isued by objects that contain children.  If anyone is
+    * interested, can latch on to this event.  Other objects within the
+    * system might be interest in this event even 
+    */
+
+   /** @param event Event signifying an object was added to a container. */
+   virtual void addObjectEvent(ossimContainerEvent& event);
+
+   /** @param event Event signifying an object was removed from a container. */
+   virtual void removeObjectEvent(ossimContainerEvent& event);
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableObjectListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableObjectListener.cpp
new file mode 100644
index 0000000000..073e94e1e0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableObjectListener.cpp
@@ -0,0 +1,102 @@
+//*******************************************************************
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimConnectableObjectListener.cpp,v 1.15 2005/09/17 20:29:37 dburken Exp $
+
+#include <base/common/events/ossimConnectableObjectListener.h>
+#include <base/common/ossimConnectableObject.h>
+#include <base/common/events/ossimObjectEvents.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimConnectableObjectListener,
+          "ossimConnectableObjectListener",
+          ossimListener);
+
+void ossimConnectableObjectListener::processEvent(ossimEvent& event)
+{
+   switch(event.getId())
+   {
+      case OSSIM_EVENT_OBJECT_DESTRUCTING_ID:
+      {
+         ossimObjectDestructingEvent* eventCast = static_cast<ossimObjectDestructingEvent*>(&event);
+         objectDestructingEvent(*eventCast);
+         
+         break;
+      }
+      case OSSIM_EVENT_CONNECTION_CONNECT_ID:
+      case OSSIM_EVENT_CONNECTION_DISCONNECT_ID:
+      {
+         ossimConnectionEvent* eventCast = static_cast<ossimConnectionEvent*>(&event);
+         
+         connectionEvent(*eventCast);
+         if(event.getId() == OSSIM_EVENT_CONNECTION_DISCONNECT_ID)
+         {
+            if(eventCast->isInputDirection())
+            {
+               disconnectInputEvent(*eventCast);
+            }
+            else if(eventCast->isOutputDirection())
+            {
+               disconnectOutputEvent(*eventCast);
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_WARN) << "ossimConnectableObjectListener::processEvent, Direction not set\n";
+            }
+         }
+         else
+         {
+            ossimConnectionEvent* eventCast = static_cast<ossimConnectionEvent*>(&event);
+            
+            if(eventCast->isInputDirection())
+            {
+               connectInputEvent(*eventCast);
+            }
+            else if(eventCast->isOutputDirection())
+            {
+               connectOutputEvent(*eventCast);
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_WARN) << "ossimConnectableObjectListener::processEvent, Direction not set\n";
+            }
+         }
+         break;
+      }
+      case OSSIM_EVENT_PROPERTY_ID:
+      {
+         ossimPropertyEvent* eventCast = static_cast<ossimPropertyEvent*>(&event);
+         propertyEvent(*eventCast);
+         break;
+      }
+      case OSSIM_EVENT_ADD_OBJECT_ID:
+      {
+         ossimContainerEvent* eventCast = static_cast<ossimContainerEvent*>(&event);
+         addObjectEvent(*eventCast);
+         break;
+      }
+      case OSSIM_EVENT_REMOVE_OBJECT_ID:
+      {
+         ossimContainerEvent* eventCast = static_cast<ossimContainerEvent*>(&event);
+         removeObjectEvent(*eventCast);
+         break;
+      }
+      case OSSIM_EVENT_REFRESH_ID:
+      {
+         ossimRefreshEvent* eventCast = static_cast<ossimRefreshEvent*>(&event);
+         refreshEvent(*eventCast);
+         break;
+      }
+      default:
+      {
+         ossimListener::processEvent(event);
+         break;
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableObjectListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableObjectListener.h
new file mode 100644
index 0000000000..a6d2fc3767
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectableObjectListener.h
@@ -0,0 +1,75 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimConnectableObjectListener.h,v 1.19 2005/10/13 13:30:33 gpotts Exp $
+#ifndef ossimConnectableObjectListener_HEADER
+#define ossimConnectableObjectListener_HEADER
+
+#include "ossimListener.h"
+#include "ossimConnectionEvent.h"
+#include "ossimObjectDestructingEvent.h"
+#include "ossimPropertyEvent.h"
+#include "ossimContainerEvent.h"
+#include "ossimRefreshEvent.h"
+
+class OSSIMDLLEXPORT ossimConnectableObjectListener : public ossimListener
+{
+public:
+   ossimConnectableObjectListener():ossimListener(){}
+   virtual ~ossimConnectableObjectListener(){}
+
+   virtual void processEvent(ossimEvent& event);
+
+   virtual void objectDestructingEvent(ossimObjectDestructingEvent& /*event*/)
+      {}
+   virtual void connectionEvent(ossimConnectionEvent& /* event */)
+      {}
+   virtual void disconnectInputEvent(ossimConnectionEvent& /* event */)
+      {}
+   virtual void disconnectOutputEvent(ossimConnectionEvent& /* event */)
+      {}
+   virtual void connectInputEvent(ossimConnectionEvent& /* event */)
+      {}
+   virtual void connectOutputEvent(ossimConnectionEvent& /* event */)
+      {}
+
+   virtual void propertyEvent(ossimPropertyEvent& /* event */)
+      {}
+
+   /*!
+    * Typically isued by objects that contain children.  If anyone is
+    * interested, can latch on to this event.  Other objects within the
+    * system might be interest in this event even 
+    */
+   virtual void addObjectEvent(ossimContainerEvent& /* event */)
+      {}
+
+   virtual void removeObjectEvent(ossimContainerEvent& /* event */)
+      {}
+
+   virtual void refreshEvent(ossimRefreshEvent& /* event */)
+      {}
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectionEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectionEvent.cpp
new file mode 100644
index 0000000000..edefd4986f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectionEvent.cpp
@@ -0,0 +1,127 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimConnectionEvent.cpp,v 1.3 2005/09/17 20:27:50 dburken Exp $
+
+#include <base/common/events/ossimConnectionEvent.h>
+
+RTTI_DEF1(ossimConnectionEvent, "ossimConnectionEvent", ossimEvent);
+
+ossimConnectionEvent::ossimConnectionEvent(ossimObject* object, long id)
+   :ossimEvent(object, id),
+    theDirectionType(OSSIM_DIRECTION_UNKNOWN)
+{
+}
+
+ossimConnectionEvent::ossimConnectionEvent(
+   ossimObject* object,
+   long id,
+   const vector<ossimConnectableObject*>& newList,
+   const vector<ossimConnectableObject*>& oldList,
+   ossimConnectionDirectionType whichDirection)
+   : ossimEvent(object, id),
+     theNewObjectList(newList),
+     theOldObjectList(oldList),
+     theDirectionType(whichDirection)
+{
+}
+
+ossimConnectionEvent::ossimConnectionEvent(
+   ossimObject* object,
+   long id,
+   ossimConnectableObject* newConnectableObject,
+   ossimConnectableObject* oldConnectableObject,
+   ossimConnectionDirectionType whichDirection)
+   : ossimEvent(object, id),
+     theDirectionType(whichDirection)
+{
+   if(newConnectableObject)
+   {
+      theNewObjectList.push_back(newConnectableObject);
+   }
+   if(oldConnectableObject)
+   {
+      theOldObjectList.push_back(oldConnectableObject);
+   }
+}
+   
+ossimConnectionEvent::ossimConnectionEvent(const ossimConnectionEvent& rhs)
+   : ossimEvent(rhs),
+     theNewObjectList(rhs.theNewObjectList),
+     theOldObjectList(rhs.theOldObjectList),
+     theDirectionType(rhs.theDirectionType)
+{
+}
+
+ossimObject* ossimConnectionEvent::dup()const
+{
+   return new ossimConnectionEvent(*this);
+}
+
+void ossimConnectionEvent::setDirection(
+   ossimConnectionDirectionType direction)
+{
+   theDirectionType   = direction;
+}
+
+ossimConnectionEvent::ossimConnectionDirectionType ossimConnectionEvent::getDirection()const
+{
+   return theDirectionType;
+}
+
+ossim_uint32 ossimConnectionEvent::getNumberOfNewObjects()const
+{
+   return theNewObjectList.size();
+}
+
+ossim_uint32 ossimConnectionEvent::getNumberOfOldObjects()const
+{
+   return theOldObjectList.size();
+}
+
+ossimConnectableObject* ossimConnectionEvent::getOldObject(ossim_uint32 i)const
+{
+   if(i < getNumberOfOldObjects())
+   {
+      return theOldObjectList[i];
+   }
+   
+   return (ossimConnectableObject*)NULL;
+}
+
+ossimConnectableObject* ossimConnectionEvent::getNewObject(ossim_uint32 i)const
+{
+   if(i < getNumberOfNewObjects())
+   {
+      return theNewObjectList[i];
+   }
+   
+   return (ossimConnectableObject*)NULL;
+}
+
+bool ossimConnectionEvent::isDisconnect()const
+{
+   return (getId()==OSSIM_EVENT_CONNECTION_DISCONNECT_ID);
+}
+
+bool ossimConnectionEvent::isConnect()const
+{
+   return (getId()==OSSIM_EVENT_CONNECTION_CONNECT_ID);
+}
+
+bool ossimConnectionEvent::isInputDirection()const
+{
+   return ((long)theDirectionType  & (long)OSSIM_INPUT_DIRECTION);
+}
+
+bool ossimConnectionEvent::isOutputDirection()const
+{
+   return ((long)theDirectionType & OSSIM_OUTPUT_DIRECTION);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectionEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectionEvent.h
new file mode 100644
index 0000000000..6fedc269a1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimConnectionEvent.h
@@ -0,0 +1,76 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+//*************************************************************************
+// $Id: ossimConnectionEvent.h,v 1.12 2005/09/17 20:27:50 dburken Exp $
+#ifndef ossimConnectionEvent_HEADER
+#define ossimConnectionEvent_HEADER
+#include <base/common/events/ossimEventIds.h>
+#include <base/common/events/ossimEvent.h>
+#include <base/common/ossimConnectableObject.h>
+
+class OSSIMDLLEXPORT ossimConnectionEvent : public ossimEvent
+{
+public:
+   enum ossimConnectionDirectionType
+   {
+      OSSIM_DIRECTION_UNKNOWN  = 0,
+      OSSIM_INPUT_DIRECTION    = 1,
+      OSSIM_OUTPUT_DIRECTION   = 2,
+      OSSIM_INPUT_OUTPUT_DIRECTION = 3
+   };
+   
+   ossimConnectionEvent(ossimObject* object=NULL,
+                        long id=OSSIM_EVENT_NULL_ID);
+
+   ossimConnectionEvent(ossimObject* object,
+                        long id,
+                        const vector<ossimConnectableObject*>& newList,
+                        const vector<ossimConnectableObject*>& oldList,
+                        ossimConnectionDirectionType whichDirection);
+
+   ossimConnectionEvent(ossimObject* object,
+                        long id,
+                        ossimConnectableObject* newConnectableObject,
+                        ossimConnectableObject* oldConnectableObject,
+                        ossimConnectionDirectionType whichDirection);
+   
+   ossimConnectionEvent(const ossimConnectionEvent& rhs);
+
+   ossimObject* dup()const;
+   
+   virtual void setDirection(ossimConnectionDirectionType direction);
+   
+   virtual ossimConnectionDirectionType getDirection()const;
+
+   virtual ossim_uint32 getNumberOfNewObjects()const;
+   
+   virtual ossim_uint32 getNumberOfOldObjects()const;
+   
+   virtual ossimConnectableObject* getOldObject(ossim_uint32 i=0)const;
+
+   virtual ossimConnectableObject* getNewObject(ossim_uint32 i=0)const;
+
+   virtual bool isDisconnect()const;
+   
+   virtual bool isConnect()const;
+      
+   virtual bool isInputDirection()const;
+   
+   virtual bool isOutputDirection()const;
+   
+protected:
+   vector<ossimConnectableObject*> theNewObjectList;
+   vector<ossimConnectableObject*> theOldObjectList;
+   ossimConnectionDirectionType theDirectionType;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimContainerEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimContainerEvent.cpp
new file mode 100644
index 0000000000..90382ff8a3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimContainerEvent.cpp
@@ -0,0 +1,38 @@
+//*******************************************************************
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimContainerEvent.cpp,v 1.1 2005/09/17 20:25:33 dburken Exp $
+
+#include <base/common/events/ossimContainerEvent.h>
+
+RTTI_DEF1(ossimContainerEvent, "ossimContainerEvent", ossimEvent);
+
+ossimContainerEvent::ossimContainerEvent(ossimObject* obj1,
+                                         ossimObject* obj2,
+                                         long id)
+   :
+   ossimEvent(obj1, id),
+   theAssociatedObject(obj2)
+{
+}
+
+ossimObject* ossimContainerEvent::getAssociatedObject()
+{
+   return theAssociatedObject;
+}
+
+const ossimObject* ossimContainerEvent::getAssociatedObject()const
+{
+   return theAssociatedObject;
+}
+
+void ossimContainerEvent::setAssociatedObject(ossimObject* obj)
+{
+   theAssociatedObject = obj;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimContainerEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimContainerEvent.h
new file mode 100644
index 0000000000..fb6fc2f503
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimContainerEvent.h
@@ -0,0 +1,41 @@
+//*******************************************************************
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimContainerEvent.h,v 1.3 2005/09/17 20:25:13 dburken Exp $
+#ifndef ossimContainerEvent_HEADER
+#define ossimContainerEvent_HEADER
+#include <base/common/events/ossimEvent.h>
+#include <base/common/events/ossimEventIds.h>
+
+class OSSIMDLLEXPORT ossimContainerEvent : public ossimEvent
+{
+public:
+
+   /** constuctor */
+   ossimContainerEvent(ossimObject* obj1,// the object theEvent was sent to.
+                       ossimObject* obj2, // the object associated 
+                       long id);
+
+   ossimObject* getAssociatedObject();
+   const ossimObject* getAssociatedObject()const;
+   void setAssociatedObject(ossimObject* obj);
+   
+protected:
+   
+   /*!
+    * This is the object associated with the container event.
+    * if this was an add then it s the object added to the
+    * container.
+    */
+   ossimObject* theAssociatedObject;
+
+TYPE_DATA
+};
+
+#endif /* end of: "#ifndef ossimContainerEvent_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayEventListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayEventListener.cpp
new file mode 100644
index 0000000000..80059e1dc1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayEventListener.cpp
@@ -0,0 +1,62 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id
+
+#include "ossimDisplayEventListener.h"
+#include "ossimDisplayListEvent.h"
+#include "ossimDisplayRefreshEvent.h"
+
+RTTI_DEF1(ossimDisplayEventListener, "ossimDisplayEventListener", ossimListener);
+
+ossimDisplayEventListener::ossimDisplayEventListener()
+   : ossimListener()
+{
+}
+
+ossimDisplayEventListener::~ossimDisplayEventListener()
+{
+}
+
+void ossimDisplayEventListener::processEvent(ossimEvent& event)
+{
+   ossimDisplayListEvent* displayListEvtPtr = PTR_CAST(ossimDisplayListEvent, &event);
+
+   if(displayListEvtPtr)
+   {
+      displayListEvent(*displayListEvtPtr);
+   }
+
+   ossimDisplayRefreshEvent* displayRefreshEvt = PTR_CAST(ossimDisplayRefreshEvent, &event);
+   if(displayRefreshEvt)
+   {
+      displayRefreshEvent(*displayRefreshEvt);
+   }
+   
+}
+
+void ossimDisplayEventListener::displayListEvent(ossimDisplayListEvent&)
+{
+}
+
+void ossimDisplayEventListener::displayRefreshEvent(ossimDisplayRefreshEvent&)
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayEventListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayEventListener.h
new file mode 100644
index 0000000000..6a6ea630f0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayEventListener.h
@@ -0,0 +1,43 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id
+#ifndef ossimDisplayEventListener_HEADER
+#define ossimDisplayEventListener_HEADER
+
+#include "ossimListener.h"
+
+class ossimDisplayListEvent;
+class ossimDisplayRefreshEvent;
+
+class OSSIMDLLEXPORT ossimDisplayEventListener : public ossimListener
+{
+public:
+   ossimDisplayEventListener();
+   virtual ~ossimDisplayEventListener();
+   virtual void processEvent(ossimEvent& event);
+   virtual void displayListEvent(ossimDisplayListEvent&);
+   virtual void displayRefreshEvent(ossimDisplayRefreshEvent&);
+
+TYPE_DATA
+};
+
+#endif /* End of "#ifndef ossimDisplayEventListener_HEADER". */
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayListEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayListEvent.cpp
new file mode 100644
index 0000000000..416e517149
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayListEvent.cpp
@@ -0,0 +1,44 @@
+#include "ossimDisplayListEvent.h"
+
+RTTI_DEF1(ossimDisplayListEvent, "ossimDisplayListEvent", ossimEvent);
+
+void ossimDisplayListEvent::addDisplay(void* display)
+{
+   std::map<void*, void*>::iterator iter = theDisplayMap.find(display);
+
+   if(iter == theDisplayMap.end())
+   {
+      theDisplayMap.insert(std::make_pair(display, display));
+   }
+}
+
+void* ossimDisplayListEvent::firstDisplay()
+{
+   theDisplayIterator = theDisplayMap.begin();
+
+   if(theDisplayIterator != theDisplayMap.end())
+   {
+      return (*theDisplayIterator).first;
+   }
+
+   return NULL;
+}
+
+void* ossimDisplayListEvent::nextDisplay()
+{
+   ++theDisplayIterator;
+
+   if(theDisplayIterator != theDisplayMap.end())
+   {
+      return (*theDisplayIterator).first;
+   }
+
+   return NULL;
+}
+
+void ossimDisplayListEvent::clearList()
+{
+   theDisplayMap.clear();
+   theDisplayIterator = theDisplayMap.end();
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayListEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayListEvent.h
new file mode 100644
index 0000000000..2d5290ca1f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayListEvent.h
@@ -0,0 +1,32 @@
+#ifndef ossimDisplayListEvent_HEADER
+#define ossimDisplayListEvent_HEADER
+#include "ossimEvent.h"
+#include <map>
+
+class OSSIMDLLEXPORT ossimDisplayListEvent : public ossimEvent
+{
+public:
+   ossimDisplayListEvent(ossimObject* obj = NULL)
+      :ossimEvent(obj, OSSIM_EVENT_DISPLAY_LIST_ID)
+      {
+         theDisplayIterator = theDisplayMap.end();
+      }
+   void addDisplay(void* display);
+   virtual ossimObject* dup()const
+  {
+    return new ossimDisplayListEvent(*this);
+  }
+   
+   void* firstDisplay();
+   void* nextDisplay();
+   void  clearList();
+   
+protected:
+   std::map<void*, void*> theDisplayMap;
+   std::map<void*, void*>::iterator theDisplayIterator;
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayRefreshEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayRefreshEvent.cpp
new file mode 100644
index 0000000000..b0e75ce497
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayRefreshEvent.cpp
@@ -0,0 +1,2 @@
+#include "ossimDisplayRefreshEvent.h"
+RTTI_DEF1(ossimDisplayRefreshEvent, "ossimDisplayRefreshEvent", ossimEvent);
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayRefreshEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayRefreshEvent.h
new file mode 100644
index 0000000000..acd3c165a3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimDisplayRefreshEvent.h
@@ -0,0 +1,16 @@
+#ifndef ossimDisplayRefreshEvent_HEADER
+#define ossimDisplayRefreshEvent_HEADER
+#include "ossimEvent.h"
+#include <map>
+
+class OSSIMDLLEXPORT ossimDisplayRefreshEvent : public ossimEvent
+{
+public:
+   ossimDisplayRefreshEvent(ossimObject* obj = NULL)
+      :ossimEvent(obj, OSSIM_EVENT_DISPLAY_REFRESH_ID)
+      {}
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEvent.cpp
new file mode 100644
index 0000000000..f675f7e7ae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEvent.cpp
@@ -0,0 +1,3 @@
+#include "ossimElevationManagerEvent.h"
+
+RTTI_DEF1(ossimElevationManagerEvent, "ossimROIEvent", ossimEvent);
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEvent.h
new file mode 100644
index 0000000000..1c4ddaded1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEvent.h
@@ -0,0 +1,28 @@
+#ifndef ossimElevationManagerEvent_HEADER
+#define ossimElevationManagerEvent_HEADER
+
+#include "base/common/events/ossimEvent.h"
+
+class ossimObject;
+
+class OSSIMDLLEXPORT ossimElevationManagerEvent : public ossimEvent
+{
+ public:
+   ossimElevationManagerEvent( ossimObject* object=NULL,
+                                    long id=OSSIM_EVENT_NULL_ID )
+      : ossimEvent( object, id )
+      {
+      }
+   ossimElevationManagerEvent( const ossimElevationManagerEvent& rhs )
+      : ossimEvent( rhs )
+      {
+      }
+   virtual ossimObject* dup() const
+      {
+         return new ossimElevationManagerEvent( *this );
+      }
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEventListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEventListener.cpp
new file mode 100644
index 0000000000..1f522f9d46
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEventListener.cpp
@@ -0,0 +1,31 @@
+#include "ossimElevationManagerEventListener.h"
+#include "ossimElevationManagerEvent.h"
+
+RTTI_DEF1(ossimElevationManagerEventListener, "ossimElevationManagerEventListener",
+          ossimListener);
+
+ossimElevationManagerEventListener::ossimElevationManagerEventListener()
+      : ossimListener()
+{
+}
+
+
+ossimElevationManagerEventListener::~ossimElevationManagerEventListener()
+{
+}
+
+void ossimElevationManagerEventListener::processEvent( ossimEvent& event )
+{
+   ossimElevationManagerEvent* elevationManagerEvent =
+      PTR_CAST( ossimElevationManagerEvent, &event );
+
+   if ( elevationManagerEvent )
+   {
+      processEvent( *elevationManagerEvent );
+   }
+}
+
+void ossimElevationManagerEventListener::processEvent( ossimElevationManagerEvent& event )
+{
+
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEventListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEventListener.h
new file mode 100644
index 0000000000..dbdaf252fa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimElevationManagerEventListener.h
@@ -0,0 +1,18 @@
+#ifndef ossimElevationManagerEventListener_HEADER
+#define ossmiElevationManagerEventListener_HEADER
+
+#include "base/common/events/ossimListener.h"
+#include "base/common/events/ossimElevationManagerEvent.h"
+
+class OSSIMDLLEXPORT ossimElevationManagerEventListener : public ossimListener
+{
+ public:
+   ossimElevationManagerEventListener();
+   virtual ~ossimElevationManagerEventListener();
+   virtual void processEvent( ossimEvent& event );
+   virtual void processEvent( ossimElevationManagerEvent& event );
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimEvent.cpp
new file mode 100644
index 0000000000..d74ab2e130
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimEvent.cpp
@@ -0,0 +1,86 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimEvent.cpp,v 1.3 2004/06/10 17:57:10 dburken Exp $
+#include "ossimEvent.h"
+
+RTTI_DEF1(ossimEvent, "ossimEvent", ossimObject);
+
+
+ossimEvent::ossimEvent(ossimObject* object, long id)
+   :
+      ossimObject(),
+      theObject(object),
+      theId(id),
+      theIsConsumedFlag(false)
+{
+}
+
+ossimEvent::ossimEvent(const ossimEvent& rhs)
+   :
+      ossimObject(),
+      theObject(rhs.theObject),
+      theId(rhs.theId),
+      theIsConsumedFlag(rhs.theIsConsumedFlag)
+{
+}
+
+long ossimEvent::getId() const
+{
+   return theId;
+}
+
+void ossimEvent::setId(long id)
+{
+   theId = id;
+}
+
+bool ossimEvent::isConsumed() const
+{
+   return theIsConsumedFlag;
+}
+
+void ossimEvent::setConsumedFlag(bool flag)
+{
+   theIsConsumedFlag = flag;
+}
+
+void ossimEvent::consume()
+{
+   setConsumedFlag(true);
+}
+
+const ossimObject* ossimEvent::getObject() const
+{
+   return theObject;
+}
+
+ossimObject* ossimEvent::getObject()
+{
+   return theObject;
+}
+
+void ossimEvent::setObject(ossimObject* object)
+{
+   theObject = object;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimEvent.h
new file mode 100644
index 0000000000..abc4404239
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimEvent.h
@@ -0,0 +1,64 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimEvent.h,v 1.10 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimEvent_HEADER
+#define ossimEvent_HEADER
+#include "ossimEventIds.h"
+#include "base/common/ossimObject.h"
+
+class OSSIMDLLEXPORT ossimEvent : public ossimObject
+{
+public:
+
+   /**
+    * @param object The object associated with the event if any.
+    *
+    * @param id The event id.
+    */
+   ossimEvent(ossimObject* object=NULL,
+              long id=OSSIM_EVENT_NULL_ID);
+
+   ossimEvent(const ossimEvent& rhs);
+
+   long getId()const;
+   void setId(long id);
+
+   bool isConsumed()const;
+   void setConsumedFlag(bool flag=true);
+   void consume();
+
+   const ossimObject* getObject()const;
+   ossimObject*       getObject();
+
+   void setObject(ossimObject* object);
+
+protected:
+   ossimObject* theObject;
+   long         theId;
+   bool         theIsConsumedFlag;
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimEvent_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimEventIds.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimEventIds.h
new file mode 100644
index 0000000000..52b5f33bba
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimEventIds.h
@@ -0,0 +1,86 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimEventIds.h,v 1.16 2003/12/03 13:57:16 gpotts Exp $
+#ifndef ossimEventIds_HEADER
+#define ossimEventIds_HEADER
+
+#define OSSIM_EVENT_NULL_ID  -1
+
+
+// destruction event
+#define OSSIM_EVENT_OBJECT_DESTRUCTING_ID     1
+
+// connection events
+#define OSSIM_EVENT_CONNECTION_DISCONNECT_ID        3
+#define OSSIM_EVENT_CONNECTION_CONNECT_ID           4
+
+#define OSSIM_EVENT_REFRESH_ID  5
+#define OSSIM_EVENT_PROCESS_PROGRESS_ID  20
+
+#define OSSIM_EVENT_ADD_OBJECT_ID     40
+#define OSSIM_EVENT_REMOVE_OBJECT_ID  41
+
+
+#define OSSIM_EVENT_PROPERTY_ID       80
+#define OSSIM_EVENT_STATE_CHANGED_ID  90
+
+
+#define OSSIM_EVENT_AOI_RECTANGLE_ID  200
+#define OSSIM_EVENT_AOI_POLYGON_ID    201
+
+
+#define OSSIM_MOUSE_EVENT_ID               400
+#define OSSIM_MOUSE_EVENT_LEAVE_WINDOW_ID  401
+#define OSSIM_MOUSE_EVENT_MOTION_ID        402
+#define OSSIM_MOUSE_EVENT_LEFT_DOWN_ID     403
+#define OSSIM_MOUSE_EVENT_RIGHT_DOWN_ID    404
+#define OSSIM_MOUSE_EVENT_MIDDLE_DOWN_ID   405
+#define OSSIM_MOUSE_EVENT_LEFT_UP_ID       406
+#define OSSIM_MOUSE_EVENT_RIGHT_UP_ID      407
+#define OSSIM_MOUSE_EVENT_MIDDLE_UP_ID     408
+
+#define OSSIM_MOUSE_EVENT_LEFT_DCLICK_ID       409
+#define OSSIM_MOUSE_EVENT_RIGHT_DCLICK_ID      410
+#define OSSIM_MOUSE_EVENT_MIDDLE_DCLICK_ID     411
+#define OSSIM_MOUSE_EVENT_ENTER_WINDOW_ID  412
+
+#define OSSIM
+
+#define OSSIM_KEYBOARD_EVENT_ID  500
+
+#define OSSIM_EVENT_VIEW_ID      600
+
+
+#define OSSIM_EVENT_DISPLAY_LIST_ID           700
+#define OSSIM_EVENT_DISPLAY_REFRESH_ID        701
+
+#define OSSIM_EVENT_IMAGE_GEOMETRY_ID         800
+
+// this is the first user defined id.  If users want to add
+// additional id's they need to start at this id.  That way
+// we have no conflicts.
+//
+#define OSSIM_FIRST_USER_DEFINED_EVENT_ID     1000000
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimImageAoiListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageAoiListener.cpp
new file mode 100644
index 0000000000..161e92f755
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageAoiListener.cpp
@@ -0,0 +1,50 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimImageAoiListener.cpp,v 1.2 2002/04/09 21:20:03 gpotts Exp $
+#include "ossimImageAoiListener.h"
+#include "ossimEventIds.h"
+#include "ossimImageRectangleEvent.h"
+#include "ossimImagePolygonEvent.h"
+
+void ossimImageAoiListener::processEvent(ossimEvent& event)
+{
+   switch(event.getId())
+   {
+   case OSSIM_EVENT_AOI_RECTANGLE_ID:
+   {
+      ossimImageRectangleEvent* eventCast = static_cast<ossimImageRectangleEvent*>(&event);
+      imageRectangleEvent(*eventCast);
+      break;
+   }
+   case OSSIM_EVENT_AOI_POLYGON_ID:
+   {
+      ossimImagePolygonEvent* eventCast = static_cast<ossimImagePolygonEvent*>(&event);
+      imagePolygonEvent(*eventCast);
+      break;
+   }
+   default:
+   {
+      ossimListener::processEvent(event);
+      break;
+   }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimImageAoiListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageAoiListener.h
new file mode 100644
index 0000000000..3d58d4933f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageAoiListener.h
@@ -0,0 +1,43 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimImageAoiListener.h,v 1.3 2002/11/25 18:49:10 gpotts Exp $
+#ifndef ossimImageAoiListener_HEADER
+#define ossimImageAoiListener_HEADER
+#include "ossimListener.h"
+
+class OSSIMDLLEXPORT ossimImageRectangleEvent;
+class OSSIMDLLEXPORT ossimImagePolygonEvent;
+
+class OSSIMDLLEXPORT ossimImageAoiListener : public ossimListener
+{
+public:
+   ossimImageAoiListener():ossimListener(){}
+   virtual ~ossimImageAoiListener(){}
+   
+   virtual void processEvent(ossimEvent& event);
+
+   virtual void imageRectangleEvent(ossimImageRectangleEvent& event)
+      {}
+   virtual void imagePolygonEvent(ossimImagePolygonEvent& event)
+      {}
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEvent.cpp
new file mode 100644
index 0000000000..6987926c6c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEvent.cpp
@@ -0,0 +1,29 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimImageGeometryEvent.cpp,v 1.1 2003/12/03 13:57:46 gpotts Exp $
+#include "ossimImageGeometryEvent.h"
+
+RTTI_DEF1(ossimImageGeometryEvent, "ossimImageGeometryEvent", ossimEvent);
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEvent.h
new file mode 100644
index 0000000000..03e2bc8ace
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEvent.h
@@ -0,0 +1,82 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimImageGeometryEvent.h,v 1.1 2003/12/03 13:57:46 gpotts Exp $
+#ifndef ossimImageGeometryEvent_HEADER
+#define ossimImageGeometryEvent_HEADER
+#include "ossimEvent.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+class ossimImageGeometryEvent : public ossimEvent
+{
+public:
+   ossimImageGeometryEvent(ossimObject* object=0,
+                           long id=OSSIM_EVENT_IMAGE_GEOMETRY_ID)
+      :ossimEvent(object, id)
+      {
+      }
+   
+   ossimImageGeometryEvent(const ossimKeywordlist& geomKwl,
+                           ossimObject* object=NULL,
+                           long id=OSSIM_EVENT_IMAGE_GEOMETRY_ID)
+      :ossimEvent(object, id),
+       theGeomKwl(geomKwl)
+      {
+      }
+   ossimImageGeometryEvent(const ossimImageGeometryEvent& rhs)
+      :ossimEvent(rhs),
+       theGeomKwl(rhs.theGeomKwl)
+      {
+      }
+   virtual ~ossimImageGeometryEvent(){}
+   virtual ossimObject* dup()const
+      {
+         return new ossimImageGeometryEvent(*this);
+      }
+   void setGeometry(const ossimKeywordlist& geomKwl)
+      {
+         theGeomKwl = geomKwl;
+      }
+   void getGeometry(ossimKeywordlist& geomKwl)const
+      {
+         geomKwl = theGeomKwl;
+      }
+   const ossimKeywordlist& getGeometry()const
+      {
+         return theGeomKwl;
+      }
+   bool isGeometrySet()const
+      {
+         return (theGeomKwl.getSize() != 0);
+      }
+   void clearGeometry()
+      {
+         theGeomKwl.clear();
+      }
+protected:
+   ossimKeywordlist theGeomKwl;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEventListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEventListener.cpp
new file mode 100644
index 0000000000..80ab1cd8d0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEventListener.cpp
@@ -0,0 +1,45 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimImageGeometryEventListener.cpp,v 1.1 2003/12/03 13:57:46 gpotts Exp $
+#include "ossimImageGeometryEventListener.h"
+
+RTTI_DEF1(ossimImageGeometryEventListener, "ossimImageGeometryEventListener", ossimListener);
+
+void ossimImageGeometryEventListener::processEvent(ossimEvent& event)
+{
+   switch(event.getId())
+   {
+   case  OSSIM_EVENT_IMAGE_GEOMETRY_ID:
+   {
+      ossimImageGeometryEvent* tempCast = (ossimImageGeometryEvent*)(&event);
+      imageGeometryEvent(*tempCast);
+      
+      break;
+   }
+   default:
+   {
+      ossimListener::processEvent(event);
+   }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEventListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEventListener.h
new file mode 100644
index 0000000000..2a1a3a66b7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageGeometryEventListener.h
@@ -0,0 +1,43 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimImageGeometryEventListener.h,v 1.1 2003/12/03 13:57:46 gpotts Exp $
+#ifndef ossimImageGeometryEventListener_HEADER
+#define ossimImageGeometryEventListener_HEADER
+#include "ossimListener.h"
+#include "ossimImageGeometryEvent.h"
+
+class ossimImageGeometryEventListener : public ossimListener
+{
+public:
+   ossimImageGeometryEventListener():ossimListener(){}
+   virtual ~ossimImageGeometryEventListener(){}
+   virtual void processEvent(ossimEvent& event);
+
+   virtual void imageGeometryEvent(ossimImageGeometryEvent& /* event */)
+      {}
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimImagePolygonEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimImagePolygonEvent.h
new file mode 100644
index 0000000000..b6f5b1bdd3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimImagePolygonEvent.h
@@ -0,0 +1,65 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimImagePolygonEvent.h,v 1.4 2005/12/16 14:27:52 dburken Exp $
+#ifndef ossimImagePolygonEvent_HEADER
+#define ossimImagePolygonEvent_HEADER
+#include <vector>
+#include <base/common/events/ossimEvent.h>
+#include <base/common/events/ossimEventIds.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt.h>
+
+
+class OSSIMDLLEXPORT ossimImagePolygonEvent : public ossimEvent
+{
+public:
+   ossimImagePolygonEvent(const std::vector<ossimIpt>& polygon,
+                          ossimObject* obj=NULL)
+      : ossimEvent(obj,OSSIM_EVENT_AOI_POLYGON_ID) ,
+        thePolygon(polygon)
+      {
+      }
+   ossimImagePolygonEvent(const std::vector<ossimDpt>& polygon,
+                          ossimObject* obj=NULL)
+      : ossimEvent(obj,OSSIM_EVENT_AOI_POLYGON_ID) ,
+        thePolygon(polygon.begin(),
+                   polygon.end())
+      {
+      }
+   virtual ossimObject* dup()const
+      {
+         return new ossimImagePolygonEvent(*this);
+      }
+   
+   const std::vector<ossimIpt>& getpolygon()const
+      {
+         return thePolygon;
+      }
+   const std::vector<ossimIpt>& getPolygon()const
+      {
+         return thePolygon;
+      }
+   void setPolygon(const std::vector<ossimIpt>& polygon)
+      {
+         thePolygon = polygon;
+      }
+   void setPolygon(const std::vector<ossimDpt>& polygon)
+      {
+         thePolygon.clear();
+         thePolygon.insert(thePolygon.begin(),
+                           polygon.begin(),
+                           polygon.end());
+      }
+   
+protected:
+   std::vector<ossimIpt> thePolygon;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimImageRectangleEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageRectangleEvent.h
new file mode 100644
index 0000000000..289d4e92cb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimImageRectangleEvent.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimImageRectangleEvent.h,v 1.3 2003/01/06 19:01:05 gpotts Exp $
+#ifndef ossimImageRectangleEvent_HEADER
+#define ossimImageRectangleEvent_HEADER
+#include "ossimEvent.h"
+#include "ossimEventIds.h"
+#include "base/data_types/ossimIrect.h"
+
+class OSSIMDLLEXPORT ossimImageRectangleEvent : public ossimEvent
+{
+public:
+   ossimImageRectangleEvent(const ossimIrect& rect,
+                            ossimObject* obj=NULL)
+      : ossimEvent(obj,OSSIM_EVENT_AOI_RECTANGLE_ID) ,
+        theRectangle(rect)
+      {
+      }
+   virtual ossimObject* dup()const
+      {
+         return new ossimImageRectangleEvent(*this);
+      }
+   
+   const ossimIrect& getRectangle()const
+      {
+         return theRectangle;
+      }
+   void setRectangle(const ossimIrect& rect)
+      {
+         theRectangle = rect;
+      }
+   
+protected:
+   ossimIrect theRectangle;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimListener.cpp
new file mode 100644
index 0000000000..22950b6f29
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimListener.cpp
@@ -0,0 +1,51 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  Garrett Potts 
+//
+//*******************************************************************
+//  $Id: ossimListener.cpp,v 1.5 2005/07/15 20:43:51 dburken Exp $
+#include <base/common/events/ossimListener.h>
+
+RTTI_DEF(ossimListener, "ossimListener");
+
+ossimListener::ossimListener()
+  :theListenerEnableFlag(true)
+{}
+
+ossimListener::~ossimListener()
+{
+}
+
+void ossimListener::processEvent(ossimEvent& /* event */)
+{
+}
+
+void ossimListener::enableListener()
+{
+  theListenerEnableFlag = true;
+}
+
+void ossimListener::disableListener()
+{
+  theListenerEnableFlag = false;
+}
+
+void ossimListener::setListenerEnableFlag(bool flag)
+{
+  theListenerEnableFlag = flag;
+}
+
+bool ossimListener::isListenerEnabled()const
+{
+  return theListenerEnableFlag;
+}
+
+bool ossimListener::getListenerEnableFlag()const
+{
+  return theListenerEnableFlag;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimListener.h
new file mode 100644
index 0000000000..face43d540
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimListener.h
@@ -0,0 +1,51 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimListener.h,v 1.7 2005/07/15 18:57:49 dburken Exp $
+#ifndef ossimListener_HEADER
+#define ossimListener_HEADER
+#include <base/common/ossimObject.h>
+
+class OSSIMDLLEXPORT ossimEvent;
+
+/*!
+ * Base class for all listners.  Listners nned to derive from this
+ * class and override the processEvent method.
+ */
+class OSSIMDLLEXPORT ossimListener
+{
+public:
+
+   ossimListener();
+
+   virtual ~ossimListener();
+
+   /**
+    * ProcessEvent.  The defaul is to do nothing.  Derived
+    * classes need to override this class.
+    */
+   virtual void processEvent(ossimEvent& event);
+
+   void enableListener();
+
+   void disableListener();
+
+   void setListenerEnableFlag(bool flag);
+
+   bool isListenerEnabled() const;
+
+   bool getListenerEnableFlag() const;
+
+protected:
+   bool theListenerEnableFlag;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimListenerManager.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimListenerManager.cpp
new file mode 100644
index 0000000000..7e4a921626
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimListenerManager.cpp
@@ -0,0 +1,155 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+// 
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimListenerManager.cpp,v 1.21 2005/12/01 16:39:14 dburken Exp $
+
+#include <algorithm>
+#include <base/common/events/ossimListenerManager.h>
+#include <base/common/events/ossimEvent.h>
+#include <base/common/events/ossimListener.h>
+
+RTTI_DEF(ossimListenerManager, "ossimListenerManager");
+
+ossimListenerManager::ossimListenerManager()
+{
+   theFireEventFlag = false;
+}
+
+ossimListenerManager::ossimListenerManager(const ossimListenerManager& rhs)
+{
+//    replaceListeners(rhs.getListeners());
+}
+
+ossimListenerManager::~ossimListenerManager()
+{
+   theListenerList.clear();
+}
+
+void ossimListenerManager::fireEvent(ossimEvent& event)
+{
+   // only process the event if it has not been consumed.
+   if(event.isConsumed())
+   {
+      return;
+   }
+   theFireEventFlag = true;
+
+   std::list<ossimListener*>::iterator currentIterator = theListenerList.begin();
+   
+   while(currentIterator != theListenerList.end())
+   {
+      // only fire if the event is not consumed
+      if(!event.isConsumed())
+      {
+         if(*currentIterator)
+         {
+            if(theDelayedRemove.end()==std::find(theDelayedRemove.begin(),
+                                                 theDelayedRemove.end(),
+                                                 (*currentIterator)))
+            {
+               if((*currentIterator)->isListenerEnabled())
+               {
+                  (*currentIterator)->processEvent(event);
+               }
+            }
+         }
+      }
+      else
+      {
+         // the event is now consumed so stop propagating.
+         //
+         theFireEventFlag = false;
+         break;
+      }
+      ++currentIterator;
+   }
+   
+   theFireEventFlag = false;
+   
+   if(theDelayedAdd.size())
+   {
+      for(std::list<ossimListener*>::iterator current = theDelayedAdd.begin();
+          current != theDelayedAdd.end();++current)
+      {
+         addListener(*current);
+      }
+      theDelayedAdd.clear();
+   }
+   
+   if(theDelayedRemove.size())
+   {
+      for(std::list<ossimListener*>::iterator current = theDelayedRemove.begin();
+          current != theDelayedRemove.end();++current)
+      {
+         removeListener(*current);
+      }
+      theDelayedRemove.clear();
+   }
+}
+
+bool ossimListenerManager::addListener(ossimListener* listener)
+{
+   if(theFireEventFlag)
+   {
+      theDelayedAdd.push_back(listener);
+   }
+   else
+   {
+      
+      if(!findListener(listener))
+      {
+         theListenerList.push_back(listener);
+      }
+   }
+   
+   return true;
+}
+
+bool ossimListenerManager::removeListener(ossimListener* listener)
+{
+   
+   if(theFireEventFlag)
+   {
+      theDelayedRemove.push_back(listener);
+      return true;
+   }
+   
+   std::list<ossimListener*>::iterator current=theListenerList.begin();
+   while(current!=theListenerList.end())
+   {
+      if( (*current) == listener)
+      {
+         current = theListenerList.erase(current);
+         break; // Should only be in list once... (drb)
+      }
+      else
+      {
+         ++current;
+      }
+   }
+   
+   return true;
+}
+
+bool ossimListenerManager::findListener(ossimListener* listener)
+{
+   bool result = false;
+
+   if(listener)
+   {
+      std::list<ossimListener*>::iterator currentIter =
+         std::find(theListenerList.begin(),
+                   theListenerList.end(),
+                   listener);
+      result = (currentIter != theListenerList.end());
+   }
+   
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimListenerManager.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimListenerManager.h
new file mode 100644
index 0000000000..17f9404ffd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimListenerManager.h
@@ -0,0 +1,138 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimListenerManager.h,v 1.16 2005/09/14 15:05:03 gpotts Exp $
+#ifndef ossimListenerManager_HEADER
+#define ossimListenerManager_HEADER
+#include "base/common/ossimConstants.h"
+#include <list>
+#include "base/common/ossimRtti.h"
+
+class OSSIMDLLEXPORT ossimListener;
+class OSSIMDLLEXPORT ossimEvent;
+
+class OSSIMDLLEXPORT ossimListenerManager
+{
+public:
+   /*!
+    * Default constructor and needs no initialization.
+    */
+   ossimListenerManager();
+
+   /*!
+    * Default destructor.  Note the Manager doesn't own the listeners
+    * and will not delete them
+    */
+   virtual ~ossimListenerManager();
+
+   /*!
+    * Traverses through all listeners and fires an event to them.
+    * if any listener sets the consumed flag on the event it
+    * will stop traversing the list.
+    */
+   virtual void fireEvent(ossimEvent& event);
+   
+   /*!
+    * Appends the listener onto the list.
+    */
+   virtual bool addListener(ossimListener* listener);
+
+   /*!
+    * Will push the lister to the front of the list.
+    */
+  //   virtual bool insertFrontListener(ossimListener* listener);
+
+   /*!
+    * Finds and removes the listener.
+    */
+   virtual bool removeListener(ossimListener* listener);
+
+   
+   /*!
+    * Will find the listener passed in as the first argument
+    * and insert the passed in listener before it.  If not
+    * found then it will default to a push to front.
+    */
+//    virtual bool insertBeforeListener(ossimListener* listenerSearchKey,
+//                                      ossimListener* listener);
+
+   /*!
+    * Will find the listener passed in as the first argument
+    * and insert the passed in listener after it.  If not
+    * found then it will default to an append.
+    */
+//    virtual bool insertAfterListener(ossimListener* listenerSearchKey,
+//                                     ossimListener* listener);
+   
+   /*!
+    * Will insert the listener before the specified
+    * listener.  If the index is invalid it defaults
+    * to a push to front.  An invalid index is any
+    * index < 0 or larger than the number of items
+    * currently in the list.
+    */
+//    virtual bool insertBeforeListener(ossimListener* listener,
+//                                      long index);
+
+   /*!
+    * Will insert the listener after the specified
+    * listener.  If the index is invalid it defaults
+    * to an addListener.  An invalid index is any
+    * index < 0 or larger than the number of items
+    * currently in the list.
+    */
+//    virtual bool insertAfterListener(ossimListener* listener,
+//                                     long index);
+
+   /*!
+    * Searches the list and sees if a listener is found
+    */
+  virtual bool findListener(ossimListener* listener);
+  
+   /*!
+    * Will search the list and return the index if found else
+    * returns a negative value.
+    */
+  //   virtual long getIndexOfListener(ossimListener* listener);
+
+  //   const std::vector<ossimListener*>& getListeners()const{return theListenerList;}
+
+   
+protected:
+  ossimListenerManager(const ossimListenerManager& rhs);
+  
+  /*!
+   *  Holds the list of listeners.
+   */
+  std::list<ossimListener*> theListenerList;
+  bool theEnabledFlag;
+  mutable std::list<ossimListener*> theDelayedAdd;
+  mutable std::list<ossimListener*> theDelayedRemove;
+  mutable bool theFireEventFlag;
+//  mutable std::list<ossimListener*>::iterator theCurrentIterator;
+  
+  
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseEvent.cpp
new file mode 100644
index 0000000000..a815133c61
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseEvent.cpp
@@ -0,0 +1,27 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimMouseEvent.cpp,v 1.2 2002/06/25 12:30:17 gpotts Exp $
+#include "ossimMouseEvent.h"
+
+RTTI_DEF1(ossimMouseEvent, "ossimMouseEvent", ossimEvent);
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseEvent.h
new file mode 100644
index 0000000000..3fb2c1a8b9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseEvent.h
@@ -0,0 +1,97 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimMouseEvent.h,v 1.11 2003/01/06 19:01:24 gpotts Exp $
+
+#ifndef ossimMouseEvent_HEADER
+#define ossimMouseEvent_HEADER
+#include "ossimEvent.h"
+#include "base/data_types/ossimIpt.h"
+
+class OSSIMDLLEXPORT ossimMouseEvent : public ossimEvent
+{
+public:
+   ossimMouseEvent(const ossimDpt& scenePoint=ossimDpt(0,0),
+                   const ossimDpt& relViewPoint=ossimDpt(0,0),
+                   ossimObject* object = NULL,
+                   long id = OSSIM_MOUSE_EVENT_ID,
+                   long mouseType = 0)
+      :ossimEvent(object, id),
+       theScenePoint(scenePoint),
+       theRelViewPoint(relViewPoint),
+       theMouseType(mouseType)
+      {
+      }
+   
+   virtual ossimObject* dup()const{return new ossimMouseEvent(*this);}
+   
+   bool controlDown() const { return theControlKeyDown; }
+   bool altDown() const { return theAltKeyDown; }
+   bool shiftDown() const { return theShiftKeyDown; }
+   
+   // Find which event was just generated
+   bool leftDown() const{   return (theMouseType == OSSIM_MOUSE_EVENT_LEFT_DOWN_ID); }
+   bool middleDown() const{ return (theMouseType == OSSIM_MOUSE_EVENT_MIDDLE_DOWN_ID); }
+   bool rightDown() const{  return (theMouseType == OSSIM_MOUSE_EVENT_RIGHT_DOWN_ID); }
+   bool leftUp() const{   return (theMouseType == OSSIM_MOUSE_EVENT_LEFT_UP_ID); }
+   bool middleUp() const{ return (theMouseType == OSSIM_MOUSE_EVENT_MIDDLE_UP_ID); }
+   bool rightUp() const{  return (theMouseType == OSSIM_MOUSE_EVENT_RIGHT_UP_ID); }
+   
+   bool leftDClick() const { return (theMouseType == OSSIM_MOUSE_EVENT_LEFT_DCLICK_ID); }
+   bool middleDClick() const { return (theMouseType == OSSIM_MOUSE_EVENT_MIDDLE_DCLICK_ID); }
+   bool rightDClick() const { return (theMouseType == OSSIM_MOUSE_EVENT_RIGHT_DCLICK_ID); }
+   
+   // Find the current state of the mouse buttons (regardless
+   // of current event type)
+   bool leftIsDown() const   { return theLeftDown; }
+   bool middleIsDown() const { return theMiddleDown; }
+   bool rightIsDown() const  { return theRightDown; }
+   
+   // True if a button is down and the mouse is moving
+   bool dragging() const
+      {
+         return (moving() &&
+                 (leftIsDown() || middleIsDown() || rightIsDown()));
+      }
+
+   // True if the mouse is moving, and no button is down
+   bool moving() const { return (theMouseType == OSSIM_MOUSE_EVENT_MOTION_ID); }
+   
+   // True if the mouse is just entering the window
+   bool entering() const { return (theMouseType == OSSIM_MOUSE_EVENT_ENTER_WINDOW_ID); }
+   
+   // True if the mouse is just leaving the window
+   bool leaving() const { return (theMouseType   == OSSIM_MOUSE_EVENT_LEAVE_WINDOW_ID); }
+   
+   ossimDpt theScenePoint;
+   ossimDpt theRelViewPoint;
+   int     theMouseType;
+   bool     theAltKeyDown;
+   bool     theControlKeyDown;
+   bool     theShiftKeyDown;
+   bool     theLeftDown;
+   bool     theRightDown;
+   bool     theMiddleDown;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseListener.cpp
new file mode 100644
index 0000000000..be0f88e683
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseListener.cpp
@@ -0,0 +1,54 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimMouseListener.cpp,v 1.4 2002/09/25 12:01:18 gpotts Exp $
+
+#include "base/common/events/ossimMouseListener.h"
+#include "base/common/events/ossimMouseEvent.h"
+
+RTTI_DEF1(ossimMouseListener,"ossimMouseListener",ossimListener);
+
+void ossimMouseListener::processEvent(ossimEvent& event)
+{
+   ossimMouseEvent* mEvent = PTR_CAST(ossimMouseEvent, &event);
+
+   if(mEvent)
+   {
+      mouseEvent(*mEvent);
+   }
+   else
+   {
+      ossimListener::processEvent(event);
+   }
+//    switch(event.getId())
+//    {
+//    case OSSIM_MOUSE_EVENT_ID:
+//    {
+//        = static_cast<ossimMouseEvent*>(&event);
+//       mouseEvent(*mEvent);
+//       break;
+//    }
+//    default:
+//    {
+//       ossimListener::processEvent(event);
+//    }
+//    }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseListener.h
new file mode 100644
index 0000000000..9de007c7be
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimMouseListener.h
@@ -0,0 +1,44 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimMouseListener.h,v 1.2 2002/11/25 18:49:10 gpotts Exp $
+#ifndef ossimMouseListener_HEADER
+#define ossimMouseListener_HEADER
+#include "ossimListener.h"
+#include "ossimMouseEvent.h"
+
+class OSSIMDLLEXPORT ossimMouseListener : public ossimListener
+{
+public:
+   ossimMouseListener():ossimListener(){}
+   virtual ~ossimMouseListener(){}
+   
+   virtual void processEvent(ossimEvent& event);
+
+   /*!
+    * processes all mouse events
+    */
+   virtual void mouseEvent(ossimMouseEvent& event)
+      {}
+
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimObjectDestructingEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimObjectDestructingEvent.cpp
new file mode 100644
index 0000000000..74fcd05c43
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimObjectDestructingEvent.cpp
@@ -0,0 +1,3 @@
+#include "ossimObjectDestructingEvent.h"
+
+RTTI_DEF1(ossimObjectDestructingEvent,"ossimObjectDestructingEvent",ossimEvent)
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimObjectDestructingEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimObjectDestructingEvent.h
new file mode 100644
index 0000000000..333fd1d7ef
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimObjectDestructingEvent.h
@@ -0,0 +1,18 @@
+#ifndef ossimObjectDestructingEvent_HEADER
+#define ossimObjectDestructingEvent_HEADER
+
+#include "ossimEvent.h"
+#include "ossimEventIds.h"
+
+class OSSIMDLLEXPORT ossimObject;
+class OSSIMDLLEXPORT ossimObjectDestructingEvent : public ossimEvent
+{
+public:
+   ossimObjectDestructingEvent(ossimObject* objectDestructing=NULL)
+      :ossimEvent(objectDestructing, OSSIM_EVENT_OBJECT_DESTRUCTING_ID)
+      {}
+   virtual ossimObject* dup()const{return new ossimObjectDestructingEvent(*this);}
+
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimObjectEvents.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimObjectEvents.h
new file mode 100644
index 0000000000..357c6dd19a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimObjectEvents.h
@@ -0,0 +1,10 @@
+#ifndef ossimObjectEvents_HEADER
+#define ossimObjectEvents_HEADER
+
+#include "base/common/events/ossimObjectDestructingEvent.h"
+#include "base/common/events/ossimConnectionEvent.h"
+#include "base/common/events/ossimPropertyEvent.h"
+#include "base/common/events/ossimContainerEvent.h"
+#include "base/common/events/ossimRefreshEvent.h"
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessListener.cpp
new file mode 100644
index 0000000000..00dd7fadcf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessListener.cpp
@@ -0,0 +1,44 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+// $Id: ossimProcessListener.cpp,v 1.4 2004/08/17 16:49:03 dburken Exp $
+//----------------------------------------------------------------------------
+
+#include "ossimProcessListener.h"
+#include "ossimProcessProgressEvent.h"
+
+RTTI_DEF1(ossimProcessListener, "ossimProcessListener", ossimListener);
+
+ossimProcessListener::ossimProcessListener()
+   : ossimListener()
+{}
+
+ossimProcessListener::~ossimProcessListener()
+{}
+
+void ossimProcessListener::processEvent(ossimEvent& event)
+{
+   switch(event.getId())
+   {
+   case OSSIM_EVENT_PROCESS_PROGRESS_ID:
+   {
+      ossimProcessProgressEvent* eventCast = static_cast<ossimProcessProgressEvent*>(&event);
+      processProgressEvent(*eventCast);
+      break;
+   }
+   default:
+   {
+      ossimListener::processEvent(event);
+      break;
+   }
+   }
+}
+
+void ossimProcessListener::processProgressEvent(ossimProcessProgressEvent& /* event */ )
+{}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessListener.h
new file mode 100644
index 0000000000..c32ac68a61
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessListener.h
@@ -0,0 +1,28 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+// $Id: ossimProcessListener.h,v 1.5 2004/08/17 16:49:03 dburken Exp $
+//----------------------------------------------------------------------------
+#ifndef ossimProcessListener_HEADER
+#define ossimProcessListener_HEADER
+#include "ossimListener.h"
+class OSSIMDLLEXPORT ossimProcessProgressEvent;
+
+class OSSIMDLLEXPORT ossimProcessListener : public ossimListener
+{
+public:
+   ossimProcessListener();
+   virtual ~ossimProcessListener();
+   virtual void processEvent(ossimEvent& event);
+   virtual void processProgressEvent(ossimProcessProgressEvent& event);
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessProgressEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessProgressEvent.cpp
new file mode 100644
index 0000000000..1e2c84a9ac
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessProgressEvent.cpp
@@ -0,0 +1,68 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description: Event for process progress.
+//
+// $Id: ossimProcessProgressEvent.cpp,v 1.3 2005/09/09 19:23:58 gpotts Exp $
+//----------------------------------------------------------------------------
+#include <base/common/events/ossimProcessProgressEvent.h>
+
+RTTI_DEF1(ossimProcessProgressEvent, "ossimProcessProgressEvent", ossimEvent);
+
+ossimProcessProgressEvent::ossimProcessProgressEvent(ossimObject* owner,
+                                                     double percentComplete,
+                                                     const ossimString message,
+                                                     bool outputMessageFlag)
+   :
+      ossimEvent(owner, OSSIM_EVENT_PROCESS_PROGRESS_ID),
+      thePercentComplete(percentComplete),
+      theMessage(message),
+      theOutputMessageFlag(outputMessageFlag)
+{
+}
+
+ossimObject* ossimProcessProgressEvent::dup()const
+{
+   return new ossimProcessProgressEvent(*this);
+}
+
+double ossimProcessProgressEvent::getPercentComplete()const
+{
+   return thePercentComplete;
+}
+   
+ossimString ossimProcessProgressEvent::getMessage()const
+{
+   return theMessage;
+}
+
+void ossimProcessProgressEvent::getMessage(ossimString& message)const
+{
+   message = theMessage;
+}
+   
+void ossimProcessProgressEvent::setPercentComplete(double percentComplete)
+{
+   thePercentComplete = percentComplete;
+}
+
+void ossimProcessProgressEvent::setMessage(const ossimString& message)
+{
+   theMessage = message;
+}
+
+void ossimProcessProgressEvent::setOutputMessageFlag(bool flag)
+{
+   theOutputMessageFlag = flag;
+}
+
+bool ossimProcessProgressEvent::getOutputMessageFlag() const
+{
+   return theOutputMessageFlag;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessProgressEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessProgressEvent.h
new file mode 100644
index 0000000000..800c825d52
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimProcessProgressEvent.h
@@ -0,0 +1,51 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description: Event for process progress.
+//
+// $Id: ossimProcessProgressEvent.h,v 1.8 2005/09/09 19:23:58 gpotts Exp $
+//----------------------------------------------------------------------------
+#ifndef ossimProcessProgressEvent_HEADER
+#define ossimProcessProgressEvent_HEADER
+
+#include <base/common/events/ossimEvent.h>
+#include <base/data_types/ossimString.h>
+
+class OSSIMDLLEXPORT ossimProcessProgressEvent : public ossimEvent
+{
+public:
+   ossimProcessProgressEvent(ossimObject* owner=NULL,
+                             double percentComplete=0.0,
+                             const ossimString message="",
+                             bool outputMessageFlag=false);
+
+   virtual ossimObject* dup()const;
+   
+   double getPercentComplete()const;
+   
+   ossimString getMessage()const;
+
+   void getMessage(ossimString& message)const;
+   
+   void setPercentComplete(double percentComplete);
+   
+   void setMessage(const ossimString& message);
+
+   void setOutputMessageFlag(bool flag);
+
+   bool getOutputMessageFlag() const;
+      
+protected:
+   double      thePercentComplete;
+   ossimString theMessage;
+   bool        theOutputMessageFlag;
+
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimPropertyEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimPropertyEvent.h
new file mode 100644
index 0000000000..70d09e0e31
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimPropertyEvent.h
@@ -0,0 +1,14 @@
+#ifndef ossimPropertyEvent_HEADER
+#define ossimPropertyEvent_HEADER
+#include "base/common/events/ossimEvent.h"
+
+class OSSIMDLLEXPORT ossimPropertyEvent : public ossimEvent
+{
+public:
+   ossimPropertyEvent(ossimObject* object) // the event id
+      :ossimEvent(object, OSSIM_EVENT_PROPERTY_ID)
+      {}
+   virtual ossimObject* dup()const{return new ossimPropertyEvent(*this);}
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEvent.cpp
new file mode 100644
index 0000000000..46c898b26f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEvent.cpp
@@ -0,0 +1,124 @@
+//----------------------------------------------------------------------------
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Scott Bortman
+//
+// Description:   Region Of Interest (ROI) Event
+//
+// $Id: ossimROIEvent.cpp,v 1.5 2006/01/04 15:48:56 dburken Exp $
+//----------------------------------------------------------------------------
+#include <base/common/events/ossimROIEvent.h>
+#include <base/data_types/ossimPolygon.h>
+#include <base/data_types/ossimPolyLine.h>
+#include <base/data_types/ossimIrect.h>
+
+RTTI_DEF1(ossimROIEvent, "ossimROIEvent", ossimEvent);
+
+ossimROIEvent::ossimROIEvent(ossimObject* object,
+                             long id)
+   : ossimEvent( object, id ),
+     theType(OSSIM_RECTANGLE_ROI),
+     theMovingFlag(false)
+   
+{
+}
+
+ossimROIEvent::ossimROIEvent( const ossimROIEvent& rhs )
+   : ossimEvent    ( rhs ),
+     theType       ( rhs.theType ),
+     theMovingFlag ( rhs.theMovingFlag)
+{
+}
+
+ossimObject* ossimROIEvent::dup() const
+{
+   return new ossimROIEvent( *this );
+}
+
+const vector<ossimIpt>& ossimROIEvent::getPoints()const
+{
+   return thePoints;
+}
+
+void ossimROIEvent::getPoint(vector<ossimIpt>& points)const 
+{
+   points = thePoints;
+}
+
+void ossimROIEvent::setPoints( const vector<ossimIpt>& points )
+{
+   thePoints = points;
+}
+
+void ossimROIEvent::setRect(const ossimIrect& rect)
+{
+   thePoints.clear();
+   thePoints.push_back(rect.ul());
+   thePoints.push_back(rect.lr());
+}
+
+void ossimROIEvent::setEventType( ossimRegionType eventType )
+{
+   theType = eventType;
+}
+
+ossimROIEvent::ossimRegionType ossimROIEvent::getEventType()const
+{
+   return theType;
+}
+
+void ossimROIEvent::setTypeToPolygon()
+{
+   theType = OSSIM_POLYGON_ROI;
+}
+
+void ossimROIEvent::setTypeToRectangle()
+{
+   theType = OSSIM_RECTANGLE_ROI;
+}
+
+void ossimROIEvent::setTypeToPolyline()
+{
+   theType = OSSIM_POLYLINE_ROI;
+}
+
+bool ossimROIEvent::isRectangleRegion()const
+{
+   return (theType == OSSIM_RECTANGLE_ROI);
+}
+
+bool ossimROIEvent::isPolygonRegion()const
+{
+   return (theType == OSSIM_POLYGON_ROI);
+}
+
+bool ossimROIEvent::isPolylineRegion()const
+{
+   return (theType == OSSIM_POLYLINE_ROI);
+}
+
+void ossimROIEvent::getRect(ossimIrect& rect)const
+{
+   rect = ossimIrect(thePoints);
+}
+
+void ossimROIEvent::getPolygon(ossimPolygon& polygon)const
+{
+   polygon = ossimPolygon(thePoints);
+}
+
+void ossimROIEvent::getPolyLine(ossimPolyLine& polyline)const
+{
+   polyline = ossimPolyLine(thePoints);
+}
+
+void ossimROIEvent::setMovingFlag(bool flag)
+{
+   theMovingFlag = flag;
+}
+
+bool ossimROIEvent::getMovingFlag() const
+{
+   return theMovingFlag;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEvent.h
new file mode 100644
index 0000000000..380c331a33
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEvent.h
@@ -0,0 +1,74 @@
+//----------------------------------------------------------------------------
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Scott Bortman
+//
+// Description:   Region Of Interest (ROI) Event
+//
+// $Id: ossimROIEvent.h,v 1.14 2006/01/04 15:48:56 dburken Exp $
+//----------------------------------------------------------------------------
+#ifndef ossimROIEvent_HEADER
+#define ossimROIEvent_HEADER
+
+#include <base/common/events/ossimEvent.h>
+#include <base/data_types/ossimIpt.h>
+#include <vector>
+
+class ossimPolygon;
+class ossimPolyLine;
+class ossimIrect;
+class OSSIMDLLEXPORT ossimROIEvent : public ossimEvent
+{
+public:
+   ossimROIEvent( ossimObject* object=NULL,
+                  long id=OSSIM_EVENT_NULL_ID );
+   ossimROIEvent( const ossimROIEvent& rhs );
+   virtual ossimObject* dup() const;
+   
+   enum ossimRegionType
+   {
+      OSSIM_RECTANGLE_ROI      = 0,
+      OSSIM_POLYGON_ROI        = 1,
+      OSSIM_POLYLINE_ROI       = 2
+   };
+
+   const std::vector<ossimIpt>& getPoints()const;
+   void getPoint(std::vector<ossimIpt>& points)const ;
+   void setPoints( const std::vector<ossimIpt>& points );
+   void setRect(const ossimIrect& rect);
+   void setEventType( ossimRegionType eventType );
+   ossimRegionType getEventType()const;
+   void setTypeToPolygon();
+   void setTypeToRectangle();
+   void setTypeToPolyline();
+   bool isRectangleRegion()const;
+   bool isPolygonRegion()const;
+   bool isPolylineRegion()const;
+   void getRect(ossimIrect& rect)const;
+   void getPolygon(ossimPolygon& polygon)const;
+   void getPolyLine(ossimPolyLine& polyline)const;
+
+   /**
+    * @param flag If true indicates region of interest is moving and size is
+    * not to change.
+    */
+   void setMovingFlag(bool flag);
+
+   /**
+    * @return Returns theMoving flag.  If true indicates region of interest
+    * is moving and size is not to change.
+    */
+   bool getMovingFlag() const;
+   
+ protected:
+   std::vector<ossimIpt> thePoints;
+   ossimRegionType  theType;
+
+   // Indicates moving so keep the same size on a redraw.
+   bool             theMovingFlag;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEventListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEventListener.cpp
new file mode 100644
index 0000000000..6d5b9ec9a3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEventListener.cpp
@@ -0,0 +1,49 @@
+#include "ossimROIEventListener.h"
+#include "ossimROIEvent.h"
+
+
+RTTI_DEF1(ossimROIEventListener, "ossimROIEventListener", ossimListener);
+
+void ossimROIEventListener::processEvent(ossimEvent& event)
+{
+   if(event.isConsumed()) return;
+   
+   ossimROIEvent* roiEvent = PTR_CAST(ossimROIEvent,
+                                      &event);
+   
+   if(roiEvent)
+   {
+      const int type = roiEvent->getEventType();
+      
+      switch ( type )
+      {
+      case ossimROIEvent::OSSIM_RECTANGLE_ROI:
+         handleRectangleROIEvent( *roiEvent );
+         break;
+
+      case ossimROIEvent::OSSIM_POLYGON_ROI:
+         handlePolygonROIEvent( *roiEvent );
+         break;
+
+
+      case ossimROIEvent::OSSIM_POLYLINE_ROI:
+         handlePolylineROIEvent( *roiEvent );
+         break;
+
+         default:
+         break;
+      }
+   }
+}
+
+void ossimROIEventListener::handleRectangleROIEvent( ossimROIEvent& event )
+{
+}
+
+void ossimROIEventListener::handlePolygonROIEvent( ossimROIEvent& event )
+{
+}
+
+void ossimROIEventListener::handlePolylineROIEvent( ossimROIEvent& event )
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEventListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEventListener.h
new file mode 100644
index 0000000000..813f2385b5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimROIEventListener.h
@@ -0,0 +1,22 @@
+#ifndef ossimROIEventListener_HEADER
+#define ossimROIEventListener_HEADER
+
+#include "base/common/events/ossimListener.h"
+//#include "gui/wx/events/ossimROIEvent.h"
+#include "ossimROIEvent.h"
+
+class OSSIMDLLEXPORT ossimROIEventListener : public ossimListener
+{
+public:
+   ossimROIEventListener()
+      {
+      }
+   virtual void processEvent(ossimEvent& event);
+   virtual void handleRectangleROIEvent( ossimROIEvent& event );
+   virtual void handlePolygonROIEvent( ossimROIEvent& event );
+   virtual void handlePolylineROIEvent( ossimROIEvent& event );
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimRefreshEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimRefreshEvent.cpp
new file mode 100644
index 0000000000..28831bfb06
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimRefreshEvent.cpp
@@ -0,0 +1,27 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimRefreshEvent.cpp,v 1.1 2002/11/14 17:49:47 gpotts Exp $
+#include "ossimRefreshEvent.h"
+
+RTTI_DEF1(ossimRefreshEvent, "ossimRefreshEvent", ossimEvent);
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimRefreshEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimRefreshEvent.h
new file mode 100644
index 0000000000..13bcf9bfd2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimRefreshEvent.h
@@ -0,0 +1,48 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimRefreshEvent.h,v 1.2 2003/01/06 19:02:30 gpotts Exp $
+#ifndef ossimRefreshEvent_HEADER
+#define ossimRefreshEvent_HEADER
+#include "ossimEvent.h"
+
+class OSSIMDLLEXPORT ossimRefreshEvent : public ossimEvent
+{
+public:
+
+   ossimRefreshEvent(ossimObject* object=NULL)  // the object associated with the event if any
+      :ossimEvent(object, OSSIM_EVENT_REFRESH_ID)
+      {}
+   ossimRefreshEvent(const ossimRefreshEvent& rhs)
+      :ossimEvent(rhs)
+      {
+      }
+   virtual ossimObject* dup()const
+      {
+         return new ossimRefreshEvent(*this);
+      }
+ 
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimStateChangedEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimStateChangedEvent.cpp
new file mode 100644
index 0000000000..77210e79fe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimStateChangedEvent.cpp
@@ -0,0 +1,38 @@
+#include "ossimStateChangedEvent.h"
+
+ossimStateChangedEvent::ossimStateChangedEvent( ossimObject* object,
+                                                 long id )
+   : ossimEvent( object, id )
+{
+}
+
+void ossimStateChangedEvent::setNewKeywordlist( ossimKeywordlist kwl )
+{
+   theNewKeywordlist = kwl;
+}
+
+ossimKeywordlist ossimStateChangedEvent::getNewKeywordlist()
+{
+   return theNewKeywordlist;
+}
+
+
+void ossimStateChangedEvent::setOldKeywordlist( ossimKeywordlist kwl )
+{
+   theOldKeywordlist = kwl;
+}
+
+ossimKeywordlist ossimStateChangedEvent::getOldKeywordlist()
+{
+   return theOldKeywordlist;
+}
+
+void ossimStateChangedEvent::setObjId( string objId )
+{
+   theObjId = objId;
+}
+
+string ossimStateChangedEvent::getObjId()
+{
+   return theObjId;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimStateChangedEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimStateChangedEvent.h
new file mode 100644
index 0000000000..6bb3c8c759
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimStateChangedEvent.h
@@ -0,0 +1,31 @@
+#ifndef ossimStateChangedEvent_HEADER
+#define ossimStateChangedEvent_HEADER
+
+#include "ossimEvent.h"
+#include "ossimEventIds.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+class OSSIMDLLEXPORT ossimStateChangedEvent : public ossimEvent
+{
+public:
+   ossimStateChangedEvent( ossimObject* object=NULL,
+                           long id=OSSIM_EVENT_STATE_CHANGED_ID );
+
+   void setObjId( string objId );
+   void setNewKeywordlist( ossimKeywordlist kwl );
+   void setOldKeywordlist( ossimKeywordlist kwl );
+
+   string getObjId();
+   ossimKeywordlist getNewKeywordlist();
+   ossimKeywordlist getOldKeywordlist();
+
+   // HACK - Need to set keywordlists too!!!
+   virtual ossimObject* dup()const{return new ossimStateChangedEvent(*this);}     
+
+private:
+   string theObjId;
+   ossimKeywordlist theNewKeywordlist;
+   ossimKeywordlist theOldKeywordlist;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimViewEvent.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimViewEvent.cpp
new file mode 100644
index 0000000000..fc66403160
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimViewEvent.cpp
@@ -0,0 +1,27 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimViewEvent.cpp,v 1.1 2002/12/09 14:38:36 gpotts Exp $
+#include "ossimViewEvent.h"
+
+RTTI_DEF1(ossimViewEvent, "ossimViewEvent",  ossimEvent);
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimViewEvent.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimViewEvent.h
new file mode 100644
index 0000000000..118887633d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimViewEvent.h
@@ -0,0 +1,169 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimViewEvent.h,v 1.8 2003/01/06 19:03:02 gpotts Exp $
+#ifndef ossimViewEvent_HEADER
+#define ossimViewEvent_HEADER
+#include "ossimEvent.h"
+#include "base/data_types/ossimGpt.h"
+
+class OSSIMDLLEXPORT ossimViewEvent : public ossimEvent
+{
+public:
+   enum ossimViewEventType
+   {
+      OSSIM_VIEW_EVENT_TYPE_GENERIC     = 0,
+      OSSIM_VIEW_EVENT_SCALE_CHANGE,
+      OSSIM_VIEW_EVENT_TRANSFORM_CHANGE,
+      OSSIM_VIEW_EVENT_VIEW_TYPE_CHANGE 
+   };
+   enum ossimViewPropagateType
+   {
+      OSSIM_VIEW_EVENT_PROPAGATE_NONE         = 0,
+      OSSIM_VIEW_EVENT_PROPAGATE_ALL_DISPLAYS = 1,
+      OSSIM_VIEW_EVENT_PROPAGATE_ALL_CHAINS   = 2,
+   };
+   
+   ossimViewEvent(ossimObject* view,
+                  ossimGpt     centerPt,
+                  ossimViewPropagateType propagateType = OSSIM_VIEW_EVENT_PROPAGATE_NONE,
+                  ossimViewEventType eventType = OSSIM_VIEW_EVENT_TYPE_GENERIC,
+                  ossimObject* object=NULL)
+      :ossimEvent(object, OSSIM_EVENT_VIEW_ID),
+       theView(view),
+       theCenterPoint(centerPt),
+       theEventType(eventType),
+       thePropagateType(propagateType),
+       theUpdateInputViewFlag(true),
+       theRefreshDisplayFlag(true)
+      {
+      }
+   ossimViewEvent(const ossimViewEvent& rhs)
+      :ossimEvent(rhs),
+       theView(rhs.theView),
+       theCenterPoint(rhs.theCenterPoint),
+       theEventType(rhs.theEventType),
+       thePropagateType(rhs.thePropagateType),
+       theUpdateInputViewFlag(rhs.theUpdateInputViewFlag),
+       theRefreshDisplayFlag(rhs.theRefreshDisplayFlag)
+      {
+      }
+   virtual ossimObject* dup()const
+      {
+         return new ossimViewEvent(*this);
+      }
+   virtual void setView(ossimObject* view)
+      {
+         theView = view;
+      }
+   virtual ossimObject* getView()
+      {
+         return theView;
+      }
+   void disablePropagation()
+      {
+         thePropagateType = OSSIM_VIEW_EVENT_PROPAGATE_NONE;
+      }
+   void setPropagateType(ossimViewPropagateType type)
+      {
+         thePropagateType = type;         
+      }
+   void setViewEventType(ossimViewEventType eventType)
+      {
+         theEventType = eventType;
+      }
+   void setEventTypeViewTypeChange()
+      {
+         theEventType = OSSIM_VIEW_EVENT_VIEW_TYPE_CHANGE;
+      }
+   void setEventTypeTransformChange()
+      {
+         theEventType = OSSIM_VIEW_EVENT_TRANSFORM_CHANGE;
+      }
+   void setEventTypeGeneric()
+      {
+         theEventType = OSSIM_VIEW_EVENT_TYPE_GENERIC;
+      }
+   void setCenterGroundPoint(const ossimGpt& gpt)
+      {
+         theCenterPoint = gpt;
+      }
+   const ossimGpt& getCenterGroundPoint()const
+      {
+         return theCenterPoint;
+      }
+   ossimViewEventType getViewEventType()const
+      {
+         return theEventType;
+      }
+   bool isViewChange()const
+      {
+         return (theEventType == OSSIM_VIEW_EVENT_VIEW_TYPE_CHANGE);
+      }
+   bool isTransformChange()const
+      {
+         return (theEventType == OSSIM_VIEW_EVENT_TRANSFORM_CHANGE);
+      }
+   bool isScaleChange()const
+      {
+         return (theEventType == OSSIM_VIEW_EVENT_SCALE_CHANGE);
+         
+      }
+   bool isPropagateEnabled()const
+      {
+         return (thePropagateType != OSSIM_VIEW_EVENT_PROPAGATE_NONE);
+      }
+   bool isPropagateToDisplays()const
+      {
+         return (thePropagateType & OSSIM_VIEW_EVENT_PROPAGATE_ALL_DISPLAYS);
+      }
+   bool isPropagateToChains()const
+      {
+         return (thePropagateType & OSSIM_VIEW_EVENT_PROPAGATE_ALL_CHAINS);
+      }
+   void setUpdateInputViewFlag(bool flag)
+      {
+         theUpdateInputViewFlag = flag;
+      }
+   bool getUpdateInputViewFlag()const
+      {
+         return theUpdateInputViewFlag;
+      }
+   void setRefreshDisplayFlag(bool flag)
+      {
+         theRefreshDisplayFlag = flag;
+      }
+   bool getRefreshDisplayFlag()const
+      {
+         return theRefreshDisplayFlag;
+      }
+protected:
+   ossimObject*           theView;
+   ossimGpt               theCenterPoint;
+   ossimViewEventType     theEventType;
+   ossimViewPropagateType thePropagateType;
+   bool                   theUpdateInputViewFlag;
+   bool                   theRefreshDisplayFlag;
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimViewListener.cpp b/Utilities/OSSIM/ossim_core/base/common/events/ossimViewListener.cpp
new file mode 100644
index 0000000000..bad5f3409b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimViewListener.cpp
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimViewListener.cpp,v 1.3 2002/12/20 15:14:44 gpotts Exp $
+#include "ossimViewListener.h"
+
+RTTI_DEF1(ossimViewListener, "ossimViewListener", ossimListener);
+void ossimViewListener::processEvent(ossimEvent& event)
+{
+   ossimViewEvent* evt = PTR_CAST(ossimViewEvent, &event);
+
+   if(evt)
+   {
+      switch(evt->getViewEventType())
+      {
+      case  ossimViewEvent::OSSIM_VIEW_EVENT_SCALE_CHANGE:
+      {
+         viewScaleChangeEvent(*evt);
+         break;
+      }
+      case  ossimViewEvent::OSSIM_VIEW_EVENT_TYPE_GENERIC:
+      {
+         viewEvent(*evt);
+         break;
+      }
+      case ossimViewEvent::OSSIM_VIEW_EVENT_TRANSFORM_CHANGE:
+      {
+         viewTransformChangeEvent(*evt);
+         break;
+      }
+      case ossimViewEvent::OSSIM_VIEW_EVENT_VIEW_TYPE_CHANGE:
+      {
+         viewTypeChangeEvent(*evt);
+         break;
+      }
+      }
+      allViewEvents(*evt);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/events/ossimViewListener.h b/Utilities/OSSIM/ossim_core/base/common/events/ossimViewListener.h
new file mode 100644
index 0000000000..5dba34d20b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/events/ossimViewListener.h
@@ -0,0 +1,51 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimViewListener.h,v 1.3 2002/12/20 15:14:38 gpotts Exp $
+#ifndef ossimViewListener_HEADER
+#define ossimViewListener_HEADER
+#include "ossimListener.h"
+#include "ossimViewEvent.h"
+
+class OSSIMDLLEXPORT ossimViewListener : public ossimListener
+{
+public:
+   ossimViewListener():ossimListener(){}
+   virtual ~ossimViewListener(){}
+   
+   virtual void processEvent(ossimEvent& event);
+   virtual void viewScaleChangeEvent(ossimViewEvent& event)
+      {}
+   virtual void viewTypeChangeEvent(ossimViewEvent& event)
+      {}
+   virtual void viewEvent(ossimViewEvent& event)
+      {}
+   virtual void viewTransformChangeEvent(ossimViewEvent& event)
+      {}
+
+   virtual void allViewEvents(ossimViewEvent& event)
+      {}
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimApplicationUsage.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimApplicationUsage.cpp
new file mode 100644
index 0000000000..a3b622c238
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimApplicationUsage.cpp
@@ -0,0 +1,206 @@
+//-------------------------------------------------------------------------
+//
+// This code was taken from Open Scene Graph and incorporated from into
+// OSSIM.
+//
+//-------------------------------------------------------------------------
+// $Id: ossimApplicationUsage.cpp,v 1.4 2005/09/08 11:01:02 gpotts Exp $
+#include <base/common/ossimApplicationUsage.h>
+#include <base/common/ossimCommon.h>
+
+ossimApplicationUsage::ossimApplicationUsage(const ossimString& commandLineUsage):
+    theCommandLineUsage(commandLineUsage)
+{
+}
+
+ossimApplicationUsage* ossimApplicationUsage::instance()
+{
+    static ossimApplicationUsage theApplicationUsage;
+    return &theApplicationUsage;
+}
+void ossimApplicationUsage::setApplicationName(const ossimString& name)
+{
+   theApplicationName = name;
+}
+
+const ossimString& ossimApplicationUsage::getApplicationName() const
+{
+   return theApplicationName;
+}
+void ossimApplicationUsage::setDescription(const ossimString& desc)
+{
+   theDescription = desc;
+}
+
+const ossimString& ossimApplicationUsage::getDescription() const
+{
+   return theDescription;
+}
+
+void ossimApplicationUsage::addUsageExplanation(Type type,const ossimString& option,const ossimString& explanation)
+{
+    switch(type)
+    {
+        case(OSSIM_COMMAND_LINE_OPTION):
+            addCommandLineOption(option,explanation);
+            break;
+        case(OSSIM_ENVIRONMENTAL_VARIABLE):
+            addEnvironmentalVariable(option,explanation);
+            break;
+    }
+}
+void ossimApplicationUsage::setCommandLineUsage(const ossimString& explanation)
+{
+   theCommandLineUsage=explanation;
+}
+
+const ossimString& ossimApplicationUsage::getCommandLineUsage() const
+{
+   return theCommandLineUsage;
+}
+
+void ossimApplicationUsage::addCommandLineOption(const ossimString& option,const ossimString& explanation)
+{
+    theCommandLineOptions[option]=explanation;
+}
+
+const ossimApplicationUsage::UsageMap& ossimApplicationUsage::getCommandLineOptions() const
+{
+   return theCommandLineOptions;
+}
+
+void ossimApplicationUsage::addEnvironmentalVariable(const ossimString& option,const ossimString& explanation)
+{
+    theEnvironmentalVariables[option]=explanation;
+}
+const ossimApplicationUsage::UsageMap& ossimApplicationUsage::getEnvironmentalVariables() const
+{
+   return theEnvironmentalVariables;
+}
+
+void ossimApplicationUsage::getFormatedString(ossimString& str, const UsageMap& um,unsigned int widthOfOutput)
+{
+
+    unsigned int maxNumCharsInOptions = 0;
+    ossimApplicationUsage::UsageMap::const_iterator citr;
+    for(citr=um.begin();
+        citr!=um.end();
+        ++citr)
+    {
+        maxNumCharsInOptions = ossimMax(maxNumCharsInOptions,(unsigned int)citr->first.length());
+    }
+    
+    unsigned int fullWidth = widthOfOutput;
+    unsigned int optionPos = 2;
+    unsigned int explanationPos = 2+maxNumCharsInOptions+2;
+    unsigned int explanationWidth = fullWidth-explanationPos;
+
+    ossimString line;
+    
+    for(citr=um.begin();
+        citr!=um.end();
+        ++citr)
+    {
+        line.assign(fullWidth,' ');
+        line.replace(optionPos,citr->first.length(),citr->first);
+        
+        const ossimString& explanation = citr->second;
+        ossimString::size_type pos = 0;
+        ossimString::size_type offset = 0;
+        bool firstInLine = true;
+        while (pos<explanation.length())
+        {
+            if (firstInLine) offset = 0;
+                    
+            // skip any leading white space.
+            while (pos<explanation.length() && *(explanation.begin()+pos)==' ')
+            {
+                if (firstInLine) ++offset;
+                ++pos;
+            }
+            
+            firstInLine = false;
+        
+            ossimString::size_type width = ossimMin((ossimString::size_type)(explanation.length()-pos),(ossimString::size_type)(explanationWidth-offset));
+            ossimString::size_type slashn_pos = explanation.find('\n',pos);
+            
+            unsigned int extraSkip = 0;
+            bool concatinated = false;
+            if (slashn_pos!=ossimString::npos)
+            {
+                if (slashn_pos<pos+width)
+                {
+                    width = slashn_pos-pos;
+                    ++extraSkip;
+                    firstInLine = true;
+                }
+                else if (slashn_pos==pos+width) 
+                {
+                    ++extraSkip;
+                    firstInLine = true;
+                }
+            }
+            
+            if (pos+width<explanation.length())
+            {
+                // now reduce width until we get a space or a return
+                // so that we ensure that whole words are printed.
+                while (width>0 && 
+                       *(explanation.begin()+(pos+width))!=' ' && 
+                       *(explanation.begin()+(pos+width))!='\n') --width;
+                       
+                if (width==0)
+                {
+                    // word must be longer than a whole line so will need
+                    // to concatinate it.
+                    width = explanationWidth-1;
+                    concatinated = true;
+                }
+            }
+
+            line.replace(explanationPos+offset,explanationWidth, explanation, pos, width);
+
+            if (concatinated) { str += line; str += "-\n"; }
+            else { str += line; str += "\n"; }
+            
+            // move to the next line of output.
+            line.assign(fullWidth,' ');
+            
+            pos += width+extraSkip;
+
+            
+        }
+                
+    }
+}
+
+void ossimApplicationUsage::write(std::ostream& output, const ossimApplicationUsage::UsageMap& um,unsigned int widthOfOutput)
+{
+    ossimString str;
+    getFormatedString(str, um, widthOfOutput);
+    output << str << std::endl;
+}
+
+void ossimApplicationUsage::write(std::ostream& output, unsigned int type, unsigned int widthOfOutput)
+{
+
+    output << "Usage: "<<getCommandLineUsage()<<std::endl;
+    bool needspace = false;
+    if ((type&OSSIM_COMMAND_LINE_OPTION) && !getCommandLineOptions().empty())
+    {
+        if (needspace) output << std::endl;
+        output << "Options:"<<std::endl;
+        write(output,getCommandLineOptions(),widthOfOutput);
+        needspace = true;
+    }
+    
+    if ((type&OSSIM_ENVIRONMENTAL_VARIABLE) && !getEnvironmentalVariables().empty())
+    {
+        if (needspace) output << std::endl;
+        output << "Environmental Variables:"<<std::endl;
+        write(output,getEnvironmentalVariables(),widthOfOutput);
+        needspace = true;
+    }
+
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimApplicationUsage.h b/Utilities/OSSIM/ossim_core/base/common/ossimApplicationUsage.h
new file mode 100644
index 0000000000..a5f68a6e09
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimApplicationUsage.h
@@ -0,0 +1,85 @@
+//-------------------------------------------------------------------------
+//
+// This code was taken from Open Scene Graph and incorporated from into
+// OSSIM.
+//
+//-------------------------------------------------------------------------
+// $Id: ossimApplicationUsage.h,v 1.3 2005/08/18 14:31:44 gpotts Exp $
+#ifndef ossimApplicationUsage_HEADER
+#define ossimApplicationUsage_HEADER 1
+
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimString.h>
+#include <map>
+#include <string>
+#include <iostream>
+
+class OSSIMDLLEXPORT ossimApplicationUsage
+{
+    public:
+        
+        static ossimApplicationUsage* instance();
+
+        ossimApplicationUsage() {}
+
+        ossimApplicationUsage(const ossimString& commandLineUsage);
+
+        typedef std::map<ossimString,ossimString> UsageMap;
+        
+
+        void setApplicationName(const ossimString& name);
+        const ossimString& getApplicationName() const;
+
+        void setDescription(const ossimString& desc);
+        const ossimString& getDescription() const;
+
+        enum Type
+        {
+            OSSIM_COMMAND_LINE_OPTION    = 0x1,
+            OSSIM_ENVIRONMENTAL_VARIABLE = 0x2
+        };
+        
+        void addUsageExplanation(Type type,const ossimString& option,const ossimString& explanation);
+        
+        void setCommandLineUsage(const ossimString& explanation);
+
+        const ossimString& getCommandLineUsage() const;
+
+
+        void addCommandLineOption(const ossimString& option,const ossimString& explanation);
+        
+        const UsageMap& getCommandLineOptions() const;
+
+
+        void addEnvironmentalVariable(const ossimString& option,const ossimString& explanation);
+        
+        const UsageMap& getEnvironmentalVariables() const;
+
+        void getFormatedString(ossimString& str, const UsageMap& um,unsigned int widthOfOutput=80);
+
+        void write(std::ostream& output,const UsageMap& um,unsigned int widthOfOutput=80);
+        
+        void write(std::ostream& output,unsigned int type=OSSIM_COMMAND_LINE_OPTION|OSSIM_ENVIRONMENTAL_VARIABLE, unsigned int widthOfOutput=80);
+
+    protected:
+    
+        ossimString theApplicationName;
+        ossimString theDescription;
+        ossimString theCommandLineUsage;
+        UsageMap    theCommandLineOptions;
+        UsageMap    theEnvironmentalVariables;
+};
+
+class ApplicationUsageProxy
+{   
+    public:
+
+        /** register an explanation of commandline/evironmentalvaraible/keyboard mouse usage.*/
+        ApplicationUsageProxy(ossimApplicationUsage::Type type,const ossimString& option,const ossimString& explanation)
+        {
+            ossimApplicationUsage::instance()->addUsageExplanation(type,option,explanation);
+        }
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimArgumentParser.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimArgumentParser.cpp
new file mode 100644
index 0000000000..c1adbdc360
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimArgumentParser.cpp
@@ -0,0 +1,468 @@
+//-------------------------------------------------------------------------
+//
+// This code was taken from Open Scene Graph and incorporated from into
+// OSSIM.
+//
+//-------------------------------------------------------------------------
+// $Id: ossimArgumentParser.cpp,v 1.4 2005/04/01 20:39:25 dburken Exp $
+#include <base/common/ossimArgumentParser.h>
+#include <base/common/ossimApplicationUsage.h>
+#include <set>
+#include <iostream>
+#include <base/data_types/ossimString.h>
+
+bool ossimArgumentParser::isOption(const char* str)
+{
+    return str && str[0]=='-';
+}
+
+bool ossimArgumentParser::isString(const char* str)
+{
+    if (!str) return false;
+
+    return true;
+//    return !isOption(str);
+}
+
+bool ossimArgumentParser::isNumber(const char* str)
+{
+   if (!str) return false;
+   
+   bool hadPlusMinus = false;
+    bool hadDecimalPlace = false;
+    bool hadExponent = false;
+    bool couldBeInt = true;
+    bool couldBeFloat = true;
+    int noZeroToNine = 0;
+
+    const char* ptr = str;
+
+    // check if could be a hex number.
+    if (strncmp(ptr,"0x",2)==0)
+    {
+        // skip over leading 0x, and then go through rest of string
+        // checking to make sure all values are 0...9 or a..f.
+        ptr+=2;
+        while (
+               *ptr!=0 &&
+               ((*ptr>='0' && *ptr<='9') ||
+                (*ptr>='a' && *ptr<='f') ||
+                (*ptr>='A' && *ptr<='F'))
+              )
+        {
+            ++ptr;
+        }
+
+        // got to end of string without failure, therefore must be a hex integer.
+        if (*ptr==0) return true;
+    }
+
+    ptr = str;
+
+    // check if a float or an int.
+    while (*ptr!=0 && couldBeFloat)
+    {
+       if (*ptr=='+' || *ptr=='-')
+       {
+          if (hadPlusMinus)
+          {
+             couldBeInt = false;
+             couldBeFloat = false;
+          }
+          else
+          {
+             hadPlusMinus = true;
+          }
+       }
+       else if (*ptr>='0' && *ptr<='9')
+       {
+          noZeroToNine++;
+       }
+       else if (*ptr=='.')
+       {
+          if (hadDecimalPlace)
+          {
+             couldBeInt = false;
+             couldBeFloat = false;
+          }
+          else
+          {
+             hadDecimalPlace = true;
+             couldBeInt = false;
+          }
+       }
+       else if (*ptr=='e' || *ptr=='E')
+       {
+          if (hadExponent || noZeroToNine==0)
+          {
+             couldBeInt = false;
+             couldBeFloat = false;
+          }
+          else
+          {
+             hadExponent = true;
+             couldBeInt = false;
+             hadDecimalPlace = false;
+             hadPlusMinus = false;
+             noZeroToNine=0;
+          }
+       }
+       else
+       {
+          couldBeInt = false;
+          couldBeFloat = false;
+       }
+       ++ptr;
+    }
+
+    if (couldBeInt && noZeroToNine>0) return true;
+    if (couldBeFloat && noZeroToNine>0) return true;
+
+    return false;
+
+}
+
+bool ossimArgumentParser::ossimParameter::valid(const char* str) const
+{
+    switch(theType)
+    {
+       case ossimParameter::OSSIM_FLOAT_PARAMETER:        return isNumber(str);
+       case ossimParameter::OSSIM_DOUBLE_PARAMETER:       return isNumber(str);
+       case ossimParameter::OSSIM_INT_PARAMETER:          return isNumber(str);
+       case ossimParameter::OSSIM_UNSIGNED_INT_PARAMETER: return isNumber(str);
+       case ossimParameter::OSSIM_STRING_PARAMETER:       return isString(str);
+    }
+    return false;
+}
+
+bool ossimArgumentParser::ossimParameter::assign(const char* str)
+{
+    if (valid(str))
+    {
+        switch(theType)
+        {
+           case ossimParameter::OSSIM_FLOAT_PARAMETER:        *theValue.theFloat = (float)ossimString(str).toDouble(); break;
+           case ossimParameter::OSSIM_DOUBLE_PARAMETER:       *theValue.theDouble = ossimString(str).toDouble(); break;
+           case ossimParameter::OSSIM_INT_PARAMETER:          *theValue.theInt = ossimString(str).toInt(); break;
+           case ossimParameter::OSSIM_UNSIGNED_INT_PARAMETER: *theValue.theUint = ossimString(str).toUInt32(); break;
+           case ossimParameter::OSSIM_STRING_PARAMETER:       *theValue.theString = str; break;
+        }
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+
+ossimArgumentParser::ossimArgumentParser(int* argc,char **argv):
+    theArgc(argc),
+    theArgv(argv),
+    theUsage(ossimApplicationUsage::instance())
+{
+}
+
+ossimArgumentParser::~ossimArgumentParser()
+{
+}
+
+std::string ossimArgumentParser::getApplicationName() const
+{
+    if (theArgc && *theArgc>0 ) return std::string(theArgv[0]);
+    return "";
+}
+
+
+bool ossimArgumentParser::isOption(int pos) const
+{
+    return pos<*theArgc && isOption(theArgv[pos]);
+}
+
+bool ossimArgumentParser::isString(int pos) const
+{
+    return pos < *theArgc && isString(theArgv[pos]);
+}
+
+bool ossimArgumentParser::isNumber(int pos) const
+{
+    return pos < *theArgc && isNumber(theArgv[pos]);
+}
+
+
+int ossimArgumentParser::find(const std::string& str) const
+{
+    for(int pos=1;pos<*theArgc;++pos)
+    {
+        if (str==theArgv[pos])
+        {
+            return pos;
+        }
+    }
+    return 0;
+}
+
+bool ossimArgumentParser::match(int pos, const std::string& str) const
+{
+    return pos<*theArgc && str==theArgv[pos];
+}
+
+
+bool ossimArgumentParser::containsOptions() const
+{
+    for(int pos=1;pos<*theArgc;++pos)
+    {
+        if (isOption(pos)) return true;
+    }
+    return false;
+}
+
+
+void ossimArgumentParser::remove(int pos,int num)
+{
+    if (num==0) return;
+
+    for(;pos+num<*theArgc;++pos)
+    {
+        theArgv[pos]=theArgv[pos+num];
+    }
+    for(;pos<*theArgc;++pos)
+    {
+        theArgv[pos]=0;
+    }
+    *theArgc-=num;
+}
+
+bool ossimArgumentParser::read(const std::string& str)
+{
+    int pos=find(str);
+    if (pos<=0) return false;
+    remove(pos);
+    return true;
+}
+
+bool ossimArgumentParser::read(const std::string& str, ossimParameter value1)
+{
+    int pos=find(str);
+    if (pos<=0) return false;
+    if (!value1.valid(theArgv[pos+1]))
+    {
+        reportError("argument to `"+str+"` is missing");
+        return false;
+    }
+    value1.assign(theArgv[pos+1]);
+    remove(pos,2);
+    return true;
+}
+
+bool ossimArgumentParser::read(const std::string& str, ossimParameter value1, ossimParameter value2)
+{
+    int pos=find(str);
+    if (pos<=0) return false;
+    if (!value1.valid(theArgv[pos+1]) ||
+        !value2.valid(theArgv[pos+2]))
+    {
+        reportError("argument to `"+str+"` is missing");
+        return false;
+    }
+    value1.assign(theArgv[pos+1]);
+    value2.assign(theArgv[pos+2]);
+    remove(pos,3);
+    return true;
+}
+
+bool ossimArgumentParser::read(const std::string& str, ossimParameter value1, ossimParameter value2, ossimParameter value3)
+{
+    int pos=find(str);
+    if (pos<=0) return false;
+    if (!value1.valid(theArgv[pos+1]) ||
+        !value2.valid(theArgv[pos+2]) ||
+        !value2.valid(theArgv[pos+3]))
+    {
+        reportError("argument to `"+str+"` is missing");
+        return false;
+    }
+    value1.assign(theArgv[pos+1]);
+    value2.assign(theArgv[pos+2]);
+    value3.assign(theArgv[pos+3]);
+    remove(pos,4);
+    return true;
+}
+
+bool ossimArgumentParser::read(const std::string& str, ossimParameter value1, ossimParameter value2, ossimParameter value3, ossimParameter value4)
+{
+    int pos=find(str);
+    if (pos<=0) return false;
+    if (!value1.valid(theArgv[pos+1]) ||
+        !value2.valid(theArgv[pos+2]) ||
+        !value2.valid(theArgv[pos+3]) ||
+        !value3.valid(theArgv[pos+4]))
+    {
+        reportError("argument to `"+str+"` is missing");
+        return false;
+    }
+    value1.assign(theArgv[pos+1]);
+    value2.assign(theArgv[pos+2]);
+    value3.assign(theArgv[pos+3]);
+    value4.assign(theArgv[pos+4]);
+    remove(pos,5);
+    return true;
+}
+
+
+/** if the argument value at the psotion pos matches specified string, and subsequent
+  * paramters are also matched then set the paramter values and remove the from the list of arguments.*/
+bool ossimArgumentParser::read(int pos, const std::string& str)
+{
+    if (match(pos,str))
+    {
+        remove(pos,1);
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+bool ossimArgumentParser::read(int pos, const std::string& str, ossimParameter value1)
+{
+    if (match(pos,str) &&
+        value1.valid(theArgv[pos+1]))
+    {
+        value1.assign(theArgv[pos+1]);
+        remove(pos,2);
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+bool ossimArgumentParser::read(int pos, const std::string& str, ossimParameter value1, ossimParameter value2)
+{
+    if (match(pos,str) &&
+        value1.valid(theArgv[pos+1]) &&
+        value2.valid(theArgv[pos+2]))
+    {
+        value1.assign(theArgv[pos+1]);
+        value2.assign(theArgv[pos+2]);
+        remove(pos,3);
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+bool ossimArgumentParser::read(int pos, const std::string& str, ossimParameter value1, ossimParameter value2, ossimParameter value3)
+{
+    if (match(pos,str) &&
+        value1.valid(theArgv[pos+1]) &&
+        value2.valid(theArgv[pos+2]) &&
+        value3.valid(theArgv[pos+3]))
+    {
+        value1.assign(theArgv[pos+1]);
+        value2.assign(theArgv[pos+2]);
+        value3.assign(theArgv[pos+3]);
+        remove(pos,4);
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+bool ossimArgumentParser::read(int pos, const std::string& str, ossimParameter value1, ossimParameter value2, ossimParameter value3, ossimParameter value4)
+{
+    if (match(pos,str) &&
+        value1.valid(theArgv[pos+1]) &&
+        value2.valid(theArgv[pos+2]) &&
+        value3.valid(theArgv[pos+3]) &&
+        value4.valid(theArgv[pos+4]))
+    {
+        value1.assign(theArgv[pos+1]);
+        value2.assign(theArgv[pos+2]);
+        value3.assign(theArgv[pos+3]);
+        value4.assign(theArgv[pos+4]);
+        remove(pos,5);
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+
+bool ossimArgumentParser::errors(ossimErrorSeverity severity) const
+{
+    for(ossimErrorMessageMap::const_iterator itr=theErrorMessageMap.begin();
+        itr!=theErrorMessageMap.end();
+        ++itr)
+    {
+        if (itr->second>=severity) return true;
+    }
+    return false;
+}
+
+void ossimArgumentParser::reportError(const std::string& message, ossimErrorSeverity severity)
+{
+    theErrorMessageMap[message]=severity;
+}
+
+void ossimArgumentParser::reportRemainingOptionsAsUnrecognized(ossimErrorSeverity severity)
+{
+    std::set<std::string> options;
+    if (theUsage)
+    {
+        // parse the usage options to get all the option that the application can potential handle.
+        for(ossimApplicationUsage::UsageMap::const_iterator itr=theUsage->getCommandLineOptions().begin();
+            itr!=theUsage->getCommandLineOptions().end();
+            ++itr)
+        {
+            const std::string& option = itr->first;
+            std::string::size_type prevpos = 0, pos = 0;
+            while ((pos=option.find(' ',prevpos))!=std::string::npos)
+            {
+                if (option[prevpos]=='-')
+                {
+                    options.insert(std::string(option,prevpos,pos-prevpos));
+                }
+                prevpos=pos+1;
+            }
+            if (option[prevpos]=='-')
+            {
+
+                options.insert(std::string(option,prevpos,std::string::npos));
+            }
+        }
+
+    }
+
+    for(int pos=1;pos<argc();++pos)
+    {
+        // if an option and havn't been previous querried for report as unrecognized.
+        if (isOption(pos) && options.find(theArgv[pos])==options.end())
+        {
+            reportError(getApplicationName() +": unrecognized option "+theArgv[pos],severity);
+        }
+    }
+}
+void ossimArgumentParser::writeErrorMessages(std::ostream& output, ossimErrorSeverity severity)
+{
+    for(ossimErrorMessageMap::iterator itr=theErrorMessageMap.begin();
+        itr!=theErrorMessageMap.end();
+        ++itr)
+    {
+        if (itr->second>=severity)
+        {
+            output<< getApplicationName() << ": " << itr->first << std::endl;
+        }
+    }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimArgumentParser.h b/Utilities/OSSIM/ossim_core/base/common/ossimArgumentParser.h
new file mode 100644
index 0000000000..92fa48f7b1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimArgumentParser.h
@@ -0,0 +1,187 @@
+//-------------------------------------------------------------------------
+//
+// This code was taken from Open Scene Graph and incorporated from into
+// OSSIM.
+//
+//-------------------------------------------------------------------------
+// $Id: ossimArgumentParser.h,v 1.3 2005/04/01 20:39:25 dburken Exp $
+#ifndef ossimArgumentParser_HEADER
+#define ossimArgumentParser_HEADER 1
+#include <base/common/ossimConstants.h>
+#include <map>
+#include <string>
+#include <iostream>
+
+class ossimApplicationUsage;
+
+class OSSIMDLLEXPORT ossimArgumentParser
+{
+public:
+   
+   class ossimParameter
+   {
+   public:
+      enum ossimParameterType
+      {
+         OSSIM_FLOAT_PARAMETER,
+         OSSIM_DOUBLE_PARAMETER,
+         OSSIM_INT_PARAMETER,
+         OSSIM_UNSIGNED_INT_PARAMETER,
+         OSSIM_STRING_PARAMETER,
+      };
+      
+      union ossimValueUnion
+      {
+         float*          theFloat;
+         double*         theDouble;
+         int*            theInt;
+         unsigned int*   theUint;
+         std::string*    theString;
+      };
+      
+      ossimParameter(float& value)
+      {
+         theType = OSSIM_FLOAT_PARAMETER; theValue.theFloat = &value;
+      }
+      
+      ossimParameter(double& value)
+      {
+         theType = OSSIM_DOUBLE_PARAMETER; theValue.theDouble = &value;
+      }
+      
+      ossimParameter(int& value)
+      {
+         theType = OSSIM_INT_PARAMETER; theValue.theInt = &value;
+      }
+      
+      ossimParameter(unsigned int& value)
+      {
+         theType = OSSIM_UNSIGNED_INT_PARAMETER; theValue.theUint = &value;
+      }
+      
+      ossimParameter(std::string& value)
+      {
+         theType = OSSIM_STRING_PARAMETER; theValue.theString = &value;
+      }
+      
+      bool valid(const char* str) const;
+      bool assign(const char* str);
+      
+   protected:
+      
+      ossimParameterType   theType;
+      ossimValueUnion      theValue;
+   };
+   
+   /** return return true if specified string is an option in the form of
+    * -option or --option .
+    */
+   static bool isOption(const char* str);
+   
+   /** return return true if string is any other string apart from an option.*/
+   static bool isString(const char* str);
+   
+   /** return return true if specified parameter is an number.*/
+   static bool isNumber(const char* str);
+   
+public:
+   
+   ossimArgumentParser(int* argc,char **argv);
+
+   ~ossimArgumentParser();
+   
+   void setApplicationUsage(ossimApplicationUsage* usage) { theUsage = usage; }
+   ossimApplicationUsage* getApplicationUsage() { return theUsage; }
+   const ossimApplicationUsage* getApplicationUsage() const { return theUsage; }
+   
+   /** return the argument count.*/
+   int& argc() { return *theArgc; }
+   
+   /** return the argument array.*/
+   char** argv() { return theArgv; }
+   
+   /** return char* argument at specificed position.*/
+   char* operator [] (int pos) { return theArgv[pos]; }
+   
+   /** return const char* argument at specificed position.*/
+   const char* operator [] (int pos) const { return theArgv[pos]; }
+   
+   /** return the application name, as specified by argv[0] */
+   std::string getApplicationName() const;
+   
+   /** return the position of an occurance of a string in the argument list.
+    * return -1 when no string is found.*/      
+   int find(const std::string& str) const;
+   
+   /** return return true if specified parameter is an option in the form of -option or --option .*/
+   bool isOption(int pos) const;
+   
+   /** return return true if specified parameter is an string, which can be any other string apart from an option.*/
+   bool isString(int pos) const;
+   
+   /** return return true if specified parameter is an number.*/
+   bool isNumber(int pos) const;
+   
+   bool containsOptions() const;
+   
+   /** remove one or more arguments from the argv argument list, and decrement the argc respectively.*/
+   void remove(int pos,int num=1);
+   
+   /** return true if specified argument matches string.*/        
+   bool match(int pos, const std::string& str) const;
+   
+   /** search for an occurance of a string in the argument list, on sucess
+    * remove that occurance from the list and return true, otherwise return false.*/
+   bool read(const std::string& str);
+   bool read(const std::string& str, ossimParameter value1);
+   bool read(const std::string& str, ossimParameter value1, ossimParameter value2);
+   bool read(const std::string& str, ossimParameter value1, ossimParameter value2, ossimParameter value3);
+   bool read(const std::string& str, ossimParameter value1, ossimParameter value2, ossimParameter value3, ossimParameter value4);
+   
+   
+   /** if the argument value at the position pos matches specified string, and subsequent
+    * paramters are also matched then set the paramter values and remove the from the list of arguments.*/
+   bool read(int pos, const std::string& str);
+   bool read(int pos, const std::string& str, ossimParameter value1);
+   bool read(int pos, const std::string& str, ossimParameter value1, ossimParameter value2);
+   bool read(int pos, const std::string& str, ossimParameter value1, ossimParameter value2, ossimParameter value3);
+   bool read(int pos, const std::string& str, ossimParameter value1, ossimParameter value2, ossimParameter value3, ossimParameter value4);
+   
+   
+   enum ossimErrorSeverity
+   {
+      OSSIM_BENIGN = 0,
+      OSSIM_CRITICAL = 1
+   };
+   
+   typedef std::map<std::string,ossimErrorSeverity> ossimErrorMessageMap;
+   
+   /** return the error flag, true if an error has occured when reading arguments.*/
+   bool errors(ossimErrorSeverity severity=OSSIM_BENIGN) const;
+   
+   /** report an error message by adding to the ErrorMessageMap.*/
+   void reportError(const std::string& message,ossimErrorSeverity severity=OSSIM_CRITICAL);
+   
+   /** for each remaining option report it as an unrecongnized.*/
+   void reportRemainingOptionsAsUnrecognized(ossimErrorSeverity severity=OSSIM_BENIGN);
+   
+   /** return the error message, if any has occured.*/
+   ossimErrorMessageMap& getErrorMessageMap() { return theErrorMessageMap; }
+   
+   /** return the error message, if any has occured.*/
+   const ossimErrorMessageMap& getErrorMessageMap() const { return theErrorMessageMap; }
+   
+   /** write out error messages at an above specified .*/
+   void writeErrorMessages(std::ostream& output,ossimErrorSeverity sevrity=OSSIM_BENIGN);
+   
+   
+protected:
+   
+   int*                     theArgc;
+   char**                   theArgv;
+   ossimErrorMessageMap     theErrorMessageMap;
+   ossimApplicationUsage*   theUsage;
+        
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimCommon.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimCommon.cpp
new file mode 100644
index 0000000000..42350b5204
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimCommon.cpp
@@ -0,0 +1,325 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems, Inc.  All rights reserved.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: David Burken
+//
+// Description: Common file for global functions.
+//
+//*************************************************************************
+// $Id: ossimCommon.cpp,v 1.9 2006/01/10 21:04:02 gpotts Exp $
+
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimPreferences.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/data_types/ossimIpt.h>
+#include <sstream>
+
+ossimMutex theCriticalSectionMutex;
+
+static ossimTrace traceDebug("ossimCommon:debug");
+
+ossimByteOrder ossimGetByteOrder()
+{
+   union
+   {
+      short s;
+      char  c[sizeof(short)];
+   } un;
+
+   un.s = 0x0102;
+   if (un.c[0] ==  2 && un.c[1] == 1)
+   {
+      return OSSIM_LITTLE_ENDIAN;
+   }
+   else
+   {
+      return OSSIM_BIG_ENDIAN;
+   }
+}
+
+double ossimGetDefaultMin(ossimScalarType scalarType)
+{
+   switch(scalarType)
+   {
+      case OSSIM_UINT8:
+      {
+	return OSSIM_DEFAULT_MIN_PIX_UCHAR;
+      }
+      case OSSIM_SINT8:
+      {
+	return OSSIM_DEFAULT_MIN_PIX_SINT8;
+      }
+      case OSSIM_UINT16:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_UINT16;
+      }
+      case OSSIM_SINT16:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_SINT16;
+      }
+      case OSSIM_USHORT11:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_UINT11;
+      }
+      case OSSIM_UINT32:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_UINT32;
+      }
+      case OSSIM_SINT32:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_SINT32;
+      }
+      case OSSIM_FLOAT32:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_FLOAT;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
+      }
+      case OSSIM_FLOAT64:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_DOUBLE;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_NORM_DOUBLE;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << __FILE__ << ":" << __LINE__
+               << "\nUnhandled scalar type:  " << scalarType << endl;
+         }
+         break;
+      }
+   }
+   
+   return OSSIM_DBL_NAN;
+}
+
+double ossimGetDefaultMax(ossimScalarType scalarType)
+{
+   switch(scalarType)
+   {
+      case OSSIM_UINT8:
+      {
+         return OSSIM_DEFAULT_MAX_PIX_UCHAR;
+      }
+      case OSSIM_SINT8:
+      {
+         return OSSIM_DEFAULT_MAX_PIX_SINT8;
+      }
+      case OSSIM_UINT16:
+      {
+	return OSSIM_DEFAULT_MAX_PIX_UINT16;
+      }
+      case OSSIM_SINT16:
+      {
+         return OSSIM_DEFAULT_MAX_PIX_SINT16;
+      }
+      case OSSIM_USHORT11:
+      {
+         return OSSIM_DEFAULT_MAX_PIX_UINT11;
+      }
+      case OSSIM_UINT32:
+      {
+	return OSSIM_DEFAULT_MAX_PIX_UINT32;
+      }
+      case OSSIM_SINT32:
+      {
+         return OSSIM_DEFAULT_MAX_PIX_SINT32;
+      }
+      case OSSIM_FLOAT32:
+      {
+         return OSSIM_DEFAULT_MAX_PIX_FLOAT;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         return OSSIM_DEFAULT_MAX_PIX_NORM_FLOAT;
+      }
+      case OSSIM_FLOAT64:
+      {
+         return OSSIM_DEFAULT_MAX_PIX_DOUBLE;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         return OSSIM_DEFAULT_MAX_PIX_NORM_DOUBLE;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << __FILE__ << ":" << __LINE__
+               << "\nUnhandled scalar type:  " << scalarType << endl;
+         }
+         break;
+      }
+   }
+   return OSSIM_DBL_NAN;
+}
+
+double ossimGetDefaultNull(ossimScalarType scalarType)
+{
+   switch(scalarType)
+   {
+      case OSSIM_UINT8:
+      {
+         return 0;
+      }
+      case OSSIM_SINT8:
+      {
+         return OSSIM_DEFAULT_MIN_PIX_SINT8-10;
+      }
+      case OSSIM_UINT16:
+      {
+         return 0;
+      }
+      case OSSIM_SINT16:
+      {
+         return OSSIM_SSHORT_NAN;
+      }
+      case OSSIM_USHORT11:
+      {
+         return 0;
+      }
+      case OSSIM_UINT32:
+      {
+         return 0;
+      }
+      case OSSIM_SINT32:
+      {
+         return OSSIM_INT_NAN;
+      }
+      case OSSIM_FLOAT32:
+      {
+         return OSSIM_FLT_NAN;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         return 0.0;
+      }
+      case OSSIM_FLOAT64:
+      {
+         return OSSIM_DBL_NAN;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         return 0.0;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << __FILE__ << ":" << __LINE__
+               << "\nUnhandled scalar type:  " << scalarType << endl;
+         }
+         break;
+      }
+    }
+
+  return OSSIM_DBL_NAN;
+}
+
+ossim_uint32 ossimGetScalarSizeInBytes(ossimScalarType scalarType)
+{
+   switch(scalarType)
+   {
+      case OSSIM_UINT8:
+      {
+         return sizeof(ossim_uint8);
+      }
+      case OSSIM_SINT8:
+      {
+         return sizeof(ossim_sint8);
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         return sizeof(ossim_uint16);
+      }
+      case OSSIM_SINT16:
+      {
+         return sizeof(ossim_sint16);
+      }
+      case OSSIM_UINT32:
+      {
+         return sizeof(ossim_uint32);
+      }
+      case OSSIM_SINT32:
+      {
+         return sizeof(ossim_sint32);
+      }
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         return sizeof(ossim_float32);
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         return sizeof(ossim_float64);
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << __FILE__ << ":" << __LINE__
+               << "\nUnhandled scalar type:  " << scalarType << endl;
+         }
+         break;
+      }
+  }
+  
+  return 1;
+}
+
+void ossimGetDefaultTileSize(ossimIpt& tileSize)
+{
+   const char* tileSizeKw = ossimPreferences::instance()->
+      findPreference("tile_size");
+
+   if(tileSizeKw)
+   {
+      std::istringstream in(tileSizeKw);
+      bool hasX = true;
+      in >> tileSize.x >> tileSize.y;
+      
+      if(tileSize.x < 1)
+      {
+         tileSize.x = OSSIM_DEFAULT_TILE_WIDTH;
+         hasX = false;
+      }
+      if(tileSize.y < 1)
+      {
+         if(!hasX)
+         {
+            tileSize.y = OSSIM_DEFAULT_TILE_HEIGHT;
+         }
+         else
+         {
+            tileSize.y = tileSize.x;
+         }
+      }
+   }
+   else
+   {
+      tileSize.x = OSSIM_DEFAULT_TILE_WIDTH;
+      tileSize.y = OSSIM_DEFAULT_TILE_HEIGHT;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimCommon.h b/Utilities/OSSIM/ossim_core/base/common/ossimCommon.h
new file mode 100644
index 0000000000..648817f79c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimCommon.h
@@ -0,0 +1,282 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// LICENSE: LGPL
+//
+// Author: Garrett Potts
+// Description: Common file for global functions.
+//
+//*************************************************************************
+// $Id: ossimCommon.h,v 1.24 2005/06/17 21:42:59 dburken Exp $
+#ifndef COMMON_H
+#define COMMON_H
+
+
+#include <cmath>
+#include <base/common/ossimMutex.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimRtti.h>
+
+class ossimIpt;
+
+/**
+ * Mutex for lock/unlocking.
+ */
+extern ossimMutex theCriticalSectionMutex;
+
+//***
+// Common math functions
+//***
+inline double  cosd(double X)   {return std::cos(X*RAD_PER_DEG);}
+inline double  sind(double X)   {return std::sin(X*RAD_PER_DEG);}
+inline double  tand(double X)   {return std::tan(X*RAD_PER_DEG);}
+inline double  acosd(double X)  {return DEG_PER_RAD * std::acos(X);}
+inline double  asind(double X)  {return DEG_PER_RAD * std::asin(X);}
+inline double  atand(double X)  {return DEG_PER_RAD * std::atan(X);}
+inline double  atan2d(double Y, double X)
+{
+   return DEG_PER_RAD * std::atan2(Y,X);
+}
+
+// Note: We use n and m as temporaries in this function, so there is no value
+// in using const IntType& as we would only need to make a copy anyway...
+template <typename IntType>
+IntType ossimGcd(IntType n, IntType m)
+{
+    // Avoid repeated construction
+    IntType zero(0);
+
+    // This is abs() - given the existence of broken compilers with Koenig
+    // lookup issues and other problems, I code this explicitly. (Remember,
+    // IntType may be a user-defined type).
+    if (n < zero)
+        n = -n;
+    if (m < zero)
+        m = -m;
+
+    // As n and m are now positive, we can be sure that %= returns a
+    // positive value (the standard guarantees this for built-in types,
+    // and we require it of user-defined types).
+    for(;;) {
+      if(m == zero)
+        return n;
+      n %= m;
+      if(n == zero)
+        return m;
+      m %= n;
+    }
+}
+
+template<class T> inline T ossimAbs(T val)
+{
+   return ( (val<0) ? ( val * ( (T)-1) ) : val );
+}
+
+template <typename IntType>
+IntType ossimLcm(IntType n, IntType m)
+{
+    // Avoid repeated construction
+    IntType zero(0);
+
+    if (n == zero || m == zero)
+        return zero;
+
+    n /= gcd(n, m);
+    n *= m;
+
+    if (n < zero)
+        n = -n;
+    return n;
+}
+
+inline bool ossimIsNan(double val)
+{
+   return (val == OSSIM_DBL_NAN);
+}
+
+inline bool ossimIsNan(float val)
+{
+   return (val == OSSIM_FLT_NAN);
+}
+
+inline bool ossimIsNan(int val)
+{
+   return (val == OSSIM_INT_NAN);
+}
+
+inline bool ossimIsNan(long val)
+{
+   return (val == OSSIM_INT_NAN);
+}
+
+inline bool ossimIsNan(unsigned long val)
+{
+   return (val == OSSIM_ULONG_NAN);
+}
+
+inline bool ossimIsNan(unsigned int val)
+{
+   return (val == OSSIM_UINT_NAN);
+}
+
+inline double sinc(double x)
+{
+   x *= M_PI;
+   if(x != 0)
+      return std::sin(x)/x;
+   else
+      return 1.0;
+}
+inline int ossimGetSign(double value)
+{
+   return (value < 0?-1:1);
+}
+
+#ifndef MAX
+#  define MAX(x,y) ((x)>(y)?(x):(y))
+#  define MIN(x,y) ((x)>(y)?(y):(x))
+#endif
+
+#ifndef ABS
+#  define ABS(x) ((x)>0?(x):-(x))
+#endif
+
+#ifndef SIGN
+#  define SIGN(x) ((x)<0?(-1):(1))
+#endif
+
+template<class T>
+T ossimClamp(const T& value,
+             const T& minValue,
+             const T& maxValue)
+{
+   if(value < minValue) return minValue;
+   if(value > maxValue) return maxValue;
+   return value;
+}
+
+template<class T>
+T ossimMax(T leftValue, T rightValue)
+{
+   if(leftValue < rightValue)
+   {
+      return rightValue;
+   }
+   return leftValue;
+}
+
+template<class T>
+T ossimMin(T leftValue, T rightValue)
+{
+   if(rightValue < leftValue)
+   {
+      return rightValue;
+   }
+   return leftValue;
+}
+
+
+template<class Type> inline Type SQ(Type &x) {return (x * x);}
+
+inline double square(double x)
+{
+   return x*x;
+}
+
+inline long square(long x)
+{
+   return x*x;
+}
+
+inline bool equals(double x, double y)
+{
+   return (ossimAbs(x-y) <= DBL_EPSILON);
+}
+
+inline bool equals(float x, float y)
+{
+   return (ossimAbs(x-y) <= FLT_EPSILON);
+}
+
+inline int factorial(int n)
+{
+   if(n == 0) return 1;
+   return (n * factorial(n - 1));
+}
+
+// Round a double to an int correctly.
+//inline int irint(double d) { return int(floor(d + 0.5)); }
+inline int irint(double d)
+{
+   return  (int) ((d < 0) ? (d-.5):(d+.5));
+}
+
+// Round a double to an int correctly.
+//inline long irlong(double d) { return long(floor(d + 0.5)); }
+inline int irlong(double d)
+{
+   return  (long) ((d < 0) ? (d-.5):(d+.5));
+}
+
+// Round a double to an int correctly.
+//inline int irint(double d) { return int(floor(d + 0.5)); }
+inline int irint(float d)
+{
+   return  (int) ((d < 0) ? (d-.5):(d+.5));
+}
+
+// Round a double to an int correctly.
+//inline long irlong(double d) { return long(floor(d + 0.5)); }
+inline int irlong(float d)
+{
+   return  (long) ((d < 0) ? (d-.5):(d+.5));
+}
+
+// Round a float to an int correctly.
+//inline int irint(f32 f) { return int(floor(f + 0.5)); }
+
+// Round a double to an int correctly.
+//inline long irlong(f32 f) { return long(floor(f + 0.5)); }
+
+// greatest common divisors of two integers
+inline int gcd(int m, int n)
+{
+   if(n == 0) return m;
+   return gcd(n, m % n);
+}
+
+//***
+// Common conversion functions
+//***
+inline double ft2mtrs(double feet)
+{
+   return (feet * MTRS_PER_FT);
+}
+
+inline double usft2mtrs(double feet)
+{
+   return (feet * US_METERS_PER_FT);
+}
+
+inline double mtrs2ft(double meters)
+{
+   return (meters / MTRS_PER_FT);
+}
+
+inline double mtrs2usft(double meters)
+{
+   return (meters / US_METERS_PER_FT);
+}
+
+ossimByteOrder ossimGetByteOrder();
+
+OSSIM_DLL double ossimGetDefaultMin(ossimScalarType scalarType);
+OSSIM_DLL double ossimGetDefaultMax(ossimScalarType scalarType);
+OSSIM_DLL double ossimGetDefaultNull(ossimScalarType scalarType);
+
+OSSIM_DLL ossim_uint32 ossimGetScalarSizeInBytes(ossimScalarType scalarType);
+
+
+OSSIM_DLL void ossimGetDefaultTileSize(ossimIpt& tileSize);
+
+#endif /* #ifndef COMMON_H */
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainer.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainer.cpp
new file mode 100644
index 0000000000..e81a530592
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainer.cpp
@@ -0,0 +1,772 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimConnectableContainer.cpp,v 1.48 2005/11/22 19:40:35 dburken Exp $
+#include <algorithm>
+#include <base/common/ossimConnectableContainer.h>
+#include <base/common/ossimIdManager.h>
+#include <base/common/events/ossimObjectDestructingEvent.h>
+#include <base/common/events/ossimPropertyEvent.h>
+#include <base/common/events/ossimConnectionEvent.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+#include <stack>
+using namespace std;
+
+static ossimTrace traceDebug("ossimConnectableContainer:debug");
+
+RTTI_DEF2(ossimConnectableContainer, "ossimConnectableContainer", ossimConnectableObject, ossimConnectableContainerInterface);
+
+class ossimConnectableContainerChildListener : public ossimConnectableObjectListener
+{
+public:
+   ossimConnectableContainerChildListener(ossimConnectableContainer* container)
+      :theContainer(container),
+       theEnabledFlag(true)
+      {}
+   void enableListener(){theEnabledFlag = true;}
+   void disableListener(){theEnabledFlag = false;}
+
+   virtual void objectDestructingEvent(ossimObjectDestructingEvent& event)
+      {
+         ossimConnectableObject* object = PTR_CAST(ossimConnectableObject, event.getObject());
+         if(object&&theContainer)
+         {
+            if(theContainer->removeChild(object))
+            {
+               object->removeListener((ossimConnectableObjectListener*) this);
+            }
+         }
+         propagatePropertyEvent(event);
+
+      }
+   virtual void disconnectInputEvent(ossimConnectionEvent& event)
+      {
+         propagatePropertyEvent(event);
+      }
+   virtual void connectInputEvent(ossimConnectionEvent& event)
+      {
+         propagatePropertyEvent(event);
+      }
+
+   void propagatePropertyEvent(ossimEvent& event)
+      {
+         if(theEnabledFlag)
+         {
+            if(event.getObject())
+            {
+               ossimConnectableObject* connectable = PTR_CAST(ossimConnectableObject,
+                                                             event.getObject());
+               if(connectable)
+               {
+                  ossimPropertyEvent evt(event.getObject());
+                  connectable->propagateEventToOutputs(evt);
+               }
+            }
+         }
+      }
+   ossimConnectableContainer* theContainer;
+   bool theEnabledFlag;
+
+};
+
+ossimConnectableContainer::ossimConnectableContainer(ossimConnectableObject* owner)
+   :ossimConnectableObject(owner, 0, 0, true, true),
+    ossimConnectableContainerInterface(NULL)
+{
+   ossimConnectableContainerInterface::theBaseObject = this;
+   theChildListener = new ossimConnectableContainerChildListener(this);
+}
+
+ossimConnectableContainer::~ossimConnectableContainer()
+{
+   // will need to destory and detach all children
+   //
+   deleteAllChildren();
+
+   if(theChildListener)
+   {
+      delete theChildListener;
+      theChildListener = NULL;
+   }
+}
+
+ossimConnectableObject* ossimConnectableContainer::findFirstObjectOfType(const RTTItypeid& typeInfo,
+                                                                         bool recurse)
+{
+   ossimConnectableObject* result = NULL;
+   connectablObjectMapType::iterator current;
+
+   current = theObjectMap.begin();
+   while(current != theObjectMap.end())
+   {
+      if(((*current).second)->canCastTo(typeInfo))
+      {
+         return (*current).second;
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current = theObjectMap.begin();
+      while(current != theObjectMap.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current).second);
+
+         if(child)
+         {
+            result = child->findFirstObjectOfType(typeInfo);
+            if(result)
+            {
+               return result;
+            }
+         }
+         ++current;
+      }
+   }
+
+   return result;
+}
+
+ossimConnectableObject* ossimConnectableContainer::findFirstObjectOfType(const ossimString& className,
+                                                                         bool recurse)
+{
+   ossimConnectableObject* result = NULL;
+   connectablObjectMapType::iterator current;
+
+   current = theObjectMap.begin();
+   while(current != theObjectMap.end())
+   {
+      if( ((*current).second)->canCastTo(className) )
+      {
+         return (*current).second;
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current = theObjectMap.begin();
+      while(current != theObjectMap.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current).second);
+
+         if(child)
+         {
+            result = child->findFirstObjectOfType(className);
+            if(result)
+            {
+               return result;
+            }
+         }
+         ++current;
+      }
+   }
+
+   return result;
+}
+
+std::vector<ossimConnectableObject*> ossimConnectableContainer::findAllObjectsOfType(const RTTItypeid& typeInfo,
+                                                                                     bool recurse)
+{
+   std::vector<ossimConnectableObject*> result;
+
+   connectablObjectMapType::iterator current;
+
+   current = theObjectMap.begin();
+   while(current != theObjectMap.end())
+   {
+      if(((*current).second)->canCastTo(typeInfo))
+      {
+         result.push_back( (*current).second);
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current = theObjectMap.begin();
+      while(current != theObjectMap.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current).second);
+
+         if(child)
+         {
+            vector<ossimConnectableObject*> temp;
+            temp = child->findAllObjectsOfType(typeInfo, recurse);
+            for(long index=0; index < (long)temp.size();++index)
+            {
+               result.push_back(temp[index]);
+            }
+         }
+         ++current;
+      }
+   }
+   return result;
+}
+
+std::vector<ossimConnectableObject*> ossimConnectableContainer::findAllObjectsOfType(const ossimString& className,
+                                                                                     bool recurse)
+{
+   std::vector<ossimConnectableObject*> result;
+
+   connectablObjectMapType::iterator current;
+
+   current = theObjectMap.begin();
+   while(current != theObjectMap.end())
+   {
+      if(((*current).second)->canCastTo(className))
+      {
+         result.push_back( (*current).second);
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current = theObjectMap.begin();
+      while(current != theObjectMap.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current).second);
+
+         if(child)
+         {
+            vector<ossimConnectableObject*> temp;
+            temp = child->findAllObjectsOfType(className, true);
+            for(long index=0; index < (long)temp.size();++index)
+            {
+               result.push_back(temp[index]);
+            }
+         }
+         ++current;
+      }
+   }
+   return result;
+}
+
+ossimConnectableObject* ossimConnectableContainer::findObject(const ossimId& id,
+                                                              bool recurse)
+{
+   connectablObjectMapType::iterator current;
+
+   current = theObjectMap.begin();
+
+   while(current != theObjectMap.end())
+   {
+      if((*current).second && ((*current).second->getId()==id))
+      {
+         return (*current).second;
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current = theObjectMap.begin();
+
+      while(current != theObjectMap.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current).second);
+
+         if(child)
+         {
+            ossimConnectableObject* object = child->findObject(id, true);
+
+            if(object) return object;
+         }
+         ++current;
+      }
+   }
+   return NULL;
+}
+
+ossimConnectableObject* ossimConnectableContainer::findObject(const ossimConnectableObject* obj,
+                                                              bool recurse)
+{
+   connectablObjectMapType::iterator current;
+
+   current = theObjectMap.begin();
+
+   while(current != theObjectMap.end())
+   {
+      if((*current).second && ((*current).second==obj))
+      {
+         return (*current).second;
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current = theObjectMap.begin();
+
+      while(current != theObjectMap.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current).second);
+
+         if(child)
+         {
+            ossimConnectableObject* object = child->findObject(obj, true);
+
+            if(object) return object;
+         }
+         ++current;
+      }
+   }
+
+   return NULL;
+}
+
+void ossimConnectableContainer::makeUniqueIds()
+{
+   connectablObjectMapType::iterator current;
+   vector<ossimConnectableObject*> objectList;
+
+
+   current = theObjectMap.begin();
+
+   setId(ossimIdManager::instance()->generateId());
+   while(current != theObjectMap.end())
+   {
+      objectList.push_back((*current).second);
+      ++current;
+   }
+   theObjectMap.clear();
+
+   for(long index = 0; index < (long)objectList.size(); ++index)
+   {
+      ossimConnectableContainerInterface* container = PTR_CAST(ossimConnectableContainerInterface,
+                                                               objectList[index]);
+      if(container)
+      {
+         container->makeUniqueIds();
+         theObjectMap.insert(make_pair(objectList[index]->getId().getId(),
+                                       objectList[index]));
+      }
+      else
+      {
+         objectList[index]->setId(ossimIdManager::instance()->generateId());
+         theObjectMap.insert(make_pair(objectList[index]->getId().getId(),
+                             objectList[index]));
+      }
+   }
+}
+
+ossim_uint32 ossimConnectableContainer::getNumberOfObjects(bool recurse)const
+{
+   ossim_uint32 result = 0;
+
+   connectablObjectMapType::const_iterator current;
+
+   current = theObjectMap.begin();
+
+   while(current != theObjectMap.end())
+   {
+      ++result;
+
+      if(recurse)
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current).second);
+         if(child)
+         {
+            result += child->getNumberOfObjects(true);
+         }
+      }
+      ++current;
+   }
+
+   return result;
+}
+
+bool ossimConnectableContainer::addChild(ossimConnectableObject* object)
+{
+   if(object)
+   {
+      // if it's not already a child
+      if(!findObject(object->getId()))
+      {
+         object->changeOwner(this);
+         theObjectMap.insert(make_pair(object->getId().getId(), object));
+//         object->addListener((ossimConnectableObjectListener*)this);
+         object->addListener(theChildListener);
+      }
+
+      return true;
+   }
+
+   return false;
+}
+
+bool ossimConnectableContainer::removeChild(ossimConnectableObject* object)
+{
+   ossimConnectableObject* result = NULL;
+
+   if(object)
+   {
+      connectablObjectMapType::iterator childIter = theObjectMap.find(object->getId().getId());
+      if(childIter != theObjectMap.end())
+      {
+         result = (*childIter).second;
+         if(result->getOwner() == this)
+         {
+            result->changeOwner(NULL);
+            result->removeListener(theChildListener);
+//            result->removeListener(this);
+         }
+         theObjectMap.erase(childIter);
+      }
+   }
+
+   return (result!=NULL);
+}
+
+bool ossimConnectableContainer::loadState(const ossimKeywordlist& kwl,
+                                               const char* prefix)
+{
+   static const char* MODULE = "ossimConnectableContainer::loadState(kwl, prefix)";
+
+   ossimString copyPrefix = prefix;
+   bool result = ossimConnectableObject::loadState(kwl, copyPrefix.c_str());
+
+   map<ossimId, vector<ossimId> > idMapping;
+   result = addAllObjects(idMapping, kwl, prefix);
+   if(!result)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " error: " << "problems adding sources" << endl;
+   }
+   result = connectAllObjects(idMapping);
+   if(!result)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " error: " << "problems connecting sources\n";
+   }
+
+   return result;
+}
+
+bool ossimConnectableContainer::saveState(ossimKeywordlist& kwl,
+                                          const char* prefix)const
+{
+   bool result = true;
+   connectablObjectMapType::const_iterator current;
+
+   ossim_int32 childIndex = 1;
+   current = theObjectMap.begin();
+   while(current != theObjectMap.end())
+   {
+     ossimString newPrefix = ( (ossimString(prefix) +
+				ossimString("object") +
+				ossimString::toString(childIndex) + "."));
+     if((*current).second)
+       {
+	 bool test = ((*current).second)->saveState(kwl, newPrefix);
+	 if(!test)
+	   {
+	     result = false;
+	   }
+       }
+     ++childIndex;
+     ++current;
+   }
+   if(result)
+   {
+      result = ossimConnectableObject::saveState(kwl, prefix);
+   }
+
+   return result;
+}
+
+void ossimConnectableContainer::getChildren(vector<ossimConnectableObject*>& children,
+                                               bool immediateChildrenOnlyFlag)
+{
+   connectablObjectMapType::iterator current;
+   current = theObjectMap.begin();
+   vector<ossimConnectableObject*> temp;
+
+   while(current != theObjectMap.end())
+   {
+      temp.push_back((*current).second);
+   }
+   ossim_uint32 i;
+   for(i = 0; i < temp.size();++i)
+   {
+
+      if(!immediateChildrenOnlyFlag)
+      {
+         ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                             (*current).second);
+         if(!inter)
+         {
+            children.push_back(temp[i]);
+         }
+      }
+      else
+      {
+         children.push_back(temp[i]);
+      }
+   }
+
+   if(!immediateChildrenOnlyFlag)
+   {
+      for(i = 0; i < temp.size(); ++i)
+      {
+         ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                             (*current).second);
+
+         if(inter)
+         {
+            inter->getChildren(children,
+                               immediateChildrenOnlyFlag);
+         }
+      }
+   }
+}
+
+void ossimConnectableContainer::deleteAllChildren()
+{
+   connectablObjectMapType::iterator current;
+   ossimConnectableObject* temp;
+   current = theObjectMap.begin();
+   removeAllListeners();
+
+   while(theObjectMap.size())
+   {
+      current = theObjectMap.begin();
+      temp = (*current).second;
+      if(temp)
+      {
+//         temp->removeListener((ossimConnectableObjectListener*) this);
+         temp->removeListener(theChildListener);
+         (*current).second = NULL;
+      }
+      theObjectMap.erase(current);
+      if(temp)
+      {
+         delete temp;
+      }
+   }
+}
+
+void ossimConnectableContainer::removeAllListeners()
+{
+   connectablObjectMapType::iterator current;
+   ossimConnectableObject* temp;
+   current = theObjectMap.begin();
+
+   while(current != theObjectMap.end())
+   {
+      temp = (*current).second;
+      if(temp)
+      {
+         temp->removeListener(theChildListener);
+//         temp->removeListener((ossimConnectableObjectListener*) this);
+      }
+      ++current;
+   }
+}
+
+bool ossimConnectableContainer::addAllObjects(map<ossimId,
+                                              vector<ossimId> >& idMapping,
+                                              const ossimKeywordlist& kwl,
+                                              const char* prefix)
+{
+   ossimString copyPrefix = prefix;
+
+   vector<ossimId> inputConnectionIds;
+
+   ossimString regExpression =  ossimString("^(") + copyPrefix + "object[0-9]+.)";
+   vector<ossimString> keys =
+      kwl.getSubstringKeyList( regExpression );
+   long numberOfSources = keys.size();
+
+   int offset = (copyPrefix+"object").size();
+   int idx = 0;
+   std::vector<int> theNumberList(numberOfSources);
+   for(idx = 0; idx < (int)theNumberList.size();++idx)
+     {
+       ossimString numberStr(keys[idx].begin() + offset,
+			     keys[idx].end());
+       theNumberList[idx] = numberStr.toInt();
+     }
+   std::sort(theNumberList.begin(), theNumberList.end());
+   for(idx=0;idx < (int)theNumberList.size();++idx)
+   {
+      ossimString newPrefix = copyPrefix;
+      newPrefix += ossimString("object");
+      newPrefix += ossimString::toString(theNumberList[idx]);
+      newPrefix += ossimString(".");
+
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "trying to create source with prefix: " << newPrefix << "\n";
+      }
+      ossimObject* object = ossimObjectFactoryRegistry::instance()->createObject(kwl,
+                                                                                 newPrefix.c_str());
+      if(object)
+      {
+         ossimConnectableObject* connectable = PTR_CAST(ossimConnectableObject, object);
+         if(connectable)
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "Created source with prefix: " << newPrefix << "\n";
+            }
+            // we did find a source so include it in the count
+            ossimId id = connectable->getId();
+            inputConnectionIds.clear();
+
+            findInputConnectionIds(inputConnectionIds,
+                                   kwl,
+                                   newPrefix);
+
+            if(inputConnectionIds.size() != 0)
+            {
+               idMapping.insert(std::make_pair(id, inputConnectionIds));
+            }
+            addChild(connectable);
+         }
+         else
+         {
+            delete object;
+            object = NULL;
+         }
+      }
+   }
+
+   return true;
+}
+
+void ossimConnectableContainer::findInputConnectionIds(vector<ossimId>& result,
+                                                       const ossimKeywordlist& kwl,
+                                                       const char* prefix)
+{
+   ossimString newPrefix = prefix;
+   long counter = 0;
+
+   long numberOfMatches = 0;
+
+   ossimString regExpression =  ossimString("^") + newPrefix + "input_connection[0-9]+";
+   long numberOfKeys = kwl.getNumberOfSubstringKeys( regExpression);
+   vector<ossimString> l = kwl.getSubstringKeyList(regExpression);
+   if(numberOfKeys > 0)
+   {
+      newPrefix += "input_connection";
+
+      while(numberOfMatches < numberOfKeys)
+      {
+         const char* lookup = kwl.find(newPrefix,
+                                       ossimString::toString(counter));
+         if(lookup)
+         {
+            ++numberOfMatches;
+            long id = ossimString(lookup).toLong();
+            if(id != ossimId::INVALID_ID)
+            {
+               result.push_back(ossimId(id));
+            }
+         }
+         ++counter;
+      }
+   }
+}
+
+bool ossimConnectableContainer::connectAllObjects(const map<ossimId, vector<ossimId> >& idMapping)
+{
+   if(idMapping.size())
+   {
+      map<ossimId, vector<ossimId> >::const_iterator iter = idMapping.begin();
+
+      while(iter != idMapping.end())
+      {
+         ossimConnectableObject* currentObject = findObject((*iter).first);
+
+         if(currentObject)
+         {
+            long upperBound = (*iter).second.size();
+            for(long index = 0; index < upperBound; ++index)
+            {
+               ossimConnectableObject* inputObject = findObject((*iter).second[index]);
+
+               currentObject->connectMyInputTo(index, inputObject);
+            }
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_FATAL) << "ossimConnectableContainer::connectAllObjects, Could not find " << (*iter).first << " for source: \n";
+            return false;
+         }
+         ++iter;
+      }
+   }
+   return true;
+}
+
+ossimObject* ossimConnectableContainer::getObject()
+{
+   return this;
+}
+
+const ossimObject* ossimConnectableContainer::getObject()const
+{
+   return this;
+}
+
+ossimConnectableObject* ossimConnectableContainer::getConnectableObject(
+   ossim_uint32 index)
+{
+   ossimConnectableObject* result = NULL;
+
+   if (index > theObjectMap.size())
+   {
+      return result;
+   }
+
+   connectablObjectMapType::iterator current;
+   current = theObjectMap.begin();
+   ossim_uint32 i = 0;
+   while(current != theObjectMap.end())
+   {
+      if (i == index)
+      {
+         return (*current).second;
+      }
+      ++current;
+      ++i;
+   }
+   
+   return result; 
+}
+
+bool ossimConnectableContainer::canConnectMyInputTo(ossim_int32,
+                                                    const ossimConnectableObject*) const
+{
+   return false;
+}
+
+bool ossimConnectableContainer::canConnectMyOutputTo(ossim_int32,
+                                                     const ossimConnectableObject*) const
+{
+   return false;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainer.h b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainer.h
new file mode 100644
index 0000000000..6e95777114
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainer.h
@@ -0,0 +1,184 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimConnectableContainer.h,v 1.28 2005/11/22 19:40:35 dburken Exp $
+
+#ifndef ossimConnectableContainer_HEADER
+#define ossimConnectableContainer_HEADER
+#include <map>
+
+#include "ossimConnectableObject.h"
+#include "base/common/events/ossimConnectableObjectListener.h"
+#include "ossimConnectableContainerInterface.h"
+
+class OSSIMDLLEXPORT ossimConnectableContainerChildListener;
+
+class OSSIMDLLEXPORT ossimConnectableContainer : public ossimConnectableObject,
+                                  public ossimConnectableContainerInterface,
+                                  public ossimConnectableObjectListener
+{
+public:
+   typedef std::map<long, ossimConnectableObject*> connectablObjectMapType;
+   
+   ossimConnectableContainer(ossimConnectableObject* owner=NULL);
+   virtual ~ossimConnectableContainer();
+
+   virtual ossimObject* getObject();
+   
+   virtual const ossimObject* getObject()const;
+
+   /**
+    * @param index Index of object to get.
+    *
+    * @see getNumberOfObjects(false) to get the number of objects inside
+    * the container.
+    *
+    * @return Container's object at that index or NULL if out of range.
+    *
+    * @note This does not recurse into other containers.
+    */
+   virtual ossimConnectableObject* getConnectableObject(ossim_uint32 index);
+
+   
+   /*!
+    * Will find all objects of the past in type.  Use the RTTI type info.
+    * An optional recurse flag will say if there is another container then
+    * recurse it to find the type you are looking for else it just looks
+    * within its immediate children.
+    * 
+    * Example: passing STATIC_TYPE_INFO(ossimImageRenderer) as an argument will
+    *          look for all ossimImageRenderer's and return the list.
+    */
+   virtual std::vector<ossimConnectableObject*> findAllObjectsOfType(const RTTItypeid& typeInfo,
+                                                            bool recurse=true);
+   virtual std::vector<ossimConnectableObject*> findAllObjectsOfType(const ossimString& className,
+                                                            bool recurse=true);
+
+   /*!
+    * Will find the firt object of the past in type.  Use the RTTI type info.
+    * An optional recurse flag will say if there is another container then
+    * recurse it to find the type you are looking for else it just looks
+    * within its immediate children.
+    * 
+    * Example: passing STATIC_TYPE_INFO(ossimImageRenderer) as an argument will
+    *          look for the first ossimImageRenderer and return that object.
+    */
+   virtual ossimConnectableObject* findFirstObjectOfType(const RTTItypeid& typeInfo,
+                                                 bool recurse=true);
+   
+   virtual ossimConnectableObject* findFirstObjectOfType(const ossimString& className,
+                                                bool recurse=true);
+
+   /*!
+    * will search for the object given an id.  If recurse is true it will
+    * recurse
+    * to other containers.
+    */ 
+   ossimConnectableObject* findObject(const ossimId& id,
+                                     bool recurse=true);
+
+   ossimConnectableObject* findObject(const ossimConnectableObject* obj,
+                                     bool recurse=true);
+
+   /*!
+    * Will cycle through all sources setting their ids. the idLast wlil be
+    * updated
+    * so we can recurse into other containers.
+    */
+   void makeUniqueIds();
+
+   /*!
+    * Returns the number of objects within this container and all child
+    * containers.
+    */
+   ossim_uint32 getNumberOfObjects(bool recurse=true)const;
+   
+   /*!
+    * Will add an object to the container and then set the added objects owner
+    * to this.
+    */
+   virtual bool addChild(ossimConnectableObject* attachableObject);
+
+
+   virtual bool removeChild(ossimConnectableObject* object);
+   
+   virtual bool canConnectMyInputTo(ossim_int32 index,
+                                    const ossimConnectableObject* obj) const;
+
+   virtual bool canConnectMyOutputTo(ossim_int32 index,
+                                     const ossimConnectableObject* obj) const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+
+   //____________________PLACE ALL EVENT HANDLING STUFF HERE_____________
+//   virtual void objectDestructingEvent(ossimObjectDestructingEvent& event);
+//   virtual void propertyEvent(ossimPropertyEvent& event);
+
+//   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+//   virtual void connectInputEvent(ossimConnectionEvent& event);
+
+//   virtual void disconnectOutputEvent(ossimConnectionEvent& event);
+//   virtual void connectOutputEvent(ossimConnectionEvent& event);
+   
+   
+   virtual void getChildren(vector<ossimConnectableObject*>& children,
+                               bool immediateChildrenOnlyFlag);
+   void deleteAllChildren();
+   
+//    void propagateEventToOutputs(ossimEvent& event,
+//                                 ossimConnectableObject* start);
+//    void propagateEventToInputs(ossimEvent& event,
+//                                ossimConnectableObject* start);
+     
+protected:
+   ossimConnectableContainer(const ossimConnectableContainer& rhs);
+
+   void removeAllListeners();
+   bool addAllObjects(map<ossimId, vector<ossimId> >& idMapping,
+                      const ossimKeywordlist& kwl,
+                      const char* prefix);
+      
+   bool connectAllObjects(const map<ossimId, vector<ossimId> >& idMapping);
+   
+   void findInputConnectionIds(vector<ossimId>& result,
+                               const ossimKeywordlist& kwl,
+                               const char* prefix);
+   
+   /*!
+    * Every object added must have a unique id.  We will sort them in a easy to
+    * query form.  Since the container can have hundreds of objects we will use a
+    * more efficient map that allows us to do binary searches of the objects.
+    *
+    * map<key, value>  The key will be the objectsUnique id and the value
+    * is a pointer to the attachable object.
+    */
+   connectablObjectMapType theObjectMap;
+
+   ossimConnectableContainerChildListener* theChildListener;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainerInterface.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainerInterface.cpp
new file mode 100644
index 0000000000..0e4997a411
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainerInterface.cpp
@@ -0,0 +1,27 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimConnectableContainerInterface.cpp,v 1.1 2002/01/15 19:45:47 gpotts Exp $
+#include "ossimConnectableContainerInterface.h"
+
+RTTI_DEF(ossimConnectableContainerInterface, "ossimConnectableContainerInterface");
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainerInterface.h b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainerInterface.h
new file mode 100644
index 0000000000..2ffae8df60
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableContainerInterface.h
@@ -0,0 +1,131 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//
+//*************************************************************************
+// $Id: ossimConnectableContainerInterface.h,v 1.12 2005/11/22 19:39:11 dburken Exp $
+#ifndef ossimConnectableContainerInterface_HEADER
+#define ossimConnectableContainerInterface_HEADER
+#include "base/common/ossimConstants.h"
+#include "base/common/ossimRtti.h"
+#include "base/common/ossimId.h"
+#include <vector>
+
+class OSSIMDLLEXPORT ossimObject;
+class OSSIMDLLEXPORT ossimConnectableObject;
+class OSSIMDLLEXPORT ossimString;
+
+class OSSIMDLLEXPORT ossimConnectableContainerInterface
+{
+public:
+   ossimConnectableContainerInterface(ossimObject* obj):theBaseObject(obj){}
+   virtual ~ossimConnectableContainerInterface(){theBaseObject=NULL;}
+   
+   /*!
+    * Will find all objects of the past in type.  Use the RTTI type info.  An optional
+    * recurse flag will say if there is another container then recurse it to
+    * find the type you are looking for else it just looks within its immediate
+    * children
+    * 
+    * Example: passing STATIC_TYPE_INFO(ossimImageRenderer) as an argument will
+    *          look for all ossimImageRenderer's and return the list.
+    */
+   virtual std::vector<ossimConnectableObject*> findAllObjectsOfType(const RTTItypeid& typeInfo,
+                                                                     bool recurse=true)=0;
+   virtual std::vector<ossimConnectableObject*> findAllObjectsOfType(const ossimString& className,
+                                                                     bool recurse=true)=0;
+
+   /*!
+    * Will find the firt object of the past in type.  Use the RTTI type info.An optional
+    * recurse flag will say if there is another container then recurse it to
+    * find the type you are looking for else it just looks within its immediate
+    * children
+    * 
+    * Example: passing STATIC_TYPE_INFO(ossimImageRenderer) as an argument will
+    *          look for the first ossimImageRenderer and return that object.
+    */
+   virtual ossimConnectableObject* findFirstObjectOfType(const RTTItypeid& typeInfo,
+                                                         bool recurse=true)=0;
+   
+   virtual ossimConnectableObject* findFirstObjectOfType(const ossimString& className,
+                                                         bool recurse=true)=0;
+
+   /*!
+    * will search for the object given an id.  If recurse is true it will recurse
+    * to other containers.
+    */ 
+   virtual ossimConnectableObject* findObject(const ossimId& id,
+                                              bool recurse=true)=0;
+
+   virtual ossimConnectableObject* findObject(const ossimConnectableObject* obj,
+                                              bool recurse=true)=0;
+   /*!
+    * Will cycle through all sources setting their ids. the idLast wlil be updated
+    * so we can recurse into other containers.
+    */
+   virtual void makeUniqueIds()=0;
+
+   /*!
+    * Returns the number of objects within this container and all child containers.
+    */
+   virtual ossim_uint32 getNumberOfObjects(bool recurse=true)const=0;
+   
+   
+   /*!
+    * Will add an object to the container and then set the added objects owner
+    * to this.
+    */
+   virtual bool addChild(ossimConnectableObject* attachableObject)=0;
+
+   /*!
+    * Will remove the child from the container.  Changes the owner of the
+    * child to be NULL;
+    */
+   virtual bool removeChild(ossimConnectableObject* object)=0;
+
+   /*!
+    * Gives access to the this point of the base object that everyone derives
+    * from.
+    */
+   ossimObject*       getObject(){return theBaseObject;}
+   const ossimObject* getObject()const{return theBaseObject;}
+
+   /**
+    * @param index Index of object to get.
+    *
+    * @see getNumberOfObjects(false) to get the number of objects inside
+    * the container.
+    *
+    * @return Container's object at that index or NULL if out of range.
+    *
+    * @note This does not recurse into other containers.
+    */
+   virtual ossimConnectableObject* getConnectableObject(ossim_uint32 index)=0;
+
+   void deleteAllChildren();
+   virtual void getChildren(vector<ossimConnectableObject*>& children,
+                            bool immediateChildrenOnlyFlag)=0;
+protected:
+   ossimObject* theBaseObject;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimConnectableObject.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableObject.cpp
new file mode 100644
index 0000000000..faa4a665a6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableObject.cpp
@@ -0,0 +1,1903 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimConnectableObject.cpp,v 1.92 2006/01/03 20:31:16 dburken Exp $
+#include <base/common/ossimConnectableObject.h>
+#include <base/common/ossimIdManager.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/events/ossimObjectEvents.h>
+#include <base/common/events/ossimObjectEvents.h>
+#include <base/common/ossimConnectableContainerInterface.h>
+#include <base/property/ossimTextProperty.h>
+#include <base/context/ossimNotifyContext.h>
+#include <algorithm>
+
+RTTI_DEF3(ossimConnectableObject,
+          "ossimConnectableObject",
+          ossimObject,
+          ossimListenerManager,
+          ossimPropertyInterface);
+
+const char* CONNECTABLE_INPUT_LIST_FIXED_KW  = "input_list_fixed";
+const char* CONNECTABLE_OUTPUT_LIST_FIXED_KW = "output_list_fixed";
+
+ossimConnectableObject::ossimConnectableObject(ossimObject* owner)
+   :ossimObject(),
+    ossimListenerManager(),
+    theInputListIsFixedFlag(false),
+    theOutputListIsFixedFlag(false)
+{
+   theId    = ossimIdManager::instance()->generateId();
+   theOwner = owner;
+}
+
+ossimConnectableObject::ossimConnectableObject(ossimObject* owner,
+                                               long inputListSize,
+                                               long outputListSize,
+                                               bool inputListIsFixedFlag,
+                                               bool outputListIsFixedFlag)
+   :ossimObject(),
+    ossimListenerManager(),
+    theInputListIsFixedFlag(inputListIsFixedFlag),
+    theOutputListIsFixedFlag(outputListIsFixedFlag)
+{
+   theId    = ossimIdManager::instance()->generateId();
+   theOwner = owner;
+
+   setNumberOfInputs(inputListSize);
+   setNumberOfOutputs(outputListSize);
+}
+
+ossimConnectableObject::~ossimConnectableObject()
+{
+
+   // tell the immediate listeners that we are destructing.
+   ossimObjectDestructingEvent event(this);
+
+//    if(theOwner)
+//    {
+//       ossimListenerManager* manager = PTR_CAST(ossimListenerManager, theOwner);
+
+//       if(manager)
+//       {
+//          // notify the owner that you are destructing
+//          //
+//          manager->fireEvent(event);
+//       }
+//    }
+
+   // notify all other listeners that you are destructing
+   //
+   fireEvent(event);
+
+   ossimIdManager::instance()->releaseId(theId);
+
+   // next we need to make sure that we are detached.
+   //
+   disconnect(this);
+
+}
+
+void ossimConnectableObject::changeOwner(ossimObject* owner)
+{
+   theOwner = owner;
+}
+
+void ossimConnectableObject::setDescription(const ossimString& description)
+{
+   theDescription = description;
+}
+
+ossimString ossimConnectableObject::getDescription()const
+{
+   return theDescription;
+}
+
+bool ossimConnectableObject::isConnected(ossimConnectableObjectDirectionType direction)const
+{
+   if(direction & CONNECTABLE_DIRECTION_INPUT)
+   {
+      if(getNumberOfInputs())
+      {
+         std::vector<ossimConnectableObject*>::const_iterator current = theInputObjectList.begin();
+
+         while(current != theInputObjectList.end())
+         {
+            if(! (*current))
+            {
+               return false;
+            }
+
+            ++current;
+         }
+      }
+      else if(!theInputListIsFixedFlag)
+      {
+         return false;
+      }
+   }
+
+   if(direction & CONNECTABLE_DIRECTION_OUTPUT)
+   {
+      std::vector<ossimConnectableObject*>::const_iterator current = theOutputObjectList.begin();
+      current = theOutputObjectList.begin();
+
+      while(current != theOutputObjectList.end())
+      {
+         if(! (*current))
+         {
+            return false;
+         }
+
+         ++current;
+      }
+   }
+
+   return true;
+}
+
+ossimConnectableObject* ossimConnectableObject::findConnectableObject(const ossimId& id)
+{
+   std::vector<ossimConnectableObject*>::iterator current;
+
+   current = theInputObjectList.begin();
+   while(current != theInputObjectList.end())
+   {
+      ossimConnectableObject* temp = *current;
+
+      if(temp->getId() == id)
+      {
+         return temp;
+      }
+
+      ++current;
+   }
+
+   // go through the outputs
+   current = theOutputObjectList.begin();
+   while(current != theOutputObjectList.end())
+   {
+      ossimConnectableObject* temp = *current;
+
+      if(temp->getId() == id)
+      {
+         return temp;
+      }
+
+      ++current;
+   }
+
+   return NULL;
+}
+
+ossimConnectableObject* ossimConnectableObject::findObjectOfType(RTTItypeid typeId,
+                                                                 ossimConnectableObjectDirectionType directionType,
+                                                                 bool recurse)
+{
+   vector<ossimConnectableObject*> *connectableList = &theInputObjectList;
+
+   if(directionType == CONNECTABLE_DIRECTION_NONE)
+   {
+      return NULL;
+   }
+
+  if(directionType == CONNECTABLE_DIRECTION_OUTPUT)
+   {
+      connectableList = &theOutputObjectList;
+
+   }
+
+
+   // see if it is in the immediate list
+   for(ossim_uint32 index = 0; index < connectableList->size(); ++index)
+   {
+      if((*connectableList)[index])
+      {
+         if((*connectableList)[index]->canCastTo(typeId))//typeId.can_cast(TYPE_INFO(theInputObjectList[index])))
+         {
+            return (*connectableList)[index];
+         }
+      }
+   }
+
+   if(recurse)
+   {
+     ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+						          this);
+     if(inter)
+       {
+            ossimConnectableObject* tempObj = inter->findFirstObjectOfType(typeId);
+            if(tempObj)
+            {
+               return tempObj;
+            }
+       }
+
+      for(ossim_uint32 index = 0; index < connectableList->size(); ++index)
+      {
+         inter = PTR_CAST(ossimConnectableContainerInterface,
+		         (*connectableList)[index]);
+         if(inter)
+         {
+            ossimConnectableObject* tempObj = inter->findFirstObjectOfType(typeId);
+            if(tempObj)
+            {
+               return tempObj;
+            }
+         }
+         if((*connectableList)[index])
+         {
+            ossimConnectableObject* result = (*connectableList)[index]->findObjectOfType(typeId,
+                                                                                         directionType,
+                                                                                         recurse);
+            if(result)
+            {
+               return result;
+            }
+         }
+      }
+   }
+
+   ossimConnectableObject* result = NULL;
+   for(ossim_uint32 index = 0; (index < connectableList->size())&&!result; ++index)
+   {
+      if((*connectableList)[index])
+      {
+         result = ((*connectableList)[index])->findObjectOfType(typeId,
+                                                                directionType,
+                                                                recurse);
+      }
+   }
+
+   return result;
+}
+
+ossimConnectableObject* ossimConnectableObject::findObjectOfType(
+   const ossimString& className,
+   ossimConnectableObjectDirectionType directionType,
+   bool recurse)
+{
+   vector<ossimConnectableObject*> *connectableList = &theInputObjectList;
+
+   if(directionType == CONNECTABLE_DIRECTION_NONE)
+   {
+      return NULL;
+   }
+
+  if(directionType == CONNECTABLE_DIRECTION_OUTPUT)
+   {
+      connectableList = &theOutputObjectList;
+
+   }
+
+   // see if it is in the immediate list
+   for(ossim_uint32 index = 0; index < connectableList->size(); ++index)
+   {
+      if((*connectableList)[index])
+      {
+         if((*connectableList)[index]->canCastTo(className))//typeId.can_cast(TYPE_INFO(theInputObjectList[index])))
+         {
+            return (*connectableList)[index];
+         }
+      }
+   }
+
+   if(recurse)
+   {
+     ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+						          this);
+     if(inter)
+       {
+            ossimConnectableObject* tempObj = inter->findFirstObjectOfType(className);
+            if(tempObj)
+            {
+               return tempObj;
+            }
+       }
+      for(ossim_uint32 index = 0; index < connectableList->size(); ++index)
+      {
+         inter = PTR_CAST(ossimConnectableContainerInterface,
+		         (*connectableList)[index]);
+         if(inter)
+         {
+            ossimConnectableObject* tempObj = inter->findFirstObjectOfType(className);
+            if(tempObj)
+            {
+               return tempObj;
+            }
+         }
+         if((*connectableList)[index])
+         {
+            ossimConnectableObject* result = (*connectableList)[index]->findObjectOfType(className,
+                                                                                         directionType,
+                                                                                         recurse);
+            if(result)
+            {
+               return result;
+            }
+         }
+      }
+   }
+   ossimConnectableObject* result = NULL;
+   for(ossim_uint32 index = 0; (index < connectableList->size())&&!result; ++index)
+   {
+      if((*connectableList)[index])
+      {
+         result = ((*connectableList)[index])->findObjectOfType(className,
+                                                                directionType,
+                                                                recurse);
+         // Return ...
+      }
+   }
+
+   return result;
+}
+
+ossimConnectableObject* ossimConnectableObject::findInputObjectOfType(
+   const ossimString& className)
+{
+   // See if we are of class type.
+   if (canCastTo(className))
+   {
+      return this;
+   }
+
+   // If we are a container, look inside for type.
+   ossimConnectableContainerInterface* container =
+      PTR_CAST(ossimConnectableContainerInterface, this);
+   if (container)
+   {
+      const ossim_uint32 NUMBER_OF_OBJECTS =
+         container->getNumberOfObjects(false);
+      if (NUMBER_OF_OBJECTS)
+      {
+         for (ossim_uint32 idx = NUMBER_OF_OBJECTS; idx > 0; --idx) 
+         {
+            ossimConnectableObject* result =
+               container->getConnectableObject(idx-1);
+            if (result)
+            {
+               if (result->canCastTo(className))
+               {
+                  return result;
+               }
+            }
+         }
+      }
+   }
+
+   if ( getInputListIsFixedFlag() && (theInputObjectList.size() == 1) )
+   {
+      // Look at the input connection.
+      ossimConnectableObject* input = theInputObjectList[0];
+
+      if(input)
+      {
+         // See if the input can cast to type.
+         if(input->canCastTo(className))
+         {
+            return input;
+         }
+         
+         // Look inside the input connection.
+         ossimConnectableObject* result =
+            input->findInputObjectOfType(className);
+         if(result)
+         {
+            return result;
+         }
+      }
+      
+   } // End of "Must have fixed input of one."
+
+   return (ossimConnectableObject*)NULL;
+}
+
+ossim_int32 ossimConnectableObject::findInputIndex(const ossimConnectableObject* object)
+{
+  ossim_int32 i = 0;
+   for(i = 0; i < (ossim_int32)theInputObjectList.size(); ++i)
+   {
+      if(theInputObjectList[i] == object)
+      {
+         return i;
+      }
+   }
+
+   return -1;
+}
+
+ossim_int32 ossimConnectableObject::findInputIndex(const ossimId& id)
+{
+   ossim_int32 i = 0;
+   for(i = 0; i < (ossim_int32)theInputObjectList.size(); ++i)
+   {
+      if(theInputObjectList[i] &&
+         (theInputObjectList[i]->getId() == id))
+      {
+         return i;
+      }
+   }
+
+   return -1;
+}
+
+ossim_int32 ossimConnectableObject::findOutputIndex(const ossimConnectableObject* object)
+{
+   ossim_int32 i = 0;
+   for(i = 0; i < (ossim_int32)theOutputObjectList.size(); ++i)
+   {
+      if(theOutputObjectList[i] == object)
+      {
+         return i;
+      }
+   }
+
+   return -1;
+}
+
+ossim_int32 ossimConnectableObject::findOutputIndex(const ossimId& id)
+{
+   ossim_int32 i = 0;
+   for(i = 0; i < (ossim_int32)theOutputObjectList.size(); ++i)
+   {
+      if(theOutputObjectList[i] &&
+         (theOutputObjectList[i]->getId() == id))
+      {
+         return i;
+      }
+   }
+
+   return -1;
+}
+
+ossim_int32 ossimConnectableObject::getMyInputIndexToConnectTo(ossimConnectableObject* object)const
+{
+   std::vector<ossimConnectableObject*>::const_iterator current;
+
+   ossim_int32 index = 0;
+   current = theInputObjectList.begin();
+   while(current != theInputObjectList.end())
+   {
+      if(!(*current))
+      {
+         if(canConnectMyInputTo(index, object))
+         {
+            return index;
+         }
+      }
+      ++current;
+      ++index;
+   }
+   if(!theInputListIsFixedFlag)
+   {
+      if(canConnectMyInputTo((ossim_int32)theInputObjectList.size(),
+                              object))
+      {
+         return (ossim_int32)theInputObjectList.size();
+      }
+   }
+   return -1;
+}
+
+ossim_int32 ossimConnectableObject::getMyOutputIndexToConnectTo(ossimConnectableObject* object)const
+{
+   std::vector<ossimConnectableObject*>::const_iterator current;
+
+   ossim_int32 index = 0;
+   current = theOutputObjectList.begin();
+   while(current != theOutputObjectList.end())
+   {
+      if(!(*current))
+      {
+         if(canConnectMyOutputTo(index, object))
+         {
+            return index;
+         }
+      }
+      ++current;
+      ++index;
+   }
+   if(!theOutputListIsFixedFlag)
+   {
+      if(canConnectMyOutputTo((ossim_int32)theOutputObjectList.size(),
+                              object))
+      {
+         return (ossim_int32)theOutputObjectList.size();
+      }
+   }
+   // default to return the size.  This will force an append.
+   //
+   return -1;
+}
+
+void ossimConnectableObject::disconnect(ossimConnectableObject* object)
+{
+   if( (object==this) || (object==(ossimConnectableObject*)NULL))
+   {
+      disconnectAllInputs();
+      disconnectAllOutputs();
+   }
+   else
+   {
+      ossim_int32 index = findInputIndex(object);
+      if(index > -1)
+      {
+         disconnectMyInput(index);
+      }
+      else
+      {
+         index = findOutputIndex(object);
+         disconnectMyOutput(index, object);
+      }
+   }
+}
+
+void ossimConnectableObject::disconnect(const ossimId& id)
+{
+   if(id == theId)
+   {
+      disconnect(this);
+   }
+   else
+   {
+      ossimConnectableObject* object = findConnectableObject(id);
+      disconnect(object);
+   }
+}
+
+ossimConnectableObject* ossimConnectableObject::disconnectMyInput(ossim_int32 inputIndex,
+								  bool disconnectOutputFlag,
+								  bool createEventFlag)
+{
+   if(theInputObjectList.size() == 0)
+     {
+       return (ossimConnectableObject*)NULL;
+     }
+
+   std::vector<ossimConnectableObject*>::iterator current;
+   ossimConnectableObject* result = NULL;
+
+   if( (inputIndex > -1)&&
+       (inputIndex < (ossim_int32)theInputObjectList.size()))
+   {
+      current = (theInputObjectList.begin()+inputIndex);
+      result = *current;
+
+      ossim_int32 index = inputIndex;
+      if(!theInputListIsFixedFlag)
+      {
+         current = theInputObjectList.erase(current);
+         index = -1;
+      }
+      else
+      {
+         *current = NULL;
+      }
+      if(createEventFlag&&result)
+      {
+         ossimConnectionEvent event(this,  // owner of message
+                                    OSSIM_EVENT_CONNECTION_DISCONNECT_ID,
+                                    NULL,  // new object
+                                    result,// old object
+                                    ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+
+         // send event to all listeners.
+         //
+         fireEvent(event);
+      }
+
+      if(disconnectOutputFlag&&result)
+      {
+         result->disconnectMyOutput(this, false, createEventFlag);
+      }
+   }
+   return result;
+}
+
+
+void ossimConnectableObject::disconnectMyInput(ossimConnectableObject* input,
+                                               bool disconnectOutputFlag,
+                                               bool createEventFlag)
+{
+   disconnectMyInput(findInputIndex(input),
+                     disconnectOutputFlag,
+                     createEventFlag);
+}
+
+void ossimConnectableObject::disconnectMyInputs(std::vector<ossimConnectableObject*>& inputList,
+                                                bool disconnectOutputFlag,
+                                                bool createEventFlag)
+{
+   if(theInputObjectList.size() == 0) return;
+   vector<ossimConnectableObject*> oldInputs;
+   vector<ossimConnectableObject*> newInputs;
+   ossim_int32 i = 0;
+
+   for(i = 0; i < (ossim_int32)inputList.size(); ++i)
+   {
+      if(findInputIndex(inputList[i]) >= 0)
+      {
+         disconnectMyInput(inputList[i], disconnectOutputFlag, false);
+         oldInputs.push_back(inputList[i]);
+      }
+   }
+   if(createEventFlag && oldInputs.size())
+   {
+      ossimConnectionEvent event(this,
+                                 OSSIM_EVENT_CONNECTION_DISCONNECT_ID,
+                                 newInputs,
+                                 oldInputs,
+                                 ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+      fireEvent(event);
+   }
+}
+
+ossimConnectableObject* ossimConnectableObject::disconnectMyOutput(ossim_int32 outputIndex,
+								   bool disconnectInputFlag,
+								   bool createEvent)
+{
+   if(theOutputObjectList.size() == 0)
+     {
+       return (ossimConnectableObject*)NULL;
+     }
+
+   std::vector<ossimConnectableObject*>::iterator current;
+   ossimConnectableObject* result = NULL;
+   if( (outputIndex > -1)&&
+       (outputIndex < (ossim_int32)theOutputObjectList.size()))
+   {
+      current = (theOutputObjectList.begin()+outputIndex);
+      result = *current;
+      ossim_int32 index = outputIndex;
+      if(!theOutputListIsFixedFlag)
+      {
+         current = theOutputObjectList.erase(current);
+         index = -1;
+      }
+      else
+      {
+         *current = NULL;
+      }
+      if(createEvent)
+      {
+         ossimConnectionEvent event(this,  // owner of message
+                                    OSSIM_EVENT_CONNECTION_DISCONNECT_ID,
+                                    NULL,  // new object
+                                    result,// old object
+                                    ossimConnectionEvent::OSSIM_OUTPUT_DIRECTION);
+
+         // send event to all listeners.
+         //
+         fireEvent(event);
+      }
+
+      if(disconnectInputFlag&&result)
+      {
+         result->disconnectMyInput(this, false, createEvent);
+      }
+   }
+   return result;
+}
+
+void ossimConnectableObject::disconnectMyOutput(ossimConnectableObject* output,
+                                                bool disconnectInputFlag,
+                                                bool createEventFlag)
+{
+   disconnectMyOutput(findOutputIndex(output), disconnectInputFlag, createEventFlag);
+}
+
+void ossimConnectableObject::disconnectMyOutputs(std::vector<ossimConnectableObject*>& outputList,
+                                                bool disconnectInputFlag,
+                                                bool createEventFlag)
+{
+   if(theOutputObjectList.size() == 0) return;
+
+   if(theOutputObjectList.size() == 1)
+   {
+      disconnectMyOutput((ossim_int32)0);
+      return;
+   }
+   vector<ossimConnectableObject*> oldOutputs;
+   vector<ossimConnectableObject*> newOutputs;
+   ossim_int32 i = 0;
+   for(i = 0; i < (ossim_int32)outputList.size(); ++i)
+   {
+      if(findOutputIndex(outputList[i]) >= 0)
+      {
+         disconnectMyOutput(outputList[i], disconnectInputFlag, false);
+         oldOutputs.push_back(outputList[i]);
+      }
+   }
+   if(createEventFlag && oldOutputs.size())
+   {
+      ossimConnectionEvent event(this,
+                                 OSSIM_EVENT_CONNECTION_DISCONNECT_ID,
+                                 newOutputs,
+                                 oldOutputs,
+                                 ossimConnectionEvent::OSSIM_OUTPUT_DIRECTION);
+      fireEvent(event);
+   }
+}
+
+void ossimConnectableObject::disconnectAllInputs()
+{
+   if(theInputObjectList.size() == 0) return;
+   if(theInputObjectList.size() == 1)
+   {
+//     ossimConnectableObject* obj = disconnectMyInput((ossim_int32)0, false);
+     disconnectMyInput((ossim_int32)0);
+//     if(obj)
+//     {
+//        obj->disconnectMyOutput(this, false);
+//     }
+     return;
+   }
+   std::vector<ossimConnectableObject*>::iterator current;
+   std::vector<ossimConnectableObject*> oldInputs = theInputObjectList;
+   std::vector<ossimConnectableObject*> newInputs;
+
+
+   current = theInputObjectList.begin();
+   while(current != theInputObjectList.end())
+   {
+      if(!theInputListIsFixedFlag)
+      {
+         current = theInputObjectList.erase(current);
+      }
+      else
+      {
+         *current = NULL;
+         ++current;
+      }
+   }
+   ossimConnectionEvent event(this,
+                              OSSIM_EVENT_CONNECTION_DISCONNECT_ID,
+                              newInputs,
+                              oldInputs,
+                              ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+   fireEvent(event);
+
+   for(ossim_uint32 index = 0; index < oldInputs.size(); ++index)
+     {
+       if(oldInputs[index])
+         {
+	   oldInputs[index]->disconnectMyOutput(this, false);
+         }
+     }
+}
+
+void ossimConnectableObject::disconnectAllOutputs()
+{
+   if(theOutputObjectList.size() == 0) return;
+   if(theOutputObjectList.size() == 1)
+   {
+//     ossimConnectableObject* obj = disconnectMyOutput((ossim_int32)0, false);
+     disconnectMyOutput((ossim_int32)0);
+//     if(obj)
+//     {
+//        obj->disconnectMyInput(this,
+//                               false);
+//     }
+     return;
+   }
+   std::vector<ossimConnectableObject*>::iterator current;
+
+   std::vector<ossimConnectableObject*> oldOutputs = theOutputObjectList;
+   std::vector<ossimConnectableObject*> newOutputs;
+
+   current = theOutputObjectList.begin();
+   while(current != theOutputObjectList.end())
+   {
+      if(!theOutputListIsFixedFlag)
+      {
+         current = theOutputObjectList.erase(current);
+      }
+      else
+      {
+         *current = NULL;
+         ++current;
+      }
+   }
+   ossimConnectionEvent event(this,
+                              OSSIM_EVENT_CONNECTION_DISCONNECT_ID,
+                              newOutputs,
+                              oldOutputs,
+                              ossimConnectionEvent::OSSIM_OUTPUT_DIRECTION);
+   fireEvent(event);
+
+   for(ossim_uint32 index = 0; index < oldOutputs.size(); ++index)
+     {
+       if(oldOutputs[index])
+         {
+	   oldOutputs[index]->disconnectMyInput(this, false);
+         }
+     }
+}
+
+ossim_int32 ossimConnectableObject::connectMyInputTo(ossimConnectableObject* object,
+					       bool makeOutputConnection,
+					       bool createEventFlag)
+{
+   if(!object) return false;
+
+   ossim_int32 index = findInputIndex(object);
+   if(index >= 0) return index;
+
+   index = getMyInputIndexToConnectTo(object);
+
+   if(index>-1)
+   {
+      if(index >= (ossim_int32)theInputObjectList.size())
+      {
+         if(theInputListIsFixedFlag) return -1;
+
+         index = (ossim_int32)theInputObjectList.size();
+         theInputObjectList.push_back(object);
+      }
+      else
+      {
+         if(!theInputObjectList[index])
+         {
+            theInputObjectList[index] = object;
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN) << "Must issue a detach first!! trying to attach object " << object->getClassName()
+                                               << "\n to input index " << index << " in " << getClassName() << "\n";
+
+            return -1;
+         }
+      }
+      if(createEventFlag)
+      {
+         ossimConnectionEvent event(this,  // owner of message
+                                    OSSIM_EVENT_CONNECTION_CONNECT_ID,
+                                    theInputObjectList[index],  // new object
+                                    NULL,// old object
+                                    ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+         // send event to any listener.
+         //
+         fireEvent(event);
+      }
+
+      if(makeOutputConnection&&object)
+      {
+         // make sure we tell the input not to connect
+         // back to us or infinite loop
+         //
+         object->connectMyOutputTo(this, false, createEventFlag);
+      }
+   }
+   else
+   {
+      return index;
+   }
+
+  return index;
+}
+
+ossim_int32 ossimConnectableObject::connectMyInputTo(ossim_int32 inputIndex,
+					       ossimConnectableObject* inputObject,
+					       bool makeOutputConnection,
+					       bool createEventFlag)
+{
+   if(!inputObject)
+     {
+       if(inputIndex < (ossim_int32)theInputObjectList.size())
+	 {
+	   ossimConnectableObject* oldObject = theInputObjectList[inputIndex];
+	   if(theInputListIsFixedFlag)
+	     {
+	       theInputObjectList[inputIndex]    = (ossimConnectableObject*)NULL;
+	     }
+	   else
+	     {
+	       theInputObjectList.erase(theInputObjectList.begin() + inputIndex);
+	     }
+	   if(createEventFlag)
+	     {
+	       ossimConnectionEvent event(this,  // owner of message
+					  OSSIM_EVENT_CONNECTION_CONNECT_ID,
+					  NULL,  // new object
+					  oldObject,// old object
+					  ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+	       // send event to any listener.
+	       //
+	       fireEvent(event);
+	     }
+	   return -1;
+	 }
+       return -1;
+     }
+
+   ossim_int32 index = findInputIndex(inputObject);
+
+   if((index >= 0)&&!inputObject) return index;
+   if(!inputObject) return -1;
+
+   if(canConnectMyInputTo(inputIndex, inputObject))
+   {
+      if(inputIndex>-1)
+      {
+	ossimConnectableObject* oldObject=NULL;
+         if(inputIndex >= (ossim_int32)theInputObjectList.size())
+         {
+            if(theInputListIsFixedFlag) return -1;
+
+            inputIndex = (ossim_int32)theInputObjectList.size();
+            theInputObjectList.push_back(inputObject);
+         }
+         else
+         {
+            oldObject = theInputObjectList[inputIndex];
+            theInputObjectList[inputIndex] = inputObject;
+            if(oldObject)
+            {
+               oldObject->disconnectMyOutput(this, false);
+            }
+         }
+
+         if(createEventFlag)
+         {
+            ossimConnectionEvent event(this,  // owner of message
+                                       OSSIM_EVENT_CONNECTION_CONNECT_ID,
+                                       theInputObjectList[inputIndex],  // new object
+                                       oldObject,// old object
+                                       ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+            // send event to any listener.
+            //
+            fireEvent(event);
+         }
+
+         if(makeOutputConnection&&inputObject)
+         {
+            // make sure we tell the input not to connect
+            // back to us or infinite loop
+            //
+            inputObject->connectMyOutputTo(this, false, createEventFlag);
+         }
+      }
+      else
+      {
+         return inputIndex;
+      }
+
+      return inputIndex;
+   }
+
+   return -1;
+}
+
+bool ossimConnectableObject::connectMyInputTo(vector<ossimConnectableObject*>& inputList,
+                                              bool makeOutputConnection,
+                                              bool createEventFlag)
+{
+   bool result = true;
+   vector<ossimConnectableObject*> oldInputs;
+   vector<ossimConnectableObject*> newInputs;
+
+   if(inputList.size() == 1)
+   {
+     if(inputList[0])
+       {
+	 return (connectMyInputTo(inputList[0], makeOutputConnection, createEventFlag) >= 0);
+       }
+     else
+     {
+        if(theInputListIsFixedFlag)
+        {
+	   theInputObjectList[0] = NULL;
+        }
+        else
+        {
+	   theInputObjectList.clear();
+        }
+        if(createEventFlag)
+        {
+           ossimConnectionEvent event(this,
+                                      OSSIM_EVENT_CONNECTION_CONNECT_ID,
+                                      (ossimConnectableObject*)NULL,
+                                      theInputObjectList[0],
+                                      ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+           fireEvent(event);
+        }
+
+        return true;
+     }
+   }
+   ossim_int32 i = 0;
+   for(i = 0; i < (ossim_int32)inputList.size(); ++i)
+   {
+     if(inputList[i])
+       {
+	 if(connectMyInputTo(inputList[i], makeOutputConnection, false)<0)
+	   {
+	     result = false;
+	   }
+	 else
+	   {
+	     newInputs.push_back(inputList[i]);
+	   }
+       }
+     else
+       {
+	 newInputs.push_back((ossimConnectableObject*)NULL);
+       }
+   }
+   if(createEventFlag)
+   {
+      ossimConnectionEvent event(this,
+                                 OSSIM_EVENT_CONNECTION_CONNECT_ID,
+                                 newInputs,
+                                 oldInputs,
+                                 ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+      fireEvent(event);
+   }
+   return result;
+}
+
+ossim_int32 ossimConnectableObject::connectMyOutputTo(ossimConnectableObject* output,
+						bool makeInputConnection,
+						bool createEventFlag)
+{
+  ossim_int32 index = findOutputIndex(output);
+   if(index >= 0) return index;
+
+   index = getMyOutputIndexToConnectTo(output);
+
+   if(index > -1)
+   {
+      if((index >= (ossim_int32)theOutputObjectList.size())&&
+         !theOutputListIsFixedFlag)
+      {
+         index = (ossim_int32)theOutputObjectList.size();
+         theOutputObjectList.push_back(output);
+      }
+      else
+      {
+         if(!theOutputObjectList[index])
+         {
+            theOutputObjectList[index] = output;
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN) << "Must issue a disconnect first!! trying to connect object " << output->getClassName()
+                                               << "\n to output index " << index << " in " << getClassName() << "\n";
+
+            return -1;
+         }
+      }
+      if(createEventFlag)
+      {
+         ossimConnectionEvent event(this,  // owner of message
+                                    OSSIM_EVENT_CONNECTION_CONNECT_ID,
+                                    theOutputObjectList[index],  // new object
+                                    NULL,// old object
+                                    ossimConnectionEvent::OSSIM_OUTPUT_DIRECTION);
+         // send event to any listener.
+         //
+         fireEvent(event);
+      }
+      if(makeInputConnection&&output)
+      {
+         // tell the output object not to connect back
+         // to us since this is already done.
+         //
+         output->connectMyInputTo(this, false, createEventFlag);
+      }
+   }
+   else
+   {
+      return index;
+   }
+
+   return index;
+}
+
+bool ossimConnectableObject::connectMyOutputTo(vector<ossimConnectableObject*>& outputList,
+                                               bool makeInputConnection,
+                                               bool createEventFlag)
+{
+   bool result = true;
+   vector<ossimConnectableObject*> oldOutputs;
+   vector<ossimConnectableObject*> newOutputs;
+
+   if(outputList.size() == 0)
+     {
+       disconnectAllOutputs();
+       return true;
+     }
+   if((outputList.size() == 1)&&outputList[0])
+   {
+     if(outputList[0])
+       {
+	 return (connectMyOutputTo(outputList[0], makeInputConnection, createEventFlag) >= 0);
+       }
+     else
+       {
+	 disconnectAllOutputs();
+       }
+   }
+
+   ossim_int32 i = 0;
+   for(i = 0; i < (ossim_int32)outputList.size(); ++i)
+   {
+      if((connectMyOutputTo(outputList[i], makeInputConnection, false)<0)&&outputList[i])
+      {
+         newOutputs.push_back(outputList[i]);
+         result = false;
+      }
+   }
+   if(createEventFlag&&newOutputs.size())
+   {
+      ossimConnectionEvent event(this,
+                                      OSSIM_EVENT_CONNECTION_CONNECT_ID,
+                                      newOutputs,
+                                      oldOutputs,
+                                      ossimConnectionEvent::OSSIM_OUTPUT_DIRECTION);
+      fireEvent(event);
+   }
+
+   return result;
+}
+
+ossimConnectableObject* ossimConnectableObject::getInput(ossim_uint32 index)
+{
+   if( (index >= 0) && (index < theInputObjectList.size()))
+   {
+      return theInputObjectList[index];
+   }
+
+   return NULL;
+}
+
+const ossimConnectableObject* ossimConnectableObject::getInput(ossim_uint32 index)const
+{
+   if( (index >= 0) && (index < theInputObjectList.size()))
+   {
+      return theInputObjectList[index];
+   }
+
+   return NULL;
+}
+
+ossimConnectableObject* ossimConnectableObject::getOutput(ossim_uint32 index)
+{
+   if( (index >= 0) && (index < theOutputObjectList.size()))
+   {
+      return theOutputObjectList[index];
+   }
+
+   return NULL;
+}
+
+bool ossimConnectableObject::connectInputList(std::vector<ossimConnectableObject*>& inputList)
+{
+   bool result = true;
+   ossim_uint32 i = 0;
+   vector<ossimConnectableObject*> oldInputs = theInputObjectList;
+   vector<ossimConnectableObject*> newInputs;
+   vector<ossimConnectableObject*>::const_iterator currentInput = inputList.begin();
+   vector<ossimConnectableObject*> tempOld;
+   if(theInputObjectList.size())
+     {
+       for(i = 0; i < theInputObjectList.size(); ++i)
+	 {
+	   if(oldInputs[i])
+	     {
+	       tempOld.push_back(oldInputs[i]);
+	     }
+	   theInputObjectList[i] = NULL;
+	 }
+     }
+   if(theInputListIsFixedFlag && (theInputObjectList.size()==0))
+   {
+      return false;
+   }
+
+   if(!theInputListIsFixedFlag)
+     {
+       theInputObjectList.clear();
+     }
+   if(tempOld.size())
+     {
+       for(i = 0; i < tempOld.size(); ++ i)
+	 {
+	   tempOld[i]->disconnectMyOutput(this, false);
+	 }
+     }
+   //   disconnectAllInputs();
+
+   if(inputList.size() == 1)
+   {
+      return (connectMyInputTo(inputList[0])>=0);
+   }
+   i = 0;
+   while(currentInput != inputList.end())
+   {
+      if(!canConnectMyInputTo(i, *currentInput))
+      {
+         result = false;
+      }
+      ++i;
+      ++currentInput;
+   }
+
+   if(!result)
+   {
+      return false;
+   }
+    // now connect the new outputs
+   //
+   currentInput = inputList.begin();
+   while(currentInput != inputList.end())
+   {
+      if(*currentInput)
+      {
+         (*currentInput)->connectMyOutputTo(this, false);
+      }
+      ++currentInput;
+   }
+   ossimConnectionEvent event(this,
+                              OSSIM_EVENT_CONNECTION_DISCONNECT_ID,
+                              newInputs,
+                              oldInputs,
+                              ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+
+   if(theInputObjectList.size())
+   {
+      theInputObjectList = inputList;
+      fireEvent(event);
+   }
+   else
+   {
+      theInputObjectList = inputList;
+   }
+
+   newInputs          = theInputObjectList;
+
+
+
+   event = ossimConnectionEvent(this,
+				OSSIM_EVENT_CONNECTION_CONNECT_ID,
+				newInputs,
+				oldInputs,
+				ossimConnectionEvent::OSSIM_INPUT_DIRECTION);
+   fireEvent(event);
+
+   return result;
+}
+
+bool ossimConnectableObject::connectOutputList(std::vector<ossimConnectableObject*>& outputList)
+{
+   bool result = true;
+   ossim_int32 index  = 0;
+   vector<ossimConnectableObject*> oldOutputs = theOutputObjectList;
+   vector<ossimConnectableObject*> newOutputs;
+   vector<ossimConnectableObject*>::const_iterator currentOutput = outputList.begin();
+
+   disconnectAllOutputs();
+
+   if(outputList.size() == 1)
+   {
+      return (connectMyOutputTo(outputList[0])>=0);
+   }
+   while(currentOutput != outputList.end())
+   {
+      if(!canConnectMyOutputTo(index, *currentOutput))
+      {
+         result = false;
+      }
+      ++currentOutput;
+   }
+
+   if(!result)
+   {
+      return false;
+   }
+
+   theOutputObjectList = outputList;
+   newOutputs = theOutputObjectList;
+
+   ossimConnectionEvent event(this,
+                              OSSIM_EVENT_CONNECTION_CONNECT_ID,
+                              newOutputs,
+                              oldOutputs,
+                              ossimConnectionEvent::OSSIM_OUTPUT_DIRECTION);
+   fireEvent(event);
+
+   return result;
+}
+
+void ossimConnectableObject::setNumberOfInputs(ossim_int32 numberOfInputs)
+{
+   if((ossim_int32)theInputObjectList.size() == numberOfInputs)
+   {
+      return;
+   }
+   ossim_int32 i = 0;
+   if(numberOfInputs < (ossim_int32)theInputObjectList.size())
+   {
+      vector<ossimConnectableObject*> v(theInputObjectList.begin(),
+                                        theInputObjectList.begin()+numberOfInputs);
+      vector<ossimConnectableObject*> disconnectList;
+
+      for(i = numberOfInputs;
+          i < (ossim_int32)theInputObjectList.size();
+          ++i)
+      {
+         if(theInputObjectList[i])
+         {
+            disconnectList.push_back(theInputObjectList[i]);
+         }
+      }
+      disconnectMyInputs(disconnectList);
+
+      theInputObjectList.clear();
+      theInputObjectList = v;
+   }
+   else
+   {
+      for(i = (ossim_int32)theInputObjectList.size();
+          i < numberOfInputs;
+          ++i)
+      {
+         theInputObjectList.push_back((ossimConnectableObject*)NULL);
+      }
+   }
+}
+
+void ossimConnectableObject::setNumberOfOutputs(ossim_int32 numberOfOutputs)
+{
+   if((ossim_int32)theOutputObjectList.size() == numberOfOutputs)
+   {
+      return;
+   }
+   ossim_int32 i = 0;
+   if(numberOfOutputs < (ossim_int32)theOutputObjectList.size())
+   {
+      vector<ossimConnectableObject*> v(theOutputObjectList.begin(),
+                                        theOutputObjectList.begin()+numberOfOutputs);
+      vector<ossimConnectableObject*> disconnectList;
+      for(i = numberOfOutputs;
+          i < (ossim_int32)theOutputObjectList.size();
+          ++i)
+      {
+         if(theOutputObjectList[i])
+         {
+            disconnectList.push_back(theOutputObjectList[i]);
+         }
+      }
+      disconnectMyOutputs(disconnectList);
+
+      theOutputObjectList.clear();
+      theOutputObjectList = v;
+   }
+   else
+   {
+      for(i = (ossim_int32)theOutputObjectList.size();
+          i < numberOfOutputs;
+          ++i)
+      {
+         theOutputObjectList.push_back((ossimConnectableObject*)NULL);
+      }
+   }
+}
+
+
+const ossimConnectableObject* ossimConnectableObject::getOutput(ossim_uint32 index)const
+{
+   if( (index >= 0) && (index < theOutputObjectList.size()))
+   {
+      return theOutputObjectList[index];
+   }
+
+   return NULL;
+}
+
+void ossimConnectableObject::findAllInputsOfType(vector<ossimConnectableObject*>& result,
+                                                 const RTTItypeid& typeInfo,
+                                                 bool propagateToInputs,
+                                                 bool recurseChildren)
+{
+   int i;
+   int j;
+   // go through children first
+   //
+   ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                        this);
+   if(inter&&recurseChildren)
+   {
+      vector<ossimConnectableObject*> tempList = inter->findAllObjectsOfType(typeInfo,
+                                                                             true);
+
+      for(j = 0; j < (int)tempList.size(); ++j)
+      {
+         std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), tempList[j]);
+         if(iter == result.end())
+         {
+            result.push_back(tempList[j]);
+         }
+      }
+   }
+
+   for(i = 0; i < (int)getNumberOfInputs(); ++i)
+   {
+      ossimConnectableObject* current = getInput(i);
+      if(current&&(current->canCastTo(typeInfo)))
+      {
+         vector<ossimConnectableObject*>::iterator position = std::find(result.begin(), result.end(), current);
+
+         if(position == result.end())
+         {
+            result.push_back(current);
+         }
+      }
+      inter = PTR_CAST(ossimConnectableContainerInterface, current);
+      if(inter)
+      {
+         vector<ossimConnectableObject*> tempList = inter->findAllObjectsOfType(typeInfo, true);
+         for(j = 0; j < (int)tempList.size(); ++j)
+         {
+            std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), tempList[j]);
+            if(iter == result.end())
+            {
+               result.push_back(tempList[j]);
+            }
+         }
+      }
+
+      if(propagateToInputs&&current)
+      {
+         current->findAllInputsOfType(result,
+                                      typeInfo,
+                                      true,
+                                      recurseChildren);
+      }
+   }
+}
+
+void ossimConnectableObject::findAllInputsOfType(vector<ossimConnectableObject*>& result,
+                                                 const ossimString& className,
+                                                 bool propagateToInputs,
+                                                 bool recurseChildren)
+{
+   int j;
+   // go through children first
+   //
+   ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                        this);
+   if(inter&&recurseChildren)
+   {
+      vector<ossimConnectableObject*> tempList = inter->findAllObjectsOfType(className,
+                                                                             true);
+
+      for(j = 0; j < (int)tempList.size(); ++j)
+      {
+         std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), tempList[j]);
+         if(iter == result.end())
+         {
+            result.push_back(tempList[j]);
+         }
+      }
+   }
+   for(ossim_uint32 i = 0; i < getNumberOfInputs(); ++i)
+   {
+      ossimConnectableObject* current = getInput(i);
+      if(current&&(current->canCastTo(className)))
+      {
+         std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), current);
+         if(iter == result.end())
+         {
+            result.push_back(current);
+         }
+      }
+      ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                           current);
+      if(inter)
+      {
+         vector<ossimConnectableObject*> tempList = inter->findAllObjectsOfType(className, true);
+         for(j = 0; j < (int)tempList.size(); ++j)
+         {
+            std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), tempList[j]);
+            if(iter == result.end())
+            {
+               result.push_back(tempList[j]);
+            }
+         }
+      }
+
+      if(propagateToInputs&&current)
+      {
+         current->findAllInputsOfType(result,
+                                      className,
+                                      true,
+                                      recurseChildren);
+      }
+   }
+}
+
+void ossimConnectableObject::findAllOutputsOfType(vector<ossimConnectableObject*>& result,
+                                                  const RTTItypeid& typeInfo,
+                                                  bool propagateToOutputs,
+                                                  bool recurseChildren)
+{
+   int j;
+   // go through children first
+   //
+   ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                        this);
+   if(inter&&recurseChildren)
+   {
+      vector<ossimConnectableObject*> tempList = inter->findAllObjectsOfType(typeInfo,
+                                                                             true);
+
+      for(j = 0; j < (int)tempList.size(); ++j)
+      {
+         std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), tempList[j]);
+         if(iter == result.end())
+         {
+            result.push_back(tempList[j]);
+         }
+      }
+   }
+   for(ossim_uint32 i = 0; i < getNumberOfOutputs(); ++i)
+   {
+      ossimConnectableObject* current = getOutput(i);
+      if(current&&(current->canCastTo(typeInfo)))
+      {
+         result.push_back(current);
+      }
+      ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                               current);
+      if(inter)
+      {
+         vector<ossimConnectableObject*> tempList = inter->findAllObjectsOfType(typeInfo, true);
+         for(j = 0; j < (int)tempList.size(); ++j)
+         {
+            std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), tempList[j]);
+            if(iter == result.end())
+            {
+               result.push_back(tempList[j]);
+            }
+         }
+      }
+
+      if(propagateToOutputs&&current)
+      {
+         current->findAllOutputsOfType(result,
+                                       typeInfo,
+                                       true,
+                                       recurseChildren);
+      }
+   }
+}
+
+void ossimConnectableObject::findAllOutputsOfType(vector<ossimConnectableObject*>& result,
+                                                  const ossimString& className,
+                                                  bool propagateToOutputs,
+                                                  bool recurseChildren)
+{
+   int j;
+   // go through children first
+   //
+   ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                        this);
+   if(inter&&recurseChildren)
+   {
+      vector<ossimConnectableObject*> tempList = inter->findAllObjectsOfType(className,
+                                                                             true);
+
+      for(j = 0; j < (int)tempList.size(); ++j)
+      {
+         std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), tempList[j]);
+         if(iter == result.end())
+         {
+            result.push_back(tempList[j]);
+         }
+      }
+   }
+   for(ossim_uint32 i = 0; i < getNumberOfOutputs(); ++i)
+   {
+      ossimConnectableObject* current = getOutput(i);
+      if(current&&(current->canCastTo(className)))
+      {
+         std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), current);
+         if(iter == result.end())
+         {
+            result.push_back(current);
+         }
+      }
+      ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                               current);
+      if(inter)
+      {
+         vector<ossimConnectableObject*> tempList = inter->findAllObjectsOfType(className,
+                                                                                true);
+         for(j = 0; j < (int)tempList.size(); ++j)
+         {
+            std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), tempList[j]);
+            if(iter == result.end())
+            {
+               result.push_back(tempList[j]);
+            }
+         }
+      }
+
+      if(propagateToOutputs&&current)
+      {
+         current->findAllOutputsOfType(result,
+                                       className,
+                                       true,
+                                       recurseChildren);
+      }
+   }
+}
+
+
+void ossimConnectableObject::propagateEventToOutputs(ossimEvent& event)
+{
+   ossim_uint32 i;
+
+   for(i = 0; i <getNumberOfOutputs(); ++i)
+   {
+      ossimConnectableObject* obj = getOutput(i);
+      if(obj)
+      {
+         obj->fireEvent(event);
+         obj->propagateEventToOutputs(event);
+      }
+   }
+}
+
+void ossimConnectableObject::propagateEventToInputs(ossimEvent& event)
+{
+   ossim_uint32 i;
+
+   for(i = 0; i <getNumberOfInputs(); ++i)
+   {
+      ossimConnectableObject* obj = getInput(i);
+      if(obj)
+      {
+         obj->fireEvent(event);
+         obj->propagateEventToInputs(event);
+      }
+   }
+}
+
+void ossimConnectableObject::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property.valid()) return;
+   if(property->getName() == "Description")
+   {
+      property->valueToString(theDescription);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimConnectableObject::getProperty(const ossimString& name)const
+{
+   if(name == "Description")
+   {
+      return new ossimTextProperty(name, theDescription);
+   }
+   else if(name == "Class name")
+   {
+      ossimProperty* prop = new ossimTextProperty(name,
+                                                  getClassName());
+      prop->setReadOnlyFlag(true);
+
+      return prop;
+   }
+   return (ossimProperty*)NULL;
+}
+
+void ossimConnectableObject::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   propertyNames.push_back("Class name");
+   propertyNames.push_back("Description");
+}
+
+bool ossimConnectableObject::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   const char* lookup = kwl.find(prefix,
+                                 ossimKeywordNames::ID_KW);
+
+   // disconnect(this);
+
+   if(lookup)
+   {
+      theId = ossimId(ossimString(lookup).toLong());
+   }
+
+   lookup = kwl.find(prefix, CONNECTABLE_INPUT_LIST_FIXED_KW);
+   if(lookup)
+   {
+      theInputListIsFixedFlag = ossimString(lookup).toBool();
+   }
+
+   lookup = kwl.find(prefix, CONNECTABLE_OUTPUT_LIST_FIXED_KW);
+   if(lookup)
+   {
+      theOutputListIsFixedFlag = ossimString(lookup).toBool();
+   }
+
+   ossim_int32 numberInputs  = 0;
+   ossim_int32 numberOutputs = 0;
+
+   ossimString regExpression;
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_INPUTS_KW);
+   if(lookup)
+   {
+      numberInputs = ossimString(lookup).toLong();
+   }
+   else
+   {
+      regExpression = ossimString("^(") + ossimString(prefix) + "input_connection[0-9]+)";
+      numberInputs = kwl.getNumberOfSubstringKeys(regExpression);
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_OUTPUTS_KW);
+   if(lookup)
+   {
+      numberOutputs = ossimString(lookup).toLong();
+   }
+   else
+   {
+      regExpression = ossimString("^(") + ossimString(prefix) + "output_connection[0-9]+)";
+      numberOutputs = kwl.getNumberOfSubstringKeys(regExpression);
+   }
+   theDescription = kwl.find(prefix, ossimKeywordNames::DESCRIPTION_KW);
+
+   setNumberOfInputs(numberInputs);
+   setNumberOfOutputs(numberOutputs);
+
+   return ossimObject::loadState(kwl, prefix);
+}
+
+bool ossimConnectableObject::saveState(ossimKeywordlist& kwl,
+                                       const char* prefix)const
+{
+   ossimObject::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           ossimKeywordNames::ID_KW,
+           theId.getId(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::DESCRIPTION_KW,
+           theDescription,
+           true);
+
+   kwl.add(prefix,
+           CONNECTABLE_INPUT_LIST_FIXED_KW,
+           (long)theInputListIsFixedFlag,
+           true);
+
+   kwl.add(prefix,
+           CONNECTABLE_OUTPUT_LIST_FIXED_KW,
+           (long)theOutputListIsFixedFlag,
+           true);
+
+   kwl.add(prefix,
+	   ossimKeywordNames::NUMBER_INPUTS_KW,
+	   (long)theInputObjectList.size(),
+	   true);
+
+   kwl.add(prefix,
+	   ossimKeywordNames::NUMBER_OUTPUTS_KW,
+	   (long)theOutputObjectList.size(),
+	   true);
+
+   ossim_int32 i = 0;
+   for(i = 1; i <= (ossim_int32)theInputObjectList.size(); ++i)
+   {
+      ossimString value = "input_connection" + ossimString::toString(i);
+
+      long id;
+
+      if(theInputObjectList[i-1])
+      {
+         id = theInputObjectList[i-1]->getId().getId();
+      }
+      else
+      {
+         id = -1;
+      }
+      kwl.add(prefix,
+              value.c_str(),
+              id,
+              true);
+   }
+
+   for(i = 1; i <= (ossim_int32)theOutputObjectList.size(); ++i)
+   {
+      ossimString value = "output_connection" + ossimString::toString(i);
+
+      long id;
+
+      if(theOutputObjectList[i-1])
+      {
+         id = theOutputObjectList[i-1]->getId().getId();
+      }
+      else
+      {
+         id = -1;
+      }
+      kwl.add(prefix,
+              value.c_str(),
+              id,
+              true);
+   }
+
+   return true;
+}
+
+ossim_uint32 ossimConnectableObject::saveStateOfAllInputs(
+   ossimKeywordlist& kwl,
+   bool              saveThisStateFlag,
+   ossim_uint32      objectIndex,
+   const char*       prefix) const
+{
+   ossim_uint32 index = objectIndex;
+   
+   const ossim_uint32 NUMBER_OF_INPUTS = getNumberOfInputs();
+   if (NUMBER_OF_INPUTS)
+   {
+      // Save all the inputs.
+      for(ossim_uint32 i = 0; i < NUMBER_OF_INPUTS; ++i)
+      {
+         const ossimConnectableObject* input = getInput(i);
+         if(input)
+         {
+            index = input->saveStateOfAllInputs(kwl,
+                                                true,
+                                                index,
+                                                prefix);
+         }
+      }
+   }
+
+   if (saveThisStateFlag)
+   {
+      ossimString myPrefix;
+      if (prefix)
+      {
+         myPrefix = prefix;
+      }
+      
+      myPrefix += "object";
+      myPrefix += ossimString::toString(index);
+      myPrefix += ".";
+
+      // Save the state of this object.
+      saveState(kwl, myPrefix.c_str());
+      ++index;
+   }
+   
+   return index;
+}
+
+bool ossimConnectableObject::canConnectMyOutputTo(ossim_int32 myOutputIndex,
+						  const ossimConnectableObject* /* object */ ) const
+{
+  if(theOutputListIsFixedFlag)
+    {
+      return ((myOutputIndex >= 0) &&
+	      (myOutputIndex < (ossim_int32)theOutputObjectList.size()));
+    }
+
+  return ((myOutputIndex >= 0) &&
+	  (myOutputIndex  <= (ossim_int32)theOutputObjectList.size()));
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimConnectableObject.h b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableObject.h
new file mode 100644
index 0000000000..9976f518a0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimConnectableObject.h
@@ -0,0 +1,470 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+// Description:
+// 
+// Contains class declaration for ossimConnectableObject the base class for
+// all connectable objects.
+//
+//*************************************************************************
+// $Id: ossimConnectableObject.h,v 1.54 2005/12/27 15:47:49 dburken Exp $
+
+#ifndef ossimConnectableObject_HEADER
+#define ossimConnectableObject_HEADER
+
+#include <vector>
+
+#include <base/common/ossimObject.h>
+#include <base/common/ossimId.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/events/ossimListenerManager.h>
+#include <base/common/ossimPropertyInterface.h>
+
+/**
+ * This class is the base of all connectable objects.  It will manage
+ * firing any attachment events (changing, adding and removing, etc.
+ * This allows us to perform automatic notification to nodes
+ * to the input's or output's.
+ *
+ * The only methods that the derived classes should override are the
+ * canConnect methods.
+ */
+class  OSSIMDLLEXPORT  ossimConnectableObject : public ossimObject,
+                                                public ossimListenerManager,
+                                                public ossimPropertyInterface
+{
+public:
+   enum ossimConnectableObjectDirectionType
+   {
+      CONNECTABLE_DIRECTION_NONE   = 0,
+      CONNECTABLE_DIRECTION_INPUT  = 1,
+      CONNECTABLE_DIRECTION_OUTPUT = 2
+   };
+   /**
+    * Base constructor of this object.
+    */
+   ossimConnectableObject(ossimObject* owner=0);
+   ossimConnectableObject(ossimObject* owner,
+                          long inputListSize,
+                          long outputListSize,
+                          bool inputListIsFixedFlag=true,
+                          bool outputListIsFixedFlag=true);
+
+   virtual ~ossimConnectableObject();
+
+   /**
+    * All connectable objects will have id's.  This allows us to
+    * set the id of this object.
+    */
+   void setId(const ossimId& id){theId = id;}
+
+   /**
+    * Will allow us to get this object's id.
+    */
+   const ossimId& getId()const{return theId;}
+   
+   /**
+    * Fetches the current owner, most likely a container but not limited to one.
+    */
+   const ossimObject* getOwner() const { return theOwner; }
+
+   /**
+    * Permits changing the object's owner.
+    */
+   virtual void changeOwner(ossimObject* owner);
+
+   virtual void setDescription(const ossimString& description);
+   virtual ossimString getDescription()const;
+   
+   /**
+    * will check the direction specified to see if all slots are full.
+    * If any slot is null then false is returned.
+    * If a filter requires options testing they
+    * need to override this method.  The argument can be ored together. If you
+    * want both checked then pass
+    * CONNECTABLE_DIRECTION_INPUT | CONNECTABLE_DIRECTION_OUTPUT
+    */
+   virtual bool isConnected(ossimConnectableObjectDirectionType direction = CONNECTABLE_DIRECTION_INPUT)const;
+
+
+   /**
+    *
+    * Searches the input list and the output list for the
+    * passed in id.  Returns NULL if it wasn't found.
+    *
+    */
+   virtual ossimConnectableObject* findConnectableObject(const ossimId& id);
+
+   /**
+    * Will search for a given object of the passed in RTTI type.
+    */
+   virtual ossimConnectableObject* findObjectOfType(RTTItypeid typeId,
+                                                    ossimConnectableObjectDirectionType directionType,
+                                                    bool recurse = true);
+
+   virtual ossimConnectableObject* findObjectOfType(const ossimString& obj,
+                                                    ossimConnectableObjectDirectionType directionType,
+                                                    bool recurse = true);
+
+   /**
+    * @param className Class name of object to look for.
+    * 
+    * @return object of the passed in RTTI type or NULL if not found.
+    *
+    * @note This method does NOT traverse beyond any objects the do not have
+    * a fixed input of one connection.
+    */
+   virtual ossimConnectableObject* findInputObjectOfType(
+      const ossimString& className);
+   
+   /**
+    * Return a valid index of the input list if the passed in object
+    * is found else return -1.
+    */
+   virtual ossim_int32 findInputIndex(const ossimConnectableObject* object);
+
+   /**
+    * Return a valid index of the input list if the passed id
+    * is found else return -1.
+    */
+   virtual ossim_int32 findInputIndex(const ossimId& id);
+
+   /**
+    * Return a valid index of the output list if the passed in object
+    * is found else return -1.
+    */
+   virtual ossim_int32 findOutputIndex(const ossimConnectableObject* object);
+
+   /**
+    * Return a valid index of the output list if the passed in object
+    * is found else return -1.
+    */   
+   virtual ossim_int32 findOutputIndex(const ossimId& id);
+   
+   /**
+    * Should return the first available index to connect to.  The connectMyInputTo
+    * that just takes another ossimConnectableObject as input and not an index
+    * will call this method.  By default this method will find the first open
+    * slot (not null) or append o the list if it's dynamic.  if the list is
+    * dynamic it calls conConnectMyInputTo(index, object) on an index = to listSize.
+    * 
+    */
+   virtual ossim_int32 getMyInputIndexToConnectTo(ossimConnectableObject* object)const;
+   
+
+   /**
+    * Should return the first available index to connect to.  The connectMyOutputTo
+    * that just takes another ossimConnectableObject as input and not an index
+    * will call this method.  By default this method will find the first open
+    * slot (not null) or append to the list if it's dynamic.  if the list is
+    * dynamic it calls canConnectMyOutputTo(index, object) on an index = to listSize.
+    * 
+    */
+   virtual ossim_int32 getMyOutputIndexToConnectTo(ossimConnectableObject* object)const;
+   
+   /**
+    * required to be overriden by derived classes
+    */
+   virtual bool canConnectMyInputTo(ossim_int32 myInputIndex,
+                                    const ossimConnectableObject* object)const=0;
+   
+   /**
+    * default implementation is to allow anyone to connect to us.
+    */
+   virtual bool canConnectMyOutputTo(ossim_int32 myOutputIndex,
+                                     const ossimConnectableObject* object)const;
+   
+   /**
+    * Will disconnect the object passed in.
+    */
+   virtual void disconnect(ossimConnectableObject* object=0);
+
+   /**
+    * Will disconnect the object passed in.
+    */
+   virtual void disconnect(const ossimId& id);
+   
+   /**
+    * Will disconnect the object at the given input index and generate
+    * a connection event.
+    */
+   virtual ossimConnectableObject* disconnectMyInput(ossim_int32 inputIndex,
+						     bool disconnectOutputFlag=true,
+						     bool createEventFlag = true);
+  
+  /**
+   * Finds the index of the passed in input and calls
+   * disconnectMyInput(inputIndex, disconnectOutputFlag, createEventFlag);
+   */
+   virtual void disconnectMyInput(ossimConnectableObject* input,
+                                  bool disconnectOutputFlag=true,
+                                  bool createEventFlag = true);
+   /**
+    *
+    */
+   virtual void disconnectMyInputs(std::vector<ossimConnectableObject*>& inputList,
+                                   bool disconnectOutputFlag=true,
+                                   bool createEventFlag=true);
+   
+   /**
+    * Will disconnect the object at the given output index and generate
+    * a connection event.  If there is no object at that index then no
+    * event is generated and NULL is returned.  The disconnectOutputFlag
+    * says do you want this method to disconnect the output pointer to
+    * this object.
+    */
+   virtual ossimConnectableObject* disconnectMyOutput(ossim_int32 outputIndex,
+						      bool disconnectInputFlag=true,
+						      bool createEventFlag = true);
+  
+   /**
+    * Will disconnect the output object.  It will get the index of
+    * the object and call disconnectMyOutput(index, disconnectOutputFlag).
+    */
+   virtual void disconnectMyOutput(ossimConnectableObject* output,
+                                   bool disconnectInputFlag=true,
+                                   bool createEventFlag=true);
+
+   virtual void disconnectMyOutputs(std::vector<ossimConnectableObject*>& outputList,
+                                    bool disconnectOutputFlag=true,
+                                    bool createEventFlag=true);
+   /**
+    * Will disconnect all of the input objects.
+    */
+   virtual void disconnectAllInputs();
+
+   /**
+    * Will disconnect all of the output objects.
+    */
+   virtual void disconnectAllOutputs();
+
+   /**
+    * Will try to connect this objects input to the passed in object.
+    * It will return a valid index >= 0 if successful.  Will use the
+    * getMyInputIndexToConnectTo method to implement the connection
+    */
+   virtual ossim_int32 connectMyInputTo(ossimConnectableObject* inputObject,
+                                        bool makeOutputConnection=true,
+                                        bool createEventFlag=true);
+
+   /**
+    * Will connect the specified input to the passed in object
+    */
+   virtual ossim_int32 connectMyInputTo(ossim_int32 inputIndex,
+                                        ossimConnectableObject* inputObject,
+                                        bool makeOutputConnection=true,
+                                        bool createEventFlag=true);
+   
+   virtual bool connectMyInputTo(std::vector<ossimConnectableObject*>& inputList,
+                                 bool makeOutputConnection=true,
+                                 bool createEventFlag = true);   
+
+   /**
+    * Will try to connect this objects output to the passed in object.
+    * It will return a valid index >= 0 if successful.  It will in turn call
+    * the passed in objects connect input command if makeInputConnection
+    * is set to true.
+    *
+    * Will use the getMyOutputIndexToConnectTo to implement this method
+    */
+   virtual ossim_int32 connectMyOutputTo(ossimConnectableObject* outputObject,
+                                         bool makeInputConnection=true,
+                                         bool createEventFlag=true);
+   
+   virtual bool connectMyOutputTo(std::vector<ossimConnectableObject*>& outputList,
+                                  bool makeInputConnection=true,
+                                  bool createEventFlag=true);
+   
+   /**
+    * Will disconnect itself from all inputs and reset to the passed in
+    * input list.  It will return true if all objects were successfully
+    * added.
+    */
+   virtual bool connectInputList(std::vector<ossimConnectableObject*>& inputList);
+   
+   /**
+    * Will disconnect itself from all outputs and reset to the passed in
+    * output list.  It will return true if all objects were successfully
+    * added.
+    */
+   virtual bool connectOutputList(std::vector<ossimConnectableObject*>& outputList);
+   
+   /**
+    * Returns the number of input objects.
+    */
+   virtual ossim_uint32 getNumberOfInputs()const
+      {
+         return (ossim_uint32)theInputObjectList.size();
+      }
+
+   /**
+    * Return the number of output objects
+    */
+   virtual ossim_uint32 getNumberOfOutputs()const
+      {
+         return (ossim_uint32)theOutputObjectList.size();
+      }
+   
+   /**
+    * returns the object at the specified index.
+    * if the index is not valid then NULL is
+    * returned
+    */
+   ossimConnectableObject* getInput(ossim_uint32 index=0);   
+
+   /**
+    * returns the object at the specified index.
+    * if the index is not valid then NULL is
+    * returned
+    */
+   const ossimConnectableObject* getInput(ossim_uint32 index=0)const;
+
+   /**
+    * returns the object at the specified index.
+    * if the index is not valid then NULL is
+    * returned
+    */
+   ossimConnectableObject* getOutput(ossim_uint32 index=0);
+
+   /**
+    * returns the object at the specified index.
+    * if the index is not valid then NULL is
+    * returned
+    */
+   const ossimConnectableObject* getOutput(ossim_uint32 index=0)const;
+   
+   /**
+    * Will set the number of inputs.  This will expand the list if the number
+    * of inputs is larger than the current number of inputs.  Will shrink
+    * the list if the current number of inputs is larger than the passed in
+    * inputs.
+    */
+   virtual void setNumberOfInputs(ossim_int32 numberOfInputs);
+
+   virtual bool getInputListIsFixedFlag()const
+      {
+         return theInputListIsFixedFlag;
+      }
+
+   virtual bool getOutputListIsFixedFlag()const
+      {
+         return theOutputListIsFixedFlag;
+      }
+   /**
+    * Will set the number of outputs.  This will expand the list if the
+    * number of outputs is larger than the current number of outputs.
+    * Will shrink the list if the current number of outputs is larger than
+    * the passed in outputs.
+    */
+   virtual void setNumberOfOutputs(ossim_int32 numberOfInputs);
+   
+   const std::vector<ossimConnectableObject*>& getInputList()const
+      {
+         return theInputObjectList;
+      }
+   const std::vector<ossimConnectableObject*>& getOutputList()const
+      {
+         return theOutputObjectList;
+      }
+   std::vector<ossimConnectableObject*>& getInputList()
+      {
+         return theInputObjectList;
+      }
+   std::vector<ossimConnectableObject*>& getOutputList()
+      {
+         return theOutputObjectList;
+      }
+
+   virtual void findAllInputsOfType(vector<ossimConnectableObject*>& result,
+                                    const RTTItypeid& typeInfo,
+                                    bool propagateToInputs=true,
+                                    bool recurseChildren=false);
+   virtual void findAllInputsOfType(vector<ossimConnectableObject*>& result,
+                                    const ossimString& className,
+                                    bool propagateToInputs=true,
+                                    bool recurseChildren=false);
+   virtual void findAllOutputsOfType(vector<ossimConnectableObject*>& result,
+                                     const ossimString& className,
+                                     bool propagateToOutputs=true,
+                                    bool recurseChildren=false);
+   virtual void findAllOutputsOfType(vector<ossimConnectableObject*>& result,
+                                     const RTTItypeid& typeInfo,
+                                     bool propagateToOutputs=true,
+                                    bool recurseChildren=false);
+   
+   virtual void propagateEventToOutputs(ossimEvent& event);
+   virtual void propagateEventToInputs(ossimEvent& event);
+
+   /* ------------------- PROPERTY INTERFACE -------------------- */
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   /* ------------------ PROPERTY INTERFACE END ------------------- */
+
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = (const char*)NULL);
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = (const char*)NULL)const;
+
+   /**
+    * Save the state of all inputs to a keyword list.  This will do a
+    * recursive call through all inputs and save their state to a
+    * keyword list.
+    *
+    * @param kwl Keyword list to save state to.
+    *
+    * @param saveThisStateFlag If the true the state of this object will be
+    * saved as well as all inputs. Default = true.
+    *
+    * @param  objectIndex Index to be used for prefix.  So if
+    * objectIndex = 1, the first object will have a prefix of: "object1."
+    * Default = 1.
+    *
+    * @param prefix Prefix to tack onto keyword.  If prefix = "myChain." and
+    * objectIndex = 1, then the first keyword would be
+    * "myChain.object1.some_keyword".
+    *
+    * @return Returns the next object index.  This is the last index used
+    * plus one.  Used internally to keep track of index to use for prefix.
+    */
+   virtual ossim_uint32 saveStateOfAllInputs(ossimKeywordlist& kwl,
+                                             bool saveThisStateFlag=true,
+                                             ossim_uint32 objectIndex=1,
+                                             const char* prefix=NULL) const;
+   
+protected:
+   ossimId      theId;
+   ossimString  theDescription;
+   ossimObject* theOwner;
+
+   /**
+    * Indicates whether the theInputObjectList is fixed
+    */
+   bool theInputListIsFixedFlag;
+
+   /**
+    * Indicates whether the theOutputObjectList is fixed
+    */
+   bool theOutputListIsFixedFlag;
+   
+   /**
+    * Holds a list of input objects.
+    */
+   std::vector<ossimConnectableObject*>     theInputObjectList;
+   
+   /**
+    * Holds a list of output objects.
+    */
+   std::vector<ossimConnectableObject*>     theOutputObjectList;
+
+private:
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimConstants.h b/Utilities/OSSIM/ossim_core/base/common/ossimConstants.h
new file mode 100644
index 0000000000..d257b2af14
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimConstants.h
@@ -0,0 +1,514 @@
+/********************************************************************
+ * Copyright (C) 2000 ImageLinks Inc.
+ *
+ * License:  LGPL
+ *
+ * See LICENSE.txt file in the top level directory for more details.
+ *
+ * Author: Ken Melero
+ * 
+ * Description: Common file for global constants.
+ *
+ **************************************************************************
+ * $Id: ossimConstants.h,v 1.69 2005/06/30 18:32:51 gpotts Exp $
+ */
+#ifndef ossimConstants_HEADER
+#define ossimConstants_HEADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <float.h>
+#include <ossimConfig.h>
+
+
+/**
+ * WARNINGS SECTION:
+ */
+#ifdef _MSC_VER /* Quiet a bunch of MSVC warnings... */
+#  pragma warning(disable:4786) /* visual c6.0 compiler */
+#  pragma warning(disable:4251)/* for std:: member variable to have dll interface */
+#  pragma warning(disable:4275) /* for std:: base class to have dll interface */
+#  pragma warning(disable:4800) /* int forcing value to bool */
+#  pragma warning(disable:4244) /* conversion, possible loss of data */
+#endif
+
+/**
+ * DLL IMPORT/EXORT SECTION
+ */
+#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(_MSC_VER) || defined(__VISUALC__) || defined(__BORLANDC__) || defined(__WATCOMC__)
+#  define OSSIMEXPORT __declspec(dllexport)
+#  define OSSIMIMPORT __declspec(dllimport)
+#  ifdef OSSIMMAKINGDLL
+#    define OSSIMDLLEXPORT OSSIMEXPORT
+#    define OSSIM_DLL       OSSIMEXPORT
+#    define OSSIMDLLEXPORT_DATA(type) OSSIMEXPORT type
+#    define OSSIM_DLL_DATA(type) OSSIMEXPORT type
+#    define OSSIMDLLEXPORT_CTORFN
+#  else
+#    define OSSIMDLLEXPORT OSSIMIMPORT
+#    define OSSIM_DLL      OSSIMIMPORT
+#    define OSSIMDLLEXPORT_DATA(type) OSSIMIMPORT type
+#    define OSSIM_DLL_DATA(type) OSSIMIMPORT type
+#    define OSSIMDLLEXPORT_CTORFN
+#  endif
+#else /* not #if defined(_MSC_VER) */
+#  define OSSIMEXPORT
+#  define OSSIMIMPORT
+#  define OSSIMDLLEXPORT
+#  define OSSIM_DLL
+#  define OSSIMDLLEXPORT_DATA
+#  define OSSIM_DLL_DATA
+#  define OSSIMDLLEXPORT_CTORFN
+#endif /* #if defined(_MSC_VER) */
+
+/**
+ * Previous DLL import export section.  Commented out, but left just in case.
+ */
+#if 0 /* Comment out ALL this mess! */
+#if defined(_MSC_VER) || defined(__VISUALC__) || defined(__BORLANDC__) || defined(__GNUC__) || defined(__WATCOMC__)
+#  if (_MSC_VER >= 1300)	/* MSVC .NET 2003 version */
+#    define OSSIMEXPORT __declspec(dllexport)
+#    define OSSIMIMPORT __declspec(dllimport)
+#  else
+#    define OSSIMEXPORT __declspec(dllexport)
+#    define OSSIMIMPORT __declspec(dllimport)
+#  endif
+#else /* compiler doesn't support __declspec() */
+#   define OSSIMEXPORT
+#   define OSSIMIMPORT
+#endif
+
+#if defined(__WXPM__)
+#  if defined (__WATCOMC__)
+#    define OSSIMEXPORT __declspec(dllexport)
+ /*
+   __declspec(dllimport) prepends __imp to imported symbols. We do NOT
+   want that!
+ */
+#    define OSSIMIMPORT
+#  elif (!(defined(__VISAGECPP__) && (__IBMCPP__ < 400 || __IBMC__ < 400 )))
+#    define OSSIMEXPORT _Export
+#    define OSSIMIMPORT _Export
+#  endif
+#elif defined(__OSSIMMAC__)
+#  ifdef __MWERKS__
+#    define OSSIMEXPORT __declspec(export)
+#    define OSSIMIMPORT __declspec(import)
+#  endif
+#endif
+
+#if defined(_MSC_VER)
+#  pragma warning(disable:4786) /* visual c6.0 compiler */
+#  pragma warning(disable:4251) /* for std:: member variable to have dll interface */
+#  pragma warning(disable:4275) /* for std:: base class to have dll interface */
+#  pragma warning(disable:4800) /* int forcing value to bool */
+#  pragma warning(disable:4244) /* conversion, possible loss of data */
+
+#  ifdef OSSIMSINGLEDLL /* one gigantic dll, all declared export */
+#    ifdef EXPORT_OSMMATRIX
+#      define EXPORT_OSMMATRIX  OSSIMEXPORT
+#    endif
+#    ifndef OSSIMDLLEXPORT
+#      define OSSIMDLLEXPORT    OSSIMEXPORT
+#    endif
+#    ifdef EXPORT_OSMELEV
+#      define EXPORT_OSMELEV    OSSIMEXPORT
+#    endif
+#    ifdef EXPORT_OSMSPTDATA
+#      define EXPORT_OSMSPTDATA OSSIMEXPORT
+#    endif
+#    ifdef EXPORT_ISO8211
+#      define EXPORT_ISO8211    OSSIMEXPORT
+#    endif
+#    ifdef EXPORT_OSMPROJ
+#      define EXPORT_OSMPROJ    OSSIMEXPORT
+#    endif
+#    ifndef EXPORT_OSMIMAGING
+#      define EXPORT_OSMIMAGING OSSIMEXPORT
+#    endif
+#  else /* individual dlls, each with their own import/export symbols */
+#    ifndef EXPORT_OSMMATRIX
+#      ifdef OSMMATRIX_EXPORTS
+#        define EXPORT_OSMMATRIX OSSIMEXPORT
+#      else
+#        define EXPORT_OSMMATRIX OSSIMIMPORT
+#      endif
+#    endif
+#    ifndef OSSIMDLLEXPORT
+#      ifdef OSMBASE_EXPORTS
+#        define OSSIMDLLEXPORT OSSIMEXPORT
+#      else
+#        define OSSIMDLLEXPORT OSSIMIMPORT
+#      endif
+#    endif
+#    ifndef EXPORT_OSMELEV
+#      ifdef OSMELEV_EXPORTS
+#        define EXPORT_OSMELEV OSSIMEXPORT
+#      else
+#        define EXPORT_OSMELEV OSSIMIMPORT
+#      endif
+#    endif
+#    ifndef EXPORT_OSMSPTDATA
+#      ifdef OSMSPTDATA_EXPORTS
+#        define EXPORT_OSMSPTDATA OSSIMEXPORT
+#      else
+#        define EXPORT_OSMSPTDATA OSSIMIMPORT
+#      endif
+#    endif
+#    ifndef EXPORT_OSMPROJ
+#      ifdef OSMPROJ_EXPORTS
+#        define EXPORT_OSMPROJ OSSIMEXPORT
+#      else
+#        define EXPORT_OSMPROJ OSSIMIMPORT
+#      endif
+#    endif
+#    ifndef EXPORT_ISO8211
+#      ifdef ISO8211_EXPORTS
+#        define EXPORT_ISO8211 OSSIMEXPORT
+#      else
+#        define EXPORT_ISO8211 OSSIMIMPORT
+#      endif
+#    endif
+#    ifndef EXPORT_OSMIMAGING
+#      ifdef OSMIMAGING_EXPORTS
+#        define EXPORT_OSMIMAGING OSSIMEXPORT
+#      else
+#        define EXPORT_OSMIMAGING OSSIMIMPORT
+#      endif
+#    endif
+#  endif
+#else /* defined(_MSC_VER) */
+#  ifdef OSSIMMAKINGDLL
+#    define OSSIMDLLEXPORT OSSIMEXPORT
+#    define OSSIM_DLL       OSSIMEXPORT
+#    define OSSIMDLLEXPORT_DATA(type) OSSIMEXPORT type
+#    define OSSIM_DLL_DATA(type) OSSIMEXPORT type
+#    define OSSIMDLLEXPORT_CTORFN
+#  elif defined(OSSIMUSINGDLL)
+#    define OSSIMDLLEXPORT OSSIMIMPORT
+#    define OSSIM_DLL      OSSIMIMPORT
+#    define OSSIMDLLEXPORT_DATA(type) OSSIMIMPORT type
+#    define OSSIM_DLL_DATA(type) OSSIMIMPORT type
+#    define OSSIMDLLEXPORT_CTORFN
+#  else /* not making nor using DLL */
+#    define OSSIMDLLEXPORT
+#    define OSSIM_DLL
+#    define OSSIM_DLL_DATA(type) type
+#    define OSSIMDLLEXPORT_DATA(type) type
+#    define OSSIMDLLEXPORT_CTORFN
+#  endif
+#  define EXPORT_OSMMATRIX  OSSIMDLLEXPORT
+#  define EXPORT_OSMELEV    OSSIMDLLEXPORT
+#  define EXPORT_OSMSPTDATA OSSIMDLLEXPORT
+#  define EXPORT_OSMPROJ    OSSIMDLLEXPORT
+#  define EXPORT_OSMIMAGING OSSIMDLLEXPORT
+#endif
+#endif /* End of commented out "#if 0" old DLL import/export section. */
+
+/*
+  we know that if this is defined all other types are defined
+  since its included from ossimConfig.h
+*/
+typedef char                   ossim_int8;
+typedef unsigned char          ossim_uint8;
+typedef signed char            ossim_sint8;
+
+typedef short                  ossim_int16;
+typedef unsigned short         ossim_uint16;
+typedef signed short           ossim_sint16;
+
+typedef int                    ossim_int32;
+typedef unsigned int           ossim_uint32;
+typedef signed int             ossim_sint32;
+
+typedef float                  ossim_float32;
+typedef double                 ossim_float64;
+
+/*
+  these are in ossimConfig.h.  For platforms that dont have a configure
+  you just copy the ossimConfig.h.in to ossimConfig.h found in src directory
+  and make modifications based on your platform
+*/
+#ifdef OSSIM_SIZEOF_LONG_INT
+
+#    if OSSIM_SIZEOF_LONG_INT == 8
+typedef long int               ossim_int64;
+typedef unsigned long int      ossim_uint64;
+typedef signed long int        ossim_sint64;
+#    elif OSSIM_SIZEOF_LONG_LONG == 8
+typedef long long              ossim_int64;
+typedef unsigned long long     ossim_uint64;
+typedef signed long long       ossim_sint64;
+#    else
+typedef long int               ossim_int64;
+typedef unsigned long int      ossim_uint64;
+typedef signed long int        ossim_sint64;
+#    endif
+
+#else
+typedef long int               ossim_int64;
+typedef unsigned long int      ossim_uint64;
+typedef signed long int        ossim_sint64;
+#endif
+
+
+typedef ossim_int32            ossimErrorCode;
+
+enum ossimVertexOrdering
+{
+   OSSIM_VERTEX_ORDER_UNKNOWN    = 0,
+   OSSIM_CLOCKWISE_ORDER         = 1,
+   OSSIM_COUNTERCLOCKWISE_ORDER  = 2
+};
+
+
+/*
+ Corner coordinates are relative to center (0) of pixel
+ or relative to the upper left of pixel (1).
+*/
+enum ossimPixelType
+{
+   OSSIM_PIXEL_IS_POINT = 0,
+   OSSIM_PIXEL_IS_AREA  = 1
+};
+
+/*
+ Definitions for scalar type identification.
+*/
+enum ossimScalarType
+{
+   OSSIM_SCALAR_UNKNOWN    =  0, 
+   OSSIM_UINT8             =  1, /**< 8 bit unsigned integer        */
+   OSSIM_SINT8             =  2, /**< 8 bit signed integer          */
+   OSSIM_UINT16            =  3, /**< 16 bit unsigned integer       */
+   OSSIM_SINT16            =  4, /**< 16 bit signed integer         */
+   OSSIM_UINT32            =  5, /**< 32 bit unsigned integer       */
+   OSSIM_SINT32            =  6, /**< 32 bit signed integer         */
+   OSSIM_FLOAT32           =  7, /**< 32 bit floating point         */
+   OSSIM_FLOAT64           =  8, /**< 64 bit floating point         */
+   OSSIM_CINT16            =  9, /**< 16 bit complex integer        */
+   OSSIM_CINT32            = 10, /**< 32 bit complex integer        */
+   OSSIM_CFLOAT32          = 11, /**< 32 bit complex floating point */
+   OSSIM_CFLOAT64          = 12, /**< 64 bit complex floating point */
+
+   //---
+   // Below for backward compatibility only.  Please use above enums in
+   // conjunction with null, min, max settings to determine bit depth.
+   //---
+   OSSIM_UCHAR             = 1,  /**< 8 bit unsigned iteger */
+   OSSIM_USHORT16          = 3,  /**< 16 bit unsigned iteger */
+   OSSIM_SSHORT16          = 4,  /**< 16 bit signed integer */
+   OSSIM_USHORT11          = 13, /**< 16 bit unsigned integer (11 bits used) */
+   OSSIM_FLOAT             = 7,  /**< 32 bit floating point */
+   OSSIM_NORMALIZED_FLOAT  = 18, /**< normalized floating point  32 bit */
+   OSSIM_DOUBLE            = 8,  /**< double 64 bit    */
+   OSSIM_NORMALIZED_DOUBLE = 20  /**< Normalized double 64 bit */
+};
+
+/*
+ Definitions for interleave type identification.
+*/
+enum ossimInterleaveType
+{
+   OSSIM_INTERLEAVE_UNKNOWN = 0,
+   OSSIM_BIL                = 1,  /* band interleaved by line */
+   OSSIM_BIP                = 2,  /* band interleaved by pixel */
+   OSSIM_BSQ                = 3,  /* band sequential */
+   OSSIM_BSQ_MULTI_FILE     = 4   /* band sequential in separate files */
+};
+
+/*
+ Definitions for origin location.
+*/
+enum ossimOriginLocationType
+{
+   OSSIM_ORIGIN_LOCATION_UNKNOWN = 0,
+   OSSIM_CENTER                  = 1,
+   OSSIM_UPPER_LEFT              = 2,
+   OSSIM_UPPER_LEFT_CENTER       = 3,
+   OSSIM_LOWER_LEFT              = 4,
+   OSSIM_LOWER_LEFT_CENTER       = 5
+};
+
+/*
+ Definitions for coordinate system type.
+*/
+enum ossimCoordinateSystemType
+{
+   OSSIM_COORDINATE_SYSTEM_UNKNOWN = 0,
+   OSSIM_IMAGE_SPACE               = 1,
+   OSSIM_GEOGRAPHIC_SPACE          = 2,
+   OSSIM_PROJECTED_SPACE           = 3,
+   OSSIM_GEOCENTRIC_SPACE          = 4
+};
+
+/*
+ Definitions for coordinate system orientation mode .
+*/
+enum ossimCoordSysOrientMode
+{
+   OSSIM_LEFT_HANDED  = 0,
+   OSSIM_RIGHT_HANDED = 1
+};
+
+
+
+/*
+ Definitions for unit type.
+*/
+enum ossimUnitType
+{
+   OSSIM_UNIT_UNKNOWN    = 0,
+   OSSIM_METERS          = 1,
+   OSSIM_FEET            = 2,
+   OSSIM_US_SURVEY_FEET  = 3,
+   OSSIM_DEGREES         = 4,
+   OSSIM_RADIANS         = 5,
+   OSSIM_NAUTICAL_MILES  = 6,
+   OSSIM_SECONDS         = 7,
+   OSSIM_MINUTES         = 8,
+   OSSIM_PIXEL           = 9,
+   OSSIM_MILES           = 10,
+   OSSIM_MILLIMETERS     = 11,
+   OSSIM_MICRONS         = 12
+};
+
+/*
+ Definitions for data object status.
+*/
+enum ossimDataObjectStatus
+{
+   OSSIM_STATUS_UNKNOWN = 0,
+   OSSIM_NULL           = 1,
+   OSSIM_EMPTY          = 2,
+   OSSIM_PARTIAL        = 3,
+   OSSIM_FULL           = 4
+};
+
+/** Definitions for image type identification. */
+enum ossimImageType
+{
+   OSSIM_IMAGE_TYPE_UNKNOWN       = 0,
+   OSSIM_TIFF_STRIP               = 1,
+   OSSIM_TIFF_STRIP_BAND_SEPARATE = 2,
+   OSSIM_TIFF_TILED               = 3,
+   OSSIM_TIFF_TILED_BAND_SEPARATE = 4,
+   OSSIM_GENERAL_RASTER_BIP       = 5,
+   OSSIM_GENERAL_RASTER_BIL       = 6,
+   OSSIM_GENERAL_RASTER_BSQ       = 7,
+   OSSIM_JPEG                     = 8
+};
+
+/** Definitions for metadata type identification. */
+enum ossimMetadataType
+{
+   OSSIM_META_UNKNOWN   = 0,
+   OSSIM_META_TFW       = 1,
+   OSSIM_META_JGW       = 2,
+   OSSIM_META_GEOM      = 3,
+   OSSIM_META_README    = 4,
+   OSSIM_META_FGDC      = 5,
+   OSSIM_META_ENVI      = 6
+};
+
+enum ossimByteOrder
+{
+   OSSIM_LITTLE_ENDIAN = 0,
+   OSSIM_BIG_ENDIAN    = 1
+};
+
+#ifndef M_PI
+#  define M_PI             ((ossim_float64)3.141592653589793238462643)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI           ((ossim_float64)(2.0 * M_PI))
+#endif
+#ifndef DEG_PER_RAD
+#  define DEG_PER_RAD      ((ossim_float64)(180.0/M_PI))
+#endif
+#ifndef SEC_PER_RAD
+#  define SEC_PER_RAD      ((ossim_float64)206264.8062471)
+#endif
+#ifndef RAD_PER_DEG
+#  define RAD_PER_DEG      ((ossim_float64)(M_PI/180.0))
+#endif
+#ifndef MTRS_PER_FT
+#  define MTRS_PER_FT      ((ossim_float64)0.3048)
+#endif
+#ifndef FT_PER_MTRS
+#  define FT_PER_MTRS      ((ossim_float64)3.280839895013122)
+#endif
+#ifndef FT_PER_MILE
+#  define FT_PER_MILE      ((ossim_float64)5280.0)
+#endif
+#ifndef SQRT_TWO_PI
+#  define SQRT_TWO_PI      ((ossim_float64)2.50662827463100050242)
+#endif
+#ifndef SQRT_TWO_PI_DIV2
+#  define SQRT_TWO_PI_DIV2 ((ossim_float64)7.07106781186547524401E-1)
+#endif
+
+#define OSSIM_DEFAULT_TILE_HEIGHT  ((ossim_int32)64)
+#define OSSIM_DEFAULT_TILE_WIDTH   ((ossim_int32)64)
+
+/*
+ NOTE Reference for U.S. feet value:
+ U.S.G.S. "Map Projections - A Working Manual"
+ USGS Professional paper 1395 page 51
+*/
+#ifndef US_METERS_PER_FT
+#  define  US_METERS_PER_FT ((ossim_float64)0.3048006096)
+#endif
+
+#define OSSIM_DBL_NAN    ((ossim_float64)-1.0/DBL_EPSILON)
+#define OSSIM_FLT_NAN    ((ossim_float32)-1.0/FLT_EPSILON)
+#define OSSIM_LONG_NAN   ((ossim_sint32)0x80000000)
+#define OSSIM_INT_NAN    ((ossim_sint32)0x80000000)
+#define OSSIM_ULONG_NAN  ((ossim_uint32)0x0)
+#define OSSIM_UINT_NAN   ((ossim_uint32)0x0)
+#define OSSIM_SSHORT_NAN ((ossim_sint16)0x8000)
+#define OSSIM_USHORT_NAN ((ossim_uint16)0)
+
+#define OSSIM_DEFAULT_MIN_PIX_UCHAR ((ossim_uint8)1)
+#define OSSIM_DEFAULT_MAX_PIX_UCHAR ((ossim_uint8)255)
+#define OSSIM_DEFAULT_MIN_PIX_UINT8 ((ossim_uint8)1)
+#define OSSIM_DEFAULT_MAX_PIX_UINT8 ((ossim_uint8)255)
+#define OSSIM_DEFAULT_MIN_PIX_SINT8 ((ossim_sint8)0x81)
+#define OSSIM_DEFAULT_MAX_PIX_SINT8 ((ossim_sint8)0x7F)
+#define OSSIM_DEFAULT_MIN_PIX_SINT16 ((ossim_sint16)0x8001)
+#define OSSIM_DEFAULT_MAX_PIX_SINT16 ((ossim_sint16)0x7FFF)
+#define OSSIM_DEFAULT_MIN_PIX_UINT16 ((ossim_uint16)1)
+#define OSSIM_DEFAULT_MAX_PIX_UINT16 ((ossim_uint16)0xFFFF)
+#define OSSIM_DEFAULT_MIN_PIX_SINT32 ((ossim_sint32)0x80000001)
+#define OSSIM_DEFAULT_MAX_PIX_SINT32 ((ossim_sint32)0x7FFFFFFF)
+#define OSSIM_DEFAULT_MIN_PIX_UINT32 ((ossim_uint32)1)
+#define OSSIM_DEFAULT_MAX_PIX_UINT32 ((ossim_uint32)0xFFFFFFFF)
+#define OSSIM_DEFAULT_MIN_PIX_UINT11 ((ossim_uint16)1)
+#define OSSIM_DEFAULT_MAX_PIX_UINT11 ((ossim_uint16)0x07FF)
+#define OSSIM_DEFAULT_MIN_PIX_FLOAT ((ossim_float32)((-1.0/FLT_EPSILON) + 1))
+#define OSSIM_DEFAULT_MAX_PIX_FLOAT  ((ossim_float32)((1.0/FLT_EPSILON)))
+#define OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT ((ossim_float32)((2*FLT_EPSILON)))
+#define OSSIM_DEFAULT_MAX_PIX_NORM_FLOAT ((ossim_float32)1.0)
+#define OSSIM_DEFAULT_MIN_PIX_DOUBLE ((ossim_float64)((-1.0/DBL_EPSILON) + 1))
+#define OSSIM_DEFAULT_MAX_PIX_DOUBLE ((ossim_float64)((1.0/DBL_EPSILON)))
+#define OSSIM_DEFAULT_MIN_PIX_NORM_DOUBLE ((ossim_float64)((2*DBL_EPSILON)))
+#define OSSIM_DEFAULT_MAX_PIX_NORM_DOUBLE ((ossim_float64)(1.0))
+
+
+/*
+ *OSSIM Numerical Limits
+ */
+#ifndef _OSSIM_LIMITS_
+#define _OSSIM_LIMITS_
+#define OSSIM_INFINITY ((ossim_float64)((1.0 / DBL_EPSILON) - 1.0))
+#define OSSIM_NAN      ((ossim_float64)(-(1.0 / DBL_EPSILON)))
+#define OSSIM_EPSILON  ((ossim_float64)(DBL_EPSILON))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimCplUtil.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimCplUtil.cpp
new file mode 100644
index 0000000000..6ac6f2531e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimCplUtil.cpp
@@ -0,0 +1,297 @@
+/*
+ * Copied from "gdal" project. See licence below.
+ *
+ * Global functions for gdal code compatibility.
+ *
+ * Project:  ISO 8211 Access
+ * Purpose:  Main declarations for ISO 8211.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam <warmerdam@pobox.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * $Id&
+ */
+
+#include <base/common/ossimCplUtil.h>
+#include <base/data_types/ossimString.h>
+
+#ifndef OSSIM_CSLT_HONOURSTRINGS
+#  define OSSIM_CSLT_HONOURSTRINGS      0x0001
+#endif
+#ifndef OSSIM_CSLT_ALLOWEMPTYTOKENS
+#  define OSSIM_CSLT_ALLOWEMPTYTOKENS   0x0002
+#endif
+#ifndef OSSIM_CSLT_PRESERVEQUOTES
+#  define OSSIM_CSLT_PRESERVEQUOTES     0x0004
+#endif
+#ifndef OSSIM_CSLT_PRESERVEESCAPES
+#  define OSSIM_CSLT_PRESERVEESCAPES    0x0008
+#endif
+
+/************************************************************************/
+/*                           ossimCSLFindString()                            */
+/*                                                                      */
+/*      Find a string within a string list.  The string must match      */
+/*      the full length, but the comparison is case insensitive.        */
+/*      Return -1 on failure.                                           */
+/************************************************************************/
+
+int ossimCSLFindString( char ** papszList, const char * pszTarget )
+
+{
+    int         i;
+
+    if( papszList == NULL )
+        return -1;
+
+    for( i = 0; papszList[i] != NULL; i++ )
+    {
+       ossimString s = papszList[i];
+       if( s == pszTarget)
+            return i;
+    }
+
+    return -1;
+}
+
+/**********************************************************************
+ *                       ossimCSLTokenizeString()
+ *
+ * Tokenizes a string and returns a StringList with one string for
+ * each token.
+ **********************************************************************/
+
+char    **ossimCSLTokenizeString( const char *pszString )
+{
+    return ossimCSLTokenizeString2( pszString, " ", OSSIM_CSLT_HONOURSTRINGS );
+}
+
+/************************************************************************/
+/*                      ossimCSLTokenizeStringComplex()                      */
+/*                                                                      */
+/*      Obsolete tokenizing api.                                        */
+/************************************************************************/
+
+char ** ossimCSLTokenizeStringComplex( const char * pszString,
+                                       const char * pszDelimiters,
+                                       int bHonourStrings,
+                                       int bAllowEmptyTokens )
+
+{
+    int         nFlags = 0;
+
+    if( bHonourStrings )
+        nFlags |= OSSIM_CSLT_HONOURSTRINGS;
+    if( bAllowEmptyTokens )
+        nFlags |= OSSIM_CSLT_ALLOWEMPTYTOKENS;
+
+    return ossimCSLTokenizeString2( pszString, pszDelimiters, nFlags );
+}
+
+/************************************************************************/
+/*                         ossimCSLTokenizeString2()                         */
+/*                                                                      */
+/*      The ultimate tokenizer?                                         */
+/************************************************************************/
+
+char ** ossimCSLTokenizeString2( const char * pszString,
+                                 const char * pszDelimiters,
+                                 int nCSLTFlags )
+
+{
+    char        **papszRetList = NULL;
+    int         nRetMax = 0, nRetLen = 0;
+    char        *pszToken;
+    int         nTokenMax, nTokenLen;
+    int         bHonourStrings = (nCSLTFlags & OSSIM_CSLT_HONOURSTRINGS);
+    int         bAllowEmptyTokens = (nCSLTFlags & OSSIM_CSLT_ALLOWEMPTYTOKENS);
+
+    pszToken = (char *) calloc(10,1);
+    nTokenMax = 10;
+    
+    while( pszString != NULL && *pszString != '\0' )
+    {
+        int     bInString = false;
+
+        nTokenLen = 0;
+        
+        /* Try to find the next delimeter, marking end of token */
+        for( ; *pszString != '\0'; pszString++ )
+        {
+
+            /* End if this is a delimeter skip it and break. */
+            if( !bInString && strchr(pszDelimiters, *pszString) != NULL )
+            {
+                pszString++;
+                break;
+            }
+            
+            /* If this is a quote, and we are honouring constant
+               strings, then process the constant strings, with out delim
+               but don't copy over the quotes */
+            if( bHonourStrings && *pszString == '"' )
+            {
+                if( nCSLTFlags & OSSIM_CSLT_PRESERVEQUOTES )
+                {
+                    pszToken[nTokenLen] = *pszString;
+                    nTokenLen++;
+                }
+
+                if( bInString )
+                {
+                    bInString = false;
+                    continue;
+                }
+                else
+                {
+                    bInString = true;
+                    continue;
+                }
+            }
+
+            /* Within string constants we allow for escaped quotes, but
+               in processing them we will unescape the quotes */
+            if( bInString && pszString[0] == '\\' && pszString[1] == '"' )
+            {
+                if( nCSLTFlags & OSSIM_CSLT_PRESERVEESCAPES )
+                {
+                    pszToken[nTokenLen] = *pszString;
+                    nTokenLen++;
+                }
+
+                pszString++;
+            }
+
+            /* Within string constants a \\ sequence reduces to \ */
+            else if( bInString 
+                     && pszString[0] == '\\' && pszString[1] == '\\' )
+            {
+                if( nCSLTFlags & OSSIM_CSLT_PRESERVEESCAPES )
+                {
+                    pszToken[nTokenLen] = *pszString;
+                    nTokenLen++;
+                }
+                pszString++;
+            }
+
+            if( nTokenLen >= nTokenMax-3 )
+            {
+                nTokenMax = nTokenMax * 2 + 10;
+                pszToken = (char *) ossimCPLRealloc( pszToken, nTokenMax );
+            }
+
+            pszToken[nTokenLen] = *pszString;
+            nTokenLen++;
+        }
+
+        pszToken[nTokenLen] = '\0';
+
+        /*
+         * If the last token is an empty token, then we have to catch
+         * it now, otherwise we won't reenter the loop and it will be lost. 
+         */
+
+        if( (pszToken[0] != '\0' || bAllowEmptyTokens)
+            || (*pszString == '\0' && bAllowEmptyTokens
+                && strchr(pszDelimiters, *(pszString-1)) ) )
+        {
+            if( nRetLen >= nRetMax - 1 )
+            {
+                nRetMax = nRetMax * 2 + 10;
+                papszRetList = (char **) 
+                    ossimCPLRealloc(papszRetList, sizeof(char*) * nRetMax );
+            }
+
+            papszRetList[nRetLen++] = strdup( pszToken );
+            papszRetList[nRetLen] = NULL;
+        }
+    }
+
+    if( papszRetList == NULL )
+        papszRetList = (char **) calloc(sizeof(char *),1);
+
+    free( pszToken );
+
+    return papszRetList;
+}
+
+/**********************************************************************
+ *                       ossimCSLCount()
+ *
+ * Return the number of lines in a Stringlist.
+ **********************************************************************/
+int ossimCSLCount(char **papszStrList)
+{
+    int nItems=0;
+
+    if (papszStrList)
+    {
+        while(*papszStrList != NULL)
+        {
+            nItems++;
+            papszStrList++;
+        }
+    }
+
+    return nItems;
+}
+
+/**********************************************************************
+ *                       ossimCSLDestroy()
+ *
+ * Free all memory used by a StringList.
+ **********************************************************************/
+void ossimCSLDestroy(char **papszStrList)
+{
+    char **papszPtr;
+
+    if (papszStrList)
+    {
+        papszPtr = papszStrList;
+        while(*papszPtr != NULL)
+        {
+            free(*papszPtr);
+            papszPtr++;
+        }
+
+        free(papszStrList);
+    }
+}
+
+void * ossimCPLRealloc( void * pData, size_t nNewSize )
+
+{
+    void        *pReturn;
+
+    if ( nNewSize == 0 )
+    {
+        free(pData);
+        return NULL;
+    }
+
+    if( pData == NULL )
+        pReturn = malloc( nNewSize );
+    else
+        pReturn = realloc( pData, nNewSize );
+
+    return pReturn;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimCplUtil.h b/Utilities/OSSIM/ossim_core/base/common/ossimCplUtil.h
new file mode 100644
index 0000000000..d3e8bc0582
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimCplUtil.h
@@ -0,0 +1,58 @@
+/*
+ * Copied from "gdal" project. See licence below.
+ *
+ * Global functions for gdal code compatibility.
+ *
+ * Project:  ISO 8211 Access
+ * Purpose:  Main declarations for ISO 8211.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam <warmerdam@pobox.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * $Id&
+ */
+
+#ifndef ossimCplUtil_HEADER
+#define ossimCplUtil_HEADER
+
+#include <cstdio> /* to pick up "size_t" */
+#include <base/common/ossimConstants.h> /* for dll export */
+
+
+OSSIMDLLEXPORT char** ossimCSLTokenizeString(const char *pszString );
+
+OSSIMDLLEXPORT char** ossimCSLTokenizeStringComplex(const char *pszString,
+                                                    const char *pszDelimiter,
+                                                    int bHonourStrings,
+                                                    int bAllowEmptyTokens );
+
+OSSIMDLLEXPORT char** ossimCSLTokenizeString2( const char *pszString, 
+                                               const char *pszDelimeter, 
+                                               int nCSLTFlags );
+
+OSSIMDLLEXPORT int ossimCSLCount(char **papszStrList);
+
+OSSIMDLLEXPORT void ossimCSLDestroy(char **papszStrList);
+
+OSSIMDLLEXPORT void* ossimCPLRealloc( void * pData, size_t nNewSize );
+
+#endif /* ossimCplUtil_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimCustomEditorWindow.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimCustomEditorWindow.cpp
new file mode 100644
index 0000000000..476f56d98a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimCustomEditorWindow.cpp
@@ -0,0 +1,26 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimCustomEditorWindow.cpp,v 1.1 2002/04/02 17:18:03 gpotts Exp $
+#include "ossimCustomEditorWindow.h"
+RTTI_DEF1(ossimCustomEditorWindow, "ossimCustomEditorWindow", ossimObject);
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimCustomEditorWindow.h b/Utilities/OSSIM/ossim_core/base/common/ossimCustomEditorWindow.h
new file mode 100644
index 0000000000..717381e3cd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimCustomEditorWindow.h
@@ -0,0 +1,71 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimCustomEditorWindow.h,v 1.7 2002/11/25 18:45:47 gpotts Exp $
+#ifndef ossimCustomEditorWindow_HEADER
+#define ossimCustomEditorWindow_HEADER
+#include "base/common/ossimObject.h"
+
+class OSSIMDLLEXPORT ossimCustomEditorWindow : public ossimObject
+{
+public:
+   /*!
+    * Returns the system dependent window.  If you are in wx it
+    * will probalby be some type of wxWindow*.
+    */
+   virtual void* getWindow()=0;
+
+   /*!
+    * This is the parent window.  If the parent can be
+    * set by the derived classes it will return true.
+    */
+   virtual void  setParent(void* parent)=0;
+   
+   /*!
+    * Will return the parent of the managed wxWindow
+    */
+   virtual void* getParent()=0;
+   
+   /*!
+    * WIll set the object to edit.  If this editor does not know
+    * anything about the passed in obj it will return false.
+    */
+   virtual bool setObjectToEdit(ossimObject* obj)=0;
+
+   /*!
+    * Just asks if I can edit the passed in object.
+    */
+   virtual bool canEdit(ossimObject* obj)const=0;
+
+   /*!
+    * Returns the object we are editing.
+    */
+   virtual ossimObject* getObject()=0;
+
+protected:
+   ossimCustomEditorWindow(){}
+   ossimCustomEditorWindow(const ossimCustomEditorWindow&){}
+   void operator =(const ossimCustomEditorWindow& rhs){}
+
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimDataObject.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimDataObject.cpp
new file mode 100644
index 0000000000..88281b8959
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimDataObject.cpp
@@ -0,0 +1,154 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimDataObject.cpp,v 1.10 2005/04/20 15:10:28 dburken Exp $
+#include "ossimDataObject.h"
+#include "base/common/ossimSource.h"
+#include "base/misc/lookup_tables/ossimScalarTypeLut.h"
+
+RTTI_DEF1(ossimDataObject, "ossimDataObject", ossimObject)
+   
+ossimDataObject::ossimDataObject(ossimSource* source,
+                                 ossimDataObjectStatus status)
+   :
+      theOwner(source),
+      theDataObjectStatus(status)
+{
+}
+
+ossimDataObject::ossimDataObject(const ossimDataObject& rhs)
+   : ossimObject(),
+     theOwner(NULL),
+     theDataObjectStatus(rhs.theDataObjectStatus)
+{
+}
+
+ossimDataObject::~ossimDataObject()
+{
+}
+
+void ossimDataObject::setOwner(ossimSource* aSource)
+{
+   theOwner = aSource;
+}
+
+ossimSource* ossimDataObject::getOwner()
+{
+   return theOwner;
+}
+
+const ossimSource* ossimDataObject::getOwner() const
+{
+   return theOwner;
+}
+
+void ossimDataObject::setDataObjectStatus(ossimDataObjectStatus status) const
+{
+   theDataObjectStatus = status;
+}
+
+ossimDataObjectStatus ossimDataObject::getDataObjectStatus()const
+{
+   return theDataObjectStatus;
+}
+
+ossimString ossimDataObject::getDataObjectStatusString() const
+{
+   ossimString s;
+   
+   switch (theDataObjectStatus)
+   {
+      case OSSIM_NULL:
+         s = "OSSIM_NULL";
+         break;
+
+      case OSSIM_EMPTY:
+         s = "OSSIM_EMPTY";
+         break;
+
+      case OSSIM_PARTIAL:
+         s = "OSSIM_PARTIAL";
+         break;
+
+      case OSSIM_FULL:
+         s = "OSSIM_FULL";
+         break;
+         
+      case OSSIM_STATUS_UNKNOWN:
+      default:
+         s = "OSSIM_STATUS_UNKNOWN";
+         break;
+   }
+   
+   return s;
+}
+
+ossim_uint32 ossimDataObject::getObjectSizeInBytes()const
+{
+   return sizeof(theOwner);
+}
+
+bool ossimDataObject::isInitialize()const
+{
+   return (getDataObjectStatus()!=OSSIM_NULL);
+}
+
+bool ossimDataObject::operator!=(const ossimDataObject& rhs) const
+{
+   return ( theOwner               != rhs.theOwner ||
+            theDataObjectStatus    != rhs.theDataObjectStatus );
+}
+
+bool ossimDataObject::operator==(const ossimDataObject& rhs) const
+{
+   return (theOwner            == rhs.theOwner &&
+           theDataObjectStatus == rhs.theDataObjectStatus);
+}
+
+void ossimDataObject::assign(const ossimDataObject* rhs)
+{
+   if(rhs != this)
+   {
+      theOwner               = rhs->theOwner;
+      theDataObjectStatus     = rhs->theDataObjectStatus;
+   }
+}
+
+const ossimDataObject* ossimDataObject::operator=(const ossimDataObject* rhs)
+{
+   assign(rhs);
+   return this;
+}
+
+const ossimDataObject& ossimDataObject::operator=(const ossimDataObject& rhs)
+{
+   assign(&rhs);
+   return *this;
+}
+
+std::ostream& ossimDataObject::print(ostream& out) const
+{
+   out << "ossimDataObject::print:";
+   
+   if (theOwner)
+   {
+      out << "\ntheOwner->getClassName():  "
+          << theOwner->getClassName()<<endl;
+   }
+   else
+   {
+      out << "\ntheOwner is null"
+          <<endl;
+   }
+   out << "theDataObjectStatus: " << getDataObjectStatusString()
+       << endl;
+
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimDataObject.h b/Utilities/OSSIM/ossim_core/base/common/ossimDataObject.h
new file mode 100644
index 0000000000..d2e2f3cac6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimDataObject.h
@@ -0,0 +1,126 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimDataObject.h,v 1.19 2005/04/20 15:10:28 dburken Exp $
+
+#ifndef ossimDataObject_HEADER
+#define ossimDataObject_HEADER
+
+#include "ossimObject.h"
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimDpt3d.h"
+
+class OSSIMDLLEXPORT ossimSource;
+
+class OSSIMDLLEXPORT ossimDataObject : public ossimObject
+{
+public:
+   ossimDataObject(ossimSource* source=0,
+                   ossimDataObjectStatus status=OSSIM_STATUS_UNKNOWN);
+   
+   ossimDataObject(const ossimDataObject& rhs);
+
+   virtual ~ossimDataObject();
+
+
+   virtual ossim_uint32 getHashId()const=0;
+   
+   /**
+    * Sets the owner of this Data object.
+    */
+   virtual void setOwner(ossimSource* aSource);
+
+   virtual ossimSource* getOwner();
+
+   virtual const ossimSource* getOwner() const;
+
+   /**
+    * Full list found in ossimConstants.h
+    *
+    * OSSIM_STATUS_UNKNOWN
+    * OSSIM_NULL            Null data.  The buffers are never allocated
+    * OSSIM_EMPTY           Allocated data but its empty.  Most of the
+    *                       time this will be the default for an initialized
+    *                       data object.
+    * OSSIM_PARTIAL         Says that some of the object is empty and is only
+    *                       partially full
+    * OSSIM_FULL            This data is completey full
+    */
+   virtual void  setDataObjectStatus(ossimDataObjectStatus status) const;
+
+   /**
+    * @return Returns enumerated status:
+    * OSSIM_STATUS_UNKNOWN = 0
+    * OSSIM_NULL           = 1
+    * OSSIM_EMPTY          = 2
+    * OSSIM_PARTIAL        = 3
+    * OSSIM_FULL           = 4
+    */
+   virtual ossimDataObjectStatus getDataObjectStatus() const;
+
+   /**
+    * @return Returns the status as a string, like "OSSIM_NULL".
+    */
+   virtual ossimString getDataObjectStatusString() const;
+
+   virtual ossim_uint32 getObjectSizeInBytes()const;
+
+   virtual ossim_uint32 getDataSizeInBytes()const=0;
+
+   /**
+    * This is to be overriden in the derived classes so they can check
+    * If their data is null.
+    */
+   virtual bool isInitialize() const;
+
+   /**
+    * Will allow derived classes to initialize their buffers.  This class
+    * does nothing with this and reset any internal attributes.
+    */
+   virtual void initialize()=0;
+   
+   virtual void assign(const ossimDataObject* rhs);
+
+   /**
+    * Derived classes should implement this method.  For data objects
+    * there is usually 2 types of tests a shallow and a deep test.  If
+    * deepTest is false then a shallow test is performed.  I shallow test
+    * just doesn't compare the data but instead compares the fields that
+    * describes the data. For example if it were an ossimImageData then a
+    * shallow compare will just compare the origin, scale, width, height,
+    * number of bands, min, max, null, and scalar type.  If
+    * it were a deep compare it will also test the actual data to one another.
+    */
+   virtual bool isEqualTo(const ossimDataObject& rhs,
+                          bool deepTest=false)const=0;
+   
+   virtual const ossimDataObject* operator =(const ossimDataObject* rhs);
+   
+   virtual const ossimDataObject& operator=(const ossimDataObject& rhs);
+
+   virtual bool operator==(const ossimDataObject& rhs) const;
+   virtual bool operator!=(const ossimDataObject& rhs) const;
+
+   virtual std::ostream& print(std::ostream& out) const;
+
+protected:
+
+   //***
+   // Note:  This object is not responsible for deletion of the ossimSource*
+   //        "theSource".  It is simply a hook to his owner for things
+   //        like unregister and so forth...
+   //***
+   ossimSource*                      theOwner;
+   mutable ossimDataObjectStatus     theDataObjectStatus;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimDate.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimDate.cpp
new file mode 100644
index 0000000000..445263b11c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimDate.cpp
@@ -0,0 +1,536 @@
+#include <base/common/ossimDate.h>
+#include <iomanip>
+#include <sstream>
+
+
+std::ostream& operator<< (std::ostream& out, const ossimDate& src)
+{
+   return src.print(out);
+}
+
+std::ostream& operator<< (std::ostream & os, ossimLocalTm const & t)
+{
+   return t.print(os);
+}
+
+int operator== (ossimLocalTm const & t1, ossimLocalTm const & t2)
+{
+   return int(t1.compare(t2) == 0);
+}
+
+int operator!= (ossimLocalTm const & t1, ossimLocalTm const & t2)
+{
+   return int(t1.compare(t2) != 0);
+}
+
+int operator<  (ossimLocalTm const & t1, ossimLocalTm const & t2)
+{
+   return int(t1.compare(t2) < 0);
+}
+
+int operator<= (ossimLocalTm const & t1, ossimLocalTm const & t2)
+{
+   return int(t1.compare(t2) <= 0);
+}
+
+int operator>  (ossimLocalTm const & t1, ossimLocalTm const & t2)
+{
+   return int(t1.compare(t2) > 0);
+}
+
+int operator>=  (ossimLocalTm const & t1, ossimLocalTm const & t2)
+{
+   return int(t1.compare(t2) >= 0);
+}
+
+char ossimLocalTm::timech = ':';
+char ossimLocalTm::datech = '/';
+
+int ossimLocalTm::datefmt = ossimLocalTm::ossimLocalTmFormatIntlShort;
+int ossimLocalTm::timefmt = ossimLocalTm::ossimTimeFormatInternational;
+
+
+ossimLocalTm::ossimLocalTm (time_t t)
+{
+    if (t == 0)
+        t = time(0);
+    *(tm *)this = *localtime(&t);
+}
+
+ossimLocalTm::ossimLocalTm (tm const & t)
+{
+    *((tm *)this) = t;
+}
+
+ossimLocalTm& ossimLocalTm::operator= (tm const & t)
+{
+    *((tm *)this) = t;
+    return *this;
+}
+
+int ossimLocalTm::compare (ossimLocalTm const & t) const
+{
+    return compare ((time_t)t);
+}
+
+int ossimLocalTm::compare (time_t const tt) const
+{
+    time_t tx = (time_t)*this;
+    return (tx == tt) ? 0 : (tx > tt) ? 1 : -1;
+}
+
+ossimLocalTm::operator time_t (void) const
+{
+    return mktime ((tm *)this);
+}
+
+int ossimLocalTm::isValid (void) const
+{
+    static int maxd[] =
+    {
+        31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+    };
+
+    return (tm_year > 0 &&
+            tm_mon >= 0 && tm_mon < 12 &&
+            tm_mday > 0 && tm_mday <= maxd[tm_mon] &&
+            tm_wday < 7 && tm_yday < 367 &&
+            tm_sec < 60 && tm_min < 60 && tm_hour < 24);
+}
+
+void ossimLocalTm::dSfx (std::ostream & os, int fmt) const
+{
+    if (fmt & ossimLocalTmFormatSepChar)
+        os << datech;
+    if (fmt & ossimLocalTmFormatSepSpace)
+        os << ' ';
+}
+
+void ossimLocalTm::pYear (std::ostream & os, int fmt) const
+{
+    if (fmt & ossimLocalTmFormatYear)
+    {
+        int year = tm_year;
+        int dig;
+        if (fmt & ossimLocalTmFormatYearShort)
+        {
+            dig = 2;
+            year %= 100;
+        }
+        else
+        {
+            dig = 4;
+            if (year < 200)
+                year += 1900;
+        }
+        os << std::setw((fmt & ossimLocalTmFormatPadYear) ? dig : 0);
+        os << std::setfill((fmt & ossimLocalTmFormatZeroYear) ? '0' : ' ');
+        os << year;
+        if ((fmt & ossimLocalTmFormatYearFirst))
+        {
+            fmt &= (ossimLocalTmFormatSepChar|ossimLocalTmFormatSepSpace);
+            dSfx (os, fmt);
+        }
+    }
+}
+
+void ossimLocalTm::pMonth (std::ostream & os, int fmt) const
+{
+
+    static const char * _months[] =
+    {
+        "January", "February", "March", "April",
+        "May", "June", "July", "August", "September",
+        "October", "November", "December"
+    };
+
+    if (fmt & ossimLocalTmFormatMonth)
+    {
+        int mon = (tm_mon % 12);
+        if (fmt & ossimLocalTmFormatMonText)
+        {
+            char const * tmon = _months[mon];
+            if (!(fmt & ossimLocalTmFormatPadMon))
+                os << tmon;
+            else
+                for (int x = 0; x < 3; ++x)
+                    os << tmon[x];
+        }
+        else
+        {
+            ++mon;
+            os << std::setw((fmt & ossimLocalTmFormatPadMon) ? 2 : 0);
+            os << std::setfill((fmt & ossimLocalTmFormatZeroMon) ? '0' : ' ');
+            os << mon;
+        }
+        if (((fmt & ossimLocalTmFormatYear) && !(fmt & ossimLocalTmFormatYearFirst)) ||
+            ((fmt & ossimLocalTmFormatDay) && (fmt & ossimLocalTmFormatMonFirst)))
+        {
+            fmt &= (ossimLocalTmFormatSepChar|ossimLocalTmFormatSepSpace);
+            dSfx (os, fmt);
+        }
+    }
+}
+
+
+void ossimLocalTm::pDate (std::ostream & os, int fmt) const
+{
+    if (fmt & ossimLocalTmFormatDay)
+    {
+        int day = tm_mday;
+        os << std::setw((fmt & ossimLocalTmFormatPadDay) ? 2 : 0);
+        os << std::setfill((fmt & ossimLocalTmFormatZeroDay) ? '0' : ' ');
+        os << day;
+        if (!(fmt & ossimLocalTmFormatYearFirst) || !(fmt & ossimLocalTmFormatMonFirst))
+        {
+            fmt &= (ossimLocalTmFormatSepChar|ossimLocalTmFormatSepSpace);
+            dSfx (os, fmt);
+        }
+    }
+}
+
+std::ostream& ossimLocalTm::print(std::ostream & os,
+                                    int df,
+                                    int tf) const
+{
+    std::ostringstream pTmp;
+    printDate (pTmp, df);
+    pTmp << ' ';
+    printTime (pTmp, tf);
+
+    return os << pTmp.str();
+}
+
+std::ostream& ossimLocalTm::printDate (std::ostream & os, int fmt) const
+{
+    std::ostringstream pTmp;
+
+    static const char * _days[] =
+    {
+        "Sunday", "Monday", "Tuesday", "Wednesday",
+        "Thursday", "Friday", "Saturday"
+    };
+
+    if (fmt & ossimLocalTmFormatDayOfWeek)
+    {
+        int day = tm_wday % 7;
+        char const * p = _days[day];
+        if (fmt & ossimLocalTmFormatPadDay)
+            for (int x = 0; x < 3; ++x)
+                pTmp << p[x];
+        else
+        {
+            pTmp << p;
+            if (fmt & ossimLocalTmFormatDMY)
+                pTmp << ',';
+        }
+        if ((fmt & ossimLocalTmFormatDMY) && fmt & ossimLocalTmFormatSepSpace)
+            pTmp << ' ';
+    }
+    if (fmt & ossimLocalTmFormatYearFirst)
+        pYear (pTmp, fmt);
+    if (fmt & ossimLocalTmFormatMonFirst)
+        pMonth (pTmp, fmt);
+    pDate (pTmp, fmt);
+    if (!(fmt & ossimLocalTmFormatMonFirst))
+        pMonth (pTmp, fmt);
+    if (!(fmt & ossimLocalTmFormatYearFirst))
+        pYear (pTmp, fmt);
+
+    return os << pTmp.str();
+}
+void ossimLocalTm::tSfx (std::ostream & os, int fmt, char ch) const
+{
+    if (fmt & ossimTimeFormatSepAbbrev)
+        os << ch;
+    if (fmt & ossimTimeFormatSepChar)
+        os << timech;
+    if (fmt & ossimTimeFormatSepSpace)
+        os << ' ';
+}
+
+void ossimLocalTm::pHour (std::ostream & os, int fmt) const
+{
+    if (fmt & ossimTimeFormatHour)
+    {
+        int hour = tm_hour;
+        if (!(fmt & ossimTimeFormat24hour))
+        {
+            if (hour > 12)
+                hour -= 12;
+            else if (!hour && (fmt & ossimTimeFormatAmPm))
+                hour += 12;
+        }
+        os << std::setw((fmt & ossimTimeFormatPadHour) ? 2 : 0);
+        os << std::setfill((fmt & ossimTimeFormatZeroHour) ? '0' : ' ');
+        os << hour;
+        if (!(fmt & ossimTimeFormatMins))
+            fmt &= ossimTimeFormatSepAbbrev;
+        tSfx (os, fmt, 'h');
+    }
+}
+
+void ossimLocalTm::pMins (std::ostream & os, int fmt) const
+{
+    if (fmt & ossimTimeFormatMins)
+    {
+        int min = tm_min;
+        int dig = 2;
+        if (!(fmt & ossimTimeFormatHour))
+        {
+            min += (tm_hour * 60);
+            dig += 2;
+        }
+        os << std::setw((fmt & ossimTimeFormatPadMins) ? dig : 0);
+        os << std::setfill((fmt & ossimTimeFormatZeroMins) ? '0' : ' ');
+        os << min;
+        if (!(fmt & ossimTimeFormatSecs))
+            fmt &= ossimTimeFormatSepAbbrev;
+        tSfx (os, fmt, 'm');
+    }
+}
+
+void ossimLocalTm::pSecs (std::ostream & os, int fmt) const
+{
+    if (fmt & ossimTimeFormatSecs)
+    {
+        int sec = tm_sec;
+        int dig = 2;
+        if (!(fmt & (ossimTimeFormatHour|ossimTimeFormatMins)))
+        {
+            sec += ((tm_hour * 60) + tm_min) + 60;
+            dig += 3;
+        }
+        os << std::setw((fmt & ossimTimeFormatPadSecs) ? dig : 0);
+        os << std::setfill((fmt & ossimTimeFormatZeroSecs) ? '0' : ' ');
+        os << sec;
+        if (fmt & ossimTimeFormatAmPm)
+            fmt &= ~ossimTimeFormatSepChar;
+        else
+            fmt &= (ossimTimeFormatSepAbbrev|ossimTimeFormatSepSpace);
+        tSfx (os, fmt, 's');
+    }
+}
+
+std::ostream &ossimLocalTm::printTime (std::ostream & os, int fmt) const
+{
+    std::ostringstream pTmp;
+    pHour (pTmp, fmt);
+    pMins (pTmp, fmt);
+    pSecs (pTmp, fmt);
+    if (fmt & ossimTimeFormatAmPm)
+    {
+        pTmp << (tm_hour > 11 ? "pm" : "am");
+    }
+
+    return os << pTmp.str();
+}
+
+
+int ossimLocalTm::getYear()const
+{
+   int result = tm_year;
+   if (result < 200)
+   {
+      result += 1900;
+   }
+   return result;
+}
+
+int ossimLocalTm::getShortYear()const
+{
+   return (getYear()%100);
+}
+
+int ossimLocalTm::getMonth()const
+{
+   return ((tm_mon % 12)+1); 
+}
+
+int ossimLocalTm::getDay()const
+{
+   return tm_mday;
+}
+
+double ossimLocalTm::getJulian()const
+{
+   int J = getMonth();
+   int K = getDay();
+   int I = getYear();
+
+   return K-32075+1461*(I+4800+(J-14)/12)/4+367*(J-2-(J-14)/12*12)
+      /12-3*((I+4900+(J-14)/12)/100)/4+
+       (getHour()/24.0)+
+       (getMin()/1440.0)+
+       (getSec()/86400.0);
+}
+
+double ossimLocalTm::getModifiedJulian()const
+{
+   return getJulian() - 2400000.5;
+}
+
+ossimLocalTm& ossimLocalTm::setDay(int day)
+{
+   tm_mday = day;
+   
+   return *this;
+}
+
+ossimLocalTm& ossimLocalTm::setMonth(int month)
+{
+   tm_mon = month - 1;
+
+   return *this;
+}
+
+ossimLocalTm& ossimLocalTm::setYear(int year)
+{
+   if(year < 2099)
+   {
+      tm_year = year - 1900;
+   }
+   else
+   {
+      tm_year = year;
+   }
+
+   return *this;
+}
+
+ossimLocalTm& ossimLocalTm::setDateFromJulian(double jd)
+{
+   double fractional = jd - (long)jd;
+   long l;
+   long n;
+   long i;
+   long j;
+   long k;
+
+
+   l= (long)(jd+68569);
+   n= 4*l/146097;
+   l= l-(146097*n+3)/4;
+   i= 4000*(l+1)/1461001;
+   l= l-1461*i/4+31l;
+   j= 80*l/2447;
+   k= l-2447*j/80;
+   l= j/11;
+   j= j+2-12*l;
+   i= 100*(n-49)+i+l;
+   setDay(k);
+   setMonth(j);
+   setYear(i);
+
+   setFractionalDay(fractional);
+   
+   return *this;
+}
+
+ossimLocalTm& ossimLocalTm::setDateFromModifiedJulian(double mjd)
+{
+   setDateFromJulian(mjd + 2400000.5);
+
+   return *this;
+}
+
+void ossimLocalTm::setFractionalDay(double fractionalDay)
+{
+   int h, m, s;
+   extractHmsFromFractionalDay(fractionalDay, h, m, s);
+
+   setHour(h);
+   setMin(m);
+   setSec(s);
+}
+
+void ossimLocalTm::extractHmsFromFractionalDay(double fractionalDay,
+                                               int &h,
+                                               int &m,
+                                               int &s)
+{
+   fractionalDay *=24;
+   h = (int)fractionalDay;
+   fractionalDay = fractionalDay-h;
+   fractionalDay*=60;
+   m = (int)fractionalDay;
+   fractionalDay = fractionalDay-m;
+   fractionalDay*=60;
+   s = (int)fractionalDay;
+}
+
+int ossimLocalTm::getHour()const
+{
+   return tm_hour;
+}
+
+int ossimLocalTm::getMin()const
+{
+   return tm_min;
+}
+
+int ossimLocalTm::getSec()const
+{
+   return tm_sec;
+}
+
+ossimLocalTm& ossimLocalTm::setHour(int h)
+{
+   tm_hour = h;
+
+   return *this;
+}
+
+ossimLocalTm& ossimLocalTm::setMin(int m)
+{
+   tm_min = m;
+
+   return *this;
+}
+
+ossimLocalTm& ossimLocalTm::setSec(int s)
+{
+   tm_sec = s;
+
+   return *this;
+}
+
+std::ostream& ossimDate::print (std::ostream & os) const
+{
+   return printDate (os, _fmt);
+}
+
+
+std::ostream& operator <<(std::ostream& out, const ossimTime& src)
+{
+   return src.print(out);
+}
+ossimTime::ossimTime(int tmfmt)
+      : ossimLocalTm(0), _fmt(tmfmt)
+{
+}
+ossimTime::ossimTime(ossimTime const & t,
+                      int tmfmt)
+      : ossimLocalTm (t), _fmt(tmfmt)
+{
+}
+
+ossimTime::ossimTime(time_t t, int tmfmt)
+      : ossimLocalTm (t), _fmt(tmfmt)
+{
+}
+      
+int ossimTime::fmt(int f)
+{
+   return _fmt = f;
+}
+
+int ossimTime::fmt(void) const
+{
+   return _fmt;
+}
+
+std::ostream& ossimTime::print (std::ostream & os) const
+{
+   return printTime(os, _fmt);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimDate.h b/Utilities/OSSIM/ossim_core/base/common/ossimDate.h
new file mode 100644
index 0000000000..63f283dd9d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimDate.h
@@ -0,0 +1,241 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimDate.h,v 1.12 2005/07/13 12:31:06 gpotts Exp $
+#ifndef ossimDate_HEADER
+#define ossimDate_HEADER
+#include <iostream>
+#include <ctime>
+#include <base/common/ossimConstants.h>
+
+class OSSIMDLLEXPORT ossimLocalTm : public std::tm
+{
+public:
+   friend  std::ostream& operator<< (std::ostream& out, const ossimLocalTm& src);
+   friend int operator== (const ossimLocalTm& t1, const ossimLocalTm& src);
+   friend int operator!= (const ossimLocalTm& t1, const ossimLocalTm& src);
+   friend int operator<  (const ossimLocalTm& t1, const ossimLocalTm& src);
+   friend int operator<= (const ossimLocalTm& t1, const ossimLocalTm& src);
+   friend int operator>  (const ossimLocalTm& t1, const ossimLocalTm& src);
+   friend int operator>=  (const ossimLocalTm& t1, const ossimLocalTm& src);
+
+   ossimLocalTm (time_t t=0);     // Set to time, 0 is magic for 'now'
+   ossimLocalTm (tm const & t); // Copy constructor
+   
+   ossimLocalTm & operator= (tm const & t);            // Assignment
+   operator time_t (void) const;        // Conversion operator
+   
+   int isValid (void) const;             // Test for validity
+   
+   int compare (ossimLocalTm const & t) const;      // Compare times
+   int compare (std::time_t const tt) const;       // Compare times
+   
+   enum ossimLocalTmFormat     // Date format flags
+   {
+      ossimLocalTmFormatYear          = (int)0x0001,            // Print year
+      ossimLocalTmFormatYearShort     = (int)0x0002, // Print last two digits
+      ossimLocalTmFormatPadYear       = (int)0x0004,    // Pad year to 2 or 4
+      ossimLocalTmFormatZeroYear      = (int)0x0008,        // Zero fill year
+      ossimLocalTmFormatMonth         = (int)0x0010,           // Print month
+      ossimLocalTmFormatMonText       = (int)0x0020,   // Print month in text
+      ossimLocalTmFormatPadMon        = (int)0x0040, // Pad to 2 (trunc to 3)
+      ossimLocalTmFormatZeroMon       = (int)0x0080,       // Zero fill month
+      ossimLocalTmFormatDay           = (int)0x0100,            // Print date
+      ossimLocalTmFormatDayOfWeek     = (int)0x0200,     // Print day of week
+      ossimLocalTmFormatPadDay        = (int)0x0400,         // Pad date to 2
+      ossimLocalTmFormatZeroDay       = (int)0x0800,         // Zero fill day
+      ossimLocalTmFormatDMY           = (int)0x0111, // Print date, mth, year
+      ossimLocalTmFormatPadDMY        = (int)0x0444,         // Pad all three
+      ossimLocalTmFormatZeroDMY       = (int)0x0888,   // Zero fill all three
+      ossimLocalTmFormatYearFirst     = (int)0x1000,      // Print year first
+      ossimLocalTmFormatMonFirst      = (int)0x2000,     // Print month first
+      ossimLocalTmFormatSepChar       = (int)0x4000,// Separate fields datech
+      ossimLocalTmFormatSepSpace      = (int)0x8000,  // Separate fields space
+      ossimLocalTmFormatInternational = (int)(ossimLocalTmFormatDMY|ossimLocalTmFormatMonText|ossimLocalTmFormatPadMon|
+                                                ossimLocalTmFormatSepSpace),
+      ossimLocalTmFormatIntlShort     = (int)(ossimLocalTmFormatDMY|ossimLocalTmFormatMonText|ossimLocalTmFormatPadMon|
+                                                ossimLocalTmFormatSepSpace|ossimLocalTmFormatYearShort),
+      ossimLocalTmFormatUsa           = (int)(ossimLocalTmFormatDMY|ossimLocalTmFormatMonFirst|ossimLocalTmFormatPadDMY|
+                                                ossimLocalTmFormatZeroDMY|ossimLocalTmFormatYearShort|ossimLocalTmFormatSepChar),
+      ossimLocalTmFormatEnglish       = (int)(ossimLocalTmFormatDMY|ossimLocalTmFormatYearShort|ossimLocalTmFormatPadDMY|
+                                                ossimLocalTmFormatZeroDMY|ossimLocalTmFormatSepChar),
+      ossimLocalTmFormatJapanese      = (int)(ossimLocalTmFormatDMY|ossimLocalTmFormatYearFirst|ossimLocalTmFormatPadDMY|
+                                                ossimLocalTmFormatZeroDMY|ossimLocalTmFormatYearShort|ossimLocalTmFormatMonFirst|
+                                                ossimLocalTmFormatSepChar),
+      ossimLocalTmFormatFull          = (int)(ossimLocalTmFormatDMY|ossimLocalTmFormatDayOfWeek|ossimLocalTmFormatMonText|
+                                                ossimLocalTmFormatSepSpace)
+   };
+   
+   enum ossimTimeFormat  // Time format (nb: time zones not implemented)
+      {
+         ossimTimeFormatSecs          = (int)0x0001,         // Print seconds
+         ossimTimeFormatZeroSecs      = (int)0x0002,     // Zero fill seconds
+         ossimTimeFormatPadSecs       = (int)0x0004,      // Pad seconds to 2
+         ossimTimeFormatSecsAll       = (int)0x0007,
+         ossimTimeFormatTimeZone      = (int)0x0008,        // Print timezone
+         ossimTimeFormatMins          = (int)0x0010,         // Print minutes
+         ossimTimeFormatZeroMins      = (int)0x0020,     // Zero fill minutes
+         ossimTimeFormatPadMins       = (int)0x0040,      // Pad minutes to 2
+         ossimTimeFormatMinsAll       = (int)0x0070,
+         ossimTimeFormatTZNumeric     = (int)0x0080,      // Print numeric TZ
+         ossimTimeFormatHour          = (int)0x0100,            // Print hour
+         ossimTimeFormatZeroHour      = (int)0x0200,        // Zero fill hour
+         ossimTimeFormatPadHour       = (int)0x0400,  // Pad hour to 2 digits
+         ossimTimeFormatHourAll       = (int)0x0700,
+         ossimTimeFormat24hour        = (int)0x0800,          // 24hour clock
+         ossimTimeFormatSepChar       = (int)0x1000, // Separate field timech
+         ossimTimeFormatSepSpace      = (int)0x2000, // Separate fields space
+         ossimTimeFormatSepAbbrev     = (int)0x4000,     // Add abbreviations
+         ossimTimeFormatAmPm          = (int)0x8000,       // Add 'am' or 'pm'
+         ossimTimeFormatInternational = (int)(ossimTimeFormatHourAll|ossimTimeFormatMinsAll|ossimTimeFormatSecsAll|
+                                              ossimTimeFormat24hour|ossimTimeFormatSepChar),
+         ossimTimeFormatShortTime     = (int)(ossimTimeFormatHourAll|ossimTimeFormatMinsAll|ossimTimeFormat24hour|
+                                              ossimTimeFormatSepChar),
+         ossimTimeFormatClockTime     = (int)(ossimTimeFormatHour|ossimTimeFormatPadHour|ossimTimeFormatMinsAll|
+                                              ossimTimeFormatAmPm|ossimTimeFormatSepChar),
+         ossimTimeFormatLongTime      = (int)(ossimTimeFormatHour|ossimTimeFormatPadHour|ossimTimeFormatMinsAll|
+                                              ossimTimeFormatSecsAll|ossimTimeFormatSepAbbrev|ossimTimeFormatSepSpace),
+         ossimTimeFormatMillitary     = (int)(ossimTimeFormatHourAll|ossimTimeFormatMinsAll|ossimTimeFormat24hour)
+      };
+   
+   
+   static char timech;    // Character used for time separator
+   static char datech;    // Character used for date separator
+   static int datefmt;                  // Default date format
+   static int timefmt;                  // Default time format
+   
+   // Output methods
+   std::ostream& print(std::ostream & os,
+                       int df =datefmt,
+                       int tf =timefmt) const;
+   std::ostream& printTime(std::ostream & os, int f =timefmt) const;
+   std::ostream& printDate(std::ostream & os, int f =datefmt) const;
+
+
+    int getYear()const;
+
+    int getShortYear()const;
+    
+    /*!
+     * This is one based i.e. values are returned between 1-12
+     */
+    int getMonth()const;
+    
+    /*!
+     * returns the day 1-31
+     */
+    int getDay()const;
+    double getJulian()const;
+    double getModifiedJulian()const;
+
+    ossimLocalTm& setDay(int day);
+   /*!
+    * The month is a number bewteen 1 and 12.  We will shift it to the internal
+    * representation
+    */
+    ossimLocalTm& setMonth(int month);
+    ossimLocalTm& setYear(int year);
+    ossimLocalTm& setDateFromJulian(double jd);
+    ossimLocalTm& setDateFromModifiedJulian(double mjd);
+
+    void setFractionalDay(double fractionalDay);
+    static void extractHmsFromFractionalDay(double fractionalDay,
+                                            int &h,
+                                            int &m,
+                                            int &s);
+    int getHour()const;
+    int getMin()const;
+    int getSec()const;
+    ossimLocalTm& setHour(int h);
+    ossimLocalTm& setMin(int m);
+    ossimLocalTm& setSec(int s);
+    
+
+    
+ protected:
+   // Time suffix
+   void tSfx(std::ostream & os, int fmt, char ch) const;
+   // Time field formatters
+   void pHour(std::ostream & os, int fmt) const;
+   void pMins(std::ostream & os, int fmt) const;
+   void pSecs(std::ostream & os, int fmt) const;
+   // Date suffix
+   void dSfx(std::ostream & os, int fmt) const;
+   // Date field formatters
+   void pDate(std::ostream & os, int fmt) const;
+   void pMonth(std::ostream & os, int fmt) const;
+   void pYear(std::ostream & os, int fmt) const;
+   
+};
+
+
+class OSSIMDLLEXPORT ossimDate : public ossimLocalTm
+{
+  public:
+   friend std::ostream& operator<<(std::ostream& out, const ossimDate& src);
+
+   ossimDate(int datefmt =ossimLocalTm::datefmt)
+      :ossimLocalTm(0), _fmt(datefmt)
+      {}
+   ossimDate (ossimLocalTm const & t,
+              int dtfmt =ossimLocalTm::datefmt)
+      : ossimLocalTm (t), _fmt(dtfmt)
+      {}
+    ossimDate (time_t t, int dtfmt =ossimLocalTm::datefmt)
+        : ossimLocalTm (t), _fmt(dtfmt)
+       {}
+   ossimDate(int month, int day, int year,int dtfmt=ossimLocalTm::datefmt)
+         :ossimLocalTm (0), _fmt(dtfmt)
+      {
+         setMonth(month);
+         setDay(day);
+         setYear(year);
+      }
+    int fmt(int f)                 {   return _fmt = f;    }
+    int fmt(void) const            {   return _fmt;        }
+
+    std::ostream & print (std::ostream & os) const;
+   
+   
+  private:
+
+    int _fmt;
+
+};
+
+class OSSIMDLLEXPORT ossimTime :public ossimLocalTm
+{
+ public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimTime& src);
+   ossimTime(int tmfmt =ossimLocalTm::timefmt);
+   ossimTime (ossimTime const & t,
+              int tmfmt =ossimLocalTm::timefmt);
+   ossimTime (time_t t, int tmfmt =ossimLocalTm::timefmt);
+   
+   int fmt (int f);
+   int fmt (void) const;
+   
+   std::ostream& print (std::ostream & os) const;
+   
+private:
+      int _fmt;   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimDisplayInterface.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimDisplayInterface.cpp
new file mode 100644
index 0000000000..428e8e6292
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimDisplayInterface.cpp
@@ -0,0 +1,31 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimDisplayInterface.cpp,v 1.2 2005/07/15 19:04:28 dburken Exp $
+#include <base/common/ossimDisplayInterface.h>
+
+RTTI_DEF(ossimDisplayInterface, "ossimDisplayInterface");
+
+ossimDisplayInterface::ossimDisplayInterface()
+{
+}
+
+ossimDisplayInterface::~ossimDisplayInterface()
+{
+}
+
+ossimString ossimDisplayInterface::getTitle()const
+{
+   ossimString result;
+   
+   getTitle(result);
+   
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimDisplayInterface.h b/Utilities/OSSIM/ossim_core/base/common/ossimDisplayInterface.h
new file mode 100644
index 0000000000..4933cdb168
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimDisplayInterface.h
@@ -0,0 +1,40 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimDisplayInterface.h,v 1.3 2005/07/15 19:04:28 dburken Exp $
+#ifndef ossimDisplayInterface_HEADER
+#define ossimDisplayInterface_HEADER
+#include <base/common/ossimRtti.h>
+#include <base/data_types/ossimString.h>
+
+class OSSIMDLLEXPORT ossimDisplayInterface
+{
+public:
+   ossimDisplayInterface();
+
+   virtual ~ossimDisplayInterface();
+
+   /*!
+    * Returns the display back to the caller
+    */
+   virtual void* getDisplayDevice()=0;
+
+   virtual void setTitle(const ossimString& title)=0;
+   virtual void getTitle(ossimString& title)const=0;
+   virtual ossimString getTitle()const;
+   virtual void close()=0;
+   virtual bool isOpen() const=0;
+   virtual bool open()=0;
+   virtual bool isMinimized()const=0;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimErrorCodes.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimErrorCodes.cpp
new file mode 100644
index 0000000000..1c5484d5f7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimErrorCodes.cpp
@@ -0,0 +1,318 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken  (dburken@imagelinks.com)
+//
+// Description:
+// 
+// Contains class definition with common error codes and methods to go
+// from code to string and string to code.
+//
+//*************************************************************************
+// $Id: ossimErrorCodes.cpp,v 1.6 2004/05/17 13:57:23 dburken Exp $
+
+#include "ossimErrorCodes.h"
+#include "base/data_types/ossimString.h"
+
+const ossimErrorCode ossimErrorCodes::OSSIM_OK                   = 0;
+const ossimErrorCode ossimErrorCodes::OSSIM_NO_ERROR             = 0;
+const ossimErrorCode ossimErrorCodes::OSSIM_WARNING              = -1;
+const ossimErrorCode ossimErrorCodes::OSSIM_ERROR                = 1;
+const ossimErrorCode ossimErrorCodes::OSSIM_ERROR_STD_PARALLEL_1 = 2; 
+const ossimErrorCode ossimErrorCodes::OSSIM_LAT_ERROR            = 3;
+const ossimErrorCode ossimErrorCodes::OSSIM_LON_ERROR            = 4;
+const ossimErrorCode ossimErrorCodes::OSSIM_NORTHING_ERROR       = 5;
+const ossimErrorCode ossimErrorCodes::OSSIM_ORIGIN_LAT_ERROR     = 6;
+const ossimErrorCode ossimErrorCodes::OSSIM_CENT_MER_ERROR       = 7;
+const ossimErrorCode ossimErrorCodes::OSSIM_A_ERROR              = 8;
+const ossimErrorCode ossimErrorCodes::OSSIM_B_ERROR              = 9;
+const ossimErrorCode ossimErrorCodes::OSSIM_A_LESS_B_ERROR       = 10;
+const ossimErrorCode ossimErrorCodes::OSSIM_FIRST_STDP_ERROR     = 11;
+const ossimErrorCode ossimErrorCodes::OSSIM_SEC_STDP_ERROR       = 12;
+const ossimErrorCode ossimErrorCodes::OSSIM_FIRST_SECOND_ERROR   = 13;
+const ossimErrorCode ossimErrorCodes::OSSIM_HEMISPHERE_ERROR     = 14;
+const ossimErrorCode ossimErrorCodes::OSSIM_EASTING_ERROR        = 15;
+const ossimErrorCode ossimErrorCodes::OSSIM_RADIUS_ERROR         = 16;
+const ossimErrorCode ossimErrorCodes::OSSIM_ORIGIN_LON_ERROR     = 17;
+const ossimErrorCode ossimErrorCodes::OSSIM_ORIENTATION_ERROR    = 18;
+const ossimErrorCode ossimErrorCodes::OSSIM_SCALE_FACTOR_ERROR   = 19;
+const ossimErrorCode ossimErrorCodes::OSSIM_ZONE_ERROR           = 20;
+const ossimErrorCode ossimErrorCodes::OSSIM_ZONE_OVERRIDE_ERROR  = 21;
+const ossimErrorCode ossimErrorCodes::OSSIM_INVALID_FILE_ERROR   = 22;
+const ossimErrorCode ossimErrorCodes::OSSIM_OPEN_FILE_ERROR      = 23;
+const ossimErrorCode ossimErrorCodes::OSSIM_WRITE_FILE_ERROR     = 24;
+const ossimErrorCode ossimErrorCodes::OSSIM_ERROR_UNKNOWN        = OSSIM_INT_NAN;
+
+ossimErrorCodes* ossimErrorCodes::theInstance = NULL;
+
+ossimErrorCodes::ossimErrorCodes()
+{
+}
+   
+ossimErrorCodes::ossimErrorCodes(const ossimErrorCodes& /* rhs */ )
+{
+}
+
+const ossimErrorCodes& ossimErrorCodes::operator=(const ossimErrorCodes&)
+{
+  return *this;
+}
+
+ossimErrorCodes::~ossimErrorCodes()
+{
+   if (theInstance)
+   {
+      delete theInstance;
+      theInstance = NULL;
+   }
+}
+
+ossimErrorCodes* ossimErrorCodes::instance()
+{
+   if (!theInstance)
+   {
+      theInstance = new ossimErrorCodes();
+   }
+
+   return theInstance;
+}
+
+ossimErrorCode ossimErrorCodes::getErrorCode(const ossimString& error_string) const
+{
+   // Upcase...
+   ossimString str;
+   str = str.upcase(error_string);
+
+   if (str == "OSSIM_OK")
+   {
+      return ossimErrorCodes::OSSIM_OK;
+   }
+   else if (str == "OSSIM_NO_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_NO_ERROR;
+   }
+   else if (str == "OSSIM_WARNING")
+   {
+      return ossimErrorCodes::OSSIM_WARNING;
+   }
+   else if (str == "OSSIM_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   else if (str == "OSSIM_ERROR_STD_PARALLEL_1")
+   {
+      return ossimErrorCodes::OSSIM_ERROR_STD_PARALLEL_1;
+   }
+   else if (str == "OSSIM_LAT_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_LAT_ERROR;
+   }
+   else if (str == "OSSIM_LON_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_LON_ERROR;
+   }
+   else if (str == "OSSIM_NORTHING_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_NORTHING_ERROR;
+   }
+   else if (str == "OSSIM_ORIGIN_LAT_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_ORIGIN_LAT_ERROR;
+   }
+   else if (str == "OSSIM_CENT_MER_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_CENT_MER_ERROR;
+   }
+   else if (str == "OSSIM_A_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_B_ERROR;
+   }
+   else if (str == "OSSIM_A_LESS_B_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_A_LESS_B_ERROR;
+   }
+   else if (str == "OSSIM_FIRST_STDP_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_FIRST_STDP_ERROR;
+   }
+   else if (str == "OSSIM_SEC_STDP_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_SEC_STDP_ERROR;
+   }
+   else if (str == "OSSIM_FIRST_SECOND_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_FIRST_SECOND_ERROR;
+   }
+   else if (str == "OSSIM_HEMISPHERE_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_HEMISPHERE_ERROR;
+   }
+   else if (str == "OSSIM_EASTING_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_EASTING_ERROR;
+   }
+   else if (str == "OSSIM_RADIUS_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_RADIUS_ERROR;
+   }
+   else if (str == "OSSIM_ORIGIN_LON_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_ORIGIN_LON_ERROR;
+   }
+   else if (str == "OSSIM_ORIENTATION_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_ORIENTATION_ERROR;
+   }
+   else if (str == "OSSIM_SCALE_FACTOR_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_SCALE_FACTOR_ERROR;
+   }
+   else if (str == "OSSIM_ZONE_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_ZONE_ERROR;
+   }
+   else if (str == "OSSIM_ZONE_OVERRIDE_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_ZONE_OVERRIDE_ERROR;
+   }
+   else if (str == "OSSIM_INVALID_FILE_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_INVALID_FILE_ERROR;
+   }
+   else if (str == "OSSIM_OPEN_FILE_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_OPEN_FILE_ERROR;
+   }
+   else if (str == "OSSIM_WRITE_FILE_ERROR")
+   {
+      return ossimErrorCodes::OSSIM_WRITE_FILE_ERROR;
+   }
+
+   return OSSIM_ERROR_UNKNOWN;
+}
+
+ossimString ossimErrorCodes::getErrorString(ossimErrorCode error_code) const
+{
+   if(error_code == OSSIM_OK)
+   {
+      // No difference between OSSIM_NO_ERROR and OSSIM_OK.
+      return ossimString("OSSIM_OK");
+   }
+   if(error_code == OSSIM_WARNING)
+   {
+      return ossimString("OSSIM_WARNING");
+   }
+   if(error_code == OSSIM_ERROR)
+   {
+      return ossimString("OSSIM_ERROR");
+   }
+   if(error_code == OSSIM_ERROR_STD_PARALLEL_1)
+   {
+      return ossimString("OSSIM_ERROR_STD_PARALLEL_1");
+   }
+   if(error_code == OSSIM_LAT_ERROR)
+   {
+      return ossimString("OSSIM_LAT_ERROR");
+   }
+   if(error_code == OSSIM_LON_ERROR)
+   {
+      return ossimString("OSSIM_LON_ERROR");
+   }
+   if(error_code == OSSIM_NORTHING_ERROR)
+   {
+      return ossimString("OSSIM_NORTHING_ERROR");
+   }
+   if(error_code == OSSIM_ORIGIN_LAT_ERROR)
+   {
+      return ossimString("OSSIM_ORIGIN_LAT_ERROR");
+   }
+   if(error_code == OSSIM_CENT_MER_ERROR)
+   {
+      return ossimString("OSSIM_CENT_MER_ERROR");
+   }
+   if(error_code == OSSIM_A_ERROR)
+   {
+      return ossimString("OSSIM_A_ERROR");
+   }
+   if(error_code == OSSIM_B_ERROR)
+   {
+      return ossimString("OSSIM_B_ERROR");
+   }
+   if(error_code == OSSIM_A_LESS_B_ERROR)
+   {
+      return ossimString("OSSIM_A_LESS_B_ERROR");
+   }
+   if(error_code == OSSIM_FIRST_STDP_ERROR)
+   {
+      return ossimString("OSSIM_FIRST_STDP_ERROR");
+   }
+   if(error_code == OSSIM_SEC_STDP_ERROR)
+   {
+      return ossimString("OSSIM_SEC_STDP_ERROR");
+   }
+   if(error_code == OSSIM_FIRST_SECOND_ERROR)
+   {
+      return ossimString("OSSIM_FIRST_SECOND_ERROR");
+   }
+   if(error_code == OSSIM_HEMISPHERE_ERROR)
+   {
+      return ossimString("OSSIM_HEMISPHERE_ERROR");
+   }
+   if(error_code == OSSIM_EASTING_ERROR)
+   {
+      return ossimString("OSSIM_EASTING_ERROR");
+   }
+   if(error_code == OSSIM_RADIUS_ERROR)
+   {
+      return ossimString("OSSIM_RADIUS_ERROR");
+   }
+   if(error_code == OSSIM_ORIGIN_LON_ERROR)
+   {
+      return ossimString("OSSIM_ORIGIN_LON_ERROR");
+   }
+   if(error_code == OSSIM_ORIENTATION_ERROR)
+   {
+      return ossimString("OSSIM_ORIENTATION_ERROR");
+   }
+   if(error_code == OSSIM_SCALE_FACTOR_ERROR)
+   {
+      return ossimString("OSSIM_SCALE_FACTOR_ERROR");
+   }
+   if(error_code == OSSIM_ZONE_ERROR)
+   {
+      return ossimString("OSSIM_ZONE_ERROR");
+   }
+   if(error_code == OSSIM_ZONE_OVERRIDE_ERROR)
+   {
+      return ossimString("OSSIM_ZONE_OVERRIDE_ERROR");
+   }
+   if(error_code == OSSIM_INVALID_FILE_ERROR)
+   {
+      return ossimString("OSSIM_INVALID_FILE_ERROR");
+   }
+   if(error_code == OSSIM_OPEN_FILE_ERROR)
+   {
+      return ossimString("OSSIM_OPEN_FILE_ERROR");
+   }
+   if(error_code == OSSIM_WRITE_FILE_ERROR)
+   {
+      return ossimString("OSSIM_WRITE_FILE_ERROR");
+   }
+
+   return ossimString("OSSIM_ERROR_UNKNOWN");
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimErrorCodes.h b/Utilities/OSSIM/ossim_core/base/common/ossimErrorCodes.h
new file mode 100644
index 0000000000..e129f50dcd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimErrorCodes.h
@@ -0,0 +1,102 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken  (dburken@imagelinks.com)
+// 
+// Description:
+// 
+// Contains class declaration with common error codes and methods to go
+// from code to string and string to code.
+//
+//*************************************************************************
+// $Id: ossimErrorCodes.h,v 1.5 2004/05/17 13:57:22 dburken Exp $
+
+#ifndef ossimErrorCodes_HEADER
+#define ossimErrorCodes_HEADER
+
+#include "ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimString;
+
+/*!
+ *  class ossimErrorCodes
+ *  Contains class declaration with common error codes and methods to go
+ *  from code to string and string to code.
+ */
+class OSSIMDLLEXPORT ossimErrorCodes
+{
+public:
+
+   ~ossimErrorCodes();
+
+   /*!
+    *  Returns a pointer to "theInstance".
+    */
+   static ossimErrorCodes* instance();
+
+   /*!
+    *  Returns the error code from a string.  Returns OSSIM_ERROR_UNKNOWN if
+    *  the string does not match.
+    */
+   ossimErrorCode getErrorCode(const ossimString& error_string) const;
+
+   /*!
+    *  Returns the string matching the error code.
+    *  Returns "OSSIM_ERROR_UNKNOWN" if code is not valid.
+    */
+   ossimString getErrorString(ossimErrorCode error_code) const;
+   
+   static const ossimErrorCode OSSIM_OK;
+   static const ossimErrorCode OSSIM_NO_ERROR;
+   static const ossimErrorCode OSSIM_WARNING;
+   static const ossimErrorCode OSSIM_ERROR;
+   static const ossimErrorCode OSSIM_ERROR_STD_PARALLEL_1; 
+   static const ossimErrorCode OSSIM_LAT_ERROR;
+   static const ossimErrorCode OSSIM_LON_ERROR;
+   static const ossimErrorCode OSSIM_NORTHING_ERROR;
+   static const ossimErrorCode OSSIM_ORIGIN_LAT_ERROR;
+   static const ossimErrorCode OSSIM_CENT_MER_ERROR;
+   static const ossimErrorCode OSSIM_A_ERROR;
+   static const ossimErrorCode OSSIM_B_ERROR;
+   static const ossimErrorCode OSSIM_A_LESS_B_ERROR;
+   static const ossimErrorCode OSSIM_FIRST_STDP_ERROR;
+   static const ossimErrorCode OSSIM_SEC_STDP_ERROR;
+   static const ossimErrorCode OSSIM_FIRST_SECOND_ERROR;
+   static const ossimErrorCode OSSIM_HEMISPHERE_ERROR;
+   static const ossimErrorCode OSSIM_EASTING_ERROR;
+   static const ossimErrorCode OSSIM_RADIUS_ERROR;
+   static const ossimErrorCode OSSIM_ORIGIN_LON_ERROR;
+   static const ossimErrorCode OSSIM_ORIENTATION_ERROR;
+   static const ossimErrorCode OSSIM_SCALE_FACTOR_ERROR;
+   static const ossimErrorCode OSSIM_ZONE_ERROR;
+   static const ossimErrorCode OSSIM_ZONE_OVERRIDE_ERROR;
+   static const ossimErrorCode OSSIM_INVALID_FILE_ERROR;
+   static const ossimErrorCode OSSIM_OPEN_FILE_ERROR;
+   static const ossimErrorCode OSSIM_WRITE_FILE_ERROR;
+   static const ossimErrorCode OSSIM_ERROR_UNKNOWN;
+   
+protected:
+   // Only allow instantiation through the "instance()" method.
+   ossimErrorCodes();
+   ossimErrorCodes(const ossimErrorCodes& rhs);
+   const ossimErrorCodes& operator=(const ossimErrorCodes &rhs);
+
+   static ossimErrorCodes* theInstance;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimErrorStatusInterface.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimErrorStatusInterface.cpp
new file mode 100644
index 0000000000..f00d35ae19
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimErrorStatusInterface.cpp
@@ -0,0 +1,79 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: David Burken  (dburken@imagelinks.com)
+//
+// Description:
+// 
+// Contains class definition for common error interfaces.
+//
+//*************************************************************************
+// $Id: ossimErrorStatusInterface.cpp,v 1.3 2005/10/17 18:37:16 gpotts Exp $
+
+#include "ossimErrorStatusInterface.h"
+#include "base/data_types/ossimString.h"
+
+RTTI_DEF(ossimErrorStatusInterface, "ossimErrorStatusInterface");
+
+ossimErrorStatusInterface::ossimErrorStatusInterface()
+   :
+   theErrorStatus(ossimErrorCodes::OSSIM_OK)
+{}
+   
+ossimErrorStatusInterface::~ossimErrorStatusInterface()
+{}
+
+ossimErrorCode ossimErrorStatusInterface::getErrorStatus() const
+{
+   return theErrorStatus;
+}
+
+ossimString ossimErrorStatusInterface::getErrorStatusString() const
+{
+   return ossimErrorCodes::instance()->getErrorString(theErrorStatus);
+}
+
+void ossimErrorStatusInterface::setErrorStatus(ossimErrorCode error_status) const
+{
+   theErrorStatus = error_status;
+}
+
+void  ossimErrorStatusInterface::setErrorStatus() const
+{
+   theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+}
+
+void  ossimErrorStatusInterface::clearErrorStatus() const
+{
+   theErrorStatus = ossimErrorCodes::OSSIM_OK;
+}
+
+std::ostream& ossimErrorStatusInterface::print(std::ostream& out) const
+{
+   out << "ossimErrorStatusInterface::print"
+       << "\ntheErrorStatus:         " << theErrorStatus
+       << "\ntheErrorStatus string:  " << getErrorStatusString()
+       << std::endl;
+   return out;
+}
+
+std::ostream& operator<<(std::ostream& out,
+                         const ossimErrorStatusInterface& obj)
+{
+   return obj.print(out);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimErrorStatusInterface.h b/Utilities/OSSIM/ossim_core/base/common/ossimErrorStatusInterface.h
new file mode 100644
index 0000000000..abb35b661c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimErrorStatusInterface.h
@@ -0,0 +1,84 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: David Burken  (dburken@imagelinks.com)
+//
+// Description:
+// 
+// Contains class declaration for common error interfaces.
+//
+//*************************************************************************
+// $Id: ossimErrorStatusInterface.h,v 1.7 2004/05/21 21:49:19 dburken Exp $
+
+#ifndef ossimErrorStatusInterface_HEADER
+#define ossimErrorStatusInterface_HEADER
+
+#include <iostream>
+
+#include "ossimConstants.h"
+#include "base/common/ossimRtti.h"
+#include "base/common/ossimErrorCodes.h"
+
+/*!
+ *  class ossimErrorStatusInterface
+ *  Provides common interfaces for error handling.
+ *
+ *  Note: For error codes and associated strings use the ossimErrorCodes class.
+ */
+class OSSIMDLLEXPORT ossimErrorStatusInterface
+{
+public:
+   ossimErrorStatusInterface();
+   
+   virtual ~ossimErrorStatusInterface();
+
+   /*!  return theErrorStatus */
+   virtual ossimErrorCode getErrorStatus() const;
+
+   /*!  return theErrorStatus as an ossimString */
+   virtual ossimString getErrorStatusString() const;
+
+   /*! Sets theErrorStatus to error_status. */
+   virtual void  setErrorStatus(ossimErrorCode error_status) const;
+
+   /*! Set theErrorStatus to ossimErrorCodes::OSSIM_ERROR. */
+   virtual void  setErrorStatus() const;
+
+   /*! Clears theErrorStatus by setting to ossimErrorCodes::OSSIM_OK or 0. */
+   virtual void  clearErrorStatus() const;
+
+   /**
+    * Outputs theErrorStatus as an ossimErrorCode and an ossimString.
+    * 
+    * @return std::ostream&
+    *
+    * @note  Derived classes should only have to implement a virtual print,
+    *        not an operator<< funtion as it's implemented here.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+   friend OSSIMDLLEXPORT std::ostream& operator<<(std::ostream& out,
+                                                  const ossimErrorStatusInterface& obj);
+   
+protected:
+   mutable ossimErrorCode theErrorStatus;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimFactoryBaseTemplate.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimFactoryBaseTemplate.cpp
new file mode 100644
index 0000000000..73068cdbe5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimFactoryBaseTemplate.cpp
@@ -0,0 +1,34 @@
+//*****************************************************************************
+// FILE: ossimFactoryBaseTemplate.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimFactoryBaseTemplate.
+//
+// SOFTWARE HISTORY:
+//>
+//   ddmmm2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimFactoryBaseTemplate.cpp,v 1.3 2001/07/12 13:21:46 gpotts Exp $
+
+#include "ossimFactoryBaseTemplate.h"
+
+   
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimFactoryBaseTemplate.h b/Utilities/OSSIM/ossim_core/base/common/ossimFactoryBaseTemplate.h
new file mode 100644
index 0000000000..f8e5789224
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimFactoryBaseTemplate.h
@@ -0,0 +1,128 @@
+//*****************************************************************************
+// FILE: ossimFactoryBaseTemplate.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of template class ossimFactory. This is the base
+//   type for all factories.
+//
+// SOFTWARE HISTORY:
+//>
+//   14Jun2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimFactoryBaseTemplate.h,v 1.5 2002/11/25 18:45:47 gpotts Exp $
+
+#ifndef ossimFactory_HEADER
+#define ossimFactory_HEADER
+#include "ossimConstants.h"
+#include <list>
+using namespace std;
+class OSSIMDLLEXPORT ossimKeywordlist;
+class OSSIMDLLEXPORT ossimString;
+
+/*!****************************************************************************
+ *
+ * TEMPLATE: ossimFactoryBase  
+ *
+ * NOTE: This is primarily intended as an interface template only to insure
+ *       that all factories prescribe to a common type. Concrete classes shall
+ *       be derived from an instance of this template as:
+ *
+ *       class MyFactory : public ossimFactoryBase<MyProductClass>
+ *
+ *       where MyProductClass is the class type being produced.
+ *
+ *       This template is applicable to "Registry" type factories that have
+ *       one or more sub-factories. Thus, a common interface is provided
+ *       without the client distinguishing between registries and factories.
+ *
+ * EXAMPLE: Refer to the projection factories for a working example of the
+ *       use of this base class template. Specifically, refer to the files:
+ *          - ../ossim_core/projections/factory/ossimProjectionFactory.h
+ *          - ../ossim_core/projections/factory/ossimMapProjectionFactory.h
+ *          - ../ossim_core/projections/factory/ossimSensorModelFactory.h
+ *
+ *****************************************************************************/
+template <class Product> class OSSIMDLLEXPORT ossimFactoryBase 
+{
+public:
+   /*!
+    * METHOD: instance()
+    * For accessing static singleton instance of concrete factory. The derived
+    * class implementation of this method invokes the factory's private
+    * constructor. MUST BE PROVIDED BY CONCRETE DERIVED CLASS as follows:
+    *
+    static <ossimFactoryBase-derived class>* instance();
+    */
+   
+   /*!
+    * PURE VIRTUAL METHODS: create(string), create(keywordlist, prefix)
+    *
+    * Attempts to create an instance of the Product given a string or
+    * keywordlist. It is up to the concrete factory implementation to decide
+    * how to interpret string. It could conceivably represent a "magic
+    * number" specification of a product (such as the class name). Or, it could
+    * be a filename that the factory must open to decide which product
+    * to instantiate. The derived factory can also define other create methods
+    * following the model used here.
+    *
+    * Returns successfully constructed product or NULL.
+    */
+   virtual Product* create(const ossimString&)     const = 0;
+   virtual Product* create(const ossimKeywordlist& kwl,
+                           const char* prefix)          const = 0;
+
+   /*!
+    * PURE VIRTUAL METHOD: getList()
+    * Returns name list of all products represented by this factory:
+    */
+   virtual list<ossimString> getList() const = 0;
+
+   /*!
+    * METHOD: registerFactory()
+    * Adds sub-factories to this one. Relevant for the case where the
+    * derived factory maintains a registry of sub-factories.
+    */
+   void registerFactory(ossimFactoryBase<Product>* new_factory)
+      { if(new_factory) theRegistry.push_back(new_factory); }
+   
+protected:
+   /*!
+    * PROTECTED DEFAULT CONSTRUCTOR
+    * Gives concrete class the opportunity to perform initialization
+    * tasks since this is called once with first instance() call. If the
+    * derived factory is to serve as a sub-factory registry, then have the
+    * derived class' constructor call registerFactory() for all of the default
+    * sub-factories involved.
+    */
+   ossimFactoryBase() {};
+
+   virtual ~ossimFactoryBase() {}
+
+   /*!
+    * Member contains list of sub-factories associated with this factory:
+    */
+   list<ossimFactoryBase<Product>*> theRegistry;
+   
+};
+
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimFontInformation.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimFontInformation.cpp
new file mode 100644
index 0000000000..722e74044a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimFontInformation.cpp
@@ -0,0 +1,221 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimFontInformation.cpp,v 1.3 2005/12/16 14:27:02 dburken Exp $
+
+#include <sstream>
+#include <base/common/ossimFontInformation.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+const char* ossimFontInformation::FAMILY_NAME_KW  = "family_name";
+const char* ossimFontInformation::STYLE_NAME_KW   = "style_name";
+const char* ossimFontInformation::POINT_SIZE_KW   = "point_size";
+const char* ossimFontInformation::POINT_SIZE_X_KW = "point_size_x";
+const char* ossimFontInformation::POINT_SIZE_Y_KW = "point_size_y";
+const char* ossimFontInformation::FIXED_FLAG_KW   = "fixed_flag";
+const char* ossimFontInformation::SHEAR_KW        = "shear";
+const char* ossimFontInformation::SHEAR_X_KW      = "shear_x";
+const char* ossimFontInformation::SHEAR_Y_KW      = "shear_y";
+const char* ossimFontInformation::SCALE_KW        = "scale";
+const char* ossimFontInformation::SCALE_X_KW      = "scale_x";
+const char* ossimFontInformation::SCALE_Y_KW      = "scale_y";
+const char* ossimFontInformation::ROTATION_KW     = "rotation";
+
+
+bool ossimFontInformation::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix)const
+{
+   kwl.add(prefix,
+           FAMILY_NAME_KW,
+           theFamilyName,
+           true);
+   kwl.add(prefix,
+           STYLE_NAME_KW,
+           theStyleName,
+           true);
+
+   kwl.add(prefix,
+           POINT_SIZE_KW,
+           thePointSize.toString().c_str(),
+           true);
+      
+   kwl.add(prefix,
+           SHEAR_KW,
+           theShear.toString().c_str(),
+           true);
+
+   kwl.add(prefix,
+           SCALE_KW,
+           theScale.toString().c_str(),
+           true);
+
+#if 0
+   kwl.add(prefix,
+           POINT_SIZE_X_KW,
+           thePointSize.x,
+           true);
+   kwl.add(prefix,
+           POINT_SIZE_Y_KW,
+           thePointSize.y,
+           true);
+   kwl.add(prefix,
+           SHEAR_Y_KW,
+           theShear.y,
+           true);
+   kwl.add(prefix,
+           SCALE_X_KW,
+           theScale.x,
+           true);
+   kwl.add(prefix,
+           SCALE_X_KW,
+           theScale.x,
+           true);
+   kwl.add(prefix,
+           SCALE_Y_KW,
+           theScale.y,
+           true);
+#endif
+   
+   kwl.add(prefix,
+           FIXED_FLAG_KW,
+           (int)theFixedFlag,
+           true);
+   kwl.add(prefix,
+           ROTATION_KW,
+           theRotation,
+           true);
+   
+
+   return true;
+}
+   
+bool ossimFontInformation::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   bool result = true;
+   
+   const char* family_name = kwl.find(prefix, FAMILY_NAME_KW);
+   const char* style_name  = kwl.find(prefix, STYLE_NAME_KW);
+   const char* fixed       = kwl.find(prefix, FIXED_FLAG_KW);
+   const char* rotation    = kwl.find(prefix, ROTATION_KW);
+
+   if(family_name)
+   {
+      theFamilyName = family_name;
+   }
+   else
+   {
+      result = false;
+   }
+
+   if(style_name)
+   {
+      theStyleName = style_name;
+   }
+   else
+   {
+      result = false;
+   }
+
+   // Look for point_size:
+   const char* lookup;
+   lookup = kwl.find(prefix, POINT_SIZE_KW);
+   if (lookup)
+   {
+      std::istringstream is(lookup);
+      is >> thePointSize;
+   }
+   else // backwards compat...
+   {
+      const char* point_x = kwl.find(prefix, POINT_SIZE_X_KW);
+      const char* point_y = kwl.find(prefix, POINT_SIZE_Y_KW);
+      if((point_x)&&(point_y))
+      {
+         thePointSize = ossimIpt(ossimString(point_x).toLong(),
+                                 ossimString(point_y).toLong());
+      }
+      else
+      {
+         result = false;
+      }
+   }
+
+   // Look for shear:
+   lookup = kwl.find(prefix, SHEAR_KW);
+   if (lookup)
+   {
+      std::istringstream is(lookup);
+      is >> theShear;
+   }
+   else
+   {
+      const char* shear_x  = kwl.find(prefix, SHEAR_X_KW);
+      if(shear_x)
+      {
+         theShear.x = ossimString(shear_x).toDouble();
+      }
+      else
+      {
+         result = false;
+      }
+      const char* shear_y  = kwl.find(prefix, SHEAR_Y_KW);
+      if(shear_y)
+      {
+         theShear.y = ossimString(shear_y).toDouble();
+      }
+      else
+      {
+         result = false;
+      }
+   }
+
+   // Look for scale:
+   lookup = kwl.find(prefix, SCALE_KW);
+   if (lookup)
+   {
+      std::istringstream is(lookup);
+      is >> theScale;
+   }
+   else
+   {
+      const char* scale_x  = kwl.find(prefix, SCALE_X_KW);
+      if(scale_x)
+      {
+         theScale.x = ossimString(scale_x).toDouble();
+      }
+      else
+      {
+         result = false;
+      }
+      const char* scale_y  = kwl.find(prefix, SCALE_Y_KW);
+      if(scale_y)
+      {
+         theScale.y = ossimString(scale_y).toDouble();
+      }
+      else
+      {
+         result = false;
+      }
+   }
+
+   if(fixed)
+   {
+      theFixedFlag = ossimString(fixed).toBool();
+   }
+
+   if(rotation)
+   {
+      theRotation = ossimString(rotation).toDouble();
+   }
+   else
+   {
+      result = false;
+   }
+   
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimFontInformation.h b/Utilities/OSSIM/ossim_core/base/common/ossimFontInformation.h
new file mode 100644
index 0000000000..ef00a043e9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimFontInformation.h
@@ -0,0 +1,163 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimFontInformation.h,v 1.4 2005/12/16 14:27:02 dburken Exp $
+#ifndef ossimFontInformation_HEADER
+#define ossimFontInformation_HEADER
+#include <iostream>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimIpt.h>
+
+class ossimKeywordlist;
+
+class OSSIMDLLEXPORT ossimFontInformation
+{
+public:
+   friend std::ostream& operator << (std::ostream& out,
+                                     const ossimFontInformation& rhs)
+      {
+         out << "Family name:  " << rhs.theFamilyName
+             << "\nStyle name:   " << rhs.theStyleName
+             << "\nPoint size:   " << rhs.thePointSize
+             << "\nFixed flag:   " << (rhs.theFixedFlag?"true":"false")
+             << std::endl;
+
+         return out;
+      }
+   ossimFontInformation()
+      :theFamilyName(""),
+       theStyleName(""),
+       thePointSize(0,0),
+       theFixedFlag(false),
+       theScale(1.0,1.0),
+       theRotation(0.0),
+       theShear(0.0,0.0)
+      {
+      }
+   ossimFontInformation(const ossimString& family,
+                        const ossimString& style,
+                        const ossimIpt&    pointSize,
+                        bool               fixedFlag,
+                        const ossimDpt&    scale=ossimDpt(1.0,1.0),
+                        double             rotation = 0.0,
+                        const ossimDpt&    shear=ossimDpt(0.0, 0.0))
+      :theFamilyName(family),
+       theStyleName(style),
+       thePointSize(pointSize),
+       theFixedFlag(fixedFlag),
+       theScale(scale),
+       theRotation(rotation),
+       theShear(shear)
+      {}
+   ossimFontInformation(const ossimFontInformation& rhs)
+      : theFamilyName(rhs.theFamilyName),
+        theStyleName(rhs.theStyleName),
+        thePointSize(rhs.thePointSize),
+        theFixedFlag(rhs.theFixedFlag),
+        theScale(rhs.theScale),
+        theRotation(rhs.theRotation),
+        theShear(rhs.theShear)
+      {
+      }
+   bool isFixed()const
+      {
+         return theFixedFlag;
+      }
+
+   /**
+    * Saves the current state of this object.
+    *
+    * For keywords see loadState:
+    */
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    *
+    * Keywords:
+    *
+    * family_name:
+    * style_name:
+    * fixed_flag:
+    * point_size: ( x, y )
+    * scale: ( x, y )
+    * shear: ( x, y )
+    * rotation:
+    *
+    * point_size_x:  (deprecated)
+    * point_size_y:  (deprecated)
+    * scale_x: (deprecated)
+    * scale_y: (deprecated)
+    * shear_x: (deprecated)
+    * shear_y: (deprecated)
+    */   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix=0);
+
+   bool operator ==(const ossimFontInformation& rhs)const
+      {
+         return ( (theFamilyName == rhs.theFamilyName)&&
+                  (theStyleName  == rhs.theStyleName)&&
+                  (thePointSize  == rhs.thePointSize)&&
+                  (theFixedFlag  == rhs.theFixedFlag)&&
+                  (theScale      == rhs.theScale)&&
+                  (theRotation   == rhs.theRotation)&&
+                  (theShear      == rhs.theShear));
+      }
+
+   bool operator !=(const ossimFontInformation& rhs)const
+      {
+         return ( (theFamilyName != rhs.theFamilyName)||
+                  (theStyleName  != rhs.theStyleName)||
+                  (thePointSize  != rhs.thePointSize)||
+                  (theFixedFlag  != rhs.theFixedFlag)||
+                  (theScale      != rhs.theScale)||
+                  (theRotation   != rhs.theRotation)||
+                  (theShear      != rhs.theShear));
+      }
+
+   const ossimFontInformation& operator =(const ossimFontInformation& rhs)
+      {
+         theFamilyName  = rhs.theFamilyName;
+         theStyleName   = rhs.theStyleName;
+         thePointSize   = rhs.thePointSize;
+         theFixedFlag   = rhs.theFixedFlag;
+         theScale       = rhs.theScale;
+         theRotation    = rhs.theRotation;
+         theShear       = rhs.theShear;
+
+         return *this;
+      }
+   
+   static const char* FAMILY_NAME_KW;
+   static const char* STYLE_NAME_KW;
+   static const char* POINT_SIZE_KW;   // point_size: ( x, y ) 
+   static const char* POINT_SIZE_X_KW; // deprecated
+   static const char* POINT_SIZE_Y_KW; // deprecated
+   static const char* FIXED_FLAG_KW;
+   static const char* SHEAR_KW;        // shear: ( x, y ) 
+   static const char* SHEAR_X_KW;      // deprecated
+   static const char* SHEAR_Y_KW;      // deprecated
+   static const char* SCALE_KW;        // scale: ( x, y ) 
+   static const char* SCALE_X_KW;      // deprecated
+   static const char* SCALE_Y_KW;      // deprecated
+   static const char* ROTATION_KW;
+   
+   
+   ossimString    theFamilyName;
+   ossimString    theStyleName;
+   ossimIpt       thePointSize;
+   bool           theFixedFlag;
+   ossimDpt       theScale;
+   double         theRotation;
+   ossimDpt       theShear;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimGzStream.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimGzStream.cpp
new file mode 100644
index 0000000000..d5683faeda
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimGzStream.cpp
@@ -0,0 +1,280 @@
+// ============================================================================
+// gzstream, C++ iostream classes wrapping the zlib compression library.
+// Copyright (C) 2001  Deepak Bandyopadhyay, Lutz Kettner
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+// ============================================================================
+//
+// File          : gzstream.C
+// Revision      : $Revision: 1.2 $
+// Revision_date : $Date: 2005/11/10 14:13:25 $
+// Author(s)     : Deepak Bandyopadhyay, Lutz Kettner
+// 
+// Standard streambuf implementation following Nicolai Josuttis, "The 
+// Standard C++ Library".
+// ============================================================================
+
+#include "ossimGzStream.h"
+
+#if OSSIM_HAS_LIBZ
+
+#include <iostream>
+#include <fstream>
+#include <string.h>  // for memcpy
+
+
+RTTI_DEF1(ossimIgzStream, "ossimIgzStream", ossimIStream);
+RTTI_DEF1(ossimOgzStream, "ossimOgzStream", ossimOStream);
+
+// ----------------------------------------------------------------------------
+// Internal classes to implement gzstream. See header file for user classes.
+// ----------------------------------------------------------------------------
+
+// --------------------------------------
+// class ossimGzStreamBuf:
+// --------------------------------------
+
+ossimGzStreamBuf* ossimGzStreamBuf::open( const char* name, int open_mode)
+{
+    if ( is_open())
+    {
+        return (ossimGzStreamBuf*)0;
+    }
+    mode = open_mode;
+    // no append nor read/write mode
+    if ((mode & std::ios::ate) || (mode & std::ios::app)
+        || ((mode & std::ios::in) && (mode & std::ios::out)))
+    {
+        return (ossimGzStreamBuf*)0;
+    }
+    
+    char  fmode[10];
+    char* fmodeptr = fmode;
+    if ( mode & std::ios::in)
+    {
+       *fmodeptr++ = 'r';
+    }
+    else if ( mode & std::ios::out)
+    {
+        *fmodeptr++ = 'w';
+    }
+    *fmodeptr++ = 'b';
+    *fmodeptr = '\0';
+    file = gzopen( name, fmode);
+    if (file == 0)
+    {
+       return (ossimGzStreamBuf*)0;
+    }
+    opened = true;
+    return this;
+}
+
+ossimGzStreamBuf * ossimGzStreamBuf::close()
+{
+   if ( is_open())
+   {
+      sync();
+      opened = false;
+      if ( gzclose( file) == Z_OK)
+      {
+         return this;
+      }
+    }
+    return (ossimGzStreamBuf*)0;
+}
+
+std::streamsize ossimGzStreamBuf::xsgetn(char_type* __s,
+                                         std::streamsize n)
+{
+   int num = gzread( file, __s, n);
+
+   if (num <= 0) // ERROR or EOF
+      return EOF;
+   
+   return num;
+}
+
+#if 0
+// int ossimGzStreamBuf::underflow()
+// {
+//    // used for input buffer only
+//    if ( gptr() && ( gptr() < egptr()))
+//       return * reinterpret_cast<unsigned char *>( gptr());
+
+//    if ( ! (mode & std::ios::in) || ! opened)
+//         return EOF;
+//     // Josuttis' implementation of inbuf
+//     int n_putback = gptr() - eback();
+//     if ( n_putback > 4)
+//         n_putback = 4;
+//     memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
+
+//     int num = gzread( file, buffer+4, bufferSize-4);
+//     if (num <= 0) // ERROR or EOF
+//         return EOF;
+
+//     // reset buffer pointers
+//     setg( buffer + (4 - n_putback),   // beginning of putback area
+//           buffer + 4,                 // read position
+//           buffer + 4 + num);          // end of buffer
+
+//     // return next character
+//     return * reinterpret_cast<unsigned char *>( gptr());
+// }
+#endif
+
+int ossimGzStreamBuf::flush_buffer()
+{
+    // Separate the writing of the buffer from overflow() and
+    // sync() operation.
+    int w = pptr() - pbase();
+    if ( gzwrite( file, pbase(), w) != w)
+        return EOF;
+    pbump( -w);
+    return w;
+}
+
+int ossimGzStreamBuf::overflow( int c) { // used for output buffer only
+    if ( ! ( mode & std::ios::out) || ! opened)
+        return EOF;
+    if (c != EOF) {
+        *pptr() = c;
+        pbump(1);
+    }
+    if ( flush_buffer() == EOF)
+        return EOF;
+    return c;
+}
+
+int ossimGzStreamBuf::sync() {
+    // Changed to use flush_buffer() instead of overflow( EOF)
+    // which caused improper behavior with std::endl and flush(),
+    // bug reported by Vincent Ricard.
+    if ( pptr() && pptr() > pbase()) {
+        if ( flush_buffer() == EOF)
+            return -1;
+    }
+    return 0;
+}
+
+ossimGzStreamBuf::pos_type ossimGzStreamBuf::seekoff(off_type t,
+                                                     std::ios_base::seekdir dir,
+                                                     std::ios_base::openmode omode)
+{
+   int whence = 0;
+   switch(dir)
+   {
+      case std::ios::beg:
+      {
+         whence = SEEK_SET;
+         break;
+      }
+      case std::ios::end:
+      {
+         whence = SEEK_END;
+         break;
+      }
+      case std::ios::cur:
+      {
+         whence = SEEK_CUR;
+         break;
+      }
+      default:
+      {
+         whence = SEEK_CUR;
+         break;
+      }
+   }
+
+   return gzseek(file, t, whence);
+}
+
+// ossimGzStreamBuf::pos_type ossimGzStreamBuf::seekpos(pos_type posType, 
+//                                                      std::ios_base::openmode)
+// {
+//    std::cout << "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW" << std::endl;
+//    int whence = 0;
+//    switch(dir)
+//    {
+//       case std::ios::beg:
+//       {
+//          whence = SEEK_SET;
+//          break;
+//       }
+//       case std::ios::end:
+//       {
+//          whence = SEEK_END;
+//          break;
+//       }
+//       case std::ios::cur:
+//       {
+//          whence = SEEK_CUR;
+//          break;
+//       }
+//       default:
+//       {
+//          whence = SEEK_CUR;
+//          break;
+//       }
+//    }
+   
+//    return gzseek(file, t, whence);
+//}
+
+// --------------------------------------
+// class ossimGzStreamBase:
+// --------------------------------------
+
+void ossimIgzStream::open( const char* name, int open_mode)
+{
+   if ( ! buf.open( name, open_mode))
+   {
+      clear( rdstate() | std::ios::badbit);
+   }
+}
+
+void ossimOgzStream::open( const char* name, int open_mode)
+{
+   if ( ! buf.open( name, open_mode))
+   {
+      clear( rdstate() | std::ios::badbit);
+   }
+}
+
+void ossimIgzStream::close()
+{
+   if ( buf.is_open())
+   {
+      if ( !buf.close())
+      {
+         clear( rdstate() | std::ios::badbit);
+      }
+   }
+}
+
+void ossimOgzStream::close()
+{
+   if ( buf.is_open())
+   {
+      if ( !buf.close())
+      {
+         clear( rdstate() | std::ios::badbit);
+      }
+   }
+}
+
+// ============================================================================
+// EOF //
+#endif // OSSIM_HAS_LIBZ
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimGzStream.h b/Utilities/OSSIM/ossim_core/base/common/ossimGzStream.h
new file mode 100644
index 0000000000..4869a51078
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimGzStream.h
@@ -0,0 +1,163 @@
+// ============================================================================
+// gzstream, C++ iostream classes wrapping the zlib compression library.
+// Copyright (C) 2001  Deepak Bandyopadhyay, Lutz Kettner
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+// ============================================================================
+//
+// File          : gzstream.h
+// Revision      : $Revision: 1.4 $
+// Revision_date : $Date: 2005/11/10 19:51:41 $
+// Author(s)     : Deepak Bandyopadhyay, Lutz Kettner
+// 
+// Standard streambuf implementation following Nicolai Josuttis, "The 
+// Standard C++ Library".
+// ============================================================================
+
+#ifndef ossimGzStream_HEADER
+#define ossimGzStream_HEADER 1
+
+// standard C++ with new header file names and std:: namespace
+#include <base/common/ossimReferenced.h>
+#include <base/common/ossimConstants.h>
+#include <ossimConfig.h>
+#include <iostream>
+#include <fstream>
+#include "ossimIoStream.h"
+
+#if OSSIM_HAS_LIBZ
+#include <zlib.h>
+// ----------------------------------------------------------------------------
+// Internal classes to implement gzstream. See below for user classes.
+// ----------------------------------------------------------------------------
+
+class OSSIM_DLL ossimGzStreamBuf : public std::streambuf {
+private:
+    static const int bufferSize = 47+256;    // size of data buff
+    // totals 512 bytes under g++ for igzstream at the end.
+
+    gzFile           file;               // file handle for compressed file
+    char             buffer[bufferSize]; // data buffer
+    bool             opened;             // open/close state of stream
+    int              mode;               // I/O mode
+
+    int flush_buffer();
+public:
+    ossimGzStreamBuf() : opened(false) {
+        setp( buffer, buffer + (bufferSize-1));
+        setg( buffer + 4,     // beginning of putback area
+              buffer + 4,     // read position
+              buffer + 4);    // end position      
+        // ASSERT: both input & output capabilities will not be used together
+    }
+    bool is_open()const { return opened; }
+    ossimGzStreamBuf* open( const char* name, int open_mode);
+    ossimGzStreamBuf* close();
+    ~ossimGzStreamBuf() { close(); }
+    
+    virtual int overflow( int c = EOF);
+
+    // will not use  buffer for get.
+    virtual std::streamsize xsgetn(char_type* __s,
+                                   std::streamsize n);
+//    virtual int     underflow();
+    virtual int     sync();
+    virtual pos_type seekoff(off_type t, std::ios_base::seekdir dir,
+                             std::ios_base::openmode omode = std::ios_base::in |
+                             std::ios_base::out);
+/*     virtual pos_type seekpos(pos_type posType,  */
+/*                              std::ios_base::openmode __mode = std::ios_base::in | */
+/*                              std::ios_base::out); */
+};
+
+/* class OSSIM_DLL ossimGzStreamBase : virtual public ossimProtocolStream */
+/* { */
+/* protected: */
+/*     ossimGzStreamBuf buf; */
+    
+/* public: */
+/*     ossimGzStreamBase():ossimProtocolStream(&buf) {  } */
+/*     ossimGzStreamBase( const char* name, int open_mode); */
+/*     virtual ~ossimGzStreamBase(); */
+/*     virtual void open( const char* name, int open_mode); */
+/*     virtual void close(); */
+/*     ossimGzStreamBuf* rdbuf() { return &buf; } */
+    
+/* TYPE_DATA     */
+/* }; */
+
+//class OSSIM_DLL ossimIgzStream : public ossimGzStreamBase, public std::istream
+class OSSIM_DLL ossimIgzStream : public ossimIStream
+{
+protected:
+    ossimGzStreamBuf buf;
+    
+public:
+    ossimIgzStream() :ossimIStream(&buf){} 
+    ossimIgzStream( const char* name, int openMode = std::ios::in)
+       : ossimIStream(&buf)
+    {
+       open(name, openMode);
+    }
+    virtual ~ossimIgzStream()
+    {
+       buf.close();
+    }
+    ossimGzStreamBuf* rdbuf() { return &buf; }
+    
+    virtual void open( const char* name, int open_mode = std::ios::in);
+    virtual void close();
+    virtual bool is_open()const
+    {
+       return buf.is_open();
+    }
+   virtual bool isCompressed()const
+   {
+      return true;
+   }
+TYPE_DATA    
+};
+
+class OSSIM_DLL ossimOgzStream : public ossimOStream
+{
+protected:
+    ossimGzStreamBuf buf;
+    
+public:
+    ossimOgzStream(){init(&buf);}
+    ossimOgzStream( const char* name, int mode = std::ios::out)
+        : ossimOStream(&buf) {}  
+    virtual ~ossimOgzStream()
+    {
+       buf.close();
+    }
+    ossimGzStreamBuf* rdbuf() { return &buf; }
+    void open( const char* name, int openMode = std::ios::out);
+    virtual void close();
+    virtual bool is_open()const
+    {
+       return buf.is_open();
+    }
+   virtual bool isCompressed()const
+   {
+      return true;
+   }
+TYPE_DATA    
+};
+
+#endif
+   
+#endif // GZSTREAM_H
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimHistogramSource.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimHistogramSource.cpp
new file mode 100644
index 0000000000..0024783382
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimHistogramSource.cpp
@@ -0,0 +1,120 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHistogramSource.cpp,v 1.5 2005/10/06 13:44:05 dburken Exp $
+
+#include <base/common/ossimHistogramSource.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimMultiResLevelHistogram.h>
+
+RTTI_DEF1(ossimHistogramSource, "ossimHistogramSource", ossimSource);
+
+
+ossimHistogramSource::ossimHistogramSource(ossimObject* owner,
+                                           ossim_uint32 numberOfInputs,
+                                           ossim_uint32 numberOfOutputs,
+                                           bool inputListFixedFlag,
+                                           bool outputListFixedFlag)
+   : ossimSource(owner,
+                 numberOfInputs,
+                 numberOfOutputs,
+                 inputListFixedFlag,
+                 outputListFixedFlag),
+     theHistogram(NULL),
+     theFilename()
+{
+}
+
+ossimHistogramSource::~ossimHistogramSource()
+{
+   if (theHistogram)
+   {
+      delete theHistogram;
+      theHistogram = NULL;
+   }
+}
+
+ossimMultiResLevelHistogram* ossimHistogramSource::getHistogram()
+{
+   return theHistogram;
+}
+
+bool ossimHistogramSource::loadState(const ossimKeywordlist& kwl,
+				     const char* prefix)
+{
+   if(theHistogram)
+   {
+      delete theHistogram;
+      theHistogram = NULL;
+   }
+   
+   const char* externalFile = kwl.find(prefix,
+                                       ossimKeywordNames::FILENAME_KW);
+
+   theHistogram = new ossimMultiResLevelHistogram;
+   if(externalFile)
+   {
+      if(!theHistogram->importHistogram(ossimFilename(externalFile)))
+      {
+         delete theHistogram;
+         theHistogram = NULL;
+         theFilename = "";
+      }
+      theFilename = externalFile;
+   }
+   else
+   {
+      ossimString newPrefix = ossimString(prefix) + "histogram.";
+      if(!theHistogram->loadState(kwl, newPrefix))
+      {
+         delete theHistogram;
+         theHistogram = NULL;
+      }
+   }
+   
+   return ossimSource::loadState(kwl, prefix);
+}
+
+bool ossimHistogramSource::saveState(ossimKeywordlist& kwl,
+				     const char* prefix)const
+{
+   if(theHistogram)
+   {
+      if( (theFilename != "")&&
+          theHistogram)
+      {
+         ossimKeywordlist kwl2;
+         
+         if(theHistogram->saveState(kwl2))
+         {
+            kwl2.write(theFilename.c_str());
+            kwl.add(prefix,
+                    ossimKeywordNames::FILENAME_KW,
+                    theFilename.c_str(),
+                    true);
+         }
+      }
+      else
+      {
+         ossimString newPrefix = ossimString(prefix) + "histogram.";
+         theHistogram->saveState(kwl, newPrefix);
+      }
+   }
+   
+   return ossimSource::saveState(kwl, prefix);
+}
+
+// Hidden from use.
+ossimHistogramSource::ossimHistogramSource(const ossimHistogramSource&)
+   :
+   theHistogram(NULL),
+   theFilename()
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimHistogramSource.h b/Utilities/OSSIM/ossim_core/base/common/ossimHistogramSource.h
new file mode 100644
index 0000000000..79f289552e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimHistogramSource.h
@@ -0,0 +1,58 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHistogramSource.h,v 1.11 2005/10/06 13:44:05 dburken Exp $
+#ifndef ossimHistogramSource_HEADER
+#define ossimHistogramSource_HEADER
+
+#include <base/common/ossimSource.h>
+#include <base/data_types/ossimFilename.h>
+
+class OSSIMDLLEXPORT ossimMultiResLevelHistogram;
+
+class OSSIMDLLEXPORT ossimHistogramSource : public ossimSource
+{
+public:
+   
+   virtual ~ossimHistogramSource();
+   
+   virtual ossimMultiResLevelHistogram* getHistogram();
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+protected:
+   ossimHistogramSource(ossimObject* owner=NULL,
+                        ossim_uint32 numberOfInputs=0,
+                        ossim_uint32 numberOfOutputs=0,
+                        bool inputListFixedFlag=true,
+                        bool outputListFixedFlag=true);
+   
+   ossimMultiResLevelHistogram* theHistogram;
+   
+   /*!
+    * if the filename is not "" then it will use
+    * this to store the histogram outside the keywordlist.
+    *
+    * it will set the filename keyword to the filename and
+    * during a save state will save it out to the file
+    * instead of inline to the keyword list.
+    */
+   ossimFilename                theFilename;
+   
+private:
+   /** Hidden from use copy constructor. */
+   ossimHistogramSource(const ossimHistogramSource&);
+
+TYPE_DATA
+};
+
+#endif /* End of "#ifndef ossimHistogramSource_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimId.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimId.cpp
new file mode 100644
index 0000000000..de8dddbb17
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimId.cpp
@@ -0,0 +1,3 @@
+#include "ossimId.h"
+
+const long ossimId::INVALID_ID = -1;
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimId.h b/Utilities/OSSIM/ossim_core/base/common/ossimId.h
new file mode 100644
index 0000000000..8b798022e4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimId.h
@@ -0,0 +1,109 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimId.h,v 1.5 2002/11/25 18:45:47 gpotts Exp $
+#ifndef ossimId_HEADER
+#define ossimId_HEADER
+#include <iostream>
+using namespace std;
+#include "ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimId
+{
+public:
+   friend ostream& operator <<(ostream &out,
+                               const ossimId& data)
+      {
+         data.print(out);
+         return out;
+      }
+   
+   explicit ossimId(long id = 0)
+      :theId(id)
+      {}
+   virtual ~ossimId(){}
+
+   virtual void print(ostream& out)const
+      {
+         out << "id: " << theId;
+      }
+   void setId(long id){theId = id;}
+   long getId()const{return theId;}
+
+   bool operator ==(const ossimId& rhs)const
+      {
+         return (theId == rhs.theId);
+      }
+   bool operator !=(const ossimId& rhs)const
+      {
+         return (theId != rhs.theId);
+      }
+  
+   bool operator == (int rhs)
+   {
+     return (theId == rhs);
+   }
+   bool operator != (int rhs)
+   {
+     return (theId != rhs);
+   }
+
+   bool operator <(const ossimId& rhs)const
+      {
+         return (theId < rhs.theId);
+      }
+   bool operator <=(const ossimId& rhs)const
+      {
+         return (theId <= rhs.theId);
+      }
+   bool operator >(const ossimId& rhs)const
+      {
+         return (theId > rhs.theId);
+      }
+   bool operator >=(const ossimId& rhs)const
+      {
+         return (theId >= rhs.theId);
+      }
+
+   bool operator <(int rhs)const
+      {
+         return (theId < rhs);
+      }
+   bool operator >(int rhs)const
+      {
+         return (theId > rhs);
+      }
+   bool operator <=(int rhs)const
+      {
+         return (theId <= rhs);
+      }
+   bool operator >=(int rhs)const
+      {
+         return (theId >= rhs);
+      }
+
+   static const long INVALID_ID;
+protected:
+   long theId;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimIdManager.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimIdManager.cpp
new file mode 100644
index 0000000000..1fa4548a67
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimIdManager.cpp
@@ -0,0 +1,64 @@
+#include "ossimIdManager.h"
+#include <time.h>
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+
+long ossimIdManager::theCurrentId           = ossimId::INVALID_ID;
+ossimIdManager* ossimIdManager::theInstance = NULL;
+
+ossimIdManager::ossimIdManager()
+{
+   theCurrentId=ossimId::INVALID_ID;
+}
+
+ossimIdManager::ossimIdManager(const ossimIdManager& /* rhs */)
+{
+   theCurrentId=ossimId::INVALID_ID;
+}
+
+ossimIdManager::~ossimIdManager()
+{
+   theCurrentId=ossimId::INVALID_ID;   
+}
+
+ossimIdManager* ossimIdManager::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimIdManager;
+      theCurrentId = -1;
+   }
+
+   return theInstance;
+}
+
+ossimId ossimIdManager::generateId()
+{
+   return ossimId(++theCurrentId);
+}
+
+ossimId ossimIdManager::generateId(long customId)
+{
+   if(customId <= theCurrentId)
+   {
+      return ossimId(++theCurrentId);
+   }
+   theCurrentId = customId;
+   return ossimId(theCurrentId);
+}
+
+void ossimIdManager::setCurrentId(long currentId)
+{
+   theCurrentId = (currentId >=0) ? currentId: theCurrentId;
+}
+
+void ossimIdManager::releaseId(const ossimId& idToRelease)
+{
+   // currently doesn't do anything but we will later
+   // store id's and make sure that they are unique.
+   //
+}
+void  ossimIdManager::operator=(const ossimIdManager& /* rhs */)
+{}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimIdManager.h b/Utilities/OSSIM/ossim_core/base/common/ossimIdManager.h
new file mode 100644
index 0000000000..40818fc35f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimIdManager.h
@@ -0,0 +1,25 @@
+#ifndef ossimIdManager_HEADER
+#define ossimIdManager_HEADER
+
+#include "ossimId.h"
+
+class OSSIMDLLEXPORT ossimIdManager
+{
+public:
+   static ossimIdManager* instance();
+   ossimId generateId();
+   ossimId generateId(long customId);
+   void releaseId(const ossimId& idToRelease);
+   void setCurrentId(long customId);
+   
+protected:
+   ossimIdManager(); // make sure this can't be constructed outside
+   ossimIdManager(const ossimIdManager& rhs);
+   ~ossimIdManager();
+   void operator =(const ossimIdManager& rhs);
+
+   static ossimIdManager* theInstance;
+   static long            theCurrentId;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimIoStream.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimIoStream.cpp
new file mode 100644
index 0000000000..5c90ed8187
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimIoStream.cpp
@@ -0,0 +1,169 @@
+#include "ossimIoStream.h"
+
+RTTI_DEF1(ossimIStream, "ossimIProtocolStream", ossimProtocolStream);
+RTTI_DEF1(ossimOStream, "ossimOProtocolStream", ossimProtocolStream);
+RTTI_DEF1(ossimIOStream, "ossimOProtocolStream", ossimProtocolStream);
+
+RTTI_DEF1(ossimIFStream, "ossimIFStream", ossimIStream);
+RTTI_DEF1(ossimOFStream, "ossimOFStream", ossimOStream);
+RTTI_DEF1(ossimIOFStream, "ossimIOFStream", ossimIOStream);
+
+void operator >> (ossimIStream& in,ossimOStream& out)
+{
+   char buf[1024];
+   bool done = false;
+
+   while(!done&&!in.fail())
+   {
+      in.read(buf, 1024);
+      if(in.gcount() < 1024)
+      {
+         done = true;
+      }
+      if(in.gcount() > 0)
+      {
+         out.write(buf, in.gcount());
+      }
+   }
+}
+
+ossimIOStream& operator >> (ossimIStream& in,ossimIOStream& out)
+{
+   char buf[1024];
+   bool done = false;
+
+   while(!done&&!in.fail())
+   {
+      in.read(buf, 1024);
+      if(in.gcount() < 1024)
+      {
+         done = true;
+      }
+      if(in.gcount() > 0)
+      {
+         out.write(buf, in.gcount());
+      }
+   }
+   
+   return out;
+}
+
+void operator >> (ossimIOStream& in,ossimOStream& out)
+{
+   char buf[1024];
+   bool done = false;
+
+   while(!done&&!in.fail())
+   {
+      in.read(buf, 1024);
+      if(in.gcount() < 1024)
+      {
+         done = true;
+      }
+      if(in.gcount() > 0)
+      {
+         out.write(buf, in.gcount());
+      }
+   }
+}
+
+ossimIOStream& operator >> (ossimIOStream& in,ossimIOStream& out)
+{
+   char buf[1024];
+   bool done = false;
+
+   while(!done&&!in.fail())
+   {
+      in.read(buf, 1024);
+      if(in.gcount() < 1024)
+      {
+         done = true;
+      }
+      if(in.gcount() > 0)
+      {
+         out.write(buf, in.gcount());
+      }
+   }
+
+   return out;
+}
+
+void operator << (ossimOStream& out, ossimIStream& in)
+{
+   char buf[1024];
+   bool done = false;
+
+   while(!done&&!in.fail())
+   {
+      in.read(buf, 1024);
+      if(in.gcount() < 1024)
+      {
+         done = true;
+      }
+      if(in.gcount() > 0)
+      {
+         out.write(buf, in.gcount());
+      }
+   }
+}
+
+void operator << (ossimOStream& out, ossimIOStream& in)
+{
+   char buf[1024];
+   bool done = false;
+
+   while(!done&&!in.fail())
+   {
+      in.read(buf, 1024);
+      if(in.gcount() < 1024)
+      {
+         done = true;
+      }
+      if(in.gcount() > 0)
+      {
+         out.write(buf, in.gcount());
+      }
+   }
+}
+
+ossimIOStream& operator << (ossimIOStream& out, ossimIStream& in)
+{
+   char buf[1024];
+   bool done = false;
+
+   while(!done&&!in.fail())
+   {
+      in.read(buf, 1024);
+      if(in.gcount() < 1024)
+      {
+         done = true;
+      }
+      if(in.gcount() > 0)
+      {
+         out.write(buf, in.gcount());
+      }
+   }
+
+   return out;
+}
+
+ossimIOStream& operator << (ossimIOStream& out, ossimIOStream& in)
+{
+   char buf[1024];
+   bool done = false;
+
+   while(!done&&!in.fail())
+   {
+      in.read(buf, 1024);
+      if(in.gcount() < 1024)
+      {
+         done = true;
+      }
+      if(in.gcount() > 0)
+      {
+         out.write(buf, in.gcount());
+      }
+   }
+
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimIoStream.h b/Utilities/OSSIM/ossim_core/base/common/ossimIoStream.h
new file mode 100644
index 0000000000..498c0f6f22
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimIoStream.h
@@ -0,0 +1,342 @@
+#ifndef ossimIoStream_HEADER
+#define ossimIoStream_HEADER
+#include "ossimProtocolStream.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+
+class OSSIM_DLL ossimIStream : public ossimProtocolStream, public std::istream
+{
+public:
+   ossimIStream():std::istream((std::streambuf*)0){}
+   ossimIStream(std::streambuf* buf):ossimProtocolStream(buf),std::istream(buf)
+   {}
+   void init(std::streambuf* buf)
+   {
+      ossimProtocolStream::init(buf);
+      std::istream::init(buf);
+   }
+TYPE_DATA
+};
+
+class OSSIM_DLL ossimOStream : public ossimProtocolStream, public std::ostream
+{
+public:
+   ossimOStream():std::ostream((std::streambuf*)0){}
+   ossimOStream(std::streambuf* buf):ossimProtocolStream(buf),std::ostream(buf)
+   {}
+   void init(std::streambuf* buf)
+   {
+      ossimProtocolStream::init(buf);
+      std::ostream::init(buf);
+   }
+   
+TYPE_DATA
+};
+
+class OSSIM_DLL ossimIOStream : public ossimProtocolStream, public std::iostream
+{
+public:
+   ossimIOStream():ossimProtocolStream((std::streambuf*)0),std::iostream((std::streambuf*)0){}
+   ossimIOStream(std::streambuf* buf):ossimProtocolStream(buf),std::iostream(buf)
+   {}
+   void init(std::streambuf* buf)
+   {
+      ossimProtocolStream::init(buf);
+      std::iostream::init(buf);
+   }
+
+TYPE_DATA      
+};
+
+class OSSIM_DLL ossimIOMemoryStream : public ossimIOStream
+{
+protected:
+   std::stringbuf theBuf;
+   
+public:
+   ossimIOMemoryStream()
+      :theBuf(std::ios::in|std::ios::out)
+   {
+      ossimIOStream::init(&theBuf);
+   }
+   bool is_open()const
+   {
+      return true;
+   }
+   virtual void open(const char* protocolString,
+                     int openMode)
+   {
+   }
+   ossimString str()
+   {
+      return theBuf.str();
+   }
+   virtual void close()
+   {}
+
+   ossim_uint32 size()const
+   {
+      ossimIOMemoryStream*  thisPtr = const_cast<ossimIOMemoryStream*>(this);
+      std::streampos pos = thisPtr->tellg();
+      thisPtr->seekg(0, std::ios::end);
+      std::streampos endPos = thisPtr->tellg();
+      thisPtr->seekg(pos, std::ios::beg);
+      
+      return (ossim_uint32)(endPos);
+   }
+   virtual bool isCompressed()const
+   {
+      return false;
+   }
+};
+
+class OSSIM_DLL ossimIMemoryStream : public ossimIStream
+{
+protected:
+   std::stringbuf theBuf;
+   
+public:
+   ossimIMemoryStream(const ossimString& inputBuf)
+      :theBuf(inputBuf.c_str(),
+              std::ios::in)
+   {
+      ossimIStream::init(&theBuf);
+   }
+   bool is_open()const
+   {
+      return true;
+   }
+   ossim_uint32 size()const
+   {
+      ossimIMemoryStream*  thisPtr = const_cast<ossimIMemoryStream*>(this);
+      std::streampos pos = thisPtr->tellg();
+      thisPtr->seekg(0, std::ios::end);
+      std::streampos endPos = thisPtr->tellg();
+      thisPtr->seekg(pos, std::ios::beg);
+      return (ossim_uint32)(endPos);
+   }
+   virtual void open(const char* protocolString,
+                     int openMode)
+   {
+   }
+   virtual void close(){}
+   ossimString str()
+   {
+      return theBuf.str();
+   }
+   virtual bool isCompressed()const
+   {
+      return false;
+   }
+};
+
+class OSSIM_DLL ossimOMemoryStream : public ossimOStream
+{
+protected:
+   std::stringbuf theBuf;
+   
+public:
+   ossimOMemoryStream()
+      :theBuf(std::ios::out)
+   {
+      ossimOStream::init(&theBuf);
+   }
+   bool is_open()const
+   {
+      return true;
+   }
+   ossim_uint32 size()const
+   {
+      ossimOMemoryStream*  thisPtr = const_cast<ossimOMemoryStream*>(this);
+      std::streampos pos = thisPtr->tellp();
+      thisPtr->seekp(0, std::ios::end);
+      std::streampos endPos = thisPtr->tellp();
+      thisPtr->seekp(pos, std::ios::beg);
+      return (ossim_uint32)(endPos);
+   }
+   virtual void open(const char* protocolString,
+                     int openMode)
+   {
+   }
+   virtual void close()
+   {}
+
+   ossimString str()
+   {
+      return theBuf.str();
+   }
+   virtual bool isCompressed()const
+   {
+      return false;
+   }
+};
+
+class OSSIM_DLL ossimIOFStream : public ossimIOStream
+{
+protected:
+   std::filebuf theBuf;
+   
+public:
+   ossimIOFStream()
+   {
+      ossimIOStream::init(&theBuf);
+   }
+   ossimIOFStream(const char* name,
+                 int openMode=std::ios::in|std::ios::out|std::ios::binary)
+   {
+      ossimIOStream::init(&theBuf);
+      open(name, openMode);
+   }
+   virtual ~ossimIOFStream()
+   {
+      if(is_open())
+      {
+         close();
+      }
+   }
+   
+   std::filebuf* rdbuf()
+   {
+      return &theBuf;
+   }
+
+   virtual void open(const char* name,
+                 int openMode=std::ios::in|std::ios::out|std::ios::binary)
+   {
+      if(!theBuf.open(name, (std::ios::openmode)openMode))
+      {
+         this->setstate(std::ios::failbit);
+      }
+   }
+   virtual void close()
+   {
+      if(!theBuf.close())
+      {
+         this->setstate(std::ios::failbit);
+      }
+   }
+   virtual bool is_open()const
+   {
+      return theBuf.is_open();
+   }
+   virtual bool isCompressed()const
+   {
+      return false;
+   }
+TYPE_DATA   
+};
+
+class OSSIM_DLL ossimIFStream : public ossimIStream
+{
+protected:
+   std::filebuf theBuf;
+   
+public:
+   ossimIFStream()
+   {
+      ossimIStream::init(&theBuf);
+   }
+   ossimIFStream(const char* name,
+                 int openMode=std::ios::in|std::ios::binary)
+   {
+      ossimIStream::init(&theBuf);
+      open(name, openMode);
+   }
+   virtual ~ossimIFStream()
+   {
+      if(is_open())
+      {
+         close();
+      }
+   }
+   
+   std::filebuf* rdbuf() { return &theBuf; }
+   virtual void open(const char* name,
+                     int openMode = std::ios::in|std::ios::binary)
+   {
+      if(!theBuf.open(name, (std::ios::openmode)openMode))
+      {
+         this->setstate(std::ios::failbit);
+      }
+   }
+   virtual void close()
+   {
+      if(!theBuf.close())
+      {
+         this->setstate(std::ios::failbit);
+      }
+   }
+   virtual bool is_open()const
+   {
+      return theBuf.is_open();
+   }
+   virtual bool isCompressed()const
+   {
+      return false;
+   }
+TYPE_DATA   
+};
+
+class OSSIM_DLL ossimOFStream : public ossimOStream
+{
+protected:
+   std::filebuf theBuf;
+   
+public:
+   ossimOFStream()
+   {
+      ossimOStream::init(&theBuf);
+   }
+   ossimOFStream(const char* name,
+                 int openMode=std::ios::out)
+   {
+      ossimOStream::init(&theBuf);
+      open(name, openMode);
+   }
+   virtual ~ossimOFStream()
+   {
+      if(is_open())
+      {
+         close();
+      }
+   }
+   std::filebuf* rdbuf() { return &theBuf; }
+   virtual void open(const char* name,
+                     int openMode = std::ios::out)
+   {
+      if(!theBuf.open(name, (std::ios::openmode)openMode))
+      {
+         this->setstate(std::ios::failbit);
+      }
+   }
+   virtual void close()
+   {
+      if(!theBuf.close())
+      {
+         this->setstate(std::ios::failbit);
+      }
+   }
+   virtual bool is_open()const
+   {
+      return theBuf.is_open();
+   }
+   virtual bool isCompressed()const
+   {
+      return false;
+   }
+TYPE_DATA   
+};
+
+OSSIM_DLL void operator >> (ossimIStream& in,ossimOStream& out);
+OSSIM_DLL ossimIOStream& operator >> (ossimIStream& in,ossimIOStream& out);
+OSSIM_DLL void operator >> (ossimIOStream& in,ossimOStream& out);
+OSSIM_DLL ossimIOStream& operator >> (ossimIOStream& in,ossimIOStream& out);
+OSSIM_DLL void operator << (ossimOStream& out, ossimIStream& in);
+OSSIM_DLL void operator << (ossimOStream& out, ossimIOStream& in);
+OSSIM_DLL ossimIOStream& operator << (ossimIOStream& out, ossimIStream& in);
+OSSIM_DLL ossimIOStream& operator << (ossimIOStream& out, ossimIOStream& in);
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimKeywordNames.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimKeywordNames.cpp
new file mode 100644
index 0000000000..4078a58dd8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimKeywordNames.cpp
@@ -0,0 +1,173 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@remotesensing.org)
+// Description: Common file for global Keywords.
+//
+//*************************************************************************
+// $Id: ossimKeywordNames.cpp,v 1.40 2005/11/16 17:44:11 dburken Exp $
+
+#include "ossimKeywordNames.h"
+
+const char* ossimKeywordNames::AZIMUTH_ANGLE_KW = "azimuth_angle";
+const char* ossimKeywordNames::BAND_KW = "band";
+const char* ossimKeywordNames::BORDER_SIZE_KW = "border_size";
+const char* ossimKeywordNames::BRUSH_COLOR_KW = "brush_color";
+const char* ossimKeywordNames::BYTE_ORDER_KW = "byte_order";
+const char* ossimKeywordNames::CENTRAL_MERIDIAN_KW = "central_meridian";
+const char* ossimKeywordNames::CENTRAL_POINT1_LAT_KW = "central_point1_lat";
+const char* ossimKeywordNames::CENTRAL_POINT1_LON_KW = "central_point1_lon";
+const char* ossimKeywordNames::CENTRAL_POINT2_LAT_KW = "central_point2_lat";
+const char* ossimKeywordNames::CENTRAL_POINT2_LON_KW = "central_point2_lon";
+const char* ossimKeywordNames::CENTER_PIXEL_X_KW = "center_pixel_x";
+const char* ossimKeywordNames::CENTER_PIXEL_Y_KW = "center_pixel_y";
+const char* ossimKeywordNames::COMPRESS_KW = "compress";
+const char* ossimKeywordNames::COMPRESSION_QUALITY_KW = "compression_quality";
+const char* ossimKeywordNames::COMPRESSION_TYPE_KW = "compression_type";
+const char* ossimKeywordNames::CONVERGENCE_THRESHOLD_KW = "convergence_threshold";
+const char* ossimKeywordNames::CREATE_EXTERNAL_GEOMETRY_KW = "create_external_geometry";
+const char* ossimKeywordNames::CREATE_IMAGE_KW = "create_image";
+const char* ossimKeywordNames::CREATE_HISTOGRAM_KW = "create_histogram";
+const char* ossimKeywordNames::CREATE_OVERVIEW_KW = "create_overview";
+const char* ossimKeywordNames::DATA_FILE_KW = "data_file";
+const char* ossimKeywordNames::DATE_KW = "date";
+const char* ossimKeywordNames::DATUM_KW = "datum";
+const char* ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT = "decimal_degrees_per_pixel_lat";
+const char* ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON = "decimal_degrees_per_pixel_lon";
+const char* ossimKeywordNames::DESCRIPTION_KW = "description";
+const char* ossimKeywordNames::ELEVATION_ANGLE_KW = "elevation_angle";
+const char* ossimKeywordNames::ELEVATION_CELL_KW = "elevation_cell";
+const char* ossimKeywordNames::ELEVATION_SOURCE_KW = "elevation_source";
+const char* ossimKeywordNames::ELLIPSE_CODE_KW = "ellipse_code";
+const char* ossimKeywordNames::ELLIPSE_NAME_KW = "ellipse_name";
+const char* ossimKeywordNames::ENABLED_KW = "enabled";
+const char* ossimKeywordNames::ENABLE_CACHE_KW = "enable_cache";
+const char* ossimKeywordNames::ENTRY_KW = "entry";
+const char* ossimKeywordNames::FALSE_EASTING_KW = "false_easting";
+const char* ossimKeywordNames::FALSE_NORTHING_KW = "false_northing";
+const char* ossimKeywordNames::FEATURE_NAME_KW = "feature_name";
+const char* ossimKeywordNames::FILENAME_KW = "filename";
+const char* ossimKeywordNames::FILEPATH_KW = "filepath";
+const char* ossimKeywordNames::FILL_FLAG_KW = "fill_flag";
+const char* ossimKeywordNames::GEOM_FILE_KW = "geom_file";
+const char* ossimKeywordNames::HEMISPHERE_KW = "hemisphere";
+const char* ossimKeywordNames::HORIZONTAL_SIZE_KW = "horizontal_size";
+const char* ossimKeywordNames::ID_KW ="id";
+const char* ossimKeywordNames::IMAGE_FILE_KW = "image_file";
+const char* ossimKeywordNames::IMAGE_PATH_KW = "image_path";
+const char* ossimKeywordNames::IMAGE_TYPE_KW = "image_type";
+const char* ossimKeywordNames::IMAGE_DATE_KW = "image_date";
+const char* ossimKeywordNames::IMAGE_FILE_SIZE_KW = "image_file_size";
+const char* ossimKeywordNames::INPUT_RR_LEVEL_KW = "input_rr_level";
+const char* ossimKeywordNames::INTERLEAVE_TYPE_KW = "interleave_type";
+const char* ossimKeywordNames::JULIAN_DAY_KW = "julian_day";
+const char* ossimKeywordNames::LAT_INCREMENT_KW = "lat_increment";
+const char* ossimKeywordNames::LL_LAT_KW = "ll_lat";
+const char* ossimKeywordNames::LL_LON_KW = "ll_lon";
+const char* ossimKeywordNames::LR_LAT_KW = "lr_lat";
+const char* ossimKeywordNames::LR_LON_KW = "lr_lon";
+const char* ossimKeywordNames::LL_X_KW = "ll_x";
+const char* ossimKeywordNames::LL_Y_KW = "ll_y";
+const char* ossimKeywordNames::LR_X_KW = "lr_x";
+const char* ossimKeywordNames::LR_Y_KW = "lr_y";
+const char* ossimKeywordNames::LON_INCREMENT_KW = "lon_increment";
+const char* ossimKeywordNames::MAJOR_AXIS_KW = "major_axis";
+const char* ossimKeywordNames::MAX_VALUE_KW = "max_value";
+const char* ossimKeywordNames::MAX_ITERATIONS_KW = "max_iterations";
+const char* ossimKeywordNames::MAX_QUADTREE_LEVELS_KW = "max_quadtree_levels";
+const char* ossimKeywordNames::METADATA_TYPE_KW = "metadata_type";
+const char* ossimKeywordNames::METERS_PER_PIXEL_X_KW = "meters_per_pixel_x";
+const char* ossimKeywordNames::METERS_PER_PIXEL_Y_KW = "meters_per_pixel_y";
+const char* ossimKeywordNames::MINOR_AXIS_KW = "minor_axis";
+const char* ossimKeywordNames::MIN_VALUE_KW = "min_value";
+const char* ossimKeywordNames::NULL_VALUE_KW = "null_value";
+const char* ossimKeywordNames::NUMBER_BANDS_KW = "number_bands";
+const char* ossimKeywordNames::NUMBER_ENTRIES_KW = "number_entries";
+const char* ossimKeywordNames::NUMBER_INPUT_BANDS_KW = "number_input_bands";
+const char* ossimKeywordNames::NUMBER_INPUTS_KW = "number_inputs";
+const char* ossimKeywordNames::NUMBER_OUTPUTS_KW = "number_outputs";
+const char* ossimKeywordNames::NUMBER_OUTPUT_BANDS_KW = "number_output_bands";
+const char* ossimKeywordNames::NUMBER_LINES_KW = "number_lines";
+const char* ossimKeywordNames::NUMBER_REDUCED_RES_SETS_KW = "number_reduced_res_sets";
+const char* ossimKeywordNames::NUMBER_SAMPLES_KW = "number_samples";
+const char* ossimKeywordNames::ORIGIN_X_KW = "origin_x";
+const char* ossimKeywordNames::ORIGIN_Y_KW = "origin_y";
+const char* ossimKeywordNames::ORIGIN_LATITUDE_KW = "origin_latitude";
+const char* ossimKeywordNames::OUTPUT_FILE_KW = "output_file";
+const char* ossimKeywordNames::OUTPUT_FILE_PREFIX_KW = "output_file_prefix";
+const char* ossimKeywordNames::OUTPUT_FILE_EXTENSION_KW = "output_file_extension";
+const char* ossimKeywordNames::OVERVIEW_COMPRESSION_QUALITY_KW = "overview_compression_quality";
+const char* ossimKeywordNames::OVERVIEW_COMPRESSION_TYPE_KW = "overview_compression_type";
+const char* ossimKeywordNames::OVERVIEW_FILE_KW  = "overview_file";
+const char* ossimKeywordNames::PCS_CODE_KW = "pcs_code";
+const char* ossimKeywordNames::PEN_COLOR_KW = "pen_color";
+const char* ossimKeywordNames::PHOTOMETRIC_KW    = "photometric";
+const char* ossimKeywordNames::PIXEL_TYPE_KW  = "pixel_type";
+const char* ossimKeywordNames::PLANAR_CONFIG_KW  = "planar_config";
+const char* ossimKeywordNames::POINT_WIDTH_HEIGHT_KW = "point_width_height";
+const char* ossimKeywordNames::PROJECTION_KW     = "projection";
+const char* ossimKeywordNames::QUALITY_KW        = "quality";
+const char* ossimKeywordNames::RADIOMETRY_KW = "radiometry";
+const char* ossimKeywordNames::REDUCED_RES_LEVEL_KW = "reduced_res_level";
+const char* ossimKeywordNames::ROTATION_KW = "rotation";
+const char* ossimKeywordNames::SCALE_PER_PIXEL_X_KW = "scale_per_pixel_x";
+const char* ossimKeywordNames::SCALE_PER_PIXEL_Y_KW = "scale_per_pixel_y";
+const char* ossimKeywordNames::SCALAR_TYPE_KW    = "scalar_type";
+const char* ossimKeywordNames::SCALE_FACTOR_KW   = "scale_factor";
+const char* ossimKeywordNames::SCALE_FACTOR_X_KW = "scale_factor_x";
+const char* ossimKeywordNames::SCALE_FACTOR_Y_KW = "scale_factor_y";
+const char* ossimKeywordNames::SCALE_X_KW = "scale_x";
+const char* ossimKeywordNames::SCALE_Y_KW = "scale_y";
+const char* ossimKeywordNames::STD_PARALLEL_1_KW = "std_parallel_1";
+const char* ossimKeywordNames::STD_PARALLEL_2_KW = "std_parallel_2";
+const char* ossimKeywordNames::THICKNESS_KW = "thickness";
+const char* ossimKeywordNames::TIE_POINT_EASTING_KW = "tie_point_easting";  // ????
+const char* ossimKeywordNames::TIE_POINT_NORTHING_KW = "tie_point_northing";  // ????
+const char* ossimKeywordNames::TIE_POINT_X_KW = "tie_point_x";  // ????
+const char* ossimKeywordNames::TIE_POINT_Y_KW = "tie_point_y";  // ????
+const char* ossimKeywordNames::TIE_POINT_LAT_KW = "tie_point_lat";
+const char* ossimKeywordNames::TIE_POINT_LON_KW = "tie_point_lon";
+const char* ossimKeywordNames::TILE_SIZE_X_KW = "tile_size_x";
+const char* ossimKeywordNames::TILE_SIZE_Y_KW = "tile_size_y";
+const char* ossimKeywordNames::TILE_SOURCE_KW = "tile_source";
+const char* ossimKeywordNames::TILE_TYPE_KW = "tile_type";
+const char* ossimKeywordNames::TRANSLATION_X_KW = "translation_x";
+const char* ossimKeywordNames::TRANSLATION_Y_KW = "translation_y";
+const char* ossimKeywordNames::TYPE_KW = "type";
+const char* ossimKeywordNames::UL_LAT_KW = "ul_lat";
+const char* ossimKeywordNames::UL_LON_KW = "ul_lon";
+const char* ossimKeywordNames::UNITS_KW = "units";
+const char* ossimKeywordNames::UR_LAT_KW = "ur_lat";
+const char* ossimKeywordNames::UR_LON_KW = "ur_lon";
+const char* ossimKeywordNames::UL_X_KW = "ul_x";
+const char* ossimKeywordNames::UL_Y_KW = "ul_y";
+const char* ossimKeywordNames::UR_X_KW = "ur_x";
+const char* ossimKeywordNames::UR_Y_KW = "ur_y";
+const char* ossimKeywordNames::VERTICAL_SIZE_KW = "vertical_size";
+const char* ossimKeywordNames::ZONE_KW = "zone";
+
+ossimKeywordNames::ossimKeywordNames()
+{}
+
+ossimKeywordNames::ossimKeywordNames(const ossimKeywordNames& /* rhs */)
+{}
+
+const ossimKeywordNames& ossimKeywordNames::operator=(const ossimKeywordNames& /* rhs */)
+{
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimKeywordNames.h b/Utilities/OSSIM/ossim_core/base/common/ossimKeywordNames.h
new file mode 100644
index 0000000000..0ebeb8f6f2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimKeywordNames.h
@@ -0,0 +1,181 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@remotesensing.org)
+// Description: Common file for global Keywors.
+//
+//*************************************************************************
+// $Id: ossimKeywordNames.h,v 1.41 2005/11/16 17:44:11 dburken Exp $
+
+#ifndef ossimKeywordNames_HEADER
+#define ossimKeywordNames_HEADER
+#include "ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimKeywordNames
+{
+public:
+   //***
+   // NOTE:  List keyword in alphabetical order.
+   //***
+   static const char* AZIMUTH_ANGLE_KW;
+   static const char* BAND_KW;
+   static const char* BORDER_SIZE_KW;
+   static const char* BRUSH_COLOR_KW;
+   static const char* BYTE_ORDER_KW;
+   static const char* CENTER_PIXEL_X_KW;
+   static const char* CENTER_PIXEL_Y_KW;
+   static const char* CENTRAL_MERIDIAN_KW;
+   static const char* CENTRAL_POINT1_LAT_KW;
+   static const char* CENTRAL_POINT1_LON_KW;
+   static const char* CENTRAL_POINT2_LAT_KW;
+   static const char* CENTRAL_POINT2_LON_KW;
+   static const char* COMPRESS_KW;
+   static const char* COMPRESSION_QUALITY_KW;
+   static const char* COMPRESSION_TYPE_KW;
+   static const char* CONVERGENCE_THRESHOLD_KW;
+   static const char* CREATE_EX_KW;
+   static const char* CREATE_EXTERNAL_GEOMETRY_KW;
+   static const char* CREATE_IMAGE_KW;
+   static const char* CREATE_HISTOGRAM_KW;   
+   static const char* CREATE_OVERVIEW_KW;
+   static const char* DATA_FILE_KW;
+   static const char* DATE_KW;
+   static const char* DATUM_KW;
+   static const char* DECIMAL_DEGREES_PER_PIXEL_LAT;
+   static const char* DECIMAL_DEGREES_PER_PIXEL_LON;
+   static const char* DESCRIPTION_KW;
+   static const char* ELEVATION_ANGLE_KW;
+   static const char* ELEVATION_CELL_KW;
+   static const char* ELEVATION_SOURCE_KW;
+   static const char* ELLIPSE_CODE_KW;
+   static const char* ELLIPSE_NAME_KW;
+   static const char* ENABLED_KW;
+   static const char* ENABLE_CACHE_KW;
+   static const char* ENTRY_KW;
+   static const char* FALSE_EASTING_KW;
+   static const char* FALSE_NORTHING_KW;
+   static const char* FEATURE_NAME_KW;
+   static const char* FILENAME_KW;
+   static const char* FILEPATH_KW;
+   static const char* FILL_FLAG_KW;
+   static const char* GEOM_FILE_KW;
+   static const char* HEMISPHERE_KW;
+   static const char* HORIZONTAL_SIZE_KW;
+   static const char* ID_KW;
+   static const char* IMAGE_FILE_KW;
+   static const char* IMAGE_PATH_KW;
+   static const char* IMAGE_TYPE_KW;
+   static const char* IMAGE_DATE_KW;
+   static const char* IMAGE_FILE_SIZE_KW;
+   static const char* INPUT_RR_LEVEL_KW;
+   static const char* INTERLEAVE_TYPE_KW;
+   static const char* JULIAN_DAY_KW;
+   static const char* LAT_INCREMENT_KW;
+   static const char* LL_LAT_KW;
+   static const char* LL_LON_KW;
+   static const char* LR_LAT_KW;
+   static const char* LR_LON_KW;
+   static const char* LL_X_KW;
+   static const char* LL_Y_KW;
+   static const char* LR_X_KW;
+   static const char* LR_Y_KW;
+   static const char* LON_INCREMENT_KW;
+   static const char* MAJOR_AXIS_KW;
+   static const char* MAX_VALUE_KW;
+   static const char* MAX_ITERATIONS_KW;
+   static const char* MAX_QUADTREE_LEVELS_KW;
+   static const char* METADATA_TYPE_KW;
+   static const char* METERS_PER_PIXEL_X_KW;
+   static const char* METERS_PER_PIXEL_Y_KW;
+   static const char* MINOR_AXIS_KW;
+   static const char* MIN_VALUE_KW;
+   static const char* NULL_VALUE_KW;
+   static const char* NUMBER_BANDS_KW;
+   static const char* NUMBER_ENTRIES_KW;
+   static const char* NUMBER_INPUT_BANDS_KW;
+   static const char* NUMBER_INPUTS_KW;
+   static const char* NUMBER_OUTPUTS_KW;
+   static const char* NUMBER_OUTPUT_BANDS_KW;
+   static const char* NUMBER_LINES_KW;
+   static const char* NUMBER_REDUCED_RES_SETS_KW;
+   static const char* NUMBER_SAMPLES_KW;
+   static const char* ORIGIN_LATITUDE_KW;
+   static const char* ORIGIN_X_KW;
+   static const char* ORIGIN_Y_KW;
+   static const char* OUTPUT_FILE_KW;
+   static const char* OUTPUT_FILE_PREFIX_KW;
+   static const char* OUTPUT_FILE_EXTENSION_KW;
+   static const char* OVERVIEW_COMPRESSION_QUALITY_KW;
+   static const char* OVERVIEW_COMPRESSION_TYPE_KW;
+   static const char* OVERVIEW_FILE_KW;
+   static const char* PCS_CODE_KW;
+   static const char* PEN_COLOR_KW;
+   static const char* PHOTOMETRIC_KW;
+   static const char* PIXEL_TYPE_KW;
+   static const char* PLANAR_CONFIG_KW;
+   static const char* POINT_WIDTH_HEIGHT_KW;
+   static const char* PROJECTION_KW;
+   static const char* QUALITY_KW;
+   static const char* RADIOMETRY_KW;
+   static const char* REDUCED_RES_LEVEL_KW;
+   static const char* ROTATION_KW;
+   static const char* SCALAR_TYPE_KW;
+   static const char* SCALE_PER_PIXEL_X_KW;
+   static const char* SCALE_PER_PIXEL_Y_KW;
+   static const char* SCALE_FACTOR_KW;
+   static const char* SCALE_X_KW;
+   static const char* SCALE_Y_KW;
+   static const char* SCALE_FACTOR_X_KW;
+   static const char* SCALE_FACTOR_Y_KW;
+   static const char* STD_PARALLEL_1_KW;
+   static const char* STD_PARALLEL_2_KW;
+   static const char* THICKNESS_KW;
+   static const char* TIE_POINT_EASTING_KW;
+   static const char* TIE_POINT_NORTHING_KW;
+   static const char* TIE_POINT_X_KW;
+   static const char* TIE_POINT_Y_KW;
+   static const char* TIE_POINT_LAT_KW;
+   static const char* TIE_POINT_LON_KW;
+   static const char* TILE_SOURCE_KW;
+   static const char* TILE_TYPE_KW;
+   static const char* TILE_SIZE_X_KW;
+   static const char* TILE_SIZE_Y_KW;
+   static const char* TRANSLATION_X_KW;
+   static const char* TRANSLATION_Y_KW;
+   static const char* TYPE_KW;
+   static const char* UL_LAT_KW;
+   static const char* UL_LON_KW;
+   static const char* UNITS_KW;
+  
+   static const char* UR_LAT_KW;
+   static const char* UR_LON_KW;
+   static const char* UL_X_KW;
+   static const char* UL_Y_KW;
+   static const char* UR_X_KW;
+   static const char* UR_Y_KW;
+   static const char* VERTICAL_SIZE_KW;
+   static const char* ZONE_KW;
+   
+
+protected:
+   ossimKeywordNames();
+   ossimKeywordNames(const ossimKeywordNames& rhs);
+   const ossimKeywordNames& operator =(const ossimKeywordNames &rhs);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimLeastSquaresBilin.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimLeastSquaresBilin.cpp
new file mode 100644
index 0000000000..b4d1095f56
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimLeastSquaresBilin.cpp
@@ -0,0 +1,151 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com
+//
+// Description: Source code produced by Dave Knopp
+//
+//*******************************************************************
+//  $Id: ossimLeastSquaresBilin.cpp,v 1.4 2004/04/02 13:51:14 gpotts Exp $
+#include <iostream>  // for debugging
+using namespace std;
+#include <base/common/ossimLeastSquaresBilin.h>
+#include <base/context/ossimNotifyContext.h>
+
+ossimLeastSquaresBilin::ossimLeastSquaresBilin()
+    : bl_a(0.0)
+    , bl_b(0.0)
+    , bl_c(0.0)
+    , bl_d(0.0)
+    , AtA(NULL)
+    , Atb(NULL)
+{
+   // allocate normal system accumulation matrices
+   AtA = new NEWMAT::Matrix(4,4);
+   Atb = new NEWMAT::Matrix(4,1);
+   
+   // ensure initilization to zero
+   *AtA = 0.0;
+   *Atb = 0.0;
+   
+   return;
+}
+ossimLeastSquaresBilin::ossimLeastSquaresBilin(const ossimLeastSquaresBilin &rhs)
+{
+   // allocate normal system accumulation matrices
+   AtA = new NEWMAT::Matrix(4,4);
+   Atb = new NEWMAT::Matrix(4,1);
+
+   bl_a = rhs.bl_a;
+   bl_b = rhs.bl_b;
+   bl_c = rhs.bl_c;
+   bl_d = rhs.bl_d;
+   
+   *AtA  = *rhs.AtA;
+   *Atb  = *rhs.Atb;
+}
+
+ossimLeastSquaresBilin::~ossimLeastSquaresBilin()
+{
+   if(AtA)
+   {
+      delete AtA;
+      AtA = NULL;
+   }
+   if(Atb)
+   {
+      delete Atb;
+      Atb = NULL;
+   }
+}
+ossimLeastSquaresBilin & ossimLeastSquaresBilin::operator = (const ossimLeastSquaresBilin &rhs)
+{
+   bl_a    = rhs.bl_a;
+   bl_b    = rhs.bl_b;
+   bl_c    = rhs.bl_c;
+   bl_d    = rhs.bl_d;
+   
+   *AtA    = *rhs.AtA;
+   *Atb    = *rhs.Atb;
+   
+   return *this;
+}
+
+void ossimLeastSquaresBilin::clear()
+{
+   *AtA    = 0.0;
+   *Atb    = 0.0;  
+   bl_a    = 0.0;
+   bl_b    = 0.0;
+   bl_c    = 0.0;
+   bl_d    = 0.0;
+}
+
+void ossimLeastSquaresBilin::addSample(double xx, double yy, double zmea)
+{
+   // form normal system layer
+   NEWMAT::Matrix AtA_layer(4,1);
+   AtA_layer(1,1) = 1.0;
+   AtA_layer(2,1) = xx;
+   AtA_layer(3,1) = yy;
+   AtA_layer(4,1) = xx*yy;
+   
+   // accumulate layer into normal system
+   *AtA += AtA_layer * AtA_layer.t();
+   *Atb += AtA_layer * zmea;
+   
+}
+
+bool ossimLeastSquaresBilin::solveLS()
+{
+   NEWMAT::Matrix Soln(4,1);
+   Soln = AtA->i() * (*Atb);
+   bl_a = Soln(1,1);
+   bl_b = Soln(2,1);
+   bl_c = Soln(3,1);
+   bl_d = Soln(4,1);
+   
+   
+   return true;
+}
+
+bool ossimLeastSquaresBilin::getLSParms(double& pa,
+                                        double& pb_x,
+                                        double& pc_y,
+                                        double& pd_xy)const
+{
+   pa    = bl_a;
+   pb_x  = bl_b;
+   pc_y  = bl_c;
+   pd_xy = bl_d;
+   
+   return true;
+}
+
+void ossimLeastSquaresBilin::setLSParams(double pa,
+                                         double pb_x,
+                                         double pc_y,
+                                         double pd_xy)
+{
+   bl_a = pa;
+   bl_b = pb_x;
+   bl_c = pc_y;
+   bl_d = pd_xy;
+}
+
+                 
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimLeastSquaresBilin.h b/Utilities/OSSIM/ossim_core/base/common/ossimLeastSquaresBilin.h
new file mode 100644
index 0000000000..51866ce154
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimLeastSquaresBilin.h
@@ -0,0 +1,146 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com
+//
+// Description: Source code produced by Dave Knopp
+//
+//*******************************************************************
+//  $Id: ossimLeastSquaresBilin.h,v 1.4 2004/04/02 13:49:19 gpotts Exp $
+#ifndef    ossimLeastSquaresBilin_INCLUDE
+#define    ossimLeastSquaresBilin_INCLUDE
+#include <base/common/ossimConstants.h>
+#include <matrix/newmat.h>
+
+/** 
+ * @brief Provide 2D Least Squares Bilinear model fitting
+ * The math model is that of a bilinear surface of the form:
+@code
+z(x,y) = a + b*x + c*y + d*x*y
+@endcode
+ * The getLSParms() method returns parameter values which are the least
+ * squares solution associated with the samples added via addSample(). Note
+ * that it is necessary to add at least four sample to obtain a solution.
+ */
+
+class OSSIMDLLEXPORT ossimLeastSquaresBilin
+{
+public:
+
+   ossimLeastSquaresBilin(const ossimLeastSquaresBilin &);
+   /** 
+    * Instantiate as zero surface.
+    */
+   ossimLeastSquaresBilin();
+   
+   ossimLeastSquaresBilin & operator = (const ossimLeastSquaresBilin &);
+   
+   /**
+    * Free internal storage.
+    */
+   virtual ~ossimLeastSquaresBilin();
+   
+
+   /**
+    * Will clear everything and set it up to
+    * for another solve.  Just add points
+    * and call the solve method.
+    */
+   virtual void clear();
+
+   /**
+    * add a single data sample.
+    *
+    * @param xx "x" coordinate of sample location.
+    * @param yy "y"  "y" coordinate of sample location.
+    * @param zmea sample value measured at (xx,yy)
+    */
+   virtual void addSample(double x, double yy, double zmea);
+   
+   /**
+    * return LS solution parameters.
+    *
+    * @param pa set to constant coefficient.
+    * @param pb_x set to linear coefficient of "x"
+    * @param pc_y set to linear coefficient of "y"
+    * @param pd_xy set to cross coefficient of "x*y"
+    */
+   virtual bool getLSParms(double& pa, double& pb_x, double& pc_y, double& pd_xy)const;
+
+   /**
+    * @param pa set to constant coefficient.
+    * @param pb_x set to linear coefficient of "x"
+    * @param pc_y set to linear coefficient of "y"
+    * @param pd_xy set to cross coefficient of "x*y"
+    */
+   virtual void setLSParams(double pa, //constant
+                            double pb_x, // linear coefficient of x,
+                            double pc_y, // linear coefficient of y
+                            double pd_xy); // coefficient of x*y
+                           
+   /**
+    * interpolate LS-fit value at location (xx,yy) - returns z(xx,yy).
+    *
+    * @param xx "x" coordinate at which to interpolate.
+    * @param yy "y" "y" coordinate at which to interpolate.
+    * 
+    */
+   virtual inline double lsFitValue(double xx, double yy) const
+      {
+         return (bl_a + bl_b*xx + bl_c*yy + bl_d*xx*yy);
+      }
+   
+   /**
+    * compute least squares parameter solution - true if succesfull.
+    */
+   bool solveLS();
+   
+private:
+   /**
+    * constant term.
+    */
+   double bl_a;  
+
+   /**
+    * linear-X term.
+    */
+   double bl_b;
+
+   /**
+    * linear-Y term.
+    */
+   double bl_c;
+
+   /**
+    * cross-XY term
+    */
+   double bl_d;   
+
+   /**
+    * Normal system coefficient matrix.
+    */
+   NEWMAT::Matrix*  AtA;
+
+   /**
+    * Normal system RHS vector
+    */
+   NEWMAT::Matrix*  Atb;
+};
+
+#endif //  LeastSquaresBilinilin_INCL_
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimMutex.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimMutex.cpp
new file mode 100644
index 0000000000..c067345436
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimMutex.cpp
@@ -0,0 +1,54 @@
+//*************************************************************************
+// Copyright (C) 2004 Intelligence Data Sytems, Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+//**************************************************************************
+// $Id: ossimMutex.cpp,v 1.3 2005/11/07 22:06:07 dburken Exp $
+
+#include <base/common/ossimMutex.h>
+
+ossimMutex::ossimMutex()
+#ifdef OSSIM_HAS_OPEN_THREADS
+#  if OSSIM_HAS_OPEN_THREADS
+   : theMutex()
+#  endif
+#endif
+{}
+
+ossimMutex::~ossimMutex()
+{}
+
+int ossimMutex::lock()
+{
+#ifdef OSSIM_HAS_OPEN_THREADS
+#  if OSSIM_HAS_OPEN_THREADS
+   return theMutex.lock();
+#  endif
+#endif
+   return 0;
+}
+
+int ossimMutex::unlock()
+{
+#ifdef OSSIM_HAS_OPEN_THREADS
+#  if OSSIM_HAS_OPEN_THREADS
+   return theMutex.unlock();
+#  endif
+#endif
+   return 0;
+}
+
+int ossimMutex::trylock()
+{
+#ifdef OSSIM_HAS_OPEN_THREADS
+#  if OSSIM_HAS_OPEN_THREADS
+   return theMutex.trylock();
+#  endif
+#endif
+   return 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimMutex.h b/Utilities/OSSIM/ossim_core/base/common/ossimMutex.h
new file mode 100644
index 0000000000..132e7c3101
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimMutex.h
@@ -0,0 +1,77 @@
+//*************************************************************************
+// Copyright (C) 2004 Intelligence Data Sytems, Inc.  All rights reserved.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+//************************************************************************** 
+// $Id: ossimMutex.h,v 1.5 2005/11/07 22:06:07 dburken Exp $
+#ifndef ossimMutex_HEADER
+#define ossimMutex_HEADER
+
+#include <ossimConfig.h>  /* to pick up platform defines */
+#include <base/common/ossimReferenced.h>
+
+#ifdef OSSIM_HAS_OPEN_THREADS
+#  if OSSIM_HAS_OPEN_THREADS
+#    include <OpenThreads/Mutex>
+#  endif
+#endif
+
+/**
+ * ossimMutex is a wrapper around OpenThreads::Mutex to allow for builds with
+ * or without the package.
+ */
+class ossimMutex : public ossimReferenced
+{
+public:
+
+   /**
+    *  Constructor
+    */
+   ossimMutex();
+
+   /**
+    *  Destructor
+    */
+   ~ossimMutex();
+   
+    /**
+     *  Lock the mutex
+     *
+     *  @return 0 if normal, -1 if errno set, errno code otherwise.
+     *
+     *  @note If #ifdef OSSIM_HAS_OPEN_THREADS is not set, always returns 0.
+     */
+   int lock();
+
+    /**
+     *  Unlock the mutex
+     *
+     *  @return 0 if normal, -1 if errno set, errno code otherwise.
+     *
+     *  @note If #ifdef OSSIM_HAS_OPEN_THREADS is not set, always returns 0.
+     */
+   int unlock();
+
+    /**
+     *  Test if mutex can be locked.
+     *
+     *  @return 0 if normal, -1 if errno set, errno code otherwise.
+     *
+     *  @note If #ifdef OSSIM_HAS_OPEN_THREADS is not set, always returns 0.
+     */
+   int trylock();
+
+private:
+#ifdef OSSIM_HAS_OPEN_THREADS
+#  if OSSIM_HAS_OPEN_THREADS
+   OpenThreads::Mutex theMutex;
+#  endif
+#endif
+   
+};
+#endif /* ossimMutex_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimNBandLutDataObject.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimNBandLutDataObject.cpp
new file mode 100644
index 0000000000..de2f3c7907
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimNBandLutDataObject.cpp
@@ -0,0 +1,342 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class declaration for TiffWriter.
+//
+//*******************************************************************
+//  $Id: ossimNBandLutDataObject.cpp,v 1.7 2005/11/14 11:58:06 gpotts Exp $
+#include <sstream>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/common/ossimNBandLutDataObject.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimNBandLutDataObject, "ossimNBandLutDataObject", ossimObject);
+
+ostream& operator <<(ostream& out,
+                     const ossimNBandLutDataObject& lut)
+{
+   if(lut.theLut)
+   {
+      out << ossimKeywordNames::NUMBER_ENTRIES_KW << ": " << lut.theNumberOfEntries << std::endl;
+      out << ossimKeywordNames::NUMBER_BANDS_KW   << ": " << lut.theNumberOfBands << std::endl;
+      out << "null_pixel_index: " << lut.theNullPixelIndex << std::endl;
+      for(ossim_uint32 idx = 0; idx < lut.theNumberOfEntries; ++idx)
+      {
+         const ossimNBandLutDataObject::LUT_ENTRY_TYPE *bandPtr =lut[idx];
+         ossim_uint32 bandIdx = 0;
+         out << ossimKeywordNames::ENTRY_KW << idx << ": ";
+         for(bandIdx = 0; bandIdx < lut.theNumberOfBands; ++bandIdx)
+         {
+            out << bandPtr[bandIdx] << " ";
+         }
+         if(idx < (lut.theNumberOfEntries-1))
+         {
+            out << std::endl;
+         }
+      }
+   }
+   return out;
+}
+
+ossimNBandLutDataObject::ossimNBandLutDataObject(ossim_uint32 numberOfEntries,
+                                                 ossim_uint32 numberOfBands,
+                                                 ossimScalarType bandScalarType,
+                                                 ossim_int32 nullPixelIndex)
+   :theLut(0),
+    theNumberOfEntries(0),
+    theNumberOfBands(0),
+    theBandScalarType(bandScalarType),
+    theNullPixelIndex(nullPixelIndex)
+{
+   create(numberOfEntries, numberOfBands);
+}
+
+ossimNBandLutDataObject::ossimNBandLutDataObject(const ossimNBandLutDataObject& lut)
+   :theLut(0),
+    theNumberOfEntries(lut.theNumberOfEntries),
+    theNumberOfBands(lut.theNumberOfBands),
+    theBandScalarType(lut.theBandScalarType),
+    theNullPixelIndex(lut.theNullPixelIndex)
+{
+   *this = lut;
+   
+}
+
+ossimNBandLutDataObject::~ossimNBandLutDataObject()
+{
+   if(theLut)
+   {
+      delete [] theLut;
+      theLut = 0;
+   }
+   theNumberOfEntries = 0;
+   theNumberOfBands   = 0;
+}
+
+void ossimNBandLutDataObject::create(ossim_uint32 numberOfEntries,
+                                     ossim_uint32 numberOfBands)
+{
+   if(theLut)
+   {
+      delete [] theLut;
+      theLut = 0;
+   }
+   if(numberOfEntries&&numberOfBands)
+   {
+      theLut = new ossimNBandLutDataObject::LUT_ENTRY_TYPE[numberOfEntries*numberOfBands];
+      theNumberOfEntries = numberOfEntries;
+      theNumberOfBands   = numberOfBands;
+   }
+   else
+   {
+      theNumberOfEntries = 0;
+      theNumberOfBands   = 0;
+   }
+}
+
+ossim_uint32 ossimNBandLutDataObject::findIndex(ossimNBandLutDataObject::LUT_ENTRY_TYPE* bandValues)const
+{
+   ossim_float64 distance = 1.0/DBL_EPSILON; 
+   ossim_uint32  result   = 0;
+
+   if(theNumberOfEntries > 0)
+   {
+      ossim_uint32 idx = 0;
+      ossim_uint32 bandIdx = 0;
+      ossimNBandLutDataObject::LUT_ENTRY_TYPE* lutPtr = theLut;
+      for(idx = 0; idx < theNumberOfEntries; ++idx,lutPtr+=theNumberOfBands)
+      {
+         ossim_float64 sumSquare = 0.0;
+
+         for(bandIdx = 0; bandIdx < theNumberOfBands; ++bandIdx)
+         {
+            ossim_int64 delta = lutPtr[bandIdx] - bandValues[bandIdx];
+            sumSquare += (delta*delta);
+         }
+         if((ossimNBandLutDataObject::LUT_ENTRY_TYPE)sumSquare == 0)
+         {
+            return idx;
+         }
+         else if( sumSquare < distance)
+         {
+            result = idx;
+            distance = sumSquare;
+         }
+      }
+   }
+
+   return result;
+}
+
+void ossimNBandLutDataObject::clearLut()
+{
+   if(theLut)
+   {
+      memset(theLut, '\0', theNumberOfEntries*theNumberOfBands*sizeof(ossimNBandLutDataObject::LUT_ENTRY_TYPE));
+   }
+}
+
+void ossimNBandLutDataObject::getMinMax(ossim_uint32 band,
+                                        ossimNBandLutDataObject::LUT_ENTRY_TYPE& minValue,
+                                        ossimNBandLutDataObject::LUT_ENTRY_TYPE& maxValue)
+{
+   minValue = 0;
+   maxValue = 0;
+   ossim_uint32 idx = 0;
+   LUT_ENTRY_TYPE *bandPtr = theLut+theNumberOfBands;
+   if((band < theNumberOfBands)&&
+      (theNumberOfEntries > 0))
+   {
+      minValue = theLut[band];
+      maxValue = theLut[band];
+      
+      for(idx = 1; idx < theNumberOfEntries; ++idx,bandPtr+=theNumberOfBands)
+      {
+         if((ossim_int32)idx != theNullPixelIndex)
+         {
+            if(bandPtr[band] < minValue)
+            {
+               minValue = bandPtr[band];
+            }
+            if(bandPtr[band] > maxValue)
+            {
+               maxValue = bandPtr[band];
+            }
+         }
+      }
+   }
+}
+
+const ossimNBandLutDataObject& ossimNBandLutDataObject::operator =(const ossimNBandLutDataObject& lut)
+{
+   if(theNumberOfEntries != lut.theNumberOfEntries)
+   {
+      delete [] theLut;
+      theLut = 0;
+   }
+
+   theNullPixelIndex = lut.theNullPixelIndex;
+   theBandScalarType = lut.theBandScalarType;
+   create(lut.theNumberOfEntries,
+          lut.theNumberOfBands);
+
+   if(theLut)
+   {
+      memcpy(theLut, lut.theLut, (theNumberOfEntries*theNumberOfBands)*sizeof(ossimNBandLutDataObject::LUT_ENTRY_TYPE));
+   }
+
+   return *this;
+}
+
+bool ossimNBandLutDataObject::operator ==(const ossimNBandLutDataObject& lut)const
+{
+   if(theNumberOfEntries != lut.theNumberOfEntries)
+   {
+      return false;
+   }
+
+   if(!theLut && !lut.theLut) return true;
+   if(theNullPixelIndex != lut.theNullPixelIndex) return false;
+   if(theBandScalarType != lut.theBandScalarType) return false;
+   
+   if(theLut&&lut.theLut)
+   {
+      return (memcmp(theLut, lut.theLut, theNumberOfEntries*theNumberOfBands*sizeof(ossimNBandLutDataObject::LUT_ENTRY_TYPE)) == 0);
+   }
+   return false;
+}
+
+bool ossimNBandLutDataObject::saveState(ossimKeywordlist& kwl, const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           getClassName(),
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_ENTRIES_KW,
+           ossimString::toString(theNumberOfEntries).c_str(),
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_BANDS_KW,
+           theNumberOfBands,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::NULL_VALUE_KW,
+           theNullPixelIndex,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::SCALAR_TYPE_KW,
+           ossimScalarTypeLut::instance()->getEntryString(theBandScalarType),
+           true);
+          
+   ossimNBandLutDataObject::LUT_ENTRY_TYPE* lutPtr = theLut;
+   for(ossim_uint32 idx = 0; idx < theNumberOfEntries; ++idx, lutPtr+=theNumberOfBands)
+   {
+      ossimString newPrefix = ossimKeywordNames::ENTRY_KW;
+      newPrefix += ossimString::toString(idx);
+      std::ostringstream ostr;
+      ossim_uint32 bandIdx = 0;
+      for(bandIdx = 0; bandIdx < theNumberOfBands; ++bandIdx)
+      {
+         ostr << lutPtr[bandIdx]
+              << " ";
+      }
+      kwl.add(prefix,
+              newPrefix,
+              ostr.str().c_str(),
+              true);
+   }
+
+   return true;
+}
+
+bool ossimNBandLutDataObject::open(const ossimFilename& lutFile)
+{
+   ossimKeywordlist kwl;
+   kwl.addFile(lutFile);
+   
+   return loadState(kwl);
+}
+
+bool ossimNBandLutDataObject::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   const char* nullPixelIndex = kwl.find(prefix, ossimKeywordNames::NULL_VALUE_KW);
+   const char* lutFile = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   ossimKeywordlist fileLut;
+   const ossimKeywordlist* tempKwl = &kwl;
+   ossimString tempPrefix = prefix;
+
+   // check to see if we should open an external file
+   // if so point the fileLut to the one that we use
+   if(lutFile)
+   {
+      ossimFilename filename(lutFile);
+      if(filename.exists())
+      {
+         fileLut.addFile(filename.c_str());
+         tempKwl = &fileLut;
+         tempPrefix = "";
+      }
+   }
+
+   if(nullPixelIndex)
+   {
+      theNullPixelIndex = ossimString(nullPixelIndex).toInt32();
+   }
+   else
+   {
+      theNullPixelIndex = -1;
+   }
+   int scalar = ossimScalarTypeLut::instance()->getEntryNumber(kwl, prefix);
+
+   if (scalar != ossimLookUpTable::NOT_FOUND)
+   {
+      theBandScalarType = static_cast<ossimScalarType>(scalar);
+   }
+   const char* numberOfBands   = tempKwl->find(tempPrefix, ossimKeywordNames::NUMBER_BANDS_KW);
+   const char* numberOfEntries = tempKwl->find(tempPrefix, ossimKeywordNames::NUMBER_ENTRIES_KW);
+   
+   create(ossimString(numberOfEntries).toUInt32(),
+          ossimString(numberOfBands).toUInt32());
+   clearLut();
+   ossimNBandLutDataObject::LUT_ENTRY_TYPE* lutPtr = theLut;
+
+   if(lutPtr)
+   {
+      ossim_uint32 entryIdx;
+      ossim_uint32 bandIdx;
+      for(entryIdx = 0; entryIdx < theNumberOfEntries; ++entryIdx)
+      {
+         ossimString newPrefix = "entry";
+         newPrefix += ossimString::toString(entryIdx);
+         ossimString v = tempKwl->find(tempPrefix, newPrefix.c_str());
+         v = v.trim();
+         if(v != "")
+         {
+            std::istringstream istr(v);
+            
+            for(bandIdx = 0; bandIdx < theNumberOfBands; ++bandIdx)
+            {
+               if(!istr.fail())
+               {
+                  istr >> lutPtr[bandIdx];
+               }
+            }
+         }
+         lutPtr += theNumberOfBands;
+      }
+   }
+   
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimNBandLutDataObject.h b/Utilities/OSSIM/ossim_core/base/common/ossimNBandLutDataObject.h
new file mode 100644
index 0000000000..c4fc70999c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimNBandLutDataObject.h
@@ -0,0 +1,456 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LICENSE: LGPL See top level license file.
+// 
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimNBandLutDataObject.h,v 1.5 2005/09/06 16:23:41 gpotts Exp $
+#ifndef ossimNBandLutDataObject_HEADER
+#define ossimNBandLutDataObject_HEADER
+#include "base/common/ossimObject.h"
+#include "base/data_types/ossimFilename.h"
+#include <iostream>
+
+/**
+ * class ossimNBandLutDataObject
+ *
+ * Sample CADRG LUT taken from an arbitrary CADRG image entry.  This is a keywordlist
+ * support by the loadstate of this class.
+ *
+ * <pre>
+ * entry0:  25 39 116 
+ * entry1:  245 242 242 
+ * entry10:  92 89 115 
+ * entry100:  74 55 85 
+ * entry101:  233 165 53 
+ * entry102:  75 2 4 
+ * entry103:  162 118 42 
+ * entry104:  233 159 130 
+ * entry105:  189 129 40 
+ * entry106:  154 109 66 
+ * entry107:  145 97 85 
+ * entry108:  121 86 31 
+ * entry109:  238 151 118 
+ * entry11:  52 31 76 
+ * entry110:  239 167 42 
+ * entry111:  236 137 100 
+ * entry112:  179 112 88 
+ * entry113:  92 37 33 
+ * entry114:  121 66 24 
+ * entry115:  120 133 151 
+ * entry116:  76 92 192 
+ * entry117:  36 50 117 
+ * entry118:  57 75 191 
+ * entry119:  125 45 50 
+ * entry12:  235 217 204 
+ * entry120:  102 65 81 
+ * entry121:  172 148 199 
+ * entry122:  204 145 95 
+ * entry123:  81 19 5 
+ * entry124:  91 4 1 
+ * entry125:  109 54 31 
+ * entry126:  137 114 118 
+ * entry127:  230 150 52 
+ * entry128:  82 38 87 
+ * entry129:  190 120 76 
+ * entry13:  244 218 172 
+ * entry130:  170 109 45 
+ * entry131:  95 20 22 
+ * entry132:  150 80 61 
+ * entry133:  225 122 82 
+ * entry134:  122 37 16 
+ * entry135:  146 88 49 
+ * entry136:  122 94 122 
+ * entry137:  230 135 63 
+ * entry138:  137 73 75 
+ * entry139:  119 46 29 
+ * entry14:  189 167 141 
+ * entry140:  190 142 128 
+ * entry141:  242 216 187 
+ * entry142:  176 125 95 
+ * entry143:  193 117 143 
+ * entry144:  19 0 0 
+ * entry145:  12 1 42 
+ * entry146:  24 4 26 
+ * entry147:  38 40 52 
+ * entry148:  8 24 175 
+ * entry149:  40 23 45 
+ * entry15:  245 213 142 
+ * entry150:  39 11 58 
+ * entry151:  10 0 22 
+ * entry152:  236 148 41 
+ * entry153:  101 41 11 
+ * entry154:  230 113 67 
+ * entry155:  148 44 46 
+ * entry156:  225 144 133 
+ * entry157:  115 2 13 
+ * entry158:  159 79 49 
+ * entry159:  164 95 33 
+ * entry16:  246 241 205 
+ * entry160:  97 6 22 
+ * entry161:  175 90 133 
+ * entry162:  112 23 20 
+ * entry163:  105 22 6 
+ * entry164:  148 59 33 
+ * entry165:  215 118 104 
+ * entry166:  211 122 41 
+ * entry167:  233 129 34 
+ * entry168:  153 73 25 
+ * entry169:  208 102 39 
+ * entry17:  240 215 89 
+ * entry170:  206 101 133 
+ * entry171:  229 113 96 
+ * entry172:  127 16 25 
+ * entry173:  224 104 28 
+ * entry174:  171 76 74 
+ * entry175:  221 94 78 
+ * entry176:  229 86 94 
+ * entry177:  213 80 57 
+ * entry178:  161 44 36 
+ * entry179:  155 54 19 
+ * entry18:  115 92 157 
+ * entry180:  130 25 5 
+ * entry181:  150 29 24 
+ * entry182:  198 54 34 
+ * entry183:  224 61 70 
+ * entry184:  213 82 37 
+ * entry185:  186 28 31 
+ * entry186:  200 64 15 
+ * entry187:  110 2 2 
+ * entry188:  195 38 12 
+ * entry189:  151 6 8 
+ * entry19:  160 163 37 
+ * entry190:  193 13 10 
+ * entry191:  205 1 3 
+ * entry192:  44 62 193 
+ * entry193:  35 14 16 
+ * entry194:  15 30 118 
+ * entry195:  28 47 189 
+ * entry196:  25 3 80 
+ * entry197:  7 16 118 
+ * entry198:  33 10 6 
+ * entry199:  39 24 95 
+ * entry2:  216 212 237 
+ * entry20:  38 29 21 
+ * entry200:  82 58 159 
+ * entry201:  55 29 142 
+ * entry202:  33 4 23 
+ * entry203:  17 14 36 
+ * entry204:  58 26 41 
+ * entry205:  11 13 14 
+ * entry206:  74 87 85 
+ * entry207:  50 60 41 
+ * entry208:  119 123 98 
+ * entry209:  193 187 172 
+ * entry21:  208 202 156 
+ * entry210:  124 126 128 
+ * entry211:  47 68 84 
+ * entry212:  110 119 60 
+ * entry213:  63 145 121 
+ * entry214:  154 166 147 
+ * entry215:  107 156 104 
+ * entry22:  242 202 152 
+ * entry23:  168 148 140 
+ * entry24:  31 22 25 
+ * entry25:  245 205 114 
+ * entry26:  245 191 137 
+ * entry27:  175 161 172 
+ * entry28:  17 6 11 
+ * entry29:  172 170 137 
+ * entry3:  247 230 113 
+ * entry30:  51 27 20 
+ * entry31:  239 210 73 
+ * entry32:  185 176 129 
+ * entry33:  35 2 13 
+ * entry34:  60 52 51 
+ * entry35:  101 78 70 
+ * entry36:  141 124 101 
+ * entry37:  206 184 107 
+ * entry38:  244 174 106 
+ * entry39:  82 98 136 
+ * entry4:  246 231 132 
+ * entry40:  190 191 239 
+ * entry41:  241 188 161 
+ * entry42:  67 51 38 
+ * entry43:  244 184 122 
+ * entry44:  211 201 142 
+ * entry45:  61 27 16 
+ * entry46:  182 182 82 
+ * entry47:  243 188 87 
+ * entry48:  86 83 60 
+ * entry49:  61 40 43 
+ * entry5:  204 198 166 
+ * entry50:  146 141 93 
+ * entry51:  44 4 4 
+ * entry52:  231 210 51 
+ * entry53:  85 74 39 
+ * entry54:  197 169 127 
+ * entry55:  182 151 60 
+ * entry56:  121 98 73 
+ * entry57:  243 182 145 
+ * entry58:  58 18 21 
+ * entry59:  241 157 91 
+ * entry6:  2 0 2 
+ * entry60:  59 4 1 
+ * entry61:  155 162 223 
+ * entry62:  154 133 80 
+ * entry63:  73 21 16 
+ * entry64:  195 183 116 
+ * entry65:  76 51 29 
+ * entry66:  234 181 63 
+ * entry67:  58 59 98 
+ * entry68:  42 22 79 
+ * entry69:  134 143 219 
+ * entry7:  204 204 239 
+ * entry70:  106 117 205 
+ * entry71:  48 65 117 
+ * entry72:  63 54 117 
+ * entry73:  125 93 62 
+ * entry74:  137 138 41 
+ * entry75:  104 68 59 
+ * entry76:  113 99 41 
+ * entry77:  76 30 11 
+ * entry78:  239 184 48 
+ * entry79:  161 129 98 
+ * entry8:  31 4 66 
+ * entry80:  241 170 126 
+ * entry81:  145 109 105 
+ * entry82:  207 163 116 
+ * entry83:  79 41 40 
+ * entry84:  175 138 41 
+ * entry85:  10 0 56 
+ * entry86:  180 151 77 
+ * entry87:  72 12 24 
+ * entry88:  242 154 105 
+ * entry89:  91 26 15 
+ * entry9:  246 238 162 
+ * entry90:  160 118 53 
+ * entry91:  228 166 141 
+ * entry92:  231 160 69 
+ * entry93:  61 2 11 
+ * entry94:  132 83 60 
+ * entry95:  86 46 24 
+ * entry96:  243 143 86 
+ * entry97:  108 60 46 
+ * entry98:  109 76 38 
+ * entry99:  96 86 84 
+ * null_value:  -1
+ * number_bands:  3
+ * number_entries:  216
+ * scalar_type:  ossim_uint8
+ * type:  ossimNBandLutDataObject
+ *
+ *
+ * NOTES:
+ * 
+ * - The null_value keyword above is the index in the lut that correspnds to an invalid pixel value.
+ * - Each entry will have number_bands.  SO if number of bands is 3 then there will be 3 values
+ *   Where the first value is for band 1, ... etc.
+ * - scalar_type is a hint as to the scalar type of the entries.  Is the resulting lut for 8 bit, 16 bit , etc data.
+ * - You should always use the LUT_ENTRY_TYPE when getting values from the lut.  This value could change to an
+ *   ossim_float32 precision and if you use the LUT_ENTRY_TYPE then your code will not have to change.
+ *   
+ * </pre>
+ */
+class OSSIM_DLL ossimNBandLutDataObject : public ossimObject
+{
+public:
+   
+   typedef ossim_int32 LUT_ENTRY_TYPE;
+   
+   friend std::ostream& operator <<(std::ostream& out,
+                                    const ossimNBandLutDataObject& lut);
+   /*!
+    * Will allocate 256 values for the color table
+    */
+   ossimNBandLutDataObject(ossim_uint32 numberOfEntries=0,
+                           ossim_uint32 numberOfBands=0,
+                           ossimScalarType bandScalarType = OSSIM_UINT8,
+                           ossim_int32 nullPixelIndex=-1);
+   ossimNBandLutDataObject(const ossimNBandLutDataObject& lut);
+   virtual ~ossimNBandLutDataObject();
+   void create(ossim_uint32 numberOfEntries,
+               ossim_uint32 numberOfBands=3);
+   const LUT_ENTRY_TYPE* operator[](ossim_uint32 idx)const
+   {
+      if(theLut)
+      {
+         return &theLut[idx*theNumberOfBands];
+      }
+      
+      return 0;
+   }
+   LUT_ENTRY_TYPE* operator[](ossim_uint32 idx)
+   {
+      if(theLut)
+      {
+         return &theLut[idx*theNumberOfBands];
+      }
+      
+      return 0;
+   }
+   const LUT_ENTRY_TYPE* operator[](ossim_int32 idx)const
+   {
+      if(theLut)
+      {
+         return &theLut[idx*theNumberOfBands];
+      }
+      
+      return 0;
+   }
+   LUT_ENTRY_TYPE* operator[](ossim_int32 idx)
+   {
+      if(theLut)
+      {
+         return &theLut[idx*theNumberOfBands];
+      }
+      
+      return 0;
+   }
+   const LUT_ENTRY_TYPE* operator[](double normalizedIndex)const
+   {
+      int idx = int(normalizedIndex*theNumberOfEntries);
+      if (idx < 0)
+      {
+         idx = 0;
+      }
+      return (*this)[idx];
+   }
+
+   /**
+    * @param normalizedIndex  If a double precision value is passed in then it is
+    *                         assumed to be in normalized space where the value ranges from 0.0 to 1.0
+    * @return the starting address of the band values.
+    */ 
+   LUT_ENTRY_TYPE* operator[](double normalizedIndex)
+   {
+      ossim_uint32 idx = int(normalizedIndex*(theNumberOfEntries-1));
+      if (idx >= theNumberOfEntries)
+      {
+         idx = theNumberOfEntries-1;
+      }
+      return (*this)[idx];
+   }
+   
+   bool hasNullPixelIndex()const
+   {
+      return (theNullPixelIndex >= 0);
+   }
+   /**
+    * Will return the min max value for a given band
+    *
+    * @param band band number to query.  This is 0 based so the first band
+    *        is indicated by the value of 0.
+    * @param minValue is the minimum value returned for the passed in band
+    * @param maxValue is the maximum value returned for the passed in band
+    */
+   void getMinMax(ossim_uint32 band,
+                  LUT_ENTRY_TYPE& minValue,
+                  LUT_ENTRY_TYPE& maxValue);
+
+   /**
+    * Allows you to specify which entry is to be designated as an invalid
+    * entry.  Note: setting this to -1 indicates no null entry is set.
+    *
+    * @param idx is the entry number that will be used for the null value
+    */
+   void setNullPixelIndex(ossim_int32 idx){theNullPixelIndex = idx;}
+
+   /**
+    * @return Return either a positive value indicating the entry designated for
+    *         a null pixel value or a -1 to say no null pixel has been designated
+    *         yet.
+    */ 
+   ossim_int32 getNullPixelIndex()const{return theNullPixelIndex;}
+
+   /**
+    * @return Return the number of bands this lut is indexed for.
+    */ 
+   ossim_uint32 getNumberOfBands()const{return theNumberOfBands;}
+
+   /**
+    * @return Return the number of entries in the lut.
+    */ 
+   ossim_uint32 getNumberOfEntries()const{return theNumberOfEntries;}
+
+   /**
+    * This method gives you a way to find an entry index closest to the passed in
+    * band values.
+    * 
+    * @param values Is an array of band values.  This array must be equal to the number
+    *        of bands for the lut.
+    * @return Returns the nearest index to the passed in value.  
+    */ 
+   ossim_uint32 findIndex(ossim_int32* values)const;
+
+   /**
+    * Will do a simple memset to '\0' all 
+    */ 
+   void clearLut();
+   /**
+    * does a deep copy from the passed in lut to the object.
+    *
+    * @param lut The lut to copy.
+    */ 
+   const ossimNBandLutDataObject& operator =(const ossimNBandLutDataObject& lut);
+
+   /**
+    * Determines if the state of this lut is identical to the passed in lut
+    *
+    * @param lut Checks equality of the this object to the lut parameter.
+    * @return True if equal and false otherwise
+    */ 
+   bool operator ==(const ossimNBandLutDataObject& lut)const;
+
+   /**
+    * Reads in an external lut file.  The external file is in a keywordlist format specified by the saveState.
+    */ 
+   bool open(const ossimFilename& lutFile);
+
+   /**
+    * <pre>
+    * 
+    * Keywords:
+    *  
+    * entry0:
+    * entry1:
+    * :
+    * entry<number_entries-1>:
+    * null_value:  -1
+    * number_bands:  3
+    * number_entries:  216
+    * scalar_type:  ossim_uint8
+    * type:  ossimNBandLutDataObject
+    *
+    * Where entry<idx> is repeasted for each entry number where idx start from 0 and goes to number_entries-1
+    * each entry must have number_bands values.
+    * </pre>
+    *
+    * @param kwl The keyword list to store the keywords to.  Each keyword could be prefixed by an optional
+    *            prefix parameter.
+    * @param prefix The optional prefix parameter used to prefix each keyword.
+    * 
+    */ 
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0)const;
+
+   
+   /**
+    * Loads the state of the object by reading in the keywords listed in the save state.
+    *
+    * @param kwl The keywordlist to extract the classes keywords from to restore its state.
+    * @param prefix  Optional prefix value used to prefix each keyword.
+    */ 
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+protected:
+   LUT_ENTRY_TYPE *theLut;
+   ossim_uint32    theNumberOfEntries;
+   ossim_uint32    theNumberOfBands;
+   ossimScalarType theBandScalarType;
+   ossim_int32     theNullPixelIndex;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimObject.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimObject.cpp
new file mode 100644
index 0000000000..7c17800421
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimObject.cpp
@@ -0,0 +1,117 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimObject.cpp,v 1.18 2005/10/14 13:26:01 dburken Exp $
+#include <base/common/ossimObject.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF(ossimObject, "ossimObject")
+
+ossimObject::ossimObject()
+{}
+
+ossimObject::~ossimObject()
+{
+}
+   
+ossimObject* ossimObject::dup()const
+{
+   ossimObject* result = NULL;
+   ossimKeywordlist kwl;
+
+   saveState(kwl);
+   
+   result = ossimObjectFactoryRegistry::instance()->createObject(kwl);
+
+   if(!result)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "dup() not implemented for object = "
+         << getClassName() << ". Please implement!\n";
+   }
+   
+   return result;
+}
+
+ossimString ossimObject::getShortName()const
+{
+   return getClassName();
+}
+
+ossimString ossimObject::getLongName()const
+{
+   return getClassName();
+}
+
+ossimString ossimObject::getDescription()const
+{
+   return getLongName();
+}
+
+
+ossimString ossimObject::getClassName()const
+{
+   return TYPE_NAME(this);
+}
+
+RTTItypeid ossimObject::getType()const
+{
+   return TYPE_INFO(this);
+}
+
+bool ossimObject::canCastTo(ossimObject* obj)const
+{
+   if(obj)
+   {
+      return obj->getType().can_cast(this->getType());
+   }
+   
+   return false;
+}
+
+bool ossimObject::canCastTo(const ossimString& parentClassName)const
+{
+   return (getType().find_baseclass(parentClassName.c_str()) !=
+           getType().null_type());
+}
+
+bool ossimObject::canCastTo(const RTTItypeid& id)const
+{
+   return id.can_cast(this->getType());
+}
+
+bool ossimObject::saveState(ossimKeywordlist& kwl,
+                            const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           getClassName(),
+           true);
+
+   return true;
+}
+
+bool ossimObject::loadState(const ossimKeywordlist&, const char*)
+{
+   return true;
+}
+
+std::ostream& ossimObject::print(std::ostream& out) const
+{
+   return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const ossimObject& obj)
+{
+   return obj.print(out);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimObject.h b/Utilities/OSSIM/ossim_core/base/common/ossimObject.h
new file mode 100644
index 0000000000..f72445e372
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimObject.h
@@ -0,0 +1,88 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: Base class for ossim objects.
+//
+//*************************************************************************
+// $Id: ossimObject.h,v 1.25 2005/06/07 17:57:04 dburken Exp $
+
+#ifndef ossimObject_HEADER
+#define ossimObject_HEADER
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimReferenced.h>
+#include <base/data_types/ossimString.h>
+#include <base/common/ossimRtti.h>
+#include <iostream>
+
+class ossimKeywordlist;
+
+class OSSIMDLLEXPORT ossimObject : public ossimReferenced
+{
+public:
+   ossimObject();
+   virtual ~ossimObject();
+   
+   virtual ossimObject* dup() const;
+   
+   virtual ossimString getShortName()   const;
+   virtual ossimString getLongName()    const;
+   virtual ossimString getDescription() const;
+   virtual ossimString getClassName()   const;
+   
+   /*!
+    * Will return the type of this class in an RTTI format.
+    */
+   virtual RTTItypeid getType() const;
+
+   virtual bool canCastTo(ossimObject* obj) const;
+   
+   virtual bool canCastTo(const RTTItypeid& id) const;
+   
+   /*!
+    * Will use RTTI to search the derived classes to see if it derives from
+    * the passed in type.  If so then this object can be casted to the
+    * passed in class name.
+    */
+   virtual bool canCastTo(const ossimString& parentClassName) const;
+
+   /*!
+    * Method to save the state of the object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   /*!
+    * Method to the load (recreate) the state of the object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /**
+    * Generic print method.  Derived classes should re-implement as they see
+    * fit.
+    * 
+    * @return std::ostream&
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+   /**
+    * @note  Since the print method is virtual, derived classes only need
+    *        to implement that, not an addition operator<<.
+    */
+   friend OSSIMDLLEXPORT std::ostream& operator<<(std::ostream& out,
+                                                  const ossimObject& obj);
+
+ protected:
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimObject_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimOutputSource.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimOutputSource.cpp
new file mode 100644
index 0000000000..337bd27b19
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimOutputSource.cpp
@@ -0,0 +1,15 @@
+#include "ossimOutputSource.h"
+
+RTTI_DEF1(ossimOutputSource, "ossimOutputSource", ossimSource);
+
+bool ossimOutputSource::saveState(ossimKeywordlist& kwl,
+                                  const char* prefix)const
+{
+   return ossimSource::saveState(kwl, prefix);
+}
+
+bool ossimOutputSource::loadState(const ossimKeywordlist& kwl,
+                                  const char* prefix)
+{
+   return ossimSource::loadState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimOutputSource.h b/Utilities/OSSIM/ossim_core/base/common/ossimOutputSource.h
new file mode 100644
index 0000000000..edb83e0206
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimOutputSource.h
@@ -0,0 +1,107 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for ossimImageWriter
+//*******************************************************************
+//  $Id: ossimOutputSource.h,v 1.11 2003/05/13 11:31:01 dburken Exp $
+//
+#ifndef ossimOutputSource_HEADER
+#define ossimOutputSource_HEADER
+#include "base/common/ossimConstants.h"
+#include "base/common/ossimSource.h"
+#include "base/common/ossimCommon.h"
+
+class OSSIMDLLEXPORT ossimOutputSource : public ossimSource
+{
+public:
+   ossimOutputSource(ossimObject* owner=NULL)
+      :ossimSource(owner)
+      {}
+   ossimOutputSource(ossimObject* owner,
+                     ossim_uint32 inputListSize,
+                     ossim_uint32 outputListSize,
+                     bool inputListIsFixedFlag=true,
+                     bool outputListIsFixedFlag=true)
+      :ossimSource(owner,
+                   inputListSize,
+                   outputListSize,
+                   inputListIsFixedFlag,
+                  outputListIsFixedFlag)
+      {
+      }
+
+   virtual ~ossimOutputSource(){}
+   
+   virtual bool isOpen()const = 0;
+   
+   /*!
+    * Allows a generic interface to open a consumer for writing.  If
+    * you are a display writer then you would probably show the window or
+    * init the device context for writing.
+    */
+   virtual bool open()=0;
+
+   /*!
+    * Will set the output name and open the output device.
+    */
+   virtual bool open(const ossimString& outputName)
+      {
+         setOutputName(outputName);
+         return open();
+      }
+   
+   /*!
+    * This is a generic interface to allow one to set the output name of
+    * the writer.  If its a Visual display this could be used to
+    * set the title.  If this is a file output then this could be a
+    * directory or a file name.
+    */
+  virtual void setOutputName(const ossimString& outputName)
+  {
+    theOutputName = outputName;
+  }
+
+  virtual const ossimString& getOutputName()
+  {
+    return theOutputName;
+  }
+   /*!
+    * Generic interface to allow one to close a consumer.  For displays
+    * this might minimize the window and free up internal pointers for
+    * file writers it will make sure the file stream is closed and flushed.
+    */
+   virtual void close()=0;
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+protected:
+  ossimString theOutputName;
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimPool.h b/Utilities/OSSIM/ossim_core/base/common/ossimPool.h
new file mode 100644
index 0000000000..8c3ee640c3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimPool.h
@@ -0,0 +1,151 @@
+//********************************************************************
+// Copyright (C) 2004 Intelligence-data, Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts
+//
+//**********************************************************************
+// $Id: ossimPool.h,v 1.2 2004/04/20 21:26:05 dburken Exp $
+#ifndef ossimPool_HEADER
+#define ossimPool_HEADER
+#include <iostream>
+#include <vector>
+#include <exception>
+#include <stdexcept>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimPoolObject.h>
+#include <base/context/ossimNotifyContext.h>
+
+#define OSSIM_DEFAULT_POOL_SIZE (ossim_uint32)10
+
+/**
+ * Container pool to be used for things like threads.
+ */
+template <class T>
+class ossimPool
+{
+ public:
+   /**
+    * Contructor
+    * @param n Number of pooled objects to create.
+    */
+   ossimPool(ossim_uint32 n=OSSIM_DEFAULT_POOL_SIZE) throw(std::bad_alloc)
+      : thePool(n)
+   {
+      for(ossim_uint32 idx = 0; idx < n; ++idx)
+      {
+         try
+         {
+               ossimPoolObject<T>* poolObject = new ossimPoolObject<T>();
+               poolObject->theAvailableFlag = true;
+               poolObject->theObjectPtr = new T();
+               thePool[idx] = poolObject;
+         }
+         catch(std::bad_alloc)
+         {
+            ossimNotify(ossimNotifyLevel_FATAL)
+               << "FATAL ossimPool::ossimPool(): Bad allocation" << endl;
+         }
+      }
+   }
+
+   /**
+    * Destructor
+    */
+   ~ossimPool()
+   {
+      thePool.clear();
+   }
+
+   /**
+    * @return A pooled object of type T*.  Will return null if the pool is
+    * used up or pool size is zero.
+    */
+   T* checkout()
+   {
+      T* t = NULL;
+      
+      theCriticalSectionMutex.lock();
+      for (ossim_uint32 idx = 0; idx < thePool.size(); ++idx)
+      {
+         if (thePool[idx]->theAvailableFlag == true)
+         {
+            thePool[idx]->theAvailableFlag = false;
+            t = thePool[idx]->theObjectPtr;
+            break;
+         }
+      }
+      theCriticalSectionMutex.unlock();
+      return t;
+   }
+
+   /**
+    * Resets and eturns object to the pool.
+    * @param obj Object to be returned to the pool.
+    * 
+    * @note The object is required to have a "reset()" method.
+    *
+    * @return Returns void unless object was not from pool then throws
+    * a std::out_of_range error.
+    */
+   void checkin(T* obj) throw(std::out_of_range)
+   {
+      theCriticalSectionMutex.lock();
+      for (ossim_uint32 idx = 0; idx < thePool.size(); ++idx)
+      {
+         if (obj == thePool[idx]->theObjectPtr)
+         {
+            obj->reset();
+            thePool[idx]->theAvailableFlag = true;
+            theCriticalSectionMutex.unlock();
+            return;
+         }
+      }
+      
+      theCriticalSectionMutex.unlock();
+      throw std::out_of_range(string("ossimPool<T>::checkin Error Object not managed by this pool!"));
+   }
+
+   /**
+    * Outputs object addresses and theAvailableFlag.
+    */
+   std::ostream& print(std::ostream& out) const
+   {
+      for (ossim_uint32 idx = 0; idx < thePool.size(); ++idx)
+      {
+         out << "obj address:  " << (hex) << thePool[idx]->theObjectPtr
+             << " is "
+             << (thePool[idx]->theAvailableFlag ? "available":"unavailable")
+             << endl;
+      } 
+      return out;
+   }
+   
+   template <class C> friend std::ostream& operator<<(std::ostream& out,
+                                                      const ossimPool<C>& obj)
+   {
+      return obj.print(out);
+   }
+
+protected:
+   
+   std::vector<ossimPoolObject<T>*> thePool;
+};
+
+#endif /* #ifndef ossimPool_HEADER */
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimPoolObject.h b/Utilities/OSSIM/ossim_core/base/common/ossimPoolObject.h
new file mode 100644
index 0000000000..2fce19ab62
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimPoolObject.h
@@ -0,0 +1,49 @@
+//********************************************************************
+// Copyright (C) 2004 Intelligence-data, Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken
+//
+//**********************************************************************
+// $Id: ossimPoolObject.h,v 1.1 2004/04/20 21:26:05 dburken Exp $
+#ifndef ossimPoolObject_HEADER
+#define ossimPoolObject_HEADER
+
+
+/**
+ * Templated container for an object pointer and a flag.
+ */
+template <class T>
+class ossimPoolObject
+{
+ public:
+   ~ossimPoolObject()
+   {
+      if(theObjectPtr)
+      {
+         cout << "deleting obj:  " << (hex) << theObjectPtr << endl;
+         delete theObjectPtr;
+         theObjectPtr = NULL;
+      }
+      theAvailableFlag = false;  
+   }
+
+
+   bool theAvailableFlag;
+   T*   theObjectPtr;
+};
+#endif /* #ifndef ossimPoolObject_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimPreferences.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimPreferences.cpp
new file mode 100644
index 0000000000..81d332871b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimPreferences.cpp
@@ -0,0 +1,241 @@
+//*****************************************************************************
+// FILE: ossimPreferences.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimPreferences. This class provides
+//   a static keywordlist for global preferences. Objects needing access to
+//   application-wide global parameters shall do so through this class.
+//
+// SOFTWARE HISTORY:
+//>
+//   23Apr2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+
+#include <stdlib.h>
+#include <iostream>
+using namespace std;
+
+#include <base/common/ossimPreferences.h>
+#include <base/context/ossimNotifyContext.h>
+
+//RTTI_DEF1(ossimPreferences, "ossimPreferences", ossimObject)
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include "base/common/ossimTrace.h"
+static ossimTrace traceExec  ("ossimPreferences:exec");
+static ossimTrace traceDebug ("ossimPreferences:debug");
+
+static const char* PREF_FILE_ENV_VAR_NAME = "OSSIM_PREFS_FILE";
+
+ossimPreferences* ossimPreferences::theInstance = NULL;
+
+ossimPreferences::ossimPreferences()
+{
+   loadPreferences();
+}
+
+ossimPreferences::~ossimPreferences()
+{
+        theInstance = NULL;
+}
+
+/*!****************************************************************************
+ * METHOD: ossimPreferences::instance()
+ *  
+ *  This is the method by which run-time objects access this singleton instance
+ *  
+ *****************************************************************************/
+ossimPreferences* ossimPreferences::instance()
+{
+   /*!
+    * Simply return the instance if already created:
+    */
+   if (theInstance)
+      return theInstance;
+
+   /*!
+    * Create the static instance of this class:
+    */
+   theInstance = new ossimPreferences();
+
+   return theInstance;
+}
+
+/*!****************************************************************************
+ * METHOD: loadPreferences()
+ *  
+ *  Loads the preferences file specified in the runtime environment.
+ *  
+ *****************************************************************************/
+bool ossimPreferences::loadPreferences()
+{
+   static const char MODULE[] = "ossimPreferences::loadPreferences()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << " entering...\n";
+
+   bool parsed_ok = false;
+   
+   /*!
+    * Fetch preferences file name from environment:
+    */
+   char* pref_filename = getenv(PREF_FILE_ENV_VAR_NAME);
+
+   if (pref_filename)
+   {
+      /*!
+       * Load the preferences file into the static keywordlist object:
+       */
+      thePrefFilename = pref_filename;
+      parsed_ok = theKWL.addFile(pref_filename);
+
+      /*!
+       * Check for error opening KWL:
+       */
+      if (!parsed_ok)
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING: " << MODULE << ", an error was encountered loading the prefererences "
+                                            << "file at \"" << thePrefFilename << "\" as specified by the "
+                                            << "environment variable \"" << PREF_FILE_ENV_VAR_NAME << "\"."
+                                            << "Preferences were not loaded.\n";
+      }
+   }
+
+   else
+   {
+//       if (traceDebug())
+//       {
+//          // No ENV var found. Print warning:
+//          CLOG << "WARNING: the preferences file environment variable \""
+//               << PREF_FILE_ENV_VAR_NAME << "\" is not defined. No preferences "
+//               << "were loaded. The environment variable should be set to "
+//               << "the full path to the preferences keywordlist file desired."
+//               << endl;
+//       }
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << "returning...\n";
+   return parsed_ok;
+}
+
+/*!****************************************************************************
+ * METHOD: loadPreferences(filename)
+ *  
+ *  Loads the preferences file specified in the arg.
+ *  
+ *****************************************************************************/
+bool ossimPreferences::loadPreferences(const ossimFilename& pathname)
+{
+   static const char MODULE[] = "ossimPreferences::loadPreferences(filename)";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << ", entering...\n";
+
+   bool parsed_ok;
+
+   /*!
+    * First clear the existing KWL:
+    */
+   theKWL.clear();
+   theInstanceIsModified = true;
+   
+   /*!
+    * Load the preferences file into the static keywordlist object:
+    */
+   thePrefFilename = pathname;
+   parsed_ok = theKWL.addFile(pathname);
+
+   /*!
+    * Check for error opening KWL:
+    */
+   if (!parsed_ok)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING: " << MODULE << ", an error was encountered loading the prefererences "
+                                         << "file at \"" << pathname << "\". Preferences were not "
+                                         << "loaded.\n";
+   }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE<< ", returning...\n";
+   return parsed_ok;
+}
+
+/*!****************************************************************************
+ * METHOD: ossimPreferences::savePreferences()
+ *  
+ *  Saves KWL to the current filename.
+ *  
+ *****************************************************************************/
+bool ossimPreferences::savePreferences() const
+{
+   static const char MODULE[] = "ossimPreferences::savePreferences()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << ", entering...\n";
+   
+   bool success = true;
+   
+   /*!
+    * Save the file to current preferences filename:
+    */
+   if (theInstanceIsModified)
+   {
+      theKWL.write(thePrefFilename);
+      theInstanceIsModified = false;
+   }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG:" << MODULE << ", returning...\n";
+   return success;
+}
+
+/*!****************************************************************************
+ * METHOD: ossimPreferences::savePreferences(filename)
+ *  
+ *  Saves KWL to the specified filename.
+ *  
+ *****************************************************************************/
+bool ossimPreferences::savePreferences(const ossimFilename& pathname)
+{
+   static const char MODULE[] = "ossimPreferences::savePreferences()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: "<< MODULE << ", entering...\n";
+   
+   bool success = true;
+   
+   /*!
+    * Save the file to the specified preferences filename:
+    */
+   theKWL.write(pathname);
+
+   thePrefFilename = pathname;
+   theInstanceIsModified = false;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << ", returning...\n";
+   return success;
+}
+
+void ossimPreferences::addPreference(const char* key, const char* value)
+{
+   theKWL.add(key, value, true);
+   theInstanceIsModified = true;
+}
+
+void ossimPreferences::addPreferences(const ossimKeywordlist& kwl,
+                                      const char* prefix,
+                                      bool stripPrefix)
+{
+   theKWL.add(kwl, prefix, stripPrefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimPreferences.h b/Utilities/OSSIM/ossim_core/base/common/ossimPreferences.h
new file mode 100644
index 0000000000..359286998d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimPreferences.h
@@ -0,0 +1,116 @@
+//*****************************************************************************
+// FILE: ossimPreferences.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimPreferences. This class provides
+//   a static keywordlist for global preferences. Objects needing access to
+//   application-wide global parameters shall do so through this class.
+//
+// SOFTWARE HISTORY:
+//>
+//   23Apr2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+
+#ifndef ossimPreferences_HEADER
+#define ossimPreferences_HEADER
+
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/common/ossimObject.h"
+
+
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimPreferences
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimPreferences
+{
+public:
+   /*!
+    * METHOD: instance()
+    * The static singleton instance of this object is accessed via this method:
+    */
+   static ossimPreferences* instance();
+
+   /*!
+    * METHOD: loadPreferences()
+    * These methods clear the current preferences and load either the default
+    * preferences file or the specified file. Returns TRUE if loaded properly:
+    */
+   bool loadPreferences();
+   bool loadPreferences(const ossimFilename& pathname);
+
+   /*!
+    * METHOD: savePrefences()
+    * This method permits saving the preferences file to the default location
+    * or to a specified location:
+    */
+   bool savePreferences() const;
+   bool savePreferences(const ossimFilename& pathname);
+
+   /*!
+    * METHOD: findPreference()
+    * Performs a lookup for the specified keyword in the preferences KWL:
+    */
+   const char* findPreference(const char* key) const {return theKWL.find(key);}
+
+
+   /*!
+    * METHOD: addPreference()
+    * Inserts keyword/value pair into the in-memory preferences KWL. It does
+    * save to disk. App must do a savePreferences() for changes to be saved.
+    */
+   void addPreference(const char* key,
+                      const char* value);
+
+   /*!
+    * METHOD: preferencesKWL()
+    * An alternative to utilizing findPreference(), for objects derived from
+    * ossimObject, is to access the preferences KWL with this method
+    * (typically during construction) and provide it to the object's
+    * loadState() method.
+    */
+   const ossimKeywordlist& preferencesKWL() const { return theKWL; }
+
+   void addPreferences(const ossimKeywordlist& kwl,
+                       const char* prefix=0,
+                       bool stripPrefix=true);
+   
+protected:
+   /*!
+    * Override the compiler default constructors:
+    */
+   ossimPreferences();
+   ossimPreferences(const ossimPreferences&) {}
+
+   ~ossimPreferences();
+   void operator = (const ossimPreferences&) const {}
+
+   static ossimPreferences* theInstance;
+   ossimKeywordlist         theKWL;
+   ossimFilename            thePrefFilename;
+   mutable bool             theInstanceIsModified;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimProcessInterface.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimProcessInterface.cpp
new file mode 100644
index 0000000000..ee23dabf6b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimProcessInterface.cpp
@@ -0,0 +1,143 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimProcessInterface.cpp,v 1.8 2004/10/06 15:33:40 dburken Exp $
+#include "ossimProcessInterface.h"
+#include "base/common/events/ossimListenerManager.h"
+
+using namespace std;
+
+RTTI_DEF(ossimProcessInterface, "ossimProcessInterface");
+
+ossimProcessInterface::ossimProcessInterface()
+   :thePercentComplete(0.0),
+    theProcessStatus(PROCESS_STATUS_NOT_EXECUTING),
+    theMessage(""),
+    theEventFlag(true)
+{
+}
+
+ossimProcessInterface::~ossimProcessInterface()
+{
+}
+
+void ossimProcessInterface::abort()
+{
+   if(theProcessStatus == PROCESS_STATUS_EXECUTING)
+   {
+      theProcessStatus =  PROCESS_STATUS_ABORT_REQUEST;
+   }
+}
+
+bool ossimProcessInterface::needsAborting() const
+{
+   return ( isAborted()|| isAbortRequested() );
+}
+
+bool ossimProcessInterface::isAbortRequested()const
+{
+   return (theProcessStatus == PROCESS_STATUS_ABORT_REQUEST);
+}
+
+bool ossimProcessInterface::isAborted()const
+{
+   return (theProcessStatus==PROCESS_STATUS_ABORTED);
+}
+
+bool ossimProcessInterface::isExecuting()const
+{
+   return ((theProcessStatus==PROCESS_STATUS_EXECUTING)||
+           (theProcessStatus==PROCESS_STATUS_ABORT_REQUEST));
+}
+
+ossimProcessInterface::ossimProcessStatus ossimProcessInterface::getProcessStatus()const
+{
+   return theProcessStatus;
+}
+
+void ossimProcessInterface::setProcessStatus(ossimProcessStatus processStatus)
+{
+   theProcessStatus = processStatus;
+}
+
+double ossimProcessInterface::getPercentComplete()const
+{
+   return thePercentComplete;
+}
+
+void ossimProcessInterface::setPercentComplete(double percentComplete)
+{
+   thePercentComplete = percentComplete;
+
+   ossimListenerManager* manager = getManager();
+   if(theEventFlag&&manager)
+   {
+      ossimProcessProgressEvent event(getObject(),
+                                      thePercentComplete,
+                                      theMessage,
+                                      false);
+      manager->fireEvent(event);
+   }
+}
+
+ossimListenerManager* ossimProcessInterface::getManager()
+{
+   return PTR_CAST(ossimListenerManager, getObject());
+}
+
+void ossimProcessInterface::enableEvents()
+{
+   theEventFlag = true;
+}
+   
+void ossimProcessInterface::disableEvents()
+{
+   theEventFlag = false;
+}
+
+void ossimProcessInterface::setCurrentMessage(const ossimString& message)
+{
+   theMessage = message;
+
+   ossimListenerManager* manager = getManager();
+   if(theEventFlag&&manager)
+   {
+      ossimProcessProgressEvent event(getObject(),
+                                      thePercentComplete,
+                                      theMessage,
+                                      true);
+      manager->fireEvent(event);
+   }   
+}
+
+ostream& ossimProcessInterface::print(ostream& out) const
+{
+   out << "process status: ";
+   if(theProcessStatus == PROCESS_STATUS_EXECUTING)
+   {
+      out << "executing" << endl;
+   }
+   else if(theProcessStatus == PROCESS_STATUS_ABORTED)
+   {
+      out << "aborted" << endl;
+   }
+   else if(theProcessStatus == PROCESS_STATUS_NOT_EXECUTING)
+   {
+      out << "not executing" << endl;
+   }
+   out << "percent_complete: " << thePercentComplete;
+   
+   return out;
+}
+
+ostream& operator<<(ostream& out, const ossimProcessInterface& data)
+{
+   return data.print(out);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimProcessInterface.h b/Utilities/OSSIM/ossim_core/base/common/ossimProcessInterface.h
new file mode 100644
index 0000000000..78a1bae135
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimProcessInterface.h
@@ -0,0 +1,88 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimProcessInterface.h,v 1.13 2004/10/06 15:32:02 dburken Exp $
+#ifndef ossimProcessInterface_HEADER
+#define ossimProcessInterface_HEADER
+#include <iostream>
+#include "base/common/ossimRtti.h"
+#include "base/data_types/ossimString.h"
+#include "base/common/events/ossimProcessProgressEvent.h"
+#include "base/common/events/ossimListenerManager.h"
+
+class OSSIMDLLEXPORT ossimObject;
+class OSSIMDLLEXPORT ossimListenerManager;
+
+class OSSIMDLLEXPORT ossimProcessInterface
+{
+public:
+
+   enum ossimProcessStatus
+   {
+      PROCESS_STATUS_UNKNOWN       = 0,
+      PROCESS_STATUS_EXECUTING     = 1,
+      PROCESS_STATUS_ABORTED       = 2,
+      PROCESS_STATUS_ABORT_REQUEST = 3,
+      PROCESS_STATUS_NOT_EXECUTING = 4
+   };
+   
+   ossimProcessInterface();
+   
+   virtual ~ossimProcessInterface();
+   
+   virtual ossimObject* getObject()=0;
+   virtual const ossimObject* getObject()const=0;
+   virtual bool execute()=0;
+   
+   virtual void abort();
+
+   bool needsAborting()const;
+
+   bool isAbortRequested()const;
+
+   bool isAborted()const;
+
+   bool isExecuting()const;
+
+   ossimProcessStatus getProcessStatus()const;
+
+   virtual void setProcessStatus(ossimProcessStatus processStatus);
+
+   virtual double getPercentComplete()const;
+
+   virtual void setPercentComplete(double percentComplete);
+
+   virtual ossimListenerManager* getManager();
+
+   void enableEvents();
+   
+   void disableEvents();
+
+   void setCurrentMessage(const ossimString& message);
+
+   /*!
+    *  Called by friend operator<< function, derived classes should override
+    *  if something different is desired.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   friend std::ostream& operator<<(std::ostream& out,
+                                   const ossimProcessInterface& data);
+   
+protected:
+   double              thePercentComplete;
+   ossimProcessStatus  theProcessStatus;
+   ossimString         theMessage;
+   bool                theEventFlag;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimPropertyInterface.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimPropertyInterface.cpp
new file mode 100644
index 0000000000..a817c750ca
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimPropertyInterface.cpp
@@ -0,0 +1,77 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimPropertyInterface.cpp,v 1.10 2004/12/21 14:06:21 gpotts Exp $
+#include "ossimPropertyInterface.h"
+#include <base/property/ossimStringProperty.h>
+
+RTTI_DEF(ossimPropertyInterface, "ossimPropertyInterface");
+
+void ossimPropertyInterface::setProperty(const ossimString& name,
+                                         const ossimString& value)
+{
+   ossimRefPtr<ossimProperty> property = new ossimStringProperty(name, value);
+
+   setProperty(property);
+}
+
+void ossimPropertyInterface::setProperty(ossimRefPtr<ossimProperty> property)
+{
+}
+
+ossimRefPtr<ossimProperty> ossimPropertyInterface::getProperty(const ossimString& name)const
+{
+   return (ossimProperty*)0;
+}
+
+void ossimPropertyInterface::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+}
+
+
+void ossimPropertyInterface::getPropertyList(std::vector<ossimRefPtr<ossimProperty> >& propertyList)const
+{
+   std::vector<ossimString> propertyNames;
+   int idx = 0;
+   getPropertyNames(propertyNames);
+
+   for(idx = 0; idx < (int)propertyNames.size();++idx)
+   {
+      ossimRefPtr<ossimProperty> prop = getProperty(propertyNames[idx]);
+      if(prop.valid())
+      {
+         propertyList.push_back(prop);  
+      }
+   }
+}
+
+void ossimPropertyInterface::setProperties(std::vector<ossimRefPtr<ossimProperty> >& propertyList)
+{
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < propertyList.size(); ++idx)
+   {
+      if(propertyList[idx].valid())
+      {
+         setProperty(propertyList[idx]);
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimPropertyInterface.h b/Utilities/OSSIM/ossim_core/base/common/ossimPropertyInterface.h
new file mode 100644
index 0000000000..eb12cb1985
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimPropertyInterface.h
@@ -0,0 +1,40 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level license.txt
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimPropertyInterface.h,v 1.13 2004/12/21 14:06:21 gpotts Exp $
+#ifndef ossimPropertyInterface_HEADER
+#define ossimPropertyInterface_HEADER
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/common/ossimObject.h"
+#include <base/common/ossimRefPtr.h>
+#include <base/property/ossimProperty.h>
+
+
+class OSSIM_DLL ossimPropertyInterface
+{
+public:
+   ossimPropertyInterface()
+      {}
+   
+   virtual ~ossimPropertyInterface()
+      {}
+
+   virtual void setProperty(const ossimString& name,
+                            const ossimString& value);
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   void getPropertyList(std::vector<ossimRefPtr<ossimProperty> >& propertyList)const;
+   void setProperties(std::vector<ossimRefPtr<ossimProperty> >& propertyList);
+   
+protected:
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimProtocolStream.h b/Utilities/OSSIM/ossim_core/base/common/ossimProtocolStream.h
new file mode 100644
index 0000000000..a8f6d7dffd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimProtocolStream.h
@@ -0,0 +1,32 @@
+#ifndef ossimProtocolStream_HEADER
+#define ossimProtocolStream_HEADER
+#include "ossimStreamBase.h"
+
+class ossimProtocolStream : public ossimStreamBase
+{
+public:
+   ossimProtocolStream(){}
+   ossimProtocolStream(std::streambuf* buf):ossimStreamBase(buf)
+      {
+      }
+
+      /**
+       * This is a generic interface to any stream for opening and closing
+       * If supported this could be an interface to not only file streams
+       * but also http, https, ftp, ... etc
+       */
+   virtual void open(const char* protocolString,
+                     int openMode=0)=0;
+
+   /**
+    * Closes the stream
+    */
+   virtual void close()=0;
+
+   
+   virtual bool is_open()const=0;
+
+   virtual bool isCompressed()const=0;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimQuadrilateralMap.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimQuadrilateralMap.cpp
new file mode 100644
index 0000000000..21484819f3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimQuadrilateralMap.cpp
@@ -0,0 +1,95 @@
+#include "ossimQuadrilateralMap.h"
+#include <iostream>
+using namespace std;
+
+#include "matrix/newmat.h"
+#include "matrix/newmatio.h"
+#include "matrix/newmatap.h"
+
+ossimQuadrilateralMap::ossimQuadrilateralMap()
+   : a(0.0),
+     b(0.0),
+     c(0.0),
+     d(0.0),
+     e(0.0),
+     f(0.0),
+     g(0.0),
+     h(0.0)
+{
+}
+ossimQuadrilateralMap::ossimQuadrilateralMap(const ossimDpt& sourceP1,
+                                             const ossimDpt& sourceP2,
+                                             const ossimDpt& sourceP3,
+                                             const ossimDpt& sourceP4,
+                                             const ossimDpt& destP1,
+                                             const ossimDpt& destP2,
+                                             const ossimDpt& destP3,
+                                             const ossimDpt& destP4)
+{
+   solveCoefficients(sourceP1, sourceP2, sourceP3, sourceP4,
+                     destP1, destP2, destP3, destP4);
+}
+
+ossimQuadrilateralMap::ossimQuadrilateralMap(const ossimQuadrilateralMap& rhs)
+  :a(rhs.a),
+   b(rhs.b),
+   c(rhs.c),
+   d(rhs.d),
+   e(rhs.e),
+   f(rhs.f),
+   g(rhs.g)
+{
+}
+
+void ossimQuadrilateralMap::solveCoefficients(const ossimDpt& sourceP1,
+                                              const ossimDpt& sourceP2,
+                                              const ossimDpt& sourceP3,
+                                              const ossimDpt& sourceP4,
+                                              const ossimDpt& destP1,
+                                              const ossimDpt& destP2,
+                                              const ossimDpt& destP3,
+                                              const ossimDpt& destP4)
+{
+      NEWMAT::Matrix m(8,8);
+      
+      m << sourceP1.x << sourceP1.y << 1.0 << 0.0 << 0.0 << 0.0 << -sourceP1.x*destP1.x << -sourceP1.y*destP1.x
+        << sourceP2.x << sourceP2.y << 1.0 << 0.0 << 0.0 << 0.0 << -sourceP2.x*destP2.x << -sourceP2.y*destP2.x 
+        << sourceP3.x << sourceP3.y << 1.0 << 0.0 << 0.0 << 0.0 << -sourceP3.x*destP3.x << -sourceP3.y*destP3.x 
+        << sourceP4.x << sourceP4.y << 1.0 << 0.0 << 0.0 << 0.0 << -sourceP4.x*destP4.x << -sourceP4.y*destP4.x 
+        << 0.0 << 0.0 << 0.0 << sourceP1.x << sourceP1.y << 1.0 << -sourceP1.x*destP1.y << -sourceP1.y*destP1.y 
+        << 0.0 << 0.0 << 0.0 << sourceP2.x << sourceP2.y << 1.0 << -sourceP2.x*destP2.y << -sourceP2.y*destP2.y
+        << 0.0 << 0.0 << 0.0 << sourceP3.x << sourceP3.y << 1.0 << -sourceP3.x*destP3.y << -sourceP3.y*destP3.y
+        << 0.0 << 0.0 << 0.0 << sourceP4.x << sourceP4.y << 1.0 << -sourceP4.x*destP4.y << -sourceP4.y*destP4.y;
+   
+      NEWMAT::Matrix A = m.i();
+      NEWMAT::ColumnVector b(8);
+      b << destP1.x << destP2.x << destP3.x << destP4.x << destP1.y << destP2.y << destP3.y << destP4.y;
+      NEWMAT::ColumnVector y = A * b;
+
+      a = y[0];
+      b = y[1];
+      c = y[2];
+      d = y[3];
+      e = y[4];
+      f = y[5];
+      g = y[6];
+      h = y[7];
+}
+
+void ossimQuadrilateralMap::map(const ossimDpt& source, ossimDpt& dest)const
+{
+   double numerator;  
+   double denominator;
+
+   //solve x first
+   numerator   = a*source.x + b*source.y + c;
+   denominator = g*source.x + h*source.y + 1;
+
+   dest.x = numerator/denominator;
+   
+   //solve y 
+   numerator   = d*source.x + e*source.y + f;
+   denominator = g*source.x + h*source.y + 1;
+
+   dest.y = numerator/denominator;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimQuadrilateralMap.h b/Utilities/OSSIM/ossim_core/base/common/ossimQuadrilateralMap.h
new file mode 100644
index 0000000000..669e3add43
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimQuadrilateralMap.h
@@ -0,0 +1,55 @@
+#ifndef ossimQuadrilateralMap_HEADER
+#define ossimQuadrilateralMap_HEADER
+#include "base/data_types/ossimDpt.h"
+
+class OSSIMDLLEXPORT ossimQuadrilateralMap
+{
+public:
+   ossimQuadrilateralMap(const ossimDpt& sourceP1,
+                         const ossimDpt& sourceP2,
+                         const ossimDpt& sourceP3,
+                         const ossimDpt& sourceP4,
+                         const ossimDpt& destP1,
+                         const ossimDpt& destP2,
+                         const ossimDpt& destP3,
+                         const ossimDpt& destP4);
+   ossimQuadrilateralMap();
+
+  ossimQuadrilateralMap(const ossimQuadrilateralMap& rhs);
+   /*!
+    * Uses a standard form of quadrilateral to quadrilateral
+    * mapping:
+    *
+    * X = (a*U + b*V + c) / (g*U + h*V + 1)
+    * Y = (d*U + e*V+f)/(g*U + h*V + 1)
+    *
+    * where:
+    * X and Y are the mapped destination point.
+    * U and V are the source point to warp
+    * a, b, c, d, e, f, g, h are coefficients sovled by
+    * the points passed to the constructor.
+    */
+   void map(const ossimDpt& source, ossimDpt& dest)const;
+
+   void solveCoefficients(const ossimDpt& sourceP1,
+                          const ossimDpt& sourceP2,
+                          const ossimDpt& sourceP3,
+                          const ossimDpt& sourceP4,
+                          const ossimDpt& destP1,
+                          const ossimDpt& destP2,
+                          const ossimDpt& destP3,
+                          const ossimDpt& destP4);
+
+protected:
+   double a;
+   double b;
+   double c;
+   double d;
+   double e;
+   double f;
+   double g;
+   double h;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimRectilinearDataObject.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimRectilinearDataObject.cpp
new file mode 100644
index 0000000000..d17919fdbe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimRectilinearDataObject.cpp
@@ -0,0 +1,312 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRectilinearDataObject.cpp,v 1.12 2005/05/09 12:39:38 dburken Exp $
+
+#include <base/common/ossimRectilinearDataObject.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+
+RTTI_DEF1(ossimRectilinearDataObject, "ossimRectilinearDataObject", ossimDataObject);
+
+ossimRectilinearDataObject::ossimRectilinearDataObject(const ossimRectilinearDataObject& rhs)
+   : ossimDataObject(rhs),
+     theNumberOfDataComponents(rhs.theNumberOfDataComponents),
+     theNumberOfSpatialComponents(rhs.theNumberOfSpatialComponents),
+     theScalarType(rhs.theScalarType),
+     theDataBuffer(NULL),
+     theSpatialExtents(NULL)
+{
+   if(rhs.theDataBuffer)
+   {
+      theDataBuffer = new ossim_uint8[rhs.getDataSizeInBytes()];
+      if(theDataBuffer)
+      {
+         memcpy(theDataBuffer, rhs.theDataBuffer, rhs.getDataSizeInBytes());
+      }
+   }
+   if(rhs.theSpatialExtents)
+   {
+      theSpatialExtents = new ossim_uint32[rhs.theNumberOfSpatialComponents];
+      memcpy(theSpatialExtents, rhs.theSpatialExtents, sizeof(ossim_uint32)*theNumberOfSpatialComponents);
+   }
+}
+
+ossimRectilinearDataObject::ossimRectilinearDataObject(ossim_uint32 numberOfSpatialComponents,
+                                                       ossimSource* owner,
+                                                       ossim_uint32 numberOfDataComponents,
+                                                       ossimScalarType   scalarType,
+                                                       ossimDataObjectStatus status)
+   :ossimDataObject(owner, OSSIM_NULL),
+    theNumberOfDataComponents(numberOfDataComponents),
+    theNumberOfSpatialComponents(numberOfSpatialComponents),
+    theScalarType(scalarType),
+    theDataBuffer(NULL),
+    theSpatialExtents(NULL)
+{
+   if(theNumberOfSpatialComponents)
+   {
+      theSpatialExtents = new ossim_uint32[theNumberOfSpatialComponents];
+      memset(theSpatialExtents, 1, theNumberOfSpatialComponents);
+   }
+}
+
+ossimRectilinearDataObject::ossimRectilinearDataObject(ossimSource* owner,
+                                                       ossim_uint32 numberOfDataComponents,
+                                                       ossim_uint32 length,
+                                                       ossimScalarType   scalarType,
+                                                       ossimDataObjectStatus status)
+   :ossimDataObject(owner, OSSIM_NULL),
+    theNumberOfDataComponents(numberOfDataComponents),
+    theNumberOfSpatialComponents(1),
+    theScalarType(scalarType),
+    theDataBuffer(NULL),
+    theSpatialExtents(NULL)
+{
+   
+   theSpatialExtents = new ossim_uint32[1];
+   theSpatialExtents[0] = length;
+}
+
+ossimRectilinearDataObject::ossimRectilinearDataObject(ossimSource* owner,
+                                                       ossim_uint32 numberOfDataComponents,
+                                                       ossim_uint32 width,
+                                                       ossim_uint32 height,
+                                                       ossimScalarType   scalarType,
+                                                       ossimDataObjectStatus status)
+   :ossimDataObject(owner, OSSIM_NULL),
+    theNumberOfDataComponents(numberOfDataComponents),
+    theNumberOfSpatialComponents(2),
+    theScalarType(scalarType),
+    theDataBuffer(NULL),
+    theSpatialExtents(NULL)
+{
+   
+   theSpatialExtents = new ossim_uint32[2];
+   theSpatialExtents[0] = width;
+   theSpatialExtents[1] = height;
+}
+
+ossimRectilinearDataObject::ossimRectilinearDataObject(ossimSource* owner,
+                                                       ossim_uint32 numberOfDataComponents,
+                                                       ossim_uint32 width,
+                                                       ossim_uint32 height,
+                                                       ossim_uint32 depth,
+                                                       ossimScalarType   scalarType,
+                                                       ossimDataObjectStatus status)
+   :ossimDataObject(owner, OSSIM_NULL),
+    theNumberOfDataComponents(numberOfDataComponents),
+    theNumberOfSpatialComponents(3),
+    theScalarType(scalarType),
+    theDataBuffer(NULL),
+    theSpatialExtents(NULL)
+{
+   
+   theSpatialExtents = new ossim_uint32[3];
+   theSpatialExtents[0] = width;
+   theSpatialExtents[1] = height;
+   theSpatialExtents[2] = depth;
+}
+
+ossimRectilinearDataObject::~ossimRectilinearDataObject()
+{
+   if(theDataBuffer)
+   {
+      delete [] theDataBuffer;
+      theDataBuffer = NULL;
+   }
+   if(theSpatialExtents)
+   {
+      delete [] theSpatialExtents;
+      theSpatialExtents = NULL;
+   }
+   theNumberOfDataComponents    = 0;
+   theNumberOfSpatialComponents = 0;
+}
+
+ossim_uint32 ossimRectilinearDataObject::computeSpatialProduct()const
+{
+   if(!theSpatialExtents) return 0;
+   ossim_uint32 spatialProduct = 1;
+   for(ossim_uint32 index = 0; index < theNumberOfSpatialComponents; ++index)
+   {
+      spatialProduct *= theSpatialExtents[index];
+   }
+
+   return spatialProduct;
+}
+
+void ossimRectilinearDataObject::setNumberOfDataComponents(ossim_uint32 n)
+{
+   theNumberOfDataComponents = n;
+}
+
+void ossimRectilinearDataObject::setSpatialExtents(ossim_uint32* extents,
+                                                   ossim_uint32 size)
+{
+   if(!extents) return;
+   if((size != theNumberOfSpatialComponents)&&size)
+   {
+      if(theSpatialExtents)
+      {
+         delete [] theSpatialExtents;
+         theSpatialExtents = NULL;
+      }
+      theSpatialExtents = new ossim_uint32[size];
+   }
+   int i = 0;
+   for(i =0; i < (int)size; ++i)
+   {
+      theSpatialExtents[i] = extents[i];
+   }
+   theNumberOfSpatialComponents = size;
+}
+
+void ossimRectilinearDataObject::setScalarType(ossimScalarType type)
+{
+   theScalarType = type;
+}
+
+ossim_uint32 ossimRectilinearDataObject::getNumberOfDataComponents() const
+{
+   return theNumberOfDataComponents;
+}
+
+ossim_uint32 ossimRectilinearDataObject::getNumberOfSpatialComponents() const
+{
+   return theNumberOfSpatialComponents;
+}
+
+const ossim_uint32* ossimRectilinearDataObject::getSpatialExtents()const
+{
+   return theSpatialExtents;
+}
+
+ossimScalarType ossimRectilinearDataObject::getScalarType() const
+{
+   return theScalarType;
+}
+
+ossim_uint32 ossimRectilinearDataObject::getScalarSizeInBytes() const
+{
+   return ossimGetScalarSizeInBytes(getScalarType());
+}
+
+void* ossimRectilinearDataObject::getBuf()
+{
+   return static_cast<void*>(theDataBuffer);
+}
+
+const void* ossimRectilinearDataObject::getBuf()const
+{
+   return static_cast<const void*>(theDataBuffer);
+}
+
+void ossimRectilinearDataObject::assign(const ossimRectilinearDataObject* data)
+{
+   if(!data) return;
+   ossimDataObject::assign(data);
+   ossim_uint32 savedSize = getDataSizeInBytes();
+   //***
+   // This method assumes contiguous buffer for "theData".  Override if
+   // needed.
+   //***
+   
+   if(theNumberOfSpatialComponents != data->theNumberOfSpatialComponents)
+   {
+      delete [] theSpatialExtents;
+      if(data->theNumberOfSpatialComponents)
+      {
+         theSpatialExtents = new ossim_uint32[data->theNumberOfSpatialComponents];
+      }
+      else
+      {
+         theSpatialExtents = NULL;
+      }
+   }
+   for(ossim_uint32 index = 0; index < theNumberOfSpatialComponents; ++index)
+   {
+      theSpatialExtents[index] = data->theSpatialExtents[index];
+   }
+   
+   theNumberOfSpatialComponents = data->theNumberOfSpatialComponents;
+   theNumberOfDataComponents    = data->theNumberOfDataComponents;
+   theScalarType                = data->theScalarType;
+   //***
+   // First copy the buffer if there is one.
+   //***
+   if(data->theDataBuffer)
+   {
+      //***
+      // Make sure this buffer is the same size; if not, delete.
+      // This could be left alone if bigger than the data buffer;
+      // however, deleting for now...
+      //***
+      ossim_uint32 source_size = data->getDataSizeInBytes();
+      ossim_uint32 newSize     = getDataSizeInBytes();
+      if(!theDataBuffer)
+      {
+         theDataBuffer = new ossim_uint8[source_size];
+      }
+      else if(savedSize != newSize)
+      {
+         if(theDataBuffer)
+         {
+            delete [] theDataBuffer;
+            theDataBuffer = NULL;
+            theDataBuffer = new ossim_uint8[newSize];
+         }
+      }
+
+      // Copy the image data...
+      memcpy(theDataBuffer, data->theDataBuffer, source_size);
+   }
+   if(!theDataBuffer) setDataObjectStatus(OSSIM_NULL);
+}
+
+void ossimRectilinearDataObject::initialize()
+{
+   deInitialize();
+
+   ossim_uint32 size = getDataSizeInBytes();
+   if(size)
+   {
+      theDataBuffer = new ossim_uint8[size];
+   }   
+}
+
+void ossimRectilinearDataObject::deInitialize()
+{
+   if(theDataBuffer)
+   {
+      delete [] theDataBuffer;
+      theDataBuffer = NULL;
+      setDataObjectStatus(OSSIM_NULL);
+   }
+}
+
+ossim_uint32 ossimRectilinearDataObject::getDataSizeInBytes()const
+{
+   return (ossim_uint32)(getScalarSizeInBytes()*
+                         computeSpatialProduct()*
+                         theNumberOfDataComponents);
+}
+
+std::ostream& ossimRectilinearDataObject::print(std::ostream& out) const
+{
+   out << "ossimRectilinearDataObject::print:"
+      << "\ntheNumberOfDataComponents:     " << theNumberOfDataComponents
+      << "\ntheNumberOfSpatialComponents:  " << theNumberOfSpatialComponents;
+   
+   out << "\ntheScalarType:                 "
+       << (ossimScalarTypeLut::instance()->getEntryString(theScalarType))
+       << endl;
+
+   return ossimDataObject::print(out);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimRectilinearDataObject.h b/Utilities/OSSIM/ossim_core/base/common/ossimRectilinearDataObject.h
new file mode 100644
index 0000000000..0eedb60534
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimRectilinearDataObject.h
@@ -0,0 +1,156 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimRectilinearDataObject.h,v 1.9 2004/04/07 23:54:47 dburken Exp $
+#ifndef ossimRectilinearDataObject_HEADER
+#define ossimRectilinearDataObject_HEADER
+#include "ossimDataObject.h"
+
+class OSSIMDLLEXPORT ossimRectilinearDataObject : public ossimDataObject
+{
+public:
+   ossimRectilinearDataObject(const ossimRectilinearDataObject&rhs);
+      
+   ossimRectilinearDataObject(ossim_uint32 numberOfSpatialComponents,
+                              ossimSource* owner,
+                              ossim_uint32 numberOfDataComponents,
+                              ossimScalarType scalarType=OSSIM_SCALAR_UNKNOWN,
+                              ossimDataObjectStatus status=OSSIM_NULL);
+   
+   /**
+    * This is a helper constructor that allows one to instantiate a one
+    * dimensional Spatial component with N number of data components.
+    * It will internally allocate theSpatialExtent to 1 and set the
+    * contents equal to the value passed in to length.
+    */
+   ossimRectilinearDataObject(ossimSource* owner,
+                              ossim_uint32 numberOfDataComponents,
+                              ossim_uint32 length,
+                              ossimScalarType scalarType=OSSIM_SCALAR_UNKNOWN,
+                              ossimDataObjectStatus status=OSSIM_NULL);
+
+   /**
+    * This is a helper constructor that allows one to instantiate a two
+    * dimensional Spatial component (WidthxHeight) with N number of
+    * data components.  It will internally allocate theSpatialExtent
+    * to 2 and set the contents equal to the value passed in to width, and
+    * height.
+    */
+   ossimRectilinearDataObject(ossimSource* owner,
+                              ossim_uint32 numberOfDataComponents,
+                              ossim_uint32 width,
+                              ossim_uint32 height,
+                              ossimScalarType scalarType=OSSIM_SCALAR_UNKNOWN,
+                              ossimDataObjectStatus status=OSSIM_NULL);
+
+   /**
+    * This is a helper constructor that allows one to instantiate a two
+    * dimensional Spatial component (WidthxHeightxDepth) with N number of
+    * data components.  It will internally allocate theSpatialExtent
+    * to 3 and set the contents equal to the value passed in to width,
+    * height, and depth.
+    */
+   ossimRectilinearDataObject(ossimSource* owner,
+                              ossim_uint32 numberOfDataComponents,
+                              ossim_uint32 width,
+                              ossim_uint32 height,
+                              ossim_uint32 depth,
+                              ossimScalarType   scalarType=OSSIM_SCALAR_UNKNOWN,
+                              ossimDataObjectStatus status=OSSIM_NULL);
+   
+   virtual ~ossimRectilinearDataObject();
+
+   /**
+    * How many components make up this data object.  For
+    * example:  If this were an RGB image data object then
+    * the number of components would be set to 3 and the
+    * RGB would be seen as a single data object being
+    * passed through.
+    */
+   virtual void setNumberOfDataComponents(ossim_uint32 n);
+   
+   virtual void setSpatialExtents(ossim_uint32* extents, ossim_uint32  size);
+
+   /**
+    *  See ossimScalarType in ossimConstants for a full list
+    *
+    *  OSSIM_SCALAR_UNKNOWN
+    *  OSSIM_UCHAR          Unsigned char
+    *  OSSIM_USHORT16       16bit unsigned short
+    *  OSSIM_SSHORT16       16bit signed short
+    *  OSSIM_USHORT11       11bit unsigned short
+    *  OSSIM_FLOAT          float
+    *  OSSIM_NORMALIZED_DOUBLE normalized 0 to 1 data
+    */
+   virtual void setScalarType(ossimScalarType type);
+
+   virtual ossim_uint32 getNumberOfDataComponents() const;
+
+   virtual ossim_uint32 getNumberOfSpatialComponents() const;
+
+   virtual const ossim_uint32* getSpatialExtents() const;
+
+   virtual ossimScalarType getScalarType() const;
+
+   virtual ossim_uint32 getScalarSizeInBytes()const;
+
+   virtual void*   getBuf();
+
+   virtual const void* getBuf() const;
+
+   virtual void assign(const ossimRectilinearDataObject* data);
+
+   /**
+    *  Calls deInitialize() which deletes theDataBuffer and sets object status
+    *  to OSSIM_NULL, then initializes theDataBuffer.
+    *
+    *  @see deInitialize
+    *  
+    *  @note This method is destructive in that if the buffer existed of
+    *  the correct size it will delete it, then reallocate.
+    */
+   virtual void initialize();
+
+   /**
+    *  If theDataBuffer exist if will delete it then set object status to
+    *  OSSIM_NULL.
+    *
+    *  @see setDataObjectStatus
+    */
+   virtual void deInitialize();
+
+   virtual ossim_uint32 computeSpatialProduct()const;
+
+   virtual ossim_uint32 getDataSizeInBytes()const;
+
+   virtual std::ostream& print(std::ostream& out) const;
+
+protected:
+   ossim_uint32    theNumberOfDataComponents;
+   ossim_uint32    theNumberOfSpatialComponents;
+   ossimScalarType theScalarType;
+   ossim_uint8*    theDataBuffer;
+   ossim_uint32*   theSpatialExtents;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimRefPtr.h b/Utilities/OSSIM/ossim_core/base/common/ossimRefPtr.h
new file mode 100644
index 0000000000..1a99324129
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimRefPtr.h
@@ -0,0 +1,88 @@
+/* -*-c++-*- ossim - Copyright (C) since 2004 Garrett Potts 
+ *
+ * This was taken directly from OpenSceneGraph and will retain OSGGPL license.
+ * This is basically an LGPL.
+ * 
+*/
+#ifndef ossimRefPtr_HEADER
+#define ossimRefPtr_HEADER
+#include <base/common/ossimConstants.h>
+
+template<class T> class ossimRefPtr
+{
+ public:
+   typedef T element_type;
+   
+   ossimRefPtr() :thePtr(0) {}
+   ossimRefPtr(T* t):thePtr(t)              { if (thePtr) thePtr->ref(); }
+   ossimRefPtr(const ossimRefPtr& rp):thePtr(rp.thePtr)  { if (thePtr) thePtr->ref(); }
+   ~ossimRefPtr()                           { if (thePtr) thePtr->unref(); thePtr=0; }
+   
+   inline ossimRefPtr& operator = (const ossimRefPtr& rp)
+      {
+         if (thePtr==rp.thePtr) return *this;
+         T* tmpPtr = thePtr;
+         thePtr = rp.thePtr;
+         if (thePtr) thePtr->ref();
+         // unref second to prevent any deletion of any object which might
+         // be referenced by the other object. i.e rp is child of the
+         // original _ptr.
+         if (tmpPtr) tmpPtr->unref();
+         return *this;
+      }
+   
+   inline ossimRefPtr& operator = (T* ptr)
+      {
+         if (thePtr==ptr) return *this;
+         T* tmpPtr = thePtr;
+         thePtr = ptr;
+         if (thePtr) thePtr->ref();
+         // unref second to prevent any deletion of any object which might
+         // be referenced by the other object. i.e rp is child of the
+         // original thePtr.
+         if (tmpPtr) tmpPtr->unref();
+         return *this;
+      }
+   
+   // comparison operators for ossimRefPtr.
+   inline bool operator == (const ossimRefPtr& rp) const { return (thePtr==rp.thePtr); }
+   inline bool operator != (const ossimRefPtr& rp) const { return (thePtr!=rp.thePtr); }
+   inline bool operator < (const ossimRefPtr& rp) const { return (thePtr<rp.thePtr); }
+   inline bool operator > (const ossimRefPtr& rp) const { return (thePtr>rp.thePtr); }
+   
+   // comparion operator for const T*.
+   inline bool operator == (const T* ptr) const { return (thePtr==ptr); }
+   inline bool operator != (const T* ptr) const { return (thePtr!=ptr); }
+   inline bool operator < (const T* ptr) const { return (thePtr<ptr); }
+   inline bool operator > (const T* ptr) const { return (thePtr>ptr); }
+   
+   
+   inline T& operator*()  { return *thePtr; }
+   
+   inline const T& operator*() const { return *thePtr; }
+   
+   inline T* operator->() { return thePtr; }
+   
+   inline const T* operator->() const   { return thePtr; }
+   
+   inline bool operator!() const	{ return thePtr==0L; }
+   
+   inline bool valid() const	{ return thePtr!=0L; }
+   
+   inline T* get() { return thePtr; }
+   
+   inline const T* get() const { return thePtr; }
+   
+   /** take control over the object pointed to by ref_ptr, unreference but do not delete even if ref count goes to 0,
+    * return the pointer to the object.
+    * Note, do not use this unless you are 100% sure your code handles the deletion of the object correctly, and
+    * only use when absolutely required.*/
+   inline T* take() { return release();}
+   
+   inline T* release() { T* tmp=thePtr; if (thePtr) thePtr->unref_nodelete(); thePtr=0; return tmp;}
+   
+ private:
+   T* thePtr;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimReferenced.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimReferenced.cpp
new file mode 100644
index 0000000000..4a8ccf95d2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimReferenced.cpp
@@ -0,0 +1,14 @@
+/* -*-c++-*- libwms - Copyright (C) since 2004 Garrett Potts
+*/
+#include <base/common/ossimReferenced.h>
+#include <base/context/ossimNotifyContext.h>
+
+ossimReferenced::~ossimReferenced()
+{
+   if (theRefCount>0)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)<<"Warning: deleting still referenced object "<<this<<std::endl;
+      ossimNotify(ossimNotifyLevel_WARN)<<"         the final reference count was "<<theRefCount
+                                        <<", memory corruption possible."<<std::endl;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimReferenced.h b/Utilities/OSSIM/ossim_core/base/common/ossimReferenced.h
new file mode 100644
index 0000000000..09a707a5a9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimReferenced.h
@@ -0,0 +1,59 @@
+/* -*-c++-*- libossim - Copyright (C) since 2004 Garrett Potts 
+ * LICENSE: LGPL
+ * Author: Garrett Potts
+*/
+#ifndef ossimReferenced_HEADER
+#define ossimReferenced_HEADER
+#include <base/common/ossimConstants.h>
+
+class OSSIMDLLEXPORT ossimReferenced
+{
+ public:
+   ossimReferenced()
+      : theRefCount(0)
+      {}
+   
+   ossimReferenced(const ossimReferenced&)
+      : theRefCount(0)
+      {}
+   
+   inline ossimReferenced& operator = (const ossimReferenced&) { return *this; }
+   
+
+   /*! increment the reference count by one, indicating that 
+       this object has another pointer which is referencing it.*/
+   inline void ref() const { ++theRefCount; }
+   
+   /*! decrement the reference count by one, indicating that 
+       a pointer to this object is referencing it.  If the
+       reference count goes to zero, it is assumed that this object
+       is no longer referenced and is automatically deleted.*/
+   inline void unref() const;
+   
+   /*! decrement the reference count by one, indicating that 
+       a pointer to this object is referencing it.  However, do
+       not delete it, even if ref count goes to 0.  Warning, unref_nodelete() 
+       should only be called if the user knows exactly who will
+       be resonsible for, one should prefer unref() over unref_nodelete() 
+       as the later can lead to memory leaks.*/
+   inline void unref_nodelete() const { --theRefCount; }
+   
+   /*! return the number pointers currently referencing this object. */
+   inline int referenceCount() const { return theRefCount; }
+   
+   
+ protected:
+   virtual ~ossimReferenced();
+   mutable int theRefCount;
+};
+
+inline void ossimReferenced::unref() const
+{
+    --theRefCount;
+    if (theRefCount==0)
+    {
+        delete this;
+    }
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimRgbLutDataObject.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimRgbLutDataObject.cpp
new file mode 100644
index 0000000000..9102689b6a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimRgbLutDataObject.cpp
@@ -0,0 +1,279 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbLutDataObject.cpp,v 1.17 2005/05/10 16:57:20 dburken Exp $
+#include <base/common/ossimRgbLutDataObject.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimColumnVector3d.h>
+#include <base/context/ossimNotifyContext.h>
+
+#include <sstream>
+using namespace std;
+
+RTTI_DEF1(ossimRgbLutDataObject, "ossimRgbLutDataObject", ossimObject);
+
+ostream& operator <<(ostream& out,
+                     const ossimRgbLutDataObject& lut)
+{
+   for(ossim_uint32 index = 0; index < lut.theNumberOfEntries; ++index)
+   {
+      out << "entry" << index << " " << lut[index] << endl;
+   }
+
+   return out;
+}
+
+ossimRgbLutDataObject::ossimRgbLutDataObject(unsigned long numberOfEntries)
+   :
+      theLut(NULL),
+      theNumberOfEntries(numberOfEntries)
+{
+   if(theNumberOfEntries > 0)
+   {
+      // allocate 256 entries for the data object;
+      theLut = new ossimRgbVector[theNumberOfEntries];
+   }
+      
+}
+
+ossimRgbLutDataObject::ossimRgbLutDataObject(const ossimRgbLutDataObject& lut)
+   :
+      theLut(NULL),
+      theNumberOfEntries(0)
+{
+   theNumberOfEntries = lut.theNumberOfEntries;
+   if(theNumberOfEntries > 0)
+   {
+      theLut = new ossimRgbVector[theNumberOfEntries];
+      for(ossim_uint32 index = 0; index < theNumberOfEntries; ++index)
+      {
+         theLut[index] = lut.theLut[index];
+      }
+   }
+}
+
+ossimRgbLutDataObject::~ossimRgbLutDataObject()
+{
+   if(theLut)
+   {
+      delete [] theLut;
+      theLut = NULL;
+   }
+   theNumberOfEntries = 0;
+}
+
+int ossimRgbLutDataObject::findIndex(ossim_uint8 r, ossim_uint8 g, ossim_uint8 b)
+{
+   ossim_uint32 distance = 0x7FFFFFFF; // max 4 byte signed
+   ossim_int32 result   = 0;
+
+   if(theNumberOfEntries > 0)
+   {
+      for(ossim_uint32 i = 0; i < theNumberOfEntries; ++i)
+      {
+         ossim_uint32 rDelta = r - theLut[i].getR();
+         ossim_uint32 gDelta = g - theLut[i].getG();
+         ossim_uint32 bDelta = b - theLut[i].getB();
+
+         ossim_uint32 deltaSumSquare = (rDelta*rDelta +
+                                        gDelta*gDelta +
+                                        bDelta*bDelta);
+         if(deltaSumSquare == 0)
+         {
+            return static_cast<int>(i);
+         }
+         else if( deltaSumSquare < distance)
+         {
+            result = static_cast<int>(i);
+            distance = deltaSumSquare;
+         }
+      }
+   }
+
+   return result;
+}
+
+ossimRgbLutDataObject ossimRgbLutDataObject::rotate(long numberOfElements)const
+{
+   if(numberOfElements < 0)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: Negative rotation is not supported yet in ossimRgbLutDataObject::rotate" << endl;
+      return *this;
+   }
+   ossimRgbLutDataObject lut;
+   for(ossim_uint32 index = 0; index < theNumberOfEntries; ++index)
+   {
+      int adjustedDestinationIndex = (index+numberOfElements)%theNumberOfEntries;
+      lut[adjustedDestinationIndex] = theLut[index] ;
+   }
+
+   return lut;
+}
+
+ossimRgbLutDataObject& ossimRgbLutDataObject::rotate(long numberOfElements)
+{
+   if(numberOfElements < 0)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: Negative rotation is not supported yet in ossimRgbLutDataObject::rotate" << endl;
+      return *this;
+   }
+   const ossimRgbLutDataObject* temp = this;
+
+   *this = temp->rotate(numberOfElements);
+
+   return *this;
+}
+
+const ossimRgbLutDataObject& ossimRgbLutDataObject::operator =(const ossimRgbLutDataObject& lut)
+{
+   if(theNumberOfEntries != lut.theNumberOfEntries)
+   {
+      delete [] theLut;
+      theLut = NULL;
+   }
+
+   theNumberOfEntries = lut.theNumberOfEntries;
+   if(!theLut&&(theNumberOfEntries > 0))
+   {
+      theLut = new ossimRgbVector[theNumberOfEntries];
+   }
+   for(unsigned long index = 0; index < theNumberOfEntries; ++index)
+   {
+      theLut[index] = lut.theLut[index];
+   }
+
+   return *this;
+}
+
+bool ossimRgbLutDataObject::operator ==(const ossimRgbLutDataObject& lut)const
+{
+   if(theNumberOfEntries != lut.theNumberOfEntries)
+   {
+      return false;
+   }
+   for(unsigned long index = 0; index < theNumberOfEntries; ++index)
+   {
+      if(theLut[index] != lut.theLut[index])
+      {
+         return false;
+      }
+   }
+   return true;
+}
+
+bool ossimRgbLutDataObject::saveState(ossimKeywordlist& kwl, const char* prefix)const
+{
+   kwl.add(prefix,
+           "type",
+           getClassName(),
+           true);
+   kwl.add(prefix,
+           "number_of_entries",
+           ossimString::toString(theNumberOfEntries).c_str(),
+           true);
+   for(unsigned long index = 0; index < theNumberOfEntries; ++index)
+   {
+      ossimString newPrefix = "entry";
+      newPrefix += ossimString::toString(index);
+      ostringstream ostr;
+      ostr << (int)(theLut[index].getR())
+           << " " << (int)(theLut[index].getG())
+           << " " << (int)(theLut[index].getB());
+      kwl.add(prefix,
+              newPrefix,
+              ostr.str().c_str(),
+              true);
+   }
+
+   return true;
+}
+
+bool ossimRgbLutDataObject::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   const char* lutFile = kwl.find(prefix, "lut_file");
+   ossimKeywordlist fileLut;
+   ossimKeywordlist* tempKwl = (const_cast<ossimKeywordlist*>(&kwl));
+   ossimString tempPrefix = prefix;
+
+   // this should have been used instead of lut_file.  We will still look
+   // for lut_file for backward compatibility.
+   //
+   if(!lutFile)
+   {
+      lutFile = kwl.find(prefix, "filename");
+   }
+   // check to see if we should open an external file
+   // if so point the fileLut to the one that we use
+   if(lutFile)
+   {
+      ossimFilename filename(lutFile);
+      if(filename.exists())
+      {
+         fileLut.addFile(filename.c_str());
+         tempKwl = &fileLut;
+         tempPrefix = "";
+      }
+   }
+ 
+   const char* numberOfEntries = tempKwl->find(tempPrefix, "number_of_entries");
+   if(!numberOfEntries)
+   {
+      numberOfEntries = tempKwl->find(tempPrefix, "number_entries");
+   }
+   if(!numberOfEntries) return false;
+   theNumberOfEntries = ossimString(numberOfEntries).toULong();
+
+   delete [] theLut;
+   theLut = new ossimRgbVector[theNumberOfEntries];
+
+   if(tempKwl->find(tempPrefix, "entry0"))
+   {
+      for(long index = 0; index < (long)theNumberOfEntries; ++index)
+      {
+         ossimString newPrefix = "entry";
+         newPrefix += ossimString::toString(index);
+         ossimString v = tempKwl->find(tempPrefix, newPrefix.c_str());
+         istringstream istr(v);
+
+         int r, g, b;
+         istr >> r >> g >> b;
+         theLut[index].setR((unsigned char)r);
+         theLut[index].setG((unsigned char)g);
+         theLut[index].setB((unsigned char)b);
+      }
+   }
+   else
+   {
+      for(long index = 0; index < (long)theNumberOfEntries; ++index)
+      {
+         ossimString newPrefix = "entry";
+         newPrefix += ossimString::toString(index);
+         
+         const char* r = tempKwl->find(tempPrefix, (newPrefix+".r").c_str());
+         const char* g = tempKwl->find(tempPrefix, (newPrefix+".g").c_str());
+         const char* b = tempKwl->find(tempPrefix, (newPrefix+".b").c_str());
+         
+         if(r)
+         {
+            theLut[index].setR((unsigned char)ossimString(r).toLong());
+         }
+         if(g)
+         {
+            theLut[index].setG((unsigned char)ossimString(g).toLong());
+         }
+         if(b)
+         {
+            theLut[index].setB((unsigned char)ossimString(b).toLong());
+         }
+      }
+   }
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimRgbLutDataObject.h b/Utilities/OSSIM/ossim_core/base/common/ossimRgbLutDataObject.h
new file mode 100644
index 0000000000..a750ac5332
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimRgbLutDataObject.h
@@ -0,0 +1,99 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimRgbLutDataObject.h,v 1.12 2004/08/07 20:40:02 dburken Exp $
+#ifndef ossimRgbLutDataObject_HEADER
+#define ossimRgbLutDataObject_HEADER
+#include "base/data_types/color_space/ossimRgbVector.h"
+#include "base/common/ossimObject.h"
+#include <iostream>
+class OSSIMDLLEXPORT ossimKeywordlist;
+
+class OSSIMDLLEXPORT ossimRgbLutDataObject : public ossimObject
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out,
+                                    const ossimRgbLutDataObject& lut);
+   /*!
+    * Will allocate 256 values for the color table
+    */
+   ossimRgbLutDataObject(unsigned long numberOfEntries=0);
+   ossimRgbLutDataObject(const ossimRgbLutDataObject& lut);
+   virtual ~ossimRgbLutDataObject();
+   const ossimRgbVector& operator[](unsigned int index)const
+      {
+         return index<theNumberOfEntries?theLut[index]:theLut[theNumberOfEntries-1];
+      }
+   ossimRgbVector& operator[](unsigned int index)
+      {
+         return index<theNumberOfEntries?theLut[index]:theLut[theNumberOfEntries-1];
+      }
+   const ossimRgbVector& operator[](int index)const
+      {
+         return index<(long)theNumberOfEntries?theLut[index]:theLut[theNumberOfEntries-1];
+      }
+   ossimRgbVector& operator[](int index)
+      {
+         return index<(long)theNumberOfEntries?theLut[index]:theLut[theNumberOfEntries-1];
+      }
+   const ossimRgbVector& operator[](double normalizedIndex)const
+      {
+         int index = int(normalizedIndex*theNumberOfEntries+.5);
+         if (index < 0)
+         {
+            index = 0;
+         }
+         return (*this)[index];
+      }
+   ossimRgbVector& operator[](double normalizedIndex)
+      {
+         int index = int(normalizedIndex*theNumberOfEntries+.5);
+         if (index < 0)
+         {
+            index = 0;
+         }
+         return (*this)[index];
+      }
+   long getNumberOfEntries()const{return theNumberOfEntries;}
+   int findIndex(const ossimRgbVector& rgb)
+      {
+         return findIndex(rgb.getR(),
+                          rgb.getG(),
+                          rgb.getB());
+      }
+   int findIndex(ossim_uint8 r, ossim_uint8 g, ossim_uint8 b);
+   ossimRgbLutDataObject& rotate(long numberOfElements=1);
+   ossimRgbLutDataObject  rotate(long numberOfElements=1)const;
+   
+   const ossimRgbLutDataObject& operator =(const ossimRgbLutDataObject& lut);
+   bool operator ==(const ossimRgbLutDataObject& lut)const;
+
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0)const;
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+protected:
+   ossimRgbVector *theLut;
+   ossim_uint32 theNumberOfEntries;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimRtti.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimRtti.cpp
new file mode 100644
index 0000000000..e9e1fb2edc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimRtti.cpp
@@ -0,0 +1,134 @@
+#include "ossimRtti.h"
+#include <iostream>
+#include <string.h>
+using namespace std;
+
+static const RTTITypeinfo* RTTI_base_null_type[] = { 0 };
+
+const RTTITypeinfo* RTTIdyntypeid::a[] = { 0 };
+
+const RTTITypeinfo RTTITypeinfo::null_type = RTTITypeinfo("NULL", RTTI_base_null_type,0,0);
+
+void RTTITypeinfo::add_subtype(const RTTITypeinfo* t)		//Adds t as last RTTITypeinfo in the
+{									//'subtypes' list. For this, the
+   const RTTITypeinfo** ptr = new const RTTITypeinfo*[ns+1];		//list is realloc'd with one extra entry.
+   int i; for(i=0;i<ns;i++) ptr[i] = subtypes[i];
+   ptr[i] = t;
+   ns++;
+   delete[] subtypes;
+   subtypes = ptr;
+}
+
+void RTTITypeinfo::del_subtype(const RTTITypeinfo* t) 		//Searches for t in the subtypes list
+{									//of this and removes it, if found.
+   int i; for(i=0;i<ns && subtypes[i]!=t;i++);
+   if (i<ns)
+     for(;i<ns-1;i++) subtypes[i] = subtypes[i+1];
+}
+
+RTTITypeinfo::RTTITypeinfo(const char* name,
+                           const RTTITypeinfo* bb[],
+                           void* (*f1)(int,void*),
+                           void* (*f2)())
+{
+  n       = strdup(name);
+  b = bb; //ns = 0; subtypes = 0;		//Create default RTTITypeinfo
+  cast    = f1;								//Attach casting func
+  new_obj = f2;								//Attach creation func
+  int i = 0;
+  for(i=0;b[i];i++)							//Add this as subtype to all its basetypes
+     ((RTTITypeinfo**)b)[i]->add_subtype(this);				//REMARK: Harmless const castaway
+}
+
+const char* RTTITypeinfo::getname() const
+{
+  return n;
+}
+
+
+RTTITypeinfo::~RTTITypeinfo()
+{
+   if(n)
+   {
+      free(n);
+      n = NULL;
+   }
+  int i = 0;
+   for(i=0;b[i];i++)
+   {
+      //Del this subtype from all its basetypes
+      ((RTTITypeinfo**)b)[i]->del_subtype(this); //REMARK: Harmless const castaway
+   }
+}
+
+int RTTITypeinfo::has_base(const RTTITypeinfo* p) const
+{
+  int i = 0;
+   for(i=0;b[i];i++)							//for all bases of this...
+      if (p->same(b[i]) || b[i]->has_base(p)) return 1;				//match found, return 1 or no match, search deeper
+   return 0;									//no match at all, return 0
+}
+
+void* RTTITypeinfo::create(const RTTITypeinfo* bt, const char* c) const	//Tries to create an obj of type-name
+{										//given by char*. Searches for this type in the
+   void* p = 0; int i;								//type-DAG rooted by this, creates it and returns
+										//it as cast to 'bt', where bt is either this or a
+										//direct base of this.
+   if (!strcmp(c,n))								//Want to create an obj of this type ?
+      p = (new_obj)? new_obj() : 0;						//Yes, do it if this type is instantiable.
+   else										//No, try with subclasses...
+      for(i=0;i<ns && !((p=subtypes[i]->create(this,c)));i++);			//Succeeded creating on ith subclass branch ?
+   if (!p) return 0;								//Couldn't create it in any way, abort.
+   if (bt==this) i = -1;							//Must cast to this's own type (i==-1)
+   else for(i=0;b[i] && b[i]!=bt;i++);						//Search to which base of this we should cast
+									        //Found: cast to ith base of this
+   return cast(i,p);								//Cast to ith base of to this, return as void*
+}
+
+RTTItypeid RTTItypeid::find_baseclass(const char* name)const
+{
+   if(strcmp(name, getname())==0)
+   {
+      return *this;
+   }
+   else if(num_baseclasses() == 0)
+   {
+      if(strcmp(name, getname()) == 0)
+      {
+         return *this;
+      }
+      return null_type();
+   }
+   else
+   {
+      int index = 0;
+
+      while(index < num_baseclasses())
+      {
+         RTTItypeid typeId = baseclass(index);
+         if(typeId == *this)
+         {
+	   return *this;//null_type();
+         }
+         if(strcmp(name, typeId.getname()) == 0)
+         {
+            return *this;
+         }
+         ++index;
+      }
+      index = 0;
+      while(index < num_baseclasses())
+      {
+         RTTItypeid typeId = baseclass(index);
+         if(typeId.find_baseclass(name) == typeId.null_type())
+         {
+            ++index;
+         }
+         else
+         {
+            return typeId;
+         }
+      }
+   }
+   return null_type();
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimRtti.h b/Utilities/OSSIM/ossim_core/base/common/ossimRtti.h
new file mode 100644
index 0000000000..fe2110605c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimRtti.h
@@ -0,0 +1,509 @@
+#ifndef RTTI_H
+#define RTTI_H
+
+#include <string.h>
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/* 
+   RTTI_H:	This file provides support for RTTI and generalized (virtual-base to derived and 
+		separate hierarchy branches) casting. There is also support for RT obj creation
+	  	from type names.
+
+		In order to enable these features for a class, two things should be done:
+
+		1)	insert the text TYPE_DATA (without ';') as the last item in the class-decl.
+		2)	in the .C file where the class's implementation resides, insert the following (without';'):
+		
+			RTTI_DEF(classname,"RT classname")	     if the class has no bases with RTTI
+ 			RTTI_DEFn(classname,"RT classname",b1,...bn) if the class has bases b1,...bn with RTTI
+
+			Use RTTI_DEF_INST instead of RTTI_DEF if you want to enable RT obj creation for classname.
+			You should provide then a public default ctor.
+			
+   RTTI is used via a class called RTTItypeid. A typeid describes a type of a class. typeids can be compared
+   with operator== and operator!= and can be retrieved from classes/pointers. They should provide all necessary 
+   support for any kind of RTTI/casting, as described by the macros below (by RTTI-class we mean a class having RTTI,
+   as described above). The 'return type' of the macros is listed between quotes:
+
+   'RTTItypeid'
+   STATIC_TYPE_INFO(T)		T=RTTI-class name. Returns a RTTItypeid with T's type. if T hasn't RTTI, a 
+				compile-time error occurs.
+   'RTTItypeid'
+   TYPE_INFO(p)		        p=ptr to a RTTI-class.  
+				Returns the RTTItypeid of the class-obj p is really pointing at. 
+			        If *p hasn't RTTI, a compile-time error occurs.	
+				If p==NULL, a special typeid for the NULL pointer is returned. 
+				This typeid has the name (const char*) "NULL".  
+   'T*'
+   PTR_CAST(T,p)		T=RTTI-class, p=RTTI-class ptr.
+				Returns p cast to the type T as a T*, if cast is possible, else
+				returns NULL. If *p or T have no RTTI, a compile-time error occurs.
+				Note that p can point to virtual base classes. Casting between separate
+				branches of a class hierarchy is also supported, as long as all classes
+				have RTTI. Therefore PTR_CAST is a fully general and safe operator.
+				If p==NULL, the operator returns NULL.
+
+   Some other macros. Not essential, provided mostly for convenience:
+   =================
+   const char*
+   STATIC_TYPE_NAME(T)		T=RTTI-class name. Returns the name (const char*) of T's type.
+				Provided for convenience. Compile-time error if T hasn't RTTI.
+   const char*
+   TYPE_NAME(p)			p=RTTI-class ptr. Returns the class name (char*) of real *p.
+				Provided for convenience.  Compile-time error if *p hasn't RTTI.
+   int				If p==NULL, "NULL" is returned.
+   DYN_CAST(t,p)		t=RTTItypeid. p=RTTI-class ptr.
+				Returns 1 if p can indeed be cast to t, else returns 0.
+				Compile-time error if *p hasn't RTTI.
+				If p==NULL, 1 is returned (NULL can be cast to anything).
+				This operator is useful when we just want to check that a pointer can be cast to
+				a RTTItypeid variable (which can be created/selected at run-time). For creating a RTTItypeid, 
+				construct a subclass of RTTItypeid called RTTIdyntypeid which allows construction from a const char*, i.e. from
+				a user specification and pass it to DYN_CAST.
+				DYN_TYPE can't return a typed pointer (since t is a RTTItypeid var and C++ has no 'real' type variables), 
+				but returns a 1/0 indicating whether the cast is possible or not. 
+   void*
+   UPTR_CAST(t,p)		t=RTTItypeid. p=RTTI-class ptr.
+				Returns p cast to a void* if cast succeeds, else returns NULL.
+				Again, p can point to virtual-bases and casts between separate branches of a class dag
+				are supported. this operator is practically the 'untyped' version of PTR_CAST, offering
+				the extra feature that the type is expressed by a run-time type variable (RTTItypeid).
+				Compile-time error if *p hasn't RTTI.
+
+  
+  Obsolete macros:		This set of macros is based on Stroustrup. They are not general and safe 
+  ===============		(e.g. virtual-base to derived casts are trapped as compile-time errors and casts
+				between separate class-dag branches are incorrectly done without any warnings). 
+				The above macros are including ALL functionality of these macros, which are
+				provided only for completeness:
+
+  OLD_PTR_CAST(T,p)		Like PTR_CAST(T,p), but without accepting p=ptr to virtual bases and performing
+				incorrect casts between separate branches of a class-dag.
+  OLD_UPTR_CAST(t,p)		Like UPTR_CAST(t,p), but with same problems as above.
+  OLD_DYN_CAST(t,p)		Like DYN_CAST(t,p), but with same problems as above.
+ 
+
+  RT Object Creation:		This feature enables the user to create objects of a RT-selected type in a generic manner.
+  ==================		Typically, we create/obtain a RT type (via a RTTItypeid t1). Then, having another RTTItypeid t2
+				(typically from the (STATIC_)TYPE_INFO of some ROOT class / ROOT* ptr, we call:
+
+				ROOT* new_obj = (ROOT*)t2.create(t1);
+
+				create() searches for t1 in the class DAG rooted at t2. If found, it creates a new obj of type 
+				t1 and returns it as a '(void*)(t2*)'. For example, we know above that we get a ROOT* since
+				t2 is ROOT's RTTItypeid, so we can _safely_ cast the void* to ROOT. If create() can't make the t1
+				object (there's no such type or the type is not declared via RTTI_DEF_INST), it returns NULL.
+				This gives a fully generic typeid-based factory method for RT obj creation.
+
+  REMARK:	RTTI support adds some additional info, both static+virtual, to a class. The current implementation
+  =======	adds a static object and some static functions and 2 virtual functions to each class desiring RTTI.
+		This may of course cause potential name-clash problems. In order to avoid this, all added identifiers
+		in the RTTI system are prefixed with RTTI_ (see the TYPE_DATA macro).
+  
+  REMARK_2:	There are two classes related to RTTI: RTTItypeid and RTTITypeinfo. A RTTItypeid is, as it says, an 'id for a type'
+  ========	It actually wraps a RTTITypeinfo*, where a RTTITypeinfo contains the actual encoding of a class type.
+		You can freely create/copy/destroy/manipulate RTTItypeid's, but you should NEVER deal directly
+		with RTTITypeinfo. A RTTITypeinfo should actually be created ONLY by the TYPE_DATA macros, as part of a class definition,
+		since the RTTITypeinfo encodes a type info for an EXISTING class. All type-related stuff should be therefore
+		handled via RTTItypeid's. If you really want to dynamically create a dummy typeid, use RTTIdyntypeid class.
+
+  REMARK 3:	All names introduced by this RTTI implementation (RTTItypeid,RTTIdyntypeid,RTTITypeinfo,etc)
+  =========	are prefixed by RTTI, to make this system easily acceptable by e.g. C++ environments which happen to 
+	 	already support typeids.
+
+*/				
+
+	
+//////////////////////////////////////////////////////////////
+
+#include <stdlib.h>							// for free
+#include <string.h>							// for strdup,strcmp
+#include "ossimConstants.h"
+/////////////////////////////////////////////////////////////
+
+class OSSIMDLLEXPORT RTTITypeinfo;
+
+class OSSIMDLLEXPORT RTTItypeid	
+		{							// Main class for RTTI interface.
+		public:
+
+		                    RTTItypeid(const RTTITypeinfo* p):  id(p)  {}
+				    RTTItypeid(); 			 
+		   int 		    operator==(RTTItypeid) const;
+		   int 		    operator!=(RTTItypeid) const;
+		   const RTTITypeinfo* get_info() const    	 { return id; }
+		   int 		    can_cast(RTTItypeid) const;	 	// 1 if the arg can be cast to this, else 0
+		   const char* 	    getname() const;
+		   int 		    num_subclasses() const;		// Return # subclasses of this
+		   RTTItypeid	    subclass(int) const;		// Return ith subclass of this
+		   int		    num_baseclasses() const;		// Return # baseclasses of this
+		   RTTItypeid 	    baseclass(int) const;		// Return ith baseclass of this
+		   void*	    create(RTTItypeid) const;	 	// Tries to create an instance of a subclass of this
+								 	// having of type given by the RTTItypeid arg. If ok, it returns it 
+								 	// casted to the class-type of this and then to void* 
+		   int		    can_create() const;			// Return 1 if this type is instantiable, else 0
+                   RTTItypeid       find_baseclass(const char* name)const;// 
+		   static RTTItypeid 
+                   null_type();			// the RTTItypeid for NULL ptrs
+                   
+	        protected:
+
+		    const RTTITypeinfo* id;				// RTTItypeid implementation (the only data-member)
+		};
+
+
+class OSSIMDLLEXPORT RTTIdyntypeid : public RTTItypeid					//Class for dynamic type creation from user strings.
+		{							//Useful for creating typeids at RT for comparison
+		public:							//purposes.
+				    RTTIdyntypeid(const char*);
+				   ~RTTIdyntypeid();
+		private:
+				    static const RTTITypeinfo* a[];
+		};
+
+///////////////////////////////////////////////////////////////////
+
+class OSSIMDLLEXPORT RTTITypeinfo {							//Implementation of type-related info
+		public:
+
+		               RTTITypeinfo(const char* name, const RTTITypeinfo* bb[],
+					 void* (*)(int,void*),void* (*)());
+		  	      ~RTTITypeinfo();
+		   const char* getname() const;				//Returns name of this RTTITypeinfo	
+		   int 	       same(const RTTITypeinfo*) const;		//Compares 2 RTTITypeinfo objs
+		   int         can_cast(const RTTITypeinfo*) const;	//1 if the arg can be cast to this, else 0
+		   int         has_base(const RTTITypeinfo*) const;	//1 if this has the arg as some base, else 0		
+		   
+		   
+		   const RTTITypeinfo*  
+		   	       subclass(int=0) const;			//get i-th subclass of this, if any, else NULL
+		   int	       num_subclasses() const;			//get # subclasses of this 
+		   void*       create(const RTTITypeinfo*,const char*) const;	//search for a subclass named char*,
+									//create obj of it and return it cast to 
+									//the RTTITypeinfo* type, which is either 
+									//this or a direct base of this. 
+		   int	       can_create() const;			//Returns 1 if this type has a default ctor, else 0			
+			
+		private:
+
+		   char* 	          n;				//type name 
+	           const RTTITypeinfo**   b;				//base types (NULL-ended array of RTTITypeinfo's for this's direct bases)
+		   int			  ns;				//#subtypes of this type
+		   const RTTITypeinfo**	  subtypes;			//types derived from this type
+		   static const RTTITypeinfo null_type;			//convenience type info for a 'null' type
+		   void*		  (*new_obj)();			//func to create a new obj of this type
+		   void*		  (*cast)(int,void*);		//func to cast an obj of this type to
+									//ith baseclass of it or to itself
+		   
+		   void 		  add_subtype(const RTTITypeinfo*);//adds a subtype to this's subtypes[]	
+		   void			  del_subtype(const RTTITypeinfo*);//dels a subtype from this's subtypes[]
+
+		   friend class		  RTTItypeid;			//for null_type
+		};      	
+
+
+
+
+inline int RTTITypeinfo::num_subclasses() const				//Return # subclasses of this
+{
+  return ns;
+} 
+
+inline const RTTITypeinfo* RTTITypeinfo::subclass(int i) const		//Return ith subclass of this, else NULL;
+{
+  return (i>=0 && i<ns)? subtypes[i]: 0;
+} 
+
+inline int RTTITypeinfo::same(const RTTITypeinfo* p) const			//Compare 2 RTTITypeinfo's:
+{  										//First, try to see if it's the same
+   return this==p || !strcmp(n,p->n); 						//'physical' RTTITypeinfo (which should be the case,
+}										//since we create them per-class and not per-obj).
+  										//If this fails, still do a textual name comaprison.
+
+inline int RTTITypeinfo::can_cast(const RTTITypeinfo* p) const
+{  
+   return same(p) || p->has_base(this); 
+}
+
+inline int RTTITypeinfo::can_create() const
+{
+   return new_obj!=0;
+}
+
+/////////////////////////////////////////////////////////////////
+//
+// RTTItypeid methods:
+//
+
+inline RTTItypeid RTTItypeid::null_type()
+{
+   return &(RTTITypeinfo::null_type);
+}
+
+inline RTTItypeid::RTTItypeid(): id(null_type().id)   
+{
+}
+
+inline int RTTItypeid::operator==(RTTItypeid i) const
+{ 
+  return id->same(i.id); 
+}
+
+inline int RTTItypeid::operator!=(RTTItypeid i) const
+{
+  return !(id->same(i.id));
+}
+
+inline int RTTItypeid::can_cast(RTTItypeid i) const
+{
+  return id->can_cast(i.id);
+}
+
+
+inline const char* RTTItypeid::getname() const
+{
+  return id->getname();
+}
+
+inline int RTTItypeid::num_subclasses() const
+{
+  return id->num_subclasses();
+}
+
+inline RTTItypeid RTTItypeid::subclass(int i) const
+{
+  return id->subclass(i);
+}
+
+inline int RTTItypeid::num_baseclasses() const
+{
+  int i; for(i=0;id->b[i];i++);
+  return i;
+}
+
+inline RTTItypeid RTTItypeid::baseclass(int i) const
+{
+  return id->b[i];
+}
+
+inline void* RTTItypeid::create(RTTItypeid t) const
+{
+  return id->create(id,t.getname());
+}
+
+inline int RTTItypeid::can_create() const
+{
+  return id->can_create();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+inline RTTIdyntypeid::RTTIdyntypeid(const char* c) : RTTItypeid(new RTTITypeinfo(c,a,0,0)) { }   //create a dummy RTTITypeinfo
+inline RTTIdyntypeid::~RTTIdyntypeid()
+{
+   if(id)
+   {
+      delete id;
+      id = 0;
+   }
+}				    //delete the dummy RTTITypeinfo
+		
+
+/////////////////////////////////////////////////////////////////////////////////////
+		
+// 1. Main operators
+#define STATIC_TYPE_INFO(T)   T::RTTI_sinfo()
+#define TYPE_INFO(p)          ((p)? (p)->RTTI_vinfo() : RTTItypeid::null_type() )
+#define PTR_CAST(T,p) 	      ((p)? (T*)((p)->RTTI_cast(STATIC_TYPE_INFO(T))) : 0)
+
+
+// 2. Convenience operators
+#define STATIC_TYPE_NAME(T)   (STATIC_TYPE_INFO(T).getname())	
+#define TYPE_NAME(p)	      ((p)? ((p)->RTTI_vinfo().getname()) : RTTItypeid::null_type().getname())	
+#define DYN_CAST(t,p)	      ((p)? ((p)->RTTI_cast((t))!=0) : 1)
+#define UPTR_CAST(t,p)	      ((p)? ((p)->RTTI_cast((t))) : 0)	
+
+// 3. Unsafe operators (see Stroustrup)
+#define OLD_PTR_CAST(T,p)     ((p)? ((STATIC_TYPE_INFO(T).can_cast((p)->RTTI_vinfo()))? (T*)p : 0) : 0)
+#define OLD_UPTR_CAST(t,p)    ((p)? ((t).can_cast((p)->RTTI_vinfo())? (void*)p : 0) : 0)
+#define OLD_DYN_CAST(t,p)     ((p)? ((t).can_cast((p)->RTTI_vinfo())? 1 : 0) : 1)
+
+
+// Definition of TYPE_DATA for a RTTI-class: introduces one static RTTITypeinfo data-member
+// and a couple of virtuals.
+
+#define TYPE_DATA			 		          \
+	protected:					          \
+	   static  const  RTTITypeinfo RTTI_obj; 		  \
+	   static  void*  RTTI_scast(int,void*);	          \
+	   static  void*  RTTI_new();			          \
+	public:						          \
+	   virtual RTTItypeid RTTI_vinfo() const { return &RTTI_obj; }\
+	   static  RTTItypeid RTTI_sinfo()	 { return &RTTI_obj; }\
+	   virtual void*  RTTI_cast(RTTItypeid);\
+	   virtual const void*  RTTI_cast(RTTItypeid)const;
+	
+
+
+// Definition of auxiliary data-structs supporting RTTI for a class: defines the static RTTITypeinfo
+// object of that class and its associated virtuals.
+
+// Auxiliary definition of the construction method:
+#define RTTI_NEW(cls,name)     void* cls::RTTI_new() { return new cls; }	\
+			       const RTTITypeinfo cls::RTTI_obj = RTTITypeinfo(name,RTTI_base_##cls,cls::RTTI_scast,cls::RTTI_new);
+
+#define RTTI_NO_NEW(cls,name)  const RTTITypeinfo cls::RTTI_obj = RTTITypeinfo(name,RTTI_base_##cls,cls::RTTI_scast,0);
+
+
+
+//////////////////////////////////////////////////////////////////
+//
+//	Top-level macros:
+//
+
+#define RTTI_DEF_BASE(cls,name)					\
+	static const RTTITypeinfo* RTTI_base_##cls [] = { 0 };\
+	void* cls::RTTI_cast(RTTItypeid t)			\
+	{							\
+	   if (t == &RTTI_obj) return this;			\
+	   return 0;						\
+	}							\
+	const void* cls::RTTI_cast(RTTItypeid t)const	\
+	{							\
+	   if (t == &RTTI_obj) return this;			\
+	   return 0;						\
+	}							\
+	void* cls::RTTI_scast(int i,void* p)			\
+	{  cls* ptr = (cls*)p; return ptr; }			
+	
+
+#define RTTI_DEF1_BASE(cls,name,b1)				\
+        static const RTTITypeinfo* RTTI_base_##cls [] = 	\
+	       { STATIC_TYPE_INFO(b1).get_info(),0 };		\
+  	void* cls::RTTI_cast(RTTItypeid t)			\
+	{							\
+	   if (t == &RTTI_obj) return this;			\
+	   void* ptr;						\
+	   if ((ptr=b1::RTTI_cast(t))) return ptr;		\
+	   return 0;						\
+	}							\
+  	const void* cls::RTTI_cast(RTTItypeid t)const	\
+	{							\
+	   if (t == &RTTI_obj) return this;			\
+	   const void* ptr;						\
+	   if ((ptr=b1::RTTI_cast(t))) return ptr;		\
+	   return 0;						\
+	}							\
+	void* cls::RTTI_scast(int i,void* p)			\
+	{  cls* ptr = (cls*)p;					\
+	   switch(i)						\
+	   {  case  0: return (b1*)ptr;	 }			\
+	   return ptr;						\
+	}							
+									
+
+#define RTTI_DEF2_BASE(cls,name,b1,b2)				\
+        static const RTTITypeinfo* RTTI_base_##cls [] = 	\
+	       { STATIC_TYPE_INFO(b1).get_info(),		\
+		 STATIC_TYPE_INFO(b2).get_info(),0 };		\
+  	void* cls::RTTI_cast(RTTItypeid t)			\
+	{							\
+	   if (t == &RTTI_obj) return this;			\
+	   void* ptr;						\
+	   if ((ptr=b1::RTTI_cast(t))) return ptr;		\
+	   if ((ptr=b2::RTTI_cast(t))) return ptr;		\
+	   return 0;						\
+	}							\
+  	const void* cls::RTTI_cast(RTTItypeid t)const	\
+	{							\
+	   if (t == &RTTI_obj) return this;			\
+	   const void* ptr;					\
+	   if ((ptr=b1::RTTI_cast(t))) return ptr;		\
+	   if ((ptr=b2::RTTI_cast(t))) return ptr;		\
+	   return 0;						\
+	}							\
+	void* cls::RTTI_scast(int i,void* p)			\
+	{  cls* ptr = (cls*)p;					\
+	   switch(i)						\
+	   {  case  0: return (b1*)ptr;				\
+	      case  1: return (b2*)ptr;				\
+	   }							\
+	   return ptr;						\
+	}							
+	
+#define RTTI_DEF3_BASE(cls,name,b1,b2,b3)			\
+        static const RTTITypeinfo* RTTI_base_##cls [] = 	\
+	       { STATIC_TYPE_INFO(b1).get_info(),		\
+		 STATIC_TYPE_INFO(b2).get_info(),		\
+		 STATIC_TYPE_INFO(b3).get_info(), 0 };		\
+  	void* cls::RTTI_cast(RTTItypeid t)			\
+	{							\
+	   if (t == &RTTI_obj) return this;			\
+	   void* ptr;						\
+	   if ((ptr=b1::RTTI_cast(t))) return ptr;		\
+	   if ((ptr=b2::RTTI_cast(t))) return ptr;		\
+	   if ((ptr=b3::RTTI_cast(t))) return ptr;		\
+	   return 0;						\
+	}							\
+  	const void* cls::RTTI_cast(RTTItypeid t)const	\
+	{							\
+	   if (t == &RTTI_obj) return this;			\
+	   const void* ptr;					\
+	   if ((ptr=b1::RTTI_cast(t))) return ptr;		\
+	   if ((ptr=b2::RTTI_cast(t))) return ptr;		\
+	   if ((ptr=b3::RTTI_cast(t))) return ptr;		\
+	   return 0;						\
+	}							\
+	void* cls::RTTI_scast(int i,void* p)			\
+	{  cls* ptr = (cls*)p;					\
+	   switch(i)						\
+	   {  case  0: return (b1*)ptr;				\
+	      case  1: return (b2*)ptr;				\
+	      case  2: return (b3*)ptr;				\
+	   }							\
+	   return ptr;						\
+	}							
+	
+					
+
+#define RTTI_DEF_INST(cls,name)					\
+	RTTI_DEF_BASE(cls,name)					\
+	RTTI_NEW(cls,name)			
+
+#define RTTI_DEF(cls,name)					\
+	RTTI_DEF_BASE(cls,name)					\
+	RTTI_NO_NEW(cls,name)
+
+#define RTTI_DEF1_INST(cls,name,b1)				\
+	RTTI_DEF1_BASE(cls,name,b1)				\
+	RTTI_NEW(cls,name)			
+
+#define RTTI_DEF1(cls,name,b1)					\
+	RTTI_DEF1_BASE(cls,name,b1)				\
+	RTTI_NO_NEW(cls,name)			
+	
+#define RTTI_DEF2_INST(cls,name,b1,b2)				\
+	RTTI_DEF2_BASE(cls,name,b1,b2)				\
+	RTTI_NEW(cls,name)			
+
+#define RTTI_DEF2(cls,name,b1,b2)				\
+	RTTI_DEF2_BASE(cls,name,b1,b2)				\
+	RTTI_NO_NEW(cls,name)			
+
+#define RTTI_DEF3_INST(cls,name,b1,b2,b3)			\
+	RTTI_DEF3_BASE(cls,name,b1,b2,b3)			\
+	RTTI_NEW(cls,name)	
+
+#define RTTI_DEF3(cls,name,b1,b2,b3)				\
+	RTTI_DEF3_BASE(cls,name,b1,b2,b3)			\
+	RTTI_NO_NEW(cls,name)			
+
+
+#endif
+
+
+			 
+
+		
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimScopedLock.h b/Utilities/OSSIM/ossim_core/base/common/ossimScopedLock.h
new file mode 100644
index 0000000000..58b9aab4c4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimScopedLock.h
@@ -0,0 +1,40 @@
+//*************************************************************************
+// Copyright (C) 2004 Intelligence Data Sytems, Inc.  All rights reserved.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// NOTES: This was taken from OpenThreads::ScopedLock
+//       
+//
+//************************************************************************** 
+// $Id: ossimScopedLock.h,v 1.2 2005/07/15 11:05:10 gpotts Exp $
+#ifndef ossimScopedLock_HEADER
+#define ossimScopedLock_HEADER
+
+template <class T> class ossimScopedLock
+{
+    private:
+        T& theLock;
+        ossimScopedLock(const ossimScopedLock&); // prevent copy
+        ossimScopedLock& operator=(const ossimScopedLock&); // prevent assign
+    public:
+        explicit ossimScopedLock(T& m):theLock(m) {theLock.lock();}
+        ~ossimScopedLock(){theLock.unlock();}
+};
+
+template <class T> class ossimReverseScopedLock
+{
+    private:
+        T& theLock;
+        ossimReverseScopedLock(const ossimReverseScopedLock&); // prevent copy
+        ossimReverseScopedLock& operator=(const ossimReverseScopedLock&); // prevent assign
+    public:
+        explicit ossimReverseScopedLock(T& m):theLock(m) {theLock.unlock();}
+        ~ossimReverseScopedLock(){theLock.lock();}
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimSource.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimSource.cpp
new file mode 100644
index 0000000000..cfcc361a88
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimSource.cpp
@@ -0,0 +1,167 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimSource.cpp,v 1.45 2005/12/08 13:50:20 gpotts Exp $
+#include <base/common/ossimSource.h>
+#include <base/common/ossimDataObject.h>
+#include <base/common/ossimIdManager.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/property/ossimBooleanProperty.h>
+
+RTTI_DEF2(ossimSource, "ossimSource",
+          ossimConnectableObject, ossimErrorStatusInterface)
+
+
+ossimSource::ossimSource(ossimObject* owner)
+   :
+      ossimConnectableObject(owner),
+      theEnableFlag(true),
+      theInitializedFlag(false)
+{
+}
+
+ossimSource::ossimSource(const ossimSource &rhs)
+   :
+      ossimConnectableObject(rhs),
+      theEnableFlag(rhs.theEnableFlag),
+      theInitializedFlag(rhs.theInitializedFlag)
+{
+}
+
+ossimSource::ossimSource(ossimObject* owner,
+                         ossim_uint32 inputListSize,
+                         ossim_uint32 outputListSize,
+                         bool inputListIsFixedFlag,
+                         bool outputListIsFixedFlag)
+   :
+      ossimConnectableObject(owner, inputListSize, outputListSize,
+                             inputListIsFixedFlag, outputListIsFixedFlag),
+      theEnableFlag(true),
+      theInitializedFlag(false)
+{}
+
+ossimSource::~ossimSource()   
+{
+}
+
+bool ossimSource::saveState(ossimKeywordlist& kwl,
+                            const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::ENABLED_KW,
+           (int)theEnableFlag,
+           true);
+
+   return ossimConnectableObject::saveState(kwl, prefix);
+}
+
+bool ossimSource::loadState(const ossimKeywordlist& kwl,
+                            const char* prefix)
+{
+   const char* lookup = kwl.find(prefix,
+                                 ossimKeywordNames::ENABLED_KW);
+   if(lookup)
+   {
+      theEnableFlag = ossimString(lookup).toBool();
+   }
+
+   return ossimConnectableObject::loadState(kwl, prefix);
+}
+
+bool ossimSource::isSourceEnabled()const
+{
+   return theEnableFlag;
+}
+
+void ossimSource::enableSource()
+{
+   setEnableFlag(true);
+}
+
+void ossimSource::disableSource()
+{
+   setEnableFlag(false);
+}
+
+bool ossimSource::getEnableFlag() const
+{
+   return theEnableFlag;
+}
+
+void ossimSource::setEnableFlag(bool flag)
+{
+   theEnableFlag = flag;
+}
+
+bool ossimSource::isInitialized() const
+{
+   return theInitializedFlag;
+}
+
+void ossimSource::setInitializedFlag(bool flag)
+{
+   theInitializedFlag = flag;
+}
+
+void ossimSource::initialize()
+{
+}
+
+void ossimSource::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property.valid()) return;
+
+   ossimString name = property->getName();
+   name = name.downcase();
+   
+   if(name == ossimKeywordNames::ENABLED_KW)
+   {
+      ossimString value;
+      
+      property->valueToString(value);
+      setEnableFlag(value.toBool());
+   }
+   else
+   {
+      ossimConnectableObject::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimSource::getProperty(const ossimString& name)const
+{
+   if( (name == "Enabled") || (name == ossimKeywordNames::ENABLED_KW) )
+   {
+      return new ossimBooleanProperty(ossimKeywordNames::ENABLED_KW,theEnableFlag);
+   }
+   return ossimConnectableObject::getProperty(name);
+}
+
+void ossimSource::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimConnectableObject::getPropertyNames(propertyNames);
+   
+   propertyNames.push_back(ossimKeywordNames::ENABLED_KW);
+}
+
+const ossimSource& ossimSource::operator=(const ossimSource &rhs)
+{
+   return *this;
+}
+
+std::ostream& ossimSource::print(std::ostream& out) const
+{
+   out << "ossimSource::print:\n"
+      << "theEnableFlag:       " << theEnableFlag
+      << "\ntheInitializedFlag:  " << theInitializedFlag
+      << endl;
+
+   return ossimErrorStatusInterface::print(out);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimSource.h b/Utilities/OSSIM/ossim_core/base/common/ossimSource.h
new file mode 100644
index 0000000000..66d22bbb2b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimSource.h
@@ -0,0 +1,83 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+// Base class for any object that can be a source.  Derives from
+// ossimConnectableObject since all source's should be connectable
+//
+//*************************************************************************
+// $Id: ossimSource.h,v 1.41 2004/11/11 20:17:25 gpotts Exp $
+
+#ifndef ossimSource_HEADER
+#define ossimSource_HEADER
+
+#include "base/common/ossimConnectableObject.h"
+#include "base/common/ossimErrorStatusInterface.h"
+#include "base/common/ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimDataObject;
+
+class OSSIMDLLEXPORT ossimSource : public ossimConnectableObject,
+				   public ossimErrorStatusInterface
+{
+public:
+   ossimSource(ossimObject* owner=0);
+   ossimSource(ossimObject* owner,
+               ossim_uint32 inputListSize,
+               ossim_uint32 outputListSize,
+               bool inputListIsFixedFlag=true,
+               bool outputListIsFixedFlag=true);
+   
+   virtual ~ossimSource();
+
+   virtual bool isSourceEnabled()const;
+   virtual void enableSource();
+   virtual void disableSource();
+   virtual bool getEnableFlag() const;
+   virtual void setEnableFlag(bool flag);
+
+   virtual bool isInitialized() const;
+   virtual void setInitializedFlag(bool flag);
+   virtual void initialize();
+
+   /*---------------------- PROPERTY INTERFACE ---------------------------*/
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   /*--------------------- PROPERTY INTERFACE END ------------------------*/
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual std::ostream& print(std::ostream& out) const;
+
+protected:
+   ossimSource(const ossimSource &rhs);
+   const ossimSource& operator=(const ossimSource &rhs);
+
+   bool   theEnableFlag;
+   bool   theInitializedFlag;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimStdOutProgress.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimStdOutProgress.cpp
new file mode 100644
index 0000000000..c5e12d2eae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimStdOutProgress.cpp
@@ -0,0 +1,58 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimStdOutProgress.cpp,v 1.5 2005/10/17 18:37:16 gpotts Exp $
+#include "ossimStdOutProgress.h"
+
+RTTI_DEF1(ossimStdOutProgress, "ossimStdOutProgress", ossimProcessListener);
+
+ossimStdOutProgress theStdOutProgress;
+
+ossimStdOutProgress::ossimStdOutProgress(long precision, bool flushStream)
+   :
+      ossimProcessListener(),
+      thePrecision(precision),
+      theFlushStreamFlag(flushStream)
+{
+}
+
+void ossimStdOutProgress::processProgressEvent(ossimProcessProgressEvent& event)
+{
+   if (event.getOutputMessageFlag())
+   {
+      ossimString s;
+      event.getMessage(s);
+      if (!s.empty())
+      {
+		  ossimNotify(ossimNotifyLevel_NOTICE) << s.c_str() << std::endl;
+      }
+      return; // Don't output percentage on a message update.
+   }
+
+   
+   double p = event.getPercentComplete();
+   ossimNotify(ossimNotifyLevel_NOTICE)
+	   << std::setiosflags(std::ios::fixed)
+      << std::setprecision(thePrecision)
+      << p << "%\r";
+   
+   if(theFlushStreamFlag)
+   {
+      (p != 100.0) ?
+         ossimNotify(ossimNotifyLevel_NOTICE).flush() :
+         ossimNotify(ossimNotifyLevel_NOTICE) << "\n";
+   }
+}
+
+void ossimStdOutProgress::setFlushStreamFlag(bool flag)
+{
+   theFlushStreamFlag = flag;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimStdOutProgress.h b/Utilities/OSSIM/ossim_core/base/common/ossimStdOutProgress.h
new file mode 100644
index 0000000000..5183dd6923
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimStdOutProgress.h
@@ -0,0 +1,33 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimStdOutProgress.h,v 1.16 2004/10/06 15:35:17 dburken Exp $
+#ifndef ossimStdOutProgress_HEADER
+#define ossimStdOutProgress_HEADER
+#include <iostream>
+#include <base/common/events/ossimProcessListener.h>
+#include <base/common/events/ossimProcessProgressEvent.h>
+#include <base/context/ossimNotifyContext.h>
+class OSSIMDLLEXPORT ossimStdOutProgress : public ossimProcessListener
+{
+public:
+   ossimStdOutProgress(long precision = 0, bool flushStream=false);
+
+   virtual void processProgressEvent(ossimProcessProgressEvent& event);
+      
+   virtual void setFlushStreamFlag(bool flag);
+
+protected:
+   long thePrecision;
+   bool theFlushStreamFlag;
+TYPE_DATA
+};
+OSSIMDLLEXPORT extern ossimStdOutProgress theStdOutProgress;
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimStreamBase.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimStreamBase.cpp
new file mode 100644
index 0000000000..d4b829dbfe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimStreamBase.cpp
@@ -0,0 +1,3 @@
+#include "ossimStreamBase.h"
+
+RTTI_DEF1(ossimStreamBase, "ossimStreamBase", ossimObject);
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimStreamBase.h b/Utilities/OSSIM/ossim_core/base/common/ossimStreamBase.h
new file mode 100644
index 0000000000..58671dc4a9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimStreamBase.h
@@ -0,0 +1,29 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//
+//*******************************************************************
+//  $Id: ossimStreamBase.h,v 1.3 2005/11/14 13:58:51 gpotts Exp $
+//
+#ifndef ossimStreamBase_HEADER
+#define ossimStreamBase_HEADER
+#include <iostream>
+#include "ossimObject.h"
+
+class OSSIM_DLL ossimStreamBase : public ossimObject, virtual public std::ios
+{
+public:
+   ossimStreamBase(){}
+   ossimStreamBase(std::streambuf* buf)
+   {
+      init(buf);
+   }
+TYPE_DATA   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimTrace.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimTrace.cpp
new file mode 100644
index 0000000000..0af738e37c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimTrace.cpp
@@ -0,0 +1,40 @@
+//*****************************************************************************
+// FILE: ossimTrace.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimTrace
+//
+// SOFTWARE HISTORY:
+//>
+//   24Apr2001  Oscar Kramer
+//              Initial coding.
+//<
+//*****************************************************************************
+// $Id: ossimTrace.cpp,v 1.7 2005/04/18 20:46:13 dburken Exp $
+
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimTraceManager.h>
+#include <base/common/ossimCommon.h>
+//*****************************************************************************
+//  CONSTRUCTOR: ossimTrace
+//  
+//*****************************************************************************
+ossimTrace::ossimTrace(const ossimString& trace_name)
+   :
+      theTraceName   (trace_name),
+      theEnabledFlag (false)
+{
+   ossimTraceManager::instance()->addTrace(this);
+}
+
+ossimTrace::~ossimTrace()
+{
+   ossimTraceManager::instance()->removeTrace(this);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimTrace.h b/Utilities/OSSIM/ossim_core/base/common/ossimTrace.h
new file mode 100644
index 0000000000..ffef22f05d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimTrace.h
@@ -0,0 +1,72 @@
+//*****************************************************************************
+// FILE: ossimTrace.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimTrace. Used for tracing code execution.
+//   Implemented as a singluy linked list of ossimTrace objects.
+//
+// SOFTWARE HISTORY:
+//   24Apr2001  Oscar Kramer
+//              Initial coding.
+//*****************************************************************************
+// $Id: ossimTrace.h,v 1.12 2005/04/18 20:46:13 dburken Exp $
+
+#ifndef ossimTrace_HEADER
+#define ossimTrace_HEADER
+
+#include <iostream>  // for "clog"
+#include <base/data_types/ossimString.h>
+#include <base/context/ossimNotifyContext.h>
+
+// Macro for use with trace...
+#define CLOG ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " (\"" __FILE__ "\", line " << __LINE__ << ") DEBUG: "
+
+
+class OSSIMDLLEXPORT ossimTrace
+{
+public:
+   ossimTrace( const ossimString& trace_name );
+   ~ossimTrace();
+
+   /**
+    * @returns true if enabled false if not.
+    */
+   bool isEnabled() const { return theEnabledFlag; }
+
+   /**
+    * Returns "theTraceName" as an ossimString.
+    */
+   ossimString getTraceName() const { return theTraceName; }
+
+
+   /**
+    * Sets "theEnabled" flag.
+    *
+    * @param flag true == enabled, false == disabled.
+    */
+   void setTraceFlag(bool flag) { theEnabledFlag = flag; }
+   
+   /**
+    * Operator() for ossimTrace.  Given the static instance:
+    * static ossimTrace traceDebug("myTrace");
+    *
+    * You can do:
+    * if (traceDebug())
+    * {
+    *     CLOG << "Your trace stuff goes here..." << endl;
+    * }
+    */
+   bool operator()() const { return theEnabledFlag; }
+
+private:
+   ossimString                theTraceName;
+   bool                       theEnabledFlag;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimTraceManager.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimTraceManager.cpp
new file mode 100644
index 0000000000..a1d31b7f96
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimTraceManager.cpp
@@ -0,0 +1,105 @@
+//*****************************************************************************
+// Copyright (C) 2005 Garrett Potts, all rights reserved.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+// 
+// DESCRIPTION:
+//   Contains declaration of class ossimTraceManager.
+//
+//*****************************************************************************
+// $Id: ossimTraceManager.cpp,v 1.2 2005/05/17 18:17:34 dburken Exp $
+
+#include <algorithm>
+
+#include <base/common/ossimTraceManager.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimRegExp.h>
+
+ossimTraceManager* ossimTraceManager::theInstance = 0;
+
+ossimTraceManager::ossimTraceManager()
+{
+   theInstance = this;
+}
+
+ossimTraceManager* ossimTraceManager::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimTraceManager;
+   }
+   
+   return theInstance;
+}
+
+void ossimTraceManager::setTracePattern(const ossimString& pattern)
+{
+   thePattern = pattern;
+   setTraceFlags(true);
+}
+
+void ossimTraceManager::addTrace(ossimTrace* traceObj)
+{
+   if(!traceObj)
+   {
+      return;
+   }
+   
+   std::vector<ossimTrace*>::iterator iter = std::find(theTraceList.begin(),
+                                                       theTraceList.end(),
+                                                       traceObj);
+   if(iter == theTraceList.end())
+   {
+      theTraceList.push_back(traceObj);
+
+      if(thePattern.size())
+      {
+         ossimRegExp rxp;
+         rxp.compile(thePattern.c_str());
+         if(rxp.find(traceObj->getTraceName().c_str()))
+         {
+            // Found a match so set the flag and increment the counter.
+            traceObj->setTraceFlag(true);
+         }
+         else
+         {
+            traceObj->setTraceFlag(false);
+         }
+      }
+      else
+      {
+         traceObj->setTraceFlag(false);
+      } 
+   }
+}
+
+void ossimTraceManager::removeTrace(ossimTrace* traceObj)
+{
+   std::vector<ossimTrace*>::iterator iter = std::find(theTraceList.begin(),
+                                                       theTraceList.end(),
+                                                       traceObj);
+
+   if(iter !=  theTraceList.end())
+   {
+      theTraceList.erase(iter);
+   }
+}
+
+void ossimTraceManager::setTraceFlags(bool flag)
+{
+   ossimRegExp rxp;
+   rxp.compile(thePattern.c_str());
+   
+   for(ossim_uint32 idx = 0; idx < theTraceList.size(); ++idx)
+   {
+      if (rxp.find(theTraceList[idx]->getTraceName().c_str()))
+      {
+         // Found a match so set the flag and increment the counter.
+         theTraceList[idx]->setTraceFlag(flag);
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimTraceManager.h b/Utilities/OSSIM/ossim_core/base/common/ossimTraceManager.h
new file mode 100644
index 0000000000..f7458b64b6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimTraceManager.h
@@ -0,0 +1,69 @@
+//*****************************************************************************
+// Copyright (C) 2005 Garrett Potts, all rights reserved.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+// 
+// DESCRIPTION:
+//   Contains declaration of class ossimTraceManager.
+//
+//*****************************************************************************
+// $Id: ossimTraceManager.h,v 1.1 2005/04/18 20:44:56 dburken Exp $
+#ifndef ossimTraceManager_HEADER
+#define ossimTraceManager_HEADER
+
+#include <base/data_types/ossimString.h>
+
+class ossimTrace;
+
+class OSSIMDLLEXPORT ossimTraceManager
+{
+public:
+   /**
+    * @return ossimTraceManager* to instance of the ossim trace manager.
+    */
+   static ossimTraceManager* instance();
+
+   /**
+    * Sets "thePattern" to "pattern", then calls setTraceFlags(true).
+    *
+    * @param pattern Regular expression to enable trace for.
+    */
+   void setTracePattern(const ossimString& pattern);
+
+   /**
+    * @param traceObj ossimTrace* to add to "theTraceList".
+    */
+   void addTrace(ossimTrace* traceObj);
+
+   /**
+    * @param traceObj ossimTrace* to remove from "theTraceList".
+    */
+   void removeTrace(ossimTrace* traceObj);
+   
+protected:
+   /** Protected default constructor. */
+   ossimTraceManager();
+
+private:
+   /**
+    * Loops through "theTraceList" and sets any trace object's enable flag to
+    * flag if it matches regular expression of "thePattern".
+    * For trace objects not matching "thePattern" no action is taken.
+    */
+   void setTraceFlags(bool flag);
+
+   /** The instance of this manager. */
+   static ossimTraceManager* theInstance;
+
+   /** The regular expression pattern like "ossimDynamic|ossimGdal". */
+   ossimString               thePattern;
+
+   /** The list of trace objects. */
+   std::vector<ossimTrace*>  theTraceList;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimViewController.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimViewController.cpp
new file mode 100644
index 0000000000..fda21c6a91
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimViewController.cpp
@@ -0,0 +1,173 @@
+#include <base/common/ossimViewController.h>
+#include <base/common/ossimViewInterface.h>
+#include <base/common/ossimConnectableContainerInterface.h>
+#include <base/common/events/ossimListenerManager.h>
+#include <base/common/events/ossimPropertyEvent.h>
+#include <base/context/ossimNotifyContext.h>
+#include <vector>
+using namespace std;
+
+RTTI_DEF1(ossimViewController, "ossimViewController", ossimSource);
+
+ossimViewController::ossimViewController()
+   :
+      ossimSource((ossimObject*)NULL, 0, 0, true, false)
+{
+   theView = NULL;
+}
+
+ossimViewController::ossimViewController(ossimObject* owner,
+                                         ossim_uint32 inputListSize,
+                                         ossim_uint32 outputListSize,
+                                         bool   inputListFixedFlag,
+                                         bool   outputListFixedFlag)
+   :
+      ossimSource(owner,
+                  inputListSize,
+                  outputListSize,
+                  inputListFixedFlag,
+                  outputListFixedFlag)
+{
+   theView = NULL;
+}
+
+ossimViewController::~ossimViewController()
+{
+   if(theView)
+   {
+      delete theView;
+      theView = NULL;
+      propagateView();
+   }
+}
+
+ossimString ossimViewController::getShortName()const
+{
+   return ossimString("View");
+}
+
+ ossimString ossimViewController::getLongName()const
+{
+   return ossimString("View controller");
+}
+
+bool ossimViewController::canConnectMyInputTo(ossim_int32,
+                                              const ossimConnectableObject*)const
+{
+   return false;
+}
+
+bool ossimViewController::propagateView()
+{
+   bool returnResult = true;
+   if(!theOwner)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: " << getClassName() << "::propagateView(), has no owner! We must find all views to set.\n";
+      return false;
+   }
+   ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                        theOwner);
+   if(inter)
+   {
+      RTTItypeid typeId = STATIC_TYPE_INFO(ossimViewInterface);
+      vector<ossimConnectableObject*> result = inter->findAllObjectsOfType(typeId,
+                                                                           true);
+      if(result.size() > 0)
+      {
+         ossim_uint32 index = 0;
+
+         // first set all views then update all outputs
+         //
+         for(index = 0; index < result.size(); ++index)
+         {
+            ossimViewInterface* viewInterface = PTR_CAST(ossimViewInterface, result[index]);
+
+            if(viewInterface)
+            {
+               if(theView)
+               {
+                  ossimObject* dupObject = theView->dup();
+                  if(!viewInterface->setView(dupObject, true))
+                  {
+                     returnResult = false;
+                     delete dupObject;
+                  }
+               }
+               else
+               {
+                  if(!viewInterface->setView((ossimObject*)NULL, true))
+                  {
+                     returnResult = false;
+                  }
+               }
+            }
+         }
+
+         for(index = 0; index < result.size(); ++index)
+         {
+            ossimPropertyEvent event(result[index]);
+            result[index]->fireEvent(event);
+            result[index]->propagateEventToOutputs(event);
+         }
+      }
+   }
+
+   return returnResult;
+}
+
+bool ossimViewController::setView(ossimObject* object)
+{
+   if(theView&&(theView != object))
+   {
+      delete theView;
+      theView = NULL;
+   }
+   theView = object;
+
+   return true;
+}
+
+ossimObject* ossimViewController::getView()
+{
+   return theView;
+}
+
+const ossimObject* ossimViewController::getView()const
+{
+   return theView;
+}
+
+const ossimObject* ossimViewController::findFirstViewOfType(RTTItypeid typeId)const
+{
+   ossimConnectableContainerInterface* inter = PTR_CAST(ossimConnectableContainerInterface,
+                                                        theOwner);
+   if(inter)
+   {
+      RTTItypeid viewInterfaceType = STATIC_TYPE_INFO(ossimViewInterface);
+      vector<ossimConnectableObject*> result = inter->findAllObjectsOfType(viewInterfaceType,
+                                                                           true);
+      if(result.size() > 0)
+      {
+         ossim_uint32 index = 0;
+
+         for(index = 0; index < result.size(); ++index)
+         {
+
+            ossimViewInterface* viewInterface = PTR_CAST(ossimViewInterface, result[index]);
+
+            if(viewInterface)
+            {
+               if(viewInterface->getView())
+               {
+                  if(typeId.can_cast(viewInterface->getView()->getType()))
+                  {
+                     return viewInterface->getView();
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   return (ossimObject*)NULL;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimViewController.h b/Utilities/OSSIM/ossim_core/base/common/ossimViewController.h
new file mode 100644
index 0000000000..f3e191276c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimViewController.h
@@ -0,0 +1,65 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimViewController.h,v 1.16 2004/05/20 14:41:10 dburken Exp $
+#ifndef ossimViewController_HEADER
+#define ossimViewController_HEADER
+#include "base/common/ossimSource.h"
+//#include "base/common/ossimViewInterface.h"
+
+/*!
+ * All view sources will derive from this class.  For example
+ * we can have a mapped view or Perspective view of the scene
+ * being rendered.  All sources within the containers are expected
+ * to derive from the view interface.
+ */
+class OSSIMDLLEXPORT ossimViewController : public ossimSource
+{
+public:
+
+   ossimViewController();
+   
+   ossimViewController(ossimObject* owner,
+                       ossim_uint32 inputListSize,
+                       ossim_uint32 outputListSize,
+                       bool   inputListFixedFlag=true,
+                       bool   outputListFixedFlag=false);
+
+   virtual ~ossimViewController();
+ 
+   virtual ossimString getShortName()const;
+   
+   virtual ossimString getLongName()const;
+
+   virtual bool propagateView();
+   virtual bool setView(ossimObject* object);
+   virtual ossimObject* getView();
+   virtual const ossimObject* getView()const;
+   virtual bool canConnectMyInputTo(ossim_int32 index,
+                                    const ossimConnectableObject* obj)const;
+   virtual const ossimObject* findFirstViewOfType(RTTItypeid typeId)const;
+protected:
+   ossimObject* theView;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimViewInterface.cpp b/Utilities/OSSIM/ossim_core/base/common/ossimViewInterface.cpp
new file mode 100644
index 0000000000..bdadb6f7ac
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimViewInterface.cpp
@@ -0,0 +1,22 @@
+#include "ossimViewInterface.h"
+
+RTTI_DEF(ossimViewInterface, "ossimViewInterface");
+
+ossimViewInterface::ossimViewInterface()
+   : theObject(NULL)
+{}
+
+ossimViewInterface::ossimViewInterface(ossimObject* base)
+   : theObject(base)
+{}
+
+ossimViewInterface::~ossimViewInterface()
+{}
+
+void ossimViewInterface::refreshView()
+{}
+
+ossimObject* ossimViewInterface::getBaseObject()
+{
+   return theObject;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/common/ossimViewInterface.h b/Utilities/OSSIM/ossim_core/base/common/ossimViewInterface.h
new file mode 100644
index 0000000000..1972560c64
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/common/ossimViewInterface.h
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimViewInterface.h,v 1.7 2004/05/13 17:41:52 dburken Exp $
+#ifndef ossimViewInterface_HEADER
+#define ossimViewInterface_HEADER
+#include "base/common/ossimRtti.h"
+
+class OSSIMDLLEXPORT ossimObject;
+
+class OSSIMDLLEXPORT ossimViewInterface
+{
+public:
+   ossimViewInterface();
+   ossimViewInterface(ossimObject* base);
+   virtual ~ossimViewInterface();
+
+   /*!
+    * The derived classes should overrid this method and
+    * return true or fals whether it was able to cast the
+    * past in view to a view that it can interface to.
+    * So if you are a projective view you might
+    * cast to an ossimProjection.  The ownsTheView specifies
+    * whether or not it owns the passed in view pointer.
+    * This will specifiy whether or not the derived classes
+    * need to re-allocate the pointer or just delete its old
+    * pointer and set it to the passed in pointer.
+    */
+   virtual bool setView(ossimObject* baseObject, bool ownsTheView = false)=0;
+   virtual ossimObject* getView()=0;
+   virtual const ossimObject* getView()const=0;
+   virtual void refreshView();
+   ossimObject* getBaseObject();
+
+protected:
+   ossimObject* theObject;
+TYPE_DATA
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/context/.cvsignore b/Utilities/OSSIM/ossim_core/base/context/.cvsignore
new file mode 100644
index 0000000000..42d2532435
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/context/.cvsignore
@@ -0,0 +1,2 @@
+*.d
+
diff --git a/Utilities/OSSIM/ossim_core/base/context/ossimErrorContext.h b/Utilities/OSSIM/ossim_core/base/context/ossimErrorContext.h
new file mode 100644
index 0000000000..20b7f4ddc1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/context/ossimErrorContext.h
@@ -0,0 +1,31 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for ossimErrorContext.
+//*******************************************************************
+//  $Id: ossimErrorContext.h,v 1.10 2004/04/01 17:25:17 gpotts Exp $
+
+#ifndef ossimErrorContext_HEADER
+#define ossimErrorContext_HEADER
+
+#include <base/context/ossimNotifyContext.h>
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/context/ossimNotifyContext.cpp b/Utilities/OSSIM/ossim_core/base/context/ossimNotifyContext.cpp
new file mode 100644
index 0000000000..963e93a719
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/context/ossimNotifyContext.cpp
@@ -0,0 +1,403 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for ossimErrorContext.
+//*******************************************************************
+//  $Id: ossimNotifyContext.cpp,v 1.15 2005/10/17 18:37:16 gpotts Exp $
+#include <iostream>
+#include <base/context/ossimNotifyContext.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stack>
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+
+
+
+
+static std::ostream* theOssimFatalStream  = &std::cerr;
+static std::ostream* theOssimWarnStream   = &std::cerr;
+static std::ostream* theOssimInfoStream   = &std::cout;
+static std::ostream* theOssimNoticeStream = &std::cout;
+static std::ostream* theOssimDebugStream  = &std::cout;
+static std::ostream* theOssimAlwaysStream = &std::cout;
+
+static ossimNotifyFlags theNotifyFlags     = ossimNotifyFlags_ALL;
+std::stack<ossimNotifyFlags> theNotifyFlagsStack;
+
+template <class charT, class traits = std::char_traits<charT> >
+class ossimNullBufferStream : public std::basic_streambuf<charT, traits>
+{
+public:
+   ossimNullBufferStream(){};
+
+
+protected:
+
+   std::streamsize xsputn(const charT * pChar, std::streamsize n)
+      {
+         return 0;
+      }
+
+private:
+   ossimNullBufferStream(const ossimNullBufferStream&);
+   ossimNullBufferStream& operator=(const ossimNullBufferStream&);
+};
+
+template <class charT, class traits = std::char_traits<charT> >
+class ossimLogFileBufferStream : public std::basic_streambuf<charT, traits>
+{
+public:
+   ossimLogFileBufferStream(){};
+
+   void setLogFilename(const ossimFilename& file)
+      {
+         theLogFilename = file;
+      }
+   ossimFilename getLogFilename()const
+      {
+         return theLogFilename;
+      }
+
+protected:
+   ossimFilename theLogFilename;
+   virtual int overflow(int c)
+      {
+         if(!traits::eq_int_type(c, traits::eof()))
+         {
+            tempString = tempString + ossimString(c);
+         }
+
+         return c;
+      }
+
+   virtual std::streamsize xsputn(const charT * pChar, std::streamsize n)
+      {
+         tempString = tempString + ossimString(pChar, pChar + n);
+
+         return n;
+      }
+
+   virtual int sync()
+      {
+         std::ofstream outFile(theLogFilename.c_str(),
+                          std::ios::app|std::ios::out);
+         if(outFile)
+         {
+            outFile.write(tempString.c_str(), tempString.length());
+         }
+
+         tempString = "";
+         return 0;
+      }
+
+private:
+   ossimString tempString;
+
+   ossimLogFileBufferStream(const ossimLogFileBufferStream&);
+   ossimLogFileBufferStream& operator=(const ossimLogFileBufferStream&);
+};
+
+
+class ossimNullStream : public std::ostream
+{
+public:
+   ossimNullStream() : std::ostream(&nullBufferStream){}
+   virtual ~ossimNullStream()
+      {
+         nullBufferStream.pubsync();
+      }
+
+private:
+   ossimNullBufferStream<char> nullBufferStream;
+   // Copy & assignment are undefined in iostreams
+   ossimNullStream(const ossimNullStream&);
+   ossimNullStream & operator=(const ossimNullStream&);
+};
+
+class ossimLogFileStream : public std::ostream
+{
+public:
+   ossimLogFileStream() : std::ostream(&theLogFileBufferStream){}
+   virtual ~ossimLogFileStream()
+      {
+         theLogFileBufferStream.pubsync();
+      }
+   void setLogFilename(const ossimFilename& filename)
+      {
+         theLogFileBufferStream.setLogFilename(filename);
+      }
+   ossimFilename getLogFilename()const
+      {
+         return theLogFileBufferStream.getLogFilename();
+      }
+
+private:
+   ossimLogFileBufferStream<char> theLogFileBufferStream;
+   // Copy & assignment are undefined in iostreams
+   ossimLogFileStream(const ossimLogFileStream&);
+   ossimLogFileStream & operator=(const ossimLogFileStream&);
+};
+
+static ossimNullStream    theOssimNullStream;
+static ossimLogFileStream theLogFileStream;
+
+void ossimSetDefaultNotifyHandlers()
+{
+   theOssimFatalStream  = &std::cerr;
+   theOssimWarnStream   = &std::cout;
+   theOssimInfoStream   = &std::cout;
+   theOssimNoticeStream = &std::cout;
+   theOssimDebugStream  = &std::cout;
+   theOssimAlwaysStream = &std::cout;
+}
+
+void ossimSetNotifyStream(std::ostream* outputStream,
+                          ossimNotifyFlags whichLevelsToRedirect)
+{
+   if(whichLevelsToRedirect&ossimNotifyFlags_FATAL)
+   {
+      theOssimFatalStream = outputStream;
+   }
+   if(whichLevelsToRedirect&ossimNotifyFlags_WARN)
+   {
+      theOssimWarnStream = outputStream;
+   }
+   if(whichLevelsToRedirect&ossimNotifyFlags_INFO)
+   {
+      theOssimInfoStream = outputStream;
+   }
+   if(whichLevelsToRedirect&ossimNotifyFlags_NOTICE)
+   {
+      theOssimNoticeStream = outputStream;
+   }
+   if(whichLevelsToRedirect&ossimNotifyFlags_DEBUG)
+   {
+      theOssimDebugStream = outputStream;
+   }
+}
+
+std::ostream* ossimGetNotifyStream(ossimNotifyLevel whichLevel)
+{
+   std::ostream* notifyStream = &theOssimNullStream;
+
+   switch(whichLevel)
+   {
+      case ossimNotifyLevel_ALWAYS:
+      {
+         notifyStream = theOssimAlwaysStream;
+         break;
+      }
+      case ossimNotifyLevel_FATAL:
+      {
+         notifyStream = theOssimFatalStream;
+         break;
+      }
+      case ossimNotifyLevel_WARN:
+      {
+         notifyStream = theOssimWarnStream;
+         break;
+      }
+      case ossimNotifyLevel_INFO:
+      {
+         notifyStream = theOssimInfoStream;
+         break;
+      }
+      case ossimNotifyLevel_NOTICE:
+      {
+         notifyStream = theOssimNoticeStream;
+         break;
+      }
+      case ossimNotifyLevel_DEBUG:
+      {
+         notifyStream = theOssimDebugStream;
+         break;
+      }
+   }
+   return notifyStream;
+}
+
+OSSIMDLLEXPORT std::ostream& ossimNotify(ossimNotifyLevel level)
+{
+   if(ossimIsReportingEnabled())
+   {
+      if(theLogFileStream.getLogFilename() != "")
+      {
+         return theLogFileStream;
+      }
+      else
+      {
+         bool reportMessageFlag = false;
+         switch(level)
+         {
+            case ossimNotifyLevel_ALWAYS:
+            {
+               reportMessageFlag = true;
+               break;
+            }
+            case ossimNotifyLevel_FATAL:
+            {
+               if(theNotifyFlags&ossimNotifyFlags_FATAL)
+               {
+                  reportMessageFlag = true;
+               }
+               break;
+            }
+            case ossimNotifyLevel_WARN:
+            {
+               if(theNotifyFlags&ossimNotifyFlags_WARN)
+               {
+                  reportMessageFlag = true;
+               }
+               break;
+            }
+            case ossimNotifyLevel_INFO:
+            {
+               if(theNotifyFlags&ossimNotifyFlags_INFO)
+               {
+                  reportMessageFlag = true;
+               }
+               break;
+            }
+            case ossimNotifyLevel_NOTICE:
+            {
+               if(theNotifyFlags&ossimNotifyFlags_NOTICE)
+               {
+                  reportMessageFlag = true;
+               }
+               break;
+            }
+            case ossimNotifyLevel_DEBUG:
+            {
+               if(theNotifyFlags&ossimNotifyFlags_DEBUG)
+               {
+                  reportMessageFlag = true;
+               }
+               break;
+            }
+         }
+         if(reportMessageFlag)
+         {
+            return *ossimGetNotifyStream(level);
+         }
+      }
+   }
+
+   return theOssimNullStream;
+}
+
+void ossimSetLogFilename(const ossimFilename& filename)
+{
+   theLogFileStream.setLogFilename(filename);
+}
+
+ossimString ossimErrorV(const char *fmt, va_list args )
+{
+   char temp[2024];
+   if(fmt)
+   {
+      vsprintf(temp, fmt, args);
+   }
+   else
+   {
+      sprintf(temp,"%s", "");
+   }
+
+   return temp;
+}
+
+void ossimEnableNotify(ossimNotifyFlags flags)
+{
+   theNotifyFlags = (ossimNotifyFlags)(theNotifyFlags | flags);
+}
+
+void ossimDisableNotify(ossimNotifyFlags flags)
+{
+   theNotifyFlags = (ossimNotifyFlags)((ossimNotifyFlags_ALL^flags)&
+                                       theNotifyFlags);
+}
+
+void ossimSetNotifyFlag(ossimNotifyFlags notifyFlags)
+{
+   theNotifyFlags = notifyFlags;
+}
+
+void ossimPushNotifyFlags()
+{
+   theNotifyFlagsStack.push(theNotifyFlags);
+}
+
+void ossimPopNotifyFlags()
+{
+   if(theNotifyFlagsStack.empty())
+   {
+      return;
+   }
+   theNotifyFlags = theNotifyFlagsStack.top();
+   theNotifyFlagsStack.pop();
+}
+
+ossimNotifyFlags ossimGetNotifyFlags()
+{
+   return theNotifyFlags;
+}
+
+
+
+bool ossimIsReportingEnabled()
+{
+   return  (theNotifyFlags != ossimNotifyFlags_NONE);
+}
+
+
+void ossimNotify(ossimString msg,
+                 ossimNotifyLevel notifyLevel)
+{
+   ossimNotify(notifyLevel) << msg << "\n";
+}
+
+void ossimSetError( const char *className,
+                    ossim_int32 error,
+                    const char *fmtString=NULL, ...)
+{
+    va_list args;
+
+    va_start(args, fmtString);
+    ossimString result = ossimErrorV(fmtString, args );
+    va_end(args);
+    ossimNotify(ossimNotifyLevel_WARN) << result << "\n";
+}
+
+void ossimSetInfo( const char *className,
+                    const char *fmtString=NULL, ...)
+{
+    va_list args;
+
+    va_start(args, fmtString);
+    ossimString result = ossimErrorV(fmtString, args );
+    va_end(args);
+    ossimNotify(ossimNotifyLevel_WARN) << result << "\n";
+}
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/context/ossimNotifyContext.h b/Utilities/OSSIM/ossim_core/base/context/ossimNotifyContext.h
new file mode 100644
index 0000000000..64f6b3b92f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/context/ossimNotifyContext.h
@@ -0,0 +1,119 @@
+//-------------------------------------------------------------------
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for ossimErrorContext.
+//-------------------------------------------------------------------
+//  $Id: ossimNotifyContext.h,v 1.6 2004/04/08 13:44:27 gpotts Exp $
+#ifndef ossimNotifyContext_HEADER
+#define ossimNotifyContext_HEADER
+#include <iostream>
+#include <fstream>
+#include <base/common/ossimErrorCodes.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimFilename.h>
+
+extern "C"
+{
+/**
+  * Notification level enumeration.  This specifies the
+  * level of the mesage being written.
+  */
+OSSIMDLLEXPORT enum ossimNotifyLevel
+{
+   ossimNotifyLevel_ALWAYS = 0,
+   ossimNotifyLevel_FATAL  = 1,
+   ossimNotifyLevel_WARN   = 2,
+   ossimNotifyLevel_NOTICE = 3,
+   ossimNotifyLevel_INFO   = 4,
+   ossimNotifyLevel_DEBUG  = 5
+};
+
+/**
+ * Flags to allow the user to turn off certain notification levels
+ * 
+ */
+OSSIMDLLEXPORT enum ossimNotifyFlags
+{
+   ossimNotifyFlags_NONE   = 0,
+   ossimNotifyFlags_FATAL  = 1,
+   ossimNotifyFlags_WARN   = 2,
+   ossimNotifyFlags_NOTICE = 4,
+   ossimNotifyFlags_INFO   = 8,
+   ossimNotifyFlags_DEBUG  = 16,
+   ossimNotifyFlags_ALL    = (ossimNotifyFlags_FATAL|
+                              ossimNotifyFlags_WARN|
+                              ossimNotifyFlags_NOTICE|
+                              ossimNotifyFlags_INFO|
+                              ossimNotifyFlags_DEBUG)
+};
+
+OSSIMDLLEXPORT void ossimSetDefaultNotifyHandlers();
+
+OSSIMDLLEXPORT void ossimSetNotifyStream(std::ostream* outputStream,
+                                         ossimNotifyFlags whichLevelsToRedirect=ossimNotifyFlags_ALL);
+
+OSSIMDLLEXPORT std::ostream* ossimGetNotifyStream(ossimNotifyLevel whichLevel);
+
+OSSIMDLLEXPORT bool ossimIsReportingEnabled();
+
+OSSIMDLLEXPORT std::ostream& ossimNotify(ossimNotifyLevel level = ossimNotifyLevel_WARN);
+
+/**
+ *
+ */
+OSSIMDLLEXPORT void ossimSetLogFilename(const ossimFilename& filename);
+
+
+/**
+ *
+ */
+OSSIMDLLEXPORT void ossimDisableNotify(ossimNotifyFlags notifyLevel=ossimNotifyFlags_ALL);
+
+/**
+ *
+ */
+OSSIMDLLEXPORT void ossimEnableNotify(ossimNotifyFlags notifyLevel=ossimNotifyFlags_ALL);
+
+
+OSSIMDLLEXPORT void ossimSetNotifyFlag(ossimNotifyFlags notifyFlags);
+OSSIMDLLEXPORT void ossimPushNotifyFlags();
+OSSIMDLLEXPORT void ossimPopNotifyFlags();
+OSSIMDLLEXPORT ossimNotifyFlags ossimGetNotifyFlags();
+
+
+/**
+ * 
+ */
+OSSIMDLLEXPORT void  ossimSetError( const char *className,
+                                    ossim_int32 error,
+                                    const char *fmtString, ...);
+
+/**
+ * This is for general warnings and information feedback
+ *
+ * @param fmtString a C printf() style formatting string used (with the
+ * following arguments) to prepare an error message.
+ */
+OSSIMDLLEXPORT void  ossimSetInfo( const char *className,
+                                   const char *fmtString, ...);
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/.cvsignore b/Utilities/OSSIM/ossim_core/base/data_types/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/.cvsignore b/Utilities/OSSIM/ossim_core/base/data_types/color_space/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimCmyVector.cpp b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimCmyVector.cpp
new file mode 100644
index 0000000000..fc7b21f4fe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimCmyVector.cpp
@@ -0,0 +1,41 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimCmyVector.cpp,v 1.1 2002/11/01 19:08:48 gpotts Exp $
+#include "ossimCmyVector.h"
+#include "ossimRgbVector.h"
+
+ossimCmyVector::ossimCmyVector(const ossimRgbVector& rgb)
+{
+   theC = 255 - rgb.getR();
+   theM = 255 - rgb.getG();
+   theY = 255 - rgb.getB();
+}
+
+const ossimCmyVector& ossimCmyVector::operator = (const ossimRgbVector& rgb)
+{
+   theC = 255 - rgb.getR();
+   theM = 255 - rgb.getG();
+   theY = 255 - rgb.getB();
+   
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimCmyVector.h b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimCmyVector.h
new file mode 100644
index 0000000000..ca62f39d4d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimCmyVector.h
@@ -0,0 +1,68 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimCmyVector.h,v 1.3 2003/05/13 11:31:02 dburken Exp $
+#include <iostream>
+#include "base/common/ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimJpegYCbCrVector;
+class OSSIMDLLEXPORT ossimHsiVector;
+class OSSIMDLLEXPORT ossimHsvVector;
+class OSSIMDLLEXPORT ossimRgbVector;
+
+class OSSIMDLLEXPORT ossimCmyVector
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimCmyVector& cmy)
+      {
+         out << "<" << cmy.theC << ", " << cmy.theM <<", " << cmy.theY << ">" << std::endl;
+         
+         return out;
+      }
+   ossimCmyVector(unsigned char c,
+                  unsigned char m,
+                  unsigned char y)
+      :
+         theC(c),
+         theM(m),
+         theY(y)
+      {}
+   ossimCmyVector(const ossimRgbVector& rgb);
+
+   ossim_uint8 getC()const
+      {
+         return theC;
+      }
+   ossim_uint8 getM()const
+      {
+         return theC;
+      }
+   ossim_uint8 getY()const
+      {
+         return theC;
+      }
+   const ossimCmyVector& operator = (const ossimRgbVector& rgb);
+protected:
+   ossim_uint8 theC;
+   ossim_uint8 theM;
+   ossim_uint8 theY;
+};
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsiVector.cpp b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsiVector.cpp
new file mode 100644
index 0000000000..04343ee6ea
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsiVector.cpp
@@ -0,0 +1,97 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@remotesensing.org)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimHsiVector.cpp,v 1.5 2005/09/08 13:35:22 gpotts Exp $
+#include "ossimHsiVector.h"
+#include "ossimRgbVector.h"
+#include "ossimNormRgbVector.h"
+#include <math.h>
+#include "base/common/ossimCommon.h"
+
+ossimHsiVector::ossimHsiVector(const ossimRgbVector& rgb)
+{
+   setFromRgb(rgb.getR()/255.0, rgb.getG()/255.0, rgb.getB()/255.0);
+}
+
+ossimHsiVector::ossimHsiVector(const ossimNormRgbVector& rgb)
+{
+   setFromRgb(rgb.getR(), rgb.getG(), rgb.getB());
+}
+
+ossimHsiVector& ossimHsiVector::operator =(const ossimRgbVector& rgb)
+{
+   setFromRgb(rgb.getR()/255.0, rgb.getG()/255.0, rgb.getB()/255.0);
+   
+   return *this;
+   
+}
+
+ossimHsiVector& ossimHsiVector::operator =(const ossimNormRgbVector& rgb)
+{
+   setFromRgb(rgb.getR(), rgb.getG(), rgb.getB());
+   
+   return *this;
+   
+}
+
+void ossimHsiVector::setFromRgb(ossim_float64 r, ossim_float64 g, ossim_float64 b)
+{
+   ossim_float64 sum = r + g + b;
+   
+   theBuf[2] =  sum/3;
+
+   if(theBuf[2] > FLT_EPSILON)
+   {
+      double deltaI1I2 = r - g;
+      double root = deltaI1I2*deltaI1I2 +
+                    ((r-b)*(g-b));
+
+      // compute Saturation from RGB
+      theBuf[1] = 1 - (3.0/sum)*(MIN(MIN(r,g),b));
+      
+      // compte Hue from Rgb.
+      if(root >= FLT_EPSILON)
+      {
+         theBuf[0] = acos((.5*((r-g)+(r-b)))/
+                          sqrt(root))*DEG_PER_RAD;
+
+         if(b > g)
+         {
+            theBuf[0] = 360 - theBuf[0];
+         }
+      }
+      else
+      {
+         theBuf[0] = b;
+      }
+   }
+   else
+   {
+      theBuf[0] = 0;
+      theBuf[1] = 0;
+      theBuf[2] = 0;
+   }
+
+   setH(theBuf[0]);
+   setS(theBuf[1]);
+   setI(theBuf[2]);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsiVector.h b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsiVector.h
new file mode 100644
index 0000000000..2dd29f9eab
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsiVector.h
@@ -0,0 +1,84 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@remotesensing.org)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimHsiVector.h,v 1.5 2005/09/08 13:35:22 gpotts Exp $
+#ifndef ossimHsiVector_HEADER
+#define ossimHsiVector_HEADER
+#include <iostream>
+#include "base/common/ossimConstants.h"
+
+class ossimRgbVector;
+class ossimNormRgbVector;
+
+class OSSIMDLLEXPORT ossimHsiVector
+{
+public:
+   friend std::ostream& operator << (std::ostream& out, const ossimHsiVector & data)
+   {
+      out << "<" << data.theBuf[0] << ", "
+          << data.theBuf[1] << ", "
+          << data.theBuf[2] << ">";
+      
+      return out;
+   }
+   // assumed normalized ossim_float64s
+   //
+   //
+   ossimHsiVector(ossim_float64 h=0, ossim_float64 s=0, ossim_float64 i=0)
+   {
+      theBuf[0] = h;
+      theBuf[1] = s;
+      theBuf[2] = i;
+   }
+   ossimHsiVector(const ossimRgbVector& rgb);
+   ossimHsiVector(const ossimNormRgbVector& rgb);
+
+   ossimHsiVector& operator =(const ossimRgbVector& rgb);
+   ossimHsiVector& operator =(const ossimNormRgbVector& rgb);
+
+   void setFromRgb(ossim_float64 r, ossim_float64 g, ossim_float64 b);
+   
+   ossim_float64 getH()const { return theBuf[0]; }
+   ossim_float64 getS()const { return theBuf[1]; }
+   ossim_float64 getI()const { return theBuf[2]; }
+   void setH(ossim_float64 H) { theBuf[0] = H; }
+   void setS(ossim_float64 S) { theBuf[1] = S; }
+   void setI(ossim_float64 I) { theBuf[2] = I; }
+
+   ossim_float64 clamp(ossim_float64 colorValue, ossim_float64 min=0, ossim_float64 max=1)const
+      {
+         colorValue = colorValue > max? max:colorValue;
+         colorValue = colorValue < min? min:colorValue;
+         
+         return colorValue;
+      }
+   
+protected:
+   /*!
+    * buf[0] = hue
+    * buf[1] = saturation
+    * buf[2] = intensity
+    */
+   ossim_float64 theBuf[3];
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsvVector.cpp b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsvVector.cpp
new file mode 100644
index 0000000000..f43f6d6617
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsvVector.cpp
@@ -0,0 +1,107 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@remotesensing.org)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimHsvVector.cpp,v 1.3 2002/01/14 16:28:04 gpotts Exp $
+#include <algorithm>
+//using namespace std;
+
+#include "ossimHsvVector.h"
+#include "ossimRgbVector.h"
+#include <math.h>
+#include "base/common/ossimCommon.h"
+
+const float ossimHsvVector::OSSIM_HSV_UNDEFINED = -1;
+ossimHsvVector::ossimHsvVector(const ossimRgbVector& rgb)
+{
+   float r,g,b;
+     
+   r = rgb.getR()/255.0;
+   g = rgb.getG()/255.0;
+   b = rgb.getB()/255.0;
+
+   // this code was taken from http://www.acm.org/jgt/papers/SmithLyons96/hsv_rgb.html
+   // the input RGB is required to be on [0, 1].
+   // Their S and V are returned on [0, 1] and H is but we will try
+   // to make it return on 0..255 for S and V and see what that looks
+   // like and keep the H on 0..6.
+   // returned on [0, 6]. Exception: H is returned UNDEFINED if S==0.
+   
+   float x, v, f, i;
+   
+   x = min(min(r, g), b);
+   v = max(max(r, g), b); 
+   if(v==x)
+   {
+      theBuf[0] = OSSIM_HSV_UNDEFINED, // we really need to mark as undefined 
+      theBuf[1] = 0;
+      theBuf[2] = v;
+   }
+   else
+   {
+      f = (r == x) ? g - b : ((g == x) ? b - r : r - g); 
+      i = (r == x) ? 3 : ((g == x) ? 5 : 1);
+      
+      theBuf[0] = clamp(i - f /(v - x), 0, 6);
+      theBuf[0]/=6.0;
+      theBuf[1] = clamp((v - x)/v, 0, 1);
+      theBuf[2] = clamp(v, 0, 1);
+   }
+}
+
+const ossimHsvVector& ossimHsvVector::operator =(const ossimRgbVector& rgb)
+{
+   float r,g,b;
+     
+   r = rgb.getR()/255.0;
+   g = rgb.getG()/255.0;
+   b = rgb.getB()/255.0;
+
+   // this code was taken from http://www.acm.org/jgt/papers/SmithLyons96/hsv_rgb.html
+   // the input RGB is required to be on [0, 1].
+   // Their S and V are returned on [0, 1] and H is but we will try
+   // to make it return on 0..255 for S and V and see what that looks
+   // like and keep the H on 0..6.
+   // returned on [0, 6]. Exception: H is returned UNDEFINED if S==0.
+   
+   float x, v, f, i;
+   
+   x = min(min(r, g), b);
+   v = max(max(r, g), b); 
+   if(v==x)
+   {
+      theBuf[0] = OSSIM_HSV_UNDEFINED, // we really need to mark as undefined 
+      theBuf[1] = 0;
+      theBuf[2] = v;
+   }
+   else
+   {
+      f = (r == x) ? g - b : ((g == x) ? b - r : r - g); 
+      i = (r == x) ? 3 : ((g == x) ? 5 : 1);
+      
+      theBuf[0] = clamp(i - f /(v - x), 0, 6);
+      theBuf[0]/=6.0;
+      theBuf[1] = clamp((v - x)/v, 0, 1);
+      theBuf[2] = clamp(v, 0, 1);
+   }
+
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsvVector.h b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsvVector.h
new file mode 100644
index 0000000000..b3efe2074d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimHsvVector.h
@@ -0,0 +1,86 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@remotesensing.org)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimHsvVector.h,v 1.5 2002/11/25 18:59:55 gpotts Exp $
+#ifndef ossimHsvVector_HEADER
+#define ossimHsvVector_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimConstants.h"
+class OSSIMDLLEXPORT ossimRgbVector;
+
+class OSSIMDLLEXPORT ossimHsvVector
+{
+public:
+   friend ostream& operator << (ostream& out, const ossimHsvVector & data)
+      {
+         out << "<" << data.theBuf[0] << ", "
+             << data.theBuf[1] << ", "
+             << data.theBuf[2] << ">";
+
+         return out;
+      }
+   // assumed normalized floats
+   //
+   //
+   ossimHsvVector(float h=0, float s=0, float i=0)
+      {
+         theBuf[0] = h;
+         theBuf[1] = s;
+         theBuf[2] = i;
+      }
+   ossimHsvVector(const ossimRgbVector& rgb);
+
+   const ossimHsvVector& operator =(const ossimRgbVector& rgb);
+   
+   float getH()const { return theBuf[0]; }
+   float getS()const { return theBuf[1]; }
+   float getV()const { return theBuf[2]; }
+   
+   unsigned char getVUnNormalized()const
+      {
+         return static_cast<unsigned char>(theBuf[2]*255);
+      }
+   void setH(float H) { theBuf[0] = H; }
+   void setS(float S) { theBuf[1] = S; }
+   void setV(float V) { theBuf[2] = V; }
+
+   float clamp(float colorValue, float min=0, float max=255)const
+      {
+         colorValue = colorValue > max? max:colorValue;
+         colorValue = colorValue < min? min:colorValue;
+         
+         return colorValue;
+      }
+   
+   static const float OSSIM_HSV_UNDEFINED;
+protected:
+   /*!
+    * buf[0] = hue     [0..1]
+    * buf[1] = saturation [0..1]
+    * buf[2] = value [0..1]
+    */
+   float theBuf[3];
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimJpegYCbCrVector.cpp b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimJpegYCbCrVector.cpp
new file mode 100644
index 0000000000..c34f2c2e83
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimJpegYCbCrVector.cpp
@@ -0,0 +1,37 @@
+#include "ossimJpegYCbCrVector.h"
+#include "base/common/ossimCommon.h"
+
+#include "ossimRgbVector.h"
+
+ossimJpegYCbCrVector::ossimJpegYCbCrVector(const ossimRgbVector& rgbColor)
+{
+   theBuf[0] = static_cast<unsigned char>(clamp(irint(0.299*rgbColor.getR() +
+                                          0.587*rgbColor.getG() +
+                                          0.114*rgbColor.getB())));
+   
+   theBuf[1] = static_cast<unsigned char>(clamp(irint((-0.1687)*rgbColor.getR() -
+                                                0.3313*rgbColor.getG() +
+                                                0.5*rgbColor.getB() + 128)));
+   
+   theBuf[2] = static_cast<unsigned char>(clamp(irint(0.5*rgbColor.getR() -
+                                                      .4187*rgbColor.getG() -
+                                                      .0813*rgbColor.getB() + 128)));
+   
+}
+
+ossimJpegYCbCrVector& ossimJpegYCbCrVector::operator =(const ossimRgbVector& rgbColor)
+{
+   theBuf[0] = static_cast<unsigned char>(clamp(irint(0.299*rgbColor.getR() +
+                                                0.587*rgbColor.getG() +
+                                                0.114*rgbColor.getB())));
+   
+   theBuf[1] = static_cast<unsigned char>(clamp(irint((-0.1687)*rgbColor.getR() -
+                                                      0.3313*rgbColor.getG() +
+                                                      0.5*rgbColor.getB() + 128)));
+   
+   theBuf[2] = static_cast<unsigned char>(clamp(irint(0.5*rgbColor.getR() -
+                                                      .4187*rgbColor.getG() -
+                                                      .0813*rgbColor.getB() + 128)));
+   
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimJpegYCbCrVector.h b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimJpegYCbCrVector.h
new file mode 100644
index 0000000000..6d7b98a7bc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimJpegYCbCrVector.h
@@ -0,0 +1,84 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@remotesensing.org)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimJpegYCbCrVector.h,v 1.3 2002/11/25 18:59:55 gpotts Exp $
+#ifndef ossimJpegYCbCrVector_HEADER
+#define ossimJpegYCbCrVector_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimRgbVector;
+
+class OSSIMDLLEXPORT ossimJpegYCbCrVector
+{
+public:
+   friend ostream& operator << (ostream& out, const ossimJpegYCbCrVector& data)
+      {
+         out << "<" << (long)data.theBuf[0] << ", "
+             << (long)data.theBuf[1] << ", "
+             << (long)data.theBuf[2] << ">";
+
+         return out;
+      }
+   
+   ossimJpegYCbCrVector(unsigned char Y=0,
+                        unsigned char Cb=0,
+                        unsigned char Cr=0)
+      {
+         theBuf[0] = Y;
+         theBuf[1] = Cb;
+         theBuf[2] = Cr;
+      }
+   
+   ossimJpegYCbCrVector(const ossimRgbVector&);
+   
+   long clamp(long colorValue, unsigned char min=0, unsigned char max=255)const
+      {
+         colorValue = colorValue > max? max:colorValue;
+         colorValue = colorValue < min? min:colorValue;
+
+         return colorValue;
+      }
+
+   
+   ossimJpegYCbCrVector& operator =(const ossimRgbVector&);
+   
+   unsigned char getY() const { return theBuf[0]; }
+   unsigned char getCb()const { return theBuf[1]; }
+   unsigned char getCr()const { return theBuf[2]; }
+   void setY(unsigned char  Y)  { theBuf[0] = Y; }
+   void setCb(unsigned char Cb) { theBuf[1] = Cb; }
+   void setCr(unsigned char Cr) { theBuf[2] = Cr; }
+   
+protected:
+   /*!
+    * JpegYCbCr is an 8-bit YCbCr color model.  We
+    * will let:
+    * buf[0] = Y
+    * buf[1] = Cb
+    * buf[2] = Cr
+    */
+   unsigned char theBuf[3];
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimNormRgbVector.cpp b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimNormRgbVector.cpp
new file mode 100644
index 0000000000..545668dc78
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimNormRgbVector.cpp
@@ -0,0 +1,183 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License: LGPL
+// Author: Garrett Potts 
+// Description:
+//
+//*************************************************************************
+// $Id: ossimNormRgbVector.cpp,v 1.1 2005/09/08 13:08:29 gpotts Exp $
+#include "ossimNormRgbVector.h"
+#include "ossimRgbVector.h"
+#include "ossimJpegYCbCrVector.h"
+#include "ossimHsiVector.h"
+#include "ossimHsvVector.h"
+#include "ossimCmyVector.h"
+#include "base/common/ossimCommon.h"
+#include <math.h>
+
+ossimNormRgbVector::ossimNormRgbVector(const ossimRgbVector& rgb)
+{
+   theBuf[0] = rgb.getR()/255.0;
+   theBuf[1] = rgb.getG()/255.0;
+   theBuf[2] = rgb.getB()/255.0;
+}
+
+ossimNormRgbVector::ossimNormRgbVector(const ossimJpegYCbCrVector& YCbCr)
+{
+   (*this) = YCbCr;
+   
+}
+
+ossimNormRgbVector::ossimNormRgbVector(const ossimHsiVector& hsi)
+{
+   (*this)=hsi;
+}
+
+ossimNormRgbVector::ossimNormRgbVector(const ossimHsvVector& hsv)
+{
+   (*this) = hsv;
+}
+
+ossimNormRgbVector::ossimNormRgbVector(const ossimCmyVector& cmy)
+{
+   theBuf[0] = 255 - cmy.getC();
+   theBuf[1] = 255 - cmy.getM();
+   theBuf[2] = 255 - cmy.getY();
+}
+
+const ossimNormRgbVector& ossimNormRgbVector::operator =(const ossimHsvVector& hsv)
+{
+   // H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1]. 
+   // RGB are each returned on [0, 1]. 
+   float h = hsv.getH(), // unnormalize it
+         s = hsv.getS(),
+         v = hsv.getV();
+   float m, n, f; 
+   int i; 
+   if(h == ossimHsvVector::OSSIM_HSV_UNDEFINED)
+   {
+      theBuf[0] = clamp(v);
+      theBuf[1] = clamp(v);
+      theBuf[2] = clamp(v);
+   }
+   else
+   {
+      h*=6.0; // unnormalize h
+      i = (int)floor(h); 
+      f = h - i; 
+      if(!(i & 1)) f = 1 - f; // if i is even 
+      m = v * (1 - s); 
+      n = v * (1 - s * f); 
+      switch (i)
+      { 
+      case 6: 
+      case 0:
+      {
+         theBuf[0] = clamp(v);
+         theBuf[1] = clamp(n);
+         theBuf[2] = clamp(m);
+         break;
+      }
+      case 1:
+      {
+         theBuf[0] = clamp(n);
+         theBuf[1] = clamp(v);
+         theBuf[2] = clamp(m);
+         break;
+      }
+      case 2:
+      {
+         theBuf[0] = clamp(m);
+         theBuf[1] = clamp(v);
+         theBuf[2] = clamp(n);
+         break;
+      }
+      case 3: 
+      {
+         theBuf[0] = clamp(m);
+         theBuf[1] = clamp(n);
+         theBuf[2] = clamp(v);
+         break;
+      }
+      case 4:
+      {
+         theBuf[0] = clamp(n);
+         theBuf[1] = clamp(m);
+         theBuf[2] = clamp(v);
+         break;
+      }
+      case 5: 
+      {
+         theBuf[0] = clamp(v);
+         theBuf[1] = clamp(m);
+         theBuf[2] = clamp(n);
+         break;
+      }
+      }
+   }
+   return *this;
+}
+
+const ossimNormRgbVector& ossimNormRgbVector::operator =(const ossimJpegYCbCrVector& YCbCr)
+{
+   theBuf[0] = clamp((YCbCr.getY() +
+                      1.402 * (YCbCr.getCr()-128.0))/255.0);
+   theBuf[1] = clamp((YCbCr.getY() -
+                      0.34414 *(YCbCr.getCb()-128.0) -
+                      0.71414*(YCbCr.getCr()-128.0))/255.0);
+   theBuf[2] = clamp((YCbCr.getY() +
+                      1.772 * ( YCbCr.getCb()-128.0))/255.0);
+
+   return *this;
+}
+
+const ossimNormRgbVector& ossimNormRgbVector::operator =(const ossimHsiVector& hsi)
+{
+   ossim_float32 h = hsi.getH();
+   ossim_float32 s = hsi.getS();
+   ossim_float32 i = hsi.getI();
+
+   ossim_float32 r=0;
+   ossim_float32 g=0;
+   ossim_float32 b=0;
+   
+   if(h <= 120.0)
+   {
+      b = i*(1-s);
+
+      r = i*(1 + s*cos(RAD_PER_DEG*h)/cos((60-h)*RAD_PER_DEG));
+      g = 3*i - (r+b);
+   }
+    else if(h <= 240.0)
+    {
+       h-=120;
+
+       r = i*(1-s);
+       g = i*(1 + s*cos(RAD_PER_DEG*h)/cos((60-h)*RAD_PER_DEG));
+       b = 3*i - (r+g);
+    }
+    else if(h <= 360.0)
+    {
+       h-=240;
+
+       g = i*(1-s);
+       b = i*(1 + s*cos(RAD_PER_DEG*h)/cos((60-h)*RAD_PER_DEG));
+       r = 3*i - (g+b);      
+    }
+   
+   theBuf[0] = clamp(r);
+   theBuf[1] = clamp(g);
+   theBuf[2] = clamp(b);
+   
+   return *this;
+}
+
+const ossimNormRgbVector& ossimNormRgbVector::operator =(const ossimCmyVector& cmy)
+{
+   theBuf[0] = (255 - cmy.getC())/255.0;
+   theBuf[1] = (255 - cmy.getM())/255.0;
+   theBuf[2] = (255 - cmy.getY())/255.0;
+
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimNormRgbVector.h b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimNormRgbVector.h
new file mode 100644
index 0000000000..dfbcfbec94
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimNormRgbVector.h
@@ -0,0 +1,109 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License: LGPL
+// Author: Garrett Potts 
+// Description:
+//
+//*************************************************************************
+// $Id: ossimNormRgbVector.h,v 1.1 2005/09/08 13:08:29 gpotts Exp $
+#ifndef ossimNormRgbVector_HEADER
+#define ossimNormRgbVector_HEADER
+#include <iostream>
+#include "base/common/ossimConstants.h"
+
+class ossimJpegYCbCrVector;
+class ossimHsiVector;
+class ossimHsvVector;
+class ossimCmyVector;
+class ossimRgbVector;
+
+class OSSIM_DLL ossimNormRgbVector
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimNormRgbVector& data)
+   {
+      out << "<" << data.theBuf[0] << ", "
+          << data.theBuf[1] << ", "
+          << data.theBuf[2] << ">";
+
+         return out;
+      }
+   ossimNormRgbVector(ossim_float64 r=0, ossim_float64 g=0, ossim_float64 b=0)
+      {
+         theBuf[0] = r;
+         theBuf[1] = g;
+         theBuf[2] = b;
+      }
+   ossimNormRgbVector(ossim_float64 grey)
+      {
+         theBuf[0] = grey;
+         theBuf[1] = grey;
+         theBuf[2] = grey;
+      }
+   ossimNormRgbVector(ossim_float64 colorData[3])
+      {
+         theBuf[0] = colorData[0];
+         theBuf[1] = colorData[1];
+         theBuf[2] = colorData[2];
+      }
+   ossimNormRgbVector(const ossimNormRgbVector& rgb)
+   {
+      theBuf[0] = rgb.theBuf[0];
+      theBuf[1] = rgb.theBuf[1];
+      theBuf[2] = rgb.theBuf[2];
+   }
+   ossimNormRgbVector(const ossimRgbVector& rgb);
+   ossimNormRgbVector(const ossimJpegYCbCrVector& YCbCr);
+   ossimNormRgbVector(const ossimHsiVector& hsi);
+   ossimNormRgbVector(const ossimHsvVector& hsv);
+   ossimNormRgbVector(const ossimCmyVector& cmy);
+   ossimNormRgbVector operator -(const ossimNormRgbVector& rgb)const
+   {
+      return ossimNormRgbVector(clamp(theBuf[0] - rgb.theBuf[0]),
+                                clamp(theBuf[1] - rgb.theBuf[1]),
+                                clamp(theBuf[2] - rgb.theBuf[2]));
+   }
+   ossimNormRgbVector operator *(ossim_float64 t)const
+   {
+      return ossimNormRgbVector(clamp(theBuf[0]*t),
+                                clamp(theBuf[1]*t),
+                                clamp(theBuf[2]*t));
+   }
+   
+   const ossimNormRgbVector& operator =(const ossimJpegYCbCrVector& data);
+   const ossimNormRgbVector& operator =(const ossimHsiVector& hsi);
+   const ossimNormRgbVector& operator =(const ossimHsvVector& hsv);
+   const ossimNormRgbVector& operator =(const ossimCmyVector& cmy);
+   bool operator ==(const ossimNormRgbVector& rgb)
+      {
+         return ( (rgb.theBuf[0] == theBuf[0])&&
+                  (rgb.theBuf[1] == theBuf[1])&&
+                  (rgb.theBuf[2] == theBuf[2]));
+      }
+   bool operator !=(const ossimNormRgbVector& rgb)
+      {
+         return ( (rgb.theBuf[0] != theBuf[0])||
+                  (rgb.theBuf[1] != theBuf[1])||
+                  (rgb.theBuf[2] != theBuf[2]));
+      }
+   static ossim_float64 clamp(ossim_float64 colorValue, ossim_float64 min=0.0, ossim_float64 max=1.0)
+      {
+         colorValue = colorValue > max? max:colorValue;
+         colorValue = colorValue < min? min:colorValue;
+         
+         return colorValue;
+      }
+   ossim_float64 getR() const { return theBuf[0]; }
+   ossim_float64 getG()const  { return theBuf[1]; }
+   ossim_float64 getB()const  { return theBuf[2]; }
+   void setR(ossim_float64 r) { theBuf[0] = r; }
+   void setG(ossim_float64 g) { theBuf[1] = g; }
+   void setB(ossim_float64 b) { theBuf[2] = b; }
+   
+protected:
+   ossim_float64 theBuf[3];
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimRgbVector.cpp b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimRgbVector.cpp
new file mode 100644
index 0000000000..f69952373b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimRgbVector.cpp
@@ -0,0 +1,296 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@remotesensing.org)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimRgbVector.cpp,v 1.7 2005/09/08 13:35:22 gpotts Exp $
+#include "ossimRgbVector.h"
+#include "ossimJpegYCbCrVector.h"
+#include "ossimHsiVector.h"
+#include "ossimHsvVector.h"
+#include "ossimCmyVector.h"
+#include "base/common/ossimCommon.h"
+#include <math.h>
+
+ossimRgbVector::ossimRgbVector(const ossimJpegYCbCrVector& YCbCr)
+{
+   theBuf[0] = static_cast<unsigned char>(clamp(irint(YCbCr.getY() +
+                                                      1.402 * (YCbCr.getCr()-128.0))));
+   theBuf[1] = static_cast<unsigned char>(clamp(irint(YCbCr.getY() -
+                                                      0.34414 *(YCbCr.getCb()-128.0) -
+                                                      0.71414*(YCbCr.getCr()-128.0))));
+   theBuf[2] = static_cast<unsigned char>(clamp(irint(YCbCr.getY() +
+                                                      1.772 * ( YCbCr.getCb()-128.0))));
+   
+}
+
+ossimRgbVector::ossimRgbVector(const ossimHsiVector& hsi)
+{
+   float h = hsi.getH();
+   float s = hsi.getS();
+   float i = hsi.getI();
+
+   float r=0;
+   float g=0;
+   float b=0;
+   
+   if(h <= 120.0)
+   {
+      b = i*(1-s);
+
+      r = i*(1 + s*cos(RAD_PER_DEG*h)/cos((60-h)*RAD_PER_DEG));
+      g = 3*i - (r+b);
+   }
+    else if(h <= 240.0)
+    {
+       h-=120;
+
+       r = i*(1-s);
+       g = i*(1 + s*cos(RAD_PER_DEG*h)/cos((60-h)*RAD_PER_DEG));
+       b = 3*i - (r+g);
+    }
+    else if(h <= 360.0)
+    {
+       h-=240;
+
+       g = i*(1-s);
+       b = i*(1 + s*cos(RAD_PER_DEG*h)/cos((60-h)*RAD_PER_DEG));
+       r = 3*i - (g+b);      
+    }
+   
+   theBuf[0] = clamp((long)(r*255));
+   theBuf[1] = clamp((long)(g*255));
+   theBuf[2] = clamp((long)(b*255));
+}
+
+ossimRgbVector::ossimRgbVector(const ossimHsvVector& hsv)
+{
+   // H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1]. 
+      // RGB are each returned on [0, 1]. 
+   float h = hsv.getH(), // unnormalize it
+         s = hsv.getS(),
+         v = hsv.getV();
+   float m, n, f; 
+   int i; 
+   if(h == ossimHsvVector::OSSIM_HSV_UNDEFINED)
+   {
+      theBuf[0] = clamp(irint(v*255));
+      theBuf[1] = clamp(irint(v*255));
+      theBuf[2] = clamp(irint(v*255));
+   }
+   else
+   {
+      h*=6.0; // unnormalize h
+      i = (int)floor(h); 
+      f = h - i; 
+      if(!(i & 1)) f = 1 - f; // if i is even 
+      m = v * (1 - s); 
+      n = v * (1 - s * f); 
+      switch (i)
+      { 
+      case 6: 
+      case 0:
+      {
+         theBuf[0] = clamp(irint(v*255));
+         theBuf[1] = clamp(irint(n*255));
+         theBuf[2] = clamp(irint(m*255));
+         break;
+      }
+      case 1:
+      {
+         theBuf[0] = clamp(irint(n*255));
+         theBuf[1] = clamp(irint(v*255));
+         theBuf[2] = clamp(irint(m*255));
+         break;
+      }
+      case 2:
+      {
+         theBuf[0] = clamp(irint(m*255));
+         theBuf[1] = clamp(irint(v*255));
+         theBuf[2] = clamp(irint(n*255));
+         break;
+      }
+      case 3: 
+      {
+         theBuf[0] = clamp(irint(m*255));
+         theBuf[1] = clamp(irint(n*255));
+         theBuf[2] = clamp(irint(v*255));
+         break;
+      }
+      case 4:
+      {
+         theBuf[0] = clamp(irint(n*255));
+         theBuf[1] = clamp(irint(m*255));
+         theBuf[2] = clamp(irint(v*255));
+         break;
+      }
+      case 5: 
+      {
+         theBuf[0] = clamp(irint(v*255));
+         theBuf[1] = clamp(irint(m*255));
+         theBuf[2] = clamp(irint(n*255));
+         break;
+      }
+      }
+   }
+}
+
+ossimRgbVector::ossimRgbVector(const ossimCmyVector& cmy)
+{
+   theBuf[0] = 255 - cmy.getC();
+   theBuf[1] = 255 - cmy.getM();
+   theBuf[2] = 255 - cmy.getY();
+}
+
+const ossimRgbVector& ossimRgbVector::operator =(const ossimHsvVector& hsv)
+{
+   // H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1]. 
+      // RGB are each returned on [0, 1]. 
+   float h = hsv.getH(), // unnormalize it
+         s = hsv.getS(),
+         v = hsv.getV();
+   float m, n, f; 
+   int i; 
+   if(h == ossimHsvVector::OSSIM_HSV_UNDEFINED)
+   {
+      theBuf[0] = clamp(irint(v*255));
+      theBuf[1] = clamp(irint(v*255));
+      theBuf[2] = clamp(irint(v*255));
+   }
+   else
+   {
+      h*=6.0; // unnormalize h
+      i = (int)floor(h); 
+      f = h - i; 
+      if(!(i & 1)) f = 1 - f; // if i is even 
+      m = v * (1 - s); 
+      n = v * (1 - s * f); 
+      switch (i)
+      { 
+      case 6: 
+      case 0:
+      {
+         theBuf[0] = clamp(irint(v*255));
+         theBuf[1] = clamp(irint(n*255));
+         theBuf[2] = clamp(irint(m*255));
+         break;
+      }
+      case 1:
+      {
+         theBuf[0] = clamp(irint(n*255));
+         theBuf[1] = clamp(irint(v*255));
+         theBuf[2] = clamp(irint(m*255));
+         break;
+      }
+      case 2:
+      {
+         theBuf[0] = clamp(irint(m*255));
+         theBuf[1] = clamp(irint(v*255));
+         theBuf[2] = clamp(irint(n*255));
+         break;
+      }
+      case 3: 
+      {
+         theBuf[0] = clamp(irint(m*255));
+         theBuf[1] = clamp(irint(n*255));
+         theBuf[2] = clamp(irint(v*255));
+         break;
+      }
+      case 4:
+      {
+         theBuf[0] = clamp(irint(n*255));
+         theBuf[1] = clamp(irint(m*255));
+         theBuf[2] = clamp(irint(v*255));
+         break;
+      }
+      case 5: 
+      {
+         theBuf[0] = clamp(irint(v*255));
+         theBuf[1] = clamp(irint(m*255));
+         theBuf[2] = clamp(irint(n*255));
+         break;
+      }
+      }
+   }
+   return *this;
+}
+
+const ossimRgbVector& ossimRgbVector::operator =(const ossimJpegYCbCrVector& YCbCr)
+{
+   theBuf[0] = static_cast<unsigned char>(clamp(irint(YCbCr.getY() +
+                                                      1.402 * (YCbCr.getCr()-128.0))));
+   theBuf[1] = static_cast<unsigned char>(clamp(irint(YCbCr.getY() -
+                                                      0.34414 *(YCbCr.getCb()-128.0) -
+                                                      0.71414*(YCbCr.getCr()-128.0))));
+   theBuf[2] = static_cast<unsigned char>(clamp(irint(YCbCr.getY() +
+                                                      1.772 * ( YCbCr.getCb()-128.0))));
+
+   return *this;
+}
+
+const ossimRgbVector& ossimRgbVector::operator =(const ossimHsiVector& hsi)
+{
+   float h = hsi.getH();
+   float s = hsi.getS();
+   float i = hsi.getI();
+
+   float r=0;
+   float g=0;
+   float b=0;
+   
+   if(h <= 120.0)
+   {
+      b = i*(1-s);
+
+      r = i*(1 + s*cos(RAD_PER_DEG*h)/cos((60-h)*RAD_PER_DEG));
+      g = 3*i - (r+b);
+   }
+    else if(h <= 240.0)
+    {
+       h-=120;
+
+       r = i*(1-s);
+       g = i*(1 + s*cos(RAD_PER_DEG*h)/cos((60-h)*RAD_PER_DEG));
+       b = 3*i - (r+g);
+    }
+    else if(h <= 360.0)
+    {
+       h-=240;
+
+       g = i*(1-s);
+       b = i*(1 + s*cos(RAD_PER_DEG*h)/cos((60-h)*RAD_PER_DEG));
+       r = 3*i - (g+b);      
+    }
+   
+   theBuf[0] = clamp((long)(r*255));
+   theBuf[1] = clamp((long)(g*255));
+   theBuf[2] = clamp((long)(b*255));
+   
+   return *this;
+}
+
+const ossimRgbVector& ossimRgbVector::operator =(const ossimCmyVector& cmy)
+{
+   theBuf[0] = 255 - cmy.getC();
+   theBuf[1] = 255 - cmy.getM();
+   theBuf[2] = 255 - cmy.getY();
+
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimRgbVector.h b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimRgbVector.h
new file mode 100644
index 0000000000..b69a473598
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/color_space/ossimRgbVector.h
@@ -0,0 +1,123 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@remotesensing.org)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimRgbVector.h,v 1.10 2002/11/01 19:08:48 gpotts Exp $
+#ifndef ossimRgbVector_HEADER
+#define ossimRgbVector_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimJpegYCbCrVector;
+class OSSIMDLLEXPORT ossimHsiVector;
+class OSSIMDLLEXPORT ossimHsvVector;
+class OSSIMDLLEXPORT ossimCmyVector;
+
+class OSSIMDLLEXPORT ossimRgbVector
+{
+public:
+   friend ostream& operator <<(ostream& out, const ossimRgbVector& data)
+      {
+         out << "<" << (long)data.theBuf[0] << ", "
+             << (long)data.theBuf[1] << ", "
+             << (long)data.theBuf[2] << ">";
+
+         return out;
+      }
+   ossimRgbVector(unsigned char r=0, unsigned char g=0, unsigned char b=0)
+      {
+         theBuf[0] = r;
+         theBuf[1] = g;
+         theBuf[2] = b;
+      }
+   ossimRgbVector(unsigned char grey)
+      {
+         theBuf[0] = grey;
+         theBuf[1] = grey;
+         theBuf[2] = grey;
+      }
+   ossimRgbVector(unsigned char colorData[3])
+      {
+         theBuf[0] = colorData[0];
+         theBuf[1] = colorData[1];
+         theBuf[2] = colorData[2];
+      }
+
+   ossimRgbVector(const ossimJpegYCbCrVector& YCbCr);
+   ossimRgbVector(const ossimHsiVector& hsi);
+   ossimRgbVector(const ossimHsvVector& hsv);
+   ossimRgbVector(const ossimCmyVector& cmy);
+
+   ossimRgbVector operator -(const ossimRgbVector& rgb)const
+      {
+         return ossimRgbVector((unsigned char)clamp((long)theBuf[0] - (long)rgb.theBuf[0]),
+                               (unsigned char)clamp((long)theBuf[1] - (long)rgb.theBuf[1]),
+                               (unsigned char)clamp((long)theBuf[2] - (long)rgb.theBuf[2]));
+      }
+
+   ossimRgbVector operator +(const ossimRgbVector& rgb)const
+      {
+         return ossimRgbVector((unsigned char)clamp((long)theBuf[0] + (long)rgb.theBuf[0]),
+                               (unsigned char)clamp((long)theBuf[1] + (long)rgb.theBuf[1]),
+                               (unsigned char)clamp((long)theBuf[2] + (long)rgb.theBuf[2]));
+      }
+   ossimRgbVector operator *(double t)const
+      {
+         return ossimRgbVector((unsigned char)clamp((long)(theBuf[0]*t)),
+                               (unsigned char)clamp((long)(theBuf[1]*t)),
+                               (unsigned char)clamp((long)(theBuf[2]*t)));
+      }
+   const ossimRgbVector& operator =(const ossimJpegYCbCrVector& data);
+   const ossimRgbVector& operator =(const ossimHsiVector& hsi);
+   const ossimRgbVector& operator =(const ossimHsvVector& hsv);
+   const ossimRgbVector& operator =(const ossimCmyVector& cmy);
+   bool operator ==(const ossimRgbVector& rgb)
+      {
+         return ( (rgb.theBuf[0] == theBuf[0])&&
+                  (rgb.theBuf[1] == theBuf[1])&&
+                  (rgb.theBuf[2] == theBuf[2]));
+      }
+   bool operator !=(const ossimRgbVector& rgb)
+      {
+         return ( (rgb.theBuf[0] != theBuf[0])||
+                  (rgb.theBuf[1] != theBuf[1])||
+                  (rgb.theBuf[2] != theBuf[2]));
+      }
+   static long clamp(long colorValue, unsigned char min=0, unsigned char max=255)
+      {
+         colorValue = colorValue > (long)max? (long)max:colorValue;
+         colorValue = colorValue < (long)min? (long)min:colorValue;
+         
+         return colorValue;
+      }
+   unsigned char getR() const { return theBuf[0]; }
+   unsigned char getG()const  { return theBuf[1]; }
+   unsigned char getB()const  { return theBuf[2]; }
+   void setR(unsigned char  R) { theBuf[0] = R; }
+   void setG(unsigned char G)  { theBuf[1] = G; }
+   void setB(unsigned char B)  { theBuf[2] = B; }
+   
+protected:
+   unsigned char theBuf[3];
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/.cvsignore b/Utilities/OSSIM/ossim_core/base/data_types/datum/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/datum.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/datum.h
new file mode 100644
index 0000000000..aa99cb3638
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/datum.h
@@ -0,0 +1,528 @@
+#ifndef DATUM_H
+#define DATUM_H
+
+/***************************************************************************/
+/* RSC IDENTIFIER: Datum
+ *
+ * ABSTRACT
+ *
+ *    This component provides datum shifts for a large collection of local
+ *    datums, WGS72, and WGS84.  A particular datum can be accessed by using its 
+ *    standard 5-letter code to find its index in the datum table.  The index 
+ *    can then be used to retrieve the name, type, ellipsoid code, and datum 
+ *    shift parameters, and to perform shifts to or from that datum.
+ *    
+ *    By sequentially retrieving all of the datum codes and/or names, a menu
+ *    of the available datums can be constructed.  The index values resulting
+ *    from selections from this menu can then be used to access the parameters
+ *    of the selected datum, or to perform datum shifts involving that datum.
+ *
+ *    This component supports both 3-parameter local datums, for which only X,
+ *    Y, and Z translations relative to WGS 84 have been defined, and 
+ *    7-parameter local datums, for which X, Y, and Z rotations, and a scale 
+ *    factor, are also defined.  It also includes entries for WGS 84 (with an
+ *    index of 0), and WGS 72 (with an index of 1), but no shift parameter 
+ *    values are defined for these.
+ *
+ *    This component provides datum shift functions for both geocentric and
+ *    geodetic coordinates.  WGS84 is used as an intermediate state when
+ *    shifting from one local datum to another.  When geodetic coordinates are
+ *    given Molodensky's method is used, except near the poles where the 3-step
+ *    step method is used instead.  Specific algorithms are used for shifting 
+ *    between WGS72 and WGS84.
+ *
+ *    This component depends on two data files, named 3_param.dat and 
+ *    7_param.dat, which contain the datum parameter values.  Copies of these
+ *    files must be located in the directory specified by the value of the 
+ *    environment variable "DATUM_DATA", if defined, or else in the current 
+ *    directory whenever a program containing this component is executed. 
+ *
+ *    Additional datums can be added to these files, either manually or using 
+ *    the Create_Datum function.  However, if a large number of datums are 
+ *    added, the datum table array sizes in this component will have to be 
+ *    increased.
+ *
+ *    This component depends on two other components: the Ellipsoid component
+ *    for access to ellipsoid parameters; and the Geocentric component for 
+ *    conversions between geodetic and geocentric coordinates.
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks for input file errors and input parameter errors.
+ *    If an invalid value is found, the error code is combined with the current
+ *    error code using the bitwise or.  This combining allows multiple error
+ *    codes to be returned. The possible error codes are:
+ *
+ *  DATUM_NO_ERROR                  : No errors occurred in function
+ *  DATUM_NOT_INITIALIZED_ERROR     : Datum module has not been initialized
+ *  DATUM_7PARAM_FILE_OPEN_ERROR    : 7 parameter file opening error
+ *  DATUM_7PARAM_FILE_PARSING_ERROR : 7 parameter file structure error
+ *  DATUM_7PARAM_OVERFLOW_ERROR     : 7 parameter table overflow
+ *  DATUM_3PARAM_FILE_OPEN_ERROR    : 3 parameter file opening error
+ *  DATUM_3PARAM_FILE_PARSING_ERROR : 3 parameter file structure error
+ *  DATUM_3PARAM_OVERFLOW_ERROR     : 3 parameter table overflow
+ *  DATUM_INVALID_INDEX_ERROR       : Index out of valid range (less than one
+ *                                      or more than Datum_Count)
+ *  DATUM_INVALID_SRC_INDEX_ERROR   : Source datum index invalid
+ *  DATUM_INVALID_DEST_INDEX_ERROR  : Destination datum index invalid
+ *  DATUM_INVALID_CODE_ERROR        : Datum code not found in table
+ *  DATUM_LAT_ERROR                 : Latitude out of valid range (-90 to 90)
+ *  DATUM_LON_ERROR                 : Longitude out of valid range (-180 to
+ *                                    360)
+ *  DATUM_SIGMA_ERROR               : Standard error values must be positive
+ *                                    (or -1 if unknown)
+ *  DATUM_DOMAIN_ERROR              : Domain of validity not well defined
+ *  DATUM_ELLIPSE_ERROR             : Error in ellipsoid module
+ *
+ *
+ * REUSE NOTES
+ *
+ *    Datum is intended for reuse by any application that needs access to 
+ *    datum shift parameters relative to WGS 84.
+ *
+ *    
+ * REFERENCES
+ *
+ *    Further information on Datum can be found in the Reuse Manual.
+ *
+ *    Datum originated from :  U.S. Army Topographic Engineering Center (USATEC)
+ *                             Geospatial Information Division (GID)
+ *                             7701 Telegraph Road
+ *                             Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    Datum has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    Datum was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC 2.8.1
+ *    2. MS Windows 95 with MS Visual C++ 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    03/30/97          Original Code
+ *    05/28/99          Added user-definable datums (for JMTK)
+ *                      Added datum domain of validity checking (for JMTK)
+ *                      Added datum shift accuracy calculation (for JMTK) 
+ */
+
+
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+#define DATUM_NO_ERROR                          0x0000
+#define DATUM_NOT_INITIALIZED_ERROR             0x0001
+#define DATUM_7PARAM_FILE_OPEN_ERROR            0x0002
+#define DATUM_7PARAM_FILE_PARSING_ERROR         0x0004
+#define DATUM_7PARAM_OVERFLOW_ERROR             0x0008
+#define DATUM_3PARAM_FILE_OPEN_ERROR            0x0010
+#define DATUM_3PARAM_FILE_PARSING_ERROR         0x0020
+#define DATUM_3PARAM_OVERFLOW_ERROR             0x0040
+#define DATUM_INVALID_INDEX_ERROR               0x0080
+#define DATUM_INVALID_SRC_INDEX_ERROR           0x0100
+#define DATUM_INVALID_DEST_INDEX_ERROR          0x0200
+#define DATUM_INVALID_CODE_ERROR                0x0400
+#define DATUM_LAT_ERROR                         0x0800
+#define DATUM_LON_ERROR                         0x1000
+#define DATUM_SIGMA_ERROR                       0x2000
+#define DATUM_DOMAIN_ERROR                      0x4000
+#define DATUM_ELLIPSE_ERROR                     0x8000
+
+
+/***************************************************************************/
+/*
+ *                          GLOBAL DECLARATIONS
+ */
+typedef enum Datum_Types
+{
+  Three_Param_Datum,
+  Seven_Param_Datum,
+  WGS84_Datum,
+  WGS72_Datum
+} Datum_Type; /* different types of datums */
+
+
+/***************************************************************************/
+/*
+ *                            FUNCTION PROTOTYPES
+ */
+
+/* ensure proper linkage to c++ programs */
+#ifdef __cplusplus 
+extern "C" {
+#endif
+
+  long Initialize_Datums(void);
+/*
+ * The function Initialize_Datums creates the datum table from two external
+ * files.  If an error occurs, the initialization stops and an error code is
+ * returned.  This function must be called before any of the other functions
+ * in this component.
+ */
+
+
+  long Create_Datum ( const char *Code,
+                      const char *Name,
+                      const char *Ellipsoid_Code,
+                      double Delta_X,
+                      double Delta_Y,
+                      double Delta_Z,
+                      double Sigma_X,
+                      double Sigma_Y,
+                      double Sigma_Z,
+                      double South_latitude,
+                      double North_latitude,
+                      double West_longitude,
+                      double East_longitude);
+/*
+ *   Code           : 5-letter new datum code.                      (input)
+ *   Name           : Name of the new datum                         (input)
+ *   Ellipsoid_Code : 2-letter code for the associated ellipsoid    (input)
+ *   Delta_X        : X translation to WGS84 in meters              (input)
+ *   Delta_Y        : Y translation to WGS84 in meters              (input)
+ *   Delta_Z        : Z translation to WGS84 in meters              (input)
+ *   Sigma_X        : Standard error in X in meters                 (input)
+ *   Sigma_Y        : Standard error in Y in meters                 (input)
+ *   Sigma_Z        : Standard error in Z in meters                 (input)
+ *   South_latitude : Southern edge of validity rectangle in radians(input)
+ *   North_latitude : Northern edge of validity rectangle in radians(input)
+ *   West_longitude : Western edge of validity rectangle in radians (input)
+ *   East_longitude : Eastern edge of validity rectangle in radians (input)
+ *
+ * The function Create_Datum creates a new local (3-parameter) datum with the 
+ * specified code, name, shift values, and standard error values.  If the 
+ * datum table has not been initialized, the specified code is already in use, 
+ * or a new version of the 3-param.dat file cannot be created, an error code 
+ * is returned, otherwise DATUM_NO_ERROR is returned.  Note that the indexes 
+ * of all datums in the datum table may be changed by this function.
+ */
+
+
+  long Datum_Count ( long *Count );
+/*
+ *  The function Datum_Count returns the number of Datums in the table
+ *  if the table was initialized without error.
+ *
+ *  Count   : number of datums in the datum table                   (output)
+ */
+
+
+  long Datum_Index ( const char *Code, 
+                     long *Index );
+/*
+ *  The function Datum_Index returns the index of the datum with the 
+ *  specified code.
+ *
+ *  Code    : The datum code being searched for                     (input)
+ *  Index   : The index of the datum in the table with the          (output)
+ *              specified code
+ */
+
+
+  long Datum_Code ( const long Index,
+                    char *Code );
+/*
+ *  The function Datum_Code returns the 5-letter code of the datum
+ *  referenced by index.
+ *
+ *  Index   : The index of a given datum in the datum table         (input)
+ *  Code    : The datum code of the datum referenced by index       (output)
+ */
+
+
+  long Datum_Name ( const long Index,
+                    char *Name );
+/*
+ *  The function Datum_Name returns the name of the datum referenced by
+ *  index.
+ *
+ *  Index   : The index of a given datum in the datum table         (input)
+ *  Name    : The datum name of the datum referenced by index       (output)
+ */
+
+
+  long Datum_Ellipsoid_Code ( const long Index,
+                              char *Code );
+/*
+ *  The function Datum_Ellipsoid_Code returns the 2-letter ellipsoid code 
+ *  for the ellipsoid associated with the datum referenced by index.
+ *
+ *  Index   : The index of a given datum in the datum table           (input)
+ *  Code    : The ellisoid code for the ellipsoid associated with the (output)
+ *               datum referenced by index 
+ */
+
+
+  long Get_Datum_Type ( const long Index,
+                        Datum_Type *Type );
+/*
+ *  The function Get_Datum_Type returns the type of the datum referenced by
+ *  index.
+ *
+ *  Index   : The index of a given datum in the datum table         (input)
+ *  Type    : The type of the datum referenced by index             (output)
+ */
+
+
+  long Datum_Seven_Parameters ( const long Index, 
+                                double *Delta_X,
+                                double *Delta_Y,
+                                double *Delta_Z,
+                                double *Rx,
+                                double *Ry,
+                                double *Rz,
+                                double *Scale_Factor );
+/*
+ *   The function Datum_Seven_Parameters returns the seven parameters
+ *   for the datum referenced by index.
+ *
+ *    Index      : The index of a given datum in the datum table   (input)
+ *    Delta_X    : X translation in meters                         (output)
+ *    Delta_Y    : Y translation in meters                         (output)
+ *    Delta_Z    : Z translation in meters                         (output)
+ *    Rx         : X rotation in radians                           (output)
+ *    Rx         : Y rotation in radians                           (output)
+ *    Ry         : Z rotation in radians                           (output)
+ *    Scale_Factor : Scale factor                                  (output)
+ */
+
+
+  long Datum_Three_Parameters ( const long Index, 
+                                double *Delta_X,
+                                double *Delta_Y,
+                                double *Delta_Z);
+/*
+ *   The function Datum_Three_Parameters returns the three parameters 
+ *   for the datum referenced by index.
+ *
+ *    Index      : The index of a given datum in the datum table   (input)
+ *    Delta_X    : X translation in meters                         (output)
+ *    Delta_Y    : Y translation in meters                         (output)
+ *    Delta_Z    : Z translation in meters                         (output)
+ */
+
+
+  long Datum_Errors ( const long Index,
+                      double *Sigma_X,
+                      double *Sigma_Y,
+                      double *Sigma_Z);
+/*
+ *   The function Datum_Errors returns the standard errors in X,Y, & Z 
+ *   for the datum referenced by index.
+ *
+ *    Index      : The index of a given datum in the datum table   (input)
+ *    Sigma_X    : Standard error in X in meters                   (output)
+ *    Sigma_Y    : Standard error in Y in meters                   (output)
+ *    Sigma_Z    : Standard error in Z in meters                   (output)
+ */
+
+
+  long Datum_Valid_Rectangle ( const long Index,
+                               double *South_latitude,
+                               double *North_latitude,
+                               double *West_longitude,
+                               double *East_longitude);
+/*
+ *   The function Datum_Valid_Rectangle returns the edges of the validity 
+ *   rectangle for the datum referenced by index.
+ *
+ *   Index          : The index of a given datum in the datum table   (input)
+ *   South_latitude : Southern edge of validity rectangle in radians  (input)
+ *   North_latitude : Northern edge of validity rectangle in radians  (input)
+ *   West_longitude : Western edge of validity rectangle in radians   (input)
+ *   East_longitude : Eastern edge of validity rectangle in radians   (input)
+ */
+
+
+  long Valid_Datum ( const long Index,
+                     double latitude,
+                     double longitude,
+                     long *result);
+/*
+ *  This function checks whether or not the specified location is within the 
+ *  validity rectangle for the specified datum.  It returns zero if the specified
+ *  location is NOT within the validity rectangle, and returns 1 otherwise.
+ *
+ *   Index     : The index of a given datum in the datum table      (input)
+ *   latitude  : Latitude of the location to be checked in radians  (input)
+ *   longitude : Longitude of the location to be checked in radians (input)
+ *   result    : Indicates whether location is inside (1) or outside (0)
+ *               of the validity rectangle of the specified datum   (output)
+ */
+
+
+  long Geocentric_Shift_To_WGS84 (const long Index,
+                                  const double X,
+                                  const double Y,
+                                  const double Z,
+                                  double *X_WGS84,
+                                  double *Y_WGS84,
+                                  double *Z_WGS84);
+/*
+ *  This function shifts a geocentric coordinate (X, Y, Z in meters) relative
+ *  to the datum referenced by index to a geocentric coordinate (X, Y, Z in
+ *  meters) relative to WGS84.
+ *
+ *  Index   : Index of local datum                       (input)
+ *  X       : X coordinate relative to the source datum  (input)
+ *  Y       : Y coordinate relative to the source datum  (input)
+ *  Z       : Z coordinate relative to the source datum  (input)
+ *  X_WGS84 : X coordinate relative to WGS84             (output)
+ *  Y_WGS84 : Y coordinate relative to WGS84             (output)
+ *  Z_WGS84 : Z coordinate relative to WGS84             (output)
+ */
+
+
+  long Geocentric_Shift_From_WGS84 (const double X_WGS84,
+                                    const double Y_WGS84,
+                                    const double Z_WGS84,
+                                    const long Index,
+                                    double *X,
+                                    double *Y,
+                                    double *Z);
+/*
+ *  This function shifts a geocentric coordinate (X, Y, Z in meters) relative
+ *  to WGS84 to a geocentric coordinate (X, Y, Z in meters) relative to the
+ *  local datum referenced by index.
+ *
+ *  X_WGS84 : X coordinate relative to WGS84                 (input)
+ *  Y_WGS84 : Y coordinate relative to WGS84                 (input)
+ *  Z_WGS84 : Z coordinate relative to WGS84                 (input)
+ *  Index   : Index of destination datum                     (input)
+ *  X       : X coordinate relative to the destination datum (output)
+ *  Y       : Y coordinate relative to the destination datum (output)
+ *  Z       : Z coordinate relative to the destination datum (output)
+ */
+
+
+  long Geocentric_Datum_Shift ( const long Index_in,
+                                const double X_in,
+                                const double Y_in,
+                                const double Z_in,
+                                const long Index_out,
+                                double *X_out,
+                                double *Y_out,
+                                double *Z_out);
+/*
+ *  This function shifts a geocentric coordinate (X, Y, Z in meters) relative
+ *  to the source datum to geocentric coordinate (X, Y, Z in meters) relative
+ *  to the destination datum.
+ *
+ *  Index_in  : Index of source datum                      (input)
+ *  X_in      : X coordinate relative to source datum      (input)
+ *  Y_in      : Y coordinate relative to source datum      (input)
+ *  Z_in      : Z coordinate relative to source datum      (input)
+ *  Index_out : Index of destination datum                 (input)
+ *  X_out     : X coordinate relative to destination datum (output)
+ *  Y_out     : Y coordinate relative to destination datum (output)
+ *  Z_out     : Z coordinate relative to destination datum (output)
+ */
+
+
+  long Geodetic_Shift_To_WGS84 (const long Index,
+                                const double Lat_in,
+                                const double Lon_in,
+                                const double Hgt_in,
+                                double *WGS84_Lat,
+                                double *WGS84_Lon,
+                                double *WGS84_Hgt);
+/*
+ *  This function shifts geodetic coordinates relative to a given source datum
+ *  to geodetic coordinates relative to WGS84.
+ *
+ *  Index     : Index of source datum                                 (input)
+ *  Lat_in    : Latitude in radians relative to source datum          (input)
+ *  Lon_in    : Longitude in radians relative to source datum         (input)
+ *  Hgt_in    : Height in meters relative to source datum's ellipsoid (input)
+ *  WGS84_Lat : Latitude in radians relative to WGS84                 (output)
+ *  WGS84_Lon : Longitude in radians relative to WGS84                (output)
+ *  WGS84_Hgt : Height in meters relative to WGS84 ellipsoid          (output)
+ */
+
+
+  long Geodetic_Shift_From_WGS84( const double WGS84_Lat,
+                                  const double WGS84_Lon,
+                                  const double WGS84_Hgt,
+                                  const long Index,
+                                  double *Lat_out,
+                                  double *Lon_out,
+                                  double *Hgt_out);
+/*
+ *  This function shifts geodetic coordinates relative to a WGS84 
+ *  to geodetic coordinates relative to a given local datum.
+ *                                                                   
+ *  WGS84_Lat : Latitude in radians relative to WGS84                      (input)
+ *  WGS84_Lon : Longitude in radians relative to WGS84                     (input)
+ *  WGS84_Hgt : Height in meters relative to WGS84 ellipsoid               (input)
+ *  Index     : Index of destination datum                                 (input)
+ *  Lat_in    : Latitude in radians relative to destination datum          (output)
+ *  Lon_in    : Longitude in radians relative to destination datum         (output)
+ *  Hgt_in    : Height in meters relative to destination datum's ellipsoid (output)
+ */
+
+
+  long Geodetic_Datum_Shift ( const long Index_in,
+                              const double Lat_in,
+                              const double Lon_in,
+                              const double Hgt_in,
+                              const long Index_out,
+                              double *Lat_out,
+                              double *Lon_out,
+                              double *Hgt_out);
+/*
+ *  This function shifts geodetic coordinates (latitude, longitude in radians
+ *  and height in meters) relative to the source datum to geodetic coordinates
+ *  (latitude, longitude in radians and height in meters) relative to the
+ *  destination datum.
+ *
+ *  Index_in  : Index of source datum                                      (input)
+ *  Lat_in    : Latitude in radians relative to source datum               (input)
+ *  Lon_in    : Longitude in radians relative to source datum              (input)
+ *  Hgt_in    : Height in meters relative to source datum's ellipsoid      (input)
+ *  Index_out : Index of destination datum                                 (input)
+ *  Lat_out   : Latitude in radians relative to destination datum          (output)
+ *  Lon_out   : Longitude in radians relative to destination datum         (output)
+ *  Hgt_out   : Height in meters relative to destination datum's ellipsoid (output)
+ */
+
+
+  long Datum_Shift_Error (const long Index_in,
+                          const long Index_out,
+                          double latitude,
+                          double longitude,
+                          double *ce90,
+                          double *le90,
+                          double *se90);
+/*
+ *  This function returns the 90% horizontal (circular), vertical (linear), and 
+ *  spherical errors for a shift from the specified source datum to the 
+ *  specified destination datum at the specified location.
+ *
+ *  Index_in  : Index of source datum                                      (input)
+ *  Index_out : Index of destination datum                                 (input)
+ *  latitude  : Latitude of point being converted in radians               (input)
+ *  longitude : Longitude of point being converted in radians              (input)
+ *  ce90      : Combined 90% circular horizontal error in meters           (output)
+ *  le90      : Combined 90% linear vertical error in meters               (output)
+ *  se90      : Combined 90% spherical error in meters                     (output)
+ */
+
+
+#ifdef __cplusplus 
+}
+#endif
+
+#endif /* DATUM_H */
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimDatum.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimDatum.cpp
new file mode 100644
index 0000000000..e77e24c148
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimDatum.cpp
@@ -0,0 +1,124 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimDatum.cpp,v 1.3 2002/05/24 16:36:02 gpotts Exp $
+#include "ossimDatum.h"
+#include "base/data_types/ossimGpt.h"
+#include "base/data_types/ellipse/ossimEllipsoid.h"
+
+void ossimDatum::molodenskyShift(double a,
+                                 double da,
+                                 double f,
+                                 double df,
+                                 double dx,
+                                 double dy,
+                                 double dz,
+                                 double Lat_in,
+                                 double Lon_in,
+                                 double Hgt_in,
+                                 double &Lat_out,
+                                 double &Lon_out,
+                                 double &Hgt_out
+)const
+{
+  /* Begin Molodensky_Shift */
+  /*
+   *  This function shifts geodetic coordinates using the Molodensky method.
+   *
+   *    a         : Semi-major axis of source ellipsoid in meters  (input)
+   *    da        : Destination a minus source a                   (input)
+   *    f         : Flattening of source ellipsoid                 (input)
+   *    df        : Destination f minus source f                   (input)
+   *    dx        : X coordinate shift in meters                   (input)
+   *    dy        : Y coordinate shift in meters                   (input)
+   *    dz        : Z coordinate shift in meters                   (input)
+   *    Lat_in    : Latitude in radians.                           (input)
+   *    Lon_in    : Longitude in radians.                          (input)
+   *    Hgt_in    : Height in meters.                              (input)
+   *    Lat_out   : Calculated latitude in radians.                (output)
+   *    Lon_out   : Calculated longitude in radians.               (output)
+   *    Hgt_out   : Calculated height in meters.                   (output)
+   */
+  double tLon_in;   /* temp longitude                                   */
+  double e2;        /* Intermediate calculations for dp, dl               */
+  double ep2;       /* Intermediate calculations for dp, dl               */
+  double sin_Lat;   /* sin(Latitude_1)                                    */
+  double sin2_Lat;  /* (sin(Latitude_1))^2                                */
+  double sin_Lon;   /* sin(Longitude_1)                                   */
+  double cos_Lat;   /* cos(Latitude_1)                                    */
+  double cos_Lon;   /* cos(Longitude_1)                                   */
+  double w2;        /* Intermediate calculations for dp, dl               */
+  double w;         /* Intermediate calculations for dp, dl               */
+  double w3;        /* Intermediate calculations for dp, dl               */
+  double m;         /* Intermediate calculations for dp, dl               */
+  double n;         /* Intermediate calculations for dp, dl               */
+  double dp;        /* Delta phi                                          */
+  double dp1;       /* Delta phi calculations                             */
+  double dp2;       /* Delta phi calculations                             */
+  double dp3;       /* Delta phi calculations                             */
+  double dl;        /* Delta lambda                                       */
+  double dh;        /* Delta height                                       */
+  double dh1;       /* Delta height calculations                          */
+  double dh2;       /* Delta height calculations                          */
+
+  if(Hgt_in == OSSIM_DBL_NAN)
+  {
+     Hgt_in = 0.0;
+  }
+  
+  if (Lon_in > M_PI)
+    tLon_in = Lon_in - (2*M_PI);
+  else
+     tLon_in = Lon_in;
+  
+  e2 = 2 * f - f * f;
+  ep2 = e2 / (1 - e2);
+  sin_Lat = sin(Lat_in);
+  cos_Lat = cos(Lat_in);
+  sin_Lon = sin(tLon_in);
+  cos_Lon = cos(tLon_in);
+  sin2_Lat = sin_Lat * sin_Lat;
+  w2 = 1.0 - e2 * sin2_Lat;
+  w = sqrt(w2);
+  w3 = w * w2;
+  m = (a * (1.0 - e2)) / w3;
+  n = a / w;
+  dp1 = cos_Lat * dz - sin_Lat * cos_Lon * dx - sin_Lat * sin_Lon * dy;
+  dp2 = ((e2 * sin_Lat * cos_Lat) / w) * da;
+  dp3 = sin_Lat * cos_Lat * (2.0 * n + ep2 * m * sin2_Lat) * (1.0 - f) * df;
+  dp = (dp1 + dp2 + dp3) / (m + Hgt_in);
+  dl = (-sin_Lon * dx + cos_Lon * dy) / ((n + Hgt_in) * cos_Lat);
+  dh1 = (cos_Lat * cos_Lon * dx) + (cos_Lat * sin_Lon * dy) + (sin_Lat * dz);
+  dh2 = -(w * da) + ((a * (1 - f)) / w) * sin2_Lat * df;
+  dh = dh1 + dh2;
+
+  Lat_out = Lat_in + dp;
+  Lon_out = Lon_in + dl;
+  Hgt_out = Hgt_in + dh;
+
+  if (Lon_out > (M_PI * 2))
+     Lon_out -= 2*M_PI;
+  if (Lon_out < (- M_PI))
+     Lon_out += 2*M_PI;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimDatum.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimDatum.h
new file mode 100644
index 0000000000..1a9bf0f571
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimDatum.h
@@ -0,0 +1,160 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for OssimDatum.  This is a class wrapper
+// for Geotrans datum.  For more thorough description of each function
+// look at the datum.h file.
+//*******************************************************************
+//  $Id: ossimDatum.h,v 1.9 2003/05/13 11:31:03 dburken Exp $
+#ifndef ossimDatum_HEADER
+#define ossimDatum_HEADER
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimGpt.h"
+#include "base/data_types/ellipse/ossimEllipsoid.h"
+
+class OSSIMDLLEXPORT ossimDatum
+{
+public:
+   ossimDatum(const ossimString &code, const ossimString &name,
+              const ossimEllipsoid* anEllipsoid,
+              ossim_float64 sigmaX, ossim_float64 sigmaY, ossim_float64 sigmaZ,
+              ossim_float64 westLongitude, ossim_float64 eastLongitude,
+              ossim_float64 southLatitude, ossim_float64 northLatitude)
+      :theCode(code),
+       theName(name),
+       theEllipsoid(anEllipsoid),
+       theSigmaX(sigmaX),
+       theSigmaY(sigmaY),
+       theSigmaZ(sigmaZ),
+       theWestLongitude(westLongitude),
+       theEastLongitude(eastLongitude),
+       theSouthLatitude(southLatitude),
+       theNorthLatitude(northLatitude)
+      {};
+   virtual ~ossimDatum(){};
+
+   // Argument holds the source point and datum.  Returns another
+   // point with this datum.
+   //
+   virtual ossimGpt shift(const ossimGpt    &aPt)const=0;
+   //utility functions to shift to and from the standard coordinates.
+   //Users should use the shift instead!!!
+   //
+   virtual ossimGpt       shiftToWgs84(const ossimGpt &aPt)const = 0;
+   virtual ossimGpt       shiftFromWgs84(const ossimGpt &aPt)const = 0;
+   
+
+   virtual bool  isTheSameAs(const ossimDatum *aDatum)const
+      {return this == aDatum;}
+   virtual const ossimString& code()const{return theCode;}
+   virtual const ossimString& name()const{return theName;}
+   virtual const ossimEllipsoid* ellipsoid()const{return theEllipsoid;}
+   virtual ossim_float64 sigmaX()const{return theSigmaX;}
+   virtual ossim_float64 sigmaY()const{return theSigmaY;}
+   virtual ossim_float64 sigmaZ()const{return theSigmaZ;}
+
+   virtual ossim_float64 westLongitude()const{return theWestLongitude;}
+   virtual ossim_float64 eastLongitude()const{return theEastLongitude;}
+   virtual ossim_float64 southLatitude()const{return theSouthLatitude;}
+   virtual ossim_float64 northLatitude()const{return theNorthLatitude;}
+   
+   virtual ossim_float64 param1()const=0;
+   virtual ossim_float64 param2()const=0;
+   virtual ossim_float64 param3()const=0;
+   virtual ossim_float64 param4()const=0;
+   virtual ossim_float64 param5()const=0;
+   virtual ossim_float64 param6()const=0;
+   virtual ossim_float64 param7()const=0;
+
+   virtual bool isInside(ossim_float64 latitude, ossim_float64 longitude)const
+      {
+         return ((theSouthLatitude <= latitude) &&
+                 (latitude <= theNorthLatitude) &&
+                 (theWestLongitude <= longitude) &&
+                 (longitude <= theEastLongitude));
+      }
+
+   bool operator ==(const ossimDatum& rhs)const
+      {
+         return ( (theCode == rhs.theCode)&&
+                  (theName == rhs.theName)&&
+                  (*theEllipsoid == *rhs.theEllipsoid)&&
+                  (theSigmaX == rhs.theSigmaX)&&
+                  (theSigmaY == rhs.theSigmaY)&&
+                  (theSigmaZ == rhs.theSigmaZ)&&
+                  (theWestLongitude == rhs.theWestLongitude)&&
+                  (theEastLongitude == rhs.theEastLongitude)&&
+                  (theSouthLatitude == rhs.theSouthLatitude)&&
+                  (theNorthLatitude == rhs.theNorthLatitude));
+      }
+protected:
+   
+   /*!
+    * This is directly from Geotrans:
+    * Begin Molodensky_Shift
+    * This function shifts geodetic coordinates using the Molodensky method.
+    *
+    *    a         : Semi-major axis of source ellipsoid in meters  (input)
+    *    da        : Destination a minus source a                   (input)
+    *    f         : Flattening of source ellipsoid                 (input)
+    *    df        : Destination f minus source f                   (input)
+    *    dx        : X coordinate shift in meters                   (input)
+    *    dy        : Y coordinate shift in meters                   (input)
+    *    dz        : Z coordinate shift in meters                   (input)
+    */
+   virtual void    molodenskyShift( double a,
+                                    double da,
+                                    double f,
+                                    double df,
+                                    double dx,
+                                    double dy,
+                                    double dz,
+                                    double Lat_in,
+                                    double Lon_in,
+                                    double Hgt_in,
+                                   double &Lat_out,
+                                   double &Lon_out,
+                                   double &Hgt_out)const;
+   bool withinMolodenskyRange(const ossimGpt& pt)const
+      {
+         double lat = pt.latd();
+         
+         return ((lat < 89.75) && (lat > -89.75));
+      }
+
+private:
+   ossimString           theCode;
+   ossimString           theName;
+   const ossimEllipsoid *theEllipsoid;
+   
+   ossim_float64        theSigmaX;
+   ossim_float64        theSigmaY;
+   ossim_float64        theSigmaZ;
+
+   ossim_float64        theWestLongitude;
+   ossim_float64        theEastLongitude;
+   ossim_float64        theSouthLatitude;
+   ossim_float64        theNorthLatitude;   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridDatum.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridDatum.cpp
new file mode 100644
index 0000000000..ee14dfda57
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridDatum.cpp
@@ -0,0 +1,128 @@
+#include "ossimNadconGridDatum.h"
+
+ossimNadconGridDatum::ossimNadconGridDatum(const ossimFilename& datumDirectory,
+					   const ossimString &code, const ossimString &name,
+					   const ossimEllipsoid* anEllipsoid,
+					   double sigmaX,
+					   double sigmaY,
+					   double sigmaZ,
+					   double westLongitude,
+					   double eastLongitude,
+					   double southLatitude,
+					   double northLatitude,
+					   double param1,
+					   double param2,
+					   double param3)
+  :ossimThreeParamDatum(code,
+			name,
+			anEllipsoid,
+			sigmaX,
+			sigmaY,
+			sigmaZ,
+			westLongitude,
+			eastLongitude,
+			southLatitude,
+			northLatitude,
+			param1,
+			param2,
+			param3),
+   theDatumDirectory(datumDirectory)
+{
+  theCurrentGridRect.makeNan();
+
+  ossimNadconGridHeader header;
+  theConusRect.makeNan();
+  theHawaiiRect.makeNan();
+  theAlaskaRect.makeNan();
+  theStGeorgeRect.makeNan();
+  theLatStLaurenceRect.makeNan();
+  theStPaulRect.makeNan();
+  thePrviRect.makeNan();
+
+  if(header.readHeader(theDatumDirectory.dirCat("conus.las")))
+    {
+      theConusRect = header.getBoundingRect();
+    }
+  if(header.readHeader(theDatumDirectory.dirCat("hawaii.las")))
+    {
+      theHawaiiRect = header.getBoundingRect();
+    }
+  if(header.readHeader(theDatumDirectory.dirCat("alaska.las")))
+    {
+      theAlaskaRect = header.getBoundingRect();
+    }
+  if(header.readHeader(theDatumDirectory.dirCat("stgeorge.las")))
+    {
+      theStGeorgeRect = header.getBoundingRect();
+    }
+  if(header.readHeader(theDatumDirectory.dirCat("stlrnc.las")))
+    {
+      theLatStLaurenceRect = header.getBoundingRect();
+    }
+  if(header.readHeader(theDatumDirectory.dirCat("stpaul.las")))
+    {
+      theStPaulRect = header.getBoundingRect();
+    }
+  if(header.readHeader(theDatumDirectory.dirCat("prvi.las")))
+    {
+      thePrviRect = header.getBoundingRect();
+    }
+}
+
+void ossimNadconGridDatum::checkGrid(const ossimDpt& latLon)const
+{
+  if(theCurrentGridRect.pointWithin(latLon))
+    {
+      return;
+    }
+  else if(theConusRect.pointWithin(latLon))
+  {
+    theLatGrid.open(theDatumDirectory.dirCat("conus.las"));
+    theLonGrid.open(theDatumDirectory.dirCat("conus.los"));
+		   
+    theCurrentGridRect = theConusRect;
+  }
+  else if(theHawaiiRect.pointWithin(latLon))
+  {
+    theLatGrid.open(theDatumDirectory.dirCat("hawaii.las"));
+    theLonGrid.open(theDatumDirectory.dirCat("hawaii.los"));
+		   
+    theCurrentGridRect = theHawaiiRect;
+  }
+  else if(theAlaskaRect.pointWithin(latLon))
+    {
+      theLatGrid.open(theDatumDirectory.dirCat("alaska.las"));
+      theLonGrid.open(theDatumDirectory.dirCat("alaska.los"));
+      
+      theCurrentGridRect = theAlaskaRect;
+    }
+  else if(theStGeorgeRect.pointWithin(latLon))
+    {
+      theLatGrid.open(theDatumDirectory.dirCat("stgeorge.las"));
+      theLonGrid.open(theDatumDirectory.dirCat("stgeorge.los"));
+      
+      theCurrentGridRect = theStGeorgeRect;
+    }
+  else if(theLatStLaurenceRect.pointWithin(latLon))
+    {
+      theLatGrid.open(theDatumDirectory.dirCat("stlrnc.las"));
+      theLonGrid.open(theDatumDirectory.dirCat("stlrnc.los"));
+      
+      theCurrentGridRect = theLatStLaurenceRect;
+    }
+  else if(theStPaulRect.pointWithin(latLon))
+    {
+      theLatGrid.open(theDatumDirectory.dirCat("stpaul.las"));
+      theLonGrid.open(theDatumDirectory.dirCat("stpaul.los"));
+      
+      theCurrentGridRect = theStPaulRect;
+    }
+  else if(thePrviRect.pointWithin(latLon))
+    {
+      theLatGrid.open(theDatumDirectory.dirCat("prvi.las"));
+      theLonGrid.open(theDatumDirectory.dirCat("prvi.los"));
+      
+      theCurrentGridRect = thePrviRect;
+    }
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridDatum.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridDatum.h
new file mode 100644
index 0000000000..77e5024318
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridDatum.h
@@ -0,0 +1,44 @@
+#ifndef ossimNadconGridDatum_HEADER
+#define ossimNadconGridDatum_HEADER
+
+#include "ossimThreeParamDatum.h"
+#include "ossimNadconGridFile.h"
+#include "base/data_types/ossimDrect.h"
+
+class ossimNadconGridDatum : public ossimThreeParamDatum
+{
+public:
+  ossimNadconGridDatum(const ossimFilename& datumDirectory,
+		       const ossimString &code, 
+		       const ossimString &name,
+		       const ossimEllipsoid* anEllipsoid,
+		       double sigmaX,
+		       double sigmaY,
+		       double sigmaZ,
+		       double westLongitude,
+		       double eastLongitude,
+		       double southLatitude,
+		       double northLatitude,
+		       double param1,
+		       double param2,
+		       double param3);
+
+protected:
+  mutable ossimDrect theConusRect;
+  mutable ossimDrect theHawaiiRect;
+  mutable ossimDrect theAlaskaRect;
+  mutable ossimDrect theStGeorgeRect;
+  mutable ossimDrect theLatStLaurenceRect;
+  mutable ossimDrect theStPaulRect;
+  mutable ossimDrect thePrviRect;
+  
+  mutable ossimNadconGridFile theLatGrid;
+  mutable ossimNadconGridFile theLonGrid;
+  
+  mutable ossimDrect    theCurrentGridRect;
+  ossimFilename theDatumDirectory;
+  
+  void checkGrid(const ossimDpt& latLon)const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridFile.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridFile.cpp
new file mode 100644
index 0000000000..dfe0e029f9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridFile.cpp
@@ -0,0 +1,100 @@
+#include <base/data_types/datum/ossimNadconGridFile.h>
+#include <base/misc/ossimEndian.h>
+
+using namespace std;
+
+ossimNadconGridFile::~ossimNadconGridFile()
+{
+   close();
+}
+
+bool ossimNadconGridFile::open(const ossimFilename& file)
+{
+   if(theHeader.readHeader(file))
+   {
+      theInputFile.close();
+      theInputFile.clear();
+      theInputFile.open(file, ios::in|ios::binary);
+
+      theBoundingRect = theHeader.getBoundingRect();
+      theLatLonOrigin.lat = theHeader.getMinY();
+      theLatLonOrigin.lon = theHeader.getMinX();
+      theFilename = file;
+      theFileOkFlag = true;
+      return theInputFile.good();
+   }
+   theFileOkFlag = false;
+   theFilename   = "";
+
+   return false;
+}
+
+void ossimNadconGridFile::close()
+{
+   theInputFile.close();
+}
+
+double ossimNadconGridFile::getShiftAtLatLon(double lat, double lon)const
+{
+   double result = OSSIM_DBL_NAN;
+   if(pointWithin(lat, lon))
+   {
+      double x = (lon - theLatLonOrigin.lon)/(double)theHeader.getDeltaX();
+      double y = (lat - theLatLonOrigin.lat)/(double)theHeader.getDeltaY();
+
+      int lat0 = (int)y;
+      int lat1 = lat0 + 1;
+      int lon0 = (int)x;
+      int lon1 = lon0 + 1;
+
+      int rows = theHeader.getNumberOfRows();
+      int cols = theHeader.getNumberOfCols();
+
+      if(lat1 >= rows) lat1 = lat0;
+      if(lon1 >= cols) lon1 = lon0;
+
+      double tLat = y - lat0;
+      double tLon = x - lon0;
+
+      int offset00 = lat0*theHeader.getBytesPerRow() + lon0*4 + theHeader.getStartOffset();
+      int offset01 = lat0*theHeader.getBytesPerRow() + lon1*4 + theHeader.getStartOffset();
+      int offset11 = lat1*theHeader.getBytesPerRow() + lon1*4 + theHeader.getStartOffset();
+      int offset10 = lat1*theHeader.getBytesPerRow() + lon0*4 + theHeader.getStartOffset();
+      
+      
+      double v00 = 0.0;
+      double v01 = 0.0;
+      double v11 = 0.0;
+      double v10 = 0.0;
+      
+      theInputFile.seekg((std::streampos)offset00);
+      theInputFile.read((char*)&v00, 4);
+      theInputFile.seekg((std::streampos)offset01);
+      theInputFile.read((char*)&v01, 4);
+      theInputFile.seekg((std::streampos)offset11);
+      theInputFile.read((char*)&v11, 4);
+      theInputFile.seekg((std::streampos)offset10);
+      theInputFile.read((char*)&v10, 4);
+      ossimEndian anEndian;
+
+      if(anEndian.getSystemEndianType() != OSSIM_LITTLE_ENDIAN)
+      {
+         anEndian.swap(v00);
+         anEndian.swap(v01);
+         anEndian.swap(v11);
+         anEndian.swap(v10);
+      }
+      
+      double top    = (double)v00 + ((double)v01 - (double)v00)*tLon;
+      double bottom = (double)v10 + ((double)v11 - (double)v10)*tLon;
+      
+      result = top + (bottom-top)*tLat;
+   }
+   
+   return result;
+}
+
+bool ossimNadconGridFile::pointWithin(double lat, double lon)const
+{
+  return theBoundingRect.pointWithin(ossimDpt(lon, lat));
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridFile.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridFile.h
new file mode 100644
index 0000000000..85d9b2ffb9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridFile.h
@@ -0,0 +1,54 @@
+//**************************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// Written by:   Kenneth Melero  <kmelero@sanz.com>
+//
+//**************************************************************************
+
+#ifndef ossimNadconGridFile_HEADER
+#define ossimNadconGridFile_HEADER
+#include "ossimNadconGridHeader.h"
+#include <fstream>
+
+class ossimNadconGridFile
+{
+public:
+  ossimNadconGridFile():
+    theFileOkFlag(false)
+      {}
+   ~ossimNadconGridFile();
+   bool open(const ossimFilename& file);
+   void close();
+
+   /*!
+    */
+   double getShiftAtLatLon(double lat, double lon)const;
+   bool pointWithin(double lat, double lon)const;
+   const ossimDrect getBoundingRect()const
+      {
+         return theBoundingRect;
+      }
+   
+   const ossimFilename& getFilename()const
+      {
+         return theFilename;
+      }
+   bool getFileOkFlag()const
+      {
+         return theFileOkFlag;
+      }
+   ossimDpt getSpacing()const
+      {
+         return theHeader.getSpacing();
+      }
+   
+protected:
+   mutable std::ifstream theInputFile;
+  mutable bool theFileOkFlag;
+  ossimFilename         theFilename;
+   ossimNadconGridHeader theHeader;
+   ossimDrect            theBoundingRect;
+  ossimDpt               theLatLonOrigin;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridHeader.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridHeader.cpp
new file mode 100644
index 0000000000..4fc4d338ca
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridHeader.cpp
@@ -0,0 +1,60 @@
+//**************************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// Written by:   Kenneth Melero  <kmelero@sanz.com>
+//
+//**************************************************************************
+
+#include <fstream>
+#include "ossimNadconGridHeader.h"
+#include "base/misc/ossimEndian.h"
+
+std::ostream& operator <<(std::ostream& out, const ossimNadconGridHeader& rhs)
+{
+   out << "theCols:    " << rhs.theCols << endl
+       << "theRows:    " << rhs.theRows << endl
+       << "theZ:       " << rhs.theZ << endl
+       << "theMinX:    " << rhs.theMinX <<endl
+       << "theDx:      " << rhs.theDx << endl
+       << "theMinY:    " << rhs.theMinY << endl
+       << "theDy:      " << rhs.theDy << endl
+       << "Bounds:     " << rhs.getBoundingRect() << endl;
+   return out;
+}
+
+bool ossimNadconGridHeader::readHeader(const ossimFilename& file)
+{
+   ifstream in(file.c_str(), ios::in|ios::binary);
+
+   if(in)
+   {
+      return readHeader(in);
+   }
+
+   return false;
+}
+
+bool ossimNadconGridHeader::readHeader(std::istream& in)
+{
+   in.read((char*)theCharBuf, 64);
+   in.read((char*)&theCols, 4);
+   in.read((char*)&theRows, 4);
+   in.read((char*)&theZ,   4);
+   in.read((char*)&theMinX, 4);
+   in.read((char*)&theDx, 4);
+   in.read((char*)&theMinY, 4);
+   in.read((char*)&theDy, 4);
+   ossimEndian anEndian;
+   if(anEndian.getSystemEndianType() != OSSIM_LITTLE_ENDIAN)
+     {
+       anEndian.swap(theCols);
+       anEndian.swap(theRows);
+       anEndian.swap(theZ);
+       anEndian.swap(theMinX);
+       anEndian.swap(theDx);
+       anEndian.swap(theMinY);
+       anEndian.swap(theDy);
+     }
+
+   return in.good();
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridHeader.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridHeader.h
new file mode 100644
index 0000000000..bedade8d20
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconGridHeader.h
@@ -0,0 +1,89 @@
+//**************************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// Written by:   Kenneth Melero  <kmelero@sanz.com>
+//
+//**************************************************************************
+
+#ifndef ossimNadconGridHeader_HEADER
+#define ossimNadconGridHeader_HEADER
+#include <iostream>
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimDrect.h"
+
+class ossimNadconGridHeader
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimNadconGridHeader& rhs);
+   ossimNadconGridHeader()
+      :theCols(0),
+       theRows(0),
+       theZ(0),
+       theMinX(0),
+       theDx(0),
+       theMinY(0),
+       theDy(0)
+      {
+      }
+   bool readHeader(const ossimFilename& file);
+   bool readHeader(std::istream& in);
+
+   int getStartOffset()const
+      {
+         return (theCols+2)*4;
+      }
+
+   int getBytesPerRow()const
+      {
+         return (theCols+1)*4;
+      }
+
+   int getNumberOfRows()const
+      {
+         return theRows;
+      }
+   int getNumberOfCols()const
+      {
+         return theCols;
+      }
+   double getDeltaX()const
+      {
+         return (double)theDx;
+      }
+   double getDeltaY()const
+      {
+         return (double)theDy;
+      }
+   ossimDrect getBoundingRect()const
+      {
+         return ossimDrect(theMinX,
+                           theMinY + (theRows)*theDy,
+                           theMinX + (theCols)*theDx,
+                           theMinY,
+                           OSSIM_RIGHT_HANDED);
+      }
+   double getMinX()const
+      {
+         return theMinX;
+      }
+   double getMinY()const
+      {
+         return theMinY;
+      }
+   ossimDpt getSpacing()const
+      {
+         return ossimDpt(theDx, theDy);
+      }
+protected:
+   int*   theCharBuf[64];
+   int   theCols;
+   int   theRows;
+   int   theZ;
+   double theMinX;
+   double theDx;
+   double theMinY;
+   double theDy;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNarDatum.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNarDatum.cpp
new file mode 100644
index 0000000000..eb2efa898d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNarDatum.cpp
@@ -0,0 +1,66 @@
+#include "ossimNadconNarDatum.h"
+
+ossimNadconNarDatum::ossimNadconNarDatum(const ossimFilename& nadconDirectory)
+   :
+      ossimNadconGridDatum(nadconDirectory,
+                           ossimString("NAR"),
+                           ossimString("NORTH AMERICAN 1983 NADCON, CONUS GRID"),
+                           ossimEllipsoidFactory::instance()->create(ossimString("RF")),
+                           2.000000000000000, 2.000000000000000, 2.000000000000000, 
+                           -135.0, -60.0, 15.0, 60.0,
+                           0.000000000000000, 0.000000000000000, 0.000000000000000)
+{
+}
+
+ossimGpt ossimNadconNarDatum::shift(const ossimGpt    &aPt)const
+{
+  const ossimDatum* datum = aPt.datum();
+  ossimString code = datum->code();
+  ossimString subCode(code.begin(),
+		      code.begin() + 3);
+  if(subCode == "NAR")
+  {
+     return aPt;
+  }
+  else
+  {
+     if(subCode == "NAS")
+     {
+	checkGrid(aPt);
+	if(!theLatGrid.getFileOkFlag()||
+	   !theLonGrid.getFileOkFlag())
+        {
+           return ossimThreeParamDatum::shift(aPt);
+        }
+	
+        double shiftLat = theLatGrid.getShiftAtLatLon(aPt.latd(), aPt.lond());
+        double shiftLon = theLonGrid.getShiftAtLatLon(aPt.latd(), aPt.lond());
+        
+        if((shiftLat == OSSIM_DBL_NAN)||
+           (shiftLon == OSSIM_DBL_NAN))
+        {
+           return ossimThreeParamDatum::shift(aPt);
+        }
+        else
+        {
+           // Note the shifts are stored in the file
+           // as seconds.
+           //
+           // convert the seconds into decimal degrees.  
+           //
+           shiftLat /= 3600.0;
+           shiftLon /= 3600.0;
+           return ossimGpt(aPt.latd() + shiftLat,
+                           aPt.lond() - shiftLon,
+                           aPt.height(),
+                           this);
+        }
+     }
+     else
+     {
+        return ossimThreeParamDatum::shift(aPt);
+     }
+  }
+  
+  return ossimThreeParamDatum::shift(aPt);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNarDatum.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNarDatum.h
new file mode 100644
index 0000000000..d629fe86d3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNarDatum.h
@@ -0,0 +1,21 @@
+#ifndef ossimNadconNarDatum_HEADER
+#define ossimNadconNarDatum_HEADER
+
+#include "ossimNadconGridDatum.h"
+#include "ossimNadconGridFile.h"
+class ossimNadconNarDatum : public ossimNadconGridDatum
+{
+public:
+   ossimNadconNarDatum(const ossimFilename& nadconDirectory);
+
+   // Argument holds the source point and datum.  Returns another
+   // point with this datum.
+   //
+   virtual ossimGpt shift(const ossimGpt    &aPt)const;
+   //utility functions to shift to and from the standard coordinates.
+   //Users should use the shift instead!!!
+   //
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNasDatum.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNasDatum.cpp
new file mode 100644
index 0000000000..a16bb61ff5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNasDatum.cpp
@@ -0,0 +1,106 @@
+#include "ossimNadconNasDatum.h"
+
+ossimNadconNasDatum::ossimNadconNasDatum(const ossimFilename& nadconDirectory)
+   :
+      ossimNadconGridDatum(nadconDirectory,
+                           ossimString("NAS"),
+                           ossimString("NORTH AMERICAN 1927 NADCON, CONUS GRID"),
+                           ossimEllipsoidFactory::instance()->create(ossimString("CC")),
+                           5.000000000000000, 5.000000000000000, 6.000000000000000, 
+                           -135, -60.0, 15.0, 60.0, -8.0, 160.0, 176.0)
+{
+}
+
+ossimGpt ossimNadconNasDatum::shift(const ossimGpt& aPt)const
+{
+  const ossimDatum* datum = aPt.datum();
+  ossimString code = datum->code();
+  ossimString subCode(code.begin(),
+		      code.begin() + 3);
+  if(subCode == "NAS")
+    {
+      return aPt;
+    }
+  else
+  {
+     if(subCode == "NAR")
+     {
+       checkGrid(aPt);
+       if(!theLatGrid.getFileOkFlag()||
+	  !theLonGrid.getFileOkFlag())
+	 {
+	   return ossimThreeParamDatum::shift(aPt);
+	 }
+        ossimDpt pt;
+        ossimDpt tempPt;
+        ossimDpt deltaPt;
+        double shiftLat;
+        double shiftLon;
+	double minLat = theCurrentGridRect.ll().lat;
+	double maxLat = theCurrentGridRect.ul().lat;
+	double minLon = theCurrentGridRect.ul().lon;
+	double maxLon = theCurrentGridRect.ur().lon;
+        int maxIter = 20;
+        double epsilon = 1.0e-9;
+        int c = 0;
+        
+        pt.lat = aPt.latd();
+        pt.lon = aPt.lond();
+        ossimDpt pt2;
+        tempPt = pt;
+        ossimDpt delta2;
+        while(c < maxIter)
+        {
+	  if(tempPt.lat < minLat) tempPt.lat = minLat;
+	  if(tempPt.lat > maxLat) tempPt.lat = maxLat;
+	  if(tempPt.lon < minLon) tempPt.lon = minLon;
+	  if(tempPt.lon > maxLon) tempPt.lon = maxLon;
+
+           shiftLat = theLatGrid.getShiftAtLatLon(tempPt.lat, tempPt.lon);
+           shiftLon = theLonGrid.getShiftAtLatLon(tempPt.lat, tempPt.lon);
+
+	   
+	   pt2.lat = tempPt.lat + shiftLat/3600.0;
+	   pt2.lon = tempPt.lon - shiftLon/3600.0;
+           
+           delta2  = pt2-pt;
+           if(c == 0)
+           {
+              if(fabs(deltaPt.lon) > epsilon)
+              {
+                 tempPt.lon = pt.lon - shiftLon/3600.0;
+              }
+              if(fabs(deltaPt.lat) > epsilon)
+              {
+                 tempPt.lat = pt.lat + shiftLat/3600.0;
+              }
+           }
+           else
+           {
+              if(fabs(delta2.lon) > epsilon)
+              {
+                 tempPt.lon = tempPt.lon - delta2.lon;
+              }
+              if(fabs(delta2.lat) > epsilon)
+              {
+                 tempPt.lat =tempPt.lat - delta2.lat;
+              }
+           }
+           if((fabs(delta2.lat) < epsilon)&&
+              (fabs(delta2.lon) < epsilon))
+           {
+              break;
+           }
+           else
+           {
+              ++c;
+           }
+        }
+        return ossimGpt(tempPt.lat,
+                        tempPt.lon,
+                        aPt.height(),
+                        this);
+     }
+  }
+  return ossimThreeParamDatum::shift(aPt);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNasDatum.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNasDatum.h
new file mode 100644
index 0000000000..202779d43f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimNadconNasDatum.h
@@ -0,0 +1,19 @@
+#ifndef ossimNadconNasDatum_HEADER
+#define ossimNadconNasDatum_HEADER
+
+#include "ossimNadconGridDatum.h"
+#include "ossimNadconGridFile.h"
+
+class ossimNadconNasDatum : public ossimNadconGridDatum
+{
+public:
+   ossimNadconNasDatum(const ossimFilename& nadconDirectory);
+
+   // Argument holds the source point and datum.  Returns another
+   // point with this datum.
+   //
+   virtual ossimGpt shift(const ossimGpt    &aPt)const;
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimSevenParamDatum.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimSevenParamDatum.cpp
new file mode 100644
index 0000000000..03eefd5f03
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimSevenParamDatum.cpp
@@ -0,0 +1,172 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// SevenParamDatum. This is a base class for all
+// seven param datums.
+//*******************************************************************
+//  $Id: ossimSevenParamDatum.cpp,v 1.9 2003/09/29 13:57:19 gpotts Exp $
+
+#include "ossimSevenParamDatum.h"
+#include "base/factory/ossimDatumFactory.h"
+#include "base/data_types/ellipse/ossimEllipsoid.h"
+#include "base/data_types/ossimEcefPoint.h"
+#include "ossimWgs84Datum.h"
+
+ossimGpt ossimSevenParamDatum::shift(const ossimGpt &aPt)const
+{
+   const ossimDatum* aDatum = aPt.datum();
+
+   if( (ellipsoid()->getA()== aPt.datum()->ellipsoid()->getA())&&
+       (ellipsoid()->getB()== aPt.datum()->ellipsoid()->getB()))
+   {
+      return ossimGpt(aPt.latd(), aPt.lond(), aPt.height(), this);
+   }
+   
+   if(aDatum)
+   {
+      return shiftFromWgs84( aDatum->shiftToWgs84(aPt) );
+   }
+
+   return aPt;
+}
+
+ossimGpt ossimSevenParamDatum::shiftToWgs84(const ossimGpt &aPt)const
+{
+   ossimEcefPoint p1 = aPt;
+   ossimEcefPoint p2;
+
+//    if(aPt.isHgtNan())
+//    {
+//       p1 = ossimEcefPoint(ossimGpt(aPt.latd(),
+//                                    aPt.lond(),
+//                                    0,
+//                                    aPt.datum()));
+//    }
+   
+//    if(withinMolodenskyRange(aPt.latd()))
+//    {
+//       ossimWgs84Datum wgs84;
+//       double latin, lonin, hgtin;
+//       double latout, lonout, hgtout;
+      
+//       double a = wgs84.ellipsoid()->getA();
+//       double f = wgs84.ellipsoid()->getFlattening();
+//       double da = a - ellipsoid()->getA();
+//       double df = f - ellipsoid()->getFlattening();
+      
+//       latin = aPt.latr();
+//       lonin = aPt.lonr();
+//       hgtin = aPt.height();
+
+//       if(aPt.isHgtNan())
+//       {
+//          hgtin = 0.0;
+//       }
+//       molodenskyShift(a, da, f, df, param1(), param2(), param3(),
+//                       latin, lonin, hgtin,
+//                       latout, lonout, hgtout);
+      
+//       ossimGpt g;
+
+//       g.latr(latout);
+//       g.lonr(lonout);
+//       g.height(hgtout);
+//       if(aPt.isHgtNan())
+//       {
+//          g.height(OSSIM_DBL_NAN);
+//       }
+//       return g;
+//    }
+//    else
+   {
+      //this is straight from Geotrans
+      p2.x() = p1.x() + theParam1 + theParam6*p1.y() -
+               theParam5*p1.z() + theParam7*p1.x();
+      p2.y() = p1.y() + theParam2 - theParam6*p1.x()+
+               theParam4*p1.z() + theParam7*p1.y();
+      p2.z() = p1.z() + theParam3 + theParam5*p1.x() -
+               theParam4*p1.y() + theParam7*p1.z();
+   }
+   
+   return ossimGpt(p2); // defaults to WGS84
+}
+
+ossimGpt ossimSevenParamDatum::shiftFromWgs84(const ossimGpt &aPt)const
+{      
+   ossimEcefPoint p1;
+   ossimEcefPoint p2;
+
+   if(aPt.isHgtNan())
+   {
+      p1 = ossimEcefPoint(ossimGpt(aPt.latd(),
+                                   aPt.lond(),
+                                   0,
+                                   aPt.datum()));
+   }
+   else
+   {
+      p1 = ossimEcefPoint(aPt);
+   }
+//    if(withinMolodenskyRange(aPt.latd()))
+//    {
+//       ossimWgs84Datum wgs84;
+//       double latin, lonin, hgtin;
+//       double latout, lonout, hgtout;
+      
+//       double a = wgs84.ellipsoid()->getA();
+//       double f = wgs84.ellipsoid()->getFlattening();
+//       double da = ellipsoid()->getA() - a;
+//       double df = ellipsoid()->getFlattening() - f;
+
+//       latin = aPt.latr();
+//       lonin = aPt.lonr();
+//       hgtin = aPt.height();
+
+//       if(aPt.isHgtNan())
+//       {
+//          hgtin = 0.0;
+//       }
+//       molodenskyShift(a, da, f, df, -param1(), -param2(), -param3(),
+//                       latin, lonin, hgtin,
+//                       latout, lonout, hgtout);
+//       ossimGpt g;
+
+//       g.latr(latout);
+//       g.lonr(lonout);
+//       g.height(hgtout);
+//       g.datum(this);
+//       return g;
+//    }
+//    else
+//    {
+      p2.x() = p1.x() - theParam1 - theParam6 * p1.y()
+               + theParam5 * p1.z() - theParam7 * p1.x();
+      p2.y() = p1.y() - theParam2 + theParam6 * p1.x()
+               - theParam4 *p1.z() - theParam7 * p1.y();
+
+      p2.z() = p1.z() - theParam3 - theParam5 * p1.x()
+               + theParam4 * p1.y() - theParam7 * p1.z();
+//   }
+   
+   return ossimGpt(p2, this);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimSevenParamDatum.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimSevenParamDatum.h
new file mode 100644
index 0000000000..8e3e5de815
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimSevenParamDatum.h
@@ -0,0 +1,91 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// SevenParamDatum. This is a base class for all
+// seven param datums.
+//*******************************************************************
+//  $Id: ossimSevenParamDatum.h,v 1.5 2003/05/13 11:31:03 dburken Exp $
+
+#ifndef ossimSevenParamDatum_HEADER
+#define ossimSevenParamDatum_HEADER
+#include "ossimDatum.h"
+class OSSIMDLLEXPORT ossimEllipsoid;
+
+class OSSIMDLLEXPORT ossimSevenParamDatum : public ossimDatum
+{
+public:
+   ossimSevenParamDatum(const ossimString &code, const ossimString &name,
+                        const ossimEllipsoid* anEllipsoid,
+                        ossim_float64 sigmaX,
+                        ossim_float64 sigmaY,
+                        ossim_float64 sigmaZ,
+                        ossim_float64 westLongitude,
+                        ossim_float64 eastLongitude,
+                        ossim_float64 southLatitude,
+                        ossim_float64 northLatitude,
+                        ossim_float64 aParam1,
+                        ossim_float64 aParam2,
+                        ossim_float64 aParam3,
+                        ossim_float64 aParam4,
+                        ossim_float64 aParam5,
+                        ossim_float64 aParam6,
+                        ossim_float64 aParam7)
+      : ossimDatum(code, name, anEllipsoid,
+                   sigmaX, sigmaY, sigmaZ,
+                   westLongitude, eastLongitude,
+                   southLatitude, northLatitude),
+        theParam1(aParam1),
+        theParam2(aParam2),
+        theParam3(aParam3),
+        theParam4(aParam4),
+        theParam5(aParam5),
+        theParam6(aParam6),
+        theParam7(aParam7)
+      {}
+   
+
+   /*!
+    * Will shift the ground point relative to this datum.
+    */
+   ossimGpt         shift(const ossimGpt    &aPt)const;
+   virtual ossimGpt shiftToWgs84(const ossimGpt &aPt)const;
+   virtual ossimGpt shiftFromWgs84(const ossimGpt &aPt)const;
+   
+   virtual ossim_float64 param1()const{return theParam1;}
+   virtual ossim_float64 param2()const{return theParam2;}
+   virtual ossim_float64 param3()const{return theParam3;}
+   virtual ossim_float64 param4()const{return theParam4;}
+   virtual ossim_float64 param5()const{return theParam5;}
+   virtual ossim_float64 param6()const{return theParam6;}
+   virtual ossim_float64 param7()const{return theParam7;}
+   
+private:
+   ossim_float64 theParam1;
+   ossim_float64 theParam2;
+   ossim_float64 theParam3;
+   ossim_float64 theParam4;
+   ossim_float64 theParam5;
+   ossim_float64 theParam6;
+   ossim_float64 theParam7;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimThreeParamDatum.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimThreeParamDatum.cpp
new file mode 100644
index 0000000000..e684a0cf4d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimThreeParamDatum.cpp
@@ -0,0 +1,138 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//*******************************************************************
+//  $Id: ossimThreeParamDatum.cpp,v 1.13 2005/09/19 11:40:10 gpotts Exp $
+
+#include <math.h>
+
+#include "ossimThreeParamDatum.h"
+#include "base/common/ossimConstants.h"
+#include "base/factory/ossimDatumFactory.h"
+#include "base/data_types/ellipse/ossimEllipsoid.h"
+#include "base/data_types/ossimGpt.h"
+#include "base/data_types/ossimEcefPoint.h"
+#include "base/data_types/datum/ossimWgs84Datum.h"
+
+ossimGpt ossimThreeParamDatum::shiftToWgs84(const ossimGpt &aPt)const
+{
+   ossimEcefPoint p1 = aPt;
+   ossimEcefPoint p2;
+ 
+   if(withinMolodenskyRange(aPt.latd()))
+   {
+      ossimWgs84Datum wgs84;
+      double latin, lonin, hgtin;
+      double latout, lonout, hgtout;
+      
+      double da = wgs84.ellipsoid()->getA() - ellipsoid()->getA();
+      double df = wgs84.ellipsoid()->getFlattening() - ellipsoid()->getFlattening();
+
+      latin = aPt.latr();
+      lonin = aPt.lonr();
+      hgtin = aPt.height();
+
+      if(aPt.isHgtNan())
+      {
+         hgtin = 0.0;
+      }
+      molodenskyShift(ellipsoid()->getA(), da, ellipsoid()->getFlattening(), df, param1(), param2(), param3(),
+                      latin, lonin, hgtin,
+                      latout, lonout, hgtout);
+      ossimGpt g;
+
+      g.latr(latout);
+      g.lonr(lonout);
+      g.height(hgtout);
+      g.datum(this);
+      return g;
+   }
+   else
+     {
+       p2 = ossimEcefPoint(p1.x() + theParam1,
+			   p1.y() + theParam2,
+			   p1.z() + theParam3);
+     }
+   
+   return ossimGpt(p2); // defaults to WGS84
+}
+
+ossimGpt ossimThreeParamDatum::shiftFromWgs84(const ossimGpt &aPt)const
+{
+   ossimEcefPoint p1=aPt;
+   ossimEcefPoint p2=aPt;
+   
+   if(withinMolodenskyRange(aPt.latd()))
+   {
+      ossimWgs84Datum wgs84;
+      double latin, lonin, hgtin;
+      double latout, lonout, hgtout;
+      
+      double da = ellipsoid()->getA() -  wgs84.ellipsoid()->getA();
+      double df = ellipsoid()->getFlattening() - wgs84.ellipsoid()->getFlattening();
+
+      latin = aPt.latr();
+      lonin = aPt.lonr();
+      hgtin = aPt.height();
+
+      if(aPt.isHgtNan())
+      {
+         hgtin = 0.0;
+      }
+      molodenskyShift(wgs84.ellipsoid()->getA(), da, wgs84.ellipsoid()->getFlattening(), df, -param1(), -param2(), -param3(),
+                      latin, lonin, hgtin,
+                      latout, lonout, hgtout);
+      ossimGpt g;
+
+      g.latr(latout);
+      g.lonr(lonout);
+      g.height(hgtout);
+      g.datum(this);
+      return g;
+   }
+   else
+   {
+      p2 = ossimEcefPoint(p1.x() - theParam1,
+                          p1.y() - theParam2,
+                          p1.z() - theParam3);
+   }
+   
+   
+   return ossimGpt(p2, this);
+}
+
+
+ossimGpt ossimThreeParamDatum::shift(const ossimGpt &aPt)const
+{
+   const ossimDatum *aDatum = aPt.datum();
+
+   if( code() == aDatum->code())
+   {
+      return ossimGpt(aPt.latd(), aPt.lond(), aPt.height(), this);
+   }
+   
+   if(aDatum)
+   {
+      return shiftFromWgs84(aDatum->shiftToWgs84(aPt));
+   }
+
+   return aPt;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimThreeParamDatum.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimThreeParamDatum.h
new file mode 100644
index 0000000000..98754e63a9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimThreeParamDatum.h
@@ -0,0 +1,81 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// ossimThreeParamDatum. This is a base class for all
+// three param datums.
+//*******************************************************************
+//  $Id: ossimThreeParamDatum.h,v 1.5 2003/05/13 11:31:03 dburken Exp $
+
+#ifndef ossimThreeParamDatum_HEADER
+#define ossimThreeParamDatum_HEADER
+#include "ossimDatum.h"
+
+class OSSIMDLLEXPORT ossimThreeParamDatum : public ossimDatum
+{
+public:
+   ossimThreeParamDatum(const ossimString &code, const ossimString &name,
+                        const ossimEllipsoid* anEllipsoid,
+                        ossim_float64 sigmaX,
+                        ossim_float64 sigmaY,
+                        ossim_float64 sigmaZ,
+                        ossim_float64 westLongitude,
+                        ossim_float64 eastLongitude,
+                        ossim_float64 southLatitude,
+                        ossim_float64 northLatitude,
+                        ossim_float64 param1,
+                        ossim_float64 param2,
+                        ossim_float64 param3)
+      : ossimDatum(code, name, anEllipsoid,
+              sigmaX, sigmaY, sigmaZ,
+              westLongitude, eastLongitude,
+              southLatitude, northLatitude),
+        theParam1(param1),
+        theParam2(param2),
+        theParam3(param3)
+      {}
+   virtual ~ossimThreeParamDatum(){}
+
+   /*!
+    * Will shift a ground point to this datum.  If they are the same
+    * datum then nothing happens.
+    */
+   virtual ossimGpt    shift(const ossimGpt    &aPt)const;
+   
+   virtual ossimGpt    shiftToWgs84(const ossimGpt &aPt)const;
+   virtual ossimGpt    shiftFromWgs84(const ossimGpt &aPt)const;
+   virtual ossim_float64 param1()const{return theParam1;}
+   virtual ossim_float64 param2()const{return theParam2;}
+   virtual ossim_float64 param3()const{return theParam3;}
+   virtual ossim_float64 param4()const{return 0.0;}
+   virtual ossim_float64 param5()const{return 0.0;}
+   virtual ossim_float64 param6()const{return 0.0;}
+   virtual ossim_float64 param7()const{return 1.0;}
+
+protected:
+   
+   ossim_float64 theParam1;
+   ossim_float64 theParam2;
+   ossim_float64 theParam3;
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs72Datum.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs72Datum.cpp
new file mode 100644
index 0000000000..c202dd6fc2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs72Datum.cpp
@@ -0,0 +1,223 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Wgs72Datum.  Special hardcoded datum.  It will create a static
+// instance of a Wgs72Ellipsoid and set the initial defaults for
+// that are specific to a Wgs72Datum
+//*******************************************************************
+//  $Id: ossimWgs72Datum.cpp,v 1.8 2004/04/02 21:17:00 gpotts Exp $
+
+#include <iostream>
+using namespace std;
+#include <base/data_types/datum/ossimWgs72Datum.h>
+
+#include <base/common/ossimConstants.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/factory/ossimEllipsoidFactory.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/context/ossimNotifyContext.h>
+
+/***************************************************************************/
+/*
+ *                               DEFINES FROM GEOTRANS
+ */
+
+
+ossimWgs72Datum::ossimWgs72Datum()
+   :ossimThreeParamDatum("WGD",
+                         "World Geodetic System 1972",
+                         ossimEllipsoidFactory::instance()->wgs72(),
+                         0.0,
+                         0.0,
+                         0.0,
+                         -M_PI/2.0,
+                         M_PI/2.0,
+                         -M_PI,
+                         M_PI,
+                         0.0,
+                         0.0,
+                         0.0)
+{
+   if(!ellipsoid())
+   {
+      //ERROR
+   }
+}
+
+ossimGpt ossimWgs72Datum::shift(const ossimGpt &aPt)const
+{
+   const ossimDatum *aDatum = aPt.datum();
+   
+   if( (ellipsoid()->getA()== aPt.datum()->ellipsoid()->getA())&&
+       (ellipsoid()->getB()== aPt.datum()->ellipsoid()->getB()))
+   {
+      return ossimGpt(aPt.latd(), aPt.lond(), aPt.height(), this);
+   }
+   
+   if(aDatum)
+   {  
+      return shiftFromWgs84(aDatum->shiftToWgs84(aPt));
+   }
+
+   return aPt;
+}
+
+ossimGpt ossimWgs72Datum::shiftToWgs84(const ossimGpt &aPt)const
+{
+/* Begin Geodetic_Shift_WGS72_To_WGS84 */
+  /*
+   *  This function shifts a geodetic coordinate (latitude, longitude in radians
+   *  and height in meters) relative to WGS72 to a geodetic coordinate 
+   *  (latitude, longitude in radians and height in meters) relative to WGS84.
+   *
+   *  WGS72_Lat : Latitude in radians relative to WGS72     (input)
+   *  WGS72_Lon : Longitude in radians relative to WGS72    (input)
+   *  WGS72_Hgt : Height in meters relative to WGS72        (input)
+   *  WGS84_Lat : Latitude in radians relative to WGS84     (output)
+   *  WGS84_Lon : Longitude in radians relative to WGS84    (output)
+   *  WGS84_Hgt : Height in meters  relative to WGS84       (output)
+   */
+   double Delta_Lat;
+   double Delta_Lon;
+   double Delta_Hgt;
+   double WGS84_a;       /* Semi-major axis of WGS84 ellipsoid               */
+   double WGS84_f;       /* Flattening of WGS84 ellipsoid                    */
+   double WGS72_a;       /* Semi-major axis of WGS72 ellipsoid               */
+   double WGS72_f;       /* Flattening of WGS72 ellipsoid                    */
+   double da;            /* WGS84_a - WGS72_a                                */
+   double df;            /* WGS84_f - WGS72_f                                */
+   double Q;
+   double sin_Lat;
+   double sin2_Lat;
+   
+   const ossimDatum *wgs84 = ossimDatumFactory::instance()->wgs84();
+   const ossimDatum *wgs72 = ossimDatumFactory::instance()->wgs72();
+   const ossimEllipsoid *wgs84Ellipsoid = ossimEllipsoidFactory::instance()->wgs84();
+   const ossimEllipsoid *wgs72Ellipsoid = ossimEllipsoidFactory::instance()->wgs72();
+
+   if(!wgs84 || !wgs72 || !wgs72Ellipsoid || !wgs84Ellipsoid)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimWgs72Datum::shiftToWgs84, NULL pointer found and no shift will be performed\n";
+      return (aPt);
+   }
+   
+   WGS84_a = wgs84Ellipsoid->a();
+   WGS84_f = wgs84Ellipsoid->flattening();
+   WGS72_a = wgs72Ellipsoid->a();
+   WGS72_f = wgs72Ellipsoid->flattening();
+   da = WGS84_a - WGS72_a;
+   df = WGS84_f - WGS72_f;
+   Q = M_PI /  648000;
+   sin_Lat = sin(aPt.latr());
+   sin2_Lat = sin_Lat * sin_Lat;
+   
+   Delta_Lat = (4.5 * cos(aPt.latr())) / (WGS72_a*Q) + (df * sin(2*aPt.latr())) / Q;
+   Delta_Lat /= SEC_PER_RAD;
+   Delta_Lon = 0.554 / SEC_PER_RAD;
+   Delta_Hgt = 4.5 * sin_Lat + WGS72_a * df * sin2_Lat - da + 1.4;
+
+   if(aPt.isHgtNan())
+   {
+      return ossimGpt(aPt.latd() + Delta_Lat*DEG_PER_RAD,
+                      aPt.lond() + Delta_Lon*DEG_PER_RAD,
+                      Delta_Hgt,
+                      wgs84);
+   }
+   return ossimGpt(aPt.latd() + Delta_Lat*DEG_PER_RAD,
+                   aPt.lond() + Delta_Lon*DEG_PER_RAD,
+                   aPt.height() + Delta_Hgt,
+                   wgs84);
+   /* End Geodetic_Shift_WGS72_To_WGS84 */
+}
+
+ossimGpt ossimWgs72Datum::shiftFromWgs84(const ossimGpt &aPt)const
+{
+ /* Begin Geodetic_Shift_WGS84_To_WGS72 */
+  /*
+   *  This function shifts a geodetic coordinate (latitude, longitude in radians
+   *  and height in meters) relative to WGS84 to a geodetic coordinate 
+   *  (latitude, longitude in radians and height in meters) relative to WGS72.
+   *
+   *  WGS84_Lat : Latitude in radians relative to WGS84     (input)
+   *  WGS84_Lon : Longitude in radians relative to WGS84    (input)
+   *  WGS84_Hgt : Height in meters  relative to WGS84       (input)
+   *  WGS72_Lat : Latitude in radians relative to WGS72     (output)
+   *  WGS72_Lon : Longitude in radians relative to WGS72    (output)
+   *  WGS72_Hgt : Height in meters relative to WGS72        (output)
+   */
+   double Delta_Lat;
+   double Delta_Lon;
+   double Delta_Hgt;
+   double WGS84_a;       /* Semi-major axis of WGS84 ellipsoid               */
+   double WGS84_f;       /* Flattening of WGS84 ellipsoid                    */
+   double WGS72_a;       /* Semi-major axis of WGS72 ellipsoid               */
+   double WGS72_b;       /* Semi-minor axis of WGS72 ellipsoid               */
+   double WGS72_f;       /* Flattening of WGS72 ellipsoid                    */
+   double da;            /* WGS72_a - WGS84_a                                */
+   double df;            /* WGS72_f - WGS84_f                                */
+   double Q;
+   double sin_Lat;
+   double sin2_Lat;
+   const ossimDatum *wgs84 = ossimDatumFactory::instance()->wgs84();
+   const ossimDatum *wgs72 = ossimDatumFactory::instance()->wgs72();
+   const ossimEllipsoid *wgs84Ellipsoid = ossimEllipsoidFactory::instance()->wgs84();
+   const ossimEllipsoid *wgs72Ellipsoid = ossimEllipsoidFactory::instance()->wgs72();
+   
+   if(!wgs84 || !wgs72 || !wgs72Ellipsoid || !wgs84Ellipsoid)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimWgs72Datum::shiftFromWgs84, NULL pointer found and no shift will be performed\n";
+      
+      return (aPt);
+   }
+   
+   WGS84_a = wgs84Ellipsoid->a();
+   WGS84_f = wgs84Ellipsoid->flattening();
+   WGS72_a = wgs72Ellipsoid->a();
+   WGS72_b = wgs72Ellipsoid->b();  
+   WGS72_f = wgs72Ellipsoid->flattening();
+   
+   da = WGS72_a - WGS84_a;
+   df = WGS72_f - WGS84_f;
+   Q = M_PI / 648000;
+   sin_Lat = sin(aPt.latr());
+   sin2_Lat = sin_Lat * sin_Lat;
+
+   Delta_Lat = (-4.5 * cos(aPt.latr())) / (WGS84_a*Q)
+               + (df * sin(2*aPt.latr())) / Q;
+   Delta_Lat /= SEC_PER_RAD;
+   Delta_Lon = -0.554 / SEC_PER_RAD;
+   Delta_Hgt = -4.5 * sin_Lat + WGS84_a * df * sin2_Lat - da - 1.4;
+
+   if(aPt.isHgtNan())
+   {
+      
+      return ossimGpt(aPt.latd() + Delta_Lat*DEG_PER_RAD,
+                      aPt.lond() + Delta_Lon*DEG_PER_RAD,
+                      Delta_Hgt,
+                      this);
+   }
+   return ossimGpt(aPt.latd() + Delta_Lat*DEG_PER_RAD,
+                   aPt.lond() + Delta_Lon*DEG_PER_RAD,
+                   aPt.height() + Delta_Hgt,
+                   this);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs72Datum.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs72Datum.h
new file mode 100644
index 0000000000..825fdb45e7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs72Datum.h
@@ -0,0 +1,45 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Wgs72Datum.  Special hardcoded datum.  It will create a static
+// instance of a Wgs72Ellipsoid and set the initial defaults for
+// that are specific to a Wgs72Datum
+//*******************************************************************
+//  $ID$
+#ifndef ossimWgs72Datum_HEADER
+#define ossimWgs72Datum_HEADER
+#include "ossimThreeParamDatum.h"
+
+class OSSIMDLLEXPORT ossimWgs72Datum : public ossimThreeParamDatum
+{
+public:
+   ossimWgs72Datum();
+
+   virtual ~ossimWgs72Datum(){}
+   virtual ossimGpt    shift(const ossimGpt    &aPt)const;
+   virtual ossimGpt    shiftToWgs84(const ossimGpt &aPt)const;
+   virtual ossimGpt    shiftFromWgs84(const ossimGpt &aPt)const;
+
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs84Datum.cpp b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs84Datum.cpp
new file mode 100644
index 0000000000..d47a802e24
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs84Datum.cpp
@@ -0,0 +1,79 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Wgs84Datum.  Special hardcoded datum.  It will create a static
+// instance of a Wgs84Ellipsoid and set the initial defaults for
+// that are specific to a Wgs84Datum
+//*******************************************************************
+//  $Id: ossimWgs84Datum.cpp,v 1.5 2001/10/26 19:41:17 gpotts Exp $
+
+#include "ossimWgs84Datum.h"
+#include "base/common/ossimConstants.h"
+#include "base/factory/ossimEllipsoidFactory.h"
+#include "base/data_types/ellipse/ossimEllipsoid.h"
+
+
+
+ossimWgs84Datum::ossimWgs84Datum()
+   :ossimThreeParamDatum("WGE",
+                         "World Geodetic System 1984",
+                         ossimEllipsoidFactory::instance()->wgs84(),
+                         0.0, 0.0, 0.0,
+                         -M_PI/2.0, M_PI/2.0, -M_PI, M_PI,
+                         0.0, 0.0, 0.0)
+{
+   if(!ellipsoid())
+   {
+      //ERROR
+   }
+}
+
+
+ossimGpt ossimWgs84Datum::shift(const ossimGpt &aPt)const
+{
+   const ossimDatum *aDatum = aPt.datum();
+   
+    if( aPt.datum()->code() == code())
+    {
+       return ossimGpt(aPt.latd(), aPt.lond(), aPt.height(), this);
+    }
+   
+    if(aDatum)
+    {
+       return aDatum->shiftToWgs84(aPt);
+    }
+
+   return aPt;      
+}
+
+ossimGpt ossimWgs84Datum::shiftToWgs84(const ossimGpt &aPt)const
+{
+   return ossimGpt(aPt.latd(),
+                   aPt.lond(),
+                   aPt.height(),
+                   ossimDatumFactory::instance()->wgs84());
+}
+
+ossimGpt ossimWgs84Datum::shiftFromWgs84(const ossimGpt &aPt)const
+{
+   return aPt;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs84Datum.h b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs84Datum.h
new file mode 100644
index 0000000000..115790d329
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/datum/ossimWgs84Datum.h
@@ -0,0 +1,48 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// ossimWgs84Datum.  Special hardcoded datum.  It will create a static
+// instance of a Wgs84Ellipsoid and set the initial defaults for
+// that are specific to a ossimWgs84Datum
+//*******************************************************************
+//  $Id: ossimWgs84Datum.h,v 1.4 2002/09/01 19:06:34 gpotts Exp $
+
+#ifndef ossimWgs84Datum_HEADER
+#define ossimWgs84Datum_HEADER
+#include "ossimThreeParamDatum.h"
+
+class OSSIMDLLEXPORT ossimWgs84Datum : public ossimThreeParamDatum
+{
+public:
+   ossimWgs84Datum();
+   virtual ~ossimWgs84Datum(){}
+   
+   virtual ossimGpt    shift(const ossimGpt    &aPt)const;
+
+   virtual ossimGpt    shiftToWgs84(const ossimGpt &aPt)const;
+   virtual ossimGpt    shiftFromWgs84(const ossimGpt&aPt)const;
+
+protected:
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ellipse/.cvsignore b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ellips.dat b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ellips.dat
new file mode 100644
index 0000000000..ab74751f7a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ellips.dat
@@ -0,0 +1,23 @@
+Airy                                    AA 6377563.396 6356256.9090 299.324964600
+Modified Airy                           AM 6377340.189 6356034.4480 299.324964600
+Australian National                     AN 6378160.000 6356774.7190 298.250000000
+Bessel 1841                             BR 6377397.155 6356078.9630 299.152812800
+Bessel 1841(Namibia)                    BN 6377483.865 6356165.3830 299.152812800
+Clarke 1866                             CC 6378206.400 6356583.8000 294.978698200
+Clarke 1880                             CD 6378249.145 6356514.8700 293.465000000
+Everest                                 EA 6377276.345 6356075.4130 300.801700000
+Everest (E. Malasia, Brunei)            EB 6377298.556 6356097.5500 300.801700000
+Everest 1956 (India)                    EC 6377301.243 6356100.2280 300.801700000
+Everest 1969 (West Malasia)             ED 6377295.664 6356094.6680 300.801700000
+Everest 1948(W.Mals. & Sing.)           EE 6377304.063 6356103.0390 300.801700000
+Everest (Pakistan)                      EF 6377309.613 6356109.5710 300.801700000
+Mod. Fischer 1960(South Asia)           FA 6378155.000 6356773.3200 298.300000000
+GRS 80                                  RF 6378137.000 6356752.3141 298.257222101
+Helmert 1906                            HE 6378200.000 6356818.1700 298.300000000
+Hough                                   HO 6378270.000 6356794.3430 297.000000000
+Indonesian 1974                         ID 6378160.000 6356774.5040 298.247000000
+International                           IN 6378388.000 6356911.9460 297.000000000
+Krassovsky                              KA 6378245.000 6356863.0190 298.300000000
+South American 1969                     SA 6378160.000 6356774.7190 298.250000000
+WGS 72                                  WD 6378135.000 6356750.5200 298.260000000
+WGS 84                                  WE 6378137.000 6356752.3142 298.257223563
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.c b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.c
new file mode 100644
index 0000000000..db2f89fb31
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.c
@@ -0,0 +1,663 @@
+/****************************************************************************/
+/* RSC IDENTIFIER:  Ellipsoid
+ *
+* ABSTRACT
+ *
+ *    The purpose of ELLIPSOID is to provide access to ellipsoid parameters 
+ *    for a collection of common ellipsoids.  A particular ellipsoid can be 
+ *    accessed by using its standard 2-letter code to find its index in the 
+ *    ellipsoid table.  The index can then be used to retrieve the ellipsoid 
+ *    name and parameters.
+ *
+ *    By sequentially retrieving all of the ellipsoid codes and/or names, a 
+ *    menu of the available ellipsoids can be constructed.  The index values 
+ *    resulting from selections from this menu can then be used to access the 
+ *    parameters of the selected ellipsoid.
+ *
+ *    This component depends on a data file named "ellips.dat", which contains
+ *    the ellipsoid parameter values.  A copy of this file must be located in 
+ *    the directory specified by the environment variable "ELLIPSOID_DATA", if 
+ *    defined, or else in the current directory, whenever a program containing 
+ *    this component is executed.
+ *
+ *    Additional ellipsoids can be added to this file, either manually or using 
+ *    the Create_Ellipsoid function.  However, if a large number of ellipsoids 
+ *    are added, the ellipsoid table array size in this component will have to 
+ *    be increased.
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *  ELLIPSE_NO_ERROR             : No errors occured in function
+ *  ELLIPSE_FILE_OPEN_ERROR      : Ellipsoid file opening error
+ *  ELLIPSE_INITIALIZE_ERROR     : Ellipsoid table can not initialize
+ *  ELLIPSE_TABLE_OVERFLOW_ERROR : Ellipsoid table overflow
+ *  ELLIPSE_NOT_INITIALIZED_ERROR: Ellipsoid table not initialized properly
+ *  ELLIPSE_INVALID_INDEX_ERROR  : Index is an invalid value
+ *  ELLIPSE_INVALID_CODE_ERROR   : Code was not found in table
+ *  ELLIPSE_A_ERROR              : Semi-major axis less than or equal to zero
+ *  ELLIPSE_B_ERROR              : Semi-minor axis less than or equal to zero
+ *  ELLIPSE_A_LESS_B_ERROR       : Semi-major axis less than semi-minor axis
+ *
+ * REUSE NOTES
+ *
+ *    Ellipsoid is intended for reuse by any application that requires Earth
+ *    approximating ellipsoids.
+ *     
+ * REFERENCES
+ *
+ *    Further information on Ellipsoid can be found in the Reuse Manual.
+ *
+ *    Ellipsoid originated from :  U.S. Army Topographic Engineering Center (USATEC)
+ *                                 Geospatial Information Division (GID)
+ *                                 7701 Telegraph Road
+ *                                 Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    Ellipsoid has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    Ellipsoid was tested and certified in the following environments
+ *
+ *    1. Solaris 2.5
+ *    2. Windows 95 
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    11-19-95          Original Code
+ *    17-Jan-97         Moved local constants out of public interface
+ *                      Improved efficiency in algorithms (GEOTRANS)
+ *    24-May-99         Added user-defined ellipsoids (GEOTRANS for JMTK)
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                               INCLUDES
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "ossimEllipse.h"
+
+/* 
+ *    ctype.h    - standard C character handling library
+ *    stdio.h    - standard C input/output library
+ *    stdlib.h   - standard C general utilities library
+ *    string.h   - standard C string handling library
+ *    ellipse.h  - prototype error checking and error codes
+ */
+
+
+/***************************************************************************/
+/*
+ *                             GLOBAL DATA STRUCTURES
+ */
+
+#define MAX_ELLIPSOIDS        32  /* Maximum number of ellipsoids in table */
+#define ELLIPSOID_CODE_LENGTH  3  /* Length of ellipsoid code (including null) */
+#define ELLIPSOID_NAME_LENGTH 30  /* Max length of ellipsoid name */
+#define ELLIPSOID_BUF         90
+#define FILENAME_LENGTH      128
+
+const char *WGS84_Ellipsoid_Code = "WE";
+const char *WGS72_Ellipsoid_Code = "WD";
+
+typedef struct Ellipsoid_Table_Row
+{
+  char Name[ELLIPSOID_NAME_LENGTH];
+  char Code[ELLIPSOID_CODE_LENGTH];
+  double A;
+  double B;
+  double Recp_F;
+} Ellipsoid_Row;
+
+#include "ossimEllipse.hpp" 
+
+static long WGS84_Index = 0;           /* Index of WGS84 in ellipsoid table */
+static long WGS72_Index = 0;           /* Index of WGS72 in ellipsoid table */
+static long Ellipsoid_Initialized = 0; /* Indicates successful initialization */
+
+/***************************************************************************/
+/*                              FUNCTIONS                                  */
+
+
+void Assign_Ellipsoid_Row (Ellipsoid_Row *destination, 
+                           const Ellipsoid_Row *source)
+{
+   /* Begin Assign_Ellipsoid_Row */
+   /*
+    *   destination  : The destination of the copy         (output)
+    *   source       : The source for the copy             (input)
+    *
+    * The function Assign_Ellipsoid_Row copies ellipsoid data.
+    */
+
+  strcpy(destination->Name, source->Name);
+  strcpy(destination->Code, source->Code);
+  destination->A = source->A;
+  destination->B = source->B;
+  destination->Recp_F = source->Recp_F;
+} /* End Assign_Ellipsoid_Row */
+
+
+long Initialize_Ellipsoids () 
+{
+   /* Begin Initialize_Ellipsoids */
+   /*
+    * The function Initialize_Ellipsoids reads ellipsoid data from ellips.dat
+    * in the current directory and builds the ellipsoid table from it.  If an 
+    * error occurs, the error code is returned, otherwise ELLIPSE_NO_ERROR is 
+    * returned.
+    */
+  long error_code = ELLIPSE_NO_ERROR;
+
+  if (error_code)
+  {
+    Ellipsoid_Initialized = 0;
+    Number_of_Ellipsoids = 0;
+  }
+  else
+    Ellipsoid_Initialized = 1;
+
+  /* Store WGS84 Index*/
+  if (Ellipsoid_Index(WGS84_Ellipsoid_Code, &WGS84_Index))
+    error_code |= ELLIPSE_INITIALIZE_ERROR;
+
+  /* Store WGS72 Index*/
+  if (Ellipsoid_Index(WGS72_Ellipsoid_Code, &WGS72_Index))
+    error_code |= ELLIPSE_INITIALIZE_ERROR;
+
+  return (error_code);
+} /* End of Initialize_Ellipsoids */
+
+
+long Create_Ellipsoid (const char* Code,
+                       const char* Name,
+                       double A,
+                       double B)
+{ /* Begin Create_Ellipsoid */
+/*
+ *   Code     : 2-letter ellipsoid code.                      (input)
+ *   Name     : Name of the new ellipsoid                     (input)
+ *   A        : Semi-major axis, in meters, of new ellipsoid  (input)
+ *   B        : Semi-minor axis, in meters, of new ellipsoid. (input)
+ *
+ * The function Create_Ellipsoid creates a new ellipsoid with the specified
+ * Code, name, and axes.  If the ellipsoid table has not been initialized,
+ * the specified code is already in use, or a new version of the ellips.dat 
+ * file cannot be created, an error code is returned, otherwise ELLIPSE_NO_ERROR 
+ * is returned.  Note that the indexes of all ellipsoids in the ellipsoid
+ * table may be changed by this function.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+  long index = 0;
+  char *PathName;
+  char FileName[FILENAME_LENGTH];
+  FILE *fp = NULL;                    /* File pointer to file ellips.dat     */
+
+  if (!Ellipsoid_Initialized)
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  else if (!(Number_of_Ellipsoids < MAX_ELLIPSOIDS))
+    error_code |= ELLIPSE_TABLE_OVERFLOW_ERROR;
+  else
+  {
+    if (!Ellipsoid_Index(Code, &index))
+      error_code |= ELLIPSE_INVALID_CODE_ERROR;
+    if (A <= 0.0)
+      error_code |= ELLIPSE_A_ERROR;
+    if (B <= 0.0)
+      error_code |= ELLIPSE_B_ERROR;
+    if (A < B)
+      error_code |= ELLIPSE_A_LESS_B_ERROR;
+    if (!error_code)
+    {
+      index = Number_of_Ellipsoids;
+      strcpy(Ellipsoid_Table[index].Name, Name);
+      strcpy(Ellipsoid_Table[index].Code, Code);
+      Ellipsoid_Table[index].A = A;
+      Ellipsoid_Table[index].B = B;
+      Ellipsoid_Table[index].Recp_F = A / (A - B);
+      Number_of_Ellipsoids++;
+
+      /*output updated ellipsoid table*/
+      PathName = getenv( "ELLIPSOID_DATA" );
+      if (PathName != NULL)
+      {
+        strcpy( FileName, PathName );
+        strcat( FileName, "/" );
+      }
+      else
+      {
+        strcpy( FileName, "./" );
+      }
+      strcat( FileName, "ellips.dat" );
+
+      if ((fp = fopen(FileName, "w")) == NULL)
+      { /* fatal error */
+        return ELLIPSE_FILE_OPEN_ERROR;
+      }
+
+      /* write file */
+      index = 0;
+      while (index < Number_of_Ellipsoids)
+      {
+        fprintf(fp, "%-29s %-2s %11.3f %12.4f %13.9f \n",
+                Ellipsoid_Table[index].Name,
+                Ellipsoid_Table[index].Code,
+                Ellipsoid_Table[index].A,
+                Ellipsoid_Table[index].B,
+                Ellipsoid_Table[index].Recp_F);
+        index++;
+      }
+      fclose(fp);
+
+      /* Store WGS84 */
+      Ellipsoid_Index(WGS84_Ellipsoid_Code, &WGS84_Index);
+
+      /* Store WGS72 */
+      Ellipsoid_Index(WGS72_Ellipsoid_Code, &WGS72_Index);
+    }
+  }
+  return (error_code);
+} /* End Create_Ellipsoid */
+
+
+long Ellipsoid_Count ( long *Count )
+{ /* Begin Ellipsoid_Count */
+/*
+ *   Count    : The number of ellipsoids in the ellipsoid table. (output)
+ *
+ * The function Ellipsoid_Count returns the number of ellipsoids in the
+ * ellipsoid table.  If the ellipsoid table has been initialized without error,
+ * ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_NOT_INITIALIZED_ERROR
+ * is returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+
+  if (!Ellipsoid_Initialized)
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  *Count = Number_of_Ellipsoids;
+  return (error_code);
+} /* End Ellipsoid_Count */
+
+
+long Ellipsoid_Index ( const char *Code,
+                       long *Index )
+{ /* Begin Ellipsoid_Index */
+/*
+ *    Code     : 2-letter ellipsoid code.                      (input)
+ *    Index    : Index of the ellipsoid in the ellipsoid table with the 
+ *                  specified code                             (output)
+ *
+ *  The function Ellipsoid_Index returns the index of the ellipsoid in 
+ *  the ellipsoid table with the specified code.  If ellipsoid_Code is found, 
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_CODE_ERROR is 
+ *  returned.
+ */
+
+  char temp_code[3];
+  long error_code = ELLIPSE_NO_ERROR;
+  long i = 0;                   /* index for ellipsoid table */
+  long j = 0;
+
+  *Index = 0;
+  if (Ellipsoid_Initialized)
+  {
+    while (j < ELLIPSOID_CODE_LENGTH)
+    {
+      temp_code[j] = toupper(Code[j]);
+      j++;
+    }
+    temp_code[ELLIPSOID_CODE_LENGTH - 1] = 0;
+    while ((i < Number_of_Ellipsoids)
+           && strcmp(temp_code, Ellipsoid_Table[i].Code))
+    {
+      i++;
+    }
+    if (strcmp(temp_code, Ellipsoid_Table[i].Code))
+      error_code |= ELLIPSE_INVALID_CODE_ERROR;
+    else
+      *Index = i+1;
+  }
+  else
+  {
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  }
+  return (error_code);
+} /* End Ellipsoid_Index */
+
+
+long Ellipsoid_Name ( const long Index,
+                      char *Name ) 
+{ /* Begin Ellipsoid_Name */
+/*
+ *    Index   : Index of a given ellipsoid.in the ellipsoid table with the
+ *                 specified index                             (input)
+ *    Name    : Name of the ellipsoid referencd by index       (output)
+ *
+ *  The Function Ellipsoid_Name returns the name of the ellipsoid in 
+ *  the ellipsoid table with the specified index.  If index is valid, 
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_INDEX_ERROR is
+ *  returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+
+  strcpy(Name,"");
+  if (Ellipsoid_Initialized)
+  {
+    if ((Index < 1) || (Index > Number_of_Ellipsoids))
+      error_code |= ELLIPSE_INVALID_INDEX_ERROR;
+    else
+      strcpy(Name, Ellipsoid_Table[Index-1].Name);
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End Ellipsoid_Name */
+
+
+long Ellipsoid_Code ( const long Index,
+                      char *Code ) 
+{ /* Begin Ellipsoid_Code */
+/*
+ *    Index    : Index of a given ellipsoid in the ellipsoid table (input)
+ *    Code     : 2-letter ellipsoid code.                          (output)
+ *
+ *  The Function Ellipsoid_Code returns the 2-letter code for the 
+ *  ellipsoid in the ellipsoid table with the specified index.  If index is 
+ *  valid, ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_INDEX_ERROR 
+ *  is returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+
+  strcpy(Code,"");
+  if (Ellipsoid_Initialized)
+  {
+    if ((Index < 1) || (Index > Number_of_Ellipsoids))
+      error_code |= ELLIPSE_INVALID_INDEX_ERROR;
+    else
+      strcpy(Code, Ellipsoid_Table[Index-1].Code);
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End Ellipsoid_Name */
+
+
+long Ellipsoid_Axes ( const long Index,
+                      double *A,
+                      double *B )
+{ /* Begin Ellipsoid_Axes */
+/*
+ *    Index    : Index of a given ellipsoid in the ellipsoid table (input)
+ *    a        : Semi-major axis, in meters, of ellipsoid          (output)
+ *    B        : Semi-minor axis, in meters, of ellipsoid.         (output)
+ *
+ *  The function Ellipsoid_Axes returns the semi-major and semi-minor axes
+ *  for the ellipsoid with the specified index.  If index is valid,
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_INDEX_ERROR is 
+ *  returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+
+  *A = 0;
+  *B = 0;
+  if (Ellipsoid_Initialized)
+  {
+    if ((Index < 1) || (Index > Number_of_Ellipsoids))
+    {
+      error_code |= ELLIPSE_INVALID_INDEX_ERROR;
+    }
+    else
+    {
+      *A = Ellipsoid_Table[Index-1].A;
+      *B = Ellipsoid_Table[Index-1].B;
+    }
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End Ellipsoid_Axes */
+
+
+long Ellipsoid_Eccentricity2 ( const long Index,
+                               double *e2 )
+{ /* Begin Ellipsoid_Eccentricity2 */
+/*
+ *    Index    : Index of a given ellipsoid in the ellipsoid table (input)
+ *    e2       : Square of eccentricity of ellipsoid               (output)
+ *
+ *  The function Ellipsoid_Eccentricity2 returns the square of the 
+ *  eccentricity for the ellipsoid with the specified index.  If index is 
+ *  valid, ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_INDEX_ERROR 
+ *  is returned.
+ */
+  double a2,b2;
+  long error_code = ELLIPSE_NO_ERROR;
+
+  *e2 = 0;
+  if (Ellipsoid_Initialized)
+  {
+    if ((Index < 1) || (Index > Number_of_Ellipsoids))
+    {
+      error_code |= ELLIPSE_INVALID_INDEX_ERROR;
+    }
+    else
+    {
+      a2 = Ellipsoid_Table[Index-1].A * Ellipsoid_Table[Index-1].A;
+      b2 = Ellipsoid_Table[Index-1].B * Ellipsoid_Table[Index-1].B;
+      *e2 = (a2 - b2) / a2;
+    }
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End Ellipsoid_Eccentricity2 */
+
+
+long Ellipsoid_Flattening ( const long Index,
+                            double *f )
+{ /* Begin Ellipsoid_Flattening */
+/*
+ *    Index    : Index of a given ellipsoid in the ellipsoid table (input)
+ *    f        : Flattening of ellipsoid.                          (output)
+ *
+ *  The function Ellipsoid_Flattening returns the flattening of the 
+ *  ellipsoid with the specified index.  If index is valid ELLIPSE_NO_ERROR is 
+ *  returned, otherwise ELLIPSE_INVALID_INDEX_ERROR is returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+
+  *f = 0;
+  if (Ellipsoid_Initialized)
+  {
+    if ((Index < 1) || (Index > Number_of_Ellipsoids))
+      error_code |= ELLIPSE_INVALID_INDEX_ERROR;
+    else
+      *f = 1 / Ellipsoid_Table[Index-1].Recp_F;
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End Ellipsoid_Flattening */
+
+
+long WGS84_Axes ( double *A,
+                  double *B)
+{ /* Begin WGS84_Axes */
+/*
+ *    A      : Semi-major axis, in meters, of ellipsoid       (output)
+ *    B      : Semi-minor axis, in meters, of ellipsoid       (output)
+ *
+ *  The function WGS84_Axes returns the lengths of the semi-major and 
+ *  semi-minor axes for the WGS84 ellipsoid.  If the ellipsoid table was 
+ *  initialized successfully, ELLIPSE_NO_ERROR is returned, otherwise 
+ *  ELLIPSE_NOT_INITIALIZED_ERROR is returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+
+  *A = 0;
+  *B = 0;
+  if (Ellipsoid_Initialized)
+  {
+    *A = Ellipsoid_Table[WGS84_Index-1].A;
+    *B = Ellipsoid_Table[WGS84_Index-1].B;
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End WGS84_Axes */
+
+
+long WGS84_Eccentricity2 ( double *e2 )
+{ /* Begin WGS84_Eccentricity2 */
+/*
+ *    e2    : Square of eccentricity of WGS84 ellipsoid      (output)
+ *
+ *  The function WGS84_Eccentricity2 returns the square of the 
+ *  eccentricity for the WGS84 ellipsoid.  If the ellipsoid table was 
+ *  initialized successfully, ELLIPSE_NO_ERROR is returned, otherwise 
+ *  ELLIPSE_NOT_INITIALIZED_ERROR is returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+  double a2, b2;
+
+  *e2 = 0;
+  if (Ellipsoid_Initialized)
+  {
+    a2 = Ellipsoid_Table[WGS84_Index-1].A * Ellipsoid_Table[WGS84_Index-1].A;
+    b2 = Ellipsoid_Table[WGS84_Index-1].B * Ellipsoid_Table[WGS84_Index-1].B;
+    *e2 = (a2 - b2) / a2;
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End WGS84_Eccentricity2 */
+
+
+long WGS84_Flattening ( double *f )
+{ /* Begin WGS84_Flattening */
+/*
+ *  f       : Flattening of WGS84 ellipsoid.                 (output)
+ *
+ *  The function WGS84_Flattening returns the flattening of the WGS84
+ *  ellipsoid.  If the ellipsoid table was initialized successfully, 
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_NOT_INITIALIZED_ERROR 
+ *  is returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+
+  *f = 0;
+  if (Ellipsoid_Initialized)
+  {
+    *f = 1 / Ellipsoid_Table[WGS84_Index-1].Recp_F;
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End WGS84_Flattening */
+
+
+long WGS72_Axes( double *A,
+                 double *B)
+{ /* Begin WGS72_Axes */
+/*
+ *    A    : Semi-major axis, in meters, of ellipsoid        (output)
+ *    B    : Semi-minor axis, in meters, of ellipsoid        (output)
+ *
+ *  The function WGS72_Axes returns the lengths of the semi-major and 
+ *  semi-minor axes for the WGS72 ellipsoid.  If the ellipsoid table was 
+ *  initialized successfully, ELLIPSE_NO_ERROR is returned, otherwise 
+ *  ELLIPSE_NOT_INITIALIZED_ERROR is returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+
+  *A = 0;
+  *B = 0;
+  if (Ellipsoid_Initialized)
+  {
+    *A = Ellipsoid_Table[WGS72_Index-1].A;
+    *B = Ellipsoid_Table[WGS72_Index-1].B;
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End WGS72_Axes */
+
+
+long WGS72_Eccentricity2 ( double *e2 )
+{ /* Begin WGS72_Eccentricity2 */
+/*
+ *    e2     : Square of eccentricity of WGS84 ellipsoid     (output)
+ *
+ *  The function WGS72_Eccentricity2 returns the square of the 
+ *  eccentricity for the WGS72 ellipsoid.  If the ellipsoid table was 
+ *  initialized successfully, ELLIPSE_NO_ERROR is returned, otherwise 
+ *  ELLIPSE_NOT_INITIALIZED_ERROR is returned.
+ */
+
+  long error_code = ELLIPSE_NO_ERROR;
+  double a2, b2;
+
+  *e2 = 0;
+  if (Ellipsoid_Initialized)
+  {
+    a2 = Ellipsoid_Table[WGS72_Index-1].A * Ellipsoid_Table[WGS72_Index-1].A;
+    b2 = Ellipsoid_Table[WGS72_Index-1].B * Ellipsoid_Table[WGS72_Index-1].B;
+    *e2 = (a2 - b2) / a2;
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End WGS72_Eccentricity2 */
+
+
+long WGS72_Flattening (double *f )
+{ /* Begin WGS72_Flattening */
+/*
+ *    f      : Flattening of WGS72 ellipsoid.                (output)
+ *
+ *  The function WGS72_Flattening returns the flattening of the WGS72
+ *  ellipsoid .  If the ellipsoid table was initialized successfully, 
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_NOT_INITIALIZED_ERROR 
+ *  is returned.
+ */
+  long error_code = ELLIPSE_NO_ERROR;
+
+  *f = 0;
+  if (Ellipsoid_Initialized)
+  {
+    *f = 1 / Ellipsoid_Table[WGS72_Index-1].Recp_F;
+  }
+  else
+    error_code |= ELLIPSE_NOT_INITIALIZED_ERROR;
+  return (error_code);
+} /* End WGS72_Flattening */
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.h b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.h
new file mode 100644
index 0000000000..c68e42175b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.h
@@ -0,0 +1,308 @@
+#ifndef ELLIPSE_H
+#define ELLIPSE_H
+
+/****************************************************************************/
+/* RSC IDENTIFIER:  Ellipsoid
+ *
+ * ABSTRACT
+ *
+ *    The purpose of ELLIPSOID is to provide access to ellipsoid parameters 
+ *    for a collection of common ellipsoids.  A particular ellipsoid can be 
+ *    accessed by using its standard 2-letter code to find its index in the 
+ *    ellipsoid table.  The index can then be used to retrieve the ellipsoid 
+ *    name and parameters.
+ *
+ *    By sequentially retrieving all of the ellipsoid codes and/or names, a 
+ *    menu of the available ellipsoids can be constructed.  The index values 
+ *    resulting from selections from this menu can then be used to access the 
+ *    parameters of the selected ellipsoid.
+ *
+ *    This component depends on a data file named "ellips.dat", which contains
+ *    the ellipsoid parameter values.  A copy of this file must be located in 
+ *    the directory specified by the environment variable "ELLIPSOID_DATA", if 
+ *    defined, or else in the current directory, whenever a program containing 
+ *    this component is executed.
+ *
+ *    Additional ellipsoids can be added to this file, either manually or using 
+ *    the Create_Ellipsoid function.  However, if a large number of ellipsoids 
+ *    are added, the ellipsoid table array size in this component will have to 
+ *    be increased.
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *  ELLIPSE_NO_ERROR             : No errors occured in function
+ *  ELLIPSE_FILE_OPEN_ERROR      : Ellipsoid file opening error
+ *  ELLIPSE_INITIALIZE_ERROR     : Ellipsoid database can not initialize
+ *  ELLIPSE_TABLE_OVERFLOW_ERROR : Ellipsoid table overflow
+ *  ELLIPSE_NOT_INITIALIZED_ERROR: Ellipsoid database not initialized properly
+ *  ELLIPSE_INVALID_INDEX_ERROR  : Index is an invalid value
+ *  ELLIPSE_INVALID_CODE_ERROR   : Code was not found in database
+ *  ELLIPSE_A_ERROR              : Semi-major axis less than or equal to zero
+ *  ELLIPSE_B_ERROR              : Semi-minor axis less than or equal to zero
+ *  ELLIPSE_A_LESS_B_ERROR       : Semi-major axis less than semi-minor axis
+ *
+ * REUSE NOTES
+ *
+ *    Ellipsoid is intended for reuse by any application that requires Earth
+ *    approximating ellipsoids.
+ *     
+ * REFERENCES
+ *
+ *    Further information on Ellipsoid can be found in the Reuse Manual.
+ *
+ *    Ellipsoid originated from :  U.S. Army Topographic Engineering Center (USATEC)
+ *                                 Geospatial Information Division (GID)
+ *                                 7701 Telegraph Road
+ *                                 Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    Ellipsoid has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    Ellipsoid was tested and certified in the following environments
+ *
+ *    1. Solaris 2.5
+ *    2. Windows 95 
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    11-19-95          Original Code
+ *    17-Jan-97         Moved local constants out of public interface
+ *                      Improved efficiency in algorithms (GEOTRANS)
+ *    24-May-99         Added user-defined ellipsoids (GEOTRANS for JMTK)
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                               GLOBALS
+ */
+
+#define ELLIPSE_NO_ERROR              0x0000
+#define ELLIPSE_FILE_OPEN_ERROR       0x0001
+#define ELLIPSE_INITIALIZE_ERROR      0x0002
+#define ELLIPSE_TABLE_OVERFLOW_ERROR  0x0004
+#define ELLIPSE_NOT_INITIALIZED_ERROR 0x0008
+#define ELLIPSE_INVALID_INDEX_ERROR   0x0010
+#define ELLIPSE_INVALID_CODE_ERROR    0x0020
+#define ELLIPSE_A_ERROR               0x0040
+#define ELLIPSE_B_ERROR               0x0080
+#define ELLIPSE_A_LESS_B_ERROR        0x0100
+
+/***************************************************************************/
+/*
+ *                          FUNCTION PROTOTYPES
+ *                             for ellipse.c
+ */
+
+/* ensure proper linkage to c++ programs */
+#ifdef __cplusplus 
+extern "C" {
+#endif
+
+  long Initialize_Ellipsoids ();
+/*
+ * The function Initialize_Ellipsoids reads ellipsoid data from ellips.dat in
+ * the current directory and builds the ellipsoid table from it.  If an error
+ * occurs, the error code is returned, otherwise ELLIPSE_NO_ERROR is returned.
+ */
+
+
+  long Create_Ellipsoid (const char* Code,
+                         const char* Name,
+                         double a,
+                         double b);
+/*
+ *   Code     : 2-letter ellipsoid code.                      (input)
+ *   Name     : Name of the new ellipsoid                     (input)
+ *   a        : Semi-major axis, in meters, of new ellipsoid  (input)
+ *   b        : Semi-minor axis, in meters, of new ellipsoid. (input)
+ *
+ * The function Create_Ellipsoid creates a new ellipsoid with the specified
+ * code, name, and axes.  If the ellipsoid table has not been initialized,
+ * the specified code is already in use, or a new version of the ellips.dat 
+ * file cannot be created, an error code is returned, otherwise ELLIPSE_NO_ERROR 
+ * is returned.  Note that the indexes of all ellipsoids in the ellipsoid
+ * table may be changed by this function.
+ */
+
+
+  long Ellipsoid_Count ( long *Count );
+/*
+ *   Count    : The number of ellipsoids in the ellipsoid table. (output)
+ *
+ * The function Ellipsoid_Count returns the number of ellipsoids in the
+ * ellipsoid table.  If the ellipsoid table has been initialized without error,
+ * ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_NOT_INITIALIZED_ERROR
+ * is returned.
+ */
+
+
+  long Ellipsoid_Index ( const char *Code,
+                         long *Index );
+/*
+ *    Code     : 2-letter ellipsoid code.                      (input)
+ *    Index    : Index of the ellipsoid in the ellipsoid table with the 
+ *                  specified code                             (output)
+ *
+ *  The function Ellipsoid_Index returns the index of the ellipsoid in 
+ *  the ellipsoid table with the specified code.  If ellipsoid_Code is found, 
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_CODE_ERROR is 
+ *  returned.
+ */
+
+
+  long Ellipsoid_Name ( const long Index, 
+                        char *Name );
+/*
+ *    Index   : Index of a given ellipsoid.in the ellipsoid table with the
+ *                 specified index                             (input)
+ *    Name    : Name of the ellipsoid referencd by index       (output)
+ *
+ *  The Function Ellipsoid_Name returns the name of the ellipsoid in 
+ *  the ellipsoid table with the specified index.  If index is valid, 
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_INDEX_ERROR is
+ *  returned.
+ */
+
+
+  long Ellipsoid_Code ( const long Index,
+                        char *Code );
+/*
+ *    Index    : Index of a given ellipsoid in the ellipsoid table (input)
+ *    Code     : 2-letter ellipsoid code.                          (output)
+ *
+ *  The Function Ellipsoid_Code returns the 2-letter code for the 
+ *  ellipsoid in the ellipsoid table with the specified index.  If index is 
+ *  valid, ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_INDEX_ERROR 
+ *  is returned.
+ */
+
+
+  long Ellipsoid_Axes ( const long Index,
+                        double *a,
+                        double *b );
+/*
+ *    Index    : Index of a given ellipsoid in the ellipsoid table (input)
+ *    a        : Semi-major axis, in meters, of ellipsoid          (output)
+ *    b        : Semi-minor axis, in meters, of ellipsoid.         (output)
+ *
+ *  The function Ellipsoid_Axes returns the semi-major and semi-minor axes
+ *  for the ellipsoid with the specified index.  If index is valid,
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_INDEX_ERROR is 
+ *  returned.
+ */
+
+
+  long Ellipsoid_Eccentricity2 ( const long Index,
+                                 double *e2 );
+/*
+ *    Index    : Index of a given ellipsoid in the ellipsoid table (input)
+ *    e2       : Square of eccentricity of ellipsoid               (output)
+ *
+ *  The function Ellipsoid_Eccentricity2 returns the square of the 
+ *  eccentricity for the ellipsoid with the specified index.  If index is 
+ *  valid, ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_INVALID_INDEX_ERROR 
+ *  is returned.
+ */
+
+
+  long Ellipsoid_Flattening ( const long Index,
+                              double *f );
+/*
+ *    Index    : Index of a given ellipsoid in the ellipsoid table (input)
+ *    f        : Flattening of ellipsoid.                          (output)
+ *
+ *  The function Ellipsoid_Flattening returns the flattening of the 
+ *  ellipsoid with the specified index.  If index is valid ELLIPSE_NO_ERROR is 
+ *  returned, otherwise ELLIPSE_INVALID_INDEX_ERROR is returned.
+ */
+
+
+  long WGS84_Axes ( double *a,
+                    double *b );
+/*
+ *    a      : Semi-major axis, in meters, of ellipsoid       (output)
+ *    b      : Semi-minor axis, in meters, of ellipsoid       (output)
+ *
+ *  The function WGS84_Axes returns the lengths of the semi-major and 
+ *  semi-minor axes for the WGS84 ellipsoid.  If the ellipsoid table was 
+ *  initialized successfully, ELLIPSE_NO_ERROR is returned, otherwise 
+ *  ELLIPSE_NOT_INITIALIZED_ERROR is returned.
+ */
+
+
+  long WGS84_Eccentricity2 ( double *e2 );
+/*
+ *    e2    : Square of eccentricity of WGS84 ellipsoid      (output)
+ *
+ *  The function WGS84_Eccentricity2 returns the square of the 
+ *  eccentricity for the WGS84 ellipsoid.  If the ellipsoid table was 
+ *  initialized successfully, ELLIPSE_NO_ERROR is returned, otherwise 
+ *  ELLIPSE_NOT_INITIALIZED_ERROR is returned.
+ */
+
+
+  long WGS84_Flattening ( double *f );
+/*
+ *  f       : Flattening of WGS84 ellipsoid.                 (output)
+ *
+ *  The function WGS84_Flattening returns the flattening of the WGS84
+ *  ellipsoid.  If the ellipsoid table was initialized successfully, 
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_NOT_INITIALIZED_ERROR 
+ *  is returned.
+ */
+
+  long WGS72_Axes( double *a,
+                   double *b);
+/*
+ *    a    : Semi-major axis, in meters, of ellipsoid        (output)
+ *    b    : Semi-minor axis, in meters, of ellipsoid        (output)
+ *
+ *  The function WGS72_Axes returns the lengths of the semi-major and 
+ *  semi-minor axes for the WGS72 ellipsoid.  If the ellipsoid table was 
+ *  initialized successfully, ELLIPSE_NO_ERROR is returned, otherwise 
+ *  ELLIPSE_NOT_INITIALIZED_ERROR is returned.
+ */
+
+  long WGS72_Eccentricity2 ( double *e2 );
+/*
+ *    e2     : Square of eccentricity of WGS84 ellipsoid     (output)
+ *
+ *  The function WGS72_Eccentricity2 returns the square of the 
+ *  eccentricity for the WGS72 ellipsoid.  If the ellipsoid table was 
+ *  initialized successfully, ELLIPSE_NO_ERROR is returned, otherwise 
+ *  ELLIPSE_NOT_INITIALIZED_ERROR is returned.
+ */
+
+  long WGS72_Flattening (double *f );
+/*
+ *    f      : Flattening of WGS72 ellipsoid.                (output)
+ *
+ *  The function WGS72_Flattening returns the flattening of the WGS72
+ *  ellipsoid .  If the ellipsoid table was initialized successfully, 
+ *  ELLIPSE_NO_ERROR is returned, otherwise ELLIPSE_NOT_INITIALIZED_ERROR 
+ *  is returned.
+ */
+
+#ifdef __cplusplus 
+}
+#endif
+
+#endif /* ELLIPSE_H */
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.hpp b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.hpp
new file mode 100644
index 0000000000..c65d9d8fb9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipse.hpp
@@ -0,0 +1,28 @@
+static Ellipsoid_Row Ellipsoid_Table [] =
+{
+   {"Airy", "AA", 6377563.396, 6356256.9090, 299.324964600},
+   {"Modified Airy","AM", 6377340.189, 6356034.4480, 299.324964600},
+   {"Australian National", "AN", 6378160.000, 6356774.7190, 298.250000000},
+   {"Bessel 1841", "BR", 6377397.155, 6356078.9630, 299.152812800},
+   {"Bessel 1841(Namibia)", "BN", 6377483.865, 6356165.3830, 299.152812800},
+   {"Clarke 1866", "CC", 6378206.400, 6356583.8000, 294.978698200},
+   {"Clarke 1880", "CD", 6378249.145, 6356514.8700, 293.465000000},
+   {"Everest", "EA", 6377276.345, 6356075.4130, 300.801700000},
+   {"Everest (E. Malasia, Brunei)", "EB", 6377298.556, 6356097.5500, 300.801700000},
+   {"Everest 1956 (India)", "EC", 6377301.243, 6356100.2280, 300.801700000},
+   {"Everest 1969 (West Malasia)", "ED", 6377295.664, 6356094.6680, 300.801700000},
+   {"Everest 1948(W.Mals. & Sing.)", "EE", 6377304.063, 6356103.0390, 300.801700000},
+   {"Everest (Pakistan)", "EF", 6377309.613, 6356109.5710, 300.801700000},
+   {"Mod. Fischer 1960(South Asia)", "FA", 6378155.000, 6356773.3200, 298.300000000},
+   {"GRS 80", "RF", 6378137.000, 6356752.3141, 298.257222101},
+   {"Helmert 1906", "HE", 6378200.000, 6356818.1700, 298.300000000},
+   {"Hough", "HO", 6378270.000, 6356794.3430, 297.000000000},
+   {"Indonesian 1974", "ID", 6378160.000, 6356774.5040, 298.247000000},
+   {"International", "IN", 6378388.000, 6356911.9460, 297.000000000},
+   {"Krassovsky","KA", 6378245.000, 6356863.0190, 298.300000000},
+   {"South American 1969", "SA", 6378160.000, 6356774.7190, 298.250000000},
+   {"WGS 72", "WD", 6378135.000, 6356750.5200, 298.260000000},
+   {"WGS 84", "WE", 6378137.000, 6356752.3142, 298.257223563}
+};
+
+static long Number_of_Ellipsoids = 23;
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipsoid.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipsoid.cpp
new file mode 100644
index 0000000000..eb6fb11608
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipsoid.cpp
@@ -0,0 +1,453 @@
+//*****************************************************************************
+// FILE: ossimEllipsoid.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimEllipsoid. The implementation is
+//   actually for an OBLATE SPHEROID (x.radius = y.radius) as Earth is
+//   considered.
+//
+// SOFTWARE HISTORY:
+//>
+//   06Aug2001  Garrett Potts, Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimEllipsoid.cpp,v 1.15 2005/05/12 14:52:52 gpotts Exp $
+
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+
+#include <base/data_types/ossimEcefRay.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/common/ossimKeywordNames.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include "base/common/ossimTrace.h"
+static ossimTrace traceExec  ("ossimEllipsoid:exec");
+static ossimTrace traceDebug ("ossimEllipsoid:debug");
+
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimEllipsoid #1 (COPY)
+//  
+//*****************************************************************************
+ossimEllipsoid::ossimEllipsoid(const ossimEllipsoid &ellipsoid)
+   :
+      theName(ellipsoid.theName),
+      theCode(ellipsoid.theCode),
+      theA(ellipsoid.theA),
+      theB(ellipsoid.theB),
+      theFlattening(ellipsoid.theFlattening),
+      theA_squared(ellipsoid.theA_squared),
+      theB_squared(ellipsoid.theB_squared),
+      theEccentricitySquared(ellipsoid.theEccentricitySquared)
+{
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimEllipsoid #2
+//  
+//*****************************************************************************
+ossimEllipsoid::ossimEllipsoid(const ossimString &name,
+                               const ossimString &code,
+                               const double &a,
+                               const double &b)
+   :
+      theName(name),
+      theCode(code),
+      theA(a),
+      theB(b),
+      theA_squared(a*a),
+      theB_squared(b*b)
+{
+   computeFlattening();
+   
+   theEccentricitySquared = 2*theFlattening - theFlattening*theFlattening;
+}
+
+ossimEllipsoid::ossimEllipsoid()
+{
+   const ossimEllipsoid* ellipse = ossimEllipsoidFactory::instance()->wgs84();
+   
+   *this = *ellipse;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimEllipsoid #3
+//  
+//*****************************************************************************
+ossimEllipsoid::ossimEllipsoid(const double &a,
+                               const double &b)
+   :
+      theName(""), // initialize to empty
+      theCode(""),
+      theA(a),
+      theB(b),
+      theA_squared(a*a),
+      theB_squared(b*b)
+{
+   computeFlattening();
+
+   theEccentricitySquared = 2*theFlattening - theFlattening*theFlattening;
+ }
+
+//*****************************************************************************
+//  METHOD: ossimEllipsoid::nearestIntersection
+//  
+//*****************************************************************************
+bool ossimEllipsoid::nearestIntersection(const ossimEcefRay &ray,
+                                         ossimEcefPoint& rtnPt) const
+{
+   return nearestIntersection(ray, 0.0, rtnPt);
+}
+
+//*****************************************************************************
+//  METHOD: ossimEllipsoid::nearestIntersection
+//  
+//   geographic objects that are derive this class will asssume that
+//   the reference datum is wgs84 and that the ray origin is a
+//   geocentric coordinate relative to the wgs84 datum.  Will return
+//   true if the object was intersected and false otherwise.
+//  
+//   The nearest intersection will use the ray sphere intersection
+//   found in most ray tracers.  We will take a Ray defined by the
+//   parametric equation:
+//  
+//     x = x0 + dxt
+//     y = y0 + dyt
+//     z = z0 + dzt
+//  
+//   and intersect this with the equation of a spheroid:
+//  
+//     x^2/theXRadius^2 + y^2/theYRadius^2 + z^2/theZRadius^2 = 1
+//  
+//  
+//   the intersection is achived by substituting the parametric line
+//   into the equation of the sphereroid.  By doing this you should
+//   get a quadratic in t and the equation should look like this:
+//  
+//    a*t^2 + b*t + c = 0
+//  
+//      let a = dx^2/theXRadius^2 + dy^2/theYRadius^2 + dz^2/theZRadius^2
+//      let b = 2*(x0*dx/theXRadius^2 +y0*dy/theYRadius^2 + z0*dz/theZRadius^2
+//      let c = x0^2/theXRadius^2 + y0^2/theYRadius^2 + z0^2/theZRadius^2 - 1
+//  
+//  
+//    Now solve the quadratic (-b +- sqrt(b^2 - 4ac) ) / 2a
+//  
+//    After solving for t, the parameter is applied to the ray to determine
+//    the 3D point position in X,Y,Z, passed back in rtnPt. The boolean
+//    "true" is returned if an intersection was found.
+//
+//*****************************************************************************
+bool ossimEllipsoid::nearestIntersection(const ossimEcefRay& ray,
+                                         const double&       offset,
+                                         ossimEcefPoint&     rtnPt) const
+{
+   static const char MODULE[] = "ossimEllipsoid::nearestIntersection";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << ", entering...\n";
+
+   
+   double A_squared = (theA + offset)*(theA + offset);
+   double B_squared = (theB + offset)*(theB + offset);
+
+//    double adjustedOffset = offset/theA;
+//    double bOverA = theB/theA;
+//    double A_squared = (1.0+adjustedOffset)*(1.0+adjustedOffset);
+//    double B_squared = ((bOverA+adjustedOffset)*(bOverA+adjustedOffset));//(theB + offset)*(theB + offset);
+   
+   //***
+   // get the origin and direction of ray:
+   //***
+   ossimEcefPoint  start = ray.origin();   
+   ossimEcefVector direction = ray.direction();
+//    start = ossimEcefPoint(start.x()/theA,
+//                           start.y()/theA,
+//                           start.z()/theA);
+   //***
+   // Solve the coefficents of the quadratic formula
+   //***
+   double a = ((direction.x() * direction.x())/A_squared) +
+              ((direction.y() * direction.y())/A_squared) +
+              ((direction.z() * direction.z())/B_squared);
+
+   double b = 2.0*( ((start.x()*direction.x())/A_squared) +
+                    ((start.y()*direction.y())/A_squared) +
+                    ((start.z()*direction.z())/B_squared) );
+
+   double c = ((start.x()*start.x())/A_squared) +
+              ((start.y()*start.y())/A_squared) +
+              ((start.z()*start.z())/B_squared) - 1.0;
+   
+   //***
+   // solve the quadratic
+   //***
+   double root = b*b - 4*a*c;
+   double t;
+   if(root < 0.0)
+   {
+      return false;
+   }
+   else
+   {
+      double squareRoot = sqrt(root);
+      double t1 = (-b + squareRoot ) / (2.0*a);
+      double t2 = (-b - squareRoot ) / (2.0*a);
+
+      //***
+      // sort t1 and t2 and take the nearest intersection if they
+      // are in front of the ray.
+      //***
+      if(t2 < t1)
+      {
+         double temp = t1;
+         t1 = t2;
+         t2 = temp;
+      }     
+
+       if(t1 > 0.0)
+          t = t1;
+       else
+          t = t2;
+//      t = t1;
+   }
+
+   //***
+   // Now apply solved t to ray to extrapolate correct distance to intersection
+   //***
+   bool rtnval = false;
+   if (t >= 0)
+   {
+      rtnval = true;
+      rtnPt  = ray.extend(t); 
+//       rtnPt  = ray.extend(t*theA); 
+   }
+      
+   return rtnval; 
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimEllipsoid::evaluate(ossimColumnVector3d)
+//  
+//  Returns neg number if inside, 0 if on, and pos number if outside of
+//  ellipsoid.
+//  
+//*****************************************************************************
+double ossimEllipsoid::evaluate(const ossimEcefPoint &location)const
+{
+   //***
+   // get the axis
+   //***
+   return (((location.x() * location.x())/theA_squared) +
+           ((location.y() * location.y())/theA_squared) +
+           ((location.z() * location.z())/theB_squared) - 1.0);   
+}
+ 
+//*****************************************************************************
+//  METHOD: ossimEllipsoid::gradient()  version A
+//  
+//  Returns vector normal to the ellipsoid at point specified.
+//  
+//*****************************************************************************
+void ossimEllipsoid::gradient(const ossimEcefPoint& location,
+                              ossimEcefVector&      result) const
+{
+   result.x() = (2.0*location.x())/theA_squared;
+   result.y() = (2.0*location.y())/theA_squared;
+   result.z() = (2.0*location.z())/theB_squared;
+}
+
+//*****************************************************************************
+//  METHOD: ossimEllipsoid::gradient()  version B
+//  
+//  Returns vector normal to the ellipsoid at point specified.
+//  
+//*****************************************************************************
+ossimEcefVector
+ossimEllipsoid::gradient(const ossimEcefPoint &location)const
+{
+   ossimEcefVector result;
+   gradient(location, result);
+   return result;
+}
+   
+   
+bool ossimEllipsoid::loadState(const ossimKeywordlist& kwl,
+                               const char* prefix)
+{
+   const char* code = kwl.find(prefix,
+                               ossimKeywordNames::ELLIPSE_CODE_KW);
+   bool foundCode = false;
+   if(code)
+   {
+      const ossimEllipsoid* ellipse = ossimEllipsoidFactory::instance()->create(ossimString(code));
+
+      if(ellipse)
+      {
+         foundCode = true;
+         *this = *ellipse;
+      }
+   }
+   if(!foundCode)
+   {     
+      const char* majorAxis = kwl.find(prefix,
+                                       ossimKeywordNames::MAJOR_AXIS_KW);
+      const char* minorAxis = kwl.find(prefix,
+                                       ossimKeywordNames::MAJOR_AXIS_KW);
+
+      theName = "";
+      theCode = "";
+      if(majorAxis && minorAxis)
+      {
+         theA = ossimString(majorAxis).toDouble();
+         theB = ossimString(minorAxis).toDouble();
+
+         computeFlattening();
+         theA_squared = theA*theA;
+         theB_squared = theB*theB;
+      }
+      else
+      {
+         const ossimEllipsoid* ellipse = ossimEllipsoidFactory::instance()->wgs84();
+         
+         *this = *ellipse;
+      }      
+   }
+
+   return true;
+}
+
+bool ossimEllipsoid::saveState(ossimKeywordlist& kwl,
+                               const char* prefix)const
+{
+   if(theCode != "")
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::ELLIPSE_CODE_KW,
+              theCode.c_str(),
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::ELLIPSE_NAME_KW,
+              theName.c_str(),
+              true);
+   }
+   kwl.add(prefix,
+           ossimKeywordNames::MAJOR_AXIS_KW,
+           theA,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::MINOR_AXIS_KW,
+           theB,
+           true);
+
+   return true;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimEllipsoid::geodeticRadius()
+//  
+//  Computes the "geodetic" radius for a given latitude in degrees
+//  
+//*****************************************************************************
+double ossimEllipsoid::geodeticRadius(const double& lat) const
+{
+   double sin_lat = sind(lat);
+   double sin2_lat = sin_lat*sin_lat;
+   
+   return (theA_squared/
+           sqrt(theA_squared - theA_squared*sin2_lat + theB_squared*sin2_lat));
+}
+
+void ossimEllipsoid::latLonHeightToXYZ(double lat, double lon, double height,
+                                       double &x, double &y, double &z)const
+{
+    double sin_latitude = sind(lat);
+    double cos_latitude = cosd(lat);
+    double N = theA / sqrt( 1.0 - theEccentricitySquared*sin_latitude*sin_latitude);
+    x = (N+height)*cos_latitude*cosd(lon);
+    y = (N+height)*cos_latitude*sind(lon);
+    z = (N*(1-theEccentricitySquared)+height)*sin_latitude;
+}
+
+void ossimEllipsoid::XYZToLatLonHeight(double x, double y, double z,
+                                       double& lat, double& lon, double& height)const
+{
+   double d = sqrt(x*x + y*y);
+
+   double phi2 = z / ((1 - theEccentricitySquared) * d);
+   double p = 1.0;
+   double phi1 = 0.0;
+   double N1 = 0.0;
+   double height1 = 0.0;
+   int iterIdx = 0;
+   const int MAX_ITER = 10;
+   if (fabs(phi2) > 1e-16 )
+   {
+      while ( (p > 1e-17) && (iterIdx < MAX_ITER))
+      {
+         phi1 = phi2;
+         N1 = theA / sqrt(1.0 - (theEccentricitySquared * pow(sin(phi1), 2.0)));
+         height1 = (d / cos(phi1) - N1);
+         phi2 = atan((z / d) * (1.0 + (theEccentricitySquared * N1 * sin(phi1)) / z));
+         p = fabs(phi2 - phi1);
+         ++iterIdx;
+         /* printf("phi: %e   phi2: %e   p: %e  \n", phi1, phi2, p); */
+      }                                                                                           
+   }                                                                                                   
+   else
+   {                                                                                              
+      phi1 = phi2;                                                                                
+      N1 = theA / sqrt(1.0 - (theEccentricitySquared * pow(sin(phi1), 2.0)));                    
+      height1 = (d / cos(phi1)) - N1;                                                             
+   }                                                                                                   
+
+   /* *Latitude = phi2 * 180/PI; */
+   /* *Longitude = atan2(Y, X) * 180/PI; */
+   lat = phi2*DEG_PER_RAD; 
+   lon = atan2(y, x)*DEG_PER_RAD;                                                                
+   height = height1; 
+
+#if 0
+    double p = sqrt(x*x + y*y);
+    double theta = atan(z*theA/ (p*theB));
+    double eDashSquared = (theA*theA - theB*theB)/
+                          (theB*theB);
+
+    double sin_theta = sin(theta);
+    double cos_theta = cos(theta);
+
+    lat = atan( (z + eDashSquared*theB*sin_theta*sin_theta*sin_theta) /
+                     (p - theEccentricitySquared*theA*cos_theta*cos_theta*cos_theta) );
+    lon = atan2(y,x);
+
+    double sin_latitude = sin(lat);
+    double N = theA / sqrt( 1.0 - theEccentricitySquared*sin_latitude*sin_latitude);
+
+    height = p/cos(lat) - N;
+    lat*=DEG_PER_RAD;
+    lon*=DEG_PER_RAD;
+#endif
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipsoid.h b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipsoid.h
new file mode 100644
index 0000000000..847a5602fb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ellipse/ossimEllipsoid.h
@@ -0,0 +1,159 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// This is the class declaration for ossimEllipsoid. Though valid for the
+// general class of geometric shape, this implementation contains additional
+// methods suited to the Earth ellipsoid.
+//
+//*******************************************************************
+//  $ID$
+
+#ifndef ossimEllipsoid_HEADER
+#define ossimEllipsoid_HEADER
+
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimColumnVector3d.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+class OSSIMDLLEXPORT ossimEcefRay;
+class OSSIMDLLEXPORT ossimEcefPoint;
+class OSSIMDLLEXPORT ossimEcefVector;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimEllipsoid
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimEllipsoid
+{
+public:
+
+   /*!
+    * CONSTRUCTORS...
+    */
+   ossimEllipsoid(const ossimEllipsoid &ellipsoid);
+   ossimEllipsoid(const ossimString &name,
+                  const ossimString &code,
+                  const double &major_axis,
+                  const double &minor_axis);
+   ossimEllipsoid(const double &major_axis,
+                  const double &minor_axis);
+   ossimEllipsoid();
+   
+   virtual ~ossimEllipsoid(){};
+
+   /*!
+    * ACCESS METHOD...
+    */
+   virtual const ossimString& name()const{return theName;}
+   virtual const ossimString& code()const{return theCode;}
+
+   virtual const double&    a()const{return theA;} // major axis
+   virtual const double&    b()const{return theB;} // minor axis
+
+   virtual const double& getA()const{return theA;}
+   virtual const double& getB()const{return theB;}
+   virtual const double& getFlattening()const{return theFlattening;}
+   
+   virtual void setA(double a){theA = a;computeFlattening();}
+   virtual void setB(double b){theB = b;computeFlattening();}
+   virtual void setAB(double a, double b){theA = a; theB = b; computeFlattening();}
+
+   virtual double eccentricitySquared() const
+   { return theEccentricitySquared; }
+   
+   virtual double flattening()const
+   { return theFlattening; }
+   
+   virtual double eccentricity()const
+   { return sqrt(theEccentricitySquared); }
+   
+   /*!
+    * METHOD: nearestIntersection()
+    * Returns the point of nearest intersection of the ray with the ellipsoid.
+    * The first version performs the intersection at the ellipsoid surface.
+    * The second version computes the ray's intersection with a surface at
+    * some offset outside (for positive offset) of the ellipsoid (think
+    * elevation).
+    */
+   virtual bool nearestIntersection(const ossimEcefRay&  ray,
+                                    ossimEcefPoint& rtnPt) const;
+   virtual bool nearestIntersection(const ossimEcefRay&  ray,
+                                    const double&        offset,
+                                    ossimEcefPoint& rtnPt) const;
+
+   /*!
+    * METHOD: evaluate()
+    * evaluate will evalate the function at location x, y, z (ECEF).
+    */
+   virtual double   evaluate(const ossimEcefPoint&)const;
+
+   /*!
+    * METHOD: gradient()
+    * Compute the partials along location x, y, and z and place
+    * the result in the result vector.
+    */
+   virtual void gradient(const ossimEcefPoint& location,
+                         ossimEcefVector& result)const;
+   virtual ossimEcefVector gradient(const ossimEcefPoint& loc)const;
+
+   /*!
+    * Computes the "geodetic" radius for a given latitude in DEGREES:
+    */
+   double geodeticRadius(const double& latitude) const;
+
+   void latLonHeightToXYZ(double lat, double lon, double height,
+                          double &x, double &y, double &z)const;
+
+   void XYZToLatLonHeight(double x, double y, double z,
+                          double& lat, double& lon, double& height)const;
+   
+   virtual bool operator ==(const ossimEllipsoid& rhs)const
+      {
+         return ( (theName == rhs.theName)&&
+                  (theCode == rhs.theCode)&&
+                  (theB    == rhs.theB)&&
+                  (theFlattening == rhs.theFlattening));
+      }
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+protected:
+   virtual void computeFlattening()
+      {
+         theFlattening = (theA - theB)/theA;
+      }
+   
+   ossimString theName;
+   ossimString theCode;
+   double    theA;           //semi-major axis in meters
+   double    theB;           //semi-minor axis in meters
+   double    theFlattening;
+   double    theA_squared;
+   double    theB_squared;
+   double    theEccentricitySquared;
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/.cvsignore b/Utilities/OSSIM/ossim_core/base/data_types/geoid/.cvsignore
new file mode 100644
index 0000000000..fa9d7a6f91
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+ww15mgh.grd
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoid.cpp b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoid.cpp
new file mode 100644
index 0000000000..94c09d70d4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoid.cpp
@@ -0,0 +1,42 @@
+//*****************************************************************************
+// FILE: ossimGeoid.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimGeoid
+//
+// SOFTWARE HISTORY:
+//>
+//   17Apr2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+
+#include "ossimGeoid.h"
+
+RTTI_DEF2(ossimGeoid, "ossimGeoid", ossimObject, ossimErrorStatusInterface)
+
+ossimGeoid::ossimGeoid()
+   :
+      ossimObject(),
+      ossimErrorStatusInterface()
+{}
+
+ossimGeoid::~ossimGeoid()
+{}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoid.h b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoid.h
new file mode 100644
index 0000000000..37c9f62628
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoid.h
@@ -0,0 +1,61 @@
+//*****************************************************************************
+// FILE: ossimGeoid.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimGeoid. Maintains a grid of elevation
+//   offsets for the geoid (mean sea level) relative to WGS-84 ellipsoid.
+//
+// SOFTWARE HISTORY:
+//>
+//   17Apr2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+
+#ifndef ossimGeoid_HEADER
+#define ossimGeoid_HEADER
+
+#include "base/common/ossimObject.h"
+#include "base/common/ossimErrorStatusInterface.h"
+
+class OSSIMDLLEXPORT ossimGpt;
+class OSSIMDLLEXPORT ossimFilename;
+
+class OSSIMDLLEXPORT ossimGeoid : public ossimObject,
+				  public ossimErrorStatusInterface
+{
+public:
+   ossimGeoid();
+   ossimGeoid(const ossimFilename& dir);
+   virtual ~ossimGeoid();
+
+   virtual bool open(const ossimFilename& dir, ossimByteOrder byteOrder=OSSIM_LITTLE_ENDIAN) = 0;
+
+   /*!
+    *  Returns the offset from the ellipsoid to the geoid.
+    *  Returns OSSIM_DBL_NAN if grid does not contain the point.
+    */
+   virtual double offsetFromEllipsoid(const ossimGpt& gpt) const = 0;
+
+protected:
+   
+   TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidEgm96.cpp b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidEgm96.cpp
new file mode 100644
index 0000000000..0484f8a88f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidEgm96.cpp
@@ -0,0 +1,328 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+//*******************************************************************
+//  $Id: ossimGeoidEgm96.cpp,v 1.18 2005/11/10 14:15:33 gpotts Exp $
+
+#include <stdio.h>
+
+#include <base/data_types/geoid/ossimGeoidEgm96.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/misc/ossimEndian.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/factory/ossimDatumFactory.h>
+
+static ossimTrace traceDebug ("ossimGeoidEgm96:debug");
+
+
+#define NumbGeoidCols 1441   /* 360 degrees of longitude at 15 minute spacing */
+#define NumbGeoidRows  721   /* 180 degrees of latitude  at 15 minute spacing */
+#define NumbHeaderItems 6    /* min, max lat, min, max long, lat, long spacing*/
+#define ScaleFactor     4    /* 4 grid cells per degree at 15 minute spacing  */
+#define NumbGeoidElevs NumbGeoidCols * NumbGeoidRows
+// #define PI              3.14159265358979323e0
+
+
+RTTI_DEF1(ossimGeoidEgm96, "ossimGeoidEgm96", ossimGeoid)
+
+ossimGeoidEgm96::ossimGeoidEgm96()
+   :
+      theGeoidHeightBuffer(NULL)
+{}
+
+ossimGeoidEgm96::ossimGeoidEgm96(const ossimFilename& grid_file,
+                                 ossimByteOrder byteOrder)
+   :
+      theGeoidHeightBuffer(NULL)
+{
+   open(grid_file, byteOrder);
+   if (getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+      if (theGeoidHeightBuffer)
+      {
+         delete theGeoidHeightBuffer;
+         theGeoidHeightBuffer = NULL;
+      }
+   }
+}
+
+ossimGeoidEgm96::~ossimGeoidEgm96()
+{
+   if (theGeoidHeightBuffer) delete [] theGeoidHeightBuffer;
+}
+
+ossimString ossimGeoidEgm96::getShortName()const
+{
+   return "geoid1996";
+}
+
+bool ossimGeoidEgm96::open(const ossimFilename& grid_file, ossimByteOrder byteOrder)
+{
+   static const char MODULE[] = "ossimGeoidEgm96::open";
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " Entered...\n";
+   }
+
+   if (theGeoidHeightBuffer)
+   {
+      delete theGeoidHeightBuffer;
+   }
+
+   theGeoidHeightBuffer = new float[NumbGeoidElevs];
+   
+   int   ItemsRead = 0;
+   long  ElevationsRead = 0;
+   long  ItemsDiscarded = 0;
+   long  num = 0;
+
+   ossimFilename grid = grid_file;
+   if (grid_file.isDir())
+   {
+      grid = grid_file.dirCat("egm96.grd");
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " Grid file:" << grid << "\n";
+   }
+   
+   // Open the File READONLY, or Return Error Condition:
+   FILE* GeoidHeightFile;
+
+   if ( ( GeoidHeightFile = fopen( grid.c_str(), "rb" ) ) == NULL)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << MODULE << " could not open file "
+                                            << grid.c_str() << "\n";
+      }
+      setErrorStatus();
+      return false;
+   }
+  
+   // Skip the Header Line:
+   ossimEndian oe;
+   bool swap_bytes = (ossimGetByteOrder() != byteOrder) ? true : false;
+   while ( num < NumbHeaderItems )
+   {
+      if (feof( GeoidHeightFile )) break;
+      if (ferror( GeoidHeightFile )) break;
+      
+      float f;
+      ItemsRead = fread( &f, 4, 1, GeoidHeightFile );
+      if (swap_bytes) oe.swap(f);
+      theGeoidHeightBuffer[num] = f;
+      ItemsDiscarded += ItemsRead;
+      ++num;
+   }
+
+   // Determine if header read properly, or NOT:
+   if (theGeoidHeightBuffer[0] !=  -90.0 ||
+       theGeoidHeightBuffer[1] !=   90.0 ||
+       theGeoidHeightBuffer[2] !=    0.0 ||
+       theGeoidHeightBuffer[3] !=  360.0 ||
+       theGeoidHeightBuffer[4] !=  ( 1.0 / ScaleFactor ) ||
+       theGeoidHeightBuffer[5] !=  ( 1.0 / ScaleFactor ) ||
+       ItemsDiscarded != NumbHeaderItems)
+   {
+      
+      fclose(GeoidHeightFile);
+
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << MODULE << " bad header file "
+                                            << grid.c_str() << "\n";
+      }
+      setErrorStatus();
+      return false;
+  }
+
+   // Extract elements from the file:
+   num = 0;
+   while ( num < NumbGeoidElevs )
+   {
+      if (feof( GeoidHeightFile )) break;
+      if (ferror( GeoidHeightFile )) break;
+      
+      float f;
+      fread( &f, 4, 1, GeoidHeightFile );
+      if (swap_bytes) oe.swap(f);
+      theGeoidHeightBuffer[num] = f;
+      ++ElevationsRead;
+      ++num;
+   }
+
+   fclose(GeoidHeightFile);
+   
+   // Determine if all elevations of file read properly, or NOT:
+   if (ElevationsRead != NumbGeoidElevs)
+   {
+      setErrorStatus();
+      ossimSetError("ossimGeoidEgm96::open",
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "Bad grid file...%s", grid.c_str());
+     return false;
+  }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "Opened geoid grid:  " << grid.c_str() << endl;
+   }
+   
+   return true;
+}
+
+double ossimGeoidEgm96::offsetFromEllipsoid(const ossimGpt& gpt) const
+{
+   double offset = OSSIM_DBL_NAN;
+   ossimGpt savedGpt = gpt;
+   if(ossimDatumFactory::instance()->wgs84())
+   {
+      savedGpt.changeDatum(ossimDatumFactory::instance()->wgs84());
+   }
+   
+   if (!theGeoidHeightBuffer)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "ossimGeoidEgm96::offsetFromEllipsoid, "
+            << "Object not initialized!\n";
+      }
+
+      return offset;
+   }
+   
+   long    Index;
+   double DeltaX, DeltaY;
+   double ElevationSE, ElevationSW, ElevationNE, ElevationNW;
+   double LatitudeDD, LongitudeDD;
+   double OffsetX, OffsetY;
+   double PostX, PostY;
+   double UpperY, LowerY;
+
+   LatitudeDD  = savedGpt.latd();
+   
+   // Check for wrap.
+   if (LatitudeDD < -90.0)
+   {
+      LatitudeDD = -180.0 - LatitudeDD;
+   }
+   else if (LatitudeDD > 90.0)
+   {
+      LatitudeDD = 180.0 - LatitudeDD;
+   }
+
+   if ( (LatitudeDD < -90.0) || LatitudeDD > 90.0)
+   {
+      if(traceDebug())
+      {
+         // Latitude out of range
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATAL: " << "ossimGeoidEgm96::offsetFromEllipsoid, "
+            << "Point out of range:  " << savedGpt << "\n";
+      }
+      return offset;
+   }
+   
+   LongitudeDD = savedGpt.lond();
+
+   // Check for wrap.
+   if (LongitudeDD < -180)
+   {
+      LongitudeDD = LongitudeDD + 360.0;
+   }
+   else if (LongitudeDD > 180.0)
+   {
+      LongitudeDD = LongitudeDD - 360.0;
+   }
+
+   if ( (LongitudeDD < -180.0) || (LongitudeDD > 180.0) )
+   {
+      // Longitude out of range
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATAL: " << "ossimGeoidEgm96::offsetFromEllipsoid, "
+            << "Point out of range:  " << savedGpt << "\n";
+      }
+      return offset;
+   }
+   
+   // Compute X and Y Offsets into Geoid Height Array:
+   
+   if (LongitudeDD < 0.0)
+   {
+      OffsetX = ( LongitudeDD + 360.0 ) * ScaleFactor;
+   }
+   else
+   {
+      OffsetX = LongitudeDD * ScaleFactor;
+   }
+   OffsetY = ( 90.0 - LatitudeDD ) * ScaleFactor;
+   
+   //***
+   // Find Four Nearest Geoid Height Cells for specified Latitude,
+   // Longitude;  Assumes that (0,0) of Geoid Height Array is at
+   // Northwest corner:
+   //***
+   PostX = floor( OffsetX );
+   if ((PostX + 1) == NumbGeoidCols)
+      PostX--;
+   PostY = floor( OffsetY );
+   if ((PostY + 1) == NumbGeoidRows)
+      PostY--;
+   
+   Index = (long)(PostY * NumbGeoidCols + PostX);
+   ElevationNW = theGeoidHeightBuffer[ Index ];
+   ElevationNE = theGeoidHeightBuffer[ Index+ 1 ];
+   
+   Index = (long)((PostY + 1) * NumbGeoidCols + PostX);
+   ElevationSW = theGeoidHeightBuffer[ Index ];
+   ElevationSE = theGeoidHeightBuffer[ Index + 1 ];
+   
+   //Perform Bi-Linear Interpolation to compute Height above Ellipsoid:
+   DeltaX = OffsetX - PostX;
+   DeltaY = OffsetY - PostY;
+   
+   UpperY = ElevationNW + DeltaX * ( ElevationNE - ElevationNW );
+   LowerY = ElevationSW + DeltaX * ( ElevationSE - ElevationSW );
+   
+   offset = UpperY + DeltaY * ( LowerY - UpperY );
+   
+  return offset;
+}
+
+double ossimGeoidEgm96::geoidToEllipsoidHeight(double lat,
+                                               double lon,
+                                               double geoidHeight)
+{
+   ossimGpt gpt(lat, lon);
+   
+   double height = offsetFromEllipsoid(gpt);
+
+   return (height + geoidHeight);
+}
+
+double ossimGeoidEgm96::ellipsoidToGeoidHeight(double lat,
+                                               double lon,
+                                               double ellipsoidHeight)
+{
+   ossimGpt gpt(lat, lon);
+   
+   double height = offsetFromEllipsoid(gpt);
+
+   return ellipsoidHeight - height;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidEgm96.h b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidEgm96.h
new file mode 100644
index 0000000000..e54a31f09e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidEgm96.h
@@ -0,0 +1,78 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken  <dburken@imagelinks.com>
+//
+// Description:
+//
+// Contains class definition for ossimGeoidEgm96 which is
+// "Earth Gravity Model 1996".
+//
+//*******************************************************************
+//  $Id: ossimGeoidEgm96.h,v 1.5 2005/11/10 14:15:33 gpotts Exp $
+
+#ifndef ossimGeoidEgm96_HEADER
+#define ossimGeoidEgm96_HEADER
+
+#include "ossimGeoid.h"
+
+
+#define GEOID_NO_ERROR              0x0000
+#define GEOID_FILE_OPEN_ERROR       0x0001
+#define GEOID_INITIALIZE_ERROR      0x0002
+#define GEOID_NOT_INITIALIZED_ERROR 0x0004
+#define GEOID_LAT_ERROR             0x0008
+#define GEOID_LON_ERROR             0x0010
+
+class OSSIMDLLEXPORT ossimGpt;
+
+class OSSIMDLLEXPORT ossimGeoidEgm96 : public ossimGeoid
+{
+
+public:
+   ossimGeoidEgm96();
+   ossimGeoidEgm96(const ossimFilename& grid_file, ossimByteOrder byteOrder=OSSIM_BIG_ENDIAN);
+   
+   virtual ~ossimGeoidEgm96();
+
+   virtual bool open(const ossimFilename& grid_file, ossimByteOrder byteOrder=OSSIM_BIG_ENDIAN);
+
+   virtual ossimString getShortName()const;
+   
+   /*!
+    *  Returns the offset from the ellipsoid to the geoid.
+    *  Returns OSSIM_DBL_NAN if grid does not contain the point.
+    */
+   virtual double offsetFromEllipsoid(const ossimGpt& gpt) const;
+
+   double geoidToEllipsoidHeight(double lat,
+                           double lon,
+                           double geoidHeight);
+   
+   double ellipsoidToGeoidHeight(double lat,
+                           double lon,
+                           double ellipsoidHeight);
+
+protected:
+
+   float* theGeoidHeightBuffer;
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidManager.cpp b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidManager.cpp
new file mode 100644
index 0000000000..50c223b847
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidManager.cpp
@@ -0,0 +1,239 @@
+//*****************************************************************************
+// FILE: ossimGeoidManager.cpp
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class ossimGeoidManager
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimGeoidManager.cpp,v 1.8 2005/11/10 14:15:33 gpotts Exp $
+
+#include <base/data_types/geoid/ossimGeoidManager.h>
+RTTI_DEF1(ossimGeoidManager, "ossimGeoidManager", ossimGeoid);
+
+#include <base/data_types/geoid/ossimGeoidNgs.h>
+#include <base/data_types/geoid/ossimGeoidEgm96.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimKeyword.h>
+#include <base/context/ossimNotifyContext.h>
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimGeoidManager:exec");
+static ossimTrace traceDebug ("ossimGeoidManager:debug");
+
+ossimGeoidManager* ossimGeoidManager::theInstance = NULL;
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimGeoidManager
+//  
+//*****************************************************************************
+ossimGeoidManager::ossimGeoidManager()
+{
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimGeoidManager
+//  
+//*****************************************************************************
+ossimGeoidManager::~ossimGeoidManager()
+{
+//    vector<ossimGeoid*>::iterator g = theGeoidList.begin();
+//    while (g != theGeoidList.end())
+//    {
+//       delete *g;
+//       ++g;
+//    }
+   theGeoidList.clear();
+}
+
+//*****************************************************************************
+//  METHOD: ossimGeoidManager::instance()
+//  
+//*****************************************************************************
+ossimGeoidManager* ossimGeoidManager::instance()
+{
+   if (!theInstance)
+      theInstance = new ossimGeoidManager();
+   
+   return theInstance;
+}
+
+//*****************************************************************************
+//  METHOD: ossimElevManager::addGeoidSource
+//  
+//*****************************************************************************
+void ossimGeoidManager::addGeoid(ossimRefPtr<ossimGeoid> geoid)
+{
+   theGeoidList.push_back(geoid);
+}
+
+//*****************************************************************************
+//  METHOD: ossimGeoidManager::loadState()
+//  
+//*****************************************************************************
+bool ossimGeoidManager::loadState(const ossimKeywordlist& kwl,
+                                  const char* prefix)
+{
+   static const char MODULE[] = "ossimGeoidManager::loadState()";
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG: " << MODULE << ", entering...\n";
+
+   
+   // Look for the ngs geoid directories
+   const char* lookup = kwl.find(prefix, "geoid_99_directory");
+   ossimByteOrder geoidNgsByteOrder = OSSIM_LITTLE_ENDIAN;
+   const char* byteOrder = kwl.find(prefix, "geoid_99_directory.byte_order");
+   if (!lookup)
+   {
+      lookup = kwl.find(prefix, "geoid_ngs_directory");
+      byteOrder = kwl.find(prefix, "geoid_ngs_directory.byte_order");
+   }
+   if(byteOrder)
+   {
+      if(ossimString(byteOrder).contains("little"))
+      {
+         geoidNgsByteOrder = OSSIM_LITTLE_ENDIAN;
+      }
+      else
+      {
+         geoidNgsByteOrder = OSSIM_BIG_ENDIAN;
+      }
+   }
+   if(lookup)
+   {
+      ossimFilename f = lookup;
+      if (f.isDir())
+      {
+         ossimGeoid* geoid = new ossimGeoidNgs(f, geoidNgsByteOrder);
+
+         if (geoid->getErrorStatus() == ossimErrorCodes::OSSIM_OK)
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "DEBUG: " << MODULE
+                  << "\nAdded geoid dir:  " << f.c_str() << "\n";
+            }
+
+            addGeoid(geoid);
+         }
+         else
+         {
+            delete geoid;
+            geoid = NULL;
+         }
+      }
+   }
+   // Look for the geoid Earth Gravity Model (EGM) 96 directory.
+   lookup = kwl.find(prefix, "geoid_egm_96_grid");
+   if (lookup)
+   {
+      ossimFilename f = lookup;
+      if (f.isDir() || f.isFile())
+      {
+         ossimGeoid* geoid = new ossimGeoidEgm96(f);
+
+         if (geoid->getErrorStatus() == ossimErrorCodes::OSSIM_OK)
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "DEBUG: " << MODULE
+                  << "\nAdded geoid egm 96:  " << f.c_str()
+                  << "\n";
+            }
+
+            addGeoid(geoid);
+         }
+         else
+         {
+            delete geoid;
+            geoid = NULL;
+         }
+      }
+   }
+   
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG: " << MODULE << ", returning...\n";
+   }
+   
+   return true;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimGeoidManager::open()
+//  
+//*****************************************************************************
+bool ossimGeoidManager::open(const ossimFilename& dir, ossimByteOrder byteOrder)
+{
+   vector<ossimRefPtr<ossimGeoid> >::iterator g = theGeoidList.begin();
+   bool status = true;
+   while (g != theGeoidList.end())
+   {
+      status &= (*g)->open(dir, byteOrder);
+      ++g;
+   }
+
+   return status;
+}
+
+//*****************************************************************************
+//  METHOD: ossimGeoidManager::open()
+//  
+//*****************************************************************************
+double ossimGeoidManager::offsetFromEllipsoid(const ossimGpt& gpt) const
+{
+   double offset = OSSIM_DBL_NAN;
+   vector<ossimRefPtr<ossimGeoid> >::const_iterator geoid = theGeoidList.begin();
+   
+   while ((offset == OSSIM_DBL_NAN) && (geoid != theGeoidList.end()))
+   {
+      offset = ((*geoid))->offsetFromEllipsoid(gpt);
+      ++geoid;
+   }
+   
+   return offset;
+}
+
+const ossimRefPtr<ossimGeoid> ossimGeoidManager::findGeoidByShortName(const ossimString& shortName,
+                                                                      bool caseSensitive)const
+{
+   ossim_uint32 idx=0;
+   ossimString testString = shortName;
+   if(!caseSensitive)
+   {
+      testString  = testString.downcase();
+   }
+   for(idx = 0; idx < theGeoidList.size(); ++idx)
+   {
+      if(!caseSensitive)
+      {
+         if(theGeoidList[idx]->getShortName().downcase() == testString)
+         {
+            return theGeoidList[idx];
+         }
+      }
+      else
+      {
+         if(theGeoidList[idx]->getShortName() == testString)
+         {
+            return theGeoidList[idx];
+         }
+      }
+   }
+   return 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidManager.h b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidManager.h
new file mode 100644
index 0000000000..83fbdccb32
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidManager.h
@@ -0,0 +1,101 @@
+//*****************************************************************************
+// FILE: ossimGeoidManager.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains declaration of class ossimGeoidManager. Maintains
+//   a list of geoids.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimGeoidManager.h,v 1.7 2005/11/10 14:15:33 gpotts Exp $
+
+#ifndef ossimGeoidManager_HEADER
+#define ossimGeoidManager_HEADER
+
+#include <vector>
+#include <base/common/ossimRefPtr.h>
+#include "ossimGeoid.h"
+
+/*!****************************************************************************
+ *
+ * CLASS: ossimGeoidManager 
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimGeoidManager : public ossimGeoid
+{
+public:
+
+
+   virtual ~ossimGeoidManager();
+      
+   /*!
+    * Implements singelton pattern:
+    */
+   static ossimGeoidManager* instance();
+
+   
+   /*!
+    * Permits initialization of geoids from directory name. Should never be
+    * called since called on specific geoid types:
+    */
+   virtual bool open(const ossimFilename& dir, ossimByteOrder byteOrder);
+
+   /*!
+    *  Returns the offset from the ellipsoid to the geoid.
+    *  Returns OSSIM_DBL_NAN if grid does not contain the point.
+    */
+   virtual double offsetFromEllipsoid(const ossimGpt& gpt) const;
+
+   /*!
+    * Method to save the state of the object to a keyword list.
+    * Return true if ok or false on error. DO NOTHING
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const { return true; }
+
+   /*!
+    * Method to the load (recreate) the state of the object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /*!
+    * Permits adding additional geoids to the list: 
+    */
+   virtual void addGeoid(ossimRefPtr<ossimGeoid> geoid);
+
+   const ossimRefPtr<ossimGeoid> findGeoidByShortName(const ossimString& shortName,
+                                                      bool caseSensitive=true)const;
+private:
+   /*!
+    *  Private constructor.  Use "instance" method.
+    */
+   ossimGeoidManager();
+
+   static ossimGeoidManager* theInstance;
+   mutable std::vector< ossimRefPtr<ossimGeoid> > theGeoidList;
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgs.cpp b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgs.cpp
new file mode 100644
index 0000000000..928ceacc56
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgs.cpp
@@ -0,0 +1,272 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimGeoidNgs.cpp,v 1.3 2005/11/10 14:15:33 gpotts Exp $
+#include <base/data_types/geoid/ossimGeoidNgs.h>
+
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimTrace.h>
+#include <base/factory/ossimDatumFactory.h>
+
+
+#include <stdlib.h>  /* standard C general utility library */
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+RTTI_DEF1(ossimGeoidNgs, "ossimGeoidNgs", ossimGeoid)
+
+static ossimTrace traceDebug ("ossimGeoidNgs:debug");
+
+ossimGeoidNgs::ossimGeoidNgs()
+   :theShortName("")
+{
+}
+
+ossimGeoidNgs::ossimGeoidNgs(const ossimFilename& dir,
+                             ossimByteOrder byteOrder)
+{
+   open(dir);
+}
+
+
+bool ossimGeoidNgs::open(const ossimFilename& dir,
+                         ossimByteOrder byteOrder)
+{
+   if (!dir.isDir())
+   {
+      return false;
+   }
+
+   if(dir.isDir())
+   {
+      ossimGeoidNgsHeader h;
+
+      if(dir.dirCat("g2003u01.bin").exists())
+      {
+         theShortName = "geoid2003";
+         addFile(dir.dirCat("g2003u01.bin"), byteOrder);
+      }
+      if(dir.dirCat("g2003u02.bin").exists())
+      {
+         theShortName = "geoid2003";
+         addFile(dir.dirCat("g2003u02.bin"), byteOrder);
+      }
+      if(dir.dirCat("g2003u02.bin").exists())
+      {
+         theShortName = "geoid2003";
+         addFile(dir.dirCat("g2003u02.bin"), byteOrder);
+      }
+      if(dir.dirCat("g2003u02.bin").exists())
+      {
+         theShortName = "geoid2003";
+         addFile(dir.dirCat("g2003u02.bin"), byteOrder);
+      }
+      if(dir.dirCat("g2003u02.bin").exists())
+      {
+         theShortName = "geoid2003";
+         addFile(dir.dirCat("g2003u02.bin"), byteOrder);
+      }
+      if(dir.dirCat("g2003u02.bin").exists())
+      {
+         theShortName = "geoid2003";
+         addFile(dir.dirCat("g2003u02.bin"), byteOrder);
+      }
+
+      if(dir.dirCat("g1999u01.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999u01.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999u02.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999u02.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999u03.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999u03.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999u04.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999u04.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999u05.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999u05.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999u06.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999u06.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999u07.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999u07.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999u08.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999u08.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999a01.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999a01.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999a02.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999a02.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999a03.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999a03.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999a04.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999a04.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999h01.bin"))
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999h01.bin"), byteOrder);
+      }
+      if(dir.dirCat("g1999p01.bin").exists())
+      {
+         theShortName = "geoid1999";
+         addFile(dir.dirCat("g1999p01.bin"), byteOrder);
+      }
+   }
+   else
+   {
+      addFile(dir, byteOrder);
+   }
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "Opened geoid grids from:  " << dir.c_str() << endl;
+   }
+   
+   return true;
+}
+
+ossimGeoidNgs::~ossimGeoidNgs()
+{
+}
+
+
+bool ossimGeoidNgs::addFile(const ossimFilename& file, ossimByteOrder byteOrder)
+{
+   bool result = false;
+   if(file.exists())
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < theGridVector.size();++idx)
+      {
+         if(file == theGridVector[idx].filename())
+         {
+            result = true;
+            return result;
+         }
+      }
+      ossimGeoidNgsHeader h;
+      result = h.initialize(file, byteOrder);
+      if(result)
+      {
+         theGridVector.push_back(h);
+      }
+   }
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimGeoidNgs::addFile: Adding file = " << file << std::endl;
+   }
+   return result;
+}
+
+double ossimGeoidNgs::offsetFromEllipsoid(const ossimGpt& gpt) const
+{
+   ossimGpt savedGpt = gpt;
+   if(ossimDatumFactory::instance()->wgs84())
+   {
+      savedGpt.changeDatum(ossimDatumFactory::instance()->wgs84());
+   }
+   double lat = savedGpt.latd();
+   double lon = savedGpt.lond();
+   fixLatLon(lat, lon);
+   
+   return deltaHeight(lat, lon); 
+}
+
+double ossimGeoidNgs::geoidToEllipsoidHeight(double lat,
+                                             double lon,
+                                             double geoidHeight)
+{
+
+   fixLatLon(lat, lon);
+   double delta = deltaHeight(lat, lon);
+
+   return geoidHeight + delta;
+}
+
+double ossimGeoidNgs::ellipsoidToGeoidHeight(double lat,
+                                      double lon,
+                                      double ellipsoidHeight)
+{
+
+   fixLatLon(lat, lon);
+   double delta = deltaHeight(lat, lon);
+
+   return ellipsoidHeight - delta;
+}
+
+void ossimGeoidNgs::fixLatLon(double &lat, double &lon) const
+{
+   if(lat < 0)
+   {
+      lat += 180;
+   }
+   if(lon < 0)
+   {
+      lon += 360;
+   }
+}
+
+double ossimGeoidNgs::deltaHeight(double lat, double lon)const
+{
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theGridVector.size();++idx)
+   {
+      if( theGridVector[idx].pointWithin(lat, lon) )
+      {
+         return theGridVector[idx].getHeightDelta(lat,
+                                                  lon);
+      }
+   }
+
+   return OSSIM_DBL_NAN;
+}
+
+ossimString ossimGeoidNgs::getShortName()const
+{
+   return theShortName;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgs.h b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgs.h
new file mode 100644
index 0000000000..e4e3997e20
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgs.h
@@ -0,0 +1,70 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimGeoidNgs.h,v 1.3 2005/11/10 14:15:33 gpotts Exp $
+#ifndef ossimGeoidNgs_HEADER
+#define ossimGeoidNgs_HEADER
+
+#include "ossimGeoid.h"
+#include "ossimGeoidNgsHeader.h"
+
+class OSSIMDLLEXPORT ossimGeoidNgs : public ossimGeoid
+{
+
+public:
+   ossimGeoidNgs();
+   ossimGeoidNgs(const ossimFilename& dir,
+                 ossimByteOrder byteOrder = OSSIM_LITTLE_ENDIAN);
+   virtual ~ossimGeoidNgs();
+
+   virtual ossimString getShortName()const;
+   
+   virtual bool open(const ossimFilename& dir,
+                     ossimByteOrder byteOrder = OSSIM_LITTLE_ENDIAN);
+
+   virtual bool addFile(const ossimFilename& file,
+                        ossimByteOrder byteOrder = OSSIM_LITTLE_ENDIAN);
+   /*!
+    *  Returns the offset from the ellipsoid to the geoid.
+    *  Returns OSSIM_DBL_NAN if grid does not contain the point.
+    */
+   virtual double offsetFromEllipsoid(const ossimGpt&) const;
+   
+   double geoidToEllipsoidHeight(double lat,
+                           double lon,
+                           double geoidHeight);
+   
+   double ellipsoidToGeoidHeight(double lat,
+                                 double lon,
+                                 double ellipsoidHeight);
+protected:
+   void fixLatLon(double &lat, double &lon) const;
+   double deltaHeight(double lat, double lon)const;
+   
+   std::vector<ossimGeoidNgsHeader> theGridVector;
+   ossimString theShortName;
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgsHeader.cpp b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgsHeader.cpp
new file mode 100644
index 0000000000..ceb7ee6ba7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgsHeader.cpp
@@ -0,0 +1,173 @@
+#include "ossimGeoidNgsHeader.h"
+#include <fstream>
+#include <base/misc/ossimEndian.h>
+#include <cmath>
+#include <base/context/ossimNotifyContext.h>
+
+using namespace std;
+
+ostream& operator << (ostream &out, const ossimGeoidNgsHeader &data)
+{
+   out << "Filename:        " << data.theFilename             << endl
+       << "Southern lat:    " << data.theSouthernMostLatitude << endl
+       << "Western lon:     " << data.theWesternMostLongitude << endl
+       << "Lat spacing:     " << data.theLatDelta             << endl
+       << "Lon spacing:     " << data.theLonDelta             << endl
+       << "rows:            " << data.theRows                 << endl
+       << "cols:            " << data.theCols                 << endl
+       << "Datatype:        " << data.theDataType             << endl;
+
+   return out;
+}
+
+
+ossimGeoidNgsHeader::ossimGeoidNgsHeader()
+   :theFilename(""),
+    theByteOrder(OSSIM_LITTLE_ENDIAN),
+    theSouthernMostLatitude(0.0),
+    theWesternMostLongitude(0.0),
+    theLatDelta(0.0),
+    theLonDelta(0.0),
+    theRows(0),
+    theCols(0),
+    theDataType(0)
+{   
+}
+
+ossimGeoidNgsHeader::ossimGeoidNgsHeader(const ossimFilename &fileName,
+                                       ossimByteOrder byteOrder)
+{
+   initialize(fileName, byteOrder);
+}
+
+bool ossimGeoidNgsHeader::initialize(const ossimFilename &fileName,
+                                    ossimByteOrder byteOrder)
+{
+   ifstream input(fileName.c_str(), ios::in|ios::binary);
+   if(!input)
+   {
+//      cerr << MODULE << " Cannot open geoid file in " << fileName.c_str()
+//           << endl;
+       return false;
+   }
+
+   theByteOrder = byteOrder;
+   double latOrigin  = 0.0;
+   double lonOrigin  = 0.0;
+   double latSpacing = 0.0;
+   double lonSpacing = 0.0;
+   int    rows       = 0;
+   int    cols       = 0;
+   int    type       = 0;
+   
+   input.read((char*)&latOrigin, 8);
+   input.read((char*)&lonOrigin, 8);
+   input.read((char*)&latSpacing, 8);
+   input.read((char*)&lonSpacing, 8);
+   input.read((char*)&rows, 4);
+   input.read((char*)&cols, 4);
+   input.read((char*)&type, 4);
+
+   ossimEndian endian;
+
+   if(endian.getSystemEndianType() != byteOrder)
+   {
+      endian.swap(latOrigin);
+      endian.swap(lonOrigin);
+      endian.swap(latSpacing);
+      endian.swap(lonSpacing);
+      endian.swap(rows);
+      endian.swap(cols);
+      endian.swap(type);
+   }
+   
+   theFilename = fileName;
+   theSouthernMostLatitude = latOrigin;
+   theWesternMostLongitude = lonOrigin;
+   theLatDelta             = latSpacing;
+   theLonDelta             = lonSpacing;
+   theRows                 = rows;
+   theCols                 = cols;
+   theDataType             = type;
+
+   return ((theSouthernMostLatitude >= -FLT_EPSILON)&&
+           (theSouthernMostLatitude <= 90.0)&&
+           (theWesternMostLongitude >= -FLT_EPSILON)&&
+           (theWesternMostLongitude <= 360.0));
+}
+
+bool ossimGeoidNgsHeader::pointWithin(double lat, double lon)const
+{
+   return( (lat >= theSouthernMostLatitude) &&
+           (lat <= (theSouthernMostLatitude + theRows*theLatDelta)) &&
+           (lon >= theWesternMostLongitude) &&
+           (lon <= theWesternMostLongitude + theCols*theLonDelta));
+}
+
+double ossimGeoidNgsHeader::getHeightDelta(double lat,
+                                           double lon)const
+{
+   float result=0.0;
+
+   // note the headers go from 0 to 360 degrees starting at the prime meridian.
+   // ours goes from -180 to 180 degrees.  We will need to shift
+   //
+   if(lon < 0.0) lon += 360;
+   double latSpaces = (lat - theSouthernMostLatitude)/theLatDelta;
+   double lonSpaces = (lon - theWesternMostLongitude)/theLonDelta;
+
+   if(latSpaces < -FLT_EPSILON) return OSSIM_DBL_NAN;
+   if(lonSpaces < -FLT_EPSILON) return OSSIM_DBL_NAN;
+
+   long latSpace0 = (long)std::floor(latSpaces);
+   long latSpace1 = latSpace0 + 1;
+   long lonSpace0 = (long)std::floor(lonSpaces);
+   long lonSpace1 = lonSpace0 + 1;
+
+   ifstream input(filename().c_str(), ios::in|ios::binary);
+   if(!input)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: " << "ossimGeoid99::getGeoidHeight, " << "unable to open file: " << theFilename << "\n";
+      return 0;
+   }
+
+   long offset00 = (long)(headerSize() + (latSpace0*theCols + lonSpace0)*dataTypeSize());
+   long offset01 = (long)(headerSize() + (latSpace0*theCols + lonSpace1)*dataTypeSize());
+   long offset11 = (long)(headerSize() + (latSpace1*theCols + lonSpace1)*dataTypeSize());
+   long offset10 = (long)(headerSize() + (latSpace1*theCols + lonSpace0)*dataTypeSize());
+
+   double tLat = latSpaces - floor(latSpaces);
+   double tLon = lonSpaces - floor(lonSpaces);
+
+
+   float v00;
+   float v01;
+   float v11;
+   float v10;
+   
+   input.seekg(offset00,ios::beg);
+   input.read((char*)&v00, 4);
+   
+   input.seekg(offset01,ios::beg);
+   input.read((char*)&v01, 4);
+   
+   input.seekg(offset11,ios::beg);
+   input.read((char*)&v11, 4);
+
+   input.seekg(offset10,ios::beg);
+   input.read((char*)&v10, 4);
+   ossimEndian endian;
+   if(endian.getSystemEndianType() != theByteOrder)
+   {
+      endian.swap(v00);
+      endian.swap(v01);
+      endian.swap(v11);
+      endian.swap(v10);
+   }
+   double bottom = (v00 + (v01 - v00)*tLat);
+   double top    = (v10 + (v11 - v10)*tLat);
+   result        = bottom + (top - bottom)*tLon;
+
+   return result;
+   
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgsHeader.h b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgsHeader.h
new file mode 100644
index 0000000000..c6f9585253
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/geoid/ossimGeoidNgsHeader.h
@@ -0,0 +1,97 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimGeoidNgsHeader.h,v 1.2 2005/11/04 17:50:35 gpotts Exp $
+#ifndef ossimGeoidNgsHeader_HEADER
+#define ossimGeoidNgsHeader_HEADER
+#include "base/data_types/ossimFilename.h"
+
+#include <iostream>
+
+class OSSIMDLLEXPORT ossimGeoidNgsHeader
+{
+public:
+   friend std::ostream& operator << (std::ostream &out, const ossimGeoidNgsHeader &data);
+   
+   ossimGeoidNgsHeader();
+   ossimGeoidNgsHeader(const ossimFilename &fileName,
+                       ossimByteOrder byteOrder=OSSIM_LITTLE_ENDIAN);
+
+   bool initialize(const ossimFilename &fileName,
+                   ossimByteOrder byteOrder=OSSIM_LITTLE_ENDIAN);
+   
+   double southernMostLat()const{return theSouthernMostLatitude;}
+   double westernMostLon()const{return theWesternMostLongitude;}
+   double latDelta()const{return theLatDelta;}
+   double lonDelta()const{return theLonDelta;}
+   int    rows()const{return theRows;}
+   int    cols()const{return theCols;}
+   int    dataType()const{return theDataType;}
+   bool   pointWithin(double lat, double lon)const;
+   const ossimFilename& filename()const{return theFilename;}
+   
+   int headerSize()const{return 44;}
+   int dataTypeSize()const{return theDataType==1?4:0;}
+
+   double getHeightDelta(double lat,
+                         double lon)const;
+private:
+   ossimFilename theFilename;
+   ossimByteOrder theByteOrder;
+   double theSouthernMostLatitude;
+
+   /*!
+    * Important:  The geoid.bin files expresses this as a possitive value.
+    *
+    * example: -90.0 is 270 degrees.
+    */
+   double theWesternMostLongitude;
+
+   /*!
+    * Specifies the spacing of the latitude direction.
+    */
+   double theLatDelta;
+
+   /*!
+    * longitude spacing.
+    */
+   double theLonDelta;
+
+   /*!
+    * theRows specifies the number of lat increments
+    */
+   int    theRows;
+
+   /*!
+    * theCols specifies the number of lon increments
+    */
+   int    theCols;
+
+   /*!
+    * Specifies the datatype.  if this is 1 then the data that follows
+    * is 4 byte floats.
+    */
+   int    theDataType;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimActiveEdgeTable.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimActiveEdgeTable.cpp
new file mode 100644
index 0000000000..6bb0113e0e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimActiveEdgeTable.cpp
@@ -0,0 +1,227 @@
+//*****************************************************************************
+// FILE: ossimPolygon.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Garrett Potts (gpotts@imagelinks.com)
+//
+//*****************************************************************************
+//  $Id: ossimActiveEdgeTable.cpp,v 1.8 2004/04/02 22:03:54 gpotts Exp $
+#include <base/data_types/ossimActiveEdgeTable.h>
+#include <base/data_types/ossimPolygon.h>
+#include <base/data_types/ossimLine.h>
+#include <base/data_types/ossimString.h>
+#include <base/context/ossimNotifyContext.h>
+#include <iterator>
+using namespace std;
+
+
+ossimActiveEdgeTable::ossimActiveEdgeTable()
+{
+   
+}
+
+void ossimActiveEdgeTable::addPolygon(const ossimPolygon& polygon)
+{
+   createTable(polygon);
+   if(theTable.size())
+   {
+      ossim_int32 iNextY, iY;
+      ossimActiveEdgeTableNode edge;
+      ossim_uint32 numPts = polygon.getVertexCount();
+      theLastScanLine = 0;
+      
+      for (ossim_uint32 i=0; i<numPts; ++i)
+      {
+         // CURRENT EDGE IS FROM polygon[i] to polygon[(i+1)%numPts]
+         int iNext = (i+1)%numPts;  // INDEX FOR SECOND EDGE VERTEX
+         iNextY = irint(polygon[iNext].y-theRectOrigin.y);
+         iY = (irint)(polygon[i].y-theRectOrigin.y);
+         int dy = (iNextY - iY);
+         if (dy != 0)   // ADD ONLY IF EDGE NOT HORIZONTAL
+         {
+            if (dy> 0)  // local max
+            {
+               double m = (polygon[iNext].x-polygon[i].x)/
+                          (polygon[iNext].y-polygon[i].y);
+                                 
+               edge = ossimActiveEdgeTableNode(iNextY+1,
+                                               m,
+                                               polygon[i].x);
+
+               addEdgeToTable(edge, iY);
+                                               
+            }
+            else         // local min so 
+            {
+               double m = (polygon[i].x-polygon[iNext].x)/
+                          (polygon[i].y-polygon[iNext].y);
+
+               edge = ossimActiveEdgeTableNode(iY,
+                                               m,
+                                               polygon[iNext].x);
+               
+               addEdgeToTable(edge, iNextY);
+            }
+            
+         }
+      }
+   }
+}
+
+void ossimActiveEdgeTable::createTable(const ossimPolygon& polygon)
+{
+   theBoundingRect.makeNan();
+   theRectOrigin.makeNan();
+   if(polygon.getVertexCount() >2)
+   {
+      theTable.clear();
+      polygon.getBoundingRect(theBoundingRect);
+      if(!theBoundingRect.hasNans())
+      {
+         theTable.resize(theBoundingRect.height()+1);
+         theRectOrigin = theBoundingRect.ul();
+      }
+   }   
+}
+
+void ossimActiveEdgeTable::addEdgeToTable(const ossimActiveEdgeTableNode& edge,
+                                          ossim_int32 scanLine)
+{
+   theTable[scanLine].push_back(edge);
+}
+
+void ossimActiveEdgeTable::initializeActiveList()
+{
+   int i = 0;
+   for(i=0;i<(int)theTable.size();++i)
+   {
+      if(theTable[i].size())
+      {
+         theActiveList = theTable[i];
+         theTable[i].clear();
+         theCurrentScanLine = i;
+         theActiveList.sort();
+         return;
+      }
+   }
+}
+
+void ossimActiveEdgeTable::updateActiveEdges()
+{
+   std::list<ossimActiveEdgeTableNode>::iterator current = theActiveList.begin();
+
+   while(current != theActiveList.end())
+   {
+      (*current).theCurrentX += (*current).theSlope;
+
+      if((*current).theMaxY == theCurrentScanLine)
+      {
+         current = theActiveList.erase(current);
+      }
+      else
+      {
+         ++current;
+      }
+   }
+};
+
+void ossimActiveEdgeTable::mergeCurrentScanLine()
+{
+   if((theCurrentScanLine < (int)theTable.size())&&
+      theTable[theCurrentScanLine].size())
+   {
+      theTable[theCurrentScanLine].sort();
+      theActiveList.merge(theTable[theCurrentScanLine]);
+      theActiveList.sort();
+
+      theTable[theCurrentScanLine].clear();
+   }
+}
+
+void ossimActiveEdgeTable::printActiveEdgeList()const
+{
+   copy(theActiveList.begin(),
+        theActiveList.end(),
+        ostream_iterator<ossimActiveEdgeTableNode>(ossimNotify(ossimNotifyLevel_INFO) << "->"));
+   ossimNotify(ossimNotifyLevel_INFO) << "NULL\n";
+}
+
+ossimActiveEdgeTableHelper::ossimActiveEdgeTableHelper(ossimActiveEdgeTable* edgeTable)
+   :theEdgeTable(edgeTable),
+    theTableInitializedFlag(false)
+{
+}
+
+bool ossimActiveEdgeTableHelper::advanceScanLine()
+{
+   if(!theEdgeTable) return false;
+   
+   if(!theTableInitializedFlag)
+   {
+      theEdgeTable->initializeActiveList();
+      theTableInitializedFlag = true;
+   }
+   else
+   {
+      ++theEdgeTable->theCurrentScanLine;
+      theEdgeTable->updateActiveEdges();
+      theEdgeTable->mergeCurrentScanLine();
+   }
+   
+   theIterator = theEdgeTable->theActiveList.begin();
+   
+   return (theEdgeTable->theActiveList.size());
+}
+
+bool ossimActiveEdgeTableHelper::getNextLineSegment(ossimIpt& start,
+                                                    ossimIpt& end)
+{
+   if(!theEdgeTable) return false;
+   if(!theTableInitializedFlag) advanceScanLine();
+   
+   if(theIterator == theEdgeTable->theActiveList.end())
+   {
+      return false;
+   }
+   else
+   {
+      int y = theEdgeTable->getCurrentScanLine()+getYShift();
+      
+      start = ossimIpt( irint((*theIterator).theCurrentX),
+                        y);
+      ++theIterator;
+      if(theIterator == theEdgeTable->theActiveList.end())
+      {
+         end = start;
+      }
+      else
+      {
+         end = ossimIpt( irint((*theIterator).theCurrentX),
+                         y);
+         
+         ++theIterator;
+      }
+   }
+
+   if(start.x > end.x)
+   {
+      swap(start.x, end.x);
+   }
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimActiveEdgeTable.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimActiveEdgeTable.h
new file mode 100644
index 0000000000..4a200cc973
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimActiveEdgeTable.h
@@ -0,0 +1,146 @@
+//*****************************************************************************
+//
+// License:  See top level LICENSE.txt file.
+//
+// AUTHOR: Garrett Potts
+//
+//*****************************************************************************
+//  $Id: ossimActiveEdgeTable.h,v 1.6 2005/12/16 14:35:56 dburken Exp $
+#include <iostream>
+#include <vector>
+#include <list>
+#include "ossimIrect.h"
+class OSSIMDLLEXPORT ossimPolygon;
+
+
+class OSSIMDLLEXPORT ossimActiveEdgeTableNode
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out,
+                                    const ossimActiveEdgeTableNode& rhs)
+      {
+          return out <<"| maxy="<<rhs.theMaxY<<" |dx="
+                     <<rhs.theSlope<<" |"<<"x="
+                     <<rhs.theCurrentX << "|"<< std::endl;
+//          return out <<"|dy="<<rhs.theDeltaY<<" |dx="
+//                     <<rhs.theSlope<<" |"<<"x="
+//                     <<rhs.theCurrentX << "|"<<endl;
+      }
+   ossimActiveEdgeTableNode(ossim_int32 maxY      = 0,
+                            double slope    = 0.0,
+                            double currentX = 0.0)
+//       :theDeltaY(deltaY),
+      :theMaxY(maxY),
+       theSlope(slope),
+       theCurrentX(currentX)
+      {
+      }
+   bool operator()(const ossimActiveEdgeTableNode& left,
+                 const ossimActiveEdgeTableNode& right)const
+      {
+         return (left.theCurrentX < right.theCurrentX);
+      }
+   bool operator<(const ossimActiveEdgeTableNode& right)const
+      {
+         return (theCurrentX < right.theCurrentX);
+      }
+   bool operator>(const ossimActiveEdgeTableNode& right)const
+      {
+         return (theCurrentX > right.theCurrentX);
+      }
+                            
+   ossim_int32  theMaxY;
+//   ossim_int32  theDeltaY;
+   double theSlope; 
+   double theCurrentX;
+};
+
+class ossimActiveEdgeTableHelper;
+/*!
+ * This class is used in fast efficient scanliine rasterization.  It will take a polygon and insert
+ * it into the table sorted by y's
+ */
+class ossimActiveEdgeTable
+{
+public:
+   friend class ossimActiveEdgeTableHelper;
+   ossimActiveEdgeTable();
+
+   /*!
+    * Currently will only work on a single polygon.  If you call this
+    * twice it currently will use the last called polygon and
+    * will wipe out the previous one.
+    * 
+    * Note: this is used for scanline rasterization and will round
+    * to integer values all vertices as they are initially added
+    * to the Active Edge Table.
+    */
+   void addPolygon(const ossimPolygon& polygon);
+
+   const std::list<ossimActiveEdgeTableNode>& getActiveList()const;
+   
+//   bool getNextScanline(list<ossimActiveEdgeTable>::const_iterator& iterator)const;
+   
+   ossim_int32 getCurrentScanLine()const
+      {
+         return theCurrentScanLine;
+      }
+   ossim_int32 getYShift()const
+      {
+         return theRectOrigin.y;
+      }
+   
+   void initializeActiveList();
+   void updateActiveEdges();
+   void mergeCurrentScanLine();
+   void printActiveEdgeList()const;
+   
+protected:
+   std::vector< std::list<ossimActiveEdgeTableNode> > theTable;
+   std::list<ossimActiveEdgeTableNode> theActiveList;
+   
+   void createTable(const ossimPolygon& polygon);
+   void addEdgeToTable(const ossimActiveEdgeTableNode& edge,
+                       ossim_int32 scanLine);
+   /*!
+    * Used in computing the number of scanlines of the passed in polygon and
+    * is also used to shift the y's relative to 0,0
+    */
+   ossimIrect  theBoundingRect;
+   ossimIpt    theRectOrigin;
+   ossim_int32 theLastScanLine;
+   ossim_int32 theCurrentScanLine;
+};
+
+class ossimActiveEdgeTableHelper
+{
+public:
+   ossimActiveEdgeTableHelper(ossimActiveEdgeTable* edgeTable);
+
+   bool advanceScanLine();
+
+   bool getNextLineSegment(ossimIpt& start,
+                           ossimIpt& end);
+   
+   ossim_int32 getCurrentScanLine()const
+      {
+         if(theEdgeTable)
+         {
+            return theEdgeTable->getCurrentScanLine();
+         }
+         return 0;
+      }
+   ossim_int32 getYShift()const
+      {
+         if(theEdgeTable)
+         {
+            return theEdgeTable->getYShift();
+         }
+         return 0;         
+      }
+protected:
+   ossimActiveEdgeTable* theEdgeTable;
+   bool theTableInitializedFlag;
+
+   std::list<ossimActiveEdgeTableNode>::const_iterator theIterator;
+};
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimAxes.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimAxes.h
new file mode 100644
index 0000000000..301745507d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimAxes.h
@@ -0,0 +1,110 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for ossimAxes.  This will allow you to
+// define three orthogonal ossimAxes and an origin in 3-D space.  This
+// information will be used to allow you to place points relative
+// to the defined axes.
+//*******************************************************************
+//  $Id: ossimAxes.h,v 1.3 2002/11/25 18:59:54 gpotts Exp $
+
+#ifndef ossimAxes_HEADER
+#define ossimAxes_HEADER
+#include <iostream>
+#include <iomanip>
+using namespace std;
+#include "ossimMatrix3x3.h"
+#include "ossimMatrix4x4.h"
+class OSSIMDLLEXPORT ossimAxes
+{
+public:
+
+   friend inline ostream& operator <<(ostream &out, const ossimAxes &axes);
+   
+   /*!
+    * Default constructor is at position 0, 0, 0 with unit axes
+    * 
+    */
+   ossimAxes(const ossimColumnVector3d &origin=ossimColumnVector3d(0,0,0),
+             const ossimColumnVector3d &xAxis=ossimColumnVector3d(1,0,0),
+             const ossimColumnVector3d &yAxis=ossimColumnVector3d(0,1,0),
+             const ossimColumnVector3d &zAxis=ossimColumnVector3d(0,0,1))
+      :
+         theOrigin(origin),
+         theXAxis(xAxis),
+         theYAxis(yAxis),
+         theZAxis(zAxis)
+      {}
+
+   ossimColumnVector3d projectPoint(const ossimColumnVector3d &pt)
+      {
+         return ossimColumnVector3d(theXAxis.dot(pt),
+                                    theYAxis.dot(pt),
+                                    theZAxis.dot(pt));
+      }
+
+   ossimColumnVector3d pointRelative(const ossimColumnVector3d& pt)
+      {
+         return projectPoint(pt - theOrigin);
+      }
+   
+   void rotateAxes(const ossimMatrix3x3& m)
+      {
+         theXAxis = m*theXAxis;
+         theYAxis = m*theYAxis;
+         theZAxis = m*theZAxis;
+      }
+   void rotateAxes(const ossimMatrix4x4& m)
+      {
+         theXAxis = m.rotateOnly(theXAxis);
+         theYAxis = m.rotateOnly(theYAxis);
+         theZAxis = m.rotateOnly(theZAxis);
+      }
+   void transformOrigin(const ossimMatrix3x3& m)
+      {
+         theOrigin = m*theOrigin;
+      }
+   void transformOrigin(const ossimMatrix4x4& m)
+      {
+         theOrigin = m*theOrigin;
+      }
+   const ossimColumnVector3d& origin()const{return theOrigin;}
+   const ossimColumnVector3d& xAxis()const{return theXAxis;}
+   const ossimColumnVector3d& yAxis()const{return theYAxis;}
+   const ossimColumnVector3d& zAxis()const{return theZAxis;}
+   
+private:
+   ossimColumnVector3d theOrigin; // Is the origin of this axes
+   ossimColumnVector3d theXAxis;  // Is the direction of the x axis
+   ossimColumnVector3d theYAxis;  // Is the direction of the y axis
+   ossimColumnVector3d theZAxis;  // Is the direction of the z axis
+};
+
+inline ostream& operator <<(ostream &out, const ossimAxes &axes)
+{
+   return out << "position: " << axes.theOrigin << endl
+              << "x axis  : " << axes.theXAxis  << endl
+              << "Y axis  : " << axes.theYAxis  << endl
+              << "z axis  : " << axes.theZAxis;
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimColumnVector3d.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimColumnVector3d.h
new file mode 100644
index 0000000000..fa7a81a7b1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimColumnVector3d.h
@@ -0,0 +1,258 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description: This is a 3-D vector without the homogeneous
+//              coordinate.
+//
+//*******************************************************************
+//  $Id: ossimColumnVector3d.h,v 1.7 2005/06/28 15:04:13 gpotts Exp $
+#ifndef ossimColumnVector3d_HEADER
+#define ossimColumnVector3d_HEADER
+#include <base/common/ossimConstants.h>
+#include <base/context/ossimNotifyContext.h>
+#include <float.h> // for FLT_EPSILON
+#include <iomanip>
+#include <iostream>
+#include <cmath>
+using namespace std;
+
+#include <matrix/newmat.h>
+
+class OSSIMDLLEXPORT ossimColumnVector3d
+{
+public:
+   ossimColumnVector3d()
+      {
+         data[0]=0;
+         data[1]=0;
+         data[2]=0;
+      }
+
+   ossimColumnVector3d(double x, double y, double z=0)
+      {
+         data[0]=x;
+         data[1]=y;
+         data[2]=z;
+      }
+
+   ossimColumnVector3d(const ossimColumnVector3d &rhs)
+      {
+         data[0] = rhs.data[0];
+         data[1] = rhs.data[1];
+         data[2] = rhs.data[2];
+      }
+
+   const ossimColumnVector3d& operator=(const NEWMAT::ColumnVector& rhs)
+   {
+      if ( (rhs.Ncols() == 1) && (rhs.Nrows() == 3) )
+      {
+         data[0] = rhs[0];
+         data[1] = rhs[1];
+         data[2] = rhs[2];
+      }
+      return *this;
+   }
+
+   friend ostream& operator <<(ostream& out, const ossimColumnVector3d& v)
+      {
+         return out << setiosflags(ios::fixed) << setprecision(15)
+                    << v[0] << " " << v[1] <<" "
+                    << v[2];
+      }
+
+   friend ossimColumnVector3d operator*(double scalar,
+					const ossimColumnVector3d &v)
+      {
+         return ossimColumnVector3d(v.data[0]*scalar,
+                                    v.data[1]*scalar,
+                                    v.data[2]*scalar);
+      }
+
+   /*!
+    *  Multiplies column vector times matrix.
+    *  Note:
+    *  If "lhs" is not a 3x3 that's an error and a blank column vector
+    *  is returned.
+    */
+   friend ossimColumnVector3d operator*(const NEWMAT::Matrix& lhs,
+                                        const ossimColumnVector3d& rhs)
+   {
+      if ((lhs.Ncols() == 3) && (lhs.Nrows() == 3))
+      {
+         return ossimColumnVector3d( (lhs[0][0]*rhs[0] + lhs[0][1]*rhs[1] + lhs[0][2]*rhs[2]),
+                                     (lhs[1][0]*rhs[0] + lhs[1][1]*rhs[1] + lhs[1][2]*rhs[2]),
+                                     (lhs[2][0]*rhs[0] + lhs[2][1]*rhs[1] + lhs[2][2]*rhs[2]));
+      }
+      else if((lhs.Ncols() == 4) && (lhs.Nrows() == 4))
+      {
+         return ossimColumnVector3d( (lhs[0][0]*rhs[0] + lhs[0][1]*rhs[1] + lhs[0][2]*rhs[2] + lhs[0][3]) ,
+                                     (lhs[1][0]*rhs[0] + lhs[1][1]*rhs[1] + lhs[1][2]*rhs[2] + lhs[1][3]) ,
+                                     (lhs[2][0]*rhs[0] + lhs[2][1]*rhs[1] + lhs[2][2]*rhs[2] + lhs[2][3]));
+      }
+      ossimNotify(ossimNotifyLevel_WARN) << "Multiplying a 3 row column vector by an invalid matrix" << std::endl;
+      return rhs;
+   }
+
+   double& operator [](int index)
+      {
+         return data[index];
+      }
+
+   const double& operator [](int index)const
+      {
+         return data[index];
+      }
+
+   ossimColumnVector3d operator*(double scalar)const
+      {
+         return ossimColumnVector3d(data[0]*scalar,
+                                    data[1]*scalar,
+                                    data[2]*scalar);
+      }
+
+   ossimColumnVector3d operator +(const ossimColumnVector3d &rhs)const
+      {
+         return ossimColumnVector3d( data[0]+rhs[0],
+                                     data[1]+rhs[1],
+                                     data[2]+rhs[2]);
+      }
+
+   const ossimColumnVector3d& operator +=(const ossimColumnVector3d &rhs)
+      {
+         data[0] += rhs[0];
+         data[1] += rhs[1];
+         data[2] += rhs[2];
+
+         return *this;
+      }
+
+   ossimColumnVector3d operator - ()const
+      {
+         return ossimColumnVector3d(-data[0],
+                                    -data[1],
+                                    -data[2]);
+      }
+
+   ossimColumnVector3d operator /(double scalar)const
+      {
+         return ossimColumnVector3d( data[0]/scalar,
+                                     data[1]/scalar,
+                                     data[2]/scalar);
+      }
+
+   const ossimColumnVector3d& operator /=(double scalar)
+      {
+         data[0]/=scalar;
+         data[1]/=scalar;
+         data[2]/=scalar;
+
+         return *this;
+      }
+
+   ossimColumnVector3d operator -(const ossimColumnVector3d &rhs)const
+      {
+         return ossimColumnVector3d( data[0]-rhs[0],
+                                     data[1]-rhs[1],
+                                     data[2]-rhs[2]);
+      }
+
+   const ossimColumnVector3d& operator -=(const ossimColumnVector3d &rhs)
+      {
+         data[0] -= rhs[0];
+         data[1] -= rhs[1];
+         data[2] -= rhs[2];
+
+         return *this;
+      }
+
+   bool operator ==(const ossimColumnVector3d &rhs) const
+      { return ((fabs(data[0] - rhs[0]) <= FLT_EPSILON) &&
+		(fabs(data[1] - rhs[1]) <= FLT_EPSILON) &&
+		(fabs(data[2] - rhs[2]) <= FLT_EPSILON));
+      }
+
+   bool operator !=(const ossimColumnVector3d &rhs) const
+      { return !(*this == rhs); }
+
+   double magnitude()const
+      {
+         return sqrt(data[0]*data[0] +
+                     data[1]*data[1] +
+                     data[2]*data[2]);
+      }
+   double dot(const ossimColumnVector3d &rhs) const
+      {
+         return (data[0]*rhs[0]+
+                 data[1]*rhs[1]+
+                 data[2]*rhs[2]);
+      }
+
+   ossimColumnVector3d unit() const
+   {
+      double mag = magnitude();
+
+      if(fabs(mag) > FLT_EPSILON)
+      {
+         mag = 1.0/mag;
+         return (*this *mag);
+      }
+
+      return *this;
+   }
+
+   ossimColumnVector3d cross(const ossimColumnVector3d &rhs) const
+      {
+         return ossimColumnVector3d( data[1]*rhs[2] - data[2]*rhs[1],
+                               data[2]*rhs[0] - data[0]*rhs[2],
+                               data[0]*rhs[1] - data[1]*rhs[0]);
+      }
+
+   const ossimColumnVector3d& xAligned()
+      {
+         data[0] = 1;
+         data[1] = 0;
+         data[2] = 0;
+
+         return *this;
+      }
+   const ossimColumnVector3d& yAligned()//
+      {
+         data[0] = 0;
+         data[1] = 1;
+         data[2] = 0;
+
+         return *this;
+      }
+   const ossimColumnVector3d& zAligned() //
+      {
+         data[0] = 0;
+         data[1] = 0;
+         data[2] = 1;
+
+         return *this;
+      }
+
+private:
+   double data[3];
+};
+
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimColumnVector4d.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimColumnVector4d.h
new file mode 100644
index 0000000000..0be3f174cf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimColumnVector4d.h
@@ -0,0 +1,213 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description: This is your 3-D vector where the 4-th dimension is
+//              for the homogenious coordinate.
+//
+//*******************************************************************
+//  $Id: ossimColumnVector4d.h,v 1.3 2004/09/10 15:45:34 gpotts Exp $
+#ifndef ossimColumnVector4d_HEADER
+#define ossimColumnVector4d_HEADER
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <float.h> // for FLT_EPSILON
+#include <iomanip>
+#include <iostream>
+#include <cmath>
+using namespace std;
+
+class OSSIMDLLEXPORT ossimColumnVector4d
+{
+public:
+   ossimColumnVector4d()
+      {
+         data[0]=0;
+         data[1]=0;
+         data[2]=0;
+         data[3]=1;
+      }
+
+   ossimColumnVector4d(double x, double y, double z, double w=1.0)
+      {
+         data[0]=x;
+         data[1]=y;
+         data[2]=z;
+         data[3]=w;
+      }
+
+   ossimColumnVector4d(const ossimColumnVector4d &rhs)
+      {
+         data[0] = rhs.data[0];
+         data[1] = rhs.data[1];
+         data[2] = rhs.data[2];
+         data[3] = rhs.data[3];
+      }
+   friend ostream& operator <<(ostream& out, const ossimColumnVector4d& v)
+      {
+         return out << setiosflags(ios::fixed) << setprecision(15)
+                    << v[0] << " " << v[1] <<" "
+                    << v[2] << " " << v[3];
+      }
+
+   friend ossimColumnVector4d operator*(double scalar, const ossimColumnVector4d &v)
+      {
+         return ossimColumnVector4d(v.data[0]*scalar,
+                              v.data[1]*scalar,
+                              v.data[2]*scalar);
+      }
+
+   double& operator [](int index)
+      {
+         return data[index];
+      }
+
+   const double& operator [](int index)const
+      {
+         return data[index];
+      }
+
+   ossimColumnVector4d operator*(double scalar)const
+      {
+         return ossimColumnVector4d(data[0]*scalar,
+                         data[1]*scalar,
+                         data[2]*scalar);
+      }
+
+   ossimColumnVector4d operator +(const ossimColumnVector4d &rhs)const
+      {
+         return ossimColumnVector4d( data[0]+rhs[0],
+                               data[1]+rhs[1],
+                               data[2]+rhs[2]);
+      }
+
+   ossimColumnVector4d operator +=(const ossimColumnVector4d &rhs)
+      {
+         data[0] += rhs[0];
+         data[1] += rhs[1];
+         data[2] += rhs[2];
+
+         return *this;
+      }
+
+   ossimColumnVector4d operator - ()const
+      {
+         return ossimColumnVector4d(-data[0],
+                         -data[1],
+                         -data[2]);
+      }
+
+   ossimColumnVector4d operator /(double scalar)const
+      {
+         return ossimColumnVector4d( data[0]/scalar,
+                               data[1]/scalar,
+                               data[2]/scalar);
+      }
+
+   ossimColumnVector4d& operator /=(double scalar)
+      {
+         data[0]/=scalar;
+         data[1]/=scalar;
+         data[2]/=scalar;
+
+         return *this;
+      }
+
+   ossimColumnVector4d operator -(const ossimColumnVector4d &rhs)const
+      {
+         return ossimColumnVector4d( data[0]-rhs[0],
+                               data[1]-rhs[1],
+                               data[2]-rhs[2]);
+      }
+
+   ossimColumnVector4d operator -=(const ossimColumnVector4d &rhs)
+      {
+         data[0] -= rhs[0];
+         data[1] -= rhs[1];
+         data[2] -= rhs[2];
+
+         return *this;
+      }
+
+   double magnitude()const
+      {
+         return std::sqrt(data[0]*data[0] +
+                          data[1]*data[1] +
+                          data[2]*data[2]);
+      }
+   double dot(const ossimColumnVector4d &rhs)const
+      {
+         return (data[0]*rhs[0]+
+                 data[1]*rhs[1]+
+                 data[2]*rhs[2]);
+      }
+
+   ossimColumnVector4d unit()const
+   {
+      double mag = magnitude();
+
+      if(ossimAbs(mag) > DBL_EPSILON)
+      {
+         mag = 1.0/mag;
+         return (*this *mag);
+      }
+
+      return *this;
+   }
+
+   ossimColumnVector4d cross(const ossimColumnVector4d &rhs)
+      {
+         return ossimColumnVector4d( data[1]*rhs[2] - data[2]*rhs[1],
+                               data[2]*rhs[0] - data[0]*rhs[2],
+                               data[0]*rhs[1] - data[1]*rhs[0]);
+      }
+
+   ossimColumnVector4d& xAligned()// creates 4-D homogeneous vectors
+      {
+         data[0] = 1;
+         data[1] = 0;
+         data[2] = 0;
+         data[3] = 1;
+
+         return *this;
+      }
+   ossimColumnVector4d& yAligned()//
+      {
+         data[0] = 0;
+         data[1] = 1;
+         data[2] = 0;
+         data[3] = 1;
+
+         return *this;
+      }
+   ossimColumnVector4d& zAligned() //
+      {
+         data[0] = 0;
+         data[1] = 0;
+         data[2] = 1;
+         data[3] = 1;
+
+         return *this;
+      }
+
+private:
+   double data[4];
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDblGrid.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimDblGrid.cpp
new file mode 100644
index 0000000000..470d30bbde
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDblGrid.cpp
@@ -0,0 +1,1127 @@
+//*****************************************************************************
+// FILE: ossimDblGrid.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR:  Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimDblGrid. This class maintains
+//   a regular grid of floating point (double) values. Access methods to the
+//   grid include interpolation between grid nodes. Capability is included
+//   to address the grid in an arbitrary, floating-point x, y coordinate
+//   system. 
+//
+//*****************************************************************************
+//  $Id: ossimDblGrid.cpp,v 1.24 2004/04/02 22:03:54 gpotts Exp $
+
+#include <base/data_types/ossimDblGrid.h>
+#include <limits.h>
+#include <iostream>
+using namespace std;
+
+#include <base/data_types/ossimDrect.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+static ossimTrace traceExec  ("ossimDblGrid:exec");
+static ossimTrace traceDebug ("ossimDblGrid:debug");
+
+const double ossimDblGrid::DEFAULT_NULL_VALUE =  OSSIM_DBL_NAN;
+static const ossimString MAGIC_NUMBER ("OSSIM_DBL_GRID");
+static const int   MAX_LENGTH_DESCR = 80;
+
+/*!****************************************************************************
+ *  DEFAULT CONSTRUCTOR: ossimDblGrid
+ *  
+ *****************************************************************************/
+ossimDblGrid::ossimDblGrid()
+   :
+      theGridData       (0),
+      theSize           (0, 0),
+      theOrigin         (0.0, 0.0),
+      theSpacing        (0.0, 0.0),
+      theMinValue       (OSSIM_INFINITY),
+      theMaxValue       (-OSSIM_INFINITY),
+      theNullValue      (DEFAULT_NULL_VALUE),
+      theMeanIsComputed (false)
+{ }
+
+
+/*!****************************************************************************
+ *  COPY CONSTRUCTOR: ossimDblGrid
+ *  
+ *****************************************************************************/
+ossimDblGrid::ossimDblGrid(const ossimDblGrid&  source)
+   :
+      theGridData(NULL),
+      theSize           (source.theSize),
+      theOrigin         (source.theOrigin),
+      theSpacing        (source.theSpacing),
+      theMinValue       (source.theMinValue),
+      theMaxValue       (source.theMaxValue),
+      theNullValue      (source.theNullValue),
+      theMeanValue      (source.theMeanValue),
+      theDeviation      (source.theDeviation),
+      theMeanIsComputed (source.theMeanIsComputed)
+{
+   static const char MODULE[] = "ossimDblGrid Constructor";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entering...\n";
+
+   *this = source;
+   /*!
+    * Allocate mem for the grid, and initialize:
+    */
+//    int buflen = theSize.x * theSize.y;
+//    theGridData = new double [buflen];
+
+//    for (int i=0; i<buflen; i++)
+//       theGridData[i] = source.theGridData[i];
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";
+}
+
+/*!****************************************************************************
+ *  CONSTRUCTOR: ossimDblGrid
+ *  
+ *****************************************************************************/
+ossimDblGrid::ossimDblGrid(const ossimIpt&  size, 
+                           const ossimDpt&  origin,
+                           const ossimDpt&  spacing,
+                           double           null_value)
+   :
+      theGridData (0)
+{
+   static const char MODULE[] = "ossimDblGrid Constructor";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entering...\n";
+
+   initialize(size, origin, spacing, null_value);
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";
+}
+
+/*!****************************************************************************
+ *  CONSTRUCTOR: ossimDblGrid
+ *  
+ *****************************************************************************/
+ossimDblGrid::ossimDblGrid(const ossimDrect&  rect, 
+                           const ossimDpt&    spacing,
+                           double             null_value)
+   :
+      theGridData (0)
+{
+   static const char MODULE[] = "ossimDblGrid Constructor";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entering...\n";
+
+   ossimIpt size ((int) (rect.width()/spacing.x)  + 1,
+                  (int) (rect.height()/spacing.y) + 1);
+   
+   initialize(size, rect.ul(), spacing, null_value);
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_WARN) << MODULE << " returning...\n";
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimDblGrid()
+//  
+//*****************************************************************************
+ossimDblGrid::~ossimDblGrid()
+{
+   if(theGridData)
+   {
+      delete [] theGridData;
+      theGridData = NULL;
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimDblGrid::initialize()
+//  
+//  Permits initialization after construction
+//  
+//*****************************************************************************
+void ossimDblGrid::initialize(const ossimIpt&  size, 
+                              const ossimDpt&  origin,
+                              const ossimDpt&  spacing,
+                              double           null_value)
+{
+   static const char MODULE[] = "ossimDblGrid::initialize()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_WARN) << MODULE << " entering...\n";
+
+   //***
+   // Delete any existing grid:
+   //***
+   if (theGridData)
+    {
+       delete [] theGridData;
+       theGridData = 0;
+    }
+   
+   //***
+   // Initialize data members:
+   //***
+   theSize           = size;
+   theOrigin         = origin;
+   theSpacing        = spacing;
+   theMinValue       = OSSIM_INFINITY;
+   theMaxValue       =  -OSSIM_INFINITY;
+   theNullValue      = null_value;
+   theMeanIsComputed = false;
+
+   /*!
+    * Allocate mem for the grid, and initialize:
+    */
+   int buflen = theSize.x * theSize.y;
+   if(buflen > 0)
+     {
+       theGridData = new double [buflen];
+
+       for (int i=0; i<buflen; i++)
+	 theGridData[i] = theNullValue;
+     }   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_WARN) << MODULE << " returning...\n";
+
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimDblGrid::initialize()
+//  
+//  Permits initialization after construction
+//  
+//*****************************************************************************
+void ossimDblGrid::initialize(const ossimDrect&  uv_rect, 
+                              const ossimDpt&    spacing,
+                              double null_value)
+{
+   static const char MODULE[] = "ossimDblGrid::initialize()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entering...\n";
+
+   ossimIpt size ((int) (uv_rect.width()/spacing.x)  + 1,
+                  (int) (uv_rect.height()/spacing.y) + 1);
+   
+   initialize(size, uv_rect.ul(), spacing, null_value);
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";
+   return;
+}
+
+void ossimDblGrid::deallocate()
+{
+  if(theGridData)
+    {
+      delete [] theGridData;
+      theGridData = 0;
+    }
+  theSize = ossimIpt(0,0); 
+}
+
+/*!****************************************************************************
+ * METHOD: ossimDblGrid::setNode(x, y) NON-CONST
+ *
+ *  This method is used to assign the grid data values.
+ *  
+ *****************************************************************************/
+void ossimDblGrid::setNode (int x, int y,
+                            const double&   value) 
+{
+  if(!theGridData) return;
+
+   if ((x>=0)&&(x<theSize.x)&&(y>=0)&&(y<theSize.y))
+   {
+      theGridData[index(x, y)] = value;
+
+      if (value != theNullValue)
+      {
+         if (value < theMinValue)
+            theMinValue = value;
+         if (value > theMaxValue)
+            theMaxValue = value;
+      }
+      
+      theMeanIsComputed = false;
+   }
+   
+   return;
+}
+
+/*!****************************************************************************
+ * METHOD: ossimDblGrid::setNearestNode(uv)
+ *
+ * Sets the node nearest the U,V point specified to the value given. This is
+ * different from setNode() in that the UV coordinate system is used to
+ * address a node instead of an XY grid point.
+ *  
+ *****************************************************************************/
+void ossimDblGrid::setNearestNode (const ossimDpt& uv_point,
+                                   const double&   value) 
+{
+  if(!theGridData) return;
+   //***
+   // Establish the grid indexes:
+   //***
+   int xi = (int) irint((uv_point.u - theOrigin.u)/theSpacing.x);
+   int yi = (int) irint((uv_point.v - theOrigin.v)/theSpacing.y);
+
+   if (xi < 0)
+      xi = 0;
+   if (xi >= theSize.x)
+      xi = theSize.x - 1;
+   if (yi < 0)
+      yi = 0;
+   if (yi >= theSize.y)
+      yi = theSize.y - 1;
+
+   setNode (xi, yi, value);
+   
+   return;
+}
+
+/*!****************************************************************************
+ * METHOD: ossimDblGrid::getNode(x, y) CONST
+ *
+ *  This method is used to return the grid data values.
+ *  
+ *****************************************************************************/
+double ossimDblGrid::getNode (int x, int y) const
+{
+  if(!theGridData) return theNullValue;
+   if ((x>=0)&&(x<theSize.x)&&(y>=0)&&(y<theSize.y))
+      return theGridData[index(x, y)];
+
+   return theNullValue;
+}
+
+/*!****************************************************************************
+ * METHOD: ossimDblGrid::operator(double, double)
+ *
+ *  This method interpolates between grid points given a fractional location
+ *  in UV (external) world space.
+ *  
+ *****************************************************************************/
+double ossimDblGrid::operator() (const double& u,
+                                 const double& v) const
+{
+  if(!theGridData) return theNullValue;
+
+   if (isInside(u, v))
+   {
+      /*!
+       * Establish the grid indexes:
+       */
+      double xi = (u - theOrigin.u)/theSpacing.x;
+      double yi = (v - theOrigin.v)/theSpacing.y;
+
+      
+      int x0 = (int) xi;
+      int y0 = (int) yi;
+
+      x0 = (x0<theSize.x)?x0:(theSize.x-1);
+      y0 = (y0<theSize.y)?y0:(theSize.y-1);
+      xi = (xi<theSize.x)?xi:(theSize.x-1);
+      yi = (yi<theSize.y)?yi:(theSize.y-1);
+      /*!
+       * Perform bilinear interpolation:
+       */
+      double wx1 = xi - x0;
+      double wy1 = yi - y0;
+
+      
+       double wx0 = 1.0 - wx1;
+       double wy0 = 1.0 - wy1;
+
+       int index00;
+       int index10;
+       int index11;
+       int index01;
+
+       
+       index00  = theSize.x*y0 + x0;
+       if(x0 < (theSize.x-1))
+       {
+          index10  = index00 + 1;
+       }
+       else
+       {
+          index10  = index00;
+       }
+       if(y0 < (theSize.y-1))
+       {
+          index01  = index00 + theSize.x;
+       }
+       else
+       {
+          index01  = index00;
+       }
+       if(y0 < (theSize.y-1))
+       {
+          index01  = index00 + theSize.x;
+       }
+       else
+       {
+          index01  = index00;
+       }
+       
+       if(x0 < (theSize.x-1))
+       {
+          index11  = index01 + 1;
+       }
+       else
+       {
+          index11  = index01;
+       }
+
+
+      double p00   = (double) theGridData[index00];
+      double p01   = (double) theGridData[index01];
+      double p10   = (double) theGridData[index10];
+      double p11   = (double) theGridData[index11];
+      
+      double w00   = wx0*wy0;
+      double w01   = wx0*wy1;
+      double w10   = wx1*wy0;
+      double w11   = wx1*wy1;
+      
+      return (p00*w00 + p01*w01 + p10*w10 + p11*w11) /
+         (w00 + w01 + w10 + w11);
+   }
+
+   // else
+   return theNullValue;
+}
+
+//*****************************************************************************
+//  OPERATOR: =
+//  
+//*****************************************************************************
+const ossimDblGrid& ossimDblGrid::operator = (const ossimDblGrid& source)
+{
+   if(&source == this) return *this;
+   
+   if (theGridData)
+     {
+       delete [] theGridData;
+       theGridData = 0;
+     }
+
+   //***
+   // Assign data members:
+   //***
+   theSize           = source.theSize;
+   theOrigin         = source.theOrigin;
+   theSpacing        = source.theSpacing;
+   theMinValue       = source.theMinValue;
+   theMaxValue       = source.theMaxValue;
+   theNullValue      = source.theNullValue;
+   theMeanValue      = source.theMeanValue;
+   theDeviation      = source.theDeviation;
+   theMeanIsComputed = source.theMeanIsComputed;
+
+   //***
+   // Allocate mem for the grid, and initialize:
+   //***
+   int buflen = theSize.x * theSize.y;
+   if(buflen>0)
+     {
+       theGridData = new double [buflen];
+       
+       for (int i=0; i<buflen; i++)
+	 {
+	   theGridData[i] = source.theGridData[i];
+	 }
+     }
+   return *this;
+}
+
+
+/*!****************************************************************************
+ * METHOD: ossimDblGrid::meanValue()
+ *  
+ *****************************************************************************/
+double  ossimDblGrid::meanValue()
+{
+   static const char MODULE[] = "ossimDblGrid::meanValue()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entering...\n";
+   
+   if (!theMeanIsComputed)
+     {
+       computeMean();
+     }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";
+   return theMeanValue;
+}
+
+/*!****************************************************************************
+ * METHOD: ossimDblGrid::meanStdDev()
+ *  
+ *****************************************************************************/
+double  ossimDblGrid::meanStdDev()
+{
+   static const char MODULE[] = "ossimDblGrid::meanStdDev()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entering...\n";
+   
+   if (!theMeanIsComputed)
+      computeMean();
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";;
+   return theDeviation;
+}
+
+/*!****************************************************************************
+ * METHOD: ossimDblGrid::computeMean()
+ *  
+ *****************************************************************************/
+void ossimDblGrid::computeMean()
+{
+   static const char MODULE[] = "ossimDblGrid::meanStdDev()";
+  if(!theGridData) return;
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "entering...\n";
+
+   if (!theMeanIsComputed)
+   {
+      double accum = 0.0;
+      double num_samples = 0.0;
+
+      /*!
+       * Loop to compute mean:
+       */
+      for (int i=0; i<(theSize.x*theSize.y); i++)
+      {
+         if (theGridData[i] != theNullValue)
+         {
+            accum += theGridData[i];
+            num_samples += 1.0;
+         }
+      }
+      theMeanValue = accum/num_samples;
+
+      /*!
+       * Loop again to compute deviation:
+       */
+      accum = 0.0;
+      double diff;
+      for (int i=0; i<(theSize.x*theSize.y); i++)
+      {
+         if (theGridData[i] != theNullValue)
+         {
+            diff = theMeanValue - theGridData[i];
+            accum += diff*diff;
+         }
+      }
+      theDeviation = sqrt(accum/num_samples);
+
+      theMeanIsComputed = true;
+   }
+      
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";
+   return;
+}
+
+/*!****************************************************************************
+ * INLINE METHOD: ossimDblGrid::isInside(const ossimDpt& pt) const
+ *****************************************************************************/
+bool ossimDblGrid::isInside(const double& u,
+                                   const double& v) const
+{
+   double xi = (u - theOrigin.u)/theSpacing.x;
+   double yi = (v - theOrigin.v)/theSpacing.y;
+//   return ((xi >= 0.0) && (xi <= ((double)theSize.x - 1.0)) &&
+//           (yi >= 0.0) && (yi <= ((double)theSize.y - 1.0)));
+   return ((xi >= 0.0) && (xi < ((double)theSize.x)) &&
+           (yi >= 0.0) && (yi < ((double)theSize.y)));
+}
+                    
+
+//*****************************************************************************
+//  METHOD: ossimDblGrid::save()
+//  
+//  Saves the grid to the stream in compact ASCII format (not necessarily
+//  human readable).
+//  
+//*****************************************************************************
+bool ossimDblGrid::save(ostream& os, const char* descr) const
+{
+   static const char MODULE[] = "ossimDblGrid::save()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entering...\n";
+
+   //***
+   // Preserve the stream's settings:
+   //***
+   ios::fmtflags new_options = ios::scientific|ios::dec;
+   //ios::streamsize new_precision = 12;
+   int new_precision = 12;
+   
+   ios::fmtflags old_options = os.flags(new_options);
+   int old_precision = os.precision(new_precision);
+
+   //***
+   // Verify the description string is not too long:
+   //***
+   char descr_buf[81];
+   strncpy(descr_buf, descr, 80);
+   descr_buf[80] = '\0';
+   
+   //***
+   // write magic number tag and the grid size X, Y, num params:
+   //***
+   os << MAGIC_NUMBER << " " << descr_buf << "\n"
+      << theSize.x << "  "
+      << theSize.y << "  "
+      << theOrigin.u << "  "
+      << theOrigin.v << "  "
+      << theSpacing.u << "  "
+      << theSpacing.v << "  "
+      << theNullValue << "\n";
+
+   if(theGridData)
+     {
+       //***
+       // Loop to write grid points:
+       //***
+       int max_index = theSize.x*theSize.y;
+       for (int i=0; i<max_index; i++)
+	 os << theGridData[i] << "  ";
+     }
+   os << "\n";
+   
+   //***
+   // Restore the stream's state:
+   //***
+   os.flags(old_options);
+   os.precision(old_precision);
+      
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimDblGrid::load()
+//  
+//  Loads the grid from the stream in compact ASCII format (not necessarily
+//  human readable).
+//  
+//*****************************************************************************
+bool ossimDblGrid::load(istream& is)
+{
+   static const char MODULE[] = "ossimDblGrid::load()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entering...\n";
+
+   char strbuf[128];
+   
+   //***
+   // Read magic number tag to insure it is an ossimDblGrid record:
+   //***
+   is >> strbuf;
+   if (strncmp(strbuf, MAGIC_NUMBER.c_str(), MAGIC_NUMBER.length()))
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << MODULE << "Error reading OSSIM_DBL_GRID magic number from stream. "
+                                          << "Aborting...\n";
+      return false;
+   }
+   is.getline(strbuf, 128, '\n');
+   theSize           = ossimDpt(0,0);
+   theOrigin         = ossimDpt(0,0);
+   theSpacing        = ossimDpt(0,0);
+   theMinValue       = OSSIM_INFINITY;
+   theMaxValue       =  -OSSIM_INFINITY;
+   theNullValue      = theNullValue;
+   theMeanIsComputed = false;
+
+   
+   //***
+   // Read the grid size, origin, and spacing:
+   //***
+   ossimIpt size;
+   ossimDpt origin, spacing;
+   double null_value;
+   is >> size.x 
+      >> size.y 
+      >> origin.u 
+      >> origin.v 
+      >> spacing.u
+      >> spacing.v
+      >> null_value;
+   
+   initialize(size, origin, spacing, null_value);
+   
+   //***
+   // Loop to read grid points:
+   //***
+   int max_index = theSize.x*theSize.y;
+   for (int i=0; i<max_index; i++)
+     {
+       is >> theGridData[i];
+     }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";
+   
+   return true;
+}
+
+//*****************************************************************************
+//  PRIVATE FUNCTION: isBlocked()
+//  
+//  Used by interpolateNullValuedNodes. Returns true if the direction indicated
+//  by the vector (x, y) has been blocked from further sampling. This occurs if
+//  a sample has already been found in that general direction. The directions
+//  are discrete (16) evenly distributed about a "compass rose." Each index
+//  corresponds to one of the directions as illustrated here:
+//
+//                        15 0 1
+//                     14    |    2
+//                    13     |     3
+//                   12------+------4
+//                    11     |     5
+//                     10    |    6
+//                         9 8 7
+//
+//*****************************************************************************
+bool isBlocked(bool* blocked, int x, int y)
+{
+   if (y == 0)
+   {
+      if (x > 0) return blocked[4];
+      return blocked[12];
+   }
+   
+   double r = x/y;
+   int c = 0;
+   int i;
+   if (x < 0.0) c = 8;
+
+   //***
+   // Test the tangent value instead of computing angle:
+   //***
+   if      (r >  5.02734) i = 12 + c;
+   else if (r >  1.49660) i = 13 + c;
+   else if (r >  0.66818) i = 14 + c;
+   else if (r >  0.19891) i = 15 + c;
+   else if (r > -0.19891) i =  0 + c;
+   else if (r > -0.66818) i =  1 + c;
+   else if (r > -1.49660) i =  2 + c;
+   else if (r > -5.02734) i =  3 + c;
+   else                   i =  4 + c;
+
+   if (i > 15) i -= 16;  // modulo 16
+   
+   return blocked[i];
+}
+
+//*****************************************************************************
+//  PRIVATE FUNCTION: blockDirection()
+//  
+//  Used by interpolateNullValuedNodes. Blocks the resampler from exploring
+//  further in a general direction, specified by thevector (x, y). The blocking
+//  is requested when a sample is found. This prevents a sample that is shadowed
+//  by a closer sample from having influence.
+//
+//  See method isBlocked() above for a description of the compass rose indexing.
+//  
+//*****************************************************************************
+void blockDirection(bool* blocked, int x, int y)
+{
+   if (y == 0)
+   {
+      if (x > 0) blocked[4] = true;
+      else       blocked[12] = true;
+      return;
+   }
+
+   double r = x/y;
+   int c = 0;
+   int i;
+   if (x < 0.0) c = 8;
+
+   //***
+   // Test the tangent value instead of computing angle:
+   //***
+   if      (r >  5.02734) i = 12 + c;
+   else if (r >  1.49660) i = 13 + c;
+   else if (r >  0.66818) i = 14 + c;
+   else if (r >  0.19891) i = 15 + c;
+   else if (r > -0.19891) i =  0 + c;
+   else if (r > -0.66818) i =  1 + c;
+   else if (r > -1.49660) i =  2 + c;
+   else if (r > -5.02734) i =  3 + c;
+   else                   i =  4 + c;
+
+   if (i > 15) i -= 16;  // modulo 16
+   blocked[i] = true;
+   
+   return;
+}
+      
+//*****************************************************************************
+//   METHOD: ossimDblGrid::interpolateNullValuedNodes(decay_rate)
+//
+//   This method performs a resampling of the defined grid nodes in order to
+//   compute interpolated values for those uninitialized nodes. This is
+//   necessary when only a subset of nodes are available for initializing the
+//   grid.
+//
+//   The decay rate is a geometric (1/r) factor applied to the weights to
+//   amplify the rate at which a neighbor's influence diminishes. For a
+//   decay_rate = 1, the influence of a sample diminishes linearly with the
+//   distance.
+//  
+//*****************************************************************************
+void ossimDblGrid::interpolateNullValuedNodes(const double& decay_rate)
+{
+   static const char MODULE[] = "ossimDblGrid::interpolateNullValuedNodes()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entering...\n";
+   if(!theGridData) return;
+
+   //***
+   // Allocate buffer to store resampled nodes:
+   //***
+   int      buf_size          = theSize.x*theSize.y;
+   double*  resampled_grid    = new double [buf_size];
+   double   min_weight_needed = 4.0/decay_rate;
+
+   int      start_x, start_y, end_x, end_y;
+   int      diameter;
+   double   sum_weights;
+   double   accumulator;
+   double   weight;
+   double   sample;
+   double   node_value;
+   bool     sample_found;
+   int      node_idx;
+   double   adj_delta;
+   int      dx, dy;
+   bool     blocked[16];
+
+   //***
+   // Loop over the entire grid to resample all NULL nodes:
+   //***
+   for (int y=0; y<theSize.y; y++)
+   {
+      for (int x=0; x<theSize.x; x++)
+      {
+         //***
+         // Only resample those nodes that contain NULL:
+         //***
+         node_idx = index(x, y);
+         node_value = theGridData[node_idx];
+         if (node_value != theNullValue)
+         {
+            //***
+            // This node had a value. Simply copy it into the resample_grid:
+            //***
+            resampled_grid[node_idx] = node_value;
+         }
+
+         else
+         {
+            //***
+            // Resampling is necessary. Initialize quantities used:
+            //***
+            start_x = x;
+            start_y = y;
+            diameter = 0;
+            sum_weights = 0;
+            accumulator = 0;
+            weight = 1.0;
+            sample_found = true;
+
+            for (int i=0; i<16; i++)
+               blocked[i] = false;
+            
+            //***
+            // Loop collecting contributions from non-null neighbors. Begin with
+            // a small kernel size (diameter) and successively grow until a
+            // sufficient number of contributors is found:
+            //***
+            while ((sum_weights < min_weight_needed) && sample_found)
+            {
+               diameter += 2;
+               start_x -= 1;
+               start_y -= 1;
+               weight *= decay_rate;
+               sample_found = false;
+
+               //***
+               // Loop over each pixel in kernel and sum in it's contribution:
+               //***
+               end_y = start_y + diameter;
+               end_x = start_x + diameter;
+               
+               for (int yn=start_y; yn<=end_y; yn++)
+               {
+                  if ((yn == start_y) || (yn == end_y))
+                  {
+                     //***
+                     // This is the top edge or bottom edge, need samples from
+                     // each x along kernel edge:
+                     //***
+                     for (int xn=start_x; xn<=end_x; xn++)
+                     {
+                        sample_found = sample_found || isInside(xn, yn);
+                        sample = getNode(xn, yn);
+                        if (sample != theNullValue)
+                        {
+                           dx = x - xn; dy = y - yn;
+                           if (!isBlocked(blocked, dx, dy))
+                           {
+                              adj_delta = weight*sqrt((double)(dx*dx + dy*dy));
+                              accumulator += sample/adj_delta;
+                              sum_weights += 1.0/adj_delta;
+                              blockDirection(blocked, dx, dy);
+                           }
+                        }
+                     }
+                  }
+                  else
+                  {
+                     //***
+                     // For the left/right edge of the kernel, need to sample
+                     // only the first (start_x) and last (end_x):
+                     //***
+                     sample_found = sample_found || isInside(start_x, yn);
+                     sample = getNode(start_x, yn);
+                     if (sample != theNullValue)
+                     {
+                        dx = x - start_x; dy = y - yn;
+                        if (!isBlocked(blocked, dx, dy))
+                        {
+                           adj_delta = weight*sqrt((double)(dx*dx + dy*dy));
+                           accumulator += sample/adj_delta;
+                           sum_weights += 1.0/adj_delta;
+                           blockDirection(blocked, dx, dy);
+                        }
+                     }
+
+                     sample_found = sample_found || isInside(end_x, yn);
+                     sample = getNode(end_x, yn);
+                     if (sample != theNullValue)
+                     {
+                        dx = x - end_x; dy = y - yn;
+                        if (!isBlocked(blocked, dx, dy))
+                        {
+                           adj_delta = weight*sqrt((double)(dx*dx + dy*dy));
+                           accumulator += sample/adj_delta;
+                           sum_weights += 1.0/adj_delta;
+                           blockDirection(blocked, dx, dy);
+                        }
+                     }
+                  } // end else
+               } // end for loop over all rows in kernel
+            } // end while loop inflating kernel size
+
+            //***
+            // Finished collecting sample contributions for this node. compute
+            // convolution and save in buffer:
+            //***
+            if (sum_weights != 0)
+               resampled_grid[node_idx] = accumulator/sum_weights;
+            else
+               resampled_grid[node_idx] = theNullValue;
+
+         } // end else (if input node is NULL)
+      } // end for loop over all columns in grid
+   } // end for loop over all lines in grid
+
+   //***
+   // Now copy the resampled grid back into the original buffer:
+   //***
+   for (node_idx=0; node_idx<buf_size; node_idx++)
+      theGridData[node_idx] = resampled_grid[node_idx];
+
+   delete [] resampled_grid;
+               
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimDblGrid::filter(size_x, size_y, kernel)
+//  
+//  Passes the grid data through a convolution filter given in the kernel array.
+//  The grid must not contain any NULL nodes as these are not scanned for.
+//  The kernel sizes should be odd numbers.
+//  
+//*****************************************************************************
+void ossimDblGrid::filter(int size_x, int size_y, double* kernel)
+{
+   static const char MODULE[] = "ossimDblGrid::filter()";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << "entering...\n";
+   if(!theGridData) return;
+
+   //***
+   // Allocate buffer to store resampled nodes:
+   //***
+   int      buf_size          = theSize.x*theSize.y;
+   double*  resampled_grid    = new double [buf_size];
+   for (int i=0; i<buf_size; i++)
+      resampled_grid[i] = 0.0;
+
+   int      rx      = (size_x - 1)/2;     // kernel radii
+   int      ry      = (size_y - 1)/2;     
+   int      start_x = rx;                 // indexes to start sampling grid
+   int      start_y = ry;
+   int      end_x   = theSize.x - rx;     // indexes to end buffer sampling
+   int      end_y   = theSize.y - ry;
+   int      knl_ctr = ry*size_x + rx;     // offset to center of kernel buffer
+   double   node_value;
+   double   kernel_value;
+   int      node_idx;
+   
+   //***
+   // Loop over the entire grid to resample all NULL nodes:
+   //***
+   for (int y=start_y; y<end_y; y++)
+   {
+      for (int x=start_x; x<end_x; x++)
+      {
+         node_idx = index(x, y);
+         
+         //***
+         // Fetch samples for each kernel element, apply gain, then accumulate
+         // in output buffer:
+         //***
+         for (int ky=-ry; ky<=ry; ky++)
+         {
+            for (int kx=-rx; kx<=rx; kx++)
+            {
+               node_value = theGridData[index(x+kx, y+ky)];
+               kernel_value = kernel[knl_ctr + ky*size_x + kx];
+               resampled_grid[node_idx] += kernel_value*node_value;
+            }
+         }
+      }
+   }
+
+   //***
+   // The grid margin has unfiltered data due to the kernel radius. Set these
+   // nodes equal to the nearest filtered nodes:
+   //***
+   for (int y=0; y<theSize.y; y++)
+   {
+      for (int x=0; x<theSize.x; x++)
+      {
+         //***
+         // Top edge:
+         //***
+         if (y < start_y)
+         {
+            if (x < start_x)      // top-left corner
+               resampled_grid[index(x, y)] = resampled_grid[index(rx, ry)];
+            else if (x >= end_x)  // top-right corner
+               resampled_grid[index(x, y)] = resampled_grid[index(end_x-1, ry)];
+            else                  // top region
+               resampled_grid[index(x, y)] = resampled_grid[index(x, ry)];
+         }
+
+         //***
+         // Middle:
+         //***
+         else if (y < end_y)
+         {
+            if (x < start_x)      // left edge
+               resampled_grid[index(x, y)] = resampled_grid[index(rx, y)];
+            else if (x >= end_x)  // right edge
+               resampled_grid[index(x, y)] = resampled_grid[index(end_x-1, y)];
+         }
+
+         //***
+         // Bottom:
+         //***
+         else
+         {
+            if (x < start_x)      // bottom-left corner
+               resampled_grid[index(x, y)] = resampled_grid[index(rx, end_y-1)];
+            else if (x >= end_x)  // bottom-right corner
+               resampled_grid[index(x, y)] = resampled_grid[index(end_x-1,
+                                                                  end_y-1)];
+            else                  // bottom region
+               resampled_grid[index(x, y)] = resampled_grid[index(x, end_y-1)];
+         }
+      }
+   }
+   
+   //***
+   // Now copy the resampled grid back into the original buffer:
+   //***
+   for (node_idx=0; node_idx<buf_size; node_idx++)
+      theGridData[node_idx] = resampled_grid[node_idx];
+
+   delete [] resampled_grid;
+               
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " returning...\n";
+   return;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimDblGrid::fill
+//  
+//  Fills the current grid with constant value provided.
+//  
+//*****************************************************************************
+void ossimDblGrid::fill(double fill_value)
+{
+   if (!theGridData)
+     {
+       return;
+     }
+   
+   int size = theSize.x * theSize.y;
+   for (int i=0; i<size; i++)
+      theGridData[i] = fill_value;
+   
+   return;
+}
+
+
+//*****************************************************************************
+//  FRIEND OPERATOR: ostream& << (ostream&) 
+//  
+//*****************************************************************************
+ostream& operator<<(ostream& os, const ossimDblGrid& grid) 
+{
+   os << "\nDump of ossimDblGrid at " << (void*) &grid
+      << "\n  theSize: "           << grid.theSize
+      << "\n  theOrigin: "         << grid.theOrigin
+      << "\n  theSpacing: "        << grid.theSpacing
+      << "\n  theMinValue: "       << grid.theMinValue
+      << "\n  theMaxValue: "       << grid.theMaxValue
+      << "\n  theNullValue: "      << grid.theNullValue
+      << "\n  theMeanValue: "      << grid.theMeanValue
+      << "\n  theDeviation: "      << grid.theDeviation
+      << "\n  theMeanIsComputed: " << grid.theMeanIsComputed
+      << "\n";
+
+   if(grid.theGridData)
+     {
+       
+       for (int y=0; y<grid.theSize.y; y++)
+	 {
+	   for (int x=0; x<grid.theSize.x; x++)
+	     {
+	       os << "\n  node(" << x << ", " << y << "): " << grid.getNode(x,y);
+	     }
+	 }
+     }
+
+   return os;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDblGrid.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimDblGrid.h
new file mode 100644
index 0000000000..0e9ab4ea2c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDblGrid.h
@@ -0,0 +1,214 @@
+//*****************************************************************************
+// FILE: ossimDblGrid.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// AUTHOR:  Oscar Kramer
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimDblGrid. This object class maintains
+//   a regular grid of floating point (double) values. Access methods to the
+//   grid include interpolation between grid nodes. Capability is included
+//   to address the grid in an arbitrary, floating-point u, v coordinate
+//   system which is related to the integer grid x, y system by scale and
+//   offset:
+//
+//          u = Sx*(x + Xo),   v = Sy*(y + Y0)
+//
+//   where Xo, Yo is the origin of the U/V cood system. Sx, Sy are the scale
+//   relations. For example, if the grid is being used to hold a grid of
+//   elevation posts, then the origin will be the SW corner post ground point,
+//   and the scale will be derived from the post spacing. Both origin and
+//   spacing are specified to the constructor.
+//
+//*****************************************************************************
+//  $Id: ossimDblGrid.h,v 1.13 2005/12/16 14:36:44 dburken Exp $
+
+#ifndef ossimDblGrid_HEADER
+#define ossimDblGrid_HEADER
+
+#include "base/data_types/ossimDpt.h"
+#include "base/data_types/ossimIpt.h"
+#include "base/common/ossimCommon.h"
+
+class OSSIMDLLEXPORT ossimDrect;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimDblGrid
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimDblGrid 
+{
+public:
+   static const double DEFAULT_NULL_VALUE;
+
+   /*!
+    * Default Constructor.
+    */
+   ossimDblGrid ();
+
+   /*!
+    * Copy Constructor.
+    */
+   ossimDblGrid (const ossimDblGrid& source_to_copy);
+
+   /*!
+    * Constructs given a U/V origin and spacing, and a grid size.
+    */
+   ossimDblGrid (const ossimIpt&  size, 
+                 const ossimDpt&  origin,
+                 const ossimDpt&  spacing,
+                 double null_value = DEFAULT_NULL_VALUE);
+
+   /*!
+    * Constructs given a rectangle in U/V space and grid spacing. The origin is
+    * taken as the upper-left corner of the rectangle. The lower-rightmost grid
+    * point may not coincide with the rectangles LR corner if the side is not
+    * evenly divisible by the corresponding spacing.
+    */
+   ossimDblGrid (const ossimDrect&  uv_rect, 
+                 const ossimDpt&    spacing,
+                 double null_value = DEFAULT_NULL_VALUE);
+
+   ~ossimDblGrid ();
+
+   /*!
+    * When constructed with default, permits initialization afterward.
+    */
+   void         initialize(const ossimIpt&  size, 
+                           const ossimDpt&  origin,
+                           const ossimDpt&  spacing,
+                           double null_value = DEFAULT_NULL_VALUE);
+   void         initialize(const ossimDrect&  uv_rect, 
+                           const ossimDpt&    spacing,
+                           double null_value = DEFAULT_NULL_VALUE);
+  void deallocate();
+   /*!
+    * Fills the current grid with the value specified.
+    */
+   void         fill(double fill_value);
+
+   /*!
+    * Fills the current grid with null values.
+    */
+   void         clear() { fill(theNullValue); }
+   
+   /*!
+    * Access individual node value by node index in the X/Y (grid) coord system.
+    */
+   void         setNode (const ossimIpt& p,
+                         const double& value)   { setNode(p.x, p.y, value); }
+   void         setNode (int x, int y, const double&  value);
+
+   double       getNode (const ossimIpt& p) const { return getNode(p.x, p.y); }
+   double       getNode (int x, int y) const;
+
+   /*!
+    * Sets the node nearest the U,V point specified to the value given. This is
+    * different from setNode() in that the UV coordinate system is used to
+    * address a node instead of an XY grid point.
+    */
+   void         setNearestNode(const ossimDpt& uv_point,
+                               const double&   value);
+   
+   /*!
+    * This method performs a resampling of the defined grid nodes in order to
+    * compute interpolated values for those uninitialized nodes. This is
+    * necessary when only a subset of nodes are available for initializing the
+    * grid.
+    */
+   void interpolateNullValuedNodes(const double& decay_rate=10.0);
+
+   /*!
+    * Passes the grid data through a convolution filter given the kernel array.
+    * The grid must not contain any NULL nodes as these are treated as valid
+    * quantities. The kernel sizes should be odd numbers. To avoid shrinking
+    * the grid by the kernel radius, the edge nodes outside of the filter's
+    * reach are set equal to the nearest filtered node. X is the contiguous
+    * axis in the kernel array, i.e., kernel(x,y) = kernel[y*size_x + x].
+    */
+   void filter(int size_x, int size_y, double* kernel);
+   
+   /*!
+    * Interpolate between grid nodes given arbitrary u/v coord system:
+    */
+   enum InterpType
+   {
+      BILINEAR
+   };
+   void  setInterpolationType (InterpType interp);
+
+   /*!
+    * Access an interpolated value in the U/V (output) coordinate system.
+    */
+   double operator() (const ossimDpt& p) const {return (*this)(p.u,p.v);}
+   double value      (const ossimDpt& p) const {return (*this)(p.u,p.v);}
+
+   double operator() (const double& u, const double& v) const;
+   double value (const double& u, const double& v) const {return (*this)(u,v);}
+
+   /*!
+    * operator for initializing this grid with another.
+    */
+   const ossimDblGrid& operator = (const ossimDblGrid& grid);
+   
+   /*!
+    *Statistics methods:
+    */
+   double minValue()   const { return theMinValue; }
+   double maxValue()   const { return theMaxValue; }
+   double nullValue()  const { return theNullValue; }
+   double meanValue();
+   double meanStdDev();
+
+   void setMinValue(double value) {theMinValue = value;}
+   void setMaxValue(double value) {theMaxValue = value;}
+   void setNullValue(double value) {theNullValue = value;}
+   /*!
+    * Other member access methods:
+    */
+   const ossimIpt& size()    const { return theSize; }
+   const ossimDpt& origin()  const { return theOrigin; }
+   const ossimDpt& spacing() const { return theSpacing; }
+   unsigned long   getSizeInBytes() const
+      { return theSize.x*theSize.y*sizeof(double); }
+   
+   /*!
+    * Returns true if double point lies within world space coverage:
+    */
+   bool  isInside(const ossimDpt& p) const {return isInside(p.u, p.v);}
+   bool  isInside(const double& u, const double& v) const;
+
+   /*!
+    * Loads and saves the grid from/to a stream. Returns TRUE if successful.
+    */
+   bool  save(std::ostream& os, const char* descr) const;
+   bool  load(std::istream& is);
+      
+   
+   friend std::ostream& operator << (std::ostream& os,
+                                     const ossimDblGrid& grid);
+   
+private:
+   
+   void  computeMean();
+   int   index(int x, int y) const { return y*theSize.x + x; }
+   
+   double*      theGridData;
+   ossimIpt     theSize;
+   ossimDpt     theOrigin;
+   ossimDpt     theSpacing;
+   double       theMinValue;
+   double       theMaxValue;
+   double       theNullValue;
+   double       theMeanValue;
+   double       theDeviation;
+   bool         theMeanIsComputed;
+   
+};
+
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectory.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectory.cpp
new file mode 100644
index 0000000000..9c01f1f7db
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectory.cpp
@@ -0,0 +1,275 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Garrett Potts
+// 
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimDirectory.cpp,v 1.16 2005/10/28 14:01:03 gpotts Exp $
+
+#include <iostream>
+
+#if defined (_WIN32)
+#include <io.h>
+#include <direct.h>
+#else
+#include "ossimDirectoryData.h"
+#endif
+#ifdef __BORLANDC__
+# include <dir.h>
+#include <direct.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <io.h>
+#define _chdir chdir
+#endif
+
+#include "ossimDirectory.h"
+#include "ossimRegExp.h"
+
+//#include "wx/filefn.h"          // for wxMatchWild
+
+// #include <sys/types.h>
+
+// #include <dirent.h>
+
+// ----------------------------------------------------------------------------
+// ossimDirectory construction/destruction
+// ----------------------------------------------------------------------------
+
+#if defined (_WIN32)
+ossimDirectory::ossimDirectory()
+   :
+      theData(0),
+      theDirectoryName(),
+      theFlags(0)
+{}
+
+ossimDirectory::ossimDirectory(const ossimFilename &dirname)
+   :
+      theData(0),
+      theDirectoryName(dirname),
+      theFlags(0)
+{
+   open(dirname);
+}
+
+ossimDirectory::~ossimDirectory()
+{
+   if (theData != 0) _findclose( theData );
+}
+
+bool ossimDirectory::open(const ossimFilename &dirname)
+{
+   // close out currently open directory
+   if (theData != 0)
+   {
+      _findclose( theData );
+      theData = 0;
+   }
+   
+   // set new directory name
+   theDirectoryName = dirname;
+
+	return (dirname.isDir());
+   // cd to the new directory
+//   if (_chdir( theDirectoryName) == -1)
+//   {
+//      return false;
+//   }
+   
+//   return true;
+}
+
+bool ossimDirectory::getFirst(ossimFilename &filename, int flags)
+{
+   struct _finddata_t c_file;
+   ossimFilename temp;
+   //long theData1 = _findfirst( "*.*", &c_file );
+   ossimFilename dirName = theDirectoryName.dirCat("*");
+   if( (theData = _findfirst( dirName.c_str(), &c_file )) != 0L )
+   {
+      setFlags(flags);
+      
+      temp = theDirectoryName.dirCat(c_file.name);
+      
+	  
+      while (!fileMatched(temp))
+      {
+         // look for next file in the directory
+         if (_findnext( theData, &c_file ) == 0 )
+         {
+            temp = theDirectoryName.dirCat(c_file.name);
+         }
+         else
+         {
+            // no more file in the directory
+            return false;
+         }
+      }
+   }
+
+   // set the filenane that matches
+   filename = temp.trim();
+
+   return (filename!="");
+}
+
+bool ossimDirectory::getNext(ossimFilename &filename) const
+{
+   struct _finddata_t c_file;
+   bool matches = false;
+   ossimFilename temp;
+
+   while (!matches )
+   {
+      // look for next file in the directory
+      if (_findnext( theData, &c_file ) == 0 )
+      {
+         temp = theDirectoryName.dirCat(c_file.name);
+         matches = fileMatched(temp);
+      }
+      else
+      {
+         // no more file in the directory
+         return false;
+      }
+   }
+
+   // set the filenane that matches
+   if (matches)
+   {
+      filename = temp.trim();
+   }
+
+   return (matches&&(filename!=""));
+}
+
+bool ossimDirectory::fileMatched(ossimFilename &filename) const
+{
+   bool matches=false;
+
+   // don't return "." and ".." unless asked for
+   if ( (filename == "..") || (filename == ".")   )
+   {
+      if (theFlags & ossimDirectory::OSSIM_DIR_DOTDOT)
+      {
+         matches = true;
+      }
+   }
+   else if((filename.isDir()) && (theFlags & ossimDirectory::OSSIM_DIR_DIRS))
+   {
+      matches = true;
+   }
+   else if((filename.isFile()) && (theFlags & ossimDirectory::OSSIM_DIR_FILES))
+   {
+      matches = true;
+   }
+   else
+   {
+      matches = false;
+   }
+
+   return matches;
+}
+
+bool ossimDirectory::isOpened() const
+{
+    return theData != 0;
+}
+
+#else
+
+ossimDirectory::ossimDirectory()
+   :
+      theData(NULL)
+{}
+
+ossimDirectory::ossimDirectory(const ossimFilename &dirname)
+{
+    theData = NULL;
+    open(dirname);
+}
+
+bool ossimDirectory::open(const ossimFilename &dirname)
+{
+    delete theData;
+    theData = new ossimDirectoryData(dirname);
+
+    if ( theData &&
+         (!theData->isOk()) )
+    {
+        delete theData;
+        theData = NULL;
+
+        return false;
+    }
+
+    return true;
+}
+
+ossimDirectory::~ossimDirectory()
+{
+    delete theData;
+}
+
+// ----------------------------------------------------------------------------
+// ossimDirectory enumerating
+// ----------------------------------------------------------------------------
+
+bool ossimDirectory::getFirst(ossimFilename &filename,
+                              int flags)
+{
+   if(theData && isOpened())
+   {
+      theData->rewind();
+
+      theData->setFlags(flags);
+
+      return getNext(filename);
+   }
+
+   return false;
+}
+
+bool ossimDirectory::getNext(ossimFilename &filename) const
+{
+   if(theData && isOpened())
+   {
+      return theData->read(filename);
+   }
+
+   return false;
+}
+
+bool ossimDirectory::isOpened() const
+{
+    return theData != NULL;
+}
+
+#endif
+
+void ossimDirectory::findAllFilesThatMatch(std::vector<ossimFilename>& result,
+					   const ossimString& regularExpressionPattern,
+					   int flags)
+{
+   ossimFilename filename;
+   ossimRegExp   regExpr;
+   regExpr.compile(regularExpressionPattern.c_str());
+   if(getFirst(filename, flags))
+   {
+      do
+      {
+         ossimString fileOnly = filename.file();
+         if(regExpr.find(fileOnly.c_str()))
+         {
+            result.push_back(filename);
+         }
+      }while(getNext(filename));
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectory.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectory.h
new file mode 100644
index 0000000000..d0351ed83e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectory.h
@@ -0,0 +1,83 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Garrett Potts
+//
+// Description: 
+//
+//*************************************************************************
+// $Id: ossimDirectory.h,v 1.7 2004/11/04 20:11:35 dburken Exp $
+#ifndef ossimDirectory_HEADER
+#define ossimDirectory_HEADER
+
+#include "ossimFilename.h"
+
+#ifndef _WIN32
+class ossimDirectoryData;
+#endif
+
+class  OSSIMDLLEXPORT ossimDirectory
+{
+public:
+   
+   /*!
+    * These flags define what kind of filenames is included in the list
+    * of files enumerated by GetFirst/GetNext.
+    */
+   enum
+   {
+      OSSIM_DIR_FILES     = 0x0001,       // include files
+      OSSIM_DIR_DIRS      = 0x0002,       // include directories
+      OSSIM_DIR_HIDDEN    = 0x0004,       // include hidden files
+      OSSIM_DIR_DOTDOT    = 0x0008,       // include '.' and '..'
+      
+      // by default, enumerate everything except '.' and '..'
+      OSSIM_DIR_DEFAULT   = OSSIM_DIR_FILES | OSSIM_DIR_DIRS | OSSIM_DIR_HIDDEN
+   };
+
+
+   ossimDirectory();
+   
+   ossimDirectory(const ossimFilename& dir);
+   
+   ~ossimDirectory();
+   
+   bool open(const ossimFilename& dir);
+   
+   bool isOpened() const;
+   
+   bool getFirst(ossimFilename &filename,
+                 int flags = OSSIM_DIR_DEFAULT);
+   
+   /*!
+    * Get next file in the enumeration started with either GetFirst() or
+    * GetFirstNormal().
+    */
+   bool getNext(ossimFilename &filename) const;
+   
+   void findAllFilesThatMatch(std::vector<ossimFilename>& result,
+                              const ossimString& regularExpressionPattern,
+                              int flags = OSSIM_DIR_DEFAULT);
+   
+#if defined (_WIN32)
+   void setFlags(int flags) { theFlags = flags; };
+   bool fileMatched(ossimFilename &filename) const;
+#endif    
+   
+   // TODO using scandir() when available later, emulating it otherwise
+   
+private:
+#if defined (_WIN32)
+   long          theData;
+   ossimFilename theDirectoryName;
+   int           theFlags;
+#else
+   ossimDirectoryData *theData;
+#endif
+};
+
+#endif /* #ifndef ossimDirectory_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryData.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryData.cpp
new file mode 100644
index 0000000000..655e967b18
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryData.cpp
@@ -0,0 +1,168 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// 
+// Description:
+// Class designed to be used by ossimDirectory class.  Should not be used
+// directly.
+//
+//*************************************************************************
+// $Id: ossimDirectoryData.cpp,v 1.4 2004/05/12 17:34:04 dburken Exp $
+
+#ifndef _MSC_VER
+
+#include <sys/types.h>
+#include <iostream>
+using namespace std;
+
+#include "ossimDirectoryData.h"
+#include "ossimDirectory.h"  /* for flag enumerations */
+
+// ----------------------------------------------------------------------------
+// ossimDirectoryData
+// ----------------------------------------------------------------------------
+
+#if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 )
+
+ossimDirectoryData::ossimDirectoryData(const ossimFilename& dirname)
+         : theDirectoryName(dirname)
+{
+    theDir = NULL;
+
+    // throw away the trailing slashes
+    size_t n = theDirectoryName.length();
+    if(n > 0)
+    {
+
+       while ( n > 0 && theDirectoryName[--n] == '/' )
+        ;
+
+//       theDirectoryName.Truncate(n + 1);
+
+    // do open the dir
+       theDir = opendir(theDirectoryName.c_str());
+    }
+}
+
+ossimDirectoryData::~ossimDirectoryData()
+{
+   if ( theDir )
+   {
+      if ( closedir(theDir) != 0 )
+      {
+         // ERROR closing directory
+      }
+   }
+}
+
+bool ossimDirectoryData::read(ossimFilename &filename)
+{
+   filename = ossimFilename::NIL;
+   dirent *de = (dirent *)NULL;    // just to silent compiler warnings
+   bool matches = false;
+   ossimFilename temp;
+
+   while ( !matches )
+   {
+      de = readdir(theDir);
+      if ( !de )
+      {
+         return false;
+      }
+      
+      temp = theDirectoryName.dirCat(de->d_name);
+
+      //***
+      // NOTE:
+      // The check for "." and ".." did not work so added pattern match check.
+      //***
+      
+      // Check for "." and ".." match at the end of the name.
+      ossimString s = temp.match("\\.$|\\.\\.$"); 
+      
+      // don't return "." and ".." unless asked for
+      if ( (temp == "..") ||
+           (temp == ".")  ||
+           (s    == ".")  ||
+           (s    == "..") )
+      {
+         if (theFlags & ossimDirectory::OSSIM_DIR_DOTDOT)
+         {
+            matches = true;
+         }
+      }
+      else if((temp.isDir()) &&
+              (theFlags & ossimDirectory::OSSIM_DIR_DIRS))
+      {
+         matches = true;
+      }
+      else if((temp.isFile()) &&
+              (theFlags & ossimDirectory::OSSIM_DIR_FILES))
+      {
+         matches = true;
+      }
+      else
+      {
+         matches = false;
+      }
+   }
+   
+   if (matches)
+   {
+      filename = temp;//de->d_name;
+   }
+   
+   return matches;
+}
+
+#else // old VMS (TODO)
+
+ossimDirectoryData::ossimDirectoryData(const ossimFilename& WXUNUSED(dirname))
+{
+}
+
+ossimDirectoryData::~ossimDirectoryData()
+{
+}
+
+bool ossimDirectoryData::read(ossimFilename &filename)
+{
+    return false;
+}
+
+#endif // not or new VMS/old VMS
+
+void ossimDirectoryData::setFlags(int flags)
+{
+   theFlags = flags;
+}
+
+int ossimDirectoryData::getFlags() const
+{
+   return theFlags;
+}
+
+void ossimDirectoryData::rewind()
+{
+   rewinddir(theDir);
+}
+
+#endif /* #ifndef _MSC_VER */
+
+ 
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryData.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryData.h
new file mode 100644
index 0000000000..70d661d66d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryData.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// 
+// Description:
+// Class designed to be used by ossimDirectory class.  Should not be used
+// directly.
+//
+//*************************************************************************
+// $Id: ossimDirectoryData.h,v 1.2 2004/05/12 17:34:04 dburken Exp $
+#ifndef ossimDirectoryData_HEADER
+#define ossimDirectoryData_HEADER
+
+#ifndef _MSC_VER
+
+#include <dirent.h>
+#include "ossimFilename.h"
+
+class OSSIMDLLEXPORT ossimDirectoryData
+{
+ public:
+   ossimDirectoryData(const ossimFilename& dirname);
+   ~ossimDirectoryData();
+   
+   bool isOk() const { return theDir != NULL; }
+   
+   void setFlags(int flags);
+   int  getFlags() const;
+   
+   void rewind();
+   bool read(ossimFilename &filename);
+   
+ private:
+   DIR*          theDir;
+   ossimFilename theDirectoryName;
+   int           theFlags;
+};
+
+#endif /* #ifndef _MSC_VER */
+
+#endif /* #ifndef ossimDirectoryData_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryTree.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryTree.cpp
new file mode 100644
index 0000000000..09cb87c7c1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryTree.cpp
@@ -0,0 +1,169 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimDirectoryTree.cpp,v 1.4 2004/05/04 12:17:06 gpotts Exp $
+
+#include "ossimDirectoryTree.h"
+#include "ossimDirectory.h"
+#include "ossimRegExp.h"
+ossimDirectoryTree::ossimDirectoryTree()
+   :
+      theCurrentDirectoryData(NULL),
+      theFlags(0)
+{
+}
+
+ossimDirectoryTree::~ossimDirectoryTree()
+{
+   deleteAll();
+}
+
+void ossimDirectoryTree::findAllFilesThatMatch(std::vector<ossimFilename>& result,
+					       const ossimString& regularExpressionPattern,
+					       int flags)
+{
+  ossimFilename filename;
+  ossimRegExp   regExpr;
+  regExpr.compile(regularExpressionPattern.c_str());
+  if(getFirst(filename, flags))
+  {
+     do
+     {
+        if(regExpr.find(filename.c_str()))
+        {
+           result.push_back(filename);
+        }
+     }while(getNext(filename));
+  }
+}
+
+bool ossimDirectoryTree::open(const ossimFilename& dir)
+{
+   if(theCurrentDirectoryData)
+   {
+      deleteAll();
+   }
+
+   theCurrentDirectoryData = new ossimDirData(new ossimDirectory, dir);
+   theCurrentDirectoryData->theDirectory->open(dir);
+   if(theCurrentDirectoryData->theDirectory->isOpened())
+   {
+      return true;
+   }
+   else
+   {
+      delete theCurrentDirectoryData;
+      theCurrentDirectoryData = NULL;
+   }
+
+   return isOpened();
+}
+
+bool ossimDirectoryTree::isOpened() const
+{
+   if(theCurrentDirectoryData)
+   {
+      return theCurrentDirectoryData->theDirectory->isOpened();
+   }
+   
+   return false;
+}
+
+bool ossimDirectoryTree::getFirst(ossimFilename &filename, int flags)
+{
+   bool result = false;
+   theFlags    = flags | ossimDirectory::OSSIM_DIR_DIRS;
+   if(theCurrentDirectoryData && isOpened())
+   {
+      result = theCurrentDirectoryData->theDirectory->getFirst(filename,
+                                                               flags);
+      while(result&&filename.isDir())
+      {
+         checkToPushDirectory(filename);
+         result = theCurrentDirectoryData->theDirectory->getNext(filename);
+      }
+
+      if(!result)
+      {
+         if(!theDirectoryQueue.empty())
+         {
+            ossimFilename newDir = theDirectoryQueue.front();
+            theDirectoryQueue.pop();
+            theCurrentDirectoryData->theDirectory->open(newDir);
+            
+            return getFirst(filename, flags);
+         }
+      }
+   }
+   
+   return result;
+}
+
+// get next file in the enumeration started with either GetFirst() or
+// GetFirstNormal()
+bool ossimDirectoryTree::getNext(ossimFilename &filename)
+{
+   bool result = false;
+   
+   if(theCurrentDirectoryData)
+   {
+      result = theCurrentDirectoryData->theDirectory->getNext(filename);
+      if(result)
+      {
+         checkToPushDirectory(filename);
+      }
+      else
+      {
+         if(!theDirectoryQueue.empty())
+         {
+            ossimFilename newDir = theDirectoryQueue.front();
+            theDirectoryQueue.pop();
+            theCurrentDirectoryData->theDirectory->open(newDir);
+            return getFirst(filename);
+         }
+      }
+   }
+   
+   return result;
+}
+
+void ossimDirectoryTree::deleteAll()
+{
+   if(theCurrentDirectoryData)
+   {
+      delete theCurrentDirectoryData;
+      theCurrentDirectoryData = NULL;
+   }
+}
+
+void ossimDirectoryTree::checkToPushDirectory(const ossimFilename &filename)
+{
+   if((filename.file().trim() == ".") ||
+      (filename.file().trim() == ".."))
+   {
+      return;
+   }
+   else if(filename.isDir())
+   {
+      theDirectoryQueue.push(filename);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryTree.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryTree.h
new file mode 100644
index 0000000000..ffce4407eb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDirectoryTree.h
@@ -0,0 +1,87 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimDirectoryTree.h,v 1.5 2004/05/04 12:17:25 gpotts Exp $
+#ifndef ossimDirectoryTree_HEADER
+#define ossimDirectoryTree_HEADER
+#include <queue>
+#include <vector>
+using namespace std;
+
+#include "ossimDirectory.h"
+
+class OSSIMDLLEXPORT ossimDirectoryTree
+{
+public:
+   ossimDirectoryTree();
+   ~ossimDirectoryTree();
+
+   bool open(const ossimFilename& dir);
+
+   bool isOpened() const;
+   
+   bool getFirst(ossimFilename &filename,
+                 int flags = ossimDirectory::OSSIM_DIR_DEFAULT);
+   
+   // get next file in the enumeration started with either GetFirst() or
+   // GetFirstNormal()
+   bool getNext(ossimFilename &filename) ;
+
+  void findAllFilesThatMatch(std::vector<ossimFilename>& result,
+			     const ossimString& regularExpressionPattern,
+			     int flags = ossimDirectory::OSSIM_DIR_DEFAULT);
+private:
+   class OSSIMDLLEXPORT ossimDirData
+   {
+   public:
+      ~ossimDirData()
+         {
+            if(theDirectory)
+            {
+               delete theDirectory;
+               theFilename = "";
+            }
+         }
+      ossimDirData(ossimDirectory *aDir,
+                         const ossimFilename &filename)
+                         :theDirectory(aDir),
+                         theFilename(filename)
+         {
+            
+         }
+      ossimDirectory* theDirectory;
+      ossimFilename   theFilename;
+   };
+   
+   queue<ossimFilename> theDirectoryQueue;
+   ossimDirData*        theCurrentDirectoryData;
+   int                  theFlags;
+
+   void deleteAll();
+
+   void checkToPushDirectory(const ossimFilename &filename);
+   // for now we will hide copy
+   ossimDirectoryTree(const ossimDirectoryTree &rhs);
+   const ossimDirectoryTree& operator =(const ossimDirectoryTree& rhs);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDms.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimDms.cpp
new file mode 100644
index 0000000000..d0fc519914
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDms.cpp
@@ -0,0 +1,941 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class definition for Degrees Minutes Seconds (ossimDms)
+//*******************************************************************
+//  $Id: ossimDms.cpp,v 1.17 2005/07/18 11:05:42 gpotts Exp $
+
+#include <math.h>
+#include <iomanip>
+#include <sstream>
+using namespace std;
+#include <stdio.h>
+
+#include "ossimDms.h"
+#include <iomanip>
+using namespace std;
+
+const ossim_uint8 ossimDms::theDegreeSign = 176;
+char *ossimDms::DEFAULT_FORMAT = "ddd mm.mmC";
+char *ossimDms::SPACES = "                   ";
+
+
+ossimDms::ossimDms(double someDegrees, bool latFlag)
+   : theDegrees(someDegrees),
+     theLatFlag(latFlag),
+     theDecDegs(0.0),
+     theAfterDot(false),
+     theDoingSeconds(true),
+     theIntDegs(0),
+     theSign(1),
+     theWorking(0.0)
+{
+}
+
+ossimDms::ossimDms(char *value)
+   : theDegrees(0.0),
+     theLatFlag(false),
+     theDecDegs(0.0),
+     theAfterDot(false),
+     theDoingSeconds(true),
+     theIntDegs(0),
+     theSign(1),
+     theWorking(0.0)
+{
+   if(value && (ossimString(value)!=ossimString("")))
+   {
+      theDegrees = string_to_degree(value);
+   }
+   else
+   {
+      theDegrees = 0.0;
+   }
+
+}
+
+ossimDms& ossimDms::setDegrees(double degrees)
+{
+   theDegrees = degrees;
+   
+   return *this;
+}
+
+bool ossimDms::setDegrees(const char *cdegrees)
+{
+   bool status = true;
+   
+   ossimString copy = cdegrees;
+   
+   double degrees, factor, dividend, units;
+   int i;
+   bool afterdelim;
+   char* cptr = const_cast<char*>(copy.c_str());
+   char c;
+
+   theAfterDot = false;
+   afterdelim = false;
+   degrees = 0.0;
+   units = 0.0;
+   factor = 1.0;
+   dividend = 60.0;
+   theSign = 1;
+
+   /* get rid of leading spaces */
+
+   while (*cptr == ' ')
+   {
+      cptr++;
+   }
+
+   while(*cptr != '\0') 
+   {
+      switch (*cptr) 
+      {
+
+         // north, west and + values will change sign of degrees to plus.
+
+         case '+':
+         {
+            theSign = 1;
+            cptr++;
+         }
+         case 'n':
+         case 'N':
+         {
+            theSign = 1;
+            theLatFlag = true;
+            cptr++;
+            break;
+         }
+         case 'e':
+         case 'E':
+         {
+            theLatFlag = false;
+            theSign = 1;
+            cptr++;
+            break;
+         }
+
+         // south, east and - values will change sign of degrees to minus
+         
+         case '-':
+         {
+            theSign = -1;
+            cptr++;
+            break;
+         }
+         case 's':
+         case 'S':
+         {
+            theSign = -1;
+            cptr++;
+            theLatFlag = true;
+            break;
+         }
+         case 'w':
+         case 'W':
+         {
+            theSign = -1;
+            cptr++;
+            theLatFlag = false;
+            break;
+         }
+         
+         case '0':
+         case '1':
+         case '2':
+         case '3':
+         case '4':
+         case '5':
+         case '6':
+         case '7':
+         case '8':
+         case '9': 
+         {
+            c = *cptr;
+            i = (c - '0');
+            
+            if (afterdelim == true) 
+            {
+               if (theAfterDot == true) 
+               {
+                  units = units + (((double)i * factor) / dividend);
+               }
+               else
+               {
+                  units = (units * factor) + ((double)i / dividend);
+               }
+            }
+            else 
+            {
+               if (theAfterDot == true)
+               {
+                  degrees = degrees + ((double)i * factor);
+               }
+               else
+               {
+                  degrees = (degrees * factor) + (double)i;
+               }
+            }
+            if (theAfterDot == true)
+            {
+               factor = factor * .10;
+            }
+            else
+            {
+               factor = 10.;
+            }
+            
+            cptr++;
+            break;
+         }
+
+         //---
+         // a decimal point indicates a change in the factor used
+         // to calculate degrees or units (minutes or seconds)
+         //---
+         case '.': 
+         {
+            factor = .10;
+            theAfterDot = true;
+            cptr++;
+            break;
+         }
+
+         // after a delimiter the value contains minutes, first time through
+         case ' ': 
+         case '\"':
+         case '\'':
+         {
+            while (*(cptr + 1) == ' ')
+            {
+               cptr++;
+            }
+            
+            degrees = degrees + units;
+            units = 0.0;
+            
+            if (afterdelim == true) 	/* must be seconds */
+            {
+               dividend = dividend * dividend;
+            }
+            else
+            {
+               afterdelim = true;
+            }
+            
+            factor = 1.;
+            
+            cptr++;
+            
+            // skip any leading zeroes after delimiter */
+            
+            while (*cptr == '0')
+            {
+               cptr++;
+            }
+            
+            break;
+         }
+
+         //---
+         //  check for a delimiter that is allowable:
+         // isspace allows: space, tab, cr, nl, vt, ff
+         // ispunct allows: punctuation char != space or control or letter
+         //---
+         default: 
+         {
+            if(isspace(*cptr) || 
+               ispunct(*cptr) || 
+               ((ossim_uint8)(*cptr) == theDegreeSign))
+            {
+               *cptr = ' ';
+            }
+            else
+            {
+               status = false;
+               ++cptr;
+            }
+         }
+         
+      }	// end switch
+
+      if (status == false)
+      {
+         break;
+      }
+      
+   } //  end while loop
+
+   // add any units that may have been calculated (minutes or seconds)
+   degrees     = degrees + units;
+   
+   theDegrees = (degrees * (double)theSign);
+   
+   return status;
+}
+
+ossimString ossimDms::toString(const ossimString& formatString)const
+{
+   ossimString result="";
+   ossimString::const_iterator stringIter;
+   ossimString tempFormatString = formatString;
+   if(formatString == ossimString(""))
+   {
+      tempFormatString = ossimDms::DEFAULT_FORMAT;
+   }
+
+   stringIter = tempFormatString.begin();
+   int i, d_s;
+   
+/* assign a default format if none is given */
+      
+   init_values(theDegrees);
+   
+   while(stringIter != tempFormatString.end())
+   {
+      switch(*stringIter)
+      {
+          case '-':
+          {
+             result +=(theWorking < 0.0) ? ('-') : (' ');
+             stringIter++;
+             break;
+	   }
+
+	   case 'c':
+      case 'C':
+      {
+         char temp;
+         if (theWorking < 0.0)
+         {
+            temp = (theLatFlag == true) ? ('S') : ('W');
+         }
+         else
+         {
+            temp= (theLatFlag == true) ? ('N') : ('E');
+         }
+
+         if(*stringIter == 'c')
+         {
+            temp = tolower(temp);
+         }
+            result += temp;
+         stringIter++;
+         break;
+      }
+
+	   case 'd':
+	   case 'D': {			/* how many 'd's until not 'd' */
+	   	d_s = 1, stringIter++;
+	   	while (*stringIter == 'd' || *stringIter == 'D')
+                {
+		   d_s++, stringIter++;
+	   	}
+		if (theAfterDot == true)
+                {		/* beyond the decimal point */
+		   i = d_s;
+		   while (i-- > 0)
+                   {
+                      theDecDegs = theDecDegs * 10.0;
+                   }
+//		   theIntDegs = (int)(theDecDegs + 0.5);
+		   theIntDegs = (int)(theDecDegs);
+		 }
+
+                // fill the rest with blanks
+                ossimString temp = ossimString::toString(theIntDegs);
+                d_s -= temp.length();
+                if(d_s>0)
+                {
+                   if(theAfterDot)
+                   {
+                      
+                      while(d_s > 0)
+                      {
+                         temp+='0';
+                         --d_s;
+                      }
+                   }
+                   else
+                   {
+                      ossimString prefix;
+                      while(d_s > 0)
+                      {
+                         prefix += '0';
+                         --d_s;
+                      }
+                      temp = prefix + temp;
+                   }
+                }
+                result += temp;
+
+                break;
+	   }
+ 
+	   case ' ':
+           {			
+              result += *stringIter;
+              
+              while (*stringIter == ' ')
+              {
+                 result += *stringIter;
+                 stringIter++;
+              }
+              break;
+	   }
+
+	   case '.': 
+           {
+              theAfterDot = true;              
+              result +=  *stringIter++;
+              break;
+	   }
+
+         case 'm':
+         case 'M':
+         case 's':
+         case 'S':
+         {
+            if((*stringIter == 's') ||
+               (*stringIter == 'S'))
+            {
+               theDoingSeconds = true;
+            }
+            
+            calc_mins_or_secs(&theDecDegs, stringIter, result);
+            break;
+         }
+
+           // This is code that I added so you can do additional
+           // formatting.
+           //
+         case '\'':
+         case '"':
+         {
+            result += *stringIter++;
+            break;
+         }
+         case '@':
+         {
+            result += (char)theDegreeSign;
+            stringIter++;
+            break;
+         }
+         default:
+         {
+            if(theDoingSeconds)
+            {
+               theAfterDot = true;
+            }
+            result += *stringIter++;
+	   }
+	 }	/* end switch statement */
+	}	/* end while loop */
+
+	return result;   
+}
+
+// The functions that follow are all dts stuff
+
+ossimString ossimDms::degree_to_string(double degrees,
+                                       char format[],
+                                       bool lat_flag)const
+{
+   char cdegrees[64];
+   char str_fmt[10];
+   char *rptr, *fptr, *sptr;
+   int i, d_s;
+   
+/* assign a default format if none is given */
+   
+   if (format[0] == '\0')
+   {
+      set_default(format, cdegrees);
+   }
+   else
+   {
+      memset(cdegrees, ' ', 64);
+//       strcpy(cdegrees, SPACES);
+   }
+   
+   init_values(degrees);
+   
+   rptr = cdegrees;
+   fptr = format;
+   sptr = str_fmt;
+   
+/* cycle through characters of the format and plug in values */
+   
+   while (*fptr != '\0') {
+      
+	 switch (*fptr) {
+
+	   case '-': {
+		(theWorking < 0.0) ? (*rptr = '-') : (*rptr = ' ');
+		rptr++, fptr++;
+		break;
+	   }
+
+	   case 'c':
+	   case 'C': {
+		if (theWorking < 0.0)
+		   (lat_flag == true) ? (*rptr = 'S') : (*rptr = 'W');
+		else
+		   (lat_flag == true) ? (*rptr = 'N') : (*rptr = 'E');
+		
+		rptr++, fptr++;
+		break;
+	   }
+
+	   case 'd':
+	   case 'D': {			/* how many 'd's until not 'd' */
+	   	d_s = 1, fptr++;
+	   	while (*fptr == 'd') {
+		   d_s++, fptr++;
+	   	}
+		setup_printf(d_s, sptr);	/* printf's fmt will be %x.xd */
+
+		if (theAfterDot == true) {		/* beyond the decimal point */
+		   i = d_s;
+		   while (i-- > 0)
+			theDecDegs = theDecDegs * 10.0;
+//		   theIntDegs = (int)(theDecDegs + 0.5);
+		   theIntDegs = (int)(theDecDegs);
+		 }
+
+		sprintf(rptr, str_fmt, theIntDegs);
+
+		if (*rptr == '0' && !theAfterDot)	/* remove leading zero */
+		   *rptr = ' ';
+	   	rptr += d_s;
+		break;
+	   }
+
+	   case ' ': {			/* compress multiple spaces in format */
+		*rptr = *fptr;
+		while (*fptr == ' ')
+			fptr++;
+		rptr++;
+		break;
+	   }
+
+	   case '.': {
+		if (theAfterDot == true) {		/* a second decimal point? */
+		   set_default(format, cdegrees);
+		   fptr = format;
+		   rptr = cdegrees;
+		   init_values(degrees);
+		}
+		else {
+		   *rptr = *fptr;
+		   rptr++, fptr++;
+		   theAfterDot = true;
+		}
+		break;
+	   }
+
+         case 'm':
+         case 'M':
+         case 's':
+         case 'S':
+         {
+		i = calc_mins_or_secs(&theDecDegs, fptr, rptr);
+		fptr += i, rptr += i;		/* i == num to advance format */
+		break;
+	   }
+
+           // This is code that I added so you can do additional
+           // formatting.
+           //
+         case '\'':
+         case '"':
+         {
+            *rptr = *fptr;
+            rptr++;
+            fptr++;
+            break;
+         }
+         case '@':
+         {
+            *rptr = (char)theDegreeSign;
+            rptr++;
+            fptr++;
+            break;
+         }
+	   default: {
+		set_default(format, cdegrees);
+		fptr = format;
+		rptr = cdegrees;
+		init_values(degrees);
+	   }
+	 }	/* end switch statement */
+
+	}	/* end while loop */
+
+	*rptr = '\0';
+	return(cdegrees);
+}
+
+
+void ossimDms::calc_mins_or_secs(double *dd,
+                            ossimString::const_iterator &formatIter,
+                            ossimString &result)const
+{
+	double du;
+	int ufactor, ires, numunits;
+	char unit;
+
+	unit = *formatIter;			/* set to 'm' or 's' */
+
+	ufactor = 1, numunits = 0;
+
+/* count minutes (or seconds) desired in this part of format */
+
+	while (*formatIter == unit)
+        {
+	   numunits++;
+	   formatIter++, ufactor *= 10;
+	}
+
+/* different calc based on beyond decimal pt or not */
+
+	if (theAfterDot == true)
+        {
+	   du = *dd * (double)ufactor;
+//	   ires = (int)(du + 0.5);
+	   ires = (int)(du);
+	   *dd = (du - ires);
+           if(*dd < 0.0) *dd = 0.0;
+	}
+	else
+        {
+	   du = (*dd * 60.0) * (double)ufactor;
+//	   ires = (int)(du + 0.5) / ufactor;
+	   ires = (int)(du) / ufactor;
+	   *dd = (du - (ires * ufactor)) / (double)ufactor;
+           if(*dd < 0.0) *dd = 0.0;
+	}
+        ostringstream out;
+        
+        out << setw(numunits)
+            << setfill('0')
+            << setiosflags(ios::right)
+            << setprecision(numunits)
+            << ires
+            << ends;
+        result+=out.str().c_str();
+        
+
+//        result += ossimString::toString(ires);
+}
+
+/****************************************************************
+ * integer function calc_mins_or_secs				*
+ *	calculates minutes from degrees, seconds from minutes,	*
+ *	based on "format", returning the resultant string	*
+ *	in "res".  "dd" is the part of 'degrees' that provides	*
+ *	the value to manipulate.  the integer returned as the 	*
+ *	value of this function is the number of places in the 	*
+ *	format that have been parsed here, to be used in the	*
+ *	main function to advance the format-parsing pointer.	*
+ ****************************************************************/
+
+
+int ossimDms::calc_mins_or_secs(double *dd,
+                                char *format,
+                                char *res)const
+{
+	double du;
+	int ufactor, ires, numunits;
+	char unit, str_fmt[8];
+
+	unit = *format;			/* set to 'm' or 's' */
+
+	ufactor = 1, numunits = 0;
+
+/* count minutes (or seconds) desired in this part of format */
+
+	while (*format == unit) {
+	   numunits++;
+	   format++, ufactor *= 10;
+	}
+
+/* different calc based on beyond decimal pt or not */
+
+	if (theAfterDot == true) {
+	   du = *dd * (double)ufactor;
+//	   ires = (int)(du + 0.5);
+	   ires = (int)(du + 0.5);
+	   *dd = (du - ires);
+	}
+	else {
+	   du = (*dd * 60.0) * (double)ufactor;
+//	   ires = (int)(du + 0.5) / ufactor;
+	   ires = (int)(du) / ufactor;
+	   *dd = (du - (ires * ufactor)) / (double)ufactor;
+	}
+	setup_printf(numunits, str_fmt);
+	sprintf(res, str_fmt, ires);
+        
+	return(numunits);
+}
+
+/****************************************************************
+ * function setup_printf					*
+ * 	the C library function sprintf takes as its second 	*
+ * 	argument, a format specifier.  this function constructs	*
+ *	that specifier based on 'ival', an integer indicating	*
+ *	the number of d's or m's or s's seen in the group	*
+ *	just parsed.						*
+ ****************************************************************/
+
+void ossimDms::setup_printf(int ival, char *fmt)const
+{
+	char precis[3];
+	
+	strcpy(fmt, "%");
+	sprintf(precis, "%d", ival);
+	strcat(fmt,precis);
+	strcat(fmt,".");
+	strcat(fmt,precis);
+	strcat(fmt,"d");
+}
+
+/****************************************************************
+ * function set_default						*
+ *	assigns a default format to be used as the template for	*
+ *	the conversion of the double precision value, degrees.	*
+ *	either an error was detected in parsing the format that	*
+ *	the user entered, or no format was entered at all.	*
+ *	also, clears the result string of any characters which	*
+ *	may have been placed therein prior to the call here.	*
+ ****************************************************************/
+
+ 
+void ossimDms::set_default(char *fp, char *rp)const
+{
+	strcpy(fp, DEFAULT_FORMAT); 	/* assign default format */
+	strcpy(rp, SPACES);
+
+}
+
+/****************************************************************
+ * function init_values						*
+ *	initializes the global values used throughout the	*
+ *	function.  see notes in header file.			*
+ ****************************************************************/
+
+void ossimDms::init_values(double d)const
+{
+
+   theAfterDot     = false;
+   theDoingSeconds = false;
+   theSign = 1;
+   if (d < 0.0)
+      theSign = -1;
+   
+   theWorking = d;
+   theIntDegs = (int)theWorking * theSign;
+   theDecDegs = (theWorking  * theSign) - theIntDegs;
+   
+   return;
+}
+
+
+/************************************************************************
+ * double function string_to_degree					*
+ *									*
+ *	requires:	dts.h					*
+ *	input:		string variable	parameter			*
+ *	returns:	double precision number				*
+ *									*
+ *	purpose: to calculate a double precision number, representing	*
+ *	degrees latitude or longitude, given a string "cdegrees".	*
+ *	valid input consists of the following characters:		*
+ *									*
+ *		+, -, N, n, S, s, E, e, W, w -- direction indicators	*
+ *		any digit [0-9]						*
+ *		a decimal point, '.' -- says decimal degrees follow	*
+ *		an ascii delimiter, for example ' ', TAB, '/' to	*
+ *		   indicate that either minutes or seconds follow.	*
+ *									*
+ *	output is a double precision number, which will be either	*
+ *	latitude or longitude degrees and decimal degrees		*
+ *									*
+ * written as part of the DIAL facility, G&G, WHOI			*
+ * April 1992								*
+ * Christine L. Hammond							*
+ ************************************************************************/
+
+
+
+double ossimDms::string_to_degree(char *cdegrees)
+{
+	double degrees, factor, dividend, units;
+	int i;
+        bool afterdelim;
+	char *cptr, c;
+
+	theAfterDot = false;
+	afterdelim = false;
+	cptr = cdegrees;
+	degrees = 0.0;
+	units = 0.0;
+	factor = 1.0;
+	dividend = 60.0;
+	theSign = 1;
+
+/* get rid of leading spaces */
+
+	while (*cptr == ' ')
+	   cptr++;
+
+	while(*cptr != '\0') {
+
+	   switch (*cptr) {
+
+/* north, west and + values will change sign of degrees to plus */
+
+	     case '+':
+	     case 'n':
+	     case 'N':
+	     case 'e':
+	     case 'E': 
+	       {
+		 if(toupper(*cptr) == 'N')
+		   {
+		     theLatFlag = true;
+		   }
+		 else if(toupper(*cptr) == 'E')
+		   {
+		     theLatFlag = false;
+		   }
+		theSign = 1;
+		cptr++;
+		break;
+	       }
+
+/* south, east and - values will change sign of degrees to minus */
+
+	     case '-':
+	     case 's':
+	     case 'S':
+	     case 'w':
+	     case 'W': 
+	       {
+		 if(toupper(*cptr) == 'S')
+		   {
+		     theLatFlag = true;
+		   }
+		 else if(toupper(*cptr) == 'W')
+		   {
+		     theLatFlag = false;
+		   }
+		theSign = -1;
+		cptr++;
+		break;
+	     }
+
+	     case '0':
+	     case '1':
+	     case '2':
+	     case '3':
+	     case '4':
+	     case '5':
+	     case '6':
+	     case '7':
+	     case '8':
+	     case '9': {
+		c = *cptr;
+		i = (c - '0');
+
+		if (afterdelim == true) {
+
+		   if (theAfterDot == true) 
+			units = units + (((double)i * factor) / dividend);
+		   else
+			units = (units * factor) + ((double)i / dividend);
+		}
+		else {
+
+		   if (theAfterDot == true)
+			degrees = degrees + ((double)i * factor);
+		   else
+			degrees = (degrees * factor) + (double)i;
+		}
+
+		if (theAfterDot == true) 
+		   factor = factor * .10;
+		else
+		   factor = 10.;
+
+		cptr++;
+		break;
+	     }
+
+/* a decimal point indicates a change in the factor used */
+/* to calculate degrees or units (minutes or seconds)    */
+
+           case '.':
+           {
+              factor = .10;
+              theAfterDot = true;
+              cptr++;
+              break;
+           }
+
+/* after a delimiter the value contains minutes, first time through */
+
+	     case ' ': {
+
+		while (*(cptr + 1) == ' ') 
+		   cptr++;
+
+		degrees = degrees + units;
+		units = 0.0;
+
+		if (afterdelim == true) 	/* must be seconds */
+		   dividend = dividend * dividend;
+		else 
+		   afterdelim = true;
+
+		factor = 1.;
+
+		cptr++;
+
+/* skip any leading zeroes after delimiter */
+
+		while (*cptr == '0')
+			cptr++;
+
+		break;
+	     }
+
+/* check for a delimiter that is allowable:
+   	isspace allows: space, tab, cr, nl, vt, ff
+   	ispunct allows: punctuation char != space or control or letter */
+
+	     default: {
+		if (isspace(*cptr) || ispunct(*cptr))
+		   *cptr = ' ';
+	     }
+
+	  }	/* end switch */
+
+	}	/* end while loop */
+
+/* add any units that may have been calculated (minutes or seconds) */
+
+	degrees = degrees + units;
+
+	return(degrees * (double)theSign);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDms.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimDms.h
new file mode 100644
index 0000000000..111f036812
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDms.h
@@ -0,0 +1,209 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class definition for Degrees Minutes Seconds (ossimDms)
+//*******************************************************************
+//  $Id: ossimDms.h,v 1.12 2005/07/18 11:06:00 gpotts Exp $
+#ifndef ossimDms_HEADER
+#define ossimDms_HEADER
+#include <iostream>
+using namespace std;
+
+#include <base/data_types/ossimString.h>
+
+class OSSIMDLLEXPORT ossimDms
+{
+public:
+   friend ostream& operator << (ostream& out, const ossimDms &dms);
+
+
+   /*!
+    *
+    * Constructor ossimDms(double, bool)
+    *
+    * You can construct a DMS class with a decimal
+    * degree and specify if its for the lat or lon.
+    *
+    * latFlag          true   its for the lat
+    *                  false  its for the lon
+    *
+    */
+   ossimDms(double someDegrees, bool latFlag = true);
+
+   /*!
+    *` Constructor.  You can specify the value in a formated
+    *  string.  Example:
+    *  "45N"     will set the decimal degree to 45 and will
+    *            set the lat flag to true
+    *
+    *  "45W"     will set the internal degree to negative and
+    *            set the lat flag to false.
+    */
+   ossimDms(char *value);
+
+   /*!
+    *  You can specify a number of different formats.
+    *  special characters:
+    *
+    *      @    is replaced with a degree character.
+    *      '    minutes character
+    *      "    seconds character
+    *      d    replaced with degree portion
+    *      m    replaced with minute portion
+    *      s    replaced with second portion
+    *      c or C replaces with N/S or E/W
+    *
+    *  examples for format string
+    *
+    *
+    */
+   ossimString toString(const ossimString& formatString=ossimString(""))const;
+
+   double getDegrees() const { return theDegrees; }
+   bool   getLatFlag() const { return theLatFlag; }
+
+   /*!
+    * setDegrees(char*).  Will allow you to set the internal
+    * paramters through a string.  examples:
+    *
+    * "45 5 6"  will assume degrees minutes seconds
+    * "45"      will assume degrees.
+    * "-45"
+    * "4e5W"
+    *
+    * @return true on success, false if unhandled characters are found.
+    */
+   bool setDegrees(const char *value);
+   
+   ossimDms& setDegrees(double degrees);
+
+   ossimDms& setLatFlag(bool latFlag){theLatFlag = latFlag;return *this;}
+   static const ossim_uint8 theDegreeSign;
+   
+private:
+   static char *DEFAULT_FORMAT;
+   static char *SPACES;
+   
+   double theDegrees;
+   bool   theLatFlag;
+   
+   // This is a port of the dts written by Christine Hammond
+   // into the OSSIM dms class.  We will use this to aid in
+   // formatting DMS data.
+   mutable double theDecDegs;/* decimal part of degrees */
+   mutable bool   theAfterDot;/* decimal values flag */
+   mutable bool   theDoingSeconds;
+   mutable int    theIntDegs;/* integer part of double degrees */
+   mutable int    theSign;/* what sign is degrees */
+   mutable double theWorking;/* degrees value to use during calc */
+
+   /*!
+    *  char * function degree_to_string
+    *					
+    *	requires:	dts.h		
+    *	input:		double precision, string, integer params
+    *	returns:	pointer to a string
+    *									
+    *	purpose:  to convert a double precision number  "degrees"
+    *	to a character string based on the input "format" and a
+    *	flag indicating whether or not the degrees are latitude. 
+    *	If 'lat_flag' is TRUE, then degrees are latitude, otherwise
+    *	they are longitude.	default format: ddd mm.mmC 	
+    *									
+    *	returns:  a pointer to a string which contains the formatted
+    *	degree value.  							
+    *									
+    * written as part of the DIAL facility, G&G, WHOI 
+    * April 1992   	
+    * Christine L. Hammond						       
+    ************************************************************************/
+
+   ossimString degree_to_string(double degrees,
+                                char format[],
+                                bool lat_flag)const;
+   
+   void calc_mins_or_secs(double *dd,
+                          ossimString::const_iterator &formatIter,
+                          ossimString &result)const;
+      /*!
+    * integer function calc_mins_or_secs				*
+    *	calculates minutes from degrees, seconds from minutes,	
+    *	based on "format", returning the resultant string	
+    *	in "res".  "dd" is the part of 'degrees' that provides	
+    *	the value to manipulate.  the integer returned as the 	
+    *	value of this function is the number of places in the 	
+    *	format that have been parsed here, to be used in the	
+    *	main function to advance the format-parsing pointer. 
+    */
+
+   int calc_mins_or_secs(double *dd,
+                         char *format,
+                         char *res)const;
+   
+   /*!
+    * function setup_printf
+    * 	the C library function sprintf takes as its second
+    * 	argument, a format specifier.  this function constructs
+    *	that specifier based on 'ival', an integer indicating
+    *	the number of d's or m's or s's seen in the group
+    *	just parsed.
+    */
+   void setup_printf(int ival, char *fmt)const;
+
+   /*!
+    * function set_default						*
+    *	assigns a default format to be used as the template for	
+    *	the conversion of the double precision value, degrees.	
+    *	either an error was detected in parsing the format that	
+    *	the user entered, or no format was entered at all.	
+    *	also, clears the result string of any characters which	
+    *	may have been placed therein prior to the call here.	
+    */
+   void set_default(char *fp, char *rp)const;
+
+   /*!
+    * function init_values
+    *	initializes the global values used throughout the
+    *	function.  see notes in header file.
+    */
+   void init_values(double d)const;
+
+   /*!
+    * double function string_to_degree
+    *
+    *	requires:	dts.h
+    *	input:		string variable	parameter
+    *	returns:	double precision number
+    *									
+    *	purpose: to calculate a double precision number, representing
+    *	degrees latitude or longitude, given a string "cdegrees".
+    *	valid input consists of the following characters:
+    * 
+    *		+, -, N, n, S, s, E, e, W, w -- direction indicators	
+    *		any digit [0-9]						
+    *		a decimal point, '.' -- says decimal degrees follow
+    *		an ascii delimiter, for example ' ', TAB, '/' to 
+    *		   indicate that either minutes or seconds follow.
+    * 
+    *	output is a double precision number, which will be either
+    *	latitude or longitude degrees and decimal degree
+    *
+    * written as part of the DIAL facility, G&G, WHOI 
+    * April 1992 
+    * Christine L. Hammond 
+    */
+
+   
+   double string_to_degree(char *cdegrees);
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt.cpp
new file mode 100644
index 0000000000..a87ef83259
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt.cpp
@@ -0,0 +1,232 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+// 
+// Description:
+// Contains class definitions for ossimDpt.
+// 
+//*******************************************************************
+//  $Id: ossimDpt.cpp,v 1.7 2005/12/16 14:25:11 dburken Exp $
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDpt3d.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimFpt.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimString.h>
+
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimDpt::ossimDpt(const ossimFpt& pt)
+   :
+      x(pt.x), y(pt.y)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+ }
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimDpt::ossimDpt(const ossimIpt& pt)
+   :
+      x(pt.x), y(pt.y)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimDpt::ossimDpt(const ossimDpt3d &pt)
+   :
+      x(pt.x), y(pt.y)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimDpt::ossimDpt(const ossimGpt &pt)
+   :
+      x(pt.lon), y(pt.lat)
+{
+   if(pt.isLatNan() || pt.isLonNan())
+   {
+      makeNan();
+   }
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+const ossimDpt& ossimDpt::operator=(const ossimFpt& pt)
+{
+   x = pt.x;
+   y = pt.y;
+   
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   return *this;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+const ossimDpt& ossimDpt::operator=(const ossimIpt& pt)
+{
+   x = pt.x;
+   y = pt.y;
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   
+   return *this;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+const ossimDpt& ossimDpt::operator=(const ossimDpt3d& pt)
+{
+   x = pt.x;
+   y = pt.y;
+   
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   
+   return *this;
+}
+
+const ossimDpt& ossimDpt::operator=(const ossimGpt& pt)
+{
+   x = pt.lon;
+   y = pt.lat;
+   return *this;
+}
+
+std::ostream& ossimDpt::print(std::ostream& os, ossim_uint32 precision) const
+{
+   os << std::setiosflags(std::ios::fixed) << std::setprecision(precision)
+      << "( ";
+
+   if (x != OSSIM_DBL_NAN)
+   {
+      os << x;
+   }
+   else
+   {
+      os << "nan";
+   }
+   
+   os << ", ";
+
+   if (y != OSSIM_DBL_NAN)
+   {
+      os << y;
+   }
+   else
+   {
+      os << "nan";
+   }
+
+   os << " )";
+
+   return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const ossimDpt& pt)
+{
+   return pt.print(os);
+}
+
+ossimString ossimDpt::toString(ossim_uint32 precision) const
+{
+   std::ostringstream os;
+   print(os, precision);
+   return ossimString(os.str());
+}
+
+std::istream& operator>>(std::istream& is, ossimDpt &pt)
+{
+   //---
+   // Expected input format:
+   // ( 30.00000000000000, -90.00000000000000 )
+   //   --------x--------  ---------y--------
+   //---
+
+   // Start with a nan point.
+   pt.makeNan();
+
+   // Check the stream.
+   if (!is) return is;
+
+   const int SZ = 64; // Real big number with 15 digit precision.
+   ossimString tempString;
+   char tempChars[SZ];
+   char c;
+
+   // Gobble the "(".
+   is >> tempString;
+   if (!is) return is;
+   
+   // Get the x.
+   is.get(tempChars, SZ, ',');
+   if (!is) return is;
+   tempChars[SZ-1] = '\0';
+   tempString = tempChars;
+   tempString.trim();
+   if (tempString == "nan")
+   {
+      pt.x = OSSIM_DBL_NAN;
+   }
+   else
+   {
+      pt.x = tempString.toDouble();
+   }
+
+   // Eat the ",".
+   is.get(c);
+   
+   // Get the y.
+   is >> tempString;
+   tempString.trim();
+   if (tempString == "nan")
+   {
+      pt.y = OSSIM_DBL_NAN;
+   }
+   else
+   {
+      pt.y = tempString.toDouble();
+   }
+
+   // Gobble the trailing ")".
+   is >> tempString;
+
+   // Finished
+   return is;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt.h
new file mode 100644
index 0000000000..b5d1a63347
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt.h
@@ -0,0 +1,153 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimDpt.
+// Used to represent an double point containing an x and y data member.
+// 
+//*******************************************************************
+//  $Id: ossimDpt.h,v 1.11 2005/12/16 14:25:11 dburken Exp $
+#ifndef ossimDpt_HEADER
+#define ossimDpt_HEADER
+#include <iostream>
+#include <cmath>
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+
+// Forward class declarations.
+class OSSIMDLLEXPORT ossimIpt;
+class OSSIMDLLEXPORT ossimFpt;
+class OSSIMDLLEXPORT ossimDpt3d;
+class OSSIMDLLEXPORT ossimGpt;
+class OSSIMDLLEXPORT ossimString;
+
+class OSSIMDLLEXPORT ossimDpt
+{
+public:
+
+   ossimDpt() : x(0), y(0) {}
+
+   ossimDpt(double anX, double aY) : x(anX), y(aY) {}
+         
+   ossimDpt(const ossimDpt& pt) : x(pt.x), y(pt.y) {}
+
+   ossimDpt(const ossimFpt& pt);
+   
+   ossimDpt(const ossimIpt& pt);
+
+   ossimDpt(const ossimDpt3d &pt);
+
+   ossimDpt(const ossimGpt &pt); // assigns lat, lon only
+
+   const ossimDpt& operator=(const ossimDpt&);
+
+   const ossimDpt& operator=(const ossimFpt&);
+   
+   const ossimDpt& operator=(const ossimIpt&);
+
+   const ossimDpt& operator=(const ossimDpt3d&);
+
+   const ossimDpt& operator=(const ossimGpt&); // assigns lat, lon only
+
+   bool operator==(const ossimDpt& pt) const
+      { return ( (x == pt.x) && (y == pt.y) ); } 
+
+   bool operator!=(const ossimDpt& pt) const
+      { return ( (x != pt.x) || (y != pt.y) ); }
+
+   void makeNan(){x = OSSIM_DBL_NAN; y=OSSIM_DBL_NAN;}
+   
+   bool hasNans()const
+      {
+         return (ossimIsNan(x) || ossimIsNan(y));
+      }
+
+   bool isNan()const
+      {
+         return (ossimIsNan(x) && ossimIsNan(y));
+      }
+   /*!
+    * METHOD: length()
+    * Returns the RSS of the components.
+    */
+   double length() const { return sqrt(x*x + y*y); }
+   
+   //***
+   // OPERATORS: +, -, +=, -=
+   // Point add/subtract with other point:
+   //***
+   ossimDpt operator+(const ossimDpt& p) const
+      { return ossimDpt(x+p.x, y+p.y); }
+   ossimDpt operator-(const ossimDpt& p) const
+      { return ossimDpt(x-p.x, y-p.y); }
+   const ossimDpt& operator+=(const ossimDpt& p)
+      { x += p.x; y += p.y; return *this; }
+   const ossimDpt& operator-=(const ossimDpt& p)
+      { x -= p.x; y -= p.y; return *this; }
+
+   //***
+   // OPERATORS: *, /
+   // Scale point components by scalar:
+   //***
+   ossimDpt operator*(const double& d) const
+      { return ossimDpt(d*x, d*y); }
+   ossimDpt operator/(const double& d) const
+      { return ossimDpt(x/d, y/d); }
+
+   std::ostream& print(std::ostream& os, ossim_uint32 precision=15) const;
+   
+   friend OSSIMDLLEXPORT std::ostream& operator<<(std::ostream& os,
+                                                  const ossimDpt& pt);
+
+   /**
+    * @param precision Output floating point precision.
+    * 
+    * @return ossimString representing point.
+    *
+    * Output format:  ( 30.00000000000000, -90.00000000000000 )
+    *                   --------x--------  ---------y--------
+    */
+   ossimString toString(ossim_uint32 precision=15) const;
+
+   /**
+    * Method to input the formatted string of the "operator<<".
+    *
+    * Expected format:  ( 30.00000000000000, -90.00000000000000 )
+    *                     --------x--------  ---------y--------
+    * 
+    * This method starts by doing a "makeNan" on pt.  So if anything goes
+    * wrong with the stream or parsing pt could be all or partially nan.
+    *
+    * @param is Input stream istream to formatted text.
+    * @param pt osimDpt to be initialized from stream.
+    * @return istream pass in.
+    */
+   friend OSSIMDLLEXPORT std::istream& operator>>(std::istream& is,
+                                                  ossimDpt& pt);
+   
+   //***
+   // Public data members:
+   //***
+   union {double x; double samp; double u; double lon;};
+   union {double y; double line; double v; double lat;};
+
+};
+
+inline const ossimDpt& ossimDpt::operator=(const ossimDpt& pt)
+{
+   if (this != &pt)
+   {
+      x = pt.x;
+      y = pt.y;
+   }
+   
+   return *this;
+}
+
+#endif /* #ifndef ossimDpt_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt3d.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt3d.cpp
new file mode 100644
index 0000000000..1b024e6571
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt3d.cpp
@@ -0,0 +1,26 @@
+#include "ossimDpt3d.h"
+#include "ossimIpt.h"
+#include "ossimDpt.h"
+
+
+ossimDpt3d::ossimDpt3d(const ossimDpt &aPt)
+   :x(aPt.x),
+    y(aPt.y),
+    z(0)
+{
+   if(aPt.isNan())
+   {
+      makeNan();
+   }
+}
+
+ossimDpt3d::ossimDpt3d(const ossimIpt &aPt)
+   :x(aPt.x),
+    y(aPt.y),
+    z(0)
+{
+   if(aPt.isNan())
+   {
+      makeNan();
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt3d.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt3d.h
new file mode 100644
index 0000000000..447a9e7863
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDpt3d.h
@@ -0,0 +1,113 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+// Description:  
+//
+// Contains class declaration for dpt3d
+// Used to represent a 3d double point containing an x, y and z data member.
+//*******************************************************************
+//  $Id: ossimDpt3d.h,v 1.5 2002/11/25 18:59:54 gpotts Exp $
+
+#ifndef ossimDpt3d_HEADER
+#define ossimDpt3d_HEADER
+#include <iostream>
+#include <iomanip>
+#include <math.h>
+
+#include "ossimString.h"
+#include "ossimDpt.h"
+#include "ossimColumnVector3d.h"
+
+class OSSIMDLLEXPORT ossimDpt3d
+{
+public:
+   friend inline std::ostream & operator << (std::ostream &out, const ossimDpt3d &rhs);
+   ossimDpt3d(const double &aX=0, const double &aY=0, const double &aZ=0)
+      :x(aX), y(aY), z(aZ) {}
+
+   ossimDpt3d(const ossimDpt &aPt);
+   ossimDpt3d(const ossimIpt &aPt);
+   
+   ossimDpt3d(const ossimColumnVector3d &pt)
+      : x(pt[0]), y(pt[1]), z(pt[2]) {}
+   
+   bool operator ==(const ossimDpt3d &rhs) const
+      {
+         return ( (x == rhs.x) &&
+                  (y == rhs.y) &&
+                  (z == rhs.z));
+      }
+   bool operator !=(const ossimDpt3d &rhs) const
+      {
+         return ( (x != rhs.x) ||
+                  (y != rhs.y) ||
+                  (z != rhs.z) );
+      }
+
+   void makeNan(){x = OSSIM_DBL_NAN; y=OSSIM_DBL_NAN; z=OSSIM_DBL_NAN;}
+
+   bool hasNans()const
+      {
+         return (ossimIsNan(x) || ossimIsNan(y) || ossimIsNan(z));
+      }
+   /*!
+    * METHOD: length()
+    * Returns the RSS of the components.
+    */
+   double length() const { return sqrt(x*x + y*y + z*z); }
+   
+   //***
+   // OPERATORS: +, -, +=, -=
+   // Point add/subtract with other point:
+   //***
+   ossimDpt3d operator+(const ossimDpt3d& p) const
+      { return ossimDpt3d(x+p.x, y+p.y, z+p.z); }
+   ossimDpt3d operator-(const ossimDpt3d& p) const
+      { return ossimDpt3d(x-p.x, y-p.y, z-p.z); }
+   const ossimDpt3d& operator+=(const ossimDpt3d& p)
+      { x += p.x; y += p.y; z += p.z; return *this; }
+   const ossimDpt3d& operator-=(const ossimDpt3d& p)
+      { x -= p.x; y -= p.y; z -= p.z; return *this; }
+
+   //***
+   // OPERATORS: *, /
+   // Scale point components by scalar:
+   //***
+   ossimDpt3d operator*(const double& d) const
+      { return ossimDpt3d(d*x, d*y, d*z); }
+   ossimDpt3d operator/(const double& d) const
+      { return ossimDpt3d(x/d, y/d, z/d); }
+   
+   double x;
+   double y;
+   double z;
+};
+
+inline std::ostream &operator << (std::ostream &out, const ossimDpt3d &rhs)
+{
+   return out << std::setiosflags(std::ios::fixed)
+              << std::setprecision(15)
+              << (rhs.x==OSSIM_DBL_NAN?ossimString("nan"):ossimString::toString(rhs.x))
+              << " "
+              << (rhs.y==OSSIM_DBL_NAN?ossimString("nan"):ossimString::toString(rhs.y))
+              << " "
+              << (rhs.z ==OSSIM_DBL_NAN?ossimString("nan"):ossimString::toString(rhs.z))<< endl;
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDrect.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimDrect.cpp
new file mode 100644
index 0000000000..9a167d7377
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDrect.cpp
@@ -0,0 +1,736 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for ossimDrect.
+//*******************************************************************
+//  $Id: ossimDrect.cpp,v 1.34 2005/07/15 18:51:25 dburken Exp $
+
+#include <iostream>
+using namespace std;
+
+#include "ossimDrect.h"
+#include "ossimIrect.h"
+#include "ossimPolygon.h"
+
+#define d_MIN(a,b)      (((a)<(b)) ? a : b)
+#define d_MAX(a,b)      (((a)>(b)) ? a : b)
+
+static int
+clip_1d (double *x0, 
+	 double *y0, 
+	 double *x1, 
+	 double *y1, 
+	 double maxdim)
+{
+  double m;			/* gradient of line */
+  if (*x0 < 0)
+    {				/* start of line is left of window */
+      if (*x1 < 0)		/* as is the end, so the line never cuts the window */
+	return 0;
+      m = (*y1 - *y0) / (double) (*x1 - *x0);	/* calculate the slope of the line */
+      /* adjust x0 to be on the left boundary (ie to be zero), and y0 to match */
+      *y0 -= m * *x0;
+      *x0 = 0;
+      /* now, perhaps, adjust the far end of the line as well */
+      if (*x1 > maxdim)
+	{
+	  *y1 += m * (maxdim - *x1);
+	  *x1 = maxdim;
+	}
+      return 1;
+    }
+  if (*x0 > maxdim)
+    {				/* start of line is right of window -
+				   complement of above */
+      if (*x1 > maxdim)		/* as is the end, so the line misses the window */
+	return 0;
+      m = (*y1 - *y0) / (double) (*x1 - *x0);	/* calculate the slope of the line */
+      *y0 += m * (maxdim - *x0);	/* adjust so point is on the right
+					   boundary */
+      *x0 = maxdim;
+      /* now, perhaps, adjust the end of the line */
+      if (*x1 < 0)
+	{
+	  *y1 -= m * *x1;
+	  *x1 = 0;
+	}
+      return 1;
+    }
+  /* the final case - the start of the line is inside the window */
+  if (*x1 > maxdim)
+    {				/* other end is outside to the right */
+      m = (*y1 - *y0) / (double) (*x1 - *x0);	/* calculate the slope of the line */
+      *y1 += m * (maxdim - *x1);
+      *x1 = maxdim;
+      return 1;
+    }
+  if (*x1 < 0)
+    {				/* other end is outside to the left */
+      m = (*y1 - *y0) / (double) (*x1 - *x0);	/* calculate the slope of the line */
+      *y1 -= m * *x1;
+      *x1 = 0;
+      return 1;
+    }
+  /* only get here if both points are inside the window */
+  return 1;
+}
+
+//*******************************************************************
+// Public Constructor: ossimDrect
+//
+//*******************************************************************
+ossimDrect::ossimDrect(const ossimIrect& rect)
+   :
+      theUlCorner(rect.ul()),
+      theUrCorner(rect.ur()),
+      theLrCorner(rect.lr()),
+      theLlCorner(rect.ll()),
+      theOrientMode(rect.orientMode())
+{
+   if(rect.isNan())
+   {
+      makeNan();
+   }
+}
+
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimDrect(const vector<ossimDpt>& points)
+//  
+//*****************************************************************************
+ossimDrect::ossimDrect(const ossimPolygon& polygon,
+                       ossimCoordSysOrientMode mode)
+   :
+      theOrientMode (mode)
+{
+   vector<ossimDpt> vertices;
+   ossimDpt point;
+   int index = 0;
+   while (polygon.vertex(index, point))
+   {
+      vertices.push_back(point);
+      index++;
+   }
+
+   initBoundingRect(vertices);
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimDrect(const vector<ossimDpt>& points)
+//  
+//*****************************************************************************
+ossimDrect::ossimDrect(const vector<ossimDpt>& points,
+                       ossimCoordSysOrientMode mode)
+   :
+      theOrientMode (mode)
+{
+  if(points.size())
+   {
+      unsigned long index;
+      double minx, miny;
+      double maxx, maxy;
+      
+      minx = points[0].x;
+      miny = points[0].y;
+      maxx = points[0].x;
+      maxy = points[0].y;
+            
+      // find the bounds
+      for(index = 1; index < points.size();index++)
+      {
+         
+         minx = std::min(minx, points[index].x);
+         miny = std::min(miny, points[index].y);
+         maxx = std::max(maxx, points[index].x);
+         maxy = std::max(maxy, points[index].y);
+         
+      }
+      if(theOrientMode == OSSIM_LEFT_HANDED)
+      {
+         *this = ossimDrect(minx, miny, maxx, maxy, mode);
+      }
+      else
+      {
+         *this = ossimDrect(minx,maxy, maxx, miny, mode);
+      }
+   }
+   else
+   {
+      makeNan();
+   }
+}
+ossimDrect::ossimDrect(const ossimDpt& p1,
+                       const ossimDpt& p2,
+                       const ossimDpt& p3,
+                       const ossimDpt& p4,
+                       ossimCoordSysOrientMode mode)
+{
+   if(p1.hasNans()||p2.hasNans()||p3.hasNans()||p4.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      double minx, miny;
+      double maxx, maxy;
+      
+      minx = std::min( p1.x, std::min(p2.x, std::min(p3.x, p4.x)));
+      miny = std::min( p1.y, std::min(p2.y, std::min(p3.y, p4.y)));
+      maxx = std::max( p1.x, std::max(p2.x, std::max(p3.x, p4.x)));
+      maxy = std::max( p1.y, std::max(p2.y, std::max(p3.y, p4.y)));
+      
+      if(mode == OSSIM_LEFT_HANDED)
+      {
+         *this = ossimDrect(minx, miny, maxx, maxy, mode);
+      }
+      else
+      {            
+         *this = ossimDrect(minx,maxy, maxx, miny, mode);
+      }
+   }
+}
+
+ossimDrect::~ossimDrect()
+{
+}
+
+void ossimDrect::initBoundingRect(const vector<ossimDpt>& points)
+{
+   unsigned long index;
+
+   // initialize everyone to the first point
+   if(points.size() > 0)
+   {
+      theUlCorner.x = points[0].x;
+      theUlCorner.y = points[0].y;
+      theLrCorner.x = theUlCorner.x;
+      theLrCorner.y = theUlCorner.y;
+   }
+   
+   // find the bounds
+   for(index = 1; index < points.size();index++)
+   {
+      // find left most
+      if(points[index].x < theUlCorner.x)
+         theUlCorner.x = points[index].x;
+
+      // find right most
+      else if(points[index].x > theLrCorner.x)
+         theLrCorner.x = points[index].x;
+
+      if (theOrientMode == OSSIM_LEFT_HANDED)
+      {
+         //find top most
+         if(points[index].y < theUlCorner.y)
+            theUlCorner.y = points[index].y;
+
+         // find bottom most
+         else if(points[index].y > theLrCorner.y)
+            theLrCorner.y = points[index].y;
+      }
+
+      else // right handed coord system
+      {
+         if(points[index].y > theUlCorner.y)
+            theUlCorner.y = points[index].y;
+
+         // find bottom most
+         else if(points[index].y < theLrCorner.y)
+            theLrCorner.y = points[index].y;
+      }
+   }
+
+   // now set the other points for the rect.
+   theUrCorner.x = theLrCorner.x;
+   theUrCorner.y = theUlCorner.y;
+   theLlCorner.x = theUlCorner.x;
+   theLlCorner.y = theLrCorner.y;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+bool ossimDrect::intersects(const ossimDrect& rect) const
+{
+   if(rect.hasNans() || hasNans())
+   {
+      return false;
+   }
+   if (theOrientMode != rect.theOrientMode)
+      return false;
+   
+   ossim_float64  ulx = d_MAX(rect.ul().x,ul().x);
+   ossim_float64  lrx = d_MIN(rect.lr().x,lr().x);
+   ossim_float64  uly, lry;
+   bool rtn;
+   
+   if (theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      uly  = d_MAX(rect.ul().y,ul().y);
+      lry  = d_MIN(rect.lr().y,lr().y);
+      rtn = ((ulx <= lrx) && (uly <= lry));
+   }
+   else
+   {
+      uly  = d_MAX(rect.ul().y,ul().y);
+      lry  = d_MIN(rect.lr().y,lr().y);
+      rtn = ((ulx <= lrx) && (uly >= lry));
+   }
+      
+   return (rtn);
+}
+
+//*******************************************************************
+// Public Method: ossimDrect::completely_within
+//*******************************************************************
+bool ossimDrect::completely_within(const ossimDrect& rect) const
+{
+   if(hasNans() || rect.hasNans())
+   {
+      return false;
+   }
+   if (theOrientMode != rect.theOrientMode)
+      return false;
+   
+   /*  --------------
+       |     1      |
+       | ---------- |
+       | |        | |
+       | |        | |
+       | |   2    | |
+       | |        | |
+       | |        | |
+       | ---------- |
+       |            |
+       --------------  */
+
+   bool rtn = true;
+   
+   if (theUlCorner.x < rect.ul().x)
+      rtn = false;
+   
+   else if (theLrCorner.x > rect.lr().x)
+      rtn = false;
+   
+   else if (theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      if (theUlCorner.y < rect.ul().y)
+         rtn = false;
+   
+      else if (theLrCorner.y > rect.lr().y)
+         rtn = false;
+   }
+   
+   else
+   {
+      if (theUlCorner.y > rect.ul().y)
+         rtn = false;
+   
+      else if (theLrCorner.y < rect.lr().y)
+         rtn = false;
+   }
+
+   return rtn;
+}
+
+//*******************************************************************
+// Public Method: ossimDrect::stretchOut
+//*******************************************************************
+void ossimDrect::stretchOut()
+{
+   set_ulx(floor(theUlCorner.x));
+   set_lrx(ceil(theLrCorner.x));
+
+   if (theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      set_uly(floor(theUlCorner.y));
+      set_lry(ceil(theLrCorner.y));
+   }
+   else
+   {
+      set_uly(ceil(theUlCorner.y));
+      set_lry(floor(theLrCorner.y));
+   }
+}
+
+void ossimDrect::stretchToTileBoundary(const ossimDpt& widthHeight)
+{
+   ossimDpt ul;
+   ossimDpt lr;
+   ossim_int32 evenDivision=0;
+
+   if(theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      ul.x = theUlCorner.x;
+      if( fmod(theUlCorner.x, widthHeight.x) != 0)
+      {
+         ul.x = ((long)(ul.x / widthHeight.x))*widthHeight.x;
+         if(ul.x > theUlCorner.x)
+         {
+            ul.x -= widthHeight.x;
+         }
+      }
+      ul.y = theUlCorner.y;
+      if( fmod(theUlCorner.y, widthHeight.y) != 0)
+      {
+         ul.y = ((long)(ul.y / widthHeight.y))*widthHeight.y;
+         if(ul.y > theUlCorner.y)
+         {
+            ul.y -= widthHeight.y;
+         }
+      }
+      
+      evenDivision = fmod(theLrCorner.x, widthHeight.x) == 0;
+      lr.x = theLrCorner.x;
+      if(!evenDivision)
+      {
+         lr.x = ((long)((lr.x)/widthHeight.x)) * widthHeight.x;
+         if(lr.x < theLrCorner.x)
+         {
+            lr.x += widthHeight.x;
+         }
+      }
+
+      evenDivision = fmod(theLrCorner.y, widthHeight.y) == 0;
+      lr.y = theLrCorner.y;
+      if(!evenDivision)
+      {
+         lr.y = ((long)(lr.y/widthHeight.y)) * widthHeight.y;
+         if(lr.y < theLrCorner.y)
+         {
+            lr.y += widthHeight.y;
+         }
+      }
+   }
+   else
+   {
+      ul.x = theUlCorner.x;
+      ul.y = theUlCorner.y;
+      if( !equals(fmod(theUlCorner.x, widthHeight.x), 0.0))
+      {
+         ul.x = ((long)(ul.x/ widthHeight.x))*widthHeight.x;
+         if(ul.x > theUlCorner.x)
+         {
+            ul.x -= widthHeight.x;
+         }
+      }
+      if( !equals((double)fmod(theUlCorner.y, widthHeight.y), (double)0.0) )
+      {
+         ul.y = ((long)(ul.y / widthHeight.y))*widthHeight.y;
+         if(ul.y < theUlCorner.y)
+         {
+            ul.y += widthHeight.y;
+         }
+      }
+      
+      evenDivision = equals( fmod(theLrCorner.x, widthHeight.x), (double)0.0);
+      lr.x = theLrCorner.x;
+      if(!evenDivision)
+      {
+         lr.x = ((long)(lr.x/widthHeight.x)) * widthHeight.x;
+         if(lr.x < theLrCorner.x)
+         {
+            lr.x += widthHeight.x;
+         }
+      }
+
+      evenDivision = equals(fmod(theLrCorner.y, widthHeight.y), 0);
+      lr.y = theLrCorner.y;
+      if(!evenDivision)
+      {
+         lr.y = ((long)(lr.y/widthHeight.y)) * widthHeight.y;
+
+         if(lr.y > theLrCorner.y)
+         {
+            lr.y -= widthHeight.y;
+         }
+      }
+  }
+
+   *this = ossimDrect(ul, lr, theOrientMode);
+}
+
+
+
+//*******************************************************************
+// Public Method: ossimDrect::print
+//*******************************************************************
+void ossimDrect::print(std::ostream& os) const
+{
+   os << (theOrientMode==OSSIM_LEFT_HANDED?"left handed: ":"right handed: ") << theUlCorner << theLrCorner;
+}
+
+//*******************************************************************
+// friend function: operator<<
+//*******************************************************************
+std::ostream& operator<<(std::ostream& os, const ossimDrect& rect)
+{
+   rect.print(os);
+
+   return os;
+}
+
+//*******************************************************************
+// Public Method: ossimDrect::clip
+//*******************************************************************
+bool ossimDrect::clip(ossimDpt &p1, ossimDpt &p2)const
+{
+   if(p1.isNan() || p2.isNan())
+   {
+      return false;
+   }
+   ossimDpt shift(-theUlCorner.x,
+		  -theUlCorner.y);
+
+   ossimDpt tempShiftP1 = p1+shift;
+   ossimDpt tempShiftP2 = p2+shift;
+   double maxW = width()-1;
+   double maxH = height()-1;
+  if (clip_1d (&tempShiftP1.x, &tempShiftP1.y, 
+	       &tempShiftP2.x, &tempShiftP2.y, 
+	       maxW) == 0)
+    {
+      return false;
+    }
+  if(clip_1d (&tempShiftP1.y, 
+	      &tempShiftP1.x, 
+	      &tempShiftP2.y, 
+	      &tempShiftP2.x, maxH) == 0)
+    {
+      return false;
+    }
+  p1 = tempShiftP1-shift;
+  p2 = tempShiftP2-shift;
+  return true;
+//   bool done    = false;
+   
+//    long p1Code = getCode(p1, (*this));
+//    long p2Code = getCode(p2, (*this));
+//    long codeOut;
+
+//    do{
+
+//       if((!p1Code) && (!p2Code))
+//       {
+//          visible = true;
+//          done    = true;
+//       }
+//       else if(p1Code&p2Code)
+//       {
+//          done    = true;
+//       }
+//       else
+//       {
+//          if(p1Code)
+//          {
+//             codeOut = p1Code;
+//          }
+//          else
+//          {
+//             codeOut = p2Code;
+//          }
+        
+//          if(codeOut&TOP) // divide rect at the top
+//          {
+//             tempPt.x = p1.x + (p2.x - p1.x)*
+//                        ((*this).ul().y - p1.y)/(p2.y - p1.y);
+//             tempPt.y = (*this).ul().y;
+//          }
+//          else if(codeOut&BOTTOM)
+//          {
+//             tempPt.x = p1.x + (p2.x - p1.x)*
+//                        ((*this).lr().y - p1.y)/(p2.y - p1.y);
+//             tempPt.y = (*this).lr().y;
+//          }
+//          else if(codeOut&RIGHT)
+//          {
+//             tempPt.y = p1.y + (p2.y - p1.y)*
+//                        ((*this).lr().x - p1.x)/(p2.x - p1.x);
+//             tempPt.x = (*this).lr().x;
+//          }
+//          else if(codeOut&LEFT)
+//          {
+//             tempPt.y = p1.y + (p2.y - p1.y)*
+//                        ((*this).ul().x - p1.x)/(p2.x - p1.x);
+//             tempPt.x = (*this).ul().x;
+//          }
+//          if(codeOut == p1Code)
+//          {
+//             p1.x = tempPt.x;
+//             p1.y = tempPt.y;
+//             p1Code = getCode(p1, (*this));
+//          }
+//          else
+//          {
+//             p2.x = tempPt.x;
+//             p2.y = tempPt.y;
+//             p2Code = getCode(p2, (*this));
+//          }
+//       }
+//    }while(!done);
+//    return visible;
+}
+
+//*******************************************************************
+// Public Method: ossimDrect::getCode
+//*******************************************************************
+long ossimDrect::getCode(const ossimDpt& aPoint,
+                         const ossimDrect& clipRect)
+{
+   long result=NONE; // initialize to inside rect
+   
+   if( (aPoint.x > clipRect.lr().x) )
+      result |= RIGHT;
+   else if( (aPoint.x < clipRect.ul().x) )
+      result |= LEFT;
+
+   if (clipRect.theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      if( (aPoint.y < clipRect.ul().y) )
+         result |= TOP;
+      else if( (aPoint.y > clipRect.lr().y) )
+         result |= BOTTOM;
+   }
+   else
+   {
+      if( (aPoint.y > clipRect.ul().y) )
+         result |= TOP;
+      else if( (aPoint.y < clipRect.lr().y) )
+         result |= BOTTOM;
+   }
+      
+   return result;
+}
+
+
+void ossimDrect::splitToQuad(ossimDrect& ulRect,
+                             ossimDrect& urRect,
+                             ossimDrect& lrRect,
+                             ossimDrect& llRect)
+{
+   ossimDpt ulPt  = this->ul();
+   ossimDpt urPt  = this->ur();
+   ossimDpt lrPt  = this->lr();
+   ossimDpt llPt  = this->ll();
+   ossimIpt midPt = this->midPoint();
+   
+   ulRect = ossimDrect(ulPt.x,
+		       ulPt.y,
+		       midPt.x,
+		       midPt.y,
+		       theOrientMode);
+   
+   urRect = ossimDrect(midPt.x+DBL_EPSILON,
+		       ulPt.y,
+		       urPt.x,
+		       midPt.y,
+		       theOrientMode);
+
+   if(theOrientMode  == OSSIM_LEFT_HANDED)
+     {
+       lrRect = ossimDrect(midPt.x+DBL_EPSILON,
+			   midPt.y+DBL_EPSILON,
+			   lrPt.x,
+			   theOrientMode);
+     }
+   else
+     {       
+       lrRect = ossimDrect(midPt.x+DBL_EPSILON,
+			   midPt.y-DBL_EPSILON,
+			   lrPt.x,
+			   theOrientMode);
+     }
+
+   if(theOrientMode  == OSSIM_LEFT_HANDED)
+     {
+       llRect = ossimDrect(ulPt.x,
+			   midPt.y+DBL_EPSILON,
+			   midPt.x,
+			   llPt.y,
+			   theOrientMode);
+     }
+   else
+     {
+       llRect = ossimDrect(ulPt.x,
+			   midPt.y-DBL_EPSILON,
+			   midPt.x,
+			   llPt.y,
+			   theOrientMode);       
+     }
+}
+
+//*******************************************************************
+// Public Method: ossimDrect::clipToRect
+//*******************************************************************
+ossimDrect ossimDrect::clipToRect(const ossimDrect& rect)const
+{
+   if(rect.hasNans() || hasNans())
+   {
+      ossimDrect result;
+      result.makeNan();
+
+      return result;
+   }
+   
+   if (theOrientMode != rect.theOrientMode)
+      return (*this);
+
+   double x0 = d_MAX(rect.ul().x, ul().x);
+   double x1 = d_MIN(rect.lr().x, lr().x);
+   double y0, y1;
+
+   if(!this->intersects(rect))
+   {
+      return ossimDrect(OSSIM_DBL_NAN,
+                        OSSIM_DBL_NAN,
+                        OSSIM_DBL_NAN,
+                        OSSIM_DBL_NAN);
+   }
+   if (theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      y0 = d_MAX(rect.ul().y, ul().y);
+      y1 = d_MIN(rect.lr().y, lr().y);
+
+      if( (x1 < x0) || (y1 < y0) )
+         return ossimDrect(ossimDpt(0,0), ossimDpt(0,0), theOrientMode);
+      else
+         return ossimDrect(x0, y0, x1, y1, theOrientMode);
+   }
+   else
+   {
+      y1 = d_MIN(rect.ul().y,ul().y);
+      y0 = d_MAX(rect.lr().y,lr().y);
+
+      if((x1 < x0) || (y1 < y0))
+         return ossimDrect(ossimDpt(0,0), ossimDpt(0,0), theOrientMode);
+      else
+         return ossimDrect(x0, y1, x1, y0, theOrientMode);
+   }
+}
+
+const ossimDrect& ossimDrect::operator=(const ossimIrect& rect)
+{
+   if(rect.isNan())
+   {
+      makeNan();
+   }
+   else
+   {
+      theUlCorner   = rect.ul();
+      theUrCorner   = rect.ur();
+      theLrCorner   = rect.lr();
+      theLlCorner   = rect.ll();
+      theOrientMode = rect.orientMode();
+   }
+   
+   return *this;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimDrect.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimDrect.h
new file mode 100644
index 0000000000..bbfc6c6410
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimDrect.h
@@ -0,0 +1,766 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for drect.
+// Container class for four double points representing a rectangle.
+// 
+//*******************************************************************
+//  $Id: ossimDrect.h,v 1.23 2005/07/15 18:51:25 dburken Exp $
+
+#ifndef ossimDrect_HEADER
+#define ossimDrect_HEADER
+#include <vector>
+using namespace std;
+
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimFpt.h>
+
+//***
+// NOTE:  A word on corner points...
+//
+// There is the concept of "pixel is area" and "pixel is point".
+// - Pixel is area means the (x,y) pixel coordinate refers to the upper left
+//   corner of the pixel, NOT the center of the pixel.
+// - Pixel is point means the (x,y) pixel coordinate refers to the center
+//   of the pixel, NOT the upper left corner.
+//
+// For the uniformity purposes, all pixel points  should be in the
+// "pixel is point" form; therefore, the (x,y) point should represent the
+// CENTER of the pixel.
+//***
+
+//***
+// Forward class declarations.
+//***
+class OSSIMDLLEXPORT ossimIrect;
+class OSSIMDLLEXPORT ossimPolygon;
+
+//*******************************************************************
+// CLASS:  ossimDrect
+//*******************************************************************
+
+class OSSIMDLLEXPORT ossimDrect
+{
+public:
+   enum
+   {
+      UPPER_LEFT  = 1,
+      LOWER_LEFT  = 2,
+      LOWER_RIGHT = 4,
+      UPPER_RIGHT = 8
+   };
+
+   ossimDrect()
+      :
+         theUlCorner(0.0, 0.0),
+         theUrCorner(0.0, 0.0),
+         theLrCorner(0.0, 0.0),
+         theLlCorner(0.0, 0.0),
+         theOrientMode(OSSIM_LEFT_HANDED)
+      {}
+
+   ossimDrect(const ossimDpt&   ul_corner,
+              const ossimDpt&   lr_corner,
+              ossimCoordSysOrientMode mode=OSSIM_LEFT_HANDED)
+      :
+         theUlCorner(ul_corner),
+         theUrCorner(lr_corner.x, ul_corner.y),
+         theLrCorner(lr_corner),
+         theLlCorner(ul_corner.x, lr_corner.y),
+         theOrientMode(mode)
+      {
+      }
+
+   ossimDrect(const double& ul_corner_x,
+              const double& ul_corner_y,
+              const double& lr_corner_x,
+              const double& lr_corner_y,
+              ossimCoordSysOrientMode mode=OSSIM_LEFT_HANDED)
+      :
+         theUlCorner(ul_corner_x, ul_corner_y),
+         theUrCorner(lr_corner_x, ul_corner_y),
+         theLrCorner(lr_corner_x, lr_corner_y),
+         theLlCorner(ul_corner_x, lr_corner_y),
+         theOrientMode(mode)
+      {}
+   
+   ossimDrect(const ossimDrect& rect)
+      :
+         theUlCorner(rect.ul()),
+         theUrCorner(rect.ur()),
+         theLrCorner(rect.lr()),
+         theLlCorner(rect.ll()),
+         theOrientMode(rect.orientMode())
+      {}
+
+   ossimDrect(const ossimIrect& rect);
+
+   /*!
+    * Must compute a bounding rect given a collection of points or polygon:
+    */
+   ossimDrect(const vector<ossimDpt>& points,
+              ossimCoordSysOrientMode mode=OSSIM_LEFT_HANDED);
+   ossimDrect(const ossimDpt& p1,
+              const ossimDpt& p2,
+              const ossimDpt& p3,
+              const ossimDpt& p4,
+              ossimCoordSysOrientMode mode=OSSIM_LEFT_HANDED);
+   ossimDrect(const ossimPolygon& polygon, 
+              ossimCoordSysOrientMode mode=OSSIM_LEFT_HANDED);
+
+   /** destructor */
+   ~ossimDrect();
+   
+   const ossimDrect& operator=  (const ossimDrect& rect);
+   const ossimDrect& operator=  (const ossimIrect& rect);
+   bool         operator!= (const ossimDrect& rect) const;
+   bool         operator== (const ossimDrect& rect) const;
+    friend ossimDrect operator*(double scalar, const ossimDrect& rect)
+      {
+         ossimDpt ul(rect.theUlCorner.x*scalar,
+                     rect.theUlCorner.y*scalar);
+
+         if(rect.theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            return ossimDrect(ul.x,
+                              ul.y,
+                              ul.x+rect.width()*scalar-1,
+                              ul.y+rect.height()*scalar-1,
+                              rect.theOrientMode);
+         }
+         return ossimDrect(ul.x,
+                           ul.y,
+                           ul.x+rect.width()*scalar-1,
+                           ul.y-(rect.height()*scalar-1),
+                           rect.theOrientMode);
+         
+      }
+   
+   const ossimDrect& operator *=(double scalar)
+      {
+          ossimDpt ul(theUlCorner.x*scalar,
+                      theUlCorner.y*scalar);
+
+          if(theOrientMode == OSSIM_LEFT_HANDED)
+          {
+             *this = ossimDrect(ul.x,
+                                ul.y,
+                                (ul.x+width()*scalar-1),
+                                (ul.y+height()*scalar-1),
+                                theOrientMode);
+          }
+          else
+          {
+             *this = ossimDrect(ul.x,
+                                ul.y,
+                                (ul.x+width()*scalar-1),
+                                (ul.y-(height()*scalar-1)),
+                                theOrientMode);
+                                
+          }
+         return *this;
+      }
+   
+   ossimDrect operator *(double scalar)const
+      {
+         ossimDpt ul((theUlCorner.x*scalar),
+                     (theUlCorner.y*scalar));
+
+         if(theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            return ossimDrect(ul.x,
+                              ul.y,
+                              (ul.x+width()*scalar-1),
+                              (ul.y+height()*scalar-1),
+                              theOrientMode);
+         }
+
+         return ossimDrect(ul.x,
+                           ul.y,
+                           (ul.x+width()*scalar-1),
+                           ul.y-(height()*scalar-1),
+                           theOrientMode);
+      }
+   const ossimDrect& operator *=(const ossimDpt& scalar)
+      {
+         ossimDpt ul((theUlCorner.x*scalar.x),
+                     (theUlCorner.y*scalar.y));
+         
+         if(theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            *this = ossimDrect(ul.x,
+                               ul.y,
+                               (ul.x+width()*scalar.x - 1),
+                               (ul.y+height()*scalar.y - 1),
+                               theOrientMode);
+         }
+         else
+         {
+            *this = ossimDrect(ul.x,
+                               ul.y,
+                               (ul.x+width()*scalar.x - 1),
+                               (ul.y-(height()*scalar.y - 1)),
+                               theOrientMode);            
+         }
+         return *this;
+      }
+   
+   ossimDrect operator *(const ossimDpt& scalar)const
+      {
+         ossimDpt ul((theUlCorner.x*scalar.x),
+                     (theUlCorner.y*scalar.y));
+         
+         if(theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            return ossimDrect(ul.x,
+                              ul.y,
+                              (ul.x+width()*scalar.x-1),
+                              (ul.y+height()*scalar.y-1),
+                              theOrientMode);
+         }
+         return ossimDrect(ul.x,
+                           ul.y,
+                           (ul.x+width()*scalar.x-1),
+                           (ul.y-(height()*scalar.y-1)),
+                           theOrientMode);
+      }
+   const ossimDrect& operator +=(const ossimDpt& shift)
+      {
+         ossimDpt ul((theUlCorner.x+shift.x),
+                     (theUlCorner.y+shift.y));
+                     
+         if(theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            *this = ossimDrect(ul.x,
+                               ul.y,
+                               ul.x+width()-1,
+                               ul.y+height()-1,
+                               theOrientMode);
+         }
+         else
+         {
+            *this = ossimDrect(ul.x,
+                               ul.y,
+                               ul.x+width()-1,
+                               ul.y-(height()-1),
+                               theOrientMode);            
+         }
+         return *this;
+      }
+   
+   const ossimDrect& operator -=(const ossimDpt& shift)
+      {
+         ossimDpt ul((theUlCorner.x-shift.x),
+                     (theUlCorner.y-shift.y));
+         
+         if(theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            *this = ossimDrect(ul.x,
+                               ul.y,
+                               ul.x+width()-1,
+                               ul.y+height()-1,
+                               theOrientMode);
+         }
+         else
+         {
+            *this = ossimDrect(ul.x,
+                               ul.y,
+                               ul.x+width()-1,
+                               ul.y-(height()-1),
+                               theOrientMode);
+         }
+         return *this;
+      }
+   
+   ossimDrect operator +(const ossimDpt& shift)const
+      {
+         ossimDpt ul((theUlCorner.x+shift.x),
+                     (theUlCorner.y+shift.y));
+                     
+         if(theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            return ossimDrect(ul.x,
+                              ul.y,
+                              ul.x+width()-1,
+                              ul.y+height()-1,
+                              theOrientMode);
+         }
+         else
+         {
+            return ossimDrect(ul.x,
+                              ul.y,
+                              ul.x+width()-1,
+                              ul.y-(height()-1),
+                              theOrientMode);
+         }
+      }  
+
+   ossimDrect operator -(const ossimDpt& shift)const
+      {
+         ossimIpt ul(irint(theUlCorner.x-shift.x),
+                     irint(theUlCorner.y-shift.y));
+                     
+         if(theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            return ossimDrect(ul.x,
+                              ul.y,
+                              ul.x+width()-1,
+                              ul.y+height()-1,
+                              theOrientMode);
+         }
+         else
+         {
+            return ossimDrect(ul.x,
+                              ul.y,
+                              ul.x+width()-1,
+                              ul.y-(height()-1),
+                              theOrientMode);            
+         }
+      }  
+
+   ossimDpt ul() const { return theUlCorner; }
+   ossimDpt ur() const { return theUrCorner; }
+   ossimDpt lr() const { return theLrCorner; }
+   ossimDpt ll() const { return theLlCorner; }
+
+   void getBounds(double& minx, double& miny,
+                  double& maxx, double& maxy)const
+      {
+         minx = theUlCorner.x;
+         maxx = theUrCorner.x;
+         if(theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            miny = theUlCorner.y;
+            maxy = theUrCorner.y;
+         }
+         else
+         {
+            maxy = theUlCorner.y;
+            miny = theUrCorner.y;
+         }
+      }
+   void makeNan()
+      {
+         theUlCorner.makeNan();
+         theLlCorner.makeNan();
+         theLrCorner.makeNan();
+         theUrCorner.makeNan();
+      }
+   
+   bool hasNans()const{ return (theUlCorner.hasNans() ||
+                                theLlCorner.hasNans() ||
+                                theLrCorner.hasNans() ||
+                                theUrCorner.hasNans());}
+   
+   bool isNan()const{ return (theUlCorner.hasNans() &&
+                              theLlCorner.hasNans() &&
+                              theLrCorner.hasNans() &&
+                              theUrCorner.hasNans());}
+
+   double area()const
+      {
+         return width()*height();
+      }
+   //***
+   // This class supports both left and right-handed coordinate systems. For
+   // both, the positive x-axis extends to the "right".
+   //***
+   ossimCoordSysOrientMode orientMode() const { return theOrientMode; }
+   void setOrientMode(ossimCoordSysOrientMode mode) { theOrientMode = mode; }
+   
+   /*!
+    * Sets the upper left corner to "pt".  Adjusts the remaining corners
+    * accordingly.
+    */
+   void set_ul(const ossimDpt& pt);
+
+   /*!
+    * Sets the upper right corner to "pt".  Adjusts the remaining corners
+    * accordingly.
+    */
+   void set_ur(const ossimDpt& pt);
+
+   /*!
+    * Sets the lower right corner to "pt".  Adjusts the remaining corners
+    * accordingly.
+    */
+   void set_lr(const ossimDpt& pt);
+
+   /*!
+    * Sets the lower left corner to "pt".  Adjusts the remaining corners
+    * accordingly.
+    */
+   void set_ll(const ossimDpt& pt);
+
+   /*!
+    * Sets the upper left x.  Adjusts the remaining corners accordingly.
+    */
+   void set_ulx(ossim_float64 x);
+
+   /*!
+    * Sets the upper left y.  Adjusts the remaining corners accordingly.
+    */
+   void set_uly(ossim_float64 y);
+
+   /*!
+    * Sets the upper right x.  Adjusts the remaining corners accordingly.
+    */
+   void set_urx(ossim_float64 x);
+
+   /*!
+    * Sets the upper right y.  Adjusts the remaining corners accordingly.
+    */
+   void set_ury(ossim_float64 y);
+
+   /*!
+    * Sets the lower right x.  Adjusts the remaining corners accordingly.
+    */
+   void set_lrx(ossim_float64 x);
+
+   /*!
+    * Sets the lower right y.  Adjusts the remaining corners accordingly.
+    */
+   void set_lry(ossim_float64 y);
+
+   /*!
+    * Sets the lower left x.  Adjusts the remaining corners accordingly.
+    */
+   void set_llx(ossim_float64 x);
+
+   /*!
+    * Sets the lower left y.  Adjusts the remaining corners accordingly.
+    */
+   void set_lly(ossim_float64 y);
+
+   /*!
+    * METHOD: initBoundingRect(points)
+    * Initializes this rect to the bounding rect containing all points in the
+    * collection passed in.
+    */
+   void initBoundingRect(const vector<ossimDpt>& points);
+
+   /*!
+    * Returns true if "pt" falls within rectangle.  Fall on an edge is also
+    * considered to be within.
+    */
+   bool pointWithin(const ossimDpt& pt) const;
+
+   /*!
+    * Returns true if "pt" falls within rectangle.  Fall on an edge is also
+    * considered to be within.
+    */
+   bool pointWithin(const ossimFpt& pt) const;
+
+   /*!
+    * Returns true if any portion of an input rectangle "rect" intersects
+    * "this" rectangle.  
+    */
+   bool intersects(const ossimDrect& rect) const;
+
+   /*!
+    * Returns true if "this" rectangle is contained completely within the
+    * input rectangle "rect".
+    */
+   bool completely_within(const ossimDrect& rect) const;
+
+   /*!
+    * Returns the height of a rectangle.
+    */
+   ossim_float64 height() const { return fabs(theLlCorner.y - theUlCorner.y) + 1.0; }
+
+   /*!
+    * Returns the width of a rectangle.
+    */
+   ossim_float64 width()  const { return fabs(theLrCorner.x - theLlCorner.x) + 1.0; }
+
+   /*!
+    * Stretches this rectangle out to integer boundaries.
+    */
+   void stretchOut();
+
+   /*!
+    * Will stretch the rect to the passed in tiled boundary.
+    */
+   void stretchToTileBoundary(const ossimDpt& widthHeight);
+
+   /*!
+    * Will subdivide this rect into four partiions.
+    */
+   void splitToQuad(ossimDrect& ulRect,
+                    ossimDrect& urRect,
+                    ossimDrect& lrRect,
+                    ossimDrect& llRect);
+   
+   ossimDrect clipToRect(const ossimDrect& rect)const;
+
+   inline ossimDpt midPoint()const;
+
+   void print(ostream& os) const;
+
+   ossimDrect combine(const ossimDrect& rect)const;
+   
+   friend OSSIMDLLEXPORT ostream& operator<<(ostream& os,
+                                             const ossimDrect& rect);
+
+   bool clip(ossimDpt &p1,
+             ossimDpt  &p2)const;
+
+   static long getCode(const ossimDpt& aPoint,
+                       const ossimDrect& clipRect);
+private:
+
+   enum ossimCohenSutherlandClipCodes
+   {
+      NONE   = 0,
+      LEFT   = 1,
+      RIGHT  = 2,
+      BOTTOM = 4,
+      TOP    = 8
+   };
+   
+   //***
+   // Private data members representing the rectangle corners.
+   //***
+   ossimDpt theUlCorner;
+   ossimDpt theUrCorner;
+   ossimDpt theLrCorner;
+   ossimDpt theLlCorner;
+
+   ossimCoordSysOrientMode  theOrientMode;
+};
+
+//*******************************************************************
+// Inline Method: ossimDrect::operator=(ossimDrect)
+//*******************************************************************
+inline const ossimDrect& ossimDrect::operator=(const ossimDrect& rect)
+{
+   if (this != &rect)
+   {
+      theUlCorner   = rect.theUlCorner;
+      theUrCorner   = rect.theUrCorner;
+      theLrCorner   = rect.theLrCorner;
+      theLlCorner   = rect.theLlCorner;
+      theOrientMode = rect.theOrientMode;
+   }
+
+   return *this;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::operator!=
+//*******************************************************************
+inline bool ossimDrect::operator!=(const ossimDrect& rect) const
+{
+   return ( (theUlCorner   != rect.theUlCorner) ||
+            (theUrCorner   != rect.theUrCorner) ||
+            (theLrCorner   != rect.theLrCorner) ||
+            (theLlCorner   != rect.theLlCorner) ||
+            (theOrientMode != rect.theOrientMode));
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::operator==
+//*******************************************************************
+inline bool ossimDrect::operator==(const ossimDrect& rect) const
+{
+   return ( (theUlCorner   == rect.theUlCorner) &&
+            (theUrCorner   == rect.theUrCorner) &&
+            (theLrCorner   == rect.theLrCorner) &&
+            (theLlCorner   == rect.theLlCorner) &&
+            (theOrientMode == rect.theOrientMode));
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_ul
+//*******************************************************************
+inline void ossimDrect::set_ul(const ossimDpt& pt)
+{
+   theUlCorner   = pt;
+   theUrCorner.y = pt.y;
+   theLlCorner.x = pt.x;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_ur
+//*******************************************************************
+inline void ossimDrect::set_ur(const ossimDpt& pt)
+{
+   theUrCorner   = pt;
+   theUlCorner.y = pt.y;
+   theLrCorner.x = pt.x;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_lr
+//*******************************************************************
+inline void ossimDrect::set_lr(const ossimDpt& pt)
+{
+   theLrCorner   = pt;
+   theUrCorner.x = pt.x;
+   theLlCorner.y = pt.y;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_ll
+//*******************************************************************
+inline void ossimDrect::set_ll(const ossimDpt& pt)
+{
+   theLlCorner   = pt;
+   theUlCorner.x = pt.x;
+   theLrCorner.y = pt.y;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_ulx
+//*******************************************************************
+inline void ossimDrect::set_ulx(ossim_float64 x)
+{
+   theUlCorner.x = x;
+   theLlCorner.x = x;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_uly
+//*******************************************************************
+inline void ossimDrect::set_uly(ossim_float64 y)
+{
+   theUlCorner.y = y;
+   theUrCorner.y = y;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_urx
+//*******************************************************************
+inline void ossimDrect::set_urx(ossim_float64 x)
+{
+   theUrCorner.x = x;
+   theLrCorner.x = x;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_ury
+//*******************************************************************
+inline void ossimDrect::set_ury(ossim_float64 y)
+{
+   theUrCorner.y = y;
+   theUlCorner.y = y;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_lrx
+//*******************************************************************
+inline void ossimDrect::set_lrx(ossim_float64 x)
+{
+   theLrCorner.x = x;
+   theUrCorner.x = x;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_lry
+//*******************************************************************
+inline void ossimDrect::set_lry(ossim_float64 y)
+{
+   theLrCorner.y = y;
+   theLlCorner.y = y;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_llx
+//*******************************************************************
+inline void ossimDrect::set_llx(ossim_float64 x)
+{
+   theLlCorner.x = x;
+   theUlCorner.x = x;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::set_lly
+//*******************************************************************
+inline void ossimDrect::set_lly(ossim_float64 y)
+{
+   theLlCorner.y = y;
+   theLrCorner.y = y;
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::pointWithin(const ossimDpt& pt) 
+//*******************************************************************
+inline bool ossimDrect::pointWithin(const ossimDpt& pt) const
+{
+   if (theOrientMode == OSSIM_LEFT_HANDED)
+      return ((pt.x >= ul().x) &&
+              (pt.x <= ur().x) &&
+              (pt.y >= ul().y) &&
+              (pt.y <= ll().y));
+   else
+      return ((pt.x >= ul().x) &&
+              (pt.x <= ur().x) &&
+              (pt.y <= ul().y) &&
+              (pt.y >= ll().y));
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::pointWithin(const ossimFpt& pt)
+//*******************************************************************
+inline bool ossimDrect::pointWithin(const ossimFpt& pt) const
+{
+   if (theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      return ( (pt.x >= ul().x) &&
+               (pt.x <= ur().x) &&
+               (pt.y >= ul().y) &&
+               (pt.y <= ll().y) );
+   }
+   return ((pt.x >= ul().x) &&
+           (pt.x <= ur().x) &&
+           (pt.y <= ul().y) &&
+           (pt.y >= ll().y));
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::midPoint()
+//*******************************************************************
+inline ossimDpt ossimDrect::midPoint()const
+{
+   return ossimDpt( (ul().x + ur().x + ll().x + lr().x)*.25,
+                    (ul().y + ur().y + ll().y + lr().y)*.25);
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::combine(const ossimDrect& rect)
+//*******************************************************************
+inline ossimDrect ossimDrect::combine(const ossimDrect& rect)const
+{
+   if (theOrientMode != rect.theOrientMode)
+      return(*this);
+   
+   ossimDpt ulCombine;
+   ossimDpt lrCombine;
+
+   if(theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      ulCombine.x = ((ul().x <= rect.ul().x)?ul().x:rect.ul().x);
+      ulCombine.y = ((ul().y <= rect.ul().y)?ul().y:rect.ul().y);
+      lrCombine.x = ((lr().x >= rect.lr().x)?lr().x:rect.lr().x);
+      lrCombine.y = ((lr().y >= rect.lr().y)?lr().y:rect.lr().y);
+   }
+   else
+   {
+      ulCombine.x = ((ul().x <= rect.ul().x)?ul().x:rect.ul().x);
+      ulCombine.y = ((ul().y >= rect.ul().y)?ul().y:rect.ul().y);
+      lrCombine.x = ((lr().x >= rect.lr().x)?lr().x:rect.lr().x);
+      lrCombine.y = ((lr().y <= rect.lr().y)?lr().y:rect.lr().y);
+   }
+
+   return ossimDrect(ulCombine, lrCombine);
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefPoint.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefPoint.cpp
new file mode 100644
index 0000000000..1a0115eade
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefPoint.cpp
@@ -0,0 +1,89 @@
+//*****************************************************************************
+// FILE: ossimEcefPoint.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of a 3D point object in the Earth-centered, earth
+//   fixed (ECEF) coordinate system.
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (http://www.oscarkramer.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimEcefPoint.cpp,v 1.9 2005/07/29 20:47:04 dburken Exp $
+
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimGeocent.h>
+#include <base/data_types/ossimDpt3d.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/ossimEcefVector.h>
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimEcefPoint(const ossimGpt&  convert_this)
+//  
+//*****************************************************************************
+ossimEcefPoint::ossimEcefPoint(const ossimGpt&  gpt)
+{
+   if(!gpt.isHgtNan())
+   {
+      gpt.datum()->ellipsoid()->latLonHeightToXYZ(gpt.latd(),
+                                                  gpt.lond(),
+                                                  gpt.height(),
+                                                  theData[0],
+                                                  theData[1],
+                                                  theData[2]);
+   }
+   else
+   {
+      gpt.datum()->ellipsoid()->latLonHeightToXYZ(gpt.latd(),
+                                                  gpt.lond(),
+                                                  0.0,
+                                                  theData[0],
+                                                  theData[1],
+                                                  theData[2]);
+   }
+}
+
+ossimEcefPoint::ossimEcefPoint(const ossimDpt3d& pt)
+   :theData(pt.x, pt.y, pt.z)
+{
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimEcefPoint::operator-(ossimEcefPoint)
+//*****************************************************************************
+ossimEcefVector ossimEcefPoint::operator-(const ossimEcefPoint& p) const
+{
+   return ossimEcefVector(theData - p.theData);
+}
+
+//*****************************************************************************
+//  METHOD: ossimEcefPoint::operator+(ossimEcefVector)
+//*****************************************************************************
+ossimEcefPoint ossimEcefPoint::operator+(const ossimEcefVector& v) const
+{
+   return ossimEcefPoint(theData + v.data());
+}
+
+//*****************************************************************************
+//  METHOD: ossimEcefPoint::operator-(ossimEcefVector)
+//*****************************************************************************
+ossimEcefPoint ossimEcefPoint::operator-(const ossimEcefVector& v) const
+{
+   return ossimEcefPoint(theData - v.data());
+}
+
+std::ostream& operator<<(std::ostream& os , const ossimEcefPoint& instance)
+{
+   instance.print(os); return os;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefPoint.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefPoint.h
new file mode 100644
index 0000000000..42c338b615
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefPoint.h
@@ -0,0 +1,192 @@
+//*****************************************************************************
+// FILE: ossimEcefPoint.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of a 3D point object in the Earth-centered, earth
+//   fixed (ECEF) coordinate system.
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimEcefPoint.h,v 1.10 2005/05/13 17:39:01 gpotts Exp $
+
+#ifndef ossimEcefPoint_HEADER
+#define ossimEcefPoint_HEADER
+#include <iostream>
+#include <stdio.h>
+#include <base/data_types/ossimColumnVector3d.h>
+#include <base/context/ossimNotifyContext.h>
+
+class ossimGpt;
+class ossimEcefVector;
+class ossimDpt3d;
+//*****************************************************************************
+//  CLASS: ossimEcefPoint
+//
+//*****************************************************************************
+class OSSIMDLLEXPORT ossimEcefPoint
+{
+public:
+   /*!
+    * CONSTRUCTORS: 
+    */
+   ossimEcefPoint()
+      : theData(0,0,0) {}
+
+   ossimEcefPoint(const ossimEcefPoint& copy_this)
+      : theData (copy_this.theData) {}
+
+   ossimEcefPoint(const ossimGpt& convert_this);
+
+   ossimEcefPoint(const double& x,
+                  const double& y,
+                  const double& z)
+      : theData(x, y, z) {}
+
+   ossimEcefPoint(const ossimColumnVector3d& assign_this)
+      : theData(assign_this) {}
+
+   ossimEcefPoint(const ossimDpt3d& pt);
+   
+   void makeNan()
+      {
+         theData[0] = OSSIM_DBL_NAN;
+         theData[1] = OSSIM_DBL_NAN;
+         theData[2] = OSSIM_DBL_NAN;
+      }
+   
+   bool hasNans()const
+      {
+         return ((theData[0]==OSSIM_DBL_NAN)||
+                 (theData[1]==OSSIM_DBL_NAN)||
+                 (theData[2]==OSSIM_DBL_NAN));
+                           
+      }
+
+   bool isNan()const
+      {
+         return ((theData[0]==OSSIM_DBL_NAN)&&
+                 (theData[1]==OSSIM_DBL_NAN)&&
+                 (theData[2]==OSSIM_DBL_NAN));
+         
+      }
+   /*!
+    * OPERATORS:
+    */
+   ossimEcefVector       operator- (const ossimEcefPoint&)  const;
+   ossimEcefPoint        operator+ (const ossimEcefVector&) const;
+   ossimEcefPoint        operator- (const ossimEcefVector&) const;
+   const ossimEcefPoint& operator= (const ossimEcefPoint&);        // inline
+   bool                  operator==(const ossimEcefPoint&)  const; // inline
+   bool                  operator!=(const ossimEcefPoint&)  const; // inline
+   
+   /*!
+    * COMPONENT ACCESS METHODS: 
+    */
+   double    x() const { return theData[0]; }
+   double&   x()       { return theData[0]; }
+   double    y() const { return theData[1]; }
+   double&   y()       { return theData[1]; }
+   double    z() const { return theData[2]; }
+   double&   z()       { return theData[2]; }
+   double&   operator[](int idx){return theData[idx];}
+   const double&   operator[](int idx)const{return theData[idx];}
+   const ossimColumnVector3d& data() const { return theData; }
+   ossimColumnVector3d&       data()       { return theData; }
+
+   double getMagnitude() const
+      {
+         return theData.magnitude();
+      }
+   double magnitude()const
+   {
+      return theData.magnitude();
+   }
+   double length()const
+   {
+      return theData.magnitude();
+   }
+   double normalize()
+   {
+      double result = magnitude();
+
+      if(result > 1e-15)
+      {
+         theData[0]/=result;
+         theData[1]/=result;
+         theData[2]/=result;
+      }
+      
+      return result;
+   }
+   /*!
+    * Debug Dump: 
+    */
+   void print(std::ostream& os = ossimNotify(ossimNotifyLevel_INFO)) const
+      {
+         if(isNan())
+         {
+            os << "(ossimEcefPoint) " << "nan nan nan";
+         }
+   
+         os << "(ossimEcefPoint) " << theData;
+      }
+   
+   friend std::ostream& operator<<(std::ostream& os ,
+                                   const ossimEcefPoint& instance);
+
+protected:
+   ossimColumnVector3d theData;
+};
+
+//================== BEGIN DEFINITIONS FOR INLINE METHODS =====================
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefPoint::operator=(ossimEcefPoint)
+//*****************************************************************************
+inline const ossimEcefPoint&
+ossimEcefPoint::operator=(const ossimEcefPoint& p)
+{
+   theData = p.theData;
+   return *this;
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefPoint::operator==(ossimEcefPoint)
+//*****************************************************************************
+inline bool ossimEcefPoint::operator==(const ossimEcefPoint& p) const
+{
+   return (theData == p.theData);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefPoint::operator!=(ossimEcefPoint)
+//*****************************************************************************
+inline bool ossimEcefPoint::operator!=(const ossimEcefPoint& p) const
+{
+   return (theData != p.theData);
+}
+
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefRay.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefRay.cpp
new file mode 100644
index 0000000000..15c9aa552a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefRay.cpp
@@ -0,0 +1,108 @@
+//*****************************************************************************
+// FILE: ossimEcefRay.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//  Class for representing a ray in the earth-centered, earth-fixed (ECEF)
+//  coordinate system. A ray is defined as having an origin point and a
+//  unit direction vector radiating from the origin.
+//
+// SOFTWARE HISTORY:
+//>
+//   10Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Log: ossimEcefRay.cpp,v $
+//  Revision 1.2  2002/05/31 12:51:14  okramer
+//  Added ossimEcefRay::intersectAboveEarthEllipsoid()
+//
+//  Revision 1.1  2001/08/14 15:01:45  okramer
+//  Initial delivery (okramer@imagelinks.com)
+//
+
+#include "ossimEcefRay.h"
+#include "ossimGpt.h"
+#include "base/data_types/datum/ossimDatum.h"
+#include "base/data_types/ellipse/ossimEllipsoid.h"
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include "base/common/ossimTrace.h"
+static ossimTrace traceExec  ("ossimEcefRay:exec");
+static ossimTrace traceDebug ("ossimEcefRay:debug");
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimEcefRay(ossimEcefPoint, ossimEcefPoint)
+//  
+//  Constructs a ray originating at "from" and pointing in direction of "to"
+//  
+//*****************************************************************************
+ossimEcefRay::ossimEcefRay(const ossimEcefPoint& from,
+                           const ossimEcefPoint& to)
+   : theOrigin(from)
+{
+   ossimEcefVector ecef (to - from);
+   ecef.normalize();
+   theDirection = ecef;
+}
+   
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimEcefRay(ossimGpt, ossimGpt)
+//  
+//  Constructs a ray originating at "from" and pointing in direction of "to"
+//  
+//*****************************************************************************
+ossimEcefRay::ossimEcefRay(const ossimGpt& from,
+                           const ossimGpt& to)
+   : theOrigin(from)
+{
+   ossimEcefVector ecef (ossimEcefPoint(to) - ossimEcefPoint(from));
+   ecef.normalize();
+   theDirection = ecef;
+}
+   
+//*****************************************************************************
+//  METHOD: ossimEcefRay::intersectAboveEarthEllipsoid
+//  
+//  Intersects the ray with the given elevation above the earth ellipsoid.
+//  
+//*****************************************************************************
+ossimEcefPoint ossimEcefRay::intersectAboveEarthEllipsoid
+   (const double&     argHeight,
+    const ossimDatum* argDatum) const
+{
+   const ossimDatum* datum = argDatum;
+   if (!datum)
+      datum = ossimDatumFactory::instance()->wgs84();
+
+   //***
+   // Pass the call on to ellipsoid where intersection math is implemented:
+   //***
+   ossimEcefPoint solution;
+   bool intersected = datum->ellipsoid()->nearestIntersection
+                      (*this, argHeight, solution);
+
+   if (!intersected)
+      solution.makeNan();
+
+   return solution;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefRay.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefRay.h
new file mode 100644
index 0000000000..f22c751eeb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefRay.h
@@ -0,0 +1,198 @@
+//*****************************************************************************
+// FILE: ossimEcefRay.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//  Class for representing a ray in the earth-centered, earth-fixed (ECEF)
+//  coordinate system. A ray is defined as having an origin point and a
+//  unit direction vector radiating from the origin.
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimEcefRay.h,v 1.10 2004/04/02 22:03:54 gpotts Exp $
+
+#ifndef ossimEcefRay_HEADER
+#define ossimEcefRay_HEADER
+
+#include <stdio.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/context/ossimNotifyContext.h>
+
+class OSSIMDLLEXPORT ossimGpt;
+class OSSIMDLLEXPORT ossimLsrRay;
+
+//*****************************************************************************
+//  CLASS: ossimEcefRay
+//
+//*****************************************************************************
+class OSSIMDLLEXPORT ossimEcefRay
+{
+public:
+   /*!
+    * CONSTRUCTORS: 
+    */
+   ossimEcefRay() {};
+     
+   ossimEcefRay(const ossimEcefRay& copy_this)
+      : theOrigin(copy_this.theOrigin), theDirection(copy_this.theDirection) {}
+   
+   ossimEcefRay(const ossimEcefPoint&  origin,
+                const ossimEcefVector& direction)
+      : theOrigin(origin), theDirection(direction.unitVector()) {}
+   
+   ossimEcefRay(const ossimEcefPoint& from,
+                const ossimEcefPoint& to);
+   
+   ossimEcefRay(const ossimGpt& from,
+                const ossimGpt& to);
+
+   bool isNan()const
+      {
+         return theOrigin.isNan()&&theDirection.isNan();
+      }
+   bool hasNans()const
+      {
+         return theOrigin.isNan()||theDirection.isNan();
+      }
+   void makeNan()
+      {
+         theOrigin.makeNan();
+         theDirection.makeNan();
+      }
+   /*!
+    * OPERATORS:
+    */
+   const ossimEcefRay& operator= (const ossimEcefRay& r); // inline below
+   bool                operator==(const ossimEcefRay& r) const; // inline below
+   bool                operator!=(const ossimEcefRay& r) const; // inline below
+   
+   /*!
+    * DATA ACCESS METHODS:
+    */
+   const ossimEcefPoint&  origin()    const     { return theOrigin; }
+   const ossimEcefVector& direction() const     { return theDirection; }
+   void  setOrigin(const ossimEcefPoint& orig)  { theOrigin = orig; }
+   void  setDirection(const ossimEcefVector& d) { theDirection=d.unitVector();}
+
+   /*!
+    * Extends the ray by distance t (meters) from the origin to the ECEF
+    * point returned.
+    */
+   ossimEcefPoint extend(const double& t) const; // inline below
+
+   /*!
+    * This method computes a ray with the same origin but a new direction
+    * corresponding to a reflection from some surface defined by its normal
+    * vector (assumed to be a unit vector):
+    */
+   ossimEcefRay reflectRay(const ossimEcefVector& normal) const;// inline below
+
+   /*!
+    * Intersects the ray with the given elevation above the earth ellipsoid.
+    */
+   ossimEcefPoint intersectAboveEarthEllipsoid
+      (const double& heightAboveEllipsoid,
+       const ossimDatum* aDatum = ossimDatumFactory::instance()->wgs84()) const;
+                                       
+   /*!
+    * Debug Dump
+    */
+   void print(ostream& os = ossimNotify(ossimNotifyLevel_INFO)) const; // inline below
+   
+   friend ostream& operator<< (ostream& os , const ossimEcefRay& instance)
+      { instance.print(os); return os; }
+
+private:
+   ossimEcefPoint  theOrigin;
+   ossimEcefVector theDirection;
+}; 
+
+//================== BEGIN DEFINITIONS FOR INLINE METHODS =====================
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefRay::operator=(ossimEcefRay)
+//*****************************************************************************
+inline const ossimEcefRay& ossimEcefRay::operator=(const ossimEcefRay& r)
+{
+   theOrigin = r.theOrigin;
+   theDirection = r.theDirection;
+   return *this;
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefRay::operator==(ossimEcefRay)
+//*****************************************************************************
+inline bool ossimEcefRay::operator==(const ossimEcefRay& r) const
+{
+   return ((theOrigin == r.theOrigin) && (theDirection == r.theDirection));
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefRay::operator!=(ossimEcefRay)
+//*****************************************************************************
+inline bool ossimEcefRay::operator!=(const ossimEcefRay& r) const 
+{
+   return !(*this == r);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefRay::extend(double t)
+//  
+//   Extends the ray by distance t (meters) from the origin to the ECEF
+//   point returned.
+//*****************************************************************************
+inline ossimEcefPoint ossimEcefRay::extend(const double& t) const
+{
+   return (theOrigin + theDirection*t);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefRay::reflectRay(normal)
+//  
+//   This method computes a ray with the same origin but a new direction
+//   corresponding to a reflection from some surface defined by its normal
+//   vector:
+//*****************************************************************************
+inline ossimEcefRay
+ossimEcefRay::reflectRay(const ossimEcefVector& normal) const
+{
+   ossimEcefVector new_dir(theDirection - normal*2.0*normal.dot(theDirection));
+   return ossimEcefRay(theOrigin, new_dir);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefRay::print(ostream)
+//  Dumps contents for debug purposes.
+//*****************************************************************************
+inline void ossimEcefRay::print(ostream& os) const
+{
+   os << "(ossimEcefRay)\n"
+      << "   theOrigin    = " << theOrigin
+      << "\n   theDirection = " << theDirection << ends;
+}
+   
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefVector.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefVector.h
new file mode 100644
index 0000000000..1133975e47
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimEcefVector.h
@@ -0,0 +1,300 @@
+//*****************************************************************************
+// FILE: ossimEcefVector.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of a 3D vector object in the Earth-centered, earth
+//   fixed (ECEF) coordinate system.
+//
+//   NOTE: There is no associated ossimEcefVector.cc file. All methods are
+//         inlined here
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimEcefVector.h,v 1.6 2005/05/13 17:39:02 gpotts Exp $
+
+#ifndef ossimEcefVector_HEADER
+#define ossimEcefVector_HEADER
+
+#include <stdio.h>
+#include <math.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimColumnVector3d.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/context/ossimNotifyContext.h>
+
+//*****************************************************************************
+//  CLASS: ossimEcefVector
+//
+//*****************************************************************************
+class OSSIMDLLEXPORT ossimEcefVector
+{
+public:
+   /*!
+    * CONSTRUCTORS: 
+    */
+   ossimEcefVector()
+      : theData(0,0,0) {}
+      
+   ossimEcefVector(const ossimEcefVector& copy_this)
+      : theData (copy_this.theData) {}
+
+   ossimEcefVector(const ossimEcefPoint& from,
+                   const ossimEcefPoint& to)
+      : theData (to.data() - from.data()) {}
+   
+   ossimEcefVector(const ossimGpt& from,
+                   const ossimGpt& to)
+      : theData ((ossimEcefPoint(to) - ossimEcefPoint(from)).data()) {}
+
+   ossimEcefVector(const double& x,
+                   const double& y,
+                   const double& z)
+      : theData(x, y, z) {}
+
+   ossimEcefVector(const ossimColumnVector3d& assign_this)
+      : theData(assign_this) {}
+
+
+   void makeNan()
+      {
+         theData[0] = OSSIM_DBL_NAN;
+         theData[1] = OSSIM_DBL_NAN;
+         theData[2] = OSSIM_DBL_NAN;
+      }
+   
+   bool hasNans()const
+      {
+         return ((theData[0]==OSSIM_DBL_NAN)||
+                 (theData[1]==OSSIM_DBL_NAN)||
+                 (theData[2]==OSSIM_DBL_NAN));
+                           
+      }
+
+   bool isNan()const
+      {
+         return ((theData[0]==OSSIM_DBL_NAN)&&
+                 (theData[1]==OSSIM_DBL_NAN)&&
+                 (theData[2]==OSSIM_DBL_NAN));
+         
+      }
+   /*!
+    * OPERATORS: (all inlined below)
+    */
+   inline ossimEcefVector        operator- () const; 
+   inline ossimEcefVector        operator+ (const ossimEcefVector&) const;
+   inline ossimEcefVector        operator- (const ossimEcefVector&) const;
+   inline ossimEcefPoint         operator+ (const ossimEcefPoint&)  const;
+   inline ossimEcefVector        operator* (const double&)          const;
+   inline ossimEcefVector        operator/ (const double&)          const;
+   inline bool                   operator==(const ossimEcefVector&) const;
+   inline bool                   operator!=(const ossimEcefVector&) const;
+   inline const ossimEcefVector& operator= (const ossimEcefVector&);
+
+   /*!
+    * Vector-related functions:  (all inlined below)
+    */
+   inline double          dot    (const ossimEcefVector&) const;
+   inline double          angleTo(const ossimEcefVector&) const; // degrees
+   inline ossimEcefVector cross  (const ossimEcefVector&) const;
+   inline ossimEcefVector unitVector()                    const;
+   inline double          magnitude()                     const; // meters
+   inline double length() const;
+   inline double          normalize();
+   
+   /*!
+    * COMPONENT ACCESS METHODS: 
+    */
+   double    x() const { return theData[0]; }
+   double&   x()       { return theData[0]; }
+   double    y() const { return theData[1]; }
+   double&   y()       { return theData[1]; }
+   double    z() const { return theData[2]; }
+   double&   z()       { return theData[2]; }
+   double& operator [](int idx){return theData[idx];}
+   const double& operator [](int idx)const{return theData[idx];}
+
+   const ossimColumnVector3d& data() const { return theData; }
+   ossimColumnVector3d&       data()       { return theData; }
+
+   /*!
+    * Debug Dump: 
+    */
+   void print(ostream& os = ossimNotify(ossimNotifyLevel_INFO)) const
+      {	 os << "(ossimEcefVector) " << theData; }
+
+   friend ostream& operator<< (ostream& os , const ossimEcefVector& instance)
+      { instance.print(os); return os; }
+
+protected:
+   ossimColumnVector3d theData;
+};
+
+//================== BEGIN DEFINITIONS FOR INLINE METHODS =====================
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::operator-()
+//  Reverses direction of vector.
+//*****************************************************************************
+inline ossimEcefVector ossimEcefVector::operator-() const
+{
+   return ossimEcefVector(-theData);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::operator+(const ossimEcefVector&)
+//*****************************************************************************
+inline ossimEcefVector
+ossimEcefVector::operator+(const ossimEcefVector& v) const
+{
+   return ossimEcefVector(theData + v.theData);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::operator-(const ossimEcefVector&)
+//*****************************************************************************
+inline ossimEcefVector
+ossimEcefVector::operator-(const ossimEcefVector& v) const
+{
+   return ossimEcefVector(theData - v.theData);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::operator+(const ossimEcefPoint&) 
+//*****************************************************************************
+inline  ossimEcefPoint
+ossimEcefVector::operator+(const ossimEcefPoint& p) const
+{
+   return ossimEcefPoint(theData + p.data());
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::operator*(const double&)
+//*****************************************************************************
+inline ossimEcefVector ossimEcefVector::operator*(const double& scalar) const
+{
+   return ossimEcefVector(theData*scalar);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::operator/(const double&)
+//*****************************************************************************
+inline ossimEcefVector ossimEcefVector::operator/(const double& scalar) const
+{
+   return ossimEcefVector(theData/scalar);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::operator==(const ossimEcefVector&)
+//*****************************************************************************
+inline bool ossimEcefVector::operator==(const ossimEcefVector& v) const
+{
+   return (theData == v.theData);
+}
+   
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::operator!=(const ossimEcefVector&)
+//*****************************************************************************
+inline bool ossimEcefVector::operator!=(const ossimEcefVector& v) const
+{
+   return (theData != v.theData);
+}
+   
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::operator=
+//*****************************************************************************
+inline const ossimEcefVector&
+ossimEcefVector::operator=(const ossimEcefVector& v)
+{
+   theData = v.theData;
+   return *this;
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::dot()
+//  Computes the scalar product.
+//*****************************************************************************
+inline double ossimEcefVector::dot(const ossimEcefVector& v) const
+{
+   return theData.dot(v.theData);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::angleTo()
+//  Returns the angle subtended (in DEGREES) between this and arg vector
+//*****************************************************************************
+inline double ossimEcefVector::angleTo(const ossimEcefVector& v) const
+{
+   double mag_product = theData.magnitude() * v.theData.magnitude();
+   return acosd(theData.dot(v.theData)/mag_product);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::cross()
+//  Computes the cross product.
+//*****************************************************************************
+inline ossimEcefVector ossimEcefVector::cross(const ossimEcefVector& v) const
+{
+   return ossimEcefVector(theData.cross(v.theData));
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::unitVector()
+//  Returns a unit vector parallel to this.
+//*****************************************************************************
+inline ossimEcefVector ossimEcefVector::unitVector() const
+{
+   return ossimEcefVector(theData/theData.magnitude());
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::magnitude()
+//*****************************************************************************
+inline double ossimEcefVector::magnitude() const
+{
+   return theData.magnitude();
+}
+
+inline double ossimEcefVector::length() const
+{
+   return theData.magnitude();
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefVector::normalize()
+//  Normalizes this vector.
+//*****************************************************************************
+inline double ossimEcefVector::normalize()
+{
+   double result = theData.magnitude();
+   if(result > 1e-15)
+   {
+      theData /= result;
+   }
+
+   return result;
+}
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimFilename.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimFilename.cpp
new file mode 100644
index 0000000000..75d04cb926
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimFilename.cpp
@@ -0,0 +1,665 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description: This class provides manipulation of filenames.
+//
+//*************************************************************************
+// $Id: ossimFilename.cpp,v 1.55 2005/11/25 16:14:08 dburken Exp $
+
+#include <ossimConfig.h>  /* to pick up platform defines */
+
+#include <iostream>
+using namespace std;
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "ossimDirectory.h"
+
+#if defined(_WIN32)
+#  include <direct.h>
+#else
+#   if HAVE_UNISTD_H
+#      include <unistd.h>
+#   endif
+#   if HAVE_DIRENT_H
+#      include <dirent.h>
+#   endif
+#   if HAVE_FCNTL_H
+#      include <fcntl.h>
+#   endif
+#endif
+
+#include <sys/stat.h>
+
+#ifdef __BORLANDC__
+#  include <dir.h>
+#  include <direct.h>
+#  include <stdio.h>
+#  include <stdlib.h>
+#  include <io.h>
+#endif
+
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimRegExp.h>
+#include <base/common/ossimConstants.h>
+#include <base/context/ossimNotifyContext.h>
+
+#if defined(_WIN32)
+const char ossimFilename::thePathSeparator = '\\';
+#else
+const char ossimFilename::thePathSeparator = '/';
+#endif
+
+const ossimFilename ossimFilename::NIL=("");
+
+ossimFilename::ossimFilename()
+   : ossimString()
+{}
+
+ossimFilename::ossimFilename(const ossimFilename& src)
+   : ossimString(src)
+{}
+ossimFilename::ossimFilename(const ossimString& src)
+   : ossimString(src)
+{}
+ossimFilename::ossimFilename(const char* src)
+   : ossimString(src)
+{}
+
+template <class Iter> ossimFilename::ossimFilename(Iter s, Iter e)
+   : ossimString(s, e)
+{}
+
+bool ossimFilename::operator == (const ossimFilename& rhs)const
+{
+//    ossimFilename tempLeft = *this;
+//    ossimFilename tempRight = rhs;
+
+//    tempLeft.convertBackToForwardSlashes();
+//    tempRight.convertBackToForwardSlashes();
+
+   return ossimString::operator==(rhs);
+//   return (*this==ossimString(rhs));
+}
+
+bool ossimFilename::operator == (const ossimString& rhs)const
+{
+   return ossimString::operator==(rhs);
+}
+
+bool ossimFilename::operator == (const char* rhs)const
+{
+   return ossimString::operator ==(rhs);
+}
+
+void ossimFilename::convertBackToForwardSlashes()
+{
+   ossimFilename::iterator currentChar = this->begin();
+
+   while(currentChar != this->end())
+   {
+      if(*currentChar == '\\')
+      {
+         *currentChar = '/';
+      }
+      ++currentChar;
+   }
+}
+
+void ossimFilename::convertForwardToBackSlashes()
+{
+   ossimFilename::iterator currentChar = this->begin();
+
+   while(currentChar != this->end())
+   {
+      if(*currentChar == '/')
+      {
+         *currentChar = '\\';
+      }
+      ++currentChar;
+   }
+}
+
+
+bool ossimFilename::exists() const
+{
+#if defined(_WIN32)
+
+	struct _stat sbuf;
+	return( _stat(c_str(), &sbuf ) == 0);
+#else
+	return ((access(c_str(), ossimFilename::OSSIM_EXIST)) == 0);
+#endif
+}
+
+bool ossimFilename::isFile() const
+{
+#if defined(_WIN32)
+
+	struct _stat sbuf;
+	if ( _stat(c_str(), &sbuf ) == -1)
+		return false;
+	return (_S_IFMT & sbuf.st_mode ? true : false);
+#else
+	struct stat sbuf;
+
+	stat(c_str(), &sbuf);
+	return ((sbuf.st_mode & S_IFMT) == S_IFREG);
+#endif
+}
+
+bool ossimFilename::isDir() const
+{
+#if defined(_WIN32)
+
+	struct _stat sbuf;
+	if ( _stat(c_str(), &sbuf ) == -1)
+		return false;
+   return (_S_IFDIR & sbuf.st_mode ? true : false);
+#else
+   struct stat sbuf;
+   if (stat(c_str(), &sbuf) == -1)
+	   return false;
+   return (S_ISDIR(sbuf.st_mode));
+#endif
+}
+
+bool ossimFilename::isReadable() const
+{
+#if defined(_WIN32)
+
+	struct _stat sbuf;
+	if ( _stat(c_str(), &sbuf ) == -1)
+		return false;
+	return (_S_IREAD & sbuf.st_mode ? true : false);
+#else
+	return (access(c_str(), ossimFilename::OSSIM_READ) == 0);
+#endif
+}
+
+bool ossimFilename::isWritable() const
+{
+#if defined(_WIN32)
+
+	struct _stat sbuf;
+	if ( _stat(c_str(), &sbuf ) == -1)
+		return false;
+	return (_S_IWRITE & sbuf.st_mode ? true : false);
+#else
+	return (access(c_str(), ossimFilename::OSSIM_WRITE) == 0);
+#endif
+}
+
+bool ossimFilename::isExecutable() const
+{
+#if defined(_WIN32)
+
+	struct _stat sbuf;
+	if ( _stat(c_str(), &sbuf ) == -1)
+		return false;
+	return (_S_IEXEC & sbuf.st_mode ? true : false);
+#else
+   return (access(c_str(), ossimFilename::OSSIM_EXE) == 0);
+#endif
+}
+
+ossimString ossimFilename::ext() const
+{
+   ossimFilename file = *this;
+   size_type pos = file.rfind('.');
+   if (pos == npos)
+   {
+      return ossimFilename::NIL;
+   }
+
+   return ossimFilename(file.substr(pos+1));
+}
+
+ossimFilename ossimFilename::file() const
+{
+   ossimFilename file = *this;
+
+   file.convertBackToForwardSlashes();
+
+   size_type pos = file.rfind('/');
+   if (pos == npos)
+      return *this;
+   else
+      return ossimFilename(file.substr(pos+1));
+}
+
+ossimFilename ossimFilename::path() const
+{
+   ossimFilename file = *this;
+   file.convertBackToForwardSlashes();
+
+    size_type pos = file.rfind('/');
+
+    if (pos == 0)
+       return ossimFilename(ossimFilename("/"));
+    if (pos == npos)
+    {
+       // We got to the end of the file and did not find a path separator.
+       return ossimFilename::NIL;
+    }
+
+    return ossimFilename(file.substr(0, pos));
+}
+
+ossimFilename ossimFilename::drive()const
+{
+   ossimFilename tempFile(*this);
+   ossimFilename result;
+
+   tempFile.convertForwardToBackSlashes();
+
+   ossimRegExp regEx("^([a-z|A-Z])+:");
+
+   if(regEx.find(tempFile.c_str()))
+   {
+      result = ossimFilename(ossimString(this->begin() + regEx.start(),
+                                         this->begin() + regEx.end()));
+   }
+   else
+   {
+      result = "";
+   }
+
+   return result;
+}
+
+ossimFilename ossimFilename::fileNoExtension()const
+{
+   ossimFilename f = *this;
+   f.convertBackToForwardSlashes();
+
+   size_type dot_pos   = f.rfind('.');
+   size_type slash_pos = f.rfind('/');
+
+   if(dot_pos == npos)
+   {
+      if(slash_pos == npos)
+      {
+         return *this;
+      }
+      else
+      {
+         return ossimFilename(this->begin()+slash_pos+1,
+                              this->end());
+      }
+   }
+   else if(slash_pos == npos)
+   {
+      return ossimFilename(this->begin(), this->begin()+dot_pos);
+   }
+   else if(slash_pos < dot_pos)
+   {
+      return ossimFilename(this->begin()+slash_pos+1,
+                           this->begin() + dot_pos);
+   }
+
+   return ossimFilename(this->begin()+slash_pos+1,
+                        this->end());
+
+}
+ossimFilename ossimFilename::noExtension()const
+{
+   ossimString drivePart;
+   ossimString pathPart;
+   ossimString filePart;
+   ossimString extPart;
+
+   split(drivePart, pathPart, filePart, extPart);
+
+   extPart.clear();
+
+   ossimFilename result;
+   
+   result.merge(drivePart, pathPart, filePart, extPart);
+   
+   return result;
+}
+
+ossimFilename& ossimFilename::setExtension(const ossimString& e)
+{
+   ossimString newExtPart = e;
+
+   //---
+   // If e has a dot "." in the front of it strip it off...
+   //---
+   if ( (*(e.begin())) == '.')
+   {
+      newExtPart = ossimString(e.begin() + 1, e.end());
+   }
+
+   ossimString drivePart;
+   ossimString pathPart;
+   ossimString filePart;
+   ossimString extPart;
+
+   split(drivePart,
+         pathPart,
+         filePart,
+         extPart);
+
+   merge(drivePart,
+         pathPart,
+         filePart,
+         newExtPart);
+
+   return *this;
+}
+
+ossimFilename& ossimFilename::setPath(const ossimString& p)
+{
+   ossimString drivePart;
+   ossimString pathPart;
+   ossimString filePart;
+   ossimString extPart;
+
+   split(drivePart,
+         pathPart,
+         filePart,
+         extPart);
+
+   merge(drivePart,
+         p,
+         filePart,
+         extPart);
+
+   return *this;
+}
+
+ossimFilename& ossimFilename::setFile(const ossimString& f)
+{
+   ossimString drivePart;
+   ossimString pathPart;
+   ossimString filePart;
+   ossimString extPart;
+
+   split(drivePart,
+         pathPart,
+         filePart,
+         extPart);
+
+   merge(drivePart,
+         pathPart,
+         f,
+         extPart);
+
+   return *this;
+}
+
+
+void ossimFilename::split(ossimString& drivePart,
+                          ossimString& pathPart,
+                          ossimString& filePart,
+                          ossimString& extPart)const
+{
+   drivePart = drive();
+   pathPart  = path();
+   if(drivePart != "")
+   {
+      pathPart = pathPart.substitute(drivePart, "");
+   }
+   filePart  = fileNoExtension();
+   extPart   = ext();
+}
+
+void ossimFilename::merge(const ossimString& drivePart,
+                          const ossimString& pathPart,
+                          const ossimString& filePart,
+                          const ossimString& extPart)
+{
+   ossimFilename result = drivePart;
+
+   if(pathPart != "")
+   {
+      result = result.dirCat(ossimFilename(pathPart));
+   }
+
+   if(filePart!="")
+   {
+      result = result.dirCat(ossimFilename(filePart));
+   }
+
+   if(extPart != "")
+   {
+      result += ".";
+      result += extPart;
+   }
+
+   *this = result;
+}
+
+ossimFilename ossimFilename::dirCat(const ossimFilename& file) const
+{
+   // If this string is empty simply return the input file.
+   if (empty()) return file;
+
+   ossimFilename dir      = *this;
+   ossimFilename tempFile = file;
+
+   dir.convertBackToForwardSlashes();
+
+   // Check the end and see if it already has a "/".
+   string::const_iterator i = dir.end();
+
+   --i; // decrement past the trailing null.
+
+   if ( (*i) != '/')
+   {
+      dir += "/";
+   }
+
+   if( (*(tempFile.begin())) == '/') // let's not duplicate a forward slash
+   {
+      dir += ossimString(tempFile.begin() + 1,
+                         tempFile.end());
+   }
+   else
+   {
+      dir += tempFile;  // Already has a separator.
+   }
+
+   return dir;
+}
+
+ossim_int64 ossimFilename::fileSize() const
+{
+   struct stat sbuf;
+
+#ifndef __BORLANDC__
+   if (stat(c_str(), &sbuf) == 0)
+   {
+      return (ossim_int64)sbuf.st_size;
+   }
+   else
+   {
+      ifstream in(c_str());
+      if(in)
+      {
+         in.seekg(SEEK_END);
+         return (ossim_int64)in.tellg();
+      }
+   }
+#else
+   ifstream in(c_str());
+   if(in)
+   {
+      in.seekg(SEEK_END);
+      return (ossim_int64)in.tellg();
+   }
+#endif
+   return 0;
+}
+
+bool ossimFilename::createDirectory(bool recurseFlag,
+                                  int perm)
+{
+   if(exists()) return true;
+
+   ossimFilename tempFile = *this;
+   tempFile.convertBackToForwardSlashes();
+   vector<ossimString> result;
+
+
+   if(recurseFlag)
+   {
+      ossimString::split(result,"/");
+
+      if(result.size())
+      {
+         ossimString current;
+
+         for(ossim_uint32 i = 1; i < result.size(); ++i)
+         {
+            current += ("/"+result[i]);
+
+            if(current != "/")
+            {
+               if(!ossimFilename(current).exists())
+               {
+
+#if defined(__BORLANDC__)
+                  if ( _mkdir(current.c_str()) != 0 )
+#elif defined(_WIN32)
+                  if ( mkdir(current.c_str()) != 0 )
+#else
+                  if ( mkdir(current.c_str(), perm) != 0 )
+#endif
+                  {
+                     return false;
+                  }
+               }
+            }
+         }
+      }
+   }
+   else
+   {
+#if defined (__BORLANDC__)
+      if ( _mkdir(c_str()) != 0 )
+
+#elif defined(_WIN32)
+      if ( mkdir(c_str()) != 0 )
+#else
+      if ( mkdir(c_str(), perm) != 0 )
+#endif
+      {
+         return false;
+      }
+      else
+      {
+         return true;
+      }
+   }
+   return true;
+}
+
+bool ossimFilename::remove(const ossimFilename& pathname)
+{
+   bool result = true;
+#if defined(__VISUALC__)  || defined(__BORLANDC__) || defined(__WATCOMC__) || \
+    defined(__GNUWIN32__) || defined(_MSC_VER)
+   
+   if(::remove(pathname.c_str()) != 0)
+   {
+      result = false;
+   }
+#elif HAVE_UNISTD_H
+   if(pathname.isDir())
+   {
+      result = (rmdir(pathname) >=0);
+   }
+   else if (unlink(pathname.c_str()) < 0)
+   {
+      result = false;
+   }
+#else
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "WARNING: "
+         << "ossimFilename::remove,  Not supported by platform!"
+         << endl;
+   }
+#endif /* HAVE_UNISTD_H */
+
+   return result;
+}
+
+bool ossimFilename::wildcardRemove(const ossimFilename& pathname)
+{
+   std::vector<ossimFilename> fileListToRemove;
+   ossimFilename tempPathname = pathname;
+   
+   if(!tempPathname.isDir())
+   {
+      ossimFilename file = tempPathname.file();
+      ossimFilename path = tempPathname.path();
+      if(path == "")
+      {
+         path = ".";
+      }
+      ossimDirectory dir;
+      if(dir.open(path))
+      {
+         dir.findAllFilesThatMatch(fileListToRemove,
+                                   file.c_str());
+      }
+      else
+      {
+      }
+   }
+   else
+   {
+      fileListToRemove.push_back(ossimFilename(pathname));
+   }
+   ossim_uint32 idx = 0;
+   bool result = true;
+   for(idx = 0; idx < fileListToRemove.size(); ++idx)
+   {
+#if defined(__VISUALC__)  || defined(__BORLANDC__) || defined(__WATCOMC__) || \
+    defined(__GNUWIN32__) || defined(_MSC_VER)
+      
+      if(remove(fileListToRemove[idx].c_str()) != 0)
+      {
+         result = false;
+      }
+#elif HAVE_UNISTD_H
+      if (unlink(fileListToRemove[idx]) == -1)
+      {
+         result = false;
+      }
+#else
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "WARNING: "
+            << "ossimFilename::remove,  Not supported by platform!"
+            << endl;
+      }
+      result = false;
+#endif /* HAVE_UNISTD_H */
+   }
+   return result;
+}
+   
+bool ossimFilename::remove()const
+{
+   return ossimFilename::remove(*this);
+}
+
+bool ossimFilename::wildcardRemove()const
+{
+   return ossimFilename::wildcardRemove(*this);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimFilename.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimFilename.h
new file mode 100644
index 0000000000..8b79ec1973
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimFilename.h
@@ -0,0 +1,179 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//
+// Description: This class provides manipulation of filenames.
+//
+//*************************************************************************
+// $Id: ossimFilename.h,v 1.21 2005/11/25 16:14:08 dburken Exp $
+
+#ifndef ossimFilename_HEADER
+#define ossimFilename_HEADER
+
+#include "base/common/ossimConstants.h"
+#include "ossimString.h"
+
+class OSSIMDLLEXPORT ossimFilename : public ossimString
+{
+public:
+   enum AccessModes
+   {
+      OSSIM_READ_WRITE = 6,
+      OSSIM_READ       = 4,
+      OSSIM_WRITE      = 2,
+      OSSIM_EXE	       = 1, // The PC docs say that this is ignored
+      OSSIM_EXIST      = 0
+   };
+   ossimFilename();
+   ossimFilename(const ossimFilename& src);
+   ossimFilename(const ossimString& src);
+   ossimFilename(const char* src);
+
+   template <class Iter> ossimFilename(Iter s, Iter e);
+
+   static const ossimFilename NIL;
+
+   bool operator == (const ossimFilename& rhs)const;
+   
+   bool operator == (const ossimString& rhs)const;
+   bool operator == (const char* rhs)const;
+   
+   void convertBackToForwardSlashes();
+   void convertForwardToBackSlashes();
+   
+   // Methods to test ossimFilename for various states.
+   bool        exists()       const;
+   bool        isFile()       const;
+   bool        isDir()        const;
+   bool        isReadable()   const;
+   bool        isWritable()   const;
+   bool        isExecutable() const;
+   ossim_int64 fileSize()     const;
+   
+   // Methods to access parts of the ossimFilename.
+
+   /**
+    * @return "tif" if file is "/data/images/t1.tif".
+    *
+    * @note The '.' (dot) is not returned.
+    */
+   ossimString   ext() const;
+
+   /**
+    * @return @return "/data/images" if file is "/data/images/t1.tif".
+    */
+   ossimFilename path() const;
+
+   /**
+    * @return @return "c:" if file is "c:\data\images\t1.tif".
+    */
+   ossimFilename drive() const;
+   
+   /**
+    * @return @return "t1.tif" if file is "/data/images/t1.tif".
+    */
+   ossimFilename file() const;
+
+   /**
+    * @return @return "t1.tif" if file is "/data/images/t1.tif".
+    */
+   ossimFilename fileNoExtension() const;
+
+   /**
+    * @return @return "/data/images/t1" if file is "/data/images/t1.tif".
+    *
+    * @note  The '.' (dot) is not returned.
+    */
+   ossimFilename noExtension() const;
+
+   /**
+    * Sets the extension of a file name.
+    *
+    * Given:
+    * ossimFilename f = "foo";
+    * f.setExtension("tif");
+    * f now equals "foo.tif"
+    *
+    * Given: 
+    * ossimFilename f = "foo.jpg";
+    * f.setExtension("tif");
+    * f now equals "foo.tif"
+    * 
+    * Given: 
+    * ossimFilename f = "foo.jpg";
+    * f.setExtension(".tif");
+    * f now equals "foo.tif"
+    *
+    * Given: 
+    * ossimFilename f = "foo.";
+    * ossimFilename f2;
+    * f2 = f.setExtension("tif");
+    * f now equals "foo.tif"
+    * f2 now equals "foo.tif"
+    *
+    * @param e Extension to add or replace.
+    *
+    * @returns a reference to this.
+    */
+   ossimFilename& setExtension(const ossimString& e);
+   
+   ossimFilename& setPath(const ossimString& p);
+   ossimFilename& setFile(const ossimString& f);
+   
+   void split(ossimString& drivePart,
+              ossimString& pathPart,
+              ossimString& filePart,
+              ossimString& extPart)const;
+   
+   void merge(const ossimString& drivePart,
+              const ossimString& pathPart,
+              const ossimString& filePart,
+              const ossimString& extPart);
+   /*!
+    * Returns file appended onto this string. Path seperator is always placed
+    * between this and file.  Returns file if this string is empty.
+    * Given: this = /foo  and file  = bar output  = /foo/bar
+    * Given: this = /foo/ and file  = bar output  = /foo/bar
+    */
+   ossimFilename dirCat(const ossimFilename& file) const;
+
+   /*!
+    */
+   bool createDirectory(bool recurseFlag=true,
+                        int perm=0775);
+
+   /*!
+    * Removes pathname from filesystem if supported by platform.
+    * Return true on success, false on error.
+    * If supported will set errno and output equivalent string if one occurs.
+    */
+   static bool remove(const ossimFilename& pathname);
+
+   /**
+    * Will use a wildcard remove.  NOTE:  This is in
+    * a regular expression format so if you want all
+    * files with prefix myfile to be erased then you would give
+    * it <path>/myfile.*
+    *
+    * The . here is a regular expression '.' character which says any character
+    * and the * "is any number of"
+    * 
+    */ 
+   static bool wildcardRemove(const ossimFilename& pathname);
+   
+   bool remove()const;
+   bool wildcardRemove()const;
+   
+   /*!
+    * since windows uses \ for path separation
+    * and unix / we need to be consistent.
+    */
+   static const char thePathSeparator;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt.cpp
new file mode 100644
index 0000000000..2e0e71a2f0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt.cpp
@@ -0,0 +1,107 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+// Description:
+//
+// Contains class definitions for ossimFpt.
+// 
+//*******************************************************************
+//  $Id: ossimFpt.cpp,v 1.3 2001/10/27 20:16:11 gpotts Exp $
+
+#include <iostream>
+#include <iomanip>
+
+#include "ossimFpt.h"
+#include "ossimIpt.h"
+#include "ossimDpt.h"
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimFpt::ossimFpt(const ossimIpt& pt)
+   :
+      x(pt.x), y(pt.y)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimFpt::ossimFpt(const ossimDpt& pt)
+   :
+      x(pt.x), y(pt.y)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+const ossimFpt& ossimFpt::operator=(const ossimDpt& pt)
+{
+   x = pt.x;
+   y = pt.y;
+   
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   return *this;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+const ossimFpt& ossimFpt::operator=(const ossimIpt& pt)
+{
+   x = pt.x;
+   y = pt.y;
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   
+   return *this;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+void ossimFpt::print(std::ostream& os) const
+{
+   os << std::setiosflags(std::ios::fixed) << std::setprecision(15)
+      << "( " << x << " " << y << " )";
+}
+
+//*******************************************************************
+// friend function:
+//*******************************************************************
+std::ostream& operator<<(std::ostream& os, const ossimFpt& pt)
+{
+   pt.print(os);
+   
+   return os;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt.h
new file mode 100644
index 0000000000..f0506a2fa4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt.h
@@ -0,0 +1,100 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for fpt.
+// Used to represent a two dimensional point containing data members x and y.
+//*******************************************************************
+//  $Id: ossimFpt.h,v 1.7 2003/05/13 11:31:02 dburken Exp $
+
+#ifndef ossimFpt_HEADER
+#define ossimFpt_HEADER
+#include <iostream>
+#include "base/common/ossimConstants.h"
+#include "base/common/ossimCommon.h"
+
+// Forward class declarations.
+class OSSIMDLLEXPORT ossimIpt;
+class OSSIMDLLEXPORT ossimDpt;
+
+
+class OSSIMDLLEXPORT ossimFpt
+{
+public:
+
+   ossimFpt() : x(0), y(0) {}
+
+   ossimFpt(ossim_float32 x, ossim_float32 y)
+      : x(x), y(y)
+      {}
+
+   ossimFpt(ossim_float64 x, ossim_float64 y)
+      : x((ossim_float64)x), y((ossim_float64)y)
+      {}
+         
+   ossimFpt(const ossimFpt& pt) : x(pt.x), y(pt.y) {}
+
+   ossimFpt(const ossimDpt& pt);
+
+   ossimFpt(const ossimIpt& pt);
+
+   const ossimFpt& operator=(const ossimFpt& pt);
+
+   const ossimFpt& operator=(const ossimDpt&);
+
+   const ossimFpt& operator=(const ossimIpt&);
+
+   bool operator==(const ossimFpt& pt) const
+      { return ( (x == pt.x) && (y == pt.y) ); } 
+
+   bool operator!=(const ossimFpt& pt) const
+      { return ( (x != pt.x) || (y != pt.y) ); }
+
+   void makeNan(){x = OSSIM_FLT_NAN; y=OSSIM_FLT_NAN;}
+   
+   bool hasNans()const
+      {
+         return (ossimIsNan(x) || ossimIsNan(y));
+      }
+   
+   void print(std::ostream& os) const;
+   
+   friend std::ostream& operator<<(std::ostream& os, const ossimFpt& pt);
+
+   //***
+   // Public data members:
+   //***
+   ossim_float32 x;
+   ossim_float32 y;
+};
+
+inline const ossimFpt& ossimFpt::operator=(const ossimFpt& pt)
+{
+   if (this != &pt)
+   {
+      x = pt.x;
+      y = pt.y;
+   }
+   
+   return *this;
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt3d.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt3d.cpp
new file mode 100644
index 0000000000..443824f9e1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt3d.cpp
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+// Description:
+//
+// Contains class definitions for ossimFpt3d.
+//
+//*******************************************************************
+//  $Id: ossimFpt3d.cpp,v 1.1.1.1 2001/02/05 20:13:22 dburken Exp $
+
+#include <iostream>
+#include <iomanip>
+using namespace std;
+
+#include "ossimFpt3d.h"
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ostream& ossimFpt3d::print(ostream& os) const
+{
+   os << setiosflags(ios::fixed) << setprecision(14)
+      << "( " << x << " " << y << " " << z << " )";
+   return os;
+}
+
+//*******************************************************************
+// friend function:
+//*******************************************************************
+ostream& operator<<(ostream& os, const ossimFpt3d& pt)
+{
+   return pt.print(os);
+}
+
+//*******************************************************************
+// friend function:
+//*******************************************************************
+istream& operator>>(istream& is, ossimFpt3d& pt)
+{
+   is >> pt.x >> pt.y >> pt.z;
+
+   return is;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt3d.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt3d.h
new file mode 100644
index 0000000000..276692fdc8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimFpt3d.h
@@ -0,0 +1,63 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:  
+//
+// Contains class declaration for fpt3d.
+//
+// Used to represent a three dimensional point containing an x and y data
+// member.
+//
+//*******************************************************************
+// $Id: ossimFpt3d.h,v 1.3 2003/05/13 11:31:02 dburken Exp $
+
+#ifndef ossimFpt3d_HEADER
+#define ossimFpt3d_HEADER
+
+#include "../common/ossimConstants.h"
+#include "ossimFpt.h"
+
+
+class OSSIMDLLEXPORT ossimFpt3d
+{
+public:
+
+   ossimFpt3d()
+      : x(0.0), y(0.0), z(0.0)
+      {}
+   ossimFpt3d(const ossim_float32& aX,
+              const ossim_float32& aY,
+              const ossim_float32& aZ)
+      : x(aX), y(aY), z(aZ)
+      {}
+
+   ossimFpt pt2d() const { return ossimFpt(x, y); }
+   
+   ostream& print(ostream& os) const;
+
+   friend ostream& operator<<(ostream& os, const ossimFpt3d& pt);
+   friend istream& operator>>(istream& is, ossimFpt3d& pt);
+
+   ossim_float32 x;
+   ossim_float32 y;
+   ossim_float32 z;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoPolygon.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoPolygon.cpp
new file mode 100644
index 0000000000..8366f6786a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoPolygon.cpp
@@ -0,0 +1,356 @@
+//*****************************************************************************
+// FILE: ossimPolygon.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Garrett Potts (gpotts@imagelinks.com)
+//
+//*****************************************************************************
+//  $Id: ossimGeoPolygon.cpp,v 1.10 2003/09/09 18:33:57 dburken Exp $
+
+#include <sstream>
+#include <algorithm>
+#include "ossimGeoPolygon.h"
+#include "base/factory/ossimDatumFactory.h"
+#include "base/data_types/datum/ossimDatum.h"
+#include "base/common/ossimKeywordNames.h"
+
+static const char* NUMBER_VERTICES_KW = "number_vertices";
+
+std::ostream& operator <<(std::ostream& out, const ossimGeoPolygon& poly)
+{
+   if(poly.size())
+   {
+      if(poly.size() >1)
+      {
+         for(ossim_uint32 i = 0; i <  poly.size()-1; ++i)
+         {
+            out << "P" << i << ": " << poly[i] << endl;
+         }
+         out << "P"  << (poly.size()-1)
+             << ": " << poly[poly.size()-1] << endl;
+      }
+      else
+      {
+         out << "P0: " << poly[0] << endl;
+      }
+   }
+
+   return out;
+}
+
+bool ossimGeoPolygon::hasNans()const
+{
+   int upper = (int)theVertexList.size();
+   int i = 0;
+
+   for(i = 0; i < upper; ++i)
+   {
+      if(theVertexList[i].hasNans())
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+bool ossimGeoPolygon::vertex(int index, ossimGpt& v) const 
+{
+   if((index >= (int)theVertexList.size()) ||
+      (index < 0))
+   {
+      return false;
+   }
+
+   v = theVertexList[index];
+   theCurrentVertex = index;
+
+   return true;
+}
+
+bool ossimGeoPolygon::nextVertex(ossimDpt& v) const 
+{
+   ++theCurrentVertex;
+   if(theCurrentVertex >= (ossim_int32)theVertexList.size())
+   {
+      return false;
+   }
+   v = theVertexList[theCurrentVertex];
+   
+   return true;
+}
+
+void ossimGeoPolygon::stretchOut(ossimGeoPolygon& newPolygon,
+                                 double displacement)
+{
+   newPolygon.resize(size());
+   if(size() >= 3)
+   {
+      const ossimDatum* datum = theVertexList[0].datum();
+      checkOrdering();
+      double signMult = 1.0;
+      if(theOrderingType == OSSIM_COUNTERCLOCKWISE_ORDER)
+      {
+         signMult = -1.0;
+      }
+      
+      ossimDpt prev, current, next;
+
+      ossim_uint32 prevI;
+      ossim_uint32 currentI;
+      ossim_uint32 nextI;
+      ossim_uint32 i = 0;
+      ossim_uint32 upper = size();
+
+      bool equalEndsFlag = false;
+      if(theVertexList[0] == theVertexList[theVertexList.size()-1])
+      {
+         equalEndsFlag = true;
+         prevI    = 0;
+         currentI = 1;
+         nextI    = 2;
+         i = 1;
+         --upper;
+      }
+      else
+      {
+         equalEndsFlag = false;
+         prevI    = size()-1;
+         currentI = 0;
+         nextI    = 1;
+      }
+      for(; i < upper;++i)
+      {
+         prev    = theVertexList[prevI];
+         current = theVertexList[currentI];
+         next    = theVertexList[nextI];
+
+         ossimDpt averageNormal;
+         
+         ossimDpt diffPrev = current - prev;
+         ossimDpt diffNext = next - current;
+
+         diffPrev = diffPrev*(1.0/diffPrev.length());
+         diffNext = diffNext*(1.0/diffNext.length());
+
+         ossimDpt diffPrevNormal(-diffPrev.y,
+                                 diffPrev.x);
+         ossimDpt diffNextNormal(-diffNext.y,
+                                 diffNext.x);
+         
+         averageNormal     = (diffPrevNormal + diffNextNormal);
+         averageNormal     = averageNormal*(signMult*(1.0/averageNormal.length()));
+         ossimDpt newPoint = ossimDpt( theVertexList[i].lond(),
+                                       theVertexList[i].latd()) +
+                             averageNormal*displacement;
+         newPolygon[i].latd(newPoint.lat);
+         newPolygon[i].lond(newPoint.lon);
+         newPolygon[i].height(theVertexList[i].height());
+         newPolygon[i].datum(datum);
+         
+         ++prevI;
+         ++currentI;
+         ++nextI;
+
+         prevI%=size();
+         nextI%=size();
+      }
+      if(equalEndsFlag)
+      {
+         
+         prev    = theVertexList[theVertexList.size()-2];
+         current = theVertexList[0];
+         next    = theVertexList[1];
+         
+         ossimDpt averageNormal;
+         
+         ossimDpt diffPrev = current - prev;
+         ossimDpt diffNext = next - current;
+
+         diffPrev = diffPrev*(1.0/diffPrev.length());
+         diffNext = diffNext*(1.0/diffNext.length());
+
+         ossimDpt diffPrevNormal(-diffPrev.y,
+                                 diffPrev.x);
+         ossimDpt diffNextNormal(-diffNext.y,
+                                 diffNext.x);
+         
+         averageNormal     = (diffPrevNormal + diffNextNormal);
+         averageNormal     = averageNormal*(signMult*(1.0/averageNormal.length()));
+         ossimDpt newPoint = ossimDpt( theVertexList[i].lond(),
+                                       theVertexList[i].latd()) +
+                             averageNormal*displacement;
+         newPolygon[0].latd(newPoint.lat);
+         newPolygon[0].lond(newPoint.lon);
+         newPolygon[0].height(theVertexList[i].height());
+         newPolygon[0].datum(datum);
+         
+         newPolygon[theVertexList.size()-1] = newPolygon[0];
+      }
+   }
+}
+
+
+double ossimGeoPolygon::area()const
+{
+   double area = 0;
+   int i=0;
+   int j=0;
+   int size = theVertexList.size();
+   
+   for (i=0;i<(int)size;i++)
+   {
+      j = (i + 1) % (int)size;
+      area += theVertexList[i].lon * theVertexList[j].lat;
+      area -= theVertexList[i].lat * theVertexList[j].lon;
+   }
+
+   area /= 2;
+
+   return area;
+}
+
+void ossimGeoPolygon::reverseOrder()
+{
+   std::reverse(theVertexList.begin(), theVertexList.end());
+   
+   if(theOrderingType == OSSIM_COUNTERCLOCKWISE_ORDER)
+   {
+      theOrderingType = OSSIM_CLOCKWISE_ORDER;
+   }
+   else if(theOrderingType == OSSIM_CLOCKWISE_ORDER)
+   {
+      theOrderingType =  OSSIM_COUNTERCLOCKWISE_ORDER;
+   }
+   
+}
+
+void ossimGeoPolygon::checkOrdering()const
+{
+   if(theOrderingType == OSSIM_VERTEX_ORDER_UNKNOWN)
+   {
+      double areaValue = area();
+      if(areaValue > 0)
+      {
+         theOrderingType = OSSIM_COUNTERCLOCKWISE_ORDER;
+      }
+      else if(areaValue <= 0)
+      {
+         theOrderingType = OSSIM_CLOCKWISE_ORDER;
+      }
+   }
+}
+
+ossimGpt ossimGeoPolygon::computeCentroid()const
+{
+   if(!size())
+   {
+      return ossimGpt();
+   }
+   ossimDpt average(0.0,0.0);
+   double height=0.0;
+   for(ossim_uint32 i = 0; i < size(); ++i)
+   {
+      average += ossimDpt(theVertexList[i]);
+      height  += theVertexList[i].height();
+   }
+
+   
+   average.x /= size();
+   average.y /= size();
+   height    /= size();
+
+   return ossimGpt(average.y, average.x, height, theVertexList[0].datum());
+}
+
+bool ossimGeoPolygon::saveState(ossimKeywordlist& kwl,
+                                const char* prefix)const
+{
+   int i = 0;
+
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           "ossimGeoPolygon",
+           true);
+   kwl.add(prefix,
+           NUMBER_VERTICES_KW,
+           theVertexList.size(),
+           true);
+   if(theVertexList.size())
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::DATUM_KW,
+              theVertexList[0].datum()->code(),
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::DATUM_KW,
+              "WGE",
+              true);
+   }
+   
+   for(i = 0; i < (int)theVertexList.size();++i)
+   {
+      ossimString vert = "v"+ossimString::toString(i);
+      ossimString value = (ossimString::toString(theVertexList[i].latd()) + " " +
+                           ossimString::toString(theVertexList[i].lond())  + " " +
+                           ( theVertexList[i].isHgtNan()?ossimString("nan"):ossimString::toString(theVertexList[i].height())));
+      kwl.add(prefix,
+              vert.c_str(),
+              value.c_str(),
+              true);
+   }
+
+   return true;
+}
+
+bool ossimGeoPolygon::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   const char* number_vertices = kwl.find(prefix, NUMBER_VERTICES_KW);
+   const char* datumStr = kwl.find(prefix, ossimKeywordNames::DATUM_KW);
+   const ossimDatum* datum = ossimDatumFactory::instance()->create(datumStr);
+   
+   theVertexList.clear();
+   int i = 0;
+   int vertexCount = ossimString(number_vertices).toLong();
+   double lat = 0.0, lon =0.0;
+   ossimString height;
+   for(i = 0; i < vertexCount; ++i)
+   {
+      ossimString v = kwl.find(prefix, (ossimString("v")+ossimString::toString(i)).c_str());
+      v = v.trim();
+
+      istringstream vStream(v);
+      vStream >> lat >> lon >> height;
+      height = height.trim();
+      if(height == "nan")
+      {
+         theVertexList.push_back(ossimGpt(lat, lon, OSSIM_DBL_NAN, datum));
+      }
+      else
+      {
+         theVertexList.push_back(ossimGpt(lat, lon, height.toDouble(), datum));
+      }
+   }
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoPolygon.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoPolygon.h
new file mode 100644
index 0000000000..e9ef92e87d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoPolygon.h
@@ -0,0 +1,170 @@
+//*****************************************************************************
+// FILE: ossimPolygon.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Garrett Potts (gpotts@imagelinks.com)
+//
+//*****************************************************************************
+//  $Id: ossimGeoPolygon.h,v 1.13 2006/01/03 20:55:56 gpotts Exp $
+#ifndef ossimGeoPolygon_HEADER
+#define ossimGeoPolygon_HEADER
+#include <vector>
+#include "ossimGpt.h"
+#include "ossimKeywordlist.h"
+
+class OSSIMDLLEXPORT ossimGeoPolygon
+{
+public:
+   friend OSSIM_DLL std::ostream& operator <<(std::ostream& out, const ossimGeoPolygon& poly);
+   ossimGeoPolygon():theCurrentVertex(-1),
+                     theOrderingType(OSSIM_VERTEX_ORDER_UNKNOWN)
+      {}
+   ossimGeoPolygon(const std::vector<ossimGpt>& points)
+      :theVertexList(points),
+       theOrderingType(OSSIM_VERTEX_ORDER_UNKNOWN)
+      {
+         theCurrentVertex = 0;
+      }
+   ossimGeoPolygon(const ossimGeoPolygon& rhs)
+      {
+         theVertexList   = rhs.theVertexList;
+         theOrderingType = rhs.theOrderingType;
+	 theAttributeList = rhs.theAttributeList;
+	 theHoleList = rhs.theHoleList;
+         theCurrentVertex = rhs.theCurrentVertex;
+      }
+
+    void addPoint(const ossimGpt& pt)
+      {
+         theVertexList.push_back(pt);
+      }
+   void addPoint(double lat, double lon, double h=OSSIM_DBL_NAN, const ossimDatum* datum=NULL)
+      {
+         theVertexList.push_back(ossimGpt(lat, lon, h, datum));
+      }
+   void addAttribute( const ossimString& attribute )
+     {
+       theAttributeList.push_back( attribute );
+     }
+   void addHole( const ossimGeoPolygon& polygon )
+     {
+       theHoleList.push_back( polygon );
+     }
+   ossimGpt& operator[](int index)
+      {
+         return theVertexList[index];
+      }
+   const ossimGpt& operator[](int index)const
+      {
+         return theVertexList[index];
+      }
+   
+   const vector<ossimGpt>& getVertexList()const
+      {
+         return theVertexList;
+      }
+   vector<ossimString>& getAttributeList()
+      {
+         return theAttributeList;
+      }
+   vector<ossimGeoPolygon>& getHoleList()
+      {
+         return theHoleList;
+      }
+
+   void clear()
+      {
+         theVertexList.clear();
+      }
+   ossim_uint32 size()const
+      {
+         return (ossim_uint32)theVertexList.size();
+      }
+   void resize(ossim_uint32 newSize)
+      {
+         theVertexList.resize(newSize);
+         theCurrentVertex = 0;
+         theOrderingType  = OSSIM_VERTEX_ORDER_UNKNOWN;
+      }
+   const ossimGeoPolygon& operator = (const vector<ossimGpt>& rhs)
+      {
+         theVertexList = rhs;
+         theCurrentVertex = 0;
+         theOrderingType = OSSIM_VERTEX_ORDER_UNKNOWN;
+
+         return *this;
+      }
+
+   const ossimGeoPolygon& operator = (const ossimGeoPolygon& rhs)
+      {
+         if(&rhs != this)
+         {
+            theVertexList = rhs.theVertexList;
+            theCurrentVertex = rhs.theCurrentVertex;
+	    theAttributeList = rhs.theAttributeList;
+	    theHoleList = rhs.theHoleList;
+         }
+         theOrderingType = rhs.theOrderingType;
+
+         return *this;
+      }
+   void stretchOut(ossimGeoPolygon& newPolygon,
+                   double displacement);
+   double area()const;
+
+   ossimGpt computeCentroid()const;
+   
+   bool vertex(int index, ossimGpt& v) const;
+   bool nextVertex(ossimDpt& v) const;
+   bool hasNans()const;
+   void reverseOrder();
+   
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix=0)const;
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix=0);
+    
+   void checkOrdering()const;
+   ossimVertexOrdering getOrdering()const
+      {
+         if(theOrderingType == OSSIM_VERTEX_ORDER_UNKNOWN)
+         {
+            checkOrdering();
+         }
+         return theOrderingType;
+      }
+   void setOrdering(ossimVertexOrdering ordering)
+      {
+         theOrderingType = ordering;
+      }
+protected:
+   vector<ossimGpt> theVertexList;
+   vector<ossimString> theAttributeList;
+   vector<ossimGeoPolygon> theHoleList;
+   mutable ossim_int32 theCurrentVertex;
+   
+   /*!
+    * This enumeration is found in ossimConstants.h
+    */
+   mutable ossimVertexOrdering theOrderingType;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGeocent.c b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeocent.c
new file mode 100644
index 0000000000..0ca395230b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeocent.c
@@ -0,0 +1,384 @@
+/***************************************************************************/
+/* RSC IDENTIFIER:  GEOCENTRIC
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between Geodetic coordinates (latitude,
+ *    longitude in radians and height in meters) and Geocentric coordinates
+ *    (X, Y, Z) in meters.
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *      GEOCENT_NO_ERROR        : No errors occurred in function
+ *      GEOCENT_LAT_ERROR       : Latitude out of valid range
+ *                                 (-90 to 90 degrees)
+ *      GEOCENT_LON_ERROR       : Longitude out of valid range
+ *                                 (-180 to 360 degrees)
+ *      GEOCENT_A_ERROR         : Semi-major axis less than or equal to zero
+ *      GEOCENT_INV_F_ERROR     : Inverse flattening outside of valid range
+ *								                 (250 to 350)
+ *
+ *
+ * REUSE NOTES
+ *
+ *    GEOCENTRIC is intended for reuse by any application that performs
+ *    coordinate conversions between geodetic coordinates and geocentric
+ *    coordinates.
+ *    
+ *
+ * REFERENCES
+ *    
+ *    An Improved Algorithm for Geocentric to Geodetic Coordinate Conversion,
+ *    Ralph Toms, February 1996  UCRL-JC-123138.
+ *    
+ *    Further information on GEOCENTRIC can be found in the Reuse Manual.
+ *
+ *    GEOCENTRIC originated from : U.S. Army Topographic Engineering Center
+ *                                 Geospatial Information Division
+ *                                 7701 Telegraph Road
+ *                                 Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    GEOCENTRIC has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    GEOCENTRIC was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC version 2.8.1
+ *    2. Windows 95 with MS Visual C++ version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    25-02-97          Original Code
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                               INCLUDES
+ */
+#include <float.h>
+#include <math.h>
+#include <base/data_types/ossimGeocent.h>
+/*
+ *    math.h     - is needed for calls to sin, cos, tan and sqrt.
+ *    geocent.h  - is needed for Error codes and prototype error checking.
+ */
+
+
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+#define PI         3.14159265358979323e0
+#define PI_OVER_2  (PI / 2.0e0)
+#define FALSE      0
+#define TRUE       1
+#define COS_67P5   0.38268343236508977  /* cosine of 67.5 degrees */
+#define AD_C       1.0026000            /* Toms region 1 constant */
+
+
+/***************************************************************************/
+/*
+ *                              GLOBAL DECLARATIONS
+ */
+/* Ellipsoid parameters, default to WGS 84 */
+double Geocent_a = 6378137.0;          /* Semi-major axis of ellipsoid in meters */
+double Geocent_f = 1 / 298.257223563;  /* Flattening of ellipsoid           */
+
+double Geocent_e2 = 0.0066943799901413800;   /* Eccentricity squared  */
+double Geocent_ep2 = 0.00673949675658690300; /* 2nd eccentricity squared */
+/*
+ * These state variables are for optimization purposes.  The only function
+ * that should modify them is Set_Geocentric_Parameters.
+ */
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+long Set_Geocentric_Parameters (double a, 
+                                double f) 
+{ /* BEGIN Set_Geocentric_Parameters */
+/*
+ * The function Set_Geocentric_Parameters receives the ellipsoid parameters
+ * as inputs and sets the corresponding state variables.
+ *
+ *    a  : Semi-major axis of ellipsoid, in meters.          (input)
+ *    f  : Flattening of ellipsoid.						               (input)
+ */
+
+/*  double inv_f = 1 / f; */
+  long Error_Code = GEOCENT_NO_ERROR;
+
+#if 0
+  if (a <= 0.0)
+    Error_Code |= GEOCENT_A_ERROR;
+  if ((inv_f < 250) || (inv_f > 350))
+  { /* Inverse flattening must be between 250 and 350 */
+    Error_Code |= GEOCENT_INV_F_ERROR;
+  }
+#endif
+  if (!Error_Code)
+  {
+    Geocent_a = a;
+    Geocent_f = f;
+    Geocent_e2 = 2 * Geocent_f - Geocent_f * Geocent_f;
+    Geocent_ep2 = (1 / (1 - Geocent_e2)) - 1;
+  }
+  return (Error_Code);
+} /* END OF Set_Geocentric_Parameters */
+
+
+void Get_Geocentric_Parameters (double *a, 
+                                double *f)
+{ /* BEGIN Get_Geocentric_Parameters */
+/*
+ * The function Get_Geocentric_Parameters returns the ellipsoid parameters
+ * to be used in geocentric coordinate conversions.
+ *
+ *    a  : Semi-major axis of ellipsoid, in meters.          (output)
+ *    f  : Flattening of ellipsoid.						               (output)
+ */
+
+  *a = Geocent_a;
+  *f = Geocent_f;
+} /* END OF Get_Geocentric_Parameters */
+
+
+long Convert_Geodetic_To_Geocentric (double Latitude,
+                                     double Longitude,
+                                     double Height,
+                                     double *X,
+                                     double *Y,
+                                     double *Z) 
+{ /* BEGIN Convert_Geodetic_To_Geocentric */
+/*
+ * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates
+ * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
+ * according to the current ellipsoid parameters.
+ *
+ *    Latitude  : Geodetic latitude in radians                     (input)
+ *    Longitude : Geodetic longitude in radians                    (input)
+ *    Height    : Geodetic height, in meters                       (input)
+ *    X         : Calculated Geocentric X coordinate, in meters    (output)
+ *    Y         : Calculated Geocentric Y coordinate, in meters    (output)
+ *    Z         : Calculated Geocentric Z coordinate, in meters    (output)
+ *
+ */
+  long Error_Code = GEOCENT_NO_ERROR;
+  double Rn;            /*  Earth radius at location  */
+  double Sin_Lat;       /*  sin(Latitude)  */
+  double Sin2_Lat;      /*  Square of sin(Latitude)  */
+  double Cos_Lat;       /*  cos(Latitude)  */
+
+#if 0
+  if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+  { /* Latitude out of range */
+    Error_Code |= GEOCENT_LAT_ERROR;
+  }
+  if ((Longitude < -PI) || (Longitude > (2*PI)))
+  { /* Longitude out of range */
+    Error_Code |= GEOCENT_LON_ERROR;
+  }
+#endif
+  if (!Error_Code)
+  { /* no errors */
+    if (Longitude > PI)
+      Longitude -= (2*PI);
+    Sin_Lat = sin(Latitude);
+    Cos_Lat = cos(Latitude);
+    Sin2_Lat = Sin_Lat * Sin_Lat;
+    Rn = Geocent_a / (sqrt(1.0e0 - Geocent_e2 * Sin2_Lat));
+    *X = (Rn + Height) * Cos_Lat * cos(Longitude);
+    *Y = (Rn + Height) * Cos_Lat * sin(Longitude);
+    *Z = ((Rn * (1 - Geocent_e2)) + Height) * Sin_Lat;
+
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Geocentric */
+
+void Convert_Geocentric_To_Geodetic (double X,
+                                     double Y, 
+                                     double Z,
+                                     double *Latitude,
+                                     double *Longitude,
+                                     double *Height)
+{
+   /* BEGIN Convert_Geocentric_To_Geodetic */
+   /*
+    * The function Convert_Geocentric_To_Geodetic converts geocentric
+    * coordinates (X, Y, Z) to geodetic coordinates (latitude, longitude, 
+    * and height), according to the current ellipsoid parameters.
+    *
+    *    X         : Geocentric X coordinate, in meters.         (input)
+    *    Y         : Geocentric Y coordinate, in meters.         (input)
+    *    Z         : Geocentric Z coordinate, in meters.         (input)
+    *    Latitude  : Calculated latitude value in radians.       (output)
+    *    Longitude : Calculated longitude value in radians.      (output)
+    *    Height    : Calculated height value, in meters.         (output)
+    *
+    */
+
+   double d = sqrt(pow(X, 2) + pow(Y, 2));
+
+   double phi2 = Z / ((1 - Geocent_e2) * d);
+   double p = 1.0;
+   double phi1 = 0.0;
+   double N1 = 0.0;
+   double height1 = 0.0;
+   int iterIdx = 0;
+   const int MAX_ITER = 10;
+   if (phi2 != 0.0)
+   {
+      while ( (p > 1e-16) && (iterIdx < MAX_ITER))
+      {
+         phi1 = phi2;
+         N1 = Geocent_a / sqrt(1.0 - (Geocent_e2 * pow(sin(phi1), 2.0)));
+         height1 = (d / cos(phi1) - N1);
+         phi2 = atan((Z / d) * (1.0 + (Geocent_e2 * N1 * sin(phi1)) / Z));
+         p = fabs(phi2 - phi1);
+         ++iterIdx;
+         /* printf("phi: %e   phi2: %e   p: %e  \n", phi1, phi2, p); */
+      }                                                                                           
+   }                                                                                                   
+   else
+   {                                                                                              
+      phi1 = phi2;                                                                                
+      N1 = Geocent_a / sqrt(1.0 - (Geocent_e2 * pow(sin(phi1), 2.0)));                    
+      height1 = (d / cos(phi1)) - N1;                                                             
+   }                                                                                                   
+
+   /* *Latitude = phi2 * 180/PI; */
+   /* *Longitude = atan2(Y, X) * 180/PI; */
+   *Latitude = phi2;                                                                       
+   *Longitude = atan2(Y, X);                                                                
+   *Height = height1; 
+} /* END OF Convert_Geocentric_To_Geodetic */
+
+
+#if 0
+void Convert_Geocentric_To_Geodetic (double X,
+                                     double Y, 
+                                     double Z,
+                                     double *Latitude,
+                                     double *Longitude,
+                                     double *Height)
+{ /* BEGIN Convert_Geocentric_To_Geodetic */
+/*
+ * The function Convert_Geocentric_To_Geodetic converts geocentric
+ * coordinates (X, Y, Z) to geodetic coordinates (latitude, longitude, 
+ * and height), according to the current ellipsoid parameters.
+ *
+ *    X         : Geocentric X coordinate, in meters.         (input)
+ *    Y         : Geocentric Y coordinate, in meters.         (input)
+ *    Z         : Geocentric Z coordinate, in meters.         (input)
+ *    Latitude  : Calculated latitude value in radians.       (output)
+ *    Longitude : Calculated longitude value in radians.      (output)
+ *    Height    : Calculated height value, in meters.         (output)
+ *
+ * The method used here is derived from 'An Improved Algorithm for
+ * Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996
+ */
+
+/* Note: Variable names follow the notation used in Toms, Feb 1996 */
+
+  double W;        /* distance from Z axis */
+  double W2;       /* square of distance from Z axis */
+  double T0;       /* initial estimate of vertical component */
+  double T1;       /* corrected estimate of vertical component */
+  double S0;       /* initial estimate of horizontal component */
+  double S1;       /* corrected estimate of horizontal component */
+  double Sin_B0;   /* sin(B0), B0 is estimate of Bowring aux variable */
+  double Sin3_B0;  /* cube of sin(B0) */
+  double Cos_B0;   /* cos(B0) */
+  double Sin_p1;   /* sin(phi1), phi1 is estimated latitude */
+  double Cos_p1;   /* cos(phi1) */
+  double Rn;       /* Earth radius at location */
+  double Sum;      /* numerator of cos(phi1) */
+  int At_Pole;     /* indicates location is in polar region */
+  double Geocent_b = Geocent_a * (1 - Geocent_f); /* Semi-minor axis of ellipsoid, in meters */
+
+  At_Pole = FALSE;
+  if (X != 0.0)
+  {
+    *Longitude = atan2(Y,X);
+  }
+  else
+  {
+    if (Y > 0)
+    {
+      *Longitude = PI_OVER_2;
+    }
+    else if (Y < 0)
+    {
+      *Longitude = -PI_OVER_2;
+    }
+    else
+    {
+      At_Pole = TRUE;
+      *Longitude = 0.0;
+      if (Z > 0.0)
+      {  /* north pole */
+        *Latitude = PI_OVER_2;
+      }
+      else if (Z < 0.0)
+      {  /* south pole */
+        *Latitude = -PI_OVER_2;
+      }
+      else
+      {  /* center of earth */
+        *Latitude = PI_OVER_2;
+        *Height = -Geocent_b;
+        return;
+      } 
+    }
+  }
+  W2 = X*X + Y*Y;
+  W = sqrt(W2);
+  T0 = Z * AD_C;
+  S0 = sqrt(T0 * T0 + W2);
+  Sin_B0 = T0 / S0;
+  Cos_B0 = W / S0;
+  Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0;
+  T1 = Z + Geocent_b * Geocent_ep2 * Sin3_B0;
+  Sum = W - Geocent_a * Geocent_e2 * Cos_B0 * Cos_B0 * Cos_B0;
+  S1 = sqrt(T1*T1 + Sum * Sum);
+  Sin_p1 = T1 / S1;
+  Cos_p1 = Sum / S1;
+  Rn = Geocent_a / sqrt(1.0 - Geocent_e2 * Sin_p1 * Sin_p1);
+  if (Cos_p1 >= COS_67P5)
+  {
+    *Height = W / Cos_p1 - Rn;
+  }
+  else if (Cos_p1 <= -COS_67P5)
+  {
+    *Height = W / -Cos_p1 - Rn;
+  }
+  else
+  {
+    *Height = Z / Sin_p1 + Rn * (Geocent_e2 - 1.0);
+  }
+  if (At_Pole == FALSE)
+  {
+    *Latitude = atan(Sin_p1 / Cos_p1);
+  }
+} /* END OF Convert_Geocentric_To_Geodetic */
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGeocent.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeocent.h
new file mode 100644
index 0000000000..f23406902e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeocent.h
@@ -0,0 +1,162 @@
+#ifndef GEOCENT_H
+  #define GEOCENT_H
+
+/***************************************************************************/
+/* RSC IDENTIFIER:  GEOCENTRIC
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between Geodetic coordinates (latitude,
+ *    longitude in radians and height in meters) and Geocentric coordinates
+ *    (X, Y, Z) in meters.
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *      GEOCENT_NO_ERROR        : No errors occurred in function
+ *      GEOCENT_LAT_ERROR       : Latitude out of valid range
+ *                                 (-90 to 90 degrees)
+ *      GEOCENT_LON_ERROR       : Longitude out of valid range
+ *                                 (-180 to 360 degrees)
+ *      GEOCENT_A_ERROR         : Semi-major axis less than or equal to zero
+ *      GEOCENT_INV_F_ERROR     : Inverse flattening outside of valid range
+ *								                 (250 to 350)
+ *
+ *
+ * REUSE NOTES
+ *
+ *    GEOCENTRIC is intended for reuse by any application that performs
+ *    coordinate conversions between geodetic coordinates and geocentric
+ *    coordinates.
+ *    
+ *
+ * REFERENCES
+ *    
+ *    An Improved Algorithm for Geocentric to Geodetic Coordinate Conversion,
+ *    Ralph Toms, February 1996  UCRL-JC-123138.
+ *    
+ *    Further information on GEOCENTRIC can be found in the Reuse Manual.
+ *
+ *    GEOCENTRIC originated from : U.S. Army Topographic Engineering Center
+ *                                 Geospatial Information Division
+ *                                 7701 Telegraph Road
+ *                                 Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    GEOCENTRIC has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    GEOCENTRIC was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC version 2.8.1
+ *    2. Windows 95 with MS Visual C++ version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+  #define GEOCENT_NO_ERROR        0x0000
+  #define GEOCENT_LAT_ERROR       0x0001
+  #define GEOCENT_LON_ERROR       0x0002
+  #define GEOCENT_A_ERROR         0x0004
+  #define GEOCENT_INV_F_ERROR     0x0008
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTION PROTOTYPES
+ */
+
+/* ensure proper linkage to c++ programs */
+  #ifdef __cplusplus
+extern "C" {
+  #endif
+
+
+  long Set_Geocentric_Parameters (double a, 
+                                  double f);
+/*
+ * The function Set_Geocentric_Parameters receives the ellipsoid parameters
+ * as inputs and sets the corresponding state variables.
+ *
+ *    a  : Semi-major axis of ellipsoid, in meters.          (input)
+ *    f  : Flattening of ellipsoid.						               (input)
+ */
+
+
+  void Get_Geocentric_Parameters (double *a, 
+                                  double *f);
+/*
+ * The function Get_Geocentric_Parameters returns the ellipsoid parameters
+ * to be used in geocentric coordinate conversions.
+ *
+ *    a  : Semi-major axis of ellipsoid, in meters.          (output)
+ *    f  : Flattening of ellipsoid.						               (output)
+ */
+
+
+  long Convert_Geodetic_To_Geocentric (double Latitude,
+                                       double Longitude,
+                                       double Height,
+                                       double *X,
+                                       double *Y,
+                                       double *Z);
+/*
+ * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates
+ * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
+ * according to the current ellipsoid parameters.
+ *
+ *    Latitude  : Geodetic latitude in radians                     (input)
+ *    Longitude : Geodetic longitude in radians                    (input)
+ *    Height    : Geodetic height, in meters                       (input)
+ *    X         : Calculated Geocentric X coordinate, in meters.   (output)
+ *    Y         : Calculated Geocentric Y coordinate, in meters.   (output)
+ *    Z         : Calculated Geocentric Z coordinate, in meters.   (output)
+ *
+ */
+
+
+  void Convert_Geocentric_To_Geodetic (double X,
+                                       double Y, 
+                                       double Z,
+                                       double *Latitude,
+                                       double *Longitude,
+                                       double *Height);
+/*
+ * The function Convert_Geocentric_To_Geodetic converts geocentric
+ * coordinates (X, Y, Z) to geodetic coordinates (latitude, longitude, 
+ * and height), according to the current ellipsoid parameters.
+ *
+ *    X         : Geocentric X coordinate, in meters.         (input)
+ *    Y         : Geocentric Y coordinate, in meters.         (input)
+ *    Z         : Geocentric Z coordinate, in meters.         (input)
+ *    Latitude  : Calculated latitude value in radians.       (output)
+ *    Longitude : Calculated longitude value in radians.      (output)
+ *    Height    : Calculated height value, in meters.         (output)
+ */
+
+
+  #ifdef __cplusplus
+}
+  #endif
+
+#endif /* GEOCENT_H */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoref.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoref.cpp
new file mode 100644
index 0000000000..27a1809152
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoref.cpp
@@ -0,0 +1,375 @@
+#include "ossimGeoref.h"
+
+#include <stdio.h> // for geotrans stuff
+#include <math.h>
+
+// These are Geotrans defines and code.
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+#define GEOREF_NO_ERROR             0x0000
+#define GEOREF_LAT_ERROR            0x0001
+#define GEOREF_LON_ERROR            0x0002
+#define GEOREF_STR_ERROR            0x0004
+#define GEOREF_STR_LAT_ERROR        0x0008
+#define GEOREF_STR_LON_ERROR        0x0010
+#define GEOREF_STR_LAT_MIN_ERROR    0x0020
+#define GEOREF_STR_LON_MIN_ERROR    0x0040
+#define GEOREF_PRECISION_ERROR      0x0080
+
+
+ossimGeoref::ossimGeoref(const ossimString &georefString,
+                         long precision)
+{
+   double lat, lon;
+   
+   long result = Convert_GEOREF_To_Geodetic(const_cast<char*>(georefString.c_str()),
+                                            &lat,
+                                            &lon);
+   if(result == GEOREF_NO_ERROR)
+   {
+      thePt.latr(lat);
+      thePt.lonr(lon);
+   }
+}
+
+ossimGeoref::ossimGeoref(const ossimGpt &groundPt)
+{
+   thePt = groundPt;
+}
+
+ossimGeoref::ossimGeoref()
+{
+}
+
+ossimString ossimGeoref::toString(long precision)
+{
+   char resultString[100];
+   
+   long result = Convert_Geodetic_To_GEOREF(thePt.latr(),
+                                            thePt.lonr(),
+                                            precision,
+                                            resultString);
+   if(result == GEOREF_NO_ERROR)
+   {
+      return ossimString(resultString);
+   }
+
+   return ossimString("");
+}
+
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+#define TRUE                1
+#define FALSE               0
+#define LATITUDE_LOW      -90  /* Minimum latitude                      */
+#define LATITUDE_HIGH      90  /* Maximum latitude                      */
+#define LONGITUDE_LOW    -180  /* Minimum longitude                     */
+#define LONGITUDE_HIGH    360  /* Maximum longitude                     */
+#define MIN_PER_DEG        60  /* Number of minutes per degree          */
+#define GEOREF_MINIMUM      4  /* Minimum number of chars for GEOREF    */
+#define GEOREF_MAXIMUM     14  /* Maximum number of chars for GEOREF    */
+#define GEOREF_LETTERS      4  /* Number of letters in GEOREF string    */
+#define MAX_PRECISION       5  /* Maximum precision of minutes part     */
+#define LETTER_I            8  /* Index for letter I                    */
+#define LETTER_M           12  /* Index for letter M                    */
+#define LETTER_O           14  /* Index for letter O                    */
+#define LETTER_Q           16  /* Index for letter Q                    */
+#define LETTER_Z           25  /* Index for letter Z                    */
+#define LETTER_A_OFFSET    65  /* Letter A offset in character set      */
+#define ZERO_OFFSET        48  /* Number zero offset in character set   */
+#define PI    3.14159265358979323e0  /* PI                              */
+#define DEGREE_TO_RADIAN   (PI / 180.0)
+#define RADIAN_TO_DEGREE   (180.0 / PI)
+#define QUAD               15  /* Degrees per grid square               */
+#define ROUND_ERROR  0.0000005 /* Rounding factor                       */
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+long Extract_Degrees (char *georef,
+                      double *latitude,
+                      double *longitude)
+{ /* BEGIN Extract_Degrees */
+/*    
+ *  This function extracts the latitude and longitude degree parts of the 
+ *  GEOREF string.  The latitude and longitude degree parts are the first four
+ *  characters.
+ *
+ *    georef        : GEOREF string             (input)
+ *    latitude      : Latitude in degrees       (output)
+ *    longitude     : Longitude in degrees      (output)
+ */
+  long i;                             /* counter in for loops            */
+  long temp_char;                     /* temporary character             */
+  long letter_number[GEOREF_LETTERS]; /* number corresponding to letter  */
+  long error_code = GEOREF_NO_ERROR;
+
+  for (i=0;i<GEOREF_LETTERS;i++)
+  {
+    temp_char = toupper(georef[i]);
+    temp_char = temp_char - LETTER_A_OFFSET;
+    if ((!isalpha(georef[i]))
+        || (temp_char == LETTER_I)
+        || (temp_char == LETTER_O))
+    {
+      if ((i == 0) || (i == 2))
+        error_code |= GEOREF_STR_LON_ERROR;
+      else
+        error_code |= GEOREF_STR_LAT_ERROR;
+    }
+    letter_number[i] = temp_char;
+  }
+  for (i=0;i<4;i++)
+  {
+    if (letter_number[i] > LETTER_O)
+      letter_number[i] -= 2;
+    else if (letter_number[i] > LETTER_I)
+      letter_number[i] -= 1;
+  }
+  if ((letter_number[0] > 23) || (letter_number[2] > 14))
+    error_code |= GEOREF_STR_LON_ERROR;
+  if ((letter_number[1] > 11) || (letter_number[3] > 14))
+    error_code |= GEOREF_STR_LAT_ERROR;
+  *latitude = (double)(letter_number[1]) * QUAD + (double)(letter_number[3]);
+  *longitude = (double)(letter_number[0]) * QUAD + (double)(letter_number[2]);
+  return (error_code);
+} /* END Extract_Degrees */
+
+
+long Extract_Minutes (char *georef,
+                      long start,
+                      long length,
+                      long ERROR_TYPE,
+                      double *minutes)
+{ /* BEGIN Extract_Minutes */
+/*    
+ *  This function extracts the minutes from the GEOREF string.  The minutes
+ *  part begins at position start and has length length.  The ERROR_TYPE is
+ *  to allow this function to work with both latitude and longitude minutes.
+ *
+ *    georef : GEOREF string                                        (input)
+ *    start  : Start position in the GEOREF string                  (input)
+ *    length : length of minutes in the GEOREF string               (input)
+ *    ERROR_TYPE  : has a value of either GEOREF_STR_LAT_MIN_ERROR  (input)
+ *                    or GEOREF_STR_LON_MIN_ERROR
+ *    minutes: minute part                                          (output)
+ */
+  long i;                    /* counter in for loop  */
+  long error_code = GEOREF_NO_ERROR;
+  char temp_str[(GEOREF_MAXIMUM-GEOREF_LETTERS)/2 + 1];
+
+  for (i=0;i<length;i++)
+  {
+    if (isdigit(georef[start+i]))
+      temp_str[i] = georef[start+i];
+    else
+      error_code |= ERROR_TYPE;
+  }
+  temp_str[length] = 0;
+  *minutes = (double)atof(temp_str);  /* need atof, atoi can't handle 59999 */
+  while (length > 2)
+  {
+    *minutes = *minutes / 10;
+    length = length - 1;
+  }
+  if (*minutes > (double)MIN_PER_DEG)
+    error_code |= ERROR_TYPE;
+  return (error_code);
+} /* END OF Extract_Minutes */
+
+
+long Round_GEOREF (double value)
+/* Round value to nearest integer, using standard engineering rule */
+{ /* Round_GEOREF */
+  double ivalue;
+  long ival;
+  double fraction = modf (value, &ivalue);
+  ival = (long)(ivalue);
+  if ((fraction > 0.5) || ((fraction == 0.5) && (ival%2 == 1)))
+    ival++;
+  return (ival);
+} /* Round_GEOREF */
+
+
+void Convert_Minutes_To_String(double minutes,
+                               long precision,
+                               char *str)
+{ /* BEGIN Convert_Minutes_To_String */
+/*    
+ *  This function converts minutes to a string of length precision.
+ *
+ *    minutes       : Minutes to be converted                  (input)
+ *    precision     : Length of resulting string               (input)
+ *    str           : String to hold converted minutes         (output)
+ */
+  double divisor;
+  long min;
+  divisor = pow ((double)10.0, (int)(5 - precision));
+  if (minutes == 60.0)
+    minutes = 59.999;
+  minutes = minutes * 1000;
+  min = Round_GEOREF (minutes/divisor);
+  sprintf (str, "%*.*ld", (int)precision, (int)precision, min);
+  if (precision == 1)
+    strcat (str, "0");
+} /* END Convert_Minutes_To_String */
+
+
+long ossimGeoref::Convert_GEOREF_To_Geodetic (char *georef,
+                                              double *latitude, 
+                                              double *longitude)
+{ /* BEGIN Convert_GEOREF_To_Geodetic */
+/*
+ *  This function converts a GEOREF coordinate string to Geodetic (latitude
+ *  and longitude in radians) coordinates.
+ *
+ *    georef    : GEOREF coordinate string.     (input)
+ *    latitude  : Latitude in radians.          (output)
+ *    longitude : Longitude in radians.         (output)
+ *
+ *    CALLS THE FOLLOWING FUNCTIONS:
+ *
+ *    Extract_Degrees
+ *    Extract_Minutes
+ */
+  long start;                /* Position in the GEOREF string                */
+  long minutes_length;       /* length of minutes in the GEOREF string       */
+  long georef_length;        /* length of GEOREF string                      */
+  double origin_long;       /* Origin longitude                             */
+  double origin_lat;        /* Origin latitude                              */
+  double long_minutes;      /* Longitude minute part of GEOREF              */
+  double lat_minutes;       /* Latitude minute part of GEOREF               */
+  long error_code = GEOREF_NO_ERROR;
+
+  origin_long = (double)LONGITUDE_LOW;
+  origin_lat = (double)LATITUDE_LOW;
+  georef_length = strlen(georef);
+  if ((georef_length < GEOREF_MINIMUM) || (georef_length > GEOREF_MAXIMUM) 
+      || ((georef_length % 2) != 0))
+  {
+    error_code |= GEOREF_STR_ERROR;
+  }
+  if (!error_code)
+  {
+    error_code |= Extract_Degrees(georef,latitude,longitude);
+    start = GEOREF_LETTERS;
+    minutes_length = (georef_length - start) / 2;
+    if (!error_code)
+    {
+      error_code |= Extract_Minutes(georef, start, minutes_length, 
+                                    GEOREF_STR_LON_MIN_ERROR, &long_minutes);
+      if (!error_code)
+      {
+        error_code |= Extract_Minutes(georef, (start+minutes_length),
+                                      minutes_length, GEOREF_STR_LAT_MIN_ERROR, &lat_minutes);
+        *latitude = *latitude + origin_lat + lat_minutes / (double)MIN_PER_DEG;
+        *longitude = *longitude + origin_long + long_minutes / (double)MIN_PER_DEG;
+        *latitude = *latitude * DEGREE_TO_RADIAN;
+        *longitude = *longitude * DEGREE_TO_RADIAN;
+      }
+    }
+  }
+  return (error_code);
+} /* END OF Convert_GEOREF_To_Geodetic */
+
+
+long ossimGeoref::Convert_Geodetic_To_GEOREF (double latitude,
+                                              double longitude,
+                                              long precision,
+                                              char *georef)
+{ /* BEGIN Convert_Geodetic_To_GEOREF */
+/*   
+ *  This function converts Geodetic (latitude and longitude in radians)
+ *  coordinates to a GEOREF coordinate string.  Precision specifies the
+ *  number of digits in the GEOREF string for latitude and longitude:
+ *                                  0 for nearest degree
+ *                                  1 for nearest ten minutes
+ *                                  2 for nearest minute
+ *                                  3 for nearest tenth of a minute
+ *                                  4 for nearest hundredth of a minute
+ *                                  5 for nearest thousandth of a minute
+ *
+ *    latitude  : Latitude in radians.                   (input)
+ *    longitude : Longitude in radians.                  (input)
+ *    precision : Precision specified by the user.       (input)
+ *    georef    : GEOREF coordinate string.              (output)
+ *
+ *    CALLS THE FOLLOWING FUNCTIONS:
+ *
+ *    Convert_Minutes_To_String
+ */
+
+  double long_min;                        /* GEOREF longitude minute part   */
+  double lat_min;                         /* GEOREF latitude minute part    */
+  double origin_long;                     /* Origin longitude (-180 degrees)*/
+  double origin_lat;                      /* Origin latitude (-90 degrees)  */
+  long letter_number[GEOREF_LETTERS + 1]; /* GEOREF letters                 */
+  char long_min_str[MAX_PRECISION + 1];   /* Longitude minute string        */
+  char lat_min_str[MAX_PRECISION + 1];    /* Latitude minute string         */
+  long i;                                 /* counter in for loop            */
+  long error_code = GEOREF_NO_ERROR;
+
+  latitude = latitude * RADIAN_TO_DEGREE;
+  longitude = longitude * RADIAN_TO_DEGREE;
+  if ((latitude < (double)LATITUDE_LOW) 
+      || (latitude > (double)LATITUDE_HIGH))
+    error_code |= GEOREF_LAT_ERROR;
+  if ((longitude < (double)LONGITUDE_LOW) 
+      || (longitude > (double)LONGITUDE_HIGH))
+    error_code |= GEOREF_LON_ERROR;
+  if ((precision < 0) || (precision > MAX_PRECISION))
+    error_code |= GEOREF_PRECISION_ERROR;
+  if (!error_code)
+  {
+    if (longitude > 180)
+      longitude -= 360;
+    origin_long = (double)LONGITUDE_LOW;
+    origin_lat = (double)LATITUDE_LOW;
+    letter_number[0] = (long)((longitude-origin_long) / QUAD + ROUND_ERROR);
+    longitude = longitude - ((double)letter_number[0] * QUAD + origin_long);
+    letter_number[2] = (long)(longitude + ROUND_ERROR);
+    long_min = (longitude - (double)letter_number[2]) * (double)MIN_PER_DEG;
+    letter_number[1] = (long)((latitude - origin_lat) / QUAD + ROUND_ERROR);
+    latitude = latitude - ((double)letter_number[1] * QUAD + origin_lat);
+    letter_number[3] = (long)(latitude + ROUND_ERROR);
+    lat_min = (latitude - (double)letter_number[3]) * (double)MIN_PER_DEG;
+    for (i = 0;i < 4; i++)
+    {
+      if (letter_number[i] >= LETTER_I)
+        letter_number[i] += 1;
+      if (letter_number[i] >= LETTER_O)
+        letter_number[i] += 1;
+    }
+
+    if (letter_number[0] == 26)
+    { /* longitude of 180 degrees */
+      letter_number[0] = LETTER_Z;
+      letter_number[2] = LETTER_Q;
+      long_min = 59.999;
+    }
+    if (letter_number[1] == 13)
+    { /* latitude of 90 degrees */
+      letter_number[1] = LETTER_M;
+      letter_number[3] = LETTER_Q;
+      lat_min = 59.999;
+    }
+
+    for (i=0;i<4;i++)
+      georef[i] = (char)(letter_number[i] + LETTER_A_OFFSET);
+    georef[4] = 0;
+    Convert_Minutes_To_String(long_min,precision,long_min_str);
+    Convert_Minutes_To_String(lat_min,precision,lat_min_str);
+    strcat(georef,long_min_str);
+    strcat(georef,lat_min_str);
+  }
+  return (error_code);
+} /* END OF Convert_Geodetic_To_GEOREF */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoref.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoref.h
new file mode 100644
index 0000000000..c256d285f6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGeoref.h
@@ -0,0 +1,70 @@
+#ifndef ossimGeoref_HEADER
+#define ossimGeoref_HEADER
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimGpt.h"
+
+class OSSIMDLLEXPORT ossimGeoref
+{
+public:
+   ossimGeoref(const ossimString &georefString,
+               long precision);
+   ossimGeoref(const ossimGpt &groundPt);
+   ossimGeoref();
+
+  /*!   
+   *  This function converts Geodetic (latitude and longitude in radians)
+   *  coordinates to a GEOREF coordinate string.  Precision specifies the
+   *  number of digits in the GEOREF string for latitude and longitude:
+   *                                  0 for nearest degree
+   *                                  1 for nearest 10 minutes
+   *                                  2 for nearest minute
+   *                                  3 for nearest tenth of a minute
+   *                                  4 for nearest hundredth of a minute
+   *                                  5 for nearest thousandth of a minute
+   *
+   *    Precision : level of precision specified by the user  (input)
+   *    ossimGeoref    : GEOREF coordinate string                  (return)
+   */    
+   ossimString toString(long precision);
+   
+private:
+   ossimGpt thePt;
+
+   // This code belongs to Geotrans
+   
+  /*!   
+   *  This function converts Geodetic (latitude and longitude in radians)
+   *  coordinates to a GEOREF coordinate string.  Precision specifies the
+   *  number of digits in the GEOREF string for latitude and longitude:
+   *                                  0 for nearest degree
+   *                                  1 for nearest 10 minutes
+   *                                  2 for nearest minute
+   *                                  3 for nearest tenth of a minute
+   *                                  4 for nearest hundredth of a minute
+   *                                  5 for nearest thousandth of a minute
+   *
+   *    Latitude  : Latitude in radians                       (input)
+   *    Longitude : Longitude in radians                      (input)
+   *    Precision : level of precision specified by the user  (input)
+   *    ossimGeoref    : GEOREF coordinate string                  (output)
+   */
+  long Convert_Geodetic_To_GEOREF (double Latitude,
+                                   double Longitude,
+                                   long Precision,
+                                   char *georef);
+
+
+  /*!
+   *  This function converts a GEOREF coordinate string to Geodetic (latitude
+   *  and longitude in radians) coordinates.
+   *
+   *    ossimGeoref    : GEOREF coordinate string     (input)
+   *    Latitude  : Latitude in radians          (output)
+   *    Longitude : Longitude in radians         (output)
+   */   
+  long Convert_GEOREF_To_Geodetic (char *georef,
+                                   double *Latitude, 
+                                   double *Longitude);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGpt.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimGpt.cpp
new file mode 100644
index 0000000000..26a61b62c6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGpt.cpp
@@ -0,0 +1,341 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+// Description:
+//
+// LATITUDE AND LONGITUDE VALUES ARE IN DEGREES.
+//
+//*******************************************************************
+//  $Id: ossimGpt.cpp,v 1.33 2005/12/16 14:25:11 dburken Exp $
+
+#include <sstream>
+
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/data_types/ossimDms.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/data_types/geoid/ossimGeoidManager.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/ossimGeocent.h>
+#include <base/data_types/ossimString.h>
+
+std::ostream& ossimGpt::print(std::ostream& os, ossim_uint32 precision) const
+{
+   os << setiosflags(ios::fixed) << setprecision(precision);
+   os << "( ";
+
+   if(isLatNan())
+   {
+      os << "nan" << ", ";
+   }
+   else
+   {
+      os << latd() << ", ";
+   }
+   if(isLonNan())
+   {
+      os << "nan" << ", ";
+   }
+   else
+   {
+      os << lond() << ", ";
+   }
+   if(isHgtNan())
+   {
+      os << "nan" << ", ";
+   }
+   else
+   {
+      os << height() << ", ";
+   }
+   
+   os << (theDatum?theDatum->code().c_str():"") << " )";
+
+   return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const ossimGpt& pt)
+{
+   return pt.print(os);
+}
+
+ossimString ossimGpt::toString(ossim_uint32 precision) const
+{
+   std::ostringstream os;
+   print(os, precision);
+   return ossimString(os.str());
+}
+
+std::istream& operator>>(std::istream& is, ossimGpt &pt)
+{
+   //---
+   // Expected input format:
+   // ( 30.00000000000000, -90.00000000000000, 0.00000000000000, WGE )
+   //   -----latitude----  -----longitude----  ------height----  datum
+   //---
+
+   // Start with a nan point.
+   pt.makeNan();
+
+   // Check the stream.
+   if (!is) return is;
+
+   const int SZ = 22;
+   ossimString tempString;
+   char tempChars[SZ];
+   char c;
+
+   // Gobble the "(".
+   is >> tempString;
+   if (!is) return is;
+   
+   // Get the latitude.
+   is.get(tempChars, SZ, ',');
+   if (!is) return is;
+   tempChars[SZ-1] = '\0';
+   tempString = tempChars;
+   tempString.trim();
+   if (tempString == "nan")
+   {
+      pt.latd(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      pt.latd(tempString.toDouble());
+   }
+
+   // Eat the ",".
+   is.get(c);
+   
+   // Get the longitude.
+   is.get(tempChars, SZ, ',');
+   if (!is) return is;
+   tempChars[SZ-1] = '\0';
+   tempString = tempChars;
+   tempString.trim();
+   if (tempString == "nan")
+   {
+      pt.lond(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      pt.lond(tempString.toDouble());
+   }
+
+   // Eat the ",".
+   is.get(c);
+   
+   // Get the height.
+   is.get(tempChars, SZ, ',');
+   if (!is) return is;
+   tempChars[SZ-1] = '\0';
+   tempString = tempChars;
+   tempString.trim();
+   if (tempString == "nan")
+   {
+      pt.height(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      pt.height(tempString.toDouble());
+   }
+
+   // Eat the ",".
+   is.get(c);
+
+   // Get the datum.
+   is >> tempString;
+   if (!is) return is;
+   const ossimDatum* datum = ossimDatumFactory::instance()->create(tempString);
+   if (datum)
+   {
+      pt.datum(datum);
+   }
+   else
+   {
+      pt.datum(ossimDatumFactory::instance()->wgs84());
+   }
+
+   // Gobble the trailing ")".
+   is >> tempString;
+
+   // Finished
+   return is;
+}
+
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: ossimGpt(ossimGpt) 
+//*****************************************************************************
+ossimGpt::ossimGpt(const ossimGpt& src)
+   : lat(src.lat),
+     lon(src.lon),
+     hgt(src.hgt)
+{
+   theDatum = src.datum();
+   if(!theDatum)
+   {
+      theDatum = ossimDatumFactory::instance()->wgs84();
+   }
+//   limitLonTo180();
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR:  ossimGpt(ossimEcefPoint, datum)
+//*****************************************************************************
+ossimGpt::ossimGpt(const ossimEcefPoint& ecef_point,
+                   const ossimDatum*     datum)
+   :
+      theDatum (datum)
+{
+   if(!theDatum)
+   {
+      theDatum = ossimDatumFactory::instance()->wgs84();
+   }
+   if(ecef_point.isNan())
+   {
+      makeNan();
+   }
+   else
+   {
+      theDatum->ellipsoid()->XYZToLatLonHeight(ecef_point.x(),
+                                               ecef_point.y(),
+                                               ecef_point.z(),
+                                               lat,
+                                               lon,
+                                               hgt);
+      
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimGpt::operator =
+//*****************************************************************************
+const ossimGpt& ossimGpt::operator = (const ossimGpt &aPt)
+{
+   lat = aPt.lat;
+   lon = aPt.lon;
+   hgt = aPt.hgt;
+   
+   if(aPt.datum())
+   {
+      theDatum = aPt.datum();
+   }
+   if(!theDatum)
+   {
+      theDatum = ossimDatumFactory::instance()->wgs84();
+   }
+   
+   return *this;
+}
+
+//*****************************************************************************
+//  METHOD: ossimGpt::changeDatum
+//*****************************************************************************
+void ossimGpt::changeDatum(const ossimDatum *datum)
+{
+   if(datum == theDatum) return;
+   if(!isLatNan() && !isLonNan()) // only shift if all values lat and lon is good
+   {
+      if(datum)
+      {
+	double h = hgt;
+        *this = datum->shift(*this);
+        if(h == OSSIM_DBL_NAN)
+        {
+           hgt = h;
+        }
+        theDatum = datum;
+      }
+   }
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimGpt::toDmsString()
+//*****************************************************************************
+ossimString ossimGpt::toDmsString()const
+{
+   ossimString result;
+
+   result += "lat: ";
+   if(isLatNan())
+   {
+      result += "nan";
+   }
+   else
+   {
+      result += ossimDms(latd()).toString("dd@mm'ss.ssss\"C");
+   }
+   result += " lon: ";
+   if(isLonNan())
+   {
+      result += "nan";
+   }
+   else
+   {
+      result += ossimDms(lond(),false).toString("dd@mm'ss.ssss\"C");
+   }
+   
+   return result;
+}
+
+//*****************************************************************************
+//  METHOD: ossimGpt::distanceTo(ossimGpt)
+//
+//  Computes straight-line distance to arg point, in meters.
+//
+//*****************************************************************************
+double ossimGpt::distanceTo(const ossimGpt& arg_pt) const
+{
+   ossimEcefPoint p1 (*this);
+   ossimEcefPoint p2 (arg_pt);
+
+   return (p1 - p2).magnitude();
+}
+
+//*****************************************************************************
+//  METHOD: ossimGpt::heightMSL() const 
+//
+//  Returns the height data member adjusted for geoid.
+//
+//*****************************************************************************
+double ossimGpt::heightMSL() const
+{
+   double offset = ossimGeoidManager::instance()->offsetFromEllipsoid(*this);
+   return (hgt - offset);
+}
+
+//*****************************************************************************
+//  METHOD: ossimGpt::heightMSL(double)
+//
+//  Sets the height data member adjusted for geoid.
+//
+//*****************************************************************************
+void ossimGpt::heightMSL(double heightMSL)
+{
+   double offset = ossimGeoidManager::instance()->offsetFromEllipsoid(*this);
+   hgt = heightMSL + offset;
+}
+
+//*****************************************************************************
+//  METHOD: ossimGpt::metersPerDegree(double)
+//
+//  Computes geodetic arc lengths at this ground point.
+//
+//*****************************************************************************
+ossimDpt ossimGpt::metersPerDegree() const
+{
+   ossimDpt result;
+
+   double radius = theDatum->ellipsoid()->geodeticRadius(lat);
+   result.y =  RAD_PER_DEG * radius;
+   result.x =  result.y * cosd(lat);
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGpt.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimGpt.h
new file mode 100644
index 0000000000..082e7c5a3d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGpt.h
@@ -0,0 +1,259 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt.
+//
+// Author: Garrett Potts
+//
+// Description:
+//
+// Contains class declaration for gpt.
+//
+// CONSTRUCTOR TAKES LAT/LON IN DEGREES!!!
+//
+// Height is relative to the ellipsoid.
+//
+//*******************************************************************
+//  $Id: ossimGpt.h,v 1.23 2005/12/16 14:25:11 dburken Exp $
+
+#ifndef gpt_HEADER
+#define gpt_HEADER
+
+#include <iomanip>
+#include <iostream>
+
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimString.h>
+#include <base/factory/ossimDatumFactory.h>
+
+class OSSIMDLLEXPORT ossimDatum;
+class OSSIMDLLEXPORT ossimEcefPoint;
+class OSSIMDLLEXPORT ossimString;
+
+class OSSIMDLLEXPORT ossimGpt
+{
+public:
+   /**
+    * Constructor.  The values are assumed to be in DEGREES.
+    */
+   ossimGpt(const double alat=0,  // degrees
+            const double alon=0,  // degrees
+            const double ahgt=0,
+            const ossimDatum* aDatum=ossimDatumFactory::instance()->wgs84())
+      : lat(alat),
+        lon(alon),
+        hgt(ahgt),  // relative to the ellipsoid
+        theDatum(aDatum) {}//limitLonTo180();}
+
+   /**
+    * Copy Constructor:
+    */
+   ossimGpt(const ossimGpt& src);
+   
+   /**
+    * Constructor.  Conversion from geocentric to ground.
+    */
+   ossimGpt(const ossimEcefPoint &aPt,
+            const ossimDatum* aDatum=ossimDatumFactory::instance()->wgs84());
+
+   /**
+    * latr().  Returns the latitude in radian measure.  Since
+    * our internal format is radians we do not have to do any
+    * conversions.
+    */
+   double latr()const{return lat*RAD_PER_DEG;}
+
+   /**
+    * Returns the latitude in radian measure.  Since
+    * our internal format is radians we do not have to do any
+    * conversions.
+    */
+   void latr(double radianValue){lat = radianValue*DEG_PER_RAD;}
+
+   /**
+    * Returns the longitude in radian measure.  Since
+    * our internal format is radians we do not have to do any
+    * conversions.
+    */
+   double lonr()const{return lon*RAD_PER_DEG;}
+
+   /**
+    * Assumes the value being passed in is in radians.
+    */
+   void lonr(double radianValue)
+      {lon = radianValue*DEG_PER_RAD; }//limitLonTo180();}
+
+   /**
+    * Will convert the radian measure to degrees.
+    */
+   double latd()const{return lat;}
+
+   /**
+    * Assumes the passed in value is in degrees.
+    */
+   void latd(double degreeValue){lat = degreeValue;}
+
+   /**
+    * Will convert the radian measure to degrees.
+    */
+   double lond()const{return lon;}
+
+   /**
+    *  Assumes the passed in value is in degrees.
+    */
+   void lond(double degreeValue){lon = degreeValue; }//limitLonTo180();}
+
+   /**
+    * @return Returns the height in meters above the ellipsoid.
+    */
+   double height()const{return hgt;}
+
+   /**
+    * @return Returns the height in meters above mean sea level (msl).
+    * 
+    * @note This is the height above the ellipsoid minus any geoid offset.
+    */
+   double heightMSL() const;
+
+   /**
+    * Sets the "hgt" data member to height.
+    *
+    * @param height Height above the ellipsoid in meters.
+    */
+   void height(double height){hgt = height;}
+
+   /**
+    * Sets the "hgt" data member to heightMsl adding any geiod offset.
+    *
+    * @param heightMSL Height in meters above msl.
+    */
+   void heightMSL(double heightMSL);
+
+   void makeNan(){lat = OSSIM_DBL_NAN; lon=OSSIM_DBL_NAN; hgt=OSSIM_DBL_NAN;}
+   bool isNan()const{return isLatNan()&&isLonNan()&&isHgtNan();}
+   bool hasNans()const
+      {
+         return (ossimIsNan(lat) || ossimIsNan(lon) || ossimIsNan(hgt));
+      }
+   bool isLatNan()const{return ossimIsNan(lat);}
+   bool isLonNan()const{return ossimIsNan(lon);}
+   bool isHgtNan()const{return ossimIsNan(hgt);}
+
+   std::ostream& print(std::ostream& os, ossim_uint32 precision=15) const;
+
+   friend OSSIMDLLEXPORT std::ostream& operator<<(std::ostream& os,
+                                                  const ossimGpt& pt);
+   
+   /**
+    * @param precision Output floating point precision.
+    * 
+    * @return ossimString representing point.
+    *
+    * Output format:
+    * ( 30.00000000000000, -90.00000000000000, 0.00000000000000, WGE )
+    *   -----latitude----  -----longitude----  ------height----  datum
+    */
+   ossimString toString(ossim_uint32 precision=15) const;
+   
+   /**
+    * Method to input the formatted string of the "operator<<".
+    * 
+    * This method starts by doing a "makeNan" on aPt.  So if anything goes
+    * wrong with the stream or parsing aPt could be all or partially nan.
+    *
+    * @param is Input stream istream to formatted text.
+    * @param aPt osimGpt to be initialized from stream.
+    * @return istream pass in.
+    *
+    * Expected format:
+    * ( 30.00000000000000, -90.00000000000000, 0.00000000000000, WGE )
+    *  -----latitude----  -----longitude----  ------height----  datum
+    */
+   friend OSSIMDLLEXPORT std::istream& operator>>(std::istream& is,
+                                                  ossimGpt& pt);
+
+   /**
+    * datum().  returns the datum associated with this ground.
+    *
+    */
+   const ossimDatum* datum()const{return theDatum;}
+
+   /**
+    * Note: this will not do a shift.  This just allows you to set the datum.
+    *       If you want an automatic shift to occur then you must call the
+    *       changeDatum method
+    */
+   void datum(const ossimDatum* aDatum){theDatum = aDatum?aDatum:theDatum;}
+
+   /**
+    * This will actually perform a shift.
+    */
+   void changeDatum(const ossimDatum *datum);
+
+   const ossimGpt& operator = (const ossimGpt &aPt);
+   bool operator ==(const ossimGpt& gpt)const
+      {
+         return ( (lat == gpt.lat)&&
+                  (lon == gpt.lon)&&
+                  (hgt == gpt.hgt)&&
+                  (theDatum == gpt.theDatum));
+      }
+
+   /**
+    * METHOD: limitLonTo180()
+    * Converts the lon data member to a value between -180 and +180:
+    */
+   void  limitLonTo180()
+      { if (lon < -180.0) lon += 360.0; else if (lon > 180.0) lon -= 360.0; }
+
+   void clampLon(double low, double high)
+      {
+         if(lon < low) lon = low;
+         if(lon > high) lon = high;
+      }
+
+   void clampLat(double low, double high)
+      {
+         if(lat < low) lat = low;
+         if(lat > high) lat = high;
+      }
+
+   void clampHgt(double low, double high)
+      {
+         if(hgt < low) hgt = low;
+         if(hgt > high) hgt = high;
+      }
+      
+   /**
+    * METHOD: distanceTo(ossimGpt)
+    * Computes straight-line distance in meters between this and arg gpt:
+    */
+   double distanceTo(const ossimGpt& arg_gpt) const;
+
+   ossimDpt metersPerDegree() const;
+   
+   ossimString toDmsString()const;
+
+   ossim_float64 lat; //> latitude in degrees measure
+   ossim_float64 lon; //> longitude in degrees measure
+
+   /**
+    * Height in meters above the ellipsiod.
+    *
+    * @note This is NOT the same as "height msl".  "Height msl" is above
+    * the geoid or better know as mean sea level.
+    */ 
+   ossim_float64 hgt;
+
+private:
+   
+   /**
+    * Know reference location plus an implied ellipsoid.
+    */
+   const ossimDatum* theDatum;
+ 
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGrect.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimGrect.cpp
new file mode 100644
index 0000000000..a63264ba3c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGrect.cpp
@@ -0,0 +1,234 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGrect.cpp,v 1.5 2005/09/23 20:11:42 dburken Exp $
+
+#include <base/data_types/ossimGrect.h>
+using namespace std;
+
+ostream& operator<<(ostream& os, const ossimGrect& rect)
+{
+   return os << rect.theUlCorner << ", " << rect.theLrCorner << endl;
+}
+
+ossimGrect::ossimGrect(vector<ossimGpt>& points)
+{
+   unsigned long index;
+   
+   // initialize everyone to the first point
+   if(points.size() > 0)
+   {
+      theUlCorner = points[0];
+      theLrCorner = theUlCorner;
+   }
+   
+   // find the bounds
+   for(index = 1; index < points.size(); index++)
+   {
+      // find left most
+      if(theUlCorner.lond() > points[index].lond())
+      {
+         theUlCorner.lond(points[index].lond());
+      } // find right most
+      else if(theLrCorner.lond() < points[index].lond())
+      {
+         theLrCorner.lond(points[index].lond());
+      }
+      //find top most
+      if(points[index].latd() > theUlCorner.latd())
+      {
+         theUlCorner.latd(points[index].latd());
+      }// find bottom most
+      else if(points[index].latd() < theLrCorner.latd())
+      {
+         theLrCorner.latd(points[index].latd());
+      }
+   }
+   
+   theUrCorner = ossimGpt(theUlCorner.latd(),
+                          theLrCorner.lond(),
+                          0,
+                          theUlCorner.datum());
+   theLlCorner = ossimGpt(theLrCorner.latd(),
+                          theUlCorner.lond(),
+                          0,
+                          theLrCorner.datum());
+}
+
+ossimGrect::ossimGrect(const ossimGpt& p1,
+                       const ossimGpt& p2,
+                       const ossimGpt& p3,
+                       const ossimGpt& p4)
+{
+   unsigned long index;
+   std::vector<ossimGpt> points(4);
+   points[0] = p1;
+   points[1] = p2;
+   points[2] = p3;
+   points[3] = p4;
+   // initialize everyone to the first point
+   if(points.size() > 0)
+   {
+      theUlCorner = points[0];
+      theLrCorner = theUlCorner;
+   }
+   
+   // find the bounds
+   for(index = 1; index < points.size(); index++)
+   {
+      // find left most
+      if(theUlCorner.lond() > points[index].lond())
+      {
+         theUlCorner.lond(points[index].lond());
+      } // find right most
+      else if(theLrCorner.lond() < points[index].lond())
+      {
+         theLrCorner.lond(points[index].lond());
+      }
+      //find top most
+      if(points[index].latd() > theUlCorner.latd())
+      {
+         theUlCorner.latd(points[index].latd());
+      }// find bottom most
+      else if(points[index].latd() < theLrCorner.latd())
+      {
+         theLrCorner.latd(points[index].latd());
+      }
+   }
+   theUrCorner = ossimGpt(theUlCorner.latd(),
+                          theLrCorner.lond(),
+                          0,
+                          theUlCorner.datum());
+   theLlCorner = ossimGpt(theLrCorner.latd(),
+                          theUlCorner.lond(),
+                          0,
+                          theLrCorner.datum());
+}
+
+ossimGrect ossimGrect::stretchToEvenBoundary(double latSpacingInDegrees,
+                                             double lonSpacingInDegrees)const
+{
+   double ulLat = ((long)ceil(theUlCorner.latd()/latSpacingInDegrees))*
+                  latSpacingInDegrees;
+   double ulLon = ((long)floor(theUlCorner.lond()/lonSpacingInDegrees))*
+                  lonSpacingInDegrees;
+   double lrLat = ((long)floor(theLrCorner.latd()/latSpacingInDegrees))*
+                  latSpacingInDegrees;
+   double lrLon = ((long)ceil(theLrCorner.lond()/lonSpacingInDegrees))*
+                  lonSpacingInDegrees;
+   
+   return ossimGrect(ulLat, ulLon, lrLat, lrLon);
+}
+
+void ossimGrect::computeEvenTiles(std::vector<ossimGrect>& result,
+                                  double latSpacingInDegrees,
+                                  double lonSpacingInDegrees,
+                                  bool clipToGeographicBounds)const
+{
+   ossimGrect clipRect = ossimGrect(90, -180, -190, 180);
+   result.clear();
+   ossimGrect temp = stretchToEvenBoundary(latSpacingInDegrees,
+                                           lonSpacingInDegrees);
+
+   ossimGpt point = temp.ul();
+   
+   while(temp.pointWithin(point))
+   {
+      while(temp.pointWithin(point))
+      {
+         ossimGrect rect(point.latd(),
+                         point.lond(),
+                         point.latd()-latSpacingInDegrees,
+                         point.lond()+lonSpacingInDegrees);
+
+         rect.theUlCorner.datum( theUlCorner.datum());
+         rect.theLlCorner.datum( theUlCorner.datum());
+         rect.theLrCorner.datum( theUlCorner.datum());
+         rect.theUrCorner.datum( theUlCorner.datum());
+         if(clipToGeographicBounds)
+         {
+            rect = rect.clipToRect(clipRect);
+         }
+         result.push_back(rect);
+
+         point.lond(point.lond()+lonSpacingInDegrees);
+      }
+      point.lond(temp.ul().lond());
+      point.latd(point.latd()-latSpacingInDegrees);
+   }
+}
+
+//*******************************************************************
+// Public Method: ossimGrect::completely_within
+//*******************************************************************
+bool ossimGrect::completely_within(const ossimGrect& rect) const
+{
+   if(rect.isLonLatNan() || isLonLatNan())
+   {
+      return false;
+   }
+   
+   /*  --------------
+       |     1      |
+       | ---------- |
+       | |        | |
+       | |        | |
+       | |   2    | |
+       | |        | |
+       | |        | |
+       | ---------- |
+       |            |
+       --------------  */
+
+   bool rtn = true;
+   
+   if (theUlCorner.lon < rect.ul().lon)
+   {
+      rtn = false;
+   }
+   else if (theLrCorner.lon > rect.lr().lon)
+   {
+      rtn = false;
+   }
+   else if (theUlCorner.lat < rect.ul().lat)
+   {
+      rtn = false;
+   }
+   else if (theLrCorner.lat > rect.lr().lat)
+   {
+      rtn = false;
+   }
+
+   return rtn;
+}
+
+//*******************************************************************
+// Public Method: ossimGrect::intersects
+//*******************************************************************
+bool ossimGrect::intersects(const ossimGrect& rect) const
+{
+		
+   if(rect.isLonLatNan() || isLonLatNan())
+   {
+      return false;
+   }
+   
+   ossim_float64  ulx = ossimMax(rect.ul().lon, ul().lon);
+   ossim_float64  lrx = ossimMin(rect.lr().lon, lr().lon);
+   ossim_float64  uly, lry;
+   bool rtn;
+   
+   uly  = ossimMin(rect.ul().lat, ul().lat);
+   lry  = ossimMax(rect.lr().lat, lr().lat);
+   rtn = ((ulx <= lrx) && (uly >= lry));
+   
+      return (rtn);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimGrect.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimGrect.h
new file mode 100644
index 0000000000..6d09ef2a28
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimGrect.h
@@ -0,0 +1,329 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGrect.h,v 1.15 2005/09/23 20:10:55 dburken Exp $
+#ifndef ossimGrect_HEADER
+#define ossimGrect_HEADER
+#include <vector>
+#include <iostream>
+
+#include <base/factory/ossimDatumFactory.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/common/ossimCommon.h> /* for ossimMin/Max */
+
+class OSSIMDLLEXPORT ossimGrect
+{
+public:
+   friend std::ostream& operator<<(std::ostream& os, const ossimGrect& rect);
+
+   /**
+    * Will default to 0,0,0,0.
+    */
+    ossimGrect()
+      :
+         theUlCorner(0.0, 0.0, 0.0),
+         theUrCorner(0.0, 0.0, 0.0),
+         theLrCorner(0.0, 0.0, 0.0),
+         theLlCorner(0.0, 0.0, 0.0)
+      {}
+
+   /**
+    * Copies the passed in rectangle to this
+    * object.
+    */
+   ossimGrect(const ossimGrect& rect)
+      :
+         theUlCorner(rect.ul()),
+         theUrCorner(rect.ur()),
+         theLrCorner(rect.lr()),
+         theLlCorner(rect.ll())
+      {}
+
+   /**
+    * WIll take two ground points and fill the
+    * bounding rect appropriately.
+    */
+   ossimGrect(const ossimGpt& ul,
+              const ossimGpt& lr)
+      : 
+         theUlCorner(ul),
+         theUrCorner(ul.latd(), lr.lond(),0,ul.datum()),
+         theLrCorner(lr),
+         theLlCorner(lr.latd(), ul.lond(), 0, ul.datum())
+      {
+      }
+
+   /**
+    * Takes the upper left and lower right ground
+    * points
+    */
+   ossimGrect(const double ulLat,
+              const double ulLon,
+              const double lrLat,
+              const double lrLon,
+              const ossimDatum* aDatum=ossimDatumFactory::instance()->wgs84())
+      : 
+         theUlCorner(ulLat, ulLon,0, aDatum),
+         theUrCorner(ulLat, lrLon, 0, aDatum),
+         theLrCorner(lrLat, lrLon, 0, aDatum),
+         theLlCorner(lrLat, ulLon, 0, aDatum)
+      {}
+   ossimGrect(const ossimGpt& point,
+              double latSpacingInDegrees,
+              double lonSpacingInDegrees)
+      :
+         theUlCorner(point),
+         theUrCorner(point),
+         theLrCorner(point),
+         theLlCorner(point)
+      {
+         std::vector<ossimGrect> v;
+         computeEvenTiles(v, latSpacingInDegrees, lonSpacingInDegrees);
+         if(v.size())
+            *this = v[0];
+      }
+   ossimGrect(std::vector<ossimGpt>& points);
+   ossimGrect(const ossimGpt& p1,
+              const ossimGpt& p2,
+              const ossimGpt& p3,
+              const ossimGpt& p4);
+              
+
+   const ossimGrect& operator=(const ossimGrect& rect)
+      {
+         theUlCorner = rect.ul();
+         theUrCorner = rect.ur();
+         theLrCorner = rect.lr();
+         theLlCorner = rect.ll();
+         return *this;
+      }
+
+   ossimGpt midPoint()const;
+   
+   /**
+    * Returns the height of a rectangle.
+    */
+   ossim_float64 height() const;
+
+   /**
+    * Returns the width of a rectangle.
+    */
+   ossim_float64 width()  const;
+   
+   const ossimGpt& ul()const;
+   const ossimGpt& ur()const;
+   const ossimGpt& ll()const;
+   const ossimGpt& lr()const;
+   
+   ossimGpt& ul();
+   ossimGpt& ur();
+   ossimGpt& ll();
+   ossimGpt& lr();
+	
+   void makeNan();
+   
+   bool isLonLatNan()const;
+	
+   bool hasNans()const;
+   
+   bool isNan()const;
+   
+   /*!
+    * Returns true if "this" rectangle is contained completely within the
+    * input rectangle "rect".
+    */
+   bool completely_within(const ossimGrect& rect) const;
+	
+   /*!
+    * Returns true if any portion of an input rectangle "rect" intersects
+    * "this" rectangle.  
+    */
+   bool intersects(const ossimGrect& rect) const;
+
+   ossimGrect clipToRect(const ossimGrect& rect)const;
+
+   ossimGrect combine(const ossimGrect& rect)const;
+
+   /**
+    * METHOD: pointWithin(ossimGpt)
+    *
+    * @param gpt Point to test for withinness.
+    * 
+    * @return true if argument is inside of horizontal rectangle
+    *
+    * @note Height is not considered and there is no datum shift applied if
+    * gpt is of a different datum than this datum.
+    */
+   bool pointWithin(const ossimGpt& gpt) const; //inline below
+
+   ossimGrect stretchToEvenBoundary(double latSpacingInDegrees,
+                                    double lonSpacingInDegrees)const;
+   
+   void computeEvenTiles(std::vector<ossimGrect>& result,
+                         double latSpacingInDegrees,
+                         double lonSpacingInDegrees,
+                         bool clipToGeographicBounds = true)const;
+private:
+   ossimGpt theUlCorner;
+   ossimGpt theUrCorner;
+   ossimGpt theLrCorner;
+   ossimGpt theLlCorner;
+  
+};
+
+//==================== BEGIN INLINE DEFINITIONS ===============================
+
+//*****************************************************************************
+//  INLINE METHOD: ossimGrect::midPoint()
+//*****************************************************************************
+inline ossimGpt ossimGrect::midPoint()const
+{
+   return ossimGpt((ul().latd() + ur().latd() + ll().latd() + lr().latd())*.25,
+                   (ul().lond() + ur().lond() + ll().lond() + lr().lond())*.25,
+                   (ul().height()+ur().height()+ll().height()+
+                    lr().height())*.25,
+                   ul().datum() );
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimGrect::clipToRect()
+//*****************************************************************************
+inline ossimGrect ossimGrect::clipToRect(const ossimGrect& rect)const
+{
+    double     ulx, uly, lrx, lry;
+
+    ulx = ossimMax(rect.ul().lond(),ul().lond());
+    uly = ossimMin(rect.ul().latd(),ul().latd());
+    lrx = ossimMin(rect.lr().lond(),lr().lond());
+    lry = ossimMax(rect.lr().latd(),lr().latd());
+
+    if( lrx < ulx || lry > uly )
+    {
+       return ossimGrect(ossimGpt(0,0,0),ossimGpt(0,0,0));
+    }
+    else
+    {
+       return ossimGrect(ossimGpt(uly, ulx, 0, rect.ul().datum()),
+                         ossimGpt(lry, lrx, 0, rect.ul().datum()));
+    }
+}
+
+//*******************************************************************
+// Inline Method: ossimDrect::combine(const ossimDrect& rect)
+//*******************************************************************
+inline ossimGrect ossimGrect::combine(const ossimGrect& rect)const
+{
+   ossimGpt ulCombine;
+   ossimGpt lrCombine;
+	
+	ulCombine.lon = ((ul().lon <= rect.ul().lon)?ul().lon:rect.ul().lon);
+   ulCombine.lat = ((ul().lat >= rect.ul().lat)?ul().lat:rect.ul().lat);
+   lrCombine.lon = ((lr().lon >= rect.lr().lon)?lr().lon:rect.lr().lon);
+   lrCombine.lat = ((lr().lat <= rect.lr().lat)?lr().lat:rect.lr().lat);
+	
+   return ossimGrect(ulCombine, lrCombine);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimGrect::pointWithin()
+//*****************************************************************************
+inline bool ossimGrect::pointWithin(const ossimGpt& gpt) const
+{
+   return ((gpt.lat <= theUlCorner.lat) && (gpt.lat >= theLrCorner.lat) &&
+           (gpt.lon >= theUlCorner.lon) && (gpt.lon <= theLrCorner.lon));
+}
+
+inline ossim_float64 ossimGrect::height() const
+{
+   return fabs(theLlCorner.latd() - theUlCorner.latd()) + 1.0;
+}
+
+inline ossim_float64 ossimGrect::width() const
+{
+   return fabs(theLrCorner.lond() - theLlCorner.lond()) + 1.0;
+}
+
+inline const ossimGpt& ossimGrect::ul() const
+{
+   return theUlCorner;
+}
+
+inline const ossimGpt& ossimGrect::ur() const
+{
+   return theUrCorner;
+}
+
+inline const ossimGpt& ossimGrect::ll() const
+{
+   return theLlCorner;
+}
+
+inline const ossimGpt& ossimGrect::lr() const
+{
+   return theLrCorner;
+}
+   
+inline ossimGpt& ossimGrect::ul()
+{
+   return theUlCorner;
+}
+
+inline ossimGpt& ossimGrect::ur()
+{
+   return theUrCorner;
+}
+
+inline ossimGpt& ossimGrect::ll()
+{
+   return theLlCorner;
+}
+
+inline ossimGpt& ossimGrect::lr()
+{
+   return theLrCorner;
+}
+	
+inline void ossimGrect::makeNan()
+{
+   theUlCorner.makeNan();
+   theLlCorner.makeNan();
+   theLrCorner.makeNan();
+   theUrCorner.makeNan();
+}
+
+inline bool ossimGrect::isLonLatNan() const
+{
+   return ( ossimIsNan(theUlCorner.lat) ||
+            ossimIsNan(theUlCorner.lon) ||
+            ossimIsNan(theUrCorner.lat) ||
+            ossimIsNan(theUrCorner.lon) ||
+            ossimIsNan(theLrCorner.lat) ||
+            ossimIsNan(theLrCorner.lon) ||
+            ossimIsNan(theLlCorner.lat) ||
+            ossimIsNan(theLlCorner.lon) );
+}
+
+inline bool ossimGrect::hasNans() const
+{
+   return ( theUlCorner.hasNans() ||
+            theLlCorner.hasNans() ||
+            theLrCorner.hasNans() ||
+            theUrCorner.hasNans() );
+}
+
+inline bool ossimGrect::isNan()const
+{
+   return ( theUlCorner.hasNans() &&
+            theLlCorner.hasNans() &&
+            theLrCorner.hasNans() &&
+            theUrCorner.hasNans() );
+}
+
+#endif /* End of "#ifndef ossimGrect_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimHexString.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimHexString.cpp
new file mode 100644
index 0000000000..5c1742622b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimHexString.cpp
@@ -0,0 +1,248 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// 
+//********************************************************************
+// $Id: ossimHexString.cpp,v 1.4 2003/07/08 12:35:40 gpotts Exp $
+#include "base/data_types/ossimHexString.h"
+
+ossim_int32 ossimHexString::toInt32()const
+{
+   return static_cast<ossim_int32>(toUint32());
+}
+
+ossim_int16 ossimHexString::toInt16()const
+{
+   return static_cast<ossim_int16>(toUint32());
+}
+
+ossim_int8 ossimHexString::toChar()const
+{
+   return static_cast<ossim_int8>(toUint32());
+}
+
+ossim_uint8 ossimHexString::toUchar()const
+{   
+   return static_cast<ossim_uint8>(toUint32());
+}
+
+ossim_uint16 ossimHexString::toUint16()const
+{
+   return static_cast<ossim_uint16>(toUint32());
+}
+
+ossim_uint32 ossimHexString::toUint32()const
+{
+   ossim_uint32 temp=0;
+
+   if(length())
+   {
+      ossim_uint32 i = 0;
+      
+      if(((*this)[0] == '0')&&
+         (((*this)[1] == 'x')||
+          ((*this)[1] == 'X')))
+      {
+         i = 2;
+      }
+         
+      for(; i <length(); ++i)
+      {
+         temp <<=4;
+         if( ((*this)[(int)i] >= '0')&&((*this)[(int)i] <= '9'))
+         {
+            temp |= (ossim_uint32)((*this)[(int)i] - '0');
+         }
+         else if( ((*this)[(int)i] >= 'A') && ((*this)[(int)i] <= 'F'))
+         {
+            temp |= (ossim_uint32)(10+((*this)[(int)i] - 'A'));
+         }
+         else if( ((*this)[(int)i] <= 'f') && ((*this)[(int)i] >= 'a'))
+         {
+            temp |= (ossim_uint32)(10 + ((*this)[(int)i] - 'a'));
+         }
+      }
+   }
+   
+   return temp;
+}
+
+void ossimHexString::assign(ossim_uint8 value)
+{
+   *this = "";
+   
+   ossim_int8 v1 = (ossim_int8)(value&0x0F);
+   ossim_int8 v2 = (ossim_int8)((value>>4)&0x0F);
+   if(v2 <=9)
+   {
+      (*this) += (ossim_int8)(v2+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v2-10 +'A');
+   }
+
+   if(v1 <=9)
+   {
+      (*this) += (ossim_int8)(v1+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v1-10 +'A');
+   }   
+}
+
+void ossimHexString::assign(ossim_uint16 value)
+{
+   *this = "";
+   
+   ossim_int8 v1 = (ossim_int8)(value&0x000F);
+   value >>=4;
+   ossim_int8 v2 = (ossim_int8)((value)&0x000F);
+   value >>=4;
+   ossim_int8 v3 = (ossim_int8)((value)&0x000F);
+   value >>=4;
+   ossim_int8 v4 = (ossim_int8)((value)&0x000F);
+
+   if(v4 <=9)
+   {
+      (*this) += (ossim_int8)(v4+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v4-10 +'A');
+   }
+
+   if(v3 <=9)
+   {
+      (*this) += (ossim_int8)(v3+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v3-10 +'A');
+   }
+
+   if(v2 <=9)
+   {
+      (*this) += (ossim_int8)(v2+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v2-10 +'A');
+   }
+
+   if(v1 <=9)
+   {
+      (*this) += (ossim_int8)(v1+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v1-10 +'A');
+   }
+}
+
+void ossimHexString::assign(ossim_uint32 value)
+{
+   *this = "";
+
+   ossim_int8 v1 = (ossim_int8)(value&0x0000000F);
+   value >>=4;
+   ossim_int8 v2 = (ossim_int8)((value)&0x0000000F);
+   value >>=4;
+   ossim_int8 v3 = (ossim_int8)((value)&0x0000000F);
+   value >>=4;
+   ossim_int8 v4 = (ossim_int8)((value)&0x0000000F);
+   value >>=4;
+   ossim_int8 v5 = (ossim_int8)((value)&0x0000000F);
+   value >>=4;
+   ossim_int8 v6 = (ossim_int8)((value)&0x0000000F);
+   value >>=4;
+   ossim_int8 v7 = (ossim_int8)((value)&0x0000000F);
+   value >>=4;
+   ossim_int8 v8 = (ossim_int8)((value)&0x0000000F);
+
+   if(v8 <=9)
+   {
+      (*this) += (ossim_int8)(v8+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v8-10 +'A');
+   }
+   if(v7 <=9)
+   {
+      (*this) += (ossim_int8)(v7+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v7-10 +'A');
+   }
+   if(v6 <=9)
+   {
+      (*this) += (ossim_int8)(v6+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v6-10 +'A');
+   }
+   if(v5 <=9)
+   {
+      (*this) += (ossim_int8)(v5+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v5-10 +'A');
+   }
+
+   if(v4 <=9)
+   {
+      (*this) += (ossim_int8)(v4+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v4-10 +'A');
+   }
+
+   if(v3 <=9)
+   {
+      (*this) += (ossim_int8)(v3+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v3-10 +'A');
+   }
+
+   if(v2 <=9)
+   {
+      (*this) += (ossim_int8)(v2+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v2-10 +'A');
+   }
+
+   if(v1 <=9)
+   {
+      (*this) += (ossim_int8)(v1+'0');
+   }
+   else
+   {
+      (*this) += (ossim_int8)(v1-10 +'A');
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimHexString.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimHexString.h
new file mode 100644
index 0000000000..6ec97e648e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimHexString.h
@@ -0,0 +1,152 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// 
+//********************************************************************
+// $Id: ossimHexString.h,v 1.6 2005/10/17 18:37:16 gpotts Exp $
+#include "base/data_types/ossimString.h"
+#include "base/common/ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimHexString : public ossimString
+{
+public:
+   ossimHexString():ossimString()
+      {}
+   ossimHexString(const std::string& aString):ossimString(aString)
+      {}
+   ossimHexString(const char *aString):ossimString(aString?aString:"")
+      {}
+   ossimHexString(const ossimString& aString):ossimString(aString.c_str())
+      {}
+   
+   ossimHexString(char value):ossimString()
+      {
+         assign(value);
+      }
+   ossimHexString(ossim_int16 value):ossimString()
+      {
+         assign(value);
+      }
+   ossimHexString(ossim_int32 value):ossimString()
+      {
+         assign(value);
+      }
+   ossimHexString(ossim_uint8 value):ossimString()
+      {
+         assign(value);
+      }
+   ossimHexString(ossim_uint16 value):ossimString()
+      {
+         assign(value);
+      }
+   ossimHexString(ossim_uint32 value):ossimString()
+      {
+         assign(value);
+      }
+
+   bool operator==(const ossimHexString& s) const {return (strcmp(this->c_str(),s.c_str())==0);}
+   bool operator==(const char* s) const {return (strcmp(this->c_str(),s)==0);}
+   bool operator!=(const ossimHexString& s) const {return (strcmp(this->c_str(),s.c_str())!=0);}
+   bool operator!=(const char* s) const {return (strcmp(this->c_str(),s)!=0);}
+   operator const char*()const{return c_str();}
+   const char* chars()const{return c_str();}
+   char& operator[](int i)
+      {
+         return *( const_cast<char*>(c_str())+i);
+      }
+   const char& operator[](int i)const
+      {
+         return *(c_str()+i);
+      }
+   const ossimHexString& operator =(ossim_int16 value)
+      {
+         assign(value);
+         return *this;
+      }
+   const ossimHexString& operator =(ossim_int32 value)
+      {
+         assign(value);
+         return *this;
+      }
+   const ossimHexString& operator =(ossim_uint16 value)
+      {
+         assign(value);
+         return *this;
+      }
+   const ossimHexString& operator =(ossim_uint32 value)
+      {
+         assign(value);
+         return *this;
+      }
+   const ossimHexString& operator =(ossim_int8 value)
+      {
+         assign(value);
+         return *this;
+      }
+   const ossimHexString& operator =(ossim_uint8 value)
+      {
+         assign(value);
+         return *this;
+      }
+   const ossimHexString& operator =(const ossim_int8* value)
+      {
+         ossimString::operator=(value);
+         return *this;
+      }
+   const ossimHexString& operator =(const ossimString& value)
+      {
+         ossimString::operator=(value);
+         return *this;
+      }
+
+   const ossimHexString& operator =(const ossimHexString& value)
+      {
+         ossimString::operator=(value);
+         return *this;
+      }
+
+   const ossimHexString& operator =(const std::string& value)
+      {
+         ossimString::operator=(value);
+         return *this;
+      }
+   
+   ossim_int32  toInt32()const;
+   ossim_int16  toInt16()const;
+   ossim_int8   toChar()const;
+   ossim_uint8  toUchar()const;
+   ossim_uint32 toUint32()const;
+   ossim_uint16 toUint16()const;
+
+   void assign(ossim_int16 value)
+      {
+         assign((ossim_uint16)value);
+      }
+   void assign(ossim_int32 value)
+      {
+         assign((ossim_uint32)value);
+      }
+   void assign(ossim_int8 value)
+      {
+         assign((ossim_uint8)value);
+      }
+   void assign(ossim_uint16 value);
+   void assign(ossim_uint32 value);
+   void assign(ossim_uint8  value);
+};
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimHistogram.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimHistogram.cpp
new file mode 100644
index 0000000000..c218f6e174
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimHistogram.cpp
@@ -0,0 +1,1378 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally developed by:
+//                   Copyright (c) 1997 TargetJr Consortium
+//               GE Corporate Research and Development (GE CRD)
+//                             1 Research Circle
+//                            Niskayuna, NY 12309
+//         Adapted from:  IUE v4.1.2
+// Description: 
+//      A ossimHistogram contains an array of "buckets", which represent finite
+// segments of some value axis, along with a corresponding array of
+// frequency counts for each of these buckets.
+//
+//********************************************************************
+// $Id: ossimHistogram.cpp,v 1.26 2005/09/09 11:14:07 gpotts Exp $
+//
+
+#include <stdio.h>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+using namespace std;
+
+#include <math.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimHistogram.h>
+#include <base/context/ossimNotifyContext.h>
+
+static const int MEAN_FLAG = 1, SD_FLAG = 2;
+RTTI_DEF1(ossimHistogram, "ossimHistogram", ossimObject);
+ossimHistogram::ossimHistogram()
+{
+    vals = new float [1];
+    vals[0] = 0.0;
+    counts = new float [1];
+    counts[0] = 0.0;
+    num = 0;
+    vmin = 0;
+    vmax = 0;
+    delta = 0.0;
+    mean = 0.0;
+    standard_dev = 0.0;
+    stats_consistent = 0;
+    stats_consistent |= (MEAN_FLAG | SD_FLAG);
+}
+
+ossimHistogram::ossimHistogram(int xres, float val1, float val2)
+{
+  vals = new float [xres];
+  counts = new float [xres];
+  num = xres;
+  vmax = MAX(val1, val2);
+  vmin = MIN(val1, val2);
+  delta = (vmax - vmin) / xres;
+  mean = (float)((vmax + vmin)/2.0);
+  standard_dev = (float)((vmax - vmin)/(2.0*sqrt(3.0)));
+  stats_consistent = 0;
+  stats_consistent |= (MEAN_FLAG | SD_FLAG);
+  int i = 0;
+
+  if (vals == NULL || counts == NULL)
+    {
+      fprintf(stderr, "Histogram : Ran out of memory for arrays.\n");
+      vals = NULL;
+      counts = NULL;
+      num = 0;
+      vmin = 0;
+      vmax = 0;
+      delta = 0.0;
+    }
+  else
+    {
+      for(i = 0; i < xres; i++)
+        {
+          vals[i] = vmin + delta * (float)(i + 0.5);
+          counts[i] = 0.0;
+        }
+    }
+}
+
+ossimHistogram::ossimHistogram(float* uvals, float* ucounts, int xres)
+{
+  vals = uvals;
+  counts = ucounts;
+  num = xres;
+  delta = vals[1] - vals[0]; // Changed this from delta = 1.0
+//  vmax = GetMaxVal();
+//  vmin = GetMinVal(); JAF version
+  vmin = uvals[0] - .5f*delta;
+  vmax = uvals[num-1] + .5f*delta;
+  mean = GetMean();
+  standard_dev = GetStandardDev();
+  stats_consistent = 0;
+  stats_consistent |= (MEAN_FLAG | SD_FLAG);
+}
+//-----------------------------------------------------------
+// -- Copy constructor
+ossimHistogram::ossimHistogram(const ossimHistogram& his)
+{
+
+  int i = 0;
+  num = his.GetRes();
+
+  vals = new float[num];
+  const float* his_vals = his.GetVals();
+
+  counts = new float[num];
+  const float* his_counts = his.GetCounts();
+
+  if (vals == NULL || counts == NULL)
+    {
+      fprintf(stderr, "Histogram : Ran out of memory for arrays.\n");
+      vals = NULL;
+      counts = NULL;
+      num = 0;
+      vmin = 0;
+      vmax = 0;
+      delta = 0.0;
+      stats_consistent = 0;
+      return;
+    }
+
+  mean = his.GetMean();
+  standard_dev = his.GetStandardDev();
+
+  for(i=0; i<num; i++)
+  {
+      vals[i] = his_vals[i];
+      counts[i] = his_counts[i];
+  }
+  vmax = his.GetMaxVal();
+  vmin = his.GetMinVal();
+  delta = his.GetBucketSize();
+
+  stats_consistent = 0;
+  stats_consistent |= (MEAN_FLAG | SD_FLAG);
+}
+
+
+//---------------------------------------
+// -- Resample a histogram
+
+ossimHistogram::ossimHistogram(const ossimHistogram* his, float width)
+{
+
+    stats_consistent =0;
+
+// Attributes of original histogram
+
+    float del = his->GetBucketSize();
+    int max_index = his->GetRes() - 1;
+    float minvalue = his->GetVals()[0] - del*.5f;
+    float maxvalue = his->GetVals()[max_index] + del*.5f;
+
+
+// Intialize a new histogram
+    if(width == del) num = his->GetRes();
+    else if(!(width == 0.0))
+      num = (int)ceil((maxvalue - minvalue)/width);
+    else
+      num = 1; // This shouldn't happen anyway.
+
+    vals = new float [num];
+    counts = new float [num];
+    delta = width;
+    float mean_val = (maxvalue + minvalue)/2.0f;
+    float half_range = (num * delta)/2.0f;
+    vmax =  mean_val + half_range;
+    vmin =  mean_val - half_range;
+   int i = 0;
+
+   if (vals == NULL || counts == NULL)
+     {
+       fprintf(stderr,
+	       "Histogram : Ran out of memory for arrays.\n");
+       vals = NULL;
+       counts = NULL;
+       num = 0;
+       vmin = 0;
+       vmax = 0;
+       delta = 0.0;
+       mean = 0.0;
+       standard_dev = 0.0;
+       stats_consistent |= (MEAN_FLAG | SD_FLAG);
+       return;
+       
+     }
+   
+   else
+     {
+       for(i = 0; i < num; i++)
+	 {
+	   vals[i] = vmin + delta * (i + 0.5f);
+	   counts[i] = 0.0;
+	 }
+     }
+
+
+// Cases:
+
+
+    if(width == del)    // Then just copy his
+	{
+	    const float* his_counts = his->GetCounts();
+	    for(i=0; i<num; i++)
+		counts[i] = his_counts[i];
+	    mean = GetMean();
+	    standard_dev = GetStandardDev();
+	    stats_consistent |= (MEAN_FLAG | SD_FLAG);
+	    return;
+	}
+
+
+    if(del > width)     // Then interpolate his counts.
+	{
+
+// Boundary conditions:
+//    Start
+	    float his_start = minvalue + .5f*del;
+            float start = vmin + .5f*delta;
+	    float c0 = his->GetCount(his_start);
+	    float c1 = his->GetCount(his_start + del);
+	    float s0 = (c1 - c0)/del;
+
+	    for(float x = start; x <= (his_start + del + delta);)
+		{
+		float interp = s0 * (x - his_start) + c0;
+		if(interp < 0) interp = 0; //Can be negative
+	        SetCount(x,interp);
+		    x += width;
+		}
+//    End
+	    float his_end = maxvalue - .5f*del;
+            float end = vmax - .5f*delta;
+	    float cn = his->GetCount(his_end);
+	    float cn_1 = his->GetCount(his_end - del);
+	    float sn = (cn_1 - cn)/del;
+
+	    for(float y = end; y >= (his_end - del + delta);)
+		{
+ 		float interp = sn * (his_end - y) + cn;
+		if(interp < 0) interp = 0; //Can be negative
+		SetCount(y, interp);
+		y -= delta;
+		}
+// Interior Loop
+
+	    for(float z = his_start + del; z <= (his_end - del);)
+		{
+		    float ci = his->GetCount(z);
+		    float ci_1 = his->GetCount(z-del);
+		    float cip1 = his->GetCount(z+del);
+		    float deriv = (cip1 - ci_1)/(2.0f*del);
+		    float second_drv =
+			((cip1 + ci_1)/2.0f - ci)/(del*del);
+		    int fine_x_index = GetIndex(z);
+		    if (fine_x_index < 0)
+		      {
+			if (z<vmin) fine_x_index = 0;
+			else fine_x_index = num-1;
+		      }
+		    float fine_x = vals[fine_x_index];
+		    for(float xfine = fine_x; xfine < z + del;)
+			{
+		            float interp = ci + deriv*(xfine -z) +
+					 second_drv*(xfine - z)*(xfine - z);
+
+		            if(interp < 0) interp = 0; //Can be negative
+			    SetCount(xfine, interp);
+			    xfine += width;
+			}
+		    z += del;
+		}
+	}
+
+
+    if(del < width)    //Just accumulate samples from his into larger bins
+	{
+	  if( del != 0.0){
+	    float his_start = minvalue + .5f*del;
+	    float his_end = maxvalue - .5f*del;
+	    for(float x = his_start; x <= his_end;)
+		{
+		SetCount(x, (GetCount(x) + his->GetCount(x)));
+		 x += del;
+		}
+	  }
+	}
+    mean = GetMean();
+    standard_dev = GetStandardDev();
+    stats_consistent =0;
+    stats_consistent |= (MEAN_FLAG | SD_FLAG);
+}
+
+void ossimHistogram::create(int xres, float val1, float val2)
+{
+   // clear all the data
+   deleteAll();
+
+   // now set it up and initialize;
+   xres = xres >0? xres:1;
+   
+   vals   = new float [xres];
+   counts = new float [xres];
+   num = xres;
+   vmax = MAX(val1, val2);
+   vmin = MIN(val1, val2);
+
+   delta = (vmax - vmin) / xres;
+   mean = (float)((vmax + vmin)/2.0);
+   standard_dev = (float)((vmax - vmin)/(2.0*sqrt(3.0)));
+   stats_consistent = 0;
+   stats_consistent |= (MEAN_FLAG | SD_FLAG);
+   int i = 0;
+   if (vals == NULL || counts == NULL)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "Histogram : Ran out of memory for arrays.\n";
+      vals = NULL;
+      counts = NULL;
+      num = 0;
+      vmin = 0;
+      vmax = 0;
+      delta = 0.0;
+   }
+   else
+   {
+      for(i = 0; i < xres; i++)
+      {
+         vals[i] = vmin + delta * (float)(i + 0.5);
+         counts[i] = 0.0;
+      }
+   }   
+}
+//--------------------------------------------------
+// -- Transform the value axis of a histogram by a
+//    translation, transl, and a scale factor, scale.
+//    The new histogram has the same resolution as his.
+
+ossimHistogram* ossimHistogram::Scale(float scale_factor)
+{
+
+// Extract attributes of self
+
+//    float lowvalue = vals[0];
+    float highvalue = vals[num-1];
+
+// Construct a new histogram
+
+    ossimHistogram* scaled_his = new ossimHistogram(this, delta);
+    float* new_counts = scaled_his->GetCounts();
+    int i = 0;
+    for(i=0; i < num; i++)  // Initialize
+	new_counts[i] = 0.0;
+
+// Compute scaled values
+// We assume that the new histogram is to be scaled down from his
+
+    float scale = scale_factor;
+    if(scale_factor > 1.0) scale = 1.0;
+
+    for(float x = highvalue; x > vmin;)
+	{
+	    float trans_x = (x-vmin)*scale + vmin; // Scaled x.
+ 	    int index = GetIndex(trans_x);
+	    if (index < 0)
+	      {
+		if (trans_x<vmin) index = 0;
+		else index = num-1;
+	      }
+	    float fraction = (trans_x - vals[index])/delta;
+	    float abs_fraction = (float)fabs(fraction);
+	    int x_index = GetIndex(x);
+	    if (x_index < 0)
+	      {
+		if (x<vmin) x_index = 0;
+		else x_index = num-1;
+	      }
+
+// Distribute the counts in proportion
+
+	    new_counts[index] += (1.0f - abs_fraction)*counts[x_index];
+	    if(fraction > 0)
+		if(index < (num-1))
+                   new_counts[index + 1] +=
+                      abs_fraction*counts[x_index];
+		else
+                   new_counts[index] +=
+                      abs_fraction*counts[x_index];
+	    else
+	        if(index > 0)
+                   new_counts[index - 1] +=
+                      abs_fraction*counts[x_index];
+		else
+                   new_counts[index] +=
+				 abs_fraction*counts[x_index];
+	    x -= delta;
+	}
+
+// Compute new Histogram attributes
+
+    mean = scaled_his->GetMean();
+    standard_dev = scaled_his->GetStandardDev();
+    return scaled_his;
+}
+
+//---------------------------------------------------------------------
+// -- Assuming that "this" is a histogram of population density,
+//    construct a new histogram which is the cumulative distribution.
+//    Each bin, xi, in his is assumed to represent a density, i.e.,
+//            {x | (xi - .5*delta) < x <= (xi + .5*delta)}
+//    Each bin, xi, in the result represents a cumulative distribution, i.e.,
+//            {x | x <= (xi + .5*delta)}
+ossimHistogram* ossimHistogram::CumulativeGreaterThanEqual()const
+{
+  ossimHistogram* cum_his = new ossimHistogram(*this);
+  const float* density_counts = this->GetCounts();
+  int res = this->GetRes();
+
+  // Intitialize cumulative counts
+  float* cum_counts = cum_his->GetCounts();
+  int i = 0;
+  for(i=0; i < res; i++)
+     cum_counts[i] = 0;
+  
+  cum_counts[res-1] = density_counts[res-1];
+  for(i = res-2; i>=0; --i)
+  {
+     cum_counts[i] += (density_counts[i] + cum_counts[i+1]);
+  }
+
+  return cum_his;
+}
+
+ossimHistogram* ossimHistogram::CumulativeLessThanEqual()const
+{
+  ossimHistogram* cum_his = new ossimHistogram(*this);
+  const float* density_counts = this->GetCounts();
+  int res = this->GetRes();
+
+  // Intitialize cumulative counts
+  float* cum_counts = cum_his->GetCounts();
+  int i = 0;
+  for(i=0; i < res; i++)
+    cum_counts[i] = 0;
+
+  cum_counts[0] = density_counts[0];
+  for(i = 1; i < res; i++)
+  {
+     cum_counts[i] += (density_counts[i] + cum_counts[i-1]);
+  }
+  
+  return cum_his;
+}
+
+//Provides the correct values for histogram counts when the bin index 
+//extends outside the valid range of the counts array.  This function
+//permits easy array access logic for the NonMaximumSuppression algorithm.
+//The cyclic flag indicates that the counts array index is circular, i.e,
+//cnts[0] equivalent to cnts[n_bins-1]
+inline float GetExtendedCount(int bin, int n_bins, float* cnts, bool cyclic)
+{
+  int nbm = n_bins-1;
+  if(!cyclic)
+    {
+      if(bin < 0)
+	return cnts[0];
+      if(bin >= n_bins)
+	return cnts[nbm];
+    }
+  else
+    {
+      if(bin<0)
+	return cnts[nbm+bin];
+      if(bin >= n_bins)
+	return cnts[bin-n_bins];
+    }
+  return cnts[bin];
+}
+//Prune any sequences of more than one maxium value
+//That is, it is possible to have a "flat" top peak with an arbitarily
+//long sequence of equal, but maximum values. The cyclic flag indictates
+//that the sequence wraps around, i.e. cnts[0] equivalent to cnts[nbins-1]
+inline void RemoveFlatPeaks(int nbins, float* cnts, bool cyclic)
+{
+  int nbm = nbins-1;
+
+  //Here we define a small state machine - parsing for runs of peaks
+  //init is the state corresponding to an initial run (starting at i ==0)
+  bool init=GetExtendedCount(0, nbins, cnts, cyclic);
+  int init_end =0;
+
+  //start is the state corresponding to any other run of peaks
+  bool start=false;  
+  int start_index=0; 
+  int i = 0;
+
+  //The scan of the state machine
+  for(i = 0; i < nbins; i++)
+    {
+      float v = GetExtendedCount(i, nbins, cnts, cyclic);
+
+      //State init: a string of non-zeroes at the begining.
+      if(init&&v!=0)
+	continue;
+
+      if(init&&v==0)
+	{
+	  init_end = i;
+	  init = false;
+	  continue;
+	}
+
+      //State !init&&!start: a string of "0s"
+      if(!start&&v==0)
+	continue;
+
+      //State !init&&start: the first non-zero value
+      if(!start&&v!=0)
+	{
+	  start_index = i;
+	  start = true;
+	  continue;
+	}
+      //State ending flat peak: encountered a subsequent zero after starting
+      if(start&&v==0)
+	{
+	  int peak_location = (start_index+i-1)/2;//The middle of the run
+	  int k = 0;
+	  for(k = start_index; k<=(i-1); k++)
+	    if(k!=peak_location)
+	      cnts[k] = 0;
+	  start = false;
+	}
+    }
+  //Now handle the boundary conditions
+  //The non-cyclic case
+  if(!cyclic)
+    {
+      if(init_end!=0)  //Was there an initial run of peaks?
+	{
+	  int init_location = (init_end-1)/2;
+	  int k = 0;
+	  for(k = 0; k<init_end; k++)
+	    if(k!=init_location)
+	      cnts[k] = 0;
+	}
+      if(start)       // Did we reach the end of the array in a run of pks?
+	{
+	  int end_location = (start_index + nbm)/2;
+	  int k = 0;
+	  for(k = start_index; k<nbins; k++)
+	    if(k!=end_location)
+	      cnts[k] = 0;
+	}
+    }
+  else  //The cyclic case
+    {
+      if(init_end!=0)  //Is there a run which crosses the cyclic cut?
+	if(start)    
+	  { //Yes, so define the peak location accordingly
+	    int peak_location = (start_index + init_end - nbm -1)/2;
+	    int k;
+	    if(peak_location < 0) //Is the peak to the left of the cut?
+	      {// Yes, to the left
+		peak_location += nbm; 
+		for( k = 0; k< init_end; k++)
+		  cnts[k]=0;
+		for( k= start_index; k <nbins; k++)
+		  if(k!=peak_location)
+		    cnts[k] = 0;
+	      }
+	    else   
+	      {//No, on the right.
+		for( k = start_index; k< nbins; k++)
+		  cnts[k]=0;
+		for( k= 0; k < init_end; k++)
+		  if(k!=peak_location)
+		    cnts[k] = 0;
+	      }
+	  }
+	else  
+	  {//There wasn't a final run so just clean up the initial run
+	    int init_location = (init_end-1)/2;
+	    int k = 0;
+	    for(k = start_index; k<init_end; k++)
+	      if(k!=init_location)
+		cnts[k] = 0;
+	  }
+    }
+}
+
+//----------------------------------------------------------
+// -- Suppress values in the Histogram which are not locally 
+//    a maxium. The neighborhood for computing the local maximum
+//    is [radius X radius], e.g. for radius =1 the neighborhood
+//    is [-X-], for radius = 2, the neighborhood is [--X--], etc.
+//    If the cyclic flag is true then the index space is assumed to
+//    be equivalent to a circle. That is, elements "0" and (n_buckets-1)
+//    are in correspondence.
+ossimHistogram* ossimHistogram::NonMaximumSupress(int radius, bool cyclic)
+{
+  if((2*radius +1)> num/2)
+    {
+       ossimNotify(ossimNotifyLevel_WARN)<<"ossimHistogram::NonMaximumSupress the radius is too large \n";
+       return NULL;
+    }
+  //Get the counts array of "this"
+  ossimHistogram* h_new = new ossimHistogram(*this);
+  int n_buckets = h_new->GetRes();
+  float* counts_old = this->GetCounts();
+
+  //Make a new Histogram for the suppressed version
+  float* counts_new = h_new->GetCounts();
+  int i;
+  for( i =0; i < n_buckets; i++)
+    counts_new[i] = 0;
+  
+  //Find local maxima
+  for( i = 0; i<  n_buckets; i++)
+    {
+      //find the maxium value in the current kernel
+      float max_count = counts_old[i];
+      int k = 0;
+      for(k = -radius; k <= radius ;k++)
+	{
+	  int index = i+k;
+	  float c = GetExtendedCount(index, n_buckets, counts_old, cyclic);
+	  if( c > max_count)
+	    max_count = c;
+	}
+      //Is position i a local maxium?
+      if(max_count == counts_old[i])
+	counts_new[i] = max_count;//Yes. So set the counts to the max value
+    }
+  RemoveFlatPeaks(n_buckets, counts_new, cyclic);
+  return h_new;
+}
+//----------------------------------------------------------
+// -- Compute the mean of the histogram population
+float ossimHistogram::GetMean()const
+{
+  float xsum = 0.0;
+
+    if(MEAN_FLAG&stats_consistent)
+	return mean;
+    else
+	{
+	  if( this->GetBucketSize() > 0.0){
+	    for(float x=this->GetMinVal(); x<= this->GetMaxVal(); x +=this->GetBucketSize())
+	      xsum += x*GetCount(x);
+	  }
+
+	  float area = ComputeArea(vmin, vmax);
+	  if(area <= 0.0)
+	    {
+	      //	      fprintf(stderr, "Histogram : Area <= 0.0\n");
+	      return 0.0;
+	    }
+	  else
+	    {
+	      stats_consistent |=1;
+	      mean = xsum/area;
+	      return mean;
+	    }
+	}
+}
+
+
+
+float ossimHistogram::GetStandardDev()const
+{
+  float sum = 0.0;
+
+    if(SD_FLAG&stats_consistent)
+	return standard_dev;
+    else
+	{
+	    float xm = this -> GetMean(); // Force an Update of Mean
+
+	    if( this->GetBucketSize() > 0.0){
+	      for(float x=this->GetMinVal();
+		  x<= this->GetMaxVal();
+		  x +=this->GetBucketSize())
+
+		sum += (x-xm)*(x-xm)*GetCount(x);
+	    }
+
+	float area = ComputeArea(vmin, vmax);
+	if(area <= 0.0)
+	{
+	  //	      fprintf(stderr, "Histogram : Area <= 0.0\n");
+	      return 0.0;
+        }
+	else
+	    {
+		stats_consistent |= 2;
+		standard_dev = (float)sqrt(sum/area);
+		return standard_dev;
+	    }
+	}
+}
+
+int ossimHistogram::GetIndex(float pixelval)const
+{
+   if ((pixelval > vmax) || (pixelval < vmin)||(num==0))
+   {
+      return -1;
+   }
+//   ossim_float32 d = vmax-vmin;
+   int bandIdx = (ossim_int32)((pixelval-vmin)/delta);
+   return bandIdx<GetRes()?bandIdx:-1;
+//    if(bandIdx == num)
+//    {
+//       return num-1;
+//    }
+//    else if(bandIdx < num)
+//    {
+//       return bandIdx;
+//    }
+//    return -1;
+#if 0
+  if ((pixelval > vmax) || (pixelval < vmin))
+    return -1;
+
+  int idx = 0;
+  int i = 0;
+
+  for(i = 0; i < num; i++)
+    {
+      // RWMC: This is very dangerous - might get an intermediate
+      // value which is between vals[i]+0.5*delta and
+      // vals[i+1]-0.5*delta, which would then return index of 0.
+      // Changed to check range one-sided, which is safe because of
+      // previous check on range.
+      //       if ((pixelval > (vals[i] - 0.5 * delta)) &&
+      //           (pixelval <= (vals[i] + 0.5 * delta)))
+      if (pixelval <= (vals[i] + 0.5 * delta))
+	{
+	  idx = i;
+	  break;
+	}
+    }
+
+  return idx;
+#endif
+}
+
+
+int ossimHistogram::GetValIndex(float pixelval)const
+{
+  if ((pixelval > vmax) || (pixelval < vmin))
+    return -1;
+
+  int idx = 0;
+  int i = 0;
+
+  for(i = 0; i < num; i++)
+    {
+      if ((pixelval > (vals[i] - 0.5 * delta)) &&
+          (pixelval <= (vals[i] + 0.5 * delta)))
+	{
+	  idx = i;
+	  break;
+	}
+    }
+
+  return idx;
+}
+
+
+
+float ossimHistogram::GetCount(float pixelval)const
+{
+  int index = GetIndex(pixelval);
+
+  if (index < 0)
+    return -1;
+  else
+    return counts[index];
+}
+
+
+
+float ossimHistogram::GetMinVal()const
+{
+  register int i=0;
+
+  while (i<num-1 && !counts[i])
+       i++;
+
+  return vals[i];
+}
+
+
+
+
+float ossimHistogram::GetMaxVal()const
+{
+  register int i=num-1;
+
+  while (i>0 && !counts[i])
+       i--;
+
+  if (i < 0)
+    return 0.0;
+
+  return vals[i];
+}
+
+
+float ossimHistogram::GetMaxCount()const
+{
+  register int i=0;
+  float max;
+  max = 0.0;
+  for (i=0; i < num; i++)
+    if (counts[i] > max)
+      max = counts[i];
+  return max;
+}
+
+
+
+
+float ossimHistogram::SetCount(float pixelval, float count)
+{
+  stats_consistent = 0;
+
+  int index = GetIndex(pixelval);
+
+  if (index < 0)
+    return -1;
+  else
+   {
+    counts[index] = count;
+    return count;
+  }
+}
+
+
+void ossimHistogram::UpCount(float pixelval)
+{
+
+  stats_consistent = 0;
+  int idx = GetIndex(pixelval);
+  if (idx >= 0)  // Originally (index > 0)
+  {
+     counts[idx] += 1.0;
+  }
+}
+
+float ossimHistogram::ComputeArea(float low, float high)const
+{
+  float maxval = GetMaxVal();
+  float minval = GetMinVal();
+
+  if (low < minval) low = minval;
+  if (high > maxval) high = maxval;
+
+  if (low <= high)
+    {
+      int indexlow, indexhigh;
+      indexlow = (int) GetIndex(low);
+      if (indexlow < 0)
+	{
+	  if (low<vmin) indexlow = 0;
+	  else indexlow = num-1;
+	}
+      indexhigh = (int) GetIndex(high);
+      if (indexhigh < 0)
+	{
+	  if (high<vmin) indexhigh = 0;
+	  else indexhigh = num-1;
+	}
+      register int i=indexlow;
+      float sum = 0.0;
+
+      while (i<=indexhigh)
+	{
+	sum+= counts[i];
+	i++;
+      }
+      return sum;
+    }
+  else
+    {
+      //      fprintf(stderr, "Histogram : Range for ComputeArea is out of bounds.\n");
+      return 0.0;
+    }
+}
+//----------------------------------------------------------------------
+// --Compute the total area under the histogram
+//
+float ossimHistogram::ComputeArea()const
+{
+  float vmin = this->GetMinVal();
+  float vmax = this->GetMaxVal();
+  if(vmin>vmax)
+    {
+      float temp = vmin;
+      vmin = vmax;
+      vmax = temp;
+    }
+  return this->ComputeArea(vmin, vmax);
+}
+
+float ossimHistogram::getLowFractionFromValue(float val) const
+{
+   
+   float min = floor(GetMinVal());
+   float max = ceil(GetMaxVal());
+   if (val < min || val > max)
+   {
+      return OSSIM_FLT_NAN;
+   }
+
+   int total_buckets = GetRes();
+   int cutoff_bucket = GetValIndex(val);
+   float partial_sum = 0.0;
+   float total_sum   = 0.0;
+   
+   for(int i = 0; i < total_buckets; ++i)
+   {
+      total_sum += counts[i];
+      if (i <= cutoff_bucket)
+      {
+         partial_sum += counts[i];
+      }
+    }
+
+   return (partial_sum/total_sum);
+}
+
+float ossimHistogram::getHighFractionFromValue(float val) const
+{
+   float min = floor(GetMinVal());
+   float max = ceil(GetMaxVal());
+   if (val < min || val > max)
+   {
+      return OSSIM_FLT_NAN;
+   }
+
+   int total_buckets = GetRes();
+   int cutoff_bucket = GetValIndex(val);
+   float partial_sum = 0.0;
+   float total_sum   = 0.0;
+   
+   for(int i = (total_buckets-1); i >= 0; --i)
+   {
+      total_sum += counts[i];
+      if (i >= cutoff_bucket)
+      {
+         partial_sum += counts[i];
+      }
+    }
+
+   return (partial_sum/total_sum);
+}
+
+//----------------------------------------------------------------------
+//  -- Finds the lower bound value which elminates a given fraction of
+//     histogram area.
+//
+float ossimHistogram::LowClipVal(float clip_fraction)const
+{
+  if(clip_fraction<0) clip_fraction=0.0;
+  if(clip_fraction>1.0) clip_fraction=1.0;
+  float area = this->ComputeArea();
+  if(area==0.0) return this->GetMinVal();
+  if(clip_fraction==0.0) return this->GetMinVal();
+  if(clip_fraction==1.0) return this->GetMaxVal();
+  float clip_area = area*clip_fraction;
+  const float* COUNTS = this->GetCounts();
+  const float* VALS = this->GetVals();
+  int res = this->GetRes();
+  float sum = 0;
+  int i=0;
+  for(; i<res; i++)
+    {
+      sum+=COUNTS[i];
+      if(sum>=clip_area)
+	break;
+    }
+  return VALS[i];
+}
+
+//----------------------------------------------------------------------
+//  -- Finds the lower bound value which elminates a given fraction of
+//     histogram area.
+//
+float ossimHistogram::HighClipVal(float clip_fraction)const
+{
+  if(clip_fraction<0) clip_fraction=0.0;
+  if(clip_fraction>1.0) clip_fraction=1.0;
+  float area = this->ComputeArea();
+  if(area==0.0) return this->GetMaxVal();
+  if(clip_fraction==0.0) return this->GetMaxVal();
+  if(clip_fraction==1.0) return this->GetMinVal();
+  float clip_area = area*clip_fraction;
+  const float* COUNTS = this->GetCounts();
+  const float* VALS = this->GetVals();
+  int res = this->GetRes();
+  float sum = 0;
+  int i = (res-1);
+  for(; i>=0; i--)
+    {
+      sum+=COUNTS[i];
+      if(sum>=clip_area)
+	break;
+    }
+  return VALS[i];
+}
+
+//--------------------------------------------------------------------------
+// -- Prints histogram counts onto cout
+void ossimHistogram::Print()const
+{
+   ostream& out = ossimNotify(ossimNotifyLevel_INFO);
+    const float* VALS = this->GetVals();
+    const float* COUNTS = this->GetCounts();
+    int res = this->GetRes();
+    int width = 0;
+    int i = 0;
+    for(i =0; i < res; i++)
+      {
+	if(width++ > 5)
+	  {
+	    width = 0;
+	    out << "\n";
+	  }
+	out << VALS[i] << " "
+            << COUNTS[i] << " | " ;
+      }
+    out << "\n MaxVal " << this->GetMaxVal() << "\n";
+    out << " MinVal " << this->GetMinVal() << "\n";
+    out << " BucketSize " << this->GetBucketSize() << "\n";
+    out << " Resolution " << this->GetRes() << "\n";
+    out << " Area "
+        << this->ComputeArea(this->GetMinVal(),this->GetMaxVal()) << "\n";
+    out << "------------------------------------------------\n\n";
+}
+
+//---------------------------------------------------------------------------
+// --- dumps histogram  values  to file.
+
+void ossimHistogram::Dump(char *dumpfile)const
+{
+  FILE *dumpfp = fopen(dumpfile, "w");
+
+  if (!dumpfp)
+    {
+      fprintf(stderr, "Error opening histogram data file.\n");
+      return;
+    }
+  int i = 0;
+
+  for(i = 0; i < num; i++)
+    fprintf(dumpfp, "%f %f\n", vals[i], counts[i]);
+  
+  fclose(dumpfp);
+  return;
+}
+
+//---------------------------------------------------------------------------
+// -- Writes histogram in format suitable for plotting tools like Gnuplot.
+
+int ossimHistogram::WritePlot(const char *fname)const
+{
+  FILE *fp = fopen(fname, "w");
+
+  if (!fp)
+    {
+      fprintf(stderr, "Error opening histogram plot file.\n");
+      return 0;
+    }
+
+  int stat_res = this->GetRes();
+
+  float * x = new float[2*stat_res];
+  float * y = new float[2*stat_res];
+
+  const float * temp_x = this->GetVals();
+  const float * temp_y = this->GetCounts();
+  float     delt = this->GetBucketSize();
+
+  for (register int i=0; i < stat_res ;i++)
+    {
+      x[2*i] = temp_x[i] - 0.5f * delt;
+      x[2*i+1] = temp_x[i] + 0.5f * delt;
+      y[2*i] = temp_y[i];
+      y[2*i+1] = temp_y[i];
+    }
+
+
+  for(register int j = 0; j < 2*stat_res; j++)
+    fprintf(fp, "%f %f\n", x[j], y[j]);
+
+  delete [] x;
+  delete [] y;
+
+  fclose(fp);
+  return 1;
+}
+
+void ossimHistogram::deleteAll()
+{
+   if (vals)
+   {
+      delete []vals;
+      vals = NULL;
+   }
+   if (counts)
+   {
+      delete []counts;
+      counts = NULL;
+   }  
+}
+
+ossimHistogram::~ossimHistogram()
+{
+   deleteAll();
+}
+
+
+bool ossimHistogram::importHistogram(istream& in)
+{
+   ossimProprietaryHeaderInformation header;
+   bool binsCreated = false;
+   
+   if(header.parseStream(in))
+   {
+      long numberOfBins = header.getNumberOfBins();
+      
+      if(numberOfBins)
+      {
+         create(numberOfBins, 0, numberOfBins - 1);
+         binsCreated = true;
+
+         if(binsCreated)
+         {
+            ossimString buffer;
+            ossimString binNumber;
+            ossimString count;
+
+            while(in.good() &&
+                  !in.eof() &&
+                  *binNumber.c_str() != '.')
+            {
+               
+               getline(in, buffer);
+
+               istringstream s(buffer);
+
+               s >> binNumber >> count;
+               if(*binNumber.c_str() != (char)'.')
+               {
+                  SetCount((float)binNumber.toDouble(),
+                           (float)count.toDouble());
+               }
+            }
+         }
+      }
+      else
+      {
+         return false;
+      }
+   }  
+   return true;
+}
+
+bool ossimHistogram::importHistogram(const ossimFilename& inputFile)
+{
+   if(inputFile.exists())
+   {
+      ifstream input(inputFile.c_str());
+
+      return importHistogram(input);
+   }
+
+   return false;  
+}
+
+
+bool ossimHistogram::ossimProprietaryHeaderInformation::parseStream(istream& in)
+{
+   ossimString inputLine;
+   
+   getline(in, inputLine);  
+   if(inputLine.find("File Type") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theFileType = inputLine.substr(index+1);
+         theFileType = theFileType.trim();
+      }
+      else
+      {
+         return false;
+      }
+
+   }
+   else
+   {
+      return false;
+   }
+
+   getline(in, inputLine);  
+   if(inputLine.find("Version") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theVersion = inputLine.substr(index+1);
+         theVersion = theVersion.trim();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+
+   getline(in, inputLine);  
+   if(inputLine.find("Mapper Type") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theMapperType = inputLine.substr(index+1);
+         theMapperType = theMapperType.trim();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+
+   getline(in, inputLine);  
+   if(inputLine.find("Number of Bins") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theNumberOfBins = inputLine.substr(index+1);
+         theNumberOfBins = theNumberOfBins.trim();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   return true;   
+}
+
+bool ossimHistogram::saveState(ossimKeywordlist& kwl,
+                               const char* prefix)const
+{
+   kwl.add(prefix,
+           "type",
+           "ossimHistogram",
+           true);
+   kwl.add(prefix,
+           "number_of_bins",
+           num,
+           true);
+   kwl.add(prefix,
+           "min_value",
+           vmin,
+           true);
+   kwl.add(prefix,
+           "max_value",
+           vmax,
+           true);
+   ossimString binValue = "";
+   for(long index = 0; index < num; ++index)
+   {
+      if(fabs(counts[index]) > FLT_EPSILON)
+      {
+         //     binValue = prefix;
+         binValue = "bin";
+         binValue += ossimString::toString(index);
+         
+         kwl.add(prefix,
+                 binValue.c_str(),
+                 counts[index],
+                 true);
+      }
+   }
+   
+   return true;
+}
+
+bool ossimHistogram::loadState(const ossimKeywordlist& kwl,
+                               const char* prefix)
+{
+   const char* number_of_bins = kwl.find(prefix, "number_of_bins");
+
+   if(number_of_bins)
+   {
+      long bins = ossimString(number_of_bins).toLong();
+
+      if(bins > 0)
+      {
+         // setup some defaults
+         float minValue = 0;
+         float maxValue = bins - 1;
+
+         // see if there is a range set for the data
+         const char* min_value = kwl.find(prefix, "min_value");
+         const char* max_value = kwl.find(prefix, "max_value");
+
+         if(min_value)
+         {
+            minValue = (ossim_float32)ossimString(min_value).toDouble();
+         }
+         if(max_value)
+         {
+            maxValue = (ossim_float32)ossimString(max_value).toDouble();
+         }
+         // create the bins
+         create(bins, minValue, maxValue);
+         ossimString binNumber = "";
+         ossimString regExpression =  ossimString("^(") + ossimString(prefix) + "bin[0-9]+)";
+         vector<ossimString> keys = kwl.getSubstringKeyList( regExpression );
+         ossim_uint32 numberOfBins = keys.size();
+         ossim_uint32 offset = (ossimString(prefix)+"bin").size();
+
+         std::vector<ossim_uint32> theNumberList(numberOfBins);
+         ossim_uint32 idx = 0;
+         for(idx = 0; idx < theNumberList.size();++idx)
+         {
+            ossimString numberStr(keys[idx].begin() + offset,
+                                  keys[idx].end());
+            theNumberList[idx] = numberStr.toUInt32();
+
+         }
+         
+         float* countsPtr = GetCounts();
+         memset(countsPtr, '\0', bins*sizeof(float));
+         for(idx = 0; idx < numberOfBins;++idx)
+         {
+            const char* binCount = kwl.find(prefix, ossimString("bin") + ossimString::toString(theNumberList[idx]));
+            countsPtr[theNumberList[idx]] = (float)ossimString(binCount).toDouble();
+         }
+      }
+   }
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimHistogram.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimHistogram.h
new file mode 100644
index 0000000000..b053f70a0a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimHistogram.h
@@ -0,0 +1,206 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally developed by:
+//                   Copyright (c) 1997 TargetJr Consortium
+//               GE Corporate Research and Development (GE CRD)
+//                             1 Research Circle
+//                            Niskayuna, NY 12309
+//         Adapted from:  IUE v4.1.2
+// Description: 
+//      A Histogram contains an array of "buckets", which represent finite
+// segments of some value axis, along with a corresponding array of
+// frequency counts for each of these buckets.
+//
+//********************************************************************
+// $Id: ossimHistogram.h,v 1.11 2005/09/01 13:59:47 gpotts Exp $
+//
+
+#ifndef ossimHistogram_HEADER
+#define ossimHistogram_HEADER
+#include <base/common/ossimObject.h>
+#include "ossimString.h"
+#include "ossimFilename.h"
+#include "ossimKeywordlist.h"
+class OSSIMDLLEXPORT ossimHistogram : public ossimObject
+{
+  private:
+
+    mutable int stats_consistent; // A 2 bit state flag  Mean =1 | StandDev = 2
+
+  protected:
+
+   virtual void deleteAll();
+   
+    float * vals;            // histogram x array
+                             // (value = midpoint of each bucket)
+    float * counts;          // histogram y array ie. count[i] is
+                             // the number of pixels with value within range
+                             // of bucket i
+
+    int num;                 // number of indices
+
+    float delta;             // "Width" of each bucket on value axis
+    float vmin, vmax;        // Maximum and minimum values on plot
+    mutable float mean;               // Mean value of the distribution
+    mutable float standard_dev;       // 
+  protected:
+
+
+   class ossimProprietaryHeaderInformation
+   {
+   public:
+      ossimProprietaryHeaderInformation(){clear();}
+
+      bool parseStream(istream& in);
+
+      long getNumberOfBins()
+         {
+            return theNumberOfBins.toLong();
+         }
+      void clear()
+         {
+            theFileType      = "";
+            theVersion       = "";
+            theMapperType    = "";
+            theNumberOfBins  = "";
+         }
+      ossimString theFileType;
+      ossimString theVersion;
+      ossimString theMapperType;
+      ossimString theNumberOfBins;
+   };
+   
+  public:
+// Constructors
+    ossimHistogram();
+    ossimHistogram(int xres, float min, float max);
+    ossimHistogram(float*, float*, int);
+    ossimHistogram(const ossimHistogram& his); // Copy constructor
+    ossimHistogram(const ossimHistogram*, float width); // Resampling constructor
+
+    virtual int GetIndex(float)const;
+// Other histogram formation operations    
+    ossimHistogram* Scale(float scale_factor); // Scale Transformation
+    ossimHistogram* CumulativeGreaterThanEqual()const;// From density to cumulative
+    ossimHistogram* CumulativeLessThanEqual()const;// From density to cumulative
+    //Suppress non-peak values.
+   ossimHistogram* NonMaximumSupress(int radius = 1, bool cyclic = false);
+   void create(int xres, float val1, float val2);
+  
+// Attribute accessors
+    void UpCount(float newval);
+    float GetCount(float uval)const;
+    float SetCount(float pixelval, float count);
+
+    float GetMinVal()const;
+    float GetMaxVal()const;
+    float GetMaxCount()const;
+
+    float GetRangeMin()const
+    {
+       return vmin;
+    }
+    float GetRangeMax()const
+    {
+       return vmax;
+    }
+    float * GetVals()
+    {
+	stats_consistent = 0; // Values might change.
+	return vals; 
+    }
+    const float * GetVals()const
+    {
+	stats_consistent = 0; // Values might change.
+	return vals; 
+    }
+
+    float * GetCounts()
+    { 
+	stats_consistent = 0; // Counts might change.
+	return counts; 
+    }
+
+   const float * GetCounts()const
+    { 
+	stats_consistent = 0; // Counts might change.
+	return counts; 
+    }
+
+    int GetRes()const
+    { return num; }
+
+    float GetBucketSize()const { return delta; }
+
+    float * GetMinValAddr()
+    { return vals+GetIndex(GetMinVal());  }
+
+    float * GetMinCountAddr()
+    { return counts+GetIndex(GetMinVal());  }
+
+   const float * GetMinValAddr()const
+    { return vals+GetIndex(GetMinVal());  }
+
+    const float * GetMinCountAddr()const
+    { return counts+GetIndex(GetMinVal());  }
+
+    float ComputeArea(float low, float high)const;// bounded area
+    float ComputeArea()const;//total area
+
+    /*!
+     * Returns the fraction of accumulation up to and including "val" bucket
+     * from min divided by the total accumulation.
+     * returns OSSIM_FLT_NAN if "val" is not between GetMinVal and GetMaxVal.
+     */
+    float getLowFractionFromValue(float val) const;
+    
+    /*!
+     * Returns the fraction of accumulation down to and including "val" bucket
+     * from max divided by the total accumulation.
+     * returns OSSIM_FLT_NAN if "val" is not between GetMin() and GetMax().
+     */
+    float getHighFractionFromValue(float val) const;
+    
+    //Find bounds that clip off a given percent of the area
+    float LowClipVal(float clip_fraction)const;
+    float HighClipVal(float clip_fraction)const;
+
+    int GetValIndex(float val)const;
+
+    float GetMean()const;
+    float GetStandardDev()const;
+
+    void Print()const;
+    void Dump(char *)const;
+    int  WritePlot(const char* fname)const;
+   virtual ~ossimHistogram();
+
+
+   virtual bool importHistogram(const ossimFilename& inputFile);
+   virtual bool importHistogram(istream& in);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+TYPE_DATA   
+};
+
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimIpt.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimIpt.cpp
new file mode 100644
index 0000000000..029003e566
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimIpt.cpp
@@ -0,0 +1,204 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+// 
+// Description:
+//
+// Contains class definitions for ipt.
+//
+//*******************************************************************
+//  $Id: ossimIpt.cpp,v 1.5 2005/12/16 14:25:11 dburken Exp $
+
+#include <iostream>
+#include <sstream>
+
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDpt3d.h>
+#include <base/data_types/ossimFpt.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimString.h>
+
+//*******************************************************************
+// Public constructor:
+//*******************************************************************
+ossimIpt::ossimIpt(const ossimDpt& pt)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      x = irint(pt.x);
+      y = irint(pt.y);
+   }
+}
+
+//*******************************************************************
+// Public constructor:
+//*******************************************************************
+ossimIpt::ossimIpt(const ossimFpt& pt)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      x = irint(pt.x);
+      y = irint(pt.y);
+   }
+}
+
+ossimIpt::ossimIpt(const ossimDpt3d &pt)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      x = irint(pt.x);
+      y = irint(pt.y);
+   }
+}
+//*******************************************************************
+// Public method:
+//*******************************************************************
+const ossimIpt& ossimIpt::operator=(const ossimDpt& pt)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      x = irint(pt.x);
+      y = irint(pt.y);
+   }
+   
+   return *this;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+const ossimIpt& ossimIpt::operator=(const ossimFpt& pt)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      x = irint(pt.x);
+      y = irint(pt.y);
+   }
+   
+   return *this;
+}
+
+std::ostream& ossimIpt::print(std::ostream& os) const
+{
+   os << "( ";
+
+   if (x != OSSIM_INT_NAN)
+   {
+      os << x;
+   }
+   else
+   {
+      os << "nan";
+   }
+   
+   os << ", ";
+
+   if (y != OSSIM_INT_NAN)
+   {
+      os << y;
+   }
+   else
+   {
+      os << "nan";
+   }
+
+   os << " )";
+
+   return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const ossimIpt& pt)
+{
+   return pt.print(os);
+}
+
+ossimString ossimIpt::toString() const
+{
+   std::ostringstream os;
+   print(os);
+   return ossimString(os.str());
+}
+
+std::istream& operator>>(std::istream& is, ossimIpt &pt)
+{
+   //---
+   // Expected input format:
+   // ( 30, -90 )
+   //   -x- -y-
+   //---
+
+   // Start with a nan point.
+   pt.makeNan();
+
+   // Check the stream.
+   if (!is) return is;
+
+   const int SZ = 64; // Handle real big number...
+   ossimString tempString;
+   char tempChars[SZ];
+   char c;
+
+   // Gobble the "(".
+   is >> tempString;
+   if (!is) return is;
+   
+   // Get the x.
+   is.get(tempChars, SZ, ',');
+   if (!is) return is;
+   tempChars[SZ-1] = '\0';
+   tempString = tempChars;
+   tempString.trim();
+   if (tempString == "nan")
+   {
+      pt.x = OSSIM_INT_NAN;
+   }
+   else
+   {
+      pt.x = tempString.toInt32();
+   }
+
+   // Eat the ",".
+   is.get(c);
+   
+   // Get the y.
+   is >> tempString;
+   tempString.trim();
+   if (tempString == "nan")
+   {
+      pt.y = OSSIM_INT_NAN;
+   }
+   else
+   {
+      pt.y = tempString.toInt32();
+   }
+
+   // Gobble the trailing ")".
+   is >> tempString;
+
+   // Finished
+   return is;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimIpt.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimIpt.h
new file mode 100644
index 0000000000..d9fc774d7b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimIpt.h
@@ -0,0 +1,142 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+//
+// Description:  
+//
+// Contains class declaration for ipt.
+// Used to represent an interger point containing an x and y data member.
+// 
+//*******************************************************************
+//  $Id: ossimIpt.h,v 1.13 2005/12/16 14:25:11 dburken Exp $
+
+#ifndef ossimIpt_HEADER
+#define ossimIpt_HEADER
+#include <iostream>
+#include <cmath>
+
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimDpt.h>
+
+// Forward class declarations.
+class OSSIMDLLEXPORT ossimFpt;
+class OSSIMDLLEXPORT ossimDpt3d;
+class OSSIMDLLEXPORT ossimString;
+
+class OSSIMDLLEXPORT ossimIpt
+{
+public:
+
+   ossimIpt() : x(0), y(0) {}
+
+   ossimIpt(ossim_int32 anX, ossim_int32 aY) : x(anX), y(aY) {}
+         
+   ossimIpt(const ossimIpt& pt) : x(pt.x), y(pt.y) {}
+
+   ossimIpt(const ossimDpt& pt);
+
+   ossimIpt(const ossimFpt& pt);
+
+   ossimIpt(const ossimDpt3d &pt);
+
+   const ossimIpt& operator=(const ossimIpt& pt);
+
+   const ossimIpt& operator=(const ossimDpt& pt);
+
+   const ossimIpt& operator=(const ossimFpt& pt);
+
+   bool operator==(const ossimIpt& pt) const
+      { return ( (x == pt.x) && (y == pt.y) ); } 
+
+   bool operator!=(const ossimIpt& pt) const
+      { return ( (x != pt.x) || (y != pt.y) ); }
+
+   void makeNan(){x = OSSIM_INT_NAN; y=OSSIM_INT_NAN;}
+   bool hasNans()const
+      {
+         return (ossimIsNan(x) || ossimIsNan(y));
+      }
+   bool isNan()const
+      {
+         return (ossimIsNan(x) && ossimIsNan(y));        
+      }
+
+   std::ostream& print(std::ostream& os) const;
+   
+   friend OSSIMDLLEXPORT std::ostream& operator<<(std::ostream& os,
+                                                  const ossimIpt& pt);
+
+   /**
+    * @return ossimString representing point.
+    *
+    * Format:  ( 30, -90 )
+    *            -x- -y-
+    */
+   ossimString toString() const;
+   
+   /**
+    * Method to input the formatted string of the "operator<<".
+    *
+    * Expected format:  ( 30, -90 )
+    *                     -x- -y-
+    * 
+    * This method starts by doing a "makeNan" on pt.  So if anything goes
+    * wrong with the stream or parsing pt could be all or partially nan.
+    *
+    * @param is Input stream istream to formatted text.
+    * @param pt osimIpt to be initialized from stream.
+    * @return istream pass in.
+    */
+   friend OSSIMDLLEXPORT std::istream& operator>>(std::istream& is,
+                                                  ossimIpt& pt);
+   
+   /*!
+    * METHOD: length()
+    * Returns the RSS of the components.
+    */
+   double length() const { return sqrt((double)x*x + (double)y*y); }
+   
+   //***
+   // OPERATORS: +, -, +=, -=
+   // Point add/subtract with other point:
+   //***
+   ossimIpt operator+(const ossimIpt& p) const
+      { return ossimIpt(x+p.x, y+p.y); }
+   ossimIpt operator-(const ossimIpt& p) const
+      { return ossimIpt(x-p.x, y-p.y); }
+   const ossimIpt& operator+=(const ossimIpt& p)
+      { x += p.x; y += p.y; return *this; }
+   const ossimIpt& operator-=(const ossimIpt& p)
+      { x -= p.x; y -= p.y; return *this; }
+
+   //***
+   // OPERATORS: *, /
+   // Scale point components by scalar:
+   //***
+   ossimDpt operator*(const double& d) const
+      { return ossimDpt(d*x, d*y); }
+   ossimDpt operator/(const double& d) const
+      { return ossimDpt(x/d, y/d); }
+
+   //***
+   // Public data members:
+   //***
+   union {ossim_int32 x; ossim_int32 u; ossim_int32 samp;};
+   union {ossim_int32 y; ossim_int32 v; ossim_int32 line;};
+      
+};
+
+inline const ossimIpt& ossimIpt::operator=(const ossimIpt& pt)
+{
+   if (this != &pt)
+   {
+      x = pt.x;
+      y = pt.y;
+   }
+   
+   return *this;
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimIrect.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimIrect.cpp
new file mode 100644
index 0000000000..ac84de0d1a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimIrect.cpp
@@ -0,0 +1,451 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for ossimIrect.
+// 
+//*******************************************************************
+//  $Id: ossimIrect.cpp,v 1.32 2005/07/15 18:51:25 dburken Exp $
+
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+
+ossimIrect::ossimIrect(const ossimDrect& rect)
+   :
+      theUlCorner(rect.ul()),
+      theUrCorner(rect.ur()),
+      theLrCorner(rect.lr()),
+      theLlCorner(rect.ll()),
+      theOrientMode(rect.orientMode())
+{}
+
+ossimIrect::ossimIrect(const vector<ossimIpt>& points,
+                       ossimCoordSysOrientMode mode)
+   :
+      theOrientMode (mode)
+{
+   if(points.size())
+   {
+      unsigned long index;
+      ossim_int32 minx, miny;
+      ossim_int32 maxx, maxy;
+      
+      minx = points[0].x;
+      miny = points[0].y;
+      maxx = points[0].x;
+      maxy = points[0].y;
+            
+      // find the bounds
+      for(index = 1; index < points.size();index++)
+      {
+         minx = ossimMin(minx, points[index].x);
+         miny = ossimMin(miny, points[index].y);
+         maxx = ossimMax(maxx, points[index].x);
+         maxy = ossimMax(maxy, points[index].y);
+         
+      }
+      if(theOrientMode == OSSIM_LEFT_HANDED)
+      {
+         *this = ossimIrect(minx, miny, maxx, maxy, mode);
+      }
+      else
+      {
+         *this = ossimIrect(minx,maxy, maxx, miny, mode);
+      }
+   }
+   else
+   {
+      makeNan();
+   }
+}
+
+ossimIrect::ossimIrect(const ossimIpt& p1,
+                       const ossimIpt& p2,
+                       const ossimIpt& p3,
+                       const ossimIpt& p4,
+                       ossimCoordSysOrientMode mode)
+   :theOrientMode(mode)
+{
+   if(p1.hasNans()||p2.hasNans()||p3.hasNans()||p4.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      ossim_int32 minx, miny;
+      ossim_int32 maxx, maxy;
+      
+      minx = ossimMin( p1.x, ossimMin(p2.x, ossimMin(p3.x, p4.x)));
+      miny = ossimMin( p1.y, ossimMin(p2.y, ossimMin(p3.y, p4.y)));
+      maxx = ossimMax( p1.x, ossimMax(p2.x, ossimMax(p3.x, p4.x)));
+      maxy = ossimMax( p1.y, ossimMax(p2.y, ossimMax(p3.y, p4.y)));
+      
+      if(theOrientMode == OSSIM_LEFT_HANDED)
+      {
+         *this = ossimIrect(minx, miny, maxx, maxy, mode);
+      }
+      else
+      {
+         *this = ossimIrect(minx,maxy, maxx, miny, mode);
+      }
+   }
+}
+
+ossimIrect::~ossimIrect()
+{
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+bool ossimIrect::intersects(const ossimIrect& rect) const
+{
+   if(rect.hasNans() || hasNans())
+   {
+      return false;
+   }
+   if (theOrientMode != rect.theOrientMode)
+      return false;
+   
+   ossim_int32 ulx = MAX(rect.ul().x,ul().x);
+   ossim_int32 lrx = MIN(rect.lr().x,lr().x);
+   ossim_int32 uly, lry;
+   bool   rtn;
+   
+   if (theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      uly = MAX(rect.ul().y,ul().y);
+      lry = MIN(rect.lr().y,lr().y);
+      rtn = ((ulx <= lrx) && (uly <= lry));
+   }
+   else
+   {
+      uly = MIN(rect.ul().y,ul().y);
+      lry = MAX(rect.lr().y,lr().y);
+      rtn = ((ulx <= lrx) && (uly >= lry));
+   }
+      
+   return (rtn);
+}
+
+void ossimIrect::stretchToTileBoundary(const ossimIpt& tileWidthHeight)
+{
+   ossimIpt ul;
+   ossimIpt lr;
+
+   if(theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      ul.x = theUlCorner.x;
+      if( (theUlCorner.x % tileWidthHeight.x) != 0)
+      {
+         ul.x = ((long)(ul.x / tileWidthHeight.x))*tileWidthHeight.x;
+         if(ul.x > theUlCorner.x)
+         {
+            ul.x -= tileWidthHeight.x;
+         }
+      }
+      ul.y = theUlCorner.y;
+      if( (theUlCorner.y % tileWidthHeight.y) != 0)
+      {
+         ul.y = ((long)(ul.y / tileWidthHeight.y))*tileWidthHeight.y;
+         if(ul.y > theUlCorner.y)
+         {
+            ul.y -= tileWidthHeight.y;
+         }
+      }
+      ossim_int32 w = (theLrCorner.x - ul.x) + 1;
+      ossim_int32 h = (theLrCorner.y - ul.y) + 1;
+      
+      ossim_int32 nw = (w / tileWidthHeight.x)*tileWidthHeight.x;
+      ossim_int32 nh = (h / tileWidthHeight.y)*tileWidthHeight.y;
+      
+      if(w%tileWidthHeight.x)
+      {
+         nw += tileWidthHeight.x;
+      }
+      if(h%tileWidthHeight.y)
+      {
+         nh += tileWidthHeight.y;
+      }
+           
+      lr.x = ul.x + (nw-1);
+      lr.y = ul.y + (nh-1);
+   }
+   else
+   {
+      ul.x = theUlCorner.x;
+      ul.y = theUlCorner.y;
+      if( (theUlCorner.x%tileWidthHeight.x)!= 0)
+      {
+         ul.x = ((long)(ul.x/ tileWidthHeight.x))*tileWidthHeight.x;
+         if(ul.x > theUlCorner.x)
+         {
+            ul.x -= tileWidthHeight.x;
+         }
+      }
+      if( (theUlCorner.y%tileWidthHeight.y)!=0 )
+      {
+         ul.y = ((long)(ul.y / tileWidthHeight.y))*tileWidthHeight.y;
+         if(ul.y < theUlCorner.y)
+         {
+            ul.y += tileWidthHeight.y;
+         }
+      }
+      ossim_int32 w = ossimAbs(theLrCorner.x - ul.x) + 1;
+      ossim_int32 h = ossimAbs(theLrCorner.y - ul.y) + 1;
+
+      ossim_int32 nw = (w / tileWidthHeight.x)*tileWidthHeight.x;
+      ossim_int32 nh = (h / tileWidthHeight.y)*tileWidthHeight.y;
+      
+      if(w%tileWidthHeight.x)
+      {
+         nw += tileWidthHeight.x;
+      }
+      if(h%tileWidthHeight.y)
+      {
+         nh += tileWidthHeight.y;
+      }
+           
+      lr.x = ul.x + (nw-1);
+      lr.y = ul.y - (nh-1);
+  }
+
+   *this = ossimIrect(ul, lr, theOrientMode);
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+bool ossimIrect::completely_within(const ossimIrect& rect) const
+{
+   if(rect.hasNans() || hasNans())
+   {
+      return false;
+   }
+   
+   if (theOrientMode != rect.theOrientMode)
+      return false;
+   
+   /*  --------------
+       |     1      |
+       | ---------- |
+       | |        | |
+       | |        | |
+       | |   2    | |
+       | |        | |
+       | |        | |
+       | ---------- |
+       |            |
+       --------------  */
+
+   bool rtn = true;
+   
+   if (theUlCorner.x < rect.ul().x)
+      rtn = false;
+   
+   else if (theLrCorner.x > rect.lr().x)
+      rtn = false;
+   
+   else if (theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      if (theUlCorner.y < rect.ul().y)
+         rtn = false;
+   
+      else if (theLrCorner.y > rect.lr().y)
+         rtn = false;
+   }
+   
+   else
+   {
+      if (theUlCorner.y > rect.ul().y)
+         rtn = false;
+   
+      else if (theLrCorner.y < rect.lr().y)
+         rtn = false;
+   }
+
+   return rtn;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+void ossimIrect::print(std::ostream& os) const
+{
+   os << theUlCorner << theLrCorner;
+}
+
+//*******************************************************************
+// friend function: operator<<
+//*******************************************************************
+ostream& operator<<(std::ostream& os, const ossimIrect& rect)
+{
+   rect.print(os);
+
+   return os;
+}
+
+//*******************************************************************
+//  Method: ossimIrect::clipToRect
+//*******************************************************************
+ossimIrect ossimIrect::clipToRect(const ossimIrect& rect)const
+{   
+   if (theOrientMode != rect.theOrientMode)
+      return (*this);
+
+   int x0 = MAX(rect.ul().x, ul().x);
+   int x1 = MIN(rect.lr().x, lr().x);
+   int y0, y1;
+
+   if(!this->intersects(rect))
+   {
+      return ossimIrect(OSSIM_INT_NAN,
+                        OSSIM_INT_NAN,
+                        OSSIM_INT_NAN,
+                        OSSIM_INT_NAN);
+                        
+   }
+   if (theOrientMode == OSSIM_LEFT_HANDED)
+   {
+      y0 = MAX(rect.ul().y, ul().y);
+      y1 = MIN(rect.lr().y, lr().y);
+
+      if( (x1 < x0) || (y1 < y0) )
+         return ossimIrect(ossimIpt(0,0), ossimIpt(0,0), theOrientMode);
+      else
+         return ossimIrect(x0, y0, x1, y1, theOrientMode);
+   }
+   else
+   {
+      y1 = MIN(rect.ul().y,ul().y);
+      y0 = MAX(rect.lr().y,lr().y);
+
+      if((x1 < x0) || (y1 < y0))
+         return ossimIrect(ossimIpt(0,0), ossimIpt(0,0), theOrientMode);
+      else
+         return ossimIrect(x0, y1, x1, y0, theOrientMode);
+   }
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::operator=(const ossimDrect& rect)
+//*******************************************************************
+const ossimIrect& ossimIrect::operator=(const ossimDrect& rect)
+{
+   theUlCorner   = rect.ul();
+   theUrCorner   = rect.ur();
+   theLrCorner   = rect.lr();
+   theLlCorner   = rect.ll();
+   theOrientMode = rect.orientMode();
+   
+   return *this;
+}
+
+bool ossimIrect::saveState(ossimKeywordlist& kwl,
+                           const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           "ossimIrect",
+           true);
+   
+   if(hasNans())
+   {
+      kwl.add(prefix,
+              "ul_x",
+              "nan",
+              true);
+      kwl.add(prefix,
+              "ul_y",
+              "nan",
+              true);
+      kwl.add(prefix,
+              "lr_x",
+              "nan",
+              true);
+      kwl.add(prefix,
+              "lr_y",
+              "nan",
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              "ul_x",
+              theUlCorner.x,
+              true);
+      kwl.add(prefix,
+              "ul_y",
+              theUlCorner.y,
+              true);
+      kwl.add(prefix,
+              "lr_x",
+              theLrCorner.x,
+              true);
+      kwl.add(prefix,
+              "lr_y",
+              theLrCorner.y,
+              true);
+   }
+
+   return true;
+}
+
+bool ossimIrect::loadState(const ossimKeywordlist& kwl,
+                           const char* prefix)
+{
+   const char* ulx = kwl.find(prefix, "ul_x");
+   const char* uly = kwl.find(prefix, "ul_y");
+   const char* lrx = kwl.find(prefix, "lr_x");
+   const char* lry = kwl.find(prefix, "lr_y");
+
+   if(ulx&&uly&&lrx&&lry)
+   {
+      if( (ossimString(ulx).trim().upcase() == "NAN") ||
+          (ossimString(uly).trim().upcase() == "NAN") ||
+          (ossimString(lrx).trim().upcase() == "NAN") ||
+          (ossimString(lry).trim().upcase() == "NAN"))
+      {
+         makeNan();
+      }
+      else
+      {
+         *this = ossimIrect(ossimString(ulx).toLong(),
+                            ossimString(uly).toLong(),
+                            ossimString(lrx).toLong(),
+                            ossimString(lry).toLong());
+      }
+   }
+   else
+   {
+      makeNan();
+      
+      return false;
+   }
+   
+   return true;
+}
+
+void ossimIrect::getCenter(ossimDpt& center_point) const
+{
+   if (hasNans())
+   {
+      center_point.makeNan();
+      return;
+   }
+
+   double d = (theUlCorner.x + theUrCorner.x + theLrCorner.x + theLlCorner.x);
+   center_point.x = d / 4.0;
+
+   d = (theUlCorner.y + theUrCorner.y + theLrCorner.y + theLlCorner.y);
+   center_point.y = d / 4.0;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimIrect.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimIrect.h
new file mode 100644
index 0000000000..d8a0667199
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimIrect.h
@@ -0,0 +1,684 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimIrect.
+// Container class for four integer points representing a rectangle.
+//
+//*******************************************************************
+//  $Id: ossimIrect.h,v 1.26 2005/12/16 14:26:21 dburken Exp $
+
+#ifndef ossimIrect_HEADER
+#define ossimIrect_HEADER
+#include <iostream>
+#include <vector>
+
+#include <base/data_types/ossimIpt.h>
+#include <base/common/ossimCommon.h>
+
+//***
+// NOTE:  A word on corner points...
+//
+// There is the concept of "pixel is area" and "pixel is point".
+// - Pixel is area means the (x,y) pixel coordinate refers to the upper left
+//   corner of the pixel, NOT the center of the pixel.
+// - Pixel is point means the (x,y) pixel coordinate refers to the center
+//   of the pixel, NOT the upper left corner.
+//
+// For the uniformity purposes, all pixel points  should be in the
+// "pixel is point" form; therefore, the (x,y) point should represent the
+// CENTER of the pixel.
+//***
+
+
+//***
+// Forward class declarations.
+//***
+class OSSIMDLLEXPORT ossimDrect;
+class OSSIMDLLEXPORT ossimKeywordlist;
+
+//*******************************************************************
+// CLASS:  ossimIrect
+//*******************************************************************
+
+class OSSIMDLLEXPORT ossimIrect
+{
+public:
+   enum
+   {
+      UPPER_LEFT  = 1,
+      LOWER_LEFT  = 2,
+      LOWER_RIGHT = 4,
+      UPPER_RIGHT = 8
+   };
+
+   ossimIrect()
+      :
+         theUlCorner(0, 0),
+         theUrCorner(0, 0),
+         theLrCorner(0, 0),
+         theLlCorner(0, 0),
+         theOrientMode(OSSIM_LEFT_HANDED)
+      {}
+
+   ossimIrect(ossimIpt ul_corner,
+              ossimIpt lr_corner,
+              ossimCoordSysOrientMode mode=OSSIM_LEFT_HANDED)
+      :
+         theUlCorner(ul_corner),
+         theUrCorner(lr_corner.x, ul_corner.y),
+         theLrCorner(lr_corner),
+         theLlCorner(ul_corner.x, lr_corner.y),
+         theOrientMode(mode)
+      {}
+
+   ossimIrect(ossim_int32 ul_corner_x,
+              ossim_int32 ul_corner_y,
+              ossim_int32 lr_corner_x,
+              ossim_int32 lr_corner_y,
+              ossimCoordSysOrientMode mode=OSSIM_LEFT_HANDED)
+      :
+         theUlCorner(ul_corner_x, ul_corner_y),
+         theUrCorner(lr_corner_x, ul_corner_y),
+         theLrCorner(lr_corner_x, lr_corner_y),
+         theLlCorner(ul_corner_x, lr_corner_y),
+         theOrientMode(mode)
+      {}
+   
+   ossimIrect(const ossimIrect& rect)
+      :
+         theUlCorner(rect.ul()),
+         theUrCorner(rect.ur()),
+         theLrCorner(rect.lr()),
+         theLlCorner(rect.ll()),
+         theOrientMode(rect.orientMode())
+      {}
+
+   ossimIrect(const ossimDrect& rect);
+
+   /*!
+    * Must compute a bounding rect given these image
+    * points.
+    */
+   ossimIrect(const std::vector<ossimIpt>& points,
+              ossimCoordSysOrientMode mode=OSSIM_LEFT_HANDED);
+
+   ossimIrect(const ossimIpt& p1,
+              const ossimIpt& p2,
+              const ossimIpt& p3,
+              const ossimIpt& p4,
+              ossimCoordSysOrientMode=OSSIM_LEFT_HANDED);
+
+   /** destructor */
+   ~ossimIrect();
+   
+   const ossimIrect& operator=  (const ossimIrect& rect);
+   const ossimIrect& operator=  (const ossimDrect& rect);
+   bool         operator!= (const ossimIrect& rect) const;
+   bool         operator== (const ossimIrect& rect) const;
+
+   friend ossimIrect operator*(double scalar, const ossimIrect& rect)
+      {
+         return ossimIrect((int)floor(rect.theUlCorner.x*scalar),
+                           (int)floor(rect.theUlCorner.y*scalar),
+                           (int)ceil(rect.theUlCorner.x*scalar+rect.width()*scalar-1),
+                           (int)ceil(rect.theUlCorner.y*scalar+rect.height()*scalar-1),
+                           rect.theOrientMode);
+      }
+   
+   const ossimIrect& operator *=(double scalar)
+      {
+         *this = ossimIrect((int)floor(theUlCorner.x*scalar),
+                            (int)floor(theUlCorner.y*scalar),
+                            (int)ceil(theUlCorner.x*scalar+width()*scalar-1),
+                            (int)ceil(theUlCorner.y*scalar+height()*scalar-1),
+                            theOrientMode);
+         return *this;
+      }
+   
+   ossimIrect operator *(double scalar)const
+      {
+         return ossimIrect((int)floor(theUlCorner.x*scalar),
+                           (int)floor(theUlCorner.y*scalar),
+                           (int)ceil(theUlCorner.x*scalar+width()*scalar-1),
+                           (int)ceil(theUlCorner.y*scalar+height()*scalar-1),
+                           theOrientMode);
+      }
+   const ossimIrect& operator *=(const ossimDpt& scalar)
+      {
+         *this = ossimIrect((int)floor(theUlCorner.x*scalar.x),
+                            (int)floor(theUlCorner.y*scalar.y),
+                            (int)ceil(theUlCorner.x*scalar.x+width()*scalar.x-1),
+                            (int)ceil(theUlCorner.y*scalar.y+height()*scalar.y-1),
+                            theOrientMode);
+         return *this;
+      }
+   
+   ossimIrect operator *(const ossimDpt& scalar)const
+      {
+         return  ossimIrect((int)floor(theUlCorner.x*scalar.x),
+                            (int)floor(theUlCorner.y*scalar.y),
+                            (int)ceil(theUlCorner.x*scalar.x+width()*scalar.x-1),
+                            (int)ceil(theUlCorner.y*scalar.y+height()*scalar.y-1),
+                            theOrientMode);
+      }
+   const ossimIrect& operator +=(const ossimIpt& shift)
+      {
+         *this = ossimIrect(theUlCorner.x+shift.x,
+                            theUlCorner.y+shift.y,
+                            theLrCorner.x+shift.x,
+                            theLrCorner.y+shift.y,
+                            theOrientMode);
+         return *this;
+      }
+   
+   const ossimIrect& operator -=(const ossimIpt& shift)
+      {
+         *this = ossimIrect(theUlCorner.x-shift.x,
+                            theUlCorner.y-shift.y,
+                            theLrCorner.x-shift.x,
+                            theLrCorner.y-shift.y,
+                            theOrientMode);
+         return *this;
+      }
+   
+   ossimIrect operator +(const ossimIpt& shift)const
+      {
+         return ossimIrect(theUlCorner.x+shift.x,
+                           theUlCorner.y+shift.y,
+                           theLrCorner.x+shift.x,
+                           theLrCorner.y+shift.y,
+                           theOrientMode);
+      }
+
+   ossimIrect operator -(const ossimIpt& shift)const
+      {
+         return ossimIrect(theUlCorner.x-shift.x,
+                           theUlCorner.y-shift.y,
+                           theLrCorner.x-shift.x,
+                           theLrCorner.y-shift.y,
+                           theOrientMode);
+      }
+
+
+   const ossimIrect& operator +=(const ossimDpt& shift)
+      {
+         *this = ossimIrect((int)floor(theUlCorner.x+shift.x),
+                            (int)floor(theUlCorner.y+shift.y),
+                            (int)ceil(theUlCorner.x+shift.x+width()-1),
+                            (int)ceil(theUlCorner.y+shift.y+height()-1),
+                            theOrientMode);
+         return *this;
+      }
+   
+   const ossimIrect& operator -=(const ossimDpt& shift)
+      {
+         *this = ossimIrect((int)floor(theUlCorner.x-shift.x),
+                            (int)floor(theUlCorner.y-shift.y),
+                            (int)ceil(theUlCorner.x-shift.x+width()-1),
+                            (int)ceil(theUlCorner.y-shift.y+height()-1),
+                            theOrientMode);
+         return *this;
+      }
+   
+   ossimIrect operator +(const ossimDpt& shift)const
+      {
+         return ossimIrect((int)floor(theUlCorner.x+shift.x),
+                           (int)floor(theUlCorner.y+shift.y),
+                           (int)ceil(theUlCorner.x+shift.x+width()-1),
+                           (int)ceil(theUlCorner.y+shift.y+height()-1),
+                           theOrientMode);
+      }
+
+   ossimIrect operator -(const ossimDpt& shift)const
+      {
+         return ossimIrect((int)floor(theUlCorner.x-shift.x),
+                           (int)floor(theUlCorner.y-shift.y),
+                           (int)ceil(theUlCorner.x-shift.x+width()-1),
+                           (int)ceil(theUlCorner.y-shift.y+height()-1),
+                           theOrientMode);
+         return *this;
+      }
+
+   
+   ossimIpt ul() const { return theUlCorner; }
+   ossimIpt ur() const { return theUrCorner; }
+   ossimIpt lr() const { return theLrCorner; }
+   ossimIpt ll() const { return theLlCorner; }
+
+   void getBounds(ossim_int32& minx, ossim_int32& miny,
+                  ossim_int32& maxx, ossim_int32& maxy)const
+      {
+         minx = theUlCorner.x;
+         maxx = theUrCorner.x;
+         if(theOrientMode == OSSIM_LEFT_HANDED)
+         {
+            miny = theUlCorner.y;
+            maxy = theUrCorner.y;
+         }
+         else
+         {
+            maxy = theUlCorner.y;
+            miny = theUrCorner.y;
+         }
+      }
+
+   /*!
+    * Initializes center_point with center of the rectangle.
+    * Makes center_point nan if this rectangle has nans.
+    */
+   void getCenter(ossimDpt& center_point) const;
+   
+   void makeNan()
+      {
+         theUlCorner.makeNan();
+         theLlCorner.makeNan();
+         theLrCorner.makeNan();
+         theUrCorner.makeNan();
+      }
+   
+   bool hasNans()const{ return (theUlCorner.hasNans() ||
+                                theLlCorner.hasNans() ||
+                                theLrCorner.hasNans() ||
+                                theUrCorner.hasNans());}
+   
+   bool isNan()const{ return (theUlCorner.hasNans() &&
+                              theLlCorner.hasNans() &&
+                              theLrCorner.hasNans() &&
+                              theUrCorner.hasNans());}
+
+   //***
+   // This class supports both left and right-handed coordinate systems. For
+   // both, the positive x-axis extends to the "right".
+   //***
+   ossimCoordSysOrientMode orientMode() const { return theOrientMode; }
+   void setOrientMode(ossimCoordSysOrientMode mode) { theOrientMode = mode; }
+
+   void stretchToTileBoundary(const ossimIpt& tileWidthHeight);
+
+   ossim_uint32 area()const
+      {
+         return width()*height();
+      }
+
+   /*!
+    * Sets the upper left corner to "pt".  Adjusts the remaining corners
+    * accordingly.
+    */
+   void set_ul(const ossimIpt& pt);
+
+   /*!
+    * Sets the upper right corner to "pt".  Adjusts the remaining corners
+    * accordingly.
+    */
+   void set_ur(const ossimIpt& pt);
+
+   /*!
+    * Sets the lower right corner to "pt".  Adjusts the remaining corners
+    * accordingly.
+    */
+   void set_lr(const ossimIpt& pt);
+
+   /*!
+    * Sets the lower left corner to "pt".  Adjusts the remaining corners
+    * accordingly.
+    */
+   void set_ll(const ossimIpt& pt);
+
+   /*!
+    * Sets the upper left x.  Adjusts the remaining corners accordingly.
+    */
+   void set_ulx(ossim_int32 x);
+
+   /*!
+    * Sets the upper left y.  Adjusts the remaining corners accordingly.
+    */
+   void set_uly(ossim_int32 y);
+
+   /*!
+    * Sets the upper right x.  Adjusts the remaining corners accordingly.
+    */
+   void set_urx(ossim_int32 x);
+
+   /*!
+    * Sets the upper right y.  Adjusts the remaining corners accordingly.
+    */
+   void set_ury(ossim_int32 y);
+
+   /*!
+    * Sets the lower right x.  Adjusts the remaining corners accordingly.
+    */
+   void set_lrx(ossim_int32 x);
+
+   /*!
+    * Sets the lower right y.  Adjusts the remaining corners accordingly.
+    */
+   void set_lry(ossim_int32 y);
+
+   /*!
+    * Sets the lower left x.  Adjusts the remaining corners accordingly.
+    */
+   void set_llx(ossim_int32 x);
+
+   /*!
+    * Sets the lower left y.  Adjusts the remaining corners accordingly.
+    */
+   void set_lly(ossim_int32 y);
+
+   /*!
+    * Returns true if "pt" falls within rectangle.  Fall on an edge is also
+    * considered to be within.
+    */
+   bool pointWithin(const ossimIpt& pt) const;
+
+   /*!
+    * Returns true if any portion of an input rectangle "rect" intersects
+    * "this" rectangle.  
+    */
+   bool intersects(const ossimIrect& rect) const;
+
+   /*!
+    * Returns true if "this" rectangle is contained completely within
+    * the input rectangular "rect".
+    */
+   bool completely_within(const ossimIrect& rect) const;
+
+   /*!
+    * Returns the height of the rectangle.
+    */
+   ossim_uint32 height() const
+   {
+      return static_cast<ossim_uint32>(ossimAbs(theLlCorner.y -
+                                                theUlCorner.y) + 1);
+   }
+
+   /*!
+    * Returns the width of a rectangle.
+    */
+   ossim_uint32 width()  const
+   {
+      return static_cast<ossim_uint32>(ossimAbs(theLrCorner.x -
+                                                theLlCorner.x) + 1);
+   }
+ 
+   ossimIrect clipToRect(const ossimIrect& rect)const;
+
+   inline ossimIpt midPoint()const;
+
+   void print(std::ostream& os) const;
+
+   ossimIrect combine(const ossimIrect& rect)const;
+   
+   friend OSSIMDLLEXPORT std::ostream& operator<<(std::ostream& os,
+                                                  const ossimIrect& rect);
+
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix=0)const;
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix=0);
+private:
+
+   //***
+   // Private data members representing the rectangle corners.
+   //***
+   ossimIpt theUlCorner;
+   ossimIpt theUrCorner;
+   ossimIpt theLrCorner;
+   ossimIpt theLlCorner;
+
+   ossimCoordSysOrientMode  theOrientMode;
+};
+
+//*******************************************************************
+// Inline Method: ossimIrect::operator=(ossimIrect)
+//*******************************************************************
+inline const ossimIrect& ossimIrect::operator=(const ossimIrect& rect)
+{
+   if (this != &rect)
+   {
+      theUlCorner   = rect.ul();
+      theUrCorner   = rect.ur();
+      theLrCorner   = rect.lr();
+      theLlCorner   = rect.ll();
+      theOrientMode = rect.theOrientMode;
+
+      if(rect.hasNans())
+      {
+         makeNan();
+      }
+   }
+
+   return *this;
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::operator!=
+//*******************************************************************
+inline bool ossimIrect::operator!=(const ossimIrect& rect) const
+{
+   return ( (theUlCorner   != rect.ul()) ||
+            (theUrCorner   != rect.ur()) ||
+            (theLrCorner   != rect.lr()) ||
+            (theLlCorner   != rect.ll()) ||
+            (theOrientMode != rect.theOrientMode));
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::operator==
+//*******************************************************************
+inline bool ossimIrect::operator==(const ossimIrect& rect) const
+{
+   return ( (theUlCorner   == rect.ul()) &&
+            (theUrCorner   == rect.ur()) &&
+            (theLrCorner   == rect.lr()) &&
+            (theLlCorner   == rect.ll()) &&
+            (theOrientMode == rect.theOrientMode) );
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_ul
+//*******************************************************************
+inline void ossimIrect::set_ul(const ossimIpt& pt)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      theUlCorner   = pt;
+      theUrCorner.y = pt.y;
+      theLlCorner.x = pt.x;
+   }
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_ur
+//*******************************************************************
+inline void ossimIrect::set_ur(const ossimIpt& pt)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      theUrCorner   = pt;
+      theUlCorner.y = pt.y;
+      theLrCorner.x = pt.x;
+   }
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_lr
+//*******************************************************************
+inline void ossimIrect::set_lr(const ossimIpt& pt)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      theLrCorner   = pt;
+      theUrCorner.x = pt.x;
+      theLlCorner.y = pt.y;
+   }
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_ll
+//*******************************************************************
+inline void ossimIrect::set_ll(const ossimIpt& pt)
+{
+   if(pt.hasNans())
+   {
+      makeNan();
+   }
+   else
+   {
+      theLlCorner   = pt;
+      theUlCorner.x = pt.x;
+      theLrCorner.y = pt.y;
+   }
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_ulx
+//*******************************************************************
+inline void ossimIrect::set_ulx(ossim_int32 x)
+{
+   theUlCorner.x = x;
+   theLlCorner.x = x;
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_uly
+//*******************************************************************
+inline void ossimIrect::set_uly(ossim_int32 y)
+{
+   theUlCorner.y = y;
+   theUrCorner.y = y;
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_urx
+//*******************************************************************
+inline void ossimIrect::set_urx(ossim_int32 x)
+{
+   theUrCorner.x = x;
+   theLrCorner.x = x;
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_ury
+//*******************************************************************
+inline void ossimIrect::set_ury(ossim_int32 y)
+{
+   theUrCorner.y = y;
+   theUlCorner.y = y;
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_lrx
+//*******************************************************************
+inline void ossimIrect::set_lrx(ossim_int32 x)
+{
+   theLrCorner.x = x;
+   theUrCorner.x = x;
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_lry
+//*******************************************************************
+inline void ossimIrect::set_lry(ossim_int32 y)
+{
+   theLrCorner.y = y;
+   theLlCorner.y = y;
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_llx
+//*******************************************************************
+inline void ossimIrect::set_llx(ossim_int32 x)
+{
+   theLlCorner.x = x;
+   theUlCorner.x = x;
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::set_lly
+//*******************************************************************
+inline void ossimIrect::set_lly(ossim_int32 y)
+{
+   theLlCorner.y = y;
+   theLrCorner.y = y;
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::pointWithin
+//*******************************************************************
+inline bool ossimIrect::pointWithin(const ossimIpt& pt) const
+{
+   if(hasNans())
+   {
+      return false;
+   }
+   if (theOrientMode == OSSIM_LEFT_HANDED)
+      return ((pt.x >= ul().x) &&
+              (pt.x <= ur().x) &&
+              (pt.y >= ul().y) &&
+              (pt.y <= ll().y));
+   else
+      return ((pt.x >= ul().x) &&
+              (pt.x <= ur().x) &&
+              (pt.y <= ul().y) &&
+              (pt.y >= ll().y));
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::midPoint
+//*******************************************************************
+inline ossimIpt ossimIrect::midPoint()const
+{
+   if(hasNans())
+   {
+      return ossimIpt(OSSIM_INT_NAN, OSSIM_INT_NAN);
+   }
+   double x = (ul().x + ur().x + ll().x + lr().x) * 0.25;
+   double y = (ul().y + ur().y + ll().y + lr().y) * 0.25;
+   
+   return ossimIpt(static_cast<ossim_int32>(irint(x)),
+                   static_cast<ossim_int32>(irint(y)));
+}
+
+//*******************************************************************
+// Inline Method: ossimIrect::combine
+//*******************************************************************
+inline ossimIrect ossimIrect::combine(const ossimIrect& rect)const
+{
+   if(rect.hasNans() || hasNans())
+   {
+      ossimIrect result;
+
+      result.makeNan();
+
+      return result;
+   }
+   if (theOrientMode != rect.theOrientMode)
+      return(*this);
+   
+   int ulx = ((ul().x <= rect.ul().x)?ul().x:rect.ul().x);
+   int uly = ((ul().y <= rect.ul().y)?ul().y:rect.ul().y);
+   int lrx = ((lr().x >= rect.lr().x)?lr().x:rect.lr().x);
+   int lry = ((lr().y >= rect.lr().y)?lr().y:rect.lr().y);
+
+   return ossimIrect(ulx, uly, lrx, lry);
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimKeyword.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimKeyword.cpp
new file mode 100644
index 0000000000..42520fcd32
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimKeyword.cpp
@@ -0,0 +1,136 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for Keyword.h
+//*******************************************************************
+//  $Id: ossimKeyword.cpp,v 1.3 2005/10/17 18:37:16 gpotts Exp $
+
+#include <base/data_types/ossimKeyword.h>
+
+ossimKeyword::ossimKeyword()
+   :
+      theKey(""),
+      theDesc(""),
+      theValue("")
+{}
+
+ossimKeyword::ossimKeyword(const char* key, const char* description)
+   :
+      theKey(key),
+      theDesc(description),
+      theValue("")
+{}
+
+ossimKeyword::ossimKeyword(const char* key,
+                           const char* description,
+                           const char* value)
+   :
+      theKey(key),
+      theDesc(description),
+      theValue(value)      
+{}
+
+ossimKeyword::ossimKeyword(const ossimKeyword& src)
+   :
+      theKey(src.key()),
+      theDesc(src.description()),
+      theValue(src.value())
+{}
+
+ossimKeyword::~ossimKeyword()
+{}
+
+ossimKeyword::operator const char*() const
+{
+   return theKey.c_str();
+}
+
+const char* ossimKeyword::key() const
+{
+   return theKey.c_str();
+}
+
+const char* ossimKeyword::description() const
+{
+   return theDesc.c_str();
+}
+
+const char* ossimKeyword::value() const
+{
+   return theValue.c_str();
+}
+
+ossimString ossimKeyword::keyString() const
+{
+   return theKey;
+}
+
+ossimString ossimKeyword::descriptionString() const
+{
+   return theDesc;
+}
+
+ossimString ossimKeyword::valueString() const
+{
+   return theValue;
+}
+
+void ossimKeyword::setValue(const char* val)
+{
+   theValue = val;
+}
+
+void ossimKeyword::setValue(const ossimString& val)
+{
+   theValue = val;
+}
+
+void ossimKeyword::setDescription(const char* desc)
+{
+   theDesc  = desc;
+}
+
+void ossimKeyword::setDescription(const ossimString& desc)
+{
+   theDesc  = desc;
+}
+   
+const ossimKeyword& ossimKeyword::operator=(const ossimKeyword& kw)
+{
+   if (this != &kw)
+   {
+      theKey = kw.key();
+      theDesc = kw.description();
+      theValue = kw.value();
+   }
+   
+   return *this;
+}
+
+std::ostream& operator<<(std::ostream& os, const ossimKeyword& kw)
+{
+   os << "\n key   = " << kw.key()
+      << "\n desc  = " << kw.description()
+      << "\n value = " << kw.value()
+      << std::endl;
+   return os;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimKeyword.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimKeyword.h
new file mode 100644
index 0000000000..1de3984add
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimKeyword.h
@@ -0,0 +1,64 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero
+// Description: This class defines a keyword.
+//              NOTE:  The keywordlist class cleans up all allocated
+//                     memory from instantiating a keyword.
+// 
+//********************************************************************
+// $Id: ossimKeyword.h,v 1.5 2005/10/17 18:37:16 gpotts Exp $
+#ifndef ossimKeyword_HEADER
+#define ossimKeyword_HEADER
+
+#include <base/data_types/ossimString.h>
+
+class OSSIMDLLEXPORT ossimKeyword
+{
+public:
+   ossimKeyword();
+   ossimKeyword(const char* key, const char* description);
+   ossimKeyword(const char* key, const char* description, const char* value);
+   ossimKeyword(const ossimKeyword& src);
+   ~ossimKeyword();
+
+   const ossimKeyword& operator=(const ossimKeyword& kw);
+   operator const char*() const;
+
+   const char* key()               const;
+   const char* description()       const;
+   const char* value()             const;
+   ossimString keyString()         const;
+   ossimString descriptionString() const;
+   ossimString valueString()       const;
+   
+   void setValue(const char* val);
+   void setValue(const ossimString& val);
+   void setDescription(const char* desc);
+   void setDescription(const ossimString& desc);
+   
+
+   friend OSSIM_DLL std::ostream& operator<<(std::ostream& os, const ossimKeyword& kw);
+
+private:
+   ossimString theKey;
+   ossimString theDesc;
+   ossimString theValue;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimKeywordlist.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimKeywordlist.cpp
new file mode 100644
index 0000000000..ef1f841d02
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimKeywordlist.cpp
@@ -0,0 +1,1244 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Description: This class provides capabilities for keywordlists.
+//
+//********************************************************************
+// $Id: ossimKeywordlist.cpp,v 1.62 2005/10/17 19:16:33 gpotts Exp $
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+
+#include <base/data_types/ossimRegExp.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug("ossimKeywordlist:debug");
+static const ossim_int32 MAX_LINE_LENGTH = 256;
+static const char NULL_KEY_NOTICE[]
+   = "ossimKeywordlist Notice:  Null key passed to method.";
+
+
+#ifdef OSSIM_ID_ENABLED
+static const bool TRACE = false;
+static const char OSSIM_ID[] = "$Id: ossimKeywordlist.cpp,v 1.62 2005/10/17 19:16:33 gpotts Exp $";
+#endif
+
+ossimKeywordlist::ossimKeywordlist(char delimiter)
+   :
+      theMap(),
+      theDelimiter(delimiter)
+{
+#ifdef OSSIM_ID_ENABLED
+   if (TRACE) ossimNotify(ossimNotifyLevel_DEBUG) << OSSIM_ID << endl;
+#endif
+}
+
+ossimKeywordlist::ossimKeywordlist(const char* file,
+                         char        delimiter,
+                         bool        ignoreBinaryChars)
+   :
+      theMap(),
+      theDelimiter(delimiter)
+{
+   ossimFilename in_file(file);
+
+   if (!parseFile(in_file, ignoreBinaryChars))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+}
+
+ossimKeywordlist::ossimKeywordlist(const ossimFilename& file,
+                         char            delimiter,
+                         bool            ignoreBinaryChars)
+   :
+      theMap(),
+      theDelimiter(delimiter)
+
+{
+   if (!parseFile(file, ignoreBinaryChars))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+}
+
+ossimKeywordlist::~ossimKeywordlist()
+{
+   theMap.clear();
+}
+
+bool ossimKeywordlist::addFile(const char* file)
+{
+   ossimFilename in_file(file);
+
+   return parseFile(in_file);
+}
+
+bool ossimKeywordlist::addFile(const ossimFilename& file)
+{
+   return parseFile(file);
+}
+
+void ossimKeywordlist::addList(const ossimKeywordlist &src, bool overwrite)
+{
+    KeywordMap::const_iterator i = src.theMap.begin();
+
+    while (i != src.theMap.end())
+    {
+        add( (*i).first, (*i).second, overwrite );
+        i++;
+    }
+}
+
+void ossimKeywordlist::add(const ossimKeywordlist& kwl,
+                           const char* prefix,
+                           bool stripPrefix)
+{
+   map<ossimString, ossimString>::const_iterator iter = kwl.theMap.begin();
+
+   ossimRegExp regExp;
+
+   regExp.compile(("^("+ossimString(prefix)+")").c_str());
+
+   while(iter != kwl.theMap.end())
+   {
+      ossimString newKey;
+
+      if(regExp.find( (*iter).first.c_str()))
+      {
+         newKey = (*iter).first;
+         if(stripPrefix)
+         {
+            newKey = newKey.substitute(prefix,
+                                       "");
+
+         }
+
+         add(newKey,
+             (*iter).second,
+            true);
+      }
+      ++iter;
+   }
+
+}
+
+void ossimKeywordlist::add(const char* prefix,
+                           const ossimKeywordlist& kwl,
+                           bool overwrite)
+{
+   map<ossimString, ossimString>::const_iterator iter = kwl.theMap.begin();
+
+   while(iter != kwl.theMap.end())
+   {
+      ossimString valueToAdd = (*iter).second;
+      ossimString newKey     = (*iter).first;
+
+      add(prefix,
+          newKey,
+          valueToAdd,
+          overwrite);
+      ++iter;
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           const char* value,
+                           bool        overwrite)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      ossimString v;
+      if (value) v = value;
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if (i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* prefix,
+                           const char* key,
+                           const char* value,
+                           bool        overwrite)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      ossimString v;
+      if (value) v = value;
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if(overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           char        value,
+                           bool        overwrite)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      char tmp[2];
+      tmp[0] = value;
+      tmp[1] = '\0';
+      ossimString v = tmp;
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if (i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* prefix,
+                           const char* key,
+                           char        value,
+                           bool        overwrite)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      char tmp[2];
+      tmp[0] = value;
+      tmp[1] = '\0';
+      ossimString v = tmp;
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if(overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           ossim_int16 value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* prefix,
+                           const char* key,
+                           ossim_int16 value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           ossim_uint16 value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* prefix,
+                           const char* key,
+                           ossim_uint16 value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           ossim_int32 value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char*  prefix,
+                           const char*  key,
+                           ossim_int32 value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           ossim_uint32 value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char*  prefix,
+                           const char*  key,
+                           ossim_uint32 value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           long value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* prefix,
+                           const char* key,
+                           long value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           unsigned long value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* prefix,
+                           const char* key,
+                           unsigned long value,
+                           bool overwrite)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      ossimString v = ossimString::toString(value);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           ossim_float32 value,
+                           bool overwrite,
+                           int precision,
+                           bool trimZeroFlag,
+                           bool scientific)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      ossimString v = ossimString::toString(value,
+                                            precision,
+                                            trimZeroFlag,
+                                            scientific);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* prefix,
+                           const char* key,
+                           ossim_float32 value,
+                           bool overwrite,
+                           int precision,
+                           bool trimZeroFlag,
+                           bool scientific)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      ossimString v = ossimString::toString(value,
+                                            precision,
+                                            trimZeroFlag,
+                                            scientific);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* key,
+                           ossim_float64 value,
+                           bool overwrite,
+                           int precision,
+                           bool trimZeroFlag,
+                           bool scientific)
+{
+   if (key)
+   {
+      ossimString k = key;
+
+      ossimString v = ossimString::toString(value,
+                                            precision,
+                                            trimZeroFlag,
+                                            scientific);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+void ossimKeywordlist::add(const char* prefix,
+                           const char* key,
+                           ossim_float64 value,
+                           bool overwrite,
+                           int precision,
+                           bool trimZeroFlag,
+                           bool scientific)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      ossimString v = ossimString::toString(value,
+                                            precision,
+                                            trimZeroFlag,
+                                            scientific);
+
+      KeywordMap::iterator i = getMapEntry(k);
+
+      if(i == theMap.end())
+      {
+         theMap.insert(std::make_pair(k, v));
+      }
+      else if (overwrite)
+      {
+         (*i).second = v;
+      }
+   }
+}
+
+bool ossimKeywordlist::write(const char* file) const
+{
+   ofstream filename(file);
+   if (!filename)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         <<"ossimKeywordlist::write, Error opening file:  "
+         << file << std::endl;
+      return false;
+   }
+
+   writeToStream(filename);
+
+   filename.close();
+
+   return true;
+}
+
+ossimString ossimKeywordlist::toString()const
+{
+   KeywordMap::const_iterator i;
+   ossimString result;
+
+   for(i = theMap.begin(); i != theMap.end(); i++)
+   {
+      result += (*i).first;
+      result += delimiter_str().c_str();
+      result += " ";
+      result += (*i).second;
+      result += '\n';
+   }
+
+   return result;
+}
+
+void ossimKeywordlist::toString(ossimString& result)const
+{
+   KeywordMap::const_iterator i;
+
+   for(i = theMap.begin(); i != theMap.end(); i++)
+   {
+      result += (*i).first;
+      result += delimiter_str().c_str();
+      result += " ";
+      result += (*i).second;
+      result += '\n';
+   }
+}
+
+void ossimKeywordlist::writeToStream(ostream& out) const
+{
+   KeywordMap::const_iterator i;
+
+   for(i = theMap.begin(); i != theMap.end(); ++i)
+   {
+      out << (*i).first  << delimiter_str().c_str() << "  "
+          << (*i).second << endl;
+   }
+}
+
+
+const char* ossimKeywordlist::find(const char* key) const
+{
+   const char* result = NULL;
+
+   if (key)
+   {
+      ossimString k = key;
+
+      KeywordMap::const_iterator i = theMap.find(k.c_str());
+
+      if (i != theMap.end())
+      {
+         result = (*i).second.c_str();
+      }
+   }
+
+   return result;
+}
+
+const char* ossimKeywordlist::find(const char* prefix,
+                              const char* key) const
+{
+   const char* result = NULL;
+
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+      KeywordMap::const_iterator i = theMap.find(k.c_str());
+      if (i != theMap.end())
+      {
+         result = (*i).second.c_str();
+      }
+   }
+
+   return result;
+}
+
+
+void ossimKeywordlist::remove(const char * key)
+{
+   ossimString k = key?key:"";
+
+   KeywordMap::iterator i = theMap.find(k);
+
+   if(i != theMap.end())
+   {
+      theMap.erase(i);
+   }
+}
+
+void ossimKeywordlist::remove(const char* prefix, const char * key)
+{
+   if (key)
+   {
+      ossimString k;
+      if (prefix) k = prefix;
+      k += key;
+
+      KeywordMap::iterator i = theMap.find(k);
+
+      if(i != theMap.end())
+      {
+         theMap.erase(i);
+      }
+   }
+}
+
+ossim_uint32 ossimKeywordlist::numberOf(const char* str) const
+{
+   ossim_uint32 count = 0;
+
+   if (str)
+   {
+      KeywordMap::const_iterator i = theMap.begin();
+
+      while (i != theMap.end())
+      {
+         if ( (*i).first.contains(str) )
+         {
+            ++count;
+         }
+         ++i;
+      }
+   }
+
+   return count;
+}
+
+ossim_uint32 ossimKeywordlist::numberOf(const char* prefix,
+                                       const char* key) const
+{
+   if (!prefix && key)  // Must have key, sometimes no prefix.
+   {
+      return numberOf(key);
+   }
+
+   ossim_uint32 count = 0;
+
+   if (prefix && key)
+   {
+      KeywordMap::const_iterator i = theMap.begin();
+
+      while (i != theMap.end())
+      {
+         if ( (*i).first.contains(prefix) && (*i).first.contains(key))
+         {
+            ++count;
+         }
+         ++i;
+      }
+   }
+
+   return count;
+}
+
+void ossimKeywordlist::clear()
+{
+   theMap.clear();
+}
+
+ossimKeywordlist::KeywordMap::iterator
+ossimKeywordlist::getMapEntry(const char* key)
+{
+   if (key)
+   {
+      ossimString k = key;
+      return theMap.find(k);
+   }
+   else
+   {
+      return theMap.end();
+   }
+}
+
+ossimKeywordlist::KeywordMap::iterator
+ossimKeywordlist::getMapEntry(const ossimString& key)
+{
+   return theMap.find(key);
+}
+
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimKeywordlist::parseFile(const ossimFilename& file,
+                                 bool ignoreBinaryChars)
+{
+   std::ifstream is;
+   is.open(file.c_str(), ios::in | ios::binary);
+
+   if (!is)
+   {
+      if(traceDebug())
+      {
+         // report all errors that aren't existance problems.
+         // we want to know about things like permissions, too many open files, etc.
+         ossimNotify(ossimNotifyLevel_DEBUG) << "Error opening file: " << file.c_str() 
+                                             << std::endl;
+      }
+      return false;
+   }
+
+   bool result = parseStream(is, ignoreBinaryChars);
+
+   is.close();
+
+   return result;
+}
+
+bool ossimKeywordlist::parseStream(istream &is,
+                                   bool ignoreBinaryChars)
+{
+   ossimString line;
+
+   while(!is.eof() && is.good())
+   {
+      line  = "";
+      // get a line and parse it
+      char c = is.get();
+      while((c != '\n') &&!is.eof()&&!is.bad())
+      {
+         if (c >= 0x20)
+         {
+            if( (c > 0x7e) )
+            {
+	      return false;
+            }
+            else if (c <= 0x7e)
+            {
+
+               line += c;
+            }
+            else
+            {
+               line += c;
+            }
+         }
+
+         c = is.get();
+      }
+
+      if(line != "")
+      {
+         ossimString key;
+         ossimString value;
+
+         // parse out key and value
+         ossim_uint32 pos = line.find(theDelimiter);
+         key = line.substr(0, pos);
+         key = key.trim();
+         value = line.substr(pos + 1);
+         value = value.trim();
+
+         // if it's not a comment then add it
+         if(key.begin()[0] != (char)'/' ||
+            key.begin()[1] != (char)'/')
+         {
+            if(pos != line.npos)
+            {
+               theMap.insert(std::make_pair(key, value));
+            }
+         }
+      }
+   }
+
+   return true;
+}
+
+vector<ossimString> ossimKeywordlist::findAllKeysThatContains(const ossimString &searchString)const
+{
+   KeywordMap::const_iterator i;
+   vector<ossimString> result;
+
+   for(i = theMap.begin(); i != theMap.end(); ++i)
+   {
+      if((*i).first.contains(searchString))
+      {
+         result.push_back((*i).first);
+      }
+   }
+
+   return result;
+}
+
+vector<ossimString> ossimKeywordlist::findAllKeysThatMatch(const ossimString &regularExpression)const
+{
+   KeywordMap::const_iterator i;
+   vector<ossimString> result;
+   ossimRegExp regExp;
+
+   regExp.compile(regularExpression.c_str());
+
+   for(i = theMap.begin(); i != theMap.end(); ++i)
+   {
+      if(regExp.find( (*i).first.c_str()))
+      {
+         result.push_back((*i).first);
+      }
+   }
+
+   return result;
+}
+
+void ossimKeywordlist::extractKeysThatMatch(ossimKeywordlist& kwl,
+                                            const ossimString &regularExpression)const
+{
+   KeywordMap::const_iterator i;
+   vector<ossimString> result;
+   ossimRegExp regExp;
+
+   regExp.compile(regularExpression.c_str());
+
+   for(i = theMap.begin(); i != theMap.end(); ++i)
+   {
+      if(regExp.find( (*i).first.c_str()))
+      {
+         kwl.add((*i).first, (*i).second);
+      }
+   }
+}
+
+void ossimKeywordlist::removeKeysThatMatch(const ossimString &regularExpression)
+{
+   KeywordMap::const_iterator i;
+   vector<ossimString> result;
+   ossimRegExp regExp;
+
+   regExp.compile(regularExpression.c_str());
+
+   for(i = theMap.begin(); i != theMap.end(); ++i)
+   {
+      if(regExp.find( (*i).first.c_str()))
+      {
+         result.push_back((*i).first);
+      }
+   }
+   for(ossim_uint32 i2 = 0; i2 < result.size(); ++i2)
+   {
+      remove(result[i2]);
+   }
+}
+
+vector<ossimString> ossimKeywordlist::getSubstringKeyList(const ossimString& regularExpression)const
+{
+   KeywordMap::const_iterator i;
+   vector<ossimString> result;
+   ossimRegExp regExp;
+
+   regExp.compile(regularExpression.c_str());
+
+   for(i = theMap.begin(); i != theMap.end(); ++i)
+   {
+      if(regExp.find( (*i).first.c_str()))
+      {
+         ossimString value = ossimString((*i).first.begin()+regExp.start(),
+                                         (*i).first.begin()+regExp.start()+regExp.end());
+
+         if(std::find(result.begin(), result.end(), value) == result.end())
+         {
+            result.push_back(value);
+         }
+      }
+   }
+
+   return result;
+}
+
+ossim_uint32 ossimKeywordlist::getNumberOfSubstringKeys(const ossimString& regularExpression)const
+{
+   KeywordMap::const_iterator i;
+   list<ossimString> currentList;
+   ossim_uint32 result = 0;
+   ossimRegExp regExp;
+
+   regExp.compile(regularExpression.c_str());
+
+   for(i = theMap.begin(); i != theMap.end(); ++i)
+   {
+      if(regExp.find( (*i).first.c_str()))
+      {
+         ossimString value = ossimString((*i).first.begin()+regExp.start(),
+                                         (*i).first.begin()+regExp.start()+regExp.end());
+
+         // make sure we have not already marked it as
+         // found
+         if(std::find(currentList.begin(),
+                      currentList.end(),
+                      value) == currentList.end())
+         {
+            currentList.push_back(value);
+            ++result;
+         }
+      }
+   }
+
+   return result;
+}
+
+void ossimKeywordlist::addPrefixToAll(const ossimString& prefix)
+{
+   ossimKeywordlist tempKwl = *this;
+
+   clear();
+
+   KeywordMap::const_iterator values = tempKwl.theMap.begin();
+
+   while(values != tempKwl.theMap.end())
+   {
+      ossimString newKey = prefix + (*values).first;
+      add(newKey,
+          (*values).second,
+          true);
+      ++values;
+   }
+}
+
+void ossimKeywordlist::stripPrefixFromAll(const ossimString& regularExpression)
+{
+   ossimKeywordlist tempKwl = *this;
+
+   clear();
+
+   KeywordMap::const_iterator values = tempKwl.theMap.begin();
+   ossimRegExp regExp;
+
+   regExp.compile(regularExpression.c_str());
+
+   while(values != tempKwl.theMap.end())
+   {
+      ossimString newKey = (*values).first;
+      if(regExp.find( (*values).first.c_str()))
+      {
+         newKey.erase(newKey.begin()+regExp.start(),
+		      newKey.begin()+regExp.start()+regExp.end());
+
+         add(newKey.c_str(),
+             (*values).second,
+             true);
+      }
+      else
+      {
+         add(newKey.c_str(),
+             (*values).second,
+             true);
+      }
+      ++values;
+   }
+}
+
+
+ossim_uint32 ossimKeywordlist::getSize()const
+{
+   return theMap.size();
+}
+
+const ossimKeywordlist::KeywordMap& ossimKeywordlist::getMap()const
+{
+   return theMap;
+}
+
+ossimKeywordlist::KeywordMap& ossimKeywordlist::getMap()
+{
+   return theMap;
+}
+
+ossimString ossimKeywordlist::delimiter_str() const
+{
+   char tmp[2];
+   tmp[0] = theDelimiter;
+   tmp[1] = '\0';
+   return ossimString(tmp);
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ostream& ossimKeywordlist::print(ostream& os) const
+{
+   KeywordMap::const_iterator i;
+
+   for(i = theMap.begin(); i != theMap.end(); ++i)
+   {
+      os << (*i).first << delimiter_str().c_str() << "  "
+         << (*i).second << endl;
+   }
+   return os;
+}
+
+//*******************************************************************
+// friend function:
+//*******************************************************************
+OSSIMDLLEXPORT ostream& operator<<(ostream& os, const ossimKeywordlist& kwl)
+{
+   kwl.print(os);
+
+   return os;
+}
+
+
+bool ossimKeywordlist::operator ==(ossimKeywordlist& kwl)const
+{
+   if(this==&kwl) return true;
+   map<ossimString, ossimString>::const_iterator iter = theMap.begin();
+
+   while(iter != theMap.end())
+   {
+      const char* value = kwl.find((*iter).first);
+
+      if(ossimString(value) != (*iter).second)
+      {
+         return false;
+      }
+      ++iter;
+   }
+
+   return true;
+}
+
+void ossimKeywordlist::downcaseKeywords()
+{
+   KeywordMap tempMap;
+   KeywordMap::iterator iter = theMap.begin();
+
+   while(iter != theMap.end())
+   {
+      tempMap.insert(make_pair(ossimString::downcase(iter->first),
+                               iter->second));
+                               
+      ++iter;
+   }
+   theMap = tempMap;
+}
+
+void ossimKeywordlist::upcaseKeywords()
+{
+   KeywordMap tempMap;
+   KeywordMap::iterator iter = theMap.begin();
+
+   while(iter != theMap.end())
+   {
+      tempMap.insert(make_pair(ossimString::upcase(iter->first),
+                               iter->second));
+                               
+      ++iter;
+   }
+   theMap = tempMap;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimKeywordlist.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimKeywordlist.h
new file mode 100644
index 0000000000..cd71b50afb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimKeywordlist.h
@@ -0,0 +1,387 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description: This class provides capabilities for keywordlists.
+//
+//********************************************************************
+// $Id: ossimKeywordlist.h,v 1.36 2005/06/06 16:56:05 gpotts Exp $
+
+#ifndef ossimKeywordlist_HEADER
+#define ossimKeywordlist_HEADER
+
+#include <map>
+#include <list>
+#include <iostream>
+using namespace std;
+
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimErrorCodes.h>
+#include <base/data_types/ossimString.h>
+
+static const char DEFAULT_DELIMITER = ':';
+
+class OSSIMDLLEXPORT ossimFilename;
+
+class OSSIMDLLEXPORT ossimKeywordlist : public ossimErrorStatusInterface
+{
+public:
+
+   typedef map<ossimString, ossimString> KeywordMap;
+
+   ossimKeywordlist(char delimiter = DEFAULT_DELIMITER);
+
+   ossimKeywordlist(const char*     file,
+               char            delimiter = DEFAULT_DELIMITER,
+               bool            ignoreBinaryChars = false);
+
+   ossimKeywordlist(const ossimFilename& fileName,
+               char            delimiter = DEFAULT_DELIMITER,
+               bool            ignoreBinaryChars = false);
+
+   ~ossimKeywordlist();
+
+   /*!
+    *  Reads file and adds keywords to the KeywordMap.
+    *  Returns true if file was parsed, false on error.
+    */
+   bool addFile(const char* file);
+
+   /*!
+    *  Reads file and adds keywords to the KeywordMap.
+    *  Returns true if file was parsed, false on error.
+    */
+   bool addFile(const ossimFilename& file);
+
+   /*!
+    *  Method to change default delimiter.  Handy when parsing
+    *  files similar to a ossimKeywordlist.  (DEFAULT = ':')
+    */
+   void change_delimiter(char del) { theDelimiter = del; }
+
+   ossimString delimiter_str() const;
+
+   void add(const char* prefix,
+            const ossimKeywordlist& kwl,
+            bool overwrite=true);
+
+
+   /*!
+    * Allows you to extract out a sub keywordlist from another
+    * you can also collapse the hieracrchy by setting
+    * strip prefix to true.
+    */
+   void add(const ossimKeywordlist& kwl,
+            const char* prefix=0,
+            bool stripPrefix=true);
+
+   // Methods to add keywords to list.
+   void add(const char*   key,
+            const char*   value,
+            bool          overwrite = true);
+
+   void add(const char*   prefix,
+            const char*   key,
+            const char*   value,
+            bool          overwrite = true);
+
+   void add(const char*   key,
+            char          value,
+            bool          overwrite = true);
+
+   void add(const char*   prefix,
+            const char*   key,
+            char          value,
+            bool          overwrite = true);
+
+   void add(const char*   key,
+            ossim_int16   value,
+            bool          overwrite = true);
+
+   void add(const char*   prefix,
+            const char*   key,
+            ossim_int16   value,
+            bool          overwrite = true);
+
+   void add(const char*   key,
+            ossim_uint16  value,
+            bool          overwrite = true);
+
+   void add(const char*   prefix,
+            const char*   key,
+            ossim_uint16  value,
+            bool          overwrite = true);
+
+   void add(const char*   key,
+            ossim_int32   value,
+            bool          overwrite = true);
+
+   void add(const char*   prefix,
+            const char*   key,
+            ossim_int32   value,
+            bool          overwrite = true);
+
+   void add(const char*   key,
+            ossim_uint32  value,
+            bool          overwrite = true);
+
+   void add(const char*   prefix,
+            const char*   key,
+            ossim_uint32  value,
+            bool          overwrite = true);
+
+   void add(const char*   key,
+            long          value,
+            bool          overwrite = true);
+
+   void add(const char*   prefix,
+            const char*   key,
+            long          value,
+            bool          overwrite = true);
+
+   void add(const char*   key,
+            unsigned long value,
+            bool          overwrite = true);
+
+   void add(const char*   prefix,
+            const char*   key,
+            unsigned long value,
+            bool          overwrite = true);
+
+   /**
+    * @param key Key for key-value pair.
+    *
+    * @param value Value to pair with key.  Note this will be stored as a
+    * string.
+    * 
+    * @param precision Decimal point precision of the output. (default = 8)
+    *
+    * @param trimZeroFlag If true trailing '0's and any trailing '.' will
+    * be trimmed from the converted string.  (default = false)
+    *
+    * @param scientific If true output will be in scientific notation else
+    * fixed is used. (default = false)
+    */
+   void add(const char*   key,
+            ossim_float32 value,
+            bool          overwrite    = true,
+            int           precision    = 8,
+            bool          trimZeroFlag = false,
+            bool          scientific   = false);
+
+   /**
+    * @param key Key for key-value pair.
+    *
+    * @param value Value to pair with key.  Note this will be stored as a
+    * string.
+    * 
+    * @param precision Decimal point precision of the output. (default = 8)
+    *
+    * @param trimZeroFlag If true trailing '0's and any trailing '.' will
+    * be trimmed from the converted string.  (default = false)
+    *
+    * @param scientific If true output will be in scientific notation else
+    * fixed is used. (default = false)
+    */
+   void add(const char*   prefix,
+            const char*   key,
+            ossim_float32 value,
+            bool          overwrite    = true,
+            int           precision    = 8,
+            bool          trimZeroFlag = false,
+            bool          scientific   = false);
+
+   /**
+    * @param key Key for key-value pair.
+    *
+    * @param value Value to pair with key.  Note this will be stored as a
+    * string.
+    * 
+    * @param precision Decimal point precision of the output. (default = 15)
+    *
+    * @param trimZeroFlag If true trailing '0's and any trailing '.' will
+    * be trimmed from the converted string.  (default = false)
+    *
+    * @param scientific If true output will be in scientific notation else
+    * fixed is used. (default = false)
+    */
+   void add(const char*   key,
+            ossim_float64 value,
+            bool          overwrite    = true,
+            int           precision    = 15,
+            bool          trimZeroFlag = false,
+            bool          scientific   = false);
+
+   /**
+    * @param key Key for key-value pair.
+    *
+    * @param value Value to pair with key.  Note this will be stored as a
+    * string.
+    * 
+    * @param precision Decimal point precision of the output. (default = 15)
+    *
+    * @param trimZeroFlag If true trailing '0's and any trailing '.' will
+    * be trimmed from the converted string.  (default = false)
+    *
+    * @param scientific If true output will be in scientific notation else
+    * fixed is used. (default = false)
+    */
+   void add(const char*   prefix,
+            const char*   key,
+            ossim_float64 value,
+            bool          overwrite    = true,
+            int           precision    = 15,
+            bool          trimZeroFlag = false,
+            bool          scientific   = false);
+
+   /*!
+    *  find methods
+    *  Searches the map for key(/prefix) and returns the resulting value
+    *  or a null string if the key was not found.
+    */
+   const char* find(const char* key) const;
+   const char* find(const char* prefix,
+                    const char* key) const;
+
+   void remove(const char * key);
+   void remove(const char* prefix, const char * key);
+
+   /*!
+    *  Searches the map for the number of keys containing the string.
+    */
+   ossim_uint32 numberOf(const char* str) const;
+
+   /*!
+    *  Searches the map for the number of keys containing the prefix
+    *  and the string.
+    *
+    *  Given the keyword list contains:
+    *
+    *  source1.type: foo
+    *  source2.type: you
+    *
+    *  This:
+    *
+    *  int number_of_sources = numberOf("source", "type");
+    *
+    *  number_of_sources equals 2
+    */
+   ossim_uint32 numberOf(const char* prefix, const char* key) const;
+
+   /**
+    * Methods to dump the ossimKeywordlist to a file on disk.
+    * @return true on success, false on error.
+    */
+   bool write(const char* file) const;
+
+   ossimString toString()const;
+   void toString(ossimString& result)const;
+
+   void writeToStream(ostream &out)const;
+
+   ostream& print(ostream& os) const;
+   OSSIMDLLEXPORT friend ostream& operator<<(ostream& os, const ossimKeywordlist& kwl);
+   bool operator ==(ossimKeywordlist& kwl)const;
+
+    /*!
+     * Clear all contents out of the ossimKeywordlist.
+     */
+
+    void clear();
+
+    /*!
+     * Add contents of another keyword list to this one.
+     *
+     * @param src the keyword list to copy items from.
+     * @param overwrite true if keys existing in this and src should have
+     * their value overwritten by the src value, otherwise false to preserve
+     * the original value.  Defaults to true.
+     */
+
+   void addList( const ossimKeywordlist &src, bool overwrite = true );
+
+   bool parseStream(istream& is,
+                    bool ignoreBinaryChars = false);
+
+   /*!
+    *  Will return a list of keys that contain the string passed in.
+    *  Later we will need to allow a user to specify regular expresion
+    *  searches.
+    */
+   vector<ossimString> findAllKeysThatContains(const ossimString &searchString)const;
+
+   vector<ossimString> findAllKeysThatMatch(const ossimString &regularExpression)const;
+
+   void extractKeysThatMatch(ossimKeywordlist& kwl,
+                             const ossimString &regularExpression)const;
+
+   void removeKeysThatMatch(const ossimString &regularExpression);
+   /*!
+    * Will return only the portion of the key that
+    * matches the regular expression.
+    *
+    * example:
+    *
+    *  source1.source1.a:
+    *  source1.source2.a:
+    *  source1.source3.a:
+    *  source1.source4.a:
+    *  source1.source10.a:
+    *
+    *  kwl.getSubstringKeyList("source1.source[0-9]*\\.");
+    *
+    *  will return:
+    *
+    *  source1.source1.
+    *  source1.source2.
+    *  source1.source3.
+    *  source1.source4.
+    *  source1.source10.
+    *
+    */
+   vector<ossimString> getSubstringKeyList(const ossimString& regularExpression)const;
+
+   ossim_uint32 getNumberOfSubstringKeys(const ossimString& regularExpression)const;
+
+   void addPrefixToAll(const ossimString& prefix);
+   void stripPrefixFromAll(const ossimString& regularExpression);
+
+   /*!
+    * Returns the number of elements.
+    */
+   ossim_uint32 getSize()const;
+
+   const ossimKeywordlist::KeywordMap& getMap()const;
+   ossimKeywordlist::KeywordMap& getMap();
+   void downcaseKeywords();
+   void upcaseKeywords();
+private:
+
+   /*!
+    *  Method to parse files to initialize the list.  Method will error on
+    *  binary characters if "ignoreBinaryChars = false".  This is used by
+    *  ImageHandler factories that can be passed a binary file inadvertently
+    *  by a user.  The "ignoreBinaryChars" flag should be set to true if
+    *  a text file contains mixed ascii/binary values.
+    *  Returns true if file was parsed, false on error.
+    */
+   bool parseFile(const ossimFilename& file,
+                  bool  ignoreBinaryChars = false);
+
+
+   // Method to see if keyword exists in list.
+   KeywordMap::iterator getMapEntry(const ossimString& key);
+   KeywordMap::iterator getMapEntry(const char* key);
+
+   KeywordMap               theMap;
+   char                     theDelimiter;
+};
+
+#endif /* #ifndef ossimKeywordlist_HEADER */
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLine.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimLine.cpp
new file mode 100644
index 0000000000..d466e5a7c3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLine.cpp
@@ -0,0 +1,176 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//*******************************************************************
+//  $Id: ossimLine.cpp,v 1.14 2004/05/19 14:11:21 dburken Exp $
+#include "ossimLine.h"
+#include "ossimDrect.h"
+#include  <iostream>
+#include <algorithm>
+
+using namespace std;
+
+std::ostream& operator <<(std::ostream& out, const ossimLine& rhs)
+{
+   return out << "line: " << rhs.theP1 << "," << rhs.theP2 << endl;
+}
+
+ossimDpt ossimLine::intersectInfinite(const ossimLine& line)const
+{
+   ossimDpt result;
+   ossimDpt p3 = line.theP1;
+   ossimDpt p4 = line.theP2;
+
+   double numerator  = ((p4.x-p3.x)*(theP1.y-p3.y)    - (p4.y-p3.y)*(theP1.x-p3.x));
+   double denominator = ((p4.y-p3.y)*(theP2.x-theP1.x) - (p4.x-p3.x)*(theP2.y-theP1.y));
+   result.makeNan();
+   // as long as the lines are not parallel
+   if(fabs(denominator) > FLT_EPSILON)
+   {
+      double ua = numerator/ denominator;
+      result = ossimDpt(theP1.x + ua*(theP2.x-theP1.x),
+                        theP1.y + ua*(theP2.y-theP1.y));
+   }
+
+   return result;
+}
+
+ossimDpt ossimLine::intersectSegment(const ossimLine& line)const
+{
+   ossimDpt result;
+   ossimDpt p3 = line.theP1;
+   ossimDpt p4 = line.theP2;
+
+   double numerator   = ((p4.x-p3.x)*(theP1.y-p3.y)    - (p4.y-p3.y)*(theP1.x-p3.x));
+   double denominator = ((p4.y-p3.y)*(theP2.x-theP1.x) - (p4.x-p3.x)*(theP2.y-theP1.y));
+   result.makeNan();
+   // as long as the lines are not parallel
+   if(fabs(denominator) > FLT_EPSILON)
+   {
+      double ua = numerator/ denominator;
+
+      if((ua >= -FLT_EPSILON) && (ua <= (1.0 + FLT_EPSILON)))
+      {
+         ossimDpt test = ossimDpt(theP1.x + ua*(theP2.x-theP1.x),
+                                  theP1.y + ua*(theP2.y-theP1.y));
+         ossimDpt midPoint = line.theP1 + (line.theP2-line.theP1)*.5;
+         if( ((test-midPoint).length()/line.length()) <= (.5+FLT_EPSILON))
+         {
+            result = test;
+         }
+      }
+   }
+
+   return result;
+}
+
+double ossimLine::length()const
+{
+   return (theP2-theP1).length();
+}
+
+ossimDpt ossimLine::midPoint()const
+{
+   return (theP1 + (theP2-theP1)*.5);
+}
+
+bool ossimLine::isPointWithin(const ossimDpt& point, double delta)const
+{   
+   if(isPointOnInfiniteLine(point, delta))
+   {
+      double minx = std::min(theP1.x, theP2.x);
+      double miny = std::min(theP1.y, theP2.y);
+      double maxx = std::max(theP1.x, theP2.x);
+      double maxy = std::max(theP1.y, theP2.y);
+      
+      ossimDrect rect(minx - delta,
+                      miny - delta,
+                      maxx + delta,
+                      maxy + delta);
+      
+      return rect.pointWithin(point);
+   }
+   
+   return false;
+}
+
+bool ossimLine::isPointOnInfiniteLine(const ossimDpt& point, double delta)const
+{
+   if((point == theP1) || (point == theP2))
+   {
+      return true;
+   }
+   else if(fabs(theP1.x-theP2.x) <= FLT_EPSILON)
+   {
+      return (fabs(point.x - theP1.x) <= delta);
+   }
+   else if(fabs(theP1.y-theP2.y) <= FLT_EPSILON)
+   {
+      return (fabs(point.y - theP1.y) <= delta);      
+   }
+   else
+   {
+      ossimDpt v1  = getVector();
+      v1 = v1 * (1.0/v1.length());
+      ossimDpt v2  = (point - theP1);
+      double s     = v1.x*v2.x + v1.y*v2.y;
+      ossimDpt p   = theP1 + v1*s;
+      double len   = (point-p).length();
+
+      if(len < delta)
+      {
+         return true;
+      }
+      else
+      {
+         return false;
+      }
+   }
+
+   return false;
+}
+
+ossimDpt ossimLine::normal()const
+{
+   ossimDpt delta = getVector();
+   ossimDpt result;
+   if(fabs(delta.x) <= FLT_EPSILON)
+   {
+      result.y = 0.0;
+      result.x = -delta.y;
+   }
+   else if(fabs(delta.y) <= FLT_EPSILON)
+   {
+      result.x = 0.0;
+      result.y = delta.x;
+   }
+   else
+   {
+      result.x = -delta.y;
+      result.y = delta.x;
+   }
+   double len = result.length();
+   
+   if(len >FLT_EPSILON)
+   {
+      result = result*(1.0/len);
+   }
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLine.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimLine.h
new file mode 100644
index 0000000000..d5703d4f57
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLine.h
@@ -0,0 +1,94 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//*******************************************************************
+//  $Id: ossimLine.h,v 1.4 2002/09/01 19:21:56 gpotts Exp $
+#ifndef ossimLine_HEADER
+#define ossimLine_HEADER
+#include "base/data_types/ossimDpt.h"
+#include <iostream>
+
+class OSSIMDLLEXPORT ossimLine
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out,
+                               const ossimLine& rhs);
+   ossimLine(const ossimDpt& p1=ossimDpt(0,0),
+             const ossimDpt& p2=ossimDpt(0,0))
+      :theP1(p1),
+       theP2(p2)
+      {
+      }
+
+   
+   ossimDpt getVector()const
+      {
+         return (theP2-theP1);
+      }
+
+   /*!
+    * Computes the following equation:
+    *
+    * Note: this object will be line a and the passed
+    *       in object will be line b;
+    *       and
+    *       P1 and P2 coorespond to this object and
+    *       P3 and P4 will coorespond to the passed in object.
+    *
+    * Now find point formed at the intersection of line a and b:
+    *
+    * Pa = P1 + ua ( P2 - P1 ) 
+    * Pb = P3 + ub ( P4 - P3 )
+    *const ossimDpt&   ul_corner,
+              const ossimDpt&   lr_corner,
+              ossimCoordSysOrientMode mode=OSSIM_LEFT_HANDED);
+    * x1 + ua (x2 - x1) = x3 + ub (x4 - x3) 
+    * and 
+    * y1 + ua (y2 - y1) = y3 + ub (y4 - y3)
+    *
+    * Solve:
+    *  ua = ((x4-x3)(y1-y3) - (y4-y3)(x1-x3))/
+    *       ((y4-y3)(x2-x1) - (x4-x3)(y2-y1))
+    *  ub = ((x2-x1)(y1-y3) - (y2-y1)(x1-x3))/
+    *       ((y4-y3)(x2-x1) - (x4-x3)(y2-y1))
+    * substitute:
+    *
+    * x = x1 + ua (x2 - x1) 
+    * y = y1 + ua (y2 - y1)
+    *
+    */
+   ossimDpt intersectInfinite(const ossimLine& line)const;
+
+   ossimDpt intersectSegment(const ossimLine& line)const;
+
+   ossimDpt midPoint()const;
+   double length()const;
+   ossimDpt normal()const;
+   /*!
+    * Will return true if the point is on the line.
+    */
+   bool isPointWithin(const ossimDpt& point, double delta=FLT_EPSILON)const;
+
+   bool isPointOnInfiniteLine(const ossimDpt& point, double delta=FLT_EPSILON)const;
+
+   ossimDpt   theP1;
+   ossimDpt   theP2;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrPoint.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrPoint.cpp
new file mode 100644
index 0000000000..d82da89b8c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrPoint.cpp
@@ -0,0 +1,124 @@
+//*****************************************************************************
+// FILE: ossimLsrPoint.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of a 3D point object in the Earth-centered, earth
+//   fixed (ECEF) coordinate system.
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Log: ossimLsrPoint.cpp,v $
+//  Revision 1.2  2003/05/02 15:34:17  dburken
+//  Fixed build errors on AIX VisualAge compiler.  <dburken@imagelinks.com>
+//
+//  Revision 1.1  2001/08/13 21:29:18  okramer
+//  Initial delivery of ECEF and LSR suite. (okramer@imagelinks.com)
+//
+
+#include "ossimLsrPoint.h"
+#include "ossimGpt.h"
+#include "ossimLsrVector.h"
+#include "ossimMatrix3x3.h"
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLsrPoint(ossimLsrPoint, space)
+//  
+//*****************************************************************************
+ossimLsrPoint::ossimLsrPoint(const ossimLsrPoint& convert_this,
+                             const ossimLsrSpace& new_space)
+   : theLsrSpace(new_space)
+{
+   initialize(ossimEcefPoint(convert_this));
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLsrPoint(const ossimLsrPoint&  convert_this)
+//  
+//*****************************************************************************
+ossimLsrPoint::ossimLsrPoint(const ossimGpt&  gpt,
+                             const ossimLsrSpace& space)
+   : theLsrSpace(space)
+{
+   initialize(ossimEcefPoint(gpt));
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLsrPoint(const ossimLsrPoint&  convert_this)
+//  
+//*****************************************************************************
+ossimLsrPoint::ossimLsrPoint(const ossimEcefPoint& convert_this,
+                             const ossimLsrSpace& space)
+   : theLsrSpace(space)
+{
+   initialize(convert_this);
+}
+
+//*****************************************************************************
+//  PROTECTED METHOD: ossimLsrPoint::initialize(ossimEcefPoint)
+//  
+//  Convenience method used by several constructors for initializing theData
+//  given an ECEF point. Assumes theLsrSpace has been previously initialized.
+//  
+//*****************************************************************************
+void ossimLsrPoint::initialize(ossimEcefPoint ecef_point)
+{
+   //***
+   // Translate to new space given the space's offset origin:
+   //***
+   ossimColumnVector3d xlated ((ecef_point - theLsrSpace.origin()).data());
+
+   //***
+   // Rotate by the inverse (transpose) of the LSR-to-ECEF rot matrix:
+   //***
+   theData = theLsrSpace.ecefToLsrRotMatrix() * xlated;
+}
+
+//*****************************************************************************
+//   OPERATOR: ossimLsrPoint::operator-(ossimLsrPoint)
+//  
+//*****************************************************************************
+ossimLsrVector ossimLsrPoint::operator-(const ossimLsrPoint& p) const
+{
+   if (theLsrSpace == p.theLsrSpace)
+      return ossimLsrVector(theData-p.theData, theLsrSpace);
+
+   //else error:
+   ossimLsrSpace::lsrSpaceErrorMessage();
+   return ossimLsrVector(OSSIM_NAN, OSSIM_NAN, OSSIM_NAN, theLsrSpace);
+}
+
+//*****************************************************************************
+//  OPERATOR: ossimLsrPoint::operator+(ossimLsrVector)
+//  
+//*****************************************************************************
+ossimLsrPoint ossimLsrPoint::operator+(const ossimLsrVector& v) const
+{
+   if (theLsrSpace == v.lsrSpace())
+      return ossimLsrPoint(theData + v.data(), theLsrSpace);
+
+   //else error:
+   theLsrSpace.lsrSpaceErrorMessage();
+   return ossimLsrPoint(OSSIM_NAN, OSSIM_NAN, OSSIM_NAN, theLsrSpace);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrPoint.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrPoint.h
new file mode 100644
index 0000000000..df88f3ae90
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrPoint.h
@@ -0,0 +1,194 @@
+//*****************************************************************************
+// FILE: ossimLsrPoint.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//  Class for representing points in some local space rectangular (LSR)
+//  coordinate system. This coordinate system is related to the ECEF system
+//  by the ossimLsrSpace member object. This class simplifies coordinate
+//  conversions between LSR and ECEF, and other LSR points.
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimLsrPoint.h,v 1.5 2004/04/02 22:03:54 gpotts Exp $
+
+#ifndef ossimLsrPoint_HEADER
+#define ossimLsrPoint_HEADER
+
+#include <stdio.h>
+
+#include <base/data_types/ossimLsrSpace.h>
+#include <base/data_types/ossimColumnVector3d.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/context/ossimNotifyContext.h>
+
+class OSSIMDLLEXPORT ossimGpt;
+class OSSIMDLLEXPORT ossimLsrVector;
+
+//*****************************************************************************
+//  CLASS: ossimLsrPoint
+//
+//*****************************************************************************
+class OSSIMDLLEXPORT ossimLsrPoint
+{
+public:
+   /*!
+    * CONSTRUCTORS: 
+    */
+   ossimLsrPoint()
+      : theData(0,0,0) {}
+   
+   ossimLsrPoint(const ossimLsrPoint& copy_this)
+      : theData(copy_this.theData), theLsrSpace(copy_this.theLsrSpace) {}
+   
+   ossimLsrPoint(const ossimColumnVector3d& assign_this,
+                 const ossimLsrSpace& space)
+      : theData(assign_this), theLsrSpace(space) {}
+   
+   ossimLsrPoint(const double& x,
+                 const double& y,
+                 const double& z,
+                 const ossimLsrSpace& space)
+      : theData(x, y, z), theLsrSpace(space) {}
+   
+   ossimLsrPoint(const ossimLsrPoint& convert_this,
+                 const ossimLsrSpace&);
+
+   ossimLsrPoint(const ossimGpt& convert_this,
+                 const ossimLsrSpace&);
+
+   ossimLsrPoint(const ossimEcefPoint& convert_this,
+                 const ossimLsrSpace&);
+
+   /*!
+    * OPERATORS:
+    */
+   const ossimLsrPoint& operator= (const ossimLsrPoint&);       //inline below
+   ossimLsrVector       operator- (const ossimLsrPoint&)  const;
+   ossimLsrPoint        operator+ (const ossimLsrVector&) const;
+   bool                 operator==(const ossimLsrPoint&)  const;//inline below
+   bool                 operator!=(const ossimLsrPoint&)  const;//inline below
+
+   /*!
+    * CASTING OPERATOR:
+    * Used as: myEcefVector = ossimEcefPoint(this) -- looks like a constructor
+    * but is an operation on this object. ECEF knows nothing about LSR, so
+    * cannot provide an ossimEcefVector(ossimLsrPoint) constructor.
+    */
+   operator ossimEcefPoint() const; // inline below
+
+   /*!
+    * DATA ACCESS METHODS: 
+    */
+   double    x() const { return theData[0]; }
+   double&   x()       { return theData[0]; }
+   double    y() const { return theData[1]; }
+   double&   y()       { return theData[1]; }
+   double    z() const { return theData[2]; }
+   double&   z()       { return theData[2]; }
+
+   ossimColumnVector3d&       data()           { return theData; }
+   const ossimColumnVector3d& data()     const { return theData; }
+
+   ossimLsrSpace&             lsrSpace()       { return theLsrSpace; }
+   const ossimLsrSpace&       lsrSpace() const { return theLsrSpace; }
+
+   /*!
+    * Debug Dump: 
+    */
+   void print(ostream& stream = ossimNotify(ossimNotifyLevel_INFO)) const;
+
+   friend ostream& operator<< (ostream& os , const ossimLsrPoint& instance)
+      { instance.print(os); return os; }
+
+protected:
+   /*!
+    * METHOD: initialize(ossimEcefPoint)
+    * Convenience method used by several constructors for initializing theData
+    * given an ECEF point. Assumes theLsrSpace has been previously initialized.
+    */
+   void initialize(ossimEcefPoint ecef_point);
+   
+   ossimColumnVector3d theData;
+   ossimLsrSpace       theLsrSpace;
+
+};
+
+//================== BEGIN DEFINITIONS FOR INLINE METHODS =====================
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrPoint::operator=(ossimLsrPoint)
+//*****************************************************************************
+inline const ossimLsrPoint&
+ossimLsrPoint::operator=(const ossimLsrPoint& p)
+{
+   theData = p.theData;
+   theLsrSpace = p.theLsrSpace;
+   
+   return *this;
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrPoint::operator==(ossimLsrPoint)
+//*****************************************************************************
+inline bool ossimLsrPoint::operator==(const ossimLsrPoint& p) const
+{
+   return ((theData == p.theData) && (theLsrSpace == p.theLsrSpace));
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrPoint::operator!=(ossimLsrPoint)
+//*****************************************************************************
+inline bool ossimLsrPoint::operator!=(const ossimLsrPoint& p) const
+{
+   return (!(*this == p));
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrPoint::operator ossimEcefPoint()
+//
+//  Looks like a constructor for an ossimEcefPoint but is an operation on this
+//  object. Returns the ossimEcefPoint equivalent.
+//*****************************************************************************
+inline ossimLsrPoint::operator ossimEcefPoint() const
+{
+   return ossimEcefPoint(theLsrSpace.origin().data() +
+                         theLsrSpace.lsrToEcefRotMatrix()*theData);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimLsrPoint::print(ostream)
+//  
+//  Dumps contents for debug purposes.
+//*****************************************************************************
+inline void ossimLsrPoint::print(ostream& os) const
+{
+   os << "(ossimLsrPoint)\n"
+      << "  theData = " << theData
+      << "\n  theLsrSpace = " << theLsrSpace;
+}
+
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrRay.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrRay.cpp
new file mode 100644
index 0000000000..f093294ede
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrRay.cpp
@@ -0,0 +1,109 @@
+//*****************************************************************************
+// FILE: ossimLsrRay.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//  Class for representing rays in some local space rectangular (LSR)
+//  coordinate system. This coordinate system is related to the ECEF system
+//  by the ossimLsrSpace member object. This class simplifies coordinate
+//  conversions between LSR and ECEF, and other LSR spaces.
+//
+//  An LSR ray is defined as having an LSR origin point and an LSR unit
+//  direction vector radiating from the origin.
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Log: ossimLsrRay.cpp,v $
+//  Revision 1.6  2004/04/08 15:25:30  gpotts
+//  *** empty log message ***
+//
+//  Revision 1.5  2004/04/08 14:12:39  gpotts
+//  Fixe clog to ossimNotify
+//
+//  Revision 1.4  2002/10/21 21:51:46  gpotts
+//  *** empty log message ***
+//
+//  Revision 1.3  2002/10/21 21:51:26  gpotts
+//  *** empty log message ***
+//
+//  Revision 1.2  2001/12/20 22:26:41  bpayne
+//  Added constructor accepting two ossimLsrPoint args
+//
+//  Revision 1.1  2001/08/13 21:29:18  okramer
+//  Initial delivery of ECEF and LSR suite. (okramer@imagelinks.com)
+//
+
+#include "ossimLsrRay.h"
+
+//*****************************************************************************
+//  CONSTRUCTOR:    ossimLsrRay(ossimLsrPoint, ossimLsrVector)
+//  
+//  Constructs by transforming the given ray into the new space.
+//  
+//*****************************************************************************
+ossimLsrRay::ossimLsrRay(const ossimLsrPoint&  origin,
+                         const ossimLsrVector& direction)
+   : theOrigin(origin),
+     theDirection(direction.unitVector())
+{
+   if (origin.lsrSpace() != direction.lsrSpace())
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL -- ossimLsrRay(ossimLsrPoint,ossimLsrVector) Constructor:"
+                                          << "\n   The origin and direction LSR quantities do not share the"
+                                          << "\n   same LSR space. Setting to NAN. Check the data for errors." << std::endl;
+
+      theOrigin    = ossimLsrPoint (OSSIM_NAN, OSSIM_NAN, OSSIM_NAN,
+                                    origin.lsrSpace());
+      theDirection = ossimLsrVector(OSSIM_NAN, OSSIM_NAN, OSSIM_NAN,
+                                    direction.lsrSpace());
+   }    
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR:    ossimLsrRay(ossimLsrPoint, ossimLsrPoint)
+//  
+//  Constructs by transforming the given ray into the new space.
+//  
+//*****************************************************************************
+ossimLsrRay::ossimLsrRay(const ossimLsrPoint&  origin,
+                         const ossimLsrPoint&  towards)
+   : theOrigin(origin)
+{
+   if (origin.lsrSpace() != towards.lsrSpace())
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "ERROR -- ossimLsrRay(ossimLsrPoint,ossimLsrPoint) Constructor:"
+                                          << "\n   The origin and direction LSR quantities do not share the"
+                                          << "\n   same LSR space. Setting to NAN. Check the data for errors." << std::endl;
+      
+      theOrigin    = ossimLsrPoint (OSSIM_NAN, OSSIM_NAN, OSSIM_NAN,
+                                    origin.lsrSpace());
+      theDirection = ossimLsrVector(OSSIM_NAN, OSSIM_NAN, OSSIM_NAN,
+                                    towards.lsrSpace());
+   }
+
+   else
+   {
+      theDirection = towards - origin;
+      theDirection.normalize();
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrRay.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrRay.h
new file mode 100644
index 0000000000..e8c32ed212
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrRay.h
@@ -0,0 +1,169 @@
+//*****************************************************************************
+// FILE: ossimLsrRay.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//  Class for representing rays in some local space rectangular (LSR)
+//  coordinate system. This coordinate system is related to the ECEF system
+//  by the ossimLsrSpace member object. This class simplifies coordinate
+//  conversions between LSR and ECEF, and other LSR spaces.
+//
+//  An LSR ray is defined as having an LSR origin point and an LSR unit
+//  direction vector radiating from the origin.
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimLsrRay.h,v 1.7 2004/04/02 22:03:54 gpotts Exp $
+
+#ifndef ossimLsrRay_HEADER
+#define ossimLsrRay_HEADER
+
+#include <stdio.h>
+#include <base/data_types/ossimLsrPoint.h>
+#include <base/data_types/ossimLsrVector.h>
+#include <base/data_types/ossimEcefRay.h>
+#include <base/context/ossimNotifyContext.h>
+
+//*****************************************************************************
+//  CLASS: ossimLsrRay
+//
+//*****************************************************************************
+class OSSIMDLLEXPORT ossimLsrRay
+{
+public:
+   /*!
+    * CONSTRUCTORS: 
+    */
+   ossimLsrRay() {}
+   
+   ossimLsrRay(const ossimLsrRay& copy_this)
+      : theOrigin(copy_this.theOrigin), theDirection(copy_this.theDirection) {}
+
+   ossimLsrRay(const ossimLsrPoint&  origin,
+               const ossimLsrVector& direction);
+
+   ossimLsrRay(const ossimLsrPoint&  origin,
+               const ossimLsrPoint&  towards);
+
+   ossimLsrRay(const ossimLsrRay& convert_this,
+               const ossimLsrSpace& new_space)
+      : theOrigin(convert_this.theOrigin, new_space),
+	theDirection(convert_this.theDirection, new_space) {}
+
+   /*!
+    * OPERATORS:
+    */
+   const ossimLsrRay&  operator= (const ossimLsrRay& r);       // inline below
+   bool                operator==(const ossimLsrRay& r) const; // inline below
+   bool                operator!=(const ossimLsrRay& r) const; // inline below
+
+   /*!
+    * DATA ACCESS METHODS:
+    */
+   const ossimLsrPoint&  origin()    const { return theOrigin; }
+   const ossimLsrVector& direction() const { return theDirection; }
+   const ossimLsrSpace&  lsrSpace()  const { return theOrigin.lsrSpace(); }
+
+   /*!
+    * CASTING OPERATOR: ossimEcefRay()
+    * Looks like a constructor for an ossimEcefRay but is an operation on this
+    * object. Returns the ossimEcefRay equivalent.
+    */
+   operator ossimEcefRay () const;  // inline below
+   
+   /*!
+    * METHOD: extend(t)
+    * Extends the ray by distance t (meters) from the origin to the LSR
+    * point returned (in same space).
+    */
+   ossimLsrPoint extend(const double& t) const
+      { return (theOrigin + theDirection*t); }
+
+   /*!
+    * Debug Dump: 
+    */
+   void print(ostream& stream = ossimNotify(ossimNotifyLevel_INFO)) const;  // inline below
+   
+   friend ostream& operator<< (ostream& os , const ossimLsrRay& instance)
+      { instance.print(os); return os; }
+
+private:
+   ossimLsrPoint  theOrigin;
+   ossimLsrVector theDirection;
+
+};
+
+//================== BEGIN DEFINITIONS FOR INLINE METHODS =====================
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefRay::operator=(ossimEcefRay)
+//*****************************************************************************
+inline const ossimLsrRay& ossimLsrRay::operator=(const ossimLsrRay& r)
+{
+   theOrigin = r.theOrigin;
+   theDirection = r.theDirection;
+   return *this;
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefRay::operator==(ossimEcefRay)
+//*****************************************************************************
+inline bool ossimLsrRay::operator==(const ossimLsrRay& r) const
+{
+   return ((theOrigin == r.theOrigin) && (theDirection == r.theDirection));
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimEcefRay::operator!=(ossimEcefRay)
+//*****************************************************************************
+inline bool ossimLsrRay::operator!=(const ossimLsrRay& r) const 
+{
+   return !(*this == r);
+}
+
+//*****************************************************************************
+//  INLINE CASTING OPERATOR: ossimEcefRay()
+//  
+//  Looks like a constructor for an ossimEcefRay but is an operation on this
+//  object. Returns the ossimEcefRay equivalent.
+//*****************************************************************************
+inline ossimLsrRay::operator ossimEcefRay() const
+{
+   return ossimEcefRay(ossimEcefPoint(theOrigin),
+                       ossimEcefVector(theDirection));
+}
+   
+//*****************************************************************************
+//  INLINE METHOD: ossimLsrRay::print(ostream)
+//  Dumps contents for debug purposes.
+//*****************************************************************************
+inline void ossimLsrRay::print(ostream& os) const
+{
+   os << "(ossimLsrRay)"
+      << "\n   theOrigin    = " << theOrigin
+      << "\n   theDirection = " << theDirection << ends;
+}
+   
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrSpace.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrSpace.cpp
new file mode 100644
index 0000000000..c655127919
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrSpace.cpp
@@ -0,0 +1,236 @@
+//*****************************************************************************
+// FILE: ossimLsrSpace.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//  This class maintains the relationship between a local space rectangular
+//  (LSR) coordinate system and the earth-centered, earth-fixed (ECEF) system.
+//
+// SOFTWARE HISTORY:
+//
+//   09Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//
+//*****************************************************************************
+//  $Id: ossimLsrSpace.cpp,v 1.5 2004/04/02 22:03:54 gpotts Exp $
+
+#include <base/data_types/ossimLsrSpace.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimGpt.h>
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLsrSpace(origin, x_dir, y_dir, int)
+//
+//  Constructs the space given origin, and X and Y ECEF directions. The int
+//  argument is a place holder only and not used.
+//  
+//*****************************************************************************
+ossimLsrSpace::ossimLsrSpace(const ossimEcefPoint&  origin,
+                             const ossimEcefVector& x_dir_ecf_vec,
+                             const ossimEcefVector& y_dir_ecf_vec,
+                             int   z_not_provided_space_holder)
+   : theOrigin (origin)
+{
+   //***
+   // Compute the remaining axis given first two:
+   //***
+   ossimColumnVector3d xdir (x_dir_ecf_vec.data().unit());
+   ossimColumnVector3d ydir (y_dir_ecf_vec.data().unit());
+   ossimColumnVector3d zdir (xdir.cross(ydir));
+
+   //***
+   // Fill the rotation matrix:
+   //***
+   theLsrToEcefRotMatrix = ossimMatrix3x3::create(xdir[0], ydir[0], zdir[0],
+                                                  xdir[1], ydir[1], zdir[1],
+                                                  xdir[2], ydir[2], zdir[2]);
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLsrSpace
+//  
+//  Constructs the space given origin, and X and Z ECEF directions. The int
+//  argument is a place holder only and not used.
+//  
+//*****************************************************************************
+ossimLsrSpace::ossimLsrSpace(const ossimEcefPoint&  origin,
+                             const ossimEcefVector& x_dir_ecf_vec,
+                             int   y_not_provided_space_holder,
+                             const ossimEcefVector& z_dir_ecf_vec)
+   : theOrigin (origin)
+{
+   //***
+   // Compute the remaining axis given first two:
+   //***
+   ossimColumnVector3d xdir (x_dir_ecf_vec.data().unit());
+   ossimColumnVector3d zdir (z_dir_ecf_vec.data().unit());
+   ossimColumnVector3d ydir (zdir.cross(xdir));
+
+   //***
+   // Fill the rotation matrix:
+   //***
+   theLsrToEcefRotMatrix = ossimMatrix3x3::create(xdir[0], ydir[0], zdir[0],
+                                                  xdir[1], ydir[1], zdir[1],
+                                                  xdir[2], ydir[2], zdir[2]);
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLsrSpace
+//  
+//  Constructs the space given origin, and Y and Z ECEF directions. The int
+//  argument is a place holder only and not used.
+//  
+//*****************************************************************************
+ossimLsrSpace::ossimLsrSpace(const ossimEcefPoint&  origin,
+                             int   x_not_provided_space_holder,
+                             const ossimEcefVector& y_dir_ecf_vec,
+                             const ossimEcefVector& z_dir_ecf_vec)
+   : theOrigin (origin)
+{
+   //***
+   // Compute the remaining axis given first two:
+   //***
+   ossimColumnVector3d ydir (y_dir_ecf_vec.data().unit());
+   ossimColumnVector3d zdir (z_dir_ecf_vec.data().unit());
+   ossimColumnVector3d xdir (ydir.cross(zdir));
+
+   //***
+   // Fill the rotation matrix:
+   //***
+   theLsrToEcefRotMatrix = ossimMatrix3x3::create(xdir[0], ydir[0], zdir[0],
+                                                  xdir[1], ydir[1], zdir[1],
+                                                  xdir[2], ydir[2], zdir[2]);
+}
+
+//*****************************************************************************
+//  CONSTRUCTORS: ossimLsrSpace(ossimGpt, y_azimuth)
+//
+//  This constructor sets up a local coordinate system centered at the
+//  specified groundpoint, with the Z-axis normal to the ellipsoid and the
+//  Y-axis rotated clockwise from north by the y_azimuth. This angle defaults
+//  to 0, producing an East-North-Up system.
+//  
+//*****************************************************************************
+ossimLsrSpace::ossimLsrSpace(const ossimGpt& origin,
+                             const double&   y_azimuth)
+{
+   //***
+   // Convert ground point origin to ECEF coordinates:
+   //***
+   theOrigin = ossimEcefPoint(origin);
+   
+   //***
+   // Establish the component vectors for ENU system::
+   //***
+   double sin_lat = sind(origin.lat);
+   double cos_lat = cosd(origin.lat);
+   double sin_lon = sind(origin.lon);
+   double cos_lon = cosd(origin.lon);
+   
+   ossimColumnVector3d E (-sin_lon,
+                          cos_lon,
+                          0.0);
+   ossimColumnVector3d N (-sin_lat*cos_lon,
+                          -sin_lat*sin_lon,
+                          cos_lat);
+   ossimColumnVector3d U (E.cross(N));
+
+   //***
+   // Fill rotation matrix with these components, rotated about the Z axis
+   // by the azimuth indicated:
+   //***
+   if (y_azimuth != 0.0)
+   {
+      double cos_azim = cosd(y_azimuth);
+      double sin_azim = sind(y_azimuth);
+      ossimColumnVector3d X (cos_azim*E - sin_azim*N);
+      ossimColumnVector3d Y (sin_azim*E + cos_azim*N);
+      ossimColumnVector3d Z (X.cross(Y));
+      
+      theLsrToEcefRotMatrix
+         = ossimMatrix3x3::create(X[0], Y[0], Z[0],
+                                  X[1], Y[1], Z[1],
+                                  X[2], Y[2], Z[2]);
+   }
+   else
+   {
+      //***
+      // No azimuth rotation, so simplify:
+      //***
+      theLsrToEcefRotMatrix = ossimMatrix3x3::create(E[0], N[0], U[0],
+                                                     E[1], N[1], U[1],
+                                                     E[2], N[2], U[2]);
+   }
+}
+
+//*****************************************************************************
+//  OPERATOR: ==
+//*****************************************************************************
+bool ossimLsrSpace::operator == (const ossimLsrSpace& that) const
+{
+   if (theOrigin != that.origin())
+      return false;
+   
+   if (theLsrToEcefRotMatrix != that.theLsrToEcefRotMatrix)
+      return false;
+
+   return true;
+}
+   
+//*****************************************************************************
+//  OPERATOR: =
+//*****************************************************************************
+const ossimLsrSpace& ossimLsrSpace::operator = (const ossimLsrSpace& space)
+{
+   theOrigin = space.theOrigin;
+   theLsrToEcefRotMatrix = space.theLsrToEcefRotMatrix;
+   return *this;
+}
+
+//*****************************************************************************
+//  STATIC METHOD: lsrSpaceErrorMessage()
+//  
+//  Convenience method accessible to all owners of an ossimLsrSpace for
+//  displaying an error message when LSR spaces do not match between
+//  objects. All operations between LSR objects must be in a common space.
+//  
+//*****************************************************************************
+ostream& ossimLsrSpace::lsrSpaceErrorMessage(ostream& os)
+{
+   os<<"ossimLsrSpace ERROR: An operation was attempted between two LSR \n"
+     <<"  objects with differing LSR spaces. This is an illegal condition.\n"
+     <<"  Please check the data and/or report the error to OSSIM development."
+     <<endl;
+
+   return os;
+}
+
+//*****************************************************************************
+//  METHOD: print()
+//  
+//  Dumps contents to stream for debug purposes. Defaults to cout.
+//  
+//*****************************************************************************
+void ossimLsrSpace::print(ostream& stream) const
+{
+   stream << "(ossimLsrSpace)"
+          << "\n   theOrigin = " << theOrigin
+          << "\n   theLsrToEcefRotMatrix = \n" << theLsrToEcefRotMatrix;
+}
+   
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrSpace.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrSpace.h
new file mode 100644
index 0000000000..ad27665ea9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrSpace.h
@@ -0,0 +1,147 @@
+//*****************************************************************************
+// FILE: ossimLsrSpace.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//  This class maintains the relationship between a local space rectangular
+//  (LSR) coordinate system and the earth-centered, earth-fixed (ECEF) system.
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimLsrSpace.h,v 1.7 2004/04/02 22:03:54 gpotts Exp $
+
+#ifndef ossimLsrSpace_HEADER
+#define ossimLsrSpace_HEADER
+
+#include <stdio.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/data_types/ossimMatrix3x3.h>
+#include <base/context/ossimNotifyContext.h>
+
+class OSSIMDLLEXPORT ossimGpt;
+
+//*****************************************************************************
+//  CLASS: ossimLsrSpace
+//
+//  This class maintains the relationship between a local space rectangular
+//  (LSR) coordinate system and the earth-centered, earth-fixed (ECEF) system.
+//
+//*****************************************************************************
+class OSSIMDLLEXPORT ossimLsrSpace
+{
+public:
+   /*!
+    * DEFAULT & COPY CONSTRUCTOR: 
+    */
+   ossimLsrSpace() {}
+   
+   ossimLsrSpace(const ossimLsrSpace& copy_this)
+      :
+	 theLsrToEcefRotMatrix(copy_this.theLsrToEcefRotMatrix),
+	 theOrigin(copy_this.theOrigin) {}
+
+   /*!
+    * CONSTRUCTORS: The following three constructors accept an ECEF origin
+    * and two of the three axes direction vectors. Note the use of the dummy
+    * "int" argument (not used) to hold the place of the unspecified axes. 
+    */
+   ossimLsrSpace(const ossimEcefPoint&  origin,
+                 const ossimEcefVector& x_dir_ecf_vec,
+                 const ossimEcefVector& y_dir_ecf_vec,
+                 const int z_not_provided_space_holder);
+
+   ossimLsrSpace(const ossimEcefPoint&  origin,
+                 const ossimEcefVector& x_dir_ecf_vec,
+                 const int y_not_provided_space_holder,
+                 const ossimEcefVector& z_dir_ecf_vec);
+
+   ossimLsrSpace(const ossimEcefPoint&  origin,
+                 const int x_not_provided_space_holder,
+                 const ossimEcefVector& y_dir_ecf_vec,
+                 const ossimEcefVector& z_dir_ecf_vec);
+
+   /*!
+    * CONSTRUCTOR: ossimLsrSpace(ossimGpt, y_azimuth)
+    * This constructor sets up a local coordinate system centered at the
+    * specified groundpoint, with the Z-axis normal to the ellipsoid and the
+    * Y-axis rotated clockwise from north by the y_azimuth. This angle defaults
+    * to 0, producing an East-North-Up (ENU) system.
+    */
+   ossimLsrSpace(const ossimGpt& origin,
+                 const double&   y_azimuth=0);
+
+   /*!
+    * CONSTRUCTOR: ossimLsrSpace(ossimEcefPt, NEWMAT::Matrix)
+    * This constructor sets up a local coordinate system centered at the
+    * specified ECF, with given LSR-to-ECF rotation.
+    */
+   ossimLsrSpace(const ossimEcefPoint& origin,
+                 const NEWMAT::Matrix& lsrToEcfRot)
+      : theLsrToEcefRotMatrix (lsrToEcfRot), theOrigin (origin) {}
+
+   ~ossimLsrSpace() {}
+
+   /*!
+    * OPERATORS:
+    */
+   bool operator == (const ossimLsrSpace&) const;
+   
+   bool operator != (const ossimLsrSpace& that) const
+      { return !(*this == that); }
+   
+   const ossimLsrSpace& operator = (const ossimLsrSpace& space);
+
+   /*!
+    * DATA ACCESS METHODS:
+    */
+   const ossimEcefPoint&  origin()          const { return theOrigin; }
+   const NEWMAT::Matrix&  lsrToEcefRotMatrix() const
+      { return theLsrToEcefRotMatrix; }
+   NEWMAT::Matrix ecefToLsrRotMatrix() const
+      { return theLsrToEcefRotMatrix.t(); }
+
+   /*!
+    * METHOD: lsrSpaceErrorMessage()
+    * Convenience method accessible to all owners of an ossimLsrSpace for
+    * displaying an error message when LSR spaces do not match between
+    * objects. All operations between LSR objects must be in a common space.
+    */
+   static ostream& lsrSpaceErrorMessage(ostream& os=ossimNotify(ossimNotifyLevel_INFO));
+   
+   /*!
+    * Debug Dump: 
+    */
+   void print(ostream& stream = ossimNotify(ossimNotifyLevel_INFO)) const;
+   
+   friend ostream& operator<< (ostream& os , const ossimLsrSpace& instance)
+      { instance.print(os); return os; }
+
+private:
+   NEWMAT::Matrix   theLsrToEcefRotMatrix;
+   ossimEcefPoint   theOrigin;
+};
+
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrVector.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrVector.cpp
new file mode 100644
index 0000000000..815c79fae0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrVector.cpp
@@ -0,0 +1,119 @@
+//*****************************************************************************
+// FILE: ossimLsrVector.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class 
+//
+// SOFTWARE HISTORY:
+//>
+//   ddmmm2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Log: ossimLsrVector.cpp,v $
+//  Revision 1.2  2004/04/02 22:03:54  gpotts
+//  Fixing all occurences of cout and cerr and CLOG to use the ossimNotify interface.
+//
+//  Revision 1.1  2001/08/13 21:29:18  okramer
+//  Initial delivery of ECEF and LSR suite. (okramer@imagelinks.com)
+//
+
+#include <base/data_types/ossimLsrVector.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/common/ossimCommon.h>
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLsrVector(ossimEcefVector, ossimLsrSpace)
+//  
+//  Establishes an LSR vector given the ECEF equivalent and the LSR space.
+//  
+//*****************************************************************************
+ossimLsrVector::ossimLsrVector(const ossimEcefVector& convert_this,
+                               const ossimLsrSpace&   new_space)
+   : theLsrSpace (new_space)
+{
+   initialize(convert_this);
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLsrVector(ossimLsrVector, ossimLsrSpace)
+//  
+//  Establishes an LSR vector in a new space given another LSR vector in a
+//  different space.
+//  
+//*****************************************************************************
+ossimLsrVector::ossimLsrVector(const ossimLsrVector& convert_this,
+                               const ossimLsrSpace&  new_space)
+   : theLsrSpace (new_space)
+{
+   initialize(ossimEcefVector(convert_this));
+}
+
+//*****************************************************************************
+//  METHOD: ossimLsrVector::dot(ossimLsrVector)
+//  
+//  Computes the scalar product.
+//  
+//*****************************************************************************
+double ossimLsrVector::dot(const ossimLsrVector& v) const
+{
+   if (theLsrSpace == v.theLsrSpace)
+      return theData.dot(v.data());
+
+   //else error:
+   ossimLsrSpace::lsrSpaceErrorMessage();
+   return OSSIM_NAN;
+}
+
+//*****************************************************************************
+//  METHOD: ossimLsrVector::angleTo(ossimLsrVector)
+//  
+//  Returns the angle subtended (in DEGREES) between this and arg vector
+//
+//*****************************************************************************
+double ossimLsrVector::angleTo(const ossimLsrVector& v) const
+{
+   if (theLsrSpace == v.theLsrSpace)
+   {
+      double mag_product = theData.magnitude() * v.theData.magnitude();
+      return acosd(theData.dot(v.theData)/mag_product);
+   }
+   
+   //else error:
+   ossimLsrSpace::lsrSpaceErrorMessage();
+   return OSSIM_NAN;
+}
+
+//*****************************************************************************
+//  METHOD: ossimLsrVector::cross(ossimLsrVector)
+//  
+//  Computes the cross product.
+//  
+//*****************************************************************************
+ossimLsrVector ossimLsrVector::cross(const ossimLsrVector& v) const
+{
+   if (theLsrSpace == v.theLsrSpace)
+      return ossimLsrVector(theData.cross(v.data()), theLsrSpace);
+
+   //else error:
+   ossimLsrSpace::lsrSpaceErrorMessage();
+   return ossimLsrVector(OSSIM_NAN, OSSIM_NAN, OSSIM_NAN, theLsrSpace);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrVector.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrVector.h
new file mode 100644
index 0000000000..bd1d706c54
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimLsrVector.h
@@ -0,0 +1,303 @@
+//*****************************************************************************
+// FILE: ossimLsrVector.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//  Class for representing vectors in some local space rectangular (LSR)
+//  coordinate system. This coordinate system is related to the ECEF system
+//  by the ossimLsrSpace member object. This class simplifies coordinate
+//  conversions between LSR and ECEF, and other LSR vectors.
+//
+// SOFTWARE HISTORY:
+//>
+//   08Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimLsrVector.h,v 1.5 2004/04/02 22:03:54 gpotts Exp $
+
+#ifndef ossimLsrVector_HEADER
+#define ossimLsrVector_HEADER
+
+#include <stdio.h>
+#include <base/data_types/ossimLsrPoint.h>
+#include <base/data_types/ossimLsrSpace.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/data_types/ossimColumnVector3d.h>
+#include <base/context/ossimNotifyContext.h>
+
+class OSSIMDLLEXPORT ossimGpt;
+
+//*****************************************************************************
+//  CLASS: ossimLsrVector
+//
+//*****************************************************************************
+class OSSIMDLLEXPORT ossimLsrVector
+{
+public:
+   /*!
+    * CONSTRUCTORS: 
+    */
+   ossimLsrVector()
+      : theData (0,0,0) {}
+   
+   ossimLsrVector(const ossimLsrVector& copy_this)
+      : theData(copy_this.theData), theLsrSpace(copy_this.theLsrSpace) {}
+
+   ossimLsrVector(const ossimColumnVector3d& assign_this,
+                  const ossimLsrSpace& space)
+      : theData(assign_this), theLsrSpace(space) {}
+   
+   ossimLsrVector(const double& x,
+                  const double& y,
+                  const double& z,
+                  const ossimLsrSpace& space)
+      : theData(x,y,z), theLsrSpace(space) {}
+   
+   ossimLsrVector(const ossimEcefVector& convert_this,
+                  const ossimLsrSpace&);
+   ossimLsrVector(const ossimLsrVector& convert_this,
+                  const ossimLsrSpace&);
+
+   /*!
+    * OPERATORS: (all methods inlined below)
+    */
+   const ossimLsrVector&  operator= (const ossimLsrVector&);
+   ossimLsrVector         operator- ()                      const;
+   ossimLsrVector         operator+ (const ossimLsrVector&) const;
+   ossimLsrVector         operator- (const ossimLsrVector&) const;
+   ossimLsrPoint          operator+ (const ossimLsrPoint&)  const;
+   ossimLsrVector         operator* (const double& scalar)  const;
+   ossimLsrVector         operator/ (const double& scalar)  const;
+   bool                   operator==(const ossimLsrVector&) const;
+   bool                   operator!=(const ossimLsrVector&) const;
+
+   /*!
+    * CASTING OPERATOR:
+    * Used as: myEcefVector = ossimEcefVector(this) -- looks like a constructor
+    * but is an operation on this object. ECEF knows nothing about LSR, so
+    * cannot provide an ossimEcefVector(ossimLsrVector) constructor.
+    */
+   operator ossimEcefVector() const; // inline below
+   
+   /*!
+    * Vector-related functions: 
+    */
+   double                 dot(const ossimLsrVector&)       const;
+   double                 angleTo(const ossimLsrVector&)   const;
+   ossimLsrVector         cross(const ossimLsrVector&)     const;
+   ossimLsrVector         unitVector()                     const;//inline below
+   double                 magnitude()                      const;//inline below
+   void                   normalize(); // inline below
+   
+   /*!
+    * DATA ACCESS METHODS: 
+    */
+   double    x() const { return theData[0]; }
+   double&   x()       { return theData[0]; }
+   double    y() const { return theData[1]; }
+   double&   y()       { return theData[1]; }
+   double    z() const { return theData[2]; }
+   double&   z()       { return theData[2]; }
+
+   ossimColumnVector3d&       data()           { return theData; }
+   const ossimColumnVector3d& data()     const { return theData; }
+
+   ossimLsrSpace&             lsrSpace()       { return theLsrSpace; }
+   const ossimLsrSpace&       lsrSpace() const { return theLsrSpace; }
+
+   /*!
+    * Debug Dump: 
+    */
+   void print(ostream& stream = ossimNotify(ossimNotifyLevel_INFO)) const;
+
+   friend ostream& operator<< (ostream& os , const ossimLsrVector& instance)
+      { instance.print(os); return os; }
+
+protected:
+   /*!
+    * METHOD: initialize(ossimEcefVector)
+    * Convenience method used by several constructors for initializing theData
+    * given an ECEF vector. Assumes theLsrSpace has been previously initialized
+    */
+   void initialize(const ossimEcefVector& ecef_point);
+   
+   ossimColumnVector3d theData;
+   ossimLsrSpace       theLsrSpace;
+
+};
+
+//================== BEGIN DEFINITIONS FOR INLINE METHODS =====================
+
+//*****************************************************************************
+// INLINE OPERATOR: ossimLsrVector::operator=(ossimLsrVector)
+//*****************************************************************************
+inline const ossimLsrVector& ossimLsrVector::operator=(const ossimLsrVector& v)
+{
+   theData = v.theData;
+   theLsrSpace = v.theLsrSpace;
+
+   return *this;
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrVector::operator-() (negate)
+//*****************************************************************************
+inline ossimLsrVector ossimLsrVector::operator-() const
+{
+   return ossimLsrVector(-theData, theLsrSpace);
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrVector::operator+(ossimLsrVector)
+//*****************************************************************************
+inline ossimLsrVector ossimLsrVector::operator+(const ossimLsrVector& v) const
+{
+   if (theLsrSpace == v.theLsrSpace)
+      return ossimLsrVector(theData + v.theData, theLsrSpace);
+
+   //else error:
+   theLsrSpace.lsrSpaceErrorMessage();
+   return ossimLsrVector(OSSIM_NAN, OSSIM_NAN, OSSIM_NAN, theLsrSpace);
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrVector::operator-(ossimLsrVector)
+//*****************************************************************************
+inline ossimLsrVector ossimLsrVector::operator-(const ossimLsrVector& v) const
+{
+   if (theLsrSpace == v.theLsrSpace)
+      return ossimLsrVector(theData - v.data(), theLsrSpace);
+
+   //else error:
+   theLsrSpace.lsrSpaceErrorMessage();
+   return ossimLsrVector(OSSIM_NAN, OSSIM_NAN, OSSIM_NAN, theLsrSpace);
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrVector::operator+(ossimLsrPoint)
+//*****************************************************************************
+inline ossimLsrPoint ossimLsrVector::operator+(const ossimLsrPoint& p) const
+{
+   if (theLsrSpace == p.lsrSpace())
+      return ossimLsrPoint(theData + p.data(), theLsrSpace);
+
+   //else error:
+   theLsrSpace.lsrSpaceErrorMessage();
+   return ossimLsrPoint(OSSIM_NAN, OSSIM_NAN, OSSIM_NAN, theLsrSpace);
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrVector::operator*(double scalar)
+//*****************************************************************************
+inline ossimLsrVector ossimLsrVector::operator*(const double& scalar) const
+{
+   return ossimLsrVector(theData*scalar, theLsrSpace);
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrVector::operator/(double scalar)
+//*****************************************************************************
+inline ossimLsrVector ossimLsrVector::operator/(const double& scalar) const
+{
+   return ossimLsrVector(theData/scalar, theLsrSpace);
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrVector::operator==(ossimLsrVector)
+//*****************************************************************************
+inline bool ossimLsrVector::operator==(const ossimLsrVector& v) const
+{
+   return ((theData == v.theData) && (theLsrSpace == v.theLsrSpace));
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR: ossimLsrVector::operator!=(ossimLsrVector)
+//*****************************************************************************
+inline bool ossimLsrVector::operator!=(const ossimLsrVector& v) const
+{
+   return (!(*this == v));
+}
+
+//*****************************************************************************
+//  INLINE OPERATOR:  ossimEcefVector()
+//
+//  Looks like a constructor for an ossimEcefVector but is an operation on this
+//  object. Returns the ossimEcefVector equivalent.
+//
+//*****************************************************************************
+inline ossimLsrVector::operator ossimEcefVector() const
+{
+   return ossimEcefVector(theLsrSpace.lsrToEcefRotMatrix()*theData);
+}   
+
+//*****************************************************************************
+//  INLINE METHOD:  ossimLsrVector::unitVector()
+//  Returns a unit vector parallel to this.
+//*****************************************************************************
+inline ossimLsrVector ossimLsrVector::unitVector() const
+{
+   return ossimLsrVector(theData/theData.magnitude(), theLsrSpace);
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimLsrVector::magnitude()
+//*****************************************************************************
+inline double ossimLsrVector::magnitude() const
+{
+   return theData.magnitude();
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimLsrVector::normalize()
+//  Normalizes this vector.
+//*****************************************************************************
+inline void ossimLsrVector::normalize()
+{
+   theData /= theData.magnitude();
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimLsrVector::print(ostream)
+//  
+//  Dumps contents for debug purposes.
+//*****************************************************************************
+inline void ossimLsrVector::print(ostream& os) const
+{
+   os << "(ossimLsrVector)\n"
+      << "  theData = " << theData
+      << "\n  theLsrSpace = " << theLsrSpace;
+}
+
+//*****************************************************************************
+//  PROTECTED INLINE METHOD: ossimLsrPoint::initialize(ossimEcefPoint)
+//  
+//  Convenience method used by several constructors for initializing theData
+//  given an ECEF point. Assumes theLsrSpace has been previously initialized.
+//  
+//*****************************************************************************
+inline void ossimLsrVector::initialize(const ossimEcefVector& ecef_vector)
+{
+   theData = theLsrSpace.ecefToLsrRotMatrix() * ecef_vector.data();
+}
+
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix3x3.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix3x3.cpp
new file mode 100644
index 0000000000..442ba1d174
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix3x3.cpp
@@ -0,0 +1,289 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimMatrix3x3.cpp,v 1.13 2005/09/06 16:23:41 gpotts Exp $
+
+#include <base/data_types/ossimMatrix3x3.h>
+#include <matrix/newmatap.h>
+#include <base/data_types/ossimColumnVector3d.h>
+#include <base/common/ossimConstants.h>
+
+NEWMAT::Matrix ossimMatrix3x3::create()
+{
+   NEWMAT::Matrix m(3, 3);
+   
+   m[0][0] = 1.0;
+   m[0][1] = 0.0;
+   m[0][2] = 0.0;
+   
+   m[1][0] = 0.0;
+   m[1][1] = 1.0;
+   m[1][2] = 0.0;
+   
+   m[2][0] = 0.0;
+   m[2][1] = 0.0;
+   m[2][2] = 1.0;
+
+   return m;
+}
+
+NEWMAT::Matrix ossimMatrix3x3::create(double v00, double v01, double v02,
+                                      double v10, double v11, double v12,
+                                      double v20, double v21, double v22)
+{
+   NEWMAT::Matrix m(3, 3);
+   
+   m[0][0] = v00;
+   m[0][1] = v01;
+   m[0][2] = v02;
+   
+   m[1][0] = v10;
+   m[1][1] = v11;
+   m[1][2] = v12;
+   
+   m[2][0] = v20;
+   m[2][1] = v21;
+   m[2][2] = v22;
+
+   return m;
+}
+
+NEWMAT::Matrix ossimMatrix3x3::create(const NEWMAT::Matrix& rhs)
+{
+   NEWMAT::Matrix m(3, 3);
+
+   if (rhs.Ncols() != 3 || rhs.Nrows() != 3)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "ossimMatrix3x3::create(const NEWMAT::Matrix& rhs) ERROR:"
+                                          << "\nMatrix passed to function not a 3x3!"
+                                          << "\nnumber of columns:  " << rhs.Ncols()
+                                          << "\nnumber of rows:     " << rhs.Nrows()
+                                          << "\nReturn blank 3x3 matrix...\n";
+      return m;
+   }
+   
+   m[0][0] = rhs[0][0];
+   m[0][1] = rhs[0][1];
+   m[0][2] = rhs[0][2];
+   m[0][3] = rhs[0][3];
+   m[1][0] = rhs[1][0];
+   m[1][1] = rhs[1][1];
+   m[1][2] = rhs[1][2];
+   m[1][3] = rhs[1][3];
+   m[2][0] = rhs[2][0];
+   m[2][1] = rhs[2][1];
+   m[2][2] = rhs[2][2];
+   m[2][3] = rhs[2][3];
+
+   return m;
+}
+
+ossimColumnVector3d ossimMatrix3x3::getEigenValues(const NEWMAT::Matrix& matrix)
+{
+   if (matrix.Ncols() != 3 || matrix.Nrows() != 3)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: ossimColumnVector3d operator*(const NEWMAT::Matrix& lhs,"
+                                          << "\nconst ossimColumnVector3d& rhs), "
+                                          << "\nMatrix passed to function not a 3x3!"
+                                          << "\nnumber of columns:  " << matrix.Ncols()
+                                          << "\nnumber of rows:     " << matrix.Nrows()
+                                          << "\nReturn blank ossimColumnVector3d...\n";
+      return ossimColumnVector3d();
+   }
+
+   NEWMAT::DiagonalMatrix d;
+   NEWMAT::SymmetricMatrix s;
+   
+   s << matrix;
+   
+   EigenValues(s, d);
+   
+   return ossimColumnVector3d(d[0], d[1], d[2]);
+}
+
+NEWMAT::Matrix ossimMatrix3x3::createIdentity()
+{
+   NEWMAT::Matrix m(3,3);
+
+   m[0][0] = 1.0;
+   m[0][1] = 0.0;
+   m[0][2] = 0.0;
+   
+   m[1][0] = 0.0;
+   m[1][1] = 1.0;
+   m[1][2] = 0.0;
+   
+   m[2][0] = 0.0;
+   m[2][1] = 0.0;
+   m[2][2] = 1.0;
+   
+   return m;
+}
+
+NEWMAT::Matrix ossimMatrix3x3::createZero()
+{
+  NEWMAT::Matrix m(3,3);
+
+  m = 0.0;
+
+  return m;
+}
+
+NEWMAT::Matrix ossimMatrix3x3::createTranslationMatrix(double dx,double dy)
+{
+  NEWMAT::Matrix m(3,3);
+
+   m[0][0] = 1.0;
+   m[0][1] = 0.0;
+   m[0][2] = dx;
+   
+   m[1][0] = 0.0;
+   m[1][1] = 1.0;
+   m[1][2] = dy;
+   
+   m[2][0] = 0.0;
+   m[2][1] = 0.0;
+   m[2][2] = 1.0;
+
+   return m;
+}
+
+NEWMAT::Matrix ossimMatrix3x3::createRotationMatrix(double angleX,
+                                                    double angleY,
+                                                    double angleZ,
+                                                    ossimCoordSysOrientMode orientationMode)
+{
+   return (createRotationZMatrix(angleZ, orientationMode)*
+           createRotationYMatrix(angleY, orientationMode)*
+           createRotationXMatrix(angleX, orientationMode));
+}
+
+NEWMAT::Matrix ossimMatrix3x3::createRotationXMatrix(double angle,
+                                                     ossimCoordSysOrientMode orientationMode)
+{
+  NEWMAT::Matrix m(3,3);
+  double Cosine = cos(angle*RAD_PER_DEG);
+  double Sine   = sin(angle*RAD_PER_DEG);
+
+  if(orientationMode == OSSIM_RIGHT_HANDED)
+  {
+     m << 1 << 0      << 0
+       << 0 << Cosine << Sine
+       << 0 << -Sine  << Cosine;
+  }
+  else
+  {
+     m << 1 << 0      << 0
+       << 0 << Cosine << -Sine
+       << 0 << Sine  << Cosine;
+  }
+  return m;
+}
+
+NEWMAT::Matrix ossimMatrix3x3::createRotationYMatrix(double angle,
+                                                     ossimCoordSysOrientMode orientationMode)
+{
+   NEWMAT::Matrix m(3,3);
+   double Cosine = cos(angle*RAD_PER_DEG);
+   double Sine   = sin(angle*RAD_PER_DEG);
+   
+  if(orientationMode == OSSIM_RIGHT_HANDED)
+  {
+     m[0][0] = Cosine;
+     m[0][1] = 0.0;
+     m[0][2] = -Sine;
+     
+     m[1][0] = 0.0;
+     m[1][1] = 1.0;
+     m[1][2] = 0.0;
+     
+     m[2][0] = Sine;
+     m[2][1] = 0.0;
+     m[2][2] = Cosine;
+  }
+  else
+  {
+     m[0][0] = Cosine;
+     m[0][1] = 0.0;
+     m[0][2] = Sine;
+     
+     m[1][0] = 0.0;
+     m[1][1] = 1.0;
+     m[1][2] = 0.0;
+     
+     m[2][0] = -Sine;
+     m[2][1] = 0.0;
+     m[2][2] = Cosine;
+  }
+  return m;
+}
+
+
+NEWMAT::Matrix ossimMatrix3x3::createRotationZMatrix(double angle,
+                                                     ossimCoordSysOrientMode orientationMode)
+{
+   NEWMAT::Matrix m(3,3);
+   double Cosine = cos(angle*RAD_PER_DEG);
+   double Sine   = sin(angle*RAD_PER_DEG);
+   
+  if(orientationMode == OSSIM_RIGHT_HANDED)
+  {
+     m[0][0] = Cosine;
+     m[0][1] = Sine;
+     m[0][2] = 0.0;
+     
+     m[1][0] = -Sine;
+     m[1][1] = Cosine;
+     m[1][2] = 0.0;
+     
+     m[2][0] = 0.0;
+     m[2][1] = 0.0;
+     m[2][2] = 1.0;
+  }
+  else
+  {
+     m[0][0] = Cosine;
+     m[0][1] = -Sine;
+     m[0][2] = 0.0;
+     
+     m[1][0] = Sine;
+     m[1][1] = Cosine;
+     m[1][2] = 0.0;
+     
+     m[2][0] = 0.0;
+     m[2][1] = 0.0;
+     m[2][2] = 1.0;
+  }
+  return m;
+}
+
+NEWMAT::Matrix ossimMatrix3x3::createScaleMatrix(double x, double y, double z)
+{
+    NEWMAT::Matrix m = createIdentity();
+
+    m[0][0] = x;
+    m[1][1] = y;
+    m[2][2] = z;
+
+    return m;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix3x3.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix3x3.h
new file mode 100644
index 0000000000..9c6c023dd7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix3x3.h
@@ -0,0 +1,96 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Helper class for using NEWMAT::Matrix's.
+//
+//*******************************************************************
+//  $Id: ossimMatrix3x3.h,v 1.14 2005/09/06 16:23:41 gpotts Exp $
+
+#ifndef ossimMatrix3x3_HEADER
+#define ossimMatrix3x3_HEADER
+
+#include <iostream>
+
+#include "matrix/newmat.h"
+#include "matrix/newmatio.h"
+#include "base/common/ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimColumnVector3d;
+
+class OSSIMDLLEXPORT ossimMatrix3x3
+{
+ public:
+
+   
+   /*!
+    *  Uses the matrix package to compute the eigenvalues for this
+    *  matrix
+    */ 
+   ossimColumnVector3d getEigenValues(const NEWMAT::Matrix& rhs);
+
+   /*!
+    *  Returns a blank 3x3 matrix.
+    */
+   static NEWMAT::Matrix create();
+
+   /*!
+    *  Returns a copy of "m".
+    *  Note:
+    *  If "m" is not a 3x3 that's an error and a blank matrix is returned.
+    */
+   static NEWMAT::Matrix create(const NEWMAT::Matrix& m);
+
+   /*!
+    *  Create a 3x3 with assigned values.
+    */
+   static NEWMAT::Matrix create(double v00, double v01, double v02,
+                                double v10, double v11, double v12,
+                                double v20, double v21, double v22);
+   
+   static NEWMAT::Matrix createIdentity();
+   
+   static NEWMAT::Matrix createZero();
+   static NEWMAT::Matrix createRotationMatrix(double angleX,
+                                              double angleY,
+                                              double angleZ,
+                                              ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED);
+   static NEWMAT::Matrix createRotationXMatrix(double angle,
+                                               ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED);
+   static NEWMAT::Matrix createRotationYMatrix(double angle,
+                                               ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED);
+   static NEWMAT::Matrix createRotationZMatrix(double angle,
+                                               ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED);
+
+   static NEWMAT::Matrix createScaleMatrix(double X, double Y, double Z);
+
+   static NEWMAT::Matrix createTranslationMatrix(double dx,double dy);
+   
+protected:
+   ossimMatrix3x3(){}  // To squash un-warranted compiler warnings...
+   
+private:
+   ossimMatrix3x3(const ossimMatrix3x3& rhs){}
+   const ossimMatrix3x3& operator=(const ossimMatrix3x3& rhs){ return rhs; }
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix4x4.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix4x4.cpp
new file mode 100644
index 0000000000..16ea57bcb9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix4x4.cpp
@@ -0,0 +1,298 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for locpt.  This uses geotrans
+// local cartesian implementation.
+//*******************************************************************
+//  $Id: ossimMatrix4x4.cpp,v 1.6 2005/09/06 16:23:41 gpotts Exp $
+
+#include "ossimMatrix4x4.h"
+#include "matrix/newmatap.h"
+#include "base/common/ossimConstants.h"
+
+ossimMatrix4x4::ossimMatrix4x4(const NEWMAT::Matrix& m)
+   :theData(4,4)
+{
+   if((m.Nrows() == 4) &&
+      (m.Ncols() == 4))
+   {
+      theData = m;
+   }
+   else if((m.Nrows()==3)&&
+           (m.Ncols()==3))
+   {
+      theData[0][0] = m[0][0];
+      theData[0][1] = m[0][1];
+      theData[0][2] = m[0][2];
+      theData[0][3] = 0.0;
+      theData[1][0] = m[1][0];
+      theData[1][1] = m[1][1];
+      theData[1][2] = m[1][2];
+      theData[1][3] = 0.0;
+      theData[2][0] = m[2][0];
+      theData[2][1] = m[2][1];
+      theData[2][2] = m[2][2];
+      theData[2][3] = 0.0;
+      theData[3][0] = 0.0;
+      theData[3][1] = 0.0;
+      theData[3][2] = 0.0;
+      theData[3][3] = 1.0;
+   }
+   else
+   {
+      theData[0][0] = 1.0;
+      theData[0][1] = 0.0;
+      theData[0][2] = 0.0;
+      theData[0][3] = 0.0;
+      
+      theData[1][0] = 0.0;
+      theData[1][1] = 1.0;
+      theData[1][2] = 0.0;
+      theData[1][3] = 0.0;
+      
+      theData[2][0] = 0.0;
+      theData[2][1] = 0.0;
+      theData[2][2] = 1.0;
+      theData[2][3] = 0.0;
+      
+      theData[3][0] = 0.0;
+      theData[3][1] = 0.0;
+      theData[3][2] = 0.0;
+      theData[3][3] = 1.0;
+   }
+}
+
+ossimMatrix4x4::ossimMatrix4x4()
+  :theData(4, 4)
+{
+  theData[0][0] = 1.0;
+  theData[0][1] = 0.0;
+  theData[0][2] = 0.0;
+  theData[0][3] = 0.0;
+
+  theData[1][0] = 0.0;
+  theData[1][1] = 1.0;
+  theData[1][2] = 0.0;
+  theData[1][3] = 0.0;
+
+  theData[2][0] = 0.0;
+  theData[2][1] = 0.0;
+  theData[2][2] = 1.0;
+  theData[2][3] = 0.0;
+
+  theData[3][0] = 0.0;
+  theData[3][1] = 0.0;
+  theData[3][2] = 0.0;
+  theData[3][3] = 1.0;
+}
+
+ossimMatrix4x4::ossimMatrix4x4(double v00, double v01, double v02, double v03,
+                               double v10, double v11, double v12, double v13,
+                               double v20, double v21, double v22, double v23,
+                               double v30, double v31, double v32, double v33)
+  :theData(4, 4)
+{
+  theData[0][0] = v00;
+  theData[0][1] = v01;
+  theData[0][2] = v02;
+  theData[0][3] = v03;
+
+  theData[1][0] = v10;
+  theData[1][1] = v11;
+  theData[1][2] = v12;
+  theData[1][3] = v13;
+
+  theData[2][0] = v20;
+  theData[2][1] = v21;
+  theData[2][2] = v22;
+  theData[2][3] = v23;
+
+  theData[3][0] = v30;
+  theData[3][1] = v31;
+  theData[3][2] = v32;
+  theData[3][3] = v33;
+}
+
+ossimColumnVector3d ossimMatrix4x4::getEigenValues()const
+{
+  NEWMAT::DiagonalMatrix d;
+  NEWMAT::SymmetricMatrix s;
+
+  s << theData;
+
+  EigenValues(s, d);
+
+  return ossimColumnVector3d(d[0], d[1], d[2]);
+}
+
+NEWMAT::Matrix ossimMatrix4x4::createIdentity()
+{
+  ossimMatrix4x4 m(1.0, 0.0, 0.0, 0.0, 
+                   0.0, 1.0, 0.0, 0.0,
+                   0.0, 0.0, 1.0, 0.0,
+                   0.0, 0.0, 0.0, 1.0);
+    
+  return m.getData();
+}
+
+NEWMAT::Matrix ossimMatrix4x4::createRotateOnly(const ossimMatrix4x4 &aMatrix)
+{
+  ossimMatrix4x4 m = aMatrix;
+
+  m.theData[0][3] = 0;
+  m.theData[1][3] = 0;
+  m.theData[2][3] = 0;
+  m.theData[3][3] = 1.0;
+
+  m.theData[3][0] = 0.0;
+  m.theData[3][1] = 0.0;
+  m.theData[3][2] = 0.0;
+  m.theData[3][3] = 1.0;
+
+  return m.getData();
+}
+
+NEWMAT::Matrix ossimMatrix4x4::createZero()
+{
+  ossimMatrix4x4 m;
+
+  m.getData() = 0.0;
+
+  return m.getData();
+}
+
+NEWMAT::Matrix ossimMatrix4x4::createTranslationMatrix(double x,
+                                                       double y,
+                                                       double z) 
+{
+   ossimMatrix4x4 m(1.0, 0.0, 0.0, x,
+                    0.0, 1.0, 0.0, y,
+                    0.0, 0.0, 1.0, z,
+                    0.0, 0.0, 0.0, 1.0);
+   
+   return m.getData();
+}
+
+NEWMAT::Matrix ossimMatrix4x4::createRotationMatrix(double angleX,
+                                                    double angleY,
+                                                    double angleZ,
+                                                    ossimCoordSysOrientMode orientationMode)
+{
+  return (createRotationZMatrix(angleZ,
+                                orientationMode)*
+	  createRotationYMatrix(angleY,
+                                orientationMode)*
+	  createRotationXMatrix(angleX,
+                                orientationMode));
+}
+
+NEWMAT::Matrix ossimMatrix4x4::createRotationXMatrix(double angle,
+                                                     ossimCoordSysOrientMode orientationMode)
+{
+   NEWMAT::Matrix m(4,4);
+   
+   double Cosine = cos(angle*RAD_PER_DEG);
+   double Sine   = sin(angle*RAD_PER_DEG);
+   
+   if(orientationMode == OSSIM_RIGHT_HANDED)
+   {
+      m << 1.0 << 0.0 << 0.0 << 0.0
+        << 0.0 << Cosine << Sine << 0.0
+        << 0.0 << -Sine  << Cosine << 0.0
+        << 0.0 << 0.0 << 0.0 << 1.0;
+   }
+   else
+   {
+      m << 1.0 << 0.0 << 0.0 << 0.0
+        << 0.0 << Cosine << -Sine << 0.0
+        << 0.0 << Sine  << Cosine << 0.0
+        << 0.0 << 0.0 << 0.0 << 1.0;
+   }
+  
+   return m;
+}
+
+NEWMAT::Matrix ossimMatrix4x4::createRotationYMatrix(double angle,
+                                                     ossimCoordSysOrientMode orientationMode)
+{
+   NEWMAT::Matrix m(4,4);
+   
+   double Cosine = cos(angle*RAD_PER_DEG);
+   double Sine   = sin(angle*RAD_PER_DEG);
+   
+   if(orientationMode == OSSIM_RIGHT_HANDED)
+   {
+      m << Cosine << 0.0 << -Sine  << 0.0
+        << 0.0    << 1.0 << 0.0    << 0.0
+        << Sine   << 0.0 << Cosine << 0.0
+        << 0.0    << 0.0 << 0.0    << 1.0;
+   }
+   else
+   {
+      m << Cosine << 0.0 << Sine   << 0.0
+        << 0.0    << 1.0 << 0.0    << 0.0
+        << -Sine  << 0.0 << Cosine << 0.0
+        << 0.0    << 0.0 << 0.0    << 1.0;
+   }
+   
+  return m;
+}
+
+
+NEWMAT::Matrix ossimMatrix4x4::createRotationZMatrix(double angle,
+                                                     ossimCoordSysOrientMode orientationMode)
+{
+   NEWMAT::Matrix m(4,4);
+   
+   double Cosine = cos(angle*RAD_PER_DEG);
+   double Sine   = sin(angle*RAD_PER_DEG);
+   
+   if(orientationMode == OSSIM_RIGHT_HANDED)
+   {
+      m << Cosine << Sine   << 0.0 << 0.0
+        << -Sine  << Cosine << 0.0 << 0.0
+        << 0.0    << 0.0    << 1.0 << 0.0
+        << 0.0    << 0.0    << 0.0 << 1.0;
+   }
+   else
+   {
+      m << Cosine << -Sine   << 0.0 << 0.0
+        << Sine   << Cosine << 0.0 << 0.0
+        << 0.0    << 0.0    << 1.0 << 0.0
+        << 0.0    << 0.0    << 0.0 << 1.0;
+   }
+   
+   return m;
+}
+
+
+NEWMAT::Matrix ossimMatrix4x4::createScaleMatrix(double x, double y, double z)
+{
+   NEWMAT::Matrix m(4, 4);
+   
+      m << x   << 0.0 << 0.0 << 0.0
+        << 0.0 << y   << 0.0 << 0.0
+        << 0.0 << 0.0 << z   << 0.0
+        << 0.0 << 0.0 << 0.0 << 1.0;
+
+    return m;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix4x4.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix4x4.h
new file mode 100644
index 0000000000..9c4a48e708
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimMatrix4x4.h
@@ -0,0 +1,283 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimMatrix4x4.h,v 1.10 2005/09/06 16:23:41 gpotts Exp $
+
+#ifndef ossimMatrix4x4_HEADER
+#define ossimMatrix4x4_HEADER
+#include <iostream>
+#include "matrix/newmat.h"
+#include "matrix/newmatio.h"
+#include "ossimColumnVector4d.h"
+#include "ossimColumnVector3d.h"
+
+class OSSIMDLLEXPORT ossimMatrix4x4
+{
+ public:
+   friend std::ostream& operator<<(std::ostream& out,
+                                   const ossimMatrix4x4& data)
+    {
+      return out << data.getData();
+    }
+  ossimMatrix4x4();
+  ossimMatrix4x4(const NEWMAT::Matrix& m);
+  ossimMatrix4x4(double v00, double v01, double v02, double v03,
+                 double v10, double v11, double v12, double v13,
+                 double v20, double v21, double v22, double v23,
+                 double v30, double v31, double v32, double v33);
+  ossimMatrix4x4(const ossimMatrix4x4& rhs)
+    :theData(4,4)
+    {
+      theData[0][0] = rhs.theData[0][0];
+      theData[0][1] = rhs.theData[0][1];
+      theData[0][2] = rhs.theData[0][2];
+      theData[0][3] = rhs.theData[0][3];
+      theData[1][0] = rhs.theData[1][0];
+      theData[1][1] = rhs.theData[1][1];
+      theData[1][2] = rhs.theData[1][2];
+      theData[1][3] = rhs.theData[1][3];
+      theData[2][0] = rhs.theData[2][0];
+      theData[2][1] = rhs.theData[2][1];
+      theData[2][2] = rhs.theData[2][2];
+      theData[2][3] = rhs.theData[2][3];
+      theData[3][0] = rhs.theData[3][0];
+      theData[3][1] = rhs.theData[3][1];
+      theData[3][2] = rhs.theData[3][2];
+      theData[3][3] = rhs.theData[3][3];
+    }
+  ossimMatrix4x4 operator+ (const ossimMatrix4x4& rhs)const
+    {
+      return ossimMatrix4x4(theData[0][0] + rhs.theData[0][0], theData[0][1] + rhs.theData[0][1], theData[0][2] + rhs.theData[0][2], theData[0][3] + rhs.theData[0][3],
+                            theData[1][0] + rhs.theData[1][0], theData[1][1] + rhs.theData[1][1], theData[1][2] + rhs.theData[1][2], theData[1][3] + rhs.theData[1][3],
+                            theData[2][0] + rhs.theData[2][0], theData[2][1] + rhs.theData[2][1], theData[2][2] + rhs.theData[2][2], theData[2][3] + rhs.theData[2][3],
+                            theData[3][0] + rhs.theData[3][0], theData[3][1] + rhs.theData[3][1], theData[3][2] + rhs.theData[3][2], theData[3][3] + rhs.theData[3][3]);
+    }
+  ossimMatrix4x4 operator- (const ossimMatrix4x4& rhs)const
+    {
+      return ossimMatrix4x4(theData[0][0] - rhs.theData[0][0], theData[0][1] - rhs.theData[0][1], theData[0][2] - rhs.theData[0][2], theData[0][3] - rhs.theData[0][3],
+                            theData[1][0] - rhs.theData[1][0], theData[1][1] - rhs.theData[1][1], theData[1][2] - rhs.theData[1][2], theData[1][3] - rhs.theData[1][3],
+                            theData[2][0] - rhs.theData[2][0], theData[2][1] - rhs.theData[2][1], theData[2][2] - rhs.theData[2][2], theData[2][3] - rhs.theData[2][3],
+                            theData[3][0] - rhs.theData[3][0], theData[3][1] - rhs.theData[3][1], theData[3][2] - rhs.theData[3][2], theData[3][3] - rhs.theData[3][3]);
+    }
+  friend ossimColumnVector4d operator * (const ossimMatrix4x4& lhs, const ossimColumnVector4d& rhs)
+      {
+         return ossimColumnVector4d( (lhs.theData[0][0]*rhs[0] + lhs.theData[0][1]*rhs[1] + lhs.theData[0][2]*rhs[2] + lhs.theData[0][3]*rhs[3]),
+                                     (lhs.theData[1][0]*rhs[0] + lhs.theData[1][1]*rhs[1] + lhs.theData[1][2]*rhs[2] + lhs.theData[1][3]*rhs[3]),
+                                     (lhs.theData[2][0]*rhs[0] + lhs.theData[2][1]*rhs[1] + lhs.theData[2][2]*rhs[2] + lhs.theData[2][3]*rhs[3]),
+                                     (lhs.theData[3][0]*rhs[0] + lhs.theData[3][1]*rhs[1] + lhs.theData[3][2]*rhs[2] + lhs.theData[3][3]*rhs[3]));
+      
+    }
+   friend ossimColumnVector3d operator * (const ossimMatrix4x4& lhs, const ossimColumnVector3d& rhs)
+      {
+         // assume the 4 coordinate (homogeneous coord) of the 3d vector is 1
+         return ossimColumnVector3d( (lhs.theData[0][0]*rhs[0] + lhs.theData[0][1]*rhs[1] + lhs.theData[0][2]*rhs[2] + lhs.theData[0][3]),
+                                     (lhs.theData[1][0]*rhs[0] + lhs.theData[1][1]*rhs[1] + lhs.theData[1][2]*rhs[2] + lhs.theData[1][3]),
+                                     (lhs.theData[2][0]*rhs[0] + lhs.theData[2][1]*rhs[1] + lhs.theData[2][2]*rhs[2] + lhs.theData[2][3]));         
+      }
+   ossimColumnVector4d rotateOnly(const ossimColumnVector4d& rhs)const
+      {
+         // multiply only by the 3x3 submatrix.
+         return ossimColumnVector4d( (theData[0][0]*rhs[0] + theData[0][1]*rhs[1] + theData[0][2]*rhs[2]),
+                                     (theData[1][0]*rhs[0] + theData[1][1]*rhs[1] + theData[1][2]*rhs[2]),
+                                     (theData[2][0]*rhs[0] + theData[2][1]*rhs[1] + theData[2][2]*rhs[2]));         
+      }
+   ossimColumnVector3d rotateOnly(const ossimColumnVector3d& rhs)const
+      {
+         // assume the 4 coordinate (homogeneous coord) of the 3d vector is 1
+         return ossimColumnVector3d( (theData[0][0]*rhs[0] + theData[0][1]*rhs[1] + theData[0][2]*rhs[2]),
+                                     (theData[1][0]*rhs[0] + theData[1][1]*rhs[1] + theData[1][2]*rhs[2]),
+                                     (theData[2][0]*rhs[0] + theData[2][1]*rhs[1] + theData[2][2]*rhs[2]));
+      }
+   ossimMatrix4x4 operator*(double scalar)const
+      {
+         return ossimMatrix4x4(theData[0][0]*scalar, theData[0][1]*scalar, theData[0][2]*scalar, theData[0][3]*scalar,
+                               theData[1][0]*scalar, theData[1][1]*scalar, theData[1][2]*scalar, theData[1][3]*scalar,
+                               theData[2][0]*scalar, theData[2][1]*scalar, theData[2][2]*scalar, theData[2][3]*scalar,
+                               theData[0][0]*scalar, theData[0][1]*scalar, theData[0][2]*scalar, theData[0][3]*scalar);
+         
+      }
+   ossimMatrix4x4 operator*(const ossimMatrix4x4& rhs)const
+      {
+         ossimMatrix4x4 m;
+         
+         // element 0,0 is first row time first column
+         m.theData[0][0] = (theData[0][0]*rhs.theData[0][0] +
+                         theData[0][1]*rhs.theData[1][0] +
+                         theData[0][2]*rhs.theData[2][0] +
+                         theData[0][3]*rhs.theData[3][0]);
+         
+         // element 0, 1 is first row second column
+         m.theData[0][1] = (theData[0][0]*rhs.theData[0][1] +
+                         theData[0][1]*rhs.theData[1][1] +
+                         theData[0][2]*rhs.theData[2][1] +
+                         theData[0][3]*rhs.theData[3][1]);
+         
+         // element 0, 2 is first row third column
+         m.theData[0][2] = (theData[0][0]*rhs.theData[0][2] +
+                         theData[0][1]*rhs.theData[1][2] +
+                         theData[0][2]*rhs.theData[2][2] +
+                         theData[0][3]*rhs.theData[3][2]);
+         
+         // element 0, 3 is first row fourth column
+         m.theData[0][3] = (theData[0][0]*rhs.theData[0][3] +
+                         theData[0][1]*rhs.theData[1][3] +
+                         theData[0][2]*rhs.theData[2][3] +
+                         theData[0][3]*rhs.theData[3][3]);
+         
+         // element 1, 0 is second row first column
+         m.theData[1][0] = (theData[1][0]*rhs.theData[0][0] +
+                         theData[1][1]*rhs.theData[1][0] +
+                         theData[1][2]*rhs.theData[2][0] +
+                         theData[1][3]*rhs.theData[3][0]);
+         
+         // element 1, 1 is second row second column
+         m.theData[1][1] = (theData[1][0]*rhs.theData[0][1] +
+                         theData[1][1]*rhs.theData[1][1] +
+                         theData[1][2]*rhs.theData[2][1] +
+                         theData[1][3]*rhs.theData[3][1]);
+         
+         // element 1, 2 is second row third column
+         m.theData[1][2] = (theData[1][0]*rhs.theData[0][2] +
+                         theData[1][1]*rhs.theData[1][2] +
+                         theData[1][2]*rhs.theData[2][2] +
+                         theData[1][3]*rhs.theData[3][2]);
+         
+         // element 1, 3 is second row fourth column
+         m.theData[1][3] = (theData[1][0]*rhs.theData[0][3] +
+                         theData[1][1]*rhs.theData[1][3] +
+                         theData[1][2]*rhs.theData[2][3] +
+                         theData[1][3]*rhs.theData[3][3]);
+         
+         // element 2, 0 is third row first column
+         m.theData[2][0] = (theData[2][0]*rhs.theData[0][0] +
+                         theData[2][1]*rhs.theData[1][0] +
+                         theData[2][2]*rhs.theData[2][0] +
+                         theData[2][3]*rhs.theData[3][0]);
+         
+         // element 2, 1 is third row second column
+         m.theData[2][1] = (theData[2][0]*rhs.theData[0][1] +
+                         theData[2][1]*rhs.theData[1][1] +
+                         theData[2][2]*rhs.theData[2][1] +
+                         theData[2][3]*rhs.theData[3][1]);
+         
+         // element 2, 2 is third row third column
+         m.theData[2][2] = (theData[2][0]*rhs.theData[0][2] +
+                         theData[2][1]*rhs.theData[1][2] +
+                         theData[2][2]*rhs.theData[2][2] +
+                         theData[2][3]*rhs.theData[3][2]);
+         
+         // element 2, 3 is third row fourth column
+         m.theData[2][3] = (theData[2][0]*rhs.theData[0][3] +
+                         theData[2][1]*rhs.theData[1][3] +
+                         theData[2][2]*rhs.theData[2][3] +
+                         theData[2][3]*rhs.theData[3][3]);
+         
+         // element 3, 0 is fourth row first column
+         m.theData[3][0] = (theData[3][0]*rhs.theData[0][0] +
+                         theData[3][1]*rhs.theData[1][0] +
+                         theData[3][2]*rhs.theData[2][0] +
+                         theData[3][3]*rhs.theData[3][0]);
+         
+         // element 3, 1 is fourth row second column
+         m.theData[3][1] = (theData[3][0]*rhs.theData[0][1] +
+                         theData[3][1]*rhs.theData[1][1] +
+                         theData[3][2]*rhs.theData[2][1] +
+                         theData[3][3]*rhs.theData[3][1]);
+         
+         // element 3, 2 is fourth row third column
+         m.theData[3][2] = (theData[3][0]*rhs.theData[0][2] +
+                         theData[3][1]*rhs.theData[1][2] +
+                         theData[3][2]*rhs.theData[2][2] +
+                         theData[3][3]*rhs.theData[3][2]);
+         
+         // element 3, 3 is fourth row fourth column
+         m.theData[3][3] = (theData[3][0]*rhs.theData[0][3] +
+                         theData[3][1]*rhs.theData[1][3] +
+                         theData[3][2]*rhs.theData[2][3] +
+                         theData[3][3]*rhs.theData[3][3]);
+         
+         return m;
+      }
+
+   /*!
+    * uses the matrix package to compute the inverse
+    */
+   ossimMatrix4x4& i()
+      {
+         theData = theData.i();
+         
+         return *this;
+      }
+   
+   /*!
+    * Uses the matrix package to compute the transpose.
+    */
+   ossimMatrix4x4& t()
+      {        
+         theData = theData.t();
+
+         return *this;
+      }
+   
+   /*!
+    * uses the matrix package to compute the determinant
+    */
+   double getDeterminant()const
+      {
+         return theData.Determinant();
+      }
+   
+   /*!
+    * Uses the matrix package to compute the eigenvalues for this
+    * matrix
+    */ 
+   ossimColumnVector3d getEigenValues()const;
+   
+   static NEWMAT::Matrix createIdentity();
+   static NEWMAT::Matrix createRotateOnly(const ossimMatrix4x4& aMatrix);
+  
+   static NEWMAT::Matrix createZero();
+   static NEWMAT::Matrix createTranslationMatrix(double x,
+                                                 double y,
+                                                 double z);
+   static NEWMAT::Matrix createRotationMatrix(double angleX,
+                                              double angleY,
+                                              double angleZ,
+                                              ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED);
+   static NEWMAT::Matrix createRotationXMatrix(double angle,
+                                               ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED);
+   static NEWMAT::Matrix createRotationYMatrix(double angle,
+                                               ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED);
+   static NEWMAT::Matrix createRotationZMatrix(double angle,
+                                               ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED);
+   
+   static NEWMAT::Matrix createScaleMatrix(double X, double Y, double Z);
+   
+  const NEWMAT::Matrix& getData()const{return theData;}
+  NEWMAT::Matrix& getData(){return theData;}
+
+private:
+  NEWMAT::Matrix theData; 
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiBandHistogram.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiBandHistogram.cpp
new file mode 100644
index 0000000000..d6e926dfef
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiBandHistogram.cpp
@@ -0,0 +1,400 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description: 
+//
+//*******************************************************************
+//  $Id: ossimMultiBandHistogram.cpp,v 1.14 2003/09/09 18:33:57 dburken Exp $
+#include "ossimMultiBandHistogram.h"
+#include "ossimHistogram.h"
+#include "ossimKeywordlist.h"
+
+#include <fstream>
+using namespace std;
+
+ossimMultiBandHistogram::ossimMultiBandHistogram()
+{  
+}
+
+ossimMultiBandHistogram::~ossimMultiBandHistogram()
+{
+   deleteHistograms();
+}
+
+ossimMultiBandHistogram::ossimMultiBandHistogram(const ossimMultiBandHistogram& rhs)
+{
+   theHistogramList.resize(rhs.theHistogramList.size());
+
+   for(ossim_uint32 i = 0; i < theHistogramList.size(); ++i)
+   {
+      theHistogramList[i] =  rhs.theHistogramList[i]?
+                             new ossimHistogram(*rhs.theHistogramList[i]):
+                             (ossimHistogram*)NULL;
+   }
+}
+
+ossimMultiBandHistogram::ossimMultiBandHistogram(long numberOfBands,
+                                                 long numberOfBuckets,
+                                                 float minValue,
+                                                 float maxValue)
+{
+   if(numberOfBands > 0)
+   {
+      create(numberOfBands, numberOfBuckets, minValue, maxValue);
+   }
+}
+
+void ossimMultiBandHistogram::create(long numberOfBands,
+                                                   long numberOfBuckets,
+                                                   float minValue,
+                                                   float maxValue)
+{
+   // make sure we clear our internal lists before
+   // we start.
+   //
+   deleteHistograms();
+
+   if(numberOfBands > 0)
+   {
+      numberOfBuckets = numberOfBuckets>0?numberOfBuckets:1;
+
+      for(long bands = 0; bands < numberOfBands; ++bands)
+      {
+         theHistogramList.push_back(new ossimHistogram(numberOfBuckets,
+                                                       minValue,
+                                                       maxValue));
+      }
+   }
+}
+
+void ossimMultiBandHistogram::create(long numberOfBands)
+{
+   deleteHistograms();
+   for(long bands = 0; bands < numberOfBands; ++bands)
+   {
+      theHistogramList.push_back(new ossimHistogram);
+   }
+}
+
+ossim_uint32 ossimMultiBandHistogram::getNumberOfBands() const
+{
+   return theHistogramList.size();
+}
+
+ossimHistogram* ossimMultiBandHistogram::getHistogram(long band)
+{
+   if((band >=0) && (band < (long)theHistogramList.size()))
+   {
+      return theHistogramList[band];
+   }
+
+   return NULL;
+}
+
+void ossimMultiBandHistogram::setBinCount(double binNumber, double count)
+{
+   if(theHistogramList.size() > 0)
+   {
+      for(long idx = 0; idx < (long)theHistogramList.size(); ++idx)
+      {
+         if(theHistogramList[idx])
+         {
+            theHistogramList[idx]->SetCount(binNumber, count);
+         }
+      }
+   }   
+}
+
+ossimMultiBandHistogram* ossimMultiBandHistogram::createAccumulationLessThanEqual()const
+{
+   ossimMultiBandHistogram* result = NULL;
+
+   if(theHistogramList.size() > 0)
+   {
+      result = new ossimMultiBandHistogram;
+      result->theHistogramList.resize(theHistogramList.size());
+      
+      for(long index = 0; index < (long)theHistogramList.size(); ++index)
+      {
+         if(theHistogramList[index])
+         {
+            result->theHistogramList[index] = theHistogramList[index]->CumulativeLessThanEqual();
+         }
+         else
+         {
+            result->theHistogramList[index] = NULL;
+         }     
+      }
+   }
+
+   return result;
+}
+
+ossimMultiBandHistogram* ossimMultiBandHistogram::createAccumulationGreaterThanEqual()const
+{
+   ossimMultiBandHistogram* result = NULL;
+
+   if(theHistogramList.size() > 0)
+   {
+      result = new ossimMultiBandHistogram;
+      
+      for(long index = 0; index < (long)theHistogramList.size(); ++index)
+      {
+         if(theHistogramList[index])
+         {
+            result->theHistogramList[index] = theHistogramList[index]->CumulativeGreaterThanEqual();
+         }
+         else
+         {
+            result->theHistogramList[index] = NULL;
+         }     
+      }
+   }
+
+   return result;
+}
+
+void ossimMultiBandHistogram::deleteHistograms()
+{
+   for(long index = 0; index < (long)theHistogramList.size(); ++index)
+   {
+      if(theHistogramList[index])
+      {
+         delete theHistogramList[index];
+         theHistogramList[index] = NULL;
+      }
+   }
+   
+   theHistogramList.clear();
+}
+
+
+bool ossimMultiBandHistogram::importHistogram(istream& in)
+{
+   ossimProprietaryHeaderInformation header;
+   deleteHistograms();
+   
+   if(header.parseStream(in))
+   {
+      long numberOfBands = header.getNumberOfBands();
+      
+      if(numberOfBands)
+      {
+         theHistogramList.resize(numberOfBands);
+
+         for(long counter = 0; counter < (long)theHistogramList.size(); ++counter)
+         {
+            theHistogramList[counter] = NULL;
+         }
+         ossimString bandBuffer;
+         ossimString buffer;
+         
+         for(long index = 0; index < numberOfBands; ++index)
+         {
+            getline(in, buffer);
+            if(buffer.find("Band") != string::npos)
+            {
+               unsigned long offset = buffer.find(":");
+               if(offset != string::npos)
+               {
+                  bandBuffer = buffer.substr(offset+1);
+               }
+               else
+               {
+                  deleteHistograms();
+                  return false;
+               }
+            }
+            else
+            {
+               deleteHistograms();
+               return false;
+            }
+            long bandIndex = bandBuffer.toLong();
+
+            if(bandIndex < (long)theHistogramList.size())
+            {
+               if(!theHistogramList[bandIndex])
+               {
+                  ossimHistogram* histogram = new ossimHistogram;
+                  if(histogram->importHistogram(in))
+                  {
+                     theHistogramList[bandIndex] = histogram;
+                  }
+                  else
+                  {
+                     delete histogram;
+                     histogram = NULL;
+                     
+                     deleteHistograms();
+                     return false;
+                  }
+               }
+            }
+            else
+            {
+               deleteHistograms();
+               return false;
+            }
+         }
+      }
+      else
+      {
+         return false;
+      }
+   }  
+   return true;
+}
+
+bool ossimMultiBandHistogram::importHistogram(const ossimFilename& file)
+{
+   if(file.exists())
+   {
+      ifstream input(file.c_str());
+
+      return importHistogram(input);
+   }
+
+   return false;
+}
+
+bool ossimMultiBandHistogram::ossimProprietaryHeaderInformation::parseStream(istream& in)
+{
+   ossimString inputLine;
+
+   getline(in, inputLine);  
+   if(inputLine.find("File Type") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theFileType = inputLine.substr(index+1);
+         theFileType = theFileType.trim();
+      }
+      else
+      {
+         return false;
+      }
+
+   }
+   else
+   {
+      return false;
+   }
+
+   getline(in, inputLine);  
+   if(inputLine.find("Version") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theVersion = inputLine.substr(index+1);
+         theVersion = theVersion.trim();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+
+   getline(in, inputLine);  
+   if(inputLine.find("Number of Bands") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theNumberOfBands = inputLine.substr(index+1);
+         theNumberOfBands = theNumberOfBands.trim();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   return true;
+}
+
+bool ossimMultiBandHistogram::saveState(ossimKeywordlist& kwl,
+                                        const char* prefix)const
+{
+   kwl.add(prefix,
+           "type",
+           "ossimMultiBandHistogram",
+           true);
+   kwl.add(prefix,
+           "number_of_bands",
+           theHistogramList.size(),
+           true);
+   
+   for(ossim_uint32 index = 0; index < theHistogramList.size(); ++index)
+   {
+      ossimString band = ossimString(prefix) + "band";
+      band += (ossimString::toString(index) + ".");
+      if(theHistogramList[index])
+      {
+         ossimString newPrefix = (ossimString(prefix) + ossimString::toString(index) + ".");
+         
+         theHistogramList[index]->saveState(kwl,
+                                            band.c_str());
+      }
+   }
+   
+   return true;
+}
+
+bool ossimMultiBandHistogram::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   deleteHistograms();
+   const char* number_of_bands = kwl.find(prefix, "number_of_bands");
+   if(number_of_bands)
+   {
+      ossim_uint32 numberOfBands = ossimString(number_of_bands).toUInt32();
+
+      if(numberOfBands>0)
+      {
+         ossimString newPrefix;
+         for(ossim_uint32 index = 0; index < numberOfBands; ++index)
+         {
+            ossimHistogram* histo = new ossimHistogram;
+
+            newPrefix = prefix;
+            newPrefix += "band";
+            newPrefix += ossimString::toString(index);
+            newPrefix += ".";
+            
+            histo->loadState(kwl, newPrefix.c_str());
+            
+            theHistogramList.push_back(histo);
+         }
+      }
+   }
+   
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiBandHistogram.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiBandHistogram.h
new file mode 100644
index 0000000000..17cbfdae08
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiBandHistogram.h
@@ -0,0 +1,101 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description: 
+//
+//*******************************************************************
+//  $Id: ossimMultiBandHistogram.h,v 1.11 2003/08/22 20:50:46 dburken Exp $
+#ifndef ossimMultiBandHistogram_HEADER
+#define ossimMultiBandHistogram_HEADER
+#include <vector>
+using namespace std;
+#include "ossimFilename.h"
+
+class OSSIMDLLEXPORT ossimHistogram;
+class OSSIMDLLEXPORT ossimKeywordlist;
+
+class OSSIMDLLEXPORT ossimMultiBandHistogram
+{
+public:
+   ossimMultiBandHistogram();
+   ossimMultiBandHistogram(const ossimMultiBandHistogram& rhs);
+   ossimMultiBandHistogram(long numberOfBands,
+                           long numberOfBuckets,
+                           float minValue,
+                           float maxValue);
+   virtual ~ossimMultiBandHistogram();
+
+   void create(long numberOfBands,
+               long numberOfBuckets,
+               float minValue,
+               float maxValue);
+   
+   ossim_uint32 getNumberOfBands() const;
+
+   void create(long numberOfBands);
+   void setBinCount(double binNumber, double count);
+   ossimHistogram* getHistogram(long band);
+
+   ossimMultiBandHistogram* createAccumulationLessThanEqual()const;
+   ossimMultiBandHistogram* createAccumulationGreaterThanEqual()const;
+   /*!
+    * Imports a text file that has histogram data
+    */
+   virtual bool importHistogram(const ossimFilename& inputFile);
+   virtual bool importHistogram(istream& in);
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = 0);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = 0)const;
+protected:
+   class  ossimProprietaryHeaderInformation
+   {
+   public:
+      ossimProprietaryHeaderInformation(){clear();}
+
+      bool parseStream(istream& in);
+
+      ossim_uint32 getNumberOfBands()
+         {
+            return theNumberOfBands.toULong();
+         }
+      void clear()
+         {
+            theFileType      = "";
+            theVersion       = "";
+            theNumberOfBands = "";
+         }
+      ossimString theFileType;
+      ossimString theVersion;
+      ossimString theNumberOfBands;
+      
+   };
+   /*!
+    * Holds the histograms for each band
+    */
+   vector<ossimHistogram*> theHistogramList;
+
+   void deleteHistograms();
+
+   bool parseProprietaryHistogram(istream& in);
+                             
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiResLevelHistogram.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiResLevelHistogram.cpp
new file mode 100644
index 0000000000..fa0d6a8940
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiResLevelHistogram.cpp
@@ -0,0 +1,500 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description: 
+//
+//*******************************************************************
+//  $Id: ossimMultiResLevelHistogram.cpp,v 1.17 2003/09/09 18:33:57 dburken Exp $
+#include "ossimMultiResLevelHistogram.h"
+#include "ossimMultiBandHistogram.h"
+#include "ossimKeyword.h"
+#include "ossimKeywordlist.h"
+#include "base/common/ossimKeywordNames.h"
+#include <fstream>
+using namespace std;
+
+static const ossimKeyword NUMBER_OF_RES_LEVELS("number_of_res_levels",
+                                               "");
+
+ossimMultiResLevelHistogram::ossimMultiResLevelHistogram()
+   :
+      theHistogramList(),
+      theHistogramFile()
+{  
+}
+
+ossimMultiResLevelHistogram::ossimMultiResLevelHistogram(long numberOfResLevels)
+   :
+      theHistogramList(),
+      theHistogramFile()
+{
+   create(numberOfResLevels);
+}
+
+ossimMultiResLevelHistogram::ossimMultiResLevelHistogram(const ossimMultiResLevelHistogram& rhs)
+   :
+      theHistogramList(),
+      theHistogramFile()
+{
+   
+   create(rhs.getNumberOfResLevels());
+   for(ossim_uint32 i = 0; i < theHistogramList.size(); ++i)
+   {
+      theHistogramList[0] = rhs.theHistogramList[i]?
+                            new ossimMultiBandHistogram(*rhs.theHistogramList[i]):
+                            (ossimMultiBandHistogram*)NULL;
+   }
+}
+
+ossimMultiResLevelHistogram::~ossimMultiResLevelHistogram()
+{
+   deleteHistograms();
+}
+
+void ossimMultiResLevelHistogram::create(long numberOfResLevels)
+{
+   deleteHistograms();
+
+   for(long index = 0; index < numberOfResLevels; ++index)
+   {
+      theHistogramList.push_back(new ossimMultiBandHistogram);      
+   }
+}
+
+ossimMultiResLevelHistogram* ossimMultiResLevelHistogram::createAccumulationLessThanEqual()const
+{
+   ossimMultiResLevelHistogram* result = NULL;
+
+   if(theHistogramList.size() > 0)
+   {
+      result = new ossimMultiResLevelHistogram(theHistogramList.size());
+
+      for(long index=0; index < (long) theHistogramList.size(); ++ index)
+      {
+         if(theHistogramList[index])
+         {
+            ossimMultiBandHistogram* multiBandAccumulator = theHistogramList[index]->createAccumulationLessThanEqual();
+            result->theHistogramList[index] = multiBandAccumulator;
+         }
+         else
+         {
+            // we will push on a null since someone could
+            // turn off a band.  A null accumulation will
+            // indicate no histogram data.
+            //
+            result->theHistogramList[index] = NULL;
+         }
+      }
+      
+      if(result->theHistogramList.size() < 1)
+      {
+         delete result;
+      }
+   }
+   
+   return result;
+}
+
+void ossimMultiResLevelHistogram::setBinCount(double binNumber, double count)
+{
+   if(theHistogramList.size() > 0)
+   {
+      for(long index=0; index < (long) theHistogramList.size(); ++ index)
+      {
+         if(theHistogramList[index])
+         {
+            theHistogramList[index]->setBinCount(binNumber, count);
+         }
+      }
+   }   
+}
+
+ossimMultiResLevelHistogram* ossimMultiResLevelHistogram::createAccumulationGreaterThanEqual()const
+{
+   ossimMultiResLevelHistogram* result = NULL;
+
+   if(theHistogramList.size() > 0)
+   {
+      result = new ossimMultiResLevelHistogram(theHistogramList.size());
+
+      for(long index=0; index < (long) theHistogramList.size(); ++ index)
+      {
+         if(theHistogramList[index])
+         {
+            ossimMultiBandHistogram* multiBandAccumulator = theHistogramList[index]->createAccumulationGreaterThanEqual();
+            result->theHistogramList[index]=multiBandAccumulator;
+         }
+         else
+         {
+            // we will push on a null since someone could
+            // turn off a band.  A null accumulation will
+            // indicate no histogram data.
+            //
+            result->theHistogramList[index] = NULL;
+         }
+      }
+      
+      if(result->theHistogramList.size() < 1)
+      {
+         delete result;
+      }
+   }
+   
+   return result;
+}
+
+void ossimMultiResLevelHistogram::addHistogram(ossimMultiBandHistogram* histo)
+{
+   theHistogramList.push_back(histo);
+}
+
+ossimMultiBandHistogram* ossimMultiResLevelHistogram::addHistogram()
+{
+   ossimMultiBandHistogram* result = new ossimMultiBandHistogram;
+   theHistogramList.push_back(result);
+   return result;
+}
+
+bool ossimMultiResLevelHistogram::setHistogram(ossimMultiBandHistogram* histo, long resLevel)
+{
+   if( (resLevel >= 0) && (resLevel < getNumberOfResLevels()))
+   {
+      if(theHistogramList[resLevel])
+      {
+         delete theHistogramList[resLevel];
+      }
+      theHistogramList[resLevel] = histo;
+      return true;
+   }
+   return false;
+}
+
+void ossimMultiResLevelHistogram::deleteHistograms()
+{
+   for(long index = 0; index < (long)theHistogramList.size(); ++index)
+   {
+      if(theHistogramList[index])
+      {
+         delete theHistogramList[index];
+         theHistogramList[index] = NULL;
+      }
+   }
+   
+   theHistogramList.clear();
+}
+
+ossimHistogram* ossimMultiResLevelHistogram::getHistogram(long band,
+                                                          long resLevel)
+{
+   ossimMultiBandHistogram* temp = getMultiBandHistogram(resLevel);
+   if(temp)
+   {
+      return temp->getHistogram(band);
+   }
+   return NULL;
+}
+
+long ossimMultiResLevelHistogram::getNumberOfResLevels()const
+{
+   return (long)theHistogramList.size();
+}
+
+ossim_uint32 ossimMultiResLevelHistogram::getNumberOfBands(long resLevel) const
+{
+   const ossimMultiBandHistogram* h = getMultiBandHistogram(resLevel);
+   if (h)
+   {
+      return h->getNumberOfBands();
+   }
+
+   return 0;
+}  
+
+ossimMultiBandHistogram* ossimMultiResLevelHistogram::getMultiBandHistogram(long resLevel) const
+{
+   if((resLevel >=0) &&(resLevel < (long)theHistogramList.size()))
+   {
+      return theHistogramList[resLevel];
+   }
+
+   return NULL;
+}
+
+bool ossimMultiResLevelHistogram::importHistogram(istream& in)
+{
+   ossimString buffer;
+   getline(in, buffer);
+   // check to see if it is a proprietary histogram file
+   // 
+   if((buffer =="") || (buffer.c_str()[0] != 'F' ||
+      buffer.c_str()[1] != 'i'))
+   {
+      in.seekg(0, ios::beg);
+      ossimKeywordlist kwl;
+      kwl.parseStream(in);
+      return loadState(kwl);
+
+   }
+   ossimProprietaryHeaderInformation header;
+   in.seekg(0, ios::beg);
+   deleteHistograms();
+   if(header.parseStream(in))
+   {
+      long numberOfResLevels = header.getNumberOfResLevels();
+      
+      if(numberOfResLevels)
+      {
+         theHistogramList.resize(numberOfResLevels);
+
+         for(long counter = 0; counter < (long)theHistogramList.size(); ++counter)
+         {
+            theHistogramList[counter] = NULL;
+         }
+         ossimString reslevelBuffer;
+         ossimString buffer;
+         
+         for(long index = 0; index < numberOfResLevels; ++index)
+         {
+            getline(in, buffer);
+            if(buffer.find("RR Level") != string::npos)
+            {
+               unsigned long offset = buffer.find(":");
+               if(offset != string::npos)
+               {
+                  reslevelBuffer = buffer.substr(offset+1);
+               }
+               else
+               {
+                  deleteHistograms();
+                  return false;
+               }
+            }
+            else
+            {
+               deleteHistograms();
+               return false;
+            }
+            long resLevelIndex = reslevelBuffer.toLong();
+
+            if(resLevelIndex < (long)theHistogramList.size())
+            {
+               if(!theHistogramList[resLevelIndex])
+               {
+                  ossimMultiBandHistogram* histogram = new ossimMultiBandHistogram;
+                  if(histogram->importHistogram(in))
+                  {
+                     theHistogramList[resLevelIndex] = histogram;
+                  }
+                  else
+                  {
+                     delete histogram;
+                     histogram = NULL;
+                     
+                     deleteHistograms();
+                     return false;
+                  }
+               }
+            }
+            else
+            {
+               deleteHistograms();
+               return false;
+            }
+            ossimString skipDot;
+            getline(in, skipDot);
+         }
+      }
+      else
+      {
+         return false;
+      }
+   }  
+
+   return true;
+}
+
+bool ossimMultiResLevelHistogram::importHistogram(const ossimFilename& file)
+{
+   if(file.exists())
+   {
+      theHistogramFile = file;
+      
+      ifstream input(file.c_str());
+
+      return importHistogram(input);
+   }
+
+   return false;
+}
+
+bool ossimMultiResLevelHistogram::ossimProprietaryHeaderInformation::parseStream(istream& in)
+{
+   ossimString inputLine;
+
+   getline(in, inputLine);  
+   if(inputLine.find("File Type") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theFileType = inputLine.substr(index+1);
+         theFileType = theFileType.trim();
+      }
+      else
+      {
+         return false;
+      }
+
+   }
+   else
+   {
+      return false;
+   }
+
+   getline(in, inputLine);  
+   if(inputLine.find("Version") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theVersion = inputLine.substr(index+1);
+         theVersion = theVersion.trim();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+
+   getline(in, inputLine);  
+   if(inputLine.find("Creator ID") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theCreatorId = inputLine.substr(index+1);
+         theCreatorId = theCreatorId.trim();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   getline(in, inputLine);  
+   if(inputLine.find("RR Levels") != string::npos)
+   {
+      unsigned long index = inputLine.find(":");
+      if(index != string::npos)
+      {
+         theNumberOfResLevels = inputLine.substr(index+1);
+         theNumberOfResLevels = theNumberOfResLevels.trim();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   return true;
+}
+
+bool ossimMultiResLevelHistogram::saveState(ossimKeywordlist& kwl,
+                                            const char* prefix)const
+{
+   bool result = true;
+   if(theHistogramList.size() > 0)
+   {
+      ossimString s1 = prefix;
+      kwl.add(prefix,
+              ossimKeywordNames::TYPE_KW,
+              "ossimMultiResLevelHistogram",
+              true);
+      kwl.add(prefix,
+              NUMBER_OF_RES_LEVELS.key(),
+              theHistogramList.size(),
+              true);
+
+      for(ossim_uint32 index = 0; index < theHistogramList.size(); ++index)
+      {
+         ossimString rr_level = ossimString(prefix) + "rr_level";
+         rr_level += ossimString::toString(index)   + ".";
+         if(theHistogramList[index])
+         {
+            result = theHistogramList[index]->saveState(kwl, rr_level.c_str());
+            
+            if(!result)
+            {
+               return result;
+            }
+         }
+      }    
+   }
+
+   return result;
+}
+
+bool ossimMultiResLevelHistogram::loadState(const ossimKeywordlist& kwl,
+                                            const char* prefix)
+{
+   deleteHistograms();
+   const char* number_of_res_levels = kwl.find(prefix, NUMBER_OF_RES_LEVELS.key());
+
+   if(number_of_res_levels)
+   {
+      ossim_uint32 numberOfResLevels = ossimString(number_of_res_levels).toUInt32();
+
+      if(numberOfResLevels)
+      {
+         ossimString newPrefix;
+         for(ossim_uint32 index = 0; index < numberOfResLevels; ++index)
+         {
+            ossimMultiBandHistogram* histo = new ossimMultiBandHistogram;
+
+            newPrefix = prefix;
+            newPrefix += "rr_level";
+            newPrefix += ossimString::toString(index);
+            newPrefix += ".";
+            
+            histo->loadState(kwl, newPrefix.c_str());
+            
+            theHistogramList.push_back(histo);
+         }
+      }
+   }
+   return true;
+}
+
+ossimFilename ossimMultiResLevelHistogram::getHistogramFile() const
+{
+   return theHistogramFile;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiResLevelHistogram.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiResLevelHistogram.h
new file mode 100644
index 0000000000..4791c131dc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimMultiResLevelHistogram.h
@@ -0,0 +1,115 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description: 
+//
+//*******************************************************************
+//  $Id: ossimMultiResLevelHistogram.h,v 1.10 2003/09/03 14:19:30 dburken Exp $
+#ifndef ossimMultiResLevelHistogram_HEADER
+#define ossimMultiResLevelHistogram_HEADER
+#include <vector>
+using namespace std;
+#include "ossimFilename.h"
+#include "ossimKeywordlist.h"
+
+class OSSIMDLLEXPORT ossimMultiBandHistogram;
+class OSSIMDLLEXPORT ossimHistogram;
+
+class OSSIMDLLEXPORT ossimMultiResLevelHistogram
+{
+public:
+   ossimMultiResLevelHistogram();
+   ossimMultiResLevelHistogram(long numberOfResLevels);
+   ossimMultiResLevelHistogram(const ossimMultiResLevelHistogram& rhs);
+   
+   virtual ~ossimMultiResLevelHistogram();
+
+   ossimHistogram* getHistogram(long band,
+                                long resLevel=0);
+   long getNumberOfResLevels()const;
+   ossim_uint32 getNumberOfBands(long resLevel=0) const;
+   void create(long numberOfResLevels);
+   ossimMultiBandHistogram* getMultiBandHistogram(long resLevel) const;
+   ossimMultiResLevelHistogram* createAccumulationLessThanEqual()const;
+   ossimMultiResLevelHistogram* createAccumulationGreaterThanEqual()const;
+
+   void setBinCount(double binNumber, double count);
+   /*!
+    * Will append to the list the passed in histogram.
+    */
+   virtual void addHistogram(ossimMultiBandHistogram* histo);
+
+   /*!
+    * This will create and append a histogram to the
+    * list and return a pointer to the new histogram.
+    */
+   virtual ossimMultiBandHistogram* addHistogram();
+
+   /*!
+    * Will set the histogram to the passed in res level.
+    * It will delete the histogram at the res level before
+    * setting the pointer to the passed in histogram.  if
+    * the resLevel is out of range it will return false meaning
+    * it was unable to assign the pointer.
+    */
+   virtual bool setHistogram(ossimMultiBandHistogram* histo, long resLevel);
+
+   virtual ossimFilename getHistogramFile() const;
+   virtual bool importHistogram(const ossimFilename& inputFile);
+   virtual bool importHistogram(istream& in);
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+protected:
+   class  ossimProprietaryHeaderInformation
+   {
+   public:
+      ossimProprietaryHeaderInformation(){clear();}
+
+      bool parseStream(istream& in);
+
+      long getNumberOfResLevels()
+         {
+            return theNumberOfResLevels.toLong();
+         }
+      void clear()
+         {
+            theFileType          = "";
+            theVersion           = "";
+            theCreatorId         = "";
+            theNumberOfResLevels = "";
+         }
+      ossimString theFileType;
+      ossimString theVersion;
+      ossimString theCreatorId;
+      ossimString theNumberOfResLevels;
+   };
+
+   vector<ossimMultiBandHistogram*> theHistogramList;
+   ossimFilename                    theHistogramFile;
+   
+   void deleteHistograms();
+   bool parseProprietaryHistogram(istream& in);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyArea2d.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyArea2d.cpp
new file mode 100644
index 0000000000..0786494ba3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyArea2d.cpp
@@ -0,0 +1,949 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimPolyArea2d.cpp,v 1.20 2005/09/30 19:56:45 gpotts Exp $
+#include <list>
+#include <sstream>
+using namespace std;
+
+#include <base/data_types/ossimPolyArea2d.h>
+#include <base/common/ossimKeywordNames.h>
+
+ostream& operator<<(ostream& out, const ossimPolyArea2d& data)
+{
+   if(!data.thePolygon)
+   {
+      return out;
+   }
+   int cnt;
+   PLINE *cntr;
+   POLYAREA * curpa;
+   
+   cnt = 0, curpa = data.thePolygon; 
+   do
+   {
+      cnt++;
+   } while ( (curpa = curpa->f) != data.thePolygon);
+   
+   curpa = data.thePolygon; 
+   do
+   {
+      for ( cntr = curpa->contours, cnt = 0; cntr != NULL; cntr = cntr->next, cnt++ )
+      {}
+      out << cnt << endl;
+      
+      for ( cntr = curpa->contours; cntr != NULL; cntr = cntr->next )
+      {
+         VNODE *cur;
+         
+         out << cntr->Count << endl;
+         cur = &cntr->head;
+         do
+         {
+            out << cur->point[0] << " " <<  cur->point[1] << endl;
+         } while ( ( cur = cur->next ) != &cntr->head );
+      }     
+   }while ( (curpa = curpa->f) != data.thePolygon);
+   
+   return out;
+}
+
+
+
+ossimPolyArea2d::ossimPolyArea2d()
+   :thePolygon(NULL)
+{  
+}
+
+ossimPolyArea2d::ossimPolyArea2d(POLYAREA* polygon,
+                               bool    copyPolygonFlag)
+   :thePolygon(NULL)
+{
+   if(copyPolygonFlag)
+   {
+      poly_Copy0(&thePolygon, polygon);
+   }
+   else
+   {
+      thePolygon = polygon;
+   }
+}
+
+ossimPolyArea2d::ossimPolyArea2d(const ossimPolyArea2d& rhs)
+   :thePolygon(NULL)
+{
+   poly_Copy0(&thePolygon, rhs.thePolygon);
+}
+
+ossimPolyArea2d::ossimPolyArea2d(const vector<ossimDpt>& polygon)
+   :thePolygon(NULL)
+{
+   if(polygon.size() > 0)
+   {
+      PLINE  *poly = NULL;
+      Vector v;
+      v[0] = polygon[0].x;
+      v[1] = polygon[0].y;
+      v[2] = 0;
+      poly = poly_NewContour(v);
+      for(long index = 1; index < (long)polygon.size(); ++index)
+      {
+
+         v[0] = polygon[index].x;
+         v[1] = polygon[index].y;
+         v[2] = 0.0;
+         
+         poly_InclVertex(poly->head.prev,
+                         poly_CreateNode(v));
+         
+      }
+      poly_PreContour(poly, TRUE);
+      
+      if ( (poly->Flags & PLF_ORIENT) != PLF_DIR)
+      {
+         poly_InvContour(poly);
+      }
+      thePolygon = poly_Create();
+      poly_InclContour(thePolygon, poly);
+//       if(!poly_Valid(thePolygon))
+//       {
+//          if(thePolygon)
+//          {
+//             poly_Free(&thePolygon);
+//             thePolygon = NULL;
+//          }
+//       }
+   }   
+}
+
+ossimPolyArea2d::ossimPolyArea2d(const vector<ossimGpt>& polygon)
+   :thePolygon(NULL)
+{
+   if(polygon.size() > 0)
+   {
+      PLINE  *poly = NULL;
+      Vector v;
+      v[0] = polygon[0].lon;
+      v[1] = polygon[0].lat;
+      v[2] = 0;
+      poly = poly_NewContour(v);
+      for(long index = 1; index < (long)polygon.size(); ++index)
+      {
+
+         v[0] = polygon[index].lon;
+         v[1] = polygon[index].lat;
+         v[2] = 0.0;
+         
+         poly_InclVertex(poly->head.prev,
+                         poly_CreateNode(v));
+         
+      }
+      poly_PreContour(poly, TRUE);
+      
+      if ( (poly->Flags & PLF_ORIENT) != PLF_DIR)
+      {
+         poly_InvContour(poly);
+      }
+      thePolygon = poly_Create();
+      poly_InclContour(thePolygon, poly);
+//       if(!poly_Valid(thePolygon))
+//       {
+//          if(thePolygon)
+//          {
+//             poly_Free(&thePolygon);
+//             thePolygon = NULL;
+//          }
+//       }
+   }   
+}
+
+ossimPolyArea2d::ossimPolyArea2d(const ossimDpt& p1,
+                                 const ossimDpt& p2,
+                                 const ossimDpt& p3,
+                                 const ossimDpt& p4)
+   :thePolygon(NULL)
+{
+   PLINE  *poly = NULL;
+   Vector v;
+   v[0] = p1.x;
+   v[1] = p1.y;
+   v[2] = 0;
+   poly = poly_NewContour(v);
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   v[0] = p2.x;
+   v[1] = p2.y;
+   v[2] = 0;
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   v[0] = p3.x;
+   v[1] = p3.y;
+   v[2] = 0;
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   v[0] = p4.x;
+   v[1] = p4.y;
+   v[2] = 0;
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   
+   poly_PreContour(poly, TRUE);
+   
+   if ( (poly->Flags & PLF_ORIENT) != PLF_DIR)
+   {
+      poly_InvContour(poly);
+   }
+   thePolygon = poly_Create();
+   poly_InclContour(thePolygon, poly);
+//    if(!poly_Valid(thePolygon))
+//    {
+//       if(thePolygon)
+//       {
+//          poly_Free(&thePolygon);
+//          thePolygon = NULL;
+//       }
+//    }   
+}
+
+
+ossimPolyArea2d::ossimPolyArea2d(ossimDpt* polygon,
+                               long number)
+   :thePolygon(NULL)
+{
+   if(number > 0)
+   {
+      PLINE  *poly = NULL;
+      Vector v;
+      v[0] = polygon[0].x;
+      v[1] = polygon[0].y;
+      v[2] = 0;
+      poly = poly_NewContour(v);
+      for(long index = 1; index < number; ++index)
+      {
+
+         v[0] = polygon[index].x;
+         v[1] = polygon[index].y;
+         v[2] = 0.0;
+         
+         poly_InclVertex(poly->head.prev,
+                         poly_CreateNode(v));
+         
+      }
+      poly_PreContour(poly, TRUE);
+      
+      if ( (poly->Flags & PLF_ORIENT) != PLF_DIR)
+      {
+         poly_InvContour(poly);
+      }
+      thePolygon = poly_Create();
+      poly_InclContour(thePolygon, poly);
+//       if(!poly_Valid(thePolygon))
+//       {
+//          poly_Free(&thePolygon);
+//          thePolygon = NULL;
+//       }
+   }
+}
+
+ossimPolyArea2d::ossimPolyArea2d(const ossimPolygon& polygon)
+   :thePolygon(NULL)
+{
+   if(polygon.getVertexCount() > 0)
+   {
+      PLINE  *poly = NULL;
+      Vector v;
+      v[0] = polygon[0].x;
+      v[1] = polygon[0].y;
+      v[2] = 0;
+      poly = poly_NewContour(v);
+      for(long index = 1; index < (long)polygon.getVertexCount(); ++index)
+      {
+
+         v[0] = polygon[index].x;
+         v[1] = polygon[index].y;
+         v[2] = 0.0;
+         
+         poly_InclVertex(poly->head.prev,
+                         poly_CreateNode(v));
+         
+      }
+      poly_PreContour(poly, TRUE);
+      
+      // make sure that its clockwise
+      if ( (poly->Flags & PLF_ORIENT) != PLF_DIR)
+      {
+         poly_InvContour(poly);
+      }
+      thePolygon = poly_Create();
+      poly_InclContour(thePolygon, poly);
+      if(!poly_Valid(thePolygon))
+      {
+//         if(thePolygon)
+//         {
+//            poly_Free(&thePolygon);
+//            thePolygon = NULL;
+//         }
+      }
+   }   
+}
+
+ossimPolyArea2d::~ossimPolyArea2d()
+{
+   if(thePolygon)
+   {
+      poly_Free(&thePolygon);
+      thePolygon = NULL;
+   }
+}
+const ossimPolyArea2d& ossimPolyArea2d::operator *=(const ossimDpt& scale)
+{
+   if(!thePolygon) return *this;
+   
+   PLINE *cntr     = (PLINE*)NULL;
+   POLYAREA *curpa = (POLYAREA*)NULL;
+   
+   curpa           = thePolygon;
+
+   do{
+      for ( cntr = curpa->contours; cntr != NULL; cntr = cntr->next )
+      {
+         VNODE *cur = &cntr->head;
+         double xmin, ymin;
+         double xmax, ymax;
+         xmin = xmax = cur->point[0];
+         ymin = ymax = cur->point[1];
+         do
+         {
+            cur->point[0] *= scale.x;
+            cur->point[1] *= scale.y;
+            xmin = std::min(cur->point[0], xmin);
+            xmax = std::max(cur->point[0], xmax);
+            ymin = std::min(cur->point[1], ymin);
+            ymax = std::max(cur->point[1], ymax);
+         } while ( ( cur = cur->next ) != &cntr->head );
+      }
+   }
+   while( (curpa = curpa->f) != thePolygon);
+   
+   return *this;
+}
+
+ossimPolyArea2d ossimPolyArea2d::operator *(const ossimDpt& scale)const
+{
+   if(!thePolygon) return *this;
+
+   ossimPolyArea2d result(*this);
+   PLINE *cntr     = (PLINE*)NULL;
+   POLYAREA *curpa = (POLYAREA*)NULL;
+   
+   curpa           = result.thePolygon;
+
+   do{
+      for ( cntr = curpa->contours; cntr != NULL; cntr = cntr->next )
+      {
+         VNODE *cur = &cntr->head;
+         double xmin, ymin;
+         double xmax, ymax;
+         xmin = xmax = cur->point[0];
+         ymin = ymax = cur->point[1];
+         
+         do
+         {
+            cur->point[0] *= scale.x;
+            cur->point[1] *= scale.y;
+            xmin = std::min(cur->point[0], xmin);
+            xmax = std::max(cur->point[0], xmax);
+            ymin = std::min(cur->point[1], ymin);
+            ymax = std::max(cur->point[1], ymax);
+         } while ( ( cur = cur->next ) != &cntr->head );
+
+         cntr->xmin = xmin;
+         cntr->ymin = ymin;
+         cntr->xmax = xmax;
+         cntr->ymax = ymax;
+      }
+   }
+   while( (curpa = curpa->f) != result.thePolygon);
+   
+   return result;
+}
+
+const ossimPolyArea2d& ossimPolyArea2d::operator *=(double scale)
+{
+   return ((*this)*=ossimDpt(scale, scale));
+}
+
+ossimPolyArea2d ossimPolyArea2d::operator *(double scale)const
+{
+   return ((*this)*ossimDpt(scale, scale));
+}
+
+/*!
+ * Assignment operator.  Allows you to assign
+ * or copy one polygon to another.
+ */
+const ossimPolyArea2d& ossimPolyArea2d::operator =(const ossimPolyArea2d& rhs)
+{
+   if(this != &rhs)
+   {
+      if(thePolygon)
+      {
+         poly_Free(&thePolygon);
+         thePolygon = NULL;
+      }
+      if(rhs.thePolygon)
+      {
+         poly_Copy0(&thePolygon, rhs.thePolygon);
+      }
+   }
+
+   return *this;
+}
+
+const ossimPolyArea2d& ossimPolyArea2d::operator =(const ossimIrect& rect)
+{
+   if(thePolygon)
+   {
+      poly_Free(&thePolygon);
+      thePolygon = NULL;
+   }
+   
+   PLINE  *poly = NULL;
+   Vector v;
+   v[0] = rect.ul().x;
+   v[1] = rect.ul().y;
+   v[2] = 0;
+   poly = poly_NewContour(v);
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   v[0] = rect.ur().x;
+   v[1] = rect.ur().y;
+   v[2] = 0;
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   v[0] = rect.lr().x;
+   v[1] = rect.lr().y;
+   v[2] = 0;
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   v[0] = rect.ll().x;
+   v[1] = rect.ll().y;
+   v[2] = 0;
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   
+   poly_PreContour(poly, TRUE);
+   
+   if ( (poly->Flags & PLF_ORIENT) != PLF_DIR)
+   {
+      poly_InvContour(poly);
+   }
+   thePolygon = poly_Create();
+   poly_InclContour(thePolygon, poly);
+//    if(!poly_Valid(thePolygon))
+//    {
+//       if(thePolygon)
+//       {
+//          poly_Free(&thePolygon);
+//          thePolygon = NULL;
+//       }
+//    }
+
+   return *this;
+}
+
+const ossimPolyArea2d& ossimPolyArea2d::operator =(const ossimDrect& rect)
+{
+   if(thePolygon)
+   {
+      poly_Free(&thePolygon);
+      thePolygon = NULL;
+   }
+   
+   PLINE  *poly = NULL;
+   Vector v;
+   v[0] = rect.ul().x;
+   v[1] = rect.ul().y;
+   v[2] = 0;
+   poly = poly_NewContour(v);
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   v[0] = rect.ur().x;
+   v[1] = rect.ur().y;
+   v[2] = 0;
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   v[0] = rect.lr().x;
+   v[1] = rect.lr().y;
+   v[2] = 0;
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   v[0] = rect.ll().x;
+   v[1] = rect.ll().y;
+   v[2] = 0;
+   poly_InclVertex(poly->head.prev,
+                   poly_CreateNode(v));
+   
+   poly_PreContour(poly, TRUE);
+   
+   if ( (poly->Flags & PLF_ORIENT) != PLF_DIR)
+   {
+      poly_InvContour(poly);
+   }
+   thePolygon = poly_Create();
+   poly_InclContour(thePolygon, poly);
+//    if(!poly_Valid(thePolygon))
+//    {
+//       if(thePolygon)
+//       {
+//          poly_Free(&thePolygon);
+//          thePolygon = NULL;
+//       }
+//    }
+   
+   return *this;
+}
+
+ossimPolyArea2d ossimPolyArea2d::operator -(const ossimPolyArea2d& rhs)const
+{
+   if(this == &rhs)
+   {
+      return ossimPolyArea2d();
+   }
+   POLYAREA* result=NULL;
+
+   if (poly_Boolean(this->thePolygon,
+                    rhs.thePolygon,
+                    &result,
+                    PBO_SUB) == err_ok) 
+   {
+      return ossimPolyArea2d(result, false);
+   }
+
+   // if there were errors then we will just return an
+   // empty polygon.
+   //
+   return ossimPolyArea2d();
+}
+
+ossimPolyArea2d& ossimPolyArea2d::operator -=(const ossimPolyArea2d& rhs)
+{
+   if(this == &rhs)
+   {
+      poly_Free(&thePolygon);
+      thePolygon = NULL;
+   }
+   else
+   {
+      POLYAREA* result=NULL;
+      
+      if (poly_Boolean(this->thePolygon,
+                       rhs.thePolygon,
+                       &result,
+                       PBO_SUB) == err_ok) 
+      {
+         poly_Free(&thePolygon);
+         thePolygon = result;
+      }
+      else
+      {
+         // errors so make it empty
+         poly_Free(&thePolygon);
+         thePolygon = NULL;
+      }
+   }
+
+   return *this;
+}
+
+ossimPolyArea2d ossimPolyArea2d::operator +(const ossimPolyArea2d& rhs)const
+{
+   if(this == &rhs)
+   {
+      return *this;
+   }
+   POLYAREA* result=NULL;
+
+   if (poly_Boolean(this->thePolygon,
+                    rhs.thePolygon,
+                    &result,
+                    PBO_UNITE) == err_ok) 
+   {
+      return ossimPolyArea2d(result, false);
+   }
+
+   // if there were errors then we will just return an
+   // empty polygon.
+   //
+   return ossimPolyArea2d();
+}
+
+ossimPolyArea2d& ossimPolyArea2d::operator +=(const ossimPolyArea2d& rhs)
+{
+   if(this == &rhs)
+   {
+      poly_Free(&thePolygon);
+      thePolygon = NULL;
+   }
+   else
+   {
+      POLYAREA* result=NULL;
+      if (poly_Boolean(this->thePolygon,
+                       rhs.thePolygon,
+                       &result,
+                       PBO_UNITE) == err_ok) 
+      {
+         poly_Free(&thePolygon);
+         thePolygon = result;
+      }
+      else
+      {
+         // errors so make it empty
+         poly_Free(&thePolygon);
+         thePolygon = NULL;
+      }
+   }
+
+   return *this;
+}
+
+ossimPolyArea2d ossimPolyArea2d::operator &(const ossimPolyArea2d& rhs)const
+{
+   if(this == &rhs)
+   {
+      return ossimPolyArea2d(*this);
+   }
+   if(thePolygon&&rhs.thePolygon)
+   {
+      POLYAREA* result=NULL;
+      
+      if (poly_Boolean(this->thePolygon,
+                       rhs.thePolygon,
+                       &result,
+                       PBO_ISECT) == err_ok) 
+      {
+         return ossimPolyArea2d(result, false);
+      }
+   }
+   
+   // if there were errors then we will just return an
+   // empty polygon.
+   //
+   return ossimPolyArea2d();
+}
+
+ossimPolyArea2d& ossimPolyArea2d::operator &=(const ossimPolyArea2d& rhs)
+{
+   if(this != &rhs)
+   {
+      POLYAREA* result=NULL;
+      if (poly_Boolean(this->thePolygon,
+                       rhs.thePolygon,
+                       &result,
+                       PBO_ISECT) == err_ok) 
+      {
+         poly_Free(&thePolygon);
+         thePolygon = result;
+      }
+      else
+      {
+         // errors so make it empty
+         poly_Free(&thePolygon);
+         thePolygon = NULL;
+      }
+   }
+
+   return *this;
+}
+
+ossimPolyArea2d ossimPolyArea2d::operator ^(const ossimPolyArea2d& rhs)const
+{
+   if(this != &rhs)
+   {
+      POLYAREA* result=NULL;
+      
+      if (poly_Boolean(this->thePolygon,
+                       rhs.thePolygon,
+                       &result,
+                       PBO_XOR) == err_ok) 
+      {
+         return ossimPolyArea2d(result, false);
+      }
+      
+   }
+   
+   return ossimPolyArea2d();
+}
+
+ossimPolyArea2d& ossimPolyArea2d::operator ^=(const ossimPolyArea2d& rhs)
+{
+   if(this == &rhs)
+   {
+      poly_Free(&thePolygon);
+      thePolygon = NULL;
+   }
+   else
+   {
+      POLYAREA* result=NULL;
+      if (poly_Boolean(this->thePolygon,
+                       rhs.thePolygon,
+                       &result,
+                       PBO_XOR) == err_ok) 
+      {
+         poly_Free(&thePolygon);
+         thePolygon = result;
+      }
+      else
+      {
+         // errors so make it empty
+         poly_Free(&thePolygon);
+         thePolygon = NULL;
+      }
+   }
+   
+   return *this;
+}
+
+bool ossimPolyArea2d::isPointWithin(const ossimDpt& point)const
+{
+   if(!thePolygon)
+   {
+      return false;
+   }
+   Vector v;
+   v[0] = point.x;
+   v[1] = point.y;
+   v[2] = 0;
+   
+   return (poly_CheckInside(thePolygon, v)==TRUE);
+  
+}
+
+bool ossimPolyArea2d::isPointWithin(double x, double y)const
+{
+   if(!thePolygon)
+   {
+      return false;
+   }
+   Vector v;
+   v[0] = x;
+   v[1] = y;
+   v[2] = 0;
+   
+   return (poly_CheckInside(thePolygon, v)==TRUE);
+}
+
+void ossimPolyArea2d::getBoundingRect(ossimDrect& rect)
+{
+   if(thePolygon)
+   {
+      PLINE*    cntr  = NULL;
+      POLYAREA* curpa = NULL;
+      
+      curpa = thePolygon;
+      rect = ossimDrect(curpa->contours->xmin,
+                        curpa->contours->ymin,
+                        curpa->contours->xmax,
+                        curpa->contours->ymax);
+      do
+      {        
+         for ( cntr = curpa->contours->next; cntr != NULL; cntr = cntr->next )
+         {
+            ossimDrect rect2 = ossimDrect(curpa->contours->xmin,
+                                          curpa->contours->ymin,
+                                          curpa->contours->xmax,
+                                          curpa->contours->ymax);
+            if(rect2.width() != 1 &&
+               rect2.height() != 1)
+            {
+               rect = rect.combine(rect2);
+            }
+         }     
+      }while ( (curpa = curpa->f) != thePolygon);
+   }
+   else
+   {
+      rect = ossimDrect(0,0,0,0);
+   }
+}
+
+bool ossimPolyArea2d::saveState(ossimKeywordlist& kwl,
+                               const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           "ossimPolyArea2d",
+           true);
+           
+   if(!thePolygon)
+   {
+      return true;
+   }
+   int cnt;
+   PLINE *cntr;
+   POLYAREA * curpa;
+   
+   cnt = 0, curpa = thePolygon; 
+   do
+   {
+      cnt++;
+   } while ( (curpa = curpa->f) != thePolygon);
+   
+   curpa = thePolygon; 
+   do
+   {
+      cnt = 1;
+      for ( cntr = curpa->contours; cntr != NULL; cntr = cntr->next )
+      {
+         VNODE *cur;
+         ossimString newPrefix = prefix;
+         newPrefix+="contour";
+         newPrefix += ossimString::toString(cnt);
+         newPrefix += ".";
+         kwl.add(newPrefix.c_str(),
+                 "flags",
+                 (int)cntr->Flags,
+                 true);
+         
+         cur = &cntr->head;
+         int pointCount = 1;
+         do
+         {
+            ossimString pointString = "point";
+            pointString += ossimString::toString(pointCount);
+            ossimString points;
+            points = ossimString::toString(cur->point[0]);
+            points += " ";
+            points += ossimString::toString(cur->point[1]);
+            kwl.add(newPrefix.c_str(),
+                    pointString,
+                    points.c_str(),
+                    true);
+            ++pointCount;
+         } while ( ( cur = cur->next ) != &cntr->head );
+         ++cnt;
+      }     
+   }while ( (curpa = curpa->f) != thePolygon);
+   
+   return true;
+}
+
+bool ossimPolyArea2d::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   
+   vector<ossimString> contourList = kwl.getSubstringKeyList(ossimString(prefix) + "contour[0-9]+\\.");
+   if(thePolygon)
+   {
+      poly_Free(&thePolygon);
+      thePolygon = NULL;
+   }
+   if(contourList.size() > 0)
+   {
+      thePolygon = poly_Create();
+      vector<ossimString>::iterator currentContour = contourList.begin();
+      
+      Vector v;
+      PLINE  *poly = NULL;
+      ossim_uint32 currentContourIndex = 0;
+      while(currentContour != contourList.end())
+      {
+         ossimString copyPrefix = *currentContour;
+         ossim_int32 contourFlags = 0;
+         
+         const char* lookupFlags = kwl.find((*currentContour).c_str(),
+                                             "flags");
+         if(lookupFlags)
+         {
+            contourFlags = ossimString(lookupFlags).toInt32();
+         }
+         ossim_uint32 numberOfPoints = kwl.getNumberOfSubstringKeys(copyPrefix + "point[0-9]");
+         ossim_uint32 numberOfMatches = 0;
+         ossim_uint32 currentPoint = 0;
+         while(numberOfMatches < numberOfPoints)
+         {
+            ossimString pointString = "point";
+            pointString += ossimString::toString(currentPoint);
+            const char* pointLookup = kwl.find((*currentContour).c_str(),
+                                               pointString);
+            if(pointLookup)
+            {
+               istringstream s(pointLookup);
+
+               s >> v[0] >> v[1];
+               v[2] = 0;
+
+               // initialize the poly if we are on the
+               // first match point else we just add it.
+               if(!numberOfMatches)
+               {
+                  poly = poly_NewContour(v);
+               }
+               else
+               {
+                  poly_InclVertex(poly->head.prev,
+                                  poly_CreateNode(v));
+               }
+               
+               ++numberOfMatches;
+            }
+            ++currentPoint;
+         }
+         poly->Flags = contourFlags;
+         poly_PreContour(poly, TRUE);
+         if ( (poly->Flags & PLF_ORIENT) !=
+              (currentContourIndex ? PLF_INV : PLF_DIR) )
+         {
+            poly_InvContour(poly);
+         }
+         if(!poly_InclContour(thePolygon, poly))
+         {
+            poly_DelContour(&poly);
+         }
+         poly = NULL;
+         ++currentContour;
+         ++currentContourIndex;
+      }
+   }
+   return true;
+}
+
+bool ossimPolyArea2d::getAllVisiblePolygons(vector<ossimPolygon>& polyList)const
+{
+   if(!thePolygon) return false;
+   if(!poly_Valid(thePolygon))
+   {
+      return false;
+   }
+   polyList.clear();
+   POLYAREA* curpa = thePolygon;
+   PLINE*    cntr;
+   int index = 0;
+   do
+   {
+      for ( cntr = curpa->contours; cntr != NULL; cntr = cntr->next )
+      {
+         if(cntr->Flags & PLF_DIR)
+         {
+            polyList.push_back(ossimPolygon());
+            VNODE* cur = &cntr->head;
+            do
+            {   
+               polyList[index].addPoint(cur->point[0],
+                                        cur->point[1]);
+               
+            } while ( ( cur = cur->next ) != &cntr->head );
+            ++index;
+         }
+      }
+   }while ( (curpa = curpa->f) != thePolygon);
+
+   return (polyList.size()>0);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyArea2d.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyArea2d.h
new file mode 100644
index 0000000000..aa86712b2d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyArea2d.h
@@ -0,0 +1,196 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimPolyArea2d.h,v 1.7 2005/09/30 19:56:45 gpotts Exp $
+#ifndef ossimPolyArea2d_HEADER
+#define ossimPolyArea2d_HEADER
+extern "C"
+{
+#include "libpolyclip/polyarea.h"
+}
+
+#include <iostream>
+#include <vector>
+using namespace std;
+
+#include "ossimDpt.h"
+#include "ossimGpt.h"
+#include "ossimDrect.h"
+#include "ossimIrect.h"
+#include "ossimKeywordlist.h"
+#include "ossimPolygon.h"
+
+/*!
+ * This class uses the multiclip 2-d polygon library
+ * to do intersections, unions, set difference, and xor
+ * operations.  It will also use the library to do quick
+ * point inside and poly inside tests.
+ */
+class OSSIMDLLEXPORT ossimPolyArea2d
+{
+public:
+   friend ostream& operator  <<(ostream& out,
+                                const ossimPolyArea2d& data);
+   /*!
+    * we will use the multi clip library in
+    * libpolyclip directory.
+    */
+   ossimPolyArea2d();
+   /*!
+    * If the copy polygon flag is false
+    * it will set its internal thePolygon to polygon
+    * else it will make a copy of it.
+    */
+   ossimPolyArea2d(POLYAREA* polygon,
+                  bool    copyPolygonFlag=false);
+   
+   ossimPolyArea2d(const ossimPolyArea2d& rhs);
+   ossimPolyArea2d(const vector<ossimDpt>& polygon);
+   ossimPolyArea2d(const vector<ossimGpt>& polygon);
+   ossimPolyArea2d(ossimDpt* points,
+                  long number);
+
+   ossimPolyArea2d(const ossimDpt& p1,
+                   const ossimDpt& p2,
+                   const ossimDpt& p3,
+                   const ossimDpt& p4);
+   ossimPolyArea2d(const ossimIrect& rect)
+      :thePolygon(NULL)
+      {
+         (*this) = rect;
+      }
+   ossimPolyArea2d(const ossimDrect& rect)
+      :thePolygon(NULL)
+      {
+         (*this) = rect;
+      }
+   
+   ossimPolyArea2d(const ossimPolygon& polygon);
+   ~ossimPolyArea2d();
+
+   /*!
+    * Will scale the polygon along the x and y direction
+    * by the passed in scale.  It will modify itself and
+    * return a const reference to itself.
+    */
+   const ossimPolyArea2d& operator *=(const ossimDpt& scale);
+   
+   /*!
+    * Will scale the polygon along the x and y direction
+    * by the passed in scale.  It will return another object.
+    */
+   ossimPolyArea2d operator *(const ossimDpt& scale)const;
+
+   /*!
+    * Scales evenly along the x and y direction.
+    */
+   const ossimPolyArea2d& operator *=(double scale);
+
+   /*!
+    * Scales evenly along the x and y direction.
+    */
+   ossimPolyArea2d operator *(double scale)const;
+
+   /*!
+    * Assignment operator.  Allows you to assign
+    * or copy one polygon to another.
+    */
+   const ossimPolyArea2d& operator =(const ossimPolyArea2d& rhs);
+
+   const ossimPolyArea2d& operator =(const ossimIrect& rect);
+   const ossimPolyArea2d& operator =(const ossimDrect& rect);
+   
+   /*!
+    * Will do a set difference on the this - right
+    * and return a new polygon.
+    */
+   ossimPolyArea2d operator -(const ossimPolyArea2d& rhs)const;
+
+   /*!
+    * This will do the same as - but will
+    * update itself.
+    */
+   ossimPolyArea2d& operator -=(const ossimPolyArea2d& rhs);
+   
+   /*!
+    * do a union of 2 polygons.
+    */
+   ossimPolyArea2d operator +(const ossimPolyArea2d& rhs)const;
+
+   /*!
+    * This will do the same as the operator
+    * + but will update itself.
+    */
+   ossimPolyArea2d& operator +=(const ossimPolyArea2d& rhs);
+
+
+   /*!
+    * do an intersection of 2 polygons
+    */
+   ossimPolyArea2d operator &(const ossimPolyArea2d& rhs)const;
+
+   /*!
+    * This will do the same as the operator &
+    * but will update itself.
+    */
+
+   ossimPolyArea2d& operator &=(const ossimPolyArea2d& rhs);
+
+   /*!
+    * Will perform the "excusive or" of the this
+    * object with the right side
+    */
+   ossimPolyArea2d operator ^(const ossimPolyArea2d& rhs)const;
+
+   /*!
+    * This is the non const version and will update
+    * itself.
+    */
+   ossimPolyArea2d& operator ^=(const ossimPolyArea2d& rhs);
+
+   /*!
+    * This only makes since if you know that there are no holes.
+    * For example, using it after an intersection only operation by loading
+    * up two filled regions and intersecting them.
+    */
+   bool getAllVisiblePolygons(vector<ossimPolygon>& polyList)const;
+   
+   bool isEmpty()const
+      {
+         return (thePolygon == NULL);
+      }
+
+   bool isPointWithin(const ossimDpt& point)const;
+   bool isPointWithin(double x, double y)const;
+   void getBoundingRect(ossimDrect& rect);
+
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix=0)const;
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix=0);
+protected:
+   POLYAREA *thePolygon;
+
+   void loadPolygonForCurrentContour(ossimPolygon& polygon,
+                                     bool visible);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyLine.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyLine.cpp
new file mode 100644
index 0000000000..bde984f798
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyLine.cpp
@@ -0,0 +1,573 @@
+//*****************************************************************************
+// FILE: ossimPolygon.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Garrett Potts (gpotts@imagelinks.com)
+//
+//*****************************************************************************
+//  $Id: ossimPolyLine.cpp,v 1.13 2004/12/21 20:12:40 gpotts Exp $
+//
+#include "ossimPolyLine.h"
+#include "base/common/ossimCommon.h"
+#include <algorithm>
+#include "base/common/ossimKeywordNames.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/data_types/ossimLine.h"
+#include "base/data_types/ossimPolygon.h"
+#include <sstream>
+#include <iterator>
+using namespace std;
+
+static const char* NUMBER_VERTICES_KW = "number_vertices";
+
+ossimPolyLine::ossimPolyLine(const vector<ossimIpt>& polyLine)
+   :theCurrentVertex(0)
+{
+   theVertexList.insert(theVertexList.end(),
+                        polyLine.begin(),
+                        polyLine.end());;
+}
+
+ossimPolyLine::ossimPolyLine(const vector<ossimDpt>& polyLine)
+   :theCurrentVertex(0)
+{
+   theVertexList = polyLine;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimPolyLine(int numVertices, const ossimDpt* vertex_array)
+//  
+//*****************************************************************************
+ossimPolyLine::ossimPolyLine(int numVertices, const ossimDpt* v)
+   : theCurrentVertex(0)
+{
+   theVertexList.insert(theVertexList.begin(),
+                        v, v+numVertices);
+}
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: ossimPolyLine(ossimPolyLine)
+//  
+//*****************************************************************************
+ossimPolyLine::ossimPolyLine(const ossimPolyLine& polyLine)
+   :theCurrentVertex(0)
+{
+   *this = polyLine;
+}
+
+ossimPolyLine::ossimPolyLine(ossimDpt v1,
+                             ossimDpt v2,
+                             ossimDpt v3,
+                             ossimDpt v4)
+   : theVertexList(4),
+     theCurrentVertex(0)
+{
+   theVertexList[0] = v1;
+   theVertexList[1] = v2;
+   theVertexList[2] = v3;
+   theVertexList[3] = v4;
+}
+
+ossimPolyLine::ossimPolyLine(const ossimIrect& rect)
+   : theVertexList(4),
+     theCurrentVertex(0)
+{
+   theVertexList[0] = rect.ul();
+   theVertexList[1] = rect.ur();
+   theVertexList[2] = rect.lr();
+   theVertexList[3] = rect.ll();
+}
+
+ossimPolyLine::ossimPolyLine(const ossimDrect& rect)
+   : theVertexList(4),
+     theCurrentVertex(0)
+{
+   theVertexList[0] = rect.ul();
+   theVertexList[1] = rect.ur();
+   theVertexList[2] = rect.lr();
+   theVertexList[3] = rect.ll();
+}
+
+ossimPolyLine::ossimPolyLine(const ossimPolygon& polygon)
+   :theVertexList(polygon.getNumberOfVertices()+1),
+    theCurrentVertex(0)
+{
+   ossim_uint32 n = polygon.getNumberOfVertices();
+   
+   if(n)
+   {
+      for(ossim_uint32 i = 0; i < n; ++i)
+      {
+         theVertexList[i] = polygon[i];
+      }
+
+      theVertexList[n] = polygon[n-1];
+   }
+   else
+   {
+      theVertexList.clear();
+   }
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimPolyLine
+//  
+//*****************************************************************************
+ossimPolyLine::~ossimPolyLine()
+{
+}
+
+void ossimPolyLine::roundToIntegerBounds(bool compress)
+{
+  int i = 0;
+  for(i = 0; i < (int)theVertexList.size(); ++i)
+    {
+      theVertexList[i] = ossimIpt(theVertexList[i]);
+    }
+  if(compress&&theVertexList.size())
+    {
+      vector<ossimDpt> polyLine;
+      
+      polyLine.push_back(theVertexList[0]);
+      ossimDpt testPt = theVertexList[0];
+      for(i=1; i < (int)theVertexList.size(); ++i)
+	{
+	  if(testPt!=theVertexList[i])
+	    {
+	      testPt = theVertexList[i];
+	      polyLine.push_back(testPt);
+	    }
+	}
+      theVertexList    = polyLine;
+      theCurrentVertex = 0;
+    }
+}
+
+bool ossimPolyLine::hasNans()const
+{
+   int upper = (int)theVertexList.size();
+   int i = 0;
+
+   for(i = 0; i < upper; ++i)
+   {
+      if(theVertexList[i].hasNans())
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+void ossimPolyLine::getIntegerBounds(ossim_int32& minX,
+                                     ossim_int32& minY,
+                                     ossim_int32& maxX,
+                                     ossim_int32& maxY)const
+{
+   ossim_int32 npoly = (ossim_int32)theVertexList.size();
+   int i = 0;
+   
+   if(npoly)
+   {
+      minX = (ossim_int32)floor(theVertexList[0].x);
+      maxX = (ossim_int32)ceil(theVertexList[0].x);
+      minY = (ossim_int32)floor(theVertexList[0].y);
+      maxY = (ossim_int32)ceil(theVertexList[0].y);
+      
+      for(i =1; i < npoly; ++i)
+      {
+         minX = std::min((ossim_int32)floor(theVertexList[i].x),
+                         (ossim_int32)minX);
+         maxX = std::max((ossim_int32)ceil(theVertexList[i].x),
+                         (ossim_int32)maxX);
+         minY = std::min((ossim_int32)floor(theVertexList[i].y),
+                         (ossim_int32)minY);
+         maxY = std::max((ossim_int32)ceil(theVertexList[i].y),
+                         (ossim_int32)maxY);
+      }
+   }
+   else
+   {
+      minX = OSSIM_INT_NAN;
+      minY = OSSIM_INT_NAN;
+      maxX = OSSIM_INT_NAN;
+      maxY = OSSIM_INT_NAN;
+   }
+}
+
+void ossimPolyLine::getBounds(double& minX,
+                              double& minY,
+                              double& maxX,
+                              double& maxY)const
+{
+   ossim_int32 npoly = (ossim_int32)theVertexList.size();
+   
+   if(npoly)
+   {
+      int i = 0;
+      minX = theVertexList[0].x;
+      maxX = theVertexList[0].x;
+      minY = theVertexList[0].y;
+      maxY = theVertexList[0].y;
+      
+      for(i =1; i < npoly; ++i)
+      {
+         minX = std::min(theVertexList[i].x, minX);
+         maxX = std::max(theVertexList[i].x, maxX);
+         minY = std::min(theVertexList[i].y, minY);
+         maxY = std::max(theVertexList[i].y, maxY);
+      }
+   }
+   else
+   {
+      minX = OSSIM_DBL_NAN;
+      minY = OSSIM_DBL_NAN;
+      maxX = OSSIM_DBL_NAN;
+      maxY = OSSIM_DBL_NAN;
+   }
+}
+
+bool ossimPolyLine::isWithin(const ossimDrect& rect)const
+{
+   if(theVertexList.size() == 1)
+   {
+      return rect.pointWithin(theVertexList[0]);
+   }
+   else if(theVertexList.size() > 1)
+   {
+      for(ossim_uint32 i = 0; i < (theVertexList.size() - 1); ++i)
+      {
+         ossimDpt p1 = theVertexList[i];
+         ossimDpt p2 = theVertexList[i+1];
+         
+         if(rect.clip(p1, p2))
+         {
+            return true;
+         }
+      }
+   }
+
+   return false;
+}
+
+
+bool ossimPolyLine::clipToRect(vector<ossimPolyLine>& result,
+                              const ossimDrect& rect)const
+{
+   result.clear();
+   
+   if(theVertexList.size() <1) return false;
+
+   ossimPolyLine currentPoly;
+
+   if(theVertexList.size() == 1)
+   {
+      rect.pointWithin(theVertexList[0]);
+      currentPoly.addPoint(theVertexList[0]);
+      result.push_back(currentPoly);
+   }
+   else
+   {
+      ossimDpt pt1 = theVertexList[0];
+      ossimDpt pt2 = theVertexList[1];
+      ossim_uint32 i = 1;
+      
+      while(i < theVertexList.size())
+      {
+         
+         bool p1Inside = rect.pointWithin(pt1);
+         bool p2Inside = rect.pointWithin(pt2);
+
+         if(p1Inside&&p2Inside) // both inside so save the first
+         {
+            currentPoly.addPoint(pt1);
+            pt1 = pt2;            
+         }
+         // going from inside to outside
+         else if(p1Inside&&
+                 !p2Inside)
+         {
+            currentPoly.addPoint(pt1);
+            ossimDpt save = pt2;
+            if(rect.clip(pt1, pt2))
+            {
+               currentPoly.addPoint(pt2);
+               result.push_back(currentPoly);
+
+               currentPoly.clear();
+            }
+            pt2  = save;
+            pt1  = save;
+         }// going outside to the inside
+         else if(!p1Inside&&
+                 p2Inside)
+         {            
+            if(rect.clip(pt1, pt2))
+            {
+               currentPoly.addPoint(pt1);
+            }
+            pt1 = pt2;
+           
+         }
+         else // both outside must do a clip to see if crosses rect
+         {
+            ossimDpt p1 = pt1;
+            ossimDpt p2 = pt2;
+
+            if(rect.clip(p1, p2))
+            {
+               currentPoly.addPoint(p1);
+               currentPoly.addPoint(p2);
+            }
+            pt1 = pt2;
+         }
+         ++i;
+         
+         if(i < theVertexList.size())
+         {
+            pt2 = theVertexList[i];
+         }            
+      }
+      if(rect.pointWithin(pt2))
+      {
+         currentPoly.addPoint(pt2);
+      }
+   }
+
+   if(currentPoly.getNumberOfVertices() > 0)
+   {
+      result.push_back(currentPoly);
+   }
+   
+   return (result.size()>0);
+}   
+
+bool ossimPolyLine::isPointWithin(const ossimDpt& point) const
+{
+   if(theVertexList.size() == 1)
+   {
+      return (point == theVertexList[0]);
+   }
+   else
+   {
+      for(ossim_uint32 i = 1; i < theVertexList.size(); ++i)
+      {
+         if(ossimLine(theVertexList[i-1],
+                      theVertexList[i]).isPointWithin(point))
+         {
+            return true;
+         }
+      }
+   }
+   
+   return false;
+}
+
+bool ossimPolyLine::vertex(int index, ossimDpt& tbd_vertex) const 
+{
+   if((index >= (int)theVertexList.size()) ||
+      (index < 0))
+   {
+      return false;
+   }
+
+   tbd_vertex = theVertexList[index];
+   theCurrentVertex = index;
+
+   return true;
+}
+
+bool ossimPolyLine::nextVertex(ossimDpt& tbd_vertex) const 
+{
+   ++theCurrentVertex;
+   if(theCurrentVertex >= (ossim_int32)theVertexList.size())
+   {
+      return false;
+   }
+   tbd_vertex = theVertexList[theCurrentVertex];
+   
+   return true;
+}
+
+
+const ossimPolyLine&  ossimPolyLine::operator=(const ossimPolygon& polygon)
+{
+   theCurrentVertex = 0;
+   ossim_uint32 n = polygon.getNumberOfVertices();
+   
+   if(n)
+   {
+      theVertexList.resize(n+1);
+      
+      for(ossim_uint32 i = 0; i < n; ++i)
+      {
+         theVertexList[i] = polygon[i];
+      }
+      
+      theVertexList[n] = polygon[n-1];
+   }
+   else
+   {
+      theVertexList.clear();
+   }
+
+   return *this;
+}
+
+const ossimPolyLine&  ossimPolyLine::operator=(const ossimPolyLine& polyLine)
+{
+   theVertexList    = polyLine.theVertexList;
+   theCurrentVertex = polyLine.theCurrentVertex;
+   theAttributeList = polyLine.theAttributeList;
+   
+   return *this;
+}
+
+const ossimPolyLine& ossimPolyLine::operator= (const vector<ossimDpt>& vertexList)
+{
+   theVertexList    = vertexList;
+   theCurrentVertex = 0;
+   
+   return *this;
+}
+
+const ossimPolyLine& ossimPolyLine::operator= (const vector<ossimIpt>& vertexList)
+{
+   theVertexList.clear();
+   theVertexList.insert(theVertexList.end(),
+                        vertexList.begin(),
+                        vertexList.end());
+   
+   theCurrentVertex = 0;
+   
+   return *this;
+}
+
+//*****************************************************************************
+//  METHOD: operator==()
+//  
+//*****************************************************************************
+bool ossimPolyLine::operator==(const ossimPolyLine& polyLine) const
+{
+   if( (theVertexList.size() != polyLine.theVertexList.size()))
+   {
+      return false;
+   }
+   if(!theVertexList.size() && polyLine.theVertexList.size())
+   {
+      return true;
+   }
+
+   return (theVertexList == polyLine.theVertexList);
+}
+
+const ossimPolyLine& ossimPolyLine::operator *=(const ossimDpt& scale)
+{
+   int upper = theVertexList.size();
+   int i = 0;
+   
+   for(i = 0; i < upper; ++i)
+   {
+      theVertexList[i].x*=scale.x;
+      theVertexList[i].y*=scale.y;
+   }
+   
+   return *this;
+}
+
+ossimPolyLine ossimPolyLine::operator *(const ossimDpt& scale)const
+{
+   ossimPolyLine result(*this);
+
+   int i = 0;
+   int upper = theVertexList.size();
+   for(i = 0; i < upper; ++i)
+   {
+      result.theVertexList[i].x*=scale.x;
+      result.theVertexList[i].y*=scale.y;
+   }
+
+   return result;
+}
+
+
+void ossimPolyLine::reverseOrder()
+{
+   std::reverse(theVertexList.begin(), theVertexList.end());   
+}
+
+//*****************************************************************************
+//  METHOD: ossimPolyLine::print(ostream)
+//  
+//*****************************************************************************
+void ossimPolyLine::print(ostream& os) const
+{
+   copy(theVertexList.begin(),
+        theVertexList.end(),
+        ostream_iterator<ossimDpt>(os, "\n"));
+}
+
+bool ossimPolyLine::saveState(ossimKeywordlist& kwl,
+                             const char* prefix)const
+{
+   int i = 0;
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           "ossimPolyLine",
+           true);
+   kwl.add(prefix,
+           NUMBER_VERTICES_KW,
+           (int)theVertexList.size(),
+           true);
+   for(i = 0; i < (int)theVertexList.size();++i)
+   {
+      ossimString vert = "v"+ossimString::toString(i);;
+      ossimString value = (ossimString::toString(theVertexList[i].x) + " " +
+                           ossimString::toString(theVertexList[i].y) );
+      kwl.add(prefix,
+              vert.c_str(),
+              value.c_str(),
+              true);
+   }
+   ossimString order = "";
+   
+   return true;
+}
+   
+bool ossimPolyLine::loadState(const ossimKeywordlist& kwl,
+                             const char* prefix)
+{
+   const char* number_vertices = kwl.find(prefix, NUMBER_VERTICES_KW);
+   int i = 0;
+
+   theVertexList.clear();
+   int vertexCount = ossimString(number_vertices).toLong();
+   double x = 0.0, y =0.0;
+   for(i = 0; i < vertexCount; ++i)
+   {
+      ossimString v = kwl.find(prefix, (ossimString("v")+ossimString::toString(i)).c_str());
+      v = v.trim();
+
+      istringstream vStream(v);
+      vStream >> x >> y;
+      theVertexList.push_back(ossimDpt(x,y));
+   }
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyLine.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyLine.h
new file mode 100644
index 0000000000..ca7ad34ebc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolyLine.h
@@ -0,0 +1,257 @@
+//*****************************************************************************
+// FILE: ossimPolygon.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains declaration of class ossimPolygon.
+//   This class provides utilities associated with N-vertex, convex
+//   (i.e., only two intersections for any line passing through the polygon).
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimPolyLine.h,v 1.10 2004/12/21 20:12:40 gpotts Exp $
+
+#ifndef ossimPolyLine_HEADER
+#define ossimPolyLine_HEADER
+#include <iostream>
+#include <vector>
+using namespace std;
+
+#include "ossimDpt.h"
+#include "ossimDrect.h"
+#include "ossimIrect.h"
+#include <base/data_types/ossimString.h>
+class OSSIMDLLEXPORT ossimLine;
+class OSSIMDLLEXPORT ossimPolygon;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimPolyLine
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimPolyLine
+{
+public:
+   ossimPolyLine()
+      :theCurrentVertex(0)
+      {}
+   ossimPolyLine(const vector<ossimIpt>& polygon);
+   ossimPolyLine(const vector<ossimDpt>& polygon);
+   ossimPolyLine(int numVertices, const ossimDpt* vertex_array);
+   
+   ossimPolyLine(const ossimPolyLine& copy_this);
+   ossimPolyLine(const ossimPolygon& polygon);
+   
+   /*!
+    * CONSTRUCTOR: Provided for convenience. Does not imply the polygon is
+    * limited to four vertices:
+    */
+   ossimPolyLine(ossimDpt v1,
+                ossimDpt v2,
+                ossimDpt v3,
+                ossimDpt v4);
+   
+   ossimPolyLine(const ossimIrect& rect);
+   ossimPolyLine(const ossimDrect& rect);
+
+   ~ossimPolyLine();
+
+   ossimDpt& operator[](int index)
+      {
+         return theVertexList[index];
+      }
+   const ossimDpt& operator[](int index)const
+      {
+         return theVertexList[index];
+      }
+   
+   ossim_uint32 getNumberOfVertices()const
+      {
+         return theVertexList.size();
+      }
+   
+   void getIntegerBounds(ossim_int32& minX,
+                         ossim_int32& minY,
+                         ossim_int32& maxX,
+                         ossim_int32& maxY)const;
+   void getBounds(double& minX,
+                  double& minY,
+                  double& maxX,
+                  double& maxY)const;
+   void getBoundingRect(ossimDrect& rect)const
+      {
+         ossim_int32 minX;
+         ossim_int32 minY;
+         ossim_int32 maxX;
+         ossim_int32 maxY;
+         getIntegerBounds(minX, minY, maxX, maxY);
+         rect = ossimDrect(minX, minY, maxX, maxY);
+         
+      }
+   ossimDrect getBoundingRect()const
+      {
+         ossimDrect result;
+
+         getBoundingRect(result);
+
+         return result;
+      }
+   
+   void roundToIntegerBounds(bool compress=true);
+   void clear()
+      {
+         theVertexList.clear();
+      }
+   void addPoint(const ossimDpt& pt)
+      {
+         theVertexList.push_back(pt);
+      }
+   void addPoint(double x, double y)
+      {
+         theVertexList.push_back(ossimDpt(x, y));
+      }
+   void addAttribute( const ossimString& attribute )
+     {
+       theAttributeList.push_back( attribute );
+     }
+
+   ossimDpt midPoint()const;
+   
+   /*!
+    * will sequence through the polygon and check to see if any values are NAN
+    */
+   bool hasNans()const;
+  
+  ossim_uint32 size()
+  {
+    return getNumberOfVertices();
+  }
+  void resize(ossim_uint32 newSize)
+  {
+    theVertexList.resize(newSize);
+  }
+   const vector<ossimDpt>& getVertexList()const
+      {
+         return theVertexList;
+      }
+
+   vector<ossimDpt>& getVertexList()
+      {
+         return theVertexList;
+      }
+   vector<ossimString>& getAttributeList()
+      {
+         return theAttributeList;
+      }
+      
+   bool clipToRect(vector<ossimPolyLine>& result,
+                   const ossimDrect& rect)const;
+
+   /*!
+    * Will clip this poly line list to the past in rect and
+    * will return true if any part of this object is visible within
+    * the rectangle;
+    */
+   bool isWithin(const ossimDrect& rect)const;
+   
+   
+   /*!
+    * METHOD: pointWithin(ossimDpt)
+    * Returns TRUE if point is inside polygon.
+    */
+   bool pointWithin(const ossimDpt& point) const
+      {
+         return isPointWithin(point);
+      }
+   bool isPointWithin(const ossimDpt& point) const;
+
+   /*!
+    * METHOD: vertex(index)
+    * Returns the ossimDpt vertex given the index. Returns false if no vertex
+    * defined.
+    */
+   bool vertex(int index, ossimDpt& tbd_vertex) const;
+
+   /*!
+    * METHOD: nextVertex()
+    * Assigns the ossimDpt tbd_vertex following the current vertex. The current
+    * vertex is initialized with a call to vertex(int), or after the last
+    * vertex is reached. Returns false if no vertex defined. Intended to be
+    * when cycling through all vertices.
+    */
+   bool nextVertex(ossimDpt& tbd_vertex) const;
+
+   void reverseOrder();
+   /*!
+    * OPERATORS: (Some are inlined at bottom) 
+    */
+   const ossimPolyLine& operator= (const ossimPolyLine& copy_this);
+   const ossimPolyLine& operator= (const vector<ossimDpt>& vertexList);
+   const ossimPolyLine& operator= (const vector<ossimIpt>& vertexList);
+   const ossimPolyLine& operator= (const ossimIrect& rect);
+   const ossimPolyLine& operator= (const ossimPolygon& polygon);
+   const ossimPolyLine& operator= (const ossimDrect& rect);
+   bool                operator==(const ossimPolyLine& compare_this) const;
+   bool                operator!=(const ossimPolyLine& compare_this) const;
+
+   const ossimPolyLine& operator *=(const ossimDpt& scale);
+   const ossimPolyLine& operator *=(double scale)
+      {
+         return ((*this)*=ossimDpt(scale, scale));
+      }
+   
+   ossimPolyLine operator *(const ossimDpt& scale)const;
+   ossimPolyLine operator *(double scale)const
+      {
+         return ((*this)*ossimDpt(scale, scale));
+      }
+
+   /*!
+    * METHOD: print()
+    */
+   void print(ostream& os) const;
+   friend ostream& operator<<(ostream&, const ossimPolyLine&);
+
+
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix=0)const;
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix=0);
+protected:
+   vector<ossimDpt> theVertexList;
+   vector<ossimString> theAttributeList;
+   
+   mutable ossim_int32 theCurrentVertex;
+};
+
+inline bool ossimPolyLine::operator!=(const ossimPolyLine& compare_this) const
+{
+   return !(*this == compare_this);
+}
+
+inline ostream& operator<<(ostream& os, const ossimPolyLine& polyLine)
+{
+   polyLine.print(os);
+   return os;
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimPolygon.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolygon.cpp
new file mode 100644
index 0000000000..e1f4b12a9e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolygon.cpp
@@ -0,0 +1,992 @@
+//*****************************************************************************
+// FILE: ossimPolygon.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimPolygon.cpp,v 1.47 2005/03/18 21:38:47 dburken Exp $
+
+#include <algorithm>
+#include <iterator>
+#include <sstream>
+#include <iterator>
+
+#include <base/data_types/ossimPolygon.h>
+#include <base/data_types/ossimLine.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimPolyArea2d.h>
+
+static const char* NUMBER_VERTICES_KW = "number_vertices";
+static const char* VERTEX_ORDER_KW    = "order";
+
+static const int RECT_LEFT_EDGE   = 0;
+static const int RECT_TOP_EDGE    = 1;
+static const int RECT_RIGHT_EDGE  = 2;
+static const int RECT_BOTTOM_EDGE = 3;
+
+ossimPolygon::ossimPolygon()
+   :theCurrentVertex(0),
+    theOrderingType(OSSIM_VERTEX_ORDER_UNKNOWN)
+{}
+
+ossimPolygon::ossimPolygon(const vector<ossimIpt>& polygon)
+   :theCurrentVertex(0),
+    theOrderingType(OSSIM_VERTEX_ORDER_UNKNOWN)
+{
+   theVertexList.insert(theVertexList.end(),
+                        polygon.begin(),
+                        polygon.end());;
+}
+
+ossimPolygon::ossimPolygon(const vector<ossimDpt>& polygon)
+   :theCurrentVertex(0),
+    theOrderingType(OSSIM_VERTEX_ORDER_UNKNOWN)
+{
+   theVertexList = polygon;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimPolygon(int numVertices, const ossimDpt* vertex_array)
+//  
+//*****************************************************************************
+ossimPolygon::ossimPolygon(int numVertices, const ossimDpt* v)
+   : theCurrentVertex(0),
+     theOrderingType(OSSIM_VERTEX_ORDER_UNKNOWN)
+{
+   theVertexList.insert(theVertexList.begin(),
+                        v, v+numVertices);
+}
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: ossimPolygon(ossimPolygon)
+//  
+//*****************************************************************************
+ossimPolygon::ossimPolygon(const ossimPolygon& polygon)
+   :theCurrentVertex(0)
+{
+   *this = polygon;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimPolygon(p1, p2, p3, p4)
+//  
+//  Provided for convenience. Does not imply the polygon is limited to four
+//  vertices
+//  
+//*****************************************************************************
+ossimPolygon::ossimPolygon(ossimDpt v1,
+                           ossimDpt v2,
+                           ossimDpt v3,
+                           ossimDpt v4)
+   : theVertexList(4),
+     theCurrentVertex(0),
+     theOrderingType(OSSIM_VERTEX_ORDER_UNKNOWN)
+{
+   theVertexList[0] = v1;
+   theVertexList[1] = v2;
+   theVertexList[2] = v3;
+   theVertexList[3] = v4;
+}
+
+ossimPolygon::ossimPolygon(const ossimIrect& rect)
+   : theVertexList(4),
+     theCurrentVertex(0),
+     theOrderingType(OSSIM_CLOCKWISE_ORDER)
+{
+   theVertexList[0] = rect.ul();
+   theVertexList[1] = rect.ur();
+   theVertexList[2] = rect.lr();
+   theVertexList[3] = rect.ll();
+}
+
+ossimPolygon::ossimPolygon(const ossimDrect& rect)
+   : theVertexList(4),
+     theCurrentVertex(0),
+     theOrderingType(OSSIM_CLOCKWISE_ORDER)
+{
+   theVertexList[0] = rect.ul();
+   theVertexList[1] = rect.ur();
+   theVertexList[2] = rect.lr();
+   theVertexList[3] = rect.ll();
+}
+
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimPolygon
+//  
+//*****************************************************************************
+ossimPolygon::~ossimPolygon()
+{
+}
+
+
+double ossimPolygon::area()const
+{
+   double area = 0;
+   int i=0;
+   int j=0;
+   int size = theVertexList.size();
+   
+   for (i=0;i<(int)size;i++)
+   {
+      j = (i + 1) % (int)size;
+      area += theVertexList[i].x * theVertexList[j].y;
+      area -= theVertexList[i].y * theVertexList[j].x;
+   }
+
+   area /= 2;
+
+   return area;
+}
+
+void ossimPolygon::roundToIntegerBounds(bool compress)
+{
+   int i = 0;
+   for(i = 0; i < (int)theVertexList.size(); ++i)
+   {
+      theVertexList[i] = ossimIpt(theVertexList[i]);
+   }
+
+  if(compress&&theVertexList.size())
+   {
+      vector<ossimDpt> polyLine;
+      
+      polyLine.push_back(theVertexList[0]);
+      ossimDpt testPt = theVertexList[0];
+      for(i=1; i < (int)theVertexList.size(); ++i)
+      {
+         if(testPt!=theVertexList[i])
+         {
+            testPt = theVertexList[i];
+            polyLine.push_back(testPt);
+         }
+      }
+      if(polyLine.size() == 1)
+      {
+         polyLine.push_back(polyLine[0]);
+      }
+      
+      if(theVertexList.size() == 1)
+      {
+         polyLine.push_back(testPt);
+      }
+      theVertexList    = polyLine;
+      theCurrentVertex = 0;
+   }
+}
+
+ossimDpt ossimPolygon::midPoint()const
+{
+   int upper = (int)theVertexList.size();
+   ossimDpt result(0.0, 0.0);
+   int i = 0;
+
+   if(!upper)
+   {
+      result.makeNan();
+   }
+   else
+   {
+      for(i = 0; i < upper; ++upper)
+      {
+         result.x+=theVertexList[i].x;
+         result.y+=theVertexList[i].y;
+      }
+      result.x/=(double)upper;
+      result.y/=(double)upper;
+   }
+   
+   return result;
+}
+
+bool ossimPolygon::hasNans()const
+{
+   int upper = (int)theVertexList.size();
+   int i = 0;
+
+   for(i = 0; i < upper; ++i)
+   {
+      if(theVertexList[i].hasNans())
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+void ossimPolygon::getIntegerBounds(ossim_int32& minX,
+                                    ossim_int32& minY,
+                                    ossim_int32& maxX,
+                                    ossim_int32& maxY)const
+{
+   ossim_int32 npoly = (ossim_int32)theVertexList.size();
+   int i = 0;
+   
+   if(npoly)
+   {
+      minX = (ossim_int32)floor(theVertexList[0].x);
+      maxX = (ossim_int32)ceil(theVertexList[0].x);
+      minY = (ossim_int32)floor(theVertexList[0].y);
+      maxY = (ossim_int32)ceil(theVertexList[0].y);
+      
+      for(i =1; i < npoly; ++i)
+      {
+         minX = std::min((ossim_int32)floor(theVertexList[i].x),
+                         (ossim_int32)minX);
+         maxX = std::max((ossim_int32)ceil(theVertexList[i].x),
+                         (ossim_int32)maxX);
+         minY = std::min((ossim_int32)floor(theVertexList[i].y),
+                         (ossim_int32)minY);
+         maxY = std::max((ossim_int32)ceil(theVertexList[i].y),
+                         (ossim_int32)maxY);
+      }
+   }
+   else
+   {
+      minX = OSSIM_INT_NAN;
+      minY = OSSIM_INT_NAN;
+      maxX = OSSIM_INT_NAN;
+      maxY = OSSIM_INT_NAN;
+   }
+}
+
+bool ossimPolygon::clipToRect(vector<ossimPolygon>& result,
+                              const ossimDrect& rect)const
+{
+   result.clear();
+   ossimPolyArea2d p1(*this);
+   ossimPolyArea2d p2(rect.ul(), rect.ur(), rect.lr(), rect.ll());
+   
+   p1&=p2;
+
+   p1.getAllVisiblePolygons(result);
+
+   return (result.size() > 0);
+}   
+
+//*****************************************************************************
+//  METHOD: ossimPolygon::clipLineSegment(p1, p2)
+//  
+//  Implements Cyrus-Beck clipping algorithm as described in:
+//  http://www.daimi.au.dk/~mbl/cgcourse/wiki/cyrus-beck_line-clipping_.html
+//
+//  Clips the line segment defined by the two endpoints provided. The
+//  endpoints are modified as needed to represent the clipped line. Returns
+//  true if intersection present.
+//  
+//*****************************************************************************
+bool ossimPolygon::clipLineSegment(ossimDpt& P, ossimDpt& Q) const
+{
+   ossimDpt PQ (Q - P);
+   double tE = 0.0;
+   double tL = 1.0;
+   ossimLine edge, edgeE, edgeL;
+   bool intersected=false;
+   double num, denom, t;
+   int npol = theVertexList.size();
+
+   checkOrdering();
+   //***
+   // clip the segment against each edge of the polygon
+   //***
+   int i = 0;
+   int j = 0;
+   for(i = 0, j = 1; i < npol;)
+   {
+      edge = ossimLine(theVertexList[i],
+                       theVertexList[j]);
+      
+      ossimDpt normal = edge.normal();
+
+      // Fix from CChuah@observera.com for counter clockwise polygons. (drb)
+      if (theOrderingType == OSSIM_COUNTERCLOCKWISE_ORDER)
+      {
+         normal.x = -normal.x;
+         normal.y = -normal.y;
+      }
+      
+      denom = normal.x*PQ.x + normal.y*PQ.y;
+      
+      num = normal.x*(edge.theP1.x - P.x) + normal.y*(edge.theP1.y - P.y);
+      
+      if (denom < 0)
+      {
+         //***
+         // Appears to be entering:
+         //***
+         t = num / denom;
+         if (t > tE)
+         {
+            tE = t; //+ FLT_EPSILON;
+            edgeE = edge;
+         }
+      }
+      else if (denom > 0)
+      {
+         //***
+         // Appears to be leaving:
+         //***
+         t = num / denom;
+         if (t < tL)
+         {
+            tL = t;// - FLT_EPSILON;
+            edgeL = edge;
+         }
+      }
+
+      ++i;
+      ++j;
+      j%=npol;
+   } 
+   
+   //***
+   // Compute clipped end points:
+   //***
+   if(tL >= tE)
+   {
+       Q.x = P.x + tL*PQ.x;
+       Q.y = P.y + tL*PQ.y;
+       P.x += tE*PQ.x;
+       P.y += tE*PQ.y;
+       intersected = true;
+   }
+   
+   return intersected;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimPolygon::pointWithin(const ossimDpt& point)
+//  
+//  Returns TRUE if point is inside polygon.
+//  
+//*****************************************************************************
+bool ossimPolygon::isPointWithin(const ossimDpt& point) const
+{
+
+   int i, j, c = 0;
+   int npol = (int)theVertexList.size();
+
+   for (i = 0, j = npol-1; i < npol; j = i++)
+   {
+      if ((((theVertexList[i].y <= point.y) && (point.y < theVertexList[j].y)) ||
+           ((theVertexList[j].y <= point.y) && (point.y < theVertexList[i].y))) &&
+          (point.x < (theVertexList[j].x - theVertexList[i].x) * (point.y - theVertexList[i].y) /
+           (theVertexList[j].y - theVertexList[i].y) + theVertexList[i].x))
+      {
+         c = !c;
+      }
+   }
+
+   if(!c) // check if on if not within
+   {
+      for (i = 0, j = npol-1; i < npol; j = i++)
+      {
+         if(ossimLine(theVertexList[i], theVertexList[j]).isPointWithin(point))
+         {
+            return true;
+         }
+      }
+   }
+
+   return (c!=0);
+}
+
+//*****************************************************************************
+//  METHOD: ossimPolygon::vertex(int)
+//  
+//  Returns the ossimDpt vertex given the index. Also initializes the current
+//  edge (theCurrentEdge) to the edge corresponding to the index.
+//  
+//*****************************************************************************
+bool ossimPolygon::vertex(int index, ossimDpt& tbd_vertex) const 
+{
+   if((index >= (int)theVertexList.size()) ||
+      (index < 0))
+   {
+      return false;
+   }
+
+   tbd_vertex = theVertexList[index];
+   theCurrentVertex = index;
+
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimPolygon::nextVertex()
+//  
+//  Assigns the ossimDpt tbd_vertex following the current vertex. The current
+//  vertex is initialized with a call to vertex(int), or after the last
+//  vertex is reached (initialized to theFirstEdge. Returns false if no vertex
+//  defined.
+//
+//*****************************************************************************
+bool ossimPolygon::nextVertex(ossimDpt& tbd_vertex) const 
+{
+   ++theCurrentVertex;
+   if(theCurrentVertex >= (ossim_int32)theVertexList.size())
+   {
+      return false;
+   }
+   tbd_vertex = theVertexList[theCurrentVertex];
+   
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: operator=()
+//  
+//*****************************************************************************
+const ossimPolygon& ossimPolygon::operator= (const ossimIrect& rect)
+{
+   theCurrentVertex = 0;
+   theVertexList.resize(4);
+   theVertexList[0] = rect.ul();
+   theVertexList[1] = rect.ur();
+   theVertexList[2] = rect.lr();
+   theVertexList[3] = rect.ll();
+
+   return *this;
+}
+
+const ossimPolygon& ossimPolygon::operator= (const ossimDrect& rect)
+{
+   theCurrentVertex = 0;
+   theVertexList.resize(4);
+   theVertexList[0] = rect.ul();
+   theVertexList[1] = rect.ur();
+   theVertexList[2] = rect.lr();
+   theVertexList[3] = rect.ll();
+
+   return *this;
+}
+
+const ossimPolygon&  ossimPolygon::operator=(const ossimPolygon& polygon)
+{
+   theVertexList    = polygon.theVertexList;
+   theCurrentVertex = polygon.theCurrentVertex;
+   theOrderingType  = polygon.theOrderingType;
+   
+   return *this;
+}
+
+const ossimPolygon& ossimPolygon::operator= (const vector<ossimDpt>& vertexList)
+{
+   theVertexList    = vertexList;
+   theCurrentVertex = 0;
+   theOrderingType = OSSIM_VERTEX_ORDER_UNKNOWN;
+   
+   return *this;
+}
+
+const ossimPolygon& ossimPolygon::operator= (const vector<ossimIpt>& vertexList)
+{
+   theVertexList.clear();
+   theVertexList.insert(theVertexList.end(),
+                        vertexList.begin(),
+                        vertexList.end());
+   
+   theCurrentVertex = 0;
+   theOrderingType = OSSIM_VERTEX_ORDER_UNKNOWN;
+   
+   return *this;
+}
+
+//*****************************************************************************
+//  METHOD: operator==()
+//  
+//*****************************************************************************
+bool ossimPolygon::operator==(const ossimPolygon& polygon) const
+{
+   if( (theVertexList.size() != polygon.theVertexList.size()))
+   {
+      return false;
+   }
+   if(!theVertexList.size() && polygon.theVertexList.size())
+   {
+      return true;
+   }
+
+   return (theVertexList == polygon.theVertexList);
+}
+
+const ossimPolygon& ossimPolygon::operator *=(const ossimDpt& scale)
+{
+   int upper = theVertexList.size();
+   int i = 0;
+   for(i = 0; i < upper; ++i)
+   {
+      theVertexList[i].x*=scale.x;
+      theVertexList[i].y*=scale.y;
+   }
+   
+   return *this;
+}
+
+ossimPolygon ossimPolygon::operator *(const ossimDpt& scale)const
+{
+   ossimPolygon result(*this);
+
+   int upper = theVertexList.size();
+   int i = 0;
+   for(i = 0; i < upper; ++i)
+   {
+      result.theVertexList[i].x*=scale.x;
+      result.theVertexList[i].y*=scale.y;
+   }
+
+   return result;
+}
+
+
+void ossimPolygon::reverseOrder()
+{
+   std::reverse(theVertexList.begin(), theVertexList.end());
+   
+   if(theOrderingType == OSSIM_COUNTERCLOCKWISE_ORDER)
+   {
+      theOrderingType = OSSIM_CLOCKWISE_ORDER;
+   }
+   else if(theOrderingType == OSSIM_CLOCKWISE_ORDER)
+   {
+      theOrderingType =  OSSIM_COUNTERCLOCKWISE_ORDER;
+   }
+   
+}
+
+//*****************************************************************************
+//  METHOD: ossimPolygon::print(ostream)
+//  
+//*****************************************************************************
+void ossimPolygon::print(ostream& os) const
+{
+   copy(theVertexList.begin(),
+        theVertexList.end(),
+        ostream_iterator<ossimDpt>(os, "\n"));
+}
+
+
+void ossimPolygon::checkOrdering()const
+{
+   if(theOrderingType == OSSIM_VERTEX_ORDER_UNKNOWN)
+   {
+      double areaValue = area();
+      if(areaValue > 0)
+      {
+         theOrderingType = OSSIM_COUNTERCLOCKWISE_ORDER;
+      }
+      else if(areaValue <= 0)
+      {
+         theOrderingType = OSSIM_CLOCKWISE_ORDER;
+      }
+   }
+}
+
+void ossimPolygon::intersectEdge(ossimDpt& result,
+                                 const ossimLine& segment,
+                                 const ossimDrect& rect,
+                                 int edge)
+{
+   ossimLine edgeLine;
+   switch(edge)
+   {
+   case RECT_LEFT_EDGE:
+   {
+      edgeLine.theP1 = rect.ll();
+      edgeLine.theP2 = rect.ul();
+      break;
+   }
+   case RECT_TOP_EDGE:
+   {
+      edgeLine.theP1 = rect.ul();
+      edgeLine.theP2 = rect.ur();
+      break;
+   }
+   case RECT_RIGHT_EDGE:
+   {
+      edgeLine.theP1 = rect.ur();
+      edgeLine.theP2 = rect.lr();
+      break;
+   }
+   case RECT_BOTTOM_EDGE:
+   {
+      edgeLine.theP1 = rect.lr();
+      edgeLine.theP2 = rect.ll();
+      break;
+   }
+   }
+   
+   result = segment.intersectInfinite(edgeLine);
+}
+
+bool ossimPolygon::isInsideEdge(const ossimDpt& pt,
+                                const ossimDrect& rect,
+                                int edge)const
+{
+   switch(edge)
+   {
+   case RECT_LEFT_EDGE:
+   {
+      return (pt.x>rect.ul().x);
+      break;
+   }
+   case RECT_TOP_EDGE:
+   {
+      if(rect.orientMode() == OSSIM_LEFT_HANDED)
+      {
+         return (pt.y > rect.ul().y);
+      }
+      else
+      {
+         return (pt.y < rect.ul().y);
+      }
+      break;
+   }
+   case RECT_RIGHT_EDGE:
+   {
+      return (pt.x<rect.lr().x);
+      
+      break;
+   }
+   case RECT_BOTTOM_EDGE:
+   {
+      if(rect.orientMode() == OSSIM_LEFT_HANDED)
+      {
+         return (pt.y < rect.lr().y);
+      }
+      else
+      {
+         return (pt.y > rect.lr().y);
+      }
+      break;
+   }
+   }
+   return false;
+}
+
+
+bool ossimPolygon::saveState(ossimKeywordlist& kwl,
+                             const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           "ossimPolygon",
+           true);
+   kwl.add(prefix,
+           NUMBER_VERTICES_KW,
+           (int)theVertexList.size(),
+           true);
+   int i = 0;
+   for(i = 0; i < (int)theVertexList.size();++i)
+   {
+      ossimString vert = "v"+ossimString::toString(i);;
+      ossimString value = (ossimString::toString(theVertexList[i].x) + " " +
+                           ossimString::toString(theVertexList[i].y) );
+      kwl.add(prefix,
+              vert.c_str(),
+              value.c_str(),
+              true);
+   }
+   ossimString order = "";
+   
+   switch(theOrderingType)
+   {
+   case OSSIM_VERTEX_ORDER_UNKNOWN:
+   {
+      order = "unknown";
+      break;
+   }
+   case OSSIM_CLOCKWISE_ORDER:
+   {
+      order = "clockwise";
+      break;
+   }
+   case OSSIM_COUNTERCLOCKWISE_ORDER:
+   {
+      order = "counter_clockwise";
+      break;
+   }
+   }
+   kwl.add(prefix,
+           VERTEX_ORDER_KW,
+           order,
+           true);
+
+   return true;
+}
+   
+bool ossimPolygon::loadState(const ossimKeywordlist& kwl,
+                             const char* prefix)
+{
+   ossimString order = kwl.find(prefix, VERTEX_ORDER_KW);
+   const char* number_vertices = kwl.find(prefix, NUMBER_VERTICES_KW);
+
+   if(order=="unknown")
+   {
+      theOrderingType = OSSIM_VERTEX_ORDER_UNKNOWN;
+   }
+   else if(order =="clockwise")
+   {
+      theOrderingType = OSSIM_CLOCKWISE_ORDER;
+   }
+   else if(order =="counter_clockwise")
+   {
+      theOrderingType = OSSIM_COUNTERCLOCKWISE_ORDER;
+   }
+
+   theVertexList.clear();
+   int vertexCount = ossimString(number_vertices).toLong();
+   double x = 0.0, y =0.0;
+   int i = 0;
+   for(i = 0; i < vertexCount; ++i)
+   {
+      ossimString v = kwl.find(prefix, (ossimString("v")+ossimString::toString(i)).c_str());
+      v = v.trim();
+
+      istringstream vStream(v);
+      vStream >> x >> y;
+      theVertexList.push_back(ossimDpt(x,y));
+   }
+
+   return true;
+}
+
+void ossimPolygon::getMinimumBoundingRect(ossimPolygon& minRect) const
+{
+   static const double MIN_STEP = (0.5)*M_PI/180.0;
+   double angle_step = M_PI/8.0;  // initial rotation step size for min area search = 22.5 deg
+   double theta;
+   double best_theta = M_PI/4.0;  // Initial guess is 45 deg orientation
+   double center_theta;
+   double cos_theta, sin_theta;
+   ossimPolygon rotatedPolygon(*this);
+   ossimDpt xlatedVertex;
+   ossimDpt rotatedVertex(0.0, 0.0);
+   double min_x, min_y, max_x, max_y;
+   double area;
+   double min_area = OSSIM_INFINITY;
+   rotatedPolygon.theVertexList[0] = ossimDpt(0, 0);  // first vertex always at origin
+   bool first_time = true;
+   ossimDrect best_rect;
+   static const bool TESTING = false;
+
+   //***
+   // Loop to converge on best orientation angle for bounding polygon:
+   //***
+   while (angle_step > MIN_STEP)
+   {
+      //***
+      // Try four different rotations evenly centered about the current best guess:
+      //***
+      center_theta = best_theta;
+      for (int i=0; i<5; i++)
+      {
+         //***
+         // Check for i=2 (center angle) since already computed quantities for this in last iteration
+         // unless this is first time through:
+         //***
+         if ((i != 2) || (first_time)) 
+         {
+            theta = center_theta + (i - 2.0)*angle_step;
+            cos_theta = cos(theta);
+            sin_theta = sin(theta);
+            min_x = rotatedPolygon.theVertexList[0].x;
+            min_y = rotatedPolygon.theVertexList[0].y;
+            max_x = min_x;
+            max_y = min_y;
+
+            //***
+            // Translate polygon to origin and rotate all vertices by current theta:
+            //***
+            for (unsigned int vertex=1; vertex < theVertexList.size(); vertex++)
+            {
+               xlatedVertex.x = theVertexList[vertex].x - theVertexList[0].x;
+               xlatedVertex.y = theVertexList[vertex].y - theVertexList[0].y;
+               rotatedVertex.x = cos_theta*xlatedVertex.x + sin_theta*xlatedVertex.y;
+               rotatedVertex.y = cos_theta*xlatedVertex.y - sin_theta*xlatedVertex.x;
+               rotatedPolygon.theVertexList[vertex] = rotatedVertex;
+
+               //***
+               // Latch max and mins of bounding rect:
+               //***
+               if (min_x > rotatedVertex.x) min_x = rotatedVertex.x;
+               if (min_y > rotatedVertex.y) min_y = rotatedVertex.y;
+               if (max_x < rotatedVertex.x) max_x = rotatedVertex.x;
+               if (max_y < rotatedVertex.y) max_y = rotatedVertex.y;
+            }
+
+            if (TESTING)
+            {
+               ossimDpt v1 (cos_theta*min_x - sin_theta*max_y + theVertexList[0].x,
+                            cos_theta*max_y + sin_theta*min_x + theVertexList[0].y);
+               ossimDpt v2 (cos_theta*max_x - sin_theta*max_y + theVertexList[0].x,
+                            cos_theta*max_y + sin_theta*max_x + theVertexList[0].y);
+               ossimDpt v3 (cos_theta*max_x - sin_theta*min_y + theVertexList[0].x,
+                            cos_theta*min_y + sin_theta*max_x + theVertexList[0].y);
+               ossimDpt v4 (cos_theta*min_x - sin_theta*min_y + theVertexList[0].x,
+                            cos_theta*min_y + sin_theta*min_x + theVertexList[0].y);
+               cout << v1.x << "\t" << v1.y << endl;
+               cout << v2.x << "\t" << v2.y << endl;
+               cout << v3.x << "\t" << v3.y << endl;
+               cout << v4.x << "\t" << v4.y << endl << endl;
+            }
+
+            //***
+            // Establish bounding rect and area about rotated polygon:
+            //***
+            area = (max_x - min_x) * (max_y - min_y);
+            if (area < min_area)
+            {
+               best_theta = theta;
+               min_area = area;
+               best_rect = ossimDrect(min_x, max_y, max_x, min_y, OSSIM_RIGHT_HANDED);
+            }
+         } // end if (i != 2 || first_time)
+      }  // end for-loop over surrounding rotations
+
+      //***
+      // Adjust step size by half to repeat process:
+      //***
+      angle_step /= 2.0;
+      first_time = false;
+
+   } // end while loop for convergence
+
+   //***
+   // best_theta now contains optimum rotation of bounding rect. Need to apply reverse
+   // rotation and translation of best_rect:
+   //***
+   cos_theta = cos(best_theta);
+   sin_theta = sin(best_theta);
+   ossimDpt v1 (cos_theta*best_rect.ul().x - sin_theta*best_rect.ul().y + theVertexList[0].x,
+                cos_theta*best_rect.ul().y + sin_theta*best_rect.ul().x + theVertexList[0].y);
+   ossimDpt v2 (cos_theta*best_rect.ur().x - sin_theta*best_rect.ur().y + theVertexList[0].x,
+                cos_theta*best_rect.ur().y + sin_theta*best_rect.ur().x + theVertexList[0].y);
+   ossimDpt v3 (cos_theta*best_rect.lr().x - sin_theta*best_rect.lr().y + theVertexList[0].x,
+                cos_theta*best_rect.lr().y + sin_theta*best_rect.lr().x + theVertexList[0].y);
+   ossimDpt v4 (cos_theta*best_rect.ll().x - sin_theta*best_rect.ll().y + theVertexList[0].x,
+                cos_theta*best_rect.ll().y + sin_theta*best_rect.ll().x + theVertexList[0].y);
+    
+   if (TESTING)
+   {
+      cout << v1.x << "\t" << v1.y << endl;
+      cout << v2.x << "\t" << v2.y << endl;
+      cout << v3.x << "\t" << v3.y << endl;
+      cout << v4.x << "\t" << v4.y << endl << endl;
+   }
+
+   //***
+   // Assign return value rect:
+   //***
+   minRect.clear();
+   minRect.addPoint(v1);
+   minRect.addPoint(v2);
+   minRect.addPoint(v3);
+   minRect.addPoint(v4);
+
+   return;
+}
+
+ossimDpt& ossimPolygon::operator[](int index)
+{
+   return theVertexList[index];
+}
+
+const ossimDpt& ossimPolygon::operator[](int index)const
+{
+   return theVertexList[index];
+}
+
+ossim_uint32 ossimPolygon::getVertexCount()const
+{
+   return getNumberOfVertices();
+}
+
+ossim_uint32 ossimPolygon::getNumberOfVertices()const
+{
+   return theVertexList.size();
+}
+
+void ossimPolygon::getBoundingRect(ossimIrect& rect)const
+{
+   ossim_int32 minX;
+   ossim_int32 minY;
+   ossim_int32 maxX;
+   ossim_int32 maxY;
+   getIntegerBounds(minX, minY, maxX, maxY);
+   rect = ossimIrect(minX, minY, maxX, maxY);
+}
+
+void ossimPolygon::clear()
+{
+   theVertexList.clear();
+   theOrderingType = OSSIM_VERTEX_ORDER_UNKNOWN;
+}
+
+void ossimPolygon::addPoint(const ossimDpt& pt)
+{
+   theVertexList.push_back(pt);
+   theOrderingType = OSSIM_VERTEX_ORDER_UNKNOWN;
+}
+
+void ossimPolygon::addPoint(double x, double y)
+{
+   theVertexList.push_back(ossimDpt(x, y));
+   theOrderingType = OSSIM_VERTEX_ORDER_UNKNOWN;
+}
+
+const vector<ossimDpt>& ossimPolygon::getVertexList()const
+{
+   return theVertexList;
+}
+
+ bool ossimPolygon::pointWithin(const ossimDpt& point) const
+{
+   return isPointWithin(point);
+}
+
+const ossimPolygon& ossimPolygon::operator *=(double scale)
+{
+   return ((*this)*=ossimDpt(scale, scale));
+}
+
+ossimPolygon ossimPolygon::operator *(double scale)const
+{
+   return ((*this)*ossimDpt(scale, scale));
+}
+
+void ossimPolygon::resize(ossim_uint32 newSize)
+{
+   theVertexList.resize(newSize);
+   theOrderingType  = OSSIM_VERTEX_ORDER_UNKNOWN;
+   theCurrentVertex = 0;
+}
+
+ossimVertexOrdering ossimPolygon::getOrdering()const
+{
+   return theOrderingType;
+}
+
+bool ossimPolygon::operator!=(const ossimPolygon& compare_this) const
+{
+   return !(*this == compare_this);
+}
+
+ostream& operator<<(ostream& os, const ossimPolygon& polygon)
+{
+   polygon.print(os);
+   return os;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimPolygon.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolygon.h
new file mode 100644
index 0000000000..7aea4698e3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimPolygon.h
@@ -0,0 +1,209 @@
+//*****************************************************************************
+// FILE: ossimPolygon.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains declaration of class ossimPolygon.
+//   This class provides utilities associated with N-vertex, convex
+//   (i.e., only two intersections for any line passing through the polygon).
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimPolygon.h,v 1.36 2005/01/14 20:43:55 dburken Exp $
+
+#ifndef ossimPolygon_HEADER
+#define ossimPolygon_HEADER
+#include <iostream>
+#include <vector>
+using namespace std;
+
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/ossimIrect.h>
+
+class OSSIMDLLEXPORT ossimLine;
+
+/******************************************************************************
+ *
+ * CLASS:  ossimPolygon
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimPolygon
+{
+public:
+   ossimPolygon();
+   ossimPolygon(const vector<ossimIpt>& polygon);
+   ossimPolygon(const vector<ossimDpt>& polygon);
+   ossimPolygon(int numVertices, const ossimDpt* vertex_array);
+
+   ossimPolygon(const ossimPolygon& copy_this);
+   
+   /**
+    * CONSTRUCTOR: Provided for convenience. Does not imply the polygon is
+    * limited to four vertices:
+    */
+   ossimPolygon(ossimDpt v1,
+                ossimDpt v2,
+                ossimDpt v3,
+                ossimDpt v4);
+   
+   ossimPolygon(const ossimIrect& rect);
+   ossimPolygon(const ossimDrect& rect);
+
+   ~ossimPolygon();
+
+   ossimDpt& operator[](int index);
+   
+   const ossimDpt& operator[](int index)const;
+
+   ossim_uint32 getVertexCount()const;
+   
+   ossim_uint32 getNumberOfVertices()const;
+
+   double area()const;
+
+   void getIntegerBounds(ossim_int32& minX,
+                         ossim_int32& minY,
+                         ossim_int32& maxX,
+                         ossim_int32& maxY)const;
+
+   void getBoundingRect(ossimIrect& rect)const;
+
+   /**
+    * Initializes minRect with the minimum area rect (not-necessarily
+    * aligned with axes) that bounds this polygon.
+    *
+    * @param minRect Polygon to initialize with the minimum rect.
+    */
+   void getMinimumBoundingRect(ossimPolygon& minRect) const;
+   
+   void roundToIntegerBounds(bool compress=false);
+
+   void clear();
+
+   void addPoint(const ossimDpt& pt);
+   void addPoint(double x, double y);
+
+   ossimDpt midPoint()const;
+   
+   /**
+    * will sequence through the polygon and check to see if any values are NAN
+    */
+   bool hasNans()const;
+
+   const vector<ossimDpt>& getVertexList()const;
+      
+   /**
+    * Uses the ossimPolyArea2d class for the intersection
+    */
+   bool clipToRect(vector<ossimPolygon>& result,
+                   const ossimDrect& rect)const;
+
+   
+   /**
+    * METHOD: clipLineSegment(p1, p2)
+    * Implements Cyrus-Beck clipping algorithm as described in:
+    * http://www.daimi.au.dk/~mbl/cgcourse/wiki/cyrus-beck_line-clipping_.html
+    * Clips the line segment defined by thw two endpoints provided. The
+    * endpoints are modified as needed to represent the clipped line. Returnes
+    * true if intersection present.
+    */
+   bool clipLineSegment(ossimDpt& p1, ossimDpt& p2) const;
+
+   /**
+    * METHOD: pointWithin(ossimDpt)
+    * Returns TRUE if point is inside polygon.
+    */
+   bool pointWithin(const ossimDpt& point) const;
+
+   bool isPointWithin(const ossimDpt& point) const;
+
+   /**
+    * METHOD: vertex(index)
+    * Returns the ossimDpt vertex given the index. Returns false if no vertex
+    * defined.
+    */
+   bool vertex(int index, ossimDpt& tbd_vertex) const;
+
+   /**
+    * METHOD: nextVertex()
+    * Assigns the ossimDpt tbd_vertex following the current vertex. The current
+    * vertex is initialized with a call to vertex(int), or after the last
+    * vertex is reached. Returns false if no vertex defined. Intended to be
+    * when cycling through all vertices.
+    */
+   bool nextVertex(ossimDpt& tbd_vertex) const;
+
+   void reverseOrder();
+   /**
+    * OPERATORS: (Some are inlined at bottom) 
+    */
+   const ossimPolygon& operator= (const ossimPolygon& copy_this);
+   const ossimPolygon& operator= (const vector<ossimDpt>& vertexList);
+   const ossimPolygon& operator= (const vector<ossimIpt>& vertexList);
+   const ossimPolygon& operator= (const ossimIrect& rect);
+   const ossimPolygon& operator= (const ossimDrect& rect);
+   bool                operator==(const ossimPolygon& compare_this) const;
+   bool                operator!=(const ossimPolygon& compare_this) const;
+
+   const ossimPolygon& operator *=(const ossimDpt& scale);
+   const ossimPolygon& operator *=(double scale);
+   
+   ossimPolygon operator *(const ossimDpt& scale)const;
+   ossimPolygon operator *(double scale)const;
+   
+   void resize(ossim_uint32 newSize);
+
+   /**
+    * METHOD: print()
+    */
+   void print(ostream& os) const;
+   friend ostream& operator<<(ostream&, const ossimPolygon&);
+
+
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix=0)const;
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix=0);
+
+   void checkOrdering()const;
+
+   ossimVertexOrdering getOrdering()const;
+
+protected:
+   /**
+    * EMBEDDED CLASS: PolygonEdge
+    * A polygon consists of an ordered list of edges. The ordering corresponds
+    * to the ordering of the vertices. Each edge has a precomputed normal.
+    * The normals point towards the exterior.
+    */
+   vector<ossimDpt> theVertexList;
+
+   
+   mutable ossim_int32 theCurrentVertex;
+
+   /**
+    * This enumeration is found in ossimConstants.h
+    */
+   mutable ossimVertexOrdering theOrderingType;
+
+
+   void intersectEdge(ossimDpt& result,
+                      const ossimLine& segment,
+                      const ossimDrect& rect,
+                      int edge);
+   
+   bool isInsideEdge(const ossimDpt& pt,
+                     const ossimDrect& rect,
+                     int edge)const;
+};
+
+#endif /* End of "#ifndef ossimPolygon_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimRationalNumber.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimRationalNumber.cpp
new file mode 100644
index 0000000000..8e832d4fa2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimRationalNumber.cpp
@@ -0,0 +1,233 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimRationalNumber.cpp,v 1.4 2004/09/15 03:15:55 gpotts Exp $
+#include "base/data_types/ossimRationalNumber.h"
+
+// Normalisation
+void ossimRationalNumber::normalize()
+{
+    if (theDen == 0)
+    {
+       return;
+    }
+
+    // Handle the case of zero separately, to avoid division by zero
+    if (theNum == 0)
+    {
+       theDen = 1;
+       return;
+    }
+
+    ossim_int32 g = ossimGcd(theNum, theDen);
+    
+    theNum /= g;
+    theDen /= g;
+
+    // Ensure that the denominator is positive
+    if (theDen < 0)
+    {
+       theNum = -theNum;
+       theDen = -theDen;
+    }
+}
+
+const ossimRationalNumber& ossimRationalNumber::assign(double value, long precision)
+{
+  ossim_sint32 s = 1;
+  if(value <= 0.0)
+    {
+      s = -1;
+      value *= -1.0;
+    }
+  ossim_int32 integerPart = (ossim_int32)std::floor(value);
+  ossim_int32 decimalPart = (ossim_int32)((value - integerPart)*precision);
+  ossimRationalNumber temp(integerPart);
+  ossimRationalNumber temp2(decimalPart, precision);
+  temp2.normalize();
+  *this = (temp + temp2);
+  theNum *= s; 
+  normalize();
+  return *this;
+}
+
+const ossimRationalNumber& ossimRationalNumber::operator+= (const ossimRationalNumber& r)
+{
+    // This calculation avoids overflow, and minimises the number of expensive
+    // calculations. Thanks to Nickolay Mladenov for this algorithm.
+    //
+    // Proof:
+    // We have to compute a/b + c/d, where gcd(a,b)=1 and gcd(b,c)=1.
+    // Let g = gcd(b,d), and b = b1*g, d=d1*g. Then gcd(b1,d1)=1
+    //
+    // The result is (a*d1 + c*b1) / (b1*d1*g).
+    // Now we have to normalize this ratio.
+    // Let's assume h | gcd((a*d1 + c*b1), (b1*d1*g)), and h > 1
+    // If h | b1 then gcd(h,d1)=1 and hence h|(a*d1+c*b1) => h|a.
+    // But since gcd(a,b1)=1 we have h=1.
+    // Similarly h|d1 leads to h=1.
+    // So we have that h | gcd((a*d1 + c*b1) , (b1*d1*g)) => h|g
+    // Finally we have gcd((a*d1 + c*b1), (b1*d1*g)) = gcd((a*d1 + c*b1), g)
+    // Which proves that instead of normalizing the result, it is better to
+    // divide num and den by gcd((a*d1 + c*b1), g)
+
+    ossim_int32 g = ossimGcd(theDen, r.theDen);
+    theDen /= g;  // = b1 from the calculations above
+    theNum = theNum * (r.theDen / g) + r.theNum * theDen;
+    g = ossimGcd(theNum, g);
+    theNum /= g;
+    theDen *= r.theDen/g;
+
+    return *this;
+}
+
+const ossimRationalNumber& ossimRationalNumber::operator-= (const ossimRationalNumber& r)
+{
+    // This calculation avoids overflow, and minimises the number of expensive
+    // calculations. It corresponds exactly to the += case above
+    ossim_int32 g = ossimGcd(theDen, r.theDen);
+    theDen /= g;
+    theNum = theNum * (r.theDen / g) - r.theNum * theDen;
+    g = ossimGcd(theNum, g);
+    theNum /= g;
+    theDen *= r.theDen/g;
+
+    return *this;
+}
+
+const ossimRationalNumber& ossimRationalNumber::operator*= (const ossimRationalNumber& r)
+{
+    // Avoid overflow and preserve normalization
+    ossim_int32 gcd1 = ossimGcd(theNum, r.theDen);
+    ossim_int32 gcd2 = ossimGcd(r.theNum, theDen);
+    theNum = (theNum/gcd1) * (r.theNum/gcd2);
+    theDen = (theDen/gcd2) * (r.theDen/gcd1);
+    
+    return *this;
+}
+
+const ossimRationalNumber& ossimRationalNumber::operator/= (const ossimRationalNumber& r)
+{
+   ossim_int32 zero(0);
+   
+   if (r.theNum == zero)
+   {
+      theNum = OSSIM_INT_NAN;
+      theDen = OSSIM_INT_NAN;
+      
+      return *this;
+   }
+   *this = (*this)*(ossimRationalNumber(r.theDen, r.theNum));
+
+   return *this;
+}
+
+// Mixed-mode operators
+const ossimRationalNumber& ossimRationalNumber::operator+= (ossim_int32 i)
+{
+    return operator += (ossimRationalNumber(i));
+}
+
+const ossimRationalNumber& ossimRationalNumber::operator-= (ossim_int32 i)
+{
+    return operator -= (ossimRationalNumber(i));
+}
+
+const ossimRationalNumber& ossimRationalNumber::operator*= (ossim_int32 i)
+{
+    return operator *= (ossimRationalNumber(i));
+}
+
+const ossimRationalNumber& ossimRationalNumber::operator/= (ossim_int32 i)
+{
+    return operator /= (ossimRationalNumber(i));
+}
+
+ossimRationalNumber ossimRationalNumber::operator+ (const ossimRationalNumber& r)const
+{
+    // This calculation avoids overflow, and minimises the number of expensive
+    // calculations. Thanks to Nickolay Mladenov for this algorithm.
+    //
+    // Proof:
+    // We have to compute a/b + c/d, where gcd(a,b)=1 and gcd(b,c)=1.
+    // Let g = gcd(b,d), and b = b1*g, d=d1*g. Then gcd(b1,d1)=1
+    //
+    // The result is (a*d1 + c*b1) / (b1*d1*g).
+    // Now we have to normalize this ratio.
+    // Let's assume h | gcd((a*d1 + c*b1), (b1*d1*g)), and h > 1
+    // If h | b1 then gcd(h,d1)=1 and hence h|(a*d1+c*b1) => h|a.
+    // But since gcd(a,b1)=1 we have h=1.
+    // Similarly h|d1 leads to h=1.
+    // So we have that h | gcd((a*d1 + c*b1) , (b1*d1*g)) => h|g
+    // Finally we have gcd((a*d1 + c*b1), (b1*d1*g)) = gcd((a*d1 + c*b1), g)
+    // Which proves that instead of normalizing the result, it is better to
+    // divide num and den by gcd((a*d1 + c*b1), g)
+
+   ossim_int32 g = ossimGcd(theDen, r.theDen);
+   ossim_int32 den = theDen;
+   ossim_int32 num = theNum;
+   den /= g;  // = b1 from the calculations above
+   num = num * (r.theDen / g) + r.theNum * den;
+   g = ossimGcd(num, g);
+   num /= g;
+   den *= r.theDen/g;
+
+    return ossimRationalNumber(num, den);
+}
+
+ossimRationalNumber ossimRationalNumber::operator-(const ossimRationalNumber& r)const
+{
+   ossimRationalNumber result = *this;
+    // This calculation avoids overflow, and minimises the number of expensive
+    // calculations. It corresponds exactly to the += case above
+    ossim_int32 g = ossimGcd(result.theDen, r.theDen);
+    result.theDen /= g;
+    result.theNum = result.theNum * (r.theDen / g) - r.theNum * result.theDen;
+    g = ossimGcd(result.theNum, g);
+    result.theNum /= g;
+    result.theDen *= r.theDen/g;
+
+    return result;
+}
+
+ossimRationalNumber ossimRationalNumber::operator*(const ossimRationalNumber& r)const
+{
+   ossimRationalNumber result = *this;
+   // Avoid overflow and preserve normalization
+   ossim_int32 gcd1 = ossimGcd(result.theNum, r.theDen);
+   ossim_int32 gcd2 = ossimGcd(r.theNum, result.theDen);
+   result.theNum = (result.theNum/gcd1) * (r.theNum/gcd2);
+   result.theDen = (result.theDen/gcd2) * (r.theDen/gcd1);
+   
+   return result;
+}
+
+ossimRationalNumber ossimRationalNumber::operator/(const ossimRationalNumber& r)const
+{
+   ossim_int32 zero(0);
+   
+   if (r.theNum == zero)
+   {
+      return ossimRationalNumber(OSSIM_INT_NAN, OSSIM_INT_NAN);;
+   }
+   
+   return (*this)*(ossimRationalNumber(r.theDen, r.theNum));
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimRationalNumber.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimRationalNumber.h
new file mode 100644
index 0000000000..9d511fbca4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimRationalNumber.h
@@ -0,0 +1,210 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+//  $Id: ossimRationalNumber.h,v 1.14 2003/09/14 18:49:42 dburken Exp $
+#ifndef ossimRationalNumber_HEADER
+#define ossimRationalNumber_HEADER
+#include "base/common/ossimCommon.h"
+#include "base/common/ossimConstants.h"
+#include <iostream>
+
+class OSSIMDLLEXPORT ossimRationalNumber
+{
+public:
+
+   friend std::ostream& operator<<(std::ostream& out, const ossimRationalNumber& rhs)
+      {
+         out<<rhs.theNum << "/" << rhs.theDen;
+         
+         return out;
+      }
+   ossimRationalNumber()
+      :theNum(1),
+       theDen(1)
+      {
+      }
+   ossimRationalNumber(ossim_int32 num,
+                       ossim_int32 den)
+      :theNum(num),
+       theDen(den)
+      {
+      }
+   ossimRationalNumber(ossim_int32 num)
+      :theNum(num),
+       theDen(1)
+      {}
+   double toDouble()const
+      {
+         return (static_cast<double>(theNum)/
+                 static_cast<double>(theDen));
+      }
+   float toFloat()const
+      {
+         return (static_cast<float>(theNum)/
+                 static_cast<float>(theDen));
+      }
+
+   void normalize();
+   
+   const ossimRationalNumber& operator=(ossim_int32 n)
+      {
+         return assign(n, 1);
+      }
+
+   const ossimRationalNumber& operator=(double n)
+      {
+         return assign(n);
+      }
+
+   ossimRationalNumber operator-()const
+      {
+         return ossimRationalNumber(-theNum, theDen);
+      }
+   const ossimRationalNumber& operator+= (const ossimRationalNumber& r);
+   const ossimRationalNumber& operator-= (const ossimRationalNumber& r);
+   const ossimRationalNumber& operator*= (const ossimRationalNumber& r);
+   const ossimRationalNumber& operator/= (const ossimRationalNumber& r);
+   
+   inline const ossimRationalNumber& operator+= (ossim_int32 i);
+   inline const ossimRationalNumber& operator-= (ossim_int32 i);
+   inline const ossimRationalNumber& operator*= (ossim_int32 i);
+   inline const ossimRationalNumber& operator/= (ossim_int32 i);
+
+   ossimRationalNumber operator+ (const ossimRationalNumber& r)const;
+   ossimRationalNumber operator- (const ossimRationalNumber& r)const;
+   ossimRationalNumber operator* (const ossimRationalNumber& r)const;
+   ossimRationalNumber operator/ (const ossimRationalNumber& r)const;
+   
+   inline ossimRationalNumber operator+ (ossim_int32 i)const;
+   inline ossimRationalNumber operator- (ossim_int32 i)const;
+   inline ossimRationalNumber operator* (ossim_int32 i)const;
+   inline ossimRationalNumber operator/ (ossim_int32 i)const;
+
+   friend inline ossimRationalNumber operator+ (ossim_int32 i, ossimRationalNumber& r);
+   friend inline ossimRationalNumber operator- (ossim_int32 i, ossimRationalNumber& r);
+   friend inline ossimRationalNumber operator* (ossim_int32 i, ossimRationalNumber& r);
+   friend inline ossimRationalNumber operator/ (ossim_int32 i, ossimRationalNumber& r);
+   
+     // Comparison operators
+//   inline bool operator< (const ossimRationalNumber& r) const;
+   inline bool operator== (const ossimRationalNumber& r) const;
+   
+   inline bool operator== (ossim_int32 i) const;
+   
+   // Increment and decrement
+   inline const ossimRationalNumber& operator++();
+   inline const ossimRationalNumber& operator--();
+   
+   // Assign in place
+   inline const ossimRationalNumber& assign(ossim_int32 n, ossim_int32 d);
+  /*!
+   * default estimation is out to the 10000 place.  Will set this 
+   * rational to a value that is close to the passed in number.
+   */
+  const ossimRationalNumber& assign(double value, long precision=10000);
+
+   /*!
+    * Holds the value of the numberator.
+    */
+   ossim_int32 theNum;
+
+   /*!
+    * Holds the value of the denominator.
+    */
+   ossim_int32 theDen;
+
+};
+
+inline const ossimRationalNumber& ossimRationalNumber::assign(ossim_int32 n, ossim_int32 d)
+{
+   theNum = n;
+   theDen = d;
+   normalize();
+   
+   return *this;  
+}
+
+// Mixed-mode operators
+inline ossimRationalNumber ossimRationalNumber::operator+(ossim_int32 i)const
+{
+    return operator + (ossimRationalNumber(i));
+}
+
+inline ossimRationalNumber ossimRationalNumber::operator-(ossim_int32 i)const
+{
+    return operator - (ossimRationalNumber(i));
+}
+
+inline ossimRationalNumber ossimRationalNumber::operator*(ossim_int32 i)const
+{
+    return operator * (ossimRationalNumber(i));
+}
+
+inline ossimRationalNumber ossimRationalNumber::operator/(ossim_int32 i)const
+{
+    return operator / (ossimRationalNumber(i));
+}
+
+inline ossimRationalNumber operator+ (ossim_int32 i, ossimRationalNumber& r)
+{
+   return ossimRationalNumber(i)+r;
+}
+
+inline ossimRationalNumber operator- (ossim_int32 i, ossimRationalNumber& r)
+{
+   return ossimRationalNumber(i)-r;
+}
+
+inline ossimRationalNumber operator* (ossim_int32 i, ossimRationalNumber& r)
+{
+   return ossimRationalNumber(i)*r;
+}
+
+inline ossimRationalNumber operator/ (ossim_int32 i, ossimRationalNumber& r)
+{
+   return ossimRationalNumber(i)/r;
+}
+
+inline const ossimRationalNumber& ossimRationalNumber::operator++()
+{
+   theNum += theDen;
+   
+   return *this;
+}
+
+inline const ossimRationalNumber& ossimRationalNumber::operator--()
+{
+   theNum -= theDen;
+   
+   return *this;   
+}
+
+inline bool ossimRationalNumber::operator== (const ossimRationalNumber& r)const
+{
+    return ((theNum == r.theNum) && (theDen == r.theDen));
+}
+
+inline bool ossimRationalNumber::operator== (ossim_int32 i) const
+{
+    return ((theDen == ossim_int32(1)) && (theNum == i));
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimRegExp.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimRegExp.cpp
new file mode 100644
index 0000000000..4e5584ef2e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimRegExp.cpp
@@ -0,0 +1,1276 @@
+ 
+//
+// Copyright (C) 1991 Texas Instruments Incorporated.
+//
+// Permission is granted to any individual or institution to use, copy, modify,
+// and distribute this software, provided that this complete copyright and
+// permission notice is maintained, intact, in all copies and supporting
+// documentation.
+//
+// Texas Instruments Incorporated provides this software "as is" without
+// express or implied warranty.
+//
+//
+// Created: MNF 06/13/89  Initial Design and Implementation
+// Updated: LGO 08/09/89  Inherit from Generic
+// Updated: MBN 09/07/89  Added conditional exception handling
+// Updated: MBN 12/15/89  Sprinkled "const" qualifiers all over the place!
+// Updated: DLS 03/22/91  New lite version
+//
+// This  is the header file  for the regular  expression class.   An object of
+// this class contains a regular expression,  in  a special "compiled" format.
+// This  compiled format consists  of  several slots   all kept as the objects
+// private data.  The  RegExp class  provides a convenient  way  to  represent
+// regular  expressions.  It makes it easy   to search  for  the  same regular
+// expression in many different strings without having to  compile a string to
+// regular expression format more than necessary.
+//
+// A regular  expression allows a programmer to  specify complex patterns that
+// can be searched for  and  matched against the  character string of a String
+// object.  In  its  simplest case, a   regular expression  is a  sequence  of
+// characters with which you can search for exact character matches.  However,
+// many times you may not know the exact sequence you want to find, or you may
+// only want to find a match at the beginning or end of  a String.  The RegExp
+// object  allows specification of  such patterns by  utilizing the  following
+// regular  expression  meta-characters   (note   that  more  one  of    these
+// meta-characters  can  be used in a single  regular  expression in  order to
+// create complex search patterns):
+//
+//         ^    Match at beginning of line
+//         $    Match at end of line
+//         .    Match any single character
+//         [ ]  Match any one character inside the brackets
+//         [^ ] Match any character NOT inside the brackets
+//         -    Match any character in range on either side of dash
+//         *    Match preceding pattern zero or more times
+//         +    Match preceding pattern one or more times
+//         ?    Match preceding pattern zero or once only
+//         ()   Save a matched expression and use it in a further match.
+//
+// There are three constructors for RegExp.  One  just creates an empty RegExp
+// object.  Another creates a RegExp object  and initializes it with a regular
+// expression  that is given  in  the form of a   char*.   The  third  takes a
+// reference  to  a RegExp  object    as an  argument    and creates an object
+// initialized with the information from the given RegExp object.
+//
+// The  find  member function  finds   the  first  occurence   of  the regualr
+// expression of that object in the string given to find as an argument.  Find
+// returns a boolean, and  if true,  mutates  the private  data appropriately.
+// Find sets pointers to the beginning and end of  the thing last  found, they
+// are pointers into the actual string  that was searched.   The start and end
+// member functions return indicies  into the searched string that  correspond
+// to the beginning   and  end pointers  respectively.   The    compile member
+// function takes a char* and puts the  compiled version of the char* argument
+// into the object's private data fields.  The == and  != operators only check
+// the  to see  if   the compiled  regular  expression   is the same, and  the
+// deep_equal functions also checks  to see if the  start and end pointers are
+// the same.  The is_valid  function returns false if  program is set to NULL,
+// (i.e. there is no valid compiled exression).  The set_invalid function sets
+// the  program to NULL  (Warning: this deletes the compiled  expression). The
+// following examples may help clarify regular expression usage:
+//
+//   *  The regular expression  "^hello" matches  a "hello"  only at  the
+//      beginning of a  line.  It would match "hello  there" but not "hi,
+//      hello there".
+//
+//   *  The regular expression "long$" matches a  "long"  only at the end
+//      of a line. It would match "so long\0", but not "long ago".
+//
+//   *  The regular expression "t..t..g"  will match anything that  has a
+//      "t" then any two characters, another "t", any  two characters and
+//      then a "g".   It will match  "testing", or "test again" but would
+//      not match "toasting"
+//
+//   *  The regular  expression "[1-9ab]" matches any  number one through
+//      nine, and the characters  "a" and  "b".  It would match "hello 1"
+//      or "begin", but would not match "no-match".
+//
+//   *  The  regular expression "[^1-9ab]"  matches any character that is
+//      not a number one  through nine, or  an "a" or "b".   It would NOT
+//      match "hello 1" or "begin", but would match "no-match".
+//
+//   *  The regular expression "br* " matches  something that begins with
+//      a "b", is followed by zero or more "r"s, and ends in a space.  It
+//      would match "brrrrr ", and "b ", but would not match "brrh ".
+//
+//   *  The regular expression "br+ " matches something  that begins with
+//      a "b", is followed by one or more "r"s, and ends in  a space.  It
+//      would match "brrrrr ",  and  "br ", but would not  match "b  " or
+//      "brrh ".
+//
+//   *  The regular expression "br? " matches  something that begins with
+//      a "b", is followed by zero or one "r"s, and ends in  a space.  It
+//      would  match  "br ", and "b  ", but would not match  "brrrr "  or
+//      "brrh ".
+//
+//   *  The regular expression "(..p)b" matches  something ending with pb
+//      and beginning with whatever the two characters before the first p
+//      encounterd in the line were.  It would find  "repb" in "rep drepa
+//      qrepb".  The regular expression "(..p)a"  would find "repa qrepb"
+//      in "rep drepa qrepb"
+//
+//   *  The regular expression "d(..p)" matches something ending  with p,
+//      beginning with d, and having  two characters  in between that are
+//      the same as the two characters before  the first p  encounterd in
+//      the line.  It would match "drepa qrepb" in "rep drepa qrepb".
+//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ossimRegExp.h"			// Include class specification 
+
+// ossimRegExp -- Copies the given regular expression.
+
+ossimRegExp::ossimRegExp (const ossimRegExp& rxp) {
+  int ind; 
+  this->progsize = rxp.progsize;		// Copy regular expression size
+  this->program = new char[this->progsize];	// Allocate storage
+  for(ind=this->progsize; ind-- != 0;)		// Copy regular expresion
+    this->program[ind] = rxp.program[ind];
+  this->startp[0] = rxp.startp[0];		// Copy pointers into last
+  this->endp[0] = rxp.endp[0];			// Successful "find" operation
+  this->regmust = rxp.regmust;			// Copy field
+  if (rxp.regmust != NULL) {
+    char* dum = rxp.program;
+    ind = 0;
+    while (dum != rxp.regmust) {
+      ++dum;
+      ++ind;
+    }
+    this->regmust = this->program + ind;
+  }
+  this->regstart = rxp.regstart;		// Copy starting index
+  this->reganch = rxp.reganch;			// Copy remaining private data
+  this->regmlen = rxp.regmlen;			// Copy remaining private data
+}
+
+
+// operator== -- Returns true if two regular expressions have the same
+// compiled program for pattern matching.
+
+bool ossimRegExp::operator== (const ossimRegExp& rxp) const {
+  if (this != &rxp) {				// Same address?
+    ossim_uint32 ind = this->progsize;		// Get regular expression size
+    if (ind != rxp.progsize)			// If different size regexp
+      return false;				// Return failure
+    while(ind-- != 0)				// Else while still characters
+      if(this->program[ind] != rxp.program[ind]) // If regexp are different    
+	return false;				 // Return failure             
+  }
+  return true;					// Else same, return success  
+}
+
+
+// deep_equal -- Returns true if have the same compiled regular expressions
+// and the same start and end pointers.
+
+bool ossimRegExp::deep_equal (const ossimRegExp& rxp) const {
+  ossim_uint32 ind = this->progsize;		// Get regular expression size
+  if (ind != rxp.progsize)			// If different size regexp
+    return false;				// Return failure
+  while(ind-- != 0)		 		// Else while still characters
+    if(this->program[ind] != rxp.program[ind])	// If regexp are different    
+      return false;				// Return failure             
+  return (this->startp[0] == rxp.startp[0] && 	// Else if same start/end ptrs,
+	  this->endp[0] == rxp.endp[0]);	// Return true
+}   
+
+// The remaining code in this file is derived from the  regular expression code
+// whose  copyright statement appears  below.  It has been  changed to work
+// with the class concepts of C++ and COOL.
+
+/*
+ * compile and find 
+ *
+ *	Copyright (c) 1986 by University of Toronto.
+ *	Written by Henry Spencer.  Not derived from licensed software.
+ *
+ *	Permission is granted to anyone to use this software for any
+ *	purpose on any computer system, and to redistribute it freely,
+ *	subject to the following restrictions:
+ *
+ *	1. The author is not responsible for the consequences of use of
+ *		this software, no matter how awful, even if they arise
+ *		from defects in it.
+ *
+ *	2. The origin of this software must not be misrepresented, either
+ *		by explicit claim or by omission.
+ *
+ *	3. Altered versions must be plainly marked as such, and must not
+ *		be misrepresented as being the original software.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions.  Serious changes in
+ * regular-expression syntax might require a total rethink.
+ */
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases.  They are:
+ *
+ * regstart	char that must begin a match; '\0' if none obvious
+ * reganch	is the match anchored (at beginning-of-line only)?
+ * regmust	string (pointer into program) that match must include, or NULL
+ * regmlen	length of regmust string
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot.  Regmust permits fast rejection
+ * of lines that cannot possibly match.  The regmust tests are costly enough
+ * that compile() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup).  Regmlen is
+ * supplied because the test in find() needs it and compile() is computing
+ * it anyway.
+ */
+
+/*
+ * Structure for regexp "program".  This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology).  Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
+ * all nodes except BRANCH implement concatenation; a "next" pointer with
+ * a BRANCH on both ends of it is connecting two alternatives.  (Here we
+ * have one of the subtle syntax dependencies:  an individual BRANCH (as
+ * opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence.)  The operand of some types of node is
+ * a literal string; for others, it is a node leading into a sub-FSM.  In
+ * particular, the operand of a BRANCH node is the first node of the branch.
+ * (NB this is *not* a tree structure:  the tail of the branch connects
+ * to the thing following the set of BRANCHes.)  The opcodes are:
+ */
+
+// definition	number	opnd?	meaning
+#define	END	0		// no	End of program.
+#define	BOL	1		// no	Match "" at beginning of line.
+#define	EOL	2		// no	Match "" at end of line.
+#define	ANY	3		// no	Match any one character.
+#define	ANYOF	4		// str	Match any character in this string.
+#define	ANYBUT	5		// str	Match any character not in this
+				// string.
+#define	BRANCH	6		// node	Match this alternative, or the
+				// next...
+#define	BACK	7		// no	Match "", "next" ptr points backward.
+#define	EXACTLY	8		// str	Match this string.
+#define	NOTHING	9		// no	Match empty string.
+#define	STAR	10		// node	Match this (simple) thing 0 or more
+				// times.
+#define	PLUS	11		// node	Match this (simple) thing 1 or more
+				// times.
+#define	OPEN	20		// no	Mark this point in input as start of
+				// #n.
+// OPEN+1 is number 1, etc.
+#define	CLOSE	30		// no	Analogous to OPEN.
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH	The set of branches constituting a single choice are hooked
+ *		together with their "next" pointers, since precedence prevents
+ *		anything being concatenated to any individual branch.  The
+ *		"next" pointer of the last BRANCH in a choice points to the
+ *		thing following the whole choice.  This is also where the
+ *		final "next" pointer of each individual branch points; each
+ *		branch starts with the operand node of a BRANCH node.
+ *
+ * BACK		Normal "next" pointers all implicitly point forward; BACK
+ *		exists to make loop structures possible.
+ *
+ * STAR,PLUS	'?', and complex '*' and '+', are implemented as circular
+ *		BRANCH structures using BACK.  Simple cases (one character
+ *		per match) are implemented with STAR and PLUS for speed
+ *		and to minimize recursive plunges.
+ *
+ * OPEN,CLOSE	...are numbered at compile time.
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit pieces, high order first.  The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node.  (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+
+#define	OP(p)		(*(p))
+#define	NEXT(p)		(((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
+#define	OPERAND(p)	((p) + 3)
+
+const unsigned char MAGIC = 0234;
+/*
+ * Utility definitions.
+ */
+
+#define	UCHARAT(p)	((const unsigned char*)(p))[0]
+
+
+#define	FAIL(m)	{ regerror(m); return(NULL); }
+#define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')
+#define	META	"^$.[()|?+*\\"
+
+
+/*
+ * Flags to be passed up and down.
+ */
+#define	HASWIDTH	01	// Known never to match null string.
+#define	SIMPLE		02	// Simple enough to be STAR/PLUS operand.
+#define	SPSTART		04	// Starts with * or +.
+#define	WORST		0	// Worst case.
+
+
+
+/////////////////////////////////////////////////////////////////////////
+//
+//  COMPILE AND ASSOCIATED FUNCTIONS
+//
+/////////////////////////////////////////////////////////////////////////
+
+
+/*
+ * Global work variables for compile().
+ */
+// static const char* regparse;	// Input-scan pointer.
+// static       int   regnpar;	// () count.
+// static       char  regdummy;
+// static       char* regcode;	// Code-emit pointer; &regdummy = don't.
+// static       long  regsize;	// Code size.
+
+/*
+ * Forward declarations for compile()'s friends.
+ */
+// #ifndef static
+// #define	static	static
+// #endif
+// static       char* reg (int, int*);
+// static       char* regbranch (int*);
+// static       char* regpiece (int*);
+// static       char* regatom (int*);
+// static       char* regnode (char);
+// static const char* regnext (register const char*);
+// static       char* regnext (register char*);
+// static void        regc (unsigned char);
+// static void        reginsert (char, char*);
+// static void        regtail (char*, const char*);
+// static void        regoptail (char*, const char*);
+
+// #ifdef STRCSPN
+// static int strcspn ();
+// #endif
+
+
+
+/*
+ * We can't allocate space until we know how big the compiled form will be,
+ * but we can't compile it (and thus know how big it is) until we've got a
+ * place to put the code.  So we cheat:  we compile it twice, once with code
+ * generation turned off and size counting turned on, and once "for real".
+ * This also means that we don't allocate space until we are sure that the
+ * thing really will compile successfully, and we never have to move the
+ * code and thus invalidate pointers into it.  (Note that it has to be in
+ * one piece because free() must be able to free it all.)
+ *
+ * Beware that the optimization-preparation code in here knows about some
+ * of the structure of the compiled regexp.
+ */
+
+
+// compile -- compile a regular expression into internal code
+// for later pattern matching.
+
+void ossimRegExp::compile (const char* exp) {
+    register const char* scan;
+    register const char* longest;
+    register unsigned long len;
+             int         flags;
+
+    if (exp == NULL) {
+      //RAISE Error, SYM(ossimRegExp), SYM(No_Expr),
+      printf ("ossimRegExp::compile(): No expression supplied.\n");
+      return;
+    }
+
+    // First pass: determine size, legality.
+    regparse = exp;
+    regnpar = 1;
+    regsize = 0L;
+    regcode = &regdummy;
+    regc(MAGIC);
+    if(!reg(0, &flags))
+      {
+	printf ("ossimRegExp::compile(): Error in compile.\n");
+	return;
+      }
+    this->startp[0] = this->endp[0] = this->searchstring = NULL;
+
+    // Small enough for pointer-storage convention? 
+    if (regsize >= 32767L) {	// Probably could be 65535L. 
+      //RAISE Error, SYM(ossimRegExp), SYM(Expr_Too_Big),
+      printf ("ossimRegExp::compile(): Expression too big.\n");
+      return;
+    }
+
+    // Allocate space. 
+//#ifndef WIN32
+    if (this->program != NULL) delete [] this->program;  
+//#endif
+    this->program = new char[regsize];
+    this->progsize = (int) regsize;
+
+    if (this->program == NULL) {
+      //RAISE Error, SYM(ossimRegExp), SYM(Out_Of_Memory),
+      printf ("ossimRegExp::compile(): Out of memory.\n"); 
+      return;
+    }
+
+    // Second pass: emit code.
+    regparse = exp;
+    regnpar = 1;
+    regcode = this->program;
+    regc(MAGIC);
+    reg(0, &flags);
+
+    // Dig out information for optimizations.
+    this->regstart = '\0';		// Worst-case defaults.
+    this->reganch = 0;
+    this->regmust = NULL;
+    this->regmlen = 0;
+    scan = this->program + 1;	// First BRANCH.
+    if (OP(regnext(scan)) == END) {	// Only one top-level choice.
+	scan = OPERAND(scan);
+
+	// Starting-point info.
+	if (OP(scan) == EXACTLY)
+	    this->regstart = *OPERAND(scan);
+	else if (OP(scan) == BOL)
+	    this->reganch++;
+
+	 //
+	 // If there's something expensive in the r.e., find the longest
+	 // literal string that must appear and make it the regmust.  Resolve
+	 // ties in favor of later strings, since the regstart check works
+	 // with the beginning of the r.e. and avoiding duplication
+	 // strengthens checking.  Not a strong reason, but sufficient in the
+	 // absence of others. 
+	 //
+	if (flags & SPSTART) {
+	    longest = NULL;
+	    len = 0;
+	    for (; scan != NULL; scan = regnext(scan))
+		if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
+		    longest = OPERAND(scan);
+		    len = strlen(OPERAND(scan));
+		}
+	    this->regmust = longest;
+	    this->regmlen = len;
+	}
+    }
+}
+
+
+/*
+ - reg - regular expression, i.e. main body or parenthesized thing
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+char* ossimRegExp::reg (int paren, int *flagp) {
+    register char* ret;
+    register char* br;
+    register char* ender;
+    register int   parno =0;
+             int   flags;
+
+    *flagp = HASWIDTH;		// Tentatively.
+
+    // Make an OPEN node, if parenthesized.
+    if (paren) {
+	if (regnpar >= NSUBEXP) {
+	  //RAISE Error, SYM(ossimRegExp), SYM(Too_Many_Parens),
+	  printf ("ossimRegExp::compile(): Too many parentheses.\n");
+	  return 0;
+        }
+	parno = regnpar;
+	regnpar++;
+	ret = regnode(OPEN + parno);
+    }
+    else
+	ret = NULL;
+
+    // Pick up the branches, linking them together.
+    br = regbranch(&flags);
+    if (br == NULL)
+	return (NULL);
+    if (ret != NULL)
+	regtail(ret, br);	// OPEN -> first.
+    else
+	ret = br;
+    if (!(flags & HASWIDTH))
+	*flagp &= ~HASWIDTH;
+    *flagp |= flags & SPSTART;
+    while (*regparse == '|') {
+	regparse++;
+	br = regbranch(&flags);
+	if (br == NULL)
+	    return (NULL);
+	regtail(ret, br);	// BRANCH -> BRANCH.
+	if (!(flags & HASWIDTH))
+	    *flagp &= ~HASWIDTH;
+	*flagp |= flags & SPSTART;
+      }
+
+    // Make a closing node, and hook it on the end.
+    ender = regnode((paren) ? CLOSE + parno : END);
+    regtail(ret, ender);
+
+    // Hook the tails of the branches to the closing node.
+    for (br = ret; br != NULL; br = regnext(br))
+	regoptail(br, ender);
+
+    // Check for proper termination.
+    if (paren && *regparse++ != ')') {
+        //RAISE Error, SYM(ossimRegExp), SYM(Unmatched_Parens),
+        printf ("ossimRegExp::compile(): Unmatched parentheses.\n");
+	return 0;
+    }
+    else if (!paren && *regparse != '\0') {
+        if (*regparse == ')') {
+            //RAISE Error, SYM(ossimRegExp), SYM(Unmatched_Parens),
+            printf ("ossimRegExp::compile(): Unmatched parentheses.\n");
+	    return 0;
+	}
+	else {
+	    //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error),
+	    printf ("ossimRegExp::compile(): Internal error.\n");
+	    return 0;
+        }
+	// NOTREACHED
+    }
+    return (ret);
+}
+
+
+/*
+ - regbranch - one alternative of an | operator
+ *
+ * Implements the concatenation operator.
+ */
+char* ossimRegExp::regbranch (int *flagp) {
+    register char* ret;
+    register char* chain;
+    register char* latest;
+    int                  flags;
+
+    *flagp = WORST;		// Tentatively.
+
+    ret = regnode(BRANCH);
+    chain = NULL;
+    while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
+	latest = regpiece(&flags);
+	if (latest == NULL)
+	    return (NULL);
+	*flagp |= flags & HASWIDTH;
+	if (chain == NULL)	// First piece.
+	    *flagp |= flags & SPSTART;
+	else
+	    regtail(chain, latest);
+	chain = latest;
+    }
+    if (chain == NULL)		// Loop ran zero times.
+	regnode(NOTHING);
+
+    return (ret);
+}
+
+
+/*
+ - regpiece - something followed by possible [*+?]
+ *
+ * Note that the branching code sequences used for ? and the general cases
+ * of * and + are somewhat optimized:  they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+char* ossimRegExp::regpiece (int *flagp) {
+    register char* ret;
+    register char  op;
+    register char* next;
+    int            flags;
+
+    ret = regatom(&flags);
+    if (ret == NULL)
+	return (NULL);
+
+    op = *regparse;
+    if (!ISMULT(op)) {
+	*flagp = flags;
+	return (ret);
+    }
+
+    if (!(flags & HASWIDTH) && op != '?') {
+        //RAISE Error, SYM(ossimRegExp), SYM(Empty_Operand),
+        printf ("ossimRegExp::compile() : *+ operand could be empty.\n");
+	return 0;
+    }
+    *flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH);
+
+    if (op == '*' && (flags & SIMPLE))
+	reginsert(STAR, ret);
+    else if (op == '*') {
+	// Emit x* as (x&|), where & means "self".
+	reginsert(BRANCH, ret);	// Either x
+	regoptail(ret, regnode(BACK));	// and loop
+	regoptail(ret, ret);	// back
+	regtail(ret, regnode(BRANCH));	// or
+	regtail(ret, regnode(NOTHING));	// null.
+    }
+    else if (op == '+' && (flags & SIMPLE))
+	reginsert(PLUS, ret);
+    else if (op == '+') {
+	// Emit x+ as x(&|), where & means "self".
+	next = regnode(BRANCH);	// Either
+	regtail(ret, next);
+	regtail(regnode(BACK), ret);	// loop back
+	regtail(next, regnode(BRANCH));	// or
+	regtail(ret, regnode(NOTHING));	// null.
+    }
+    else if (op == '?') {
+	// Emit x? as (x|)
+	reginsert(BRANCH, ret);	// Either x
+	regtail(ret, regnode(BRANCH));	// or
+	next = regnode(NOTHING);// null.
+	regtail(ret, next);
+	regoptail(ret, next);
+    }
+    regparse++;
+    if (ISMULT(*regparse)) {
+        //RAISE Error, SYM(ossimRegExp), SYM(Nested_Operand),
+        printf ("ossimRegExp::compile(): Nested *?+.\n");
+	return 0;
+    }
+    return (ret);
+}
+
+
+/*
+ - regatom - the lowest level
+ *
+ * Optimization:  gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run.  Backslashed characters are exceptions, each becoming a
+ * separate node; the code is simpler that way and it's not worth fixing.
+ */
+char* ossimRegExp::regatom (int *flagp) {
+    register char* ret;
+             int   flags;
+
+    *flagp = WORST;		// Tentatively.
+
+    switch (*regparse++) {
+	case '^':
+	    ret = regnode(BOL);
+	    break;
+	case '$':
+	    ret = regnode(EOL);
+	    break;
+	case '.':
+	    ret = regnode(ANY);
+	    *flagp |= HASWIDTH | SIMPLE;
+	    break;
+	case '[':{
+		register int    rxpclass;
+		register int    rxpclassend;
+
+		if (*regparse == '^') {	// Complement of range.
+		    ret = regnode(ANYBUT);
+		    regparse++;
+		}
+		else
+		    ret = regnode(ANYOF);
+		if (*regparse == ']' || *regparse == '-')
+		    regc(*regparse++);
+		while (*regparse != '\0' && *regparse != ']') {
+		    if (*regparse == '-') {
+			regparse++;
+			if (*regparse == ']' || *regparse == '\0')
+			    regc('-');
+			else {
+			    rxpclass = UCHARAT(regparse - 2) + 1;
+			    rxpclassend = UCHARAT(regparse);
+			    if (rxpclass > rxpclassend + 1) {
+			       //RAISE Error, SYM(ossimRegExp), SYM(Invalid_Range),
+			       printf ("ossimRegExp::compile(): Invalid range in [].\n");
+			       return 0;
+                            }
+			    for (; rxpclass <= rxpclassend; rxpclass++)
+				regc(rxpclass);
+			    regparse++;
+			}
+		    }
+		    else
+			regc(*regparse++);
+		}
+		regc('\0');
+		if (*regparse != ']') {
+                    //RAISE Error, SYM(ossimRegExp), SYM(Unmatched_Bracket),
+                    printf ("ossimRegExp::compile(): Unmatched [].\n");
+		    return 0;
+	        }
+		regparse++;
+		*flagp |= HASWIDTH | SIMPLE;
+	    }
+	    break;
+	case '(':
+	    ret = reg(1, &flags);
+	    if (ret == NULL)
+		return (NULL);
+	    *flagp |= flags & (HASWIDTH | SPSTART);
+	    break;
+	case '\0':
+	case '|':
+	case ')':
+	    //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error),
+            printf ("ossimRegExp::compile(): Internal error.\n"); // Never here
+	    return 0;
+	case '?':
+	case '+':
+	case '*':
+	    //RAISE Error, SYM(ossimRegExp), SYM(No_Operand),
+            printf ("ossimRegExp::compile(): ?+* follows nothing.\n");
+	    return 0;
+	case '\\':
+	    if (*regparse == '\0') {
+	        //RAISE Error, SYM(ossimRegExp), SYM(Trailing_Backslash),
+                printf ("ossimRegExp::compile(): Trailing backslash.\n");
+		return 0;
+            }
+	    ret = regnode(EXACTLY);
+	    regc(*regparse++);
+	    regc('\0');
+	    *flagp |= HASWIDTH | SIMPLE;
+	    break;
+	default:{
+		register int    len;
+		register char   ender;
+
+		regparse--;
+		len = strcspn(regparse, META);
+		if (len <= 0) {
+		    //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error),
+                    printf ("ossimRegExp::compile(): Internal error.\n");
+		    return 0;
+                }
+		ender = *(regparse + len);
+		if (len > 1 && ISMULT(ender))
+		    len--;	// Back off clear of ?+* operand.
+		*flagp |= HASWIDTH;
+		if (len == 1)
+		    *flagp |= SIMPLE;
+		ret = regnode(EXACTLY);
+		while (len > 0) {
+		    regc(*regparse++);
+		    len--;
+		}
+		regc('\0');
+	    }
+	    break;
+    }
+    return (ret);
+}
+
+
+/*
+ - regnode - emit a node
+   Location.
+ */
+char* ossimRegExp::regnode (char op) {
+    register char* ret;
+    register char* ptr;
+
+    ret = regcode;
+    if (ret == &regdummy) {
+	regsize += 3;
+	return (ret);
+    }
+
+    ptr = ret;
+    *ptr++ = op;
+    *ptr++ = '\0';		// Null "next" pointer.
+    *ptr++ = '\0';
+    regcode = ptr;
+
+    return (ret);
+}
+
+
+/*
+ - regc - emit (if appropriate) a byte of code
+ */
+void ossimRegExp::regc (unsigned char b) {
+    if (regcode != &regdummy)
+	*regcode++ = b;
+    else
+	regsize++;
+}
+
+
+/*
+ - reginsert - insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+void ossimRegExp::reginsert (char op, char* opnd) {
+    register char* src;
+    register char* dst;
+    register char* place;
+
+    if (regcode == &regdummy) {
+	regsize += 3;
+	return;
+    }
+
+    src = regcode;
+    regcode += 3;
+    dst = regcode;
+    while (src > opnd)
+	*--dst = *--src;
+
+    place = opnd;		// Op node, where operand used to be.
+    *place++ = op;
+    *place++ = '\0';
+    *place++ = '\0';
+}
+
+
+/*
+ - regtail - set the next-pointer at the end of a node chain
+ */
+void ossimRegExp::regtail (char* p, const char* val) {
+    register char* scan;
+    register char* temp;
+    register int   offset;
+
+    if (p == &regdummy)
+	return;
+
+    // Find last node.
+    scan = p;
+    for (;;) {
+	temp = regnext(scan);
+	if (temp == NULL)
+	    break;
+	scan = temp;
+    }
+
+    if (OP(scan) == BACK)
+	offset = (const char*)scan - val;
+    else
+	offset = val - scan;
+    *(scan + 1) = (offset >> 8) & 0377;
+    *(scan + 2) = offset & 0377;
+}
+
+
+/*
+ - regoptail - regtail on operand of first argument; nop if operandless
+ */
+void ossimRegExp::regoptail (char* p, const char* val) {
+    // "Operandless" and "op != BRANCH" are synonymous in practice.
+    if (p == NULL || p == &regdummy || OP(p) != BRANCH)
+	return;
+    regtail(OPERAND(p), val);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// 
+//  find and friends
+// 
+////////////////////////////////////////////////////////////////////////
+
+
+/*
+ * Global work variables for find().
+ */
+// static const char*  reginput;	// String-input pointer.
+// static const char*  regbol;	// Beginning of input, for ^ check.
+// static const char* *regstartp;	// Pointer to startp array.
+// static const char* *regendp;	// Ditto for endp.
+
+/*
+ * Forwards.
+ */
+// static int regtry (const char*, const char* *,
+// 		   const char* *, const char*);
+// static int regmatch (const char*);
+// static int regrepeat (const char*);
+
+// #ifdef DEBUG
+// int          regnarrate = 0;
+// void         regdump ();
+// static char* regprop ();
+// #endif
+
+
+
+// find -- Matches the regular expression to the given string.
+// Returns true if found, and sets start and end indexes accordingly.
+
+bool ossimRegExp::find (const char* string) {
+    register const char* s;
+
+    this->searchstring = string;
+
+     // Check validity of program.
+    if (!this->program || UCHARAT(this->program) != MAGIC) {
+        //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error),
+        printf ("ossimRegExp::find(): Compiled regular expression corrupted.\n");
+        return 0;
+    }
+    
+    // If there is a "must appear" string, look for it.
+    if (this->regmust != NULL) {
+	s = string;
+	while ((s = strchr(s, this->regmust[0])) != NULL) {
+	    if (strncmp(s, this->regmust, this->regmlen) == 0)
+		break;		// Found it.
+	    s++;
+	}
+	if (s == NULL)		// Not present.
+	    return (0);
+    }
+     
+    // Mark beginning of line for ^ .
+    regbol = string;
+
+    // Simplest case:  anchored match need be tried only once.
+    if (this->reganch)
+	return (regtry(string, this->startp, this->endp, this->program));
+    
+    // Messy cases:  unanchored match.
+    s = string;
+    if (this->regstart != '\0')
+	// We know what char it must start with.
+	while ((s = strchr(s, this->regstart)) != NULL) {
+	    if (regtry(s, this->startp, this->endp, this->program))
+		return (1);
+	    s++;
+	  
+	}
+    else
+	// We don't -- general case.
+	do {
+	    if (regtry(s, this->startp, this->endp, this->program))
+		return (1);
+	} while (*s++ != '\0');
+    
+    // Failure.
+    return (0);
+}
+
+
+/*
+ - regtry - try match at specific point
+   0 failure, 1 success
+ */
+int ossimRegExp::regtry (const char* string, const char* *start,
+		   const char* *end, const char* prog) {
+    register       int    i;
+    register const char* *sp1;
+    register const char* *ep;
+
+    reginput = string;
+    regstartp = start;
+    regendp = end;
+
+    sp1 = start;
+    ep = end;
+    for (i = NSUBEXP; i > 0; i--) {
+	*sp1++ = NULL;
+	*ep++ = NULL;
+    }
+    if (regmatch(prog + 1)) {
+	start[0] = string;
+	end[0] = reginput;
+	return (1);
+    }
+    else
+	return (0);
+}
+
+
+/*
+ - regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple:  check to see whether the current
+ * node matches, call self recursively to see whether the rest matches,
+ * and then act accordingly.  In practice we make some effort to avoid
+ * recursion, in particular by going through "ordinary" nodes (that don't
+ * need to know whether the rest of the match failed) by a loop instead of
+ * by recursion.
+ * 0 failure, 1 success
+ */
+int ossimRegExp::regmatch (const char* prog) {
+    register const char* scan;	// Current node.
+             const char* next;	// Next node.
+
+    scan = prog;
+
+    while (scan != NULL) {
+
+	next = regnext(scan);
+
+	switch (OP(scan)) {
+	    case BOL:
+		if (reginput != regbol)
+		    return (0);
+		break;
+	    case EOL:
+		if (*reginput != '\0')
+		    return (0);
+		break;
+	    case ANY:
+		if (*reginput == '\0')
+		    return (0);
+		reginput++;
+		break;
+	    case EXACTLY:{
+		    register int         len;
+		    register const char* opnd;
+
+		    opnd = OPERAND(scan);
+		    // Inline the first character, for speed.
+		    if (*opnd != *reginput)
+			return (0);
+		    len = strlen(opnd);
+		    if (len > 1 && strncmp(opnd, reginput, len) != 0)
+			return (0);
+		    reginput += len;
+		}
+		break;
+	    case ANYOF:
+		if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
+		    return (0);
+		reginput++;
+		break;
+	    case ANYBUT:
+		if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
+		    return (0);
+		reginput++;
+		break;
+	    case NOTHING:
+		break;
+	    case BACK:
+		break;
+	    case OPEN + 1:
+	    case OPEN + 2:
+	    case OPEN + 3:
+	    case OPEN + 4:
+	    case OPEN + 5:
+	    case OPEN + 6:
+	    case OPEN + 7:
+	    case OPEN + 8:
+	    case OPEN + 9:{
+		    register       int    no;
+		    register const char* save;
+
+		    no = OP(scan) - OPEN;
+		    save = reginput;
+
+		    if (regmatch(next)) {
+
+			//
+			// Don't set startp if some later invocation of the
+			// same parentheses already has. 
+			//
+			if (regstartp[no] == NULL)
+			    regstartp[no] = save;
+			return (1);
+		    }
+		    else
+			return (0);
+		}
+//		break;
+	    case CLOSE + 1:
+	    case CLOSE + 2:
+	    case CLOSE + 3:
+	    case CLOSE + 4:
+	    case CLOSE + 5:
+	    case CLOSE + 6:
+	    case CLOSE + 7:
+	    case CLOSE + 8:
+	    case CLOSE + 9:{
+		    register       int    no;
+		    register const char* save;
+
+		    no = OP(scan) - CLOSE;
+		    save = reginput;
+
+		    if (regmatch(next)) {
+
+			//
+			// Don't set endp if some later invocation of the
+			// same parentheses already has. 
+			//
+			if (regendp[no] == NULL)
+			    regendp[no] = save;
+			return (1);
+		    }
+		    else
+			return (0);
+		}
+//		break;
+	    case BRANCH:{
+	      
+	      register const char* save;
+
+		    if (OP(next) != BRANCH)	// No choice.
+			next = OPERAND(scan);	// Avoid recursion.
+		    else {
+			do {
+			    save = reginput;
+			    if (regmatch(OPERAND(scan)))
+				return (1);
+			    reginput = save;
+			    scan = regnext(scan);
+			} while (scan != NULL && OP(scan) == BRANCH);
+			return (0);
+			// NOTREACHED
+		    }
+		}
+		break;
+	    case STAR:
+	    case PLUS:{
+	      register char   nextch;
+		    register int        no;
+		    register const char* save;
+		    register int        min_no;
+
+		    //
+		    // Lookahead to avoid useless match attempts when we know
+		    // what character comes next. 
+		    //
+		    nextch = '\0';
+		    if (OP(next) == EXACTLY)
+			nextch = *OPERAND(next);
+		    min_no = (OP(scan) == STAR) ? 0 : 1;
+		    save = reginput;
+		    no = regrepeat(OPERAND(scan));
+		    while (no >= min_no) {
+			// If it could work, try it.
+			if (nextch == '\0' || *reginput == nextch)
+			    if (regmatch(next))
+				return (1);
+			// Couldn't or didn't -- back up.
+			no--;
+			reginput = save + no;
+		    }
+		    return (0);
+		}
+//		break;
+	    case END:
+ 		return (1);	// Success!
+
+	    default:
+	        //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error),
+                printf ("ossimRegExp::find(): Internal error -- memory corrupted.\n");
+		return 0;
+	}
+	scan = next;
+    }
+
+    // 
+    //  We get here only if there's trouble -- normally "case END" is the
+    //  terminating point. 
+    // 
+    //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error),
+    printf ("ossimRegExp::find(): Internal error -- corrupted pointers.\n");
+    return (0);
+}
+
+
+/*
+ - regrepeat - repeatedly match something simple, report how many
+ */
+int ossimRegExp::regrepeat (const char* p) {
+    register       int   count = 0;
+    register const char* scan;
+    register const char* opnd;
+
+    scan = reginput;
+    opnd = OPERAND(p);
+    switch (OP(p)) {
+	case ANY:
+	    count = strlen(scan);
+	    scan += count;
+	    break;
+	case EXACTLY:
+	    while (*opnd == *scan) {
+		count++;
+		scan++;
+	    }
+	    break;
+	case ANYOF:
+	    while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
+		count++;
+		scan++;
+	    }
+	    break;
+	case ANYBUT:
+	    while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
+		count++;
+		scan++;
+	    }
+	    break;
+	default:		// Oh dear.  Called inappropriately.
+	    //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error),
+	    printf ("ossimRegExp::find(): Internal error.\n");
+	    return 0;
+    }
+    reginput = scan;
+    return (count);
+}
+
+
+/*
+ - regnext - dig the "next" pointer out of a node
+ */
+const char* ossimRegExp::regnext (register const char* p) {
+    register int offset;
+
+    if (p == &regdummy)
+	return (NULL);
+
+    offset = NEXT(p);
+    if (offset == 0)
+	return (NULL);
+
+    if (OP(p) == BACK)
+	return (p - offset);
+    else
+	return (p + offset);
+}
+
+
+char* ossimRegExp::regnext (register char* p) {
+    register int offset;
+
+    if (p == &regdummy)
+	return (NULL);
+
+    offset = NEXT(p);
+    if (offset == 0)
+	return (NULL);
+
+    if (OP(p) == BACK)
+	return (p - offset);
+    else
+	return (p + offset);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimRegExp.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimRegExp.h
new file mode 100644
index 0000000000..37ad40740a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimRegExp.h
@@ -0,0 +1,223 @@
+//
+// Copyright (C) 1991 Texas Instruments Incorporated.
+//
+// Permission is granted to any individual or institution to use, copy, modify,
+// and distribute this software, provided that this complete copyright and
+// permission notice is maintained, intact, in all copies and supporting
+// documentation.
+//
+// Texas Instruments Incorporated provides this software "as is" without
+// express or implied warranty.
+//
+// .NAME CoolRegExp - Pattern matching with regular expressions.
+// .LIBRARY cool
+// .HEADER String Classes
+// .INCLUDE cool/RegExp.h
+// .FILE cool/RegExp.C
+// .FILE cool/RegExp.h
+// .EXAMPLE examples/ex_RegExp.C
+//
+//
+// .SECTION Description
+//  A regular expression allows a programmer to specify  complex
+//  patterns  that  can  be searched for and matched against the
+//  character string of a string object. In its simplest form, a
+//  regular  expression  is  a  sequence  of  characters used to
+//  search for exact character matches. However, many times  the
+//  exact  sequence to be found is not known, or only a match at
+//  the beginning or end of a string is desired. The cool  regu-
+//  lar  expression  class implements regular expression pattern
+//  matching as is found and implemented in many  UNIX  commands
+//  and utilities.
+//
+//  The regular expression class provides a convenient mechanism
+//  for  specifying  and  manipulating  regular expressions. The
+//  regular expression object allows specification of such  pat-
+//  terns  by using the following regular expression metacharac-
+//  ters:
+// 
+//   ^        Matches at beginning of a line
+//
+//   $        Matches at end of a line
+//
+//  .         Matches any single character
+//
+//  [ ]       Matches any character(s) inside the brackets
+//
+//  [^ ]      Matches any character(s) not inside the brackets
+//
+//   -        Matches any character in range on either side of a dash
+//
+//   *        Matches preceding pattern zero or more times
+//
+//   +        Matches preceding pattern one or more times
+//
+//   ?        Matches preceding pattern zero or once only
+//
+//  ()        Saves a matched expression and uses it in a  later match
+// 
+//  Note that more than one of these metacharacters can be  used
+//  in  a  single  regular expression in order to create complex
+//  search patterns. For example, the pattern [^ab1-9]  says  to
+//  match  any  character  sequence that does not begin with the
+//  characters "ab"  followed  by  numbers  in  the  series  one
+//  through nine.
+ 
+
+#ifndef ossimRegExph
+#define ossimRegExph
+
+#include "ossimString.h"
+
+const int NSUBEXP = 10;
+
+
+class OSSIMDLLEXPORT ossimRegExp {
+public:
+  inline ossimRegExp ();			// ossimRegExp with program=NULL
+  inline ossimRegExp (const char*);	// ossimRegExp with compiled char*
+  ossimRegExp (const ossimRegExp&);	// Copy constructor
+  inline ~ossimRegExp();			// Destructor 
+
+  void compile (const char*);		// Compiles char* --> regexp
+  bool find (const char*);		// true if regexp in char* arg
+  inline ossim_uint32 start() const;	// Index to start of first find
+  inline ossim_uint32 end() const;	// Index to end of first find
+
+  bool operator== (const ossimRegExp&) const;	// Equality operator
+  inline bool operator!= (const ossimRegExp&) const; // Inequality operator
+  bool deep_equal (const ossimRegExp&) const;	// Same regexp and state?
+  
+  inline bool is_valid() const;		// true if compiled regexp
+  inline void set_invalid();		// Invalidates regexp
+
+  // awf added
+  ossim_uint32 start(ossim_uint32 n) const;
+  ossim_uint32 end(ossim_uint32 n) const;
+  std::string match(ossim_uint32 n) const;
+  
+private: 
+  const char* startp[NSUBEXP];
+  const char* endp[NSUBEXP];
+  char  regstart;			// Internal use only
+  char  reganch;			// Internal use only
+  const char* regmust;			// Internal use only
+  ossim_uint32 regmlen;			// Internal use only
+  char* program;   
+  ossim_uint32 progsize;
+  const char* searchstring;
+
+ // work variables
+  mutable const char* regparse;
+  mutable int   regnpar;	// () count.
+  mutable char  regdummy;
+  mutable char* regcode;	// Code-emit pointer; &regdummy = don't.
+  mutable long  regsize;	// Code size.
+  const char*  reginput;	// String-input pointer.
+  const char*  regbol;	// Beginning of input, for ^ check.
+  const char* *regstartp;	// Pointer to startp array.
+  const char* *regendp;	// Ditto for endp.
+
+  char* reg (int, int*);
+  char* regbranch (int*);
+  char* regpiece (int*);
+  char* regatom (int*);
+  char* regnode (char);
+  const char* regnext (register const char*);
+  char* regnext (register char*);
+  void        regc (unsigned char);
+  void        reginsert (char, char*);
+  void        regtail (char*, const char*);
+  void        regoptail (char*, const char*);
+  int regtry (const char*, const char* *,
+              const char* *, const char*);
+  int regmatch (const char*);
+  int regrepeat (const char*);
+#ifdef STRCSPN
+  int strcspn ();
+#endif
+  
+}; 
+
+// ossimRegExp -- Creates an empty regular expression.
+
+inline ossimRegExp::ossimRegExp () { 
+  this->program = NULL;
+}
+
+
+// ossimRegExp -- Creates a regular expression from string s, and
+// compiles s.
+
+
+inline ossimRegExp::ossimRegExp (const char* s) {  
+  this->program = NULL;
+  compile(s);
+}
+
+// ~ossimRegExp -- Frees space allocated for regular expression.
+
+inline ossimRegExp::~ossimRegExp () {
+//#ifndef WIN32
+  delete [] this->program;
+//#endif
+}
+
+// Start -- 
+
+inline ossim_uint32 ossimRegExp::start () const {
+  return(this->startp[0] - searchstring);
+}
+
+
+// End -- Returns the start/end index of the last item found.
+
+
+inline ossim_uint32 ossimRegExp::end () const {
+  return(this->endp[0] - searchstring);
+}
+
+
+// operator!= //
+
+inline bool ossimRegExp::operator!= (const ossimRegExp& r) const {
+  return(!(*this == r));
+}
+
+
+// is_valid -- Returns true if a valid regular expression is compiled
+// and ready for pattern matching.
+
+inline bool ossimRegExp::is_valid () const {
+  return (this->program != NULL);
+}
+
+
+// set_invalid -- Invalidates regular expression.
+
+inline void ossimRegExp::set_invalid () {
+//#ifndef WIN32
+  delete [] this->program;
+//#endif
+  this->program = NULL;
+}
+
+// -- Return start index of nth submatch. start(0) is the start of the full match.
+inline ossim_uint32 ossimRegExp::start(ossim_uint32 n) const
+{
+  return this->startp[n] - searchstring;
+}
+
+// -- Return end index of nth submatch. end(0) is the end of the full match.
+inline ossim_uint32 ossimRegExp::end(ossim_uint32 n) const
+{
+  return this->endp[n] - searchstring;
+}
+
+// -- Return nth submatch as a string.
+inline std::string ossimRegExp::match(ossim_uint32 n) const
+{
+	return std::string(this->startp[n], this->endp[n] - this->startp[n]);
+}
+
+#endif // CoolRegExph
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimString.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimString.cpp
new file mode 100644
index 0000000000..763af52bbc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimString.cpp
@@ -0,0 +1,743 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// Description: This class extends the stl's string class.
+// 
+//********************************************************************
+// $Id: ossimString.cpp,v 1.52 2005/10/17 18:37:16 gpotts Exp $
+
+#include <sstream>
+#include <algorithm>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimRegExp.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug("ossimString:debug");
+
+#ifdef OSSIM_ID_ENABLED
+static char OSSIM_ID[] = "$Id: ossimString.cpp,v 1.52 2005/10/17 18:37:16 gpotts Exp $";
+#endif
+
+ossimString::ossimString(char aChar)
+   :
+	std::string()
+{
+   char tmp[2];
+   tmp[0] = aChar;
+   tmp[1] = '\0';
+   append(tmp);
+}
+
+ossimString::ossimString(size_type n, char c)
+: std::string(n, c)
+{
+}
+
+ossimString ossimString::upcase(const ossimString& aString)
+{
+   ossimString s(aString);
+
+   ossimString::iterator eachCharacter = s.begin();
+   while(eachCharacter != s.end())
+   {
+      *eachCharacter = toupper(*eachCharacter);
+      eachCharacter++;
+   }
+
+   return s;
+}
+
+ossimString ossimString::downcase(const ossimString& aString)
+{
+   ossimString s(aString);
+
+   ossimString::iterator eachCharacter = s.begin();
+   while(eachCharacter != s.end())
+   {
+      *eachCharacter = tolower(*eachCharacter);
+      eachCharacter++;
+   }
+
+   return s;
+}
+
+ossimString& ossimString::upcase()
+{
+   ossimString::iterator eachCharacter = begin();
+   while(eachCharacter != end())
+   {
+      *eachCharacter = toupper(*eachCharacter);
+      eachCharacter++;
+   }
+
+   return *this;
+}
+
+ossimString& ossimString::downcase()
+{
+   ossimString::iterator eachCharacter=begin();
+   while(eachCharacter != end())
+   {
+      *eachCharacter = tolower(*eachCharacter);
+      eachCharacter++;
+   }
+
+   return *this;
+}
+
+char* ossimString::stringDup()const
+{
+   char *result = 0;
+
+   if(length() == 0)
+   {
+      result = new char;
+      result[0] = '\0';
+   }
+   else
+   {  
+      long index = 0;
+      long len = length();
+      result = new char[len+1];
+      const char* sourceString = c_str();
+
+      while(index < len) 
+      {
+         result[index] = sourceString[index];
+         index++;
+      }
+      result[len] = '\0';
+   }
+   return result;
+}
+
+ossimString ossimString::stripLeading(const ossimString &value, char characterToStrip)
+{
+   ossimString result;
+   ossimString::const_iterator stringIter = value.begin();
+   
+   while((*stringIter == characterToStrip)&&(stringIter!=value.end()))
+   {
+      ++stringIter;
+   }
+
+   while(stringIter != value.end())
+   {
+      result += *stringIter;
+      ++stringIter;
+   }
+   
+   return result;
+}
+
+ossimString ossimString::substitute(const ossimString &searchKey,
+                                    const ossimString &replacementValue,
+                                    bool replaceAll)const
+{
+   ossimString result = *this;
+
+   size_type pos = result.find(searchKey);
+   
+   if (pos == npos) return result;  // Search key not found.
+   
+   if(replaceAll)
+   {
+      while(pos != npos)
+      {
+         result.replace(pos, searchKey.size(), replacementValue.c_str());
+         pos = result.find(searchKey, pos+replacementValue.size());
+      }
+   }
+   else  // Replace only the first instance.
+   {
+      result.replace(pos, searchKey.size(), replacementValue.c_str());
+   }
+
+   return result;
+}
+
+ossimString& ossimString::gsub(const ossimString &searchKey,
+                               const ossimString &replacementValue,
+                               bool replaceAll)
+{
+   size_type pos = find(searchKey);
+   
+   if (pos == npos) return *this;  // Search key not found.
+   
+   if(replaceAll)
+   {
+      while(pos < size())
+      {
+         replace(pos, searchKey.size(), replacementValue.c_str());
+         pos = find(searchKey, pos+replacementValue.size());
+      }
+   }
+   else  // Replace only the first instance.
+   {
+      replace(pos, searchKey.size(), replacementValue.c_str());
+   }
+
+   return *this;
+}
+
+ossimString  ossimString::trim(const ossimString& valueToTrim) const
+{
+   ossimString tempString(*this);
+   
+   return tempString.trim(valueToTrim);
+}
+
+ossimString& ossimString::trim(const ossimString& valueToTrim)
+{
+   iterator startPos = (*this).begin();
+   iterator endPos   = (*this).end();
+
+   --endPos;
+   
+   while( (std::find(valueToTrim.begin(),
+                     valueToTrim.end(),
+                     *startPos)!=valueToTrim.end()) &&
+          (startPos != (*this).end())) ++startPos;
+
+   if(startPos == (*this).end())
+   {
+      *this = "";
+      return *this;
+   }
+   
+   while( (endPos!=startPos)&& (std::find(valueToTrim.begin(),
+                                          valueToTrim.end(),
+                                          *endPos)!=valueToTrim.end())) --endPos;
+
+   *this = ossimString(startPos, endPos+1);
+
+   return *this;
+}
+
+ossimString ossimString::beforePos(ossim_uint32 pos)const
+{
+   ossimString result = *this;
+
+   if(pos < length())
+   {
+      result.erase(pos, npos);
+   }
+
+   return result;
+}
+
+ossimString ossimString::afterPos(ossim_uint32 pos)const
+{
+   ossimString result = *this;
+
+   if(pos < length())
+   {
+      result.erase(0, pos+1);
+   }
+   else
+   {
+      return "";
+   }
+
+   return result;
+   
+}
+
+std::vector<ossimString> ossimString::explode(const ossimString& delimeter) const
+{
+   ossimString exp_str = *this;
+   std::vector<ossimString> result;
+   char* tokenPtr;
+
+   tokenPtr = strtok((char*)exp_str.chars(), (char*)delimeter.chars());
+
+   while(tokenPtr != NULL)
+   {
+      result.push_back(tokenPtr);
+      tokenPtr = strtok(NULL, delimeter.chars());
+   }
+
+   return result;
+}
+
+//---
+// Regular expression pattern utilities
+//---
+
+ossimString ossimString::beforeRegExp(const char *regularExpressionPattern) const
+{   
+   ossimRegExp anExpression;
+   
+   anExpression.compile(regularExpressionPattern);
+
+   if(anExpression.find(c_str()))
+   {
+      if (anExpression.start() > 0)
+      {
+         return substr(0, anExpression.start());
+      }
+   }
+   
+   return ossimString("");
+}
+
+ossimString ossimString::fromRegExp(const char *regularExpressionPattern) const
+{   
+   ossimRegExp anExpression;
+   
+   anExpression.compile(regularExpressionPattern);
+
+   if(anExpression.find(c_str()))
+   {
+      if (anExpression.start() < size())
+      {
+         return substr(anExpression.start(), (size()-anExpression.start()));
+      }
+   }
+   
+   return ossimString("");
+}
+
+ossimString ossimString::afterRegExp(const char *regularExpressionPattern) const
+{   
+   ossimRegExp anExpression;
+   
+   anExpression.compile(regularExpressionPattern);
+
+   if(anExpression.find(c_str()))
+   {
+      if (anExpression.end() < size())
+      {
+         return substr(anExpression.end(), (size()-anExpression.end()));
+      }
+   }
+   
+   return ossimString("");
+}
+
+ossimString ossimString::match(const char *regularExpressionPattern) const
+{   
+   ossimRegExp anExpression;
+   
+   anExpression.compile(regularExpressionPattern);
+
+   if((anExpression.find(this->c_str())) &&
+      (anExpression.start() !=anExpression.end()))
+   {
+      return this->substr(anExpression.start(),
+                          anExpression.end() - anExpression.start() );
+   }
+
+   
+   return ossimString("");
+}
+
+ossimString ossimString::replaceAllThatMatch(const char *regularExpressionPattern,
+                                             const char *value) const
+{
+   ossimString result = *this;
+   ossimRegExp anExpression;
+   ossim_uint32 offset     = 0;
+   ossim_uint32 valueLength = ossimString(value).length();
+   anExpression.compile(regularExpressionPattern);
+   if(!anExpression.is_valid())
+   {
+      return *this;
+   }
+   while(anExpression.find(result.c_str()+offset))
+   {
+      if(anExpression.start() < anExpression.end())
+      {
+         result.replace(anExpression.start() + offset,
+                        anExpression.end()-anExpression.start(),
+                        value);
+         offset += anExpression.start() + valueLength;
+      }
+      else
+      {
+         break;
+      }
+   }
+
+   return result;
+}
+
+ossimString ossimString::replaceStrThatMatch(const char *regularExpressionPattern,
+                                             const char *value) const
+{
+   ossimString result = *this;
+   ossimRegExp anExpression;
+   anExpression.compile(regularExpressionPattern);
+   if(!anExpression.is_valid())
+   {
+      return *this;
+   }
+   if(anExpression.find(result.c_str()))
+   {
+      if(anExpression.start() < anExpression.end())
+      {
+         result.replace(anExpression.start(),
+                        anExpression.end()-anExpression.start(),
+                        value);
+      }
+   }
+
+   return result;
+}
+
+double ossimString::toDouble()const
+{
+   if(contains("nan"))
+   {
+      return OSSIM_DBL_NAN;
+   }
+
+   return atof(c_str());
+}
+
+double ossimString::toDouble(const ossimString& aString)
+{
+   if(aString.contains("nan"))
+   {
+      return OSSIM_DBL_NAN;
+   }
+   return atof(aString.c_str());
+}
+
+int ossimString::toInt()const
+{
+   return atoi(c_str());
+}
+
+int ossimString::toInt(const ossimString& aString)
+{
+   return (int)atoi(aString.c_str());
+}
+
+ossim_int32 ossimString::toInt32()const
+{
+   return (ossim_int32)atoi(c_str());
+}
+
+ossim_int32 ossimString::toInt32(const ossimString& aString)
+{
+   return (ossim_int32)atoi(aString.c_str());
+}
+
+ossim_uint32 ossimString::toUInt32()const
+{
+   return static_cast<ossim_uint32>(atoi(c_str()));
+}
+
+ossim_uint32 ossimString::toUInt32(const ossimString& aString)
+{
+   return static_cast<ossim_uint32>(atoi(aString.c_str()));
+}
+
+long ossimString::toLong()const
+{
+   return atol(c_str());
+}
+
+long ossimString::toLong(const ossimString& aString)
+{
+   return atol(aString.c_str());
+}
+
+unsigned long  ossimString::toULong()const
+{
+   return static_cast<unsigned long>(atol(c_str()));
+}
+
+unsigned long ossimString::toULong(const ossimString& aString)
+{
+   return static_cast<unsigned long>(atol(aString.c_str()));
+}
+
+bool ossimString::toBool()const
+{
+   ossimString s = c_str();
+   s = s.trim().downcase();
+   if ( (s == "true") ||
+        (s == "yes")  ||
+        (s == "y")    ||
+        (s == "1") )
+   {
+      return true;
+   }
+   else if ( (s == "false") ||
+             (s == "no")    ||
+             (s == "n")     ||
+             (s == "0") )
+   {
+      return false;
+      
+   }
+   else if (toULong())
+   {
+      return true;
+   }
+
+   return false;
+}
+
+bool ossimString::toBool(const ossimString& aString)
+{
+   // Check for true or false, yes or no, y or n, and 1 or 0...
+   ossimString s = aString;
+   s.downcase();
+   if ( (s == "true") ||
+        (s == "yes")  ||
+        (s == "y")    ||
+        (s == "1") )
+   {
+      return true;
+   }
+   else if ( (s == "false") ||
+             (s == "no")    ||
+             (s == "n")     ||
+             (s == "0") )
+   {
+      return false;
+      
+   }
+   else if (aString.toULong())
+   {
+      return true;
+   }
+
+   return false;
+}
+
+ossimString ossimString::toString(bool aValue)
+{
+	std::ostringstream s;
+
+   s << aValue;
+
+   ossimString result(s.str());
+
+   return result;
+}
+
+ossimString ossimString::toString(ossim_int16 aValue)
+{
+	std::ostringstream s;
+
+   s << aValue;
+
+   ossimString result(s.str());
+
+   return result;
+}
+
+ossimString ossimString::toString(ossim_uint16 aValue)
+{
+	std::ostringstream s;
+
+   s << aValue;
+
+   ossimString result(s.str());
+
+   return result;
+}
+
+ossimString ossimString::toString(ossim_int32 aValue)
+{
+	std::ostringstream s;
+
+   s << aValue;
+
+   ossimString result(s.str());
+
+   return result;
+}
+
+ossimString ossimString::toString(ossim_uint32 aValue)
+{
+	std::ostringstream s;
+
+   s << aValue;
+
+   ossimString result(s.str());
+
+   return result;
+}
+
+ossimString ossimString::toString(long aValue)
+{
+	std::ostringstream s;
+
+   s << aValue;
+
+   ossimString result(s.str());
+
+   return result;
+}
+
+ossimString ossimString::toString(unsigned long aValue)
+{
+	std::ostringstream s;
+
+   s << aValue;
+
+   ossimString result(s.str());
+
+   return result;
+}
+
+ossimString ossimString::toString(ossim_float32 aValue,
+                                  int precision,
+                                  bool trimZeroFlag,
+                                  bool scientific)
+{
+   if (aValue == OSSIM_FLT_NAN)
+   {
+      return ossimString("nan");
+   }
+   
+   std::ostringstream s;
+
+   if (!scientific)
+   {
+	   s << setiosflags(std::ios::fixed);
+   }
+   else
+   {
+	   s << setiosflags(std::ios::scientific);
+   }
+
+   s << std::setprecision(precision) << aValue;
+   
+   ossimString result(s.str());
+
+   if( trimZeroFlag && result.contains(".") )
+   {
+      result = result.trim('0');
+      result = result.trim('.');
+   }
+   return result;
+}
+
+ossimString ossimString::toString(ossim_float64 aValue,
+                                  int precision,
+                                  bool trimZeroFlag,
+                                  bool scientific)
+{
+   if (aValue == OSSIM_DBL_NAN)
+   {
+      return ossimString("nan");
+   }
+   
+   std::ostringstream s;
+   
+   if (!scientific)
+   {
+	   s << setiosflags(std::ios::fixed);
+   }
+   else
+   {
+	   s << setiosflags(std::ios::scientific);
+   }
+
+   s << std::setprecision(precision) << aValue;
+
+   ossimString result(s.str());
+
+   if( trimZeroFlag && result.contains(".") )
+   {
+      result = result.trim('0');
+      result = result.trim('.');
+   }
+
+   return result;
+}
+
+ossimString ossimString::before(const ossimString& str, ossim_uint32 pos)
+{
+   if(*this == "") return ossimString();
+   
+   ossim_uint32 last = find(str.c_str(), pos);
+   if(last >= npos) return *this;
+   
+   return substr(0, last);
+}
+
+ossimString ossimString::after(const ossimString& str, ossim_uint32 pos)
+{
+   size_t last = find(str.c_str(), pos);
+   if (last >= npos) return ossimString();
+   
+   return substr(last+str.length());
+}
+
+void ossimString::split(std::vector<ossimString>& result,
+                        const ossimString& separatorList)const
+{
+//   result = split(separatorList);
+   ossimString copyString = *this;
+
+   char* s = strtok(const_cast<char*>(copyString.c_str()),
+                    separatorList.c_str());
+
+   for(ossim_uint32 i = 0; i < separatorList.size(); ++ i)
+   {
+      if((*(this->begin())) == separatorList.c_str()[i])
+      {
+         result.push_back("");
+      }
+   }
+   while(s)
+   {
+      result.push_back(ossimString(s));
+      s = strtok(NULL,
+                 separatorList.c_str());
+   }
+   for(ossim_uint32 i = 0; i < separatorList.size(); ++ i)
+   {
+      if((*(this->end()-1)) == separatorList.c_str()[i])
+      {
+         result.push_back("");
+      }
+   }
+}
+
+std::vector<ossimString> ossimString:: split(const ossimString& separatorList)const
+{
+   std::vector<ossimString> result;
+
+   split(result, separatorList);
+   
+   return result;
+}
+
+const ossimString& ossimString::join(const std::vector<ossimString>& stringList,
+                                     const ossimString& separator)
+{
+   *this = "";
+   if(stringList.size())
+   {
+      for(long i = 0; i < ((long)stringList.size()-1); ++i)
+      {
+         *this += stringList[i];
+         *this += separator;
+      }
+      *this += stringList[stringList.size()-1];
+   }
+
+   return *this;
+}
+
+ossimString ossimString::getOssimId() const
+{
+#ifdef OSSIM_ID_ENABLED
+   return ossimString(OSSIM_ID);
+#endif
+   return ossimString("");
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimString.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimString.h
new file mode 100644
index 0000000000..6fa67e321d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimString.h
@@ -0,0 +1,307 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// Description: This class extends the stl's string class.
+//
+//********************************************************************
+// $Id: ossimString.h,v 1.42 2005/10/17 18:37:16 gpotts Exp $
+#ifndef ossimString_HEADER
+#define ossimString_HEADER
+#include <string>
+#include <cstring>
+#include <cstdlib>
+#include <iomanip>
+#include <vector>
+#include <base/common/ossimConstants.h>
+
+class OSSIM_DLL ossimString : public std::string
+{
+public:
+	ossimString():std::string(){}
+	ossimString(const std::string& aString):std::string(aString){}
+	ossimString(const char *aString):std::string(aString?aString:""){}
+	ossimString(const ossimString& aString):std::string(aString.c_str()){}
+   ossimString(char aChar);
+
+   /**
+    * Create a string with n copies of c.
+    */
+   ossimString(size_type n, char c);
+   
+   template <class Iter>
+	   ossimString(Iter start, Iter end):std::string(start, end){}
+
+
+   bool contains(const ossimString& aString) const {return find(aString)!=npos;}
+   bool contains(const char*   aString) const {return find(aString)!=npos;}
+
+   const ossimString& operator =(const char* s)
+      {
+         return (*this = ossimString(s));
+
+      }
+   const ossimString& operator =(char c)
+      {
+         return (*this = ossimString(c));
+
+      }
+   const ossimString& operator =(const ossimString& s)
+      {
+		  std::string::operator =(s.c_str());
+         return *this;
+      }
+   const ossimString& operator +=(const ossimString& s)
+      {
+         append(s.c_str());
+         return *this;
+      }
+   const ossimString& operator +=(const char* s)
+      {
+         append(ossimString(s).c_str());
+         return *this;
+      }
+   const ossimString& operator +=(char c)
+      {
+         append(ossimString(c).c_str());
+         return *this;
+      }
+   ossimString operator +(const ossimString& s)const
+      {
+         ossimString returnS(*this);
+
+         returnS.append(s.c_str());
+
+         return returnS;
+      }
+   ossimString operator +(const char* s)const
+      {
+         ossimString returnS(*this);
+
+         returnS.append(ossimString(s).c_str());
+
+         return returnS;
+      }
+   ossimString operator +(char c)const
+      {
+         ossimString returnS(*this);
+
+         returnS.append(ossimString(c).c_str());
+
+         return returnS;
+      }
+   bool operator==(const ossimString& s) const {return (strcmp(this->c_str(),s.c_str())==0);}
+   bool operator==(const char* s) const {return (strcmp(this->c_str(),s)==0);}
+   bool operator!=(const ossimString& s) const {return (strcmp(this->c_str(),s.c_str())!=0);}
+   bool operator!=(const char* s) const {return (strcmp(this->c_str(),s)!=0);}
+
+   char& operator[](int i)
+      {
+         return *( const_cast<char*>(c_str())+i);
+      }
+   const char& operator[](int i)const
+      {
+         return *(c_str()+i);
+      }
+   /**
+    * this will strip lead and trailing character passed in.
+    * So if you want to remove blanks:
+    *    ossimString temp("       asdfasdf      ");
+    *    ossimString trimmedString = temp.trim(" \n\t\r");
+    *
+    *    this will now contain "asdfasdf" without the blanks.
+    *
+    */
+   ossimString trim(const ossimString& valueToTrim= ossimString(" \t\n\r"))const;
+   ossimString& trim(const ossimString& valueToTrim= ossimString(" \t\n\r"));
+
+   ossimString beforePos(ossim_uint32 pos)const;
+   ossimString afterPos(ossim_uint32 pos)const;
+
+   /**
+    *  Substitudes searchKey string with replacementValue and returns a
+    *  string.  Will replace all occurrances found if "replaceAll" is true.
+    */
+   ossimString substitute(const ossimString &searchKey,
+                          const ossimString &replacementValue,
+                          bool replaceAll=false)const;
+
+   /**
+    *  Substitudes searchKey string with replacementValue and returns a
+    *  reference to *this.  Will replace all occurrances found if
+    *  "replaceAll" is true.  (like substitute only works on "this")
+    */
+   ossimString& gsub(const ossimString &searchKey,
+                     const ossimString &replacementValue,
+                     bool replaceAll=false);
+
+   std::vector<ossimString> explode(const ossimString& delimeter) const;
+
+   /**
+    * @param aString String to make an upcased copy of.
+    * 
+    * @return An upcased version of aString.
+    */
+   static ossimString upcase(const ossimString& aString);
+
+   /**
+    * @param aString String to make an downcased copy of.
+    * 
+    * @return A downcased version of aString.
+    */
+   static ossimString downcase(const ossimString& aString);
+
+   /**
+    * Upcases this string.
+    * 
+    * @return Reference to this.
+    */
+   ossimString& upcase();
+   
+   /**
+    * Downcases this string.
+    * 
+    * @return Reference to this.
+    */
+   ossimString& downcase();
+
+   operator const char*()const{return c_str();}
+   const char* chars()const{return c_str();}
+
+   /**
+    * METHOD: before(str, pos)
+    * Returns string beginning at pos and ending one before the token str
+    * If string not found or pos out of range the whole string will be
+    * returned.
+    */
+   ossimString before(const ossimString& str, ossim_uint32 pos=0);
+
+   /**
+    * METHOD: after(str, pos)
+    * Returns string immediately after the token str. The search for str
+    * begins at pos.  Returns an emptry string if not found or pos out of
+    * range.
+    */
+   ossimString after (const ossimString& str, ossim_uint32 pos=0);
+
+   char* stringDup()const;
+
+   /**
+    * String to numeric methods.
+    */
+   bool                 toBool()const;
+   static bool          toBool(const ossimString& aString);
+   int                  toInt()const;
+   static int           toInt(const ossimString& aString);
+   ossim_int32          toInt32()const;
+   static ossim_int32   toInt32(const ossimString& aString);
+   ossim_uint32         toUInt32()const;
+   static ossim_uint32  toUInt32(const ossimString& aString);
+   long                 toLong()const;
+   static long          toLong(const ossimString& aString);
+   unsigned long        toULong()const;
+   static unsigned long toULong(const ossimString& aString);
+   double               toDouble()const;
+   static double        toDouble(const ossimString& aString);
+
+   /**
+    * Numeric to string methods.
+    */
+   static ossimString toString(bool aValue);
+   static ossimString toString(ossim_int16   aValue);
+   static ossimString toString(ossim_uint16  aValue);
+   static ossimString toString(ossim_int32   aValue);
+   static ossimString toString(ossim_uint32  aValue);
+   static ossimString toString(long          aValue);
+   static ossimString toString(unsigned long aValue);
+
+   /**
+    * @param aValue Value to convert to string.
+    *
+    * @param precision Decimal point precision of the output.
+    * 
+    * @param trimZeroFlag If true trailing '0's and any trailing '.' will
+    * be trimmed.
+    *
+    * @param scientific If true output will be in scientific notation else
+    * fixed is used.
+    */
+   static ossimString toString(ossim_float32 aValue,
+                               int  precision    = 8,
+                               bool trimZeroFlag = false,
+                               bool scientific   = false );
+   
+   /**
+    * @param aValue Value to convert to string.
+    *
+    * @param precision Decimal point precision of the output.
+    *
+    * @param trimZeroFlag If true trailing '0's and any trailing '.' will
+    * be trimmed.
+    *
+    * @param scientific If true output will be in scientific notation else
+    * fixed is used.
+    */
+   static ossimString toString(ossim_float64 aValue,
+                               int  precision    = 15,
+                               bool trimZeroFlag = false,
+                               bool scientific   = false);
+
+   static ossimString stripLeading(const ossimString &value,
+                                   char characterToStrip);
+
+
+   void split(std::vector<ossimString>& result,
+              const ossimString& separatorList)const;
+
+   std::vector<ossimString> split(const ossimString& separatorList)const;
+
+   const ossimString& join(const std::vector<ossimString>& stringList,
+                           const ossimString& separator);
+
+   //---
+   // Regular expression pattern utilities
+   //---
+
+   /**
+    * Returns from start of string up to but not including found pattern.
+    * Returns "" if pattern not found.
+    */
+   ossimString beforeRegExp(const char *regularExpressionPattern) const;
+
+   /**
+    * Returns from position of found pattern to end of string.
+    * Returns "" if pattern not found.
+    */
+   ossimString fromRegExp(const char *regularExpressionPattern) const;
+
+   /**
+    * Returns from position after found pattern to end of string.
+    * Returns "" if pattern not found.
+    */
+   ossimString afterRegExp(const char *regularExpressionPattern) const;
+
+   /**
+    * Returns from found pattern to end of pattern.
+    * Returns "" if pattern not found.
+    */
+   ossimString match(const char *regularExpressionPattern) const;
+
+   ossimString replaceAllThatMatch(const char *regularExpressionPattern,
+                                   const char *value="") const;
+
+   ossimString replaceStrThatMatch(const char *regularExpressionPattern,
+                                   const char *value="") const;
+
+   /**
+    * If OSSIM_ID_ENABLED returns the OSSIM_ID which currently is the
+    * expanded cvs $Id: ossimString.h,v 1.42 2005/10/17 18:37:16 gpotts Exp $ macro; else, an empty string.
+    */
+   ossimString getOssimId() const;
+};
+
+#endif /* #ifndef ossimString_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimTempFilename.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimTempFilename.cpp
new file mode 100644
index 0000000000..8e92c8ad66
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimTempFilename.cpp
@@ -0,0 +1,114 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// Description: This is a tmeporary filename class it will create a temporary
+//              file and will also delete it upon destruction
+//
+//*************************************************************************
+// $Id: ossimTempFilename.cpp,v 1.5 2005/10/04 15:10:35 gpotts Exp $
+#include <stdlib.h>
+#include <fstream>
+#include "ossimTempFilename.h"
+#include <time.h>
+
+ossimTempFilename::ossimTempFilename(const ossimString& tempDir,
+                                     const ossimString& prefix,
+                                     const ossimString& extension,
+                                     bool autodelete,
+                                     bool useWildcardDelete)
+   :theTempDir(tempDir),
+    thePrefix(prefix),
+    theExtension(extension),
+    theAutoDeleteFlag(autodelete),
+    theWildCardDeleteFlag(useWildcardDelete)
+{
+}
+
+ossimTempFilename::~ossimTempFilename()
+{
+   if(*((ossimFilename*)this) != "")
+   {
+      
+      if(theAutoDeleteFlag)
+      {
+         if(theWildCardDeleteFlag)
+         {
+            wildcardRemove(*this + ".*");
+         }
+         else
+         {
+            remove();
+         }
+      }
+   }
+}
+
+void  ossimTempFilename::generateRandomFile()
+{
+   generate(false);
+}
+
+void ossimTempFilename::generateRandomDir()
+{
+   generate(true);
+}
+
+void ossimTempFilename::generate(bool createAsDirectoryFlag)
+{
+   srand(time(0));
+   ossimString tempDirCopy = theTempDir;
+
+   if(tempDirCopy == "")
+   {
+      tempDirCopy = ossimString(getenv("TEMP"));
+      if(tempDirCopy=="")
+      {
+         tempDirCopy  = ossimString(getenv("TMP"));
+      }
+      if(tempDirCopy == "")
+      {
+         if(ossimFilename("/tmp").exists())
+         {
+            tempDirCopy = "/tmp";
+         }
+      }
+   }
+
+   int count = 0;
+   int randNumber1 = rand();
+   ossimFilename prefixDir = ossimFilename(tempDirCopy);
+   ossimFilename result = prefixDir.dirCat(thePrefix+
+                                           ossimString::toString(randNumber1));
+   
+   while((count < RAND_MAX)&&result.exists())
+   {
+      randNumber1 = rand();
+      result = prefixDir.dirCat(thePrefix+
+                                ossimString::toString(randNumber1));
+      
+      ++count;
+   }
+
+   if(theExtension != "")
+   {
+      result = result.setExtension(theExtension);
+   }
+   *((ossimFilename*)this) = result;
+   if(result != "")
+   {
+      if(createAsDirectoryFlag)
+      {
+         createDirectory();
+      }
+      else
+      {
+         std::ofstream out(result.c_str());
+         out.close();
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimTempFilename.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimTempFilename.h
new file mode 100644
index 0000000000..5fc2a1d6c3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimTempFilename.h
@@ -0,0 +1,42 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// Description: This is a tmeporary filename class it will create a temporary
+//              file and will also delete it upon destruction
+//
+//*************************************************************************
+// $Id: ossimTempFilename.h,v 1.3 2005/10/03 13:20:24 gpotts Exp $
+#ifndef ossimTempFilename_HEADER
+#define ossimTempFilename_HEADER
+#include <base/data_types/ossimFilename.h>
+
+class OSSIM_DLL ossimTempFilename : public ossimFilename
+{
+public:
+   ossimTempFilename(const ossimString& tempDir="",
+                     const ossimString& prefix = "",
+                     const ossimString& extension = "",
+                     bool autodelete=true,
+                     bool useWildcardDelete=true);
+
+   void generateRandomFile();
+   void generateRandomDir();
+   
+   ~ossimTempFilename();
+   
+protected:
+   ossimString theTempDir;
+   ossimString thePrefix;
+   ossimString theExtension;
+   bool theAutoDeleteFlag;
+   bool theWildCardDeleteFlag;
+   
+
+   void generate(bool createAsDirectoryFlag);
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimVrect.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimVrect.cpp
new file mode 100644
index 0000000000..976e00c206
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimVrect.cpp
@@ -0,0 +1,41 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class declaration for vrect.
+// Container class for four double points representing a rectangle
+// where y is up
+// 
+//*******************************************************************
+//  $Id: ossimVrect.cpp,v 1.3 2005/07/15 18:51:25 dburken Exp $
+
+#include "ossimVrect.h"
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+void ossimVrect::print(std::ostream& os) const
+{
+   os << theUlCorner << theLrCorner;
+}
+
+//*******************************************************************
+// friend function:
+//*******************************************************************
+std::ostream& operator<<(std::ostream& os, const ossimVrect& rect)
+{
+   rect.print(os);
+
+   return os;
+}
+
+ossimVrect::~ossimVrect()
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimVrect.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimVrect.h
new file mode 100644
index 0000000000..72f5a38538
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimVrect.h
@@ -0,0 +1,162 @@
+//*******************************************************************
+//
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class declaration for vrect.
+// Container class for four double points representing a rectangle
+// where y is up
+// 
+//*******************************************************************
+//  $Id: ossimVrect.h,v 1.5 2005/07/15 18:51:25 dburken Exp $
+#ifndef ossimVrect_HEADER
+#define ossimVrect_HEADER
+#include <iostream>
+
+#include <base/data_types/ossimDpt.h>
+
+class OSSIMDLLEXPORT ossimVrect
+{
+public:
+   ossimVrect()
+      :theUlCorner(0.0, 0.0),
+       theLlCorner(0.0, 0.0),
+       theLrCorner(0.0, 0.0),
+       theUrCorner(0.0, 0.0)
+      {}
+   ossimVrect(const ossimDpt &ul,
+         const ossimDpt &lr)
+      :theUlCorner(ul),
+       theLlCorner(ul.x, lr.y),
+       theLrCorner(lr),
+       theUrCorner(lr.x, ul.y)
+      {}
+   ossimVrect(double ul_corner_x,
+         double ul_corner_y,
+         double lr_corner_x,
+         double lr_corner_y)
+      :
+         theUlCorner(ul_corner_x, ul_corner_y),
+         theLlCorner(ul_corner_x, lr_corner_y),
+         theLrCorner(lr_corner_x, lr_corner_y),
+         theUrCorner(lr_corner_x, ul_corner_y)
+      {}
+   ossimVrect(const ossimVrect& rect)
+      :
+         theUlCorner(rect.ul()),
+         theLlCorner(rect.ll()),
+         theLrCorner(rect.lr()),
+         theUrCorner(rect.ur())
+      {}
+
+   ~ossimVrect();
+
+   const ossimVrect& operator=  (const ossimVrect& rect);
+   bool         operator!= (const ossimVrect& rect) const;
+   bool         operator== (const ossimVrect& rect) const;
+   
+   const ossimDpt &ul() const { return theUlCorner; }
+   const ossimDpt &ur() const { return theUrCorner; }
+   const ossimDpt &lr() const { return theLrCorner; }
+   const ossimDpt &ll() const { return theLlCorner; }
+   /*!
+    * Returns the height of a rectangle.
+    */
+   ossim_float64 height() const
+      { return fabs(theLlCorner.y - theUlCorner.y) + 1.0; }
+
+   /*!
+    * Returns the width of a rectangle.
+    */
+   ossim_float64 width()  const
+      { return fabs(theLrCorner.x - theLlCorner.x) + 1.0; }
+   
+   inline ossimDpt midPoint()const;
+   void print(std::ostream& os) const;
+   
+   ossimVrect combine(const ossimVrect& rect)const;
+   inline ossimVrect clipToRect(const ossimVrect& rect)const;
+
+   friend std::ostream& operator<<(std::ostream& os, const ossimVrect& rect);
+
+private:
+   ossimDpt theUlCorner;
+   ossimDpt theLlCorner;
+   ossimDpt theLrCorner;
+   ossimDpt theUrCorner;
+};
+
+inline const ossimVrect& ossimVrect::operator=(const ossimVrect& rect)
+{
+   if (this != &rect)
+   {
+      theUlCorner = rect.ul();
+      theUrCorner = rect.ur();
+      theLrCorner = rect.lr();
+      theLlCorner = rect.ll();
+   }
+
+   return *this;
+}
+
+inline bool ossimVrect::operator!=(const ossimVrect& rect) const
+{
+   return ( (theUlCorner != rect.ul()) ||
+            (theUrCorner != rect.ur()) ||
+            (theLrCorner != rect.lr()) ||
+            (theLlCorner != rect.ll()) );
+}
+
+inline bool ossimVrect::operator==(const ossimVrect& rect) const
+{
+   return ( (theUlCorner == rect.ul()) &&
+            (theUrCorner == rect.ur()) &&
+            (theLrCorner == rect.lr()) &&
+            (theLlCorner == rect.ll()) );
+}
+
+#define d_MIN(a,b)      (((a)<(b)) ? a : b)
+#define d_MAX(a,b)      (((a)>(b)) ? a : b)
+
+inline ossimVrect ossimVrect::clipToRect(const ossimVrect& rect)const
+{
+    ossim_float64     ulx, uly, lrx, lry;
+
+    ulx = d_MAX(rect.ul().x,ul().x);
+    uly = d_MAX(rect.ul().y,ul().y);
+    lrx = d_MIN(rect.lr().x,lr().x);
+    lry = d_MIN(rect.lr().y,lr().y);
+
+    if( lrx <= ulx || lry <= uly )
+        return ossimVrect(ossimDpt(0,0),ossimDpt(0,0));
+    else
+       return ossimVrect(ulx,uly,lrx,lry);
+}
+
+inline ossimDpt ossimVrect::midPoint()const
+{
+   return ossimDpt( (ul().x + ur().x + ll().x + lr().x)*.25,
+               (ul().y + ur().y + ll().y + lr().y)*.25);
+}
+
+inline ossimVrect ossimVrect::combine(const ossimVrect& rect)const
+{
+   ossimDpt ulCombine;
+   ossimDpt lrCombine;
+   
+   ulCombine.x = ((ul().x <= rect.ul().x)?ul().x:rect.ul().x);
+   ulCombine.y = ((ul().y >= rect.ul().y)?ul().y:rect.ul().y);
+   lrCombine.x = ((lr().x >= rect.lr().x)?lr().x:rect.lr().x);
+   lrCombine.y = ((lr().y <= rect.lr().y)?lr().y:rect.lr().y);
+
+   return ossimVrect(ulCombine, lrCombine);
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlAttribute.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlAttribute.cpp
new file mode 100644
index 0000000000..e0d6b50294
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlAttribute.cpp
@@ -0,0 +1,236 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.  All rights reserved.
+//
+// License:  See top level LICENSE.txt file.
+// 
+// Author:  Oscar Kramer (ossim port by D. Burken)
+//
+// Description:  
+//
+// Contains definition of class ossimXmlAttribute.
+// 
+//*****************************************************************************
+// $Id: ossimXmlAttribute.cpp,v 1.6 2005/12/16 14:26:21 dburken Exp $
+
+#include <iostream>
+#include <sstream>
+
+#include <base/data_types/ossimXmlAttribute.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF2(ossimXmlAttribute, "ossimXmlAttribute", ossimObject, ossimErrorStatusInterface)
+
+static std::istream& xmlskipws(std::istream& in)
+{
+   int c = in.peek();
+   while((c == ' ') ||
+         (c == '\t') ||
+         (c == '\n'))
+   {
+      in.ignore(1);
+      c = in.peek();
+   }
+   
+   return in;
+}
+
+ossimXmlAttribute::ossimXmlAttribute(ossimString& spec)
+{
+   std::stringstream in(spec);
+
+   read(in);
+}
+
+ossimXmlAttribute::ossimXmlAttribute(const ossimXmlAttribute& src)
+   :theName(src.theName),
+    theValue(src.theValue)
+{
+}
+
+bool ossimXmlAttribute::read(std::istream& in)
+{
+   in >> xmlskipws;
+   if(readName(in))
+   {
+      in >> xmlskipws;
+      if(in.peek() != '=')
+      {
+         setErrorStatus();
+         return false;
+      }
+      in.ignore(1);
+      if(readValue(in))
+      {
+         return true;
+      }
+      else
+      {
+         setErrorStatus();
+         return false;
+      }
+   }
+   return false;
+   
+#if 0   
+   //
+   // Pull out name:
+   //
+   theName = spec.before('=');
+   theName = theName.trim();
+   if (theName.empty())
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "ossimXmlAttribute::ossimXmlAttribute \n"
+                                           << "Bad attribute format encountered near:\n\""<< spec<<"\"\n"
+                                           << "Parsing aborted...\n";
+      setErrorStatus();
+      
+      return;
+   }
+   spec = spec.after('=');
+
+   //***
+   // Read value:
+   //***
+   char quote_char = spec[0];
+   spec = spec.after(quote_char);  // after first quote
+   theValue = spec.before(quote_char); // before second quote
+
+   //
+   // Reposition attribute specification to the start of next attribute or end
+   // of tag:
+   //
+   spec = spec.after(quote_char);  // after second quote
+   ossimString next_entry ("-?[+0-9A-Za-z<>]+");
+   spec = spec.fromRegExp(next_entry.c_str());
+#endif
+}
+
+ossimXmlAttribute::~ossimXmlAttribute()
+{
+}
+
+ossimXmlAttribute::ossimXmlAttribute()
+{
+}
+
+ossimXmlAttribute::ossimXmlAttribute(const ossimString& name,
+                                     const ossimString& value)
+{
+   setNameValue(name, value);
+}
+
+ossimString ossimXmlAttribute::getName()  const
+{
+   return theName;
+}
+
+ossimString ossimXmlAttribute::getValue() const
+{
+   return theValue;
+}
+
+void ossimXmlAttribute::setNameValue(const ossimString& name,
+                                     const ossimString& value)
+{
+   theName  = name;
+   theValue = value;
+}
+
+void ossimXmlAttribute::setName(const ossimString& name)
+{
+   theName = name;
+}
+
+void ossimXmlAttribute::setValue(const ossimString& value)
+{
+   theValue = value;
+}
+
+std::ostream& operator << (std::ostream& os, const ossimXmlAttribute* xml_attr) 
+{
+   os << " " << xml_attr->theName << "=\"" << xml_attr->theValue << "\"";
+
+   return os;
+}
+
+
+bool ossimXmlAttribute::readName(std::istream& in)
+{
+   in >>xmlskipws;
+   theName = "";
+   char c = in.peek();
+   while((c != ' ')&&
+         (c != '\n')&&
+         (c != '\t')&&
+         (c != '=')&&
+         (c != '<')&&
+         (c != '/')&&
+         (c != '>')&&
+         (!in.bad()))
+   {
+      theName += (char)in.get();
+      c = in.peek();
+   }
+
+   return ((!in.bad())&&
+           (theName != ""));
+}
+
+bool ossimXmlAttribute::readValue(std::istream& in)
+{
+   in >>xmlskipws;
+   theValue = "";
+   char c = in.peek();
+   bool done = false;
+
+   if((c == '\'')||
+      (c == '"'))
+   {
+      theValue += in.get();
+      while(!done&&!in.bad())
+      {
+         c = in.peek();
+         if((c == '\'')||
+            (c == '"'))
+         {
+            theValue += c;
+            done = true;
+            in.ignore(1);
+            
+         }
+         else if(c == '\n')
+         {
+            done = true;
+         }
+         else
+         {
+            theValue += in.get();
+         }
+      }
+   }
+
+   if(theValue != "")
+   {
+      ossimString::iterator startIter = theValue.begin();
+      ossimString::iterator endIter   = --theValue.end();
+      if((*startIter == '\'')||
+         (*startIter == '"'))
+      {
+         ++startIter;
+      }
+      else
+      {
+         return false;
+         setErrorStatus();
+      }
+      if((*endIter != '\'')&&
+         (*endIter != '"'))
+      {
+         return false;
+         setErrorStatus();
+      }
+      theValue = ossimString(startIter, endIter);
+   }
+   return ((!in.bad())&&
+           (theValue !=""));
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlAttribute.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlAttribute.h
new file mode 100644
index 0000000000..45b54e877f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlAttribute.h
@@ -0,0 +1,52 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.  All rights reserved.
+//
+// License:  See top level LICENSE.txt file.
+// 
+// Author:  Oscar Kramer (ossim port by D. Burken)
+//
+// Description:  
+//
+// Contains declaration of class ossimAttribute.
+//
+//*****************************************************************************
+// $Id: ossimXmlAttribute.h,v 1.6 2005/12/16 14:26:21 dburken Exp $
+#ifndef ossimXmlAttribute_HEADER
+#define ossimXmlAttribute_HEADER
+
+#include <base/common/ossimErrorStatusInterface.h>
+#include "ossimString.h"
+#include <base/common/ossimObject.h>
+
+class OSSIMDLLEXPORT ossimXmlAttribute : public ossimObject,
+                                         public ossimErrorStatusInterface
+{
+public:
+   ossimXmlAttribute(ossimString& spec);  // attribute removed from spec string
+   ossimXmlAttribute();
+   ossimXmlAttribute(const ossimXmlAttribute& src);
+   ossimXmlAttribute(const ossimString& name,
+                     const ossimString& value);
+   ~ossimXmlAttribute();
+
+   bool read(std::istream& in);
+   ossimString getName()  const;
+   ossimString getValue() const;
+   void setNameValue(const ossimString& name,
+                     const ossimString& value);
+   void setName(const ossimString& name);
+   void setValue(const ossimString& value);
+   
+   OSSIMDLLEXPORT friend std::ostream& operator<<(
+      std::ostream& os, const ossimXmlAttribute* xml_attr);
+
+protected:
+   ossimString theName;
+   ossimString theValue;
+
+   bool readName(std::istream& in);
+   bool readValue(std::istream& in);
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimXmlAttribute_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlDocument.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlDocument.cpp
new file mode 100644
index 0000000000..8accdb476c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlDocument.cpp
@@ -0,0 +1,409 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Oscar Kramer (ossim port by D. Burken)
+//
+// Description:  
+//
+// Contains definition of class ossimXmlDocument. This class provides read-only
+// parsing and accessing of an XML document file.
+//*****************************************************************************
+// $Id: ossimXmlDocument.cpp,v 1.7 2005/06/13 18:53:37 gpotts Exp $
+
+#include <stack>
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+#include <base/data_types/ossimXmlDocument.h>
+#include <base/data_types/ossimXmlAttribute.h>
+#include <base/data_types/ossimXmlNode.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimRegExp.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimKeywordNames.h>
+
+//
+// Static trace for debugging
+//
+#include "base/common/ossimTrace.h"
+static ossimTrace traceDebug("ossimXmlDocument:debug");
+
+static std::istream& xmlskipws(std::istream& in)
+{
+   int c = in.peek();
+   while((c == ' ') ||
+         (c == '\t') ||
+         (c == '\n'))
+   {
+      in.ignore(1);
+      c = in.peek();
+   }
+   
+   return in;
+}
+
+static const int BUFFER_MAX_LEN = 1000;
+static const ossimString XPATH_DELIM ("/");
+
+RTTI_DEF1(ossimXmlDocument, "ossimXmlDocument", ossimObject)
+ossimXmlDocument::ossimXmlDocument(const ossimFilename& xmlFileName)
+   :
+   theRootNode  (0),
+   theXmlHeader("<?xml version='1.0'?>")
+{
+
+   if(xmlFileName != "")
+   {
+      openFile(xmlFileName);
+   }
+}
+
+ossimXmlDocument::~ossimXmlDocument()
+{
+}
+
+bool ossimXmlDocument::write(const ossimFilename& file)
+{
+   std::ofstream out(file);
+
+   if(out)
+   {
+      out << *this << std::endl;
+   }
+   else
+   {
+      return false;
+   }
+
+   return true;
+}
+
+bool ossimXmlDocument::openFile(const ossimFilename& filename)
+{
+   
+   theFilename = filename;
+
+   if(theFilename == "")
+   {
+      return false;
+   }
+
+   //
+   // Open XML File:
+   // Note: Opening text document binary to overcome an apparent windows bug.
+   //
+   ifstream xml_stream (filename.c_str(), ios::binary);
+   if (!xml_stream)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG: ossimXmlDocument::ossimXmlDocument\n"
+            << "encountered opening file <" << filename << "> for "
+            << "reading. Aborting..." << endl;
+      }
+      return false;
+   }
+
+   return read(xml_stream);
+}
+
+bool ossimXmlDocument::read(std::istream& in)
+{
+//   char buffer[BUFFER_MAX_LEN];
+//   streampos file_pos;
+//   bool readingHeader = true;
+   bool startTagCharacterFound = false;
+   char c = in.peek();
+
+
+   // initially we will do our own skipping to make sure we ar not binary
+   //
+   while(!in.bad()&&
+         (c != '<')&&
+         (c >= 0x20)&&(c <= 0x7e))
+   {
+      in.ignore(1);
+      c = in.peek();
+   }
+
+   if (in.bad()||
+       (c!='<'))
+   {
+      setErrorStatus();
+      return false;
+   }
+   startTagCharacterFound = true;
+
+   theXmlHeader = "";
+   if(readHeader(in))
+   {
+      if(theXmlHeader=="")
+      {
+         if(startTagCharacterFound)
+         {
+            theXmlHeader = "<?xml version='1.0'?>";
+         }
+         else
+         {
+            setErrorStatus();
+            return false;
+         }
+      }
+   }
+   if((!theXmlHeader.contains("xml version"))&&
+      (!startTagCharacterFound))
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "FATAL: ossimXmlDocument::ossimXmlDocument"
+            << "encountered parsing XML file <" << theFilename
+            << ">. The file does not appear to be XML v1.0. \n"
+            << "Header = \n" << theXmlHeader <<"\n"
+            << endl;
+      }
+      setErrorStatus();
+      return false;
+   }
+   theRootNode = new ossimXmlNode(in, 0);
+   setErrorStatus(theRootNode->getErrorStatus());
+   return (getErrorStatus()==ossimErrorCodes::OSSIM_OK);
+}
+
+void ossimXmlDocument::findNodes(const ossimString& arg_xpath,
+                            vector<ossimRefPtr<ossimXmlNode> >& result) const
+{
+   //
+   // First verify the root node exists:
+   //
+   if (!theRootNode.valid())
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "WARNING: ossimXmlDocument::findNodes,\n"
+            << "No root node has been instantiated. Returning null "
+            << "node list..." << endl;
+      }
+      return;
+   }
+
+   //
+   // Make a copy to manipulate:
+   //
+   ossimString xpath (arg_xpath);
+   if (xpath.empty())
+      return;
+   
+   //
+   // Check if absolute path:
+   //
+   if (xpath[0] != XPATH_DELIM[0])
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "WARNING: ossimXmlDocument::findNodes\n"
+            << "Only absolute XPaths are supported. Returning null "
+            << "node list..." << endl;
+      }
+      return;
+   }
+
+   //
+   // Check that root tag matches path root:
+   //
+   ossimString rel_xpath (xpath.after(XPATH_DELIM));
+   ossimString root_tag (rel_xpath);
+   if (root_tag.contains(XPATH_DELIM))
+       root_tag = rel_xpath.before(XPATH_DELIM);
+   
+   if (root_tag != theRootNode->getTag())
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "WARNING: ossimXmlDocument::findNodes\n"
+            << "XPath's root node <"<<root_tag<<"> does not match the "
+            << "stored root node's tag <" << theRootNode->getTag() << ">. "
+            << "Returning null node list..." << endl;
+      }
+      return;
+   }
+
+   //
+   // If the root node was the requested node, return it alone:
+   //
+   rel_xpath = rel_xpath.after(XPATH_DELIM);
+   if (rel_xpath.empty())
+   {
+      result.push_back(theRootNode);
+      return;
+   }
+   
+   //
+   // Pass the node request on to the root node with the relative path:
+   //
+   theRootNode->findChildNodes(rel_xpath, result);
+}
+
+ostream& operator << (ostream& os, const ossimXmlDocument& xml_doc) 
+{
+   os << xml_doc.theXmlHeader << endl;
+   if (xml_doc.theRootNode.valid())
+   {
+      os << (xml_doc.theRootNode.get()) << endl;
+   }
+//    else
+//       os << "-- no root node assigned -- " << endl;
+   
+   return os;
+}
+
+void ossimXmlDocument::initRoot(ossimRefPtr<ossimXmlNode> node)
+{
+   theRootNode = node;
+}
+
+ossimRefPtr<ossimXmlNode> ossimXmlDocument::getRoot()
+{
+   return theRootNode;
+}
+
+const ossimRefPtr<ossimXmlNode> ossimXmlDocument::getRoot()const
+{
+   return theRootNode;
+}
+
+ossimRefPtr<ossimXmlNode> ossimXmlDocument::removeRoot()
+{
+   ossimRefPtr<ossimXmlNode> root = theRootNode;
+
+   theRootNode = 0;
+
+   return root;
+}
+
+
+void ossimXmlDocument::fromKwl(const ossimKeywordlist& kwlToConvert)
+{
+
+   ossimKeywordlist kwl = kwlToConvert;
+   theRootNode = 0;
+   theRootNode = new ossimXmlNode;
+
+   
+   ossimString prefix = "";
+   ossimKeywordlist::KeywordMap& map              = kwl.getMap();
+   ossimKeywordlist::KeywordMap::iterator mapIter = map.begin();
+
+   while(mapIter != map.end())
+   {
+      ossimString key = mapIter->first;
+      key = key.substitute(".", "/", true);
+      theRootNode->addNode(key, mapIter->second);
+      ++mapIter;
+   }
+
+   // now collapse all keywordlist styles to the XML style
+   //
+   std::stack<ossimRefPtr<ossimXmlNode> > tempStack;
+   tempStack.push(theRootNode);
+   while(!tempStack.empty())
+   {
+      
+      ossimRefPtr<ossimXmlNode> node = tempStack.top();
+      tempStack.pop();
+      vector<ossimRefPtr<ossimXmlNode> >& childNodes = node->getChildNodes();
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < childNodes.size(); ++idx)
+      {
+         tempStack.push(childNodes[idx]);
+      }
+      if(node->getChildNodes().size() > 0)
+      {
+         if(node->getTag()!="")
+         {
+            node->addAttribute("name", node->getTag());
+         }
+         node->setTag("object");
+      }
+      
+      if(node->getTag() == "type")
+      {
+         if(node->getParentNode())
+         {
+            node->getParentNode()->removeChild("type");
+            node->getParentNode()->addAttribute("type", node->getText());
+         }
+      }
+      else if(node->getChildNodes().size() < 1)
+      {
+         if(node->getTag()!="")
+         {
+            node->addAttribute("name", node->getTag());
+         }
+         if(!node->getText().contains("\n"))
+         {
+            if(node->getText()!="")
+            {
+               node->addAttribute("value", node->getText());
+               node->setText("");
+            }
+         }
+         node->setTag("property");
+      }
+   }
+}
+
+void ossimXmlDocument::toKwl(ossimKeywordlist& kwl ,
+                             const ossimString& prefix)const
+{
+   
+//    const std::vector<ossimRefPtr<ossimXmlNode> >& children = theRootNode->getChildNodes();
+   
+//    ossim_uint32 idx = 0;
+   
+//    for(idx = 0; idx < children.size(); ++idx)
+//    {
+//       children[idx]->toKwl(kwl, prefix);
+//    }
+   theRootNode->toKwl(kwl, prefix);
+}
+
+bool ossimXmlDocument::readHeader(std::istream& in)
+{
+   char c;
+   in>>xmlskipws;
+
+   while(in.peek() == '<')
+   {
+      in.ignore(1);
+      c = in.peek();
+      if((c == '?')||
+         (c == '!'))
+      {
+         theXmlHeader += "<";
+         theXmlHeader += (char)in.get();
+         
+         while((in.peek() != '>')&&
+               (!in.bad()))
+         {
+            theXmlHeader += (char)in.get();
+         }
+         if(!in.bad())
+         {
+            theXmlHeader += (char)in.get();
+         }
+         in>>xmlskipws;
+      }
+   }
+
+   return (!in.bad());
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlDocument.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlDocument.h
new file mode 100644
index 0000000000..3ea409963f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlDocument.h
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Oscar Kramer <okramer@imagelinks.com> (ossim port by D. Burken)
+//
+// Description:  
+//
+// Contains declaration of class ossimXmlDocument. This class provides read-only
+// parsing and accessing of an XML document file.
+// 
+//*****************************************************************************
+// $Id: ossimXmlDocument.h,v 1.4 2005/06/17 13:35:57 gpotts Exp $
+#ifndef ossimXmlDocument_HEADER
+#define ossimXmlDocument_HEADER
+
+#include <vector>
+#include <base/common/ossimObject.h>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/common/ossimRefPtr.h>
+#include "ossimFilename.h"
+
+class ossimXmlNode;
+
+class OSSIMDLLEXPORT ossimXmlDocument : public ossimObject,
+                                     public ossimErrorStatusInterface
+{
+public:
+   ossimXmlDocument(const ossimFilename& xmlFileName="");
+   ~ossimXmlDocument();
+
+   bool write(const ossimFilename& file);
+   bool openFile(const ossimFilename& filename);
+   bool read(std::istream& in);
+   /**
+    * Appends any matching nodes to the list supplied (should be empty):
+    */
+   void findNodes(const ossimString& xpath,
+                  std::vector<ossimRefPtr<ossimXmlNode> >& nodelist) const;
+   
+   OSSIMDLLEXPORT friend std::ostream& operator << (std::ostream& os, const ossimXmlDocument& xml_doc);
+
+   void initRoot(ossimRefPtr<ossimXmlNode> node);
+
+   ossimRefPtr<ossimXmlNode> getRoot();
+   const ossimRefPtr<ossimXmlNode> getRoot()const;
+   ossimRefPtr<ossimXmlNode> removeRoot();
+   void fromKwl(const ossimKeywordlist& kwl);
+   void toKwl(ossimKeywordlist& kwl, const ossimString& prefix = "")const;
+   
+private:
+   ossimRefPtr<ossimXmlNode>  theRootNode;
+   ossimString                theXmlHeader;
+   ossimFilename              theFilename;
+
+   bool readHeader(std::istream& in);
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimXmlDocument_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlNode.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlNode.cpp
new file mode 100644
index 0000000000..c163acac95
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlNode.cpp
@@ -0,0 +1,840 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Oscar Kramer <okramer@imagelinks.com> (ossim port by D. Burken)
+//
+// Description:  
+//
+// Contains definition of class ossimXmlNode.
+// 
+//*****************************************************************************
+// $Id: ossimXmlNode.cpp,v 1.12 2005/06/07 17:43:37 gpotts Exp $
+
+#include <iostream>
+using namespace std;
+
+#include <base/data_types/ossimXmlNode.h>
+#include <base/data_types/ossimXmlAttribute.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/context/ossimNotifyContext.h>
+
+static const ossimString XPATH_DELIM ("/");
+
+RTTI_DEF2(ossimXmlNode, "ossimXmlNode", ossimObject, ossimErrorStatusInterface);
+
+static std::istream& xmlskipws(std::istream& in)
+{
+   int c = in.peek();
+   while((c == ' ') ||
+         (c == '\t') ||
+         (c == '\n'))
+   {
+      in.ignore(1);
+      c = in.peek();
+   }
+   
+   return in;
+}
+
+
+ossimXmlNode::ossimXmlNode(istream& xml_stream, ossimXmlNode* parent)
+   :
+   theParentNode (parent)
+{
+   read(xml_stream);
+}
+
+ossimXmlNode::ossimXmlNode()
+   :theParentNode(0)
+{
+}
+
+ossimXmlNode::~ossimXmlNode()
+{
+}
+
+void ossimXmlNode::setParent(ossimXmlNode* parent)
+{
+   theParentNode = parent;
+}
+
+bool ossimXmlNode::read(std::istream& in)
+{
+
+   in >> xmlskipws;
+   if(in.peek() == '<')
+   {
+      in.ignore(1);
+   }
+   streampos file_pos = in.tellg();
+   ossimString endTag;
+
+   
+   readTag(in, theTag);
+   char c = in.peek();
+
+   if(readEndTag(in, endTag))
+   {
+      if((endTag == "")||
+         (endTag == theTag))
+      {
+         return true;
+      }
+      else
+      {
+         setErrorStatus();
+         return false;
+      }
+   }
+   // now parse attributes
+   ossimRefPtr<ossimXmlAttribute> attribute = new ossimXmlAttribute;
+   while(attribute->read(in))
+   {
+      theAttributes.push_back(new ossimXmlAttribute(*attribute));
+   }
+   // skip white space characters
+   //
+   in >> xmlskipws;
+
+   c = in.peek();
+
+   if(readEndTag(in, endTag))
+   {
+      if((endTag == "")||
+         (endTag == theTag))
+      {
+         return true;
+      }
+      else
+      {
+         setErrorStatus();
+         return false;
+      }
+   }
+   c = in.peek();
+   // make sure the attribute is closed
+   //
+   if(c != '>')
+   {
+      setErrorStatus();
+      return false;
+   }
+
+   in.ignore(1);
+   c = in.peek();
+   // now do the text portion
+   //
+   theText = "";
+
+   readTextContent(in, theText);
+   in >> xmlskipws;
+   c = in.peek();
+
+   c = in.peek();
+
+   if(c != '<')
+   {
+      setErrorStatus();
+      return false;
+   }
+   in.ignore(1);
+   if(readEndTag(in, endTag))
+   {
+      if((endTag == "")||
+         (endTag == theTag))
+      {
+         return true;
+      }
+      else
+      {
+         setErrorStatus();
+         return false;
+      }
+   }
+   c = in.peek();
+   // now if it's not an endtag then it must be a tag starting the new child node
+   //
+   bool done = false;
+
+   ossimRefPtr<ossimXmlNode> childNode;
+   do
+   {
+      childNode = new ossimXmlNode;
+      childNode->setParent(this);
+      if(childNode->read(in))
+      {
+         theChildNodes.push_back(childNode);
+      }
+      else
+      {
+         setErrorStatus();
+         return false;
+      }
+      in >> xmlskipws;
+
+      c = in.peek();
+      if(c != '<')
+      {
+         setErrorStatus();
+         return false;
+      }
+      in.ignore(1);
+      if(readEndTag(in, endTag))
+      {
+         if((endTag == "")||
+            (endTag == theTag))
+         {
+            return true;
+         }
+         else
+         {
+            setErrorStatus();
+            return false;
+         }
+      }
+   }while((!done)&&(!in.bad()));
+
+   return true;
+}
+
+
+void ossimXmlNode::findChildNodes(const ossimString& xpath,
+                                  vector<ossimRefPtr<ossimXmlNode> >& result)const
+{
+   //***
+   // Scan for trivial result (no children owned):
+   //***
+   if (theChildNodes.size() == 0)
+      return;
+   
+   //***
+   // Make a copy to manipulate:
+   //***
+   ossimString rel_xpath (xpath);
+   if (rel_xpath.empty())
+      return;
+   
+   //***
+   // First verify that this is not an absolute path:
+   //***
+   if (rel_xpath[0] == XPATH_DELIM[0])
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING: ossimXmlNode::findChildNodes\n"
+                                         << "Only relative XPaths can be searched from a node. "
+                                         << "Returning null list...\n";
+      return;
+   }
+
+   //***
+   // Read the desired tag from the relative xpath
+   //***
+   ossimString desired_tag (rel_xpath);
+   if (rel_xpath.contains(XPATH_DELIM))
+      desired_tag = rel_xpath.before(XPATH_DELIM);
+   ossimString sub_xpath (rel_xpath.after(XPATH_DELIM));
+   
+   //***
+   // Loop over all child nodes for match:
+   //***
+   vector<ossimRefPtr<ossimXmlNode> >::const_iterator child_iter = theChildNodes.begin();
+   while(child_iter != theChildNodes.end())
+   {
+      if ((*child_iter)->getTag() == desired_tag)
+      {
+         if (sub_xpath.empty())
+         {
+            //***
+            // This was the final target node, simply append to the result:
+            //***
+            result.push_back(*child_iter);
+         }
+         else
+         {
+            //***
+            // This match identifies a possible tree to search given the
+            // remaining xpath (sub_xpath). Query this child node to search
+            // its tree for the remaining xpath:
+            //***
+            (*child_iter)->findChildNodes(sub_xpath, result);
+         }
+      }
+
+      //***
+      // Proceed to next child:
+      //***
+      child_iter++;
+   }
+}
+
+const ossimRefPtr<ossimXmlNode> ossimXmlNode::findFirstNode(const ossimString& xpath)const
+{
+   if(theChildNodes.size() < 1) return 0;
+   //
+   // Make a copy to manipulate:
+   //
+   ossimString rel_xpath (xpath);
+   if (rel_xpath.empty())
+      return 0;
+   
+   //
+   // First verify that this is not an absolute path:
+   //
+   if (rel_xpath[0] == XPATH_DELIM[0])
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING: ossimXmlNode::findChildNodes\n"
+                                         << "Only relative XPaths can be searched from a node. "
+                                         << "Returning null list...\n";
+      return 0;
+   }
+
+   //
+   // Read the desired tag from the relative xpath
+   //
+   ossimString desired_tag (rel_xpath);
+   if (rel_xpath.contains(XPATH_DELIM))
+      desired_tag = rel_xpath.before(XPATH_DELIM);
+   ossimString sub_xpath (rel_xpath.after(XPATH_DELIM));
+
+   ossimRefPtr<ossimXmlNode> result = 0;
+   
+   //
+   // Loop over all child nodes for match:
+   //
+   vector<ossimRefPtr<ossimXmlNode> >::const_iterator child_iter = theChildNodes.begin();
+   while((child_iter != theChildNodes.end())&&
+         (!result.valid()))
+   {
+      if ((*child_iter)->getTag() == desired_tag)
+      {
+         if (sub_xpath.empty())
+         {
+            return *child_iter;
+         }
+         else
+         {
+            //
+            // This match identifies a possible tree to search given the
+            // remaining xpath (sub_xpath). Query this child node to search
+            // its tree for the remaining xpath:
+            //
+            result = (*child_iter)->findFirstNode(sub_xpath);
+         }
+      }
+
+      //
+      // Proceed to next child:
+      //
+      ++child_iter;
+   }
+
+   return result;
+}
+
+ossimRefPtr<ossimXmlNode> ossimXmlNode::findFirstNode(const ossimString& xpath)
+{
+   if(theChildNodes.size() < 1) return 0;
+   //
+   // Make a copy to manipulate:
+   //
+   ossimString rel_xpath (xpath);
+   if (rel_xpath.empty())
+      return 0;
+   
+   //
+   // First verify that this is not an absolute path:
+   //
+   if (rel_xpath[0] == XPATH_DELIM[0])
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING: ossimXmlNode::findChildNodes\n"
+                                         << "Only relative XPaths can be searched from a node. "
+                                         << "Returning null list...\n";
+      return 0;
+   }
+
+   //
+   // Read the desired tag from the relative xpath
+   //
+   ossimString desired_tag (rel_xpath);
+   if (rel_xpath.contains(XPATH_DELIM))
+      desired_tag = rel_xpath.before(XPATH_DELIM);
+   ossimString sub_xpath (rel_xpath.after(XPATH_DELIM));
+
+   ossimRefPtr<ossimXmlNode> result = 0;
+   
+   //
+   // Loop over all child nodes for match:
+   //
+   vector<ossimRefPtr<ossimXmlNode> >::iterator child_iter = theChildNodes.begin();
+   while((child_iter != theChildNodes.end())&&
+         (!result.valid()))
+   {
+      if ((*child_iter)->getTag() == desired_tag)
+      {
+         if (sub_xpath.empty())
+         {
+            return *child_iter;
+         }
+         else
+         {
+            //
+            // This match identifies a possible tree to search given the
+            // remaining xpath (sub_xpath). Query this child node to search
+            // its tree for the remaining xpath:
+            //
+            result = (*child_iter)->findFirstNode(sub_xpath);
+         }
+      }
+
+      //
+      // Proceed to next child:
+      //
+      ++child_iter;
+   }
+
+   return result;
+}
+
+ossimRefPtr<ossimXmlAttribute> ossimXmlNode::findAttribute(const ossimString& name)
+{
+   ossim_uint32 idx = 0;
+   
+   for(idx = 0; idx < theAttributes.size();++idx)
+   {
+      if(theAttributes[idx]->getName() == name)
+      {
+         return theAttributes[idx];
+      }
+   }
+
+   return 0;
+}
+
+const ossimRefPtr<ossimXmlAttribute> ossimXmlNode::findAttribute(const ossimString& name)const
+{
+   ossim_uint32 idx = 0;
+   
+   for(idx = 0; idx < theAttributes.size();++idx)
+   {
+      if(theAttributes[idx]->getName() == name)
+      {
+         return theAttributes[idx];
+      }
+   }
+
+   return 0;
+}
+
+void ossimXmlNode::setTag(const ossimString& tag)
+{
+   theTag = tag;
+}
+
+ossimString ossimXmlNode::getTag() const
+{
+   return theTag;
+}
+
+const ossimXmlNode* ossimXmlNode::getParentNode() const
+{
+   return theParentNode;
+}
+
+ossimXmlNode* ossimXmlNode::getParentNode()
+{
+   return theParentNode;
+}
+
+const vector<ossimRefPtr<ossimXmlNode> >& ossimXmlNode::getChildNodes() const
+{
+   return theChildNodes;
+}
+
+vector<ossimRefPtr<ossimXmlNode> >& ossimXmlNode::getChildNodes()
+{
+   return theChildNodes;
+}
+
+const vector<ossimRefPtr<ossimXmlAttribute> >& ossimXmlNode::getAttributes() const
+{
+   return theAttributes;
+}
+
+void ossimXmlNode::setText(const ossimString& text)
+{
+   theText = text;
+}
+
+ossimString ossimXmlNode::getText() const
+{
+   return theText;
+}
+
+ostream& operator << (ostream& os, const ossimXmlNode& xml_node)
+{
+   return operator <<(os, &xml_node);
+}
+
+//**************************************************************************
+//  FRIEND OPERATOR
+//**************************************************************************
+ostream& operator << (ostream& os, const ossimXmlNode* xml_node) 
+{
+   //
+   // Determine the indentation level:
+   //
+   ossimString indent ("");
+   const ossimXmlNode* parent = xml_node->theParentNode;
+   while (parent)
+   {
+      indent += "   ";
+      parent = parent->theParentNode;
+   }
+   
+   //
+   // Dump the tag opening:
+   //
+   os << "\n" << indent << "<" << xml_node->theTag;
+
+   //
+   // Dump any attributes:
+   //
+   if (xml_node->theAttributes.size())
+   {
+      vector<ossimRefPtr<ossimXmlAttribute> >::const_iterator attr =
+         xml_node->theAttributes.begin();
+      while (attr != xml_node->theAttributes.end())
+      {
+         os << attr->get();
+         attr++;
+      }
+   }
+
+   if((xml_node->theChildNodes.size() == 0)&&
+      (xml_node->theText == ""))
+   {
+      os << "/>";
+   }
+   else
+   {
+      os << ">";
+      
+      //
+      // Dump any text:
+      //
+      os << xml_node->theText;
+      
+      //
+      // Dump any child nodes:
+      //
+      if (xml_node->theChildNodes.size())
+      {
+         vector<ossimRefPtr<ossimXmlNode> >::const_iterator nodes = xml_node->theChildNodes.begin();
+         while (nodes != xml_node->theChildNodes.end())
+         {
+            os << (*nodes).get();
+            nodes++;
+         }
+         os << "\n" << indent;
+      }
+   
+      //
+      // Dump the tag closing:
+      // 
+      os << "</" << xml_node->theTag << ">";
+   }
+
+   return os;
+}
+
+void ossimXmlNode::addAttribute(ossimRefPtr<ossimXmlAttribute> attribute)
+{
+   theAttributes.push_back(attribute);
+}
+
+void ossimXmlNode::addAttribute(const ossimString& name,
+                                const ossimString& value)
+{
+   theAttributes.push_back(new ossimXmlAttribute(name, value));
+}
+
+ossimRefPtr<ossimXmlNode> ossimXmlNode::addNode(const ossimString& relPath,
+                                                const ossimString& text)
+{
+   //
+   // Make a copy to manipulate:
+   //
+   ossimString relXpath (relPath);
+   if (relXpath.empty())
+      return 0;
+   
+   //
+   // First verify that this is not an absolute path:
+   //
+   if (relXpath[0] == XPATH_DELIM[0])
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING: ossimXmlNode::findChildNodes\n"
+                                         << "Only relative XPaths can be searched from a node. "
+                                         << "Returning null list...\n";
+      return 0;
+   }
+
+   //
+   // Read the desired tag from the relative xpath
+   //
+   ossimString desiredTag (relXpath);
+   if (relXpath.contains(XPATH_DELIM))
+   {
+      desiredTag = relXpath.before(XPATH_DELIM);
+   }
+   ossimString subPath (relXpath.after(XPATH_DELIM));
+   
+   ossimRefPtr<ossimXmlNode> node = findFirstNode(desiredTag);
+
+   if(!node.valid())
+   {
+      if(subPath.empty())
+      {
+         node = addChildNode(desiredTag, text);
+      }
+      else
+      {
+         node = addChildNode(desiredTag, "");
+      }
+   }
+   if(!subPath.empty())
+   {
+      return node->addNode(subPath, text);
+   }
+
+   return node;
+}
+
+ossimRefPtr<ossimXmlNode> ossimXmlNode::addOrSetNode(const ossimString& relPath,
+                                                     const ossimString& text)
+{
+
+   ossimRefPtr<ossimXmlNode> result = addNode(relPath, text);
+
+   result->setText(text);
+
+   return result;
+}
+
+void ossimXmlNode::addChildNode(ossimRefPtr<ossimXmlNode> node)
+{
+   if(node->theParentNode)
+   {
+      node->theParentNode->removeChild(node);
+   }
+   node->theParentNode = this;
+   theChildNodes.push_back(node);
+}
+
+ossimRefPtr<ossimXmlNode> ossimXmlNode::addChildNode(const ossimString& tagName,
+                                                     const ossimString& text)
+{
+   ossimRefPtr<ossimXmlNode> node = new ossimXmlNode();
+   node->setParent(this);
+   node->theTag = tagName;
+   node->theText = text;
+   theChildNodes.push_back(node);
+
+   return node;
+}
+
+ossimRefPtr<ossimXmlNode> ossimXmlNode::removeChild(ossimRefPtr<ossimXmlNode> node)
+{
+   vector<ossimRefPtr<ossimXmlNode> >::iterator iter = theChildNodes.begin();
+   while(iter != theChildNodes.end())
+   {
+      
+      if(node.get() == iter->get())
+      {
+         ossimRefPtr<ossimXmlNode> temp = *iter;
+
+         theChildNodes.erase(iter);
+
+         return temp;
+      }
+      ++iter;
+   }
+   
+   return 0;
+}
+
+ossimRefPtr<ossimXmlNode> ossimXmlNode::removeChild(const ossimString& tag)
+{
+   vector<ossimRefPtr<ossimXmlNode> >::iterator iter = theChildNodes.begin();
+   while(iter != theChildNodes.end())
+   {
+      if(tag == iter->get()->theTag)
+      {
+         ossimRefPtr<ossimXmlNode> temp = *iter;
+
+         theChildNodes.erase(iter);
+
+         return temp;
+      }
+      ++iter;
+   }
+   
+   return 0;
+}
+
+void ossimXmlNode::toKwl(ossimKeywordlist& kwl,
+                         const ossimString& prefix)const
+{
+   ossimRefPtr<ossimXmlAttribute> nameAtt  = findAttribute("name");
+   ossimRefPtr<ossimXmlAttribute> valueAtt = findAttribute("value");
+   ossimRefPtr<ossimXmlAttribute> typeAtt  = findAttribute("type");
+
+   ossimString name;
+   ossimString value;
+   ossimString type;
+   if(nameAtt.valid())
+   {
+      name = nameAtt->getValue();
+   }
+   if(valueAtt.valid())
+   {
+      value = valueAtt->getValue();
+   }
+   else
+   {
+      value = theText;
+   }
+   
+   if(typeAtt.valid())
+   {
+      type = typeAtt->getValue();
+   }
+   ossimString copyPrefix = prefix;
+
+   if(name != "")
+   {
+      copyPrefix += (name+".");
+   }
+   if(type!= "")
+   {
+      kwl.add(copyPrefix,
+              "type",
+              typeAtt->getValue(),
+              true);
+   }
+   
+   if(theChildNodes.size() < 1)
+   {
+      kwl.add(prefix+name,
+              value,
+              true);
+   }
+   else
+   {
+      ossim_uint32 idx=0;
+
+      for(idx = 0; idx < theChildNodes.size();++idx)
+      {
+         theChildNodes[idx]->toKwl(kwl,
+                                   copyPrefix);
+      }
+   }
+}
+
+bool ossimXmlNode::readTag(std::istream& in,
+                           ossimString& tag)
+{
+   in >> xmlskipws;
+
+   tag = "";
+   int c = in.peek();
+   
+   while( (c != ' ')&&
+          (c != '\n')&&
+          (c != '\t')&&
+          (c != '<')&&
+          (c != '>')&&
+          (c != '/')&&
+          (!in.bad()))
+   {
+      tag += (char)c;
+      in.ignore(1);
+      c = in.peek();
+   }
+
+   return ((tag != "")&&(!in.bad()));
+}
+
+bool ossimXmlNode::readTextContent(std::istream& in,
+                                   ossimString& text)
+{
+   in >> xmlskipws;
+
+   text = "";
+   char c = in.peek();
+   bool done = false;
+
+   do
+   {
+      if(c == '<')
+      {
+         done = true;
+      }
+      else
+      {
+         text += (char)in.get();
+         c = in.peek();
+      }
+   }while((!in.bad())&&
+          (!done));
+
+   return (text != "");
+}
+
+bool ossimXmlNode::readEndTag(std::istream& in,
+                              ossimString& endTag)
+{
+   bool result = false;
+   char c = in.peek();
+   endTag = "";
+
+   // check end tag
+   //
+   if(c == '/')
+   {
+      in.ignore();
+      readTag(in, endTag);
+      in >> xmlskipws;
+      c = in.peek();
+      result = true;
+   }
+   else
+   {
+      return false;
+   }
+   if(c != '>')
+   {
+      setErrorStatus();
+      return false;
+   }
+   else
+   {
+      in.ignore(1);
+   }
+   
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlNode.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlNode.h
new file mode 100644
index 0000000000..a37e04c688
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlNode.h
@@ -0,0 +1,103 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Oscar Kramer <okramer@imagelinks.com> (ossim port by D. Burken)
+//
+// Description:  
+//
+// Contains declaration of class ossimXmlNode.
+// 
+//*****************************************************************************
+// $Id: ossimXmlNode.h,v 1.9 2005/06/17 13:35:57 gpotts Exp $
+#ifndef ossimXmlNode_HEADER
+#define ossimXmlNode_HEADER
+
+#include <vector>
+using namespace std;
+
+#include "base/common/ossimObject.h"
+#include "base/common/ossimRefPtr.h"
+#include "base/common/ossimErrorStatusInterface.h"
+#include "ossimXmlAttribute.h"
+#include "ossimString.h"
+
+
+class OSSIMDLLEXPORT ossimXmlNode : public ossimObject,
+                                    public ossimErrorStatusInterface
+{
+public:
+   ossimXmlNode(istream& xml_stream, ossimXmlNode* parent=0);
+   ossimXmlNode();
+
+   bool read(std::istream& in);
+   // Appends any matching nodes to the list supplied
+   void findChildNodes(const ossimString& rel_xpath,
+                       vector<ossimRefPtr<ossimXmlNode> >& nodelist)const;
+   const ossimRefPtr<ossimXmlNode> findFirstNode(const ossimString& rel_xpath)const;
+   ossimRefPtr<ossimXmlNode> findFirstNode(const ossimString& rel_xpath);
+
+   ossimRefPtr<ossimXmlAttribute> findAttribute(const ossimString& name);
+   const ossimRefPtr<ossimXmlAttribute> findAttribute(const ossimString& name)const;
+   void setTag(const ossimString& tag);
+   ossimString                      getTag()        const;
+   const ossimXmlNode*              getParentNode() const;
+   ossimXmlNode*              getParentNode();
+   void setParent(ossimXmlNode* parent);
+   const vector<ossimRefPtr<ossimXmlNode> >&      getChildNodes() const;
+   vector<ossimRefPtr<ossimXmlNode> >&      getChildNodes();
+   const vector<ossimRefPtr<ossimXmlAttribute> >& getAttributes() const;
+   void addAttribute(ossimRefPtr<ossimXmlAttribute> attribute);
+   void addAttribute(const ossimString& name, const ossimString& value);
+   ossimRefPtr<ossimXmlNode> addNode(const ossimString& relPath,
+                                     const ossimString& text = "");
+   ossimRefPtr<ossimXmlNode> addOrSetNode(const ossimString& relPath,
+                                          const ossimString& text = "");
+   void addChildNode(ossimRefPtr<ossimXmlNode> node);
+   ossimRefPtr<ossimXmlNode> addChildNode(const ossimString& tagName,
+                                          const ossimString& text="");
+   void setText(const ossimString& text);
+   ossimString                      getText()       const;
+
+   OSSIMDLLEXPORT friend ostream& operator << (ostream& os, const ossimXmlNode* xml_node);
+   OSSIMDLLEXPORT friend ostream& operator << (ostream& os, const ossimXmlNode& xml_node);
+
+   ossimRefPtr<ossimXmlNode> removeChild(ossimRefPtr<ossimXmlNode> node);
+   ossimRefPtr<ossimXmlNode> removeChild(const ossimString& tag);
+
+   void toKwl(ossimKeywordlist& kwl,
+              const ossimString& prefix="")const;
+   void fromKwl(const ossimKeywordlist& kwlToConvert);
+  
+protected:
+   ~ossimXmlNode();
+   ossimString                 theTag;
+   ossimXmlNode*         theParentNode;
+   vector<ossimRefPtr<ossimXmlNode> >      theChildNodes;
+   vector<ossimRefPtr<ossimXmlAttribute> >  theAttributes;
+   ossimString                 theText;
+
+   bool readTag(std::istream& in,
+                ossimString& tag);
+   bool readTextContent(std::istream& in,
+                        ossimString& text);
+   bool readEndTag(std::istream& in,
+                   ossimString& endTag);
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimXmlNode_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlString.cpp b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlString.cpp
new file mode 100644
index 0000000000..4f904c38b2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlString.cpp
@@ -0,0 +1,72 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public License 
+// as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU Library General Public License
+// along with this library. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@remotesensing.org)
+// Description: This class provides manipulation of filenames.
+//
+//*************************************************************************
+// $Id: ossimXmlString.cpp,v 1.1 2002/06/12 20:39:30 gpotts Exp $
+#include "ossimXmlString.h"
+
+const ossimXmlString& ossimXmlString::assign(const ossimString& s)
+{
+   ossimString result = s;
+   
+   size_type pos = 0;
+
+   pos = result.find("&");
+   // do ampersand first
+   //
+   while(pos != npos)
+   {
+      ossimString s1(result.begin() + pos,
+                     result.begin()+pos+5);
+      ossimString s2(result.begin() + pos,
+                     result.begin()+pos+4);
+      ossimString s3(result.begin() + pos,
+                     result.begin()+pos+3);
+      
+      if((s2 != "&amp")&&
+         (s1 != "&quot")&&
+         (s3 != "&gt")&&
+         (s3 != "&lt")&&
+         (s1 != "&apos"))
+      {
+         result.replace(pos, 1, "&amp");
+      }
+      
+      pos = result.find("&", pos+4);
+   }
+
+   result = result.substitute("\"",
+                              "&quot",
+                              true);
+   result = result.substitute("<",
+                              "&lt",
+                              true);
+   result = result.substitute(">",
+                              "&gt",
+                              true);
+   result = result.substitute("'",
+                              "&apos",
+                              true);
+                     
+   *((ossimString*)this) = result;
+
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlString.h b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlString.h
new file mode 100644
index 0000000000..e37bedbbde
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/data_types/ossimXmlString.h
@@ -0,0 +1,79 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public License 
+// as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU Library General Public License
+// along with this library. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@remotesensing.org)
+// Description: This class provides manipulation of filenames.
+//
+//*************************************************************************
+// $Id: ossimXmlString.h,v 1.3 2005/10/17 18:37:16 gpotts Exp $
+
+#ifndef ossimXmlString_HEADER
+#define ossimXmlString_HEADER
+
+#include "base/common/ossimConstants.h"
+#include "ossimString.h"
+
+class OSSIM_DLL ossimXmlString : public ossimString
+{
+public:
+   ossimXmlString()
+      :
+         ossimString()
+      {}
+   ossimXmlString(const ossimXmlString& src)
+      :
+         ossimString(src)
+      {}
+   ossimXmlString(const ossimString& src)
+      :
+         ossimString("")
+      {
+         assign(src);
+
+      }
+   ossimXmlString(const char* src)
+      :
+         ossimString("")
+      {
+         assign(src);
+      }
+   
+   template <class Iter>
+   ossimXmlString(Iter s, Iter e)
+      :ossimString("")
+      {
+         assign(ossimString(s, e));
+      }
+
+   const ossimXmlString& operator =(const char* s)
+      {
+         return assign(ossimString(s));
+      }
+   	  const ossimXmlString& operator =(const ossimString& s)
+      {
+         return assign(ossimString(s));
+      }
+	  const ossimXmlString& operator =(const std::string& s)
+      {
+         return assign(ossimString(s));
+      }
+
+   const ossimXmlString& assign(const ossimString& s);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/.cvsignore b/Utilities/OSSIM/ossim_core/base/factory/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimBaseObjectFactory.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimBaseObjectFactory.cpp
new file mode 100644
index 0000000000..f1b2d11a0b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimBaseObjectFactory.cpp
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimBaseObjectFactory.cpp,v 1.2 2002/03/26 19:05:22 gpotts Exp $
+#include "base/factory/ossimBaseObjectFactory.h"
+#include "base/common/ossimConnectableContainer.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+RTTI_DEF1(ossimBaseObjectFactory, "ossimBaseObjectFactory", ossimObjectFactory);
+
+ossimBaseObjectFactory* ossimBaseObjectFactory::theInstance = NULL;
+
+ossimBaseObjectFactory* ossimBaseObjectFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimBaseObjectFactory;
+   }
+
+   return theInstance;
+}
+
+ossimObject* ossimBaseObjectFactory::createObject(const ossimString& typeName)const
+{
+   if(typeName == STATIC_TYPE_NAME(ossimConnectableContainer))
+   {
+      return new ossimConnectableContainer;
+   }
+
+   return (ossimObject*)NULL;
+}
+
+ossimObject* ossimBaseObjectFactory::createObject(const ossimKeywordlist& kwl,
+                                                  const char* prefix)const
+{
+   const char* type = kwl.find(prefix,
+                               ossimKeywordNames::TYPE_KW);
+   ossimString copyPrefix = prefix;
+   if(type)
+   {
+      ossimObject* object = createObject(ossimString(type));
+      if(object)
+      {
+         object->loadState(kwl, copyPrefix.c_str());
+      }
+      return object;
+   }
+   return NULL;  
+}
+
+void ossimBaseObjectFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   typeList.push_back(STATIC_TYPE_NAME(ossimConnectableContainer));
+}
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimBaseObjectFactory.h b/Utilities/OSSIM/ossim_core/base/factory/ossimBaseObjectFactory.h
new file mode 100644
index 0000000000..a7bd7405b0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimBaseObjectFactory.h
@@ -0,0 +1,49 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimBaseObjectFactory.h,v 1.5 2002/11/25 19:16:28 gpotts Exp $
+#ifndef ossimBaseObjectFactory_HEADER
+#define ossimBaseObjectFactory_HEADER
+#include "base/factory/ossimObjectFactory.h"
+
+class OSSIMDLLEXPORT ossimBaseObjectFactory : public ossimObjectFactory
+{
+public:
+   virtual ~ossimBaseObjectFactory(){theInstance = NULL;}
+   
+   static ossimBaseObjectFactory* instance();
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+protected:
+   static ossimBaseObjectFactory* theInstance;
+   
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowFactoryBase.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowFactoryBase.cpp
new file mode 100644
index 0000000000..e17f18a8da
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowFactoryBase.cpp
@@ -0,0 +1,25 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimCustomEditorWindowFactoryBase.cpp,v 1.2 2002/04/02 13:06:53 gpotts Exp $
+#include "base/factory/ossimCustomEditorWindowFactoryBase.h"
+RTTI_DEF1(ossimCustomEditorWindowFactoryBase, "ossimCustomEditorWindowFactoryBase", ossimObjectFactory);
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowFactoryBase.h b/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowFactoryBase.h
new file mode 100644
index 0000000000..3a2f865e97
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowFactoryBase.h
@@ -0,0 +1,52 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimCustomEditorWindowFactoryBase.h,v 1.7 2003/02/07 13:54:55 gpotts Exp $
+#ifndef ossimCustomEditorWindowFactoryBase_HEADER
+#define ossimCustomEditorWindowFactoryBase_HEADER
+#include "base/factory/ossimObjectFactory.h"
+
+class OSSIMDLLEXPORT ossimCustomEditorWindow;
+
+class OSSIMDLLEXPORT ossimCustomEditorWindowFactoryBase : public ossimObjectFactory
+{
+public:
+   virtual ossimCustomEditorWindow* createCustomEditor(ossimObject* obj,
+                                                       void* parent=NULL)const=0;
+   virtual ossimCustomEditorWindow* createCustomEditor(const ossimString& classType,
+                                                       void* parent=NULL)const=0;
+
+   /*!
+    * Returns a native GUI Editor with popup
+    */
+   virtual void* createPopupEditor(ossimObject* obj,
+                                   void* parent=NULL)const=0;
+   
+   /*!
+    * Returns a native GUI child window without a popup.
+    */
+   virtual void* createPanelEditor(ossimObject* obj,
+                                   void* parent=NULL)const=0;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowRegistry.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowRegistry.cpp
new file mode 100644
index 0000000000..10a91b1e3a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowRegistry.cpp
@@ -0,0 +1,168 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimCustomEditorWindowRegistry.cpp,v 1.8 2005/10/17 18:37:16 gpotts Exp $
+#include "ossimCustomEditorWindowRegistry.h"
+#include "base/factory/ossimCustomEditorWindowFactoryBase.h"
+ossimCustomEditorWindowRegistry* ossimCustomEditorWindowRegistry::theInstance=0;
+
+RTTI_DEF(ossimCustomEditorWindowRegistry, "ossimCustomEditorWindowRegistry");
+
+ossimCustomEditorWindowRegistry::~ossimCustomEditorWindowRegistry()
+{
+   theInstance = NULL;
+}
+
+ossimCustomEditorWindowRegistry* ossimCustomEditorWindowRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimCustomEditorWindowRegistry;
+   }
+
+   return theInstance;
+}
+
+bool ossimCustomEditorWindowRegistry::registerFactory(ossimCustomEditorWindowFactoryBase* factory)
+{
+   bool result = false;
+   if(factory)
+   {
+      theFactoryList.push_back(factory);
+      result = true;
+   }
+
+   return result;
+}
+
+ossimCustomEditorWindow* ossimCustomEditorWindowRegistry::createCustomEditor(ossimObject* obj,
+                                                                             void* parent)const
+{
+   ossimCustomEditorWindow* result = NULL;
+   int i = 0;
+
+   for(i = 0; (i < (int)theFactoryList.size())&&(!result); ++i)
+   {
+      result = theFactoryList[i]->createCustomEditor(obj, parent);
+   }
+
+   return result;
+}
+ossimCustomEditorWindow* ossimCustomEditorWindowRegistry::createCustomEditor(const ossimString& classType,
+                                                                             void* parent)const
+{
+   ossimCustomEditorWindow* result = NULL;
+   int i = 0;
+
+   for(i = 0; (i < (int)theFactoryList.size())&&(!result); ++i)
+   {
+      result = theFactoryList[i]->createCustomEditor(classType, parent);
+   }
+
+   return result;
+}
+
+ossimObject* ossimCustomEditorWindowRegistry::createObject(const ossimString& typeName)const
+{
+   ossimObject* result = NULL;
+   unsigned long index = 0;
+   
+   while((index < theFactoryList.size()) &&(!result))
+   {
+      result = theFactoryList[index]->createObject(typeName);
+      ++index;
+   }
+   return result;
+}
+
+ossimObject* ossimCustomEditorWindowRegistry::createObject(const ossimKeywordlist& kwl,
+                                                           const char* prefix)const
+{
+   ossimObject* result = NULL;
+   unsigned long index = 0;
+
+   while((index < theFactoryList.size()) &&(!result))
+   {
+      result = theFactoryList[index]->createObject(kwl,
+                                                   prefix);
+      ++index;
+   }
+
+   return result;
+}
+
+void* ossimCustomEditorWindowRegistry::createPopupEditor(ossimObject* obj,
+                                                         void* parent)const
+{
+   void* result = NULL;
+   unsigned long index = 0;
+
+   while((index < theFactoryList.size()) &&(!result))
+   {
+      result = theFactoryList[index]->createPopupEditor(obj,
+                                                        parent);
+      ++index;
+   }
+
+   return result;
+}
+   
+void* ossimCustomEditorWindowRegistry::createPanelEditor(ossimObject* obj,
+                                                         void* parent)const
+{
+   void* result = NULL;
+   unsigned long index = 0;
+
+   while((index < theFactoryList.size()) &&(!result))
+   {
+      result = theFactoryList[index]->createPanelEditor(obj,
+                                                        parent);
+      ++index;
+   }
+
+   return result;
+}
+
+void ossimCustomEditorWindowRegistry::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   std::vector<ossimCustomEditorWindowFactoryBase*>::const_iterator iter = theFactoryList.begin();
+   std::vector<ossimString> result;
+   
+   while(iter != theFactoryList.end())
+   {
+      result.clear();
+      (*iter)->getTypeNameList(result);
+
+      typeList.insert(typeList.end(),
+                      result.begin(),
+                      result.end());
+      ++iter;
+   }
+}
+
+extern "C"
+{
+  void* ossimCustomEditorWindowRegistryGetInstance()
+  {
+    return ossimCustomEditorWindowRegistry::instance();
+  }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowRegistry.h b/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowRegistry.h
new file mode 100644
index 0000000000..e1f74f6290
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimCustomEditorWindowRegistry.h
@@ -0,0 +1,78 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimCustomEditorWindowRegistry.h,v 1.8 2003/04/09 15:48:46 gpotts Exp $
+#ifndef ossimCustomEditorWindowRegistry_HEADER
+#define ossimCustomEditorWindowRegistry_HEADER
+#include "base/common/ossimObject.h"
+#include "base/common/ossimCustomEditorWindow.h"
+#include "base/factory/ossimCustomEditorWindowFactoryBase.h"
+
+#include <vector>
+class OSSIMDLLEXPORT ossimCustomEditorWindowFactoryBase;
+
+class OSSIMDLLEXPORT ossimCustomEditorWindowRegistry : public ossimCustomEditorWindowFactoryBase
+{
+public:
+   virtual ~ossimCustomEditorWindowRegistry();
+   static ossimCustomEditorWindowRegistry* instance();
+   bool registerFactory(ossimCustomEditorWindowFactoryBase* factory);
+
+   virtual ossimCustomEditorWindow* createCustomEditor(ossimObject* obj,
+                                                       void* parent=NULL)const;
+   virtual ossimCustomEditorWindow* createCustomEditor(const ossimString& classType,
+                                                       void* parent=NULL)const;
+
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   /*!
+    * Returns a native GUI Editor with popup
+    */
+   virtual void* createPopupEditor(ossimObject* obj,
+                                   void* parent=NULL)const;
+   
+   /*!
+    * Returns a native GUI child window without a popup.
+    */
+   virtual void* createPanelEditor(ossimObject* obj,
+                                   void* parent=NULL)const;
+   
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+protected:
+   ossimCustomEditorWindowRegistry(){}
+   ossimCustomEditorWindowRegistry(const ossimCustomEditorWindowRegistry&){}
+   void operator =(const ossimCustomEditorWindowRegistry& rhs){}
+   
+   std::vector<ossimCustomEditorWindowFactoryBase*> theFactoryList;
+   
+   static ossimCustomEditorWindowRegistry*                 theInstance;
+
+TYPE_DATA
+};
+
+extern "C"
+{
+  OSSIMDLLEXPORT void* ossimCustomEditorWindowRegistryGetInstance();
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.cpp
new file mode 100644
index 0000000000..d1c5d01192
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.cpp
@@ -0,0 +1,340 @@
+
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// This holds the class definition of DatumFactory.
+//*******************************************************************
+//  $Id: ossimDatumFactory.cpp,v 1.8 2004/05/14 13:45:56 gpotts Exp $
+
+#include "ossimDatumFactory.h"
+#include "ossimEllipsoidFactory.h"
+#include "base/data_types/datum/ossimDatum.h"
+#include "base/data_types/datum/ossimThreeParamDatum.h"
+#include "base/data_types/datum/ossimSevenParamDatum.h"
+#include "base/data_types/datum/ossimWgs84Datum.h"
+#include "base/data_types/datum/ossimWgs72Datum.h"
+#include "base/data_types/datum/ossimNadconNarDatum.h"
+#include "base/data_types/datum/ossimNadconNasDatum.h"
+#include "base/common/ossimPreferences.h"
+#include <base/factory/ossimDatumFactory.inc>
+
+ossimDatumFactory* ossimDatumFactory::theInstance = 0;
+map<ossimString, ossimDatum*> ossimDatumFactory::theDatumTable;
+
+ossimDatumFactory::~ossimDatumFactory()
+{
+   deleteAll();
+   theInstance = 0;
+}
+
+
+ossimDatumFactory* ossimDatumFactory::instance()
+{
+   if(!theInstance) 
+   {
+      theInstance = new ossimDatumFactory;
+
+      // datum depends on the creation of an ellipsoid factory
+      // so make sure an instance exists
+      ossimEllipsoidFactory::instance();
+      theInstance->initializeDefaults();
+      theInstance->theWgs84Datum = theInstance->create("WGE");
+      theInstance->theWgs72Datum = theInstance->create("WGD");
+   }  
+   return theInstance; 
+} 
+
+
+void ossimDatumFactory::writeCStructure(const ossimFilename& file)
+{
+#if 0
+   std::ofstream out(file.c_str());
+
+   if(!out) return;
+   
+   out << "typedef struct ossimSevenParamDatumType" << std::endl
+       << "{" << std::endl
+       << "   ossimString theCode;\n"
+       << "   ossimString theName;\n"
+       << "   ossimString theEllipsoidCode;\n"
+       << "   ossim_float64 theSigmaX;\n"
+       << "   ossim_float64 theSigmaY;\n"
+       << "   ossim_float64 theSigmaZ;\n"
+       << "   ossim_float64 theWestLongitude;\n"
+       << "   ossim_float64 theEastLongitude;\n"
+       << "   ossim_float64 theSouthLatitude;\n"
+       << "   ossim_float64 theNorthLatitude;\n"
+       << "   ossim_float64 theParam1;\n"
+       << "   ossim_float64 theParam2;\n"
+       << "   ossim_float64 theParam3;\n"
+       << "   ossim_float64 theParam4;\n"
+       << "   ossim_float64 theParam5;\n"
+       << "   ossim_float64 theParam6;\n"
+       << "   ossim_float64 theParam7;\n"
+       << "};\n";
+
+   out << "typedef struct ossimThreeParamDatumType" << std::endl
+       << "{" << std::endl
+       << "   ossimString theCode;\n"
+       << "   ossimString theName;\n"
+       << "   ossimString theEllipsoidCode;\n"
+       << "   ossim_float64 theSigmaX;\n"
+       << "   ossim_float64 theSigmaY;\n"
+       << "   ossim_float64 theSigmaZ;\n"
+       << "   ossim_float64 theWestLongitude;\n"
+       << "   ossim_float64 theEastLongitude;\n"
+       << "   ossim_float64 theSouthLatitude;\n"
+       << "   ossim_float64 theNorthLatitude;\n"
+       << "   ossim_float64 theParam1;\n"
+       << "   ossim_float64 theParam2;\n"
+       << "   ossim_float64 theParam3;\n"
+       << "};\n";
+   out << "#define NUMBER_OF_SEVEN_PARAM_DATUMS " << 2 << std::endl;
+   if(out)
+   {
+      map<ossimString, ossimDatum*>::iterator datum;
+      out << "static ossimThreeParamDatumType threeParamDatum[] = {\n";
+      datum = theDatumTable.begin();
+      ossim_uint32 datumCount = 0;
+      while(datum != theDatumTable.end())
+      {
+         bool written = false;
+         if( ((*datum).first != "NAS") &&
+             ((*datum).first != "NAR")&&
+             ((*datum).first != "EUR-7")&&
+             ((*datum).first != "OGB-7"))
+         {
+            written = true;
+            const ossimDatum* d = (*datum).second;
+            
+            out << "{\"" << d->code() << "\", "
+                << "\"" << d->name() << "\", "
+                << "\"" << d->ellipsoid()->code() << "\", "
+                << d->sigmaX() << ", "
+                << d->sigmaY() << ", "
+                << d->sigmaZ() << ", "
+                << d->westLongitude()*DEG_PER_RAD << ", "
+                << d->eastLongitude()*DEG_PER_RAD << ", "
+                << d->southLatitude()*DEG_PER_RAD << ", "
+                << d->northLatitude()*DEG_PER_RAD << ", "
+                << d->param1() << ", " 
+                << d->param2() << ", " 
+                << d->param3() << "}";
+            ++datumCount;
+         }
+         ++datum;
+         if(datum != theDatumTable.end()&&written)
+         {
+            
+            out << "," << std::endl;
+         }
+         else if(datum == theDatumTable.end())
+         {
+            out << std::endl;
+         }
+      }
+      out << "};" << std::endl;
+
+      out << "#define NUMBER_OF_THREE_PARAM_DATUMS " << datumCount << std::endl;
+      out << "static ossimSevenParamDatumType sevenParamDatum[] = {\n";
+      const ossimDatum* d = create("EUR-7");
+      if(d)
+      {
+            out << "{\"" << d->code() << "\", "
+                << "\"" << d->name() << "\", "
+                << "\"" << d->ellipsoid()->code() << "\", "
+                << d->sigmaX() << ", "
+                << d->sigmaY() << ", "
+                << d->sigmaZ() << ", "
+                << d->westLongitude()*DEG_PER_RAD << ", "
+                << d->eastLongitude()*DEG_PER_RAD << ", "
+                << d->southLatitude()*DEG_PER_RAD << ", "
+                << d->northLatitude()*DEG_PER_RAD << ", "
+                << d->param1() << ", " 
+                << d->param2() << ", " 
+                << d->param3() << ", "
+                << d->param4() << ", "
+                << d->param5() << ", "
+                << d->param6() << ", "
+                << d->param7() << "},\n";
+      }
+      d = create("OGB-7");
+      if(d)
+      {
+         out << "{\"" << d->code() << "\", "
+             << "\"" << d->name() << "\", "
+             << "\"" << d->ellipsoid()->code() << "\", "
+             << d->sigmaX() << ", "
+             << d->sigmaY() << ", "
+             << d->sigmaZ() << ", "
+             << d->westLongitude()*DEG_PER_RAD << ", "
+             << d->eastLongitude()*DEG_PER_RAD << ", "
+             << d->southLatitude()*DEG_PER_RAD << ", "
+             << d->northLatitude()*DEG_PER_RAD << ", "
+             << d->param1() << ", " 
+             << d->param2() << ", " 
+             << d->param3() << ", "
+             << d->param4() << ", "
+             << d->param5() << ", "
+             << d->param6() << ", "
+             << d->param7() << "}\n";
+      }
+      out << "};" << std::endl;
+   }
+#endif
+}
+
+
+const ossimDatum* ossimDatumFactory::create(const ossimString &code)const
+{
+   map<ossimString, ossimDatum*>::const_iterator
+      datum = theDatumTable.find(code);
+
+   if(datum != theDatumTable.end())
+   { 
+      return (*datum).second;
+   }
+   else
+   {
+     if(code == "NAR")
+       {
+	 map<ossimString, ossimDatum*>::const_iterator
+	   datum = theDatumTable.find("NAR-C");
+	 if(datum != theDatumTable.end())
+	   {
+	     return (*datum).second;
+	   }
+       }
+     else if(code == "NAS")
+       {
+	 map<ossimString, ossimDatum*>::const_iterator
+	   datum = theDatumTable.find("NAS-C");
+	 if(datum != theDatumTable.end())
+	   {
+	     return (*datum).second;
+	   }
+       }
+      return NULL;
+   }
+}
+
+const ossimDatum* ossimDatumFactory::create(const ossimDatum* aDatum)const
+{
+   if (aDatum)
+      return create (aDatum->code());
+   else
+      return NULL;
+}
+
+list<ossimString> ossimDatumFactory::getList()const
+{
+   map<ossimString, ossimDatum*>::const_iterator datum = theDatumTable.begin();
+   list<ossimString> result;
+
+   while(datum != theDatumTable.end())
+   {
+      result.push_back((*datum).first);
+      ++datum;
+   }
+   return result;
+}
+
+void ossimDatumFactory::deleteAll()
+{   
+   map<ossimString, ossimDatum*>::iterator datum;
+   
+   datum = theDatumTable.begin();
+   while(datum != theDatumTable.end())
+   {
+      delete ((*datum).second);
+      
+      ++datum;
+   }
+   
+   theDatumTable.clear();
+
+}
+
+void ossimDatumFactory::initializeDefaults()
+{
+        //make the standards
+   theDatumTable.insert(make_pair(ossimString("WGE"), new ossimWgs84Datum));
+   theDatumTable.insert(make_pair(ossimString("WGD"), new ossimWgs72Datum));
+
+   ossim_uint32 idx = 0;     
+
+   for(idx = 0; idx < NUMBER_OF_THREE_PARAM_DATUMS; ++idx)
+   {
+      if((threeParamDatum[idx].theCode != "WGE")&&
+         (threeParamDatum[idx].theCode != "WGD"))
+      {
+         theDatumTable.insert(make_pair(threeParamDatum[idx].theCode,
+                                        new ossimThreeParamDatum(threeParamDatum[idx].theCode, threeParamDatum[idx].theName,
+                                                                 ossimEllipsoidFactory::instance()->create(ossimString(threeParamDatum[idx].theEllipsoidCode)),
+                                                                 threeParamDatum[idx].theSigmaX, threeParamDatum[idx].theSigmaY, threeParamDatum[idx].theSigmaZ, 
+                                                                 threeParamDatum[idx].theWestLongitude, threeParamDatum[idx].theEastLongitude, threeParamDatum[idx].theSouthLatitude, 
+                                                                 threeParamDatum[idx].theNorthLatitude, threeParamDatum[idx].theParam1, threeParamDatum[idx].theParam2, 
+                                                                 threeParamDatum[idx].theParam3)));
+      }
+   }
+   for(idx = 0; idx < NUMBER_OF_SEVEN_PARAM_DATUMS; ++idx)
+   {
+      if((threeParamDatum[idx].theCode != "WGE")&&
+         (threeParamDatum[idx].theCode != "WGD"))
+      {
+         theDatumTable.insert(make_pair(sevenParamDatum[idx].theCode,
+                                        new ossimSevenParamDatum(sevenParamDatum[idx].theCode, sevenParamDatum[idx].theName,
+                                                                 ossimEllipsoidFactory::instance()->create(ossimString(sevenParamDatum[idx].theEllipsoidCode)),
+                                                                 sevenParamDatum[idx].theSigmaX, sevenParamDatum[idx].theSigmaY, sevenParamDatum[idx].theSigmaZ, 
+                                                                 sevenParamDatum[idx].theWestLongitude, sevenParamDatum[idx].theEastLongitude, sevenParamDatum[idx].theSouthLatitude, 
+                                                                 sevenParamDatum[idx].theNorthLatitude,
+                                                                 sevenParamDatum[idx].theParam1,
+                                                                 sevenParamDatum[idx].theParam2, 
+                                                                 sevenParamDatum[idx].theParam3,
+                                                                 sevenParamDatum[idx].theParam4, 
+                                                                 sevenParamDatum[idx].theParam5,
+                                                                 sevenParamDatum[idx].theParam6, 
+                                                                 sevenParamDatum[idx].theParam7)));
+      }
+   }
+   ossimFilename file = ossimPreferences::instance()->findPreference("datum_grids");
+   
+   if(file != "")
+   {
+      if(!file.isDir())
+      {
+         file = file.path();
+      }
+      
+      ossimFilename fileTest1 = file.dirCat("conus.las");
+      ossimFilename fileTest2 = file.dirCat("conus.los");
+      
+      if(fileTest1.exists()&&
+         fileTest2.exists())
+      {
+         theDatumTable.insert(std::make_pair(ossimString("NAS"),
+                                             new ossimNadconNasDatum(file)));
+         theDatumTable.insert(std::make_pair(ossimString("NAR"),
+                                             new ossimNadconNarDatum(file)));
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.h b/Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.h
new file mode 100644
index 0000000000..a6278dd07b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.h
@@ -0,0 +1,67 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// This is the DatumFactory class.  You give it a code and it will
+// construct a Datum class.  It returns NULL if no code was found.
+//*******************************************************************
+//  $Id: ossimDatumFactory.h,v 1.4 2004/05/14 13:45:56 gpotts Exp $
+
+#ifndef ossimDatumFactory_HEADER
+#define ossimDatumFactory_HEADER
+#include <list>
+#include <map>
+using namespace std;
+#include "base/data_types/ossimString.h"
+#include "ossimEllipsoidFactory.h"
+class ossimFilename;
+class ossimDatum;
+class ossimWgs84Datum;
+class ossimWgs72Datum;
+
+class OSSIMDLLEXPORT ossimDatumFactory
+{
+public:
+   ~ossimDatumFactory();
+   const ossimDatum* create(const ossimString &code)const;
+   const ossimDatum* create(const ossimDatum* copy) const;
+
+   static ossimDatumFactory* instance();
+   const ossimDatum* wgs84()const{return theWgs84Datum;}
+   const ossimDatum* wgs72()const{return theWgs72Datum;}
+   list<ossimString> getList()const;
+   void writeCStructure(const ossimFilename& file);
+protected:
+   static ossimDatumFactory*       theInstance;
+   const ossimDatum*               theWgs84Datum;
+   const ossimDatum*               theWgs72Datum;
+   static map<ossimString, ossimDatum*> theDatumTable;
+   
+
+   ossimDatumFactory()
+      :theWgs84Datum(0),
+       theWgs72Datum(0)
+      {}
+   ossimDatumFactory(const ossimDatumFactory&){}
+   void deleteAll();
+   void initializeDefaults();
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.inc b/Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.inc
new file mode 100644
index 0000000000..e14ba1070a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimDatumFactory.inc
@@ -0,0 +1,299 @@
+//*************************************************************************
+// Copyright (C) 2004 Intelligence Data Sytems, Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts
+//
+//**************************************************************************
+// $Id: ossimDatumFactory.inc,v 1.5 2005/12/15 12:07:19 gpotts Exp $
+
+struct ossimSevenParamDatumType
+{
+   const char* theCode;
+   const char* theName;
+   const char* theEllipsoidCode;
+   ossim_float64 theSigmaX;
+   ossim_float64 theSigmaY;
+   ossim_float64 theSigmaZ;
+   ossim_float64 theWestLongitude;
+   ossim_float64 theEastLongitude;
+   ossim_float64 theSouthLatitude;
+   ossim_float64 theNorthLatitude;
+   ossim_float64 theParam1;
+   ossim_float64 theParam2;
+   ossim_float64 theParam3;
+   ossim_float64 theParam4;
+   ossim_float64 theParam5;
+   ossim_float64 theParam6;
+   ossim_float64 theParam7;
+};
+
+struct ossimThreeParamDatumType
+{
+public:
+   const char* theCode;
+   const char* theName;
+   const char* theEllipsoidCode;
+   ossim_float64 theSigmaX;
+   ossim_float64 theSigmaY;
+   ossim_float64 theSigmaZ;
+   ossim_float64 theWestLongitude;
+   ossim_float64 theEastLongitude;
+   ossim_float64 theSouthLatitude;
+   ossim_float64 theNorthLatitude;
+   ossim_float64 theParam1;
+   ossim_float64 theParam2;
+   ossim_float64 theParam3;
+};
+
+#define NUMBER_OF_SEVEN_PARAM_DATUMS 2
+#define NUMBER_OF_THREE_PARAM_DATUMS 226
+
+static ossimThreeParamDatumType threeParamDatum[] = {
+{"ADI-A", "ADINDAN, Ethiopia", "CD", 3, 3, 3, 26, 50, -3, 25, -165, -11, 206},
+{"ADI-B", "ADINDAN, Sudan", "CD", 3, 5, 3, 15, 45, -3, 31, -161, -14, 205},
+{"ADI-C", "ADINDAN, Mali", "CD", 25, 25, 25, -20, 11, 3, 31, -123, -20, 220},
+{"ADI-D", "ADINDAN, Senegal", "CD", 25, 25, 25, -24, -5, 5, 23, -128, -18, 224},
+{"ADI-E", "ADINDAN, Burkina Faso", "CD", 25, 25, 25, -5, 8, 4, 22, -118, -14, 218},
+{"ADI-F", "ADINDAN, Cameroon", "CD", 25, 25, 25, 3, 23, -4, 19, -134, -2, 210},
+{"ADI-M", "ADINDAN, Mean", "CD", 5, 5, 3, 15, 55, -5, 31, -166, -15, 204},
+{"AFG", "AFGOOYE, Somalia", "KA", 25, 25, 25, 35, 60, -8, 19, -43, -163, 45},
+{"AIA", "ANTIGUA ISLAND ASTRO 1943", "CD", 25, 25, 25, -65, -61, 16, 20, -270, 13, 62},
+{"AIN-A", "AIN EL ABD 1970, Bahrain", "IN", 25, 25, 25, 49, 53, 24, 28, -150, -250, -1},
+{"AIN-B", "AIN EL ABD 1970, Saudi Arabia", "IN", 10, 10, 10, 28, 62, 8, 38, -143, -236, 7},
+{"AMA", "AMERICAN SAMOA 1962", "CC", 25, 25, 25, -174, -165, -19, -9, -115, 118, 426},
+{"ANO", "ANNA 1 ASTRO 1965, Cocos Is.", "AN", 25, 25, 25, 94, 99, -14, -10, -491, -22, 435},
+{"ARF-A", "ARC 1950, Botswana", "CD", 3, 5, 3, 13, 36, -33, -13, -138, -105, -289},
+{"ARF-B", "ARC 1950, Lesotho", "CD", 3, 3, 8, 21, 35, -36, -23, -125, -108, -295},
+{"ARF-C", "ARC 1950, Malawi", "CD", 9, 24, 8, 26, 42, -21, -3, -161, -73, -317},
+{"ARF-D", "ARC 1950, Swaziland", "CD", 15, 15, 15, 25, 40, -33, -20, -134, -105, -295},
+{"ARF-E", "ARC 1950, Zaire", "CD", 25, 25, 25, 4, 38, -21, 10, -169, -19, -278},
+{"ARF-F", "ARC 1950, Zambia", "CD", 21, 21, 27, 15, 40, -24, -1, -147, -74, -283},
+{"ARF-G", "ARC 1950, Zimbabwe", "CD", 5, 8, 11, 19, 39, -29, -9, -142, -96, -293},
+{"ARF-H", "ARC 1950, Burundi", "CD", 20, 20, 20, 21, 37, -11, 4, -153, -5, -292},
+{"ARF-M", "ARC 1950, Mean", "CD", 20, 33, 20, 4, 42, -36, 10, -143, -90, -294},
+{"ARS-A", "ARC 1960, Kenya", "CD", 4, 3, 3, 28, 47, -11, 8, -157, -2, -299},
+{"ARS-B", "ARC 1960, Tanzania", "CD", 6, 9, 10, 23, 47, -18, 5, -175, -23, -303},
+{"ARS-M", "ARC 1960, Kenya & Tanzania", "CD", 20, 20, 20, 23, 47, -18, 8, -160, -6, -302},
+{"ASC", "ASCENSION ISLAND 1958", "IN", 25, 25, 25, -16, -13, -9, -6, -205, 107, 53},
+{"ASM", "MONTSERRAT ISLAND ASTRO 1958", "CD", 25, 25, 25, -64, -61, 15, 18, 174, 359, 365},
+{"ASQ", "ASTRO STATION 1952, Marcus Is.", "IN", 25, 25, 25, 152, 156, 22, 26, 124, -234, -25},
+{"ATF", "ASTRO BEACON E 1845, Iwo Jima", "IN", 25, 25, 25, 140, 144, 22, 26, 145, 75, -272},
+{"AUA", "AUSTRALIAN GEODETIC 1966", "AN", 3, 3, 3, 109, 161, -46, -4, -133, -48, 148},
+{"AUG", "AUSTRALIAN GEODETIC 1984", "AN", 2, 2, 2, 109, 161, -46, -4, -134, -48, 149},
+{"BAT", "DJAKARTA, INDONESIA", "BR", 3, 3, 3, 89, 146, -16, 11, -377, 681, -50},
+{"BER", "BERMUDA 1957, Bermuda Islands", "CC", 20, 20, 20, -66, -63, 31, 34, -73, 213, 296},
+{"BID", "BISSAU, Guinea-Bissau", "IN", 25, 25, 25, -23, -7, 5, 19, -173, 253, 27},
+{"BOO", "BOGOTA OBSERVATORY, Columbia", "IN", 6, 5, 6, -85, -61, -10, 16, 307, 304, -318},
+{"BUR", "BUKIT RIMPAH, Banka & Belitung", "BR", -1, -1, -1, 103, 110, -6, 0, -384, 664, -48},
+{"CAC", "CAPE CANAVERAL, Fla & Bahamas", "CC", 3, 3, 3, -94, -12, 15, 38, -2, 151, 181},
+{"CAI", "CAMPO INCHAUSPE 1969, Arg.", "IN", 5, 5, 5, -72, -51, -58, -27, -148, 136, 90},
+{"CAO", "CANTON ASTRO 1966, Phoenix Is.", "IN", 15, 15, 15, -180, -165, -13, 3, 298, -304, -375},
+{"CAP", "CAPE, South Africa", "CD", 3, 6, 6, 10, 40, -43, -15, -136, -108, -292},
+{"CAZ", "CAMP AREA ASTRO, Camp McMurdo", "IN", -1, -1, -1, 135, 180, -85, -70, -104, -129, 239},
+{"CCD", "S-JTSK, Czech Republic", "BR", 4, 2, 3, 6, 28, 43, 56, 589, 76, 480},
+{"CGE", "CARTHAGE, Tunisia", "CD", 6, 9, 8, 2, 18, 24, 43, -263, 6, 431},
+{"CHI", "CHATHAM ISLAND ASTRO 1971, NZ", "IN", 15, 15, 15, -180, -174, -46, -42, 175, -38, 113},
+{"CHU", "CHUA ASTRO, Paraguay", "IN", 6, 9, 5, -69, -49, -33, -14, -134, 229, -29},
+{"COA", "CORREGO ALEGRE, Brazil", "IN", 5, 3, 5, -80, -29, -39, -2, -206, 172, -6},
+{"DAL", "DABOLA, Guinea", "CD", 15, 15, 15, 12, 11, 1, 19, -83, 37, 124},
+{"DID", "DECEPTION ISLAND", "CD", 20, 20, 20, 58, 62, -65, -62, 260, 12, -147},
+{"DOB", "GUX 1 ASTRO, Guadalcanal Is.", "IN", 25, 25, 25, 158, 163, -12, -8, 252, -209, -751},
+{"EAS", "EASTER ISLAND 1967", "IN", 25, 25, 25, -111, -108, -29, -26, 211, 147, 111},
+{"ENW", "WAKE-ENIWETOK 1960", "HO", 3, 3, 3, 159, 175, 1, 16, 102, 52, -38},
+{"EST", "ESTONIA, 1937", "BR", 2, 3, 3, 16, 34, 52, 65, 374, 150, 588},
+{"EUR-A", "EUROPEAN 1950, Western Europe", "IN", 3, 3, 3, -15, 25, 30, 78, -87, -96, -120},
+{"EUR-B", "EUROPEAN 1950, Greece", "IN", 25, 25, 25, 14, 34, 30, 48, -84, -95, -130},
+{"EUR-C", "EUROPEAN 1950, Norway & Finland", "IN", 3, 5, 3, -2, 38, 52, 80, -87, -95, -120},
+{"EUR-D", "EUROPEAN 1950, Portugal & Spain", "IN", 5, 6, 3, -15, 10, 30, 49, -84, -107, -120},
+{"EUR-E", "EUROPEAN 1950, Cyprus", "IN", 15, 15, 15, 31, 36, 33, 37, -104, -101, -140},
+{"EUR-F", "EUROPEAN 1950, Egypt", "IN", 6, 8, 8, 19, 42, 16, 38, -130, -117, -151},
+{"EUR-G", "EUROPEAN 1950, England, Channel", "IN", 3, 3, 3, -10, 3, 48, 62, -86, -96, -120},
+{"EUR-H", "EUROPEAN 1950, Iran", "IN", 9, 12, 11, 37, 69, 19, 47, -117, -132, -164},
+{"EUR-I", "EUROPEAN 1950, Sardinia(Italy)", "IN", 25, 25, 25, 6, 12, 37, 43, -97, -103, -120},
+{"EUR-J", "EUROPEAN 1950, Sicily(Italy)", "IN", 20, 20, 20, 10, 17, 35, 40, -97, -88, -135},
+{"EUR-K", "EUROPEAN 1950, England, Ireland", "IN", 3, 3, 3, -12, 3, 48, 62, -86, -96, -120},
+{"EUR-L", "EUROPEAN 1950, Malta", "IN", 25, 25, 25, 12, 16, 34, 38, -107, -88, -149},
+{"EUR-M", "EUROPEAN 1950, Mean (3 Param)", "IN", 3, 8, 5, 5, 33, 30, 80, -87, -98, -121},
+{"EUR-S", "EUROPEAN 1950, Iraq, Israel", "IN", -1, -1, -1, 36, 57, -38, -4, -103, -106, -141},
+{"EUR-T", "EUROPEAN 1950, Tunisia", "IN", 25, 25, 25, 2, 18, 24, 43, -112, -77, -145},
+{"EUS", "EUROPEAN 1979", "IN", 3, 3, 3, -15, 24, 30, 80, -86, -98, -119},
+{"FAH", "OMAN", "CD", 3, 3, 9, 46, 65, 10, 32, -346, -1, 224},
+{"FLO", "OBSERVATORIO MET. 1939, Flores", "IN", 20, 20, 20, -33, -30, 38, 41, -425, -169, 81},
+{"FOT", "FORT THOMAS 1955, Leeward Is.", "CD", 25, 25, 25, -64, -61, 16, 19, -7, 215, 225},
+{"GAA", "GAN 1970, Rep. of Maldives", "IN", 25, 25, 25, 71, 75, -2, 9, -133, -321, 50},
+{"GEO", "GEODETIC DATUM 1949, NZ", "IN", 5, 3, 5, 165, 180, -48, -33, 84, -22, 209},
+{"GIZ", "DOS 1968, Gizo Island", "IN", 25, 25, 25, 155, 158, -10, -7, 230, -199, -752},
+{"GRA", "GRACIOSA BASE SW 1948, Azores", "IN", 3, 3, 3, -30, -26, 37, 41, -104, 167, -38},
+{"GSE", "GUNUNG SEGARA, Indonesia", "BR", -1, -1, -1, 106, 121, -6, 9, -403, 684, 41},
+{"GUA", "GUAM 1963", "CC", 3, 3, 3, 143, 146, 12, 15, -100, -248, 259},
+{"HEN", "HERAT NORTH, Afghanistan", "IN", -1, -1, -1, 55, 81, 23, 44, -333, -222, 114},
+{"HER", "HERMANNSKOGEL, old Yugoslavia", "BR", -1, -1, -1, 7, 29, 35, 52, 682, -203, 480},
+{"HIT", "PROVISIONAL SOUTH CHILEAN 1963", "IN", 25, 25, 25, -83, -60, -64, -25, 16, 196, 93},
+{"HJO", "HJORSEY 1955, Iceland", "IN", 3, 3, 6, -24, -11, 61, 69, -73, 46, -86},
+{"HKD", "HONG KONG 1963", "IN", 25, 25, 25, 112, 116, 21, 24, -156, -271, -189},
+{"HTN", "HU-TZU-SHAN, Taiwan", "IN", 15, 15, 15, 117, 124, 20, 28, -637, -549, -203},
+{"IBE", "BELLEVUE (IGN), Efate Is.", "IN", 20, 20, 20, 167, 171, -20, -16, -127, -769, 472},
+{"IDN", "INDONESIAN 1974", "ID", 25, 25, 25, 89, 146, -16, 11, -24, -15, 5},
+{"IND-B", "INDIAN, Bangladesh", "EA", 10, 8, 12, 80, 100, 15, 33, 282, 726, 254},
+{"IND-I", "INDIAN, India & Nepal", "EC", 12, 10, 15, 62, 105, 2, 44, 295, 736, 257},
+{"IND-P", "INDIAN, Pakistan", "EA", -1, -1, -1, 55, 81, 17, 44, 283, 682, 231},
+{"INF-A", "INDIAN 1954, Thailand", "EA", 15, 6, 12, 91, 111, 0, 27, 217, 823, 299},
+{"ING-A", "INDIAN 1960, Vietnam 16N", "EA", 25, 25, 25, 101, 115, 11, 23, 198, 881, 317},
+{"ING-B", "INDIAN 1960, Con Son Island", "EA", 25, 25, 25, 104, 109, 6, 11, 182, 915, 344},
+{"INH-A", "INDIAN 1975, Thailand", "EA", 12, 10, 12, 91, 111, 0, 27, 209, 818, 290},
+{"INH-A1", "INDIAN 1975, Thailand", "EA", 3, 2, 3, 91, 111, 0, 27, 210, 814, 289},
+{"IRL", "IRELAND 1965", "AM", 3, 3, 3, -12, -4, 50, 57, 506, -122, 611},
+{"ISG", "ISTS 061 ASTRO 1968, S Georgia", "IN", 25, 25, 25, -38, -34, -56, -52, -794, 119, -298},
+{"IST", "ISTS 073 ASTRO 1969, Diego Garc", "IN", 25, 25, 25, 69, 75, -10, -4, 208, -435, -229},
+{"JOH", "JOHNSTON ISLAND 1961", "IN", 25, 25, 25, -76, -73, -46, -43, 189, -79, -202},
+{"KAN", "KANDAWALA, Sri Lanka", "EA", 20, 20, 20, 77, 85, 4, 12, -97, 787, 86},
+{"KEA", "KERTAU 1948, W Malaysia & Sing.", "EE", 10, 8, 6, 94, 112, -5, 12, -11, 851, 5},
+{"KEG", "KERGUELEN ISLAND 1949", "IN", 25, 25, 25, 139, 180, -81, -74, 145, -187, 103},
+{"KUS", "KUSAIE ASTRO 1951, Caroline Is.", "IN", 25, 25, 25, 134, 167, -1, 12, 647, 1777, -1124},
+{"LCF", "L.C. 5 ASTRO 1961, Cayman Brac", "CC", 25, 25, 25, -81, -78, 18, 21, 42, 124, 147},
+{"LEH", "LEIGON, Ghana", "CD", 2, 3, 2, -9, 7, -1, 17, -130, 29, 364},
+{"LIB", "LIBERIA 1964", "CD", 15, 15, 15, -17, -1, -1, 14, -90, 40, 88},
+{"LUZ-A", "LUZON, Phillipines", "CC", 8, 11, 9, 115, 128, 3, 23, -133, -77, -51},
+{"LUZ-B", "LUZON, Mindanao Island", "CC", 25, 25, 25, 120, 128, 4, 12, -133, -79, -72},
+{"MAS", "MASSAWA, Ethiopia", "BR", 25, 25, 25, 37, 53, 7, 25, 639, 405, 60},
+{"MER", "MERCHICH, Morocco", "CD", 5, 3, 3, -19, 5, 22, 42, 31, 146, 47},
+{"MID", "MIDWAY ASTRO 1961, Midway Is.", "IN", 25, 25, 25, -180, -169, 25, 30, 912, -58, 1227},
+{"MIK", "MAHE 1971, Mahe Is.", "CD", 25, 25, 25, 54, 57, -6, -3, 41, -220, -134},
+{"MIN-A", "MINNA, Cameroon", "CD", 25, 25, 25, 3, 23, -4, 19, -81, -84, 115},
+{"MIN-B", "MINNA, Nigeria", "CD", 3, 6, 5, -4, 20, -1, 21, -92, -93, 122},
+{"MOD", "ROME 1940, Sardinia", "IN", 25, 25, 25, 6, 12, 37, 43, -225, -65, 9},
+{"MPO", "M'PORALOKO, Gabon", "CD", 25, 25, 25, 3, 20, -10, 8, -74, -130, 42},
+{"MVS", "VITI LEVU 1916, Viti Levu Is.", "CD", 25, 25, 25, 176, 180, -20, -16, 51, 391, -36},
+{"NAH-A", "NAHRWAN, Masirah Island (Oman)", "CD", 25, 25, 25, 57, 60, 19, 22, -247, -148, 369},
+{"NAH-B", "NAHRWAN, United Arab Emirates", "CD", 25, 25, 25, 45, 62, 17, 32, -249, -156, 381},
+{"NAH-C", "NAHRWAN, Saudi Arabia", "CD", 25, 25, 20, 28, 62, 8, 38, -243, -192, 477},
+{"NAP", "NAPARIMA, Trinidad & Tobago", "IN", 15, 15, 15, -64, -59, 8, 13, -10, 375, 165},
+{"NAR-A", "NORTH AMERICAN 1983, Alaska", "RF", 2, 2, 2, -175, -135, 48, 78, 0, 0, 0},
+{"NAR-B", "NORTH AMERICAN 1983, Canada", "RF", 2, 2, 2, -150, -50, 36, 90, 0, 0, 0},
+{"NAR-C", "NORTH AMERICAN 1983, CONUS", "RF", 2, 2, 2, -135, -60, 15, 60, 0, 0, 0},
+{"NAR-D", "NORTH AMERICAN 1983, Mexico", "RF", 2, 2, 2, -122, -72, 11, 35, 0, 0, 0},
+{"NAR-E", "NORTH AMERICAN 1983, Aleutian", "RF", 5, 2, 5, -180, 180, 51, 74, -2, 0, 4},
+{"NAR-H", "NORTH AMERICAN 1983, Hawai'i", "RF", 2, 2, 2, -164, -153, 17, 24, 1, 1, -1},
+{"NAS-A", "NORTH AMERICAN 1927, Eastern US", "CC", 5, 5, 8, -102, -60, 18, 55, -9, 161, 179},
+{"NAS-B", "NORTH AMERICAN 1927, Western US", "CC", 5, 3, 3, -132, -87, 19, 55, -8, 159, 175},
+{"NAS-C", "NORTH AMERICAN 1927, CONUS", "CC", 5, 5, 6, -135, -60, 15, 60, -8, 160, 176},
+{"NAS-D", "NORTH AMERICAN 1927, Alaska", "CC", 5, 9, 5, -175, -130, 47, 78, -5, 135, 172},
+{"NAS-E", "NORTH AMERICAN 1927, Canada", "CC", 15, 11, 6, -150, -50, 36, 90, -10, 158, 187},
+{"NAS-F", "NORTH AMERICAN 1927, Alberta/BC", "CC", 8, 8, 6, -145, -105, 43, 65, -7, 162, 188},
+{"NAS-G", "NORTH AMERICAN 1927, E. Canada", "CC", 6, 6, 3, -85, -45, 38, 68, -22, 160, 190},
+{"NAS-H", "NORTH AMERICAN 1927, Man/Ont", "CC", 9, 5, 5, -108, -69, 36, 63, -9, 157, 184},
+{"NAS-I", "NORTH AMERICAN 1927, NW Terr.", "CC", 5, 5, 3, -144, -55, 43, 90, 4, 159, 188},
+{"NAS-J", "NORTH AMERICAN 1927, Yukon", "CC", 5, 8, 3, -147, -117, 53, 75, -7, 139, 181},
+{"NAS-L", "NORTH AMERICAN 1927, Mexico", "CC", 8, 6, 6, -122, -80, 10, 38, -12, 130, 190},
+{"NAS-N", "NORTH AMERICAN 1927, C. America", "CC", 8, 3, 5, -98, -77, 3, 25, 0, 125, 194},
+{"NAS-O", "NORTH AMERICAN 1927, Canal Zone", "CC", 20, 20, 20, -86, -74, 3, 15, 0, 125, 201},
+{"NAS-P", "NORTH AMERICAN 1927, Caribbean", "CC", 3, 9, 12, -87, -58, 8, 29, -3, 142, 183},
+{"NAS-Q", "NORTH AMERICAN 1927, Bahamas", "CC", 5, 3, 5, -83, -71, 19, 29, -4, 154, 178},
+{"NAS-R", "NORTH AMERICAN 1927, San Salv.", "CC", 25, 25, 25, -75, -74, 23, 26, 1, 140, 165},
+{"NAS-T", "NORTH AMERICAN 1927, Cuba", "CC", 25, 25, 25, -87, -72, 18, 25, -9, 152, 178},
+{"NAS-U", "NORTH AMERICAN 1927, Greenland", "CC", 25, 25, 25, 74, 56, 74, 81, 11, 114, 195},
+{"NAS-V", "NORTH AMERICAN 1927, Aleutian E", "CC", 6, 8, 10, -180, -161, 50, 58, -2, 152, 149},
+{"NAS-W", "NORTH AMERICAN 1927, Aleutian W", "CC", 10, 10, 10, 169, 180, 50, 58, 2, 204, 105},
+{"NSD", "NORTH SAHARA 1959, Algeria", "CD", 25, 25, 25, -15, 11, 13, 43, -186, -93, 310},
+{"NTF", "NOUVELLE TRIANGULATION DE LA FRANCE, FRANCE", "CE", 0, 0, 0, -6, 12, 41, 51, -168, -60, 320},
+{"OEG", "OLD EGYPTIAN 1907", "HE", 3, 6, 8, 19, 42, 16, 38, -130, 110, -13},
+{"OGB-A", "ORDNANCE GB 1936, England", "AA", 5, 5, 6, -12, 7, 44, 61, 371, -112, 434},
+{"OGB-B", "ORDNANCE GB 1936, Eng., Wales", "AA", 10, 10, 15, -12, 7, 44, 61, 371, -111, 434},
+{"OGB-C", "ORDNANCE GB 1936, Scotland", "AA", 10, 10, 10, -14, 4, 49, 66, 384, -111, 425},
+{"OGB-D", "ORDNANCE GB 1936, Wales", "AA", 20, 20, 20, -11, 3, 46, 59, 370, -108, 434},
+{"OGB-M", "ORDNANCE GB 1936, Mean (3 Para)", "AA", 10, 10, 15, -14, 7, 44, 66, 375, -111, 431},
+{"OHA-A", "OLD HAWAI'IAN (CC), Hawai'i", "CC", 25, 25, 25, -158, -153, 17, 22, 89, -279, -183},
+{"OHA-B", "OLD HAWAI'IAN (CC), Kauai", "CC", 20, 20, 20, -161, -158, 20, 24, 45, -290, -172},
+{"OHA-C", "OLD HAWAI'IAN (CC), Maui", "CC", 25, 25, 25, -158, -154, 19, 23, 65, -290, -190},
+{"OHA-D", "OLD HAWAI'IAN (CC), Oahu", "CC", 10, 6, 6, -160, -156, 20, 23, 58, -283, -182},
+{"OHA-M", "OLD HAWAI'IAN (CC), Mean", "CC", 25, 20, 20, -164, -153, 17, 24, 61, -285, -181},
+{"OHI-A", "OLD HAWAI'IAN (IN), Hawai'i", "IN", 25, 25, 25, -158, -153, 17, 22, 229, -222, -348},
+{"OHI-B", "OLD HAWAI'IAN (IN), Kauai", "IN", 20, 20, 20, -161, -158, 20, 24, 185, -233, -337},
+{"OHI-C", "OLD HAWAI'IAN (IN), Maui", "IN", 25, 25, 25, -158, -154, 19, 23, 205, -233, -355},
+{"OHI-D", "OLD HAWAI'IAN (IN), Oahu", "IN", 10, 6, 6, -160, -156, 20, 23, 198, -226, -347},
+{"OHI-M", "OLD HAWAI'IAN (IN), Mean", "IN", 25, 20, 20, -164, -153, 17, 24, 201, -228, -346},
+{"PHA", "AYABELLA LIGHTHOUSE, Bjibouti", "CD", 25, 25, 25, 36, 49, 5, 20, -79, -129, 145},
+{"PIT", "PITCAIRN ASTRO 1967", "IN", 25, 25, 25, -134, -119, -27, -21, 185, 165, 42},
+{"PLN", "PICO DE LAS NIEVES, Canary Is.", "IN", 25, 25, 25, -20, -12, 26, 31, -307, -92, 127},
+{"POS", "PORTO SANTO 1936, Madeira Is.", "IN", 25, 25, 25, -18, -15, 31, 35, -499, -249, 314},
+{"PRP-A", "PROV. S AMERICAN 1956, Bolivia", "IN", 5, 11, 14, -75, -51, -28, -4, -270, 188, -388},
+{"PRP-B", "PROV. S AMERICAN 1956, N Chile", "IN", 25, 25, 25, -83, -60, -45, -12, -270, 183, -390},
+{"PRP-C", "PROV. S AMERICAN 1956, S Chile", "IN", 20, 20, 20, -83, -60, -64, -20, -305, 243, -442},
+{"PRP-D", "PROV. S AMERICAN 1956, Colombia", "IN", 15, 15, 15, -85, -61, -10, 16, -282, 169, -371},
+{"PRP-E", "PROV. S AMERICAN 1956, Ecuador", "IN", 3, 5, 3, -85, -70, -11, 7, -278, 171, -367},
+{"PRP-F", "PROV. S AMERICAN 1956, Guyana", "IN", 6, 14, 5, -67, -51, -4, 14, -298, 159, -369},
+{"PRP-G", "PROV. S AMERICAN 1956, Peru", "IN", 6, 8, 12, -87, -63, -24, 5, -279, 175, -379},
+{"PRP-H", "PROV. S AMERICAN 1956, Venez", "IN", 9, 14, 15, -79, -54, -5, 18, -295, 173, -371},
+{"PRP-M", "PROV. S AMERICAN 1956, Mean", "IN", 17, 27, 27, -87, -51, -64, 18, -288, 175, -376},
+{"PTB", "POINT 58, Burkina Faso & Niger", "CD", 25, 25, 25, -15, 25, 0, 10, -106, -129, 165},
+{"PTN", "POINT NOIRE 1948", "CD", 25, 25, 25, 5, 25, -11, 10, -148, 51, -291},
+{"PUK", "PULKOVO 1942, Russia", "KA", -1, -1, -1, -180, 180, 36, 89, 28, -130, -95},
+{"PUR", "PUERTO RICO & Virgin Is.", "CC", 3, 3, 3, -69, -63, 16, 20, 11, 72, -101},
+{"QAT", "QATAR NATIONAL", "IN", 20, 20, 20, 45, 57, 19, 32, -128, -283, 22},
+{"QUO", "QORNOQ, South Greenland", "IN", 25, 25, 32, -77, -7, 57, 85, 164, 138, -189},
+{"REU", "REUNION, Mascarene Is.", "IN", 25, 25, 25, 47, 65, -27, -12, 94, -948, -1262},
+{"SAE", "SANTO (DOS) 1965", "IN", 22, 25, 25, 160, 169, -17, -13, 170, 42, 84},
+{"SAN-A", "SOUTH AMERICAN 1969, Argentina", "SA", 5, 5, 5, -76, -47, -62, -23, -62, -1, -37},
+{"SAN-B", "SOUTH AMERICAN 1969, Bolivia", "SA", 15, 15, 15, -75, -51, -28, -4, -61, 2, -48},
+{"SAN-C", "SOUTH AMERICAN 1969, Brazil", "SA", 3, 5, 5, -80, -29, -39, -2, -60, -2, -41},
+{"SAN-D", "SOUTH AMERICAN 1969, Chile", "SA", 15, 8, 11, -83, -60, -64, -12, -75, -1, -44},
+{"SAN-E", "SOUTH AMERICAN 1969, Colombia", "SA", 6, 6, 5, -85, -61, -10, 16, -44, 6, -36},
+{"SAN-F", "SOUTH AMERICAN 1969, Ecuador", "SA", 3, 3, 3, -85, -70, -11, 7, -48, 3, -44},
+{"SAN-G", "SOUTH AMERICAN 1969, Guyana", "SA", 9, 5, 5, -67, -51, -4, 14, -53, 3, -47},
+{"SAN-H", "SOUTH AMERICAN 1969, Paraguay", "SA", 15, 15, 15, -69, -49, -33, -14, -61, 2, -33},
+{"SAN-I", "SOUTH AMERICAN 1969, Peru", "SA", 5, 5, 5, -87, -63, -24, 5, -58, 0, -44},
+{"SAN-J", "SOUTH AMERICAN 1969, Baltra", "SA", 25, 25, 25, -92, -89, -2, 1, -47, 26, -42},
+{"SAN-K", "SOUTH AMERICAN 1969, Trinidad", "SA", 25, 25, 25, -68, -55, 4, 17, -45, 12, -33},
+{"SAN-L", "SOUTH AMERICAN 1969, Venezuela", "SA", 3, 6, 3, -79, -54, -5, 18, -45, 8, -33},
+{"SAN-M", "SOUTH AMERICAN 1969, Mean", "SA", 15, 6, 9, -90, -25, -65, -50, -57, 1, -41},
+{"SAO", "SAO BRAZ, Santa Maria Is.", "IN", 25, 25, 25, -27, -23, 35, 39, -203, 141, 53},
+{"SAP", "SAPPER HILL 1943, E Falkland Is", "IN", 1, 1, 1, -61, -56, -54, -50, -355, 21, 72},
+{"SCK", "SCHWARZECK, Namibia", "BN", 20, 20, 20, 5, 31, -35, -11, 616, 97, -251},
+{"SGM", "SELVAGEM GRADE 1938, Salvage Is", "IN", 25, 25, 25, -18, -14, 28, 32, -289, -124, 60},
+{"SHB", "ASTRO DOS 71/4, St. Helena Is.", "IN", 25, 25, 25, -7, -4, -18, -14, -320, 550, -494},
+{"SOA", "SOUTH ASIA, Singapore", "FA", 25, 25, 25, 102, 106, 0, 3, 7, -10, -26},
+{"SPK-A", "S-42 (PULKOVO 1942), Hungary", "KA", 2, 2, 2, 11, 29, 40, 54, 28, -121, -77},
+{"SPK-B", "S-42 (PULKOVO 1942), Poland", "KA", 4, 2, 4, 8, 30, 43, 60, 23, -124, -82},
+{"SPK-C", "S-42 (PK42) Former Czechoslov.", "KA", 3, 3, 2, 6, 28, 42, 57, 26, -121, -78},
+{"SPK-D", "S-42 (PULKOVO 1942), Latvia", "KA", 2, 2, 2, 15, 34, 50, 64, 24, -124, -82},
+{"SPK-E", "S-42 (PK 1942), Kazakhstan", "KA", 25, 25, 25, 41, 93, 35, 62, 15, -130, -84},
+{"SPK-F", "S-42 (PULKOVO 1942), Albania", "KA", 3, 3, 3, 14, 26, 34, 48, 24, -130, -92},
+{"SPK-G", "S-42 (PULKOVO 1942), Romania", "KA", 3, 5, 3, 15, 35, 38, 54, 28, -121, -77},
+{"SRL", "SIERRA LEONE 1960", "CD", 15, 15, 15, -19, -4, 1, 16, -88, 4, 101},
+{"TAN", "TANANARIVE OBSERVATORY 1925", "IN", -1, -1, -1, 40, 53, -34, -8, -189, -242, -91},
+{"TDC", "TRISTAN ASTRO 1968", "IN", 25, 25, 25, -14, -11, -39, -36, -632, 438, -609},
+{"TIL", "TIMBALAI 1948, Brunei & E Malay", "EA", 10, 10, 12, 101, 125, -5, 15, -679, 669, -48},
+{"TOY-A", "TOKYO, Japan", "BR", 8, 5, 8, 119, 156, 19, 51, -148, 507, 685},
+{"TOY-B", "TOKYO, South Korea", "BR", 8, 5, 8, 120, 139, 27, 45, -146, 507, 687},
+{"TOY-B1", "TOKYO, South Korea", "BR", 2, 2, 2, 120, 139, 27, 45, -147, 506, 687},
+{"TOY-C", "TOKYO, Okinawa", "BR", 20, 5, 20, 119, 134, 19, 31, -158, 507, 676},
+{"TOY-M", "TOKYO, Mean", "BR", 20, 5, 20, 120, 155, 23, 53, -148, 507, 685},
+{"TRN", "ASTRO TERN ISLAND (FRIG) 1961", "IN", 25, 25, 25, -166, -166, 22, 26, 114, -116, -333},
+{"VOI", "VOIROL 1874, Algeria", "CD", -1, -1, -1, -15, 11, 13, 43, -73, -247, 227},
+{"VOR", "VOIROL 1960, Algeria", "CD", 25, 25, 25, -15, 11, 13, 43, -123, -206, 219},
+{"WAK", "WAKE ISLAND ASTRO 1952", "IN", 25, 25, 25, -176, -171, 17, 21, 276, -57, 149},
+{"WGD", "World Geodetic System 1972", "WD", 0, 0, 0, -180.0, 180.0, -90, 90, 0, 0, 0},
+{"WGE", "World Geodetic System 1984", "WE", 0, 0, 0, -180.0, 180.0, -90, 90, 0, 0, 0},
+{"YAC", "YACARE, Uruguay", "IN", -1, -1, -1, -65, -47, -40, -25, -155, 171, 37},
+{"ZAN", "ZANDERIJ, Suriname", "IN", 5, 5, 8, -76, -47, -10, 20, -265, 120, -358}
+};
+
+static ossimSevenParamDatumType sevenParamDatum[] = {
+{"EUR-7", "EUROPEAN 1950, Mean (7 Param)", "IN", 0, 0, 0, -180, 180, -90, 90, -102, -102, -129, 2.00228e-06, -8.92057e-07, 1.86653e-06, 2.4664e-06},
+{"OGB-7", "ORDNANCE GB 1936, Mean (7 Para)", "AA", 0, 0, 0, -180, 180, -90, 90, 446, -99, 544, -4.58149e-06, -1.26536e-06, -2.10894e-06, -2.08927e-05}
+};
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimEllipsoidFactory.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimEllipsoidFactory.cpp
new file mode 100644
index 0000000000..8edbb94daa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimEllipsoidFactory.cpp
@@ -0,0 +1,187 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// 
+//*******************************************************************
+//  $Id: ossimEllipsoidFactory.cpp,v 1.5 2005/12/15 12:38:08 gpotts Exp $
+#include "ossimEllipsoidFactory.h"
+#include "base/data_types/ellipse/ossimEllipsoid.h"
+
+ossimEllipsoidFactory* ossimEllipsoidFactory::theInstance = 0;
+
+ossimEllipsoidFactory* ossimEllipsoidFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimEllipsoidFactory;
+      theInstance->initializeTable();
+   }
+ 
+   return theInstance; 
+} 
+
+ossimEllipsoidFactory::ossimEllipsoidFactory()
+{
+}
+
+ossimEllipsoidFactory::~ossimEllipsoidFactory()
+{
+   deleteAll();
+   theInstance = NULL;
+}
+
+
+const ossimEllipsoid* ossimEllipsoidFactory::create(const ossimString &code)const
+{
+   TableType::const_iterator ellipsoid = theEllipsoidTable.find(code);
+
+   if(ellipsoid != theEllipsoidTable.end())
+   {
+      return (*ellipsoid).second;
+   }
+   
+   return NULL;
+}
+
+void ossimEllipsoidFactory::initializeTable()
+{
+   if(theEllipsoidTable.size()<1)
+   {
+      theEllipsoidTable.insert(make_pair(ossimString("AA"),
+                                         new ossimEllipsoid(ossimString("Airy"), ossimString("AA"), 6377563.396, 6356256.9090)));   
+      theEllipsoidTable.insert(make_pair(ossimString("AM"),
+                                         new ossimEllipsoid(ossimString("Modified Airy"), ossimString("AM"), 6377340.189, 6356034.448)));
+      theEllipsoidTable.insert(make_pair(ossimString("AN"),
+                                         new ossimEllipsoid(ossimString("Australian National"), ossimString("AN"), 6378160.000, 6356774.7190)));
+      theEllipsoidTable.insert(make_pair(ossimString("BR"),
+                                         new ossimEllipsoid(ossimString("Bessel 1841"), ossimString("BR"), 6377397.155, 6356078.9630)));
+      theEllipsoidTable.insert(make_pair(ossimString("BN"),
+                                         new ossimEllipsoid(ossimString("Bessel 1841(Namibia)"), ossimString("BN"), 6377483.865, 6356165.3830)));
+      theEllipsoidTable.insert(make_pair(ossimString("CC"),
+                                         new ossimEllipsoid(ossimString("Clarke 1866"), ossimString("CC"), 6378206.400, 6356583.8000)));
+      theEllipsoidTable.insert(make_pair(ossimString("CD"),
+                                         new ossimEllipsoid(ossimString("Clarke 1880"), ossimString("CD"), 6378249.145, 6356514.8700)));
+      theEllipsoidTable.insert(make_pair(ossimString("CE"),
+                                         new ossimEllipsoid(ossimString("Clarke 1880 (IGN)EPSG 7011"), ossimString("CE"), 6378249.200, 6356515.0000)));
+      theEllipsoidTable.insert(make_pair(ossimString("EA"),
+                                         new ossimEllipsoid(ossimString("Everest"), ossimString("EA"), 6377276.345, 6356075.4130)));
+      theEllipsoidTable.insert(make_pair(ossimString("EB"),
+                                         new ossimEllipsoid(ossimString("Everest (E. Malasia, Brunei)"), ossimString("EB"), 6377298.556, 6356097.55)));
+      theEllipsoidTable.insert(make_pair(ossimString("EC"),
+                                         new ossimEllipsoid(ossimString("Everest 1956 (India)"), ossimString("EC"), 6377301.243, 6356100.228)));
+      theEllipsoidTable.insert(make_pair(ossimString("ED"),
+                                         new ossimEllipsoid(ossimString("Everest 1969 (West Malasia)"), ossimString("ED"), 6377295.664, 6356094.668)));
+      theEllipsoidTable.insert(make_pair(ossimString("EE"),
+                                         new ossimEllipsoid(ossimString("Everest 1948(W.Mals. & Sing.)"), ossimString("EE"), 6377304.063, 6356103.039)));
+      theEllipsoidTable.insert(make_pair(ossimString("EF"),
+                                         new ossimEllipsoid(ossimString("Everest (Pakistan)"), ossimString("EF"), 6377309.613, 6356109.571)));
+      theEllipsoidTable.insert(make_pair(ossimString("FA"),
+                                         new ossimEllipsoid(ossimString("Mod. Fischer 1960(South Asia)"), ossimString("FA"), 6378155.0, 6356773.32)));
+      theEllipsoidTable.insert(make_pair(ossimString("RF"),
+                                         new ossimEllipsoid(ossimString("GRS 80"), ossimString("RF"), 6378137.0, 6356752.3141)));
+      theEllipsoidTable.insert(make_pair(ossimString("HE"),
+                                         new ossimEllipsoid(ossimString("Helmert 1906"), ossimString("HE"), 6378200.0, 6356818.17)));
+      theEllipsoidTable.insert(make_pair(ossimString("HO"),
+                                         new ossimEllipsoid(ossimString("Hough"), ossimString("HO"), 6378270.0, 6356794.3430)));
+      theEllipsoidTable.insert(make_pair(ossimString("ID"),
+                                         new ossimEllipsoid(ossimString("Indonesian 1974"), ossimString("ID"), 6378160.0, 6356774.504)));
+      theEllipsoidTable.insert(make_pair(ossimString("IN"),
+                                         new ossimEllipsoid(ossimString("International"), ossimString("IN"), 6378388.0, 6356911.946)));
+      theEllipsoidTable.insert(make_pair(ossimString("KA"),
+                                         new ossimEllipsoid(ossimString("Krassovsky"), ossimString("KA"), 6378245.0, 6356863.0190)));
+      theEllipsoidTable.insert(make_pair(ossimString("SA"),
+                                         new ossimEllipsoid(ossimString("South American 1969"),ossimString("SA"), 6378160.0, 6356774.719)));
+      theEllipsoidTable.insert(make_pair(ossimString("WD"),
+                                         new ossimEllipsoid(ossimString("WGS 72"), ossimString("WD"), 6378135.000, 6356750.5200)));
+      theEllipsoidTable.insert(make_pair(ossimString("WE"),
+                                         new ossimEllipsoid(ossimString("WGS 84"), ossimString("WE"), 6378137.000, 6356752.3142)));
+      theWgs84Ellipsoid = new ossimEllipsoid(ossimString("WGS 84"), ossimString("WE"), 6378137.000, 6356752.3142);
+      theWgs72Ellipsoid = new ossimEllipsoid(ossimString("WGS 72"), ossimString("WD"), 6378135.000, 6356750.5200);
+   }
+   
+#if 0   
+   if(theEllipsoidTable.size()<1)
+   {
+      theEllipsoidTable.insert(make_pair(ossimString("AA"),
+                                         new ossimEllipsoid(ossimString("Airy"), ossimString("AA"), 6377563.396, 6356256.9090, 299.3249646)));   
+      theEllipsoidTable.insert(make_pair(ossimString("AM"),
+                                         new ossimEllipsoid(ossimString("Modified Airy"), ossimString("AM"), 6377340.189, 6356034.448, 299.3249646)));
+      theEllipsoidTable.insert(make_pair(ossimString("AN"),
+                                         new ossimEllipsoid(ossimString("Australian National"), ossimString("AN"), 6378160.000, 6356774.7190, 298.25)));
+      theEllipsoidTable.insert(make_pair(ossimString("BR"),
+                                         new ossimEllipsoid(ossimString("Bessel 1841"), ossimString("BR"), 6377397.155, 6356078.9630, 299.1528128)));
+      theEllipsoidTable.insert(make_pair(ossimString("BN"),
+                                         new ossimEllipsoid(ossimString("Bessel 1841(Namibia)"), ossimString("BN"), 6377483.865, 6356165.3830, 299.1528128)));
+      theEllipsoidTable.insert(make_pair(ossimString("CC"),
+                                         new ossimEllipsoid(ossimString("Clarke 1866"), ossimString("CC"), 6378206.400, 6356583.8000, 294.9786982)));
+      theEllipsoidTable.insert(make_pair(ossimString("CD"),
+                                         new ossimEllipsoid(ossimString("Clarke 1880"), ossimString("CD"), 6378249.145, 6356514.8700, 293.465)));
+      theEllipsoidTable.insert(make_pair(ossimString("EA"),
+                                         new ossimEllipsoid(ossimString("Everest"), ossimString("EA"), 6377276.345, 6356075.4130, 300.8017)));
+      theEllipsoidTable.insert(make_pair(ossimString("EB"),
+                                         new ossimEllipsoid(ossimString("Everest (E. Malasia, Brunei)"), ossimString("EB"), 6377298.556, 6356097.55, 300.8017)));
+      theEllipsoidTable.insert(make_pair(ossimString("EC"),
+                                         new ossimEllipsoid(ossimString("Everest 1956 (India)"), ossimString("EC"), 6377301.243, 6356100.228, 300.8017)));
+      theEllipsoidTable.insert(make_pair(ossimString("ED"),
+                                         new ossimEllipsoid(ossimString("Everest 1969 (West Malasia)"), ossimString("ED"), 6377295.664, 6356094.668, 300.8017)));
+      theEllipsoidTable.insert(make_pair(ossimString("EE"),
+                                         new ossimEllipsoid(ossimString("Everest 1948(W.Mals. & Sing.)"), ossimString("EE"), 6377304.063, 6356103.039, 300.8017)));
+      theEllipsoidTable.insert(make_pair(ossimString("EF"),
+                                         new ossimEllipsoid(ossimString("Everest (Pakistan)"), ossimString("EF"), 6377309.613, 6356109.571, 300.8017)));
+      theEllipsoidTable.insert(make_pair(ossimString("FA"),
+                                         new ossimEllipsoid(ossimString("Mod. Fischer 1960(South Asia)"), ossimString("FA"), 6378155.0, 6356773.32, 298.3)));
+      theEllipsoidTable.insert(make_pair(ossimString("RF"),
+                                         new ossimEllipsoid(ossimString("GRS 80"), ossimString("RF"), 6378137.0, 6356752.3141, 298.257222101)));
+      theEllipsoidTable.insert(make_pair(ossimString("HE"),
+                                         new ossimEllipsoid(ossimString("Helmert 1906"), ossimString("HE"), 6378200.0, 6356818.17, 298.3)));
+      theEllipsoidTable.insert(make_pair(ossimString("HO"),
+                                         new ossimEllipsoid(ossimString("Hough"), ossimString("HO"), 6378270.0, 6356794.3430, 297.0)));
+      theEllipsoidTable.insert(make_pair(ossimString("ID"),
+                                         new ossimEllipsoid(ossimString("Indonesian 1974"), ossimString("ID"), 6378160.0, 6356774.504, 298.247)));
+      theEllipsoidTable.insert(make_pair(ossimString("IN"),
+                                         new ossimEllipsoid(ossimString("International"), ossimString("IN"), 6378388.0, 6356911.946, 297.0)));
+      theEllipsoidTable.insert(make_pair(ossimString("KA"),
+                                         new ossimEllipsoid(ossimString("Krassovsky"), ossimString("KA"), 6378245.0, 6356863.0190, 298.3)));
+      theEllipsoidTable.insert(make_pair(ossimString("SA"),
+                                         new ossimEllipsoid(ossimString("South American 1969"),ossimString("SA"), 6378160.0, 6356774.719, 298.25)));
+      theEllipsoidTable.insert(make_pair(ossimString("WD"),
+                                         new ossimEllipsoid(ossimString("WGS 72"), ossimString("WD"), 6378135.000, 6356750.5200, 298.26)));
+      theEllipsoidTable.insert(make_pair(ossimString("WE"),
+                                         new ossimEllipsoid(ossimString("WGS 84"), ossimString("WE"), 6378137.000, 6356752.3142, 298.257223563)));
+      theWgs84Ellipsoid = new ossimEllipsoid(ossimString("WGS 84"), ossimString("WE"), 6378137.000, 6356752.3142, 298.257223563);
+      theWgs72Ellipsoid = new ossimEllipsoid(ossimString("WGS 72"), ossimString("WD"), 6378135.000, 6356750.5200, 298.26);
+   }
+#endif
+}
+
+void ossimEllipsoidFactory::deleteAll()
+{
+   TableType::const_iterator ellipsoid = theEllipsoidTable.begin();
+   
+   while(ellipsoid != theEllipsoidTable.end())
+   {
+      delete (*ellipsoid).second;
+      ++ellipsoid;
+   }
+
+   theEllipsoidTable.clear();
+}
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimEllipsoidFactory.h b/Utilities/OSSIM/ossim_core/base/factory/ossimEllipsoidFactory.h
new file mode 100644
index 0000000000..0c5ef83855
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimEllipsoidFactory.h
@@ -0,0 +1,58 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Thie file contains the ossimEllipsoidFactory.
+//*******************************************************************
+//  $Id: ossimEllipsoidFactory.h,v 1.2 2002/11/25 19:16:28 gpotts Exp $
+
+#ifndef ossimEllipsoidFactory_HEADER
+#define ossimEllipsoidFactory_HEADER
+#include <map>
+using namespace std;
+#include "base/data_types/ossimString.h"
+class OSSIMDLLEXPORT ossimString;
+class OSSIMDLLEXPORT ossimEllipsoid;
+class OSSIMDLLEXPORT ossimWgs84Ellipsoid;
+class OSSIMDLLEXPORT ossimWgs72Ellipsoid;
+
+class OSSIMDLLEXPORT ossimEllipsoidFactory
+{
+public:
+   typedef map<ossimString, ossimEllipsoid*> TableType;
+   virtual ~ossimEllipsoidFactory();
+   const ossimEllipsoid* create(const ossimString &code)const;
+   const ossimEllipsoid* wgs84()const{return theWgs84Ellipsoid;}
+   const ossimEllipsoid* wgs72()const{return theWgs72Ellipsoid;}
+
+   static ossimEllipsoidFactory* instance();
+   
+private:
+   static ossimEllipsoidFactory*     theInstance;
+   ossimEllipsoid*       theWgs84Ellipsoid;
+   ossimEllipsoid*       theWgs72Ellipsoid;
+   TableType             theEllipsoidTable;
+   ossimEllipsoidFactory();
+   void initializeTable();
+   void deleteAll();
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactory.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactory.cpp
new file mode 100644
index 0000000000..c6915453ff
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactory.cpp
@@ -0,0 +1,4 @@
+#include "ossimObjectFactory.h"
+
+RTTI_DEF1(ossimObjectFactory, "ossimObjectFactory", ossimObject);
+
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactory.h b/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactory.h
new file mode 100644
index 0000000000..225da5adc1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactory.h
@@ -0,0 +1,58 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimObjectFactory.h,v 1.5 2002/11/25 19:16:28 gpotts Exp $
+#ifndef ossimObjectFactory_HEADER
+#define ossimObjectFactory_HEADER
+
+#include "base/common/ossimObject.h"
+
+class OSSIMDLLEXPORT ossimObjectFactory : public ossimObject
+{
+public:
+   virtual ~ossimObjectFactory(){}
+
+   /*!
+    * Creates an object given a type name.
+    */
+   virtual ossimObject* createObject(const ossimString& typeName)const=0;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const=0;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const=0;
+   
+protected:
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactoryRegistry.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactoryRegistry.cpp
new file mode 100644
index 0000000000..f6c83c72bc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactoryRegistry.cpp
@@ -0,0 +1,187 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimObjectFactoryRegistry.cpp,v 1.10 2003/03/27 18:31:43 gpotts Exp $
+
+#include "ossimObjectFactoryRegistry.h"
+
+RTTI_DEF1(ossimObjectFactoryRegistry, "ossimObjectFactoryRegistry", ossimObject);
+#include "ossimObjectFactoryRegistry.h"
+#include "ossimObjectFactory.h"
+#include "ossimBaseObjectFactory.h"
+using namespace std;
+
+ossimObjectFactoryRegistry* ossimObjectFactoryRegistry::theInstance=NULL;
+
+ossimObjectFactoryRegistry::~ossimObjectFactoryRegistry()
+{
+   theInstance = NULL;
+}
+
+ossimObjectFactoryRegistry* ossimObjectFactoryRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimObjectFactoryRegistry;
+   }
+   
+   return theInstance;
+}
+
+bool ossimObjectFactoryRegistry::addFactory(ossimObjectFactory* factory)
+{
+   return registerFactory(factory);
+}
+
+bool ossimObjectFactoryRegistry::registerFactory(ossimObjectFactory* factory)
+{
+   if(factory)
+   {
+      if(!findFactory(factory))
+      {
+         theFactoryList.push_back(factory);
+         return true;
+      }
+      else
+      {
+         return true;
+      }
+   }
+   
+   return false;
+}
+
+void ossimObjectFactoryRegistry::unregisterFactory(ossimObjectFactory* factory)
+{
+   vector<ossimObjectFactory*>::iterator iter = theFactoryList.begin();
+
+   while(iter != theFactoryList.end())
+   {
+      if( (*iter) == factory)
+      {
+         theFactoryList.erase(iter);
+         return;
+      }
+      ++iter;
+   }
+}
+
+ossimObject* ossimObjectFactoryRegistry::createObject(const ossimString& name)const
+{
+   ossimObject* result = NULL;
+   unsigned long index = 0;
+   
+   while((index < theFactoryList.size()) &&(!result))
+   {
+      result = theFactoryList[index]->createObject(name);
+      ++index;
+   }
+   return result;
+}
+
+ossimObject* ossimObjectFactoryRegistry::createObject(const ossimKeywordlist& kwl,
+                                                      const char* prefix)const
+{
+   ossimObject* result = NULL;
+   unsigned long index = 0;
+
+   while((index < theFactoryList.size()) &&(!result))
+   {
+      result = theFactoryList[index]->createObject(kwl,
+                                                   prefix);
+      ++index;
+   }
+
+   return result;
+}
+
+void ossimObjectFactoryRegistry::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   vector<ossimString> result;
+   vector<ossimObjectFactory*>::const_iterator iter = theFactoryList.begin();
+
+   while(iter != theFactoryList.end())
+   {
+      result.clear();
+      (*iter)->getTypeNameList(result);
+
+      typeList.insert(typeList.end(),
+                      result.begin(),
+                      result.end());
+      ++iter;
+   }
+}
+
+ossimObjectFactory* ossimObjectFactoryRegistry::findFactory(ossimObjectFactory* factory)const
+{
+   vector<ossimObjectFactory*>::const_iterator iter = theFactoryList.begin();
+
+   while(iter != theFactoryList.end())
+   {
+      if( (*iter) == factory)
+      {
+         return factory;
+      }
+      ++iter;
+   }
+
+   return NULL;
+}
+
+void ossimObjectFactoryRegistry::getTypeNameList(std::vector<ossimString>& typeList,
+                                                 const ossimString& baseType)const
+{
+   vector<ossimString> allTypeList;
+
+   getTypeNameList(allTypeList);
+
+   if(baseType == "")
+   {
+      typeList.insert(typeList.end(),
+                      allTypeList.begin(),
+                      allTypeList.end());
+   }
+   else
+   {
+      int i = 0;
+      ossimObject* obj = (ossimObject*)NULL;
+      for(i = 0; i < (int)allTypeList.size(); ++i)
+      {
+         obj = createObject(allTypeList[i]);
+         if(obj)
+         {
+            if(obj->canCastTo(baseType))
+            {
+               typeList.push_back(allTypeList[i]);
+            }
+            delete obj;
+            obj = (ossimObject*)NULL;
+         }
+      }
+   }
+}
+
+
+void* ossimObjectFactoryRegistryGetInstance()
+{
+  return ossimObjectFactoryRegistry::instance();
+}
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactoryRegistry.h b/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactoryRegistry.h
new file mode 100644
index 0000000000..ee5f59f56a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimObjectFactoryRegistry.h
@@ -0,0 +1,90 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimObjectFactoryRegistry.h,v 1.10 2003/07/07 16:34:45 gpotts Exp $
+#ifndef ossimObjectFactoryRegistry_HEADER
+#define ossimObjectFactoryRegistry_HEADER
+#include <vector>
+
+#include "base/common/ossimObject.h"
+#include "base/data_types/ossimString.h"
+
+class OSSIMDLLEXPORT ossimObjectFactory;
+class OSSIMDLLEXPORT ossimKeywordlist;
+
+class OSSIMDLLEXPORT ossimObjectFactoryRegistry : public ossimObject
+{
+public:
+   virtual ~ossimObjectFactoryRegistry();
+   static ossimObjectFactoryRegistry* instance();
+   /*!
+    * Should use the registerFactory to add a factory to the list.
+    * This method will call registerFactory.
+    */
+   bool                addFactory(ossimObjectFactory* factory);
+
+   /*!
+    * Registers a factory to the list.
+    */
+   bool                registerFactory(ossimObjectFactory* factory);
+   void                unregisterFactory(ossimObjectFactory* factory);
+   
+   virtual ossimObject* createObject(const ossimString& name)const;
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * Returns a type list of all objects that can be instantiated
+    * through the createObjectMethods above.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /*!
+    * returns a list of objects that are of the passed in
+    * base type.  for example:
+    *
+    *  If I want all ossimImageSource objects then I call:
+    *
+    *  ossimObjectFactoryRegistry::instance()->getTypeNameList(l,
+    *                                                          "ossimImageSource");
+    */ 
+   virtual void getTypeNameList(std::vector<ossimString>& typeList,
+                                const ossimString& baseType)const;
+   
+protected:
+   ossimObjectFactoryRegistry(){}//hide
+   ossimObjectFactoryRegistry(const ossimObjectFactoryRegistry&):ossimObject(){}//hide
+   void operator =(const ossimObjectFactoryRegistry&){}//hide
+   
+   static ossimObjectFactoryRegistry* theInstance;
+   std::vector<ossimObjectFactory*>        theFactoryList;
+
+   ossimObjectFactory* findFactory(ossimObjectFactory* factory)const;
+
+TYPE_DATA
+};
+
+extern "C"
+{
+  OSSIMDLLEXPORT void* ossimObjectFactoryRegistryGetInstance();
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceFactory.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceFactory.cpp
new file mode 100644
index 0000000000..85bffd0d04
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceFactory.cpp
@@ -0,0 +1,5 @@
+#include "base/factory/ossimPropertyInterfaceFactory.h"
+
+RTTI_DEF1( ossimPropertyInterfaceFactory, "ossimPropertyInterfaceFactory", ossimObject );
+
+   
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceFactory.h b/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceFactory.h
new file mode 100644
index 0000000000..df7587193d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceFactory.h
@@ -0,0 +1,48 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimPropertyInterfaceFactory.h,v 1.6 2002/11/25 19:16:28 gpotts Exp $
+#ifndef ossimPropertyInterfaceFactory_HEADER
+#define ossimPropertyInterfaceFactory_HEADER
+
+
+#include "base/common/ossimRtti.h"
+#include "base/factory/ossimObjectFactory.h"
+class OSSIMDLLEXPORT ossimObject;
+class OSSIMDLLEXPORT ossimPropertyInterface;
+
+class OSSIMDLLEXPORT ossimPropertyInterfaceFactory : public ossimObjectFactory
+{
+public:
+   ossimPropertyInterfaceFactory()
+      :ossimObjectFactory()
+      {}
+   virtual ~ossimPropertyInterfaceFactory()
+      {}
+
+   virtual ossimPropertyInterface* createInterface( const ossimObject* obj ) const = 0;
+
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceRegistry.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceRegistry.cpp
new file mode 100644
index 0000000000..f755fa630d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceRegistry.cpp
@@ -0,0 +1,112 @@
+#include "base/factory/ossimPropertyInterfaceRegistry.h"
+#include "base/factory/ossimPropertyInterfaceFactory.h"
+
+using namespace std;
+
+RTTI_DEF1( ossimPropertyInterfaceRegistry, "ossimPropertyInterfaceRegistry", ossimObject );
+
+ossimPropertyInterfaceRegistry* ossimPropertyInterfaceRegistry::theInstance = NULL;
+
+ossimPropertyInterfaceRegistry::~ossimPropertyInterfaceRegistry()
+{
+   theInstance = NULL;
+}
+
+ossimPropertyInterface* ossimPropertyInterfaceRegistry::createInterface( const ossimObject* obj ) const
+{
+   vector<ossimPropertyInterfaceFactory*>::const_iterator i = theFactoryList.begin();
+   ossimPropertyInterface* result = NULL;
+   
+   while ( ( i != theFactoryList.end() ) && ( ! result ) )
+   {
+      result = (*i)->createInterface( obj );
+
+      ++i;
+   }
+
+   return result;
+}
+
+ossimPropertyInterfaceRegistry* ossimPropertyInterfaceRegistry::instance()
+{
+   if ( !theInstance)
+   {
+      theInstance = new ossimPropertyInterfaceRegistry;
+   }
+
+   return theInstance;
+}
+
+ossimObject* ossimPropertyInterfaceRegistry::createObject(const ossimString& typeName)const
+{
+   ossimObject* result = (ossimObject*)NULL;
+   vector<ossimPropertyInterfaceFactory*>::const_iterator i = theFactoryList.begin();
+
+   while ( ( i != theFactoryList.end() ) && ( ! result ) )
+   {
+      result = (*i)->createObject(typeName);
+
+      ++i;
+   }
+   
+   return result;
+}
+
+ossimObject* ossimPropertyInterfaceRegistry::createObject(const ossimKeywordlist& kwl,
+                                                          const char* prefix)const
+{
+   ossimObject* result = (ossimObject*)NULL;
+   vector<ossimPropertyInterfaceFactory*>::const_iterator i = theFactoryList.begin();
+
+   while ( ( i != theFactoryList.end() ) && ( ! result ) )
+   {
+      result = (*i)->createObject(kwl, prefix);
+
+      ++i;
+   }
+   
+   return result;
+}
+
+void ossimPropertyInterfaceRegistry::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   vector<ossimPropertyInterfaceFactory*>::const_iterator i = theFactoryList.begin();
+
+   while ( i != theFactoryList.end() )
+   {
+      std::vector<ossimString> tempTypeList;
+      
+      (*i)->getTypeNameList(tempTypeList);
+      typeList.insert(typeList.end(),
+                      tempTypeList.begin(),
+                      tempTypeList.end());
+      ++i;
+   }
+   
+}
+
+bool ossimPropertyInterfaceRegistry::addFactory( ossimPropertyInterfaceFactory* factory )
+{
+   return registerFactory(factory);
+}
+
+bool ossimPropertyInterfaceRegistry::registerFactory(ossimPropertyInterfaceFactory* factory)
+{
+   bool result = false;
+   
+   if ( factory )
+   {
+      theFactoryList.push_back( factory );
+      result = true;
+   }
+
+   return result;
+}
+
+extern "C"
+{
+  void* ossimPropertyInterfaceRegistryGetInstance()
+  {
+    return ossimPropertyInterfaceRegistry::instance();
+  }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceRegistry.h b/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceRegistry.h
new file mode 100644
index 0000000000..695cc8a8a6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimPropertyInterfaceRegistry.h
@@ -0,0 +1,62 @@
+#ifndef ossimPropertyInterfaceRegistry_HEADER
+#define ossimPropertyInterfaceRegistry_HEADER
+#include "base/factory/ossimObjectFactory.h"
+
+class OSSIMDLLEXPORT ossimPropertyInterfaceFactory;
+class OSSIMDLLEXPORT ossimPropertyInterface;
+
+#include "base/common/ossimRtti.h"
+
+#include <vector>
+using namespace std;
+
+class OSSIMDLLEXPORT ossimPropertyInterfaceRegistry : public ossimObjectFactory
+{
+public:
+   virtual ~ossimPropertyInterfaceRegistry();
+   
+   static ossimPropertyInterfaceRegistry* instance();
+   
+   virtual ossimPropertyInterface* createInterface( const ossimObject* obj ) const;
+
+   /*!
+    * Creates an object given a type name.
+    */
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+   bool addFactory( ossimPropertyInterfaceFactory* factory );
+   bool registerFactory(ossimPropertyInterfaceFactory* factory);
+
+protected:
+   ossimPropertyInterfaceRegistry()
+      :ossimObjectFactory()
+      {}
+
+   ossimPropertyInterfaceRegistry( const ossimPropertyInterfaceRegistry& rhs )
+      :ossimObjectFactory(rhs)
+      {}
+   void operator =(const ossimPropertyInterfaceRegistry&){}
+   static ossimPropertyInterfaceRegistry* theInstance;
+   vector<ossimPropertyInterfaceFactory*> theFactoryList;
+
+TYPE_DATA
+};
+
+extern "C"
+{
+  OSSIMDLLEXPORT void* ossimPropertyInterfaceRegistryGetInstance();
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactory.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactory.cpp
new file mode 100644
index 0000000000..afa602fbe5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactory.cpp
@@ -0,0 +1,82 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//
+//*******************************************************************
+//  $Id: ossimStreamFactory.cpp,v 1.4 2005/11/14 13:47:01 gpotts Exp $
+//
+#include "ossimStreamFactory.h"
+#include <fstream>
+#include <ossimConfig.h>
+#if OSSIM_HAS_LIBZ
+#include <base/common/ossimGzStream.h>
+#endif 
+
+ossimStreamFactory* ossimStreamFactory::theInstance = 0;
+
+ossimStreamFactory::ossimStreamFactory()
+{
+}
+
+ossimStreamFactory::~ossimStreamFactory()
+{
+}
+
+ossimStreamFactory* ossimStreamFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimStreamFactory;
+   }
+
+   return theInstance;
+}
+
+ossimRefPtr<ossimIStream> ossimStreamFactory::createNewInputStream(const ossimFilename& file,
+																   std::ios::openmode openMode)
+{
+#if OSSIM_HAS_LIBZ
+   ossimFilename copyFile = file;
+
+   if(!copyFile.exists())
+   {
+      ossimString ext = copyFile.ext();
+      copyFile.setExtension("gz");
+      if(!copyFile.exists())
+      {
+         copyFile.setExtension(ext);
+         copyFile += ".gz";
+
+         if(!copyFile.exists())
+         {
+            return false;
+         }
+      }
+   }
+   
+   std::ifstream in(copyFile.c_str(), std::ios::in|std::ios::binary);
+
+   if(!in) return 0;
+
+   unsigned char buf[2];
+
+   in.read((char*)buf, 2);
+   in.close();
+   // check for gzip magic number
+   //
+   if((buf[0] == 0x1F) &&
+      (buf[1] == 0x8B))
+   {
+      return new ossimIgzStream(copyFile.c_str(),
+                                openMode);
+   }
+#endif
+   return 0;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactory.h b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactory.h
new file mode 100644
index 0000000000..844ee4cc6a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactory.h
@@ -0,0 +1,35 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//
+//*******************************************************************
+//  $Id: ossimStreamFactory.h,v 1.3 2005/11/14 13:47:01 gpotts Exp $
+//
+#ifndef ossimStreamFactory_HEADER
+#define ossimStreamFactory_HEADER
+#include "ossimStreamFactoryBase.h"
+
+class OSSIM_DLL ossimStreamFactory : public ossimStreamFactoryBase
+{
+public:
+   static ossimStreamFactory* instance();
+   virtual ~ossimStreamFactory();
+ 
+   virtual ossimRefPtr<ossimIStream> createNewInputStream(const ossimFilename& file,
+	   std::ios::openmode openMode);
+
+   
+protected:
+   ossimStreamFactory();
+   ossimStreamFactory(const ossimStreamFactory&){}
+   static ossimStreamFactory* theInstance;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryBase.h b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryBase.h
new file mode 100644
index 0000000000..d6d1be7d73
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryBase.h
@@ -0,0 +1,32 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//
+//*******************************************************************
+//  $Id: ossimStreamFactoryBase.h,v 1.5 2005/11/14 13:47:01 gpotts Exp $
+//
+#ifndef ossimStreamFactoryBase_HEADER
+#define ossimStreamFactoryBase_HEADER
+#include <iostream>
+#include <base/common/ossimIoStream.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimFilename.h>
+
+class OSSIM_DLL ossimStreamFactoryBase
+{
+public:
+   virtual ~ossimStreamFactoryBase(){}
+   
+   virtual ossimRefPtr<ossimIStream> createNewInputStream(
+      const ossimFilename& file,
+	  std::ios::openmode openMode)=0;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryRegistry.cpp b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryRegistry.cpp
new file mode 100644
index 0000000000..0e78e69f45
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryRegistry.cpp
@@ -0,0 +1,71 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//
+//*******************************************************************
+//  $Id: ossimStreamFactoryRegistry.cpp,v 1.3 2005/11/14 13:47:01 gpotts Exp $
+//
+#include "ossimStreamFactoryRegistry.h"
+#include "ossimStreamFactory.h"
+#include <fstream>
+#include <algorithm>
+
+ossimStreamFactoryRegistry* ossimStreamFactoryRegistry::theInstance = 0;
+
+ossimStreamFactoryRegistry::ossimStreamFactoryRegistry()
+{
+}
+
+ossimStreamFactoryRegistry::~ossimStreamFactoryRegistry()
+{
+}
+
+ossimStreamFactoryRegistry* ossimStreamFactoryRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimStreamFactoryRegistry;
+      theInstance->registerFactory(ossimStreamFactory::instance());
+   }
+
+   return theInstance;
+}
+
+ossimRefPtr<ossimIStream> ossimStreamFactoryRegistry::createNewInputStream(const ossimFilename& file,
+																		   std::ios::openmode openMode)
+{
+   ossim_uint32 idx = 0;
+   ossimRefPtr<ossimIStream> result = 0;
+   for(idx = 0; ((idx < theFactoryList.size())&&(!result)); ++idx)
+   {
+      result = theFactoryList[idx]->createNewInputStream(file, openMode);
+   }
+
+   if(!result)
+   {
+      result = new ossimIFStream(file.c_str(),
+                                 openMode);
+//       result = new std::ifstream(file.c_str(),
+//                                  openMode);
+   }
+   
+   return result;
+}
+
+
+void ossimStreamFactoryRegistry::registerFactory(ossimStreamFactoryBase* factory)
+{
+   std::vector<ossimStreamFactoryBase*>::iterator iter = std::find(theFactoryList.begin(),
+                                                                  theFactoryList.end(),
+                                                                  factory);
+   if(iter == theFactoryList.end())
+   {
+      theFactoryList.push_back(factory);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryRegistry.h b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryRegistry.h
new file mode 100644
index 0000000000..be064fed19
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/factory/ossimStreamFactoryRegistry.h
@@ -0,0 +1,38 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//
+//*******************************************************************
+//  $Id: ossimStreamFactoryRegistry.h,v 1.3 2005/11/14 13:47:01 gpotts Exp $
+//
+#ifndef ossimStreamFactoryRegistry_HEADER
+#define ossimStreamFactoryRegistry_HEADER
+#include "ossimStreamFactoryBase.h"
+#include <vector>
+
+class OSSIM_DLL ossimStreamFactoryRegistry : public ossimStreamFactoryBase
+{
+public:
+   static ossimStreamFactoryRegistry* instance();
+   virtual ~ossimStreamFactoryRegistry();
+   
+   void registerFactory(ossimStreamFactoryBase* factory);
+   
+   virtual ossimRefPtr<ossimIStream> createNewInputStream(const ossimFilename& file,
+	   std::ios::openmode openMode);
+   
+protected:
+   ossimStreamFactoryRegistry();
+private:
+   ossimStreamFactoryRegistry(const ossimStreamFactoryRegistry&){}
+   std::vector<ossimStreamFactoryBase*> theFactoryList;
+   static ossimStreamFactoryRegistry* theInstance;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/.cvsignore b/Utilities/OSSIM/ossim_core/base/misc/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/base/misc/FlexLexer.h b/Utilities/OSSIM/ossim_core/base/misc/FlexLexer.h
new file mode 100644
index 0000000000..8c1defd17c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/FlexLexer.h
@@ -0,0 +1,188 @@
+// $Header: /cvs/ossim/src/ossim_core/base/misc/FlexLexer.h,v 1.4 2004/03/19 18:31:47 gpotts Exp $
+
+// FlexLexer.h -- define interfaces for lexical analyzer classes generated
+//		  by flex
+
+// Copyright (c) 1993 The Regents of the University of California.
+// All rights reserved.
+//
+// This code is derived from software contributed to Berkeley by
+// Kent Williams and Tom Epperly.
+//
+// Redistribution and use in source and binary forms with or without
+// modification are permitted provided that: (1) source distributions retain
+// this entire copyright notice and comment, and (2) distributions including
+// binaries display the following acknowledgement:  ``This product includes
+// software developed by the University of California, Berkeley and its
+// contributors'' in the documentation or other materials provided with the
+// distribution and in all advertising materials mentioning features or use
+// of this software.  Neither the name of the University nor the names of
+// its contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+
+// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+// This file defines FlexLexer, an abstract class which specifies the
+// external interface provided to flex C++ lexer objects, and yyFlexLexer,
+// which defines a particular lexer class.
+//
+// If you want to create multiple lexer classes, you use the -P flag
+// to rename each yyFlexLexer to some other xxFlexLexer.  You then
+// include <FlexLexer.h> in your other sources once per lexer class:
+//
+//	#undef yyFlexLexer
+//	#define yyFlexLexer xxFlexLexer
+//	#include <FlexLexer.h>
+//
+//	#undef yyFlexLexer
+//	#define yyFlexLexer zzFlexLexer
+//	#include <FlexLexer.h>
+//	...
+
+#ifndef __FLEX_LEXER_H
+// Never included before - need to define base class.
+#define __FLEX_LEXER_H
+#include <iostream>
+#include "base/common/ossimConstants.h"
+using namespace std;
+
+extern "C++" {
+
+struct yy_buffer_state;
+typedef int yy_state_type;
+
+class OSSIMDLLEXPORT FlexLexer {
+public:
+	virtual ~FlexLexer()	{ }
+
+	const char* YYText()	{ return yytext; }
+	int YYLeng()		{ return yyleng; }
+
+	virtual void
+		yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
+	virtual struct yy_buffer_state*
+		yy_create_buffer( istream* s, int size ) = 0;
+	virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
+	virtual void yyrestart( istream* s ) = 0;
+
+	virtual int yylex() = 0;
+
+	// Call yylex with new input/output sources.
+	int yylex( istream* new_in, ostream* new_out = 0 )
+		{
+		switch_streams( new_in, new_out );
+		return yylex();
+		}
+
+	// Switch to new input/output streams.  A nil stream pointer
+	// indicates "keep the current one".
+	virtual void switch_streams( istream* new_in = 0,
+					ostream* new_out = 0 ) = 0;
+
+	int lineno() const		{ return yylineno; }
+
+	int debug() const		{ return yy_flex_debug; }
+	void set_debug( int flag )	{ yy_flex_debug = flag; }
+
+protected:
+	char* yytext;
+	int yyleng;
+	int yylineno;		// only maintained if you use %option yylineno
+	int yy_flex_debug;	// only has effect with -d or "%option debug"
+};
+
+}
+#endif
+
+#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
+// Either this is the first time through (yyFlexLexerOnce not defined),
+// or this is a repeated include to define a different flavor of
+// yyFlexLexer, as discussed in the flex man page.
+#define yyFlexLexerOnce
+
+class OSSIMDLLEXPORT yyFlexLexer : public FlexLexer {
+public:
+	// arg_yyin and arg_yyout default to the cin and cout, but we
+	// only make that assignment when initializing in yylex().
+	yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 );
+
+	virtual ~yyFlexLexer();
+
+	void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
+	struct yy_buffer_state* yy_create_buffer( istream* s, int size );
+	void yy_delete_buffer( struct yy_buffer_state* b );
+	void yyrestart( istream* s );
+
+	virtual int yylex();
+	virtual void switch_streams( istream* new_in, ostream* new_out );
+
+protected:
+	virtual int LexerInput( char* buf, int max_size );
+	virtual void LexerOutput( const char* buf, int size );
+	virtual void LexerError( const char* msg );
+
+	void yyunput( int c, char* buf_ptr );
+	int yyinput();
+
+	void yy_load_buffer_state();
+	void yy_init_buffer( struct yy_buffer_state* b, istream* s );
+	void yy_flush_buffer( struct yy_buffer_state* b );
+
+	int yy_start_stack_ptr;
+	int yy_start_stack_depth;
+	int* yy_start_stack;
+
+	void yy_push_state( int new_state );
+	void yy_pop_state();
+	int yy_top_state();
+
+	yy_state_type yy_get_previous_state();
+	yy_state_type yy_try_NUL_trans( yy_state_type current_state );
+	int yy_get_next_buffer();
+
+	istream* yyin;	// input source for default LexerInput
+	ostream* yyout;	// output sink for default LexerOutput
+
+	struct yy_buffer_state* yy_current_buffer;
+
+	// yy_hold_char holds the character lost when yytext is formed.
+	char yy_hold_char;
+
+	// Number of characters read into yy_ch_buf.
+	int yy_n_chars;
+
+	// Points to current character in buffer.
+	char* yy_c_buf_p;
+
+	int yy_init;		// whether we need to initialize
+	int yy_start;		// start state number
+
+	// Flag which is used to allow yywrap()'s to do buffer switches
+	// instead of setting up a fresh yyin.  A bit of a hack ...
+	int yy_did_buffer_switch_on_eof;
+
+	// The following are not always needed, but may be depending
+	// on use of certain flex features (like REJECT or yymore()).
+
+	yy_state_type yy_last_accepting_state;
+	char* yy_last_accepting_cpos;
+
+	yy_state_type* yy_state_buf;
+	yy_state_type* yy_state_ptr;
+
+	char* yy_full_match;
+	int* yy_full_state;
+	int yy_full_lp;
+
+	int yy_lp;
+	int yy_looking_for_trail_begin;
+
+	int yy_more_flag;
+	int yy_more_len;
+	int yy_more_offset;
+	int yy_prev_more_offset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/hash/.cvsignore b/Utilities/OSSIM/ossim_core/base/misc/hash/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/hash/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/base/misc/hash/ossimPointHash.h b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimPointHash.h
new file mode 100644
index 0000000000..f478836595
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimPointHash.h
@@ -0,0 +1,28 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description: Point Hash is a base for hashing functions
+//              
+//*******************************************************************
+//  $Id: ossimPointHash.h,v 1.3 2005/07/15 19:16:59 dburken Exp $
+
+#ifndef ossimPointHash_HEADER
+#define ossimPointHash_HEADER
+#include "base/data_types/ossimDpt.h"
+#include "base/data_types/ossimFpt.h"
+
+class OSSIMDLLEXPORT ossimPointHash
+{
+public:
+   virtual ~ossimPointHash(){}
+   virtual long operator ()(const ossimDpt &aPoint)=0;
+   virtual long operator ()(const ossimFpt &aPoint)=0;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTileHash.cpp b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTileHash.cpp
new file mode 100644
index 0000000000..53151502a9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTileHash.cpp
@@ -0,0 +1,123 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken Copied from TiledImageHash.
+//
+// Description: Hashing function for tiled rectangles.  WIll hash a
+//              dpt or a to a single index value.
+//
+// NOTE:  This works with rectangles that are positive in the line up
+//        (y) direction.
+//              
+//*******************************************************************
+//  $Id: ossimTileHash.cpp,v 1.3 2005/07/15 19:25:10 dburken Exp $
+
+#include <cfloat> // for FLT_EPSILON
+
+#include <base/misc/hash/ossimTileHash.h>
+
+ossimTileHash::ossimTileHash(const ossimDrect& imageRect,
+                             double tileWidth,
+                             double tileHeight)
+   :
+      ossimPointHash(),
+      theImageRect(imageRect)
+{
+   // make sure that the width of the tile is not larger than
+   // the width of the image rectangle.
+   if(theImageRect.width() <= tileWidth)
+   {
+      theTileWidth = theImageRect.width();
+      theNumberOfHorizTiles = 1;
+   }
+   else
+   {
+      theTileWidth          = tileWidth;
+      double tempDiv        = theImageRect.width()/theTileWidth;
+      double overFlow       = tempDiv  - static_cast<long>(tempDiv);
+      theNumberOfHorizTiles = static_cast<long>(tempDiv);
+      
+      if(fabs(overFlow) > FLT_EPSILON) // if the extent went beyond a tile
+      {
+         theNumberOfHorizTiles ++;      // we must say it has another tile
+      }
+   }
+
+   // make sure the height of the tile is not larger than the
+   // height of the image rectangle.
+   if(theImageRect.height() <= tileHeight)
+   {
+      theTileHeight = theImageRect.height();
+      theNumberOfVertTiles = 1;
+   }
+   else
+   {
+      theTileHeight         = tileHeight;
+      double tempDiv        = theImageRect.height()/theTileHeight;
+      double overFlow       = tempDiv  - static_cast<long>(tempDiv);
+      theNumberOfVertTiles = static_cast<long>(tempDiv);
+
+      if(fabs(overFlow) > FLT_EPSILON) // if the extent went beyond a tile
+      {
+         theNumberOfVertTiles ++;      // we must say it has another tile
+      }
+   }
+}
+
+ossimTileHash::~ossimTileHash()
+{
+}
+
+long ossimTileHash::operator()(const ossimFpt& aPoint)
+{
+   if ( (aPoint.x >= theImageRect.ul().x) &&
+        (aPoint.x <= theImageRect.lr().x) &&
+        (aPoint.y <= theImageRect.ul().y) &&
+        (aPoint.y >= theImageRect.lr().y) )
+   {
+      // how far is the point horizontally  from the upper left corner
+      double deltaWidth  = aPoint.x - theImageRect.ul().x;
+
+      // how far is the point vertically from the upper left point
+      double deltaHeight = theImageRect.ul().y - aPoint.y;
+
+      // solve the horizontal and vertical index numbers
+      long indexWidth  = static_cast<long>(deltaWidth  / theTileWidth);
+      long indexHeight = static_cast<long>(deltaHeight / theTileHeight);
+
+      // Map to a linear array.
+      // Just like you would index a 2-D array in memory
+      return static_cast<long>(theNumberOfHorizTiles*indexHeight + indexWidth);
+   }
+
+   return -1;
+}
+
+long ossimTileHash::operator()(const ossimDpt& aPoint)
+{
+   if ( (aPoint.x >= theImageRect.ul().x) &&
+        (aPoint.x <= theImageRect.lr().x) &&
+        (aPoint.y <= theImageRect.ul().y) &&
+        (aPoint.y >= theImageRect.lr().y) )
+   {
+      // how far is the point horizontally  from the upper left corner
+      double deltaWidth  = aPoint.x - theImageRect.ul().x;
+
+      // how far is the point vertically from the upper left point
+      double deltaHeight = theImageRect.ul().y - aPoint.y;
+
+      // solve the horizontal and vertical index numbers
+      long indexWidth  = static_cast<long>(deltaWidth  / theTileWidth);
+      long indexHeight = static_cast<long>(deltaHeight / theTileHeight);
+
+      // Map to a linear array.
+      // Just like you would index a 2-D array in memory
+      return static_cast<long>(theNumberOfHorizTiles*indexHeight + indexWidth);
+   }
+
+   return -1;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTileHash.h b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTileHash.h
new file mode 100644
index 0000000000..456f509e0a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTileHash.h
@@ -0,0 +1,46 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken Copied from TiledImageHash.
+//
+// Description: Hashing function for tiled rectangles.  Will hash a
+//              dpt or fpt to a single index value.
+//
+// NOTE:  Works on rectangles that are positive in the line up (y)
+//        direction.  Use TiledImageHash for rectangles that are positive
+//        in the line down direction.
+//              
+//*******************************************************************
+//  $Id: ossimTileHash.h,v 1.4 2005/07/15 19:25:46 dburken Exp $
+
+#ifndef TileHash_HEADER
+#define TileHash_HEADER
+
+#include <base/data_types/ossimDrect.h>
+#include <base/misc/hash/ossimPointHash.h>
+
+class OSSIMDLLEXPORT ossimTileHash : public ossimPointHash
+{
+public:
+   ossimTileHash(const ossimDrect &imageRect,
+                 double tileWidth,
+                 double tileHeight);
+
+   virtual ~ossimTileHash();
+
+   virtual long operator()(const ossimDpt &aPoint);
+   virtual long operator()(const ossimFpt &aPoint);
+   
+private:
+   ossimDrect   theImageRect;
+   double  theTileWidth;
+   double  theTileHeight;
+   long    theNumberOfHorizTiles;
+   long    theNumberOfVertTiles;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTiledImageHash.cpp b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTiledImageHash.cpp
new file mode 100644
index 0000000000..d07fdd56ae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTiledImageHash.cpp
@@ -0,0 +1,140 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description: Hashing function for tiled rectangles.  WIll hash a
+//              dpt to a single index value.
+//              
+//*******************************************************************
+//  $Id: ossimTiledImageHash.cpp,v 1.2 2005/07/15 19:16:59 dburken Exp $
+
+#include <cfloat> // for FLT_EPSILON
+
+#include <base/misc/hash/ossimTiledImageHash.h>
+
+
+ossimTiledImageHash::ossimTiledImageHash(const ossimDrect &imageRect,
+                                         double tileWidth,
+                                         double tileHeight)
+   :ossimPointHash(),
+    theImageRect(imageRect)
+{
+   // make sure that the width of the tile is not larger than
+   // the width of the image rectangle.
+   if(theImageRect.width() < tileWidth)
+   {
+      theTileWidth = theImageRect.width();
+      theNumberOfHorizTiles = 1;
+   }
+   else
+   {
+      theTileWidth          = tileWidth;
+      double tempDiv        = theImageRect.width()/theTileWidth;
+      double overFlow       = tempDiv  - static_cast<long>(tempDiv);
+      theNumberOfHorizTiles = static_cast<long>(tempDiv);
+      
+      if(fabs(overFlow) >= FLT_EPSILON) // if the extent went beyond a tile
+      {
+         theNumberOfHorizTiles ++;      // we must say it has another tile
+      }
+   }
+
+   // make sure the height of the tile is not larger than the
+   // height of the image rectangle.
+   if(theImageRect.height() < tileHeight)
+   {
+      theTileHeight = theImageRect.height();
+      theNumberOfVertTiles = 1;
+   }
+   else
+   {
+      theTileHeight         = tileHeight;
+      double tempDiv        = theImageRect.height()/theTileHeight;
+      double overFlow       = tempDiv  - static_cast<long>(tempDiv);
+      theNumberOfVertTiles = static_cast<long>(tempDiv);
+
+      if(fabs(overFlow) >= FLT_EPSILON) // if the extent went beyond a tile
+      {
+         theNumberOfVertTiles ++;      // we must say it has another tile
+      }
+   }
+
+}
+
+ossimTiledImageHash::~ossimTiledImageHash()
+{
+}
+
+long ossimTiledImageHash::operator()(const ossimDpt &aPoint)
+{
+   if(aPoint.x >= theImageRect.ul().x && aPoint.y >= theImageRect.ul().y)
+   {
+      // how far is the point horizontally  from the upper left corner
+      double deltaWidth  = aPoint.x - theImageRect.ul().x;
+
+      // how far is the point vertically from the upper left point
+      double deltaHeight = aPoint.y - theImageRect.ul().y;
+
+      // if deltas are negative then we are outside the
+      // bounds
+      if((deltaWidth < 0) || (deltaHeight < 0)) 
+      {
+         return -1;
+      }
+
+      // check if outside the rectangle
+      if( (deltaWidth > theNumberOfHorizTiles*theTileWidth)||
+          (deltaHeight > theNumberOfVertTiles*theTileHeight))
+      {
+         return -1;
+      }
+      // solve the horizontal and vertical index numbers
+      long indexWidth  = static_cast<long>(deltaWidth  / theTileWidth);
+      long indexHeight = static_cast<long>(deltaHeight / theTileHeight);
+
+      // map to a linear array.  Just like you would index a 2-D array in memory
+      return static_cast<long>(theNumberOfHorizTiles*indexHeight + indexWidth);
+   }
+
+   return -1;
+}
+
+long ossimTiledImageHash::operator()(const ossimFpt &aPoint)
+{
+   if(aPoint.x >= theImageRect.ul().x && aPoint.y >= theImageRect.ul().y)
+   {
+      // how far is the point horizontally  from the upper left corner
+      double deltaWidth  = aPoint.x - theImageRect.ul().x;
+
+      // how far is the point vertically from the upper left point
+      double deltaHeight = aPoint.y - theImageRect.ul().y;
+
+      // if deltas are negative then we are outside the
+      // bounds
+      if((deltaWidth < 0) || (deltaHeight < 0)) 
+      {
+         return -1;
+      }
+
+      // check if outside the rectangle
+      if( (deltaWidth > theNumberOfHorizTiles*theTileWidth)||
+          (deltaHeight > theNumberOfVertTiles*theTileHeight))
+      {
+         return -1;
+      }
+      // solve the horizontal and vertical index numbers
+      long indexWidth  = static_cast<long>(deltaWidth  / theTileWidth);
+      long indexHeight = static_cast<long>(deltaHeight / theTileHeight);
+
+      // map to a linear array.  Just like you would index a 2-D array in memory
+      return static_cast<long>(theNumberOfHorizTiles*indexHeight + indexWidth);
+   }
+
+   return -1;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTiledImageHash.h b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTiledImageHash.h
new file mode 100644
index 0000000000..b142a4e042
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/hash/ossimTiledImageHash.h
@@ -0,0 +1,40 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description: Hashing function for tiled rectangles.  Will hash a
+//              dpt to a single index value.
+//              
+//*******************************************************************
+//  $Id: ossimTiledImageHash.h,v 1.3 2005/07/15 19:16:59 dburken Exp $
+#ifndef ossimTiledImageHash_HEADER
+#define ossimTiledImageHash_HEADER
+#include "base/data_types/ossimDrect.h"
+#include "ossimPointHash.h"
+
+class OSSIMDLLEXPORT ossimTiledImageHash : public ossimPointHash
+{
+public:
+   ossimTiledImageHash(const ossimDrect &imageRect,
+                       double tileWidth,
+                       double tileHeight);
+
+   virtual ~ossimTiledImageHash();
+
+   virtual long operator()(const ossimDpt &aPoint);
+   virtual long operator()(const ossimFpt &aPoint);
+   
+private:
+   ossimDrect   theImageRect;
+   double  theTileWidth;
+   double  theTileHeight;
+   long    theNumberOfHorizTiles;
+   long    theNumberOfVertTiles;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/.cvsignore b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffCoordTransformsLut.cpp b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffCoordTransformsLut.cpp
new file mode 100644
index 0000000000..de0b0a2981
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffCoordTransformsLut.cpp
@@ -0,0 +1,97 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class definition for ossimGeoTiffCoordTransformsLut.
+//*******************************************************************
+//  $Id: ossimGeoTiffCoordTransformsLut.cpp,v 1.2 2001/06/29 21:01:26 dburken Exp $
+
+#include "ossimGeoTiffCoordTransformsLut.h"
+#include "base/data_types/ossimString.h"
+
+static const int TABLE_SIZE = 27;
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimGeoTiffCoordTransformsLut::ossimGeoTiffCoordTransformsLut()
+   :
+      ossimLookUpTable(TABLE_SIZE)
+{
+   //***
+   // Complete initialization of data member "theTable".
+   // Note:  Scalar types defined in constants.h file.
+   //***
+   theTable[0].theKey    = CT_TransverseMercator;
+   theTable[0].theValue  = "ossimTransMercatorProjection";
+   theTable[1].theKey    = CT_TransvMercator_Modified_Alaska;
+   theTable[1].theValue  = "unknown";
+   theTable[2].theKey    = CT_ObliqueMercator;
+   theTable[2].theValue  = "unknown";
+   theTable[3].theKey    = CT_ObliqueMercator_Laborde;
+   theTable[3].theValue  = "unknown";
+   theTable[4].theKey    = CT_ObliqueMercator_Rosenmund;
+   theTable[4].theValue  = "unknown";   
+   theTable[5].theKey    = CT_ObliqueMercator_Spherical;
+   theTable[5].theValue  = "unknown";   
+   theTable[6].theKey    = CT_Mercator;
+   theTable[6].theValue  = "ossimMercatorProjection";
+   theTable[7].theKey    = CT_LambertConfConic_2SP;
+   theTable[7].theValue  = "ossimLambertConformalConicProjection";
+   theTable[8].theKey    = CT_LambertConfConic_Helmert;
+   theTable[8].theValue  = "unknown";
+   theTable[9].theKey    = CT_LambertAzimEqualArea;
+   theTable[9].theValue  = "unknown";
+   theTable[10].theKey   = CT_AlbersEqualArea;
+   theTable[10].theValue = "ossimAlbersProjection";
+   theTable[11].theKey   = CT_AzimuthalEquidistant;
+   theTable[11].theValue = "unknown";
+   theTable[12].theKey   = CT_EquidistantConic;
+   theTable[12].theValue = "unknown";
+   theTable[13].theKey   = CT_Stereographic;
+   theTable[13].theValue = "unknown";
+   theTable[14].theKey   = CT_PolarStereographic;
+   theTable[14].theValue = "ossimPolarStereoProjection";
+   theTable[15].theKey   = CT_ObliqueStereographic;
+   theTable[15].theValue = "ossimPolarStereoProjection";
+   theTable[16].theKey   = CT_Equirectangular;
+   theTable[16].theValue = "ossimEquDistCylProjection";
+   theTable[17].theKey   = CT_CassiniSoldner;
+   theTable[17].theValue = "ossimCassiniProjection";
+   theTable[18].theKey   = CT_Gnomonic;
+   theTable[18].theValue = "unknown";
+   theTable[19].theKey   = CT_MillerCylindrical;
+   theTable[19].theValue = "ossimMillerProjection";
+   theTable[20].theKey   = CT_Orthographic;
+   theTable[20].theValue = "ossimOrthoGraphicProjection";
+   theTable[21].theKey   = CT_Polyconic;
+   theTable[21].theValue = "ossimPolyconicrojection";
+   theTable[22].theKey   = CT_Robinson;
+   theTable[22].theValue = "unkknown";
+   theTable[23].theKey   = CT_Sinusoidal;
+   theTable[23].theValue = "ossimSinusoidalProjection";
+   theTable[24].theKey   = CT_VanDerGrinten;
+   theTable[24].theValue = "ossimVanDerGrintenProjection";
+   theTable[25].theKey   = CT_NewZealandMapGrid;
+   theTable[25].theValue = "unknown";
+   theTable[26].theKey   = CT_TransvMercator_SouthOriented;
+   theTable[26].theValue = "unknown";
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffCoordTransformsLut.h b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffCoordTransformsLut.h
new file mode 100644
index 0000000000..cbb2799618
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffCoordTransformsLut.h
@@ -0,0 +1,81 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for GeoTiffCoordTransformsLut. Used to map a
+// geotiff coordinate transformation code to an ossim projection.
+//*******************************************************************
+//  $Id: ossimGeoTiffCoordTransformsLut.h,v 1.2 2002/11/25 19:16:28 gpotts Exp $
+
+#ifndef ossimGeoTiffCoordTransformsLut_HEADER
+#define ossimGeoTiffCoordTransformsLut_HEADER
+
+#include "ossimLookUpTable.h"
+#include "base/common/ossimKeywordNames.h"
+
+class OSSIMDLLEXPORT ossimGeoTiffCoordTransformsLut : public ossimLookUpTable
+{
+public:
+
+   enum
+   {
+      //***
+      // Coordinate Transformation Codes cut from geotiff specification
+      // section 6.3.3.3.
+      //***
+      CT_TransverseMercator             = 1,
+      CT_TransvMercator_Modified_Alaska = 2,
+      CT_ObliqueMercator                = 3,
+      CT_ObliqueMercator_Laborde        = 4,
+      CT_ObliqueMercator_Rosenmund      = 5,
+      CT_ObliqueMercator_Spherical      = 6,
+      CT_Mercator                       = 7,
+      CT_LambertConfConic_2SP           = 8,
+      CT_LambertConfConic_Helmert       = 9,
+      CT_LambertAzimEqualArea           = 10,
+      CT_AlbersEqualArea                = 11,
+      CT_AzimuthalEquidistant           = 12,
+      CT_EquidistantConic               = 13,
+      CT_Stereographic                  = 14,
+      CT_PolarStereographic             = 15,
+      CT_ObliqueStereographic           = 16,
+      CT_Equirectangular                = 17,
+      CT_CassiniSoldner                 = 18,
+      CT_Gnomonic                       = 19,
+      CT_MillerCylindrical              = 20,
+      CT_Orthographic                   = 21,
+      CT_Polyconic                      = 22,
+      CT_Robinson                       = 23,
+      CT_Sinusoidal                     = 24,
+      CT_VanDerGrinten                  = 25,
+      CT_NewZealandMapGrid              = 26,
+      CT_TransvMercator_SouthOriented   = 27
+   };
+   
+   ossimGeoTiffCoordTransformsLut();
+
+   virtual ~ossimGeoTiffCoordTransformsLut(){}
+   
+   virtual ossimKeyword getKeyword() const
+      { return ossimKeyword("geotiff_coordinate_transform_code", ""); }
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffDatumLut.cpp b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffDatumLut.cpp
new file mode 100644
index 0000000000..666cf55513
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffDatumLut.cpp
@@ -0,0 +1,116 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for ossimGeoTiffDatumLut.
+//*******************************************************************
+//  $Id: ossimGeoTiffDatumLut.cpp,v 1.4 2005/01/21 18:55:19 dburken Exp $
+
+#include "ossimGeoTiffDatumLut.h"
+#include "base/data_types/ossimString.h"
+
+static const int TABLE_SIZE = 24;
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimGeoTiffDatumLut::ossimGeoTiffDatumLut()
+   :
+      ossimLookUpTable(TABLE_SIZE)
+{
+   //***
+   // Complete initialization of data member "theTable".
+   // Note:  Scalar types defined in constants.h file.
+   //***
+   theTable[0].theKey    = GCS_Adindan;
+   theTable[0].theValue  = "ADI-M";
+   
+   theTable[1].theKey    = GCS_Arc_1950;
+   theTable[1].theValue  = "ARF-M";
+   
+   theTable[2].theKey    = GCS_Arc_1960;
+   theTable[2].theValue  = "ARS-M";
+   
+   theTable[3].theKey    = GCS_ED50;
+   theTable[3].theValue  = "EUR-M";
+   
+   theTable[4].theKey    = GCS_NAD27;
+   theTable[4].theValue  = "NAS-C";
+   
+   theTable[5].theKey    = GCS_NAD83;
+   theTable[5].theValue  = "NAR-C";
+   
+   theTable[6].theKey    = GCS_OSGB_1936;
+   theTable[6].theValue  = "OGB-M";
+   
+   theTable[7].theKey    = GCS_WGS_72;
+   theTable[7].theValue  = "WGD";
+   
+   theTable[8].theKey    = GCS_WGS_84;
+   theTable[8].theValue  = "WGE";
+   
+   theTable[9].theKey    = GCS_Tokyo;
+   theTable[9].theValue  = "TOY-M";
+   
+   theTable[10].theKey   = DatumE_WGS84;
+   theTable[10].theValue = "WGE";
+   
+   theTable[11].theKey   = Datum_Adindan;
+   theTable[11].theValue = "ADI-M";
+   
+   theTable[12].theKey   = Datum_Arc_1950;
+   theTable[12].theValue = "ARF-M";
+   
+   theTable[13].theKey   = Datum_Arc_1960;
+   theTable[13].theValue = "ARS-M";
+   
+   theTable[14].theKey   = Datum_European_Datum_1950;
+   theTable[14].theValue = "EUR-M";
+   
+   theTable[15].theKey   = Datum_North_American_Datum_1927;
+   theTable[15].theValue = "NAS-C";
+   
+   theTable[16].theKey   = Datum_North_American_Datum_1983;
+   theTable[16].theValue = "NAR-C";
+   
+   theTable[17].theKey   = Datum_OSGB_1936;
+   theTable[17].theValue = "OGB-M";
+   
+   theTable[18].theKey   = Datum_Tokyo;
+   theTable[18].theValue = "TOY-M";
+   
+   theTable[19].theKey   = Datum_WGS72;
+   theTable[19].theValue = "WGD";
+   
+   theTable[20].theKey   = Datum_WGS84;
+   theTable[20].theValue = "WGE";
+
+   theTable[21].theKey   = Datum_NAD83_HARN;
+   theTable[21].theValue = "NAR";
+
+   theTable[22].theKey   = GCS_NAD83_HARN;
+   theTable[22].theValue = "NAR";
+
+   //---
+   // Note:  This code implies a Clark 1866 ellipse with no datum.
+   // NAS-C used as work around for poor tag setting out of Erdas Imagine.
+   //---
+   theTable[23].theKey   = GCS_Clark_1866;
+   theTable[23].theValue = "NAS-C";
+}
+
+ossimGeoTiffDatumLut::~ossimGeoTiffDatumLut()
+{
+}
+
+ossimKeyword ossimGeoTiffDatumLut::getKeyword() const
+{
+   return ossimKeyword("geotiff_datum_code", "");
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffDatumLut.h b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffDatumLut.h
new file mode 100644
index 0000000000..fe5b1973b5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimGeoTiffDatumLut.h
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for GeoTiffDatumLut. Used to map a
+// geotiff coordinate transformation code to an ossim projection.
+//*******************************************************************
+//  $Id: ossimGeoTiffDatumLut.h,v 1.5 2005/01/21 18:55:19 dburken Exp $
+
+#ifndef ossimGeoTiffDatumLut_HEADER
+#define ossimGeoTiffDatumLut_HEADER
+
+#include "ossimLookUpTable.h"
+#include "base/common/ossimKeywordNames.h"
+
+class OSSIMDLLEXPORT ossimGeoTiffDatumLut : public ossimLookUpTable
+{
+public:
+
+   enum
+   {
+      //---
+      // Datum codes cut from geotiff specification section 6.3.2.1.
+      //---
+      GCS_Adindan                     = 4201,
+      GCS_Arc_1950                    = 4209,
+      GCS_Arc_1960                    = 4210,
+      GCS_ED50                        = 4230,
+      GCS_NAD27                       = 4267,
+      GCS_NAD83                       = 4269,
+      GCS_OSGB_1936                   = 4277,
+      GCS_WGS_72                      = 4322,
+      GCS_WGS_84                      = 4326,
+      GCS_Tokyo                       = 4301,
+      GCS_NAD83_HARN                  = 4152,
+
+      //---
+      // Datum codes cut from geotiff specification section 6.3.2.1.
+      // NOTE:  These codes imply an ellipsoid only!
+      //---
+      GCS_Clark_1866                  = 4008,
+      
+      //---
+      // Datum codes cut from geotiff specification section 6.3.2.2.
+      //---
+      DatumE_WGS84                    = 6030,
+      Datum_Adindan                   = 6201,
+      Datum_Arc_1950                  = 6209,
+      Datum_Arc_1960                  = 6210,
+      Datum_European_Datum_1950       = 6230,
+      Datum_North_American_Datum_1927 = 6267,
+      Datum_North_American_Datum_1983 = 6269,
+      Datum_OSGB_1936                 = 6277,
+      Datum_Tokyo                     = 6301,
+      Datum_WGS72                     = 6322,
+      Datum_WGS84                     = 6326,
+      Datum_NAD83_HARN                = 6152
+   };
+   
+   ossimGeoTiffDatumLut();
+
+   virtual ~ossimGeoTiffDatumLut();
+   
+   virtual ossimKeyword getKeyword() const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimImageTypeLut.cpp b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimImageTypeLut.cpp
new file mode 100644
index 0000000000..9010890f5d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimImageTypeLut.cpp
@@ -0,0 +1,68 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class definition for ImageTypeLUT.  Currently has mapping of
+// ouput image writes from enumeration to string and string to
+// enumeration.
+//
+//*******************************************************************
+//  $Id: ossimImageTypeLut.cpp,v 1.3 2002/03/04 12:32:29 dburken Exp $
+
+#include "ossimImageTypeLut.h"
+
+//***
+// Pixel type keyword to use for getState/saveState methods.
+//***
+const ossimKeyword ossimImageTypeLut::IMAGE_TYPE_KW("image_type",
+                                                    "Image type.\n\
+Valid types are:  ccf, tiff, tiled_tiff, jpeg, and general_raster.");
+
+static const int TABLE_SIZE = 8;
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimImageTypeLut::ossimImageTypeLut()
+   :
+      ossimLookUpTable(TABLE_SIZE)
+{
+   //***
+   // Complete initialization of data member "theImageTypeTable".
+   // Note:  Output type enumerations defined in constants.h file.
+   //***
+   theTable[0].theKey   = OSSIM_TIFF_STRIP;
+   theTable[0].theValue = "tiff_strip";
+   theTable[1].theKey   = OSSIM_TIFF_STRIP_BAND_SEPARATE;
+   theTable[1].theValue = "tiff_strip_band_separate";
+   theTable[2].theKey   = OSSIM_TIFF_TILED;
+   theTable[2].theValue = "tiff_tiled";
+   theTable[3].theKey   = OSSIM_TIFF_TILED_BAND_SEPARATE;
+   theTable[3].theValue = "tiff_tiled_band_separate";
+   theTable[4].theKey   = OSSIM_GENERAL_RASTER_BIP;
+   theTable[4].theValue = "general_raster_bip";
+   theTable[5].theKey   = OSSIM_GENERAL_RASTER_BIL;
+   theTable[5].theValue = "general_raster_bil";
+   theTable[6].theKey   = OSSIM_GENERAL_RASTER_BSQ;
+   theTable[6].theValue = "general_raster_bsq";
+   theTable[7].theKey   = OSSIM_JPEG;
+   theTable[7].theValue = "jpeg";
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimImageTypeLut.h b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimImageTypeLut.h
new file mode 100644
index 0000000000..77fe3eeb54
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimImageTypeLut.h
@@ -0,0 +1,47 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for ImageTypeLut.  Currently has mapping of
+// ouput image writes from enumeration to string and string to
+// enumeration.
+//
+//*******************************************************************
+//  $Id: ossimImageTypeLut.h,v 1.3 2002/11/25 19:16:28 gpotts Exp $
+
+#ifndef ImageTypeLUT_HEADER
+#define ImageTypeLUT_HEADER
+
+#include "ossimLookUpTable.h"
+
+class OSSIMDLLEXPORT ossimImageTypeLut : public ossimLookUpTable
+{
+public:
+
+   ossimImageTypeLut();
+
+   virtual ~ossimImageTypeLut(){}
+
+   virtual ossimKeyword getKeyword() const { return IMAGE_TYPE_KW; }
+
+   static const ossimKeyword IMAGE_TYPE_KW;
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimInterleaveTypeLut.cpp b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimInterleaveTypeLut.cpp
new file mode 100644
index 0000000000..8ae20dfc16
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimInterleaveTypeLut.cpp
@@ -0,0 +1,50 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class definition for InterleaveTypeLUT.
+//*******************************************************************
+//  $Id: ossimInterleaveTypeLut.cpp,v 1.1.1.1 2001/02/05 20:13:25 dburken Exp $
+
+#include "ossimInterleaveTypeLut.h"
+
+static const int TABLE_SIZE = 4;
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimInterleaveTypeLut::ossimInterleaveTypeLut()
+   :
+      ossimLookUpTable(TABLE_SIZE)
+{
+   //***
+   // Complete initialization of data member "theTable".
+   // Note:  Interleave types defined in constants.h file.
+   //***
+   theTable[0].theKey   = OSSIM_BIL;
+   theTable[0].theValue = "bil";
+   theTable[1].theKey   = OSSIM_BIP;
+   theTable[1].theValue = "bip";
+   theTable[2].theKey   = OSSIM_BSQ;
+   theTable[2].theValue = "bsq";
+   theTable[3].theKey   = OSSIM_BSQ_MULTI_FILE;
+   theTable[3].theValue = "bsq_multi_file";
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimInterleaveTypeLut.h b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimInterleaveTypeLut.h
new file mode 100644
index 0000000000..70ffd5d0fe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimInterleaveTypeLut.h
@@ -0,0 +1,45 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for InterleaveTypeLUT.
+//*******************************************************************
+//  $Id: ossimInterleaveTypeLut.h,v 1.2 2002/11/25 19:16:28 gpotts Exp $
+
+#ifndef ossimInterleaveTypeLUT_HEADER
+#define ossimInterleaveTypeLUT_HEADER
+
+#include "ossimLookUpTable.h"
+#include "base/common/ossimKeywordNames.h"
+
+class OSSIMDLLEXPORT ossimInterleaveTypeLut : public ossimLookUpTable
+{
+public:
+
+   ossimInterleaveTypeLut();
+
+   virtual ~ossimInterleaveTypeLut(){}
+
+   virtual ossimKeyword getKeyword() const
+      { return ossimKeyword(ossimKeywordNames::INTERLEAVE_TYPE_KW, ""); }
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimLookUpTable.cpp b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimLookUpTable.cpp
new file mode 100644
index 0000000000..f403d2d697
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimLookUpTable.cpp
@@ -0,0 +1,147 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for 
+//*******************************************************************
+//  $Id: ossimLookUpTable.cpp,v 1.9 2004/06/04 14:28:46 dburken Exp $
+
+#include <iostream>
+using namespace std;
+
+#include "ossimLookUpTable.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+//*******************************************************************
+// Protected Constructor:
+//*******************************************************************
+ossimLookUpTable::ossimLookUpTable(ossim_int32 table_size)
+   :
+      theTable(table_size)
+{}
+
+ossimLookUpTable::~ossimLookUpTable()
+{
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ossimString ossimLookUpTable::getEntryString(ossim_int32 entry_number) const
+{
+   for (ossim_uint32 i=0; i<theTable.size(); ++i)
+   {
+      if (theTable[i].theKey == entry_number)
+      {
+         return theTable[i].theValue;
+      }
+   }
+
+   return ossimString(); // Entry number not found.
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ossimString ossimLookUpTable::getTableIndexString(ossim_uint32 table_index) const
+{
+   if (table_index < theTable.size())
+   {
+      return theTable[table_index].theValue;
+   }
+
+   return ossimString(); // Index out of range.
+}
+
+ossimString ossimLookUpTable::operator[](ossim_int32 entry_number) const
+{
+   return getEntryString(entry_number);
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ossimString ossimLookUpTable::getEntryString(const ossimKeywordlist& kwl,
+                                             const char* prefix) const
+{
+   ossimString s = kwl.find(prefix, getKeyword());
+   return s;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ossim_int32 ossimLookUpTable::getEntryNumber(const char*  entry_string,
+                                             bool case_insensitive) const
+{
+   ossimString s1 = entry_string;
+   s1 = s1.trim();
+   for (ossim_uint32 i=0; i<theTable.size(); i++)
+   {
+      ossimString s2 = theTable[i].theValue;
+
+      if (case_insensitive == true)
+      {
+         s1.downcase();
+         s2.downcase();
+      }
+      
+      if (s1 == s2)
+      {
+         return theTable[i].theKey;
+      }
+   }
+
+   return ossimLookUpTable::NOT_FOUND; // Entry number not found.   
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ossim_int32 ossimLookUpTable::getEntryNumber(const ossimKeywordlist& kwl,
+                                             const char* prefix,
+                                             bool case_insensitive) const
+{
+   const char* lookup = kwl.find(prefix, getKeyword());
+
+   if (lookup)
+   {
+      return getEntryNumber(lookup, case_insensitive);
+   }
+
+   return ossimLookUpTable::NOT_FOUND; // Entry number not found.   
+}
+
+ossim_uint32 ossimLookUpTable::getTableSize() const
+{
+   return theTable.size();
+}
+
+void ossimLookUpTable::dumpValues(std::ostream& out)const
+{
+  ossim_uint32 tableSize = getTableSize();
+  ossim_uint32 i = 0;
+
+  for(i = 0; i < tableSize; ++i)
+    {
+      out << theTable[0].theValue << std::endl;
+    }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimLookUpTable.h b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimLookUpTable.h
new file mode 100644
index 0000000000..6e63c97dcf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimLookUpTable.h
@@ -0,0 +1,116 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for LookUpTable. 
+//*******************************************************************
+//  $Id: ossimLookUpTable.h,v 1.12 2005/05/13 18:57:48 dburken Exp $
+
+#ifndef ossimLookUpTable_HEADER
+#define ossimLookUpTable_HEADER
+
+#include <vector>
+
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimKeyword.h"
+
+class OSSIMDLLEXPORT ossimKeywordlist;
+
+//*******************************************************************
+// CLASS:  LookUpTable
+//*******************************************************************
+class OSSIMDLLEXPORT ossimLookUpTable
+{
+public:
+
+   enum
+   {
+      NOT_FOUND    = -1
+   };
+   
+   virtual ~ossimLookUpTable();
+
+   /*!
+    *  @return
+    *  Returns the entry string associated with the entry number (key) passed
+    *  in. Returns empty string if entry number is not in the list.
+    */
+   virtual ossimString getEntryString(ossim_int32 entry_number) const;
+
+   /*!
+    *  @param table_index Index into the table
+    *  Note:  This is not the key mapped to the but the index into the table.
+    *  @return
+    *  Returns the entry string associated with the table index passed in.
+    *  Returns empty string if index is out of range.
+    */
+   virtual ossimString getTableIndexString(ossim_uint32 table_index) const;
+
+   /*!
+    *  Returns the entry string associated with the entry number passed in.
+    *  Returns empty string if entry number is not in the list.
+    */
+   virtual ossimString operator[](ossim_int32 entry_number) const;
+
+   /*!
+    *  Returns the entry string associated with lookup table keyword entry
+    *  in the Keywordlist passed in.
+    *  Returns empty string if keyword entry is not in the Keywordlist.
+    */
+   virtual ossimString getEntryString(const ossimKeywordlist& kwl,
+                                      const char* prefix=0) const;
+
+   /*!
+    *  Returns the entry number associated with the entry string passed in.
+    *  Returns NOT_FOUND(-1) if entry string is not in the list.
+    *  If case_insensitive == true(default), the test is case insensitive;
+    *  else, the test will be case sensitive.
+    */
+   virtual ossim_int32 getEntryNumber(const char* entry_string,
+                                      bool case_insensitive = true) const;
+
+   /*!
+    *  Returns the entry number associated with the lookup table keyword
+    *  entry in the Keywordlist passed in.  Returns NOT_FOUND(-1) if no
+    *  matching entry.
+    *  If case_insensitive == true(default), the test is case insensitive;
+    *  else, the test will be case sensitive.
+    */
+   virtual ossim_int32 getEntryNumber(const ossimKeywordlist& kwl,
+                                      const char* prefix=0,
+                                      bool case_insensitive = true) const;
+
+   /*!
+    *  Returns keyword for lookups from a Keywordlist.
+    */
+   virtual ossimKeyword getKeyword() const=0;
+
+   virtual ossim_uint32 getTableSize() const;
+  
+  void dumpValues(std::ostream& out)const;
+protected:
+
+   ossimLookUpTable(ossim_int32 table_size);
+
+   class ossimKeyValueMap
+   {
+   public:
+      ossim_int32  theKey;
+      ossimString theValue;
+   };
+
+   std::vector<ossimKeyValueMap>  theTable;
+   
+private:
+   ossimLookUpTable(){} // disallow...
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimScalarTypeLut.cpp b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimScalarTypeLut.cpp
new file mode 100644
index 0000000000..3a76e0d4da
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimScalarTypeLut.cpp
@@ -0,0 +1,126 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for ossimScalarTypeLUT.
+// 
+//*******************************************************************
+//  $Id: ossimScalarTypeLut.cpp,v 1.6 2005/05/09 12:30:30 dburken Exp $
+
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/data_types/ossimString.h>
+
+ossimScalarTypeLut* ossimScalarTypeLut::theInstance = NULL;
+
+static const int TABLE_SIZE = 21;
+
+ossimScalarTypeLut* ossimScalarTypeLut::instance()
+{
+   if (!theInstance)
+   {
+      theInstance = new ossimScalarTypeLut;
+   }
+   return theInstance;
+}
+
+ossimScalarTypeLut::ossimScalarTypeLut()
+   :
+      ossimLookUpTable(TABLE_SIZE)
+{
+   //---
+   // Complete initialization of data member "theTable".
+   // Note:  Scalar types defined in constants.h file.
+   //---
+   theTable[0].theKey   = OSSIM_SCALAR_UNKNOWN;
+   theTable[0].theValue = "unknown";
+   
+   theTable[1].theKey   = OSSIM_UINT8;
+   theTable[1].theValue = "ossim_uint8";
+
+   theTable[2].theKey   = OSSIM_SINT8;
+   theTable[2].theValue = "ossim_sint8";
+
+   theTable[3].theKey   = OSSIM_UINT16;
+   theTable[3].theValue = "ossim_uint16";
+
+   theTable[4].theKey   = OSSIM_SINT16;
+   theTable[4].theValue = "ossim_sint16";
+
+   theTable[5].theKey   = OSSIM_UINT32;
+   theTable[5].theValue = "ossim_uint32";
+
+   theTable[6].theKey   = OSSIM_SINT32;
+   theTable[6].theValue = "ossim_sint32";
+
+   theTable[7].theKey   = OSSIM_FLOAT32;
+   theTable[7].theValue = "ossim_float32";
+
+   theTable[8].theKey   = OSSIM_FLOAT64;
+   theTable[8].theValue = "ossim_float64";
+
+   theTable[9].theKey   = OSSIM_CINT16;
+   theTable[9].theValue = "ossim_cint16";
+
+   theTable[10].theKey   = OSSIM_CINT32;
+   theTable[10].theValue = "ossim_cint32";
+
+   theTable[11].theKey   = OSSIM_CFLOAT32;
+   theTable[11].theValue = "ossim_cfloat32";
+
+   theTable[12].theKey   = OSSIM_CFLOAT64;
+   theTable[12].theValue = "ossim_cfloat64";
+   
+   theTable[13].theKey   = OSSIM_UCHAR;
+   theTable[13].theValue = "uchar";
+
+   theTable[14].theKey   = OSSIM_USHORT16;
+   theTable[14].theValue = "ushort16";
+
+   theTable[15].theKey   = OSSIM_SSHORT16;
+   theTable[15].theValue = "sshort16";
+
+   theTable[16].theKey   = OSSIM_USHORT11;
+   theTable[16].theValue = "ushort11";
+
+   theTable[17].theKey   = OSSIM_FLOAT;
+   theTable[17].theValue = "float";   
+
+   theTable[18].theKey   = OSSIM_NORMALIZED_FLOAT;
+   theTable[18].theValue = "normalized_float";   
+
+   theTable[19].theKey   = OSSIM_NORMALIZED_DOUBLE;
+   theTable[19].theValue = "normalized_double";
+
+   theTable[20].theKey   = OSSIM_DOUBLE;
+   theTable[20].theValue = "double";
+}
+
+ossimScalarTypeLut::~ossimScalarTypeLut()
+{
+   theInstance = NULL;
+}
+
+ossimScalarType
+ossimScalarTypeLut::getScalarTypeFromString(const ossimString& s) const
+{
+   int scalar_type = getEntryNumber(s.c_str());
+   
+   if (scalar_type == -1)
+   {
+      return OSSIM_SCALAR_UNKNOWN;
+   }
+   
+   return static_cast<ossimScalarType>(scalar_type);
+}   
+
+ossimKeyword ossimScalarTypeLut::getKeyword() const
+{
+   return ossimKeyword((ossimKeywordNames::SCALAR_TYPE_KW), "");
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimScalarTypeLut.h b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimScalarTypeLut.h
new file mode 100644
index 0000000000..3644958118
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimScalarTypeLut.h
@@ -0,0 +1,53 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimScalarTypeLut.
+// 
+//*******************************************************************
+//  $Id: ossimScalarTypeLut.h,v 1.4 2005/05/09 12:30:30 dburken Exp $
+
+#ifndef ossimScalarTypeLut_HEADER
+#define ossimScalarTypeLut_HEADER
+
+#include <base/misc/lookup_tables/ossimLookUpTable.h>
+#include <base/common/ossimKeywordNames.h>
+
+/**
+ * Used to convert from scalar type enumeration to strings and vice versa.
+ * See ossimConstants.h for a complete list of enumerations.  This class is
+ * a singleton, only one of them so all callers must go through the
+ * instance method like:
+ * ossimScalarTypeLut::instance()->getEntryString(scalar);
+ */
+class OSSIMDLLEXPORT ossimScalarTypeLut : public ossimLookUpTable
+{
+public:
+
+   /**
+    * Returns the static instance of an ossimScalarTypeLut object.
+    */
+   static ossimScalarTypeLut* instance();
+
+   virtual ~ossimScalarTypeLut();
+
+   ossimScalarType getScalarTypeFromString(const ossimString& s) const;
+   
+   virtual ossimKeyword getKeyword() const;
+
+protected:
+   ossimScalarTypeLut();
+
+private:
+
+   static ossimScalarTypeLut* theInstance;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimUnitTypeLut.cpp b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimUnitTypeLut.cpp
new file mode 100644
index 0000000000..c3e5307d3e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimUnitTypeLut.cpp
@@ -0,0 +1,54 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+//  $Id: ossimUnitTypeLut.cpp,v 1.5 2005/06/15 14:15:22 gpotts Exp $
+#include "ossimUnitTypeLut.h"
+static const int TABLE_SIZE = 13;
+ossimUnitTypeLut::ossimUnitTypeLut()
+  :ossimLookUpTable(TABLE_SIZE)
+{
+   theTable[0].theKey   = OSSIM_UNIT_UNKNOWN;
+   theTable[0].theValue = "unknown";
+   theTable[1].theKey   = OSSIM_METERS;
+   theTable[1].theValue = "meters";
+   theTable[2].theKey   = OSSIM_FEET;
+   theTable[2].theValue = "feet";
+   theTable[3].theKey   = OSSIM_US_SURVEY_FEET;
+   theTable[3].theValue = "us_survey_feet";
+   theTable[4].theKey   = OSSIM_DEGREES;
+   theTable[4].theValue = "degrees";
+   theTable[5].theKey   = OSSIM_RADIANS;
+   theTable[5].theValue = "radians";
+   theTable[6].theKey   = OSSIM_NAUTICAL_MILES;
+   theTable[6].theValue = "nautical_miles";
+   theTable[7].theKey   = OSSIM_SECONDS;
+   theTable[7].theValue = "seconds";
+   theTable[8].theKey   = OSSIM_MINUTES;
+   theTable[8].theValue = "minutes";
+   theTable[9].theKey   = OSSIM_PIXEL;
+   theTable[9].theValue = "pixel";
+   theTable[10].theKey   = OSSIM_MILES;
+   theTable[10].theValue = "miles";
+   theTable[11].theKey   = OSSIM_MILLIMETERS;
+   theTable[11].theValue = "millimeters";
+   theTable[12].theKey   = OSSIM_MICRONS;
+   theTable[12].theValue = "microns";
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimUnitTypeLut.h b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimUnitTypeLut.h
new file mode 100644
index 0000000000..5f87dde43b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/lookup_tables/ossimUnitTypeLut.h
@@ -0,0 +1,80 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+//  $Id: ossimUnitTypeLut.h,v 1.4 2003/05/13 11:31:03 dburken Exp $
+#ifndef ossimUnitTypeLut_HEADER
+#define ossimUnitTypeLut_HEADER
+
+#include "ossimLookUpTable.h"
+#include "base/common/ossimKeywordNames.h"
+
+class OSSIMDLLEXPORT ossimUnitTypeLut : public ossimLookUpTable
+{
+public:
+
+   ossimUnitTypeLut();
+
+   virtual ~ossimUnitTypeLut(){}
+
+   /*!
+    *  Returns the entry number associated with the entry string passed in.
+    *  Returns OSSIM_UNIT_UNKNOWN if entry string is not in the list.
+    *  If case_insensitive == true(default), the test is case insensitive;
+    *  else, the test will be case sensitive.
+    */
+   virtual ossim_int32 getEntryNumber(const char* entry_string,
+                                bool case_insensitive = true) const
+      {
+         ossim_int32 result
+            = ossimLookUpTable::getEntryNumber(entry_string, case_insensitive);
+         if(result < 0)
+         {
+            return (ossim_int32)OSSIM_UNIT_UNKNOWN;
+         }
+         
+         return result;
+      }
+
+   /*!
+    *  Returns the entry number associated with the lookup table keyword
+    *  entry in the Keywordlist passed in.  Returns NOT_FOUND(-1) if no
+    *  matching entry.
+    *  If case_insensitive == true(default), the test is case insensitive;
+    *  else, the test will be case sensitive.
+    */
+   virtual ossim_int32 getEntryNumber(const ossimKeywordlist& kwl,
+                                      const char* prefix=NULL,
+                                      bool case_insensitive = true) const
+      {
+         ossim_int32 result =
+            ossimLookUpTable::getEntryNumber(kwl, prefix, case_insensitive);
+         if(result < 0)
+         {
+            return (ossim_int32)OSSIM_UNIT_UNKNOWN;
+         }
+         return result;
+      }
+   
+   virtual ossimKeyword getKeyword() const
+      { return ossimKeyword(ossimKeywordNames::UNITS_KW, ""); }
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossim2dLinearRegression.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossim2dLinearRegression.cpp
new file mode 100644
index 0000000000..d688b80b9b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossim2dLinearRegression.cpp
@@ -0,0 +1,73 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossim2dLinearRegression.cpp,v 1.3 2005/12/07 20:24:17 gpotts Exp $
+#include "ossim2dLinearRegression.h"
+
+ossim2dLinearRegression::ossim2dLinearRegression()
+{
+   clear();
+}
+
+void ossim2dLinearRegression::solve()
+{
+   
+//    theSumX           = 0.0;
+//    theSumXX          = 0.0;
+//    theSumY           = 0.0;
+//    theSumYY          = 0.0;
+//    theIntercept      = 0.0;
+//    theSlope          = 0.0;
+//    theSumXY          = 0.0;
+//    ossim_uint32 idx = 0;
+//    for(idx = 0; idx < thePoints.size(); ++idx)
+//    {
+//       theSumX  += thePoints[idx].x;
+//       theSumY  += thePoints[idx].y;
+//       theSumXX += thePoints[idx].x*thePoints[idx].x;
+//       theSumYY += thePoints[idx].y*thePoints[idx].y;
+//       theSumXY += thePoints[idx].x*thePoints[idx].y; 
+      
+//    }
+   
+   double numberOfPoints = (double)theNumberOfPoints;
+
+   if(numberOfPoints < 1)
+   {
+      theSlope = 0.0;
+      theIntercept = 0.0;
+      return;
+   }
+   double Sxx = theSumXX - ((theSumX*theSumX)/numberOfPoints);
+   double Sxy = theSumXY - ((theSumX*theSumY)/numberOfPoints);
+
+   if(fabs(Sxx) < FLT_EPSILON)
+   {
+      theSlope = 0.0;
+      theIntercept = 0.0;
+      return;
+   }
+   
+   theSlope     = Sxy/Sxx;
+   theIntercept = (theSumY - theSlope*theSumX)/numberOfPoints;
+
+   theSolvedFlag = true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossim2dLinearRegression.h b/Utilities/OSSIM/ossim_core/base/misc/ossim2dLinearRegression.h
new file mode 100644
index 0000000000..e6cb2dd878
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossim2dLinearRegression.h
@@ -0,0 +1,89 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossim2dLinearRegression.h,v 1.5 2005/12/07 20:24:17 gpotts Exp $
+#ifndef ossim2dLinearRegression_HEADER
+#define ossim2dLinearRegression_HEADER
+#include "base/data_types/ossimDpt.h"
+#include <vector>
+#include <iostream>
+
+class ossim2dLinearRegression
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossim2dLinearRegression& data)
+      {
+         out << "y = " << data.theSlope << "*x + " << data.theIntercept;
+
+         return out;
+      }
+   ossim2dLinearRegression();
+   void getEquation(double& slope,
+                    double& intercept)
+   {
+      slope     = theSlope;
+      intercept = theIntercept;
+   }
+   void addPoint(const ossimDpt& pt)
+      {
+//         thePoints.push_back(pt);
+         ++theNumberOfPoints;
+         theSumX  += pt.x;
+         theSumY  += pt.y;
+         theSumXX += pt.x*pt.x;
+         theSumYY += pt.y*pt.y;
+         theSumXY += pt.x*pt.y; 
+         theSolvedFlag     = false;
+      }
+   void clear()
+      {
+//         thePoints.clear();
+         theNumberOfPoints = 0;
+         theSumX           = 0.0;
+         theSumXX          = 0.0;
+         theSumY           = 0.0;
+         theSumYY          = 0.0;
+         theIntercept      = 0.0;
+         theSlope          = 0.0;
+         theSumXY          = 0.0;
+         theSolvedFlag     = false;
+      }
+   void solve();
+   ossim_uint32 getNumberOfPoints()const
+      {
+         return theNumberOfPoints;
+//         return thePoints.size();
+      }
+protected:
+//   std::vector<ossimDpt> thePoints;
+   ossim_uint32 theNumberOfPoints;
+   double theSumX;
+   double theSumY;
+   double theSumXX;
+   double theSumYY;
+   double theSumXY;
+   
+   double theIntercept;
+   double theSlope;
+   bool   theSolvedFlag;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossim2dTo2dTransform.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossim2dTo2dTransform.cpp
new file mode 100644
index 0000000000..a87350486a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossim2dTo2dTransform.cpp
@@ -0,0 +1,242 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossim2dTo2dTransform.cpp,v 1.16 2005/05/17 19:05:14 gpotts Exp $
+#include <base/misc/ossim2dTo2dTransform.h>
+#include <sstream>
+
+RTTI_DEF1(ossim2dTo2dTransform, "ossim2dTo2dTransform", ossimObject);
+
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/context/ossimNotifyContext.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossim2dTo2dTransform:exec");
+static ossimTrace traceDebug ("ossim2dTo2dTransform:debug");
+
+static const double DEFAULT_THRESHOLD      = 1000.0*DBL_EPSILON;
+static const int    DEFAULT_MAX_ITERATIONS = 10;
+
+//*****************************************************************************
+//  CONSTRUCTOR: 
+//*****************************************************************************
+ossim2dTo2dTransform::ossim2dTo2dTransform()
+   :
+      theConvergenceThreshold (DEFAULT_THRESHOLD),
+      theMaxIterations        (DEFAULT_MAX_ITERATIONS),
+      theDxDy(1.0, 1.0)
+{
+}
+ 
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+void ossim2dTo2dTransform::inverse(const ossimDpt& input,
+                                   ossimDpt&       output) const
+{
+   static const char MODULE[] = "ossim2dTo2dTransform::inverse";
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << ", entering...\n";
+   
+   //***
+   // Begin with guess. Forward transform is defined as trasforming left to
+   // right. We are therefore solving for left:
+   //***
+   ossimDpt left = getOrigin();
+   ossimDpt left_dx;
+   ossimDpt left_dy;
+   ossimDpt right;
+   ossimDpt right_dx;
+   ossimDpt right_dy;
+   ossimDpt dr_dx;
+   ossimDpt dr_dy;
+   ossimDpt r_diff;
+   ossimDpt l_diff;
+   double inverse_norm;
+   int iters=0;
+   //***
+   // Begin iterations:
+   //***
+   do
+   {
+      //***
+      // establish perturbed image points about the guessed point:
+      //***
+      left_dx.x = left.x + theDxDy.x;
+      left_dx.y = left.y;
+      left_dy.x = left.x;
+      left_dy.y = left.y + theDxDy.y;
+      
+      //***
+      // Compute numerical partials at current guessed point:
+      //***
+      forward(left,    right);
+      forward(left_dx, right_dx);
+      forward(left_dy, right_dy);
+
+      dr_dx.x = (right_dx.x - right.x)/theDxDy.x; //e
+      dr_dx.y = (right_dx.y - right.y)/theDxDy.y; //g
+      dr_dy.x = (right_dy.x - right.x)/theDxDy.x; //f
+      dr_dy.y = (right_dy.y - right.y)/theDxDy.y; //h
+
+      //***
+      // Test for convergence:
+      //***
+      r_diff = input - right;
+      
+      //***
+      // Compute linearized estimate of image point given gp delta:
+      //***
+      inverse_norm = dr_dy.x*dr_dx.y - dr_dx.x*dr_dy.y; // fg-eh
+
+      if (inverse_norm != 0)
+      {
+         l_diff.x = (-dr_dy.y*r_diff.x + dr_dy.x*r_diff.y)/inverse_norm;
+         l_diff.y = ( dr_dx.y*r_diff.x - dr_dx.x*r_diff.y)/inverse_norm;
+
+         left += l_diff;
+      }
+      else
+      {
+         l_diff.x = 0;
+         l_diff.y = 0;
+      }
+
+      iters++;
+      
+   } while (((fabs(l_diff.x) > theConvergenceThreshold) ||
+             (fabs(l_diff.y) > theConvergenceThreshold)) &&
+            (iters < theMaxIterations));
+
+   //***
+   // Note that this error mesage appears only if max count was reached while
+   // iterating. A linear (no iteration) solution would finish with iters =
+   // MAX_NUM_ITERATIONS + 1:
+   //***
+    if (iters == theMaxIterations)
+    {
+       ossimNotify(ossimNotifyLevel_WARN) << "WARNING: " << MODULE << ", exceeded max number of iterations computing inverse "
+                                          << "transform for point: " << input << "\n";
+    }
+
+   output = left;
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << ", returning...\n";
+   return;
+   
+}
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+bool ossim2dTo2dTransform::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::CONVERGENCE_THRESHOLD_KW,
+           theConvergenceThreshold,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::MAX_ITERATIONS_KW,
+           theMaxIterations,
+           true);
+   kwl.add(prefix,
+           "dxdy",
+           ossimString::toString(theDxDy.x) + " " +
+           ossimString::toString(theDxDy.y),
+           true);
+           
+   return ossimObject::saveState(kwl, prefix);
+}
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+bool ossim2dTo2dTransform::loadState(const ossimKeywordlist& kwl,
+               const char* prefix)
+{
+  bool result = true;
+
+   const char* buf;
+
+   buf= kwl.find(prefix, ossimKeywordNames::CONVERGENCE_THRESHOLD_KW);
+
+   if (buf)
+   {
+      theConvergenceThreshold = atof(buf);
+   }
+   else
+   {
+      theConvergenceThreshold = .00000000000002;
+   }
+   
+   buf= kwl.find(prefix, ossimKeywordNames::MAX_ITERATIONS_KW);
+   if(buf)
+   {
+      theMaxIterations = atoi(buf);
+   }
+   else
+   {
+      theMaxIterations = 10;
+   }
+   const char* dxdy = kwl.find(prefix, "dxdy");
+   if(dxdy)
+   {
+      std::istringstream in(dxdy);
+      in>>theDxDy.x >> theDxDy.y;
+   }
+   if(result)
+   {
+      ossimObject::loadState(kwl, prefix);
+   }
+   
+   return result;
+}
+   
+void ossim2dTo2dTransform::forward(ossimDpt&  modify_this) const 
+{
+   ossimDpt output;
+   forward(modify_this, output);
+   modify_this = output;
+}
+
+void ossim2dTo2dTransform::inverse(ossimDpt&  modify_this) const 
+{
+   ossimDpt output;
+   inverse(modify_this, output);
+   modify_this = output;
+}
+
+ossimDpt ossim2dTo2dTransform::getOrigin()const
+{
+   return ossimDpt(0,0);
+}
+
+void ossim2dTo2dTransform::setConvergenceThreshold(const double& new_threshold)
+{
+   theConvergenceThreshold = new_threshold;
+}
+
+void ossim2dTo2dTransform::setMaxIterations(int new_max_iters)
+{
+   theMaxIterations = new_max_iters;
+}
+
+void ossim2dTo2dTransform::setDxDy(const ossimDpt& dxdy)
+{
+   theDxDy.x = dxdy.x;
+   theDxDy.y = dxdy.y;
+}
+
+void ossim2dTo2dTransform::operator=(const ossim2dTo2dTransform& /* rhs */ )
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossim2dTo2dTransform.h b/Utilities/OSSIM/ossim_core/base/misc/ossim2dTo2dTransform.h
new file mode 100644
index 0000000000..a96401daee
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossim2dTo2dTransform.h
@@ -0,0 +1,62 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossim2dTo2dTransform.h,v 1.8 2004/08/17 21:09:57 dburken Exp $
+#ifndef ossim2dTo2dTransform_HEADER
+#define ossim2dTo2dTransform_HEADER
+#include "base/common/ossimObject.h"
+#include "base/data_types/ossimDpt.h"
+
+class OSSIMDLLEXPORT ossim2dTo2dTransform : public ossimObject
+{
+public:
+   virtual void forward(const ossimDpt& input,
+                        ossimDpt& output) const=0;
+   
+   virtual void forward(ossimDpt&  modify_this) const;
+      
+   virtual void inverse(const ossimDpt& input,
+                        ossimDpt&       output) const;
+
+   virtual void inverse(ossimDpt&  modify_this) const;
+      
+   /*!
+    * Used by the inverse iterator.  This will give it a good initial value
+    * that is within the input transforms
+    */
+   virtual ossimDpt getOrigin() const;
+
+   virtual std::ostream& print(std::ostream& out) const = 0;
+   
+   bool saveState(ossimKeywordlist& kwl,
+                   const char* prefix = 0)const;
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix = 0);
+   
+   void setConvergenceThreshold(const double& new_threshold);
+   
+   void setMaxIterations(int new_max_iters);
+
+   void setDxDy(const ossimDpt& dxdy);
+
+protected:
+   ossim2dTo2dTransform();
+   void operator =(const ossim2dTo2dTransform& rhs);
+
+   double theConvergenceThreshold;
+   int    theMaxIterations;
+
+   ossimDpt theDxDy;
+   
+TYPE_DATA      
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInfo.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInfo.cpp
new file mode 100644
index 0000000000..af098eab97
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInfo.cpp
@@ -0,0 +1,126 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimAdjustableParameterInfo.cpp,v 1.8 2004/01/09 18:32:00 gpotts Exp $
+#include <sstream>
+#include <algorithm>
+#include "ossimAdjustableParameterInfo.h"
+#include "base/misc/lookup_tables/ossimUnitTypeLut.h"
+#include "base/common/ossimKeywordNames.h"
+
+// static const char* PARAM_NAME_KW       = "name";
+// static const char* PARAM_UNITS_KW      = "units";
+static const char* PARAM_KW            = "parameter";
+static const char* PARAM_SIGMA_KW      = "sigma";
+static const char* PARAM_CENTER_KW     = "center";
+
+std::ostream& operator <<(std::ostream& out, const ossimAdjustableParameterInfo& data)
+{
+   out << "description: " << data.theDescription << std::endl
+       << "center:      " << data.theCenter <<  std::endl
+       << "parameter:   " << data.theParameter << std::endl
+       << "sigma:       " << data.theSigma << std::endl
+       << "units:       " << ossimUnitTypeLut().getEntryString(data.theUnit) << endl;
+   
+   return out;
+}
+
+
+ossimString ossimAdjustableParameterInfo::getUnitAsString()const
+{
+   return ossimUnitTypeLut().getEntryString((int)theUnit);
+}
+
+void ossimAdjustableParameterInfo::setCenter(double center)
+{
+  theCenter = center;
+}
+
+double ossimAdjustableParameterInfo::getCenter()const
+{
+  return theCenter;
+}
+
+double ossimAdjustableParameterInfo::computeOffset()const
+{
+  return theCenter + theSigma*theParameter;
+}
+
+bool ossimAdjustableParameterInfo::loadState(const ossimKeywordlist& kwl,
+                                             const ossimString& prefix)
+{
+   const char* param       = kwl.find(prefix, PARAM_KW);
+   const char* sigma       = kwl.find(prefix, PARAM_SIGMA_KW);
+   const char* center      = kwl.find(prefix, PARAM_CENTER_KW);
+   const char* unit        = kwl.find(prefix, ossimKeywordNames::UNITS_KW);
+   
+   theDescription          = kwl.find(prefix, ossimKeywordNames::DESCRIPTION_KW);
+   
+   if(param)
+   {
+      theParameter = ossimString(param).toDouble();
+   }
+   else
+   {
+      theParameter = 0.0;
+   }
+   if(unit)
+   {
+      theUnit = (ossimUnitType)(ossimUnitTypeLut().getEntryNumber(unit));
+   }
+   else
+   {
+      theUnit      = OSSIM_UNIT_UNKNOWN;
+   }
+   if(sigma)
+   {
+      theSigma  = ossimString(sigma).toDouble();
+   }
+   else
+   {
+      theSigma     = 0.0;
+   }
+   if(center)
+   {
+     theCenter = ossimString(center).toDouble();
+   }
+   else
+   {
+     theCenter = 0.0;
+   }
+
+   return true;
+}
+
+bool ossimAdjustableParameterInfo::saveState(ossimKeywordlist& kwl,
+                                             const ossimString& prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::DESCRIPTION_KW,
+           theDescription,
+           true);
+   kwl.add(prefix, ossimKeywordNames::UNITS_KW, ossimUnitTypeLut().getEntryString(theUnit), true);
+   kwl.add(prefix, PARAM_KW, theParameter, true);
+   kwl.add(prefix, PARAM_SIGMA_KW, theSigma, true);
+   kwl.add(prefix, PARAM_CENTER_KW, theCenter, true);
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInfo.h b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInfo.h
new file mode 100644
index 0000000000..a3982587ba
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInfo.h
@@ -0,0 +1,97 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimAdjustableParameterInfo.h,v 1.6 2004/01/09 18:32:00 gpotts Exp $
+#ifndef ossimAdjustableParameterInfo_HEADER
+#define ossimAdjustableParameterInfo_HEADER
+#include <iostream>
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+class ossimAdjustableParameterInfo
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimAdjustableParameterInfo& data);
+   
+   ossimAdjustableParameterInfo()
+      : theParameter(0.0),
+        theSigma(0.0),
+	theCenter(0.0),
+        theUnit(OSSIM_UNIT_UNKNOWN),
+        theDescription("")
+      {
+      }
+   double getParameter()const
+      {
+         return theParameter;
+      }
+   void setParameter(double parameter)
+      {
+         theParameter = parameter;
+      }
+   double getSigma()const
+      {
+         return theSigma;
+      }
+   void setSigma(double sigma)
+      {
+         theSigma = sigma;
+      }
+   const ossimString& getDescription()const
+      {
+         return theDescription;
+      }
+   void setDescription(const ossimString& description)
+      {
+         theDescription = description;
+      }
+   ossimUnitType getUnit()const
+      {
+         return theUnit;
+      }
+   void setUnit(ossimUnitType unit)
+      {
+         theUnit = unit;
+      }
+   ossimString getUnitAsString()const;
+
+   void setCenter(double center);
+   double getCenter()const;
+
+  /*!
+   * will return theCenter + theSigma*theParameter
+   */
+   double computeOffset()const;
+
+   bool loadState(const ossimKeywordlist& kwl,
+                  const ossimString& prefix=ossimString(""));
+   bool saveState(ossimKeywordlist& kwl,
+                  const ossimString& prefix=ossimString(""))const;
+protected:
+   double        theParameter;
+   double        theSigma;
+   double        theCenter;
+   ossimUnitType theUnit;     
+   ossimString   theDescription;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInterface.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInterface.cpp
new file mode 100644
index 0000000000..e683f248af
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInterface.cpp
@@ -0,0 +1,617 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimAdjustableParameterInterface.cpp,v 1.29 2005/12/09 17:02:51 gpotts Exp $
+#include <algorithm>
+#include "ossimAdjustableParameterInterface.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/misc/lookup_tables/ossimUnitTypeLut.h"
+
+RTTI_DEF(ossimAdjustableParameterInterface, "ossimAdjustableParameterInterface");
+
+static const char* NUMBER_OF_ADJUSTMENTS_KW = "number_of_adjustments";
+static const char* NUMBER_OF_ADJUSTMENTS_OLD_KW = "number_of_adjustements";
+static const char* CURRENT_ADJUSTMENT_OLD_KW    = "current_adjustement";
+static const char* CURRENT_ADJUSTMENT_KW    = "current_adjustment";
+static const char* ADJUSTMENT_PREFIX        = "adjustment_";
+
+ossimAdjustableParameterInterface::ossimAdjustableParameterInterface()
+{
+   theCurrentAdjustment = 0;
+}
+
+void ossimAdjustableParameterInterface::newAdjustment(ossim_uint32 numberOfParameters)
+{
+   theAdjustmentList.push_back(ossimAdjustmentInfo());
+   if(numberOfParameters > 0)
+   {
+      theAdjustmentList[theAdjustmentList.size()-1].setNumberOfAdjustableParameters(numberOfParameters);
+      theAdjustmentList[theAdjustmentList.size()-1].setDescription("Initial adjustment");
+   }
+
+   theCurrentAdjustment = theAdjustmentList.size() - 1;
+
+}
+
+void ossimAdjustableParameterInterface::setAdjustmentDescription(const ossimString& description)
+{
+   if(!theAdjustmentList.size())
+   {
+      return;
+   }
+   theAdjustmentList[theCurrentAdjustment].setDescription(description);
+}
+
+ossimString ossimAdjustableParameterInterface::getAdjustmentDescription()const
+{
+   if(theAdjustmentList.size())
+   {
+      return theAdjustmentList[theCurrentAdjustment].getDescription();
+   }
+
+   return "";
+}
+
+void ossimAdjustableParameterInterface::setCurrentAdjustment(ossim_uint32 adjustmentIdx, bool notify)
+{
+   if(adjustmentIdx < theAdjustmentList.size())
+   {
+      theCurrentAdjustment = adjustmentIdx;
+      if(notify)
+      {
+         adjustableParametersChanged();
+      }
+   }
+}
+
+
+void ossimAdjustableParameterInterface::initAdjustableParameters()
+{
+}
+
+void ossimAdjustableParameterInterface::resetAdjustableParameters(bool notify)
+{
+    if(!theAdjustmentList.size())
+    {
+       return;
+    }
+    
+    ossim_uint32 saveCurrent = theCurrentAdjustment;
+    copyAdjustment();
+    initAdjustableParameters();
+    ossim_uint32 numberOfAdjustables = getNumberOfAdjustableParameters();
+    ossim_uint32 idx = 0;
+    
+    for(idx = 0; idx < numberOfAdjustables; ++idx)
+    {
+       theAdjustmentList[saveCurrent].getParameterList()[idx].setParameter(theAdjustmentList[theAdjustmentList.size()-1].getParameterList()[idx].getParameter());
+    }
+
+    setCurrentAdjustment(saveCurrent);
+
+    eraseAdjustment(theAdjustmentList.size()-1, false);
+    
+    if(notify)
+    {
+       adjustableParametersChanged();
+    }
+}
+
+void ossimAdjustableParameterInterface::copyAdjustment(ossim_uint32 idx, bool notify)
+{
+    if(!theAdjustmentList.size())
+    {
+       return;
+    }
+    if((idx >=0)&&(idx < theAdjustmentList.size()))
+    {
+       theAdjustmentList.push_back(theAdjustmentList[idx]);
+
+       if(idx == theCurrentAdjustment)
+       {
+          theCurrentAdjustment = theAdjustmentList.size() - 1;
+       }
+       if(notify)
+       {
+          adjustableParametersChanged();
+       }
+    }
+    
+}
+
+void ossimAdjustableParameterInterface::copyAdjustment(bool notify)
+{
+   copyAdjustment(theCurrentAdjustment, notify);
+}
+
+void ossimAdjustableParameterInterface::keepAdjustment(ossim_uint32 idx,
+                                                       bool createCopy)
+{
+    if(!theAdjustmentList.size())
+    {
+       return;
+    }
+    if((idx >=0)&&(idx < theAdjustmentList.size()))
+    {
+       if(createCopy)
+       {
+          copyAdjustment(idx);
+       }
+       theAdjustmentList[theCurrentAdjustment].keep();
+    }
+}
+
+void ossimAdjustableParameterInterface::keepAdjustment(bool createCopy)
+{
+   keepAdjustment(theCurrentAdjustment, createCopy);
+}
+
+void ossimAdjustableParameterInterface::removeAllAdjustments()
+{
+   theAdjustmentList.clear();
+   theCurrentAdjustment = 0;
+}
+
+ossim_uint32 ossimAdjustableParameterInterface::getNumberOfAdjustableParameters()const
+{
+   if(theAdjustmentList.size())
+   {
+      return theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters();
+   }
+
+   return 0;
+}
+
+void ossimAdjustableParameterInterface::eraseAdjustment(bool notify)
+{
+   eraseAdjustment(theCurrentAdjustment, notify);
+}
+
+void ossimAdjustableParameterInterface::eraseAdjustment(ossim_uint32 idx, bool notify)
+{
+   if(!theAdjustmentList.size())
+   {
+      return;
+   }
+   
+   if(theCurrentAdjustment == idx)
+   {
+      theAdjustmentList.erase(theAdjustmentList.begin() + theCurrentAdjustment);
+      if(theCurrentAdjustment >= theAdjustmentList.size())
+      {
+         if(theAdjustmentList.size() < 1)
+         {
+            theCurrentAdjustment = 0;
+         }
+         else
+         {
+            theCurrentAdjustment = theAdjustmentList.size() - 1;
+         }
+         
+      }
+      
+      if(notify)
+      {
+         adjustableParametersChanged();
+      }
+   }
+   else if(idx < theAdjustmentList.size())
+   {
+      theAdjustmentList.erase(theAdjustmentList.begin() + idx);
+      if(theAdjustmentList.size() < 1)
+      {
+         theCurrentAdjustment = 0;
+      }
+      else
+      {
+         if(theCurrentAdjustment > idx)
+         {
+            --theCurrentAdjustment;
+            if(notify)
+            {
+               adjustableParametersChanged();
+            }
+         }
+      }
+      if(notify)
+      {
+         adjustableParametersChanged();
+      }
+   }
+}
+
+double ossimAdjustableParameterInterface::getAdjustableParameter(ossim_uint32 idx)const
+{
+   if(theAdjustmentList.size())
+   {
+      if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+      {
+         return theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].getParameter();
+      }
+   }
+   
+   return 0.0;
+}
+
+void ossimAdjustableParameterInterface::setAdjustableParameter(ossim_uint32 idx, double value, double sigma, bool notify)
+{
+   if(!theAdjustmentList.size())
+   {
+      return;
+   }
+   if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+   {
+      theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].setParameter(value);
+      theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].setSigma(sigma);
+      if(notify)
+      {
+         adjustableParametersChanged();
+      }
+   }
+   
+}
+
+void ossimAdjustableParameterInterface::setAdjustableParameter(ossim_uint32 idx, double value, bool notify)
+{
+   if(!theAdjustmentList.size())
+   {
+      return;
+   }
+   if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+   {
+      theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].setParameter(value);
+
+      if(notify)
+      {
+         adjustableParametersChanged();
+      }
+   }
+}
+
+double ossimAdjustableParameterInterface::getParameterSigma(ossim_uint32 idx)const
+{
+   if(theAdjustmentList.size())
+   {
+      if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+      {
+         return theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].getSigma();
+      }
+   }
+
+   return 0.0;
+}
+
+void ossimAdjustableParameterInterface::setParameterSigma(ossim_uint32 idx, double value, bool notify)
+{
+   if(!theAdjustmentList.size())
+   {
+      return;
+   }
+   if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+   {
+      theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].setSigma(value);
+      if(notify)
+      {
+         adjustableParametersChanged();
+      }
+   }
+}
+
+ossimUnitType ossimAdjustableParameterInterface::getParameterUnit(ossim_uint32 idx)const
+{
+   if(theAdjustmentList.size())
+   {
+      if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+      {
+         return theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].getUnit();
+      }
+   }
+
+   return OSSIM_UNIT_UNKNOWN;
+}
+
+void ossimAdjustableParameterInterface::setParameterUnit(ossim_uint32 idx, ossimUnitType unit)
+{
+   if(theAdjustmentList.size())
+   {
+      if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+      {
+         theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].setUnit(unit);
+      }
+   }
+}
+
+void ossimAdjustableParameterInterface::setParameterUnit(ossim_uint32 idx, const ossimString& unit)
+{
+   if(theAdjustmentList.size())
+   {
+      if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+      {
+         theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].setUnit((ossimUnitType)ossimUnitTypeLut().getEntryNumber(unit));
+      }
+   }
+}
+
+
+ossimString ossimAdjustableParameterInterface::getParameterDescription(ossim_uint32 idx)const
+{
+   if(theAdjustmentList.size())
+   {
+      if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+      {
+         return theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].getDescription();
+      }
+   }
+
+   return ossimString("");
+}
+
+void ossimAdjustableParameterInterface::setParameterDescription(ossim_uint32 idx,
+                                                                const ossimString& description)
+{
+   if(!theAdjustmentList.size())
+   {
+      return;
+   }
+   if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+   {
+      theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].setDescription(description);
+   }
+}
+
+void  ossimAdjustableParameterInterface::setParameterCenter(ossim_uint32 idx, double center, bool notify)
+{
+   if(!theAdjustmentList.size())
+   {
+      return;
+   }
+
+   if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+   {
+     theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].setCenter(center);
+
+	 if(notify)
+	 {
+	   adjustableParametersChanged();
+	 }
+   }
+}
+
+double ossimAdjustableParameterInterface::getParameterCenter(ossim_uint32 idx)const
+{
+   if(!theAdjustmentList.size())
+   {
+      return 0.0;
+   }
+   if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+   {
+      return theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].getCenter();
+   }
+
+   return 0.0;
+}
+
+double   ossimAdjustableParameterInterface::computeParameterOffset(ossim_uint32 idx)const
+{
+   if(!theAdjustmentList.size())
+   {
+      return 0.0;
+   }
+   if(idx < theAdjustmentList[theCurrentAdjustment].getNumberOfAdjustableParameters())
+   {
+      return theAdjustmentList[theCurrentAdjustment].getParameterList()[idx].computeOffset();
+   }
+
+   return 0.0;
+}
+
+void ossimAdjustableParameterInterface::setParameterOffset(ossim_uint32 idx,
+                                                           ossim_float64 value,
+                                                           bool notify)
+{
+   double center   = getParameterCenter(idx);
+   double sigma    = getParameterSigma(idx);
+   double minValue = center - sigma;
+   double maxValue = center + sigma;
+   double x = 0.0;
+   
+   if(sigma != 0.0)
+   {
+      x = (value - center)/sigma;
+      
+      value = center + x*sigma;
+      
+      if(value < minValue)
+      {
+         x = -1;
+      }
+      else if(value >maxValue)
+      {
+         x = 1.0;
+      }
+      setAdjustableParameter(idx, x, false);
+   }   
+   if(notify)
+   {
+      adjustableParametersChanged();
+   }
+}
+
+void ossimAdjustableParameterInterface::resizeAdjustableParameterArray(ossim_uint32 numberOfParameters)
+{
+   if(!theAdjustmentList.size())
+   {
+      newAdjustment(numberOfParameters);
+      return;
+   }
+
+   theAdjustmentList[theCurrentAdjustment].setNumberOfAdjustableParameters(numberOfParameters);
+}
+
+void ossimAdjustableParameterInterface::setAdjustment(const ossimAdjustmentInfo& adj, bool notify)
+{
+   setAdjustment(theCurrentAdjustment, adj, notify);
+}
+
+void ossimAdjustableParameterInterface::setAdjustment(ossim_uint32 idx, const ossimAdjustmentInfo& adj, bool notify)
+{
+   if(idx < getNumberOfAdjustments())
+   {
+      theAdjustmentList[(int)idx] = adj;
+      if(notify)
+      {
+         adjustableParametersChanged();
+      }
+   }
+}
+
+
+void ossimAdjustableParameterInterface::addAdjustment(const ossimAdjustmentInfo& adj, bool notify)
+{
+   theAdjustmentList.push_back(adj);
+   if(notify)
+   {
+      adjustableParametersChanged();
+   }
+}
+
+void ossimAdjustableParameterInterface::getAdjustment(ossimAdjustmentInfo& adj)
+{
+   getAdjustment(theCurrentAdjustment,  adj);
+}
+
+void ossimAdjustableParameterInterface::getAdjustment(ossim_uint32 idx, ossimAdjustmentInfo& adj)
+{
+   adj.setNumberOfAdjustableParameters(0);
+
+   if(idx < getNumberOfAdjustments())
+   {
+      adj = theAdjustmentList[(int)idx];
+   }
+}
+
+ossim_uint32 ossimAdjustableParameterInterface::getNumberOfAdjustments()const
+{
+   return theAdjustmentList.size();
+}
+
+ossim_uint32 ossimAdjustableParameterInterface::getCurrentAdjustmentIdx()const
+{
+   return theCurrentAdjustment;
+}
+
+void ossimAdjustableParameterInterface::setDirtyFlag(bool flag)
+{
+   if(theAdjustmentList.size() > 0)
+   {
+      theAdjustmentList[theCurrentAdjustment].setDirtyFlag(flag);
+   }
+}
+
+void ossimAdjustableParameterInterface::setAllDirtyFlag(bool flag)
+{
+   ossim_uint32 idx = 0;
+   
+   for(idx = 0; idx < theAdjustmentList.size(); ++idx)
+   {
+      theAdjustmentList[idx].setDirtyFlag(flag);
+   }
+}
+
+bool ossimAdjustableParameterInterface::hasDirtyAdjustments()const
+{
+   ossim_uint32 idx = 0;
+      
+   for(idx = 0; idx < theAdjustmentList.size(); ++idx)
+   {
+      if(theAdjustmentList[idx].isDirty())
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+bool ossimAdjustableParameterInterface::saveAdjustments(ossimKeywordlist& kwl,
+                                                        const ossimString& prefix)const
+{
+   kwl.add(prefix,
+           NUMBER_OF_ADJUSTMENTS_KW,
+           theAdjustmentList.size(),
+           true);
+   kwl.add(prefix,
+           CURRENT_ADJUSTMENT_KW,
+           (int)theCurrentAdjustment,
+           true);
+   
+   for(ossim_uint32 adjIdx = 0; adjIdx < theAdjustmentList.size(); ++adjIdx)
+   {
+      ossimString adjPrefix = prefix + (ossimString(ADJUSTMENT_PREFIX) + ossimString::toString(adjIdx)+".");
+
+      theAdjustmentList[adjIdx].saveState(kwl,
+                                          adjPrefix);
+   }
+
+   return true;
+}
+
+bool ossimAdjustableParameterInterface::loadAdjustments(const ossimKeywordlist& kwl,
+                                                        const ossimString& prefix)
+{
+   theAdjustmentList.clear();
+   theCurrentAdjustment = 0;
+   
+   const char* numberOfAdjustments = kwl.find(prefix, NUMBER_OF_ADJUSTMENTS_KW);
+   const char* currentAdjustment   = kwl.find(prefix, CURRENT_ADJUSTMENT_KW);
+
+   if(!numberOfAdjustments)
+   {
+      numberOfAdjustments = kwl.find(prefix, NUMBER_OF_ADJUSTMENTS_OLD_KW);
+   }
+   if(!currentAdjustment)
+   {
+      currentAdjustment = kwl.find(prefix, CURRENT_ADJUSTMENT_OLD_KW);
+   }
+   if(!numberOfAdjustments) return false;
+   
+   int maxdjustments = ossimString(numberOfAdjustments).toInt();
+   
+   for(int adjIdx = 0; adjIdx <maxdjustments; ++adjIdx)
+   {
+      ossimAdjustmentInfo info;
+      ossimString adjPrefix = prefix + (ossimString(ADJUSTMENT_PREFIX) + ossimString::toString(adjIdx)+".");
+
+      if(!info.loadState(kwl, adjPrefix))
+      {
+         return false;
+      }
+      theAdjustmentList.push_back(info);
+   }
+
+   theCurrentAdjustment = ossimString(currentAdjustment).toUInt32();
+   
+   return true;
+}
+
+void ossimAdjustableParameterInterface::adjustableParametersChanged()
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInterface.h b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInterface.h
new file mode 100644
index 0000000000..fa239af00c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustableParameterInterface.h
@@ -0,0 +1,121 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimAdjustableParameterInterface.h,v 1.29 2005/12/09 17:02:30 gpotts Exp $
+#ifndef ossimAdjustableParameterInterface_HEADER
+#define ossimAdjustableParameterInterface_HEADER
+#include "base/common/ossimRtti.h"
+#include <vector>
+#include "ossimAdjustmentInfo.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/common/ossimObject.h"
+
+class OSSIMDLLEXPORT ossimAdjustableParameterInterface
+{
+public:
+   ossimAdjustableParameterInterface();
+   virtual ~ossimAdjustableParameterInterface(){}
+   void newAdjustment(ossim_uint32 numberOfParameters=0);
+   void setAdjustmentDescription(const ossimString& description);
+   ossimString getAdjustmentDescription()const;
+   void setCurrentAdjustment(ossim_uint32 adjustmentIndex, bool notify=false);
+   void eraseAdjustment(bool notify);
+   void eraseAdjustment(ossim_uint32 idx, bool notify);
+   virtual void initAdjustableParameters();
+   void resetAdjustableParameters(bool notify=false);
+   void copyAdjustment(ossim_uint32 idx, bool notify);
+   void copyAdjustment(bool notify = false);
+
+   virtual ossimObject* getBaseObject()=0;
+   virtual const ossimObject* getBaseObject()const=0;
+   
+   /*!
+    * Will copy the adjustment but will set the new center to the
+    * applied current center plus the application of the adjustment
+    *
+    */
+   void keepAdjustment(ossim_uint32 idx, bool createCopy);
+   void keepAdjustment(bool createCopy=true);
+   
+   
+   void removeAllAdjustments();
+   ossim_uint32 getNumberOfAdjustableParameters()const;
+   double       getAdjustableParameter(ossim_uint32 idx)const;
+   void         setAdjustableParameter(ossim_uint32 idx, double value,
+                                       bool notify=false);
+   void         setAdjustableParameter(ossim_uint32 idx,
+                                       double value,
+                                       double sigma,
+                                       bool notify=false);
+   double       getParameterSigma(ossim_uint32 idx)const;
+   void         setParameterSigma(ossim_uint32 idx,
+                                  double value,
+                                  bool notify=false);
+   ossimUnitType getParameterUnit(ossim_uint32 idx)const;
+   void          setParameterUnit(ossim_uint32 idx, ossimUnitType unit);
+   void          setParameterUnit(ossim_uint32 idx, const ossimString& unit);
+
+   void           setParameterCenter(ossim_uint32 idx,
+                                     double center,
+                                     bool notify = false);
+   double        getParameterCenter(ossim_uint32 idx)const;
+   double        computeParameterOffset(ossim_uint32 idx)const;
+   void          setParameterOffset(ossim_uint32 idx,
+                                    ossim_float64 value,
+                                    bool notify = false);
+   
+   ossimString   getParameterDescription(ossim_uint32 idx)const;
+   void          setParameterDescription(ossim_uint32 idx,
+                                         const ossimString& descrption);
+   
+   void resizeAdjustableParameterArray(ossim_uint32 numberOfParameters);
+
+   void setAdjustment(const ossimAdjustmentInfo& adj, bool notify=false);
+   void setAdjustment(ossim_uint32 idx, const ossimAdjustmentInfo& adj, bool notify=false);
+   
+   void addAdjustment(const ossimAdjustmentInfo& adj, bool notify);
+   void getAdjustment(ossimAdjustmentInfo& adj);
+   void getAdjustment(ossim_uint32 idx, ossimAdjustmentInfo& adj);
+   
+   ossim_uint32 getNumberOfAdjustments()const;
+   ossim_uint32 getCurrentAdjustmentIdx()const;
+
+
+   
+   void setDirtyFlag(bool flag=true);
+   void setAllDirtyFlag(bool flag = true);
+   bool hasDirtyAdjustments()const;
+   
+   bool saveAdjustments(ossimKeywordlist& kwl,
+                        const ossimString& prefix=ossimString(""))const;
+   bool loadAdjustments(const ossimKeywordlist& kwl,
+                        const ossimString& prefix=ossimString(""));
+private:
+   std::vector<ossimAdjustmentInfo> theAdjustmentList;
+   ossim_uint32                     theCurrentAdjustment;
+   
+public:
+   virtual void adjustableParametersChanged();
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustmentInfo.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustmentInfo.cpp
new file mode 100644
index 0000000000..f86b7ccc5e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustmentInfo.cpp
@@ -0,0 +1,188 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimAdjustmentInfo.cpp,v 1.5 2004/09/08 21:58:00 gpotts Exp $
+#include "ossimAdjustmentInfo.h"
+#include "base/common/ossimKeywordNames.h"
+
+static const char* PARAM_PREFIX             = "adj_param_";
+static const char* NUMBER_OF_PARAMS_KW      = "number_of_params";
+static const char* DIRTY_FLAG_KW            = "dirty_flag";
+
+
+std::ostream& operator <<(std::ostream& out, const ossimAdjustmentInfo& data)
+{
+   ossim_int32 idx = 0;
+
+   out << "Description:      " << data.getDescription() << endl
+       << "Number of Params: " << data.theParameterList.size()<< endl
+       << "Dirty flag:       " << data.theDirtyFlag << endl;
+
+   for(idx = 0; idx < (int)data.getNumberOfAdjustableParameters(); ++idx)
+   {
+      out << "Param " << idx << endl;
+      out << data.theParameterList[idx] << endl;
+   }
+
+   return out;
+}
+
+
+ossimAdjustmentInfo::ossimAdjustmentInfo(int numberOfAdjustableParameters)
+   :theParameterList(numberOfAdjustableParameters),
+    theDescription(""),
+    theDirtyFlag(false)
+{
+}
+
+ossimAdjustmentInfo::ossimAdjustmentInfo(const ossimAdjustmentInfo& rhs)
+   :theParameterList(rhs.theParameterList),
+    theDescription(rhs.theDescription),
+    theDirtyFlag(rhs.theDirtyFlag)
+{
+}
+
+void ossimAdjustmentInfo::setNumberOfAdjustableParameters(ossim_uint32 numberOfAdjustableParameters)
+{
+   std::vector<ossimAdjustableParameterInfo> temp = theParameterList;
+
+   theParameterList.resize(numberOfAdjustableParameters);
+   if(temp.size() < numberOfAdjustableParameters)
+   {
+      std::copy(temp.begin(),
+                temp.end(),
+                theParameterList.begin());
+   }
+   else if(temp.size() > numberOfAdjustableParameters)
+   {
+      if(numberOfAdjustableParameters > 0)
+      {
+         std::copy(temp.begin(),
+                   temp.begin()+numberOfAdjustableParameters,
+                   theParameterList.begin());
+      }
+   }
+}
+
+ossim_uint32 ossimAdjustmentInfo::getNumberOfAdjustableParameters()const
+{
+   return theParameterList.size();
+}
+
+ossimString ossimAdjustmentInfo::getDescription()const
+{
+   return theDescription;
+}
+
+void ossimAdjustmentInfo::setDescription(const ossimString& description)
+{
+   theDescription = description;
+}
+
+bool ossimAdjustmentInfo::isDirty()const
+{
+   return theDirtyFlag;
+}
+
+void ossimAdjustmentInfo::setDirtyFlag(bool flag)
+{
+   theDirtyFlag = flag;
+}
+
+void ossimAdjustmentInfo::keep()
+{
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theParameterList.size();++idx)
+   {
+      double center = theParameterList[idx].computeOffset();
+      theParameterList[idx].setParameter(0.0);
+      theParameterList[idx].setCenter(center);
+   }
+}
+
+
+std::vector<ossimAdjustableParameterInfo>& ossimAdjustmentInfo::getParameterList()
+{
+   return theParameterList;
+}
+
+const std::vector<ossimAdjustableParameterInfo>& ossimAdjustmentInfo::getParameterList()const
+{
+   return theParameterList;
+}
+
+
+bool ossimAdjustmentInfo::saveState(ossimKeywordlist& kwl,
+                                    const ossimString& prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::DESCRIPTION_KW,
+           getDescription(),
+           true);
+   kwl.add(prefix.c_str(),
+           NUMBER_OF_PARAMS_KW,
+           theParameterList.size(),
+           true);
+
+   kwl.add(prefix,
+           DIRTY_FLAG_KW,
+           (short)theDirtyFlag,
+           true);
+
+   ossimString value;
+   for(ossim_uint32 idx = 0; idx < theParameterList.size();++idx)
+   {
+      ossimString newPrefix = ossimString(prefix) + (ossimString(PARAM_PREFIX) + ossimString::toString(idx)+".");
+      theParameterList[idx].saveState(kwl, newPrefix.c_str());
+   }
+
+   return true;
+}
+
+bool ossimAdjustmentInfo::loadState(const ossimKeywordlist& kwl,
+                                    const ossimString& prefix)
+{
+   setDescription(kwl.find(prefix, ossimKeywordNames::DESCRIPTION_KW));
+   setNumberOfAdjustableParameters(ossimString(kwl.find(prefix, NUMBER_OF_PARAMS_KW)).toUInt32());
+   const char *dirtyFlag = kwl.find(prefix, DIRTY_FLAG_KW);
+   ossimString value;
+
+   if(dirtyFlag)
+   {
+      theDirtyFlag = ossimString(dirtyFlag).toBool();
+   }
+   else
+   {
+      theDirtyFlag = false;
+   }
+
+   for(ossim_uint32 idx = 0; idx < theParameterList.size();++idx)
+   {
+      ossimString newPrefix = ossimString(prefix) + (ossimString(PARAM_PREFIX) + ossimString::toString(idx)+".");
+      if(!theParameterList[idx].loadState(kwl, newPrefix.c_str()))
+      {
+         return false;
+      }
+   }
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustmentInfo.h b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustmentInfo.h
new file mode 100644
index 0000000000..8aa7aa9b9c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAdjustmentInfo.h
@@ -0,0 +1,62 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimAdjustmentInfo.h,v 1.2 2004/01/09 19:10:09 gpotts Exp $
+#ifndef ossimAdjustmentInfo_HEADER
+#define ossimAdjustmentInfo_HEADER
+#include <vector>
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimString.h"
+#include "ossimAdjustableParameterInfo.h"
+
+class ossimAdjustmentInfo
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimAdjustmentInfo& data);
+   
+   
+   ossimAdjustmentInfo(int numberOfAdjustableParameters=0);
+   ossimAdjustmentInfo(const ossimAdjustmentInfo& rhs);
+   
+   void setNumberOfAdjustableParameters(ossim_uint32 numberOfAdjustableParameters);
+   ossim_uint32 getNumberOfAdjustableParameters()const;
+   ossimString getDescription()const;
+   void setDescription(const ossimString& description);
+   bool isDirty()const;
+   void setDirtyFlag(bool flag=true);
+
+   void keep();
+   
+   std::vector<ossimAdjustableParameterInfo>& getParameterList();
+   const std::vector<ossimAdjustableParameterInfo>& getParameterList()const;
+   
+   bool saveState(ossimKeywordlist& kwl,
+                  const ossimString& prefix=ossimString(""))const;
+   bool loadState(const ossimKeywordlist& kwl,
+                  const ossimString& prefix=ossimString(""));
+   
+private:
+   std::vector<ossimAdjustableParameterInfo> theParameterList;
+   ossimString                               theDescription;
+   mutable bool                              theDirtyFlag;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAdrData.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimAdrData.cpp
new file mode 100644
index 0000000000..cf6945f21e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAdrData.cpp
@@ -0,0 +1,422 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class definition for  ADR_Data.
+//*******************************************************************
+//  $Id: ossimAdrData.cpp,v 1.3 2004/04/02 22:03:54 gpotts Exp $
+
+
+#include <stdlib.h>
+#include <iostream>
+#include <iomanip>
+using namespace std;
+
+
+#include <base/misc/ossimAdrData.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimKeyword.h>
+#include <base/context/ossimNotifyContext.h>
+//! Specifies the longitude of the ul corner of image in degrees
+static const ossimKeyword UL_LONGITUDE("ul_longitude",
+                                  "\
+Specifies the longitude of the ul corner of image in degrees.");
+
+//! Specifies the latitude of the ul corner of image in degrees
+static const ossimKeyword UL_LATITUDE("ul_latitude",
+                                 "\
+Specifies the latitude of the ul corner of image in degrees.");
+
+//! Specifies the longitude of the ur corner of image in degrees
+static const ossimKeyword UR_LONGITUDE("ur_longitude",
+                                  "\
+Specifies the longitude of the ur corner of image in degrees.");
+
+//! Specifies the latitude of the ur corner of image in degrees
+static const ossimKeyword UR_LATITUDE("ur_latitude",
+                                 "\
+Specifies the latitude of the ur corner of image in degrees.");
+
+//! Specifies the longitude of the lr corner of image in degrees
+static const ossimKeyword LR_LONGITUDE("lr_longitude",
+                                  "\
+Specifies the longitude of the lr corner of image in degrees.");
+
+//! Specifies the latitude of the lr corner of image in degrees
+static const ossimKeyword LR_LATITUDE("lr_latitude",
+                                 "\
+Specifies the latitude of the lr corner of image in degrees.");
+
+//! Specifies the longitude of the ll corner of image in degrees
+static const ossimKeyword LL_LONGITUDE("ll_longitude",
+                                  "\
+Specifies the longitude of the ll corner of image in degrees.");
+
+//! Specifies the latitude of the ll corner of image in degrees
+static const ossimKeyword LL_LATITUDE("ll_latitude",
+                                 "\
+Specifies the latitude of the ll corner of image in degrees.");
+
+//! Number of lines in the raster image
+static const ossimKeyword NUMBER_LINES("number_lines",
+                                  "\
+   Number of lines in the raster image.");
+
+//! Number of samples in the raster image
+static const ossimKeyword NUMBER_SAMPLES("number_samples",
+                                    "\
+   Number of samples in the raster image.");
+
+//! Upper left latitude of the image
+static const ossimKeyword UPPER_LAT("Upper Lat",
+                               "Upper left latitude of the image.");
+
+//! Upper left longitude of the image
+static const ossimKeyword LEFT_LON("Left Lon",
+                              "Upper left longitude of the image.");
+
+//! Lower right latitude of the image
+static const ossimKeyword LOWER_LAT("Lower Lat",
+                               "Lower right latitude of the image.");
+
+//! Lower Right longitude of the image
+static const ossimKeyword RIGHT_LON("Right Lon",
+                               "Lower Right longitude of the image.");
+
+//! Number of samples of the image
+static const ossimKeyword SAMPLES("Width",
+                             "Number of samples of the image.");
+
+//! Number of lines of the image
+static const ossimKeyword LINES("Height",
+                           "Number of lines of the image.");
+			   
+//! One sigma of position error in meters
+static const ossimKeyword
+POSITION_ERROR("position_error",
+               "One sigma of position error in meters.");
+
+//***************************************************************************
+//! Public Constructor:
+//***************************************************************************
+ossimAdrData::ossimAdrData()
+   :
+      theLines(0),
+      theSamples(0),
+      theUlLon(0.0),
+      theUlLat(0.0),
+      theUrLon(0.0),
+      theUrLat(0.0),
+      theLrLon(0.0),
+      theLrLat(0.0),
+      theLlLon(0.0),
+      theLlLat(0.0),
+      thePositionError(0.0),
+      theErrorStatus(ossimErrorCodes::OSSIM_OK)
+{}
+//***************************************************************************
+// !Public Constructor:
+//***************************************************************************
+ossimAdrData::ossimAdrData(const ossimKeywordlist& kwl)
+   :
+      theLines(0),
+      theSamples(0),
+      theUlLon(0.0),
+      theUlLat(0.0),
+      theUrLon(0.0),
+      theUrLat(0.0),
+      theLrLon(0.0),
+      theLrLat(0.0),
+      theLlLon(0.0),
+      theLlLat(0.0),
+      thePositionError(0.0),
+      theErrorStatus(ossimErrorCodes::OSSIM_OK)
+{
+   static const char MODULE[] = "ossimAdrData::ossimAdrData";
+
+   if (kwl.getErrorStatus())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                          << "Detected an error in the keywordlist.\n";
+      return;
+   }
+
+   const char* kwlLookup = 0;
+   
+   kwlLookup = kwl.find(UL_LONGITUDE);
+   if(kwlLookup)
+   {
+      theUlLon = atof(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(LEFT_LON);
+      if (kwlLookup)
+      {
+         theUlLon = atof(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                             << "Error looking up upper left longitude keyword.\n"
+                                             << "Could not find:  " << UL_LONGITUDE << " or:  " << LEFT_LON
+                                             << " keyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(UL_LATITUDE);
+   if(kwlLookup)
+   {
+      theUlLat = atof(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(UPPER_LAT); 
+      if (kwlLookup)
+      {
+         theUlLat = atof(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                             << "Error looking up upper left latitude keyword.\n"
+                                             << "Could not find:  " << UL_LATITUDE << " or:  " << UPPER_LAT
+                                             << " keyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(UR_LONGITUDE);
+   if(kwlLookup)
+   {
+      theUrLon = atof(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(RIGHT_LON);
+      if (kwlLookup)
+      {
+         theUrLon = atof(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                             << "Error looking up upper right longitude keyword.\n"
+                                             << "Could not find:  " << UR_LONGITUDE << " or:  " << RIGHT_LON
+                                             << " keyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(UR_LATITUDE);
+   if(kwlLookup)
+   {
+      theUrLat = atof(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(UPPER_LAT); 
+      if (kwlLookup)
+      {
+         theUrLat = atof(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                             << "Error looking up upper right latitude keyword.\n"
+                                             << "Could not find:  " << UR_LATITUDE << " or:  " << UPPER_LAT
+                                             << " keyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(LR_LONGITUDE);
+   if(kwlLookup)
+   {
+      theLrLon = atof(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(RIGHT_LON);
+      if (kwlLookup)
+      {
+         theLrLon = atof(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL)<< MODULE << " ERROR:\n"
+                                            << "Error looking up lower right longitude keyword.\n"
+                                            << "Could not find:  " << LR_LONGITUDE << " or:  " << RIGHT_LON
+                                            << " keyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(LR_LATITUDE);
+   if(kwlLookup)
+   {
+      theLrLat = atof(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(LOWER_LAT); 
+      if (kwlLookup)
+      {
+         theLrLat = atof(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                             << "Error looking up lower right latitude keyword.\n"
+                                             << "Could not find:  " << LR_LATITUDE << " or:  " << LOWER_LAT
+                                             << " keyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(LL_LONGITUDE);
+   if(kwlLookup)
+   {
+      theLlLon = atof(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(LEFT_LON);
+      if (kwlLookup)
+      {
+         theLlLon = atof(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                             << "Error looking up lower left longitude keyword.\n"
+                                             << "Could not find:  " << LL_LONGITUDE << " or:  " << LEFT_LON
+                                             << " keyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(LL_LATITUDE);
+   if(kwlLookup)
+   {
+      theLlLat = atof(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(LOWER_LAT); 
+      if (kwlLookup)
+      {
+         theLlLat = atof(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                             << "Error looking up lower left latitude keyword.\n"
+                                             << "Could not find:  " << LL_LATITUDE << " or:  " << LOWER_LAT
+                                             << " keyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(NUMBER_LINES);
+   if(kwlLookup)
+   {
+      theLines = atoi(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(LINES);  
+      if (kwlLookup)
+      {
+         theLines = atoi(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                             << "Error looking up lines keyword.\n"
+                                             << "Could not find:  " << NUMBER_LINES << " or: " << LINES
+                                             << " kwyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(NUMBER_SAMPLES);
+   if(kwlLookup)
+   {
+      theSamples = atoi(kwlLookup);
+   }
+   else
+   {
+      kwlLookup = kwl.find(SAMPLES);  
+      if (kwlLookup)
+      {
+         theSamples = atoi(kwlLookup);
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:\n"
+                                             << "Error looking up lines keyword.\n"
+                                             << "Could not find:  " << NUMBER_SAMPLES << " or: " << SAMPLES
+                                             << " kwyword.\n";
+      }
+   }
+
+   kwlLookup = kwl.find(POSITION_ERROR);
+   if(kwlLookup)
+   {
+      thePositionError = atof(kwlLookup);
+   }
+}
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+//! Prints a list of keywords and respective values
+
+void ossimAdrData::print(ostream& os) const
+{
+   os << setiosflags(ios::fixed) << setprecision(10)
+      << "number_lines:        " << theLines            << "\n"
+      << "number_samples:      " << theSamples          << "\n"
+      << "ul_longitude:        " << theUlLon            << "\n"
+      << "ul_latitude:         " << theUlLat            << "\n"
+      << "ur_longitude:        " << theUrLon            << "\n"
+      << "ur_latitude:         " << theUrLat            << "\n"
+      << "lr_longitude:        " << theLrLon            << "\n"
+      << "lr_latitude:         " << theLrLat            << "\n"
+      << "ll_longitude:        " << theLlLon            << "\n"
+      << "ll_latitude:         " << theLlLat            << "\n"
+      << "position_error:      " << thePositionError    << "\n"
+      << "\n";
+}
+
+//***************************************************************************
+// Function:
+//***************************************************************************
+ostream& operator<<(ostream& os, const ossimAdrData& ad)
+{
+   ad.print(os);
+
+   return os;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAdrData.h b/Utilities/OSSIM/ossim_core/base/misc/ossimAdrData.h
new file mode 100644
index 0000000000..6ccebd8110
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAdrData.h
@@ -0,0 +1,63 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for ossimAdrData. 
+//*******************************************************************
+// $Id: ossimAdrData.h,v 1.5 2003/05/13 11:31:03 dburken Exp $
+
+#ifndef ossimAdrData_HEADER
+#define ossimAdrData_HEADER
+
+#include "base/common/ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimKeywordlist;
+
+//*******************************************************************
+// CLASS:  ossimAdrData
+//*******************************************************************
+class OSSIMDLLEXPORT ossimAdrData
+{
+public:
+   ossimAdrData  ();
+   ossimAdrData (const ossimKeywordlist& kwl);
+   ~ossimAdrData (){};
+
+   ossim_int32 getErrorStatus() const { return theErrorStatus; } 
+   
+   void print(ostream& os) const;
+
+   friend ostream& operator<<(ostream& os, const ossimAdrData& ad);
+
+   ossim_sint32      theLines;
+   ossim_sint32      theSamples;
+   ossim_float64     theUlLon;
+   ossim_float64     theUlLat;
+   ossim_float64     theUrLon;
+   ossim_float64     theUrLat;
+   ossim_float64     theLrLon;
+   ossim_float64     theLrLat;
+   ossim_float64     theLlLon;
+   ossim_float64     theLlLat;
+   ossim_float64     thePositionError;
+   ossim_int32       theErrorStatus;
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAffineTransform.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimAffineTransform.cpp
new file mode 100644
index 0000000000..96b76510e3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAffineTransform.cpp
@@ -0,0 +1,219 @@
+//*****************************************************************************
+// FILE: ossimAffineTransform.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains implementation of class ossimAffineTransform
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimAffineTransform.cpp,v 1.5 2003/12/22 18:48:32 dburken Exp $
+
+#include "ossimAffineTransform.h"
+RTTI_DEF1(ossimAffineTransform, "ossimAffineTransform", ossim2dTo2dTransform);
+
+#include "base/common/ossimKeywordNames.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/data_types/ossimMatrix3x3.h"
+
+//*****************************************************************************
+//  CONSTRUCTOR: 
+//*****************************************************************************
+ossimAffineTransform::ossimAffineTransform()
+   :
+      theForwardXform(3, 3),
+      theInverseXform(3, 3),
+      theAffineEnabledFlag(true)
+{
+   setIdentity();
+}
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+void ossimAffineTransform::forward(const ossimDpt& input,
+                                   ossimDpt& output) const
+{
+   if(theAffineEnabledFlag)
+   {
+      output.x = theForwardXform[0][0]*input.x+
+                 theForwardXform[0][1]*input.y+
+                 theForwardXform[0][2];
+      output.y = theForwardXform[1][0]*input.x+
+                 theForwardXform[1][1]*input.y+
+                 theForwardXform[1][2];
+   }
+   else
+   {
+      output = input;
+   }
+}
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+void ossimAffineTransform::inverse(const ossimDpt& input,
+                                   ossimDpt&       output) const
+{
+   if(theAffineEnabledFlag)
+   {
+      output.x = theInverseXform[0][0]*input.x+
+                 theInverseXform[0][1]*input.y+
+                 theInverseXform[0][2];
+      output.y = theInverseXform[1][0]*input.x+
+                 theInverseXform[1][1]*input.y+
+                 theInverseXform[1][2];
+   }
+   else
+   {
+      output = input;
+   }
+}
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+bool ossimAffineTransform::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_X_KW,
+           theScale.x,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_Y_KW,
+           theScale.y,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::TRANSLATION_X_KW,
+           theTranslation.x,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::TRANSLATION_Y_KW,
+           theTranslation.y,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::ROTATION_KW,
+           theRotation,
+           true);
+
+   ossim2dTo2dTransform::saveState(kwl, prefix);
+   
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+bool ossimAffineTransform::loadState(const ossimKeywordlist& kwl,
+               const char* prefix)
+{
+   const char* buf;
+
+   if (!ossim2dTo2dTransform::loadState(kwl, prefix))
+      goto BAD_KEYWORD;
+       
+   buf= kwl.find(prefix, ossimKeywordNames::SCALE_X_KW);
+   if (!buf) goto BAD_KEYWORD;
+   theScale.x = atof(buf);
+
+   buf= kwl.find(prefix, ossimKeywordNames::SCALE_Y_KW);
+   if (!buf) goto BAD_KEYWORD;
+   theScale.y = atof(buf);
+
+   buf= kwl.find(prefix, ossimKeywordNames::TRANSLATION_X_KW);
+   if (!buf) goto BAD_KEYWORD;
+   theTranslation.x = atof(buf);
+
+   buf= kwl.find(prefix, ossimKeywordNames::TRANSLATION_Y_KW);
+   if (!buf) goto BAD_KEYWORD;
+   theTranslation.y = atof(buf);
+
+   buf= kwl.find(prefix, ossimKeywordNames::ROTATION_KW);
+   if (!buf) goto BAD_KEYWORD;
+   theRotation = atof(buf);
+
+   computeMatrix();   
+   return true;
+
+ BAD_KEYWORD:
+   return false;
+}
+   
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+void ossimAffineTransform::setMatrix(double rotation,
+                                     const ossimDpt& scale,
+                                     const ossimDpt& translation)
+{
+   theScale       = scale;
+   theRotation    = rotation;
+   theTranslation = translation;
+   
+   computeMatrix();
+}
+   
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+void ossimAffineTransform::setIdentity()
+{
+   theScale.x       = 1;
+   theScale.y       = 1;
+   theTranslation.x = 0;
+   theTranslation.y = 0;
+   theRotation      = 0.0;
+   
+   computeMatrix();
+}
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+void ossimAffineTransform::computeMatrix()
+{
+   theForwardXform =
+      ossimMatrix3x3::createTranslationMatrix(theTranslation.x, 
+                                              theTranslation.y)* 
+      ossimMatrix3x3::createRotationZMatrix(theRotation)* 
+      ossimMatrix3x3::createScaleMatrix(theScale.x,
+                                        theScale.y,
+                                        1.0);
+
+   //***
+   // The inverse transform is just the matrix inverse:
+   //***
+   theInverseXform = theForwardXform.i();
+}
+
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+std::ostream& ossimAffineTransform::print(std::ostream& os) const
+{
+   os << "ossimAffineTransform:"
+      << "\n  theScale       = " << theScale
+      << "\n  theTranslation = " << theTranslation
+      << "\n  theRotation    = " << theRotation << endl;
+   return os;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimAffineTransform.h b/Utilities/OSSIM/ossim_core/base/misc/ossimAffineTransform.h
new file mode 100644
index 0000000000..e0df1dddb6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimAffineTransform.h
@@ -0,0 +1,110 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public License 
+// as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU Library General Public License
+// along with this library. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimAffineTransform.h,v 1.4 2003/12/22 18:48:32 dburken Exp $
+
+#ifndef ossimAffineTransform_HEADER
+#define ossimAffineTransform_HEADER
+
+#include "ossim2dTo2dTransform.h"
+#include "matrix/newmat.h"
+
+class OSSIMDLLEXPORT ossimAffineTransform : public ossim2dTo2dTransform
+{
+public:
+   ossimAffineTransform();
+
+   virtual void forward(const ossimDpt& input,
+                        ossimDpt& output)const;
+   virtual void inverse(const ossimDpt& input,
+                        ossimDpt&       output)const;
+
+   /*!
+    * Used by the inverse iterator.  This will give it a good initial value
+    * that is within the input transforms
+    */
+   virtual ossimDpt getOrigin()const
+      {
+         return ossimDpt(0,0);
+      }
+   
+   bool saveState(ossimKeywordlist& kwl,
+                   const char* prefix = 0)const;
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix = 0);
+   
+   void setMatrix(double rotation,
+                  const ossimDpt& scale,
+                  const ossimDpt& translation);
+   
+   void setScale(const ossimDpt& scale)
+      {
+         theScale       = scale;
+         computeMatrix();
+      }
+   
+   void setRotation(double rotation)
+      {
+         theRotation = rotation;
+         computeMatrix();
+      }
+
+   void setTranslation(const ossimDpt& translation)
+      {
+         theTranslation = translation;
+         computeMatrix();
+      }
+   ossimDpt getScale()const
+      {
+         return theScale;
+      }
+   ossimDpt getTranslation()const
+      {
+         return theTranslation;
+      }
+   double getRotation()const
+      {
+         return theRotation;
+      }
+   void setIdentity();
+
+   void setAffineEnabledFlag(bool flag)
+      {
+         theAffineEnabledFlag = flag;
+      }
+   virtual std::ostream& print(std::ostream& out) const;
+      
+protected:
+   void computeMatrix();
+   
+   NEWMAT::Matrix theForwardXform;
+   NEWMAT::Matrix theInverseXform;
+
+   ossimDpt       theScale;
+   double         theRotation;
+   ossimDpt       theTranslation;
+   bool           theAffineEnabledFlag;
+
+TYPE_DATA      
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimBilSplitter.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimBilSplitter.cpp
new file mode 100644
index 0000000000..c46dca0c39
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimBilSplitter.cpp
@@ -0,0 +1,184 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class definition for ossimBilSplitter.
+//
+// Utility class for splitting an image that is band interleaved by line into
+// separate files.
+//*******************************************************************
+//  $Id: ossimBilSplitter.cpp,v 1.6 2004/04/02 22:03:54 gpotts Exp $
+
+#include <iomanip>
+#include <iostream>
+using namespace std;
+
+#include <base/misc/ossimBilSplitter.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/context/ossimNotifyContext.h>
+
+ossimBilSplitter::ossimBilSplitter(const char* file_to_split,
+                                   ossim_uint32      header_size_in_bytes,
+                                   ossim_uint32      bytes_per_pixel,
+                                   ossim_uint32      samples_per_line,
+                                   ossim_uint32      number_of_channels)
+   :
+      theSourceFileStr(),
+      theHeaderSizeInBytes(header_size_in_bytes),
+      theBytesPerLine(bytes_per_pixel * samples_per_line),
+      theLinesToWrite(0),
+      theNumberOfChannels(number_of_channels),
+      theErrorStatus(OSSIM_OK)
+{
+   static const char MODULE[] = "ossimBilSplitter::ossimBilSplitter";
+                                
+   //***
+   // Open up the source bil file and check for a good descriptor.
+   //***
+   theSourceFileStr.open(file_to_split, ios::in | ios::binary);
+   if (!theSourceFileStr)
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << MODULE << ":\nCould not open file:  " << file_to_split
+           << "\n";
+      
+      return;
+   }
+
+   //***
+   // Get the file size to make sure that the ( size - header ) / byte per line
+   // come out even; if not, consider this an error.
+   //***
+   ossimFilename f(file_to_split);
+   ossim_uint32 size = f.fileSize();
+   
+   if ( (size-theHeaderSizeInBytes) % (theBytesPerLine * theNumberOfChannels) )
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << MODULE << ":"
+                                          << "\nFile size error..."
+                                          << "\nbytes_per_pixel * samples_per_line * "
+                                          << "number_of_channels should"
+                                          << "\ndivide evenly into total file size in bytes."
+                                          << "\nHeader size in bytes:  " << header_size_in_bytes
+                                          << "\nBytes per pixel:       " << bytes_per_pixel
+                                          << "\nSamples per line:      " << samples_per_line
+                                          << "\nBytes per line:        " << theBytesPerLine
+                                          << "\nNumber of channels:    " << theNumberOfChannels
+                                          << "\nFile size in bytes:    " << size
+                                          << "\nthe file size in bytes.  Returning with error."
+                                          << "\n";
+      return;
+   }
+
+   theLinesToWrite = (size-theHeaderSizeInBytes) /
+                     (theBytesPerLine * theNumberOfChannels);
+
+   ossimNotify(ossimNotifyLevel_INFO) << "\nFile to split:               " << file_to_split
+                                      << "\nHeader size in bytes:        " << header_size_in_bytes
+                                      << "\nBytes per pixel:             " << bytes_per_pixel
+                                      << "\nSamples per line:            " << samples_per_line
+                                      << "\nBytes per line:              " << theBytesPerLine
+                                      << "\nNumber of channels:          " << theNumberOfChannels
+                                      << "\nLines to write per channel:  " << theLinesToWrite
+                                      << "\n";
+}
+
+ossimBilSplitter::~ossimBilSplitter()
+{
+   theSourceFileStr.close();
+}
+
+bool ossimBilSplitter::output_multi_files(const char* output_dir)
+{
+   static const char MODULE[] = "ossimBilSplitter::output_multi_files";
+   
+   if (theErrorStatus)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " :"
+           << "\nError status has been set.  Cannot split file." << "\n";
+      return false;
+   }
+   
+   // Open up all the FILE pointers needed.
+   ossimFilename outDir = output_dir;
+   ossimString base("channel_");
+   ossimString ext(".ras");
+   ofstream* os = new ofstream[theNumberOfChannels];
+
+   ossim_uint32 i = 0;
+   for(i = 0; i < theNumberOfChannels; i++)
+   {
+      ossimString file_basename = base + ossimString::toString(int(i+1)) + ext;
+      ossimFilename tmpFile = outDir.dirCat(file_basename);
+      
+      os[i].open(tmpFile.c_str(), ios::out | ios::binary);
+
+      if (!os)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << MODULE << ":\n"
+              << "Cannot open:  " << tmpFile.c_str()
+              << "\nReturning from application." << "\n";
+         return false;
+      }
+   }
+
+   char* lineBuffer = new char[theBytesPerLine];
+
+   // Move the source pointer past the header.
+   theSourceFileStr.seekg(theHeaderSizeInBytes, ios::beg);
+   
+   // Write the lines out to the individual files.
+   ossimNotify(ossimNotifyLevel_INFO) << "\nOutputting to separate files to:  " << output_dir << "\n";
+   
+   for (i=0; i<theLinesToWrite; ++i)
+   {
+      for(ossim_uint32 j=0; j < theNumberOfChannels; ++j)
+      {
+         // Read a line.
+         theSourceFileStr.read(lineBuffer, theBytesPerLine);
+
+         // Write the line to the channel file.
+         os[j].write(lineBuffer, theBytesPerLine);
+
+      } // End of loop through the channels.
+
+      //***
+      // Output some status info.
+      //***
+      ossim_float64 totalLines     = theLinesToWrite;
+      ossim_float64 linesWritten   = i + 1;
+      ossimNotify(ossimNotifyLevel_INFO) << setiosflags(ios::fixed)
+                                         << setprecision(0) << setw(3)
+                                         << linesWritten / totalLines * 100.0 << " % \r"
+                                         << flush;
+
+   } // End of loop through lines.
+
+   ossimNotify(ossimNotifyLevel_INFO) << "100 %\nFinished...\n";
+
+   // Cleanup.
+   for(i = 0; i < theNumberOfChannels; i++) os[i].close();
+   delete [] os;
+   delete [] lineBuffer;   
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimBilSplitter.h b/Utilities/OSSIM/ossim_core/base/misc/ossimBilSplitter.h
new file mode 100644
index 0000000000..26f41d27c1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimBilSplitter.h
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for ossimBilSplitter.
+// 
+// Utility class for splitting an image that is band interleaved by line into
+// separate files.
+//*******************************************************************
+//  $Id: ossimBilSplitter.h,v 1.3 2003/05/13 11:31:03 dburken Exp $
+
+#ifndef ossimBilSplitter_HEADER
+#define ossimBilSplitter_HEADER
+
+#include <fstream>
+using namespace std;
+
+#include "base/common/ossimConstants.h"
+
+class OSSIMDLLEXPORT ossimBilSplitter
+{
+public:
+   ossimBilSplitter(const char* file_to_split,
+                    ossim_uint32      header_size_in_bytes,
+                    ossim_uint32      bytes_per_pixel,
+                    ossim_uint32      samples_per_line,
+                    ossim_uint32      number_of_channels);
+
+   ~ossimBilSplitter();
+
+   enum ossimStatus
+   {
+      OSSIM_OK    = 0,
+      OSSIM_ERROR = 1
+   };
+
+   /*!
+    *  Splits source image into separate bands and writes to output
+    *  directory as channel_1.ras, channel_2.ras, ...
+    *  Returns true on success, false on error.
+    */
+   bool output_multi_files(const char* output_dir);
+
+   int errorStatus() const { return theErrorStatus; }
+
+private:
+
+   ifstream      theSourceFileStr;
+   ossim_uint32  theHeaderSizeInBytes;
+   ossim_uint32  theBytesPerLine;
+   ossim_uint32  theLinesToWrite;
+   ossim_uint32  theNumberOfChannels;
+   ossimStatus   theErrorStatus;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimEndian.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimEndian.cpp
new file mode 100644
index 0000000000..c42ae282e1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimEndian.cpp
@@ -0,0 +1,213 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: This file contains the implementation of the
+//              endian byte swap routines.
+//
+//***********************************
+// $Id: ossimEndian.cpp,v 1.6 2005/02/09 15:16:58 dburken Exp $
+
+#include <base/misc/ossimEndian.h>
+
+ossimEndian::ossimEndian()
+{
+   ossim_uint16  test;
+   ossim_uint8  *testPtr=NULL;
+   test = 0x0001;
+   
+   testPtr       = reinterpret_cast<unsigned char*>(&test);
+   theSystemEndianType = testPtr[0] ? OSSIM_LITTLE_ENDIAN : OSSIM_BIG_ENDIAN;
+}
+
+ossimByteOrder ossimEndian::getSystemEndianType() const
+{
+   return theSystemEndianType;
+}
+
+void ossimEndian::swap(ossim_int16 &data) const
+{
+   swapTwoBytes(reinterpret_cast<void*>(&data));   
+} 
+
+void ossimEndian::swap(ossim_uint16 &data) const
+{
+   swapTwoBytes(reinterpret_cast<void*>(&data));
+}
+
+void ossimEndian::swap(ossim_int32 &data) const
+{
+   swapFourBytes(reinterpret_cast<void*>(&data));
+}
+
+void ossimEndian::swap(ossim_uint32 &data) const
+{
+   swapFourBytes(reinterpret_cast<void*>(&data));
+}
+
+void ossimEndian::swap(ossim_float32 &data) const
+{
+   swapFourBytes(reinterpret_cast<void*>(&data));
+}
+
+void ossimEndian::swap(ossim_float64 &data) const
+{
+   swapEightBytes(reinterpret_cast<void*>(&data));
+}
+
+void ossimEndian::swapTwoBytes(void *data) const
+{
+   unsigned char *c = reinterpret_cast<unsigned char*>(data);
+
+   swap(&c[0], &c[1]);
+}
+
+void ossimEndian::swapFourBytes(void* data) const
+{
+   unsigned char *c = reinterpret_cast<unsigned char*>(data);
+
+   swap(&c[0], &c[3]);
+   swap(&c[1], &c[2]);
+}
+
+void ossimEndian::swapEightBytes(void* data) const
+{
+   unsigned char *c = reinterpret_cast<unsigned char*>(data);
+
+   swap(&c[0], &c[7]);
+   swap(&c[1], &c[6]);
+   swap(&c[2], &c[5]);
+   swap(&c[3], &c[4]);
+}
+
+void ossimEndian::swap(ossim_uint8 *c1,                       
+                       ossim_uint8 *c2) const
+{
+   ossim_uint8 temp_c = *c1;
+   *c1 = *c2;
+   *c2 = temp_c;
+}
+
+void ossimEndian::swap(ossimScalarType scalar,
+                       void* data, ossim_uint32 size) const
+{
+   switch (scalar)
+   {
+   case OSSIM_USHORT16:
+   case OSSIM_SSHORT16:
+   case  OSSIM_USHORT11:
+      swapTwoBytes(data, size);
+      return;
+
+   case OSSIM_FLOAT:
+   case OSSIM_NORMALIZED_FLOAT:
+      swapFourBytes(data, size);
+      return;
+
+   case OSSIM_DOUBLE:
+   case OSSIM_NORMALIZED_DOUBLE:
+      swapEightBytes(data, size);
+      break;
+
+   default:
+      return;
+   }
+}
+
+void ossimEndian::swap(ossim_int16* data, ossim_uint32 size) const
+{
+   swapTwoBytes(data, size);
+}
+
+void ossimEndian::swap(ossim_uint16* data, ossim_uint32 size) const
+{
+   swapTwoBytes(data, size);
+}
+
+void ossimEndian::swap(ossim_int32* data, ossim_uint32 size) const
+{
+   swapFourBytes(data, size);
+}
+
+void ossimEndian::swap(ossim_uint32* data, ossim_uint32 size) const
+{
+   swapFourBytes(data, size);
+}
+
+#ifdef HAS_LONG_LONG
+
+void ossimEndian::swap(ossim_int64* data, ossim_uint32 size) const
+{
+   swapEightBytes(data, size);
+}
+
+void ossimEndian::swap(ossim_uint64* data, ossim_uint32 size) const
+{
+   swapEightBytes(data, size);
+}
+
+#endif /* End of #ifdef HAS_LONG_LONG */
+
+void ossimEndian::swap(ossim_float32* data, ossim_uint32 size) const
+{
+   swapFourBytes(data, size);
+}
+
+void ossimEndian::swap(ossim_float64* data, ossim_uint32 size) const
+{
+   swapEightBytes(data, size);
+}
+
+void ossimEndian::swapTwoBytes(void* data, ossim_uint32 size) const
+{
+   ossim_uint16* buf = reinterpret_cast<ossim_uint16*>(data);
+   for (ossim_uint32 i=0; i<size; ++i)
+   {
+      buf[i] = (buf[i] << 8) | (buf[i] >> 8);
+   }
+}
+
+void ossimEndian::swapFourBytes(void* data, ossim_uint32 size) const
+{
+   ossim_uint32* buf = reinterpret_cast<ossim_uint32*>(data);
+   for (ossim_uint32 i=0; i<size; ++i)
+   {
+      buf[i]
+         = (  ((buf[i] & 0xff000000) >> 24)
+            | ((buf[i] & 0x00ff0000) >> 8)
+            | ((buf[i] & 0x0000ff00) << 8)
+            | ((buf[i] & 0x000000ff) << 24));
+   }
+}
+
+void ossimEndian::swapEightBytes(void* data, ossim_uint32 size) const
+{
+#ifdef HAS_LONG_LONG
+   uint64* buf = reinterpret_cast<ossim_uint64*>(data);
+   for (uint32 i=0; i<size; ++i)
+   {
+      buf[i]
+         = (  ((buf[i] & 0xff00000000000000ull) >> 56)
+            | ((buf[i] & 0x00ff000000000000ull) >> 40)
+            | ((buf[i] & 0x0000ff0000000000ull) >> 24)
+            | ((buf[i] & 0x000000ff00000000ull) >> 8)
+            | ((buf[i] & 0x00000000ff000000ull) << 8)
+            | ((buf[i] & 0x0000000000ff0000ull) << 24)
+            | ((buf[i] & 0x000000000000ff00ull) << 40)
+            | ((buf[i] & 0x00000000000000ffull) << 56));
+   }
+#else
+   ossim_float64* buf = reinterpret_cast<ossim_float64*>(data);
+   for (ossim_uint32 i=0; i<size; ++i)
+   {
+      swapEightBytes(buf+i);
+   }
+   
+#endif
+   
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimEndian.h b/Utilities/OSSIM/ossim_core/base/misc/ossimEndian.h
new file mode 100644
index 0000000000..d329d9c2be
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimEndian.h
@@ -0,0 +1,77 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: This file contains the interface to the
+//              endian byte swap
+//
+//***********************************
+// $ID$
+#ifndef ossimEndian_HEADER
+#define ossimEndian_HEADER
+#include <iostream>
+using namespace std;
+
+// for OSSIM_LITTLE_ENDIAN AND BIG_ENDIAN
+#include <base/common/ossimConstants.h>
+
+class OSSIMDLLEXPORT ossimEndian
+{
+public:
+   ossimEndian();
+
+   /*!
+    *  Swap bytes methods that work on a single pixel.
+    */
+   void swap(ossim_int16   &data) const;
+   void swap(ossim_uint16  &data) const;
+   void swap(ossim_int32   &data) const;
+   void swap(ossim_uint32  &data) const;
+   void swap(ossim_float32 &data) const;
+   void swap(ossim_float64 &data) const;
+
+   /*!
+    *  Swap bytes methods that work on arrays of pixels.
+    *
+    *  @note size is number of pixels, not number of bytes.
+    */
+   void swap(ossimScalarType scalar, void* data, ossim_uint32 size) const;
+   
+   void swap(ossim_int16* data, ossim_uint32 size) const;
+   void swap(ossim_uint16* data, ossim_uint32 size) const;
+
+   void swap(ossim_int32* data, ossim_uint32 size) const;
+   void swap(ossim_uint32* data, ossim_uint32 size) const;
+
+#ifdef HAS_LONG_LONG
+   void swap(ossim_int64* data, ossim_uint32 size) const;
+   void swap(ossim_uint64* data, ossim_uint32 size) const;
+#endif
+
+   void swap(ossim_float32* data, ossim_uint32 size) const;
+   void swap(ossim_float64* data, ossim_uint32 size) const;
+
+   void swapTwoBytes(void* data, ossim_uint32 size) const;
+   void swapFourBytes(void* data, ossim_uint32 size) const;
+   void swapEightBytes(void* data, ossim_uint32 size) const;
+   ossimByteOrder getSystemEndianType() const;
+
+private:
+
+   // Holds the Endian of the architecture that you are running on.
+   ossimByteOrder  theSystemEndianType;  
+   
+   void swapTwoBytes(void *data) const;
+   void swapFourBytes(void *data) const;
+   void swapEightBytes(void *data) const;
+
+   void swap(ossim_uint8 *c1,
+             ossim_uint8 *c2) const;
+};
+
+#endif /* End of #ifndef ossimEndian_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenDefines.h b/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenDefines.h
new file mode 100644
index 0000000000..24e6b6badc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenDefines.h
@@ -0,0 +1,54 @@
+#ifndef ossimEquTokenDefines_HEADER
+#define ossimEquTokenDefines_HEADER
+
+#define OSSIM_EQU_TOKEN_LEFT_PAREN  1
+#define OSSIM_EQU_TOKEN_RIGHT_PAREN 2
+#define OSSIM_EQU_TOKEN_LOG         3
+#define OSSIM_EQU_TOKEN_MULT        4
+#define OSSIM_EQU_TOKEN_DIV         5
+#define OSSIM_EQU_TOKEN_MINUS             6
+#define OSSIM_EQU_TOKEN_PLUS              7
+#define OSSIM_EQU_TOKEN_IMAGE_VARIABLE    8
+#define OSSIM_EQU_TOKEN_CONSTANT          9
+#define OSSIM_EQU_TOKEN_EXP         10
+#define OSSIM_EQU_TOKEN_LOG10       11
+#define OSSIM_EQU_TOKEN_PI          12
+#define OSSIM_EQU_TOKEN_POWER       13
+#define OSSIM_EQU_TOKEN_SIN         14
+#define OSSIM_EQU_TOKEN_SIND        15
+#define OSSIM_EQU_TOKEN_COS         16
+#define OSSIM_EQU_TOKEN_COSD        17
+#define OSSIM_EQU_TOKEN_ABS         18
+#define OSSIM_EQU_TOKEN_MIN         19
+#define OSSIM_EQU_TOKEN_MAX         20
+#define OSSIM_EQU_TOKEN_SQRT        21
+#define OSSIM_EQU_TOKEN_COMMA       22
+#define OSSIM_EQU_TOKEN_BLURR       23
+#define OSSIM_EQU_TOKEN_SHIFT       24
+#define OSSIM_EQU_TOKEN_CONV        25
+#define OSSIM_EQU_TOKEN_BAND        26
+#define OSSIM_EQU_TOKEN_ASSIGN_BAND 27
+#define OSSIM_EQU_TOKEN_MOD         28
+#define OSSIM_EQU_TOKEN_ASIN        29
+#define OSSIM_EQU_TOKEN_ASIND       30
+#define OSSIM_EQU_TOKEN_ACOS        31
+#define OSSIM_EQU_TOKEN_ACOSD       32
+#define OSSIM_EQU_TOKEN_TAN         33
+#define OSSIM_EQU_TOKEN_TAND        34
+#define OSSIM_EQU_TOKEN_ATAN        35
+#define OSSIM_EQU_TOKEN_ATAND       36
+#define OSSIM_EQU_TOKEN_LEFT_ARRAY_BRACKET 37
+#define OSSIM_EQU_TOKEN_RIGHT_ARRAY_BRACKET 38
+#define OSSIM_EQU_TOKEN_AMPERSAND 39
+#define OSSIM_EQU_TOKEN_OR_BAR    40
+#define OSSIM_EQU_TOKEN_TILDE     41
+#define OSSIM_EQU_TOKEN_XOR       42
+#define OSSIM_EQU_TOKEN_CLAMP     43
+#define OSSIM_EQU_TOKEN_CLIP      44
+#define OSSIM_EQU_TOKEN_BEQUAL 45
+#define OSSIM_EQU_TOKEN_BGREATER 46
+#define OSSIM_EQU_TOKEN_BGREATEROREQUAL 47
+#define OSSIM_EQU_TOKEN_BLESS 48
+#define OSSIM_EQU_TOKEN_BLESSOREQUAL 49
+#define OSSIM_EQU_TOKEN_BDIFFERENT 50
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.cpp
new file mode 100644
index 0000000000..4683568e1a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.cpp
@@ -0,0 +1,1795 @@
+#define yyFlexLexer ossimEquTokenizerFlexLexer
+#define yywrap ossimEquTokenizerwrap
+
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /cvs/ossim/src/ossim_core/base/misc/ossimEquTokenizer.cpp,v 1.20 2005/07/12 15:41:56 gpotts Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <iostream>
+using namespace std;
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	istream* yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+#define yytext_ptr yytext
+#define YY_INTERACTIVE
+
+#include <base/misc/FlexLexer.h>
+
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yyleng = (int) (yy_cp - yy_bp); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 52
+#define YY_END_OF_BUFFER 53
+static yyconst short int yy_accept[119] =
+    {   0,
+        0,    0,   53,   52,    1,   11,    7,   14,   15,    5,
+        9,    3,   10,   52,    4,    2,   49,   52,   47,   52,
+       12,   13,   16,   52,   52,   52,   52,   52,   52,   52,
+       52,   52,   52,    6,    8,    1,    2,    2,    2,    0,
+       50,   51,   46,   48,   19,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,   18,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    2,   35,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,   27,   22,   20,   38,
+       37,    0,   23,    0,   31,   17,    0,    2,   29,   25,
+        0,   33,   42,    0,    0,   44,   39,   28,    0,    0,
+
+       24,   36,   32,   30,   26,    0,   34,   41,   45,   21,
+       40,    0,    0,    0,    0,    0,   43,    0
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    1,    1,    1,    3,    4,    1,    5,
+        6,    7,    8,    9,   10,   11,   12,   13,   14,   15,
+       15,   15,   15,   15,   15,   15,   15,    1,    1,   16,
+       17,   18,    1,    1,    1,    1,    1,    1,   19,    1,
+        1,    1,   20,    1,    1,    1,    1,    1,    1,   21,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+       22,    1,   23,   24,   25,    1,   26,   27,   28,   29,
+
+       30,   31,   32,   33,   34,    1,    1,   35,   36,   37,
+       38,   39,   40,   41,   42,   43,   44,   45,    1,   46,
+        1,    1,    1,   47,    1,   48,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst int yy_meta[49] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1
+    } ;
+
+static yyconst short int yy_base[119] =
+    {   0,
+        0,    0,  170,  171,  167,  171,  171,  171,  171,  171,
+      171,  171,  171,   36,  171,   41,   40,  151,  150,  146,
+      171,  171,  171,   34,   33,   28,  119,  127,  125,   38,
+       40,  136,  123,  171,  171,  158,   68,   71,   78,   92,
+      171,  171,  171,  171,  171,  117,  120,   33,  131,  119,
+      111,   44,   57,  115,  171,  121,  106,  114,  116,  112,
+      107,  110,  105,  101,  104,  107,  171,  103,  107,  109,
+      105,  112,   99,  103,   99,   92,  107,  171,  121,  171,
+      171,  103,  104,   89,  102,  171,  110,  113,  101,  100,
+       81,   83,  171,   69,   65,  171,  171,  171,   90,   53,
+
+      171,  171,  171,  171,  171,   58,  171,  171,  171,  171,
+      171,   63,   52,   43,   28,   24,  171,  171
+    } ;
+
+static yyconst short int yy_def[119] =
+    {   0,
+      118,    1,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,    0
+    } ;
+
+static yyconst short int yy_nxt[220] =
+    {   0,
+        4,    5,    6,    7,    8,    9,   10,   11,   12,   13,
+       14,   15,   16,   16,   16,   17,   18,   19,    4,    4,
+       20,   21,   22,   23,    4,   24,   25,   26,    4,   27,
+        4,    4,    4,   28,   29,   30,    4,    4,    4,    4,
+        4,   31,   32,    4,    4,   33,   34,   35,   37,   37,
+       37,   38,  117,   39,   39,   39,   41,   42,   50,   40,
+       46,   47,   52,   57,  116,   53,   69,   51,  115,   74,
+       40,   58,   59,   60,   70,   48,   49,   75,  114,   61,
+       37,   37,   37,   37,   37,   37,   64,  113,   38,   40,
+       39,   39,   39,   76,  112,  111,   40,   64,   77,   65,
+
+       40,   65,  110,  109,   66,   66,   66,   40,   87,  108,
+       87,  107,  106,   88,   88,   88,   66,   66,   66,   66,
+       66,   66,   88,   88,   88,   88,   88,   88,  105,  104,
+      103,  102,  101,  100,   99,   98,   97,   96,   95,   94,
+       93,   92,   91,   90,   89,   86,   85,   84,   83,   82,
+       81,   80,   79,   78,   73,   72,   71,   68,   67,   36,
+       63,   62,   56,   55,   54,   45,   44,   43,   36,  118,
+        3,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118
+    } ;
+
+static yyconst short int yy_chk[220] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,   14,   14,
+       14,   16,  116,   16,   16,   16,   17,   17,   25,   16,
+       24,   24,   26,   30,  115,   26,   48,   25,  114,   52,
+       16,   30,   31,   31,   48,   24,   24,   52,  113,   31,
+       37,   37,   37,   38,   38,   38,   37,  112,   39,   38,
+       39,   39,   39,   53,  106,  100,   39,   37,   53,   40,
+
+       38,   40,   99,   95,   40,   40,   40,   39,   64,   94,
+       64,   92,   91,   64,   64,   64,   65,   65,   65,   66,
+       66,   66,   87,   87,   87,   88,   88,   88,   90,   89,
+       85,   84,   83,   82,   79,   77,   76,   75,   74,   73,
+       72,   71,   70,   69,   68,   63,   62,   61,   60,   59,
+       58,   57,   56,   54,   51,   50,   49,   47,   46,   36,
+       33,   32,   29,   28,   27,   20,   19,   18,    5,    3,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+
+      118,  118,  118,  118,  118,  118,  118,  118,  118,  118,
+      118,  118,  118,  118,  118,  118,  118,  118,  118
+    } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "ossimEquTokenizer.l"
+#define INITIAL 0
+#line 2 "ossimEquTokenizer.l"
+#include "ossimEquTokenDefines.h"
+#line 413 "lex.ossimEquTokenizer.cc"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+#define ECHO LexerOutput( yytext, yyleng )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) LexerError( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yyFlexLexer::yylex()
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp = NULL, *yy_bp = NULL;
+	register int yy_act;
+
+#line 15 "ossimEquTokenizer.l"
+
+
+#line 543 "lex.ossimEquTokenizer.cc"
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = &cin;
+
+		if ( ! yyout )
+			yyout = &cout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				yy_last_accepting_state = yy_current_state;
+				yy_last_accepting_cpos = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 119 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 171 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+
+do_action:	/* This label is used only to access EOF actions. */
+
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = yy_hold_char;
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 17 "ossimEquTokenizer.l"
+/* skip blanks and tabs */
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 19 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_CONSTANT;
+           }
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 22 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_COMMA;
+           }
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 25 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_DIV;
+           }
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 29 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_MULT;
+           }
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 33 "ossimEquTokenizer.l"
+{ 
+               return OSSIM_EQU_TOKEN_OR_BAR;
+           }
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 37 "ossimEquTokenizer.l"
+{ 
+               return OSSIM_EQU_TOKEN_AMPERSAND;
+           }
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 40 "ossimEquTokenizer.l"
+{ 
+               return OSSIM_EQU_TOKEN_TILDE;
+           }
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 44 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_PLUS;
+           }
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 47 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_MINUS;
+           }
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 50 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_MOD;
+           }
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 53 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_LEFT_ARRAY_BRACKET;
+           }
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 56 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_RIGHT_ARRAY_BRACKET;
+           }
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 59 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_LEFT_PAREN;
+        }
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 62 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_RIGHT_PAREN;
+           }
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 65 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_POWER;
+           }
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 68 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_XOR;
+        }
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 72 "ossimEquTokenizer.l"
+{
+             return OSSIM_EQU_TOKEN_IMAGE_VARIABLE;
+        }
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 75 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_PI;
+           }
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 78 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_LOG;
+           }
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 81 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_LOG10;
+           }
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 84 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_EXP;
+           } 
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 87 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_SIN;
+           }
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 90 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_SIND;
+           }
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 93 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_ASIN;
+           }
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 96 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_ASIND;
+           }
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 99 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_COS;
+           }
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 102 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_COSD;
+           }
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 105 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_ACOS;
+           }
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 108 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_ACOSD;
+           }
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 111 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_TAN;
+           }
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 114 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_TAND;
+           }
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 117 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_ATAN;
+           }
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 120 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_ATAND;
+           }
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 123 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_ABS;
+           }
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 126 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_SQRT;
+           }
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 129 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_MIN;
+           }
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 132 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_MAX;
+           }
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 135 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_CONV;
+           }
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 138 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_SHIFT;
+           }
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 141 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_BLURR;
+           }
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 144 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_BAND;
+           }
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 147 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_ASSIGN_BAND;
+              }
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 150 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_CLIP;
+        }
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 153 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_CLAMP;
+        }
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 156 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_BEQUAL;
+}
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 159 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_BGREATER;
+}
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 162 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_BGREATEROREQUAL;
+}
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 165 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_BLESS;
+}
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 168 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_BLESSOREQUAL;
+}
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 171 "ossimEquTokenizer.l"
+{
+               return OSSIM_EQU_TOKEN_BDIFFERENT;
+}
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 175 "ossimEquTokenizer.l"
+ECHO;
+	YY_BREAK
+#line 986 "lex.ossimEquTokenizer.cc"
+case YY_STATE_EOF(INITIAL):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+yyFlexLexer::yyFlexLexer( istream* arg_yyin, ostream* arg_yyout )
+	{
+	yyin = arg_yyin;
+	yyout = arg_yyout;
+	yy_c_buf_p = 0;
+	yy_init = 1;
+	yy_start = 0;
+	yy_flex_debug = 0;
+	yylineno = 1;	// this will only get updated if %option yylineno
+
+	yy_did_buffer_switch_on_eof = 0;
+
+	yy_looking_for_trail_begin = 0;
+	yy_more_flag = 0;
+	yy_more_len = 0;
+	yy_more_offset = yy_prev_more_offset = 0;
+
+	yy_start_stack_ptr = yy_start_stack_depth = 0;
+	yy_start_stack = 0;
+
+	yy_current_buffer = 0;
+
+#ifdef YY_USES_REJECT
+	yy_state_buf = new yy_state_type[YY_BUF_SIZE + 2];
+#else
+	yy_state_buf = 0;
+#endif
+	}
+
+yyFlexLexer::~yyFlexLexer()
+	{
+	delete yy_state_buf;
+	yy_delete_buffer( yy_current_buffer );
+	}
+
+void yyFlexLexer::switch_streams( istream* new_in, ostream* new_out )
+	{
+	if ( new_in )
+		{
+		yy_delete_buffer( yy_current_buffer );
+		yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) );
+		}
+
+	if ( new_out )
+		yyout = new_out;
+	}
+
+#ifdef YY_INTERACTIVE
+int yyFlexLexer::LexerInput( char* buf, int /* max_size */ )
+#else
+int yyFlexLexer::LexerInput( char* buf, int max_size )
+#endif
+	{
+	if ( yyin->eof() || yyin->fail() )
+		return 0;
+
+#ifdef YY_INTERACTIVE
+	yyin->get( buf[0] );
+
+	if ( yyin->eof() )
+		return 0;
+
+	if ( yyin->bad() )
+		return -1;
+
+	return 1;
+
+#else
+	(void) yyin->read( buf, max_size );
+
+	if ( yyin->bad() )
+		return -1;
+	else
+		return yyin->gcount();
+#endif
+	}
+
+void yyFlexLexer::LexerOutput( const char* buf, int size )
+	{
+	(void) yyout->write( buf, size );
+	}
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+int yyFlexLexer::yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+yy_state_type yyFlexLexer::yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			yy_last_accepting_state = yy_current_state;
+			yy_last_accepting_cpos = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 119 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state )
+	{
+	register int yy_is_jam;
+	register char *yy_cp = yy_c_buf_p;
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		yy_last_accepting_state = yy_current_state;
+		yy_last_accepting_cpos = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 119 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 118);
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+void yyFlexLexer::yyunput( int c, register char* yy_bp )
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+
+
+int yyFlexLexer::yyinput()
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+
+	return c;
+	}
+
+void yyFlexLexer::yyrestart( istream* input_file )
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+void yyFlexLexer::yy_load_buffer_state()
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( istream* file, int size )
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b )
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, istream* file )
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+	b->yy_is_interactive = 0;
+	}
+
+
+void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b )
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+void yyFlexLexer::yy_push_state( int new_state )
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+void yyFlexLexer::yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+int yyFlexLexer::yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+
+void yyFlexLexer::LexerError( yyconst char msg[] )
+	{
+	cerr << msg << '\n';
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 175 "ossimEquTokenizer.l"
+
+int yywrap()
+{
+   return 1;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.h b/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.h
new file mode 100644
index 0000000000..c3e2f4ab36
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.h
@@ -0,0 +1,9 @@
+#ifndef ossimEquTokenizer_HEADER
+#define ossimEquTokenizer_HEADER
+#define yyFlexLexer ossimEquTokenizerFlexLexer
+
+#include "base/misc/ossimEquTokenDefines.h"
+#include "base/misc/FlexLexer.h"
+typedef ossimEquTokenizerFlexLexer ossimEquTokenizer;
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.l b/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.l
new file mode 100644
index 0000000000..c74c1b81a5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimEquTokenizer.l
@@ -0,0 +1,179 @@
+%{
+#include "ossimEquTokenDefines.h"
+%}
+
+string  \"[^\n"]+\"
+
+ws      [ \t]+
+
+alpha   [A-Za-z]
+dig     [0-9]
+num1    {dig}+\.?([eE][-+]?{dig}+)?
+num2    {dig}*\.{dig}+([eE][-+]?{dig}+)?
+number  {num1}|{num2}
+
+%%
+
+{ws}    /* skip blanks and tabs */
+
+{number}   {
+               return OSSIM_EQU_TOKEN_CONSTANT;
+           }
+","        {
+               return OSSIM_EQU_TOKEN_COMMA;
+           }
+"/"        {
+               return OSSIM_EQU_TOKEN_DIV;
+           }
+
+"*"        {
+               return OSSIM_EQU_TOKEN_MULT;
+           }
+
+"|"        { 
+               return OSSIM_EQU_TOKEN_OR_BAR;
+           }
+
+"&"        { 
+               return OSSIM_EQU_TOKEN_AMPERSAND;
+           }
+"~"        { 
+               return OSSIM_EQU_TOKEN_TILDE;
+           }
+
+"+"        {
+               return OSSIM_EQU_TOKEN_PLUS;
+           }
+"-"        {
+               return OSSIM_EQU_TOKEN_MINUS;
+           }
+"%"        {
+               return OSSIM_EQU_TOKEN_MOD;
+           }
+"["        {
+               return OSSIM_EQU_TOKEN_LEFT_ARRAY_BRACKET;
+           }
+"]"        {
+               return OSSIM_EQU_TOKEN_RIGHT_ARRAY_BRACKET;
+           }
+"("     {
+               return OSSIM_EQU_TOKEN_LEFT_PAREN;
+        }
+")"        {
+               return OSSIM_EQU_TOKEN_RIGHT_PAREN;
+           }
+"\^"        {
+               return OSSIM_EQU_TOKEN_POWER;
+           }
+"xor"   {
+               return OSSIM_EQU_TOKEN_XOR;
+        }
+
+"in"    {
+             return OSSIM_EQU_TOKEN_IMAGE_VARIABLE;
+        }
+"PI"       {
+               return OSSIM_EQU_TOKEN_PI;
+           }
+"log"      {
+               return OSSIM_EQU_TOKEN_LOG;
+           }
+"log10"      {
+               return OSSIM_EQU_TOKEN_LOG10;
+           }
+"exp"      {
+               return OSSIM_EQU_TOKEN_EXP;
+           } 
+"sin"      {
+               return OSSIM_EQU_TOKEN_SIN;
+           }
+"sind"     {
+               return OSSIM_EQU_TOKEN_SIND;
+           }
+"asin"      {
+               return OSSIM_EQU_TOKEN_ASIN;
+           }
+"asind"     {
+               return OSSIM_EQU_TOKEN_ASIND;
+           }
+"cos"      {
+               return OSSIM_EQU_TOKEN_COS;
+           }
+"cosd"     {
+               return OSSIM_EQU_TOKEN_COSD;
+           }
+"acos"      {
+               return OSSIM_EQU_TOKEN_ACOS;
+           }
+"acosd"     {
+               return OSSIM_EQU_TOKEN_ACOSD;
+           }
+"tan"     {
+               return OSSIM_EQU_TOKEN_TAN;
+           }
+"tand"     {
+               return OSSIM_EQU_TOKEN_TAND;
+           }
+"atan"     {
+               return OSSIM_EQU_TOKEN_ATAN;
+           }
+"atand"     {
+               return OSSIM_EQU_TOKEN_ATAND;
+           }
+"abs"      {
+               return OSSIM_EQU_TOKEN_ABS;
+           }
+"sqrt"      {
+               return OSSIM_EQU_TOKEN_SQRT;
+           }
+"min"      {
+               return OSSIM_EQU_TOKEN_MIN;
+           }
+"max"      {
+               return OSSIM_EQU_TOKEN_MAX;
+           }
+"conv"     {
+               return OSSIM_EQU_TOKEN_CONV;
+           }
+"shift"    {
+               return OSSIM_EQU_TOKEN_SHIFT;
+           }
+"blurr"    {
+               return OSSIM_EQU_TOKEN_BLURR;
+           }
+"band"     {
+               return OSSIM_EQU_TOKEN_BAND;
+           }
+"assign_band" {
+               return OSSIM_EQU_TOKEN_ASSIGN_BAND;
+              }
+"clip" {
+               return OSSIM_EQU_TOKEN_CLIP;
+        }
+"clamp" {
+               return OSSIM_EQU_TOKEN_CLAMP;
+        }
+"==" {
+               return OSSIM_EQU_TOKEN_BEQUAL;
+}
+"\>" {
+               return OSSIM_EQU_TOKEN_BGREATER;
+}
+"\>=" {
+               return OSSIM_EQU_TOKEN_BGREATEROREQUAL;
+}
+"\<" {
+               return OSSIM_EQU_TOKEN_BLESS;
+}
+"\<=" {
+               return OSSIM_EQU_TOKEN_BLESSOREQUAL;
+}
+"\<\>" {
+               return OSSIM_EQU_TOKEN_BDIFFERENT;
+}
+
+%%
+int yywrap()
+{
+   return 1;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimQuadTreeWarp.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimQuadTreeWarp.cpp
new file mode 100644
index 0000000000..6302a1a8f4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimQuadTreeWarp.cpp
@@ -0,0 +1,1426 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public License 
+// as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU Library General Public License
+// along with this library. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@remotesensing.org)
+//
+//*************************************************************************
+// $Id: ossimQuadTreeWarp.cpp,v 1.36 2004/04/05 13:31:35 gpotts Exp $
+
+#include <base/misc/ossimQuadTreeWarp.h>
+#include <algorithm>
+#include <stack>
+using namespace std;
+
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+static ossimTrace traceExec  ("ossimQuadTreeWarp:exec");
+static ossimTrace traceDebug ("ossimQuadTreeWarp:debug");
+
+RTTI_DEF1(ossimQuadTreeWarp, "ossimQuadTreeWarp", ossim2dTo2dTransform);
+
+
+void ossimQuadTreeWarpVertex::removeNode(ossimQuadTreeWarpNode* node)
+{
+   vector<ossimQuadTreeWarpNode*>::iterator iter = theSharedNodeList.begin();
+   bool found = false;
+   ossimQuadTreeWarpNode* removedNode = NULL;
+   while((iter != theSharedNodeList.end())&&!found)
+   {
+      if(*iter == node)
+      {
+         removedNode = *iter;
+         iter = theSharedNodeList.erase(iter);
+         found = true;
+      }
+      else
+      {
+         ++iter;
+      }
+   }
+
+   if(removedNode)
+   {
+      removedNode->removeVertex(this);
+   }
+}
+
+ossimQuadTreeWarpVertex::~ossimQuadTreeWarpVertex()
+{
+   for(ossim_uint32 i = 0;i< theSharedNodeList.size();++i)
+   {
+      theSharedNodeList[i]->removeVertex(this);
+   }
+                  
+}
+
+bool ossimQuadTreeWarpVertex::saveState(ossimKeywordlist& kwl,
+                                      const char* prefix)const
+{
+   kwl.add(prefix,
+           "x",
+           thePosition.x,
+           true);
+   kwl.add(prefix,
+           "y",
+           thePosition.y,
+           true);
+   kwl.add(prefix,
+           "dx",
+           theDelta.x,
+           true);
+   kwl.add(prefix,
+           "dy",
+           theDelta.y,
+           true);
+   kwl.add(prefix,
+           "lock_flag",
+           (int)theLockedFlag,
+           true);
+   
+   return true;
+}
+
+bool ossimQuadTreeWarpVertex::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   const char* x = kwl.find(prefix,
+                            "x");
+   const char* y = kwl.find(prefix,
+                            "y");
+   const char* dx = kwl.find(prefix,
+                             "dx");
+   const char* dy = kwl.find(prefix,
+                             "dy");
+   const char* lockedFlag = kwl.find(prefix,
+                                     "lock_flag");
+   if(x&&y&&dx&&dy&&lockedFlag)
+   {
+      thePosition.x = ossimString(x).toDouble();
+      thePosition.y = ossimString(y).toDouble();
+      theDelta.x    = ossimString(dx).toDouble();
+      theDelta.y    = ossimString(dy).toDouble();
+      theLockedFlag = ossimString(lockedFlag).toBool();
+      
+      return true;
+   }
+   
+   return false;
+}
+
+
+
+ossimQuadTreeWarpNode::~ossimQuadTreeWarpNode()
+{
+   removeVertices();
+
+   theUlVertex = NULL;
+   theUrVertex = NULL;
+   theLrVertex = NULL;
+   theLlVertex = NULL;
+   
+}
+
+void ossimQuadTreeWarpNode::removeChild(ossimQuadTreeWarpNode* node)
+{
+   vector<ossimQuadTreeWarpNode*>::iterator iter =  theChildren.begin();
+
+   while(iter != theChildren.end())
+   {
+      if(*iter == node)
+      {
+         theChildren.erase(iter);
+         return;
+      }
+      ++iter;
+   }
+}
+
+bool ossimQuadTreeWarpNode::saveState(ossimKeywordlist& kwl,
+                                      const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::UL_X_KW,
+           theBoundingRect.ul().x,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::UL_Y_KW,
+           theBoundingRect.ul().y,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::LR_X_KW,
+           theBoundingRect.lr().x,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::LR_Y_KW,
+           theBoundingRect.lr().y,
+           true);
+   
+   return true;
+}
+
+bool ossimQuadTreeWarpNode::loadState(const ossimKeywordlist& kwl,
+                                      const char* prefix)
+{
+   const char* ul_x = kwl.find(prefix, ossimKeywordNames::UL_X_KW);
+   const char* ul_y = kwl.find(prefix, ossimKeywordNames::UL_Y_KW);
+   const char* lr_x = kwl.find(prefix, ossimKeywordNames::LR_X_KW);
+   const char* lr_y = kwl.find(prefix, ossimKeywordNames::LR_Y_KW);
+
+   if(ul_x&&ul_y&&lr_x&&lr_y)
+   {
+      theBoundingRect = ossimDrect(ossimString(ul_x).toDouble(),
+                                   ossimString(ul_y).toDouble(),
+                                   ossimString(lr_x).toDouble(),
+                                   ossimString(lr_y).toDouble());
+      return true;
+   }
+   
+   return false;
+}
+
+
+ossimQuadTreeWarp::ossimQuadTreeWarp(const ossimQuadTreeWarp& rhs)
+   :ossim2dTo2dTransform(),
+    theWarpEnabledFlag(true),
+    theTree(NULL)
+{
+   ossimKeywordlist kwl;
+
+   rhs.saveState(kwl);
+
+   loadState(kwl);
+}
+
+
+void ossimQuadTreeWarp::create(const ossimDrect& boundingRect,
+                               const ossimDpt& ulShift,
+                               const ossimDpt& urShift,
+                               const ossimDpt& lrShift,
+                               const ossimDpt& llShift)
+{
+   clear();
+
+   theTree = new ossimQuadTreeWarpNode(boundingRect);
+
+   ossimQuadTreeWarpVertex* ul = new ossimQuadTreeWarpVertex(boundingRect.ul(),
+                                                             ulShift);
+   ossimQuadTreeWarpVertex* ur = new ossimQuadTreeWarpVertex(boundingRect.ur(),
+                                                             urShift);
+   ossimQuadTreeWarpVertex* lr = new ossimQuadTreeWarpVertex(boundingRect.lr(),
+                                                             lrShift);
+   ossimQuadTreeWarpVertex* ll = new ossimQuadTreeWarpVertex(boundingRect.ll(),
+                                                             llShift);
+   ul->addSharedNode(theTree);
+   ur->addSharedNode(theTree);
+   lr->addSharedNode(theTree);
+   ll->addSharedNode(theTree);
+
+   theVertexList.push_back(ul);
+   theVertexList.push_back(ur);
+   theVertexList.push_back(lr);
+   theVertexList.push_back(ll);
+   
+   theTree->theUlVertex = ul;
+   theTree->theUrVertex = ur;
+   theTree->theLrVertex = lr;
+   theTree->theLlVertex = ll;
+   
+}
+
+void ossimQuadTreeWarp::printVertices(std::ostream& out)const
+{
+   for(ossim_uint32 i = 0; i < theVertexList.size();++i)
+   {
+      out << *theVertexList[i] << "\n";
+   }
+}
+
+std::ostream& ossimQuadTreeWarp::print(std::ostream& out) const
+{
+   if(!isEmpty())
+   {
+      out << "___________VERTEX LIST____________________\n";
+      printVertices(out);
+      out << "___________TREE LIST____________________\n";
+      
+      recursivePrint(out, theTree);
+   }
+   else
+   {
+      out << "<empty tree>\n";
+   }
+   return out;
+}
+
+ossimQuadTreeWarpVertex* ossimQuadTreeWarp::findClosestVertex(ossimDpt& position)
+{
+   if(position.hasNans()) return (ossimQuadTreeWarpVertex*)NULL;
+      
+   double dist = 1.0/DBL_EPSILON;
+   ossimQuadTreeWarpVertex* result = (ossimQuadTreeWarpVertex*)NULL;
+   for(ossim_uint32 i = 0; i < theVertexList.size(); ++i)
+   {
+      double d = (position-theVertexList[i]->thePosition).length();
+      if( d < dist)
+      {
+         result = theVertexList[i];
+         dist = d;
+      }
+   }
+
+   return result;
+//    ossimQuadTreeWarpNode* node = findNode(position);
+
+//    if(node&&node->hasValidVertices())
+//    {
+//       double ulDist = (position-node->theUlVertex->thePosition).length();
+//       double urDist = (position-node->theUrVertex->thePosition).length();
+//       double lrDist = (position-node->theLrVertex->thePosition).length();
+//       double llDist = (position-node->theLlVertex->thePosition).length();
+
+//       double minDist = std::min(ulDist, std::min(urDist, std::min(lrDist, llDist)));
+
+//       if(minDist == ulDist)
+//       {
+//          return node->theUlVertex;
+//       }
+//       else if(minDist == urDist)
+//       {
+//          return node->theUrVertex;
+//       }
+//       else if(minDist == lrDist)
+//       {
+//          return node->theLrVertex;
+//       }
+//       else if(minDist == llDist)
+//       {
+//          return node->theLlVertex;
+//       }
+//    }
+
+//    return ((ossimQuadTreeWarpVertex*)NULL);
+}
+
+
+ossimQuadTreeWarpVertex* ossimQuadTreeWarp::findVertex(const ossimDpt& position)
+{
+   ossim_uint32 i = 0;
+   ossimQuadTreeWarpVertex* result = (ossimQuadTreeWarpVertex*)NULL;
+   ossimQuadTreeWarpNode*   currentNode = theTree;
+   
+   if((currentNode)&&
+      (currentNode->theBoundingRect.pointWithin(position)))
+   {
+      while((currentNode)&&
+            (!currentNode->isLeaf()))
+      {
+         for(i = 0; i < currentNode->theChildren.size(); ++i)
+         {
+            if(currentNode->theChildren[i]->theBoundingRect.pointWithin(position))
+            {
+               currentNode = currentNode->theChildren[i];
+               break;
+            }
+         }
+      }
+
+      if(currentNode&&currentNode->hasValidVertices())
+      {
+         if(currentNode->theUlVertex->thePosition == position)
+         {
+            result = currentNode->theUlVertex;
+         }
+         else if(currentNode->theUrVertex->thePosition == position)
+         {
+            result = currentNode->theUrVertex;            
+         }
+         else if(currentNode->theLrVertex->thePosition == position)
+         {
+            result = currentNode->theLrVertex;
+         }
+         else if(currentNode->theLlVertex->thePosition == position)
+         {
+            result = currentNode->theLlVertex;
+         }
+      }
+               
+   }
+
+   return result;   
+}
+
+ossimQuadTreeWarpVertex* ossimQuadTreeWarp::getVertex(const ossimDpt& position)
+{
+   std::vector<ossimQuadTreeWarpVertex*>::iterator iter = theVertexList.begin();
+
+   while(iter != theVertexList.end())
+   {
+      if(position == (*iter)->getPosition())
+      {
+         return (*iter);
+      }
+      ++iter;
+   }
+   
+   return (ossimQuadTreeWarpVertex*)NULL;
+}
+
+void ossimQuadTreeWarp::clear()
+{
+   if(theTree)
+   {     
+      recursiveDelete(theTree);
+      theTree = NULL;
+   }
+
+   for(ossim_uint32 i = 0; i < theVertexList.size(); ++i)
+   {
+      delete theVertexList[i];
+   }
+   
+   theVertexList.clear();
+}
+
+void ossimQuadTreeWarp::forward(const ossimDpt& pt,
+                                ossimDpt& result)const
+{
+   if(theWarpEnabledFlag)
+   {
+      ossimDpt shift;
+      
+      getShift(shift,
+               pt);
+      
+      result = pt + shift;
+   }
+   else
+   {
+      result = pt;
+   }
+}
+
+void ossimQuadTreeWarp::forward(ossimDpt& pt)const
+{
+   if(theWarpEnabledFlag)
+   {
+      ossimDpt shift;
+      
+      getShift(shift,
+               pt);
+      
+      pt += shift;
+   }
+}
+
+void ossimQuadTreeWarp::getShift(ossimDpt& result,
+                                 const ossimDpt& pt)const
+{
+   getShift(result,
+            findNode(pt),
+            pt);
+}
+
+void ossimQuadTreeWarp::split(const ossimDpt& point,
+                              double splitHoriCoefficient,
+                              double splitVertCoefficient)
+{
+   ossimQuadTreeWarpNode* node = findNode(point);
+
+   if(node)
+   {
+      if(splitHoriCoefficient == 0.0)
+      {
+         splitHoriCoefficient = (point.x - node->theBoundingRect.ul().x)/
+                                node->theBoundingRect.width();
+      }
+      if(splitVertCoefficient == 0.0)
+      {
+         splitVertCoefficient = (point.y - node->theBoundingRect.ul().y)/
+                                node->theBoundingRect.height();
+      }
+      split(node,
+            splitHoriCoefficient,
+            splitVertCoefficient);
+   }
+}
+
+
+void ossimQuadTreeWarp::split(ossimQuadTreeWarpNode* node,
+                              double splitHoriCoefficient,
+                              double splitVertCoefficient)
+{
+   if(!node) return;
+
+   splitHoriCoefficient = splitHoriCoefficient>1?1:splitHoriCoefficient;
+   splitHoriCoefficient = splitHoriCoefficient<0?0:splitHoriCoefficient;
+   splitVertCoefficient = splitVertCoefficient>1?1:splitVertCoefficient;
+   splitVertCoefficient = splitVertCoefficient<0?0:splitVertCoefficient;
+
+   if( ((splitHoriCoefficient == 0)&&(splitVertCoefficient == 0)) ||
+       ((splitHoriCoefficient == 1)&&(splitVertCoefficient == 1)))
+   {
+      return;
+   }
+
+   if(node->isLeaf())
+   {
+      if(node->theBoundingRect.hasNans())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)  << "WARNING: " << "ossimQuadTreeWarp::split, Node has nans for the rect and can't split\n";
+      }
+      else
+      {
+         ossimDpt ul = node->theBoundingRect.ul();
+         ossimDpt ur = node->theBoundingRect.ur();
+         ossimDpt lr = node->theBoundingRect.lr();
+         ossimDpt ll = node->theBoundingRect.lr();
+         
+         
+         double xmid = ul.x + (ur.x - ul.x)*splitHoriCoefficient;
+         double ymid = ul.y + (ll.y - ul.y)*splitVertCoefficient;
+         
+         ossimDpt left(ul.x, ymid);
+         
+         ossimDpt right(ur.x,
+                        ymid);
+         
+         ossimDpt top(xmid,
+                      ul.y);
+         
+         ossimDpt bottom(xmid,
+                         lr.y);
+
+
+         ossimDrect ulRect(ul.x,
+                           ul.y,
+                           xmid,
+                           ymid);
+         
+         ossimDrect urRect(top.x,
+                           top.y,
+                           right.x,
+                           right.y);
+         
+         ossimDrect lrRect(xmid,
+                           ymid,
+                           lr.x,
+                           lr.y);
+         
+         ossimDrect llRect(left.x,
+                           left.y,
+                           bottom.x,
+                           bottom.y);
+         
+         ossimQuadTreeWarpNode* ulNode=(ossimQuadTreeWarpNode*)NULL;
+         ossimQuadTreeWarpNode* urNode=(ossimQuadTreeWarpNode*)NULL;
+         ossimQuadTreeWarpNode* lrNode=(ossimQuadTreeWarpNode*)NULL;
+         ossimQuadTreeWarpNode* llNode=(ossimQuadTreeWarpNode*)NULL;
+
+         getNewQuads(node,
+                     ulRect,
+                     urRect,
+                     lrRect,
+                     llRect,
+                     ulNode,
+                     urNode,
+                     lrNode,
+                     llNode);
+
+         if(ulNode&&urNode&&lrNode&&llNode)
+         {
+            node->theChildren.push_back(ulNode);
+            node->theChildren.push_back(urNode);
+            node->theChildren.push_back(lrNode);
+            node->theChildren.push_back(llNode);            
+            
+            // it's no longer a leaf so remove the vertices
+            // from the list
+            node->removeVertex(node->theUlVertex);
+            node->removeVertex(node->theUrVertex);
+            node->removeVertex(node->theLrVertex);
+            node->removeVertex(node->theLlVertex);
+         }         
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING: " << "ossimQuadTreeWarp::split, can only split leaf nodes\n";
+   }
+   
+   updateAllVericeLockFlags();
+}
+
+void ossimQuadTreeWarp::getNewQuads(ossimQuadTreeWarpNode* parent,
+                                    const ossimDrect& ul,
+                                    const ossimDrect& ur,
+                                    const ossimDrect& lr,
+                                    const ossimDrect& ll,
+                                    ossimQuadTreeWarpNode*& ulNode,
+                                    ossimQuadTreeWarpNode*& urNode,
+                                    ossimQuadTreeWarpNode*& lrNode,
+                                    ossimQuadTreeWarpNode*& llNode)
+{
+   ossimDpt midShift;
+   getShift(midShift,
+            parent,
+            ul.lr());
+   
+   ossimQuadTreeWarpVertex* midV = new ossimQuadTreeWarpVertex(ul.lr(),
+                                                               midShift);
+
+   ulNode = new ossimQuadTreeWarpNode(ul,
+                                      parent);
+   urNode = new ossimQuadTreeWarpNode(ur,
+                                      parent);
+   lrNode = new ossimQuadTreeWarpNode(lr,
+                                      parent);
+   llNode = new ossimQuadTreeWarpNode(ll,
+                                      parent);
+
+   midV->addSharedNode(ulNode);
+   midV->addSharedNode(urNode);
+   midV->addSharedNode(lrNode);
+   midV->addSharedNode(llNode);
+   
+   // get the shared vertices first.  We will add ourself
+   // to the pointer list. when we construct
+   // the quad nodes.  Note the mid point will be shared
+   // by all quads and will be marked as adjustable
+   //
+   ossimQuadTreeWarpVertex* ulSharedV = getVertex(ul.ul());
+   ossimQuadTreeWarpVertex* urSharedV = getVertex(ur.ur());
+   ossimQuadTreeWarpVertex* lrSharedV = getVertex(lr.lr());
+   ossimQuadTreeWarpVertex* llSharedV = getVertex(ll.ll());
+   
+   if(!ulSharedV||
+      !urSharedV||
+      !lrSharedV||
+      !llSharedV)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: " << "ossimQuadTreeWarp::split, can't locating shared vertices.  This Shouldn't happen!!!\n";
+      return;
+   }
+
+   // we know that the midpoint is new and is shared by all quads
+   // so we have 2 more to check
+   ossimQuadTreeWarpVertex* topSharedV    = getVertex(ul.ur());
+   ossimQuadTreeWarpVertex* bottomSharedV = getVertex(lr.ll());
+
+   ossimQuadTreeWarpVertex* leftSharedV   = getVertex(ul.ll());
+   ossimQuadTreeWarpVertex* rightSharedV  = getVertex(ur.lr());
+   
+   ossimDpt tempShift;
+   
+   if(!topSharedV)
+   {
+      getShift(tempShift, parent, ul.ur());
+      topSharedV = new ossimQuadTreeWarpVertex(ul.ur(),
+                                               tempShift);
+      theVertexList.push_back(topSharedV);
+   }
+   if(!bottomSharedV)
+   {
+      getShift(tempShift, parent, ll.lr());
+      bottomSharedV = new ossimQuadTreeWarpVertex(ll.lr(),
+                                                  tempShift);
+      
+      theVertexList.push_back(bottomSharedV);
+   }
+   if(!leftSharedV)
+   {
+      getShift(tempShift, parent, ul.ll());
+      leftSharedV = new ossimQuadTreeWarpVertex(ul.ll(),
+                                               tempShift);
+      theVertexList.push_back(leftSharedV);
+   }
+   if(!rightSharedV)
+   {
+      getShift(tempShift, parent, ur.lr());
+      rightSharedV = new ossimQuadTreeWarpVertex(ur.lr(),
+                                               tempShift);
+      theVertexList.push_back(rightSharedV);
+   }
+   theVertexList.push_back(midV);
+
+   topSharedV->addSharedNode(ulNode);
+   topSharedV->addSharedNode(urNode);
+   
+   bottomSharedV->addSharedNode(llNode);
+   bottomSharedV->addSharedNode(lrNode);
+   leftSharedV->addSharedNode(ulNode);
+   leftSharedV->addSharedNode(llNode);
+   rightSharedV->addSharedNode(urNode);
+   rightSharedV->addSharedNode(lrNode);
+
+   ulSharedV->addSharedNode(ulNode); 
+   urSharedV->addSharedNode(urNode);
+   lrSharedV->addSharedNode(lrNode);
+   llSharedV->addSharedNode(llNode);
+  
+   ulNode->theUlVertex = ulSharedV;
+   ulNode->theUrVertex = topSharedV;
+   ulNode->theLrVertex = midV;
+   ulNode->theLlVertex = leftSharedV;
+
+   urNode->theUlVertex = topSharedV;
+   urNode->theUrVertex = urSharedV;
+   urNode->theLrVertex = rightSharedV;
+   urNode->theLlVertex = midV;
+
+   lrNode->theUlVertex = midV;
+   lrNode->theUrVertex = rightSharedV;
+   lrNode->theLrVertex = lrSharedV;
+   lrNode->theLlVertex = bottomSharedV;
+
+   llNode->theUlVertex = leftSharedV;
+   llNode->theUrVertex = midV;
+   llNode->theLrVertex = bottomSharedV;
+   llNode->theLlVertex = llSharedV;   
+}
+
+void ossimQuadTreeWarp::getShift(ossimDpt& result,
+                                 const ossimQuadTreeWarpNode* node,
+                                 const ossimDpt& pt)const
+{
+   result.x = 0.0;
+   result.y = 0.0;
+
+   if(!node)
+   {
+      return;
+   }
+   if(!node->isLeaf())
+   {
+      return;
+   }
+
+   if(node->hasValidVertices())
+   {
+      ossimDpt ulShift = node->theUlVertex->getDelta();
+      ossimDpt urShift = node->theUrVertex->getDelta();
+      ossimDpt lrShift = node->theLrVertex->getDelta();
+      ossimDpt llShift = node->theLlVertex->getDelta();
+
+      ossimDpt ul = node->theBoundingRect.ul();
+      ossimDpt ur = node->theBoundingRect.ur();
+      ossimDpt ll = node->theBoundingRect.ll();
+      
+      double horizontalPercent = fabs((pt.x-ul.x))/
+                                 (ur.x-ul.x);
+      
+      double verticalPercent   = fabs((pt.y - ul.y))/
+                                 (ll.y-ul.y);
+
+      ossimDpt upper = ulShift + (urShift - ulShift)*horizontalPercent;
+      ossimDpt lower = llShift + (lrShift - llShift)*horizontalPercent;
+      
+      result = upper + (lower - upper)*verticalPercent;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING: ossimQuadTreeWarp::getShift, " << "Node does not have valid vertices in ossimQuadTreeWarp::getShift\n";
+   }
+}
+
+void ossimQuadTreeWarp::pruneTree(ossimQuadTreeWarpNode* node)
+{
+   if(node&&
+      !node->isLeaf())
+   {
+      ossimQuadTreeWarpVertex* ulV = getVertex(node->theBoundingRect.ul());
+      ossimQuadTreeWarpVertex* urV = getVertex(node->theBoundingRect.ur());
+      ossimQuadTreeWarpVertex* lrV = getVertex(node->theBoundingRect.lr());
+      ossimQuadTreeWarpVertex* llV = getVertex(node->theBoundingRect.ll());
+      
+      recursivePruneTree(node);
+
+      if(ulV&&urV&&lrV&&llV)
+      {
+         node->theUlVertex = ulV;
+         node->theUrVertex = urV;
+         node->theLrVertex = lrV;
+         node->theLlVertex = llV;
+
+         ulV->addSharedNode(node);
+         urV->addSharedNode(node);
+         lrV->addSharedNode(node);
+         llV->addSharedNode(node);
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING: ossimQuadTreeWarp::pruneTree, invlaid vertex find\n";
+      }
+      pruneSharedVertices();
+      updateAllVericeLockFlags();
+   }
+}
+
+void ossimQuadTreeWarp::recursivePruneTree(ossimQuadTreeWarpNode* node)
+{
+   if(!node||node->isLeaf()) return;
+   
+   for(ossim_uint32 i = 0; i < node->theChildren.size(); ++i)
+   {
+      recursivePruneTree(node->theChildren[i]);
+      delete node->theChildren[i];
+      node->theChildren[i] = NULL;
+   }
+   node->theChildren.clear();
+}
+
+
+ossimQuadTreeWarpNode* ossimQuadTreeWarp::findNode(const ossimDpt& pt)
+{
+   if((!pt.hasNans())&&(!isEmpty()))
+   {
+      if(theTree->theBoundingRect.pointWithin(pt))
+      {
+         return findNode(theTree,
+                         pt);
+      }
+   }
+   
+   return (ossimQuadTreeWarpNode*)NULL;
+}
+
+const ossimQuadTreeWarpNode* ossimQuadTreeWarp::findNode(const ossimDpt& pt)const
+{
+   if((!pt.hasNans())&&(!isEmpty()))
+   {
+      if(theTree->theBoundingRect.pointWithin(pt))
+      {
+         return findNode(theTree,
+                         pt);
+      }
+   }
+   
+   return (const ossimQuadTreeWarpNode*)NULL;
+}
+
+ossimQuadTreeWarpNode* ossimQuadTreeWarp::findNode(ossimQuadTreeWarpNode* node,
+                                                   const ossimDpt& pt)
+{
+   ossimQuadTreeWarpNode* result = (ossimQuadTreeWarpNode*)NULL;
+   
+   if(!node)
+   {
+      return result;
+   }
+   if(node->isLeaf())
+   {
+      result = node;
+   }
+   else
+   {
+      bool found = false;
+      for(ossim_uint32 i = 0; (i < node->theChildren.size())&&(!found); ++i)
+      {
+         if(node->theChildren[i]->theBoundingRect.pointWithin(pt))
+         {
+            result = findNode(node->theChildren[i],
+                              pt);
+            found = true;
+         }
+      }
+   }
+
+   return result;
+}
+
+void ossimQuadTreeWarp::findAllNodes(std::vector<ossimQuadTreeWarpNode*>& result,
+                                     const ossimDpt& pt)
+{
+   if((!pt.hasNans())&&(!isEmpty()))
+   {
+      if(theTree->theBoundingRect.pointWithin(pt))
+      {
+         findAllNodes(result,
+                      theTree,
+                      pt);
+      }
+   }
+   
+}
+
+void ossimQuadTreeWarp::findAllNodes(std::vector<const ossimQuadTreeWarpNode*>& result,
+                                     const ossimDpt& pt)const
+{
+   if(!pt.hasNans()&&(!isEmpty()))
+   {
+      if(theTree->theBoundingRect.pointWithin(pt))
+      {
+         findAllNodes(result,
+                      theTree,
+                      pt);
+      }
+   }
+   
+}
+
+const ossimQuadTreeWarpNode* ossimQuadTreeWarp::findNode(const ossimQuadTreeWarpNode* node,
+                                                         const ossimDpt& pt)const
+{
+   const ossimQuadTreeWarpNode* result = (const ossimQuadTreeWarpNode*)NULL;
+   
+   if(!node)
+   {
+      return result;
+   }
+   if(node->isLeaf())
+   {
+      result = node;
+   }
+   else
+   {
+      bool found = false;
+      for(ossim_uint32 i = 0; (i < node->theChildren.size())&&(!found); ++i)
+      {
+         if(node->theChildren[i]->theBoundingRect.pointWithin(pt))
+         {
+            result = findNode(node->theChildren[i],
+                              pt);
+            found = true;
+         }
+      }
+   }
+
+   return result;
+}
+
+void ossimQuadTreeWarp::findAllNodes(std::vector<ossimQuadTreeWarpNode*>& result,
+                                     ossimQuadTreeWarpNode* node,
+                                     const ossimDpt& pt)
+{   
+   if(node->isLeaf())
+   {
+      result.push_back(node);
+   }
+   else
+   {
+      for(ossim_uint32 i = 0;
+          i < node->theChildren.size();
+          ++i)
+      {
+         if(node->theChildren[i]->theBoundingRect.pointWithin(pt))
+         {
+            findAllNodes(result,
+                         node->theChildren[i],
+                         pt);
+         }
+      }
+   }
+}
+
+void ossimQuadTreeWarp::findAllNodes(std::vector<const ossimQuadTreeWarpNode*>& result,
+                                     ossimQuadTreeWarpNode* node,
+                                     const ossimDpt& pt)const
+{   
+   if(!node) return;
+   if(node->isLeaf())
+   {
+      result.push_back(node);
+   }
+   else
+   {
+      for(ossim_uint32 i = 0;
+          i < node->theChildren.size();
+          ++i)
+      {
+         if(node->theChildren[i]->theBoundingRect.pointWithin(pt))
+         {
+            findAllNodes(result,
+                         node->theChildren[i],
+                         pt);
+         }
+      }
+   }
+}
+void ossimQuadTreeWarp::pruneSharedVertices()
+{
+   std::vector<ossimQuadTreeWarpVertex*>::iterator iter = theVertexList.begin();
+
+   while(iter != theVertexList.end())
+   {
+      if( !(*iter)->isShared())
+      {
+         delete (*iter);
+         iter = theVertexList.erase(iter);
+      }
+      else
+      {
+         ++iter;
+      }
+   }
+}
+
+void ossimQuadTreeWarp::removeSharedVertex(ossimQuadTreeWarpVertex* v)
+{
+   std::vector<ossimQuadTreeWarpVertex*>::iterator iter = std::find(theVertexList.begin(),
+                                                                    theVertexList.end(),
+                                                                    v);
+   if(iter != theVertexList.end())
+   {
+      delete (*iter);
+      iter = theVertexList.erase(iter);
+   }
+}
+
+
+void ossimQuadTreeWarp::recursivePrint(std::ostream& out,
+                                       ossimQuadTreeWarpNode* node)const
+{
+   if(node)
+   {
+      out << (*node) << "\n";
+   }
+
+   if(!node->isLeaf())
+   {
+      for(ossim_uint32 i =0; i < node->theChildren.size();++i)
+      {
+         recursivePrint(out, node->theChildren[i]);
+      }
+   }
+}
+
+void ossimQuadTreeWarp::recursiveDelete(ossimQuadTreeWarpNode* node)
+{
+   if(node->isLeaf())
+   {
+      delete node;
+   }
+   else
+   {
+      for(ossim_uint32 i = 0; i < node->theChildren.size(); ++ i)
+      {
+         recursiveDelete(node->theChildren[i]);
+      }
+      
+      delete node;
+   }
+}
+ 
+bool ossimQuadTreeWarp::isOnEdge(ossimQuadTreeWarpNode* node,
+                                 const ossimDpt& point)const
+{
+   if(!node) return false;
+
+   if(node->theBoundingRect.pointWithin(point))
+   {
+      double minx, maxx;
+      double miny, maxy;
+      node->theBoundingRect.getBounds(minx, miny, maxx, maxy);
+
+      return ( (point.x == minx) ||
+               (point.x == miny) ||
+               (point.y == miny) ||
+               (point.y == maxy) );
+   }
+
+   return false;
+}
+
+bool ossimQuadTreeWarp::isOnPoint(ossimQuadTreeWarpNode* node,
+                                 const ossimDpt& point)const
+{
+   if(!node) return false;
+
+   return ( (point == node->theBoundingRect.ul())||
+            (point == node->theBoundingRect.ur())||
+            (point == node->theBoundingRect.lr())||
+            (point == node->theBoundingRect.ll()) );
+}
+
+void ossimQuadTreeWarp::updateLockFlag(ossimQuadTreeWarpVertex* v)
+{
+   std::vector<ossimQuadTreeWarpNode*> nodeList;
+   
+   findAllNodes(nodeList,
+                v->getPosition());
+
+   if(nodeList.size() != v->theSharedNodeList.size())
+   {
+      if(isOnEdge(theTree, v->getPosition()))
+      {
+         v->theLockedFlag = false;
+      }
+      else
+      {
+         v->theLockedFlag = true;
+      }
+   }
+   else
+   {
+      v->theLockedFlag = false;
+   }
+
+   // if the original was not locked
+   // then we need to make sure we change the delta
+   // along the locked edge so to produce no artifacts
+   //
+   if(v->theLockedFlag)
+   {
+      updateDelta(v);
+   }
+}
+
+void ossimQuadTreeWarp::updateDelta(ossimQuadTreeWarpVertex* v)
+{
+   ossimQuadTreeWarpVertex* top    = NULL;
+   ossimQuadTreeWarpVertex* bottom = NULL;
+   ossimQuadTreeWarpVertex* left   = NULL;
+   ossimQuadTreeWarpVertex* right  = NULL;
+
+   std::vector<ossimQuadTreeWarpVertex*>::iterator iter = theVertexList.begin();
+   
+   while(iter != theVertexList.end())
+   {
+      ossimQuadTreeWarpVertex* testV = (*iter);
+
+      // test along the vertical
+      if( (testV->thePosition.x == v->thePosition.x)&&
+          (testV->thePosition.y != v->thePosition.y)&&
+          (!testV->theLockedFlag))
+      {
+         if(testV->thePosition.y >  v->thePosition.y)
+         {
+            if(bottom)
+            {
+               if(bottom->thePosition.y > testV->thePosition.y)
+               {
+                  bottom = testV;
+               }
+            }
+            else
+            {
+               bottom = testV;
+            }
+         }
+         else
+         {
+            if(top)
+            {
+               if(top->thePosition.y < testV->thePosition.y)
+               {
+                  top = testV;
+               }
+            }
+            else
+            {
+               top = testV;
+            }            
+         }
+      }
+
+      if( (testV->thePosition.y == v->thePosition.y)&&
+          (testV->thePosition.x != v->thePosition.x)&&
+          (!testV->theLockedFlag))
+      {
+         if(testV->thePosition.x >  v->thePosition.x)
+         {
+            if(right)
+            {
+               if(right->thePosition.x > testV->thePosition.x)
+               {
+                  right = testV;
+               }
+            }
+            else
+            {
+               right = testV;
+            }
+         }
+         else
+         {
+            if(left)
+            {
+               if(left->thePosition.x < testV->thePosition.x)
+               {
+                  left = testV;
+               }
+            }
+            else
+            {
+               left = testV;
+            }            
+         }
+      }
+      
+      ++iter;
+   }
+   ossimDpt topBottomDelta;
+   ossimDpt leftRightDelta;
+
+   topBottomDelta.makeNan();
+   leftRightDelta.makeNan();
+   
+   if(top&&bottom)
+   {
+      double t = (v->thePosition.y - top->thePosition.y)/
+                 (bottom->thePosition.y - top->thePosition.y);
+      
+      topBottomDelta = top->theDelta + (bottom->theDelta-top->theDelta)*t;
+      v->theDelta = topBottomDelta;
+      
+   }
+   if(left&&right)
+   {
+      double t = (v->thePosition.x - left->thePosition.x)/
+                 (right->thePosition.x - left->thePosition.x);
+      
+      leftRightDelta = left->theDelta + (right->theDelta-left->theDelta)*t;
+      v->theDelta = leftRightDelta;
+   }
+
+   if(top&&bottom&&left&&right)
+   {
+      v->theDelta = (topBottomDelta+leftRightDelta)*.5;
+   }
+}
+   
+void ossimQuadTreeWarp::updateAllVericeLockFlags()
+{
+   std::vector<ossimQuadTreeWarpVertex*>::iterator iter = theVertexList.begin();
+
+   while(iter != theVertexList.end())
+   {
+      if(*iter)
+      {
+         updateLockFlag(*iter);
+      }
+      
+      ++iter;
+   }
+}
+
+void ossimQuadTreeWarp::setToIdentity()
+{
+   for(ossim_uint32 i = 0; i < theVertexList.size(); ++i)
+   {
+      theVertexList[i]->theDelta = ossimDpt(0,0);
+   }
+}
+
+bool ossimQuadTreeWarp::saveState(ossimKeywordlist& kwl,
+                                  const char* prefix)const
+{
+   for(ossim_uint32 i = 0; i < theVertexList.size(); ++i)
+   {
+      ossimString newPrefix = ossimString(prefix)+ "v" + ossimString::toString(i) +".";
+
+      theVertexList[i]->saveState(kwl, newPrefix.c_str());
+   }
+
+   recursiveSave(theTree, kwl, prefix);
+   
+   return ossim2dTo2dTransform::saveState(kwl, prefix);   
+}
+
+bool ossimQuadTreeWarp::loadState(const ossimKeywordlist& kwl,
+                                  const char* prefix)
+{
+   clear();
+   ossimString newPrefix = ossimString(prefix);
+
+   // load the vertices first
+   //
+   ossimString regExpression =  ossimString("^(") + newPrefix + "v[0-9]+\\.)";
+
+   ossim_uint32 result = kwl.getNumberOfSubstringKeys(regExpression);
+   
+   ossim_uint32 numberOfMatches = 0;
+   ossim_uint32 count = 0;
+   while(numberOfMatches < result)
+   {
+      ossimString newPrefix = ossimString(prefix)+ossimString("v") + ossimString::toString(count) +".";
+      
+      ossimQuadTreeWarpVertex* vert = new ossimQuadTreeWarpVertex;
+      
+      if(!vert->loadState(kwl, newPrefix.c_str()))
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: "<< " ossimQuadTreeWarp::loadState, invalid load on vertex\n";
+         delete vert;
+         clear();
+         
+         return false;
+      }
+      else
+      {
+         ++numberOfMatches;
+         theVertexList.push_back(vert);
+      }
+      
+      ++count;
+   }
+
+   theTree = new ossimQuadTreeWarpNode;
+
+   if(!theTree->loadState(kwl, prefix))
+   {
+      clear();
+      return false;
+   }
+   if(!recursiveLoad(theTree, kwl, prefix))
+   {
+      clear();
+      return false;
+   }
+   
+   if(!ossim2dTo2dTransform::loadState(kwl, prefix))
+   {
+      clear();
+      return false;
+   }
+
+   return true;
+}
+
+bool ossimQuadTreeWarp::recursiveSave(ossimQuadTreeWarpNode* node,
+                                      ossimKeywordlist& kwl,
+                                      const char* prefix)const
+{
+   if(!node) return false;
+   
+   if(!node->saveState(kwl,
+                      prefix))
+   {
+      return false;
+   }
+   
+   if(node->isLeaf())
+   {
+      return true;
+   }
+   else
+   {
+     for(ossim_uint32 i = 0; i < node->theChildren.size(); ++ i)
+       {
+	 ossimString newPrefix = ossimString(prefix) + ossimString::toString(i) + ".";
+      
+	 if(!recursiveSave(node->theChildren[i],
+                           kwl,
+                           newPrefix.c_str()))
+         {
+            return false;
+         }
+       }
+   }
+
+   return true;
+}
+
+bool ossimQuadTreeWarp::recursiveLoad(ossimQuadTreeWarpNode* node,
+                                      const ossimKeywordlist& kwl,
+                                      const char* prefix)
+{
+   if(!node) return false;
+   ossimString copyPrefix = prefix;
+   
+   ossimQuadTreeWarpNode* ul = new ossimQuadTreeWarpNode;
+   ossimQuadTreeWarpNode* ur = new ossimQuadTreeWarpNode;
+   ossimQuadTreeWarpNode* lr = new ossimQuadTreeWarpNode;
+   ossimQuadTreeWarpNode* ll = new ossimQuadTreeWarpNode;
+   
+   ossimString ulPre = copyPrefix + "0.";
+   ossimString urPre = copyPrefix + "1.";
+   ossimString lrPre = copyPrefix + "2.";
+   ossimString llPre = copyPrefix + "3.";
+
+   if(ul->loadState(kwl,
+                    ulPre.c_str()))
+   {
+      ul->theParent = node;
+      node->theChildren.push_back(ul);
+      recursiveLoad(ul,
+                    kwl,
+                    ulPre.c_str());
+   }
+   else
+   {
+      delete ul;
+      ul = NULL;
+   }
+   
+   if(ur->loadState(kwl,
+                    urPre.c_str()))
+   {
+      ur->theParent = node;
+      node->theChildren.push_back(ur);
+      recursiveLoad(ur,
+                    kwl,
+                    urPre.c_str());
+   }
+   else
+   {
+      delete ur;
+      ur = NULL;
+   }
+
+   if(lr->loadState(kwl,
+                    lrPre.c_str()))
+   {
+      lr->theParent = node;
+      node->theChildren.push_back(lr);
+      recursiveLoad(lr,
+                    kwl,
+                    lrPre.c_str());
+   }
+   else
+   {
+      delete lr;
+      lr = NULL;
+   }
+
+   if(ll->loadState(kwl,
+                    llPre.c_str()))
+   {
+      ll->theParent = node;
+      node->theChildren.push_back(ll);
+      recursiveLoad(ll,
+                    kwl,
+                    llPre.c_str());
+   }
+   else
+   {
+      delete ll;
+      ll = NULL;
+   }
+
+   if(node->isLeaf())
+   {
+      node->theUlVertex = getVertex(node->theBoundingRect.ul());
+      node->theUrVertex = getVertex(node->theBoundingRect.ur());
+      node->theLrVertex = getVertex(node->theBoundingRect.lr());
+      node->theLlVertex = getVertex(node->theBoundingRect.ll());
+
+      if(node->hasValidVertices())
+      {
+         node->theUlVertex->addSharedNode(node);
+         node->theUrVertex->addSharedNode(node);
+         node->theLrVertex->addSharedNode(node);
+         node->theLlVertex->addSharedNode(node);
+      }
+      else
+      {
+         return false;
+      }
+   }
+   
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimQuadTreeWarp.h b/Utilities/OSSIM/ossim_core/base/misc/ossimQuadTreeWarp.h
new file mode 100644
index 0000000000..5ee14ae3fc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimQuadTreeWarp.h
@@ -0,0 +1,461 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public License 
+// as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU Library General Public License
+// along with this library. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimQuadTreeWarp.h,v 1.23 2003/12/22 18:48:32 dburken Exp $
+#ifndef ossimQuadTreeWarp_HEADER
+#define ossimQuadTreeWarp_HEADER
+#include "base/data_types/ossimDpt.h"
+#include "base/data_types/ossimDrect.h"
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/misc/ossim2dTo2dTransform.h"
+#include <vector>
+#include <iostream>
+
+class OSSIMDLLEXPORT ossimQuadTreeWarpNode;
+
+class OSSIMDLLEXPORT ossimQuadTreeWarpVertex
+{
+public:
+   friend ostream& operator<<(ostream& out,
+                              const ossimQuadTreeWarpVertex& rhs)
+      {
+         out << "Position:     " << rhs.thePosition   << endl
+             << "Delta:        " << rhs.theDelta      << endl
+             << "Locked flag:  " << rhs.theLockedFlag << endl
+             << "Shared nodes: " << rhs.theSharedNodeList.size();
+
+         return out;
+      }
+   
+   ossimQuadTreeWarpVertex(const ossimDpt& position=ossimDpt(0,0),
+                       const ossimDpt& delta=ossimDpt(0,0))
+      :thePosition(position),
+       theDelta(delta),
+       theLockedFlag(false)
+      {
+      }
+   ~ossimQuadTreeWarpVertex();
+   
+   void setPosition(const ossimDpt& position)
+      {
+         thePosition = position;
+      }
+   void setDelta(const ossimDpt& delta)
+      {
+         theDelta    = delta;
+      }
+   const ossimDpt& getDelta()const
+      {
+         return theDelta;
+      }
+   const ossimDpt& getPosition()const
+      {
+         return thePosition;
+      }
+   void addSharedNode(ossimQuadTreeWarpNode* node)
+      {
+         if(node)
+         {
+            theSharedNodeList.push_back(node);
+         }
+      }
+   void removeNode(ossimQuadTreeWarpNode* node);
+   bool isShared()const
+      {
+         return (theSharedNodeList.size() > 0);
+      }
+
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix)const;
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix);
+   
+   vector<ossimQuadTreeWarpNode*> theSharedNodeList;
+   
+   ossimDpt                       thePosition;
+   ossimDpt                       theDelta;
+   bool                           theLockedFlag;
+   
+};
+
+class ossimQuadTreeWarpNode
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out,
+                                   const ossimQuadTreeWarpNode& rhs)
+      {
+         out << "Bounding rect: " << rhs.theBoundingRect << endl;
+
+         if(rhs.theUlVertex)
+         {
+            out << "ulVertex:\n" << *rhs.theUlVertex<< endl;
+         }
+         if(rhs.theUrVertex)
+         {
+            out << "urVertex:\n" << *rhs.theUrVertex<< endl;
+         }
+         if(rhs.theLrVertex)
+         {
+            out << "lrVertex:\n" << *rhs.theLrVertex<< endl;
+         }
+         if(rhs.theLlVertex)
+         {
+            out << "llVertex:\n" << *rhs.theLlVertex;
+         }
+
+         return out;
+      }
+   ~ossimQuadTreeWarpNode();
+   ossimQuadTreeWarpNode()
+      :
+        theUlVertex(NULL),
+        theUrVertex(NULL),
+        theLrVertex(NULL),
+        theLlVertex(NULL),
+        theParent(NULL)
+      {
+         theBoundingRect.makeNan();
+      }
+   
+   ossimQuadTreeWarpNode(const ossimDrect& bounds,
+                         ossimQuadTreeWarpNode* parent=NULL,
+                         ossimQuadTreeWarpVertex* ulVertex=(ossimQuadTreeWarpVertex*)NULL,
+                         ossimQuadTreeWarpVertex* urVertex=(ossimQuadTreeWarpVertex*)NULL,
+                         ossimQuadTreeWarpVertex* lrVertex=(ossimQuadTreeWarpVertex*)NULL,
+                         ossimQuadTreeWarpVertex* llVertex=(ossimQuadTreeWarpVertex*)NULL)
+      : theBoundingRect(bounds),
+        theUlVertex(ulVertex),
+        theUrVertex(urVertex),
+        theLrVertex(lrVertex),
+        theLlVertex(llVertex),
+        theParent(parent)
+      {
+      }
+
+   bool hasValidVertices()const
+      {
+         return (theUlVertex&&theUrVertex&&theLrVertex&&theLlVertex);
+      }
+   
+   void removeVertex(ossimQuadTreeWarpVertex* v)
+      {
+         if(!v) return;
+
+         if(theUlVertex == v)
+         {
+            theUlVertex = NULL;
+            v->removeNode(this);
+         }
+         if(theUrVertex == v)
+         {
+            theUrVertex = NULL;
+            v->removeNode(this);
+         }
+         if(theLrVertex == v)
+         {
+            theLrVertex = NULL;
+            v->removeNode(this);
+         }
+         if(theLlVertex == v)
+         {
+            theLlVertex = NULL;
+            v->removeNode(this);
+         }
+         
+      }
+   void removeVertices()
+      {
+         removeVertex(theUlVertex);
+         removeVertex(theUrVertex);
+         removeVertex(theLrVertex);
+         removeVertex(theLlVertex);
+      }
+   
+   bool isLeaf()const
+      {
+         return (theChildren.size() == 0);
+      }
+   void clear()
+      {
+         theBoundingRect.makeNan();
+         theChildren.clear();
+         theParent = NULL;
+         removeVertex(theUlVertex);
+         removeVertex(theUrVertex);
+         removeVertex(theLrVertex);
+         removeVertex(theLlVertex);
+      }
+   void removeChild(ossimQuadTreeWarpNode* node);
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix = 0)const;
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix = 0);
+
+   ossimDrect                 theBoundingRect;
+   ossimQuadTreeWarpVertex*   theUlVertex;
+   ossimQuadTreeWarpVertex*   theUrVertex;
+   ossimQuadTreeWarpVertex*   theLrVertex;
+   ossimQuadTreeWarpVertex*   theLlVertex;
+   ossimQuadTreeWarpNode*     theParent;
+   
+   vector<ossimQuadTreeWarpNode*> theChildren;
+};
+
+class ossimQuadTreeWarp : public ossim2dTo2dTransform
+{
+public:
+   friend std::ostream& operator<<(std::ostream& out,
+                                   const ossimQuadTreeWarp& rhs)
+      {
+         rhs.print(out);
+
+         return out;
+      }
+
+   ossimQuadTreeWarp()
+      :theTree(NULL)
+      {
+      }
+   
+   ossimQuadTreeWarp(const ossimDrect& boundingRect,
+                     const ossimDpt& ulShift=ossimDpt(0,0),
+                     const ossimDpt& urShift=ossimDpt(0,0),
+                     const ossimDpt& lrShift=ossimDpt(0,0),
+                     const ossimDpt& llShift=ossimDpt(0,0))
+      :theTree(NULL)
+      {
+         create(boundingRect, ulShift, urShift, lrShift, llShift);
+      }
+
+   ossimQuadTreeWarp::ossimQuadTreeWarp(const ossimQuadTreeWarp& rhs);
+   virtual ossimObject* dup()const
+      {
+         return new ossimQuadTreeWarp(*this);
+      }
+   
+   virtual ~ossimQuadTreeWarp()
+      {
+         clear();
+      }
+   
+   virtual ossimDpt getOrigin()const
+      {
+         if(!isEmpty())
+         {
+            if(!theTree->theBoundingRect.hasNans())
+            {
+               return theTree->theBoundingRect.midPoint();
+            }
+            
+         }
+         
+         return ossimDpt(0,0);
+      }
+
+   void create(const ossimDrect& boundingRect,
+               const ossimDpt& ulShift=ossimDpt(0,0),
+               const ossimDpt& urShift=ossimDpt(0,0),
+               const ossimDpt& lrShift=ossimDpt(0,0),
+               const ossimDpt& llShift=ossimDpt(0,0));
+               
+   /*!
+    * Will warp the passed in point and placed the warped value in result
+    */
+   virtual void forward(const ossimDpt& pt,
+                        ossimDpt& result)const;   
+   /*!
+    * Will warp the passed in point and overwrite it
+    */
+   virtual void forward(ossimDpt& pt)const;
+   
+//    void inverse(const ossimDpt& input,
+//                 ossimDpt&       output) const;
+   
+   virtual std::ostream& print(std::ostream& out) const;
+   virtual void printVertices(std::ostream& out)const;
+
+   ossimQuadTreeWarpNode* getRoot()
+      {
+         return theTree;
+      }
+   const ossimQuadTreeWarpNode* getRoot()const
+      {
+         return theTree;
+      }
+   
+   bool isEmpty()const
+      {
+         return (theTree==NULL);
+      }
+
+   ossimQuadTreeWarpVertex* findClosestVertex(ossimDpt& position);
+   
+   /*!
+    * This method will go through the tree and try to locate the
+    * vertex.  This is faster sine the tree is sorted.  Use
+    * the getVertex to just search the internal shared vertex list.
+    */
+   ossimQuadTreeWarpVertex* findVertex(const ossimDpt& position);
+
+   /*!
+    * Searches the shared vetex list.  This will not go through the tree.
+    * this is needed for load states to perform correctly.
+    */
+   ossimQuadTreeWarpVertex* getVertex(const ossimDpt& position);
+   
+   /*!
+    * Will get the shift or delta value for the passed in pt.
+    */
+   void getShift(ossimDpt& result,
+                 const ossimDpt& pt)const;
+
+   /*!
+    * The initial passed in node must not be a leaf.  It will
+    * turn the passed in node into a leaf by recursively
+    * pruning its children.  
+    */
+   void pruneTree(ossimQuadTreeWarpNode* node);
+   
+   // Search methods
+   ossimQuadTreeWarpNode* findNode(const ossimDpt& pt);
+   
+   const ossimQuadTreeWarpNode* findNode(const ossimDpt& pt)const;
+   
+    /*!
+    * Will get the shift or delta value for the passed in pt.
+    */
+   ossimDpt getShift(const ossimDpt& pt)const
+      {
+         ossimDpt result;
+         
+         getShift(result, pt);
+         
+         return result;
+      }
+
+   
+   void clear();
+
+   void split(const ossimDpt& point,
+              double splitHoriCoefficient=0.0,
+              double splitVertCoefficient=0.0);
+
+   /*!
+    * The passed in node is suppose to be a leaf node.
+    * it splits the leaf node horizontally and vertically
+    * by the passed in percentage.  Use find node to
+    * find the leaf node of a given point 
+    */
+   void split(ossimQuadTreeWarpNode* node,
+              double splitHoriCoefficient=.5,
+              double splitVertCoefficient=.5);
+
+
+   const ossimQuadTreeWarpNode* findNode(const ossimQuadTreeWarpNode* node,
+                                         const ossimDpt& pt)const;
+   
+   ossimQuadTreeWarpNode* findNode(ossimQuadTreeWarpNode* node,
+                                   const ossimDpt& pt);
+
+   void findAllNodes(std::vector<ossimQuadTreeWarpNode*>& result,
+                     const ossimDpt& pt);
+   void findAllNodes(std::vector<const ossimQuadTreeWarpNode*>& result,
+                     const ossimDpt& pt)const;
+   void findAllNodes(std::vector<ossimQuadTreeWarpNode*>& result,
+                     ossimQuadTreeWarpNode* node,
+                     const ossimDpt& pt);
+   void findAllNodes(std::vector<const ossimQuadTreeWarpNode*>& result,
+                     ossimQuadTreeWarpNode* node,
+                     const ossimDpt& pt)const;
+  
+   bool isOnEdge(ossimQuadTreeWarpNode* node,
+                 const ossimDpt& point)const;
+
+   bool isOnPoint(ossimQuadTreeWarpNode* node,
+                  const ossimDpt& point)const;
+
+   void updateAllVericeLockFlags();
+
+   const std::vector<ossimQuadTreeWarpVertex*>& getVertices()const
+      {
+         return theVertexList;
+      }
+   void setWarpEnabledFlag(bool flag)
+      {
+         theWarpEnabledFlag = flag;
+      }
+   void setToIdentity();
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+      
+protected:
+   bool                             theWarpEnabledFlag;
+   ossimQuadTreeWarpNode*           theTree;
+   std::vector<ossimQuadTreeWarpVertex*> theVertexList;
+
+   void getShift(ossimDpt& result,
+                 const ossimQuadTreeWarpNode* node,
+                 const ossimDpt& pt)const;
+
+   void recursivePruneTree(ossimQuadTreeWarpNode* node);
+   void pruneSharedVertices();
+   void removeSharedVertex(ossimQuadTreeWarpVertex* v);
+
+   void recursivePrint(std::ostream& out,
+                       ossimQuadTreeWarpNode* node)const;
+   void recursiveDelete(ossimQuadTreeWarpNode* node);
+
+   void getNewQuads(ossimQuadTreeWarpNode* parent,
+                    const ossimDrect& ul,
+                    const ossimDrect& ur,
+                    const ossimDrect& lr,
+                    const ossimDrect& ll,
+                    ossimQuadTreeWarpNode*& ulNode,
+                    ossimQuadTreeWarpNode*& urNode,
+                    ossimQuadTreeWarpNode*& lrNode,
+                    ossimQuadTreeWarpNode*& llNode);
+   
+   void updateLockFlag(ossimQuadTreeWarpVertex* v);
+   void updateDelta(ossimQuadTreeWarpVertex* v);
+   
+   bool recursiveSave(ossimQuadTreeWarpNode* node,
+                      ossimKeywordlist& kwl,
+                      const char* prefix)const;
+
+   bool recursiveLoad(ossimQuadTreeWarpNode* node,
+                      const ossimKeywordlist& kwl,
+                      const char* prefix);
+
+//   bool resetAllSharedLists();
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimRectanglePartitioner.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimRectanglePartitioner.cpp
new file mode 100644
index 0000000000..6620c69e59
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimRectanglePartitioner.cpp
@@ -0,0 +1,248 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2004 David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// Utility class to partition up a rectangle.
+//
+// $Id: ossimRectanglePartitioner.cpp,v 1.3 2005/01/28 21:12:27 dburken Exp $
+//----------------------------------------------------------------------------
+
+#include <base/misc/ossimRectanglePartitioner.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimTrace.h>
+using namespace std;
+
+static ossimTrace traceDebug("ossimRectanglePartitioner:degug");
+
+ossimRectanglePartitioner::ossimRectanglePartitioner()
+{
+}
+
+ossimRectanglePartitioner::~ossimRectanglePartitioner()
+{
+}
+
+void ossimRectanglePartitioner::binaryPartition(
+   const ossimIrect& inputRectangle,
+   vector<ossimIrect>& result,
+   ossim_uint64 maxSizeInBytes,
+   ossim_uint32 bands,
+   ossim_uint32 bytesPerPixel,
+   ossim_uint32 internalOverlapPixels) const
+{
+   // Clear the result rect for starters.
+   result.clear();
+
+   // Some sanity checks.
+   if (maxSizeInBytes == 0)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "Waning:  0 passed for max size in bytes.  Returning..."
+         << endl;
+      return;
+   }
+   if (bands == 0)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "Waning:  0 passed for number of bands.  Returning..."
+         << endl;
+      return;
+   }
+   if (bytesPerPixel == 0)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "Waning:  0 passed for bytes per pixel.  Returning..."
+         << endl;
+      return;
+   }
+   if (inputRectangle.hasNans())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "Waning:  Input rectangle has nans in it!  Returning..."
+         << endl;
+      return;
+   }
+   if ( (maxSizeInBytes / (bands*bytesPerPixel)) < 4)
+   {
+      // Come on now you have to have at least four pixels.
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "Waning:  Max size in bytes too small.  Returning..."
+         << endl;
+      return;
+   }
+   // End of sanity checks...
+
+   // Check the size... We could already be there.
+   if (getSize(inputRectangle, bands, bytesPerPixel) <= maxSizeInBytes)
+   {
+      result.push_back(inputRectangle);
+
+      if (traceDebug())
+      {
+         trace(inputRectangle, result, maxSizeInBytes, bands, bytesPerPixel);
+      }
+      
+      return;
+   }   
+
+   // OK, find the rectangle size that gets that will fit the max size.
+   ossimIrect tileRect = inputRectangle;
+   
+   splitUntilLessThanMax(tileRect,
+                         maxSizeInBytes,
+                         bands,
+                         bytesPerPixel,
+                         internalOverlapPixels);
+
+   ossim_int32 input_width  = static_cast<ossim_int32>(inputRectangle.width());
+   ossim_int32 input_height = static_cast<ossim_int32>(inputRectangle.height());
+
+   ossim_int32 tile_width   = static_cast<ossim_int32>(tileRect.width());
+   ossim_int32 tile_height  = static_cast<ossim_int32>(tileRect.height());
+
+   ossim_int32 tiles_wide   = (input_width % tile_width) ?
+      ( (input_width/tile_width)+1) : (input_width/tile_width);
+   ossim_int32 tiles_high   = (input_height % tile_height) ?
+      ( (input_height/tile_height)+1) : (input_height/tile_height);
+
+   ossim_int32 y_start = inputRectangle.ul().y;
+   ossim_int32 y_stop  = y_start + tile_height - 1 + internalOverlapPixels;
+
+   for (ossim_int32 y = 0; y < tiles_high; ++y)
+   {
+      // Clip to bottom if needed.
+      if (y_stop > inputRectangle.lr().y)
+      {
+         y_stop = inputRectangle.lr().y;
+      }
+      
+      ossim_int32 x_start = inputRectangle.ul().x;
+      ossim_int32 x_stop  = x_start + tile_width - 1 + internalOverlapPixels;
+      
+      for (ossim_int32 x = 0; x < tiles_wide; ++x)
+      {
+         // Clip to right edge is needed.
+         if (x_stop > inputRectangle.lr().x)
+         {
+            x_stop = inputRectangle.lr().x;
+         }
+
+         ossimIrect r(x_start, y_start, x_stop, y_stop);
+
+         // Add it to the result.
+         result.push_back(r);
+         
+         if( 0 == x )
+         {
+            x_start += tile_width - internalOverlapPixels;
+         }
+         else
+         {
+            x_start += tile_width;
+         }
+         x_stop  += tile_width;
+         
+      } // End of tiles_wide loop.
+      
+      if( 0 == y )
+      {
+         y_start += tile_height - internalOverlapPixels;
+      }
+      else
+      {
+         y_start += tile_height;
+      }
+      y_stop  += tile_height;
+      
+   } // End of tiles_high loop.
+   
+   if (traceDebug())
+   {
+      trace(inputRectangle, result, maxSizeInBytes, bands, bytesPerPixel);
+   }
+}
+
+void ossimRectanglePartitioner::splitUntilLessThanMax(
+   ossimIrect& rect,
+   ossim_uint64 maxSizeInBytes,
+   ossim_uint32 bands,
+   ossim_uint32 bytesPerPixel,
+   ossim_uint32 internalOverlapPixels) const
+{
+   do
+   {
+      splitRect(rect);
+
+   } while ( getSize(rect,
+                     bands,
+                     bytesPerPixel,
+                     internalOverlapPixels) > maxSizeInBytes );
+}
+
+void ossimRectanglePartitioner::splitRect(ossimIrect& rect) const
+{
+   ossim_int32 width  = static_cast<ossim_int32>(rect.width());
+   ossim_int32 height = static_cast<ossim_int32>(rect.height());
+   ossim_int32 new_width;
+   ossim_int32 new_height;
+   
+   if (height > width)
+   {
+      new_width  = width;
+      new_height = (height % 2) ? ( (height/2) + 1 ) : (height/2);
+   }
+   else
+   {
+      new_width  = (width % 2) ? ( (width/2) + 1) : (width/2);
+      new_height = height;
+   }
+   
+   rect = ossimIrect(0, 0, new_width-1, new_height-1);
+}
+
+ossim_uint64 ossimRectanglePartitioner::getSize(
+   const ossimIrect& rect,
+   ossim_uint32 bands,
+   ossim_uint32 bytesPerPixel,
+   ossim_uint32 internalOverlapPixels) const
+{
+   return( ( rect.width()  + 2 * internalOverlapPixels ) *
+           ( rect.height() + 2 * internalOverlapPixels ) *
+           bands * bytesPerPixel );
+}
+
+void ossimRectanglePartitioner::trace(const ossimIrect& r,
+                                      const std::vector<ossimIrect>& v,
+                                      ossim_uint64 maxSizeInBytes,
+                                      ossim_uint32 bands,
+                                      ossim_uint32 bytesPerPixel) const
+{
+   ossimNotify(ossimNotifyLevel_DEBUG)
+      << "ossimRectanglePartitioner DEBUG:"
+      << "\nInput rectangle:            " << r
+      << "\nInput rectangle byte size:  " << getSize(r, bands, bytesPerPixel)
+      << "\nTile max size in bytes:     " << maxSizeInBytes
+      << "\nbands:                      " << bands
+      << "\nbytesPerPixel:              " << bytesPerPixel
+      << "\nNumber of output tiles:     " << v.size()
+      << "\nTiled rectangles:\n";
+
+   int index = 0;
+   vector<ossimIrect>::const_iterator i = v.begin();
+   while(i != v.end())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "tile[" << index << "]:  " << *i
+         << "\nsize in bytes:  " << getSize(*i, bands, bytesPerPixel)
+         << endl;
+      ++i;
+      ++index;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimRectanglePartitioner.h b/Utilities/OSSIM/ossim_core/base/misc/ossimRectanglePartitioner.h
new file mode 100644
index 0000000000..585cc2c2a7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimRectanglePartitioner.h
@@ -0,0 +1,147 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2004 David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// Utility class to partition up a rectangle.
+//
+// $Id: ossimRectanglePartitioner.h,v 1.3 2005/01/28 21:12:27 dburken Exp $
+//----------------------------------------------------------------------------
+#ifndef ossimRectanglePartitioner_HEADER
+#define ossimRectanglePartitioner_HEADER
+
+#include <base/common/ossimConstants.h>
+#include <vector>
+
+class ossimIrect;
+
+/**
+ * class ossimRectanglePartitioner
+ * Utility class to partition up a rectangle.
+ */
+class OSSIMDLLEXPORT ossimRectanglePartitioner
+{
+public:
+
+   /** default construtor */
+   ossimRectanglePartitioner();
+
+   /** destructor */
+   ~ossimRectanglePartitioner();
+
+   /**
+    * Partitions the rectangle doing a binary split on the longest dimension
+    * until the total size is less than or equal to the "maxSizeInBytes".
+    * Initializes "result" with the resulting rectangles starting at the
+    * upper left corner.
+    *
+    * @param inputRectangle The source rectangle usually the bounding rectangle
+    * of a scene.
+    *
+    * @param result The vector of ossimIrects to hold the result.
+    *
+    * @param maxSizeInBytes Maximum size of the resulting rectangle partitions
+    * in bytes.
+    *
+    * @param bands The number of bands in the image.
+    *
+    * @param bytesPerPixel.  The number of bytes per pixel for a single band.
+    *
+    * @param internalOverlapPixels Overlap in pixels for desired partitions.
+    * (default = 0) This is added to all four sides of the rectangle so 
+    *
+    * @note The result rectangle passed in will be cleared for starters.
+    *
+    * @note Edge rectangles will be clipped to the inputRectangle.
+    */
+   void binaryPartition(const ossimIrect& inputRectangle,
+                        std::vector<ossimIrect>& result,
+                        ossim_uint64 maxSizeInBytes,
+                        ossim_uint32 bands,
+                        ossim_uint32 bytesPerPixel,
+                        ossim_uint32 internalOverlapPixels = 0) const;
+
+private:
+
+   /**
+    * Recursively splits the input rectangle until the size is less than
+    * or equal to maxSizeInBytes.
+    * 
+    * @param rect Input rectangle to split.
+    *
+    * @param maxSizeInBytes Maximum size of the resulting rectangle partitions
+    * in bytes.
+    *
+    * @param bands The number of bands in the image.
+    *
+    * @param bytesPerPixel.  The number of bytes per pixel for a single band.
+    *
+    * @param internalOverlapPixels Overlap in pixels for desired partitions.
+    * (default = 0)
+    *
+    * @note Will split the longest dimension.  If square will split in the
+    * lengthwise direction.
+    */
+   void splitUntilLessThanMax(ossimIrect& rect,
+                              ossim_uint64 maxSizeInBytes,
+                              ossim_uint32 bands,
+                              ossim_uint32 bytesPerPixel,
+                              ossim_uint32 internalOverlapPixels = 0) const;
+
+   /**
+    * Splits rectangle in half rounding up if needed.
+    *
+    * @param input Rectangle to split.
+    *
+    * @note output will be a zero base rect.
+    *
+    * @notes Will split the longest dimension.  If square will split in the
+    * lengthwise direction.
+    */
+   void splitRect(ossimIrect& rect) const;
+
+   /**
+    * @param rect Rectangle to give size for in bytes.
+    *
+    * @param bands The number of bands in the image.
+    *
+    * @param bytesPerPixel.  The number of bytes per pixel for a single band.
+    *
+    * @param internalOverlapPixels Overlap in pixels.
+    * (default = 0)
+    * 
+    * @return size of rectangle in bytes.
+    */
+   ossim_uint64 getSize(const ossimIrect& rect,
+                        ossim_uint32 bands,
+                        ossim_uint32 bytesPerPixel,
+                        ossim_uint32 internalOverlapPixels = 0) const;
+
+   /**
+    * Convenience trace method.
+    *
+    * @param r Input rectangle.
+    *
+    * @param v Vector of resulting partitioned rectangles.
+    *
+    * @param maxSizeInBytes Maximum size of the resulting rectangle partitions
+    * in bytes.
+    *
+    * @param bands The number of bands in the image.
+    *
+    * @param bytesPerPixel.  The number of bytes per pixel for a single band.
+    */
+   void trace(const ossimIrect& r,
+              const std::vector<ossimIrect>& v,
+              ossim_uint64 maxSizeInBytes,
+              ossim_uint32 bands,
+              ossim_uint32 bytesPerPixel) const;
+   
+};
+
+#endif /* End of "#ifndef ossimRectanglePartitioner_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimUnitConversionTool.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimUnitConversionTool.cpp
new file mode 100644
index 0000000000..519a5e1449
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimUnitConversionTool.cpp
@@ -0,0 +1,349 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimUnitConversionTool.cpp,v 1.12 2005/08/02 17:24:17 dburken Exp $
+#include <base/misc/ossimUnitConversionTool.h>
+#include <base/data_types/ossimGpt.h>
+
+std::ostream& operator<<(std::ostream& out,
+                         const ossimUnitConversionTool& data)
+{
+   out << setprecision(15) << setiosflags(ios::fixed)
+       << "Meters:           " << data.getMeters() << endl
+       << "Feet:             " << data.getFeet() << endl
+       << "U.S. Survey Feet: " << data.getUsSurveyFeet() << endl
+       << "Nautical miles:   " << data.getNauticalMiles() << endl
+       << "Degrees:          " << data.getDegrees() << endl
+       << "Minutes:          " << data.getMinutes() << endl
+       << "Seconds:          " << data.getSeconds() << endl;
+   
+   return out;
+}
+
+ossimUnitConversionTool::ossimUnitConversionTool(double value,
+                                                 ossimUnitType unitType)
+   : theValue(value),
+     theUnitType(unitType),
+     theOrigin()
+{
+}
+
+ossimUnitConversionTool::ossimUnitConversionTool(const ossimGpt& origin,
+                                                 double value,
+                                                 ossimUnitType unitType)
+   : theValue(value),
+     theUnitType(unitType),
+     theOrigin(origin)
+{
+}
+
+void ossimUnitConversionTool::setOrigin(const ossimGpt& gpt)
+{
+   theOrigin = gpt;
+}
+
+ossimGpt ossimUnitConversionTool::getOrigin()const
+{
+   return theOrigin;
+}
+
+void ossimUnitConversionTool::getOrigin(ossimGpt& result)const
+{
+   result = theOrigin;
+}
+
+void ossimUnitConversionTool::setValue(double value,
+                                       ossimUnitType unitType)
+{
+   theValue    = value;
+   theUnitType = unitType;
+}
+
+double ossimUnitConversionTool::getValue(ossimUnitType unitType) const
+{
+   switch(unitType)
+   {
+      case OSSIM_METERS:
+      {
+         return getMeters();
+      }
+      case OSSIM_RADIANS:
+      {
+         return getRadians();
+      }
+      case OSSIM_DEGREES:
+      {
+         return getDegrees();
+      }
+      case OSSIM_US_SURVEY_FEET:
+      {
+         return getUsSurveyFeet();
+      }
+      case OSSIM_FEET:
+      {
+         return getFeet();
+      }
+      case OSSIM_SECONDS:
+      {
+         return getSeconds();
+      }
+      case OSSIM_MINUTES:
+      {
+         return getMinutes();
+      }
+      case OSSIM_NAUTICAL_MILES:
+      {
+         return getNauticalMiles();
+      }
+      case OSSIM_MILES:
+      {
+         return getMiles();
+      }
+      default:
+         break;
+   }
+
+   return OSSIM_DBL_NAN;
+}
+
+void ossimUnitConversionTool::setMeters(double value)
+{
+   setValue(value, OSSIM_METERS);
+}
+
+void ossimUnitConversionTool::setRadians(double value)
+{
+   setValue(value, OSSIM_RADIANS);
+}
+
+void ossimUnitConversionTool::setDegrees(double value)
+{
+   setValue(value, OSSIM_DEGREES);
+}
+
+void ossimUnitConversionTool::setMinutes(double value)
+{
+   setValue(value, OSSIM_MINUTES);
+}
+
+void ossimUnitConversionTool::setSeconds(double value)
+{
+   setValue(value, OSSIM_SECONDS);
+}
+
+void ossimUnitConversionTool::setUsSurveyFeet(double value)
+{
+   setValue(value, OSSIM_US_SURVEY_FEET);
+}
+
+void ossimUnitConversionTool::setFeet(double value)
+{
+   setValue(value, OSSIM_FEET);
+}
+
+void ossimUnitConversionTool::setNauticalMiles(double value)
+{
+   setValue(value, OSSIM_NAUTICAL_MILES);
+}
+
+void ossimUnitConversionTool::setMiles(double value)
+{
+   setValue(value, OSSIM_MILES);
+}
+
+void ossimUnitConversionTool::setMillimeters(double value)
+{
+   setValue(value, OSSIM_MILLIMETERS);
+}
+
+void ossimUnitConversionTool::setMicrons(double value)
+{
+   setValue(value, OSSIM_MICRONS);
+}
+
+double ossimUnitConversionTool::getMeters()const
+{
+   if(theUnitType == OSSIM_METERS)
+   {
+      return theValue;
+   }
+   
+   return computeMeters();
+}
+
+double ossimUnitConversionTool::getRadians()const
+{
+   if(theUnitType == OSSIM_RADIANS)
+   {
+      return theValue;
+   }
+   return getDegrees()*RAD_PER_DEG;
+}
+
+double ossimUnitConversionTool::getDegrees()const
+{
+   switch (theUnitType)
+   {
+      case OSSIM_DEGREES:
+      {
+         return theValue;
+      }
+      case OSSIM_MINUTES:
+      {
+         return (theValue / 60.0);
+      }
+      case OSSIM_SECONDS:
+      {
+         return (theValue / 3600.0);
+      }
+      case OSSIM_RADIANS:
+      {
+         return (theValue * DEG_PER_RAD);
+      }
+      default:
+         break;
+   }
+   
+   ossimDpt pt = theOrigin.metersPerDegree();
+   return (computeMeters() /((pt.x+pt.y)*.5));
+}
+
+double ossimUnitConversionTool::getMinutes()const
+{
+   if(theUnitType == OSSIM_MINUTES)
+   {
+      return theValue;
+   }
+   return (getDegrees()*60.0);
+}
+
+double ossimUnitConversionTool::getSeconds()const
+{
+   if(theUnitType == OSSIM_SECONDS)
+   {
+      return theValue;
+   }
+   return (getDegrees()*3600.0);
+}
+
+double ossimUnitConversionTool::getUsSurveyFeet()const
+{
+   if(theUnitType == OSSIM_US_SURVEY_FEET)
+   {
+      return theValue;
+   }
+   return (computeMeters()/US_METERS_PER_FT);
+}
+
+double ossimUnitConversionTool::getFeet()const
+{
+   if(theUnitType == OSSIM_FEET)
+   {
+      return theValue;
+   }
+   return (computeMeters()*FT_PER_MTRS);
+}
+
+double ossimUnitConversionTool::getNauticalMiles()const
+{
+   if(theUnitType == OSSIM_NAUTICAL_MILES)
+   {
+      return theValue;
+   }
+   
+   return (computeMeters()/(theOrigin.metersPerDegree().y/60.0));
+}
+
+double ossimUnitConversionTool::getMiles()const
+{
+   if(theUnitType == OSSIM_MILES)
+   {
+      return theValue;
+   }
+   return ((computeMeters()*FT_PER_MTRS)/FT_PER_MILE);
+}
+
+double ossimUnitConversionTool::getMillimeters()const
+{
+   if(theUnitType == OSSIM_MILLIMETERS)
+   {
+      return theValue;
+   }
+   return ((computeMeters()*1e3));
+}
+
+double ossimUnitConversionTool::getMicrons()const
+{
+   if(theUnitType == OSSIM_MICRONS)
+   {
+      return theValue;
+   }
+   return ((computeMeters()*1e6));
+}
+
+double ossimUnitConversionTool::computeMeters()const
+{
+   switch(theUnitType)
+   {
+      case OSSIM_METERS:
+      {
+         return theValue;
+         break;
+      }
+      case OSSIM_RADIANS:
+      {
+         ossimDpt pt = theOrigin.metersPerDegree();
+         return (theValue*DEG_PER_RAD)*((pt.x+pt.y)*.5);
+      }
+      case OSSIM_DEGREES:
+      {
+         ossimDpt pt = theOrigin.metersPerDegree();
+         return theValue*((pt.x+pt.y)*.5);
+      }
+      case OSSIM_US_SURVEY_FEET:
+      {
+         return  US_METERS_PER_FT*theValue;
+      }
+      case OSSIM_FEET:
+      {
+         return MTRS_PER_FT*theValue;
+      }
+      case OSSIM_SECONDS:
+      {
+         ossimDpt pt = theOrigin.metersPerDegree();
+         return (theValue/3600.0)*((pt.x+pt.y)*.5);
+      }
+      case OSSIM_MINUTES:
+      {
+         ossimDpt pt = theOrigin.metersPerDegree();
+         return (theValue/60.0)*((pt.x+pt.y)*.5);
+      }
+      case OSSIM_NAUTICAL_MILES:
+      {
+         return (theOrigin.metersPerDegree().y/60.0)*theValue;
+      }
+      case OSSIM_MILES:
+      {
+         return MTRS_PER_FT*FT_PER_MILE*theValue;
+      }
+      case OSSIM_MILLIMETERS:
+      {
+         return (theValue/(1e3));
+      }
+      case OSSIM_MICRONS:
+      {
+         return (theValue/(1e6));
+      }
+      default:
+         break;
+   }
+
+   return OSSIM_DBL_NAN;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimUnitConversionTool.h b/Utilities/OSSIM/ossim_core/base/misc/ossimUnitConversionTool.h
new file mode 100644
index 0000000000..1eade17b0d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimUnitConversionTool.h
@@ -0,0 +1,93 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimUnitConversionTool.h,v 1.13 2005/08/02 17:24:17 dburken Exp $
+#ifndef ossimUnitConversionTool_HEADER
+#define ossimUnitConversionTool_HEADER
+#include <iostream>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimGpt.h>
+
+class OSSIM_DLL ossimUnitConversionTool
+{
+public:
+   friend std::ostream& operator<<(std::ostream& out,
+                                   const ossimUnitConversionTool& data);
+
+   ossimUnitConversionTool(double value=1.0,
+                           ossimUnitType unitType=OSSIM_METERS);
+
+   ossimUnitConversionTool(const ossimGpt& origin,
+                           double value,
+                           ossimUnitType unitType=OSSIM_METERS);
+
+   void setOrigin(const ossimGpt& gpt);
+
+   ossimGpt getOrigin()const;
+
+   void getOrigin(ossimGpt& result)const;
+
+   void setValue(double value, ossimUnitType unitType=OSSIM_METERS);
+
+   double getValue(ossimUnitType unitType=OSSIM_METERS) const;
+   
+   void setMeters(double value);
+
+   void setRadians(double value);
+
+   void setDegrees(double value);
+
+   void setMinutes(double value);
+
+   void setSeconds(double value);
+
+   void setUsSurveyFeet(double value);
+
+   void setFeet(double value);
+
+   void setNauticalMiles(double value);
+
+   void setMiles(double value);
+
+   void setMillimeters(double value);
+
+   void setMicrons(double value);
+
+   double getMeters()const;
+   
+   double getRadians()const;
+
+   double getDegrees()const;
+
+   double getMinutes()const;
+
+   double getSeconds()const;
+
+   double getUsSurveyFeet()const;
+
+   double getFeet()const;
+
+   double getNauticalMiles()const;
+
+   double getMiles()const;
+
+   double getMillimeters()const;
+
+   double getMicrons()const;
+   
+protected:
+   double         theValue;
+   ossimUnitType  theUnitType;
+   ossimGpt       theOrigin;
+
+   double computeMeters()const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimUsgsQuad.cpp b/Utilities/OSSIM/ossim_core/base/misc/ossimUsgsQuad.cpp
new file mode 100644
index 0000000000..181f2f14f3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimUsgsQuad.cpp
@@ -0,0 +1,730 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimUsgsQuad.cpp,v 1.7 2004/04/05 13:31:35 gpotts Exp $
+#include <sstream>
+#include <iomanip>
+
+#include <base/misc/ossimUsgsQuad.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+using namespace std;
+
+static const
+double QUARTER_QUAD_SEG_SIZE_IN_DEGREES = 0.03125; // 3.75 minutes/60.0/2.0
+static const double QUARTER_QUAD_SIZE_IN_DEGREES = 0.0625; // 3.75 minutes/60.0
+static const double QUAD_SIZE_IN_DEGREES = 0.125; // 7.5 minutes/60
+
+
+//***
+// Static trace for debugging
+//***
+static ossimTrace traceDebug("USGS_quad::debug");
+
+
+ossimUsgsQuad::ossimUsgsQuad(const ossimGpt& lrGpt)
+   :
+      theQuadLowerRightCorner(0.0, 0.0, 0.0, lrGpt.datum()),
+      theQuarterQuadLowerRightCorner(0.0, 0.0, 0.0, lrGpt.datum())
+//      thePaddingInDegrees(0.0, 0.0),
+
+{
+   const char* MODULE = "ImgOutput::quadBasename";
+
+   //***
+   // NOTE:
+   // This method computes a file name from the lower right corner of the
+   // image.  The format is derived from USGS Digital Raster Graphic(DRG)
+   // program for standardized data set names for DRG products.  Due to
+   // customer  requirements there is one deviation:  The first digit of the
+   // name is converted to a letter with 1 being = A, 2 being = B,
+   // 3 being = C, ....
+   // This was done to allow the name to be used on a pc.
+   //***
+
+   const double QUAD_SIZE_IN_DEGREES = 0.125;
+
+   ossimString          baseString;
+   int                  tmpInt;
+   double               tmpDbl;
+   char quadChar        = 'A';
+   char quadNum         = '1';
+
+   ostringstream           os;
+   os << setiosflags(ios::right)
+      << setiosflags(ios::fixed)
+      << setfill('0');
+
+   tmpInt = abs(static_cast<int>(lrGpt.lat)); // Cast away the fractional part.
+   os << tmpInt; // latitude
+
+   //***
+   // Get the quadrant charactor in the latitude direction. (A - H)
+   //***
+   tmpDbl = fabs(lrGpt.lat) - (double)tmpInt;
+   quadChar += static_cast<int>(tmpDbl / QUAD_SIZE_IN_DEGREES);
+
+   tmpInt = abs(static_cast<int>(lrGpt.lon)); // longitude
+   os << setw(3) << tmpInt;
+
+   tmpDbl = fabs(lrGpt.lon) - (double)tmpInt;
+
+   quadNum += static_cast<char>(tmpDbl / QUAD_SIZE_IN_DEGREES);
+
+   os << quadChar << quadNum;
+
+   double latFraction = (lrGpt.lat / QUAD_SIZE_IN_DEGREES) -
+                        irint((lrGpt.lat) / QUAD_SIZE_IN_DEGREES);
+   double lonFraction = (lrGpt.lon / QUAD_SIZE_IN_DEGREES) -
+                        irint((lrGpt.lon) / QUAD_SIZE_IN_DEGREES);
+
+   // Black & White
+//   if(theRectsStandardFlag && 
+//      theChipSource->radiometry().numberOfBands() == 1)
+//   {
+//       char quarterQuadChar = '4';
+//       if (latFraction && lonFraction)
+//       {
+//          quarterQuadChar = '1';
+//       }
+//       else if (latFraction && !lonFraction)
+//       {
+//          quarterQuadChar = '2';
+//       }
+//       else if (!latFraction && lonFraction)
+//       {
+//          quarterQuadChar = '3';
+//       }   
+//       os << quarterQuadChar << ends;
+//    }
+//    // Color 
+//    else if(theRectsStandardFlag &&
+//            theChipSource->radiometry().numberOfBands() > 1)
+//    {
+//       char quarterQuadChar = '8';
+//       if (latFraction && lonFraction)
+//       {
+//          quarterQuadChar = '5';
+//       }
+//       else if (latFraction && !lonFraction)
+//       {
+//          quarterQuadChar = '6';
+//       }
+//       else if (!latFraction && lonFraction)
+//       {
+//          quarterQuadChar = '7';
+//       }   
+//       os << quarterQuadChar << ends;
+//    }
+//    else
+//    {
+      char quarterQuadChar = 'D';
+      if (latFraction && lonFraction)
+      {
+         quarterQuadChar = 'A';
+      }
+      else if (latFraction && !lonFraction)
+      {
+         quarterQuadChar = 'B';
+      }
+      else if (!latFraction && lonFraction)
+      {
+         quarterQuadChar = 'C';
+      }   
+      os << quarterQuadChar << ends;
+//   }
+
+   
+   baseString = os.str().c_str();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << " DEBUG: " << MODULE  
+                                          << "\nbaseString:  " << baseString << "\n";
+   }
+   
+   setQuadName(baseString);
+}
+
+
+//***************************************************************************
+// USGS_quad::USGS_quad(const String& name)
+//***************************************************************************
+ossimUsgsQuad::ossimUsgsQuad(const ossimString& name,
+                             const ossimDatum* datum)
+//                             double paddingInMeters)
+   :
+      theQuadLowerRightCorner(0.0, 0.0, 0.0, datum),
+      theQuarterQuadLowerRightCorner(0.0, 0.0, 0.0, datum)
+//      thePaddingInDegrees(0.0, 0.0),
+{
+   static const char MODULE[] = "ossimUsgsQuad::ossimUsgsQuad";
+
+   setQuadName(name);
+   if (!datum)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: " << MODULE << "\n"
+                                          << "ossimDatum pointer passed in is null. Returning...\n";
+      return;
+   }
+
+
+   //***
+   // Initialize the padding.
+   //***
+//    ossimGpt metersPerDegree = theQuadLowerRightCorner.metersPerDegree();
+
+//    thePaddingInDegrees.u = paddingInMeters / metersPerDegree.u;
+//    thePaddingInDegrees.v = paddingInMeters / metersPerDegree.v;
+
+}
+
+void ossimUsgsQuad::setQuadName(const ossimString& name)
+{
+   const char* MODULE = "ossimUsgsQuad::setQuadName";
+   ossimString qqName = name;
+
+   //***
+   // Check the length of "name" to see if it's correct.  
+   //***
+   if (name.length() < 7)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: " << MODULE << "\n"
+                                          << "Quarder quad name length incorrect.\n"
+                                          << "Name:  " << name << "\n"
+                                          << "Expected length:  7 or 8  Name length:  " << name.length()
+                                          << "\nExample of valid quad:  30089C6B\n"
+                                          << "Represents lower right corner of "
+                                          << "30 deg. 15 min. N., 89 deg. 37.5 min. W.\n"
+                                          << "Breakdown:\n"
+                                          << "30  = latitude on even degree boundary "
+                                          << "(Northern Hemisphere implied)\n"
+                                          << "089 = longitude on even degree boundary "
+                                          << "(Western Hemisphere implied)\n"
+                                          << "C   = Third quad section in latitude direction\n"
+                                          << "6   = Sixth quad section in longitude direction\n"
+                                          << "B   = Quarter quad segment within the quad\n"
+                                          << "    (A=upper left, B=upper right, C=lower left, D=lower right)\n"
+                                          << "Quad size 7.5 minute square,  quarter quad size 3.75 "
+                                          << "minute square.\n";
+
+      
+      return;
+   }
+
+   qqName.upcase();
+
+   char latChars[3];
+   char lonChars[4];
+   char latQuad;
+   char lonQuad;
+//   char segment;
+
+   //***
+   // Get the latitude.
+   //***
+   latChars[0] = qqName.c_str()[0];
+   latChars[1] = qqName.c_str()[1];
+   latChars[2] = '\0';
+
+   //***
+   // Get the longitude.
+   //***
+   lonChars[0] = qqName.c_str()[2];
+   lonChars[1] = qqName.c_str()[3];
+   lonChars[2] = qqName.c_str()[4];
+   lonChars[3] = '\0';
+
+   //***
+   // Get the latitude quad.
+   //***
+   latQuad = qqName.c_str()[5];
+
+   //***
+   // Get the longitude quad.
+   //***
+   lonQuad = qqName.c_str()[6];
+
+   //***
+   // Get the segment within the quad.
+   //***
+   if (name.length() == 8)
+   {
+      theQuarterQuadSegment = qqName.c_str()[7];
+   }
+   else
+   {
+      theQuarterQuadSegment = 'D';
+      ossimNotify(ossimNotifyLevel_NOTICE) << MODULE << ":\n"
+           << "No quarter quad segment entered.  Defaulting to D segment."
+           << "\n";
+   }
+
+   //***
+   // Build up the lower right corner from the extracted parts.
+   //***
+
+   //***
+   // Get the latitude and check the range.
+   //***
+   double lat = atof(latChars);
+   if ( (lat < 0.0) || (lat > 90.0) )
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: " << MODULE << "\n"
+                                          << "Latitude range error.  Latitude extracted:  " << lat
+                                          << "\nRange:  0 to 90\n";
+      return;
+   }
+
+   //***
+   // Get the longitude and check the range.
+   //***
+   double lon = atof(lonChars);
+   if ( (lon  < 0.0) || (lon > 180) )
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: " << MODULE << "\n"
+                                          << "Longitud range error.  Longitude extracted:  " << lon
+                                          << "\nRange:  0 to 180\n";
+      return;
+   }
+
+   //***
+   // Get the latitude quad and add this to "lat".  The quad are letters from
+   // A - H with A being on an even degree boundary, B being 7.5 minute up
+   // and so on.
+   //***
+   double tmp = latQuad - 65;  // Ascii decimal value for A = 65.
+
+   if (tmp)
+   {
+      //***
+      // Check the range.  The are eight quads within one degree.
+      //***
+      if (tmp > 7.0)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL:" << MODULE << "\n"
+                                             << "Latitude quad range error.  Quad extracted:  " << latQuad
+                                             << "\nRange:  A to H\n";
+         return;
+      }
+
+      tmp *= 7.5;  // Convert the quad to minutes.
+
+      lat += tmp/60.0; // Conver minutes to degrees and add to "lat".
+   }
+   
+   //***
+   // Get the longitude quad and add this to "lat".  The quad are letters from
+   // A - H with A being on an even degree boundary, B being 7.5 minute up
+   // and so on.
+   //***
+   tmp = lonQuad - 49; // Ascii decimal value for 1 = 49.
+
+   if (tmp)
+   {
+      //***
+      // Check the range.  The are eight quads within one degree.
+      //***
+      if (tmp > 7.0)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL:" << MODULE << "\n"
+                                             << "Longitude quad range error.  Quad extracted:  " << latQuad
+                                             << "\nRange:  1 to 8\n";
+         return;
+      }
+
+      tmp *= 7.5;  // Convert the quad to minutes.
+
+      lon += tmp/60.0; // Conver minutes to degrees and add to "lon".
+   }
+   
+   //***
+   // Currently this naming convention assumes Northern and Western hemisphere.
+   //***
+   lon = -lon;  // Make negative for Western hemisphere.
+
+   //***
+   // Initialize "theQuadLowerRightCorner".
+   //***
+   theQuadLowerRightCorner.lat = lat;
+   theQuadLowerRightCorner.lon = lon;
+
+   //***
+   // Get the segment and add to "lat" and "lon".
+   //***
+   switch (theQuarterQuadSegment)
+   {
+   case 'A':
+      lat += QUARTER_QUAD_SIZE_IN_DEGREES;
+      lon -= QUARTER_QUAD_SIZE_IN_DEGREES;
+      break;
+
+   case 'B':
+      lat += QUARTER_QUAD_SIZE_IN_DEGREES;
+      break;
+
+   case 'C':
+      lon -= QUARTER_QUAD_SIZE_IN_DEGREES;
+      break;
+
+   case 'D':
+      break; // At the corner of a quad so nothing to do here.
+
+   default:
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL:" << MODULE << "\n"
+                                          << "Quarter quad segment range error.\n"
+                                          << "Quarter quad segment extracted:  " << theQuarterQuadSegment
+                                          << "Range:  A to D\n";
+      return;
+   }
+
+   //***
+   // Initialize "theQuarterQuadLowerRightCorner".
+   //***
+   theQuarterQuadLowerRightCorner.lat = lat;
+   theQuarterQuadLowerRightCorner.lon = lon;
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << ", "
+                                          << qqName << " lower right quad corner:  "
+                                          << theQuadLowerRightCorner << "\n"
+                                          << "Quarter quad segment:  " << theQuarterQuadSegment << "\n"
+                                          << qqName << " lower right quarter quad corner:  "
+                                          << theQuarterQuadLowerRightCorner << "\n";
+   }   
+   theName = qqName;
+}
+
+void ossimUsgsQuad::getQuadList(vector<ossimUsgsQuad>& result,
+                                const ossimGrect& rect)
+{
+   result.clear();
+//   QUAD_SIZE_IN_DEGREES;
+
+   ossimGpt point = rect.ul();
+
+   while(rect.pointWithin(point))
+   {
+      while(rect.pointWithin(point))
+      {
+         result.push_back(ossimUsgsQuad(point));
+
+         point.lond(point.lond()+QUAD_SIZE_IN_DEGREES);
+      }
+      point.lond(rect.ul().lond());
+      point.latd(point.latd()-QUAD_SIZE_IN_DEGREES);
+   }
+}
+
+
+//***************************************************************************
+// ossimUsgsQuad::quarterQuadSegRect()
+//***************************************************************************
+ossimGrect ossimUsgsQuad::quarterQuadSegRect(char seg)
+{
+   static const char MODULE[] = "ossimUsgsQuad::quarterQuadSegRect";
+
+   double startLat=0.0;
+   double startLon=0.0;
+   double stopLat=0.0;
+   double stopLon=0.0;
+
+   //***
+   // Get the segment and add to "lat" and "lon".
+   //***
+   switch (seg)
+   {
+   case 'A':  // Upper left segment of quarter quad.
+      startLat = theQuarterQuadLowerRightCorner.lat +
+                 QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// -
+//                 thePaddingInDegrees.u;
+
+      startLon = theQuarterQuadLowerRightCorner.lon -
+                 QUARTER_QUAD_SIZE_IN_DEGREES;// -
+                 //thePaddingInDegrees.v;
+                 
+      stopLat = theQuarterQuadLowerRightCorner.lat +
+                QUARTER_QUAD_SIZE_IN_DEGREES;// +
+                                             //thePaddingInDegrees.u;
+
+      stopLon =  theQuarterQuadLowerRightCorner.lon -
+                 QUARTER_QUAD_SEG_SIZE_IN_DEGREES; // +
+                                                  //thePaddingInDegrees.v;
+      break;
+
+   case 'B': // Upper right segment of the quarter quad.
+      startLat = theQuarterQuadLowerRightCorner.lat +
+                 QUARTER_QUAD_SEG_SIZE_IN_DEGREES; //-
+//                 thePaddingInDegrees.u;
+
+      startLon = theQuarterQuadLowerRightCorner.lon -
+                 QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// -
+//                 thePaddingInDegrees.v;
+                 
+      stopLat = theQuarterQuadLowerRightCorner.lat +
+                QUARTER_QUAD_SIZE_IN_DEGREES;// +
+//                thePaddingInDegrees.u;
+
+      stopLon =  theQuarterQuadLowerRightCorner.lon;// +
+//                 thePaddingInDegrees.v;
+      break;
+
+   case 'C': // Lower left segment of the quarter quad.
+      startLat = theQuarterQuadLowerRightCorner.lat;// -
+//                 thePaddingInDegrees.u;
+
+      startLon = theQuarterQuadLowerRightCorner.lon -
+                 QUARTER_QUAD_SIZE_IN_DEGREES;// -
+//                 thePaddingInDegrees.v;
+                 
+      stopLat = theQuarterQuadLowerRightCorner.lat +
+                QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// +
+//                thePaddingInDegrees.u;
+
+      stopLon =  theQuarterQuadLowerRightCorner.lon -
+                 QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// +
+//                 thePaddingInDegrees.v;
+
+      break;
+
+   case 'D':
+      startLat = theQuarterQuadLowerRightCorner.lat;// -
+//                 thePaddingInDegrees.u;
+
+      startLon = theQuarterQuadLowerRightCorner.lon -
+                 QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// -
+//                 thePaddingInDegrees.v;
+                 
+      stopLat = theQuarterQuadLowerRightCorner.lat +
+                QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// +
+//                thePaddingInDegrees.u;
+
+      stopLon =  theQuarterQuadLowerRightCorner.lon;// +
+//                 thePaddingInDegrees.v;
+      break; // At the corner of a quad so nothing to do here.
+
+   default:
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL:" << MODULE << "\n"
+                                          << "Quarter quad segment range error.\n"
+                                          << "Quarter quad segment extracted:  " << seg
+                                          << "Range:  A to D\n";
+      break;
+   }
+
+   ossimGrect
+      rect(ossimGpt(startLat,
+                    startLon,
+                    theQuarterQuadLowerRightCorner.height(),
+                    theQuarterQuadLowerRightCorner.datum()),
+           ossimGpt(stopLat,
+                    stopLon,
+                    theQuarterQuadLowerRightCorner.height(),
+                    theQuarterQuadLowerRightCorner.datum()));
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE
+                                          << "\nQuarter quad segment " << seg << " rect:  " << rect << "\n";
+   }
+
+
+   return rect;
+}
+
+//***************************************************************************
+// ossimUsgsQuad::quarterQuadRect()
+//***************************************************************************
+ossimGrect ossimUsgsQuad::quarterQuadRect() const
+{
+   static const char MODULE[] = "ossimUsgsQuad::quarterQuadRect";
+
+   double startLat = theQuarterQuadLowerRightCorner.lat;// -
+//                     thePaddingInDegrees.u;  // SouthWest corner lat.
+
+   double startLon = theQuarterQuadLowerRightCorner.lon -
+                     QUARTER_QUAD_SIZE_IN_DEGREES;// -
+//                     thePaddingInDegrees.v; // SouthWest corner lon.
+   
+   double stopLat = theQuarterQuadLowerRightCorner.lat +
+                     QUARTER_QUAD_SIZE_IN_DEGREES;// +
+//                    thePaddingInDegrees.u; // NorthEast corner lat.
+   
+   double stopLon  = theQuarterQuadLowerRightCorner.lon;// +
+//                     thePaddingInDegrees.v; // NorthEast corner lon.
+
+   ossimGrect
+      rect(ossimGpt(startLat,
+                    startLon,
+                    theQuarterQuadLowerRightCorner.height(),
+                    theQuarterQuadLowerRightCorner.datum()),
+           ossimGpt(stopLat,
+                    stopLon,
+                    theQuarterQuadLowerRightCorner.height(),
+                    theQuarterQuadLowerRightCorner.datum()));
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE
+                                          << "\nQuarter quad rect:  " << rect <<"\n";
+   }
+
+
+   return rect;
+}
+
+//***************************************************************************
+// ossimUsgsQuad::quadRect()
+//***************************************************************************
+ossimGrect ossimUsgsQuad::quadRect() const
+{
+   static const char MODULE[] = "ossimUsgsQuad::quadRect";
+
+   double startLat = theQuadLowerRightCorner.lat;// -
+//                     thePaddingInDegrees.u;  // SouthWest corner lat.
+
+   double startLon = theQuadLowerRightCorner.lon -
+                     QUAD_SIZE_IN_DEGREES;// -
+//                     thePaddingInDegrees.v; // SouthWest corner lon.
+   
+   double stopLat = theQuadLowerRightCorner.lat +
+                     QUAD_SIZE_IN_DEGREES;// +
+//                    thePaddingInDegrees.u; // NorthEast corner lat.
+   
+   double stopLon  = theQuadLowerRightCorner.lon;// +
+//                     thePaddingInDegrees.v; // NorthEast corner lon.
+
+   ossimGrect
+      rect(ossimGpt(startLat,
+                    startLon,
+                    theQuarterQuadLowerRightCorner.height(),
+                    theQuarterQuadLowerRightCorner.datum()),
+           ossimGpt(stopLat,
+                    stopLon,
+                    theQuarterQuadLowerRightCorner.height(),
+                    theQuarterQuadLowerRightCorner.datum()));
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE
+                                          << "\nQuarter quad rect:  " << rect << "\n";
+   }
+
+   return rect;
+}
+
+//***************************************************************************
+// ossimUsgsQuad::quarterQuadSegKwRect(char seg)
+//***************************************************************************
+ossimString ossimUsgsQuad::quarterQuadSegKwRect(char seg)
+{
+   static const char MODULE[] = "ossimUsgsQuad::quarterQuadSegKwRect";
+
+   ossimString tmp;
+
+   //***
+   // Check the range of the segment, must be A, B, C or D.
+   //***
+   if ( (seg < 65) || (seg > 68) )
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL:" << MODULE << "\n"
+                                          << seg << " out of range!\n"
+                                          << "Possible values:  A, B, C, or D\n";
+      return tmp;
+   }
+
+   ossimGrect rect = quarterQuadSegRect(seg);
+
+   ostringstream os;
+
+   os << setprecision(12)
+      << rect.ll().lat  << " "
+      << rect.ul().lon << " "
+      << rect.ul().lat << " "
+      << rect.ur().lon  << ends;
+//      << rect.stop.lat  << " "
+//      << rect.start.lon << " "
+//      << rect.start.lat << " "
+//      << rect.stop.lon  << ends;
+
+   tmp = os.str().c_str();
+
+   return tmp;
+}
+
+//***************************************************************************
+// ossimUsgsQuad::quarterQuadKwRect()
+//***************************************************************************
+ossimString ossimUsgsQuad::quarterQuadKwRect() const
+{
+//   static const char MODULE[] = "ossimUsgsQuad::quarterQuadKwRect";
+
+   ossimGrect rect = quarterQuadRect();
+
+   ostringstream os;
+
+   os << setprecision(12)
+      << rect.ll().lat  << " "
+      << rect.ul().lon << " "
+      << rect.ul().lat << " "
+      << rect.ur().lon  << ends;
+//    os << setprecision(12)
+//       << rect.stop.lat  << " "
+//       << rect.start.lon << " "
+//       << rect.start.lat << " "
+//       << rect.stop.lon  << ends;
+
+   ossimString tmp = os.str().c_str();
+
+
+
+   return tmp;
+}
+
+//***************************************************************************
+// ossimUsgsQuad::quadKwRect()
+//***************************************************************************
+ossimString ossimUsgsQuad::quadKwRect() const
+{
+//   static const char MODULE[] = "ossimUsgsQuad::quadKwRect";
+
+   ossimGrect rect = quadRect();
+
+   ostringstream os;
+
+   os << setprecision(12)
+      << rect.ll().lat  << " "
+      << rect.ul().lon << " "
+      << rect.ul().lat << " "
+      << rect.ur().lon  << ends;
+//    os << setprecision(12)
+//       << rect.stop.lat  << " "
+//       << rect.start.lon << " "
+//       << rect.start.lat << " "
+//       << rect.stop.lon  << ends;
+
+   ossimString tmp = os.str().c_str();
+
+   return tmp;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/misc/ossimUsgsQuad.h b/Utilities/OSSIM/ossim_core/base/misc/ossimUsgsQuad.h
new file mode 100644
index 0000000000..f75fd6ace9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/misc/ossimUsgsQuad.h
@@ -0,0 +1,118 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimUsgsQuad.h,v 1.4 2003/01/27 15:24:34 gpotts Exp $
+#ifndef  ossimUsgsQuad_HEADER
+#define ossimUsgsQuad_HEADER
+#include "base/data_types/ossimGpt.h"
+#include "base/data_types/ossimGrect.h"
+#include "base/data_types/ossimString.h"
+#include "base/common/ossimCommon.h"
+#include "base/common/ossimErrorStatusInterface.h"
+
+#include <vector>
+
+class OSSIMDLLEXPORT  ossimUsgsQuad
+{
+public:
+   ossimUsgsQuad(const ossimGpt& lrGpt);
+   ossimUsgsQuad(const ossimString& name,
+                 const ossimDatum* datum);
+//                 double paddingInMeters = 100);
+
+   void setQuadName(const ossimString& name);
+   /*!  Returns the bounding rectangle of the quarter quad segment.
+    *   A segment is 1/4 of a quarter quad.
+    *   Segment assingments:  upper_left=A, upper_right=B, lower_left=C,
+    *   lower_right=D   NOTE:  padding is added in.
+    */
+   ossimGrect quarterQuadSegRect(char seg);
+
+   /*!  Returns the bounding rectangle of the quarter quad segment
+    *   in the "area.lat_lon" keyword format:
+    *   start_lat, start_lon, stop_lat, stop_lon
+    *   NOTE:  padding is added in.
+    */
+   ossimString quarterQuadSegKwRect(char seg);
+
+   /*!  Returns the bounding rectangle of the quarter quad (3.75 minutes).  
+    *   NOTE:  padding is added in.
+    */
+   ossimGrect quarterQuadRect() const;
+
+   /*!  Returns the bounding rectangle of the quarter quad (3.75 minutes)  
+    *   in the "area.lat_lon" keyword format:
+    *   start_lat, start_lon, stop_lat, stop_lon
+    *   NOTE:  padding is added in.
+    */
+   ossimString quarterQuadKwRect() const;
+
+   /*!  Returns the bounding rectangle of the quarter quad (7.5 minutes).  
+    *   NOTE:  padding is added in.
+    */
+   ossimGrect quadRect() const;
+
+   /*!  Returns the bounding rectangle of the quarter quad (7.5 minutes)
+    *   in the "area.lat_lon" keyword format:
+    *   start_lat, start_lon, stop_lat, stop_lon
+    *   NOTE:  padding is added in.
+    */
+   ossimString quadKwRect() const;
+
+   /*!
+    * Returns the USGS quarter quad name.
+    */
+   ossimString quarterQuadName() const
+      {
+         return ossimString(theName.begin(),
+                            theName.begin()+7);
+      }
+
+   ossimString quarterQuadSegName() const
+      {
+         return theName;
+      }
+
+   
+   /*!
+    *  Returns the lower right hand corner of quad with no padding.
+    */
+   ossimGpt lrQuadCorner() const { return theQuadLowerRightCorner ; }
+   
+   /*!
+    * Returns the lower right hand corner of quarter quad with no padding.
+    */
+   ossimGpt lrQuarterQuadCorner() const
+      { return theQuarterQuadLowerRightCorner; }
+
+   static void getQuadList(std::vector<ossimUsgsQuad>& result,
+                           const ossimGrect& rect);
+   
+protected:
+   ossimString         theName;
+   ossimGpt            theQuadLowerRightCorner; // Lower right corner of quad.
+   ossimGpt            theQuarterQuadLowerRightCorner;// quarter quad lr corner.
+//   ossimDpt            thePaddingInDegrees;
+   char                theQuarterQuadSegment; // A, B, C, D
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/.cvsignore b/Utilities/OSSIM/ossim_core/base/property/.cvsignore
new file mode 100644
index 0000000000..7d50165874
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/.cvsignore
@@ -0,0 +1,7 @@
+*.~*
+*.o
+Makefile
+core.*
+*.d
+.libs
+*.lo
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimBooleanProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimBooleanProperty.cpp
new file mode 100644
index 0000000000..6492c2a5cb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimBooleanProperty.cpp
@@ -0,0 +1,82 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimBooleanProperty.cpp,v 1.6 2004/01/29 13:29:31 gpotts Exp $
+#include "ossimBooleanProperty.h"
+
+RTTI_DEF1(ossimBooleanProperty, "ossimBooleanProperty", ossimProperty);
+
+ossimBooleanProperty::ossimBooleanProperty(const ossimString& name,
+                                           bool value)
+   :ossimProperty(name),
+    theValue(value)
+{
+}
+
+ossimBooleanProperty::ossimBooleanProperty(const ossimBooleanProperty& rhs)
+   :ossimProperty(rhs),
+    theValue(rhs.theValue)
+{
+}
+
+ossimObject* ossimBooleanProperty::dup()const
+{
+   return new ossimBooleanProperty(*this);
+}
+
+const ossimProperty& ossimBooleanProperty::assign(const ossimProperty& rhs)
+{
+   ossimProperty::assign(rhs);
+
+   ossimBooleanProperty* property = PTR_CAST(ossimBooleanProperty,
+                                             &rhs);
+   if(property)
+   {
+      theValue = property->theValue;
+   }
+   
+   return *this;
+}
+
+bool ossimBooleanProperty::setValue(const ossimString& value)
+{
+   theValue = value.toBool();
+   
+   return true;
+}
+
+bool ossimBooleanProperty::setBooleanValue(bool value,
+					   ossimString& msg)
+{
+   theValue = value;
+
+   return true;
+}
+
+void ossimBooleanProperty::valueToString(ossimString& valueResult)const
+{
+   valueResult = theValue?"1":"0";
+}
+
+bool ossimBooleanProperty::getBoolean()const
+{
+   return theValue;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimBooleanProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimBooleanProperty.h
new file mode 100644
index 0000000000..ae23f2b7eb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimBooleanProperty.h
@@ -0,0 +1,47 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimBooleanProperty.h,v 1.6 2004/05/19 18:29:38 dburken Exp $
+#ifndef ossimBoolenaProperty_HEADER
+#define ossimBoolenaProperty_HEADER
+#include "ossimProperty.h"
+
+class OSSIMDLLEXPORT ossimBooleanProperty : public ossimProperty
+{
+public:
+   ossimBooleanProperty(const ossimString& name=ossimString(""),
+                        bool value = false);
+   ossimBooleanProperty(const ossimBooleanProperty& rhs);
+   virtual ossimObject* dup()const;
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+   virtual bool setValue(const ossimString& value);
+   bool setBooleanValue(bool value,
+			ossimString& msg);
+   void valueToString(ossimString& valueResult)const;
+   bool getBoolean()const;
+   
+protected:
+   bool theValue;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimColorProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimColorProperty.cpp
new file mode 100644
index 0000000000..e8852120cf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimColorProperty.cpp
@@ -0,0 +1,128 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimColorProperty.cpp,v 1.5 2005/05/23 17:52:23 gpotts Exp $
+#include <sstream>
+#include "ossimColorProperty.h"
+
+RTTI_DEF1(ossimColorProperty, "ossimColorProperty", ossimProperty);
+
+ossimColorProperty::ossimColorProperty(const ossimString& name,
+                                       const ossimRgbVector& value)
+   :ossimProperty(name),
+    theValue(value)
+{
+}
+
+ossimColorProperty::ossimColorProperty(const ossimColorProperty& rhs)
+   :ossimProperty(rhs),
+    theValue(rhs.theValue)
+{
+}
+
+ossimColorProperty::~ossimColorProperty()
+{
+}
+
+ossimObject* ossimColorProperty::dup()const
+{
+   return new ossimColorProperty(*this);
+}
+
+const ossimProperty& ossimColorProperty::assign(const ossimProperty& rhs)
+{
+   ossimProperty::assign(rhs);
+
+   ossimColorProperty* rhsPtr = PTR_CAST(ossimColorProperty, &rhs);
+
+   if(rhsPtr)
+   {
+      theValue = rhsPtr->theValue;
+   }
+   else
+   {
+      setValue(rhs.valueToString());
+   }
+
+   return *this;
+}
+
+bool ossimColorProperty::setValue(const ossimString& value)
+{
+   istringstream in(value);
+
+   int r,g,b;
+
+   in >> r >> g >> b;
+
+   theValue = ossimRgbVector(r,g,b);
+   
+   return in.good();
+}
+
+void ossimColorProperty::valueToString(ossimString& valueResult)const
+{
+   ostringstream out;
+
+   out << (int)theValue.getR() << " " << (int)theValue.getG() << " " << (int)theValue.getB() << endl;
+
+   valueResult = out.str().c_str();
+}
+
+const ossimRgbVector& ossimColorProperty::getColor()const
+{
+   return theValue;
+}
+
+void ossimColorProperty::setColor(const ossimRgbVector& value)
+{
+   theValue = value;
+}
+
+ossim_uint8 ossimColorProperty::getRed()const
+{
+   return theValue.getR();
+}
+
+ossim_uint8 ossimColorProperty::getGreen()const
+{
+   return theValue.getG();
+}
+
+ossim_uint8 ossimColorProperty::getBlue()const
+{
+   return theValue.getB();
+}
+
+void ossimColorProperty::setRed(ossim_uint8 r)
+{
+   theValue.setR(r);
+}
+
+void ossimColorProperty::setGreen(ossim_uint8 g)
+{
+   theValue.setG(g);
+}
+
+void ossimColorProperty::setBlue(ossim_uint8 b)
+{
+   theValue.setB(b);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimColorProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimColorProperty.h
new file mode 100644
index 0000000000..57fbc76321
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimColorProperty.h
@@ -0,0 +1,54 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimColorProperty.h,v 1.6 2004/09/22 15:32:24 gpotts Exp $
+#ifndef ossimColorProperty_HEADER
+#define ossimColorProperty_HEADER
+#include <base/property/ossimProperty.h>
+#include <base/common/ossimRtti.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+
+class OSSIMDLLEXPORT ossimColorProperty : public ossimProperty
+{
+public:
+   ossimColorProperty(const ossimString& name=ossimString(""),
+                      const ossimRgbVector& value = ossimRgbVector(0,0,0));
+   ossimColorProperty(const ossimColorProperty& rhs);
+   virtual ~ossimColorProperty();
+   virtual ossimObject* dup()const;
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+   virtual bool setValue(const ossimString& value);
+   virtual void valueToString(ossimString& valueResult)const;
+   const ossimRgbVector& getColor()const;
+   void setColor(const ossimRgbVector& value);
+   ossim_uint8 getRed()const;
+   ossim_uint8 getGreen()const;
+   ossim_uint8 getBlue()const;
+   void setRed(ossim_uint8 r);
+   void setGreen(ossim_uint8 r);
+   void setBlue(ossim_uint8 r);
+protected:
+   ossimRgbVector theValue;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimContainerProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimContainerProperty.cpp
new file mode 100644
index 0000000000..162221f055
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimContainerProperty.cpp
@@ -0,0 +1,172 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimContainerProperty.cpp,v 1.6 2004/09/23 17:18:27 gpotts Exp $
+#include "ossimContainerProperty.h"
+
+RTTI_DEF1(ossimContainerProperty, "ossimContainerProperty", ossimProperty);
+
+ossimContainerProperty::ossimContainerProperty(const ossimString& name)
+   :ossimProperty(name)
+{
+}
+
+ossimContainerProperty::ossimContainerProperty(const ossimContainerProperty& rhs)
+   :ossimProperty(rhs)
+{
+   copyList(rhs);
+}
+
+ossimContainerProperty::~ossimContainerProperty()
+{
+   deleteChildren();
+}
+
+ossimObject* ossimContainerProperty::dup()const
+{
+   return new ossimContainerProperty(*this);
+}
+
+const ossimProperty& ossimContainerProperty::assign(const ossimProperty& rhs)
+{
+   ossimContainerProperty* rhsContainer = PTR_CAST(ossimContainerProperty,
+                                                   &rhs);
+   ossimProperty::assign(rhs);
+
+   if(rhsContainer)
+   {
+      copyList(*rhsContainer);
+   }
+
+   return *this;
+}
+
+void ossimContainerProperty::copyList(const ossimContainerProperty& rhs)
+{
+   deleteChildren();
+
+   for(ossim_uint32 idx = 0; idx < rhs.theChildPropertyList.size();++idx)
+   {
+      if(rhs.theChildPropertyList[idx].valid())
+      {
+         theChildPropertyList.push_back((ossimProperty*)(rhs.theChildPropertyList[idx]->dup()));
+      }
+      else
+      {
+         theChildPropertyList.push_back((ossimProperty*)NULL);
+      }
+   }
+}
+
+void ossimContainerProperty::addChildren(std::vector<ossimRefPtr<ossimProperty> >& propertyList)
+{
+   for(ossim_uint32 idx = 0; idx < propertyList.size(); ++idx)
+   {
+      if(propertyList[idx].valid())
+      {
+         theChildPropertyList.push_back(propertyList[idx]);
+      }
+   }
+}
+
+void ossimContainerProperty::addChild(ossimProperty* property)
+{
+   theChildPropertyList.push_back(property);
+}
+
+ossimRefPtr<ossimProperty> ossimContainerProperty::getProperty(const ossimString& name,
+                                                   bool recurse)
+{
+   ossim_uint32 idx = 0;
+   std::vector<ossimRefPtr<ossimContainerProperty> > containers;
+   
+   for(idx = 0; idx < theChildPropertyList.size(); ++idx)
+   {
+      if(theChildPropertyList[idx].valid())
+      {
+         if(theChildPropertyList[idx]->getName() == name)
+         {
+            return theChildPropertyList[idx];
+         }
+         if(PTR_CAST(ossimContainerProperty, theChildPropertyList[idx].get())&&recurse)
+         {
+            containers.push_back(PTR_CAST(ossimContainerProperty, theChildPropertyList[idx].get()));
+         }
+      }
+   }
+
+   if(containers.size())
+   {
+      for(idx = 0; idx < containers.size();++idx)
+      {
+         ossimRefPtr<ossimProperty> prop = containers[idx]->getProperty(name, recurse);
+         if(prop.valid())
+         {
+            return prop;
+         }
+      }
+   }
+   
+   return (ossimProperty*)NULL;
+}
+
+void ossimContainerProperty::deleteChildren()
+{
+//    for(ossim_uint32 idx = 0; idx < theChildPropertyList.size(); ++idx)
+//    {
+//       if(theChildPropertyList[idx])
+//       {
+//          delete theChildPropertyList[idx];
+//          theChildPropertyList[idx] = (ossimProperty*)NULL;
+//       }
+//    }
+   theChildPropertyList.clear();
+}
+
+
+bool ossimContainerProperty::setValue(const ossimString& value)
+{
+   return false;
+}
+
+void ossimContainerProperty::valueToString(ossimString& valueResult)const
+{
+}
+
+ossim_uint32 ossimContainerProperty::getNumberOfProperties()const
+{
+   return theChildPropertyList.size();
+}
+
+ossimRefPtr<ossimProperty> ossimContainerProperty::getProperty(ossim_uint32 idx)
+{
+   if(idx < theChildPropertyList.size())
+   {
+      return theChildPropertyList[idx];
+   }
+
+   return (ossimProperty*)NULL;
+}
+
+void ossimContainerProperty::getPropertyList(std::vector<ossimRefPtr<ossimProperty> >& children)
+{
+   children = theChildPropertyList;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimContainerProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimContainerProperty.h
new file mode 100644
index 0000000000..8610156bb7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimContainerProperty.h
@@ -0,0 +1,56 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL  see top level LICENSE.txt
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimContainerProperty.h,v 1.7 2004/09/23 17:18:27 gpotts Exp $
+#ifndef ossimContainerProperty_HEADER
+#define ossimContainerProperty_HEADER
+#include <vector>
+#include <base/common/ossimRefPtr.h>
+#include "ossimProperty.h"
+
+class OSSIMDLLEXPORT ossimContainerProperty : public ossimProperty
+{
+public:
+   ossimContainerProperty(const ossimString& name=ossimString(""));
+   ossimContainerProperty(const ossimContainerProperty& rhs);
+   virtual ~ossimContainerProperty();
+   
+   virtual ossimObject* dup()const;
+
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+   /*! 
+    * Note:  the container will own the properties passed in.
+    */
+   virtual void addChildren(std::vector<ossimRefPtr<ossimProperty> >& propertyList);
+
+   /*!
+    * Will add the child to the list and take ownership
+    */
+   virtual void addChild(ossimProperty* propery);
+   
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name,
+                                                  bool recurse=false);
+   virtual void deleteChildren();
+   virtual bool setValue(const ossimString& value);
+   virtual void valueToString(ossimString& valueResult)const;
+
+   virtual ossim_uint32 getNumberOfProperties()const;
+   virtual ossimRefPtr<ossimProperty> getProperty(ossim_uint32 idx);
+
+   virtual void getPropertyList(std::vector<ossimRefPtr<ossimProperty> >& children);
+   
+protected:
+   std::vector<ossimRefPtr<ossimProperty> > theChildPropertyList;
+
+   virtual void copyList(const ossimContainerProperty& rhs);
+
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimDateProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimDateProperty.cpp
new file mode 100644
index 0000000000..016b46ce4d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimDateProperty.cpp
@@ -0,0 +1,142 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level license.txt
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimDateProperty.cpp,v 1.3 2005/10/17 18:37:16 gpotts Exp $
+//
+#include <base/property/ossimDateProperty.h>
+#include <sstream>
+
+RTTI_DEF1(ossimDateProperty, "ossimDateProperty", ossimProperty);
+
+ossimDateProperty::ossimDateProperty()
+      :ossimProperty("")
+{
+   setDate(ossimDate());
+}
+
+ossimDateProperty::ossimDateProperty(const ossimString& name,
+                                     const ossimString& value)
+      :ossimProperty(name)
+{
+   setValue(value);
+}
+
+ossimDateProperty::ossimDateProperty(const ossimString& name,
+                                     const ossimLocalTm& value)
+      :ossimProperty(name),
+       theValue(value)
+{
+}
+
+ossimDateProperty::ossimDateProperty(const ossimDateProperty& src)
+   :ossimProperty(src),
+    theValue(src.theValue)
+{
+}
+
+ossimObject* ossimDateProperty::dup()const
+{
+   return new ossimDateProperty(*this);
+}
+
+void ossimDateProperty::setDate(const ossimLocalTm& localTm)
+{
+   theValue = localTm;
+}
+
+const ossimLocalTm& ossimDateProperty::getDate()const
+{
+   return theValue;
+}
+
+bool ossimDateProperty::setValue(const ossimString& value)
+{
+   if(value.trim() == "")
+   {
+      theValue = ossimDate();
+      return true;
+   }
+   bool result = value.size() == 14;
+   
+   ossimString year;
+   ossimString month;
+   ossimString day;
+   ossimString hour;
+   ossimString min;
+   ossimString sec;
+
+   if(value.size() == 14)
+   {
+      year = ossimString(value.begin(),
+                         value.begin()+4);
+      month = ossimString(value.begin()+4,
+                          value.begin()+6);
+      day = ossimString(value.begin()+6,
+                        value.begin()+8);
+      hour = ossimString(value.begin()+8,
+                        value.begin()+10);
+      min = ossimString(value.begin()+10,
+                        value.begin()+12);
+      sec = ossimString(value.begin()+12,
+                        value.begin()+14);
+
+      theValue.setYear(year.toUInt32());
+      theValue.setMonth(month.toUInt32());
+      theValue.setDay(day.toUInt32());
+      theValue.setHour(hour.toUInt32());
+      theValue.setMin(min.toUInt32());
+      theValue.setSec(sec.toUInt32());
+   }
+
+   return result;
+}
+
+void ossimDateProperty::valueToString(ossimString& valueResult)const
+{
+    std::ostringstream out;
+
+   out << std::setw(4)
+       << std::setfill('0')
+       << theValue.getYear()
+       << std::setw(2)
+       << std::setfill('0')
+       << theValue.getMonth()
+       << std::setw(2)
+       << std::setfill('0')
+       << theValue.getDay()
+       << std::setw(2)
+       << std::setfill('0')
+       << theValue.getHour()
+       << std::setw(2)
+       << std::setfill('0')
+       << theValue.getMin()
+       << std::setw(2)
+       << std::setfill('0')
+       << theValue.getSec();
+   
+   valueResult =  out.str();
+  
+}
+
+const ossimProperty& ossimDateProperty::assign(const ossimProperty& rhs)
+{
+   ossimProperty::assign(rhs);
+
+   ossimDateProperty* rhsPtr = PTR_CAST(ossimDateProperty, &rhs);
+
+   if(rhsPtr)
+   {
+      theValue = rhsPtr->theValue;
+   }
+   else
+   {
+      setValue(rhs.valueToString());
+   }
+
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimDateProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimDateProperty.h
new file mode 100644
index 0000000000..fe1733c5fd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimDateProperty.h
@@ -0,0 +1,29 @@
+#ifndef ossimDateProperty_HEADER
+#define ossimDateProperty_HEADER
+#include "ossimProperty.h"
+#include <base/common/ossimDate.h>
+
+class OSSIM_DLL ossimDateProperty : public ossimProperty
+{
+public:
+   ossimDateProperty();
+   ossimDateProperty(const ossimString& name,
+                     const ossimString& value);
+   ossimDateProperty(const ossimString& name,
+                     const ossimLocalTm& value);
+   ossimDateProperty(const ossimDateProperty& src);
+   virtual ossimObject* dup()const;
+   
+   void setDate(const ossimLocalTm& localTm);
+   const ossimLocalTm& getDate()const;
+   virtual bool setValue(const ossimString& value);
+   virtual void valueToString(ossimString& valueResult)const;
+   virtual const ossimProperty& ossimDateProperty::assign(const ossimProperty& rhs);
+   
+protected:
+   ossimLocalTm theValue;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimDoubleGridProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimDoubleGridProperty.cpp
new file mode 100644
index 0000000000..dc8801d6c3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimDoubleGridProperty.cpp
@@ -0,0 +1,159 @@
+#include <sstream>
+#include "ossimDoubleGridProperty.h"
+
+RTTI_DEF1(ossimDoubleGridProperty, "ossimDoubleGridProperty", ossimProperty);
+
+ossimDoubleGridProperty::ossimDoubleGridProperty(const ossimString& name,
+						 int numberOfRows,
+						 int numberOfCols,
+						 const std::vector<double>& values)
+  :ossimProperty(name),
+   theMinNumberOfCols(-1),
+   theMaxNumberOfCols(-1),
+   theMinNumberOfRows(-1),
+   theMaxNumberOfRows(-1)
+{
+
+}
+
+ossimDoubleGridProperty::ossimDoubleGridProperty(const ossimDoubleGridProperty& rhs)
+  :ossimProperty(rhs),
+  theMinNumberOfCols(rhs.theMinNumberOfCols),
+  theMaxNumberOfCols(rhs.theMaxNumberOfCols),
+  theMinNumberOfRows(rhs.theMinNumberOfRows),
+  theMaxNumberOfRows(rhs.theMaxNumberOfRows),
+  theValues(rhs.theValues)
+{
+}
+
+ossimDoubleGridProperty::~ossimDoubleGridProperty()
+{
+}
+
+ossimObject* ossimDoubleGridProperty::dup()const
+{
+  return new ossimDoubleGridProperty(*this);
+}
+
+const ossimProperty& ossimDoubleGridProperty::assign(const ossimProperty& rhs)
+{
+  ossimProperty::assign(rhs);
+  ossimDoubleGridProperty* rhsPtr = PTR_CAST(ossimDoubleGridProperty, &rhs);
+
+  if(rhsPtr)
+    {
+      theMinNumberOfCols = rhsPtr->theMinNumberOfCols;
+      theMaxNumberOfCols = rhsPtr->theMaxNumberOfCols;
+      theMinNumberOfRows = rhsPtr->theMinNumberOfRows;
+      theMaxNumberOfRows = rhsPtr->theMaxNumberOfRows;
+      theValues          = rhsPtr->theValues;
+    }
+  else
+    {
+      setValue(rhs.valueToString());
+      
+    }
+  
+  return *this;
+}
+
+  
+bool ossimDoubleGridProperty::setValue(const ossimString& value)
+{
+  std::istringstream in(value.c_str());
+
+  int numberOfRows;
+  int numberOfCols;
+  int rowIdx = 0;
+  int colIdx = 0;
+  in >> numberOfRows >> numberOfCols;
+  
+  theValues.resize(numberOfRows);
+
+  for(rowIdx = 0; rowIdx < numberOfRows; ++rowIdx)
+    {
+      theValues[rowIdx].resize(numberOfCols);
+      for(colIdx = 0; colIdx < numberOfCols; ++ colIdx)
+	{
+	  in >> theValues[rowIdx][colIdx];
+	}
+    }
+
+  return true;
+}
+
+void ossimDoubleGridProperty::valueToString(ossimString& valueResult)const
+{
+  std::ostringstream out;
+  int rowIdx = 0;
+  int colIdx = 0;
+  out << getNumberOfRows() << " " << getNumberOfCols() << " ";
+
+  for(rowIdx = 0; rowIdx < (int)getNumberOfRows(); ++rowIdx)
+    {
+      for(colIdx = 0; colIdx < (int)getNumberOfCols(); ++colIdx)
+	{
+	  out << ossimString::toString(getValue(rowIdx, colIdx)) << " ";
+	}
+    }
+  valueResult = out.str();
+}
+
+void ossimDoubleGridProperty::clearConstraints()
+{
+  theMinNumberOfCols = -1;
+  theMaxNumberOfCols = -1;
+  theMinNumberOfRows = -1;
+  theMaxNumberOfRows = -1;
+}
+
+void ossimDoubleGridProperty::setColConstraints(int minNumberOfCols,
+		  int maxNumberOfCols)
+{
+  theMinNumberOfCols = minNumberOfCols;
+  theMaxNumberOfCols = maxNumberOfCols;
+}
+
+void ossimDoubleGridProperty::setRowConstraints(int minNumberOfRows,
+						int maxNumberOfRows)
+{
+  theMinNumberOfRows = minNumberOfRows;
+  theMaxNumberOfRows = maxNumberOfRows;
+}
+
+void ossimDoubleGridProperty::setContraints(int minNumberOfRows,
+					    int maxNumberOfRows,
+					    int minNumberOfCols,
+					    int maxNumberOfCols)
+{
+  theMinNumberOfRows = minNumberOfRows;
+  theMaxNumberOfRows = maxNumberOfRows;
+  theMinNumberOfCols = minNumberOfCols;
+  theMaxNumberOfCols = maxNumberOfCols;
+}
+
+ossim_uint32 ossimDoubleGridProperty::getNumberOfRows()const
+{
+  return ((int)theValues.size());
+}
+
+ossim_uint32 ossimDoubleGridProperty::getNumberOfCols()const
+{
+  if(getNumberOfRows())
+    {
+      return theValues[0].size();
+    }
+  return 0;
+}
+
+double ossimDoubleGridProperty::getValue(ossim_uint32 row, 
+					 ossim_uint32 col)const
+{
+  if((row < getNumberOfRows())&&
+     (col < getNumberOfCols()))
+    {
+      return theValues[(int)row][(int)col];
+    }
+
+  return 0.0;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimDoubleGridProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimDoubleGridProperty.h
new file mode 100644
index 0000000000..460987cee9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimDoubleGridProperty.h
@@ -0,0 +1,79 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimDoubleGridProperty.h,v 1.4 2004/05/19 18:29:38 dburken Exp $
+#ifndef ossimDoubleGridProperty_HEADER
+#define ossimDoubleGridProperty_HEADER
+#include "ossimProperty.h"
+
+class OSSIMDLLEXPORT ossimDoubleGridProperty : public ossimProperty
+{
+public:
+  ossimDoubleGridProperty(const ossimString& name = ossimString(""),
+			  int numberOfRows = 0,
+			  int numberOfCols = 0,
+			  const std::vector<double>& values = std::vector<double>());
+  ossimDoubleGridProperty(const ossimDoubleGridProperty& rhs);
+  
+  virtual ~ossimDoubleGridProperty();
+
+  ossimObject* dup()const;
+
+  virtual const ossimProperty& assign(const ossimProperty& rhs);
+
+  virtual bool setValue(const ossimString& value);
+  virtual void valueToString(ossimString& valueResult)const;
+
+  void clearConstraints();
+  /*!
+   * Setting both values to -1 will say no constraints.
+   * if min is constrained and max not then it will not allow
+   * the cols to grow any larger than the passed in max.
+   *
+   * If the min is -1 and max not then it will not exceed the 
+   * max number of cols
+   */
+  void setColConstraints(int minNumberOfCols,
+			 int maxNumberOfCols);
+
+  void setRowConstraints(int minNumberOfRows,
+			 int maxNumberOfRows);
+  
+  void setContraints(int minNumberOfRows,
+		     int maxNumberOfRows,
+		     int minNumberOfCols,
+		     int maxNumberOfCols);
+
+  ossim_uint32 getNumberOfRows()const;
+  ossim_uint32 getNumberOfCols()const;
+
+  double getValue(ossim_uint32 row, ossim_uint32 col)const;
+protected:
+  int theMinNumberOfCols;
+  int theMaxNumberOfCols;
+  int theMinNumberOfRows;
+  int theMaxNumberOfRows;
+  std::vector< std::vector<double> > theValues;
+    
+
+TYPE_DATA
+};
+#endif 
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimFilenameProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimFilenameProperty.cpp
new file mode 100644
index 0000000000..2a28ef0a74
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimFilenameProperty.cpp
@@ -0,0 +1,168 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimFilenameProperty.cpp,v 1.5 2004/01/29 13:29:31 gpotts Exp $
+#include "ossimFilenameProperty.h"
+
+RTTI_DEF1(ossimFilenameProperty, "ossimFilenameProperty", ossimProperty);
+
+ossimFilenameProperty::ossimFilenameProperty(const ossimString& name,
+                                             const ossimFilename& value,
+                                             const std::vector<ossimString>& filterList)
+   :ossimProperty(name),
+    theValue(value),
+    theFilterList(filterList),
+    theIoType(ossimFilenamePropertyIoType_NOT_SPECIFIED)
+{
+}
+
+ossimFilenameProperty::ossimFilenameProperty(const ossimFilenameProperty& rhs)
+   :ossimProperty(rhs),
+    theValue(rhs.theValue),
+    theFilterList(rhs.theFilterList),
+    theIoType(rhs.theIoType)
+{
+}
+
+ossimFilenameProperty::~ossimFilenameProperty()
+{
+}
+
+ossimObject* ossimFilenameProperty::dup()const
+{
+   return new ossimFilenameProperty(*this);
+}
+
+void ossimFilenameProperty::valueToString(ossimString& valueResult)const
+{
+   valueResult = theValue;
+}
+
+bool ossimFilenameProperty::setValue(const ossimString& value)
+{
+   theValue = value;
+
+   return true;
+}
+
+const ossimFilenameProperty& ossimFilenameProperty::operator = (ossimFilenameProperty& rhs)
+{
+   assign(rhs);
+
+   return *this;
+}
+
+const ossimProperty& ossimFilenameProperty::assign(const ossimProperty& rhs)
+{
+   ossimProperty::assign(rhs);
+   theValue = rhs.valueToString();
+
+   ossimFilenameProperty* rhsPtr = PTR_CAST(ossimFilenameProperty,
+                                            &rhs);
+
+   if(rhsPtr)
+   {
+      theFilterList = rhsPtr->theFilterList;
+      theIoType     = rhsPtr->theIoType;
+   }
+
+   return *this;
+}
+
+void ossimFilenameProperty::clearFilterList()
+{
+   theFilterList.clear();
+}
+
+ossim_uint32 ossimFilenameProperty::getNumberOfFilters()const
+{
+   return theFilterList.size();
+}
+
+void ossimFilenameProperty::setFilter(ossim_uint32 idx,
+                                      const ossimString& filterValue)
+{
+   if(idx < getNumberOfFilters())
+   {
+      theFilterList[idx] = filterValue;
+   }
+}
+
+ossimString ossimFilenameProperty::getFilter(ossim_uint32 idx)const
+{
+   if(idx < getNumberOfFilters())
+   {
+      return theFilterList[idx];
+   }
+
+   return ossimString("");
+}
+
+
+ossimString ossimFilenameProperty::getFilterListAsString(const ossimString& separator)const
+{
+   ossimString result;
+   ossim_uint32 idx = 0;
+
+   if(getNumberOfFilters() > 0)
+   {
+      for(idx = 0; idx < getNumberOfFilters()-1;++idx)
+      {
+         result += getFilter(idx);
+         result += separator;
+      }
+      result += getFilter(getNumberOfFilters()-1);
+   }
+
+   return result;
+}
+
+
+const std::vector<ossimString>& ossimFilenameProperty::getFilterList()const
+{
+   return theFilterList;
+}
+
+void ossimFilenameProperty::addFilter(const ossimString& filter)
+{
+   theFilterList.push_back(filter);
+}
+
+
+void ossimFilenameProperty::setIoType(ossimFilenamePropertyIoType ioType)
+{
+   theIoType = ioType;
+}
+
+ossimFilenameProperty::ossimFilenamePropertyIoType ossimFilenameProperty::getIoType()const
+{
+   return theIoType;
+}
+
+bool ossimFilenameProperty::isIoTypeInput()const
+{
+   return (theIoType==ossimFilenamePropertyIoType_INPUT);
+}
+
+bool ossimFilenameProperty::isIoTypeOutput()const
+{
+   return (theIoType==ossimFilenamePropertyIoType_OUTPUT);
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimFilenameProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimFilenameProperty.h
new file mode 100644
index 0000000000..225d187c37
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimFilenameProperty.h
@@ -0,0 +1,75 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimFilenameProperty.h,v 1.5 2004/05/19 18:29:38 dburken Exp $
+#ifndef ossimFilenameProperty_HEADER
+#define ossimFilenameProperty_HEADER
+#include <vector>
+#include "ossimProperty.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimString.h"
+
+class OSSIMDLLEXPORT ossimFilenameProperty : public ossimProperty
+{
+public:
+
+   enum ossimFilenamePropertyIoType
+   {
+      ossimFilenamePropertyIoType_NOT_SPECIFIED = 0,
+      ossimFilenamePropertyIoType_INPUT         = 1,
+      ossimFilenamePropertyIoType_OUTPUT        = 2
+   };
+   
+   ossimFilenameProperty(const ossimString& name = ossimString(""),
+                         const ossimFilename& value = ossimFilename(""),
+                         const std::vector<ossimString>& filterList = std::vector<ossimString>());
+
+   ossimFilenameProperty(const ossimFilenameProperty& rhs);
+   virtual ~ossimFilenameProperty();
+   ossimObject* dup()const;
+   virtual void valueToString(ossimString& valueResult)const;
+  virtual bool setValue(const ossimString& value);
+   const ossimFilenameProperty& operator = (ossimFilenameProperty& rhs);
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+
+   void clearFilterList();
+   ossim_uint32 getNumberOfFilters()const;
+   void setFilter(ossim_uint32 idx,
+                  const ossimString& filterValue);
+   ossimString getFilter(ossim_uint32 idx)const;
+   ossimString getFilterListAsString(const ossimString& separator=ossimString("\n"))const;
+   const std::vector<ossimString>& getFilterList()const;
+   void addFilter(const ossimString& filter);
+
+   void setIoType(ossimFilenamePropertyIoType ioType);
+   ossimFilenamePropertyIoType getIoType()const;
+   bool isIoTypeInput()const;
+   bool isIoTypeOutput()const;
+   
+protected:
+   ossimFilename            theValue;
+   std::vector<ossimString> theFilterList;
+   ossimFilenamePropertyIoType theIoType;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimFontProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimFontProperty.cpp
new file mode 100644
index 0000000000..7fdb47c07a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimFontProperty.cpp
@@ -0,0 +1,103 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimFontProperty.cpp,v 1.4 2004/01/29 13:29:31 gpotts Exp $
+#include <sstream>
+#include "ossimFontProperty.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+
+RTTI_DEF1(ossimFontProperty, "ossimFontProperty", ossimProperty);
+
+ossimFontProperty::ossimFontProperty(const ossimString& name,
+                                     const ossimFontInformation& value)
+   :ossimProperty(name),
+    theValue(value)
+{
+   
+}
+
+ossimFontProperty::ossimFontProperty(const ossimFontProperty& rhs)
+   :ossimProperty(rhs),
+    theValue(rhs.theValue)
+{
+}
+
+ossimFontProperty::~ossimFontProperty()
+{
+}
+
+ossimObject* ossimFontProperty::dup()const
+{
+   return new ossimFontProperty(*this);
+}
+
+const ossimProperty& ossimFontProperty::assign(const ossimProperty& rhs)
+{
+   ossimProperty::assign(rhs);
+
+   ossimFontProperty* rhsPtr = PTR_CAST(ossimFontProperty,
+                                        &rhs);
+
+   if(rhsPtr)
+   {
+      theValue = rhsPtr->theValue;
+   }
+   
+   return *this;
+}
+
+bool ossimFontProperty::setValue(const ossimString& value)
+{
+   bool result = true;
+   ossimKeywordlist kwl;
+
+   istringstream in(value);
+
+   result = kwl.parseStream(in);
+   if(result)
+   {
+      theValue.loadState(kwl);
+   }
+
+   return result;
+}
+
+void ossimFontProperty::valueToString(ossimString& valueResult)const
+{
+   ostringstream out;
+   ossimKeywordlist kwl;
+
+   theValue.saveState(kwl);
+   
+   kwl.writeToStream(out);
+   valueResult = kwl.toString();
+}
+
+void ossimFontProperty::setFontInformation(ossimFontInformation& fontInfo)
+{
+   theValue = fontInfo;
+}
+
+const ossimFontInformation& ossimFontProperty::getFontInformation()const
+{
+   return theValue;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimFontProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimFontProperty.h
new file mode 100644
index 0000000000..38552de3c9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimFontProperty.h
@@ -0,0 +1,48 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimFontProperty.h,v 1.4 2004/01/29 13:29:31 gpotts Exp $
+#ifndef ossimFontProperty_HEADER
+#define ossimFontProperty_HEADER
+#include "ossimProperty.h"
+#include "base/common/ossimFontInformation.h"
+
+class OSSIMDLLEXPORT ossimFontProperty : public ossimProperty
+{
+public:
+   ossimFontProperty(const ossimString& name,
+                     const ossimFontInformation& value);
+   ossimFontProperty(const ossimFontProperty& rhs);
+   virtual ~ossimFontProperty();
+   virtual ossimObject* dup()const;
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+  virtual bool setValue(const ossimString& value);
+   virtual void valueToString(ossimString& valueResult)const;
+
+   void setFontInformation(ossimFontInformation& fontInfo);
+   const ossimFontInformation& getFontInformation()const;
+protected:
+   ossimFontInformation theValue;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimMatrixProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimMatrixProperty.cpp
new file mode 100644
index 0000000000..a065a976c2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimMatrixProperty.cpp
@@ -0,0 +1,331 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimMatrixProperty.cpp,v 1.7 2005/10/17 18:37:16 gpotts Exp $
+#include <sstream>
+#include "ossimMatrixProperty.h"
+#include "base/common/ossimCommon.h"
+
+RTTI_DEF1(ossimMatrixProperty, "ossimMatrixProperty", ossimProperty);
+
+ossimMatrixProperty::ossimMatrixProperty(const ossimString& name,
+                                         const std::vector<double>& values,
+                                         int numberOfRows,
+                                         int numberOfCols)
+   :ossimProperty(name),
+    theMinNumberOfCols(-1),
+    theMaxNumberOfCols(-1),
+    theMinNumberOfRows(-1),
+    theMaxNumberOfRows(-1)
+{
+   resize(numberOfRows, numberOfCols);
+
+   if((int)values.size() == numberOfRows*numberOfCols)
+   {
+      int rowIdx = 0;
+      int colIdx = 0;
+      int linearIdx = 0;
+      for(rowIdx = 0; rowIdx < getNumberOfRows(); ++rowIdx)
+      {
+         for(colIdx = 0; colIdx < getNumberOfCols(); ++colIdx)
+         {
+            theValueArray[rowIdx][colIdx] = values[linearIdx];
+            ++linearIdx;
+         }
+      }
+   }
+}
+
+
+ossimMatrixProperty::ossimMatrixProperty(const ossimMatrixProperty& rhs)
+   :ossimProperty(rhs),
+    theValueArray(rhs.theValueArray),
+    theMinNumberOfCols(rhs.theMinNumberOfCols),
+    theMaxNumberOfCols(rhs.theMaxNumberOfCols),
+    theMinNumberOfRows(rhs.theMaxNumberOfCols),
+    theMaxNumberOfRows(rhs.theMaxNumberOfRows)
+{
+}
+
+ossimMatrixProperty::~ossimMatrixProperty()
+{
+   
+}
+
+ossimObject* ossimMatrixProperty::dup()const
+{
+   return new ossimMatrixProperty(*this);
+}
+
+
+const ossimProperty& ossimMatrixProperty::assign(const ossimProperty& rhs)
+{
+   ossimMatrixProperty* rhsPtr = PTR_CAST(ossimMatrixProperty,
+                                          &rhs);
+   if(rhsPtr)
+   {
+      theValueArray      = rhsPtr->theValueArray;
+      theMinNumberOfCols = rhsPtr->theMinNumberOfCols;
+      theMaxNumberOfCols = rhsPtr->theMaxNumberOfCols;
+      theMinNumberOfRows = rhsPtr->theMinNumberOfRows;
+      theMaxNumberOfRows = rhsPtr->theMaxNumberOfRows;
+   }
+
+   return ossimProperty::assign(rhs);
+}
+
+bool ossimMatrixProperty::setValue(const ossimString& value)
+{
+   std::istringstream in(value);
+   
+   int numberOfRows;
+   int numberOfCols;
+   double tempValue;
+   
+   in>>numberOfRows >> numberOfCols;
+
+   if(!in.bad())
+   {
+      resize(numberOfRows, numberOfCols);
+
+      int rowIdx = 0;
+      int colIdx = 0;
+      for(rowIdx = 0; ((rowIdx < getNumberOfRows())&&(!in.bad())); ++rowIdx)
+      {
+         for(colIdx = 0; ((colIdx < getNumberOfCols())&&(!in.bad()));++ colIdx)
+         {
+            in >> tempValue;
+            
+            theValueArray[rowIdx][colIdx] = tempValue;
+         }
+      }
+   }
+
+   return !in.bad();
+}
+
+void ossimMatrixProperty::valueToString(ossimString& valueResult)const
+{
+   if(theValueArray.size()>0)
+   {
+      if(theValueArray[0].size() > 0)
+      {
+         valueResult = "";
+         
+         int rowIdx = 0;
+         int colIdx = 0;
+         valueResult += ossimString::toString(getNumberOfRows()) + " " +
+                        ossimString::toString(getNumberOfCols()) + " ";
+         for(rowIdx = 0; rowIdx < getNumberOfRows();++rowIdx)
+         {
+            for(colIdx = 0; colIdx < getNumberOfCols(); ++colIdx)
+            {
+               valueResult += ossimString::toString(theValueArray[rowIdx][colIdx]);
+               valueResult += " ";
+            }
+         }
+      }
+   }
+}
+
+void ossimMatrixProperty::resize(int numberOfRows,
+                                 int numberOfCols)
+{
+   int tempNumberOfRows = numberOfRows;
+   int tempNumberOfCols = numberOfCols;
+
+   if(theMinNumberOfCols > 0)
+   {
+      if(tempNumberOfCols < theMinNumberOfCols)
+      {
+         tempNumberOfCols = theMinNumberOfCols;
+      }
+   }
+   if(theMinNumberOfRows > 0)
+   {
+      if(tempNumberOfRows < theMinNumberOfRows)
+      {
+         tempNumberOfRows = theMinNumberOfRows;
+      }
+   }
+   if(theMaxNumberOfCols > 0)
+   {
+      if(tempNumberOfCols > theMaxNumberOfCols)
+      {
+         tempNumberOfCols = theMaxNumberOfCols;
+      }
+   }
+   if(theMaxNumberOfRows > 0)
+   {
+      if(tempNumberOfRows > theMaxNumberOfRows)
+      {
+         tempNumberOfRows = theMaxNumberOfRows;
+      }
+   }
+
+   int currentNumberOfRows = getNumberOfRows();
+   int currentNumberOfCols = getNumberOfCols();
+   
+   if((currentNumberOfRows != tempNumberOfRows) ||
+      (currentNumberOfCols != tempNumberOfCols))
+   {
+      std::vector< std::vector<double> > tempValue = theValueArray;
+      
+      theValueArray.resize(tempNumberOfRows);
+
+      int minCols = ossimMin((int)currentNumberOfCols,
+                             (int)tempNumberOfCols);
+      int rowIdx = 0;
+      int colIdx = 0;
+      
+      for(rowIdx = 0 ; rowIdx < tempNumberOfRows; ++rowIdx)
+      {
+         theValueArray[rowIdx].resize(tempNumberOfCols);
+         std::fill(theValueArray[rowIdx].begin(), theValueArray[rowIdx].end(), 0);
+
+         if(tempNumberOfRows < currentNumberOfRows)
+         {
+            for(colIdx = 0 ; colIdx < minCols; ++colIdx)
+            {
+               theValueArray[rowIdx][colIdx] = tempValue[rowIdx][colIdx];
+            }
+         }
+      }
+   }
+}
+
+double& ossimMatrixProperty::operator()(int rowIdx,
+                                        int colIdx)
+{
+   return theValueArray[rowIdx][colIdx];
+}
+
+const double& ossimMatrixProperty::operator()(int rowIdx,
+                                              int colIdx)const
+{
+   return theValueArray[rowIdx][colIdx];
+}
+
+int ossimMatrixProperty::getNumberOfRows()const
+{
+   return (int)theValueArray.size();
+}
+
+int ossimMatrixProperty::getNumberOfCols()const
+{
+   if(getNumberOfRows())
+   {
+      return theValueArray[0].size();
+   }
+
+   return 0;
+}
+
+void ossimMatrixProperty::clearConstraints()
+{
+   theMinNumberOfCols = -1;
+   theMaxNumberOfCols = -1;
+   theMinNumberOfRows = -1;
+   theMaxNumberOfRows = -1;
+}
+
+void ossimMatrixProperty::setColContraints(int minNumberOfCols,
+                                           int maxNumberOfCols)
+{
+   theMinNumberOfCols = minNumberOfCols;
+   theMaxNumberOfCols = theMaxNumberOfCols;
+}
+
+void ossimMatrixProperty::setRowContraints(int minNumberOfRows,
+                                          int maxNumberOfRows)
+{
+   theMinNumberOfRows = minNumberOfRows;
+   theMaxNumberOfRows = theMaxNumberOfRows;
+}
+
+void ossimMatrixProperty::getColContraints(int& minNumberOfCols,
+                                           int& maxNumberOfCols)
+{
+   minNumberOfCols = theMinNumberOfCols;
+   maxNumberOfCols = theMaxNumberOfCols;
+}
+
+void ossimMatrixProperty::getRowContraints(int& minNumberOfRows,
+                                           int& maxNumberOfRows)
+{
+   minNumberOfRows = theMinNumberOfRows;
+   maxNumberOfRows = theMaxNumberOfRows;
+}
+
+void ossimMatrixProperty::normalize()
+{
+   double densityValue = density();
+
+   if(fabs(densityValue) <= DBL_EPSILON)
+   {
+      return;
+   }
+   int rowIdx = 0;
+   int colIdx = 0;
+   for(rowIdx = 0 ; rowIdx < (int)theValueArray.size(); ++rowIdx)
+   {
+      for(colIdx = 0 ; colIdx < (int)theValueArray[rowIdx].size(); ++colIdx)
+      {
+         theValueArray[rowIdx][colIdx]/=densityValue;
+      }
+   }
+   
+}
+
+void ossimMatrixProperty::zero()
+{
+   int rowIdx = 0;
+   int colIdx = 0;
+   for(rowIdx = 0 ; rowIdx < (int)theValueArray.size(); ++rowIdx)
+   {
+      for(colIdx = 0 ; colIdx < (int)theValueArray[rowIdx].size(); ++colIdx)
+      {
+         theValueArray[rowIdx][colIdx] = 0.0;
+      }
+   }
+}
+
+double ossimMatrixProperty::density()const
+{
+   double result = 0.0;
+
+   if((getNumberOfRows() > 0)&&
+      (getNumberOfCols() > 0))
+   {
+      int rowIdx = 0;
+      int colIdx = 0;
+      
+      for(rowIdx = 0 ; rowIdx < (int)theValueArray.size(); ++rowIdx)
+      {
+         for(colIdx = 0 ; colIdx < (int)theValueArray[rowIdx].size(); ++colIdx)
+         {
+            result += theValueArray[rowIdx][colIdx];
+         }
+      }
+   }
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimMatrixProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimMatrixProperty.h
new file mode 100644
index 0000000000..916005a568
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimMatrixProperty.h
@@ -0,0 +1,96 @@
+#ifndef ossimMatrixProperty_HEADER
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimMatrixProperty.h,v 1.6 2004/05/19 18:29:38 dburken Exp $
+#define ossimMatrixProperty_HEADER
+#include <vector>
+#include "ossimProperty.h"
+
+
+class OSSIMDLLEXPORT ossimMatrixProperty : public ossimProperty
+{
+public:
+   ossimMatrixProperty(const ossimString& name=ossimString(""),
+                       const std::vector<double>& values = std::vector<double>(),
+                       int numberOfRows    = 0,
+                       int numberOfColumns = 0);
+   ossimMatrixProperty(const ossimMatrixProperty& rhs);
+
+   virtual ~ossimMatrixProperty();
+
+   virtual ossimObject* dup()const;
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+  virtual bool setValue(const ossimString& value);
+   virtual void valueToString(ossimString& valueResult)const;
+   
+   void resize(int numberOfRows,
+               int numberOfColumns);
+
+   double& operator ()(int rowIdx,
+                       int colIdx);
+   
+   const double& operator()(int rowIdx,
+                            int colIdx)const;
+
+   int getNumberOfRows()const;
+   int getNumberOfCols()const;
+
+   void clearConstraints();
+   
+   /*!
+    * If any of the contraints are set to something < 0 then it means there
+    * isn't a constraint for that value.  So if you give a min value of -1
+    * and a max value of 10 then the column can grow from 10 downto 0.
+    */
+   void setColContraints(int minNumberOfColumns,
+                         int maxNumberOfColumns);
+
+   /*!
+    * If any of the contraints are set to something < 0 then it means there
+    * isn't a constraint for that value.  So if you give a min value of -1
+    * and a max value of 10 then the row can grow from 10 downto 0.
+    */
+   void setRowContraints(int minNumberOfRows,
+                         int maxNumberOfRows);
+
+   void getColContraints(int& minNumberOfColumns,
+                         int& maxNumberOfColumns);
+   
+   void getRowContraints(int& minNumberOfRows,
+                         int& maxNumberOfRows);
+
+
+   void normalize();
+   void zero();
+   
+protected:
+   std::vector< std::vector<double> > theValueArray;
+   int theMinNumberOfCols;
+   int theMaxNumberOfCols;
+   int theMinNumberOfRows;
+   int theMaxNumberOfRows;
+
+   double density()const;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimNumericProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimNumericProperty.cpp
new file mode 100644
index 0000000000..af9be4f2d4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimNumericProperty.cpp
@@ -0,0 +1,224 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimNumericProperty.cpp,v 1.5 2004/01/29 13:29:31 gpotts Exp $
+#include <algorithm>
+#include "ossimNumericProperty.h"
+
+
+RTTI_DEF1(ossimNumericProperty, "ossimNumericProperty", ossimProperty);
+
+ossimNumericProperty::ossimNumericProperty(const ossimString& name,
+                                           const ossimString& value)
+   :ossimProperty(name),
+    theValue(value),
+    theType(ossimNumericPropertyType_FLOAT64)
+{
+}
+
+ossimNumericProperty::ossimNumericProperty(const ossimString& name,
+                                           const ossimString& value,
+                                           double minValue,
+                                           double maxValue)
+   :ossimProperty(name),
+    theValue(value),
+    theType(ossimNumericPropertyType_FLOAT64)
+{
+   setConstraints(minValue,
+                  maxValue);
+}
+
+ossimNumericProperty::ossimNumericProperty(const ossimNumericProperty& rhs)
+   :ossimProperty(rhs),
+    theValue(rhs.theValue),
+    theType(rhs.theType),
+    theRangeConstraint(rhs.theRangeConstraint)
+{
+}
+
+ossimObject* ossimNumericProperty::dup()const
+{
+   return new ossimNumericProperty(*this);
+}
+
+const ossimProperty& ossimNumericProperty::assign(const ossimProperty& rhs)
+{
+   ossimProperty::assign(rhs);
+
+   ossimNumericProperty* numericProperty = PTR_CAST(ossimNumericProperty,
+                                                   &rhs);
+   if(numericProperty)
+   {
+      theValue           = numericProperty->theValue;
+      theType            = numericProperty->theType;
+      theRangeConstraint = numericProperty->theRangeConstraint;
+   }
+   else
+   {
+      ossimString value;
+      rhs.valueToString(value);
+      setValue(value);
+   }
+   return *this;
+}
+
+bool ossimNumericProperty::hasConstraints()const
+{
+   return (theRangeConstraint.size() == 2);
+}
+
+double ossimNumericProperty::getMinValue()const
+{
+   if(hasConstraints())
+   {
+      return theRangeConstraint[0];
+   }
+
+   return 0.0;
+}
+
+double ossimNumericProperty::getMaxValue()const
+{
+   if(hasConstraints())
+   {
+      return theRangeConstraint[1];
+   }
+
+   return 0.0;
+}
+
+void ossimNumericProperty::clearConstraints()
+{
+   theRangeConstraint.clear();
+}
+
+void ossimNumericProperty::setConstraints(double minValue,
+                                          double maxValue)
+{
+   theRangeConstraint.resize(2);
+   theRangeConstraint[0] = minValue;
+   theRangeConstraint[1] = maxValue;
+
+   if(minValue > maxValue)
+   {
+      std::swap(theRangeConstraint[0],
+                theRangeConstraint[1]);
+   }
+}
+
+bool ossimNumericProperty::setValue(const ossimString& value)
+{
+   bool result = true;
+   if(hasConstraints())
+   {
+      ossim_float64 tempV = (ossim_float64)value.toDouble();
+      if((tempV >= theRangeConstraint[0])&&
+         (tempV <= theRangeConstraint[1]))
+      {
+         theValue = value;
+      }
+   }
+   else
+   {
+     theValue = value;
+   }
+
+   return result;
+}
+
+void ossimNumericProperty::valueToString(ossimString& valueResult)const
+{
+   switch(theType)
+   {
+   case ossimNumericPropertyType_INT:
+   {
+      valueResult = ossimString::toString(asInt32());
+      break;
+   }
+   case ossimNumericPropertyType_UINT:
+   {
+      valueResult = ossimString::toString(asUInt32());
+      break;
+   }
+   case ossimNumericPropertyType_FLOAT32:
+   {
+      valueResult = ossimString::toString(asFloat32());
+      
+      break;
+   }
+   case ossimNumericPropertyType_FLOAT64:
+   {
+      valueResult = ossimString::toString(asFloat64());
+      break;
+   }
+   };
+}
+
+
+ossimNumericProperty::ossimNumericPropertyType ossimNumericProperty::getNumericType()const
+{
+   return theType;
+}
+
+void ossimNumericProperty::setNumericType(ossimNumericPropertyType type)
+{
+   theType = type;
+}
+
+ossim_float64 ossimNumericProperty::asFloat64()const
+{
+   return (ossim_float64)theValue.toDouble();
+}
+
+ossim_float32 ossimNumericProperty::asFloat32()const
+{
+   return (ossim_float32)theValue.toDouble();
+}
+
+ossim_uint32  ossimNumericProperty::asUInt32()const
+{
+   return theValue.toUInt32();
+}
+
+ossim_uint16 ossimNumericProperty::asUInt16()const
+{
+   return (ossim_uint16)theValue.toUInt32();
+}
+
+ossim_uint8 ossimNumericProperty::asUInt8()const
+{
+   return (ossim_uint8)theValue.toUInt32();
+}
+
+ossim_sint32 ossimNumericProperty::asInt32()const
+{
+   return (ossim_int32)theValue.toInt32();
+}
+
+ossim_sint16 ossimNumericProperty::asInt16()const
+{
+   return (ossim_int16)theValue.toInt32();
+}
+
+ossim_sint8 ossimNumericProperty::asInt8()const
+{
+   return (ossim_int8)theValue.toInt32();
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimNumericProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimNumericProperty.h
new file mode 100644
index 0000000000..a005a4af3c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimNumericProperty.h
@@ -0,0 +1,78 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimNumericProperty.h,v 1.7 2004/05/19 18:29:38 dburken Exp $
+#ifndef ossimNumericProperty_HEADER
+#define ossimNumericProperty_HEADER
+#include "ossimProperty.h"
+
+class OSSIMDLLEXPORT ossimNumericProperty : public ossimProperty
+{
+public:
+   enum ossimNumericPropertyType
+   {
+      ossimNumericPropertyType_INT   = 0,
+      ossimNumericPropertyType_UINT,
+      ossimNumericPropertyType_FLOAT32,
+      ossimNumericPropertyType_FLOAT64
+   };
+   
+   ossimNumericProperty(const ossimString& name=ossimString(""),
+                        const ossimString& value=ossimString("0"));
+   ossimNumericProperty(const ossimString& name,
+                        const ossimString& value,
+                        double minValue,
+                        double maxValue);
+   ossimNumericProperty(const ossimNumericProperty& rhs);
+   virtual ossimObject* dup()const;
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+   
+   virtual bool hasConstraints()const;
+   double getMinValue()const;
+   double getMaxValue()const;
+   
+   virtual void clearConstraints();
+   virtual void setConstraints(double minValue,
+                               double maxValue);
+  virtual bool setValue(const ossimString& value);
+   virtual void valueToString(ossimString& valueResult)const;
+
+   virtual ossimNumericPropertyType getNumericType()const;
+   virtual void setNumericType(ossimNumericPropertyType type);
+   
+   virtual ossim_float64 asFloat64()const;
+   virtual ossim_float32 asFloat32()const;
+   virtual ossim_uint32  asUInt32()const;
+   virtual ossim_uint16  asUInt16()const;
+   virtual ossim_uint8   asUInt8()const;
+   virtual ossim_sint32  asInt32()const;
+   virtual ossim_sint16  asInt16()const;
+   virtual ossim_sint8   asInt8()const;
+   
+protected:
+   ossimString              theValue;
+   ossimNumericPropertyType theType;
+   std::vector<double>      theRangeConstraint;
+TYPE_DATA
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimProperty.cpp
new file mode 100644
index 0000000000..1d299a4d07
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimProperty.cpp
@@ -0,0 +1,168 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimProperty.cpp,v 1.14 2005/06/09 11:25:35 gpotts Exp $
+#include "ossimProperty.h"
+
+
+RTTI_DEF1(ossimProperty, "ossimProperty", ossimObject);
+
+const ossimProperty& ossimProperty::operator = (const ossimProperty& rhs)
+{
+   this->assign(rhs);
+   
+   return *this;
+}
+
+ossimProperty::ossimProperty(const ossimString& name)
+   :theName(name),
+    theReadOnlyFlag(false),
+    theChangeType(ossimPropertyChangeType_NOTSPECIFIED),
+    theModifiedFlag(false)
+{
+}
+
+ossimProperty::ossimProperty(const ossimProperty& rhs)
+   :theName(rhs.theName),
+    theReadOnlyFlag(rhs.theReadOnlyFlag),
+    theChangeType(rhs.theChangeType),
+    theModifiedFlag(rhs.theModifiedFlag)
+{
+}
+
+ossimProperty::~ossimProperty()
+{
+}
+
+const ossimString& ossimProperty::getName()const
+{
+   return theName;
+}
+
+void ossimProperty::setName(const ossimString& name)
+{
+   theName = name;
+}
+
+const ossimProperty& ossimProperty::assign(const ossimProperty& rhs)
+{
+   theName         = rhs.theName;
+   theReadOnlyFlag = rhs.theReadOnlyFlag;
+   theChangeType   = rhs.theChangeType;
+   theModifiedFlag = rhs.theModifiedFlag;
+   
+   return *this;
+}
+
+ossimString ossimProperty::valueToString()const
+{
+   ossimString result;
+
+   valueToString(result);
+   
+   return result;
+   
+}
+
+void ossimProperty::clearChangeType()
+{
+   theChangeType = ossimPropertyChangeType_NOTSPECIFIED;
+}
+
+void ossimProperty::setChangeType(ossimPropertyChangeType type)
+{
+   theChangeType = type;
+}
+
+void ossimProperty::setFullRefreshBit()
+{
+   theChangeType = (ossimPropertyChangeType)(theChangeType | ossimPropertyChangeType_FULL_REFRESH);
+}
+
+void ossimProperty::setCacheRefreshBit()
+{
+   theChangeType = (ossimPropertyChangeType)(theChangeType | ossimPropertyChangeType_CACHE_REFRESH);
+}
+
+ossimProperty::ossimPropertyChangeType ossimProperty::getChangeType()const
+{
+   return theChangeType;
+}
+
+bool ossimProperty::isFullRefresh()const
+{
+   return ((theChangeType & ossimPropertyChangeType_FULL_REFRESH) != 0);
+}
+
+bool ossimProperty::isCacheRefresh()const
+{
+   return ((theChangeType & ossimPropertyChangeType_CACHE_REFRESH) != 0);
+}
+
+bool ossimProperty::isChangeTypeSpecified()const
+{
+   return (theChangeType != ossimPropertyChangeType_NOTSPECIFIED);
+}
+
+void ossimProperty::setReadOnlyFlag(bool flag)
+{
+   theReadOnlyFlag = flag;
+}
+
+bool ossimProperty::getReadOnlyFlag()const
+{
+   return theReadOnlyFlag;
+}
+
+bool ossimProperty::isReadOnly()const
+{
+   return (getReadOnlyFlag());
+}
+
+void ossimProperty::setModifiedFlag(bool flag)
+{
+   theModifiedFlag = flag;
+}
+
+bool ossimProperty::getModifiedFlag()const
+{
+   return theModifiedFlag;
+}
+
+bool ossimProperty::isModified()const
+{
+   return (theModifiedFlag == true);
+}
+
+void ossimProperty::clearModifiedFlag()
+{
+   theModifiedFlag = false;
+}
+
+void ossimProperty::setDescription(const ossimString& description)
+{
+   theDescription = description;
+}
+
+ossimString ossimProperty::getDescription()const
+{
+   return theDescription;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimProperty.h
new file mode 100644
index 0000000000..0b434d9229
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimProperty.h
@@ -0,0 +1,89 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimProperty.h,v 1.15 2005/06/09 11:25:35 gpotts Exp $
+#ifndef ossimProperty_HEADER
+#define ossimProperty_HEADER
+#include "base/common/ossimObject.h"
+#include "base/data_types/ossimString.h"
+
+class OSSIMDLLEXPORT ossimProperty : public ossimObject
+{
+public:
+   /*!
+    * This are bitwise and can be ored together
+    * The change type is very important and
+    * it determines how things are refreshed.
+    */
+   enum ossimPropertyChangeType
+   {
+      ossimPropertyChangeType_NOTSPECIFIED   = 0,
+      ossimPropertyChangeType_CACHE_REFRESH  = 1,
+      ossimPropertyChangeType_FULL_REFRESH   = 2
+   };
+   ossimProperty(const ossimString& name=ossimString(""));
+   ossimProperty(const ossimProperty& rhs);
+   virtual ~ossimProperty();
+   
+   const  ossimProperty& operator = (const ossimProperty& rhs);
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+
+   const ossimString& getName()const;
+   void setName(const ossimString& name);
+
+   virtual bool setValue(const ossimString& value)=0;
+   virtual void valueToString(ossimString& valueResult)const=0;
+   virtual ossimString valueToString()const;
+   
+   void clearChangeType();
+   void setChangeType(ossimPropertyChangeType type);
+   void setFullRefreshBit();
+   void setCacheRefreshBit();
+   
+   ossimPropertyChangeType getChangeType()const;
+   bool isFullRefresh()const;
+   bool isCacheRefresh()const;
+   bool isChangeTypeSpecified()const;
+
+   void setReadOnlyFlag(bool flag);
+   bool getReadOnlyFlag()const;
+   bool isReadOnly()const;
+
+   void setModifiedFlag(bool flag);
+   bool getModifiedFlag()const;
+   bool isModified()const;
+   void clearModifiedFlag();
+
+   void setDescription(const ossimString& description);
+   
+   virtual ossimString getDescription()const;
+   
+protected:
+   ossimString             theName;
+   ossimString             theDescription;
+   bool                    theReadOnlyFlag;
+   ossimPropertyChangeType theChangeType;
+   bool                    theModifiedFlag;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimStringListProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimStringListProperty.cpp
new file mode 100644
index 0000000000..aa271e98ba
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimStringListProperty.cpp
@@ -0,0 +1,272 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimStringListProperty.cpp,v 1.8 2004/01/29 13:29:31 gpotts Exp $
+//
+#include <sstream>
+#include <algorithm>
+#include "ossimStringListProperty.h"
+#include "base/data_types/ossimKeywordlist.h"
+RTTI_DEF1(ossimStringListProperty, "ossimStringListProperty", ossimProperty);
+
+ossimStringListProperty::ossimStringListProperty(const ossimString& name,
+                                                 const std::vector<ossimString>& value)
+   :ossimProperty(name),
+    theValueList(value),
+    theUniqueFlag(false),
+    theOrderMattersFlag(false)
+{
+}
+
+ossimStringListProperty::ossimStringListProperty(const ossimStringListProperty& rhs)
+   :ossimProperty(rhs),
+    theValueList(rhs.theValueList),
+    theConstraintList(rhs.theConstraintList),
+    theUniqueFlag(rhs.theUniqueFlag),
+    theOrderMattersFlag(rhs.theOrderMattersFlag),
+    theMinNumberOfValues(rhs.theMinNumberOfValues),
+    theMaxNumberOfValues(rhs.theMaxNumberOfValues)
+{
+}
+   
+ossimObject* ossimStringListProperty::dup()const
+{
+   return new ossimStringListProperty(*this);
+}
+
+const ossimProperty& ossimStringListProperty::assign(const ossimProperty& rhs)
+{
+   ossimProperty::assign(rhs);
+
+   ossimStringListProperty *rhsPtr = PTR_CAST(ossimStringListProperty,
+                                              &rhs);
+
+   if(rhsPtr)
+   {
+      theValueList         = rhsPtr->theValueList;
+      theConstraintList    = rhsPtr->theConstraintList;
+      theUniqueFlag        = rhsPtr->theUniqueFlag;
+      theOrderMattersFlag  = rhsPtr->theOrderMattersFlag;
+      theMinNumberOfValues = rhsPtr->theMinNumberOfValues;
+      theMaxNumberOfValues = rhsPtr->theMaxNumberOfValues;
+   }
+
+   return *this;
+}
+
+bool ossimStringListProperty::setValue(const ossimString& value)
+{
+   ossimKeywordlist kwl;
+   istringstream in(value);
+   bool result = true;
+   
+   if(kwl.parseStream(in))
+   {
+      int idx = 0;
+      vector<ossimString> keys =
+         kwl.getSubstringKeyList( "^([0-9]*" );
+      
+      std::vector<int> theNumberList(keys.size());
+      for(idx = 0; idx < (int)theNumberList.size();++idx)
+      {
+         theNumberList[idx] = keys[idx].toInt();
+      }
+      std::sort(theNumberList.begin(), theNumberList.end());
+      clearValueList();
+      for(idx = 0; idx < (int)theNumberList.size(); ++idx)
+      {
+         const char* temp = kwl.find(ossimString::toString(theNumberList[idx]));
+
+         if(temp)
+         {
+            addValue(temp);
+         }
+      }
+   }
+   else
+   {
+      result = false;
+   }
+
+   return result;
+}
+
+void ossimStringListProperty::valueToString(ossimString& valueResult)const
+{
+   ossimKeywordlist kwl;
+   int idx = 0;
+
+   for(idx = 0; idx < (int)theValueList.size(); ++idx)
+   {
+      kwl.add(ossimString::toString(idx),
+              theValueList[idx],
+              true);
+   }
+   
+   valueResult = kwl.toString();
+}
+
+
+void ossimStringListProperty::clearValueList()
+{
+   theValueList.clear();
+}
+
+ossimString ossimStringListProperty::getValueAt(int idx)const
+{
+   if((idx >= 0)&&
+      (idx < (int)getNumberOfValues()))
+   {
+      return theValueList[idx];
+   }
+   
+   return ossimString("");;
+}
+
+bool ossimStringListProperty::setValueAt(int idx,
+                                         const ossimString& value)
+{
+   bool result = true;
+   
+   if(canAddValue(value))
+   {
+      if((idx < (int)getNumberOfValues())&&
+         (idx >= 0))
+      {
+         theValueList[idx] = value;
+      }
+   }
+   else
+   {
+      result = false;
+   }
+   return result;
+   
+}
+
+bool ossimStringListProperty::addValue(const ossimString& value)
+{
+   bool result = true;
+   
+   if(canAddValue(value))
+   {
+      theValueList.push_back(value);
+   }
+   else
+   {
+      result = false;
+   }
+
+   return result;
+}
+ 
+ossim_uint32 ossimStringListProperty::getNumberOfValues()const
+{
+   return (int)theValueList.size();
+}
+
+ossim_uint32 ossimStringListProperty::getNumberOfContraints()const
+{
+   return theConstraintList.size();
+}
+
+ossimString ossimStringListProperty::getConstraintAt(ossim_uint32 idx)const
+{
+   if(idx < theConstraintList.size())
+   {
+      return theConstraintList[(int)idx];
+   }
+
+   return ossimString("");
+}
+
+void ossimStringListProperty::setConstraints(const std::vector<ossimString>& constraints)
+{
+   theConstraintList =  constraints;
+}
+
+bool ossimStringListProperty::hasConstraints()const
+{
+   return (theConstraintList.size()>0);
+}
+
+void ossimStringListProperty::setUniqueFlag(bool flag)
+{
+   theUniqueFlag = flag;
+}
+
+void ossimStringListProperty::setOrderMattersFlag(bool flag)
+{
+   theOrderMattersFlag = flag;
+}
+
+void ossimStringListProperty::setNumberOfValuesBounds(int minNumber,
+                                                      int maxNumber)
+{
+   theMinNumberOfValues = minNumber;
+   theMaxNumberOfValues = maxNumber;
+}
+
+void ossimStringListProperty::getNumberofValuesBounds(int& minNumber,
+                                                      int& maxNumber)const
+{
+   minNumber = theMinNumberOfValues;
+   maxNumber = theMaxNumberOfValues;
+}
+
+bool ossimStringListProperty::findValueInConstraintList(const ossimString& value)const
+{
+   return (std::find(theConstraintList.begin(),
+                     theConstraintList.end(),
+                     value)!=theConstraintList.end());
+}
+
+bool ossimStringListProperty::findValueInValueList(const ossimString& value)const
+{
+   return (std::find(theValueList.begin(),
+                     theValueList.end(),
+                     value)!=theConstraintList.end());
+}
+
+bool ossimStringListProperty::canAddValue(const ossimString& value)const
+{
+   bool result = true;
+
+   if(hasConstraints())
+   {
+      if(findValueInConstraintList(value))
+      {
+         if(theUniqueFlag)
+         {
+            if(findValueInValueList(value))
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+   }
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimStringListProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimStringListProperty.h
new file mode 100644
index 0000000000..5f877b4714
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimStringListProperty.h
@@ -0,0 +1,80 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimStringListProperty.h,v 1.7 2004/05/19 18:29:38 dburken Exp $
+//
+#ifndef ossimStringListProperty_HEADER
+#define ossimStringListProperty_HEADER
+#include "ossimProperty.h"
+
+class OSSIMDLLEXPORT ossimStringListProperty : public ossimProperty
+{
+public:
+   ossimStringListProperty(const ossimString& name=ossimString(""),
+                           const std::vector<ossimString>& value = std::vector<ossimString>());
+   ossimStringListProperty(const ossimStringListProperty& rhs);
+   
+   ossimObject* dup()const;
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+  virtual bool setValue(const ossimString& value);
+   virtual void valueToString(ossimString& valueResult)const;
+
+   void clearValueList();
+   ossimString getValueAt(int idx)const;
+   bool setValueAt(int idx,
+                   const ossimString& value);
+   bool addValue(const ossimString& value);
+   ossim_uint32 getNumberOfValues()const;
+
+   ossim_uint32 getNumberOfContraints()const;
+   ossimString getConstraintAt(ossim_uint32 idx)const;
+   
+   void setConstraints(const std::vector<ossimString>& constraints);
+   bool hasConstraints()const;
+   void setUniqueFlag(bool flag);
+   void setOrderMattersFlag(bool flag);
+
+   /*!
+    * You can specify how many values are allowed in the value list
+    * If any of the values are less than 0 then now constraints are
+    * placed on that value.  So if the min was < 0 then there is
+    * no minumum number of values.  If the max is < 0 then there is
+    * no maximum number of values.
+    */
+   void setNumberOfValuesBounds(int minNumber,
+                                int maxNumber);
+   void getNumberofValuesBounds(int& minNumber,
+                                int& maxNumber)const;
+protected:
+   std::vector<ossimString> theValueList;
+   std::vector<ossimString> theConstraintList;
+   bool                     theUniqueFlag;
+   bool                     theOrderMattersFlag;
+   int                      theMinNumberOfValues;
+   int                      theMaxNumberOfValues;
+   
+   bool findValueInConstraintList(const ossimString& value)const;
+   bool findValueInValueList(const ossimString& value)const;
+   bool canAddValue(const ossimString& value)const;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimStringProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimStringProperty.cpp
new file mode 100644
index 0000000000..92311b636b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimStringProperty.cpp
@@ -0,0 +1,127 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level license.txt
+// 
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimStringProperty.cpp,v 1.11 2004/09/22 16:31:08 gpotts Exp $
+#include "ossimStringProperty.h"
+#include <algorithm>
+RTTI_DEF1(ossimStringProperty, "ossimStringProperty", ossimProperty);
+
+ossimStringProperty::ossimStringProperty(const ossimString& name,
+                                         const ossimString& value,
+                                         bool editableFlag,
+                                         const std::vector<ossimString>& constraintList)
+   :ossimProperty(name),
+    theValue(value),
+    theEditableFlag(editableFlag),
+    theConstraints(constraintList)
+{
+}
+
+ossimStringProperty::ossimStringProperty(const ossimStringProperty& rhs)
+   :ossimProperty(rhs),
+    theValue(rhs.theValue),
+    theEditableFlag(rhs.theEditableFlag),
+    theConstraints(rhs.theConstraints)
+{
+}
+
+ossimObject* ossimStringProperty::dup()const
+{
+   return new ossimStringProperty(*this);
+}
+
+const ossimProperty& ossimStringProperty::assign(const ossimProperty& rhs)
+{
+   ossimProperty::assign(rhs);
+   
+   ossimStringProperty* rhsPtr = PTR_CAST(ossimStringProperty,
+					  &rhs);
+   
+   theValue        = rhs.valueToString();
+   
+   if(rhsPtr)
+     {
+       theEditableFlag = rhsPtr->theEditableFlag;
+       theConstraints  = rhsPtr->theConstraints;
+     }
+   
+   return *this;
+}
+
+
+void ossimStringProperty::setEditableFlag(bool flag)
+{
+   theEditableFlag = flag;
+}
+
+bool ossimStringProperty::getEditableFlag()const
+{
+   return theEditableFlag;
+}
+
+bool ossimStringProperty::isEditable()const
+{
+   return (getEditableFlag() == true);
+}
+
+
+void ossimStringProperty::clearConstraints()
+{
+   theConstraints.clear();
+}
+
+void ossimStringProperty::setConstraints(const std::vector<ossimString>& constraintList)
+{
+   theConstraints = constraintList;
+}
+
+void ossimStringProperty::addConstraint(const ossimString& value)
+{
+   theConstraints.push_back(value);
+}
+
+const std::vector<ossimString>& ossimStringProperty::getConstraints()const
+{
+   return theConstraints;
+}
+
+bool ossimStringProperty::hasConstraints()const
+{
+   return (theConstraints.size() > 0);
+}
+
+bool ossimStringProperty::setValue(const ossimString& value)
+{
+   bool result = true;
+   
+   if(theConstraints.size() > 0)
+   {
+      if(std::find(theConstraints.begin(),
+                   theConstraints.end(),
+                   value)
+                    != theConstraints.end())
+      {
+         theValue = value;
+      }
+      else
+      {
+         result = false;
+      }
+   }
+   else
+   {
+      theValue = value;
+   }
+
+   return result;
+}
+
+void ossimStringProperty::valueToString(ossimString& valueResult)const
+{
+   valueResult = theValue;
+}
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimStringProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimStringProperty.h
new file mode 100644
index 0000000000..8506d2205a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimStringProperty.h
@@ -0,0 +1,73 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level license.txt
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimStringProperty.h,v 1.11 2004/09/22 16:31:08 gpotts Exp $
+#ifndef ossimStringProperty_HEADER
+#define ossimStringProperty_HEADER
+#include "ossimProperty.h"
+#include <vector>
+
+class OSSIMDLLEXPORT ossimStringProperty : public ossimProperty
+{
+public:
+   ossimStringProperty(const ossimString& name = ossimString(""),
+                       const ossimString& value = ossimString(""),
+                       bool editableFlag = true,
+                       const std::vector<ossimString>& constraintList = std::vector<ossimString>());
+   
+   ossimStringProperty(const ossimStringProperty& rhs);
+
+   /*!
+    * Duplicates the object and returns a new one
+    */
+   virtual ossimObject* dup()const;
+
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+   
+   void setEditableFlag(bool flag);
+   bool getEditableFlag()const;
+   bool isEditable()const;
+   
+   /*!
+    * Clears the constraints for this string.  You can constrain
+    * it to a string list by calling setConstraints.
+    */
+   void clearConstraints();
+
+   /*!
+    * Sets the constraints for this property.  If the editable
+    * flag is present then this says the editing is not readonly
+    * and one can hand type the value in without only selecting
+    * from a choice list.
+    */
+   void setConstraints(const std::vector<ossimString>& constraintList);
+
+   void addConstraint(const ossimString& value);
+   const std::vector<ossimString>& getConstraints()const;
+   
+   bool hasConstraints()const;
+   
+   /*!
+    * will try to set the value.  If the constraints are set
+    * it will make sure that the value is in the list and
+    * if its not then it will return false 
+    */
+   virtual bool setValue(const ossimString& value);
+   
+   virtual void valueToString(ossimString& valueResult)const;
+  
+   
+protected:
+   ossimString theValue;
+   bool        theEditableFlag;
+   std::vector<ossimString> theConstraints;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimTextProperty.cpp b/Utilities/OSSIM/ossim_core/base/property/ossimTextProperty.cpp
new file mode 100644
index 0000000000..7a9b4273e4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimTextProperty.cpp
@@ -0,0 +1,76 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimTextProperty.cpp,v 1.6 2004/01/29 13:29:31 gpotts Exp $
+#include "ossimTextProperty.h"
+
+RTTI_DEF1(ossimTextProperty, "ossimTextProperty", ossimProperty);
+
+ossimTextProperty::ossimTextProperty(const ossimString& name,
+                                     const ossimString& value,
+                                     bool multiLineFlag)
+   :ossimProperty(name),
+    theValue(value),
+    theMultiLineFlag(multiLineFlag)
+{
+}
+
+ossimTextProperty::ossimTextProperty(const ossimTextProperty& rhs)
+   :ossimProperty(rhs),
+    theValue(rhs.theValue),
+    theMultiLineFlag(rhs.theMultiLineFlag)
+{
+}
+
+ossimObject* ossimTextProperty::dup()const
+{
+   return new ossimTextProperty(*this);
+}
+
+bool ossimTextProperty::isMulitLine()const
+{
+   return theMultiLineFlag;
+}
+
+void ossimTextProperty::setMultiLineFlag(bool flag)
+{
+   theMultiLineFlag = flag;
+}
+
+bool ossimTextProperty::setValue(const ossimString& value)
+{
+   theValue = value;
+   
+   return true;
+}
+
+void ossimTextProperty::valueToString(ossimString& valueResult)const
+{
+   valueResult = theValue;
+}
+
+const ossimProperty& ossimTextProperty::assign(const ossimProperty& rhs)
+{
+   theValue = rhs.valueToString();
+
+   return *this;
+}
+   
diff --git a/Utilities/OSSIM/ossim_core/base/property/ossimTextProperty.h b/Utilities/OSSIM/ossim_core/base/property/ossimTextProperty.h
new file mode 100644
index 0000000000..004bb3e584
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/base/property/ossimTextProperty.h
@@ -0,0 +1,50 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimTextProperty.h,v 1.7 2004/05/19 18:29:38 dburken Exp $
+#ifndef ossimTextProperty_HEADER
+#define ossimTextProperty_HEADER
+#include "ossimProperty.h"
+
+class OSSIMDLLEXPORT ossimTextProperty : public ossimProperty
+{
+public:
+   ossimTextProperty(const ossimString& name  = ossimString(""),
+                     const ossimString& value = ossimString(""),
+                     bool isMultiLine = false);
+   ossimTextProperty(const ossimTextProperty& rhs);
+   virtual ossimObject* dup()const;
+
+   bool isMulitLine()const;
+   void setMultiLineFlag(bool flag);
+
+   virtual void valueToString(ossimString& valueResult)const;
+  virtual bool setValue(const ossimString& value);
+   virtual const ossimProperty& assign(const ossimProperty& rhs);
+   
+protected:
+   ossimString theValue;
+   bool theMultiLineFlag;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/dll_main/Makefile b/Utilities/OSSIM/ossim_core/dll_main/Makefile
new file mode 100644
index 0000000000..fcb07e56e3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/dll_main/Makefile
@@ -0,0 +1,10 @@
+###
+# $Id: Makefile,v 1.1 2005/08/01 14:59:59 dburken Exp $
+# Intentionally left blank for unix build.
+###
+
+all:
+
+depends:
+
+clean:
diff --git a/Utilities/OSSIM/ossim_core/dll_main/ossimDllMain.cpp b/Utilities/OSSIM/ossim_core/dll_main/ossimDllMain.cpp
new file mode 100644
index 0000000000..04881d0d28
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/dll_main/ossimDllMain.cpp
@@ -0,0 +1,13 @@
+// This is the main DLL file.
+#include <windows.h>
+#include "ossimDllMain.h"
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance,  /* handle to DLL module */
+                    DWORD     dwReason,   /* reason for calling function */
+		    LPVOID    lpReserved )/* reserved */
+{
+   /* Nothing to do here yet. */
+   return TRUE;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/dll_main/ossimDllMain.h b/Utilities/OSSIM/ossim_core/dll_main/ossimDllMain.h
new file mode 100644
index 0000000000..224e4d101c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/dll_main/ossimDllMain.h
@@ -0,0 +1,7 @@
+// ossim_core_project.h
+
+
+namespace ossim_core_project
+{
+
+}
diff --git a/Utilities/OSSIM/ossim_core/elevation/.cvsignore b/Utilities/OSSIM/ossim_core/elevation/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/elevation/CMakeLists.txt b/Utilities/OSSIM/ossim_core/elevation/CMakeLists.txt
new file mode 100644
index 0000000000..0b5f0dd2cb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_elevation_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_elevation_HDRS "*.h")
+ADD_LIBRARY(ossim_elevation ${ossim_elevation_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_elevation)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_elevation_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/.cvsignore b/Utilities/OSSIM/ossim_core/elevation/formats/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/.cvsignore b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedFactory.cpp b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedFactory.cpp
new file mode 100644
index 0000000000..c95559b084
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedFactory.cpp
@@ -0,0 +1,168 @@
+//**************************************************************************
+// FILE: ossimDtedFactory.cc
+//
+// Copyright (C) 2002 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class definition for ossimDtedFactory.
+//
+// This is the base class interface for elevation source factories.  Contains
+// pure virtual methods that all elevation source factories must implement.
+//
+//**************************************************************************
+// $Id: ossimDtedFactory.cpp,v 1.13 2005/11/18 20:24:49 gpotts Exp $
+
+#include <sstream>
+#include <iomanip>
+#include <elevation/formats/dted_cell/ossimDtedFactory.h>
+#include <elevation/formats/dted_cell/ossimDtedHandler.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimGpt.h>
+#include <elevation/ossimElevManager.h>
+#include <base/context/ossimNotifyContext.h>
+
+static ossimTrace traceDebug ("ossimDtedFactory:debug");
+
+RTTI_DEF1(ossimDtedFactory, "ossimDtedFactory", ossimElevSourceFactory)
+
+ossimDtedFactory::ossimDtedFactory()
+   : ossimElevSourceFactory()
+{}
+
+ossimDtedFactory::ossimDtedFactory(const ossimFilename& dir)
+   : ossimElevSourceFactory()
+{
+   theDirectory = dir;
+}
+
+ossimDtedFactory::~ossimDtedFactory()
+{}
+
+ossimElevSource* ossimDtedFactory::getNewElevSource(const ossimGpt& gpt) const
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimDtedFactory::getNewElevSource: Entered..."
+         << std::endl;
+   }
+   
+   ossimElevManager* mgr = ossimElevManager::instance();
+   
+   ossimElevSource* dted_ptr = NULL;
+   
+   if (theDirectory == ossimFilename::NIL)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimDtedFactory::getNewElevSource: "
+         << "DTED directory has not been set!"
+         << "\nReturning null elevation source..."
+         << std::endl;
+      return dted_ptr;
+   }
+   
+   // Build up a dted file name.
+   ossimFilename dted_file_base;
+   
+   int ilon = static_cast<int>(floor(gpt.lond()));
+   
+   if (ilon < 0)
+   {
+      dted_file_base = "w";
+   }
+   else
+   {
+      dted_file_base = "e";
+   }
+   
+   ilon = abs(ilon);
+   ostringstream  s1;
+   s1<< setfill('0')<<setw(3)<< ilon;
+   
+   dted_file_base += s1.str().c_str();//ossimString::toString(ilon);
+   dted_file_base += "/";
+   
+   int ilat =  static_cast<int>(floor(gpt.latd()));
+   if (ilat < 0)
+   {
+      dted_file_base += "s";
+   }
+   else
+   {
+      dted_file_base += "n";
+   }
+
+   ilat = abs(ilat);
+   ostringstream  s2;
+
+   s2<< setfill('0')<<setw(2)<<ilat;
+   
+   dted_file_base += s2.str().c_str();
+
+   // Look for a dted file with a level 2 extension first.
+   ossimFilename dted_name = theDirectory.dirCat(dted_file_base);
+   dted_name += ".dt2";
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimDtedFactory::getNewElevSource:"
+         << "\nSearching for file:  " << dted_name
+         << std::endl;
+   }
+   
+   if (dted_name.exists() && !(mgr->isCellOpen(dted_name)) )
+   {
+      dted_ptr = new ossimDtedHandler(dted_name);
+      if ( (!(dted_ptr->getErrorStatus())) &&
+           dted_ptr->pointHasCoverage(gpt) )
+      {
+         return dted_ptr;
+      }
+      else
+      {
+         delete dted_ptr;
+         dted_ptr = NULL;
+      }
+   }
+
+   // Look for a dted file with a level 1 extension next.
+   dted_name = theDirectory.dirCat(dted_file_base);
+   dted_name += ".dt1";
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimDtedFactory::getNewElevSource:"
+         << "\nSearching for file:  " << dted_name
+         << std::endl;
+   }
+   
+   if (dted_name.exists() && !(mgr->isCellOpen(dted_name)) )
+   {
+      dted_ptr = new ossimDtedHandler(dted_name);
+      if ( (!(dted_ptr->getErrorStatus())) &&
+           dted_ptr->pointHasCoverage(gpt) )
+      {
+         return dted_ptr;
+      }
+      else
+      {
+         delete dted_ptr;
+         dted_ptr = NULL;
+      }
+   }
+
+   return dted_ptr;
+}
+
+void ossimDtedFactory::createIndex()
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedFactory.h b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedFactory.h
new file mode 100644
index 0000000000..ddd795f0cd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedFactory.h
@@ -0,0 +1,38 @@
+//*****************************************************************************
+// FILE: ossimDtedFactory.cc
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  David Burken
+//
+// Description:
+//
+// Class declaration for ossimDtedFactory.
+// This is the base class interface for elevation cell factories.
+//*****************************************************************************
+// $Id: ossimDtedFactory.h,v 1.6 2005/11/18 20:24:49 gpotts Exp $
+#ifndef ossimDtedFactory_HEADER
+#define ossimDtedFactory_HEADER
+
+#include <elevation/ossimElevSourceFactory.h>
+
+/** CLASS:  ossimDtedFactory */
+class OSSIM_DLL ossimDtedFactory : public ossimElevSourceFactory
+{
+public:
+
+   ossimDtedFactory();
+   ossimDtedFactory(const ossimFilename& dir);
+      
+   virtual ~ossimDtedFactory();
+
+   virtual ossimElevSource* getNewElevSource(const ossimGpt& gpt) const;
+   virtual void createIndex();
+protected:
+
+TYPE_DATA
+};
+
+#endif /* End of "#ifndef ossimDtedFactory_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedHandler.cpp b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedHandler.cpp
new file mode 100644
index 0000000000..90f76ca609
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedHandler.cpp
@@ -0,0 +1,460 @@
+//*****************************************************************************
+// FILE: ossimDtedHandler.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimDtedHandler. This class derives from
+//   ossimElevHandler. It is responsible for loading an individual DTED cell
+//   from disk. This elevation files are memory mapped.
+//
+//*****************************************************************************
+// $Id: ossimDtedHandler.cpp,v 1.31 2005/03/04 13:35:53 gpotts Exp $
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <elevation/formats/dted_cell/ossimDtedHandler.h>
+#include <support_data/dted/ossimDtedVol.h>
+#include <support_data/dted/ossimDtedHdr.h>
+#include <support_data/dted/ossimDtedUhl.h>
+#include <support_data/dted/ossimDtedDsi.h>
+#include <support_data/dted/ossimDtedAcc.h>
+#include <support_data/dted/ossimDtedRecord.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+RTTI_DEF1(ossimDtedHandler, "ossimDtedHandler" , ossimElevCellHandler)
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimDtedHandler:exec");
+static ossimTrace traceDebug ("ossimDtedHandler:debug");
+
+static const char ENABLE_STATS_KW[] = "elevation.compute_statistics.enabled";
+
+
+ossimDtedHandler::ossimDtedHandler(const ossimFilename& dted_file)
+   :
+      ossimElevCellHandler(dted_file),
+      theFileStr(),
+      theNumLonLines(0),
+      theNumLatPoints(0),
+      theDtedRecordSizeInBytes(0),
+      theEdition(),
+      theProductLevel(),
+      theCompilationDate(),
+      theOffsetToFirstDataRecord(0),
+      theLatSpacing(0.0),
+      theLonSpacing(0.0),
+      theSwCornerPost(),
+      theSwapBytesFlag(false)
+{
+   static const char MODULE[] = "ossimDtedHandler (Filename) Constructor";
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG " << MODULE <<": entering..." << std::endl;
+   }
+ 
+   //---
+   //  Open the dted file for reading.
+   //---
+   if (!open())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATAL " << MODULE << ": "
+            << "\nCould not open file:  " << dted_file.c_str()
+            << "\nReturning..." << std::endl;
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG " << MODULE << ": returning with error..." << std::endl;
+      }
+      return;
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG " << MODULE <<": Loading dted file: " << dted_file
+            << std::endl;
+      }
+   }
+
+   // DTED is stored in big endian.
+   theSwapBytesFlag = ossimGetByteOrder() == OSSIM_LITTLE_ENDIAN ? true : false;
+
+   // Attempt to parse.
+   ossimDtedVol vol(theFileStr, 0);
+   ossimDtedHdr hdr(theFileStr, vol.stopOffset());
+   ossimDtedUhl uhl(theFileStr, hdr.stopOffset());
+   ossimDtedDsi dsi(theFileStr, uhl.stopOffset());
+   ossimDtedAcc acc(theFileStr, dsi.stopOffset());
+
+   //***
+   // Check for errors.  Must have uhl, dsi and acc records.  vol and hdr
+   // are for magnetic tape only; hence, may or may not be there.
+   //***
+   if (uhl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR ||
+       dsi.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR ||
+       acc.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG " << MODULE << ": "
+            << "\nError parsing file:  " << dted_file.c_str()
+            << "\nPossibly not a dted file."
+            << endl;
+      }
+      
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      theFileStr.close();
+      return;
+   }
+   
+   theNumLonLines  = uhl.numLonLines();
+   theNumLatPoints = uhl.numLatPoints();
+   theLatSpacing   = uhl.latInterval();
+   theLonSpacing   = uhl.lonInterval();
+   theDtedRecordSizeInBytes = theNumLatPoints*2+ossimDtedRecord::DATA_LENGTH;
+
+   theEdition  = dsi.edition();
+   theProductLevel = dsi.productLevel();
+   theCompilationDate = dsi.compilationDate();
+
+   theOffsetToFirstDataRecord = acc.stopOffset();
+   
+   //***
+   //  initialize the bounding rectangle:
+   //***
+   double south_boundary = uhl.latOrigin();
+   double west_boundary  = uhl.lonOrigin();
+   double north_boundary = south_boundary + theLatSpacing*(theNumLatPoints-1);
+   double east_boundary  = west_boundary  + theLonSpacing*(theNumLonLines-1);
+                         
+   theGroundRect = ossimGrect(ossimGpt(north_boundary, west_boundary, 0.0),
+                              ossimGpt(south_boundary, east_boundary, 0.0));
+
+   theSwCornerPost.lat = south_boundary;
+   theSwCornerPost.lon = west_boundary;
+
+   //***
+   //  Determine the mean spacing:
+   //***
+   double center_lat = (south_boundary + north_boundary)/2.0;
+   theMeanSpacing = (theLatSpacing + theLonSpacing*cosd(center_lat))
+                    * ossimGpt().metersPerDegree().x / 2.0;
+
+   //  Initialize the accuracy values:
+   theAbsLE90 = (double) acc.absLE();
+   theAbsCE90 = (double) acc.absCE();
+
+   // Set the base class null height value.
+   theNullHeightValue = -32767.0;
+
+   // Get the statistics.
+   gatherStatistics();
+   
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG " << MODULE << ": returning..." << endl;
+   }
+}
+
+ossimDtedHandler::~ossimDtedHandler()
+{
+   theFileStr.close();
+}
+
+double ossimDtedHandler::getHeightAboveMSL(const ossimGpt& gpt)
+{
+   // Establish the grid indexes:
+   double xi = (gpt.lon - theSwCornerPost.lon) / theLonSpacing;
+   double yi = (gpt.lat - theSwCornerPost.lat) / theLatSpacing;
+
+   // Check for right edge.
+   int x0 = static_cast<int>(xi);
+   int y0 = static_cast<int>(yi);
+
+   // Check for right edge.
+   if (gpt.lon == theGroundRect.lr().lon)
+   {
+      --x0; // Move over one post.
+   }
+   
+   // Check for top edge.
+   if (gpt.lat == theGroundRect.ul().lat)
+   {
+      --y0; // Move down one post.
+   }
+
+   // Do some error checking.
+   if ( xi < 0.0 || yi < 0.0 ||
+        x0 > (theNumLonLines  - 2.0) ||
+        y0 > (theNumLatPoints - 2.0) )
+   {
+      return theNullHeightValue;
+   }
+
+   // We need an open stream to file from here on out...
+   if (!open())
+   {
+      return theNullHeightValue;
+   }
+
+   double p00;
+   double p01;
+   double p10;
+   double p11;
+
+   //***
+   // Grab the four points from the dted cell needed.  These are big endian,
+   // signed magnitude shorts so they must be interpreted accordingly.
+   //***
+   int offset = theOffsetToFirstDataRecord + x0 * theDtedRecordSizeInBytes +
+                y0 * 2 + DATA_RECORD_OFFSET_TO_POST;
+
+   // Put the file pointer at the start of the first elevation post.
+   theFileStr.seekg(offset, ios::beg);
+
+   ossim_sint16 ss;
+   ossim_uint16 us;
+
+   // Get the first post.
+   theFileStr.read((char*)&us, POST_SIZE);
+   ss = convertSignedMagnitude(us);
+   p00 = ss;
+
+   // Get the second post.
+   theFileStr.read((char*)&us, POST_SIZE);
+   ss = convertSignedMagnitude(us);
+   p01 = ss;
+
+   // Move over to the next column.
+   offset += theDtedRecordSizeInBytes;
+   theFileStr.seekg(offset, ios::beg);
+
+   // Get the third post.
+   theFileStr.read((char*)&us, POST_SIZE);
+   ss = convertSignedMagnitude(us);
+   p10 = ss;
+
+   // Get the fourth post.
+   theFileStr.read((char*)&us, POST_SIZE);
+   ss = convertSignedMagnitude(us);
+   p11 = ss;
+   
+   // Perform bilinear interpolation:
+   double wx1 = xi  - x0;
+   double wy1 = yi  - y0;
+   double wx0 = 1.0 - wx1;
+   double wy0 = 1.0 - wy1;
+   
+   double w00 = wx0*wy0;
+   double w01 = wx0*wy1;
+   double w10 = wx1*wy0;
+   double w11 = wx1*wy1;
+
+   //***
+   // Test for null posts and set the corresponding weights to 0:
+   //***
+   if (p00 == NULL_POST)
+      w00 = 0.0;
+   if (p01 == NULL_POST)
+      w01 = 0.0;
+   if (p10 == NULL_POST)
+      w10 = 0.0;
+   if (p11 == NULL_POST)
+      w11 = 0.0;
+
+#if 0 /* Serious debug only... */
+   cout << "\np00:  " << p00
+        << "\np01:  " << p01
+        << "\np10:  " << p10
+        << "\np11:  " << p11
+        << "\nw00:  " << w00
+        << "\nw01:  " << w01
+        << "\nw10:  " << w10
+        << "\nw11:  " << w11
+        << endl;
+#endif
+
+   double sum_weights = w00 + w01 + w10 + w11;
+
+   if (sum_weights)
+   {
+      return (p00*w00 + p01*w01 + p10*w10 + p11*w11) / sum_weights;
+   }
+   
+   return NULL_POST;
+}
+
+double ossimDtedHandler::getPostValue(const ossimIpt& gridPt) const
+{
+   static const char MODULE[] = "ossimDtedHandler::getPostValue";
+   
+   // Do some error checking.
+   if ( gridPt.x < 0.0 || gridPt.y < 0.0 ||
+        gridPt.x > (theNumLonLines  - 1) ||
+        gridPt.y > (theNumLatPoints - 1) )
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "WARNING " << MODULE << ": No intersection..." << std::endl;
+      }
+      return theNullHeightValue;
+   }
+
+   if (!open())
+   {
+      return theNullHeightValue;
+   }
+
+   int offset =
+      theOffsetToFirstDataRecord + gridPt.x * theDtedRecordSizeInBytes +
+      gridPt.y * 2 + DATA_RECORD_OFFSET_TO_POST;
+
+   // Put the file pointer at the start of the first elevation post.
+   theFileStr.seekg(offset, ios::beg);
+
+   ossim_uint16 us;
+
+   // Get the post.
+   theFileStr.read((char*)&us, POST_SIZE);
+   return double(convertSignedMagnitude(us));
+}
+
+void ossimDtedHandler::gatherStatistics()
+{
+   //***
+   // Check to see if there is a statistics file already.  If so; do a lookup
+   // for the min and max values.
+   //***
+   ossimFilename stats_file = theFilename;//theFilename.path();
+   stats_file.setExtension("statistics");
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimDtedHandler::gatherStatistics(): Looking for "
+         << stats_file << " statistics file..." << std::endl;
+   }
+
+   ossimKeywordlist kwl;
+   const char* min_str = NULL;
+   const char* max_str = NULL;
+
+   if (stats_file.exists())
+   {
+      if (kwl.addFile(stats_file))
+      {
+         // Look for the min_pixel_value keyword.
+         min_str = kwl.find(ossimKeywordNames::MIN_VALUE_KW);
+         max_str = kwl.find(ossimKeywordNames::MAX_VALUE_KW);
+      }
+   }
+
+   if (min_str && max_str)
+   {
+      theMinHeightAboveMSL = atoi(min_str);
+      theMaxHeightAboveMSL = atoi(max_str);
+   }
+   else if (theComputeStatsFlag)  // Scan the cell and gather the statistics...
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "NOTICE ossimDtedHandler::gatherStatistics():"
+            << " scanning for min/max"
+            << "\nThis may take a while..." << std::endl;
+      }
+      // Start off with the min and max pegged.
+      theMinHeightAboveMSL =  32767;
+      theMaxHeightAboveMSL = -32767;
+      
+      // Put the file pointer at the start of the first elevation post.
+      theFileStr.seekg(theOffsetToFirstDataRecord, ios::beg);
+      
+      //---
+      // Loop through all records and scan for lowest min and highest max.
+      // Each record contains a row of latitude points for a given longitude.
+      // There are eight bytes in front of the post and four checksum bytes at
+      // the end so ignore them.
+      //---
+      for (ossim_int32 i=0; i<theNumLonLines; ++i)  // longitude direction
+      {
+         theFileStr.seekg(DATA_RECORD_OFFSET_TO_POST, ios::cur);
+         
+         for (ossim_int32 j=0; j<theNumLatPoints; ++j) // latitude direction
+         {
+            ossim_uint16 us;
+            ossim_sint16 ss;
+            theFileStr.read((char*)&us, POST_SIZE);
+            ss = convertSignedMagnitude(us);
+            if (ss < theMinHeightAboveMSL && ss != NULL_POST)
+            {
+               theMinHeightAboveMSL = ss;
+            }
+            if (ss > theMaxHeightAboveMSL)
+            {
+               theMaxHeightAboveMSL = ss;
+            }
+         }
+         
+         theFileStr.seekg(DATA_RECORD_CHECKSUM_SIZE, ios::cur);
+      }
+      
+      // Add the stats to the keyword list.
+      kwl.add(ossimKeywordNames::MIN_VALUE_KW, theMinHeightAboveMSL);
+      kwl.add(ossimKeywordNames::MAX_VALUE_KW, theMaxHeightAboveMSL);
+      
+      // Write out the statistics file.
+      kwl.write(stats_file.c_str());
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimDtedHandler::gatherStatistics:"
+         << "\ntheMinHeightAboveMSL:  " << theMinHeightAboveMSL
+         << "\ntheMaxHeightAboveMSL:  " << theMaxHeightAboveMSL
+         << std::endl;
+   }
+}
+
+ossimIpt ossimDtedHandler::getSizeOfElevCell() const
+{
+   return ossimIpt(theNumLonLines, theNumLatPoints);
+}
+
+ossimString  ossimDtedHandler::edition() const
+{
+   return theEdition;
+}
+
+ossimString  ossimDtedHandler::productLevel() const
+{
+   return theProductLevel;
+}
+
+ossimString  ossimDtedHandler::compilationDate() const
+{
+   return theCompilationDate;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedHandler.h b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedHandler.h
new file mode 100644
index 0000000000..0ab8a54366
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/dted_cell/ossimDtedHandler.h
@@ -0,0 +1,156 @@
+//*****************************************************************************
+// FILE: ossimDtedHandler.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimDtedHandler. This class derives from
+//   ossimElevHandler. It is responsible for loading an individual DTED cell
+//   from disk. This elevation files are memory mapped.
+//
+// SOFTWARE HISTORY:
+//>
+//   05Feb2001  Ken Melero
+//              Initial coding of ossimDted.h
+//   19Apr2001  Oscar Kramer
+//              Derived from ossimElevCellHandler.
+//<
+//*****************************************************************************
+// $Id: ossimDtedHandler.h,v 1.19 2005/03/03 21:57:55 dburken Exp $
+
+#ifndef ossimDtedHandler_HEADER
+#define ossimDtedHandler_HEADER
+
+#include <fstream>
+
+#include <base/data_types/ossimString.h>
+#include <elevation/formats/ossimElevCellHandler.h>
+
+class ossimDtedHandler : public ossimElevCellHandler
+{
+public:
+   ossimDtedHandler(const ossimFilename& dted_file);
+   
+   virtual ~ossimDtedHandler();
+
+   enum
+   {
+      DATA_RECORD_OFFSET_TO_POST = 8,     // bytes
+      DATA_RECORD_CHECKSUM_SIZE  = 4,     // bytes
+      POST_SIZE                  = 2,     // bytes
+      NULL_POST                  = -32767 // Fixed by DTED specification.
+   };
+
+   /*!
+    * METHOD: getHeightAboveMSL
+    * Height access methods.
+    */
+   virtual double getHeightAboveMSL(const ossimGpt&);
+
+   /*!
+    *  METHOD:  getSizeOfElevCell
+    *  Returns the number of post in the cell.  Satisfies pure virtual.
+    *  Note:  x = longitude, y = latitude
+    */
+   virtual ossimIpt getSizeOfElevCell() const;
+      
+   /*!
+    *  METHOD:  getPostValue
+    *  Returns the value at a given grid point as a double.
+    *  Satisfies pure virtual.
+    */
+   virtual double getPostValue(const ossimIpt& gridPt) const;
+
+   ossimString  edition()         const;
+   ossimString  productLevel()    const;
+   ossimString  compilationDate() const;
+
+   /**
+    * Opens a stream to the dted cell.
+    *
+    * @return Returns true on success, false on error.
+    */
+   virtual bool open() const;
+
+   /**
+    * Closes the stream to the file.
+    */
+   virtual void close() const;
+   
+private:
+   // Disallow operator= and copy constrution...
+   const ossimDtedHandler& operator=(const ossimDtedHandler& rhs)
+      { return rhs; }
+   ossimDtedHandler(const ossimDtedHandler&){}
+
+   /*!
+    *  If statistics file exist, stats will be initialized from that; else,
+    *  this scans the dted cell and gets stats, then, writes new stats file.
+    *  The statistics file will be named accordingly:
+    *  If dted cell = n27.dt1 then the stats file = n27.statistics.
+    *  Currently method only grabs the min and max posts value.
+    */
+   void gatherStatistics();
+
+   ossim_sint16 convertSignedMagnitude(ossim_uint16& s) const;
+   
+   mutable ifstream theFileStr;
+   ossim_int32      theNumLonLines;  // east-west dir
+   ossim_int32      theNumLatPoints; // north-south
+   ossim_int32      theDtedRecordSizeInBytes;
+   ossimString      theEdition;
+   ossimString      theProductLevel;
+   ossimString      theCompilationDate;
+   ossim_int32      theOffsetToFirstDataRecord;
+   double           theLatSpacing;   // degrees
+   double           theLonSpacing;   // degrees
+   ossimDpt         theSwCornerPost; // cell origin;
+
+   // Indicates whether byte swapping is needed.
+   bool theSwapBytesFlag;
+
+   TYPE_DATA
+};
+
+inline ossim_sint16 ossimDtedHandler::convertSignedMagnitude(ossim_uint16& s) const
+{
+   // DATA_VALUE_MASK 0x7fff = 0111 1111 1111 1111
+   // DATA_SIGN_MASK  0x8000 = 1000 0000 0000 0000
+   
+   // First check to see if the bytes need swapped.
+   s = (theSwapBytesFlag ? ( (s << 8) | (s >> 8) ) : s);
+   
+   // If the sign bit is set, mask it out then multiply by negative one.
+   if (s & 0x8000)
+   {
+      return (static_cast<ossim_sint16>(s & 0x7fff) * -1);
+   }
+   
+   return static_cast<ossim_sint16>(s);
+}
+
+inline bool ossimDtedHandler::open() const
+{
+   if (theFileStr.is_open())
+   {
+      return true;
+   }
+
+   theFileStr.open(theFilename.c_str(), ios::in | ios::binary);
+
+   return theFileStr.is_open();
+}
+
+inline void ossimDtedHandler::close() const
+{
+   if (theFileStr.is_open())
+   {
+      theFileStr.close();
+   }
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandler.cpp b/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandler.cpp
new file mode 100644
index 0000000000..cfcd129212
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandler.cpp
@@ -0,0 +1,88 @@
+//*****************************************************************************
+// FILE: ossimElevCellHandler.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimElevCellHandler. This is the base
+//   class for all DEM file readers including DTED. Each file shall have its
+//   corresponding ossimElevCellHandler. When more than one file is accessed,
+//   an ossimElevCombiner is used which owns multiple instances of this class.
+//
+// SOFTWARE HISTORY:
+//>
+//   19Apr2001  Oscar Kramer
+//              Initial coding.
+//<
+//*****************************************************************************
+
+#include <elevation/formats/ossimElevCellHandler.h>
+#include <base/data_types/ossimKeyword.h>
+#include <base/data_types/ossimGpt.h>
+
+RTTI_DEF1(ossimElevCellHandler, "ossimElevCellHandler" , ossimElevSource)
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include "base/common/ossimTrace.h"
+static ossimTrace traceExec  ("ossimElevCellHandler:exec");
+static ossimTrace traceDebug ("ossimElevCellHandler:debug");
+
+static const ossimKeyword DEM_FILENAME_KW ("dem_filename",
+                                           "Name of DEM file to load.");
+static const ossimIpt ZERO_SIZE_IPT (0, 0);
+
+ossimElevCellHandler::ossimElevCellHandler ()
+{
+}
+
+ossimElevCellHandler::ossimElevCellHandler(const char* filename)
+   :
+      theFilename (filename)
+{}
+
+ossimElevCellHandler::~ossimElevCellHandler()
+{}
+
+ossimFilename ossimElevCellHandler::getFilename() const
+{
+   return theFilename;
+}
+
+double ossimElevCellHandler::getMeanSpacingMeters() const
+{
+   return theMeanSpacing;
+}
+
+double ossimElevCellHandler::getAccuracyLE90(const ossimGpt&) const
+{
+   return theAbsLE90;
+}
+
+double ossimElevCellHandler::getAccuracyCE90(const ossimGpt&) const
+{
+   return theAbsCE90;
+}
+
+bool ossimElevCellHandler::canConnectMyInputTo(
+   ossim_int32 inputIndex,
+   const ossimConnectableObject* object) const
+{         
+   return false;
+}
+
+// Hidden from use.
+ossimElevCellHandler::ossimElevCellHandler (const ossimElevCellHandler&)
+{
+}
+
+const ossimElevCellHandler& ossimElevCellHandler::operator=(
+   const ossimElevCellHandler& rhs)
+{
+   return rhs;
+}
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandler.h b/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandler.h
new file mode 100644
index 0000000000..d88c83907d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandler.h
@@ -0,0 +1,115 @@
+//*****************************************************************************
+// FILE: ossimElevCellHandler.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of class osimElevHandler. This class provides a
+//   base-class interface for the various DEM file formats.
+//
+// SOFTWARE HISTORY:
+//>
+//   13Apr2001  Oscar Kramer
+//              Initial coding.
+//<
+//*****************************************************************************
+// $Id: ossimElevCellHandler.h,v 1.14 2005/01/22 16:46:02 dburken Exp $
+
+
+#ifndef ossimElevCellHandler_HEADER
+#define ossimElevCellHandler_HEADER
+
+#include <elevation/ossimElevSource.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDrect.h>
+
+// class ossimDblGrid;
+
+/******************************************************************************
+ *
+ * CLASS:  ossimElevCellHandler
+ *
+ *****************************************************************************/
+class ossimElevCellHandler : public ossimElevSource
+{
+public:
+   /**
+    * Constructors:
+    */
+
+   ossimElevCellHandler (const char* elev_filename);
+
+   virtual ~ossimElevCellHandler();
+
+   virtual ossimFilename getFilename() const;
+   
+   
+   /**
+    *  METHOD:  getSizeOfElevCell 
+    *  Returns the number of post in the cell.
+    *  Note:  x = longitude, y = latitude
+    */
+   virtual ossimIpt getSizeOfElevCell() const = 0;
+
+   /**
+    *  METHOD:  getPostValue
+    *  Returns the value at a given grid point as a double.
+    */
+   virtual double getPostValue(const ossimIpt& gridPt) const = 0;
+      
+   /**
+    * METHOD: meanSpacingMeters()
+    * Implements pure virtual for. This method is used for deterrming
+    * preferred DEM among multiple overlapping elev sources:
+    */
+   virtual double getMeanSpacingMeters() const;
+
+   /**
+    * METHOD: pointIsInsideRect()
+    * Method to check if the ground point elevation is defined:
+    */
+   virtual bool pointHasCoverage(const ossimGpt&) const;
+
+   /**
+    * METHODS: accuracyLE90(), accuracyCE90()
+    * Returns the vertical and horizontal accuracy (90% confidence):
+    */
+   virtual double getAccuracyLE90(const ossimGpt&) const;
+   virtual double getAccuracyCE90(const ossimGpt&) const;
+
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const;
+      
+protected:
+   ossimElevCellHandler ();
+   
+   /**
+    * Virtual method for reading 
+    */
+   ossimFilename        theFilename;
+   double               theMeanSpacing;  // meters
+   double               theAbsLE90;
+   double               theAbsCE90;
+
+private:
+   // disallow...
+   ossimElevCellHandler (const ossimElevCellHandler&);
+   const ossimElevCellHandler& operator=(const ossimElevCellHandler& rhs);
+
+   
+TYPE_DATA
+};
+
+inline bool ossimElevCellHandler::pointHasCoverage(const ossimGpt& gpt) const
+{
+   return theGroundRect.pointWithin(gpt);
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandlerFactory.cpp b/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandlerFactory.cpp
new file mode 100644
index 0000000000..f31a745487
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandlerFactory.cpp
@@ -0,0 +1,130 @@
+//*****************************************************************************
+// FILE: ossimElevCellHandlerFactory.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimElevCellHandlerFactory. This is
+//   a "super-factory" owning a list of subfactories for each particular DEM
+//   format class.
+//
+//   NOT CURRENTLY UTILIZED -- USE DTED MANAGER
+//
+// LIMITATIONS:
+//   The intention of this factory is to produce individual instances of
+//   elevation cell handlers. Presently this is not supported since DTED is
+//   the only elevation source being handled. DTED is loaded via the
+//   ossimDtedManager class as a DB interface, and not by accessing individual
+//   DTED handlers.
+//
+// SOFTWARE HISTORY:
+//>
+//   01Aug2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimElevCellHandlerFactory.cpp,v 1.2 2005/01/22 16:46:02 dburken Exp $
+
+#include "ossimElevCellHandlerFactory.h"
+#include "base/data_types/ossimString.h"
+
+ossimElevCellHandlerFactory* ossimElevCellHandlerFactory::theInstance = 0;
+
+//*****************************************************************************
+//  STATIC METHOD: instance()
+//  
+//*****************************************************************************
+ossimElevCellHandlerFactory* ossimElevCellHandlerFactory::instance()
+{
+   if(!theInstance)
+      theInstance = new ossimElevCellHandlerFactory;
+ 
+   return (ossimElevCellHandlerFactory*) theInstance; 
+} 
+
+//*****************************************************************************
+//  PROTECTED DEFAULT CONSTRUCTOR: ossimElevCellHandlerFactory
+//  
+//*****************************************************************************
+ossimElevCellHandlerFactory::ossimElevCellHandlerFactory()
+{
+   //***
+   // Add default sub factories to this factory's registry list:
+   // NOTE: DTED handlers are managed by their own ossimDtedManager so should
+   // never be created individually via a factory. This will be the typical
+   // pattern for all but custom DEM files.
+   //***
+//   registerFactory(ossimUsgsDemCellFactory::instance());
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimElevCellHandlerFactory::create(kwl, prefix)
+//  
+//*****************************************************************************
+ossimElevCellHandler*
+ossimElevCellHandlerFactory::create(const ossimKeywordlist &keywordList,
+                                    const char *prefix) const
+{
+   list<ossimFactoryBase<ossimElevCellHandler>*>::const_iterator
+      elevCellFactory;
+
+   ossimElevCellHandler* product = 0;
+   
+   elevCellFactory = theRegistry.begin();
+   while((elevCellFactory != theRegistry.end()) && (!product))
+   {
+      product = (*elevCellFactory)->create(keywordList, prefix);
+      elevCellFactory++;
+   }
+
+   return product;
+}
+
+//*****************************************************************************
+//  METHOD: ossimElevCellHandlerFactory::create(proj_name)
+//  
+//*****************************************************************************
+ossimElevCellHandler*
+ossimElevCellHandlerFactory::create(const ossimString &name) const 
+{
+   list<ossimFactoryBase<ossimElevCellHandler>*>::const_iterator
+      elevCellFactory;
+
+   ossimElevCellHandler* product = 0;
+   
+   elevCellFactory = theRegistry.begin();
+   while((elevCellFactory != theRegistry.end()) && (!product))
+   {
+      product = (*elevCellFactory)->create(name);
+      elevCellFactory++;
+   }
+
+   return product;
+}
+
+//*****************************************************************************
+//  METHOD: ossimElevCellHandlerFactory::getList()
+//  
+//*****************************************************************************
+list<ossimString> ossimElevCellHandlerFactory::getList() const 
+{
+   list<ossimString> rtn_list;
+   list<ossimString> sub_list;
+   list<ossimFactoryBase<ossimElevCellHandler>*>::const_iterator factory_iter;
+
+   factory_iter = theRegistry.begin();
+   while(factory_iter != theRegistry.end())
+   {
+      sub_list = (*factory_iter)->getList();
+      rtn_list.merge(sub_list);
+      factory_iter++;
+   }
+
+   return rtn_list;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandlerFactory.h b/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandlerFactory.h
new file mode 100644
index 0000000000..888764208a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/ossimElevCellHandlerFactory.h
@@ -0,0 +1,63 @@
+//*****************************************************************************
+// FILE: ossimElevCellHandlerFactory.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimElevCellHandlerFactory. This factory
+//   class instantiates the proper ossimElevCellHandler given a file name.
+//
+// SOFTWARE HISTORY:
+//>
+//   26Apr2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+
+#ifndef ossimElevCellHandlerFactory_HEADER
+#define ossimElevCellHandlerFactory_HEADER
+
+#include "base/common/ossimFactoryBaseTemplate.h"
+
+class ossimElevCellHandler;
+class ossimGpt;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimElevCellHandlerFactory
+ *
+ *****************************************************************************/
+class ossimElevCellHandlerFactory :
+   public ossimFactoryBase <ossimElevCellHandler>
+{
+ public:
+   static ossimElevCellHandlerFactory* instance();
+   
+   virtual ossimElevCellHandler* create(const ossimString&) const;
+   virtual ossimElevCellHandler* create(const ossimKeywordlist& kwl,
+                                        const char* prefix) const;
+   
+   virtual list<ossimString> getList() const;
+   
+ protected:
+   ossimElevCellHandlerFactory();
+
+   static ossimElevCellHandlerFactory*  theInstance;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/srtm/.cvsignore b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/.cvsignore
new file mode 100644
index 0000000000..2dc074247b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/.cvsignore
@@ -0,0 +1,2 @@
+*.d
+Makefile
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmFactory.cpp b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmFactory.cpp
new file mode 100644
index 0000000000..f62fa7d052
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmFactory.cpp
@@ -0,0 +1,228 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Shuttle Radar Topography Mission (SRTM) factory to return an
+// ossimSrtmElevSource given a ground point.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimSrtmFactory.cpp,v 1.7 2005/11/21 15:04:59 gpotts Exp $
+
+#include <sstream>
+#include <elevation/formats/srtm/ossimSrtmFactory.h>
+#include <elevation/formats/srtm/ossimSrtmHandler.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimGpt.h>
+#include <elevation/ossimElevManager.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/factory/ossimStreamFactoryRegistry.h>
+#include <base/data_types/ossimDirectory.h>
+#include <support_data/srtm/ossimSrtmFilename.h>
+#include <support_data/srtm/ossimSrtmSupportData.h>
+#include <elevation/ossimElevationShapeIdx.h>
+
+static ossimTrace traceDebug ("ossimSrtmFactory:debug");
+
+RTTI_DEF1(ossimSrtmFactory, "ossimSrtmFactory", ossimElevSourceFactory)
+
+ossimSrtmFactory::ossimSrtmFactory()
+   : ossimElevSourceFactory()
+{}
+
+ossimSrtmFactory::ossimSrtmFactory(const ossimFilename& dir)
+   : ossimElevSourceFactory()
+{
+   theDirectory = dir;
+}
+      
+ossimSrtmFactory::~ossimSrtmFactory()
+{}
+
+ossimElevSource* ossimSrtmFactory::getNewElevSource(const ossimGpt& gpt) const
+{
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimSrtmFactory::getNewElevSource: Entered..."
+         << std::endl;
+   }
+
+   ossimElevManager* mgr = ossimElevManager::instance();
+   
+   ossimElevSource* srtmPtr = NULL;
+
+   if (theDirectory == ossimFilename::NIL)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "ossimSrtmFactory::getNewElevSource: "
+         << "SRTM directory has not been set!"
+         << "\nReturning null elevation source..."
+         << std::endl;
+      
+      return srtmPtr;
+   }
+
+   //---
+   // Build up a srtm file name.
+   //
+   // Standard for name is upper case 'N' and 'W' lower case "hgt" like:
+   // N27W081.hgt
+   //---
+   ossimFilename srtmFileBasename;
+
+   int ilat =  static_cast<int>(floor(gpt.latd()));
+   if (ilat < 0)
+   {
+      srtmFileBasename = "S";
+   }
+   else
+   {
+      srtmFileBasename = "N";
+   }
+
+   ilat = abs(ilat);
+   std::ostringstream  os1;
+   
+   os1 << setfill('0') <<setw(2) <<ilat;
+   
+   srtmFileBasename += os1.str().c_str();
+
+   int ilon = static_cast<int>(floor(gpt.lond()));
+   
+   if (ilon < 0)
+   {
+      srtmFileBasename += "W";
+   }
+   else
+   {
+      srtmFileBasename += "E";
+   }
+
+   ilon = abs(ilon);
+   std::ostringstream  os2;
+   os2 << setfill('0') <<setw(3) << ilon;
+   
+   srtmFileBasename += os2.str().c_str();
+   srtmFileBasename.setExtension(".hgt");
+
+   ossimFilename srtmFile = theDirectory.dirCat(srtmFileBasename);
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimSrtmFactory::getNewElevSource:"
+         << "\nSearching for file:  " << srtmFile
+         << std::endl;
+   }
+
+   ossimRefPtr<ossimIStream> is = ossimStreamFactoryRegistry::instance()->
+      createNewInputStream(srtmFile, ios::in | ios::binary);
+
+   // Look for the file mix case, then all lower case, then all upper case.
+   if (is.valid())
+   {
+      if(is->fail())
+      {
+         // Try down casing the whole thing.
+         srtmFileBasename = srtmFileBasename.downcase();
+         srtmFile = theDirectory.dirCat(srtmFileBasename);
+         
+         is =  ossimStreamFactoryRegistry::instance()->
+            createNewInputStream(srtmFile, ios::in | ios::binary);      
+         if (is.valid())
+         {
+            if(is->fail())
+            {
+               // OK, try upcasing the whole thing.
+               srtmFileBasename = srtmFileBasename.upcase();
+               srtmFile = theDirectory.dirCat(srtmFileBasename);
+               is =  ossimStreamFactoryRegistry::instance()->
+                  createNewInputStream(srtmFile, ios::in | ios::binary);
+            }
+         }
+      }
+   }
+
+   if ( is.valid() && (!is->fail())&&!(mgr->isCellOpen(srtmFile)) )
+   {
+      is->close();
+      is = 0;
+      srtmPtr = new ossimSrtmHandler(srtmFile);
+      if (srtmPtr->pointHasCoverage(gpt) )
+      {
+         return srtmPtr;
+      }
+      else
+      {
+         delete srtmPtr;
+         srtmPtr = NULL;
+      }
+   }
+   return srtmPtr;
+}
+
+void ossimSrtmFactory::createIndex()
+{
+   ossimDirectory dir;
+
+   if(dir.open(theDirectory))
+   {
+      ossimFilename f;
+      if(dir.getFirst(f, ossimDirectory::OSSIM_DIR_FILES))
+      {
+         ossimRefPtr<ossimElevationShapeIdx> shpIdx = 0;
+         try
+         {
+            shpIdx = new ossimElevationShapeIdx(theDirectory, true);
+         }
+         catch(...)
+         {
+            shpIdx = 0;
+            return;
+         }
+         
+         do
+         {
+            if(f.contains(".hgt"))
+            {
+               // check and remove the gz extension if present
+               //
+               ossimFilename file = f.file();
+               if(f.ext() == "gz")
+               {
+                  f = f.setExtension("");
+               }
+               ossimSrtmFilename srtmFile;
+               if(srtmFile.setFilename(f.file()))
+               {
+                  ossimSrtmSupportData srtmSupport;
+
+                  if(srtmSupport.setFilename(f, true))
+                  {
+                     shpIdx->add(f,
+                                 srtmFile.ul().lond(),
+                                 srtmFile.ll().latd(),
+                                 srtmSupport.getMinPixelValue(),
+                                 srtmFile.ur().lond(),
+                                 srtmFile.ur().latd(),
+                                 srtmSupport.getMaxPixelValue());
+                  }
+               }
+            }
+         }while(dir.getNext(f));
+         shpIdx->buildQuadTree();
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimSrtmFactory::createIndex(): Directory can't be opened for indexing." << std::endl;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmFactory.h b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmFactory.h
new file mode 100644
index 0000000000..167251f0d3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmFactory.h
@@ -0,0 +1,59 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Shuttle Radar Topography Mission (SRTM) factory to return an
+// ossimSrtmElevSource given a ground point.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimSrtmFactory.h,v 1.4 2005/11/18 20:24:49 gpotts Exp $
+#ifndef ossimSrtmFactory_HEADER
+#define ossimSrtmFactory_HEADER
+
+#include <elevation/ossimElevSourceFactory.h>
+
+/**
+ * @class ossimSrtmFactory Used by the elevation manager, this class returns
+ * an ossimSrtmElevSource given a ground point and some directory with srtm
+ * files in it.
+ */
+class OSSIM_DLL ossimSrtmFactory : public ossimElevSourceFactory
+{
+public:
+
+   /** default constructor */
+   ossimSrtmFactory();
+
+   /** Constructor that takes a directory name. */
+   ossimSrtmFactory(const ossimFilename& dir);
+
+   /** destructor */
+   virtual ~ossimSrtmFactory();
+
+   /**
+    * Open the appropriate ossimSrtmElevSource that covers given a
+    * ground point.
+    *
+    * @param gpt Ground point that an elevation source is need for.
+    *
+    * @return Returns a pointer to an ossimElevSource if an srtm file is found
+    * that can cover the ground point.  Returns NULL if no cell is found
+    * for the point.
+    */
+   virtual ossimElevSource* getNewElevSource(const ossimGpt& gpt) const;
+
+   virtual void createIndex();
+   
+protected:
+
+TYPE_DATA
+};
+
+#endif /* End of "#ifndef ossimSrtmFactory_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmHandler.cpp b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmHandler.cpp
new file mode 100644
index 0000000000..038c5ea587
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmHandler.cpp
@@ -0,0 +1,364 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Shuttle Radar Topography Mission (SRTM) elevation source.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimSrtmHandler.cpp,v 1.7 2005/11/16 15:06:33 dburken Exp $
+
+#include <elevation/formats/srtm/ossimSrtmHandler.h>
+#include <support_data/srtm/ossimSrtmSupportData.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/misc/ossimEndian.h>
+#include <base/factory/ossimStreamFactoryRegistry.h>
+
+RTTI_DEF1(ossimSrtmHandler, "ossimSrtmHandler" , ossimElevCellHandler)
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceDebug ("ossimSrtmElevSource:debug");
+
+ossimSrtmHandler::ossimSrtmHandler(const ossimFilename& srtmFile)
+   :
+      ossimElevCellHandler(srtmFile),
+      theFileStr(0),
+      theNumberOfLines(0),
+      theNumberOfSamples(0),
+      theSrtmRecordSizeInBytes(0),
+      theLatSpacing(0.0),
+      theLonSpacing(0.0),
+      theNwCornerPost(),
+      theSwapper(NULL)
+{
+   ossimSrtmSupportData sd;
+   if ( !sd.setFilename(srtmFile, false) )
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      return;
+   }
+
+   theScalarType = sd.getScalarType();
+   // SRTM is stored in big endian.
+   if ( ossimGetByteOrder() == OSSIM_LITTLE_ENDIAN)
+   {
+      theSwapper = new ossimEndian();
+   }
+
+   theNumberOfLines         = sd.getNumberOfLines();
+   theNumberOfSamples       = sd.getNumberOfSamples();
+   theSrtmRecordSizeInBytes = theNumberOfSamples * ossimGetScalarSizeInBytes(theScalarType);
+   theLatSpacing            = sd.getLatitudeSpacing();
+   theLonSpacing            = sd.getLongitudeSpacing();
+   theNwCornerPost.lon      = sd.getSouthwestLongitude();
+   theNwCornerPost.lat      = sd.getSouthwestLatitude()+1.0;
+   theScalarType            = sd.getScalarType();
+   theGroundRect = ossimGrect(ossimGpt(theNwCornerPost.lat,
+                                       theNwCornerPost.lon,
+                                       0.0),
+                              ossimGpt(theNwCornerPost.lat-1.0,
+                                       theNwCornerPost.lon+1.0,
+                                       0.0));
+
+   //---
+   //  Determine the mean spacing:
+   //---
+   // double center_lat = (south_boundary + north_boundary)/2.0;
+   // theMeanSpacing = (theLatSpacing + theLonSpacing*cosd(center_lat))
+   //          * ossimGpt().metersPerDegree().x / 2.0;
+
+   //  Initialize the accuracy values:
+   // theAbsLE90 = (double) acc.absLE();
+   // theAbsCE90 = (double) acc.absCE();
+
+   // Set the base class null height value.
+   theNullHeightValue = -32768.0;
+
+   // theMinHeightAboveMSL;
+   // theMaxHeightAboveMSL;
+}
+
+ossimSrtmHandler::~ossimSrtmHandler()
+{
+   if (theSwapper)
+   {
+      delete theSwapper;
+      theSwapper = NULL;
+   }
+
+   theFileStr = 0;
+//    if(theFileStr)
+//    {
+//       delete theFileStr;
+//       theFileStr = 0;
+//    }
+//   theFileStr.close();
+}
+
+double ossimSrtmHandler::getHeightAboveMSL(const ossimGpt& gpt)
+{
+   switch(theScalarType)
+   {
+      case OSSIM_SINT16:
+      {
+         return getHeightAboveMSLTemplate((ossim_sint16)0,
+                                          gpt);
+      }
+      case OSSIM_FLOAT32:
+      {
+         return getHeightAboveMSLTemplate((ossim_float32)0,
+                                          gpt);
+      }
+      default:
+      {
+         break;
+      }
+   }
+
+   return NULL_POST;
+}
+
+template <class T>
+double ossimSrtmHandler::getHeightAboveMSLTemplate(T dummy,
+                                                   const ossimGpt& gpt)
+{
+   // Establish the grid indexes:
+   double xi = (gpt.lon - theNwCornerPost.lon) / theLonSpacing;
+   double yi = (theNwCornerPost.lat - gpt.lat) / theLatSpacing;
+
+   int x0 = static_cast<int>(xi);
+   int y0 = static_cast<int>(yi);
+
+   // Check for right edge.
+   if (gpt.lon == theGroundRect.lr().lon)
+   {
+      --x0; // Move over one post to the left.
+   }
+   
+   // Check for bottom edge.
+   if (gpt.lat == theGroundRect.lr().lat)
+   {
+      --y0; // Move up one post.
+   }
+
+   // Do some error checking.
+   if ( xi < 0.0 || yi < 0.0 ||
+        x0 > (theNumberOfSamples  - 2.0) ||
+        y0 > (theNumberOfLines    - 2.0) )
+   {
+//       std::cout << "ossimSrtmHandler::getHeightAboveMSLTemplate: leaving 1" << std::endl;
+      return theNullHeightValue;
+   }
+
+   // We need an open stream to file from here on out...
+   if (!open())
+   {
+//       std::cout << "ossimSrtmHandler::getHeightAboveMSLTemplate: leaving 2" << std::endl;
+      return theNullHeightValue;
+   }
+
+   T p[4];
+   
+   double p00;
+   double p01;
+   double p10;
+   double p11;
+
+   //---
+   // Grab the four points from the srtm cell needed.
+   //---
+   streampos offset = y0 * theSrtmRecordSizeInBytes + x0 * sizeof(T);
+
+//   ossim_int64 currentG = theFileStr->tellg();
+   // lets a seek cur
+   // 
+   // Put the file pointer at the start of the first elevation post.
+      theFileStr->seekg(offset, ios::beg);
+      //theFileStr->seekg(offset-currentG, ios::cur);
+   // Get the first post.
+   theFileStr->read((char*)p, sizeof(T));
+   
+   // Get the second post.
+   theFileStr->read((char*)(p+1), sizeof(T));
+   
+   // Move over to the next column.
+   offset += theSrtmRecordSizeInBytes;
+
+//   currentG = theFileStr->tellg();
+//   theFileStr->seekg(offset-currentG, ios::cur);
+   
+   theFileStr->seekg(offset, ios::beg);
+   
+   // Get the third post.
+   theFileStr->read((char*)(p+2), sizeof(T));
+
+   // Get the fourth post.
+   theFileStr->read((char*)(p+3), sizeof(T));
+
+   if(theFileStr->fail())
+   {
+      return theNullHeightValue;
+   }
+   if (theSwapper)
+   {
+      theSwapper->swap((T*)p, 4);
+   }
+
+   p00 = p[0];
+   p01 = p[1];
+   p10 = p[2];
+   p11 = p[3];
+   
+   // Perform bilinear interpolation:
+//    double wx1 = xi  - x0;
+//    double wy1 = yi  - y0;
+//    double wx0 = 1.0 - wx1;
+//    double wy0 = 1.0 - wy1;
+
+   double xt0 = xi - x0;
+   double yt0 = yi - y0;
+   double xt1 = 1-xt0;
+   double yt1 = 1-yt0;
+
+//    double w00 = wx0*wy0;
+//    double w01 = wx0*wy1;
+//    double w10 = wx1*wy0;
+//    double w11 = wx1*wy1;
+   double w00 = xt1*yt1;
+   double w01 = xt0*yt1;
+   double w10 = xt1*yt0;
+   double w11 = xt0*yt0;
+
+   //***
+   // Test for null posts and set the corresponding weights to 0:
+   //***
+   if (p00 == theNullHeightValue)
+      w00 = 0.0;
+   if (p01 == theNullHeightValue)
+      w01 = 0.0;
+   if (p10 == theNullHeightValue)
+      w10 = 0.0;
+   if (p11 == theNullHeightValue)
+      w11 = 0.0;
+
+#if 0 /* Serious debug only... */
+   cout << "\np00:  " << p00
+        << "\np01:  " << p01
+        << "\np10:  " << p10
+        << "\np11:  " << p11
+        << "\nw00:  " << w00
+        << "\nw01:  " << w01
+        << "\nw10:  " << w10
+        << "\nw11:  " << w11
+        << endl;
+#endif
+
+   double sum_weights = w00 + w01 + w10 + w11;
+
+   if (sum_weights)
+   {
+      return (p00*w00 + p01*w01 + p10*w10 + p11*w11) / sum_weights;
+   }
+
+   return theNullHeightValue;
+}
+
+double ossimSrtmHandler::getPostValue(const ossimIpt& gridPt) const
+{
+   static const char MODULE[] = "ossimSrtmHandler::getPostValue";
+   
+   if(!theFileStr.valid()) return theNullHeightValue;
+   
+   // Do some error checking.
+   if ( gridPt.x < 0.0 || gridPt.y < 0.0 ||
+        gridPt.x > (theNumberOfSamples  - 1) ||
+        gridPt.y > (theNumberOfLines - 1) )
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "WARNING " << MODULE << ": No intersection..." << std::endl;
+      }
+      return theNullHeightValue;
+   }
+
+   if (!open())
+   {
+      return theNullHeightValue;
+   }
+
+   streampos offset = gridPt.y * theSrtmRecordSizeInBytes + gridPt.x * 2;
+
+   // Put the file pointer at the start of the first elevation post.
+   theFileStr->seekg(offset, ios::beg);
+
+   ossim_sint16 p;
+
+   // Get the post.
+   theFileStr->read((char*)&p, 2);
+   if (theSwapper)
+   {
+      theSwapper->swap(p);
+   }
+   return p;
+}
+
+ossimIpt ossimSrtmHandler::getSizeOfElevCell() const
+{
+   return ossimIpt(theNumberOfSamples, theNumberOfLines);
+}
+
+const ossimSrtmHandler&
+ossimSrtmHandler::operator=(const ossimSrtmHandler& rhs)
+{
+   return rhs;
+}
+
+ossimSrtmHandler::ossimSrtmHandler(const ossimSrtmHandler&)
+{
+}
+
+
+bool ossimSrtmHandler::open() const
+{
+   if(theFileStr.valid())
+   {
+      if(!theFileStr->fail())
+      {
+         return true;
+      }
+   }
+   theFileStr = 0;
+
+   
+   theFileStr = ossimStreamFactoryRegistry::instance()->createNewInputStream(theFilename,
+                                                                             ios::in | ios::binary);   
+
+   if(theFileStr.valid())
+   {
+      return (!theFileStr->fail());
+   }
+   return false;
+}
+
+void ossimSrtmHandler::close() const
+{
+   if(theFileStr.valid())
+   {
+      theFileStr->close();
+      theFileStr = 0;
+   }
+   
+}
diff --git a/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmHandler.h b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmHandler.h
new file mode 100644
index 0000000000..df821e4f0b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/formats/srtm/ossimSrtmHandler.h
@@ -0,0 +1,100 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Shuttle Radar Topography Mission (SRTM) elevation source.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimSrtmHandler.h,v 1.4 2005/11/10 14:15:33 gpotts Exp $
+#ifndef ossimSrtmHandler_HEADER
+#define ossimSrtmHandler_HEADER
+
+#include <base/common/ossimIoStream.h>
+//#include <fstream>
+
+#include <base/data_types/ossimString.h>
+#include <elevation/formats/ossimElevCellHandler.h>
+
+class ossimEndian;
+
+/**
+ * @class ossimSrtmHandler Elevation source for an srtm file.
+ */
+class OSSIMDLLEXPORT ossimSrtmHandler : public ossimElevCellHandler
+{
+public:
+
+   /** Constructor that takes a file name. */
+   ossimSrtmHandler(const ossimFilename& srtmFile);
+
+   /** destructor */
+   virtual ~ossimSrtmHandler();
+
+   enum
+   {
+      NULL_POST = -32768 // Fixed by SRTM specification.
+   };
+
+   /**
+    * METHOD: getHeightAboveMSL
+    * Height access methods.
+    */
+   virtual double getHeightAboveMSL(const ossimGpt&);
+
+   /**
+    *  METHOD:  getSizeOfElevCell
+    *  Returns the number of post in the cell.  Satisfies pure virtual.
+    *  Note:  x = longitude, y = latitude
+    */
+   virtual ossimIpt getSizeOfElevCell() const;
+      
+   /**
+    *  METHOD:  getPostValue
+    *  Returns the value at a given grid point as a double.
+    *  Satisfies pure virtual.
+    */
+   virtual double getPostValue(const ossimIpt& gridPt) const;
+
+   /**
+    * Opens a stream to the srtm cell.
+    *
+    * @return Returns true on success, false on error.
+    */
+   virtual bool open() const;
+
+   /**
+    * Closes the stream to the file.
+    */
+   virtual void close() const;
+   
+private:
+   // Disallow operator= and copy constrution...
+   const ossimSrtmHandler& operator=(const ossimSrtmHandler& rhs);
+   ossimSrtmHandler(const ossimSrtmHandler&);
+
+   mutable ossimRefPtr<ossimIStream> theFileStr;
+//   mutable std::istream* theFileStr;
+//   mutable ifstream theFileStr;
+   ossim_int32      theNumberOfLines;
+   ossim_int32      theNumberOfSamples;
+   ossim_int32      theSrtmRecordSizeInBytes;
+   double           theLatSpacing;   // degrees
+   double           theLonSpacing;   // degrees
+   ossimDpt         theNwCornerPost; // cell origin;
+   ossimEndian*     theSwapper;
+   ossimScalarType theScalarType;
+   
+   template <class T>
+   double getHeightAboveMSLTemplate(T dummy,
+                                    const ossimGpt& gpt);
+TYPE_DATA
+};
+
+#endif /* End of "#ifndef ossimSrtmHandler_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/elevation/ossimElevLess.h b/Utilities/OSSIM/ossim_core/elevation/ossimElevLess.h
new file mode 100644
index 0000000000..ac61385d55
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/ossimElevLess.h
@@ -0,0 +1,45 @@
+//*****************************************************************************
+// FILE: ossimElevLess.h
+//
+// Copyright (C) 2002 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+// Function object (functor) to for stl's sort method for sorting
+// a vector of ossimElevSource* by best post spacing.
+//*****************************************************************************
+//  $Id: ossimElevLess.h,v 1.3 2005/11/18 20:24:49 gpotts Exp $
+
+#ifndef ossimElevLess_HEADER
+#define ossimElevLess_HEADER
+
+#include <functional>
+
+#include "ossimElevSource.h"
+
+class ossimElevLess :
+           public std::binary_function<const ossimRefPtr<ossimElevSource>,
+                  const ossimRefPtr<ossimElevSource>, bool>
+{
+public:
+   bool operator() (const ossimRefPtr<ossimElevSource> a, const ossimRefPtr< ossimElevSource> b) const
+   {
+      return (a->getMeanSpacingMeters() < b->getMeanSpacingMeters());
+   }
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/elevation/ossimElevManager.cpp b/Utilities/OSSIM/ossim_core/elevation/ossimElevManager.cpp
new file mode 100644
index 0000000000..eb51c163c4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/ossimElevManager.cpp
@@ -0,0 +1,1538 @@
+//**************************************************************************
+// FILE: ossimElevManager.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimElevManager. This object 
+//   provides a single interface for accessing multiple elevation
+//   sources. This object owns one or more elevation sources in an ordered
+//   list. When queried for an elevation at a particular point, it searches
+//   the available sources for the best result, instantiating new sources if
+//   necessary.
+//
+// SOFTWARE HISTORY:
+//>
+//   23Apr2001  Oscar Kramer
+//              Initial coding.
+//<
+//**************************************************************************
+// $Id: ossimElevManager.cpp,v 1.46 2005/12/21 21:25:21 dburken Exp $
+
+#include <algorithm>
+
+#include <elevation/ossimElevManager.h>
+#include <elevation/ossimElevLess.h>
+#include <elevation/formats/dted_cell/ossimDtedFactory.h>
+#include <elevation/formats/dted_cell/ossimDtedHandler.h>
+#include <elevation/formats/srtm/ossimSrtmFactory.h>
+#include <elevation/formats/srtm/ossimSrtmHandler.h>
+#include <elevation/formats/ossimElevCellHandler.h>
+#include <base/data_types/geoid/ossimGeoidManager.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimKeyword.h>
+#include <base/data_types/ossimDirectory.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimScopedLock.h>
+#include <base/common/events/ossimElevationManagerEvent.h>
+#include <base/context/ossimNotifyContext.h>
+
+
+RTTI_DEF1(ossimElevManager, "ossimElevManager" , ossimElevSource)
+
+//***
+// Define Trace flags for use within this file:
+//***
+static ossimTrace traceDebug ("ossimElevManager:debug");
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimElevManager.cpp,v 1.46 2005/12/21 21:25:21 dburken Exp $";
+#endif
+
+ossimElevManager* ossimElevManager::theInstance = NULL;
+
+ossimElevManager* ossimElevManager::instance()
+{
+   if (!theInstance)
+      theInstance = new ossimElevManager();
+   
+   return theInstance;
+}
+
+ossimElevManager::ossimElevManager()
+   :
+      ossimElevSource(),
+      theElevSourceList(0),
+      theElevSourceFactoryList(0),
+      theGeoidManager(ossimGeoidManager::instance()),
+      theAutoLoadFlag(true),
+      theAutoSortFlag(true),
+      theDefaultElevationPath(ossimFilename::NIL)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimElevManager::ossimElevManager() entered..."
+         << std::endl;
+#if OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "OSSIM_ID:  "
+         << OSSIM_ID
+         << std::endl;
+#endif      
+   }
+
+   if (!theInstance) theInstance = this;
+}
+
+ossimElevManager::~ossimElevManager()
+{
+   theInstance = NULL;
+
+   // Delete the list of elevation sources and clear the list.
+//    vector<ossimElevSource*>::iterator s = theElevSourceList.begin();
+//    while (s != theElevSourceList.end())
+//    {
+//       delete *s;
+//       ++s;
+//    }
+   theElevSourceList.clear();
+
+   // Delete the list of elevation factories and clear the list.
+//    vector<const ossimElevSourceFactory*>::iterator f
+//       = theElevSourceFactoryList.begin();
+//    while (f != theElevSourceFactoryList.end())
+//    {
+//       delete *f;
+//       ++f;
+//    }
+   theElevSourceFactoryList.clear();
+}
+
+bool ossimElevManager::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevManager::loadState: Entered..."
+         << std::endl;
+   }
+   ossimString copyPrefix = prefix;
+
+   //---
+   // Call the base class loadState.  This will pick up the enabled keyword.
+   // Note we need to tack on the "elevation." prefix so the lookup of
+   // "elevation.enabled" occurs.
+   //---
+   ossimString elev_prefix;
+   if (prefix)
+   {
+      elev_prefix = prefix;
+   }
+   elev_prefix += "elevation.";
+   ossimSource::loadState(kwl, elev_prefix);
+   
+   const char* lookup; // used throughout
+
+   // Check for the elevation.autoload_dted.enabled keyword.
+   lookup = kwl.find(prefix, "elevation.auto_load_dted.enabled");
+   if (lookup)
+   {
+      theAutoLoadFlag = ossimString(lookup).toBool();
+   }
+
+   // Check for the autosort_elevation keyword.
+   lookup = kwl.find(prefix, "elevation.auto_sort.enabled");
+   if (lookup)
+   {
+      theAutoSortFlag = ossimString(lookup).toBool();
+   }
+
+   // Check for a default elevation path.
+   const char DEFAULT_ELEVATION_PATH_KW[] = "default_elevation_path";
+   lookup = kwl.find(DEFAULT_ELEVATION_PATH_KW);
+   if(lookup)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            <<  "DEBUG ossimElevManager::loadState: "
+            << DEFAULT_ELEVATION_PATH_KW
+            << " lookup:  " << lookup << std::endl;
+      }
+      theDefaultElevationPath = lookup;
+   }
+   ossimString regExpression =  ossimString("^(") + copyPrefix + "elevation_source[0-9]+.)";
+   vector<ossimString> keys =
+      kwl.getSubstringKeyList( regExpression );
+   long numberOfSources = keys.size();
+   ossim_uint32 offset = (copyPrefix+"elevation_source").size();
+   ossim_uint32 idx = 0;
+   std::vector<int> theNumberList(numberOfSources);
+   for(idx = 0; idx < theNumberList.size();++idx)
+   {
+      ossimString numberStr(keys[idx].begin() + offset,
+                            keys[idx].end());
+      theNumberList[idx] = numberStr.toInt();
+   }
+   std::sort(theNumberList.begin(), theNumberList.end());
+   
+   for(idx=0;idx < theNumberList.size();++idx)
+   {
+      ossimString newPrefix = copyPrefix;
+      newPrefix += ossimString("elevation_source");
+      newPrefix += ossimString::toString(theNumberList[idx]);
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::loadState:"
+            << "\nLooking for key:  " << newPrefix
+            << std::endl;
+      }
+      ossimString fileKey = newPrefix;
+      fileKey += ".";
+      fileKey += ossimKeywordNames::FILENAME_KW;
+      lookup = kwl.find(prefix, fileKey.c_str());
+      if (lookup)
+      {
+         ossimFilename file = lookup;
+         
+         // Lookup the type.
+         ossimString typeKey = newPrefix;
+         typeKey += ".";
+         typeKey += ossimKeywordNames::TYPE_KW;
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimElevManager::loadState:"
+               << "\nLooking for key:  " << typeKey
+               << std::endl;
+         }
+         
+         lookup = kwl.find(prefix, typeKey.c_str());
+         if (lookup)
+         {
+            ossimString type = lookup;
+            if (type == "dted_cell")
+            {
+               openDtedCell(file);
+            }
+            else if (type == "srtm_cell")
+            {
+               openSrtmCell(file);
+            }
+            else if (type == "dted_directory")
+            {
+               addDtedFactory(file);
+            }
+            else if (type == "srtm_directory")
+            {
+               addSrtmFactory(file);
+            }
+         }
+         else // No "type" specified, try to auto detect.
+         {
+            if(!file.isDir())
+            {
+               openCell(file);
+            }
+            else
+            {
+               if ( isDtedDirectory(file) )
+               {
+                  addDtedFactory(file);
+               }
+               
+               else if ( isSrtmDirectory(file) )
+               {
+                  addSrtmFactory(file);
+               }
+            }
+//             ossimString tempFile = file;
+//             if(!file.isFile())
+//             {
+//                tempFile += ".gz";
+//             }
+//             if (tempFile.isFile())
+//             {
+//                if ( isSrtmFilenameFormat(tempFile) )
+//                {
+//                   openSrtmCell(file);
+//                }
+//                else if ( isDtedFilenameFormat(file) )
+//                {
+//                   openDtedCell(file);
+//                }
+//             }
+//             else // Directory...
+//             {
+//                if ( isDtedDirectory(file) )
+//                {
+//                   addDtedFactory(file);
+//                }
+               
+//                else if ( isSrtmDirectory(file) )
+//                {
+//                   addSrtmFactory(file);
+//                }
+//             }
+         }
+      } // end if lookup
+   } // end for loop
+#if 0      
+   // Find any cells using "elevation_source" keyword.
+    count =  kwl.numberOf(ossimKeywordNames::ELEVATION_SOURCE_KW);
+    if (count)
+    {
+      //---
+      // Look for numbered keyword like "elevation_source1",
+      // "elevation_source2" and so on.
+      //---
+      ossim_uint32 sourceNumber = 0;
+      ossim_uint32 found = 0;
+      while ((found < count) && (sourceNumber < 10000) )
+      {
+         ossimString key = ossimKeywordNames::ELEVATION_SOURCE_KW;
+         key += ossimString::toString(sourceNumber);
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimElevManager::loadState:"
+               << "\nLooking for key:  " << key
+               << std::endl;
+         }
+
+         ossimString fileKey = key;
+         fileKey += ".";
+         fileKey += ossimKeywordNames::FILENAME_KW;
+
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimElevManager::loadState:"
+               << "\nLooking for key:  " << fileKey
+               << std::endl;
+         }
+         
+         lookup = kwl.find(prefix, fileKey.c_str());
+         if (lookup)
+         {
+            ++found;
+            ossimFilename file = lookup;
+
+            // Lookup the type.
+            ossimString typeKey = key;
+            typeKey += ".";
+            typeKey += ossimKeywordNames::TYPE_KW;
+
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "DEBUG ossimElevManager::loadState:"
+                  << "\nLooking for key:  " << typeKey
+                  << std::endl;
+            }
+
+            lookup = kwl.find(prefix, typeKey.c_str());
+            if (lookup)
+            {
+               ++found;
+               
+               ossimString type = lookup;
+               if (type == "dted_cell")
+               {
+                  openDtedCell(file);
+               }
+               else if (type == "srtm_cell")
+               {
+                  openSrtmCell(file);
+               }
+               else if (type == "dted_directory")
+               {
+                  addDtedFactory(file);
+               }
+               else if (type == "srtm_directory")
+               {
+                  addSrtmFactory(file);
+               }
+            }
+            else // No "type" specified, try to auto detect.
+            {
+               if (file.isFile())
+               {
+                  if ( isDtedFilenameFormat(file) )
+                  {
+                     openSrtmCell(file);
+                  }
+                  else if ( isSrtmFilenameFormat(file) )
+                  {
+                     openDtedCell(file);
+                  }
+               }
+               else // Directory...
+               {
+                  if ( isDtedDirectory(file) )
+                  {
+                     addDtedFactory(file);
+                  }
+                     
+                  else if ( isSrtmDirectory(file) )
+                  {
+                     addSrtmFactory(file);
+                  }
+               }
+            }
+         }
+         
+         ++sourceNumber;
+         
+      } // End of "while ((found < count) && (sourceNumber < 10000) )"
+    }// End of "if (count)" ELEVATION_SOURCE_KW
+#endif
+    //---
+    // Below is only here for backwards compatibility.
+   
+   //***
+   // Find any dted cells.
+   //***
+   const char DTED_CELL_KW[] = "dted_cell";
+   
+   // int number_of_cells = kwl.numberOf(prefix, DTED_CELL_KW);
+   int number_of_cells = kwl.numberOf(DTED_CELL_KW);
+
+   if (number_of_cells)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "DEBUG ossimElevManager::loadState: "
+            << "\nNumber of cells = " << number_of_cells
+            << std::endl;
+      }
+      
+      int count = 0;
+   
+      // Look for just the keyword "dted_cell" with no number appended to it.
+      lookup = kwl.find(prefix, DTED_CELL_KW);
+      if (lookup)
+      {
+         ++count;
+         ossimFilename f = lookup;
+         openDtedCell(f);
+      }
+   
+      // Look for numbered keyword like "dted_cell1".
+      int cell_number = 0;
+      while ((count < number_of_cells) &&
+             (cell_number < 1000) )
+      {
+         ossimString key = DTED_CELL_KW;
+         key += ossimString::toString(cell_number);
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimElevManager::loadState:"
+               << "\nLooking for key:  " << key
+               << std::endl;
+         }
+         
+         lookup = kwl.find(prefix, key);
+         if (lookup)
+         {
+            ++count;
+            
+            ossimFilename f = lookup;
+            openDtedCell(f);
+         }
+      
+         ++cell_number;
+         
+      }  // End of "while (count < number_of_cells)"
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::loadState:"
+            << "\nNo dted_cell found in the keyword list."
+            << std::endl;
+      }
+   }
+   
+   // Add any factories for dted_directory  keyword:
+   addDtedFactories(kwl, prefix);
+
+   // Add any factories for srtm_directory keyword:
+   addSrtmFactories(kwl, prefix);
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevManager::loadState:"
+         << "\nElevation is:  "
+         << (isSourceEnabled()?"enabled":"disabled")
+         << "\nAuto elevation loading is:  "
+         << (isAutoLoadEnabled()?"enabled":"disabled")
+         << "\nAuto sorting of elevation is:  "
+         << (isAutoSortEnabled()?"enabled":"disabled")
+         << "\ntheDefaultElevationPath = "
+         << theDefaultElevationPath
+         << "DEBUG ossimElevManager::loadState: Exited..."
+         << std::endl;
+   }
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevManager::loadState: Exited..." << std::endl;
+   }
+   
+   return true;
+}
+
+bool ossimElevManager::saveState(ossimKeywordlist& kwl,
+                                 const char* prefix) const
+{
+   ossim_uint32 sourceNumber = 1;
+
+   // Save the cells.
+   ossimElevSourceListConstIterator s = theElevSourceList.begin();
+   while (s != theElevSourceList.end())
+   {
+      ossimString keywordBase = ossimKeywordNames::ELEVATION_SOURCE_KW;
+      keywordBase += ossimString::toString(sourceNumber);
+      
+      ossimString typeKw = keywordBase;
+      typeKw += ".";
+      typeKw += ossimKeywordNames::TYPE_KW;
+      
+      ossimString filenameKw = keywordBase;
+      filenameKw += ".";
+      filenameKw += ossimKeywordNames::FILENAME_KW;
+      
+      kwl.add(prefix, filenameKw.c_str(), (*s)->getFilename());
+      if ((*s)->getClassName() == "ossimDtedHandler")
+      {
+         kwl.add(prefix, typeKw.c_str(), "dted_cell");
+      }
+      else if ((*s)->getClassName() == "ossimSrtmHandler")
+      {
+         kwl.add(prefix, typeKw.c_str(), "strm_cell");
+      }
+      ++s;
+      ++sourceNumber;
+   }
+
+   // Save the factories.
+   ossimElevSourceFactoryConstIterator f = theElevSourceFactoryList.begin();
+
+   while (f != theElevSourceFactoryList.end())
+   {
+      ossimString keywordBase = ossimKeywordNames::ELEVATION_SOURCE_KW;
+      keywordBase += ossimString::toString(sourceNumber);
+      
+      ossimString typeKw = keywordBase;
+      typeKw += ".";
+      typeKw += ossimKeywordNames::TYPE_KW;
+      
+      ossimString filenameKw = keywordBase;
+      filenameKw += ".";
+      filenameKw += ossimKeywordNames::FILENAME_KW;
+
+      kwl.add(prefix, filenameKw.c_str(), (*f)->getDirectory());
+      
+      if ((*f)->getClassName() == "ossimDtedFactory")
+      {
+         kwl.add(prefix, typeKw.c_str(), "dted_directory");
+      }
+      else if ((*f)->getClassName() == "ossimSrtmFactory")
+      {
+         kwl.add(prefix, typeKw.c_str(), "strm_directory");
+      }
+      
+      ++f;
+      ++sourceNumber;
+   }
+   
+   return true;
+}
+
+void ossimElevManager::loadElevData(const ossimDrect& ground_rect)
+{
+   //***
+   // NOT YET IMPLEMENTED. DEM Loading will occur when height is requested.
+   // list until 
+   //***
+}
+
+double ossimElevManager::getHeightAboveMSL(const ossimGpt& gpt)
+{
+   
+   if (theEnableFlag)
+   {
+      ossimScopedLock<ossimMutex> scopedLock(theMutex);
+      //***
+      // Search through the list of elevation sources for a valid elevation
+      // post.
+      //***
+      ossimElevSourceListIterator s = theElevSourceList.begin();
+      while (s != theElevSourceList.end())
+      {
+         double d = (*s)->getHeightAboveMSL(gpt);
+         if (d != (*s)->getNullHeightValue())
+         {
+            return  d;
+         }
+         (*s)->close();  // Close to keep file descriptors down.
+         ++s;
+      }
+      
+      if (theAutoLoadFlag)
+      {
+         //
+         // If we got here there were no sources in the list that contained
+         // coverage so go through the list of managers and see if they have
+         // coverage.
+         //
+         ossimElevSourceFactoryConstIterator sf =
+            theElevSourceFactoryList.begin();
+
+         while (sf != theElevSourceFactoryList.end())
+         {
+            ossimElevSource* source = (*sf)->getNewElevSource(gpt);
+            if (source)
+            {
+               theMutex.unlock();
+               // Add it to the list.
+               addElevSource(source);
+               
+               theMutex.lock();
+               
+               double d = source->getHeightAboveMSL(gpt);
+               if (d != source->getNullHeightValue())
+               {
+                  return d;
+               }
+               else
+               {
+                  return theNullHeightValue;
+               }
+            }
+            ++sf;
+         }
+      }
+      
+   }  // End of "if (isSourceEnabled())"
+   
+   // If we get here return a null height value.
+   return theNullHeightValue;
+}
+
+double ossimElevManager::getHeightAboveEllipsoid(const ossimGpt& gpt)
+{
+   if (theEnableFlag)
+   {
+      // Fetch the geoid offset first:
+      double d = theGeoidManager->offsetFromEllipsoid(gpt);
+      
+      if (d != OSSIM_DBL_NAN)
+      {
+         double h = getHeightAboveMSL(gpt);
+         if (h != theNullHeightValue)
+         {
+            return  (h + d);
+         }
+         else
+         {
+            return d;
+         }
+      }
+   }
+
+   return theNullHeightValue;
+}
+
+double ossimElevManager::getAccuracyCE90(const ossimGpt& gpt) const
+{
+   // return theDtedManager->getAccuracyCE90(gpt);
+   return 0.0;
+}
+
+double ossimElevManager::getAccuracyLE90(const ossimGpt& gpt) const
+{
+   // return theDtedManager->getAccuracyLE90(gpt);
+   return 0.0;
+}
+
+double ossimElevManager::getMeanSpacingMeters() const
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimElevManager::getMeanSpacingMeters: not implemented..."
+         << std::endl;
+   }
+   return 0.0;
+}
+
+bool ossimElevManager::pointHasCoverage(const ossimGpt& gpt) const
+{
+   // return theDtedManager->pointHasCoverage(gpt);
+   return 0.0;
+}
+
+void ossimElevManager::addElevSource(ossimElevSource* source)
+{
+   // Add it to the list...
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_INFO)
+         << "INFO ossimElevManager::addElevSource: Opened cell "
+         << source->getFilename().c_str() << std::endl;
+   }
+   
+   theElevSourceList.push_back(source);
+   
+   if (theAutoSortFlag)
+   {
+      // Sort by highest resolution.
+      sort(theElevSourceList.begin(),
+           theElevSourceList.end(),
+           ossimElevLess());
+   }
+
+   // Update the min / max values.
+   updateMinMax();
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevManager::addElevSource Sorted elevation sources:"
+         << std::endl;
+      
+      int index = 0;
+      ossimElevSourceListConstIterator s = theElevSourceList.begin();
+      while (s != theElevSourceList.end())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Elevation source[" << index << "]:  "
+            << (*s)->getFilename().c_str() << std::endl;
+         ++s;
+         ++index;
+      }
+   }
+
+   ossimElevationManagerEvent event( this );
+
+   fireEvent( event );
+}
+
+void ossimElevManager::updateMinMax()
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevManager::updateMinMax: "
+         << "\nInitial min height above MSL:  " << theMinHeightAboveMSL
+         << "\nInitial max height above MSL:  " << theMaxHeightAboveMSL
+         << std::endl;
+   }
+
+   double BOGUS_MIN = 100000.0;
+   double BOGUS_MAX = -100000.0;
+   double min_value = BOGUS_MIN;
+   double max_value = BOGUS_MAX;
+   
+   ossimElevSourceListConstIterator s = theElevSourceList.begin();
+   while (s != theElevSourceList.end())
+   {
+      double s_min = (*s)->getMinHeightAboveMSL();
+      double s_max = (*s)->getMaxHeightAboveMSL();
+
+      if (s_min < min_value) min_value = s_min;
+      if (s_max > max_value) max_value = s_max;
+      ++s;
+   }
+
+   // Don't asign if unless something was found...
+   if (min_value != BOGUS_MIN) theMinHeightAboveMSL = min_value;
+   if (max_value != BOGUS_MAX) theMaxHeightAboveMSL = max_value;
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevManager::updateMinMax:\n"
+         << "Updated min height above MSL:  " << theMinHeightAboveMSL
+         << "\nUpdated max height above MSL:  " << theMaxHeightAboveMSL
+         << std::endl;
+   }
+}
+
+void ossimElevManager::addElevSourceFactory(ossimRefPtr<ossimElevSourceFactory> source)
+{
+   theElevSourceFactoryList.push_back(source);
+}
+
+void ossimElevManager::enableAutoLoad()
+{
+   theAutoLoadFlag = true;
+}
+
+void ossimElevManager::disableAutoLoad()
+{
+   theAutoLoadFlag = false;
+}
+
+bool ossimElevManager::isAutoLoadEnabled() const
+{
+   return theAutoLoadFlag;
+}
+
+void ossimElevManager::enableAutoSort()
+{
+   theAutoSortFlag = true;
+}
+
+void ossimElevManager::disableAutoSort()
+{
+   theAutoSortFlag = false;
+}
+
+bool ossimElevManager::isAutoSortEnabled() const
+{
+   return theAutoSortFlag;
+}
+
+ossimRefPtr<ossimElevSourceFactory> ossimElevManager::findFactoryFromDir(const ossimFilename& dir)
+{
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theElevSourceFactoryList.size(); ++idx)
+   {
+      if(theElevSourceFactoryList[idx]->getDirectory() == dir)
+      {
+         return theElevSourceFactoryList[idx];
+      }
+   }
+   
+   return ossimRefPtr<ossimElevSourceFactory>();
+}
+
+const ossimRefPtr<ossimElevSourceFactory> ossimElevManager::findFactoryFromDir(const ossimFilename& dir)const
+{
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theElevSourceFactoryList.size(); ++idx)
+   {
+      if(theElevSourceFactoryList[idx]->getDirectory() == dir)
+      {
+         return theElevSourceFactoryList[idx];
+      }
+   }
+   
+   return ossimRefPtr<ossimElevSourceFactory>();
+}
+
+
+bool ossimElevManager::isCellOpen(const ossimFilename& cell) const
+{
+   bool result = false;
+
+   if (cell == ossimFilename::NIL) return result;
+   
+   ossimElevSourceListConstIterator s = theElevSourceList.begin();
+   while (s != theElevSourceList.end())
+   {
+      if (cell == (*s)->getFilename())
+      {
+         result = true;
+         break;
+      }
+      ++s;
+   }
+   
+   return result;
+}
+
+bool ossimElevManager::openCell(const ossimFilename& cell)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevManager::openCell: Entered..."
+         << "\nCell:  " << cell << std::endl;
+   }
+
+   if (cell == ossimFilename::NIL) return false;
+
+   ossimFilename tempFile = cell;
+   if(!tempFile.isFile())
+   {
+      tempFile += ".gz";
+   }
+   if(!tempFile.isFile()) return false;
+   
+   if (isDtedFilenameFormat(tempFile))
+   {
+      return openDtedCell(tempFile);
+   }
+   else if (isSrtmFilenameFormat(tempFile))
+   {
+      return openSrtmCell(tempFile);
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevManager::openCell:\n"
+         << "Could not open:  " << cell 
+         << std::endl;
+   }
+   
+   return false;
+}
+
+bool ossimElevManager::openDirectory(const ossimFilename& dir)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG  ossimElevManager::openDirectory Entered..."
+         << "\nDirectory:  " << dir << std::endl;
+   }
+
+   if (dir == ossimFilename::NIL || !dir.isDir()) return false;
+
+   ossimDirectory od(dir);
+
+   if (od.isOpened() == false) return false;
+
+   ossimFilename f;
+
+   bool result = false;
+   
+   if (od.getFirst(f, ossimDirectory::OSSIM_DIR_FILES))
+   {
+      do
+      {
+         if (openCell(f) == true)
+         {
+            result = true;
+         }
+      } while (od.getNext(f));
+   }
+   
+   return result;
+}
+
+bool ossimElevManager::closeCell(const ossimFilename& cell)
+{
+   if (cell == ossimFilename::NIL) return false;
+   
+   ossimElevSourceListIterator s = theElevSourceList.begin();
+   while (s != theElevSourceList.end())
+   {
+      if (cell == (*s)->getFilename())
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "Closed cell:  " << (*s)->getFilename().c_str()
+               << std::endl;
+         }
+         theElevSourceList.erase(s);
+         return true;
+      }
+      ++s;
+   }
+   
+   return false;
+}
+
+void ossimElevManager::closeAllCells()
+{
+   ossimElevSourceListIterator s = theElevSourceList.begin();
+   while (s != theElevSourceList.end())
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Closed cell:  " << (*s)->getFilename().c_str() << std::endl;
+      }
+      ++s;
+   }
+
+   theElevSourceList.clear();
+}
+
+void ossimElevManager::getOpenCellList(std::vector<ossimFilename>& list) const
+{
+   list.clear();
+   
+   ossimElevSourceListConstIterator s = theElevSourceList.begin();
+
+   while (s != theElevSourceList.end())
+   {
+      list.push_back((*s)->getFilename());
+      ++s;
+   }
+}
+
+ossimFilename ossimElevManager::getDefaultElevationPath() const
+{
+   return theDefaultElevationPath;
+}
+
+void ossimElevManager::setDefaultElevationPath(const ossimFilename& path)
+{
+   theDefaultElevationPath = path;
+}
+
+bool ossimElevManager::moveCellUpOne(const ossimFilename& cell)
+{
+   if (cell == ossimFilename::NIL) return false;
+
+   ossimElevSourceListIterator a = theElevSourceList.begin();
+   ossimElevSourceListIterator b = a;
+   ++b;
+   while (b != theElevSourceList.end())
+   {
+      if ( cell == (*b)->getFilename() )
+      {
+         iter_swap(a, b);
+         return true;
+      }
+      ++a;
+      ++b;
+   }
+   
+   return false;
+}
+
+bool ossimElevManager::moveCellDownOne(const ossimFilename& cell)
+{
+   if (cell == ossimFilename::NIL) return false;
+
+   ossimElevSourceListIterator a = theElevSourceList.begin();
+   ossimElevSourceListIterator b = a;
+   ++b;
+   while (b != theElevSourceList.end())
+   {
+      if ( cell == (*a)->getFilename() )
+      {
+         iter_swap(a, b);
+         return true;
+      }
+      ++a;
+      ++b;
+   }
+   
+   return false;
+}
+
+bool ossimElevManager::moveCellToTop(const ossimFilename& cell)
+{
+   if (cell == ossimFilename::NIL) return false;
+
+   ossimElevSourceListIterator a = theElevSourceList.begin();
+   ossimElevSourceListIterator b = a;
+   ++b;
+   while (b != theElevSourceList.end())
+   {
+      if ( cell == (*b)->getFilename() )
+      {
+         ossimFilename f = (*b)->getFilename();
+         while (moveCellUpOne(f) == true){}
+         return true;
+      }
+      ++b;
+   }
+   
+   return false;
+}
+
+bool ossimElevManager::moveCellToBottom(const ossimFilename& cell)
+{
+   if (cell == ossimFilename::NIL) return false;
+
+   ossimElevSourceListIterator a = theElevSourceList.begin();
+   ossimElevSourceListIterator b = theElevSourceList.end();
+   --b;
+   while (a != b)
+   {
+      if ( cell == (*a)->getFilename() )
+      {
+         ossimFilename f = (*a)->getFilename();
+         while (moveCellDownOne(f) == true){}
+         return true;
+      }
+      ++a;
+   }
+   
+   return false;
+}
+
+void ossimElevManager::addDtedFactories(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   //---
+   // Find the dted direcories to search in.
+   // We'll capture these regardless of being enabled in case someone wants to
+   // turn on the autoload midstream in a program.
+   //---
+   const char DTED_DIRECTORY_KW[] = "dted_directory";
+   
+   int number_of_directories = kwl.numberOf(DTED_DIRECTORY_KW);
+   
+   if (number_of_directories)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::addDtedFactories:"
+            << "\nNumber of dirs = " << number_of_directories
+            << std::endl;
+      }
+      
+      int count = 0;
+      
+      //---
+      // Look for just the keyword "dted_directory" with no number appended
+      // to it.
+      //
+      const char* lookup = kwl.find(prefix, DTED_DIRECTORY_KW);
+      if (lookup)
+      {
+         ++count;
+         ossimFilename f = lookup;
+         addDtedFactory(f);
+      }
+      
+      // Look for numbered keyword like "dted_directory1".
+      int dir_number = 0;
+      while ((count < number_of_directories) &&
+             (dir_number < 1000) )
+      {
+         ossimString key = DTED_DIRECTORY_KW;
+         key += ossimString::toString(dir_number);
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimElevManager::addDtedFactories:"
+               << "\nLooking for key:  " << key
+               << std::endl;
+         }
+         
+         lookup = kwl.find(prefix, key);
+         if (lookup)
+         {
+            ++count;
+            ossimFilename f = lookup;
+            addDtedFactory(f);
+         }
+         
+         ++dir_number;
+         
+      } // End of "while (count < number_of_directories)"
+      
+   } // End of "if (number_of_directories)
+   else
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::addDtedFactories::"
+            << "\nNo dted_directories found in the keyword list."
+            << std::endl;
+      }
+   }
+   
+}
+
+void ossimElevManager::addSrtmFactories(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   //---
+   // Find the srtm direcories to search in.
+   // We'll capture these regardless of being enabled in case someone wants to
+   // turn on the autoload midstream in a program.
+   //---
+   const char SRTM_DIRECTORY_KW[] = "srtm_directory";
+   
+   int number_of_directories = kwl.numberOf(SRTM_DIRECTORY_KW);
+   
+   if (number_of_directories)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::addSrtmFactories:"
+            << "\nNumber of dirs = " << number_of_directories
+            << std::endl;
+      }
+      
+      int count = 0;
+      
+      //---
+      // Look for just the keyword "srtm_directory" with no number appended
+      // to it.
+      //---
+      const char* lookup = kwl.find(prefix, SRTM_DIRECTORY_KW);
+       if (lookup)
+       {
+          ++count;
+          ossimFilename f = lookup;
+          
+          if (f.isDir())
+          {
+             // Add a srtm factory for this directory.
+             ossimRefPtr<ossimElevSourceFactory> factory = new ossimSrtmFactory(f);
+             addElevSourceFactory(factory);
+             if (traceDebug())
+             {
+                ossimNotify(ossimNotifyLevel_DEBUG)
+                   << "Added elevation factory for:  " << f.c_str()
+                   << std::endl;
+             }
+          }
+       }
+       
+       // Look for numbered keyword like "srtm_directory1".
+       int dir_number = 0;
+       while ((count < number_of_directories) &&
+              (dir_number < 1000) )
+       {
+          ossimString key = SRTM_DIRECTORY_KW;
+          key += ossimString::toString(dir_number);
+          
+          if (traceDebug())
+          {
+             ossimNotify(ossimNotifyLevel_DEBUG)
+                << "DEBUG ossimElevManager::addSrtmFactories:"
+                << "\nLooking for key:  " << key
+                << std::endl;
+          }
+          
+          lookup = kwl.find(prefix, key);
+          if (lookup)
+          {
+             ++count;
+             
+             ossimFilename f = lookup;
+             if (f.isDir())
+             {
+                // Add a srtm factory for this directory.
+                ossimRefPtr<ossimElevSourceFactory> factory = new ossimSrtmFactory(f);
+                addElevSourceFactory(factory);
+                
+                if (traceDebug())
+                {
+                   ossimNotify(ossimNotifyLevel_DEBUG)
+                      << "Added srtm factory for:  " << f.c_str() << std::endl;
+                }
+             }
+          }
+          
+          ++dir_number;
+          
+       } // End of "while (count < number_of_directories)"
+       
+   } // End of "if (number_of_directories)
+   else
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::addSrtmFactories::"
+            << "\nNo srtm_directories found in the keyword list."
+            << std::endl;
+      }
+   }
+}
+
+bool ossimElevManager::isDtedFilenameFormat(const ossimFilename& file) const
+{
+   // Format example: "n32.dt2"
+   
+   // Strip any path away.
+   ossimFilename f = file.file();
+
+   // Downcase it.
+   f.downcase();
+
+   // Must be seven characters long.
+   if (f.size() != 7)
+   {
+      return false;
+   }
+
+   // Must start with 'n' or 's'.
+   if ( (f[0] != 'n') && (f[0] != 's') )
+   {
+      return false;
+   }
+
+   // Fourth character must be a dot '.'.
+   if (f[3] != '.')
+   {
+      return false;
+   }
+
+   // Fith character must be a 'd'.
+   if (f[4] != 'd')
+   {
+      return false;
+   }
+
+   // Sixth character must be a 't'.
+   if (f[5] != 't')
+   {
+      return false;
+   }
+
+   return true;
+}
+
+bool ossimElevManager::isSrtmFilenameFormat(const ossimFilename& file) const
+{
+   // Format example:  "N37W120.hgt"
+   // or N37W120.hgt.gz
+   
+   // Strip any path away.
+   ossimFilename f = file.file();
+
+   // Downcase it.
+   f.downcase();
+
+   // Must be eleven characters long. or if it's gzipped then
+   // it can be 14 characters lond with the .gz added extension
+   //
+   if ((f.size() != 11)&&
+       (f.size() != 14))
+   {
+      return false;
+   }
+
+   // Must start with 'n' or 's'.
+   if ( (f[0] != 'n') && (f[0] != 's') )
+   {
+      return false;
+   }
+
+   // Fourth character must be 'e' or 'w'.
+   if ( (f[3] != 'e') && (f[3] != 'w') )
+   {
+      return false;
+   }
+
+   // Eight character must be a dot '.'.
+   if (f[7] != '.')
+   {
+      return false;
+   }
+
+   if(!f.contains(".hgt")&&
+      !f.contains(".hgt.gz"))
+   {
+      return false;
+   }
+   // Extension must be "hgt".
+//    if (f.ext() != "hgt")
+//    {
+//       return false;
+//    }
+
+   return true;
+}
+
+
+bool ossimElevManager::isDtedDirectory(const ossimFilename& dir) const
+{
+   //---
+   // Sample format
+   //                          dir
+   //                    |            |
+   //                 e040            e041
+   //              |        |        |       |
+   //            n31.dt2 n32.dt2  n31.dt2 n32.dt2
+   //---
+   if (!dir.isDir())
+   {
+      return false;
+   }
+
+   ossimDirectory od(dir);
+   if (od.isOpened() == false)
+   {
+      return false;
+   }
+
+   ossimFilename f;
+   // Get the first directory.
+   od.getFirst(f, ossimDirectory::OSSIM_DIR_DEFAULT);
+
+   do
+   {
+      // Must be a directory.
+      if (f.isDir())
+      {
+         
+         // Discard any full path.
+         f = f.file();
+         
+         // Downcase it.
+         f.downcase();
+         
+         // Must start with 'e' or 'w'.
+         if ( ((f.c_str()[0] == 'e') || ( f.c_str()[0] == 'w')) &&
+              (f.size() == 4))
+         {
+            return true;
+         }
+      }
+   }while(od.getNext(f));
+   
+   return false;
+}
+
+bool ossimElevManager::isSrtmDirectory(const ossimFilename& dir) const
+{
+   //---
+   // Sample format:
+   //            dir
+   //         |          |
+   //    N35W121.hgt N35W121.hgt
+   //---
+   if (!dir.isDir())
+   {
+      return false;
+   }
+
+   ossimDirectory od(dir);
+   if (od.isOpened() == false)
+   {
+      return false;
+   }
+
+   ossimFilename f;
+
+   if(od.getFirst(f, ossimDirectory::OSSIM_DIR_FILES))
+   {
+      do
+      {
+         if(isSrtmFilenameFormat(f))
+         {
+            return true;
+         }
+      }while(od.getNext(f));
+   }
+
+   
+   return isSrtmFilenameFormat(f);
+}
+
+bool ossimElevManager::openDtedCell(const ossimFilename& file)
+{
+   if (isCellOpen(file))
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::openDtedCell:\n"
+            << file << " has already been opened by the manager."
+            << std::endl;
+      }
+
+      return false;
+   }
+   
+   ossimElevSource* source = new ossimDtedHandler(file);
+   if (source->getErrorStatus() == ossimErrorCodes::OSSIM_OK)
+   {
+      // Add the source to the list.
+      addElevSource(source);
+      
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::openDtedCell:"
+            << "\nAdded dted cell:  " << file << std::endl;
+      }
+   }
+   else
+   {
+      delete source;
+      return false;
+   }
+   return true;
+}
+
+bool ossimElevManager::openSrtmCell(const ossimFilename& file)
+{
+   if (isCellOpen(file))
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::openSrtmCell:\n"
+            << file << " has already been opened by the manager."
+            << std::endl;
+      }
+      return false;
+   }
+   
+   ossimElevSource* source = new ossimSrtmHandler(file);
+   if (source->getErrorStatus() == ossimErrorCodes::OSSIM_OK)
+   {
+      // Add the source to the list.
+      addElevSource(source);
+      
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimElevManager::openSrtmCell:"
+            << "\nAdded srtm cell:  " << file << std::endl;
+      }
+   }
+   else
+   {
+      delete source;
+      return false;
+   }
+   return true;
+}
+
+void ossimElevManager::addDtedFactory(const ossimFilename& file)
+{
+   // Add a dted factory for this directory.
+   ossimRefPtr<ossimElevSourceFactory> factory = new ossimDtedFactory(file);
+   addElevSourceFactory(factory);
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimElevManager::addDtedFactory:"
+         << "\nAdded elevation factory for:  " << file.c_str()
+         << std::endl;
+   }
+}
+
+void ossimElevManager::addSrtmFactory(const ossimFilename& file)
+{
+   ossimRefPtr<ossimElevSourceFactory> factory = new ossimSrtmFactory(file);
+   addElevSourceFactory(factory);
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "Added elevation factory for:  " << file.c_str()
+         << std::endl;
+   }
+}
+
diff --git a/Utilities/OSSIM/ossim_core/elevation/ossimElevManager.h b/Utilities/OSSIM/ossim_core/elevation/ossimElevManager.h
new file mode 100644
index 0000000000..3211341f0c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/ossimElevManager.h
@@ -0,0 +1,331 @@
+//*****************************************************************************
+// FILE: ossimElevManager.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimElevManager. This object provides a
+//   single interface to an imaging chain for accessing multiple elevation
+//   sources. This object owns one or more elevation sources in an ordered
+//   list. When queried for an elevation at a particular point, it searches
+//   the available sources for the best result, instantiating new sources if
+//   necessary.
+//
+// SOFTWARE HISTORY:
+//>
+//   13Apr2001  Oscar Kramer
+//              Initial coding.
+//<
+//*****************************************************************************
+#ifndef ossimElevManager_HEADER
+#define ossimElevManager_HEADER
+
+#include <vector>
+#include <elevation/ossimElevSource.h>
+#include <base/common/ossimMutex.h>
+#include <elevation/ossimElevSourceFactory.h>
+
+class ossimDrect;
+class ossimKeywordlist;
+class ossimElevHandler;
+class ossimGeoidManager;
+
+// class ossimDtedManager;
+
+/*!****************************************************************************
+ * CLASS:  ossimElevManager
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimElevManager : public ossimElevSource
+{
+public:
+   virtual ~ossimElevManager();
+   
+   /*!
+    * METHOD: instance()
+    * Implements singelton pattern
+    */
+   static ossimElevManager* instance();
+
+   /*!
+    * Height access methods:
+    * Return OSSIM_DBL_NAN if point is not found.
+    */
+   virtual double getHeightAboveMSL(const ossimGpt& gpt);
+   virtual double getHeightAboveEllipsoid(const ossimGpt& gpt);
+
+   /*!
+    * Method to check if the ground point elevation is defined:
+    */
+   virtual bool pointHasCoverage(const ossimGpt& gpt) const;
+
+   /*!
+    * Method to load new elevation data given ground rectangle:
+    */
+   void loadElevData(const ossimDrect& ground_rect);
+
+   /*!
+    * METHODS: accuracyLE90(), accuracyCE90()
+    * Returns the vertical and horizontal accuracy (90% confidence) in the
+    * region of gpt:
+    */
+   virtual double getAccuracyLE90(const ossimGpt& gpt) const;
+   virtual double getAccuracyCE90(const ossimGpt& gpt) const;
+
+   /*!
+    * METHOD: meanSpacingMeters() const
+    * Returns the mean spacing in meters between posts in the region of gpt.
+    */
+   virtual double getMeanSpacingMeters() const;
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual void addElevSource(ossimElevSource* source);
+   virtual void addElevSourceFactory(
+      ossimRefPtr<ossimElevSourceFactory> factory);
+   
+   // Auto loading control...
+   virtual void enableAutoLoad();
+   virtual void disableAutoLoad();
+   virtual bool isAutoLoadEnabled() const;
+
+   /*!
+    * Auto sorting control...
+    * Auto sorting sorts cell on add by mean post spacing putting cells with
+    * lowest(best) post spacing at the top.
+    */
+   virtual void enableAutoSort();
+   virtual void disableAutoSort();
+   virtual bool isAutoSortEnabled() const;
+
+   /*!
+    * METHOD:  bool isCellOpen(const ossimFilename& cell) const
+    * Returns true if cell is currently opened(in theElevSourceList).
+    */
+   virtual bool isCellOpen(const ossimFilename& cell) const;
+
+   virtual ossimRefPtr<ossimElevSourceFactory> findFactoryFromDir(
+      const ossimFilename& dir);
+   virtual const ossimRefPtr<ossimElevSourceFactory> findFactoryFromDir(
+      const ossimFilename& dir)const;
+   
+      
+   /*!
+    * METHOD: bool openDirectory(const ossimFilename& dir)
+    * Method to open a directory of elevation cells.
+    * Returns true on success, false on error.
+    */
+   virtual bool openDirectory(const ossimFilename& dir);
+
+   /*!
+    * METHOD: bool openCell(const ossimFilename& cell)
+    * Method to open an elevation cell.
+    * Returns true on success, false on error.
+    */
+   virtual bool openCell(const ossimFilename& cell);
+
+   /*!
+    * METHOD: bool closeCell(const ossimFilename& cell)
+    * Method to close an elevation cell.
+    * Returns true on success, false on error.
+    */
+   virtual bool closeCell(const ossimFilename& cell);
+
+   /*!
+    * METHOD: void closeAllCells()
+    * Method to close all open elevation cells.
+    */
+   virtual void closeAllCells();
+
+   /*!
+    * METHOD: bool moveCellUpOne(const ossimFilename& cell)
+    * Method to move an elevation cell on the list up by one.
+    * Returns true on success, false on error.
+    */
+   virtual bool moveCellUpOne(const ossimFilename& cell);
+
+   /*!
+    * METHOD: bool moveCellDownOne(const ossimFilename& cell)
+    * Method to move an elevation cell on the list down by one.
+    * Returns true on success, false on error.
+    */
+   virtual bool moveCellDownOne(const ossimFilename& cell);
+
+   /*!
+    * METHOD: bool moveCellToTop(const ossimFilename& cell)
+    * Method to move an elevation cell to the top of the list.
+    * Returns true on success, false on error.
+    */
+   virtual bool moveCellToTop(const ossimFilename& cell);
+
+   /*!
+    * METHOD: bool moveCellToBottomconst ossimFilename& cell)
+    * Method to move an elevation cell to the bottom of the list.
+    * Returns true on success, false on error.
+    */
+   virtual bool moveCellToBottom(const ossimFilename& cell);
+
+   /*!
+    * @param list List to initialize with open cells.
+    *
+    * @note list is clear prior to stuffing.
+    */
+   void getOpenCellList(std::vector<ossimFilename>& list) const;
+
+   ossimFilename getDefaultElevationPath() const;
+
+   void setDefaultElevationPath(const ossimFilename& path);
+
+protected:
+   typedef std::vector<ossimRefPtr<ossimElevSourceFactory> >::iterator ossimElevSourceFactoryIterator;
+   typedef std::vector<ossimRefPtr<ossimElevSourceFactory> >::const_iterator ossimElevSourceFactoryConstIterator;
+
+   typedef std::vector<ossimRefPtr<ossimElevSource> >::iterator ossimElevSourceListIterator;
+   typedef std::vector<ossimRefPtr<ossimElevSource> >::const_iterator ossimElevSourceListConstIterator;
+   
+   /*! Protected constructor. */
+   ossimElevManager();
+
+   void updateMinMax();
+
+   /**
+    * Searches keyword list for "elevation_directory" keywords and adds
+    * factories if found.  Will look for key words in this order.
+    *
+    * 1) "elevation_directory"
+    * 2) "elevation_directory0"
+    * 3) "elevation_directory1"
+    * ...
+    * ...
+    * Until count of all elevation_directory keywords is reached.
+    *
+    * @param kwl Keyword list to search.
+    *
+    * @prefix Prefix for keys.
+    */
+   void addElevFactories(const ossimKeywordlist& kwl, const char* prefix=0);
+
+   /**
+    * Searches keyword list for "dted_directory" keywords and adds factories
+    * if found.  Will look for key words in this order.
+    *
+    * 1) "dted_directory"
+    * 2) "dted_directory0"
+    * 3) "dted_directory1"
+    * ...
+    * ...
+    * Until count of all dted_directory keywords is reached.
+    *
+    * @param kwl Keyword list to search.
+    *
+    * @prefix Prefix for keys.
+    */
+   void addDtedFactories(const ossimKeywordlist& kwl, const char* prefix=0);
+
+   /**
+    * Searches keyword list for "srtm_directory" keywords and adds factories
+    * if found.  Will look for key words in this order.
+    *
+    * 1) "srtm_directory"
+    * 2) "srtm_directory0"
+    * 3) "srtm_directory1"
+    * ...
+    * ...
+    * Until count of all srtm_directory keywords is reached.
+    *
+    * @param kwl Keyword list to search.
+    *
+    * @prefix Prefix for keys.
+    */
+   void addSrtmFactories(const ossimKeywordlist& kwl, const char* prefix=0);
+   
+   /**
+    * Searches keyword list for "elevation_cell" keywords and adds
+    * factories if found.  Will look for key words in this order.
+    *
+    * 1) "elevation_cell"
+    * 2) "elevation_cell0"
+    * 3) "elevation_cell1"
+    * ...
+    * ...
+    * Until count of all elevation_cell keywords is reached.
+    *
+    * @param kwl Keyword list to search.
+    *
+    * @prefix Prefix for keys.
+    */
+   void addElevCells(const ossimKeywordlist& kwl, const char* prefix=0);
+
+   /**
+    * Method to determine if a file name is of dted format.
+    *
+    * @param f File to look at.
+    *
+    * @return true if dted format, false if not.
+    */
+   bool isDtedFilenameFormat(const ossimFilename& file) const;
+
+   /**
+    * Method to determine if a file name is of srtm format.
+    *
+    * @param f File to look at.
+    *
+    * @return true if dted format, false if not.
+    */
+   bool isSrtmFilenameFormat(const ossimFilename& file) const;
+
+   /**
+    * Method to determine if a directory is of dted structure.
+    *
+    * @param dir Directory to look at.
+    *
+    * @return true if dted directory structure, false if not.
+    */
+   bool isDtedDirectory(const ossimFilename& dir) const;
+
+   /**
+    * Method to determine if a directory looks like srtm.
+    *
+    * @param dir Directory to look at.
+    *
+    * @return true if srtm directory structure, false if not.
+    */
+   bool isSrtmDirectory(const ossimFilename& dir) const;
+
+   bool openDtedCell(const ossimFilename& file);
+
+   bool openSrtmCell(const ossimFilename& file);
+
+   void addDtedFactory(const ossimFilename& file);
+
+   void addSrtmFactory(const ossimFilename& file);
+   
+   /*!
+    * Data members:
+    */
+   static ossimElevManager*              theInstance;
+   std::vector<ossimRefPtr<ossimElevSource> >        theElevSourceList;
+   std::vector<ossimRefPtr<ossimElevSourceFactory> > theElevSourceFactoryList;
+   ossimGeoidManager*                    theGeoidManager;
+   bool                                  theAutoLoadFlag;
+   bool                                  theAutoSortFlag;
+   ossimFilename                         theDefaultElevationPath;
+   ossimMutex                            theMutex;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/elevation/ossimElevSource.cpp b/Utilities/OSSIM/ossim_core/elevation/ossimElevSource.cpp
new file mode 100644
index 0000000000..2bf61ee420
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/ossimElevSource.cpp
@@ -0,0 +1,265 @@
+//*****************************************************************************
+// FILE: ossimElevSource.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimElevSource. This is the base class
+//   for all sources of elevation data. it maintains a single common static
+//   instance of the geoid for use by all instances of objects derived from
+//   this one. 
+//
+// SOFTWARE HISTORY:
+//>
+//   18Apr2001  Oscar Kramer
+//              Initial coding.
+//<
+//*****************************************************************************
+// $Id: ossimElevSource.cpp,v 1.22 2005/11/17 17:22:58 gpotts Exp $
+
+#include <elevation/ossimElevSource.h>
+#include <base/common/ossimPreferences.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimEcefRay.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimElevSource, "ossimElevSource" , ossimSource)
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimElevSource:exec");
+static ossimTrace traceDebug ("ossimElevSource:debug");
+
+const double ossimElevSource::DEFAULT_NULL_HEIGHT = OSSIM_DBL_NAN;
+const double ossimElevSource::DEFAULT_SEA_LEVEL   = 0.0;
+
+static const char ENABLE_STATS_KW[] = "elevation.compute_statistics.enabled";
+
+ossimElevSource::ossimElevSource()
+   :
+      theMinHeightAboveMSL (0.0),
+      theMaxHeightAboveMSL (0.0),
+      theNullHeightValue   (DEFAULT_NULL_HEIGHT),
+      theSeaLevelValue     (DEFAULT_SEA_LEVEL),
+      theGroundRect(),
+      theComputeStatsFlag(true)
+   
+{
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevSource::ossimElevSource: entering..."
+         << std::endl;
+   }
+   
+   // User can turn on off with a keyword.
+   const char* lookup =
+      ossimPreferences::instance()->findPreference(ENABLE_STATS_KW);
+   if (lookup)
+   {
+     theComputeStatsFlag = ossimString(lookup).toBool();
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG:"
+         << "\ntheComputeStatsFlag:  "
+         << (theComputeStatsFlag?"true":"false")
+         << endl;
+   }
+
+
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimElevSource::ossimElevSource: returning..."
+         << std::endl;
+   }
+}
+
+ossimElevSource::~ossimElevSource()
+{}
+
+double ossimElevSource::getHeightAboveEllipsoid(const ossimGpt& argGpt)
+{
+   ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimElevSource::getHeightAboveEllipsoid Not implemented..."
+                                       << std::endl;
+   return theNullHeightValue;
+}
+
+//*****************************************************************************
+//  METHOD: intersectRay()
+//  
+//  Service method for intersecting a ray with the elevation surface to
+//  arrive at a ground point. The ray is expected to originate ABOVE the
+//  surface and pointing down.
+//
+//  NOTE: the gpt argument is expected to be initialized with the desired
+//  datum, including ellipsoid, for the proper intersection point to be
+//  computed.
+//
+//  LIMITATION: This release supports only single valued solutions, i.e., it
+//  is possible a ray passing through one side of a mountain and out the other
+//  will return an intersection with the far side. Eventually, a more robust
+//  algorithm will be employed.
+//
+//*****************************************************************************
+bool ossimElevSource::intersectRay(const ossimEcefRay& ray, ossimGpt& gpt)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimElevSource::intersectRay: entering..." << std::endl;
+
+   static const double CONVERGENCE_THRESHOLD = 0.001; // meters
+   static const int    MAX_NUM_ITERATIONS    = 50;
+   
+   double          h_ellips; // height above ellipsoid
+   bool            intersected;
+   ossimEcefPoint  prev_intersect_pt (ray.origin());
+   ossimEcefPoint  new_intersect_pt;
+   double          distance;
+   bool            done = false;
+   int             iteration_count = 0;
+   
+   //***
+   // Set the initial guess for horizontal intersect position as the ray's
+   // origin, and establish the datum and ellipsoid:
+   //***
+   const ossimDatum*     datum     = gpt.datum();
+   const ossimEllipsoid* ellipsoid = datum->ellipsoid();
+//    double lat, lon, h;
+
+//    ellipsoid->XYZToLatLonHeight(ray.origin().x(),
+//                                 ray.origin().y(),
+//                                 ray.origin().z(),
+//                                 lat, lon, h);
+//    ossimGpt nadirGpt(lat, lon, h);
+
+//    std::cout << "nadir pt = " << nadirGpt << std::endl;
+   
+   gpt = ossimGpt(prev_intersect_pt, datum);
+
+   //
+   // Loop to iterate on ray intersection with variable elevation surface:
+   //
+   do
+   {
+      //
+      // Intersect ray with ellipsoid inflated by h_ellips:
+      //
+      h_ellips = getHeightAboveEllipsoid(gpt);
+      if (h_ellips == theNullHeightValue) h_ellips = 0.0;
+      
+      intersected = ellipsoid->nearestIntersection(ray,
+                                                   h_ellips,
+                                                   new_intersect_pt);
+      if (!intersected)
+      {
+         //
+         // No intersection (looking over the horizon), so set ground point
+         // to NaNs:
+         //
+         gpt.makeNan();
+         done = true;
+      }
+      else
+      {
+         //
+         // Assign the ground point to the latest iteration's intersection
+         // point:
+         //
+         gpt = ossimGpt(new_intersect_pt, datum);
+         
+         //
+         // Determine if convergence achieved:
+         //
+         distance = (new_intersect_pt - prev_intersect_pt).magnitude();
+         if (distance < CONVERGENCE_THRESHOLD)
+            done = true;
+         else
+         {
+            prev_intersect_pt = new_intersect_pt;
+         }
+      }
+
+      iteration_count++;
+
+   } while ((!done) && (iteration_count < MAX_NUM_ITERATIONS));
+
+   if (iteration_count == MAX_NUM_ITERATIONS)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimElevSource::intersectRay: Max number of iterations reached solving for ground "
+                                            << "point. Result is probably inaccurate." << std::endl;
+      }
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimElevSource::intersectRay: returning..." << std::endl;
+   return intersected;
+}
+
+double ossimElevSource::getMinHeightAboveMSL() const
+{
+   return theMinHeightAboveMSL;
+}
+
+double ossimElevSource::getMaxHeightAboveMSL() const
+{
+   return theMaxHeightAboveMSL;
+}
+
+double ossimElevSource::getNullHeightValue() const
+{
+   return theNullHeightValue;
+}
+
+double ossimElevSource::getSeaLevelValue() const
+{
+   return theSeaLevelValue;
+}
+
+const ossimGrect& ossimElevSource::getBoundingGndRect() const
+{
+   return theGroundRect;
+}
+
+bool ossimElevSource::canConnectMyInputTo(ossim_int32 inputIndex,
+                                          const ossimConnectableObject* object)const
+{
+   return false;
+}
+
+void ossimElevSource::initialize()
+{}
+
+ossimFilename ossimElevSource::getFilename() const
+{
+   return ossimFilename::NIL;
+}
+
+bool ossimElevSource::open() const
+{
+   return true;
+}
+
+void ossimElevSource::close() const
+{
+}
+
+bool ossimElevSource::getComputeStatisticsFlag() const
+{
+   return theComputeStatsFlag;
+}
+
+void ossimElevSource::setComputeStatisticsFlag(bool flag)
+{
+   theComputeStatsFlag = flag;
+}
diff --git a/Utilities/OSSIM/ossim_core/elevation/ossimElevSource.h b/Utilities/OSSIM/ossim_core/elevation/ossimElevSource.h
new file mode 100644
index 0000000000..81b69382c1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/ossimElevSource.h
@@ -0,0 +1,184 @@
+//*****************************************************************************
+// FILE: ossimElevSource.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimElevSource. This is the base class for
+//   all objects providing height information given horizontal ground position.
+//
+//*****************************************************************************
+// $Id: ossimElevSource.h,v 1.19 2005/03/03 21:52:30 dburken Exp $
+
+#ifndef ossimElevSource_HEADER
+#define ossimElevSource_HEADER
+
+#include <base/common/ossimSource.h>
+#include <base/data_types/ossimGrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/geoid/ossimGeoid.h>
+
+class ossimEcefRay;
+class ossimKeywordlist;
+
+/******************************************************************************
+ * CLASS:  ossimElevSource
+ *
+ *****************************************************************************/
+class ossimElevSource : public ossimSource
+{
+public:
+
+   virtual ~ossimElevSource();
+   
+   /**
+    * Height access methods:
+    */
+   virtual double getHeightAboveMSL(const ossimGpt&) = 0;
+   virtual double getHeightAboveEllipsoid(const ossimGpt&);
+
+   /**
+    *  METHOD: intersectRay()
+    *  
+    *  Service method for intersecting a ray with the elevation surface to
+    *  arrive at a ground point. The ray is expected to originate ABOVE the
+    *  surface and pointing down.
+    *
+    *  NOTE: the gpt argument is expected to be initialized with the desired
+    *  datum, including ellipsoid, for the proper intersection point to be
+    *  computed.
+    *
+    *  LIMITATION: This release supports only single valued solutions, i.e., it
+    *  is possible a ray passing through one side of a mountain and out the
+    *  other will return an intersection with the far side. Eventually,
+    *  a more robust algorithm will be employed.
+    *
+    *  Returns true if good intersection found.
+    */
+   bool intersectRay(const ossimEcefRay& ray, ossimGpt& gpt);
+   
+   /**
+    * Access methods for the bounding elevations:
+    */
+   virtual double getMinHeightAboveMSL() const;
+   virtual double getMaxHeightAboveMSL() const;
+
+   /**
+    * Special numeric quantities as defined by this source:
+    */
+   double getNullHeightValue() const;
+   double getSeaLevelValue()   const;
+
+   /**
+    * METHOD: pointHasCoverage(gpt)
+    * Returns TRUE if coverage exists over gpt:
+    */
+   virtual bool pointHasCoverage(const ossimGpt&) const = 0;
+
+   /**
+    * METHOD: meanSpacingMeters()
+    * This method returns the post spacing in the region of gpt:
+    */
+   virtual double getMeanSpacingMeters() const = 0;
+
+   /**
+    * METHODS: accuracyLE90(), accuracyCE90()
+    * Returns the vertical and horizontal accuracy (90% confidence) in the
+    * region of gpt:
+    */
+   virtual double getAccuracyLE90(const ossimGpt& gpt) const = 0;
+   virtual double getAccuracyCE90(const ossimGpt& gpt) const = 0;
+
+
+   /**
+    *  METHOD:  getBoundingGndRect
+    *  
+    *  @return  The bounding geograpic rectangle in decimal degrees.
+    */
+   virtual const ossimGrect& getBoundingGndRect() const;
+   
+   virtual bool canConnectMyInputTo(ossim_int32 inputIndex,
+                                    const ossimConnectableObject* object)const;
+   
+   /**
+    * Implement ossimSource base-class pure virtuals:
+    */
+   virtual void initialize();
+
+   virtual ossimFilename getFilename() const;
+
+   /**
+    * Opens a stream to an elevation cell.
+    *
+    * @return Returns true on success, false on error.
+    *
+    * @note This implementation always returns true.  This should be
+    * overridden in derived classes that have streams to files.
+    */
+   virtual bool open() const;
+   
+   /**
+    * Closes the stream to the file.
+    *
+    * @note This implementation does nothing.  This should be
+    * overridden in derived classes that have streams to files.
+    */
+   virtual void close()const;
+
+   /**
+    * @return Returns the flag which controls whether or not statistics will
+    * be computed upon opening a cell and not finding a corresponding
+    * statistics file.
+    */
+   virtual bool getComputeStatisticsFlag() const;
+
+   /**
+    * Sets the flag which controls whether or not statistics will
+    * be computed upon opening a cell and not finding a corresponding
+    * statistics file.
+    *
+    * @param flag  true to enable, false to disable.
+    *
+    * @note This flag can also be controlled by user via the ossim preferences
+    * keyword = "elevation.compute_statistics.enabled".
+    */
+   virtual void setComputeStatisticsFlag(bool flag);
+
+   /**
+    * Static, public data members:
+    */
+   static const double DEFAULT_NULL_HEIGHT;
+   static const double DEFAULT_SEA_LEVEL;
+
+protected:
+   /**
+    * Constructors/Destructors:
+    */
+   ossimElevSource();
+
+
+   /**
+    * Data members:
+    */
+   double     theMinHeightAboveMSL;
+   double     theMaxHeightAboveMSL;
+   double     theNullHeightValue;
+   double     theSeaLevelValue;
+   ossimGrect theGroundRect;
+
+   //> Controls statistics gathering.  Defaulted to true.
+   bool       theComputeStatsFlag;
+
+
+private:
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/elevation/ossimElevSourceFactory.cpp b/Utilities/OSSIM/ossim_core/elevation/ossimElevSourceFactory.cpp
new file mode 100644
index 0000000000..eda0250a33
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/ossimElevSourceFactory.cpp
@@ -0,0 +1,43 @@
+//----------------------------------------------------------------------------
+// FILE: ossimElevSourceFactory.cc
+//
+// Copyright (C) 2002 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class definition for ossimElevSourceFactory.
+//
+// This is the base class interface for elevation source factories.  Contains
+// pure virtual methods that all elevation source factories must implement.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimElevSourceFactory.cpp,v 1.3 2005/11/16 20:22:19 dburken Exp $
+
+#include <elevation/ossimElevSourceFactory.h>
+
+RTTI_DEF1(ossimElevSourceFactory, "ossimElevSourceFactory" , ossimObject)
+
+ossimElevSourceFactory::ossimElevSourceFactory()
+   : theDirectory(ossimFilename::NIL)
+{
+}
+
+ossimElevSourceFactory::~ossimElevSourceFactory()
+{
+}
+
+ossimFilename ossimElevSourceFactory::getDirectory() const
+{
+   return theDirectory;
+}
+
+void ossimElevSourceFactory::setDirectory(const ossimFilename& directory)
+{
+   theDirectory = directory;
+}
diff --git a/Utilities/OSSIM/ossim_core/elevation/ossimElevSourceFactory.h b/Utilities/OSSIM/ossim_core/elevation/ossimElevSourceFactory.h
new file mode 100644
index 0000000000..253033f45b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/ossimElevSourceFactory.h
@@ -0,0 +1,76 @@
+//----------------------------------------------------------------------------
+// FILE: ossimElevSourceFactory.cc
+//
+// Copyright (C) 2002 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class declaration for ossimElevSourceFactory.
+//
+// This is the base class interface for elevation source factories which main
+// function is to return an elevation source that covers the ground point
+// passed to the "getElevSource" method.
+//
+// Note the caller of "getElevSource" is responsible for managing the memory
+// new'd from the method.
+// 
+//----------------------------------------------------------------------------
+// $Id: ossimElevSourceFactory.h,v 1.4 2005/11/18 20:24:49 gpotts Exp $
+
+#ifndef ossimElevSourceFactory_HEADER
+#define ossimElevSourceFactory_HEADER
+
+#include <base/common/ossimObject.h>
+#include <base/data_types/ossimFilename.h>
+
+class ossimElevSource;
+class ossimGpt;
+
+/*!****************************************************************************
+ * CLASS:  ossimElevSourceFactory
+ *
+ *****************************************************************************/
+class OSSIM_DLL ossimElevSourceFactory : public ossimObject
+{
+public:
+
+   /** default constructor */
+   ossimElevSourceFactory();
+
+   /** virtual destructor */
+   virtual ~ossimElevSourceFactory();
+
+   /**
+    *  Pure virtual method.
+    *  return an elevation source pointer that has elevation coverage for the
+    *  ground point passed in.
+    *  Note the caller of this method is responsible for managing the memory
+    *  allocated.
+    */
+   virtual ossimElevSource* getNewElevSource(const ossimGpt& gpt)const=0;
+   virtual void createIndex()=0;
+
+   /**
+    * @return The directory the factory returns data from.
+    */
+   virtual ossimFilename getDirectory() const;
+
+   /**
+    * @param directory The directory to return data from.
+    */
+   virtual void setDirectory(const ossimFilename& directory);
+
+protected:
+
+   ossimFilename theDirectory;
+   
+TYPE_DATA
+}; 
+
+#endif /* End of "#ifndef ossimElevSourceFactory_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/elevation/ossimElevationShapeIdx.cpp b/Utilities/OSSIM/ossim_core/elevation/ossimElevationShapeIdx.cpp
new file mode 100644
index 0000000000..4cae3055f7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/ossimElevationShapeIdx.cpp
@@ -0,0 +1,274 @@
+#include "ossimElevationShapeIdx.h"
+#include <vec/shape/shapefil.h>
+
+ossimString ossimElevationShapeIdx::theDefaultName = "elevation_idx.shp";
+
+class ossimElevationShapeIdxPrivate : public ossimReferenced
+{
+public:
+   ossimElevationShapeIdxPrivate()
+      :theShapefileHandle(0),
+       theDbfHandle(0)
+      {
+      }
+   virtual ~ossimElevationShapeIdxPrivate()
+      {
+         shpClose();
+      }
+   SHPHandle shpOpen(const ossimFilename& file, bool overWriteFlag)
+      {
+         shpClose();
+         theShapeFilename = file;
+         if(overWriteFlag)
+         {
+            theShapefileHandle = SHPCreate(file.c_str(),
+                                           SHPT_POLYGON);
+         }
+         else
+         {
+            theShapefileHandle = SHPOpen(file.c_str(),
+                                         "r+b");
+            if(!theShapefileHandle)
+            {
+               theShapefileHandle = SHPCreate(file.c_str(),
+                                              SHPT_POLYGON);
+            }
+         }
+         dbfOpen(overWriteFlag);
+         
+         return theShapefileHandle;
+      }
+   void shpClose()
+      {
+         if(theShapefileHandle)
+         {
+            SHPClose(theShapefileHandle);
+            theShapefileHandle = 0;  
+         }
+      }
+   SHPHandle shpHandle()
+      {
+         return theShapefileHandle;
+      }
+
+   DBFHandle dbfHandle()
+      {
+         return theDbfHandle;
+      }
+   
+protected:
+   void dbfOpen(bool overWriteFlag)
+      {
+         dbfClose();
+
+         if(overWriteFlag)
+         {
+            theDbfHandle = DBFCreate(theShapeFilename.c_str());
+            if(theDbfHandle)
+            {
+               DBFAddField(theDbfHandle, "FILENAME", FTString, 256, 0);
+               DBFAddField(theDbfHandle, "MINZ", FTDouble, 32, 17);
+               DBFAddField(theDbfHandle, "MAXZ", FTDouble, 32, 17);
+            }
+         }
+         else
+         {
+            theDbfHandle = DBFOpen(theShapeFilename.c_str(), "r+b");
+            if(!theDbfHandle)
+            {
+               theDbfHandle = DBFCreate(theShapeFilename.c_str());
+               if(theDbfHandle)
+               {
+                  DBFAddField(theDbfHandle, "FILENAME", FTString, 256, 0);
+                  DBFAddField(theDbfHandle, "MINZ", FTDouble, 32, 17);
+                  DBFAddField(theDbfHandle, "MAXZ", FTDouble, 32, 17);
+               }
+            }
+         }
+      }
+   void dbfClose()
+      {
+         if(theDbfHandle)
+         {
+            DBFClose(theDbfHandle);
+            theDbfHandle = 0;
+         }
+      }
+   ossimFilename theShapeFilename;
+   SHPHandle   theShapefileHandle;
+   DBFHandle   theDbfHandle;
+};
+
+ossimElevationShapeIdx::ossimElevationShapeIdx(const ossimFilename& shapeFilename,
+                                               bool overWriteFlag)
+{
+   setFilename(shapeFilename, overWriteFlag);
+}
+
+ossimElevationShapeIdx::~ossimElevationShapeIdx()
+{
+   if(thePrivateData)
+   {
+      delete thePrivateData;
+      thePrivateData = 0;
+   }
+}
+
+const ossimString& ossimElevationShapeIdx::defaultName()
+{
+   return theDefaultName;
+}
+
+void ossimElevationShapeIdx::setFilename(const ossimFilename& shapeFilename, bool overWriteFlag)throw(std::exception())
+{
+   if(thePrivateData)
+   {
+      delete thePrivateData;
+      thePrivateData = 0;
+   }
+   if(shapeFilename == "") return;
+   if(shapeFilename.isDir())
+   {
+      theShapeFilename = shapeFilename.dirCat(theDefaultName);
+   }
+   else if(shapeFilename.isFile())
+   {
+      theShapeFilename = shapeFilename;
+      theShapeFilename.setExtension("shp");
+   }
+   else
+   {
+      theShapeFilename = shapeFilename.path();
+      
+      theShapeFilename = theShapeFilename.dirCat(theDefaultName);
+      theShapeFilename.setExtension("shp");
+   }
+   thePrivateData = new ossimElevationShapeIdxPrivate();
+   
+   if(!thePrivateData->shpOpen(theShapeFilename, overWriteFlag))
+   {
+      thePrivateData = 0;
+      throw(("ossimElevationShapeIdx::setFilename: Unable to setup index file " + theShapeFilename).c_str());
+   }
+   double minBounds[4];
+   double maxBounds[4];
+   int nEntities = 0;
+   int shapeType = SHPT_NULL;
+   SHPGetInfo(thePrivateData->shpHandle(),
+              &nEntities,
+              &shapeType,
+              minBounds,
+              maxBounds);
+   if(nEntities < 0)
+   {
+      // set it up for the adds
+      //
+      theGlobalMinx = 180.0;
+      theGlobalMiny = 90.0;
+      theGlobalMaxx = -180.0;
+      theGlobalMaxy = -90.0;
+   }
+   else
+   {
+      theGlobalMinx = minBounds[0];
+      theGlobalMiny = minBounds[1];
+      theGlobalMaxx = maxBounds[0];
+      theGlobalMaxy = maxBounds[1];
+   }
+}
+
+void ossimElevationShapeIdx::add(const ossimFilename& filename,
+                                 ossim_float64 minx, // decimal degrees
+                                 ossim_float64 miny, // decimal degrees
+                                 ossim_float64 minz, // meters
+                                 ossim_float64 maxx, // decimal degrees
+                                 ossim_float64 maxy, // decimal degrees
+                                 ossim_float64 maxz )// meters
+{
+   if(!thePrivateData) return;
+   int iRecord = DBFGetRecordCount(thePrivateData->dbfHandle());
+   double* x = new double[8];
+   double* y = new double[8];
+   int nVertices = 4;
+   x[0] = minx;
+   x[1] = maxx;
+   x[2] = maxx;
+   x[3] = minx;
+   
+   y[0] = maxy;
+   y[1] = maxy;
+   y[2] = miny;
+   y[3] = miny;
+   
+
+   if(minx < theGlobalMinx)
+   {
+      theGlobalMinx = minx;
+   }
+   if(miny < theGlobalMiny)
+   {
+      theGlobalMiny = miny;
+   }
+   if(maxx > theGlobalMaxx)
+   {
+      theGlobalMaxx = maxx;
+   }
+   if(maxy > theGlobalMaxy)
+   {
+      theGlobalMaxy = maxy;
+   }
+   SHPObject* obj = SHPCreateSimpleObject(SHPT_POLYGON,
+                                          nVertices,
+                                          x,
+                                          y,
+                                          0);
+
+   SHPWriteObject( thePrivateData->shpHandle(),
+                   -1,
+                   obj );
+   DBFWriteStringAttribute(thePrivateData->dbfHandle(),
+                           iRecord,
+                           0,
+                           filename.c_str());
+   DBFWriteDoubleAttribute(thePrivateData->dbfHandle(),
+                           iRecord,
+                           0,
+                           (double)minz);
+   DBFWriteDoubleAttribute(thePrivateData->dbfHandle(),
+                           iRecord,
+                           0,
+                           (double)maxz);
+}
+
+void ossimElevationShapeIdx::buildQuadTree(int maxDepth)
+{
+   if(!thePrivateData) return;
+   
+   ossimFilename qTree = theShapeFilename;
+
+   qTree.setExtension("qtree");
+
+   if(thePrivateData->shpHandle())
+   {
+      double minBounds[4] = {0.0,0.0,0.0,0.0};
+      double maxBounds[4] = {0.0,0.0,0.0,0.0};
+
+      minBounds[0] = theGlobalMinx;
+      minBounds[1] = theGlobalMiny;
+      maxBounds[0] = theGlobalMaxx;
+      maxBounds[1] = theGlobalMaxy;
+      
+      SHPTree* tree = SHPCreateTree(thePrivateData->shpHandle(),
+                                    2,
+                                    maxDepth,
+                                    minBounds,
+                                    maxBounds);
+      if(tree)
+      {
+         SHPWriteTree(tree,
+                      qTree.c_str());
+         
+         SHPDestroyTree(tree);
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/elevation/ossimElevationShapeIdx.h b/Utilities/OSSIM/ossim_core/elevation/ossimElevationShapeIdx.h
new file mode 100644
index 0000000000..44498b4f21
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/elevation/ossimElevationShapeIdx.h
@@ -0,0 +1,41 @@
+#ifndef ossimElevationShapeIdx_HEADER
+#define ossimElevationShapeIdx_HEADER
+#include <exception>
+#include <base/common/ossimObject.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimFilename.h>
+
+class ossimElevationShapeIdxPrivate;
+
+class ossimElevationShapeIdx : public ossimObject
+{
+public:
+   ossimElevationShapeIdx(const ossimFilename& shapeFilename = "",
+                          bool overWriteFlag = false);
+   virtual ~ossimElevationShapeIdx();
+   void setFilename(const ossimFilename& file, bool overWriteFlag=false)throw(std::exception());
+
+   void add(const ossimFilename& filename,
+            ossim_float64 minx,  // decimal degrees
+            ossim_float64 miny,  // decimal degrees
+            ossim_float64 minz,  // height in meters meters 
+            ossim_float64 maxx,  // decimal degrees
+            ossim_float64 maxy,  // decimal degrees
+            ossim_float64 maxz); // height in meters meters
+
+   void buildQuadTree(int maxDepth=0);
+   static const ossimString& defaultName();
+
+protected:
+   static ossimString theDefaultName;
+   ossimElevationShapeIdxPrivate* thePrivateData;
+
+   ossimFilename theShapeFilename;
+   ossim_float64 theGlobalMinx;
+   ossim_float64 theGlobalMiny;
+   ossim_float64 theGlobalMaxx;
+   ossim_float64 theGlobalMaxy;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/fonts/.cvsignore b/Utilities/OSSIM/ossim_core/fonts/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/fonts/CMakeLists.txt b/Utilities/OSSIM/ossim_core/fonts/CMakeLists.txt
new file mode 100644
index 0000000000..5ce7ff17a8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_font_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_font_HDRS "*.h")
+ADD_LIBRARY(ossim_font ${ossim_font_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_font)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_font_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/fonts/factory/.cvsignore b/Utilities/OSSIM/ossim_core/fonts/factory/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/factory/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryBase.h b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryBase.h
new file mode 100644
index 0000000000..2255c6d713
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryBase.h
@@ -0,0 +1,41 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimFontFactoryBase.h,v 1.4 2005/07/15 19:45:48 dburken Exp $
+#ifndef ossimFontFactoryBase_HEADER
+#define ossimFontFactoryBase_HEADER
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/common/ossimFontInformation.h>
+class ossimFont;
+
+class ossimFontFactoryBase
+{
+public:
+
+   virtual ~ossimFontFactoryBase(){}
+   
+   /*!
+    * Will find the best font for the passed in infromation.
+    * If none is found a default font should be returned.
+    */
+   virtual ossimFont* createFont(const ossimFontInformation& information)const=0;
+
+   /*!
+    * Usually for trutype fonts but any font stored in a file it
+    * will try to create a font from it.
+    */
+   virtual ossimFont* createFont(const ossimFilename& file)const=0;
+
+   virtual void getFontInformation(std::vector<ossimFontInformation>& informationList)const=0;
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryRegistry.cpp b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryRegistry.cpp
new file mode 100644
index 0000000000..77bb93921f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryRegistry.cpp
@@ -0,0 +1,191 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+// 
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimFontFactoryRegistry.cpp,v 1.11 2005/12/10 20:08:39 dburken Exp $
+#include <algorithm>
+#include "ossimFontFactoryRegistry.h"
+#include "fonts/ossimGdBitmapFont.h"
+
+#if OSSIM_HAS_FREETYPE
+#  include "fonts/factory/ossimFreeTypeFontFactory.h"
+#endif
+
+#include "fonts/ossimGdSansBold.inc"
+
+ossimFontFactoryRegistry* ossimFontFactoryRegistry::theInstance = 0;
+
+ossimFontFactoryRegistry::ossimFontFactoryRegistry()
+   :theDefaultFont(NULL)
+{
+   theInstance = this;
+}
+
+ossimFontFactoryRegistry* ossimFontFactoryRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimFontFactoryRegistry;
+#if OSSIM_HAS_FREETYPE
+      theInstance->registerFactory(ossimFreeTypeFontFactory::instance());
+#endif
+   }
+
+   return theInstance;
+}
+
+bool ossimFontFactoryRegistry::registerFactory(ossimFontFactoryBase* factory)
+{
+   bool result = false;
+   if(factory&&!findFactory(factory))
+   {
+      theFactoryList.push_back(factory);
+      result = true;
+   }
+
+   return result;
+}
+
+void ossimFontFactoryRegistry::unregisterFactory(ossimFontFactoryBase* factory)
+{
+   std::vector<ossimFontFactoryBase*>::iterator iter =  std::find(theFactoryList.begin(),
+                                                                  theFactoryList.end(),
+                                                                  factory);
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+}
+
+bool ossimFontFactoryRegistry::findFactory(ossimFontFactoryBase* factory)const
+{
+   return (std::find(theFactoryList.begin(),
+                     theFactoryList.end(),
+                     factory)!=theFactoryList.end());
+}
+
+
+ossimFont* ossimFontFactoryRegistry::createFont(const ossimFontInformation& information)const
+{
+   ossimFont* result = (ossimFont*)NULL;
+   int i = 0;
+
+   for(i= 0; ( (i < (int)theFactoryList.size()) &&(!result)); ++i)
+   {
+      result = theFactoryList[i]->createFont(information);
+   }
+   
+   return result;
+}
+
+ossimFont* ossimFontFactoryRegistry::createFont(const ossimFilename& file)const
+{
+   ossimFont* result = (ossimFont*)NULL;
+   int i = 0;
+
+   for(i= 0; ( (i < (int)theFactoryList.size()) &&(!result)); ++i)
+   {
+      result = theFactoryList[i]->createFont(file);
+   }
+   
+   return result;
+}
+
+void ossimFontFactoryRegistry::getFontInformation(std::vector<ossimFontInformation>& informationList)const
+{
+   int i = 0;
+   for(i= 0; i < (int)theFactoryList.size(); ++i)
+   {
+      theFactoryList[i]->getFontInformation(informationList);
+   }
+}
+
+void ossimFontFactoryRegistry::getFontInformationFamilyName(std::vector<ossimFontInformation>& informationList,
+                                                            const ossimString& familyName)const
+{
+   vector<ossimFontInformation> info;
+   getFontInformation(info);
+    
+   ossimString right = familyName;
+   right = right.upcase().trim();
+   int i = 0;
+   for(i = 0; i < (int)info.size(); ++i)
+   {
+      ossimString left  = info[i].theFamilyName;
+      left  = left.upcase().trim();
+      
+      if(left == right)
+      {
+         informationList.push_back(info[i]);
+      }
+   }
+}
+
+void ossimFontFactoryRegistry::getFontInformationContainingFamilyName(std::vector<ossimFontInformation>& informationList,
+                                                                      const ossimString& familyName)const
+{
+   vector<ossimFontInformation> info;
+   getFontInformation(info);
+   
+   ossimString right = familyName;
+   right = right.upcase().trim();
+   int i = 0;
+   for(i = 0; i < (int)info.size(); ++i)
+   {
+      ossimString left  = info[i].theFamilyName;
+
+      left  = left.upcase().trim();
+      if(left.contains(right))
+      {
+         informationList.push_back(info[i]);
+      }
+   }
+}
+
+ossimFont* ossimFontFactoryRegistry::getDefaultFont()const
+{
+   if(!theDefaultFont)
+   {
+      std::vector<ossimFontInformation> infoList;
+      getFontInformationContainingFamilyName(infoList,
+					     "Times");
+      if(infoList.size() < 1)
+	{
+	  getFontInformationContainingFamilyName(infoList,
+						 "Roman");
+	}
+      if(infoList.size() < 1)
+	{
+	  getFontInformationContainingFamilyName(infoList,
+						 "Sanz");
+	}
+      if(infoList.size() < 1)
+	{
+	  getFontInformation(infoList);
+	}
+      if(infoList.size())
+      {
+         theDefaultFont = createFont(infoList[0]);
+         theDefaultFont->setPixelSize(12, 12);
+      }
+      else
+      {
+         theDefaultFont = new  ossimGdBitmapFont("gd sans",
+                                                 "bold",
+                                                 ossimGdSansBold);
+      }
+   }
+   return theDefaultFont;
+}
+
+ossimFontFactoryRegistry::ossimFontFactoryRegistry(const ossimFontFactoryRegistry& /* rhs */ )
+{
+}
+
+void ossimFontFactoryRegistry::operator=(const ossimFontFactoryRegistry& /* rhs */ )
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryRegistry.h b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryRegistry.h
new file mode 100644
index 0000000000..85bc85290f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFontFactoryRegistry.h
@@ -0,0 +1,82 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: 
+// 
+//********************************************************************
+// $Id: ossimFontFactoryRegistry.h,v 1.9 2004/05/19 18:35:57 dburken Exp $
+#ifndef ossimFontFactoryRegistry_HEADER
+#define ossimFontFactoryRegistry_HEADER
+#include <vector>
+#include "base/common/ossimFontInformation.h"
+#include "base/data_types/ossimFilename.h"
+#include "fonts/factory/ossimFontFactoryBase.h"
+
+
+class OSSIMDLLEXPORT ossimFontFactoryRegistry
+{
+public:
+   static ossimFontFactoryRegistry* instance();
+
+   bool registerFactory(ossimFontFactoryBase* factory);
+   void unregisterFactory(ossimFontFactoryBase* factory);
+   bool findFactory(ossimFontFactoryBase* factory)const;
+   
+   ossimFont* createFont(const ossimFontInformation& information)const;
+   ossimFont* createFont(const ossimFilename& file)const;
+
+   /*!
+    * Returns all font information.
+    */
+   void getFontInformation(std::vector<ossimFontInformation>& informationList)const;
+
+   /*!
+    * Matches the entire string.  Does a case insensitive match.
+    */ 
+   void getFontInformationFamilyName(std::vector<ossimFontInformation>& informationList,
+                                     const ossimString& familyName)const;
+
+   /*!
+    * Matches the sub-string.  Does a case insensitive match.
+    */ 
+   void getFontInformationContainingFamilyName(std::vector<ossimFontInformation>& informationList,
+                                               const ossimString& familyName)const;
+
+   /*!
+    * This font should not be deleted.  It returns the default font.  If you
+    * want to make a copy then just call the dup method on
+    * font.
+    */
+   ossimFont* getDefaultFont()const;
+   
+protected:
+   mutable ossimFont* theDefaultFont;
+
+   static ossimFontFactoryRegistry* theInstance;
+
+   std::vector<ossimFontFactoryBase*> theFactoryList;
+
+   ossimFontFactoryRegistry();
+   
+private:
+   ossimFontFactoryRegistry(const ossimFontFactoryRegistry& rhs);
+   void operator =(const ossimFontFactoryRegistry& rhs);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/fonts/factory/ossimFreeTypeFontFactory.cpp b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFreeTypeFontFactory.cpp
new file mode 100644
index 0000000000..3ae4eabcea
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFreeTypeFontFactory.cpp
@@ -0,0 +1,237 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimFreeTypeFontFactory.cpp,v 1.13 2005/12/10 20:08:07 dburken Exp $
+
+#include <ossimConfig.h> /* To pick up OSSIM_HAS_FREETYPE. */
+
+#if OSSIM_HAS_FREETYPE
+#  include <fonts/factory/ossimFreeTypeFontFactory.h>
+#  include <fonts/ossimFreeTypeFont.h>
+#  include <base/common/ossimPreferences.h>
+#  include <base/data_types/ossimDirectory.h>
+#  include <base/context/ossimNotifyContext.h>
+
+ossimFreeTypeFontFactory* ossimFreeTypeFontFactory::theInstance=0;
+
+ossimFreeTypeFontFactory::ossimFreeTypeFontFactory()
+{
+   theInstance = this;
+}
+
+ossimFreeTypeFontFactory::~ossimFreeTypeFontFactory()
+{
+   theInstance = (ossimFreeTypeFontFactory*)NULL;
+}
+
+ossimFreeTypeFontFactory* ossimFreeTypeFontFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimFreeTypeFontFactory;
+      theInstance->initializeDefaults();
+   }
+
+   return theInstance;
+}
+
+
+ossimFont* ossimFreeTypeFontFactory::createFont(const ossimFontInformation& information)const
+
+{
+   ossimFont* result = (ossimFont*)NULL;
+   
+   ossimString rightFamilyName = information.theFamilyName;
+   ossimString rightStyleName  = information.theStyleName;
+   rightFamilyName = rightFamilyName.upcase().trim();
+   rightStyleName  = rightStyleName.upcase().trim();
+   int i = 0;
+   
+   for(i = 0; ( (i < (int)theFontInformationList.size())&&(!result));++i)
+   {
+      ossimString leftFamilyName = theFontInformationList[i].theFontInformation.theFamilyName;
+      ossimString leftStyleName = theFontInformationList[i].theFontInformation.theStyleName;
+
+      leftFamilyName = leftFamilyName.upcase().trim();
+      leftStyleName  = leftStyleName.upcase().trim();
+      
+      if( (leftFamilyName == rightFamilyName)&&
+          (leftStyleName == rightStyleName))
+      {
+         if(theFontInformationList[i].theFontInformation.theFixedFlag)
+         {
+            if(theFontInformationList[i].theFontInformation.thePointSize ==
+               information.thePointSize)
+            {
+               result = new ossimFreeTypeFont(theFontInformationList[i].theFilename);
+               if(result)
+               {
+                  if(result->getErrorStatus())
+                  {
+                     delete result;
+                     result = NULL;
+                     ossimNotify(ossimNotifyLevel_WARN) <<"WARNING ossimFreeTypeFontFactory::createFont:  unable to open font file "
+                                                        << theFontInformationList[i].theFilename << std::endl;
+                  }
+               }
+            }
+         }
+         else
+         {
+            result = new ossimFreeTypeFont(theFontInformationList[i].theFilename);
+            if(result)
+            {
+               if(result->getErrorStatus())
+               {
+                  delete result;
+                  result = NULL;
+                  ossimNotify(ossimNotifyLevel_WARN) <<  "WARNING ossimFreeTypeFontFactory::createFont: unable to open font file "
+                                                     << theFontInformationList[i].theFilename << std::endl;
+               }
+               else
+               {
+                  if(information.thePointSize.x&&
+                     information.thePointSize.y)
+                  {
+                     result->setPixelSize(information.thePointSize.x,
+                                          information.thePointSize.y);
+                  }
+               }
+            }
+         }
+      }         
+   }
+
+   if(result)
+   {
+      result->setScale(information.theScale.x,
+                       information.theScale.y);
+      result->setScale(information.theScale.x,
+                       information.theScale.y);
+      result->setHorizontalVerticalShear(information.theShear.x,
+                                         information.theShear.y);
+      result->setRotation(information.theRotation);
+   }
+   
+   return result;
+}
+
+ossimFont* ossimFreeTypeFontFactory::createFont(const ossimFilename& file)const
+{
+   ossimFont* result = new ossimFreeTypeFont(file);
+
+   if(result->getErrorStatus())
+   {
+      delete result;
+      result = (ossimFont*)NULL;
+   }
+   
+   return result;
+}
+
+void ossimFreeTypeFontFactory::getFontInformation(std::vector<ossimFontInformation>& informationList)const
+{
+   int i = 0;
+   for(i = 0; i < (int)theFontInformationList.size();++i)
+   {
+      informationList.push_back(theFontInformationList[i].theFontInformation);
+   }
+}
+
+bool ossimFreeTypeFontFactory::addFile(const ossimFilename& file)
+{
+   ossimFreeTypeFont* font = new ossimFreeTypeFont(file);
+   std::vector<ossimFontInformation> fontInfoList;
+   
+   bool result = false;
+   int i = 0;
+   if(font->getFontFace())
+     {
+       if(!font->getErrorStatus())
+	 {
+	   font->getFontInformation(fontInfoList);
+	   
+	   for(i = 0; i < (int)fontInfoList.size();++i)
+	     {
+	       theFontInformationList.push_back(ossimFreeTypeFontInformation(file,
+									     fontInfoList[i]));
+	     }
+	   result = true;
+	 }
+     }
+
+   return result;
+}
+
+void ossimFreeTypeFontFactory::initializeDefaults()
+{
+   const ossimKeywordlist& kwl = ossimPreferences::instance()->preferencesKWL();
+   ossimString regExpressionDir =  ossimString("^(") + "font.dir[0-9]+)";
+   ossimString regExpressionFile =  ossimString("^(") + "font.file[0-9]+)";
+   vector<ossimString> dirs =
+      kwl.getSubstringKeyList( regExpressionDir );
+   vector<ossimString> files =
+      kwl.getSubstringKeyList( regExpressionFile );
+   
+   int idx = 0;
+   for(idx = 0; idx < (int)dirs.size();++idx)
+   {
+      const char* directoryLocation = kwl.find(dirs[idx]);
+      if(directoryLocation)
+      {
+         ossimDirectory d;
+	 
+         if(d.open(ossimFilename(directoryLocation)))
+         {
+            ossimFilename file;
+	    
+            if(d.getFirst(file, ossimDirectory::OSSIM_DIR_FILES))
+            {
+               do
+               {
+                  addFile(file);
+               }while(d.getNext(file));
+            }
+         }
+      }
+   }
+   for(idx = 0; idx < (int)files.size();++idx)
+   {
+      const char* fileName = kwl.find(files[idx]);
+      
+      if(fileName)
+      {
+         addFile(ossimFilename(fileName));
+      }
+   }   
+#if 0
+   if(!numberOfDirs&&!numberOfFiles)
+   {
+#ifdef __UNIX__
+      ossimFilename file("/usr/X11R6/lib/X11/fonts/Type1");
+      
+      if(file.exists())
+      {
+         ossimDirectory d;
+         if(d.open(file))
+         {
+            if(d.getFirst(file, ossimDirectory::OSSIM_DIR_FILES))
+            {
+               do
+               {
+                  addFile(file);
+               }while(d.getNext(file));
+            }
+         }
+      }
+#endif
+   }
+#endif
+}
+
+#endif /* #if OSSIM_HAS_FREETYPE */
diff --git a/Utilities/OSSIM/ossim_core/fonts/factory/ossimFreeTypeFontFactory.h b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFreeTypeFontFactory.h
new file mode 100644
index 0000000000..ad1401603a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/factory/ossimFreeTypeFontFactory.h
@@ -0,0 +1,64 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// 
+//********************************************************************
+// $Id: ossimFreeTypeFontFactory.h,v 1.1 2002/04/30 18:50:55 gpotts Exp $
+#ifndef ossimFreeTypeFontFactory_HEADER
+#define ossimFreeTypeFontFactory_HEADER
+#include "fonts/factory/ossimFontFactoryBase.h"
+
+class ossimFreeTypeFontInformation
+{
+public:
+   ossimFreeTypeFontInformation(const ossimFilename& file,
+                                const ossimFontInformation& info)
+      :theFilename(file),
+       theFontInformation(info)
+      {}
+
+   ossimFilename        theFilename;
+   ossimFontInformation theFontInformation;
+};
+
+class ossimFreeTypeFontFactory : public ossimFontFactoryBase
+{
+public:
+   virtual ~ossimFreeTypeFontFactory();
+   static ossimFreeTypeFontFactory* instance();
+   virtual ossimFont* createFont(const ossimFontInformation& information)const;
+   virtual ossimFont* createFont(const ossimFilename& file)const;
+   virtual void getFontInformation(std::vector<ossimFontInformation>& informationList)const;
+  
+   bool addFile(const ossimFilename& file);
+   
+protected:
+   ossimFreeTypeFontFactory();
+
+   static ossimFreeTypeFontFactory* theInstance;
+   std::vector<ossimFreeTypeFontInformation> theFontInformationList;
+
+   void initializeDefaults();
+private:
+   ossimFreeTypeFontFactory(const ossimFreeTypeFontFactory& rhs){}
+   void operator =(const ossimFreeTypeFontFactory& rhs){}
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/fonts/ossimFont.cpp b/Utilities/OSSIM/ossim_core/fonts/ossimFont.cpp
new file mode 100644
index 0000000000..c0a40bed0d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/ossimFont.cpp
@@ -0,0 +1,83 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: 
+// 
+//********************************************************************
+// $Id: ossimFont.cpp,v 1.9 2002/08/23 14:05:22 gpotts Exp $
+#include "ossimFont.h"
+#include "math.h"
+#include <iostream>
+using namespace std;
+
+#include "matrix/newmatio.h"
+
+RTTI_DEF2(ossimFont, "ossimFont", ossimObject, ossimErrorStatusInterface);
+
+void ossimFont::setRotation(double rotationInDegrees)
+{
+    theRotation    = rotationInDegrees;
+
+    computeMatrix();
+}
+
+void ossimFont::setScale(double horizontal,
+                         double vertical)
+{
+   theHorizontalScale = horizontal;
+   theVerticalScale   = vertical;
+   
+   computeMatrix();   
+}
+
+void ossimFont::computeMatrix()
+{
+   NEWMAT::Matrix r(2,2);
+   NEWMAT::Matrix s(2,2);
+
+   double radRotation = theRotation*M_PI/180.0;
+   
+   r << cos(radRotation) << -sin(radRotation)
+     << sin(radRotation) << cos(radRotation);
+   
+   s << theHorizontalScale << theVerticalShear
+     << theHorizontalShear << theVerticalScale;
+
+   theAffineTransform = s*r;
+
+}
+
+void ossimFont::getBoundingClipBox(ossimIrect& clippedBox)
+{
+   getBoundingBox(clippedBox);
+   
+   if(!theClippingBox.hasNans()&&
+      (theClippingBox.width()>1)&&(theClippingBox.height()>1) )
+   {
+      clippedBox = clippedBox.clipToRect(theClippingBox);
+   }
+}
+
+ossimIrect ossimFont::getBoundingClipBox()
+{
+   ossimIrect clipBox;
+   getBoundingClipBox(clipBox);
+   
+   return clipBox;
+}
diff --git a/Utilities/OSSIM/ossim_core/fonts/ossimFont.h b/Utilities/OSSIM/ossim_core/fonts/ossimFont.h
new file mode 100644
index 0000000000..f86ab810e6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/ossimFont.h
@@ -0,0 +1,336 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: 
+// 
+//********************************************************************
+// $Id: ossimFont.h,v 1.17 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimFont_HEADER
+#define ossimFont_HEADER
+#include "base/data_types/ossimIpt.h"
+#include "base/data_types/ossimIrect.h"
+#include "base/data_types/ossimString.h"
+#include "imaging/ossimRgbImage.h"
+#include "base/common/ossimConstants.h"
+#include "matrix/newmat.h"
+#include "base/common/ossimObject.h"
+#include "base/common/ossimErrorStatusInterface.h"
+#include "base/common/ossimFontInformation.h"
+
+#define OSSIM_FONT_DEFAULT_SIZE_X 12
+#define OSSIM_FONT_DEFAULT_SIZE_Y 12
+
+class ossimFont : public ossimObject, public ossimErrorStatusInterface
+{
+public:
+   ossimFont()
+      :theStringToRasterize(""),
+       theFamilyName(""),
+       theStyleName(""),
+       theRotation(0),
+       theHorizontalShear(0.0),
+       theVerticalShear(0.0),
+       theHorizontalScale(1.0),
+       theVerticalScale(1.0),
+       theHorizontalPixelSize(8),
+       theVerticalPixelSize(8),
+       theHorizontalDeviceUnits(72),
+       theVerticalDeviceUnits(72),
+       theAffineTransform(2,2)
+      {
+         theAffineTransform << 1.0 << 0.0
+                            << 0.0 << 1.0;
+      }
+   
+   ossimFont(const ossimString& familyName,
+             const ossimString& styleName,
+             int                horizontalPixelSize,
+             int                verticalPixelSize,
+             int                horizontalDeviceUnits=72,// 72 dpi is default,
+             int                verticalDeviceUnits=72)// 72 dpi is default
+      :theStringToRasterize(""),
+       theFamilyName(familyName),
+       theStyleName(styleName),
+       theRotation(0),
+       theHorizontalShear(0.0),
+       theVerticalShear(0.0),
+       theHorizontalScale(1.0),
+       theVerticalScale(1.0),
+       theHorizontalPixelSize(horizontalPixelSize),
+       theVerticalPixelSize(verticalPixelSize),
+       theHorizontalDeviceUnits(horizontalDeviceUnits),
+       theVerticalDeviceUnits(horizontalDeviceUnits),
+       theAffineTransform(2,2)
+      {
+         theAffineTransform << 1.0 << 0.0
+                            << 0.0 << 1.0;
+      }
+
+   ossimFont(const ossimFont& rhs)
+      {
+         theStringToRasterize      = rhs.theStringToRasterize;
+         theFamilyName             = rhs.theFamilyName;
+         theStyleName              = rhs.theStyleName;
+         theRotation               = rhs.theRotation;
+         theHorizontalShear        = rhs.theHorizontalShear;
+         theVerticalShear          = rhs.theVerticalShear;
+         theHorizontalScale        = rhs.theHorizontalScale;
+         theVerticalScale          = rhs.theVerticalScale;
+         theHorizontalPixelSize    = rhs.theHorizontalPixelSize;
+         theHorizontalDeviceUnits  = rhs.theHorizontalDeviceUnits;
+         theVerticalDeviceUnits    = rhs.theVerticalDeviceUnits;
+         theAffineTransform        = rhs.theAffineTransform;
+         theClippingBox            = rhs.theClippingBox;
+         theLocalOrigin            = rhs.theLocalOrigin;
+         theAffineTransform        = rhs.theAffineTransform;
+      }
+   virtual ~ossimFont()
+      {}
+   virtual ossimObject* dup()const=0;
+
+   /*!
+    * Returns true if this font is a fixed size font
+    */
+   virtual bool isFixed()const=0;
+
+   /*!
+    * You can get a list of fixed sizes supported by
+    * this font.
+    */
+   virtual void getFixedSizes(vector<ossimIpt>& sizes)const=0;
+
+   /*!
+    * Will return the previously rasterized buffer.
+    */
+   virtual const ossim_uint8* getBuf()const=0;
+   
+   /*!
+    * Will return an internal buffer for rasterizing and will
+    * also set the width, and height arguments of the returned buffer.
+    */
+   virtual const ossim_uint8* rasterize()=0;
+
+   virtual const ossim_uint8* rasterize(const ossimString& s)
+      {
+         setString(s);
+         return rasterize();
+      }
+
+   virtual void setString(const ossimString& s)
+      {
+         theStringToRasterize = s;
+      }
+   
+   /*!
+    * Will return the bounding box of the last string that was set
+    * to be rasterized in pixel space
+    */
+   virtual void getBoundingBox(ossimIrect& box)=0;
+
+   /*!
+    * Specifies if its helvetica, times new roman ... etc.
+    */ 
+   virtual ossimString getFamilyName()const
+      {
+         return theFamilyName;
+      }
+   
+   /*!
+    * Specifies if its bold or italic .. etc
+    */
+   virtual ossimString getStyleName()const
+      {
+         return theStyleName;
+      }
+
+   /*!
+    * Allow us to rotate a font.
+    */
+    virtual void setRotation(double rotationInDegrees);
+
+    virtual double getRotation()const
+      {
+         return theRotation;
+      }
+   
+   virtual void getRotation(double& rotation)const
+      {
+         rotation = theRotation;
+      }
+
+   virtual void setHorizontalVerticalShear(double horizontalShear,
+                                           double verticalShear)
+      {
+         theVerticalShear   = verticalShear;
+         theHorizontalShear = horizontalShear;
+         computeMatrix();
+      }
+   virtual void setVerticalShear(double verticalShear)
+      {
+         setHorizontalVerticalShear(theHorizontalShear,
+                                    verticalShear);
+      }
+
+   virtual void setHorizontalShear(double horizontalShear)
+      {
+         setHorizontalVerticalShear(horizontalShear,
+                                    theVerticalShear);
+      }
+
+   virtual double getVerticalShear()const
+      {
+         return theVerticalShear;
+      }
+
+   virtual double getHorizontalShear()const
+      {
+         return theHorizontalShear;
+      }
+
+   /*!
+    * Sets the scale of the font. I'll have code in place to perform
+    * reflections.  This can be specified with a - scale along the direction
+    * you wish to reflect.
+    */
+   virtual void setScale(double horizontal,
+                         double vertical);
+   
+   virtual void getScale(double& horizontal,
+                         double& vertical)
+      {
+         horizontal = theHorizontalScale;
+         vertical   = theVerticalScale;
+      }
+
+   virtual void setPixelSize(int horizontalPixelSize,
+                             int verticalPixelSize)
+      {
+         theHorizontalPixelSize = horizontalPixelSize;
+         theVerticalPixelSize   = verticalPixelSize;
+      }
+
+   virtual void setPixelSize(int pixelSize)
+      {
+         setPixelSize(pixelSize, pixelSize);
+      }
+   
+   virtual void getPixelSize(int& horizontal,
+                             int& vertical)
+      {
+         horizontal = theHorizontalPixelSize;
+         vertical   = theVerticalPixelSize;
+      }
+
+   virtual long getHorizontalPixelSize()const
+      {
+         return theHorizontalPixelSize;
+      }
+   virtual ossimIpt getPixelSize()const
+      {
+         return ossimIpt(theHorizontalPixelSize,
+                         theVerticalPixelSize);
+      }
+   virtual long getVerticalPixelSize()const
+      {
+         return theVerticalPixelSize;
+      }
+
+   virtual void setDeviceDpi(int horizontalDeviceUnits,
+                             int verticalDeviceUnits)
+      {
+         theHorizontalDeviceUnits = horizontalDeviceUnits;
+         theVerticalDeviceUnits   = verticalDeviceUnits;
+      }
+   
+   /*!
+    * Will clip the clipping box with the bounding box of the string and this
+    * is the viewable information.
+    *
+    * If the clipping box is set then this should be used to get the dimensions
+    * of the buffer.
+    */
+   virtual void getBufferRect(ossimIrect& bufRect)
+      {
+         getBoundingClipBox(bufRect);
+      }
+   
+   virtual ossimIrect getBufferRect()
+      {
+         return getBoundingClipBox();
+      }
+   
+   virtual void getBoundingClipBox(ossimIrect& clippedBox);
+   
+   virtual ossimIrect getBoundingClipBox();
+   
+   virtual void setClippingBox(const ossimIrect& clipBox=ossimIrect(0,0,0,0))
+      {
+         theClippingBox = clipBox;
+      }
+   
+   virtual ossimIrect getClippingBox()const
+      {
+         return theClippingBox;
+      }
+
+   bool isIdentityTransform()const
+      {
+         return ( (theAffineTransform[0][0] == 1.0) && (theAffineTransform[1][0] == 0.0)&&
+                  (theAffineTransform[0][1] == 0.0) && (theAffineTransform[1][1] == 1.0));
+      }
+   virtual void getFontInformation(vector<ossimFontInformation>& fontInformationList)const
+      {
+         fontInformationList.push_back(ossimFontInformation(getFamilyName(),
+                                                            getStyleName(),
+                                                            getPixelSize(),
+                                                            isFixed()));         
+      }
+
+protected:
+   ossimString theStringToRasterize;
+   ossimString theFamilyName;
+   ossimString theStyleName;
+   double      theRotation;
+   double      theHorizontalShear;
+   double      theVerticalShear;
+   double      theHorizontalScale;
+   double      theVerticalScale;
+   int         theHorizontalPixelSize;
+   int         theVerticalPixelSize;
+   int         theHorizontalDeviceUnits;
+   int         theVerticalDeviceUnits;
+   ossimIrect  theClippingBox;
+   /*!
+    * During the compution of the global bounding rect we will
+    * Make sure that we save off the upper left since its not really 0,0.
+    * We will make sure that the bounding rect is shifted to 0,0 but the
+    * shift will be saved.  That way we can render the shape correctly
+    * later.
+    */
+   mutable ossimIpt    theLocalOrigin;
+   
+   NEWMAT::Matrix  theAffineTransform;
+
+
+   void computeMatrix();
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/fonts/ossimFreeTypeFont.cpp b/Utilities/OSSIM/ossim_core/fonts/ossimFreeTypeFont.cpp
new file mode 100644
index 0000000000..2b6f920321
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/ossimFreeTypeFont.cpp
@@ -0,0 +1,646 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimFreeTypeFont.cpp,v 1.27 2005/12/10 21:21:01 dburken Exp $
+
+// ossimFreeTypeFont.h should be load prior to checking for OSSIM_HAS_FREETYPE.
+#include <fonts/ossimFreeTypeFont.h>
+
+#if OSSIM_HAS_FREETYPE
+#  include <matrix/newmatio.h>
+#  include <base/data_types/ossimFilename.h>
+#  include <base/context/ossimErrorContext.h>
+#  include <base/common/ossimTrace.h>
+#  include <string.h> // for memset
+#  ifndef NULL
+#    include <stddef.h>
+#  endif
+
+static ossimTrace traceDebug ("ossimFreeTypeFont:debug");
+
+RTTI_DEF1(ossimFreeTypeFont, "ossimFreeTypeFont", ossimFont);
+
+ossimFreeTypeFont::ossimFreeTypeFont(const ossimFilename& fontFile)
+   :ossimFont(),
+    theFontFace(NULL),
+    theLibrary(NULL),
+    theFontFile(fontFile),
+    theOutputBuffer(NULL),
+    theBufferSize(0),
+    theKerningEnabledFlag(true),
+    theNeedToLayoutGlyphsFlag(true),
+    theBoundingRectIsValid(false)
+{
+   int error;
+   if(fontFile.exists())
+   {
+      error = FT_Init_FreeType(&theLibrary);
+      if(error)
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimFreeTypeFont::ossimFreeTypeFont: Can't initialize freetype" << std::endl;
+         setErrorStatus();
+      }
+      if(getErrorStatus() == ossimErrorCodes::OSSIM_OK)
+      {
+         error = FT_New_Face( theLibrary,
+                              fontFile.c_str(),
+                              0,
+                              &theFontFace );
+         if((error == FT_Err_Unknown_File_Format))
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "WARNING ossimFreeTypeFont::ossimFreeTypeFont: Unable to create a font face for file = "
+                  << fontFile
+                  << std::endl;
+            }
+            FT_Done_Library(theLibrary);
+            theLibrary = NULL;
+            setErrorStatus();
+         }
+         else
+         {
+            setBaseClassInformation();
+         }
+      }
+   }
+   else
+   {
+      setErrorStatus();
+   }
+}
+
+ossimFreeTypeFont::ossimFreeTypeFont(const ossimFreeTypeFont& rhs)
+   :ossimFont(rhs),
+    theMatrix(rhs.theMatrix),
+    theFontFile(rhs.theFontFile),
+    theOutputBuffer(NULL),
+    theBufferSize(0),
+    theKerningEnabledFlag(rhs.theKerningEnabledFlag),
+    theNeedToLayoutGlyphsFlag(rhs.theNeedToLayoutGlyphsFlag),
+    theStringCenter(rhs.theStringCenter),
+    theShift(rhs.theShift),
+    thePrecomputedBoundingRect(rhs.thePrecomputedBoundingRect),
+    theBoundingRectIsValid(rhs.theBoundingRectIsValid)   
+{   
+   if(rhs.getErrorStatus())
+   {
+      setErrorStatus();
+   }
+   else
+   {
+      int error;
+      error = FT_Init_FreeType(&theLibrary);
+      
+      if(error)
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimFreeTypeFoont::ossimFreeTypeFont: Can't initialize freetype in copy constructor" <<std::endl;
+         setErrorStatus();
+      }
+      if(getErrorStatus() == ossimErrorCodes::OSSIM_OK)
+      {
+         error = FT_New_Face( theLibrary,
+                              rhs.theFontFile.c_str(),
+                              0,
+                              &theFontFace );
+         if((error == FT_Err_Unknown_File_Format))
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "WARNING ossimFreeTypeFoont::ossimFreeTypeFont: Unable to create a font face for file = "
+                  << rhs.theFontFile
+                  << std::endl;
+            }
+            
+            FT_Done_Library(theLibrary);
+            theLibrary = NULL;
+            setErrorStatus();
+         }
+         else
+         {
+            if(rhs.theBufferSize)
+            {
+               theBufferSize = rhs.theBufferSize;
+               theOutputBuffer = new ossim_uint8[theBufferSize];
+               memcpy(theOutputBuffer, rhs.theOutputBuffer, theBufferSize);
+               setBaseClassInformation();
+               theNeedToLayoutGlyphsFlag = true;
+               layoutGlyphs(theStringToRasterize);
+            }
+         }
+      }
+   }      
+}
+
+ossimFreeTypeFont::~ossimFreeTypeFont()
+{
+   if(theOutputBuffer)
+   {
+      delete [] theOutputBuffer;
+      theOutputBuffer = NULL;
+   }
+   if(theFontFace)
+   {
+      FT_Done_Face(theFontFace);
+      theFontFace = NULL;
+   }
+   if(theLibrary)
+   {
+      FT_Done_FreeType(theLibrary);
+      theLibrary = NULL;
+   }
+}
+
+void ossimFreeTypeFont::layoutGlyphs(const ossimString& s )
+{
+   if(!theNeedToLayoutGlyphsFlag||!theFontFace)
+   {
+      return;
+   }
+
+   
+   int        n;
+   FT_Vector  origin;
+   FT_Pos     origin_x = 0;
+   FT_UInt    load_flags;
+   FT_UInt    num_grays;
+   FT_UInt    prev_index = 0;
+   FT_UInt num_glyphs = s.size();
+   int error = 0;
+   
+   deleteGlyphs(theStringLayout);
+   theStringLayout.resize(s.size());
+
+   theMatrix.xx = (FT_Fixed)(theAffineTransform[0][0]*0x10000);
+   theMatrix.xy = (FT_Fixed)(theAffineTransform[1][0]*0x10000);
+   theMatrix.yx = (FT_Fixed)(theAffineTransform[0][1]*0x10000);
+   theMatrix.yy = (FT_Fixed)(theAffineTransform[1][1]*0x10000);
+   
+   int hasKerning = FT_HAS_KERNING(theFontFace);
+   
+   load_flags = FT_LOAD_DEFAULT;
+   
+   num_grays = 256;
+   const char* c = s.c_str();
+   for ( n = 0; n < (int)num_glyphs; n++)
+   {
+      long charOffset = c[n];
+      
+      FT_ULong charIndex = 0;
+
+      if(charOffset < 0)
+      {
+         charIndex = (charOffset + 256);
+      }
+      else
+      {
+         charIndex = charOffset;
+      }
+      theStringLayout[n].glyph_index = FT_Get_Char_Index( theFontFace,
+                                                          charIndex );
+      theStringLayout[n].image = NULL;
+      /* compute glyph origin */
+      if (hasKerning&&theKerningEnabledFlag&&prev_index)
+      {
+         FT_Vector  kern;
+         
+         
+         FT_Get_Kerning( theFontFace,
+                         prev_index,
+                         theStringLayout[n].glyph_index,
+                         ft_kerning_default,
+                         &kern );
+         
+         origin_x += (kern.x);
+      }
+      
+      origin.x = origin_x;
+      origin.y = 0;
+      
+      
+      /* load the glyph image (in its native format); */
+      /* for now, we take a monochrome glyph bitmap   */
+      error = FT_Load_Glyph( theFontFace,
+                             theStringLayout[n].glyph_index,
+                             FT_LOAD_DEFAULT);
+      if ( error )
+      {
+         continue;
+      }
+      
+      error = FT_Get_Glyph ( theFontFace->glyph, &theStringLayout[n].image );
+      
+      if ( error )
+      {
+         continue;
+      }
+      
+      theStringLayout[n].pos = origin;
+      
+      origin_x  += (theFontFace->glyph->advance.x);
+      prev_index = theStringLayout[n].glyph_index;
+   }
+   
+   theStringCenter.x = origin_x / 2;
+   theStringCenter.y = 0;
+
+   FT_Vector_Transform( &theStringCenter, &theMatrix );
+   theNeedToLayoutGlyphsFlag = false;
+}
+
+const ossim_uint8* ossimFreeTypeFont::rasterize()
+{
+   allocateBuffer();
+   setupForRasterization();
+   layoutGlyphs(theStringToRasterize);
+
+   int num_glyphs = theStringLayout.size();
+   int        n;
+   FT_Vector  delta;
+   int        error;
+   
+   /* first of all, we must compute the general delta for the glyph set */
+   delta.x = -theStringCenter.x;
+   delta.y = 0;
+
+   memset(theOutputBuffer, 0, theBufferSize);
+   for ( n = 0; n < num_glyphs; n++)
+   {
+      FT_Glyph   image;
+      FT_Vector  vec;
+      
+      
+      if ( !theStringLayout[n].image )
+      {
+         continue;
+      }
+      
+      /* copy image */
+      error = FT_Glyph_Copy( theStringLayout[n].image, &image );
+      if ( error )
+         continue;
+      
+      /* transform it */
+      vec = theStringLayout[n].pos;
+      FT_Vector_Transform( &vec, &theMatrix );
+      vec.x += (delta.x);
+      vec.y += (delta.y);
+      error = FT_Glyph_Transform( image, &theMatrix, &vec );
+      if ( !error )
+      {
+         FT_BBox  bbox;
+         /* check bounding box; if it is not within the display surface, */
+         /* we don't need to render it                                   */
+         
+         FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox );
+
+         // since freetype coordinates are right handed we will
+         // adjust the rects so they are right handed before passing
+         // them to our rendering system.
+         //
+         ossimIrect box(bbox.xMin,
+                        bbox.yMax,
+                        bbox.xMax,
+                        bbox.yMin,
+                        OSSIM_RIGHT_HANDED);
+         ossimIrect bufRect;
+         ossimIrect boundingBox;;
+         getBufferRect(bufRect);
+         getBoundingBox(boundingBox);
+         
+         bufRect = ossimIrect(bufRect.ul().x,
+                              boundingBox.lr().y - bufRect.ul().y,
+                              bufRect.lr().x,
+                              boundingBox.lr().y - bufRect.lr().y,
+                              OSSIM_RIGHT_HANDED);
+         box += ossimIpt(-theShift.x,
+                         -theShift.y);
+         if(bufRect.intersects(box))
+         {
+            // now let's convert it to a bitmap
+            error = FT_Glyph_To_Bitmap( &image,
+                                        ft_render_mode_normal,
+                                        0,
+                                        1 );
+            if ( !error )
+            {
+               // cast it
+               FT_BitmapGlyph  bitmap = (FT_BitmapGlyph)image;
+
+               ossimIpt ul(bitmap->left -theShift.x,
+                           bitmap->top  -theShift.y);
+
+               // the bounding char box does not coorespond to the
+               // buffer rect of rfreetype's internal sorage.
+               // We will need to adjust the box and then render it
+               //
+               box = ossimIrect(ul.x,
+                                ul.y,
+                                ul.x + bitmap->bitmap.width-1,
+                                ul.y - (bitmap->bitmap.rows-1),
+                                OSSIM_RIGHT_HANDED);
+
+               // draw the sub rect within our buffer.
+               drawBitmap(&bitmap->bitmap,
+                          bufRect,
+                          box);
+            }
+         }
+      }
+      FT_Done_Glyph( image );
+    }
+    
+    return theOutputBuffer;    
+}
+
+void ossimFreeTypeFont::getBoundingBox(ossimIrect& box)
+{
+
+   if(theBoundingRectIsValid)
+   {
+      box = thePrecomputedBoundingRect;
+      return;
+   }
+   setupForRasterization();
+   layoutGlyphs(theStringToRasterize);
+
+   int num_glyphs = theStringLayout.size();
+   int        n;
+   FT_Vector  delta;
+   int        error;
+   bool firstBoxSet = false;
+   /* first of all, we must compute the general delta for the glyph set */
+   delta.x = -theStringCenter.x;
+   delta.y = 0;
+   
+   for ( n = 0; n < num_glyphs; n++)
+   {
+      FT_Glyph   image;
+      FT_Vector  vec;
+      
+      
+      if ( !theStringLayout[n].image )
+      {
+         continue;
+      }
+      
+      /* copy image */
+      error = FT_Glyph_Copy( theStringLayout[n].image, &image );
+      if ( error )
+         continue;
+      
+      /* transform it */
+      vec = theStringLayout[n].pos;
+      FT_Vector_Transform( &vec, &theMatrix );
+      vec.x += (delta.x);
+      vec.y += (delta.y);
+      error = FT_Glyph_Transform( image, &theMatrix, &vec );
+      if ( !error )
+      {
+         FT_BBox  bbox;
+         /* check bounding box; if it is not within the display surface, */
+         /* we don't need to render it                                   */
+         
+         FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox );
+         ossimIrect charBox(bbox.xMin,
+                            bbox.yMin,
+                            bbox.xMax,
+                            bbox.yMax);
+            
+            if(firstBoxSet)
+            {
+               box =  box.combine(charBox);
+            }
+            else
+            {
+               firstBoxSet = true;
+               box = charBox;
+            }
+      }
+      FT_Done_Glyph( image );
+   }
+
+   theShift = box.ul();
+
+   box += ossimIpt(-theShift.x,
+                   -theShift.y);
+
+   thePrecomputedBoundingRect = box;
+}
+
+void ossimFreeTypeFont::computeGlyphBox(FT_Glyph slot,
+                                        ossimIrect& box)const
+{
+   long yBearing = theFontFace->glyph->metrics.horiBearingY/64;
+   long h        = theFontFace->glyph->metrics.height/64;
+   long w        = theFontFace->glyph->metrics.width/64;
+
+   if(h&&w)
+   {
+      box = ossimIrect(0,
+                       yBearing-(h-1),
+                       (w-1),
+                       yBearing);
+   }
+   else
+   {
+      box = ossimIrect(0,0,0,0);
+   }   
+}
+
+void ossimFreeTypeFont::drawBitmap(FT_Bitmap* bitmap,
+                                   const ossimIrect& bufRect,
+                                   const ossimIrect& glyphBox)
+{
+   if(bufRect.intersects(glyphBox))
+   {
+      unsigned char* buf   = bitmap->buffer;
+      if(!theOutputBuffer||!buf) return;
+      
+      ossimIrect intersectionRect = bufRect.clipToRect(glyphBox);
+      
+
+      long difInX           = intersectionRect.ul().x - glyphBox.ul().x;
+      long difInY           = glyphBox.ul().y - intersectionRect.ul().y;
+      
+      long difOutX          = intersectionRect.ul().x - bufRect.ul().x;
+      long difOutY          = bufRect.ul().y - intersectionRect.ul().y;
+
+      
+      
+      long startInOffset    = bitmap->width*difInY + difInX;
+      long startOutOffset   = bufRect.width()*difOutY + difOutX;
+      
+      long outBufW = bufRect.width();
+      long inBufW  = bitmap->width;
+
+      // let's just make sure that the increment will not exceed the input
+      // buffers width and height.
+      //
+      long height  = std::min((long)intersectionRect.height(), (long)glyphBox.height());
+      long width   = std::min((long)intersectionRect.width(), (long)glyphBox.width());
+      
+      for(long rows = 0 ; rows < height; ++rows)
+      {
+         for(long cols = 0; cols < width; ++cols)
+         {
+            if(buf[startInOffset+cols])
+            {
+               theOutputBuffer[startOutOffset + cols] = buf[startInOffset+cols];
+            }
+         }
+         startInOffset+=inBufW;
+         startOutOffset+=outBufW;
+      }
+   }
+}
+
+void ossimFreeTypeFont::setupForRasterization()
+{
+   int error=0;
+   if(!theFontFace) return;
+
+   if(!theFontFace->charmap)
+   {
+     error = FT_Select_Charmap(theFontFace,     /* target face object */
+			       ft_encoding_big5 );   /* encoding..         */   
+   }
+
+   error = FT_Set_Char_Size(theFontFace,
+                            theHorizontalPixelSize*64,
+                            theVerticalPixelSize*64,
+                            theHorizontalDeviceUnits,
+                            theVerticalDeviceUnits);
+   if(error)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimFreeTypeFont::setupForRasterization: Cant set the pixel size" <<std::endl;
+   }
+}
+
+void ossimFreeTypeFont::setBaseClassInformation()
+{
+   if(theFontFace)
+   {
+      theFamilyName = theFontFace->family_name;
+
+      if(isFixed())
+      {
+         vector<ossimIpt> initialPointList;
+         getFixedSizes(initialPointList);
+
+         theHorizontalPixelSize = initialPointList[0].x;
+         theVerticalPixelSize   = initialPointList[0].y;
+      }
+      else
+      {
+         theHorizontalPixelSize = 8;
+         theVerticalPixelSize   = 8;
+      }
+      if((theFontFace->style_flags & FT_STYLE_FLAG_BOLD) &&
+         (theFontFace->style_flags&FT_STYLE_FLAG_ITALIC))
+      {
+         theStyleName = "bold italic";
+      }
+      else if(theFontFace->style_flags & FT_STYLE_FLAG_BOLD)
+      {
+         theStyleName = "bold";
+      }
+      else if(theFontFace->style_flags & FT_STYLE_FLAG_ITALIC)
+      {
+         theStyleName = "italic";
+      }
+      else
+      {
+         theStyleName = "normal";
+      }
+   }
+}
+
+
+void ossimFreeTypeFont::setCurrentFace(long index)
+{
+   int error;
+   if(theFontFace)
+   {
+      if((index >0) && (index < theFontFace->num_faces))
+      {
+         FT_Done_Face(theFontFace);
+         theFontFace = NULL;
+         
+         error = FT_New_Face( theLibrary,
+                              theFontFile.c_str(),
+                              index,
+                              &theFontFace );
+         if((error == FT_Err_Unknown_File_Format)||error)
+         {
+            setErrorStatus();
+         }
+         else
+         {
+            setBaseClassInformation();
+         }
+         theBoundingRectIsValid = false;
+      }
+   }
+}
+
+void ossimFreeTypeFont::getFixedSizes(vector<ossimIpt>& sizeArray)const
+{
+   if(theFontFace)
+   {
+      sizeArray.clear();
+      int i = 0;
+
+      for(i = 0; i < theFontFace->num_fixed_sizes; ++i)
+      {
+         sizeArray.push_back(ossimIpt(theFontFace->available_sizes[i].width,
+                                      theFontFace->available_sizes[i].height));
+      }
+   }
+}
+
+void ossimFreeTypeFont::allocateBuffer()
+{   
+   ossimIrect box;
+   setupForRasterization();
+   getBoundingClipBox(box);
+   long bufferSize = box.width()*box.height();
+   if(bufferSize != theBufferSize)
+   {
+      theBufferSize = bufferSize;
+      
+      if(theOutputBuffer)
+      {
+         delete theOutputBuffer;
+         theOutputBuffer = NULL;
+      }
+      if(!theOutputBuffer&&theBufferSize)
+      {
+         theOutputBuffer = new ossim_uint8[theBufferSize];            
+      }
+   }
+}
+
+void ossimFreeTypeFont::deleteGlyphs(vector<TGlyph>& glyphs)
+{
+   int i = 0;
+
+   for(i = 0; i < (int)glyphs.size(); ++i)
+   {
+      if(glyphs[i].image)
+      {
+         FT_Done_Glyph(glyphs[i].image);
+      }
+   }
+   
+   glyphs.clear();
+}
+
+#endif /* #if OSSIM_HAS_FREETYPE */
diff --git a/Utilities/OSSIM/ossim_core/fonts/ossimFreeTypeFont.h b/Utilities/OSSIM/ossim_core/fonts/ossimFreeTypeFont.h
new file mode 100644
index 0000000000..1a78ddf9e7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/ossimFreeTypeFont.h
@@ -0,0 +1,199 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimFreeTypeFont.h,v 1.18 2005/12/10 21:21:01 dburken Exp $
+#ifndef ossimFreeTypeFont_HEADER
+#define ossimFreeTypeFont_HEADER
+
+#include <ossimConfig.h> /* To pick up OSSIM_HAS_FREETYPE. */
+
+#if OSSIM_HAS_FREETYPE
+#  include "ossimFont.h"
+#  include <ft2build.h>
+#  include FT_FREETYPE_H
+//#include <freetype/freetype.h>
+#  include FT_MODULE_H // for FT_Done_Library
+#  include FT_GLYPH_H
+
+#  include "base/data_types/ossimFilename.h"
+
+
+typedef struct  TGlyph_
+{
+   FT_UInt    glyph_index;         /* glyph index in face      */
+   FT_Vector  pos;                 /* position of glyph origin */
+   FT_Glyph   image;               /* glyph image              */
+   
+} TGlyph, *PGlyph;
+
+class ossimFreeTypeFont: public ossimFont
+{
+public:
+   ossimFreeTypeFont(const ossimFilename& fontFile);
+   ossimFreeTypeFont(const ossimFreeTypeFont& rhs);
+
+   virtual ossimObject* dup()const
+      {
+         return new ossimFreeTypeFont(*this);
+      }
+   virtual ~ossimFreeTypeFont();
+
+   virtual const ossim_uint8* getBuf()const
+      {
+         return theOutputBuffer;
+      }
+   
+   void layoutGlyphs(vector<TGlyph>& glyphs,
+                     const ossimString& s );
+   
+   virtual const ossim_uint8* rasterize();
+   void getBoundingBox(ossimIrect& box);
+
+   long getNumberOfFaces()const
+      {
+         if(theFontFace)
+         {
+            return theFontFace->num_faces;
+         }
+         return 0;
+      }
+   void setCurrentFace(long index);
+
+   /*!
+    * Fonts found in files .FNT and .PCF are fixed
+    */
+   bool isFixed()const
+      {
+         if(theFontFace)
+         {
+            return (theFontFace->num_fixed_sizes > 0);
+         }
+         return false;
+      }
+   
+   virtual void getFixedSizes(vector<ossimIpt>& sizeArray)const;
+
+   /*!
+    * Will enable kerning support.  This is enabled
+    * by default.  This is for true type fonts and
+    * if its available for the current font this
+    * will tell us to make sure we use it.  This
+    * adjusts spacing between pairs of glyphs.
+    */
+   virtual void enableKerningSupport()
+      {
+         theKerningEnabledFlag = true;
+         theBoundingRectIsValid = false;
+      }
+
+   /*!
+    * Will disable kerning support.  
+    */   
+   virtual void disableKerningSupport()
+      {
+         theKerningEnabledFlag = false;
+         theBoundingRectIsValid = false;
+      }
+
+   virtual void setHorizontalVerticalShear(double horizontalShear,
+                                           double verticalShear)
+      {
+         ossimFont::setHorizontalVerticalShear(horizontalShear,
+                                               verticalShear);
+         theBoundingRectIsValid = false;
+      }
+   virtual void setScale(double horizontal,
+                         double vertical)
+      {
+         ossimFont::setScale(horizontal,
+                             vertical);
+         theBoundingRectIsValid = false;
+      }
+
+   virtual void setPixelSize(int horizontalPixelSize,
+                             int verticalPixelSize)
+      {
+         ossimFont::setPixelSize(horizontalPixelSize,
+                                 verticalPixelSize);
+         theBoundingRectIsValid = false;
+      }
+   virtual void setPixelSize(int pixelSize)
+      {
+         ossimFont::setPixelSize(pixelSize);
+         theBoundingRectIsValid = false;         
+      }
+   
+   virtual void setDeviceDpi(int horizontalDeviceUnits,
+                             int verticalDeviceUnits)
+      {
+         ossimFont::setDeviceDpi(horizontalDeviceUnits,
+                                 verticalDeviceUnits);
+         theBoundingRectIsValid = false;
+      }
+   virtual void setString(const ossimString& s)
+      {
+         ossimFont::setString(s);
+         theBoundingRectIsValid = false;
+         theNeedToLayoutGlyphsFlag = true;
+      }
+
+  const FT_Face getFontFace()const
+  {
+    return theFontFace;
+  }
+private:
+   
+   FT_Face       theFontFace;
+   FT_Library    theLibrary;
+   FT_Matrix     theMatrix;
+   
+   ossimFilename theFontFile;
+
+   ossim_uint8*  theOutputBuffer;
+   long          theBufferSize;
+   bool          theKerningEnabledFlag;
+   bool          theNeedToLayoutGlyphsFlag;
+   FT_Vector     theStringCenter;
+   ossimIpt      theShift;
+   /*!
+    * Pre-compute all glyphs but don't render it
+    */
+   vector<TGlyph> theStringLayout;
+   
+   /*!
+    * We will precompute the bounding rect only when we have to.
+    * this will avoid re-computing on all rasterization calls.  We
+    * will use the dirty flag to tell us if we need to re-compute.
+    */
+   mutable ossimIrect    thePrecomputedBoundingRect;
+
+
+   /*!
+    * Used to tell us when we need to recompute.
+    */
+   mutable bool          theBoundingRectIsValid;
+   void layoutGlyphs(const ossimString& s);
+   
+   void setBaseClassInformation();
+   void setupForRasterization();
+   void allocateBuffer();
+
+   void drawBitmap(FT_Bitmap* bitmap,
+                   const ossimIrect& bufRect,
+                   const ossimIrect& glyphBox);
+
+   void computeGlyphBox(FT_Glyph,
+                        ossimIrect& box)const;
+   void deleteGlyphs(vector<TGlyph>& glyphs);
+
+TYPE_DATA
+};
+
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/fonts/ossimGdBitmapFont.cpp b/Utilities/OSSIM/ossim_core/fonts/ossimGdBitmapFont.cpp
new file mode 100644
index 0000000000..7fc1de3784
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/ossimGdBitmapFont.cpp
@@ -0,0 +1,263 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: 
+// 
+//********************************************************************
+// $Id: ossimGdBitmapFont.cpp,v 1.7 2003/05/13 11:31:03 dburken Exp $
+#include "fonts/ossimGdBitmapFont.h"
+#include "string.h"
+
+RTTI_DEF1(ossimGdBitmapFont, "ossimGdBitmapFont", ossimFont);
+
+ossimGdBitmapFont::ossimGdBitmapFont(const ossimString& familyName,
+                                     const ossimString& styleName,
+                                     const ossimGdFont* gdFontPtr)
+   :ossimFont(familyName,
+              styleName,
+              (int)gdFontPtr->w,
+              (int)gdFontPtr->h),
+    theGdFontPtr(gdFontPtr),
+    theBufferSize(0),
+    theOutputBuffer(NULL)
+{
+}
+
+ossimGdBitmapFont::ossimGdBitmapFont(const ossimGdBitmapFont& rhs)
+   :ossimFont(rhs),
+    theGdFontPtr(rhs.theGdFontPtr),
+    theBufferSize(rhs.theBufferSize),
+    theOutputBuffer(NULL)    
+{
+   if(theBufferSize)
+   {
+      theOutputBuffer = new ossim_uint8[theBufferSize];
+      memcpy(theOutputBuffer, rhs.theOutputBuffer, theBufferSize);
+   }
+}
+
+ossimGdBitmapFont::~ossimGdBitmapFont()
+{
+   if(theOutputBuffer)
+   {
+      delete [] theOutputBuffer;
+      theOutputBuffer = NULL;
+   }
+}
+
+void ossimGdBitmapFont::getBoundingBox(ossimIrect& box)
+{
+   if(theStringToRasterize.size())
+   {
+      box = ossimIrect(0,0,
+                       (int)ceil(theStringToRasterize.size()*theHorizontalPixelSize*theHorizontalScale)-1,
+                       (int)ceil(theVerticalPixelSize*theVerticalScale)-1);
+   }
+   else
+   {
+      box = ossimIrect(0,
+                       0,
+                       0,
+                       0);
+   }
+
+   // I currently don't support rotations and other affine operations so I will comment this
+   // bounding box test out and use the above.
+   //
+#if 0
+   if(theGdFontPtr)
+   {
+      if((theRotation == 0.0)&&
+         (theHorizontalScale == 1.0)&&
+         (theVerticalScale   == 1.0))
+      {
+         box = ossimIrect(0,0, theGdFontPtr->w-1, theGdFontPtr->h-1);
+      }
+      else
+      {
+         ossimIrect localBox(0,0, theGdFontPtr->w-1, theGdFontPtr->h-1);
+         double ulx, uly;
+         double llx, lly;
+         double lrx, lry;
+         double urx, ury;
+         
+         double min_x, min_y, max_x, max_y;
+
+         ulx = 0.0;
+         uly = 0.0;
+
+         llx = (theAffineTransform[0][0]*localBox.ll().x +
+                theAffineTransform[0][1]*localBox.ll().y);
+         lly = theAffineTransform[1][0]*localBox.ll().x +
+               theAffineTransform[1][1]*localBox.ll().y;
+         
+         lrx = (theAffineTransform[0][0]*localBox.lr().x +
+                theAffineTransform[0][1]*localBox.lr().y);
+         lry = theAffineTransform[1][0]*localBox.lr().x +
+               theAffineTransform[1][1]*localBox.lr().y;
+         urx = (theAffineTransform[0][0]*localBox.ur().x +
+                theAffineTransform[0][1]*localBox.ur().y);
+         ury = theAffineTransform[1][0]*localBox.ur().x +
+               theAffineTransform[1][1]*localBox.ur().y;
+
+         
+         min_x = std::min(ulx, std::min(llx, (std::min(lrx, urx))));
+         max_x = std::max(ulx, std::max(llx, (std::max(lrx, urx))));
+
+         min_y = std::min(uly, std::min(lly, (std::min(lry, ury))));
+         max_y = std::max(uly, std::max(lly, (std::max(lry, ury))));
+
+
+         
+         box = ossimIrect((int)floor(min_x), (int)floor(min_y),
+                          (int)ceil(max_x), (int)ceil(max_y));
+      }
+   }
+#endif
+}
+
+const ossim_uint8* ossimGdBitmapFont::rasterize()
+{
+   // make sure the buffer is allocated for the output string
+   allocateBuffer();
+
+   if(theOutputBuffer)
+   {
+      memset(theOutputBuffer, 0, theBufferSize);
+      rasterizeNormal();
+   }
+
+   return theOutputBuffer;
+}
+
+void ossimGdBitmapFont::rasterizeNormal()
+{
+   ossimIrect outBox;
+   ossimIrect inBox(0,0,
+                    theStringToRasterize.length()*theGdFontPtr->w-1,
+                    theGdFontPtr->h-1);
+   
+   getBoundingBox(outBox);
+
+   
+   long charOffset = 0;
+   long bufOffset  = 0;
+   long inW    = inBox.width();
+   long inH    = inBox.height();
+   long outW = outBox.width();
+   long outH = outBox.height();
+   ossim_uint8* inBuf = new ossim_uint8[inBox.width()*inBox.height()];
+      
+   for(long character = 0;
+       character < (long)theStringToRasterize.size();
+       ++character)
+   {
+      charOffset = theStringToRasterize[(int)character];
+      
+      // we need to shift the offset to a positive value.
+      // if it goes negative we just add 256 to the value.
+      if(charOffset < 0)
+      {
+         charOffset += 256;
+      }
+
+      // which col do we start on
+      bufOffset = character*theGdFontPtr->w;
+      
+      // get the starting offset to the bitmap
+      charOffset  = charOffset*theGdFontPtr->w*theGdFontPtr->h;
+      
+      for(long row = 0; row < (theGdFontPtr->h); ++row)
+      {         
+         for(long col = 0; col < theGdFontPtr->w; ++col)
+         {
+            if(theGdFontPtr->data[charOffset])
+            {
+               inBuf[bufOffset+col] = 255;
+            }
+            ++charOffset;
+         }
+         bufOffset += inW;
+      }
+   }
+
+   if((inW == outW)&&(inH==outH))
+   {
+      memcpy(theOutputBuffer, inBuf, inW*inH);
+   }
+   else
+   {
+      // now lets expand or contract the input buf to the output buf.
+      long *xLut = new long[outW];
+      long *yLut = new long[outH];
+      long i = 0;
+      for(i = 0; i < outW; ++i)
+      {
+         xLut[i] = (int)(i*((double)inW/(double)outW));
+      }
+      for(i = 0; i < outH; ++i)
+      {
+         yLut[i] = (int)(i*((double)inH/(double)outH));
+      }
+      
+      ossim_uint8* outBuf = theOutputBuffer;
+      for(long row= 0; row < outH; ++row)
+      {
+         long inYOffset = yLut[row]*inW;
+         for(long col=0; col < outW; ++col)
+         {
+            *outBuf = inBuf[inYOffset + xLut[col]];
+            ++outBuf;
+         }
+      }
+      delete [] xLut;
+      delete [] yLut;
+   }
+
+   delete [] inBuf;
+}
+
+void ossimGdBitmapFont::allocateBuffer()
+{   
+   ossimIrect box;
+   
+   getBoundingBox(box);
+   long bufferSize = box.width()*box.height();
+   if(bufferSize != theBufferSize)
+   {
+      theBufferSize = bufferSize;
+      
+      if(theOutputBuffer)
+      {
+         delete theOutputBuffer;
+         theOutputBuffer = NULL;
+      }
+      if(!theOutputBuffer&&theBufferSize)
+      {
+         theOutputBuffer = new ossim_uint8[theBufferSize];
+            
+      }
+   }   
+}
+
+void ossimGdBitmapFont::getFixedSizes(vector<ossimIpt>& sizes)const
+{
+   sizes.push_back(ossimIpt(theHorizontalPixelSize,
+                            theVerticalPixelSize));
+}
diff --git a/Utilities/OSSIM/ossim_core/fonts/ossimGdBitmapFont.h b/Utilities/OSSIM/ossim_core/fonts/ossimGdBitmapFont.h
new file mode 100644
index 0000000000..96f508aba5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/ossimGdBitmapFont.h
@@ -0,0 +1,101 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: 
+// 
+//********************************************************************
+// $Id: ossimGdBitmapFont.h,v 1.8 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimGdBitmapFont_HEADER
+#define ossimGdBitmapFont_HEADER
+#include "fonts/ossimFont.h"
+
+struct ossimGdFont
+{
+	/* # of characters in font */
+	int nchars;
+	/* First character is numbered... (usually 32 = space) */
+	int offset;
+	/* Character width and height */
+	int w;
+	int h;
+	/* Font data; array of characters, one row after another.
+		Easily included in code, also easily loaded from
+		data files. */
+	char *data;
+};
+typedef ossimGdFont* ossimGdFontPtr;
+
+/*!
+ *  This is a wrapper for the gd library fonts.
+ *  Note that this class will currently only support scaling.  It will not support
+ *  any other affine operation.
+ */
+class ossimGdBitmapFont : public ossimFont
+{
+public:
+   
+   ossimGdBitmapFont(const ossimString& familyName,
+                     const ossimString& styleName,
+                     const ossimGdFont* gdFontPtr);
+
+   ossimGdBitmapFont(const ossimGdBitmapFont& rhs);
+   virtual ~ossimGdBitmapFont();
+
+   virtual ossimObject* dup()const
+      {
+         return new ossimGdBitmapFont(*this);
+      }
+   virtual const ossim_uint8* getBuf()const
+      {
+         return theOutputBuffer;
+      }
+    /*!
+    * Will return an internal buffer for rasterizing and will
+    */
+   virtual const ossim_uint8* rasterize();
+   virtual void getBoundingBox(ossimIrect& box);
+   bool isFixed()const
+      {
+         return true;
+      }
+   
+   virtual void getFixedSizes(vector<ossimIpt>& sizes)const;
+
+protected:
+   const ossimGdFont* theGdFontPtr;
+
+   long         theBufferSize;
+   ossim_uint8* theOutputBuffer;
+
+   /*!
+    * This will take into consideration the point size along
+    * the horizontal and vertical and also the scale
+    * values.  So the actual scale will be:
+    *
+    * Scale*(pointSize/fixedSize);
+    */
+   void getActualScale(ossimDpt& scales)const;
+
+   void rasterizeNormal();
+   void allocateBuffer();
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/fonts/ossimGdSansBold.inc b/Utilities/OSSIM/ossim_core/fonts/ossimGdSansBold.inc
new file mode 100644
index 0000000000..e9d774ae04
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/fonts/ossimGdSansBold.inc
@@ -0,0 +1,4383 @@
+
+/*
+   This is a header file for gd font, generated using
+   bdftogd version 0.51 by Jan Pazdziora, adelton@fi.muni.cz
+   from bdf font
+   -Misc-Fixed-Bold-R-Normal-Sans-15-140-75-75-C-90-ISO8859-2
+   at Mon Jan 26 14:45:58 1998.
+   The original bdf was holding following copyright:
+   "Libor Skarvada, libor@informatics.muni.cz"
+ */
+
+
+#include "ossimGdBitmapFont.h"
+
+char ossimGdSansBoldData[] =
+{
+/* Char 0 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 1 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 2 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+
+/* Char 3 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 4 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 5 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 6 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 7 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 8 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 9 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 10 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 11 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 12 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 13 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 14 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 15 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 16 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 17 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 18 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 19 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 20 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 21 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 22 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 23 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 24 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 25 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 26 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 27 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 28 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 29 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 30 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 0, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 31 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 32 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 33 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 34 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 35 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 36 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 37 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 38 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 39 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 40 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 41 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 42 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 43 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 44 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 45 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 46 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 47 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 48 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 49 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 50 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 51 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 52 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 53 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 54 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 55 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 56 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 57 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 58 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 59 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 60 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 61 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 62 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 63 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 64 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 65 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 66 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 67 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 68 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 69 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 70 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 71 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 72 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 73 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 74 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 75 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 76 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 77 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 78 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 79 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 80 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 81 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 82 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 83 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 84 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 85 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 86 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 87 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 88 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 89 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 90 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 91 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 92 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 93 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 94 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 95 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 96 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 97 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 98 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 99 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 100 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 101 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 102 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 103 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+
+/* Char 104 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 105 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 106 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+
+/* Char 107 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 108 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 109 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 110 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 111 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 112 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 113 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+
+/* Char 114 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 115 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 116 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 117 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 118 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 119 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 120 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 121 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+
+/* Char 122 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 123 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 124 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 125 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 126 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 127 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 128 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 129 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 130 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 131 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 132 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 133 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 134 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 135 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 136 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 137 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 138 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 139 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 140 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 141 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 142 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 143 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 144 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 145 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 146 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 147 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 148 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 149 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 150 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 151 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 152 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 153 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 154 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 155 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 156 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 157 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 158 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 159 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 160 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 161 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+
+/* Char 162 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 163 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 164 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 165 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 166 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 167 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 168 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 169 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 170 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+
+/* Char 171 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 172 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 173 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 174 */
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 175 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 176 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 177 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 1,
+
+/* Char 178 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+
+/* Char 179 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 180 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 181 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 182 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 183 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 184 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 185 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 186 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+
+/* Char 187 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 188 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 189 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 190 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 191 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 192 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 193 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 194 */
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 195 */
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 196 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 197 */
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 198 */
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 199 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 200 */
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 201 */
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 202 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+
+/* Char 203 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 204 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 205 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 206 */
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 207 */
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 208 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 209 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 210 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 211 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 212 */
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 213 */
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 214 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 215 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 216 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 217 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 218 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 219 */
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 220 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 221 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 222 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 223 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 224 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 225 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 226 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 227 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 228 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 229 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 230 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 231 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 232 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 233 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 234 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+
+/* Char 235 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 236 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 237 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 238 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 239 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 1, 1,
+  0, 0, 0, 0, 0, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 240 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 241 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 242 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 243 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 244 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 245 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 246 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 247 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 248 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 249 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 250 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 251 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 252 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 253 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+
+/* Char 254 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 255 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+
+};
+
+ossimGdFont ossimGdSansBoldRep =
+{
+  256,
+  0,
+  9,
+  15,
+  ossimGdSansBoldData
+};
+
+ossimGdFontPtr ossimGdSansBold = &ossimGdSansBoldRep;
+
+/* This file has not been truncated. */
diff --git a/Utilities/OSSIM/ossim_core/imaging/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/CMakeLists.txt b/Utilities/OSSIM/ossim_core/imaging/CMakeLists.txt
new file mode 100644
index 0000000000..890ea9460e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_imaging_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_imaging_HDRS "*.h")
+ADD_LIBRARY(ossim_imaging ${ossim_imaging_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_imaging)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_imaging_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/annotation/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontg.inc b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontg.inc
new file mode 100644
index 0000000000..f14aacee90
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontg.inc
@@ -0,0 +1,4384 @@
+
+
+/*
+   This is a header file for gd font, generated using
+   bdftogd version 0.51 by Jan Pazdziora, adelton@fi.muni.cz
+   from bdf font
+   -Misc-Fixed-Bold-R-Normal-Sans-15-140-75-75-C-90-ISO8859-2
+   at Mon Jan 26 14:45:58 1998.
+   The original bdf was holding following copyright:
+   "Libor Skarvada, libor@informatics.muni.cz"
+ */
+
+
+#include "ossimGdFont.h"
+
+char ossimGdFontGiantData[] =
+{
+/* Char 0 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 1 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 2 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 1, 0,
+
+/* Char 3 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 4 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 5 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 6 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 7 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 8 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 9 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 10 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 11 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 12 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 13 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 14 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 15 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 16 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 17 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 18 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 19 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 20 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 21 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 22 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 23 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 24 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 25 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 26 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 27 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 28 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 29 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 30 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 0, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 31 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 32 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 33 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 34 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 35 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 36 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 37 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 38 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 39 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 40 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 41 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 42 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 43 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 44 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 45 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 46 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 47 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 48 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 49 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 50 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 51 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 52 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 53 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 54 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 55 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 56 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 57 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 58 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 59 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 60 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 61 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 62 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 63 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 64 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 65 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 66 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 67 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 68 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 69 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 70 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 71 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 72 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 73 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 74 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 75 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 76 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 77 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 78 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 79 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 80 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 81 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 82 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 83 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 84 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 85 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 86 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 87 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 88 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 89 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 90 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 91 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 92 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 93 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 94 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 95 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 96 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 97 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 98 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 99 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 100 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 101 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 102 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 103 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+
+/* Char 104 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 105 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 106 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0, 0,
+
+/* Char 107 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 108 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 109 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 110 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 111 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 112 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 113 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+
+/* Char 114 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 115 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 116 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 117 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 118 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 119 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 120 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 121 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+
+/* Char 122 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 123 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 124 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 125 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 126 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 127 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 128 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 129 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 130 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 131 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 132 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 133 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 134 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 135 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 136 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 137 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 138 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 139 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 140 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 141 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 142 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 143 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 144 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 145 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 146 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 147 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 148 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 149 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 150 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 151 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 152 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 153 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 154 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 155 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 156 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 157 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 158 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 159 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 160 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 161 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+
+/* Char 162 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 163 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 164 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 165 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 166 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 167 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 168 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 169 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 170 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+
+/* Char 171 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 172 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 173 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 174 */
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 175 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 176 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 177 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 1,
+
+/* Char 178 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+
+/* Char 179 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 180 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 181 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 182 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 183 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 184 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 185 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 186 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+
+/* Char 187 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 188 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 189 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 190 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 191 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 192 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 193 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 194 */
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 195 */
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 196 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 197 */
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 198 */
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 199 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 200 */
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 201 */
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 202 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+
+/* Char 203 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 204 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 205 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 206 */
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 207 */
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 208 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 209 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 210 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 211 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 212 */
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 213 */
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 214 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 215 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 216 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 217 */
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 218 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 219 */
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 220 */
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 221 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 222 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 223 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 224 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 225 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 226 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 227 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 228 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 229 */
+  0, 0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 230 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 231 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 232 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 233 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 234 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+
+/* Char 235 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 236 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 237 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 238 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 239 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 1, 1,
+  0, 0, 0, 0, 0, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 240 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 241 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 242 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 243 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 244 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 245 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 246 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 247 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 248 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 249 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 250 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 251 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 252 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 253 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0, 0,
+
+/* Char 254 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+/* Char 255 */
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+
+};
+
+ossimGdFont ossimGdFontGiantRep =
+{
+  256,
+  0,
+  9,
+  15,
+  ossimGdFontGiantData
+};
+
+ossimGdFontPtr ossimGdFontGiant = &ossimGdFontGiantRep;
+
+/* This file has not been truncated. */
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontl.inc b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontl.inc
new file mode 100644
index 0000000000..f268f7f084
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontl.inc
@@ -0,0 +1,4641 @@
+
+
+/*
+   This is a header file for gd font, generated using
+   bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
+   from bdf font
+   -misc-fixed-medium-r-normal--16-140-75-75-c-80-iso8859-2
+   at Tue Jan  6 19:39:27 1998.
+
+   The original bdf was holding following copyright:
+   "Libor Skarvada, libor@informatics.muni.cz"
+ */
+
+
+#include "ossimGdFont.h"
+
+char ossimGdFontLargeData[] =
+{
+/* Char 0 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 1 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 2 */
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 0, 1,
+
+/* Char 3 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0, 0, 0,
+  1, 0, 0, 0, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0,
+  1, 0, 0, 0, 1, 0, 0, 0,
+  1, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 4 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 5 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 6 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 7 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 8 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 9 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 0, 0, 0,
+  1, 0, 1, 0, 1, 0, 0, 0,
+  1, 0, 0, 1, 1, 0, 0, 0,
+  1, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 10 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0, 0, 0,
+  1, 0, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 11 */
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 12 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 13 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 14 */
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 15 */
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 16 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 17 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 18 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 19 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 20 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 21 */
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 22 */
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 23 */
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 24 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 25 */
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 26 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 27 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 28 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  1, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 29 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 30 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  1, 0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 31 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 32 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 33 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 34 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 35 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 36 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 37 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 1, 0, 0,
+  0, 1, 1, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 1, 1, 0, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 38 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0, 1, 0,
+  1, 0, 0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 39 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 40 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 41 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 42 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 43 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 44 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 45 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 46 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 47 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 48 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 49 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 50 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 51 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 52 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 53 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 54 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 55 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 56 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 57 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 58 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 59 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 60 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 61 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 62 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 63 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 64 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 65 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 66 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 67 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 68 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 69 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 70 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 71 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 72 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 73 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 74 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 75 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 76 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 77 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 1, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 78 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0, 1, 0,
+  0, 1, 0, 0, 1, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 79 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 80 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 81 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 1, 0, 1, 0,
+  0, 1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 82 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 83 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 84 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 85 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 86 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 87 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 88 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 89 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 90 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 91 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 92 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 93 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 94 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 95 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 96 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 97 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 98 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 99 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 100 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 101 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 102 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 103 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+
+/* Char 104 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 105 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 106 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+
+/* Char 107 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 108 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 109 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 110 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 111 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 112 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+
+/* Char 113 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+
+/* Char 114 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 115 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 116 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 117 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 118 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 119 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 120 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 121 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+
+/* Char 122 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 123 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 124 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 125 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 126 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 127 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 128 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 129 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 130 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 131 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 132 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 133 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 134 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 135 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 136 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 137 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 138 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 139 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 140 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 141 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 142 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 143 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 144 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 145 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 146 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 147 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 148 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 149 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 150 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 151 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 152 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 153 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 154 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 155 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 156 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 157 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 158 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 159 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 160 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 161 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0,
+
+/* Char 162 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 163 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 164 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 165 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 166 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 167 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 168 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 169 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 170 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 171 */
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 172 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 173 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 174 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 175 */
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 176 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 177 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0,
+
+/* Char 178 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 1, 0,
+
+/* Char 179 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 180 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 181 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 182 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 183 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 184 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+
+/* Char 185 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 186 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 187 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 188 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 189 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 190 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 191 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 192 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 193 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 194 */
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 195 */
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 196 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 197 */
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 198 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 199 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+
+/* Char 200 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 201 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 202 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1, 0,
+
+/* Char 203 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 204 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 205 */
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 206 */
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 207 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 208 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 209 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0, 1, 0,
+  0, 1, 0, 0, 1, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 210 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0, 1, 0,
+  0, 1, 0, 0, 1, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 211 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 212 */
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 213 */
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 214 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 215 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 216 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 217 */
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 218 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 219 */
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 220 */
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 221 */
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 222 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 223 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  1, 1, 0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 224 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 225 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 226 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 227 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 228 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 229 */
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 230 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 231 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+
+/* Char 232 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 233 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 234 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+
+/* Char 235 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 236 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 237 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 238 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 239 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 1, 1,
+  0, 0, 0, 0, 0, 0, 0, 1,
+  0, 0, 0, 0, 0, 1, 0, 1,
+  0, 0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 240 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 241 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 242 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 243 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 244 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 245 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 1,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 246 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 247 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 248 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 249 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 250 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 251 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 1,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 252 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+/* Char 253 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0, 0,
+
+/* Char 254 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0, 0, 0,
+
+/* Char 255 */
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+
+
+};
+
+ossimGdFont ossimGdFontLargeRep =
+{
+  256,
+  0,
+  8,
+  16,
+  ossimGdFontLargeData
+};
+
+ossimGdFontPtr ossimGdFontLarge = &ossimGdFontLargeRep;
+
+/* This file has not been truncated. */
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontmb.inc b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontmb.inc
new file mode 100644
index 0000000000..4ac44cecae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontmb.inc
@@ -0,0 +1,3870 @@
+
+/*
+   This is a header file for gd font, generated using
+   bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
+   from bdf font
+   -misc-fixed-bold-r-normal-sans-13-94-100-100-c-70-iso8859-2
+   at Thu Jan  8 13:54:57 1998.
+   No copyright info was found in the original bdf.
+ */
+
+
+#include "ossimGdFont.h"
+
+char ossimGdFontMediumBoldData[] =
+{
+/* Char 0 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 1 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 2 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 3 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 4 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 5 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 0,
+  0, 0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 6 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 7 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 8 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 9 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 10 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 11 */
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 12 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+
+/* Char 13 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1,
+  0, 0, 1, 1, 1, 1, 1,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+
+/* Char 14 */
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1,
+  0, 0, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 15 */
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+
+/* Char 16 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 17 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 18 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 19 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 20 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 21 */
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1,
+  0, 0, 1, 1, 1, 1, 1,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+
+/* Char 22 */
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+
+/* Char 23 */
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 24 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+
+/* Char 25 */
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+
+/* Char 26 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 27 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 28 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 29 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 30 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  1, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 31 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 32 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 33 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 34 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 35 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 36 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 0, 1, 1, 0, 1, 0,
+  1, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 1, 0,
+  1, 0, 1, 1, 0, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 37 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 1, 0, 1, 0,
+  1, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 38 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 0, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 39 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 40 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 41 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 42 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 43 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 44 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 45 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 46 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 47 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 48 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 49 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 50 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 51 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 52 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 53 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 54 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 55 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 56 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 57 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 58 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 59 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 60 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 61 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 62 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 63 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 64 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 1, 0,
+  1, 0, 1, 1, 1, 1, 0,
+  1, 0, 1, 0, 1, 1, 0,
+  1, 0, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 65 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 66 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 67 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 68 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 69 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 70 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 71 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 72 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 73 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 74 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 75 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 76 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 77 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 78 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 79 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 80 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 81 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 82 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 83 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 84 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 85 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 86 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 87 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 88 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 89 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 90 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 91 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 92 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 93 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 94 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 95 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 96 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 97 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 98 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 99 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 100 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 101 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 102 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 103 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+
+/* Char 104 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 105 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 106 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+
+/* Char 107 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 108 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 109 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 110 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 111 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 112 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+
+/* Char 113 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+
+/* Char 114 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 115 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 116 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 117 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 118 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 119 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 120 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 121 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+
+/* Char 122 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 123 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 124 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 125 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 126 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 127 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 128 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 129 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 130 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 131 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 132 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 133 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 134 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 135 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 136 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 137 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 138 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 139 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 140 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 141 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 142 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 143 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 144 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 145 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 146 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 147 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 148 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 149 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 150 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 151 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 152 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 153 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 154 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 155 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 156 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 157 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 158 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 159 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 160 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 161 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+
+/* Char 162 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 163 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 164 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 165 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 166 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 167 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 168 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 169 */
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 170 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+
+/* Char 171 */
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 172 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 173 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 174 */
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 175 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 176 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 177 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+
+/* Char 178 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+
+/* Char 179 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 1, 0,
+  0, 0, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 180 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 181 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 182 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 183 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 184 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+
+/* Char 185 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 186 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+
+/* Char 187 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 188 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 189 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 190 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 191 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 192 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 193 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 194 */
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 195 */
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 196 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 197 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 198 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 199 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+
+/* Char 200 */
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 201 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 202 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+
+/* Char 203 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 204 */
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 205 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 206 */
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 207 */
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 208 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 209 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 210 */
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 211 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 212 */
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 213 */
+  0, 1, 1, 0, 0, 1, 1,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 214 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 215 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 216 */
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 217 */
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 218 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 219 */
+  0, 1, 1, 0, 0, 1, 1,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 220 */
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 221 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 222 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+
+/* Char 223 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 0, 1, 1, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 224 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 225 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 226 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 227 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 228 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 229 */
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 230 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 231 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+
+/* Char 232 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 233 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 234 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0, 0,
+
+/* Char 235 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 236 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 237 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 238 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 239 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 1, 1,
+  0, 0, 0, 1, 1, 0, 1,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 0, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  1, 1, 0, 1, 1, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 240 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 1, 1, 1,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 241 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 242 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 243 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 244 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 245 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 246 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 247 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 248 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 249 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 250 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 251 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 1, 1,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 252 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+/* Char 253 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  1, 1, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 1, 0,
+  0, 1, 1, 1, 1, 0, 0,
+
+/* Char 254 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 1, 0,
+  0, 0, 1, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0, 0,
+
+/* Char 255 */
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0,
+
+
+};
+
+ossimGdFont ossimGdFontMediumBoldRep =
+{
+  256,
+  0,
+  7,
+  13,
+  ossimGdFontMediumBoldData
+};
+
+ossimGdFontPtr ossimGdFontMediumBold = &ossimGdFontMediumBoldRep;
+
+/* This file has not been truncated. */
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/gdfonts.inc b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfonts.inc
new file mode 100644
index 0000000000..d2d3c0a74b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfonts.inc
@@ -0,0 +1,3871 @@
+
+
+/*
+   This is a header file for gd font, generated using
+   bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
+   from bdf font
+   -misc-fixed-medium-r-semicondensed-sans-12-116-75-75-c-60-iso8859-2
+   at Thu Jan  8 14:13:20 1998.
+   No copyright info was found in the original bdf.
+ */
+
+
+#include "ossimGdFont.h"
+
+char ossimGdFontSmallData[] =
+{
+/* Char 0 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 1 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 2 */
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1, 0,
+
+/* Char 3 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 4 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 5 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 6 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 7 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 8 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 9 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 10 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 11 */
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 12 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+
+/* Char 13 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+
+/* Char 14 */
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 15 */
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+
+/* Char 16 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 17 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 18 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 19 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 20 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 21 */
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 1, 1,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+
+/* Char 22 */
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+
+/* Char 23 */
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 24 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 1,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+
+/* Char 25 */
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+
+/* Char 26 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 27 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 28 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 29 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 30 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 31 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 32 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 33 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 34 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 35 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 36 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 1, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 1, 0,
+  0, 0, 1, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 37 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 38 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 39 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 40 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 41 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 42 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 0, 1, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 43 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 44 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 45 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 46 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 47 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 48 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 49 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 50 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 51 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 52 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 53 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 54 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 55 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 56 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 57 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  1, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 58 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 59 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 60 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 61 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 62 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 63 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 64 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 65 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 66 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 67 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 68 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 69 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 70 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 71 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 72 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 73 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 74 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 75 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 1, 1, 0, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 76 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 77 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 0, 1, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 78 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 79 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 80 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 81 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 82 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 83 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 84 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 85 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 86 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 87 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 88 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 89 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 90 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 91 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 92 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 93 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 94 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 95 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 96 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 97 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 98 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 99 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 100 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 101 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 102 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 103 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+
+/* Char 104 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 105 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 106 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 0,
+
+/* Char 107 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 108 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 109 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 0, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 110 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 111 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 112 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+
+/* Char 113 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+
+/* Char 114 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 115 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 116 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 117 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 118 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 119 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 120 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 121 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  1, 1, 1, 0, 0, 0,
+
+/* Char 122 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 123 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 124 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 125 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 126 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 127 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 128 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 129 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 130 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 131 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 132 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 133 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 134 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 135 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 136 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 137 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 138 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 139 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 140 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 141 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 142 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 143 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 144 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 145 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 146 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 147 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 148 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 149 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 150 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 151 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 152 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 153 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 154 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 155 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 156 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 157 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 158 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 159 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 160 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 161 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 1,
+
+/* Char 162 */
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 163 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 164 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 165 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 166 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 167 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 168 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 169 */
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 170 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+
+/* Char 171 */
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 172 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 173 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 174 */
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 175 */
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 176 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 177 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 1, 1,
+
+/* Char 178 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+
+/* Char 179 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 180 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 181 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1,
+  0, 1, 1, 0, 0, 1,
+  0, 0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 182 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 183 */
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 184 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 0,
+
+/* Char 185 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 186 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+
+/* Char 187 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 188 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 189 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 1,
+  0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 190 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 191 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 192 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 193 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 194 */
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 195 */
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 196 */
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 197 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 198 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 199 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 0,
+
+/* Char 200 */
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 201 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 202 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+
+/* Char 203 */
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 204 */
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 205 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 206 */
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 207 */
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 208 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0,
+  1, 1, 1, 0, 1, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 209 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 210 */
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 1, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 211 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 212 */
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 213 */
+  0, 0, 1, 0, 0, 1,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 214 */
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 215 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 216 */
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 1, 0, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 217 */
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 218 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 219 */
+  0, 0, 1, 0, 0, 1,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 220 */
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 221 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 222 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+
+/* Char 223 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 224 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 225 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 226 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 227 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 228 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 229 */
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 230 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 231 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0, 0,
+
+/* Char 232 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 233 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 234 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+
+/* Char 235 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 236 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 237 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 238 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 239 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 1,
+  0, 0, 0, 0, 0, 1,
+  0, 0, 0, 1, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 240 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 1, 1,
+  0, 0, 0, 0, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 241 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 242 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 243 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 244 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 245 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 246 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 247 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 248 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 1, 1, 0, 0,
+  1, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 249 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 250 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 251 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 252 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+/* Char 253 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 0, 1, 0,
+  1, 0, 0, 1, 1, 0,
+  0, 1, 1, 0, 1, 0,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  1, 1, 1, 0, 0, 0,
+
+/* Char 254 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+
+/* Char 255 */
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0,
+
+
+};
+
+ossimGdFont ossimGdFontSmallRep =
+{
+  256,
+  0,
+  6,
+  13,
+  ossimGdFontSmallData
+};
+
+ossimGdFontPtr ossimGdFontSmall = &ossimGdFontSmallRep;
+
+/* This file has not been truncated. */
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontt.inc b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontt.inc
new file mode 100644
index 0000000000..6db0045fb5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/gdfontt.inc
@@ -0,0 +1,2589 @@
+
+/*
+   This is a header file for gd font, generated using
+   bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
+   from bdf font
+   -Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-2
+   at Thu Jan  8 13:49:54 1998.
+   The original bdf was holding following copyright:
+   "Libor Skarvada, libor@informatics.muni.cz"
+ */
+#include "ossimGdFont.h"
+
+char ossimGdFontTinyData[] =
+{
+/* Char 0 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 1 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 1, 1, 1, 1,
+  0, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 2 */
+  0, 1, 0, 1, 0,
+  1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  1, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  1, 0, 1, 0, 0,
+
+/* Char 3 */
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 1, 1,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+
+/* Char 4 */
+  1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 0, 0, 0,
+  1, 0, 1, 1, 1,
+  1, 0, 1, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 5 */
+  0, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 1, 0, 1,
+  0, 0, 1, 1, 0,
+  0, 0, 1, 0, 1,
+
+/* Char 6 */
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 7 */
+  0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 8 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 9 */
+  1, 0, 0, 1, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1,
+
+/* Char 10 */
+  1, 0, 1, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 1, 1,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+
+/* Char 11 */
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 12 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 13 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 14 */
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 15 */
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 16 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 17 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 18 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 19 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 20 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 21 */
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 22 */
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 23 */
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 24 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 25 */
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 26 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 27 */
+  0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 28 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 29 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 30 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 1, 0, 0, 1,
+  1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 1,
+  1, 0, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 31 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 32 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 33 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 34 */
+  0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 35 */
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  1, 1, 1, 1, 1,
+  0, 1, 0, 1, 0,
+  1, 1, 1, 1, 1,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 36 */
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 1, 0, 1,
+  0, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 37 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 0, 0, 1,
+  1, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 1,
+  1, 0, 0, 1, 1,
+  0, 0, 0, 0, 0,
+
+/* Char 38 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 1,
+  0, 0, 0, 0, 0,
+
+/* Char 39 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 40 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 41 */
+  0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 42 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 43 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 44 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 45 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 46 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 47 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 1,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 48 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 49 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 50 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 51 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 52 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 53 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 54 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 55 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 56 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 57 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 58 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 59 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+
+/* Char 60 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 61 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 62 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 63 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 64 */
+  0, 0, 1, 1, 0,
+  0, 1, 0, 0, 1,
+  1, 0, 0, 1, 1,
+  1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1,
+  1, 0, 0, 1, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 1, 0,
+
+/* Char 65 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 66 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 67 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 68 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 69 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 70 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 71 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 72 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 73 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 74 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 75 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 0, 0,
+  1, 1, 0, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 76 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 77 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 78 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 1, 1, 0,
+  1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 79 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 80 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 81 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0,
+
+/* Char 82 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 83 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 84 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 85 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 86 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 87 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 88 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 89 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1,
+  1, 0, 0, 0, 1,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 90 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 91 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 92 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 0, 1,
+  0, 0, 0, 0, 0,
+
+/* Char 93 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 94 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 95 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+
+/* Char 96 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 97 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 98 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 99 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 100 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 101 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 1, 1, 0,
+  1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 102 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 103 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+
+/* Char 104 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 105 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 106 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+
+/* Char 107 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 108 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 109 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1,
+  1, 0, 0, 0, 1,
+  0, 0, 0, 0, 0,
+
+/* Char 110 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 111 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 112 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+
+/* Char 113 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0,
+
+/* Char 114 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 115 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 116 */
+  0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 117 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 118 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 119 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1,
+  1, 0, 1, 0, 1,
+  1, 0, 1, 0, 1,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 120 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 121 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+
+/* Char 122 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 123 */
+  0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 124 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 125 */
+  0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 126 */
+  0, 0, 0, 0, 0,
+  0, 1, 0, 1, 0,
+  1, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 127 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 128 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 129 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 130 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 131 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 132 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 133 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 134 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 135 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 136 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 137 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 138 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 139 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 140 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 141 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 142 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 143 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 144 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 145 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 146 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 147 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 148 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 149 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 150 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 151 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 152 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 153 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 154 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 155 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 156 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 157 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 158 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 159 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 160 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 161 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 0, 0, 1, 1,
+
+/* Char 162 */
+  1, 0, 0, 0, 1,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 163 */
+  0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 0, 0, 0,
+  0, 1, 1, 1, 1,
+  0, 0, 0, 0, 0,
+
+/* Char 164 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 0, 1,
+  0, 1, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 0, 1,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 165 */
+  0, 0, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 166 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 167 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 1, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+
+/* Char 168 */
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 169 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 170 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0,
+
+/* Char 171 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 172 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 173 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 174 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 175 */
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 176 */
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 177 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 1, 1,
+
+/* Char 178 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 1, 1,
+
+/* Char 179 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 180 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 181 */
+  0, 0, 0, 1, 1,
+  1, 1, 0, 0, 1,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 182 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 183 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 184 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+
+/* Char 185 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 186 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 1, 0, 0, 0,
+  0, 0, 1, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0,
+
+/* Char 187 */
+  0, 0, 0, 1, 1,
+  0, 1, 0, 0, 1,
+  0, 1, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 188 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 189 */
+  0, 1, 0, 0, 1,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 190 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 191 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 192 */
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 193 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 194 */
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 195 */
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 196 */
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 197 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 198 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 199 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  1, 1, 0, 0, 0,
+
+/* Char 200 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 201 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 202 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 1, 1,
+
+/* Char 203 */
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 204 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 205 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 206 */
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 207 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 208 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  1, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 1, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 209 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 210 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 0, 1, 0,
+  1, 1, 1, 1, 0,
+  1, 0, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 211 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 212 */
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 213 */
+  0, 1, 0, 0, 1,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 214 */
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 215 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 216 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 217 */
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 218 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 219 */
+  0, 1, 0, 0, 1,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 220 */
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 221 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  1, 0, 0, 0, 1,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 222 */
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 0, 0, 0,
+
+/* Char 223 */
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 1, 0, 0,
+  1, 0, 0, 0, 0,
+
+/* Char 224 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 225 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 226 */
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 227 */
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 228 */
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 229 */
+  0, 0, 0, 0, 1,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 230 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 231 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 1, 1, 0, 0,
+
+/* Char 232 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 233 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 1, 1, 0,
+  1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 234 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 1, 1, 0,
+  1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 1, 1,
+
+/* Char 235 */
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 1, 1, 0,
+  1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 236 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 1, 1, 0,
+  1, 1, 0, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 237 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 238 */
+  0, 0, 1, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 239 */
+  0, 0, 0, 1, 1,
+  0, 0, 1, 0, 1,
+  0, 0, 1, 0, 1,
+  0, 1, 1, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 0, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 240 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 1, 1,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 241 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 242 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 243 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 244 */
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 245 */
+  0, 1, 0, 0, 1,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 246 */
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 247 */
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 248 */
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 1, 0, 0,
+  1, 1, 0, 1, 0,
+  1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 249 */
+  0, 1, 1, 0, 0,
+  0, 1, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 250 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 251 */
+  0, 1, 0, 0, 1,
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 252 */
+  1, 0, 0, 1, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 1, 1, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 0, 0, 0,
+
+/* Char 253 */
+  0, 0, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  1, 0, 0, 1, 0,
+  1, 0, 0, 1, 0,
+  0, 1, 1, 1, 0,
+  0, 0, 0, 1, 0,
+  0, 1, 1, 0, 0,
+
+/* Char 254 */
+  0, 0, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0,
+  1, 1, 1, 0, 0,
+  0, 1, 0, 0, 0,
+  0, 1, 0, 1, 0,
+  0, 0, 1, 0, 0,
+  0, 1, 1, 0, 0,
+
+/* Char 255 */
+  0, 0, 0, 0, 0,
+  0, 0, 1, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
+
+
+};
+
+ossimGdFont ossimGdFontTinyRep =
+{
+  256,
+  0,
+  5,
+  8,
+  ossimGdFontTinyData
+};
+
+ossimGdFontPtr ossimGdFontTiny = &ossimGdFontTinyRep;
+
+/* This file has not been truncated. */
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationEllipseObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationEllipseObject.cpp
new file mode 100644
index 0000000000..9c276a689b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationEllipseObject.cpp
@@ -0,0 +1,180 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationEllipseObject.cpp,v 1.9 2005/12/07 19:08:55 dburken Exp $
+#include <imaging/annotation/ossimAnnotationEllipseObject.h>
+#include <imaging/ossimRgbImage.h>
+#include <base/common/ossimCommon.h>
+
+RTTI_DEF1(ossimAnnotationEllipseObject,
+          "ossimAnnotationEllipseObject",
+          ossimAnnotationObject)
+   
+ossimAnnotationEllipseObject::ossimAnnotationEllipseObject(
+   const ossimDpt& center,
+   const ossimDpt& widthHeight,
+   bool enableFill,
+   ossim_uint8 r,
+   ossim_uint8 g,
+   ossim_uint8 b,
+   ossim_uint8 thickness)
+   : ossimAnnotationObject(r, g, b, thickness),
+     theCenter(center),
+     theWidthHeight(widthHeight),
+     theFillEnabled(enableFill),
+     theBoundingRect(0,0,0,0)
+{
+   computeBoundingRect();
+}
+
+ossimAnnotationEllipseObject::ossimAnnotationEllipseObject(
+   const ossimAnnotationEllipseObject& rhs)
+   :
+   theCenter(rhs.theCenter),
+   theWidthHeight(rhs.theWidthHeight),
+   theFillEnabled(rhs.theFillEnabled),
+   theBoundingRect(rhs.theBoundingRect)
+{
+}
+
+ossimObject* ossimAnnotationEllipseObject::dup()const
+{
+   return new ossimAnnotationEllipseObject(*this);
+}
+
+ossimAnnotationEllipseObject::~ossimAnnotationEllipseObject()
+{
+}
+
+void ossimAnnotationEllipseObject::applyScale(double x, double y)
+{
+   theCenter.x      *= x;
+   theCenter.y      *= y;
+   theWidthHeight.x *= x;
+   theWidthHeight.y *= y;
+   theBoundingRect  *= ossimDpt(x,y);
+}
+
+
+
+void ossimAnnotationEllipseObject::draw(ossimRgbImage& anImage)const
+{
+   anImage.setDrawColor(theRed, theGreen, theBlue);
+   anImage.setThickness(theThickness);
+
+   if(theBoundingRect.intersects(anImage.getImageData()->getImageRectangle()))
+   {
+      if(theFillEnabled)
+      {
+//         anImage.drawFilledArc(irint(theCenter.x),
+//                               irint(theCenter.y),
+//                               irint(theWidthHeight.x),
+//                               irint(theWidthHeight.y),
+//                               0,
+//                               360);
+         anImage.drawFilledArc((int)(theCenter.x),
+                               (int)(theCenter.y),
+                               (int)(theWidthHeight.x),
+                               (int)(theWidthHeight.y),
+                               0,
+                               360);
+      }
+      else
+      {
+//         anImage.drawArc(irint(theCenter.x),
+//                         irint(theCenter.y),
+//                         irint(theWidthHeight.x),
+//                         irint(theWidthHeight.y),
+//                         0,
+//                         360);
+         anImage.drawArc((int)(theCenter.x),
+                         (int)(theCenter.y),
+                         (int)(theWidthHeight.x),
+                         (int)(theWidthHeight.y),
+                         0,
+                         360);
+      }
+   }
+}
+
+bool ossimAnnotationEllipseObject::intersects(const ossimDrect& rect)const
+{
+   return rect.intersects(theBoundingRect);
+}
+
+ossimAnnotationObject* ossimAnnotationEllipseObject::getNewClippedObject(
+   const ossimDrect& rect)const
+{
+   if(intersects(rect))
+   {
+      return (ossimAnnotationObject*)dup();
+   }
+   
+   return (ossimAnnotationEllipseObject*)NULL;
+}
+
+std::ostream& ossimAnnotationEllipseObject::print(std::ostream& out)const
+{
+   ossimAnnotationObject::print(out);
+   out << endl;
+   out << "ellipse_center:        " << theCenter << endl
+       << "ellipse_height:        " << theWidthHeight.y << endl
+       << "ellipse_width:         " << theWidthHeight.x << endl
+       << "fill_enabled:          " << theFillEnabled << endl
+       << "ellipse_bounding_rect: " << theBoundingRect;
+   return out;
+}
+
+void ossimAnnotationEllipseObject::getBoundingRect(ossimDrect& rect)const
+{
+   rect = theBoundingRect;
+}
+
+void ossimAnnotationEllipseObject::computeBoundingRect()
+{
+   theBoundingRect = ossimDrect(theCenter.x - theWidthHeight.x,
+                                theCenter.y - theWidthHeight.y,
+                                theCenter.x + theWidthHeight.x,
+                                theCenter.y + theWidthHeight.y);
+}
+
+bool ossimAnnotationEllipseObject::isPointWithin(const ossimDpt& point)const
+{
+  return theBoundingRect.pointWithin(point);
+}
+
+void ossimAnnotationEllipseObject::setCenterWidthHeight(const ossimDpt& center,
+                                                        const ossimDpt& widthHeight)
+{
+   theCenter          = center;
+   theWidthHeight     = widthHeight;
+
+   computeBoundingRect();
+}
+
+void ossimAnnotationEllipseObject::setFill(bool enabled)
+{
+   theFillEnabled = enabled;
+}
+
+bool ossimAnnotationEllipseObject::getFill() const
+{
+   return theFillEnabled;
+}
+
+bool ossimAnnotationEllipseObject::saveState(ossimKeywordlist& kwl,
+                                             const char* prefix)const
+{
+   return ossimAnnotationObject::saveState(kwl, prefix);
+}
+
+bool ossimAnnotationEllipseObject::loadState(const ossimKeywordlist& kwl,
+                                                const char* prefix)
+{
+   return ossimAnnotationObject::loadState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationEllipseObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationEllipseObject.h
new file mode 100644
index 0000000000..742418465e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationEllipseObject.h
@@ -0,0 +1,75 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationEllipseObject.h,v 1.12 2005/12/07 19:08:55 dburken Exp $
+#ifndef ossimAnnotationEllipseObject_HEADER
+#define ossimAnnotationEllipseObject_HEADER
+
+#include <imaging/annotation/ossimAnnotationObject.h>
+
+class OSSIMDLLEXPORT ossimAnnotationEllipseObject : public ossimAnnotationObject
+{
+public:
+   ossimAnnotationEllipseObject(const ossimDpt& center = ossimDpt(0,0),
+                                const ossimDpt& widthHeight = ossimDpt(1,1),
+                                bool enableFill = false,
+                                ossim_uint8 r = 255,
+                                ossim_uint8 g = 255,
+                                ossim_uint8 b = 255,
+                                ossim_uint8 thickness = 1);
+   ossimAnnotationEllipseObject(const ossimAnnotationEllipseObject& rhs);
+
+   virtual ossimObject* dup()const;
+
+   virtual ~ossimAnnotationEllipseObject();
+
+   virtual void applyScale(double x, double y);
+
+   virtual void draw(ossimRgbImage& anImage)const;
+
+   virtual bool intersects(const ossimDrect& rect)const;
+
+   virtual ossimAnnotationObject* getNewClippedObject(
+      const ossimDrect& rect)const;
+   
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void computeBoundingRect();
+  /*!
+   */
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   virtual void setCenterWidthHeight(const ossimDpt& center,
+                                     const ossimDpt& widthHeight);
+   virtual void setFill(bool enabled);
+
+   /** @return theFillEnabled flag. */
+   virtual bool getFill() const;
+
+   /**
+    * Saves the current state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+protected:
+   ossimDpt   theCenter;
+   ossimDpt   theWidthHeight;
+   bool       theFillEnabled;
+   ossimDrect theBoundingRect;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationFontObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationFontObject.cpp
new file mode 100644
index 0000000000..9fc70658dd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationFontObject.cpp
@@ -0,0 +1,397 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationFontObject.cpp,v 1.14 2005/12/09 21:53:22 dburken Exp $
+
+#include <imaging/annotation/ossimAnnotationFontObject.h>
+#include <fonts/factory/ossimFontFactoryRegistry.h>
+
+RTTI_DEF1(ossimAnnotationFontObject, "ossimAnnotationFontObject", ossimAnnotationObject);
+
+ossimAnnotationFontObject::ossimAnnotationFontObject()
+   :ossimAnnotationObject(),
+    theFont(ossimFontFactoryRegistry::instance()->getDefaultFont()),
+    theOwnsFontFlag(false),
+    theCenterPosition(0,0),
+    theString(""),
+    theRotation(0.0),
+    theHorizontalScale(0.0),
+    theVerticalScale(0.0),
+    theHorizontalShear(0.0),
+    theVerticalShear(0.0)
+{
+   setFontInfo();
+   theBoundingRect.makeNan();
+}
+
+ossimAnnotationFontObject::ossimAnnotationFontObject(const ossimIpt& upperLeft,
+                                                     const ossimString& s,
+                                                     const ossimIpt& pixelSize,
+                                                     double rotation,
+                                                     const ossimDpt& scale,
+                                                     const ossimDpt& shear,
+                                                     unsigned char r,
+                                                     unsigned char g,
+                                                     unsigned char b)
+   :ossimAnnotationObject(r,g,b),
+    theFont(ossimFontFactoryRegistry::instance()->getDefaultFont()),
+    theOwnsFontFlag(false),
+    theString(s),
+    thePixelSize(pixelSize),
+    theRotation(rotation),
+    theHorizontalScale(scale.x),
+    theVerticalScale(scale.y),
+    theHorizontalShear(shear.x),
+    theVerticalShear(shear.y)
+{
+   setFontInfo();
+   if (theFont)
+   {
+      theFont->getBoundingBox(theBoundingRect);
+   }
+   theBoundingRect += upperLeft;
+   theCenterPosition = theBoundingRect.midPoint();
+}
+
+ossimAnnotationFontObject::ossimAnnotationFontObject(const ossimAnnotationFontObject& rhs)
+   :ossimAnnotationObject(rhs),
+    theCenterPosition(rhs.theCenterPosition),
+    theString(rhs.theString),
+    thePixelSize(rhs.thePixelSize),
+    theRotation(rhs.theRotation),
+    theHorizontalScale(rhs.theHorizontalScale),
+    theVerticalScale(rhs.theVerticalScale),
+    theHorizontalShear(rhs.theHorizontalShear),
+    theVerticalShear(rhs.theVerticalShear),
+    theBoundingRect(rhs.theBoundingRect)
+{
+   if(rhs.theOwnsFontFlag&&theFont)
+   {
+      theFont = (ossimFont*)rhs.theFont->dup();
+   }
+   else
+   {
+      theFont = rhs.theFont;
+   }
+   
+   setFontInfo();
+}
+
+
+ossimAnnotationFontObject::~ossimAnnotationFontObject()
+{
+   if(theFont&&theOwnsFontFlag)
+   {
+      delete theFont;
+      theFont = NULL;
+      theOwnsFontFlag = false;
+   }
+   else
+   {
+      theFont = NULL;
+      theOwnsFontFlag = false;
+   }
+}
+
+void ossimAnnotationFontObject::draw(ossimRgbImage& anImage)const
+{
+   if(theBoundingRect.hasNans())
+   {
+      return;
+   }
+   if (!theFont)
+   {
+      return;
+   }
+   
+   if(!thePixelSize.x || !thePixelSize.y)
+   {
+      return; // (DAH) we have to have some demension to write!
+   }
+
+   ossimRefPtr<ossimImageData> destination = anImage.getImageData();
+   
+   if(destination.valid())
+   {
+      ossimIrect destRect = anImage.getImageData()->getImageRectangle();
+      
+      ossimIpt shift(-theBoundingRect.ul().x,
+                     -theBoundingRect.ul().y);
+
+      destRect += shift;
+      ossimIrect boundingRect = theBoundingRect + shift;
+      
+      if(boundingRect.intersects(destRect))
+      {
+         setFontInfo();
+ 
+         ossimIrect fontBufferRect;
+         ossimIrect boundingFontBox;
+         
+         theFont->setClippingBox(destRect);
+         theFont->getBoundingBox(boundingFontBox);
+
+         const ossim_uint8* srcBuf = theFont->rasterize();
+         if (!srcBuf)
+         {
+            return;
+         }
+         
+         theFont->getBufferRect(fontBufferRect);
+
+         ossimIrect clipRect = boundingRect.clipToRect(fontBufferRect);
+         
+         long clipHeight = clipRect.height();
+         long clipWidth  = clipRect.width();
+         
+         long destinationOffset   = (long)(((clipRect.ul().y - destRect.ul().y)* destRect.width()) +
+                                           (clipRect.ul().x - destRect.ul().x));
+         long fontBufferOffset    = (long)(((clipRect.ul().y - fontBufferRect.ul().y)*fontBufferRect.width()) +
+                                           (clipRect.ul().x - fontBufferRect.ul().x));
+
+         
+         long destinationIndex = destinationOffset;
+         long srcIndex         = fontBufferOffset;
+         long num_bands        = destination->getNumberOfBands();
+         ossim_int32 s_width = (ossim_int32)fontBufferRect.width();
+         ossim_int32 d_width = (ossim_int32)destRect.width();
+         
+         num_bands = num_bands > 3? 3:num_bands;
+         
+         unsigned char colorArray[3];
+         long band = 0;
+         colorArray[0] = theRed;
+         colorArray[1] = theGreen;
+         colorArray[2] = theBlue;
+         ossim_uint8** destBuf = new ossim_uint8*[num_bands];
+         for(band = 0; band < num_bands;++band)
+         {
+            destBuf[band] = static_cast<ossim_uint8*>(destination->getBuf(band));
+            if (!destBuf[band])
+            {
+               delete [] destBuf;
+               return;
+            }
+         }
+         
+         for(long line = 0; line < clipHeight; ++line)
+         {
+            for(long col = 0; col < clipWidth; ++col)
+            {
+               if(srcBuf[srcIndex + col])
+               {
+                  for (band=0; band<num_bands; ++band)
+                  {
+                     *(destBuf[band] + destinationIndex + col) = colorArray[band];
+                  }
+               }
+            }
+            srcIndex         += s_width;
+            destinationIndex += d_width;
+         }
+         delete [] destBuf;
+      }
+   }
+}
+
+std::ostream& ossimAnnotationFontObject::print(std::ostream& out)const
+{
+   if(theFont)
+   {
+      out << "Family:          " << theFont->getFamilyName() << endl
+          << "Style:           " << theFont->getStyleName()  << endl;
+   }
+   out << "String:             " << theString << endl
+       << "Center Position:    " << theCenterPosition << endl
+       << "Rotation:           " << theRotation << endl
+       << "Horizontal shear:   " << theHorizontalShear << endl
+       << "Vertical shear:     " << theVerticalShear << endl
+       << "Vertical scale:     " << theVerticalScale << endl
+       << "Horizontal scale:   " << theHorizontalScale << endl
+       << "Bounding rect:      " << theBoundingRect << endl;
+   return out;
+}
+
+void ossimAnnotationFontObject::getBoundingRect(ossimDrect& rect)const
+{
+   rect =  theBoundingRect;
+}
+
+void ossimAnnotationFontObject::computeBoundingRect()
+{
+   setFontInfo();
+   if(theFont)
+   {
+      ossimIrect textRect;
+      theFont->getBoundingBox(textRect);
+      ossim_int32 w = textRect.width();
+      ossim_int32 h = textRect.height();
+      ossim_int32 ulx = theCenterPosition.x - w/2;
+      ossim_int32 uly = theCenterPosition.y - h/2;
+      theBoundingRect = ossimIrect(ulx,
+                                   uly,
+                                   ulx + w - 1,
+                                   uly + h - 1);
+   }
+}
+
+bool ossimAnnotationFontObject::isPointWithin(const ossimDpt& imagePoint)const
+{
+   return theBoundingRect.pointWithin(imagePoint);
+}
+
+void ossimAnnotationFontObject::setFont(ossimFont* font,
+                                        bool ownsFontFlag)
+{
+   if(theOwnsFontFlag)
+   {
+      delete theFont;
+      theFont = (ossimFont*)NULL;
+   }
+   theFont = font;
+   theOwnsFontFlag = ownsFontFlag;
+
+   if(!theFont)
+   {
+      theFont = ossimFontFactoryRegistry::instance()->getDefaultFont();
+      theOwnsFontFlag = false;
+   }
+}
+
+void ossimAnnotationFontObject::setPositionCenter(const ossimIpt& position)
+{
+   theCenterPosition = position;
+   computeBoundingRect();
+}
+
+void ossimAnnotationFontObject::setFontInfo()const
+{
+   if(theFont)
+   {
+      theFont->setString(theString);
+      theFont->setRotation(theRotation);
+      theFont->setScale(theHorizontalScale, theVerticalScale);
+      theFont->setHorizontalVerticalShear(theHorizontalShear, theVerticalShear);
+      theFont->setPixelSize(thePixelSize.x,
+                            thePixelSize.y);
+   }
+}
+
+void ossimAnnotationFontObject::setString(const ossimString& s)
+{
+   theString = s;
+}
+
+ossimString ossimAnnotationFontObject::getString()const
+{
+   return theString;
+}
+
+ossimAnnotationObject* ossimAnnotationFontObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   if(intersects(rect))
+   {
+      return (ossimAnnotationObject*)dup();
+   }
+   
+   return (ossimAnnotationObject*)NULL;
+}
+
+bool ossimAnnotationFontObject::intersects(const ossimDrect& rect)const
+{
+   return rect.intersects(theBoundingRect);
+}
+
+void ossimAnnotationFontObject::setPointSize(const ossimIpt& size)
+{
+   thePixelSize = size;
+   setFontInfo();
+   if (theFont)
+   {
+      theFont->getBoundingBox(theBoundingRect);
+   }
+   theBoundingRect += (theCenterPosition - theBoundingRect.midPoint());
+   theCenterPosition = theBoundingRect.midPoint();
+}
+
+void ossimAnnotationFontObject::setRotation(double rotation)
+{
+   theRotation = rotation;
+   setFontInfo();
+   if (theFont)
+   {
+      theFont->getBoundingBox(theBoundingRect);
+   }
+   theBoundingRect += (theCenterPosition - theBoundingRect.midPoint());
+   theCenterPosition = theBoundingRect.midPoint();         
+}
+
+void ossimAnnotationFontObject::setScale(const ossimDpt& scale)
+{
+   theHorizontalScale = scale.x;
+   theVerticalScale   = scale.y;
+   setFontInfo();
+   if (theFont)
+   {
+      theFont->getBoundingBox(theBoundingRect);
+   }
+   theBoundingRect += (theCenterPosition - theBoundingRect.midPoint());
+   theCenterPosition = theBoundingRect.midPoint();         
+}
+
+void ossimAnnotationFontObject::setShear(const ossimDpt& shear)
+{
+   theHorizontalShear = shear.x;
+   theVerticalShear   = shear.y;
+   setFontInfo();
+   if (theFont)
+   {
+      theFont->getBoundingBox(theBoundingRect);
+   }
+   theBoundingRect += (theCenterPosition - theBoundingRect.midPoint());
+   theCenterPosition = theBoundingRect.midPoint();                  
+}
+
+void ossimAnnotationFontObject::setGeometryInformation(const ossimFontInformation& info)
+{
+   thePixelSize       = info.thePointSize;
+   theRotation        = info.theRotation;
+   theHorizontalScale = info.theScale.x;
+   theVerticalScale   = info.theScale.y;
+   theHorizontalShear = info.theShear.x;
+   theVerticalShear   = info.theShear.y;
+   
+   setFontInfo();
+   if (theFont)
+   {
+      theFont->getBoundingBox(theBoundingRect);
+   }
+   theBoundingRect += (theCenterPosition - theBoundingRect.midPoint());
+   theCenterPosition = theBoundingRect.midPoint();
+}
+
+void ossimAnnotationFontObject::applyScale(double x, double y)
+{
+   theCenterPosition.x = irint(theCenterPosition.x *x);
+   theCenterPosition.y = irint(theCenterPosition.x *y);
+   theHorizontalScale *= x;
+   theVerticalScale   *= y;
+   
+   setFontInfo();
+   if (theFont)
+   {
+      theFont->getBoundingBox(theBoundingRect);
+   }
+   theBoundingRect += (theCenterPosition - theBoundingRect.midPoint());
+   theCenterPosition = theBoundingRect.midPoint();
+}
+
+ossimObject* ossimAnnotationFontObject::dup()const
+{
+   return new ossimAnnotationFontObject(*this);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationFontObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationFontObject.h
new file mode 100644
index 0000000000..6394dab77c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationFontObject.h
@@ -0,0 +1,85 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationFontObject.h,v 1.13 2005/12/09 21:51:47 dburken Exp $
+#ifndef ossimAnnotationFontObject_HEADER
+#define ossimAnnotationFontObject_HEADER
+#include <imaging/annotation/ossimAnnotationObject.h>
+#include <base/common/ossimFontInformation.h>
+#include <base/data_types/ossimIpt.h>
+#include <fonts/ossimFont.h>
+
+/**
+ * Class to draw fonts onto an image.
+ * @note  This class requires a font path to be set for the factory:
+ * "ossimFontFactoryRegistry".  You should set at a minimum the keyword
+ * "font.dir1" in your ossim_prefernces file.
+ * Example from a RedHat 9.0 system:
+ * font.dir1: /usr/share/fonts/default/Type1
+ *
+ * @see file ossim/etc/templates/ossim_prefernces_template
+ */
+class OSSIMDLLEXPORT ossimAnnotationFontObject : public ossimAnnotationObject
+{
+
+public:
+  friend class ossimGeoAnnotationFontObject;
+   ossimAnnotationFontObject();
+   ossimAnnotationFontObject(const ossimIpt& upperLeft,
+                             const ossimString& s,
+                             const ossimIpt& pixelSize = ossimIpt(12, 12),
+                             double rotation = 0.0,
+                             const ossimDpt& scale = ossimDpt(1.0, 1.0),
+                             const ossimDpt& shear = ossimDpt(0.0,0.0),
+                             unsigned char r=255,
+                             unsigned char g=255,
+                             unsigned char b=255);
+   ossimAnnotationFontObject(const ossimAnnotationFontObject& rhs);
+                             
+   
+   virtual ~ossimAnnotationFontObject();
+
+   virtual ossimObject* dup()const;
+
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void setString(const ossimString& s);
+   virtual ossimString getString()const;
+   virtual void computeBoundingRect();
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   virtual void setFont(ossimFont* font,
+                        bool ownsFontFlag=true);
+   virtual void setPositionCenter(const ossimIpt& position);
+   virtual void setPointSize(const ossimIpt& size);
+   virtual void setRotation(double rotation);
+   virtual void setScale(const ossimDpt& scale);
+   virtual void setShear(const ossimDpt& shear);
+   virtual void setGeometryInformation(const ossimFontInformation& info);
+   virtual void applyScale(double x, double y);
+                           
+protected:
+   mutable ossimFont*   theFont;
+   bool                 theOwnsFontFlag;
+   ossimIpt             theCenterPosition;
+   ossimString          theString;
+   ossimIpt             thePixelSize;
+   double               theRotation;
+   double               theHorizontalScale;
+   double               theVerticalScale;
+   double               theHorizontalShear;
+   double               theVerticalShear;
+   ossimIrect           theBoundingRect;
+
+   void setFontInfo()const;
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationGdBitmapFont.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationGdBitmapFont.cpp
new file mode 100644
index 0000000000..6fe84b3dfe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationGdBitmapFont.cpp
@@ -0,0 +1,195 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimAnnotationGdBitmapFont.cpp,v 1.11 2004/05/23 17:49:36 dburken Exp $
+#include "ossimAnnotationGdBitmapFont.h"
+#include "imaging/ossimRgbImage.h"
+#include "base/common/ossimCommon.h"
+
+#include "gdfonts.inc"
+#include "gdfontl.inc"
+#include "gdfontg.inc"
+#include "gdfontmb.inc"
+#include "gdfontt.inc"
+
+ossimAnnotationGdBitmapFont::ossimAnnotationGdBitmapFont(const ossimDpt& position,
+                                                         const ossimString &text,
+                                                         ossimGdFontPtr font,
+                                                         unsigned char r,
+                                                         unsigned char g,
+                                                         unsigned char b,
+                                                         long thickness)
+   :ossimAnnotationObject(r, g, b, thickness),
+    theFontPtr(font),
+    theText(text),
+    thePosition(position)
+{
+   computeBoundingRect();
+}
+
+ossimAnnotationGdBitmapFont::ossimAnnotationGdBitmapFont(const ossimAnnotationGdBitmapFont& rhs)
+   : ossimAnnotationObject(rhs),
+     theFontPtr(rhs.theFontPtr),
+     theText(rhs.theText),
+     theBoundingRect(rhs.theBoundingRect),
+     thePosition(rhs.thePosition)
+{
+}
+
+ossimAnnotationGdBitmapFont::~ossimAnnotationGdBitmapFont()
+{
+}
+
+void ossimAnnotationGdBitmapFont::getBoundingRect(ossimDrect& rect)const
+{
+   rect = theBoundingRect;
+}
+
+void ossimAnnotationGdBitmapFont::applyScale(double x, double y)
+{
+   thePosition.x *= x;
+   thePosition.y *= y;
+
+   theBoundingRect *= ossimDpt(x, y);
+}
+
+void ossimAnnotationGdBitmapFont::draw(ossimRgbImage& anImage)const
+{
+   if(!theFontPtr||
+   !anImage.getImageData())
+   {
+      return;
+   }
+   ossimDpt origin = anImage.getImageData()->getOrigin();
+
+   ossimDrect rect = anImage.getImageData()->getImageRectangle();
+
+   if(theBoundingRect.intersects(rect))
+   {
+      anImage.setDrawColor(theRed, theGreen, theBlue);
+      ossimDpt position(thePosition.x - origin.x,
+                        thePosition.y - origin.y);
+      for(ossim_uint32 character = 0; character < theText.size(); ++character)
+      {
+         long charOffset = theText[(int)character];
+
+         // we need to shift the offset to a positive value.
+         // if it goes negative we just add 256 to the value.
+         if(charOffset < 0)
+         {
+            charOffset += 256;
+         }
+         // get the starting offset to the bitmap
+         long offset = charOffset*theFontPtr->w*theFontPtr->h;
+         for(long row = 0; row < theFontPtr->h; ++row)
+         {
+            for(long col = 0; col < theFontPtr->w; ++col)
+            {
+               if(theFontPtr->data[(int)offset])
+               {
+                  anImage.slowPlotPixel(irint(position.x + col),
+                                        irint(position.y + row),
+                                        theRed,
+                                        theGreen,
+                                        theBlue);
+               }
+               ++offset;
+            }
+         }
+         position.x += theFontPtr->w;
+      }
+   }
+}
+
+ossimAnnotationObject* ossimAnnotationGdBitmapFont::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimAnnotationGdBitmapFont* result = (ossimAnnotationGdBitmapFont*)NULL;
+
+   if(intersects(rect))
+   {
+      result = (ossimAnnotationGdBitmapFont*)dup();
+   }
+
+   return result;
+}
+
+std::ostream& ossimAnnotationGdBitmapFont::print(std::ostream& out)const
+{
+   out << "text_value:        " << theText << endl
+       << "text_bouding_rect: " << theBoundingRect << endl
+       << "text_position:     " << thePosition << endl;
+   return out;
+}
+
+void ossimAnnotationGdBitmapFont::computeBoundingRect()
+{
+   if(theFontPtr)
+   {
+      theBoundingRect = ossimDrect(thePosition.x,
+                                   thePosition.y,
+                                   thePosition.x + theText.size()*theFontPtr->w,
+                                   thePosition.y + theFontPtr->h);
+   }
+}
+
+void ossimAnnotationGdBitmapFont::setFont(ossimGdFontPtr font)
+{
+   theFontPtr = font;
+}
+
+void ossimAnnotationGdBitmapFont::setText(const ossimString& text)
+{
+   theText = text;
+   computeBoundingRect();
+}
+
+void ossimAnnotationGdBitmapFont::setUpperLeftText(const ossimDpt& upperLeft,
+                                                   const ossimString& text)
+{
+   setText(text);
+   setUpperLeftTextPosition(upperLeft);
+}
+
+void ossimAnnotationGdBitmapFont::setUpperLeftTextPosition(const ossimDpt& position)
+{
+   thePosition = position;
+   computeBoundingRect();
+}
+
+void ossimAnnotationGdBitmapFont::setCenterText(const ossimDpt& upperLeft,
+                                                   const ossimString& text)
+{
+   setText(text);
+   setCenterTextPosition(upperLeft);
+}
+
+void ossimAnnotationGdBitmapFont::setCenterTextPosition(const ossimDpt& position)
+{
+   thePosition.x = position.x - theBoundingRect.width()/2.0;
+   thePosition.y = position.y - theBoundingRect.height()/2.0;
+   computeBoundingRect();
+}
+
+bool ossimAnnotationGdBitmapFont::isPointWithin(const ossimDpt& imagePoint)const
+{
+   return theBoundingRect.pointWithin(imagePoint);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationGdBitmapFont.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationGdBitmapFont.h
new file mode 100644
index 0000000000..72a1ae3b3a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationGdBitmapFont.h
@@ -0,0 +1,137 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimAnnotationGdBitmapFont.h,v 1.10 2004/05/23 17:49:36 dburken Exp $
+#ifndef ossimAnnotationGdBitmapFont_HEADER
+#define ossimAnnotationGdBitmapFont_HEADER
+#include "ossimAnnotationObject.h"
+#include "ossimGdFont.h"
+#include "ossimGdFontExterns.h"
+#include "base/data_types/ossimString.h"
+
+/*!
+ * This is a class that will have hardcoded
+ * bitmap fonts.  These fonts will be from
+ * the gd library.
+ */
+class OSSIMDLLEXPORT ossimAnnotationGdBitmapFont : public ossimAnnotationObject
+{
+public:
+   ossimAnnotationGdBitmapFont(const ossimDpt& position=ossimDpt(0,0),
+                               const ossimString &text=ossimString(""),
+                               ossimGdFontPtr font = ossimGdFontLarge,
+                               unsigned char r = 255,
+                               unsigned char g = 255,
+                               unsigned char b = 255,
+                               long thickness = 1);
+   ossimAnnotationGdBitmapFont(const ossimAnnotationGdBitmapFont& rhs);
+   virtual ~ossimAnnotationGdBitmapFont();
+
+   virtual ossimObject* dup()const
+      {
+         return new ossimAnnotationGdBitmapFont(*this);
+      }
+   
+   virtual void applyScale(double x, double y);
+
+   /*!
+    * Will draw the bitmap to the screen.
+    */
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual bool intersects(const ossimDrect& rect)const
+      {
+         return rect.intersects(theBoundingRect);
+      }
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+
+   virtual std::ostream& print(std::ostream& out)const;
+   
+   /*!
+    * Will retrieve the bound rectangle for this
+    * object.
+    */
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   
+   /*!
+    * will compute the bounding rectangle.
+    */
+   virtual void computeBoundingRect();
+
+   /*!
+    * Sets the current bitmap font to use.
+    */
+   virtual void setFont(ossimGdFontPtr font);
+
+   /*!
+    * Set's the text string to render.
+    */
+   virtual void setText(const ossimString& text);
+
+   /*!
+    * Set's the text string to render.  This
+    * will assume that the x,y passed in is
+    * suppose to be the center.  We will compute
+    * the upper left corner from this
+    */
+   virtual void setCenterText(const ossimDpt& center,
+                              const ossimString& text);
+
+   /*!
+    * Set's the text string to render.  This
+    * will assume that the x,y passed in is
+    * suppose to be the upper left.  
+    */
+   virtual void setUpperLeftText(const ossimDpt& upperLeft,
+                                 const ossimString& text);
+
+   /*!
+    * Sets the center position of the string.
+    * will use this value to compute the actual
+    * origin of upper left corner of the first
+    * character.  Make sure you have the text
+    * set before you call this method
+    */
+   virtual void setCenterTextPosition(const ossimDpt& position);
+
+   /*!
+    * The actual upper left corner of the character.
+    */
+   virtual void setUpperLeftTextPosition(const ossimDpt& position);
+
+   /*!
+    * Will determine if the point is within the font
+    */
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   
+protected:
+   ossimGdFontPtr theFontPtr;
+   ossimString    theText;
+   ossimDrect     theBoundingRect;
+
+   /*!
+    * This position is suppose to be the upperleft
+    * corner of the first character in the string
+    */
+   ossimDpt       thePosition;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationLineObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationLineObject.cpp
new file mode 100644
index 0000000000..604e0f840d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationLineObject.cpp
@@ -0,0 +1,183 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationLineObject.cpp,v 1.10 2005/02/11 15:07:30 dburken Exp $
+
+#include <imaging/annotation/ossimAnnotationLineObject.h>
+#include <imaging/ossimRgbImage.h>
+
+RTTI_DEF1(ossimAnnotationLineObject,
+          "ossimAnnotationLineObject",
+          ossimAnnotationObject)
+
+ossimAnnotationLineObject::ossimAnnotationLineObject()
+   :ossimAnnotationObject(),
+    theStart(0,0),
+    theEnd(0,0),
+    theBoundingRect(0,0,0,0)
+{
+}
+
+ossimAnnotationLineObject::ossimAnnotationLineObject(const ossimIpt& start,
+                                                     const ossimIpt& end,
+                                                     unsigned char r,
+                                                     unsigned char g,
+                                                     unsigned char b,
+                                                     long thickness)
+   :ossimAnnotationObject(r, g, b, thickness),
+    theStart(start),
+    theEnd(end)
+{
+   computeBoundingRect();
+}
+
+ossimAnnotationLineObject::ossimAnnotationLineObject(long x1,
+                                                     long y1,
+                                                     long x2,
+                                                     long y2,
+                                                     unsigned char r,
+                                                     unsigned char g,
+                                                     unsigned char b,
+                                                     long thickness)
+   :ossimAnnotationObject(r, g, b, thickness),
+    theStart(x1, y1),
+    theEnd(x2, y2)
+{
+   computeBoundingRect();
+}
+
+ossimAnnotationLineObject::ossimAnnotationLineObject(const ossimAnnotationLineObject& rhs)
+      :ossimAnnotationObject(rhs),
+       theStart(rhs.theStart),
+       theEnd(rhs.theEnd),
+       theBoundingRect(rhs.theBoundingRect)
+{
+}
+
+ossimObject* ossimAnnotationLineObject::dup()const
+{
+   return new ossimAnnotationLineObject(*this);
+}
+
+void ossimAnnotationLineObject::applyScale(double x, double y)
+{
+   theStart.x = irint(theStart.x*x);
+   theStart.y = irint(theStart.y*y);
+   theEnd.x   = irint(theEnd.x*x);
+   theEnd.y   = irint(theEnd.y*y);
+}
+
+ossimAnnotationObject* ossimAnnotationLineObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimAnnotationLineObject* result = (ossimAnnotationLineObject*)NULL;
+   ossimDpt start = theStart;
+   ossimDpt end   = theEnd;
+   
+   if(rect.clip(start, end))
+   {
+      result = (ossimAnnotationLineObject*)dup();
+      result->setLine(start, end);
+   }
+   
+   return result;
+}
+
+bool ossimAnnotationLineObject::intersects(const ossimDrect& rect)const
+{
+   ossimDpt start = theStart;
+   ossimDpt end   = theEnd;
+   
+   return rect.clip(start, end);
+}
+
+void ossimAnnotationLineObject::draw(ossimRgbImage& anImage)const
+{
+   if(anImage.getImageData().valid())
+   {
+      anImage.setDrawColor(theRed, theGreen, theBlue);
+      anImage.setThickness(theThickness);
+      ossimDrect imageRect = anImage.getImageData()->getImageRectangle();
+      ossimDpt start = theStart;
+      ossimDpt end   = theEnd;
+      
+      if(anImage.getImageData().valid())
+      {
+         // we need to extend it by a couple of pixels since
+         // if a pixel lies on the edge and then another pixel is just off
+         // the edge we will get a stair step and so for several pixels
+         // the line might be inside the image rectangle but the clip
+         // algorithm will only draw 1 pixel since it thinks the first
+         // point is inside and the second point is outside and will
+         // execute the clip algorithm keeping only the first
+         // point.
+         ossimDrect clipRect(imageRect.ul().x - 10,
+                             imageRect.ul().y - 10,
+                             imageRect.lr().x + 10,
+                             imageRect.lr().y + 10);
+         // now we can draw.
+         if(clipRect.clip(start, end))
+         {
+            anImage.drawLine(ossimIpt((int)start.x,
+                                      (int)start.y),
+                             ossimIpt((int)end.x,
+                                      (int)end.y));
+         }
+      }
+   }
+}
+
+std::ostream& ossimAnnotationLineObject::print(std::ostream& out)const
+{
+   out << "line_start:    " << theStart << endl
+       << "line_end:      " << theEnd   << endl
+       << "bounding_rect: " << theBoundingRect << endl;
+   return out;
+}
+
+void ossimAnnotationLineObject::getBoundingRect(ossimDrect& rect)const
+{
+   rect = theBoundingRect;
+}
+
+void ossimAnnotationLineObject::computeBoundingRect()
+{
+   vector<ossimDpt> pts(2);
+      
+   pts[0] = theStart;
+   pts[1] = theEnd;
+
+   theBoundingRect = ossimDrect(pts);
+}
+
+void ossimAnnotationLineObject::setLine(const ossimDpt& start,
+                                        const ossimDpt& end)
+{
+   theStart = start;
+   theEnd   = end;
+   computeBoundingRect();
+}
+void ossimAnnotationLineObject::getLine(ossimDpt& start, ossimDpt& end)
+{
+   start = theStart;
+   end   = theEnd;
+}
+
+bool ossimAnnotationLineObject::isPointWithin(const ossimDpt& point)const
+{
+  if(theBoundingRect.pointWithin(point))
+  {
+    // we will use the implicit form of a line to determine if the point is
+    // on the line.  For now we will just return true if it is within the 
+    // bounding rect.
+    return true;
+  }
+
+  return false;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationLineObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationLineObject.h
new file mode 100644
index 0000000000..d483e90b35
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationLineObject.h
@@ -0,0 +1,76 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimAnnotationLineObject.h,v 1.12 2004/05/23 17:49:37 dburken Exp $
+#ifndef ossimAnnotationLineObject_HEADER
+#define ossimAnnotationLineObject_HEADER
+#include "ossimAnnotationObject.h"
+#include "base/data_types/ossimIpt.h"
+
+class OSSIMDLLEXPORT ossimAnnotationLineObject : public ossimAnnotationObject
+{
+public:
+   ossimAnnotationLineObject();
+   ossimAnnotationLineObject(const ossimIpt& start,
+                             const ossimIpt& end,
+                             unsigned char r=255,
+                             unsigned char g=255,
+                             unsigned char b=255,
+                             long thickness=1);
+   
+   ossimAnnotationLineObject(long x1,
+                             long y1,
+                             long x2,
+                             long y2,
+                             unsigned char r=255,
+                             unsigned char g=255,
+                             unsigned char b=255,
+                             long thickness=1);
+
+   ossimAnnotationLineObject(const ossimAnnotationLineObject& rhs);
+       
+   virtual ossimObject* dup()const;
+   
+   virtual void applyScale(double x, double y);
+
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   virtual void computeBoundingRect();
+
+   void setLine(const ossimDpt& start, const ossimDpt& end);
+   void getLine(ossimDpt& start, ossimDpt& end);
+
+protected:
+   ossimIpt theStart;
+   ossimIpt theEnd;
+   ossimDrect theBoundingRect;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMapGridSource.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMapGridSource.h
new file mode 100644
index 0000000000..75e273f322
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMapGridSource.h
@@ -0,0 +1,14 @@
+#ifndef ossimAnnotationMapGridSource_HEADER
+#define ossimAnnotationMapGridSource_HEADER
+#include "ossimAnnotationSource.h"
+
+class ossimAnnotationMapGridSource : public ossimAnnotationSource
+{
+public:
+   ossimAnnotationMapGridSource();
+   
+protected:
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiEllipseObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiEllipseObject.cpp
new file mode 100644
index 0000000000..c28f200576
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiEllipseObject.cpp
@@ -0,0 +1,237 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationMultiEllipseObject.cpp,v 1.5 2004/05/23 17:49:37 dburken Exp $
+
+#include <imaging/annotation/ossimAnnotationMultiEllipseObject.h>
+
+ossimAnnotationMultiEllipseObject::ossimAnnotationMultiEllipseObject
+   (const std::vector<ossimDpt>& pointList,
+    const ossimDpt& widthHeight,
+    bool enableFill,
+    unsigned char r,
+    unsigned char g,
+    unsigned char b,
+    long thickness)
+   :
+         ossimAnnotationObject(r, g, b, thickness),
+         thePointList(pointList),
+         theWidthHeight(widthHeight),
+         theFillFlag(enableFill)
+{
+   computeBoundingRect();
+}
+
+ossimAnnotationMultiEllipseObject::ossimAnnotationMultiEllipseObject
+   (const ossimDpt& widthHeight,
+    bool enableFill,
+    unsigned char r,
+    unsigned char g,
+    unsigned char b,
+    long thickness)
+   :
+         ossimAnnotationObject(r, g, b, thickness),
+         theWidthHeight(widthHeight),
+         theFillFlag(enableFill)
+{
+   theBoundingRect.makeNan();
+}
+
+ossimAnnotationMultiEllipseObject::ossimAnnotationMultiEllipseObject(const ossimAnnotationMultiEllipseObject& rhs)
+      :thePointList(rhs.thePointList),
+       theWidthHeight(rhs.theWidthHeight),
+       theFillFlag(rhs.theFillFlag),
+       theBoundingRect(rhs.theBoundingRect)
+{
+}
+
+ossimObject* ossimAnnotationMultiEllipseObject::dup()const
+{
+   return new ossimAnnotationMultiEllipseObject(*this);
+}
+
+ossimAnnotationMultiEllipseObject::~ossimAnnotationMultiEllipseObject()
+{}
+
+ossimAnnotationObject* ossimAnnotationMultiEllipseObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimNotify(ossimNotifyLevel_WARN)
+      << "ossimAnnotationMultiEllipseObject::getNewClippedObject WARNING: Not implemented"
+      << std::endl;
+   return NULL;
+}
+
+void ossimAnnotationMultiEllipseObject::applyScale(double x, double y)
+{
+   int i;
+   int upper = (int)thePointList.size();
+   for(i = 0; i < upper; ++i)
+   {
+      thePointList[i].x *= x;
+      thePointList[i].y *= y;
+   }
+   theWidthHeight.x *= x;
+   theWidthHeight.y *= y;
+   
+   computeBoundingRect();
+}
+
+void ossimAnnotationMultiEllipseObject::draw(ossimRgbImage& anImage)const
+{
+   anImage.setDrawColor(theRed, theGreen, theBlue);
+   anImage.setThickness(theThickness);
+   ossimDrect imageRect = anImage.getImageData()->getImageRectangle();
+
+   if(theBoundingRect.intersects(imageRect))
+   {
+      int i;
+      int upper = (int)thePointList.size();
+      if(theFillFlag)
+      {
+         for(i = 0; i < upper; ++i)
+         {
+            ossimDpt tempPoint = thePointList[i];
+            
+            ossimDrect tempRect(ossimDpt(tempPoint.x - theWidthHeight.x,
+                                         tempPoint.y - theWidthHeight.y),
+                                ossimDpt(tempPoint.x + theWidthHeight.x,
+                                         tempPoint.y + theWidthHeight.y));
+            if(tempRect.intersects(imageRect))
+            {
+               anImage.drawFilledArc(irint(tempPoint.x),
+                                     irint(tempPoint.y),
+                                     irint(theWidthHeight.x),
+                                     irint(theWidthHeight.y),
+                                     0,
+                                     360);
+            }
+         }
+      }
+      else
+      {
+         for(i = 0; i < upper; ++i)
+         {
+            ossimDpt tempPoint = thePointList[i];
+            
+            ossimDrect tempRect(ossimDpt(tempPoint.x - theWidthHeight.x,
+                                         tempPoint.y - theWidthHeight.y),
+                                ossimDpt(tempPoint.x + theWidthHeight.x,
+                                         tempPoint.y + theWidthHeight.y));
+            if(tempRect.intersects(imageRect))
+            {
+               anImage.drawArc(irint(tempPoint.x),
+                               irint(tempPoint.y),
+                               irint(theWidthHeight.x),
+                               irint(theWidthHeight.y),
+                               0,
+                               360);
+            }
+         }
+      }
+   }
+}
+
+bool ossimAnnotationMultiEllipseObject::intersects(const ossimDrect& rect)const
+{
+   return rect.intersects(theBoundingRect);
+}
+
+std::ostream& ossimAnnotationMultiEllipseObject::print(std::ostream& out)const
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimAnnotionMultiEllipseObject::print NOT IMPLEMENTED"
+      << endl;
+   return out;
+}
+
+void ossimAnnotationMultiEllipseObject::getBoundingRect(ossimDrect& rect)const
+{
+   rect =  theBoundingRect;
+}
+
+void ossimAnnotationMultiEllipseObject::computeBoundingRect()
+{
+   theBoundingRect.makeNan();
+
+   int i;
+   int upper = (int)thePointList.size();
+   for(i = 0; i < upper; ++i)
+   {
+      ossimDpt tempPoint = thePointList[i];
+      if(!tempPoint.hasNans())
+      {
+         ossimDrect tempRect(ossimDpt(tempPoint.x - theWidthHeight.x,
+                                      tempPoint.y - theWidthHeight.y),
+                             ossimDpt(tempPoint.x + theWidthHeight.x,
+                                      tempPoint.y + theWidthHeight.y));
+         if(!theBoundingRect.hasNans())
+         {
+            theBoundingRect.combine(tempRect);
+         }
+         else
+         {
+            theBoundingRect = tempRect;
+         }
+      }
+   }
+}
+
+bool ossimAnnotationMultiEllipseObject::isPointWithin(const ossimDpt& imagePoint)const
+{
+   if(!theBoundingRect.hasNans())
+   {
+      return theBoundingRect.pointWithin(imagePoint);
+   }
+   return false;
+}
+
+void ossimAnnotationMultiEllipseObject::setFillFlag(bool flag)
+{
+   theFillFlag = flag;
+}
+
+void ossimAnnotationMultiEllipseObject::resize(ossim_uint32 size)
+{
+   if(size)
+   {
+      thePointList.resize(size);
+   }
+   else
+   {
+      thePointList.clear();
+   }
+}
+
+void ossimAnnotationMultiEllipseObject::setWidthHeight(const ossimDpt& widthHeight)
+{
+   theWidthHeight = widthHeight;
+   computeBoundingRect();
+}
+
+ossimDpt& ossimAnnotationMultiEllipseObject::operator[](int i)
+{
+   return thePointList[i];
+}
+
+const ossimDpt& ossimAnnotationMultiEllipseObject::operator[](int i)const
+{
+   return thePointList[i];
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiEllipseObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiEllipseObject.h
new file mode 100644
index 0000000000..e8bc5dfabd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiEllipseObject.h
@@ -0,0 +1,80 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimAnnotationMultiEllipseObject.h,v 1.6 2004/05/23 17:49:37 dburken Exp $
+#ifndef ossimAnnotationMultiEllipseObject_HEADER
+#define ossimAnnotationMultiEllipseObject_HEADER
+#include <imaging/annotation/ossimAnnotationObject.h>
+#include <vector>
+
+class OSSIMDLLEXPORT ossimAnnotationMultiEllipseObject : public ossimAnnotationObject
+{
+public:
+   ossimAnnotationMultiEllipseObject(const std::vector<ossimDpt>& pointList,
+                                     const ossimDpt& widthHeight = ossimDpt(1,1),
+                                     bool enableFill = false,
+                                     unsigned char r = 255,
+                                     unsigned char g = 255,
+                                     unsigned char b = 255,
+                                     long thickness = 1);
+
+   ossimAnnotationMultiEllipseObject(const ossimDpt& widthHeight = ossimDpt(1,1),
+                                     bool enableFill = false,
+                                     unsigned char r = 255,
+                                     unsigned char g = 255,
+                                     unsigned char b = 255,
+                                     long thickness = 1);
+
+   ossimAnnotationMultiEllipseObject(const ossimAnnotationMultiEllipseObject& rhs);
+
+   ossimObject* dup()const;
+
+   virtual ~ossimAnnotationMultiEllipseObject();
+
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual void applyScale(double x, double y);
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void computeBoundingRect();
+  /*!
+   */
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   
+   void setFillFlag(bool flag);
+
+   void resize(ossim_uint32 size);
+
+   virtual void setWidthHeight(const ossimDpt& widthHeight);
+
+   ossimDpt& operator[](int i);
+   
+   const ossimDpt& operator[](int i)const;
+   
+protected:
+   std::vector<ossimDpt>  thePointList;
+   ossimDpt               theWidthHeight;
+   bool                   theFillFlag;
+   ossimDrect             theBoundingRect;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiLineObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiLineObject.cpp
new file mode 100644
index 0000000000..9d25120b93
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiLineObject.cpp
@@ -0,0 +1,191 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationMultiLineObject.cpp,v 1.8 2005/02/11 15:07:30 dburken Exp $
+#include <imaging/annotation/ossimAnnotationMultiLineObject.h>
+
+RTTI_DEF1(ossimAnnotationMultiLineObject,
+          "ossimAnnotationMultiLineObject",
+          ossimAnnotationObject);
+
+void ossimAnnotationMultiLineObject::draw(ossimRgbImage& anImage)const
+{
+   if(anImage.getImageData().valid())
+   {
+      anImage.setDrawColor(theRed, theGreen, theBlue);
+      anImage.setThickness(theThickness);
+      ossimDrect imageRect = anImage.getImageData()->getImageRectangle();
+
+      
+      
+      if(theBoundingRect.intersects(imageRect))
+      {
+         // we need to extend it by a couple of pixels since
+         // if a pixel lies on the edge and then another pixel is just off
+         // the edge we will get a stair step and so for several pixels
+         // the line might be inside the image rectangle but the clip
+         // algorithm will only draw 1 pixel since it thinks the first
+         // point is inside and the second point is outside and will
+         // execute the clip algorithm keeping only the first
+         // point.
+         ossimDrect clipRect(imageRect.ul().x - 10,
+                             imageRect.ul().y - 10,
+                             imageRect.lr().x + 10,
+                             imageRect.lr().y + 10);
+         
+         for(ossim_uint32 i = 0; i < thePolyLineList.size(); ++i)
+         {
+            const vector<ossimDpt>& vList = thePolyLineList[i].getVertexList();
+            
+            if(vList.size() == 1)
+            {
+               anImage.drawLine(ossimIpt(vList[0]),
+                                ossimIpt(vList[0]));
+            }
+            else
+            {
+               for(ossim_uint32 i2 = 0; i2 < (vList.size()-1); ++i2)
+               {
+                  ossimDpt start = vList[i2];
+                  ossimDpt end   = vList[i2+1];
+                  // now we can draw.
+                  if(clipRect.clip(start, end))
+                  {
+                     anImage.drawLine(ossimIpt((int)start.x,
+                                               (int)start.y),
+                                      ossimIpt((int)end.x,
+                                               (int)end.y));
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+
+bool ossimAnnotationMultiLineObject::intersects(const ossimDrect& rect)const
+{
+
+   for(ossim_uint32 i = 0; i < thePolyLineList.size(); ++i)
+   {
+      if(thePolyLineList[i].isWithin(rect))
+      {
+         return true;
+      }
+   }
+   return false;
+}
+
+
+void ossimAnnotationMultiLineObject::applyScale(double x,
+                                                double y)
+{
+   for(ossim_uint32 i=0; i < thePolyLineList.size(); ++i)
+   {
+      vector<ossimDpt>& vList = thePolyLineList[i].getVertexList();
+      
+      for(ossim_uint32 i2 = 0; i2 < vList.size(); ++i2)
+      {
+         vList[i].x *= x;
+         vList[i].y *= y;
+         vList[i].x *= x;
+         vList[i].y *= y;
+      }
+   }
+   theBoundingRect *= ossimDpt(x, y);
+}
+
+ossimAnnotationObject* ossimAnnotationMultiLineObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimAnnotationMultiLineObject* result = (ossimAnnotationMultiLineObject*)NULL;
+
+   if(intersects(rect))
+   {
+      vector<ossimPolyLine> lineList;
+      vector<ossimPolyLine> tempResult;
+      
+      ossimDrect clipRect(rect.ul().x - 10,
+                          rect.ul().y - 10,
+                          rect.lr().x + 10,
+                          rect.lr().y + 10);
+
+      for(ossim_uint32 i =0; i< thePolyLineList.size();++i)
+      {
+         if(thePolyLineList[i].clipToRect(tempResult, clipRect))
+         {
+            lineList.insert(lineList.end(),
+                            tempResult.begin(),
+                            tempResult.end());
+         }
+      }
+      
+      if(lineList.size() > 0)
+      {
+         result = new ossimAnnotationMultiLineObject(lineList,
+                                                     theRed,
+                                                     theGreen,
+                                                     theBlue,
+                                                     theThickness);
+      }
+   }
+   
+   return result;
+}
+
+bool ossimAnnotationMultiLineObject::isPointWithin(const ossimDpt& imagePoint)const
+{
+   for(ossim_uint32 i=0; i < thePolyLineList.size(); ++i)
+   {
+      if(thePolyLineList[i].isPointWithin(imagePoint))
+      {
+         return true;
+      }
+      
+   }
+
+   return false;
+}
+
+void ossimAnnotationMultiLineObject::computeBoundingRect()
+{
+   theBoundingRect.makeNan();
+   
+   if(thePolyLineList.size() == 1)
+   {
+      theBoundingRect = thePolyLineList[0].getBoundingRect();
+   }
+   else if(thePolyLineList.size() > 1)
+   {
+      for(ossim_uint32 i = 0; i < thePolyLineList.size(); ++i)
+      {
+         ossimDrect rect = thePolyLineList[i].getBoundingRect();
+         if(theBoundingRect.hasNans())
+         {
+            theBoundingRect = rect;
+         }
+         else if(!rect.hasNans())
+         {
+            theBoundingRect = theBoundingRect.combine(rect);
+         }
+      }
+   }
+}
+
+std::ostream& ossimAnnotationMultiLineObject::print(std::ostream& out)const
+{
+   ossimAnnotationObject::print(out);
+
+   for(ossim_uint32 i = 0; i < thePolyLineList.size();++i)
+   {
+      out << thePolyLineList[i] << endl
+          <<"______________________________________"<<endl;
+   }
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiLineObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiLineObject.h
new file mode 100644
index 0000000000..7485bfa937
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiLineObject.h
@@ -0,0 +1,102 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimAnnotationMultiLineObject.h,v 1.5 2004/05/23 17:49:37 dburken Exp $
+#ifndef ossimAnnotationMultiLineObject_HEADER
+#define ossimAnnotationMultiLineObject_HEADER
+#include "ossimAnnotationObject.h"
+#include "base/data_types/ossimIpt.h"
+#include "base/data_types/ossimPolyLine.h"
+
+class OSSIMDLLEXPORT ossimAnnotationMultiLineObject : public ossimAnnotationObject
+{
+public:
+   ossimAnnotationMultiLineObject();
+   ossimAnnotationMultiLineObject(const std::vector<ossimPolyLine>& lineList,
+                                  unsigned char r=255,
+                                  unsigned char g=255,
+                                  unsigned char b=255,
+                                  long thickness=1)
+      :ossimAnnotationObject(r, g, b, thickness),
+       thePolyLineList(lineList)
+      {
+         computeBoundingRect();
+      }
+
+   ossimAnnotationMultiLineObject(const ossimPolyLine& lineList,
+                                  unsigned char r=255,
+                                  unsigned char g=255,
+                                  unsigned char b=255,
+                                  long thickness=1)
+      :ossimAnnotationObject(r, g, b, thickness)
+      {
+         thePolyLineList.push_back(lineList);
+         computeBoundingRect();
+      }
+   
+
+   ossimAnnotationMultiLineObject(const ossimAnnotationMultiLineObject& rhs)
+      :ossimAnnotationObject(rhs),
+       thePolyLineList(rhs.thePolyLineList),
+       theBoundingRect(rhs.theBoundingRect)
+      {
+      }
+       
+   virtual ossimObject* dup()const
+      {
+         return new ossimAnnotationMultiLineObject(*this);
+      }
+   
+   virtual void applyScale(double x,
+                           double y);
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual bool intersects(const ossimDrect& rect)const;   
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const
+      {
+         rect = theBoundingRect;
+      }
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   virtual void computeBoundingRect();
+
+   virtual const vector<ossimPolyLine>& getPolyLineList()const
+      {
+         return thePolyLineList;
+      }
+
+   virtual vector<ossimPolyLine>& getPolyLineList()
+      {
+         return thePolyLineList;
+      }
+   virtual void setPolyLine(const ossimPolyLine& line)
+      {
+         thePolyLineList.clear();
+         thePolyLineList.push_back(line);
+      }
+protected:
+   vector<ossimPolyLine> thePolyLineList;
+   ossimDrect            theBoundingRect;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyLineObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyLineObject.cpp
new file mode 100644
index 0000000000..5b9066fccf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyLineObject.cpp
@@ -0,0 +1,268 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationMultiPolyLineObject.cpp,v 1.5 2004/05/23 17:49:37 dburken Exp $
+#include <imaging/annotation/ossimAnnotationMultiPolyLineObject.h>
+#include <imaging/annotation/ossimAnnotationMultiLineObject.h>
+#include <imaging/ossimRgbImage.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/ossimLine.h>
+
+RTTI_DEF1(ossimAnnotationMultiPolyLineObject, "ossimAnnotationMultiPolyLineObject", ossimAnnotationObject)
+
+ossimAnnotationMultiPolyLineObject::ossimAnnotationMultiPolyLineObject()
+   :ossimAnnotationObject()
+{
+   computeBoundingRect();
+}
+
+ossimAnnotationMultiPolyLineObject::ossimAnnotationMultiPolyLineObject(const vector<ossimPolyLine>& multiPoly,
+								       unsigned char r,
+								       unsigned char g,
+								       unsigned char b,
+								       long thickness)
+   :ossimAnnotationObject(r, g, b, thickness)
+{
+   theMultiPolyLine = multiPoly;
+   computeBoundingRect();
+}
+
+ossimAnnotationMultiPolyLineObject::~ossimAnnotationMultiPolyLineObject()
+{
+}
+
+void ossimAnnotationMultiPolyLineObject::applyScale(double x,
+                                                double y)
+{
+   for(ossim_uint32 i =0; i<theMultiPolyLine.size(); ++i)
+   {
+      theMultiPolyLine[i] *= ossimDpt(x, y);
+   }
+   
+   theBoundingRect *= ossimDpt(x,y);
+}
+
+bool ossimAnnotationMultiPolyLineObject::intersects(const ossimDrect& rect)const
+{
+   // do the quick checks first
+   //
+   if(rect.hasNans()) return false;
+   if(!rect.intersects(theBoundingRect)) return false;
+   if(theMultiPolyLine.size()<1) return false;
+   
+   for(ossim_uint32 i =0; i < theMultiPolyLine.size(); ++i)
+   {
+      vector<ossimPolyLine> result;
+      
+      if(theMultiPolyLine[i].clipToRect(result, rect))
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+ossimAnnotationObject* ossimAnnotationMultiPolyLineObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimAnnotationObject* result = (ossimAnnotationObject*)NULL;
+   
+   ossimNotify(ossimNotifyLevel_WARN)
+      << "ossimAnnotationMultiPolyLineObject::getNewClippedObject\n"
+      << "Not implemented for " << getClassName() << endl;
+   return result;
+}
+
+void ossimAnnotationMultiPolyLineObject::draw(ossimRgbImage& anImage)const
+{
+   if(theMultiPolyLine.size()<1) return;
+   if(theBoundingRect.hasNans()) return;
+   
+   
+   anImage.setDrawColor(theRed, theGreen, theBlue);
+   anImage.setThickness(theThickness);
+   ossimDrect imageRect = anImage.getImageData()->getImageRectangle();
+   
+   if(theBoundingRect.intersects(imageRect))
+   {
+      // we need to extend it by a couple of pixels since
+      // if a pixel lies on the edge and then another pixel is just off
+      // the edge we will get a stair step and so for several pixels
+      // the line might be inside the image rectangle but the clip
+      // algorithm will only draw 1 pixel since it thinks the first
+      // point is inside and the second point is outside and will
+      // execute the clip algorithm keeping only the first
+      // point.
+      ossimDrect clipRect(imageRect.ul().x - 10,
+                          imageRect.ul().y - 10,
+                          imageRect.lr().x + 10,
+                          imageRect.lr().y + 10);
+      
+      int j = 0;
+      for(ossim_uint32 i = 0; i < theMultiPolyLine.size(); ++i)
+      {
+         const ossimPolyLine& poly = theMultiPolyLine[i];
+         int vertexCount            = poly.getNumberOfVertices();
+
+	 if(vertexCount > 1)
+	   {
+
+	     ossimDpt start, end;
+	     start = poly[0];
+	     end   = poly[1];
+	     j = 1;
+	     do
+	       {
+		 if(clipRect.clip(start, end))
+		   {            
+		     anImage.drawLine(ossimIpt(start),
+				      ossimIpt(end));
+		   }
+		 ++j;
+		 start = poly[j-1];
+		 end   = poly[j];
+	       }while(j < vertexCount);
+	   }
+	 else if(vertexCount == 1)
+	   {
+		     anImage.drawLine(ossimIpt(poly[0]),
+				      ossimIpt(poly[0]));
+	   }
+      }
+   }
+}
+
+std::ostream& ossimAnnotationMultiPolyLineObject::print(std::ostream& out)const
+{
+   ossimAnnotationObject::print(out);
+   out << endl;
+   out << setw(15)<<setiosflags(ios::left)<<"type:"<<getClassName() << endl
+       << setw(15)<<setiosflags(ios::left)<<"polylines:"<<theMultiPolyLine.size()<<endl;
+   
+   for(ossim_uint32 i = 0; i < theMultiPolyLine.size(); ++i)
+   {
+      out << "____________________________________________________"<<endl
+          << theMultiPolyLine[i] << endl;
+   }
+   out << "____________________________________________________"<<endl;
+   return out;
+}
+
+void ossimAnnotationMultiPolyLineObject::getBoundingRect(ossimDrect& rect)const
+{   
+   rect = theBoundingRect;
+}
+
+void ossimAnnotationMultiPolyLineObject::computeBoundingRect()
+{
+   if(theMultiPolyLine.size())
+   {
+      ossimDrect rect(theMultiPolyLine[0].getVertexList());
+      
+      for(ossim_uint32 i = 1; i < theMultiPolyLine.size(); ++i)
+      {
+         ossimDrect rect2(theMultiPolyLine[i].getVertexList());
+
+         if(rect.hasNans())
+         {
+            rect = rect2;
+         }
+         else
+         {
+            if(!rect2.hasNans())
+            {
+               rect = rect.combine(rect2);
+            }
+         }
+      }
+      
+      theBoundingRect = rect;
+   }
+   else
+   {
+      theBoundingRect.makeNan();
+   }
+   if(!theBoundingRect.hasNans())
+   {
+      ossimIpt origin = theBoundingRect.ul();
+      theBoundingRect = ossimDrect(origin.x - theThickness/2,
+                                   origin.y - theThickness/2,
+                                   origin.x + (theBoundingRect.width()-1) + theThickness/2,
+                                   origin.y + (theBoundingRect.height()-1) + theThickness/2);
+   }
+}
+
+bool ossimAnnotationMultiPolyLineObject::isPointWithin(const ossimDpt& imagePoint)const
+{
+//    for(ossim_uint32 i = 0; i < theMultiPolyLine.size(); ++i)
+//    {
+//       if(theMultiPolyLine[i].isPointWithin(imagePoint))
+//       {
+//          return true;
+//       }
+//   }
+
+  return theBoundingRect.pointWithin(imagePoint);
+}
+
+ossimAnnotationMultiPolyLineObject::ossimAnnotationMultiPolyLineObject(const ossimAnnotationMultiPolyLineObject& rhs)
+      : ossimAnnotationObject(rhs),
+        theMultiPolyLine(rhs.theMultiPolyLine),
+        theBoundingRect(rhs.theBoundingRect)
+{
+}
+
+ossimObject* ossimAnnotationMultiPolyLineObject::dup()const
+{
+   return new ossimAnnotationMultiPolyLineObject(*this);
+}
+
+void ossimAnnotationMultiPolyLineObject::addPolyLine(const ossimPolyLine& poly)
+{
+   theMultiPolyLine.push_back(poly);
+}
+
+void ossimAnnotationMultiPolyLineObject::addPoint(ossim_uint32 polygonIndex,
+                                                  const ossimDpt& pt)
+{
+   if(polygonIndex < theMultiPolyLine.size())
+   {
+      theMultiPolyLine[polygonIndex].addPoint(pt);
+   }
+}
+
+void ossimAnnotationMultiPolyLineObject::setMultiPolyLine(const vector<ossimPolyLine>& multiPoly)
+{
+   theMultiPolyLine = multiPoly;
+   computeBoundingRect();
+}
+
+const std::vector<ossimPolyLine>& ossimAnnotationMultiPolyLineObject::getMultiPolyLine()const
+{
+   return theMultiPolyLine;
+}
+
+std::vector<ossimPolyLine>& ossimAnnotationMultiPolyLineObject::getMultiPolyLine()
+{
+   return theMultiPolyLine;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyLineObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyLineObject.h
new file mode 100644
index 0000000000..e51894b43e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyLineObject.h
@@ -0,0 +1,70 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimAnnotationMultiPolyLineObject.h,v 1.2 2004/05/23 17:49:37 dburken Exp $
+#ifndef ossimAnnotationMultiPolyLineObject_HEADER
+#define ossimAnnotationMultiPolyLineObject_HEADER
+
+#include "ossimAnnotationObject.h"
+#include "base/data_types/ossimIpt.h"
+#include "base/data_types/ossimPolyLine.h"
+
+class OSSIMDLLEXPORT ossimAnnotationMultiPolyLineObject : public ossimAnnotationObject
+{
+public:
+   ossimAnnotationMultiPolyLineObject();
+   ossimAnnotationMultiPolyLineObject(const vector<ossimPolyLine>& multiPoly,
+                                  unsigned char r,
+                                  unsigned char g,
+                                  unsigned char b,
+                                  long thickness);
+   
+   ossimAnnotationMultiPolyLineObject(const ossimAnnotationMultiPolyLineObject& rhs);
+
+   virtual ossimObject* dup()const;
+
+   virtual ~ossimAnnotationMultiPolyLineObject();
+   virtual void applyScale(double x,
+                           double y);
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void addPolyLine(const ossimPolyLine& poly);
+   virtual void addPoint(ossim_uint32 polygonIndex, const ossimDpt& pt);
+   
+   virtual void setMultiPolyLine(const vector<ossimPolyLine>& multiPoly);
+   virtual void computeBoundingRect();
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   
+   const std::vector<ossimPolyLine>& getMultiPolyLine()const;
+   std::vector<ossimPolyLine>& getMultiPolyLine();
+protected:
+   vector<ossimPolyLine> theMultiPolyLine;
+   ossimDrect           theBoundingRect;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyObject.cpp
new file mode 100644
index 0000000000..64330c07a7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyObject.cpp
@@ -0,0 +1,322 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimAnnotationMultiPolyObject.cpp,v 1.18 2004/12/21 20:12:40 gpotts Exp $
+#include "ossimAnnotationMultiPolyObject.h"
+#include "ossimAnnotationMultiLineObject.h"
+#include "imaging/ossimRgbImage.h"
+#include "base/data_types/ossimIrect.h"
+#include "base/data_types/ossimDrect.h"
+#include "base/data_types/ossimLine.h"
+
+RTTI_DEF1(ossimAnnotationMultiPolyObject, "ossimAnnotationMultiPolyObject", ossimAnnotationObject)
+
+ossimAnnotationMultiPolyObject::ossimAnnotationMultiPolyObject()
+   :ossimAnnotationObject(),
+    theFillEnabled(false)
+{
+   computeBoundingRect();
+}
+
+ossimAnnotationMultiPolyObject::ossimAnnotationMultiPolyObject(const vector<ossimPolygon>& multiPoly,
+                                                               bool enableFill,
+                                                               unsigned char r,
+                                                               unsigned char g,
+                                                               unsigned char b,
+                                                               long thickness)
+   :ossimAnnotationObject(r, g, b, thickness),
+    theFillEnabled(enableFill)
+{
+   theMultiPolygon = multiPoly;
+   computeBoundingRect();
+}
+
+ossimAnnotationMultiPolyObject::~ossimAnnotationMultiPolyObject()
+{
+}
+
+void ossimAnnotationMultiPolyObject::applyScale(double x,
+                                                double y)
+{
+   for(ossim_uint32 i =0; i<theMultiPolygon.size(); ++i)
+   {
+      theMultiPolygon[i] *= ossimDpt(x, y);
+   }
+   
+   theBoundingRect *= ossimDpt(x,y);
+}
+
+bool ossimAnnotationMultiPolyObject::intersects(const ossimDrect& rect)const
+{
+   // do the quick checks first
+   //
+   if(rect.hasNans()) return false;
+   if(!rect.intersects(theBoundingRect)) return false;
+   if(theMultiPolygon.size()<1) return false;
+   
+   for(ossim_uint32 i =0; i < theMultiPolygon.size(); ++i)
+   {
+      vector<ossimPolygon> result;
+      
+      if(theMultiPolygon[i].clipToRect(result, rect))
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+ossimAnnotationObject* ossimAnnotationMultiPolyObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimAnnotationObject* result = (ossimAnnotationObject*)NULL;
+
+   if(theBoundingRect.intersects(rect))
+   {
+      ossimDrect clipRect(rect.ul().x - 10,
+                          rect.ul().y - 10,
+                          rect.lr().x + 10,
+                          rect.lr().y + 10);
+      
+      if(theFillEnabled)
+      {
+         vector<ossimPolygon> polyListResult;
+         
+         for(ossim_uint32 i = 0; i < theMultiPolygon.size(); ++i)
+         {
+            vector<ossimPolygon> tempList;
+            
+            if(theMultiPolygon[i].clipToRect(tempList, rect))
+            {
+               polyListResult.insert(polyListResult.end(),
+                                     tempList.begin(),
+                                     tempList.end());
+            }
+         }
+         
+         if(polyListResult.size())
+         {
+            result = new ossimAnnotationMultiPolyObject(polyListResult,
+                                                        theFillEnabled,
+                                                        theRed,
+                                                        theGreen,
+                                                        theBlue,
+                                                        theThickness);
+         }
+      }
+      else
+      {
+         vector<ossimPolyLine> lineListResult;
+         vector<ossimPolyLine> tempResult;
+
+         for(ossim_uint32 i = 0; i< theMultiPolygon.size();++i)
+         {
+            ossimPolyLine polyLine = theMultiPolygon[i];
+
+            if(polyLine.clipToRect(tempResult,
+                                   clipRect))
+            {
+               lineListResult.insert(lineListResult.end(),
+                                     tempResult.begin(),
+                                     tempResult.end());
+            }
+         }
+         
+         if(lineListResult.size())
+         {
+            result = new ossimAnnotationMultiLineObject(lineListResult,
+                                                        theRed,
+                                                        theGreen,
+                                                        theBlue,
+                                                        theThickness);
+         }
+      }
+   }
+   
+   return result;
+}
+
+void ossimAnnotationMultiPolyObject::draw(ossimRgbImage& anImage)const
+{
+   if(theMultiPolygon.size()<1) return;
+   if(theBoundingRect.hasNans()) return;
+   
+   
+   anImage.setDrawColor(theRed, theGreen, theBlue);
+   anImage.setThickness(theThickness);
+   ossimDrect imageRect = anImage.getImageData()->getImageRectangle();
+   
+   if(theBoundingRect.intersects(imageRect))
+   {
+      // we need to extend it by a couple of pixels since
+      // if a pixel lies on the edge and then another pixel is just off
+      // the edge we will get a stair step and so for several pixels
+      // the line might be inside the image rectangle but the clip
+      // algorithm will only draw 1 pixel since it thinks the first
+      // point is inside and the second point is outside and will
+      // execute the clip algorithm keeping only the first
+      // point.
+      ossimDrect clipRect(imageRect.ul().x - 10,
+                          imageRect.ul().y - 10,
+                          imageRect.lr().x + 10,
+                          imageRect.lr().y + 10);
+
+      int j = 0;
+      for(ossim_uint32 i = 0; i < theMultiPolygon.size(); ++i)
+      {
+         const ossimPolygon& poly = theMultiPolygon[i];
+         int vertexCount          = poly.getVertexCount();
+         if(!theFillEnabled)
+         {
+            if(poly.getNumberOfVertices() == 1)
+            {
+               ossimDpt start, end;
+               start = poly[0];
+               end   = poly[0];
+               if(clipRect.clip(start, end))
+               {
+                  anImage.drawLine(ossimIpt(start),
+                                   ossimIpt(end));
+               }
+            }
+            else if(poly.getNumberOfVertices() == 2)
+            {
+               ossimDpt start, end;
+               start = poly[0];
+               end   = poly[1];
+               if(clipRect.clip(start, end))
+               {
+                  anImage.drawLine(ossimIpt(start),
+                                   ossimIpt(end));
+               }
+            }
+            else if(vertexCount > 2)
+            {
+               ossimDpt start, end;
+               start = poly[vertexCount-1];
+               end   = poly[0];
+               j = 0;
+               do
+               {
+                  if(clipRect.clip(start, end))
+                  {
+                     anImage.drawLine(ossimIpt(start),
+                                      ossimIpt(end));
+                  }
+                  ++j;
+                  start = poly[j-1];
+                  end   = poly[j];
+               }while(j < vertexCount);
+            }
+         }
+         else
+         {
+            vector<ossimPolygon> result;
+            if(poly.clipToRect(result, imageRect))
+            {
+               for(j = 0; j < (int)result.size();++j)
+               {
+                  anImage.drawFilledPolygon(result[j].getVertexList());
+               }
+            }
+         }
+      }
+   }
+}
+
+std::ostream& ossimAnnotationMultiPolyObject::print(std::ostream& out)const
+{
+   ossimAnnotationObject::print(out);
+   out << endl;
+   out << setw(15)<<setiosflags(ios::left)<<"type:"<<getClassName() << endl
+       << setw(15)<<setiosflags(ios::left)<<"polygons:"<<theMultiPolygon.size()<<endl
+       << setw(15)<<setiosflags(ios::left)<<"fill enable: " << theFillEnabled << endl;
+   
+   for(ossim_uint32 i = 0; i < theMultiPolygon.size(); ++i)
+   {
+      out << "____________________________________________________"<<endl
+          << theMultiPolygon[i] << endl;
+   }
+   out << "____________________________________________________"<<endl;
+   return out;
+}
+
+void ossimAnnotationMultiPolyObject::getBoundingRect(ossimDrect& rect)const
+{   
+   rect = theBoundingRect;
+}
+
+void ossimAnnotationMultiPolyObject::clear()
+{
+   theMultiPolygon.clear();
+}
+
+void ossimAnnotationMultiPolyObject::computeBoundingRect()
+{
+   if(theMultiPolygon.size())
+   {
+      ossimDrect rect(theMultiPolygon[0]);
+      
+      for(ossim_uint32 i = 1; i < theMultiPolygon.size(); ++i)
+      {
+         ossimDrect rect2(theMultiPolygon[i]);
+
+         if(rect.hasNans())
+         {
+            rect = rect2;
+         }
+         else
+         {
+            if(!rect2.hasNans())
+            {
+               rect = rect.combine(rect2);
+            }
+         }
+      }
+      
+      theBoundingRect = rect;
+   }
+   else
+   {
+      theBoundingRect.makeNan();
+   }
+   if(!theBoundingRect.hasNans())
+   {
+      ossimIpt origin = theBoundingRect.ul();
+      theBoundingRect = ossimDrect(origin.x - theThickness/2,
+                                   origin.y - theThickness/2,
+                                   origin.x + (theBoundingRect.width()-1) + theThickness/2,
+                                   origin.y + (theBoundingRect.height()-1) + theThickness/2);
+   }
+}
+
+bool ossimAnnotationMultiPolyObject::isPointWithin(const ossimDpt& imagePoint)const
+{
+   for(ossim_uint32 i = 0; i < theMultiPolygon.size(); ++i)
+   {
+      if(theMultiPolygon[i].isPointWithin(imagePoint))
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyObject.h
new file mode 100644
index 0000000000..95a3b5a9dd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationMultiPolyObject.h
@@ -0,0 +1,97 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimAnnotationMultiPolyObject.h,v 1.7 2004/05/23 17:49:37 dburken Exp $
+#ifndef ossimAnnotationMultiPolyObject_HEADER
+#define ossimAnnotationMultiPolyObject_HEADER
+#include "ossimAnnotationObject.h"
+#include "base/data_types/ossimIpt.h"
+#include "base/data_types/ossimPolygon.h"
+
+class OSSIMDLLEXPORT ossimAnnotationMultiPolyObject : public ossimAnnotationObject
+{
+public:
+   ossimAnnotationMultiPolyObject();
+   ossimAnnotationMultiPolyObject(const vector<ossimPolygon>& multiPoly,
+                                  bool enableFill,
+                                  unsigned char r,
+                                  unsigned char g,
+                                  unsigned char b,
+                                  long thickness);
+   
+   ossimAnnotationMultiPolyObject(const ossimAnnotationMultiPolyObject& rhs)
+      : ossimAnnotationObject(rhs),
+        theMultiPolygon(rhs.theMultiPolygon),
+        theBoundingRect(rhs.theBoundingRect),
+        theFillEnabled(rhs.theFillEnabled)
+      {
+      }
+   virtual ossimObject* dup()const
+      {
+         return new ossimAnnotationMultiPolyObject(*this);
+      }
+   virtual ~ossimAnnotationMultiPolyObject();
+   virtual void applyScale(double x,
+                           double y);
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void clear();
+   virtual void addPolygon(const ossimPolygon& poly)
+      {
+         theMultiPolygon.push_back(poly);
+      }
+   virtual void addPoint(ossim_uint32 polygonIndex,
+                         const ossimDpt& pt)
+      {
+         if(polygonIndex < theMultiPolygon.size())
+         {
+            theMultiPolygon[polygonIndex].addPoint(pt);
+         }
+      }
+   
+   virtual void setMultiPolygon(const vector<ossimPolygon>& multiPoly)
+      {
+         theMultiPolygon = multiPoly;
+         computeBoundingRect();
+      }
+   virtual void computeBoundingRect();
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   
+   const std::vector<ossimPolygon>& getMultiPolygon()const{return theMultiPolygon;}
+   std::vector<ossimPolygon>& getMultiPolygon(){return theMultiPolygon;}
+   void setFillFlag(bool flag)
+      {
+         theFillEnabled = flag;
+      }
+protected:
+   vector<ossimPolygon> theMultiPolygon;
+   ossimDrect           theBoundingRect;
+   bool                 theFillEnabled;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationObject.cpp
new file mode 100644
index 0000000000..8e81d39d12
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationObject.cpp
@@ -0,0 +1,161 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationObject.cpp,v 1.14 2005/12/07 19:03:12 dburken Exp $
+#include "ossimAnnotationObject.h"
+
+RTTI_DEF1(ossimAnnotationObject, "ossimAnnotationObject", ossimObject)
+
+ossim_uint32 ossimAnnotationObject::theIdCounter = 0;
+
+ossimAnnotationObject::~ossimAnnotationObject()
+{}
+
+void ossimAnnotationObject::restIdCounter()
+{
+  theIdCounter = 0;
+}
+
+ossim_uint32 ossimAnnotationObject::getNextId()
+{
+  ossim_uint32 id = theIdCounter;
+  ++theIdCounter;
+  return id;
+}
+
+ossimAnnotationObject::ossimAnnotationObject(ossim_uint8 r,
+                                             ossim_uint8 g,
+                                             ossim_uint8 b,
+                                             ossim_uint8 thickness)
+   :theRed(r),
+    theGreen(g),
+    theBlue(b),
+    theThickness(thickness)
+{
+  theId = getNextId();
+}
+
+void ossimAnnotationObject::setColor(ossim_uint8 r,
+                                     ossim_uint8 g,
+                                     ossim_uint8 b)
+{
+   theRed    = r;
+   theGreen = g;
+   theBlue   = b;
+}
+
+void ossimAnnotationObject::setThickness(ossim_uint8 thickness)
+{
+   theThickness = thickness;
+}
+
+void ossimAnnotationObject::getColor(ossim_uint8 &r,
+                                     ossim_uint8 &g,
+                                     ossim_uint8 &b)const
+{
+   r = theRed;
+   g = theGreen;
+   b = theBlue;
+}
+
+ossim_uint8 ossimAnnotationObject::getThickness()const
+{
+   return theThickness;
+}
+
+ossim_uint32 ossimAnnotationObject::getId()const
+{
+  return theId;
+}
+
+ossim_uint32 ossimAnnotationObject::setId()
+{
+  theId = getNextId();
+  return getId();
+}
+
+bool ossimAnnotationObject::saveState(ossimKeywordlist& kwl,
+                                      const char* prefix) const
+{
+   kwl.add(prefix, "red",       theRed);
+   kwl.add(prefix, "green",     theGreen);
+   kwl.add(prefix, "blue",      theBlue);
+   kwl.add(prefix, "thickness", theThickness);
+   
+   return ossimObject::saveState(kwl, prefix);
+}
+
+bool ossimAnnotationObject::loadState(const ossimKeywordlist& kwl,
+                                      const char* prefix)
+{
+   const char* red       = kwl.find(prefix, "red");
+   const char* green     = kwl.find(prefix, "green");
+   const char* blue      = kwl.find(prefix, "blue");
+   const char* thickness = kwl.find(prefix, "thickness");
+
+   if(red)
+   {
+      theRed = (ossim_uint8)ossimString(red).toLong();
+   }
+   if(green)
+   {
+      theGreen = (ossim_uint8)ossimString(green).toLong();
+   }
+   if(blue)
+   {
+      theBlue = (ossim_uint8)ossimString(blue).toLong();
+   }
+   if(thickness)
+   {
+      theThickness = (ossim_uint8)ossimString(thickness).toLong();
+   }
+   
+   return ossimObject::loadState(kwl, prefix);
+}
+
+bool ossimAnnotationObject::isPointWithin(const ossimDpt& /* imagePoint */) const
+{
+   return false;
+}
+
+ossimString ossimAnnotationObject::getName()const
+{
+   return theName;
+}
+
+void ossimAnnotationObject::setName(const ossimString& name)
+{
+   theName = name;
+}
+
+ossimDrect ossimAnnotationObject::getBoundingRect()const
+{
+   ossimDrect rect;
+   getBoundingRect(rect);
+   return rect;
+}
+
+void ossimAnnotationObject::applyScale(const ossimDpt& scale)
+{
+   applyScale(scale.x,
+              scale.y);
+}
+
+std::ostream& ossimAnnotationObject::print(ostream& out) const
+{
+   
+   out << setw(15)<<setiosflags(ios::left)<<"Red:" << (long)theRed   << endl
+       <<  setw(15)<<setiosflags(ios::left)<<"Green:" << (long)theGreen << endl
+       <<  setw(15)<<setiosflags(ios::left)<<"Blue" << (long)theBlue << endl
+       <<  setw(15)<<setiosflags(ios::left)<<"Thickness:"<<theThickness
+       << "color_red:   " << (long)theRed       << endl
+       << "color_green: " << (long)theGreen     << endl
+       << "color_blue:  " << (long)theBlue      << endl
+       << "thickness:   " << theThickness << endl;
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationObject.h
new file mode 100644
index 0000000000..dbc62a0a78
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationObject.h
@@ -0,0 +1,105 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationObject.h,v 1.25 2005/12/07 19:03:12 dburken Exp $
+#ifndef ossimAnnotationObject_HEADER
+#define ossimAnnotationObject_HEADER
+#include <iostream>
+
+#include <base/common/ossimObject.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <imaging/ossimRgbImage.h>
+#include <base/data_types/ossimString.h>
+
+class OSSIMDLLEXPORT ossimAnnotationObject : public ossimObject
+{
+public:
+   ossimAnnotationObject(ossim_uint8 r=255,
+                         ossim_uint8 g=255,
+                         ossim_uint8 b=255,
+                         ossim_uint8 thickness=1);
+   virtual ~ossimAnnotationObject();
+   virtual void applyScale(double x,
+                           double y)=0;
+   virtual void applyScale(const ossimDpt& scale);
+   
+   virtual std::ostream& print(std::ostream& out)const;
+
+   virtual void draw(ossimRgbImage& anImage)const=0;
+   virtual bool intersects(const ossimDrect& rect)const=0;
+
+   /*!
+    * Will allocate a new object that is clipped to the passed.
+    * in rect.  Look at derived classes to see if the object is actually
+    * clipped or not.  A new object is returned if it clips to the rect
+    * else NULL should be returned it doesn't clip.
+    */
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const=0;
+   
+   virtual void getBoundingRect(ossimDrect& rect)const=0;
+   virtual ossimDrect getBoundingRect()const;
+
+   virtual void computeBoundingRect()=0;
+   
+   virtual void setColor(ossim_uint8 r,
+                         ossim_uint8 g,
+                         ossim_uint8 b);
+
+   void getColor(ossim_uint8 &r,
+                 ossim_uint8 &g,
+                 ossim_uint8 &b)const;
+
+   ossim_uint8  getThickness()const;
+   virtual void setThickness(ossim_uint8 thickness);
+   
+   /*!
+    * This method allows you to pick an object.  It will
+    * return true or false if the point falls somewhere
+    * on an object.  Look at derived classes for further
+    * information.
+    */
+   virtual bool isPointWithin(const ossimDpt& imagePoint) const;
+
+   /**
+    * Saves the current state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual ossimString getName() const;
+   virtual void setName(const ossimString& name);
+
+  ossim_uint32 getId()const;
+  virtual ossim_uint32 setId();
+
+  static ossim_uint32 getNextId();
+  static void restIdCounter();
+
+protected:
+   ossim_uint8 theRed;
+   ossim_uint8 theGreen;
+   ossim_uint8 theBlue;
+   ossim_uint8 theThickness;
+
+   ossimString  theName;
+   ossim_uint32 theId;
+
+  static ossim_uint32 theIdCounter;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationPolyObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationPolyObject.cpp
new file mode 100644
index 0000000000..5298f781f0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationPolyObject.cpp
@@ -0,0 +1,283 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationPolyObject.cpp,v 1.22 2005/12/09 17:16:05 dburken Exp $
+#include <imaging/annotation/ossimAnnotationPolyObject.h>
+#include <imaging/annotation/ossimAnnotationMultiPolyObject.h>
+#include <imaging/annotation/ossimAnnotationMultiLineObject.h>
+#include <imaging/ossimRgbImage.h>
+#include <base/data_types/ossimIrect.h>
+
+RTTI_DEF1(ossimAnnotationPolyObject,
+          "ossimAnnotationPolyObject",
+          ossimAnnotationObject)
+
+   ossimAnnotationPolyObject::ossimAnnotationPolyObject(bool enableFill,
+                                                        ossim_uint8 r,
+                                                        ossim_uint8 g,
+                                                        ossim_uint8 b,
+                                                        ossim_uint8 thickness)
+      :ossimAnnotationObject(r, g, b, thickness),
+       thePolygon(),
+       theBoundingRect(),
+       theFillEnabled(enableFill)
+{
+}
+
+ossimAnnotationPolyObject::ossimAnnotationPolyObject(
+   const vector<ossimDpt>& imagePts,
+   bool enableFill,
+   ossim_uint8 r,
+   ossim_uint8 g,
+   ossim_uint8 b,
+   ossim_uint8 thickness)
+   :ossimAnnotationObject(r, g, b, thickness),
+    theFillEnabled(enableFill)
+{
+   thePolygon = imagePts;
+   computeBoundingRect();
+}
+
+ossimAnnotationPolyObject::ossimAnnotationPolyObject(
+   const ossimAnnotationPolyObject& rhs)
+   : ossimAnnotationObject(rhs),
+     thePolygon(rhs.thePolygon),
+     theBoundingRect(rhs.theBoundingRect),
+     theFillEnabled(rhs.theFillEnabled)
+{
+}
+
+ossimObject* ossimAnnotationPolyObject::dup()const
+{
+   return new ossimAnnotationPolyObject(*this);
+}
+
+ossimAnnotationPolyObject::~ossimAnnotationPolyObject()
+{
+}
+
+void ossimAnnotationPolyObject::applyScale(double x, double y)
+{
+   thePolygon      *= ossimDpt(x, y);
+   theBoundingRect *= ossimDpt(x,y);
+}
+
+bool ossimAnnotationPolyObject::intersects(const ossimDrect& rect)const
+{
+   // do the quick checks first
+   //
+   if(rect.hasNans()) return false;
+   if(!rect.intersects(theBoundingRect)) return false;
+   
+   if(!theFillEnabled)
+   {
+      int vertexCount = thePolygon.getVertexCount();
+      ossimDpt start, end;
+      start = thePolygon[vertexCount-1];
+      end   = thePolygon[0];
+      int i = 0;
+      do
+      {
+         if(rect.clip(start, end))
+         {
+            return true;
+         }
+         ++i;
+         start = thePolygon[i];
+         end   = thePolygon[i-1];
+      }while(i < vertexCount);
+   }
+   else
+   {
+      vector<ossimPolygon> result;
+      return thePolygon.clipToRect(result, rect);
+   }
+
+   return false;
+}
+
+ossimAnnotationObject* ossimAnnotationPolyObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimAnnotationObject* result = (ossimAnnotationObject*)NULL;
+
+   if(theBoundingRect.intersects(rect))
+   {
+      if(theFillEnabled)
+      {
+         vector<ossimPolygon> resultPoly;
+         
+         if(thePolygon.clipToRect(resultPoly, rect))
+         {
+            if(resultPoly.size() == 1)
+            {
+               result = new ossimAnnotationPolyObject(resultPoly[0].getVertexList(),
+                                                      theFillEnabled,
+                                                      theRed,
+                                                      theGreen,
+                                                      theBlue,
+                                                      theThickness);
+            }
+            else
+            {
+               result = new ossimAnnotationMultiPolyObject(resultPoly,
+                                                           theFillEnabled,
+                                                           theRed,
+                                                           theGreen,
+                                                           theBlue,
+                                                           theThickness);
+            }
+         }
+      }
+      else
+      {
+         vector<ossimPolyLine> lineListResult;
+         ossimPolyLine polyLine = thePolygon;
+         
+         if(polyLine.clipToRect(lineListResult,
+                                rect))
+         {
+            result = new ossimAnnotationMultiLineObject(lineListResult,
+                                                        theRed,
+                                                        theGreen,
+                                                        theBlue,
+                                                        theThickness);
+         }
+      }
+   }
+
+   return result;
+}
+
+void ossimAnnotationPolyObject::draw(ossimRgbImage& anImage)const
+{
+   if(thePolygon.getVertexCount() < 2) return;
+   if(theBoundingRect.hasNans()) return;
+   int vertexCount = thePolygon.getVertexCount();
+   
+   anImage.setDrawColor(theRed, theGreen, theBlue);
+   anImage.setThickness(theThickness);
+   ossimDrect imageRect = anImage.getImageData()->getImageRectangle();
+   if(theBoundingRect.intersects(imageRect))
+   {
+      // we need to extend it by a couple of pixels since
+      // if a pixel lies on the edge and then another pixel is just off
+      // the edge we will get a stair step and so for several pixels
+      // the line might be inside the image rectangle but the clip
+      // algorithm will only draw 1 pixel since it thinks the first
+      // point is inside and the second point is outside and will
+      // execute the clip algorithm keeping only the first
+      // point.
+      ossimDrect clipRect(imageRect.ul().x - 10,
+                          imageRect.ul().y - 10,
+                          imageRect.lr().x + 10,
+                          imageRect.lr().y + 10);
+      
+      if(!theFillEnabled)
+      {
+         ossimDpt start, end;
+         start = thePolygon[vertexCount-1];
+         end   = thePolygon[0];
+         int i = 0;
+         do
+         {
+            if(clipRect.clip(start, end))
+            {
+               anImage.drawLine(ossimIpt((int)start.x, (int)start.y),
+                                ossimIpt((int)end.x, (int)end.y));
+            }
+            ++i;
+            start = thePolygon[i];
+            end   = thePolygon[i-1];
+         }while(i < vertexCount);
+         
+      }
+      else
+      {
+         vector<ossimPolygon> result;
+         if(thePolygon.clipToRect(result, imageRect))
+         {
+            for(int i = 0; i < (int)result.size();++i)
+            {
+               anImage.drawFilledPolygon(result[i].getVertexList());
+            }
+         }
+      }
+   }
+}
+
+std::ostream& ossimAnnotationPolyObject::print(std::ostream& out)const
+{
+   out << "number_of_points:  " << thePolygon.getVertexCount();
+   if(thePolygon.getVertexCount() > 0)
+   {
+      for(long index =0; index < (long)(thePolygon.getVertexCount()-1); ++index)
+      {
+         out << thePolygon[index] << endl;
+            
+      }
+      out << thePolygon[thePolygon.getVertexCount()-1] << endl;
+   }
+   out << "fill_enabled:      " << theFillEnabled << endl
+       << "bounding_rect:     " << theBoundingRect << endl;
+   return out;
+}
+
+void ossimAnnotationPolyObject::getBoundingRect(ossimDrect& rect)const
+{
+   rect = theBoundingRect;
+}
+
+void ossimAnnotationPolyObject::addPoint(const ossimDpt& pt)
+{
+   thePolygon.addPoint(pt);
+}
+
+void ossimAnnotationPolyObject::setPolygon(const vector<ossimDpt>& imagePoints)
+{
+   thePolygon = imagePoints;
+}
+
+void ossimAnnotationPolyObject::setPolygon(const ossimPolygon& polygon)
+{
+   thePolygon = polygon;
+}
+
+void ossimAnnotationPolyObject::setPolygon(const ossimIrect& rect)
+{
+   thePolygon = rect;
+}
+
+void ossimAnnotationPolyObject::setPolygon(const ossimDrect& rect)
+{
+   thePolygon = rect;
+}
+
+void ossimAnnotationPolyObject::computeBoundingRect()
+{
+   theBoundingRect = ossimDrect(thePolygon);
+}
+
+bool ossimAnnotationPolyObject::isPointWithin(const ossimDpt& imagePoint)const
+{
+   return theBoundingRect.pointWithin(imagePoint);
+}
+
+const ossimPolygon& ossimAnnotationPolyObject::getPolygon() const
+{
+   return thePolygon;
+}
+
+ossimPolygon& ossimAnnotationPolyObject::getPolygon()
+{
+   return thePolygon;
+}
+
+void ossimAnnotationPolyObject::setFillFlag(bool flag)
+{
+   theFillEnabled = flag;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationPolyObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationPolyObject.h
new file mode 100644
index 0000000000..aceed27464
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationPolyObject.h
@@ -0,0 +1,80 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationPolyObject.h,v 1.16 2005/12/09 17:16:05 dburken Exp $
+#ifndef ossimAnnotationPolyObject_HEADER
+#define ossimAnnotationPolyObject_HEADER
+
+#include <imaging/annotation/ossimAnnotationObject.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimPolygon.h>
+
+class OSSIMDLLEXPORT ossimAnnotationPolyObject : public ossimAnnotationObject
+{
+public:
+   ossimAnnotationPolyObject(bool enableFill = false,
+                             ossim_uint8 r=255,
+                             ossim_uint8 g=255,
+                             ossim_uint8 b=255,
+                             ossim_uint8 thickness=1);
+   
+   ossimAnnotationPolyObject(const vector<ossimDpt>& imagePts,
+                             bool enableFill = false,
+                             ossim_uint8 r=255,
+                             ossim_uint8 g=255,
+                             ossim_uint8 b=255,
+                             ossim_uint8 thickness=1);
+   
+   ossimAnnotationPolyObject(const ossimAnnotationPolyObject& rhs);
+
+   ossimObject* dup()const;
+
+   virtual ~ossimAnnotationPolyObject();
+
+   virtual void applyScale(double x, double y);
+
+   virtual void draw(ossimRgbImage& anImage)const;
+
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual ossimAnnotationObject* getNewClippedObject(
+      const ossimDrect& rect)const;
+
+   virtual std::ostream& print(std::ostream& out)const;
+
+   virtual void getBoundingRect(ossimDrect& rect)const;
+
+   virtual void addPoint(const ossimDpt& pt);
+
+   virtual void setPolygon(const vector<ossimDpt>& imagePoints);
+
+   virtual void setPolygon(const ossimPolygon& polygon);
+
+   virtual void setPolygon(const ossimIrect& rect);
+
+   virtual void setPolygon(const ossimDrect& rect);
+
+   virtual void computeBoundingRect();
+
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+
+   const ossimPolygon& getPolygon()const;
+
+   ossimPolygon& getPolygon();
+
+   virtual void setFillFlag(bool flag);
+
+protected:
+   ossimPolygon thePolygon;
+   ossimDrect   theBoundingRect;
+   bool         theFillEnabled;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationSource.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationSource.cpp
new file mode 100644
index 0000000000..2a8676d3c6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationSource.cpp
@@ -0,0 +1,457 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationSource.cpp,v 1.61 2005/12/07 20:54:19 dburken Exp $
+#include <imaging/annotation/ossimAnnotationSource.h>
+#include <imaging/annotation/ossimAnnotationObject.h>
+#include <imaging/factory/ossimAnnotationObjectFactory.h>
+#include <imaging/ossimRgbImage.h>
+#include <imaging/ossimU8ImageData.h>
+
+#include <base/common/ossimTrace.h>
+
+RTTI_DEF1(ossimAnnotationSource, "ossimAnnotationSource", ossimImageSourceFilter)
+   
+static ossimTrace traceDebug("ossimAnnotationSource:debug");
+
+ossimAnnotationSource::ossimAnnotationSource(ossimImageSource* inputSource)
+   :
+      ossimImageSourceFilter(inputSource),
+      theRectangle(0, 0, 0, 0),
+      theNumberOfBands(1),
+      theImage(NULL),
+      theTile(NULL),
+      theAnnotationObjectList()
+{
+   theRectangle.makeNan();
+}
+
+ossimAnnotationSource::~ossimAnnotationSource()
+{
+   deleteAll();
+   destroy();
+}
+
+void ossimAnnotationSource::destroy()
+{
+   if(theImage)
+   {
+      delete theImage;
+      theImage = NULL;
+   }
+}
+
+void ossimAnnotationSource::allocate(const ossimIrect& rect)
+{
+   destroy();
+
+   ossim_uint32 width  = rect.width();
+   ossim_uint32 height = rect.height();
+   
+   theImage = new ossimRgbImage();
+   
+   theTile = new ossimU8ImageData(this,
+                                  theNumberOfBands,
+                                  width,
+                                  height);
+   
+   theTile->initialize();
+}
+
+ossimScalarType ossimAnnotationSource::getOutputScalarType() const
+{
+   if(theInputConnection && !isSourceEnabled())
+   {
+      return theInputConnection->getOutputScalarType();
+   }
+   return OSSIM_UCHAR;
+}
+
+ossim_uint32 ossimAnnotationSource::getNumberOfOutputBands()const
+{
+   if(theInputConnection && !isSourceEnabled())
+   {
+      return theInputConnection->getNumberOfOutputBands();
+   }
+   // this source is an RGB source
+   return theNumberOfBands;
+}
+
+
+void ossimAnnotationSource::initialize()
+{
+   //---
+   // Call the base class initialize.
+   // Note:  This will reset "theInputConnection" if it changed...
+   //---
+   ossimImageSourceFilter::initialize();
+
+   if (theInputConnection)
+   {
+      computeBoundingRect();
+
+      ossim_uint32 bands = theInputConnection->getNumberOfOutputBands();
+      if (bands == 1 || bands == 3)
+      {
+         setNumberOfBands(bands);
+      }
+
+      if (theTile.valid())  // Check for number of band change.
+      {
+         if ( theInputConnection->getNumberOfOutputBands() !=
+              theTile->getNumberOfBands())
+         {
+            //---
+            // This will wide things slick and force an allocate()
+            // call on first getTile().
+            //---
+            destroy();
+         }
+      }
+   }
+   else
+   {
+      destroy();
+   }
+}
+
+ossimIrect ossimAnnotationSource::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimIrect result;
+   result.makeNan();
+   
+   if(theInputConnection)
+   {
+      ossimIrect temp = theInputConnection->getBoundingRect(resLevel);
+      result = temp;
+   }
+   
+   if(result.hasNans())
+   {
+      result = theRectangle;
+   }
+   else if(!theRectangle.hasNans())
+   {
+      result.combine(theRectangle);
+   }
+      
+   return result;
+}
+
+
+void ossimAnnotationSource::setNumberOfBands(ossim_uint32 bands)
+{
+   theNumberOfBands = bands;
+
+   if(theNumberOfBands == 2) theNumberOfBands = 3;
+   if(theNumberOfBands > 3) theNumberOfBands  = 3;
+   if(theNumberOfBands < 1) theNumberOfBands  = 1;
+}
+
+ossimRefPtr<ossimImageData> ossimAnnotationSource::getTile(const ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> inputTile = NULL;
+
+   if(theInputConnection)
+   {
+   // Fetch tile from pointer from the input source.
+      inputTile = theInputConnection->getTile(tile_rect,
+                                              resLevel);
+   }
+   
+   // Check for remap bypass:
+   if ( !theEnableFlag)
+   {
+      return inputTile;
+   }
+
+   // Check for first time through or size or band change.
+   if ( !theTile ||  
+        tile_rect.height() != theTile->getHeight() ||
+        tile_rect.width()  != theTile->getWidth())
+   {
+      allocate(tile_rect);
+   }
+   if(!theTile)
+   {
+      return theTile;
+   }
+   
+   theTile->makeBlank();
+
+   // Set the origin of the output tile.
+   theTile->setImageRectangle(tile_rect);
+   
+   if(inputTile.valid() &&
+      inputTile->getBuf()&&
+      (inputTile->getDataObjectStatus()!=OSSIM_EMPTY))
+   {
+      if(theTile->getNumberOfBands() !=
+         inputTile->getNumberOfBands())
+      {
+         int maxBands = ossimMin(theTile->getNumberOfBands(),
+                                 inputTile->getNumberOfBands());
+         int idx = 0;
+         for(idx = 0; idx < maxBands; ++idx)
+         {
+            theTile->loadBand(inputTile->getBuf(idx),
+                              inputTile->getImageRectangle(),
+                              idx);
+         }
+         int saveIdx = idx - 1;
+         for(;idx<(int)theTile->getNumberOfBands();++idx)
+         {
+            theTile->loadBand(inputTile->getBuf(saveIdx),
+                              inputTile->getImageRectangle(),
+                              idx);
+         }
+      }
+      else
+      {
+         theTile->loadTile(inputTile.get());
+      }
+   }
+
+   drawAnnotations(theTile);
+
+   theTile->validate();
+      
+   return theTile;
+}
+
+bool ossimAnnotationSource::addObject(ossimAnnotationObject* anObject)
+{
+   if(anObject)
+   {
+      theAnnotationObjectList.push_back(anObject);
+      return true;
+   }
+
+   return false;
+}
+
+bool ossimAnnotationSource::deleteObject(ossimAnnotationObject* anObject)
+{
+   if(anObject)
+   {
+      vector<ossimAnnotationObject*>::iterator current = theAnnotationObjectList.begin();
+      while(current != theAnnotationObjectList.end())
+      {
+         if(*current == anObject)
+         {
+            delete anObject;
+            theAnnotationObjectList.erase(current);
+            return true;
+         }
+         ++current;
+      }
+   }
+
+   return false;
+}
+
+bool ossimAnnotationSource::saveState(ossimKeywordlist& kwl,
+                                      const char* prefix)const
+{
+   // Save the state of all annotation objects we have.
+   vector<ossimAnnotationObject*>::const_iterator obj =
+      theAnnotationObjectList.begin();
+   ossim_uint32 objIdx = 0;
+   while (obj < theAnnotationObjectList.end())
+   {
+      ossimString newPrefix = prefix;
+      
+      newPrefix += (ossimString("object") +
+                    ossimString::toString(objIdx) +
+                    ossimString("."));
+      (*obj)->saveState(kwl, newPrefix.c_str());
+      ++objIdx;
+      ++obj;
+   }
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimAnnotationSource::loadState(const ossimKeywordlist& kwl,
+                                      const char* prefix)
+{
+   ossim_uint32 index = 0;
+   ossimString copyPrefix = prefix;
+   ossim_uint32 result = kwl.getNumberOfSubstringKeys(copyPrefix +
+                                                      "object[0-9]+\\.");
+   
+   ossim_uint32 numberOfMatches = 0;
+   const ossim_uint32 MAX_INDEX = result + 100;
+   
+   while(numberOfMatches < result)
+   {
+      ossimString newPrefix = copyPrefix;
+      newPrefix += ossimString("object");
+      newPrefix += ossimString::toString(index);
+      newPrefix += ossimString(".");
+
+      const char* lookup = kwl.find(newPrefix.c_str(), "type");
+      if (lookup)
+      {
+         ++numberOfMatches;
+         
+         ossimAnnotationObject* obj = NULL;
+         obj = ossimAnnotationObjectFactory::instance()->
+            create(kwl, newPrefix.c_str());
+         if (obj)
+         {
+            if(!addObject(obj))
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "ossimGeoAnnotationSource::loadState\n"
+                  << "Object " << obj->getClassName()
+                  << " is not a geographic object" << endl;
+               delete obj;
+            }
+         }
+      }
+
+      ++index;
+      
+      if (index > MAX_INDEX) // Avoid infinite loop...
+      {
+         break;
+      }
+   }
+
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+void ossimAnnotationSource::computeBoundingRect()
+{   
+   theRectangle.makeNan();
+
+   if(theAnnotationObjectList.size()>0)
+   {
+      ossimDrect rect;
+      theAnnotationObjectList[0]->computeBoundingRect();
+      
+      theAnnotationObjectList[0]->getBoundingRect(theRectangle);
+      
+      vector<ossimAnnotationObject*>::iterator object = (theAnnotationObjectList.begin()+1);
+      while(object != theAnnotationObjectList.end())
+      {
+         (*object)->computeBoundingRect();
+         (*object)->getBoundingRect(rect);
+         if(theRectangle.hasNans())
+         {
+            theRectangle = rect;
+         }
+         else if(!rect.hasNans())
+         {  
+            theRectangle = theRectangle.combine(rect);
+         }
+         ++object;
+      }
+   }
+}
+
+vector<ossimAnnotationObject*> ossimAnnotationSource::pickObjects(const ossimDpt& imagePoint)
+{
+   vector<ossimAnnotationObject*> result;
+   vector<ossimAnnotationObject*>::iterator currentObject;
+
+   currentObject = theAnnotationObjectList.begin();
+
+   while(currentObject != theAnnotationObjectList.end())
+   {
+      if((*currentObject)->isPointWithin(imagePoint))
+      {
+         result.push_back(*currentObject);
+      }
+      
+      ++currentObject;
+   }
+   return result;
+}
+
+vector<ossimAnnotationObject*> ossimAnnotationSource::pickObjects(const ossimDrect& imageRect)
+{
+   vector<ossimAnnotationObject*> result;
+   vector<ossimAnnotationObject*>::iterator currentObject;
+
+   currentObject = theAnnotationObjectList.begin();
+
+   while(currentObject != theAnnotationObjectList.end())
+   {
+      ossimAnnotationObject* current = (*currentObject);
+      if(current->isPointWithin(imageRect.ul()))
+      {
+         result.push_back(*currentObject);
+      }
+      else if(current->isPointWithin(imageRect.ll()))
+      {
+         result.push_back(*currentObject);
+      }
+      else if(current->isPointWithin(imageRect.lr()))
+      {
+         result.push_back(*currentObject);
+      }
+      else if(current->isPointWithin(imageRect.ur()))
+      {
+         result.push_back(*currentObject);
+      }
+      
+      ++currentObject;
+   }
+   return result;
+}
+
+void ossimAnnotationSource::deleteAll()
+{
+   vector<ossimAnnotationObject*>::iterator obj;
+
+   obj = theAnnotationObjectList.begin();
+
+   while(obj != theAnnotationObjectList.end())
+   {
+      if(*obj)
+      {
+         delete *obj;
+         *obj = NULL;
+      }
+      
+      ++obj;
+   }
+
+   theAnnotationObjectList.clear();
+}
+
+void ossimAnnotationSource::drawAnnotations(ossimRefPtr<ossimImageData> tile)
+{
+   theImage->setCurrentImageData(tile);
+
+   if(theImage->getImageData().valid())
+   {
+      vector<ossimAnnotationObject*>::iterator object = theAnnotationObjectList.begin();
+      while(object != theAnnotationObjectList.end())
+      {
+         if(*object)
+         {
+            (*object)->draw(*theImage);
+         }
+         ++object;
+      }      
+   }
+}
+
+const vector<ossimAnnotationObject*>& ossimAnnotationSource::getObjectList()const
+{
+   return theAnnotationObjectList;
+}
+
+vector<ossimAnnotationObject*>& ossimAnnotationSource::getObjectList()
+{
+   return theAnnotationObjectList;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationSource.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationSource.h
new file mode 100644
index 0000000000..871d14eaa4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimAnnotationSource.h
@@ -0,0 +1,140 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationSource.h,v 1.29 2005/12/07 18:58:11 dburken Exp $
+#ifndef ossimAnnotationSource_HEADER
+#define ossimAnnotationSource_HEADER
+#include <list>
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+
+class ossimRgbImage;
+class ossimAnnotationObject;
+
+class OSSIMDLLEXPORT ossimAnnotationSource : public ossimImageSourceFilter
+{
+public:
+   ossimAnnotationSource(ossimImageSource* inputSource=NULL);
+   virtual ~ossimAnnotationSource();
+
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+
+   virtual ossimScalarType getOutputScalarType() const;
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel = 0);
+   
+   /*!
+    * Will allow this source to initialize its data objects.  If it needs to
+    * it should call its connection to get what it needs.
+    */
+   virtual void initialize();
+
+   /*!
+    * Will return the bounding rectangle.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+
+   /*!
+    * This can be 1 or 3 bands
+    */
+   virtual void setNumberOfBands(ossim_uint32 bands);
+   
+   /*!
+    * Will add an object to the list.
+    * it will own the object added.
+    */
+   virtual bool addObject(ossimAnnotationObject* anObject);
+   
+   /*!
+    * Will delete an object from the list.
+    * Note: the passed in pointer is no long
+    *       valid.
+    */
+   virtual bool deleteObject(ossimAnnotationObject* anObject);
+
+   /*!
+    * Saves the current state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual void computeBoundingRect();
+
+   /*!
+    * Calls the isPointWithin all Annotation
+    * Objects.  Note:  Do not delete these objects.
+    */
+   vector<ossimAnnotationObject*> pickObjects(const ossimDpt& imagePoint);
+
+   /*!
+    * Note: do not delete the objects returned.
+    */
+   vector<ossimAnnotationObject*> pickObjects(const ossimDrect& imageRect);
+
+   const vector<ossimAnnotationObject*>& getObjectList()const;
+
+   vector<ossimAnnotationObject*>& getObjectList();
+
+   /*!
+     Clears theAnnotationObjectList vector.  All elements are deleted.
+   */
+   void deleteAll();
+   
+   virtual void drawAnnotations(ossimRefPtr<ossimImageData> tile);
+   
+protected:
+   
+   void allocate(const ossimIrect& rect);
+   void destroy();
+   
+   ossimAnnotationSource(const ossimAnnotationSource& rhs):ossimImageSourceFilter(rhs){}
+
+   /*!
+    * What is the size of the image.  This class
+    * is an image producer and it needs to know about
+    * its bounds. We will default the rectangle to an
+    * empty region.
+    */
+   ossimDrect theRectangle;
+   
+   /*!
+    * The output band can be set to 1 or 3 for
+    * grey or RGB scale. We will default this to
+    * a 1 band image.
+    */
+   ossim_uint32 theNumberOfBands;
+
+   /*!
+    * This has all the routines we need for drawing
+    * lines, circles and polygons.
+    */
+   ossimRgbImage* theImage;
+   
+   ossimRefPtr<ossimImageData> theTile;
+
+   /*!
+    * These will be all your primitives in
+    * Example: lines, circles, text ...
+    */
+   std::vector<ossimAnnotationObject*> theAnnotationObjectList;   
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimAnnotationSource_HEADER */
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimEsriShapeFileFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimEsriShapeFileFilter.cpp
new file mode 100644
index 0000000000..6c34bbb611
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimEsriShapeFileFilter.cpp
@@ -0,0 +1,813 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License: See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimEsriShapeFileFilter.cpp,v 1.47 2005/12/07 19:07:00 dburken Exp $
+
+#include <cstdio>
+#include <cstdlib>
+#include <sstream>
+using namespace std;
+
+#include <imaging/annotation/ossimEsriShapeFileFilter.h>
+#include <vec/shape/ossimShapeFile.h>
+#include <imaging/annotation/ossimAnnotationPolyObject.h>
+#include <imaging/annotation/ossimGeoAnnotationPolyLineObject.h>
+#include <imaging/annotation/ossimAnnotationObject.h>
+#include <imaging/annotation/ossimGeoAnnotationPolyObject.h>
+#include <imaging/annotation/ossimGeoAnnotationEllipseObject.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimGeoPolygon.h>
+#include <base/misc/ossimUnitConversionTool.h>
+#include <projections/ossimProjection.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/map_projections/ossimMapProjection.h>
+
+
+RTTI_DEF2(ossimEsriShapeFileFilter,
+          "ossimEsriShapeFileFilter",
+          ossimAnnotationSource,
+          ossimViewInterface);
+
+static const ossimTrace traceDebug("ossimEsriShapeFileFilter:debug");
+
+ossimEsriShapeFileFilter::ossimEsriShapeFileFilter(ossimImageSource* inputSource)
+   :ossimAnnotationSource(inputSource),
+    ossimViewInterface(),
+    theViewProjection(NULL),
+    theShapeFileProjection(NULL),
+    theOwnsViewProjectionFlag(true),
+    theCoordinateSystem(OSSIM_GEOGRAPHIC_SPACE),
+    theUnitType(OSSIM_METERS),
+    theTree((SHPTree*)NULL),
+    theMaxQuadTreeLevels(10),
+    thePenColor(255,255,255),
+    theBrushColor(255,255,255),
+    theFillFlag(false),
+    theThickness(1),
+    thePointWidthHeight(1, 1),
+    theBorderSize(0.0),
+    theBorderSizeUnits(OSSIM_DEGREES)
+{
+   ossimViewInterface::theObject = this;
+   ossimAnnotationSource::setNumberOfBands(3);
+   theBoundingRect.makeNan();
+   theMinArray[0] = theMinArray[1] = theMinArray[2] = theMinArray[3] = OSSIM_DBL_NAN;
+   theMaxArray[0] = theMaxArray[1] = theMaxArray[2] = theMaxArray[3] = OSSIM_DBL_NAN;
+}
+
+ossimEsriShapeFileFilter::~ossimEsriShapeFileFilter()
+{
+   removeViewProjection();
+   
+   if(theTree)
+   {
+      SHPDestroyTree(theTree);
+   }
+
+   deleteCache();
+}
+
+bool ossimEsriShapeFileFilter::setView(ossimObject* baseObject,
+                                       bool ownsTheView)
+{
+   ossimProjection* proj = PTR_CAST(ossimProjection, baseObject);
+   if(proj)
+   {
+      setProjection(proj, ownsTheView);
+      
+      return true;
+   }
+   else if(!baseObject)
+   {
+      setProjection((ossimProjection*)NULL, true);
+   }
+
+   return false;
+}
+
+ossimObject* ossimEsriShapeFileFilter::getView()
+{
+   return theViewProjection;
+}
+
+const ossimObject* ossimEsriShapeFileFilter::getView()const
+{
+   return theViewProjection;
+}
+
+bool ossimEsriShapeFileFilter::addObject(ossimAnnotationObject* anObject)
+{
+   ossimNotify(ossimNotifyLevel_WARN)
+      << "ossimEsriShapeFileFilter::addObject\n"
+      << "Can't add objects to layer, must go through Esri loadShapeFile"
+      <<endl;
+   
+   return false;
+}
+
+void ossimEsriShapeFileFilter::computeBoundingRect()
+{
+//   ossimAnnotationSource::computeBoundingRect();
+   
+   std::multimap<int, ossimAnnotationObject*>::iterator iter = theShapeCache.begin();
+   
+   theBoundingRect.makeNan();
+   while(iter != theShapeCache.end())
+   {
+       ossimDrect rect = (*iter).second->getBoundingRect();
+      if(theBoundingRect.hasNans())
+      {
+         theBoundingRect = rect;
+      }
+      else
+      {
+         if(!rect.hasNans())
+         {
+            theBoundingRect = theBoundingRect.combine(rect);
+         }
+      }
+      
+      ++iter;
+   }
+}
+
+ossimIrect ossimEsriShapeFileFilter::getBoundingRect(ossim_uint32 resLevel)const
+{
+   if(!isSourceEnabled()||
+      getInput())
+   {
+      if(getInput())
+      {
+         ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                                     getInput());
+         if(input)
+         {
+            return input->getBoundingRect(resLevel);
+         }
+      }
+   }
+   return theBoundingRect;
+}
+
+void ossimEsriShapeFileFilter::drawAnnotations(ossimRefPtr<ossimImageData> tile)
+{
+   ossimAnnotationSource::drawAnnotations(tile);
+   
+   if (!theTree||!theShapeFile.isOpen()) return;
+   if(theViewProjection)
+   {
+      ossimIrect rect = tile->getImageRectangle();
+
+      rect = ossimIrect(rect.ul().x,
+                        rect.ul().y,
+                        rect.lr().x,
+                        rect.lr().y);
+      double boundsMin[2];
+      double boundsMax[2];
+      
+      ossimGpt gp1;
+      ossimGpt gp2;
+      ossimGpt gp3;
+      ossimGpt gp4;
+
+      theViewProjection->lineSampleToWorld(rect.ul(),
+                                           gp1);
+      theViewProjection->lineSampleToWorld(rect.ur(),
+                                           gp2);
+      theViewProjection->lineSampleToWorld(rect.lr(),
+                                           gp3);
+      theViewProjection->lineSampleToWorld(rect.ll(),
+                                           gp4);
+
+      ossimDrect boundsRect( ossimDpt(gp1.lond(),
+                                      gp1.latd()),
+                             ossimDpt(gp2.lond(),
+                                      gp2.latd()),
+                             ossimDpt(gp3.lond(),
+                                      gp3.latd()),
+                             ossimDpt(gp4.lond(),
+                                      gp4.latd()),
+                             OSSIM_RIGHT_HANDED);
+
+      boundsMin[0] = boundsRect.ul().x;
+      boundsMin[1] = boundsRect.lr().y;
+
+      boundsMax[0] = boundsRect.lr().x;
+      boundsMax[1] = boundsRect.ul().y;
+
+      int n;
+      int *array=(int*)NULL;
+      
+      array = SHPTreeFindLikelyShapes(theTree,
+                                      boundsMin,
+                                      boundsMax,
+                                      &n);
+      
+      theImage->setCurrentImageData(tile);
+      if(n&&array)
+      {
+         for(int i = 0; i < n; ++i)
+         {
+            std::multimap<int, ossimAnnotationObject*>::iterator iter = theShapeCache.find(array[i]);
+            while( ((*iter).first == array[i]) && (iter != theShapeCache.end()) )
+            {
+               (*iter).second->draw(*theImage);
+               ++iter;
+            }
+         }
+         
+         free(array);
+      }
+   }
+}
+
+void ossimEsriShapeFileFilter::transformObjects(ossimProjection* projection)
+{
+   std::multimap<int, ossimAnnotationObject*>::iterator iter = theShapeCache.begin();
+
+
+   ossimProjection* proj = theViewProjection;
+   if(projection)
+   {
+      proj = projection;
+   }
+
+   if(!proj) return;
+   
+   while(iter != theShapeCache.end())
+   {
+      ossimGeoAnnotationObject* obj = PTR_CAST(ossimGeoAnnotationObject,
+                                               (*iter).second);
+      if(obj)
+      {
+         obj->transform(proj);
+      }
+      ++iter;
+   }
+
+   computeBoundingRect();
+}
+
+void ossimEsriShapeFileFilter::setProjection(ossimProjection* projection,
+                                             bool ownsProjectionFlag)
+{
+   removeViewProjection();
+
+   theViewProjection         = projection;
+   theOwnsViewProjectionFlag = ownsProjectionFlag;
+
+   transformObjects();
+}
+
+bool ossimEsriShapeFileFilter::getImageGeometry(ossimKeywordlist& kwl,
+                                                const char* prefix)
+{
+   if(theViewProjection)
+   {
+      return theViewProjection->saveState(kwl, prefix);
+   }
+   else
+   {
+      ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface, getInput(0));
+      if(input)
+      {
+         return input->getImageGeometry(kwl, prefix);
+      }
+      else
+      {
+         kwl.add(prefix,
+                 ossimKeywordNames::TYPE_KW,
+                 "ossimEquDistCylProjection",
+                 true);
+         kwl.add(prefix,
+                 ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+                 .1,
+                 true);
+         kwl.add(prefix,
+                 ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+                 .1,
+                 true);
+         kwl.add(prefix,
+                 ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+                 0.0,
+                 true);
+         kwl.add(prefix,
+                 ossimKeywordNames::ORIGIN_LATITUDE_KW,
+                 0.0,
+                 true);
+         kwl.add(prefix,
+                 ossimKeywordNames::DATUM_KW,
+                 "WGE",
+                 true);
+         return true;
+      }
+   }
+   
+   return false;
+}
+
+void ossimEsriShapeFileFilter::removeViewProjection()
+{
+   if(theViewProjection&&theOwnsViewProjectionFlag)
+   {
+      delete theViewProjection;
+   }
+
+   theViewProjection = NULL;
+}
+
+void ossimEsriShapeFileFilter::deleteCache()
+{
+   std::multimap<int, ossimAnnotationObject*>::iterator iter = theShapeCache.begin();
+
+
+   while(iter != theShapeCache.end())
+   {
+      if((*iter).second)
+      {
+         delete (*iter).second;
+      }
+      ++iter;
+   }
+
+   theShapeCache.clear();
+}
+
+void ossimEsriShapeFileFilter::checkAndSetDefaultView()
+{
+   if(!theViewProjection)
+   {
+      ossimKeywordlist tempKwl;
+      getImageGeometry(tempKwl);
+      
+      theViewProjection = ossimProjectionFactoryRegistry::instance()->createProjection(tempKwl);
+      
+      if(theViewProjection)
+      {
+         transformObjects();
+      }
+   }
+}
+
+bool ossimEsriShapeFileFilter::loadShapeFile(const ossimFilename& shapeFile)
+{
+   if(theTree)
+   {
+      SHPDestroyTree(theTree);
+      theTree = (SHPTree*)NULL;
+   }
+   theShapeFile.open(shapeFile);
+   deleteCache();
+   deleteAll();
+   
+   if(theShapeFile.isOpen())
+   {
+      theShapeFile.getBounds(theMinArray[0],theMinArray[1],theMinArray[2],theMinArray[3],
+                             theMaxArray[0],theMaxArray[1],theMaxArray[2],theMaxArray[3]);
+
+      theTree = SHPCreateTree(theShapeFile.getHandle(),
+                              2,
+                              theMaxQuadTreeLevels,
+                              theMinArray,
+                              theMaxArray);  
+      
+      ossimShapeObject obj;
+      for(int index = 0 ; index < theShapeFile.getNumberOfShapes(); ++index)
+      {
+         obj.loadShape(theShapeFile,
+                       index);
+         
+         if(obj.isLoaded())
+         {
+            switch(obj.getType())
+            {
+               case SHPT_POLYGON:
+               case SHPT_POLYGONZ:
+               {
+                  loadPolygon(obj);
+                  break;
+               }
+               case SHPT_POINT:
+               case SHPT_POINTZ:
+               {
+                  loadPoint(obj);
+                  break;
+               }
+               case SHPT_ARC:
+               case SHPT_ARCZ:
+               {
+                  loadArc(obj);
+                  break;
+               }
+               case SHPT_NULL:
+               {
+                  break;
+               }
+               default:
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << "ossimEsriShapeFileFilter::loadShapeFile\n"
+                     << "SHAPE " << obj.getTypeByName()
+                     << " Not supported" <<  endl;
+                  break;
+               }
+            }
+         }
+      }
+      
+      theCurrentObject = theShapeCache .begin();
+      if(theViewProjection)
+      {
+         transformObjects();
+      }
+      else
+      {
+         checkAndSetDefaultView();
+      }
+   }
+   
+   return true;
+}
+
+void ossimEsriShapeFileFilter::loadPolygon(ossimShapeObject& obj)
+{
+   int starti = 0;
+   int endi   = 0;
+   if(obj.getNumberOfParts() > 1)
+   {
+      starti = obj.getShapeObject()->panPartStart[0];
+      endi   = obj.getShapeObject()->panPartStart[1];
+   }
+   else
+   {
+      starti = 0;
+      endi   = obj.getShapeObject()->nVertices;
+   }
+   
+   vector<ossimGpt> groundPolygon;
+   for(ossim_uint32 part = 0; part < obj.getNumberOfParts(); ++part)
+   {
+      if(obj.getPartType(part) != SHPP_RING)
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimEsriShapeFileFilter::loadPolygon\n"
+            << "Part = " << obj.getPartByName(part)
+            << " not supported for shape = "
+            << obj.getTypeByName() << endl;
+         break;
+      }
+      groundPolygon.clear();
+      for(ossim_int32 vertexNumber = starti; vertexNumber < endi; ++vertexNumber)
+      {
+         groundPolygon.push_back(ossimGpt(obj.getShapeObject()->padfY[vertexNumber],
+                                          obj.getShapeObject()->padfX[vertexNumber]));
+         
+      }
+      starti = endi;   
+      if((part + 2) < obj.getNumberOfParts())
+      {  
+         endi = obj.getShapeObject()->panPartStart[part+2];
+      }
+      else
+      {
+         endi = obj.getShapeObject()->nVertices;
+      }
+      
+      ossimRgbVector color;
+      
+      if(theFillFlag)
+      {
+         color = theBrushColor;
+      }
+      else
+      {
+         color = thePenColor;
+      }
+
+      if(theBorderSize != 0.0)
+      {
+         ossimGeoPolygon tempPoly(groundPolygon);
+         ossimGeoPolygon tempPoly2;
+         
+         tempPoly.stretchOut(tempPoly2,
+                             theBorderSize);
+         groundPolygon = tempPoly2.getVertexList();
+
+      }
+      
+      ossimGeoAnnotationObject *newGeoObj = new ossimGeoAnnotationPolyObject(groundPolygon,
+                                                                             theFillFlag,
+                                                                             color.getR(),
+                                                                             color.getG(),
+                                                                             color.getB(),
+                                                                             theThickness);
+      newGeoObj->setName(theFeatureName);
+      theShapeCache.insert(make_pair(obj.getId(),
+                                     newGeoObj));
+   }
+}
+
+void ossimEsriShapeFileFilter::loadPoint(ossimShapeObject& obj)
+{
+   int n   = obj.getNumberOfVertices();
+
+   if(n)
+   {
+      ossimGpt gpt(obj.getShapeObject()->padfY[0],
+                   obj.getShapeObject()->padfX[0]);
+      
+      ossimRgbVector color;
+      
+      if(theFillFlag)
+      {
+         color = theBrushColor;
+      }
+      else
+      {
+         color = thePenColor;
+      }
+      ossimGeoAnnotationEllipseObject *newGeoObj =
+         new ossimGeoAnnotationEllipseObject(gpt,
+                                             thePointWidthHeight,
+                                             theFillFlag,
+                                             color.getR(),
+                                             color.getG(),
+                                             color.getB(),
+                                             theThickness);
+      newGeoObj->setEllipseWidthHeightUnitType(OSSIM_PIXEL);
+      newGeoObj->setName(theFeatureName);
+      theShapeCache.insert(make_pair(obj.getId(),
+                                     newGeoObj));
+
+   }
+}
+
+void ossimEsriShapeFileFilter::loadArc(ossimShapeObject& obj)
+{
+   int starti = 0;
+   int endi   = 0;
+   if(obj.getNumberOfParts() > 1)
+   {
+      starti = obj.getShapeObject()->panPartStart[0];
+      endi   = obj.getShapeObject()->panPartStart[1];
+   }
+   else
+   {
+      starti = 0;
+      endi   = obj.getShapeObject()->nVertices;
+   }
+   
+   vector<ossimGpt> groundPolygon;
+   for(ossim_uint32 part = 0; part < obj.getNumberOfParts(); ++part)
+   {
+      if(obj.getPartType(part) != SHPP_RING)
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimEsriShapeFileFilter::loadArc\n"
+            << "Part = " << obj.getPartByName(part)
+            << " not supported for shape = "
+            << obj.getTypeByName() << endl;
+         break;
+      }
+      groundPolygon.clear();
+      for(ossim_int32 vertexNumber = starti; vertexNumber < endi; ++vertexNumber)
+      {
+         groundPolygon.push_back(ossimGpt(obj.getShapeObject()->padfY[vertexNumber],
+                                          obj.getShapeObject()->padfX[vertexNumber]));
+         
+      }
+      starti = endi;   
+      if((part + 2) < obj.getNumberOfParts())
+      {  
+         endi = obj.getShapeObject()->panPartStart[part+2];
+      }
+      else
+      {
+         endi = obj.getShapeObject()->nVertices;
+      }
+      
+      ossimRgbVector color;
+      
+      if(theFillFlag)
+      {
+         color = theBrushColor;
+      }
+      else
+      {
+         color = thePenColor;
+      }
+      
+      ossimGeoAnnotationObject *newGeoObj = new ossimGeoAnnotationPolyLineObject(groundPolygon,
+                                                                                 color.getR(),
+                                                                                 color.getG(),
+                                                                                 color.getB(),
+                                                                                 theThickness);
+      newGeoObj->setName(theFeatureName);
+      theShapeCache.insert(make_pair(obj.getId(),
+                                     newGeoObj));
+   }
+}
+
+bool ossimEsriShapeFileFilter::saveState(ossimKeywordlist& kwl,
+                                         const char* prefix)const
+{
+   ossimString s;
+   
+   kwl.add(prefix,
+           ossimKeywordNames::FILENAME_KW,
+           theShapeFile.getFilename(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::MAX_QUADTREE_LEVELS_KW,
+           theMaxQuadTreeLevels,
+           true);
+
+   s = ossimString::toString((int)thePenColor.getR()) + " " +
+       ossimString::toString((int)thePenColor.getG()) + " " +
+       ossimString::toString((int)thePenColor.getB());
+   
+   kwl.add(prefix,
+           ossimKeywordNames::PEN_COLOR_KW,
+           s.c_str(),
+           true);
+
+   s = ossimString::toString((int)theBrushColor.getR()) + " " +
+       ossimString::toString((int)theBrushColor.getG()) + " " +
+       ossimString::toString((int)theBrushColor.getB());
+   
+   kwl.add(prefix,
+           ossimKeywordNames::BRUSH_COLOR_KW,
+           s.c_str(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FILL_FLAG_KW,
+           (int)theFillFlag,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FEATURE_NAME_KW,
+           theFeatureName.c_str(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::THICKNESS_KW,
+           theThickness,
+           true);
+
+   ossimString border;
+   border = ossimString::toString(theBorderSize);
+   border += " degrees";
+   kwl.add(prefix,
+           ossimKeywordNames::BORDER_SIZE_KW,
+           border,
+           true);
+   
+   s = ossimString::toString((int)thePointWidthHeight.x) + " " +
+       ossimString::toString((int)thePointWidthHeight.y) + " ";
+   
+   kwl.add(prefix,
+           ossimKeywordNames::POINT_WIDTH_HEIGHT_KW,
+           s.c_str(),
+           true);
+   
+   if(theViewProjection)
+   {
+      ossimString newPrefix = prefix;
+      newPrefix += "view_proj.";
+      theViewProjection->saveState(kwl,
+                                   newPrefix.c_str());
+   }
+   
+   return ossimAnnotationSource::saveState(kwl, prefix);
+}
+
+bool ossimEsriShapeFileFilter::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   
+   const char* quadLevels  = kwl.find(prefix, ossimKeywordNames::MAX_QUADTREE_LEVELS_KW);
+   const char* filename    = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   const char* penColor    = kwl.find(prefix, ossimKeywordNames::PEN_COLOR_KW);
+   const char* brushColor  = kwl.find(prefix, ossimKeywordNames::BRUSH_COLOR_KW);
+   const char* featureName = kwl.find(prefix, ossimKeywordNames::FEATURE_NAME_KW);
+   const char* fillFlag    = kwl.find(prefix, ossimKeywordNames::FILL_FLAG_KW);
+   const char* thickness   = kwl.find(prefix, ossimKeywordNames::THICKNESS_KW);
+   const char* pointWh     = kwl.find(prefix, ossimKeywordNames::POINT_WIDTH_HEIGHT_KW);
+   const char* border_size = kwl.find(prefix, ossimKeywordNames::BORDER_SIZE_KW);
+   
+   deleteCache();
+
+   if(thickness)
+   {
+      theThickness = ossimString(thickness).toLong();
+   }
+   if(quadLevels)
+   {
+      theMaxQuadTreeLevels = ossimString(quadLevels).toLong();
+   }
+   
+   if(penColor)
+   {
+      int r, g, b;
+      istringstream s(penColor);
+      s>>r>>g>>b;
+      thePenColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(brushColor)
+   {
+      int r, g, b;
+      istringstream s(brushColor);
+      s>>r>>g>>b;
+      theBrushColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+   if(pointWh)
+   {
+      double w, h;
+      istringstream s(pointWh);
+      s>>w>>h;
+      thePointWidthHeight = ossimDpt(w, h);
+   }
+   
+   if(fillFlag)
+   {
+      theFillFlag = ossimString(fillFlag).toBool();
+   }
+
+   if(border_size)
+   {
+      istringstream input(border_size);
+
+      ossimString s;
+      input >> s;
+
+      theBorderSize = s.toDouble();
+      
+      ossimString s2;
+      
+      input >> s2;
+
+      s2 = s2.upcase();
+      
+      if(s2 == "US")
+      {
+         theBorderSizeUnits = OSSIM_US_SURVEY_FEET;
+      }
+      else if(s2 == "METERS")
+      {
+         theBorderSizeUnits = OSSIM_METERS;
+      }
+      else if(s2 == "FEET")
+      {
+         theBorderSizeUnits = OSSIM_FEET;
+      }
+      else
+      {
+         theBorderSizeUnits = OSSIM_DEGREES;
+      }
+      ossimUnitConversionTool unitConvert(theBorderSize,
+                                          theBorderSizeUnits);
+      
+      theBorderSize      = unitConvert.getValue(OSSIM_DEGREES);
+      theBorderSizeUnits = OSSIM_DEGREES;
+   }
+   else
+   {
+      theBorderSize      = 0.0;
+      theBorderSizeUnits = OSSIM_DEGREES;
+   }
+   
+   theFeatureName = featureName;
+   
+   removeViewProjection();
+   
+   ossimString newPrefix = prefix;
+   newPrefix += "view_proj.";
+   
+   theViewProjection = ossimProjectionFactoryRegistry::instance()->createProjection(kwl,
+                                                                                    newPrefix.c_str());
+   theOwnsViewProjectionFlag = true;
+   
+   if(filename)
+   {
+      loadShapeFile(ossimFilename(filename));
+   }
+   
+   checkAndSetDefaultView();
+
+   
+   return ossimAnnotationSource::loadState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimEsriShapeFileFilter.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimEsriShapeFileFilter.h
new file mode 100644
index 0000000000..13a28e837c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimEsriShapeFileFilter.h
@@ -0,0 +1,270 @@
+//*******************************************************************
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimEsriShapeFileFilter.h,v 1.26 2005/05/23 15:40:28 gpotts Exp $
+
+#ifndef ossimEsriShapeFileFilter_HEADER
+#define ossimEsriShapeFileFilter_HEADER
+#include <map>
+#include <imaging/annotation/ossimGeoAnnotationSource.h>
+#include <base/common/ossimViewInterface.h>
+#include <vec/shape/shapefil.h>
+#include <vec/shape/ossimShapeFile.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+
+class ossimGeoAnnotationObject;
+class ossimAnnotationObject;
+
+/*!
+ * class ossimEsriShapeFileFilter
+ *
+ * This class is used to render shape files.  Iif this filter has
+ * an input connection to an ossimImageSourceInterface then it will
+ * draw any vectors over the input tile.  If it is not connected
+ * it will just render its vector data to a tile and return it.
+ * <pre>
+ * supported keywords:
+ *
+ *   max_quadtree_levels:    // number of levels for faster hit testing
+ *                           // defaults to 10
+ *
+ *   fill_flag:              // 1 for true 0 for false.  Default is false
+ *                           // and specifies how all closed surfaces are
+ *                           // to be drawn
+ *
+ *   feature_name:           // currently not used.
+ *
+ *   pen_color:              // specified in Red Green Blue and is the color used
+ *                           // if the fill flag is not specified.  Future changes
+ *                           // might be to include this as an outline color for
+ *                           // filled objects.  Default is white. Example: 255 255 255
+ *
+ *   brush_color:            // Color used by objects that have the fill flag enabled
+ *                           // format is Red Green Blue. Default is white.
+ *
+ *   line_thickness:         // line drawing thickness in pixels.
+ *
+ *   border_size:            // can be us feet, feet, meters, degrees,
+ *                           // will automatically expand all polygons by the
+ *                           // specified size.  Uses the centroid to estimate
+ *                           // non degree units when converting to degrees.
+ *
+ *   point_width_height:     // Specifies the width and height of a point object in
+ *                           // pixels.  Default is 1 and has the following format
+ *                           // w h.  Example 1 1
+ *
+ *   filename:               // The esri shape file to be used
+ *
+ * example Keyword list:  See ossimAnnotationSource for any additional keywords
+ *
+ *
+ * brush_color:  255 255 255
+ * feature_name:
+ * filename:
+ * fill_flag:  0
+ * max_quadtree_levels:  10
+ * pen_color:  255 255 255
+ * point_width_height:  1 1
+ * thickness:  1
+ * border_size: 25 meters
+ * type:  ossimEsriShapeFileFilter
+ *
+ * </pre>
+ */
+class ossimEsriShapeFileFilter : public ossimAnnotationSource,
+                                 public ossimViewInterface
+{
+public:
+   ossimEsriShapeFileFilter(ossimImageSource* inputSource=NULL);
+   ~ossimEsriShapeFileFilter();
+
+   virtual bool setView(ossimObject* baseObject,
+                        bool ownsTheView = false);
+
+   virtual ossimObject*       getView();
+   virtual const ossimObject* getView()const;
+
+   virtual bool addObject(ossimAnnotationObject* anObject);
+   virtual void transformObjects(ossimProjection* projection=0);
+   virtual void setProjection(ossimProjection* projection,
+                              bool ownsProjectionFlag=false);
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix = 0);
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+   virtual void computeBoundingRect();
+
+   virtual void drawAnnotations(ossimRefPtr<ossimImageData> tile);
+   /*!
+    * Will delete the current objects within the layer and add all
+    * objects in the passed in file.
+    */
+   virtual bool loadShapeFile(const ossimFilename& shapeFile);
+
+   virtual ossimFilename getFilename()const
+      {
+         return theShapeFile.getFilename();
+      }
+   virtual ossim_int32 getMaxQuadTreeLevels()const
+      {
+         return theMaxQuadTreeLevels;
+      }
+
+   virtual void setMaxQuadTreeLevels(ossim_int32 levels)
+      {
+         theMaxQuadTreeLevels = (levels>0?levels:10);
+      }
+
+   virtual void setBrushColor(const ossimRgbVector& brushColor)
+      {
+         theBrushColor = brushColor;
+      }
+
+   virtual void setPenColor(const ossimRgbVector& penColor)
+      {
+         thePenColor = penColor;
+      }
+
+   virtual ossimRgbVector getPenColor()const
+      {
+         return thePenColor;
+      }
+
+   virtual ossimRgbVector getBrushColor()const
+      {
+         return theBrushColor;
+      }
+
+   virtual bool getFillFlag()const
+      {
+         return theFillFlag;
+      }
+
+   virtual void setFillFlag(bool flag)
+      {
+         theFillFlag=flag;
+      }
+   virtual ossimString getFeatureName()const
+      {
+         return theFeatureName;
+      }
+   virtual void setFeatureName(const ossimString& name)
+      {
+         theFeatureName = name;
+      }
+
+   virtual void setThickness(ossim_int32 thickness)
+      {
+         theThickness = thickness >= 0? thickness:1;
+      }
+   virtual ossim_int32 getThickness()const
+      {
+         return theThickness;
+      }
+   virtual void setPointRadius(double r)
+      {
+         thePointWidthHeight = ossimDpt(fabs(r)*2, fabs(r)*2);
+      }
+   virtual double getPointRadius()const
+      {
+         return thePointWidthHeight.x/2.0;
+      }
+
+   virtual ossimAnnotationObject* nextObject(bool restart=false)
+      {
+         if(restart)
+         {
+            theCurrentObject = theShapeCache.begin();
+         }
+         else
+         {
+            if(theCurrentObject != theShapeCache.end())
+            {
+               ++theCurrentObject;
+            }
+
+         }
+
+         if(theCurrentObject == theShapeCache.end())
+         {
+            return (ossimAnnotationObject*)NULL;
+         }
+         return (*theCurrentObject).second;
+      }
+
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+protected:
+
+   /*!
+    *  This holds the output projection.  This is used to transform
+    * the objects to the projection plane.
+    */
+   ossimProjection* theViewProjection;
+
+   /*!
+    * If the shape file is projected we must know the projector.
+    * This will allow us to define the geographic objects correctly.
+    */
+   ossimProjection* theShapeFileProjection;
+
+   /*!
+    * Flag that indicates if we own the view projection.
+    */
+   bool             theOwnsViewProjectionFlag;
+
+   /*!
+    * Specifies if its image/pixel space, Geographic, projected ...etc.
+    */
+   ossimCoordinateSystemType theCoordinateSystem;
+
+   /*!
+    * If its projected this spceifies the type of unit.  We
+    * need to know if the projection is in meters, feet, us survey feet
+    * ... etc.
+    */
+   ossimUnitType             theUnitType;
+
+   SHPTree*                  theTree;
+
+   ossimShapeFile            theShapeFile;
+
+   double                    theMinArray[4];
+   double                    theMaxArray[4];
+
+   int                       theMaxQuadTreeLevels;
+   ossimRgbVector            thePenColor;
+   ossimRgbVector            theBrushColor;
+   bool                      theFillFlag;
+   ossim_int32               theThickness;
+   ossimString               theFeatureName;
+   ossimDpt                  thePointWidthHeight;
+   double                    theBorderSize;
+   ossimUnitType             theBorderSizeUnits;
+
+   mutable std::multimap<int, ossimAnnotationObject*>::iterator theCurrentObject;
+
+   std::multimap<int, ossimAnnotationObject*> theShapeCache;
+   ossimDrect theBoundingRect;
+
+   void removeViewProjection();
+   void deleteCache();
+   void checkAndSetDefaultView();
+
+   virtual void loadPolygon(ossimShapeObject& obj);
+   virtual void loadPoint(ossimShapeObject& obj);
+   virtual void loadArc(ossimShapeObject& obj);
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGdFont.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGdFont.h
new file mode 100644
index 0000000000..5a6b4cc024
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGdFont.h
@@ -0,0 +1,54 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGdFont.h,v 1.1 2001/06/05 19:11:52 gpotts Exp $
+#ifndef ossimGdFont_HEADER
+#define ossimGdFont_HEADER
+/* gd.h: declarations file for the graphic-draw module.
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  This software is provided "AS IS." Thomas Boutell and
+ * Boutell.Com, Inc. disclaim all warranties, either express or implied, 
+ * including but not limited to implied warranties of merchantability and 
+ * fitness for a particular purpose, with respect to this code and accompanying
+ * documentation. */
+
+typedef struct {
+	/* # of characters in font */
+	int nchars;
+	/* First character is numbered... (usually 32 = space) */
+	int offset;
+	/* Character width and height */
+	int w;
+	int h;
+	/* Font data; array of characters, one row after another.
+		Easily included in code, also easily loaded from
+		data files. */
+	char *data;
+} ossimGdFont;
+
+/* Text functions take these. */
+typedef ossimGdFont *ossimGdFontPtr;
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGdFontExterns.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGdFontExterns.h
new file mode 100644
index 0000000000..a8fb1d75dd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGdFontExterns.h
@@ -0,0 +1,33 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGdFontExterns.h,v 1.1 2001/06/05 19:11:52 gpotts Exp $
+#ifndef ossimGdFontExterns_HEADER
+#define ossimGdFontExterns_HEADER
+#include "ossimGdFont.h"
+extern ossimGdFontPtr ossimGdFontGiant;
+extern ossimGdFontPtr ossimGdFontTiny;
+extern ossimGdFontPtr ossimGdFontSmall;
+extern ossimGdFontPtr ossimGdFontLarge;
+extern ossimGdFontPtr ossimGdFontMediumBold;
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationBitmap.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationBitmap.cpp
new file mode 100644
index 0000000000..e242232347
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationBitmap.cpp
@@ -0,0 +1,168 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationBitmap.cpp,v 1.8 2005/02/18 15:27:41 dburken Exp $
+
+#include <imaging/annotation/ossimGeoAnnotationBitmap.h>
+#include <projections/ossimProjection.h>
+#include <base/data_types/ossimIrect.h>
+
+RTTI_DEF1(ossimGeoAnnotationBitmap,
+          "ossimGeoAnnotationBitmap",
+          ossimGeoAnnotationObject)
+   
+ossimGeoAnnotationBitmap::ossimGeoAnnotationBitmap(
+   const ossimGpt& center,
+   ossimRefPtr<ossimImageData> imageData,
+   unsigned char r,
+   unsigned char g,
+   unsigned char b)
+   :ossimGeoAnnotationObject(r, g, b),
+    theCenterPoint(center),
+    theProjectedPoint(0,0),
+    theImageData(NULL)
+{
+   if(imageData.valid() &&
+      (imageData->getScalarType()==OSSIM_UCHAR))
+   {
+      theImageData = imageData;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimGeoAnnotationBitmap::ossimGeoAnnotationBitmap\n"
+         << "Invalid image data passed to ossimGeoAnnotationBitmap "
+         << "constructor" << endl;
+   }
+}
+
+ossimGeoAnnotationBitmap::ossimGeoAnnotationBitmap(
+   const ossimGeoAnnotationBitmap& rhs)
+   :
+   ossimGeoAnnotationObject(rhs),
+   theCenterPoint(theCenterPoint),
+   theProjectedPoint(theProjectedPoint),
+   theImageData(rhs.theImageData)
+{
+}
+
+ossimGeoAnnotationBitmap::~ossimGeoAnnotationBitmap()
+{
+}
+   
+std::ostream& ossimGeoAnnotationBitmap::print(std::ostream& out)const
+{
+   out << "center:    " << theCenterPoint << endl;
+   return out;
+}
+
+void ossimGeoAnnotationBitmap::draw(ossimRgbImage& anImage)const
+{
+   ossimRefPtr<ossimImageData> destination = anImage.getImageData();
+
+   if(!destination)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimGeoAnnotationBitmap::draw\n"
+         << "ERROR: can't draw annotation bitmap to NULL buffer" << endl;
+      
+      return;
+   }
+   ossimIrect destinationRect = destination->getImageRectangle();
+   ossimIrect srcRect         = theImageData->getImageRectangle();
+   if(!srcRect.intersects(destinationRect))
+   {
+      return;
+   }
+   ossimIrect clipRect        = srcRect.clipToRect(destinationRect);
+   
+   long clipHeight = (long)clipRect.height();
+   long clipWidth  = (long)clipRect.width();
+
+
+   if(clipRect.width() != 1.0 &&
+      clipRect.height() != 1.0)
+   {         
+      long destinationOffset   = (long)(((clipRect.ul().y - destinationRect.ul().y)* destinationRect.width()) +
+                                        (clipRect.ul().x - destinationRect.ul().x));
+      long srcOffset   = (long)(((clipRect.ul().y - srcRect.ul().y)*srcRect.width()) +
+                         (clipRect.ul().x - srcRect.ul().x));
+      long destinationIndex = destinationOffset;
+      long srcIndex         = srcOffset;
+      long num_bands        = destination->getNumberOfBands();
+      ossim_int32 s_width = (ossim_int32)srcRect.width();
+      ossim_int32 d_width = (ossim_int32)destinationRect.width();
+      
+      num_bands = num_bands > 3? 3:num_bands;
+      
+      const ossim_uint8* imageDataBuf = static_cast<const ossim_uint8*>(theImageData->getBuf());
+      unsigned char colorArray[3];
+      colorArray[0] = theRed;
+      colorArray[1] = theGreen;
+      colorArray[2] = theBlue;
+      for (long band=0; band<num_bands; ++band)
+      {
+         ossim_uint8* destinationBand = static_cast<ossim_uint8*>(destination->getBuf(band));
+         destinationIndex       = destinationOffset;
+         srcIndex               = srcOffset;
+         for(long line = 0; line < clipHeight; ++line)
+         {
+            for(long col = 0; col < clipWidth; ++col)
+            {
+               if(imageDataBuf[srcIndex + col])
+               {
+                  destinationBand[destinationIndex + col] = colorArray[band];
+               }
+            }
+            srcIndex += s_width;
+            destinationIndex += d_width;
+         }
+      } 
+   }
+}
+
+void ossimGeoAnnotationBitmap::getBoundingRect(ossimDrect& rect)const
+{
+   rect = ossimDrect(0,0,0,0);
+
+   if(theImageData.valid())
+   {
+      rect = theImageData->getImageRectangle();
+   }
+}
+
+void ossimGeoAnnotationBitmap::transform(ossimProjection* projection)
+{
+   if(projection)
+   {
+      projection->worldToLineSample(theCenterPoint,
+                                    theProjectedPoint);
+      theProjectedPoint = ossimIpt(theProjectedPoint);
+      if(theImageData.valid())
+      {
+         ossimDpt origin(theProjectedPoint.x - theImageData->getWidth()/2.0,
+                         theProjectedPoint.y - theImageData->getHeight()/2.0);
+         
+         theImageData->setOrigin(origin);
+      }
+   }
+}
+
+void ossimGeoAnnotationBitmap::setImageData(
+   ossimRefPtr<ossimImageData>& imageData)
+{
+   theImageData = imageData;
+}
+
+void ossimGeoAnnotationBitmap::computeBoundingRect()
+{
+   // nothing to be done since we don't support
+   // rotated bitmaps yet.
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationBitmap.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationBitmap.h
new file mode 100644
index 0000000000..01efcde127
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationBitmap.h
@@ -0,0 +1,71 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationBitmap.h,v 1.10 2005/02/18 15:27:41 dburken Exp $
+#ifndef ossimGeoAnnotationBitmap_HEADER
+#define ossimGeoAnnotationBitmap_HEADER
+#include <imaging/annotation/ossimGeoAnnotationObject.h>
+
+class OSSIMDLLEXPORT ossimGeoAnnotationBitmap: public ossimGeoAnnotationObject
+{
+public:
+
+   ossimGeoAnnotationBitmap(const ossimGpt& center= ossimGpt(0,0,0),
+                            ossimRefPtr<ossimImageData> imageData=NULL,
+                            unsigned char r = 255,
+                            unsigned char g = 255,
+                            unsigned char b = 255);
+   
+   ossimGeoAnnotationBitmap(const ossimGeoAnnotationBitmap& rhs);
+
+   virtual ~ossimGeoAnnotationBitmap();
+   
+   virtual ossimObject* dup()const
+      {
+         return new ossimGeoAnnotationBitmap(*this);
+      }
+   virtual bool intersects(const ossimDrect& rect) const
+      {
+         if(theImageData.valid())
+         {
+            return theImageData->getImageRectangle().intersects(rect);
+         }
+
+         return false;
+      }
+   virtual ossimGeoAnnotationBitmap* getNewClippedObject(const ossimDrect& rect)const
+      {
+         ossimGeoAnnotationBitmap* result = (ossimGeoAnnotationBitmap*)dup();
+
+         ossimNotify(ossimNotifyLevel_WARN) << "ossimGeoAnnotationBitmap::getNewClippedObject WRNING: not implemented" << std::endl;
+         
+         return result;
+      }
+   virtual void applyScale(double x,
+                           double y)
+      {
+         
+      }
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void transform(ossimProjection* projection);
+   virtual void setImageData(ossimRefPtr<ossimImageData>& imageData);
+   virtual void computeBoundingRect();
+
+protected:
+   ossimGpt                    theCenterPoint;
+   ossimDpt                    theProjectedPoint;
+   ossimRefPtr<ossimImageData> theImageData;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationEllipseObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationEllipseObject.cpp
new file mode 100644
index 0000000000..3203d98057
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationEllipseObject.cpp
@@ -0,0 +1,307 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationEllipseObject.cpp,v 1.16 2005/12/16 14:28:27 dburken Exp $
+
+#include <sstream>
+
+#include <imaging/annotation/ossimGeoAnnotationEllipseObject.h>
+#include <imaging/annotation/ossimAnnotationEllipseObject.h>
+#include <projections/ossimProjection.h>
+#include <base/misc/lookup_tables/ossimUnitTypeLut.h>
+#include <base/misc/ossimUnitConversionTool.h>
+
+RTTI_DEF1(ossimGeoAnnotationEllipseObject,
+          "ossimGeoAnnotationEllipseObject",
+          ossimGeoAnnotationObject);
+   
+ossimGeoAnnotationEllipseObject::ossimGeoAnnotationEllipseObject(
+   const ossimGpt& center,
+   const ossimDpt& widthHeight,
+   bool enableFill,
+   ossim_uint8 r,
+   ossim_uint8 g,
+   ossim_uint8 b,
+   ossim_uint8 thickness)
+   :ossimGeoAnnotationObject(r, g, b, thickness),
+    theProjectedEllipse(NULL),
+    theCenter(center),
+    theWidthHeight(widthHeight),
+    theEllipseWidthHeightUnitType(OSSIM_PIXEL) // default to image space
+{
+   theProjectedEllipse = new ossimAnnotationEllipseObject(ossimDpt(0,0),
+							  ossimDpt(0,0),
+							  enableFill,
+							  r,
+							  g,
+							  b,
+							  thickness);
+}
+
+ossimGeoAnnotationEllipseObject::ossimGeoAnnotationEllipseObject(
+   const ossimGeoAnnotationEllipseObject& rhs)
+   :ossimGeoAnnotationObject(rhs),
+    theProjectedEllipse(rhs.theProjectedEllipse?(ossimAnnotationEllipseObject*)rhs.theProjectedEllipse->dup():(ossimAnnotationEllipseObject*)NULL),
+    theCenter(rhs.theCenter),
+    theWidthHeight(rhs.theWidthHeight),
+    theEllipseWidthHeightUnitType(rhs.theEllipseWidthHeightUnitType)
+{
+}
+
+ossimGeoAnnotationEllipseObject::~ossimGeoAnnotationEllipseObject()
+{
+   if(theProjectedEllipse)
+   {
+      delete theProjectedEllipse;
+      theProjectedEllipse = NULL;
+   }
+}
+
+ossimObject* ossimGeoAnnotationEllipseObject::dup()const
+{
+   return new ossimGeoAnnotationEllipseObject(*this);
+}
+
+void ossimGeoAnnotationEllipseObject::applyScale(double x,
+                                                 double y)
+{
+   if(theProjectedEllipse) theProjectedEllipse->applyScale(x, y);
+   theCenter.lond(theCenter.lond()*x);
+   theCenter.latd(theCenter.latd()*y);
+   theWidthHeight .x *= x;
+   theWidthHeight .y *= y;
+}
+
+std::ostream& ossimGeoAnnotationEllipseObject::print(std::ostream& out)const
+{
+   out << "center ground:                  " <<  theCenter << endl
+       << "width height image space flag = " << theEllipseWidthHeightUnitType
+       << endl
+       << *theProjectedEllipse;
+   return out;
+}
+
+void ossimGeoAnnotationEllipseObject::draw(ossimRgbImage& anImage)const
+{
+   if(theProjectedEllipse)
+   {
+      theProjectedEllipse->draw(anImage);
+   }
+}
+
+bool ossimGeoAnnotationEllipseObject::intersects(const ossimDrect& rect)const
+{
+   if(theProjectedEllipse)
+   {
+      theProjectedEllipse->intersects(rect);
+   }
+
+   return false;
+}
+
+ossimAnnotationObject* ossimGeoAnnotationEllipseObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   if(intersects(rect))
+   {
+      if(theProjectedEllipse)
+      {
+         return theProjectedEllipse->getNewClippedObject(rect);
+      }
+   }
+   
+   return (ossimAnnotationObject*)NULL;
+}
+
+void ossimGeoAnnotationEllipseObject::getBoundingRect(ossimDrect& rect)const
+{
+   if(theProjectedEllipse)
+   {
+      theProjectedEllipse->getBoundingRect(rect);
+   }
+   else
+   {
+      rect.makeNan();
+   }
+}
+
+void ossimGeoAnnotationEllipseObject::computeBoundingRect()
+{
+   if(theProjectedEllipse)
+   {
+      theProjectedEllipse->computeBoundingRect();
+   }
+}
+
+void ossimGeoAnnotationEllipseObject::transform(ossimProjection* projection)
+{
+   if(!projection)
+   {
+      return;
+   }
+
+   // Ellipse center, height and width in image space.
+   ossimDpt projectedCenter;
+   ossimDpt projectedWidthHeight;
+
+   // first get the center projected
+   projection->worldToLineSample(theCenter, projectedCenter);
+
+   getWidthHeightInPixels(projectedWidthHeight, projection);
+
+   theProjectedEllipse->setCenterWidthHeight(projectedCenter,
+                                             projectedWidthHeight);      
+}
+
+bool ossimGeoAnnotationEllipseObject::saveState(ossimKeywordlist& kwl,
+                                                const char* prefix) const
+{
+   ossimUnitTypeLut ul;
+
+   kwl.add(prefix, "center", theCenter.toString().c_str());
+   kwl.add(prefix, "ellipse_width", theWidthHeight.x);
+   kwl.add(prefix, "ellipse_height", theWidthHeight.y);
+   kwl.add(prefix, "fill", (ossim_int32)theProjectedEllipse->getFill());
+   kwl.add(prefix, "units",
+           ul.getEntryString(theEllipseWidthHeightUnitType).c_str());
+   
+   return ossimGeoAnnotationObject::saveState(kwl, prefix);
+}
+
+bool ossimGeoAnnotationEllipseObject::loadState(const ossimKeywordlist& kwl,
+                                                const char* prefix)
+{
+   if (!theProjectedEllipse)
+   {
+      return false;
+   }
+   
+   //---
+   // Base class state must be called first to pick up colors...
+   //---
+   bool status =  ossimGeoAnnotationObject::loadState(kwl, prefix);
+   if (status == true)
+   {
+      theProjectedEllipse->setColor(theRed, theGreen, theBlue);
+      theProjectedEllipse->setThickness(theThickness);
+   }
+
+   const char* center         = kwl.find(prefix, "center");
+   const char* ellipse_width  = kwl.find(prefix, "ellipse_width");
+   const char* ellipse_height = kwl.find(prefix, "ellipse_height");
+   const char* fill           = kwl.find(prefix, "fill");
+   const char* units          = kwl.find(prefix, "units");
+   
+   if(units)
+   {
+      ossimUnitTypeLut ul;
+      theEllipseWidthHeightUnitType =
+         static_cast<ossimUnitType>(ul.getEntryNumber(units));
+      if (theEllipseWidthHeightUnitType == OSSIM_UNIT_UNKNOWN)
+      {
+         theEllipseWidthHeightUnitType = OSSIM_PIXEL;
+      }
+   }
+
+   if (center)
+   {
+      std::istringstream is(center);
+      is >> theCenter;
+   }
+   if(ellipse_width)
+   {
+      theWidthHeight.x = ossimString(ellipse_width).toDouble();
+   }
+   if(ellipse_height)
+   {
+      theWidthHeight.y = ossimString(ellipse_height).toDouble();
+   }
+   if(fill)
+   {
+      if(ossimString(fill).toLong())
+      {
+         theProjectedEllipse->setFill(true);
+      }
+      else
+      {
+         theProjectedEllipse->setFill(false);
+      }
+   }
+
+   return status;
+}
+
+void ossimGeoAnnotationEllipseObject::setEllipseWidthHeightUnitType(
+   ossimUnitType type)
+{
+   theEllipseWidthHeightUnitType = type;
+}
+
+void ossimGeoAnnotationEllipseObject::getWidthHeightInPixels(
+   ossimDpt& widthHeight, const ossimProjection* projection) const
+{
+   switch (theEllipseWidthHeightUnitType)
+   {
+      case OSSIM_PIXEL:
+      {
+         widthHeight = theWidthHeight;
+
+         break;
+      }
+      
+      case OSSIM_DEGREES:
+      case OSSIM_MINUTES:
+      case OSSIM_SECONDS:
+      {
+         ossimGpt origin = projection->origin();
+         ossimDpt gsd = projection->getMetersPerPixel();
+         
+         ossimUnitConversionTool uct(origin,
+                                     theWidthHeight.x,
+                                     theEllipseWidthHeightUnitType);
+
+         double x = uct.getValue(OSSIM_METERS);
+
+         uct.setValue(theWidthHeight.y, theEllipseWidthHeightUnitType);
+         
+         double y = uct.getValue(OSSIM_METERS);
+
+         widthHeight.x = ceil(x/gsd.x);
+         widthHeight.y = ceil(y/gsd.y);
+         
+         break;
+      }
+
+      case OSSIM_METERS:
+      {
+         ossimDpt gsd = projection->getMetersPerPixel();
+         widthHeight.x = static_cast<ossim_int32>(theWidthHeight.x/gsd.x+0.5);
+         widthHeight.y = static_cast<ossim_int32>(theWidthHeight.y/gsd.y+0.5);
+
+         break;
+      }
+
+      default:
+      {
+         ossimDpt gsd = projection->getMetersPerPixel();
+         
+         ossimUnitConversionTool uct(theWidthHeight.x,
+                                     theEllipseWidthHeightUnitType);
+
+         double x = uct.getValue(OSSIM_METERS);
+         
+         uct.setValue(theWidthHeight.y, theEllipseWidthHeightUnitType);
+         
+         double y = uct.getValue(OSSIM_METERS);
+         
+         widthHeight.x = ceil(x/gsd.x);
+         widthHeight.y = ceil(y/gsd.y);
+         
+         break;
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationEllipseObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationEllipseObject.h
new file mode 100644
index 0000000000..069ede1832
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationEllipseObject.h
@@ -0,0 +1,86 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationEllipseObject.h,v 1.12 2005/12/09 21:49:02 dburken Exp $
+#ifndef ossimGeoAnnotationEllipseObject_HEADER
+#define ossimGeoAnnotationEllipseObject_HEADER
+#include <imaging/annotation/ossimGeoAnnotationObject.h>
+
+class ossimAnnotationEllipseObject;
+
+class OSSIMDLLEXPORT ossimGeoAnnotationEllipseObject : public ossimGeoAnnotationObject
+{
+public:
+   
+   /*!
+    * It is important to note that the width and height
+    * should be specified in width = deltaLon and
+    * height = deltaLat.  Use the ossimDpt .lat and .lon
+    * attributes to set it.
+    */
+   ossimGeoAnnotationEllipseObject(const ossimGpt& center = ossimGpt(0,0),
+                                   const ossimDpt& widthHeight = ossimDpt(0,0),
+                                   bool enableFill = false,
+                                   ossim_uint8 r = 255,
+                                   ossim_uint8 g = 255,
+                                   ossim_uint8 b = 255,
+                                   ossim_uint8 thickness = 1);
+   ossimGeoAnnotationEllipseObject(const ossimGeoAnnotationEllipseObject& rhs);
+   virtual ~ossimGeoAnnotationEllipseObject();
+
+   virtual ossimObject* dup()const;
+
+   virtual void applyScale(double x, double y);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void computeBoundingRect();
+   virtual void transform(ossimProjection* projection);
+
+   /**
+    * Saves the current state of this object.
+    *
+    * Keywords:
+    *
+    * center:  ( 42.403388263727003, -90.708557648541046, 0.0, WGE )
+    *
+    * ellipse_width: 500
+    *
+    * ellipse_height: 500
+    *
+    * units: meters
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual void setEllipseWidthHeightUnitType(ossimUnitType type);
+
+protected:
+
+   void getWidthHeightInPixels(ossimDpt& widthHeight,
+                               const ossimProjection* projection) const;
+   
+   ossimAnnotationEllipseObject* theProjectedEllipse;
+   ossimGpt                      theCenter;
+   ossimDpt                      theWidthHeight;
+
+   ossimUnitType                 theEllipseWidthHeightUnitType;
+   
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationFontObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationFontObject.cpp
new file mode 100644
index 0000000000..367e20dae4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationFontObject.cpp
@@ -0,0 +1,290 @@
+//*************************************************************************
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+//$Id: ossimGeoAnnotationFontObject.cpp,v 1.7 2005/12/16 14:28:27 dburken Exp $
+
+#include <sstream>
+
+#include <imaging/annotation/ossimGeoAnnotationFontObject.h>
+#include <imaging/annotation/ossimAnnotationFontObject.h>
+#include <projections/ossimProjection.h>
+#include <fonts/ossimFont.h>
+#include <fonts/factory/ossimFontFactoryRegistry.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimGeoAnnotationFontObject,
+          "ossimGeoAnnotationFontObject",
+          ossimGeoAnnotationObject);
+
+
+ossimGeoAnnotationFontObject::ossimGeoAnnotationFontObject()
+   :
+   ossimGeoAnnotationObject(),
+   theCenterGround(),
+   theFont(NULL),
+   theFontInfo(),
+   theAnnotationFontObject(NULL)
+{
+   theFont = (ossimFont*)ossimFontFactoryRegistry::instance()->
+      getDefaultFont()->dup();
+   if (!theFont)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimGeoAnnotationFontObject::ossimGeoAnnotationFontObject"
+         << " WARNING: No font support..."
+         << endl;
+   }
+   theAnnotationFontObject =
+      new ossimAnnotationFontObject(ossimIpt(0,0),
+                                    ossimString(""));
+   
+   theAnnotationFontObject->setFont(theFont, false);
+   
+}
+
+ossimGeoAnnotationFontObject::ossimGeoAnnotationFontObject(
+   const ossimGpt& location,
+   const ossimString& s,
+   const ossimIpt& pixelSize,
+   double rotation,
+   const ossimDpt& scale,
+   const ossimDpt& shear,
+   ossim_uint8 r,
+   ossim_uint8 g,
+   ossim_uint8 b)
+   :
+   ossimGeoAnnotationObject(r, g, b),
+   theCenterGround(location),
+   theFont(NULL),
+   theFontInfo(),
+   theAnnotationFontObject(NULL)
+{
+  ossimDpt pt;
+  pt.makeNan();
+
+  theAnnotationFontObject = new ossimAnnotationFontObject(pt,
+							  s,
+							  pixelSize,
+							  rotation,
+							  scale,
+							  shear,
+							  r,
+							  g,
+							  b);
+}
+
+ossimGeoAnnotationFontObject::ossimGeoAnnotationFontObject(
+   const ossimGeoAnnotationFontObject& rhs)
+   :
+   ossimGeoAnnotationObject(rhs),
+   theCenterGround(rhs.theCenterGround),
+   theFont(rhs.theFont?(ossimFont*)rhs.theFont->dup():(ossimFont*)NULL),
+   theFontInfo(),
+   theAnnotationFontObject(
+      new ossimAnnotationFontObject(
+         ossimDpt(OSSIM_DBL_NAN, OSSIM_DBL_NAN),
+         rhs.theAnnotationFontObject->theString,
+         rhs.theAnnotationFontObject->thePixelSize,
+         rhs.theAnnotationFontObject->theRotation,
+         ossimDpt(rhs.theAnnotationFontObject->theHorizontalScale,
+                  rhs.theAnnotationFontObject->theVerticalScale),
+         ossimDpt(rhs.theAnnotationFontObject->theHorizontalShear,
+                  rhs.theAnnotationFontObject->theVerticalShear),
+         rhs.theRed,
+         rhs.theGreen,
+         rhs.theBlue))
+{
+   theAnnotationFontObject->setFont(theFont, false);
+}
+
+ossimGeoAnnotationFontObject::~ossimGeoAnnotationFontObject()
+{
+   if(theAnnotationFontObject)
+   {
+      delete theAnnotationFontObject;
+      theAnnotationFontObject = NULL;
+   }
+   if(theFont)
+   {
+      delete theFont;
+      theFont = NULL;
+   }
+}
+
+ossimObject* ossimGeoAnnotationFontObject::dup()const
+{
+   return new ossimGeoAnnotationFontObject(*this);
+}
+
+
+void ossimGeoAnnotationFontObject::setFont(ossimFont* font)
+{
+   if(theFont)
+   {
+     delete theFont;
+     theFont = NULL;
+   }
+   theFont = font;
+
+   theAnnotationFontObject->setFont(theFont, false);
+}
+
+ossimFont* ossimGeoAnnotationFontObject::getFont()
+{
+   return theFont;
+}
+
+void ossimGeoAnnotationFontObject::setPointSize(const ossimIpt& size)
+{
+   if(theAnnotationFontObject)
+   {
+      theAnnotationFontObject->setPointSize(size);
+   }
+}
+
+void ossimGeoAnnotationFontObject::setRotation(double rotation)
+{
+   if(theAnnotationFontObject)
+   {
+      theAnnotationFontObject->setRotation(rotation);
+   }
+}
+
+void ossimGeoAnnotationFontObject::setScale(const ossimDpt& scale)
+{
+   if(theAnnotationFontObject)
+   {
+      theAnnotationFontObject->setScale(scale);
+   }
+}
+
+void ossimGeoAnnotationFontObject::setShear(const ossimDpt& shear)
+{
+   if(theAnnotationFontObject)
+   {
+      theAnnotationFontObject->setShear(shear);
+   }
+}
+
+void ossimGeoAnnotationFontObject::setColor(ossim_uint8 r,
+                                            ossim_uint8 g,
+                                            ossim_uint8 b)
+{
+   if(theAnnotationFontObject)
+   {
+      theAnnotationFontObject->setColor(r, g, b);
+   }
+}
+
+void ossimGeoAnnotationFontObject::transform(ossimProjection* projection)
+{
+   if(projection)
+   {
+      ossimDpt ipt;
+
+      projection->worldToLineSample(theCenterGround, ipt);
+      theAnnotationFontObject->setPositionCenter(ipt);
+      theAnnotationFontObject->computeBoundingRect();
+   }
+}
+
+void ossimGeoAnnotationFontObject::setCenterGround(const ossimGpt& gpt)
+{
+   theCenterGround = gpt;
+}
+
+ossimAnnotationFontObject* ossimGeoAnnotationFontObject::getFontObject()
+{
+   return theAnnotationFontObject;
+}
+
+void ossimGeoAnnotationFontObject::draw(ossimRgbImage& anImage)const
+{
+   theAnnotationFontObject->draw(anImage);
+}
+
+void ossimGeoAnnotationFontObject::computeBoundingRect()
+{
+   theAnnotationFontObject->computeBoundingRect();
+}
+
+void ossimGeoAnnotationFontObject::getBoundingRect(ossimDrect& rect)const
+{
+   theAnnotationFontObject->getBoundingRect(rect);
+}
+
+ossimAnnotationObject* ossimGeoAnnotationFontObject::getNewClippedObject(
+   const ossimDrect& rect)const
+{
+   return (ossimAnnotationObject*)NULL;
+}
+
+bool ossimGeoAnnotationFontObject::intersects(const ossimDrect& rect)const
+{
+   return theAnnotationFontObject->intersects(rect);
+}
+
+void ossimGeoAnnotationFontObject::applyScale(double x, double y)
+{
+   theAnnotationFontObject->applyScale(x,y);
+}
+
+bool ossimGeoAnnotationFontObject::saveState(ossimKeywordlist& kwl,
+                                             const char* prefix) const
+{
+   kwl.add(prefix, "center", theCenterGround.toString().c_str());
+   kwl.add(prefix, "text", theAnnotationFontObject->getString().c_str());
+   theFontInfo.saveState(kwl, prefix);
+   
+   return ossimGeoAnnotationObject::saveState(kwl, prefix);
+}
+
+bool ossimGeoAnnotationFontObject::loadState(const ossimKeywordlist& kwl,
+                                             const char* prefix)
+{
+   //---
+   // Base class state must be called first to pick up colors...
+   //---
+   bool status =  ossimGeoAnnotationObject::loadState(kwl, prefix);
+
+   theAnnotationFontObject->setColor(theRed, theGreen, theBlue);
+   theAnnotationFontObject->setThickness(theThickness);
+   
+   const char* lookup;
+
+   lookup = kwl.find(prefix, "text");
+   if (lookup)
+   {
+      theAnnotationFontObject->setString(ossimString(lookup));
+   }
+
+   lookup = kwl.find(prefix, "center");
+   if (lookup)
+   {
+      std::istringstream is(lookup);
+      is >> theCenterGround;
+   }
+
+   // Get the font information.
+   theFontInfo.loadState(kwl, prefix);
+
+   // See if we can make a font.
+   ossimFont* f = ossimFontFactoryRegistry::instance()->
+      createFont(theFontInfo);
+   if (f)
+   {
+      if (theFont)
+      {
+         delete theFont;
+      }
+      theFont = f;
+      theAnnotationFontObject->setFont(theFont, false);
+   }
+
+   theAnnotationFontObject->setGeometryInformation(theFontInfo);
+   
+   return status;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationFontObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationFontObject.h
new file mode 100644
index 0000000000..f52a7b8b97
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationFontObject.h
@@ -0,0 +1,128 @@
+//*************************************************************************
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationFontObject.h,v 1.6 2005/12/11 17:12:16 dburken Exp $
+#ifndef ossimGeoAnnotationFontObject_HEADER
+#define ossimGeoAnnotationFontObject_HEADER
+#include <imaging/annotation/ossimGeoAnnotationObject.h>
+#include <imaging/annotation/ossimAnnotationFontObject.h>
+
+class ossimFont;
+
+class ossimGeoAnnotationFontObject : public ossimGeoAnnotationObject
+{
+public:
+   ossimGeoAnnotationFontObject();
+   
+   
+   ossimGeoAnnotationFontObject(const ossimGpt& location,
+                                const ossimString& s,
+                                const ossimIpt& pixelSize = ossimIpt(12, 12),
+                                double rotation = 0.0,
+                                const ossimDpt& scale = ossimDpt(1.0, 1.0),
+                                const ossimDpt& shear = ossimDpt(0.0,0.0),
+                                ossim_uint8 r=255,
+                                ossim_uint8 g=255,
+                                ossim_uint8 b=255);
+   ossimGeoAnnotationFontObject(const ossimGeoAnnotationFontObject& rhs);
+   
+   virtual ~ossimGeoAnnotationFontObject();
+   
+   virtual ossimObject* dup()const;
+
+   ossimAnnotationFontObject* getFontObject();
+
+   void setFont(ossimFont* font);
+
+   ossimFont* getFont();
+
+   virtual void setPointSize(const ossimIpt& size);
+
+   virtual void setRotation(double rotation);
+
+   virtual void setScale(const ossimDpt& scale);
+
+   virtual void setShear(const ossimDpt& shear);
+   
+   virtual void setColor(ossim_uint8 r,
+                         ossim_uint8 g,
+                         ossim_uint8 b);
+
+   virtual void transform(ossimProjection* projection);
+   
+   virtual void setCenterGround(const ossimGpt& gpt);
+   
+   virtual void draw(ossimRgbImage& anImage)const;
+   
+   virtual void computeBoundingRect();
+   
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   
+   virtual ossimAnnotationObject* getNewClippedObject(
+      const ossimDrect& rect)const;
+   
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual void applyScale(double x, double y);
+   
+   /**
+    * Saves the current state of this object.
+    *
+    * @see loadState for keywords.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    *
+    * Keywords:
+    *
+    * For center format is: ( latitude, longitude, height, datum_code )
+    * center: ( 42.01, -90.71, 0.0, WGE )
+    *
+    * For point_size format is: "( x, y )"
+    * point_size:  ( 18, 18 )
+    *
+    * For scale format is: "( x, y )"
+    * scale: ( 1.0, 1.0 )
+    *
+    * For shear format is: "( x, y )"
+    * shear: ( 0.0, 0.0 )
+    *
+    * text: Airport
+    *
+    * USE ONE OF family_name:
+    * family_name: URW Palladio L
+    * family_name: gd sans
+    * family_name: URW Bookman L
+    * family_name: Nimbus Roman No9 L
+    * family_name: Nimbus Sans L
+    * family_name: URW Palladio L
+    * family_name: Century Schoolbook L
+    * family_name: Nimbus Mono L
+    * family_name: Nimbus Sans L Condensed
+    *
+    * USE ONE OF style_name:
+    * style_name:  normal
+    * style_name:  bold
+    * style_name:  italic
+    * style_name:  bold italic
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+protected:
+   ossimGpt                   theCenterGround;
+   ossimFont*                 theFont;
+   ossimFontInformation       theFontInfo;
+   ossimAnnotationFontObject* theAnnotationFontObject;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationGdBitmapFont.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationGdBitmapFont.cpp
new file mode 100644
index 0000000000..41e4eb7de2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationGdBitmapFont.cpp
@@ -0,0 +1,139 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationGdBitmapFont.cpp,v 1.8 2004/05/23 17:49:37 dburken Exp $
+#include "ossimGeoAnnotationGdBitmapFont.h"
+#include "ossimAnnotationGdBitmapFont.h"
+#include "projections/ossimProjection.h"
+
+RTTI_DEF1(ossimGeoAnnotationGdBitmapFont, "ossimGeoAnnotationGdBitmapFont", ossimGeoAnnotationObject)
+
+ossimGeoAnnotationGdBitmapFont::ossimGeoAnnotationGdBitmapFont(const ossimGpt& position,
+                                                               const ossimString &text,
+                                                               ossimGdFontPtr font,
+                                                               unsigned char r,
+                                                               unsigned char g,
+                                                               unsigned char b,
+                                                               long thickness)
+   : ossimGeoAnnotationObject(r, g, b, thickness),
+     thePosition(position)
+{
+   theProjectedFont = new ossimAnnotationGdBitmapFont(ossimDpt(0,0),
+                                                      text,
+                                                      font,
+                                                      r,
+                                                      g,
+                                                      b,
+                                                      thickness);
+}
+
+ossimGeoAnnotationGdBitmapFont::ossimGeoAnnotationGdBitmapFont(const ossimGeoAnnotationGdBitmapFont& rhs)
+   :ossimGeoAnnotationObject(rhs),
+    theProjectedFont(rhs.theProjectedFont?(ossimAnnotationGdBitmapFont*)theProjectedFont->dup():(ossimAnnotationGdBitmapFont*)NULL),
+    thePosition(rhs.thePosition)
+{
+}
+
+
+ossimGeoAnnotationGdBitmapFont::~ossimGeoAnnotationGdBitmapFont()
+{
+   if(theProjectedFont)
+   {
+      delete theProjectedFont;
+      theProjectedFont=NULL;
+   }
+}
+
+void ossimGeoAnnotationGdBitmapFont::applyScale(double x, double y)
+{
+   thePosition.lond(thePosition.lond()*x);
+   thePosition.latd(thePosition.latd()*y);
+
+   if(theProjectedFont)
+   {
+      theProjectedFont->applyScale(x, y);
+   }
+}
+
+std::ostream& ossimGeoAnnotationGdBitmapFont::print(std::ostream& out)const
+{
+   out << "position:     " << thePosition;
+   theProjectedFont->print(out);
+   return out;
+}
+
+void ossimGeoAnnotationGdBitmapFont::draw(ossimRgbImage& anImage)const
+{
+   theProjectedFont->draw(anImage);
+}
+
+void ossimGeoAnnotationGdBitmapFont::getBoundingRect(ossimDrect& rect)const
+{
+   theProjectedFont->getBoundingRect(rect);
+}
+
+bool ossimGeoAnnotationGdBitmapFont::intersects(const ossimDrect& rect)const
+{
+   if(theProjectedFont)
+   {
+      return theProjectedFont->intersects(rect);
+   }
+
+   return false;
+}
+
+ossimAnnotationObject* ossimGeoAnnotationGdBitmapFont::getNewClippedObject(const ossimDrect& rect)const
+{
+   if(intersects(rect))
+   {
+      if(theProjectedFont)
+      {
+         return theProjectedFont->getNewClippedObject(rect);
+      }
+   }
+   
+   return (ossimAnnotationObject*)NULL;
+}
+
+void ossimGeoAnnotationGdBitmapFont::computeBoundingRect()
+{
+   theProjectedFont->computeBoundingRect();
+}
+
+void ossimGeoAnnotationGdBitmapFont::transform(ossimProjection* projection)
+{
+   ossimDpt position;
+
+   projection->worldToLineSample(thePosition, position);
+   
+   theProjectedFont->setUpperLeftTextPosition(position);
+}
+
+void ossimGeoAnnotationGdBitmapFont::setText(const ossimString& text)
+{
+   theProjectedFont->setText(text);
+}
+
+void ossimGeoAnnotationGdBitmapFont::setFont(ossimGdFontPtr font)
+{
+   theProjectedFont->setFont(font);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationGdBitmapFont.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationGdBitmapFont.h
new file mode 100644
index 0000000000..eb933574d9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationGdBitmapFont.h
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationGdBitmapFont.h,v 1.8 2004/05/23 17:49:37 dburken Exp $
+#ifndef ossimGeoAnnotationGdBitmapFont_HEADER
+#define ossimGeoAnnotationGdBitmapFont_HEADER
+
+#include "ossimGeoAnnotationObject.h"
+#include "ossimGdFont.h"
+#include "ossimGdFontExterns.h"
+class ossimAnnotationGdBitmapFont;
+
+class OSSIMDLLEXPORT ossimGeoAnnotationGdBitmapFont : public ossimGeoAnnotationObject
+{
+public:
+   ossimGeoAnnotationGdBitmapFont(const ossimGpt& position=ossimGpt(0,0,0),
+                                  const ossimString &text=ossimString(""),
+                                  ossimGdFontPtr font = ossimGdFontLarge,
+                                  unsigned char r = 255,
+                                  unsigned char g = 255,
+                                  unsigned char b = 255,
+                                  long thickness = 1);
+   ossimGeoAnnotationGdBitmapFont(const ossimGeoAnnotationGdBitmapFont& rhs);
+   virtual ~ossimGeoAnnotationGdBitmapFont();
+   virtual ossimObject* dup()const
+      {
+         return new ossimGeoAnnotationGdBitmapFont(*this);
+      }
+   virtual void applyScale(double x, double y);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void computeBoundingRect();
+   /*!
+    * Add the projection interface to all
+    * geographically defined objects.
+    */
+   virtual void transform(ossimProjection* projection);
+
+   virtual void setText(const ossimString& text);
+   virtual void setFont(ossimGdFontPtr font);
+
+protected:
+   ossimAnnotationGdBitmapFont* theProjectedFont;
+
+   /*!
+    * Will be the upper left corner of text;
+    */
+   ossimGpt                     thePosition;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationLineObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationLineObject.cpp
new file mode 100644
index 0000000000..398673b91c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationLineObject.cpp
@@ -0,0 +1,141 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationLineObject.cpp,v 1.9 2004/05/23 17:49:37 dburken Exp $
+#include "ossimGeoAnnotationLineObject.h"
+#include "ossimAnnotationLineObject.h"
+#include "projections/ossimProjection.h"
+
+RTTI_DEF1(ossimGeoAnnotationLineObject, "ossimGeoAnnotationLineObject", ossimGeoAnnotationObject)
+   
+ossimGeoAnnotationLineObject::ossimGeoAnnotationLineObject(const ossimGpt& start,
+                                                           const ossimGpt& end,
+                                                           unsigned char r,
+                                                           unsigned char g,
+                                                           unsigned char b,
+                                                           long thickness)
+   :ossimGeoAnnotationObject(r, g, b, thickness),
+    theProjectedLineObject(NULL),
+    theStart(start),
+    theEnd(end)
+{
+   theProjectedLineObject = new ossimAnnotationLineObject(ossimDpt(0,0),
+                                                          ossimDpt(0,0),
+                                                          r,
+                                                          g,
+                                                          b,
+                                                          thickness);
+}
+
+ossimGeoAnnotationLineObject::ossimGeoAnnotationLineObject(const ossimGeoAnnotationLineObject& rhs)
+   :ossimGeoAnnotationObject(rhs),
+    theProjectedLineObject(rhs.theProjectedLineObject?(ossimAnnotationLineObject*)rhs.theProjectedLineObject->dup():(ossimAnnotationLineObject*)NULL),
+    theStart(rhs.theStart),
+    theEnd(rhs.theEnd)
+{
+   
+}
+
+
+ossimGeoAnnotationLineObject::~ossimGeoAnnotationLineObject()
+{
+   if(theProjectedLineObject)
+   {
+      delete theProjectedLineObject;
+      theProjectedLineObject = NULL;
+   }
+}
+
+void ossimGeoAnnotationLineObject::applyScale(double x, double y)
+{
+   theStart.lond(theStart.lond()*x);
+   theStart.latd(theStart.latd()*y);
+   theEnd.lond(theEnd.lond()*x);
+   theEnd.latd(theEnd.latd()*y);
+
+   if(theProjectedLineObject)
+   {
+      theProjectedLineObject->applyScale(x, y);
+   }
+}
+
+void ossimGeoAnnotationLineObject::transform(ossimProjection* projection)
+{
+   if(projection)
+   {
+      ossimDpt projectedStart;
+      ossimDpt projectedEnd;
+      
+      projection->worldToLineSample(theStart,
+                                    projectedStart);
+      projection->worldToLineSample(theEnd,
+                                    projectedEnd);
+
+      theProjectedLineObject->setLine(projectedStart,
+                                      projectedEnd);
+   }
+}
+
+std::ostream& ossimGeoAnnotationLineObject::print(std::ostream& out)const
+{
+   out << "start ground:     " << theStart << endl;
+   out << "end ground:       " << theEnd   << endl;
+   return out;
+}
+
+void ossimGeoAnnotationLineObject::draw(ossimRgbImage& anImage)const
+{
+   theProjectedLineObject->draw(anImage);
+}
+
+bool ossimGeoAnnotationLineObject::intersects(const ossimDrect& rect)const
+{
+   if(theProjectedLineObject)
+   {
+      return theProjectedLineObject->intersects(rect);
+   }
+
+   return false;
+}
+
+ossimAnnotationObject* ossimGeoAnnotationLineObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   if(intersects(rect))
+   {
+      if(theProjectedLineObject)
+      {
+         return theProjectedLineObject->getNewClippedObject(rect);
+      }
+   }
+   
+   return (ossimAnnotationObject*)NULL;
+}
+
+void ossimGeoAnnotationLineObject::getBoundingRect(ossimDrect& rect)const
+{
+   theProjectedLineObject->getBoundingRect(rect);
+}
+
+void ossimGeoAnnotationLineObject::computeBoundingRect()
+{
+   theProjectedLineObject->computeBoundingRect();
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationLineObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationLineObject.h
new file mode 100644
index 0000000000..453400d7b4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationLineObject.h
@@ -0,0 +1,65 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationLineObject.h,v 1.7 2004/05/23 17:49:37 dburken Exp $
+#ifndef ossimGeoAnnotationLineObject_HEADER
+#define ossimGeoAnnotationLineObject_HEADER
+#include "base/data_types/ossimGpt.h"
+#include "ossimGeoAnnotationObject.h"
+
+class OSSIMDLLEXPORT ossimAnnotationLineObject;
+
+class ossimGeoAnnotationLineObject : public ossimGeoAnnotationObject
+{
+public:
+   ossimGeoAnnotationLineObject(const ossimGpt& start,
+                                const ossimGpt& end,
+                                unsigned char r=255,
+                                unsigned char g=255,
+                                unsigned char b=255,
+                                long thickness=1);
+   ossimGeoAnnotationLineObject(const ossimGeoAnnotationLineObject& rhs);
+   virtual ~ossimGeoAnnotationLineObject();
+
+   virtual ossimObject* dup()const
+      {
+         return new ossimGeoAnnotationLineObject(*this);
+      }
+
+   virtual void applyScale(double x, double y);
+   virtual void transform(ossimProjection* projection);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void computeBoundingRect();
+
+protected:
+   ossimAnnotationLineObject* theProjectedLineObject;
+   ossimGpt                   theStart;
+   ossimGpt                   theEnd;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiEllipseObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiEllipseObject.cpp
new file mode 100644
index 0000000000..c868dbbaca
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiEllipseObject.cpp
@@ -0,0 +1,186 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationMultiEllipseObject.cpp,v 1.7 2004/05/23 17:49:37 dburken Exp $
+
+#include <imaging/annotation/ossimGeoAnnotationMultiEllipseObject.h>
+#include <imaging/annotation/ossimAnnotationMultiEllipseObject.h>
+#include <projections/ossimProjection.h>
+
+ossimGeoAnnotationMultiEllipseObject::ossimGeoAnnotationMultiEllipseObject()
+   :ossimGeoAnnotationObject(),
+    theProjectedObject(new ossimAnnotationMultiEllipseObject()),
+    theWidthHeight(1,1),
+    theFillFlag(false)
+{
+   theProjectedObject->setFillFlag(false);
+}
+
+ossimGeoAnnotationMultiEllipseObject::ossimGeoAnnotationMultiEllipseObject(const std::vector<ossimGpt>& pointList,
+                                                                           const ossimDpt& widthHeight,
+                                                                           bool enableFill,
+                                                                           unsigned char r,
+                                                                           unsigned char g,
+                                                                           unsigned char b,
+                                                                           long thickness)
+   :ossimGeoAnnotationObject(r, g, b, thickness),
+    theProjectedObject(new ossimAnnotationMultiEllipseObject(widthHeight,enableFill, r, g, b, thickness )),
+    thePointList(pointList),
+    theWidthHeight(widthHeight),
+    theFillFlag(enableFill)
+{
+   
+}
+
+ossimGeoAnnotationMultiEllipseObject::ossimGeoAnnotationMultiEllipseObject(const ossimDpt& widthHeight,
+                                                                           bool enableFill,
+                                                                           unsigned char r,
+                                                                           unsigned char g,
+                                                                           unsigned char b,
+                                                                           long thickness)
+   :ossimGeoAnnotationObject(r, g, b,thickness),
+    theProjectedObject(new ossimAnnotationMultiEllipseObject(widthHeight,enableFill, r, g, b, thickness )),
+    theWidthHeight(widthHeight),
+    theFillFlag(enableFill)
+{
+}
+
+ossimGeoAnnotationMultiEllipseObject::ossimGeoAnnotationMultiEllipseObject(const ossimGeoAnnotationMultiEllipseObject& rhs)
+   :ossimGeoAnnotationObject(rhs),
+    theProjectedObject((ossimAnnotationMultiEllipseObject*)rhs.theProjectedObject->dup()),
+    thePointList(rhs.thePointList),
+    theWidthHeight(rhs.theWidthHeight),
+    theFillFlag(rhs.theFillFlag)
+{
+}
+   
+void ossimGeoAnnotationMultiEllipseObject::transform(ossimProjection* projection)
+{
+   theProjectedObject->resize(thePointList.size());
+   int i = 0;
+   int bounds = (int)thePointList.size();
+
+   for(i = 0; i < bounds; ++i)
+   {
+      projection->worldToLineSample(thePointList[i], (*theProjectedObject)[i]);
+      
+   }
+   computeBoundingRect();
+}
+
+void ossimGeoAnnotationMultiEllipseObject::setFillFlag(bool fillFlag)
+{
+   theProjectedObject->setFillFlag(fillFlag);
+   theFillFlag = fillFlag;
+}
+
+void ossimGeoAnnotationMultiEllipseObject::setColor(unsigned char r,
+                                                    unsigned char g,
+                                                    unsigned char b)
+{
+   ossimAnnotationObject::setColor(r,g,b);
+   if(theProjectedObject)
+   {
+      theProjectedObject->setColor(r,g,b);
+   }
+}
+
+void ossimGeoAnnotationMultiEllipseObject::setThickness(long thickness)
+{
+   ossimAnnotationObject::setThickness(thickness);
+   if(theProjectedObject)
+   {
+      theProjectedObject->setThickness(thickness);
+   }
+}
+
+
+void ossimGeoAnnotationMultiEllipseObject::applyScale(double x,
+                                                      double y)
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimGeoAnnotationMultiEllipseObject::applyScale NOT IMPLEMENTED"
+      << endl;
+}
+
+void ossimGeoAnnotationMultiEllipseObject::draw(ossimRgbImage& anImage)const
+{
+   theProjectedObject->draw(anImage); 
+}
+
+bool ossimGeoAnnotationMultiEllipseObject::intersects(const ossimDrect& rect)const
+{
+   return theProjectedObject->intersects(rect);
+}
+
+void ossimGeoAnnotationMultiEllipseObject::setWidthHeight(const ossimDpt& widthHeight)
+{
+   theWidthHeight = widthHeight;
+   theProjectedObject->setWidthHeight(widthHeight);
+}
+
+std::ostream& ossimGeoAnnotationMultiEllipseObject::print(std::ostream& out)const
+{
+   theProjectedObject->print(out);
+   return out;
+}
+
+void ossimGeoAnnotationMultiEllipseObject::getBoundingRect(ossimDrect& rect)const
+{
+   theProjectedObject->getBoundingRect(rect);
+}
+
+void ossimGeoAnnotationMultiEllipseObject::computeBoundingRect()
+{
+   theProjectedObject->computeBoundingRect();
+}
+
+ossimObject* ossimGeoAnnotationMultiEllipseObject::dup()const
+{
+   return new ossimGeoAnnotationMultiEllipseObject(*this);
+}
+
+ossimAnnotationObject* ossimGeoAnnotationMultiEllipseObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimGeoAnnotationMultiEllipseObject::getNewClippedObject "
+      << "NOT IMPLEMENTED" << endl;
+   return (ossimAnnotationObject*)dup();
+}
+
+void ossimGeoAnnotationMultiEllipseObject::addPoint(const ossimGpt& point)
+{
+   thePointList.push_back(point);
+}
+
+void ossimGeoAnnotationMultiEllipseObject::setPoint(int i,
+                                                    const ossimGpt& point)
+{
+   thePointList[i] = point;
+}
+
+void ossimGeoAnnotationMultiEllipseObject::resize(ossim_uint32 newSize)
+{
+   if(newSize)
+   {
+      thePointList.resize(newSize);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiEllipseObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiEllipseObject.h
new file mode 100644
index 0000000000..27b00a0649
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiEllipseObject.h
@@ -0,0 +1,83 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationMultiEllipseObject.h,v 1.8 2004/05/23 17:49:37 dburken Exp $
+#ifndef ossimGeoAnnotationMultiEllipseObject_HEADER
+#define ossimGeoAnnotationMultiEllipseObject_HEADER
+#include "ossimGeoAnnotationObject.h"
+#include <vector>
+class ossimAnnotationMultiEllipseObject;
+class OSSIMDLLEXPORT ossimGeoAnnotationMultiEllipseObject : public ossimGeoAnnotationObject
+{
+public:
+   ossimGeoAnnotationMultiEllipseObject();
+   ossimGeoAnnotationMultiEllipseObject(const std::vector<ossimGpt>& centerPoints,
+                                        const ossimDpt& widthHeight,
+                                        bool enableFill = false,
+                                        unsigned char r = 255,
+                                        unsigned char g = 255,
+                                        unsigned char b = 255,
+                                        long thickness = 1);
+   ossimGeoAnnotationMultiEllipseObject(const ossimDpt& widthHeight,
+                                        bool enableFill = false,
+                                        unsigned char r = 255,
+                                        unsigned char g = 255,
+                                        unsigned char b = 255,
+                                        long thickness = 1);
+   ossimGeoAnnotationMultiEllipseObject(const ossimGeoAnnotationMultiEllipseObject& rhs);
+   
+   virtual ossimObject* dup()const;
+
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+
+   virtual void transform(ossimProjection* projection);
+
+   virtual void applyScale(double x, double y);
+
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual void addPoint(const ossimGpt& point);
+
+   virtual void setColor(unsigned char r,
+                         unsigned char g,
+                         unsigned char b);
+   virtual void setThickness(long thickness);
+   
+   virtual void setPoint(int i, const ossimGpt& point);
+
+   virtual void setWidthHeight(const ossimDpt& widthHeight);
+   virtual void resize(ossim_uint32 newSize);
+
+   virtual void setFillFlag(bool fillFlag);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void computeBoundingRect();
+   
+protected:
+   ossimAnnotationMultiEllipseObject* theProjectedObject;
+   
+   std::vector<ossimGpt> thePointList;
+   ossimDpt              theWidthHeight;
+   bool                  theFillFlag;
+};
+
+#endif /* #ifndef ossimGeoAnnotationMultiEllipseObject_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.cpp
new file mode 100644
index 0000000000..1f021df206
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.cpp
@@ -0,0 +1,354 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationMultiPolyLineObject.cpp,v 1.7 2005/12/08 13:42:58 dburken Exp $
+
+#include <sstream>
+
+#include <imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.h>
+#include <imaging/annotation/ossimAnnotationMultiPolyLineObject.h>
+#include <projections/ossimProjection.h>
+
+RTTI_DEF1(ossimGeoAnnotationMultiPolyLineObject,
+          "ossimGeoAnnotationMultiPolyLineObject",
+          ossimGeoAnnotationObject);
+
+ossimGeoAnnotationMultiPolyLineObject::ossimGeoAnnotationMultiPolyLineObject()
+   :
+   ossimGeoAnnotationObject(),
+   theMultiPolyLine(),
+   theBoundingRect(),
+   theDatum(ossimDatumFactory::instance()->wgs84()),
+   theProjectedPolyLineObject(NULL)
+{
+   allocateProjectedPolyLine();   
+   theBoundingRect.makeNan();
+}
+
+ossimGeoAnnotationMultiPolyLineObject::ossimGeoAnnotationMultiPolyLineObject(
+   const vector<ossimPolyLine>& multiPoly,
+   ossim_uint8 r,
+   ossim_uint8 g,
+   ossim_uint8 b,
+   ossim_uint8 thickness)
+   :
+   ossimGeoAnnotationObject(r, g, b, thickness),
+   theMultiPolyLine(multiPoly),
+   theBoundingRect(),
+   theDatum(ossimDatumFactory::instance()->wgs84()),
+   theProjectedPolyLineObject(NULL)
+{
+   allocateProjectedPolyLine();   
+   theBoundingRect.makeNan();
+}
+
+ossimGeoAnnotationMultiPolyLineObject::ossimGeoAnnotationMultiPolyLineObject(
+   const ossimGeoAnnotationMultiPolyLineObject& rhs)
+   :ossimGeoAnnotationObject(rhs),
+    theMultiPolyLine(rhs.theMultiPolyLine),
+    theBoundingRect(rhs.theBoundingRect),
+    theDatum(rhs.theDatum),
+    theProjectedPolyLineObject(rhs.theProjectedPolyLineObject?(ossimAnnotationMultiPolyLineObject*)rhs.theProjectedPolyLineObject->dup():NULL)
+{
+}
+
+ossimObject* ossimGeoAnnotationMultiPolyLineObject::dup()const
+{
+   return new ossimGeoAnnotationMultiPolyLineObject(*this);
+}
+
+ossimGeoAnnotationMultiPolyLineObject::~ossimGeoAnnotationMultiPolyLineObject()
+{
+   if(theProjectedPolyLineObject)
+   {
+      delete theProjectedPolyLineObject;
+      theProjectedPolyLineObject = NULL;
+   }
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::applyScale(double x, double y)
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimGeoAnnotationPolyLineObject::applyScale NOT IMPLEMENTED!!!!"
+      << endl;
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::transform(ossimProjection* projection)
+{
+   cout << "ossimGeoAnnotationMultiPolyLineObject::transform entered..."
+        << endl;
+   
+   if(!projection) return;
+   int polyI  = 0;
+   int pointI = 0;
+   
+   allocateProjectedPolyLine();
+   if(!theProjectedPolyLineObject)
+   {
+      return;
+   }
+   std::vector<ossimPolyLine>& multiPolyLine = theProjectedPolyLineObject->getMultiPolyLine();
+   ossimGpt tempPoint(0,0, OSSIM_DBL_NAN, theDatum);
+   for(polyI = 0; polyI < (int)theMultiPolyLine.size(); ++polyI)
+   {
+      ossimPolyLine polyLine;
+      
+      int numberOfVertices = (int)theMultiPolyLine[polyI].getNumberOfVertices();
+      for(pointI = 0; pointI < numberOfVertices; ++pointI)
+      {
+         tempPoint.latd(theMultiPolyLine[polyI][pointI].lat);
+         tempPoint.lond(theMultiPolyLine[polyI][pointI].lon);
+         ossimDpt temp;
+         projection->worldToLineSample(tempPoint, temp);
+         if(!temp.hasNans())
+         {
+	    multiPolyLine[polyI].addPoint(temp);
+         }
+      }
+      multiPolyLine[polyI].roundToIntegerBounds(true);
+   }
+   
+}
+
+std::ostream& ossimGeoAnnotationMultiPolyLineObject::print(std::ostream& out)const
+{
+   ossimNotify(ossimNotifyLevel_INFO)
+      << "ossimGeoAnnotationMultiPolyLineObject::print\n"
+      << "Poly line size: " << theMultiPolyLine.size() << endl;
+   return out;
+}
+
+bool ossimGeoAnnotationMultiPolyLineObject::intersects(const ossimDrect& rect)const
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimGeoAnnotationMultiPolyObject::intersects NOT IMPLEMENTED"
+      << endl;
+  return false;
+}
+
+ossimAnnotationObject* ossimGeoAnnotationMultiPolyLineObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimGeoAnnotationMultiPolyObject::getNewClippedObject "
+      << "NOT IMPLEMENTED" << endl;
+
+   return (ossimAnnotationObject*)(dup());
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::draw(ossimRgbImage& anImage)const
+{
+   if(theProjectedPolyLineObject)
+   {
+      theProjectedPolyLineObject->draw(anImage);
+   }
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::getBoundingRect(ossimDrect& rect)const
+{
+   rect = theBoundingRect;
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::addPoint(ossim_uint32 polygonIndex,
+                                                     const ossimGpt& pt)
+{
+   if(polygonIndex < theMultiPolyLine.size())
+   {
+      theMultiPolyLine[polygonIndex].addPoint(pt);
+      
+      // we will have to reset the projected polygon
+      if(theProjectedPolyLineObject)
+      {
+         delete theProjectedPolyLineObject;
+         theProjectedPolyLineObject = NULL;
+      }
+   }
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::setMultiPolyLine(
+   const vector<ossimPolyLine>& multiPoly)
+{
+   theMultiPolyLine = multiPoly;
+   if(theProjectedPolyLineObject)
+   {
+      delete theProjectedPolyLineObject;
+      theProjectedPolyLineObject = NULL;
+   }
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::computeBoundingRect()
+{
+   theBoundingRect.makeNan();
+   if(theProjectedPolyLineObject)
+   {
+      theProjectedPolyLineObject->computeBoundingRect();
+      theProjectedPolyLineObject->getBoundingRect(theBoundingRect);
+   }
+   
+}
+
+bool ossimGeoAnnotationMultiPolyLineObject::isPointWithin(const ossimDpt& imagePoint)const
+{
+   if(theProjectedPolyLineObject)
+   {
+      return theProjectedPolyLineObject->isPointWithin(imagePoint);
+   }
+   
+   return false;
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::setColor(ossim_uint8 r,
+                                                     ossim_uint8 g,
+                                                     ossim_uint8 b)
+{
+   ossimAnnotationObject::setColor(r, g, b);
+   if(theProjectedPolyLineObject)
+   {
+      theProjectedPolyLineObject->setColor(r, g, b);
+   }
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::setThickness(long thickness)
+{
+   ossimAnnotationObject::setThickness(thickness);
+   if(theProjectedPolyLineObject)
+   {
+      theProjectedPolyLineObject->setThickness(thickness);
+   }
+}
+   
+void ossimGeoAnnotationMultiPolyLineObject::setDatum(const ossimDatum* datum)
+{
+   theDatum = datum;
+}
+
+const ossimDatum* ossimGeoAnnotationMultiPolyLineObject::getDatum()const
+{
+   return theDatum;
+}
+
+const std::vector<ossimPolyLine>&
+ossimGeoAnnotationMultiPolyLineObject::getMultiPolyLine() const
+{
+   return theMultiPolyLine;
+}
+
+std::vector<ossimPolyLine>&
+ossimGeoAnnotationMultiPolyLineObject::getMultiPolyLine()
+{
+   return theMultiPolyLine;
+}
+
+bool ossimGeoAnnotationMultiPolyLineObject::saveState(ossimKeywordlist& kwl,
+                                                      const char* prefix) const
+{
+   ossim_uint32 vIdx = 0;
+   
+   for(ossim_uint32 i = 0; i < theMultiPolyLine.size(); ++i)
+   {
+      ossimPolyLine pl = theMultiPolyLine[i];
+      for(ossim_uint32 j = 0; j < pl.getNumberOfVertices(); ++j)
+      {
+         ossimDpt dpt = pl[j];
+         std::ostringstream os;
+         os << setprecision(15) << dpt.x << " " << dpt.y << endl;
+         
+         ossimString key = "v";
+         key += ossimString::toString(vIdx);
+         kwl.add(prefix, key.c_str(), os.str().c_str());
+         ++vIdx;
+      }
+   }      
+      
+   return ossimGeoAnnotationObject::saveState(kwl, prefix);
+}
+
+bool ossimGeoAnnotationMultiPolyLineObject::loadState(
+   const ossimKeywordlist& kwl, const char* prefix)
+{
+   cout << "ossimGeoAnnotationMultiPolyLineObject::loadState entered..."
+        << endl;
+   
+   //---
+   // Base class state must be called first to pick up colors...
+   //---
+   bool status =  ossimGeoAnnotationObject::loadState(kwl, prefix);
+
+   ossim_uint32 index = 0;
+   ossimString copyPrefix = prefix;
+   ossim_uint32 count = kwl.getNumberOfSubstringKeys(copyPrefix+
+                                                      "v[0-9]");
+   
+
+   cout << "count: " << count << endl;
+   
+   ossim_uint32 numberOfMatches = 0;
+   const ossim_uint32 MAX_INDEX = count + 100;
+   ossimPolyLine pl;
+   
+   while(numberOfMatches < count)
+   {
+      ossimString key = "v";
+      key += ossimString::toString(index);
+
+      cout << "prefix: " << prefix
+           << "\nkey: " << key
+           << endl;
+      
+      const char* lookup = kwl.find(prefix, key.c_str());
+      if (lookup)
+      {
+         ++numberOfMatches;
+         ossimDpt dpt;
+
+         std::istringstream is(lookup);
+         is >> dpt.x >> dpt.y;
+         cout << "added point: " << dpt << endl;
+         pl.addPoint(dpt);
+      }
+
+      if (pl.size() == 2)
+      {
+         cout << "added line: " << pl << endl;
+         
+         theMultiPolyLine.push_back(pl);
+         pl.clear();
+      }
+
+      ++index;
+      
+      if (index > MAX_INDEX) // Avoid infinite loop...
+      {
+         break;
+      }
+   }
+
+   return status;
+}
+
+void ossimGeoAnnotationMultiPolyLineObject::allocateProjectedPolyLine()
+{
+   if(theProjectedPolyLineObject)
+   {
+      delete theProjectedPolyLineObject;
+      theProjectedPolyLineObject = NULL;
+   }
+
+   vector<ossimPolyLine> polyList;
+   
+   if(theMultiPolyLine.size())
+   {
+      polyList.resize(theMultiPolyLine.size());
+
+      theProjectedPolyLineObject = new ossimAnnotationMultiPolyLineObject(
+         polyList,
+         theRed,
+         theGreen,
+         theBlue,
+         theThickness);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.h
new file mode 100644
index 0000000000..aaa629f7a0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.h
@@ -0,0 +1,90 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationMultiPolyLineObject.h,v 1.5 2005/12/08 13:42:58 dburken Exp $
+#ifndef ossimGeoAnnotationMultiPolyLineObject_HEADER
+#define ossimGeoAnnotationMultiPolyLineObject_HEADER
+
+#include <imaging/annotation/ossimGeoAnnotationObject.h>
+#include <imaging/annotation/ossimAnnotationMultiPolyObject.h>
+#include <imaging/annotation/ossimAnnotationMultiPolyLineObject.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimPolyLine.h>
+
+class ossimDatum;
+
+class OSSIMDLLEXPORT ossimGeoAnnotationMultiPolyLineObject : public ossimGeoAnnotationObject
+{
+public:
+   ossimGeoAnnotationMultiPolyLineObject();
+   ossimGeoAnnotationMultiPolyLineObject(const vector<ossimPolyLine>& multiPolyLine,
+					 ossim_uint8 r=255,
+					 ossim_uint8 g=255,
+					 ossim_uint8 b=255,
+					 ossim_uint8 thickness=1);
+  
+   ossimGeoAnnotationMultiPolyLineObject(const ossimGeoAnnotationMultiPolyLineObject& rhs);
+   virtual ossimObject* dup()const;
+
+   virtual ~ossimGeoAnnotationMultiPolyLineObject();
+   virtual void transform(ossimProjection* projection);
+   virtual void applyScale(double x, double y);
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void addPoint(ossim_uint32 polygonIndex,
+                         const ossimGpt& pt);
+   
+   virtual void setMultiPolyLine(const vector<ossimPolyLine>& multiPoly);
+
+   virtual void computeBoundingRect();
+   
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   
+   virtual void setColor(ossim_uint8 r,
+                         ossim_uint8 g,
+                         ossim_uint8 b);
+   
+   virtual void setThickness(long thickness);
+   
+   void setDatum(const ossimDatum* datum);
+
+   const ossimDatum* getDatum()const;
+
+   const std::vector<ossimPolyLine>& getMultiPolyLine()const;
+   
+   std::vector<ossimPolyLine>& getMultiPolyLine();
+
+   /**
+    * Saves the current state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+protected:
+  vector<ossimPolyLine>               theMultiPolyLine;
+  ossimDrect                          theBoundingRect;
+  const ossimDatum*                   theDatum;
+  ossimAnnotationMultiPolyLineObject* theProjectedPolyLineObject;
+  
+  void allocateProjectedPolyLine();
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyObject.cpp
new file mode 100644
index 0000000000..d135298336
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyObject.cpp
@@ -0,0 +1,199 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationMultiPolyObject.cpp,v 1.11 2004/12/21 20:12:40 gpotts Exp $
+
+#include <imaging/annotation/ossimGeoAnnotationMultiPolyObject.h>
+#include <imaging/annotation/ossimAnnotationMultiPolyObject.h>
+#include <projections/ossimProjection.h>
+#include <base/data_types/ossimPolyArea2d.h>
+
+RTTI_DEF1(ossimGeoAnnotationMultiPolyObject, "ossimGeoAnnotationMultiPolyObject", ossimGeoAnnotationObject);
+
+ossimGeoAnnotationMultiPolyObject::ossimGeoAnnotationMultiPolyObject()
+   :
+      ossimGeoAnnotationObject(),
+      theMultiPolygon(),
+      theBoundingRect(),
+      theFillEnabled(false),
+      theProjectedPolyObject(NULL)
+{
+   allocateProjectedPolygon();   
+   theBoundingRect.makeNan();
+}
+
+ossimGeoAnnotationMultiPolyObject::ossimGeoAnnotationMultiPolyObject(const vector<ossimGeoPolygon>& multiPoly,
+                                                                     bool enableFill,
+                                                                     unsigned char r,
+                                                                     unsigned char g,
+                                                                     unsigned char b,
+                                                                     long thickness)
+   :
+      ossimGeoAnnotationObject(r, g, b, thickness),
+      theMultiPolygon(multiPoly),
+      theBoundingRect(),
+      theFillEnabled(enableFill),
+      theProjectedPolyObject(NULL)
+{
+   allocateProjectedPolygon();   
+   theBoundingRect.makeNan();
+}
+
+ossimGeoAnnotationMultiPolyObject::ossimGeoAnnotationMultiPolyObject(const ossimGeoAnnotationMultiPolyObject& rhs)
+   :
+      ossimGeoAnnotationObject(rhs),
+      theMultiPolygon(rhs.theMultiPolygon),
+      theBoundingRect(rhs.theBoundingRect),
+      theFillEnabled(rhs.theFillEnabled),
+      theProjectedPolyObject(rhs.theProjectedPolyObject?(ossimAnnotationMultiPolyObject*)rhs.theProjectedPolyObject->dup():NULL)
+{
+}
+
+ossimGeoAnnotationMultiPolyObject::~ossimGeoAnnotationMultiPolyObject()
+{
+   if(theProjectedPolyObject)
+   {
+      delete theProjectedPolyObject;
+      theProjectedPolyObject = NULL;
+   }
+}
+
+void ossimGeoAnnotationMultiPolyObject::applyScale(double x,
+                                              double y)
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimGeoAnnotationPolyObject::applyScale NOT IMPLEMENTED!!!!"
+      << endl;
+}
+
+void ossimGeoAnnotationMultiPolyObject::transform(ossimProjection* projection)
+{
+   if(!projection) return;
+   allocateProjectedPolygon();   
+   int polyI  = 0;
+   int pointI = 0;
+
+   ossimDpt temp;
+   std::vector<ossimPolygon> visiblePolygons;
+   ossimPolygon polygon;
+   for(polyI = 0; polyI < (int)theMultiPolygon.size(); ++polyI)
+   {
+      polygon.clear();
+      for(pointI = 0; pointI < (int)theMultiPolygon[polyI].size(); ++pointI)
+      {
+         projection->worldToLineSample(theMultiPolygon[polyI][pointI],
+                                       temp);
+         if(!temp.hasNans())
+         {
+            polygon.addPoint(temp);
+         }
+      }
+      theProjectedPolyObject->addPolygon(polygon);
+   }
+}
+
+std::ostream& ossimGeoAnnotationMultiPolyObject::print(std::ostream& out)const
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimGeoAnnotationMultiPolyObject::print NOT IMPLEMENTED"
+      << endl;
+   return out;
+}
+
+bool ossimGeoAnnotationMultiPolyObject::intersects(const ossimDrect& rect)const
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimGeoAnnotationMultiPolyObject::intersects NOT IMPLEMENTED"
+      << endl;
+  return false;
+}
+
+ossimAnnotationObject* ossimGeoAnnotationMultiPolyObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimGeoAnnotationMultiPolyObject::getNewClippedObject "
+      << "NOT IMPLEMENTED" << endl;
+   
+  return (ossimAnnotationObject*)(dup());
+}
+
+void ossimGeoAnnotationMultiPolyObject::draw(ossimRgbImage& anImage)const
+{
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->draw(anImage);
+   }
+}
+
+void ossimGeoAnnotationMultiPolyObject::getBoundingRect(ossimDrect& rect)const
+{
+   rect = theBoundingRect;
+}
+ 
+void ossimGeoAnnotationMultiPolyObject::computeBoundingRect()
+{
+   theBoundingRect.makeNan();
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->computeBoundingRect();
+      theProjectedPolyObject->getBoundingRect(theBoundingRect);
+   }
+}
+
+bool ossimGeoAnnotationMultiPolyObject::isPointWithin(const ossimDpt& imagePoint)const
+{
+   if(theProjectedPolyObject)
+   {
+      return theProjectedPolyObject->isPointWithin(imagePoint);
+   }
+
+   return false;
+}
+
+void ossimGeoAnnotationMultiPolyObject::setFillFlag(bool flag)
+{
+   theFillEnabled = flag;
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->setFillFlag(flag);
+   }
+}
+
+void ossimGeoAnnotationMultiPolyObject::allocateProjectedPolygon()
+{
+   if(theProjectedPolyObject)
+   {
+      delete theProjectedPolyObject;
+      theProjectedPolyObject = NULL;
+   }
+
+   vector<ossimPolygon> polyList;
+   
+   if(theMultiPolygon.size())
+   {
+      theProjectedPolyObject = new ossimAnnotationMultiPolyObject(polyList,
+                                                                  theFillEnabled,
+                                                                  theRed,
+                                                                  theGreen,
+                                                                  theBlue,
+                                                                  theThickness);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyObject.h
new file mode 100644
index 0000000000..ec88ca5889
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationMultiPolyObject.h
@@ -0,0 +1,118 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationMultiPolyObject.h,v 1.5 2004/05/23 17:49:37 dburken Exp $
+#ifndef ossimGeoAnnotationMultiPolyObject_HEADER
+#define ossimGeoAnnotationMultiPolyObject_HEADER
+#include "ossimGeoAnnotationObject.h"
+#include "base/data_types/ossimIpt.h"
+#include "base/data_types/ossimGeoPolygon.h"
+#include "ossimAnnotationMultiPolyObject.h"
+
+class OSSIMDLLEXPORT ossimGeoAnnotationMultiPolyObject : public ossimGeoAnnotationObject
+{
+public:
+   ossimGeoAnnotationMultiPolyObject();
+   ossimGeoAnnotationMultiPolyObject(const vector<ossimGeoPolygon>& multiPoly,
+                                     bool enableFill=false,
+                                     unsigned char r=255,
+                                     unsigned char g=255,
+                                     unsigned char b=255,
+                                     long thickness=1);
+   
+   ossimGeoAnnotationMultiPolyObject(const ossimGeoAnnotationMultiPolyObject& rhs);
+   virtual ossimObject* dup()const
+      {
+         return new ossimGeoAnnotationMultiPolyObject(*this);
+      }
+   virtual ~ossimGeoAnnotationMultiPolyObject();
+   virtual void transform(ossimProjection* projection);
+   virtual void applyScale(double x,
+                                double y);
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void addPoint(ossim_uint32 polygonIndex,
+                         const ossimGpt& pt)
+      {
+         if(polygonIndex < theMultiPolygon.size())
+         {
+            theMultiPolygon[polygonIndex].addPoint(pt);
+
+            // we will have to reset the projected polygon
+            if(theProjectedPolyObject)
+            {
+               delete theProjectedPolyObject;
+               theProjectedPolyObject = NULL;
+            }
+         }
+      }
+   
+   virtual void setMultiPolygon(const vector<ossimGeoPolygon>& multiPoly)
+      {
+         theMultiPolygon = multiPoly;
+         if(theProjectedPolyObject)
+         {
+            delete theProjectedPolyObject;
+            theProjectedPolyObject = NULL;
+         }
+      }
+   virtual void setColor(unsigned char r,
+                         unsigned char g,
+                         unsigned char b)
+      {
+         ossimAnnotationObject::setColor(r, g, b);
+         if(theProjectedPolyObject)
+         {
+            theProjectedPolyObject->setColor(r, g, b);
+         }
+      }
+   
+   virtual void setThickness(long thickness)
+      {
+         ossimAnnotationObject::setThickness(thickness);
+         if(theProjectedPolyObject)
+         {
+            theProjectedPolyObject->setThickness(thickness);
+         }
+      }
+   virtual void computeBoundingRect();
+   virtual bool isPointWithin(const ossimDpt& imagePoint)const;
+   virtual void setFillFlag(bool flag);
+  
+   const std::vector<ossimGeoPolygon>& getMultiPolygon()const{return theMultiPolygon;}
+   std::vector<ossimGeoPolygon>& getMultiPolygon(){return theMultiPolygon;}
+   
+protected:
+   vector<ossimGeoPolygon> theMultiPolygon;
+   ossimDrect              theBoundingRect;
+   bool                   theFillEnabled;
+   ossimAnnotationMultiPolyObject* theProjectedPolyObject;
+   
+   void allocateProjectedPolygon();
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationObject.cpp
new file mode 100644
index 0000000000..03f7998348
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationObject.cpp
@@ -0,0 +1,46 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationObject.cpp,v 1.3 2005/12/07 19:05:11 dburken Exp $
+
+#include <imaging/annotation/ossimGeoAnnotationObject.h>
+
+RTTI_DEF1(ossimGeoAnnotationObject,
+          "ossimGeoAnnotationObject",
+          ossimAnnotationObject)
+
+ossimGeoAnnotationObject::ossimGeoAnnotationObject(unsigned char r,
+                                                   unsigned char g,
+                                                   unsigned char b,
+                                                   long thickness)
+   :ossimAnnotationObject(r, g, b, thickness)
+{
+}
+
+ossimGeoAnnotationObject::ossimGeoAnnotationObject(
+   const ossimGeoAnnotationObject& rhs)
+   :
+   ossimAnnotationObject(rhs)
+{
+}
+
+ossimGeoAnnotationObject::~ossimGeoAnnotationObject()
+{
+}
+
+bool ossimGeoAnnotationObject::saveState(ossimKeywordlist& kwl,
+                                         const char* prefix) const
+{
+   return ossimAnnotationObject::saveState(kwl, prefix);
+}
+
+bool ossimGeoAnnotationObject::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   return ossimAnnotationObject::loadState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationObject.h
new file mode 100644
index 0000000000..97e94f6226
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationObject.h
@@ -0,0 +1,51 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationObject.h,v 1.4 2005/12/07 19:05:11 dburken Exp $
+#ifndef ossimGeoAnnotationObject_HEADER
+#define ossimGeoAnnotationObject_HEADER
+#include <imaging/annotation/ossimAnnotationObject.h>
+#include <base/data_types/ossimGpt.h>
+
+class ossimProjection;
+
+class OSSIM_DLL ossimGeoAnnotationObject : public ossimAnnotationObject
+{
+public:
+   ossimGeoAnnotationObject(unsigned char r=255,
+                            unsigned char g=255,
+                            unsigned char b=255,
+                            long thickness=1);
+
+   ossimGeoAnnotationObject(const ossimGeoAnnotationObject& rhs);
+
+   virtual ~ossimGeoAnnotationObject();
+   
+   /*!
+    * Add the projection interface to all
+    * geographically defined objects.
+    */
+   virtual void transform(ossimProjection* projection)=0;
+
+   /**
+    * Saves the current state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyLineObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyLineObject.cpp
new file mode 100644
index 0000000000..20d0def39e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyLineObject.cpp
@@ -0,0 +1,178 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationPolyLineObject.cpp,v 1.3 2005/05/27 12:17:43 gpotts Exp $
+#include "ossimGeoAnnotationPolyLineObject.h"
+#include "ossimAnnotationMultiLineObject.h"
+#include "projections/ossimProjection.h"
+
+RTTI_DEF1(ossimGeoAnnotationPolyLineObject, "ossimGeoAnnotationPolyLineObject", ossimGeoAnnotationObject)
+   
+ossimGeoAnnotationPolyLineObject::ossimGeoAnnotationPolyLineObject(const vector<ossimGpt>& groundPts,
+                                                           unsigned char r,
+                                                           unsigned char g,
+                                                           unsigned char b,
+                                                           long thickness)
+   :ossimGeoAnnotationObject(r, g, b, thickness),
+    theProjectedMultiLineObject(NULL)
+{
+
+   thePolygon = groundPts;
+
+   // we will initialize the projected polygon's size
+   // so we don't have to reset it every time we do a
+   // projection
+   //
+   vector<ossimDpt> projectedPoints(thePolygon.size());
+   
+   theProjectedMultiLineObject = new ossimAnnotationMultiLineObject(ossimPolyLine(projectedPoints),
+                                                                    r,
+                                                                    g,
+                                                                    b,
+                                                                    thickness);
+}
+
+ossimGeoAnnotationPolyLineObject::ossimGeoAnnotationPolyLineObject(const ossimGeoAnnotationPolyLineObject& rhs)
+   :ossimGeoAnnotationObject(rhs),
+    thePolygon(rhs.thePolygon),
+    theProjectedMultiLineObject(rhs.theProjectedMultiLineObject?(ossimAnnotationMultiLineObject*)rhs.theProjectedMultiLineObject->dup():(ossimAnnotationMultiLineObject*)NULL)
+{
+}
+
+ossimGeoAnnotationPolyLineObject::~ossimGeoAnnotationPolyLineObject()
+{
+   if(theProjectedMultiLineObject)
+   {
+      delete theProjectedMultiLineObject;
+      theProjectedMultiLineObject = NULL;
+   }
+}
+
+void ossimGeoAnnotationPolyLineObject::applyScale(double x,
+                                                   double y)
+{
+   for(int i = 0; i < (int)thePolygon.size(); ++i)
+   {
+      thePolygon[i].lond(thePolygon[i].lond()*x);
+      thePolygon[i].latd(thePolygon[i].latd()*y);
+   }
+   if(theProjectedMultiLineObject)
+   {
+      theProjectedMultiLineObject->applyScale(x, y);
+   }
+      
+}
+
+void ossimGeoAnnotationPolyLineObject::transform(ossimProjection* projection)
+{
+   // make sure it's not null
+   if(!projection)
+   {
+      return;
+   }
+   vector<ossimPolyLine>& polyList =theProjectedMultiLineObject->getPolyLineList();
+
+   if(polyList.size())
+   {
+      vector<ossimDpt>& poly = polyList[0].getVertexList();
+      
+      long upperBound = thePolygon.size();
+      
+      for(long index=0; index < upperBound; ++index)
+      {
+         projection->worldToLineSample(thePolygon[index], poly[index]);
+      }
+      
+      // update the bounding rect
+      //
+      theProjectedMultiLineObject->computeBoundingRect();
+   }
+}
+
+std::ostream& ossimGeoAnnotationPolyLineObject::print(std::ostream& out)const
+{
+   out << "number_of_points:  " << thePolygon.size() << endl;
+   if(thePolygon.size() > 0)
+   {
+      for(long index =0; index < (long)(thePolygon.size()-1); ++index)
+      {
+         out << thePolygon[index] << endl;
+      }
+      out << thePolygon[thePolygon.size()-1] << endl;
+   }
+   out << "Projected Polygon" << endl;
+   theProjectedMultiLineObject->print(out);
+   return out;
+}
+
+void ossimGeoAnnotationPolyLineObject::draw(ossimRgbImage& anImage)const
+{
+   theProjectedMultiLineObject->draw(anImage);
+}
+
+bool ossimGeoAnnotationPolyLineObject::intersects(const ossimDrect& rect)const
+{
+   if(theProjectedMultiLineObject)
+   {
+      return theProjectedMultiLineObject->intersects(rect);
+   }
+   
+   return false;
+}
+
+ossimAnnotationObject* ossimGeoAnnotationPolyLineObject::getNewClippedObject(const ossimDrect& rect)const
+{
+   if(theProjectedMultiLineObject)
+   {
+      return theProjectedMultiLineObject->getNewClippedObject(rect);
+   }
+   
+   return (ossimAnnotationObject*)NULL;;
+}
+
+void ossimGeoAnnotationPolyLineObject::getBoundingRect(ossimDrect& rect)const
+{
+   theProjectedMultiLineObject->getBoundingRect(rect);
+}
+
+void ossimGeoAnnotationPolyLineObject::computeBoundingRect()
+{
+   theProjectedMultiLineObject->computeBoundingRect();
+}
+
+void ossimGeoAnnotationPolyLineObject::setColor(unsigned char r,
+                                                unsigned char g,
+                                                unsigned char b)
+{
+   if(theProjectedMultiLineObject)
+   {
+      theProjectedMultiLineObject->setColor(r, g, b);
+   }
+}
+
+void ossimGeoAnnotationPolyLineObject::setThickness(long thickness)
+{
+   if(theProjectedMultiLineObject)
+   {
+      theProjectedMultiLineObject->setThickness(thickness);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyLineObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyLineObject.h
new file mode 100644
index 0000000000..e0f06f4c35
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyLineObject.h
@@ -0,0 +1,69 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationPolyLineObject.h,v 1.4 2005/05/27 12:17:43 gpotts Exp $
+#ifndef ossimGeoAnnotationPolyLineObject_HEADER
+#define ossimGeoAnnotationPolyLineObject_HEADER
+#include "base/data_types/ossimGpt.h"
+#include "ossimGeoAnnotationObject.h"
+
+class ossimAnnotationMultiLineObject;
+
+class OSSIMDLLEXPORT ossimGeoAnnotationPolyLineObject : public ossimGeoAnnotationObject
+{
+public:
+   ossimGeoAnnotationPolyLineObject(const vector<ossimGpt>& groundPts,
+                                     unsigned char r=255,
+                                     unsigned char g=255,
+                                     unsigned char b=255,
+                                     long thickness=1);
+   ossimGeoAnnotationPolyLineObject(const ossimGeoAnnotationPolyLineObject& rhs);
+   virtual ~ossimGeoAnnotationPolyLineObject();
+   virtual ossimObject* dup()const
+      {
+         return new ossimGeoAnnotationPolyLineObject(*this);
+      }
+   
+   virtual void applyScale(double x,
+                           double y);
+
+   virtual void transform(ossimProjection* projection);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual void draw(ossimRgbImage& anImage)const;
+   virtual ossimAnnotationObject* getNewClippedObject(const ossimDrect& rect)const;
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void computeBoundingRect();
+   virtual void setColor(unsigned char r,
+                         unsigned char g,
+                         unsigned char b);
+   virtual void setThickness(long thickness);
+
+protected:
+   vector<ossimGpt>                thePolygon;
+   ossimAnnotationMultiLineObject* theProjectedMultiLineObject;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyObject.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyObject.cpp
new file mode 100644
index 0000000000..9c08803471
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyObject.cpp
@@ -0,0 +1,302 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationPolyObject.cpp,v 1.14 2005/12/16 14:28:27 dburken Exp $
+
+#include <sstream>
+
+#include <imaging/annotation/ossimGeoAnnotationPolyObject.h>
+#include <imaging/annotation/ossimAnnotationPolyObject.h>
+#include <projections/ossimProjection.h>
+#include <base/common/ossimTrace.h>
+
+static const ossimTrace
+traceDebug(ossimString("ossimGeoAnnotationPolyObject:debug"));
+
+RTTI_DEF1(ossimGeoAnnotationPolyObject,
+          "ossimGeoAnnotationPolyObject",
+          ossimGeoAnnotationObject)
+
+ossimGeoAnnotationPolyObject::ossimGeoAnnotationPolyObject(bool enableFill,
+                                                           ossim_uint8 r,
+                                                           ossim_uint8 g,
+                                                           ossim_uint8 b,
+                                                           ossim_uint8 thickness)
+   :ossimGeoAnnotationObject(r, g, b, thickness),
+    thePolygon(),
+    theProjectedPolyObject(NULL)
+{
+   theProjectedPolyObject = new ossimAnnotationPolyObject(enableFill,
+                                                          r,
+                                                          g,
+                                                          b,
+                                                          thickness);
+}
+   
+ossimGeoAnnotationPolyObject::ossimGeoAnnotationPolyObject(
+   const std::vector<ossimGpt>& groundPts,
+   bool enableFill,
+   ossim_uint8 r,
+   ossim_uint8 g,
+   ossim_uint8 b,
+   ossim_uint8 thickness)
+   :ossimGeoAnnotationObject(r, g, b, thickness),
+    thePolygon(),
+    theProjectedPolyObject(NULL)
+{
+   
+   thePolygon = groundPts;
+   
+   // we will initialize the projected polygon's size
+   // so we don't have to reset it every time we do a
+   // projection
+   //
+   std::vector<ossimDpt> projectedPoints(thePolygon.size());
+   
+   theProjectedPolyObject = new ossimAnnotationPolyObject(projectedPoints,
+                                                          enableFill,
+                                                          r,
+                                                          g,
+                                                          b,
+                                                          thickness);
+}
+
+ossimGeoAnnotationPolyObject::ossimGeoAnnotationPolyObject(
+   const ossimGeoAnnotationPolyObject& rhs)
+   :ossimGeoAnnotationObject(rhs),
+    thePolygon(rhs.thePolygon),
+    theProjectedPolyObject(rhs.theProjectedPolyObject?(ossimAnnotationPolyObject*)rhs.theProjectedPolyObject->dup():(ossimAnnotationPolyObject*)NULL)
+{
+}
+
+ossimGeoAnnotationPolyObject::~ossimGeoAnnotationPolyObject()
+{
+   if(theProjectedPolyObject)
+   {
+      delete theProjectedPolyObject;
+      theProjectedPolyObject = NULL;
+   }
+}
+
+ossimObject* ossimGeoAnnotationPolyObject::dup()const
+{
+   return new ossimGeoAnnotationPolyObject(*this);
+}
+
+void ossimGeoAnnotationPolyObject::applyScale(double x,
+                                              double y)
+{
+   for(int i = 0; i < (int)thePolygon.size(); ++i)
+   {
+      thePolygon[i].lond(thePolygon[i].lond()*x);
+      thePolygon[i].latd(thePolygon[i].latd()*y);
+   }
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->applyScale(x, y);
+   }
+      
+}
+
+void ossimGeoAnnotationPolyObject::transform(ossimProjection* projection)
+{
+   // make sure it's not null
+   if(!projection)
+   {
+      return;
+   }
+   ossimPolygon& poly = theProjectedPolyObject->getPolygon();
+   long upperBound = thePolygon.size();
+
+   for(long index=0; index < upperBound; ++index)
+   {
+      projection->worldToLineSample(thePolygon[index], poly[index]);
+   }
+
+   // update the bounding rect
+   //
+   theProjectedPolyObject->computeBoundingRect();
+}
+
+std::ostream& ossimGeoAnnotationPolyObject::print(std::ostream& out)const
+{
+   out << "number_of_points:  " << thePolygon.size() << std::endl;
+   if(thePolygon.size() > 0)
+   {
+      for(long index =0; index < (long)(thePolygon.size()-1); ++index)
+      {
+         out << thePolygon[index] << std::endl;
+      }
+      out << thePolygon[thePolygon.size()-1] << std::endl;
+   }
+   out << "Projected Polygon" << std::endl;
+   theProjectedPolyObject->print(out);
+   return out;
+}
+
+void ossimGeoAnnotationPolyObject::draw(ossimRgbImage& anImage)const
+{
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->draw(anImage);
+   }
+}
+
+ossimAnnotationObject* ossimGeoAnnotationPolyObject::getNewClippedObject(
+   const ossimDrect& rect)const
+{
+   if(theProjectedPolyObject)
+   {
+      return theProjectedPolyObject->getNewClippedObject(rect);
+   }
+   
+   return (ossimAnnotationObject*)NULL;
+}
+
+bool ossimGeoAnnotationPolyObject::intersects(const ossimDrect& rect)const
+{
+   if(theProjectedPolyObject)
+   {
+      return theProjectedPolyObject->intersects(rect);
+   }
+   
+   return false;
+}
+
+void ossimGeoAnnotationPolyObject::getBoundingRect(ossimDrect& rect)const
+{
+   rect.makeNan();
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->getBoundingRect(rect);
+   }
+}
+
+void ossimGeoAnnotationPolyObject::computeBoundingRect()
+{
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->computeBoundingRect();
+   }
+}
+
+const std::vector<ossimGpt>& ossimGeoAnnotationPolyObject::getPolygon()const
+{
+   return thePolygon;
+}
+
+void ossimGeoAnnotationPolyObject::setFillFlag(bool flag)
+{
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->setFillFlag(flag);
+   }
+}
+
+void ossimGeoAnnotationPolyObject::setColor(ossim_uint8 r,
+                                            ossim_uint8 g,
+                                            ossim_uint8 b)
+{
+   ossimAnnotationObject::setColor(r, g, b);
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->setColor(r, g, b);
+   }
+}
+
+void ossimGeoAnnotationPolyObject::setThickness(long thickness)
+{
+   ossimAnnotationObject::setThickness(thickness);
+   if(theProjectedPolyObject)
+   {
+      theProjectedPolyObject->setThickness(thickness);
+   }
+}
+
+bool ossimGeoAnnotationPolyObject::saveState(ossimKeywordlist& kwl,
+                                             const char* prefix) const
+{
+   ossim_uint32 vIdx = 0;
+   
+   for(ossim_uint32 i = 0; i < thePolygon.size(); ++i)
+   {
+      ossimString key = "v";
+      key += ossimString::toString(vIdx);
+
+      kwl.add(prefix, key.c_str(), thePolygon[i].toString().c_str());
+
+      ++vIdx;
+   }
+   
+   return ossimGeoAnnotationObject::saveState(kwl, prefix);
+}
+
+bool ossimGeoAnnotationPolyObject::loadState(const ossimKeywordlist& kwl,
+                                             const char* prefix)
+{
+   if (!theProjectedPolyObject)
+   {
+      return false;
+   }
+   
+   //---
+   // Base class state must be called first to pick up colors...
+   //---
+   bool status =  ossimGeoAnnotationObject::loadState(kwl, prefix);
+
+   ossim_uint32 index = 0;
+   ossimString copyPrefix = prefix;
+   ossim_uint32 count = kwl.getNumberOfSubstringKeys(copyPrefix+"v[0-9]*");
+
+   ossim_uint32 numberOfMatches = 0;
+   const ossim_uint32 MAX_INDEX = count + 100;
+   
+   while(numberOfMatches < count)
+   {
+      ossimString key = "v";
+      key += ossimString::toString(index);
+
+      const char* lookup = kwl.find(prefix, key.c_str());
+      if (lookup)
+      {
+         ++numberOfMatches;
+         ossimGpt gpt;
+
+         std::istringstream is(lookup);
+         is >> gpt;
+         thePolygon.push_back(gpt);
+      }
+
+      ++index;
+      
+      if (index > MAX_INDEX) // Avoid infinite loop...
+      {
+         break;
+      }
+   }
+
+   // Set up the annotator.
+   theProjectedPolyObject->setColor(theRed, theGreen, theBlue);
+   theProjectedPolyObject->setThickness(theThickness);
+   
+   std::vector<ossimDpt> projectedPoints(thePolygon.size());
+   theProjectedPolyObject->setPolygon(projectedPoints);
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimGeoAnnotationPolyObject::loadState DEBUG:" << std::endl;
+      for (ossim_uint32 i=0; i<thePolygon.size(); ++i)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "thePolygon[" << i << "]:  " << thePolygon[i] << std::endl;
+      }
+   }
+   
+   return status;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyObject.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyObject.h
new file mode 100644
index 0000000000..e58c560477
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationPolyObject.h
@@ -0,0 +1,88 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationPolyObject.h,v 1.12 2005/12/09 18:23:47 dburken Exp $
+#ifndef ossimGeoAnnotationPolyObject_HEADER
+#define ossimGeoAnnotationPolyObject_HEADER
+
+#include <vector>
+
+#include <base/data_types/ossimGpt.h>
+#include <imaging/annotation/ossimGeoAnnotationObject.h>
+class ossimAnnotationPolyObject;
+
+class OSSIMDLLEXPORT ossimGeoAnnotationPolyObject : public ossimGeoAnnotationObject
+{
+public:
+   ossimGeoAnnotationPolyObject(bool enableFill = false,
+                                ossim_uint8 r=255,
+                                ossim_uint8 g=255,
+                                ossim_uint8 b=255,
+                                ossim_uint8 thickness=1);
+
+   ossimGeoAnnotationPolyObject(const std::vector<ossimGpt>& groundPts,
+                                bool enableFill = false,
+                                ossim_uint8 r=255,
+                                ossim_uint8 g=255,
+                                ossim_uint8 b=255,
+                                ossim_uint8 thickness=1);
+
+   ossimGeoAnnotationPolyObject(const ossimGeoAnnotationPolyObject& rhs);
+
+   virtual ~ossimGeoAnnotationPolyObject();
+
+   virtual ossimObject* dup()const;
+
+   virtual void applyScale(double x, double y);
+
+   virtual void transform(ossimProjection* projection);
+   
+   virtual std::ostream& print(std::ostream& out)const;
+
+   virtual void draw(ossimRgbImage& anImage)const;
+
+   virtual ossimAnnotationObject* getNewClippedObject(
+      const ossimDrect& rect)const;
+
+   virtual bool intersects(const ossimDrect& rect)const;
+   
+   virtual void getBoundingRect(ossimDrect& rect)const;
+
+   virtual void computeBoundingRect();
+
+   virtual const std::vector<ossimGpt>& getPolygon()const;
+
+   virtual void setFillFlag(bool flag);
+
+   virtual void setColor(ossim_uint8 r,
+                         ossim_uint8 g,
+                         ossim_uint8 b);
+   
+   virtual void setThickness(long thickness);
+
+   /**
+    * Saves the current state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+protected:
+   std::vector<ossimGpt>      thePolygon;
+   ossimAnnotationPolyObject* theProjectedPolyObject;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationSource.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationSource.cpp
new file mode 100644
index 0000000000..22475c395e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationSource.cpp
@@ -0,0 +1,207 @@
+//************************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimGeoAnnotationSource.cpp,v 1.19 2005/12/07 18:56:13 dburken Exp $
+
+#include <imaging/annotation/ossimGeoAnnotationSource.h>
+#include <imaging/annotation/ossimGeoAnnotationObject.h>
+#include <projections/ossimProjection.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+
+RTTI_DEF2(ossimGeoAnnotationSource,
+          "ossimGeoAnnotationSource",
+          ossimAnnotationSource,
+          ossimViewInterface);
+   
+
+ostream& operator <<(ostream& out, const ossimGeoAnnotationSource& rhs)
+{
+   const vector<ossimAnnotationObject*> &tempList = rhs.getObjectList();
+   for(ossim_uint32 index = 0; index < tempList.size(); ++index)
+   {
+      out << "output " << index << endl;
+      tempList[index]->print(out);
+   }
+
+   return out;
+}
+
+ossimGeoAnnotationSource::ossimGeoAnnotationSource(ossimProjection* projection,
+                                                   bool ownsProjectionFlag)
+   :ossimAnnotationSource(),
+    ossimViewInterface(),
+    theProjection(projection),
+    theOwnsProjectionFlag(ownsProjectionFlag)
+{
+   ossimViewInterface::theObject = this;
+}
+
+ossimGeoAnnotationSource::ossimGeoAnnotationSource(ossimImageSource* inputSource,
+                                                   ossimProjection* projection,
+                                                   bool ownsProjectionFlag)
+   :ossimAnnotationSource(inputSource),
+    ossimViewInterface(),
+    theProjection(projection),
+    theOwnsProjectionFlag(ownsProjectionFlag)
+{
+   ossimViewInterface::theObject = this;
+}
+
+ossimGeoAnnotationSource::~ossimGeoAnnotationSource()
+{
+   removeProjection();
+}
+
+bool ossimGeoAnnotationSource::addObject(ossimAnnotationObject* anObject)
+{
+   ossimGeoAnnotationObject *objectToAdd = PTR_CAST(ossimGeoAnnotationObject, anObject);
+   
+   if(objectToAdd)
+   {
+      ossimAnnotationSource::addObject(objectToAdd);
+      if(theProjection)
+      {
+         objectToAdd->transform(theProjection);
+         computeBoundingRect();
+      }
+      return true;
+   }
+
+   return false;
+}
+
+void ossimGeoAnnotationSource::setProjection(ossimProjection* projection,
+                                             bool ownsProjectionFlag)
+{
+   // remove our current set projection first
+   removeProjection();
+
+   theProjection         = projection;
+   theOwnsProjectionFlag = ownsProjectionFlag;
+   transformObjects(theProjection);
+   
+}
+
+bool ossimGeoAnnotationSource::setView(ossimObject* baseObject,
+                                       bool ownsTheView)
+{
+   ossimProjection* proj = PTR_CAST(ossimProjection, baseObject);
+   if(proj)
+   {
+      setProjection(proj, ownsTheView);
+
+      return true;
+   }
+
+   return false;
+}
+
+ossimObject* ossimGeoAnnotationSource::getView()
+{
+   return theProjection;
+}
+
+const ossimObject* ossimGeoAnnotationSource::getView()const
+{
+   return theProjection;
+}
+
+void ossimGeoAnnotationSource::computeBoundingRect()
+{
+//   static const char *MODULE = "ossimAnnotationSource::computeBoundingRect";
+   
+   theRectangle.makeNan();
+
+   if(theAnnotationObjectList.size()>0)
+   {
+      ossimDrect rect;
+      theAnnotationObjectList[0]->getBoundingRect(theRectangle);
+      
+      vector<ossimAnnotationObject*>::iterator object = (theAnnotationObjectList.begin()+1);
+      while(object != theAnnotationObjectList.end())
+      {
+         (*object)->getBoundingRect(rect);
+         theRectangle = theRectangle.combine(rect);
+         ++object;
+      }
+   }
+}
+
+void ossimGeoAnnotationSource::transformObjects(ossimProjection* projection)
+{
+   if(!theProjection && !projection)
+   {
+      return;
+   }
+   if(!projection)
+   {
+      projection = theProjection;
+   }
+
+   if(!theProjection) return;
+   vector<ossimAnnotationObject*>::iterator currentObject;
+
+   currentObject = theAnnotationObjectList.begin();
+
+   while(currentObject != theAnnotationObjectList.end())
+   {
+      // this is safe since we trapped all adds to make
+      // sure that each object added to the list is
+      // geographic.
+      ossimGeoAnnotationObject* object = static_cast<ossimGeoAnnotationObject*>(*currentObject);
+
+      // transform the object to image space.
+      object->transform(projection);
+
+      ++currentObject;
+   }
+   computeBoundingRect();
+}
+
+void ossimGeoAnnotationSource::removeProjection()
+{
+   if(theProjection&&theOwnsProjectionFlag)
+   {
+      delete theProjection;
+   }
+
+   theProjection = NULL;
+}
+
+bool ossimGeoAnnotationSource::getImageGeometry(ossimKeywordlist& kwl,
+						const char* prefix)
+{
+  if(theProjection)
+    {
+      theProjection->saveState(kwl, prefix);
+      return true;
+    }
+  return ossimImageSource::getImageGeometry(kwl, prefix);
+}
+
+bool ossimGeoAnnotationSource::saveState(ossimKeywordlist& kwl,
+                                         const char* prefix)const
+{
+   return ossimAnnotationSource::saveState(kwl, prefix);
+}
+
+
+bool ossimGeoAnnotationSource::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl,"view_proj.");
+
+   if(proj)
+   {
+      removeProjection();
+      theOwnsProjectionFlag = true;
+      theProjection = proj;
+   }
+   
+   return ossimAnnotationSource::loadState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationSource.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationSource.h
new file mode 100644
index 0000000000..2fb28210fd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeoAnnotationSource.h
@@ -0,0 +1,75 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*******************************************************************
+// $Id: ossimGeoAnnotationSource.h,v 1.8 2005/12/07 18:56:13 dburken Exp $
+#ifndef ossimGeoAnnotationSource_HEADER
+#define ossimGeoAnnotationSource_HEADER
+
+#include <iostream>
+#include <imaging/annotation/ossimAnnotationSource.h>
+#include <base/common/ossimViewInterface.h>
+
+class ossimGeoAnnotationObject;
+class ossimProjection;
+
+class OSSIM_DLL ossimGeoAnnotationSource :
+   public ossimAnnotationSource,
+   public ossimViewInterface
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimGeoAnnotationSource& rhs);
+   ossimGeoAnnotationSource(ossimProjection* projection=NULL,
+                            bool ownsProjectionFlag=false);
+
+   ossimGeoAnnotationSource(ossimImageSource* inputSource,
+                            ossimProjection* projection=NULL,
+                            bool ownsProjectionFlag=false);
+
+   virtual ~ossimGeoAnnotationSource();
+   
+   /*!
+    * Will add an object to the list.
+    * it will own the object added.  If the
+    * object is not geographic 
+    */
+   virtual bool addObject(ossimAnnotationObject* anObject);
+   virtual void computeBoundingRect();
+   virtual void transformObjects(ossimProjection* projection=0);
+   virtual void setProjection(ossimProjection* projection,
+                              bool ownsProjectionFlag=false);
+   virtual bool setView(ossimObject* baseObject,
+                        bool ownsTheView = false);
+    virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+  
+   virtual ossimObject*       getView();
+   virtual const ossimObject* getView()const;
+
+   /**
+    * Saves the current state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+protected:
+   ossimProjection* theProjection;
+   bool           theOwnsProjectionFlag;
+   
+   void removeProjection();
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeographicAnnotationGrid.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeographicAnnotationGrid.cpp
new file mode 100644
index 0000000000..b61d2d7334
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeographicAnnotationGrid.cpp
@@ -0,0 +1,283 @@
+#include "ossimGeographicAnnotationGrid.h"
+#include "projections/map_projections/ossimMapProjection.h"
+#include "imaging/ossimRgbImage.h"
+#include "base/data_types/ossimGrect.h"
+#include "ossimAnnotationLineObject.h"
+#include "ossimAnnotationGdBitmapFont.h"
+#include "base/data_types/ossimDms.h"
+#include "base/common/ossimTrace.h"
+
+
+static ossimTrace traceDebug("ossimGeographicAnnotationGrid:debug");
+
+ossimGeographicAnnotationGrid::ossimGeographicAnnotationGrid()
+   : ossimAnnotationObject(),
+     theViewProjection(NULL),
+     theGroundRect(0,0,0,0),
+     theDeltaLatSpacing(1.0/60.0), // every minute
+     theDeltaLonSpacing(1.0/60.0)
+{
+}
+
+void ossimGeographicAnnotationGrid::draw(ossimRgbImage& anImage)const
+
+{
+   if(!anImage.getImageData())
+   {
+      return;
+   }
+   anImage.setDrawColor(theRed, theGreen,theBlue);
+   
+   if((fabs(theDeltaLatSpacing) <= DBL_EPSILON)||
+      (fabs(theDeltaLonSpacing) <= DBL_EPSILON))
+   {
+      return;
+   }
+
+//   ossimDrect imageRect = anImage.getImageData()->getImageRectangle();
+   // If the view projection exists we will use it to
+   // compute the bounding ground rect and find all lines
+   // that overlap that area in the lat and lon direction
+   // and draw them.
+   //
+   // I the projection doesn't exist we will assume that
+   // the geographic grid to generate will be 0,0 is origin
+   // -180lon and 90lat.
+   //
+   if(theViewProjection)
+   {
+      ossimAnnotationLineObject *line=NULL;
+      ossimAnnotationGdBitmapFont *font=NULL;
+      
+      line = new ossimAnnotationLineObject();
+      font = new ossimAnnotationGdBitmapFont();
+      
+      ossimDpt start;
+      ossimDpt end;
+      ossimGpt groundUpper(0,0,0,theGroundRect.ul().datum());
+      ossimGpt groundLower(0,0,0,theGroundRect.ul().datum());
+      double height = theGroundRect.height();
+      double width  = theGroundRect.width();
+      double lat = theGroundRect.ul().latd();
+//      ossimDrect imageRect = anImage.getImageData()->getImageRectangle();
+      double lon;
+
+      // used for the font spacing
+      ossimDrect boundingRect;
+      
+      // we will go across the longitudinal direction first
+      for(lon = theGroundRect.ul().lond()+theDeltaLonSpacing;
+          lon <= theGroundRect.ur().lond();
+          lon += theDeltaLonSpacing)
+      {
+         groundUpper.lond(lon);
+         groundUpper.latd(lat);
+         groundLower.lond(lon);
+         groundLower.latd(lat-height);
+
+         theViewProjection->worldToLineSample(groundUpper, start);
+         theViewProjection->worldToLineSample(groundLower, end);
+
+         line->setLine(start, end);
+         line->draw(anImage);
+      }
+      lon = theGroundRect.ul().lond();
+
+      // now go accross longitude and place the
+      // text in.
+      for(lon = theGroundRect.ul().lond()+theDeltaLonSpacing;
+          lon <= theGroundRect.ur().lond();
+          lon += theDeltaLonSpacing)
+      {
+         groundUpper.lond(lon);
+         groundUpper.latd(lat);
+         groundLower.lond(lon);
+         groundLower.latd(lat-height);
+
+         theViewProjection->worldToLineSample(groundUpper, start);
+         theViewProjection->worldToLineSample(groundLower, end);
+         font->setText(ossimDms(groundUpper.lond(), false).toString("ddd@mm'ss.ssss\"C"));
+         font->getBoundingRect(boundingRect);
+         start.y -= boundingRect.height();
+         font->setCenterTextPosition(start);
+         font->draw(anImage);
+
+         end.y   += boundingRect.height();
+         font->setCenterText(end,
+                             ossimDms(groundLower.lond(), false).toString("ddd@mm'ss.ssssC"));
+         font->draw(anImage);
+      }
+      lon = theGroundRect.ul().lond();
+
+      ossimGpt groundLeft;
+      ossimGpt groundRight;
+      
+      // Now go down lat direction
+      for(lat =  theGroundRect.ul().latd()-theDeltaLatSpacing;
+          lat >= theGroundRect.lr().latd();
+          lat -= theDeltaLatSpacing)
+      {
+         groundLeft.lond(lon);
+         groundLeft.latd(lat);
+         groundRight.lond(lon+width);
+         groundRight.latd(lat);
+
+         theViewProjection->worldToLineSample(groundLeft,  start);
+         theViewProjection->worldToLineSample(groundRight, end);
+         
+         line->setLine(start, end);
+         line->draw(anImage);
+      }
+
+      // now go down lat direction font
+      for(lat =  theGroundRect.ul().latd()-theDeltaLatSpacing;
+          lat >= theGroundRect.lr().latd();
+          lat -= theDeltaLatSpacing)
+      {
+         groundLeft.lond(lon);
+         groundLeft.latd(lat);
+         groundRight.lond(lon+width);
+         groundRight.latd(lat);
+
+         theViewProjection->worldToLineSample(groundLeft, start);
+         theViewProjection->worldToLineSample(groundRight, end);
+
+         
+         font->setText(ossimDms(groundLeft.latd()).toString("ddd@mm'ss.ssss\"C"));
+         font->getBoundingRect(boundingRect);
+         start.x -= boundingRect.width()/2.0-1;
+         font->setCenterTextPosition(start);
+         font->draw(anImage);
+
+         end.x  += boundingRect.width()/2.0+1;
+         font->setCenterText(end,
+                             ossimDms(groundRight.latd()).toString("ddd@mm'ss.ssssC"));
+         font->draw(anImage);
+      }
+
+      delete line;
+      line = NULL;
+      delete font;
+      font = NULL;
+   }
+}
+
+
+void ossimGeographicAnnotationGrid::setViewProjectionInformation(ossimMapProjection* projection,
+                                                                 const ossimGrect& boundingGroundRect)
+{
+   static const char* MODULE = "ossimGeographicAnnotationGrid::setViewProjectionInformation";
+   theViewProjection = projection;
+
+   // set the ground and then stretch it
+   // to cover which even degree grid we are currently
+   // in.
+   theGroundRect     = boundingGroundRect;
+
+   // find the even degree grid.
+   ossimGrect rect(ossimGpt(90, -180),
+                   ossimGpt(-90, 180));
+
+   // make sure that it is within the range of the
+   // geographic grid.
+   ossimGrect clipRect = rect.clipToRect(boundingGroundRect);
+
+   // for easier math we will shift the points so they
+   // are between 0..360Lon and 0..180Lat.  This way
+   // we are working with just positive numbers
+   double upperLeftLonShift   = clipRect.ul().lond() + 180;
+   double upperLeftLatShift   = clipRect.ul().latd() + 90;
+   double lowerRightLonShift   = clipRect.lr().lond() + 180;
+   double lowerRightLatShift   = clipRect.lr().latd() + 90;
+
+   // now find the even boundaries
+   double upperLeftLonCell = floor(upperLeftLonShift/theDeltaLonSpacing)*
+                             theDeltaLonSpacing;
+   double upperLeftLatCell  = floor(upperLeftLatShift/theDeltaLatSpacing)*
+                              theDeltaLatSpacing;
+   double lowerRightLonCell = floor(lowerRightLonShift/theDeltaLonSpacing)*
+                              theDeltaLonSpacing;
+   double lowerRightLatCell  = floor(lowerRightLatShift/theDeltaLatSpacing)*
+                               theDeltaLatSpacing;
+
+   // now adjust them by 1 boundary distance.
+   upperLeftLonCell  -= theDeltaLonSpacing;
+   upperLeftLatCell  += theDeltaLatSpacing;
+   lowerRightLonCell += theDeltaLonSpacing;
+   lowerRightLatCell -= theDeltaLatSpacing;
+
+   // now clamp to the range of the lat and lon
+   upperLeftLonCell  = (upperLeftLonCell<0?0:upperLeftLonCell);
+   upperLeftLatCell  = (upperLeftLatCell>180?180:upperLeftLatCell);
+   lowerRightLonCell = (lowerRightLonCell>360?360:lowerRightLonCell);
+   lowerRightLatCell = (lowerRightLatCell<0?0:lowerRightLatCell);
+
+   // now shift them back into range
+   upperLeftLonCell  -= 180;
+   upperLeftLatCell  -= 90;
+   lowerRightLonCell -= 180;
+   lowerRightLatCell -= 90;
+   
+   const ossimDatum* datum = theGroundRect.ul().datum();
+   theGroundRect = ossimGrect(upperLeftLatCell, upperLeftLonCell,
+                              lowerRightLatCell, lowerRightLonCell,
+                              datum);
+
+   if(traceDebug())
+   {
+      CLOG << "Ground Rect: " << theGroundRect << endl;
+   }
+   computeBoundingRect();
+}
+
+void ossimGeographicAnnotationGrid::getBoundingRect(ossimDrect& rect)const
+{
+   rect = theBoundingRect;
+}
+
+void ossimGeographicAnnotationGrid::computeBoundingRect()
+{
+   static const char* MODULE = "ossimGeographicAnnotationGrid::computeBoundingRect";
+   
+   if(theViewProjection)
+   {
+      vector<ossimDpt> points(4);
+
+      theViewProjection->worldToLineSample(theGroundRect.ul(), points[0]);
+      theViewProjection->worldToLineSample(theGroundRect.ll(), points[1]);
+      theViewProjection->worldToLineSample(theGroundRect.lr(), points[2]);
+      theViewProjection->worldToLineSample(theGroundRect.ur(), points[3]);
+
+      // now solve the bounding rect in view space.
+      theBoundingRect = ossimDrect(points);
+
+      // for now we will add a border for the labelling
+      // of lat lon readouts.  We need a better border
+      // computation that checks exactly what we need
+      // based on font sizes.
+      //
+      ossimDpt ul = theBoundingRect.ul();
+      ossimDpt lr = theBoundingRect.lr();
+
+      
+      ossimAnnotationGdBitmapFont font;
+      font.setCenterText(ossimDpt(0,0),"ddd@mm'ss.ssssC");
+      ossimDrect boundingRect;
+      font.getBoundingRect(boundingRect);
+      
+      theBoundingRect = ossimDrect(ul.x - boundingRect.width(),
+                                   ul.y - boundingRect.height(),
+                                   lr.x + boundingRect.width(),
+                                   lr.y + boundingRect.height());
+
+      if(traceDebug())
+      {
+         CLOG << " bounding rect: " << theBoundingRect << endl;
+      }
+   }
+}
+
+std::ostream& ossimGeographicAnnotationGrid::print(std::ostream& out)const
+{
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeographicAnnotationGrid.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeographicAnnotationGrid.h
new file mode 100644
index 0000000000..3b5fc0a882
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimGeographicAnnotationGrid.h
@@ -0,0 +1,52 @@
+#ifndef ossimGeographicAnnotationGrid_HEADER
+#define ossimGeographicAnnotationGrid_HEADER
+#include "ossimAnnotationObject.h"
+#include "base/data_types/ossimGpt.h"
+#include "base/data_types/ossimGrect.h"
+#include "base/data_types/ossimDrect.h"
+
+class ossimMapProjection;
+
+class ossimGeographicAnnotationGrid : public ossimAnnotationObject
+{
+public:
+   ossimGeographicAnnotationGrid();
+
+   virtual void draw(ossimRgbImage& anImage)const;
+
+   /*!
+    * We need to know what projection the view
+    * and we need to know the bounding rect for
+    * the view in geographic space.  The bounding
+    * rect is there for an area of interest.
+    */
+   virtual void setViewProjectionInformation(ossimMapProjection* projection,
+                                             const ossimGrect& boundingGroundRect);
+
+   virtual void getBoundingRect(ossimDrect& rect)const;
+   virtual void computeBoundingRect();
+   virtual std::ostream& print(std::ostream& out)const;
+
+protected:
+   /*!
+    * Holds the view projection.
+    */
+   ossimMapProjection* theViewProjection;
+
+   ossimGrect       theGroundRect;
+
+   /*!
+    * This will be computed based on the bounding
+    * ground and projection.
+    */
+   ossimDrect       theBoundingRect;
+   
+   /*!
+    * Will hold the spacing of the grid cells in
+    * geographic lat lon change.
+    */
+   double theDeltaLatSpacing;
+   double theDeltaLonSpacing;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimMapCompositionSource.cpp b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimMapCompositionSource.cpp
new file mode 100644
index 0000000000..55874d4745
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimMapCompositionSource.cpp
@@ -0,0 +1,4032 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimMapCompositionSource.cpp,v 1.41 2005/09/09 19:23:58 gpotts Exp $
+
+#include <imaging/annotation/ossimMapCompositionSource.h>
+#include <imaging/ossimU8ImageData.h>
+#include <imaging/ossimImageDataHelper.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <imaging/annotation/ossimAnnotationFontObject.h>
+#include <imaging/annotation/ossimAnnotationLineObject.h>
+#include <fonts/factory/ossimFontFactoryRegistry.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimDms.h>
+#include <base/common/ossimTrace.h>
+#include <base/property/ossimColorProperty.h>
+#include <base/property/ossimContainerProperty.h>
+#include <base/property/ossimFontProperty.h>
+#include <base/property/ossimBooleanProperty.h>
+#include <base/property/ossimTextProperty.h>
+#include <base/property/ossimNumericProperty.h>
+#include <base/property/ossimStringProperty.h>
+
+#include <sstream>
+using namespace std;
+
+static const char* GRID_TYPE_ENUM_NAMES[] = {"none",
+                                             "line",
+                                             "reseaux"};
+
+static const char* VIEW_WIDTH_KW              = "view_width";
+static const char* VIEW_HEIGHT_KW             = "view_height";
+static const char* METER_GRID_SPACING_X_KW    = "meter_grid_spacing_x";
+static const char* METER_GRID_SPACING_Y_KW    = "meter_grid_spacing_y";
+static const char* GEO_GRID_SPACING_LON_KW    = "geo_grid_spacing_lon";
+static const char* GEO_GRID_SPACING_LAT_KW    = "geo_grid_spacing_lat";
+static const char* METER_GRID_TYPE_KW         = "meter_grid_type";
+static const char* GEO_GRID_TYPE_KW           = "geo_grid_type";
+static const char* TOP_BORDER_LENGTH_KW       = "top_border_length";
+static const char* BOTTOM_BORDER_LENGTH_KW    = "bottom_border_length";
+static const char* LEFT_BORDER_LENGTH_KW      = "top_border_length";
+static const char* RIGHT_BORDER_LENGTH_KW     = "right_border_length";
+static const char* BORDER_COLOR_KW            = "border_color";
+static const char* GEO_GRID_COLOR_KW          = "geo_grid_color";
+static const char* METER_GRID_COLOR_KW        = "meter_grid_color";
+static const char* TITLE_STRING_KW            = "title_string";
+static const char* TITLE_COLOR_KW             = "title_color";
+
+static const char* TOP_GEO_LABEL_COLOR_KW     = "top_geo_label_color";
+static const char* BOTTOM_GEO_LABEL_COLOR_KW  = "bottom_geo_label_color";
+static const char* LEFT_GEO_LABEL_COLOR_KW    = "left_geo_label_color";
+static const char* RIGHT_GEO_LABEL_COLOR_KW   = "right_geo_label_color";
+
+static const char* TOP_METER_LABEL_COLOR_KW     = "top_meter_label_color";
+static const char* BOTTOM_METER_LABEL_COLOR_KW  = "bottom_meter_label_color";
+static const char* LEFT_METER_LABEL_COLOR_KW    = "left_meter_label_color";
+static const char* RIGHT_METER_LABEL_COLOR_KW   = "right_meter_label_color";
+
+
+static const char* TOP_GEO_LABEL_FORMAT_KW    = "top_geo_label_format";
+static const char* BOTTOM_GEO_LABEL_FORMAT_KW = "bottom_geo_label_format";
+static const char* LEFT_GEO_LABEL_FORMAT_KW   = "left_geo_label_format";
+static const char* RIGHT_GEO_LABEL_FORMAT_KW  = "right_geo_label_format";
+
+static const char* TOP_GEO_LABEL_FLAG_KW      = "top_geo_label_flag";
+static const char* BOTTOM_GEO_LABEL_FLAG_KW   = "bottom_geo_label_flag";
+static const char* LEFT_GEO_LABEL_FLAG_KW     = "left_geo_label_flag";
+static const char* RIGHT_GEO_LABEL_FLAG_KW    = "right_geo_label_flag";
+
+static const char* TOP_METER_LABEL_FLAG_KW    = "top_meter_label_flag";
+static const char* BOTTOM_METER_LABEL_FLAG_KW = "bottom_meter_label_flag";
+static const char* LEFT_METER_LABEL_FLAG_KW   = "left_meter_label_flag";
+static const char* RIGHT_METER_LABEL_FLAG_KW  = "right_meter_label_flag";
+
+static const char* TOP_GEO_LABEL_FONT_KW      = "top_geo_label_font";
+static const char* BOTTOM_GEO_LABEL_FONT_KW   = "bottom_geo_label_font";
+static const char* LEFT_GEO_LABEL_FONT_KW     = "left_geo_label_font";
+static const char* RIGHT_GEO_LABEL_FONT_KW    = "right_geo_label_font";
+static const char* TOP_METER_LABEL_FONT_KW    = "top_meter_label_font";
+static const char* BOTTOM_METER_LABEL_FONT_KW = "bottom_meter_label_font";
+static const char* LEFT_METER_LABEL_FONT_KW   = "left_meter_label_font";
+static const char* RIGHT_METER_LABEL_FONT_KW  = "right_meter_label_font";
+static const char* TITLE_FONT_KW              = "title_font";
+
+static ossimTrace traceDebug("ossimMapCompositionSource:debug");
+
+RTTI_DEF1(ossimMapCompositionSource, "ossimMapCompositionSource", ossimAnnotationSource);
+ossimMapCompositionSource::ossimMapCompositionSource()
+   :ossimAnnotationSource(),
+    theMeterGridType(OSSIM_GRID_NONE),
+    theGeographicGridType(OSSIM_GRID_LINE),
+    theTopBorderLength(200),
+    theBottomBorderLength(200),
+    theLeftBorderLength(300),
+    theRightBorderLength(300),
+    theBorderColor(255,255,255),
+    theGeographicGridColor(255,255,255),
+    theMeterGridColor(255,255,255),
+    theTitleString(""),
+    theTitleFont(NULL),
+    theTitleColor(1, 1, 1),
+    theTopGeographicLabelColor(1, 1, 1),
+    theBottomGeographicLabelColor(1, 1, 1),
+    theLeftGeographicLabelColor(1, 1, 1),
+    theRightGeographicLabelColor(1, 1, 1),
+    theTopMeterLabelColor(1, 1, 1),
+    theBottomMeterLabelColor(1, 1, 1),
+    theLeftMeterLabelColor(1, 1, 1),
+    theRightMeterLabelColor(1, 1, 1),
+    theGeographicTopLabelFont(NULL),
+    theGeographicBottomLabelFont(NULL),
+    theGeographicLeftLabelFont(NULL),
+    theGeographicRightLabelFont(NULL),
+    theMeterTopLabelFont(NULL),
+    theMeterBottomLabelFont(NULL),
+    theMeterLeftLabelFont(NULL),
+    theMeterRightLabelFont(NULL),
+    theTopGeographicFormat("dd@mm'ss\".ssssC"),
+    theBottomGeographicFormat("dd@mm'ss\".ssssC"),
+    theLeftGeographicFormat("dd@mm'ss\".ssssC"),
+    theRightGeographicFormat("dd@mm'ss\".ssssC"),
+    theTopGeographicLabelFlag(true),
+    theBottomGeographicLabelFlag(true),
+    theLeftGeographicLabelFlag(true),
+    theRightGeographicLabelFlag(true),
+    theTopGeographicTickFlag(true),
+    theBottomGeographicTickFlag(true),
+    theLeftGeographicTickFlag(true),
+    theRightGeographicTickFlag(true),
+    theTopMeterLabelFlag(false),
+    theBottomMeterLabelFlag(false),
+    theLeftMeterLabelFlag(false),
+    theRightMeterLabelFlag(false),
+    theTopMeterTickFlag(false),
+    theBottomMeterTickFlag(false),
+    theLeftMeterTickFlag(false),
+    theRightMeterTickFlag(false),
+    theGeographicSpacing(1.0, 1.0),
+    theMeterSpacing(3600*30, 3600*30),
+    theInputProjection(NULL)
+{
+   theViewWidthHeight = ossimIpt(-1,-1);
+   vector<ossimFontInformation> info;
+   ossimFontFactoryRegistry::instance()->getFontInformation(info);
+
+   if(info.size())
+   {
+      theGeographicTopLabelFont = ossimFontFactoryRegistry::instance()->createFont(info[0]);
+      theGeographicTopLabelFontInfo = info[0];
+      theGeographicTopLabelFontInfo.thePointSize = ossimIpt(12,12);
+
+      if(theGeographicTopLabelFont)
+      {
+         theGeographicBottomLabelFont     = (ossimFont*)theGeographicTopLabelFont->dup();
+         theGeographicBottomLabelFontInfo = theGeographicTopLabelFontInfo;
+         theGeographicLeftLabelFont       = (ossimFont*)theGeographicTopLabelFont->dup();
+         theGeographicLeftLabelFontInfo   = theGeographicTopLabelFontInfo;
+         theGeographicRightLabelFont      = (ossimFont*)theGeographicTopLabelFont->dup();
+         theGeographicRightLabelFontInfo  = theGeographicTopLabelFontInfo;
+
+         theMeterTopLabelFont             = (ossimFont*)theGeographicTopLabelFont->dup();
+         theMeterTopLabelFontInfo         = theGeographicTopLabelFontInfo;
+         theMeterBottomLabelFont          = (ossimFont*)theGeographicTopLabelFont->dup();
+         theMeterBottomLabelFontInfo      = theGeographicTopLabelFontInfo;
+         theMeterLeftLabelFont            = (ossimFont*)theGeographicTopLabelFont->dup();
+         theMeterLeftLabelFontInfo        = theGeographicTopLabelFontInfo;
+         theMeterRightLabelFont           = (ossimFont*)theGeographicTopLabelFont->dup();
+         theMeterRightLabelFontInfo       = theGeographicTopLabelFontInfo;
+         
+         theTitleFont                     = (ossimFont*)theGeographicTopLabelFont->dup();
+         theTitleFontInfo                 = theGeographicTopLabelFontInfo;
+         theTitleFontInfo.thePointSize    = ossimIpt(48, 48);
+      }
+   }
+}
+
+ossimMapCompositionSource::~ossimMapCompositionSource()
+{
+   if(theInputProjection)
+   {
+      delete theInputProjection;
+      theInputProjection = NULL;
+   }
+   
+   if(theGeographicTopLabelFont)
+   {
+      delete theGeographicTopLabelFont;
+      theGeographicTopLabelFont = NULL;
+   }
+   if(theGeographicBottomLabelFont)
+   {
+      delete theGeographicBottomLabelFont;
+      theGeographicBottomLabelFont = NULL;
+   }
+   if(theGeographicLeftLabelFont)
+   {
+      delete theGeographicLeftLabelFont;
+      theGeographicLeftLabelFont = NULL;
+   }
+   if(theGeographicRightLabelFont)
+   {
+      delete theGeographicRightLabelFont;
+      theGeographicRightLabelFont = NULL;
+   }
+
+   if(theMeterTopLabelFont)
+   {
+      delete theMeterTopLabelFont;
+      theMeterTopLabelFont = NULL;
+   }
+   
+   if(theMeterBottomLabelFont)
+   {
+      delete theMeterBottomLabelFont;
+      theMeterBottomLabelFont = NULL;
+   }
+
+   if(theMeterLeftLabelFont)
+   {
+      delete theMeterLeftLabelFont;
+      theMeterLeftLabelFont = NULL;
+   }
+
+   if(theMeterRightLabelFont)
+   {
+      delete theMeterRightLabelFont;
+      theMeterRightLabelFont = NULL;
+   }
+   
+   if(theTitleFont)
+   {
+      delete theTitleFont;
+      theTitleFont = NULL;
+   }
+   deleteFixedAnnotations();
+}
+
+ossimRefPtr<ossimImageData> ossimMapCompositionSource::getTile(const ossimIrect& tileRect,
+                                                   ossim_uint32 resLevel)
+{
+   if(!theTile)
+   {
+      allocate(tileRect);
+      if(!theTile)
+      {
+         if(theInputConnection)
+         {
+            return theInputConnection->getTile(tileRect, resLevel);
+         }
+      }
+   }
+   theTile->setImageRectangle(tileRect);
+   theTile->makeBlank();
+   
+   if(theInputConnection)
+   {
+      ossimRefPtr<ossimImageData> tile = theInputConnection->getTile(tileRect,
+                                                                     resLevel);
+
+      if(tile.valid())
+      {
+         if(tile->getScalarType() != OSSIM_UCHAR)
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "ossimMapCompositionSource::getTile\n"
+               << "Error input is not uchar" << endl;
+            return tile;
+         }
+         else
+         {
+            if(tile->getBuf()&&(tile->getDataObjectStatus() != OSSIM_EMPTY))
+            {
+               int band = 0;
+               int outBands = theTile->getNumberOfBands();
+               int minBand = std::min((long)theTile->getNumberOfBands(),
+                                      (long)tile->getNumberOfBands());
+               for(band = 0; band < minBand; ++band)
+               {
+                  theTile->loadBand(tile->getBuf(band),
+                                    tile->getImageRectangle(),
+                                    band);
+               }
+               // copy last band of input tile to all output
+               // bands if the input tile did not have enough bands.
+               //
+               for(;band < outBands;++band)
+               {
+                  theTile->loadBand(tile->getBuf(minBand-1),
+                                    tile->getImageRectangle(),
+                                    band);
+               }
+            }
+	    drawBorders();
+	    drawAnnotations(theTile);
+         }
+      }
+   }
+   theTile->validate();
+   return theTile;
+}
+
+void ossimMapCompositionSource::setGeographicLabelFormat(const ossimString format)
+{
+   if( (format == theTopGeographicFormat)&&
+       (format == theBottomGeographicFormat)&&
+       (format == theLeftGeographicFormat)&&
+       (format == theRightGeographicFormat))
+   {
+      return;
+   }
+   theTopGeographicFormat    = format;
+   theBottomGeographicFormat = format;
+   theLeftGeographicFormat   = format;
+   theRightGeographicFormat  = format;
+}
+
+void ossimMapCompositionSource::setTopGeographicLabelFormat(const ossimString& format)
+{
+   if(format == theTopGeographicFormat)
+   {
+      return;
+   }
+   theTopGeographicFormat = format;
+}
+
+void ossimMapCompositionSource::setBottomGeographicLabelFormat(const ossimString& format)
+{
+   if(format == theBottomGeographicFormat)
+   {
+      return;
+   }
+   theBottomGeographicFormat = format;
+
+   // need to reset the fonts
+//   layoutAnnotations();
+}
+
+void ossimMapCompositionSource::setLeftGeographicLabelFormat(const ossimString& format)
+{
+   if(format == theLeftGeographicFormat)
+   {
+      return;
+   }
+   theLeftGeographicFormat = format;
+
+   // need to reset the fonts
+//   layoutAnnotations();
+}
+
+void ossimMapCompositionSource::setRightGeographicLabelFormat(const ossimString& format)
+{
+   if(format == theRightGeographicFormat)
+   {
+      return;
+   }
+   theRightGeographicFormat = format;
+
+}
+
+void ossimMapCompositionSource::setTitleFont(const ossimFontInformation& fontInfo)
+{
+   if(theTitleFontInfo == fontInfo)
+   {
+      return;
+   }
+   ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(fontInfo);
+   if(font)
+   {
+      if(theTitleFont)
+      {
+         delete theTitleFont;
+         theTitleFont = NULL;
+      }
+
+      theTitleFont     = font;
+      theTitleFontInfo = fontInfo;      
+   }
+}
+
+void ossimMapCompositionSource::setGeographicTopLabelFont(const ossimFontInformation& fontInfo)
+{
+   const char* MODULE = "ossimMapCompositionSource::setGeographicTopLabelFont";
+   
+   if(traceDebug())
+   {
+      CLOG << "Entering...." <<endl;
+   }
+   if(theGeographicTopLabelFontInfo == fontInfo)
+   {
+      if(traceDebug())
+      {
+         CLOG << "Font info the same exiting...." <<endl
+              << theGeographicTopLabelFontInfo << endl;
+      }
+      
+      return;
+   }
+   ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(fontInfo);
+
+   if(font)
+   {
+      if(theGeographicTopLabelFont)
+      {
+         delete theGeographicTopLabelFont;
+         theGeographicTopLabelFont = NULL;
+      }
+      
+      if(traceDebug())
+      {
+         CLOG << "Previous font info " <<endl
+              << theGeographicTopLabelFont << endl;
+      }
+      theGeographicTopLabelFont = font;
+      theGeographicTopLabelFontInfo = fontInfo;
+
+      if(traceDebug())
+      {
+         CLOG << "New font info " <<endl
+              << theGeographicTopLabelFont << endl;
+      }      
+   }
+}
+
+void ossimMapCompositionSource::setGeographicBottomLabelFont(const ossimFontInformation& fontInfo)
+{
+   if(theGeographicBottomLabelFontInfo == fontInfo)
+   {
+      return;
+   }
+   ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(fontInfo);
+
+   if(font)
+   {
+      if(theGeographicBottomLabelFont)
+      {
+         delete theGeographicBottomLabelFont;
+         theGeographicBottomLabelFont = NULL;
+      }
+      
+      theGeographicBottomLabelFont     = font;
+      theGeographicBottomLabelFontInfo = fontInfo;
+
+   }
+}
+
+void ossimMapCompositionSource::setGeographicLeftLabelFont(const ossimFontInformation& fontInfo)
+{
+   if(theGeographicRightLabelFontInfo == fontInfo)
+   {
+      return;
+   }
+   ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(fontInfo);
+
+   if(font)
+   {
+      if(theGeographicLeftLabelFont)
+      {
+         delete theGeographicLeftLabelFont;
+         theGeographicLeftLabelFont = NULL;
+      }
+      
+      theGeographicLeftLabelFont     = font;
+      theGeographicLeftLabelFontInfo = fontInfo;
+
+   }
+}
+
+void ossimMapCompositionSource::setGeographicRightLabelFont(const ossimFontInformation& fontInfo)
+{
+   if(theGeographicRightLabelFontInfo == fontInfo)
+   {
+      return;
+   }
+   
+   ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(fontInfo);
+
+   if(font)
+   {
+      if(theGeographicRightLabelFont)
+      {
+         delete theGeographicRightLabelFont;
+         theGeographicRightLabelFont = NULL;
+      }
+      
+      theGeographicRightLabelFont = font;
+      theGeographicRightLabelFontInfo = fontInfo;
+   }
+}
+
+
+void ossimMapCompositionSource::setMeterTopLabelFont(const ossimFontInformation& fontInfo)
+{
+   if(theMeterTopLabelFontInfo == fontInfo)
+   {
+      return;
+   }
+   ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(fontInfo);
+
+   if(font)
+   {
+      if(theMeterTopLabelFont)
+      {
+         delete theMeterTopLabelFont;
+         theMeterTopLabelFont = NULL;
+      }
+      
+      theMeterTopLabelFont     = font;
+      theMeterTopLabelFontInfo = fontInfo;
+   }
+}
+
+void ossimMapCompositionSource::setMeterBottomLabelFont(const ossimFontInformation& fontInfo)
+{
+   if(theMeterBottomLabelFontInfo == fontInfo)
+   {
+      return;
+   }
+   ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(fontInfo);
+
+   if(font)
+   {
+      if(theMeterBottomLabelFont)
+      {
+         delete theMeterBottomLabelFont;
+         theMeterBottomLabelFont = NULL;
+      }
+      
+      theMeterBottomLabelFont     = font;
+      theMeterBottomLabelFontInfo = fontInfo;
+   }
+}
+
+void ossimMapCompositionSource::setMeterLeftLabelFont(const ossimFontInformation& fontInfo)
+{
+   if(theMeterLeftLabelFontInfo == fontInfo)
+   {
+      return;
+   }
+   ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(fontInfo);
+
+   if(font)
+   {
+      if(theMeterLeftLabelFont)
+      {
+         delete theMeterLeftLabelFont;
+         theMeterLeftLabelFont = NULL;
+      }
+      
+      theMeterLeftLabelFont     = font;
+      theMeterLeftLabelFontInfo = fontInfo;
+   }
+}
+
+void ossimMapCompositionSource::setMeterRightLabelFont(const ossimFontInformation& fontInfo)
+{
+   if(theMeterRightLabelFontInfo == fontInfo)
+   {
+      return;
+   }
+   ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(fontInfo);
+
+   if(font)
+   {
+      if(theMeterRightLabelFont)
+      {
+         delete theMeterRightLabelFont;
+         theMeterRightLabelFont = NULL;
+      }
+      
+      theMeterRightLabelFont     = font;
+      theMeterRightLabelFontInfo = fontInfo;
+   }
+}
+
+ossimIrect ossimMapCompositionSource::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimIrect result;
+
+   result.makeNan();
+   if(theInputConnection)
+   {
+      ossimIrect inputRect  = getViewingRect();
+
+      if(!inputRect.hasNans())
+      {
+         ossimDpt decimation;
+         getDecimationFactor(resLevel,
+                             decimation);
+         int leftBorderLength   = theLeftBorderLength;
+         int rightBorderLength  = theRightBorderLength;
+         int topBorderLength    = theTopBorderLength;
+         int bottomBorderLength = theBottomBorderLength;
+
+         ossimIpt p1(inputRect.ul().x - leftBorderLength,
+                     inputRect.ul().y - topBorderLength);
+         
+         ossimIpt p2(inputRect.ur().x + rightBorderLength,
+                     inputRect.ur().y - topBorderLength);
+         
+         ossimIpt p3(inputRect.lr().x + rightBorderLength,
+                     inputRect.lr().y + bottomBorderLength);
+         
+         ossimIpt p4(inputRect.ll().x - leftBorderLength,
+                     inputRect.ll().y + bottomBorderLength);
+
+         result = ossimIrect(p1, p2, p3, p4);
+         
+         if(!decimation.hasNans())
+         {
+            result*=decimation;
+         }
+      }
+   }
+   return result;
+}
+
+void ossimMapCompositionSource::layoutAnnotations()
+{
+   deleteFixedAnnotations();
+
+   addTitle();
+   addGridLabels();
+   if(theGeographicGridType == OSSIM_GRID_LINE)
+   {
+      addGeographicGridLines();
+   }
+   else if(theGeographicGridType == OSSIM_GRID_RESEAUX)
+   {
+      addGeographicGridReseaux();
+   }
+   
+   if(theMeterGridType == OSSIM_GRID_LINE)
+   {
+      addMeterGridLines();
+   }
+   else if(theMeterGridType == OSSIM_GRID_RESEAUX)
+   {
+      addMeterGridReseaux();
+   }
+}
+
+
+void ossimMapCompositionSource::initialize()
+{
+   ossimAnnotationSource::initialize();   
+
+   if(theInputConnection)
+   {
+      if(theInputProjection)
+      {
+         delete theInputProjection;
+         theInputProjection = NULL;
+      }
+      
+      computeBorderRects();
+
+      ossimKeywordlist kwl;
+      
+      theInputConnection->getImageGeometry(kwl);
+      ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+      
+      theInputProjection = PTR_CAST(ossimMapProjection, proj);
+      if(!theInputProjection&&proj)
+      {
+         delete proj;
+         proj = NULL;
+      }
+
+      layoutAnnotations();
+   }
+   else 
+   {
+      deleteFixedAnnotations();
+   }
+}
+
+void ossimMapCompositionSource::computeBorderRects()
+{
+   if(theInputConnection)
+   {
+      ossimIrect inputRect = getViewingRect();;
+      
+      theTopBorder = ossimIrect(inputRect.ul().x - theLeftBorderLength,
+                                inputRect.ul().y - theTopBorderLength,
+                                inputRect.ur().x + theRightBorderLength,
+                                inputRect.ur().y);
+      
+      theBottomBorder = ossimIrect(inputRect.ll().x - theLeftBorderLength,
+                                   inputRect.ll().y,
+                                   inputRect.lr().x + theRightBorderLength,
+                                   inputRect.lr().y + theBottomBorderLength);
+      
+      theLeftBorder   = ossimIrect(theTopBorder.ul().x,
+                                   theTopBorder.ll().y,
+                                   inputRect.ll().x,
+                                   inputRect.ll().y);
+      
+      theRightBorder   = ossimIrect(inputRect.ur().x,
+                                    inputRect.ur().y,
+                                    theBottomBorder.lr().x,
+                                    inputRect.lr().y);
+   }
+   else
+   {
+      theTopBorder.makeNan();
+      theBottomBorder.makeNan();
+      theLeftBorder.makeNan();
+      theRightBorder.makeNan();
+   }
+      
+}
+
+void ossimMapCompositionSource::drawBorders()
+{
+   if(theTile.valid())
+   {
+      ossimIrect top    = theTopBorder;
+      ossimIrect bottom = theBottomBorder;
+      ossimIrect left   = theLeftBorder;
+      ossimIrect right  = theRightBorder;
+
+//       if(resLevel)
+//       {
+//          ossimDpt decimation;
+//          getDecimationFactor(resLevel,
+//                              decimation);
+
+//          if(!decimation.hasNans())
+//          {
+//             top*=decimation;
+//             bottom*=decimation;
+//             left*=decimation;
+//             right*=decimation;            
+//          }
+//       }
+      ossimIrect tileRect = theTile->getImageRectangle();
+      
+      ossimImageDataHelper helper(theTile.get());
+      
+      if(top.intersects(tileRect))
+      {
+         helper.fill(theBorderColor,
+                     top.clipToRect(tileRect),false);
+      }
+      if(bottom.intersects(tileRect))
+      {
+         helper.fill(theBorderColor,
+                     bottom.clipToRect(tileRect),false);
+      }
+      if(left.intersects(tileRect))
+      {
+         helper.fill(theBorderColor,
+                     left.clipToRect(tileRect),false);
+      }
+      if(right.intersects(tileRect))
+      {
+         helper.fill(theBorderColor,
+                     right.clipToRect(tileRect),false);
+      }
+   }
+}
+
+void ossimMapCompositionSource::addGridLabels()
+{
+   addGeographicTopGridLabels();
+   addGeographicBottomGridLabels();
+   addGeographicLeftGridLabels();
+   addGeographicRightGridLabels();
+
+   addMeterGridLabels();
+}
+
+void ossimMapCompositionSource::addGeographicTopGridLabels()
+{
+   const char* MODULE = "ossimMapCompositionSource::addGeographicTopGridLabels";
+   if(traceDebug())
+   {
+      CLOG << "Entering...." << endl;
+   }
+   if((!theTopGeographicLabelFlag)&&(!theTopGeographicTickFlag))
+   {
+      if(traceDebug())
+      {
+         CLOG << "Exiting, flags are false...." << endl;
+      }
+      return;
+   }
+   if(theInputConnection&&theInputProjection)
+   { 
+      ossimGpt gpt[4];
+      ossimDrect rect = getViewingRect();
+
+      if(rect.hasNans()) return;
+      theInputProjection->lineSampleToWorld(rect.ul(),
+                                            gpt[0]);
+      theInputProjection->lineSampleToWorld(rect.ur(),
+                                            gpt[1]);
+      theInputProjection->lineSampleToWorld(rect.lr(),
+                                            gpt[2]);
+      theInputProjection->lineSampleToWorld(rect.ll(),
+                                            gpt[3]);
+      
+      ossimDrect grect(gpt[0],
+                       gpt[1],
+                       gpt[2],
+                       gpt[3],
+                       OSSIM_RIGHT_HANDED);
+
+      if(grect.hasNans()) return;
+      ossimDpt ulLatLon(((int)((grect.ul().x-theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.ul().y+theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+      
+      ossimDpt lrLatLon(((int)((grect.lr().x+theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.lr().y-theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+
+      while(ulLatLon.lat > 90)
+      {
+         ulLatLon.lat -= theGeographicSpacing.lat;
+      }
+      while(ulLatLon.lon < -180)
+      {
+         ulLatLon.lon += theGeographicSpacing.lon;
+      }
+      while(lrLatLon.lat < -90)
+      {
+         ulLatLon.lat += theGeographicSpacing.lat;
+      }
+      while(lrLatLon.lon > 180)
+      {
+         ulLatLon.lon -= theGeographicSpacing.lon;
+      }
+      
+      ossimDrect latLonSpacing(ulLatLon,
+                               lrLatLon,
+                               OSSIM_RIGHT_HANDED);
+
+      if(traceDebug())
+      {
+         CLOG << "labeling bounding geo rect = " << latLonSpacing << endl;
+      }
+      // do the top side labels.
+      for(double lon = latLonSpacing.ul().x; lon <= latLonSpacing.lr().x; lon+=theGeographicSpacing.x)
+      {
+         ossimDpt tipt; // top
+         ossimDpt bipt; // bottom
+         
+         ossimGpt tgpt(latLonSpacing.ul().y,
+                       lon,
+                       0.0,
+                       gpt[0].datum());
+
+         ossimGpt bgpt(latLonSpacing.lr().y,
+                       lon,
+                       0.0,
+                       gpt[0].datum());
+         
+         theInputProjection->worldToLineSample(tgpt,
+                                               tipt);
+         
+         theInputProjection->worldToLineSample(bgpt,
+                                               bipt);
+
+         
+         if((!tipt.hasNans()&&
+             !bipt.hasNans()) &&
+            rect.clip(tipt, bipt))
+         {
+            ossimIpt rounded(tipt);
+            if( (rounded.x >= rect.ul().x)&&
+                (rounded.x <= rect.lr().x))
+            {
+               if(theTopGeographicLabelFlag)
+               {
+                  ossimDms dms(tgpt.lond(), false);
+               
+                  ossimString dmsString = dms.toString(theTopGeographicFormat.c_str());
+                  ossimAnnotationFontObject* lonLabel = new ossimAnnotationFontObject(ossimIpt(0,0),
+                                                                                      dmsString);
+                  lonLabel->setFont(theGeographicTopLabelFont, false);
+
+                  lonLabel->setGeometryInformation(theGeographicTopLabelFontInfo);
+                  lonLabel->computeBoundingRect();
+                  ossimDrect boundsD;
+                  lonLabel->getBoundingRect(boundsD);
+                  
+                  ossimIpt center( rounded.x,
+                                   irint(rect.ul().y-(boundsD.height()/2)));
+               
+                  lonLabel->setColor(theTopGeographicLabelColor.getR(), theTopGeographicLabelColor.getG(), theTopGeographicLabelColor.getB());
+                  lonLabel->setPositionCenter(center);
+                  lonLabel->computeBoundingRect();
+
+                  ossimDrect labelRect;
+                  lonLabel->getBoundingRect(labelRect);
+                  
+                  if(rect.intersects(labelRect))
+                  {
+                     ossimIrect intersection = rect.clipToRect(labelRect);
+                     center.y -= irint(rect.ul().y - intersection.lr().y);
+                  }
+
+                  center.y -= 24; // this will need to be the tick height later;
+                  lonLabel->setPositionCenter(center);
+                  lonLabel->computeBoundingRect();
+                  
+                  addFixedAnnotation(lonLabel);
+               }
+               if(theTopGeographicTickFlag)
+               {
+                  ossimAnnotationLineObject* lineLabel = new ossimAnnotationLineObject(ossimIpt(rounded.x,
+                                                                                                irint(rect.ul().y-24)),
+                                                                                       ossimIpt(rounded.x,
+                                                                                                irint(rect.ul().y)));
+                  lineLabel->setColor(theTopGeographicLabelColor.getR(), theTopGeographicLabelColor.getG(), theTopGeographicLabelColor.getB());
+                  addFixedAnnotation(lineLabel);
+               }
+            }
+         }
+      }
+   }
+   if(traceDebug())
+   {
+      CLOG << "Exiting...." << endl;
+   }
+}
+
+void ossimMapCompositionSource::addGeographicBottomGridLabels()
+{
+   if((!theBottomGeographicLabelFlag)&&(!theBottomGeographicTickFlag))
+   {
+      return;
+   }
+   if(theInputConnection&&theInputProjection)
+   { 
+      ossimGpt gpt[4];
+      ossimDrect rect = getViewingRect();
+
+      if(rect.hasNans()) return;
+      theInputProjection->lineSampleToWorld(rect.ul(),
+                                            gpt[0]);
+      theInputProjection->lineSampleToWorld(rect.ur(),
+                                            gpt[1]);
+      theInputProjection->lineSampleToWorld(rect.lr(),
+                                            gpt[2]);
+      theInputProjection->lineSampleToWorld(rect.ll(),
+                                            gpt[3]);
+      
+      ossimDrect grect(gpt[0],
+                       gpt[1],
+                       gpt[2],
+                       gpt[3],
+                       OSSIM_RIGHT_HANDED);
+
+      if(grect.hasNans()) return;
+      ossimDpt ulLatLon(((int)((grect.ul().x-theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.ul().y+theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+      
+      ossimDpt lrLatLon(((int)((grect.lr().x+theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.lr().y-theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+
+      while(ulLatLon.lat > 90)
+      {
+         ulLatLon.lat -= theGeographicSpacing.lat;
+      }
+      while(ulLatLon.lon < -180)
+      {
+         ulLatLon.lon += theGeographicSpacing.lon;
+      }
+      while(lrLatLon.lat < -90)
+      {
+         ulLatLon.lat += theGeographicSpacing.lat;
+      }
+      while(lrLatLon.lon > 180)
+      {
+         ulLatLon.lon -= theGeographicSpacing.lon;
+      }
+      
+      ossimDrect latLonSpacing(ulLatLon,
+                               lrLatLon,
+                               OSSIM_RIGHT_HANDED);
+
+      // do the top side labels.
+      for(double lon = latLonSpacing.ul().x; lon <= latLonSpacing.lr().x; lon+=theGeographicSpacing.x)
+      {
+         ossimDpt tipt; // top
+         ossimDpt bipt; // bottom
+         
+         ossimGpt tgpt(latLonSpacing.ul().y,
+                       lon,
+                       0.0,
+                       gpt[0].datum());
+
+         ossimGpt bgpt(latLonSpacing.lr().y,
+                       lon,
+                       0.0,
+                       gpt[0].datum());
+         
+         theInputProjection->worldToLineSample(tgpt,
+                                               tipt);
+         
+         theInputProjection->worldToLineSample(bgpt,
+                                               bipt);
+
+         if(rect.clip(tipt, bipt))
+         {
+            ossimIpt rounded(bipt);
+            if( (rounded.x >= rect.ul().x)&&
+                (rounded.x <= rect.lr().x))
+            {
+               if(theBottomGeographicLabelFlag)
+               {
+                  ossimDms dms(bgpt.lond(), false);
+                  
+                  ossimString dmsString = dms.toString(theBottomGeographicFormat.c_str());
+                  ossimAnnotationFontObject* lonLabel = new ossimAnnotationFontObject(ossimIpt(0,0),
+                                                                                      dmsString);
+                  lonLabel->setGeometryInformation(theGeographicBottomLabelFontInfo);
+                  lonLabel->setFont(theGeographicBottomLabelFont, false);
+//                  lonLabel->setFont(theGeographicBottomLabelFont->dup());
+                  
+                  lonLabel->computeBoundingRect();
+                  ossimDrect boundsD;
+                  lonLabel->getBoundingRect(boundsD);
+                  ossimIrect bounds = boundsD;
+                  
+                  ossimIpt center( rounded.x,
+                                   irint(rect.lr().y+(bounds.height()/2)));
+                  
+                  lonLabel->setColor(theBottomGeographicLabelColor.getR(), theBottomGeographicLabelColor.getG(), theBottomGeographicLabelColor.getB());
+                  lonLabel->setPositionCenter(center);
+                  lonLabel->computeBoundingRect();
+                  lonLabel->getBoundingRect(boundsD);
+                  bounds = boundsD;
+
+                  ossimDrect labelRect;
+                  lonLabel->getBoundingRect(labelRect);
+                  
+                  if(rect.intersects(labelRect))
+                  {
+                     ossimIrect intersection = rect.clipToRect(labelRect);
+                     center.y += irint(rect.lr().y - intersection.ul().y);
+                  }
+
+                  center.y += 24; // this will need to be the tick height later;
+                  lonLabel->setPositionCenter(center);
+                  lonLabel->computeBoundingRect();
+
+
+                  addFixedAnnotation(lonLabel);
+               }
+               if(theBottomGeographicTickFlag)
+               {
+                  ossimAnnotationLineObject* lineLabel = new ossimAnnotationLineObject(ossimIpt(rounded.x,
+                                                                                                irint(rect.lr().y+24)),
+                                                                                       ossimIpt(rounded.x,
+                                                                                                irint(rect.lr().y)));
+                  lineLabel->setColor(theBottomGeographicLabelColor.getR(), theBottomGeographicLabelColor.getG(), theBottomGeographicLabelColor.getB());
+                  addFixedAnnotation(lineLabel);
+               }
+            }         
+         }
+      }
+   }   
+}
+
+void ossimMapCompositionSource::addGeographicLeftGridLabels()
+{
+   if((!theLeftGeographicLabelFlag)&&(!theLeftGeographicTickFlag))
+   {
+      return;
+   }
+   if(theInputConnection&&theInputProjection)
+   { 
+      ossimGpt gpt[4];
+      ossimDrect rect = getViewingRect();
+
+      if(rect.hasNans()) return;
+      theInputProjection->lineSampleToWorld(rect.ul(),
+                                            gpt[0]);
+      theInputProjection->lineSampleToWorld(rect.ur(),
+                                            gpt[1]);
+      theInputProjection->lineSampleToWorld(rect.lr(),
+                                            gpt[2]);
+      theInputProjection->lineSampleToWorld(rect.ll(),
+                                            gpt[3]);
+      
+      ossimDrect grect(gpt[0],
+                       gpt[1],
+                       gpt[2],
+                       gpt[3],
+                       OSSIM_RIGHT_HANDED);
+
+      if(grect.hasNans()) return;
+      ossimDpt ulLatLon(((int)((grect.ul().x-theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.ul().y+theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+      
+      ossimDpt lrLatLon(((int)((grect.lr().x+theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.lr().y-theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+
+      while(ulLatLon.lat > 90)
+      {
+         ulLatLon.lat -= theGeographicSpacing.lat;
+      }
+      while(ulLatLon.lon < -180)
+      {
+         ulLatLon.lon += theGeographicSpacing.lon;
+      }
+      while(lrLatLon.lat < -90)
+      {
+         ulLatLon.lat += theGeographicSpacing.lat;
+      }
+      while(lrLatLon.lon > 180)
+      {
+         ulLatLon.lon -= theGeographicSpacing.lon;
+      }
+      
+      ossimDrect latLonSpacing(ulLatLon,
+                               lrLatLon,
+                               OSSIM_RIGHT_HANDED);
+      // do the left side labels
+      for(double lat = latLonSpacing.ul().y; lat >= latLonSpacing.lr().y; lat-=theGeographicSpacing.y)
+      {
+         ossimDpt lipt;
+         ossimDpt ript;
+         ossimGpt lgpt(lat,
+                       latLonSpacing.ul().x,
+                       0.0,
+                       gpt[0].datum());
+         ossimGpt rgpt(lat,
+                       latLonSpacing.ur().x,
+                       0.0,
+                       gpt[0].datum());
+
+         
+         theInputProjection->worldToLineSample(lgpt,
+                                               lipt);
+
+         theInputProjection->worldToLineSample(rgpt,
+                                               ript);
+         if(rect.clip(lipt, ript))
+         {
+            ossimIpt rounded(lipt);
+            if( (rounded.y >= rect.ul().y)&&
+                (rounded.y <= rect.lr().y))
+            {
+               if(theLeftGeographicLabelFlag)
+               {
+                  ossimDms dms(lgpt.latd());
+                  
+                  ossimString dmsString = dms.toString(theLeftGeographicFormat.c_str());
+                  ossimAnnotationFontObject* latLabel = new ossimAnnotationFontObject(ossimIpt(0,0),
+                                                                                      dmsString);
+                  latLabel->setGeometryInformation(theGeographicLeftLabelFontInfo);
+                  latLabel->setFont(theGeographicLeftLabelFont, false);
+//                  latLabel->setFont(theGeographicLeftLabelFont->dup());
+                  
+                  latLabel->computeBoundingRect();
+                  ossimDrect boundsD;
+                  latLabel->getBoundingRect(boundsD);
+                  ossimIrect bounds = boundsD;
+                  
+                  ossimIpt center( irint((rect.ul().x - (bounds.width()/2))),
+                                   rounded.y);
+                  
+                  latLabel->setColor(theLeftGeographicLabelColor.getR(), theLeftGeographicLabelColor.getG(), theLeftGeographicLabelColor.getB());
+                  latLabel->setPositionCenter(center);
+                  latLabel->computeBoundingRect();
+                  latLabel->getBoundingRect(boundsD);
+                  bounds = boundsD;
+
+                  ossimDrect labelRect;
+                  latLabel->getBoundingRect(labelRect);
+                  
+                  if(rect.intersects(labelRect))
+                  {
+                     ossimIrect intersection = rect.clipToRect(labelRect);
+                     center.x -= irint(rect.ul().x - intersection.ur().x);
+                  }
+
+                  center.x -= 24; // this will need to be the tick height later;
+                  latLabel->setPositionCenter(center);
+                  latLabel->computeBoundingRect();
+
+
+                  
+                  addFixedAnnotation(latLabel);
+               }
+               
+               if(theLeftGeographicTickFlag)
+               {
+                  ossimAnnotationLineObject* lineLabel = new ossimAnnotationLineObject(ossimIpt(irint(rect.ul().x),
+                                                                                                rounded.y),
+                                                                                       ossimIpt(irint(rect.ul().x-23),
+                                                                                                rounded.y));
+                  lineLabel->setColor(theLeftGeographicLabelColor.getR(), theLeftGeographicLabelColor.getG(), theLeftGeographicLabelColor.getB());
+                  addFixedAnnotation(lineLabel);
+               }
+            }
+         }
+      }
+   }
+}
+
+void ossimMapCompositionSource::addGeographicRightGridLabels()
+{
+   if((!theRightGeographicLabelFlag)&&(!theRightGeographicTickFlag))
+   {
+      return;
+   }
+   if(theInputConnection&&theInputProjection)
+   { 
+      ossimGpt gpt[4];
+      ossimDrect rect = getViewingRect();
+
+      if(rect.hasNans()) return;
+      theInputProjection->lineSampleToWorld(rect.ul(),
+                                            gpt[0]);
+      theInputProjection->lineSampleToWorld(rect.ur(),
+                                            gpt[1]);
+      theInputProjection->lineSampleToWorld(rect.lr(),
+                                            gpt[2]);
+      theInputProjection->lineSampleToWorld(rect.ll(),
+                                            gpt[3]);
+      
+      ossimDrect grect(gpt[0],
+                       gpt[1],
+                       gpt[2],
+                       gpt[3],
+                       OSSIM_RIGHT_HANDED);
+
+      if(grect.hasNans()) return;
+      ossimDpt ulLatLon(((int)((grect.ul().x-theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.ul().y+theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+      
+      ossimDpt lrLatLon(((int)((grect.lr().x+theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.lr().y-theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+
+      while(ulLatLon.lat > 90)
+      {
+         ulLatLon.lat -= theGeographicSpacing.lat;
+      }
+      while(ulLatLon.lon < -180)
+      {
+         ulLatLon.lon += theGeographicSpacing.lon;
+      }
+      while(lrLatLon.lat < -90)
+      {
+         ulLatLon.lat += theGeographicSpacing.lat;
+      }
+      while(lrLatLon.lon > 180)
+      {
+         ulLatLon.lon -= theGeographicSpacing.lon;
+      }
+      
+      ossimDrect latLonSpacing(ulLatLon,
+                               lrLatLon,
+                               OSSIM_RIGHT_HANDED);
+      // do the left side labels
+      for(double lat = latLonSpacing.ul().y; lat >= latLonSpacing.lr().y; lat-=theGeographicSpacing.y)
+      {
+         ossimDpt lipt;
+         ossimDpt ript;
+         ossimGpt lgpt(lat,
+                       latLonSpacing.ul().x,
+                       0.0,
+                       gpt[0].datum());
+         ossimGpt rgpt(lat,
+                       latLonSpacing.ur().x,
+                       0.0,
+                       gpt[0].datum());
+         
+         
+         theInputProjection->worldToLineSample(lgpt,
+                                               lipt);
+         
+         theInputProjection->worldToLineSample(rgpt,
+                                               ript);
+         
+         if(rect.clip(lipt, ript))
+         {
+            ossimIpt rounded(ript);
+            if( (rounded.y >= rect.ul().y)&&
+                (rounded.y <= rect.lr().y))
+            {
+               if(theRightGeographicLabelFlag)
+               {
+                  ossimDms dms(rgpt.latd());
+                  
+                  ossimString dmsString = dms.toString(theRightGeographicFormat.c_str());
+                  ossimAnnotationFontObject* latLabel = new ossimAnnotationFontObject(ossimIpt(0,0),
+                                                                                      dmsString);
+                  latLabel->setGeometryInformation(theGeographicRightLabelFontInfo);
+                  latLabel->setFont(theGeographicRightLabelFont, false);
+//                  latLabel->setFont(theGeographicRightLabelFont->dup());
+                  latLabel->computeBoundingRect();
+                  ossimDrect boundsD;
+                  latLabel->getBoundingRect(boundsD);
+                  ossimIrect bounds = boundsD;
+                  
+                  ossimIpt center( irint((rect.ur().x + (bounds.width()/2))),
+                                   rounded.y);
+               
+                  latLabel->setColor(theRightGeographicLabelColor.getR(), theRightGeographicLabelColor.getG(), theRightGeographicLabelColor.getB());
+                  latLabel->setPositionCenter(center);
+                  latLabel->computeBoundingRect();
+                  latLabel->getBoundingRect(boundsD);
+                  bounds = boundsD;
+
+                  ossimDrect labelRect;
+                  latLabel->getBoundingRect(labelRect);
+                  
+                  if(rect.intersects(labelRect))
+                  {
+                     ossimIrect intersection = rect.clipToRect(labelRect);
+                     center.x -= irint(rect.ur().x - intersection.ul().x);
+                  }
+
+                  center.x += 24; // this will need to be the tick height later;
+                  latLabel->setPositionCenter(center);
+                  latLabel->computeBoundingRect();
+                  
+
+                  addFixedAnnotation(latLabel);
+               }
+               
+               if(theRightGeographicTickFlag)
+               {
+                  ossimAnnotationLineObject* lineLabel = new ossimAnnotationLineObject(ossimIpt(irint(rect.lr().x),
+                                                                                                rounded.y),
+                                                                                       ossimIpt(irint(rect.lr().x+23),
+                                                                                                rounded.y));
+                  
+                  lineLabel->setColor(theRightGeographicLabelColor.getR(), theRightGeographicLabelColor.getG(), theRightGeographicLabelColor.getB());
+                  addFixedAnnotation(lineLabel);
+               }
+            }
+         }
+      }
+   }
+}
+
+void ossimMapCompositionSource::addGeographicGridLines()
+{
+   if(theInputConnection&&theInputProjection)
+   { 
+      ossimGpt gpt[4];
+      ossimDrect rect = getViewingRect();
+
+      if(rect.hasNans()) return;
+      theInputProjection->lineSampleToWorld(rect.ul(),
+                                            gpt[0]);
+      theInputProjection->lineSampleToWorld(rect.ur(),
+                                            gpt[1]);
+      theInputProjection->lineSampleToWorld(rect.lr(),
+                                            gpt[2]);
+      theInputProjection->lineSampleToWorld(rect.ll(),
+                                            gpt[3]);
+      
+      ossimDrect grect(gpt[0],
+                       gpt[1],
+                       gpt[2],
+                       gpt[3],
+                       OSSIM_RIGHT_HANDED);
+
+      if(grect.hasNans()) return;
+      ossimDpt ulLatLon(((int)((grect.ul().x-theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.ul().y+theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+      
+      ossimDpt lrLatLon(((int)((grect.lr().x+theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.lr().y-theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+
+      while(ulLatLon.lat > 90)
+      {
+         ulLatLon.lat -= theGeographicSpacing.lat;
+      }
+      while(ulLatLon.lon < -180)
+      {
+         ulLatLon.lon += theGeographicSpacing.lon;
+      }
+      while(lrLatLon.lat < -90)
+      {
+         ulLatLon.lat += theGeographicSpacing.lat;
+      }
+      while(lrLatLon.lon > 180)
+      {
+         ulLatLon.lon -= theGeographicSpacing.lon;
+      }
+      
+      ossimDrect latLonSpacing(ulLatLon,
+                               lrLatLon,
+                               OSSIM_RIGHT_HANDED);
+
+
+      for(double lon = latLonSpacing.ul().x; lon <= latLonSpacing.lr().x; lon+=theGeographicSpacing.x)
+      {
+         ossimDpt tipt; // top
+         ossimDpt bipt; // bottom
+         
+         ossimGpt tgpt(latLonSpacing.ul().y,
+                       lon,
+                       0.0,
+                       gpt[0].datum());
+
+         ossimGpt bgpt(latLonSpacing.lr().y,
+                       lon,
+                       0.0,
+                       gpt[0].datum());
+         
+         theInputProjection->worldToLineSample(tgpt,
+                                               tipt);
+         
+         theInputProjection->worldToLineSample(bgpt,
+                                               bipt);
+
+         if(rect.clip(tipt, bipt))
+         {
+            ossimAnnotationLineObject* line = new ossimAnnotationLineObject(tipt, bipt);
+            line->setColor(theGeographicGridColor.getR(),
+                           theGeographicGridColor.getG(),
+                           theGeographicGridColor.getB());
+            addFixedAnnotation(line);
+         }
+      }
+      // do the left side labels
+      for(double lat = latLonSpacing.ul().y; lat >= latLonSpacing.lr().y; lat-=theGeographicSpacing.y)
+      {
+         ossimDpt lipt;
+         ossimDpt ript;
+         ossimGpt lgpt(lat,
+                       latLonSpacing.ul().x,
+                       0.0,
+                       gpt[0].datum());
+         ossimGpt rgpt(lat,
+                       latLonSpacing.ur().x,
+                       0.0,
+                       gpt[0].datum());
+
+         theInputProjection->worldToLineSample(lgpt,
+                                               lipt);
+         theInputProjection->worldToLineSample(rgpt,
+                                               ript);
+         
+         if(rect.clip(lipt, ript))
+         {
+            ossimAnnotationLineObject* line = new ossimAnnotationLineObject(lipt,
+                                                                            ript);
+         
+            line->setColor(theGeographicGridColor.getR(),
+                                theGeographicGridColor.getG(),
+                                theGeographicGridColor.getB());
+         
+            addFixedAnnotation(line);
+         }
+      }
+   }   
+}
+
+void ossimMapCompositionSource::addGeographicGridReseaux()
+{
+   if(theInputConnection&&theInputProjection)
+   { 
+      ossimGpt gptArray[4];
+      ossimDrect rect = getViewingRect();
+      
+      theInputProjection->lineSampleToWorld(rect.ul(),
+                                            gptArray[0]);
+      theInputProjection->lineSampleToWorld(rect.ur(),
+                                            gptArray[1]);
+      theInputProjection->lineSampleToWorld(rect.lr(),
+                                            gptArray[2]);
+      theInputProjection->lineSampleToWorld(rect.ll(),
+                                            gptArray[3]);
+      
+      ossimDrect grect(gptArray[0],
+                       gptArray[1],
+                       gptArray[2],
+                       gptArray[3],
+                       OSSIM_RIGHT_HANDED);
+
+      ossimDpt ulLatLon(((int)((grect.ul().x-theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.ul().y+theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+      
+      ossimDpt lrLatLon(((int)((grect.lr().x+theGeographicSpacing.x)/theGeographicSpacing.x))*theGeographicSpacing.x,
+                        ((int)((grect.lr().y-theGeographicSpacing.y)/theGeographicSpacing.y))*theGeographicSpacing.y);
+      
+      ossimDrect latLonSpacing(ulLatLon,
+                               lrLatLon,
+                               OSSIM_RIGHT_HANDED);
+
+      ossimDpt ipt; // top
+      for(double lat = latLonSpacing.ul().y; lat >= latLonSpacing.lr().y; lat-=theGeographicSpacing.y)
+      {
+         for(double lon = latLonSpacing.ul().x; lon <= latLonSpacing.lr().x; lon+=theGeographicSpacing.x)
+         {
+            
+            ossimGpt gpt(lat,
+                         lon,
+                         0.0,
+                         gptArray[0].datum());
+            
+            
+            theInputProjection->worldToLineSample(gpt,
+                                                  ipt);
+
+            ossimIpt rounded(ipt);
+            if(rect.pointWithin(ossimDpt(rounded)))
+            {
+               ossimIpt horizontalStart(rounded.x-10, rounded.y);
+               ossimIpt horizontalEnd(rounded.x+10, rounded.y);
+
+               ossimIpt verticalStart(rounded.x, rounded.y-10);
+               ossimIpt verticalEnd(rounded.x, rounded.y+10);
+               
+               ossimAnnotationLineObject* line1 = new ossimAnnotationLineObject(horizontalStart, horizontalEnd);
+               ossimAnnotationLineObject* line2 = new ossimAnnotationLineObject(verticalStart,verticalEnd);
+
+               line1->setColor(theGeographicGridColor.getR(),
+                               theGeographicGridColor.getG(),
+                               theGeographicGridColor.getB());
+               line2->setColor(theGeographicGridColor.getR(),
+                               theGeographicGridColor.getG(),
+                               theGeographicGridColor.getB());
+               addFixedAnnotation(line1);
+               addFixedAnnotation(line2);
+            }  
+         }
+      }
+   }   
+}
+
+void ossimMapCompositionSource::addMeterGridLines()
+{
+   if(theInputConnection&&theInputProjection)
+   { 
+      ossimDpt dptArray[4];
+      ossimDrect rect = getViewingRect();
+      
+      theInputProjection->lineSampleToEastingNorthing(rect.ul(),
+                                                      dptArray[0]);
+      theInputProjection->lineSampleToEastingNorthing(rect.ur(),
+                                                      dptArray[1]);
+      theInputProjection->lineSampleToEastingNorthing(rect.lr(),
+                                                      dptArray[2]);
+      theInputProjection->lineSampleToEastingNorthing(rect.ll(),
+                                                      dptArray[3]);
+      
+      
+      ossimDrect drect(dptArray[0],
+                       dptArray[1],
+                       dptArray[2],
+                       dptArray[3],
+                       OSSIM_RIGHT_HANDED);
+      
+      ossimDpt ulMeter(((int)((drect.ul().x-theMeterSpacing.x)/theMeterSpacing.x))*theMeterSpacing.x,
+                       ((int)((drect.ul().y+theMeterSpacing.y)/theMeterSpacing.y))*theMeterSpacing.y);
+      
+      ossimDpt lrMeter(((int)((drect.lr().x+theMeterSpacing.x)/theMeterSpacing.x))*theMeterSpacing.x,
+                        ((int)((drect.lr().y-theMeterSpacing.y)/theMeterSpacing.y))*theMeterSpacing.y);
+      
+      ossimDrect meterSpacing(ulMeter,
+                              lrMeter,
+                              OSSIM_RIGHT_HANDED);
+
+      for(double horizontal = meterSpacing.ul().x;
+          horizontal <= meterSpacing.lr().x;
+          horizontal+=theMeterSpacing.x)
+      {
+         ossimDpt tipt; // top
+         ossimDpt bipt; // bottom
+
+         ossimDpt tdpt(horizontal,
+                       meterSpacing.ul().y);
+
+         ossimDpt bdpt(horizontal,
+                       meterSpacing.lr().y);
+         
+         theInputProjection->eastingNorthingToLineSample(tdpt,
+                                                         tipt);
+         
+         theInputProjection->eastingNorthingToLineSample(bdpt,
+                                                         bipt);
+         
+         if(rect.clip(tipt, bipt))
+         {
+            ossimAnnotationLineObject* line = new ossimAnnotationLineObject(tipt, bipt);
+            line->setColor(theMeterGridColor.getR(),
+                           theMeterGridColor.getG(),
+                           theMeterGridColor.getB());
+            addFixedAnnotation(line);
+         }
+      }
+      // do the left side labels
+      for(double vertical = meterSpacing.ul().y;
+          vertical >= meterSpacing.lr().y;
+          vertical-=theMeterSpacing.y)
+      {
+         ossimDpt lipt;
+         ossimDpt ript;
+         ossimDpt ldpt(meterSpacing.ul().x,
+                       vertical);
+         ossimDpt rdpt(meterSpacing.ur().x,
+                       vertical);
+
+         theInputProjection->eastingNorthingToLineSample(ldpt,
+                                                         lipt);
+         theInputProjection->eastingNorthingToLineSample(rdpt,
+                                                         ript);
+         
+         if(rect.clip(lipt, ript))
+         {
+            ossimAnnotationLineObject* line = new ossimAnnotationLineObject(lipt,
+                                                                            ript);
+         
+            line->setColor(theMeterGridColor.getR(),
+                           theMeterGridColor.getG(),
+                           theMeterGridColor.getB());
+            
+            addFixedAnnotation(line);
+         }
+      }
+   }
+}
+
+void ossimMapCompositionSource::addMeterGridLabels()
+{
+   if(theInputConnection&&theInputProjection)
+   {
+      ossimDpt dptArray[4];
+      ossimDrect rect = getViewingRect();
+      
+      theInputProjection->lineSampleToEastingNorthing(rect.ul(),
+                                                      dptArray[0]);
+      theInputProjection->lineSampleToEastingNorthing(rect.ur(),
+                                                      dptArray[1]);
+      theInputProjection->lineSampleToEastingNorthing(rect.lr(),
+                                                      dptArray[2]);
+      theInputProjection->lineSampleToEastingNorthing(rect.ll(),
+                                                      dptArray[3]);
+      
+      ossimDrect drect(dptArray[0],
+                       dptArray[1],
+                       dptArray[2],
+                       dptArray[3],
+                       OSSIM_RIGHT_HANDED);
+      
+      ossimDpt ulMeter(((int)((drect.ul().x-theMeterSpacing.x)/theMeterSpacing.x))*theMeterSpacing.x,
+                       ((int)((drect.ul().y+theMeterSpacing.y)/theMeterSpacing.y))*theMeterSpacing.y);
+      
+      ossimDpt lrMeter(((int)((drect.lr().x+theMeterSpacing.x)/theMeterSpacing.x))*theMeterSpacing.x,
+                        ((int)((drect.lr().y-theMeterSpacing.y)/theMeterSpacing.y))*theMeterSpacing.y);
+      
+      ossimDrect meterSpacing(ulMeter,
+                              lrMeter,
+                              OSSIM_RIGHT_HANDED);
+      
+      ossimDrect labelRect;
+
+      // Since we support overlapping grid lables.  We will shift
+      // the meter label if there exists a gegraphic label.  To
+      // do this we need to compute an extra shift length based
+      // on the font type on each of the sides.  We could actually make this
+      // shift adjustable later????
+      //
+      long extraTopDelta     = 0;
+      long extraBottomDelta  = 0;
+      long extraLeftDelta    = 0;
+      long extraRightDelta   = 0;
+         
+      if(theTopGeographicLabelFlag&&theGeographicTopLabelFont)
+      {  
+         ossimDms dms(180, false);
+         ossimString dmsString = dms.toString(theTopGeographicFormat.c_str());
+         
+         theGeographicTopLabelFont->setString(dmsString);
+         ossimIrect box;
+         
+         theGeographicTopLabelFont->getBoundingBox(box);
+         extraTopDelta = box.height();
+      }
+      if(theBottomGeographicLabelFlag&&theGeographicBottomLabelFont)
+      {  
+         ossimDms dms(180, false);
+         ossimString dmsString = dms.toString(theBottomGeographicFormat.c_str());
+         theGeographicBottomLabelFont->setString(dmsString);
+         ossimIrect box;
+         
+         theGeographicBottomLabelFont->getBoundingBox(box);
+         extraBottomDelta = box.height();
+      }
+      if(theLeftGeographicLabelFlag&&theGeographicLeftLabelFont)
+      {  
+         ossimDms dms(90.0, true);
+         ossimString dmsString = dms.toString(theLeftGeographicFormat.c_str());
+         theGeographicLeftLabelFont->setString(dmsString);
+         ossimIrect box;
+         
+         theGeographicLeftLabelFont->getBoundingBox(box);
+         extraLeftDelta = box.width();
+      }
+      if(theRightGeographicLabelFlag&&theGeographicRightLabelFont)
+      {  
+         ossimDms dms(90.0, true);
+         ossimString dmsString = dms.toString(theRightGeographicFormat.c_str());
+         
+         theGeographicRightLabelFont->setString(dmsString);
+         ossimIrect box;
+         
+         theGeographicRightLabelFont->getBoundingBox(box);
+         extraRightDelta = box.width();
+      }
+
+      if(theTopMeterLabelFlag || theBottomMeterLabelFlag)
+      {
+         for(double horizontal = meterSpacing.ul().x;
+             horizontal <= meterSpacing.lr().x;
+             horizontal+=theMeterSpacing.x)
+         {
+            ossimDpt tipt; // top
+            ossimDpt bipt; // bottom
+            
+            ossimDpt tdpt(horizontal,
+                          meterSpacing.ul().y);
+            
+            ossimDpt bdpt(horizontal,
+                          meterSpacing.lr().y);
+            
+            theInputProjection->eastingNorthingToLineSample(tdpt,
+                                                            tipt);
+            
+            theInputProjection->eastingNorthingToLineSample(bdpt,
+                                                            bipt);
+            
+            rect.clip(tipt, bipt);
+            
+            tipt = ossimIpt(tipt);
+            bipt = ossimIpt(bipt);
+            
+            if(theTopMeterLabelFlag&&rect.clip(tipt, bipt))
+            {
+               ossimAnnotationFontObject* topLabel = new ossimAnnotationFontObject(ossimIpt(0,0),
+                                                                                   ossimString::toString(horizontal).c_str());
+               
+               
+               topLabel->setFont(theMeterTopLabelFont, false);
+               
+               topLabel->setGeometryInformation(theMeterTopLabelFontInfo);
+               topLabel->computeBoundingRect();
+               ossimDrect boundsTop;
+               topLabel->getBoundingRect(boundsTop);
+               
+               ossimIpt centerTop(irint(tipt.x),
+                                  irint(rect.ul().y-(boundsTop.height()/2)));
+               
+               topLabel->setColor(theTopMeterLabelColor.getR(),
+                                  theTopMeterLabelColor.getG(),
+                                  theTopMeterLabelColor.getB());
+               
+               
+               topLabel->setPositionCenter(centerTop);
+               topLabel->computeBoundingRect();
+               
+               topLabel->getBoundingRect(labelRect);
+               
+               if(rect.intersects(labelRect))
+               {
+                  ossimIrect intersection = rect.clipToRect(labelRect);
+                  centerTop.y -= irint(rect.ul().y - intersection.lr().y);
+               }
+               
+               centerTop.y -= (24+extraTopDelta); // this will need to be the tick height later;
+               topLabel->setPositionCenter(centerTop);
+               topLabel->computeBoundingRect();
+               addFixedAnnotation(topLabel);
+
+               if(theTopMeterTickFlag)
+               {
+                  ossimAnnotationLineObject* lineLabel = new ossimAnnotationLineObject(ossimIpt(irint(tipt.x),
+                                                                                                irint(tipt.y-24)),
+                                                                                       ossimIpt(irint(tipt.x),
+                                                                                                irint(tipt.y)));
+                  
+                  lineLabel->setColor(theTopMeterLabelColor.getR(), theTopMeterLabelColor.getG(), theTopMeterLabelColor.getB());
+                  addFixedAnnotation(lineLabel);
+               }
+            }
+         // ------------------------- BOTTOM ----------------------------
+            
+            if(theBottomMeterLabelFlag&&rect.pointWithin(bipt))
+            {
+               ossimAnnotationFontObject* bottomLabel = new ossimAnnotationFontObject(ossimIpt(0,0),
+                                                                                      ossimString::toString(horizontal).c_str());
+               
+               
+               bottomLabel->setFont(theMeterBottomLabelFont, false);
+               
+               bottomLabel->setGeometryInformation(theMeterBottomLabelFontInfo);
+               bottomLabel->computeBoundingRect();
+               ossimDrect boundsBottom;
+               bottomLabel->getBoundingRect(boundsBottom);
+               
+               ossimIpt centerBottom(irint(bipt.x),
+                                     irint(rect.lr().y+(boundsBottom.height()/2)));
+               
+               bottomLabel->setColor(theBottomMeterLabelColor.getR(),
+                                     theBottomMeterLabelColor.getG(),
+                                     theBottomMeterLabelColor.getB());
+               
+               
+               bottomLabel->setPositionCenter(centerBottom);
+               bottomLabel->computeBoundingRect();
+               
+               bottomLabel->getBoundingRect(labelRect);
+               
+               if(rect.intersects(labelRect))
+               {
+                  ossimIrect intersection = rect.clipToRect(labelRect);
+                  centerBottom.y += irint(rect.lr().y - intersection.ul().y);
+               }
+               
+               centerBottom.y += (24+extraBottomDelta); // this will need to be the tick height later;
+               bottomLabel->setPositionCenter(centerBottom);
+               bottomLabel->computeBoundingRect();
+               addFixedAnnotation(bottomLabel);
+               if(theBottomMeterTickFlag)
+               {
+                  ossimAnnotationLineObject* lineLabel = new ossimAnnotationLineObject(ossimIpt(irint(bipt.x),
+                                                                                                irint(bipt.y+24)),
+                                                                                       ossimIpt(irint(bipt.x),
+                                                                                                irint(bipt.y)));
+                  
+                  lineLabel->setColor(theBottomMeterLabelColor.getR(), theBottomMeterLabelColor.getG(), theBottomMeterLabelColor.getB());
+                  addFixedAnnotation(lineLabel);
+               }
+            }            
+         }
+      }
+      if(theLeftMeterLabelFlag || theRightMeterLabelFlag)
+      {
+         for(double vertical = meterSpacing.ul().y;
+             vertical >= meterSpacing.lr().y;
+             vertical-=theMeterSpacing.y)
+         {
+            ossimDpt lipt;
+            ossimDpt ript;
+            ossimDpt ldpt(meterSpacing.ul().x,
+                          vertical);
+            ossimDpt rdpt(meterSpacing.ur().x,
+                          vertical);
+            
+            theInputProjection->eastingNorthingToLineSample(ldpt,
+                                                            lipt);
+            theInputProjection->eastingNorthingToLineSample(rdpt,
+                                                            ript);
+            
+            if(rect.clip(lipt, ript))
+            {
+               //------------------------------------------------ Left label ----------------------------------------------
+               ossimAnnotationFontObject* leftLabel = new ossimAnnotationFontObject(ossimIpt(0,0),
+                                                                                    ossimString::toString(vertical).c_str());
+               
+               
+               leftLabel->setFont(theMeterLeftLabelFont, false);
+               
+               leftLabel->setGeometryInformation(theMeterLeftLabelFontInfo);
+               leftLabel->computeBoundingRect();
+               ossimDrect boundsLeft;
+               leftLabel->getBoundingRect(boundsLeft);
+               
+               ossimIpt centerLeft(irint(rect.ul().x-(boundsLeft.width()/2)),
+                                   irint(lipt.y));
+                                  
+               
+               leftLabel->setColor(theLeftMeterLabelColor.getR(),
+                                   theLeftMeterLabelColor.getG(),
+                                   theLeftMeterLabelColor.getB());
+               
+               
+               leftLabel->setPositionCenter(centerLeft);
+               leftLabel->computeBoundingRect();
+               
+               leftLabel->getBoundingRect(labelRect);
+               
+               if(rect.intersects(labelRect))
+               {
+                  ossimIrect intersection = rect.clipToRect(labelRect);
+                  centerLeft.x -= irint(intersection.lr().x - rect.ul().x);
+               }
+               
+               centerLeft.x -= (24+extraLeftDelta); // this will need to be the tick height later;
+               leftLabel->setPositionCenter(centerLeft);
+               leftLabel->computeBoundingRect();
+               addFixedAnnotation(leftLabel);
+               if(theLeftMeterTickFlag)
+               {
+                  ossimAnnotationLineObject* lineLabel = new ossimAnnotationLineObject(ossimIpt(irint(lipt.x-24),
+                                                                                                irint(lipt.y)),
+                                                                                       ossimIpt(irint(lipt.x),
+                                                                                                irint(lipt.y)));
+                  
+                  lineLabel->setColor(theLeftMeterLabelColor.getR(), theLeftMeterLabelColor.getG(), theLeftMeterLabelColor.getB());
+                  addFixedAnnotation(lineLabel);
+               }
+
+               
+               //--------------------------------RIGHT-----------------------------------------------------------
+               ossimAnnotationFontObject* rightLabel = new ossimAnnotationFontObject(ossimIpt(0,0),
+                                                                                     ossimString::toString(vertical).c_str());
+               
+               
+               rightLabel->setFont(theMeterRightLabelFont, false);
+               
+               rightLabel->setGeometryInformation(theMeterRightLabelFontInfo);
+               rightLabel->computeBoundingRect();
+               ossimDrect boundsRight;
+               rightLabel->getBoundingRect(boundsRight);
+               
+               ossimIpt centerRight(irint(rect.ur().x+(boundsRight.width()/2)),
+                                    irint(ript.y));
+                                  
+               
+               rightLabel->setColor(theRightMeterLabelColor.getR(),
+                                    theRightMeterLabelColor.getG(),
+                                    theRightMeterLabelColor.getB());
+               
+               
+               rightLabel->setPositionCenter(centerRight);
+               rightLabel->computeBoundingRect();
+               
+               rightLabel->getBoundingRect(labelRect);
+               
+               if(rect.intersects(labelRect))
+               {
+                  ossimIrect intersection = rect.clipToRect(labelRect);
+                  centerRight.x += irint(intersection.ul().x - rect.ur().x);
+               }
+               
+               centerRight.x += (24+extraRightDelta); // this will need to be the tick height later;
+               rightLabel->setPositionCenter(centerRight);
+               rightLabel->computeBoundingRect();
+               addFixedAnnotation(rightLabel);
+               if(theRightMeterTickFlag)
+               {
+                  ossimAnnotationLineObject* lineLabel = new ossimAnnotationLineObject(ossimIpt(irint(ript.x+24),
+                                                                                                irint(ript.y)),
+                                                                                       ossimIpt(irint(ript.x),
+                                                                                                irint(ript.y)));
+                  
+                  lineLabel->setColor(theRightMeterLabelColor.getR(), theRightMeterLabelColor.getG(), theRightMeterLabelColor.getB());
+                  addFixedAnnotation(lineLabel);
+               }
+            }
+         }
+      }
+   }
+}
+
+
+void ossimMapCompositionSource::addMeterGridReseaux()
+{
+   if(theInputConnection&&theInputProjection)
+   { 
+      ossimDpt dpt[4];
+      ossimDrect rect = getViewingRect();
+      
+      theInputProjection->lineSampleToEastingNorthing(rect.ul(),
+                                                      dpt[0]);
+      theInputProjection->lineSampleToEastingNorthing(rect.ur(),
+                                                      dpt[1]);
+      theInputProjection->lineSampleToEastingNorthing(rect.lr(),
+                                                      dpt[2]);
+      theInputProjection->lineSampleToEastingNorthing(rect.ll(),
+                                                      dpt[3]);
+      
+      ossimDrect drect(dpt[0],
+                       dpt[1],
+                       dpt[2],
+                       dpt[3],
+                       OSSIM_RIGHT_HANDED);
+
+      ossimDpt ulMeter(((int)((drect.ul().x-theMeterSpacing.x)/theMeterSpacing.x))*theMeterSpacing.x,
+                       ((int)((drect.ul().y+theMeterSpacing.y)/theMeterSpacing.y))*theMeterSpacing.y);
+      
+      ossimDpt lrMeter(((int)((drect.lr().x+theMeterSpacing.x)/theMeterSpacing.x))*theMeterSpacing.x,
+                        ((int)((drect.lr().y-theMeterSpacing.y)/theMeterSpacing.y))*theMeterSpacing.y);
+
+      ossimDrect meterSpacing(ulMeter,
+                              lrMeter,
+                              OSSIM_RIGHT_HANDED);
+
+      ossimDpt ipt; // top
+
+      for(double vertical = meterSpacing.ul().y; vertical >= meterSpacing.lr().y; vertical-=theMeterSpacing.y)
+      {
+         for(double horizontal = meterSpacing.ul().x;  horizontal <= meterSpacing.lr().x; horizontal+=theMeterSpacing.x)
+         {            
+            ossimDpt dpt(horizontal,
+                         vertical);
+            
+            theInputProjection->eastingNorthingToLineSample(dpt,
+                                                            ipt);
+
+            ossimIpt rounded(ipt);
+            if(rect.pointWithin(ossimDpt(rounded)))
+            {
+               ossimIpt horizontalStart(rounded.x-10, rounded.y);
+               ossimIpt horizontalEnd(rounded.x+10, rounded.y);
+
+               ossimIpt verticalStart(rounded.x, rounded.y-10);
+               ossimIpt verticalEnd(rounded.x, rounded.y+10);
+               
+               ossimAnnotationLineObject* line1 = new ossimAnnotationLineObject(horizontalStart, horizontalEnd);
+               ossimAnnotationLineObject* line2 = new ossimAnnotationLineObject(verticalStart,verticalEnd);
+
+               line1->setColor(theMeterGridColor.getR(),
+                               theMeterGridColor.getG(),
+                               theMeterGridColor.getB());
+
+               line2->setColor(theMeterGridColor.getR(),
+                               theMeterGridColor.getG(),
+                               theMeterGridColor.getB());
+               addFixedAnnotation(line1);
+               addFixedAnnotation(line2);
+            }  
+         }
+      }
+   }   
+}
+
+void ossimMapCompositionSource::addTitle()
+{
+   ossimAnnotationFontObject* title = new ossimAnnotationFontObject(ossimIpt(0,0),
+                                                                    theTitleString);
+   title->setGeometryInformation(theTitleFontInfo);
+   title->setFont(theTitleFont, false);
+   title->setColor(theTitleColor.getR(),
+                   theTitleColor.getG(),
+                   theTitleColor.getB());
+   title->setPositionCenter(theTopBorder.midPoint());
+   title->computeBoundingRect();
+
+   addFixedAnnotation(title);
+}
+
+ossimIrect ossimMapCompositionSource::getViewingRect()const
+{
+   ossimIrect result;
+   result.makeNan();
+
+   if(theInputConnection)
+   {
+      result = theInputConnection->getBoundingRect();
+
+      if(!result.hasNans())
+      {
+         ossimIpt mid = result.midPoint();
+         ossim_int32 w = result.width();
+         ossim_int32 h = result.width();
+
+         if(theViewWidthHeight.x >-1)
+         {
+            w = theViewWidthHeight.x;
+         }
+         if(theViewWidthHeight.y >-1)
+         {
+            h = theViewWidthHeight.y;
+         }
+         ossimIpt ul(mid.x - w/2,
+                     mid.y - h/2);
+         
+         result = ossimIrect(ul.x,
+                             ul.y,
+                             ul.x + w-1,
+                             ul.y + h -1);
+      }
+   }
+
+   return result;
+}
+
+void ossimMapCompositionSource::drawAnnotations(
+   ossimRefPtr<ossimImageData> tile)
+{
+   if (!theImage)
+   {
+      return;
+   }
+      
+   theImage->setCurrentImageData(theTile);
+   
+   if(theImage->getImageData().valid())
+   {
+      vector<ossimAnnotationObject*>::iterator object = theFixedAnnotationList.begin();
+      while(object != theFixedAnnotationList.end())
+      {
+         if(*object)
+         {
+            (*object)->draw(*theImage);
+         }
+         ++object;
+      }      
+   }
+   
+   ossimAnnotationSource::drawAnnotations(tile);
+}
+
+void ossimMapCompositionSource::deleteFixedAnnotations()
+{
+   for(int i = 0; i < (int)theFixedAnnotationList.size();++i)
+   {
+      if(theFixedAnnotationList[i])
+      {
+         delete theFixedAnnotationList[i];
+      }
+   }
+
+   theFixedAnnotationList.clear();
+}
+
+
+void ossimMapCompositionSource::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property.valid()) return;
+   
+   ossimRefPtr<ossimProperty>        tempProp     = 0;
+   ossimFontProperty*    fontProp     = 0;
+   ossimColorProperty*   colorProp    = 0;
+   ossimBooleanProperty* booleanProp  = 0;
+   
+   if(property->getName() == "Geographic label properties")
+   {
+      ossimContainerProperty* containerProp = PTR_CAST(ossimContainerProperty,
+                                                       property.get());
+      if(containerProp)
+      {
+         // first set the font format
+         //
+         tempProp = containerProp->getProperty("Top font");
+         fontProp = PTR_CAST(ossimFontProperty, tempProp.get());
+         if(fontProp)
+         {
+            setGeographicTopLabelFont(fontProp->getFontInformation());
+         }
+         tempProp = containerProp->getProperty("Bottom font");
+         fontProp = PTR_CAST(ossimFontProperty, tempProp.get());
+         if(fontProp)
+         {
+            setGeographicBottomLabelFont(fontProp->getFontInformation());
+         }
+         tempProp = containerProp->getProperty("Left font");
+         fontProp = PTR_CAST(ossimFontProperty, tempProp.get());
+         if(fontProp)
+         {
+            setGeographicLeftLabelFont(fontProp->getFontInformation());
+         }
+         tempProp = containerProp->getProperty("Right font");
+         fontProp = PTR_CAST(ossimFontProperty, tempProp.get());
+         if(fontProp)
+         {
+            setGeographicRightLabelFont(fontProp->getFontInformation());
+         }
+
+         // set color property
+         tempProp = containerProp->getProperty("Top color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(colorProp)
+         {
+            setTopGeographicLabelColor(colorProp->getColor());
+         }
+         tempProp = containerProp->getProperty("Bottom color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(colorProp)
+         {
+            setBottomGeographicLabelColor(colorProp->getColor());
+         }
+         tempProp = containerProp->getProperty("Left color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(colorProp)
+         {
+            setLeftGeographicLabelColor(colorProp->getColor());
+         }
+         tempProp = containerProp->getProperty("Right color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(colorProp)
+         {
+            setRightGeographicLabelColor(colorProp->getColor());
+         }
+
+         // set enable flags
+         tempProp = containerProp->getProperty("Top enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setTopGeographicLabelFlag(booleanProp->getBoolean());
+         }
+
+         tempProp = containerProp->getProperty("Bottom enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setBottomGeographicLabelFlag(booleanProp->getBoolean());
+         }
+
+         tempProp = containerProp->getProperty("Left enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setLeftGeographicLabelFlag(booleanProp->getBoolean());
+         }
+
+         tempProp = containerProp->getProperty("Right enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setRightGeographicLabelFlag(booleanProp->getBoolean());
+         }
+         
+         tempProp = containerProp->getProperty("Top tick enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setTopGeographicTickMarkFlag(booleanProp->getBoolean());
+         }
+         tempProp = containerProp->getProperty("Bottom tick enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setBottomGeographicTickMarkFlag(booleanProp->getBoolean());
+         }
+         tempProp = containerProp->getProperty("Left tick enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setLeftGeographicTickMarkFlag(booleanProp->getBoolean());
+         }
+         tempProp = containerProp->getProperty("Right tick enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setRightGeographicTickMarkFlag(booleanProp->getBoolean());
+         }
+      }
+   }
+   else if(property->getName() == "Geographic grid properties")
+   {
+      ossimContainerProperty* containerProp = PTR_CAST(ossimContainerProperty,
+                                                       property.get());
+      if(containerProp)
+      {
+         tempProp = containerProp->getProperty("Grid type");
+         if(tempProp.valid())
+         {
+            ossimString value = tempProp->valueToString();
+
+            if(value == "none")
+            {
+               setGeographicGridType(OSSIM_GRID_NONE);
+            }
+            else if(value == "line")
+            {
+               setGeographicGridType(OSSIM_GRID_LINE);
+            }
+            else if(value == "reseaux")
+            {
+               setGeographicGridType(OSSIM_GRID_RESEAUX);
+            }
+         }
+         tempProp = containerProp->getProperty("Horizontal spacing");
+         if(tempProp.valid())
+         {
+            setGeographicSpacingLon(tempProp->valueToString().toDouble());
+         }
+
+         tempProp = containerProp->getProperty("Vertical spacing");
+         if(tempProp.valid())
+         {
+            setGeographicSpacingLat(tempProp->valueToString().toDouble());
+         }
+
+         tempProp = containerProp->getProperty("Color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(tempProp.valid())
+         {
+            setGeographicGridColor(colorProp->getColor());
+         }
+      }
+   }
+   else if(property->getName() == "Meter label properties")
+   {
+      ossimContainerProperty* containerProp = PTR_CAST(ossimContainerProperty,
+                                                       property.get());
+      if(containerProp)
+      {
+         // first set the font format
+         //
+         tempProp = containerProp->getProperty("Top font");
+         fontProp = PTR_CAST(ossimFontProperty, tempProp.get());
+         if(fontProp)
+         {
+            setMeterTopLabelFont(fontProp->getFontInformation());
+         }
+         tempProp = containerProp->getProperty("Bottom font");
+         fontProp = PTR_CAST(ossimFontProperty, tempProp.get());
+         if(fontProp)
+         {
+            setMeterBottomLabelFont(fontProp->getFontInformation());
+         }
+         tempProp = containerProp->getProperty("Left font");
+         fontProp = PTR_CAST(ossimFontProperty, tempProp.get());
+         if(fontProp)
+         {
+            setMeterLeftLabelFont(fontProp->getFontInformation());
+         }
+         tempProp = containerProp->getProperty("Right font");
+         fontProp = PTR_CAST(ossimFontProperty, tempProp.get());
+         if(fontProp)
+         {
+            setMeterRightLabelFont(fontProp->getFontInformation());
+         }
+
+         // set color property
+         tempProp = containerProp->getProperty("Top color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(colorProp)
+         {
+            setTopMeterLabelColor(colorProp->getColor());
+         }
+         tempProp = containerProp->getProperty("Bottom color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(colorProp)
+         {
+            setBottomMeterLabelColor(colorProp->getColor());
+         }
+         tempProp = containerProp->getProperty("Left color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(colorProp)
+         {
+            setLeftMeterLabelColor(colorProp->getColor());
+         }
+         tempProp = containerProp->getProperty("Right color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(colorProp)
+         {
+            setRightMeterLabelColor(colorProp->getColor());
+         }
+
+         // set enable flags
+         tempProp = containerProp->getProperty("Top enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setTopMeterLabelFlag(booleanProp->getBoolean());
+         }
+
+         tempProp = containerProp->getProperty("Bottom enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setBottomMeterLabelFlag(booleanProp->getBoolean());
+         }
+
+         tempProp = containerProp->getProperty("Left enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setLeftMeterLabelFlag(booleanProp->getBoolean());
+         }
+
+         tempProp = containerProp->getProperty("Right enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setRightMeterLabelFlag(booleanProp->getBoolean());
+         }
+         
+         tempProp = containerProp->getProperty("Top tick enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setTopMeterTickMarkFlag(booleanProp->getBoolean());
+         }
+         tempProp = containerProp->getProperty("Bottom tick enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setBottomMeterTickMarkFlag(booleanProp->getBoolean());
+         }
+         tempProp = containerProp->getProperty("Left tick enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setLeftMeterTickMarkFlag(booleanProp->getBoolean());
+         }
+         tempProp = containerProp->getProperty("Right tick enabled");
+         booleanProp = PTR_CAST(ossimBooleanProperty,
+                                tempProp.get());
+         if(booleanProp)
+         {
+            setRightMeterTickMarkFlag(booleanProp->getBoolean());
+         }
+      }
+   }
+   else if(property->getName() == "Meter grid properties")
+   {
+      ossimContainerProperty* containerProp = PTR_CAST(ossimContainerProperty,
+                                                       property.get());
+      if(containerProp)
+      {
+         tempProp = containerProp->getProperty("Grid type");
+         if(tempProp.valid())
+         {
+            ossimString value = tempProp->valueToString();
+
+            if(value == "none")
+            {
+               setMeterGridType(OSSIM_GRID_NONE);
+            }
+            else if(value == "line")
+            {
+               setMeterGridType(OSSIM_GRID_LINE);
+            }
+            else if(value == "reseaux")
+            {
+               setMeterGridType(OSSIM_GRID_RESEAUX);
+            }
+         }
+         tempProp = containerProp->getProperty("Horizontal spacing");
+         if(tempProp.valid())
+         {
+            setMeterSpacingX(tempProp->valueToString().toDouble());
+         }
+
+         tempProp = containerProp->getProperty("Vertical spacing");
+         if(tempProp.valid())
+         {
+            setMeterSpacingY(tempProp->valueToString().toDouble());
+         }
+
+         tempProp = containerProp->getProperty("Color");
+         colorProp = PTR_CAST(ossimColorProperty, tempProp.get());
+         if(tempProp.valid())
+         {
+            setMeterGridColor(colorProp->getColor());
+         }
+      }
+   }
+   else if(property->getName() == "Title properties")
+   {
+      ossimContainerProperty* container = PTR_CAST(ossimContainerProperty,
+                                                   property.get());
+      if(container)
+      {
+         ossimProperty* titleProp = container->getProperty("Title").get();
+         if(titleProp)
+         {
+            setTitle(titleProp->valueToString());
+         }
+         ossimFontProperty* fontProp = PTR_CAST(ossimFontProperty,
+                                                container->getProperty("Font").get());
+         ossimColorProperty* colorProp = PTR_CAST(ossimColorProperty,
+                                                  container->getProperty("Color").get());
+
+         if(fontProp)
+         {
+            setTitleFont(fontProp->getFontInformation());
+         }
+         if(colorProp)
+         {
+            setTitleColor(colorProp->getColor());
+         }
+      }
+   }
+   else if(property->getName() == "Viewport properties")
+   {
+      ossimContainerProperty* container = PTR_CAST(ossimContainerProperty,
+                                                   property.get());
+      if(container)
+      {
+         int w = -1;
+         int h = -1;
+         tempProp = container->getProperty("Width");
+         if(tempProp.valid())
+         {
+            w = tempProp->valueToString().toInt32();
+         }
+         tempProp = container->getProperty("Height");
+         if(tempProp.valid())
+         {
+            h = tempProp->valueToString().toInt32();
+         }
+         setViewWidthHeight(ossimIpt(w, h));
+      }
+   }
+   else if(property->getName() == "Border color")
+   {
+      colorProp = PTR_CAST(ossimColorProperty,
+                           property.get());
+      if(colorProp)
+      {
+         setBorderColor(colorProp->getColor());
+      }
+   }
+   else if(property->getName() == "Border size")
+   {
+      ossimContainerProperty* container = PTR_CAST(ossimContainerProperty,
+                                                   property.get());
+      if(container)
+      {
+         tempProp = container->getProperty("Top");
+         if(tempProp.valid())
+         {
+            setTopBorderLength(tempProp->valueToString().toInt32());
+            
+         }
+         tempProp = container->getProperty("Bottom");
+         if(tempProp.valid())
+         {
+            setBottomBorderLength(tempProp->valueToString().toInt32());
+            
+         }
+         tempProp = container->getProperty("Left");
+         if(tempProp.valid())
+         {
+            setLeftBorderLength(tempProp->valueToString().toInt32());
+            
+         }
+         tempProp = container->getProperty("Right");
+         if(tempProp.valid())
+         {
+            setRightBorderLength(tempProp->valueToString().toInt32());
+         }
+      }
+   }
+   else
+   {
+      ossimAnnotationSource::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimMapCompositionSource::getProperty(const ossimString& name)const
+{
+   if(name == "Viewport properties")
+   {
+      ossimContainerProperty* container = new ossimContainerProperty(name);
+
+      container->addChild(new ossimNumericProperty("Width",
+                                                   ossimString::toString(theViewWidthHeight.x),
+                                                   -1,1.0/DBL_EPSILON));
+      container->addChild(new ossimNumericProperty("Height",
+                                                   ossimString::toString(theViewWidthHeight.y),
+                                                   -1,1.0/DBL_EPSILON));
+      container->setCacheRefreshBit();
+      return container;
+   }
+   else if(name == "Geographic label properties")
+   {
+
+      ossimContainerProperty* container = new ossimContainerProperty(name);
+      
+      container->addChild(new ossimFontProperty("Top font",
+                                                theGeographicTopLabelFontInfo));
+      container->addChild(new ossimColorProperty("Top color",
+                                                 theTopGeographicLabelColor));
+      container->addChild(new ossimBooleanProperty("Top enabled",
+                                                   theTopGeographicLabelFlag));
+      container->addChild(new ossimBooleanProperty("Top tick enabled",
+                                                   theTopGeographicTickFlag));
+      
+      container->addChild(new ossimFontProperty("Bottom font",
+                                                theGeographicBottomLabelFontInfo));
+      container->addChild(new ossimColorProperty("Bottom color",
+                                                 theBottomGeographicLabelColor));
+      container->addChild(new ossimBooleanProperty("Bottom enabled",
+                                                   theBottomGeographicLabelFlag));
+      container->addChild(new ossimBooleanProperty("Bottom tick enabled",
+                                                   theBottomGeographicTickFlag));
+      
+      container->addChild(new ossimFontProperty("Left font",
+                                                theGeographicLeftLabelFontInfo));
+      container->addChild(new ossimColorProperty("Left color",
+                                                 theLeftGeographicLabelColor));
+      container->addChild(new ossimBooleanProperty("Left enabled",
+                                                   theLeftGeographicLabelFlag));
+      container->addChild(new ossimBooleanProperty("Left tick enabled",
+                                                   theLeftGeographicTickFlag));
+      
+      container->addChild(new ossimFontProperty("Right font",
+                                                theGeographicRightLabelFontInfo));
+      container->addChild(new ossimColorProperty("Right color",
+                                                 theRightGeographicLabelColor));
+      container->addChild(new ossimBooleanProperty("Right enabled",
+                                                   theRightGeographicLabelFlag));
+      container->addChild(new ossimBooleanProperty("Right tick enabled",
+                                                   theRightGeographicTickFlag));
+      container->setCacheRefreshBit();
+      return container;
+   }
+   else if(name == "Geographic grid properties")
+   {
+      ossimContainerProperty* container = new ossimContainerProperty(name);
+      std::vector<ossimString> gridTypeConstraints;
+      ossimString value = GRID_TYPE_ENUM_NAMES[(int)theGeographicGridType];
+
+      gridTypeConstraints.push_back("none");
+      gridTypeConstraints.push_back("line");
+      gridTypeConstraints.push_back("reseaux");
+      
+      container->addChild(new ossimStringProperty("Grid type",
+                                                  value,
+                                                  false,
+                                                  gridTypeConstraints));
+      container->addChild(new ossimColorProperty("Color",
+                                                 theGeographicGridColor));
+
+      container->addChild(new ossimNumericProperty("Horizontal spacing",
+                                                   ossimString::toString(theGeographicSpacing.x),
+                                                   0.0, 180.0));
+
+      container->addChild(new ossimNumericProperty("Vertical spacing",
+                                                   ossimString::toString(theGeographicSpacing.y),
+                                                   0.0, 180.0));
+                                                   
+      container->setCacheRefreshBit();
+      return container;
+   }
+   else if(name == "Meter label properties")
+   {
+      ossimContainerProperty* container = new ossimContainerProperty(name);
+      
+      container->addChild(new ossimFontProperty("Top font",
+                                                theMeterTopLabelFontInfo));
+      container->addChild(new ossimColorProperty("Top color",
+                                                 theTopMeterLabelColor));
+      container->addChild(new ossimBooleanProperty("Top enabled",
+                                                   theTopMeterLabelFlag));
+      container->addChild(new ossimBooleanProperty("Top tick enabled",
+                                                   theTopMeterTickFlag));
+      
+      container->addChild(new ossimFontProperty("Bottom font",
+                                                theMeterBottomLabelFontInfo));
+      container->addChild(new ossimColorProperty("Bottom color",
+                                                 theBottomMeterLabelColor));
+      container->addChild(new ossimBooleanProperty("Bottom enabled",
+                                                   theBottomMeterLabelFlag));
+      container->addChild(new ossimBooleanProperty("Bottom tick enabled",
+                                                   theBottomMeterTickFlag));
+      
+      container->addChild(new ossimFontProperty("Left font",
+                                                theMeterLeftLabelFontInfo));
+      container->addChild(new ossimColorProperty("Left color",
+                                                 theLeftMeterLabelColor));
+      container->addChild(new ossimBooleanProperty("Left enabled",
+                                                   theLeftMeterLabelFlag));
+      container->addChild(new ossimBooleanProperty("Left tick enabled",
+                                                   theLeftMeterTickFlag));
+      
+      container->addChild(new ossimFontProperty("Right font",
+                                                theMeterRightLabelFontInfo));
+      container->addChild(new ossimColorProperty("Right color",
+                                                 theRightMeterLabelColor));
+      container->addChild(new ossimBooleanProperty("Right enabled",
+                                                   theRightMeterLabelFlag));
+      container->addChild(new ossimBooleanProperty("Right tick enabled",
+                                                   theRightMeterTickFlag));
+      
+      container->setCacheRefreshBit();
+      return container;
+   }
+   else if(name == "Meter grid properties")
+   {
+      ossimContainerProperty* container = new ossimContainerProperty(name);
+      std::vector<ossimString> gridTypeConstraints;
+      ossimString value = GRID_TYPE_ENUM_NAMES[(int)theMeterGridType];
+
+      gridTypeConstraints.push_back("none");
+      gridTypeConstraints.push_back("line");
+      gridTypeConstraints.push_back("reseaux");
+      
+      container->addChild(new ossimStringProperty("Grid type",
+                                                  value,
+                                                  false,
+                                                  gridTypeConstraints));
+      container->addChild(new ossimColorProperty("Color",
+                                                 theMeterGridColor));
+      
+      container->addChild(new ossimNumericProperty("Horizontal spacing",
+                                                   ossimString::toString(theMeterSpacing.x),
+                                                   0.0, 1.0/DBL_EPSILON));
+
+      container->addChild(new ossimNumericProperty("Vertical spacing",
+                                                   ossimString::toString(theMeterSpacing.y),
+                                                   0.0, 1.0/DBL_EPSILON));
+      container->setCacheRefreshBit();
+      return container;
+   }
+   else if(name == "Title properties")
+   {
+      ossimContainerProperty* container = new ossimContainerProperty(name);
+      container->addChild(new ossimTextProperty("Title",
+                                                theTitleString));
+      container->addChild(new ossimFontProperty("Font",
+                                                theTitleFontInfo));
+      container->addChild(new ossimColorProperty("Color",
+                                                 theTitleColor));
+      
+      container->setCacheRefreshBit();
+      return container;
+   }
+   else if(name == "Border size")
+   {
+      ossimContainerProperty* container = new ossimContainerProperty(name);
+      
+      container->addChild(new ossimNumericProperty("Top",
+                                                   ossimString::toString(theTopBorderLength),
+                                                   0,10000));
+      container->addChild(new ossimNumericProperty("Bottom",
+                                                   ossimString::toString(theBottomBorderLength),
+                                                   0,10000));
+      container->addChild(new ossimNumericProperty("Left",
+                                                   ossimString::toString(theLeftBorderLength),
+                                                   0,10000));
+      container->addChild(new ossimNumericProperty("Right",
+                                                   ossimString::toString(theRightBorderLength),
+                                                   0,10000));
+      container->setCacheRefreshBit();
+      return container;
+   }
+   else if(name == "Border color")
+   {
+      ossimColorProperty* colorProp = new ossimColorProperty(name,
+                                                             theBorderColor);
+      colorProp->setCacheRefreshBit();
+      
+      return colorProp;
+   }
+   else if(name == "Viewport properties")
+   {
+      
+   }
+   return ossimAnnotationSource::getProperty(name);
+}
+
+void ossimMapCompositionSource::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimAnnotationSource::getPropertyNames(propertyNames);
+
+   
+   propertyNames.push_back("Title properties");
+   propertyNames.push_back("Border size");
+   propertyNames.push_back("Border color");
+   propertyNames.push_back("Viewport properties");
+   propertyNames.push_back("Geographic label properties");
+   propertyNames.push_back("Geographic grid properties");
+   propertyNames.push_back("Meter label properties");
+   propertyNames.push_back("Meter grid properties");
+}
+
+bool ossimMapCompositionSource::saveState(ossimKeywordlist& kwl,
+                                          const char* prefix)const
+{
+   kwl.add(prefix,
+           VIEW_WIDTH_KW,
+           theViewWidthHeight.x,
+           true);
+   
+   kwl.add(prefix,
+           VIEW_HEIGHT_KW,
+           theViewWidthHeight.x,
+           true);
+   
+   kwl.add(prefix,
+           METER_GRID_SPACING_X_KW,
+           theMeterSpacing.x,
+           true);
+
+   kwl.add(prefix,
+           METER_GRID_SPACING_Y_KW,
+           theMeterSpacing.y,
+           true);
+   
+   kwl.add(prefix,
+           GEO_GRID_SPACING_LON_KW,
+           theGeographicSpacing.lon,
+           true);
+
+   kwl.add(prefix,
+           GEO_GRID_SPACING_LAT_KW,
+           theGeographicSpacing.lat,
+           true);
+
+   ossimString meterGridType = "line";
+   if(theMeterGridType == OSSIM_GRID_NONE)
+   {
+      meterGridType = "none";
+   }
+   else if(theMeterGridType == OSSIM_GRID_RESEAUX)
+   {
+      meterGridType = "reseaux";
+   }
+   
+   kwl.add(prefix,
+           METER_GRID_TYPE_KW,
+           meterGridType.c_str(),
+           true);
+
+   ossimString geoGridType = "line";
+   if(theGeographicGridType == OSSIM_GRID_NONE)
+   {
+      geoGridType = "none";
+   }
+   else if(theGeographicGridType == OSSIM_GRID_RESEAUX)
+   {
+      geoGridType = "reseaux";
+   }
+
+   kwl.add(prefix,
+           GEO_GRID_TYPE_KW,
+           geoGridType.c_str(),
+           true);
+
+   kwl.add(prefix,
+           TOP_BORDER_LENGTH_KW,
+           theTopBorderLength,
+           true);
+   
+   kwl.add(prefix,
+           BOTTOM_BORDER_LENGTH_KW,
+           theBottomBorderLength,
+           true);
+
+   kwl.add(prefix,
+           LEFT_BORDER_LENGTH_KW,
+           theLeftBorderLength,
+           true);
+
+   kwl.add(prefix,
+           RIGHT_BORDER_LENGTH_KW,
+           theRightBorderLength,
+           true);
+
+   kwl.add(prefix,
+           BORDER_COLOR_KW,
+           (ossimString::toString(theBorderColor.getR()) +" "+
+            ossimString::toString(theBorderColor.getG()) +" "+
+            ossimString::toString(theBorderColor.getB())).c_str(),
+           true);
+
+   kwl.add(prefix,
+           GEO_GRID_COLOR_KW,
+           (ossimString::toString(theGeographicGridColor.getR()) +" "+
+            ossimString::toString(theGeographicGridColor.getG()) +" "+
+            ossimString::toString(theGeographicGridColor.getB())).c_str(),
+           true);
+
+   kwl.add(prefix,
+           METER_GRID_COLOR_KW,
+           (ossimString::toString(theMeterGridColor.getR()) +" "+
+            ossimString::toString(theMeterGridColor.getG()) +" "+
+            ossimString::toString(theMeterGridColor.getB())).c_str(),
+           true);
+
+   kwl.add(prefix,
+           TITLE_STRING_KW,
+           theTitleString.c_str(),
+           true);
+   
+   kwl.add(prefix,
+           TITLE_COLOR_KW,
+           (ossimString::toString(theTitleColor.getR()) +" "+
+            ossimString::toString(theTitleColor.getG()) +" "+
+            ossimString::toString(theTitleColor.getB())).c_str(),
+           true);
+
+   kwl.add(prefix,
+           TOP_GEO_LABEL_COLOR_KW,
+           (ossimString::toString(theTopGeographicLabelColor.getR()) +" "+
+            ossimString::toString(theTopGeographicLabelColor.getG()) +" "+
+            ossimString::toString(theTopGeographicLabelColor.getB())).c_str(),
+           true);
+
+   kwl.add(prefix,
+           BOTTOM_GEO_LABEL_COLOR_KW,
+           (ossimString::toString(theBottomGeographicLabelColor.getR()) +" "+
+            ossimString::toString(theBottomGeographicLabelColor.getG()) +" "+
+            ossimString::toString(theBottomGeographicLabelColor.getB())).c_str(),
+           true);
+   kwl.add(prefix,
+           LEFT_GEO_LABEL_COLOR_KW,
+           (ossimString::toString(theLeftGeographicLabelColor.getR()) +" "+
+            ossimString::toString(theLeftGeographicLabelColor.getG()) +" "+
+            ossimString::toString(theLeftGeographicLabelColor.getB())).c_str(),
+           true);
+   kwl.add(prefix,
+           RIGHT_GEO_LABEL_COLOR_KW,
+           (ossimString::toString(theRightGeographicLabelColor.getR()) +" "+
+            ossimString::toString(theRightGeographicLabelColor.getG()) +" "+
+            ossimString::toString(theRightGeographicLabelColor.getB())).c_str(),
+           true);
+
+   kwl.add(prefix,
+           TOP_GEO_LABEL_FORMAT_KW,
+           theTopGeographicFormat,
+           true);
+
+   kwl.add(prefix,
+           BOTTOM_GEO_LABEL_FORMAT_KW,
+           theBottomGeographicFormat,
+           true);
+   kwl.add(prefix,
+           LEFT_GEO_LABEL_FORMAT_KW,
+           theLeftGeographicFormat,
+           true);
+   kwl.add(prefix,
+           RIGHT_GEO_LABEL_FORMAT_KW,
+           theRightGeographicFormat,
+           true);
+
+   kwl.add(prefix,
+           TOP_GEO_LABEL_FLAG_KW,
+           (int)theTopGeographicLabelFlag,
+           true);
+
+   kwl.add(prefix,
+           BOTTOM_GEO_LABEL_FLAG_KW,
+           (int)theBottomGeographicLabelFlag,
+           true);
+
+   kwl.add(prefix,
+           LEFT_GEO_LABEL_FLAG_KW,
+           (int)theLeftGeographicLabelFlag,
+           true);
+
+   kwl.add(prefix,
+           RIGHT_GEO_LABEL_FLAG_KW,
+           (int)theRightGeographicLabelFlag,
+           true);
+
+   kwl.add(prefix,
+           TOP_METER_LABEL_COLOR_KW,
+           (ossimString::toString(theTopMeterLabelColor.getR()) +" "+
+            ossimString::toString(theTopMeterLabelColor.getG()) +" "+
+            ossimString::toString(theTopMeterLabelColor.getB())).c_str(),
+           true);
+
+   kwl.add(prefix,
+           BOTTOM_METER_LABEL_COLOR_KW,
+           (ossimString::toString(theBottomMeterLabelColor.getR()) +" "+
+            ossimString::toString(theBottomMeterLabelColor.getG()) +" "+
+            ossimString::toString(theBottomMeterLabelColor.getB())).c_str(),
+           true);
+   kwl.add(prefix,
+           LEFT_METER_LABEL_COLOR_KW,
+           (ossimString::toString(theLeftMeterLabelColor.getR()) +" "+
+            ossimString::toString(theLeftMeterLabelColor.getG()) +" "+
+            ossimString::toString(theLeftMeterLabelColor.getB())).c_str(),
+           true);
+   kwl.add(prefix,
+           RIGHT_METER_LABEL_COLOR_KW,
+           (ossimString::toString(theRightMeterLabelColor.getR()) +" "+
+            ossimString::toString(theRightMeterLabelColor.getG()) +" "+
+            ossimString::toString(theRightMeterLabelColor.getB())).c_str(),
+           true);
+
+
+   kwl.add(prefix,
+           TOP_METER_LABEL_FLAG_KW,
+           (int)theTopMeterLabelFlag,
+           true);
+
+   kwl.add(prefix,
+           BOTTOM_METER_LABEL_FLAG_KW,
+           (int)theBottomMeterLabelFlag,
+           true);
+
+   kwl.add(prefix,
+           LEFT_METER_LABEL_FLAG_KW,
+           (int)theLeftMeterLabelFlag,
+           true);
+
+   kwl.add(prefix,
+           RIGHT_METER_LABEL_FLAG_KW,
+           (int)theRightMeterLabelFlag,
+           true);
+   
+   theGeographicTopLabelFontInfo.saveState(kwl, (ossimString(prefix) + ossimString(TOP_GEO_LABEL_FONT_KW) + ".").c_str());
+   theGeographicBottomLabelFontInfo.saveState(kwl, (ossimString(prefix) + ossimString(BOTTOM_GEO_LABEL_FONT_KW) + ".").c_str());
+   theGeographicLeftLabelFontInfo.saveState(kwl, (ossimString(prefix) + ossimString(LEFT_GEO_LABEL_FONT_KW) + ".").c_str());
+   theGeographicRightLabelFontInfo.saveState(kwl, (ossimString(prefix) + ossimString(RIGHT_GEO_LABEL_FONT_KW) + ".").c_str());
+
+   theMeterTopLabelFontInfo.saveState(kwl, (ossimString(prefix) + ossimString(TOP_METER_LABEL_FONT_KW) + ".").c_str());
+   theMeterBottomLabelFontInfo.saveState(kwl, (ossimString(prefix) + ossimString(BOTTOM_METER_LABEL_FONT_KW) + ".").c_str());
+   theMeterLeftLabelFontInfo.saveState(kwl, (ossimString(prefix) + ossimString(LEFT_METER_LABEL_FONT_KW) + ".").c_str());
+   theMeterRightLabelFontInfo.saveState(kwl, (ossimString(prefix) + ossimString(RIGHT_METER_LABEL_FONT_KW) + ".").c_str());
+   
+   theTitleFontInfo.saveState(kwl, (ossimString(prefix) + ossimString(TITLE_FONT_KW) + ".").c_str());
+   
+           
+   return ossimImageSource::saveState(kwl, prefix);
+   
+}
+
+bool ossimMapCompositionSource::loadState(const ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   const char* viewWidth            = kwl.find(prefix, VIEW_WIDTH_KW);
+   const char* viewHeight           = kwl.find(prefix, VIEW_HEIGHT_KW);
+   const char* meterGridSpacingX    = kwl.find(prefix, METER_GRID_SPACING_X_KW);
+   const char* meterGridSpacingY    = kwl.find(prefix, METER_GRID_SPACING_Y_KW);
+   const char* geoGridSpacingLon    = kwl.find(prefix, GEO_GRID_SPACING_LON_KW);
+   const char* geoGridSpacingLat    = kwl.find(prefix, GEO_GRID_SPACING_LAT_KW);
+   const char* meterGridType        = kwl.find(prefix, METER_GRID_TYPE_KW);
+   const char* geoGridType          = kwl.find(prefix, GEO_GRID_TYPE_KW);
+   const char* topBorderLength      = kwl.find(prefix, TOP_BORDER_LENGTH_KW);
+   const char* bottomBorderLength   = kwl.find(prefix, BOTTOM_BORDER_LENGTH_KW);
+   const char* leftBorderLength     = kwl.find(prefix, LEFT_BORDER_LENGTH_KW);
+   const char* rightBorderLength    = kwl.find(prefix, RIGHT_BORDER_LENGTH_KW);
+   
+   const char* borderColor          = kwl.find(prefix, BORDER_COLOR_KW);
+   const char* geoGridColor         = kwl.find(prefix, GEO_GRID_COLOR_KW);
+   const char* meterGridColor       = kwl.find(prefix, METER_GRID_COLOR_KW);
+   const char* titleString          = kwl.find(prefix, TITLE_STRING_KW);
+   const char* titleColor           = kwl.find(prefix, TITLE_COLOR_KW);
+
+   const char* topGeoLabelColor     = kwl.find(prefix, TOP_GEO_LABEL_COLOR_KW);
+   const char* bottomGeoLabelColor  = kwl.find(prefix, BOTTOM_GEO_LABEL_COLOR_KW);
+   const char* leftGeoLabelColor    = kwl.find(prefix, LEFT_GEO_LABEL_COLOR_KW);
+   const char* rightGeoLabelColor   = kwl.find(prefix, RIGHT_GEO_LABEL_COLOR_KW);
+
+   const char* topMeterLabelColor     = kwl.find(prefix, TOP_METER_LABEL_COLOR_KW);
+   const char* bottomMeterLabelColor  = kwl.find(prefix, BOTTOM_METER_LABEL_COLOR_KW);
+   const char* leftMeterLabelColor    = kwl.find(prefix, LEFT_METER_LABEL_COLOR_KW);
+   const char* rightMeterLabelColor   = kwl.find(prefix, RIGHT_METER_LABEL_COLOR_KW);
+   
+   const char* topGeoLabelFormat    = kwl.find(prefix, TOP_GEO_LABEL_FORMAT_KW);
+   const char* bottomGeoLabelFormat = kwl.find(prefix, BOTTOM_GEO_LABEL_FORMAT_KW);
+   const char* leftGeoLabelFormat   = kwl.find(prefix, LEFT_GEO_LABEL_FORMAT_KW);
+   const char* rightGeoLabelFormat  = kwl.find(prefix, RIGHT_GEO_LABEL_FORMAT_KW);
+
+   const char* topGeoLabelFlag      = kwl.find(prefix, TOP_GEO_LABEL_FLAG_KW);
+   const char* bottomGeoLabelFlag   = kwl.find(prefix, BOTTOM_GEO_LABEL_FLAG_KW);
+   const char* leftGeoLabelFlag     = kwl.find(prefix, LEFT_GEO_LABEL_FLAG_KW);
+   const char* rightGeoLabelFlag    = kwl.find(prefix, RIGHT_GEO_LABEL_FLAG_KW);
+
+   const char* topMeterLabelFlag    = kwl.find(prefix, TOP_METER_LABEL_FLAG_KW);
+   const char* bottomMeterLabelFlag = kwl.find(prefix, BOTTOM_METER_LABEL_FLAG_KW);
+   const char* leftMeterLabelFlag   = kwl.find(prefix, LEFT_METER_LABEL_FLAG_KW);
+   const char* rightMeterLabelFlag  = kwl.find(prefix, RIGHT_METER_LABEL_FLAG_KW);
+
+   deleteFixedAnnotations();
+   theViewWidthHeight.makeNan();
+   
+   if(viewWidth)
+   {
+      theViewWidthHeight.x = ossimString(viewWidth).toLong();
+   }
+   if(viewHeight)
+   {
+      theViewWidthHeight.y = ossimString(viewHeight).toLong();
+   }
+   
+   if(meterGridSpacingX)
+   {
+      theMeterSpacing.x = ossimString(meterGridSpacingX).toDouble();
+   }
+
+   if(meterGridSpacingY)
+   {
+      theMeterSpacing.y = ossimString(meterGridSpacingY).toDouble();
+   }
+   if(geoGridSpacingLon)
+   {
+      theGeographicSpacing.lon = ossimString(geoGridSpacingLon).toDouble();
+   }
+   if(geoGridSpacingLat)
+   {
+      theGeographicSpacing.lat = ossimString(geoGridSpacingLat).toDouble();
+   }
+   if(meterGridType)
+   {
+      ossimString type = ossimString(meterGridType).trim().downcase();
+      if(type == "reseaux")
+      {
+         theMeterGridType = OSSIM_GRID_RESEAUX;
+      }
+      else if(type == "line")
+      {
+         theMeterGridType = OSSIM_GRID_LINE;
+      }
+      else
+      {
+         theMeterGridType = OSSIM_GRID_NONE;
+      }
+   }
+
+   if(geoGridType)
+   {
+      ossimString type = ossimString(geoGridType).trim().downcase();
+      if(type == "reseaux")
+      {
+         theGeographicGridType = OSSIM_GRID_RESEAUX;
+      }
+      else if(type == "line")
+      {
+         theGeographicGridType = OSSIM_GRID_LINE;
+      }
+      else
+      {
+         theGeographicGridType = OSSIM_GRID_NONE;
+      }
+   }
+
+   if(topBorderLength)
+   {
+      theTopBorderLength = ossimString(topBorderLength).toULong();
+   }
+
+   if(bottomBorderLength)
+   {
+      theBottomBorderLength = ossimString(bottomBorderLength).toULong();
+   }
+   if(leftBorderLength)
+   {
+      theLeftBorderLength = ossimString(leftBorderLength).toULong();
+   }
+   if(rightBorderLength)
+   {
+      theRightBorderLength = ossimString(rightBorderLength).toULong();
+   }
+
+   if(borderColor)
+   {
+      istringstream in(borderColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theBorderColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(geoGridColor)
+   {
+      istringstream in(geoGridColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theGeographicGridColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(meterGridColor)
+   {
+      istringstream in(meterGridColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theMeterGridColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);      
+   }
+
+   if(titleString)
+   {
+      theTitleString = titleString;
+   }
+   
+   if(titleColor)
+   {
+      istringstream in(titleColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theTitleColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(topGeoLabelColor)
+   {
+      istringstream in(topGeoLabelColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theTopGeographicLabelColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(bottomGeoLabelColor)
+   {
+      istringstream in(bottomGeoLabelColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theBottomGeographicLabelColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(leftGeoLabelColor)
+   {
+      istringstream in(leftGeoLabelColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theLeftGeographicLabelColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(rightGeoLabelColor)
+   {
+      istringstream in(rightGeoLabelColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theRightGeographicLabelColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+
+/////
+   if(topMeterLabelColor)
+   {
+      istringstream in(topMeterLabelColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theTopMeterLabelColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(bottomMeterLabelColor)
+   {
+      istringstream in(bottomMeterLabelColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theBottomMeterLabelColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(leftMeterLabelColor)
+   {
+      istringstream in(leftMeterLabelColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theLeftMeterLabelColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(rightMeterLabelColor)
+   {
+      istringstream in(rightMeterLabelColor);
+
+      int r;
+      int g;
+      int b;
+      in >> r >> g >> b;
+
+      theRightMeterLabelColor = ossimRgbVector((ossim_uint8)r, (ossim_uint8)g, (ossim_uint8)b);
+   }
+
+   if(topGeoLabelFormat)
+   {
+      theTopGeographicFormat = topGeoLabelFormat;
+   }
+   
+   if(bottomGeoLabelFormat)
+   {
+      theBottomGeographicFormat = bottomGeoLabelFormat;
+   }
+   
+   if(leftGeoLabelFormat)
+   {
+      theLeftGeographicFormat = leftGeoLabelFormat;
+   }
+   
+   if(rightGeoLabelFormat)
+   {
+      theRightGeographicFormat = rightGeoLabelFormat;
+   }
+
+   if(topGeoLabelFlag)
+   {
+      theTopGeographicLabelFlag = ossimString(topGeoLabelFlag).toBool();
+   }
+   if(bottomGeoLabelFlag)
+   {
+      theBottomGeographicLabelFlag = ossimString(bottomGeoLabelFlag).toBool();
+   }
+   if(leftGeoLabelFlag)
+   {
+      theLeftGeographicLabelFlag = ossimString(leftGeoLabelFlag).toBool();
+   }
+   if(rightGeoLabelFlag)
+   {
+      theRightGeographicLabelFlag = ossimString(rightGeoLabelFlag).toBool();
+   }
+
+   if(topMeterLabelFlag)
+   {
+      theTopMeterLabelFlag = ossimString(topMeterLabelFlag).toBool();
+   }
+   if(bottomMeterLabelFlag)
+   {
+      theBottomMeterLabelFlag = ossimString(bottomMeterLabelFlag).toBool();
+   }
+   if(leftMeterLabelFlag)
+   {
+      theLeftMeterLabelFlag = ossimString(leftMeterLabelFlag).toBool();
+   }
+   if(rightMeterLabelFlag)
+   {
+      theRightMeterLabelFlag = ossimString(rightMeterLabelFlag).toBool();
+   }
+   
+   theGeographicTopLabelFontInfo.loadState(kwl, (ossimString(prefix) + ossimString(TOP_GEO_LABEL_FONT_KW) + ".").c_str());
+   theGeographicBottomLabelFontInfo.loadState(kwl, (ossimString(prefix) + ossimString(BOTTOM_GEO_LABEL_FONT_KW) + ".").c_str());
+   theGeographicLeftLabelFontInfo.loadState(kwl, (ossimString(prefix) + ossimString(LEFT_GEO_LABEL_FONT_KW) + ".").c_str());
+   theGeographicRightLabelFontInfo.loadState(kwl, (ossimString(prefix) + ossimString(RIGHT_GEO_LABEL_FONT_KW) + ".").c_str());
+
+   theMeterTopLabelFontInfo.loadState(kwl, (ossimString(prefix) + ossimString(TOP_METER_LABEL_FONT_KW) + ".").c_str());
+   theMeterBottomLabelFontInfo.loadState(kwl, (ossimString(prefix) + ossimString(BOTTOM_METER_LABEL_FONT_KW) + ".").c_str());
+   theMeterLeftLabelFontInfo.loadState(kwl, (ossimString(prefix) + ossimString(LEFT_METER_LABEL_FONT_KW) + ".").c_str());
+   theMeterRightLabelFontInfo.loadState(kwl, (ossimString(prefix) + ossimString(RIGHT_METER_LABEL_FONT_KW) + ".").c_str());
+   
+   theTitleFontInfo.loadState(kwl, (ossimString(prefix) + ossimString(TITLE_FONT_KW) + ".").c_str());
+   if(theTitleFont)
+   {
+      delete theTitleFont;
+      theTitleFont = NULL;
+   }
+   if(theGeographicTopLabelFont)
+   {
+      delete theGeographicTopLabelFont;
+      theGeographicTopLabelFont = NULL;
+   }
+   if(theGeographicBottomLabelFont)
+   {
+      delete theGeographicBottomLabelFont;
+      theGeographicBottomLabelFont = NULL;
+   }
+   if(theGeographicLeftLabelFont)
+   {
+      delete theGeographicLeftLabelFont;
+      theGeographicLeftLabelFont = NULL;
+   }
+   if(theGeographicRightLabelFont)
+   {
+      delete theGeographicRightLabelFont;
+      theGeographicRightLabelFont = NULL;
+   }
+
+   if(theMeterTopLabelFont)
+   {
+      delete theMeterTopLabelFont;
+      theMeterTopLabelFont = NULL;
+   }
+   if(theMeterBottomLabelFont)
+   {
+      delete theMeterBottomLabelFont;
+      theMeterBottomLabelFont = NULL;
+   }
+   if(theMeterLeftLabelFont)
+   {
+      delete theMeterLeftLabelFont;
+      theMeterLeftLabelFont = NULL;
+   }
+   if(theMeterRightLabelFont)
+   {
+      delete theMeterRightLabelFont;
+      theMeterRightLabelFont = NULL;
+   }
+   
+   theTitleFont = ossimFontFactoryRegistry::instance()->createFont(theTitleFontInfo);
+   theGeographicTopLabelFont = ossimFontFactoryRegistry::instance()->createFont(theGeographicTopLabelFontInfo);
+   theGeographicBottomLabelFont = ossimFontFactoryRegistry::instance()->createFont(theGeographicBottomLabelFontInfo);
+   theGeographicLeftLabelFont = ossimFontFactoryRegistry::instance()->createFont(theGeographicLeftLabelFontInfo);
+   theGeographicRightLabelFont = ossimFontFactoryRegistry::instance()->createFont(theGeographicRightLabelFontInfo);
+
+   theMeterTopLabelFont = ossimFontFactoryRegistry::instance()->createFont(theMeterTopLabelFontInfo);
+   theMeterBottomLabelFont = ossimFontFactoryRegistry::instance()->createFont(theMeterBottomLabelFontInfo);
+   theMeterLeftLabelFont = ossimFontFactoryRegistry::instance()->createFont(theMeterLeftLabelFontInfo);
+   theMeterRightLabelFont = ossimFontFactoryRegistry::instance()->createFont(theMeterRightLabelFontInfo);
+   
+   vector<ossimFontInformation> info;
+
+   
+   if(!theTitleFont)
+   {
+      theTitleFont = (ossimFont*)ossimFontFactoryRegistry::instance()->getDefaultFont()->dup();
+      theTitleFont->getFontInformation(info);
+      theTitleFontInfo = info[0];
+   }
+   if(!theGeographicTopLabelFont)
+   {
+      info.clear();
+      theGeographicTopLabelFont = (ossimFont*)ossimFontFactoryRegistry::instance()->getDefaultFont()->dup();
+      theGeographicTopLabelFont->getFontInformation(info);
+      theGeographicTopLabelFontInfo = info[0];
+   }
+   if(!theGeographicBottomLabelFont)
+   {
+      info.clear();
+      theGeographicBottomLabelFont = (ossimFont*)ossimFontFactoryRegistry::instance()->getDefaultFont()->dup();
+      theGeographicBottomLabelFont->getFontInformation(info);
+      theGeographicBottomLabelFontInfo = info[0];
+   }
+   if(!theGeographicLeftLabelFont)
+   {
+      info.clear();
+      theGeographicLeftLabelFont = (ossimFont*)ossimFontFactoryRegistry::instance()->getDefaultFont()->dup();
+      theGeographicLeftLabelFont->getFontInformation(info);
+      theGeographicLeftLabelFontInfo = info[0];
+   }
+   if(!theGeographicRightLabelFont)
+   {
+      info.clear();
+      theGeographicRightLabelFont = (ossimFont*)ossimFontFactoryRegistry::instance()->getDefaultFont()->dup();
+      theGeographicRightLabelFont->getFontInformation(info);
+      theGeographicRightLabelFontInfo = info[0];
+   }
+
+   if(!theMeterTopLabelFont)
+   {
+      info.clear();
+      theMeterTopLabelFont = (ossimFont*)ossimFontFactoryRegistry::instance()->getDefaultFont()->dup();
+      theMeterTopLabelFont->getFontInformation(info);
+      theMeterTopLabelFontInfo = info[0];
+   }
+   if(!theMeterBottomLabelFont)
+   {
+      info.clear();
+      theMeterBottomLabelFont = (ossimFont*)ossimFontFactoryRegistry::instance()->getDefaultFont()->dup();
+      theMeterBottomLabelFont->getFontInformation(info);
+      theMeterBottomLabelFontInfo = info[0];
+   }
+   if(!theMeterLeftLabelFont)
+   {
+      info.clear();
+      theMeterLeftLabelFont = (ossimFont*)ossimFontFactoryRegistry::instance()->getDefaultFont()->dup();
+      theMeterLeftLabelFont->getFontInformation(info);
+      theMeterLeftLabelFontInfo = info[0];
+   }
+   if(!theMeterRightLabelFont)
+   {
+      info.clear();
+      theMeterRightLabelFont = (ossimFont*)ossimFontFactoryRegistry::instance()->getDefaultFont()->dup();
+      theMeterRightLabelFont->getFontInformation(info);
+      theMeterRightLabelFontInfo = info[0];
+   }
+
+   bool result =  ossimAnnotationSource::loadState(kwl,
+                                                   prefix);
+   layoutAnnotations();
+
+   return result;
+}
+
+ossimScalarType ossimMapCompositionSource::getOutputScalarType() const
+{
+   return OSSIM_UCHAR;
+}
+
+ossim_uint32 ossimMapCompositionSource::getNumberOfOutputBands() const
+{
+   return 3;
+}
+
+ossimIpt ossimMapCompositionSource::getViewWidthHeight()const
+{
+   return theViewWidthHeight;
+}
+
+void ossimMapCompositionSource::getViewWidthHeight(ossimIpt& widthHeight)const
+{
+   widthHeight = theViewWidthHeight;
+}
+
+void ossimMapCompositionSource::setViewWidthHeight(const ossimIpt& widthHeight)
+{
+   theViewWidthHeight = widthHeight;
+}
+
+ossim_int32 ossimMapCompositionSource::getTopBorderLength()const
+{
+   return theTopBorderLength;
+}
+
+ossim_int32 ossimMapCompositionSource::getBottomBorderLength()const
+{
+   return theBottomBorderLength;
+}
+
+ossim_int32 ossimMapCompositionSource::getLeftBorderLength()const
+{
+   return theLeftBorderLength;
+}
+
+ossim_int32 ossimMapCompositionSource::getRightBorderLength()const
+{
+   return theRightBorderLength;
+}
+
+void ossimMapCompositionSource::setTopBorderLength(ossim_int32 length)
+{
+   theTopBorderLength = length;
+}
+
+void ossimMapCompositionSource::setBottomBorderLength(ossim_int32 length)
+{
+   theBottomBorderLength = length;
+}
+
+void ossimMapCompositionSource::setLeftBorderLength(ossim_int32 length)
+{
+   theLeftBorderLength = length;
+}
+
+void ossimMapCompositionSource::setRightBorderLength(ossim_int32 length)
+{
+   theRightBorderLength = length;
+}
+
+void ossimMapCompositionSource::setGeographicSpacingLat(double value)
+{
+   theGeographicSpacing.lat = value;
+}
+
+void ossimMapCompositionSource::setGeographicSpacingLon(double value)
+{
+   theGeographicSpacing.lon = value;
+}
+
+void ossimMapCompositionSource::setMeterSpacingX(double value)
+{
+   theMeterSpacing.x = value;
+}
+
+void ossimMapCompositionSource::setMeterSpacingY(double value)
+{
+   theMeterSpacing.y = value;
+}
+
+void ossimMapCompositionSource::setMeterSpacing(double x, double y)
+{
+   theMeterSpacing.x = x;
+   theMeterSpacing.y = y;
+}
+
+void ossimMapCompositionSource::setGeographicSpacing(double lat, double lon)
+{
+   theGeographicSpacing.lat = lat;
+   theGeographicSpacing.lon = lon;
+}
+
+ossimDpt ossimMapCompositionSource::getGeographicSpacing()const
+{
+   return theGeographicSpacing;
+}
+
+ossimDpt ossimMapCompositionSource::getMeterSpacing()const
+{
+   return theMeterSpacing;
+}
+
+ossimString ossimMapCompositionSource::getTopGeographicLabelFormat()const
+{
+   return theTopGeographicFormat;
+}
+
+ossimString ossimMapCompositionSource::getBottomGeographicLabelFormat()const
+{
+   return theBottomGeographicFormat;
+}
+
+ossimString ossimMapCompositionSource::getLeftGeographicLabelFormat()const
+{
+   return theLeftGeographicFormat;
+}
+
+ossimString ossimMapCompositionSource::getRightGeographicLabelFormat()const
+{
+   return theRightGeographicFormat;
+}
+
+ossimString ossimMapCompositionSource::getTitle()const
+{
+   return theTitleString;
+}
+
+ossimRgbVector ossimMapCompositionSource::getTitleColor()const
+{
+   return theTitleColor;
+}
+
+void ossimMapCompositionSource::setTitleColor(const ossimRgbVector& color)
+{
+   if(theTitleColor != color)
+   {
+      theTitleColor = color;
+   }
+}
+
+void ossimMapCompositionSource::setTitle(const ossimString& s)
+{
+   if(theTitleString != s)
+   {
+      theTitleString = s;
+   }
+         
+}
+
+ossimFontInformation ossimMapCompositionSource::getTitleFont()const
+{
+   return theTitleFontInfo;
+}
+
+ossimFontInformation ossimMapCompositionSource::getGeographicTopLabelFontInfo()const
+{
+   return theGeographicTopLabelFontInfo;
+}
+
+ossimFontInformation ossimMapCompositionSource::getGeographicBottomLabelFontInfo()const
+{
+   return theGeographicBottomLabelFontInfo;
+}
+
+ossimFontInformation ossimMapCompositionSource::getGeographicLeftLabelFontInfo()const
+{
+   return theGeographicLeftLabelFontInfo;
+}
+
+ossimFontInformation ossimMapCompositionSource::getGeographicRightLabelFontInfo()const
+{
+   return theGeographicRightLabelFontInfo;
+}
+
+ossimFontInformation ossimMapCompositionSource::getMeterTopLabelFontInfo()const
+{
+   return theMeterTopLabelFontInfo;
+}
+
+ossimFontInformation ossimMapCompositionSource::getMeterBottomLabelFontInfo()const
+{
+   return theMeterBottomLabelFontInfo;
+}
+
+ossimFontInformation ossimMapCompositionSource::getMeterLeftLabelFontInfo()const
+{
+   return theMeterLeftLabelFontInfo;
+}
+
+ossimFontInformation ossimMapCompositionSource::getMeterRightLabelFontInfo()const
+{
+   return theMeterRightLabelFontInfo;
+}
+   
+ossimRgbVector ossimMapCompositionSource::getBorderColor()const
+{
+   return theBorderColor;
+}
+
+void ossimMapCompositionSource::setBorderColor(const ossimRgbVector& color)
+{
+   theBorderColor=color;
+}
+
+ossimRgbVector ossimMapCompositionSource::getGeographicGridColor()const
+{
+   return theGeographicGridColor;
+}
+
+ossimRgbVector ossimMapCompositionSource::getMeterGridColor()const
+{
+   return theMeterGridColor;
+}
+
+ossimRgbVector ossimMapCompositionSource::getTopGeographicLabelColor()const
+{
+   return theTopGeographicLabelColor;
+}
+
+ossimRgbVector ossimMapCompositionSource::getBottomGeographicLabelColor()const
+{
+   return theBottomGeographicLabelColor;
+}
+
+ossimRgbVector ossimMapCompositionSource::getLeftGeographicLabelColor()const
+{
+   return theLeftGeographicLabelColor;
+}
+
+ossimRgbVector ossimMapCompositionSource::getRightGeographicLabelColor()const
+{
+   return theRightGeographicLabelColor;
+}
+
+void ossimMapCompositionSource::setGeographicGridColor(const ossimRgbVector& color)
+{
+   theGeographicGridColor = color;
+}
+
+void ossimMapCompositionSource::setTopGeographicLabelColor(const ossimRgbVector& color)
+{
+   theTopGeographicLabelColor = color;
+}
+
+void ossimMapCompositionSource::setBottomGeographicLabelColor(const ossimRgbVector& color)
+{
+   theBottomGeographicLabelColor = color;
+}
+
+void ossimMapCompositionSource::setLeftGeographicLabelColor(const ossimRgbVector& color)
+{
+   theLeftGeographicLabelColor = color;
+}
+
+void ossimMapCompositionSource::setRightGeographicLabelColor(const ossimRgbVector& color)
+{
+   theRightGeographicLabelColor = color;
+}
+
+void ossimMapCompositionSource::setGeographicLabelColor(const ossimRgbVector& color)
+{
+   setTopGeographicLabelColor(color);
+   setBottomGeographicLabelColor(color);
+   setLeftGeographicLabelColor(color);
+   setRightGeographicLabelColor(color);
+}
+
+ossimRgbVector ossimMapCompositionSource::getTopMeterLabelColor()const
+{
+   return theTopMeterLabelColor;
+}
+
+ossimRgbVector ossimMapCompositionSource::getBottomMeterLabelColor()const
+{
+   return theBottomMeterLabelColor;
+}
+
+ossimRgbVector ossimMapCompositionSource::getLeftMeterLabelColor()const
+{
+   return theLeftMeterLabelColor;
+}
+
+ossimRgbVector ossimMapCompositionSource::getRightMeterLabelColor()const
+{
+   return theRightMeterLabelColor;
+}
+   
+void ossimMapCompositionSource::setTopMeterLabelColor(const ossimRgbVector& color)
+{
+   theTopMeterLabelColor = color;
+}
+
+void ossimMapCompositionSource::setBottomMeterLabelColor(const ossimRgbVector& color)
+{
+   theBottomMeterLabelColor = color;
+}
+
+void ossimMapCompositionSource::setLeftMeterLabelColor(const ossimRgbVector& color)
+{
+   theLeftMeterLabelColor = color;
+}
+
+void ossimMapCompositionSource::setRightMeterLabelColor(const ossimRgbVector& color)
+{
+   theRightMeterLabelColor = color;
+}
+
+void ossimMapCompositionSource::setMeterLabelColor(const ossimRgbVector& color)
+{
+   setTopMeterLabelColor(color);
+   setBottomMeterLabelColor(color);
+   setLeftMeterLabelColor(color);
+   setRightMeterLabelColor(color);
+}
+   
+void ossimMapCompositionSource::setMeterGridColor(const ossimRgbVector& color)
+{
+   theMeterGridColor = color;
+}
+
+void ossimMapCompositionSource::setMeterGridType(ossimGridLineType gridType)
+{
+   theMeterGridType = gridType;
+}
+
+void ossimMapCompositionSource::setGeographicGridType(ossimGridLineType gridType)
+{
+   theGeographicGridType = gridType;
+}
+
+void ossimMapCompositionSource::setBorderColor(ossimRgbVector& color)
+{
+   theBorderColor = color;
+}
+
+ossimMapCompositionSource::ossimGridLineType ossimMapCompositionSource::getGeographicGridType()const
+{
+   return theGeographicGridType;
+}
+
+ossimMapCompositionSource::ossimGridLineType ossimMapCompositionSource::getMeterGridType()const
+{
+   return theMeterGridType;
+}
+ 
+void ossimMapCompositionSource::setGeographicTickMarkFlag(bool flag)
+{
+   setTopGeographicTickMarkFlag(flag);
+   setBottomGeographicTickMarkFlag(flag);
+   setLeftGeographicTickMarkFlag(flag);
+   setRightGeographicTickMarkFlag(flag);
+}
+
+void ossimMapCompositionSource::setTopGeographicTickMarkFlag(bool flag)
+{
+   theTopGeographicTickFlag = flag;
+}
+
+void ossimMapCompositionSource::setBottomGeographicTickMarkFlag(bool flag)
+{
+   theBottomGeographicTickFlag = flag;
+}
+
+void ossimMapCompositionSource::setLeftGeographicTickMarkFlag(bool flag)
+{
+   theLeftGeographicTickFlag = flag;
+}
+
+void ossimMapCompositionSource::setRightGeographicTickMarkFlag(bool flag)
+{
+   theRightGeographicTickFlag = flag;
+}
+
+void ossimMapCompositionSource::setTopGeographicLabelFlag(bool flag)
+{
+   theTopGeographicLabelFlag = flag;
+}
+
+void ossimMapCompositionSource::setBottomGeographicLabelFlag(bool flag)
+{
+   theBottomGeographicLabelFlag = flag;
+}
+
+void ossimMapCompositionSource::setLeftGeographicLabelFlag(bool flag)
+{
+   theLeftGeographicLabelFlag = flag;
+}
+
+void ossimMapCompositionSource::setRightGeographicLabelFlag(bool flag)
+{
+   theRightGeographicLabelFlag = flag;
+}
+
+bool ossimMapCompositionSource::getTopGeographicTickMarkFlag()const
+{
+   return theTopGeographicTickFlag;
+}
+
+bool ossimMapCompositionSource::getBottomGeographicTickMarkFlag()const
+{
+   return theBottomGeographicTickFlag;
+}
+
+bool ossimMapCompositionSource::getLeftGeographicTickMarkFlag()const
+{
+   return theLeftGeographicTickFlag;
+}
+
+bool ossimMapCompositionSource::getRightGeographicTickMarkFlag()const
+{
+   return theRightGeographicTickFlag;
+}
+
+bool ossimMapCompositionSource::getTopGeographicLabelFlag()const
+{
+   return theTopGeographicLabelFlag;
+}
+
+bool ossimMapCompositionSource::getBottomGeographicLabelFlag()const
+{
+   return theBottomGeographicLabelFlag;
+}
+
+bool ossimMapCompositionSource::getLeftGeographicLabelFlag()const
+{
+   return theLeftGeographicLabelFlag;
+}
+
+bool ossimMapCompositionSource::getRightGeographicLabelFlag()const
+{
+   return theRightGeographicLabelFlag;
+}
+
+void ossimMapCompositionSource::setMeterTickMarkFlag(bool flag)
+{
+   setTopMeterTickMarkFlag(flag);
+   setBottomMeterTickMarkFlag(flag);
+   setLeftMeterTickMarkFlag(flag);
+   setRightMeterTickMarkFlag(flag);
+}
+
+void ossimMapCompositionSource::setTopMeterTickMarkFlag(bool flag)
+{
+   theTopMeterTickFlag = flag;
+}
+
+void ossimMapCompositionSource::setBottomMeterTickMarkFlag(bool flag)
+{
+   theBottomMeterTickFlag = flag;
+}
+
+void ossimMapCompositionSource::setLeftMeterTickMarkFlag(bool flag)
+{
+   theLeftMeterTickFlag = flag;
+}
+
+void ossimMapCompositionSource::setRightMeterTickMarkFlag(bool flag)
+{
+   theRightMeterTickFlag = flag;
+}
+
+void ossimMapCompositionSource::setTopMeterLabelFlag(bool flag)
+{
+   theTopMeterLabelFlag = flag;
+}
+
+void ossimMapCompositionSource::setBottomMeterLabelFlag(bool flag)
+{
+   theBottomMeterLabelFlag = flag;
+}
+
+void ossimMapCompositionSource::setLeftMeterLabelFlag(bool flag)
+{
+   theLeftMeterLabelFlag = flag;
+}
+
+void ossimMapCompositionSource::setRightMeterLabelFlag(bool flag)
+{
+   theRightMeterLabelFlag = flag;
+}
+   
+bool ossimMapCompositionSource::getTopMeterTickMarkFlag()const
+{
+   return theTopMeterTickFlag;
+}
+
+bool ossimMapCompositionSource::getBottomMeterTickMarkFlag()const
+{
+   return theBottomMeterTickFlag;
+}
+
+bool ossimMapCompositionSource::getLeftMeterTickMarkFlag()const
+{
+   return theLeftMeterTickFlag;
+}
+
+bool ossimMapCompositionSource::getRightMeterTickMarkFlag()const
+{
+   return theRightMeterTickFlag;
+}
+
+bool ossimMapCompositionSource::getTopMeterLabelFlag()const
+{
+   return theTopMeterLabelFlag;
+}
+
+bool ossimMapCompositionSource::getBottomMeterLabelFlag()const
+{
+   return theBottomMeterLabelFlag;
+}
+
+bool ossimMapCompositionSource::getLeftMeterLabelFlag()const
+{
+   return theLeftMeterLabelFlag;
+}
+
+bool ossimMapCompositionSource::getRightMeterLabelFlag()const
+{
+   return theRightMeterLabelFlag;
+}
+
+void ossimMapCompositionSource::addFixedAnnotation(ossimAnnotationObject* obj)
+{
+   if(obj)
+   {
+      theFixedAnnotationList.push_back(obj);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/annotation/ossimMapCompositionSource.h b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimMapCompositionSource.h
new file mode 100644
index 0000000000..9d4bf456f2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/annotation/ossimMapCompositionSource.h
@@ -0,0 +1,339 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimMapCompositionSource.h,v 1.27 2005/05/23 15:40:28 gpotts Exp $
+#ifndef ossimMapCompositionSource_HEADER
+#define ossimMapCompositionSource_HEADER
+#include <imaging/annotation/ossimAnnotationSource.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+#include <base/data_types/ossimPolyArea2d.h>
+#include <fonts/ossimFont.h>
+#include <base/common/ossimFontInformation.h>
+
+class ossimFont;
+class ossimMapProjection;
+class ossimU8ImageData;
+
+class ossimMapCompositionSource : public ossimAnnotationSource
+{
+public:
+   enum ossimGridLineType
+   {
+      OSSIM_GRID_NONE    = 0,
+      OSSIM_GRID_LINE    = 1,
+      OSSIM_GRID_RESEAUX = 2
+   };
+
+   ossimMapCompositionSource();
+   virtual ~ossimMapCompositionSource();
+   
+   virtual ossimScalarType getOutputScalarType() const;
+   virtual ossim_uint32    getNumberOfOutputBands() const;
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+
+   ossimIpt getViewWidthHeight()const;
+
+   void getViewWidthHeight(ossimIpt& widthHeight)const;
+   
+   void setViewWidthHeight(const ossimIpt& widthHeight);
+   
+   // all borders here
+   virtual ossim_int32 getTopBorderLength()const;
+   virtual ossim_int32 getBottomBorderLength()const;
+   virtual ossim_int32 getLeftBorderLength()const;
+   virtual ossim_int32 getRightBorderLength()const;
+
+   virtual void setTopBorderLength(ossim_int32 length);
+   virtual void setBottomBorderLength(ossim_int32 length);
+   virtual void setLeftBorderLength(ossim_int32 length);
+   virtual void setRightBorderLength(ossim_int32 length);
+
+   //all spacing here
+   void setGeographicSpacingLat(double value);
+   void setGeographicSpacingLon(double value);
+   void setMeterSpacingX(double value);
+   void setMeterSpacingY(double value);
+   void setMeterSpacing(double x, double y);
+   void setGeographicSpacing(double lat, double lon);
+
+   ossimDpt getGeographicSpacing()const;
+   ossimDpt getMeterSpacing()const;
+   
+   // All geographic formatting here
+   virtual ossimString getTopGeographicLabelFormat()const;
+   virtual ossimString getBottomGeographicLabelFormat()const;
+   virtual ossimString getLeftGeographicLabelFormat()const;
+   virtual ossimString getRightGeographicLabelFormat()const;
+
+   virtual void setGeographicLabelFormat(const ossimString format);
+   virtual void setTopGeographicLabelFormat(const ossimString& format);
+   virtual void setBottomGeographicLabelFormat(const ossimString& format);
+   virtual void setLeftGeographicLabelFormat(const ossimString& format);
+   virtual void setRightGeographicLabelFormat(const ossimString& format);
+   
+   // All font funtions here.
+   virtual ossimString    getTitle()const;
+   virtual ossimRgbVector getTitleColor()const;
+
+   virtual void setTitleFont(const ossimFontInformation& fontInfo);
+   virtual void setTitleColor(const ossimRgbVector& color);
+   virtual void setTitle(const ossimString& s);
+   virtual void setGeographicTopLabelFont(const ossimFontInformation& fontInfo);
+   virtual void setGeographicBottomLabelFont(const ossimFontInformation& fontInfo);
+   virtual void setGeographicLeftLabelFont(const ossimFontInformation& fontInfo);
+   virtual void setGeographicRightLabelFont(const ossimFontInformation& fontInfo);
+
+   virtual void setMeterTopLabelFont(const ossimFontInformation& fontInfo);
+   virtual void setMeterBottomLabelFont(const ossimFontInformation& fontInfo);
+   virtual void setMeterLeftLabelFont(const ossimFontInformation& fontInfo);
+   virtual void setMeterRightLabelFont(const ossimFontInformation& fontInfo);
+
+   virtual ossimFontInformation getTitleFont()const;
+   virtual ossimFontInformation getGeographicTopLabelFontInfo()const;
+   virtual ossimFontInformation getGeographicBottomLabelFontInfo()const;
+   virtual ossimFontInformation getGeographicLeftLabelFontInfo()const;
+   virtual ossimFontInformation getGeographicRightLabelFontInfo()const;
+   virtual ossimFontInformation getMeterTopLabelFontInfo()const;
+   virtual ossimFontInformation getMeterBottomLabelFontInfo()const;
+   virtual ossimFontInformation getMeterLeftLabelFontInfo()const;
+   virtual ossimFontInformation getMeterRightLabelFontInfo()const;
+
+   // All color funtions here
+   virtual ossimRgbVector getBorderColor()const;
+   virtual void setBorderColor(const ossimRgbVector& color);
+
+   virtual ossimRgbVector getGeographicGridColor()const;
+   virtual ossimRgbVector getMeterGridColor()const;
+   virtual ossimRgbVector getTopGeographicLabelColor()const;
+   virtual ossimRgbVector getBottomGeographicLabelColor()const;
+   virtual ossimRgbVector getLeftGeographicLabelColor()const;
+   virtual ossimRgbVector getRightGeographicLabelColor()const;
+
+   virtual void setGeographicGridColor(const ossimRgbVector& color);
+   virtual void setTopGeographicLabelColor(const ossimRgbVector& color);
+   virtual void setBottomGeographicLabelColor(const ossimRgbVector& color);
+   virtual void setLeftGeographicLabelColor(const ossimRgbVector& color);
+   virtual void setRightGeographicLabelColor(const ossimRgbVector& color);
+   virtual void setGeographicLabelColor(const ossimRgbVector& color);
+
+   virtual ossimRgbVector getTopMeterLabelColor()const;
+   virtual ossimRgbVector getBottomMeterLabelColor()const;
+   virtual ossimRgbVector getLeftMeterLabelColor()const;
+   virtual ossimRgbVector getRightMeterLabelColor()const;
+   
+   virtual void setTopMeterLabelColor(const ossimRgbVector& color);
+   virtual void setBottomMeterLabelColor(const ossimRgbVector& color);
+   virtual void setLeftMeterLabelColor(const ossimRgbVector& color);
+   virtual void setRightMeterLabelColor(const ossimRgbVector& color);
+   virtual void setMeterLabelColor(const ossimRgbVector& color);
+   virtual void setMeterGridColor(const ossimRgbVector& color);
+
+   // All grid types here
+   virtual void setMeterGridType(ossimGridLineType gridType);
+   virtual void setGeographicGridType(ossimGridLineType gridType);
+   virtual void setBorderColor(ossimRgbVector& color);
+
+   virtual ossimGridLineType getGeographicGridType()const;
+   virtual ossimGridLineType getMeterGridType()const;
+   
+   // all grid flags here
+   void setGeographicTickMarkFlag(bool flag);
+   void setTopGeographicTickMarkFlag(bool flag);
+   void setBottomGeographicTickMarkFlag(bool flag);
+   void setLeftGeographicTickMarkFlag(bool flag);
+   void setRightGeographicTickMarkFlag(bool flag);
+   void setTopGeographicLabelFlag(bool flag);
+   void setBottomGeographicLabelFlag(bool flag);
+   void setLeftGeographicLabelFlag(bool flag);
+   void setRightGeographicLabelFlag(bool flag);
+
+   virtual bool getTopGeographicTickMarkFlag()const;
+   virtual bool getBottomGeographicTickMarkFlag()const;
+   virtual bool getLeftGeographicTickMarkFlag()const;
+   virtual bool getRightGeographicTickMarkFlag()const;
+   virtual bool getTopGeographicLabelFlag()const;
+   virtual bool getBottomGeographicLabelFlag()const;
+   virtual bool getLeftGeographicLabelFlag()const;
+   virtual bool getRightGeographicLabelFlag()const;
+
+   void setMeterTickMarkFlag(bool flag);
+   virtual void setTopMeterTickMarkFlag(bool flag);
+   virtual void setBottomMeterTickMarkFlag(bool flag);
+   virtual void setLeftMeterTickMarkFlag(bool flag);
+   virtual void setRightMeterTickMarkFlag(bool flag);
+   virtual void setTopMeterLabelFlag(bool flag);
+   virtual void setBottomMeterLabelFlag(bool flag);
+   virtual void setLeftMeterLabelFlag(bool flag);
+   virtual void setRightMeterLabelFlag(bool flag);
+   
+   virtual bool getTopMeterTickMarkFlag()const;
+   virtual bool getBottomMeterTickMarkFlag()const;
+   virtual bool getLeftMeterTickMarkFlag()const;
+   virtual bool getRightMeterTickMarkFlag()const;
+   virtual bool getTopMeterLabelFlag()const;
+   virtual bool getBottomMeterLabelFlag()const;
+   virtual bool getLeftMeterLabelFlag()const;
+   virtual bool getRightMeterLabelFlag()const;
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+
+   virtual void initialize();
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+
+
+protected:
+   ossimIpt            theViewWidthHeight;
+   ossimGridLineType   theMeterGridType;
+   ossimGridLineType   theGeographicGridType;
+   
+   ossim_uint32        theTopBorderLength;
+   ossim_uint32        theBottomBorderLength;
+   ossim_uint32        theLeftBorderLength;
+   ossim_uint32        theRightBorderLength;
+   
+   ossimRgbVector      theBorderColor;
+
+   ossimRgbVector      theGeographicGridColor;
+   ossimRgbVector      theMeterGridColor;
+
+   // title info
+   //
+   ossimString          theTitleString;
+   ossimFont*           theTitleFont;
+   ossimFontInformation theTitleFontInfo;
+   ossimRgbVector       theTitleColor;
+   
+   // grid label colors
+   //
+   ossimRgbVector      theTopGeographicLabelColor;
+   ossimRgbVector      theBottomGeographicLabelColor;
+   ossimRgbVector      theLeftGeographicLabelColor;
+   ossimRgbVector      theRightGeographicLabelColor;
+   ossimRgbVector      theTopMeterLabelColor;
+   ossimRgbVector      theBottomMeterLabelColor;
+   ossimRgbVector      theLeftMeterLabelColor;
+   ossimRgbVector      theRightMeterLabelColor;
+
+   // grid label font
+   //
+   ossimFontInformation theGeographicTopLabelFontInfo;
+   ossimFont*           theGeographicTopLabelFont;
+   ossimFontInformation theGeographicBottomLabelFontInfo;
+   ossimFont*           theGeographicBottomLabelFont;
+   ossimFontInformation theGeographicLeftLabelFontInfo;
+   ossimFont*           theGeographicLeftLabelFont;
+   ossimFontInformation theGeographicRightLabelFontInfo;
+   ossimFont*           theGeographicRightLabelFont;
+
+   ossimFontInformation theMeterTopLabelFontInfo;
+   ossimFont*           theMeterTopLabelFont;
+   ossimFontInformation theMeterBottomLabelFontInfo;
+   ossimFont*           theMeterBottomLabelFont;
+   ossimFontInformation theMeterLeftLabelFontInfo;
+   ossimFont*           theMeterLeftLabelFont;
+   ossimFontInformation theMeterRightLabelFontInfo;
+   ossimFont*           theMeterRightLabelFont;
+   
+   // grid label dms format strings
+   //
+   ossimString         theTopGeographicFormat;
+   ossimString         theBottomGeographicFormat;
+   ossimString         theLeftGeographicFormat;
+   ossimString         theRightGeographicFormat;
+
+   // grid label flag
+   //
+   bool                theTopGeographicLabelFlag;
+   bool                theBottomGeographicLabelFlag;
+   bool                theLeftGeographicLabelFlag;
+   bool                theRightGeographicLabelFlag;
+
+   bool                theTopGeographicTickFlag;
+   bool                theBottomGeographicTickFlag;
+   bool                theLeftGeographicTickFlag;
+   bool                theRightGeographicTickFlag;
+
+   bool                theTopMeterLabelFlag;
+   bool                theBottomMeterLabelFlag;
+   bool                theLeftMeterLabelFlag;
+   bool                theRightMeterLabelFlag;
+
+   bool                theTopMeterTickFlag;
+   bool                theBottomMeterTickFlag;
+   bool                theLeftMeterTickFlag;
+   bool                theRightMeterTickFlag;
+   
+   
+   ossimIrect          theTopBorder;
+   ossimIrect          theBottomBorder;
+   ossimIrect          theLeftBorder;
+   ossimIrect          theRightBorder;
+
+   // geo-tick spacing in lat lon
+   ossimDpt            theGeographicSpacing;
+
+   //  tick spacing in meter units
+   ossimDpt            theMeterSpacing;
+   
+   ossimMapProjection* theInputProjection;
+
+   vector<ossimAnnotationObject*> theFixedAnnotationList;
+
+   /*!
+    * Override base classes drawAnnotations so we can layout
+    * any fixed annotations first.
+    */
+   virtual void drawAnnotations(ossimRefPtr<ossimImageData> tile);
+   
+   virtual void computeBorderRects();
+   virtual void drawBorders();
+   virtual void addGridLabels();
+   
+   virtual void addGeographicTopGridLabels();
+   virtual void addGeographicBottomGridLabels();
+   virtual void addGeographicLeftGridLabels();
+   virtual void addGeographicRightGridLabels();
+
+   virtual void addGeographicGridLines();
+   virtual void addGeographicGridReseaux();
+   
+   virtual void addMeterGridLabels();
+   
+   virtual void addMeterGridLines();
+   virtual void addMeterGridReseaux();
+
+   
+   virtual void addTitle();
+   
+   virtual void layoutAnnotations();
+
+   virtual void addFixedAnnotation(ossimAnnotationObject* obj);
+      
+   virtual void deleteFixedAnnotations();
+   
+   ossimIrect getViewingRect()const;
+   
+// For RTTI
+TYPE_DATA
+};
+#endif /* #ifndef ossimMapCompositionSource_HEADER */
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/.cvsignore
new file mode 100644
index 0000000000..93652de916
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+ossimAOD.d
+ossimAtCorrGridRemapper.d
+ossimAtCorrRemapper.d
+ossimGammaRemapper.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAOD.cpp b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAOD.cpp
new file mode 100644
index 0000000000..ff32461359
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAOD.cpp
@@ -0,0 +1,238 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kathy Minear
+//
+// Description:
+// 
+// Class to compute Aerosol Optical Depth (AOD) for with atmospheric
+// correction.
+// 
+//
+//*************************************************************************
+// $Id: ossimAOD.cpp,v 1.5 2005/02/11 15:07:30 dburken Exp $
+
+#include <math.h>
+#include <imaging/atmospheric_correction/ossimAOD.h>
+#include <base/common/ossimTrace.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/ossimU8ImageData.h>
+
+
+RTTI_DEF1(ossimAOD, "ossimAOD", ossimImageSourceFilter)
+
+static ossimTrace traceDebug("ossimAOD:debug");
+
+ossimAOD::ossimAOD(ossimObject* owner)
+   :
+      ossimImageSourceFilter  (owner),  // base class
+      theTile                 (NULL)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+
+   // Construction not complete.
+}
+
+ossimAOD::ossimAOD(ossimImageSource* inputSource)
+   :
+      ossimImageSourceFilter  (NULL, inputSource),  // base class
+      theTile                 (NULL)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+
+   if (inputSource == NULL)
+   {
+      setErrorStatus();
+      cerr << "ossimAOD::ossimAOD ERROR:"
+           << "\nNull input source passed to constructor!" << endl;
+      return;
+   }
+
+   initialize();
+}
+
+
+ossimAOD::ossimAOD(ossimObject* owner,
+                                         ossimImageSource* inputSource)
+   :
+      ossimImageSourceFilter  (owner, inputSource),  // base class     
+      theTile                 (NULL)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+
+   if (inputSource == NULL)
+   {
+      setErrorStatus();
+      cerr << "ossimAOD::ossimAOD ERROR:"
+           << "\nNull input source passed to constructor!" << endl;
+      return;
+   }
+
+   initialize();
+}
+
+ossimAOD::~ossimAOD()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimAOD::getTile(const ossimIrect& tile_rect,
+                                              ossim_uint32 resLevel)
+{
+   if (!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+      
+   // Fetch tile from pointer from the input source.
+   ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(tile_rect,
+                                                                       resLevel);
+
+
+   if (!inputTile.valid())  // Just in case...
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimAOD::getTile ERROR:"
+         << "\nReceived null pointer to tile from input source!"
+         << "\nReturning blank tile."
+         << endl;
+      return inputTile;
+   }
+
+   ossimDataObjectStatus tile_status = inputTile->getDataObjectStatus();
+
+   if ( !theEnableFlag ||
+        (tile_status == OSSIM_NULL) ||
+        (tile_status == OSSIM_EMPTY) )
+   {
+      return inputTile;
+   }
+   
+   if (!theTile.valid())
+   {
+      allocate();
+      if (!theTile.valid())
+      {
+         return inputTile;
+      }
+   }
+
+   ossim_uint32 w     = tile_rect.width();
+   ossim_uint32 h     = tile_rect.height();
+   ossim_uint32 tw    = theTile->getWidth();
+   ossim_uint32 th    = theTile->getHeight();
+   // ossim_uint32 bands = theTile->getNumberOfBands();
+
+   // Set the origin of the output tile.
+   theTile->setOrigin(tile_rect.ul());
+
+   if(w*h != tw*th)
+   {
+      theTile->setWidthHeight(w, h);
+      theTile->initialize();
+   }
+   return theTile;
+}
+
+void ossimAOD::initialize()
+{
+   ossimImageSourceFilter::initialize();
+}
+
+void ossimAOD::allocate()
+{
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,
+                                                          theInputConnection);
+      theTile->initialize();
+      setInitializedFlag(true);
+      clearErrorStatus();
+   }
+   else
+   {
+      setInitializedFlag(false);
+      setErrorStatus();
+      cerr << "ossimAOD::initialize ERROR:"
+           << "\nCannot call method when input connection is NULL!"
+           << endl;
+   };
+
+   verifyEnabled();
+}
+
+bool ossimAOD::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   static const char MODULE[] = "ossimAOD::loadState()";
+
+   if (traceDebug())  CLOG << "entering..." << endl;
+
+   if (!theTile)
+   {
+      cerr << MODULE << " ERROR:"
+           << "Not initialized..." << endl;
+      return false;
+   }
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << *this
+           << "\nreturning..."
+           << endl;
+   }
+   
+   return true;
+}
+
+
+void ossimAOD::verifyEnabled()
+{
+   // Check all the pointers...
+   if ( !theInputConnection    || !theTile )
+   {
+      disableSource();
+      return;
+   }
+
+   enableSource();
+}
+
+ostream& ossimAOD::print(ostream& os) const
+{
+   os << "ossimAOD:"
+      << "\ntheEnableFlag:  " << (theEnableFlag?"enabled":"disabled")
+      << endl;
+
+   return os;
+}
+
+ostream& operator<<(ostream& os, const ossimAOD& hr)
+{
+   return hr.print(os);
+}
+
+void ossimAOD::writeTemplate(ostream& os)
+{
+}
+
+ossimString ossimAOD::getShortName() const
+{
+   return ossimString("Aerosol Optical Depth");
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAOD.h b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAOD.h
new file mode 100644
index 0000000000..496ca17220
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAOD.h
@@ -0,0 +1,66 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kathy Minear
+//
+// Description:
+// 
+// Class to compute Aerosol Optical Depth (AOD) for with atmospheric
+// correction.
+//
+//*************************************************************************
+// $Id: ossimAOD.h,v 1.4 2005/02/11 15:07:30 dburken Exp $
+#ifndef ossimAOD_HEADER
+#define ossimAOD_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimAOD : public ossimImageSourceFilter
+{
+public:
+
+   ossimAOD(ossimObject* owner=NULL);
+   ossimAOD(ossimImageSource* inputSource);
+   ossimAOD(ossimObject* owner, ossimImageSource* inputSource);
+
+   virtual ~ossimAOD();
+
+   virtual ossimString getShortName() const;
+
+   virtual void initialize();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual ostream& print(ostream& os) const;
+   friend ostream& operator << (ostream& os,  const ossimAOD& hr);
+
+   static void writeTemplate(ostream& os);
+
+protected:
+
+   void allocate();
+   
+   /*!
+    * Method to set unset the enable flag.
+    */
+   void verifyEnabled();
+
+   ossimRefPtr<ossimImageData> theTile;
+
+   TYPE_DATA
+};
+
+#endif /* #ifndef ossimAOD_HEADER */
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrGridRemapper.cpp b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrGridRemapper.cpp
new file mode 100644
index 0000000000..f137505e37
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrGridRemapper.cpp
@@ -0,0 +1,351 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts <gpotts@imagelinks.com>
+//
+// Description:
+//*******************************************************************
+//  $Id: ossimAtCorrGridRemapper.cpp,v 1.5 2003/10/07 17:09:55 gpotts Exp $
+#include "ossimAtCorrGridRemapper.h"
+
+RTTI_DEF1(ossimAtCorrGridRemapper, "ossimAtCorrGridRemapper", ossimAtCorrRemapper);
+
+ossimAtCorrGridRemapper::ossimAtCorrGridRemapper(ossimObject* owner,
+                                                 ossimImageSource* inputSource,
+                                                 const ossimString& sensorType)
+   :ossimAtCorrRemapper(owner, inputSource, sensorType)
+{
+   theUseInterpolationFlag = true;
+}
+
+ossimAtCorrGridRemapper::~ossimAtCorrGridRemapper()
+{
+}
+
+void ossimAtCorrGridRemapper::interpolate(const ossimDpt& pt,
+                                          int band,
+                                          double& a,
+                                          double& b,
+                                          double& c)const
+{
+   if(theGridBounds.pointWithin(pt))
+   {
+      double x = (((double)(pt.x - theUlGridBound.x))/theGridBounds.width())*(theGridSize.x-1);
+      double y = (((double)(pt.y - theUlGridBound.y))/theGridBounds.height())*(theGridSize.y-1);
+
+      int xidx = (int)x;
+      int yidx = (int)y;
+      
+      double xt = x - xidx;
+      double yt = y - yidx;
+
+      double va00 = theAGrid[band][yidx][xidx];
+      double va01 = theAGrid[band][yidx][xidx+1];
+      double va11 = theAGrid[band][yidx+1][xidx+1];
+      double va10 = theAGrid[band][yidx+1][xidx];
+      double vb00 = theBGrid[band][yidx][xidx];
+      double vb01 = theBGrid[band][yidx][xidx+1];
+      double vb11 = theBGrid[band][yidx+1][xidx+1];
+      double vb10 = theBGrid[band][yidx+1][xidx];
+      double vc00 = theCGrid[band][yidx][xidx];
+      double vc01 = theCGrid[band][yidx][xidx+1];
+      double vc11 = theCGrid[band][yidx+1][xidx+1];
+      double vc10 = theCGrid[band][yidx+1][xidx];
+
+      double vaInterpH1 = va00 + (va01-va00)*xt;
+      double vaInterpH2 = va10 + (va11-va10)*xt;
+      double vbInterpH1 = vb00 + (vb01-vb00)*xt;
+      double vbInterpH2 = vb10 + (vb11-vb10)*xt;
+      double vcInterpH1 = vc00 + (vc01-vc00)*xt;
+      double vcInterpH2 = vc10 + (vc11-vc10)*xt;
+      
+      a = vaInterpH1 + (vaInterpH2-vaInterpH1)*yt;
+      b = vbInterpH1 + (vbInterpH2-vbInterpH1)*yt;
+      c = vcInterpH1 + (vcInterpH2-vcInterpH1)*yt;
+   }
+   else
+   {
+      ossimAtCorrRemapper::interpolate(pt,
+                                       band,
+                                       a,
+                                       b,
+                                       c);
+   }
+}
+
+void ossimAtCorrGridRemapper::initialize()
+{
+   ossimAtCorrRemapper::initialize();
+   
+   if(theInputConnection)
+   {
+      theGridBounds = theInputConnection->getBoundingRect();
+      theUlGridBound = theGridBounds.ul();
+   }
+   else
+   {
+      theGridBounds.makeNan();
+   }
+
+   if(!theAGrid.size()||
+      !theBGrid.size()||
+      !theCGrid.size())
+   {
+      theUseInterpolationFlag=false;
+   }
+   setBaseToAverage();
+}
+
+void ossimAtCorrGridRemapper::setGridSize(ossim_uint32 numberOfBands, const ossimIpt& gridSize)
+{
+   
+   if((theGridSize!=gridSize)||(numberOfBands != theAGrid.size()))
+   {
+      theAGrid.resize(numberOfBands);
+      theBGrid.resize(numberOfBands);
+      theCGrid.resize(numberOfBands);
+
+      for(ossim_uint32 b = 0; b < numberOfBands;++b)
+      {
+         theAGrid[b].resize(gridSize.y);
+         theBGrid[b].resize(gridSize.y);
+         theCGrid[b].resize(gridSize.y);
+         for(int r = 0; r < gridSize.y; ++r)
+         {
+            theAGrid[b][r].resize(gridSize.x);
+            theBGrid[b][r].resize(gridSize.x);
+            theCGrid[b][r].resize(gridSize.x);
+         }
+         
+      }
+      theGridSize = gridSize;
+   }
+   
+}
+
+
+void ossimAtCorrGridRemapper::setBaseToAverage()
+{
+   ossim_uint32 idxBand;
+   vector<double> xaAverage(theAGrid.size());
+   vector<double> xcAverage(theBGrid.size());
+   vector<double> xbAverage(theCGrid.size());
+   // double aAverage=0.0, bAverage=0.0, cAverag=0.0;
+
+
+   if((theAGrid.size() != theBGrid.size())||
+      (theAGrid.size() != theCGrid.size())||
+      (theAGrid.size() == 0))
+   {
+      return;
+   }
+   
+   for(idxBand = 0; idxBand < theAGrid.size(); ++idxBand)
+   {
+      ossim_uint32 idxRow = 0;
+      xaAverage[idxBand] = 0.0;
+      xbAverage[idxBand] = 0.0;
+      xcAverage[idxBand] = 0.0;
+      for(idxRow = 0; idxRow < theAGrid[idxBand].size();++idxRow)
+      {
+         ossim_uint32 idxCol = 0;
+         for(idxCol = 0; idxCol < theAGrid[idxBand][idxRow].size();++idxCol)
+         {
+            xaAverage[idxBand] += theAGrid[idxBand][idxRow][idxCol];
+            
+         }
+      }
+      for(idxRow = 0; idxRow < theBGrid[idxBand].size();++idxRow)
+      {
+         ossim_uint32 idxCol = 0;
+         for(idxCol = 0; idxCol < theBGrid[idxBand][idxRow].size();++idxCol)
+         {
+            xbAverage[idxBand] += theBGrid[idxBand][idxRow][idxCol];
+         }
+      }
+      for(idxRow = 0; idxRow < theCGrid[idxBand].size();++idxRow)
+      {
+         ossim_uint32 idxCol = 0;
+         for(idxCol = 0; idxCol < theCGrid[idxBand][idxRow].size();++idxCol)
+         {
+            xaAverage[idxBand] += theCGrid[idxBand][idxRow][idxCol];
+            xbAverage[idxBand] += theCGrid[idxBand][idxRow][idxCol];
+            xcAverage[idxBand] += theCGrid[idxBand][idxRow][idxCol];
+            
+         }
+      }
+   }
+
+   for(idxBand = 0; idxBand < theAGrid.size(); ++idxBand)
+   {
+      xaAverage[idxBand] /=(double)(theGridSize.x*theGridSize.y);
+      xbAverage[idxBand] /=(double)(theGridSize.x*theGridSize.y);
+      xcAverage[idxBand] /=(double)(theGridSize.x*theGridSize.y);
+   }
+
+   theXaArray = xaAverage;
+   theXbArray = xbAverage;
+   theXcArray = xcAverage;
+}
+
+/*!
+ * Method to the load (recreate) the state of an object from a keyword
+ * list.  Return true if ok or false on error.
+ */
+bool ossimAtCorrGridRemapper::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   const char* MODULE = "ossimAtCorrGridRemapper::loadState";
+   theAGrid.clear();
+   theBGrid.clear();
+   theCGrid.clear();
+   
+   if (!theTile || !theSurfaceReflectance)
+   {
+      cerr << MODULE << " ERROR:"
+           << "Not initialized..." << endl;
+      return false;
+   }
+   theUseInterpolationFlag=true;
+   ossim_uint32 bands = theTile->getNumberOfBands();
+
+   theAGrid.resize(bands);
+   theBGrid.resize(bands);
+   theCGrid.resize(bands);
+
+
+   const char* rowsLookup = NULL;
+   const char* colsLookup = NULL;
+   for(ossim_uint32 band = 0; band < bands; ++band)
+   {
+      ossim_uint32 r = 0;
+      ossim_uint32 c = 0;
+      ossimString gridString = "band";
+      gridString += ossimString::toString(band+1);
+      gridString += ".grid";
+      
+      rowsLookup = kwl.find(prefix,
+                            gridString + ".rows");
+      
+      colsLookup = kwl.find(prefix,
+                            gridString + ".cols");
+      if(rowsLookup&&colsLookup)
+      {
+         cout << "both keywords needed: " << (gridString+".rows") << endl
+              << (gridString+".cols") << endl;
+
+         theUseInterpolationFlag=false;
+         return false;
+      }
+      
+      ossim_uint32 rows = ossimString(rowsLookup).toULong();
+      ossim_uint32 cols = ossimString(colsLookup).toULong();
+
+      if(cols&&rows)
+      {
+         cout << "value for cols and rows keyword have 0" << endl;
+         theUseInterpolationFlag=false;
+         return false;
+      }
+
+      theAGrid[band].resize(rows);
+      theBGrid[band].resize(rows);
+      theCGrid[band].resize(rows);
+      for(r = 0; r < rows; ++r)
+      {
+         theAGrid[band][r].resize(cols);
+         theBGrid[band][r].resize(cols);
+         theCGrid[band][r].resize(cols);
+      }
+
+      ossim_uint32 idx = 1;
+      const char* aLookup;
+      const char* bLookup;
+      const char* cLookup;
+      for(r = 0; r < rows; ++r)
+      {
+         for(c = 0; c < cols; ++c)
+         {
+            aLookup = kwl.find(prefix, gridString+".a"+ossimString::toString(idx));
+            bLookup = kwl.find(prefix, gridString+".b"+ossimString::toString(idx));
+            cLookup = kwl.find(prefix, gridString+".c"+ossimString::toString(idx));
+            theAGrid[band][r][c] = ossimString(aLookup).toDouble();
+            theBGrid[band][r][c] = ossimString(bLookup).toDouble();
+            theCGrid[band][r][c] = ossimString(cLookup).toDouble();
+            
+            ++idx;
+         }
+      }
+
+      theGridSize.x = cols;
+      theGridSize.y = rows;
+      setBaseToAverage();
+   }
+
+   return true;
+}
+
+bool ossimAtCorrGridRemapper::saveState(ossimKeywordlist& kwl,
+                                        const char* prefix)const
+{
+
+   ossim_uint32 bands = theAGrid.size();
+   
+   for(ossim_uint32 band = 0; band < bands; ++band)
+   {
+      int idx = 1;
+      int r = 0;
+      int c = 0;
+      ossimString gridString = "band";
+      gridString += ossimString::toString(band+1);
+      gridString += ".grid";
+
+      ossim_uint32 rows = theAGrid[band].size();
+      kwl.add(prefix,
+              gridString+".rows",
+              rows,
+              true);
+      ossim_uint32 cols = theAGrid[band][0].size();
+      kwl.add(prefix,
+              gridString+".cols",
+              cols,
+              true);
+      for(r = 0; r < theGridSize.y; ++r)
+      {
+         for(c = 0; c < theGridSize.x; ++c)
+         {
+            kwl.add(prefix,
+                    gridString+".a"+ossimString::toString(idx),
+                    theAGrid[band][r][c],
+                    true);
+            kwl.add(prefix,
+                    gridString+".b"+ossimString::toString(idx),
+                    theAGrid[band][r][c],
+                    true);
+            kwl.add(prefix,
+                    gridString+".c"+ossimString::toString(idx),
+                    theAGrid[band][r][c],
+                    true);
+            
+            ++idx;
+         }
+      }
+   }
+
+   return ossimAtCorrRemapper::saveState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrGridRemapper.h b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrGridRemapper.h
new file mode 100644
index 0000000000..14414d2a1e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrGridRemapper.h
@@ -0,0 +1,154 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts <gpotts@imagelinks.com>
+//
+//*******************************************************************
+//  $Id: ossimAtCorrGridRemapper.h,v 1.3 2003/10/07 17:10:02 gpotts Exp $
+#ifndef ossimAtCorrGridRemapper_HEADER
+#define ossimAtCorrGridRemapper_HEADER
+#include "ossimAtCorrRemapper.h"
+
+/*!
+ * The grid is encoded into band separate grid and allows bilinear interpolation
+ * of atmospheric correction coefficients.  It uses the implementation found in
+ * ossimAtCorrRemapper.  The base class will call interpolate to calculate the
+ * a, b, c coefficients used.  This class just overrides the base interpolation method. For
+ * gridded remappers
+ *
+ *
+ *
+ * Sample keywordlist includes:
+ *
+ * band1.grid.rows: 4
+ * band1.grid.cols: 4
+ * band1.grid.a1:
+ * band1.grid.b1:
+ * band1.grid.c1:
+ * band1.grid.a2:
+ * band1.grid.b2:
+ * band1.grid.c2:
+ * band1.grid.a3:
+ * band1.grid.b3:
+ * band1.grid.c3:
+ * band1.grid.a4:
+ * band1.grid.b4:
+ * band1.grid.c4:
+ * band2.grid.rows: 4
+ * band2.grid.cols: 4
+ * band2.grid.a1:
+ * band2.grid.b1:
+ * band2.grid.c1:
+ * band2.grid.a2:
+ * band2.grid.b2:
+ * band2.grid.c2:
+ * band2.grid.a3:
+ * band2.grid.b3:
+ * band2.grid.c3:
+ * band2.grid.a4:
+ * band2.grid.b4:
+ * band2.grid.c4:
+ *
+ *  :
+ *  :
+ *  :
+ */
+class ossimAtCorrGridRemapper: public ossimAtCorrRemapper
+{
+public:
+   ossimAtCorrGridRemapper(ossimObject* owner = NULL,
+                           ossimImageSource* inputSource =  NULL,
+                           const ossimString& sensorType = "");
+   
+   virtual ~ossimAtCorrGridRemapper();
+
+
+   void setGridRect(const ossimIrect& rect)
+      {
+         theGridBounds  = rect;
+         theUlGridBound = rect.ul();
+      }
+   void setGridSize(ossim_uint32 numberOfBands, const ossimIpt& gridSize);
+   ossimIpt getGridSize()const
+      {
+         return theGridSize;
+      }
+   
+   void getValues(ossim_uint32 band,
+                  ossim_uint32 row,
+                  ossim_uint32 col,
+                  double& a,
+                  double& b,
+                  double& c)
+      {
+         a = theAGrid[band][row][col];
+         b = theAGrid[band][row][col];
+         c = theAGrid[band][row][col];
+      }
+
+   void getValues(const ossimDpt& pt,
+                  ossim_uint32 band,
+                  double& a,
+                  double& b,
+                  double& c)
+      {
+         interpolate(pt, band, a, b, c);
+      }
+   
+   void setValues(ossim_uint32 band,
+                  ossim_uint32 row,
+                  ossim_uint32 col,
+                  const double& a,
+                  const double& b,
+                  const double& c)
+      {
+         theAGrid[band][row][col] = a;
+         theBGrid[band][row][col] = b;
+         theCGrid[band][row][col] = c;
+      }
+   
+   virtual void initialize();
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+protected:
+   ossimIrect theGridBounds;
+   ossimIpt   theUlGridBound;
+   ossimIpt   theGridSize;
+   std::vector< std::vector< std::vector<double> > >theAGrid;
+   std::vector< std::vector< std::vector<double> > >theBGrid;
+   std::vector< std::vector< std::vector<double> > >theCGrid;
+
+   virtual void interpolate(const ossimDpt& pt,
+                            int band,
+                            double& a,
+                            double& b,
+                            double& c)const;
+   virtual void setBaseToAverage();
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrKeywords.h b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrKeywords.h
new file mode 100644
index 0000000000..9505ce475a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrKeywords.h
@@ -0,0 +1,35 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken <dburken@imagelinks.com>
+//
+// Description:
+// Keywords utilized by atmospheric correction code.
+//
+//*************************************************************************
+// $Id: ossimAtCorrKeywords.h,v 1.3 2003/05/13 18:08:37 kminear Exp $
+
+static const char AT_CORR_XA_KW[]   = "atmospheric_correction.xa";
+static const char AT_CORR_XB_KW[]   = "atmospheric_correction.xb";
+static const char AT_CORR_XC_KW[]   = "atmospheric_correction.xc";
+static const char AT_CORR_BIAS_KW[] = "atmospheric_correction.bias";
+static const char AT_CORR_GAIN_KW[] = "atmospheric_correction.gain";
+static const char AT_CORR_CALCOEF_KW[] = "atmospheric_correction.calcoef";
+static const char AT_CORR_BANDWIDTH_KW[] = "atmospheric_correction.bandwidth";
+
+static const char GAMMA_REMAPPER_GAMMA_KW[] = "gamma_remapper.gamma";
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrRemapper.cpp b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrRemapper.cpp
new file mode 100644
index 0000000000..ea72ba067e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrRemapper.cpp
@@ -0,0 +1,729 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kathy Minear
+//
+// Description:
+// Takes in DNs for any number of bands
+// Converts DNs to Radiance at the satellite values Lsat
+// Converts Lsat to Surface Reflectance values
+//
+//*************************************************************************
+// $Id: ossimAtCorrRemapper.cpp,v 1.21 2005/02/11 15:07:30 dburken Exp $
+
+#include <math.h>
+
+#include <imaging/atmospheric_correction/ossimAtCorrRemapper.h>
+#include <imaging/atmospheric_correction/ossimAtCorrKeywords.h>
+#include <base/common/ossimTrace.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+
+RTTI_DEF1(ossimAtCorrRemapper, "ossimAtCorrRemapper", ossimImageSourceFilter);
+
+static ossimTrace traceDebug("ossimAtCorrRemapper:debug");
+
+ossimAtCorrRemapper::ossimAtCorrRemapper(ossimObject* owner,
+                                         ossimImageSource* inputSource,
+                                         const ossimString& sensorType)
+      :
+      ossimImageSourceFilter  (owner, inputSource),  // base class     
+      theTile                 (NULL),
+      theSurfaceReflectance   (NULL),
+      theUseInterpolationFlag(false),
+      theMinPixelValue        (0),  
+      theMaxPixelValue        (0),
+      theXaArray              (0),
+      theXbArray              (0),
+      theXcArray              (0),
+      theBiasArray            (0),
+      theGainArray            (0),
+      theCalCoefArray         (0),
+      theBandWidthArray       (0),
+      theSensorType(sensorType)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+
+   initialize();
+}
+
+ossimAtCorrRemapper::~ossimAtCorrRemapper()
+{
+   if (theSurfaceReflectance)
+   {
+      delete [] theSurfaceReflectance;
+      theSurfaceReflectance = NULL;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimAtCorrRemapper::getTile(
+   const ossimIrect& tile_rect,
+   ossim_uint32 resLevel)
+{
+#if 0
+   if (traceDebug())
+   {
+      cout << "ossimAtCorrRemapper::getTile DEBUG:"
+           << "\ntile_rect:  " << tile_rect << endl;
+   }
+#endif
+   
+   if (!isInitialized()||!theInputConnection)
+   {
+       cerr << "ossimAtCorrRemapper::getTile ERROR:"
+            << "\nNot initialized!"
+            << endl;
+       return ossimRefPtr<ossimImageData>();
+   }
+
+   if(!theTile.valid())
+   {
+      initialize();
+      if(!theTile)
+      {
+         return ossimRefPtr<ossimImageData>();
+      }
+   }
+   
+   // Fetch tile from pointer from the input source.
+   ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(tile_rect,
+                                                                       resLevel);
+
+   if (!inputTile.valid())  // Just in case...
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   // Check for remap bypass or empty / null input tile.
+   ossimDataObjectStatus tile_status = inputTile->getDataObjectStatus();
+   if (!theEnableFlag || tile_status == OSSIM_NULL ||
+       tile_status == OSSIM_EMPTY)
+   {
+      return inputTile;
+   }
+
+   ossim_uint32 w     = tile_rect.width();
+   ossim_uint32 h     = tile_rect.height();
+   ossim_uint32 tw    = theTile->getWidth();
+   ossim_uint32 th    = theTile->getHeight();
+   ossim_uint32 bands = theTile->getNumberOfBands();
+
+   // Set the origin of the output tile.
+   theTile->setOrigin(tile_rect.ul());
+
+   if(w*h != tw*th)
+   {
+      theTile->setWidthHeight(w, h);
+      theTile->initialize();
+      if(theSurfaceReflectance)
+      {
+         delete [] theSurfaceReflectance;
+         theSurfaceReflectance = NULL;
+      }
+   }
+   
+   if(!theSurfaceReflectance)
+   {
+      ossim_uint32 size  = tw*th*bands;
+#if 0
+      if (traceDebug())
+      {
+         cout << "ossimAtCorrRemapper::getTile DEBUG:"
+              << "\ntile_rect:    " << tile_rect
+              << "\ntile width:   " << tw
+              << "\ntile height:  " << th
+              << "\nbands:        " << bands
+              << "\nBuffer size:  " << size << endl;
+      }
+#endif
+      
+      theSurfaceReflectance = new double[size];
+   }
+
+   ossim_uint32 buffer_index = 0;
+   ossimIpt ul = tile_rect.ul();
+   ossimIpt lr = tile_rect.lr();
+   const double MP = theTile->getMinNormalizedPix(); // Minimum normalized pix.
+   double a, b, c;
+   buffer_index = 0;
+
+   cout << setprecision(6);
+   for (ossim_uint32 band=0; band < bands; ++band)
+   {
+      for(ossim_sint32 idxy = ul.y; idxy <= lr.y; ++idxy)
+      {
+         for(ossim_sint32 idxx = ul.x; idxx <= lr.x; ++idxx)
+         {
+            double p = inputTile->getPix(buffer_index);
+            
+            if (p>0.0)
+            {
+               if(!theUseInterpolationFlag)
+               {
+                  a = theXaArray[band];
+                  b = theXbArray[band];
+                  c = theXcArray[band];
+               }
+               else
+               {
+                  interpolate(ossimDpt(idxx, idxy),
+                              band,
+                              a,
+                              b,
+                              c);
+               }
+               if(theSensorType == "ls7ms")
+               {
+                  double radiance_at_satellite
+                     = (theGainArray[band] * p) + theBiasArray[band];
+                  
+                  double y =  (radiance_at_satellite * a) -  b;
+                  
+                  p = (y / (1.0 + (c * y)) );
+               }
+               else if(theSensorType == "qbms")
+               {
+                  double radiance_at_satellite
+                     = theCalCoefArray[band] * p / theBandWidthArray[band];
+                  
+                  double y =  (radiance_at_satellite * a) - b;
+                  
+                  p = (y / (1.0 + (c * y)) );
+               }
+               else if(theSensorType == "ikms")
+               {
+                  
+                 
+                  double radiance_at_satellite
+                     =   p  /((theCalCoefArray[band]/1.0)/ theBandWidthArray[band]);
+                  double y =  (radiance_at_satellite * a) -  b;
+    
+                  p = (y / (1.0 + (c * y)) );
+     
+               }  
+                   
+               // Note that "p" should now be normalized between 0.0 and 1.0;
+               
+               // ***
+               // Since it wasn't null to start with clip / clamp between minimum
+               // normalized pixel and one(max).
+               // ***
+               p =  ( p > MP ? ( p < 1.0 ? p : 1.0) : MP );
+               
+               // Scan the new tile and set the min / max.
+               if (p < theMinPixelValue[band])
+               {
+                  theMinPixelValue[band] = p;
+               }
+               else if (p > theMaxPixelValue[band])
+               {
+                  theMaxPixelValue[band] = p;
+               }
+               
+               theSurfaceReflectance[buffer_index] = p;
+            }
+            else
+            {
+               theSurfaceReflectance[buffer_index] = 0.0;  // pixel was null...
+            }
+            
+            ++buffer_index;
+            
+         }  // End of sample loop...
+         
+      } // End of line loop...
+      
+   } // End of band loop...
+
+   // Copy the buffer to the output tile at the same time unnormalizing it.
+   theTile->copyNormalizedBufferToTile(theSurfaceReflectance);
+   
+   // Validate the output to set the tile status.
+   theTile->validate();
+   
+   return theTile;
+}
+
+void ossimAtCorrRemapper::initialize()
+{
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,
+                                                          theInputConnection);
+      theTile->initialize();
+
+      if(theSurfaceReflectance)
+      {
+         delete []theSurfaceReflectance;
+         theSurfaceReflectance = NULL;
+      }
+      
+      ossim_uint32 tw    = theTile->getWidth();
+      ossim_uint32 th    = theTile->getHeight();
+      ossim_uint32 bands = theTile->getNumberOfBands();
+      ossim_uint32 size  = tw*th*bands;
+      if (traceDebug())
+      {
+         cout << "ossimAtCorrRemapper::initialize DEBUG:"
+              << "\ntile width:   " << tw
+              << "\ntile height:  " << th
+              << "\nbands:        " << bands
+              << "\nBuffer size:  " << size << endl;
+      }
+      
+      theSurfaceReflectance = new double[size];
+
+      setInitializedFlag(true);
+      clearErrorStatus();
+   }
+   else
+   {
+      setInitializedFlag(false);
+      setErrorStatus();
+   };
+
+   verifyEnabled();
+
+   if (traceDebug())
+   {
+      cout << "ossimAtCorrRemapper::initialize DEBUG:"
+           << *this
+           << endl;
+   }
+
+}
+
+bool ossimAtCorrRemapper::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   static const char MODULE[] = "ossimAtCorrRemapper::loadState()";
+
+   if (traceDebug())  CLOG << "entering..." << endl;
+
+   if (!theTile || !theSurfaceReflectance)
+   {
+      cerr << MODULE << " ERROR:"
+           << "Not initialized..." << endl;
+      return false;
+   }
+
+   ossim_uint32 bands = theTile->getNumberOfBands();
+
+   // Clear out the old values.
+   theMinPixelValue.clear();
+   theMaxPixelValue.clear();   
+   theXaArray.clear();
+   theXbArray.clear();
+   theXcArray.clear();
+   theBiasArray.clear();
+   theGainArray.clear();
+   theCalCoefArray.clear();
+   theBandWidthArray.clear();
+ 
+   
+   // Now resize them.
+
+   // Start with arbitrary big number.
+   theMinPixelValue.resize(bands, 1.0);
+
+   // Start with arbitrary small number.
+   theMaxPixelValue.resize(bands, 0.0);
+
+   
+   theXaArray.resize(bands, 1.0);
+   theXbArray.resize(bands, 1.0);
+   theXcArray.resize(bands, 1.0);
+   
+   theBiasArray.resize(bands, 0.0);
+   theGainArray.resize(bands, 1.0);
+   theCalCoefArray.resize(bands);
+   theBandWidthArray.resize(bands);
+   
+   for(ossim_uint32 band = 0; band < bands; ++band)
+   {
+      const char* lookup = NULL;
+      ossimString band_string = ".band";
+      band_string += ossimString::toString(band+1);
+      
+      ossimString kw = AT_CORR_XA_KW;
+      kw += band_string;
+      lookup = kwl.find(prefix, kw.c_str());
+      if (lookup)
+      {
+         theXaArray[band] = atof(lookup);
+      }
+      else
+      {
+         if (traceDebug())
+         {
+            CLOG << "DEBUG:"
+                 << "\nlookup failed for keyword:  " << kw.c_str() << endl;
+         }
+      }
+      
+      kw = AT_CORR_XB_KW;
+      kw += band_string;
+      lookup = kwl.find(prefix, kw.c_str());
+      if (lookup)
+      {
+         theXbArray[band] = atof(lookup);
+      }
+      else
+      {
+         if (traceDebug())
+         {
+            CLOG << "DEBUG:"
+                 << "\nlookup failed for keyword:  " << kw.c_str()
+                 << endl;
+         }
+      }
+      
+      kw = AT_CORR_XC_KW;
+      kw += band_string;
+      lookup = kwl.find(prefix, kw.c_str());
+      if (lookup)
+      {
+         theXcArray[band] = atof(lookup);
+      }
+      else
+      {
+         if (traceDebug())
+         {
+            CLOG << "DEBUG:"
+                 << "\nlookup failed for keyword:  " << kw.c_str()
+                 << endl;
+         }
+      }
+      
+      if(theSensorType == "ls7ms")
+      {
+         kw = AT_CORR_BIAS_KW;
+         kw += band_string;
+         lookup = kwl.find(prefix, kw.c_str());
+         if (lookup)
+         {
+            theBiasArray[band] = atof(lookup);
+         }
+         else
+         {
+            if (traceDebug())
+            {
+               CLOG << "DEBUG:"
+                    << "\nlookup failed for keyword:  " << kw.c_str()
+                    << endl;
+            }
+         }
+         
+         kw = AT_CORR_GAIN_KW;
+         kw += band_string;
+         lookup = kwl.find(prefix, kw.c_str());
+         if (lookup)
+         {
+            theGainArray[band] = atof(lookup);
+         }
+         else
+         {
+            if (traceDebug())
+            {
+               CLOG << "DEBUG:"
+                    << "\nlookup failed for keyword:  " << kw.c_str()
+                    << endl;
+            }
+         }
+      }
+      
+      if(theSensorType == "qbms")
+      {
+         kw = AT_CORR_CALCOEF_KW;
+         kw += band_string;
+         lookup = kwl.find(prefix, kw.c_str());
+         if (lookup)
+         {
+            theCalCoefArray[band] = atof(lookup);
+         }
+         else
+         {
+            if (traceDebug())
+            {
+               CLOG << "DEBUG:"
+                    << "\nlookup failed for keyword:  " << kw.c_str()
+                    << endl;
+            }
+         }
+         
+         kw = AT_CORR_BANDWIDTH_KW;
+         kw += band_string;
+         lookup = kwl.find(prefix, kw.c_str());
+         if (lookup)
+         {
+            theBandWidthArray[band] = atof(lookup);
+         }
+         else
+         {
+            if (traceDebug())
+            {
+               CLOG << "DEBUG:"
+                    << "\nlookup failed for keyword:  " << kw.c_str()
+                    << endl;
+            }
+         }
+      }
+      if(theSensorType == "ikms")
+      {
+         kw = AT_CORR_CALCOEF_KW;
+         kw += band_string;
+         lookup = kwl.find(prefix, kw.c_str());
+         if (lookup)
+         {
+            theCalCoefArray[band] = atof(lookup);
+         }
+         else
+         {
+            if (traceDebug())
+            {
+               CLOG << "DEBUG:"
+                    << "\nlookup failed for keyword:  " << kw.c_str()
+                    << endl;
+            }
+         }
+         
+         kw = AT_CORR_BANDWIDTH_KW;
+         kw += band_string;
+         lookup = kwl.find(prefix, kw.c_str());
+         if (lookup)
+         {
+            theBandWidthArray[band] = atof(lookup);
+         }
+         else
+         {
+            if (traceDebug())
+            {
+               CLOG << "DEBUG:"
+                    << "\nlookup failed for keyword:  " << kw.c_str()
+                    << endl;
+            }
+         }
+      }
+   }
+   
+   verifyEnabled();
+
+   if (theEnableFlag)
+   {
+      //***
+      // Call the base class to pick up the enable flag.  Note that this
+      // can override the state set from verifyEnabled() method.
+      //***
+      ossimString pref;
+      if (prefix) pref += prefix;
+      pref += "atmospheric_correction.";
+
+   }
+   
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << *this
+           << "returning..."
+           << endl;
+   }
+   
+   return true;
+}
+
+void ossimAtCorrRemapper::verifyEnabled()
+{
+   // Check all the pointers...
+   if ( !theInputConnection    || !theTile ||
+        !theSurfaceReflectance )
+   {
+      disableSource();
+      return;
+   }
+
+   ossim_uint32 bands = theTile->getNumberOfBands();
+   if ( (theMinPixelValue.size() != bands) ||
+        (theMaxPixelValue.size() != bands) ||
+        (theXaArray.size()       != bands) ||
+        (theXbArray.size()       != bands) ||
+        (theXcArray.size()       != bands) ||
+        (theBiasArray.size()     != bands) ||
+        (theGainArray.size()     != bands) ||
+        (theCalCoefArray.size()  != bands) ||
+        (theBandWidthArray.size()!= bands))
+   {
+      disableSource(); 
+      return;
+   }
+
+   enableSource();
+}
+
+ossimString ossimAtCorrRemapper::getShortName() const
+{
+   return ossimString("Atmospheric Correction Remapper");
+}
+
+vector<double> ossimAtCorrRemapper::getNormMinPixelValues() const
+{
+   return theMinPixelValue;
+}
+
+vector<double> ossimAtCorrRemapper::getNormMaxPixelValues() const
+{
+   return theMaxPixelValue;
+}
+
+void ossimAtCorrRemapper::getNormMinPixelValues(vector<double>& v) const
+{
+   v = theMinPixelValue;
+}
+
+void ossimAtCorrRemapper::getNormMaxPixelValues(vector<double>& v) const
+{
+   v = theMaxPixelValue;
+}
+
+const ossimString& ossimAtCorrRemapper::getSensorType() const
+{
+   return theSensorType;
+}
+
+void ossimAtCorrRemapper::setSensorType(const ossimString& sensorType)
+{
+   theSensorType = sensorType;
+}
+
+void ossimAtCorrRemapper::interpolate(const ossimDpt& pt,
+                                      int band,
+                                      double& a,
+                                      double& b,
+                                      double& c)const
+{
+   a = theXaArray[band];
+   b = theXbArray[band];
+   c = theXcArray[band];
+}
+
+ostream& ossimAtCorrRemapper::print(ostream& os) const
+{
+   os << "ossimAtCorrRemapper:"
+      << "\ntheEnableFlag:  " << (theEnableFlag?"enabled":"disabled")
+      << endl;
+
+   os << setprecision(15) << setiosflags(ios::fixed);
+
+   ossim_uint32 band = 1;
+   vector<double>::const_iterator i = theMinPixelValue.begin();
+   while (i != theMinPixelValue.end())
+   {
+      os << "band[" << band << "] min:  " << (*i) << endl;
+      ++i;
+      ++band;
+   }
+
+   band = 1;
+   i = theMaxPixelValue.begin();
+   while (i != theMaxPixelValue.end())
+   {
+      os << "band[" << band << "] max:  " << (*i) << endl;
+      ++i;
+      ++band;
+   }
+
+   band = 1;
+   i = theXaArray.begin();
+   while (i != theXaArray.end())
+   {
+      os << "band[" << band << "] xa:  " << (*i) << endl;
+      ++i;
+      ++band;
+   }
+
+   band = 1;
+   i = theXbArray.begin();
+   while (i != theXbArray.end())
+   {
+      os << "band[" << band << "] xb:  " << (*i) << endl;
+      ++i;
+      ++band;
+   }
+
+   band = 1;
+   i = theXcArray.begin();
+   while (i != theXcArray.end())
+   {
+      os << "band[" << band << "] xc:  " << (*i) << endl;
+      ++i;
+      ++band;
+   }
+
+   if(theSensorType == "ls7ms")
+   {
+      band = 1;
+      i = theBiasArray.begin();
+      while (i != theBiasArray.end())
+      {
+         os << "band[" << band << "] bias:  " << (*i) << endl;
+         ++i;
+         ++band;
+      }
+      
+      band = 1;
+      i = theGainArray.begin();
+      while (i != theGainArray.end())
+      {
+         os << "band[" << band << "] gain:  " << (*i) << endl;
+         ++i;
+         ++band;
+      }
+   }
+   if(theSensorType == "qbms")
+   {
+      band = 1;
+      i = theCalCoefArray.begin();
+      while (i != theCalCoefArray.end())
+      {
+         os << "band[" << band << "] calcoef:  " << (*i) << endl;
+         ++i;
+         ++band;
+      }
+
+      band = 1;
+      i = theBandWidthArray.begin();
+      while (i != theBandWidthArray.end())
+      {
+         os << "band[" << band << "] bandwidth:  " << (*i) << endl;
+         ++i;
+         ++band;
+      }
+   }
+   if(theSensorType == "ikms")
+   {
+      band = 1;
+      i = theCalCoefArray.begin();
+      while (i != theCalCoefArray.end())
+      {
+         os << "band[" << band << "] calcoef:  " << (*i) << endl;
+         ++i;
+         ++band;
+      }
+
+   }
+   return os;
+}
+
+ostream& operator<<(ostream& os, const ossimAtCorrRemapper& hr)
+{
+   return hr.print(os);
+}
+
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrRemapper.h b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrRemapper.h
new file mode 100644
index 0000000000..91b70146d3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimAtCorrRemapper.h
@@ -0,0 +1,88 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kathy Minear
+//
+// Description:
+// Takes in DNs for any number of bands
+// Converts DNs to Radiance at the satellite values Lsat
+// Converts Lsat to Surface Reflectance values
+//
+//*************************************************************************
+// $Id: ossimAtCorrRemapper.h,v 1.12 2005/02/11 15:07:30 dburken Exp $
+#ifndef ossimAtCorrRemapper_HEADER
+#define ossimAtCorrRemapper_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimAtCorrRemapper : public ossimImageSourceFilter
+{
+public:
+
+   ossimAtCorrRemapper(ossimObject* owner = NULL,
+                       ossimImageSource* inputSource =  NULL,
+                       const ossimString& sensorType = "");
+
+   virtual ~ossimAtCorrRemapper();
+
+   virtual ossimString getShortName() const;
+
+   virtual void initialize();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual ostream& print(ostream& os) const;
+   friend ostream& operator << (ostream& os,  const ossimAtCorrRemapper& hr);
+
+   vector<double> getNormMinPixelValues() const;
+   vector<double> getNormMaxPixelValues() const;
+
+   void getNormMinPixelValues(vector<double>& v) const;
+   void getNormMaxPixelValues(vector<double>& v) const;
+
+   const ossimString& getSensorType() const;
+
+   void setSensorType(const ossimString& sensorType);
+
+protected:
+
+   /*!
+    * Method to set unset the enable flag.
+    */
+   void verifyEnabled();
+   virtual void interpolate(const ossimDpt& pt,
+                            int band,
+                            double& a,
+                            double& b,
+                            double& c)const;
+                            
+   ossimRefPtr<ossimImageData> theTile;
+   double*            theSurfaceReflectance;
+   bool               theUseInterpolationFlag;
+   vector<double>     theMinPixelValue;
+   vector<double>     theMaxPixelValue;
+   vector<double>     theXaArray;
+   vector<double>     theXbArray;
+   vector<double>     theXcArray;
+   vector<double>     theBiasArray;
+   vector<double>     theGainArray;
+   vector<double>     theCalCoefArray;
+   vector<double>     theBandWidthArray;
+   ossimString        theSensorType;
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimAtCorrRemapper_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimGammaRemapper.cpp b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimGammaRemapper.cpp
new file mode 100644
index 0000000000..481f3cb61a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimGammaRemapper.cpp
@@ -0,0 +1,433 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kathy Minear
+//
+// Description: Takes in DNs for any number of bands
+// Converts DNs to Radiance at the satellite values Lsat
+// Converts Lsat to Surface Reflectance values
+//
+//*************************************************************************
+// $Id: ossimGammaRemapper.cpp,v 1.11 2005/05/09 12:39:38 dburken Exp $
+
+#include <math.h>
+
+#include <imaging/atmospheric_correction/ossimGammaRemapper.h>
+#include <imaging/atmospheric_correction/ossimAtCorrKeywords.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+
+RTTI_DEF1(ossimGammaRemapper, "ossimGammaRemapper", ossimImageSourceFilter)
+
+static const double DEFAULT_GAMMA = 1.0;
+
+
+static ossimTrace traceDebug("ossimGammaRemapper:debug");
+
+ossimGammaRemapper::ossimGammaRemapper(ossimObject* owner)
+   :
+      ossimImageSourceFilter  (owner),  // base class
+      theTile                 (NULL),
+      theBuffer               (NULL), 
+      theMinPixelValue        (0),
+      theMaxPixelValue        (0),
+      theGamma                (0),
+      theUserDisabledFlag     (false)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+
+   // Construction not complete.
+}
+
+
+ossimGammaRemapper::ossimGammaRemapper(ossimImageSource* inputSource)
+   :
+      ossimImageSourceFilter  (NULL, inputSource),  // base class
+      theTile                 (NULL),
+      theBuffer               (NULL),
+      theMinPixelValue        (0),
+      theMaxPixelValue        (0),
+      theGamma                (0),
+      theUserDisabledFlag     (false)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+
+   if (inputSource == NULL)
+   {
+      setErrorStatus();
+      cerr << "ossimGammaRemapper::ossimGammaRemapper ERROR:"
+           << "\nNull input source passed to constructor!" << endl;
+      return;
+   }
+
+   initialize();
+}
+
+
+ossimGammaRemapper::ossimGammaRemapper(ossimObject* owner,
+                                         ossimImageSource* inputSource)
+   :
+      ossimImageSourceFilter  (owner, inputSource),  // base class     
+      theTile                 (NULL),
+      theBuffer               (NULL),
+      theMinPixelValue        (0),
+      theMaxPixelValue        (0),
+      theGamma                (0)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+
+   if (inputSource == NULL)
+   {
+      setErrorStatus();
+      cerr << "ossimGammaRemapper::ossimGammaRemapper ERROR:"
+           << "\nNull input source passed to constructor!" << endl;
+      return;
+   }
+
+   initialize();
+}
+
+ossimGammaRemapper::~ossimGammaRemapper()
+{
+   if (theBuffer)
+   {
+      delete [] theBuffer;
+      theBuffer = NULL;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimGammaRemapper::getTile(const ossimIrect& tile_rect,
+                                            ossim_uint32 resLevel)
+{
+   if (!isInitialized())
+   {
+      cerr << "ossimGammaRemapper::getTile ERROR:"
+           << "\nNot initialized!"
+           << endl;
+      return ossimRefPtr<ossimImageData>();
+   }
+      
+   // Fetch tile from pointer from the input source.
+   ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(
+      tile_rect, resLevel);
+
+   if (!inputTile.valid())  // Just in case...
+   {
+      cerr << "ossimGammaRemapper::getTile ERROR:"
+           << "\nReceived null pointer to tile from input source!"
+           << "\nReturning blank tile."
+           << endl;
+      theTile->makeBlank();
+      return theTile;
+   }
+
+   // Get its status.
+   ossimDataObjectStatus tile_status = inputTile->getDataObjectStatus();
+   
+   //---
+   // Check for remap bypass:
+   //---
+   if (!theEnableFlag || tile_status == OSSIM_NULL ||!theTile.valid() ||
+       tile_status == OSSIM_EMPTY)
+   {
+      return inputTile;
+   }
+
+   ossim_uint32 w     = tile_rect.width();
+   ossim_uint32 h     = tile_rect.height();
+   ossim_uint32 tw    = theTile->getWidth();
+   ossim_uint32 th    = theTile->getHeight();
+   ossim_uint32 bands = theTile->getNumberOfBands();
+
+   // Set the origin of the output tile.
+   theTile->setOrigin(tile_rect.ul());
+
+   if(w*h != tw*th)
+   {
+      theTile->setWidthHeight(w, h);
+      theTile->initialize();
+      if(theBuffer)
+      {
+         delete [] theBuffer;
+         theBuffer = NULL;
+      }
+   }   
+   
+   if(!theBuffer)
+   {
+      theBuffer = new double[w*h*bands];
+   }
+   
+   // Copy the source tile into the buffer at the same time normalizing it.
+   inputTile->copyTileToNormalizedBuffer(theBuffer);
+   
+   // for each band, get the radiance value
+
+   ossim_uint32 buffer_index = 0;
+   const double MP = theTile->getMinNormalizedPix(); // Minimum normalized pix.
+   const ossim_uint32 PPTB = theTile->getSizePerBand();  // Pixels Per Tile Band
+
+   for (ossim_uint32 band=0; band<bands; ++band)
+   {
+      for (ossim_uint32 i=0; i<PPTB; ++i)
+      {
+         double p = theBuffer[buffer_index]; // input pixel
+         // double p = getPix(buffer_index);
+
+         if (p)
+         {
+            // cout<<"p before:  "<<p<<endl;
+            // Stretch it...
+            p = (p - theMinPixelValue[band]) /
+               (theMaxPixelValue[band] -
+                theMinPixelValue[band]);
+            
+            p = pow(p, theGamma[band]);
+           
+            
+            //***
+            // Since it wasn't null to start with clip / clamp between minimum
+            // normalized pixel and one(max).
+            //*** 
+            p =  ( p > MP ? ( p < 1.0 ? p : 1.0) : MP );  
+
+            theBuffer[buffer_index] = p;
+         }
+         else
+         {
+            theBuffer[buffer_index] = 0.0;
+         }
+         
+         ++buffer_index;
+      }
+   }
+   
+   // Copy the buffer to the output tile at the same time unnormalizing it.
+   theTile->copyNormalizedBufferToTile(theBuffer);
+   
+   // Set the status to that of the input tile.
+   theTile->setDataObjectStatus(tile_status);
+
+   return theTile;
+}
+
+void ossimGammaRemapper::initialize()
+{
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,
+                                                          theInputConnection);
+      theTile->initialize();
+
+      if(theBuffer)
+      {
+         delete []theBuffer;
+         theBuffer = NULL;
+      }
+      
+      ossim_uint32 tw    = theTile->getWidth();
+      ossim_uint32 th    = theTile->getHeight();
+      ossim_uint32 bands = theTile->getNumberOfBands();
+      
+      theBuffer = new double[tw*th*bands];
+      memset(theBuffer, '\0', tw*th*bands);
+
+      setInitializedFlag(true);
+      clearErrorStatus();
+   }
+   else
+   {
+      setInitializedFlag(false);
+      setErrorStatus();
+      cerr << "ossimGammaRemapper::initialize ERROR:"
+           << "\nCannot call method when input connection is NULL!"
+           << endl;
+   };
+
+   verifyEnabled();
+}
+
+void ossimGammaRemapper::setMinMaxPixelValues(const vector<double>& v_min,
+                                              const vector<double>& v_max)
+{
+   theMinPixelValue = v_min;
+   theMaxPixelValue = v_max;
+   verifyEnabled();
+}
+
+void ossimGammaRemapper::verifyEnabled()
+{
+   // Check all the pointers...
+   if ( !theInputConnection || !theTile || !theBuffer )
+   {
+      disableSource();
+      return;
+   }
+
+   ossim_uint32 bands = theTile->getNumberOfBands();
+   if ( (theMinPixelValue.size() != bands) ||
+        (theMaxPixelValue.size() != bands) )
+   {
+      disableSource(); 
+      return;
+   }
+
+   if (theUserDisabledFlag == false)
+   {
+      enableSource();
+   }
+
+   if (traceDebug())
+   {
+      cout << *this << endl;
+   }
+}
+
+bool ossimGammaRemapper::loadState(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+{
+   //***
+   // Call the base class to pick up the enable flag.  Note that the
+   // verifyEnabled flag can override this.
+   //***
+   ossimString pref;
+   if (prefix) pref += prefix;
+   pref += "gamma_remapper.";
+
+   if (!theTile)
+   {
+      cerr << "ossimGammaRemapper::loadState:  ERROR"
+           << "Not initialized yet!" << endl;
+      return false;
+   }
+
+   //---
+   // NOTE:
+   // base class seems to call initialize which in turn errors if you don't
+   // have a connection yet, so check for the enable keyword here...
+   // ossimSource::loadState(kwl, pref.c_str());
+   //---
+   cout << "pref:  " << pref
+        << "kw:  " << ossimKeywordNames::ENABLED_KW    << endl;
+   
+   const char* lookup = kwl.find(pref, ossimKeywordNames::ENABLED_KW);
+   if(lookup)
+   {
+      theEnableFlag = ossimString(lookup).toBool();
+      if (theEnableFlag == false)
+      {
+         // User want filter disabled...
+         theUserDisabledFlag = true;
+      }
+   }
+
+   ossim_uint32 bands = theTile->getNumberOfBands();
+
+   theGamma.clear();
+   theGamma.resize(bands, 1.0);
+
+   for(ossim_uint32 band = 0; band < bands; ++band)
+   {
+      ossimString band_string = ".band";
+      band_string += ossimString::toString(band+1);  // Start at one.
+
+      ossimString kw = GAMMA_REMAPPER_GAMMA_KW;
+      kw += band_string;
+      lookup = kwl.find(prefix, kw.c_str());
+      if (lookup)
+      {
+         theGamma[band] = atof(lookup);
+      }
+      else
+      {
+         cout << "MODULE NOTICE:"
+              << "\nlookup failed for keyword:  " << kw.c_str()
+              << "\nGamma set to " << DEFAULT_GAMMA << " for band:  "
+              << (band+1) << endl;
+         theGamma[band] = DEFAULT_GAMMA;
+      }
+   }
+
+   if (traceDebug())
+   {
+      cout << "ossimGammaRemapper DEBUG:"
+           << *this
+           << endl;
+   }
+   
+   return true;
+}
+
+ostream& ossimGammaRemapper::print(ostream& os) const
+{
+   os << setprecision(15) << setiosflags(ios::fixed)
+      << "ossimGammaRemapper:"
+      << "\ntheEnableFlag:  " << (theEnableFlag?"enabled":"disabled")
+      << endl;
+
+   ossim_uint32 band = 1;
+   vector<double>::const_iterator i = theMinPixelValue.begin();
+   while (i != theMinPixelValue.end())
+   {
+      os << "band[" << band << "] min:  " << (*i) << endl;
+      ++i;
+      ++band;
+   }
+
+   band = 1;
+   i = theMaxPixelValue.begin();
+   while (i != theMaxPixelValue.end())
+   {
+      os << "band[" << band << "] max:  " << (*i) << endl;
+      ++i;
+      ++band;
+   }
+   
+   band = 1;
+   i = theGamma.begin();
+   while (i != theGamma.end())
+   {
+      os << "band[" << band << "] gamma:  " << (*i) << endl;
+      ++i;
+      ++band;
+   }
+
+   return os;
+}
+
+void ossimGammaRemapper::enableSource()
+{
+   // Clear the flag...
+   theUserDisabledFlag = false;
+   ossimSource::enableSource();
+}
+
+ossimString ossimGammaRemapper::getShortName() const
+{
+   return ossimString("Gamma Remapper");
+}
+
+ostream& operator<<(ostream& os, const ossimGammaRemapper& hr)
+{
+   return hr.print(os);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimGammaRemapper.h b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimGammaRemapper.h
new file mode 100644
index 0000000000..d540518112
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/atmospheric_correction/ossimGammaRemapper.h
@@ -0,0 +1,71 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kathy Minear
+//
+// Description:
+//
+// Gamma remapper.
+//
+//*************************************************************************
+// $Id: ossimGammaRemapper.h,v 1.8 2005/02/11 15:07:30 dburken Exp $
+#ifndef ossimGammaRemapper_HEADER
+#define ossimGammaRemapper_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimGammaRemapper : public ossimImageSourceFilter
+{
+public:
+
+   ossimGammaRemapper(ossimObject* owner=NULL);
+   ossimGammaRemapper(ossimImageSource* inputSource);
+   ossimGammaRemapper(ossimObject* owner, ossimImageSource* inputSource);
+
+   virtual ~ossimGammaRemapper();
+
+   virtual ossimString getShortName()const;
+
+   virtual void initialize();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                   ossim_uint32 resLevel=0);
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual ostream& print(ostream& os) const;
+   friend ostream& operator<< (ostream& os,  const ossimGammaRemapper& hr);
+
+   void setMinMaxPixelValues(const vector<double>& v_min,
+                             const vector<double>& v_max);
+
+   virtual void enableSource();
+   
+protected:
+
+   /*!
+    * Method to set unset the enable flag.
+    */
+
+   void verifyEnabled();
+
+   ossimRefPtr<ossimImageData> theTile;
+   double*         theBuffer;
+   vector<double>  theMinPixelValue;
+   vector<double>  theMaxPixelValue;
+   vector<double>  theGamma;
+   bool            theUserDisabledFlag;
+
+   TYPE_DATA
+};
+
+#endif /* #ifndef ossimGammaRemapper_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/cache/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/cache/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/cache/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppFixedTileCache.cpp b/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppFixedTileCache.cpp
new file mode 100644
index 0000000000..da3db0ceca
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppFixedTileCache.cpp
@@ -0,0 +1,383 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: This file contains the Application cache algorithm
+//
+//***********************************
+// $Id: ossimAppFixedTileCache.cpp,v 1.9 2005/08/17 19:18:12 gpotts Exp $
+#include <algorithm>
+#include <sstream>
+#include <imaging/cache/ossimAppFixedTileCache.h>
+#include <imaging/cache/ossimFixedTileCache.h>
+#include <base/common/ossimPreferences.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimTrace.h>
+
+ossimAppFixedTileCache* ossimAppFixedTileCache::theInstance = NULL;
+ossimAppFixedTileCache::ossimAppFixedCacheId ossimAppFixedTileCache::theUniqueAppIdCounter = 0;
+const ossim_uint32 ossimAppFixedTileCache::DEFAULT_SIZE = 1024*1024*80;
+
+static const ossimTrace traceDebug("ossimAppFixedTileCache:debug");
+std::ostream& operator <<(std::ostream& out, const ossimAppFixedTileCache& rhs)
+{
+   std::map<ossimAppFixedTileCache::ossimAppFixedCacheId, ossimFixedTileCache*>::const_iterator iter = rhs.theAppCacheMap.begin();
+
+   if(iter == rhs.theAppCacheMap.end())
+   {
+      cout << "***** APP CACHE EMPTY *****" << endl;
+   }
+   else
+   {
+      while(iter != rhs.theAppCacheMap.end())
+      {
+         out << "Cache id = "<< (*iter).first << " size = " << (*iter).second->getCacheSize() << endl;
+         ++iter;
+      }
+   }
+
+   return out;
+}
+
+
+ossimAppFixedTileCache::ossimAppFixedTileCache()
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimAppFixedTileCache::ossimAppFixedTileCache() DEBUG: entered ..." << std::endl;
+   }
+   theInstance = this;
+   theTileSize = ossimIpt(64, 64);
+   theCurrentCacheSize = 0;
+
+   ossimGetDefaultTileSize(theTileSize);
+   
+   ossim_uint32 cacheSize = ossimString(ossimPreferences::instance()->findPreference("cache_size")).toUInt32()*(1024*1024);
+   const char* tileSize = ossimPreferences::instance()->findPreference("tile_size");
+   if(tileSize)
+   {
+      std::stringstream in(tileSize);
+      in >> theTileSize.x >> theTileSize.y;
+      if(theTileSize.x < 1) theTileSize.x = 64;
+      if(theTileSize.y < 1) theTileSize.y = 64;
+   }
+   if(cacheSize)
+   {
+      setMaxCacheSize(cacheSize);
+   }
+   else
+   {
+      setMaxCacheSize(DEFAULT_SIZE);
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: cache tile size = " << theTileSize << std::endl
+                                          << "Cache size = " << cacheSize << " bytes" << std::endl;
+   }
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimAppFixedTileCache::ossimAppFixedTileCache() DEBUG: leaving ..." << std::endl;
+   }
+}
+
+ossimAppFixedTileCache::~ossimAppFixedTileCache()
+{
+   deleteAll();
+}
+
+ossimAppFixedTileCache *ossimAppFixedTileCache::instance(ossim_uint32  maxSize)
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimAppFixedTileCache;
+      if(maxSize)
+	{
+	  theInstance->setMaxCacheSize(maxSize);
+	}
+   }
+   return theInstance;
+}
+
+void ossimAppFixedTileCache::setMaxCacheSize(ossim_uint32 cacheSize)
+{
+   theMaxGlobalCacheSize = cacheSize;
+   theMaxCacheSize = cacheSize;
+   //   theMaxCacheSize      = (ossim_uint32)(theMaxGlobalCacheSize*.2);
+}
+
+void ossimAppFixedTileCache::flush()
+{
+   std::map<ossimAppFixedCacheId, ossimFixedTileCache*>::iterator currentIter = theAppCacheMap.begin();
+
+   while(currentIter != theAppCacheMap.end())
+   {
+      (*currentIter).second->flush();
+      ++currentIter;
+   }
+   theCurrentCacheSize = 0;
+}
+
+void ossimAppFixedTileCache::flush(ossimAppFixedCacheId cacheId)
+{
+   ossimFixedTileCache* cache = getCache(cacheId);
+
+   if(cache)
+   {
+      theCurrentCacheSize -= cache->getCacheSize();
+      cache->flush();
+   }
+}
+
+void ossimAppFixedTileCache::deleteCache(ossimAppFixedCacheId cacheId)
+{
+   ossimFixedTileCache* cache = getCache(cacheId);
+   std::map<ossimAppFixedCacheId, ossimFixedTileCache*>::iterator iter = theAppCacheMap.find(cacheId);
+
+   if(cache)
+   {
+      theAppCacheMap.erase(iter);
+      theCurrentCacheSize -= cache->getCacheSize();
+      delete cache;
+   }
+}
+
+ossimAppFixedTileCache::ossimAppFixedCacheId ossimAppFixedTileCache::newTileCache(const ossimIrect& tileBoundaryRect,
+                                                                                  const ossimIpt& tileSize)
+{
+   ossimAppFixedCacheId result = theUniqueAppIdCounter;
+   ossimFixedTileCache* newCache = new ossimFixedTileCache;
+   if(tileSize.x == 0 ||
+      tileSize.y == 0)
+   {
+      newCache->setRect(tileBoundaryRect, theTileSize);
+   }
+   else
+   {
+      newCache->setRect(tileBoundaryRect, tileSize);
+   }
+   
+   theAppCacheMap.insert(std::make_pair(result, newCache));
+   ++theUniqueAppIdCounter;
+   
+   return result;
+}
+
+ossimAppFixedTileCache::ossimAppFixedCacheId ossimAppFixedTileCache::newTileCache()
+{
+   ossimAppFixedCacheId result = theUniqueAppIdCounter;
+   ossimFixedTileCache* newCache = new ossimFixedTileCache;
+   
+   theAppCacheMap.insert(std::make_pair(result, newCache));
+   ++theUniqueAppIdCounter;
+   
+   return result;
+   
+}
+
+void ossimAppFixedTileCache::setRect(ossimAppFixedCacheId cacheId,
+                                     const ossimIrect& boundaryTileRect)
+{
+   ossimFixedTileCache* cache = getCache(cacheId);
+   if(cache)
+   {
+      ossim_uint32 cacheSize = cache->getCacheSize();
+      cache->setRect(boundaryTileRect, theTileSize);
+      theCurrentCacheSize += (cache->getCacheSize() - cacheSize);
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimAppFixedTileCache::getTile(
+   ossimAppFixedCacheId cacheId,
+   const ossimIpt& origin)
+{
+   ossimRefPtr<ossimImageData> result = NULL;
+   ossimFixedTileCache* cache = getCache(cacheId);
+   if(cache)
+   {
+      result = cache->getTile(origin);
+   }
+
+   return result;
+}
+
+
+ossimRefPtr<ossimImageData> ossimAppFixedTileCache::addTile(
+   ossimAppFixedCacheId cacheId,
+   ossimRefPtr<ossimImageData> data)
+{
+   ossimRefPtr<ossimImageData> result = NULL;
+   ossimFixedTileCache *aCache = this->getCache(cacheId);
+   if(!aCache)
+   {         
+      return result;
+   }
+   long dataSize = data->getDataSizeInBytes();
+
+   if( (theCurrentCacheSize+dataSize) > theMaxGlobalCacheSize)
+   {
+      shrinkGlobalCacheSize((ossim_int32)(theMaxGlobalCacheSize*0.1));
+   }
+
+   ossim_uint32 cacheSize = aCache->getCacheSize();
+   if(cacheSize > theMaxCacheSize)
+   {
+//       shrinkCacheSize(aCache,
+//                       (ossim_int32)(aCache->getCacheSize()*.1));
+      shrinkCacheSize(aCache,
+                      (ossim_int32)(1024*1024));
+   }
+   cacheSize = aCache->getCacheSize();
+   aCache->addTile(data);
+   theCurrentCacheSize += (aCache->getCacheSize() - cacheSize);
+   
+   return result;
+}
+
+void ossimAppFixedTileCache::deleteAll()
+{
+   std::map<ossimAppFixedCacheId, ossimFixedTileCache*>::iterator iter = theAppCacheMap.begin();
+   theCurrentCacheSize = 0;
+
+   while(iter != theAppCacheMap.end())
+   {
+      if((*iter).second)
+      {
+         delete (*iter).second;
+      }
+      
+      ++iter;
+   }
+   theAppCacheMap.clear();
+}
+
+ossimRefPtr<ossimImageData> ossimAppFixedTileCache::removeTile(
+   ossimAppFixedCacheId cacheId,
+   const ossimIpt& origin)
+{
+   ossimRefPtr<ossimImageData> result = NULL;
+   
+   ossimFixedTileCache* cache = getCache(cacheId);
+   if(cache)
+   {
+      ossim_uint32 cacheSize = cache->getCacheSize();
+      result = cache->removeTile(origin);
+      theCurrentCacheSize += (cache->getCacheSize() - cacheSize);
+   }
+
+   return result;
+}
+
+void ossimAppFixedTileCache::deleteTile(ossimAppFixedCacheId cacheId,
+                                        const ossimIpt& origin)
+{
+   ossimFixedTileCache* cache = getCache(cacheId);
+   if(cache)
+   {
+      ossim_uint32 cacheSize = cache->getCacheSize();
+      cache->deleteTile(origin);
+      theCurrentCacheSize += (cache->getCacheSize() - cacheSize);
+   }
+}
+
+ossimFixedTileCache* ossimAppFixedTileCache::getCache(ossimAppFixedCacheId cacheId)
+{
+   std::map<ossimAppFixedCacheId, ossimFixedTileCache*>::iterator currentIter = theAppCacheMap.find(cacheId);
+   ossimFixedTileCache* result = (ossimFixedTileCache*)NULL;
+   
+   if(currentIter != theAppCacheMap.end())
+   {
+      result = (*currentIter).second;
+   }
+
+   return result;
+}
+
+void ossimAppFixedTileCache::shrinkGlobalCacheSize(ossim_int32 byteCount)
+{
+   if(static_cast<ossim_uint32>(byteCount) >= theCurrentCacheSize)
+   {
+      flush();
+   }
+   else
+   {
+      while(byteCount > 0)
+      {
+         std::map<ossimAppFixedCacheId, ossimFixedTileCache*>::iterator iter = theAppCacheMap.begin();
+         while( (iter != theAppCacheMap.end())&&(byteCount>0))
+         {
+            ossimFixedTileCache* cache = getCache((*iter).first);
+            if(cache)
+            {
+               ossim_uint32 before = cache->getCacheSize();
+               cache->deleteTile();
+               ossim_uint32 after = cache->getCacheSize();
+               ossim_uint32 delta = (before - after);
+               byteCount -= delta;
+               theCurrentCacheSize -= (delta);
+               ++iter;
+            }
+         }
+      }
+   }
+}
+
+void ossimAppFixedTileCache::shrinkCacheSize(ossimAppFixedCacheId id,
+                                             ossim_int32 byteCount)
+{
+   ossimFixedTileCache* cache = getCache(id);
+
+   if(cache)
+   {
+      shrinkCacheSize(cache, byteCount);
+   }
+}
+
+void ossimAppFixedTileCache::shrinkCacheSize(ossimFixedTileCache* cache,
+                                             ossim_int32 byteCount)
+{
+   if(cache)
+   {
+      ossim_int32 cacheSize = cache->getCacheSize();
+      if(cacheSize <= byteCount)
+      {
+         cache->flush();
+      }
+      else
+      {
+         while(byteCount > 0)
+         {
+            ossim_uint32 before = cache->getCacheSize();
+            cache->deleteTile();
+            ossim_uint32 after = cache->getCacheSize();
+            ossim_uint32 delta = ossimAbs((int)(before - after));
+            if(delta)
+            {
+               byteCount -= delta;
+               theCurrentCacheSize -= (delta);
+            }
+            else
+            {
+               byteCount = 0;
+            }
+         }
+      }
+   }
+}
+
+const ossimIpt& ossimAppFixedTileCache::getTileSize(ossimAppFixedCacheId cacheId)
+{
+   ossimFixedTileCache* cache = getCache(cacheId);
+
+   if(cache)
+   {
+      return cache->getTileSize();
+   }
+
+   return theTileSize;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppFixedTileCache.h b/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppFixedTileCache.h
new file mode 100644
index 0000000000..f4a83190b8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppFixedTileCache.h
@@ -0,0 +1,118 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: This file contains the Application cache algorithm
+//
+//***********************************
+// $Id: ossimAppFixedTileCache.h,v 1.6 2005/08/17 19:18:12 gpotts Exp $
+#ifndef ossimAppFixedTileCache_HEADER
+#define ossimAppFixedTileCache_HEADER
+#include <map>
+#include <list>
+#include <iostream>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimIrect.h>
+
+
+class ossimFixedTileCache;
+class ossimImageData;
+
+class ossimAppFixedTileCache
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out,
+                                    const ossimAppFixedTileCache& rhs);
+   static const ossim_uint32 DEFAULT_SIZE;
+   typedef ossim_int32 ossimAppFixedCacheId;
+   static ossimAppFixedTileCache *instance(ossim_uint32  maxSize   = 0);
+   virtual ~ossimAppFixedTileCache();
+   
+   /*!
+    * Will flush all cache registered
+    */
+   virtual void flush();
+   virtual void flush(ossimAppFixedCacheId cacheId);
+   virtual void deleteCache(ossimAppFixedCacheId cacheId);
+   /*!
+    * Will create a new Tile cache for this application if the tile size is 0,0 it will
+    * use the default tile size.  Will
+    * return 0 if not successful.
+    */
+   ossimAppFixedCacheId newTileCache(const ossimIrect& tileBoundaryRect,
+                                     const ossimIpt& tileSize=ossimIpt(0,0));
+   ossimAppFixedCacheId newTileCache();
+
+   virtual void setRect(ossimAppFixedCacheId cacheId,
+                        const ossimIrect& boundaryTileRect);
+   
+   ossimRefPtr<ossimImageData> getTile(ossimAppFixedCacheId cacheId,
+                           const ossimIpt& origin);
+   ossimRefPtr<ossimImageData> addTile(ossimAppFixedCacheId cacheId,
+                                       ossimRefPtr<ossimImageData> data);
+   
+   ossimRefPtr<ossimImageData> removeTile(ossimAppFixedCacheId cacheId,
+                                          const ossimIpt& origin);
+   void deleteTile(ossimAppFixedCacheId cacheId,
+                   const ossimIpt& origin);
+   
+   const ossimIpt& getTileSize(ossimAppFixedCacheId cacheId);
+   
+   virtual void setMaxCacheSize(ossim_uint32 cacheSize);
+   
+protected:
+//    struct ossimAppFixedCacheTileInfo
+//    {
+//    public:
+//       ossimAppFixedCacheTileInfo(ossimAppFixedCacheId appId,
+//                                  const ossimIpt& origin)
+//          :theAppCacheId(appId),
+//           theOrigin(origin)
+//          {}
+//       ossimAppFixedCacheId  theAppCacheId;
+//       ossimIpt       theOrigin;
+      
+//       bool operator ==(const ossimAppFixedCacheTileInfo &rhs)const
+//          {
+//             return (theAppCacheId == rhs.theAppCacheId &&
+//                     theOrigin     == rhs.theOrigin);
+//          } 
+//    };
+   
+   ossimAppFixedTileCache();
+   
+   ossimFixedTileCache* getCache(ossimAppFixedCacheId cacheId);
+
+   void shrinkGlobalCacheSize(ossim_int32 byteCount);
+   void shrinkCacheSize(ossimAppFixedCacheId id,
+                        ossim_int32 byteCount);
+   void shrinkCacheSize(ossimFixedTileCache* cache,
+                        ossim_int32 byteCount);
+   void deleteAll();
+   
+   static ossimAppFixedTileCache *theInstance;
+   
+   /*!
+    * Will hold the current unique Application id.
+    */
+   static ossimAppFixedCacheId    theUniqueAppIdCounter;
+   ossimIpt                       theTileSize;
+   ossim_uint32                   theMaxCacheSize;
+   ossim_uint32                   theMaxGlobalCacheSize;
+   ossim_uint32                   theCurrentCacheSize;
+
+   std::map<ossimAppFixedCacheId, ossimFixedTileCache*> theAppCacheMap;
+
+   /*!
+    * Is used in an Least recently used algorithm
+    */
+//   std::list<ossimAppFixedCacheTileInfo>      theUsedQueue;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppTileCache.cpp b/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppTileCache.cpp
new file mode 100644
index 0000000000..295e0f99d9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppTileCache.cpp
@@ -0,0 +1,307 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+// Description: This file contains the Application cache algorithm
+//
+//***********************************
+// $Id: ossimAppTileCache.cpp,v 1.11 2005/03/03 21:59:16 dburken Exp $
+
+#include <imaging/cache/ossimAppTileCache.h>
+#include <imaging/cache/ossimTileCache.h>
+#include <base/common/ossimDataObject.h>
+#include <base/common/ossimPreferences.h>
+
+ossimAppTileCache* ossimAppTileCache::theInstance = NULL;
+
+// we will need to grab this from the preferences
+const ossim_uint32 ossimAppTileCache::DEFAULT_SIZE          = 80*1024*1024;
+const ossim_uint32 ossimAppTileCache::DEFAULT_BUCKET_SIZE          = 293;
+ossimAppTileCache::ossimAppCacheId ossimAppTileCache::theUniqueAppIdCounter = 1;
+
+ossimAppTileCache *ossimAppTileCache::instance(ossim_uint32  maxSize)
+{
+   cout << "HERE---------------------MAXSIZE = " << maxSize << std::endl;
+   if(!theInstance)
+   {
+      if(maxSize < 1)
+      {
+         ossimString cacheSize = ossimPreferences::instance()->findPreference("cache_size");
+         if(cacheSize!="")
+         {
+            maxSize = cacheSize.toUInt32()*1024*1024;
+         }
+         else
+         {
+            maxSize = DEFAULT_SIZE;
+         }
+         cout << "Setting SIZE----------------------- " << maxSize << std::endl;
+      }
+      theInstance = new ossimAppTileCache(maxSize);
+   }
+
+   return theInstance;
+}
+
+ossimAppTileCache::~ossimAppTileCache()
+{
+   deleteAll();
+}
+
+ossimAppTileCache::ossimAppCacheId ossimAppTileCache::newTileCache(ossim_uint32 bucketSize)
+{
+   ossimTileCache *aCache = NULL;
+   ossimAppCacheId result = 0;
+
+   aCache = new ossimTileCache(bucketSize);
+
+   if(aCache)
+   {
+      theAppCache.insert(make_pair(theUniqueAppIdCounter, aCache));
+      result = theUniqueAppIdCounter;
+      ++theUniqueAppIdCounter;
+   }
+
+   return result;
+}
+
+/*!
+ * Will retrieve a tile from the cache.
+ */
+ossimDataObject *ossimAppTileCache::get(ossimAppCacheId id,
+                                        const ossimDpt3d &origin,
+                                        ossim_uint32 resLevel)
+{
+   ossimDataObject* result = NULL;
+   if(id>0)
+   {
+      ossimTileCache *aCache = this->get(id);
+      if(aCache)
+      {
+         result = aCache->get(origin,
+                              resLevel);
+         if(result)
+         {
+            adjustQueue(id, origin, resLevel);
+         }
+      }
+   }
+
+   return result;
+}
+
+ossimDataObject* ossimAppTileCache::removeTile(ossimAppCacheId id,
+                                              const ossimDpt3d &origin,
+                                              unsigned long resLevel)
+{
+   ossimDataObject *result = NULL;
+   if(id>0)
+   {
+      ossimTileCache *aCache = this->get(id);
+      if(aCache)
+      {
+         // remove from cache
+         result = aCache->remove(origin,
+                                 resLevel);
+         // adjust the byte count
+         if(result)
+         {
+            theCurrentCacheSize -= result->getDataSizeInBytes();
+         }
+         removeTileFromQueue(id, origin, resLevel);
+      }
+   }
+
+   return result;
+}
+
+ossimDataObject* ossimAppTileCache::insert(ossimAppCacheId appId,
+                                          const ossimDpt3d &origin,
+                                          const ossimDataObject* data,
+                                          ossim_uint32 resLevel)
+{
+   static char *MODULE = "ossimAppTileCache::insert";
+   ossimDataObject *result = NULL;
+
+   // find the cache and if it's not there then return NULL
+   ossimTileCache *aCache = this->get(appId);
+   if(!aCache)
+   {         
+      return result;
+   }
+   
+   ossimDataObject *tileToInsert = NULL;
+   long dataSize = data->getDataSizeInBytes();
+   
+   if( (theCurrentCacheSize+dataSize) > theMaxCacheSize)
+   {
+      ossimDataObject *tempTile     = NULL;
+      do
+      {
+         tempTile = removeTile();
+
+         if(tempTile)
+         {
+            delete tempTile;
+            tempTile = NULL;
+         }
+      }while((theCurrentCacheSize+dataSize) > theMaxCacheSize);
+   }
+
+   if(data)
+   {
+      tileToInsert = (ossimDataObject*)data->dup();
+
+      result = aCache->insert(origin,
+                              tileToInsert,
+                              resLevel);
+      if(!result)
+      {
+         cout << MODULE << " ERROR: can't insert and should not happen"
+              << endl;
+
+         delete tileToInsert;
+      }
+      else
+      {
+         theCurrentCacheSize += dataSize;
+         theUsedQueue.push_back(ossimAppCacheTileInfo(appId,
+                                                 origin,
+                                                 resLevel));
+      }
+   }
+
+   return result;
+}
+
+
+ossimTileCache* ossimAppTileCache::get(ossimAppCacheId id)
+{
+   ossimTileCache *result=NULL;
+   
+   AppIdIterator anIterator = theAppCache.find(id);
+   
+   if(anIterator != theAppCache.end())
+   {
+      result = (*anIterator).second;
+   }
+
+   return result;
+}
+
+void ossimAppTileCache::deleteCache(ossimAppCacheId appId)
+{
+   // first delete the cache
+   AppIdIterator anIterator = theAppCache.find(appId);
+   if(anIterator != theAppCache.end())
+   {
+      ossimTileCache *aCache = (*anIterator).second;
+      theCurrentCacheSize -= aCache->sizeInBytes();
+
+      delete aCache;
+
+      theAppCache.erase(anIterator);      
+   }
+   // now delete all occurences of the appCacheId in the queue
+   // used for LRU algorithm.
+   deleteAppCacheFromQueue(appId);
+}
+
+void ossimAppTileCache::deleteAll()
+{
+   AppIdIterator iter = theAppCache.begin();
+
+   while(iter != theAppCache.end())
+   {
+      delete (*iter).second;
+      ++iter;
+   }
+   
+   theAppCache.clear();
+}
+
+void ossimAppTileCache::removeTileFromQueue(ossimAppCacheId appId,
+                                       const ossimDpt3d &origin,
+                                       ossim_uint32 resLevel)
+{
+   list<ossimAppCacheTileInfo>::iterator anIterator;
+
+   anIterator = theUsedQueue.begin();
+   while(anIterator != theUsedQueue.end())
+   {
+      if( ((*anIterator).theAppCacheId == appId) &&
+          ((*anIterator).theOrigin     == origin)&&
+          ((*anIterator).theResLevel   == resLevel))
+      {
+         theUsedQueue.erase(anIterator);
+         return;
+      }
+      else
+      {
+         ++anIterator;
+      }
+   }
+}
+
+void ossimAppTileCache::deleteAppCacheFromQueue(ossimAppCacheId appId)
+{
+   list<ossimAppCacheTileInfo>::iterator anIterator;
+
+   anIterator = theUsedQueue.begin();
+   while(anIterator != theUsedQueue.end())
+   {
+      if( (*anIterator).theAppCacheId == appId)
+      {
+         anIterator = theUsedQueue.erase(anIterator);
+      }
+      else
+      {
+         ++anIterator;
+      }
+   }
+}
+
+ossimDataObject* ossimAppTileCache::removeTile()
+{
+   ossimDataObject *result = NULL;
+   if(!theUsedQueue.empty())
+   {
+      ossimAppCacheTileInfo &info = *(theUsedQueue.begin());
+
+      ossimTileCache *aCache = get(info.theAppCacheId);
+      if(aCache)
+      {
+         result            = aCache->remove(info.theOrigin,
+                                            info.theResLevel);
+         theCurrentCacheSize -= result->getDataSizeInBytes();
+      }
+      theUsedQueue.erase(theUsedQueue.begin());
+   }
+
+   return result;
+}
+
+void ossimAppTileCache::adjustQueue(ossimAppCacheId id,
+                                    const ossimDpt3d &origin,
+                                    ossim_uint32 resLevel)
+{
+   list<ossimAppCacheTileInfo>::iterator anIterator = theUsedQueue.begin();
+   ossimAppCacheTileInfo info(id, origin, resLevel);
+   
+   while(anIterator != theUsedQueue.end())
+   {
+     
+      if((*anIterator) == info)
+      {
+         theUsedQueue.erase(anIterator);
+         theUsedQueue.push_back(info);
+         return;
+      }
+      ++anIterator;
+   }              
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppTileCache.h b/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppTileCache.h
new file mode 100644
index 0000000000..fa88b5c883
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/cache/ossimAppTileCache.h
@@ -0,0 +1,169 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+// Description: This file contains the Application cache algorithm
+//
+//***********************************
+// $Id: ossimAppTileCache.h,v 1.7 2005/03/03 21:59:16 dburken Exp $
+#ifndef ossimAppTileCache_HEADER
+#define ossimAppTileCache_HEADER
+#include <map>
+#include <list>
+using namespace std;
+
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimDpt3d.h>
+// class ossimTile;
+class ossimTileCache;
+class ossimDataObject;
+
+class ossimAppTileCache
+{
+public:
+   static const ossim_uint32 DEFAULT_SIZE;
+
+   static const ossim_uint32 DEFAULT_BUCKET_SIZE;
+
+   typedef ossim_int32 ossimAppCacheId;
+   typedef ossim_int32 ossimTileId;
+   typedef map<ossimAppCacheId, ossimTileCache*>::iterator AppIdIterator;
+
+   ~ossimAppTileCache();
+
+   /*!
+    *  We will force a singleton on this class.
+    */
+   static ossimAppTileCache *instance(ossim_uint32  maxSize   = 0);
+
+   /*!
+    * Will create a new Tile cache for this application.  Will
+    * return 0 if not successful.
+    */
+   ossimAppCacheId newTileCache(ossim_uint32 bucketSize=DEFAULT_BUCKET_SIZE);
+
+   /*!
+    * Will retrieve a tile from the cache.  Will return NULL
+    * if not found.
+    */
+   ossimDataObject *get(ossimAppCacheId id,
+                        const ossimDpt3d &origin,
+                        ossim_uint32 resLevel=0);
+
+   /*!
+    * Will remove a tile completly from the cache.  The
+    * returned tile is no longer owned by the cache.
+    */
+   ossimDataObject* removeTile(ossimAppCacheId id,
+                              const ossimDpt3d &origin,
+                              unsigned long resLevel);
+   /*!
+    * Will insert a tile into the cache.
+    */
+   ossimDataObject* insert(ossimAppCacheId id,
+                          const ossimDpt3d &origin,
+                          const ossimDataObject* data,
+                          ossim_uint32 resLevel=0);
+   
+   /*!
+    * This will delete the specified cache. The LRU queue will
+    * be updated accordingly
+    */
+   void deleteCache(ossimAppCacheId appId);
+protected:
+
+   struct ossimAppCacheTileInfo
+   {
+   public:
+      ossimAppCacheTileInfo(ossimAppCacheId appId,
+                       const ossimDpt3d& origin,
+                       ossim_uint32    resLevel)
+         :theAppCacheId(appId),
+          theOrigin(origin),
+          theResLevel(resLevel)
+         {}
+      ossimAppCacheId  theAppCacheId;
+      ossimDpt3d         theOrigin;
+      ossim_uint32     theResLevel;
+
+      bool operator ==(const ossimAppCacheTileInfo &rhs)
+         {
+            return (theAppCacheId == rhs.theAppCacheId &&
+                    theOrigin     == rhs.theOrigin &&
+                    theResLevel   == rhs.theResLevel);
+         } 
+  
+   };
+
+   ossimAppTileCache(ossim_uint32  maxSize   = DEFAULT_SIZE)
+      :
+         theMaxCacheSize(maxSize),
+         theCurrentCacheSize(0)
+      {}
+
+   void deleteAll();
+   /*!
+    * Used to get access to the App cache.
+    */
+  ossimTileCache* get(ossimAppCacheId id);
+
+   /*!
+    * will remove all occurances of the appId from the
+    * queue
+    */
+   void deleteAppCacheFromQueue(ossimAppCacheId appId);
+
+   /*!
+    * Will remove a single instance of a tile from the queue.
+    */
+   void removeTileFromQueue(ossimAppCacheId appId,
+                            const ossimDpt3d &origin,
+                            ossim_uint32 resLevel);
+
+   void adjustQueue(ossimAppCacheId id,
+                    const ossimDpt3d &origin,
+                    ossim_uint32 resLevel);
+   /*!
+    * will pop the queue and remove that tile from its cache
+    * and return it to the caller. This is used by the insert
+    * when the max cache size is exceeded.
+    */
+   ossimDataObject* removeTile();
+
+
+   static ossimAppTileCache *theInstance;
+   /*!
+    * Will hold the current unique Application id.
+    */
+   static ossimAppCacheId                   theUniqueAppIdCounter;
+   /*!
+    * Will hold the list of application caches
+    */
+   map<ossimAppCacheId, ossimTileCache*>  theAppCache;
+
+   /*!
+    * Is the maximum size of the cache.
+    */
+   ossim_uint32                      theMaxGlobalCacheSize;
+   ossim_uint32                      theMaxCacheSize;
+   
+
+   /*!
+    * This holds the current cache size.
+    */
+   ossim_uint32                      theCurrentCacheSize;
+   
+
+   /*!
+    * Is used in an Least recently used algorithm
+    */
+   list<ossimAppCacheTileInfo>      theUsedQueue;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/cache/ossimFixedTileCache.cpp b/Utilities/OSSIM/ossim_core/imaging/cache/ossimFixedTileCache.cpp
new file mode 100644
index 0000000000..3c3a94a5b5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/cache/ossimFixedTileCache.cpp
@@ -0,0 +1,282 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: This file contains the Application cache algorithm
+//
+//***********************************
+// $Id: ossimFixedTileCache.cpp,v 1.18 2005/08/17 19:18:12 gpotts Exp $
+#include <imaging/cache/ossimFixedTileCache.h>
+#include <algorithm>
+
+ossimFixedTileCache::ossimFixedTileCache()
+{
+   ossimIrect tempRect;
+   tempRect.makeNan();
+
+   setRect(tempRect);
+   theCacheSize    = 0;
+   theMaxCacheSize = 0;
+   theUseLruFlag = true;
+}
+
+ossimFixedTileCache::~ossimFixedTileCache()
+{
+   flush();
+}
+
+void ossimFixedTileCache::setRect(const ossimIrect& rect)
+{
+   ossimGetDefaultTileSize(theTileSize);
+   theTileBoundaryRect      = rect;
+   theTileBoundaryRect.stretchToTileBoundary(theTileSize);
+   theBoundaryWidthHeight.x = theTileBoundaryRect.width();
+   theBoundaryWidthHeight.y = theTileBoundaryRect.height();
+   theTilesHorizontal       = theBoundaryWidthHeight.x/theTileSize.x;
+   theTilesVertical         = theBoundaryWidthHeight.y/theTileSize.y;
+   flush();
+}
+
+void ossimFixedTileCache::setRect(const ossimIrect& rect,
+                                  const ossimIpt& tileSize)
+{
+   theTileBoundaryRect      = rect;
+   theTileSize              = tileSize;
+   theTileBoundaryRect.stretchToTileBoundary(theTileSize);
+   theBoundaryWidthHeight.x = theTileBoundaryRect.width();
+   theBoundaryWidthHeight.y = theTileBoundaryRect.height();
+   theTilesHorizontal       = theBoundaryWidthHeight.x/theTileSize.x;
+   theTilesVertical         = theBoundaryWidthHeight.y/theTileSize.y;
+   flush();
+}
+
+
+void ossimFixedTileCache::keepTilesWithinRect(const ossimIrect& rect)
+{
+   std::map<ossim_int32, ossimFixedTileCacheInfo>::iterator tileIter = theTileMap.begin();
+
+   while(tileIter != theTileMap.end())
+   {
+      ossimIrect tileRect = (*tileIter).second.theTile->getImageRectangle();
+      if(!tileRect.intersects(rect))
+      {
+         eraseFromLru(computeId((*tileIter).second.theTile->getOrigin()));
+         theCacheSize -= (*tileIter).second.theTile->getDataSizeInBytes();
+         (*tileIter).second.theTile = NULL;
+         theTileMap.erase(tileIter);
+      }
+      ++tileIter;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimFixedTileCache::addTile(
+   ossimRefPtr<ossimImageData> imageData)
+{
+   ossimRefPtr<ossimImageData> result = NULL;
+   if(!imageData.valid())
+   {
+      return result;
+   }
+   if(!imageData->getBuf())
+   {
+      return result;
+   }
+   
+   ossim_int32 id = computeId(imageData->getOrigin());
+   if(id < 0)
+   {
+      return result;
+   }
+   
+   std::map<ossim_int32, ossimFixedTileCacheInfo>::iterator tileIter =
+      theTileMap.find(id);
+
+   if(tileIter==theTileMap.end())
+   {
+      result = (ossimImageData*)imageData->dup();
+      ossimFixedTileCacheInfo cacheInfo(result, id);
+       
+      theCacheSize += imageData->getDataSizeInBytes();
+      theTileMap.insert(make_pair(id, cacheInfo));
+      if(theUseLruFlag)
+      {
+         theLruQueue.push_back(id);
+      }
+   }
+   
+   return result;
+}
+
+ossimRefPtr<ossimImageData> ossimFixedTileCache::getTile(ossim_int32 id)
+{
+   ossimRefPtr<ossimImageData> result = NULL;
+
+   std::map<ossim_int32, ossimFixedTileCacheInfo>::iterator tileIter =
+      theTileMap.find(id);
+   if(tileIter!=theTileMap.end())
+   {
+      result = (*tileIter).second.theTile;
+      adjustLru(id);
+   }
+
+   return result;
+}
+
+ossimIpt ossimFixedTileCache::getTileOrigin(ossim_int32 tileId)
+{
+   ossimIpt result;
+   result.makeNan();
+
+   if(tileId < 0)
+   {
+      return result;
+   }
+   ossim_int32 ty = (tileId/theTilesHorizontal);
+   ossim_int32 tx = (tileId%theTilesVertical);
+   
+   ossimIpt ul = theTileBoundaryRect.ul();
+   
+   result = ossimIpt(ul.x + tx*theTileSize.x, ul.y + ty*theTileSize.y);
+
+   return result;
+}
+
+ossim_int32 ossimFixedTileCache::computeId(const ossimIpt& tileOrigin)const
+{
+   ossimIpt idDiff = tileOrigin - theTileBoundaryRect.ul();
+
+   if((idDiff.x < 0)||
+      (idDiff.y < 0)||
+      (idDiff.x >= theBoundaryWidthHeight.x)||
+      (idDiff.y >= theBoundaryWidthHeight.y))
+     {
+       return -1;
+     }
+   ossim_uint32 y = idDiff.y/theTileSize.y;
+   y*=theTilesHorizontal;
+
+   ossim_uint32 x = idDiff.x/theTileSize.x;
+   
+   
+   return (y + x);
+}
+
+void ossimFixedTileCache::deleteTile(ossim_int32 tileId)
+{
+   std::map<ossim_int32, ossimFixedTileCacheInfo>::iterator tileIter =
+      theTileMap.find(tileId);
+
+   if(tileIter != theTileMap.end())
+   {
+      if((*tileIter).second.theTile.valid())
+      {
+         theCacheSize -= (*tileIter).second.theTile->getDataSizeInBytes();
+         (*tileIter).second.theTile = NULL;
+      }
+      theTileMap.erase(tileIter);
+      eraseFromLru(tileId);
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimFixedTileCache::removeTile(ossim_int32 tileId)
+{
+   ossimRefPtr<ossimImageData> result = NULL;
+   
+   std::map<ossim_int32, ossimFixedTileCacheInfo>::iterator tileIter =
+      theTileMap.find(tileId);
+
+   if(tileIter != theTileMap.end())
+   {
+      theCacheSize -= (*tileIter).second.theTile->getDataSizeInBytes();
+      if((*tileIter).second.theTile.valid())
+      {
+         result =  (*tileIter).second.theTile;
+      }
+      theTileMap.erase(tileIter);
+      eraseFromLru(tileId);
+   }
+   
+   return result;
+}
+
+void ossimFixedTileCache::flush()
+{
+   std::map<ossim_int32, ossimFixedTileCacheInfo>::iterator tileIter =
+      theTileMap.begin();
+
+   while(tileIter != theTileMap.end())
+   {
+      if( (*tileIter).second.theTile.valid())
+      {
+         (*tileIter).second.theTile = NULL;
+      }
+      ++tileIter;
+   }
+   theLruQueue.clear();
+   theTileMap.clear();
+   theCacheSize = 0;
+}
+
+void ossimFixedTileCache::deleteTile()
+{
+   if(theUseLruFlag)
+   {
+      if(theLruQueue.begin() != theLruQueue.end())
+      {
+         deleteTile(*(theLruQueue.begin()));
+      }
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimFixedTileCache::removeTile()
+{
+   if(theUseLruFlag)
+   {
+      if(theLruQueue.begin() != theLruQueue.end())
+      {
+         return removeTile(*(theLruQueue.begin()));
+      }
+   }
+
+   return NULL;
+}
+
+void ossimFixedTileCache::adjustLru(ossim_int32 id)
+{
+   if(theUseLruFlag)
+   {
+      std::list<ossim_int32>::iterator iter = std::find(theLruQueue.begin(), theLruQueue.end(), id);
+      
+      if(iter != theLruQueue.end())
+      {
+         ossim_int32 value = *iter;
+         theLruQueue.erase(iter);
+         theLruQueue.push_back(value);
+      }
+   }
+}
+
+void ossimFixedTileCache::eraseFromLru(ossim_int32 id)
+{
+   if(theUseLruFlag)
+   {
+      
+      std::list<ossim_int32>::iterator iter = std::find(theLruQueue.begin(), theLruQueue.end(), id);
+      
+      if(iter != theLruQueue.end())
+      {
+         theLruQueue.erase(iter);
+      }
+   }
+}
+
+
+void ossimFixedTileCache::setTileSize(const ossimIpt& tileSize)
+{
+   setRect(theTileBoundaryRect, tileSize);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/cache/ossimFixedTileCache.h b/Utilities/OSSIM/ossim_core/imaging/cache/ossimFixedTileCache.h
new file mode 100644
index 0000000000..dd6bf59dfe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/cache/ossimFixedTileCache.h
@@ -0,0 +1,143 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: This file contains the Application cache algorithm
+//
+//***********************************
+// $Id: ossimFixedTileCache.h,v 1.11 2005/08/17 19:18:12 gpotts Exp $
+#ifndef ossimFixedTileCache_HEADER
+#define ossimFixedTileCache_HEADER
+#include <map>
+#include <list>
+#include <base/data_types/ossimIpt.h>
+#include <base/common/ossimReferenced.h>
+#include <base/common/ossimRefPtr.h>
+#include <imaging/ossimImageData.h>
+
+class  ossimFixedTileCacheInfo
+{
+public:
+   ossimFixedTileCacheInfo(ossimRefPtr<ossimImageData>& tile,
+                           ossim_int32 tileId=-1)
+      :theTile(tile),
+      theTileId(tileId)
+      {
+      }
+   
+   bool operator <(const ossimFixedTileCacheInfo& rhs)const
+      {
+         return (theTileId < rhs.theTileId);
+      }
+   bool operator <(ossim_int32 tileId)const
+      {
+         return (theTileId < tileId);
+      }
+   bool operator >(const ossimFixedTileCacheInfo& rhs)const
+      {
+         return (theTileId > rhs.theTileId);
+      }
+   bool operator >(ossim_int32 tileId)const
+      {
+         return (theTileId > tileId);
+      }
+   bool operator ==(const ossimFixedTileCacheInfo& rhs)const
+      {
+         return (theTileId == rhs.theTileId);
+      }
+   bool operator ==(ossim_int32 tileId)const
+      {
+         return (theTileId == tileId);
+      }
+   
+   ossimRefPtr<ossimImageData> theTile;
+   ossim_int32 theTileId;
+};
+
+class ossimFixedTileCache : public ossimReferenced
+{
+public:
+   ossimFixedTileCache();
+   virtual ~ossimFixedTileCache();
+   virtual void setRect(const ossimIrect& rect);
+   virtual void setRect(const ossimIrect& rect,
+                        const ossimIpt& tileSize);
+   void ossimFixedTileCache::keepTilesWithinRect(const ossimIrect& rect);
+   virtual ossimRefPtr<ossimImageData> addTile(ossimRefPtr<ossimImageData> imageData);
+   virtual ossimRefPtr<ossimImageData> getTile(ossim_int32 id);
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIpt& origin)
+      {
+         return getTile(computeId(origin));
+      }
+   virtual void setUseLruFlag(bool flag)
+      {
+         theUseLruFlag = flag;
+      }
+   virtual bool getUseLruFlag()const
+      {
+         return theUseLruFlag;
+      }
+   virtual void flush();
+   virtual void deleteTile(const ossimIpt& origin)
+      {
+         deleteTile(computeId(origin));
+      }
+   virtual void deleteTile(ossim_int32 tileId);
+   virtual ossimRefPtr<ossimImageData> removeTile(const ossimIpt& origin)
+      {
+         return removeTile(computeId(origin));
+      }
+   virtual ossimRefPtr<ossimImageData> removeTile(ossim_int32 tileId);
+   virtual const ossimIrect& getTileBoundaryRect()const
+      {
+         return theTileBoundaryRect;
+      }
+   virtual ossim_uint32 getNumberOfTiles()const
+      {
+         return (ossim_uint32)theTileMap.size();
+      }
+   virtual const ossimIpt& getTileSize()const
+      {
+         return theTileSize;
+      }
+   virtual ossim_uint32 getCacheSize()const
+      {
+         return theCacheSize;
+      }
+   virtual void deleteTile();
+   virtual ossimRefPtr<ossimImageData> removeTile();
+   
+   virtual void setMaxCacheSie(ossim_uint32 cacheSize)
+      {
+         theMaxCacheSize = cacheSize;
+      }
+
+   ossim_uint32 getMaxCacheSize()const
+      {
+         return theMaxCacheSize;
+      }
+   
+   virtual ossimIpt getTileOrigin(ossim_int32 tileId);
+   virtual ossim_int32 computeId(const ossimIpt& tileOrigin)const;
+   virtual void setTileSize(const ossimIpt& tileSize);
+protected:
+   ossimIrect   theTileBoundaryRect;
+   ossimIpt     theTileSize;
+   ossimIpt     theBoundaryWidthHeight;
+   ossim_uint32 theTilesHorizontal;
+   ossim_uint32 theTilesVertical;
+   ossim_uint32 theCacheSize;
+   ossim_uint32 theMaxCacheSize;
+   std::map<ossim_int32, ossimFixedTileCacheInfo> theTileMap;
+   std::list<ossim_int32> theLruQueue;
+   bool                   theUseLruFlag;
+   virtual void eraseFromLru(ossim_int32 id);
+   void adjustLru(ossim_int32 id);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/cache/ossimTileCache.cpp b/Utilities/OSSIM/ossim_core/imaging/cache/ossimTileCache.cpp
new file mode 100644
index 0000000000..18ee8e783c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/cache/ossimTileCache.cpp
@@ -0,0 +1,189 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This file contains the cache algorithm
+//
+//***********************************
+// $Id: ossimTileCache.cpp,v 1.7 2003/06/15 19:00:41 dburken Exp $
+
+#include "ossimTileCache.h"
+#include "base/common/ossimDataObject.h"
+
+void ossimTileCache::display()const
+{
+   ossimTileCache::Iterator tiles;
+
+   for(long buckets = 0; buckets < theNumberOfBuckets; buckets++)
+   {
+      tiles = theCache[buckets].begin();
+      while(tiles != theCache[buckets].end())
+      {
+         cout << ((*tiles).second) << endl;
+         ++tiles;
+      }
+   }
+}
+
+ossimTileCache::ossimTileCache(long numberOfBuckets)
+   : theCache(NULL),
+     theNumberOfBuckets(numberOfBuckets>0?numberOfBuckets:255),
+     theSizeInBytes(0)
+{
+   theCache = new multimap<ossim_uint32, ossimTileInformation*>[theNumberOfBuckets];
+}
+
+ossimTileCache::~ossimTileCache()
+{
+   deleteAll();
+}
+
+ossimDataObject* ossimTileCache::get(const ossimDpt3d &origin,
+                                    unsigned long resLevel)
+{
+   ossimDataObject* result = NULL;
+   Iterator anIterator;
+
+   ossim_uint32 bucket = bucketHash(origin);
+   
+   anIterator = theCache[bucket].find(tileId(origin));
+   while(anIterator != theCache[bucket].end())
+   {
+      CacheDataPtr info = (*anIterator).second;
+      if(info)
+      {
+         if(info->theOrigin   == origin &&
+            info->theResLevel == resLevel)
+         {
+            return info->theCachedTile;
+         }
+      }
+
+      ++anIterator;
+   }
+   return result;
+}
+
+ossimDataObject* ossimTileCache::remove(const ossimDpt3d &origin,
+                                  unsigned long resLevel)
+{
+   Iterator anIterator;
+   ossimDataObject *result;
+   ossim_uint32 bucket = bucketHash(origin);
+   
+   anIterator = theCache[bucket].find(tileId(origin));
+   while(anIterator != theCache[bucket].end())
+   {
+      CacheDataPtr info = (*anIterator).second;
+      if(info)
+      {
+         if(info->theOrigin   == origin &&
+            info->theResLevel == resLevel)
+         {
+            theCache[bucket].erase(anIterator);
+            theSizeInBytes -= info->theCachedTile->getDataSizeInBytes();
+
+            result = info->theCachedTile;
+
+            delete info;
+            return result;
+         }
+      }
+
+      ++anIterator;
+   }
+   
+   return NULL;   
+}
+
+ossimDataObject* ossimTileCache::insert(const ossimDpt3d &origin,
+                                       ossimDataObject* data,
+                                       unsigned long resLevel)
+{   
+   ossim_uint32 bucket = bucketHash(origin);
+
+   // make sure we keep up with the current size of the
+   // cache in bytes.  This is only the count of the data
+   // and not any overhead required by the cache.
+   theSizeInBytes += data->getDataSizeInBytes();
+   theCache[bucket].insert(make_pair(tileId(origin),
+                                     new CacheData(data,
+                                                   origin,
+                                                   resLevel)));
+   
+   return data;
+}
+
+void ossimTileCache::invalidate()
+{
+   
+}
+
+void ossimTileCache::invalidate(const ossimDpt3d &origin,
+                                ossim_uint32 resLevel)
+{
+}
+
+
+
+ossim_uint32 ossimTileCache::tileId(const ossimDpt3d &aPt)
+{
+   const unsigned char *bufx = (unsigned char*)(&aPt.x);
+   const unsigned char *bufy = (unsigned char*)(&aPt.y);
+   const unsigned char *bufz = (unsigned char*)(&aPt.z);
+
+   // this just multiplies each byte by some prime number
+   // and add together.
+   return (ossim_uint32)(bufx[0]*101 + bufx[1]*103 +
+                    bufx[2]*107 + bufx[3]*109 +
+                    bufx[4]*113 + bufx[5]*127 +
+                    bufx[6]*131 + bufx[7]*137 +
+                    bufy[0]*139 + bufy[1]*149 +
+                    bufy[2]*151 + bufy[3]*157 +
+                    bufy[4]*163 + bufy[5]*167 +
+                    bufy[6]*173 + bufy[7]*179 +
+                    bufz[0]*181 + bufz[1]*191 +
+                    bufz[2]*193 + bufz[3]*197 +
+                    bufz[4]*199 + bufz[5]*211 +
+                    bufz[6]*223 + bufz[6]*227);       
+}
+
+ossim_uint32 ossimTileCache::bucketHash(const ossimDpt3d &aPt)
+{   
+   return tileId(aPt)%theNumberOfBuckets;
+}
+
+void ossimTileCache::deleteAll()
+{
+   Iterator anIterator;
+
+   for(long bucket = 0; bucket < theNumberOfBuckets; bucket++)
+   {
+      anIterator = theCache[bucket].begin();
+      while(anIterator != theCache[bucket].end())
+      {
+         CacheDataPtr info = (*anIterator).second;
+         delete info->theCachedTile;
+         delete info;
+         
+         ++anIterator;
+      }
+      theCache[bucket].clear();
+   }
+   delete [] theCache;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/cache/ossimTileCache.h b/Utilities/OSSIM/ossim_core/imaging/cache/ossimTileCache.h
new file mode 100644
index 0000000000..fc4b73f5bd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/cache/ossimTileCache.h
@@ -0,0 +1,114 @@
+//******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This file contains the cache algorithm
+//
+//***********************************
+// $Id: ossimTileCache.h,v 1.5 2003/05/15 14:34:16 dburken Exp $
+
+#ifndef DataCache_HEADER
+#define DataCache_HEADER
+#include <map>
+#include <stack>
+using namespace std;
+
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimDpt3d.h" 
+class ossimDataObject;
+class ossimTileCache
+{
+public:
+   
+   ossimTileCache(long numberOfBuckets  = 10);
+   virtual ~ossimTileCache();
+
+   /*!
+    * This will return a tile if found.  Note this tile is still
+    * owned by the cache.
+    */
+   virtual ossimDataObject* get(const ossimDpt3d &origin,
+                               unsigned long resLevel=0);
+
+   /*!
+    * Will remove the tile from the cache and will not delete.  Note:
+    * the cache no longer owns the tile.
+    */
+   virtual ossimDataObject* remove(const ossimDpt3d &origin,
+                                  unsigned long resLevel=0);
+   /*!
+    * This will not duplicate the tile.  Note the tile is owned
+    * by the cache.
+    */
+   virtual ossimDataObject* insert(const ossimDpt3d &origin,
+                                  ossimDataObject* data,
+                                  unsigned long resLevel=0);
+   /*!
+    * Not implemented
+    */
+   void invalidate();
+   /*!
+    * Not implemented
+    */
+   virtual void invalidate(const ossimDpt3d &origin,
+                           ossim_uint32 resLevel);
+
+
+   
+   virtual long numberOfItems()const{return theCache?theCache->size():0;}
+   virtual void display()const;
+
+   virtual ossim_uint32 sizeInBytes(){return theSizeInBytes;}
+   
+protected:
+
+   struct ossimTileInformation
+   {
+   public:
+      friend ostream& operator <<(ostream &out,
+                                  const ossimTileInformation &info)
+         {
+
+            return out;
+         }
+      ossimTileInformation(ossimDataObject* aTile,
+                      const ossimDpt3d &origin = ossimDpt(0,0),
+                      unsigned long resLevel = 0)
+         : theCachedTile(aTile),
+           theOrigin(origin),
+           theResLevel(resLevel)
+         {}
+      ossimDataObject*    theCachedTile;
+      ossimDpt3d         theOrigin;
+      unsigned long      theResLevel;
+   };
+
+   typedef multimap<ossim_uint32, ossimTileInformation*>::iterator Iterator;
+   typedef ossimTileInformation* CacheDataPtr;
+   typedef ossimTileInformation  CacheData;
+   
+   void deleteAll();
+   virtual ossim_uint32 bucketHash(const ossimDpt3d &aPt);
+   virtual ossim_uint32 tileId(const ossimDpt3d &aPt);
+   
+   multimap<ossim_uint32, ossimTileInformation*>  *theCache;
+   long                                            theNumberOfBuckets;
+   ossim_uint32                                    theSizeInBytes;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/elevation/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/elevation/.cvsignore
new file mode 100644
index 0000000000..42d2532435
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/elevation/.cvsignore
@@ -0,0 +1,2 @@
+*.d
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/elevation/ossimElevImageSource.cpp b/Utilities/OSSIM/ossim_core/imaging/elevation/ossimElevImageSource.cpp
new file mode 100644
index 0000000000..6db439edab
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/elevation/ossimElevImageSource.cpp
@@ -0,0 +1,821 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:  Class provides an elevation image source from the elevation
+// manager.
+// 
+//*******************************************************************
+//  $Id: ossimElevImageSource.cpp,v 1.13 2005/02/11 15:07:30 dburken Exp $
+
+#include <time.h>
+
+#include "ossimElevImageSource.h"
+#include "elevation/ossimElevManager.h"
+#include "projections/map_projections/ossimLlxyProjection.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/common/ossimTrace.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+RTTI_DEF1(ossimElevImageSource, "ossimElevImageSource", ossimImageSource)
+
+// Static trace for debugging
+static ossimTrace traceDebug("ossimElevImage:debug");
+   
+ossimElevImageSource::ossimElevImageSource()
+   :
+      ossimImageSource(NULL,
+                       0,
+                       0,
+                       true,
+                       false),// output list is not fixed
+      theElevManager(NULL),
+      theTile(NULL),
+      theTiePoint(),
+      theLatSpacing(0.0),
+      theLonSpacing(0.0),
+      theNumberOfLines(0),
+      theNumberOfSamps(0)
+{}
+
+ossimElevImageSource::ossimElevImageSource(ossimObject* owner)
+   :
+      ossimImageSource(owner,
+                       0,
+                       0,
+                       true,
+                       false),// output list is not fixed
+      theElevManager(NULL),
+      theTile(NULL),
+      theTiePoint(),
+      theLatSpacing(0.0),
+      theLonSpacing(0.0),
+      theNumberOfLines(0),
+      theNumberOfSamps(0)
+{}
+
+ossimElevImageSource::ossimElevImageSource(ossimObject* owner,
+                                           const ossimGpt& tie,
+                                           double latSpacing,
+                                           double lonSpacing,
+                                           ossim_uint32 numberLines,
+                                           ossim_uint32 numberSamples)
+   :
+      ossimImageSource(owner,
+                       0,
+                       0,
+                       true,
+                       false),// output list is not fixed
+      theElevManager(NULL),
+      theTile(NULL),
+      theTiePoint(tie),
+      theLatSpacing(latSpacing),
+      theLonSpacing(lonSpacing),
+      theNumberOfLines(numberLines),
+      theNumberOfSamps(numberSamples)
+{
+   initialize();
+}
+
+ossimElevImageSource::ossimElevImageSource(ossimObject* owner,
+                                           const ossimKeywordlist& kwl,
+                                           const char* prefix)
+   :
+      ossimImageSource(owner,
+                       0,
+                       0,
+                       true,
+                       false),
+      theElevManager(NULL),
+      theTile(NULL),
+      theTiePoint(),
+      theLatSpacing(0),
+      theLonSpacing(0),
+      theNumberOfLines(0),
+      theNumberOfSamps(0)
+{
+   if (loadState(kwl, prefix) == false)
+   {
+      setErrorStatus();
+   }
+}
+
+ossimElevImageSource::~ossimElevImageSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimElevImageSource::getTile(
+   const  ossimIrect& tile_rect,
+   ossim_uint32 resLevel)
+{
+   if (!theTile.get())
+   {
+      return theTile;
+   }
+   
+   // First make sure our tile is the right size.
+   ossim_int32 w = tile_rect.width();
+   ossim_int32 h = tile_rect.height();
+   ossim_int32 tileW = theTile->getWidth();
+   ossim_int32 tileH = theTile->getHeight();
+   if( (w != tileW) || (h != tileH) )
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+
+         //***
+         // Initialize can reset the min max to defaults if the min happens
+         // to be "0" so reset it just in case.
+         // NOTE:  We need to fix initialize!
+         //***
+         theTile->setMinPix(theElevManager->getMinHeightAboveMSL(), 0);
+         theTile->setMaxPix(theElevManager->getMaxHeightAboveMSL(), 0);
+      }
+   }
+
+   // Set the origin.
+   theTile->setOrigin(tile_rect.ul());
+      
+   
+   if(!isSourceEnabled())
+   {
+      // This tile source bypassed.
+      theTile->makeBlank();
+      return theTile;
+   }
+
+   //***
+   // No overview support yet...
+   //***
+   if (resLevel)
+   {
+      // NOTE:  Need to add overview support.
+      cerr << "ossimElevImageSource::getTile ERROR:\nOverviews not supported!"
+           << endl;
+      theTile->makeBlank();
+      return theTile;
+   }
+
+   ossimIrect image_rect = getImageRectangle(0);
+
+   if ( !tile_rect.intersects(image_rect) )
+   {
+      // No point in the tile falls within the set boundaries of this source.
+      theTile->makeBlank();
+      return theTile;
+   }
+
+   // Ok fill the tile with the data from the post...
+   ossimIrect clip_rect = tile_rect.clipToRect(image_rect);
+
+   if ( !tile_rect.completely_within(clip_rect) )
+   {
+      // Start with a blank tile since it won't be filled all the way.
+      theTile->makeBlank();
+   }
+
+
+   // Move the buffer pointer to the first valid pixel.
+   ossim_uint32 tile_width = theTile->getWidth();
+   
+   ossim_int32 start_offset = (clip_rect.lr().y - tile_rect.ul().y) * tile_width +
+      clip_rect.ul().x - tile_rect.ul().x;
+
+   //***
+   // Since most elevation formats have posts organized positive line up,
+   // start at the lower left side of the cell so all reads are going
+   // forward in the file.
+   //***
+   double start_lat = theTiePoint.latd() - theLatSpacing *
+      (clip_rect.lr().y - image_rect.ul().y);
+   if (start_lat < -90.0)
+   {
+      start_lat = -(start_lat + 180.0);  // Wrapped around the south poll.
+   }
+
+   double lon = theTiePoint.lond() + theLonSpacing *
+      (clip_rect.ul().x  - image_rect.ul().x);
+   if (lon > 180.0)
+   {
+      lon -= 360.0; // Went across the central meridian.
+   }
+
+   // Copy the data.
+   ossim_uint32 clipHeight = clip_rect.height();
+   ossim_uint32 clipWidth  = clip_rect.width();
+
+   // Get a pointer to the tile buffer.
+   ossim_float32* buf = static_cast<ossim_float32*>(theTile->getBuf());
+
+   for (ossim_uint32 sample = 0; sample < clipWidth; ++sample)
+   {
+      double lat = start_lat;
+      ossim_int32 offset = start_offset;
+      for (ossim_uint32 line = 0; line < clipHeight; ++line)
+      {
+         ossimGpt gpt(lat, lon);
+         buf[offset+sample] = theElevManager->getHeightAboveMSL(gpt);
+         
+         lat += theLatSpacing;
+         if (lat > 90) lat = 180.0 - lat;
+
+         offset -= tile_width;
+      }
+      
+      lon += theLonSpacing;
+      if (lon > 180.0) lon = lon - 360.0; // Went across the central meridian.
+   }
+   
+#if 0   
+   for (ossim_uint32 line = 0; line < clipHeight; ++line)
+   {
+      double lon = start_lon;
+      for (ossim_uint32 sample = 0; sample < clipWidth; ++sample)
+      {
+         ossimGpt gpt(lat, lon);
+         buf[sample] = theElevManager->getHeightAboveMSL(gpt);
+         lon += theLonSpacing;
+         if (start_lon > 180.0)
+         {
+            start_lon -= 360.0; // Went across the central meridian.
+         }
+      }
+
+      buf += tile_width;
+      lat -= theLatSpacing;
+      if (lat < -90.0) lat = -(lat + 180.0);// Wrapped around the south poll.
+   }
+#endif
+   
+   theTile->validate();
+   return theTile;
+}
+
+bool ossimElevImageSource::saveState(ossimKeywordlist& kwl,
+                                  const char* prefix) const
+{
+   static const char MODULE[] = "ossimElevImageSource::saveState";
+
+   if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      cerr << MODULE
+           << " ERROR detected in keyword list!  State not saved."
+           << endl;
+      return false;
+   }
+
+   // Save the state of the base class.
+   ossimImageSource::saveState(kwl, prefix);
+
+   // Save the tie point.
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LAT_KW,
+           theTiePoint.latd(),
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LON_KW,
+           theTiePoint.lond(),
+           true);
+
+   // Save the post spacing.
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+           theLatSpacing,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+           theLonSpacing,
+           true);
+
+   // Save the image size
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_LINES_KW,
+           theNumberOfLines,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_SAMPLES_KW,
+           theNumberOfSamps,
+           true);
+
+   // Save the min / max pixel values.
+   kwl.add(prefix,
+           ossimKeywordNames::MIN_VALUE_KW,
+           getMinPixelValue(0),
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::MAX_VALUE_KW,
+           getMaxPixelValue(0),
+           true);
+
+   return true;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimElevImageSource::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   static const char MODULE[] = "ossimElevImageSource::loadState";
+
+   if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      cerr << MODULE
+           << " ERROR detected in keyword list!  State not load."
+           << endl;
+      return false;
+   }
+
+   // Base class...
+   ossimImageSource::loadState(kwl, prefix);
+   
+   const char* lookup;
+
+   // Get the tie point.
+   lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LAT_KW);
+   if (lookup)
+   {
+      theTiePoint.latd(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nRequired keyword not found:  "
+              << ossimKeywordNames::TIE_POINT_LAT_KW
+              << "\nReturning false"
+              << endl;
+      }
+
+      return false;
+   }
+   
+   lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LON_KW);
+   if (lookup)
+   {
+      theTiePoint.lond(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nRequired keyword not found:  "
+              << ossimKeywordNames::TIE_POINT_LON_KW
+              << "\nReturning false"
+              << endl;
+      }
+
+      return false;
+   }
+
+   // Get the post spacing.
+   lookup = kwl.find(prefix, ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT);
+   if (lookup)
+   {
+      theLatSpacing = ossimString(lookup).toDouble();
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nRequired keyword not found:  "
+              << ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT
+              << "\nReturning false"
+              << endl;
+      }
+
+      return false;
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON);
+   if (lookup)
+   {
+      theLonSpacing = ossimString(lookup).toDouble();
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nRequired keyword not found:  "
+              << ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON
+              << "\nReturning false"
+              << endl;
+      }
+
+      return false;
+   }
+
+   // Get the image size.
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_LINES_KW);
+   if (lookup)
+   {
+      theNumberOfLines = ossimString(lookup).toULong();
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nRequired keyword not found:  "
+              << ossimKeywordNames::NUMBER_LINES_KW
+              << "\nReturning false"
+              << endl;
+      }
+
+      return false;
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_SAMPLES_KW);
+   if (lookup)
+   {
+      theNumberOfSamps = ossimString(lookup).toULong();
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nRequired keyword not found:  "
+              << ossimKeywordNames::NUMBER_SAMPLES_KW
+              << "\nReturning false"
+              << endl;
+      }
+
+      return false;
+   }
+
+   initialize();
+
+   //***
+   // See if the min / max keyword was set and reset it.
+   // Note this must be done after initialize since it sets the min / max from
+   // the elevation manager.
+   //***
+   lookup = kwl.find(prefix, ossimKeywordNames::MIN_VALUE_KW);
+   if (lookup)
+   {
+      setMinPixelValue(ossimString(lookup).toDouble());
+   }
+   lookup = kwl.find(prefix, ossimKeywordNames::MAX_VALUE_KW);
+   if (lookup)
+   {
+      setMaxPixelValue(ossimString(lookup).toDouble());
+   }
+
+   if (getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+      return false;
+   }
+
+   //***
+   // Reset the base class to have a fixed input list of "0" size.
+   // Note:  To not do this will result in a core dump destroying objects
+   // connected to this output.
+   //***
+   theInputObjectList.clear();
+   theInputListIsFixedFlag = true;
+   theOutputListIsFixedFlag = false;
+  
+   return true;
+}
+
+void ossimElevImageSource::initialize()
+{
+   static const char MODULE[] = "ossimElevImageSource::initialize";
+   
+   if (traceDebug()) CLOG << " Entered..." << endl;
+   
+   //***
+   // First see if the manager pointer has been captured.
+   //***
+   if (!theElevManager) theElevManager = ossimElevManager::instance();
+
+   if (!theElevManager)
+   {
+      setErrorStatus();
+      cerr << MODULE << "ERROR:\nNULL elevation manager pointer!"
+           << "\nObject not initialized!" << endl;
+      return;
+   }
+
+   // Basic sanity checks.
+   if (!theLatSpacing || !theLonSpacing ||
+       !theNumberOfLines || !theNumberOfSamps)
+   {
+      setErrorStatus();
+      cerr << MODULE << "ERROR:"
+           << "\nMust set latitude/longitude spacing and number of line and"
+           << " samples."
+           << "Object not initialized!" << endl;
+      return;
+      
+   }
+
+   // Check the ground point.
+   if ( theTiePoint.latd() > 90.0  || theTiePoint.latd() < -90.0  ||
+        theTiePoint.lond() > 180.0 || theTiePoint.lond() < -180.0 )
+   {
+      setErrorStatus();
+      cerr << MODULE << "ERROR:\nBogus tie point."
+           << "\nObject not initialized!" << endl;
+      return;
+   }
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\nTie point:  " << theTiePoint
+           << "\nLatitude spacing:  " << theLatSpacing
+           << "\nLongitude spacing:  " << theLonSpacing
+           << "\nLines:              " << theNumberOfLines
+           << "\nSamples:            " << theNumberOfSamps
+           << endl;
+   }
+   
+   //***
+   // Since this will return float data we need to set the min / max values
+   // of the data so that anybody who remaps it to eight bit will do it
+   // properly.  So scan the entire image rectangle using the manager.
+   // This will do two things, force the elevation manager to load all the
+   // cells, and at the same time the min / max elevation value will be set.
+   // NOTE:
+   // ??? Should the elevation manager clear the list of sources prior to
+   // the code segment so that the min / max is only from the cells we
+   // need!
+   //***
+
+   cout << "Initializing elevation manager..." << endl;
+
+#if 0
+   // Loop in the longitude or sample direction.
+   time_t start_t = time(NULL);
+   double lon = theTiePoint.lond();
+   for (ossim_uint32 samp = 0; samp < theNumberOfSamps; ++samp)
+   {
+      double lat = theTiePoint.latd() - theLatSpacing * (theNumberOfLines - 1);
+      if (lat < -90.0) lat = -(lat + 180.0); // Wrapped around the south poll.
+      
+      for (ossim_uint32 line = 0; line < theNumberOfLines; ++line)
+      {
+         ossimGpt gpt(lat, lon);
+         theElevManager->getHeightAboveMSL(gpt);
+
+         lat += theLatSpacing;
+         if (lat > 90) lat = 180 - lat; // Went across poll.
+      }
+      
+      lon += theLonSpacing;
+      if (lon > 180.0) lon -= 360.0; // Went across the central meridian.
+   }
+   time_t stop_t = time(NULL);
+   cout << "Finished loop two..." << endl;
+   cout << "Elapsed time for loop two:  " << (stop_t - start_t) << endl;
+#endif
+   
+   theTile = new ossimImageData(this,
+                                OSSIM_FLOAT);
+   theTile->initialize();
+
+   // Set the min / max for any normalization down the chain...
+   theTile->setMinPix(theElevManager->getMinHeightAboveMSL(), 0);
+   theTile->setMaxPix(theElevManager->getMaxHeightAboveMSL(), 0);
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\nMin pix:            " << theTile->getMinPix(0)
+           << "\nMax pix:            " << theTile->getMaxPix(0)
+           << endl;
+   }
+}
+
+ossimIrect ossimElevImageSource::getImageRectangle(ossim_uint32 reduced_res_level) const
+{
+   ossimIrect result(0, 0, theNumberOfSamps-1, theNumberOfLines-1);
+   
+   if (reduced_res_level != 0)
+   {
+      cerr << "ossimElevImageSource::getImageRectangle ERROR:"
+           << "\nOnly R0 is supported." << endl;
+   }
+
+   return result;
+}
+
+bool ossimElevImageSource::getImageGeometry(ossimKeywordlist& kwl,
+                                            const char* prefix)
+{
+   // Save off the image dimensions.
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_LINES_KW,
+           theNumberOfLines,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_SAMPLES_KW,
+           theNumberOfLines,
+           true);
+
+   // Save off the projection info (tie and post spacing).
+   ossimLlxyProjection proj(theTiePoint, theLatSpacing, theLonSpacing);
+   return proj.saveState(kwl, prefix);
+}
+
+void ossimElevImageSource::getDecimationFactor(ossim_uint32 resLevel, ossimDpt& result) const
+{
+   if (resLevel)
+   {
+      cerr << "ossimElevImageSource::getDecimationFactor ERROR:"
+           << "\nReduced res sets currently not supported!"
+           << endl;
+   }
+
+   result.line = 1.0;
+   result.samp = 1.0;
+}
+
+void ossimElevImageSource::getDecimationFactors(vector<ossimDpt>& decimations) const
+{
+   ossimDpt pt(1.0, 1.0);
+   decimations.clear();
+   decimations.push_back(pt);
+}
+
+ossim_uint32 ossimElevImageSource::getNumberOfDecimationLevels()const
+{
+   return 1;
+}
+
+ossim_uint32 ossimElevImageSource::getNumberOfInputBands() const
+{
+   return 1;
+}
+
+ossimScalarType ossimElevImageSource::getOutputScalarType() const
+{
+   return OSSIM_FLOAT;
+}
+
+ossim_uint32 ossimElevImageSource::getTileWidth() const
+{
+   if (theTile.get()) return theTile->getWidth();
+
+   return 0;
+}
+
+ossim_uint32 ossimElevImageSource::getTileHeight() const
+{
+   if (theTile.get()) return theTile->getHeight();
+
+   return 0;
+}
+
+void ossimElevImageSource::changeTileSize(const ossimIpt& size)
+{
+   if (traceDebug())
+   {
+      cout << "ossimElevImageSource::changeTileSize DEBUG:"
+           << "\nx size:  " << size.x
+           << "\ny size:  " << size.y
+           << endl;
+   }
+
+   if (!theTile)
+   {
+      cerr << "ossimElevImageSource::changeTileSize ERROR:"
+           << "\nObject not initialized!  Returning..." << endl;
+      return;
+   }
+
+   theTile = new ossimImageData(this,
+                                OSSIM_FLOAT,
+                                1,
+                                size.x,
+                                size.y);
+   theTile->initialize();
+   
+   // Set the min / max for any normalization down the chain...
+   theTile->setMinPix(theElevManager->getMinHeightAboveMSL(), 0);
+   theTile->setMaxPix(theElevManager->getMaxHeightAboveMSL(), 0);
+}
+
+ossim_uint32 ossimElevImageSource::getNumberOfLines(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level)
+   {
+      cerr << "ossimElevImageSource::getNumberOfLines ERROR:"
+           << "\nReduced res sets currently not supported!"
+           << endl;
+      return 0;
+   }
+
+   return theNumberOfLines;
+}
+
+ossim_uint32 ossimElevImageSource::getNumberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level)
+   {
+      cerr << "ossimElevImageSource::getNumberOfSamples ERROR:"
+           << "\nReduced res sets currently not supported!"
+           << endl;
+      return 0;
+   }
+
+   return theNumberOfSamps;
+}
+
+double ossimElevImageSource::getMinPixelValue(ossim_uint32 band) const
+{
+   if (band)
+   {
+      cerr << "ossimElevImageSource::getMinPixelValue ERROR:"
+           << "\nReduced res sets currently not supported!"
+           << endl;
+      return 0.0;
+   }
+
+   if (theTile.get())
+   {
+      return theTile->getMinPix(0);
+   }
+   else if (theElevManager)
+   {
+      return theElevManager->getMinHeightAboveMSL();
+   }
+
+   return 0.0;
+}
+
+double ossimElevImageSource::getMaxPixelValue(ossim_uint32 band) const
+{
+   if (band)
+   {
+      cerr << "ossimElevImageSource::getMaxPixelValue ERROR:"
+           << "\nReduced res sets currently not supported!"
+           << endl;
+      return 0.0;
+   }
+
+   if (theTile.get())
+   {
+      return theTile->getMaxPix(0);
+   }
+   else if (theElevManager)
+   {
+      return theElevManager->getMaxHeightAboveMSL();
+   }
+
+   return 0.0;
+}
+
+void ossimElevImageSource::setMinPixelValue(ossim_float64 min_pix)
+{
+   if (theTile.get()) 
+   {
+      theTile->setMinPix(min_pix, 0);
+      if (traceDebug())
+      {
+         cout << "ossimElevImageSource::setMinPixelValue DEBUG:"
+              << "\nMin pixel value:  " << min_pix
+              << endl;
+      }
+   }
+   else
+   {
+      cerr << "ossimElevImageSource::setMinPixelValue ERROR:"
+           << "\nObject not initialized!"
+           << endl;
+   }
+}
+
+void ossimElevImageSource::setMaxPixelValue(ossim_float64 max_pix)
+{
+   if (theTile.get()) 
+   {
+      theTile->setMaxPix(max_pix, 0);
+      if (traceDebug())
+      {
+         cout << "ossimElevImageSource::setMaxPixelValue DEBUG:"
+              << "\nMax pixel value:  " << max_pix
+              << endl;
+      }
+   }
+   else
+   {
+      cerr << "ossimElevImageSource::setMinPixelValue ERROR:"
+           << "\nObject not initialized!"
+           << endl;
+   }
+}      
diff --git a/Utilities/OSSIM/ossim_core/imaging/elevation/ossimElevImageSource.h b/Utilities/OSSIM/ossim_core/imaging/elevation/ossimElevImageSource.h
new file mode 100644
index 0000000000..70ca60a94f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/elevation/ossimElevImageSource.h
@@ -0,0 +1,146 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+// 
+// Description:  Class provides an elevation image source from the elevation
+// manager.
+//
+//********************************************************************
+// $Id: ossimElevImageSource.h,v 1.9 2005/02/11 15:07:30 dburken Exp $
+
+#ifndef ossimElevImageSource_HEADER
+#define ossimElevImageSource_HEADER
+
+#include "imaging/ossimImageSource.h"
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimGrect.h"
+
+class ossimElevSource;
+
+class ossimElevImageSource : public ossimImageSource
+{
+public:
+
+   ossimElevImageSource();
+   ossimElevImageSource(ossimObject* owner);
+   ossimElevImageSource(ossimObject* owner,
+                        const ossimGpt& tie,
+                        double latSpacing,  // decimal degrees
+                        double lonSpacing ,
+                        ossim_uint32 numberLines,
+                        ossim_uint32 numberSamples);
+   ossimElevImageSource(ossimObject* owner,
+                        const ossimKeywordlist& kwl,
+                        const char* prefix=0);
+   
+   virtual ~ossimElevImageSource();
+
+   /*!
+    *  Returns a pointer to a tile given an origin representing the upper left
+    *  corner of the tile to grab from the image.
+    *  Satisfies pure virtual from TileSource class.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& rect,
+                                   ossim_uint32 resLevel=0);
+
+   /*!
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *  Returns true if geometry info is present, false if not.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+   
+   /*!
+    *  Returns the number of bands in the image.  Alway one for this source.
+    */
+   virtual ossim_uint32 getNumberOfOutputBands()const { return 1; }
+
+
+   /*!
+    * Returns the zero-based (relative) image rectangle for the reduced
+    * resolution data set (rrds) passed in.  Note that rrds 0 is the highest
+    * resolution rrds.
+    */
+   virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level = 0) const; 
+
+   /*!
+    * Returns the absolute bounding rectangle of the image. The upper left
+    * corner may be non-zero if this is a subimage.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel = 0) const
+      {
+         return getImageRectangle(resLevel);
+      }
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const
+      {      
+         return false;
+      }
+      
+   virtual void initialize();
+
+   /*!
+    *  Satisfy pure virtuals from base classes...
+    */
+   virtual void getDecimationFactor(ossim_uint32 resLevel, ossimDpt& result) const;
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations) const;
+   virtual ossim_uint32 getNumberOfDecimationLevels()const;
+   virtual ossim_uint32 getNumberOfInputBands() const;
+   virtual ossimScalarType getOutputScalarType() const;
+   virtual ossim_uint32 getTileWidth() const;
+   virtual ossim_uint32 getTileHeight() const;
+   virtual void changeTileSize(const ossimIpt& size);
+
+   // access methods
+   virtual ossimGpt getTiePoint()         const { return theTiePoint; }
+   virtual ossim_float64 getLatitudeSpacing()  const { return theLatSpacing; }
+   virtual ossim_float64 getLongitudeSpacing() const { return theLonSpacing; }
+   virtual ossim_uint32  getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   
+   // set methods
+   virtual void setTiePoint(const ossimGpt& gpt) { theTiePoint = gpt; }
+   virtual void setLatitudeSpacing(ossim_float64 sp) { theLatSpacing = sp; }
+   virtual void setLongitudeSpacing(ossim_float64 sp) { theLonSpacing = sp; }
+   virtual void setNumberOfLines(ossim_uint32 lines) { theNumberOfLines = lines; }
+   virtual void setNumberOfSamples(ossim_uint32 samps) { theNumberOfSamps = samps;}
+   virtual void setMinPixelValue(ossim_float64 min_pix);
+   virtual void setMaxPixelValue(ossim_float64 max_pix);
+   
+protected:
+
+   ossimElevSource*            theElevManager;
+   ossimRefPtr<ossimImageData> theTile;
+   ossimGpt                    theTiePoint;      // upper left tie point
+   ossim_float64               theLatSpacing;    // in decimal degrees
+   ossim_float64               theLonSpacing;    // in decimal degrees
+   ossim_uint32                theNumberOfLines;
+   ossim_uint32                theNumberOfSamps;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/factory/.cvsignore
new file mode 100644
index 0000000000..42d2532435
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/.cvsignore
@@ -0,0 +1,2 @@
+*.d
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimAnnotationObjectFactory.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimAnnotationObjectFactory.cpp
new file mode 100644
index 0000000000..f1c99a23eb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimAnnotationObjectFactory.cpp
@@ -0,0 +1,102 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimAnnotationObjectFactory.cpp,v 1.4 2005/12/09 17:09:23 dburken Exp $
+#include <imaging/factory/ossimAnnotationObjectFactory.h>
+
+#include <imaging/annotation/ossimGeoAnnotationEllipseObject.h>
+#include <imaging/annotation/ossimGeoAnnotationFontObject.h>
+#include <imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.h>
+#include <imaging/annotation/ossimGeoAnnotationPolyObject.h>
+
+ossimAnnotationObjectFactory*  ossimAnnotationObjectFactory::theInstance=NULL;
+
+ossimAnnotationObjectFactory::ossimAnnotationObjectFactory()
+   :ossimFactoryBase<ossimAnnotationObject>()
+{
+}
+
+ossimAnnotationObject* ossimAnnotationObjectFactory::create(
+   const ossimString& spec) const
+{
+   if(spec == STATIC_TYPE_NAME(ossimGeoAnnotationEllipseObject))
+   {
+      return new ossimGeoAnnotationEllipseObject;
+   }
+   if(spec == STATIC_TYPE_NAME(ossimGeoAnnotationFontObject))
+   {
+      return new ossimGeoAnnotationFontObject;
+   }
+   if(spec == STATIC_TYPE_NAME(ossimGeoAnnotationMultiPolyLineObject))
+   {
+      return new ossimGeoAnnotationMultiPolyLineObject;
+   }
+   if(spec == STATIC_TYPE_NAME(ossimGeoAnnotationPolyObject))
+   {
+      return new ossimGeoAnnotationPolyObject;
+   }
+
+   return NULL;
+}
+
+ossimAnnotationObject* ossimAnnotationObjectFactory::create(
+   const ossimKeywordlist& kwl,
+   const char* prefix)    const
+{
+   ossimAnnotationObject* result = NULL;
+   
+   const char* type = kwl.find(prefix, "type");
+   if(type)
+   {
+      result = create(ossimString(type));
+      if(result)
+      {
+         result->loadState(kwl, prefix);
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimAnnotationObjectFactory::create WARNING"
+            << "Unable to create object of type:  "
+            << type << std::endl;
+      }
+   }
+
+   return result;
+}
+
+ossimAnnotationObjectFactory* ossimAnnotationObjectFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimAnnotationObjectFactory();
+   }
+
+   return theInstance;
+}
+
+//*****************************************************************************
+//  METHOD: ossimProjectionFactory::getList()
+//  
+//*****************************************************************************
+list<ossimString> ossimAnnotationObjectFactory::getList() const 
+{
+   list<ossimString> rtn_list;
+   list<ossimString> sub_list;
+   list<ossimFactoryBase<ossimAnnotationObject>*>::const_iterator factory;
+
+   factory = theRegistry.begin();
+   while(factory != theRegistry.end())
+   {
+      sub_list = (*factory)->getList();
+      rtn_list.merge(sub_list);
+      ++factory;
+   }
+
+   return rtn_list;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimAnnotationObjectFactory.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimAnnotationObjectFactory.h
new file mode 100644
index 0000000000..c4c033db8a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimAnnotationObjectFactory.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimAnnotationObjectFactory.h,v 1.1 2001/09/21 19:45:08 gpotts Exp $
+#ifndef ossimAnnotationObjectFactory_HEADER
+#define ossimAnnotationObjectFactory_HEADER
+#include "base/common/ossimFactoryBaseTemplate.h"
+#include "imaging/annotation/ossimAnnotationObject.h"
+class ossimAnnotationObjectFactory : public ossimFactoryBase<ossimAnnotationObject>
+{
+public:
+   /*!
+    * METHOD: instance()
+    * For accessing static instance of concrete factory.
+    */
+   static ossimAnnotationObjectFactory* instance();
+   
+   /*!
+    * METHOD: create()
+    * Attempts to create an instance of the Product given a Specifier or
+    * keywordlist. Returns successfully constructed product or NULL.
+    */
+   virtual ossimAnnotationObject* create(const ossimString& spec) const;
+   virtual ossimAnnotationObject* create(const ossimKeywordlist& kwl,
+                                         const char* prefix=0)    const;
+
+   /*!
+    * METHOD: getList()
+    * Returns name list of all products represented by this factory:
+    */
+   virtual list<ossimString> getList() const;
+
+protected:
+   ossimAnnotationObjectFactory();
+   static ossimAnnotationObjectFactory*  theInstance;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageDataFactory.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageDataFactory.cpp
new file mode 100644
index 0000000000..cbeadf9529
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageDataFactory.cpp
@@ -0,0 +1,254 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description:
+//
+//*************************************************************************
+// $Id: ossimImageDataFactory.cpp,v 1.25 2005/05/11 17:08:19 dburken Exp $
+#include "ossimImageDataFactory.h"
+#include "imaging/ossimU8ImageData.h"
+#include "imaging/ossimU11ImageData.h"
+#include "imaging/ossimU16ImageData.h"
+#include "imaging/ossimS16ImageData.h"
+#include "imaging/ossimImageData.h"
+#include "imaging/ossimImageSource.h"
+#include "base/common/ossimTrace.h"
+#include "base/misc/lookup_tables/ossimScalarTypeLut.h"
+
+// Static trace for debugging
+static ossimTrace traceDebug("ossimImageDataFactory:debug");
+
+ossimImageDataFactory* ossimImageDataFactory::theInstance = NULL;
+ossimImageDataFactory::ossimImageDataFactory()
+{
+   theInstance = NULL;
+}
+
+ossimImageDataFactory::~ossimImageDataFactory()
+{
+   if(theInstance)
+   {
+      delete theInstance;
+      theInstance = NULL;
+   }
+}
+
+ossimImageDataFactory* ossimImageDataFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimImageDataFactory;
+   }
+
+   return theInstance;
+}
+
+ossimRefPtr<ossimImageData> ossimImageDataFactory::create(
+   ossimSource* owner,
+   ossimScalarType scalar,
+   ossim_uint32 bands)const
+{
+   ossimIpt defaultTileSize;
+   ossimGetDefaultTileSize(defaultTileSize);
+   ossim_uint32 width  = defaultTileSize.x;
+   ossim_uint32 height = defaultTileSize.y;
+   
+   // do some bounds checking and initialize to a default
+   bands  = (bands>0)?bands:1;
+   scalar = scalar != OSSIM_SCALAR_UNKNOWN?scalar:OSSIM_UINT8;
+
+   if (traceDebug())
+   {
+      cout << "ossimImageDataFactory::create DEBUG:"
+           << "\nCaller:  "
+           << (owner ? owner->getClassName().c_str() : "unknown")
+           << "\nbands:   " << bands
+           << "\nwidth:   " << width
+           << "\nheight:  " << height
+           << "\nScalar type:  "
+           << (ossimScalarTypeLut::instance()->getEntryString(scalar))
+           << endl;
+   }
+   
+   ossimRefPtr<ossimImageData> result = NULL;
+   switch(scalar)
+   {
+      case OSSIM_UINT8:
+      {
+         result = new ossimU8ImageData(owner, bands, width, height);
+         break;
+      }
+
+      case OSSIM_USHORT11:
+      {
+         result = new ossimU11ImageData(owner, bands, width, height);
+         break;
+      }
+      
+      // ther are bugs in the 16 bit that I don't have time to find.
+      // The default image data object works good though.
+      //
+      // So for now I will comment these out.  I think it has something to
+      // do with the normalization it makes everything black
+      //
+      //
+//       case OSSIM_USHORT16:
+//       {
+//          result = new ossimU16ImageData(owner, bands, width, height);
+//          break;
+//       }
+//       case OSSIM_SSHORT16:
+//       {
+//          result = new ossimS16ImageData(owner, bands, width, height);
+//          break;
+//       }
+      default:
+      {
+         // create a generic image data implementation.
+         result = new ossimImageData(owner, scalar, bands, width, height);
+         break;
+      }
+   }
+   
+   return result;
+}
+
+ossimRefPtr<ossimImageData> ossimImageDataFactory::create(
+   ossimSource* owner,
+   ossimScalarType scalar,
+   ossim_uint32 bands,
+   ossim_uint32 width,
+   ossim_uint32 height)const
+{
+   ossimIpt defaultTileSize;
+   ossimGetDefaultTileSize(defaultTileSize);
+   // do some bounds checking and initialize to a default
+   bands  = bands  > 0?bands:1;
+   width  = width  > 0?width:defaultTileSize.x;
+   height = height > 0?height:defaultTileSize.y;
+   scalar = scalar != OSSIM_SCALAR_UNKNOWN?scalar:OSSIM_UINT8;
+
+   if (traceDebug())
+   {
+      cout << "ossimImageDataFactory::create DEBUG:"
+           << "\nCaller:  "
+           << (owner ? owner->getClassName().c_str() : "unknown")
+           << "\nbands:   " << bands
+           << "\nwidth:   " << width
+           << "\nheight:  " << height
+           << "\nScalar type:  "
+           << (ossimScalarTypeLut::instance()->getEntryString(scalar))
+           << endl;
+   }
+   
+   ossimRefPtr<ossimImageData> result = NULL;
+   switch(scalar)
+   {
+      case OSSIM_UINT8:
+      {
+         result = new ossimU8ImageData(owner, bands, width, height);
+         break;
+      }
+
+      case OSSIM_USHORT11:
+      {
+         result = new ossimU11ImageData(owner, bands, width, height);
+         break;
+      }
+      
+      // ther are bugs in the 16 bit that I don't have time to find.
+      // The default image data object works good though.
+      //
+      // So for now I will comment these out.  I think it has something to
+      // do with the normalization it makes everything black
+      //
+      //
+//       case OSSIM_USHORT16:
+//       {
+//          result = new ossimU16ImageData(owner, bands, width, height);
+//          break;
+//       }
+//       case OSSIM_SSHORT16:
+//       {
+//          result = new ossimS16ImageData(owner, bands, width, height);
+//          break;
+//       }
+      default:
+      {
+         // create a generic image data implementation.
+         result = new ossimImageData(owner, scalar, bands, width, height);
+         break;
+      }
+   }
+   
+   return result;
+}
+
+ossimRefPtr<ossimImageData> ossimImageDataFactory::create(
+   ossimSource* owner,
+   ossim_uint32 bands,
+   ossimImageSourceInterface* inputSource)const
+{
+   ossimRefPtr<ossimImageData> result = NULL;
+
+   if(inputSource)
+   {
+      ossimScalarType scalar = inputSource->getOutputScalarType();
+      ossim_uint32 width  = inputSource->getTileWidth();
+      ossim_uint32 height = inputSource->getTileHeight();
+      
+      result = create(owner, scalar, bands, width, height);
+      
+      for(ossim_uint32 band = 0; band < bands; ++band)
+      {
+         result->setMinPix(inputSource->getMinPixelValue(band));
+         result->setMaxPix(inputSource->getMaxPixelValue(band));
+         result->setNullPix(inputSource->getNullPixelValue(band));
+      }
+   }
+   else
+   {
+      cerr << "ossimImageDataFactory::create ERROR:"
+           << "\nNULL input source!" << endl;
+   }
+   
+   return result;
+}
+
+
+ossimRefPtr<ossimImageData> ossimImageDataFactory::create(
+   ossimSource* owner,
+   ossimImageSourceInterface* inputSource)const
+{
+   ossimRefPtr<ossimImageData> result = NULL;
+
+   if(inputSource)
+   {
+      ossimScalarType scalar = inputSource->getOutputScalarType();
+      ossim_uint32 bands  = inputSource->getNumberOfOutputBands();
+      ossim_uint32 width  = inputSource->getTileWidth();
+      ossim_uint32 height = inputSource->getTileHeight();
+      
+      result = create(owner, scalar, bands, width, height);
+      
+      for(ossim_uint32 band = 0; band < bands; ++band)
+      {
+         result->setMinPix(inputSource->getMinPixelValue(band));
+         result->setMaxPix(inputSource->getMaxPixelValue(band));
+      }
+      result->setNullPix(inputSource->getNullPixelValue());
+   }
+   else
+   {
+      cerr << "ossimImageDataFactory::create ERROR:"
+           << "\nNULL input source!" << endl;
+   }
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageDataFactory.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageDataFactory.h
new file mode 100644
index 0000000000..269ad7ebb0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageDataFactory.h
@@ -0,0 +1,62 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description:
+//
+//*************************************************************************
+// $Id: ossimImageDataFactory.h,v 1.9 2005/05/20 20:25:19 dburken Exp $
+#ifndef ossimImageDataFactory_HEADER
+#define ossimImageDataFactory_HEADER
+
+#include <imaging/ossimImageData.h>
+#include <base/common/ossimRefPtr.h>
+
+class ossimSource;
+class ossimImageSourceInterface;
+
+
+/*!
+ * This factory should be called by all image source producers to allocate
+ * an image tile.
+ */
+class OSSIM_DLL ossimImageDataFactory
+{
+public:
+   virtual ~ossimImageDataFactory();
+   static ossimImageDataFactory* instance();
+
+   virtual ossimRefPtr<ossimImageData> create(ossimSource* owner,
+                                              ossimScalarType scalar,
+                                              ossim_uint32 bands = 1)const;
+
+   virtual ossimRefPtr<ossimImageData> create(ossimSource* owner,
+                                              ossimScalarType scalar,
+                                              ossim_uint32 bands,
+                                              ossim_uint32 width,
+                                              ossim_uint32 height)const;
+   
+   virtual ossimRefPtr<ossimImageData> create(
+      ossimSource* owner,
+      ossim_uint32 bands,
+      ossimImageSourceInterface* inputSource)const;
+   
+   
+   virtual ossimRefPtr<ossimImageData> create(
+      ossimSource* owner,
+      ossimImageSourceInterface* inputSource)const;
+   
+protected:
+   ossimImageDataFactory(); // hide
+   ossimImageDataFactory(const ossimImageDataFactory&){}//hide
+   void operator = (ossimImageDataFactory&){}// hide
+   
+   static ossimImageDataFactory* theInstance;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactory.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactory.cpp
new file mode 100644
index 0000000000..7ae79e8297
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactory.cpp
@@ -0,0 +1,633 @@
+//----------------------------------------------------------------------------
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimImageHandlerFactory.cpp,v 1.38 2005/11/17 15:26:20 gpotts Exp $
+#include <imaging/factory/ossimImageHandlerFactory.h>
+#include <imaging/formats/adrg/ossimAdrgTileSource.h>
+#include <imaging/formats/ccf/ossimCcfTileSource.h>
+#include <imaging/formats/cibcadrg/ossimCibCadrgTileSource.h>
+#include <imaging/formats/doqq/ossimDoqqTileSource.h>
+#include <imaging/formats/dted/ossimDtedTileSource.h>
+#include <imaging/formats/nitf/ossimNitfTileSource.h>
+#include <imaging/formats/nitf/ossimQuickbirdNitfTileSource.h>
+#include <imaging/formats/srtm/ossimSrtmTileSource.h>
+#include <imaging/formats/tiff/ossimQuickbirdTiffTileSource.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+#include <imaging/formats/usgs_dem/ossimUsgsDemTileSource.h>
+#include <imaging/formats/landsat/ossimLandsatTileSource.h>
+#include <imaging/formats/general_raster/ossimGeneralRasterTileSource.h>
+#include <imaging/formats/ers/ossimERSTileSource.h>
+#include <imaging/formats/vpf/ossimVpfTileSource.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimKeywordNames.h>
+#include <imaging/formats/jpeg/ossimJpegTileSource.h>
+
+static const ossimTrace traceDebug("ossimImageHandlerFactory:debug");
+
+RTTI_DEF1(ossimImageHandlerFactory, "ossimImageHandlerFactory", ossimImageHandlerFactoryBase);
+
+ossimImageHandlerFactory* ossimImageHandlerFactory::theInstance = 0;
+ossimImageHandlerFactory::~ossimImageHandlerFactory()
+{
+   theInstance = (ossimImageHandlerFactory*)NULL;
+}
+
+ossimImageHandlerFactory* ossimImageHandlerFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimImageHandlerFactory;
+
+      // let's turn off tiff error reporting
+      TIFFSetErrorHandler(NULL);
+      TIFFSetWarningHandler(NULL);
+   }
+
+   return theInstance;
+}
+
+ossimImageHandler* ossimImageHandlerFactory::open(const ossimFilename& fileName)const
+{
+   ossimFilename copyFilename = fileName;
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandlerFactory::open(filename) DEBUG: entered..."
+         << std::endl
+         << "Attempting to open file " << copyFilename << std::endl;
+   }
+   ossimImageHandler* result = NULL;
+
+
+   if(copyFilename.ext() == "gz")
+   {
+      copyFilename = copyFilename.setExtension("");
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying JPEG" << std::endl;
+   }
+   result = new ossimJpegTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying adrg" << std::endl;
+   }
+
+   // test if ADRG
+   result  = new ossimAdrgTileSource();
+
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying ccf" << std::endl;
+   }
+   // test if ccf
+   result = new ossimCcfTileSource();
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+
+   delete result;
+
+   // this must be checked first before the TIFF handler
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying Quickbird TIFF"
+         << std::endl;
+   }
+   result = new ossimQuickbirdTiffTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying tif" << std::endl;
+   }
+   // test for tiff
+   result = new ossimTiffTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying CIB/CADRG"
+         << std::endl;
+   }
+   result = new ossimCibCadrgTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying DOQQ" << std::endl;
+   }
+   result = new ossimDoqqTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying DTED" << std::endl;
+   }
+   result = new ossimDtedTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+
+   delete result;
+
+   // this must be checked first before the NITF raw handler
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying Quickbird Nitf"
+         << std::endl;
+   }
+   result = new ossimQuickbirdNitfTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying Nitf" << std::endl;
+   }
+   result = new ossimNitfTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying USGS Dem"
+         << std::endl;
+   }
+   result = new ossimUsgsDemTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying Landsat"
+         << std::endl;
+   }
+   result = new ossimLandsatTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying Vpf" << std::endl;
+   }
+   result = new ossimVpfTileSource;
+   if(result->open(copyFilename))
+     {
+       return result;
+     }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying ERS" << std::endl;
+   }
+   result = new ossimERSTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   // Note:  SRTM should be in front of general raster...
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying SRTM"
+         << std::endl;
+   }
+   result = new ossimSrtmTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying General Raster"
+         << std::endl;
+   }
+   result = new ossimGeneralRasterTileSource;
+   if(result->open(copyFilename))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandlerFactory::open(filename) DEBUG: returning..." << std::endl;
+   }
+   return (ossimImageHandler*)NULL;
+}
+
+ossimImageHandler* ossimImageHandlerFactory::open(const ossimKeywordlist& kwl,
+                                                  const char* prefix)const
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandlerFactory::open(kwl, prefix) DEBUG: entered..."
+         << std::endl;
+   }
+   ossimImageHandler* result = NULL;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying adrg" << std::endl;
+   }
+   result = new ossimAdrgTileSource();
+
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying ccf" << std::endl;
+   }
+   result  = new ossimCcfTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying CIB/CADRG"
+         << std::endl;
+   }
+   result  = new ossimCibCadrgTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying DOQQ" << std::endl;
+   }
+   result  = new ossimDoqqTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying DTED" << std::endl;
+   }
+   result  = new ossimDtedTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying jpeg" << std::endl;
+   }
+   result  = new ossimJpegTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying Quickbird NITF"
+         << std::endl;
+   }
+   result = new ossimQuickbirdNitfTileSource;
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+
+   delete result;
+
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying Nitf" << std::endl;
+   }
+   result  = new ossimNitfTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   // Must be before tiff...
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying Quickbird TIFF"
+         << std::endl;
+   }
+   result = new ossimQuickbirdTiffTileSource;
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   
+   delete result;
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying tiff" << std::endl;
+   }
+   result  = new ossimTiffTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying USGS Dem"
+         << std::endl;
+   }
+   result  = new ossimUsgsDemTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying Landsat" << std::endl;
+   }
+   result  = new ossimLandsatTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying VPF" << std::endl;
+   }
+   result = new ossimVpfTileSource;
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying ERS" << std::endl;
+   }
+   result = new ossimERSTileSource;
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+
+   // Note:  SRTM should be in front of general raster...
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying SRTM"
+         << std::endl;
+   }
+   result  = new ossimSrtmTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "trying General Raster"
+         << std::endl;
+   }
+   result  = new ossimGeneralRasterTileSource();
+   if(result->loadState(kwl, prefix))
+   {
+      return result;
+   }
+   delete result;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandlerFactory::open(kwl, prefix) DEBUG: returning..."
+         << std::endl;
+   }
+   return (ossimImageHandler*)NULL;
+}
+
+ossimObject* ossimImageHandlerFactory::createObject(const ossimString& typeName)const
+{
+   if(STATIC_TYPE_NAME(ossimAdrgTileSource) == typeName)
+   {
+      return new ossimAdrgTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimCcfTileSource) == typeName)
+   {
+      return new ossimCcfTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimCibCadrgTileSource) == typeName)
+   {
+      return new ossimCibCadrgTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimDoqqTileSource) == typeName)
+   {
+      return new ossimDoqqTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimDtedTileSource) == typeName)
+   {
+      return new ossimDtedTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimJpegTileSource) == typeName)
+   {
+      return new ossimJpegTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimNitfTileSource) == typeName)
+   {
+      return new ossimNitfTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimTiffTileSource) == typeName)
+   {
+      return new ossimTiffTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimUsgsDemTileSource) == typeName)
+   {
+      return new ossimUsgsDemTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimLandsatTileSource) == typeName)
+   {
+      return new ossimLandsatTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimERSTileSource) == typeName)
+   {
+      return new ossimERSTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimSrtmTileSource) == typeName)
+   {
+      return new ossimSrtmTileSource();
+   }
+   if(STATIC_TYPE_NAME(ossimGeneralRasterTileSource) == typeName)
+   {
+      return new ossimGeneralRasterTileSource();
+   }
+
+   return (ossimObject*)NULL;
+}
+
+ossimObject* ossimImageHandlerFactory::createObject(const ossimKeywordlist& kwl,
+                                                    const char* prefix)const
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandlerFactory::createObject(kwl, prefix) DEBUG:"
+         << " entering ..." << std::endl;
+   }
+   ossimObject* result = (ossimObject*)NULL;
+   const char* type = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+
+   if(type)
+   {
+      if (ossimString(type).trim() == STATIC_TYPE_NAME(ossimImageHandler))
+      {
+         const char* lookup = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+
+         if (lookup)
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "BEBUG: filename " << lookup << std::endl;
+            }
+            // Call the open that takes a filename...
+            result = this->open(kwl, prefix);//ossimFilename(lookup));
+         }
+      }
+      else
+      {
+         result = createObject(ossimString(type));
+         if(result)
+         {
+            result->loadState(kwl, prefix);
+         }
+      }
+   }
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageHandlerFactory::createObject(kwl, prefix) DEBUG: returning result ..." << std::endl;
+   }
+   return result;
+}
+
+void ossimImageHandlerFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   typeList.push_back(STATIC_TYPE_NAME(ossimAdrgTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimCcfTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimCibCadrgTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimDoqqTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimDtedTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimJpegTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimNitfTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimTiffTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimUsgsDemTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimLandsatTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimERSTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimSrtmTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimGeneralRasterTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimQuickbirdNitfTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimQuickbirdTiffTileSource));
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactory.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactory.h
new file mode 100644
index 0000000000..cdcdce312f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactory.h
@@ -0,0 +1,76 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for ossimImageHandlerFactoryMaker.
+//*******************************************************************
+//  $Id: ossimImageHandlerFactory.h,v 1.4 2004/05/26 21:43:14 dburken Exp $
+
+#ifndef ossimImageHandlerFactory_HEADER
+#define ossimImageHandlerFactory_HEADER
+#include "ossimImageHandlerFactoryBase.h"
+
+#include "base/data_types/ossimString.h"
+
+class ossimImageHandler;
+class ossimFilename;
+class ossimKeywordlist;
+
+//*******************************************************************
+// CLASS:  ossimImageHandlerFactory
+//*******************************************************************
+class OSSIMDLLEXPORT ossimImageHandlerFactory : public ossimImageHandlerFactoryBase
+{
+public:
+   virtual ~ossimImageHandlerFactory();
+   static ossimImageHandlerFactory* instance();
+   
+   virtual ossimImageHandler* open(const ossimFilename& fileName)const;
+   virtual ossimImageHandler* open(const ossimKeywordlist& kwl,
+                                   const char* prefix=0)const;
+
+   
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+   
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+  
+protected:
+   ossimImageHandlerFactory(){}
+   ossimImageHandlerFactory(const ossimImageHandlerFactory&){}
+   void operator = (const ossimImageHandlerFactory&){}
+
+   static ossimImageHandlerFactory* theInstance;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactoryBase.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactoryBase.cpp
new file mode 100644
index 0000000000..9229ed7514
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactoryBase.cpp
@@ -0,0 +1,25 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+//  $Id: ossimImageHandlerFactoryBase.cpp,v 1.1 2002/03/26 20:41:04 gpotts Exp $
+#include "ossimImageHandlerFactoryBase.h"
+
+RTTI_DEF1(ossimImageHandlerFactoryBase, "ossimImageHandlerFactoryBase", ossimObjectFactory);
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactoryBase.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactoryBase.h
new file mode 100644
index 0000000000..2493a05688
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerFactoryBase.h
@@ -0,0 +1,44 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+//  $Id: ossimImageHandlerFactoryBase.h,v 1.3 2005/05/20 20:25:19 dburken Exp $
+
+#ifndef ossimImageHandlerFactoryBase_HEADER
+#define ossimImageHandlerFactoryBase_HEADER
+
+#include "base/data_types/ossimString.h"
+#include "base/factory/ossimObjectFactory.h"
+
+class ossimImageHandler;
+class ossimFilename;
+class ossimKeywordlist;
+
+class OSSIM_DLL ossimImageHandlerFactoryBase : public ossimObjectFactory
+{
+public:
+   virtual ossimImageHandler* open(const ossimFilename& fileName)const = 0;
+   virtual ossimImageHandler* open(const ossimKeywordlist& kwl,
+                                   const char* prefix=0)const = 0;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerRegistry.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerRegistry.cpp
new file mode 100644
index 0000000000..8682c95cff
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerRegistry.cpp
@@ -0,0 +1,193 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Contains class definition for ImageHandlerRegistry.
+//
+//*******************************************************************
+//  $Id: ossimImageHandlerRegistry.cpp,v 1.15 2004/01/13 19:24:31 gpotts Exp $
+#include <algorithm>
+#include "ossimImageHandlerRegistry.h"
+#include "ossimImageHandlerFactory.h"
+#include "ossimImageHandlerFactoryBase.h"
+#include "base/data_types/ossimFilename.h"
+#include "imaging/formats/ossimImageHandler.h"
+#include "base/factory/ossimObjectFactoryRegistry.h"
+
+using namespace std;
+
+RTTI_DEF1(ossimImageHandlerRegistry, "ossimImageHandlerRegistry", ossimObjectFactory);
+
+ossimImageHandlerRegistry* ossimImageHandlerRegistry::theInstance = 0;
+
+ossimImageHandlerRegistry::ossimImageHandlerRegistry()
+{  
+}
+
+ossimImageHandlerRegistry* ossimImageHandlerRegistry::instance()
+{
+   if (theInstance == 0)
+   {
+      theInstance = new ossimImageHandlerRegistry();
+      ossimObjectFactoryRegistry::instance()->registerFactory(theInstance);
+      theInstance->registerFactory(ossimImageHandlerFactory::instance());
+   }
+   return theInstance;
+}
+
+ossimImageHandlerRegistry::~ossimImageHandlerRegistry()
+{
+   clear();
+   theInstance = 0;
+}
+
+void ossimImageHandlerRegistry::registerFactory(ossimImageHandlerFactoryBase* factory)
+{
+   if(factory&&!findFactory(factory))
+   {
+      theFactoryList.push_back(factory);
+   }
+}
+
+void ossimImageHandlerRegistry::unregisterFactory(ossimImageHandlerFactoryBase* factory)
+{
+   std::vector<ossimImageHandlerFactoryBase*>::iterator iter =  std::find(theFactoryList.begin(),
+                                                                          theFactoryList.end(),
+                                                                          factory);
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+}
+
+bool ossimImageHandlerRegistry::findFactory(ossimImageHandlerFactoryBase* factory)const
+{
+   return (std::find(theFactoryList.begin(),
+                     theFactoryList.end(),
+                     factory)!=theFactoryList.end());
+}
+
+
+ossimObject* ossimImageHandlerRegistry::createObject(const ossimString& typeName)const
+{
+   ossimObject*                   result = NULL;
+   vector<ossimImageHandlerFactoryBase*>::const_iterator factory;
+
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+     result = (*factory)->createObject(typeName);
+     ++factory;
+   }
+   
+   return result;
+ 
+}
+
+ossimObject* ossimImageHandlerRegistry::createObject(const ossimKeywordlist& kwl,
+                                                     const char* prefix)const
+{
+   ossimObject* result = NULL;
+   vector<ossimImageHandlerFactoryBase*>::const_iterator factory;
+
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+     result = (*factory)->createObject(kwl, prefix);
+     ++factory;
+   }
+   if(!result)
+   {
+      result = open(kwl, prefix);
+   }
+   return result;
+}
+
+void ossimImageHandlerRegistry::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   vector<ossimString> result;
+   vector<ossimImageHandlerFactoryBase*>::const_iterator iter = theFactoryList.begin();
+
+   while(iter != theFactoryList.end())
+   {
+      result.clear();
+      (*iter)->getTypeNameList(result);
+
+      // now append to the end of the typeList.
+      typeList.insert(typeList.end(),
+                      result.begin(),
+                      result.end());
+      ++iter;
+   }
+}
+ 
+ossimImageHandler* ossimImageHandlerRegistry::open(const ossimFilename& fileName)const
+{
+   ossimImageHandler*                   result = NULL;
+   vector<ossimImageHandlerFactoryBase*>::const_iterator factory;
+
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+      
+      result = (*factory)->open(fileName);
+      ++factory;
+   }
+   
+   return result;
+}
+
+ossimImageHandler* ossimImageHandlerRegistry::open(const ossimKeywordlist& kwl,
+                                                   const char* prefix)const
+{
+   ossimImageHandler*                   result = NULL;
+   vector<ossimImageHandlerFactoryBase*>::const_iterator factory;
+
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+     result = (*factory)->open(kwl, prefix);
+     ++factory;
+   }
+   
+   return result;
+}
+
+void ossimImageHandlerRegistry::clear()
+{
+   theFactoryList.clear();
+}
+
+ossimImageHandlerRegistry::ossimImageHandlerRegistry(const ossimImageHandlerRegistry& rhs)
+   :  ossimObjectFactory()
+{}
+
+const ossimImageHandlerRegistry&
+ossimImageHandlerRegistry::operator=(const ossimImageHandlerRegistry& rhs)
+{ return rhs; }
+
+extern "C"
+{
+  void* ossimImageHandlerRegistryGetInstance()
+  {
+    return ossimImageHandlerRegistry::instance();
+  }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerRegistry.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerRegistry.h
new file mode 100644
index 0000000000..38df422ac4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageHandlerRegistry.h
@@ -0,0 +1,98 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpott@imagelinks.com)
+//
+// Description:  Contains class definition for the class
+//               ImageHandlerRegistry.
+//
+//*******************************************************************
+//  $Id: ossimImageHandlerRegistry.h,v 1.11 2004/05/19 17:54:51 dburken Exp $
+
+#ifndef ossimImageHandlerRegistry_HEADER
+#define ossimImageHandlerRegistry_HEADER
+
+#include <vector>
+#include "base/factory/ossimObjectFactory.h"
+#include "base/common/ossimRtti.h"
+
+class ossimImageHandler;
+class ossimImageHandlerFactoryBase;
+class ossimFilename;
+class ossimKeywordlist;
+
+class OSSIMDLLEXPORT ossimImageHandlerRegistry : public ossimObjectFactory
+{
+public:
+   ~ossimImageHandlerRegistry();
+   static ossimImageHandlerRegistry* instance();
+   
+   void addFactory(ossimImageHandlerFactoryBase* factory)
+      {
+         registerFactory(factory);
+      }
+   void registerFactory(ossimImageHandlerFactoryBase* factory);
+   void unregisterFactory(ossimImageHandlerFactoryBase* factory);
+   bool findFactory(ossimImageHandlerFactoryBase* factory)const;
+   
+   ossimImageHandler* open(const ossimFilename& fileName)const;
+
+   
+   /*!
+    *  Given a keyword list return a pointer to an ImageHandler.  Returns
+    *  null if a valid handler cannot be found.
+    */
+   ossimImageHandler* open(const ossimKeywordlist& kwl, const char* prefix=0)const;
+
+   /*!
+    * Creates an object given a type name.
+    */
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+protected:
+   ossimImageHandlerRegistry();
+   ossimImageHandlerRegistry(const ossimImageHandlerRegistry& rhs);
+   const ossimImageHandlerRegistry&
+      operator=(const ossimImageHandlerRegistry& rhs);
+
+private:
+   void clear();
+   std::vector<ossimImageHandlerFactoryBase*>   theFactoryList;
+   static ossimImageHandlerRegistry*            theInstance;
+
+TYPE_DATA
+};
+
+extern "C"
+{
+ OSSIMDLLEXPORT  void* ossimImageHandlerRegistryGetInstance();
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactory.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactory.cpp
new file mode 100644
index 0000000000..cc80fb0906
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactory.cpp
@@ -0,0 +1,206 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero
+//
+//*******************************************************************
+//  $Id: ossimImageMetaDataWriterFactory.cpp,v 1.11 2005/08/09 19:10:41 dburken Exp $
+
+#include <imaging/factory/ossimImageMetaDataWriterFactory.h>
+
+#include <imaging/metadata/ossimEnviHeaderFileWriter.h>
+#include <imaging/metadata/ossimFgdcFileWriter.h>
+#include <imaging/metadata/ossimGeomFileWriter.h>
+#include <imaging/metadata/ossimJpegWorldFileWriter.h>
+#include <imaging/metadata/ossimReadmeFileWriter.h>
+#include <imaging/metadata/ossimTiffWorldFileWriter.h>
+
+#include <base/common/ossimKeywordNames.h>
+
+RTTI_DEF1(ossimImageMetaDataWriterFactory,
+          "ossimImageMetaDataWriterFactory",
+          ossimImageMetaDataWriterFactoryBase);
+
+ossimImageMetaDataWriterFactory*
+ossimImageMetaDataWriterFactory::theInstance = NULL;
+
+ossimImageMetaDataWriterFactory::ossimImageMetaDataWriterFactory()
+{
+   theInstance = this;
+}
+
+ossimImageMetaDataWriterFactory::~ossimImageMetaDataWriterFactory()
+{
+   theInstance = NULL;
+}
+
+ossimImageMetaDataWriterFactory* ossimImageMetaDataWriterFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimImageMetaDataWriterFactory;
+   }
+
+   return theInstance;
+}
+
+ossimObject* ossimImageMetaDataWriterFactory::createObject(
+   const ossimString& typeName) const
+{
+   // Use the type name to instantiate the class.
+   ossimObject* result = (ossimObject*)NULL;
+   
+   if(STATIC_TYPE_NAME(ossimEnviHeaderFileWriter) == typeName)
+   {
+     result = new ossimEnviHeaderFileWriter;
+   }
+   else if(STATIC_TYPE_NAME(ossimFgdcFileWriter) == typeName)
+   {
+     result = new ossimFgdcFileWriter;
+   }
+   else if(STATIC_TYPE_NAME(ossimGeomFileWriter) == typeName)
+   {
+     result = new ossimGeomFileWriter;
+   }
+   else if(STATIC_TYPE_NAME(ossimJpegWorldFileWriter) == typeName)
+   {
+     result = new ossimJpegWorldFileWriter;
+   }
+   else if(STATIC_TYPE_NAME(ossimReadmeFileWriter) == typeName)
+   {
+     result = new ossimReadmeFileWriter;
+   }
+   else if(STATIC_TYPE_NAME(ossimTiffWorldFileWriter) == typeName)
+   {
+     result = new ossimTiffWorldFileWriter;
+   }
+
+   return result;
+}
+
+ossimObject* ossimImageMetaDataWriterFactory::createObject(
+   const ossimKeywordlist& kwl, const char* prefix)const
+{
+   //---
+   // Check the type keyword found in kwl.  Use the create by class name
+   // above and then call load state.
+   //---
+   ossimObject* result = (ossimObject*)NULL;
+
+   const char* type = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+
+   if(type)
+   {
+      result = createObject(ossimString(type));
+      if(result)
+      {
+         result->loadState(kwl, prefix);
+      }
+   }
+   
+   return result;
+}
+
+ossimRefPtr<ossimMetadataFileWriter>
+ossimImageMetaDataWriterFactory::createWriter(const ossimString& type)const
+{
+   ossimRefPtr<ossimMetadataFileWriter> writer;
+   
+   writer = new ossimEnviHeaderFileWriter;
+   if ( (writer->getClassName() == type) ||
+        (writer->hasMetadataType(type)) )
+   {
+      return writer;
+   }
+
+   writer = new ossimFgdcFileWriter;
+   if ( (writer->getClassName() == type) ||
+        (writer->hasMetadataType(type)) )
+   {
+      return writer;
+   }
+
+   writer = new ossimGeomFileWriter;
+   if ( (writer->getClassName() == type) ||
+        (writer->hasMetadataType(type)) )
+   {
+      return writer;
+   }
+   
+   writer = new ossimJpegWorldFileWriter;
+   if ( (writer->getClassName() == type) ||
+        (writer->hasMetadataType(type)) )
+   {
+      return writer;
+   }
+
+   writer = new ossimReadmeFileWriter;
+   if ( (writer->getClassName() == type) ||
+        (writer->hasMetadataType(type)) )
+   {
+      return writer;
+   }
+
+   writer = new ossimTiffWorldFileWriter;
+   if ( (writer->getClassName() == type) ||
+        (writer->hasMetadataType(type)) )
+   {
+      return writer;
+   }
+
+   // Not in factory.
+   writer = NULL;
+   return writer;
+}
+
+void ossimImageMetaDataWriterFactory::getTypeNameList(
+   std::vector<ossimString>& typeList) const
+{
+   // add each object's RTTI name here
+   typeList.push_back(STATIC_TYPE_NAME(ossimEnviHeaderFileWriter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimFgdcFileWriter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimGeomFileWriter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimJpegWorldFileWriter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimReadmeFileWriter));   
+   typeList.push_back(STATIC_TYPE_NAME(ossimTiffWorldFileWriter));
+}
+
+void ossimImageMetaDataWriterFactory::getMetadatatypeList(
+   std::vector<ossimString>& metadatatypeList) const
+{
+   ossimRefPtr<ossimMetadataFileWriter> writer;
+
+   writer = new ossimEnviHeaderFileWriter;
+   writer->getMetadatatypeList(metadatatypeList);
+
+   writer = new ossimFgdcFileWriter;
+   writer->getMetadatatypeList(metadatatypeList);
+   
+   writer = new ossimGeomFileWriter;
+   writer->getMetadatatypeList(metadatatypeList);
+
+   writer = new ossimJpegWorldFileWriter;
+   writer->getMetadatatypeList(metadatatypeList);
+
+   writer = new ossimReadmeFileWriter;
+   writer->getMetadatatypeList(metadatatypeList);
+
+   writer = new ossimTiffWorldFileWriter;
+   writer->getMetadatatypeList(metadatatypeList);
+}
+
+ossimImageMetaDataWriterFactory::ossimImageMetaDataWriterFactory(
+   const ossimImageMetaDataWriterFactory& rhs)
+{
+}
+
+const ossimImageMetaDataWriterFactory&
+ossimImageMetaDataWriterFactory::operator=(
+   const ossimImageMetaDataWriterFactory& rhs)
+{
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactory.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactory.h
new file mode 100644
index 0000000000..5bccd9656b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactory.h
@@ -0,0 +1,87 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimImageMetaDataWriterFactory.h,v 1.5 2005/08/08 22:01:32 dburken Exp $
+
+#ifndef ossimImageMetaDataWriterFactory_HEADER
+#define ossimImageMetaDataWriterFactory_HEADER
+
+#include <imaging/factory/ossimImageMetaDataWriterFactoryBase.h>
+#include <base/common/ossimRefPtr.h>
+
+class ossimMetadataFileWriter;
+
+class OSSIMDLLEXPORT ossimImageMetaDataWriterFactory:
+   public ossimImageMetaDataWriterFactoryBase
+{
+public:
+   ~ossimImageMetaDataWriterFactory();
+
+   static ossimImageMetaDataWriterFactory* instance();
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+
+   /**
+    * Creates a writer from either a class name or a string representing the
+    * meta data type like "tiff_world_file".
+    *
+    * @return ossimRefPtr<ossimMetadataFileWriter>
+    *
+    * @note Return can have a null pointer if type is not found in a factory so
+    * the caller should always check the pointer like:
+    * ossimRefPtr<ossimMetadataFileWriter> mw =
+    *    ossimImageMetaDataWriterRegistry::instance("ossim_readme");
+    * if (!mw.valid())
+    * {
+    *    // not in factory
+    * }
+    */
+   virtual ossimRefPtr<ossimMetadataFileWriter> createWriter(
+      const ossimString& type)const;
+
+   /**
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /**
+    * Satisfies pure virtual from ossimImageMetaDataWriterFactoryBase.
+    * 
+    * Appends the meta data writers types from each of the supported meta
+    * data writers in this factor to the "metadatatypeList".
+    * 
+    * This is the actual metadata type name like:
+    *   ossim_geometry
+    *   envi_header
+    *   tiff_world_file
+    *   jpeg_world_file
+    *   
+    * @param metadatatypeList stl::vector<ossimString> List to append to.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList) const;
+ 
+protected:
+   static ossimImageMetaDataWriterFactory* theInstance;
+
+   ossimImageMetaDataWriterFactory();
+
+   ossimImageMetaDataWriterFactory(const ossimImageMetaDataWriterFactory& rhs);
+
+   const ossimImageMetaDataWriterFactory& operator =(
+      const ossimImageMetaDataWriterFactory& rhs);
+   
+TYPE_DATA 
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactoryBase.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactoryBase.cpp
new file mode 100644
index 0000000000..c8cfae7dda
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactoryBase.cpp
@@ -0,0 +1,28 @@
+//----------------------------------------------------------------------------
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//----------------------------------------------------------------------------
+// $Id: ossimImageMetaDataWriterFactoryBase.cpp,v 1.2 2005/06/24 17:54:09 dburken Exp $
+
+#include  <imaging/factory/ossimImageMetaDataWriterFactoryBase.h>
+
+RTTI_DEF1(ossimImageMetaDataWriterFactoryBase,
+          "ossimImageMetaDataWriterFactoryBase",
+          ossimObjectFactory);
+
+ossimImageMetaDataWriterFactoryBase::ossimImageMetaDataWriterFactoryBase()
+{
+}
+
+ossimImageMetaDataWriterFactoryBase::ossimImageMetaDataWriterFactoryBase(
+   const ossimImageMetaDataWriterFactoryBase&)
+{
+}
+
+const ossimImageMetaDataWriterFactoryBase&
+ossimImageMetaDataWriterFactoryBase::operator=(
+   const ossimImageMetaDataWriterFactoryBase&)
+{
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactoryBase.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactoryBase.h
new file mode 100644
index 0000000000..30efed5fbc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterFactoryBase.h
@@ -0,0 +1,67 @@
+//----------------------------------------------------------------------------
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//----------------------------------------------------------------------------
+// $Id: ossimImageMetaDataWriterFactoryBase.h,v 1.3 2005/08/08 22:01:32 dburken Exp $
+#ifndef ossimImageMetaDataWriterFactoryBase_HEADER
+#define ossimImageMetaDataWriterFactoryBase_HEADER
+#include <base/factory/ossimObjectFactory.h>
+#include <base/common/ossimRefPtr.h>
+
+class ossimMetadataFileWriter;
+
+class ossimImageMetaDataWriterFactoryBase : public ossimObjectFactory
+{
+public:
+   /**
+    * Pure virtual.  All ossimImageMetaDataWriterFactories must implement.
+    * 
+    * Creates a writer from either a class name or a string representing the
+    * meta data type like "tiff_world_file".
+    *
+    * @return ossimRefPtr<ossimMetadataFileWriter>
+    *
+    * @note Return can have a null pointer if type is not found in a factory so
+    * the caller should always check the pointer like:
+    * ossimRefPtr<ossimMetadataFileWriter> mw =
+    *    ossimImageMetaDataWriterRegistry::instance("ossim_readme");
+    * if (!mw.valid())
+    * {
+    *    // not in factory
+    * }
+    */
+   virtual ossimRefPtr<ossimMetadataFileWriter> createWriter(
+      const ossimString& type)const=0;
+
+   /**
+    * Pure virtual.  All ossimImageMetaDataWriterFactories must implement.
+    * 
+    * Appends the meta data writers types to the "metadatatypeList".
+    * 
+    * This is the actual metadata type name like:
+    *   ossim_geometry
+    *   envi_header
+    *   tiff_world_file
+    *   jpeg_world_file
+    *   
+    * @param metadatatypeList stl::vector<ossimString> List to append to.
+    *
+    * @note All writers should append to the list, not, clear it and then add
+    * their types.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList) const=0;
+
+protected:
+   ossimImageMetaDataWriterFactoryBase();
+   
+   ossimImageMetaDataWriterFactoryBase(
+      const ossimImageMetaDataWriterFactoryBase&);
+   
+   const ossimImageMetaDataWriterFactoryBase& operator=(
+      const ossimImageMetaDataWriterFactoryBase&);
+
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterRegistry.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterRegistry.cpp
new file mode 100644
index 0000000000..ff901bd424
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterRegistry.cpp
@@ -0,0 +1,176 @@
+//----------------------------------------------------------------------------
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//----------------------------------------------------------------------------
+// $Id: ossimImageMetaDataWriterRegistry.cpp,v 1.10 2005/08/08 22:01:32 dburken Exp $
+
+
+#include <imaging/factory/ossimImageMetaDataWriterRegistry.h>
+#include <imaging/factory/ossimImageMetaDataWriterFactory.h>
+#include <imaging/metadata/ossimMetadataFileWriter.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <algorithm>
+
+ossimImageMetaDataWriterRegistry*
+ossimImageMetaDataWriterRegistry::theInstance= NULL;
+
+ossimImageMetaDataWriterRegistry::ossimImageMetaDataWriterRegistry()
+{
+   theInstance = this;
+}
+
+ossimImageMetaDataWriterRegistry::~ossimImageMetaDataWriterRegistry()
+{
+   ossimObjectFactoryRegistry::instance()->unregisterFactory(theInstance);
+   theInstance = NULL;
+}
+
+ossimImageMetaDataWriterRegistry* ossimImageMetaDataWriterRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimImageMetaDataWriterRegistry;
+      theInstance->registerFactory(ossimImageMetaDataWriterFactory::instance());
+      ossimObjectFactoryRegistry::instance()->registerFactory(theInstance);
+   }
+
+   return theInstance;
+}
+
+void ossimImageMetaDataWriterRegistry::registerFactory(
+   ossimImageMetaDataWriterFactoryBase* factory)
+{
+   if(factory&&!findFactory(factory))
+   {
+      theFactoryList.push_back(factory);
+   }
+}
+
+void ossimImageMetaDataWriterRegistry::unregisterFactory(
+   ossimImageMetaDataWriterFactoryBase* factory)
+{
+   std::vector<ossimImageMetaDataWriterFactoryBase*>::iterator iter =
+      std::find(theFactoryList.begin(),
+                theFactoryList.end(),
+                factory);
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+}
+
+bool ossimImageMetaDataWriterRegistry::findFactory(
+   ossimImageMetaDataWriterFactoryBase* factory)const
+{
+   return (std::find(theFactoryList.begin(),
+                     theFactoryList.end(),
+                     factory)!=theFactoryList.end());
+}
+
+
+ossimObject* ossimImageMetaDataWriterRegistry::createObject(
+   const ossimString& typeName) const
+{
+   ossimObject* result = NULL;
+   vector<ossimImageMetaDataWriterFactoryBase*>::const_iterator factory;
+   
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+      result = (*factory)->createObject(typeName);
+      ++factory;
+   }
+   
+   return result;
+}
+
+ossimObject* ossimImageMetaDataWriterRegistry::createObject(
+   const ossimKeywordlist& kwl,
+   const char* prefix) const
+{
+   ossimObject* result = NULL;
+   vector<ossimImageMetaDataWriterFactoryBase*>::const_iterator factory;
+
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+     result = (*factory)->createObject(kwl, prefix);
+     ++factory;
+   }
+   return result;
+}
+
+ossimRefPtr<ossimMetadataFileWriter>
+ossimImageMetaDataWriterRegistry::createWriter(const ossimString& type) const
+{
+   ossimRefPtr<ossimMetadataFileWriter> result = NULL;
+   
+   vector<ossimImageMetaDataWriterFactoryBase*>::const_iterator factory;
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+     result = (*factory)->createWriter(type);
+     ++factory;
+   }
+   return result;
+}
+
+void ossimImageMetaDataWriterRegistry::getTypeNameList(
+   std::vector<ossimString>& typeList) const
+{
+   vector<ossimString> result;
+   vector<ossimImageMetaDataWriterFactoryBase*>::const_iterator iter =
+      theFactoryList.begin();
+
+   while(iter != theFactoryList.end())
+   {
+      result.clear();
+      (*iter)->getTypeNameList(result);
+
+      // now append to the end of the typeList.
+      typeList.insert(typeList.end(),
+                      result.begin(),
+                      result.end());
+      ++iter;
+   }
+}
+
+void ossimImageMetaDataWriterRegistry::getMetadatatypeList(
+   std::vector<ossimString>& metadatatypeList) const
+{
+   //---
+   // Since this is the master registry for all meta data writer factories
+   // we will start with a cleared list.
+   //---
+   metadatatypeList.clear();
+   
+   vector<ossimImageMetaDataWriterFactoryBase*>::const_iterator iter =
+      theFactoryList.begin();
+   
+   while(iter != theFactoryList.end())
+   {
+      (*iter)->getMetadatatypeList(metadatatypeList);
+      ++iter;
+   } 
+}
+
+ossimImageMetaDataWriterRegistry::ossimImageMetaDataWriterRegistry(
+   const ossimImageMetaDataWriterRegistry& rhs)
+{
+}
+
+const ossimImageMetaDataWriterRegistry&
+ossimImageMetaDataWriterRegistry::operator=(
+   const ossimImageMetaDataWriterRegistry &rhs)
+{
+   return *this;
+}
+
+extern "C"
+{
+   void* ossimImageMetaDataWriterRegistryGetInstance()
+   {
+      return ossimImageMetaDataWriterRegistry::instance();
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterRegistry.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterRegistry.h
new file mode 100644
index 0000000000..3caecd25a4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageMetaDataWriterRegistry.h
@@ -0,0 +1,98 @@
+//----------------------------------------------------------------------------
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//----------------------------------------------------------------------------
+// $Id: ossimImageMetaDataWriterRegistry.h,v 1.6 2005/08/08 22:01:32 dburken Exp $
+
+#ifndef ossimImageMetaDataWriterRegistry_HEADER
+#define ossimImageMetaDataWriterRegistry_HEADER
+#include <imaging/factory/ossimImageMetaDataWriterFactoryBase.h>
+#include <base/common/ossimRefPtr.h>
+
+class ossimMetadataFileWriter;
+
+class OSSIMDLLEXPORT ossimImageMetaDataWriterRegistry :
+   public ossimImageMetaDataWriterFactoryBase
+{
+public:
+   ~ossimImageMetaDataWriterRegistry();
+   
+   static ossimImageMetaDataWriterRegistry* instance();
+   
+   void registerFactory(ossimImageMetaDataWriterFactoryBase* factory);
+   void unregisterFactory(ossimImageMetaDataWriterFactoryBase* factory);
+   bool findFactory(ossimImageMetaDataWriterFactoryBase* factory)const;
+   /**
+    * Creates an object given a type name.
+    */
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /**
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+
+   /**
+    * Creates a writer from either a class name or a string representing the
+    * meta data type like "tiff_world_file".
+    *
+    * @return ossimRefPtr<ossimMetadataFileWriter>
+    *
+    * @note Return can have a null pointer if type is not found in a factory so
+    * the caller should always check the pointer like:
+    * ossimRefPtr<ossimMetadataFileWriter> mw =
+    *    ossimImageMetaDataWriterRegistry::instance("ossim_readme");
+    * if (!mw.valid())
+    * {
+    *    // not in factory
+    * }
+    */
+   virtual ossimRefPtr<ossimMetadataFileWriter> createWriter(
+      const ossimString& type)const;
+   
+   /**
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /**
+    * Initializes list with meta data types from all registered
+    * metadata factories.
+    * 
+    * This is the actual image type name like:
+    *   ossim_geometry
+    *   envi_header
+    *   tiff_world_file
+    *   jpeg_world_file
+    *   
+    * @param metadatatypeList stl::vector<ossimString> list to append to.
+    *
+    * @note Since this is the master registry for all meta data factories
+    * this method starts by clearing the metadatatypeList.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList)const;
+   
+protected:
+   ossimImageMetaDataWriterRegistry();
+
+   ossimImageMetaDataWriterRegistry(
+      const ossimImageMetaDataWriterRegistry& rhs);
+   
+   const ossimImageMetaDataWriterRegistry& operator=(
+      const ossimImageMetaDataWriterRegistry &rhs);
+
+   static ossimImageMetaDataWriterRegistry* theInstance;
+   std::vector<ossimImageMetaDataWriterFactoryBase*> theFactoryList;
+};
+
+
+extern "C"
+{
+   OSSIMDLLEXPORT void* ossimImageMetaDataWriterRegistryGetInstance();
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterFactory.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterFactory.cpp
new file mode 100644
index 0000000000..f4ef8bca43
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterFactory.cpp
@@ -0,0 +1,86 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimImageReconstructionFilterFactory.cpp,v 1.3 2004/08/30 11:23:26 gpotts Exp $
+#include "ossimImageReconstructionFilterFactory.h"
+#include "base/common/ossimTrace.h"
+#include "imaging/reconstruction/ossimMeanMedianFilter.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimImageReconstructionFilterFactory, "ossimImageReconstructionFilterFactory",  ossimImageSourceFactoryBase);
+
+ossimImageReconstructionFilterFactory* ossimImageReconstructionFilterFactory::theInstance = 0;
+
+ossimImageReconstructionFilterFactory::~ossimImageReconstructionFilterFactory()
+{
+   theInstance = NULL;
+}
+
+ossimImageReconstructionFilterFactory* ossimImageReconstructionFilterFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimImageReconstructionFilterFactory;
+   }
+
+   return theInstance;
+}
+
+ossimImageReconstructionFilterFactory::ossimImageReconstructionFilterFactory()
+{
+   theInstance = this;
+}
+
+ossimObject* ossimImageReconstructionFilterFactory::createObject(const ossimString& name)const
+{
+   if(STATIC_TYPE_NAME(ossimMeanMedianFilter) == name)
+   {
+      return new ossimMeanMedianFilter;
+   }
+
+   return 0;
+}
+
+ossimObject* ossimImageReconstructionFilterFactory::createObject(const ossimKeywordlist& kwl,
+                                                                 const char* prefix)const
+{
+   const char* typeKw = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+
+   if(typeKw)
+   {
+      ossimObject* obj = createObject(ossimString(typeKw).trim());
+
+      if(obj)
+      {
+         obj->loadState(kwl,
+                        prefix);
+         
+         return obj;
+      }
+   }
+   
+   return 0;
+}
+
+void ossimImageReconstructionFilterFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   typeList.push_back(STATIC_TYPE_NAME(ossimMeanMedianFilter));
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterFactory.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterFactory.h
new file mode 100644
index 0000000000..ac91f0704d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterFactory.h
@@ -0,0 +1,47 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimImageReconstructionFilterFactory.h,v 1.1 2004/01/21 14:57:25 gpotts Exp $
+#ifndef ossimImageReconstructionFilterFactory_HEADER
+#define ossimImageReconstructionFilterFactory_HEADER
+#include "ossimImageSourceFactoryBase.h"
+
+class ossimImageReconstructionFilterFactory : public ossimImageSourceFactoryBase
+{
+public:
+   virtual ~ossimImageReconstructionFilterFactory();
+   static ossimImageReconstructionFilterFactory* instance();
+   virtual ossimObject* createObject(const ossimString& name)const;
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   
+protected:
+   ossimImageReconstructionFilterFactory(); // hide
+   ossimImageReconstructionFilterFactory(const ossimImageReconstructionFilterFactory&){}//hide
+   void operator = (ossimImageReconstructionFilterFactory&){}// hide
+
+   static ossimImageReconstructionFilterFactory* theInstance;
+   
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterRegistry.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterRegistry.cpp
new file mode 100644
index 0000000000..53cf74e765
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterRegistry.cpp
@@ -0,0 +1,126 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimImageReconstructionFilterRegistry.cpp,v 1.3 2005/10/17 18:42:27 gpotts Exp $
+#include <algorithm>
+#include "ossimImageReconstructionFilterRegistry.h"
+#include "ossimImageReconstructionFilterFactory.h"
+
+ossimImageReconstructionFilterRegistry* ossimImageReconstructionFilterRegistry::theInstance = 0;
+
+RTTI_DEF1(ossimImageReconstructionFilterRegistry, "ossimImageReconstructionFilterRegistry", ossimImageSourceFactoryBase);
+
+ossimImageReconstructionFilterRegistry::ossimImageReconstructionFilterRegistry()
+{
+   theInstance = this;
+}
+
+ossimImageReconstructionFilterRegistry::~ossimImageReconstructionFilterRegistry()
+{
+   theInstance = NULL;
+}
+
+ossimImageReconstructionFilterRegistry* ossimImageReconstructionFilterRegistry::instance()
+{
+  if(theInstance == NULL)
+  {
+     theInstance = new ossimImageReconstructionFilterRegistry;
+     theInstance->registerFactory(ossimImageReconstructionFilterFactory::instance());
+  }
+  return theInstance;
+}
+
+ossimObject* ossimImageReconstructionFilterRegistry::createObject(const ossimString& name)const
+{
+   ossimObject*                   result = NULL;
+   std::vector<ossimImageSourceFactoryBase*>::const_iterator factory;
+
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+     result = (*factory)->createObject(name);
+     ++factory;
+   }
+   
+   return result;
+}
+
+ossimObject* ossimImageReconstructionFilterRegistry::createObject(const ossimKeywordlist& kwl,
+							   const char* prefix)const
+{
+   ossimObject*                   result = NULL;
+   std::vector<ossimImageSourceFactoryBase*>::const_iterator factory;
+
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+     result = (*factory)->createObject(kwl, prefix);
+     ++factory;
+   }
+   
+   return result;
+ 
+}
+
+void ossimImageReconstructionFilterRegistry::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   std::vector<ossimString> result;
+   std::vector<ossimImageSourceFactoryBase*>::const_iterator iter = theFactoryList.begin();
+
+   while(iter != theFactoryList.end())
+   {
+      result.clear();
+      (*iter)->getTypeNameList(result);
+
+      // now append to the end of the typeList.
+      typeList.insert(typeList.end(),
+                      result.begin(),
+                      result.end());
+      ++iter;
+   }
+  
+}
+
+void ossimImageReconstructionFilterRegistry::registerFactory(ossimImageSourceFactoryBase* factory)
+{
+  if(factory&&!findFactory(factory))
+  {
+     theFactoryList.push_back(factory);
+  }
+}
+
+void ossimImageReconstructionFilterRegistry::unregisterFactory(ossimImageSourceFactoryBase* factory)
+{
+   std::vector<ossimImageSourceFactoryBase*>::iterator iter =  std::find(theFactoryList.begin(),
+                                                                          theFactoryList.end(),
+                                                                          factory);
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+}
+
+bool ossimImageReconstructionFilterRegistry::findFactory(ossimImageSourceFactoryBase* factory)const
+{
+   return (std::find(theFactoryList.begin(),
+                     theFactoryList.end(),
+                     factory)!=theFactoryList.end());
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterRegistry.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterRegistry.h
new file mode 100644
index 0000000000..aea8ea6ea2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageReconstructionFilterRegistry.h
@@ -0,0 +1,51 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimImageReconstructionFilterRegistry.h,v 1.1 2004/01/21 14:57:25 gpotts Exp $
+#ifndef ossimImageReconstructionFilterRegistry_HEADER
+#define ossimImageReconstructionFilterRegistry_HEADER
+#include "ossimImageSourceFactoryBase.h"
+
+class ossimImageReconstructionFilterRegistry : public ossimImageSourceFactoryBase
+{
+public:
+   virtual ~ossimImageReconstructionFilterRegistry();
+   static ossimImageReconstructionFilterRegistry* instance();
+   virtual ossimObject* createObject(const ossimString& name)const;
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+   void registerFactory(ossimImageSourceFactoryBase* factory);
+   void unregisterFactory(ossimImageSourceFactoryBase* factory);
+   bool findFactory(ossimImageSourceFactoryBase* factory)const;
+   
+protected:
+   ossimImageReconstructionFilterRegistry(); // hide
+   ossimImageReconstructionFilterRegistry(const ossimImageReconstructionFilterRegistry&){}//hide
+   void operator = (ossimImageReconstructionFilterRegistry&){}// hide
+   
+   static ossimImageReconstructionFilterRegistry* theInstance;
+   std::vector<ossimImageSourceFactoryBase*> theFactoryList;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactory.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactory.cpp
new file mode 100644
index 0000000000..8c59dd272f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactory.cpp
@@ -0,0 +1,551 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: This is the image source factory.
+//              It will try to create image filters
+//              first then it will try the image writers
+//              and image handlers (image readers)
+//
+//*************************************************************************
+// $Id: ossimImageSourceFactory.cpp,v 1.96 2005/12/22 15:32:59 gpotts Exp $
+
+#include <imaging/factory/ossimImageSourceFactory.h>
+#include <imaging/tile_sources/ossimConvolutionFilter1D.h>
+#include <imaging/tile_sources/ossimImageGaussianFilter.h>
+#include <imaging/tile_sources/ossimImageRenderer.h>
+#include <imaging/tile_sources/ossimCacheTileSource.h>
+#include <imaging/tile_sources/ossimFeatherMosaic.h>
+#include <imaging/tile_sources/ossimHistogramRemapper.h>
+#include <imaging/tile_sources/ossimImageMosaic.h>
+#include <imaging/tile_sources/ossimClosestToCenterCombiner.h>
+#include <imaging/tile_sources/ossimBlendMosaic.h>
+#include <imaging/tile_sources/ossimMaxMosaic.h>
+#include <imaging/tile_sources/ossimOrthoImageMosaic.h>
+#include <imaging/tile_sources/ossimColorNormalizedFusion.h>
+#include <imaging/tile_sources/ossimLocalCorrelationFusion.h>
+#include <imaging/tile_sources/ossimSFIMFusion.h>
+#include <imaging/tile_sources/ossimTopographicCorrectionFilter.h>
+#include <imaging/tile_sources/ossimBandSelector.h>
+#include <imaging/tile_sources/ossimNBandToIndexFilter.h>
+#include <imaging/tile_sources/ossimRgbToGreyFilter.h>
+#include <imaging/tile_sources/ossimRgbToJpegYCbCrSource.h>
+#include <imaging/tile_sources/ossimRgbToHsvSource.h>
+#include <imaging/tile_sources/ossimRgbToHsiSource.h>
+#include <imaging/tile_sources/ossimHsiToRgbSource.h>
+#include <imaging/tile_sources/ossimHsvToRgbSource.h>
+#include <imaging/tile_sources/ossimHsiRemapper.h>
+#include <imaging/tile_sources/ossimJpegYCbCrToRgbSource.h>
+#include <imaging/tile_sources/ossimPolyCutter.h>
+#include <imaging/tile_sources/ossimGeoPolyCutter.h>
+#include <imaging/tile_sources/ossimHistogramEqualization.h>
+#include <imaging/tile_sources/ossimHistogramMatchFilter.h>
+#include <imaging/tile_sources/ossimHistogramThreshholdFilter.h>
+#include <imaging/tile_sources/ossimConvolutionSource.h>
+#include <imaging/tile_sources/ossimBrightnessContrastSource.h>
+#include <imaging/tile_sources/ossimBrightnessMatch.h>
+#include <imaging/tile_sources/ossimScalarRemapper.h>
+#include <imaging/tile_sources/ossimBandMergeSource.h>
+#include <imaging/tile_sources/ossimIndexToRgbLutFilter.h>
+#include <imaging/tile_sources/ossimBumpShadeTileSource.h>
+#include <imaging/tile_sources/ossimSubImageTileSource.h>
+#include <imaging/tile_sources/ossimRLevelFilter.h>
+#include <imaging/tile_sources/ossimBandClipFilter.h>
+#include <imaging/tile_sources/ossimValueAssignImageSourceFilter.h>
+#include <imaging/tile_sources/ossimImageSharpenFilter.h>
+#include <imaging/tile_sources/ossim3x3ConvolutionFilter.h>
+#include <imaging/tile_sources/ossimCastTileSourceFilter.h>
+#include <imaging/tile_sources/ossimEquationCombiner.h>
+#include <imaging/tile_sources/ossimMaskFilter.h>
+#include <imaging/misc/ossimPixelFlipper.h>
+#include <imaging/elevation/ossimElevImageSource.h>
+#include <imaging/tile_sources/ossimLandsatTopoCorrectionFilter.h>
+#include <imaging/annotation/ossimGeoAnnotationSource.h>
+#include <imaging/annotation/ossimEsriShapeFileFilter.h>
+#include <imaging/tile_sources/ossimEsriShapeFileCutter.h>
+#include <imaging/annotation/ossimMapCompositionSource.h>
+#include <imaging/tile_sources/ossimScaleFilter.h>
+#include <imaging/tile_sources/ossimEastingNorthingCutter.h>
+#include <imaging/tile_sources/ossimEdgeFilter.h>
+#include <imaging/tile_sources/ossimFftFilter.h>
+#include <imaging/tile_sources/ossimWatermarkFilter.h>
+#include <imaging/tile_sources/ossimTrimFilter.h>
+
+
+#include <imaging/tonal_balance/ossimGridRemapSource.h>
+
+// Not sure if we want to keep this here
+#include <imaging/tonal_balance/ossimAtbController.h>
+
+#include <imaging/ossimImageChain.h>
+#include <imaging/histogram/ossimHistogramWriter.h>
+#include <imaging/tile_sources/ossimRectangleCutFilter.h>
+
+
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <imaging/histogram/ossimImageHistogramSource.h>
+
+#include <imaging/tile_sources/ossimMultiBandHistogramTileSource.h>
+
+#include <imaging/tile_sources/ossimBandAverageFilter.h>
+#include <imaging/tile_sources/ossimImageToPlaneNormalFilter.h>
+
+#include <imaging/atmospheric_correction/ossimAtCorrGridRemapper.h>
+#include <imaging/atmospheric_correction/ossimAtCorrRemapper.h>
+
+#include <base/common/ossimTrace.h>
+
+RTTI_DEF1(ossimImageSourceFactory, "ossimImageSourceFactory", ossimImageSourceFactoryBase);
+
+static ossimTrace traceDebug("ossimImageSourceFactory:debug");
+
+ossimImageSourceFactory* ossimImageSourceFactory::theInstance=NULL;
+
+ossimImageSourceFactory::~ossimImageSourceFactory()
+{
+   theInstance = NULL;
+   ossimObjectFactoryRegistry::instance()->unregisterFactory(this);
+}
+ossimImageSourceFactory* ossimImageSourceFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimImageSourceFactory;
+   }
+
+   return theInstance;
+}
+
+ossimObject* ossimImageSourceFactory::createObject(const ossimString& name)const
+{
+
+   // lets do the filters first
+   if( name == STATIC_TYPE_NAME(ossimBandSelector) ||
+       name == "ossimNativeBandSelectorTileSource" ) 
+   {
+      //---
+      // For backwards compatibility check old name:
+      // "ossimNativeBandSelectorTileSource"
+      //---
+      return new ossimBandSelector;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimImageRenderer))
+   {
+      return new ossimImageRenderer;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimCacheTileSource))
+   {
+      return new ossimCacheTileSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimColorNormalizedFusion))
+   {
+      return new ossimColorNormalizedFusion;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimLocalCorrelationFusion))
+   {
+      return new ossimLocalCorrelationFusion;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimSFIMFusion))
+   {
+      return new ossimSFIMFusion;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimBlendMosaic))
+   {
+      return new ossimBlendMosaic;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimMaxMosaic))
+   {
+      return new ossimMaxMosaic;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimHistogramRemapper))
+   {
+      return new ossimHistogramRemapper;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimImageMosaic))
+   {
+      return new ossimImageMosaic;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimClosestToCenterCombiner))
+   {
+      return new ossimClosestToCenterCombiner;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimRgbToGreyFilter))
+   {
+      return new ossimRgbToGreyFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimNBandToIndexFilter))
+   {
+      return new ossimNBandToIndexFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimImageChain))
+   {
+      return new ossimImageChain;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimPolyCutter))
+   {
+      return new ossimPolyCutter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimGeoPolyCutter))
+   {
+      return new ossimGeoPolyCutter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimJpegYCbCrToRgbSource))
+   {
+      return new ossimJpegYCbCrToRgbSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimRgbToJpegYCbCrSource))
+   {
+      return new ossimRgbToJpegYCbCrSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimHsiToRgbSource))
+   {
+      return new ossimHsiToRgbSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimRgbToHsiSource))
+   {
+      return new ossimRgbToHsiSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimHsvToRgbSource))
+   {
+      return new ossimHsvToRgbSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimRgbToHsvSource))
+   {
+      return new ossimRgbToHsvSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimHistogramEqualization))
+   {
+      return new ossimHistogramEqualization;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimHistogramMatchFilter))
+   {
+      return new ossimHistogramMatchFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimHistogramThreshholdFilter))
+   {
+      return new ossimHistogramThreshholdFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimGeoAnnotationSource))
+   {
+      return new ossimGeoAnnotationSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimConvolutionSource))
+   {
+      return new ossimConvolutionSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimBrightnessContrastSource))
+   {
+      return new ossimBrightnessContrastSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimBrightnessMatch))
+   {
+      return new ossimBrightnessMatch;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimScalarRemapper))
+   {
+      return new ossimScalarRemapper;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimBandMergeSource))
+   {
+      return new ossimBandMergeSource;
+   }  
+   else if(name == STATIC_TYPE_NAME(ossimFeatherMosaic))
+   {
+      return new ossimFeatherMosaic;
+   }  
+   else if(name == STATIC_TYPE_NAME(ossimGridRemapSource))
+   {
+      return new ossimGridRemapSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimEquationCombiner))
+   {
+      return new ossimEquationCombiner;
+   }
+   // Not sure if we want to keep this here
+   else if(name == STATIC_TYPE_NAME(ossimAtbController))
+   {
+      return new ossimAtbController;
+   }  
+   else if(name == STATIC_TYPE_NAME(ossimIndexToRgbLutFilter))
+   {
+      return new ossimIndexToRgbLutFilter;
+   }
+   else if(name ==  STATIC_TYPE_NAME(ossimBumpShadeTileSource))
+   {
+      return new ossimBumpShadeTileSource;
+   }
+   else if(name ==  STATIC_TYPE_NAME(ossimSubImageTileSource))
+   {
+      return new ossimSubImageTileSource;
+   }
+   else if(name ==  STATIC_TYPE_NAME(ossimRLevelFilter))
+   {
+      return new ossimRLevelFilter;
+   }
+   else if(name ==  STATIC_TYPE_NAME(ossimBandClipFilter))
+   {
+      return new ossimBandClipFilter;
+   }
+   else if(name ==  STATIC_TYPE_NAME(ossimHsiRemapper))
+   {
+      return new ossimHsiRemapper;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimHistogramWriter))
+   {
+      return new ossimHistogramWriter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimImageHistogramSource))
+   {
+      return new ossimImageHistogramSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimRectangleCutFilter))
+   {
+      return new ossimRectangleCutFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimCastTileSourceFilter))
+   {
+      return new ossimCastTileSourceFilter;
+   }
+   // all the image handlers
+   else if(name == STATIC_TYPE_NAME(ossimValueAssignImageSourceFilter))
+   {
+      return new ossimValueAssignImageSourceFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimImageSharpenFilter))
+   {
+      return new ossimImageSharpenFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossim3x3ConvolutionFilter))
+   {
+      return new ossim3x3ConvolutionFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimEsriShapeFileFilter))
+   {
+      return new ossimEsriShapeFileFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimEsriShapeFileCutter))
+   {
+      return new ossimEsriShapeFileCutter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimOrthoImageMosaic))
+   {
+      return new ossimOrthoImageMosaic;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimMapCompositionSource))
+   {
+      return new ossimMapCompositionSource;
+   }
+   else if(name ==  STATIC_TYPE_NAME(ossimElevImageSource))
+   {
+      return new ossimElevImageSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimMaskFilter))
+   {
+      return new ossimMaskFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimMultiBandHistogramTileSource))
+   {
+      return new ossimMultiBandHistogramTileSource;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimBandAverageFilter))
+   {
+      return new ossimBandAverageFilter;
+   }
+   else if(name == STATIC_TYPE_NAME(ossimPixelFlipper))
+   {
+      return new ossimPixelFlipper();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimScaleFilter))
+   {
+      return new ossimScaleFilter();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimImageToPlaneNormalFilter))
+   {
+      return new ossimImageToPlaneNormalFilter();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimTopographicCorrectionFilter))
+   {
+      return new ossimTopographicCorrectionFilter();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimLandsatTopoCorrectionFilter))
+   {
+      return new ossimLandsatTopoCorrectionFilter();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimAtCorrRemapper))
+   {
+      return new ossimAtCorrRemapper();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimAtCorrGridRemapper))
+   {
+      return new ossimAtCorrGridRemapper();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimEastingNorthingCutter))
+   {
+      return new ossimEastingNorthingCutter();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimEdgeFilter))
+   {
+      return new ossimEdgeFilter();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimFftFilter))
+   {
+      return new ossimFftFilter();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimWatermarkFilter))
+   {
+      return new ossimWatermarkFilter();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimConvolutionFilter1D))
+   {
+      return new ossimConvolutionFilter1D(); 
+   }
+   else if(name == STATIC_TYPE_NAME(ossimImageGaussianFilter))
+   {
+      return new ossimImageGaussianFilter();
+   }
+   else if(name == STATIC_TYPE_NAME(ossimTrimFilter))
+   {
+      return new ossimTrimFilter();
+   }
+   return NULL;
+}
+
+ossimObject* ossimImageSourceFactory::createObject(const ossimKeywordlist& kwl,
+                                                   const char* prefix)const
+{
+   static const char* MODULE = "ossimImageSourceFactory::createSource";
+   
+   ossimString copyPrefix = prefix;
+   ossimObject* result = NULL;
+   
+   if(traceDebug())
+   {
+      CLOG << "looking up type keyword for prefix = " << copyPrefix << endl;
+   }
+
+   const char* lookup = kwl.find(copyPrefix, "type");
+   if(lookup)
+   {
+      ossimString name = lookup;
+      result           = createObject(name);
+      
+      if(result)
+      {
+         if(traceDebug())
+         {
+            CLOG << "found source " << result->getClassName() << " now loading state" << endl;
+         }
+         result->loadState(kwl, copyPrefix.c_str());
+      }
+      else
+      {
+         if(traceDebug())
+         {
+            CLOG << "type not found " << lookup << endl;
+         }
+      }
+   }
+   else
+   {
+      if(traceDebug())
+      {
+         CLOG << "type keyword not found" << endl;
+      }
+   }
+   return result;
+}
+
+void ossimImageSourceFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   typeList.push_back(STATIC_TYPE_NAME(ossimBandSelector));
+   typeList.push_back(STATIC_TYPE_NAME(ossimImageRenderer));
+   typeList.push_back(STATIC_TYPE_NAME(ossimCacheTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimBlendMosaic));
+   typeList.push_back(STATIC_TYPE_NAME(ossimMaxMosaic));   
+   typeList.push_back(STATIC_TYPE_NAME(ossimColorNormalizedFusion));
+   typeList.push_back(STATIC_TYPE_NAME(ossimLocalCorrelationFusion));
+   typeList.push_back(STATIC_TYPE_NAME(ossimSFIMFusion));
+   typeList.push_back(STATIC_TYPE_NAME(ossimHistogramRemapper));
+   typeList.push_back(STATIC_TYPE_NAME(ossimImageMosaic));
+   typeList.push_back(STATIC_TYPE_NAME(ossimClosestToCenterCombiner));
+   typeList.push_back(STATIC_TYPE_NAME(ossimRgbToGreyFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimNBandToIndexFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimImageChain));
+   typeList.push_back(STATIC_TYPE_NAME(ossimPolyCutter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimGeoPolyCutter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimJpegYCbCrToRgbSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimRgbToJpegYCbCrSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimHsiToRgbSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimRgbToHsiSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimHsvToRgbSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimRgbToHsvSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimHistogramEqualization));
+   typeList.push_back(STATIC_TYPE_NAME(ossimHistogramMatchFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimHistogramThreshholdFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimGeoAnnotationSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimConvolutionSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimBrightnessContrastSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimBrightnessMatch));
+   typeList.push_back(STATIC_TYPE_NAME(ossimScalarRemapper));
+   typeList.push_back(STATIC_TYPE_NAME(ossimBandMergeSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimFeatherMosaic));
+   typeList.push_back(STATIC_TYPE_NAME(ossimGridRemapSource));
+   // Not sure if we want to keep this here
+   typeList.push_back(STATIC_TYPE_NAME(ossimAtbController));
+   typeList.push_back(STATIC_TYPE_NAME(ossimIndexToRgbLutFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimBumpShadeTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimSubImageTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimRLevelFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimBandClipFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimHsiRemapper));
+   typeList.push_back(STATIC_TYPE_NAME(ossimHistogramWriter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimImageHistogramSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimRectangleCutFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimElevImageSource));
+   
+   typeList.push_back(STATIC_TYPE_NAME(ossimValueAssignImageSourceFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimImageSharpenFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossim3x3ConvolutionFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimEsriShapeFileFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimEsriShapeFileCutter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimOrthoImageMosaic));
+   typeList.push_back(STATIC_TYPE_NAME(ossimMapCompositionSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimCastTileSourceFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimEquationCombiner));
+   typeList.push_back(STATIC_TYPE_NAME(ossimMaskFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimMultiBandHistogramTileSource));
+   typeList.push_back(STATIC_TYPE_NAME(ossimBandAverageFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimPixelFlipper));
+   typeList.push_back(STATIC_TYPE_NAME(ossimScaleFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimImageToPlaneNormalFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimTopographicCorrectionFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimLandsatTopoCorrectionFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimAtCorrRemapper));
+   typeList.push_back(STATIC_TYPE_NAME(ossimAtCorrGridRemapper));
+   typeList.push_back(STATIC_TYPE_NAME(ossimEastingNorthingCutter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimEdgeFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimFftFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimWatermarkFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimConvolutionFilter1D));
+   typeList.push_back(STATIC_TYPE_NAME(ossimImageGaussianFilter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimTrimFilter));
+}
+
+// Hide from use...
+ossimImageSourceFactory::ossimImageSourceFactory()
+   :ossimImageSourceFactoryBase()
+{}
+
+ossimImageSourceFactory::ossimImageSourceFactory(const ossimImageSourceFactory&)
+   :ossimImageSourceFactoryBase()
+{}
+
+const ossimImageSourceFactory& ossimImageSourceFactory::operator=(ossimImageSourceFactory&)
+{
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactory.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactory.h
new file mode 100644
index 0000000000..381ee22e3c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactory.h
@@ -0,0 +1,46 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimImageSourceFactory.h,v 1.5 2004/01/30 23:30:24 dburken Exp $
+#ifndef ossimImageSourceFactory_HEADER
+#define ossimImageSourceFactory_HEADER
+#include "ossimImageSourceFactoryBase.h"
+
+class ossimImageSourceFactory : public ossimImageSourceFactoryBase
+{
+public:
+   virtual ~ossimImageSourceFactory();
+   static ossimImageSourceFactory* instance();
+   virtual ossimObject* createObject(const ossimString& name)const;
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+protected:
+   // Hide from use.
+   ossimImageSourceFactory();
+   ossimImageSourceFactory(const ossimImageSourceFactory&);
+   const ossimImageSourceFactory& operator=(ossimImageSourceFactory&);
+
+   static ossimImageSourceFactory* theInstance;
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryBase.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryBase.cpp
new file mode 100644
index 0000000000..0ac62c2fb3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryBase.cpp
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2004 ImageLinks Inc. All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: David Burken <dburken@imagelinks.com>
+//
+//*************************************************************************
+// $Id: ossimImageSourceFactoryBase.cpp,v 1.2 2004/08/26 19:14:35 gpotts Exp $
+
+#include <imaging/factory/ossimImageSourceFactoryBase.h>
+#include <imaging/ossimImageSource.h>
+ossimImageSourceFactoryBase::ossimImageSourceFactoryBase()
+   : ossimObjectFactory()
+{}
+
+ossimImageSourceFactoryBase::ossimImageSourceFactoryBase(const ossimImageSourceFactoryBase&)
+   : ossimObjectFactory()
+{}
+
+const ossimImageSourceFactoryBase& ossimImageSourceFactoryBase::operator=(const ossimImageSourceFactoryBase&)
+{
+   return *this;
+}
+
+ossimImageSource* ossimImageSourceFactoryBase::createImageSource(const ossimString& name)const
+{
+   ossimObject* result =createObject(name);
+   
+   if(PTR_CAST(ossimImageSource, result))
+   {
+      return (ossimImageSource*)result;
+   }
+
+   if(result)
+   {
+      delete result;
+      result = NULL;
+   }
+
+   return (ossimImageSource*)NULL;
+}
+
+ossimImageSource* ossimImageSourceFactoryBase::createImageSource(const ossimKeywordlist& kwl,
+                                                                 const char* prefix)const
+{
+   ossimObject* result =createObject(kwl, prefix);
+   
+   if(PTR_CAST(ossimImageSource, result))
+   {
+      return (ossimImageSource*)result;
+   }
+
+   if(result)
+   {
+      delete result;
+      result = NULL;
+   }
+
+   return (ossimImageSource*)NULL;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryBase.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryBase.h
new file mode 100644
index 0000000000..5ac16fddef
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryBase.h
@@ -0,0 +1,46 @@
+//*******************************************************************
+// Copyright (C) 2004 ImageLinks Inc. All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts  <gpotts@imagelinks.com>
+//
+//*************************************************************************
+// $Id: ossimImageSourceFactoryBase.h,v 1.4 2004/08/31 19:15:57 gpotts Exp $
+#ifndef ossimImageSourceFactoryBase_HEADER
+#define ossimImageSourceFactoryBase_HEADER
+#include "base/factory/ossimObjectFactory.h"
+class ossimImageSource;
+
+class OSSIMDLLEXPORT ossimImageSourceFactoryBase : public ossimObjectFactory
+{
+public:
+   /*!
+    * Convenient conversion method.  Gurantees an ossimImageSource is returned.  Returns
+    * NULL otherwise
+    */
+   virtual ossimImageSource* createImageSource(const ossimString& name)const;
+   virtual ossimImageSource* createImageSource(const ossimKeywordlist& kwl,
+                                               const char* prefix=0)const;
+   
+protected:
+   // Hide from use.
+   ossimImageSourceFactoryBase();
+   ossimImageSourceFactoryBase(const ossimImageSourceFactoryBase&);
+   const ossimImageSourceFactoryBase& operator=(const ossimImageSourceFactoryBase&);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryRegistry.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryRegistry.cpp
new file mode 100644
index 0000000000..cebc752f0f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryRegistry.cpp
@@ -0,0 +1,144 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimImageSourceFactoryRegistry.cpp,v 1.7 2005/10/17 18:42:27 gpotts Exp $
+#include <algorithm>
+#include "ossimImageSourceFactoryRegistry.h"
+#include "ossimImageSourceFactory.h"
+#include "ossimImageReconstructionFilterRegistry.h"
+
+ossimImageSourceFactoryRegistry* ossimImageSourceFactoryRegistry::theInstance = NULL;
+
+RTTI_DEF1(ossimImageSourceFactoryRegistry, "ossimImageSourceFactoryRegistry", ossimImageSourceFactoryBase);
+
+ossimImageSourceFactoryRegistry::ossimImageSourceFactoryRegistry()
+{
+   theInstance = this;
+}
+
+ossimImageSourceFactoryRegistry::~ossimImageSourceFactoryRegistry()
+{
+   theInstance->unregisterFactory(ossimImageSourceFactory::instance());
+   
+   theInstance = NULL;
+}
+
+ossimImageSourceFactoryRegistry* ossimImageSourceFactoryRegistry::instance()
+{
+  if(theInstance == NULL)
+  {
+    theInstance = new ossimImageSourceFactoryRegistry;
+    theInstance->registerFactory(ossimImageSourceFactory::instance());
+    theInstance->registerFactory(ossimImageReconstructionFilterRegistry::instance());
+  }
+  return theInstance;
+}
+
+ossimObject* ossimImageSourceFactoryRegistry::createObject(const ossimString& name)const
+{
+   ossimObject*                   result = NULL;
+   std::vector<ossimImageSourceFactoryBase*>::const_iterator factory;
+
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+     result = (*factory)->createObject(name);
+     ++factory;
+   }
+   
+   return result;
+}
+
+ossimObject* ossimImageSourceFactoryRegistry::createObject(const ossimKeywordlist& kwl,
+							   const char* prefix)const
+{
+   ossimObject*                   result = NULL;
+   std::vector<ossimImageSourceFactoryBase*>::const_iterator factory;
+
+   factory = theFactoryList.begin();
+   while((factory != theFactoryList.end()) && !result)
+   {
+     result = (*factory)->createObject(kwl, prefix);
+     ++factory;
+   }
+   
+   return result;
+ 
+}
+
+void ossimImageSourceFactoryRegistry::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   std::vector<ossimString> result;
+   std::vector<ossimImageSourceFactoryBase*>::const_iterator iter = theFactoryList.begin();
+
+   while(iter != theFactoryList.end())
+   {
+      result.clear();
+      (*iter)->getTypeNameList(result);
+
+      // now append to the end of the typeList.
+      typeList.insert(typeList.end(),
+                      result.begin(),
+                      result.end());
+      ++iter;
+   }
+  
+}
+
+void ossimImageSourceFactoryRegistry::registerFactory(ossimImageSourceFactoryBase* factory)
+{
+  if(factory&&!findFactory(factory))
+  {
+     theFactoryList.push_back(factory);
+  }
+}
+
+void ossimImageSourceFactoryRegistry::unregisterFactory(ossimImageSourceFactoryBase* factory)
+{
+   std::vector<ossimImageSourceFactoryBase*>::iterator iter =  std::find(theFactoryList.begin(),
+                                                                          theFactoryList.end(),
+                                                                          factory);
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+}
+
+bool ossimImageSourceFactoryRegistry::findFactory(ossimImageSourceFactoryBase* factory)const
+{
+   return (std::find(theFactoryList.begin(),
+                     theFactoryList.end(),
+                     factory)!=theFactoryList.end());
+}
+
+void* ossimImageSourceFactoryRegistryGetInstance()
+{
+  return ossimImageSourceFactoryRegistry::instance();
+}
+
+// Hidden
+ossimImageSourceFactoryRegistry::ossimImageSourceFactoryRegistry(const ossimImageSourceFactoryRegistry&)
+   : ossimImageSourceFactoryBase()
+{}
+
+// Hidden
+void ossimImageSourceFactoryRegistry::operator=(ossimImageSourceFactoryRegistry&)
+{}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryRegistry.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryRegistry.h
new file mode 100644
index 0000000000..41c2dc141d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageSourceFactoryRegistry.h
@@ -0,0 +1,55 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimImageSourceFactoryRegistry.h,v 1.5 2004/05/28 20:36:01 dburken Exp $
+#ifndef ossimImageSourceFactoryRegistry_HEADER
+#define ossimImageSourceFactoryRegistry_HEADER
+#include "ossimImageSourceFactoryBase.h"
+
+class OSSIMDLLEXPORT ossimImageSourceFactoryRegistry : public ossimImageSourceFactoryBase
+{
+public:
+   virtual ~ossimImageSourceFactoryRegistry();
+   static ossimImageSourceFactoryRegistry* instance();
+   virtual ossimObject* createObject(const ossimString& name)const;
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+   void registerFactory(ossimImageSourceFactoryBase* factory);
+   void unregisterFactory(ossimImageSourceFactoryBase* factory);
+   bool findFactory(ossimImageSourceFactoryBase* factory)const;
+   
+protected:
+   ossimImageSourceFactoryRegistry(); // hide
+   ossimImageSourceFactoryRegistry(const ossimImageSourceFactoryRegistry&);//hide
+   void operator = (ossimImageSourceFactoryRegistry&);// hide
+   
+   static ossimImageSourceFactoryRegistry* theInstance;
+   std::vector<ossimImageSourceFactoryBase*> theFactoryList;
+TYPE_DATA
+};
+
+extern "C"
+{
+  OSSIMDLLEXPORT void* ossimImageSourceFactoryRegistryGetInstance();
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactory.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactory.cpp
new file mode 100644
index 0000000000..92e91e6cb9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactory.cpp
@@ -0,0 +1,226 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimImageWriterFactory.cpp,v 1.10 2005/05/27 17:08:05 gpotts Exp $
+
+#include "ossimImageWriterFactory.h"
+#include "ossimImageWriterFactoryRegistry.h"
+#include <base/common/ossimKeywordNames.h>
+#include <imaging/formats/tiff/ossimTiffWriter.h>
+#include <imaging/formats/jpeg/ossimJpegWriter.h>
+#include <imaging/formats/general_raster/ossimGeneralRasterWriter.h>
+#include <imaging/formats/nitf/ossimNitfWriter.h>
+#include <base/misc/lookup_tables/ossimImageTypeLut.h>
+
+ossimImageWriterFactory* ossimImageWriterFactory::theInstance = (ossimImageWriterFactory*)NULL;
+
+
+ossimImageWriterFactory* ossimImageWriterFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimImageWriterFactory;
+      ossimImageWriterFactoryRegistry::instance()->
+         registerFactory(theInstance);
+   }
+
+   return theInstance;
+}
+
+ossimImageWriterFactory::~ossimImageWriterFactory()
+{
+   theInstance = (ossimImageWriterFactory*)NULL;
+}
+
+ossimImageFileWriter *ossimImageWriterFactory::createWriterFromExtension(const ossimString& fileExtension)const
+{
+   if((fileExtension == "tif")||
+      (fileExtension == "tiff"))
+   {
+      return new ossimTiffWriter;
+   }
+   else if((fileExtension == "jpg")||
+           (fileExtension == "jpeg"))
+   {
+      return new ossimJpegWriter;
+   }
+   else if(fileExtension == "ras")
+   {
+      return new ossimGeneralRasterWriter;
+   }
+   else if((fileExtension == "ntf")||
+           (fileExtension == "nitf"))
+   {
+      return new ossimNitfWriter;
+   }
+   
+   return NULL;
+}
+
+ossimImageFileWriter*
+ossimImageWriterFactory::createWriter(const ossimKeywordlist& kwl,
+                                      const char *prefix)const
+{
+   ossimString type = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   ossimImageFileWriter* result = (ossimImageFileWriter*)NULL;
+   
+   if(type != "")
+   {
+      result = createWriter(type);
+      if (result)
+      {
+         if (result->hasImageType(type))
+         {
+            ossimKeywordlist kwl2(kwl);
+            kwl2.add(prefix,
+                     ossimKeywordNames::IMAGE_TYPE_KW,
+                     type,
+                     true);
+         
+            result->loadState(kwl2, prefix);
+         }
+         else
+         {
+            result->loadState(kwl, prefix);
+         }
+      }
+   }
+
+   return result;
+}
+
+ossimImageFileWriter*
+ossimImageWriterFactory::createWriter(const ossimString& typeName)const
+{
+   // Check for tiff writer.
+   ossimImageFileWriter* writer = new ossimTiffWriter;
+   if (writer->getClassName() == typeName )
+   {
+      return writer;
+   }
+   else
+   {
+      // See if the type name is supported by the writer.
+      if ( writer->hasImageType(typeName) )
+      {
+         writer->setOutputImageType(typeName);
+         return writer;
+      }
+   }
+   delete writer; // Not a tiff writer.
+
+   // Check for jpeg writer.
+   writer = new ossimJpegWriter;
+   if ( writer->getClassName() == typeName )
+   {
+      return writer;
+   }
+   else
+   {
+      // See if the type name is supported by the writer.
+      if ( writer->hasImageType(typeName) )
+      {
+         writer->setOutputImageType(typeName);
+         return writer;
+      }
+   }
+   delete writer; // Not a jpeg writer.
+
+   // Check for general raster writer.
+   writer = new ossimGeneralRasterWriter;
+   if ( writer->getClassName() == typeName )
+   {
+      return writer;
+   }
+   else
+   {
+      // See if the type name is supported by the writer.
+      if ( writer->hasImageType(typeName) )
+      {
+         writer->setOutputImageType(typeName);
+         return writer;
+      }
+   }
+   delete writer; // Not a general raster writer.   
+
+   // Check for nitf writer.
+   writer = new ossimNitfWriter;
+   if ( writer->getClassName() == typeName )
+   {
+      return writer;
+   }
+   else
+   {
+      // See if the type name is supported by the writer.
+      if ( writer->hasImageType(typeName) )
+      {
+         writer->setOutputImageType(typeName);
+         return writer;
+      }
+   }
+   delete writer; // Not a nitf writer.   
+
+   writer = NULL;
+
+   return writer; // Return a null writer.
+}
+
+ossimObject* ossimImageWriterFactory::createObject(const ossimKeywordlist& kwl,
+                                                   const char *prefix)const
+{
+   return createWriter(kwl, prefix);
+}
+
+ossimObject* ossimImageWriterFactory::createObject(const ossimString& typeName)const
+{
+   return createWriter(typeName);
+}
+
+
+void ossimImageWriterFactory::getExtensions(std::vector<ossimString>& result)const
+{
+   result.push_back("ras");
+   result.push_back("tif");
+   result.push_back("jpg");
+   result.push_back("ntf");
+}
+
+void ossimImageWriterFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   typeList.push_back(STATIC_TYPE_NAME(ossimTiffWriter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimJpegWriter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimGeneralRasterWriter));
+   typeList.push_back(STATIC_TYPE_NAME(ossimNitfWriter));
+}
+
+void ossimImageWriterFactory::getImageTypeList(std::vector<ossimString>& imageTypeList)const
+{
+   // Add the tiff writer types.
+   ossimImageFileWriter* writer = new ossimTiffWriter;
+   writer->getImageTypeList(imageTypeList);
+   delete writer;
+
+   // Add the jpeg writer types.
+   writer = new ossimJpegWriter;
+   writer->getImageTypeList(imageTypeList);
+   delete writer;
+
+   // Add the general raster writer types.
+   writer = new ossimGeneralRasterWriter;
+   writer->getImageTypeList(imageTypeList);
+   delete writer;
+   writer = NULL;
+
+   // Add the nitf writer types.
+   writer = new ossimNitfWriter;
+   writer->getImageTypeList(imageTypeList);
+   delete writer;
+   writer = NULL;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactory.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactory.h
new file mode 100644
index 0000000000..8c254328cb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactory.h
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Frank Warmerdam (warmerda@home.com)
+//
+//*******************************************************************
+//  $Id: ossimImageWriterFactory.h,v 1.6 2004/12/10 16:46:36 gpotts Exp $
+
+#ifndef ossimImageWriterFactory_HEADER
+#define ossimImageWriterFactory_HEADER
+#include "ossimImageWriterFactoryBase.h"
+
+class ossimImageWriter;
+class ossimKeywordlist;
+
+class ossimImageWriterFactory: public ossimImageWriterFactoryBase
+{   
+public:
+   virtual ~ossimImageWriterFactory();
+   static ossimImageWriterFactory* instance();
+   
+   ossimImageFileWriter *createWriterFromExtension(const ossimString& fileExtension)const;
+   virtual ossimImageFileWriter* createWriter(const ossimKeywordlist& kwl,
+                                              const char *prefix=0)const;
+   virtual ossimImageFileWriter* createWriter(const ossimString& typeName)const;
+   
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char *prefix=0)const;
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+   
+   virtual void getExtensions(std::vector<ossimString>& result)const;
+   
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+   /*!
+    * getImageTypeList.  This is the actual image type name.  So for
+    * example, ossimTiffWriter has several image types.  Some of these
+    * include TIFF_TILED, TIFF_TILED_BAND_SEPARATE ... etc.  The
+    * ossimGdalWriter
+    * may include GDAL_IMAGINE_HFA, GDAL_RGB_NITF, GDAL_JPEG20000, ... etc
+    * A writer should be able to be instantiated by this name as well as a
+    * class name
+    */
+   virtual void getImageTypeList(std::vector<ossimString>& imageTypeList)const;
+   
+protected:
+   ossimImageWriterFactory() {}
+
+   static ossimImageWriterFactory* theInstance;
+
+
+   bool isImageTypeName(const ossimString& name)const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryBase.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryBase.cpp
new file mode 100644
index 0000000000..ccefb46984
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryBase.cpp
@@ -0,0 +1,26 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+//  $Id: ossimImageWriterFactoryBase.cpp,v 1.1 2002/03/26 20:41:04 gpotts Exp $
+#include "ossimImageWriterFactoryBase.h"
+
+RTTI_DEF1(ossimImageWriterFactoryBase, "ossimImageWriterFactoryBase", ossimObjectFactory);
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryBase.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryBase.h
new file mode 100644
index 0000000000..f13750f8ef
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryBase.h
@@ -0,0 +1,55 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+//  $Id: ossimImageWriterFactoryBase.h,v 1.7 2005/05/20 20:25:19 dburken Exp $
+#ifndef ossimImageWriterFactoryBase_HEADER
+#define ossimImageWriterFactoryBase_HEADER
+#include "base/factory/ossimObjectFactory.h"
+#include "base/data_types/ossimString.h"
+
+#include <vector>
+class ossimImageFileWriter;
+class ossimKeywordlist;
+
+class OSSIM_DLL ossimImageWriterFactoryBase : public ossimObjectFactory
+{   
+public:
+   virtual ~ossimImageWriterFactoryBase() {}
+   virtual ossimImageFileWriter *createWriterFromExtension(const ossimString& fileExtension)const=0;
+   virtual ossimImageFileWriter* createWriter(const ossimKeywordlist& kwl,
+                                          const char *prefix=0)const=0;
+   virtual ossimImageFileWriter* createWriter(const ossimString& typeName)const=0;
+
+   virtual void getExtensions(std::vector<ossimString>& result)const=0;
+   
+   /*!
+    * getImageTypeList.  This is the actual image type name.  So for
+    * example, ossimTiffWriter has several image types.  Some of these
+    * include tiff_tiled, tiff_tiled_band_separate ... etc.  The ossimGdalWriter
+    * may include gdal_imagine_hfa,gdal_nitf_rgb_band_separate, ... etc
+    * A writer should be able to be instantiated by this name as well as a class name
+    */
+   virtual void getImageTypeList(std::vector<ossimString>& imageTypeList)const=0;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryRegistry.cpp b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryRegistry.cpp
new file mode 100644
index 0000000000..ed1c6fa5e8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryRegistry.cpp
@@ -0,0 +1,220 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Frank Warmerdam (warmerda@home.com)
+//
+//*******************************************************************
+//  $Id: ossimImageWriterFactoryRegistry.cpp,v 1.11 2005/05/09 12:39:38 dburken Exp $
+#include <algorithm>
+#include <imaging/factory/ossimImageWriterFactory.h>
+#include <imaging/factory/ossimImageWriterFactoryRegistry.h>
+#include <imaging/formats/ossimImageFileWriter.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <base/common/ossimKeywordNames.h>
+
+ossimImageWriterFactoryRegistry* ossimImageWriterFactoryRegistry::theInstance = NULL;
+
+ossimImageWriterFactoryRegistry::ossimImageWriterFactoryRegistry()
+{
+}
+
+ossimImageWriterFactoryRegistry* ossimImageWriterFactoryRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimImageWriterFactoryRegistry;
+      ossimObjectFactoryRegistry::instance()->registerFactory(theInstance);
+      ossimImageWriterFactory::instance();
+   }
+
+   return theInstance;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+bool ossimImageWriterFactoryRegistry::addFactory(ossimImageWriterFactoryBase* factory)
+{
+   return registerFactory(factory);
+}
+
+bool ossimImageWriterFactoryRegistry::registerFactory(ossimImageWriterFactoryBase* factory)
+{
+   bool result = false;
+   if(factory&&!findFactory(factory))
+   {
+      theFactoryList.push_back(factory);
+      result = true;
+   }
+
+   return result;
+}
+
+void ossimImageWriterFactoryRegistry::unregisterFactory(ossimImageWriterFactoryBase* factory)
+{
+   std::vector<ossimImageWriterFactoryBase*>::iterator iter =  std::find(theFactoryList.begin(),
+                                                                          theFactoryList.end(),
+                                                                          factory);
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+}
+
+bool ossimImageWriterFactoryRegistry::findFactory(ossimImageWriterFactoryBase* factory)const
+{
+   return (std::find(theFactoryList.begin(),
+                     theFactoryList.end(),
+                     factory)!=theFactoryList.end());
+}
+
+ossimImageFileWriter *ossimImageWriterFactoryRegistry::createWriterFromExtension(const ossimString& fileExtension)const
+{
+   vector<ossimImageWriterFactoryBase*>::const_iterator factories;
+   ossimImageFileWriter *result = NULL;
+
+   factories = theFactoryList.begin();
+   while(factories != theFactoryList.end())
+   {
+      result = (*factories)->createWriterFromExtension(fileExtension);
+      if(result)
+      {
+         return result;
+      }
+      ++factories;
+   }
+
+   return result;
+   
+}
+
+ossimImageFileWriter *ossimImageWriterFactoryRegistry::createWriter(const ossimKeywordlist &kwl,
+                                                                const char *prefix)const
+{
+   // let's see if we ned to return an object based on extension.
+   // this is specified by the type to be a generic
+   // ossimImageFileWriter
+   //
+   ossimString type = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+
+   if(type == "ossimImageFileWriter")
+   {
+      ossimFilename filename = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+
+      if((filename != "")&&
+         (filename.ext() != ""))
+      {
+         ossimImageFileWriter* writer = createWriterFromExtension(filename.ext());
+
+         if(writer)
+         {
+            writer->setFilename(filename);
+         }
+         return writer;
+      }
+   }
+   
+   vector<ossimImageWriterFactoryBase*>::const_iterator factories;
+   ossimImageFileWriter *result = NULL;
+
+   factories = theFactoryList.begin();
+   while(factories != theFactoryList.end())
+   {
+      result = (*factories)->createWriter(kwl, prefix);
+      if(result)
+      {
+         return result;
+      }
+      ++factories;
+   }
+
+   return result;
+}
+
+ossimImageFileWriter *ossimImageWriterFactoryRegistry::createWriter(const ossimString& typeName)const
+{
+   vector<ossimImageWriterFactoryBase*>::const_iterator factories;
+   ossimImageFileWriter *result = NULL;
+
+   factories = theFactoryList.begin();
+   while(factories != theFactoryList.end())
+   {
+      result = (*factories)->createWriter(typeName);
+      if(result)
+      {
+         return result;
+      }
+      ++factories;
+   }
+
+   return result;
+}
+
+ossimObject* ossimImageWriterFactoryRegistry::createObject(const ossimKeywordlist &kwl,
+                                                           const char *prefix)const
+{
+   return createWriter(kwl, prefix);
+}
+
+ossimObject* ossimImageWriterFactoryRegistry::createObject(const ossimString& typeName)const
+{
+   return createWriter(typeName);
+}
+
+void ossimImageWriterFactoryRegistry::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   vector<ossimString> result;
+   vector<ossimImageWriterFactoryBase*>::const_iterator iter = theFactoryList.begin();
+   
+   while(iter != theFactoryList.end())
+   {
+      result.clear();
+      (*iter)->getTypeNameList(result);
+      
+      // now append to the end of the typeList.
+      typeList.insert(typeList.end(),
+                      result.begin(),
+                      result.end());
+      ++iter;
+   }  
+}
+
+void ossimImageWriterFactoryRegistry::getImageTypeList(std::vector<ossimString>& typeList)const
+{
+   vector<ossimString> result;
+   vector<ossimImageWriterFactoryBase*>::const_iterator iter = theFactoryList.begin();
+   
+   while(iter != theFactoryList.end())
+   {
+      result.clear();
+      (*iter)->getImageTypeList(result);
+      
+      // now append to the end of the typeList.
+      typeList.insert(typeList.end(),
+                      result.begin(),
+                      result.end());
+      ++iter;
+   }  
+}
+
+extern "C"
+{
+  void* ossimImageWriterFactoryRegistryGetInstance()
+  {
+    return ossimImageWriterFactoryRegistry::instance();
+  }
+}
+
+ossimImageWriterFactoryRegistry::ossimImageWriterFactoryRegistry(const ossimImageWriterFactoryRegistry&)
+   :
+      ossimObjectFactory()
+{
+}
+
+void ossimImageWriterFactoryRegistry::operator=(const ossimImageWriterFactoryRegistry&)
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryRegistry.h b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryRegistry.h
new file mode 100644
index 0000000000..2ed3ab1554
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/factory/ossimImageWriterFactoryRegistry.h
@@ -0,0 +1,73 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Frank Warmerdam (warmerda@home.com)
+//
+//*******************************************************************
+//  $Id: ossimImageWriterFactoryRegistry.h,v 1.13 2004/12/10 16:46:37 gpotts Exp $
+
+#ifndef ossimImageWriterFactoryRegistry_HEADER
+#define ossimImageWriterFactoryRegistry_HEADER
+#include "base/factory/ossimObjectFactory.h"
+
+#include <vector>
+
+#include "base/common/ossimCommon.h"
+
+class ossimImageFileWriter;
+class ossimImageWriterFactoryBase;
+class ossimKeywordlist;
+
+class OSSIMDLLEXPORT ossimImageWriterFactoryRegistry : public ossimObjectFactory
+{   
+public:
+   static ossimImageWriterFactoryRegistry* instance();
+   bool addFactory(ossimImageWriterFactoryBase*);
+   bool registerFactory(ossimImageWriterFactoryBase* factory);   
+   void unregisterFactory(ossimImageWriterFactoryBase* factory);
+   bool findFactory(ossimImageWriterFactoryBase* factory)const;
+
+   ossimImageFileWriter *createWriterFromExtension(const ossimString& fileExtension)const;
+   ossimImageFileWriter *createWriter(const ossimKeywordlist &kwl,
+                                      const char *prefix=0)const;
+   ossimImageFileWriter* createWriter(const ossimString& typeName)const;
+   
+   ossimObject* createObject(const ossimKeywordlist &kwl,
+                             const char *prefix=0)const;
+   ossimObject* createObject(const ossimString& typeName)const;
+
+   /**
+    * getTypeNameList.  This should return the class type of the object being
+    * used to perform the writting.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /**
+    * getImageTypeList.  This is the actual image type name.  So for
+    * example, ossimTiffWriter has several image types.  Some of these
+    * include TIFF_TILED, TIFF_TILED_BAND_SEPARATE ... etc.
+    * The ossimGdalWriter
+    * may include GDAL_IMAGINE_HFA, GDAL_RGB_NITF, GDAL_JPEG20000, ... etc
+    * A writer should be able to be instantiated by this name as well as a
+    * class name
+    */
+   virtual void getImageTypeList(std::vector<ossimString>& imageTypeList)const;
+   
+protected:
+   ossimImageWriterFactoryRegistry();
+   ossimImageWriterFactoryRegistry(const ossimImageWriterFactoryRegistry&);
+   void operator=(const ossimImageWriterFactoryRegistry&);
+   
+   std::vector<ossimImageWriterFactoryBase*>  theFactoryList;
+   static ossimImageWriterFactoryRegistry*    theInstance;
+};
+
+extern "C"
+{
+  OSSIMDLLEXPORT void* ossimImageWriterFactoryRegistryGetInstance();
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/filters/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscrete3x3HatFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscrete3x3HatFilter.cpp
new file mode 100644
index 0000000000..7b6a59712d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscrete3x3HatFilter.cpp
@@ -0,0 +1,289 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// LICENSE: LGPL
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimDiscrete3x3HatFilter.cpp,v 1.11 2004/09/21 12:41:26 gpotts Exp $
+#include "ossimDiscrete3x3HatFilter.h"
+#include <base/common/ossimCommon.h>
+
+ossimDiscrete3x3HatFilter::ossimDiscrete3x3HatFilter()
+   :ossimDiscreteConvolutionKernel(3,3)
+{
+   // make the default be the nearest neighbor
+   (*theKernel)[0][0] = 0;
+   (*theKernel)[0][1] = 0;
+   (*theKernel)[0][2] = 0;
+
+   (*theKernel)[1][0] = 0;
+   (*theKernel)[1][1] = 1;
+   (*theKernel)[1][2] = 0;
+
+   (*theKernel)[2][0] = 0;
+   (*theKernel)[2][1] = 0;
+   (*theKernel)[2][2] = 0;
+}
+
+void ossimDiscrete3x3HatFilter::convolve(const float* data,
+                                         double& result,
+                                         float nullPixel)const
+{
+   double divisor = 0;
+   result         = 0;
+
+   if(data[0] != nullPixel)
+   {
+      divisor += (*theKernel)[0][0];
+      result  += (*theKernel)[0][0] * data[0];
+   }
+   if(data[1] != nullPixel)
+   {
+      divisor += (*theKernel)[0][1];
+      result  += (*theKernel)[0][1] * data[1];
+   }
+   if(data[2] != nullPixel)
+   {
+      divisor += (*theKernel)[0][2];
+      result  += (*theKernel)[0][2] * data[2];
+   }
+   if(data[3] != nullPixel)
+   {
+      divisor += (*theKernel)[1][0];
+      result  += (*theKernel)[1][0] * data[3];
+   }
+   if(data[4] != nullPixel)
+   {
+      divisor += (*theKernel)[1][1];
+      result  += (*theKernel)[1][1] * data[4];
+   }
+   if(data[5] != nullPixel)
+   {
+      divisor += (*theKernel)[1][2];
+      result  += (*theKernel)[1][2] * data[5];
+   }
+   if(data[6] != nullPixel)
+   {
+      divisor += (*theKernel)[2][0];
+      result  += (*theKernel)[2][0] * data[6];
+   }
+   if(data[7] != nullPixel)
+   {
+      divisor += (*theKernel)[2][1];
+      result  += (*theKernel)[2][1] * data[7];
+   }
+   if(data[8] != nullPixel)
+   {
+      divisor += (*theKernel)[2][2];
+      result  += (*theKernel)[2][2] * data[8];
+   }
+   
+
+   if(divisor > 0)
+      result /= divisor;
+}
+
+void ossimDiscrete3x3HatFilter::convolveSubImage(const float* data,
+                                                 long dataWidth,
+                                                 double& result,
+                                                 float nullPixel)const
+{
+   double divisor = 0.0;
+   result = 0;
+   
+   if(data[0] != nullPixel)
+   {
+      divisor += (*theKernel)[0][0];
+      result  += (*theKernel)[0][0]*data[0];
+   }
+   if(data[1] != nullPixel)
+   {
+      divisor += (*theKernel)[0][1];
+      result  += (*theKernel)[0][1]*data[1];
+   }
+   if(data[2] != nullPixel)
+   {
+      divisor += (*theKernel)[0][2];
+      result  += (*theKernel)[0][2]*data[2];
+   }
+   
+   data +=dataWidth;
+   if(data[0] != nullPixel)
+   {
+      divisor += (*theKernel)[1][0];
+      result  += (*theKernel)[1][0]*data[0];
+   }
+   if(data[1] != nullPixel)
+   {
+      divisor += (*theKernel)[1][1];
+      result  += (*theKernel)[1][1]*data[1];
+   }
+   if(data[2] != nullPixel)
+   {
+      divisor += (*theKernel)[1][2];
+      result  += (*theKernel)[1][2]*data[2];
+   }
+   
+   data +=dataWidth;
+   if(data[0] != nullPixel)
+   {
+      divisor += (*theKernel)[2][0];
+      result  += (*theKernel)[2][0]*data[0];
+   }
+   if(data[1] != nullPixel)
+   {
+      divisor += (*theKernel)[2][1];
+      result  += (*theKernel)[2][1]*data[1];
+   }
+   if(data[2] != nullPixel)
+   {
+      divisor += (*theKernel)[2][2];
+      result  += (*theKernel)[2][2]*data[2];
+   }
+
+   if(divisor > 0)
+   {
+      result /= divisor;
+   }
+}
+
+void ossimDiscrete3x3HatFilter::convolve(const unsigned char* data,
+                                         double& result,
+                                         ossim_uint8 nullPixel)const
+{
+   double divisor = 0;
+   result         = 0;
+
+   if(data[0] != nullPixel)
+   {
+      divisor += (*theKernel)[0][0];
+      result  += (*theKernel)[0][0] * data[0];
+   }
+   if(data[1] != nullPixel)
+   {
+      divisor += (*theKernel)[0][1];
+      result  += (*theKernel)[0][1] * data[1];
+   }
+   if(data[2] != nullPixel)
+   {
+      divisor += (*theKernel)[0][2];
+      result  += (*theKernel)[0][2] * data[2];
+   }
+   if(data[3] != nullPixel)
+   {
+      divisor += (*theKernel)[1][0];
+      result  += (*theKernel)[1][0] * data[3];
+   }
+   if(data[4] != nullPixel)
+   {
+      divisor += (*theKernel)[1][1];
+      result  += (*theKernel)[1][1] * data[4];
+   }
+   if(data[5] != nullPixel)
+   {
+      divisor += (*theKernel)[1][2];
+      result  += (*theKernel)[1][2] * data[5];
+   }
+   if(data[6] != nullPixel)
+   {
+      divisor += (*theKernel)[2][0];
+      result  += (*theKernel)[2][0] * data[6];
+   }
+   if(data[7] != nullPixel)
+   {
+      divisor += (*theKernel)[2][1];
+      result  += (*theKernel)[2][1] * data[7];
+   }
+   if(data[8] != nullPixel)
+   {
+      divisor += (*theKernel)[2][2];
+      result  += (*theKernel)[2][2] * data[8];
+   }
+   
+
+   if(divisor > 0)
+      result /= divisor;
+}
+
+
+void ossimDiscrete3x3HatFilter::convolveSubImage(const unsigned char* data,
+                                                 long dataWidth,
+                                                 double& result,
+                                                 ossim_uint8 nullPixel)const
+{
+   double divisor = 0.0;
+   result = 0;
+   
+   if(data[0] != nullPixel)
+   {
+      divisor += (*theKernel)[0][0];
+      result  += (*theKernel)[0][0]*data[0];
+   }
+   if(data[1] != nullPixel)
+   {
+      divisor += (*theKernel)[0][1];
+      result  += (*theKernel)[0][1]*data[1];
+   }
+   if(data[2] != nullPixel)
+   {
+      divisor += (*theKernel)[0][2];
+      result  += (*theKernel)[0][2]*data[2];
+   }
+   
+   data +=dataWidth;
+   if(data[0] != nullPixel)
+   {
+      divisor += (*theKernel)[1][0];
+      result  += (*theKernel)[1][0]*data[0];
+   }
+   if(data[1] != nullPixel)
+   {
+      divisor += (*theKernel)[1][1];
+      result  += (*theKernel)[1][1]*data[1];
+   }
+   if(data[2] != nullPixel)
+   {
+      divisor += (*theKernel)[1][2];
+      result  += (*theKernel)[1][2]*data[2];
+   }
+   
+   data +=dataWidth;
+   if(data[0] != nullPixel)
+   {
+      divisor += (*theKernel)[2][0];
+      result  += (*theKernel)[2][0]*data[0];
+   }
+   if(data[1] != nullPixel)
+   {
+      divisor += (*theKernel)[2][1];
+      result  += (*theKernel)[2][1]*data[1];
+   }
+   if(data[2] != nullPixel)
+   {
+      divisor += (*theKernel)[2][2];
+      result  += (*theKernel)[2][2]*data[2];
+   }
+
+   if(divisor > 0)
+   {
+      result /= divisor;
+   }
+}
+
+void ossimDiscrete3x3HatFilter::buildConvolution(double xLocation,
+                                                 double yLocation)
+{
+   NEWMAT::RowVector    row(3);
+   NEWMAT::ColumnVector col(3);
+   
+   row[0] = ossimAbs(xLocation);
+   row[1] = 1;
+   row[2] = ossimAbs(xLocation);
+   col[0] = ossimAbs(yLocation);
+   col[1] = 1;
+   col[2] = ossimAbs(yLocation);
+  
+   (*theKernel) = col*row;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscrete3x3HatFilter.h b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscrete3x3HatFilter.h
new file mode 100644
index 0000000000..f1fa41429a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscrete3x3HatFilter.h
@@ -0,0 +1,64 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimDiscrete3x3HatFilter.h,v 1.6 2003/05/13 11:31:04 dburken Exp $
+#ifndef ossimDiscrete3x3HatFilter_HEADER
+#define ossimDiscrete3x3HatFilter_HEADER
+#include "ossimDiscreteConvolutionKernel.h"
+class ossimDiscrete3x3HatFilter : public ossimDiscreteConvolutionKernel
+{
+public:
+   ossimDiscrete3x3HatFilter();
+
+   /*!
+    * Will expect a data buffer of size width*height
+    * and is row ordered.
+    */
+   virtual void convolve(const float* data,
+                         double& result,
+                         float nullPixel=OSSIM_FLT_NAN)const;
+   
+   virtual void convolveSubImage(const float* data,
+                                 long dataWidth,
+                                 double& result,
+                                 float nullPixel=OSSIM_FLT_NAN)const;
+   
+   virtual void convolve(const unsigned char* data,
+                         double& result,
+                         ossim_uint8 nullPixel=0.0)const;
+   /*!
+    * this allows you to pass a subImage to
+    * the convolution engine.  It needs to know
+    * the width of the buffer so it can increment
+    * to the next element.
+    */
+   virtual void convolveSubImage(const unsigned char* data,
+                                 long dataWidth,
+                                 double& result,
+                                 ossim_uint8 nullPixel=0.0)const;
+   
+   virtual void buildConvolution(double widthPercent,
+                                 double heightPercent);   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteConvolutionKernel.cpp b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteConvolutionKernel.cpp
new file mode 100644
index 0000000000..33817595ca
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteConvolutionKernel.cpp
@@ -0,0 +1,557 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimDiscreteConvolutionKernel.cpp,v 1.11 2003/05/13 11:31:04 dburken Exp $
+#include "ossimDiscreteConvolutionKernel.h"
+
+ 
+ossimDiscreteConvolutionKernel::ossimDiscreteConvolutionKernel(long width,
+                                                               long height,
+                                                               bool doWeightedAverage)
+   : theKernel(NULL),
+     theWidth(width),
+     theHeight(height),
+     theComputeWeightedAverageFlag(doWeightedAverage)
+{
+   theWidth  = theWidth <0?1:theWidth;
+   theHeight = theHeight <0?1:theHeight;
+   
+   theKernel = new NEWMAT::Matrix(theHeight, theWidth);
+   *theKernel = (1.0/(theHeight*theWidth));
+}
+
+ossimDiscreteConvolutionKernel::ossimDiscreteConvolutionKernel(const NEWMAT::Matrix& kernel,
+                                                               bool doWeightedAverage)
+   :theKernel(new NEWMAT::Matrix(kernel)),
+   theComputeWeightedAverageFlag(doWeightedAverage)
+{
+   theWidth  = theKernel->Ncols();
+   theHeight = theKernel->Nrows();
+}
+
+ossimDiscreteConvolutionKernel::~ossimDiscreteConvolutionKernel()
+{
+   if(theKernel)
+   {
+      delete theKernel;
+      theKernel = NULL;
+   }
+}
+
+void ossimDiscreteConvolutionKernel::buildSymmetric(const std::vector<float>& coefficients,
+                                                    NEWMAT::Matrix& result)
+{
+   long size = coefficients.size();
+   if(size > 0)
+   {
+
+      NEWMAT::RowVector row(size);
+      NEWMAT::ColumnVector col(size);
+      for(long index = 0; index < size; ++index)
+      {
+         row[index] = coefficients[index];
+         col[index] = coefficients[index];
+      }
+      result = col*row;
+   }
+}
+
+void ossimDiscreteConvolutionKernel::buildSymmetric(float *coefficients,
+                                                    long size,
+                                                    NEWMAT::Matrix& result)
+{
+   if(size > 0)
+   {
+      NEWMAT::RowVector    row(size);
+      NEWMAT::ColumnVector col(size);
+      for(long index = 0; index < size; ++index)
+      {
+         row[index] = coefficients[index];
+         col[index] = coefficients[index];
+      }
+      result = col*row;
+   }
+}
+
+void ossimDiscreteConvolutionKernel::setKernel(const NEWMAT::Matrix& kernel)
+{
+   if(theKernel)
+   {
+      theKernel = new NEWMAT::Matrix;
+   }
+   *theKernel = kernel;
+   theWidth  = theKernel->Ncols();
+   theHeight = theKernel->Nrows();   
+}
+
+void ossimDiscreteConvolutionKernel::convolve(const float* data,
+                                              double& result,
+                                              float nullPixel)const
+{
+   result = 0;
+
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+   }
+}
+
+void ossimDiscreteConvolutionKernel::convolveSubImage(const float* data,
+                                                      long dataWidth,
+                                                      double& result,
+                                                      float nullPixel)const
+{
+   const float* dataStart = NULL;
+   result = 0;
+   
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+   }
+}
+
+void ossimDiscreteConvolutionKernel::convolve(const unsigned char* data,
+                                              double& result,
+                                              ossim_uint8 nullPixel)const
+{
+   result = 0;
+
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+   }
+}
+
+void ossimDiscreteConvolutionKernel::convolveSubImage(const unsigned char* data,
+                                                      long dataWidth,
+                                                      double& result,
+                                                      ossim_uint8 nullPixel)const
+{
+   const ossim_uint8* dataStart = NULL;
+   result = 0;
+   
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+   }
+}
+
+
+void ossimDiscreteConvolutionKernel::convolve(const unsigned short* data,
+                                              double& result,
+                                              ossim_uint16 nullPixel)const
+{
+   result = 0;
+
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+   }
+}
+
+void ossimDiscreteConvolutionKernel::convolveSubImage(const unsigned short* data,
+                                                      long dataWidth,
+                                                      double& result,
+                                                      ossim_uint16 nullPixel)const
+{
+   const ossim_uint16* dataStart = NULL;
+   result = 0;
+   
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+   }
+}
+
+void ossimDiscreteConvolutionKernel::convolve(const short* data,
+                                              double& result,
+                                              ossim_sint16 nullPixel)const
+{
+   result = 0;
+
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+   }
+}
+
+void ossimDiscreteConvolutionKernel::convolveSubImage(const short* data,
+                                                      long dataWidth,
+                                                      double& result,
+                                                      ossim_sint16 nullPixel)const
+{
+   const ossim_sint16* dataStart = NULL;
+   result = 0;
+   
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+   }
+}
+
+
+void ossimDiscreteConvolutionKernel::convolve(const double* data,
+                                              double& result,
+                                              double nullPixel)const
+{
+   result = 0;
+
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*data != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*data));
+            }
+            ++data;
+         }
+      }
+   }
+}
+
+void ossimDiscreteConvolutionKernel::convolveSubImage(const double* data,
+                                                      long dataWidth,
+                                                      double& result,
+                                                      double nullPixel)const
+{
+   const double* dataStart = NULL;
+   result = 0;
+   
+   if(theComputeWeightedAverageFlag)
+   {
+      double divisor = 0.0;
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               divisor += (*theKernel)[row][col];
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+      if(divisor > 0)
+      {
+         result /= divisor;
+      }
+   }
+   else
+   {
+      for(long row=0; row < theHeight; ++row)
+      {
+         dataStart=data;
+         for(long col=0; col < theWidth; ++col)
+         {
+            if(*dataStart != nullPixel)
+            {
+               result  += ((*theKernel)[row][col] * (*dataStart));
+            }
+            ++dataStart;
+         }
+         data+=dataWidth;
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteConvolutionKernel.h b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteConvolutionKernel.h
new file mode 100644
index 0000000000..e54c29ad3c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteConvolutionKernel.h
@@ -0,0 +1,151 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimDiscreteConvolutionKernel.h,v 1.12 2003/05/13 11:31:04 dburken Exp $
+#ifndef ossimDiscreteConvolutionKernel_HEADER
+#define ossimDiscreteConvolutionKernel_HEADER
+#include <vector>
+#include "base/common/ossimConstants.h"
+#include <iostream>
+using namespace std;
+
+#include "matrix/newmat.h"
+#include "matrix/newmatio.h"
+
+class ossimDiscreteConvolutionKernel
+{
+public:
+   ossimDiscreteConvolutionKernel(long width,
+                                  long height,
+                                  bool doWeightedAverage=true);
+   ossimDiscreteConvolutionKernel(const NEWMAT::Matrix& kernel,
+                                  bool doWeightedAverage=true);
+   virtual ~ossimDiscreteConvolutionKernel();
+   static void buildSymmetric(const std::vector<float>& coefficients,
+                              NEWMAT::Matrix& result);
+   static void buildSymmetric(float* coefficients, long size,
+                              NEWMAT::Matrix& result);
+
+   virtual void setKernel(const NEWMAT::Matrix& kernel);
+
+   /*!
+    * Will expect a data buffer of size width*height
+    * and is row ordered.
+    */
+   virtual void convolve(const float* data,
+                         double& result,
+                         float nullPixel=OSSIM_FLT_NAN)const;
+   
+   virtual void convolveSubImage(const float* data,
+                                 long dataWidth,
+                                 double& result,
+                                 float nullPixel=OSSIM_FLT_NAN)const;
+
+   /*!
+    * Will expect a data buffer of size width*height
+    * and is row ordered.
+    */
+   virtual void convolve(const double* data,
+                         double& result,
+                         double nullPixel=OSSIM_DBL_NAN)const;
+
+   virtual void convolveSubImage(const double* data,
+                                 long dataWidth,
+                                 double& result,
+                                 double nullPixel=OSSIM_DBL_NAN)const;
+   /*!
+    * Will expect a data buffer of size width*height
+    * and is row ordered.
+    */
+   virtual void convolve(const short* data,
+                         double& result,
+                         ossim_sint16 nullPixel=OSSIM_SSHORT_NAN)const;
+   
+   virtual void convolveSubImage(const short* data,
+                                 long dataWidth,
+                                 double& result,
+                                 ossim_sint16 nullPixel=OSSIM_SSHORT_NAN)const;
+
+   /*!
+    * Will expect a data buffer of size width*height
+    * and is row ordered.
+    */
+   virtual void convolve(const unsigned short* data,
+                         double& result,
+                         ossim_uint16 nullPixel=OSSIM_USHORT_NAN)const;
+   
+   virtual void convolveSubImage(const unsigned short* data,
+                                 long dataWidth,
+                                 double& result,
+                                 ossim_uint16 nullPixel=OSSIM_USHORT_NAN)const;
+   
+   
+   virtual void convolve(const unsigned char* data,
+                              double& result,
+                              ossim_uint8 nullPixel=0)const;
+   /*!
+    * this allows you to pass a subImage to
+    * the convolution engine.  It needs to know
+    * the width of the buffer so it can increment
+    * to the next element.
+    */
+   virtual void convolveSubImage(const unsigned char* data,
+                                      long dataWidth,
+                                      double& result,
+                                      ossim_uint8 nullPixel=0)const;
+   /*!
+    * This is used to allow me to continually adjust a convolution kernel
+    * based on where it center lies on a pixel. The xLocation and yLocation
+    * are all from the center of pixel.  If I am convolving at full resolution
+    * then xLocation and yLocation should both be 0.  Let's pretend that we
+    * contract an image by .5 scale factor or zooming out by a factor of 2.  Then
+    * we actually of it .5 off from cneter of pixel in both the x and y direction.
+    * This information can be used to allow a kernel to adjust it's waits accordingly.
+    *
+    * Typically if the xLocation and yLocation is directly on the center indicated
+    * by 0 vor both then the kernel defaults to 1 in the middle and all other weights
+    * are zero.
+    */
+   virtual void buildConvolution(double xLocation,
+                                 double yLocation)
+      {}
+   virtual long getWidth()const
+      {
+         return theWidth;
+      }
+   virtual long getHeight()const
+      {
+         return theHeight;
+      }
+   const NEWMAT::Matrix& getKernel()const
+      {
+         return *theKernel;
+      }
+protected:
+   NEWMAT::Matrix  *theKernel;
+   long theWidth;
+   long theHeight;
+   bool theComputeWeightedAverageFlag;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteNearestNeighbor.h b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteNearestNeighbor.h
new file mode 100644
index 0000000000..90a6317c90
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/ossimDiscreteNearestNeighbor.h
@@ -0,0 +1,123 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimDiscreteNearestNeighbor.h,v 1.2 2001/07/11 15:17:01 gpotts Exp $
+#ifndef ossimDiscreteNearestNeighbor_HEADER
+#define ossimDiscreteNearestNeighbor_HEADER
+#include "ossimDiscreteConvolutionKernel.h"
+class ossimDiscreteNearestNeighbor : public ossimDiscreteConvolutionKernel
+{
+public:
+   ossimDiscreteNearestNeighbor()
+      :ossimDiscreteConvolutionKernel(1, 1)
+      {
+         
+      }
+
+   /*!
+    * We will override and optimize by unrolling the
+    * loop
+    */
+   virtual void convolveFloat(const float* data,
+                              double& result)const
+      {
+         result = *data;
+      }
+
+   /*!
+    * We will override and optimize by unrolling the
+    * loop
+    */
+   virtual void convolveSubImageFloat(const float* data,
+                                      long dataWidth,
+                                      double& result)const
+      {
+         result = *data;
+      }
+   
+   virtual void convolveDouble(const double* data,
+                               double& result)const
+      {
+         result = *data;
+      }
+
+   virtual void convolveSubImageDouble(const double* data,
+                                      long dataWidth,
+                                       double& result)const
+      {
+         result = *data;
+      }
+   /*!
+    * We will override and optimize by unrolling the
+    * loop
+    */
+   virtual void convolveUchar(const unsigned char* data,
+                              double& result)const
+      {
+         result = *data;
+      }
+   /*!
+    * We will override and optimize by unrolling the
+    * loop
+    */
+   virtual void convolveSubImageUchar(const unsigned char* data,
+                                      long dataWidth,
+                                      double& result)const
+      {
+         result = *data;
+      }
+   
+   virtual void convolveSshort(const short* data,
+                              double& result)const
+      {
+         result = *data;        
+      }
+
+   virtual void convolveSubImageSshort(const short* data,
+                                       long dataWidth,
+                                       double& result)const
+
+      {
+         result = *data;
+      }
+   
+   virtual void convolveUshort(const unsigned short* data,
+                               double& result)const
+      {
+         result = *data;        
+      }
+
+   virtual void convolveSubImageUshort(const unsigned short* data,
+                                      long dataWidth,
+                                       double& result)const
+      {
+         result = *data;
+      }
+   
+   virtual void buildConvolution(double widthPercent,
+                                 double heightPercent)
+      {
+      }
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilter.cpp
new file mode 100644
index 0000000000..69f7afc9d0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilter.cpp
@@ -0,0 +1,333 @@
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%                        ZZZZZ   OOO    OOO   M   M                           %
+%                           ZZ  O   O  O   O  MM MM                           %
+%                         ZZZ   O   O  O   O  M M M                           %
+%                        ZZ     O   O  O   O  M   M                           %
+%                        ZZZZZ   OOO    OOO   M   M                           %
+%                                                                             %
+%                                                                             %
+%                      ImageMagick Image Zoom Methods                         %
+%                                                                             %
+%                                                                             %
+%                              Software Design                                %
+%                                John Cristy                                  %
+%                                 July 1992                                   %
+%                                                                             %
+%                                                                             %
+%  Copyright (C) 2000 ImageMagick Studio, a non-profit organization dedicated %
+%  to making software imaging solutions freely available.                     %
+%                                                                             %
+%  Permission is hereby granted, free of charge, to any person obtaining a    %
+%  copy of this software and associated documentation files ("ImageMagick"),  %
+%  to deal in ImageMagick without restriction, including without limitation   %
+%  the rights to use, copy, modify, merge, publish, distribute, sublicense,   %
+%  and/or sell copies of ImageMagick, and to permit persons to whom the       %
+%  ImageMagick is furnished to do so, subject to the following conditions:    %
+%                                                                             %
+%  The above copyright notice and this permission notice shall be included in %
+%  all copies or substantial portions of ImageMagick.                         %
+%                                                                             %
+%  The software is provided "as is", without warranty of any kind, express or %
+%  implied, including but not limited to the warranties of merchantability,   %
+%  fitness for a particular purpose and noninfringement.  In no event shall   %
+%  ImageMagick Studio be liable for any claim, damages or other liability,    %
+%  whether in an action of contract, tort or otherwise, arising from, out of  %
+%  or in connection with ImageMagick or the use or other dealings in          %
+%  ImageMagick.                                                               %
+%                                                                             %
+%  Except as contained in this notice, the name of the ImageMagick Studio     %
+%  shall not be used in advertising or otherwise to promote the sale, use or  %
+%  other dealings in ImageMagick without prior written authorization from the %
+%  ImageMagick Studio.                                                        %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+#include "base/common/ossimConstants.h"
+#include "ossimFilter.h"
+#include "matrix/newmat.h"
+#include <iostream>
+
+
+RTTI_DEF(ossimFilter, "ossimFilter");
+RTTI_DEF1(ossimBoxFilter, "ossimBoxFilter",ossimFilter);
+RTTI_DEF1(ossimSincFilter, "ossimSincFilter",ossimFilter);
+RTTI_DEF1(ossimBellFilter, "ossimBellFilter",ossimFilter);
+RTTI_DEF1(ossimNearestNeighborFilter, "ossimNearestNeighborFilter",ossimFilter);
+RTTI_DEF1(ossimBesselFilter, "ossimBesselFilter",ossimFilter);
+RTTI_DEF1(ossimBesselOrderOneFilter, "ossimBesselOrderOneFilter",ossimFilter);
+RTTI_DEF1(ossimBlackmanFilter, "ossimBlackmanFilter",ossimFilter);
+RTTI_DEF1(ossimBlackmanSincFilter, "ossimBlackmanSincFilter",ossimFilter);
+RTTI_DEF1(ossimBlackmanBesselFilter, "ossimBlackmanBesselFilter",ossimFilter);
+RTTI_DEF1(ossimCatromFilter, "ossimCatromFilter",ossimFilter);
+RTTI_DEF1(ossimCubicFilter, "ossimCubicFilter",ossimFilter);
+RTTI_DEF1(ossimBSplineFilter, "ossimBSplineFilter",ossimFilter);
+RTTI_DEF1(ossimGaussianFilter, "ossimGaussianFilter",ossimFilter);
+RTTI_DEF1(ossimHanningFilter, "ossimHanningFilter",ossimFilter);
+RTTI_DEF1(ossimHammingFilter, "ossimHammingFilter",ossimFilter);
+RTTI_DEF1(ossimHermiteFilter, "ossimHermiteFilter",ossimFilter);
+RTTI_DEF1(ossimLanczosFilter, "ossimLanczosFilter",ossimFilter);
+RTTI_DEF1(ossimMitchellFilter, "ossimMitchellFilter",ossimFilter);
+RTTI_DEF1(ossimQuadraticFilter, "ossimQuadraticFilter",ossimFilter);
+RTTI_DEF1(ossimTriangleFilter, "ossimTriangleFilter",ossimFilter);
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
++   B e s s e l O r d e r O n e                                               %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  Method BesselOrderOne computes the Bessel function of x of the first kind
+%  of order 0:
+%
+%    Reduce x to |x| since j1(x)= -j1(-x), and for x in (0,8]
+%
+%       j1(x) = x*j1(x);
+%
+%    For x in (8,inf)
+%
+%       j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
+%
+%    where x1 = x-3*pi/4. Compute sin(x1) and cos(x1) as follow:
+%
+%       cos(x1) =  cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+%               =  1/sqrt(2) * (sin(x) - cos(x))
+%       sin(x1) =  sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+%               = -1/sqrt(2) * (sin(x) + cos(x))
+%
+%  The format of the BesselOrderOne method is:
+%
+%      double BesselOrderOne(double x)
+%
+%  A description of each parameter follows:
+%
+%    o value: Method BesselOrderOne returns the Bessel function of x of the
+%      first kind of orders 1.
+%
+%    o x: double value.
+%
+%
+*/
+
+static double J1(double x)
+{
+  double
+    p,
+    q;
+
+  register int
+    i;
+
+  static const double
+    Pone[] =
+    {
+       0.581199354001606143928050809e+21,
+      -0.6672106568924916298020941484e+20,
+       0.2316433580634002297931815435e+19,
+      -0.3588817569910106050743641413e+17,
+       0.2908795263834775409737601689e+15,
+      -0.1322983480332126453125473247e+13,
+       0.3413234182301700539091292655e+10,
+      -0.4695753530642995859767162166e+7,
+       0.270112271089232341485679099e+4
+    },
+    Qone[] =
+    {
+      0.11623987080032122878585294e+22,
+      0.1185770712190320999837113348e+20,
+      0.6092061398917521746105196863e+17,
+      0.2081661221307607351240184229e+15,
+      0.5243710262167649715406728642e+12,
+      0.1013863514358673989967045588e+10,
+      0.1501793594998585505921097578e+7,
+      0.1606931573481487801970916749e+4,
+      0.1e+1
+    };
+
+  p=Pone[8];
+  q=Qone[8];
+  for (i=7; i >= 0; i--)
+  {
+    p=p*x*x+Pone[i];
+    q=q*x*x+Qone[i];
+  }
+  return(p/q);
+}
+
+static double P1(double x)
+{
+  double
+    p,
+    q;
+
+  register int
+    i;
+
+  static const double
+    Pone[] =
+    {
+      0.352246649133679798341724373e+5,
+      0.62758845247161281269005675e+5,
+      0.313539631109159574238669888e+5,
+      0.49854832060594338434500455e+4,
+      0.2111529182853962382105718e+3,
+      0.12571716929145341558495e+1
+    },
+    Qone[] =
+    {
+      0.352246649133679798068390431e+5,
+      0.626943469593560511888833731e+5,
+      0.312404063819041039923015703e+5,
+      0.4930396490181088979386097e+4,
+      0.2030775189134759322293574e+3,
+      0.1e+1
+    };
+
+  p=Pone[5];
+  q=Qone[5];
+  for (i=4; i >= 0; i--)
+  {
+    p=p*(8.0/x)*(8.0/x)+Pone[i];
+    q=q*(8.0/x)*(8.0/x)+Qone[i];
+  }
+  return(p/q);
+}
+
+static double Q1(double x)
+{
+   double
+      p,
+      q;
+   
+   register int
+      i;
+   
+   static const double
+      Pone[] =
+   {
+      0.3511751914303552822533318e+3,
+      0.7210391804904475039280863e+3,
+      0.4259873011654442389886993e+3,
+      0.831898957673850827325226e+2,
+      0.45681716295512267064405e+1,
+      0.3532840052740123642735e-1
+   },
+      Qone[] =
+      {
+         0.74917374171809127714519505e+4,
+         0.154141773392650970499848051e+5,
+         0.91522317015169922705904727e+4,
+         0.18111867005523513506724158e+4,
+         0.1038187585462133728776636e+3,
+         0.1e+1
+      };
+      
+      p=Pone[5];
+      q=Qone[5];
+      for (i=4; i >= 0; i--)
+      {
+         p=p*(8.0/x)*(8.0/x)+Pone[i];
+         q=q*(8.0/x)*(8.0/x)+Qone[i];
+      }
+      return(p/q);
+}
+
+double ossimBesselOrderOneFilter::filter(double x, double support)const
+{
+   double
+      p,
+      q;
+   
+   if (x == 0.0)
+      return(0.0);
+   p=x;
+   if (x < 0.0)
+      x=(-x);
+   if (x < 8.0)
+      return(p*J1(x));
+   q=sqrt(2.0/(M_PI*x))*(P1(x)*(1.0/sqrt(2.0)*(sin(x)-cos(x)))-8.0/x*Q1(x)*
+                         (-1.0/sqrt(2.0)*(sin(x)+cos(x))));
+   if (p < 0.0)
+      q=(-q);
+   return(q);
+
+}
+
+void ossimFilter::createMatrix(NEWMAT::Matrix& m,
+                               long width,
+                               double middle,
+                               double scale)const
+{
+   NEWMAT::ColumnVector colVec(width);
+   NEWMAT::RowVector    rowVec(width);
+
+   double t = 0.0;
+   double val = 0.0;
+   if(width == 1)
+   {
+      t = 0;
+      val = filter(t, getSupport());
+      colVec[0] = val;
+      rowVec[0] = val;
+   }
+   else
+   {
+      for(long index = 0; index < width; index++)
+      {
+         t = (double)index/(double)(width-1);
+         t = middle + (t - .5)*scale;
+         val = filter(t, getSupport());
+         colVec[index] = val;
+         rowVec[index] = val;
+      }
+   }
+
+   // do the outer product to construct the
+   // filter matrix
+   m = colVec * rowVec;
+}
+
+
+NEWMAT::Matrix *ossimFilter::newMatrix(long width,
+                                       double middle,
+                                       double scale)const
+{
+   NEWMAT::Matrix *result = new NEWMAT::Matrix(width, width);
+
+   createMatrix(*result,
+                width,
+                middle,
+                scale);
+
+   return result;
+}
+
+NEWMAT::RowVector *ossimFilter::newVector(long width,
+                                          double middle,
+                                          double scale)const
+{
+   NEWMAT::RowVector *result = new NEWMAT::RowVector(width);
+
+
+   double t = 0.0;
+   double val = 0.0;
+   for(long index = 0; index < width; index++)
+   {
+      t = (double)index/(double)(width-1);
+      t = middle + (t- .5)*scale;
+      val = filter(t, getSupport());
+      (*result)[index] = val;
+   }
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilter.h b/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilter.h
new file mode 100644
index 0000000000..52e374bfd0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilter.h
@@ -0,0 +1,486 @@
+#ifndef ossimFilter_HEADER
+#define ossimFilter_HEADER
+#include <math.h>
+#include "matrix/newmat.h"
+#include "base/common/ossimRtti.h"
+
+
+class ossimFilter
+{
+public:
+   ossimFilter()
+      {}
+   virtual ~ossimFilter() {}
+   
+   virtual double filter (double x, double support)const = 0;
+   /*!
+    * Will call the filter method to create a
+    * convolution matrix.  This matrix will not
+    * have normalized weights.
+    *
+    * Will generate a matrix by creating an outer
+    * product of the 1-D filter array.  This matrix
+    * will be square width-by-width.
+    *
+    * note:  the matrix is a new matrix and needs to
+    *        be destroyed by the caller
+    */
+   virtual NEWMAT::Matrix *newMatrix(long width=3,
+                                     double middle=0.0,
+                                     double scale=0.0)const;
+   virtual void createMatrix(NEWMAT::Matrix& m,
+                             long width=3,
+                             double middle=0.0,
+                             double scale=0.0)const;
+   
+   virtual NEWMAT::RowVector *newVector(long width,
+                                        double middle=0.0,
+                                        double scale = 1.0)const;
+   static double Sinc(double x)
+      {
+         if (x != 0.0)
+         {
+            x*=M_PI;
+            return(sin(x)/x);
+         }
+         
+         return(1.0);
+      }
+   static double Sinc(double x, double /* support */ )
+      {
+         if (x != 0.0)
+         {
+            x*=M_PI;
+            return(sin(x)/x);
+         }
+         
+         return(1.0);
+      }
+
+   virtual double getSupport()const=0;
+   
+TYPE_DATA
+};
+
+class ossimBoxFilter : public ossimFilter
+{
+public:
+   ossimBoxFilter (){}
+   virtual ~ossimBoxFilter() {}
+   
+   virtual double filter (double x, double /* support */ )const
+      {
+         if (x < -0.5)
+            return(0.0);
+         if (x < 0.5)
+            return(1.0);
+         return(0.0);
+      }
+   virtual double getSupport()const
+      {
+         return .5;
+      }
+TYPE_DATA
+};
+
+class ossimSincFilter : public ossimFilter
+{
+public:
+   ossimSincFilter(){}
+   virtual ~ossimSincFilter(){}
+   double filter(double x, double /* support */ )const
+      {
+         x*=M_PI;
+         if (x != 0.0)
+            return(sin(x)/x);
+         return(1.0);
+      }
+   virtual double getSupport()const
+      {
+         return 1.0;
+      }
+TYPE_DATA
+};
+
+class ossimBellFilter : public ossimFilter
+{
+public:
+   ossimBellFilter(){}
+   virtual ~ossimBellFilter(){}
+   virtual double getSupport()const
+      {
+         return 1.5;
+      }
+   virtual double filter(double value, double /* support */ )const
+      {
+         if(value < 0) value = -value;
+         if(value < .5) return(.75 - (value * value));
+         if(value < 1.5) {
+            value = (value - 1.5);
+            return(.5 * (value * value));
+         }
+         return(0.0);
+      }
+TYPE_DATA
+};
+
+class ossimNearestNeighborFilter: public ossimBoxFilter
+{
+public:
+   ossimNearestNeighborFilter (){}
+   virtual ~ossimNearestNeighborFilter() {}
+   
+   virtual double getSupport()const
+      {
+         return 0.0;
+      }
+TYPE_DATA
+};
+
+   
+class ossimBesselOrderOneFilter : public ossimFilter
+{
+public:
+   ossimBesselOrderOneFilter(){}
+   virtual ~ossimBesselOrderOneFilter(){}
+   virtual double filter(double value, double /* support */ )const;
+   virtual double getSupport()const
+      {
+         return 1.0;
+      }
+TYPE_DATA
+};
+class ossimBesselFilter : public ossimFilter
+{
+public:
+   ossimBesselFilter(){}
+   virtual ~ossimBesselFilter(){}
+   virtual double filter(double x, double support)const
+      {
+         if (x == 0.0)
+         {
+            return(M_PI/4.0);
+         }
+         
+         return(ossimBesselOrderOneFilter().filter((M_PI*x)/(2.0*x), support));
+      }
+   virtual double getSupport()const
+      {
+         return 1.0;
+      }
+   
+TYPE_DATA
+};
+
+class ossimBlackmanFilter : public ossimFilter
+{
+public:
+    ossimBlackmanFilter (){}
+    virtual ~ossimBlackmanFilter() {}
+
+    virtual double filter (double x, double /* support */ ) const
+        {
+           return(0.42+0.50*cos(M_PI*x)+0.08*cos(2.0*M_PI*x));
+        }
+   virtual double getSupport()const
+      {
+         return 1.0;
+      }
+TYPE_DATA
+};
+
+class ossimBlackmanSincFilter : public ossimBlackmanFilter
+{
+public:
+    ossimBlackmanSincFilter (){}
+    virtual ~ossimBlackmanSincFilter() {}
+
+    virtual double filter (double x, double support) const
+        {
+           return ((ossimBlackmanFilter::filter(x/support,support))*
+                   (ossimSincFilter().filter(x, support)));
+        }
+   virtual double getSupport()const
+      {
+         return 4.0;
+      }
+TYPE_DATA
+};
+
+class ossimBlackmanBesselFilter : public ossimBlackmanFilter
+{
+public:
+    ossimBlackmanBesselFilter(){}
+    virtual ~ossimBlackmanBesselFilter() {}
+
+    virtual double filter (double x, double support) const
+        {
+           return ((ossimBlackmanFilter::filter(x/support,support))*
+                   (ossimBesselFilter().filter(x, support)));
+        }
+   virtual double getSupport()const
+      {
+         return 3.2383;
+      }
+TYPE_DATA
+};
+
+
+class ossimCatromFilter : public ossimFilter
+{
+public:
+   ossimCatromFilter(){}
+   virtual ~ossimCatromFilter(){}
+   double filter(double x, double /* support */ )const
+      {
+         if (x < -2.0)
+            return(0.0);
+         if (x < -1.0)
+            return(0.5*(4.0+x*(8.0+x*(5.0+x))));
+         if (x < 0.0)
+            return(0.5*(2.0+x*x*(-5.0-3.0*x)));
+         if (x < 1.0)
+            return(0.5*(2.0+x*x*(-5.0+3.0*x)));
+         if (x < 2.0)
+            return(0.5*(4.0+x*(-8.0+x*(5.0-x))));
+         return(0.0);
+      }
+   virtual double getSupport()const
+      {
+         return 2.0;
+      }
+TYPE_DATA
+};
+
+class ossimCubicFilter : public ossimFilter
+{
+public:
+   ossimCubicFilter(){}
+   virtual ~ossimCubicFilter(){}
+   double filter(double x, double /* support */ )const
+      {
+         if (x < -2.0)
+            return(0.0);
+         if (x < -1.0)
+            return((2.0+x)*(2.0+x)*(2.0+x)/6.0);
+         if (x < 0.0)
+            return((4.0+x*x*(-6.0-3.0*x))/6.0);
+         if (x < 1.0)
+            return((4.0+x*x*(-6.0+3.0*x))/6.0);
+         if (x < 2.0)
+            return((2.0-x)*(2.0-x)*(2.0-x)/6.0);
+         return(0.0);
+      }
+   virtual double getSupport()const
+      {
+         return 2.0;
+      }
+TYPE_DATA
+};
+
+class ossimBSplineFilter : public ossimFilter
+{
+public:
+   ossimBSplineFilter(){}
+   virtual ~ossimBSplineFilter(){}
+   virtual double filter(double value, double /* support */ )const
+      {
+	double tt;
+
+	if(value < 0) value = -value;
+	if(value < 1) {
+		tt = value * value;
+		return((.5 * tt * value) - tt + (2.0 / 3.0));
+	} else if(value < 2) {
+		value = 2 - value;
+		return((1.0 / 6.0) * (value * value * value));
+	}
+	return(0.0);
+      }
+   virtual double getSupport()const
+      {
+         return 2.0;
+      }
+TYPE_DATA
+};
+
+class ossimGaussianFilter : public ossimFilter
+{
+public:
+    ossimGaussianFilter (){}
+    virtual ~ossimGaussianFilter() {}
+
+    virtual double filter (double x, double /* support */ ) const
+        {
+           return(exp(-2.0*x*x)*sqrt(2.0/M_PI));
+        }
+   virtual double getSupport()const
+      {
+         return 1.25;
+      }
+TYPE_DATA
+};
+
+class ossimHanningFilter : public ossimFilter
+{
+public:
+   ossimHanningFilter(){}
+   virtual ~ossimHanningFilter(){}
+   double filter(double x, double /* support */ )const
+      {
+         return(0.5+0.5*cos(M_PI*x));
+      }
+   virtual double getSupport()const
+      {
+         return 1.0;
+      }
+TYPE_DATA
+};
+
+class ossimHammingFilter : public ossimFilter
+{
+public:
+    ossimHammingFilter (){}
+    virtual ~ossimHammingFilter() {}
+
+    virtual double filter (double x, double /* support */ ) const
+        {
+           return(0.54+0.46*cos(M_PI*x));
+        }
+   virtual double getSupport()const
+      {
+         return 1.0;
+      }
+TYPE_DATA
+};
+
+class ossimHermiteFilter : public ossimFilter
+{
+public:
+   ossimHermiteFilter(){}
+   virtual ~ossimHermiteFilter(){}
+   double filter(double x, double /* support */ )const
+      {
+         if (x < -1.0)
+            return(0.0);
+         if (x < 0.0)
+            return((2.0*(-x)-3.0)*(-x)*(-x)+1.0);
+         if (x < 1.0)
+            return((2.0*x-3.0)*x*x+1.0);
+         return(0.0);
+      }
+   virtual double getSupport()const
+      {
+         return 1.0;
+      }
+TYPE_DATA
+};
+
+
+class ossimLanczosFilter : public ossimFilter
+{
+public:
+   ossimLanczosFilter(){}
+   virtual ~ossimLanczosFilter(){}
+   double filter(double x, double /* support */ )const
+      {
+         if (x < -3.0)
+            return(0.0);
+         if (x < 0.0)
+            return(Sinc(-x,getSupport())*Sinc(-x/3.0,getSupport()));
+         if (x < 3.0)
+            return(Sinc(x,getSupport())*Sinc(x/3.0,getSupport()));
+         return(0.0);
+      }
+   virtual double getSupport()const
+      {
+         return 3.0;
+      }
+TYPE_DATA
+};
+
+class ossimMitchellFilter : public ossimFilter
+{
+public:
+   ossimMitchellFilter(){}
+   virtual ~ossimMitchellFilter(){}
+   double filter(double x, double /* support */ )const
+      {
+#define MITCHELL_B   (1.0/3.0)
+#define MITCHELL_C   (1.0/3.0)
+#define MITCHELL_P0  ((  6.0- 2.0*MITCHELL_B       )/6.0)
+#define MITCHELL_P2  ((-18.0+12.0*MITCHELL_B+ 6.0*MITCHELL_C)/6.0)
+#define MITCHELL_P3  (( 12.0- 9.0*MITCHELL_B- 6.0*MITCHELL_C)/6.0)
+#define MITCHELL_Q0  ((       8.0*MITCHELL_B+24.0*MITCHELL_C)/6.0)
+#define MITCHELL_Q1  ((     -12.0*MITCHELL_B-48.0*MITCHELL_C)/6.0)
+#define MITCHELL_Q2  ((       6.0*MITCHELL_B+30.0*MITCHELL_C)/6.0)
+#define MITCHELL_Q3  ((     - 1.0*MITCHELL_B- 6.0*MITCHELL_C)/6.0)
+         
+         if (x < -2.0)
+            return(0.0);
+         if (x < -1.0)
+            return(MITCHELL_Q0-x*(MITCHELL_Q1-x*(MITCHELL_Q2-x*MITCHELL_Q3)));
+         if (x < 0.0)
+            return(MITCHELL_P0+x*x*(MITCHELL_P2-x*MITCHELL_P3));
+         if (x < 1.0)
+            return(MITCHELL_P0+x*x*(MITCHELL_P2+x*MITCHELL_P3));
+         if (x < 2.0)
+            return(MITCHELL_Q0+x*(MITCHELL_Q1+x*(MITCHELL_Q2+x*MITCHELL_Q3)));
+         return(0.0);
+      }
+   virtual double getSupport()const
+      {
+         return 2.0;
+      }
+TYPE_DATA
+};
+
+class ossimQuadraticFilter : public ossimFilter
+{
+public:
+   ossimQuadraticFilter(){}
+   virtual ~ossimQuadraticFilter(){}
+   double filter(double x, double /* support */ )const
+      {
+         if (x < -1.5)
+            return(0.0);
+         if (x < -0.5)
+            return(0.5*(x+1.5)*(x+1.5));
+         if (x < 0.5)
+            return(0.75-x*x);
+         if (x < 1.5)
+            return(0.5*(x-1.5)*(x-1.5));
+         return(0.0);
+      }
+   double getSupport()const
+      {
+         return 1.5;
+      }
+TYPE_DATA
+};
+
+class ossimTriangleFilter : public ossimFilter
+{
+public:
+   ossimTriangleFilter(){}
+   virtual ~ossimTriangleFilter() {}
+   
+   virtual double filter (double x, double /* support */ )const
+      {
+         if (x < -1.0)
+            return(0.0);
+         if (x < 0.0)
+            return(1.0+x);
+         if (x < 1.0)
+            return(1.0-x);
+         return(0.0);
+      }
+   virtual double getSupport()const
+      {
+         return 1.0;
+      }
+TYPE_DATA
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilterTable.cpp b/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilterTable.cpp
new file mode 100644
index 0000000000..ef45f4e7c0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilterTable.cpp
@@ -0,0 +1,149 @@
+//----------------------------------------------------------------------------
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+//----------------------------------------------------------------------------
+// $Id: ossimFilterTable.cpp,v 1.5 2005/08/12 17:08:07 dburken Exp $
+#include <iostream>
+#include <imaging/filters/ossimFilterTable.h>
+#include <imaging/filters/ossimFilter.h>
+
+ossimFilterTable::ossimFilterTable()
+   :theWeights(0),
+    theWidth(0),
+    theHeight(0),
+    theWidthHeight(0),
+    theXSupport(0),
+    theYSupport(0),
+    theFilterSteps(0)
+{
+   
+}
+
+ossimFilterTable::~ossimFilterTable()
+{
+   if(theWeights)
+   {
+      delete [] theWeights;
+      theWeights = 0;
+   }
+}
+
+void ossimFilterTable::buildTable(ossim_uint32  filterSteps,
+                                  const ossimFilter& filter)
+{
+   buildTable(filterSteps, filter, filter);
+}
+
+void ossimFilterTable::buildTable(ossim_uint32  filterSteps,
+                                  const ossimFilter& xFilter,
+                                  const ossimFilter& yFilter)
+{
+   ossim_int32 subpixelSample=0;
+   ossim_int32 subpixelLine=0;
+   double dx   = 0.0;
+   double dy   = 0.0;
+   double kernelH   = 0.0;
+   double kernelV   = 0.0;
+   double x = 0;
+   double y = 0;
+
+   double xsupport = ceil(xFilter.getSupport());
+   double ysupport = ceil(yFilter.getSupport());
+   double left    = 0;
+   double right   = 0;
+   double top     = 0;
+   double bottom  = 0;
+
+   theXSupport = (ossim_uint32)xsupport;
+   theYSupport = (ossim_uint32)ysupport;
+   theFilterSteps = filterSteps;
+   theWidth  = (2*theXSupport);
+   theHeight = (2*theYSupport);
+   theWidthHeight = theWidth*theHeight;
+   
+   allocateWeights();
+   left   = -(xsupport-1);
+   right  = xsupport;
+   top    = -(ysupport-1);
+   bottom = ysupport;
+   ossim_uint32 idx = 0;
+      
+   for (subpixelLine = 0; subpixelLine < (int)filterSteps; 
+        subpixelLine++)
+   {
+     
+     // Calculate subpixel sample step.
+     // ---------------------------------- 
+     dy = subpixelLine / (double)(filterSteps);
+     for (subpixelSample = 0; subpixelSample < (int)filterSteps; 
+	  subpixelSample++)
+       {
+      
+	 // Calculate subpixel sample step.
+	 // ---------------------------------- 
+	 dx = subpixelSample / (double)(filterSteps);
+	 
+	 for (kernelV=top; kernelV<=bottom;
+	      kernelV++)
+	   {
+	     y = kernelV - dy;
+	     double tempWeight = yFilter.filter(y, yFilter.getSupport());
+	     for(kernelH=left; kernelH<=right;++kernelH)
+	       {
+		 x = kernelH - dx;
+         
+		 // Get the weight for the current pixel.
+		 //   ----------------------------------------
+		 theWeights[idx] = tempWeight*xFilter.filter(x, xFilter.getSupport());
+		 ++idx;
+	       }
+	   }
+       }
+   }
+}
+
+ossim_uint32 ossimFilterTable::getWidthByHeight()const
+{
+   return theWidthHeight;
+}
+
+ossim_uint32 ossimFilterTable::getXSupport()const
+{
+   return theXSupport;
+}
+
+ossim_uint32 ossimFilterTable::getYSupport()const
+{
+   return theYSupport;
+}
+
+ossim_uint32 ossimFilterTable::getWidth()const
+{
+   return theWidth;
+}
+
+ossim_uint32 ossimFilterTable::getHeight()const
+{
+   return theHeight;
+}
+
+void ossimFilterTable::allocateWeights()
+{
+   if(theWeights)
+   {
+      delete [] theWeights;
+      theWeights = 0;
+   }
+
+   ossim_uint32 size = (theWidthHeight*(theFilterSteps*theFilterSteps));
+
+   if(size)
+   {
+      theWeights = new double[size];
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilterTable.h b/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilterTable.h
new file mode 100644
index 0000000000..e417ad9e24
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/filters/ossimFilterTable.h
@@ -0,0 +1,97 @@
+//----------------------------------------------------------------------------
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+//----------------------------------------------------------------------------
+// $Id: ossimFilterTable.h,v 1.4 2005/08/12 18:23:33 dburken Exp $
+#ifndef ossimFilterTable_HEADER
+#define ossimFilterTable_HEADER
+
+#include <cmath>
+#include <base/common/ossimConstants.h>
+
+class ossimFilter;
+
+class ossimFilterTable
+{
+public:
+   /** default constructor */
+   ossimFilterTable();
+
+   /** destructor */
+   ~ossimFilterTable();
+
+   /** Builds a table with filter being used in both x and y direction. */
+   void buildTable(ossim_uint32  filterSteps,
+                   const ossimFilter& filter);
+
+   /** Builds a table. */
+   void buildTable(ossim_uint32  filterSteps,
+                   const ossimFilter& xFilter,
+                   const ossimFilter& yFilter);
+
+   /** @return theWidth*theHeight */
+   ossim_uint32 getWidthByHeight() const;
+
+   /** @return theXSupport */
+   ossim_uint32 getXSupport()      const;
+
+   /** @return theYSupport */
+   ossim_uint32 getYSupport()      const;
+
+   /** @return theWidth */
+   ossim_uint32 getWidth()         const;
+
+   /** @return theHeight */
+   ossim_uint32 getHeight()        const;
+
+   /**
+    * Inlined below.
+    *
+    * @return const double* to the closest weight of x and y.
+    */
+   const double* getClosestWeights(const double& x, const double& y)const;
+
+protected:
+
+   /**
+    * Creates the weight array "theWeights".  Will delete if previously
+    * allocated.
+    */
+   void allocateWeights();
+
+   double*      theWeights;
+   ossim_uint32 theWidth;
+   ossim_uint32 theHeight;
+   ossim_uint32 theWidthHeight;
+   ossim_uint32 theXSupport;
+   ossim_uint32 theYSupport;
+   ossim_uint32 theFilterSteps;
+};
+
+/**
+ * Method inlined for speed as it is used in the inner pixel loop of
+ * ossimFilterResampler::resampleBilinearTile method.
+ */
+inline const double* ossimFilterTable::getClosestWeights(const double& x,
+                                                         const double& y)const
+{
+   // Extract the decimal part of x and y.
+   double intPartDummy;
+   double decimalPrecisionX = fabs(modf(x, &intPartDummy));
+   double decimalPrecisionY = fabs(modf(y, &intPartDummy));
+   
+   ossim_int32 kernelLine =
+      (ossim_int32)(theFilterSteps*decimalPrecisionY);
+   ossim_int32 kernelSamp =
+      (ossim_int32)(theFilterSteps*decimalPrecisionX);
+  
+  return &theWeights[(kernelLine*theFilterSteps +
+                      kernelSamp)*theWidthHeight];
+}
+
+#endif /* End of "#ifndef ossimFilterTable_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgHeader.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgHeader.cpp
new file mode 100644
index 0000000000..0e5ce93951
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgHeader.cpp
@@ -0,0 +1,499 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// Description: This class encapsulates the image parameters and
+//              support data for a ADRG image file(s).
+//
+//********************************************************************
+// $Id: ossimAdrgHeader.cpp,v 1.7 2005/02/13 16:08:04 dburken Exp $
+
+#include <iostream>
+
+using namespace std;
+
+#include <imaging/formats/adrg/ossimAdrgHeader.h>
+#include <imaging/formats/adrg/ossimIso8211.h>
+
+//**************************************************************************
+// Constructor
+//**************************************************************************
+ossimAdrgHeader::ossimAdrgHeader(const ossimFilename& img_file)
+   :
+      theErrorStatus(OSSIM_OK),
+      theHeaderFile(ossimFilename("")),
+      theImageFile(img_file),
+      theValidImageRect(0,0,0,0),
+      thePixelType(OSSIM_UCHAR),
+      theInterleaveType(OSSIM_BSQ),
+      theNumberOfBands(3),
+      theLines(0),
+      theSamples(0),
+      theHeaderSize(0),
+      theTim(0)
+{
+   // Validate header file exists.
+   ossimFilename tmp_file;
+   ossimFilename tmp_path;
+   ossimFilename tmp_base;
+   ossimFilename tmp_hdr1;
+   ossimFilename tmp_hdr2;
+
+   tmp_file = theImageFile.file();
+   tmp_path = theImageFile.path();
+   tmp_base = tmp_file.beforePos(6);
+
+   tmp_hdr1 = tmp_path.dirCat(tmp_base);
+   tmp_hdr1 += "01.GEN";
+
+   tmp_hdr2 = tmp_path.dirCat(tmp_base);
+   tmp_hdr2 += "01.gen";
+
+   // we will force an open on the .img file
+   //
+   if(img_file.ext().downcase() != "img")
+   {
+      theErrorStatus = OSSIM_ERROR;
+      return;
+   }
+   if(tmp_hdr1.exists())
+   {
+      theHeaderFile = tmp_hdr1;
+   }
+   else if(tmp_hdr2.exists())
+   {
+      theHeaderFile = tmp_hdr2;
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      return;
+   }
+
+   // Parse header for all needed support data.
+   parse();
+}
+
+//**************************************************************************
+// Destructor
+//**************************************************************************
+ossimAdrgHeader::~ossimAdrgHeader()
+{
+   if(theTim)
+      delete [] theTim;
+}
+
+//**************************************************************************
+// Parse header
+//**************************************************************************
+void ossimAdrgHeader::parse()
+{
+   // NOTE:  By default, ISO8211 library reports errors to stderr,
+   //        so we don't bother doing it ourselves.  We simply set
+   //        the OSSIM_ERROR flag.
+
+   ossimDDFModule oModule;
+   ossimDDFRecord* oRecord;
+
+   // Open header file which is ISO8211 encoded.
+   if(!oModule.Open(theHeaderFile.chars()) )
+   {
+      theErrorStatus = OSSIM_ERROR;
+      return;
+   }
+
+   oRecord = oModule.ReadRecord();
+
+   ossimDDFField* oField = oRecord->FindField("DRF");
+   int bytesOfData = oField->GetDataSize();
+   int nBytesConsumed = 0;
+   const char* rawFieldData;
+
+   ossimDDFFieldDefn* fieldDefn = oField->GetFieldDefn();
+   ossimDDFSubfieldDefn* nfile = fieldDefn->FindSubfieldDefn("NOZ");
+   rawFieldData = oField->GetSubfieldData(nfile);
+   ossimString num_img_files = nfile->ExtractStringData(rawFieldData,
+                                                        bytesOfData,
+                                                        &nBytesConsumed);
+
+   // Number of ZDR images
+   ossim_uint32 num_ifiles = (ossim_uint32)ossimString::toInt(num_img_files);
+
+   // Skip overview record.
+   oRecord = oModule.ReadRecord();
+
+   // Validate this is the correct record and it is an ADRG image.
+   ossimString img_file = "";
+   ossimString img_base = theImageFile.fileNoExtension();
+   img_base.downcase();
+
+   // Find the correct geometry record corresponding to the image file.
+   ossim_uint32 count = 0;
+   while(count < num_ifiles)
+   {
+      oField = oRecord->FindField("001");
+      bytesOfData = oField->GetDataSize();
+      nBytesConsumed = 0;
+      
+      fieldDefn = oField->GetFieldDefn();
+      ossimDDFSubfieldDefn* rty = fieldDefn->FindSubfieldDefn("RTY");  
+      rawFieldData = oField->GetSubfieldData(rty);
+      ossimString rtype = rty->ExtractStringData(rawFieldData,
+                                                 bytesOfData,
+                                                 &nBytesConsumed);
+
+      // Found general information record
+      if(rtype == "GIN")
+      {
+         // Validate that this is an ADRG header file.
+         oField = oRecord->FindField("DSI");
+         bytesOfData = oField->GetDataSize();
+         nBytesConsumed = 0;
+         
+         fieldDefn = oField->GetFieldDefn();
+         ossimDDFSubfieldDefn* ptype = fieldDefn->FindSubfieldDefn("PRT");  
+         rawFieldData = oField->GetSubfieldData(ptype);
+         ossimString product_type = ptype->ExtractStringData(rawFieldData,
+                                                             bytesOfData,
+                                                             &nBytesConsumed);
+         
+         if(!(strncmp(product_type.c_str(), "ADRG", 4) == 0))
+         {
+            cout << "File does not appear to be an ADRG header file: "
+                 << theHeaderFile.chars() << endl;
+            
+            theErrorStatus = OSSIM_ERROR;
+            return;      
+         }
+         
+         fieldDefn = oField->GetFieldDefn();
+         ossimDDFSubfieldDefn* ifile = fieldDefn->FindSubfieldDefn("NAM");
+         rawFieldData = oField->GetSubfieldData(ifile);
+         img_file = ifile->ExtractStringData(rawFieldData, bytesOfData,
+                                             &nBytesConsumed);
+         img_file.downcase();
+         
+         count++;
+
+         if(img_base == img_file)
+            break;
+         else
+            oRecord = oModule.ReadRecord();
+      }
+      else
+         oRecord = oModule.ReadRecord();
+   }
+
+   // Find Distribution Rectangle name.
+   oField = oRecord->FindField("GEN");
+   bytesOfData = oField->GetDataSize();
+   nBytesConsumed = 0;
+   
+   fieldDefn = oField->GetFieldDefn();
+
+   // Find Subfield names.
+   ossimDDFSubfieldDefn* min_lon = fieldDefn->FindSubfieldDefn("SWO");  
+   ossimDDFSubfieldDefn* min_lat = fieldDefn->FindSubfieldDefn("SWA");  
+   ossimDDFSubfieldDefn* max_lon = fieldDefn->FindSubfieldDefn("NEO");  
+   ossimDDFSubfieldDefn* max_lat = fieldDefn->FindSubfieldDefn("NEA");  
+      
+   // Extract the min/max lon/lat coordinates.
+   rawFieldData = oField->GetSubfieldData(min_lon);
+   theMinLon = min_lon->ExtractStringData(rawFieldData,
+                                          bytesOfData,
+                                          &nBytesConsumed);
+   rawFieldData = oField->GetSubfieldData(min_lat);
+   theMinLat = min_lat->ExtractStringData(rawFieldData,
+                                          bytesOfData,
+                                          &nBytesConsumed);
+   rawFieldData = oField->GetSubfieldData(max_lon);
+   theMaxLon = max_lon->ExtractStringData(rawFieldData,
+                                          bytesOfData,
+                                          &nBytesConsumed);
+   rawFieldData = oField->GetSubfieldData(max_lat);
+   theMaxLat = max_lat->ExtractStringData(rawFieldData,
+                                          bytesOfData,
+                                          &nBytesConsumed);   
+   
+   // Find the DATA_SET_PARAMETERS_FIELD
+   oField = oRecord->FindField("SPR");
+   bytesOfData = oField->GetDataSize();
+   nBytesConsumed = 0;
+
+   fieldDefn = oField->GetFieldDefn();
+
+   // Find subfields.
+   ossimDDFSubfieldDefn* start_row = fieldDefn->FindSubfieldDefn("NUL");   
+   ossimDDFSubfieldDefn* stop_col  = fieldDefn->FindSubfieldDefn("NUS");   
+   ossimDDFSubfieldDefn* stop_row  = fieldDefn->FindSubfieldDefn("NLL");   
+   ossimDDFSubfieldDefn* start_col = fieldDefn->FindSubfieldDefn("NLS");   
+   ossimDDFSubfieldDefn* lines     = fieldDefn->FindSubfieldDefn("NFL");   
+   ossimDDFSubfieldDefn* samples   = fieldDefn->FindSubfieldDefn("NFC");   
+   ossimDDFSubfieldDefn* tif       = fieldDefn->FindSubfieldDefn("TIF");
+
+   // Extract the number of lines & samples per tile.
+   rawFieldData = oField->GetSubfieldData(start_row);
+   theStartRow = atoi(start_row->ExtractStringData(rawFieldData,
+                                                   bytesOfData,
+                                                   &nBytesConsumed));
+   rawFieldData = oField->GetSubfieldData(start_col);
+   theStartCol = atoi(start_col->ExtractStringData(rawFieldData,
+                                                   bytesOfData,
+                                                   &nBytesConsumed));
+   rawFieldData = oField->GetSubfieldData(stop_row);
+   theStopRow = atoi(stop_row->ExtractStringData(rawFieldData,
+                                                   bytesOfData,
+                                                   &nBytesConsumed));
+   rawFieldData = oField->GetSubfieldData(stop_col);
+   theStopCol = atoi(stop_col->ExtractStringData(rawFieldData,
+                                                   bytesOfData,
+                                                   &nBytesConsumed));
+   rawFieldData = oField->GetSubfieldData(lines);
+   theLinesInTiles = atoi(lines->ExtractStringData(rawFieldData,
+                                                   bytesOfData,
+                                                   &nBytesConsumed));
+   rawFieldData = oField->GetSubfieldData(samples);
+   theSamplesInTiles = atoi(samples->ExtractStringData(rawFieldData,
+                                                       bytesOfData,
+                                                       &nBytesConsumed));
+   rawFieldData = oField->GetSubfieldData(tif);
+   theTif = tif->ExtractStringData(rawFieldData, bytesOfData,
+                                   &nBytesConsumed);
+   
+   theLines = theLinesInTiles * ADRG_TILE_SIZE;
+   theSamples = theSamplesInTiles * ADRG_TILE_SIZE;  
+
+   theValidImageRect = ossimIrect(0, 0, theSamples - 1, theLines - 1);
+
+   // Initialize the TIM (tile index map).
+   theTim = new ossim_uint32[theLinesInTiles * theSamplesInTiles];
+
+   // Read in the tile index map (TIM) if it exists.
+   if(strncmp(theTif.c_str(), "Y", 1) == 0)
+   {
+      // Find the TILE_INDEX_MAP_FIELD
+      oField = oRecord->FindField("TIM");
+      bytesOfData = oField->GetDataSize();
+      fieldDefn = oField->GetFieldDefn();
+      rawFieldData = oField->GetData();
+      nBytesConsumed = 0;
+
+      for(ossim_uint32 r = 0; r < theLinesInTiles * theSamplesInTiles; r++ )
+      {
+         ossimDDFSubfieldDefn* tim = fieldDefn->FindSubfieldDefn("TSI");
+         theTim[r] = atoi(tim->ExtractStringData(rawFieldData, bytesOfData,
+                                                 &nBytesConsumed));
+         bytesOfData -= nBytesConsumed;
+         rawFieldData += nBytesConsumed;
+      }
+   }
+   else
+   {
+      for(ossim_uint32 m = 0; m < (theLinesInTiles * theSamplesInTiles); m++)
+         theTim[m] = (m+1);
+   }
+   
+   // Close module used for reading encoded header file.
+   oModule.Close();
+}
+
+//*********************************************************************
+// tim(int32 row, int32 col)
+//*********************************************************************
+ossim_uint32 ossimAdrgHeader::tim(ossim_uint32 row, ossim_uint32 col) const
+{
+   return ( theTim[(row * theSamplesInTiles) + col] );
+}
+
+//*********************************************************************
+// operator <<
+//*********************************************************************
+ostream& operator<<(ostream& os, const ossimAdrgHeader& adrg)
+{
+   os << "\nContents of ADRG Header file (.gen):"
+      << "\nImage File = " << adrg.theImageFile
+      << "\nHeader File = " << adrg.theHeaderFile
+      << "\nPixelType = " << adrg.thePixelType
+      << "\nInterleaveType = " << adrg.theInterleaveType
+      << "\nNumberOfBands = " << adrg.theNumberOfBands
+      << "\nLines = " << adrg.theLines
+      << "\nLines (tiles) = " << adrg.theLinesInTiles
+      << "\nSamples = " << adrg.theSamples      
+      << "\nSamples (tiles) = " << adrg.theSamplesInTiles
+      << "\nHeaderSize = " << adrg.theHeaderSize
+      << "\nValidImageRect = " << adrg.theValidImageRect
+      << "\nTIF = " << adrg.theTif
+      << "\nMin Lon = " << adrg.theMinLon
+      << "\nMin Lat = " << adrg.theMinLat
+      << "\nMax Lon = " << adrg.theMaxLon
+      << "\nMax Lat = " << adrg.theMaxLat
+      << "\nStart Row = " << adrg.theStartRow
+      << "\nStart Col = " << adrg.theStartCol
+      << "\nStop Row = " << adrg.theStopRow
+      << "\nStop Col = " << adrg.theStopCol
+      << endl;
+
+   for(ossim_uint32 m = 0; m < (adrg.theLinesInTiles * adrg.theSamplesInTiles); m++)
+      os << "\nTIM[" << m << "] = " << adrg.theTim[m];
+
+   os << endl;
+
+   return(os);
+}
+
+//*********************************************************************
+// Public method:
+//*********************************************************************
+double ossimAdrgHeader::minLongitude() const
+{
+   return parseLongitudeString(theMinLon);
+}
+
+//*********************************************************************
+// Public method:
+//*********************************************************************
+double ossimAdrgHeader::minLatitude() const
+{
+   return parseLatitudeString(theMinLat);
+}
+
+//*********************************************************************
+// Public method:
+//*********************************************************************
+double ossimAdrgHeader::maxLongitude() const
+{
+   return parseLongitudeString(theMaxLon);
+}
+
+//*********************************************************************
+// Public method:
+//*********************************************************************
+double ossimAdrgHeader::maxLatitude() const
+{
+   return parseLatitudeString(theMaxLat);
+}
+
+//*********************************************************************
+// Private method:
+//*********************************************************************
+double ossimAdrgHeader::parseLongitudeString(const ossimString& lon) const
+{
+   static const char MODULE[] = "ossimAdrgHeader::parseLongitudeString";
+
+   // Format = +|-dddmmss.ss
+   
+   if (lon.size() != 11)
+   {
+      cerr << MODULE << " Longitude string error!"
+           << "Bad longitude string:  " << lon.c_str() << endl;
+   }
+         
+   const char* cstr = lon.c_str();
+
+   double degrees = 0.0;
+   double sign = 1.0;
+   char tmp_str[6];
+   
+   // Get the sign.
+   if (cstr[0] == '-') sign = -1.0;
+
+   // Get the degrees.
+   tmp_str[3] = '\0';
+   cstr++; // Increment past the sign. 
+   strncpy(tmp_str, cstr, 3);
+
+   if (tmp_str)
+   {
+      degrees = atof(tmp_str);
+   }
+   
+   // Get the minutes.
+   tmp_str[2] = '\0';
+   cstr += 3; // Increment to the minutes.
+   strncpy(tmp_str, cstr, 2);
+   
+   if (tmp_str)
+   {
+      degrees += atof(tmp_str) / 60.0;
+   }
+   
+   // Get the seconds.
+   tmp_str[5] = '\0';
+   cstr += 2; // Increment to seconds.
+   strncpy(tmp_str, cstr, 5);
+   
+   if (tmp_str)
+   {
+      degrees += atof(tmp_str) / 3600.0;
+   }
+   
+   // Set the sign.
+   degrees *= sign;
+
+   return degrees;
+}
+
+//*********************************************************************
+// Private method:
+//*********************************************************************
+double ossimAdrgHeader::parseLatitudeString(const ossimString& lat) const
+{
+   static const char MODULE[] = "ossimAdrgHeader::parseLatitudeString";
+   
+   // Format = +|-ddmmss.ss
+   
+   if (lat.size() != 10)
+   {
+      cerr << MODULE << " Latitude string error!"
+           << "Bad latitude string:  " << lat.c_str() << endl;
+   }
+   
+   const char* cstr = lat.c_str();
+   
+   double degrees = 0.0;
+   double sign = 1.0;
+   char tmp_str[6];
+   
+   // Get the sign.
+   if (cstr[0] == '-') sign = -1.0;
+   
+   // Get the degrees.
+   tmp_str[2] = '\0';
+   cstr++; // Increment past the sign. 
+   strncpy(tmp_str, cstr, 2);
+   
+   if (tmp_str)
+   {
+      degrees = atof(tmp_str);
+   }
+   
+   // Get the minutes.
+   tmp_str[2] = '\0';
+   cstr += 2; // Increment to the minutes.
+   strncpy(tmp_str, cstr, 2);
+
+   if (tmp_str)
+   {
+      degrees += atof(tmp_str) / 60.0;
+   }
+   
+   // Get the seconds.
+   tmp_str[5] = '\0';
+   cstr += 2; // Increment to seconds.
+   strncpy(tmp_str, cstr, 5);
+   
+   if (tmp_str)
+   {
+      degrees += atof(tmp_str) / 3600.0;
+   }
+   
+   // Set the sign.
+   degrees *= sign;
+   
+   return degrees;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgHeader.h b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgHeader.h
new file mode 100644
index 0000000000..e8a824b6e5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgHeader.h
@@ -0,0 +1,130 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+// Description: This class encapsulates the image parameters and
+//              support data for a ADRG image file(s).
+//
+//********************************************************************
+// $Id: ossimAdrgHeader.h,v 1.3 2004/06/23 20:10:55 dburken Exp $
+
+#ifndef ossimAdrgHeader_H
+#define ossimAdrgHeader_H
+
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimIrect.h"
+
+class OSSIMDLLEXPORT ossimAdrgHeader
+{
+public:
+   // Instantiated with the image file (.img)
+   ossimAdrgHeader(const ossimFilename& img_file);
+   ~ossimAdrgHeader();
+   
+   enum ErrorStatus
+   {
+      OSSIM_OK    = 0,
+      OSSIM_ERROR = 1
+   };
+
+   enum
+   {
+      ADRG_TILE_SIZE = 128
+   };
+   
+   int errorStatus() const { return theErrorStatus; }
+
+   ossimFilename file()
+      const { return theHeaderFile; }
+   ossimFilename imageFile()
+      const { return theImageFile; }
+   ossimIrect validImageRect()
+      const { return theValidImageRect; }
+
+   ossim_uint32    pixelType()      const { return thePixelType; }
+   ossim_uint32    interleaveType() const { return theInterleaveType; }
+   ossim_uint32    numberOfBands()  const { return theNumberOfBands; }
+   ossim_uint32    lines()          const { return theLines; }
+   ossim_uint32    tlines()         const { return theLinesInTiles; }
+   ossim_uint32    samples()        const { return theSamples; }
+   ossim_uint32    tsamples()       const { return theSamplesInTiles; }
+   ossim_uint32    headerSize()     const { return theHeaderSize; }
+   ossim_uint32    startRow()       const { return theStartRow; }
+   ossim_uint32    startCol()       const { return theStartCol; }
+   ossim_uint32    stopRow()        const { return theStopRow; }
+   ossim_uint32    stopCol()        const { return theStopCol; }
+
+   ossim_uint32    tim(ossim_uint32 row, ossim_uint32 col) const;
+   
+   ossimString minLon() const { return theMinLon; }
+   ossimString minLat() const { return theMinLat; }
+   ossimString maxLon() const { return theMaxLon; }
+   ossimString maxLat() const { return theMaxLat; }
+
+   double minLongitude()   const;
+   double minLatitude()    const;
+   double maxLongitude()   const;
+   double maxLatitude()    const;
+   
+   friend ostream& operator<<(ostream& os, const ossimAdrgHeader& adrg);
+
+private:
+
+   // Returns the longitude in decimal degrees given the formatted string.
+   double parseLongitudeString(const ossimString& lon) const;
+
+   // Returns the latitude in decimal degrees given the formatted string.
+   double parseLatitudeString(const ossimString& lat) const;
+   
+   // prevent use.
+   ossimAdrgHeader();
+   ossimAdrgHeader(const ossimAdrgHeader& source);
+
+   ErrorStatus theErrorStatus;
+
+   ossimFilename theHeaderFile;
+   ossimFilename theImageFile;
+   ossimIrect    theValidImageRect;
+   
+   ossim_uint32  thePixelType;
+   ossim_uint32  theInterleaveType;
+   ossim_uint32  theNumberOfBands;
+   ossim_uint32  theLines;
+   ossim_uint32  theLinesInTiles;
+   ossim_uint32  theSamples;
+   ossim_uint32  theSamplesInTiles;
+   ossim_uint32  theHeaderSize;
+   ossim_uint32  theStartRow;
+   ossim_uint32  theStartCol;
+   ossim_uint32  theStopRow;
+   ossim_uint32  theStopCol;
+   ossim_uint32* theTim;   // Tile index map value -- only valid if TIF is 'Y'.
+   
+   ossimString theMinLon;
+   ossimString theMinLat;
+   ossimString theMaxLon;
+   ossimString theMaxLat;
+   ossimString theTif;  // Tile index map flag -- Y indicates there are tiles
+                        // with no data; N indicates that all tiles contain
+                        // RGB graphic data.
+
+   void parse();
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgTileSource.cpp
new file mode 100644
index 0000000000..250ece1f42
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgTileSource.cpp
@@ -0,0 +1,782 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Ken Melero
+//
+// Author: Ken Melero
+// 
+// Description: This class give the capability to access tiles from an
+//              ADRG file.
+//
+//********************************************************************
+// $Id: ossimAdrgTileSource.cpp,v 1.50 2005/02/11 15:07:30 dburken Exp $
+
+#include <iostream>
+using namespace std;
+
+#include <imaging/formats/adrg/ossimAdrgTileSource.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/ossimU8ImageData.h>
+
+RTTI_DEF1(ossimAdrgTileSource, "ossimAdrgTileSource", ossimImageHandler)
+
+//***
+// Static trace for debugging
+//***
+static ossimTrace traceDebug("ossimAdrgTileSource:debug");
+
+//***
+// NOTE:  Currently this tilesource is hard-coded to access tiles
+//        from the ZDR image file. This will change as I wrote support
+//        data classes for all the ADRG image files: ZDR, overview,
+//        and legend support data.  Next step in development will
+//        be to put in flags to access overview and legend image files.
+//***
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimAdrgTileSource::ossimAdrgTileSource()
+   :
+      ossimImageHandler(),
+      theTile(NULL),
+      theTileBuffer(NULL),
+      theFileStr(),
+      theAdrgHeader(NULL)
+{
+   // Construction not complete.  Users should call "open" method.
+}
+
+ossimAdrgTileSource::~ossimAdrgTileSource()
+{
+   if(theAdrgHeader)
+   {
+      delete theAdrgHeader;
+      theAdrgHeader = NULL;
+   }
+   if (theTileBuffer)
+   {
+      delete [] theTileBuffer;
+      theTileBuffer = NULL;
+   }
+
+   close();
+}
+
+ossimRefPtr<ossimImageData> ossimAdrgTileSource::getTile(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   long w = rect.width();
+   long h = rect.height();
+   
+   // This tile source bypassed, or invalid res level, return a blank tile.
+   if (!isSourceEnabled() || !isValidRLevel(resLevel))
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   if (theOverview)
+   {
+      if (theOverview->hasR0() || resLevel)
+      {
+         return theOverview->getTile(rect, resLevel);
+      }
+   }
+
+   long tileW = theTile->getWidth();
+   long tileH = theTile->getHeight();
+   if((w != tileW)||
+      (h != tileH))
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+      }
+   }
+   theTile->setOrigin(rect.ul());
+   ossimIrect image_rect = getImageRectangle(resLevel);
+   
+   //***
+   // See if any point of the requested tile is in the image.
+   //***
+   if ( rect.intersects(image_rect) )
+   {
+      ossimIrect clip_rect = rect.clipToRect(image_rect);
+      
+      if ( !rect.completely_within(clip_rect) )
+      {
+         // Start with a blank tile.
+         theTile->makeBlank();
+      }
+
+      // Load the tile buffer with data from the adrg.
+      if (fillBuffer(rect, clip_rect))
+      {
+//         theTile->setOrigin(rect.ul()); // Capture the origin...
+         theTile->validate();
+         return theTile;
+      }
+      else
+      {
+         return ossimRefPtr<ossimImageData>();
+      }
+      
+   } // End of if ( tile_rect.intersects(image_rect) )
+
+   // No part of requested tile within the image rectangle.
+   return ossimRefPtr<ossimImageData>();
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimAdrgTileSource::fillBuffer(const ossimIrect& tile_rect,
+                                     const ossimIrect& clip_rect)
+{
+   const ossim_uint8 NULL_PIXEL         = (ossim_uint8)theTile->getNullPix(0);
+   const ossim_int32 TILE_SIZE_PER_BAND = theTile->getSizePerBand();
+
+   //***
+   // Shift the upper left corner of the "clip_rect" to the an even chunk
+   // boundry.
+   //***
+   ossimIpt tileOrigin = clip_rect.ul();
+   adjustToStartOfTile(tileOrigin);
+
+   //***
+   // Calculate the number of tiles needed in the line/sample directions.
+   //***
+   ossim_int32 size_in_x = clip_rect.lr().x - tileOrigin.x + 1;
+   ossim_int32 size_in_y = clip_rect.lr().y - tileOrigin.y + 1;
+   
+   ossim_int32 tiles_in_x_dir = size_in_x / ADRG_TILE_WIDTH  + (size_in_x % ADRG_TILE_WIDTH  ? 1 : 0);
+   ossim_int32 tiles_in_y_dir = size_in_y / ADRG_TILE_HEIGHT + (size_in_y % ADRG_TILE_HEIGHT ? 1 : 0);
+
+
+   ossimIpt ulTilePt = tileOrigin;
+   
+   // Chunk loop in line direction.
+   for (int32 y=0; y<tiles_in_y_dir; y++)
+   {
+      ulTilePt.x = tileOrigin.x;
+
+      // Tile loop in sample direction.
+      for (int32 x=0; x<tiles_in_x_dir; x++)
+      {
+         ossimIrect adrg_tile_rect(ulTilePt.x,
+                              ulTilePt.y,
+                              ulTilePt.x + ADRG_TILE_SIZE - 1,
+                              ulTilePt.y + ADRG_TILE_SIZE - 1);
+         
+         if (adrg_tile_rect.intersects(clip_rect))
+         {
+            ossimIrect tile_clip_rect = clip_rect.clipToRect(adrg_tile_rect);
+            
+            //***
+            // Some point in the chip intersect the tile so grab the
+            // data.
+            //***
+            ossim_int32 row = (ossim_int32) ulTilePt.y / ADRG_TILE_HEIGHT; 
+            ossim_int32 col = (ossim_int32) ulTilePt.x / ADRG_TILE_WIDTH;
+            ossim_int32 tileOffset = theAdrgHeader->tim(row, col);
+
+            if(tileOffset != 0)
+            {
+               // Get the data.
+               int seek_position = (tileOffset - 1) * 49152 + 2048;
+               int band;
+
+               for (band=0; band<3; band++)
+               {
+                  // Seek to the chip
+                  theFileStr.seekg(seek_position, ios::beg);
+
+                  //***
+                  // Read the chip from the ccf file into the chunk buffer.
+                  // This will get all the bands.  Bands are interleaved by
+                  // chip.
+                  //***
+                  if (!theFileStr.read((char*)theTileBuffer,
+                                       ADRG_TILE_SIZE))
+                  {
+                     theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+                     return false;
+                  }
+
+                  seek_position += BAND_OFFSET;
+
+                  //***
+                  // Get a pointer positioned at the first valid pixel in
+                  // the adrg tile.
+                  //***
+                  ossim_uint8* s
+                     = theTileBuffer + 
+                     (tile_clip_rect.ul().y - adrg_tile_rect.ul().y) *
+                     ADRG_TILE_WIDTH + tile_clip_rect.ul().x -
+                     adrg_tile_rect.ul().x;
+
+                  //***
+                  // Get a pointer positioned at the first valid pixel in
+                  // the tile.
+                  //***
+                  ossim_uint8* d
+                     = (ossim_uint8*)theTile->getBuf() +
+                     band * TILE_SIZE_PER_BAND +
+                     (tile_clip_rect.ul().y - tile_rect.ul().y) *
+                     theTile->getWidth() + tile_clip_rect.ul().x -
+                     tile_rect.ul().x;      
+
+                  // Line loop through valid portion of the adrg tile.
+                  for (ossim_int32 line = tile_clip_rect.ul().y;
+                       line <= tile_clip_rect.lr().y;
+                       line++)
+                  {
+                     // Sample loop through the adrg tile.
+                     int i=0;
+                     for (ossim_int32 sample = tile_clip_rect.ul().x;
+                          sample <= tile_clip_rect.lr().x;
+                          sample++)
+                     {
+                        d[i] = s[i];
+                        i++;
+                     }
+
+                     // Increment the pointers by one line.
+                     s += ADRG_TILE_WIDTH;
+                     d += theTile->getWidth();
+                  }
+
+               } // End of band loop.
+
+            } // End of if (tileOffset != 0)
+            else
+            {
+               // The adrg tile is null.
+
+               for (int band=0; band<3; band++)
+               {
+                  //***
+                  // Get a pointer positioned at the first valid pixel in
+                  // the tile.
+                  //***
+                  ossim_uint8* d
+                     = (ossim_uint8*)theTile->getBuf() +
+                     band * TILE_SIZE_PER_BAND +
+                     (tile_clip_rect.ul().y - tile_rect.ul().y) *
+                     theTile->getWidth() + tile_clip_rect.ul().x -
+                     tile_rect.ul().x;      
+                  
+                  // Line loop through valid portion of the adrg tile.
+                  for (ossim_int32 line = tile_clip_rect.ul().y;
+                       line <= tile_clip_rect.lr().y;
+                       line++)
+                  {
+                     // Sample loop through a chip.
+                     int i=0;
+                     for (ossim_int32 sample = tile_clip_rect.ul().x;
+                          sample <= tile_clip_rect.lr().x;
+                          sample++)
+                     {
+                        d[i] = NULL_PIXEL;
+                        i++;
+                     }
+                     
+                     // Increment the pointers by one line.
+                     d += theTile->getWidth();
+                  }
+                  
+               } // End of band loop.
+
+            } // End of else.
+
+         } // End of if (adrg_tile_rect.intersects(clip_rect))
+         
+         ulTilePt.x += ADRG_TILE_WIDTH;
+         
+      }  // End of tile loop in the sample direction.
+
+      ulTilePt.y += ADRG_TILE_HEIGHT;
+      
+   }  // End of tile loop in the line direction.
+
+   return true;
+}
+
+ossim_uint32 ossimAdrgTileSource::getNumberOfOutputBands()const
+{
+   return getNumberOfInputBands();
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ossimIrect
+ossimAdrgTileSource::getImageRectangle(ossim_uint32 reduced_res_level) const
+{
+   return ossimIrect(0,                         // upper left x
+                     0,                         // upper left y
+                     getNumberOfSamples(reduced_res_level) - 1,  // lower right x
+                     getNumberOfLines(reduced_res_level)   - 1); // lower right y
+}
+
+void ossimAdrgTileSource::close()
+{
+   if(theAdrgHeader)
+   {
+      delete theAdrgHeader;
+      theAdrgHeader = NULL;
+   }
+   if(theFileStr.is_open())
+   {
+      theFileStr.close();
+   }
+   theTile = NULL;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimAdrgTileSource::open()
+{
+   static const char MODULE[] = "ossimAdrgTileSource::open";
+
+   if(traceDebug())
+   {
+      CLOG << "Entered..."<<endl;
+   }
+   if(isOpen())
+   {
+      close();
+   }
+   if(theAdrgHeader)
+   {
+      delete theAdrgHeader;
+      theAdrgHeader = NULL;
+   }
+   // Instantiate support data class to parse header file.
+   theAdrgHeader = new ossimAdrgHeader(theImageFile);
+
+   // Check for errors.
+   if (theAdrgHeader->errorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      if (traceDebug())
+      {
+         cerr << MODULE << " Error in ossimAdrg header detected." << endl;
+      }
+
+      close();
+      return false;
+   }
+
+   theFileStr.open(theAdrgHeader->imageFile().c_str(),
+                   ios::in | ios::binary);
+
+   // Check the file pointer.
+   if(!theFileStr)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      if (traceDebug())
+      {
+         cerr << MODULE << "\nCannot open:  "
+              << theAdrgHeader->imageFile().c_str() << endl;
+      }
+      close();
+      
+      return false;
+   }
+   
+   if(traceDebug())
+   {
+      CLOG << "File is opened -> "<< theAdrgHeader->imageFile()<<endl;
+   }
+
+   // allow the base handler to check for other overrides
+   completeOpen();
+   // Allocate memory.
+   theTile      = ossimImageDataFactory::instance()->create(this, this);
+   theTile->initialize();
+   theTileBuffer  = new ossim_uint8[ADRG_TILE_SIZE];
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nminLon:   " << theAdrgHeader->minLon()
+         << "\nminLond:  " << theAdrgHeader->minLongitude() 
+         << "\nminLat:   " << theAdrgHeader->minLat()
+         << "\nminLatd:  " << theAdrgHeader->minLatitude()
+         << "\nmaxLon:   " << theAdrgHeader->maxLon()
+         << "\nmaxLond:  " << theAdrgHeader->maxLongitude()
+         << "\nmaxLat:   " << theAdrgHeader->maxLat()
+         << "\nmaxLatd:  " << theAdrgHeader->maxLatitude()
+         << endl;
+   }
+   
+   return true;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimAdrgTileSource::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix) const
+{
+   // Currently nothing to do here.
+   return ossimImageHandler::saveState(kwl, prefix);
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimAdrgTileSource::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   if (ossimImageHandler::loadState(kwl, prefix))
+   {
+      if (open())
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimAdrgTileSource::getImageGeometry(ossimKeywordlist& kwl,
+                                           const char* prefix)
+{
+
+   if(ossimImageSource::getImageGeometry(kwl, prefix))
+   {
+      return true;
+   }
+   
+   //***
+   // NOTE:
+   // All these keywords are going to change.  Hard coded right now for test.
+   //***
+   
+   // model type.  This will be going away soon and will
+   // be replaced with projection.type bellow.
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           "ossimEquDistCylProjection",
+           true);
+   
+   ossimString projPref = prefix?prefix:"";
+
+   // origin of latitude
+   double lat = (theAdrgHeader->maxLatitude() +
+                 theAdrgHeader->minLatitude()) / 2.0;
+   
+   // central meridian.
+   double lon = (theAdrgHeader->maxLongitude() +
+                 theAdrgHeader->minLongitude()) / 2.0;
+   
+   //***
+   // Make a projection to get the easting / northing of the tie point and
+   // the scale in meters.
+   //***
+   const ossimDatum* datum = ossimDatumFactory::instance()->wgs84();
+
+   ossimProjection* proj
+      = new ossimEquDistCylProjection(*(datum->ellipsoid()),
+                                      ossimGpt(lat, lon),
+                                      0.0,   // false easting
+                                      0.0);  // false northing
+   proj->saveState(kwl, projPref);
+   
+   // Get the scale in meters.
+   ossimGpt ul_gpt(theAdrgHeader->maxLatitude(),
+                   theAdrgHeader->minLongitude(),
+                   OSSIM_DBL_NAN);
+
+   //   ossimDpt ul_dpt = proj->forward(ul_gpt);
+   
+   ossimGpt ur_gpt(theAdrgHeader->maxLatitude(),
+                   theAdrgHeader->maxLongitude(),
+                   0.0);
+
+   //   ossimDpt ur_dpt = proj->forward(ur_gpt);
+
+   ossimGpt ll_gpt(theAdrgHeader->minLatitude(),
+                   theAdrgHeader->minLongitude(),
+                   0.0);
+   
+   //   ossimDpt ll_dpt = proj->forward(ll_gpt);
+   
+   ossimGpt lr_gpt(theAdrgHeader->minLatitude(),
+                   theAdrgHeader->maxLongitude(),
+                   0.0);
+   
+   //   ossimDpt lr_dpt = proj->forward(lr_gpt);
+
+   double samples = theAdrgHeader->stopCol() - theAdrgHeader->startCol() + 1;
+   double lines   = theAdrgHeader->stopRow() - theAdrgHeader->startRow() + 1;
+
+//    double meters_per_pix_x = (ur_dpt.x - ul_dpt.x) / samples;
+//    double meters_per_pix_y = (ur_dpt.y - lr_dpt.y) / lines;
+
+   // will remove these two and replace with the next two
+   // we will for now just duplicate with different prefix.
+//    kwl.add(prefix,
+//            ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+//            meters_per_pix_x,
+//            true);
+
+//    kwl.add(prefix,
+//            ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+//            meters_per_pix_y,
+//            true);
+
+
+   //***
+   // To get the tie point the padding must be accounted for...
+   // The min / max lat / lon is relative to the unpadded image.
+   //***
+   double degrees_in_lat_dir = theAdrgHeader->maxLatitude() -
+                               theAdrgHeader->minLatitude();
+   double degrees_in_lon_dir = theAdrgHeader->maxLongitude() -
+                               theAdrgHeader->minLongitude();
+   
+   double degPerPixelY = degrees_in_lat_dir / lines;
+   double degPerPixelX = degrees_in_lon_dir / samples;
+
+//    double ul_lat = theAdrgHeader->maxLatitude() +
+//                    (theAdrgHeader->startRow() - 1.0) * degPerPixelY;
+//    double ul_lon = theAdrgHeader->minLongitude() -
+//                    (theAdrgHeader->startCol() - 1.0) * degPerPixelX;
+   double ul_lat = (theAdrgHeader->maxLatitude() + 
+                    theAdrgHeader->startRow()*degPerPixelY) - (degPerPixelY*.5);
+   double ul_lon = (theAdrgHeader->minLongitude() -
+                    theAdrgHeader->startCol()*degPerPixelX) +  (degPerPixelX*.5);
+
+//    ossimGpt ul_adjusted_gpt(ul_lat,
+//                             ul_lon,
+//                             0.0);
+
+//   ossimDpt ul_adjusted_dpt = proj->forward(ul_adjusted_gpt);
+
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LAT_KW,
+           ul_lat,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LON_KW,
+           ul_lon,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+           degPerPixelY,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+           degPerPixelX,
+           true);
+   
+   
+   // will remove the first two here and replace
+   // with the second 2
+//    kwl.add(prefix,
+//            ossimKeywordNames::TIE_POINT_EASTING_KW,
+//            ul_adjusted_dpt.x,
+//            true);
+
+//    kwl.add(prefix,
+//            ossimKeywordNames::TIE_POINT_NORTHING_KW,
+//            ul_adjusted_dpt.y,
+//            true);
+
+//    kwl.add(projPref,
+//            ossimKeywordNames::TIE_POINT_EASTING_KW,
+//            ul_adjusted_dpt.x,
+//            true);
+
+//    kwl.add(projPref,
+//            ossimKeywordNames::TIE_POINT_NORTHING_KW,
+//            ul_adjusted_dpt.y,
+//            true);
+   
+   // now add the general image geometry to the
+   // list.
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_LINES_KW,
+           getNumberOfLines());
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_SAMPLES_KW,
+           getNumberOfSamples());
+   
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_REDUCED_RES_SETS_KW,
+           getNumberOfDecimationLevels());
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_INPUT_BANDS_KW,
+           getNumberOfInputBands());
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_OUTPUT_BANDS_KW,
+           getNumberOfOutputBands());
+
+   kwl.add(prefix,
+           ossimKeywordNames::DATUM_KW,
+           "WGE",
+           true);
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nminLon:           " << theAdrgHeader->minLon()
+         << "\nminLond:          " << theAdrgHeader->minLongitude() 
+         << "\nminLat:           " << theAdrgHeader->minLat()
+         << "\nminLatd:          " << theAdrgHeader->minLatitude()
+         << "\nmaxLon:           " << theAdrgHeader->maxLon()
+         << "\nmaxLond:          " << theAdrgHeader->maxLongitude()
+         << "\nmaxLat:           " << theAdrgHeader->maxLat()
+         << "\nmaxLatd:          " << theAdrgHeader->maxLatitude()
+         << "\nstartRow:         " << theAdrgHeader->startRow()
+         << "\nstartCol:         " << theAdrgHeader->startCol()
+         << "\nstopRow:          " << theAdrgHeader->stopRow()
+         << "\nstopCol:          " << theAdrgHeader->stopCol()
+//            << "\nul_adjusted_gpt:  " << ul_adjusted_gpt
+         << "\nul_gpt:           " << ul_gpt
+         << "\nur_gpt:           " << ur_gpt
+         << "\nlr_gpt:           " << lr_gpt
+         << "\nll_gpt:           " << ll_gpt
+//            << "\nul_adjusted_dpt:  " << ul_adjusted_dpt
+//            << "\nul_dpt:           " << ul_dpt
+//            << "\nur_dpt:           " << ur_dpt
+//            << "\nlr_dpt:           " << lr_dpt
+//            << "\nll_dpt:           " << ll_dpt
+//            << "\nmeters_per_pix_x: " << meters_per_pix_x
+//            << "\nmeters_per_pix_y: " << meters_per_pix_y
+         << "kwl:\n"               << kwl
+         << endl;
+   }
+
+   setImageGeometry(kwl);
+
+   return true;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossimScalarType ossimAdrgTileSource::getOutputScalarType() const
+{
+  return OSSIM_UCHAR;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimAdrgTileSource::getTileWidth() const
+{
+   return ( theTile.valid() ? theTile->getWidth() : 0 );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimAdrgTileSource::getTileHeight() const
+{
+   return ( theTile.valid() ? theTile->getHeight() : 0 );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimAdrgTileSource::getNumberOfLines(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theAdrgHeader->lines();
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfLines(reduced_res_level);
+   }
+
+   return 0;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimAdrgTileSource::getNumberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theAdrgHeader->samples();
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfSamples(reduced_res_level);
+   }
+
+   return 0;
+}
+
+ossim_uint32 ossimAdrgTileSource::getImageTileWidth() const
+{
+   return ADRG_TILE_WIDTH;
+}
+
+ossim_uint32 ossimAdrgTileSource::getImageTileHeight() const
+{
+   return ADRG_TILE_HEIGHT;
+}
+
+ossimString ossimAdrgTileSource::getShortName()const
+{
+   return ossimString("adrg");
+}
+
+ossimString ossimAdrgTileSource::getLongName()const
+{
+   return ossimString("adrg reader");
+}
+
+ossimString ossimAdrgTileSource::className()const
+{
+   return ossimString("ossimAdrgTileSource");
+}
+
+ossim_uint32 ossimAdrgTileSource::getNumberOfInputBands() const
+{
+   return theAdrgHeader->numberOfBands();
+}
+
+bool ossimAdrgTileSource::isOpen()const
+{
+   return (theAdrgHeader!=NULL);
+}
+
+void ossimAdrgTileSource::adjustToStartOfTile(ossimIpt& pt) const
+{
+   pt.x &= 0xffffff80;
+   pt.y &= 0xffffff80;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgTileSource.h
new file mode 100644
index 0000000000..30a9929f31
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimAdrgTileSource.h
@@ -0,0 +1,175 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Ken Melero
+// 
+// Description: This class give the capability to access tiles from an
+//              ADRG file.
+//
+//********************************************************************
+// $Id: ossimAdrgTileSource.h,v 1.21 2005/07/25 22:42:22 dburken Exp $
+
+#ifndef ossimAdrgTileSource_HEADER
+#define ossimAdrgTileSource_HEADER
+
+#include <fstream>
+using namespace std;
+
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/formats/adrg/ossimAdrgHeader.h>
+
+class ossimImageData;
+
+class OSSIM_DLL ossimAdrgTileSource : public ossimImageHandler
+{
+public:
+   
+   enum
+   {
+      ADRG_TILE_WIDTH  = 128,
+      ADRG_TILE_HEIGHT = 128,
+      ADRG_TILE_SIZE   = 16384, // 128 * 128,
+      BAND_OFFSET      = 16384, // 8 * 2048,
+      NUMBER_OF_BANDS  = 3
+   };
+   
+   enum ADRG_COLOR
+   {
+      RED_BAND    = 0,  // the ADRG rgb value
+      GREEN_BAND  = 1,
+      BLUE_BAND   = 2
+   };
+      
+   ossimAdrgTileSource();
+   virtual ~ossimAdrgTileSource();
+
+   virtual ossimString getShortName()const;
+   virtual ossimString getLongName()const;
+   virtual ossimString className()const;
+
+   /**
+    *  @return Returns true on success, false on error.
+    *
+    *  @note This method relies on the data member ossimImageData::theImageFile
+    *  being set.  Callers should do a "setFilename" prior to calling this
+    *  method or use the ossimImageHandler::open that takes a file name and an
+    *  entry index.
+    */
+   virtual bool open();
+
+   /**
+    *  Returns a pointer to a tile given an origin representing the upper
+    *  left corner of the tile to grab from the image.
+    *  Satisfies pure virtual requirement from TileSource class.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+   
+   /**
+    *  Returns the number of bands in the image.
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfInputBands() const;
+   
+   virtual ossim_uint32 getNumberOfOutputBands()const;
+
+   /**
+    *  Returns the number of lines in the image.
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    *  Returns the number of samples in the image.  
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
+
+   /**
+    * Returns the zero based image rectangle for the reduced resolution data
+    * set (rrds) passed in.  Note that rrds 0 is the highest resolution rrds.
+    */
+   virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /**
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *  Returns true if geometry info is present, false if not.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+   
+   /**
+    * Returns the output pixel type of the tile source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32 getTileWidth() const;
+
+   virtual void close();
+   /**
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   virtual bool isOpen()const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width, which can be different than the
+    * internal image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileHeight which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;
+   
+private:
+   
+   /**
+    *  Adjust point to even 128 boundary.  Assumes 0,0 origin.
+    */
+   void adjustToStartOfTile(ossimIpt& pt) const;
+   
+   /**
+    *  Returns true on success, false on error.
+    */
+   bool fillBuffer(const ossimIrect& tile_rect,
+                   const ossimIrect& clip_rect);
+   
+   ossimRefPtr<ossimImageData>  theTile;
+   ossim_uint8*                 theTileBuffer;
+   ifstream                     theFileStr;
+   ossimAdrgHeader*             theAdrgHeader;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdffield.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdffield.cpp
new file mode 100644
index 0000000000..40056f56dd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdffield.cpp
@@ -0,0 +1,336 @@
+/******************************************************************************
+ * Copied from "gdal" project. See licence below.
+ *
+ * Project:  ISO 8211 Access
+ * Purpose:  Implements the DDFField class.
+ * Author:   Frank Warmerdam, warmerda@home.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * $Id: ossimDdffield.cpp,v 1.2 2005/02/13 16:08:04 dburken Exp $
+ */
+
+#include <imaging/formats/adrg/ossimIso8211.h>
+#include <base/common/ossimCplUtil.h>
+#include <base/common/ossimCommon.h>
+
+// #include "cpl_conv.h"
+
+// CPL_CVSID("$Id: ossimDdffield.cpp,v 1.2 2005/02/13 16:08:04 dburken Exp $");
+
+// Note, we implement no constructor for this class to make instantiation
+// cheaper.  It is required that the Initialize() be called before anything
+// else.
+
+/************************************************************************/
+/*                             Initialize()                             */
+/************************************************************************/
+
+void ossimDDFField::Initialize( ossimDDFFieldDefn *poDefnIn, const char * pachDataIn,
+                           int nDataSizeIn )
+
+{
+    pachData = pachDataIn;
+    nDataSize = nDataSizeIn;
+    poDefn = poDefnIn;
+}
+
+/************************************************************************/
+/*                                Dump()                                */
+/************************************************************************/
+
+/**
+ * Write out field contents to debugging file.
+ *
+ * A variety of information about this field, and all it's
+ * subfields is written to the given debugging file handle.  Note that
+ * field definition information (ala DDFFieldDefn) isn't written.
+ *
+ * @param fp The standard io file handle to write to.  ie. stderr
+ */
+
+void ossimDDFField::Dump( FILE * fp )
+
+{
+    int         nMaxRepeat = 8;
+
+    if( getenv("DDF_MAXDUMP") != NULL )
+        nMaxRepeat = atoi(getenv("DDF_MAXDUMP"));
+
+    fprintf( fp, "  DDFField:\n" );
+    fprintf( fp, "      Tag = `%s'\n", poDefn->GetName() );
+    fprintf( fp, "      DataSize = %d\n", nDataSize );
+
+    fprintf( fp, "      Data = `" );
+    for( int i = 0; i < MIN(nDataSize,40); i++ )
+    {
+        if( pachData[i] < 32 || pachData[i] > 126 )
+            fprintf( fp, "\\%02X", ((unsigned char *) pachData)[i] );
+        else
+            fprintf( fp, "%c", pachData[i] );
+    }
+
+    if( nDataSize > 40 )
+        fprintf( fp, "..." );
+    fprintf( fp, "'\n" );
+
+/* -------------------------------------------------------------------- */
+/*      dump the data of the subfields.                                 */
+/* -------------------------------------------------------------------- */
+    int         iOffset = 0, nLoopCount;
+
+    for( nLoopCount = 0; nLoopCount < GetRepeatCount(); nLoopCount++ )
+    {
+        if( nLoopCount > nMaxRepeat )
+        {
+            fprintf( fp, "      ...\n" );
+            break;
+        }
+        
+        for( int i = 0; i < poDefn->GetSubfieldCount(); i++ )
+        {
+            int         nBytesConsumed;
+
+            poDefn->GetSubfield(i)->DumpData( pachData + iOffset,
+                                              nDataSize - iOffset, fp );
+        
+            poDefn->GetSubfield(i)->GetDataLength( pachData + iOffset,
+                                                   nDataSize - iOffset,
+                                                   &nBytesConsumed );
+
+            iOffset += nBytesConsumed;
+        }
+    }
+}
+
+/************************************************************************/
+/*                          GetSubfieldData()                           */
+/************************************************************************/
+
+/**
+ * Fetch raw data pointer for a particular subfield of this field.
+ *
+ * The passed DDFSubfieldDefn (poSFDefn) should be acquired from the
+ * DDFFieldDefn corresponding with this field.  This is normally done
+ * once before reading any records.  This method involves a series of
+ * calls to DDFSubfield::GetDataLength() in order to track through the
+ * DDFField data to that belonging to the requested subfield.  This can
+ * be relatively expensive.<p>
+ *
+ * @param poSFDefn The definition of the subfield for which the raw
+ * data pointer is desired.
+ * @param pnMaxBytes The maximum number of bytes that can be accessed from
+ * the returned data pointer is placed in this int, unless it is NULL.
+ * @param iSubfieldIndex The instance of this subfield to fetch.  Use zero
+ * (the default) for the first instance.
+ *
+ * @return A pointer into the DDFField's data that belongs to the subfield.
+ * This returned pointer is invalidated by the next record read
+ * (DDFRecord::ReadRecord()) and the returned pointer should not be freed
+ * by the application.
+ */
+
+const char *ossimDDFField::GetSubfieldData( ossimDDFSubfieldDefn *poSFDefn,
+                                       int *pnMaxBytes, int iSubfieldIndex )
+
+{
+    int         iOffset = 0;
+    
+    if( poSFDefn == NULL )
+        return NULL;
+
+    if( iSubfieldIndex > 0 && poDefn->GetFixedWidth() > 0 )
+    {
+        iOffset = poDefn->GetFixedWidth() * iSubfieldIndex;
+        iSubfieldIndex = 0;
+    }
+
+    while( iSubfieldIndex >= 0 )
+    {
+        for( int iSF = 0; iSF < poDefn->GetSubfieldCount(); iSF++ )
+        {
+            int nBytesConsumed;
+            ossimDDFSubfieldDefn * poThisSFDefn = poDefn->GetSubfield( iSF );
+            
+            if( poThisSFDefn == poSFDefn && iSubfieldIndex == 0 )
+            {
+                if( pnMaxBytes != NULL )
+                    *pnMaxBytes = nDataSize - iOffset;
+                
+                return pachData + iOffset;
+            }
+            
+            poThisSFDefn->GetDataLength( pachData+iOffset, nDataSize - iOffset,
+                                         &nBytesConsumed);
+            iOffset += nBytesConsumed;
+        }
+
+        iSubfieldIndex--;
+    }
+
+    // We didn't find our target subfield or instance!
+    return NULL;
+}
+
+/************************************************************************/
+/*                           GetRepeatCount()                           */
+/************************************************************************/
+
+/**
+ * How many times do the subfields of this record repeat?  This    
+ * will always be one for non-repeating fields.
+ *
+ * @return The number of times that the subfields of this record occur
+ * in this record.  This will be one for non-repeating fields.
+ *
+ * @see <a href="example.html">8211view example program</a>
+ * for demonstation of handling repeated fields properly.
+ */
+
+int ossimDDFField::GetRepeatCount()
+
+{
+    if( !poDefn->IsRepeating() )
+        return 1;
+
+/* -------------------------------------------------------------------- */
+/*      The occurance count depends on how many copies of this          */
+/*      field's list of subfields can fit into the data space.          */
+/* -------------------------------------------------------------------- */
+    if( poDefn->GetFixedWidth() )
+    {
+        return nDataSize / poDefn->GetFixedWidth();
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Note that it may be legal to have repeating variable width      */
+/*      subfields, but I don't have any samples, so I ignore it for     */
+/*      now.                                                            */
+/*                                                                      */
+/*      The file data/cape_royal_AZ_DEM/1183XREF.DDF has a repeating    */
+/*      variable length field, but the count is one, so it isn't        */
+/*      much value for testing.                                         */
+/* -------------------------------------------------------------------- */
+    int         iOffset = 0, iRepeatCount = 1;
+    
+    while( true )
+    {
+        for( int iSF = 0; iSF < poDefn->GetSubfieldCount(); iSF++ )
+        {
+            int nBytesConsumed;
+            ossimDDFSubfieldDefn * poThisSFDefn = poDefn->GetSubfield( iSF );
+
+            if( poThisSFDefn->GetWidth() > nDataSize - iOffset )
+                nBytesConsumed = poThisSFDefn->GetWidth();
+            else
+                poThisSFDefn->GetDataLength( pachData+iOffset, 
+                                             nDataSize - iOffset,
+                                             &nBytesConsumed);
+
+            iOffset += nBytesConsumed;
+            if( iOffset > nDataSize )
+                return iRepeatCount - 1;
+        }
+
+        if( iOffset > nDataSize - 2 )
+            return iRepeatCount;
+
+        iRepeatCount++;
+    }
+}
+
+/************************************************************************/
+/*                          GetInstanceData()                           */
+/************************************************************************/
+
+/**
+ * Get field instance data and size.
+ *
+ * The returned data pointer and size values are suitable for use with
+ * DDFRecord::SetFieldRaw(). 
+ *
+ * @param nInstance a value from 0 to GetRepeatCount()-1.  
+ * @param pnInstanceSize a location to put the size (in bytes) of the
+ * field instance data returned.  This size will include the unit terminator
+ * (if any), but not the field terminator.  This size pointer may be NULL
+ * if not needed.
+ *
+ * @return the data pointer, or NULL on error. 
+ */
+
+const char *ossimDDFField::GetInstanceData( int nInstance, 
+                                       int *pnInstanceSize )
+
+{
+    int nRepeatCount = GetRepeatCount();
+    const char *pachWrkData;
+
+    if( nInstance < 0 || nInstance >= nRepeatCount )
+        return NULL;
+
+/* -------------------------------------------------------------------- */
+/*      Special case for fields without subfields (like "0001").  We    */
+/*      don't currently handle repeating simple fields.                 */
+/* -------------------------------------------------------------------- */
+    if( poDefn->GetSubfieldCount() == 0 )
+    {
+        pachWrkData = GetData();
+        if( pnInstanceSize != 0 )
+            *pnInstanceSize = GetDataSize();
+        return pachWrkData;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Get a pointer to the start of the existing data for this        */
+/*      iteration of the field.                                         */
+/* -------------------------------------------------------------------- */
+    int         nBytesRemaining1, nBytesRemaining2;
+    ossimDDFSubfieldDefn *poFirstSubfield;
+
+    poFirstSubfield = poDefn->GetSubfield(0);
+
+    pachWrkData = GetSubfieldData(poFirstSubfield, &nBytesRemaining1,
+                               nInstance);
+
+/* -------------------------------------------------------------------- */
+/*      Figure out the size of the entire field instance, including     */
+/*      unit terminators, but not any trailing field terminator.        */
+/* -------------------------------------------------------------------- */
+    if( pnInstanceSize != NULL )
+    {
+        ossimDDFSubfieldDefn *poLastSubfield;
+        int              nLastSubfieldWidth;
+        const char          *pachLastData;
+        
+        poLastSubfield = poDefn->GetSubfield(poDefn->GetSubfieldCount()-1);
+        
+        pachLastData = GetSubfieldData( poLastSubfield, &nBytesRemaining2, 
+                                        nInstance );
+        poLastSubfield->GetDataLength( pachLastData, nBytesRemaining2, 
+                                       &nLastSubfieldWidth );
+        
+        *pnInstanceSize = 
+            nBytesRemaining1 - (nBytesRemaining2 - nLastSubfieldWidth);
+    }
+
+    return pachWrkData;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdffielddefn.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdffielddefn.cpp
new file mode 100644
index 0000000000..80ab350105
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdffielddefn.cpp
@@ -0,0 +1,865 @@
+/******************************************************************************
+ * Copied from "gdal" project. See licence below.
+ *
+ * Project:  ISO 8211 Access
+ * Purpose:  Implements the DDFFieldDefn class.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * $Id: ossimDdffielddefn.cpp,v 1.5 2005/10/17 18:42:27 gpotts Exp $
+ */
+
+#include <imaging/formats/adrg/ossimIso8211.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimCplUtil.h>
+#include <base/common/ossimTrace.h>
+#include <ctype.h>
+
+// Static trace for debugging
+static ossimTrace traceDebug("ossimDDFFieldDefn:debug");
+
+
+/************************************************************************/
+/*                            DDFFieldDefn()                            */
+/************************************************************************/
+
+ossimDDFFieldDefn::ossimDDFFieldDefn()
+
+{
+    poModule = NULL;
+    pszTag = NULL;
+    _fieldName = NULL;
+    _arrayDescr = NULL;
+    _formatControls = NULL;
+    nSubfieldCount = 0;
+    papoSubfields = NULL;
+    bRepeatingSubfields = false;
+    nFixedWidth = 0;
+}
+
+/************************************************************************/
+/*                           ~DDFFieldDefn()                            */
+/************************************************************************/
+
+ossimDDFFieldDefn::~ossimDDFFieldDefn()
+
+{
+    int   i;
+
+    free( pszTag );
+    free( _fieldName );
+    free( _arrayDescr );
+    free( _formatControls );
+
+    for( i = 0; i < nSubfieldCount; i++ )
+        delete papoSubfields[i];
+    free( papoSubfields );
+}
+
+/************************************************************************/
+/*                            AddSubfield()                             */
+/************************************************************************/
+
+void ossimDDFFieldDefn::AddSubfield( const char *pszName, 
+                                const char *pszFormat )
+
+{
+    ossimDDFSubfieldDefn *poSFDefn = new ossimDDFSubfieldDefn;
+
+    poSFDefn->SetName( pszName );
+    poSFDefn->SetFormat( pszFormat );
+    AddSubfield( poSFDefn );
+}
+
+/************************************************************************/
+/*                            AddSubfield()                             */
+/************************************************************************/
+
+void ossimDDFFieldDefn::AddSubfield( ossimDDFSubfieldDefn *poNewSFDefn,
+                                int bDontAddToFormat )
+
+{
+    nSubfieldCount++;
+    papoSubfields = (ossimDDFSubfieldDefn ** )
+        realloc( papoSubfields, sizeof(void*) * nSubfieldCount );
+    papoSubfields[nSubfieldCount-1] = poNewSFDefn;
+    
+    if( bDontAddToFormat )
+        return;
+
+/* -------------------------------------------------------------------- */
+/*      Add this format to the format list.  We don't bother            */
+/*      aggregating formats here.                                       */
+/* -------------------------------------------------------------------- */
+    if( _formatControls == NULL || strlen(_formatControls) == 0 )
+    {
+        free( _formatControls );
+        _formatControls = strdup( "()" );
+    }
+    
+    int nOldLen = strlen(_formatControls);
+    
+    char *pszNewFormatControls = (char *) 
+        malloc(nOldLen+3+strlen(poNewSFDefn->GetFormat()));
+    
+    strcpy( pszNewFormatControls, _formatControls );
+    pszNewFormatControls[nOldLen-1] = '\0';
+    if( pszNewFormatControls[nOldLen-2] != '(' )
+        strcat( pszNewFormatControls, "," );
+    
+    strcat( pszNewFormatControls, poNewSFDefn->GetFormat() );
+    strcat( pszNewFormatControls, ")" );
+    
+    free( _formatControls );
+    _formatControls = pszNewFormatControls;
+
+/* -------------------------------------------------------------------- */
+/*      Add the subfield name to the list.                              */
+/* -------------------------------------------------------------------- */
+    if( _arrayDescr == NULL )
+        _arrayDescr = strdup("");
+
+    _arrayDescr = (char *) 
+        realloc(_arrayDescr, 
+                   strlen(_arrayDescr)+strlen(poNewSFDefn->GetName())+2);
+    if( strlen(_arrayDescr) > 0 )
+        strcat( _arrayDescr, "!" );
+    strcat( _arrayDescr, poNewSFDefn->GetName() );
+}
+
+/************************************************************************/
+/*                               Create()                               */
+/*                                                                      */
+/*      Initialize a new field defn from application input, instead     */
+/*      of from an existing file.                                       */
+/************************************************************************/
+
+int ossimDDFFieldDefn::Create( const char *pszTag, const char *pszFieldName, 
+                          const char *pszDescription, 
+                          DDF_data_struct_code eDataStructCode,
+                          DDF_data_type_code   eDataTypeCode,
+                          const char *pszFormat )
+
+{
+   // assert( this->pszTag == NULL );
+   poModule = NULL;
+   this->pszTag = strdup( pszTag );
+   _fieldName = strdup( pszFieldName );
+   _arrayDescr = strdup( pszDescription );
+   _formatControls = strdup( "" );
+   
+   _data_struct_code = eDataStructCode;
+   _data_type_code = eDataTypeCode;
+   
+   if( pszFormat != NULL )
+      _formatControls = strdup( pszFormat );
+   
+   if( pszDescription != NULL && *pszDescription == '*' )
+      bRepeatingSubfields = true;
+   
+   return true;
+}
+
+/************************************************************************/
+/*                          GenerateDDREntry()                          */
+/************************************************************************/
+
+int ossimDDFFieldDefn::GenerateDDREntry( char **ppachData, 
+                                    int *pnLength )
+
+{
+    *pnLength = 9 + strlen(_fieldName) + 1 
+        + strlen(_arrayDescr) + 1
+        + strlen(_formatControls) + 1;
+
+    if( strlen(_formatControls) == 0 )
+        *pnLength -= 1;
+
+    if( ppachData == NULL )
+        return true;
+
+    *ppachData = (char *) malloc( *pnLength+1 );
+    
+    if( _data_struct_code == dsc_elementary )
+        (*ppachData)[0] = '0';
+    else if( _data_struct_code == dsc_vector )
+        (*ppachData)[0] = '1';
+    else if( _data_struct_code == dsc_array )
+        (*ppachData)[0] = '2';
+    else if( _data_struct_code == dsc_concatenated )
+        (*ppachData)[0] = '3';
+    
+    if( _data_type_code == dtc_char_string )
+        (*ppachData)[1] = '0';
+    else if( _data_type_code == dtc_implicit_point )
+        (*ppachData)[1] = '1';
+    else if( _data_type_code == dtc_explicit_point )
+        (*ppachData)[1] = '2';
+    else if( _data_type_code == dtc_explicit_point_scaled )
+        (*ppachData)[1] = '3';
+    else if( _data_type_code == dtc_char_bit_string )
+        (*ppachData)[1] = '4';
+    else if( _data_type_code == dtc_bit_string )
+        (*ppachData)[1] = '5';
+    else if( _data_type_code == dtc_mixed_data_type )
+        (*ppachData)[1] = '6';
+
+    (*ppachData)[2] = '0';
+    (*ppachData)[3] = '0';
+    (*ppachData)[4] = ';';
+    (*ppachData)[5] = '&';
+    (*ppachData)[6] = ' ';
+    (*ppachData)[7] = ' ';
+    (*ppachData)[8] = ' ';
+    sprintf( *ppachData + 9, "%s%c%s", 
+             _fieldName, OSSIM_DDF_UNIT_TERMINATOR, _arrayDescr );
+
+    if( strlen(_formatControls) > 0 )
+        sprintf( *ppachData + strlen(*ppachData), "%c%s",
+                 OSSIM_DDF_UNIT_TERMINATOR, _formatControls );
+    sprintf( *ppachData + strlen(*ppachData), "%c", OSSIM_DDF_FIELD_TERMINATOR );
+
+    return true;
+}
+
+/************************************************************************/
+/*                             Initialize()                             */
+/*                                                                      */
+/*      Initialize the field definition from the information in the     */
+/*      DDR record.  This is called by DDFModule::Open().               */
+/************************************************************************/
+
+int ossimDDFFieldDefn::Initialize( ossimDDFModule * poModuleIn,
+                              const char * pszTagIn, 
+                              int nFieldEntrySize,
+                              const char * pachFieldArea )
+
+{
+    int         iFDOffset = poModuleIn->GetFieldControlLength();
+    int         nCharsConsumed;
+
+    poModule = poModuleIn;
+    
+    pszTag = strdup( pszTagIn );
+
+/* -------------------------------------------------------------------- */
+/*      Set the data struct and type codes.                             */
+/* -------------------------------------------------------------------- */
+    switch( pachFieldArea[0] )
+    {
+      case '0':
+        _data_struct_code = dsc_elementary;
+        break;
+
+      case '1':
+        _data_struct_code = dsc_vector;
+        break;
+
+      case '2':
+        _data_struct_code = dsc_array;
+        break;
+
+      case '3':
+        _data_struct_code = dsc_concatenated;
+        break;
+
+      default:
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Unrecognised data_struct_code value %c.\n"
+               << "Field %s initialization incorrect.\n"
+               << pachFieldArea[0]
+               << pszTag
+               << std::endl;
+         }
+        _data_struct_code = dsc_elementary;
+    }
+
+    switch( pachFieldArea[1] )
+    {
+      case '0':
+        _data_type_code = dtc_char_string;
+        break;
+        
+      case '1':
+        _data_type_code = dtc_implicit_point;
+        break;
+        
+      case '2':
+        _data_type_code = dtc_explicit_point;
+        break;
+        
+      case '3':
+        _data_type_code = dtc_explicit_point_scaled;
+        break;
+        
+      case '4':
+        _data_type_code = dtc_char_bit_string;
+        break;
+        
+      case '5':
+        _data_type_code = dtc_bit_string;
+        break;
+        
+      case '6':
+        _data_type_code = dtc_mixed_data_type;
+        break;
+
+      default:
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Unrecognised data_type_code value %c.\n"
+               << "Field %s initialization incorrect.\n"
+               << pachFieldArea[1] << pszTag << std::endl;
+         }
+        _data_type_code = dtc_char_string;
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      Capture the field name, description (sub field names), and      */
+/*      format statements.                                              */
+/* -------------------------------------------------------------------- */
+
+    _fieldName =
+        ossimDDFFetchVariable( pachFieldArea + iFDOffset,
+                          nFieldEntrySize - iFDOffset,
+                          OSSIM_DDF_UNIT_TERMINATOR,
+                          OSSIM_DDF_FIELD_TERMINATOR,
+                          &nCharsConsumed );
+    iFDOffset += nCharsConsumed;
+    
+    _arrayDescr =
+        ossimDDFFetchVariable( pachFieldArea + iFDOffset,
+                               nFieldEntrySize - iFDOffset,
+                               OSSIM_DDF_UNIT_TERMINATOR,
+                               OSSIM_DDF_FIELD_TERMINATOR, 
+                               &nCharsConsumed );
+    iFDOffset += nCharsConsumed;
+    
+    _formatControls =
+        ossimDDFFetchVariable( pachFieldArea + iFDOffset,
+                               nFieldEntrySize - iFDOffset,
+                               OSSIM_DDF_UNIT_TERMINATOR,
+                               OSSIM_DDF_FIELD_TERMINATOR, 
+                               &nCharsConsumed );
+    
+/* -------------------------------------------------------------------- */
+/*      Parse the subfield info.                                        */
+/* -------------------------------------------------------------------- */
+    if( _data_struct_code != dsc_elementary )
+    {
+        if( !BuildSubfields() )
+            return false;
+
+        if( !ApplyFormats() )
+            return false;
+    }
+    
+    return true;
+}
+
+/************************************************************************/
+/*                                Dump()                                */
+/************************************************************************/
+
+/**
+ * Write out field definition info to debugging file.
+ *
+ * A variety of information about this field definition, and all it's
+ * subfields is written to the give debugging file handle.
+ *
+ * @param fp The standard io file handle to write to.  ie. stderr
+ */
+
+void ossimDDFFieldDefn::Dump( FILE * fp )
+
+{
+    const char  *pszValue = "";
+    
+    fprintf( fp, "  DDFFieldDefn:\n" );
+    fprintf( fp, "      Tag = `%s'\n", pszTag );
+    fprintf( fp, "      _fieldName = `%s'\n", _fieldName );
+    fprintf( fp, "      _arrayDescr = `%s'\n", _arrayDescr );
+    fprintf( fp, "      _formatControls = `%s'\n", _formatControls );
+
+    switch( _data_struct_code )
+    {
+      case dsc_elementary:
+        pszValue = "elementary";
+        break;
+        
+      case dsc_vector:
+        pszValue = "vector";
+        break;
+        
+      case dsc_array:
+        pszValue = "array";
+        break;
+        
+      case dsc_concatenated:
+        pszValue = "concatenated";
+        break;
+        
+      default:
+         // assert( false );
+        pszValue = "(unknown)";
+    }
+
+    fprintf( fp, "      _data_struct_code = %s\n", pszValue );
+
+    switch( _data_type_code )
+    {
+      case dtc_char_string:
+        pszValue = "char_string";
+        break;
+        
+      case dtc_implicit_point:
+        pszValue = "implicit_point";
+        break;
+        
+      case dtc_explicit_point:
+        pszValue = "explicit_point";
+        break;
+        
+      case dtc_explicit_point_scaled:
+        pszValue = "explicit_point_scaled";
+        break;
+        
+      case dtc_char_bit_string:
+        pszValue = "char_bit_string";
+        break;
+        
+      case dtc_bit_string:
+        pszValue = "bit_string";
+        break;
+        
+      case dtc_mixed_data_type:
+        pszValue = "mixed_data_type";
+        break;
+
+      default:
+         // assert( false );
+        pszValue = "(unknown)";
+        break;
+    }
+    
+    fprintf( fp, "      _data_type_code = %s\n", pszValue );
+
+    for( int i = 0; i < nSubfieldCount; i++ )
+        papoSubfields[i]->Dump( fp );
+}
+
+/************************************************************************/
+/*                           BuildSubfields()                           */
+/*                                                                      */
+/*      Based on the _arrayDescr build a set of subfields.              */
+/************************************************************************/
+
+int ossimDDFFieldDefn::BuildSubfields()
+
+{
+    char        **papszSubfieldNames;
+    const char  *pszSublist = _arrayDescr;
+
+    if( pszSublist[0] == '*' )
+    {
+        bRepeatingSubfields = true;
+        pszSublist++;
+    }
+
+    papszSubfieldNames = ossimCSLTokenizeStringComplex( pszSublist, "!",
+                                                   false, false );
+
+    int nSFCount = ossimCSLCount( papszSubfieldNames );
+    for( int iSF = 0; iSF < nSFCount; iSF++ )
+    {
+        ossimDDFSubfieldDefn *poSFDefn = new ossimDDFSubfieldDefn;
+        
+        poSFDefn->SetName( papszSubfieldNames[iSF] );
+        AddSubfield( poSFDefn, true );
+    }
+
+    ossimCSLDestroy( papszSubfieldNames );
+
+    return true;
+}
+
+/************************************************************************/
+/*                          ExtractSubstring()                          */
+/*                                                                      */
+/*      Extract a substring terminated by a comma (or end of            */
+/*      string).  Commas in brackets are ignored as terminated with     */
+/*      bracket nesting understood gracefully.  If the returned         */
+/*      string would being and end with a bracket then strip off the    */
+/*      brackets.                                                       */
+/*                                                                      */
+/*      Given a string like "(A,3(B,C),D),X,Y)" return "A,3(B,C),D".    */
+/*      Give a string like "3A,2C" return "3A".                         */
+/************************************************************************/
+
+char *ossimDDFFieldDefn::ExtractSubstring( const char * pszSrc )
+
+{
+    int         nBracket=0, i;
+    char        *pszReturn;
+
+    for( i = 0;
+         pszSrc[i] != '\0' && (nBracket > 0 || pszSrc[i] != ',');
+         i++ )
+    {
+        if( pszSrc[i] == '(' )
+            nBracket++;
+        else if( pszSrc[i] == ')' )
+            nBracket--;
+    }
+
+    if( pszSrc[0] == '(' )
+    {
+        pszReturn = strdup( pszSrc + 1 );
+        pszReturn[i-2] = '\0';
+    }
+    else
+    {
+        pszReturn = strdup( pszSrc  );
+        pszReturn[i] = '\0';
+    }
+
+    return pszReturn;
+}
+
+/************************************************************************/
+/*                            ExpandFormat()                            */
+/************************************************************************/
+
+char *ossimDDFFieldDefn::ExpandFormat( const char * pszSrc )
+
+{
+    int         nDestMax = 32;
+    char       *pszDest = (char *) malloc(nDestMax+1);
+    int         iSrc, iDst;
+    int         nRepeat = 0;
+
+    iSrc = 0;
+    iDst = 0;
+    pszDest[0] = '\0';
+
+    while( pszSrc[iSrc] != '\0' )
+    {
+        /* This is presumably an extra level of brackets around some
+           binary stuff related to rescaning which we don't care to do
+           (see 6.4.3.3 of the standard.  We just strip off the extra
+           layer of brackets */
+        if( (iSrc == 0 || pszSrc[iSrc-1] == ',') && pszSrc[iSrc] == '(' )
+        {
+            char       *pszContents = ExtractSubstring( pszSrc+iSrc );
+            char       *pszExpandedContents = ExpandFormat( pszContents );
+
+            if( (int) (strlen(pszExpandedContents) + strlen(pszDest) + 1)
+                > nDestMax )
+            {
+                nDestMax = 2 * (strlen(pszExpandedContents) + strlen(pszDest));
+                pszDest = (char *) realloc(pszDest,nDestMax+1);
+            }
+
+            strcat( pszDest, pszExpandedContents );
+            iDst = strlen(pszDest);
+            
+            iSrc = iSrc + strlen(pszContents) + 2;
+
+            free( pszContents );
+            free( pszExpandedContents );
+        }
+
+        /* this is a repeated subclause */
+        else if( (iSrc == 0 || pszSrc[iSrc-1] == ',')
+                 && isdigit(pszSrc[iSrc]) )
+        {
+            const char *pszNext;
+            nRepeat = atoi(pszSrc+iSrc);
+            
+            // skip over repeat count.
+            for( pszNext = pszSrc+iSrc; isdigit(*pszNext); pszNext++ )
+                iSrc++;
+
+            char       *pszContents = ExtractSubstring( pszNext );
+            char       *pszExpandedContents = ExpandFormat( pszContents );
+                
+            for( int i = 0; i < nRepeat; i++ )
+            {
+                if( (int) (strlen(pszExpandedContents) + strlen(pszDest) + 1)
+                    > nDestMax )
+                {
+                    nDestMax = 
+                        2 * (strlen(pszExpandedContents) + strlen(pszDest));
+                    pszDest = (char *) realloc(pszDest,nDestMax+1);
+                }
+
+                strcat( pszDest, pszExpandedContents );
+                if( i < nRepeat-1 )
+                    strcat( pszDest, "," );
+            }
+
+            iDst = strlen(pszDest);
+            
+            if( pszNext[0] == '(' )
+                iSrc = iSrc + strlen(pszContents) + 2;
+            else
+                iSrc = iSrc + strlen(pszContents);
+
+            free( pszContents );
+            free( pszExpandedContents );
+        }
+        else
+        {
+            if( iDst+1 >= nDestMax )
+            {
+                nDestMax = 2 * iDst;
+                pszDest = (char *) realloc(pszDest,nDestMax);
+            }
+
+            pszDest[iDst++] = pszSrc[iSrc++];
+            pszDest[iDst] = '\0';
+        }
+    }
+
+    return pszDest;
+}
+                                 
+/************************************************************************/
+/*                            ApplyFormats()                            */
+/*                                                                      */
+/*      This method parses the format string partially, and then        */
+/*      applies a subfield format string to each subfield object.       */
+/*      It in turn does final parsing of the subfield formats.          */
+/************************************************************************/
+
+int ossimDDFFieldDefn::ApplyFormats()
+
+{
+    char        *pszFormatList;
+    char        **papszFormatItems;
+    
+/* -------------------------------------------------------------------- */
+/*      Verify that the format string is contained within brackets.     */
+/* -------------------------------------------------------------------- */
+    if( strlen(_formatControls) < 2
+        || _formatControls[0] != '('
+        || _formatControls[strlen(_formatControls)-1] != ')' )
+    {
+       ossimNotify(ossimNotifyLevel_WARN)
+          << "Format controls for `%s' field missing brackets:%s\n"
+          << pszTag << _formatControls << std::endl;
+        
+        return false;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Duplicate the string, and strip off the brackets.               */
+/* -------------------------------------------------------------------- */
+
+    pszFormatList = ExpandFormat( _formatControls );
+
+/* -------------------------------------------------------------------- */
+/*      Tokenize based on commas.                                       */
+/* -------------------------------------------------------------------- */
+    papszFormatItems =
+        ossimCSLTokenizeStringComplex(pszFormatList, ",", false, false );
+
+    free( pszFormatList );
+
+/* -------------------------------------------------------------------- */
+/*      Apply the format items to subfields.                            */
+/* -------------------------------------------------------------------- */
+    int iFormatItem;
+    
+    for( iFormatItem = 0;
+         papszFormatItems[iFormatItem] != NULL;
+         iFormatItem++ )
+    {
+        const char      *pszPastPrefix;
+
+        pszPastPrefix = papszFormatItems[iFormatItem];
+        while( *pszPastPrefix >= '0' && *pszPastPrefix <= '9' )
+            pszPastPrefix++;
+
+        ///////////////////////////////////////////////////////////////
+        // Did we get too many formats for the subfields created
+        // by names?  This may be legal by the 8211 specification, but
+        // isn't encountered in any formats we care about so we just
+        // blow.
+        
+        if( iFormatItem >= nSubfieldCount )
+        {
+           ossimNotify(ossimNotifyLevel_WARN)
+              << "Got more formats than subfields for field `%s'.\n"
+              << pszTag << std::endl;
+            break;
+        }
+        
+        if( !papoSubfields[iFormatItem]->SetFormat(pszPastPrefix) )
+            return false;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Verify that we got enough formats, cleanup and return.          */
+/* -------------------------------------------------------------------- */
+    ossimCSLDestroy( papszFormatItems );
+
+    if( iFormatItem < nSubfieldCount )
+    {
+       ossimNotify(ossimNotifyLevel_DEBUG)
+          << "Got less formats than subfields for field `%s',\n"
+          << pszTag << std::endl;
+        return false;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If all the fields are fixed width, then we are fixed width      */
+/*      too.  This is important for repeating fields.                   */
+/* -------------------------------------------------------------------- */
+    nFixedWidth = 0;
+    for( int i = 0; i < nSubfieldCount; i++ )
+    {
+        if( papoSubfields[i]->GetWidth() == 0 )
+        {
+            nFixedWidth = 0;
+            break;
+        }
+        else
+            nFixedWidth += papoSubfields[i]->GetWidth();
+    }
+
+    return true;
+}
+
+/************************************************************************/
+/*                          FindSubfieldDefn()                          */
+/************************************************************************/
+
+/**
+ * Find a subfield definition by it's mnemonic tag.  
+ *
+ * @param pszMnemonic The name of the field.
+ *
+ * @return The subfield pointer, or NULL if there isn't any such subfield.
+ */
+ 
+
+ossimDDFSubfieldDefn *ossimDDFFieldDefn::FindSubfieldDefn( const char * pszMnemonic )
+
+{
+    for( int i = 0; i < nSubfieldCount; i++ )
+    {
+       ossimString s = papoSubfields[i]->GetName();
+       if( s == pszMnemonic )
+            return papoSubfields[i];
+    }
+
+    return NULL;
+}
+
+/************************************************************************/
+/*                            GetSubfield()                             */
+/*                                                                      */
+/*      Fetch a subfield by it's index.                                 */
+/************************************************************************/
+
+/**
+ * Fetch a subfield by index.
+ *
+ * @param i The index subfield index. (Between 0 and GetSubfieldCount()-1)
+ *
+ * @return The subfield pointer, or NULL if the index is out of range.
+ */
+
+ossimDDFSubfieldDefn *ossimDDFFieldDefn::GetSubfield( int i )
+
+{
+    if( i < 0 || i >= nSubfieldCount )
+    {
+       // assert( false );
+       return NULL;
+    }
+             
+    return papoSubfields[i];
+}
+
+/************************************************************************/
+/*                          GetDefaultValue()                           */
+/************************************************************************/
+
+/**
+ * Return default data for field instance.
+ */
+
+char *ossimDDFFieldDefn::GetDefaultValue( int *pnSize )
+
+{                                                                       
+/* -------------------------------------------------------------------- */
+/*      Loop once collecting the sum of the subfield lengths.           */
+/* -------------------------------------------------------------------- */
+    int iSubfield;
+    int nTotalSize = 0;
+
+    for( iSubfield = 0; iSubfield < nSubfieldCount; iSubfield++ )
+    {
+        int nSubfieldSize;
+
+        if( !papoSubfields[iSubfield]->GetDefaultValue( NULL, 0, 
+                                                        &nSubfieldSize ) )
+            return NULL;
+        nTotalSize += nSubfieldSize;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Allocate buffer.                                                */
+/* -------------------------------------------------------------------- */
+    char *pachData = (char *) malloc( nTotalSize );
+
+    if( pnSize != NULL )
+        *pnSize = nTotalSize;
+
+/* -------------------------------------------------------------------- */
+/*      Loop again, collecting actual default values.                   */
+/* -------------------------------------------------------------------- */
+    int nOffset = 0;
+    for( iSubfield = 0; iSubfield < nSubfieldCount; iSubfield++ )
+    {
+        int nSubfieldSize;
+
+        if( !papoSubfields[iSubfield]->GetDefaultValue( 
+                pachData + nOffset, nTotalSize - nOffset, &nSubfieldSize ) )
+        {
+           // assert( false );
+           return NULL;
+        }
+
+        nOffset += nSubfieldSize;
+    }
+
+    // assert( nOffset == nTotalSize );
+
+    return pachData;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfmodule.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfmodule.cpp
new file mode 100644
index 0000000000..56d5fdd171
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfmodule.cpp
@@ -0,0 +1,709 @@
+/******************************************************************************
+ * Copied from "gdal" project. See licence below.
+ *
+ * Project:  ISO 8211 Access
+ * Purpose:  Implements the DDFModule class.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * $Id: ossimDdfmodule.cpp,v 1.3 2005/10/17 18:42:27 gpotts Exp $
+ */
+
+#include <imaging/formats/adrg/ossimIso8211.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimCplUtil.h>
+
+
+/************************************************************************/
+/*                             DDFModule()                              */
+/************************************************************************/
+
+/**
+ * The constructor.
+ */
+
+ossimDDFModule::ossimDDFModule()
+
+{
+    nFieldDefnCount = 0;
+    papoFieldDefns = NULL;
+    poRecord = NULL;
+
+    papoClones = NULL;
+    nCloneCount = nMaxCloneCount = 0;
+
+    fpDDF = NULL;
+    bReadOnly = true;
+
+    _interchangeLevel = '\0';
+    _inlineCodeExtensionIndicator = '\0';
+    _versionNumber = '\0';
+    _appIndicator = '\0';
+    _fieldControlLength = '\0';
+    strcpy( _extendedCharSet, " ! " );
+
+    _recLength = 0;
+    _leaderIden = 'L';
+    _fieldAreaStart = 0;
+    _sizeFieldLength = 0;
+    _sizeFieldPos = 0;
+    _sizeFieldTag = 0;
+}
+
+/************************************************************************/
+/*                             ~DDFModule()                             */
+/************************************************************************/
+
+/**
+ * The destructor.
+ */
+
+ossimDDFModule::~ossimDDFModule()
+
+{
+    Close();
+}
+
+/************************************************************************/
+/*                               Close()                                */
+/*                                                                      */
+/*      Note that closing a file also destroys essentially all other    */
+/*      module datastructures.                                          */
+/************************************************************************/
+
+/**
+ * Close an ISO 8211 file.
+ */
+
+void ossimDDFModule::Close()
+
+{
+/* -------------------------------------------------------------------- */
+/*      Close the file.                                                 */
+/* -------------------------------------------------------------------- */
+    if( fpDDF != NULL )
+    {
+        fclose( fpDDF );
+        fpDDF = NULL;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Cleanup the working record.                                     */
+/* -------------------------------------------------------------------- */
+    if( poRecord != NULL )
+    {
+        delete poRecord;
+        poRecord = NULL;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Cleanup the clones.  Deleting them will cause a callback to     */
+/*      remove them from the list.                                      */
+/* -------------------------------------------------------------------- */
+    while( nCloneCount > 0 )
+        delete papoClones[0];
+
+    nMaxCloneCount = 0;
+    free( papoClones );
+    papoClones = NULL;
+    
+/* -------------------------------------------------------------------- */
+/*      Cleanup the field definitions.                                  */
+/* -------------------------------------------------------------------- */
+    int i;
+
+    for( i = 0; i < nFieldDefnCount; i++ )
+        delete papoFieldDefns[i];
+    free( papoFieldDefns );
+    papoFieldDefns = NULL;
+    nFieldDefnCount = 0;
+}
+
+/************************************************************************/
+/*                                Open()                                */
+/*                                                                      */
+/*      Open an ISO 8211 file, and read the DDR record to build the     */
+/*      field definitions.                                              */
+/************************************************************************/
+
+/**
+ * Open a ISO 8211 (DDF) file for reading.
+ *
+ * If the open succeeds the data descriptive record (DDR) will have been
+ * read, and all the field and subfield definitions will be available.
+ *
+ * @param pszFilename   The name of the file to open.
+ * @param bFailQuietly If false a CPL Error is issued for non-8211 files, 
+ * otherwise quietly return NULL.
+ *
+ * @return false if the open fails or true if it succeeds.  Errors messages
+ * are issued internally with CPLError().
+ */
+
+int ossimDDFModule::Open( const char * pszFilename, int bFailQuietly )
+
+{
+    static const size_t nLeaderSize = 24;
+
+/* -------------------------------------------------------------------- */
+/*      Close the existing file if there is one.                        */
+/* -------------------------------------------------------------------- */
+    if( fpDDF != NULL )
+        Close();
+    
+/* -------------------------------------------------------------------- */
+/*      Open the file.                                                  */
+/* -------------------------------------------------------------------- */
+    fpDDF = fopen( pszFilename, "rb" );
+
+    if( fpDDF == NULL )
+    {
+        if( !bFailQuietly )
+           ossimNotify(ossimNotifyLevel_WARN)
+              << "Unable to open DDF file `%s'."
+              << pszFilename << std::endl;
+        return false;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Read the 24 byte leader.                                        */
+/* -------------------------------------------------------------------- */
+    char        achLeader[nLeaderSize];
+    
+    if( fread( achLeader, 1, nLeaderSize, fpDDF ) != nLeaderSize )
+    {
+        fclose( fpDDF );
+        fpDDF = NULL;
+
+        if( !bFailQuietly )
+           ossimNotify(ossimNotifyLevel_WARN)
+              << "Leader is short on DDF file `%s'."
+              << pszFilename << std::endl;
+        
+        return false;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Verify that this appears to be a valid DDF file.                */
+/* -------------------------------------------------------------------- */
+    int         i, bValid = true;
+
+    for( i = 0; i < (int)nLeaderSize; i++ )
+    {
+        if( achLeader[i] < 32 || achLeader[i] > 126 )
+            bValid = false;
+    }
+
+    if( achLeader[5] != '1' && achLeader[5] != '2' && achLeader[5] != '3' )
+        bValid = false;
+
+    if( achLeader[6] != 'L' )
+        bValid = false;
+    if( achLeader[8] != '1' && achLeader[8] != ' ' )
+        bValid = false;
+
+/* -------------------------------------------------------------------- */
+/*      Extract information from leader.                                */
+/* -------------------------------------------------------------------- */
+
+    if( bValid )
+    {
+        _recLength                        = ossimDDFScanInt( achLeader+0, 5 );
+        _interchangeLevel                 = achLeader[5];
+        _leaderIden                   = achLeader[6];
+        _inlineCodeExtensionIndicator = achLeader[7];
+        _versionNumber                = achLeader[8];
+        _appIndicator                 = achLeader[9];
+        _fieldControlLength           = ossimDDFScanInt(achLeader+10,2);
+        _fieldAreaStart               = ossimDDFScanInt(achLeader+12,5);
+        _extendedCharSet[0]           = achLeader[17];
+        _extendedCharSet[1]           = achLeader[18];
+        _extendedCharSet[2]           = achLeader[19];
+        _extendedCharSet[3]           = '\0';
+        _sizeFieldLength              = ossimDDFScanInt(achLeader+20,1);
+        _sizeFieldPos                 = ossimDDFScanInt(achLeader+21,1);
+        _sizeFieldTag                 = ossimDDFScanInt(achLeader+23,1);
+
+        if( _recLength < 12 || _fieldControlLength == 0
+            || _fieldAreaStart < 24 || _sizeFieldLength == 0
+            || _sizeFieldPos == 0 || _sizeFieldTag == 0 )
+        {
+            bValid = false;
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If the header is invalid, then clean up, report the error       */
+/*      and return.                                                     */
+/* -------------------------------------------------------------------- */
+    if( !bValid )
+    {
+        fclose( fpDDF );
+        fpDDF = NULL;
+
+        if( !bFailQuietly )
+           ossimNotify(ossimNotifyLevel_WARN)
+              << "File `%s' does not appear to have\n"
+              << "a valid ISO 8211 header.\n"
+              << pszFilename << std::endl;
+        return false;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Read the whole record info memory.                              */
+/* -------------------------------------------------------------------- */
+    char        *pachRecord;
+
+    pachRecord = (char *) malloc(_recLength);
+    memcpy( pachRecord, achLeader, nLeaderSize );
+
+    if( fread( pachRecord+nLeaderSize, 1, _recLength-nLeaderSize, fpDDF )
+        != _recLength - nLeaderSize )
+    {
+        if( !bFailQuietly )
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Header record is short on DDF file `%s'."
+               << pszFilename << std::endl;
+        
+        return false;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      First make a pass counting the directory entries.               */
+/* -------------------------------------------------------------------- */
+    int         nFieldEntryWidth, nFDCount = 0;
+
+    nFieldEntryWidth = _sizeFieldLength + _sizeFieldPos + _sizeFieldTag;
+
+    for( i = nLeaderSize; i < _recLength; i += nFieldEntryWidth )
+    {
+        if( pachRecord[i] == OSSIM_DDF_FIELD_TERMINATOR )
+            break;
+
+        nFDCount++;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Allocate, and read field definitions.                           */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nFDCount; i++ )
+    {
+        char    szTag[128];
+        int     nEntryOffset = nLeaderSize + i*nFieldEntryWidth;
+        int     nFieldLength, nFieldPos;
+        ossimDDFFieldDefn *poFDefn;
+        
+        strncpy( szTag, pachRecord+nEntryOffset, _sizeFieldTag );
+        szTag[_sizeFieldTag] = '\0';
+
+        nEntryOffset += _sizeFieldTag;
+        nFieldLength = ossimDDFScanInt( pachRecord+nEntryOffset, _sizeFieldLength );
+        
+        nEntryOffset += _sizeFieldLength;
+        nFieldPos = ossimDDFScanInt( pachRecord+nEntryOffset, _sizeFieldPos );
+        
+        poFDefn = new ossimDDFFieldDefn();
+        poFDefn->Initialize( this, szTag, nFieldLength,
+                             pachRecord+_fieldAreaStart+nFieldPos );
+        AddField( poFDefn );
+    }
+
+    free( pachRecord );
+    
+/* -------------------------------------------------------------------- */
+/*      Record the current file offset, the beginning of the first      */
+/*      data record.                                                    */
+/* -------------------------------------------------------------------- */
+    nFirstRecordOffset = ftell( fpDDF );
+    
+    return true;
+}
+
+/************************************************************************/
+/*                             Initialize()                             */
+/************************************************************************/
+
+int ossimDDFModule::Initialize( char chInterchangeLevel,
+                           char chLeaderIden, 
+                           char chCodeExtensionIndicator,
+                           char chVersionNumber,
+                           char chAppIndicator,
+                           const char *pszExtendedCharSet,
+                           int nSizeFieldLength,
+                           int nSizeFieldPos,
+                           int nSizeFieldTag )
+
+{
+    _interchangeLevel = chInterchangeLevel;
+    _leaderIden = chLeaderIden;
+    _inlineCodeExtensionIndicator = chCodeExtensionIndicator;
+    _versionNumber = chVersionNumber;
+    _appIndicator = chAppIndicator;
+    strcpy( _extendedCharSet, pszExtendedCharSet );
+    _sizeFieldLength = nSizeFieldLength;
+    _sizeFieldPos = nSizeFieldPos;
+    _sizeFieldTag = nSizeFieldTag;
+
+    return true;
+}
+
+/************************************************************************/
+/*                               Create()                               */
+/************************************************************************/
+
+int ossimDDFModule::Create( const char *pszFilename )
+
+{
+   // CPLAssert( fpDDF == NULL );
+    
+/* -------------------------------------------------------------------- */
+/*      Create the file on disk.                                        */
+/* -------------------------------------------------------------------- */
+    fpDDF = fopen( pszFilename, "wb+" );
+    if( fpDDF == NULL )
+    {
+       ossimNotify(ossimNotifyLevel_WARN)
+          << "Failed to create file %s, check path and permissions."
+          << pszFilename << std::endl;
+        return false;
+    }
+    
+    bReadOnly = false;
+
+/* -------------------------------------------------------------------- */
+/*      Prepare all the field definition information.                   */
+/* -------------------------------------------------------------------- */
+    int iField;
+
+    _fieldControlLength = 9;
+    _recLength = 24 
+        + nFieldDefnCount * (_sizeFieldLength+_sizeFieldPos+_sizeFieldTag) 
+        + 1;
+    
+    _fieldAreaStart = _recLength;
+
+    for( iField=0; iField < nFieldDefnCount; iField++ )
+    {
+        int nLength;
+
+        papoFieldDefns[iField]->GenerateDDREntry( NULL, &nLength );
+        _recLength += nLength;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Setup 24 byte leader.                                           */
+/* -------------------------------------------------------------------- */
+    char achLeader[25];
+
+    sprintf( achLeader+0, "%05d", (int) _recLength );
+    achLeader[5] = _interchangeLevel;
+    achLeader[6] = _leaderIden;
+    achLeader[7] = _inlineCodeExtensionIndicator;
+    achLeader[8] = _versionNumber;
+    achLeader[9] = _appIndicator;
+    sprintf( achLeader+10, "%02d", (int) _fieldControlLength );
+    sprintf( achLeader+12, "%05d", (int) _fieldAreaStart );
+    strncpy( achLeader+17, _extendedCharSet, 3 );
+    sprintf( achLeader+20, "%1d", (int) _sizeFieldLength );
+    sprintf( achLeader+21, "%1d", (int) _sizeFieldPos );
+    achLeader[22] = '0';
+    sprintf( achLeader+23, "%1d", (int) _sizeFieldTag );
+    fwrite( achLeader, 24, 1, fpDDF );
+
+/* -------------------------------------------------------------------- */
+/*      Write out directory entries.                                    */
+/* -------------------------------------------------------------------- */
+    int nOffset = 0;
+    for( iField=0; iField < nFieldDefnCount; iField++ )
+    {
+        char achDirEntry[12];
+        int nLength;
+
+        papoFieldDefns[iField]->GenerateDDREntry( NULL, &nLength );
+
+        strcpy( achDirEntry, papoFieldDefns[iField]->GetName() );
+        sprintf( achDirEntry + _sizeFieldTag, "%03d", nLength );
+        sprintf( achDirEntry + _sizeFieldTag + _sizeFieldLength, 
+                 "%04d", nOffset );
+        nOffset += nLength;
+
+        fwrite( achDirEntry, 11, 1, fpDDF );
+    }
+
+    char chUT = OSSIM_DDF_FIELD_TERMINATOR;
+    fwrite( &chUT, 1, 1, fpDDF );
+
+/* -------------------------------------------------------------------- */
+/*      Write out the field descriptions themselves.                    */
+/* -------------------------------------------------------------------- */
+    for( iField=0; iField < nFieldDefnCount; iField++ )
+    {
+        char *pachData;
+        int nLength;
+
+        papoFieldDefns[iField]->GenerateDDREntry( &pachData, &nLength );
+        fwrite( pachData, nLength, 1, fpDDF );
+        free( pachData );
+    }
+    
+    return true;
+}
+
+/************************************************************************/
+/*                                Dump()                                */
+/************************************************************************/
+
+/**
+ * Write out module info to debugging file.
+ *
+ * A variety of information about the module is written to the debugging
+ * file.  This includes all the field and subfield definitions read from
+ * the header. 
+ *
+ * @param fp The standard io file handle to write to.  ie. stderr.
+ */
+
+void ossimDDFModule::Dump( FILE * fp )
+
+{
+    fprintf( fp, "DDFModule:\n" );
+    fprintf( fp, "    _recLength = %ld\n", _recLength );
+    fprintf( fp, "    _interchangeLevel = %c\n", _interchangeLevel );
+    fprintf( fp, "    _leaderIden = %c\n", _leaderIden );
+    fprintf( fp, "    _inlineCodeExtensionIndicator = %c\n",
+             _inlineCodeExtensionIndicator );
+    fprintf( fp, "    _versionNumber = %c\n", _versionNumber );
+    fprintf( fp, "    _appIndicator = %c\n", _appIndicator );
+    fprintf( fp, "    _extendedCharSet = `%s'\n", _extendedCharSet );
+    fprintf( fp, "    _fieldControlLength = %d\n", _fieldControlLength );
+    fprintf( fp, "    _fieldAreaStart = %ld\n", _fieldAreaStart );
+    fprintf( fp, "    _sizeFieldLength = %ld\n", _sizeFieldLength );
+    fprintf( fp, "    _sizeFieldPos = %ld\n", _sizeFieldPos );
+    fprintf( fp, "    _sizeFieldTag = %ld\n", _sizeFieldTag );
+
+    for( int i = 0; i < nFieldDefnCount; i++ )
+    {
+        papoFieldDefns[i]->Dump( fp );
+    }
+}
+
+/************************************************************************/
+/*                           FindFieldDefn()                            */
+/************************************************************************/
+
+/**
+ * Fetch the definition of the named field.
+ *
+ * This function will scan the DDFFieldDefn's on this module, to find
+ * one with the indicated field name.
+ *
+ * @param pszFieldName The name of the field to search for.  The comparison is
+ *                     case insensitive.
+ *
+ * @return A pointer to the request DDFFieldDefn object is returned, or NULL
+ * if none matching the name are found.  The return object remains owned by
+ * the DDFModule, and should not be deleted by application code.
+ */
+
+ossimDDFFieldDefn *ossimDDFModule::FindFieldDefn( const char *pszFieldName )
+
+{
+    int         i;
+    
+/* -------------------------------------------------------------------- */
+/*      This pass tries to reduce the cost of comparing strings by      */
+/*      first checking the first character, and by using strcmp()       */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nFieldDefnCount; i++ )
+    {
+        const char *pszThisName = papoFieldDefns[i]->GetName();
+        
+        if( *pszThisName == *pszFieldName
+            && strcmp( pszFieldName+1, pszThisName+1) == 0 )
+            return papoFieldDefns[i];
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Now do a more general check.  Application code may not          */
+/*      always use the correct name case.                               */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nFieldDefnCount; i++ )
+    {
+       ossimString s = papoFieldDefns[i]->GetName();
+       if( s == pszFieldName )
+          return papoFieldDefns[i];
+    }
+
+    return NULL;
+}
+
+/************************************************************************/
+/*                             ReadRecord()                             */
+/*                                                                      */
+/*      Read one record from the file, and return to the                */
+/*      application.  The returned record is owned by the module,       */
+/*      and is reused from call to call in order to preserve headers    */
+/*      when they aren't being re-read from record to record.           */
+/************************************************************************/
+
+/**
+ * Read one record from the file.
+ *
+ * @return A pointer to a DDFRecord object is returned, or NULL if a read
+ * error, or end of file occurs.  The returned record is owned by the
+ * module, and should not be deleted by the application.  The record is
+ * only valid untill the next ReadRecord() at which point it is overwritten.
+ */
+
+ossimDDFRecord *ossimDDFModule::ReadRecord()
+
+{
+    if( poRecord == NULL )
+        poRecord = new ossimDDFRecord( this );
+
+    if( poRecord->Read() )
+        return poRecord;
+    else
+        return NULL;
+}
+
+/************************************************************************/
+/*                              AddField()                              */
+/************************************************************************/
+
+/**
+ * Add new field definition.
+ *
+ * Field definitions may only be added to DDFModules being used for 
+ * writing, not those being used for reading.  Ownership of the 
+ * DDFFieldDefn object is taken by the DDFModule.
+ *
+ * @param poNewFDefn definition to be added to the module. 
+ */
+
+void ossimDDFModule::AddField( ossimDDFFieldDefn *poNewFDefn )
+
+{
+    nFieldDefnCount++;
+    papoFieldDefns = (ossimDDFFieldDefn **) 
+        ossimCPLRealloc(papoFieldDefns, sizeof(void*)*nFieldDefnCount);
+    papoFieldDefns[nFieldDefnCount-1] = poNewFDefn;
+}
+
+/************************************************************************/
+/*                              GetField()                              */
+/************************************************************************/
+
+/**
+ * Fetch a field definition by index.
+ *
+ * @param i (from 0 to GetFieldCount() - 1.
+ * @return the returned field pointer or NULL if the index is out of range.
+ */
+
+ossimDDFFieldDefn *ossimDDFModule::GetField(int i)
+
+{
+    if( i < 0 || i >= nFieldDefnCount )
+        return NULL;
+    else
+        return papoFieldDefns[i];
+}
+    
+/************************************************************************/
+/*                           AddCloneRecord()                           */
+/*                                                                      */
+/*      We want to keep track of cloned records, so we can clean        */
+/*      them up when the module is destroyed.                           */
+/************************************************************************/
+
+void ossimDDFModule::AddCloneRecord( ossimDDFRecord * poRecord )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Do we need to grow the container array?                         */
+/* -------------------------------------------------------------------- */
+    if( nCloneCount == nMaxCloneCount )
+    {
+        nMaxCloneCount = nCloneCount*2 + 20;
+        papoClones = (ossimDDFRecord **) ossimCPLRealloc(papoClones,
+                                               nMaxCloneCount * sizeof(void*));
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Add to the list.                                                */
+/* -------------------------------------------------------------------- */
+    papoClones[nCloneCount++] = poRecord;
+}
+
+/************************************************************************/
+/*                         RemoveCloneRecord()                          */
+/************************************************************************/
+
+void ossimDDFModule::RemoveCloneRecord( ossimDDFRecord * poRecord )
+
+{
+    int         i;
+ 
+    for( i = 0; i < nCloneCount; i++ )
+    {
+        if( papoClones[i] == poRecord )
+        {
+            papoClones[i] = papoClones[nCloneCount-1];
+            nCloneCount--;
+            return;
+        }
+    }
+
+    // CPLAssert( false );
+}
+
+/************************************************************************/
+/*                               Rewind()                               */
+/************************************************************************/
+
+/**
+ * Return to first record.
+ * 
+ * The next call to ReadRecord() will read the first data record in the file.
+ *
+ * @param nOffset the offset in the file to return to.  By default this is
+ * -1, a special value indicating that reading should return to the first
+ * data record.  Otherwise it is an absolute byte offset in the file.
+ */
+
+void ossimDDFModule::Rewind( long nOffset )
+
+{
+    if( nOffset == -1 )
+        nOffset = nFirstRecordOffset;
+
+    if( fpDDF == NULL )
+        return;
+    
+    fseek( fpDDF, nOffset, SEEK_SET );
+
+    if( nOffset == nFirstRecordOffset && poRecord != NULL )
+        poRecord->Clear();
+        
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfrecord.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfrecord.cpp
new file mode 100644
index 0000000000..7ef774db7b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfrecord.cpp
@@ -0,0 +1,1850 @@
+/******************************************************************************
+ * Copied from "gdal" project. See licence below.
+ *
+ * Project:  ISO 8211 Access
+ * Purpose:  Implements the DDFRecord class.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * $Id: ossimDdfrecord.cpp,v 1.3 2005/10/17 18:42:27 gpotts Exp $
+ */
+
+#include <imaging/formats/adrg/ossimIso8211.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimCplUtil.h>
+
+// CPL_CVSID("$Id: ossimDdfrecord.cpp,v 1.3 2005/10/17 18:42:27 gpotts Exp $");
+
+static const size_t nLeaderSize = 24;
+
+/************************************************************************/
+/*                             DDFRecord()                              */
+/************************************************************************/
+
+ossimDDFRecord::ossimDDFRecord( ossimDDFModule * poModuleIn )
+
+{
+    poModule = poModuleIn;
+
+    nReuseHeader = false;
+
+    nFieldOffset = 0;
+
+    nDataSize = 0;
+    pachData = NULL;
+
+    nFieldCount = 0;
+    paoFields = NULL;
+
+    bIsClone = false;
+
+    _sizeFieldTag = 4;
+    _sizeFieldPos = 0;
+    _sizeFieldLength = 0;
+}
+
+/************************************************************************/
+/*                             ~DDFRecord()                             */
+/************************************************************************/
+
+ossimDDFRecord::~ossimDDFRecord()
+
+{
+    Clear();
+
+    if( bIsClone )
+        poModule->RemoveCloneRecord( this );
+}
+
+/************************************************************************/
+/*                                Dump()                                */
+/************************************************************************/
+
+/**
+ * Write out record contents to debugging file.
+ *
+ * A variety of information about this record, and all it's fields and
+ * subfields is written to the given debugging file handle.  Note that
+ * field definition information (ala DDFFieldDefn) isn't written.
+ *
+ * @param fp The standard io file handle to write to.  ie. stderr
+ */
+
+void ossimDDFRecord::Dump( FILE * fp )
+
+{
+    fprintf( fp, "DDFRecord:\n" );
+    fprintf( fp, "    nReuseHeader = %d\n", nReuseHeader );
+    fprintf( fp, "    nDataSize = %d\n", nDataSize );
+    fprintf( fp, 
+             "    _sizeFieldLength=%d, _sizeFieldPos=%d, _sizeFieldTag=%d\n",
+             _sizeFieldLength, _sizeFieldPos, _sizeFieldTag );
+
+    for( int i = 0; i < nFieldCount; i++ )
+    {
+        paoFields[i].Dump( fp );
+    }
+}
+
+/************************************************************************/
+/*                                Read()                                */
+/*                                                                      */
+/*      Read a record of data from the file, and parse the header to    */
+/*      build a field list for the record (or reuse the existing one    */
+/*      if reusing headers).  It is expected that the file pointer      */
+/*      will be positioned at the beginning of a data record.  It is    */
+/*      the DDFModule's responsibility to do so.                        */
+/*                                                                      */
+/*      This method should only be called by the DDFModule class.       */
+/************************************************************************/
+
+int ossimDDFRecord::Read()
+
+{
+/* -------------------------------------------------------------------- */
+/*      Redefine the record on the basis of the header if needed.       */
+/*      As a side effect this will read the data for the record as well.*/
+/* -------------------------------------------------------------------- */
+    if( !nReuseHeader )
+    {
+        return( ReadHeader() );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Otherwise we read just the data and carefully overlay it on     */
+/*      the previous records data without disturbing the rest of the    */
+/*      record.                                                         */
+/* -------------------------------------------------------------------- */
+    size_t      nReadBytes;
+
+    nReadBytes = fread( pachData + nFieldOffset, 1,
+                           nDataSize - nFieldOffset,
+                           poModule->GetFP() );
+    if( nReadBytes != (size_t) (nDataSize - nFieldOffset)
+        && nReadBytes == 0
+        && feof( poModule->GetFP() ) )
+    {
+        return false;
+    }
+    else if( nReadBytes != (size_t) (nDataSize - nFieldOffset) )
+    {
+        ossimNotify(ossimNotifyLevel_WARN)
+           << "Data record is short on DDF file.\n" << std::endl;
+        
+        return false;
+    }
+
+    // notdef: eventually we may have to do something at this point to 
+    // notify the DDFField's that their data values have changed. 
+    
+    return true;
+}
+
+/************************************************************************/
+/*                               Write()                                */
+/************************************************************************/
+
+/**
+ * Write record out to module.
+ *
+ * This method writes the current record to the module to which it is 
+ * attached.  Normally this would be at the end of the file, and only used
+ * for modules newly created with DDFModule::Create().  Rewriting existing
+ * records is not supported at this time.  Calling Write() multiple times
+ * on a DDFRecord will result it multiple copies being written at the end of
+ * the module.
+ *
+ * @return true on success or false on failure.
+ */
+
+int ossimDDFRecord::Write()
+
+{
+    if( !ResetDirectory() )
+        return false;
+    
+/* -------------------------------------------------------------------- */
+/*      Prepare leader.                                                 */
+/* -------------------------------------------------------------------- */
+    char szLeader[nLeaderSize+1];
+
+    memset( szLeader, ' ', nLeaderSize );
+
+    sprintf( szLeader+0, "%05d", nDataSize + nLeaderSize );
+    szLeader[5] = ' ';
+    szLeader[6] = 'D';
+    
+    sprintf( szLeader + 12, "%05d", nFieldOffset + nLeaderSize );
+    szLeader[17] = ' ';
+
+    szLeader[20] = (char) ('0' + _sizeFieldLength);
+    szLeader[21] = (char) ('0' + _sizeFieldPos);
+    szLeader[22] = '0';
+    szLeader[23] = (char) ('0' + _sizeFieldTag);
+
+    /* notdef: lots of stuff missing */
+
+/* -------------------------------------------------------------------- */
+/*      Write the leader.                                               */
+/* -------------------------------------------------------------------- */
+    fwrite( szLeader, nLeaderSize, 1, poModule->GetFP() );
+
+/* -------------------------------------------------------------------- */
+/*      Write the remainder of the record.                              */
+/* -------------------------------------------------------------------- */
+    fwrite( pachData, nDataSize, 1, poModule->GetFP() );
+    
+    return true;
+}
+
+/************************************************************************/
+/*                               Clear()                                */
+/*                                                                      */
+/*      Clear any information associated with the last header in        */
+/*      preparation for reading a new header.                           */
+/************************************************************************/
+
+void ossimDDFRecord::Clear()
+
+{
+    if( paoFields != NULL )
+        delete[] paoFields;
+
+    paoFields = NULL;
+    nFieldCount = 0;
+
+    if( pachData != NULL )
+        free( pachData );
+
+    pachData = NULL;
+    nDataSize = 0;
+    nReuseHeader = false;
+}
+
+/************************************************************************/
+/*                             ReadHeader()                             */
+/*                                                                      */
+/*      This perform the header reading and parsing job for the         */
+/*      Read() method.  It reads the header, and builds a field         */
+/*      list.                                                           */
+/************************************************************************/
+
+int ossimDDFRecord::ReadHeader()
+
+{
+/* -------------------------------------------------------------------- */
+/*      Clear any existing information.                                 */
+/* -------------------------------------------------------------------- */
+    Clear();
+    
+/* -------------------------------------------------------------------- */
+/*      Read the 24 byte leader.                                        */
+/* -------------------------------------------------------------------- */
+    char        achLeader[nLeaderSize];
+    int         nReadBytes;
+
+    nReadBytes = fread(achLeader,1,nLeaderSize,poModule->GetFP());
+    if( nReadBytes == 0 && feof( poModule->GetFP() ) )
+    {
+        return false;
+    }
+    else if( nReadBytes != (int) nLeaderSize )
+    {
+        ossimNotify(ossimNotifyLevel_WARN)
+           << "Leader is short on DDF file." << std::endl;
+        
+        return false;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Extract information from leader.                                */
+/* -------------------------------------------------------------------- */
+    int         _recLength, _fieldAreaStart;
+    char        _leaderIden;
+    
+    _recLength                    = ossimDDFScanInt( achLeader+0, 5 );
+    _leaderIden                   = achLeader[6];
+    _fieldAreaStart               = ossimDDFScanInt(achLeader+12,5);
+    
+    _sizeFieldLength = achLeader[20] - '0';
+    _sizeFieldPos = achLeader[21] - '0';
+    _sizeFieldTag = achLeader[23] - '0';
+
+    if( _sizeFieldLength < 0 || _sizeFieldLength > 9 
+        || _sizeFieldPos < 0 || _sizeFieldPos > 9
+        || _sizeFieldTag < 0 || _sizeFieldTag > 9 )
+    {
+        ossimNotify(ossimNotifyLevel_WARN)
+           << "ISO8211 record leader appears to be corrupt." << std::endl;
+        return false;
+    }
+
+    if( _leaderIden == 'R' )
+        nReuseHeader = true;
+
+    nFieldOffset = _fieldAreaStart - nLeaderSize;
+
+/* -------------------------------------------------------------------- */
+/*      Is there anything seemly screwy about this record?              */
+/* -------------------------------------------------------------------- */
+    if(( _recLength < 24 || _recLength > 100000000
+         || _fieldAreaStart < 24 || _fieldAreaStart > 100000 )
+       && (_recLength != 0))
+    {
+        ossimNotify(ossimNotifyLevel_WARN)
+           << "Data record appears to be corrupt on DDF file.\n"
+           << " -- ensure that the files were uncompressed without modifying\n"
+           << "carriage return/linefeeds (by default WINZIP does this)."
+           << std::endl;
+        
+        return false;
+    }
+
+/* ==================================================================== */
+/*      Handle the normal case with the record length available.        */
+/* ==================================================================== */
+    if(_recLength != 0) {
+/* -------------------------------------------------------------------- */
+/*      Read the remainder of the record.                               */
+/* -------------------------------------------------------------------- */
+        nDataSize = _recLength - nLeaderSize;
+        pachData = (char *) malloc(nDataSize);
+
+        if( fread( pachData, 1, nDataSize, poModule->GetFP()) !=
+            (size_t) nDataSize )
+        {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Data record is short on DDF file."
+               << std::endl;
+          
+            return false;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If we don't find a field terminator at the end of the record    */
+/*      we will read extra bytes till we get to it.                     */
+/* -------------------------------------------------------------------- */
+        while( pachData[nDataSize-1] != OSSIM_DDF_FIELD_TERMINATOR )
+        {
+            nDataSize++;
+            pachData = (char *) ossimCPLRealloc(pachData,nDataSize);
+            
+            if( fread( pachData + nDataSize - 1, 1, 1, poModule->GetFP() )
+                != 1 )
+            {
+                ossimNotify(ossimNotifyLevel_WARN)
+                   << "Data record is short on DDF file."
+                   << std::endl;
+                
+                return false;
+            }
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "Didn't find field terminator, read one more byte."
+               << std::endl;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Loop over the directory entries, making a pass counting them.   */
+/* -------------------------------------------------------------------- */
+        int         i;
+        int         nFieldEntryWidth;
+      
+        nFieldEntryWidth = _sizeFieldLength + _sizeFieldPos + _sizeFieldTag;
+        nFieldCount = 0;
+        for( i = 0; i < nDataSize; i += nFieldEntryWidth )
+        {
+            if( pachData[i] == OSSIM_DDF_FIELD_TERMINATOR )
+                break;
+          
+            nFieldCount++;
+        }
+    
+/* -------------------------------------------------------------------- */
+/*      Allocate, and read field definitions.                           */
+/* -------------------------------------------------------------------- */
+        paoFields = new ossimDDFField[nFieldCount];
+    
+        for( i = 0; i < nFieldCount; i++ )
+        {
+            char    szTag[128];
+            int     nEntryOffset = i*nFieldEntryWidth;
+            int     nFieldLength, nFieldPos;
+          
+/* -------------------------------------------------------------------- */
+/*      Read the position information and tag.                          */
+/* -------------------------------------------------------------------- */
+            strncpy( szTag, pachData+nEntryOffset, _sizeFieldTag );
+            szTag[_sizeFieldTag] = '\0';
+          
+            nEntryOffset += _sizeFieldTag;
+            nFieldLength = ossimDDFScanInt( pachData+nEntryOffset, _sizeFieldLength );
+          
+            nEntryOffset += _sizeFieldLength;
+            nFieldPos = ossimDDFScanInt( pachData+nEntryOffset, _sizeFieldPos );
+          
+/* -------------------------------------------------------------------- */
+/*      Find the corresponding field in the module directory.           */
+/* -------------------------------------------------------------------- */
+            ossimDDFFieldDefn    *poFieldDefn = poModule->FindFieldDefn( szTag );
+          
+            if( poFieldDefn == NULL )
+            {
+                ossimNotify(ossimNotifyLevel_WARN)
+                   << "Undefined field `%s' encountered in data record."
+                   << szTag << std::endl;
+                return false;
+            }
+
+/* -------------------------------------------------------------------- */
+/*      Assign info the DDFField.                                       */
+/* -------------------------------------------------------------------- */
+            paoFields[i].Initialize( poFieldDefn, 
+                                     pachData + _fieldAreaStart + nFieldPos - nLeaderSize,
+                                     nFieldLength );
+        }
+      
+        return true;
+    }
+/* ==================================================================== */
+/*      Handle the exceptional case where the record length is          */
+/*      zero.  In this case we have to read all the data based on       */
+/*      the size of data items as per ISO8211 spec Annex C, 1.5.1.      */
+/*                                                                      */
+/*      See Bugzilla bug 181 and test with file US4CN21M.000.           */
+/* ==================================================================== */
+    else {
+        ossimNotify(ossimNotifyLevel_WARN)
+           << "Record with zero length, use variant (C.1.5.1) logic."
+           << std::endl;
+
+        /* ----------------------------------------------------------------- */
+        /*   _recLength == 0, handle the large record.                       */
+        /*                                                                   */
+        /*   Read the remainder of the record.                               */
+        /* ----------------------------------------------------------------- */
+        nDataSize = 0;
+        pachData = NULL;
+
+        /* ----------------------------------------------------------------- */
+        /*   Loop over the directory entries, making a pass counting them.   */
+        /* ----------------------------------------------------------------- */
+        int nFieldEntryWidth = _sizeFieldLength + _sizeFieldPos + _sizeFieldTag;
+        nFieldCount = 0;
+        int i=0;
+        char *tmpBuf = (char*)malloc(nFieldEntryWidth);
+      
+        // while we're not at the end, store this entry,
+        // and keep on reading...
+        do {
+            // read an Entry:
+            if(nFieldEntryWidth != 
+               (int) fread(tmpBuf, 1, nFieldEntryWidth, poModule->GetFP())) {
+                ossimNotify(ossimNotifyLevel_WARN)
+                   << "Data record is short on DDF file." << std::endl;
+                return false;
+            }
+      
+            // move this temp buffer into more permanent storage:
+            char *newBuf = (char*)malloc(nDataSize+nFieldEntryWidth);
+            if(pachData!=NULL) {
+                memcpy(newBuf, pachData, nDataSize);
+                free(pachData);
+            }
+            memcpy(&newBuf[nDataSize], tmpBuf, nFieldEntryWidth);
+            pachData = newBuf;
+            nDataSize += nFieldEntryWidth;
+
+            if(OSSIM_DDF_FIELD_TERMINATOR != tmpBuf[0]) {
+                nFieldCount++;
+            }
+        }
+        while(OSSIM_DDF_FIELD_TERMINATOR != tmpBuf[0]);
+
+        // Now, rewind a little.  Only the TERMINATOR should have been read:
+        int rewindSize = nFieldEntryWidth - 1;
+        FILE *fp = poModule->GetFP();
+        long pos = ftell(fp) - rewindSize;
+        fseek(fp, pos, SEEK_SET);
+        nDataSize -= rewindSize;
+
+        // --------------------------------------------------------------------
+        // Okay, now let's populate the heck out of pachData...
+        // --------------------------------------------------------------------
+        for(i=0; i<nFieldCount; i++) {
+            int nEntryOffset = (i*nFieldEntryWidth) + _sizeFieldTag;
+            int nFieldLength = ossimDDFScanInt(pachData + nEntryOffset,
+                                          _sizeFieldLength);
+            char *tmpBuf = (char*)malloc(nFieldLength);
+
+            // read an Entry:
+            if(nFieldLength != 
+               (int) fread(tmpBuf, 1, nFieldLength, poModule->GetFP())) {
+                ossimNotify(ossimNotifyLevel_WARN)
+                   << "Data record is short on DDF file." << std::endl;
+                return false;
+            }
+      
+            // move this temp buffer into more permanent storage:
+            char *newBuf = (char*)malloc(nDataSize+nFieldLength);
+            memcpy(newBuf, pachData, nDataSize);
+            free(pachData);
+            memcpy(&newBuf[nDataSize], tmpBuf, nFieldLength);
+            free(tmpBuf);
+            pachData = newBuf;
+            nDataSize += nFieldLength;
+        }
+    
+        /* ----------------------------------------------------------------- */
+        /*     Allocate, and read field definitions.                         */
+        /* ----------------------------------------------------------------- */
+        paoFields = new ossimDDFField[nFieldCount];
+      
+        for( i = 0; i < nFieldCount; i++ )
+        {
+            char    szTag[128];
+            int     nEntryOffset = i*nFieldEntryWidth;
+            int     nFieldLength, nFieldPos;
+          
+            /* ------------------------------------------------------------- */
+            /* Read the position information and tag.                        */
+            /* ------------------------------------------------------------- */
+            strncpy( szTag, pachData+nEntryOffset, _sizeFieldTag );
+            szTag[_sizeFieldTag] = '\0';
+          
+            nEntryOffset += _sizeFieldTag;
+            nFieldLength = ossimDDFScanInt( pachData+nEntryOffset, _sizeFieldLength );
+          
+            nEntryOffset += _sizeFieldLength;
+            nFieldPos = ossimDDFScanInt( pachData+nEntryOffset, _sizeFieldPos );
+          
+            /* ------------------------------------------------------------- */
+            /* Find the corresponding field in the module directory.         */
+            /* ------------------------------------------------------------- */
+            ossimDDFFieldDefn    *poFieldDefn = poModule->FindFieldDefn( szTag );
+          
+            if( poFieldDefn == NULL )
+            {
+                ossimNotify(ossimNotifyLevel_WARN)
+                   << "Undefined field `%s' encountered in data record."
+                   << szTag << std::endl;
+                return false;
+            }
+
+            /* ------------------------------------------------------------- */
+            /* Assign info the DDFField.                                     */
+            /* ------------------------------------------------------------- */
+
+            paoFields[i].Initialize( poFieldDefn, 
+                                     pachData + _fieldAreaStart
+                                     + nFieldPos - nLeaderSize,
+                                     nFieldLength );
+        }
+      
+        return true;
+    }
+}
+
+/************************************************************************/
+/*                             FindField()                              */
+/************************************************************************/
+
+/**
+ * Find the named field within this record.
+ *
+ * @param pszName The name of the field to fetch.  The comparison is
+ * case insensitive.
+ * @param iFieldIndex The instance of this field to fetch.  Use zero (the
+ * default) for the first instance.
+ *
+ * @return Pointer to the requested DDFField.  This pointer is to an
+ * internal object, and should not be freed.  It remains valid until
+ * the next record read. 
+ */
+
+ossimDDFField * ossimDDFRecord::FindField( const char * pszName, int iFieldIndex )
+
+{
+    for( int i = 0; i < nFieldCount; i++ )
+    {
+       ossimString s = paoFields[i].GetFieldDefn()->GetName();
+        if( s == pszName)
+        {
+            if( iFieldIndex == 0 )
+                return paoFields + i;
+            else
+                iFieldIndex--;
+        }
+    }
+
+    return NULL;
+}
+
+/************************************************************************/
+/*                              GetField()                              */
+/************************************************************************/
+
+/**
+ * Fetch field object based on index.
+ *
+ * @param i The index of the field to fetch.  Between 0 and GetFieldCount()-1.
+ *
+ * @return A DDFField pointer, or NULL if the index is out of range.
+ */
+
+ossimDDFField *ossimDDFRecord::GetField( int i )
+
+{
+    if( i < 0 || i >= nFieldCount )
+        return NULL;
+    else
+        return paoFields + i;
+}
+
+/************************************************************************/
+/*                           GetIntSubfield()                           */
+/************************************************************************/
+
+/**
+ * Fetch value of a subfield as an integer.  This is a convenience
+ * function for fetching a subfield of a field within this record.
+ *
+ * @param pszField The name of the field containing the subfield.
+ * @param iFieldIndex The instance of this field within the record.  Use
+ * zero for the first instance of this field.
+ * @param pszSubfield The name of the subfield within the selected field.
+ * @param iSubfieldIndex The instance of this subfield within the record.
+ * Use zero for the first instance.
+ * @param pnSuccess Pointer to an int which will be set to true if the fetch
+ * succeeds, or false if it fails.  Use NULL if you don't want to check
+ * success.
+ * @return The value of the subfield, or zero if it failed for some reason.
+ */
+
+int ossimDDFRecord::GetIntSubfield( const char * pszField, int iFieldIndex,
+                               const char * pszSubfield, int iSubfieldIndex,
+                               int * pnSuccess )
+
+{
+    ossimDDFField    *poField;
+    int         nDummyErr;
+
+    if( pnSuccess == NULL )
+        pnSuccess = &nDummyErr;
+
+    *pnSuccess = false;
+            
+/* -------------------------------------------------------------------- */
+/*      Fetch the field. If this fails, return zero.                    */
+/* -------------------------------------------------------------------- */
+    poField = FindField( pszField, iFieldIndex );
+    if( poField == NULL )
+        return 0;
+
+/* -------------------------------------------------------------------- */
+/*      Get the subfield definition                                     */
+/* -------------------------------------------------------------------- */
+    ossimDDFSubfieldDefn     *poSFDefn;
+
+    poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield );
+    if( poSFDefn == NULL )
+        return 0;
+
+/* -------------------------------------------------------------------- */
+/*      Get a pointer to the data.                                      */
+/* -------------------------------------------------------------------- */
+    int         nBytesRemaining;
+    
+    const char *pachData = poField->GetSubfieldData(poSFDefn,
+                                                    &nBytesRemaining,
+                                                    iSubfieldIndex);
+
+/* -------------------------------------------------------------------- */
+/*      Return the extracted value.                                     */
+/* -------------------------------------------------------------------- */
+    *pnSuccess = true;
+
+    return( poSFDefn->ExtractIntData( pachData, nBytesRemaining, NULL ) );
+}
+
+/************************************************************************/
+/*                          GetFloatSubfield()                          */
+/************************************************************************/
+
+/**
+ * Fetch value of a subfield as a float (double).  This is a convenience
+ * function for fetching a subfield of a field within this record.
+ *
+ * @param pszField The name of the field containing the subfield.
+ * @param iFieldIndex The instance of this field within the record.  Use
+ * zero for the first instance of this field.
+ * @param pszSubfield The name of the subfield within the selected field.
+ * @param iSubfieldIndex The instance of this subfield within the record.
+ * Use zero for the first instance.
+ * @param pnSuccess Pointer to an int which will be set to true if the fetch
+ * succeeds, or false if it fails.  Use NULL if you don't want to check
+ * success.
+ * @return The value of the subfield, or zero if it failed for some reason.
+ */
+
+double ossimDDFRecord::GetFloatSubfield( const char * pszField, int iFieldIndex,
+                                 const char * pszSubfield, int iSubfieldIndex,
+                                    int * pnSuccess )
+
+{
+    ossimDDFField    *poField;
+    int         nDummyErr;
+
+    if( pnSuccess == NULL )
+        pnSuccess = &nDummyErr;
+
+    *pnSuccess = false;
+            
+/* -------------------------------------------------------------------- */
+/*      Fetch the field. If this fails, return zero.                    */
+/* -------------------------------------------------------------------- */
+    poField = FindField( pszField, iFieldIndex );
+    if( poField == NULL )
+        return 0;
+
+/* -------------------------------------------------------------------- */
+/*      Get the subfield definition                                     */
+/* -------------------------------------------------------------------- */
+    ossimDDFSubfieldDefn     *poSFDefn;
+
+    poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield );
+    if( poSFDefn == NULL )
+        return 0;
+
+/* -------------------------------------------------------------------- */
+/*      Get a pointer to the data.                                      */
+/* -------------------------------------------------------------------- */
+    int         nBytesRemaining;
+    
+    const char *pachData = poField->GetSubfieldData(poSFDefn,
+                                                    &nBytesRemaining,
+                                                    iSubfieldIndex);
+
+/* -------------------------------------------------------------------- */
+/*      Return the extracted value.                                     */
+/* -------------------------------------------------------------------- */
+    *pnSuccess = true;
+
+    return( poSFDefn->ExtractFloatData( pachData, nBytesRemaining, NULL ) );
+}
+
+/************************************************************************/
+/*                         GetStringSubfield()                          */
+/************************************************************************/
+
+/**
+ * Fetch value of a subfield as a string.  This is a convenience
+ * function for fetching a subfield of a field within this record.
+ *
+ * @param pszField The name of the field containing the subfield.
+ * @param iFieldIndex The instance of this field within the record.  Use
+ * zero for the first instance of this field.
+ * @param pszSubfield The name of the subfield within the selected field.
+ * @param iSubfieldIndex The instance of this subfield within the record.
+ * Use zero for the first instance.
+ * @param pnSuccess Pointer to an int which will be set to true if the fetch
+ * succeeds, or false if it fails.  Use NULL if you don't want to check
+ * success.
+ * @return The value of the subfield, or NULL if it failed for some reason.
+ * The returned pointer is to internal data and should not be modified or
+ * freed by the application.
+ */
+
+const char *
+ossimDDFRecord::GetStringSubfield( const char * pszField, int iFieldIndex,
+                              const char * pszSubfield, int iSubfieldIndex,
+                              int * pnSuccess )
+
+{
+    ossimDDFField    *poField;
+    int         nDummyErr;
+
+    if( pnSuccess == NULL )
+        pnSuccess = &nDummyErr;
+
+    *pnSuccess = false;
+            
+/* -------------------------------------------------------------------- */
+/*      Fetch the field. If this fails, return zero.                    */
+/* -------------------------------------------------------------------- */
+    poField = FindField( pszField, iFieldIndex );
+    if( poField == NULL )
+        return NULL;
+
+/* -------------------------------------------------------------------- */
+/*      Get the subfield definition                                     */
+/* -------------------------------------------------------------------- */
+    ossimDDFSubfieldDefn     *poSFDefn;
+
+    poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield );
+    if( poSFDefn == NULL )
+        return NULL;
+
+/* -------------------------------------------------------------------- */
+/*      Get a pointer to the data.                                      */
+/* -------------------------------------------------------------------- */
+    int         nBytesRemaining;
+    
+    const char *pachData = poField->GetSubfieldData(poSFDefn,
+                                                    &nBytesRemaining,
+                                                    iSubfieldIndex);
+
+/* -------------------------------------------------------------------- */
+/*      Return the extracted value.                                     */
+/* -------------------------------------------------------------------- */
+    *pnSuccess = true;
+
+    return( poSFDefn->ExtractStringData( pachData, nBytesRemaining, NULL ) );
+}
+
+/************************************************************************/
+/*                               Clone()                                */
+/************************************************************************/
+
+/**
+ * Make a copy of a record.
+ *
+ * This method is used to make a copy of a record that will become (mostly)
+ * the properly of application.  However, it is automatically destroyed if
+ * the DDFModule it was created relative to is destroyed, as it's field
+ * and subfield definitions relate to that DDFModule.  However, it does
+ * persist even when the record returned by DDFModule::ReadRecord() is
+ * invalidated, such as when reading a new record.  This allows an application
+ * to cache whole DDFRecords.
+ *
+ * @return A new copy of the DDFRecord.  This can be delete'd by the
+ * application when no longer needed, otherwise it will be cleaned up when
+ * the DDFModule it relates to is destroyed or closed.
+ */
+
+ossimDDFRecord * ossimDDFRecord::Clone()
+
+{
+    ossimDDFRecord   *poNR;
+
+    poNR = new ossimDDFRecord( poModule );
+
+    poNR->nReuseHeader = false;
+    poNR->nFieldOffset = nFieldOffset;
+    
+    poNR->nDataSize = nDataSize;
+    poNR->pachData = (char *) malloc(nDataSize);
+    memcpy( poNR->pachData, pachData, nDataSize );
+    
+    poNR->nFieldCount = nFieldCount;
+    poNR->paoFields = new ossimDDFField[nFieldCount];
+    for( int i = 0; i < nFieldCount; i++ )
+    {
+        int     nOffset;
+
+        nOffset = (paoFields[i].GetData() - pachData);
+        poNR->paoFields[i].Initialize( paoFields[i].GetFieldDefn(),
+                                       poNR->pachData + nOffset,
+                                       paoFields[i].GetDataSize() );
+    }
+    
+    poNR->bIsClone = true;
+    poModule->AddCloneRecord( poNR );
+
+    return poNR;
+}
+
+/************************************************************************/
+/*                              CloneOn()                               */
+/************************************************************************/
+
+/**
+ * Recreate a record referencing another module.
+ *
+ * Works similarly to the DDFRecord::Clone() method, but creates the
+ * new record with reference to a different DDFModule.  All DDFFieldDefn
+ * references are transcribed onto the new module based on field names.
+ * If any fields don't have a similarly named field on the target module
+ * the operation will fail.  No validation of field types and properties
+ * is done, but this operation is intended only to be used between 
+ * modules with matching definitions of all affected fields. 
+ *
+ * The new record will be managed as a clone by the target module in
+ * a manner similar to regular clones. 
+ *
+ * @param poTargetModule the module on which the record copy should be
+ * created.
+ *
+ * @return NULL on failure or a pointer to the cloned record.
+ */
+
+ossimDDFRecord *ossimDDFRecord::CloneOn( ossimDDFModule *poTargetModule )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Verify that all fields have a corresponding field definition    */
+/*      on the target module.                                           */
+/* -------------------------------------------------------------------- */
+    int         i;
+
+    for( i = 0; i < nFieldCount; i++ )
+    {
+        ossimDDFFieldDefn    *poDefn = paoFields[i].GetFieldDefn();
+
+        if( poTargetModule->FindFieldDefn( poDefn->GetName() ) == NULL )
+            return NULL;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Create a clone.                                                 */
+/* -------------------------------------------------------------------- */
+    ossimDDFRecord   *poClone;
+
+    poClone = Clone();
+
+/* -------------------------------------------------------------------- */
+/*      Update all internal information to reference other module.      */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nFieldCount; i++ )
+    {
+        ossimDDFField        *poField = poClone->paoFields+i;
+        ossimDDFFieldDefn    *poDefn;
+
+        poDefn = poTargetModule->FindFieldDefn( 
+            poField->GetFieldDefn()->GetName() );
+        
+        poField->Initialize( poDefn, poField->GetData(), 
+                             poField->GetDataSize() );
+    }
+
+    poModule->RemoveCloneRecord( poClone );
+    poClone->poModule = poTargetModule;
+    poTargetModule->AddCloneRecord( poClone );
+
+    return poClone;
+}
+
+
+/************************************************************************/
+/*                            DeleteField()                             */
+/************************************************************************/
+
+/**
+ * Delete a field instance from a record.
+ *
+ * Remove a field from this record, cleaning up the data            
+ * portion and repacking the fields list.  We don't try to          
+ * reallocate the data area of the record to be smaller.            
+ *                                                                       
+ * NOTE: This method doesn't actually remove the header             
+ * information for this field from the record tag list yet.        
+ * This should be added if the resulting record is even to be      
+ * written back to disk!                                           
+ *
+ * @param poTarget the field instance on this record to delete.
+ *
+ * @return true on success, or false on failure.  Failure can occur if 
+ * poTarget isn't really a field on this record.
+ */
+
+int ossimDDFRecord::DeleteField( ossimDDFField *poTarget )
+
+{
+    int         iTarget, i;
+
+/* -------------------------------------------------------------------- */
+/*      Find which field we are to delete.                              */
+/* -------------------------------------------------------------------- */
+    for( iTarget = 0; iTarget < nFieldCount; iTarget++ )
+    {
+        if( paoFields + iTarget == poTarget )
+            break;
+    }
+
+    if( iTarget == nFieldCount )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      Change the target fields data size to zero.  This takes care    */
+/*      of repacking the data array, and updating all the following     */
+/*      field data pointers.                                            */
+/* -------------------------------------------------------------------- */
+    ResizeField( poTarget, 0 );
+
+/* -------------------------------------------------------------------- */
+/*      remove the target field, moving down all the other fields       */
+/*      one step in the field list.                                     */
+/* -------------------------------------------------------------------- */
+    for( i = iTarget; i < nFieldCount-1; i++ )
+    {
+        paoFields[i] = paoFields[i+1];
+    }
+
+    nFieldCount--;
+
+    return true;
+}
+
+/************************************************************************/
+/*                            ResizeField()                             */
+/************************************************************************/
+
+/**
+ * Alter field data size within record.
+ *
+ * This method will rearrange a DDFRecord altering the amount of space
+ * reserved for one of the existing fields.  All following fields will
+ * be shifted accordingly.  This includes updating the DDFField infos, 
+ * and actually moving stuff within the data array after reallocating
+ * to the desired size.
+ *
+ * @param poField the field to alter.
+ * @param nNewDataSize the number of data bytes to be reserved for the field.
+ *
+ * @return true on success or false on failure. 
+ */
+
+int ossimDDFRecord::ResizeField( ossimDDFField *poField, int nNewDataSize )
+
+{
+    int         iTarget, i;
+    int         nBytesToMove;
+
+/* -------------------------------------------------------------------- */
+/*      Find which field we are to resize.                              */
+/* -------------------------------------------------------------------- */
+    for( iTarget = 0; iTarget < nFieldCount; iTarget++ )
+    {
+        if( paoFields + iTarget == poField )
+            break;
+    }
+
+    if( iTarget == nFieldCount )
+    {
+       // CPLAssert( false );
+        return false;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Reallocate the data buffer accordingly.                         */
+/* -------------------------------------------------------------------- */
+    int nBytesToAdd = nNewDataSize - poField->GetDataSize();
+    const char *pachOldData = pachData;
+
+    // Don't realloc things smaller ... we will cut off some data.
+    if( nBytesToAdd > 0 )
+        pachData = (char *) ossimCPLRealloc(pachData, nDataSize + nBytesToAdd );
+
+    nDataSize += nBytesToAdd;
+
+/* -------------------------------------------------------------------- */
+/*      How much data needs to be shifted up or down after this field?  */
+/* -------------------------------------------------------------------- */
+    nBytesToMove = nDataSize 
+        - (poField->GetData()+poField->GetDataSize()-pachOldData+nBytesToAdd);
+
+/* -------------------------------------------------------------------- */
+/*      Update fields to point into newly allocated buffer.             */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nFieldCount; i++ )
+    {
+        int     nOffset;
+
+        nOffset = paoFields[i].GetData() - pachOldData;
+        paoFields[i].Initialize( paoFields[i].GetFieldDefn(), 
+                                 pachData + nOffset, 
+                                 paoFields[i].GetDataSize() );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Shift the data beyond this field up or down as needed.          */
+/* -------------------------------------------------------------------- */
+    if( nBytesToMove > 0 )
+        memmove( (char *)poField->GetData()+poField->GetDataSize()+nBytesToAdd,
+                 (char *)poField->GetData()+poField->GetDataSize(), 
+                 nBytesToMove );
+             
+/* -------------------------------------------------------------------- */
+/*      Update the target fields info.                                  */
+/* -------------------------------------------------------------------- */
+    poField->Initialize( poField->GetFieldDefn(),
+                         poField->GetData(), 
+                         poField->GetDataSize() + nBytesToAdd );
+
+/* -------------------------------------------------------------------- */
+/*      Shift all following fields down, and update their data          */
+/*      locations.                                                      */
+/* -------------------------------------------------------------------- */
+    if( nBytesToAdd < 0 )
+    {
+        for( i = iTarget+1; i < nFieldCount; i++ )
+        {
+            char *pszOldDataLocation;
+
+            pszOldDataLocation = (char *) paoFields[i].GetData();
+
+            paoFields[i].Initialize( paoFields[i].GetFieldDefn(), 
+                                     pszOldDataLocation + nBytesToAdd,
+                                     paoFields[i].GetDataSize() ); 
+        }
+    }
+    else
+    {
+        for( i = nFieldCount-1; i > iTarget; i-- )
+        {
+            char *pszOldDataLocation;
+
+            pszOldDataLocation = (char *) paoFields[i].GetData();
+
+            paoFields[i].Initialize( paoFields[i].GetFieldDefn(), 
+                                     pszOldDataLocation + nBytesToAdd,
+                                     paoFields[i].GetDataSize() ); 
+        }
+    }
+
+    return true;
+}
+
+/************************************************************************/
+/*                              AddField()                              */
+/************************************************************************/
+
+/**
+ * Add a new field to record.
+ *
+ * Add a new zero sized field to the record.  The new field is always
+ * added at the end of the record. 
+ *
+ * NOTE: This method doesn't currently update the header information for
+ * the record to include the field information for this field, so the
+ * resulting record image isn't suitable for writing to disk.  However, 
+ * everything else about the record state should be updated properly to 
+ * reflect the new field.
+ *
+ * @param poDefn the definition of the field to be added.
+ *
+ * @return the field object on success, or NULL on failure.
+ */
+
+ossimDDFField *ossimDDFRecord::AddField( ossimDDFFieldDefn *poDefn )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Reallocate the fields array larger by one, and initialize       */
+/*      the new field.                                                  */
+/* -------------------------------------------------------------------- */
+    ossimDDFField    *paoNewFields;
+
+    paoNewFields = new ossimDDFField[nFieldCount+1];
+    if( nFieldCount > 0 )
+    {
+        memcpy( paoNewFields, paoFields, sizeof(ossimDDFField) * nFieldCount );
+        delete[] paoFields;
+    }
+    paoFields = paoNewFields;
+    nFieldCount++;
+
+/* -------------------------------------------------------------------- */
+/*      Initialize the new field properly.                              */
+/* -------------------------------------------------------------------- */
+    if( nFieldCount == 1 )
+    {
+        paoFields[0].Initialize( poDefn, GetData(), 0 );
+    }
+    else
+    {
+        paoFields[nFieldCount-1].Initialize( 
+            poDefn, 
+            paoFields[nFieldCount-2].GetData()
+            + paoFields[nFieldCount-2].GetDataSize(), 
+            0 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Initialize field.                                               */
+/* -------------------------------------------------------------------- */
+    CreateDefaultFieldInstance( paoFields + nFieldCount-1, 0 );
+
+    return paoFields + (nFieldCount - 1);
+}
+
+/************************************************************************/
+/*                            SetFieldRaw()                             */
+/************************************************************************/
+
+/**
+ * Set the raw contents of a field instance.
+ *
+ * @param poField the field to set data within. 
+ * @param iIndexWithinField The instance of this field to replace.  Must
+ * be a value between 0 and GetRepeatCount().  If GetRepeatCount() is used, a
+ * new instance of the field is appeneded.
+ * @param pachRawData the raw data to replace this field instance with.
+ * @param nRawDataSize the number of bytes pointed to by pachRawData.
+ *
+ * @return true on success or false on failure.
+ */
+
+int
+ossimDDFRecord::SetFieldRaw( ossimDDFField *poField, int iIndexWithinField,
+                        const char *pachRawData, int nRawDataSize )
+
+{
+    int         iTarget, nRepeatCount;
+
+/* -------------------------------------------------------------------- */
+/*      Find which field we are to update.                              */
+/* -------------------------------------------------------------------- */
+    for( iTarget = 0; iTarget < nFieldCount; iTarget++ )
+    {
+        if( paoFields + iTarget == poField )
+            break;
+    }
+
+    if( iTarget == nFieldCount )
+        return false;
+
+    nRepeatCount = poField->GetRepeatCount();
+
+    if( iIndexWithinField < 0 || iIndexWithinField > nRepeatCount )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      Are we adding an instance?  This is easier and different        */
+/*      than replacing an existing instance.                            */
+/* -------------------------------------------------------------------- */
+    if( iIndexWithinField == nRepeatCount 
+        || !poField->GetFieldDefn()->IsRepeating() )
+    {
+        char    *pachFieldData;
+        int     nOldSize;
+
+        if( !poField->GetFieldDefn()->IsRepeating() && iIndexWithinField != 0 )
+            return false;
+
+        nOldSize = poField->GetDataSize();
+        if( nOldSize == 0 )
+            nOldSize++; // for added DDF_FIELD_TERMINATOR. 
+
+        if( !ResizeField( poField, nOldSize + nRawDataSize ) )
+            return false;
+
+        pachFieldData = (char *) poField->GetData();
+        memcpy( pachFieldData + nOldSize - 1, 
+                pachRawData, nRawDataSize );
+        pachFieldData[nOldSize+nRawDataSize-1] = OSSIM_DDF_FIELD_TERMINATOR;
+
+        return true;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Get a pointer to the start of the existing data for this        */
+/*      iteration of the field.                                         */
+/* -------------------------------------------------------------------- */
+    const char *pachWrkData;
+    int         nInstanceSize;
+
+    // We special case this to avoid alot of warnings when initializing 
+    // the field the first time.
+    if( poField->GetDataSize() == 0 )
+    {
+        pachWrkData = poField->GetData();
+        nInstanceSize = 0;
+    }
+    else
+    {
+        pachWrkData = poField->GetInstanceData( iIndexWithinField, 
+                                                &nInstanceSize );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Create new image of this whole field.                           */
+/* -------------------------------------------------------------------- */
+    char        *pachNewImage;
+    int         nPreBytes, nPostBytes, nNewFieldSize;
+
+    nNewFieldSize = poField->GetDataSize() - nInstanceSize + nRawDataSize;
+
+    pachNewImage = (char *) malloc(nNewFieldSize);
+
+    nPreBytes = pachWrkData - poField->GetData();
+    nPostBytes = poField->GetDataSize() - nPreBytes - nInstanceSize;
+
+    memcpy( pachNewImage, poField->GetData(), nPreBytes );
+    memcpy( pachNewImage + nPreBytes + nRawDataSize, 
+            poField->GetData() + nPreBytes + nInstanceSize,
+            nPostBytes );
+    memcpy( pachNewImage + nPreBytes, pachRawData, nRawDataSize );
+
+/* -------------------------------------------------------------------- */
+/*      Resize the field to the desired new size.                       */
+/* -------------------------------------------------------------------- */
+    ResizeField( poField, nNewFieldSize );
+
+    memcpy( (void *) poField->GetData(), pachNewImage, nNewFieldSize );
+    free( pachNewImage );
+
+    return true;
+}
+
+/************************************************************************/
+/*                           UpdateFieldRaw()                           */
+/************************************************************************/
+
+int
+ossimDDFRecord::UpdateFieldRaw( ossimDDFField *poField, int iIndexWithinField,
+                           int nStartOffset, int nOldSize, 
+                           const char *pachRawData, int nRawDataSize )
+
+{
+    int         iTarget, nRepeatCount;
+
+/* -------------------------------------------------------------------- */
+/*      Find which field we are to update.                              */
+/* -------------------------------------------------------------------- */
+    for( iTarget = 0; iTarget < nFieldCount; iTarget++ )
+    {
+        if( paoFields + iTarget == poField )
+            break;
+    }
+
+    if( iTarget == nFieldCount )
+        return false;
+
+    nRepeatCount = poField->GetRepeatCount();
+
+    if( iIndexWithinField < 0 || iIndexWithinField >= nRepeatCount )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      Figure out how much pre and post data there is.                 */
+/* -------------------------------------------------------------------- */
+    char *pachWrkData;
+    int         nInstanceSize, nPostBytes, nPreBytes;
+        
+    pachWrkData = (char *) poField->GetInstanceData( iIndexWithinField, 
+                                                     &nInstanceSize );
+    nPreBytes = pachWrkData - poField->GetData() + nStartOffset;
+    nPostBytes = poField->GetDataSize() - nPreBytes - nOldSize;
+
+/* -------------------------------------------------------------------- */
+/*      If we aren't changing the size, just copy over the existing     */
+/*      data.                                                           */
+/* -------------------------------------------------------------------- */
+    if( nOldSize == nRawDataSize )
+    {
+        memcpy( pachWrkData + nStartOffset, pachRawData, nRawDataSize );
+        return true;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If we are shrinking, move in the new data, and shuffle down     */
+/*      the old before resizing.                                        */
+/* -------------------------------------------------------------------- */
+    if( nRawDataSize < nOldSize )
+    {
+        memcpy( ((char*) poField->GetData()) + nPreBytes, 
+                pachRawData, nRawDataSize );
+        memmove( ((char *) poField->GetData()) + nPreBytes + nRawDataSize, 
+                 ((char *) poField->GetData()) + nPreBytes + nOldSize, 
+                 nPostBytes );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Resize the whole buffer.                                        */
+/* -------------------------------------------------------------------- */
+    if( !ResizeField( poField, 
+                      poField->GetDataSize() - nOldSize + nRawDataSize ) )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      If we growing the buffer, shuffle up the post data, and         */
+/*      move in our new values.                                         */
+/* -------------------------------------------------------------------- */
+    if( nRawDataSize >= nOldSize )
+    {
+        memmove( ((char *) poField->GetData()) + nPreBytes + nRawDataSize, 
+                 ((char *) poField->GetData()) + nPreBytes + nOldSize, 
+                 nPostBytes );
+        memcpy( ((char*) poField->GetData()) + nPreBytes, 
+                pachRawData, nRawDataSize );
+    }
+
+    return true;
+}
+
+/************************************************************************/
+/*                           ResetDirectory()                           */
+/*                                                                      */
+/*      Re-prepares the directory information for the record.           */
+/************************************************************************/
+
+int ossimDDFRecord::ResetDirectory()
+
+{
+    int iField;
+
+/* -------------------------------------------------------------------- */
+/*      Eventually we should try to optimize the size of offset and     */
+/*      field length.  For now we will use 5 for each which is          */
+/*      pretty big.                                                     */
+/* -------------------------------------------------------------------- */
+    _sizeFieldPos = 5;
+    _sizeFieldLength = 5;
+
+/* -------------------------------------------------------------------- */
+/*      Compute how large the directory needs to be.                    */
+/* -------------------------------------------------------------------- */
+    int nEntrySize, nDirSize;
+
+    nEntrySize = _sizeFieldPos + _sizeFieldLength + _sizeFieldTag;
+    nDirSize = nEntrySize * nFieldCount + 1;
+
+/* -------------------------------------------------------------------- */
+/*      If the directory size is different than what is currently       */
+/*      reserved for it, we must resize.                                */
+/* -------------------------------------------------------------------- */
+    if( nDirSize != nFieldOffset )
+    {
+        char *pachNewData;
+        int  nNewDataSize;
+
+        nNewDataSize = nDataSize - nFieldOffset + nDirSize;
+        pachNewData = (char *) malloc(nNewDataSize);
+        memcpy( pachNewData + nDirSize, 
+                pachData + nFieldOffset, 
+                nNewDataSize - nDirSize );
+     
+        for( iField = 0; iField < nFieldCount; iField++ )
+        {
+            int nOffset;
+            ossimDDFField *poField = GetField( iField );
+
+            nOffset = poField->GetData() - pachData - nFieldOffset + nDirSize;
+            poField->Initialize( poField->GetFieldDefn(), 
+                                 pachNewData + nOffset, 
+                                 poField->GetDataSize() );
+        }
+
+        free( pachData );
+        pachData = pachNewData;
+        nDataSize = nNewDataSize;
+        nFieldOffset = nDirSize;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Now set each directory entry.                                   */
+/* -------------------------------------------------------------------- */
+    for( iField = 0; iField < nFieldCount; iField++ )
+    {
+        ossimDDFField *poField = GetField( iField );
+        ossimDDFFieldDefn *poDefn = poField->GetFieldDefn();
+        char      szFormat[128];
+
+        sprintf( szFormat, "%%%ds%%0%dd%%0%dd", 
+                 _sizeFieldTag, _sizeFieldLength, _sizeFieldPos );
+
+        sprintf( pachData + nEntrySize * iField, szFormat, 
+                 poDefn->GetName(), poField->GetDataSize(),
+                 poField->GetData() - pachData - nFieldOffset );
+    }
+
+    pachData[nEntrySize * nFieldCount] = OSSIM_DDF_FIELD_TERMINATOR;
+        
+    return true;
+}
+
+/************************************************************************/
+/*                     CreateDefaultFieldInstance()                     */
+/************************************************************************/
+
+/**
+ * Initialize default instance.
+ *
+ * This method is normally only used internally by the AddField() method
+ * to initialize the new field instance with default subfield values.  It
+ * installs default data for one instance of the field in the record
+ * using the DDFFieldDefn::GetDefaultValue() method and 
+ * DDFRecord::SetFieldRaw(). 
+ *
+ * @param poField the field within the record to be assign a default 
+ * instance. 
+ * @param iIndexWithinField the instance to set (may not have been tested with
+ * values other than 0). 
+ *
+ * @return true on success or false on failure. 
+ */
+
+int ossimDDFRecord::CreateDefaultFieldInstance( ossimDDFField *poField, 
+                                           int iIndexWithinField )
+
+{
+    int nRawSize, nSuccess;
+    char *pachRawData;
+
+    pachRawData = poField->GetFieldDefn()->GetDefaultValue( &nRawSize );
+    if( pachRawData == NULL )
+        return false;
+
+    nSuccess = SetFieldRaw( poField, iIndexWithinField, pachRawData, nRawSize);
+
+    free( pachRawData );
+
+    return nSuccess;
+}
+
+/************************************************************************/
+/*                         SetStringSubfield()                          */
+/************************************************************************/
+
+/**
+ * Set a string subfield in record.
+ *
+ * The value of a given subfield is replaced with a new string value 
+ * formatted appropriately. 
+ *
+ * @param pszField the field name to operate on.
+ * @param iFieldIndex the field index to operate on (zero based).
+ * @param pszSubfield the subfield name to operate on. 
+ * @param iSubfieldIndex the subfield index to operate on (zero based). 
+ * @param pszValue the new string to place in the subfield.  This may be 
+ * arbitrary binary bytes if nValueLength is specified. 
+ * @param nValueLength the number of valid bytes in pszValue, may be -1 to 
+ * internally fetch with strlen(). 
+ * 
+ * @return true if successful, and false if not. 
+ */
+
+int ossimDDFRecord::SetStringSubfield( const char *pszField, int iFieldIndex, 
+                                  const char *pszSubfield, int iSubfieldIndex,
+                                  const char *pszValue, int nValueLength )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Fetch the field. If this fails, return zero.                    */
+/* -------------------------------------------------------------------- */
+    ossimDDFField *poField; 
+
+    poField = FindField( pszField, iFieldIndex );
+    if( poField == NULL )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      Get the subfield definition                                     */
+/* -------------------------------------------------------------------- */
+    ossimDDFSubfieldDefn     *poSFDefn;
+
+    poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield );
+    if( poSFDefn == NULL )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      How long will the formatted value be?                           */
+/* -------------------------------------------------------------------- */
+    int nFormattedLen;
+
+    if( !poSFDefn->FormatStringValue( NULL, 0, &nFormattedLen, pszValue,
+                                      nValueLength ) )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      Get a pointer to the data.                                      */
+/* -------------------------------------------------------------------- */
+    int         nMaxBytes;
+    char *pachSubfieldData = (char *) 
+        poField->GetSubfieldData(poSFDefn, &nMaxBytes,
+                                 iSubfieldIndex);
+
+/* -------------------------------------------------------------------- */
+/*      Add new instance if we have run out of data.                    */
+/* -------------------------------------------------------------------- */
+    if( nMaxBytes == 0 
+        || (nMaxBytes == 1 && pachSubfieldData[0] == OSSIM_DDF_FIELD_TERMINATOR) )
+    {
+        CreateDefaultFieldInstance( poField, iSubfieldIndex );
+
+        // Refetch.
+        pachSubfieldData = (char *) 
+            poField->GetSubfieldData(poSFDefn, &nMaxBytes,
+                                     iSubfieldIndex);
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If the new length matches the existing length, just overlay     */
+/*      and return.                                                     */
+/* -------------------------------------------------------------------- */
+    int nExistingLength;
+
+    poSFDefn->GetDataLength( pachSubfieldData, nMaxBytes, &nExistingLength );
+
+    if( nExistingLength == nFormattedLen )
+    {
+        return poSFDefn->FormatStringValue( pachSubfieldData, nFormattedLen,
+                                            NULL, pszValue, nValueLength );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      We will need to resize the raw data.                            */
+/* -------------------------------------------------------------------- */
+    const char *pachFieldInstData;
+    int         nInstanceSize, nStartOffset, nSuccess;
+    char *pachNewData;
+
+    pachFieldInstData = poField->GetInstanceData( iFieldIndex,
+                                                  &nInstanceSize );
+
+    nStartOffset = pachSubfieldData - pachFieldInstData;
+
+    pachNewData = (char *) malloc(nFormattedLen);
+    poSFDefn->FormatStringValue( pachNewData, nFormattedLen, NULL, 
+                                 pszValue, nValueLength );
+    
+    nSuccess = UpdateFieldRaw( poField, iFieldIndex,
+                               nStartOffset, nExistingLength, 
+                               pachNewData, nFormattedLen );
+
+    free( pachNewData );
+
+    return nSuccess;
+}
+
+/************************************************************************/
+/*                           SetIntSubfield()                           */
+/************************************************************************/
+
+/**
+ * Set an integer subfield in record.
+ *
+ * The value of a given subfield is replaced with a new integer value 
+ * formatted appropriately. 
+ *
+ * @param pszField the field name to operate on.
+ * @param iFieldIndex the field index to operate on (zero based).
+ * @param pszSubfield the subfield name to operate on. 
+ * @param iSubfieldIndex the subfield index to operate on (zero based). 
+ * @param nNewValue the new value to place in the subfield. 
+ * 
+ * @return true if successful, and false if not. 
+ */
+
+int ossimDDFRecord::SetIntSubfield( const char *pszField, int iFieldIndex, 
+                               const char *pszSubfield, int iSubfieldIndex,
+                               int nNewValue )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Fetch the field. If this fails, return zero.                    */
+/* -------------------------------------------------------------------- */
+    ossimDDFField *poField; 
+
+    poField = FindField( pszField, iFieldIndex );
+    if( poField == NULL )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      Get the subfield definition                                     */
+/* -------------------------------------------------------------------- */
+    ossimDDFSubfieldDefn     *poSFDefn;
+
+    poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield );
+    if( poSFDefn == NULL )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      How long will the formatted value be?                           */
+/* -------------------------------------------------------------------- */
+    int nFormattedLen;
+
+    if( !poSFDefn->FormatIntValue( NULL, 0, &nFormattedLen, nNewValue ) )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      Get a pointer to the data.                                      */
+/* -------------------------------------------------------------------- */
+    int         nMaxBytes;
+    char *pachSubfieldData = (char *) 
+        poField->GetSubfieldData(poSFDefn, &nMaxBytes,
+                                 iSubfieldIndex);
+
+/* -------------------------------------------------------------------- */
+/*      Add new instance if we have run out of data.                    */
+/* -------------------------------------------------------------------- */
+    if( nMaxBytes == 0 
+        || (nMaxBytes == 1 && pachSubfieldData[0] == OSSIM_DDF_FIELD_TERMINATOR) )
+    {
+        CreateDefaultFieldInstance( poField, iSubfieldIndex );
+
+        // Refetch.
+        pachSubfieldData = (char *) 
+            poField->GetSubfieldData(poSFDefn, &nMaxBytes,
+                                     iSubfieldIndex);
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If the new length matches the existing length, just overlay     */
+/*      and return.                                                     */
+/* -------------------------------------------------------------------- */
+    int nExistingLength;
+
+    poSFDefn->GetDataLength( pachSubfieldData, nMaxBytes, &nExistingLength );
+
+    if( nExistingLength == nFormattedLen )
+    {
+        return poSFDefn->FormatIntValue( pachSubfieldData, nFormattedLen,
+                                         NULL, nNewValue );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      We will need to resize the raw data.                            */
+/* -------------------------------------------------------------------- */
+    const char *pachFieldInstData;
+    int         nInstanceSize, nStartOffset, nSuccess;
+    char *pachNewData;
+
+    pachFieldInstData = poField->GetInstanceData( iFieldIndex,
+                                                  &nInstanceSize );
+
+    nStartOffset = pachSubfieldData - pachFieldInstData;
+
+    pachNewData = (char *) malloc(nFormattedLen);
+    poSFDefn->FormatIntValue( pachNewData, nFormattedLen, NULL, 
+                              nNewValue );
+    
+    nSuccess = UpdateFieldRaw( poField, iFieldIndex,
+                               nStartOffset, nExistingLength, 
+                               pachNewData, nFormattedLen );
+
+    free( pachNewData );
+
+    return nSuccess;
+}
+
+/************************************************************************/
+/*                          SetFloatSubfield()                          */
+/************************************************************************/
+
+/**
+ * Set a float subfield in record.
+ *
+ * The value of a given subfield is replaced with a new float value 
+ * formatted appropriately. 
+ *
+ * @param pszField the field name to operate on.
+ * @param iFieldIndex the field index to operate on (zero based).
+ * @param pszSubfield the subfield name to operate on. 
+ * @param iSubfieldIndex the subfield index to operate on (zero based). 
+ * @param dfNewValue the new value to place in the subfield. 
+ * 
+ * @return true if successful, and false if not. 
+ */
+
+int ossimDDFRecord::SetFloatSubfield( const char *pszField, int iFieldIndex, 
+                                 const char *pszSubfield, int iSubfieldIndex,
+                                 double dfNewValue )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Fetch the field. If this fails, return zero.                    */
+/* -------------------------------------------------------------------- */
+    ossimDDFField *poField; 
+
+    poField = FindField( pszField, iFieldIndex );
+    if( poField == NULL )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      Get the subfield definition                                     */
+/* -------------------------------------------------------------------- */
+    ossimDDFSubfieldDefn     *poSFDefn;
+
+    poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield );
+    if( poSFDefn == NULL )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      How long will the formatted value be?                           */
+/* -------------------------------------------------------------------- */
+    int nFormattedLen;
+
+    if( !poSFDefn->FormatFloatValue( NULL, 0, &nFormattedLen, dfNewValue ) )
+        return false;
+
+/* -------------------------------------------------------------------- */
+/*      Get a pointer to the data.                                      */
+/* -------------------------------------------------------------------- */
+    int         nMaxBytes;
+    char *pachSubfieldData = (char *) 
+        poField->GetSubfieldData(poSFDefn, &nMaxBytes,
+                                 iSubfieldIndex);
+
+/* -------------------------------------------------------------------- */
+/*      Add new instance if we have run out of data.                    */
+/* -------------------------------------------------------------------- */
+    if( nMaxBytes == 0 ||
+        (nMaxBytes == 1 && pachSubfieldData[0] == OSSIM_DDF_FIELD_TERMINATOR) )
+    {
+        CreateDefaultFieldInstance( poField, iSubfieldIndex );
+
+        // Refetch.
+        pachSubfieldData = (char *) 
+            poField->GetSubfieldData(poSFDefn, &nMaxBytes,
+                                     iSubfieldIndex);
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If the new length matches the existing length, just overlay     */
+/*      and return.                                                     */
+/* -------------------------------------------------------------------- */
+    int nExistingLength;
+
+    poSFDefn->GetDataLength( pachSubfieldData, nMaxBytes, &nExistingLength );
+
+    if( nExistingLength == nFormattedLen )
+    {
+        return poSFDefn->FormatFloatValue( pachSubfieldData, nFormattedLen,
+                                         NULL, dfNewValue );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      We will need to resize the raw data.                            */
+/* -------------------------------------------------------------------- */
+    const char *pachFieldInstData;
+    int         nInstanceSize, nStartOffset, nSuccess;
+    char *pachNewData;
+
+    pachFieldInstData = poField->GetInstanceData( iFieldIndex,
+                                                  &nInstanceSize );
+
+    nStartOffset = (int) (pachSubfieldData - pachFieldInstData);
+
+    pachNewData = (char *) malloc(nFormattedLen);
+    poSFDefn->FormatFloatValue( pachNewData, nFormattedLen, NULL, 
+                              dfNewValue );
+    
+    nSuccess = UpdateFieldRaw( poField, iFieldIndex,
+                               nStartOffset, nExistingLength, 
+                               pachNewData, nFormattedLen );
+
+    free( pachNewData );
+
+    return nSuccess;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfsubfielddefn.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfsubfielddefn.cpp
new file mode 100644
index 0000000000..179e4c45a4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfsubfielddefn.cpp
@@ -0,0 +1,950 @@
+/******************************************************************************
+ * Copied from "gdal" project. See licence below.
+ *
+ * Project:  ISO 8211 Access
+ * Purpose:  Implements the DDFSubfieldDefn class.
+ * Author:   Frank Warmerdam, warmerda@home.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * $Id: ossimDdfsubfielddefn.cpp,v 1.3 2005/10/17 18:42:27 gpotts Exp $
+ */
+
+#include <imaging/formats/adrg/ossimIso8211.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimCommon.h>
+
+/************************************************************************/
+/*                          DDFSubfieldDefn()                           */
+/************************************************************************/
+
+ossimDDFSubfieldDefn::ossimDDFSubfieldDefn()
+
+{
+    pszName = NULL;
+    
+    bIsVariable = true;
+    nFormatWidth = 0;
+    chFormatDelimeter = OSSIM_DDF_UNIT_TERMINATOR;
+    eBinaryFormat = NotBinary;
+    eType = DDFString;
+    
+    pszFormatString = strdup("");
+
+    nMaxBufChars = 0;
+    pachBuffer = NULL;
+}
+
+/************************************************************************/
+/*                          ~DDFSubfieldDefn()                          */
+/************************************************************************/
+
+ossimDDFSubfieldDefn::~ossimDDFSubfieldDefn()
+
+{
+    free( pszName );
+    free( pszFormatString );
+    free( pachBuffer );
+}
+
+/************************************************************************/
+/*                              SetName()                               */
+/************************************************************************/
+
+void ossimDDFSubfieldDefn::SetName( const char * pszNewName )
+
+{
+    int         i;
+    
+    free( pszName );
+
+    pszName = strdup( pszNewName );
+
+    for( i = strlen(pszName)-1; i > 0 && pszName[i] == ' '; i-- )
+        pszName[i] = '\0';
+}
+
+/************************************************************************/
+/*                             SetFormat()                              */
+/*                                                                      */
+/*      While interpreting the format string we don't support:          */
+/*                                                                      */
+/*       o Passing an explicit terminator for variable length field.    */
+/*       o 'X' for unused data ... this should really be filtered       */
+/*         out by DDFFieldDefn::ApplyFormats(), but isn't.              */
+/*       o 'B' bitstrings that aren't a multiple of eight.              */
+/************************************************************************/
+
+int ossimDDFSubfieldDefn::SetFormat( const char * pszFormat )
+
+{
+    free( pszFormatString );
+    pszFormatString = strdup( pszFormat );
+
+/* -------------------------------------------------------------------- */
+/*      These values will likely be used.                               */
+/* -------------------------------------------------------------------- */
+    if( pszFormatString[1] == '(' )
+    {
+        nFormatWidth = atoi(pszFormatString+2);
+        bIsVariable = nFormatWidth == 0;
+    }
+    else
+        bIsVariable = true;
+    
+/* -------------------------------------------------------------------- */
+/*      Interpret the format string.                                    */
+/* -------------------------------------------------------------------- */
+    switch( pszFormatString[0] )
+    {
+      case 'A':
+      case 'C':         // It isn't clear to me how this is different than 'A'
+        eType = DDFString;
+        break;
+
+      case 'R':
+        eType = DDFFloat;
+        break;
+        
+      case 'I':
+      case 'S':
+        eType = DDFInt;
+        break;
+
+      case 'B':
+      case 'b':
+        // Is the width expressed in bits? (is it a bitstring)
+        bIsVariable = false;
+        if( pszFormatString[1] == '(' )
+        {
+           // CPLAssert( atoi(pszFormatString+2) % 8 == 0 );
+            
+            nFormatWidth = atoi(pszFormatString+2) / 8;
+            eBinaryFormat = SInt; // good default, works for SDTS.
+
+            if( nFormatWidth < 5 )
+                eType = DDFInt;
+            else
+                eType = DDFBinaryString;
+        }
+        
+        // or do we have a binary type indicator? (is it binary)
+        else
+        {
+            eBinaryFormat = (DDFBinaryFormat) (pszFormatString[1] - '0');
+            nFormatWidth = atoi(pszFormatString+2);
+
+            if( eBinaryFormat == SInt || eBinaryFormat == UInt )
+                eType = DDFInt;
+            else
+                eType = DDFFloat;
+        }
+        break;
+
+      case 'X':
+        // 'X' is extra space, and shouldn't be directly assigned to a
+        // subfield ... I haven't encountered it in use yet though.
+        ossimNotify(ossimNotifyLevel_WARN)
+           << "Format type of `%c' not supported.\n"
+           << pszFormatString[0] << std::endl;
+        
+        // CPLAssert( false );
+        return false;
+        
+      default:
+        ossimNotify(ossimNotifyLevel_WARN)
+           << "Format type of `%c' not recognised.\n"
+           << pszFormatString[0] << std::endl;
+        
+        // CPLAssert( false );
+        return false;
+    }
+    
+    return true;
+}
+
+/************************************************************************/
+/*                                Dump()                                */
+/************************************************************************/
+
+/**
+ * Write out subfield definition info to debugging file.
+ *
+ * A variety of information about this field definition is written to the
+ * give debugging file handle.
+ *
+ * @param fp The standard io file handle to write to.  ie. stderr
+ */
+
+void ossimDDFSubfieldDefn::Dump( FILE * fp )
+
+{
+    fprintf( fp, "    DDFSubfieldDefn:\n" );
+    fprintf( fp, "        Label = `%s'\n", pszName );
+    fprintf( fp, "        FormatString = `%s'\n", pszFormatString );
+}
+
+/************************************************************************/
+/*                           GetDataLength()                            */
+/*                                                                      */
+/*      This method will scan for the end of a variable field.          */
+/************************************************************************/
+
+/**
+ * Scan for the end of variable length data.  Given a pointer to the data
+ * for this subfield (from within a DDFRecord) this method will return the
+ * number of bytes which are data for this subfield.  The number of bytes
+ * consumed as part of this field can also be fetched.  This number may
+ * be one longer than the length if there is a terminator character
+ * used.<p>
+ *
+ * This method is mainly for internal use, or for applications which
+ * want the raw binary data to interpret themselves.  Otherwise use one
+ * of ExtractStringData(), ExtractIntData() or ExtractFloatData().
+ *
+ * @param pachSourceData The pointer to the raw data for this field.  This
+ * may have come from DDFRecord::GetData(), taking into account skip factors
+ * over previous subfields data.
+ * @param nMaxBytes The maximum number of bytes that are accessable after
+ * pachSourceData.
+ * @param pnConsumedBytes Pointer to an integer into which the number of
+ * bytes consumed by this field should be written.  May be NULL to ignore.
+ *
+ * @return The number of bytes at pachSourceData which are actual data for
+ * this record (not including unit, or field terminator).  
+ */
+
+int ossimDDFSubfieldDefn::GetDataLength( const char * pachSourceData,
+                                    int nMaxBytes, int * pnConsumedBytes )
+
+{
+    if( !bIsVariable )
+    {
+        if( nFormatWidth > nMaxBytes )
+        {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Only %d bytes available for subfield %s with\n"
+               << "format string %s ... returning shortened data."
+               << nMaxBytes << pszName << pszFormatString << std::endl;
+
+            if( pnConsumedBytes != NULL )
+                *pnConsumedBytes = nMaxBytes;
+
+            return nMaxBytes;
+        }
+        else
+        {
+            if( pnConsumedBytes != NULL )
+                *pnConsumedBytes = nFormatWidth;
+
+            return nFormatWidth;
+        }
+    }
+    else
+    {
+        int     nLength = 0;
+        int     bCheckFieldTerminator = true;
+
+        /* We only check for the field terminator because of some buggy 
+         * datasets with missing format terminators.  However, we have found
+         * the field terminator is a legal character within the fields of
+         * some extended datasets (such as JP34NC94.000).  So we don't check
+         * for the field terminator if the field appears to be multi-byte
+         * which we established by the first character being out of the 
+         * ASCII printable range (32-127). 
+         */
+
+        if( pachSourceData[0] < 32 || pachSourceData[0] >= 127 )
+            bCheckFieldTerminator = false;
+        
+        while( nLength < nMaxBytes
+               && pachSourceData[nLength] != chFormatDelimeter )
+        {
+            if( bCheckFieldTerminator 
+                && pachSourceData[nLength] == OSSIM_DDF_FIELD_TERMINATOR )
+                break;
+
+            nLength++;
+        }
+
+        if( pnConsumedBytes != NULL )
+        {
+            if( nMaxBytes == 0 )
+                *pnConsumedBytes = nLength;
+            else
+                *pnConsumedBytes = nLength+1;
+        }
+        
+        return nLength;
+    }
+}
+
+/************************************************************************/
+/*                         ExtractStringData()                          */
+/************************************************************************/
+
+/**
+ * Extract a zero terminated string containing the data for this subfield.
+ * Given a pointer to the data
+ * for this subfield (from within a DDFRecord) this method will return the
+ * data for this subfield.  The number of bytes
+ * consumed as part of this field can also be fetched.  This number may
+ * be one longer than the string length if there is a terminator character
+ * used.<p>
+ *
+ * This function will return the raw binary data of a subfield for
+ * types other than DDFString, including data past zero chars.  This is
+ * the standard way of extracting DDFBinaryString subfields for instance.<p>
+ *
+ * @param pachSourceData The pointer to the raw data for this field.  This
+ * may have come from DDFRecord::GetData(), taking into account skip factors
+ * over previous subfields data.
+ * @param nMaxBytes The maximum number of bytes that are accessable after
+ * pachSourceData.
+ * @param pnConsumedBytes Pointer to an integer into which the number of
+ * bytes consumed by this field should be written.  May be NULL to ignore.
+ * This is used as a skip factor to increment pachSourceData to point to the
+ * next subfields data.
+ *
+ * @return A pointer to a buffer containing the data for this field.  The
+ * returned pointer is to an internal buffer which is invalidated on the
+ * next ExtractStringData() call on this DDFSubfieldDefn().  It should not
+ * be freed by the application.
+ *
+ * @see ExtractIntData(), ExtractFloatData()
+ */
+
+const char *
+ossimDDFSubfieldDefn::ExtractStringData( const char * pachSourceData,
+                                    int nMaxBytes, int * pnConsumedBytes )
+
+{
+    int         nLength = GetDataLength( pachSourceData, nMaxBytes,
+                                         pnConsumedBytes );
+
+/* -------------------------------------------------------------------- */
+/*      Do we need to grow the buffer.                                  */
+/* -------------------------------------------------------------------- */
+    if( nMaxBufChars < nLength+1 )
+    {
+        free( pachBuffer );
+        
+        nMaxBufChars = nLength+1;
+        pachBuffer = (char *) malloc(nMaxBufChars);
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Copy the data to the buffer.  We use memcpy() so that it        */
+/*      will work for binary data.                                      */
+/* -------------------------------------------------------------------- */
+    memcpy( pachBuffer, pachSourceData, nLength );
+    pachBuffer[nLength] = '\0';
+
+    return pachBuffer;
+}
+
+/************************************************************************/
+/*                          ExtractFloatData()                          */
+/************************************************************************/
+
+/**
+ * Extract a subfield value as a float.  Given a pointer to the data
+ * for this subfield (from within a DDFRecord) this method will return the
+ * floating point data for this subfield.  The number of bytes
+ * consumed as part of this field can also be fetched.  This method may be
+ * called for any type of subfield, and will return zero if the subfield is
+ * not numeric.
+ *
+ * @param pachSourceData The pointer to the raw data for this field.  This
+ * may have come from DDFRecord::GetData(), taking into account skip factors
+ * over previous subfields data.
+ * @param nMaxBytes The maximum number of bytes that are accessable after
+ * pachSourceData.
+ * @param pnConsumedBytes Pointer to an integer into which the number of
+ * bytes consumed by this field should be written.  May be NULL to ignore.
+ * This is used as a skip factor to increment pachSourceData to point to the
+ * next subfields data.
+ *
+ * @return The subfield's numeric value (or zero if it isn't numeric).
+ *
+ * @see ExtractIntData(), ExtractStringData()
+ */
+
+double
+ossimDDFSubfieldDefn::ExtractFloatData( const char * pachSourceData,
+                                   int nMaxBytes, int * pnConsumedBytes )
+
+{
+    switch( pszFormatString[0] )
+    {
+      case 'A':
+      case 'I':
+      case 'R':
+      case 'S':
+      case 'C':
+        return atof(ExtractStringData(pachSourceData, nMaxBytes,
+                                      pnConsumedBytes));
+
+      case 'B':
+      case 'b':
+      {
+          unsigned char   abyData[8];
+
+          // CPLAssert( nFormatWidth <= nMaxBytes );
+          if( pnConsumedBytes != NULL )
+              *pnConsumedBytes = nFormatWidth;
+
+          // Byte swap the data if it isn't in machine native format.
+          // In any event we copy it into our buffer to ensure it is
+          // word aligned.
+#ifdef CPL_LSB
+          if( pszFormatString[0] == 'B' )
+#else            
+              if( pszFormatString[0] == 'b' )
+#endif            
+              {
+                  for( int i = 0; i < nFormatWidth; i++ )
+                      abyData[nFormatWidth-i-1] = pachSourceData[i];
+              }
+              else
+              {
+                  memcpy( abyData, pachSourceData, nFormatWidth );
+              }
+
+          // Interpret the bytes of data.
+          switch( eBinaryFormat )
+          {
+            case UInt:
+              if( nFormatWidth == 1 )
+                  return( abyData[0] );
+              else if( nFormatWidth == 2 )
+                  return( *((ossim_uint16 *) abyData) );
+              else if( nFormatWidth == 4 )
+                  return( *((ossim_uint32 *) abyData) );
+              else
+              {
+                  // CPLAssert( false );
+                  return 0.0;
+              }
+            
+            case SInt:
+              if( nFormatWidth == 1 )
+                  return( *((signed char *) abyData) );
+              else if( nFormatWidth == 2 )
+                  return( *((ossim_int16 *) abyData) );
+              else if( nFormatWidth == 4 )
+                  return( *((ossim_int32 *) abyData) );
+              else
+              {
+                  // CPLAssert( false );
+                  return 0.0;
+              }
+            
+            case FloatReal:
+              if( nFormatWidth == 4 )
+                  return( *((float *) abyData) );
+              else if( nFormatWidth == 8 )
+                  return( *((double *) abyData) );
+              else
+              {
+                  // CPLAssert( false );
+                  return 0.0;
+              }
+
+            case NotBinary:            
+            case FPReal:
+            case FloatComplex:
+              // CPLAssert( false );
+              return 0.0;
+          }
+          break;
+          // end of 'b'/'B' case.
+      }
+
+      default:
+        // CPLAssert( false );
+        return 0.0;
+    }
+
+    // CPLAssert( false );
+    return 0.0;
+}
+
+/************************************************************************/
+/*                           ExtractIntData()                           */
+/************************************************************************/
+
+/**
+ * Extract a subfield value as an integer.  Given a pointer to the data
+ * for this subfield (from within a DDFRecord) this method will return the
+ * int data for this subfield.  The number of bytes
+ * consumed as part of this field can also be fetched.  This method may be
+ * called for any type of subfield, and will return zero if the subfield is
+ * not numeric.
+ *
+ * @param pachSourceData The pointer to the raw data for this field.  This
+ * may have come from DDFRecord::GetData(), taking into account skip factors
+ * over previous subfields data.
+ * @param nMaxBytes The maximum number of bytes that are accessable after
+ * pachSourceData.
+ * @param pnConsumedBytes Pointer to an integer into which the number of
+ * bytes consumed by this field should be written.  May be NULL to ignore.
+ * This is used as a skip factor to increment pachSourceData to point to the
+ * next subfields data.
+ *
+ * @return The subfield's numeric value (or zero if it isn't numeric).
+ *
+ * @see ExtractFloatData(), ExtractStringData()
+ */
+
+int
+ossimDDFSubfieldDefn::ExtractIntData( const char * pachSourceData,
+                                 int nMaxBytes, int * pnConsumedBytes )
+
+{
+    switch( pszFormatString[0] )
+    {
+      case 'A':
+      case 'I':
+      case 'R':
+      case 'S':
+      case 'C':
+        return atoi(ExtractStringData(pachSourceData, nMaxBytes,
+                                      pnConsumedBytes));
+
+      case 'B':
+      case 'b':
+      {
+          unsigned char   abyData[8];
+
+          if( nFormatWidth > nMaxBytes )
+          {
+              ossimNotify(ossimNotifyLevel_WARN)
+                 << "Attempt to extract int subfield %s with format %s\n"
+                 << "failed as only %d bytes available.  Using zero."
+                 << pszName << pszFormatString << nMaxBytes << std::endl;
+              return 0;
+          }
+
+          if( pnConsumedBytes != NULL )
+              *pnConsumedBytes = nFormatWidth;
+
+          // Byte swap the data if it isn't in machine native format.
+          // In any event we copy it into our buffer to ensure it is
+          // word aligned.
+#ifdef CPL_LSB
+          if( pszFormatString[0] == 'B' )
+#else            
+              if( pszFormatString[0] == 'b' )
+#endif            
+              {
+                  for( int i = 0; i < nFormatWidth; i++ )
+                      abyData[nFormatWidth-i-1] = pachSourceData[i];
+              }
+              else
+              {
+                  memcpy( abyData, pachSourceData, nFormatWidth );
+              }
+
+          // Interpret the bytes of data.
+          switch( eBinaryFormat )
+          {
+            case UInt:
+              if( nFormatWidth == 4 )
+                  return( (int) *((ossim_uint32 *) abyData) );
+              else if( nFormatWidth == 1 )
+                  return( abyData[0] );
+              else if( nFormatWidth == 2 )
+                  return( *((ossim_uint16 *) abyData) );
+              else
+              {
+                  // CPLAssert( false );
+                  return 0;
+              }
+            
+            case SInt:
+              if( nFormatWidth == 4 )
+                  return( *((ossim_int32 *) abyData) );
+              else if( nFormatWidth == 1 )
+                  return( *((signed char *) abyData) );
+              else if( nFormatWidth == 2 )
+                  return( *((ossim_int16 *) abyData) );
+              else
+              {
+                  // CPLAssert( false );
+                  return 0;
+              }
+            
+            case FloatReal:
+              if( nFormatWidth == 4 )
+                  return( (int) *((float *) abyData) );
+              else if( nFormatWidth == 8 )
+                  return( (int) *((double *) abyData) );
+              else
+              {
+                  // CPLAssert( false );
+                  return 0;
+              }
+
+            case NotBinary:            
+            case FPReal:
+            case FloatComplex:
+              // CPLAssert( false );
+              return 0;
+          }
+          break;
+          // end of 'b'/'B' case.
+      }
+
+      default:
+        // CPLAssert( false );
+        return 0;
+    }
+
+    // CPLAssert( false );
+    return 0;
+}
+
+/************************************************************************/
+/*                              DumpData()                              */
+/*                                                                      */
+/*      Dump the instance data for this subfield from a data            */
+/*      record.  This fits into the output dump stream of a DDFField.   */
+/************************************************************************/
+
+/**
+ * Dump subfield value to debugging file.
+ *
+ * @param pachData Pointer to data for this subfield.
+ * @param nMaxBytes Maximum number of bytes available in pachData.
+ * @param fp File to write report to.
+ */
+
+void ossimDDFSubfieldDefn::DumpData( const char * pachData, int nMaxBytes,
+                                FILE * fp )
+
+{
+    if( eType == DDFFloat )
+        fprintf( fp, "      Subfield `%s' = %f\n",
+                 pszName,
+                 ExtractFloatData( pachData, nMaxBytes, NULL ) );
+    else if( eType == DDFInt )
+        fprintf( fp, "      Subfield `%s' = %d\n",
+                 pszName,
+                 ExtractIntData( pachData, nMaxBytes, NULL ) );
+    else if( eType == DDFBinaryString )
+    {
+        int     nBytes, i;
+        ossim_uint8   *pabyBString = (ossim_uint8 *) ExtractStringData( pachData, nMaxBytes, &nBytes );
+
+        fprintf( fp, "      Subfield `%s' = 0x", pszName );
+        for( i = 0; i < MIN(nBytes,24); i++ )
+            fprintf( fp, "%02X", pabyBString[i] );
+
+        if( nBytes > 24 )
+            fprintf( fp, "%s", "..." );
+
+        fprintf( fp, "\n" );
+    }
+    else
+        fprintf( fp, "      Subfield `%s' = `%s'\n",
+                 pszName,
+                 ExtractStringData( pachData, nMaxBytes, NULL ) );
+}
+
+/************************************************************************/
+/*                          GetDefaultValue()                           */
+/************************************************************************/
+
+/**
+ * Get default data. 
+ *
+ * Returns the default subfield data contents for this subfield definition.
+ * For variable length numbers this will normally be "0<unit-terminator>". 
+ * For variable length strings it will be "<unit-terminator>".  For fixed
+ * length numbers it is zero filled.  For fixed length strings it is space
+ * filled.  For binary numbers it is binary zero filled. 
+ *
+ * @param pachData the buffer into which the returned default will be placed.
+ * May be NULL if just querying default size.
+ * @param nBytesAvailable the size of pachData in bytes. 
+ * @param pnBytesUsed will receive the size of the subfield default data in
+ * bytes.
+ *
+ * @return true on success or false on failure or if the passed buffer is too
+ * small to hold the default.
+ */
+
+int ossimDDFSubfieldDefn::GetDefaultValue( char *pachData, int nBytesAvailable, 
+                                      int *pnBytesUsed )
+
+{
+    int nDefaultSize;
+
+    if( !bIsVariable )
+        nDefaultSize = nFormatWidth;
+    else
+        nDefaultSize = 1;
+
+    if( pnBytesUsed != NULL )
+        *pnBytesUsed = nDefaultSize;
+
+    if( pachData == NULL )
+        return true;
+
+    if( nBytesAvailable < nDefaultSize )
+        return false;
+
+    if( bIsVariable )
+    {
+        pachData[0] = OSSIM_DDF_UNIT_TERMINATOR;
+    }
+    else
+    {
+        if( GetBinaryFormat() == NotBinary )
+        {
+            if( GetType() == DDFInt || GetType() == DDFFloat )
+                memset( pachData, '0', nDefaultSize );
+            else
+                memset( pachData, ' ', nDefaultSize );
+        }
+        else
+            memset( pachData, 0, nDefaultSize );
+    }
+
+    return true;
+}
+
+/************************************************************************/
+/*                         FormatStringValue()                          */
+/************************************************************************/
+
+/**
+ * Format string subfield value.
+ *
+ * Returns a buffer with the passed in string value reformatted in a way
+ * suitable for storage in a DDFField for this subfield.  
+ */
+
+int ossimDDFSubfieldDefn::FormatStringValue( char *pachData, int nBytesAvailable, 
+                                        int *pnBytesUsed, 
+                                        const char *pszValue,
+                                        int nValueLength )
+
+{
+    int nSize;
+
+    if( nValueLength == -1 )
+        nValueLength = strlen(pszValue);
+
+    if( bIsVariable )
+    {
+        nSize = nValueLength + 1;
+    }
+    else
+    {                                                                  
+        nSize = nFormatWidth;
+    }
+
+    if( pnBytesUsed != NULL )
+        *pnBytesUsed = nSize;
+
+    if( pachData == NULL )
+        return true;
+
+    if( nBytesAvailable < nSize )
+        return false;
+
+    if( bIsVariable )
+    {
+        strncpy( pachData, pszValue, nSize-1 );
+        pachData[nSize-1] = OSSIM_DDF_UNIT_TERMINATOR;
+    }
+    else
+    {
+        if( GetBinaryFormat() == NotBinary )
+        {
+            memset( pachData, ' ', nSize );
+            memcpy( pachData, pszValue, MIN(nValueLength,nSize) );
+        }
+        else
+        {
+            memset( pachData, 0, nSize );
+            memcpy( pachData, pszValue, MIN(nValueLength,nSize) );
+        }
+    }
+
+    return true;
+}
+
+/************************************************************************/
+/*                           FormatIntValue()                           */
+/************************************************************************/
+
+/**
+ * Format int subfield value.
+ *
+ * Returns a buffer with the passed in int value reformatted in a way
+ * suitable for storage in a DDFField for this subfield.  
+ */
+
+int ossimDDFSubfieldDefn::FormatIntValue( char *pachData, int nBytesAvailable, 
+                                     int *pnBytesUsed, int nNewValue )
+
+{
+    int nSize;
+    char szWork[30];
+
+    sprintf( szWork, "%d", nNewValue );
+
+    if( bIsVariable )
+    {
+        nSize = strlen(szWork) + 1;
+    }
+    else
+    {                                                                  
+        nSize = nFormatWidth;
+
+        if( GetBinaryFormat() == NotBinary && (int) strlen(szWork) > nSize )
+            return false;
+    }
+
+    if( pnBytesUsed != NULL )
+        *pnBytesUsed = nSize;
+
+    if( pachData == NULL )
+        return true;
+
+    if( nBytesAvailable < nSize )
+        return false;
+
+    if( bIsVariable )
+    {
+        strncpy( pachData, szWork, nSize-1 );
+        pachData[nSize-1] = OSSIM_DDF_UNIT_TERMINATOR;
+    }
+    else
+    {
+        ossim_uint32 nMask = 0xff;
+        int i;
+
+        switch( GetBinaryFormat() )
+        {
+          case NotBinary:
+            memset( pachData, '0', nSize );
+            strncpy( pachData + nSize - strlen(szWork), szWork,
+                     strlen(szWork) );
+            break;
+
+          case UInt:
+          case SInt:
+            for( i = 0; i < nFormatWidth; i++ )
+            {
+                int iOut;
+
+                // big endian required?
+                if( pszFormatString[0] == 'B' )
+                    iOut = nFormatWidth - i - 1;
+                else
+                    iOut = i;
+
+                pachData[iOut] = (nNewValue & nMask) >> (i*8);
+                nMask *= 256;
+            }
+            break;
+
+          case FloatReal:
+            // CPLAssert( false );
+            break;
+
+          default:
+            // CPLAssert( false );
+            break;
+        }
+    }
+
+    return true;
+}
+
+/************************************************************************/
+/*                          FormatFloatValue()                          */
+/************************************************************************/
+
+/**
+ * Format float subfield value.
+ *
+ * Returns a buffer with the passed in float value reformatted in a way
+ * suitable for storage in a DDFField for this subfield.  
+ */
+
+int ossimDDFSubfieldDefn::FormatFloatValue( char *pachData, int nBytesAvailable, 
+                                       int *pnBytesUsed, double dfNewValue )
+
+{
+    int nSize;
+    char szWork[120];
+
+    sprintf( szWork, "%.16g", dfNewValue );
+
+    if( bIsVariable )
+    {
+        nSize = strlen(szWork) + 1;
+    }
+    else
+    {
+        nSize = nFormatWidth;
+
+        if( GetBinaryFormat() == NotBinary && (int) strlen(szWork) > nSize )
+            return false;
+    }
+
+    if( pnBytesUsed != NULL )
+        *pnBytesUsed = nSize;
+
+    if( pachData == NULL )
+        return true;
+
+    if( nBytesAvailable < nSize )
+        return false;
+
+    if( bIsVariable )
+    {
+        strncpy( pachData, szWork, nSize-1 );
+        pachData[nSize-1] = OSSIM_DDF_UNIT_TERMINATOR;
+    }
+    else
+    {
+        if( GetBinaryFormat() == NotBinary )
+        {
+            memset( pachData, '0', nSize );
+            strncpy( pachData + nSize - strlen(szWork), szWork,
+                     strlen(szWork) );
+        }
+        else
+        {
+            // CPLAssert( false );
+            /* implement me */
+        }
+    }
+
+    return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfutils.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfutils.cpp
new file mode 100644
index 0000000000..f681a34cb4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimDdfutils.cpp
@@ -0,0 +1,101 @@
+/******************************************************************************
+ * Copied from "gdal" project. See licence below.
+ *
+ * Project:  ISO 8211 Access
+ * Purpose:  Various utility functions.
+ * Author:   Frank Warmerdam, warmerda@home.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * $Id: ossimDdfutils.cpp,v 1.2 2005/02/13 16:08:04 dburken Exp $
+ */
+
+#include <cstring>
+#include <imaging/formats/adrg/ossimIso8211.h>
+
+/************************************************************************/
+/*                             DDFScanInt()                             */
+/*                                                                      */
+/*      Read up to nMaxChars from the passed string, and interpret      */
+/*      as an integer.                                                  */
+/************************************************************************/
+
+long ossimDDFScanInt( const char * pszString, int nMaxChars )
+
+{
+    char        szWorking[33];
+
+    if( nMaxChars > 32 || nMaxChars == 0 )
+        nMaxChars = 32;
+
+    memcpy( szWorking, pszString, nMaxChars );
+    szWorking[nMaxChars] = '\0';
+
+    return( atoi(szWorking) );
+}
+
+/************************************************************************/
+/*                          DDFScanVariable()                           */
+/*                                                                      */
+/*      Establish the length of a variable length string in a           */
+/*      record.                                                         */
+/************************************************************************/
+
+int ossimDDFScanVariable( const char *pszRecord, int nMaxChars, int nDelimChar )
+
+{
+    int         i;
+    
+    for( i = 0; i < nMaxChars-1 && pszRecord[i] != nDelimChar; i++ ) {}
+
+    return i;
+}
+
+/************************************************************************/
+/*                          DDFFetchVariable()                          */
+/*                                                                      */
+/*      Fetch a variable length string from a record, and allocate      */
+/*      it as a new string (with CPLStrdup()).                          */
+/************************************************************************/
+
+char * ossimDDFFetchVariable( const char *pszRecord, int nMaxChars,
+                              int nDelimChar1, int nDelimChar2,
+                              int *pnConsumedChars )
+
+{
+    int         i;
+    char        *pszReturn;
+
+    for( i = 0; i < nMaxChars-1 && pszRecord[i] != nDelimChar1
+                                && pszRecord[i] != nDelimChar2; i++ ) {}
+
+    *pnConsumedChars = i;
+    if( i < nMaxChars
+        && (pszRecord[i] == nDelimChar1 || pszRecord[i] == nDelimChar2) )
+        (*pnConsumedChars)++;
+
+    pszReturn = (char *) malloc(i+1);
+    pszReturn[i] = '\0';
+    strncpy( pszReturn, pszRecord, i );
+
+    return pszReturn;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimIso8211.h b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimIso8211.h
new file mode 100644
index 0000000000..7714ebe270
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/adrg/ossimIso8211.h
@@ -0,0 +1,527 @@
+/******************************************************************************
+ * Copied from "gdal" project. See licence below.
+ *
+ * Project:  ISO 8211 Access
+ * Purpose:  Main declarations for ISO 8211.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam <warmerdam@pobox.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * $Id: ossimIso8211.h,v 1.2 2005/02/13 16:08:04 dburken Exp $
+ */
+
+#ifndef ossimIso8211_HEADER
+#define ossimIso8211_HEADER
+
+#include <cstdio>
+#include <cstdlib>
+
+
+/**
+  General data type
+    */
+typedef enum {
+    DDFInt,
+    DDFFloat,
+    DDFString,
+    DDFBinaryString
+} DDFDataType;
+  
+/************************************************************************/
+/*      These should really be private to the library ... they are      */
+/*      mostly conveniences.                                            */
+/************************************************************************/
+
+long ossimDDFScanInt( const char *pszString, int nMaxChars );
+int  ossimDDFScanVariable( const char * pszString,
+                           int nMaxChars, int nDelimChar );
+char *ossimDDFFetchVariable( const char *pszString, int nMaxChars,
+                             int nDelimChar1, int nDelimChar2,
+                             int *pnConsumedChars );
+
+#ifndef OSSIM_DDF_FIELD_TERMINATOR
+#  define OSSIM_DDF_FIELD_TERMINATOR    30
+#endif
+#ifndef OSSIM_DDF_UNIT_TERMINATOR
+#  define OSSIM_DDF_UNIT_TERMINATOR     31
+#endif
+
+/************************************************************************/
+/*                           Predeclarations                            */
+/************************************************************************/
+
+class ossimDDFFieldDefn;
+class ossimDDFSubfieldDefn;
+class ossimDDFRecord;
+class ossimDDFField;
+
+/************************************************************************/
+/*                              DDFModule                               */
+/************************************************************************/
+
+/**
+  The primary class for reading ISO 8211 files.  This class contains all
+  the information read from the DDR record, and is used to read records
+  from the file.           
+
+*/  
+
+class ossimDDFModule
+{
+  public:
+                ossimDDFModule();
+                ~ossimDDFModule();
+                
+    int         Open( const char * pszFilename, int bFailQuietly = false );
+    int         Create( const char *pszFilename );
+    void        Close();
+
+    int         Initialize( char chInterchangeLevel = '3',
+                            char chLeaderIden = 'L', 
+                            char chCodeExtensionIndicator = 'E',
+                            char chVersionNumber = '1',
+                            char chAppIndicator = ' ',
+                            const char *pszExtendedCharSet = " ! ",
+                            int nSizeFieldLength = 3,
+                            int nSizeFieldPos = 4,
+                            int nSizeFieldTag = 4 );
+
+    void        Dump( FILE * fp );
+
+    ossimDDFRecord   *ReadRecord( void );
+    void        Rewind( long nOffset = -1 );
+
+    ossimDDFFieldDefn *FindFieldDefn( const char * );
+
+    /** Fetch the number of defined fields. */
+
+    int         GetFieldCount() { return nFieldDefnCount; }
+    ossimDDFFieldDefn *GetField(int);
+    void        AddField( ossimDDFFieldDefn *poNewFDefn );
+    
+    // This is really just for internal use.
+    int         GetFieldControlLength() { return _fieldControlLength; }
+    void        AddCloneRecord( ossimDDFRecord * );
+    void        RemoveCloneRecord( ossimDDFRecord * );
+    
+    // This is just for DDFRecord.
+    FILE        *GetFP() { return fpDDF; }
+    
+  private:
+    FILE        *fpDDF;
+    int         bReadOnly;
+    long        nFirstRecordOffset;
+
+    char        _interchangeLevel;
+    char        _inlineCodeExtensionIndicator;
+    char        _versionNumber;
+    char        _appIndicator;
+    int         _fieldControlLength;
+    char        _extendedCharSet[4];
+
+    long _recLength;
+    char _leaderIden;
+    long _fieldAreaStart;
+    long _sizeFieldLength;
+    long _sizeFieldPos;
+    long _sizeFieldTag;
+
+    // One DirEntry per field.  
+    int         nFieldDefnCount;
+    ossimDDFFieldDefn **papoFieldDefns;
+
+    ossimDDFRecord   *poRecord;
+
+    int         nCloneCount;
+    int         nMaxCloneCount;
+    ossimDDFRecord   **papoClones;
+};
+
+/************************************************************************/
+/*                             DDFFieldDefn                             */
+/************************************************************************/
+
+  typedef enum { dsc_elementary, dsc_vector, dsc_array, dsc_concatenated } DDF_data_struct_code;
+  typedef enum { dtc_char_string, 
+                 dtc_implicit_point, 
+                 dtc_explicit_point, 
+                 dtc_explicit_point_scaled, 
+                 dtc_char_bit_string, 
+                 dtc_bit_string, 
+                 dtc_mixed_data_type } DDF_data_type_code;
+
+/**
+ * Information from the DDR defining one field.  Note that just because
+ * a field is defined for a DDFModule doesn't mean that it actually occurs
+ * on any records in the module.  DDFFieldDefns are normally just significant
+ * as containers of the DDFSubfieldDefns.
+ */
+
+class ossimDDFFieldDefn
+{
+  public:
+                ossimDDFFieldDefn();
+                ~ossimDDFFieldDefn();
+
+    int         Create( const char *pszTag, const char *pszFieldName,
+                        const char *pszDescription,
+                        DDF_data_struct_code eDataStructCode,
+                        DDF_data_type_code   eDataTypeCode,
+                        const char *pszFormat = NULL );
+    void        AddSubfield( ossimDDFSubfieldDefn *poNewSFDefn,
+                             int bDontAddToFormat = false );
+    void        AddSubfield( const char *pszName, const char *pszFormat );
+    int         GenerateDDREntry( char **ppachData, int *pnLength ); 
+                            
+    int         Initialize( ossimDDFModule * poModule, const char *pszTag,
+                            int nSize, const char * pachRecord );
+    
+    void        Dump( FILE * fp );
+
+    /** Fetch a pointer to the field name (tag).
+     * @return this is an internal copy and shouldn't be freed.
+     */
+    const char  *GetName() { return pszTag; }
+
+    /** Fetch a longer descriptio of this field.
+     * @return this is an internal copy and shouldn't be freed.
+     */
+    const char  *GetDescription() { return _fieldName; }
+
+    /** Get the number of subfields. */
+    int         GetSubfieldCount() { return nSubfieldCount; }
+    
+    ossimDDFSubfieldDefn *GetSubfield( int i );
+    ossimDDFSubfieldDefn *FindSubfieldDefn( const char * );
+
+    /**
+     * Get the width of this field.  This function isn't normally used
+     * by applications.
+     *
+     * @return The width of the field in bytes, or zero if the field is not
+     * apparently of a fixed width.
+     */
+    int         GetFixedWidth() { return nFixedWidth; }
+
+    /**
+     * Fetch repeating flag.
+     * @see DDFField::GetRepeatCount()
+     * @return TRUE if the field is marked as repeating.
+     */
+    int         IsRepeating() { return bRepeatingSubfields; }
+
+    static char       *ExpandFormat( const char * );
+
+    /** this is just for an S-57 hack for swedish data */
+    void SetRepeatingFlag( int n ) { bRepeatingSubfields = n; }
+
+    char        *GetDefaultValue( int *pnSize );
+    
+  private:
+
+    static char       *ExtractSubstring( const char * );
+
+    ossimDDFModule * poModule;
+    char *      pszTag;
+
+    char *      _fieldName;
+    char *      _arrayDescr;
+    char *      _formatControls;
+
+    int         bRepeatingSubfields;
+    int         nFixedWidth;    // zero if variable. 
+
+    int         BuildSubfields();
+    int         ApplyFormats();
+
+    DDF_data_struct_code _data_struct_code;
+
+    DDF_data_type_code   _data_type_code;
+
+    int         nSubfieldCount;
+    ossimDDFSubfieldDefn **papoSubfields;
+};
+
+/************************************************************************/
+/*                           DDFSubfieldDefn                            */
+/*                                                                      */
+/*      Information from the DDR record for one subfield of a           */
+/*      particular field.                                               */
+/************************************************************************/
+
+/**
+ * Information from the DDR record describing one subfield of a DDFFieldDefn.
+ * All subfields of a field will occur in each occurance of that field
+ * (as a DDFField) in a DDFRecord.  Subfield's actually contain formatted
+ * data (as instances within a record).
+ */
+
+class ossimDDFSubfieldDefn
+{
+public:
+
+                ossimDDFSubfieldDefn();
+                ~ossimDDFSubfieldDefn();
+
+    void        SetName( const char * pszName );
+
+    /** Get pointer to subfield name. */
+    const char  *GetName() { return pszName; }
+    
+    /** Get pointer to subfield format string */
+    const char  *GetFormat() { return pszFormatString; }
+    int         SetFormat( const char * pszFormat );
+
+    /**
+     * Get the general type of the subfield.  This can be used to
+     * determine which of ExtractFloatData(), ExtractIntData() or
+     * ExtractStringData() should be used.
+     * @return The subfield type.  One of DDFInt, DDFFloat, DDFString or
+     * DDFBinaryString.
+     */
+      
+    DDFDataType GetType() { return eType; }
+
+    double      ExtractFloatData( const char *pachData, int nMaxBytes,
+                                  int * pnConsumedBytes );
+    int         ExtractIntData( const char *pachData, int nMaxBytes,
+                                int * pnConsumedBytes );
+    const char  *ExtractStringData( const char *pachData, int nMaxBytes,
+                                    int * pnConsumedBytes );
+    int         GetDataLength( const char *, int, int * );
+    void        DumpData( const char *pachData, int nMaxBytes, FILE * fp );
+
+    int         FormatStringValue( char *pachData, int nBytesAvailable, 
+                                   int *pnBytesUsed, const char *pszValue, 
+                                   int nValueLength = -1 );
+
+    int         FormatIntValue( char *pachData, int nBytesAvailable, 
+                                int *pnBytesUsed, int nNewValue );
+
+    int         FormatFloatValue( char *pachData, int nBytesAvailable, 
+                                  int *pnBytesUsed, double dfNewValue );
+
+    /** Get the subfield width (zero for variable). */
+    int         GetWidth() { return nFormatWidth; } // zero for variable.
+
+    int         GetDefaultValue( char *pachData, int nBytesAvailable, 
+                                 int *pnBytesUsed );
+    
+    void        Dump( FILE * fp );
+
+/**
+  Binary format: this is the digit immediately following the B or b for
+  binary formats. 
+  */
+typedef enum {
+    NotBinary=0,
+    UInt=1,
+    SInt=2,
+    FPReal=3,
+    FloatReal=4,
+    FloatComplex=5
+} DDFBinaryFormat;
+
+    DDFBinaryFormat GetBinaryFormat(void) const { return eBinaryFormat; }
+    
+
+private:
+
+  char      *pszName;   // a.k.a. subfield mnemonic
+  char      *pszFormatString; 
+
+  DDFDataType           eType;
+  DDFBinaryFormat       eBinaryFormat;
+
+/* -------------------------------------------------------------------- */
+/*      bIsVariable determines whether we using the                     */
+/*      chFormatDelimeter (TRUE), or the fixed width (false).           */
+/* -------------------------------------------------------------------- */
+  int        bIsVariable;
+  
+  char       chFormatDelimeter;
+  int        nFormatWidth;
+
+/* -------------------------------------------------------------------- */
+/*      Fetched string cache.  This is where we hold the values         */
+/*      returned from ExtractStringData().                              */
+/* -------------------------------------------------------------------- */
+  int        nMaxBufChars;
+  char       *pachBuffer;
+};
+
+/************************************************************************/
+/*                              DDFRecord                               */
+/*                                                                      */
+/*      Class that contains one DR record from a file.  We read into    */
+/*      the same record object repeatedly to ensure that repeated       */
+/*      leaders can be easily preserved.                                */
+/************************************************************************/
+
+/**
+ * Contains instance data from one data record (DR).  The data is contained
+ * as a list of DDFField instances partitioning the raw data into fields.
+ */
+
+class ossimDDFRecord
+{
+  public:
+                ossimDDFRecord( ossimDDFModule * );
+                ~ossimDDFRecord();
+
+    ossimDDFRecord  *Clone();
+    ossimDDFRecord  *CloneOn( ossimDDFModule * );
+    
+    void        Dump( FILE * );
+
+    /** Get the number of DDFFields on this record. */
+    int         GetFieldCount() { return nFieldCount; }
+
+    ossimDDFField    *FindField( const char *, int = 0 );
+    ossimDDFField    *GetField( int );
+
+    int         GetIntSubfield( const char *, int, const char *, int,
+                                int * = NULL );
+    double      GetFloatSubfield( const char *, int, const char *, int,
+                                  int * = NULL );
+    const char *GetStringSubfield( const char *, int, const char *, int,
+                                   int * = NULL );
+
+    int         SetIntSubfield( const char *pszField, int iFieldIndex, 
+                                const char *pszSubfield, int iSubfieldIndex,
+                                int nValue );
+    int         SetStringSubfield( const char *pszField, int iFieldIndex, 
+                                   const char *pszSubfield, int iSubfieldIndex,
+                                   const char *pszValue, int nValueLength=-1 );
+    int         SetFloatSubfield( const char *pszField, int iFieldIndex, 
+                                  const char *pszSubfield, int iSubfieldIndex,
+                                  double dfNewValue );
+
+    /** Fetch size of records raw data (GetData()) in bytes. */
+    int         GetDataSize() { return nDataSize; }
+
+    /**
+     * Fetch the raw data for this record.  The returned pointer is effectively
+     * to the data for the first field of the record, and is of size 
+     * GetDataSize().
+     */
+    const char  *GetData() { return pachData; }
+
+    /**
+     * Fetch the DDFModule with which this record is associated.
+     */
+
+    ossimDDFModule * GetModule() { return poModule; }
+
+    int ResizeField( ossimDDFField *poField, int nNewDataSize );
+    int DeleteField( ossimDDFField *poField );
+    ossimDDFField* AddField( ossimDDFFieldDefn * );
+
+    int CreateDefaultFieldInstance( ossimDDFField *poField, int iIndexWithinField );
+
+    int SetFieldRaw( ossimDDFField *poField, int iIndexWithinField, 
+                     const char *pachRawData, int nRawDataSize );
+    int UpdateFieldRaw( ossimDDFField *poField, int iIndexWithinField, 
+                        int nStartOffset, int nOldSize,
+                        const char *pachRawData, int nRawDataSize );
+
+    int         Write();
+    
+    // This is really just for the DDFModule class.
+    int         Read();
+    void        Clear();
+    int         ResetDirectory();
+    
+  private:
+
+    int         ReadHeader();
+    
+    ossimDDFModule   *poModule;
+
+    int         nReuseHeader;   
+
+    int         nFieldOffset;   // field data area, not dir entries.
+
+    int         _sizeFieldTag;
+    int         _sizeFieldPos;
+    int         _sizeFieldLength;
+
+    int         nDataSize;      // Whole record except leader with header
+    char        *pachData;
+
+    int         nFieldCount;
+    ossimDDFField    *paoFields;
+
+    int         bIsClone;
+};
+
+/************************************************************************/
+/*                               DDFField                               */
+/*                                                                      */
+/*      This object represents one field in a DDFRecord.                */
+/************************************************************************/
+
+/**
+ * This object represents one field in a DDFRecord.  This
+ * models an instance of the fields data, rather than it's data definition
+ * which is handled by the DDFFieldDefn class.  Note that a DDFField
+ * doesn't have DDFSubfield children as you would expect.  To extract
+ * subfield values use GetSubfieldData() to find the right data pointer and
+ * then use ExtractIntData(), ExtractFloatData() or ExtractStringData().
+ */
+
+class ossimDDFField
+{
+  public:
+    void                Initialize( ossimDDFFieldDefn *, const char *pszData,
+                                    int nSize );
+
+    void                Dump( FILE * fp );
+
+    const char         *GetSubfieldData( ossimDDFSubfieldDefn *,
+                                         int * = NULL, int = 0 );
+
+    const char         *GetInstanceData( int nInstance, int *pnSize );
+
+    /**
+     * Return the pointer to the entire data block for this record. This
+     * is an internal copy, and shouldn't be freed by the application.
+     */
+    const char         *GetData() { return pachData; }
+
+    /** Return the number of bytes in the data block returned by GetData(). */
+    int                 GetDataSize() { return nDataSize; }
+
+    int                 GetRepeatCount();
+
+    /** Fetch the corresponding DDFFieldDefn. */
+    ossimDDFFieldDefn        *GetFieldDefn() { return poDefn; }
+    
+  private:
+    ossimDDFFieldDefn        *poDefn;
+
+    int                 nDataSize;
+
+    const char          *pachData;
+};
+
+#endif /* ifndef ossimIso8211_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/aigrid/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/aigrid/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/aigrid/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/aigrid/ossimArcInfoGridWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/aigrid/ossimArcInfoGridWriter.cpp
new file mode 100644
index 0000000000..4a85ed9ae5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/aigrid/ossimArcInfoGridWriter.cpp
@@ -0,0 +1,367 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimArcInfoGridWriter.cpp,v 1.8 2006/01/06 16:46:46 dburken Exp $
+
+#include <cstring>
+#include <cstdio>
+#include <fstream>
+#include <iostream>
+
+#include <imaging/formats/aigrid/ossimArcInfoGridWriter.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/misc/ossimEndian.h>
+#include <base/data_types/ossimDpt.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSource.h>
+#include <imaging/tile_sources/ossimCastTileSourceFilter.h>
+
+#include <support_data/esri/ossimAigStatistics.h>
+#include <support_data/esri/ossimAigHeader.h>
+#include <support_data/esri/ossimAigBounds.h>
+#include <support_data/esri/ossimAigIndexFileHeader.h>
+#include <support_data/esri/ossimAigDataFileHeader.h>
+
+#include <imaging/tile_sources/ossimCastTileSourceFilter.h>
+
+static const ossimTrace traceDebug("ossimArcInfoGridWriter:debug");
+
+RTTI_DEF1(ossimArcInfoGridWriter,
+          "ossimArcInfoGridWriter",
+          ossimImageFileWriter);
+
+//*******************************************************************
+// Constructor:
+//*******************************************************************
+ossimArcInfoGridWriter::ossimArcInfoGridWriter()
+   : ossimImageFileWriter(),
+     theOutputTileSize(256, 4)
+{
+}
+
+ossimArcInfoGridWriter::ossimArcInfoGridWriter(ossimImageSource* inputSource,
+                                 const ossimFilename& filename)
+   :ossimImageFileWriter(filename, inputSource)
+{
+}
+
+//*******************************************************************
+// Destructor
+//*******************************************************************
+ossimArcInfoGridWriter::~ossimArcInfoGridWriter()
+{
+   close();
+}
+
+bool ossimArcInfoGridWriter::writeFile()
+{
+   const char* MODULE = "ossimArcInfoGridWriter::writeFile";
+   
+   ossimCastTileSourceFilter* filter = new ossimCastTileSourceFilter;
+   filter->setOutputScalarType(OSSIM_FLOAT);
+   filter->connectMyInputTo(theInputConnection);
+   filter->initialize();
+   
+   if(!theInputConnection)
+   {
+      delete filter;
+      
+      return false;
+   }
+   open();
+
+   // make sure we have a region of interest
+   if(theAreaOfInterest.hasNans())
+   {
+      theInputConnection->initialize();
+      theAreaOfInterest = theInputConnection->getAreaOfInterest();
+   }
+   else
+   {
+      theInputConnection->setAreaOfInterest(theAreaOfInterest);
+   }
+   
+   if(theAreaOfInterest.hasNans()) return false;   
+   
+   theInputConnection->setTileSize(theOutputTileSize);
+   theInputConnection->setToStartOfSequence();
+   
+   bool result = writeBinaryAigHeader()&&
+                 writeBinaryAigBounds()&&
+                 writeBinaryAigStats();
+   if(result)
+   {
+      ossimFilename indexFile=ossimFilename(theFilename+"/"+"w001001x.adf");
+      ossimFilename dataFile=ossimFilename(theFilename+"/"+"w001001.adf");
+      
+      std::ofstream indexFileStream(indexFile.c_str(),
+                               ios::out|ios::binary);
+      std::ofstream dataFileStream(dataFile.c_str(),
+                              ios::out|ios::binary);
+      ossimEndian endian;
+
+      if(indexFileStream&&dataFileStream)
+      {
+         ossimAigIndexFileHeader aigIndexHeader;
+         ossimAigDataFileHeader  aigDataFileHeader;
+         
+         ossimRefPtr<ossimImageData> currentTile =
+            theInputConnection->getNextTile();
+         long tileNumber = 0;
+         long totalNumberOfTiles = theInputConnection->getNumberOfTiles();
+         ossim_int32 tileOffsetShorts = 0;
+         ossim_int32 tileSizeShorts   = 0;
+
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "Tile height  = " << theInputConnection->getTileHeight()
+            << std::endl
+            << "Tile width   = " << theInputConnection->getTileWidth()
+            << std::endl;
+         ossim_int32 tileSizeInShorts = 2*(theInputConnection->getTileHeight()*
+                                           theInputConnection->getTileWidth());
+         // Note: this is in shorts
+         //
+         aigIndexHeader.theFileSize += (4*totalNumberOfTiles);
+
+         // Note this is in shorts
+         //
+         
+         aigDataFileHeader.theFileSize = 50+
+                                         (tileSizeInShorts*totalNumberOfTiles) +
+                                         totalNumberOfTiles;
+         aigDataFileHeader.theTileSize = tileSizeInShorts;
+         
+         aigIndexHeader.writeStream(indexFileStream);
+         aigDataFileHeader.writeStream(dataFileStream);
+
+         if(traceDebug())
+         {
+            CLOG << "AIG INDEX HEADER = \n" << aigIndexHeader << std::endl;
+            CLOG << "AIG DATA FILE HEADER\n"
+                 << "file size = " << aigDataFileHeader.theFileSize
+                 << std::endl;
+         }
+         
+         while(currentTile.valid())
+         {
+            currentTile = filter->applyCast(currentTile);
+            
+            if(!currentTile->getBuf())
+            {
+               currentTile->initialize();
+            }
+
+            tileOffsetShorts = dataFileStream.tellp()/2;
+            tileSizeShorts   = 2*currentTile->getHeight()*currentTile->getWidth();
+            ossim_int16 tileSizeShorts16 = 2*currentTile->getHeight()*currentTile->getWidth();
+            if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+            {
+               endian.swap(tileOffsetShorts);
+               endian.swap(tileSizeShorts);
+               endian.swap(tileSizeShorts16);
+               endian.swap((ossim_float32*)currentTile->getBuf(),
+                           currentTile->getWidth()*
+                           currentTile->getHeight());
+            }
+            
+            indexFileStream.write((char*)(&tileOffsetShorts), 4);
+            indexFileStream.write((char*)(&tileSizeShorts), 4);
+            dataFileStream.write((char*)(&tileSizeShorts16),
+                                 2);
+            dataFileStream.write((char*)(currentTile->getBuf()),
+                                 currentTile->getWidth()*currentTile->getHeight()*4);
+            
+            currentTile = theInputConnection->getNextTile();
+            ++tileNumber;
+         }
+      }
+   }
+   
+   close();
+   delete filter;
+   return result;
+}
+
+bool ossimArcInfoGridWriter::saveState(ossimKeywordlist& kwl,
+                                const char* prefix)const
+{
+   return ossimImageFileWriter::saveState(kwl, prefix);
+}
+
+bool ossimArcInfoGridWriter::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   
+   return ossimImageFileWriter::loadState(kwl, prefix);
+}
+
+bool ossimArcInfoGridWriter::isOpen()const
+{
+   return (theFilename.isDir() && theFilename.exists());
+}
+
+bool ossimArcInfoGridWriter::open()
+{
+   if(theFilename.isDir()&&
+      theFilename.exists())
+   {
+      return true;
+   }
+   else
+   {
+      theFilename = theFilename.path();
+      if(theFilename.isDir()&&
+         theFilename.exists())
+      {
+         return true;
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimArcInfoGridWriter::open(): Directory "
+            << theFilename << " doesn't exist" << std::endl;
+      }
+      
+   }
+   return false;   
+}
+
+void ossimArcInfoGridWriter::close()
+{
+}
+
+
+bool ossimArcInfoGridWriter::writeBinaryAigHeader()
+{
+   const char* MODULE = "ossimArcInfoGridWriter::writeBinaryAigHeader";
+   ossimAigHeader aigHeader;
+
+   ossimFilename file=ossimFilename(theFilename+"/"+"hdr.adf");
+
+   if(isOpen())
+   {
+      switch(theInputConnection->getOutputScalarType())
+      {
+         case OSSIM_UCHAR:
+         case OSSIM_SSHORT16:
+         case OSSIM_USHORT11:
+         case OSSIM_USHORT16:
+//      {
+//         aigHeader.setIntCoverage();
+//         break;
+//      }
+         case OSSIM_DOUBLE:
+         case OSSIM_FLOAT:
+         case OSSIM_NORMALIZED_FLOAT:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            aigHeader.setFloatCoverage();
+            break;
+         }
+         default:
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "ossimArcInfoGridWriter::writeBinaryAigHeader: "
+               << "unkown scalar type" << std::endl;
+         }
+      }
+      
+      // need to set pixel size
+      //
+
+      // code goes here
+      
+      // now setting number of tiles per row
+      aigHeader.theNumberOfTilesPerRow    = theInputConnection->getNumberOfTilesHorizontal();
+      aigHeader.theNumberOfTilesPerColumn = theInputConnection->getNumberOfTilesVertical();
+      aigHeader.theWidthOfTileInPixels    = theInputConnection->getTileWidth();
+      aigHeader.theHeightOfTileInPixels   = theInputConnection->getTileHeight();
+      
+      std::ofstream out;
+      out.open(file.c_str(), ios::out|ios::binary);
+
+      if(out)
+      {
+         if(traceDebug())
+         {
+            CLOG << "AIG_HEADER = \n" << aigHeader << std::endl;
+         }
+         return aigHeader.writeStream(out);
+      }
+   }
+   
+   return false;
+}
+
+bool ossimArcInfoGridWriter::writeBinaryAigBounds()
+{
+   const char* MODULE = "ossimArcInfoGridWriter::writeBinaryAigBounds";
+   ossimAigBounds aigBounds;
+   
+
+   // setup bounds
+   ossimIrect bounds = theInputConnection->getBoundingRect();
+   if(!bounds.hasNans())
+   {
+      aigBounds.ll_x = -.5;
+      aigBounds.ll_y = -.5;
+      aigBounds.ur_x = bounds.width()-.5;
+      aigBounds.ur_y = bounds.height()-.5;
+      
+      //
+      ossimFilename file=ossimFilename(theFilename+"/"+"dblbnd.adf");
+      
+      if(isOpen())
+      {
+         std::ofstream out;
+         out.open(file.c_str(), ios::out|ios::binary);
+         
+         if(out)
+         {
+            if(traceDebug())
+            {
+               CLOG << "AIG BOUNDS =\n" <<aigBounds << std::endl;
+            }
+            return aigBounds.writeStream(out);
+         }
+      }
+   }
+   
+   return false;
+}
+
+bool ossimArcInfoGridWriter::writeBinaryAigStats()
+{
+   ossimAigStatistics aigStats;
+
+
+   // setup bounds
+   aigStats.theMin  = theInputConnection->getMinPixelValue();
+   aigStats.theMax  = theInputConnection->getMaxPixelValue();
+   aigStats.theMean = (aigStats.theMax-aigStats.theMin)/2.0;
+
+   //
+   ossimFilename file=ossimFilename(theFilename+"/"+"sta.adf");
+
+   if(isOpen())
+   {
+      std::ofstream out;
+      out.open(file.c_str(), ios::out|ios::binary);
+      
+      if(out)
+      {
+         return aigStats.writeStream(out);
+      }
+   }
+
+   return false;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/aigrid/ossimArcInfoGridWriter.h b/Utilities/OSSIM/ossim_core/imaging/formats/aigrid/ossimArcInfoGridWriter.h
new file mode 100644
index 0000000000..7fd5feec87
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/aigrid/ossimArcInfoGridWriter.h
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimArcInfoGridWriter.h,v 1.5 2006/01/06 16:46:46 dburken Exp $
+#ifndef ossimArcInfoGridWriter_HEADER
+#define ossimArcInfoGridWriter_HEADER
+
+#include <imaging/formats/ossimImageFileWriter.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+//*******************************************************************
+// CLASS:  ossimArdcInfoGridWriterFactory
+//*******************************************************************
+
+class OSSIM_DLL ossimArcInfoGridWriter : public ossimImageFileWriter
+{
+public:
+   ossimArcInfoGridWriter();
+   virtual              ~ossimArcInfoGridWriter();
+   
+   ossimArcInfoGridWriter(ossimImageSource *inputSource,
+                          const ossimFilename& filename);
+   virtual bool isOpen()const;
+   
+   virtual bool open();
+   virtual void close();
+
+   /*!
+    * saves the state of the object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+   virtual bool writeFile();
+
+   virtual bool writeBinaryAigHeader();
+   virtual bool writeBinaryAigBounds();
+   virtual bool writeBinaryAigStats();
+   
+   ossimIpt theOutputTileSize;
+   
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ccf/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfHead.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfHead.cpp
new file mode 100644
index 0000000000..e28177ce9a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfHead.cpp
@@ -0,0 +1,767 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for CcfHead.
+// 
+//*******************************************************************
+//  $Id: ossimCcfHead.cpp,v 1.12 2005/05/09 12:39:38 dburken Exp $
+
+#include <sstream>
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+#include "ossimCcfHead.h"
+#include "base/data_types/ossimIrect.h"
+#include "base/misc/lookup_tables/ossimScalarTypeLut.h"
+#include "base/common/ossimErrorCodes.h"
+#include "base/context/ossimErrorContext.h"
+
+static const bool TRACE = false; // Temp until trace code implemented.
+
+ossimCcfHead::ossimCcfHead()
+   :
+      theCcfFile(),
+      theNumberOfBands(1),
+      thePixelType(OSSIM_UCHAR),
+      theFileType(),
+      theVersionNumber(0),
+      theLinesPerChip(0),
+      theSamplesPerChip(0),
+      theLineChipsPerChunk(0),
+      theSampleChipsPerChunk(0),
+      theRectInFullImageStartLine(0),
+      theRectInFuleImageStartSample(0),
+      theRectInFullImageStopLine(0),
+      theRectInFuleImageStopSample(0),
+      theNumberOfValidImageVertices(0),
+      theValidImageVertices(1),
+      theFirstBandHeaderPointer(0),
+      theRadiometryString(),
+      theBytesPerPixel(0),
+      theBytesPerChip(0),
+      theBytesPerChunk(0),
+      theCompressionType(),
+      theNumberOfRLevels(0),
+      theOccupiedFlag(1),
+      theStartOfData(1),
+      theNumberOfLines(1),
+      theNumberOfSamples(1),
+      theChunksInLineDir(1),
+      theChunksInSampleDir(1)
+{}
+
+//***************************************************************************
+// Public Constructor:
+//***************************************************************************
+ossimCcfHead::ossimCcfHead(const char* ccf_file)
+   :
+      theCcfFile(ccf_file),
+      theNumberOfBands(1),
+      thePixelType(OSSIM_UCHAR),
+      theFileType(),
+      theVersionNumber(0),
+      theLinesPerChip(0),
+      theSamplesPerChip(0),
+      theLineChipsPerChunk(0),
+      theSampleChipsPerChunk(0),
+      theRectInFullImageStartLine(0),
+      theRectInFuleImageStartSample(0),
+      theRectInFullImageStopLine(0),
+      theRectInFuleImageStopSample(0),
+      theNumberOfValidImageVertices(0),
+      theValidImageVertices(1),
+      theFirstBandHeaderPointer(0),
+      theRadiometryString(""),
+      theBytesPerPixel(0),
+      theBytesPerChip(0),
+      theBytesPerChunk(0),
+      theCompressionType(),
+      theNumberOfRLevels(0),
+      theOccupiedFlag(1),
+      theStartOfData(1),
+      theNumberOfLines(1),
+      theNumberOfSamples(1),
+      theChunksInLineDir(1),
+      theChunksInSampleDir(1)
+{
+   static const char MODULE[] = "ossimCcfHead::ossimCcfHead";
+   
+   if (!parseCcfHeader(ccf_file))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      
+      if (TRACE)
+      {
+         cerr << MODULE << " ERROR!"
+              << "\nError initializing from ccf_file:  " << ccf_file
+              << "\nReturning..." << endl;
+      }
+   }
+}
+
+//***************************************************************************
+// Destructor:
+//***************************************************************************
+ossimCcfHead::~ossimCcfHead()
+{}
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+bool ossimCcfHead::parseCcfHeader(const char* ccf_file)
+{
+   static const char MODULE[] = "ossimCcfHead::parseossimCcfHeader";
+
+   theCcfFile = ccf_file;
+   
+   ifstream *is = new ifstream(ccf_file);
+
+   if (!(*is))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      
+      if (TRACE)
+      {
+         cerr << MODULE << " ERROR!"
+              << "\nCannot open file:  " << ccf_file << endl;
+      }
+      
+      is->close();
+      delete is;
+      
+      return false;
+   }
+
+   const ossim_uint32 MAX_LEN = 256;
+   char tmp[MAX_LEN];
+
+   // Check the first string should be "CCF" else get out...
+   // this might hang so I changed it to not use the
+   // >> operator unless it is a ccf file.  If it is another
+   // file we might not be guranteed a whitespace or \n character
+   // will exist and therefore the entrie file could have
+   // been read in.
+   //
+   char type[4];
+   is->read(type, 3);
+   type[3] = '\0';
+   theFileType = type;
+   if (theFileType != "CCF")
+   {
+      if (TRACE)
+      {
+         cerr << MODULE << " ERROR!"
+              << "\nNot a ccf file.  Returning..." << endl;
+      }
+
+      is->close();
+      delete is;
+
+      return false;
+   }
+
+   
+   // Check the version number.
+   (*is) >> tmp 
+         >> theVersionNumber;
+
+   //***
+   // Call the appropriate method for the version.  Currently only version 6
+   // supported as that was all I had in-house.  Feel free to add your own
+   // version reader!
+   //***
+   bool status = false;
+   
+   switch(theVersionNumber)
+   {
+   case 5:
+      status = parseV5CcfHeader(*is);
+      break;
+   case 6:
+      status = parseV6CcfHeader(*is);
+      break;
+   default:
+      // Version type not supported...
+      if (TRACE)
+      {
+         cerr << MODULE << " ERROR!"
+              << "\nUsupported version:  " << theVersionNumber
+              << "  Returning..." << endl;
+      }
+      is->close();
+      delete is;
+      status = false;
+
+      break;
+   }
+   
+   // Close the stream.
+   is->close();
+   delete is;
+   //***
+   // Parse the radiometry string.  This will initialize "theNumberOfBands"
+   // and the pixel type.
+   //***
+   parseRadString();
+
+   return status;
+}
+
+//***************************************************************************
+// Private Method:
+//***************************************************************************
+bool ossimCcfHead::parseV5CcfHeader(istream& is)
+{
+   static const char MODULE[] = "CcfHead::parseV5CcfHeader";
+
+   // Check the stream.
+   if (!is)
+   {
+      if (TRACE)
+      {
+         cerr << MODULE << " Bad Stream passed to method!"
+              << "\nReturning..."
+              << endl;
+      }
+
+      return false;
+   }
+
+   const ossim_uint32 MAX_LEN = 256;
+   char tmp[MAX_LEN];
+   
+   //***
+   // These are all fixed/not used so just skip...
+   //***
+   is.read(tmp, 1);                   // eat the '\n'
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "ccf_maker"
+
+   is >> tmp // "LinesPerChip"
+      >> theLinesPerChip
+      >> tmp // "SamplesPerChip"
+      >> theSamplesPerChip
+      >> tmp // "LineChipsPerChunk"
+      >> theLineChipsPerChunk
+      >> tmp // "SampleChipsPerChunk"   
+      >> theSampleChipsPerChunk;
+
+   is.read(tmp, 1);                   // eat the '\n'
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "NumberOfBands"
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "RectInFullImageSpace"
+
+   is >> tmp // skip "StartLine"
+      >> theRectInFullImageStartLine
+      >> tmp // skip "StartSample"
+      >> theRectInFuleImageStartSample
+      >> tmp // skip "StopLine"
+      >> theRectInFullImageStopLine
+      >> tmp // skip "StopSample"
+      >> theRectInFuleImageStopSample;
+
+   // No valid image vertices in this version.
+   theNumberOfValidImageVertices = 0;
+   theValidImageVertices[0] = ossimIpt(0,0);
+   
+   is.read(tmp, 1);                   // eat the '\n'
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip blank line
+
+   is >> tmp                         // skip "FirstBandHeaderPointer"
+      >> theFirstBandHeaderPointer;  // Offset to band header.
+
+   // Seek to the band header record.
+   is.seekg(theFirstBandHeaderPointer, ios::beg);
+
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "BAND" line
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "NextBandHeaderPointer" line
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "ChunkMapPointer" line
+
+   is >> tmp;  // skip "Radiometry"
+
+   is.getline(tmp, MAX_LEN-1, '\n'); // Get the radiometry string.
+   const char* rad = tmp;
+   while ( *rad && (*rad == ' ')) rad++;  // Eat the whitespaces...
+   theRadiometryString = rad;
+
+   is >> tmp // skip "BytesPerPixel"
+      >> theBytesPerPixel
+      >> tmp // skip "BytesPerChip"
+      >> theBytesPerChip
+      >> tmp // skip "BytesPerChunk"
+      >> theBytesPerChunk
+      >> tmp // skip "CompressionType"
+      >> theCompressionType
+      >> tmp // skip "NumberOfRLevels"
+      >> theNumberOfRLevels;
+
+   if ((ossim_uint32)theNumberOfRLevels > theOccupiedFlag.size())
+   {
+      // Resize all the vectors.
+      theOccupiedFlag.resize(theNumberOfRLevels);
+      theStartOfData.resize(theNumberOfRLevels);
+      theNumberOfLines.resize(theNumberOfRLevels);
+      theNumberOfSamples.resize(theNumberOfRLevels);
+      theChunksInLineDir.resize(theNumberOfRLevels);
+      theChunksInSampleDir.resize(theNumberOfRLevels);
+   }
+
+   is.read(tmp, 1);                  // eat the '\n'
+   is.getline(tmp, MAX_LEN-1, '\n'); // skip blank line
+   
+   ossim_uint32 i;
+   for (i=0; i<theNumberOfRLevels; i++)
+   {
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip the Rlevel line
+
+      ossim_uint32 tmp_long;
+      
+      is >> tmp // skip "Occupied"
+         >> tmp_long;
+
+      theOccupiedFlag[i] = tmp_long;
+
+      is >> tmp // skip "StartOfData"
+         >> tmp_long;
+
+      theStartOfData[i] = tmp_long;
+      
+      is >> tmp // skip "NumberOfLines"
+         >> tmp_long;
+
+      theNumberOfLines[i] = tmp_long;
+
+      is >> tmp // skip "NumberOfSamples"
+         >> tmp_long;
+
+      theNumberOfSamples[i] = tmp_long;
+
+      is >> tmp // skip "ChunksInLineDir"
+         >> tmp_long;
+
+      theChunksInLineDir[i] = tmp_long;
+
+      is >> tmp // skip "ChunksInSampleDir"
+         >> tmp_long;
+
+      theChunksInSampleDir[i] = tmp_long;
+
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip "LineOffset" line
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip "LineDecimation" line
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip "SampleOffset" line
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip "SampleDecimation" line
+      is.read(tmp, 1);                  // Eat the '\n'
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip blank line
+      is.read(tmp, 1);                  // Eat the '\n'
+   }
+
+   // Note:  The caller will close the stream.
+   
+   return true;
+}
+
+//***************************************************************************
+// Private Method:
+//***************************************************************************
+bool ossimCcfHead::parseV6CcfHeader(istream& is)
+{
+   static const char MODULE[] = "CcfHead::parseV6CcfHeader";
+
+   // Check the stream.
+   if (!is)
+   {
+      if (TRACE)
+      {
+         cerr << MODULE << " Bad Stream passed to method!"
+              << "\nReturning..."
+              << endl;
+      }
+
+      return false;
+   }
+
+   const ossim_uint32 MAX_LEN = 256;
+   char tmp[MAX_LEN];
+   
+   //***
+   // These are all fixed/not used so just skip...
+   //***
+   is.read(tmp, 1);                   // eat the '\n'
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "ccf_maker"
+
+   is >> tmp // "LinesPerChip"
+      >> theLinesPerChip
+      >> tmp // "SamplesPerChip"
+      >> theSamplesPerChip
+      >> tmp // "LineChipsPerChunk"
+      >> theLineChipsPerChunk
+      >> tmp // "SampleChipsPerChunk"
+      >> theSampleChipsPerChunk;
+
+   is.read(tmp, 1);                   // eat the '\n'
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "NumberOfBands"
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "RectInFullImageSpace"
+
+   is >> tmp // skip "StartLine"
+      >> theRectInFullImageStartLine
+      >> tmp // skip "StartSample"
+      >> theRectInFuleImageStartSample
+      >> tmp // skip "StopLine"
+      >> theRectInFullImageStopLine
+      >> tmp // skip "StopSample"
+      >> theRectInFuleImageStopSample
+      >> tmp // skip "ValidImageVertices"
+      >> theNumberOfValidImageVertices;
+
+   // Get the valid image vertices.
+   ossim_uint32 i;
+
+   if (theNumberOfValidImageVertices != theValidImageVertices.size())
+   {
+      theValidImageVertices.resize(theNumberOfValidImageVertices);
+   }
+
+   for (i=0; i<theNumberOfValidImageVertices; i++)
+   {
+      ossim_float64 tmp_dbl;  // Can be doubles in header.
+      
+      is >> tmp      // skip "Vertex"
+         >> tmp      // skip Vertex number
+         >> tmp_dbl; // line
+
+      theValidImageVertices[i].y = static_cast<int>(tmp_dbl);
+
+      is >> tmp_dbl; // sample
+
+      theValidImageVertices[i].x = static_cast<int>(tmp_dbl);
+   }
+
+   is.read(tmp, 1);                   // eat the '\n'
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip blank line
+
+   is >> tmp                         // skip "FirstBandHeaderPointer"
+      >> theFirstBandHeaderPointer;  // Offset to band header.
+
+   // Seek to the band header record.
+   is.seekg(theFirstBandHeaderPointer, ios::beg);
+
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "BAND" line
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "NextBandHeaderPointer" line
+   is.getline(tmp, MAX_LEN-1, '\n');  // skip "ChunkMapPointer" line
+
+   is >> tmp;  // skip "Radiometry"
+
+   is.getline(tmp, MAX_LEN-1, '\n'); // Get the radiometry string.
+   
+   const char* rad = tmp;
+   while ( *rad && (*rad == ' ')) rad++;  // Eat the whitespaces...
+   theRadiometryString = rad;
+
+   is >> tmp // skip "BytesPerPixel"
+      >> theBytesPerPixel
+      >> tmp // skip "BytesPerChip"
+      >> theBytesPerChip
+      >> tmp // skip "BytesPerChunk"
+      >> theBytesPerChunk
+      >> tmp // skip "CompressionType"
+      >> theCompressionType
+      >> tmp // skip "NumberOfRLevels"
+      >> theNumberOfRLevels;
+
+   if (theNumberOfRLevels > theOccupiedFlag.size())
+   {
+      // Resize all the vectors.
+      theOccupiedFlag.resize(theNumberOfRLevels);
+      theStartOfData.resize(theNumberOfRLevels);
+      theNumberOfLines.resize(theNumberOfRLevels);
+      theNumberOfSamples.resize(theNumberOfRLevels);
+      theChunksInLineDir.resize(theNumberOfRLevels);
+      theChunksInSampleDir.resize(theNumberOfRLevels);
+   }
+
+   is.read(tmp, 1);                  // eat the '\n'
+   is.getline(tmp, MAX_LEN-1, '\n'); // skip blank line
+   
+   for (i=0; i<theNumberOfRLevels; i++)
+   {
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip the Rlevel line
+
+      ossim_uint32 tmp_long;
+      
+      is >> tmp // skip "Occupied"
+         >> tmp_long;
+
+      theOccupiedFlag[i] = tmp_long;
+
+      is >> tmp // skip "StartOfData"
+         >> tmp_long;
+
+      theStartOfData[i] = tmp_long;
+      
+      is >> tmp // skip "NumberOfLines"
+         >> tmp_long;
+
+      theNumberOfLines[i] = tmp_long;
+
+      is >> tmp // skip "NumberOfSamples"
+         >> tmp_long;
+
+      theNumberOfSamples[i] = tmp_long;
+
+      is >> tmp // skip "ChunksInLineDir"
+         >> tmp_long;
+
+      theChunksInLineDir[i] = tmp_long;
+
+      is >> tmp // skip "ChunksInSampleDir"
+         >> tmp_long;
+
+      theChunksInSampleDir[i] = tmp_long;      
+
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip "LineOffset" line
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip "LineDecimation" line
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip "SampleOffset" line
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip "SampleDecimation" line
+      is.read(tmp, 1);                  // Eat the '\n'
+      is.getline(tmp, MAX_LEN-1, '\n'); // skip blank line
+      is.read(tmp, 1);                  // Eat the '\n'
+   }
+
+   // Note:  The caller will close the stream.
+   
+   return true;
+}
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+std::ostream& ossimCcfHead::print(std::ostream& out) const
+{
+   static const char MODULE[] = "ossimCcfHead::print";
+
+   out << MODULE
+       << "\ntheErrorStatus:                 " << theErrorStatus
+       << "\ntheCcfFile:                     " << theCcfFile
+       << "\ntheNumberOfBands:               " << theNumberOfBands
+       << "\nthePixelType:                   "
+       << (ossimScalarTypeLut::instance()->getEntryString(thePixelType))
+       << "\ntheFileType:                    " << theFileType
+       << "\ntheVersionNumber:               " << theVersionNumber
+       << "\ntheLinesPerChip:                " << theLinesPerChip
+       << "\ntheSamplesPerChip:              " << theSamplesPerChip
+       << "\ntheLineChipsPerChunk:           " << theLineChipsPerChunk
+       << "\ntheSampleChipsPerChunk:         " << theSampleChipsPerChunk
+       << "\ntheRectInFullImageStartLine:    " << theRectInFullImageStartLine
+       << "\ntheRectInFuleImageStartSample:  " << theRectInFuleImageStartSample
+       << "\ntheRectInFullImageStopLine:     " << theRectInFullImageStopLine
+       << "\ntheRectInFuleImageStopSample:   " << theRectInFuleImageStopSample
+       << "\ntheNumberOfValidImageVertices:  "
+       << theNumberOfValidImageVertices;
+   
+   ossim_uint32 i;
+   
+   for (i=0; i<theNumberOfValidImageVertices; i++)
+   {
+      out << "\ntheValidImageVertices[" << i << "]:  "
+          << theValidImageVertices[i];
+   }
+   
+   out << "\ntheFirstBandHeaderPointer:  " << theFirstBandHeaderPointer
+       << "\ntheRadiometryString:        " << theRadiometryString
+       << "\ntheBytesPerPixel:           " << theBytesPerPixel
+       << "\ntheBytestPerChip:           " << theBytesPerChip
+       << "\ntheBytesPerChunk:           " << theBytesPerChunk
+       << "\ntheCompressionType:         " << theCompressionType
+       << "\ntheNumberOfRLevels:         " << theNumberOfRLevels;
+   
+   for (i=0; i<theNumberOfRLevels; i++)
+   {
+      out << "\ntheOccupiedFlag[" << i << "]:       " << theOccupiedFlag[i]
+          << "\ntheStartOfData[" << i << "]:        " << theStartOfData[i]
+          << "\ntheNumberOfLines[" << i << "]:      " << theNumberOfLines[i]
+          << "\ntheNumberOfSamples[" << i << "]:    " << theNumberOfSamples[i]
+          << "\ntheChunksInLineDir[" << i << "]:    " << theChunksInLineDir[i]
+          << "\ntheChunksInSampleDir[" << i << "]:  "
+          << theChunksInSampleDir[i];
+   }
+   
+   out << endl;
+
+   return ossimErrorStatusInterface::print(out);
+}
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+ossim_uint32 ossimCcfHead::numberOfLines(ossim_uint32 reduced_res_level) const
+{
+   static const char MODULE[] = "ossimCcfHead::numberOfLines";
+
+   if (reduced_res_level > highestReducedResSet() )
+   {
+      cerr << MODULE << " ERROR!"
+           << "\nInvalid reduced res level:  " << reduced_res_level
+           << "\nHighest reduced res level available:  "
+           << highestReducedResSet() << endl;   
+      return 0;
+   }
+
+   return theNumberOfLines[reduced_res_level];
+}
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+ossim_uint32 ossimCcfHead::numberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   static const char MODULE[] = "ossimCcfHead::numberOfSamples";
+
+   if (reduced_res_level > highestReducedResSet() )
+   {
+      cerr << MODULE << " ERROR!"
+           << "\nInvalid reduced res level:  " << reduced_res_level
+           << "\nHighest reduced res level available:  "
+           << highestReducedResSet() << endl;   
+      return 0;
+   }
+   
+   return theNumberOfSamples[reduced_res_level];
+}
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+ossim_uint32 ossimCcfHead::chunksInLineDir(ossim_uint32 reduced_res_level) const
+{
+   static const char MODULE[] = "ossimCcfHead::chunksInLineDir";
+
+   if (reduced_res_level > highestReducedResSet() )
+   {
+      cerr << MODULE << " ERROR!"
+           << "\nInvalid reduced res level:  " << reduced_res_level
+           << "\nHighest reduced res level available:  "
+           << highestReducedResSet() << endl;   
+      return 0;
+   }
+   
+   return theChunksInLineDir[reduced_res_level];
+}
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+ossim_uint32 ossimCcfHead::chunksInSampleDir(ossim_uint32 reduced_res_level) const
+{
+   static const char MODULE[] = "ossimCcfHead::chunksInSampleDir";
+
+   if (reduced_res_level > highestReducedResSet() )
+   {
+      cerr << MODULE << " ERROR!"
+           << "\nInvalid reduced res level:  " << reduced_res_level
+           << "\nHighest reduced res level available:  "
+           << highestReducedResSet() << endl;   
+      return 0;
+   }
+   
+   return theChunksInSampleDir[reduced_res_level];
+}
+
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+streampos ossimCcfHead::startOfData(ossim_uint32 reduced_res_level) const
+{
+   static const char MODULE[] = "ossimCcfHead::startOfData";
+
+   if (reduced_res_level > highestReducedResSet() )
+   {
+      cerr << MODULE << " ERROR!"
+           << "\nInvalid reduced res level:  " << reduced_res_level
+           << "\nHighest reduced res level available:  "
+           << highestReducedResSet() << endl;   
+      return 0;
+   }
+   
+   return theStartOfData[reduced_res_level];
+}
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+ossimIrect ossimCcfHead::imageRect(ossim_uint32 reduced_res_level) const
+{
+   static const char MODULE[] = "ossimCcfHead::imageRect";
+   
+   if (reduced_res_level > highestReducedResSet() )
+   {
+      cerr << MODULE << " ERROR!"
+           << "\nInvalid reduced res level:  " << reduced_res_level
+           << "\nHighest reduced res level available:  "
+           << highestReducedResSet() << endl;
+      return ossimIrect(0,0,0,0);
+   }
+
+   return ossimIrect(0,
+                     0,
+                     numberOfSamples(reduced_res_level) - 1,
+                     numberOfLines(reduced_res_level)   - 1);
+}
+
+//***************************************************************************
+// Public Method:
+//***************************************************************************
+void ossimCcfHead::parseRadString()
+{
+   static const char MODULE[] = "ossimCcfHead::parseRadString";
+   
+   if (theRadiometryString.contains("RadiomNBand"))
+   {
+      //***
+      // Complex string, must parse. Should look like:
+      // "RadiomNBand (3 3 Linear8 )"
+      //***
+      char tmp[80];
+      istringstream is(theRadiometryString);
+
+      is >> tmp;               // Skip the "RadiomNBand" string.
+      is.get(tmp, 3);          // Eat the space and the '('.
+      is >> theNumberOfBands;  // Get the number of bands.
+   }
+
+   if (theRadiometryString.contains("8"))
+   {
+      thePixelType = OSSIM_UCHAR;
+   }
+   else if(theRadiometryString.contains("16"))
+   {
+      thePixelType = OSSIM_USHORT16;
+   }
+   else if (theRadiometryString.contains("11"))
+   {
+      thePixelType = OSSIM_USHORT11;
+   }
+   else
+   {
+      cerr << MODULE << " Unknown radiometry!"
+           << "\ntheRadiometryString:  " << theRadiometryString << endl;
+   }
+
+   if (TRACE)
+   {
+      cout << MODULE
+           << "\ntheRadiometryString:  " << theRadiometryString
+           << "\ntheNumberOfBands:     " << theNumberOfBands
+           << "\nthePixelType:         "
+           << (ossimScalarTypeLut::instance()->getEntryString(thePixelType))
+           << endl;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfHead.h b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfHead.h
new file mode 100644
index 0000000000..afd243320e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfHead.h
@@ -0,0 +1,202 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for CcfHead.
+//
+// Notes:
+// - This is not a full blown CCF header class as it only captures the
+//   data needed for loading.
+// - Currently only version 6 is supported.
+//
+//*******************************************************************
+//  $Id: ossimCcfHead.h,v 1.8 2004/01/12 16:32:39 dburken Exp $
+#ifndef ossimCcfHead_HEADER
+#define ossimCcfHead_HEADER
+
+#include <vector>
+
+using namespace std;
+
+#include "base/common/ossimErrorStatusInterface.h"
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimIpt.h"
+
+class ossimIrect;
+
+//***************************************************************************
+// CLASS:  ossimCcfHead
+//***************************************************************************
+class ossimCcfHead : public ossimErrorStatusInterface
+{
+public:
+
+   ossimCcfHead();
+   
+   ossimCcfHead(const char* ccf_file);
+
+   ~ossimCcfHead ();
+
+   /*!
+    *  Reads the ccf header and initializes data members.  Returns true on
+    *  successful read, false on error.
+    */
+   bool parseCcfHeader(const char* ccf_file);
+
+   virtual std::ostream& print(std::ostream& out) const;
+
+   ossim_uint32 numberOfReducedResSets() const { return theNumberOfRLevels; }
+
+   ossim_uint32 numberOfLines(ossim_uint32 reduced_res_level) const;
+
+   ossim_uint32 numberOfSamples(ossim_uint32 reduced_res_level) const;
+
+   ossim_uint32 chunksInLineDir(ossim_uint32 reduced_res_level) const;
+   
+   ossim_uint32 chunksInSampleDir(ossim_uint32 reduced_res_level) const;
+
+   streampos startOfData(ossim_uint32 reduced_res_level) const;
+
+   /*!
+    *  Returns the highest available reduced resolution level.
+    *  Zero based.
+    */
+   ossim_uint32 highestReducedResSet() const
+      { return !theNumberOfRLevels ? 0 : (theNumberOfRLevels - 1); }
+
+   /*!
+    *  Returns the zero based image rectangle for the reduced resolution
+    *  level passed in.  Returns a rectangle of (0,0,0,0) if reduced_res_level
+    *  is out of range.
+    */
+   ossimIrect imageRect(ossim_uint32 reduced_res_level) const;
+
+   /*!
+    *  Returns the ccf file name as a String.
+    */
+   ossimString imageFile() const { return theCcfFile; }
+
+   /*!
+    *  Returns the radiometry string.
+    */
+   ossimString radiometry() const { return theRadiometryString; }
+
+   /*!
+    *  Returns the number of bands.
+    */
+   ossim_uint32 numberOfBands() const { return theNumberOfBands; }
+
+   /*!
+    *  Returns the enumerated pixel type.
+    */
+   ossimScalarType pixelType() const { return thePixelType; }
+
+   /*!
+    *  Returns the bytes per chunk.
+    */
+   ossim_uint32 bytesPerChunk() const { return theBytesPerChunk; }
+
+   /*!
+    *  Returns the bytes per chip.
+    */
+   ossim_uint32 bytesPerChip() const { return theBytesPerChip; }
+
+   /*!
+    *  Returns the number of chips in sample direction of a chunk.
+    */
+   ossim_uint32 sampleChipsPerChunk() const { return theSampleChipsPerChunk; }
+
+   /*!
+    *  Returns the number of chips in line direction of a chunk.
+    */
+   ossim_uint32 lineChipsPerChunk() const { return theLineChipsPerChunk; }
+
+   /*!
+    *  Returns the samples per chip.
+    */
+   ossim_uint32 samplesPerChip() const { return theSamplesPerChip; }
+
+   /*!
+    *  Returns the lines per chip.
+    */
+   ossim_uint32 linesPerChip() const { return theLinesPerChip; }
+
+   /*!
+    *  Returns the number of pixels in a single band of a chip.
+    *  Note:  This is not in bytes but in pixels.
+    */
+   ossim_uint32 chipSizePerBand() const
+      { return theLinesPerChip * theSamplesPerChip; }
+
+   const vector<ossimIpt>& getValidImageVertices()const
+      {
+         return theValidImageVertices;
+      }
+private:
+
+   /*!
+    *  Parses a version five header.
+    */
+   bool parseV5CcfHeader(istream& is);
+
+   /*!
+    *  Parses a version six header.
+    */
+   bool parseV6CcfHeader(istream& is);
+
+   /*!
+    *  Parses the radiometry string and initializes "theNumberOfBands" and
+    *  "thePixelType".
+    */
+   void parseRadString();
+
+   ossimString            theCcfFile;
+   ossim_uint32           theNumberOfBands;
+   ossimScalarType        thePixelType;
+   ossimString            theFileType;
+   ossim_uint32           theVersionNumber;
+   ossim_uint32           theLinesPerChip;
+   ossim_uint32           theSamplesPerChip;
+   ossim_uint32           theLineChipsPerChunk;
+   ossim_uint32           theSampleChipsPerChunk;
+   ossim_uint32           theRectInFullImageStartLine;
+   ossim_uint32           theRectInFuleImageStartSample;
+   ossim_uint32           theRectInFullImageStopLine;
+   ossim_uint32           theRectInFuleImageStopSample;
+   ossim_uint32           theNumberOfValidImageVertices;
+   vector<ossimIpt>       theValidImageVertices;
+   ossim_uint32           theFirstBandHeaderPointer;
+   ossimString            theRadiometryString;
+   ossim_uint32           theBytesPerPixel;
+   ossim_uint32           theBytesPerChip;
+   ossim_uint32           theBytesPerChunk;
+   ossimString            theCompressionType;
+   ossim_uint32           theNumberOfRLevels;
+   vector<bool>           theOccupiedFlag;
+   vector<streampos>      theStartOfData;
+   vector<ossim_uint32>   theNumberOfLines;
+   vector<ossim_uint32>   theNumberOfSamples;
+   vector<ossim_uint32>   theChunksInLineDir;
+   vector<ossim_uint32>   theChunksInSampleDir;
+};
+
+
+#endif // #ifndef CcfHead_HEADER
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfTileSource.cpp
new file mode 100644
index 0000000000..be885dee69
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfTileSource.cpp
@@ -0,0 +1,847 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for ossimCcfTileSource.
+//*******************************************************************
+//  $Id: ossimCcfTileSource.cpp,v 1.48 2005/05/09 12:39:38 dburken Exp $
+
+#include <algorithm>
+#include <imaging/formats/ccf/ossimCcfTileSource.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimDirectory.h>
+#include <base/misc/lookup_tables/ossimInterleaveTypeLut.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+using namespace std;
+
+RTTI_DEF1(ossimCcfTileSource, "ossimCcfTileSource", ossimImageHandler);
+
+//***
+// Define Trace flags for use within this file:
+//***
+
+static ossimTrace traceExec  ("ossimCcfTileSource:exec");
+static ossimTrace traceDebug ("ossimCcfTileSource:debug");
+
+// For interleave type enum to string conversions.
+static const ossimInterleaveTypeLut ILUT;
+
+ossimCcfTileSource::ossimCcfTileSource()
+   :
+      ossimImageHandler(),
+      theCcfHead(),
+      theTile(NULL),
+      theChipBuffer(NULL),
+      theFileStr(NULL),
+      theOutputBandList(1),
+      theByteOrder(ossimGetByteOrder())
+{}
+
+ossimCcfTileSource::~ossimCcfTileSource()
+{
+  close();
+}
+
+ossimRefPtr<ossimImageData> ossimCcfTileSource::getTile(
+   const  ossimIrect& rect, ossim_uint32 resLevel)
+{
+   if (!isSourceEnabled() || !isOpen() ||
+       (resLevel >= theCcfHead.numberOfReducedResSets()) )
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   theTile->setImageRectangle(rect);
+
+   ossimIrect image_rect = theCcfHead.imageRect(resLevel);
+   
+   //***
+   // See if any point of the requested tile is in the image.
+   //***
+   if ( rect.intersects(image_rect) )
+   {
+      ossimIrect clip_rect = rect.clipToRect(image_rect);
+
+      if ( !rect.completely_within(clip_rect) )
+      {
+         // Start with a blank tile.
+         theTile->makeBlank();
+      }
+
+      // Load the tile buffer with data from the ccf.
+      if (fillBuffer(rect, clip_rect, image_rect, resLevel))
+      {
+         theTile->validate();
+         return theTile;
+      }
+      else
+      {
+         // Error in filling buffer.
+         cerr << "ossimCcfTileSource getTile ERROR:  Returning blank tile..."
+              << endl;
+         return ossimRefPtr<ossimImageData>();
+      }
+   }
+
+   // No part of requested tile within the image rectangle.
+   return ossimRefPtr<ossimImageData>();
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimCcfTileSource::fillBuffer(const ossimIrect& tile_rect,
+                                    const ossimIrect& clip_rect,
+                                    const ossimIrect& image_rect,
+                                    ossim_uint32 reduced_res_level)
+{
+   bool status = false;
+   
+   //***
+   // Determine the pixel type and make the appropriate tiles.
+   //***
+   switch (theCcfHead.pixelType())
+   {
+   case OSSIM_UCHAR:
+      status = fillUcharBuffer(tile_rect,
+                               clip_rect,
+                               image_rect,
+                               reduced_res_level);
+      break;
+   case OSSIM_USHORT11:
+   case OSSIM_USHORT16:
+      status = fillUshortBuffer(tile_rect,
+                                clip_rect,
+                                image_rect,
+                                reduced_res_level);
+      break;
+   default:
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      cerr << "ossimCcfTileSource fillBuffer ERROR:"
+           << "\nUnsupported pixel type!"
+           << "\nBuffer not filled.  Returning error." << endl;
+      break;
+   }
+
+   return status;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimCcfTileSource::fillUcharBuffer(const ossimIrect& tile_rect,
+                                         const ossimIrect& clip_rect,
+                                         const ossimIrect& image_rect,
+                                         ossim_uint32 reduced_res_level)
+{
+   if(!isOpen()) return false;
+      
+   const ossim_uint32 TILE_SIZE_PER_BAND     = theTile->getSizePerBand();
+   const ossim_uint32 CHIP_SIZE_PER_BAND     = theCcfHead.chipSizePerBand();
+   const ossim_uint32 SAMPLES_PER_CHIP       = theCcfHead.samplesPerChip();
+   const ossim_uint32 LINES_PER_CHIP         = theCcfHead.linesPerChip();
+   const ossim_uint32 BYTES_PER_CHUNK        = theCcfHead.bytesPerChunk();
+   const ossim_uint32 BYTES_PER_CHIP         = theCcfHead.bytesPerChip();
+   const ossim_uint32 CHIPS_IN_SAMPLE_DIR    = theCcfHead.sampleChipsPerChunk();
+   const ossim_uint32 CHIPS_IN_LINE_DIR      = theCcfHead.lineChipsPerChunk();
+   const ossim_uint32 NUMBER_OF_INPUT_BANDS  = theCcfHead.numberOfBands();
+   const ossim_uint32 CHUNKS_IN_SAMPLE_DIR   = theCcfHead.chunksInSampleDir(reduced_res_level);
+   const ossim_uint32 CHUNK_SIDE_SIZE        = SAMPLES_PER_CHIP *
+                                        CHIPS_IN_SAMPLE_DIR;
+   const ossim_uint32 CHIP_OFFSET_TO_END     = SAMPLES_PER_CHIP - 1;
+
+   //***
+   // Shift the upper left corner of the "clip_rect" to the an even chunk
+   // boundry.
+   //***
+   ossimIpt chunkOrigin = clip_rect.ul();
+   adjustToStartOfChunk(chunkOrigin);
+
+   //***
+   // Calculate the number of chunks needed in the line/sample directions.
+   //***
+   ossim_uint32 size_in_x
+      = static_cast<ossim_uint32>(clip_rect.lr().x - chunkOrigin.x + 1);
+   ossim_uint32 size_in_y
+      = static_cast<ossim_uint32>(clip_rect.lr().y - chunkOrigin.y + 1);
+   ossim_uint32 w = (CHIPS_IN_SAMPLE_DIR*SAMPLES_PER_CHIP);
+   ossim_uint32 h = (CHIPS_IN_LINE_DIR*LINES_PER_CHIP);
+   ossim_uint32 chunks_in_x_dir = size_in_x / w  + (size_in_x % w  ? 1 : 0);
+   ossim_uint32 chunks_in_y_dir = size_in_y / h + (size_in_y % h ? 1 : 0);
+   
+   
+   //***
+   // Get the start of data for the "reduced_res_level" passed in.
+   //***
+   streampos startOfData = theCcfHead.startOfData(reduced_res_level);
+   ossimIpt ulChunkPt = chunkOrigin;
+
+   // Chunk loop in line direction.
+   for (ossim_uint32 y=0; y<chunks_in_y_dir; ++y)
+   {
+      ulChunkPt.x = chunkOrigin.x;
+
+      // Chunk loop in sample direction.
+      for (ossim_uint32 x=0; x<chunks_in_x_dir; ++x)
+      {
+         //***
+         // Sequence through the chips in the chunk.
+         // Grab the ccf data and stuff the tile buffer.
+         //***
+         ossimIpt chip_pt = ulChunkPt;
+
+         // Chip loop in line direction.
+         for (ossim_uint32 y_chip=0; y_chip<CHIPS_IN_LINE_DIR; ++y_chip) 
+         {
+            chip_pt.x = ulChunkPt.x;  // Reset x back to front of chunk.
+
+            // Chip loop in sample direction.
+            for (ossim_uint32 x_chip=0; x_chip<CHIPS_IN_SAMPLE_DIR; ++x_chip)
+            {
+               ossimIrect chip_rect(chip_pt.x,
+                               chip_pt.y,
+                               chip_pt.x + CHIP_OFFSET_TO_END,
+                               chip_pt.y + CHIP_OFFSET_TO_END);
+               
+               if (chip_rect.intersects(clip_rect))
+               {
+                  //***
+                  // Some point in the chip intersect the tile so grab the
+                  // data.
+                  //***
+
+                  //***
+                  // Get the seek position for the chunk.
+                  //***
+                  streampos tmp_offset
+                     = ( ulChunkPt.y / CHUNK_SIDE_SIZE * BYTES_PER_CHUNK *
+                         CHUNKS_IN_SAMPLE_DIR ) +
+                     ( ulChunkPt.x / CHUNK_SIDE_SIZE * BYTES_PER_CHUNK );
+
+                  streampos seek_position = startOfData + tmp_offset;
+
+                  // Now move it to the chip.
+                  tmp_offset
+                     = ( y_chip *  BYTES_PER_CHIP * CHIPS_IN_SAMPLE_DIR ) +
+                     (x_chip * BYTES_PER_CHIP);
+
+                  seek_position += tmp_offset;
+
+                  // Seek to the chip
+                  theFileStr->seekg(seek_position, ios::beg);
+
+                  //***
+                  // Read the chip from the ccf file into the chip buffer.
+                  // This will get all the bands.  Bands are interleaved by
+                  // chip.
+                  //***
+                  if (!theFileStr->read((char*)theChipBuffer, BYTES_PER_CHIP))
+                  {
+                     theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+                     cerr << "ossimCcfTileSource fillUchBuffer READ ERROR!"
+                          << "\nReturning from method." << endl;
+                     return false;
+                  }
+                  
+                  ossimIrect chip_clip_rect = clip_rect.clipToRect(chip_rect);
+
+                  //***
+                  // Band loop in sample direction.  Bands are interleaved by
+                  // chip.
+                  //***
+                  for (ossim_uint32 band=0; band<NUMBER_OF_INPUT_BANDS; ++band)
+                  {
+                     //***
+                     // Get a pointer positioned at the first valid pixel in
+                     // the chip.
+                     //***
+                     ossim_uint8* s
+                        = theChipBuffer +
+                        band * CHIP_SIZE_PER_BAND + 
+                        (chip_clip_rect.ul().y - chip_rect.ul().y) *
+                        SAMPLES_PER_CHIP + chip_clip_rect.ul().x -
+                        chip_rect.ul().x;
+                                
+                     //***
+                     // Get a pointer positioned at the first valid pixel in
+                     // the tile.
+                     //***
+                     ossim_uint8* d
+                        = (ossim_uint8*)theTile->getBuf() +
+                        band * TILE_SIZE_PER_BAND +
+                        (chip_clip_rect.ul().y - tile_rect.ul().y) *
+                        theTile->getWidth() + chip_clip_rect.ul().x -
+                        tile_rect.ul().x;      
+
+                     // Line loop through a chip.
+                     for (ossim_int32 chip_line = chip_clip_rect.ul().y;
+                          chip_line <= chip_clip_rect.lr().y;
+                          chip_line++)
+                     {
+                        // Sample loop through a chip.
+                        ossim_uint32 i=0;
+                        for (ossim_int32 chip_sample = chip_clip_rect.ul().x;
+                             chip_sample <= chip_clip_rect.lr().x;
+                             chip_sample++)
+                        {
+                           d[i] = s[i];
+                           i++;
+                        }
+
+                        // Increment the pointers by one line.
+                        s += SAMPLES_PER_CHIP;
+                        d += theTile->getWidth();
+                     }
+                     
+                  } // End of band loop.
+                  
+               } // End of if (chip_rect.intersects(clip_rect))
+               
+               chip_pt.x += SAMPLES_PER_CHIP;
+               
+            } // End of chip loop in the sample direction.
+
+           chip_pt.y += LINES_PER_CHIP; 
+            
+         } // End of chip loop in the line direction.
+         
+         ulChunkPt.x += CHUNK_SIDE_SIZE;
+         
+      }  // End of chunk loop in the sample direction.
+
+      ulChunkPt.y += CHUNK_SIDE_SIZE;
+      
+   }  // End of chunk loop in the line direction.
+
+   return true;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimCcfTileSource::fillUshortBuffer(const ossimIrect& tile_rect,
+                                          const ossimIrect& clip_rect,
+                                          const ossimIrect& image_rect,
+                                          ossim_uint32 reduced_res_level)
+{
+   const ossim_uint32 TILE_SIZE_PER_BAND     = theTile->getSizePerBand();
+   const ossim_uint32 CHIP_SIZE_PER_BAND     = theCcfHead.chipSizePerBand();
+   const ossim_uint32 SAMPLES_PER_CHIP       = theCcfHead.samplesPerChip();
+   const ossim_uint32 LINES_PER_CHIP         = theCcfHead.linesPerChip();
+   const ossim_uint32 BYTES_PER_CHUNK        = theCcfHead.bytesPerChunk();
+   const ossim_uint32 BYTES_PER_CHIP         = theCcfHead.bytesPerChip();
+   const ossim_uint32 CHIPS_IN_SAMPLE_DIR    = theCcfHead.sampleChipsPerChunk();
+   const ossim_uint32 CHIPS_IN_LINE_DIR      = theCcfHead.lineChipsPerChunk();
+   const ossim_uint32 NUMBER_OF_INPUT_BANDS  = theCcfHead.numberOfBands();
+   const ossim_uint32 CHUNKS_IN_SAMPLE_DIR   = theCcfHead.
+                                        chunksInSampleDir(reduced_res_level);
+   const ossim_uint32 CHUNK_SIDE_SIZE        = SAMPLES_PER_CHIP *
+                                        CHIPS_IN_SAMPLE_DIR;
+   const ossim_uint32 CHIP_OFFSET_TO_END     = SAMPLES_PER_CHIP - 1;
+   
+   //***
+   // Shift the upper left corner of the "clip_rect" to the an even chunk
+   // boundry.
+   //***
+   ossimIpt chunkOrigin = clip_rect.ul();
+   adjustToStartOfChunk(chunkOrigin);
+
+   //***
+   // Calculate the number of chunks needed in the line/sample directions.
+   //***
+   
+   ossim_uint32 size_in_x = clip_rect.lr().x - chunkOrigin.x + 1;
+   ossim_uint32 size_in_y = clip_rect.lr().y - chunkOrigin.y + 1;
+   ossim_uint32 w = (CHIPS_IN_SAMPLE_DIR*SAMPLES_PER_CHIP);
+   ossim_uint32 h = (CHIPS_IN_LINE_DIR*LINES_PER_CHIP);
+   ossim_uint32 chunks_in_x_dir = size_in_x / w  + (size_in_x % w  ? 1 : 0);
+   ossim_uint32 chunks_in_y_dir = size_in_y / h + (size_in_y % h ? 1 : 0);
+   //***
+   // Get the start of data for the "reduced_res_level" passed in.
+   //***
+   streampos startOfData = theCcfHead.startOfData(reduced_res_level);
+   ossimIpt ulChunkPt = chunkOrigin;
+
+   // Chunk loop in line direction.
+   for (ossim_uint32 y=0; y<chunks_in_y_dir; ++y)
+   {
+      ulChunkPt.x = chunkOrigin.x;
+
+      // Chunk loop in sample direction.
+      for (ossim_uint32 x=0; x<chunks_in_x_dir; ++x)
+      {
+         //***
+         // Sequence through the chips in the chunk.
+         // Grab the ccf data and stuff the tile buffer.
+         //***
+         ossimIpt chip_pt = ulChunkPt;
+
+         // Chip loop in line direction.
+         for (ossim_uint32 y_chip=0; y_chip<CHIPS_IN_LINE_DIR; ++y_chip) 
+         {
+            chip_pt.x = ulChunkPt.x;  // Reset x back to front of chunk.
+
+            // Chip loop in sample direction.
+            for (ossim_uint32 x_chip=0; x_chip<CHIPS_IN_SAMPLE_DIR; ++x_chip)
+            {
+               ossimIrect chip_rect(chip_pt.x,
+                               chip_pt.y,
+                               chip_pt.x + CHIP_OFFSET_TO_END,
+                               chip_pt.y + CHIP_OFFSET_TO_END);
+               
+               if (chip_rect.intersects(clip_rect))
+               {
+                  //***
+                  // Some point in the chip intersect the tile so grab the
+                  // data.
+                  //***
+
+                  //***
+                  // Get the seek position for the chunk.
+                  //***
+                  streampos tmp_offset
+                     = ( ulChunkPt.y / CHUNK_SIDE_SIZE * BYTES_PER_CHUNK *
+                         CHUNKS_IN_SAMPLE_DIR ) +
+                     ( ulChunkPt.x / CHUNK_SIDE_SIZE * BYTES_PER_CHUNK );
+
+                  streampos seek_position = startOfData + tmp_offset;
+
+                  // Now move it to the chip.
+                  tmp_offset
+                     = ( y_chip *  BYTES_PER_CHIP * CHIPS_IN_SAMPLE_DIR ) +
+                     (x_chip * BYTES_PER_CHIP);
+
+                  seek_position += tmp_offset;
+
+                  // Seek to the chip
+                  theFileStr->seekg(seek_position, ios::beg);
+
+                  //***
+                  // Read the chip from the ccf file into the chip buffer.
+                  // This will get all the bands.  Bands are interleaved by
+                  // chip.
+                  //***
+                  if (!theFileStr->read((char*)theChipBuffer, BYTES_PER_CHIP))
+                  {
+                     theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+                     cerr << "ossimCcfTileSource fillUshortBuffer READ ERROR!"
+                          << "Returning from method." << endl;
+                     return false;
+                  }
+                  
+                  ossimIrect chip_clip_rect = clip_rect.clipToRect(chip_rect);
+
+                  //***
+                  // Band loop in sample direction.  Bands are interleaved by
+                  // chip.
+                  //***
+                  for (ossim_uint32 band=0; band<NUMBER_OF_INPUT_BANDS; band++)
+                  {
+                     //***
+                     // Get a pointer positioned at the first valid pixel in
+                     // the chip.
+                     //***
+                     ossim_uint16* s
+                        = (ossim_uint16*)theChipBuffer +
+                        band * CHIP_SIZE_PER_BAND + 
+                        (chip_clip_rect.ul().y - chip_rect.ul().y) *
+                        SAMPLES_PER_CHIP + chip_clip_rect.ul().x -
+                        chip_rect.ul().x;       
+                     
+                     //***
+                     // Get a pointer positioned at the first valid pixel in
+                     // the tile.
+                     //***
+                     ossim_uint16* d
+                        = (ossim_uint16*)theTile->getBuf() +
+                        band * TILE_SIZE_PER_BAND +
+                        (chip_clip_rect.ul().y - tile_rect.ul().y) *
+                        theTile->getWidth() + chip_clip_rect.ul().x -
+                        tile_rect.ul().x;
+                     
+                     // Line loop through a chip.
+                     for (ossim_int32 chip_line = chip_clip_rect.ul().y;
+                          chip_line <= chip_clip_rect.lr().y;
+                          ++chip_line)
+                     {
+                        // Sample loop through a chip.
+                        ossim_uint32 i=0;
+                        for (ossim_int32 chip_sample = chip_clip_rect.ul().x;
+                             chip_sample <= chip_clip_rect.lr().x;
+                             ++chip_sample)
+                        {
+                           if (theByteOrder == OSSIM_LITTLE_ENDIAN)
+                           {
+                              //***
+                              // CCF data alway stored in big endian byte
+                              // order so swap the bytes.
+                              //***
+                              d[i] = (s[i] << 8) | (s[i] >> 8);
+                           }
+                           else
+                           {
+                              d[i] = s[i];
+                           }
+                           
+                           ++i;
+                        }
+
+                        // Increment the pointers by one line.
+                        s += SAMPLES_PER_CHIP;
+                        d += theTile->getWidth();
+                     }
+                     
+                  } // End of band loop.
+                  
+               } // End of if (chip_rect.intersects(clip_rect))
+               
+               chip_pt.x += SAMPLES_PER_CHIP;
+               
+            } // End of chip loop in the sample direction.
+
+           chip_pt.y += LINES_PER_CHIP; 
+            
+         } // End of chip loop in the line direction.
+         
+         ulChunkPt.x += CHUNK_SIDE_SIZE;
+         
+      }  // End of chunk loop in the sample direction.
+
+      ulChunkPt.y += CHUNK_SIDE_SIZE;
+      
+   }  // End of chunk loop in the line direction.
+
+   return true;
+}
+   
+            
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ossimIrect
+ossimCcfTileSource::getImageRectangle(ossim_uint32 reduced_res_level) const
+{
+   return theCcfHead.imageRect(reduced_res_level);
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+bool ossimCcfTileSource::setOutputBandList(const vector<ossim_uint32>& outputBandList)
+{
+   static const char MODULE[] = "ossimCcfTileSource::setOutputBandList";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   if (outputBandList.size() != theOutputBandList.size())
+   {
+      //***
+      // Verify that each individual band does not bust the range of input
+      // bands.
+      //***
+      for (ossim_uint32 i=0; i<outputBandList.size(); i++)
+      {
+         if (outputBandList[i] > (getNumberOfInputBands() - 1))
+         {
+            setErrorStatus();
+
+            cerr << MODULE << " ERROR:"
+                 << "\nOutput band number in list is greater than the "
+                 << "number of bands in the image source!"
+                 << "\noutputBandList[" << i << "]:  "
+                 << "\nHighest availabe band:  "
+                 << (getNumberOfInputBands() - 1)
+                 << "\nError status has been set!  Returning..."
+                 << endl;
+            return false;            
+         }
+      }
+
+      // Remove the old tiles and reallocate with the new size.
+      theTile = NULL;
+   }
+
+   theOutputBandList = outputBandList;  // Assign the new list.
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return true;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimCcfTileSource::saveState(ossimKeywordlist& kwl,
+                                   const char* prefix) const
+{
+   // Currently nothing to do here.
+   return ossimImageHandler::saveState(kwl, prefix);
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimCcfTileSource::loadState(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+{
+   if (ossimImageHandler::loadState(kwl, prefix))
+   {
+      if (open())
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimCcfTileSource::open()
+{
+   static const char MODULE[] = "ossimCcfTileSource::open";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   if(isOpen())
+   {
+      close();
+   }
+   
+   if (traceDebug())
+   {
+      CLOG << "DEBUG -- "
+           << "\n\t theImageFile: " << theImageFile << endl;
+   }
+   
+   if (theCcfHead.parseCcfHeader(theImageFile.c_str()) == false)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      if (traceExec())  CLOG << "returning with error..." << endl;
+      return false;
+   }
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG -- "
+           << "\n\t theImageFile: " << theImageFile
+           << "\n\t theCcfHead: " << theCcfHead
+           << endl;
+   }
+
+   theFileStr = new std::ifstream;
+   // Open up the file for reading.
+   theFileStr->open(theImageFile.c_str(), ios::in | ios::binary);
+   
+   if (!(*theFileStr))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      
+      cerr << MODULE << " ERROR!"
+           << "\nCould not open file:  " << theImageFile.c_str()
+           << "\nReturning..." << endl;
+      if (traceExec())  CLOG << "returning with error..." << endl;
+
+      delete theFileStr;
+      theFileStr = NULL;
+      return false;
+   }
+
+   theTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile->initialize();
+     
+   theChipBuffer  = new ossim_uint8[theCcfHead.bytesPerChip()];
+   
+   // Initialize the output band list.
+   if (getNumberOfInputBands() > theOutputBandList.size())
+   {
+      theOutputBandList.resize(getNumberOfInputBands());
+   }
+   
+   for (ossim_uint32 i=0; i<getNumberOfInputBands(); ++i)
+   {
+      theOutputBandList[i] = i; // One to one for initial setup.
+   }
+   
+   completeOpen();
+   
+   if (traceDebug() && theTile.valid())
+   {
+      CLOG << "DEBUG:"
+           << "\ntheTile:\n" << *theTile << endl;
+   }
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return true;
+}
+
+void ossimCcfTileSource::close()
+{
+   theTile = NULL;
+   if (theChipBuffer)
+   {
+      delete [] theChipBuffer;
+      theChipBuffer = NULL;
+   }
+   if(theFileStr)
+   {
+      theFileStr->close();
+      theFileStr->clear();
+      delete theFileStr;
+      theFileStr = NULL;
+   }
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossimScalarType ossimCcfTileSource::getOutputScalarType() const
+{
+   return theCcfHead.pixelType();
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimCcfTileSource::getTileWidth() const
+{
+   return ( theTile.valid() ? theTile->getWidth() : 0 );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimCcfTileSource::getTileHeight() const
+{
+   return ( theTile.valid() ? theTile->getHeight() : 0 );
+}
+
+ossim_uint32 ossimCcfTileSource::getImageTileWidth() const
+{
+   return 32;
+}
+
+ossim_uint32 ossimCcfTileSource::getImageTileHeight() const
+{
+   return 32;
+}
+
+void ossimCcfTileSource::initVerticesFromHeader()
+{
+   theValidImageVertices.clear();
+   
+   const vector<ossimIpt>& validImageVertices
+      = theCcfHead.getValidImageVertices();
+   
+   ossim_uint32 upper = validImageVertices.size();
+   if(!upper) return;
+   for(ossim_uint32 index = 0; index < upper; ++index)
+   {
+      theValidImageVertices.push_back(validImageVertices[index]);
+   }
+
+   if (traceDebug())
+   {
+      cout << "ossimCcfTileSource::initVerticesFromHeader DEBUG:"
+           << "\nValid image vertices:"
+           << endl;
+      for (ossim_uint32 i=0; i<upper; ++i)
+      {
+         cout << "\npoint[" << i << "]:  " << theValidImageVertices[i];
+      }
+      cout << endl;
+   }
+}
+
+bool ossimCcfTileSource::isEcgGeom(const ossimFilename& filename)const
+{
+   ossimFilename file = filename;
+   file.setExtension("geom");
+   
+   if(file.exists())
+   {
+      char bytes[3];
+      ifstream in(file.c_str());
+      
+      in.read((char*)bytes, 3);
+      ossimString testEcg(bytes,
+                          bytes + 3);
+      testEcg = testEcg.downcase();
+      if(in&&(testEcg == "ecg"))
+      {
+         return true;
+      }
+   }
+   return false;
+}
+
+ossimString ossimCcfTileSource::getShortName()const
+{
+   return ossimString("ccf");
+}
+
+ossimString ossimCcfTileSource::getLongName()const
+{
+   return ossimString("ccf reader");
+}
+
+ossimString ossimCcfTileSource::className()const
+{
+   return ossimString("ossimCcfTileSource");
+}
+
+ossim_uint32 ossimCcfTileSource::getNumberOfInputBands() const
+{
+   return theCcfHead.numberOfBands();
+}
+
+ossim_uint32 ossimCcfTileSource::getNumberOfOutputBands()const
+{
+   return getNumberOfInputBands();
+}
+
+ossim_uint32 ossimCcfTileSource::getNumberOfLines(ossim_uint32 reduced_res_level) const
+{
+   return theCcfHead.numberOfLines(reduced_res_level);
+}
+
+ossim_uint32 ossimCcfTileSource::getNumberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   return theCcfHead.numberOfSamples(reduced_res_level);
+}
+
+ossim_uint32 ossimCcfTileSource::getNumberOfDecimationLevels() const
+{
+   return theCcfHead.numberOfReducedResSets();
+}
+
+bool ossimCcfTileSource::isOpen()const
+{
+   return (theFileStr != NULL);
+}
+
+void ossimCcfTileSource::adjustToStartOfChunk(ossimIpt& pt) const
+{
+   pt.x &= 0xffffff00;
+   pt.y &= 0xffffff00;
+}
+
+void ossimCcfTileSource::adjustToStartOfChip(ossimIpt& pt) const
+{
+   pt.x &= 0xffffffe0;
+   pt.y &= 0xffffffe0;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfTileSource.h
new file mode 100644
index 0000000000..194c4ea7cc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ccf/ossimCcfTileSource.h
@@ -0,0 +1,202 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for CcfTileSource.
+//
+// A ccf (Chip Chunk Format) is a double tiled format.  Image data is
+// arranged in chips and chunks.  Each chip is 32 x 32 pixels.  Each chunk
+// is 8 x 8 chips for a single band image.  Bands are interleaved by chip
+// so a rgb image has a red chip a green chip, then a blue chip which
+// would make the chunk 24 x 8 chips.
+//
+//*******************************************************************
+//  $Id: ossimCcfTileSource.h,v 1.26 2005/07/25 22:44:41 dburken Exp $
+
+#ifndef ossimCcfTileSource_HEADER
+#define ossimCcfTileSource_HEADER
+
+#include <fstream>
+using namespace std;
+
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/formats/ccf/ossimCcfHead.h>
+
+class  ossimImageData;
+
+class OSSIM_DLL ossimCcfTileSource : public ossimImageHandler
+{
+public:
+
+   ossimCcfTileSource();
+   virtual ~ossimCcfTileSource();
+   
+   virtual ossimString getShortName()const;
+   virtual ossimString getLongName()const;
+   virtual ossimString className()const;
+
+   /**
+    *  @return Returns true on success, false on error.
+    *
+    *  @note This method relies on the data member ossimImageData::theImageFile
+    *  being set.  Callers should do a "setFilename" prior to calling this
+    *  method or use the ossimImageHandler::open that takes a file name and an
+    *  entry index.
+    */
+   virtual bool open();
+   
+   virtual void close();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+   
+    /**
+     *  Returns the number of bands in the image.
+     *  Satisfies pure virtual from ImageHandler class.
+     */
+   virtual ossim_uint32 getNumberOfInputBands() const;
+   virtual ossim_uint32 getNumberOfOutputBands()const;
+
+   /**
+     *  Returns the number of lines in the image.
+     *  Satisfies pure virtual from ImageHandler class.
+     */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    *  Returns the number of samples in the image.  
+    *  Satisfies pure virtual from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
+
+   /**
+    *  Returns the number of reduced resolution data sets (rrds).
+    *  Note:  The full res image is counted as a data set so an image with no
+    *         reduced resolution data set will have a count of one.
+    */
+   virtual ossim_uint32 getNumberOfDecimationLevels() const;
+   
+   /**
+    *  Returns the zero based image rectangle for the reduced resolution data
+    *  set (rrds) passed in.  Note that rrds 0 is the highest resolution rrds.
+    */
+   virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    *  Set the output band list.  Use to set the number and order of output
+    *  bands.  Will set an error if out of range.
+    */
+   bool setOutputBandList(const vector<ossim_uint32>& outputBandList);
+
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+      
+   /**
+    * Returns the output pixel type of the tile source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32 getTileWidth() const;
+   
+   /**
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;
+
+   virtual bool isOpen()const;
+
+
+   
+private:
+
+   void initVerticesFromHeader();
+   
+   // Disallow these...
+   ossimCcfTileSource(const ossimCcfTileSource& source);
+   ossimCcfTileSource& operator=(const ossimCcfTileSource& source); 
+   
+   /**
+    *  Returns true on success, false on error.
+    */
+   bool fillBuffer(const  ossimIrect& tile_rect,
+                   const  ossimIrect& clip_rect,
+                   const  ossimIrect& image_rect,
+                   ossim_uint32 reduced_res_level);
+
+   /**
+    *  Returns true on success, false on error.
+    */
+   bool fillUshortBuffer(const  ossimIrect& tile_rect,
+                         const  ossimIrect& clip_rect,
+                         const  ossimIrect& image_rect,
+                         ossim_uint32 reduced_res_level);
+
+   /**
+    *  Returns true on success, false on error.
+    */
+   bool fillUcharBuffer(const  ossimIrect& tile_rect,
+                        const  ossimIrect& clip_rect,
+                        const  ossimIrect& image_rect,
+                        ossim_uint32 reduced_res_level);
+
+   /**
+    *  Adjust point to even 256 boundary.  Assumes 0,0 origin.
+    */
+   void adjustToStartOfChunk(ossimIpt& pt) const;
+
+   /**
+    *  Adjust point to even 32 boundary.  Assumes 0,0 origin.
+    */
+   void adjustToStartOfChip(ossimIpt& pt) const;
+
+   bool isEcgGeom(const ossimFilename& filename)const;
+
+   ossimCcfHead                theCcfHead;
+   ossimRefPtr<ossimImageData> theTile;
+   ossim_uint8*                theChipBuffer;
+   ifstream*                   theFileStr;
+   vector<ossim_uint32>        theOutputBandList;
+   ossim_int32                 theByteOrder;
+
+
+TYPE_DATA
+};
+   
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/ossimCibCadrgTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/ossimCibCadrgTileSource.cpp
new file mode 100644
index 0000000000..8342f3872b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/ossimCibCadrgTileSource.cpp
@@ -0,0 +1,1423 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//********************************************************************
+// $Id: ossimCibCadrgTileSource.cpp,v 1.86 2005/08/29 19:56:41 gpotts Exp $
+#include <algorithm>
+using namespace std;
+
+#include <imaging/formats/cibcadrg/ossimCibCadrgTileSource.h>
+
+#include <base/common/ossimStdOutProgress.h>
+#include <base/common/ossimNBandLutDataObject.h>
+#include <imaging/histogram/ossimHistogramWriter.h>
+#include <imaging/histogram/ossimImageHistogramSource.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <support_data/rpf/ossimRpfFrame.h>
+#include <support_data/rpf/ossimRpfHeader.h>
+#include <support_data/rpf/ossimRpfToc.h>
+#include <support_data/rpf/ossimRpfTocEntry.h>
+#include <support_data/rpf/ossimRpfCompressionSection.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <projections/map_projections/ossimCylEquAreaProjection.h>
+#include <base/misc/ossimEndian.h>
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug = ossimTrace("ossimCibCadrgTileSource:debug");
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimCibCadrgTileSource.cpp,v 1.86 2005/08/29 19:56:41 gpotts Exp $";
+#endif
+
+RTTI_DEF1(ossimCibCadrgTileSource, "ossimCibCadrgTileSource", ossimImageHandler)
+
+const ossim_uint32 ossimCibCadrgTileSource::CIBCADRG_FRAME_WIDTH  = 1536;
+const ossim_uint32 ossimCibCadrgTileSource::CIBCADRG_FRAME_HEIGHT = 1536;
+
+ossimCibCadrgTileSource::ossimCibCadrgTileSource()
+   :ossimImageHandler(),
+    theCompressedBuffer(NULL),
+    theUncompressedBuffer(NULL),
+    theNumberOfLines(0),
+    theNumberOfSamples(0),
+    theTile(NULL),
+    theTableOfContents(NULL),
+    theEntryToRender(NULL),
+    theEntryNumberToRender(1),
+    theTileSize(128, 128),
+    theProductType(OSSIM_PRODUCT_TYPE_UNKNOWN)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimCibCadrgTileSource::ossimCibCadrgTileSource entered...\n";
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "OSSIM_ID:  " << OSSIM_ID << "\n";
+#endif      
+   }
+   theWorkFrame = new ossimRpfFrame;
+   
+   theActualImageRect.makeNan();
+
+   // a CADRG and CIBis a 64*64*12 bit buffer and must divide by 8 to
+   // convert to bytes
+   theCompressedBuffer   = new ossim_uint8[(64*64*12)/8];
+
+   // whether CIB or CADRG we will alocate the buffer
+   // to the larger of the 2 (CADRG is 3 bands)
+   theUncompressedBuffer = new ossim_uint8[256*256*3];
+                           
+}
+
+ossimCibCadrgTileSource::~ossimCibCadrgTileSource()
+{
+   if(theCompressedBuffer)
+   {
+      delete [] theCompressedBuffer;
+      theCompressedBuffer = 0;
+   }
+   if(theUncompressedBuffer)
+   {
+      delete [] theUncompressedBuffer;
+      theUncompressedBuffer = 0;
+   }
+   if(theWorkFrame)
+   {
+      delete theWorkFrame;
+      theWorkFrame = 0;
+   }
+   close();
+}
+
+ossimString ossimCibCadrgTileSource::getShortName()const
+{
+   return ossimString("CIB/CADRG");
+}
+
+ossimString ossimCibCadrgTileSource::getLongName()const
+{
+   return ossimString("CIB/CADRG reader");
+}
+
+
+void ossimCibCadrgTileSource::close()
+{
+   deleteAll();
+}
+
+bool ossimCibCadrgTileSource::isOpen()const
+{
+   return (theTableOfContents!=NULL);
+}
+
+bool ossimCibCadrgTileSource::open()
+{
+   ossimFilename imageFile = theImageFile;
+  bool result = true;
+   if(isOpen())
+   {
+      close();
+   }
+   
+   theTableOfContents = new ossimRpfToc;
+
+   if(theTableOfContents)
+   {      
+      if(theTableOfContents->parseFile(imageFile) == ossimErrorCodes::OSSIM_OK)
+      {
+         if(theTableOfContents->getNumberOfEntries() > 0)
+         {
+            vector<ossimString> scaleList = getProductScaleList();
+            if(scaleList.size() > 0)
+            {               
+               vector<long>  entryList = getProductEntryList(scaleList[0]);
+               if(entryList.size() > 0)
+               {
+                  //open(imageFile, entryList[0]);
+                  setCurrentEntry(entryList[0]);
+                  
+                  if(theEntryToRender)
+                  {
+                     // a CADRG is 1536x1536 per frame.
+                     theNumberOfLines   = theEntryToRender->getNumberOfFramesVertical()*CIBCADRG_FRAME_HEIGHT;
+                     theNumberOfSamples = theEntryToRender->getNumberOfFramesHorizontal()*CIBCADRG_FRAME_WIDTH;
+                  }
+                  else // we didn't find a frame to render
+                  {
+                     result = false;
+                  }
+                  if(theEntryToRender->getProductType().trim().upcase() == "CADRG")
+                  {
+                     theProductType = OSSIM_PRODUCT_TYPE_CADRG;
+                  }
+                  else if(theEntryToRender->getProductType().trim().upcase() == "CIB")
+                  {
+                     theProductType = OSSIM_PRODUCT_TYPE_CIB;
+                  }
+                  else
+                  {
+                     result = false;
+                  }
+                  allocateForProduct();
+               }
+               else
+               {
+                  result = false;
+               }
+            }
+            else
+            {
+               result = false;
+            }
+         }
+         else
+         {
+            result = false;
+         }
+      }
+      else
+      {
+         result = false;
+      }
+   }
+   else
+   {
+      result = false;
+   }
+
+   if(!result)
+   {
+      close();
+   }
+   else
+   {
+      //---
+      // Adjust image rect so not to go over the -180 to 180 and -90 to 90
+      // bounds.
+      //---
+      setActualImageRect();
+
+      // Set the base class image file name.
+      theImageFile = imageFile;
+
+      completeOpen();
+
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+      theTile->initialize();
+   }
+
+   return result;
+}
+
+ossimRefPtr<ossimImageData> ossimCibCadrgTileSource::getTile(
+   const  ossimIrect& rect, ossim_uint32 resLevel)
+{
+   ossimIpt origin = rect.ul();
+      
+   if(!isOpen())
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+   ossimIrect imageRect = getImageRectangle();
+   if( (!rect.intersects(imageRect) )||
+       (theProductType == OSSIM_PRODUCT_TYPE_UNKNOWN) )
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+   
+   theTile->setImageRectangle(rect);
+   if (theOverview)
+   {
+      if (theOverview->hasR0() || resLevel)
+      {
+         return theOverview->getTile(rect, resLevel);
+      }
+   }
+
+   vector<ossimFrameEntryData> frames = getIntersectingEntries(rect);
+   if(frames.size() > 0)
+   {
+      theTile->makeBlank();
+      // now lets render each frame.  Note we will have to find subframes
+      // that intersect the rectangle of interest for each frame.
+      //
+      fillTile(rect, frames);
+   }
+   else
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   theTile->validate();
+   
+   return theTile;
+}
+
+ossim_uint32 ossimCibCadrgTileSource::getNumberOfInputBands()const
+{
+   switch(theProductType)
+   {
+   case  OSSIM_PRODUCT_TYPE_UNKNOWN:
+   {
+      return 0;
+   }
+   case OSSIM_PRODUCT_TYPE_CIB:
+   {
+      return 1;
+   }
+   case OSSIM_PRODUCT_TYPE_CADRG:
+   {
+      return 3;
+   }
+   }
+   
+   return 0;
+}
+
+ossim_uint32 ossimCibCadrgTileSource::getNumberOfOutputBands()const
+{
+   switch(theProductType)
+   {
+   case  OSSIM_PRODUCT_TYPE_UNKNOWN:
+   {
+      return 0;
+   }
+   case OSSIM_PRODUCT_TYPE_CIB:
+   {
+      return 1;
+   }
+   case OSSIM_PRODUCT_TYPE_CADRG:
+   {
+      return 3;
+   }
+   }
+   
+   return 0;
+}
+
+ossim_uint32 ossimCibCadrgTileSource::getNumberOfLines(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theNumberOfLines;
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfLines(reduced_res_level);
+   }
+
+   return 0;
+}
+
+ossim_uint32 ossimCibCadrgTileSource::getNumberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theNumberOfSamples;
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfSamples(reduced_res_level);
+   }
+
+   return 0;
+}
+
+void ossimCibCadrgTileSource::setActualImageRect()
+{
+   ossimRpfBoundaryRectRecord boundaryInfo = theEntryToRender->getBoundaryInformation();
+   ossimGpt ul(boundaryInfo.getCoverage().getUlLat(),
+               boundaryInfo.getCoverage().getUlLon());
+//    ossimGpt ll(boundaryInfo.getCoverage().getLlLat(),
+//                boundaryInfo.getCoverage().getLlLon());
+//    ossimGpt ur(boundaryInfo.getCoverage().getUrLat(),
+//                boundaryInfo.getCoverage().getUrLon());
+   ossimGpt lr(boundaryInfo.getCoverage().getLrLat(),
+               boundaryInfo.getCoverage().getLrLon());
+   
+   double latInterval = boundaryInfo.getCoverage().getVerticalInterval();
+   double lonInterval = boundaryInfo.getCoverage().getHorizontalInterval();
+   
+   int lines   = irint(fabs(ul.lat - lr.lat)/latInterval);
+   int samples = irint(fabs(ul.lon - lr.lon)/lonInterval);
+
+
+   theNumberOfLines   = lines;
+   theNumberOfSamples = samples;
+
+   theActualImageRect = ossimIrect(0,0,theNumberOfLines, theNumberOfSamples);
+   
+}
+
+ossimIrect ossimCibCadrgTileSource::getImageRectangle(ossim_uint32 reduced_res_level) const
+{
+   return ossimIrect(0,                         // upper left x
+                     0,                         // upper left y
+                     getNumberOfSamples(reduced_res_level) - 1,  // lower right x
+                     getNumberOfLines(reduced_res_level)   - 1); // lower right y                     
+}
+   
+
+   
+bool ossimCibCadrgTileSource::getImageGeometry(ossimKeywordlist& kwl,
+                                            const char* prefix)
+{
+   if(!theEntryToRender)
+   {
+      return false;
+   }
+
+   if (theGeometryKwl.getSize())
+   {
+      kwl = theGeometryKwl;
+      return true;
+   }
+
+   // datum
+   // WGS 84
+   kwl.add(prefix,
+           ossimKeywordNames::DATUM_KW,
+           "WGE",
+           true);   
+
+   ossimRpfBoundaryRectRecord boundaryInfo = theEntryToRender->getBoundaryInformation();
+
+   ossimGpt ul(boundaryInfo.getCoverage().getUlLat(),
+               boundaryInfo.getCoverage().getUlLon());
+   ossimGpt ll(boundaryInfo.getCoverage().getLlLat(),
+               boundaryInfo.getCoverage().getLlLon());
+   ossimGpt ur(boundaryInfo.getCoverage().getUrLat(),
+               boundaryInfo.getCoverage().getUrLon());
+   ossimGpt lr(boundaryInfo.getCoverage().getLrLat(),
+               boundaryInfo.getCoverage().getLrLon());
+
+   
+//    double latInterval = fabs(ul.latd() - lr.latd())/ getNumberOfLines();
+//    double lonInterval = fabs(ul.lond() - ur.lond())/ getNumberOfSamples();
+   double latInterval = boundaryInfo.getCoverage().getVerticalInterval();
+   double lonInterval = boundaryInfo.getCoverage().getHorizontalInterval();
+
+     
+   // double latInterval = boundaryInfo.getCoverage().getVerticalInterval();
+   // double lonInterval = boundaryInfo.getCoverage().getHorizontalInterval();
+
+   kwl.add(prefix,
+           ossimKeywordNames::UL_LAT_KW,
+           ul.latd(),//-(latInterval/2.0),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::UL_LON_KW,
+           ul.lond(),//+(lonInterval/2.0),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::LL_LAT_KW,
+           ll.latd(),//+(latInterval/2.0),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::LL_LON_KW,
+           ll.lond(),//+(lonInterval/2.0),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::LR_LAT_KW,
+           lr.latd(),//+(latInterval/2.0),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::LR_LON_KW,
+           lr.lond(),//-(lonInterval/2.0),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::UR_LAT_KW,
+           ur.latd(),//-(latInterval/2.0),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::UR_LON_KW,
+           ur.lond(),//-(latInterval/2.0),
+           true);
+   
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_INPUT_BANDS_KW,
+           getNumberOfInputBands(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_OUTPUT_BANDS_KW,
+           getNumberOfOutputBands(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_LINES_KW,
+           getNumberOfLines(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_SAMPLES_KW,
+           getNumberOfSamples(),
+           true);
+   
+
+   //***
+   // Make a projection to get the easting / northing of the tie point and
+   // the scale in meters.  This will only be used by the CIB.
+   //***
+//   const ossimDatum* datum = ossimDatumFactory::instance()->wgs84();
+
+   kwl.add(prefix,
+           ossimKeywordNames::DATUM_KW,
+           "WGE",
+           true);
+
+   ossimGpt origin((ul.latd()+lr.latd())*.5,
+                   (ul.lond()+lr.lond())*.5,
+                   0.0);
+   
+   double deltaLatPerPixel = latInterval;
+   double deltaLonPerPixel = lonInterval;
+   
+   ossimDpt tie;
+
+   tie.lat = boundaryInfo.getCoverage().getUlLat() - deltaLatPerPixel/2.0;
+   tie.lon = boundaryInfo.getCoverage().getUlLon() + deltaLonPerPixel/2.0;
+   
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+           deltaLatPerPixel,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+           deltaLonPerPixel,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::ORIGIN_LATITUDE_KW,
+           origin.latd(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+           origin.lond(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LAT_KW,
+           ul.latd()-(deltaLatPerPixel/2.0),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LON_KW,
+           ul.lond()+(deltaLonPerPixel/2.0),
+           true);
+   
+   
+   int z = boundaryInfo.getZone();
+   
+   if (z == 74) z--; // Fix J to a zone.
+   if (z > 64) z -= 64; // Below the equator
+   else z -= 48; // Above the equator
+   
+   kwl.add(prefix,
+           ossimKeywordNames::ZONE_KW,
+            z,
+            true);
+
+    if(z!=9)
+    {
+       kwl.add(prefix,
+               ossimKeywordNames::TYPE_KW,
+	       "ossimEquDistCylProjection",
+               true);
+    }
+    else
+    {
+       kwl.add(prefix,
+               ossimKeywordNames::TYPE_KW,
+               "ossimAzimEquDistProjection",
+               true);
+    }
+    
+    if(theProductType == OSSIM_PRODUCT_TYPE_CADRG)
+    {
+       
+       ossimString scale = boundaryInfo.getScale();
+       scale = scale.after(":").upcase();
+       scale = scale.trim();
+
+       double scaleValue = 1000000;
+       if(scale == "5M")
+       {
+          scaleValue = 5000000;
+       }
+       else if(scale == "2M")
+       {
+          scaleValue = 2000000;
+       }
+       else if(scale == "1M")
+       {
+          scaleValue = 1000000;
+       }
+       else if(scale == "500K")
+       {
+          scaleValue = 500000;
+       }
+       else if(scale == "250K")
+       {
+          scaleValue = 250000; 
+       }
+       else if(scale == "100K")
+       {
+          scaleValue = 100000; 
+       }
+       else if(scale == "50K")
+       {
+          scaleValue = 50000;
+       }
+       else if(scale == "25K")
+       {
+          scaleValue = 25000;
+       }
+       else if(scale == "20K")
+       {
+          scaleValue = 20000;
+       }
+       else if(scale == "15K")
+       {
+          scaleValue = 15000;
+       }
+       else if(scale == "12,500")
+       {
+          scaleValue = 12500;
+       }
+       else if(scale == "10K")
+       {
+          scaleValue = 10000;
+       }
+       else
+       {
+          cout << "ossimCibCadrgTileSource::getImageGeometry: scale not supported for projection --> " << scale << endl;
+       }
+       
+       kwl.add(prefix,
+               "map_scale",
+               scaleValue,
+               true);        
+    }
+    else if(theProductType ==  OSSIM_PRODUCT_TYPE_CIB)
+    {
+       ossimString scale = boundaryInfo.getScale();
+       scale = scale.upcase();
+       scale = scale.trim('M');
+
+       // from the CIB spec the scale is equivalent to
+       // a CADRG by the following formula
+       //
+       // 100*10^-6/<meter product>
+       //
+       // where <meter product is 10, 5 ....etc
+       //
+       double scaleValue = 1.0/((100.0/1000000.0) / scale.toDouble());
+
+       kwl.add(prefix,
+               "map_scale",
+               scaleValue,
+               true);        
+    }
+
+    setImageGeometry(kwl);
+    
+    return true;
+}
+   
+ossimScalarType ossimCibCadrgTileSource::getOutputScalarType() const
+{
+   return OSSIM_UCHAR;
+}
+
+ossim_uint32 ossimCibCadrgTileSource::getTileWidth() const
+{
+   return theTileSize.x;
+}
+   
+ossim_uint32 ossimCibCadrgTileSource::getTileHeight() const
+{
+   return theTileSize.y;
+}
+
+ossim_uint32 ossimCibCadrgTileSource::getCurrentEntry()const
+{
+   return (ossim_uint32)theEntryNumberToRender;
+}
+
+bool ossimCibCadrgTileSource::setCurrentEntry(ossim_uint32 entryIdx)
+{
+   theGeometryKwl.clear();
+   if(!setEntryToRender(entryIdx))
+   {
+      return false;
+   }
+   completeOpen();
+
+   return true;
+}
+
+void ossimCibCadrgTileSource::getEntryList(std::vector<ossim_uint32>& entryList)const
+{
+   std::vector<ossimString> scaleList = getProductScaleList();
+   ossim_uint32 scaleIdx = 0;
+   ossim_uint32 entryIdx = 0;
+   for(scaleIdx = 0; scaleIdx < scaleList.size(); ++scaleIdx)
+   {
+      std::vector<long> eList = getProductEntryList(scaleList[scaleIdx]);
+      
+      for(entryIdx = 0; entryIdx < eList.size(); ++entryIdx)
+      {
+         entryList.push_back(eList[entryIdx]);
+      }
+   }
+
+}
+
+bool ossimCibCadrgTileSource::setEntryToRender(ossim_uint32 index)
+{
+   if(isOpen())
+   {
+      const ossimRpfTocEntry *temp = theTableOfContents->getTocEntry(index);
+
+      if(temp)
+      {
+         if(!(temp->getBoundaryInformation().getCoverage().isGeographicRectNull()))
+         {
+            setTocEntryToRender(temp);
+            theEntryNumberToRender = index;
+            if(theEntryToRender)
+            {
+               if(theEntryToRender->getProductType().trim().upcase() == "CADRG")
+               {
+                  theProductType = OSSIM_PRODUCT_TYPE_CADRG;
+               }
+               else if(theEntryToRender->getProductType().trim().upcase() == "CIB")
+               {
+                  theProductType = OSSIM_PRODUCT_TYPE_CIB;
+               }
+               else
+               {
+                  theProductType = OSSIM_PRODUCT_TYPE_UNKNOWN;
+               }
+            }
+            
+            populateLut();
+            
+            return true;
+         }
+      }
+   }
+   
+   return false;
+}
+
+void ossimCibCadrgTileSource::setTocEntryToRender(const ossimRpfTocEntry* entry)
+{
+   if(isOpen()&&entry)
+   {
+      // a CIB is 1536x1536 per frame.
+      theEntryToRender = entry;
+      theNumberOfLines   = theEntryToRender->getNumberOfFramesVertical()*CIBCADRG_FRAME_HEIGHT;
+      theNumberOfSamples = theEntryToRender->getNumberOfFramesHorizontal()*CIBCADRG_FRAME_HEIGHT;
+      theEntryNumberToRender = theTableOfContents->getTocEntryIndex(entry);
+   }
+}
+
+ossim_int32 ossimCibCadrgTileSource::getCurrentEntryIndex()const
+{
+   return theEntryNumberToRender;
+}
+
+const ossimRpfTocEntry* ossimCibCadrgTileSource::getCurrentTocEntry()const
+{
+   return theEntryToRender;
+}
+
+const ossimRpfToc*  ossimCibCadrgTileSource::getToc()const
+{
+   return theTableOfContents;
+}
+
+bool ossimCibCadrgTileSource::isValidRLevel(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return true;
+   }
+   else if (theOverview)
+   {
+      return theOverview->isValidRLevel(reduced_res_level);
+   }
+   else
+   {
+      return false;
+   }
+}
+
+vector<ossimString> ossimCibCadrgTileSource::getProductScaleList()const
+{
+   vector<ossimString> result;
+   
+   if(isOpen())
+   {
+      long upperBound = theTableOfContents->getNumberOfEntries();
+      for(long index = 0; index < upperBound; ++index)
+      {
+         const ossimRpfTocEntry* entry = theTableOfContents->getTocEntry(index);
+         ossimString scale = entry->getBoundaryInformation().getScale();
+
+         scale = scale.trim().upcase();
+         if(scale!="")
+         {
+            // CIB will have product scales like 5M or 10M
+            // and CADRG's will have product scales like
+            // 1:50K and 1:250K ...
+            // So if these patterns exist then add it to
+            // the product list.
+            if((std::find(scale.begin(), scale.end(), ':') != scale.end()) ||
+               (scale[(int)scale.size()-1]=='M'))
+            {
+               // only add it if it doesn't already exist
+               // on the list.
+               if(find(result.begin(), result.end(), scale) == result.end())
+               {
+                  result.push_back(scale);
+               }
+            }
+         }
+      }
+   }
+   
+   return result;
+}
+
+vector<long> ossimCibCadrgTileSource::getProductEntryList(const ossimString& productScale)const
+{
+   vector<long> result;
+   
+   if(isOpen())
+   {
+      long upperBound = theTableOfContents->getNumberOfEntries();
+      for(long index = 0; index < upperBound; ++index)
+      {
+         const ossimRpfTocEntry* entry = theTableOfContents->getTocEntry(index);
+
+         if(entry)
+         {
+            // if the entry is not empty then add it to the list.
+            //
+            if(!entry->isEmpty())
+            {
+               ossimString scale = entry->getBoundaryInformation().getScale();
+               scale = scale.trim().upcase();
+               if(scale==productScale)
+               {
+                  result.push_back(index);
+               }
+            }
+         }
+      }
+   }
+
+   return result;
+   
+}
+
+vector<ossimCibCadrgTileSource::ossimFrameEntryData> ossimCibCadrgTileSource::getIntersectingEntries(const ossimIrect& rect)
+{
+   vector<ossimFrameEntryData> result;
+
+   // make sure we have the Toc entry to render
+   if(!isOpen()) return result;
+   
+   ossimIrect imageRect = getImageRectangle();
+   if(rect.intersects(imageRect))
+   {
+      ossimIrect clipRect  = rect.clipToRect(imageRect);
+      ossimIrect frameRect(clipRect.ul().x/CIBCADRG_FRAME_WIDTH,
+                           clipRect.ul().y/CIBCADRG_FRAME_HEIGHT,
+                           clipRect.lr().x/CIBCADRG_FRAME_WIDTH,
+                           clipRect.lr().y/CIBCADRG_FRAME_HEIGHT);
+
+      ossimRpfFrameEntry tempEntry;
+
+      
+     for(long row = frameRect.ul().y; row <= frameRect.lr().y; ++row)
+      {
+         for(long col = frameRect.ul().x; col <= frameRect.lr().x; ++col)
+         {
+            if(theEntryToRender->getEntry((theEntryToRender->getNumberOfFramesVertical()-1) - row,
+                                          col,
+                                          tempEntry))
+            {
+               if(tempEntry.exists())
+               {
+                   result.push_back(ossimFrameEntryData(row,
+                                                        col,
+                                                        row*CIBCADRG_FRAME_HEIGHT,
+                                                        col*CIBCADRG_FRAME_WIDTH,
+                                                        tempEntry));
+               }
+            }
+         }
+      }
+   }
+   
+   return result;
+}
+
+void ossimCibCadrgTileSource::fillTile(const ossimIrect& tileRect,
+                                       const vector<ossimFrameEntryData>& framesInvolved)
+{
+   ossim_uint32 idx = 0;
+   for(idx = 0;
+       idx < framesInvolved.size();
+       ++idx)
+   {
+
+      if(theWorkFrame->parseFile(framesInvolved[idx].theFrameEntry.getFullPath())
+         == ossimErrorCodes::OSSIM_OK)
+      {
+         // we will fill a subtile.  We pass in which frame it is and the position of the frame.
+         // the actual pixel will be 1536*row and 1536 *col.
+         if(theProductType == OSSIM_PRODUCT_TYPE_CIB)
+         {
+            fillSubTileCib(*theWorkFrame,
+                           tileRect,
+                           framesInvolved[idx]);
+         }
+         else
+         {
+            fillSubTileCadrg(*theWorkFrame,
+                             tileRect,
+                             framesInvolved[idx]);
+         }
+      }
+   }
+}
+
+void ossimCibCadrgTileSource::fillSubTileCadrg(const ossimRpfFrame&  aFrame,
+                                               const ossimIrect& tileRect,
+                                               const ossimFrameEntryData& frameEntryData)
+{;
+   // first let's grab the absolute position of the frame rectangle in pixel space
+   ossimIrect frameRect(frameEntryData.thePixelCol,
+                        frameEntryData.thePixelRow,
+                        frameEntryData.thePixelCol + CIBCADRG_FRAME_WIDTH  - 1,
+                        frameEntryData.thePixelRow + CIBCADRG_FRAME_HEIGHT - 1);
+
+   
+   // now clip it to the tile
+   ossimIrect clipRect = tileRect.clipToRect(frameRect);
+   
+   const ossimRpfCompressionSection* compressionSection = aFrame.getCompressionSection();
+   
+   if(!compressionSection)
+   {
+      return;
+   }
+
+   ossim_uint8 *tempRows[3];
+   
+   tempRows[0] = theUncompressedBuffer;
+   tempRows[1] = (theUncompressedBuffer + 256*256);
+   tempRows[2] = (tempRows[1] + 256*256);
+   
+   // find the shift to 0,0
+   ossimIpt tempDelta(clipRect.ul().x - frameEntryData.thePixelCol,
+                      clipRect.ul().y - frameEntryData.thePixelRow);
+   
+   
+   // In order to compute the subframe we will need the corner offsets of
+   // the upper left of the frame and the upper left of the clip rect.  The
+   // clip rect should be completely within the frame.  This just translates the value
+   // to make the upper left of the frame be 0,0.
+   //
+   ossimIrect offsetRect(tempDelta.x,
+                         tempDelta.y,
+                         tempDelta.x + clipRect.width()-1,
+                         tempDelta.y + clipRect.height()-1);
+   
+   // each subframe is 64x64.  We will actually use 256x256 since
+   // we will be uncompressing them.  Note CADRG is a 256x256 tile
+   // compressed to 64x64x12 bit data
+   //
+    ossimIrect subFrameRect(offsetRect.ul().x/256,
+                            offsetRect.ul().y/256,
+                            (offsetRect.lr().x)/256,
+                            (offsetRect.lr().y)/256);
+   
+   ossim_uint32 readPtr  = 0;
+   const vector<ossimRpfColorGrayscaleTable>& colorTable =
+      aFrame.getColorGrayscaleTable();
+   
+   long row = 0;
+   long col = 0;
+   ossim_uint32 i = 0;
+   ossim_uint32 j = 0;
+   long upperY = subFrameRect.lr().y;
+   long upperX = subFrameRect.lr().x;
+   long lowerY = subFrameRect.ul().y;
+   long lowerX = subFrameRect.ul().x; 
+   for(row = lowerY; row <= upperY; ++row)
+   {
+      for(col = lowerX; col <= upperX; ++col)
+      {
+         readPtr = 0;
+         if(aFrame.fillSubFrameBuffer(theCompressedBuffer, 0, row, col))
+         {
+            for (i = 0; i < 256; i += 4)
+            {
+               for (j = 0; j < 256; j += 8)
+               {
+                  ossim_uint16 firstByte  = theCompressedBuffer[readPtr++] & 0xff;
+                  ossim_uint16 secondByte = theCompressedBuffer[readPtr++] & 0xff;
+                  ossim_uint16 thirdByte  = theCompressedBuffer[readPtr++] & 0xff;
+                  
+                  //because dealing with half-bytes is hard, we
+                  //uncompress two 4x4 tiles at the same time. (a
+                  //4x4 tile compressed is 12 bits )
+                  // this little code was grabbed from openmap software.
+                  
+                  /* Get first 12-bit value as index into VQ table */
+                  // I think we need to swap
+                  ossim_uint16 val1 = (firstByte << 4) | (secondByte >> 4);
+                  
+                  /* Get second 12-bit value as index into VQ table*/
+                  ossim_uint16 val2 = ((secondByte & 0x000F) << 8) | thirdByte;
+                  
+                  for (ossim_uint32 t = 0; t < 4; ++t)
+                  {
+                     for (ossim_uint32 e = 0; e < 4; ++e)
+                     {
+                        ossim_uint16 tableVal1 = compressionSection->getTable()[t].theData[val1*4 + e] & 0xff;
+                        ossim_uint16 tableVal2 = compressionSection->getTable()[t].theData[val2*4 + e] & 0xff;
+
+                        ossim_uint32 pixindex = ((i+t)*256) +
+                                                 (j + e);
+                        const ossim_uint8* color1 = colorTable[0].getStartOfData(tableVal1);
+                        const ossim_uint8* color2 = colorTable[0].getStartOfData(tableVal2);
+                        
+                        
+                        tempRows[0][pixindex] = color1[0];
+                        tempRows[1][pixindex] = color1[1];
+                        tempRows[2][pixindex] = color1[2];
+                        
+                        tempRows[0][pixindex+4] = color2[0];
+                        tempRows[1][pixindex+4] = color2[1];
+                        tempRows[2][pixindex+4] = color2[2];
+                     } //for e
+                  } //for t
+               }  /* for j */
+            } //for i
+         }
+         else
+         {
+            memset(theUncompressedBuffer, 0, 256*256*3);
+         }
+         long tempCol = col*256;
+         long tempRow = row*256;
+         ossimIrect subRectToFill(frameRect.ul().x + tempCol,
+                                  frameRect.ul().y + tempRow,
+                                  frameRect.ul().x + tempCol + 255,
+                                  frameRect.ul().y + tempRow + 255);
+         theTile->loadTile(theUncompressedBuffer,
+                              subRectToFill,
+                              OSSIM_BSQ);
+      }
+   }
+}
+
+void ossimCibCadrgTileSource::fillSubTileCib(const ossimRpfFrame&  aFrame,
+                                               const ossimIrect& tileRect,
+                                               const ossimFrameEntryData& frameEntryData)
+{
+   // first let's grab the absolute position of the frame rectangle in pixel space
+   ossimIrect frameRect(frameEntryData.thePixelCol,
+                        frameEntryData.thePixelRow,
+                        frameEntryData.thePixelCol + CIBCADRG_FRAME_WIDTH  - 1,
+                        frameEntryData.thePixelRow + CIBCADRG_FRAME_HEIGHT - 1);
+
+   
+   // now clip it to the tile
+   ossimIrect clipRect = tileRect.clipToRect(frameRect);
+
+   const ossimRpfCompressionSection* compressionSection = aFrame.getCompressionSection();
+   
+   if(!compressionSection)
+   {
+      return;
+   }
+
+   // check to see if it does overlap.  If it doesn't then the width and height
+   // will be a single point
+   {
+      ossim_uint8 *tempRow;
+
+      tempRow = theUncompressedBuffer;
+      
+      // find the shift to 0,0
+      ossimIpt tempDelta(clipRect.ul().x - frameEntryData.thePixelCol,
+                         clipRect.ul().y - frameEntryData.thePixelRow);
+      
+      // In order to compute the subframe we will need the corner offsets of
+      // the upper left of the frame and the upper left of the clip rect.  The
+      // clip rect should be completely within the frame.  This just translates the value
+      // to make the upper left of the frame be 0,0.
+      //
+      ossimIrect offsetRect(tempDelta.x,
+                            tempDelta.y,
+                            tempDelta.x + clipRect.width()-1,
+                            tempDelta.y + clipRect.height()-1);
+
+      // each subframe is 64x64.  We will actually use 256x256 since
+      // we will be uncompressing them.  Note CADRG is a 256x256 tile
+      // compressed to 64x64x12 bit data
+      //
+      ossimIrect subFrameRect(offsetRect.ul().x/256,
+                              offsetRect.ul().y/256,
+                              (offsetRect.lr().x)/256,
+                              (offsetRect.lr().y)/256);
+
+      const vector<ossimRpfColorGrayscaleTable>& colorTable =
+                                        aFrame.getColorGrayscaleTable();
+
+      long row = 0;
+      long col = 0;
+      ossim_uint32 i = 0;
+      ossim_uint32 j = 0;
+      ossim_uint32 readPtr = 0;
+      for(row = subFrameRect.ul().y; row <= subFrameRect.lr().y; ++row)
+      {
+         for(col = subFrameRect.ul().x; col <= subFrameRect.lr().x; ++col)
+         {
+            readPtr = 0;
+            if(aFrame.fillSubFrameBuffer(theCompressedBuffer, 0, row, col))
+            {
+               for (i = 0; i < 256; i += 4)
+               {
+                  for (j = 0; j < 256; j += 8)
+                  {
+                     ossim_uint16 firstByte  = theCompressedBuffer[readPtr++] & 0xff;
+                     ossim_uint16 secondByte = theCompressedBuffer[readPtr++] & 0xff;
+                     ossim_uint16 thirdByte  = theCompressedBuffer[readPtr++] & 0xff;
+                     
+                     //because dealing with half-bytes is hard, we
+                     //uncompress two 4x4 tiles at the same time. (a
+                     //4x4 tile compressed is 12 bits )
+                     // this little code was grabbed from openmap software.
+                     
+                     /* Get first 12-bit value as index into VQ table */
+                     // I think we need to swap
+                     ossim_uint16 val1 = (firstByte << 4) | (secondByte >> 4);
+                     
+                     /* Get second 12-bit value as index into VQ table*/
+                     ossim_uint16 val2 = ((secondByte & 0x000F) << 8) | thirdByte;
+
+                     for (ossim_uint32 t = 0; t < 4; ++t)
+                     {
+                        for (ossim_uint32 e = 0; e < 4; ++e)
+                        {
+                           ossim_uint16 tableVal1 = compressionSection->getTable()[t].theData[val1*4 + e] & 0xff;
+                           ossim_uint16 tableVal2 = compressionSection->getTable()[t].theData[val2*4 + e] & 0xff;
+
+                           ossim_uint32 pixindex = ((i+t)*256) + (j + e);
+                           const ossim_uint8* color1 = colorTable[0].getStartOfData(tableVal1);
+                           const ossim_uint8* color2 = colorTable[0].getStartOfData(tableVal2);
+
+                           
+                           tempRow[pixindex]      = color1[0];
+                           tempRow[pixindex + 4]  = color2[0];
+                        } //for e
+                     } //for t
+                  }  /* for j */
+               } //for i
+            }
+            else
+            {
+               memset(theUncompressedBuffer, 0, 256*256);
+            }
+            long tCol = col*256;
+            long tRow = row*256;
+            ossimIrect subRectToFill(frameRect.ul().x + tCol,
+                                     frameRect.ul().y + tRow,
+                                     frameRect.ul().x + tCol + 255,
+                                     frameRect.ul().y + tRow + 255);
+            theTile->loadTile(theUncompressedBuffer,
+                              subRectToFill,
+                              OSSIM_BSQ);
+         }
+      }
+   }  
+}
+
+void ossimCibCadrgTileSource::allocateForProduct()
+{
+   if(theProductType ==  OSSIM_PRODUCT_TYPE_UNKNOWN)
+   {
+      return;
+   }
+   if(theUncompressedBuffer)
+   {
+      delete [] theUncompressedBuffer;
+      theUncompressedBuffer = NULL;
+   }
+   if(theCompressedBuffer)
+   {
+      delete [] theCompressedBuffer;
+      theCompressedBuffer = NULL;
+   }
+   
+   // a CADRG and CIBis a 64*64*12 bit buffer and must divide by 8 to
+   // convert to bytes
+   theCompressedBuffer   = new ossim_uint8[(64*64*12)/8];
+   if(theProductType == OSSIM_PRODUCT_TYPE_CIB)
+   {
+      theUncompressedBuffer = new ossim_uint8[256*256];
+   }
+   else
+   {
+      theUncompressedBuffer = new ossim_uint8[256*256*3];
+   }
+   
+   theTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile->initialize();
+}
+
+const ossimRpfTocEntry* ossimCibCadrgTileSource::findFirstFrame()
+{
+   vector<ossimString> products = getProductScaleList();
+   vector<long> indexProducts;
+
+   if(products.size() > 0)
+   {
+      indexProducts = getProductEntryList(products[0]);
+
+      if(indexProducts.size()>0)
+      {
+         theEntryNumberToRender = indexProducts[0];
+         
+         return theTableOfContents->getTocEntry(indexProducts[0]);
+      }
+   }
+   
+   return NULL;
+}
+
+
+void ossimCibCadrgTileSource::deleteAll()
+{
+   if(theOverview)
+   {
+      delete theOverview;
+      theOverview = NULL;
+   }
+   if(theTableOfContents)
+   {
+      delete theTableOfContents;
+      theTableOfContents = NULL;
+   }
+}
+
+bool ossimCibCadrgTileSource::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix)const
+{
+   bool result = ossimImageHandler::saveState(kwl, prefix);
+
+   kwl.add(prefix, 
+	   "entry",
+	   theEntryNumberToRender,
+	   true);
+
+   return result;
+}
+   
+bool ossimCibCadrgTileSource::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   const char* MODULE = "ossimCibCadrgTileSource::loadState";
+
+   if(traceDebug())
+   {
+      CLOG << "Entering..." << endl;
+   }
+   bool result = ossimImageHandler::loadState(kwl, prefix);
+
+   if(!result)
+   {
+      return false;
+   }
+   const char* lookup = NULL;
+   
+   lookup = kwl.find(prefix, "entry");
+   long entry = ossimString(lookup).toLong();
+
+   // if an entry is specified then
+   // call the open with an entry number
+   if(lookup)
+   {
+      if(traceDebug())
+      {
+         CLOG << "Leaving..." << endl;
+      }
+      result = ossimImageHandler::open(theImageFile);
+      setCurrentEntry(entry);
+      return result;
+   }
+
+   result = ossimImageHandler::open(theImageFile);
+   
+   return result;
+}
+
+ossim_uint32 ossimCibCadrgTileSource::getImageTileWidth() const
+{
+   return 256;
+}
+
+ossim_uint32 ossimCibCadrgTileSource::getImageTileHeight() const
+{
+   return 256;
+}
+
+bool ossimCibCadrgTileSource::isCib() const
+{
+   return (theProductType==OSSIM_PRODUCT_TYPE_CIB);
+}
+
+bool ossimCibCadrgTileSource::isCadrg() const
+{
+   return (theProductType==OSSIM_PRODUCT_TYPE_CADRG);
+}
+
+ossimString ossimCibCadrgTileSource::getProductScale() const
+{
+   ossimString result;
+   
+   const ossimRpfTocEntry* entry =
+      theTableOfContents->getTocEntry(theEntryNumberToRender);
+
+   if (entry)
+   {
+      result = entry->getBoundaryInformation().getScale();
+   }
+
+   return result;
+}
+
+ossimString ossimCibCadrgTileSource::getSecurityClassification()const
+{
+   ossimString result;
+   
+   const ossimRpfHeader* header =
+      theTableOfContents->getRpfHeader();
+
+   if (header)
+   {
+      result = header->getSecurityClassification();
+   }
+
+   return result;
+}
+
+void ossimCibCadrgTileSource::populateLut()
+{
+   theLut = 0;
+   if(theEntryToRender)
+   {
+      ossim_uint32 w = theEntryToRender->getNumberOfFramesHorizontal();
+      ossim_uint32 h = theEntryToRender->getNumberOfFramesVertical();
+      ossim_uint32 wi, hi;
+      bool found = false;
+      ossimRpfFrameEntry tempEntry;
+      ossimRpfFrame aFrame;
+      for(wi = 0; ((wi < w)&&(!found)); ++wi)
+      {
+         for(hi = 0; ((hi < h)&&(!found)); ++hi)
+         {
+            theEntryToRender->getEntry(hi,
+                                       wi,
+                                       tempEntry);
+            if(tempEntry.getFullPath().exists())
+            {
+               found = true;
+            }
+         }
+      }
+      if(aFrame.parseFile(tempEntry.getFullPath())
+         == ossimErrorCodes::OSSIM_OK)
+      {
+         const vector<ossimRpfColorGrayscaleTable>& colorTable =
+            aFrame.getColorGrayscaleTable();
+
+         ossim_uint32 numElements = colorTable[0].getNumberOfElements();
+         if(numElements > 0)
+         {
+            if((theProductType == OSSIM_PRODUCT_TYPE_CIB)||
+               (theProductType == OSSIM_PRODUCT_TYPE_CADRG))
+            {
+               theLut = new ossimNBandLutDataObject(numElements,
+                                                    3,
+                                                    OSSIM_UINT8);
+            }
+            else
+            {
+               theLut = 0;
+               return;
+            }
+            ossim_uint32 idx = 0;
+
+            for(idx = 0; idx < numElements;++idx)
+            {
+               const ossim_uint8* startOfData = colorTable[0].getStartOfData(idx);
+               switch(theProductType)
+               {
+                  case OSSIM_PRODUCT_TYPE_CIB:
+                  {
+                     (*theLut)[idx][0] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[0]);
+                     (*theLut)[idx][1] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[0]);
+                     (*theLut)[idx][2] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[0]);
+                     break;
+                  }
+                  case OSSIM_PRODUCT_TYPE_CADRG:
+                  {
+                     (*theLut)[idx][0] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[0]);
+                     (*theLut)[idx][1] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[1]);
+                     (*theLut)[idx][2] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(startOfData[2]);
+                     break;
+                  }
+                  default:
+                  {
+                     break;
+                  }
+               }
+            }
+         }
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/ossimCibCadrgTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/ossimCibCadrgTileSource.h
new file mode 100644
index 0000000000..884892f575
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/cibcadrg/ossimCibCadrgTileSource.h
@@ -0,0 +1,574 @@
+//-----------------------------------------------------------------------
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+// Description: This class give the capability to access tiles from an
+//              CADRG file.
+//
+//-----------------------------------------------------------------------
+//$Id: ossimCibCadrgTileSource.h,v 1.39 2005/08/29 19:34:28 gpotts Exp $
+#ifndef ossimCibCadrgTileSource_HEADER
+#define ossimCibCadrgTileSource_HEADER
+#include <imaging/formats/ossimImageHandler.h>
+#include <support_data/rpf/ossimRpfFrameEntry.h>
+
+class ossimRpfToc;
+class ossimRpfTocEntry;
+class ossimRpfFrame;
+
+/**
+ * Cib/Cadrg fromats are encoded the same except that the CIB is a grey
+ * scale image and the CADRG is a color image.  Both are VQ compressed.
+ * The images are encoded into an NITF format with embedded RPF headers.
+ * It reads the embedded RPF tags from the NITF file and parses the data.
+ * It allows for you to select which CIB/CADRG entry to render.  The handler
+ * is opened by giving it the associated a.toc file.  This is a table of
+ * contents file that describes all the entries found in the CIB/CADARD
+ * product.  You must set which entry you wish to render.  By default it
+ * will render the first product it comes to.
+ *
+ * Note:  This handler will eventually merge into the nitf handler.
+ */
+class OSSIMDLLEXPORT ossimCibCadrgTileSource : public ossimImageHandler
+{
+public:
+   friend class ossimMultiEntryCibCadrg;
+
+   /**
+    * Basic enumeration.  This should
+    * be either a CIB or a CADRG product
+    * type.
+    */
+   enum ossimCibCadrgProductType
+   {
+      OSSIM_PRODUCT_TYPE_UNKNOWN = 0,
+      OSSIM_PRODUCT_TYPE_CIB     = 1,
+      OSSIM_PRODUCT_TYPE_CADRG   = 2
+   };
+
+   /**
+    * Default constructor.
+    *
+    * Initializes all internal attributes to a default state.
+    */
+   ossimCibCadrgTileSource();
+
+   /**
+    * Destructor.
+    *
+    * Will return allocated memory back to the heap.
+    */
+   virtual ~ossimCibCadrgTileSource();
+
+   /**
+    * This method is defined in the base class ossimObject.
+    * This class overrides the default implementation
+    * to return its own short name.
+    * 
+    * @return The short name for this class as an ossimString.
+    */
+   virtual ossimString getShortName()const;
+
+   /**
+    * This method is defined in the base class ossimObject.
+    * This class overrides the default implementation
+    * to return its own long name.
+    * 
+    * @return The long name for this class as an ossimString.
+    */
+   virtual ossimString getLongName()const;
+
+   /**
+    * Closes this image handler and deletes any allocated data.
+    */
+   virtual void close();
+   
+   /**
+    */
+   virtual bool open();
+   /**
+    *  Returns a pointer to an ossimImageDataObject given a rectangluar
+    *  region of interest.
+    *
+    *  @param rect The region of interest to return.
+    *  @param resLevel From which resolution set are we querying
+    *  (default is 0 full res).
+    *
+    *  @return The ossimImageData object to the caller.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& rect,
+                                               ossim_uint32 resLevel = 0);
+
+   /**
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    *
+    *  @param reduced_res_level The reduced res level to query number of lines from.
+    *  @return The number of lines in the image.
+    */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    *
+    *  @param reduced_res_level The reduced res level to query number of samples from.
+    *  @return The number of samples in the image.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
+
+   /**
+    * @param reduced_res_level Which res level to get the bounds for.  0 represents
+    *                          the default and is the full resolution.
+    * 
+    * @return A rectangle representing the bounds for the passed in resolution level.
+    */
+   virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    *
+    * Saving data without a prefix.
+    * @code
+    *  ossimCibCadrgTileSource* cibCadrgHandler = new ossimCibCadrgTileSource;
+    *  ossimKeywordlist kwl;
+    *  cibCadrgHandler->open(filename);
+    *  cibCadrgHandler->saveState(kwl);
+    * @endcode
+    *
+    * and saving data with a prefix.
+    * @code
+    *  ossimCibCadrgTileSource* cibCadrgHandler = new ossimCibCadrgTileSource;
+    *  ossimKeywordlist kwl;
+    *  cibCadrgHandler->open(filename);
+    *  cibCadrgHandler->saveState(kwl, "handler1.");
+    * @endcode
+    *
+    * Saving with a prefix will help uniquely identify objects in the kwl.
+    * To see what is in the keywordlist after a save state then do:
+    *
+    * @code
+    * cout << kwl << endl;
+    * @endcode
+    *
+    * There is only 1 keyword for this object:
+    * 
+    * entry: <entry number>
+    *
+    * where <entry number> is the index value for the current entry.
+    *
+    * @see ossimImageHandler for additional keywords.
+    *
+    * @param kwl Keywordlist to save the state of the object to.
+    * @param prefix prefix to prepend to the keywords.  This will
+    *               help uniquely identify each keyword if multiple
+    *               objects are saved to the same list.
+    * @return True if successfully saved the state of the object and
+    *         false otherwise.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to load the state of an object from a keyword list.
+    *
+    * Loading with a prefix.
+    * @code
+    *  cibCadrgHandler->laodState(kwl, "handler1.");
+    * @endcode
+    * 
+    * Loading without a prefix.
+    * @code
+    *  cibCadrgHandler->laodState(kwl);
+    * @endcode
+    *
+    * Since all objects are factory created you can go through the
+    * registry and pass the keyword list in.
+    * @code
+    * ossimImageHandler* handler = ossimImageHandlerRegistry::instance()->open(kwl, prefix);
+    * @endcode
+    * 
+    * @param kwl Keywordlist that holds the state information for this
+    *            object.
+    *
+    *
+    * @param prefix prefix value prepended to all keywords to uniquely
+    *                      locate the state attributes for this object.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /**
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *  Returns true if geometry info is present, false if not.
+    *  Keywords supported by this object are:
+    *  @verbatim
+    *  datum:    // datum code>   // Datum code
+    *  ul_lat:   // upper left latitude
+    *  ul_lon:   // upper left longitude
+    *  ll_lat:   // lower left latitude
+    *  ll_lon:   // lower left longitude
+    *  lr_lat:   // lower right latitude
+    *  lr_lon:   // lower right longitude
+    *  ur_lat:   // upper right latitude
+    *  ur_lon:   // upper right longitude
+    *  number_input_bands:     
+    *  number_output_bands:    
+    *  number_lines:           
+    *  number_samples:
+    *  decimal_degrees_per_pixel_lat:  // specifies the spacing per pixel along Y direction
+    *  decimal_degrees_per_pixel_lon:  // specifies the spacing per pixel along X direction
+    *  origin_latitude:                // specifies the origin or center of the projector for the latitude
+    *  central_meridian:               // specifies the origin or center of the projector for the longitude
+    *  tie_point_lat:     // tie point lat.  Represents the latitude of the upper left center of pixel
+    *  tie_point_lon:     // tie point lon.  Represents the longitude of the upper left center of pixel
+    *  zone:              // zone read from the CIB/CADRG boundary info
+    *  type:              // class name of the object for factory driven reconstruction
+    *  map_scale:         // Map scale of the image
+    *  @endverbatim
+    *  @see ossimImageSource for further code example on using the geometry
+    *       information in kwl.
+    *  @param kwl Keywordlist to populate the image geometry with.
+    *  @param prefix A unique prefix to prepend to the keywords.
+    *    
+    *  @return True if image geometry is present and false otherwise.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+   
+   /**
+    * This method allows you to query the scalar type of the output data.
+    * This is simply the data type, i.e. whether its OSSIM_FLOAT, OSSIM_DOUBLE,
+    * OSSIM_UCHAR, ... etc.  This means that if there are bands of different
+    * scalar types from a single image then they must be casted to the highest
+    * precision type. @see ossimConstants.h for all ossimScalarType.
+    * 
+    * @return The output scalar type.
+    *         
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * This method allows you to query the number of input bands.  If an image
+    * is band selectable this will allow one to select the bands you wish
+    * to read in.  This indicates that the number of input bands might not
+    * match the number of output bands.
+    * @return number of input bands.
+    */
+   virtual ossim_uint32 getNumberOfInputBands()const;
+
+   /**
+    * This method allows one to query the number of output bands.  This might not
+    * be the same as the n umber of input bands.
+    *
+    * @see getNumberOfInputBands().
+    * @return number of output bands.
+    */
+   virtual ossim_uint32 getNumberOfOutputBands()const;
+   
+   /**
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32 getTileWidth() const;
+   
+   /**
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;
+
+   virtual ossim_uint32 getCurrentEntry()const;
+   virtual bool setCurrentEntry(ossim_uint32 entryIdx);
+   virtual void getEntryList(std::vector<ossim_uint32>& entryList)const;
+   
+
+   /**
+    * Returns -1 if invalid
+    */
+   virtual ossim_int32 getCurrentEntryIndex()const;
+   
+   /**
+    * @return The current entry being rendered
+    */
+   virtual const ossimRpfTocEntry* getCurrentTocEntry()const;
+
+   /**
+    * @return The table of contents object.
+    */
+   virtual const ossimRpfToc*      getToc()const;
+
+   /**
+    * @param reduced_res_level passed in resolution level.
+    * @return True if the reduced_res_level is within an acceptable range
+    *         and false otherwise.
+    */
+   bool isValidRLevel(ossim_uint32 reduced_res_level) const;
+
+   /**
+    * Determines if its open if there eists a table of contents object.
+    * 
+    * @return True if the handler is open and flase otherwise.
+    */
+   bool isOpen()const;
+
+   /** @return true if CIB */
+   bool isCib() const;
+
+   /** @return true if CADRG */
+   bool isCadrg() const;
+
+   /** @return Scale string ( like 1:24000 ) for current entry. */
+   ossimString getProductScale() const;
+
+   /**
+    * This retrieves all product scales that are within the Table of contents.
+    * I make no assumptions that a CIB/CADRG has only one product.  A product
+    * here is 1meter, 5 meter, 10 meter ... etc for CIB and 1:24000, 1:50000,
+    * ... etc for CADRG.
+    *
+    * @return The prduct list as a vector of strings.
+    */
+   vector<ossimString> getProductScaleList()const;
+
+   /**
+    * Using the product scales from getProductScaleList() you can pass each string
+    * in so you can get all associated indices for a given product.
+    * 
+    * @return Entry indices for a passed in product scale.
+    */
+   vector<long>      getProductEntryList(const ossimString& productScale)const;
+
+   ossimString getSecurityClassification()const;
+   
+   /**
+    * CONSTANT representing the width of a Frame.  This should be 1536.
+    */
+   static const ossim_uint32 CIBCADRG_FRAME_WIDTH;
+   
+   /**
+    * CONSTANT representing the height of a Frame.  This should be 1536.
+    */
+   static const ossim_uint32 CIBCADRG_FRAME_HEIGHT;
+   
+protected:
+
+   /**
+    * Sets the entry to be renderer.  The entry within the table
+    * of contents are stored in an Toc entry object.
+    *
+    * @param entry the Rpf toc entry object to set to.
+    */
+   virtual void setTocEntryToRender(const ossimRpfTocEntry* entry);
+
+
+   /**
+    * Will shift the rect and clamp it so not to go outside the -180 to 180
+    * degree range.
+    */
+   void setActualImageRect();
+   
+   /**
+    * Protected structure that is only used internally by this class.
+    * 
+    * This is used to establish which entry data is being used.
+    * all we need is the ro, col of the entry.  We can compute the
+    * image rect from this since the CibCadrg are 1536x1536 frame.
+    * 
+    */
+   struct ossimFrameEntryData
+   {
+      ossimFrameEntryData()
+         :theRow(-1),
+          theCol(-1),
+          thePixelRow(-1),
+          thePixelCol(-1)
+         {}
+      ossimFrameEntryData(long row,
+                          long col,
+                          long pixelRow,
+                          long pixelCol,
+                          const ossimRpfFrameEntry& entry)
+         :theRow(row),
+          theCol(col),
+          thePixelRow(pixelRow),
+          thePixelCol(pixelCol),
+          theFrameEntry(entry)
+         {}
+      ossimFrameEntryData(const ossimFrameEntryData& rhs)
+         :theRow(rhs.theRow),
+          theCol(rhs.theCol),
+          thePixelRow(rhs.thePixelRow),
+          thePixelCol(rhs.thePixelCol),
+          theFrameEntry(rhs.theFrameEntry)
+         {}
+      long theRow;
+      long theCol;
+      long thePixelRow;
+      long thePixelCol;
+      ossimRpfFrameEntry theFrameEntry;
+   };
+
+   /**
+    * Sets the entry to render.
+    *
+    */
+   virtual bool setEntryToRender(ossim_uint32 index);
+   
+   /**
+    * It is important to note that each frame is organized into an easting northing
+    * type orientation.  This means that a frame at 0,0 is at the lower left corner.
+    * Each frame's pixel data is has 0,0 at the upper left.
+    *
+    * It will take the curent region to render and then find all entries that intersect
+    * that region.
+    *
+    * @param rect the current region to render.
+    * @return The list of entry data objects found for this rect.
+    */
+   vector<ossimFrameEntryData> getIntersectingEntries(const ossimIrect& rect);
+
+   /**
+    * This is a wrapper for the fill cib and fill cadrg.  It takes the frames
+    * involved that were found in the getIntersectingEntries and call the
+    * appropriate fill cib or fill cadrg on each frame entry data.  It will
+    * loop through making sure that the frame file exists before calling
+    * the associated fill routines.
+    *
+    * @param tileRect Region to fill.
+    * @param framesInvolved All intersecting frames used to render the region.
+    */
+   void fillTile(const ossimIrect& tileRect,
+                 const vector<ossimFrameEntryData>& framesInvolved);
+
+   /**
+    * Will uncompress the CIB file using a VQ decompression algorithm.
+    *
+    * @param aFrame Frame that overlaps the requested tile rect.
+    * @param tileRect The region requested to render.
+    * @param frameEntryData The frame entry data.
+    */
+   void fillSubTileCib(const ossimRpfFrame& aFrame,
+                       const ossimIrect& tileRect,
+                       const ossimFrameEntryData& frameEntryData);
+   
+   /**
+    * Will uncompress the CADRG file using a VQ decompression algorithm.
+    *
+    * @param aFrame Frame that overlaps the requested tile rect.
+    * @param tileRect The region requested to render.
+    * @param frameEntryData The frame entry data.
+    */
+   void fillSubTileCadrg(const ossimRpfFrame& aFrame,
+                         const ossimIrect& tileRect,
+                         const ossimFrameEntryData& frameEntryData);
+   
+   /**
+    * Will allocate an internal buffer for the given product.  If the product is
+    * a CIB then it is a single band OSSIM_UCHAR buffer and if its a CADRG it
+    * is a 3 band OSSIM_UCHAR buffer.
+    */
+   void allocateForProduct();
+   
+   /**
+    * This will search each entry in the table and look for a certain
+    * entry.  The first entry it comes to that has Geographic coverage
+    * will be the frame to render.  This method is best here instead of
+    * in the ossimRpfToc.  I am not sure, but I feel these types of
+    * searches are specific to the product (CADRG, CIB ...).  This
+    * is called immediately after a succesful open of the ossimRpfToc
+    */
+   const ossimRpfTocEntry* findFirstFrame();
+
+   void deleteAll();
+
+   void populateLut();
+
+   /**
+    * This holds the image bounds for the current entry.
+    */
+   ossimIrect                  theActualImageRect;
+   
+   /**
+    * This is for storage of a single compressed buffer.
+    */
+   unsigned char*               theCompressedBuffer;
+
+   /**
+    * This is used as a buffer to uncompress the data to
+    */
+   unsigned char*               theUncompressedBuffer;
+   
+   /**
+    * This will be computed based on the frames organized within
+    * the directory.  The CibCadrg have fixed size frames of 1536x1536
+    * and we must count how many there are.  
+    */
+   unsigned long                theNumberOfLines;
+
+   /**
+    * This will be computed based on the frames organized within
+    * the directory.  The CibCadrg have fixed size frames of 1536x1536
+    * and we must count how many there are.  
+    */
+   unsigned long                theNumberOfSamples;
+   
+   /**
+    * This is the actual data returned from a getTile request.
+    */
+   ossimRefPtr<ossimImageData>  theTile;
+
+   /**
+    * Will own a table of contents.  This describes all entries within
+    * the CIB/CADRG.
+    */
+   ossimRpfToc*                 theTableOfContents;
+
+   /**
+    * This is the actual frame file to render.  This should be
+    * divided into frames where each frame is 1536x1536 in
+    * size.
+    */
+   const ossimRpfTocEntry*      theEntryToRender;
+
+   /**
+    * This will be the entry number that we are currently
+    * rendering.  This will mainly be used when using
+    * overviews.
+    */
+   long                          theEntryNumberToRender;
+   
+   /**
+    * The size of the output tile.
+    */
+   ossimIpt                     theTileSize;
+
+   /**
+    * Holds the enumeration specifying the product type.
+    * The product type can be a CIB or a CADRG product.
+    */
+   ossimCibCadrgProductType     theProductType;
+   
+   mutable ossimRpfFrame*       theWorkFrame;
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimCibCadrgTileSource_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/doqq/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/doqq/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/doqq/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/doqq/ossimDoqqTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/doqq/ossimDoqqTileSource.cpp
new file mode 100644
index 0000000000..75d35ff52b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/doqq/ossimDoqqTileSource.cpp
@@ -0,0 +1,222 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimDoqqTileSource.cpp,v 1.16 2005/11/08 18:25:52 gpotts Exp $
+#include <imaging/formats/doqq/ossimDoqqTileSource.h>
+#include <support_data/doqq/ossimDoqq.h>
+#include <imaging/formats/general_raster/ossimGeneralRasterInfo.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+
+RTTI_DEF1(ossimDoqqTileSource,
+          "ossimDoqqTileSource",
+          ossimGeneralRasterTileSource);
+
+ossimDoqqTileSource::ossimDoqqTileSource()
+   :theHeaderInformation(0)
+{
+}
+
+ossimDoqqTileSource::~ossimDoqqTileSource()
+{
+   theHeaderInformation = 0;
+}
+
+bool ossimDoqqTileSource::open(const ossimFilename& filename)
+{
+   bool result = false;
+   
+   theHeaderInformation = new ossimDoqq(filename);
+   if(theHeaderInformation->errorStatus() == ossimDoqq::OSSIM_ERROR)
+   {
+      theHeaderInformation = 0;
+      
+      return result;
+   }
+   else
+   {
+     // Set the Acquisition Date
+     theAcqDate = theHeaderInformation->theAcqYear;
+     theAcqDate += "-";
+     theAcqDate += theHeaderInformation->theAcqMonth;
+     theAcqDate += "-";
+     theAcqDate += theHeaderInformation->theAcqDay;
+
+     vector<ossimFilename> f;
+     f.push_back(filename);
+     ossimGeneralRasterInfo genRasterInfo(f,
+					  OSSIM_UCHAR,
+					  OSSIM_BIP,
+					  theHeaderInformation->theRgb,
+					  theHeaderInformation->theLine,
+					  theHeaderInformation->theSample,
+					  theHeaderInformation->theHeaderSize,
+					  ossimGeneralRasterInfo::NONE,
+					  0);
+     
+     result = ossimGeneralRasterTileSource::open(genRasterInfo);
+   }
+
+   return result;
+}
+
+bool ossimDoqqTileSource::getImageGeometry(ossimKeywordlist& kwl,
+                                           const char* prefix)
+{
+   if (theGeometryKwl.getSize())
+   {
+      kwl = theGeometryKwl;
+      return true;
+   }
+   
+   if(theHeaderInformation.valid())
+   {
+      ossimString proj  = theHeaderInformation->theProjection.trim().upcase();
+      ossimString datum = theHeaderInformation->theDatum.trim().upcase();
+
+      if(proj == ossimString("UTM") || proj == ossimString("1"))
+      {
+         kwl.add(prefix,
+                 ossimKeywordNames::TYPE_KW,
+                 "ossimUtmProjection",
+                 true);
+         kwl.add(prefix,
+                 ossimKeywordNames::ZONE_KW,
+                 theHeaderInformation->theUtmZone,
+                 true);
+      }
+      else
+      {
+         return false;
+      }
+
+      if(datum == ossimString("NAR") || datum == ossimString("4"))
+      {
+         kwl.add(prefix,
+                 ossimKeywordNames::DATUM_KW,
+                 "NAR-C", // North American Conus 1983
+                 true);
+      }
+      else if(datum == ossimString("NAS") || datum == ossimString("1"))
+      {
+         kwl.add(prefix,
+                 ossimKeywordNames::DATUM_KW,
+                 "NAS-C", // North American Conus 1927
+                 true);
+      }
+      else if(datum == ossimString("2"))
+      {
+         kwl.add(prefix,
+                 ossimKeywordNames::DATUM_KW,
+                 "WGD", // WGS 72
+                 true);
+      }
+      else if(datum == ossimString("3"))
+      {
+         kwl.add(prefix,
+                 ossimKeywordNames::DATUM_KW,
+                 "WGE", // WGS 84
+                 true);
+      }
+      else
+      {
+         return false;
+      }
+
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+              theHeaderInformation->theGsd.x,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+              theHeaderInformation->theGsd.y,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_EASTING_KW,
+//            theHeaderInformation->theUE + (theHeaderInformation->theGsd/2.0),
+	      theHeaderInformation->theEasting,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_NORTHING_KW,
+//            theHeaderInformation->theUN - (theHeaderInformation->theGsd/2.0),
+	      theHeaderInformation->theNorthing,
+              true);
+
+      // Capture this for next time.
+      setImageGeometry(kwl);
+      
+      return true;
+   }
+   return false;
+}
+
+bool ossimDoqqTileSource::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   const char* lookup = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   if(!ossimImageHandler::loadState(kwl, prefix))
+   {
+      return false;
+   }
+
+   if(lookup)
+   {
+      theHeaderInformation = new ossimDoqq(ossimFilename(lookup));
+      if(theHeaderInformation->errorStatus() != ossimDoqq::OSSIM_OK)
+      {
+         theHeaderInformation = 0;
+         return false;
+      }
+      else
+      {
+         ossimFilename filename(lookup);
+         vector<ossimFilename> f;
+         f.push_back(filename);
+         ossimGeneralRasterInfo genRasterInfo(f,
+                                              OSSIM_UCHAR,
+                                              OSSIM_BIP,
+                                              theHeaderInformation->theRgb,
+                                              theHeaderInformation->theLine,
+                                              theHeaderInformation->theSample,
+                                              theHeaderInformation->theHeaderSize,
+                                              ossimGeneralRasterInfo::NONE,
+                                              0);
+         return open(genRasterInfo);
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   return true;
+}
+
+ossimString ossimDoqqTileSource::getShortName()const
+{
+   return ossimString("doqq");
+}
+
+ossimString ossimDoqqTileSource::getLongName()const
+{
+   return ossimString("doqq handler");
+}
+
+bool ossimDoqqTileSource::open(const ossimGeneralRasterInfo& info)
+{
+   return ossimGeneralRasterTileSource::open(info);
+}
+
+ossimString ossimDoqqTileSource::acqdate() const
+{
+   return theAcqDate;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/doqq/ossimDoqqTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/doqq/ossimDoqqTileSource.h
new file mode 100644
index 0000000000..9d419cfbb5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/doqq/ossimDoqqTileSource.h
@@ -0,0 +1,43 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimDoqqTileSource.h,v 1.10 2005/11/14 13:47:01 gpotts Exp $
+#ifndef ossimDoqqTileSource_HEADER
+#define ossimDoqqTileSource_HEADER
+#include <imaging/formats/general_raster/ossimGeneralRasterTileSource.h>
+#include <support_data/doqq/ossimDoqq.h>
+
+class OSSIM_DLL ossimDoqqTileSource: public ossimGeneralRasterTileSource
+{
+public:
+   ossimDoqqTileSource();
+   virtual ~ossimDoqqTileSource();
+   
+   ossimString getShortName()const;
+   ossimString getLongName()const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = NULL);
+   
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+   bool open(const ossimFilename& filename);
+   bool open(const ossimGeneralRasterInfo& info);
+
+   ossimString acqdate() const;
+
+protected:
+  ossimRefPtr<ossimDoqq>   theHeaderInformation;
+  ossimString  theAcqDate;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/dted/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/dted/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/dted/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedElevationImageSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedElevationImageSource.cpp
new file mode 100644
index 0000000000..497f927e08
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedElevationImageSource.cpp
@@ -0,0 +1,719 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2005 David Burken, all rights reserved.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: David Burken
+//
+// Description:
+//
+// Contains class declaration of ossimDtedElevationImageSource.
+//
+// $Id: ossimDtedElevationImageSource.cpp,v 1.4 2005/02/11 15:07:31 dburken Exp $
+//----------------------------------------------------------------------------
+
+#include <vector>
+#include <sstream>
+using namespace std;
+
+#include <base/common/ossimTrace.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <base/data_types/ossimIrect.h>
+#include <elevation/formats/dted_cell/ossimDtedHandler.h>
+#include <projections/ossimImageViewProjectionTransform.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <imaging/formats/dted/ossimDtedElevationImageSource.h>
+#include <imaging/formats/dted/ossimDtedTileSource.h>
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+#include <imaging/tile_sources/ossimImageRenderer.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageChain.h>
+
+static ossimTrace traceDebug("ossimDtedElevationImageSource:degug");
+
+ossimDtedElevationImageSource::ossimDtedElevationImageSource()
+   :
+   theDirectory(),
+   theCellExtension("dt2"),
+   theResamplerType(ossimDtedElevationImageSource::BILINEAR)
+{
+}
+
+ossimDtedElevationImageSource::~ossimDtedElevationImageSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimDtedElevationImageSource::getBlock(
+   const ossimGrect& rect,
+   ossim_uint32 lines,
+   ossim_uint32 samples) const
+{
+
+   ossimDpt postSpacing;
+   getPostSpacing(rect, lines, samples, postSpacing);
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDtedElevationImageSource::getBlock DEBUG:"
+         << "\nrect:          " << rect
+         << "\nlines:         " << lines
+         << "\nsamples:       " << samples
+         << "\npost spacing:  " << postSpacing
+         << "\ntheDirectory:  " << theDirectory
+         << endl;
+   }
+
+   // Get a list of needed cells.
+   vector<ossimFilename> vf;
+   findCells(rect, vf);
+
+   // Create a mosaic of them.
+   ossimImageChain* mosaic = createMosaic(vf);
+   if (!mosaic)
+   {
+      return NULL;
+   }
+
+   // Get the view.
+   ossimMapProjection* view = getView(mosaic);
+   if (!view)
+   {
+      delete mosaic;
+      return NULL;
+   }
+   
+   // Set the output resolution.
+   view->setDecimalDegreesPerPixel(postSpacing);
+
+   // Set the tie point to be the upper left of the requested rect.
+   view->setUlGpt(rect.ul());
+
+   // Convert the ground rectangle to the view's image space.
+   ossimIrect tileRect;
+   computeImageRect(view, rect, tileRect);
+
+   cout << "tileRect:  " << tileRect << endl;
+   
+   ossimRefPtr<ossimImageData> result = mosaic->getTile(tileRect);
+
+   delete mosaic;
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDtedElevationImageSource::getBlock DEBUG:"
+         << *result
+         << "\nReturning..."
+         << endl;
+   }
+
+   return result;
+}
+
+void ossimDtedElevationImageSource::setDirectory(const ossimFilename& directory)
+{
+   theDirectory = directory;
+}
+
+void ossimDtedElevationImageSource::getDirectory(ossimFilename& directory) const
+{
+   directory = theDirectory;
+}
+
+void ossimDtedElevationImageSource::findCells(
+   const ossimGrect& rect,
+   vector<ossimFilename>& vf) const
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDtedElevationImageSource::findCells entered..." << endl;
+   }
+
+   // Clear the vector of filenames passed to us.
+   vf.clear();
+
+   if (!theDirectory.isDir())
+   {
+      return;
+   }   
+
+   //---
+   // Expand out the rectangle to even degree boundaries.
+   // Handle wrapping???
+   //---
+   
+   ossimGrect expandedRect = rect.stretchToEvenBoundary(1.0, 1.0);
+
+
+   ossim_int32 startLat = static_cast<ossim_int32>(expandedRect.ll().latd());
+   ossim_int32 startLon = static_cast<ossim_int32>(expandedRect.ll().lond());
+   ossim_int32 stopLat  =
+      static_cast<ossim_int32>(expandedRect.ur().latd()-1);
+   ossim_int32 stopLon  =
+      static_cast<ossim_int32>(expandedRect.ur().lond()-1);
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG:"
+         << "\nepandedRect:  " << expandedRect
+         << "\nstartLat:  " << startLat
+         << "\nstartLon:  " << startLon
+         << "\nstopLat:   " << stopLat
+         << "\nstopLon:   " << stopLon
+         
+         << endl;
+   }
+
+   
+   for (ossim_int32 lon = startLon; lon <= stopLon; ++lon)
+   {
+      // Build up a dted file name.
+      ossimString lonBase;
+      if (lon < 0)
+      {
+         lonBase = "w";
+      }
+      else
+      {
+         lonBase = "e";
+      }
+
+      ossim_int32 tmpLon = abs(lon);
+      ostringstream  s1;
+      s1<< setfill('0')<<setw(3)<< tmpLon;
+
+      lonBase += s1.str().c_str();
+      lonBase += "/";
+
+      for (ossim_int32 lat = startLat; lat <= stopLat; ++lat)
+      {
+         ossimFilename dtedFile = theDirectory.dirCat(lonBase);
+         if (lat >= 0)
+         {
+            dtedFile += "n";
+         }
+         else
+         {
+            dtedFile += "s";
+         }
+         
+         ossim_int32 tmpLat = abs(lat);
+         ostringstream  s2;
+         s2<< setfill('0')<<setw(2)<<tmpLat;
+         dtedFile += s2.str().c_str();
+         
+         dtedFile.setExtension(theCellExtension);
+
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "\nSearching for:  " << dtedFile
+               << endl;
+         }
+
+         if (dtedFile.exists())
+         {
+            vf.push_back(dtedFile);
+         }
+      }
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "Cell list:\n";
+      
+      vector<ossimFilename>::const_iterator i = vf.begin();
+      while (i != vf.end())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << (*i) << "\n";
+         ++i;
+      }
+      ossimNotify(ossimNotifyLevel_DEBUG) << endl;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDtedElevationImageSource::findCells exited..." << endl;
+   }
+}
+
+void ossimDtedElevationImageSource::resampleCell(
+   const ossimGrect& rect,
+   const ossimFilename& dtedFile,
+   ossimImageData& id,
+   const ossimDpt& postSpacing) const
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDtedElevationImageSource::resampleCell DEBUG:  Entered..."
+         << endl;
+   }
+
+   switch (theResamplerType)
+   {
+      case NEAREST_NEIGHBOR:
+         resampleCellNearestNeighbor(rect, dtedFile, id, postSpacing);
+         break;
+
+      case BILINEAR:
+         resampleCellBilinear(rect, dtedFile, id, postSpacing);
+         break;
+
+      default:
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimDtedElevationImageSource::resampleCell type not handled!"
+            << endl;
+         break;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDtedElevationImageSource::resampleCell DEBUG:  Exited..."
+         << endl;
+   }
+}
+
+void ossimDtedElevationImageSource::resampleCellBilinear(
+   const ossimGrect& rect,
+   const ossimFilename& dtedFile,
+   ossimImageData& id,
+   const ossimDpt& postSpacing) const
+{
+   cout << dtedFile << endl;
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDtedElevationImageSource::resampleCellBilinear DEBUG:"
+         << " Entered..."
+         << endl;
+   }
+
+   ossimDtedHandler* dh = new ossimDtedHandler(dtedFile);
+   if (!dh)
+   {
+      return;
+   }
+   if (dh->getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+      delete dh;
+      return;
+   }
+
+   ossim_float32* buf = id.getFloatBuf();
+   if (!buf)
+   {
+      delete dh;
+      return;
+   }
+   
+   // Get the clip rectangle.
+   const ossimGrect clipRect = rect.clipToRect(dh->getBoundingGndRect());
+   const ossimGpt STOP_GPT = clipRect.lr();
+   ossimGpt gpt = clipRect.ul();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "clipRect:  " << clipRect
+         << "\nSTOP_GPT:  " << STOP_GPT
+         << "\nStarting gpt:       " << gpt
+         << endl;
+   }
+
+   // Walk in the latitude (line) direction.
+   while (gpt.lat >= STOP_GPT.lat)
+   {
+      // Walk in longitude (sample) direction.
+      gpt.lon = clipRect.ul().lon;
+      while (gpt.lon <= STOP_GPT.lon)
+      {
+         ossim_uint32 index = computeIndex(id, rect, gpt, postSpacing);
+//         cout << "index:  " << index << endl;
+         if (index != OSSIM_UINT_NAN)
+         {
+            ossim_float32 hgt =
+               static_cast<ossim_float32>(dh->getHeightAboveMSL(gpt));
+//             cout << "index: " << index
+//                  << "\ngpt: " << gpt
+//                  << "\nhgt: " << hgt
+//                  << endl;
+            buf[index] = hgt;
+            if (hgt == -32767.0)
+            {
+               cout << gpt << endl;
+            }
+            // static_cast<ossim_float32>(dh->getHeightAboveMSL(gpt));
+         }
+         else
+         {
+            cout << "nan index for gpt:\n" << gpt << endl;
+         }
+         
+         gpt.lon = gpt.lon + postSpacing.x;
+      }
+      gpt.lat = gpt.lat - postSpacing.y;
+   }
+//   cout << "Ending gpt:  " << gpt << endl;
+
+//    // Walk in the latitude direction
+//    while (gpt.lat <= STOP_GPT.lat)
+//    {
+//       while (gpt.lon <= STOP_GPT.lon)
+//       {
+//          gpt.lon += postSpacing.x;
+//       }
+//       gpt.lat += postSpacing.y;
+//    }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDtedElevationImageSource::resampleCellBilinear DEBUG:"
+         << " Exited..."
+         << endl;
+   }
+   
+   delete dh;
+}
+
+void ossimDtedElevationImageSource::resampleCellNearestNeighbor(
+   const ossimGrect& rect,
+   const ossimFilename& dtedFile,
+   ossimImageData& id,
+   const ossimDpt& requestedPostSpacing) const
+{
+   // Open the cell.
+   ossimImageHandler* dts = new ossimDtedTileSource();
+   dts->open(dtedFile);
+
+   if (dts->isOpen() == false)
+   {
+      delete dts;
+      return;
+   }
+
+   // Get the post spacing of the cell.
+   ossimDpt cellPostSpacing;
+   ((ossimDtedTileSource*)dts)->getPostSpacing(cellPostSpacing);
+
+//    // Compute the rlevel to grab from.
+//    ossim_uint32 rLevel = computeRLevel(dts->getNumberOfDecimationLevels(),
+//                                        requestedPostSpacing,
+//                                        cellPostSpacing);
+
+   
+}
+
+void ossimDtedElevationImageSource::getPostSpacing(const ossimGrect& rect,
+                                                   ossim_uint32 lines,
+                                                   ossim_uint32 samples,
+                                                   ossimDpt& result) const
+{
+   result.lat = (rect.ul().lat - rect.ll().lat) / (lines   - 1);
+   result.lon = (rect.lr().lon - rect.ll().lon) / (samples - 1);
+}
+
+void ossimDtedElevationImageSource::snap(const ossimGrect& rect,
+                                         const ossimDpt& postSpacing,
+                                         ossimGrect& clipRect) const
+{
+   ossim_float64 d;
+
+   // upper left latitude
+   d = (rect.ul().lat - clipRect.ul().lat) / postSpacing.y;
+   if (d != 0.0)
+   {
+      clipRect.ul().lat = floor(d) * postSpacing.y;
+   }
+
+   // upper left longitude
+   d = (rect.ul().lon - clipRect.ul().lon) / postSpacing.x;
+   if (d != 0.0)
+   {
+      clipRect.ul().lon = ceil(d) * postSpacing.x;
+   }
+
+   // upper right latitude
+   d = (rect.ul().lat - clipRect.ur().lat) / postSpacing.y;
+   if (d != 0.0)
+   {
+      clipRect.ur().lat = floor(d) * postSpacing.y;
+   }
+
+   // upper right longitude
+   d = (rect.ul().lon - clipRect.ur().lon) / postSpacing.x;
+   if (d != 0.0)
+   {
+      clipRect.ul().lon = floor(d) * postSpacing.x;
+   }
+
+   // lower right latitude
+   d = (rect.ul().lat - clipRect.lr().lat) / postSpacing.y;
+   if (d != 0.0)
+   {
+      clipRect.lr().lat = ceil(d) * postSpacing.y;
+   }
+
+   // lower right longitude
+   d = (rect.ul().lon - clipRect.lr().lon) / postSpacing.x;
+   if (d != 0.0)
+   {
+      clipRect.ul().lon = floor(d) * postSpacing.x;
+   }
+
+   // lower left latitude
+   d = (rect.ul().lat - clipRect.ll().lat) / postSpacing.y;
+   if (d != 0.0)
+   {
+      clipRect.ll().lat = ceil(d) * postSpacing.y;
+   }
+
+   // lower left longitude
+   d = (rect.ul().lon - clipRect.ll().lon) / postSpacing.x;
+   if (d != 0.0)
+   {
+      clipRect.ul().lon = ceil(d) * postSpacing.x;
+   }
+}
+
+ossim_uint32 ossimDtedElevationImageSource::computeIndex(
+   const ossimImageData& id,
+   const ossimGrect& idRect,
+   const ossimGpt& gpt,
+   const ossimDpt& postSpacing) const
+{
+   if ( ! idRect.pointWithin(gpt) )
+   {
+      return OSSIM_INT_NAN;
+   }
+
+   ossim_uint32 line = static_cast<ossim_uint32>( (idRect.ul().lat - gpt.lat)
+                                                  / postSpacing.y );
+   ossim_uint32 samp = static_cast<ossim_uint32>( (gpt.lon - idRect.ul().lon)
+                                                  / postSpacing.x );
+   return ( (line * id.getWidth()) + samp );
+}
+
+ossim_uint32 ossimDtedElevationImageSource::computeRLevel(
+   ossim_uint32 numberOfRLevels,
+   const ossimDpt& requestedPostSpacing,
+   const ossimDpt& cellPostSpacing) const
+{
+   if (numberOfRLevels == 1)
+   {
+      return 0;
+   }
+
+   // Start the check at r1 postspacing.
+   ossimDpt rLevelPostSpacing(cellPostSpacing.x * 2.0,
+                              cellPostSpacing.y * 2.0);
+   ossim_uint32 level = 0;
+
+   for (ossim_uint32 i = 1; i < numberOfRLevels; ++i)
+   {
+      if ( (rLevelPostSpacing.x > requestedPostSpacing.x) &&
+           (rLevelPostSpacing.y > requestedPostSpacing.y) )
+      {
+         break;
+      }
+      
+      rLevelPostSpacing.x = rLevelPostSpacing.x * 2.0;
+      rLevelPostSpacing.y = rLevelPostSpacing.y * 2.0;
+      ++level;
+   }
+
+   return level;
+}
+
+void ossimDtedElevationImageSource::setCellExtension(const ossimString& ext)
+{
+   theCellExtension = ext;
+}
+
+void ossimDtedElevationImageSource::getCellExtension(ossimString& ext) const
+{
+   ext = theCellExtension;
+}
+
+ossimConnectableObject* ossimDtedElevationImageSource::createRawChain(
+   const ossimFilename& file) const
+{
+   ossimImageHandler* ih  = ossimImageHandlerRegistry::instance()->open(file);
+   ossimConnectableObject* result = NULL;
+   if(ih)
+   {
+      ossimImageChain* chain = new ossimImageChain;
+      chain->add(ih);
+      chain->setDescription(file);
+      result = chain;
+   }
+
+   return result;
+}
+
+ossimImageChain* ossimDtedElevationImageSource::createMosaic(
+   const std::vector<ossimFilename>& inputs) const
+{
+   std::vector<ossimConnectableObject*> inputObjects;
+   for(int idx = 0; idx < (int)inputs.size();++idx)
+   {
+      ossimConnectableObject* obj = createRawChain(inputs[idx]);
+      if(obj)
+      {
+         inputObjects.push_back(obj);
+      }
+   }
+   return createMosaic(inputObjects);
+}
+
+ossimImageChain* ossimDtedElevationImageSource::createMosaic(
+   const std::vector<ossimConnectableObject*>& inputs) const
+{
+   if(!inputs.size())
+   {
+      return NULL;
+   }
+
+   std::vector<ossimConnectableObject*> inputList;
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < inputs.size(); ++idx)
+   {
+      ossimImageChain* chain = PTR_CAST(ossimImageChain, inputs[idx]);
+      if(chain)
+      {
+         inputList.push_back(chain);
+      }
+   }
+   if(!inputList.size())
+   {
+      return NULL;
+   }
+   
+   ossimImageChain* chainResult = NULL;
+   ossimString defaultDescription="ossimOrthoImageMosaic";;
+   ossimKeywordlist kwl;
+   
+   kwl.add("type",
+           "ossimImageChain",
+           true);
+   
+   kwl.add("id",
+           0,
+           true);
+   
+   kwl.add("object1.type",
+           "ossimOrthoImageMosaic",
+           true);
+   kwl.add("object1.id",
+           1,
+           true);
+   
+   
+   kwl.add("object10.type",
+           "ossimCacheTileSource",
+           true);
+   kwl.add("object10.id",
+           10,
+           true);
+   kwl.add("object10.input_connection1",
+           1,
+           true);
+   
+   kwl.add("object20.type",
+           "ossimImageRenderer",
+           true);
+   kwl.add("object20.id",
+           20,
+           true);
+   kwl.add("object20.input_connection1",
+           10,
+           true);
+   
+    ossimObject* objResult =
+       ossimObjectFactoryRegistry::instance()->createObject(kwl);
+    chainResult      = PTR_CAST(ossimImageChain, objResult);
+    if(chainResult)
+    {
+	chainResult->makeUniqueIds();
+        chainResult->setDescription(defaultDescription);
+        for(idx = 0; idx < inputList.size(); ++idx)
+        {
+           chainResult->connectMyInputTo(inputList[idx]);
+        }
+    }
+    else if(objResult)
+    {
+	delete objResult;
+    }
+    
+    return chainResult;
+}
+
+ossimMapProjection* ossimDtedElevationImageSource::getView(
+   ossimConnectableObject* container) const
+{
+   if (!container)
+   {
+      cerr << "a..." << endl;
+      return NULL;
+   }
+
+   // Find the resampler.
+   ossimImageRenderer* rs =
+      (ossimImageRenderer*)container->
+      findObjectOfType("ossimImageRenderer",
+                       ossimConnectableObject::CONNECTABLE_DIRECTION_INPUT);
+
+   if (!rs)
+   {
+      cerr << "b..." << endl;
+      return NULL;
+   }
+   
+   const ossimObject* obj = rs->getView();
+   if (!obj)
+   {
+      cerr << "b2..." << endl;
+   }
+
+   return PTR_CAST(ossimMapProjection, obj);
+}
+
+void ossimDtedElevationImageSource::computeImageRect(
+   const ossimMapProjection* view,
+   const ossimGrect& grect,
+   ossimIrect& irect) const
+{
+   if (!view)
+   {
+      return;
+   }
+   
+   ossimDpt dpt;
+   view->worldToLineSample(grect.ul(), dpt);
+   irect.set_ul(dpt);
+   view->worldToLineSample(grect.lr(), dpt);
+   irect.set_lr(dpt);
+}
+
+void ossimDtedElevationImageSource::setResamplerType(ossimDtedElevationImageSource::ResamplerType type)
+{
+   theResamplerType = type;
+}
+
+ossimDtedElevationImageSource::ResamplerType ossimDtedElevationImageSource::getResamplerType() const
+{
+   return theResamplerType;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedElevationImageSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedElevationImageSource.h
new file mode 100644
index 0000000000..ec8098b21a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedElevationImageSource.h
@@ -0,0 +1,226 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2005 David Burken, all rights reserved.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: David Burken
+//
+// Description:
+//
+// Contains class declaration of ossimDtedElevationImageSource.
+//
+// $Id: ossimDtedElevationImageSource.h,v 1.4 2005/02/11 15:07:31 dburken Exp $
+//----------------------------------------------------------------------------
+#ifndef ossimDtedElevationImageSource_HEADER
+#define ossimDtedElevationImageSource_HEADER
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimGrect.h>
+
+
+// Forward class declarations.
+class ossimImageData;
+class ossimImageChain;
+class ossimDtedTileSource;
+class ossimConnectableObject;
+class ossimMapProjection;
+class ossimIrect;
+
+
+/**
+ * Class to return large area blocks of data as an ossimImageData object from
+ * multiple dted cells.  Source dted cells must be of the same resolution and
+ * in the standard dted directory stucture.
+ *
+ * Example directory structure:
+ *
+ *                      dted_level2_directory
+ *                        /              \  
+ *                       /                \
+ *                    w099                w100
+ *                   /    \              /    \
+ *                  /      \            /      \
+ *               n32.dt2  n33.dt2   n32.dt2  n33.dt2
+ */
+class OSSIMDLLEXPORT ossimDtedElevationImageSource
+{
+public:
+
+   enum ResamplerType
+   {
+      NEAREST_NEIGHBOR = 0,
+      BILINEAR         = 1
+   };
+   
+   /**
+    * Default constructor
+    */
+   ossimDtedElevationImageSource();
+
+   /**
+    * Destructor
+    */
+   virtual ~ossimDtedElevationImageSource();
+
+   /**
+    * @param rect Requested rectangle.
+    *
+    * @param lines Number of lines.  This will determine the
+    * post spacing in the latitude direction.
+    *
+    * @param samples Number of samples.  This will determine the post spacing
+    * in the longitude direction.
+    */
+   ossimRefPtr<ossimImageData> getBlock(const ossimGrect& rect,
+                                        ossim_uint32 lines,
+                                        ossim_uint32 samples) const;
+   
+   /**
+    * @param directory Directory to search for dted cells.
+    *
+    * @note Directory should be in a standard dted format.
+    *
+    * @note All cells in the directory should be of same resolution.
+    */
+   void setDirectory(const ossimFilename& directory);
+
+   /**
+    * @param directory Will be initialized to the current dted directory.
+    */
+   void getDirectory(ossimFilename& directory) const;
+
+    /**
+    * @param ext Should be the extension of cells in the directory like
+    * "dt1", "dt2".
+    *
+    * @note All cells in the directory should have same extension.
+    */
+   void setCellExtension(const ossimString& ext);
+
+   /**
+    * @param ext Will be initialized to the current cell extension.
+    */
+   void getCellExtension(ossimString& ext) const;
+
+   /**
+    * @param type Enumerated resampler type.
+    */
+   void setResamplerType(ossimDtedElevationImageSource::ResamplerType type);
+
+   /**
+    * @return Resampler type.
+    */
+   ossimDtedElevationImageSource::ResamplerType getResamplerType() const;
+   
+
+private:
+   
+   /**
+    * Finds all cells in "theDirectory" for rectangle passed in.
+    *
+    * @param rect Rectangle of requested elevation block.
+    *
+    * @param vf Vector of ossimFilenames to initialize with cells that are
+    * present and overlap rect.
+    *
+    * @note vf will be cleared upon entring this method, so if vf.empty() is
+    * true than no cells were found.
+    */
+   void findCells(const ossimGrect& rect,
+                  vector<ossimFilename>& vf) const;
+
+   /**
+    * Main resample method.
+    *
+    * @param rect Rectangle of requested elevation block.
+    *
+    */
+   void resampleCell(const ossimGrect& rect,
+                     const ossimFilename& dtedFile,
+                     ossimImageData& id,
+                     const ossimDpt& postSpacing) const;
+
+   /**
+    * Specialized resample method.  Uses ossimDtedHandler and its
+    * getHeightAboveMSL method to fill rect.
+    */
+   void resampleCellBilinear(const ossimGrect& rect,
+                             const ossimFilename& dtedFile,
+                             ossimImageData& id,
+                             const ossimDpt& postSpacing) const;
+
+   /**
+    * Specialized resample method.  Uses ossimDtedTileSource to fill a patch,
+    * then resamples to post spacing using nearest neighbor.
+    */
+   void resampleCellNearestNeighbor(const ossimGrect& rect,
+                                    const ossimFilename& dtedFile,
+                                    ossimImageData& id,
+                                    const ossimDpt& requestedPostSpacing)const;
+
+   /**
+    * @param rect Ground rectangle.
+    *
+    * @param lines Number of desired lines in latitude direction.
+    *
+    * @param samples Number of desired samples in the longitude direction.
+    *
+    * @param result
+    * result.y = (rect.ul().latd - rect.ll().latd) / lines
+    * result.x = (rect.lr().lond - rect.ll().lond) / samples
+    */
+   void getPostSpacing(const ossimGrect& rect,
+                       ossim_uint32 lines,
+                       ossim_uint32 samples,
+                       ossimDpt& result) const;
+
+   /**
+    * Aligns clip rect to requested rect with respect to post spacing.
+    */
+   void snap(const ossimGrect& rect,
+             const ossimDpt& postSpacing,
+             ossimGrect& clipRect) const;
+
+   /**
+    * @return The index for gpt into id's buf.  If point does not intersect
+    * the rectangle an "OSSIM_UINT_NAN" is returned.
+    */
+   ossim_uint32 computeIndex(const ossimImageData& id,
+                             const ossimGrect& idRect,
+                             const ossimGpt& gpt,
+                             const ossimDpt& postSpacing) const;
+
+   /**
+    * @return Returns the rLevel that is equal to, or greater than the
+    * requestedPostSpacing.
+    */
+   ossim_uint32 computeRLevel(ossim_uint32 numberOfRLevels,
+                              const ossimDpt& requestedPostSpacing,
+                              const ossimDpt& cellPostSpacing) const;
+
+   ossimConnectableObject* createRawChain(const ossimFilename& file) const;
+
+   ossimImageChain* createMosaic(
+      const std::vector<ossimFilename>& inputs) const;
+   
+   ossimImageChain* createMosaic(
+      const std::vector<ossimConnectableObject*>& inputs) const;
+
+   ossimMapProjection* getView(ossimConnectableObject* container) const;
+
+   void computeImageRect(const ossimMapProjection* view,
+                         const ossimGrect& grect,
+                         ossimIrect& irect) const;
+
+   ossimFilename theDirectory;
+   ossimString   theCellExtension;
+   ResamplerType theResamplerType;
+   
+};
+
+#endif /* End of #ifndef ossimDtedElevationImageSource_HEADER */
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedTileSource.cpp
new file mode 100644
index 0000000000..8a1cf23150
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedTileSource.cpp
@@ -0,0 +1,739 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimDtedTileSource.
+//
+//********************************************************************
+// $Id: ossimDtedTileSource.cpp,v 1.37 2005/02/11 15:07:31 dburken Exp $
+
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+#include <imaging/formats/dted/ossimDtedTileSource.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimS16ImageData.h>
+#include <support_data/dted/ossimDtedVol.h>
+#include <support_data/dted/ossimDtedHdr.h>
+#include <support_data/dted/ossimDtedUhl.h>
+#include <support_data/dted/ossimDtedDsi.h>
+#include <support_data/dted/ossimDtedAcc.h>
+
+RTTI_DEF1(ossimDtedTileSource, "ossimDtedTileSource", ossimImageHandler)
+
+// Static trace for debugging
+static ossimTrace traceDebug("ossimDtedTileSource:debug");
+
+
+ossimDtedTileSource::ossimDtedTileSource()
+   :
+      ossimImageHandler(),
+      theTile(NULL),
+      theFileStr(),
+      theTileWidth(0),
+      theTileHeight(0),
+      theNumberOfLines(0),
+      theNumberOfSamps(0),
+      theOffsetToFirstDataRecord(0),
+      theDataRecordSize(0),
+      theMinHeight(0),
+      theMaxHeight(0),
+      thePostSpacing(0.0, 0.0),
+      theSwapBytesFlag(false)
+{
+   if (ossimGetByteOrder() == OSSIM_LITTLE_ENDIAN)
+   {
+      theSwapBytesFlag = true;
+   }
+
+   // Set the tile size to the default.
+   ossimIpt defaultTileSize;
+   ossimGetDefaultTileSize(defaultTileSize);
+   theTileWidth  = static_cast<ossim_uint32>(defaultTileSize.x);
+   theTileHeight = static_cast<ossim_uint32>(defaultTileSize.y);
+   
+   // Construction not complete.  Users should call "open" method.
+}
+
+ossimDtedTileSource::~ossimDtedTileSource()
+{
+   theFileStr.close();
+}
+
+ossimString ossimDtedTileSource::getShortName()const
+{
+   return ossimString("dted");
+}
+
+ossimString ossimDtedTileSource::getLongName()const
+{
+   return ossimString("dted reader");
+}
+
+ossimString ossimDtedTileSource::className()const
+{
+   return ossimString("ossimDtedTileSource");
+}   
+
+ossimRefPtr<ossimImageData> ossimDtedTileSource::getTile(
+   const  ossimIrect& tile_rect, ossim_uint32 resLevel)
+{
+   if (!theTile.valid())
+   {
+      allocate(); // First getTile call or after changeTileSize.
+      if (!theTile.valid())
+      {
+         return ossimRefPtr<ossimImageData>(); // Throw exception???
+      }
+   }
+
+   // This tile source bypassed, or invalid res level, return a blank tile.
+   if (!isOpen()||!isSourceEnabled() || !isValidRLevel(resLevel))
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   if (theOverview)
+   {
+      if (theOverview->hasR0() || resLevel)
+      {
+         ossimRefPtr<ossimImageData> temp =
+            theOverview->getTile(tile_rect, resLevel);
+         if(temp.valid() && temp->getBuf())
+         {
+            temp->setMinPix(theTile->getMinPix(), theTile->getNumberOfBands());
+            temp->setMaxPix(theTile->getMaxPix(), theTile->getNumberOfBands());
+            temp->setNullPix(theTile->getNullPix(),
+                             theTile->getNumberOfBands());
+         }
+         else
+         {
+            return ossimRefPtr<ossimImageData>();
+         }
+         return temp;
+      }
+   }
+
+   // Set the origing and resize if needed...
+   theTile->setImageRectangle(tile_rect);
+   
+   ossimIrect image_rect = getImageRectangle(resLevel);
+   
+   //***
+   // See if any point of the requested tile is in the image.
+   //***
+   if ( tile_rect.intersects(image_rect) )
+   {
+      ossimIrect clip_rect = tile_rect.clipToRect(image_rect);
+      
+      if ( !tile_rect.completely_within(clip_rect) )
+      {
+         // Start with a blank tile.
+         theTile->makeBlank();
+      }
+
+      // Load the tile buffer with data from the dted cell.
+      if (fillBuffer(tile_rect, clip_rect))
+      {
+         theTile->validate();
+         return theTile;
+      }
+      else
+      {
+         return ossimRefPtr<ossimImageData>();
+      }
+      
+   } // End of if ( tile_rect.intersects(image_rect) )
+
+   // No part of requested tile within the image rectangle.
+   return ossimRefPtr<ossimImageData>();
+   
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimDtedTileSource::fillBuffer(const ossimIrect& tile_rect,
+                                     const ossimIrect& clip_rect)
+{
+   //***
+   // NOTE:
+   // Elevation posts are organized positive line up.
+   // The "tile_rect" and "clip_rect" is organized positive line down.
+   //***
+
+   const ossim_int32 TILE_WIDTH = theTile->getWidth();
+   
+   //***
+   // Position the file pointer to the first record needed.
+   // Posts are organized positive line up so we're going to start at
+   // the lower left side of the cell so all reads are going forward in
+   // the file.
+   //***
+   ossim_int32 seek_position = theOffsetToFirstDataRecord +
+                         (clip_rect.ul().x * theDataRecordSize);
+   seek_position += DATA_RECORD_OFFSET_TO_POST +
+                    (theNumberOfLines - 1 - clip_rect.lr().y) * 2;
+   
+   //***
+   // Get a pointer positioned at the first valid pixel in
+   // the tile.  Tiles are organized positive line down.
+   //***
+   ossim_sint16* d = static_cast<ossim_sint16*>(theTile->getBuf());
+   
+   // Loop in the longitude or sample direction.
+   for (ossim_int32 samp = clip_rect.ul().x; samp <= clip_rect.lr().x; samp++)
+   {
+      ossim_int32 d_offset = (clip_rect.lr().y - tile_rect.ul().y) *
+                       TILE_WIDTH +
+                       (samp - tile_rect.ul().x);
+
+      theFileStr.seekg(seek_position, ios::beg); // Seek to the first post.
+
+      for (ossim_int32 line = clip_rect.lr().y; line >= clip_rect.ul().y; line--)
+      {
+         // Grab all the post needed from the column.
+         ossim_uint16 temp;
+         ossim_sint16 s;
+         theFileStr.read((char*)&temp, POST_SIZE);
+         s = convertSignedMagnitude(temp);
+         d[d_offset] = s;
+         d_offset -= TILE_WIDTH;
+      }
+      seek_position += theDataRecordSize;
+   }
+
+
+   return true;
+}
+
+ossim_uint32 ossimDtedTileSource::getNumberOfOutputBands()const
+{
+   return getNumberOfInputBands();
+}
+
+ossimIrect
+ossimDtedTileSource::getImageRectangle(ossim_uint32 reduced_res_level) const
+{
+   return ossimIrect(0,
+                     0,
+                     getNumberOfSamples(reduced_res_level) - 1,
+                     getNumberOfLines(reduced_res_level)   - 1);
+}
+
+bool ossimDtedTileSource::isOpen()const
+{
+   return theFileStr.is_open();
+}
+
+bool ossimDtedTileSource::open()
+{
+   static const char MODULE[] = "ossimDtedTileSource::open";
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\nAttempting to parse file:  " << theImageFile.c_str()
+           << endl;
+   }
+   
+   if (!theImageFile.exists()) // See if file exists.
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nFile " << theImageFile.c_str() << " does not exist!"
+              << endl;
+      }
+      return false;
+   }
+
+   // Open up the file for reading.
+   theFileStr.open(theImageFile.c_str(), ios::in | ios::binary);
+   if (!theFileStr)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      
+      ossimNotify(ossimNotifyLevel_WARN) << MODULE << " ERROR!"
+                                         << "\nCould not open file:  " << theImageFile.c_str()
+                                         << "\nReturning..." << endl;
+      if (traceDebug())  CLOG << "returning with error..." << endl;
+      return false;
+   }
+                                   
+   if(!theFileStr)
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nCannot open:  " << theImageFile.c_str()
+              << endl;
+      }
+      theFileStr.close();
+      return false;
+   }
+                                 
+   // Attempt to parse.
+   ossimDtedVol vol(theFileStr, 0);
+   ossimDtedHdr hdr(theFileStr, vol.stopOffset());
+   ossimDtedUhl uhl(theFileStr, hdr.stopOffset());
+   ossimDtedDsi dsi(theFileStr, uhl.stopOffset());
+   ossimDtedAcc acc(theFileStr, dsi.stopOffset());
+
+   //***
+   // Check for errors.  Must have uhl, dsi and acc records.  vol and hdr
+   // are for magnetic tape only; hence, may or may not be there.
+   //***
+   if (uhl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR ||
+       dsi.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR ||
+       acc.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nError parsing file:  " << theImageFile.c_str()
+              << "\nPossibly not a dted file."
+              << endl;
+      }
+      
+      theFileStr.close();
+      return false;
+   }
+
+   // Get the cell specific info needed for later.
+   theNumberOfLines = uhl.numLatPoints();
+   theNumberOfSamps = uhl.numLonLines();
+   thePostSpacing.x = uhl.lonInterval();
+   thePostSpacing.y = uhl.latInterval();
+   theOffsetToFirstDataRecord = acc.stopOffset();
+   theDataRecordSize = DATA_RECORD_OFFSET_TO_POST +
+                       (theNumberOfLines * sizeof(ossim_sint16)) +
+                       DATA_RECORD_CHECKSUM_SIZE;
+
+   // Scan the file to get the min / max post.
+   gatherStatistics();
+   
+   completeOpen();
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\nNull pix:  " << getNullPixelValue(0)
+           << "\nMin  pix:  " << getMinPixelValue(0)
+           << "\nMax  pix:  " << getMaxPixelValue(0)
+           << "\ntheNumberOfLines:  " << theNumberOfLines
+           << "\ntheNumberOfSamps:  " << theNumberOfSamps
+           << "\ntheOffsetToFirstDataRecord:  " << theOffsetToFirstDataRecord
+           << "\ntheDataRecordSize:  " << theDataRecordSize
+           << endl;
+   }
+
+
+   return true;
+}
+
+void ossimDtedTileSource::allocate()
+{
+   //---
+   // Set up the tiles.  Note the blank tile will not get initialized to save
+   // memory.  This includes setting the min and max pixel value gathered
+   // from the statistics.
+   //---
+   theTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile->initialize();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG:"
+         << "\ntheTile:\n" << *theTile
+         << endl;
+   }
+}
+
+bool ossimDtedTileSource::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix) const
+{
+   // Currently nothing to do here.
+   return ossimImageHandler::saveState(kwl, prefix);
+}
+
+bool ossimDtedTileSource::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   if (ossimImageHandler::loadState(kwl, prefix))
+   {
+      if (ossimImageHandler::open(theImageFile))
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+bool ossimDtedTileSource::getImageGeometry(ossimKeywordlist& kwl,
+                                           const char* prefix)
+{
+   static const char MODULE[] = "ossimDtedTileSource::getImageGeometry";
+
+   if (traceDebug()) CLOG << " Entered..." << endl;
+
+   // Previously saved...
+   if (theGeometryKwl.getSize())
+   {
+      kwl = theGeometryKwl;
+      return true;
+   }   
+      
+   if(!theFileStr)
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nCannot open:  " << theImageFile.c_str()
+              << endl;
+      }
+
+      return false;
+   }
+
+   // Attempt to parse.
+   ossimDtedVol vol(theFileStr, (ossim_int32)0);
+   ossimDtedHdr hdr(theFileStr, vol.stopOffset());
+   ossimDtedUhl uhl(theFileStr, hdr.stopOffset());
+   ossimDtedDsi dsi(theFileStr, uhl.stopOffset());
+   ossimDtedAcc acc(theFileStr, dsi.stopOffset());
+
+   //***
+   // Check for errors.  Must have uhl, dsi and acc records.  vol and hdr
+   // are for magnetic tape only; hence, may or may not be there.
+   //***
+   if (uhl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR ||
+       dsi.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR ||
+       acc.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nError parsing file:  " << theImageFile.c_str()
+              << "\nPossibly not a dted file."
+              << endl;
+      }
+      return false;
+   }
+
+   //***
+   // Make an Equidistant Cylindrical projection with a origin at the equator
+   // since the DTED post spacing is considered to be square.  Save its
+   // state to the keyword list.
+   //***
+   ossimString projPref = prefix?prefix:"";
+//   const ossimDatum* datum = ossimDatumFactory::instance()->wgs84();
+//    ossimProjection* proj
+//       = new ossimEquDistCylProjection(*(datum->ellipsoid()),
+//                                       ossimGpt(0.0, 0.0),
+//                                       0.0,   // false easting
+//                                       0.0);  // false northing
+//    proj->saveState(kwl, projPref);
+
+//    delete proj;
+//    proj = NULL;
+
+   //***
+   // Get the latitude origin.  DTED uses the South West corner as the origin
+   // so the latitude must be shifted to the upper left for the purpose of
+   // a tie point.
+   //***
+   double lat = uhl.latOrigin() +
+                (uhl.latInterval() * (uhl.numLatPoints()-1.0));
+   
+   // Add the tie point.
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           "ossimEquDistCylProjection",
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::ORIGIN_LATITUDE_KW,
+           0.0,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+           0.0,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LAT_KW,
+           lat,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LON_KW,
+           uhl.lonOrigin(),
+           true);
+
+   // Add the pixel scale.
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+           uhl.latInterval(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+           uhl.lonInterval(),
+           true);
+
+   //***
+   // The projection code will save a meters_per_pixel of 1.0 off so remove it
+   // since we want it to use the DECIMAL_DEGREES_PER_PIXEL keyword instead.
+   //***
+//   kwl.remove(prefix, ossimKeywordNames::METERS_PER_PIXEL_X_KW);
+//   kwl.remove(prefix, ossimKeywordNames::METERS_PER_PIXEL_Y_KW);
+
+   // Add the datum.  (always WGS-84 per spec)
+   kwl.add(prefix,
+           ossimKeywordNames::DATUM_KW,
+           ossimDatumFactory::instance()->wgs84()->code(),
+           true);
+
+   // Add the number of lines and samples.
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_LINES_KW,
+           static_cast<int>(uhl.numLatPoints()));
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_SAMPLES_KW,
+           static_cast<int>(uhl.numLonLines()));
+
+   // Add the number of reduced resolution sets.
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_REDUCED_RES_SETS_KW,
+           getNumberOfDecimationLevels());
+
+   // Add the number of bands.  (alway one...)
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_INPUT_BANDS_KW,
+           1);
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_OUTPUT_BANDS_KW,
+           1);
+
+   if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG) << "kwl:\n" << kwl << MODULE << " Exited..." << endl;
+
+   // Capture for next time.
+   setImageGeometry(kwl);
+   
+   return true;
+}
+
+ossimScalarType
+ossimDtedTileSource::getOutputScalarType() const
+{
+   return OSSIM_SSHORT16;  // Always signed 16 bit.
+}
+
+ossim_uint32 ossimDtedTileSource::getTileWidth() const
+{
+   return theTileWidth;
+}
+
+ossim_uint32 ossimDtedTileSource::getTileHeight() const
+{
+   return theTileHeight;
+}
+
+ossim_uint32 ossimDtedTileSource::getNumberOfLines(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theNumberOfLines;
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfLines(reduced_res_level);
+   }
+
+   return 0;
+}
+
+ossim_uint32 ossimDtedTileSource::getNumberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theNumberOfSamps;
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfSamples(reduced_res_level);
+   }
+
+   return 0;
+}
+
+void ossimDtedTileSource::gatherStatistics()
+{
+   //***
+   // Check to see if there is a statistics file already.  If so; do a lookup
+   // for the min and max values.
+   //***
+   ossimFilename stats_file = theImageFile.path();
+   stats_file = stats_file.dirCat(theImageFile.fileNoExtension());
+   stats_file += ".statistics";
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "Looking for " << stats_file
+                                          << " statistics file..." << std::endl;
+   }
+
+   ossimKeywordlist kwl;
+   const char* min_str = NULL;
+   const char* max_str = NULL;
+
+   if (stats_file.exists())
+   {
+      if (kwl.addFile(stats_file))
+      {
+         // Look for the min_pixel_value keyword.
+         min_str = kwl.find(ossimKeywordNames::MIN_VALUE_KW);
+         max_str = kwl.find(ossimKeywordNames::MAX_VALUE_KW);
+      }
+   }
+
+   if (min_str && max_str)
+   {
+      theMinHeight = atoi(min_str);
+      theMaxHeight = atoi(max_str);
+   }
+   else  // Scan the cell and gather the statistics...
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimDtedTileSource::gatherStatistics() scanning for min/max"
+                                          << "\nThis may take a while..."
+                                          << std::endl;
+      
+      // Start off with the min and max pegged.
+      theMinHeight =  32767;
+      theMaxHeight = -32767;
+      
+      // Put the file pointer at the start of the first elevation post.
+      theFileStr.seekg(theOffsetToFirstDataRecord, ios::beg);
+      
+      //***
+      // Loop through all records and scan for lowest min and highest max.
+      // Each record contains a row of latitude points for a given longitude.
+      // There are eight bytes in front of the post and four checksum bytes at
+      // the end so ignore them.
+      //***
+      for (ossim_uint32 i=0; i<theNumberOfSamps; i++)  // longitude direction
+      {
+         theFileStr.seekg(DATA_RECORD_OFFSET_TO_POST, ios::cur);
+         
+         for (ossim_uint32 j=0; j<theNumberOfLines; j++) // latitude direction
+         {
+            ossim_uint16 temp;
+            ossim_sint16 s;
+            theFileStr.read((char*)&temp, POST_SIZE);
+            s = convertSignedMagnitude(temp);
+            if (s < theMinHeight && s != NULL_PIXEL) theMinHeight = s;
+            if (s > theMaxHeight) theMaxHeight = s;
+         }
+
+         theFileStr.seekg(DATA_RECORD_CHECKSUM_SIZE, ios::cur);
+      }
+
+      // Add the stats to the keyword list.
+      kwl.add(ossimKeywordNames::MIN_VALUE_KW, theMinHeight);
+      kwl.add(ossimKeywordNames::MAX_VALUE_KW, theMaxHeight);
+      
+      // Write out the statistics file.
+      kwl.write(stats_file.c_str());
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDtedTileSource::gatherStatistics DEBUG:"
+         << "\ntheMinHeight:  " << theMinHeight
+         << "\ntheMaxHeight:  " << theMaxHeight
+         << std::endl;
+   }
+}
+
+ossim_uint32 ossimDtedTileSource::getImageTileWidth() const
+{
+   return 0;
+}
+
+ossim_uint32 ossimDtedTileSource::getImageTileHeight() const
+{
+   return 0;
+}
+
+ossim_uint32 ossimDtedTileSource::getNumberOfInputBands() const
+{
+   return 1;
+}
+
+double ossimDtedTileSource::getNullPixelValue(ossim_uint32 band)const
+{
+   if(theMetaData.getNumberOfBands())
+   {
+      return theMetaData.getNullPix(0);
+   }
+   return -32767.0;
+}
+double ossimDtedTileSource::getMinPixelValue(ossim_uint32 band)const
+{
+   if(theMetaData.getNumberOfBands())
+   {
+      return theMetaData.getMinPix(band);
+   }
+   return theMinHeight;
+}
+
+ double ossimDtedTileSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(theMetaData.getNumberOfBands())
+   {
+      return theMetaData.getMaxPix(band);
+   }
+   return theMaxHeight;
+}
+
+void ossimDtedTileSource::getPostSpacing(ossimDpt& postSpacing) const
+{
+   postSpacing.x = thePostSpacing.x;
+   postSpacing.y = thePostSpacing.y;
+}
+
+const ossimDtedTileSource& ossimDtedTileSource::operator=(const  ossimDtedTileSource& rhs)
+{
+   return rhs;
+} 
+
+ossimDtedTileSource::ossimDtedTileSource(const ossimDtedTileSource&)
+{
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedTileSource.h
new file mode 100644
index 0000000000..517b597f55
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/dted/ossimDtedTileSource.h
@@ -0,0 +1,209 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: David Burken
+//
+// Description:
+//
+// Contains class declaration of ossimDtedTileSource.  The ossimDtedTileSource
+// class is derived from ossimImageHandler and is intended to be an image
+// handler for DTED files.
+//
+//********************************************************************
+// $Id: ossimDtedTileSource.h,v 1.20 2005/07/25 22:46:29 dburken Exp $
+
+#ifndef ossimDtedTileSource_HEADER
+#define ossimDtedTileSource_HEADER
+
+#include <fstream>
+using namespace std;
+
+#include <imaging/formats/ossimImageHandler.h>
+
+class ossimImageData;
+
+class OSSIM_DLL ossimDtedTileSource : public ossimImageHandler
+{
+public:
+      
+   ossimDtedTileSource();
+   virtual ~ossimDtedTileSource();
+
+   enum
+   {
+      DATA_RECORD_OFFSET_TO_POST = 8,  // bytes
+      DATA_RECORD_CHECKSUM_SIZE  = 4,  // bytes
+      POST_SIZE                  = 2,  // bytes
+      NULL_PIXEL                 = -32767
+   };
+   
+   virtual ossimString getShortName()const;
+   virtual ossimString getLongName()const;
+   virtual ossimString className()const;
+
+   /**
+    *  Returns true if "theImageFile" can be opened and is a valid adrg file.
+    */
+   virtual bool open();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+   
+   /**
+    *  Returns the number of bands in the image.
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfInputBands() const;
+   
+   virtual ossim_uint32 getNumberOfOutputBands()const;
+   
+   /**
+    *  Returns the number of lines in the image.
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfLines(
+      ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    *  Returns the number of samples in the image.  
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfSamples(
+      ossim_uint32 reduced_res_level = 0) const;
+
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   /**
+    * Returns the zero based image rectangle for the reduced resolution data
+    * set (rrds) passed in.  Note that rrds 0 is the highest resolution rrds.
+    */
+   virtual ossimIrect getImageRectangle(
+      ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /**
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *  Returns true if geometry info is present, false if not.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+   
+   /**
+    * Returns the output pixel type of the tile source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32 getTileWidth() const;
+
+   /**
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;
+
+   virtual bool isOpen()const;
+
+   /**
+    * Initializes spacing to the post spacing of the cell.
+    *
+    * @param postSpacing ossimDpt to initialize with spacing where
+    * postspacing.x = longitude interval and postspacing.y = latitude interval.
+    */
+   void getPostSpacing(ossimDpt& postSpacing) const;
+   
+private:
+   // Disallow operator= and copy constrution...
+   const ossimDtedTileSource& operator=(const  ossimDtedTileSource& rhs);
+   ossimDtedTileSource(const ossimDtedTileSource&);
+
+   /**
+    * Allocated the tiles.
+    */
+   void allocate();
+
+   /**
+    *  Returns true on success, false on error.
+    */
+   bool fillBuffer(const ossimIrect& tile_rect,
+                   const ossimIrect& clip_rect);
+
+   void gatherStatistics();
+   ossim_sint16 convertSignedMagnitude(ossim_uint16& s) const;
+   
+   ossimRefPtr<ossimImageData> theTile;
+   mutable ifstream           theFileStr;
+   ossim_uint32               theTileWidth;
+   ossim_uint32               theTileHeight;   
+   ossim_uint32               theNumberOfLines;
+   ossim_uint32               theNumberOfSamps;
+   ossim_uint32               theOffsetToFirstDataRecord;
+   ossim_uint32               theDataRecordSize;
+   ossim_sint16               theMinHeight;
+   ossim_sint16               theMaxHeight;
+   ossimDpt                   thePostSpacing;
+   
+   /**
+    *  DTED data is always stored as BIG_ENDIAN.  This flag indicates that
+    *  byte swapping is needed (LITTLE_ENDIAN machine).
+    */
+   bool  theSwapBytesFlag;    
+
+TYPE_DATA
+};
+
+inline ossim_sint16 ossimDtedTileSource::convertSignedMagnitude(ossim_uint16& s) const
+{
+   // DATA_VALUE_MASK 0x7fff = 0111 1111 1111 1111
+   // DATA_SIGN_MASK  0x8000 = 1000 0000 0000 0000
+   
+   // First check to see if the bytes need swapped.
+   s = (theSwapBytesFlag ? ( (s << 8) | (s >> 8) ) : s);
+
+   // If the sign bit is set, mask it out then multiply by negative one.
+   if (s & 0x8000)
+   {
+      return (static_cast<ossim_sint16>(s & 0x7fff) * -1);
+   }
+   
+   return static_cast<ossim_sint16>(s);
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ers/ossimERSTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/ers/ossimERSTileSource.cpp
new file mode 100644
index 0000000000..d3aaa2206a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ers/ossimERSTileSource.cpp
@@ -0,0 +1,199 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Chong-Ket Chuah
+//
+// Description:
+//
+// Implementation for the class "ossimERSTileSource".  ossimERSTileSource
+// is used for reading ER Mapper raster file format.  The format consists
+// of a raster file with no extension and a header file with the same name 
+// as the raster file but with an .ers extension.
+//
+//*******************************************************************
+//  $Id: ossimERSTileSource.cpp,v 1.16 2005/05/09 12:39:38 dburken Exp $
+
+#include <imaging/formats/ers/ossimERSTileSource.h>
+#include <support_data/ers/ossimERS.h>
+
+#include <base/data_types/ossimDirectory.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimKeywordNames.h>
+
+
+RTTI_DEF1(ossimERSTileSource, "ossimERSTileSource", ossimGeneralRasterTileSource);
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimERSTileSource::ossimERSTileSource()
+   :  ossimGeneralRasterTileSource(),
+      theHdr(NULL)
+{
+}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimERSTileSource::ossimERSTileSource(const ossimKeywordlist& kwl,
+                                               const char* prefix)
+   :  ossimGeneralRasterTileSource(),
+      theHdr(NULL)
+{
+   if (loadState(kwl, prefix) == false)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+}
+
+//*******************************************************************
+// Destructor:
+//*******************************************************************
+ossimERSTileSource::~ossimERSTileSource()
+{
+   if (theHdr)
+   {
+      delete theHdr;
+      theHdr = NULL;
+   }
+}
+
+bool ossimERSTileSource::open(const ossimFilename& fileName)
+{
+   // Open and parse the header file
+   theHdr = new ossimERS(fileName);
+   
+//   theHdr->dump(cout);
+   
+   if(theHdr->errorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      delete theHdr;
+      theHdr = NULL;
+      return false;
+   }
+   else
+   {
+      vector<ossimFilename> f;
+	  ossimFilename fne;
+	  ossimFilename fpath = fileName.path();
+	  if (fpath.empty())
+		fne = fileName.fileNoExtension();
+	  else
+		fne = fpath+"/"+fileName.fileNoExtension();
+      f.push_back(fne);
+      ossimGeneralRasterInfo genRasterInfo(f,
+                                           theHdr->theCelltype,
+                                           OSSIM_BIL,
+                                           theHdr->theBands,
+                                           theHdr->theLine,
+                                           theHdr->theSample,
+                                           0,
+                                           ossimGeneralRasterInfo::NONE,
+                                           0);
+      if(theHdr->theHasNullCells)
+      {
+         ossim_uint32 i = 0;
+         ossim_uint32 bands = static_cast<ossim_uint32>(theHdr->theBands);
+         for(i = 0; i < bands; ++i)
+         {
+            genRasterInfo.setNullPixelValue(i, theHdr->theNullCell);
+         }
+      }
+      ossimFilename metadataFile = fne;
+      metadataFile = metadataFile + ".omd";
+
+      if(metadataFile.exists())
+      {
+         ossimKeywordlist kwl;
+      
+         kwl.addFile(metadataFile.c_str());
+      
+         theMetaData.loadState(kwl);
+         ossim_uint32 i = 0;
+         ossim_uint32 bands = static_cast<ossim_uint32>(theHdr->theBands);
+         for(i = 0; i < bands; ++i)
+         {
+            if(theMetaData.getMinValuesValidFlag())
+            {
+               genRasterInfo.setMinPixelValue(i, theMetaData.getMinPix(i));
+            }
+            if(theMetaData.getMaxValuesValidFlag())
+            {
+               genRasterInfo.setMaxPixelValue(i, theMetaData.getMaxPix(i));
+            }
+            if(theMetaData.getNullValuesValidFlag())
+            {
+               genRasterInfo.setNullPixelValue(i, theMetaData.getNullPix(i));
+            }
+         }
+      }
+      ossimNotify(ossimNotifyLevel_INFO)
+         << "general raster info is\n";
+      genRasterInfo.print(ossimNotify(ossimNotifyLevel_INFO));
+      ossimGeneralRasterTileSource::open(genRasterInfo);
+   }
+	   
+   return true;
+}
+   
+
+bool ossimERSTileSource::getImageGeometry(ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   if (theGeometryKwl.getSize())
+   {
+      kwl = theGeometryKwl;
+      return true;
+   }
+   
+   if(theHdr)
+   {
+      
+      bool result = theHdr->toOssimProjectionGeom(kwl, prefix);
+      if (result == true)
+      {
+         // Capture for next time.
+         setImageGeometry(kwl);
+      }
+      return result;
+   }
+
+   return false;
+}
+
+bool ossimERSTileSource::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   const char* lookup = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+
+   if (lookup)
+   {
+      ossimFilename fileName = lookup;
+
+      bool result =  open(fileName);
+      ossimImageSource::loadState(kwl, prefix);
+      return result;
+   }
+      
+   return ossimGeneralRasterTileSource::loadState(kwl, prefix);
+}
+
+ossimString ossimERSTileSource::getShortName() const
+{
+   return ossimString("ERS");
+}
+
+ossimString ossimERSTileSource::getLongName() const
+{
+   return ossimString("ER Mapper Raster");
+}
+
+ossimString  ossimERSTileSource::className() const
+{
+   return ossimString("ossimERSTileSource");
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ers/ossimERSTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/ers/ossimERSTileSource.h
new file mode 100644
index 0000000000..640b8b3f2a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ers/ossimERSTileSource.h
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Chong-Ket Chuah
+//
+// Description:
+//
+// Contains class definition for the class "ossimERSTileSource".
+//
+//*******************************************************************
+//  $Id: ossimERSTileSource.h,v 1.6 2005/07/25 22:47:29 dburken Exp $
+
+#ifndef ossimERSTileSource_HEADER
+#define ossimERSTileSource_HEADER
+
+#include <imaging/formats/general_raster/ossimGeneralRasterTileSource.h>
+#include <support_data/ers/ossimERS.h>
+
+
+class OSSIM_DLL ossimERSTileSource : public ossimGeneralRasterTileSource
+{
+public:
+   ossimERSTileSource();
+
+   ossimERSTileSource(const ossimKeywordlist& kwl, const char* prefix=0);
+   
+   virtual ~ossimERSTileSource();
+
+   virtual ossimString getShortName() const;
+   virtual ossimString getLongName() const;
+   virtual ossimString className() const;
+
+   virtual bool open(const ossimFilename& filename);
+  
+  /*!
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *  Returns true if geometry info is present, false if not.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = NULL);
+private:
+
+   void openHeader(const ossimFilename& file);
+   
+   ossimERS* theHdr;
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterInfo.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterInfo.cpp
new file mode 100644
index 0000000000..6a274137e5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterInfo.cpp
@@ -0,0 +1,611 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimGeneralRasterInfo.cpp,v 1.26 2005/06/15 19:44:03 gpotts Exp $
+
+#include <stdlib.h>
+#include <iostream>
+#include <iomanip>
+
+#include <imaging/formats/general_raster/ossimGeneralRasterInfo.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimString.h>
+#include <base/misc/lookup_tables/ossimInterleaveTypeLut.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+
+static const ossimKeyword
+NUMBER_LINES("number_lines",
+             "Number of lines in the raster image.");
+
+static const ossimKeyword
+NUMBER_SAMPLES("number_samples",
+              "Number of samples in the raster image.");
+
+static const ossimKeyword
+VALID_START_LINE("valid_start_line",
+                 "First valid line of raster image(zero based).");
+
+static const ossimKeyword
+VALID_STOP_LINE("valid_stop_line",
+                "Last valid line of raster image(zero based).");
+
+static const ossimKeyword
+VALID_START_SAMPLE("valid_start_sample",
+                   "First valid sample of raster image(zero based).");
+
+static const ossimKeyword
+VALID_STOP_SAMPLE("valid_stop_sample",
+                  "Last valid sample of raster image(zero based).");
+
+static const ossimKeyword
+SUB_IMAGE_OFFSET_LINE(
+   "sub_image_offset_line",
+   "Pixel line offset of sub-image in the full-image pixel space.");
+
+static const ossimKeyword
+SUB_IMAGE_OFFSET_SAMP(
+   "sub_image_offset_samp",
+   "Pixel sample offset of sub-image in the full-image pixel space."); 
+
+static const ossimKeyword
+HEADER_SIZE("header_size",
+            "Header size in bytes.");
+
+static const ossimKeyword
+SET_NULLS("set_fill_to_nulls_mode",
+          "0 = do nothing to pixels,\n1 = all zeroes to min values,\
+\n2 = zeroes to null on edges only.");
+
+static const ossimKeyword
+PIXELS_TO_CHOP("pixels_to_chop",
+               "Ammount of pixels to chop from edge.");
+
+static const ossimInterleaveTypeLut INTERLEAVE_TYPE_LUT;
+
+static ossimTrace traceDebug("ossimGeneralRasterInfo:debug");
+
+ossimGeneralRasterInfo::ossimGeneralRasterInfo()
+   :
+      theImageFileList(),
+      theInterleaveType(OSSIM_BIL),
+      theRawImageRect(0,0,0,0),
+      theValidImageRect(0,0,0,0),
+      theImageRect(0,0,0,0),
+      theSubImageOffset(0,0),
+      theHeaderSize(0),
+      theSetNullsMode(NONE),
+      thePixelsToChop(0),
+      theImageDataByteOrder(OSSIM_LITTLE_ENDIAN)
+{}
+
+ossimGeneralRasterInfo::ossimGeneralRasterInfo(const vector<ossimFilename>& imageFileList,
+                                               ossimScalarType     pixelType,
+                                               ossimInterleaveType il_type,
+                                               ossim_uint32        numberOfBands,
+                                               ossim_uint32        lines,
+                                               ossim_uint32        samples,
+                                               ossim_uint32        headerSize,
+                                               ossimFillMode       nullsMode,
+                                               ossim_uint32        pixelsToChop)
+   :
+  theMetaData(pixelType,
+	      numberOfBands),
+      theImageFileList(imageFileList),
+      theInterleaveType(il_type),
+      theRawImageRect(0,0,0,0),
+      theValidImageRect(0,0,0,0),
+      theImageRect(0,0,0,0),
+      theSubImageOffset(0,0),
+      theHeaderSize(headerSize),
+      theSetNullsMode(nullsMode),
+      thePixelsToChop(pixelsToChop),
+      theImageDataByteOrder(OSSIM_LITTLE_ENDIAN)
+{
+   theRawImageRect.set_lry(lines - 1);
+   theRawImageRect.set_lrx(samples - 1);
+   theValidImageRect = theRawImageRect;
+   theImageRect = theRawImageRect;
+}
+
+ossimGeneralRasterInfo::ossimGeneralRasterInfo(const ossimKeywordlist& kwl,
+                     const char* prefix)
+   :
+      theImageFileList(),
+      theInterleaveType(OSSIM_BIL),
+      theRawImageRect(0,0,0,0),
+      theValidImageRect(0,0,0,0),
+      theImageRect(0,0,0,0),
+      theSubImageOffset(0,0),
+      theHeaderSize(0),
+      theSetNullsMode(NONE),
+      thePixelsToChop(0),
+      theImageDataByteOrder(OSSIM_LITTLE_ENDIAN)
+{
+   loadState(kwl, prefix);
+}
+
+ossimGeneralRasterInfo::~ossimGeneralRasterInfo()
+{
+}
+  
+std::ostream& ossimGeneralRasterInfo::print(std::ostream& out) const
+{
+   //***
+   // This will print in a keyword format that can be read by the constructor.
+   // that takes a keyword list.
+   //***
+   out << setiosflags(ios::left);
+   ossim_uint32 i;
+   for (i=0; i<theImageFileList.size(); ++i)
+   {
+      out << ossimKeywordNames::FILENAME_KW << (i+1) << ":  "
+          << theImageFileList[i].c_str() << endl;
+   }
+            
+   out  << ossimScalarTypeLut::instance()->getKeyword().key() << ":  "
+        << ossimScalarTypeLut::instance()->getEntryString(getScalarType())
+        << "\n" << INTERLEAVE_TYPE_LUT.getKeyword().key() << ":  "
+        << INTERLEAVE_TYPE_LUT.getEntryString(theInterleaveType)
+        << "\n" << ossimKeywordNames::NUMBER_BANDS_KW << ":  "
+        << numberOfBands()
+        << "\n" << NUMBER_LINES.key() << ":  "
+        << rawLines()
+        << "\n" << NUMBER_SAMPLES.key() << ":  "
+        << rawSamples()
+        << "\n" << VALID_START_LINE.key() << ":  "
+        << theValidImageRect.ul().y
+        << "\n" << VALID_STOP_LINE.key() << ":  "
+        << theValidImageRect.lr().y
+        << "\n" << VALID_START_SAMPLE.key() << ":  "
+        << theValidImageRect.ul().x
+        << "\n" << VALID_STOP_SAMPLE.key() << ":  "
+        << theValidImageRect.lr().x
+        << "\n" << SUB_IMAGE_OFFSET_LINE.key() << ":  "
+        << theSubImageOffset.line
+        << "\n" << SUB_IMAGE_OFFSET_SAMP.key() << ":  "
+        << theSubImageOffset.samp
+        << "\n" << HEADER_SIZE.key() << ":  "
+        << theHeaderSize
+        << "\n" << SET_NULLS.key() << ":  "
+        << (ossim_uint32)theSetNullsMode
+        << "\n" << PIXELS_TO_CHOP.key() << ":  "
+        << thePixelsToChop
+        << endl;
+   
+   if (bytesPerPixel() > 1)
+   {
+      out << ossimKeywordNames::BYTE_ORDER_KW << ":  "
+          << (theImageDataByteOrder == OSSIM_LITTLE_ENDIAN ? "little_endian" :
+              "big_endian")
+          << endl;
+   }
+   for (i=0; i<numberOfBands(); ++i)
+   {
+      out << "band" << i+1 << ".min_value: "  << theMetaData.getMinPix(i)
+          << "\nband" << i+1 << ".max_value: "  << theMetaData.getMaxPix(i)
+          << "\nband" << i+1 << ".null_value: " << theMetaData.getNullPix(i)
+          << endl;
+   }
+   
+   return ossimErrorStatusInterface::print(out);
+}
+
+void ossimGeneralRasterInfo::setFillToNullsMode(ossim_uint32 mode)
+{
+   static const char MODULE[] = "ossimGeneralRasterInfo::setFillToNullMode";
+   if(mode < 3)
+   {
+      theSetNullsMode = (ossimFillMode)mode;
+   }
+   else
+   {
+      cerr << MODULE << " ERROR:"
+           << "\nmode out of bounds(0 - 2):  " << mode << endl
+           << "\nmode has not been changed." << endl;
+   }
+}
+
+ossim_uint32 ossimGeneralRasterInfo::bytesPerPixel(ossimScalarType type) const
+{
+   ossim_uint32 bpp;
+   
+   switch (type)
+   {
+   case OSSIM_UCHAR:
+      bpp = 1;
+      break;
+   case OSSIM_USHORT16:
+   case OSSIM_SSHORT16:
+   case OSSIM_USHORT11:
+      bpp = 2;
+      break;
+   case OSSIM_FLOAT:
+   case OSSIM_NORMALIZED_FLOAT:
+      bpp = 4;
+      break;
+   case OSSIM_NORMALIZED_DOUBLE:
+   case OSSIM_DOUBLE:
+      bpp = 8;
+      break;
+   default:
+      bpp = 0;
+      break;
+   }
+
+   return bpp;
+}
+
+void ossimGeneralRasterInfo::setImageDataByteOrder(ossimByteOrder byteOrder)
+{
+   theImageDataByteOrder = byteOrder;
+}
+
+bool ossimGeneralRasterInfo::saveState(ossimKeywordlist& kwl,
+                                       const char* prefix) const
+{
+   for (ossim_uint32 i=0; i<theImageFileList.size(); ++i)
+   {
+      ossimString kw = ossimKeywordNames::FILENAME_KW;
+      kw += ossimString::toString(i+1);
+      kwl.add(prefix, theImageFileList[i].c_str());
+   }
+
+   theMetaData.saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           NUMBER_LINES,
+           rawLines(),
+           true);
+   kwl.add(prefix,
+           NUMBER_SAMPLES,
+           rawSamples(),
+           true);
+   kwl.add(prefix,
+           HEADER_SIZE,
+           theHeaderSize,
+           true);
+   kwl.add(prefix,
+           SUB_IMAGE_OFFSET_LINE,
+           theSubImageOffset.line,
+           true);
+   kwl.add(prefix,
+           SUB_IMAGE_OFFSET_SAMP,
+           theSubImageOffset.samp,
+           true);
+   kwl.add(prefix,
+           VALID_START_LINE,
+           theValidImageRect.ul().y,
+           true);
+   kwl.add(prefix,
+           VALID_STOP_LINE,
+           theValidImageRect.lr().y,
+           true);
+   kwl.add(prefix,
+           VALID_START_SAMPLE,
+           theValidImageRect.ul().x,
+           true);
+   kwl.add(prefix,
+           VALID_STOP_SAMPLE,
+           theValidImageRect.ur().x,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::INTERLEAVE_TYPE_KW,
+           INTERLEAVE_TYPE_LUT.getEntryString(theInterleaveType),
+           true);
+
+   kwl.add(prefix,
+           PIXELS_TO_CHOP,
+           thePixelsToChop,
+           true);
+
+   kwl.add(prefix,
+           SET_NULLS,
+           theSetNullsMode,
+           true);
+
+
+   if (bytesPerPixel() > 1)
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::BYTE_ORDER_KW,
+              (theImageDataByteOrder == OSSIM_LITTLE_ENDIAN ? "little_endian" :
+               "big_endian"),
+              true);
+   }
+
+   return true;
+}
+
+bool ossimGeneralRasterInfo::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   static const char MODULE[] = "ossimGeneralRasterInfo::loadState";
+   // Check for errors in the ossimKeywordlist.
+   if(kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      cerr << MODULE << " ERROR:\n"
+           << "Detected an error in the keywordlist:  " << kwl
+           << endl;
+      return false;
+   }
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\nprefix:  " << (prefix ? prefix : "")
+           << "\nInput keyword list\n"
+           << kwl
+           << endl;
+   }
+
+   const char* kwlLookup = 0; // Use for keyword list lookups.
+
+   if(!theMetaData.loadState(kwl, prefix))
+     {
+       return false;
+     }
+
+   int tmp = INTERLEAVE_TYPE_LUT.getEntryNumber(kwl);
+   if (tmp == ossimLookUpTable::NOT_FOUND)
+   {
+      theInterleaveType = OSSIM_BIL;
+   }
+   else
+   {
+      theInterleaveType = static_cast<ossimInterleaveType>(tmp);
+   }
+   
+    // Get the image files.
+   
+   theImageFileList.clear(); // Start with a clean list.
+   
+   if (theInterleaveType != OSSIM_BSQ_MULTI_FILE)
+   {
+      // Look for "filename" first, then deprecated "image_file".      
+      kwlLookup = kwl.find(ossimKeywordNames::FILENAME_KW);
+      if (!kwlLookup)
+      {
+         // deprecated keyword...
+         kwlLookup = kwl.find(ossimKeywordNames::IMAGE_FILE_KW);
+      }
+      
+      if (kwlLookup)
+      {
+         theImageFileList.push_back(ossimFilename(kwlLookup));
+      }
+      else
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         if (traceDebug())
+         {
+            cerr << "ERROR:\n"
+                 << "Required keyword not found:  "
+                 << ossimKeywordNames::FILENAME_KW << endl;
+         }
+         return false;
+      }
+   }
+   else
+   {
+      // multiple file names.
+      ossim_uint32 count = 0;
+
+      // look for image file key word with no number.
+      // Required to have this.
+      kwlLookup = kwl.find(ossimKeywordNames::FILENAME_KW);
+      if (!kwlLookup)
+      {
+         // deprecated keyword...
+         kwlLookup = kwl.find(ossimKeywordNames::IMAGE_FILE_KW);
+      }
+      
+      if (kwlLookup)
+      {
+         theImageFileList.push_back(ossimFilename(kwlLookup));
+         ++count;
+      }
+      
+      ossim_int32 i = 0;
+      while ( (count < numberOfBands()) && (i < 1000) )
+      {
+         ossimString kw = ossimKeywordNames::FILENAME_KW;
+         kw += ossimString::toString(i);
+         kwlLookup = kwl.find(kw);
+         if (!kwlLookup)
+         {
+            // Lookup for deprecated keyword.
+            kw = ossimKeywordNames::IMAGE_FILE_KW;
+            kw += ossimString::toString(i);
+            kwlLookup = kwl.find(kw);
+         }
+         
+         if (kwlLookup)
+         {
+            theImageFileList.push_back(ossimFilename(kwlLookup));
+            ++count;
+         }
+         ++i;
+      }
+
+      if (count != numberOfBands())  // Error, count should equal bands!
+      {
+         if (traceDebug())
+         {
+            cerr << " ERROR:\n"
+                 << "Required keyword not found:  "
+                 << ossimKeywordNames::FILENAME_KW
+                 << "\nInterleave type is multi file; however,"
+                 << " not enough were pick up!"  << endl;
+         }
+         return false; 
+      }
+   }
+
+   kwlLookup = kwl.find(NUMBER_LINES);  // Required to have this.
+   if (kwlLookup)
+   {
+      theRawImageRect.set_lry(atoi(kwlLookup) - 1);
+   }
+   else
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      if (traceDebug())
+      {
+         cerr << " ERROR:\n"
+              << "Required keyword not found:  " << NUMBER_LINES << endl;
+      }
+      return false;
+   }
+
+   kwlLookup = kwl.find(NUMBER_SAMPLES);  // Required to have this.
+   if (kwlLookup)
+   {
+      theRawImageRect.set_lrx(atoi(kwlLookup) - 1);
+   }
+   else
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      if (traceDebug())
+      {
+         cerr << " ERROR:\n"
+              << "Required keyword not found:  " << NUMBER_SAMPLES << endl;
+      }
+      return false;
+   }
+
+   kwlLookup = kwl.find(VALID_START_LINE); // Default is zero.
+   if (kwlLookup)
+   {
+      theValidImageRect.set_uly(atoi(kwlLookup));
+   }
+
+   kwlLookup = kwl.find(VALID_STOP_LINE); // Default is last line.
+   if (kwlLookup)
+   {
+      theValidImageRect.set_lry(atoi(kwlLookup));
+   }
+   else
+   {
+      theValidImageRect.set_lry(theRawImageRect.lr().y);
+   }
+
+   if (theValidImageRect.lr().y < theValidImageRect.ul().y)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      cerr << " ERROR:"
+           << "\nValid stop line < start line."
+           << "\nValid start line:  " << theValidImageRect.ul().y
+           << "\nValid stop line:   " << theValidImageRect.lr().y
+           << "\nError status has been set.  Returning." << endl;
+      return false;
+   }
+
+   kwlLookup = kwl.find(VALID_START_SAMPLE); // Default is zero.
+   if (kwlLookup)
+   {
+     theValidImageRect.set_ulx(atoi(kwlLookup));
+   }
+
+   kwlLookup = kwl.find(VALID_STOP_SAMPLE); // Default is last sample.
+   if (kwlLookup) 
+   {
+      theValidImageRect.set_lrx(atoi(kwlLookup));
+   }
+   else
+   {
+      theValidImageRect.set_lrx(theRawImageRect.lr().x); 
+   }
+
+   if (theValidImageRect.lr().x < theValidImageRect.ul().x)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      cerr << " ERROR:"
+           << "\nValid stop samp < start samp."
+           << "\nValid start samp:  " << theValidImageRect.ul().x
+           << "\nValid stop samp:   " << theValidImageRect.lr().x
+           << "\nError status has been set.  Returning." << endl;
+      return false;
+   }
+
+   theImageRect.set_lry(theValidImageRect.lr().y -
+                        theValidImageRect.ul().y);
+   theImageRect.set_lrx(theValidImageRect.lr().x -
+                        theValidImageRect.ul().x);
+
+   kwlLookup = kwl.find(SUB_IMAGE_OFFSET_LINE); // Default is zero.
+   if (kwlLookup)
+      theSubImageOffset.line = atoi(kwlLookup);
+
+   kwlLookup = kwl.find(SUB_IMAGE_OFFSET_SAMP); // Default is zero.
+   if (kwlLookup)
+      theSubImageOffset.samp = atoi(kwlLookup);
+      
+   kwlLookup = kwl.find(HEADER_SIZE); // Default is zero.
+   if (kwlLookup)
+   {
+      theHeaderSize = atoi(kwlLookup);
+   }
+
+   kwlLookup = kwl.find(SET_NULLS); // Default is 2.
+   if (kwlLookup)
+   {
+      int tmp;
+      tmp = atoi(kwlLookup);
+      if ((tmp < 3) && (tmp > -1))
+      {
+         theSetNullsMode = (ossimFillMode)tmp;
+      }
+      else
+      {
+         theSetNullsMode = ZEROES_TO_NULL_EDGES_ONLY;  // 2
+         ossimNotify(ossimNotifyLevel_WARN)
+            << " WARNING:"
+            << "\nset_fill_to_nulls_mode value out of range."
+            << "\nDefaulted to 2" << endl;
+      }
+   }
+
+   kwlLookup = kwl.find(PIXELS_TO_CHOP); // Default is zero.
+   if (kwlLookup)
+   {
+      thePixelsToChop = atoi(kwlLookup);
+   }
+
+   if (bytesPerPixel() > 1)
+   {
+      // get the byte order of the data.
+      kwlLookup = kwl.find(ossimKeywordNames::BYTE_ORDER_KW);
+      if (kwlLookup)
+      {
+         ossimString s(kwlLookup);
+         if (s.trim() != "")  // Check for empty string.
+         {
+            s.downcase();
+            if (s.contains("big"))
+            {
+               theImageDataByteOrder = OSSIM_BIG_ENDIAN;
+            }
+            else if(s.contains("little"))
+            {
+               theImageDataByteOrder = OSSIM_LITTLE_ENDIAN;
+            }
+         }
+      }
+   }
+   if (traceDebug())
+   {
+     CLOG << "Exiting....." << endl;
+   }
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterInfo.h b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterInfo.h
new file mode 100644
index 0000000000..299dd18076
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterInfo.h
@@ -0,0 +1,367 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimGeneralRasterInfo
+//*******************************************************************
+//  $Id: ossimGeneralRasterInfo.h,v 1.18 2005/04/18 14:17:52 dburken Exp $
+
+#ifndef ossimGeneralRasterInfo_HEADER
+#define ossimGeneralRasterInfo_HEADER
+
+#include <base/common/ossimObject.h>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/context/ossimErrorContext.h>
+#include <imaging/ossimImageMetaData.h>
+
+//***
+// Forward class declarations.
+//***
+class ossimKeywordlist;
+class ossimIect;
+class ossimDrect;
+class ossimString;
+
+
+//***************************************************************************
+// CLASS:  ossimGeneralRasterInfo
+//***************************************************************************
+class OSSIMDLLEXPORT ossimGeneralRasterInfo : public ossimObject,
+                                              public ossimErrorStatusInterface
+{
+public:
+
+   enum ossimFillMode
+   {
+      NONE,
+      ZEROES_TO_MIN,
+      ZEROES_TO_NULL_EDGES_ONLY
+   };
+
+   enum
+   {
+      UNKNOWN = -1
+   };
+   
+   ossimGeneralRasterInfo();
+
+   ossimGeneralRasterInfo(const vector<ossimFilename>& imageFileList,
+                          ossimScalarType      pixelType,
+                          ossimInterleaveType  il_type,
+                          ossim_uint32         numberOfBands,
+                          ossim_uint32         lines,
+                          ossim_uint32         samples,
+                          ossim_uint32         headerSize,
+                          ossimFillMode        nullsMode,
+                          ossim_uint32         pixelsToChop);
+   
+   ossimGeneralRasterInfo(const ossimKeywordlist& kwl, const char* prefix=0);
+
+   ~ossimGeneralRasterInfo ();
+
+   /*!
+    *  Zero based rectangle of the valid image.
+    */
+   ossimIrect imageRect()       const { return theImageRect;      }
+
+   /*!
+    *  Returns the rectangle of where the image is within the raster file.
+    *  In most cases this will be the same as the rawImageRect. (zero based)
+    */
+   ossimIrect validImageRect()  const { return theValidImageRect; }
+
+   /*!
+    *  Zero based rectangle of the raw image.
+    */
+   ossimIrect rawImageRect()    const { return theRawImageRect;   }
+
+   /*!
+    * Returns the offset of this image's origin to a full-image's origin, in
+    * the case where this image is a sub-image of a larger full-image.
+    */
+   ossimIpt subImageOffset()  const { return theSubImageOffset; }
+
+   /*!
+    *  Returns the size of header in bytes.
+    */
+   ossim_uint32 headerSize()      const { return theHeaderSize;     }
+
+   /*!
+    *  Returns the fill mode.  This is used to flip values on ingest.
+    *  Valid Mode Enumerations:
+    *  - 0  Do nothing to the pixels on ingest.
+    *  - 1  Flip all zeroes to the minimum pixel value.
+    *  - 2  Flip zeroes within the image line to minimum pixel value.
+    *       This is used by edge walking code.
+    */
+   ossim_uint32 fillToNullsMode() const { return theSetNullsMode;   }
+
+   /*!
+    *  Sets theSetNullsMode.
+    */
+   void setFillToNullsMode(ossim_uint32 mode);
+
+   void setMinPixelValue(ossim_uint32 band, double value)
+      {
+         theMetaData.setMinPix(band, value);
+      }
+  double getMinPixelValue(ossim_uint32 band)const
+  {
+    return theMetaData.getMinPix(band);
+  }
+   void setMaxPixelValue(ossim_uint32 band, double value)
+      {
+         theMetaData.setMaxPix(band, value);
+      }
+  double getMaxPixelValue(ossim_uint32 band)const
+  {
+    return theMetaData.getMaxPix(band);
+  }
+   void setNullPixelValue(ossim_uint32 band, double value)
+      {
+         theMetaData.setNullPix(band, value);
+      }
+  double getNullPixelValue(ossim_uint32 band)const
+  {
+    return theMetaData.getNullPix(band);
+  }
+   /*!
+    *  Sets theNumberOfBands.
+    */
+   void setNumberOfBands(ossim_uint32 bands) { theMetaData.setNumberOfBands(bands); }
+
+   /*!
+    *  Returns the number of pixels from the edge of a line
+    *  to set to the fill value.  This can be used to eliminate
+    *  resampling error on the edge of an image and still keep
+    *  the image demensions relative to the geometry file.
+    */
+   ossim_uint32 pixelsToChop()   const { return thePixelsToChop;   } 
+
+   /*!
+    *  Number of bands.  Defaulted to one.
+    */
+   ossim_uint32 numberOfBands()  const { return theMetaData.getNumberOfBands();  }
+
+   /*!
+    *  Enumerated in InterleaveTypeLUT. Should be either bip,
+    *  bil or bsq.  Defaulted to bip.
+    */
+   ossimInterleaveType interleaveType() const { return theInterleaveType; }
+
+   /*!
+    * Returns the pixel type represented as a "PixelType" enumeration.
+    * See "constants.h" file for PixelType enumerations.
+    */
+   ossimScalarType getScalarType() const { return theMetaData.getScalarType(); }
+   
+   /*!
+    *  Returns the number of lines within "theValidImageRect".
+    */
+   ossim_uint32 validLines()        const;
+
+   /*!
+    *  Returns the number of lines within "theRawImageRect".
+    */
+   ossim_uint32 rawLines()          const;
+
+   /*!
+    *  Returns the number of bytes in a raw line.
+    */
+   ossim_uint32 bytesPerRawLine()   const;
+
+   /*!
+    *  Returns the number of bytes in a valid line.
+    */
+   ossim_uint32 bytesPerValidLine() const;
+
+   /*!
+    *  Returns the number of samples within "theValidImageRect".
+    */
+   ossim_uint32 validSamples()      const;
+
+   /*!
+    *  Returns the number of samples within "theRawImageRect".
+    */
+   ossim_uint32 rawSamples()        const;
+
+   /*!
+    *  Returns the offset in bytes to the first valid sample in the image.
+    */
+   ossim_uint32 offsetToFirstValidSample() const;
+   
+   vector<ossimFilename> getImageFileList() const { return theImageFileList; }
+
+   void setImageFileList(const vector<ossimFilename>& list)
+      { theImageFileList = list; }
+   void setHeaderSize(ossim_uint32 headerSize) {theHeaderSize = headerSize;}
+   void setInterleaveType(ossimInterleaveType il_type)
+      {theInterleaveType = il_type;}
+   virtual std::ostream& print(std::ostream& out) const;
+   void setImageRect(const ossimIrect& imageRect){theImageRect = imageRect;}
+   void setValidImageRect(const ossimIrect &imageRect)
+      {theValidImageRect = imageRect;}
+   void setRawImageRect(const ossimIrect &imageRect)
+      {theRawImageRect=imageRect;}
+   void setSubImageOffset(const ossimIpt& d) { theSubImageOffset = d; }
+   
+   ossim_uint32 bytesPerPixel(ossimScalarType type) const;
+   ossim_uint32 bytesPerPixel() const;
+   
+   ossimByteOrder getImageDataByteOrder() const
+      { return theImageDataByteOrder; }
+
+   void setImageDataByteOrder(ossimByteOrder byteOrder);
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+private:
+  ossimImageMetaData     theMetaData;
+   vector<ossimFilename> theImageFileList;
+   ossimInterleaveType   theInterleaveType;
+   ossim_uint32                theNumberOfBands;
+
+   /*!
+    *  The zero based rectangle of the entire image not including any header.
+    */
+   ossimIrect theRawImageRect;
+
+   /*!
+    *  The rectangle representing where the valid part of the image lies
+    *  within "theRawImageRect".
+    */
+   ossimIrect theValidImageRect;
+
+   /*!
+    *  The valid image rectangle normalized to be zero based.
+    */
+   ossimIrect theImageRect;
+
+   /*!
+    *  The offset from the full-image origin to this image's origin
+    */
+   ossimIpt theSubImageOffset;
+
+   /*!
+    *  Size of header in bytes.
+    */
+   ossim_uint32 theHeaderSize;
+
+   /*!
+    *  Mode of how to handle pixels on import.
+    *   0 = Do nothing the pixels.
+    *   1 = Set any zeroes to min value of radiometry.
+    *   2 = Set zeroes on line edges only to nulls; any other zeroes are
+    *       set to min value of radiometry.
+    */
+   ossimFillMode theSetNullsMode;
+
+   /*!
+    *  Amount of pixels to chop for each line edge.
+    */
+   ossim_uint32 thePixelsToChop;
+
+   /*!
+    *  The byte order the image data is stored in.
+    */
+  ossimByteOrder theImageDataByteOrder;
+};
+
+
+//***
+// Inlines
+//***
+inline ossim_uint32 ossimGeneralRasterInfo::validLines() const
+{
+   return theValidImageRect.lr().y - theValidImageRect.ul().y + 1;
+}
+
+inline ossim_uint32 ossimGeneralRasterInfo::rawLines() const
+{
+   return theRawImageRect.lr().y - theRawImageRect.ul().y + 1;
+}
+
+inline ossim_uint32 ossimGeneralRasterInfo::bytesPerRawLine() const
+{
+   if (interleaveType() == OSSIM_BIP)
+   {
+      return rawSamples() * bytesPerPixel() * numberOfBands();
+   }
+   else
+   {
+      return rawSamples() * bytesPerPixel();
+   }
+}
+
+inline ossim_uint32 ossimGeneralRasterInfo::bytesPerValidLine() const
+{
+   if (interleaveType() == OSSIM_BIP)
+   {
+      return validSamples() * bytesPerPixel() * numberOfBands();
+   }
+   else
+   {
+      return validSamples() * bytesPerPixel();
+   }
+}
+
+inline ossim_uint32 ossimGeneralRasterInfo::validSamples() const
+{
+   return theValidImageRect.lr().x - theValidImageRect.ul().x + 1;
+}
+
+inline ossim_uint32 ossimGeneralRasterInfo::rawSamples() const
+{
+   return theRawImageRect.lr().x - theRawImageRect.ul().x + 1;
+}
+
+inline ossim_uint32 ossimGeneralRasterInfo::bytesPerPixel() const
+{
+   return bytesPerPixel((ossimScalarType)theMetaData.getScalarType());
+}
+
+inline ossim_uint32 ossimGeneralRasterInfo::offsetToFirstValidSample() const
+{
+   if (interleaveType() == OSSIM_BIP)
+   {
+      return headerSize() +
+         ( bytesPerRawLine() * validImageRect().ul().y ) +
+         ( validImageRect().ul().x * numberOfBands() * bytesPerPixel() );
+   }
+   else if (interleaveType() == OSSIM_BIL)
+   {
+      return headerSize() +
+         ( bytesPerRawLine() * validImageRect().ul().y * numberOfBands() ) +
+         ( validImageRect().ul().x * bytesPerPixel());
+   }
+   else // BSQ
+   {
+      return headerSize() +
+         ( bytesPerRawLine() * validImageRect().ul().y ) +
+         ( validImageRect().ul().x * bytesPerPixel() );
+   }
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterTileSource.cpp
new file mode 100644
index 0000000000..fe1428b98c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterTileSource.cpp
@@ -0,0 +1,1192 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for ossimGeneralRasterTileSource.
+//*******************************************************************
+//  $Id: ossimGeneralRasterTileSource.cpp,v 1.73 2005/11/17 15:05:57 gpotts Exp $
+
+#include <imaging/formats/general_raster/ossimGeneralRasterTileSource.h>
+#include <base/common/ossimConstants.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/misc/lookup_tables/ossimInterleaveTypeLut.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/misc/ossimEndian.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+#include <base/factory/ossimStreamFactoryRegistry.h>
+
+RTTI_DEF1_INST(ossimGeneralRasterTileSource,
+               "ossimGeneralRasterTileSource",
+               ossimImageHandler)
+
+static ossimTrace traceDebug("ossimGeneralRasterTileSource:debug");
+
+// For interleave type enum to string conversions.
+static const ossimInterleaveTypeLut ILUT;
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimGeneralRasterTileSource::ossimGeneralRasterTileSource()
+   :
+      ossimImageHandler(),
+      theTile(NULL),
+      theBuffer(NULL),
+      theBufferInterleave(OSSIM_BIL),
+      theFileStrList(0),
+      theImageData(),
+      theBufferRect(0, 0, 0, 0),
+      theSwapBytesFlag(false),
+      theBufferSizeInPixels(0)
+{}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimGeneralRasterTileSource::
+ossimGeneralRasterTileSource(const ossimKeywordlist& kwl,
+                             const char* prefix)
+   :
+      ossimImageHandler(),
+      theTile(NULL),
+      theBuffer(NULL),
+      theBufferInterleave(OSSIM_BIL),
+      theFileStrList(0),
+      theImageData(),
+      theBufferRect(0, 0, 0, 0),
+      theSwapBytesFlag(false),
+      theBufferSizeInPixels(0)
+{
+   if (loadState(kwl, prefix) == false)
+   {
+     theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimGeneralRasterTileSource::ossimGeneralRasterTileSource(const ossimGeneralRasterInfo& id)
+   :
+      ossimImageHandler(),
+      theTile(NULL),
+      theBuffer(NULL),
+      theBufferInterleave(OSSIM_BIL),
+      theFileStrList(0),
+      theImageData(id),
+      theBufferRect(0, 0, 0, 0),
+      theSwapBytesFlag(false),
+      theBufferSizeInPixels(0)
+{
+   open(id);
+   
+}
+
+//*******************************************************************
+// Destructor:
+//*******************************************************************
+ossimGeneralRasterTileSource::~ossimGeneralRasterTileSource()
+{
+   if (theBuffer)
+   {
+      delete [] theBuffer;
+      theBuffer = NULL;
+   }
+
+   // Delete the list of input streams and clear the list.
+//    std::vector<ossimRefPtr<ossimIStream> >::iterator is = theFileStrList.begin();
+//    while (is != theFileStrList.end())
+//    {
+//       (*is)->close();
+//       *is = 0;
+//      (*is)->close();
+//       delete *is;
+//       *is = NULL;
+//       ++is;
+//    }
+
+   theFileStrList.clear();
+}
+
+ossimRefPtr<ossimImageData> ossimGeneralRasterTileSource::getTile(
+   const ossimIrect& tile_rect, ossim_uint32 resLevel)
+{
+   if( !isOpen() || !isSourceEnabled() || !isValidRLevel(resLevel) )
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+   
+   // general rasters can have a subimage as an offset so let's make sure we 
+   // shift it if its in the header
+   ossimIrect theShiftedImageRect = tile_rect - theImageData.subImageOffset();
+
+   if (theOverview)
+   {
+      if (resLevel || theOverview->hasR0())
+      {
+         return theOverview->getTile(theShiftedImageRect, resLevel);
+      }
+   }
+
+   theTile->setImageRectangle(theShiftedImageRect);
+   
+   ossimIrect image_rect = ossimIrect(0, 
+				      0, 
+				      getNumberOfSamples(resLevel) - 1,
+				      getNumberOfLines(resLevel) - 1);
+
+   ossimIrect clip_rect = theShiftedImageRect.clipToRect(image_rect);
+    
+   checkBuffer(tile_rect);
+
+   //***
+   // Check origin to see if it falls with the image.  If not, return a
+   // blank chip.
+   //***
+   if ( theShiftedImageRect.intersects(image_rect) )
+   {
+      if ( ! theShiftedImageRect.completely_within(theBufferRect) )
+      {
+         // A new buffer must be loaded.
+         if ( !theShiftedImageRect.completely_within(clip_rect) )
+         {
+            //***
+            // Start with a blank tile since the whole tile buffer will not be
+            // filled.
+            //***
+            theTile->makeBlank();
+         }
+
+         if(!fillBuffer(clip_rect.ul()))
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Error from fill buffer..."
+               << endl;
+            //***
+            // Error in filling buffer.
+            //***
+            setErrorStatus();
+            return ossimRefPtr<ossimImageData>();
+         }
+      }
+         
+      theTile->loadTile(theBuffer,
+                        theBufferRect,
+                        clip_rect,
+                        theBufferInterleave);
+      theTile->validate();
+   }
+   else
+   {
+      // tile does not intersect the image rectangle.
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   return theTile;
+   
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimGeneralRasterTileSource::fillBuffer(const ossimIpt& origin)
+{
+   static const char MODULE[] = "ossimGeneralRasterTileSource::fillBuffer";
+
+   // Note:  InterleaveType enumerations in "constants.h" file.
+   bool status = false;
+   switch (theImageData.interleaveType())
+   {
+   case OSSIM_BIP:
+      status = fillBIP(origin);
+      break;
+   case OSSIM_BIL:
+      status = fillBIL(origin);
+      break;
+   case OSSIM_BSQ:
+      status = fillBSQ(origin);
+      break;
+   case OSSIM_BSQ_MULTI_FILE:
+      status = fillBsqMultiFile(origin);
+      break;
+   default:
+      ossimNotify(ossimNotifyLevel_WARN) << MODULE << " ERROR:\n"
+                                         << " Unsupported interleave type:  "
+                                         << ILUT.getEntryString(theImageData.interleaveType())
+                                         << endl;
+   }
+
+   if (status && theSwapBytesFlag)
+   {
+      ossimEndian oe;
+      oe.swap(theImageData.getScalarType(),
+              theBuffer,
+              theBufferSizeInPixels);
+   }
+
+   return status;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimGeneralRasterTileSource::fillBIP(const ossimIpt& origin)
+{
+   static const char MODULE[] = "ossimGeneralRasterTileSource::fillBIP";
+   
+   //***
+   // This will fill a buffer the full width of valid samples * getHeight().
+   //***
+   theBufferRect.set_ul(origin);
+
+   theBufferRect.set_lry(min( (origin.y + (ossim_int32)theTile->getHeight() -1),
+                              theImageData.imageRect().lr().y));
+   theBufferRect.set_lrx(min( (origin.x + (ossim_int32)theTile->getWidth() -1),
+                              theImageData.imageRect().lr().x));
+   
+   ossim_int32 currentLine = origin.y;
+   
+   //***
+   // Seek position.  The seek position must take into account:
+   // 1).  Any header offset "theOffsetInBytes".
+   // 2).  Any line offset "theLineOffset."
+   // 3).  Number of bands.
+   //
+   // NOTE:  seekPos is in bytes so theBytesPerPixel must be taken into
+   //        account also.
+   //***
+   std::streampos offset = theImageData.offsetToFirstValidSample() +
+      currentLine * theImageData.bytesPerRawLine() +
+      origin.x * theImageData.bytesPerPixel() *
+      theImageData.numberOfBands();
+
+#if 0
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nDEBUG:"
+         << "\norigin:                 " << origin
+         << "\nSeek position:          " << offset
+         << "\nStarting line number:   " << currentLine << endl;
+   }
+#endif
+   
+   //***
+   // Loop through and process lines. 
+   //***
+   ossim_int32 linesProcessed = 0;
+   
+   size_t buffer_width = theBufferRect.width() * theImageData.numberOfBands() *
+                         theImageData.bytesPerPixel();
+   
+   
+   ossim_uint8* buf = theBuffer;
+
+   ossim_sint32 height = theTile->getHeight();
+   
+   while (currentLine <= theImageData.imageRect().lr().y &&
+          linesProcessed < height)
+   {
+      //***
+      // Seek to line.
+      //***
+      theFileStrList[0]->seekg(offset, ios::beg);
+      if (!(*theFileStrList[0]))
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_WARN) << MODULE << " ERROR:\n"
+                                            << " Seek error!  Returning with error..." << endl;
+         return false;
+      }
+
+      //***
+      // Read the line of image data.   
+      //***
+      theFileStrList[0]->read((char*)buf, buffer_width);
+      if ((long)theFileStrList[0]->gcount() !=  (long)buffer_width) 
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_WARN) << MODULE << "\nERROR:  Reading image line." << endl;
+         return false;
+      }
+
+      ++currentLine;
+      ++linesProcessed;
+      buf += buffer_width;
+      offset += theImageData.bytesPerRawLine();
+   }
+   
+   return true;
+}
+   
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimGeneralRasterTileSource::fillBIL(const ossimIpt& origin)
+{
+   static const char MODULE[] = "ossimGeneralRasterTileSource::fillBIL";
+   
+   //***
+   // This will fill a buffer the full width of valid samples * tileHeight().
+   //***
+   theBufferRect.set_ul(origin);
+   theBufferRect.set_lry(min((origin.y + (ossim_int32)theTile->getHeight() - 1),
+                             theImageData.imageRect().lr().y));
+   theBufferRect.set_lrx(min((origin.x + (ossim_int32)theTile->getWidth() - 1),
+                             theImageData.imageRect().lr().x));
+   
+   ossim_int32 currentLine = origin.y;
+   
+   // Start seek position.
+   std::streampos offset = theImageData.offsetToFirstValidSample() +
+                 currentLine * theImageData.bytesPerRawLine() *
+                   theImageData.numberOfBands() +
+                   origin.x * theImageData.bytesPerPixel();
+
+   //***
+   // Loop through and process lines. 
+   //***
+   ossim_int32 linesProcessed = 0;
+   
+   size_t buffer_width = theBufferRect.width() * theImageData.bytesPerPixel();
+   
+   ossim_uint8* buf = theBuffer;
+
+#if 0
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nDEBUG:"
+         << "\norigin:                 " << origin
+         << "\nSeek position:          " << offset
+         << "\nStarting line number:   " << currentLine
+         << "\nbuffer_width:           " << buffer_width << endl;
+   }
+#endif
+
+   ossim_int32 height    = theTile->getHeight();
+   ossim_int32 num_bands = theImageData.numberOfBands();
+   
+   while (currentLine <= theImageData.imageRect().lr().y &&
+          linesProcessed < height)
+   {
+      for (ossim_int32 band = 0; band < num_bands; ++band)
+      {
+         //***
+         // Seek to line.
+         //***
+         theFileStrList[0]->seekg(offset, ios::beg);
+         if (!theFileStrList[0])
+         {
+            theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+             ossimNotify(ossimNotifyLevel_WARN) << MODULE << " ERROR:\n"
+                                                << " Seek error!  Returning with error..." << endl;
+            return false;
+         }
+         
+         //***
+         // Read the line of image data.   
+         //***
+         theFileStrList[0]->read((char*)buf, buffer_width);
+         if ((long)theFileStrList[0]->gcount() !=  (long)buffer_width) 
+         {
+            theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+            ossimNotify(ossimNotifyLevel_WARN) << MODULE << "\nERROR:  Reading image line."
+                                               << "\ncurrentLine:  " << currentLine << endl;
+            return false;
+         }
+
+         buf += buffer_width;
+         offset += theImageData.bytesPerRawLine();
+
+      } // End of band loop.
+      
+      ++linesProcessed;
+      ++currentLine;
+   }
+   
+   return true;
+}
+   
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimGeneralRasterTileSource::fillBSQ(const ossimIpt& origin)
+{
+   static const char MODULE[] = "ossimGeneralRasterTileSource::fillBSQ";
+
+   //***
+   // This will fill a buffer the full width of valid samples * tileHeight().
+   //***
+   theBufferRect.set_ul(origin);
+   
+   theBufferRect.set_lry(min((origin.y + (ossim_int32)theTile->getHeight() -1),
+                             theImageData.imageRect().lr().y));
+   theBufferRect.set_lrx(min((origin.x + (ossim_int32)theTile->getWidth() - 1),
+                             theImageData.imageRect().lr().x));
+   
+   //***
+   // Start seek position.
+   //***
+   std::streampos startSeekPosition
+      = theImageData.offsetToFirstValidSample() +
+      origin.y * theImageData.bytesPerRawLine() +
+      origin.x * theImageData.bytesPerPixel();
+
+   //***
+   // Loop through and process lines. 
+   //***
+   size_t buffer_width = theBufferRect.width() * theImageData.bytesPerPixel();
+   
+   ossim_uint8* buf = (ossim_uint8*)theBuffer;
+
+#if 0
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nDEBUG:"
+         << "\norigin:                 " << origin
+         << "\nSeek position:          " << startSeekPosition
+         << "\nStarting line number:   " << origin.y
+         << "\nbuffer_width:           " << buffer_width
+         << "\nbytesPerRawLine():      "
+         << theImageData.bytesPerRawLine()
+         << "\ntheImageData.offsetToFirstValidSample():  "
+         << theImageData.offsetToFirstValidSample() << endl;
+   }
+#endif
+
+   std::streampos bandOffset
+      = theImageData.bytesPerRawLine() * theImageData.rawLines();
+
+   ossim_int32 num_bands = theImageData.numberOfBands();
+   ossim_int32 height    = theTile->getHeight();
+   
+   for (ossim_int32 band = 0; band < num_bands; ++band)
+   {
+      ossim_int32 currentLine    = origin.y;
+      ossim_int32 linesProcessed = 0;
+
+      std::streampos offset = startSeekPosition + (band * bandOffset);
+      
+      while (currentLine <= theImageData.imageRect().lr().y &&
+             linesProcessed < height)
+      {
+         //***
+         // Seek to line.
+         //***
+         theFileStrList[0]->seekg(offset, ios::beg);
+         if (!theFileStrList[0])
+         {
+            theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+            ossimNotify(ossimNotifyLevel_WARN) << MODULE << " ERROR:\n"
+                                               << " Seek error!  Returning with error..." << endl;
+            return false;
+         }
+         
+         //***
+         // Read the line of image data.   
+         //***
+         theFileStrList[0]->read((char*)buf, buffer_width);
+         if ((long)theFileStrList[0]->gcount() !=  (long)buffer_width) 
+         {
+            theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+            ossimNotify(ossimNotifyLevel_WARN) << MODULE << "\nERROR:  Reading image line."
+                                               << "\ncurrentLine:  " << currentLine << endl;
+            return false;
+         }
+
+         // Increment everybody accordingly.
+         buf += buffer_width;
+         offset += theImageData.bytesPerRawLine();
+         ++linesProcessed;
+         ++currentLine;
+
+      } // End of line loop.
+
+   } // End of band loop.
+   
+   return true;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimGeneralRasterTileSource::fillBsqMultiFile(const ossimIpt& origin)
+{
+   static const char MODULE[]
+      = "ossimGeneralRasterTileSource::fillBsqMultiFile";
+
+   if (traceDebug()) CLOG << " Entered..." << endl;
+   
+   
+   //***
+   // This will fill a buffer the full width of valid samples * tileHeight().
+   //***
+   theBufferRect.set_ul(origin);
+   
+   theBufferRect.set_lry(min((origin.y + (ossim_int32)theTile->getHeight() -1),
+                             theImageData.imageRect().lr().y));
+   theBufferRect.set_lrx(min((origin.x + (ossim_int32)theTile->getWidth() - 1),
+                             theImageData.imageRect().lr().x));
+   
+   //***
+   // Start seek position.
+   //***
+   std::streampos startSeekPosition
+      = theImageData.offsetToFirstValidSample() +
+      origin.y * theImageData.bytesPerRawLine() +
+      origin.x * theImageData.bytesPerPixel();
+
+   //***
+   // Loop through and process lines. 
+   //***
+   size_t buffer_width = theBufferRect.width() * theImageData.bytesPerPixel();
+   
+   ossim_uint8* buf = (ossim_uint8*)theBuffer;
+
+#if 0
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nDEBUG:"
+         << "\norigin:                 " << origin
+         << "\nSeek position:          " << startSeekPosition
+         << "\nStarting line number:   " << origin.y
+         << "\nbuffer_width:           " << buffer_width
+         << "\nbuffer_rect:            " << theBufferRect
+         << "\nbytesPerRawLine():      "
+         << theImageData.bytesPerRawLine()
+         << "\ntheImageData.offsetToFirstValidSample():  "
+         << theImageData.offsetToFirstValidSample() << endl;
+   }
+#endif
+
+   ossim_int32 num_bands = theImageData.numberOfBands();
+   ossim_int32 height    = theTile->getHeight();
+   
+   for (ossim_int32 band = 0; band < num_bands; ++band)
+   {
+      ossim_int32 currentLine    = origin.y;
+      ossim_int32 linesProcessed = 0;
+
+      ossim_int64 offset = startSeekPosition;
+      
+      while (currentLine <= theImageData.imageRect().lr().y &&
+             linesProcessed < height)
+      {
+         //***
+         // Seek to line.
+         //***
+         theFileStrList[band]->seekg(offset, ios::beg);
+         if (!theFileStrList[band])
+         {
+            theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+            ossimNotify(ossimNotifyLevel_WARN) << MODULE << " ERROR:\n"
+                                                << " Seek error!  Returning with error..." << endl;
+            return false;
+         }
+         
+         //***
+         // Read the line of image data.   
+         //***
+         theFileStrList[band]->read((char*)buf, buffer_width);
+         if ((long)theFileStrList[band]->gcount() !=  (long)buffer_width) 
+         {
+            theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+            ossimNotify(ossimNotifyLevel_WARN) << MODULE << "\nERROR:  Reading image line."
+                                               << "\ncurrentLine:  " << currentLine << endl;
+            return false;
+         }
+
+         // Increment everybody accordingly.
+         buf += buffer_width;
+         offset += theImageData.bytesPerRawLine();
+         ++linesProcessed;
+         ++currentLine;
+
+      } // End of line loop.
+
+   } // End of band loop.
+   
+   return true;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+// ossimIrect
+// ossimGeneralRasterTileSource::getImageRectangle(ossim_uint32 reduced_res_level) const
+// {
+//   if(reduced_res_level < getNumberOfDecimationLevels())
+//     {
+//       ossimDpt decimation;
+//       getDecimationFactor(reduced_res_level, decimation);
+//       ossimIpt offset = theImageData.subImageOffset();
+//       offset.x = irint(offset.x*decimation.x);
+//       offset.y = irint(offset.y*decimation.y);
+      
+//       return ossimIrect(offset.x,                         // upper left x
+// 			offset.y,                         // upper left y
+// 			offset.x + getNumberOfSamples(reduced_res_level) - 1,  // lower right x
+// 			offset.y + getNumberOfLines(reduced_res_level)   - 1); // lower right y
+//     }
+//   ossimIrect result;
+//   result.makeNan();
+//   return result;
+// }
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimGeneralRasterTileSource::saveState(ossimKeywordlist& kwl,
+                                        const char* prefix) const
+{
+   theImageData.saveState(kwl, prefix);
+   
+   return ossimImageHandler::saveState(kwl, prefix);
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimGeneralRasterTileSource::loadState(const ossimKeywordlist& kwl,
+                                             const char* prefix)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimGeneralRasterTileSource::loadState DEBUG: entered ... "
+         << std::endl;
+   }
+   
+   if(isOpen())
+   {
+     close();
+   }
+
+   const char* filename = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "Trying to open filename " << filename << std::endl;
+   }
+   if(filename)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "leaving with open... " << filename << std::endl;
+      }
+      if (ossimImageHandler::open(ossimFilename(filename)))
+      {
+         // Must call to pick up id for connections.
+         return ossimImageSource::loadState(kwl, prefix);
+      }
+   }
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimGeneralRasterTileSource::loadState DEBUG: "
+         << "leaving without open... " << std::endl;
+   }
+   return false;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossimScalarType ossimGeneralRasterTileSource::getOutputScalarType() const
+{
+   return ( theTile.valid() ? theTile->getScalarType()
+            : OSSIM_SCALAR_UNKNOWN );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimGeneralRasterTileSource::getTileWidth() const
+{
+   return ( theTile.valid() ? theTile->getWidth() : 0 );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimGeneralRasterTileSource::getTileHeight() const
+{
+   return ( theTile.valid() ? theTile->getHeight() : 0 );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool
+ossimGeneralRasterTileSource::isValidRLevel(ossim_uint32 reduced_res_level) const
+{
+   static const char MODULE[] = "ossimGeneralRasterTileSource::isValidRLevel";
+   
+   if (reduced_res_level == 0)
+   {
+      return true;
+   }
+   else if (theOverview)
+   {
+      return theOverview->isValidRLevel(reduced_res_level);
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE
+         << " Invalid reduced_res_level:  " << reduced_res_level
+         << "\nHighest available:  " << (getNumberOfDecimationLevels() - 1)
+         << endl;
+      return false;
+   }
+}
+
+
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32
+ossimGeneralRasterTileSource::getNumberOfLines(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theImageData.validLines();
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfLines(reduced_res_level);
+   }
+
+   return 0;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimGeneralRasterTileSource::
+getNumberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theImageData.validSamples();
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfSamples(reduced_res_level);
+   }
+
+   return 0;
+}
+
+double ossimGeneralRasterTileSource::getNullPixelValue(ossim_uint32 band) const
+{
+   return theImageData.getNullPixelValue(band);
+}
+
+double ossimGeneralRasterTileSource::getMinPixelValue(ossim_uint32 band)const
+{
+   return theImageData.getMinPixelValue(band);
+}
+
+double ossimGeneralRasterTileSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   return theImageData.getMaxPixelValue(band);
+}
+
+bool ossimGeneralRasterTileSource::open()
+{
+  if(isOpen())
+  {
+     close();
+  }
+  static const char MODULE[] = "ossimGeneralRasterTileSource::open";
+  
+  if (traceDebug()) CLOG << " Entered..." << endl;
+  
+  if(isOpen())
+  {
+     close();
+  }
+  
+  //
+  // A general raster image requires a keyword list to get essential image
+  // information or meta data as its sometimes called.  The meta data file
+  // can have three types of extensions: ".omd", ".hdr" and ".kwl"
+  // Look for them in that order.
+  // Note that the ".omd" extension is for "Ossim Meta Data" and was made
+  // up to avoid conflicting with other software packages ".hdr" files.
+  //
+  
+  ossimFilename hdr = theImageFile;
+  
+  hdr.setExtension("omd");   
+  
+  // See if it's readable.
+  if ( ! hdr.isReadable() )
+  {
+     hdr.setExtension("hdr");   
+     
+     // See if this one's readable.
+     if ( ! hdr.isReadable() )
+     {
+        // Ok try .kwl extension.
+        hdr.setExtension("kwl");   
+        if ( ! hdr.isReadable() )
+        {
+           // No header file so get out.
+           return false;
+        }
+     }
+  }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << "\nHeader file:  " << hdr.c_str() << endl;
+   }
+   
+   // Give the header file to the keyword list object.
+   ossimKeywordlist kwl(hdr);
+
+   // Check for errors.
+   if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      if (traceDebug())
+      {
+          ossimNotify(ossimNotifyLevel_WARN) << MODULE << " Keywordlist open error detected." << endl;
+      }
+      
+      return false;
+   }
+   
+   //
+   // If the file name passed to us was the header it's assumed the image_file
+   // keyword is present else assume it's the image file and add if to the
+   // keyword list.  This will overwrite the "image_file" in the header if
+   // it's in there.
+   //
+   if (theImageFile != hdr)
+   {
+      kwl.add(ossimKeywordNames::FILENAME_KW,
+              theImageFile.c_str(),
+              true);
+   }
+
+   ossimGeneralRasterInfo generalRasterInfo;
+   
+   bool status = generalRasterInfo.loadState(kwl);
+   theMetaData.loadState(kwl);
+   // Let the load state do the rest...
+   //   bool status = loadState(kwl);
+   if(status)
+   {
+      status = open(generalRasterInfo);
+   }
+   
+   if (traceDebug()) CLOG << " Exited..." << endl;
+   
+   return status;
+}
+
+bool ossimGeneralRasterTileSource::open(const ossimGeneralRasterInfo& info)
+{
+   if(isOpen())
+   {
+      close();
+   }
+   
+   theImageData = info;
+
+   if(initializeHandler())
+     {
+       completeOpen();
+     }
+   else
+     {
+       return false;
+     }
+
+   return true;
+}
+
+bool ossimGeneralRasterTileSource::initializeHandler()
+{
+   //***
+   // This private method assumes that "theImageData" object has been
+   // initialized.  Note that "close() should have already been called if
+   // there was an open file prior to this.
+   //***
+   if(isOpen())
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimGeneralRasterTileSource::initialize() Coding Error!"
+                                         << "\nFile was not closed prior to initialize call!"
+                                         << "\nReturning false..."
+                                         << endl;
+      return false;
+   }
+   
+   theSubImageOffset = theImageData.subImageOffset();
+
+   ossim_uint32 number_of_bands = theImageData.numberOfBands();
+
+   std::streampos expectedSizeInBytes;
+
+   if (theImageData.interleaveType() != OSSIM_BSQ_MULTI_FILE)
+   {
+      expectedSizeInBytes = theImageData.validSamples()  *
+                            theImageData.validLines()    *
+                            number_of_bands *
+                            theImageData.bytesPerPixel();
+   }
+   else
+   {
+      expectedSizeInBytes = theImageData.validSamples()  *
+                            theImageData.validLines()    *
+                            theImageData.bytesPerPixel();
+   }
+   
+   vector<ossimFilename> aList = theImageData.getImageFileList();
+
+   for (ossim_uint32 i=0; i<aList.size(); ++i)
+   {
+      // Check the file size.
+      
+
+      ossimRefPtr<ossimIStream> is = ossimStreamFactoryRegistry::instance()->createNewInputStream(aList[i], std::ios::in|std::ios::binary);//new ifstream(aList[i].c_str(), ios::in | ios::binary);
+      if ((!is->isCompressed()) &&
+          (aList[i].fileSize() < expectedSizeInBytes))
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_WARN) << "ossimGeneralRasterTileSource::open" << " ERROR:"
+                                            << "\nFile size not big enough!\n"
+                                            << "\nExpected:  " << expectedSizeInBytes
+                                            << "\nGot:       " << aList[i].fileSize()
+                                            << "\nReturning with error..." << endl;
+         return false;
+      }
+      if(is.valid())
+      {
+         // Check the file stream.
+         if ( is->fail() )
+         {
+            theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+            ossimNotify(ossimNotifyLevel_WARN) << "ossimGeneralRasterTileSource::open" << " ERROR:\n"
+                                               << "Cannot open:  " << aList[i].c_str() << endl;
+            is = 0;
+            return false;
+         }
+      }
+   
+      theFileStrList.push_back(is); // Add it to the list...
+   }
+
+   if(aList.size()==1)
+   {
+      theImageFile  = aList[0];
+   }
+   
+   //***
+   // Determine the pixel type and make the appropriate tiles.
+   //***
+   ossimScalarType scalar = theImageData.getScalarType();
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimGeneralRasterTileSource::open DEBUG:"
+         << "\nScalar type:  "
+         << ossimScalarTypeLut::instance()->
+         getEntryString(theImageData.getScalarType())
+         << endl;
+   }
+
+   // Make the tiles for the getTile return.
+                            
+   ossimImageDataFactory* idf = ossimImageDataFactory::instance();
+
+   theTile = idf->create(this,
+                         scalar,
+                         number_of_bands);
+   
+   theTile->initialize();
+
+   // These values can be overridden by loadState...
+   for(ossim_uint32 band = 0; band < number_of_bands; ++ band)
+     {
+       theTile->setNullPix(theImageData.getNullPixelValue(band), band);
+       theTile->setMinPix(theImageData.getMinPixelValue(band), band);
+       theTile->setMaxPix(theImageData.getMaxPixelValue(band), band);
+     }
+   theTile->makeBlank();
+   // Store the size of the buffer in pixels for swapping bytes.
+   theBufferSizeInPixels = theTile->getWidth() * theTile->getHeight() *
+                           number_of_bands;
+   
+   // Get the buffer size.  This is bytes, not pixels.
+   ossim_int32 buffer_size = theBufferSizeInPixels * theImageData.bytesPerPixel();
+
+   theBuffer = new ossim_uint8[buffer_size];
+
+   // Set the buffer interleave type.
+   theBufferInterleave = theImageData.interleaveType();
+   if (theBufferInterleave == OSSIM_BSQ_MULTI_FILE)
+   {
+      theBufferInterleave = OSSIM_BSQ;
+   }
+
+   // Zero out the buffer rect.
+   theBufferRect = ossimIrect(0, 0, 0, 0);
+   
+//    // Check for an overview if not already initialized.
+//    if (!theOverview)
+//    {
+//       openOverview();
+//    }
+
+//    // Check for valid image vertices file if not already initialized.
+//    if (theValidImageVertices.size() == 0)
+//    {
+//       openValidVertices();
+//    }
+
+   //***
+   // Get the byte order of the image data and host machine.  If different,
+   // set the swap bytes flag...
+   //***
+   if (theImageData.getImageDataByteOrder() != ossimGetByteOrder())
+   {
+      theSwapBytesFlag = true;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimGeneralRasterTileSource::open" << " DEBUG:"
+         << "\nByte swapping is "
+         << (theSwapBytesFlag?"enabled.":"not enabled.")
+         << "\ntheBufferSizeInPixels:  " << theBufferSizeInPixels
+         << "\nbuffer size:  " << buffer_size
+         << "\nImageData:\n";
+      theImageData.print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+   
+   return true;
+}
+
+void ossimGeneralRasterTileSource::checkBuffer(const ossimIrect& rect)
+{
+  if((theBufferRect.width()*theBufferRect.height()) !=
+     (rect.width()*rect.height()))
+    {
+      if(theBuffer)
+	{
+	  delete [] theBuffer;
+	  theBuffer = NULL;
+	}
+    }
+
+  if(!theBuffer)
+    {
+      ossim_uint32 number_of_bands = theImageData.numberOfBands();
+      theBufferSizeInPixels = rect.width()*rect.height()*number_of_bands;
+      
+      // Get the buffer size.  This is bytes, not pixels.
+      ossim_int32 buffer_size = theBufferSizeInPixels * theImageData.bytesPerPixel();
+      
+      theBuffer = new ossim_uint8[buffer_size];
+      theBufferRect = ossimIrect(0,0,0,0);
+    }
+}
+
+
+bool ossimGeneralRasterTileSource::isOpen() const
+{
+   if (theFileStrList.size() > 0)
+   {
+      if(theFileStrList[0].valid())
+      {
+         return !(theFileStrList[0]->fail());
+      }
+//      return  const_cast<ifstream*>(theFileStrList[0])->is_open();
+   }
+
+   return false;
+}
+
+void ossimGeneralRasterTileSource::close()
+{
+   ossimImageHandler::close();  // base class
+
+   theTile = NULL;
+   if (theBuffer)
+   {
+      delete [] theBuffer;
+      theBuffer = NULL;
+   }
+
+   // Delete the list of input streams and clear the list.
+//    vector<istream*>::iterator is = theFileStrList.begin();
+//    while (is != theFileStrList.end())
+//    {
+//       delete *is;
+//       *is = NULL;
+//       ++is;
+//    }
+
+   theFileStrList.clear();
+}
+
+ossim_uint32 ossimGeneralRasterTileSource::getImageTileWidth() const
+{
+   return 0;
+}
+
+ossim_uint32 ossimGeneralRasterTileSource::getImageTileHeight() const
+{
+   return 0;
+}
+
+ossimString ossimGeneralRasterTileSource::getShortName()const
+{
+   return ossimString("ras");
+}
+
+ossimString ossimGeneralRasterTileSource::getLongName()const
+{
+   return ossimString("general raster reader");
+}
+
+ossimString ossimGeneralRasterTileSource::className()const
+{
+   return ossimString("ossimGeneralRasterTileSource");
+}
+
+ossim_uint32 ossimGeneralRasterTileSource::getNumberOfInputBands() const
+{
+   return theImageData.numberOfBands();
+}
+
+ossim_uint32 ossimGeneralRasterTileSource::getNumberOfOutputBands() const
+{
+   return getNumberOfInputBands();
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterTileSource.h
new file mode 100644
index 0000000000..366c08e89a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterTileSource.h
@@ -0,0 +1,168 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimGeneralRasterTileSource.
+// ossimGeneralRasterTileSource is derived from ImageHandler which is
+// derived from ossimTileSource.
+//*******************************************************************
+//  $Id: ossimGeneralRasterTileSource.h,v 1.38 2005/11/10 14:15:33 gpotts Exp $
+
+#ifndef ossimGeneralRasterTileSource_HEADER
+#define ossimGeneralRasterTileSource_HEADER
+
+#include <fstream>
+#include <base/common/ossimIoStream.h>
+  //using namespace std;
+
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/formats/general_raster/ossimGeneralRasterInfo.h>
+
+class  ossimImageData;
+
+class OSSIM_DLL ossimGeneralRasterTileSource : public ossimImageHandler
+{
+public:
+
+   ossimGeneralRasterTileSource();
+
+   explicit ossimGeneralRasterTileSource(const ossimKeywordlist& kwl,
+					 const char* prefix=0);
+   
+   explicit ossimGeneralRasterTileSource(const ossimGeneralRasterInfo& id);
+   
+   virtual ~ossimGeneralRasterTileSource();
+
+   virtual ossimString getShortName()const;
+   virtual ossimString getLongName()const;
+   virtual ossimString className()const;
+   
+   /**
+    *  Returns a pointer to a tile given an origin representing the upper
+    *  left corner of the tile to grab from the image.
+    *  Satisfies pure virtual from TileSource class.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+   
+    /**
+     *  Returns the number of bands in the image.
+     *  Satisfies pure virtual from ImageHandler class.
+     */
+   virtual ossim_uint32 getNumberOfInputBands() const;
+   
+   /**
+    * Returns the number of bands in a tile returned from this TileSource.
+    * Note: we are supporting sources that can have multiple data objects.
+    * If you want to know the scalar type of an object you can pass in the 
+    */
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+   
+   /**
+    *  Returns the number of lines in the image.
+    *  Satisfies pure virtual from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    *  Returns the number of samples in the image.  
+    *  Satisfies pure virtual from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
+
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /**
+    * Returns the output pixel type of the tile source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32    getTileWidth() const;
+   
+   /**
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32    getTileHeight() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    * Note:  This handler will always return 0 for this method.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    * Note:  This handler will always return 0 for this method.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;   
+   
+   bool isValidRLevel(ossim_uint32 reduced_res_level) const;
+  
+   virtual void close();
+   virtual bool isOpen() const;
+   virtual bool open();
+   virtual bool open(const ossimGeneralRasterInfo& info);
+
+   /**
+    * Override base getXXXXPixValue methods since the null/min/max can be set
+    * to something different.  Currently returns the same value for all bands.
+    */
+    virtual double getNullPixelValue(ossim_uint32 band=0)const;
+    virtual double getMinPixelValue(ossim_uint32 band=0)const;
+    virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+protected:
+   /**
+    *  Methods return true on succes false on error.
+    */
+   virtual bool fillBuffer(const ossimIpt& origin);
+   virtual bool fillBIP(const ossimIpt& origin);
+   virtual bool fillBIL(const ossimIpt& origin);
+   virtual bool fillBSQ(const ossimIpt& origin);
+   virtual bool fillBsqMultiFile(const ossimIpt& origin);
+
+   virtual bool initializeHandler();
+   virtual void checkBuffer(const ossimIrect& rect);
+   ossimRefPtr<ossimImageData>  theTile;
+   ossim_uint8*                 theBuffer;
+   ossimInterleaveType          theBufferInterleave;
+   std::vector<ossimRefPtr<ossimIStream> > theFileStrList;
+//   vector<istream*>            theFileStrList;   
+   ossimGeneralRasterInfo       theImageData;
+   ossimIrect                   theBufferRect;
+   bool                         theSwapBytesFlag;
+   ossim_uint32                 theBufferSizeInPixels;
+
+TYPE_DATA
+};
+
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterWriter.cpp
new file mode 100644
index 0000000000..744f558942
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterWriter.cpp
@@ -0,0 +1,829 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+//
+//*******************************************************************
+//  $Id: ossimGeneralRasterWriter.cpp,v 1.57 2006/01/06 16:46:46 dburken Exp $
+
+#include <fstream>
+
+#include <imaging/formats/general_raster/ossimGeneralRasterWriter.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/metadata/ossimEnviHeaderFileWriter.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/misc/ossimEndian.h>
+
+
+static ossimTrace traceDebug("ossimGeneralRasterWriter:debug");
+
+RTTI_DEF1(ossimGeneralRasterWriter,
+          "ossimGeneralRasterWriter",
+          ossimImageFileWriter)
+
+static const char DEFAULT_FILE_NAME[] = "output.ras";
+
+ossimGeneralRasterWriter::ossimGeneralRasterWriter()
+   :
+      ossimImageFileWriter(),
+      theRlevel(0)
+{
+  setOutputImageType(OSSIM_GENERAL_RASTER_BSQ);
+
+  // Since there is no internal geometry set the flag to write out one.
+  setWriteExternalGeometryFlag(true);
+  theOutputByteOrder = ossimEndian().getSystemEndianType();
+}
+
+ossimGeneralRasterWriter::ossimGeneralRasterWriter(
+   ossimImageSource* inputSource, const ossimFilename& file)
+   :
+      ossimImageFileWriter(file,
+                         inputSource,
+                         NULL),
+      theRlevel(0)
+{
+  setOutputImageType(OSSIM_GENERAL_RASTER_BSQ);
+
+  // Since there is no internal geometry set the flag to write out one.
+  setWriteExternalGeometryFlag(true);
+  theOutputByteOrder = ossimEndian().getSystemEndianType();
+}
+
+ossimGeneralRasterWriter::~ossimGeneralRasterWriter()
+{
+   if(isOpen())
+   {
+     close();
+   }
+}
+
+bool ossimGeneralRasterWriter::isOpen()const
+{
+   // fstream::is_open not const; hence, the messy code...
+   return const_cast<std::ofstream*>(&theFileStream)->is_open();
+}
+
+bool ossimGeneralRasterWriter::open()
+{
+   if(isOpen())
+   {
+      close();
+   }
+
+   theFileStream.open(theFilename.c_str(), ios::out | ios::binary);
+   
+   if(theFileStream)
+   {
+      return true;
+   }
+
+   return false;
+}
+
+void ossimGeneralRasterWriter::close()
+{
+   if (theFileStream.is_open())
+   {
+      theFileStream.close();
+   }
+   theFileStream.clear();
+}
+
+bool ossimGeneralRasterWriter::writeFile()
+{
+   static const char MODULE[] = "ossimGeneralRasterWriter::writeFile";
+   
+   if( getErrorStatus() != ossimErrorCodes::OSSIM_OK )
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << MODULE << " ERROR:"
+         << "\nError status previously set!" << std::endl;
+      return false;
+   }
+   
+   if(!theInputConnection->isMaster())
+   {
+      theInputConnection->slaveProcessTiles();
+      return true;
+   }
+   
+   open();
+   
+   if(!theFileStream)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << MODULE << " ERROR:"
+         << "\nOutput file not open:  " << theFilename.c_str()
+         << "\nReturning from method." << std::endl;
+      setErrorStatus();
+      return false;
+   }
+
+   bool result = true;
+   // Write the file with the image data.
+   if ( (theOutputImageType == "general_raster_bip") ||
+        (theOutputImageType == "general_raster_bip_envi") )
+   {
+      result = writeToBip();
+   }
+   else if ( (theOutputImageType == "general_raster_bil") ||
+             (theOutputImageType == "general_raster_bil_envi") )
+   {
+      result = writeToBil();
+   }
+   else if ( (theOutputImageType == "general_raster_bsq") ||
+             (theOutputImageType == "general_raster_bsq_envi") )
+   {
+      result = writeToBsq();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << MODULE << " ERROR:"
+         << "\nUnsupported output type:  " << theOutputImageType << std::endl;
+      result = false;
+   }
+   
+   if (result)
+   {
+      // Flush the stream to disk...
+      theFileStream.flush();
+
+      // Do this only on the master process. Note left to right precedence!
+      if (getSequencer() && getSequencer()->isMaster())
+      {
+         //---
+         // Write the header out.  We do this last since we must
+         // compute min max pixel while we are writting the image.
+         // since the header is an external text file this is Ok
+         // to do.
+         //---
+         writeHeader();
+
+         if (theOutputImageType.contains("envi"))
+         {
+            writeEnviHeader();
+         }
+      }
+   }
+   
+   if (traceDebug()) CLOG << " Exited..." << std::endl;
+
+   close();
+   
+   return result;
+}
+
+
+bool ossimGeneralRasterWriter::writeToBip()
+{
+   ossimEndian endian;
+   static const char* const MODULE = "ossimGeneralRasterWriter::writeToBip";
+   
+   if (traceDebug()) CLOG << " Entered." << std::endl;
+   
+   
+   //---
+   // Get an arbitrary tile just to get the size in bytes!
+   // This should be changed later... An ossimImageSourceInterface should know
+   // this.
+   //---
+   ossimRefPtr<ossimImageData> id;
+   
+   // Start the sequence at the first tile.
+   theInputConnection->setToStartOfSequence();
+   
+   ossim_uint32 bands     = theInputConnection->getNumberOfOutputBands();
+   ossim_uint32 tilesWide =  theInputConnection->getNumberOfTilesHorizontal();
+   ossim_uint32 tilesHigh     = theInputConnection->getNumberOfTilesVertical();
+   ossim_uint32 tileHeight    = theInputConnection->getTileHeight();
+   ossim_uint32 numberOfTiles = theInputConnection->getNumberOfTiles();
+   ossim_uint32 width         = theAreaOfInterest.width();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nossimGeneralRasterWriter::writeToBip DEBUG:"
+         << "\nbands:          " << bands
+         << "\ntilesWide:      " << tilesWide
+         << "\ntilesHigh:      " << tilesHigh
+         << "\ntileHeight:     " << tileHeight
+         << "\nnumberOfTiles:  " << numberOfTiles
+         << "\nwidth:          " << width
+         << std::endl;
+   }
+   
+   //---
+   // Buffer to hold one line x tileHeight
+   //---
+   ossim_uint32 bufferSizeInBytes = 0;
+   ossim_uint32 bytesInLine       = 0;
+   unsigned char* buffer = NULL;
+   
+   theMinPerBand.clear();
+   theMaxPerBand.clear();
+   int tileNumber = 0;
+   bool wroteSomethingOut = false;
+   ossimScalarType scalarType = theInputConnection->getOutputScalarType();
+   for(ossim_uint32 i = 0; ((i < tilesHigh)&&(!needsAborting())); ++i)
+   {
+      // Clear the buffer.
+      if(buffer)
+      {
+	 memset(buffer, 0, bufferSizeInBytes);
+      }
+      
+      ossimIrect bufferRect(theAreaOfInterest.ul().x,
+			    theAreaOfInterest.ul().y + i*tileHeight,
+			    theAreaOfInterest.ul().x + (width - 1),
+			    theAreaOfInterest.ul().y + i*tileHeight + (tileHeight - 1));
+      // Tile loop in the sample (width) direction.
+      for(ossim_uint32 j = 0; ((j < tilesWide)&&(!needsAborting())); ++j)
+      {
+         // Get the tile and copy it to the buffer.
+         id = theInputConnection->getNextTile();
+	 if(id.valid())
+         {
+            id->computeMinMaxPix(theMinPerBand, theMaxPerBand);
+            if(!buffer)
+            {
+               bytesInLine     = id->getScalarSizeInBytes() * width * bands;
+               
+               //---
+               // Buffer to hold one line x tileHeight
+               //---
+               bufferSizeInBytes = bytesInLine * tileHeight;
+               buffer = new unsigned char[bufferSizeInBytes];
+               memset(buffer, 0, bufferSizeInBytes);
+            }
+            id->unloadTile(buffer,
+                           bufferRect,
+                           OSSIM_BIP);
+         }
+         ++tileNumber;
+      }
+      
+      // Get the number of lines to write from the buffer.
+      ossim_uint32 linesToWrite =
+         min(tileHeight,
+             static_cast<ossim_uint32>(theAreaOfInterest.lr().y -
+                                       bufferRect.ul().y + 1));
+      // Write the buffer out to disk.  
+      ossim_uint8* buf = buffer;
+      if(buf)
+      {
+         for (ossim_uint32 ii=0; ((ii<linesToWrite)&&(!needsAborting())); ++ii)
+         {
+            std::streamsize lineBytes = bytesInLine;
+            wroteSomethingOut = true;
+
+            if(endian.getSystemEndianType() != theOutputByteOrder)
+            {
+               endian.swap(scalarType,
+                           buf,
+                           lineBytes/ossimGetScalarSizeInBytes(scalarType));
+            }
+            theFileStream.write((char*)buf, lineBytes);
+            if (!theFileStream)
+            {
+               ossimNotify(ossimNotifyLevel_FATAL)
+                  << MODULE << " ERROR:"
+                  << "Error returned writing line!" << std::endl;
+               setErrorStatus();
+               if(buffer)
+               {
+                  // Free the memory.
+                  delete [] buffer;
+               }
+               return false;
+            }
+	    
+            buf += bytesInLine;
+	    
+         } // End of loop to write lines from buffer to tiff file.
+      }
+      double tile = tileNumber;
+      double numTiles = numberOfTiles;
+      setPercentComplete(tile / numTiles * 100);
+      if(needsAborting())
+      {
+         setPercentComplete(100.0);
+      }
+      
+   } // End of loop in the line (height) direction.
+   if(buffer)
+   {
+      // Free the memory.
+      delete [] buffer;
+   }
+   
+   if (traceDebug()) CLOG << " Exited." << std::endl;
+   
+   return wroteSomethingOut;
+}
+
+bool ossimGeneralRasterWriter::writeToBil()
+{
+   ossimEndian endian;
+   static const char* const MODULE = "ossimGeneralRasterWriter::writeToBil";
+
+   if (traceDebug()) CLOG << " Entered." << std::endl;
+
+   //***
+   // Get an arbitrary tile just to get the size in bytes!
+   // This should be changed later... An ossimImageSourceInterface should know
+   // this.
+   //***
+   ossimRefPtr<ossimImageData> id;
+   theInputConnection->setToStartOfSequence();
+
+   ossim_uint32 bands     = theInputConnection->getNumberOfOutputBands();
+   ossim_uint32 tilesWide = theInputConnection->getNumberOfTilesHorizontal();
+   ossim_uint32 tilesHigh = theInputConnection->getNumberOfTilesVertical();
+   ossim_uint32 tileHeight        = theInputConnection->getTileHeight();
+   ossim_uint32 numberOfTiles     = theInputConnection->getNumberOfTiles();
+   ossim_uint32 width             = theAreaOfInterest.width();
+   ossim_uint32 bufferSizeInBytes = 0;
+   ossim_uint32 bytesInLine       = 0;
+   unsigned char* buffer    = NULL;
+
+   // Start with a clean min/max.
+   theMinPerBand.clear();
+   theMaxPerBand.clear();
+
+   int tileNumber = 0;
+   bool wroteSomethingOut = false;
+   ossimScalarType scalarType = theInputConnection->getOutputScalarType();
+   for(ossim_uint32 i = 0; ((i < tilesHigh)&&(!needsAborting())); ++i)
+   {
+      // Clear the buffer.
+      // Clear the buffer.
+      if(buffer)
+      {
+         memset(buffer, 0, bufferSizeInBytes);
+      }
+      
+      ossimIrect bufferRect(theAreaOfInterest.ul().x,
+                            theAreaOfInterest.ul().y + i*tileHeight,
+                            theAreaOfInterest.ul().x + (width - 1),
+                            theAreaOfInterest.ul().y + i *
+                            tileHeight + (tileHeight - 1));
+      
+      // Tile loop in the sample (width) direction.
+      for(ossim_uint32 j = 0; ((j < tilesWide)&&(!needsAborting())); ++j)
+      {
+         // Get the tile and copy it to the buffer.
+         id = theInputConnection->getNextTile();
+	 if(id.valid())
+         {
+            id->computeMinMaxPix(theMinPerBand, theMaxPerBand);
+            
+            if(!buffer)
+            {
+               bytesInLine     = id->getScalarSizeInBytes() * width;
+               
+               // Buffer to hold one line x tileHeight
+               bufferSizeInBytes = bytesInLine * tileHeight * bands;
+               buffer = new unsigned char[bufferSizeInBytes];
+               memset(buffer, 0, bufferSizeInBytes);
+            }
+            id->unloadTile(buffer,
+                           bufferRect,
+                           OSSIM_BIL);
+         }
+         ++tileNumber;
+      }
+      
+      // Get the number of lines to write from the buffer.
+      ossim_uint32 linesToWrite =
+         min(tileHeight,
+             static_cast<ossim_uint32>(theAreaOfInterest.lr().y -
+                                       bufferRect.ul().y + 1));
+      
+      // Write the buffer out to disk.  
+      ossim_uint8* buf = buffer;
+      for (ossim_uint32 ii=0; ((ii<linesToWrite)&(!needsAborting())); ++ii)
+      {
+         for (ossim_uint32 band = 0;
+              ((band < bands)&&(!needsAborting()));
+              ++band)
+         {
+            wroteSomethingOut = true;
+            if(endian.getSystemEndianType() != theOutputByteOrder)
+            {
+               endian.swap(scalarType,
+                           buf,
+                           bytesInLine/ossimGetScalarSizeInBytes(scalarType));
+            }
+            theFileStream.write((char*)buf, bytesInLine);
+            if (!theFileStream)
+            {
+               ossimNotify(ossimNotifyLevel_FATAL)
+                  << MODULE << " ERROR:"
+                  << "Error returned writing line!" << std::endl;
+               setErrorStatus();
+	       if(buffer)
+               {
+                  // Free the memory.
+                  delete [] buffer;
+               }
+               return false;
+            }
+
+            buf += bytesInLine;
+         }
+         
+      } // End of loop to write lines from buffer to tiff file.
+
+      double tile = tileNumber;
+      double numTiles = numberOfTiles;
+      setPercentComplete(tile / numTiles * 100);
+
+      if(needsAborting())
+      {
+         setPercentComplete(100.0);
+      }
+
+   } // End of loop in the line (height) direction.
+
+   if(buffer)
+   {
+      // Free the memory.
+      delete [] buffer;
+   }
+   
+   if (traceDebug()) CLOG << " Exited." << std::endl;
+
+   return wroteSomethingOut;
+}
+
+bool ossimGeneralRasterWriter::writeToBsq()
+{
+   ossimEndian endian;
+   static const char* const MODULE = "ossimGeneralRasterWriter::writeToBsq";
+
+   if (traceDebug()) CLOG << " Entered." << std::endl;
+
+   //***
+   // Get an arbitrary tile just to get the size in bytes!
+   // This should be changed later... An ossimImageSourceInterface should know
+   // this.
+   //***
+   ossimRefPtr<ossimImageData> id;
+
+   // Start the sequence at the first tile.
+   theInputConnection->setToStartOfSequence();
+
+   ossim_uint32 bands     = theInputConnection->getNumberOfOutputBands();
+   ossim_uint32 tilesWide = theInputConnection->getNumberOfTilesHorizontal();
+   ossim_uint32 tilesHigh = theInputConnection->getNumberOfTilesVertical();
+   ossim_uint32 tileHeight      = theInputConnection->getTileHeight();
+   ossim_uint32 numberOfTiles   = theInputConnection->getNumberOfTiles();
+   ossim_uint32 width           = theAreaOfInterest.width();
+   ossim_uint32 height          = theAreaOfInterest.height();
+
+   ossim_uint32 bytesInLine     = 0;
+   ossim_uint32 buf_band_offset = 0;
+   
+   // Use the system "streampos" typedef for future 64 bit seeks (long long).
+   streampos file_band_offset = 0;
+   
+   //***
+   // Buffer to hold one line x tileHeight
+   //***
+   ossim_uint32 bufferSizeInBytes = 0;
+   unsigned char* buffer = NULL;
+      
+   theMinPerBand.clear();
+   theMaxPerBand.clear();
+
+   int tileNumber = 0;
+   bool wroteSomethingOut = false;
+   ossimScalarType scalarType = theInputConnection->getOutputScalarType();
+   for(ossim_uint32 i = 0; ((i < tilesHigh)&&(!needsAborting())); ++i)
+   {
+      if(buffer)
+      {
+	 // Clear the buffer.
+	 memset(buffer, 0, bufferSizeInBytes);
+      }
+      
+      ossimIrect bufferRect(theAreaOfInterest.ul().x,
+			    theAreaOfInterest.ul().y + i*tileHeight,
+			    theAreaOfInterest.ul().x + (width - 1),
+			    theAreaOfInterest.ul().y + i *
+                            tileHeight + (tileHeight - 1));
+      
+      // Tile loop in the sample (width) direction.
+      for(ossim_uint32 j = 0; ((j < tilesWide)&&(!needsAborting())); ++j)
+      {
+         // Get the tile and copy it to the buffer.
+         id = theInputConnection->getNextTile();
+	 if(id.valid())
+         {
+            id->computeMinMaxPix(theMinPerBand, theMaxPerBand);
+            if(!buffer)
+            {
+               bytesInLine     = id->getScalarSizeInBytes() * width;
+               buf_band_offset = bytesInLine * tileHeight;
+               file_band_offset = height * bytesInLine;
+               bufferSizeInBytes = bytesInLine * tileHeight * bands;
+               buffer = new unsigned char[bufferSizeInBytes];
+               memset(buffer, 0, bufferSizeInBytes);
+            }
+            id->unloadTile(buffer,
+                           bufferRect,
+                           OSSIM_BSQ);
+         }
+         ++tileNumber;
+      }
+      
+      // Get the number of lines to write from the buffer.
+      ossim_uint32 linesToWrite =
+         min(tileHeight,
+             static_cast<ossim_uint32>(theAreaOfInterest.lr().y -
+                                       bufferRect.ul().y + 1));
+      
+      // Write the buffer out to disk.  
+      ossim_uint32 start_line =
+         static_cast<ossim_uint32>(bufferRect.ul().y -
+                                   theAreaOfInterest.ul().y);
+      for (ossim_uint32 band = 0; ((band < bands)&&(!needsAborting())); ++band)
+      {
+         ossim_uint8* buf = buffer;
+         buf += buf_band_offset * band;
+         
+         // Put the file pointer in the right spot.
+         streampos pos = file_band_offset * band + start_line * bytesInLine;
+         theFileStream.seekp(pos, ios::beg);
+         if (!theFileStream)
+         {
+            ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:"
+                 << "Error returned seeking to image data position!" << std::endl;
+            setErrorStatus();
+            return false;
+         }
+         
+         for (ossim_uint32 ii=0; ((ii<linesToWrite)&&(!needsAborting())); ++ii)
+         {
+            wroteSomethingOut = true;
+            if(endian.getSystemEndianType() != theOutputByteOrder)
+            {
+               endian.swap(scalarType,
+                           buf,
+                           bytesInLine/ossimGetScalarSizeInBytes(scalarType));
+            }
+
+            theFileStream.write((char*)buf, bytesInLine);
+            
+            if (!theFileStream)
+            {
+               ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " ERROR:"
+                    << "Error returned writing line!" << std::endl;
+               setErrorStatus();
+               return false;
+            }
+            
+            buf += bytesInLine;
+         }
+         
+      } // End of loop to write lines from buffer to tiff file.
+      
+      double tile = tileNumber;
+      double numTiles = numberOfTiles;
+      setPercentComplete(tile / numTiles * 100);
+
+      if(needsAborting())
+      {
+         setPercentComplete(100.0);
+      }
+      
+   } // End of loop in the line (height) direction.
+   
+   // Free the memory.
+   delete [] buffer;
+   
+   if (traceDebug()) CLOG << " Exited." << std::endl;
+   
+   return wroteSomethingOut;
+}
+
+bool ossimGeneralRasterWriter::saveState(ossimKeywordlist& kwl,
+                                         const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::BYTE_ORDER_KW,
+           ((theOutputByteOrder==OSSIM_LITTLE_ENDIAN)?"little_endian":"big_endian"),
+           true);
+   return ossimImageFileWriter::saveState(kwl,
+                                      prefix);
+}
+
+bool ossimGeneralRasterWriter::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   const char* value;
+   
+   value = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   if(value)
+   {
+      setFilename(ossimFilename(value));
+   }
+   
+   value = kwl.find(prefix, ossimKeywordNames::INPUT_RR_LEVEL_KW);
+   if(value)
+   {
+      theRlevel = atoi(value);
+   }
+
+   if(ossimImageFileWriter::loadState(kwl, prefix))
+   {
+      if( (theOutputImageType!="general_raster_bip")      &&
+          (theOutputImageType!="general_raster_bil")      &&
+          (theOutputImageType!="general_raster_bsq")      &&
+          (theOutputImageType!="general_raster_bip_envi") &&
+          (theOutputImageType!="general_raster_bil_envi") &&
+          (theOutputImageType!="general_raster_bsq_envi")
+         )
+      {
+         theOutputImageType = "general_raster_bsq";
+      }
+   }
+   else
+   {
+      return false;
+   }
+   const char* outputByteOrder = kwl.find(prefix, ossimKeywordNames::BYTE_ORDER_KW);
+   theOutputByteOrder = ossimEndian().getSystemEndianType();
+   if(outputByteOrder)
+   {
+      ossimString byteOrder = outputByteOrder;
+      byteOrder = byteOrder.downcase();
+      if(byteOrder.contains("little"))
+      {
+         theOutputByteOrder = OSSIM_LITTLE_ENDIAN;
+      }
+      else if(byteOrder.contains("big"))
+      {
+         theOutputByteOrder = OSSIM_BIG_ENDIAN;
+      }
+   }
+   
+   return true;
+}
+
+void ossimGeneralRasterWriter::writeHeader() const
+{
+   static const char MODULE[] = "ossimGeneralRasterWriter::writeHeader";
+
+   if (traceDebug()) CLOG << " Entered..." << std::endl;
+
+   // Make a header file name from the image file.
+   ossimFilename headerFile = theFilename;
+   headerFile.setExtension(".omd"); // ossim meta data
+
+   std::ofstream os;
+   os.open(headerFile.c_str(), ios::out);
+   if (!os)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << MODULE << " Error:\n"
+           << "Could not open:  " << headerFile << std::endl;
+      return;
+   }
+
+   ossimString interleaveType = getInterleaveString();
+
+   ossimString scalar =
+      ossimScalarTypeLut::instance()->getEntryString(theInputConnection->
+                                                     getOutputScalarType());
+   
+   os << "// *** ossim meta data general raster header file ***\n"
+      << ossimKeywordNames::IMAGE_FILE_KW << ":  "
+      << theFilename.file().c_str() << "\n"
+      << ossimKeywordNames::IMAGE_TYPE_KW << ":  "
+      << getOutputImageTypeString() << "\n"
+      << ossimKeywordNames::INTERLEAVE_TYPE_KW << ":  "
+      << interleaveType.c_str() << "\n"
+      << ossimKeywordNames::NUMBER_BANDS_KW << ":  "
+      << theInputConnection->getNumberOfOutputBands() << "\n"
+      << ossimKeywordNames::NUMBER_LINES_KW << ":  "
+      << (theAreaOfInterest.lr().y - theAreaOfInterest.ul().y + 1) << "\n"
+      << ossimKeywordNames::NUMBER_SAMPLES_KW << ":  "
+      << (theAreaOfInterest.lr().x - theAreaOfInterest.ul().x + 1) << "\n"
+      << ossimKeywordNames::SCALAR_TYPE_KW << ":  "
+      << scalar.c_str() << "\n"
+      << ossimKeywordNames::BYTE_ORDER_KW <<": "
+      << ((theOutputByteOrder==OSSIM_BIG_ENDIAN)?"big_endian":"little_endian")
+      << "\n"
+      << std::endl;
+
+   // Output the null/min/max for each band.
+   os << "\n// NOTE:  Bands are one based, band1 is the first band."
+      << std::endl;
+
+   for (ossim_uint32 i=0; i<theInputConnection->getNumberOfOutputBands(); ++i)
+   {
+      ossimString prefix = ossimKeywordNames::BAND_KW +
+                           ossimString::toString(i+1) + ".";
+      
+      ossimString null_pix = ossimString::toString(theInputConnection->
+                                                   getNullPixelValue(i));
+      ossimString min_pix;
+      ossimString max_pix;
+
+      if(!theMinPerBand.size()||!theMaxPerBand.size())
+      {
+         min_pix  = ossimString::toString(theInputConnection->
+					  getMinPixelValue(i));
+         max_pix  =  ossimString::toString(theInputConnection->
+                                           getMaxPixelValue(i));
+      }
+      else
+      {
+         min_pix   = ossimString::toString(theMinPerBand[i]);
+         max_pix  = ossimString::toString(theMaxPerBand[i]);
+      }
+      
+      os << prefix.c_str() << ossimKeywordNames::NULL_VALUE_KW << ":  "
+         << null_pix.c_str() << "\n"
+         << prefix << ossimKeywordNames::MIN_VALUE_KW << ":  "
+         << min_pix.c_str() << "\n"
+         << prefix << ossimKeywordNames::MAX_VALUE_KW << ":  "
+         << max_pix.c_str() << std::endl;
+   }
+   
+   os.close();
+   
+   if (traceDebug()) CLOG << " Exited..." << endl;
+}
+
+void ossimGeneralRasterWriter::writeEnviHeader() const
+{
+   static const char MODULE[] = "ossimGeneralRasterWriter::writeEnviHeader";
+
+   if (traceDebug()) CLOG << " Entered..." << endl;
+
+   if (!theInputConnection)
+   {
+      return;
+   }
+   
+   // Make a header file name from the image file.
+   ossimFilename headerFile = theFilename;
+   headerFile.setExtension(".hdr"); // ossim meta data
+
+   ossimString interleaveType = getInterleaveString();
+   ossimKeywordlist kwl;
+   kwl.add(ossimKeywordNames::INTERLEAVE_TYPE_KW, interleaveType.c_str());
+
+   ossimEnviHeaderFileWriter hdr;
+   hdr.connectMyInputTo(0, theInputConnection);
+   hdr.initialize();
+   hdr.setFilename(headerFile);
+   hdr.loadState(kwl);
+   hdr.setAreaOfInterest(theAreaOfInterest);
+   hdr.execute();
+   
+   if (traceDebug()) CLOG << " Exited..." << endl;
+}
+
+void ossimGeneralRasterWriter::getImageTypeList(std::vector<ossimString>& imageTypeList)const
+{
+   imageTypeList.push_back(ossimString("general_raster_bip"));
+   imageTypeList.push_back(ossimString("general_raster_bil"));
+   imageTypeList.push_back(ossimString("general_raster_bsq"));
+   imageTypeList.push_back(ossimString("general_raster_bip_envi"));
+   imageTypeList.push_back(ossimString("general_raster_bil_envi"));
+   imageTypeList.push_back(ossimString("general_raster_bsq_envi"));
+}
+
+ossimString ossimGeneralRasterWriter::getInterleaveString() const
+{
+   ossimString interleaveType = "unknown";
+   if ( (theOutputImageType == "general_raster_bip") ||
+        (theOutputImageType == "general_raster_bip_envi") )
+   {
+      interleaveType = "bip";
+   }
+   else if ( (theOutputImageType == "general_raster_bil") ||
+             (theOutputImageType == "general_raster_bil_envi") )
+   {
+      interleaveType = "bil";
+   }
+   else if ( (theOutputImageType == "general_raster_bsq") ||
+             (theOutputImageType == "general_raster_bsq") )
+   {
+      interleaveType = "bsq";
+   }
+   return interleaveType;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterWriter.h b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterWriter.h
new file mode 100644
index 0000000000..089c43db28
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/general_raster/ossimGeneralRasterWriter.h
@@ -0,0 +1,120 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimGeneralRasterWriter.
+//
+//*******************************************************************
+//  $Id: ossimGeneralRasterWriter.h,v 1.27 2006/01/06 16:46:46 dburken Exp $
+
+#ifndef ossimGeneralRasterWriter_HEADER
+#define ossimGeneralRasterWriter_HEADER
+
+#include "imaging/formats/ossimImageFileWriter.h"
+#include "base/data_types/ossimIrect.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/data_types/ossimKeyword.h"
+
+class ossimGeneralRasterWriter : public ossimImageFileWriter
+{
+public:
+   ossimGeneralRasterWriter();
+   ossimGeneralRasterWriter(ossimImageSource* inputSource,
+                            const ossimFilename& file=ossimFilename(""));
+   virtual ~ossimGeneralRasterWriter();
+
+   /**
+    * void getImageTypeList(std::vector<ossimString>& imageTypeList)const
+    *
+    * Appends this writer image types to list "imageTypeList".
+    *
+    * This writer has the following types:
+    * general_raster_bip
+    * general_raster_bil
+    * general_raster_bsq
+    *
+    * @param imageTypeList stl::vector<ossimString> list to append to.
+    */ 
+   virtual void getImageTypeList(std::vector<ossimString>& imageTypeList)const;
+   
+   virtual void set_rr_level(ossim_uint32 rr) { theRlevel = rr; }
+   virtual bool isOpen()const;      
+   virtual bool open();
+   virtual void close();
+
+   /**
+    * saves the state of the object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+private:
+   virtual bool writeFile();
+
+   /**
+    *  Writes image data to output file in BIP(Band Interleaved by Pixel)
+    *  format.
+    *  @return true on success, false on error.
+    */
+   bool writeToBip();
+
+   /**
+    *  Writes image data to output file in BIL(Band Interleaved by Line)
+    *  format.
+    *  @return true on success, false on error.
+    */
+   bool writeToBil();
+   
+   /**
+    *  Writes image data to output file in BSQ(Band Sequential) format.
+    *  @return true on success, false on error.
+    */
+   bool writeToBsq();
+   
+   /**
+    *  Writes an ossim header file which can be used to load file in ossim.
+    *  Returns true on success, false on error.
+    */
+   void writeHeader() const;
+
+   /**
+    *  Writes an envi header file which can be used to load file in envi.
+    *  If the output image file is "foo.ras" then the ossim header file will
+    *  be "foo.hdr".
+    */
+   void writeEnviHeader() const;
+
+   /**
+    * @return The interleave as a string of either: bil, bip, or bsq
+    */
+   ossimString getInterleaveString() const;
+   
+   
+   std::ofstream       theFileStream;
+   bool                theOverviewFlag;
+   ossim_uint32        theRlevel;
+   ossimByteOrder      theOutputByteOrder;
+   
+  /**
+   * Populated while writting the data
+   */
+  std::vector<double>     theMinPerBand;
+  std::vector<double>     theMaxPerBand;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegTileSource.cpp
new file mode 100644
index 0000000000..532f597f47
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegTileSource.cpp
@@ -0,0 +1,606 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for JpegTileSource.
+//*******************************************************************
+//  $Id: ossimJpegTileSource.cpp,v 1.28 2005/10/20 19:58:37 gpotts Exp $
+
+#include <imaging/formats/jpeg/ossimJpegTileSource.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <imaging/ossimU8ImageData.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+
+RTTI_DEF1_INST(ossimJpegTileSource, "ossimJpegTileSource", ossimImageHandler)
+
+static ossimTrace traceDebug("ossimJpegTileSource:degug");  
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimJpegTileSource::ossimJpegTileSource()
+   :
+      ossimImageHandler(),
+      theTile(NULL),
+      theCacheTile(NULL),
+      theLineBuffer(NULL),
+      theFilePtr(0),
+      theBufferRect(0, 0, 0, 0),
+      theImageRect(0, 0, 0, 0),
+      theNumberOfBands(0),
+      theCacheSize	(0),
+      theCinfo(),
+      theJerr(),
+      theCacheId(-1)
+{}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimJpegTileSource::ossimJpegTileSource(const ossimKeywordlist& kwl,
+                               const char* prefix)
+   :
+      ossimImageHandler(),
+      theTile(NULL),
+      theCacheTile(NULL),
+      theLineBuffer(NULL),
+      theFilePtr(0),
+      theBufferRect(0, 0, 0, 0),
+      theImageRect(0, 0, 0, 0),
+      theNumberOfBands(0),
+      theCacheSize	(0),
+      theCinfo(),
+      theJerr(),
+      theCacheId(-1)
+{
+   if (loadState(kwl, prefix) == false)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimJpegTileSource::ossimJpegTileSource(const char* jpeg_file)
+   :
+      ossimImageHandler(),
+      theTile(NULL),
+      theCacheTile(NULL),
+      theLineBuffer(NULL),
+      theFilePtr(0),
+      theBufferRect(0, 0, 0, 0),
+      theImageRect(0, 0, 0, 0),
+      theNumberOfBands(0),
+      theCacheSize(0),
+      theCinfo(),
+      theJerr(),
+      theCacheId(-1)
+{
+   static const char MODULE[]
+      = "ossimJpegTileSource::ossimJpegTileSource";
+
+   if (!open())
+   {
+
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE
+         << "\nCannot open:  " << jpeg_file
+         << endl;
+   }
+}
+
+//*******************************************************************
+// Destructor:
+//*******************************************************************
+ossimJpegTileSource::~ossimJpegTileSource()
+{
+   destroy();
+}
+
+void ossimJpegTileSource::destroy()
+{
+   ossimAppFixedTileCache::instance()->deleteCache(theCacheId);
+
+   theTile      = NULL;
+   theCacheTile = NULL;
+
+   if (theLineBuffer)
+   {
+      delete [] theLineBuffer;
+      theLineBuffer = NULL;
+   }
+   if (theFilePtr)
+   {
+      fclose(theFilePtr);
+      theFilePtr = NULL;
+   }
+   jpeg_destroy_decompress( &theCinfo );
+}
+
+void ossimJpegTileSource::allocate()
+{
+   if(theLineBuffer)
+   {
+      delete [] theLineBuffer;
+      theLineBuffer = 0;
+   }
+   // Make the cache tile the height of one tile by the image width.
+   ossimGetDefaultTileSize(theCacheSize);
+   theCacheSize.x = theImageRect.width();
+
+   ossimAppFixedTileCache::instance()->deleteCache(theCacheId);
+   theCacheId = ossimAppFixedTileCache::instance()->newTileCache(theImageRect, theCacheSize);
+
+   theTile = ossimImageDataFactory::instance()->create(this, this);
+   theCacheTile = (ossimImageData*)theTile->dup();
+   theTile->initialize();
+   
+   ossimIrect cache_rect(theImageRect.ul().x,
+                         theImageRect.ul().y,
+                         theImageRect.ul().x + (theCacheSize.x-1),
+                         theImageRect.ul().y + (theCacheSize.y-1));
+   
+   theCacheTile->setImageRectangle(cache_rect);
+   theCacheTile->initialize();
+   
+   theLineBuffer = new ossim_uint8[theImageRect.width() * theNumberOfBands];
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimJpegTileSource::allocate DEBUG:"
+         << "\ncache tile size:           " << theCacheSize
+         << "\nimage width:               " << theImageRect.width()
+         << "\nimage height:              " << theImageRect.height()
+         << "\nnumber of bands:           " << theNumberOfBands
+         << endl;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimJpegTileSource::getTile(
+   const ossimIrect& tile_rect, ossim_uint32 resLevel)
+{
+   if(!isSourceEnabled()||!isOpen()||!isValidRLevel(resLevel))
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+   
+   if (theOverview)
+   {
+      if (theOverview->hasR0() || resLevel)
+      {
+         return theOverview->getTile(tile_rect, resLevel);
+      }
+   }
+
+   if (!theTile.valid())
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   theTile->setImageRectangle(tile_rect);
+   if (getImageRectangle(0).intersects(tile_rect))
+   {
+      // Make a clip rect.
+      ossimIrect clip_rect = tile_rect.clipToRect(getImageRectangle(0));
+
+      fillTile(clip_rect);
+   }
+   else
+   {
+      // No point in requested tile within the image rectangle.
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   return theTile;
+}
+
+void ossimJpegTileSource::fillTile(const ossimIrect& clip_rect)
+{
+   if (!theTile || !theFilePtr) return;
+
+   ossimIrect buffer_rect = clip_rect;
+   buffer_rect.stretchToTileBoundary(theCacheSize);
+   buffer_rect.set_ulx(0);
+   buffer_rect.set_lrx(getImageRectangle(0).lr().x);
+
+   // Check for a partial tile.
+   if ( ! theTile->getImageRectangle().completely_within(buffer_rect) )
+   {
+      theTile->makeBlank();
+   }
+
+   ossim_int32 number_of_cache_tiles = buffer_rect.height()/theCacheSize.y;
+
+#if 0
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "tiles high:  " << number_of_cache_tiles
+         << endl;
+   }
+#endif
+
+   ossimIpt origin = buffer_rect.ul();
+   
+   for (int tile = 0; tile < number_of_cache_tiles; ++tile)
+   {
+      // See if it's in the cache already.
+      ossimRefPtr<ossimImageData> tempTile;
+      tempTile = ossimAppFixedTileCache::instance()->
+         getTile(theCacheId, origin);
+      if (tempTile.valid())
+      {
+         theTile->loadTile(tempTile.get());
+      }
+      else
+      {
+         // Have to read from the jpeg file.
+         ossim_uint32 start_line = static_cast<ossim_uint32>(origin.y);
+         ossim_uint32 stop_line  = 
+            static_cast<ossim_uint32>( min(origin.y+theCacheSize.y-1,
+                                           getImageRectangle().lr().y) );
+         ossimIrect cache_rect(origin.x,
+                               origin.y,
+                               origin.x+theCacheSize.x-1,
+                               origin.y+theCacheSize.y-1);
+
+         theCacheTile->setImageRectangle(cache_rect);
+
+         if ( !theCacheTile->getImageRectangle().
+              completely_within(getImageRectangle()) )
+         {
+            theCacheTile->makeBlank();
+         }
+
+         if (start_line < theCinfo.output_scanline)
+         {
+            // Must restart the compression process again.
+            restart();
+         }
+         
+         // Get pointers to the cache tile buffers.
+         JSAMPROW jbuf[1];
+//         ossim_uint8* buf[3] = new ossim_uint8*[theNumberOfBands];
+         ossim_uint8* buf[3];
+         ossim_uint32 band = 0;
+         for (band = 0; band < theNumberOfBands; ++band)
+         {
+            buf[band] = theCacheTile->getUcharBuf(band);
+         }
+
+         const ossim_uint32 SAMPLES = getNumberOfSamples();
+         jbuf[0] = (JSAMPROW) theLineBuffer;
+
+         // Gobble any not needed lines.
+         while (theCinfo.output_scanline < start_line)
+         {
+            jpeg_read_scanlines(&theCinfo, jbuf, 1);
+         }
+
+         while (theCinfo.output_scanline <= stop_line)
+         {
+            // Read a line from the jpeg file.
+            jpeg_read_scanlines(&theCinfo, jbuf, 1);
+            
+            //---
+            // Copy the line which if band interleaved by pixel the the band
+            // separate buffers.
+            //---
+            ossim_uint32 index = 0;
+            for (ossim_uint32 sample = 0; sample < SAMPLES; ++sample)
+            {
+               for (band = 0; band < theNumberOfBands; ++band)
+               {
+                  buf[band][sample] = theLineBuffer[index];
+                  ++index;
+               }
+            }
+            
+            for (band = 0; band < theNumberOfBands; ++band)
+            {
+               buf[band] += SAMPLES;
+            }
+         }
+         theCacheTile->validate();
+         
+         theTile->loadTile(theCacheTile.get());
+         
+         // Add it to the cache for the next time.
+         ossimAppFixedTileCache::instance()->addTile(theCacheId, theCacheTile);
+         
+
+//         delete[] buf;
+
+      } // End of reading for jpeg file.
+      
+      origin.y += theCacheSize.y;
+      
+   } // for (int tile = 0; tile < number_of_cache_tiles; ++tile)
+
+   theTile->validate();
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+ossimIrect
+ossimJpegTileSource::getImageRectangle(ossim_uint32 reduced_res_level) const
+{
+   return ossimIrect(0,
+                     0,
+                     getNumberOfSamples(reduced_res_level) - 1,
+                     getNumberOfLines(reduced_res_level)   - 1);
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimJpegTileSource::saveState(ossimKeywordlist& kwl,
+                               const char* prefix) const
+{
+   return ossimImageHandler::saveState(kwl, prefix);
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimJpegTileSource::loadState(const ossimKeywordlist& kwl,
+                               const char* prefix)
+{
+   if (ossimImageHandler::loadState(kwl, prefix))
+   {
+      return open();
+   }
+
+   return false;
+}
+
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimJpegTileSource::open(const ossimFilename& jpeg_file)
+{
+   theImageFile = jpeg_file;
+
+   return open();
+}
+
+//*******************************************************************
+// Private method:
+//*******************************************************************
+bool ossimJpegTileSource::open()
+{
+   static const char MODULE[] = "ossimJpegTileSource::open";
+
+   // Start with a clean slate.
+   destroy();
+
+   // Open Jpeg file.
+   if((theFilePtr = fopen(theImageFile.c_str(), "rb")) == NULL)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << "\nERROR:\n"
+            << "Could not open:  " << theImageFile.c_str()
+            << endl;
+      }
+      
+      return false;
+   }
+
+   //***
+   // Verify the file is a jpeg by checking the first two bytes.
+   //***
+   ossim_uint8 c[2];
+   fread(c, 2, 1, theFilePtr);
+   if( c[0] != 0xFF || c[1] != 0xD8 )
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " NOTICE:\n"
+            << "Not a jpeg file..." << endl;
+      }
+      
+      fclose(theFilePtr);
+      theFilePtr = NULL;
+      return false;
+   }
+
+   rewind(theFilePtr);
+
+   //---
+   // Step 1: allocate and initialize JPEG decompression object
+   // We set up the normal JPEG error routines, then override error_exit.
+   //---   
+   theCinfo.err = jpeg_std_error(&theJerr);
+
+   // Initialize the JPEG decompression object.
+   jpeg_create_decompress(&theCinfo);
+
+   // Specify data source.
+   jpeg_stdio_src(&theCinfo, theFilePtr);
+
+   // Read the file parameters with jpeg_read_header.
+   jpeg_read_header(&theCinfo, TRUE);
+
+   jpeg_start_decompress(&theCinfo);
+
+   theNumberOfBands = theCinfo.output_components;
+
+   theImageRect = ossimIrect(0,
+                             0,
+                             theCinfo.output_width  - 1,
+                             theCinfo.output_height - 1);
+   
+   theBufferRect.set_lrx(theCinfo.output_width  - 1);
+   
+   completeOpen();
+
+   // Allocate memory...
+   allocate();
+
+   return true;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimJpegTileSource::getTileWidth() const
+{
+   return ( theTile.valid() ? theTile->getWidth() : 0 );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimJpegTileSource::getTileHeight() const
+{
+   return ( theTile.valid() ? theTile->getHeight() : 0 );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimJpegTileSource::isValidRLevel(ossim_uint32 reduced_res_level) const
+{
+   static const char MODULE[] = "ossimJpegTileSource::isValidRLevel";
+
+   if (reduced_res_level == 0)
+   {
+      return true;
+   }
+   else if (theOverview)
+   {
+      return theOverview->isValidRLevel(reduced_res_level);
+   }
+   else
+   {
+      cerr << MODULE << " Invalid reduced_res_level:  " << reduced_res_level
+           << "\nHighest available:  " << (getNumberOfDecimationLevels() - 1)
+           << endl;
+      return false;
+   }
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimJpegTileSource::getNumberOfLines(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theImageRect.lr().y - theImageRect.ul().y + 1;
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfLines(reduced_res_level);
+   }
+
+   return 0;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimJpegTileSource::getNumberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      return theImageRect.lr().x - theImageRect.ul().x + 1;;
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfSamples(reduced_res_level);
+   }
+
+   return 0;
+}
+
+ossim_uint32 ossimJpegTileSource::getImageTileWidth() const
+{
+   return 0;
+}
+
+ossim_uint32 ossimJpegTileSource::getImageTileHeight() const
+{
+   return 0;
+}
+
+ossimString ossimJpegTileSource::getShortName()const
+{
+   return ossimString("jpg");
+}
+   
+ossimString ossimJpegTileSource::getLongName()const
+{
+   return ossimString("jpg reader");
+}
+
+ossimString  ossimJpegTileSource::className()const
+{
+   return ossimString("ossimJpegTileSource");
+}
+
+ossim_uint32 ossimJpegTileSource::getNumberOfInputBands() const
+{
+   return theNumberOfBands;
+}
+
+ossim_uint32 ossimJpegTileSource::getNumberOfOutputBands()const
+{
+   return getNumberOfInputBands();
+}
+
+ossimScalarType ossimJpegTileSource::getOutputScalarType() const
+{
+   return OSSIM_UCHAR;
+}
+
+bool ossimJpegTileSource::isOpen()const
+{
+   return (theFilePtr != NULL);
+}
+
+void ossimJpegTileSource::restart()
+{
+   jpeg_abort_decompress( &theCinfo );
+   jpeg_destroy_decompress( &theCinfo );
+   
+   // Put the theFilePtr back to the start...
+   rewind(theFilePtr);
+
+   // Initialize the JPEG decompression object.
+   jpeg_create_decompress(&theCinfo);
+
+   // Specify data source.
+   jpeg_stdio_src(&theCinfo, theFilePtr);
+
+   // Read the file parameters with jpeg_read_header.
+   jpeg_read_header(&theCinfo, TRUE);
+
+   jpeg_start_decompress(&theCinfo);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegTileSource.h
new file mode 100644
index 0000000000..04a3a1e9a4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegTileSource.h
@@ -0,0 +1,198 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for JpegTileSource.
+// JpegTileSource is derived from ImageHandler which is derived from
+// TileSource.
+//*******************************************************************
+//  $Id: ossimJpegTileSource.h,v 1.23 2005/07/25 22:49:06 dburken Exp $
+
+#ifndef ossimJpegTileSource_HEADER
+#define ossimJpegTileSource_HEADER
+
+#include <cstdio>
+
+//---
+// Using windows .NET compiler there is a conflict in the libjpeg with INT32
+// in the file jmorecfg.h.  Defining XMD_H fixes this.
+//---
+#if defined(__BORLANDC__)
+#include <iostream>
+using std::size_t;
+#include <stdlib.h>
+#include <stdio.h>
+#endif
+extern "C"
+{
+#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__)
+#  ifndef XMD_H
+#    define XMD_H
+#  endif
+#endif
+#include <jpeglib.h>
+#include <setjmp.h>
+}
+
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/cache/ossimAppFixedTileCache.h>
+
+class  ossimImageData;
+
+class OSSIM_DLL ossimJpegTileSource : public ossimImageHandler
+{
+public:
+
+   ossimJpegTileSource();
+
+   ossimJpegTileSource(const ossimKeywordlist& kwl,
+                       const char* prefix=0);
+
+   ossimJpegTileSource(const char* jpeg_file);
+
+   virtual ~ossimJpegTileSource();
+
+   virtual ossimString getShortName() const;
+   virtual ossimString getLongName()  const;
+   virtual ossimString className()    const;
+
+   /**
+    *  Returns a pointer to a tile given an origin representing the upper
+    *  left corner of the tile to grab from the image.
+    *  Satisfies pure virtual from TileSource class.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+
+    /**
+     *  Returns the number of bands in the image.
+     *  Satisfies pure virtual from ImageHandler class.
+     */
+   virtual ossim_uint32 getNumberOfInputBands() const;
+
+   /**
+    * Returns the number of bands in a tile returned from this TileSource.
+    * Note: we are supporting sources that can have multiple data objects.
+    * If you want to know the scalar type of an object you can pass in the
+    */
+   virtual ossim_uint32 getNumberOfOutputBands()const;
+
+   /**
+     *  Returns the number of lines in the image.
+     *  Satisfies pure virtual from ImageHandler class.
+     */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
+
+   /**
+    *  Returns the number of samples in the image.
+    *  Satisfies pure virtual from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
+
+   /**
+    * Returns the zero based image rectangle for the reduced resolution data
+    * set (rrds) passed in.  Note that rrds 0 is the highest resolution rrds.
+    */
+   virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level = 0) const;
+
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * Returns the output pixel type of the tile source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32    getTileWidth() const;
+
+   /**
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32    getTileHeight() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;
+
+   bool isValidRLevel(ossim_uint32 reduced_res_level) const;
+
+
+   bool isOpen()const;
+   /**
+    *  Returns true if the image_file can be opened and is a valid tiff file.
+    */
+   bool open(const ossimFilename& jpeg_file);
+
+protected:
+   /**
+    *  Returns true if no errors initializing object.
+    *
+    *  Notes:
+    *  - Callers of this method must ensure "theTiffPtr" data member
+    *    is initialized.
+    *  - This method was added to consolidate object initialization code
+    *    between constructor and public open method.
+    */
+   virtual bool open();
+
+   void allocate();
+   void destroy();
+   void restart();
+
+   /**
+    * @note this method assumes that setImageRectangle has been called on
+    * theTile.
+    */
+   void fillTile(const ossimIrect& clip_rect);
+
+   ossimRefPtr<ossimImageData>  theTile;
+   ossimRefPtr<ossimImageData>  theCacheTile;
+   ossim_uint8*                 theLineBuffer;
+   FILE*                        theFilePtr;
+   ossimIrect                   theBufferRect;
+   ossimIrect                   theImageRect;
+   ossim_uint32                 theNumberOfBands;
+   ossimIpt                     theCacheSize;
+
+   struct jpeg_decompress_struct theCinfo;
+   struct jpeg_error_mgr         theJerr;
+
+   ossimAppFixedTileCache::ossimAppFixedCacheId theCacheId;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegWriter.cpp
new file mode 100644
index 0000000000..d833f13dfa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegWriter.cpp
@@ -0,0 +1,469 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+//
+//*******************************************************************
+//  $Id: ossimJpegWriter.cpp,v 1.51 2006/01/06 16:46:46 dburken Exp $
+
+#include <cstdio>
+
+//---
+// Using windows .NET compiler there is a conflict in the libjpeg with INT32
+// in the file jmorecfg.h.  Defining XMD_H fixes this.
+extern "C"
+{
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#  ifndef XMD_H
+#    define XMD_H
+#  endif
+#endif
+#include <jpeglib.h>
+}
+
+#include <imaging/formats/jpeg/ossimJpegWriter.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/property/ossimNumericProperty.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSource.h>
+#include <imaging/tile_sources/ossimScalarRemapper.h>
+
+RTTI_DEF1_INST(ossimJpegWriter, "ossimJpegWriter", ossimImageFileWriter)
+
+static const char DEFAULT_FILE_NAME[] = "output.jpg";
+static const ossim_int32 DEFAULT_JPEG_QUALITY = 75;
+static ossimTrace traceDebug("ossimJpegWriter:debug");
+
+
+//*******************************************************************
+// Constructor:
+//*******************************************************************
+ossimJpegWriter::ossimJpegWriter()
+   : ossimImageFileWriter(),
+     theQuality(DEFAULT_JPEG_QUALITY),
+     theRlevel(0),
+     theOutputFilePtr(NULL)
+{
+   // Since there is no internal geometry set the flag to write out one.
+   setWriteExternalGeometryFlag(true);
+}
+
+ossimJpegWriter::ossimJpegWriter(ossimImageSource* inputSource,
+                                 const ossimFilename& filename)
+   :ossimImageFileWriter(filename, inputSource),
+    theQuality(DEFAULT_JPEG_QUALITY),
+    theRlevel(0),
+    theOutputFilePtr(NULL)
+{
+   // Since there is no internal geometry set the flag to write out one.
+   setWriteExternalGeometryFlag(true);
+}
+//*******************************************************************
+// Destructor
+//*******************************************************************
+ossimJpegWriter::~ossimJpegWriter()
+{
+   close();
+}
+
+bool ossimJpegWriter::writeFile()
+{
+   static const char MODULE[] = "ossimJpegWriter::writeFile";
+
+   if( getErrorStatus() != ossimErrorCodes::OSSIM_OK )
+   {
+      return false;
+   }
+
+   bool needToDeleteInput = false;
+
+   if(theInputConnection->getOutputScalarType() != OSSIM_UINT8)
+   {
+      ossimImageSource* inputSource=new ossimScalarRemapper;
+
+      inputSource->connectMyInputTo(0, theInputConnection->getInput(0));
+      theInputConnection->connectMyInputTo(0, inputSource);
+      theInputConnection->initialize();
+      needToDeleteInput = true;
+   }
+
+   if(theInputConnection->isMaster())
+   {
+      if (!isOpen())
+      {
+         open();
+      }
+      
+      if (!theOutputFilePtr)
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " ERROR:"
+            << "\nCannot open:  " << theFilename.c_str()
+            << "\nReturning from method." << endl;
+         
+         return false;
+      }
+      
+      if (traceDebug())
+      {
+         CLOG << " DEBUG:"
+              << "\nOutput Rect:  " << theAreaOfInterest << endl;
+      }
+      
+      // Get the number of bands.  Must be one or three for this writer.
+      ossim_int32 components   = theInputConnection->getNumberOfOutputBands();
+      
+      if (components != 1 && components != 3)
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " Range Error:"
+            << "\nInvalid number of input bands!  Must be one or three."
+            << "\nInput bands = " << components
+            << "\nReturning from method." << endl;
+         
+         return false;
+      }
+      
+      //
+      // There should be a check to see if "theRlevel" is out of range.
+      //
+      // if (theRlevel < theImageSource
+      
+      ossim_int32 image_height
+         = theAreaOfInterest.lr().y - theAreaOfInterest.ul().y + 1;
+      ossim_int32 image_width
+         = theAreaOfInterest.lr().x - theAreaOfInterest.ul().x + 1;
+      ossim_int32 tileWidth    = theInputConnection->getTileWidth();
+      ossim_int32 tileHeight   = theInputConnection->getTileHeight();
+      
+      // Allocate a buffer to hold a row of tiles.
+      ossim_int32 buf_size = tileHeight*image_width*components;
+      
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nbuf_size:  " << buf_size
+              << endl;
+      }
+      
+      ossim_uint8* buf = new ossim_uint8[buf_size];
+      ossimImageData* blankTile = new ossimImageData(NULL,
+                                                     OSSIM_UINT8,
+                                                     components,
+                                                     tileWidth,
+                                                     tileHeight);
+      blankTile->initialize();
+      //
+      // Stuff needed for the jpeg library.
+      // Taken from "example.c" file of the "jpeg-6b" package.
+      //
+      struct jpeg_compress_struct cinfo;
+      struct jpeg_error_mgr jerr;
+      JSAMPROW row_pointer[1];  // pointer to JSAMPLE row[s]
+      
+      // physical row width in image buffer
+      int row_stride = image_width * components;
+      
+      cinfo.err = jpeg_std_error(&jerr);
+      jpeg_create_compress(&cinfo);
+      jpeg_stdio_dest(&cinfo, theOutputFilePtr);
+      cinfo.image_width = image_width;   // image width and height, in pixels
+      cinfo.image_height = image_height;
+      cinfo.input_components = components;	// # of color components per pixel
+      
+      // colorspace of input image 
+      if (components == 3)
+      {
+         cinfo.in_color_space = JCS_RGB;
+      }
+      else
+      {
+         cinfo.in_color_space = JCS_GRAYSCALE;
+      }
+      
+      jpeg_set_defaults(&cinfo);
+      jpeg_set_quality(&cinfo, theQuality, TRUE); //limit to baseline-JPEG values 
+      jpeg_start_compress(&cinfo, TRUE);
+      
+      theInputConnection->setAreaOfInterest(theAreaOfInterest);
+      theInputConnection->setToStartOfSequence();
+      long maxY = (long)theInputConnection->getNumberOfTilesVertical();
+      long maxX = (long)theInputConnection->getNumberOfTilesHorizontal();
+      
+      ossimProcessInterface::ossimProcessStatus processStatus = getProcessStatus();
+      
+      double tileCount = 0.0;
+      double totalTiles = theInputConnection->getNumberOfTiles();
+      //
+      // Ok the jpeg stuff should be set.  Loop through and grab a row of tiles
+      // and copy to the buffer.  Then write the buffer to the jpeg file.
+      // Get the next row... until finished.
+      //
+      for (ossim_int32 i=0;
+           ((i<maxY)&&
+            (!needsAborting()));
+           ++i)
+      {
+         ossimIrect buf_rect = theAreaOfInterest;
+         buf_rect.set_uly(theAreaOfInterest.ul().y+i*tileHeight);
+         buf_rect.set_lry(buf_rect.ul().y + tileHeight - 1);
+         
+         for (ossim_int32 j=0;
+              ((j<maxX)&&
+               (!needsAborting()));
+              ++j)
+         {
+            // Grab the tile.
+            const ossimRefPtr<ossimImageData> t =
+               theInputConnection->getNextTile();
+
+            if ( t.valid() )
+            {
+               if (t->getDataObjectStatus() != OSSIM_NULL)
+               {
+                  // Copy the tile to the buffer.
+                  t->unloadTile(buf, buf_rect, OSSIM_BIP);
+               }
+               else
+               {
+                  blankTile->setOrigin(t->getOrigin());
+                  blankTile->unloadTile(buf, buf_rect, OSSIM_BIP);
+               }
+            }
+            ++tileCount;
+            setPercentComplete((100.0*(tileCount/totalTiles)));
+            
+         }  // End of loop through tiles in the x direction.
+         
+         // Copy the buffer to the jpeg file.
+         ossim_int32 lines_to_copy =
+            min( (buf_rect.lr().y-buf_rect.ul().y+1),
+                 (theAreaOfInterest.lr().y-buf_rect.ul().y+1) );
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << MODULE
+               << "buf_rect:       " << buf_rect
+               << "lines_to_copy:  " << lines_to_copy << endl;
+         }
+         
+         processStatus = getProcessStatus();
+         if(!needsAborting())
+         {
+            // Now copy the buffer that should be full to the jpeg file.
+            ossim_int32 buf_offset = 0;
+            for (ossim_int32 line=0; line<lines_to_copy; ++line)
+            {
+               row_pointer[0] = &buf[buf_offset];
+               jpeg_write_scanlines(&cinfo, row_pointer, 1);
+               buf_offset += row_stride;
+            }
+         }
+         
+      } // End of loop through tiles in the y direction.
+      
+      // Free memory.
+      if(!needsAborting())
+      {
+	jpeg_finish_compress(&cinfo);
+      }
+      
+      fclose(theOutputFilePtr);
+      theOutputFilePtr = NULL;
+
+      jpeg_destroy_compress(&cinfo);
+      
+      delete [] buf;
+      delete blankTile;
+      blankTile = NULL;
+   }
+   else
+   {
+      theInputConnection->slaveProcessTiles();
+   }
+   if(needToDeleteInput)
+   {
+      ossimConnectableObject* obj = theInputConnection->getInput(0);
+      if(obj)
+      {
+         theInputConnection->connectMyInputTo(0, obj->getInput(0));
+         delete obj;
+         obj = NULL;
+      }
+   }
+   
+   return true;
+}
+
+bool ossimJpegWriter::saveState(ossimKeywordlist& kwl,
+                                const char* prefix)const
+{
+   return ossimImageFileWriter::saveState(kwl, prefix);
+}
+
+bool ossimJpegWriter::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   const char* value;
+   
+   value = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   if(value)
+   {
+      setFilename(value);
+   }
+   
+   value = kwl.find(prefix, ossimKeywordNames::COMPRESSION_QUALITY_KW);
+   if(value)
+   {
+      setQuality(atoi(value));
+   }
+   
+   value = kwl.find(prefix, ossimKeywordNames::OVERVIEW_FILE_KW);
+   if(value)
+   {
+      theOverviewFlag = (atoi(value)) ? true : false;
+   }
+   
+   value = kwl.find(prefix, ossimKeywordNames::REDUCED_RES_LEVEL_KW);
+   if(value)
+   {
+      theRlevel = atoi(value);
+   }
+   theOutputImageType = "jpeg";
+   
+   return ossimImageFileWriter::loadState(kwl, prefix);
+}
+
+void ossimJpegWriter::setQuality(ossim_int32 quality)
+{
+   static const char MODULE[] = "ossimJpegWriter::setQuality";
+   
+   // Range 1 to 100 with 100 being best.
+   if (quality > 0 && quality < 101)
+   {
+      theQuality = quality;
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nquality out of range:  " << quality
+            << "\nquality has been set to default:  " 
+            << DEFAULT_JPEG_QUALITY
+            << "\nvalid range:  1 to 100 with 100 being best."
+            << endl;
+      }
+      
+      theQuality = DEFAULT_JPEG_QUALITY;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " DEBUG:"
+         << "\nQuality set to:  "
+         << theQuality << endl;
+   }
+}
+
+void ossimJpegWriter::set_rr_level(ossim_uint32 rr)
+{
+   theRlevel = rr;
+}
+
+bool ossimJpegWriter::isOpen() const
+{
+   return (theOutputFilePtr!=NULL);
+}
+
+bool ossimJpegWriter::open()
+{
+   close();
+   theOutputFilePtr = fopen(theFilename.c_str(), "wb");
+   if(theOutputFilePtr)
+   {
+      return true;
+   }
+   return false;
+}
+
+void ossimJpegWriter::close()
+{
+   if(theOutputFilePtr)
+   {
+      fclose(theOutputFilePtr);
+      theOutputFilePtr = NULL;
+   }
+}
+
+void ossimJpegWriter::getImageTypeList(std::vector<ossimString>& imageTypeList)const
+{
+   imageTypeList.push_back(ossimString("jpeg"));
+}
+
+bool ossimJpegWriter::hasImageType(const ossimString& imageType) const
+{
+   if((imageType == "image/jpeg")||
+      (imageType == "image/jpg"))
+   {
+      return true;
+   }
+
+   return ossimImageFileWriter::hasImageType(imageType);
+}
+
+void ossimJpegWriter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if (!property)
+   {
+      return;
+   }
+   
+   if(property->getName() == ossimKeywordNames::COMPRESSION_QUALITY_KW)
+   {
+      ossimNumericProperty* numericProperty = PTR_CAST(ossimNumericProperty,
+                                                       property.get());
+      if (numericProperty)
+      {
+         setQuality( numericProperty->asInt32() );
+      }
+   }
+   else
+   {
+      ossimImageFileWriter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimJpegWriter::getProperty(const ossimString& name)const
+{
+   if (name == ossimKeywordNames::COMPRESSION_QUALITY_KW)
+   {
+      ossimNumericProperty* prop =
+         new ossimNumericProperty(name,
+                                  ossimString::toString(theQuality),
+                                  1.0,
+                                  100.0);
+      prop->setNumericType(ossimNumericProperty::ossimNumericPropertyType_INT);
+      return prop;
+   }
+
+   return ossimImageFileWriter::getProperty(name);
+}
+
+void ossimJpegWriter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimString name = ossimKeywordNames::COMPRESSION_QUALITY_KW;
+   propertyNames.push_back(name);
+   
+   ossimImageFileWriter::getPropertyNames(propertyNames);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegWriter.h b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegWriter.h
new file mode 100644
index 0000000000..fc6ef3a26d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/jpeg/ossimJpegWriter.h
@@ -0,0 +1,110 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for JpegWriter.
+//
+//*******************************************************************
+//  $Id: ossimJpegWriter.h,v 1.18 2006/01/06 16:46:46 dburken Exp $
+#ifndef ossimJpegWriter_HEADER
+#define ossimJpegWriter_HEADER
+
+#include <imaging/formats/ossimImageFileWriter.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+//*******************************************************************
+// CLASS:  ossimJpegWriterFactory
+//*******************************************************************
+
+class OSSIMDLLEXPORT ossimJpegWriter : public ossimImageFileWriter
+{
+public:
+
+   ossimJpegWriter();
+
+   virtual              ~ossimJpegWriter();
+
+   ossimJpegWriter(ossimImageSource *inputSource,
+                   const ossimFilename& filename);
+
+   /**
+    * void getImageTypeList(std::vector<ossimString>& imageTypeList)const
+    *
+    * Appends this writer image types to list "imageTypeList".
+    *
+    * This writer only has one type "jpeg".
+    *
+    * @param imageTypeList stl::vector<ossimString> list to append to.
+    */
+   virtual void getImageTypeList(std::vector<ossimString>& imageTypeList)const;
+   
+   /**
+    * Sets the jpeg compression quality.
+    *
+    * @param quality Compression quality.  (valid range is 1 to 100)
+    */
+   virtual void  setQuality(ossim_int32 quality);
+   
+   virtual void  set_rr_level(ossim_uint32 rr);
+
+   virtual bool isOpen()const;   
+   
+   virtual bool open();
+
+   virtual void close();
+   
+   /**
+    * saves the state of the object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * Will set the property whose name matches the argument
+    * "property->getName()".
+    *
+    * @param property Object containing property to set.
+    */
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+
+   /**
+    * @param name Name of property to return.
+    * 
+    * @returns A pointer to a property object which matches "name".
+    */
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+
+   /**
+    * Pushes this's names onto the list of property names.
+    *
+    * @param propertyNames array to add this's property names to.
+    */
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   bool hasImageType(const ossimString& imageType) const;
+
+   
+private:
+   virtual bool writeFile();
+   
+   ossim_int32       theQuality;
+   bool              theOverviewFlag;
+   ossim_uint32      theRlevel;
+   FILE*             theOutputFilePtr;
+   
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimJpegWriter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/landsat/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/landsat/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/landsat/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/landsat/ossimLandsatTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/landsat/ossimLandsatTileSource.cpp
new file mode 100644
index 0000000000..a05c73da8b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/landsat/ossimLandsatTileSource.cpp
@@ -0,0 +1,450 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class implementaiton for the class "ossim LandsatTileSource".
+//
+//*******************************************************************
+//  $Id: ossimLandsatTileSource.cpp,v 1.27 2005/11/10 15:07:49 gpotts Exp $
+
+#include <imaging/formats/landsat/ossimLandsatTileSource.h>
+#include <base/data_types/ossimDirectory.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimKeywordNames.h>
+#include <support_data/ff_l7/ossimFfL7.h>
+#include <support_data/ff_l7/ossimFfL5.h>
+#include <projections/sensor_modeling/landsat/ossimLandSatModel.h>
+
+RTTI_DEF1_INST(ossimLandsatTileSource,
+               "ossimLandsatTileSource",
+               ossimGeneralRasterTileSource)
+
+static ossimTrace traceDebug("ossimLandsatTileSource:debug");
+
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimLandsatTileSource::ossimLandsatTileSource()
+   :
+      ossimGeneralRasterTileSource(),
+      theFfHdr(NULL)
+{
+}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimLandsatTileSource::ossimLandsatTileSource(const ossimKeywordlist& kwl,
+                                               const char* prefix)
+   :
+      ossimGeneralRasterTileSource(),
+      theFfHdr(NULL)
+{
+   if (loadState(kwl, prefix) == false)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+}
+
+//*******************************************************************
+// Destructor:
+//*******************************************************************
+ossimLandsatTileSource::~ossimLandsatTileSource()
+{
+   if (theFfHdr)
+   {
+      delete theFfHdr;
+      theFfHdr = NULL;
+   }
+}
+
+bool ossimLandsatTileSource::open()
+{
+   static const char MODULE[] = "ossimLandsatTileSource::open";
+
+   if (traceDebug()) CLOG << " Entered..." << endl
+                          << " trying to open file " << theImageFile << std::endl;
+
+   ossimFilename tempFilename = theImageFile;
+   // See if the file passed in is a header file.
+
+   openHeader(theImageFile);
+
+   if (!theFfHdr) return false;
+
+   // Start building the keyword list for the general raster base class.
+   ossimKeywordlist kwl;
+
+   //***
+   // There can be up to seven (six for L7) files that belong to the header.
+   // Note that it seems the file names in the header are always upper case.
+   // So test the file given to us to see if they should be downcased.  This
+   // is assuming that all files in the directory have the same case.
+   //***
+   ossimFilename f1 = theImageFile.file();
+   vector<ossimFilename> fileList;
+
+   const char* c = f1.c_str();
+   bool downcase = false;
+   if ((c[0]<='z') && (c[0]>='a')) downcase = true;
+   for (ossim_uint32 i=0; i<theFfHdr->getBandCount(); ++i)
+   {
+      f1 = theFfHdr->theBandFileNames[i];
+      if (f1.trim() != "")
+      {
+         if (downcase) f1.downcase();
+         
+          // Make the file name.
+          ossimFilename f2 = theImageFile.path();
+          f2 = f2.dirCat(f1);
+
+          if (traceDebug())
+          {
+             CLOG << "DEBUG:"
+                  << "\nfile[" << i << "]  " << f2.c_str() << endl;
+          }
+
+          // See if it exists.
+          if (f2.exists())
+          {
+             if (traceDebug())
+             {
+                CLOG << "DEBUG:"
+                     << "\nAdding file:  " << f2 << endl;
+             }
+	     fileList.push_back(f2);
+          }
+      }
+   }
+   if(fileList.size() == 0)
+   {
+      close();
+      return false;
+   }
+   ossimGeneralRasterInfo generalRasterInfo(fileList,
+					    OSSIM_UINT8,
+					    OSSIM_BSQ_MULTI_FILE,
+					    fileList.size(),
+					    theFfHdr->theLinesPerBand,
+					    theFfHdr->thePixelsPerLine,
+					    0,
+					    ossimGeneralRasterInfo::NONE,
+					    0);
+   if(fileList.size() == 1)
+   {
+      generalRasterInfo = ossimGeneralRasterInfo(fileList,
+                                                 OSSIM_UINT8,
+                                                 OSSIM_BSQ,
+                                                 fileList.size(),
+                                                 theFfHdr->theLinesPerBand,
+                                                 theFfHdr->thePixelsPerLine,
+                                                 0,
+                                                 ossimGeneralRasterInfo::NONE,
+                                                 0);
+   }
+   theMetaData.clear();
+   theMetaData.setScalarType(OSSIM_UINT8);
+   theMetaData.setNumberOfBands(fileList.size());   
+   theImageData = generalRasterInfo;
+   if(initializeHandler())
+   {
+      theImageFile = tempFilename;
+      
+      completeOpen();
+   }
+   else
+   {
+      if (traceDebug()) CLOG << " Exited..." << endl;
+      return false;
+   }
+   
+   if (traceDebug()) CLOG << " Exited..." << endl;
+   
+   return true;
+}
+   
+void ossimLandsatTileSource::openHeader(const ossimFilename& file)
+{
+   //***
+   // Landsat file name example:  l71024031_03119990929_hpn.fst
+   // Three header header file type substrings:
+   // HPN = Pan
+   // HRF = VNIR/SWIR (visible near infrared/shortwave infrared)
+   // HTM = Thermal
+   //***
+   ossimFilename hdr = file.file();
+   hdr.downcase();
+   if ( hdr.contains("hpn") || hdr.contains("hrf") || hdr.contains("htm") )
+   {
+      theFfHdr = new ossimFfL7(file.c_str());      
+   } else if (hdr.contains("header.dat"))
+   {
+      theFfHdr = new ossimFfL5(file.c_str());
+   } else {
+      theFfHdr = NULL;
+      return;
+   }
+   if (theFfHdr->getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+      delete theFfHdr;
+      theFfHdr = NULL;
+   }
+   return;
+
+   // I had to force the open to go with a header since there are duplicate entries when scanning
+   // landsat directories.
+   //  For now I am commenting this code out.
+   //
+#if 0
+   //***
+   // User may have passed in an image file name in which case the header file
+   // must be derived from it.
+   //***
+   if (hdr.size() < 25)
+   {
+      // file name not long enough...
+      if (traceDebug())
+      {
+         cout << "ossimLandsatTileSource::openHeader DEBUG:"
+              << "\nNot a standard landsat 7 file name:  " << hdr << endl;
+         return;
+      }
+   }
+   
+   char substr[4];
+   const char* f = hdr.c_str();
+   strncpy(substr, (f+22), 3);
+   substr[3] = '\0';
+   ossimString s1 = substr;
+   ossimString s2;
+   s1.downcase();
+   if (s1 == "b80")
+   {
+      s2 = "hpn";
+   }
+   else if (s1 == "b61" || s1 == "b62")
+   {
+      s2 = "htm";
+   }
+   else if (s1 == "b10" || s1 == "b20" || s1 == "b30" ||
+            s1 == "b40" || s1 == "b50" || s1 == "b70")
+   {
+      s2 = "hrf";
+   }
+   else
+   {
+      // Not of any format we know of...
+      if (traceDebug())
+      {
+         cout << "ossimLandsatTileSource::openHeader DEBUG:"
+              << "\nCould not derive header name from:  " << file
+              << endl;
+      }
+
+      return;
+   }
+
+   // Set the case to be the same as the file passed in.
+   if (substr[0] == 0x42) // ascii "B"
+   {
+      s1.upcase();
+      s2.upcase();
+      hdr.upcase();
+
+      // Header files alway start with "L71"
+      hdr = hdr.substitute(ossimString("L72"), ossimString("L71"));  
+   }
+   else
+   {
+      // Header files alway start with "l71"
+      hdr = hdr.substitute(ossimString("l72"), ossimString("l71")); 
+   }
+
+   // Make the hdr file name.
+   hdr = hdr.substitute(s1, s2);
+
+   ossimFilename f1 = file.drive();
+   f1 += file.path();
+   hdr = f1.dirCat(hdr);
+   theFfHdr = new ossimFfL7(hdr.c_str());
+
+   if (theFfHdr->getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+      delete theFfHdr;
+      theFfHdr = NULL;
+   }
+#endif
+}
+   
+bool ossimLandsatTileSource::getImageGeometry(ossimKeywordlist& kwl,
+                                              const char* prefix)
+{
+   // Check for override for an external geometry file, or a previous save.
+   if(ossimImageHandler::getImageGeometry(kwl, prefix))
+   {
+      return true;
+   }
+   
+   if (!theFfHdr) return false;
+
+   // Make a model
+   ossimLandSatModel model(*theFfHdr);
+
+   if (model.getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+   
+      return false;
+   }
+
+   bool result = model.saveState(kwl, prefix);
+   if (result)
+   {
+      // Capture for next time...
+      setImageGeometry(kwl);
+   }
+   return result;
+}
+
+bool ossimLandsatTileSource::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   const char* lookup = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+
+   if (lookup)
+   {
+      ossimFilename fileName = lookup;
+
+      ossimString ext = fileName.ext();
+
+      if((ext.upcase() == "FST") || (ext.upcase() == "DAT"))
+      {
+         bool result =  ossimImageHandler::open(fileName);
+         ossimImageSource::loadState(kwl, prefix);
+         return result;
+      }
+   }
+      
+   return ossimGeneralRasterTileSource::loadState(kwl, prefix);
+}
+
+ossimString ossimLandsatTileSource::getShortName() const
+{
+   return ossimString("Landsat");
+}
+   
+ossimString ossimLandsatTileSource::getLongName() const
+{
+   return ossimString("Landsat reader");
+}
+
+ossimString  ossimLandsatTileSource::className() const
+{
+   return ossimString("ossimLandsatTileSource");
+}
+ 
+double ossimLandsatTileSource::getNullPixelValue(ossim_uint32)const
+{
+   return 0.0;
+}
+
+double ossimLandsatTileSource::getMinPixelValue(ossim_uint32)const
+{
+   return 1.0;
+}
+
+double ossimLandsatTileSource::getMaxPixelValue(ossim_uint32)const
+{
+   return 255.0;
+}
+
+ossimScalarType ossimLandsatTileSource::getOutputScalarType() const
+{
+   return OSSIM_UINT8;
+}
+
+bool ossimLandsatTileSource::getAcquisitionDate(ossimDate& date)const
+{
+   if(!theFfHdr) return false;
+
+   std::cout << "Date = " << theFfHdr->theAcquisitionDate << std::endl;
+   
+   ossimString y = ossimString(theFfHdr->theAcquisitionDate,
+                               theFfHdr->theAcquisitionDate+4);
+   ossimString m = ossimString(theFfHdr->theAcquisitionDate+4,
+                               theFfHdr->theAcquisitionDate+6);
+   ossimString d = ossimString(theFfHdr->theAcquisitionDate+6,
+                               theFfHdr->theAcquisitionDate+8);
+
+   date = ossimDate(m.toInt(),
+                    d.toInt(),
+                    y.toInt());
+   
+   return true;
+}
+
+ossimString ossimLandsatTileSource::getSatelliteName()const
+{
+   if(!theFfHdr) return "";
+
+   return theFfHdr->theSatName;
+}
+
+ossimFilename ossimLandsatTileSource::getBandFilename(ossim_uint32 idx)const
+{
+   ossim_uint32 maxIdx = getNumberOfInputBands();
+
+   if(!theFfHdr||(idx > maxIdx))
+   {
+      return "";
+   }
+
+   ossimFilename path = getFilename().path();
+   ossimString filename = theFfHdr->theBandFileNames[idx];
+   filename = filename.trim();
+   ossimFilename file = path.dirCat(filename);
+
+   if (file.exists())
+   {
+      return file;
+   }
+
+   // Try downcased name.
+   file = path.dirCat(filename.downcase());
+   if (file.exists())
+   {
+      return file;
+   }
+   
+   // Try upcase name.
+   file = path.dirCat(filename.upcase());
+   if (file.exists())
+   {
+      return file;
+   }
+   
+   return ossimFilename();
+}
+
+bool ossimLandsatTileSource::isPan()const
+{
+   return (getNumberOfInputBands() == 1);
+}
+
+bool ossimLandsatTileSource::isVir()const
+{
+   return (getNumberOfInputBands() == 6);
+}
+
+bool ossimLandsatTileSource::isTm()const
+{
+   return (getNumberOfInputBands() == 2);
+}
+   
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/landsat/ossimLandsatTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/landsat/ossimLandsatTileSource.h
new file mode 100644
index 0000000000..5af9e52267
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/landsat/ossimLandsatTileSource.h
@@ -0,0 +1,83 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class definition for the class "ossimLandsatTileSource".
+// ossimLandsatTileSource is derived from ImageHandler which is derived from
+// TileSource.
+//
+//*******************************************************************
+//  $Id: ossimLandsatTileSource.h,v 1.13 2005/07/25 22:49:54 dburken Exp $
+
+#ifndef ossimLandsatTileSource_HEADER
+#define ossimLandsatTileSource_HEADER
+
+#include <imaging/formats/general_raster/ossimGeneralRasterTileSource.h>
+#include <base/common/ossimDate.h>
+
+class ossimFfL7;
+
+class OSSIM_DLL ossimLandsatTileSource : public ossimGeneralRasterTileSource
+{
+public:
+   ossimLandsatTileSource();
+
+   ossimLandsatTileSource(const ossimKeywordlist& kwl,
+                           const char* prefix=0);
+   
+   virtual ~ossimLandsatTileSource();
+
+   virtual ossimString getShortName() const;
+   
+   virtual ossimString getLongName() const;
+
+   virtual ossimString  className() const;
+
+   virtual bool open();
+   
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   virtual ossimScalarType getOutputScalarType() const;
+
+   bool getAcquisitionDate(ossimDate& date)const;
+   ossimString getSatelliteName()const;
+
+   ossimFilename getBandFilename(ossim_uint32 idx)const;
+   
+   bool isPan()const;
+   bool isVir()const;
+   bool isTm()const;
+   
+  /*!
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *  Returns true if geometry info is present, false if not.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = NULL);
+   
+private:
+
+   void openHeader(const ossimFilename& file);
+   
+   ossimFfL7* theFfHdr;
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/nitf/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/.cvsignore
new file mode 100644
index 0000000000..42d2532435
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/.cvsignore
@@ -0,0 +1,2 @@
+*.d
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfTileSource.cpp
new file mode 100644
index 0000000000..091ebca0a4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfTileSource.cpp
@@ -0,0 +1,2175 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:  Contains class definition for ossimNitfTileSource.
+// 
+//*******************************************************************
+//  $Id: ossimNitfTileSource.cpp,v 1.88 2006/01/05 15:00:01 dburken Exp $
+
+#include <imaging/formats/nitf/ossimNitfTileSource.h>
+
+#include <support_data/nitf/ossimNitfPackedBits.h>
+#include <support_data/nitf/ossimNitfFile.h>
+#include <support_data/nitf/ossimNitfFileHeader.h>
+#include <support_data/nitf/ossimNitfImageHeader.h>
+#include <support_data/nitf/ossimNitfImageHeaderV2_0.h>
+#include <support_data/nitf/ossimNitfImageHeaderV2_1.h>
+#include <support_data/nitf/ossimNitfVqCompressionHeader.h>
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/misc/lookup_tables/ossimInterleaveTypeLut.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/misc/ossimEndian.h>
+#include <base/property/ossimBooleanProperty.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+RTTI_DEF1_INST(ossimNitfTileSource, "ossimNitfTileSource", ossimImageHandler)
+
+#ifdef OSSIM_ID_ENABLED
+   static const char OSSIM_ID[] = "$Id: ossimNitfTileSource.cpp,v 1.88 2006/01/05 15:00:01 dburken Exp $";
+#endif
+   
+//---
+// NOTE:  This should match the enumerations for ReadMode.
+//---
+static const char* READ_MODE[] = { "READ_MODE_UNKNOWN",
+                                   "READ_BIB_BLOCK",
+                                   "READ_BIP_BLOCK",
+                                   "READ_BIR_BLOCK",
+                                   "READ_BSQ_BLOCK",
+                                   "READ_BIB",
+                                   "READ_BIP",
+                                   "READ_BIR" };
+
+//***
+// Static trace for debugging
+//***
+static ossimTrace traceDebug("ossimNitfTileSource:debug");
+
+// 64x64*12bits
+// divide by 8 bits to get bytes gives you 6144 bytes
+static const ossim_uint32   OSSIM_NITF_VQ_BLOCKSIZE = 6144;
+
+ossimNitfTileSource::ossimNitfTileSource()
+   :
+      ossimImageHandler(),
+      theTile(NULL),
+      theCacheTile(NULL),
+      theNitfFile(new ossimNitfFile()),
+      theNitfImageHeader(0),
+      theReadMode(READ_MODE_UNKNOWN),
+      theScalarType(OSSIM_SCALAR_UNKNOWN),
+      theSwapBytesFlag(false),
+      theNumberOfInputBands(0),
+      theNumberOfOutputBands(0),
+      theBlockSizeInBytes(0),
+      theReadBlockSizeInBytes(0),
+      theNumberOfImages(0),
+      theCurrentEntry(0),
+      theImageRect(0,0,0,0),
+      theFileStr(),
+      theOutputBandList(),
+      theCacheSize(0, 0),
+      theCacheTileInterLeaveType(OSSIM_INTERLEAVE_UNKNOWN),
+      theCacheEnabledFlag(false),
+      theCacheId(-1),
+      thePackedBitsFlag(false),
+      theCompressedBuf(NULL)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::ossimNitfTileSource entered..." << endl;
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)<< "OSSIM_ID:  " << OSSIM_ID << endl;
+#endif
+   }
+
+}
+
+ossimNitfTileSource::~ossimNitfTileSource()
+{
+   destroy();
+}
+
+void ossimNitfTileSource::destroy()
+{
+   if (theCacheId != -1)
+   {
+      ossimAppFixedTileCache::instance()->deleteCache(theCacheId);
+      theCacheId = -1;
+   }
+
+   // Delete the list of image headers.
+   vector<ossimNitfImageHeader*>::iterator i = theNitfImageHeader.begin();
+   while (i != theNitfImageHeader.end())
+   {
+     if(*i)
+       {
+	 delete *i;
+	 (*i) = 0;
+       }
+      ++i;
+   }
+   theNitfImageHeader.clear();
+
+   if(theFileStr.is_open())
+   {
+      theFileStr.close();
+   }
+   if (theNitfFile)
+   {
+      delete theNitfFile;
+      theNitfFile = NULL;
+   }
+
+   theCacheTile = NULL;
+   theTile      = NULL;
+
+   if(theOverview)
+   {
+      delete theOverview;
+      theOverview = NULL;
+   }
+   if(theCompressedBuf)
+   {
+      delete [] theCompressedBuf;
+      theCompressedBuf = NULL;
+   }
+}
+
+bool ossimNitfTileSource::isOpen()const
+{
+   return (theNitfImageHeader.size() > 0);
+}
+
+bool ossimNitfTileSource::open()
+{
+   if(isOpen())
+   {
+      close();
+   }
+   
+   theErrorStatus = ossimErrorCodes::OSSIM_OK;
+
+   if ( !parseFile() )
+   {
+      return false;
+   }
+   return allocate();
+}
+
+void ossimNitfTileSource::close()
+{
+   destroy();
+}
+
+bool ossimNitfTileSource::parseFile()
+{
+   static const char MODULE[] = "ossimNitfTileSource::parseFile";
+   
+   ossimFilename file = getFilename();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " DEBUG: Nitf file =  " << file << endl;
+   }
+
+   if (file.empty())
+   {
+      setErrorStatus();
+      return false;
+   }
+
+   if ( !theNitfFile )  // A close deletes "theNitfFile".
+   {
+      theNitfFile = new ossimNitfFile();
+   }
+   
+   if ( !theNitfFile->parseFile(file) )
+   {
+      setErrorStatus();
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << "DEBUG:" << "\nError parsing file!" << endl;
+      }
+
+      return false;
+   }
+
+   // Get the number of images within the file.
+   theNumberOfImages = theNitfFile->getHeader()->getNumberOfImages();
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << "DEBUG:\nNumber of images "
+         <<theNumberOfImages << std::endl; 
+   }
+   
+   if ( theNumberOfImages == 0 )
+   {
+      setErrorStatus();
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << "DEBUG:\nNo images in file!" << endl;
+      }
+      
+      return false;
+   }
+   theEntryList.clear();
+   //---
+   // Get image header pointers.  Note there can be multiple images in one
+   // image file.
+   //---
+   for (ossim_uint32 i = 0; i < theNumberOfImages; ++i)
+   {
+      ossimNitfImageHeader* hdr = theNitfFile->getNewImageHeader(i);
+      if (!hdr)
+      {
+         setErrorStatus();
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " ERROR:\nNull image header!" << endl;
+         }
+         
+         return false;
+      }
+      if (traceDebug())
+      {
+         if(hdr)
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << MODULE << "DEBUG:"
+               << "\nImage header[" << i << "]:\n" << *hdr
+               << endl;
+         }
+      }
+      if(!hdr->isCompressed())
+      {
+         theEntryList.push_back(i);
+      }
+      else
+      {
+         if(isVqCompressed(hdr->getCompressionCode())&&
+            (hdr->getCompressionHeader().valid()))
+         {
+            // we will only support single band vq compressed NITFS
+            // basically CIB and CADRG products are single band code words.
+            //
+            if(hdr->getNumberOfBands() == 1)
+            {
+               theEntryList.push_back(i);
+            }
+            theCacheEnabledFlag = true;
+         }
+         else
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "Entry " << i
+                  <<" has an unsupported compression code = "
+                  << hdr->getCompressionCode() << std::endl;
+            }
+         }
+      }
+      theNitfImageHeader.push_back(hdr);
+   }
+   if(theEntryList.size()<1)
+   {
+      return false;
+   }
+   if(theNitfImageHeader.size() == 1)
+   {
+      theLut = theNitfImageHeader[0]->createLut(0);
+   }
+   if(theEntryList.size()>0)
+   {
+      theCurrentEntry = theEntryList[0];
+   }
+
+   theNumberOfImages = theNitfImageHeader.size();
+   
+   if (theNitfImageHeader.size() != theNumberOfImages)
+   {
+      setErrorStatus();
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE
+            << "DEBUG:\nNumber of header not equal number of images!"
+            << endl;
+      }
+      
+      return false;
+   }
+
+   // Check the current entry range.
+   if ( theCurrentEntry >= theNumberOfImages )
+   {
+      if(theEntryList.size())
+      {
+         theCurrentEntry = theEntryList[0];
+      }
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " DEBUG:"
+         << "\nCurrent entry:  " << theCurrentEntry
+         << endl;
+   }
+
+
+   // Open up a stream to the file.
+   theFileStr.open(file.c_str(), ios::in | ios::binary);
+   if (!theFileStr)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " ERROR:"
+            << "\nCannot open:  " << file.c_str() << endl;
+      }
+      return false;
+   }
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " leaving with true..." << endl;
+      
+   }
+   
+   return true;
+}
+
+bool ossimNitfTileSource::allocate()
+{
+   // Clear out the cache if there was any.
+   if (theCacheId != -1)
+   {
+      ossimAppFixedTileCache::instance()->deleteCache(theCacheId);
+      theCacheId = -1;
+   }
+
+   // Set the scalar type.
+   initializeScalarType();
+   if (theScalarType == OSSIM_SCALAR_UNKNOWN)
+   {
+      return false;
+   }
+
+   // Set the swap bytes flag.
+   initializeSwapBytesFlag();
+   
+   // Set the read mode.
+   initializeReadMode();
+   if (theReadMode == READ_MODE_UNKNOWN)
+   {
+      return false;
+   }
+   
+   // Set the number of bands.
+   initializeBandCount();
+   if (theNumberOfInputBands == 0)
+   {
+      return false;
+   }
+
+   // Initialize the image rectangle. before the cache size is done
+   //
+   initializeImageRect();
+   if (theImageRect.hasNans())
+   {
+      return false;
+   }
+   
+   // Initialize the cache size.  Must be done before
+   // setting the blocksize.  Since bit encoded data may very
+   // and we need to know if the nitf file needs to be accessed
+   // like a general raster.
+   //
+   initializeCacheSize();
+   if ( (theCacheSize.x == 0) || (theCacheSize.y == 0) )
+   {
+      return false;
+   }
+   
+   // Initialize the block size.
+   initializeBlockSize();
+   if (theBlockSizeInBytes == 0)
+   {
+      return false;
+   }
+
+
+   // Initialize the cache tile interleave type.
+   initializeCacheTileInterLeaveType();
+   if (theCacheTileInterLeaveType == OSSIM_INTERLEAVE_UNKNOWN)
+   {
+      return false;
+   }
+
+   //---
+   // Initialize the cache tile.  This will be used for a block buffer even
+   // if the cache is disabled.
+   //---
+   initializeCacheTile();
+   if (!theCacheTile.valid())
+   {
+      return false;
+   }
+
+   // Initialize the cache if enabled.
+   if (theCacheEnabledFlag)
+   {
+      theCacheId = ossimAppFixedTileCache::instance()->
+         newTileCache(theBlockImageRect, theCacheSize);
+   }
+
+   // Make the tiles.  Note the blank tile is intentionally left blank.
+   ossimImageDataFactory* idf = ossimImageDataFactory::instance();
+   theTile = idf->create(this, this);
+   theTile->initialize();
+
+   // Call base class complete open.
+   completeOpen();
+
+   return true;
+}
+
+void ossimNitfTileSource::initializeReadMode()
+{
+   // Initialize the read mode.
+   theReadMode = READ_MODE_UNKNOWN;
+   
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return;
+   }
+
+   ossim_uint32 numberOfBlocks = getNumberOfBlocks();
+   ossimString imode           = hdr->getIMode();
+   if (numberOfBlocks > 1)
+   {
+      if (imode == "B")
+      {
+         theReadMode = READ_BIB_BLOCK;
+      }
+      else if (imode == "P")
+      {
+         theReadMode = READ_BIP_BLOCK;
+      }
+      else if (imode == "R")
+      {
+         theReadMode = READ_BIR_BLOCK;
+      }
+      else if (imode == "S")
+      {
+         theReadMode = READ_BSQ_BLOCK;
+      }
+   }
+   else // The entire image comprises one block.
+   {
+      if ( (imode == "B") || (imode == "S"))
+      {
+         theReadMode = READ_BIB;
+      }
+      else if (imode == "P")
+      {
+         theReadMode = READ_BIP;
+      }
+      else if (imode == "R")
+      {
+         theReadMode = READ_BIR;
+      }
+   }        
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::initializeReadMode DEBUG:"
+         << "\nnumberOfBlocks:  " << numberOfBlocks
+         << "\nIMODE:           " << imode
+         << "\nRead Mode:       " << READ_MODE[theReadMode]
+         << endl;
+   }
+}
+
+void ossimNitfTileSource::initializeScalarType()
+{
+   thePackedBitsFlag = false;
+   // Initialize the read mode.
+   theScalarType = OSSIM_SCALAR_UNKNOWN;
+   
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return;
+   }
+
+   ossim_int32 bitsPerPixel = hdr->getActualBitsPerPixelPerBand();
+   if (bitsPerPixel < 1)
+   {
+      bitsPerPixel = hdr->getBitsPerPixelPerBand();
+   }
+
+   ossimString pixelValueType = hdr->getPixelValueType().upcase();
+   
+   switch (bitsPerPixel)
+   {
+      case 8:
+      {
+         theScalarType = OSSIM_UCHAR;
+         break;
+      }
+      case 11:
+      {
+         theScalarType = OSSIM_USHORT11;
+         break;
+      }
+      case 16:
+      {
+         if(pixelValueType == "SI")
+         {
+            theScalarType = OSSIM_SSHORT16;
+         }
+         else
+         {
+            theScalarType = OSSIM_USHORT16;
+         }
+         break;
+      }
+      case 32:
+      {
+         if(pixelValueType == "R")
+         {
+            theScalarType = OSSIM_FLOAT;
+         }
+         
+         break;
+      }
+      case 64:
+      {
+         if(pixelValueType == "R")
+         {
+            theScalarType = OSSIM_DOUBLE;
+         }
+         
+         break;
+      }
+      default:
+      {
+         if(!hdr->isCompressed())
+         {
+            thePackedBitsFlag = true;
+            if(bitsPerPixel < 8)
+            {
+               theScalarType = OSSIM_UCHAR;
+            }
+            else if(bitsPerPixel < 16)
+            {
+               theScalarType = OSSIM_USHORT16;
+            }
+            else if(bitsPerPixel < 32)
+            {
+               theScalarType = OSSIM_FLOAT;
+            }
+         }
+         break;
+      }
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::initializeScalarType DEBUG:"
+         << "\nScalar type:  "
+         << (ossimScalarTypeLut::instance()->getEntryString(theScalarType))
+         << "\nPacked bits:  " << (thePackedBitsFlag?"true":"false")
+         << endl;
+   }
+}
+
+void ossimNitfTileSource::initializeSwapBytesFlag()
+{
+   if ( (theScalarType != OSSIM_UCHAR) &&
+        (ossimGetByteOrder() == OSSIM_LITTLE_ENDIAN) )
+   {
+      theSwapBytesFlag = true;
+   }
+   else
+   {
+     theSwapBytesFlag = false;
+   }
+}
+
+void ossimNitfTileSource::initializeBandCount()
+{
+   // Initialize the read mode.
+   theNumberOfInputBands = 0;
+   theNumberOfOutputBands = 0;
+   theOutputBandList.clear();
+   
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return;
+   }
+
+   if(!isVqCompressed(hdr->getCompressionCode()))
+   {
+      theNumberOfInputBands = hdr->getNumberOfBands();
+      theNumberOfOutputBands = hdr->getNumberOfBands();
+   }
+   else 
+   {
+      theNumberOfInputBands = 1;
+      theNumberOfOutputBands = 3;
+//       const ossimRefPtr<ossimNitfCompressionHeader> header = hdr->getCompressionHeader();
+
+//       ossimNitfVqCompressionHeader* header = PTR_CAST(ossimNitfVqCompressionHeader,
+//                                                       header.get());
+
+//       if(header)
+//       {
+         
+//       }
+   }
+   
+   theOutputBandList.resize(theNumberOfOutputBands);
+   
+   for (ossim_uint32 i=0; i < theNumberOfOutputBands; ++i)
+   {
+      theOutputBandList[i] = i; // One to one for initial setup.
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::initializeBandCount DEBUG:"
+         << "\nInput Band count:  " << theNumberOfInputBands
+         << "\nOutput Band count:  " << theNumberOfOutputBands
+         << endl;
+   }
+}
+
+void ossimNitfTileSource::initializeBlockSize()
+{
+   theBlockSizeInBytes     = 0;
+   theReadBlockSizeInBytes = 0;
+   
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return;
+   }
+
+   
+                                                              
+  // This returns block size in bytes.
+  //     ossim_uint32 bytesPerPixel =
+  //        static_cast<ossim_uint32>(ceil(hdr->getBitsPerPixelPerBand()/8.0));
+
+   ossim_uint32 bytesRowCol = 0;
+   ossim_uint32 bytesRowColCacheTile = 0;
+
+   if(isVqCompressed(hdr->getCompressionCode()))
+   {
+      bytesRowCol = OSSIM_NITF_VQ_BLOCKSIZE;
+   }
+   else
+   {
+      bytesRowCol = (hdr->getNumberOfPixelsPerBlockHoriz()*
+                     hdr->getNumberOfPixelsPerBlockVert()*
+                     hdr->getBitsPerPixelPerBand()) / 8;
+   }
+   
+   bytesRowColCacheTile = (theCacheSize.x*
+                           theCacheSize.y*
+                           hdr->getBitsPerPixelPerBand())/8;
+
+#if 0
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG:"
+         << "\ncompressionHeader:  " << compressionHeader
+         << "\ngetNumberOfPixelsPerBlockHoriz():  "
+         << hdr->getNumberOfPixelsPerBlockHoriz()
+         << "\ngetNumberOfPixelsPerBlockVert():  "
+         << hdr->getNumberOfPixelsPerBlockVert()
+         << "\ngetBitsPerPixelPerBand():  "
+         << hdr->getBitsPerPixelPerBand()
+         << "\nbytesRowCol:  " << bytesRowCol
+         << "\nbytesRowColCacheTile:  " << bytesRowColCacheTile
+         << endl;
+   }
+#endif
+   
+   theBlockSizeInBytes = bytesRowCol;
+   theReadBlockSizeInBytes = theBlockSizeInBytes;
+   switch (theReadMode)
+   {
+      case READ_BSQ_BLOCK:
+      case READ_BIB_BLOCK:
+      {
+         break;
+      }
+      case READ_BIB:
+      {
+         theReadBlockSizeInBytes = bytesRowColCacheTile;
+         
+         break;
+      }
+      
+      case READ_BIP_BLOCK:
+      case READ_BIR_BLOCK:
+      {
+         theBlockSizeInBytes     *= theNumberOfInputBands;
+         theReadBlockSizeInBytes *= theNumberOfInputBands;
+         break;
+      }
+      case READ_BIP:
+      case READ_BIR:   
+      {
+         theBlockSizeInBytes *= theNumberOfInputBands;
+         theReadBlockSizeInBytes = bytesRowColCacheTile*theNumberOfInputBands;
+         break;
+      }
+      
+      default:
+      {
+         break;
+      }
+   }
+
+//#if 0
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::initializeBlockSize DEBUG:"
+         << "\nNumber of input bands:          " << theNumberOfInputBands
+         << "\nNumber of output bands:          " << theNumberOfOutputBands
+         << "\nBlock size in bytes:      " << theBlockSizeInBytes
+         << "\nRead block size in bytes: " << theReadBlockSizeInBytes
+         << endl;
+   }
+//#endif
+}
+
+void ossimNitfTileSource::initializeImageRect()
+{
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      theImageRect.makeNan();
+      return;
+   }
+
+   theBlockImageRect = hdr->getBlockImageRect();
+   theImageRect      = hdr->getImageRect();
+   theSubImageOffset = theImageRect.ul();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::initializeImageRect DEBUG:"
+         << "\nImage Rect:        " << theImageRect
+         << "\nSub image offset:  " << theSubImageOffset
+         << endl;
+   }
+}
+
+void ossimNitfTileSource::initializeCacheSize()
+{
+   theCacheSize.x = 0;
+   theCacheSize.y = 0;
+   
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return;
+   }
+   switch (theReadMode)
+   {
+      case READ_BIB_BLOCK:
+      case READ_BIP_BLOCK:
+      case READ_BIR_BLOCK:
+      case READ_BSQ_BLOCK:
+         theCacheSize.x = hdr->getNumberOfPixelsPerBlockHoriz();
+         theCacheSize.y = hdr->getNumberOfPixelsPerBlockVert();
+         break;
+
+      case READ_BIB:
+      case READ_BIP:
+      case READ_BIR:
+         theCacheSize.x = getNumberOfSamples(0);
+         theCacheSize.y = getTileHeight();
+         if(theCacheSize.y > hdr->getNumberOfPixelsPerBlockVert())
+         {
+            theCacheSize.y = hdr->getNumberOfPixelsPerBlockVert();
+         }
+         break;
+
+      default:
+         break;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::initializeCacheSize DEBUG:"
+         << "\nCache size:  " << theCacheSize
+         << endl;
+   }
+}
+void ossimNitfTileSource::initializeCacheTileInterLeaveType()
+{
+   theCacheTileInterLeaveType = OSSIM_INTERLEAVE_UNKNOWN;
+   
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return;
+   }
+
+   switch (theReadMode)
+   {
+      case READ_BIB_BLOCK:
+      case READ_BSQ_BLOCK:
+      case READ_BIB:
+         theCacheTileInterLeaveType = OSSIM_BSQ;
+         break;
+
+      case READ_BIP_BLOCK:
+      case READ_BIP:
+         theCacheTileInterLeaveType = OSSIM_BIP;
+         break;
+
+      case READ_BIR_BLOCK:
+      case READ_BIR:
+         theCacheTileInterLeaveType = OSSIM_BIL;
+         break;
+
+      default:
+         break;
+   }
+
+   if (traceDebug())
+   {
+      ossimInterleaveTypeLut lut;
+      
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::initializeCacheTileInterLeaveType DEBUG:"
+         << "\nCache tile interleave type:  "
+         << lut.getEntryString(theCacheTileInterLeaveType)
+         << endl;
+   }
+}
+
+void ossimNitfTileSource::initializeCacheTile()
+{
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return;
+   }
+
+   if(theCompressedBuf)
+   {
+      delete [] theCompressedBuf;
+      theCompressedBuf = NULL;
+   }
+   
+   ossimImageDataFactory* idf = ossimImageDataFactory::instance();
+   theCacheTile = idf->create(this,
+                              theScalarType,
+                              theNumberOfOutputBands,
+                              theCacheSize.x,
+                              theCacheSize.y);
+   theCacheTile->initialize();
+
+   if(hdr->getRepresentation().upcase().contains("LUT"))
+   {
+      theCompressedBuf = new ossim_uint8[theReadBlockSizeInBytes];
+      memset(theCompressedBuf, '\0', theReadBlockSizeInBytes);
+   }
+   else if(isVqCompressed(hdr->getCompressionCode()))
+   {
+      theCompressedBuf = new ossim_uint8[theReadBlockSizeInBytes];
+      memset(theCompressedBuf, '\0', theReadBlockSizeInBytes);
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimNitfTileSource::getTile(
+   const  ossimIrect& tileRect, ossim_uint32 resLevel)
+{
+   // This tile source bypassed, or invalid res level, return a blank tile.
+   if(!isSourceEnabled() || !isOpen() || !isValidRLevel(resLevel))
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   if (theOverview)
+   {
+      if (theOverview->hasR0() || resLevel)
+      {
+         // Subtract any offsets since the overview doesn't know about them.
+         ossimIrect rr_rect = tileRect - getSubImageOffset(resLevel);
+
+         //---
+         // If there is a sub image offset then we will not be requesting
+         // the same rectangle as was requested from us.  For this reason,
+         // we'll do a setOrigin, rather than just returning the getTile
+         // result.
+         //---
+         ossimRefPtr<ossimImageData> tileData = theOverview->getTile(rr_rect,
+                                                                     resLevel);
+         if(tileData.valid())
+         {
+            tileData->setImageRectangle(tileRect);
+         }
+         
+         if(getOutputScalarType() == OSSIM_USHORT11)
+         {
+            //---
+            // Temp fix:
+            // The overview handler could return a tile of OSSIM_UINT16 if
+            // the max sample value was not set to 2047.  
+            //---
+            tileData->setScalarType(OSSIM_USHORT11);
+         }
+         
+         return tileData;
+      }
+   }
+
+   if (!theTile.valid())
+   {
+      return theTile;
+   }
+   
+   theTile->setImageRectangle(tileRect);
+
+   ossimIrect  cacheRect  = theCacheTile->getImageRectangle();
+   
+   //---
+   // See if any point of the requested tile is in the image.
+   //---
+   if ( tileRect.intersects(theBlockImageRect) )
+   {
+      ossimIrect clipRect = tileRect.clipToRect(theImageRect);
+
+      //---
+      // See if the whole tile is going to be filled, if not, start out with
+      // a blank tile so data from a previous load gets wiped out.
+      //---
+      if ( !tileRect.completely_within(clipRect) )
+      {
+         // Start with a blank tile.
+         if (theTile->getDataObjectStatus() != OSSIM_EMPTY)
+         {
+            theTile->makeBlank();
+         }
+      }
+            
+      // See if the requested clip rect is already in the cache tile.
+      bool status = true;
+      if ( (clipRect.completely_within(theCacheTile->getImageRectangle()))&&
+           (theCacheTile->getDataObjectStatus() != OSSIM_EMPTY)&&
+           (theCacheTile->getBuf()))
+      {
+         theTile->loadTile(theCacheTile->getBuf(),
+                           theCacheTile->getImageRectangle(),
+                           theCacheTileInterLeaveType);
+      }
+      else
+      {
+         
+         status = loadTile(clipRect);
+      }
+
+      if (status)
+      {
+         //---
+         // Validate the tile.  This will set the status to full, partial
+         // or empty.  Must be performed if any type of combining is to be
+         // performed down the chain.
+         //---
+         theTile->validate();
+         return theTile;
+      }
+
+   } // End of if ( tileRect.intersects(image_rect) )
+
+   // No part of requested tile within the image rectangle or loadTile failed.
+   return ossimRefPtr<ossimImageData>();   
+}
+
+bool ossimNitfTileSource::loadTile(const ossimIrect& clipRect)
+{
+   // Subtract any offsets and work in zero based image space.
+   ossimIrect zbClipRect  = clipRect - theSubImageOffset;
+
+   const ossim_uint32 BLOCK_HEIGHT = theCacheSize.y;
+   const ossim_uint32 BLOCK_WIDTH  = theCacheSize.x;
+
+   zbClipRect.stretchToTileBoundary(ossimIpt(BLOCK_WIDTH, BLOCK_HEIGHT));
+   
+   //---
+   // Shift the upper left corner of the "clip_rect" to the an even nitf
+   // block boundry.  
+   //---
+   ossimIpt nitfBlockOrigin = zbClipRect.ul();
+//   adjustToStartOfBlock(nitfBlockOrigin, BLOCK_HEIGHT, BLOCK_WIDTH);
+   
+   // Vertical block loop.
+   ossim_int32 y = nitfBlockOrigin.y;
+   while (y < zbClipRect.lr().y)
+   {
+      // Horizontal block loop.
+      ossim_int32 x = nitfBlockOrigin.x;
+      while (x < zbClipRect.lr().x)
+      {
+         if (loadBlock(x, y))
+         {
+            theTile->loadTile(theCacheTile->getBuf(),
+                              theCacheTile->getImageRectangle(),
+                              theCacheTileInterLeaveType);
+         }
+         else
+         {
+            // Error loading...
+            return false;
+         }
+         
+         x += BLOCK_WIDTH; // Go to next block.
+      }
+      
+      y += BLOCK_HEIGHT; // Go to next row of blocks.
+   }
+
+   return true;
+}
+
+bool ossimNitfTileSource::loadBlock(ossim_uint32 x, ossim_uint32 y)
+{
+#if 0
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::loadBlock DEBUG:"
+         << "  x:  " << x << " y:  " << y << endl;
+   }
+#endif
+   
+   //---
+   // The origin set in the cache tile must have the sub image offset in it
+   // since "theTile" is relative to any sub image offset.  This is so that
+   // "theTile->loadTile(theCacheTile)" will work.
+   //---
+   ossimIpt origin(x, y);
+   origin = origin + theSubImageOffset;
+   
+   if (theCacheEnabledFlag)
+   {
+      // See if it's in the cache already.
+      ossimRefPtr<ossimImageData> tempTile = NULL;
+      tempTile = ossimAppFixedTileCache::instance()->
+         getTile(theCacheId, origin);
+      if (tempTile.valid())
+      {
+         theTile->loadTile(tempTile.get());
+         return true;
+      }
+   }
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   theCacheTile->setOrigin(origin);
+   ossim_uint32 readSize = theReadBlockSizeInBytes;
+   if(!theCacheTile->getImageRectangle().completely_within(theBlockImageRect))
+   {
+      readSize = getPartialReadSize(origin);
+   }
+   if((hdr->hasBlockMaskRecords())||
+      (readSize != theReadBlockSizeInBytes))
+   {
+      theCacheTile->makeBlank();
+   }
+
+   switch (theReadMode)
+   {
+      case READ_BIR:  
+      case READ_BIR_BLOCK:
+      case READ_BIP:  
+      case READ_BIP_BLOCK:
+      {
+         std::streampos p;
+         if(getPosition(p, x, y, 0))
+         {
+            theFileStr.seekg(p, ios::beg);
+            char* buf = (char*)(theCacheTile->getBuf());
+            if (!theFileStr.read(buf, readSize))
+            {
+               theFileStr.clear();
+               ossimNotify(ossimNotifyLevel_FATAL)
+                  << "ossimNitfTileSource::loadBlock BIP Read Error!"
+                  << "\nReturning error..." << endl;
+               theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+               
+               return false;
+            }
+         }
+         break;
+      }
+      case READ_BSQ_BLOCK:
+      case READ_BIB_BLOCK:
+      case READ_BIB:
+      {
+         //---
+         // NOTE:
+         // With some of these types we could do one read and get all bands.
+         // The reads are done per for future enabling on band selection
+         // at the image handler level.
+         //---
+         for (ossim_uint32 band = 0; band < theNumberOfInputBands; ++band)
+         {
+            ossim_uint8* buf =0;
+            if(isVqCompressed(hdr->getCompressionCode())||
+               hdr->getRepresentation().upcase().contains("LUT"))
+            {
+               buf = theCompressedBuf;
+            }
+            else
+            {
+               buf = (ossim_uint8*)(theCacheTile->getBuf(band));
+            }
+            std::streampos p;
+            if(getPosition(p, x, y, band))
+            {
+               theFileStr.seekg(p, ios::beg);
+               if (!theFileStr.read((char*)buf, readSize))
+               {
+                  theFileStr.clear();
+                  ossimNotify(ossimNotifyLevel_FATAL)
+                     << "ossimNitfTileSource::loadBlock Read Error!"
+                     << "\nReturning error..." << endl;
+                  theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+                  return false;
+               }
+               else if(isVqCompressed(hdr->getCompressionCode()))
+               {
+                  vqUncompress(theCacheTile, theCompressedBuf);
+               }
+               else if(hdr->getRepresentation().upcase().contains("LUT"))
+               {
+                  lutUncompress(theCacheTile, theCompressedBuf);
+               }
+            }
+         }
+         break;
+      }
+
+      default:
+         break;
+   }
+   
+   if(thePackedBitsFlag)
+   {
+      explodePackedBits(theCacheTile);
+   }
+   // Check for swap bytes.
+   if (theSwapBytesFlag)
+   {
+      ossimEndian swapper;
+      swapper.swap(theScalarType,
+                   theCacheTile->getBuf(),
+                   theCacheTile->getSize());
+   }
+   convertTransparentToNull(theCacheTile);
+
+   // Set the origin of the cache tile.
+   theCacheTile->validate();
+   if (theCacheEnabledFlag)
+   {
+      // Add it to the cache for the next time.
+      ossimAppFixedTileCache::instance()->addTile(theCacheId, theCacheTile);
+   }
+   
+   return true;
+}
+
+void ossimNitfTileSource::explodePackedBits(ossimRefPtr<ossimImageData> packedBuffer)const
+{
+   ossim_uint8* tempBuf = new ossim_uint8[packedBuffer->getSizePerBandInBytes()];
+   ossim_uint32 idx      = 0;
+   ossim_uint32 bandIdx  = 0;
+   ossim_uint32 h = packedBuffer->getHeight();
+   ossim_uint32 w = packedBuffer->getWidth();
+   ossim_uint32 maxIdx = w*h;
+   ossim_uint32 bandCount = packedBuffer->getNumberOfBands();
+   switch(packedBuffer->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         
+         ossim_uint8* outputBuf = (ossim_uint8*)tempBuf;
+         for(bandIdx = 0; bandIdx < bandCount; ++bandIdx)
+         {
+            ossimNitfPackedBits packedBits((ossim_uint8*)packedBuffer->getBuf(bandIdx),
+                                           getCurrentImageHeader()->getBitsPerPixelPerBand());
+            for(idx = 0; idx < maxIdx; ++idx)
+            {
+               *outputBuf = (ossim_uint8)packedBits.getValueAsUint32(idx);
+               ++outputBuf;
+            }
+            
+            memcpy((char*)packedBuffer->getBuf(bandIdx),
+                   (char*)tempBuf,
+                   theCacheTile->getSizePerBandInBytes()*bandCount);
+         }
+         break;
+      }
+      case OSSIM_USHORT16:
+      {
+         
+         ossim_uint16* outputBuf = (ossim_uint16*)tempBuf;
+         for(bandIdx = 0; bandIdx < bandCount; ++bandIdx)
+         {
+            ossimNitfPackedBits packedBits((ossim_uint8*)packedBuffer->getBuf(bandIdx),
+                                           getCurrentImageHeader()->getBitsPerPixelPerBand());
+            for(idx = 0; idx < maxIdx; ++idx)
+            {
+               *outputBuf = (ossim_uint16)packedBits.getValueAsUint32(idx);
+               ++outputBuf;
+            }
+            
+            memcpy((char*)packedBuffer->getBuf(bandIdx),
+                   (char*)tempBuf,
+                   theCacheTile->getSizePerBandInBytes()*bandCount);
+         }
+         break;
+      }
+      case OSSIM_FLOAT:
+      {
+         ossim_float32* outputBuf = (ossim_float32*)tempBuf;
+         for(bandIdx = 0; bandIdx < bandCount; ++bandIdx)
+         {
+            ossimNitfPackedBits packedBits((ossim_uint8*)packedBuffer->getBuf(bandIdx),
+                                           getCurrentImageHeader()->getBitsPerPixelPerBand());
+            for(idx = 0; idx < maxIdx; ++idx)
+            {
+               *outputBuf = (ossim_float32)packedBits.getValueAsUint32(idx);
+               ++outputBuf;
+            }
+            
+            memcpy((char*)packedBuffer->getBuf(bandIdx),
+                   (char*)tempBuf,
+                   theCacheTile->getSizePerBandInBytes()*bandCount);
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   delete [] tempBuf;
+}
+
+void ossimNitfTileSource::convertTransparentToNull(ossimRefPtr<ossimImageData> tile)const
+{
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+
+   if(!hdr||!tile) return;
+
+   if(!tile->getBuf()) return;
+   ossimIpt tempOrigin = tile->getOrigin()-theSubImageOffset;
+   ossim_uint32 blockNumber = getBlockNumber(tempOrigin);
+   ossim_uint32 numberOfBands = tile->getNumberOfBands();
+   ossim_uint32 band = 0;
+   if(hdr->hasPadPixelMaskRecords())
+   {
+      if(hdr->hasTransparentCode())
+      {
+         ossim_uint32 idx = 0;
+         ossim_uint32 maxIdx = tile->getWidth()*tile->getHeight();
+         
+         for (band = 0; band < numberOfBands; ++band)
+         {
+            if(hdr->getPadPixelMaskRecordOffset(blockNumber,
+                                                band)!=0xffffffff)
+            {
+               switch(tile->getScalarType())
+               {
+                  case OSSIM_UCHAR:
+                  {
+                     ossim_uint8 transparentValue = hdr->getTransparentCode();
+                     ossim_uint8* buf = (ossim_uint8*)tile->getBuf(band);
+                     ossim_uint8 nullPix = (ossim_uint8)tile->getNullPix(band);
+                     for(idx = 0; idx < maxIdx; ++idx)
+                     {
+                        if(*buf == transparentValue)
+                        {
+                           *buf = nullPix;
+                        }
+                        ++buf;
+                     }
+                     break;
+                  }
+                  case OSSIM_USHORT11:
+                  case OSSIM_USHORT16:
+                  {
+                     ossim_uint16 transparentValue = hdr->getTransparentCode();
+                     ossim_uint16* buf = (ossim_uint16*)tile->getBuf(band);
+                     ossim_uint16 nullPix = (ossim_uint16)tile->getNullPix(band);
+                     for(idx = 0; idx < maxIdx; ++idx)
+                     {
+                        if(*buf == transparentValue)
+                        {
+                           *buf = nullPix;
+                        }
+                        ++buf;
+                     }
+                     break;
+                  }
+                  case OSSIM_SSHORT16:
+                  {
+                     ossim_sint16 transparentValue = hdr->getTransparentCode();
+                     ossim_sint16* buf = (ossim_sint16*)tile->getBuf(band);
+                     ossim_sint16 nullPix = (ossim_sint16)tile->getNullPix(band);
+                     for(idx = 0; idx < maxIdx; ++idx)
+                     {
+                        if(*buf == transparentValue)
+                        {
+                           *buf = nullPix;
+                        }
+                        ++buf;
+                     }
+                     break;
+                  }
+				  default:
+				  {
+					  break;
+				  }
+               }
+            }
+         }
+      }
+   }
+}
+
+
+double ossimNitfTileSource::getMinPixelValue(ossim_uint32 band)const
+{
+   double result = ossimImageHandler::getMinPixelValue(band);
+
+   if(thePackedBitsFlag)
+   {
+      if(result < 1.0) result = 1.0;
+   }
+   
+   return result;
+}
+
+double ossimNitfTileSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   double result = ossimImageHandler::getMaxPixelValue(band);
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+
+   if(hdr)
+   {
+      if(thePackedBitsFlag)
+      {
+         double test = 1<<(hdr->getBitsPerPixelPerBand());
+         
+         if(result > test) result = test;
+      }
+   }
+
+   return result;
+}
+
+double ossimNitfTileSource::getNullPixelValue(ossim_uint32 band)const
+{
+   double result = ossimImageHandler::getNullPixelValue(band);
+
+   if(thePackedBitsFlag)
+   {
+      if((result < 0) ||
+         (result > getMaxPixelValue(band)))
+         {
+            result = 0.0;
+         }
+   }
+
+
+   return result;
+}
+
+
+bool ossimNitfTileSource::getPosition(std::streampos& streamPosition,
+                                      ossim_uint32 x,
+                                      ossim_uint32 y,
+                                      ossim_uint32 band) const
+{
+   //
+   // NOTE:  "theCacheSize is always relative to a block size except in
+   // the case where a block is the entire image.
+   //
+   streamPosition = 0;
+   
+   
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return streamPosition;
+   }
+
+   ossim_uint32 blockNumber = getBlockNumber(ossimIpt(x,y));
+
+#if 0
+   cout << "ossimNitfTileSource::getPosition blockNumber:  "
+        << blockNumber << endl;
+#endif
+   
+   streamPosition = hdr->getDataLocation(); // Position to first block.
+   if(hdr->hasBlockMaskRecords())
+   {
+      ossim_uint32 blockOffset = hdr->getBlockMaskRecordOffset(blockNumber,
+                                                               band);
+      if(blockOffset == 0xffffffff)
+      {
+         return false;
+      }
+      streamPosition += blockOffset;
+   }
+   
+   switch (theReadMode)
+   {
+      case READ_BIB_BLOCK:
+      {
+         if(!hdr->hasBlockMaskRecords())
+         {
+            streamPosition +=
+               (blockNumber * getBlockOffset()) +
+               (getBandOffset() * band);
+         }
+         else
+         {
+            streamPosition += (getBandOffset() * band);
+            
+         }
+         break;
+      }
+   
+      case READ_BIB:
+      {
+         streamPosition +=
+            (blockNumber * theReadBlockSizeInBytes)+
+            (getBandOffset() * band);
+         break;
+      }
+
+      case READ_BSQ_BLOCK:
+      {
+         
+         if(!hdr->hasBlockMaskRecords())
+         {
+            streamPosition += (blockNumber * getBlockOffset()) +
+               (getBandOffset() * band);
+         }
+         
+         break;
+      }
+      default:
+      {
+         if(!hdr->hasBlockMaskRecords())
+         {
+            streamPosition += (blockNumber*getBlockOffset());
+         }
+         
+         break;
+      }
+   }
+
+   return true;
+}
+
+std::streampos ossimNitfTileSource::getBandOffset() const
+{
+   std::streampos bandOffset = 0;
+
+   switch (theReadMode)
+   {
+      case READ_BIB_BLOCK:
+      case READ_BIP_BLOCK:
+      case READ_BIR_BLOCK:
+      case READ_BIB:
+      case READ_BIP:
+      case READ_BIR:
+         bandOffset = theBlockSizeInBytes;
+         break;
+         
+      case READ_BSQ_BLOCK:
+         bandOffset = getNumberOfBlocks() * theBlockSizeInBytes;
+         break;
+
+      default:
+         break;
+   }
+
+   return bandOffset;
+}
+
+std::streampos ossimNitfTileSource::getBlockOffset() const
+{
+   std::streampos blockOffset = 0;
+   std::streampos blockSizeInBytes = 0;
+   if (getNumberOfBlocks() == 1)
+   {
+      blockSizeInBytes = theReadBlockSizeInBytes;
+   }
+   else
+   {
+      blockSizeInBytes = theBlockSizeInBytes;
+   }
+   
+   switch (theReadMode)
+   {
+      case READ_BIB_BLOCK:
+      case READ_BIB:
+         // Band interleaved by block.
+         blockOffset = blockSizeInBytes * theNumberOfInputBands;
+         break;
+         
+      case READ_BIR_BLOCK:
+      case READ_BSQ_BLOCK:
+      case READ_BIP_BLOCK:
+      case READ_BIP:
+      case READ_BIR:
+         // Blocks side by side.
+         blockOffset = blockSizeInBytes;
+         break;
+      
+      default:
+         break;
+   }
+
+   return blockOffset;
+}
+   
+ossim_uint32 ossimNitfTileSource::getNumberOfBlocks() const
+{
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return 0;
+   }
+
+   return static_cast<ossim_uint32>( hdr->getNumberOfBlocksPerRow() *
+                                     hdr->getNumberOfBlocksPerCol() );
+}
+
+bool ossimNitfTileSource::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   if ( !ossimImageHandler::loadState(kwl, prefix) )
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfTileSource::loadState(kwl, prefix) DEBUG:"
+            << "\nUnable to load, exiting..." << std::endl;
+      }
+      return false;
+   }
+   
+   const char* lookup = kwl.find(prefix, "entry");
+   if (lookup)
+   {
+      ossimString s(lookup);
+      theCurrentEntry = s.toUInt32();
+   }
+
+   lookup = kwl.find(prefix,ossimKeywordNames::ENABLE_CACHE_KW);
+   if (lookup)
+   {
+      ossimString s(lookup);
+      theCacheEnabledFlag = s.toBool();
+   }
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfTileSource::loadState(kwl, prefix) DEBUG:"
+         << "\nCurrent entry:      " << theCurrentEntry
+         << "\nCache enable flag:  " << theCacheEnabledFlag
+         << std::endl;
+   }
+   
+   return open();
+}
+
+bool ossimNitfTileSource::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix) const
+{
+   // Add the entry number.
+   kwl.add(prefix, "entry", theCurrentEntry, true);
+
+   // Add the cache_enable flag.
+   kwl.add(prefix, ossimKeywordNames::ENABLE_CACHE_KW, theCacheEnabledFlag, true);
+
+   // Call the base class save state.
+   return ossimImageHandler::saveState(kwl, prefix);
+}
+
+ossimScalarType ossimNitfTileSource::getOutputScalarType() const
+{
+   return theScalarType;
+}
+
+ossim_uint32 ossimNitfTileSource::getTileWidth() const
+{
+   if (theTile.valid())
+   {
+      return theTile->getWidth();
+   }
+
+   ossimIpt tileSize;
+   ossimGetDefaultTileSize(tileSize);
+   return static_cast<ossim_uint32>(tileSize.x);
+}
+
+ossim_uint32 ossimNitfTileSource::getTileHeight() const
+{
+   if (theTile.valid())
+   {
+      return theTile->getHeight();
+   }
+
+   ossimIpt tileSize;
+   ossimGetDefaultTileSize(tileSize);
+   return static_cast<ossim_uint32>(tileSize.y);
+}
+
+ossim_uint32 ossimNitfTileSource::getNumberOfInputBands() const
+{
+   return theNumberOfInputBands;
+}
+
+ossim_uint32 ossimNitfTileSource::getNumberOfOutputBands() const
+{
+   return theNumberOfOutputBands;
+}
+
+ossim_uint32 ossimNitfTileSource::getNumberOfLines(ossim_uint32 resLevel) const
+{
+   if (resLevel == 0)
+   {
+      const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+      if (!hdr)
+      {
+         return 0;
+      }
+      return  hdr->getNumberOfRows();
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfLines(resLevel);
+   }
+   return 0;
+}
+
+ossim_uint32 ossimNitfTileSource::getNumberOfSamples(ossim_uint32 resLevel) const
+{
+   if (resLevel == 0)
+   {
+      const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+      if (!hdr)
+      {
+         return 0;
+      }
+      return  hdr->getNumberOfCols();
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfSamples(resLevel);
+   }
+   return 0;
+}
+
+void ossimNitfTileSource::adjustToStartOfBlock(ossimIpt& pt,
+                                               ossim_int32 tile_height,
+                                               ossim_int32 tile_width) const
+{
+   if (pt.x > 0)
+   {
+      pt.x = pt.x/tile_width*tile_width;
+   }
+   else if (pt.x < 0)
+   {
+      pt.x = (pt.x-tile_width)/tile_width*tile_width;
+   }
+
+   if (pt.y > 0)
+   {
+      pt.y = pt.y/tile_height*tile_height;
+   }
+   else if (pt.y < 0)
+   {
+      pt.y = (pt.y-tile_height)/tile_height*tile_height;
+   }
+}
+
+ossim_uint32 ossimNitfTileSource::getBlockNumber(const ossimIpt& block_origin) const
+{
+   ossim_uint32 blockNumber = 0;
+   
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return blockNumber;
+   }
+
+   ossim_uint32 blockY;
+   ossim_uint32 blockX;
+   blockX  = (block_origin.x /
+              theCacheSize.x);
+   blockY= (block_origin.y /
+            theCacheSize.y);
+
+   switch (theReadMode)
+   {
+      case READ_BIB_BLOCK:
+      case READ_BIP_BLOCK:
+      case READ_BIR_BLOCK:
+      case READ_BSQ_BLOCK:
+         
+         blockNumber = ((blockY*hdr->getNumberOfBlocksPerRow()) +
+                        blockX);
+         break;
+      case READ_BIB:
+      case READ_BIP:
+      case READ_BIR:
+         //---
+         // These read modes are for a single block image.  The cache size will
+         // be set to the width of the image (block) by the height of one tile.
+         //
+         // This is to avoid reading an entire large image with a single block
+         // into memory.
+         //---
+         blockNumber = blockY;
+         break;
+
+      default:
+         break;
+   }
+   return blockNumber;
+}
+
+ossim_uint32 ossimNitfTileSource::getPartialReadSize(const ossimIpt& blockOrigin)const
+{
+   ossim_uint32 result = 0;
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return result;
+   }
+   
+   if(theCacheTile->getImageRectangle().completely_within(theBlockImageRect))
+   {
+      return theReadBlockSizeInBytes;
+   }
+   ossimIrect clipRect = theCacheTile->getImageRectangle().clipToRect(theBlockImageRect);
+   
+   result = (theCacheSize.x*
+             clipRect.height()*
+             hdr->getBitsPerPixelPerBand())/8;
+   
+   switch (theReadMode)
+   {
+      case READ_BSQ_BLOCK:
+      case READ_BIB_BLOCK:
+      case READ_BIB:
+      {
+         // purposely left blank.  only hear for clarity.
+         break;
+      }
+
+      case READ_BIP_BLOCK:
+      case READ_BIR_BLOCK:
+      case READ_BIP:
+      case READ_BIR:   
+      {
+         result *= theNumberOfInputBands;
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   return result;
+}
+
+bool ossimNitfTileSource::isVqCompressed(const ossimString& compressionCode)const
+{
+   return((compressionCode == "C4")||
+          (compressionCode == "M4"));
+}
+
+
+ossim_uint32 ossimNitfTileSource::getImageTileWidth() const
+{
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return 0;
+   }
+   return hdr->getNumberOfPixelsPerBlockHoriz();
+}
+
+ossim_uint32 ossimNitfTileSource::getImageTileHeight() const
+{
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr)
+   {
+      return 0;
+   }
+   return hdr->getNumberOfPixelsPerBlockVert();
+}
+
+ossimString ossimNitfTileSource::getShortName()const
+{
+   return ossimString("nitf");
+}
+
+ossimString ossimNitfTileSource::getLongName()const
+{
+   return ossimString("nitf reader");
+}
+
+ossimString ossimNitfTileSource::className()const
+{
+   return ossimString("ossimNitfTileSource");
+}
+
+ossim_uint32 ossimNitfTileSource::getCurrentEntry() const
+{
+   return theCurrentEntry;
+}
+
+ossim_uint32 ossimNitfTileSource::getNumberOfEntries() const
+{
+   return theEntryList.size();
+}
+
+void ossimNitfTileSource::getEntryList(std::vector<ossim_uint32>& entryList)const
+{
+   entryList = theEntryList;
+//    entryList.resize(theNumberOfImages);
+//    for (ossim_uint32 i = 0; i < theNumberOfImages; ++i)
+//    {
+//       entryList[i] = i;
+//    }
+}
+
+bool ossimNitfTileSource::setCurrentEntry(ossim_uint32 entryIdx)
+{
+   if (theCurrentEntry == entryIdx)
+   {
+      return true; // Nothing to change.
+   }
+
+   if ( isOpen() )
+   {
+      if ( entryIdx < theNumberOfImages )
+      {
+         theCurrentEntry = entryIdx;
+         //---
+         // Since we were previously open and the the entry has changed we
+         // need to reinitialize some things.
+         //---
+         allocate();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      //---
+      // Not open.
+      // Allow this know that the parseFile will check for out of range.
+      //---
+      theCurrentEntry = entryIdx;
+   }
+
+   return true;
+}
+
+bool ossimNitfTileSource::getCacheEnabledFlag() const
+{
+   return theCacheEnabledFlag;
+}
+
+void ossimNitfTileSource::setCacheEnabledFlag(bool flag)
+{
+   if (flag != theCacheEnabledFlag)
+   {
+      // State of caching has changed...
+
+      theCacheEnabledFlag = flag;
+
+      if ( theCacheEnabledFlag) // Cache enabled.
+      {
+         theCacheId = ossimAppFixedTileCache::instance()->
+            newTileCache(theBlockImageRect, theCacheSize);
+      }
+      else // Cache disabled...
+      {
+         // Clean out the cache if there was one.
+         if (theCacheId != -1)
+         {
+            ossimAppFixedTileCache::instance()->deleteCache(theCacheId);
+            theCacheId = -1;
+         }
+      }
+   }
+}
+
+const ossimNitfImageHeader* ossimNitfTileSource::getCurrentImageHeader() const
+{
+   return theNitfImageHeader[theCurrentEntry];
+}
+
+void ossimNitfTileSource::setBoundingRectangle(const ossimIrect& imageRect)
+{
+   theImageRect = imageRect;
+   theSubImageOffset = theImageRect.ul();
+   
+   // now shift the internal block rect as well
+   theBlockImageRect = (theBlockImageRect - theBlockImageRect.ul()) + theSubImageOffset;
+}
+
+ossimRefPtr<ossimProperty> ossimNitfTileSource::getProperty(const ossimString& name)const
+{
+   if (name == ossimKeywordNames::ENABLE_CACHE_KW)
+   {
+      ossimProperty* p = new ossimBooleanProperty(name, theCacheEnabledFlag);
+      return ossimRefPtr<ossimProperty>(p);
+   }
+
+   return ossimImageHandler::getProperty(name);
+}
+
+void ossimNitfTileSource::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if (!property) return;
+   
+   ossimString name = property->getName();
+
+   if (name == ossimKeywordNames::ENABLE_CACHE_KW)
+   {
+      ossimBooleanProperty* obj = PTR_CAST(ossimBooleanProperty,
+                                           property.get());
+      if (obj)
+      {
+         setCacheEnabledFlag(obj->getBoolean());
+      }
+   }
+   else
+   {
+      ossimImageHandler::setProperty(property);
+   }
+}
+
+void ossimNitfTileSource::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   propertyNames.push_back(ossimKeywordNames::ENABLE_CACHE_KW);
+
+   ossimImageHandler::getPropertyNames(propertyNames);
+}
+
+ossimString ossimNitfTileSource::getSecurityClassification() const
+{
+   if(getCurrentImageHeader())
+   {
+      return getCurrentImageHeader()->getSecurityClassification();
+   }
+   
+   return "U";
+}
+
+void ossimNitfTileSource::lutUncompress(ossimRefPtr<ossimImageData> destination, ossim_uint8* source)
+{
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr||!destination)
+   {
+      return;
+   }
+   if((destination->getNumberOfBands()<3)||
+      (!destination->getBuf())||
+      (destination->getScalarType()!=OSSIM_UCHAR)||
+      (!theLut.valid()))
+   {
+      return;
+   }
+
+   if(destination->getNumberOfBands()!=theLut->getNumberOfBands())
+   {
+      return;
+   }
+   
+   ossim_uint8* tempRows[3];
+   tempRows[0] = (ossim_uint8*)destination->getBuf(0);
+   tempRows[1] = (ossim_uint8*)destination->getBuf(1);
+   tempRows[2] = (ossim_uint8*)destination->getBuf(2);
+   
+   ossim_uint8* srcPtr = source;
+   ossim_uint32 compressionYidx   = 0;
+   ossim_uint32 compressionXidx   = 0;
+   ossim_uint32 uncompressIdx     = 0;
+   ossim_uint32 h = destination->getHeight();
+   ossim_uint32 w = destination->getWidth();
+   
+   for(compressionYidx = 0; compressionYidx < h; ++compressionYidx)
+   {
+      for(compressionXidx = 0; compressionXidx < w; ++compressionXidx)
+      {
+         tempRows[0][uncompressIdx] = (*theLut)[*srcPtr][0];
+         tempRows[1][uncompressIdx] = (*theLut)[*srcPtr][1];
+         tempRows[2][uncompressIdx] = (*theLut)[*srcPtr][2];
+         ++srcPtr;
+         ++uncompressIdx;
+      }
+   }
+}
+
+void ossimNitfTileSource::vqUncompress(ossimRefPtr<ossimImageData> destination, ossim_uint8* source)
+{
+   const ossimNitfImageHeader* hdr = getCurrentImageHeader();
+   if (!hdr||!destination)
+   {
+      return;
+   }
+   if((destination->getNumberOfBands()<3)||
+      (!destination->getBuf())||
+      (destination->getScalarType()!=OSSIM_UCHAR))
+   {
+      return;
+   }
+   ossimNitfVqCompressionHeader* compressionHeader = PTR_CAST(ossimNitfVqCompressionHeader,
+                                                              hdr->getCompressionHeader().get());
+
+   if(!compressionHeader)
+   {
+      return;
+   }
+   const std::vector<ossimNitfVqCompressionOffsetTableData>& table = compressionHeader->getTable();
+   ossimRefPtr<ossimNitfImageBand> bandInfo = hdr->getBandInformation(0);
+
+//    if(!bandInfo.valid()) return;
+
+//    if(!theLut.valid()) return;
+//    if(theLut->getNumberOfBands() != 3) return;
+   std::vector<ossimRefPtr<ossimNitfImageLut> > luts(destination->getNumberOfBands());
+
+   if(bandInfo->getNumberOfLuts() == 1)
+   {
+      luts[0] = bandInfo->getLut(0);
+      luts[1] = bandInfo->getLut(0);
+      luts[2] = bandInfo->getLut(0);
+   }
+   else
+   {
+      luts[0] = bandInfo->getLut(0);
+      luts[1] = bandInfo->getLut(1);
+      luts[2] = bandInfo->getLut(2);
+   }
+
+   if(!luts[0].valid()||
+      !luts[1].valid()||
+      !luts[2].valid())
+   {
+      return;
+   }
+   ossim_uint8* tempRows[3];
+   tempRows[0] = (ossim_uint8*)destination->getBuf(0);
+   tempRows[1] = (ossim_uint8*)destination->getBuf(1);
+   tempRows[2] = (ossim_uint8*)destination->getBuf(2);
+   
+   ossim_uint32 destWidth  = destination->getWidth();
+   ossimNitfPackedBits bits(source,
+                            compressionHeader->getImageCodeBitLength());
+//    ossimNitfPackedBits bits(source,
+//                             12); // vq is 12 bits
+
+   ossim_uint32 compressionYidx   = 0;
+   ossim_uint32 compressionXidx   = 0;
+   ossim_uint32 compressionIdx    = 0;
+   ossim_uint32 uncompressIdx     = 0;
+   ossim_uint32 uncompressYidx    = 0;
+   ossim_uint32 rows   = table.size();
+   ossim_uint32 cols   = 0;
+   ossim_uint32 rowIdx = 0;
+   ossim_uint32 colIdx = 0;
+   if(rows)
+   {
+      cols = table[0].theNumberOfValuesPerCompressionLookup;
+   }
+   ossim_uint32 compressionHeight = compressionHeader->getNumberOfImageRows();
+   ossim_uint32 compressionWidth  = compressionHeader->getNumberOfImageCodesPerRow();
+   ossim_uint8 lutValue = 0;
+   ossim_uint8* data=0;
+   
+   for(compressionYidx = 0; compressionYidx < compressionHeight; ++compressionYidx)
+   {
+      uncompressYidx = compressionYidx*rows*destWidth;
+      for(compressionXidx = 0; compressionXidx < compressionWidth; ++compressionXidx)
+      {
+         uncompressIdx = uncompressYidx + cols*compressionXidx;
+         ossim_uint32 codeWord = bits.getValueAsUint32(compressionIdx);
+         
+         codeWord *= cols;
+         for(rowIdx = 0; rowIdx < rows; ++rowIdx)
+         {
+            data = &table[rowIdx].theData[codeWord];
+            for(colIdx = 0; colIdx < cols; ++colIdx)
+            {
+               lutValue = (*data)&0xff;
+               tempRows[0][uncompressIdx+colIdx] = (*theLut)[lutValue][0];
+               tempRows[1][uncompressIdx+colIdx] = (*theLut)[lutValue][1];
+               tempRows[2][uncompressIdx+colIdx] = (*theLut)[lutValue][2];
+               ++data;
+            }
+            uncompressIdx += destWidth;
+         }
+         ++compressionIdx;
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfTileSource.h
new file mode 100644
index 0000000000..d678293cc7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfTileSource.h
@@ -0,0 +1,416 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for NitfTileSource.
+//
+//*******************************************************************
+//  $Id: ossimNitfTileSource.h,v 1.42 2005/11/09 16:07:43 dburken Exp $
+#ifndef ossimNitfTileSource_HEADER
+#define ossimNitfTileSource_HEADER
+
+#include <fstream>
+using namespace std;
+
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/cache/ossimAppFixedTileCache.h>
+
+class ossimNitfFile;
+class ossimNitfImageHeader;
+
+class OSSIM_DLL ossimNitfTileSource : public ossimImageHandler
+{
+public:
+
+   enum ReadMode
+   {
+      READ_MODE_UNKNOWN = 0,
+      
+      /** IMODE = B "Band Interleaved By Block or a single band" */
+      READ_BIB_BLOCK = 1,
+
+      /** IMODE = P "Band Interleaved By Pixel" */
+      READ_BIP_BLOCK = 2,
+
+      /** IMODE = R "Band Interleaved By Row" */
+      READ_BIR_BLOCK = 3,
+
+      /** IMODE = S "Band Sequential" */
+      READ_BSQ_BLOCK = 4,
+
+      /** IMODE = B of S "single block or one block for each band" */
+      READ_BIB       = 5,
+
+      /** IMODE = P "single block Band Interleaved By Pixel" */
+      READ_BIP       = 6,
+
+      /** IMODE = R "single block Band Interleaved By Row" */
+      READ_BIR       = 7
+   };
+
+   ossimNitfTileSource();
+   
+   virtual ~ossimNitfTileSource();
+   
+   virtual ossimString getShortName() const;
+   virtual ossimString getLongName()  const;
+   virtual ossimString className()    const;
+
+   /**
+    *  Returns true if the image_file can be opened and is a valid nitf file.
+    */
+   virtual bool open();
+
+   /**
+    * Closes file and destroys all memory allocated.
+    */
+   virtual void close();
+
+   /**
+    * @param tileRect Requested rectangle.
+    *
+    * @param resLevel Reduced resolution level to grab tileRect from.
+    * Default = 0 or the full resolution data set.
+    *
+    * @return Returns an image data object with requested rectangle from the
+    * image.  Depending on the overlap of tileRect with respect to the image
+    * rectangle, the returned tile could be full, partial, or an empty(blank)
+    * tile.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+    /**
+     * @return Returns the number of bands in the image.
+     * Satisfies pure virtual from ImageHandler class.
+     */
+   virtual ossim_uint32 getNumberOfInputBands() const;
+
+   /**
+    * @return Number of output bands.
+    */
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+
+   /**
+     *  Returns the number of lines in the image.
+     *  Satisfies pure virtual from ImageHandler class.
+     */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel = 0) const;
+   
+   /**
+    *  Returns the number of samples in the image.  
+    *  Satisfies pure virtual from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel = 0) const;
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /**
+    * Returns the output pixel type of the tile source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32 getTileWidth() const;
+   
+   /**
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;   
+
+   virtual bool isOpen()const;
+
+   /**
+    * @return The current entry number.
+    *
+    * @note NITF's can contain multiple images in a single file.  This returns
+    * the index of the current image being read.
+    */
+   virtual ossim_uint32 getCurrentEntry() const;
+
+   /**
+    * @param entryList This is the list to initialize with entry indexes.
+    */
+   virtual void getEntryList(std::vector<ossim_uint32>& entryList) const;
+
+   /**
+    * @return Returns the number of entries (or images) within the nitf
+    * file.
+    */
+   ossim_uint32 getNumberOfEntries() const;
+   
+   /**
+    * @param entryIdx Zero base entry number to select.  Sets data member
+    * "theCurrentEntry".
+    *
+    * @note "theCurrentEntry" will not be set if "entryIdx" is out of range.
+    */
+   virtual bool setCurrentEntry(ossim_uint32 entryIdx);
+
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   ossimString getSecurityClassification()const;
+   
+   /**
+    * @return Returns theCacheEnabledFlag.
+    */
+   bool getCacheEnabledFlag() const;
+
+   /**
+    * @param flag Sets theCacheEnabledFlag and disables/enables caching
+    * accordingly.  If cache is disabled it is also flushed at the same time.
+    * If cache is enabled, blocks read from the image will be cached.
+    */
+   void setCacheEnabledFlag(bool flag);
+
+protected:
+
+   /**
+    * @param imageRect The full resolution image rectangle.
+    *
+    * @note Should contain offsets if there are any.
+    */
+   void setBoundingRectangle(const ossimIrect& imageRect);
+
+   /**
+    * @return The image header for the current entry.
+    */
+   const ossimNitfImageHeader* getCurrentImageHeader() const;
+
+private:
+   
+   /** Copy constructor, disallow... */
+   ossimNitfTileSource(const ossimNitfTileSource& source);
+
+   /** Operator=, disallow... */
+   ossimNitfTileSource& operator=(const ossimNitfTileSource& source); 
+
+   /**
+    *  Returns true on success, false on error.
+    */
+   bool loadTile(const ossimIrect& clipRect);
+
+   /**
+    * @param pt Point to adjust.  This will be modified by the method to fall
+    * on an even block boundary.  Behavior is to snap to the nearest upper
+    * left block corner.
+    *
+    * @param tileHeight Height of one tile in pixels.
+    *
+    * @param tileWidth Width of one tile in pixels.
+    */
+   void adjustToStartOfBlock(ossimIpt& pt,
+                             ossim_int32 tileHeight,
+                             ossim_int32 tileWidth) const;
+
+   /**
+    * @return Returns the block number given an origin.
+    */
+   ossim_uint32 getBlockNumber(const ossimIpt& block_origin) const;
+
+   /**
+    * Deletes all memory allocated by this object.
+    */
+   void destroy();
+
+   /**
+    * Parses "theImageFile" and initializes all nitf headers.
+    *
+    * @return true on success, false on error.
+    *
+    * @note parseFile() and initialize() are separated  so initialize() can
+    * be called on a entry change to an already open nitf file.
+    */
+   bool parseFile();
+
+   /**
+    * Allocates all memory with the exception of headers.
+    *
+    * @note parseFile() and allocate() are separated so allocate() can
+    * be called on a entry change to an already open nitf file.
+    */
+   bool allocate();
+
+   /**
+    * Initializes the data member "theScalarType" from the current entry.
+    */
+   void initializeScalarType();
+
+   /**
+    * Initializes the data member "theSwapBytesFlag" from the current entry.
+    */
+   void initializeSwapBytesFlag();
+   
+   /**
+    * Initializes the data member "theReadMode" from the current entry.
+    */
+   void initializeReadMode();
+
+   /**
+    * Initializes the data member "theNumberOfBands" from the current entry.
+    */
+   void initializeBandCount();
+
+   /**
+    * Initializes the data member "theBlockSize" from the current entry.
+    *
+    * @note This should be performed after setting the read mode and
+    * band count.
+    *
+    * @note This is the size of a single block read.  So if the bands are
+    * separated by block, a read of this size will get one block.
+    */
+   void initializeBlockSize();
+
+   /**
+    * Initializes the data members "theImageRect" and "theSubImageOffset"
+    * from the current entry.
+    */
+   void initializeImageRect();
+
+   /**
+    * Initializes the data member "theCacheSize".
+    */
+   void initializeCacheSize();
+
+   /**
+    * Initializes the data member "theCacheTileInterLeaveType".
+    */
+   void initializeCacheTileInterLeaveType();
+   
+   /**
+    * Initializes the cache tile size(width and height).  For block images
+    * this will be the size of one block.  For images that are a single block,
+    * this will be the image width by the height of one tile.
+    */
+   void initializeCacheTile();
+
+   /**
+    * Loads a block of data to theCacheTile.
+    * 
+    * @param x Starting x position of block to load.
+    *
+    * @param y Starting y position of block to load.
+    *
+    * @return true on success, false on error.
+    *
+    * @note x and y are zero based relative to the upper left corner so any
+    * sub image offset should be subtracted off.
+    */
+   bool loadBlock(ossim_uint32 x, ossim_uint32 y);
+
+   /**
+    * @param x Horizontal upper left pixel position of the requested block.
+    *
+    * @param y Vertical upper left pixel position of the requested block.
+    *
+    * @param band Band of block.  Only relative with IMODES that have bands
+    * in separate blocks.
+    *
+    * @return true if the stream position was settable and false otherwise.
+    */
+   bool getPosition(std::streampos& position,
+                    ossim_uint32 x,
+                    ossim_uint32 y,
+                    ossim_uint32 band) const;
+
+   /**
+    * @return the total number of blocks for the current entry.
+    *
+    * @note For band separated blocks, all bands will be counted as on block.
+    */
+   ossim_uint32 getNumberOfBlocks() const;
+
+   /**
+    * @return The number of bytes to get from one block band to the next band.
+    */
+   std::streampos getBandOffset() const;
+
+   /**
+    * @return The number of bytes to get from one block to the next block.
+    */
+   std::streampos getBlockOffset() const;
+   
+
+   void explodePackedBits(ossimRefPtr<ossimImageData> packedBuffer)const;
+
+   void convertTransparentToNull(ossimRefPtr<ossimImageData> tile)const;
+   
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   ossim_uint32 getPartialReadSize(const ossimIpt& blockOrigin)const;
+   bool isVqCompressed(const ossimString& compressionCode)const;
+   void vqUncompress(ossimRefPtr<ossimImageData> destination,
+                     ossim_uint8* source);
+
+   void lutUncompress(ossimRefPtr<ossimImageData> destination,
+                     ossim_uint8* source);
+   
+   ossimRefPtr<ossimImageData>   theTile;
+   ossimRefPtr<ossimImageData>   theCacheTile;
+   ossimNitfFile*                theNitfFile;
+   vector<ossimNitfImageHeader*> theNitfImageHeader;
+   ReadMode                      theReadMode;
+   ossimScalarType               theScalarType;
+   bool                          theSwapBytesFlag;
+   ossim_uint32                  theNumberOfInputBands;
+   ossim_uint32                  theNumberOfOutputBands;
+   ossim_uint32                  theBlockSizeInBytes;
+   ossim_uint32                  theReadBlockSizeInBytes;
+   ossim_uint32                  theNumberOfImages;
+   ossim_uint32                  theCurrentEntry;
+   ossimIrect                    theImageRect;
+   ifstream                      theFileStr;   
+   vector<ossim_uint32>          theOutputBandList;
+   ossimIpt                      theCacheSize;
+   ossimInterleaveType           theCacheTileInterLeaveType;
+   bool                          theCacheEnabledFlag;
+   std::vector<ossim_uint32>     theEntryList;
+   ossimAppFixedTileCache::ossimAppFixedCacheId theCacheId;
+   bool                          thePackedBitsFlag;
+   ossimIrect                    theBlockImageRect;
+   ossim_uint8*                  theCompressedBuf;
+TYPE_DATA
+};
+   
+#endif /* #ifndef ossimNitfTileSource_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfWriter.cpp
new file mode 100644
index 0000000000..3587cab9a9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfWriter.cpp
@@ -0,0 +1,1045 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimNitfWriter.cpp,v 1.41 2006/01/06 16:46:46 dburken Exp $
+#include <algorithm>
+#include <sstream>
+#include <iomanip>
+#include <tiffio.h>
+#include <imaging/formats/nitf/ossimNitfWriter.h>
+#include <base/common/ossimDate.h>
+#include <base/common/ossimPreferences.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/common/ossimTrace.h>
+#include <base/misc/ossimEndian.h>
+#include <projections/ossimProjection.h>
+#include <projections/ossimRpcSolver.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <imaging/tile_sources/ossimRectangleCutFilter.h>
+#include <base/property/ossimProperty.h>
+#include <base/property/ossimContainerProperty.h>
+#include <base/property/ossimStringProperty.h>
+#include <base/property/ossimNumericProperty.h>
+#include <base/property/ossimBooleanProperty.h>
+#include <support_data/nitf/ossimNitfGeoPositioningTag.h>
+#include <support_data/nitf/ossimNitfLocalGeographicTag.h>
+#include <support_data/nitf/ossimNitfLocalCartographicTag.h>
+#include <support_data/nitf/ossimNitfProjectionParameterTag.h>
+#include <support_data/nitf/ossimNitfNameConversionTables.h>
+#include <support_data/nitf/ossimNitfBlockaTag.h>
+
+RTTI_DEF1(ossimNitfWriter, "ossimNitfWriter", ossimImageFileWriter);
+
+static ossimTrace traceDebug(ossimString("ossimNitfWriter:debug"));
+                             
+ossimNitfWriter::ossimNitfWriter(const ossimFilename& filename,
+                                 ossimImageSource* inputSource)
+   : ossimImageFileWriter(filename, inputSource, NULL),
+     theOutputStream(NULL),
+     theFileHeader(),
+     theImageHeader(),
+     theEnableRpcbTagFlag(false),
+     theEnableBlockaTagFlag(true)
+{
+   //---
+   // 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_1;
+   theImageHeader     = new ossimNitfImageHeaderV2_1;
+   theOutputImageType = "nitf_block_band_separate";
+}
+
+ossimNitfWriter::~ossimNitfWriter()
+{
+   //---
+   // This looks like a leak but it's not as both of these are ossimRefPtr's.
+   //---
+   theFileHeader=NULL;
+   theImageHeader=NULL;
+   
+   close();
+}
+
+bool ossimNitfWriter::isOpen()const
+{
+   return (theOutputStream != NULL);
+}
+
+bool ossimNitfWriter::open()
+{
+   if(isOpen())
+   {
+      close();
+   }
+   theOutputStream = new std::ofstream;
+   theOutputStream->open(theFilename.c_str(), ios::out|ios::binary);
+   
+   return theOutputStream->good();
+}
+
+void ossimNitfWriter::close()
+{
+   if(theOutputStream)
+   {
+      theOutputStream->close();
+      delete theOutputStream;
+      theOutputStream = (std::ofstream*)NULL;
+   }
+}
+
+bool ossimNitfWriter::writeFile()
+{
+   if(!theInputConnection->isMaster())
+   {
+      theInputConnection->slaveProcessTiles();
+
+      return true;
+   }
+
+   open();
+
+   if (!isOpen())
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfWriter::writeFile ERROR:"
+            << " Could not open!  Returning..."
+            << std::endl;
+      }
+
+      return false;
+   }
+
+   // Write out the geometry info.
+   writeGeometry();
+
+   // addStandardTags();
+   
+   bool result = false;
+   if((theOutputImageType == "nitf_block_band_separate")||
+      (theOutputImageType == "image/nitf"))
+   {
+      result =  writeBlockBandSeparate();
+   }
+   else if(theOutputImageType == "nitf_block_band_sequential")
+   {
+      result =  writeBlockBandSequential();
+   }
+   
+   close();
+   
+   return result;
+}
+
+void ossimNitfWriter::getImageTypeList(std::vector<ossimString>& imageTypeList)const
+{
+   imageTypeList.push_back(ossimString("nitf_block_band_separate"));
+   imageTypeList.push_back(ossimString("nitf_block_band_sequential"));
+}
+
+void ossimNitfWriter::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")
+   {
+      ossimBooleanProperty* boolProperty = PTR_CAST(ossimBooleanProperty,
+                                                    property.get());
+      if (boolProperty)
+      {
+         theEnableRpcbTagFlag = boolProperty->getBoolean();
+      }
+   }
+   else if (name == "enable_blocka_tag")
+   {
+      ossimBooleanProperty* boolProperty = PTR_CAST(ossimBooleanProperty,
+                                                    property.get());
+      if (boolProperty)
+      {
+         theEnableBlockaTagFlag = boolProperty->getBoolean();
+      }
+   }
+   else
+   {
+      ossimImageFileWriter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimNitfWriter::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
+   {
+      return ossimImageFileWriter::getProperty(name);
+   }
+
+   return result;
+}
+
+void ossimNitfWriter::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");
+}
+
+bool ossimNitfWriter::writeBlockBandSeparate()
+{
+   ossimScalarType scalarType = theInputConnection->getOutputScalarType();
+   ossim_uint32 byteSize      = ossimGetScalarSizeInBytes(scalarType);
+   ossimIrect rect            = theInputConnection->getBoundingRect();
+   ossim_uint32 bands         = theInputConnection->getNumberOfOutputBands();
+   ossim_uint32 idx           = 0;
+   ossim_uint64 headerStart   = (ossim_uint64)theOutputStream->tellp();
+   
+   ossimNitfImageInfoRecordV2_1 imageInfoRecord;
+   imageInfoRecord.setSubheaderLength(439); // ok if no tags
+   imageInfoRecord.setImageLength(bands*byteSize*rect.width()*rect.height());
+   
+
+   ossimString pixelType = "INT";
+   ossim_uint32 bitsPerPixel = 8;
+   ossim_uint32 actualBitsPerPixel = 8;
+   switch(scalarType)
+   {
+      case OSSIM_UCHAR:
+      {
+         // already set to this type by default
+         break;
+      }
+      case OSSIM_USHORT11:
+      {
+         actualBitsPerPixel = 11;
+         bitsPerPixel = 16;
+         break;
+      }
+      case OSSIM_USHORT16:
+      {
+         actualBitsPerPixel = 16;
+         bitsPerPixel = 16;
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         actualBitsPerPixel = 16;
+         bitsPerPixel = 16;
+         pixelType    = "SI";
+         break;
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         actualBitsPerPixel = 32;
+         bitsPerPixel = 32;
+         pixelType    = "R";
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         actualBitsPerPixel = 64;
+         bitsPerPixel = 64;
+         pixelType    = "R";
+         break;
+      }
+      default:
+      {
+         // ERROR
+         return false;
+      }
+   }
+   ossimDate currentDate;
+   
+   theFileHeader->setDate(currentDate);
+   theFileHeader->addImageInfoRecord(imageInfoRecord);
+   theFileHeader->writeStream(*theOutputStream); // 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
+   //
+   ossim_uint64 headerLength = ((ossim_uint64)theOutputStream->tellp() - headerStart) /* + 1 */;
+   
+   ossimString representation;
+   theImageHeader->setActualBitsPerPixel(actualBitsPerPixel);
+   theImageHeader->setBitsPerPixel(bitsPerPixel);
+   theImageHeader->setPixelType(pixelType);
+   theImageHeader->setNumberOfBands(bands);
+   theImageHeader->setImageMode('B');// blocked
+   theImageHeader->setNumberOfRows(rect.height());
+   theImageHeader->setNumberOfCols(rect.width());
+
+   ossimIpt blockSize(64, 64);
+   ossim_uint32 blocksHorizontal = (ossim_uint32)ceil(((double)rect.width()/(double)blockSize.x));
+   ossim_uint32 blocksVertical   = (ossim_uint32)ceil(((double)rect.height()/(double)blockSize.y));
+   
+#if 0
+   
+   ossimKeywordlist kwl;
+   theInputConnection->getImageGeometry(kwl);
+   ossimRefPtr<ossimProjection> proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+   
+
+//    while((ceil(((double)rect.width()/(double)blockSize.x)) < 2) &&
+//          (blockSize.x > 4))
+//    {
+//       blockSize.x >>= 1;
+//       blockSize.y >>= 1;
+//    }
+   
+   /*
+    * Geo encode the image using the simple igeolo field for NITF.   
+    */
+   if(proj.valid())
+   {
+      ossimUtmProjection* utmProj = PTR_CAST(ossimUtmProjection, proj.get());
+      if(utmProj)
+      {
+         ossimMapProjectionInfo mapInfo(utmProj,
+                                        rect);
+         mapInfo.setPixelType(OSSIM_PIXEL_IS_AREA);
+         
+         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
+      {
+         ossimMapProjection* tempProj = PTR_CAST(ossimMapProjection,
+                                             proj.get());
+         if(tempProj)
+         {
+            ossimMapProjectionInfo mapInfo(tempProj,
+                                           rect);
+            
+            mapInfo.setPixelType(OSSIM_PIXEL_IS_AREA);
+            ossimGpt ul = mapInfo.ulGroundPt();
+            ossimGpt ur = mapInfo.urGroundPt();
+            ossimGpt lr = mapInfo.lrGroundPt();
+            ossimGpt ll = mapInfo.llGroundPt();
+            theImageHeader->setGeographicLocationDms(ul, ur, lr, ll);
+         }
+         else
+         {
+            ossimGpt ul;
+            ossimGpt ur;
+            ossimGpt lr;
+            ossimGpt ll;
+            proj->lineSampleToWorld(rect.ul(), ul);
+            proj->lineSampleToWorld(rect.ur(), ur);
+            proj->lineSampleToWorld(rect.lr(), lr);
+            proj->lineSampleToWorld(rect.ll(), ll);
+            theImageHeader->setGeographicLocationDms(ul, ur, lr, ll);
+         }
+      }
+   }
+
+#endif
+   
+   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(blockSize.y*blocksVertical);
+//    theImageHeader->setNumberOfCols(blockSize.x*blocksHorizontal);
+    theImageHeader->setNumberOfRows(rect.height());
+    theImageHeader->setNumberOfCols(rect.width());
+
+   ossimNitfImageBandV2_1 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;
+
+   theInputConnection->setTileSize(blockSize);
+   ossim_uint32 numberOfTiles   = theInputConnection->getNumberOfTiles();
+   theInputConnection->setToStartOfSequence();
+   ossimRefPtr<ossimImageData> data = theInputConnection->getNextTile();
+   ossim_uint32 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();
+
+   /*
+    * 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 ossimNitfWriter::writeBlockBandSequential()
+{
+   ossimScalarType scalarType = theInputConnection->getOutputScalarType();
+   ossim_uint32 byteSize      = ossimGetScalarSizeInBytes(scalarType);
+   ossimIrect rect            = theInputConnection->getBoundingRect();
+   ossim_uint32 bands         = theInputConnection->getNumberOfOutputBands();
+   ossim_uint32 idx           = 0;
+   ossim_uint64 headerStart   = (ossim_uint64)theOutputStream->tellp();
+
+   ossimIpt blockSize(64, 64);
+
+//    while((ceil(((double)rect.width()/(double)blockSize.x)) < 2) &&
+//          (blockSize.x > 4))
+//    {
+//       blockSize.x >>= 1;
+//       blockSize.y >>= 1;
+//    }
+   ossim_uint32 blocksHorizontal = theInputConnection->getNumberOfTilesHorizontal();
+   ossim_uint32 blocksVertical   = theInputConnection->getNumberOfTilesVertical();
+   theInputConnection->setTileSize(blockSize);
+   ossim_uint32 numberOfTiles   = theInputConnection->getNumberOfTiles();
+   theInputConnection->setToStartOfSequence();
+   
+   ossimNitfImageInfoRecordV2_1 imageInfoRecord;
+   imageInfoRecord.setSubheaderLength(439);
+   imageInfoRecord.setImageLength(bands*byteSize*rect.width()*rect.height());
+   
+
+   ossimString pixelType = "INT";
+   ossim_uint32 bitsPerPixel = 8;
+   switch(scalarType)
+   {
+      case OSSIM_UCHAR:
+      {
+         // already set to this type by default
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         bitsPerPixel = 16;
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         bitsPerPixel = 16;
+         pixelType    = "SI";
+         break;
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         bitsPerPixel = 32;
+         pixelType    = "R";
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         bitsPerPixel = 64;
+         pixelType    = "R";
+         break;
+      }
+      default:
+      {
+         // ERROR
+         return false;
+      }
+   }
+   ossimDate currentDate;
+   
+   theFileHeader->setDate(currentDate);
+   theFileHeader->addImageInfoRecord(imageInfoRecord);
+   theFileHeader->writeStream(*theOutputStream);
+
+   // need a better way to get the length.  This should be queried on the header before writing
+   //
+   ossim_uint64 headerLength = ((ossim_uint64)theOutputStream->tellp() - headerStart) /* + 1 */;
+   
+   ossimString representation;
+   theImageHeader->setBitsPerPixel(bitsPerPixel);
+   theImageHeader->setPixelType(pixelType);
+   theImageHeader->setNumberOfBands(bands);
+   theImageHeader->setImageMode('S');// blocked
+   theImageHeader->setNumberOfRows(rect.height());
+   theImageHeader->setNumberOfCols(rect.width());
+
+#if 0
+   
+   ossimKeywordlist kwl;
+   theInputConnection->getImageGeometry(kwl);
+   ossimRefPtr<ossimProjection> proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+
+   /*
+    * Geo encode the image using the simple igeolo field for NITF.   
+    */
+   if(proj.valid())
+   {
+      ossimUtmProjection* utmProj = PTR_CAST(ossimUtmProjection, proj.get());
+      if(utmProj)
+      {
+         ossimDpt ul;
+         ossimDpt ur;
+         ossimDpt lr;
+         ossimDpt ll;
+
+         utmProj->lineSampleToEastingNorthing(rect.ul(), ul);
+         utmProj->lineSampleToEastingNorthing(rect.ur(), ur);
+         utmProj->lineSampleToEastingNorthing(rect.lr(), lr);
+         utmProj->lineSampleToEastingNorthing(rect.ll(), ll);
+         if(utmProj->getHemisphere() == 'N')
+         {
+            theImageHeader->setUtmNorth(utmProj->getZone(), ul, ur, lr, ll);
+         }
+         else                
+         {
+            theImageHeader->setUtmSouth(utmProj->getZone(), ul, ur, lr, ll);
+         }
+      }
+      else
+      {
+         ossimGpt ul;
+         ossimGpt ur;
+         ossimGpt lr;
+         ossimGpt ll;
+         proj->lineSampleToWorld(rect.ul(), ul);
+         proj->lineSampleToWorld(rect.ur(), ur);
+         proj->lineSampleToWorld(rect.lr(), lr);
+         proj->lineSampleToWorld(rect.ll(), ll);
+         theImageHeader->setGeographicLocationDms(ul, ur, lr, ll);
+      }
+   }
+
+#endif
+   
+   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(blockSize.y*blocksVertical);
+   theImageHeader->setNumberOfCols(blockSize.x*blocksHorizontal);
+
+   ossimNitfImageBandV2_1 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);
+   }
+   
+   theImageHeader->writeStream(*theOutputStream);
+   ossimIpt ul = rect.ul();
+   ossimRefPtr<ossimImageData> data = theInputConnection->getNextTile();
+   ossim_uint32 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_uint32 blockSizeInBytes = blockSize.x*blockSize.y*ossimGetScalarSizeInBytes(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();
+
+   /*
+    * 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);
+   theFileHeader->writeStream(*theOutputStream);
+   
+   return true;
+}
+
+
+void ossimNitfWriter::addRegisteredTag(
+   ossimRefPtr<ossimNitfRegisteredTag> registeredTag)
+{
+   ossimNitfTagInformation tagInfo;
+   tagInfo.setTagData(registeredTag.get());
+     theImageHeader->addTag(tagInfo);
+}
+
+void ossimNitfWriter::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);
+   }
+}
+
+#if 0
+void ossimNitfWriter::addStandardTags()
+{
+
+   if(!theInputConnection)
+   {
+      return;
+   }
+   
+   // commenting this out for now.  For some reason the pixels
+   // are off when I add this tag.  I checked the parsing and it
+   // appears to be the correct length???  So, I am not sure
+   // why we are off when reading the output back in.
+   //
+   // first lets do the projection tag.  I REALLY need to add
+   // parameter support soon or this tag is useless.
+   //
+   ossimKeywordlist kwl;
+   theInputConnection->getImageGeometry(kwl);
+   ossimRefPtr<ossimProjection> proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+   ossimNitfNameConversionTables table;
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj.get());
+   ossimNitfTagInformation tagInfo;
+   
+   if(mapProj)
+   {
+
+      if(!PTR_CAST(ossimUtmProjection, mapProj))
+      {
+         ossimRefPtr<ossimNitfProjectionParameterTag> parameterTag = new ossimNitfProjectionParameterTag;
+         
+         ossimString nitfCode = table.convertMapProjectionNameToNitfCode(proj->getClassName());
+         ossimString nitfName = table.convertNitfCodeToNitfProjectionName(nitfCode);
+         
+         parameterTag->setName(nitfName);
+         parameterTag->setCode(nitfCode);
+         parameterTag->setFalseX(mapProj->getFalseEasting());
+         parameterTag->setFalseY(mapProj->getFalseNorthing());
+         
+         tagInfo.setTagData(parameterTag.get());
+         theImageHeader->addTag(tagInfo);
+      }
+   }
+}
+#endif
+
+void ossimNitfWriter::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)
+         << "ossimNitfWriter::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 ossimNitfWriter::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)
+         << "ossimNitfWriter::addRpcbTag DEBUG:"
+         << "\nRPCB Tag:" << *((ossimObject*)(tag.get()))
+         << "\nProjection:" << std::endl;
+      
+      proj->print(ossimNotify(ossimNotifyLevel_DEBUG));
+      
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nRect: " << rect << std::endl;
+   }
+}
+
+bool ossimNitfWriter::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 ossimNitfWriter::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/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfWriter.h b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfWriter.h
new file mode 100644
index 0000000000..d8b1d4db07
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimNitfWriter.h
@@ -0,0 +1,166 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimNitfWriter.h,v 1.17 2006/01/06 16:46:46 dburken Exp $
+#ifndef ossimNitfWriter_HEADER
+#define ossimNitfWriter_HEADER
+
+#include <fstream>
+#include <imaging/formats/ossimImageFileWriter.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <base/common/ossimRgbLutDataObject.h>
+#include <base/common/ossimRefPtr.h>
+#include <support_data/nitf/ossimNitfFileHeaderV2_1.h>
+#include <support_data/nitf/ossimNitfImageHeaderV2_1.h>
+
+class ossimProjection;
+
+class OSSIM_DLL ossimNitfWriter : public ossimImageFileWriter
+{
+public:
+   ossimNitfWriter(const ossimFilename& filename=ossimFilename(""),
+                   ossimImageSource* inputSource = (ossimImageSource*)NULL);
+   virtual ~ossimNitfWriter();
+   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();
+
+   /** Currently disabled... */
+   // virtual void addStandardTags();
+
+   /**
+    * 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);
+
+
+   std::ofstream* theOutputStream;
+   
+   ossimRefPtr<ossimNitfFileHeaderV2_1>  theFileHeader;
+   ossimRefPtr<ossimNitfImageHeaderV2_1> 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;
+   
+TYPE_DATA   
+};
+
+#endif /* #ifndef ossimNitfWriter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimQuickbirdNitfTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimQuickbirdNitfTileSource.cpp
new file mode 100644
index 0000000000..6a3a6cf9eb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimQuickbirdNitfTileSource.cpp
@@ -0,0 +1,187 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimQuickbirdNitfTileSource.cpp,v 1.12 2005/11/09 16:08:26 dburken Exp $
+#include <imaging/formats/nitf/ossimQuickbirdNitfTileSource.h>
+#include <support_data/qb/ossimQuickbirdTile.h>
+#include <base/common/ossimTrace.h>
+#include "support_data/nitf/ossimNitfImageHeader.h"
+
+RTTI_DEF1(ossimQuickbirdNitfTileSource, "ossimQuickbirdNitfTileSource", ossimNitfTileSource);
+
+static const ossimTrace traceDebug("ossimQuickbirdNitfTileSource:debug");
+
+bool ossimQuickbirdNitfTileSource::open()
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimQuickbirdNitfTileSource::open(file) DEBUG: entered ..."
+         << std::endl;
+   }
+   
+   ossimFilename file = theImageFile;
+   file = file.replaceAllThatMatch("_R[0-9]+C[0-9]+");
+   ossimQuickbirdTile tileFile;
+   bool openedTileFile = false;
+   file.setExtension("TIL");
+   
+   if(!tileFile.open(file))
+   {
+      file.setExtension("TIL");
+      if(tileFile.open(file))
+      {
+         openedTileFile = true;
+      }
+      else
+      {
+         file.setExtension("til");
+         if(tileFile.open(file))
+         {
+            openedTileFile = true;
+         }
+      }
+   }
+   else
+   {
+      openedTileFile = true;
+   }
+   
+   if(openedTileFile)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimQuickbirdNitfTileSource::open(file) DEBUG:"
+            << "\nOpened tile file" << std::endl;
+      }
+
+      // Call the base class open...
+      if(!ossimNitfTileSource::open())
+      {
+         return false;
+      }
+      
+      ossimQuickbirdTileInfo info;
+      ossimIrect tempBounds = getCurrentImageHeader()->getImageRect();
+      
+      
+      tempBounds = ossimIrect(0,
+                              0,
+                              tempBounds.width() - 1,
+                              tempBounds.height() - 1);
+      
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimQuickbirdNitfTileSource::open(file) DEBUG:"
+            << "\nheader rectangle = " << tempBounds << std::endl;
+      }
+      
+      ossimIpt ulPt;
+      ossimIpt urPt;
+      ossimIpt lrPt;
+      ossimIpt llPt;
+      
+      if(tileFile.getInfo(info, theImageFile.file().upcase()))
+      {
+         ulPt.makeNan();
+         urPt.makeNan();
+         lrPt.makeNan();
+         llPt.makeNan();
+         
+         if((info.theUlXOffset != OSSIM_INT_NAN) &&
+            (info.theUlYOffset != OSSIM_INT_NAN))
+         {
+            theSubImageOffset = ossimIpt(info.theUlXOffset, info.theUlYOffset);
+         }
+         else
+         {
+            theSubImageOffset = ossimIpt(0,0);
+         }
+          
+         ulPt = theSubImageOffset;
+         
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "ossimQuickbirdNitfTileSource::open(file) DEBUG:"
+               << "\nSub image offset  = " << theSubImageOffset
+               << std::endl;
+         }
+         
+         if((info.theUrXOffset != OSSIM_INT_NAN) &&
+            (info.theUrYOffset != OSSIM_INT_NAN))
+         {
+            urPt = ossimIpt(info.theUrXOffset,
+                            info.theUrYOffset);
+         }
+         else
+         {
+            urPt = tempBounds.ur() + ulPt;
+         }
+         
+         if((info.theLrXOffset != OSSIM_INT_NAN) &&
+            (info.theLrYOffset != OSSIM_INT_NAN))
+         {
+            lrPt = ossimIpt(info.theLrXOffset,
+                            info.theLrYOffset);
+         }
+         else
+         {
+            lrPt = tempBounds.lr() + ulPt;
+         }
+         
+         if((info.theLlXOffset != OSSIM_INT_NAN) &&
+            (info.theLlYOffset != OSSIM_INT_NAN))
+         {
+            llPt = ossimIpt(info.theLlXOffset,
+                            info.theLlYOffset);
+         }
+         else
+         {
+            llPt = tempBounds.ll() + ulPt;
+         }
+      }
+
+      //---
+      // Set the base class image rectangle in case a sub image offset was
+      // picked up here.
+      //---
+      setBoundingRectangle(ossimIrect(ulPt, urPt, lrPt, llPt));
+      
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimQuickbirdNitfTileSource::open(file) DEBUG:"
+            << "\nUl = " << ulPt
+            << "\nUr = " << urPt
+            << "\nLr = " << lrPt
+            << "\nLl = " << llPt
+            << "\ntheImageRect:  " << getImageRectangle(0)
+            << "\nExiting..." 
+            << std::endl;
+      }
+   }
+   else
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimQuickbirdNitfTileSource::open(file) DEBUG"
+            << "Not opened..."
+            << std::endl;
+      }
+   }
+   
+   return openedTileFile;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimQuickbirdNitfTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimQuickbirdNitfTileSource.h
new file mode 100644
index 0000000000..ae76023750
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/nitf/ossimQuickbirdNitfTileSource.h
@@ -0,0 +1,27 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimQuickbirdNitfTileSource.h,v 1.7 2004/10/28 18:27:18 dburken Exp $
+#ifndef ossimQuickbirdNitfTileSource_HEADER
+#define ossimQuickbirdNitfTileSource_HEADER
+#include "ossimNitfTileSource.h"
+
+class ossimQuickbirdNitfTileSource : public ossimNitfTileSource
+{
+public:
+  virtual bool open();
+
+ protected:
+
+TYPE_DATA   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageFileWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageFileWriter.cpp
new file mode 100644
index 0000000000..2a49f638b2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageFileWriter.cpp
@@ -0,0 +1,1123 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Frank Warmerdam (warmerdam@pobox.com)
+//
+// Description:
+//
+// Contains class declaration for ossimImageFileWriter.
+//*******************************************************************
+//  $Id: ossimImageFileWriter.cpp,v 1.45 2005/12/27 16:09:10 dburken Exp $
+
+#include <ossimConfig.h>
+#include <imaging/formats/ossimImageFileWriter.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimMultiResLevelHistogram.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/misc/lookup_tables/ossimImageTypeLut.h>
+#include <imaging/formats/tiff/ossimTiffOverviewBuilder.h>
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/histogram/ossimHistogramWriter.h>
+#include <imaging/histogram/ossimImageHistogramSource.h>
+#include <imaging/metadata/ossimMetadataFileWriter.h>
+#include <imaging/metadata/ossimGeomFileWriter.h>
+#include <imaging/metadata/ossimEnviHeaderFileWriter.h>
+#include <imaging/metadata/ossimFgdcFileWriter.h>
+#include <imaging/metadata/ossimJpegWorldFileWriter.h>
+#include <imaging/metadata/ossimReadmeFileWriter.h>
+#include <imaging/metadata/ossimTiffWorldFileWriter.h>
+#include <base/common/ossimStdOutProgress.h>
+#include <base/property/ossimFilenameProperty.h>
+#include <base/property/ossimBooleanProperty.h>
+#include <base/common/ossimTrace.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+
+static ossimTrace traceDebug("ossimImageFileWriter:debug");
+
+#if OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimImageFileWriter.cpp,v 1.45 2005/12/27 16:09:10 dburken Exp $";
+#endif
+
+RTTI_DEF3(ossimImageFileWriter,
+          "ossimImageFileWriter",
+          ossimImageWriter,
+          ossimProcessInterface,
+          ossimConnectableObjectListener);
+
+ossimImageFileWriter::ossimImageFileWriter(const ossimFilename& file,
+                                           ossimImageSource* inputSource,
+                                           ossimObject* owner)
+   : ossimImageWriter(owner,
+                      1,
+                      0,
+                      true,
+                      false),
+     ossimProcessInterface(),
+     ossimConnectableObjectListener(),
+     theViewController(NULL),
+     theProgressListener(NULL),
+     theFilename(file),
+     theOutputImageType(ossimImageTypeLut().getEntryString(OSSIM_IMAGE_TYPE_UNKNOWN)),
+     theWriteImageFlag(true),
+     theWriteOverviewFlag(false),
+     theWriteHistogramFlag(false),
+     theOverviewCompressType(COMPRESSION_NONE),
+     theOverviewJpegCompressQuality(75),
+
+     theWriteEnviHeaderFlag(false),
+     theWriteExternalGeometryFlag(false),
+     theWriteFgdcFlag(false),
+     theWriteJpegWorldFileFlag(false),
+     theWriteReadmeFlag(false),
+     theWriteTiffWorldFileFlag(false)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageFileWriter::ossimImageFileWriter entered..."
+         << std::endl;
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "OSSIM_ID:  " << OSSIM_ID << std::endl;
+#endif
+   }
+
+   theInputConnection = new ossimImageSourceSequencer(inputSource);
+
+   // now map the sequencer to the same input
+   connectMyInputTo(0, inputSource);
+   initialize();
+
+   // make sure we listen to our input changes so we can change
+   // it for the sequencer as well.
+   //
+   ossimImageWriter::addListener((ossimConnectableObjectListener*)this);
+
+   theInputConnection->connectMyInputTo(0, inputSource, false);
+   theAreaOfInterest.makeNan();
+}
+
+ossimImageFileWriter::~ossimImageFileWriter()
+{
+   if(theInputConnection)
+   {
+      delete theInputConnection;
+      theInputConnection = NULL;
+   }
+   theProgressListener = NULL;
+   removeListener((ossimConnectableObjectListener*)this);
+}
+
+void ossimImageFileWriter::initialize()
+{
+   if(theInputConnection)
+   {
+      theInputConnection->initialize();
+      setAreaOfInterest(theInputConnection->getBoundingRect());
+   }
+}
+
+void ossimImageFileWriter::changeSequencer(ossimImageSourceSequencer* sequencer)
+{
+   if(!sequencer) return;
+   if(theInputConnection)
+   {
+      sequencer->setAreaOfInterest(theInputConnection->getAreaOfInterest());
+   }
+
+   if(theInputConnection)
+   {
+      delete theInputConnection;
+   }
+   theInputConnection = sequencer;
+   theInputConnection->connectMyInputTo(0, getInput(0));
+}
+
+
+bool ossimImageFileWriter::saveState(ossimKeywordlist& kwl,
+                                 const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           TYPE_NAME(this),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FILENAME_KW,
+           theFilename.c_str(),
+           true);
+
+   kwl.add(prefix,
+           "create_envi_hdr",
+           (ossim_uint32)theWriteEnviHeaderFlag,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CREATE_EXTERNAL_GEOMETRY_KW,
+           (ossim_uint32)theWriteExternalGeometryFlag,
+           true);
+
+   kwl.add(prefix,
+           "create_fgdc",
+           (ossim_uint32)theWriteFgdcFlag,
+           true);
+   
+   kwl.add(prefix,
+           "create_jpeg_world_file",
+           (ossim_uint32)theWriteJpegWorldFileFlag,
+           true);
+
+   kwl.add(prefix,
+           "create_readme",
+           (ossim_uint32)theWriteReadmeFlag,
+           true);
+   
+   kwl.add(prefix,
+           "create_tiff_world_file",
+           (ossim_uint32)theWriteTiffWorldFileFlag,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CREATE_IMAGE_KW,
+           (ossim_uint32)theWriteImageFlag,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CREATE_OVERVIEW_KW,
+           (ossim_uint32)theWriteOverviewFlag,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CREATE_HISTOGRAM_KW,
+           (ossim_uint32)theWriteHistogramFlag,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::OVERVIEW_COMPRESSION_TYPE_KW,
+           theOverviewCompressType,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::OVERVIEW_COMPRESSION_QUALITY_KW,
+           theOverviewJpegCompressQuality,
+           true);
+
+   ossimImageTypeLut lut;
+   kwl.add(prefix,
+           ossimKeywordNames::IMAGE_TYPE_KW,
+           theOutputImageType,
+           true);
+
+   return ossimSource::saveState(kwl, prefix);
+}
+
+bool ossimImageFileWriter::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   // Load the state of the base class.
+   bool result = ossimSource::loadState(kwl, prefix);
+
+   // Get the filename...
+   const char* lookup = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   if(lookup)
+   {
+      ossimString filename = lookup;
+
+      lookup =  kwl.find(prefix, ossimKeywordNames::FILEPATH_KW);
+      if(lookup)
+      {
+         filename = ossimString(lookup) + filename;
+      }
+
+      setFilename(filename);
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::CREATE_EXTERNAL_GEOMETRY_KW);
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theWriteExternalGeometryFlag = s.toBool();
+   }
+   
+   lookup = kwl.find(prefix, "create_envi_hdr");
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theWriteEnviHeaderFlag = s.toBool();
+   }
+   
+   lookup = kwl.find(prefix, "create_fgdc");
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theWriteFgdcFlag = s.toBool();
+   }
+   
+   lookup = kwl.find(prefix, "create_jpeg_world_file");
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theWriteJpegWorldFileFlag = s.toBool();
+   }
+   
+   lookup = kwl.find(prefix, "create_readme");
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theWriteReadmeFlag = s.toBool();
+   }
+   
+   lookup = kwl.find(prefix, "create_tiff_world_file");
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theWriteTiffWorldFileFlag = s.toBool();
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::CREATE_IMAGE_KW);
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theWriteImageFlag = s.toBool();
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::CREATE_OVERVIEW_KW);
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theWriteOverviewFlag = s.toBool();
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::CREATE_HISTOGRAM_KW);
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theWriteHistogramFlag = s.toBool();
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::OVERVIEW_COMPRESSION_TYPE_KW);
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theOverviewCompressType = static_cast<ossim_uint16>(s.toUInt32());
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::OVERVIEW_COMPRESSION_QUALITY_KW);
+   if(lookup)
+   {
+      ossimString s = lookup;
+      theOverviewJpegCompressQuality = s.toInt32();
+   }
+
+   const char* outputImageType = kwl.find(prefix, ossimKeywordNames::IMAGE_TYPE_KW);
+   if(outputImageType)
+   {
+      theOutputImageType = outputImageType;
+   }
+
+   if(theInputObjectList.size() != 2)
+   {
+      theInputObjectList.resize(2);
+      theInputListIsFixedFlag = true;
+   }
+
+   theOutputListIsFixedFlag = false;
+
+   return result;
+}
+
+bool ossimImageFileWriter::writeOverviewFile(ossim_uint16 tiff_compress_type,
+                                             ossim_int32 jpeg_compress_quality) const
+{
+   if(theFilename == "") return false;
+
+   // Get an image handler for the source file.
+   ossimImageHandler* ih
+      = ossimImageHandlerRegistry::instance()->open(theFilename);
+
+   if (!ih)
+   {
+      if (ih) delete ih;
+
+      // Set the error...
+      return false;
+   }
+
+   ossimTiffOverviewBuilder ob(ih);
+
+   if (ob.getErrorStatus() != ossimErrorCodes::OSSIM_ERROR)
+   {
+      // Give the listener to the overview builder if set.
+      if (theProgressListener)
+      {
+         ob.addListener(theProgressListener);
+      }
+      
+      // Build a new file name for the overview.
+      ossimFilename overview_file = theFilename;
+      overview_file.setExtension(ossimString("ovr"));
+      ob.setCompressionType(tiff_compress_type);
+      ob.setJpegCompressionQuality(jpeg_compress_quality);
+      ob.buildOverview(overview_file, 0);
+
+      // Remove the listener from the overview builder.
+      if (theProgressListener)
+      {
+         ob.removeListener(theProgressListener);
+      }
+   }
+
+   delete ih;
+
+   return true;
+}
+
+bool ossimImageFileWriter::writeEnviHeaderFile() const
+{
+   if( (theFilename == "") || !theInputConnection ||
+       theAreaOfInterest.hasNans())
+   {
+      return false;
+   }
+
+   // Make the file name.
+   ossimFilename outputFile = theFilename;
+   outputFile.setExtension(ossimString("hdr"));
+
+   // Make the writer.
+   ossimRefPtr<ossimMetadataFileWriter> writer =
+      new ossimEnviHeaderFileWriter();
+   
+   // Set things up.
+   writer->connectMyInputTo(0, theInputConnection);
+   writer->initialize();
+   writer->setFilename(outputFile);
+   writer->setAreaOfInterest(theAreaOfInterest);
+   
+   // Write it to disk.
+   return writer->execute();
+}
+
+bool ossimImageFileWriter::writeExternalGeometryFile() const
+{
+   if( (theFilename == "") || !theInputConnection ||
+       theAreaOfInterest.hasNans())
+   {
+      return false;
+   }
+
+   // Make the file name.
+   ossimFilename geomFile = theFilename;
+   geomFile.setExtension(ossimString("geom"));
+
+   // Make the writer.
+   ossimRefPtr<ossimMetadataFileWriter> writer = new ossimGeomFileWriter();
+
+   // Set things up.
+   writer->connectMyInputTo(0, theInputConnection);
+   writer->initialize();
+   writer->setFilename(geomFile);
+   writer->setAreaOfInterest(theAreaOfInterest);
+
+   // Write it to disk.
+   return writer->execute();
+}
+
+bool ossimImageFileWriter::writeFgdcFile() const
+{
+   if( (theFilename == "") || !theInputConnection ||
+       theAreaOfInterest.hasNans())
+   {
+      return false;
+   }
+
+   // Make the file name.
+   ossimFilename outputFile = theFilename;
+   outputFile.setExtension(ossimString("xml"));
+
+   // Make the writer.
+   ossimRefPtr<ossimMetadataFileWriter> writer = new ossimFgdcFileWriter();
+   
+   // Set things up.
+   writer->connectMyInputTo(0, theInputConnection);
+   writer->initialize();
+   writer->setFilename(outputFile);
+   writer->setAreaOfInterest(theAreaOfInterest);
+   
+   // Write it to disk.
+   return writer->execute();
+}
+
+bool ossimImageFileWriter::writeJpegWorldFile() const
+{
+   if( (theFilename == "") || !theInputConnection ||
+       theAreaOfInterest.hasNans())
+   {
+      return false;
+   }
+
+   // Make the file name.
+   ossimFilename outputFile = theFilename;
+   outputFile.setExtension(ossimString("jpw")); // jpw???
+
+   // Make the writer.
+   ossimRefPtr<ossimMetadataFileWriter> writer =
+      new ossimJpegWorldFileWriter();
+   
+   // Set things up.
+   writer->connectMyInputTo(0, theInputConnection);
+   writer->initialize();
+   writer->setFilename(outputFile);
+   writer->setAreaOfInterest(theAreaOfInterest);
+   
+   // Write it to disk.
+   return writer->execute();
+}
+
+bool ossimImageFileWriter::writeReadmeFile() const
+{
+   if( (theFilename == "") || !theInputConnection ||
+       theAreaOfInterest.hasNans())
+   {
+      return false;
+   }
+
+   // Make the file name.
+   ossimFilename outputFile = theFilename.noExtension();
+   
+   outputFile += "_readme.txt";
+
+   // Make the writer.
+   ossimRefPtr<ossimMetadataFileWriter> writer =
+      new ossimReadmeFileWriter();
+   
+   // Set things up.
+   writer->connectMyInputTo(0, theInputConnection);
+   writer->initialize();
+   writer->setFilename(outputFile);
+   writer->setAreaOfInterest(theAreaOfInterest);
+   
+   // Write it to disk.
+   return writer->execute();
+}
+
+bool ossimImageFileWriter::writeTiffWorldFile() const
+{
+   if( (theFilename == "") || !theInputConnection ||
+       theAreaOfInterest.hasNans())
+   {
+      return false;
+   }
+
+   // Make the file name.
+   ossimFilename outputFile = theFilename;
+   outputFile.setExtension(ossimString("tfw"));
+
+   // Make the writer.
+   ossimRefPtr<ossimMetadataFileWriter> writer =
+      new ossimTiffWorldFileWriter();
+   
+   // Set things up.
+   writer->connectMyInputTo(0, theInputConnection);
+   writer->initialize();
+   writer->setFilename(outputFile);
+   writer->setAreaOfInterest(theAreaOfInterest);
+   
+   // Write it to disk.
+   return writer->execute();
+}
+
+bool ossimImageFileWriter::writeMetaDataFiles() const
+{
+   bool status = true;
+   
+   if(theWriteEnviHeaderFlag)
+   {
+      if(writeEnviHeaderFile() == false)
+      {
+         status = false;
+
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Write of envi header file failed!" << endl;
+      }
+   }
+
+   if (theWriteExternalGeometryFlag)
+   {
+      if( writeExternalGeometryFile() == false)
+      {
+         status = false;
+
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Write of geometry file failed!" << endl;
+      }
+   }
+   if(theWriteFgdcFlag)
+   {
+      if(writeFgdcFile() == false)
+      {
+         status = false;
+
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Write of fgdc file failed!" << endl;
+      }
+   }
+   if(theWriteJpegWorldFileFlag)
+   {
+      if(writeJpegWorldFile() == false)
+      {
+         status = false;
+         
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Write of jpeg world file failed!" << endl;
+      }
+   }
+   if(theWriteReadmeFlag)
+   {
+      if(writeReadmeFile() == false)
+      {
+         status = false;
+         
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Write of readme file failed!" << endl;
+      }
+   }
+   if(theWriteTiffWorldFileFlag)
+   {
+      if(writeTiffWorldFile() == false)
+      {
+         status = false;
+         
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Write of tiff world file failed!" << endl;
+      }
+   }
+
+   if (theWriteOverviewFlag)
+   {
+      if (!writeOverviewFile(theOverviewCompressType,
+                             theOverviewJpegCompressQuality))
+      {
+         status = false;
+         
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Write of overview file failed!" << endl;
+      }
+   }
+         
+   if (theWriteHistogramFlag)
+   {
+      if (!writeHistogramFile())
+      {
+         status = false;
+         
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Write of histogram file failed!" << endl;
+      }
+   }
+
+   return status;
+}
+
+bool ossimImageFileWriter::writeHistogramFile() const
+{
+   if(theFilename == "") return false;
+
+   ossimFilename histogram_file = theFilename;
+   histogram_file.setExtension(ossimString("his"));
+
+   ossimImageHandler* handler = ossimImageHandlerRegistry::instance()->
+      open(theFilename);
+
+   if (!handler)
+   {
+      return false;
+   }
+
+   ossimImageHistogramSource* histoSource = new ossimImageHistogramSource;
+
+   ossimHistogramWriter* writer = new ossimHistogramWriter;
+   histoSource->setMaxNumberOfRLevels(1); // Only compute for r0.
+   histoSource->connectMyInputTo(0, handler);
+   histoSource->enableSource();
+   writer->connectMyInputTo(0, histoSource);
+   writer->setFilename(histogram_file);
+   writer->addListener(&theStdOutProgress);
+   writer->execute();
+
+   delete handler;
+   delete writer;
+
+   return true;
+}
+
+void ossimImageFileWriter::disconnectInputEvent(ossimConnectionEvent& event)
+{
+   if(!getInput(0))
+   {
+      theInputConnection->disconnectMyInput((ossim_int32)0, false);
+   }
+   theViewController = PTR_CAST(ossimViewController, getInput(1));
+
+   initialize();
+}
+
+void ossimImageFileWriter::connectInputEvent(ossimConnectionEvent& event)
+{
+   theInputConnection->connectMyInputTo((ossim_int32)0,
+                                        getInput(0),
+                                        false);
+   theViewController = PTR_CAST(ossimViewController, getInput(1));
+   initialize();
+}
+
+void ossimImageFileWriter::propertyEvent(ossimPropertyEvent& event)
+{
+   initialize();
+}
+
+void ossimImageFileWriter::setOutputImageType(const ossimString& type)
+{
+   theOutputImageType = type;
+}
+
+void ossimImageFileWriter::setOutputImageType(ossim_int32 type)
+{
+   ossimImageTypeLut lut;
+   theOutputImageType = lut.getEntryString(type);
+}
+
+ossimString ossimImageFileWriter::getOutputImageTypeString() const
+{
+   return theOutputImageType;
+
+}
+
+ossim_int32 ossimImageFileWriter::getOutputImageType() const
+{
+   ossimImageTypeLut lut;
+   return lut.getEntryNumber(theOutputImageType);
+}
+
+
+bool ossimImageFileWriter::getWriteImageFlag() const
+{
+   return theWriteImageFlag;
+}
+
+bool ossimImageFileWriter::getWriteHistogramFlag() const
+{
+   return theWriteHistogramFlag;
+}
+
+bool ossimImageFileWriter::getWriteOverviewFlag() const
+{
+   return theWriteOverviewFlag;
+}
+
+bool ossimImageFileWriter::getWriteEnviHeaderFlag() const
+{
+   return theWriteEnviHeaderFlag;
+}
+
+bool ossimImageFileWriter::getWriteExternalGeometryFlag() const
+{
+   return theWriteExternalGeometryFlag;
+}
+
+bool ossimImageFileWriter::getWriteFgdcFlag() const
+{
+   return theWriteFgdcFlag;
+}
+
+bool ossimImageFileWriter::getWriteJpegWorldFileFlag() const
+{
+   return theWriteJpegWorldFileFlag;
+}
+
+bool ossimImageFileWriter::getWriteReadmeFlag() const
+{
+   return theWriteReadmeFlag;
+}
+
+bool ossimImageFileWriter::getWriteTiffWorldFileFlag() const
+{
+   return theWriteTiffWorldFileFlag;
+}
+
+
+void ossimImageFileWriter::setWriteOverviewFlag(bool flag)
+{
+   theWriteOverviewFlag = flag;
+}
+
+void ossimImageFileWriter::setWriteImageFlag(bool flag)
+{
+   theWriteImageFlag = flag;
+}
+
+void ossimImageFileWriter::setWriteHistogramFlag(bool flag)
+{
+   theWriteHistogramFlag = flag;
+}
+
+void ossimImageFileWriter::setWriteEnviHeaderFlag(bool flag)
+{
+   theWriteEnviHeaderFlag = flag;
+}
+
+void ossimImageFileWriter::setWriteExternalGeometryFlag(bool flag)
+{
+   theWriteExternalGeometryFlag = flag;
+}
+
+void ossimImageFileWriter::setWriteFgdcFlag(bool flag)
+{
+   theWriteFgdcFlag = flag;
+}
+
+void ossimImageFileWriter::setWriteJpegWorldFile(bool flag)
+{
+   theWriteJpegWorldFileFlag  = flag;
+}
+
+void ossimImageFileWriter::setWriteReadme(bool flag)
+{
+   theWriteReadmeFlag = flag;
+}
+
+void ossimImageFileWriter::setWriteTiffWorldFile(bool flag)
+{
+   theWriteTiffWorldFileFlag  = flag;
+}
+
+ossimObject* ossimImageFileWriter::getObject()
+{
+   return this;
+}
+
+const ossimObject* ossimImageFileWriter::getObject() const
+{
+   return this;
+}
+
+void ossimImageFileWriter::setAreaOfInterest(const ossimIrect& inputRect)
+{
+   ossimImageWriter::setAreaOfInterest(inputRect);
+   if(theInputConnection)
+   {
+      theInputConnection->setAreaOfInterest(inputRect);
+   }
+}
+
+ossimImageSourceSequencer* ossimImageFileWriter::getSequencer()
+{
+   return theInputConnection;
+}
+
+bool ossimImageFileWriter::execute()
+{
+   static const char MODULE[] = "ossimImageFileWriter::execute";
+   
+   if (!theInputConnection) // Must have a sequencer...
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:\ntheInputConnection is NULL!" << endl;
+      }
+      return false;
+   }
+   
+   if (theFilename == "") // Must have a filename...
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:\ntheFilename is empty!" << endl;
+      }
+      return false;
+   }
+   
+   // make sure we have a region of interest
+   if(theAreaOfInterest.hasNans())
+   {
+      theInputConnection->initialize();
+      theAreaOfInterest = theInputConnection->getAreaOfInterest();
+   }
+   else
+   {
+      theInputConnection->setAreaOfInterest(theAreaOfInterest);
+   }
+
+   if(theAreaOfInterest.hasNans()) // Must have an area of interest...
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " ERROR:  Area of interest has nans!"
+            << "Area of interest:  "
+            << theAreaOfInterest
+            << "\nReturning..." << endl;
+      }
+
+      return false;
+   }
+
+   setProcessStatus(ossimProcessInterface::PROCESS_STATUS_EXECUTING);
+   setPercentComplete(0.0);
+   bool wroteFile = true;
+   if (theWriteImageFlag)
+   {
+      wroteFile = writeFile();
+   }
+   
+   if(needsAborting())
+   {
+      setProcessStatus(ossimProcessInterface::PROCESS_STATUS_ABORTED);
+   }
+   else
+   {
+      setProcessStatus(ossimProcessInterface::PROCESS_STATUS_NOT_EXECUTING);
+   }
+
+   if(getProcessStatus() != ossimProcessInterface::PROCESS_STATUS_ABORTED)
+   {
+      // Do these only on the master process. Note left to right precedence!
+      if (getSequencer() && getSequencer()->isMaster())
+      {
+         if (wroteFile)
+         {
+            if (writeMetaDataFiles() == false)
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "Write of overview file failed!" << endl;
+               return false;
+            }
+         }
+         
+      } // End of "if (getSequencer() && getSequencer()->isMaster()))
+   }
+   
+   return true;
+}
+
+void ossimImageFileWriter::setPercentComplete(double percentComplete)
+{
+   ossimProcessInterface::setPercentComplete(percentComplete);
+   ossimProcessProgressEvent event(this, percentComplete);
+   fireEvent(event);
+}
+
+void ossimImageFileWriter::setOutputName(const ossimString& outputName)
+{
+   ossimImageWriter::setOutputName(outputName);
+   setFilename(ossimFilename(outputName));
+}
+
+void ossimImageFileWriter::setFilename(const ossimFilename& file)
+{
+   theFilename = file;
+}
+
+const ossimFilename& ossimImageFileWriter::getFilename()const
+{
+   return theFilename;
+}
+
+bool ossimImageFileWriter::canConnectMyInputTo(ossim_int32 inputIndex,
+                                               const ossimConnectableObject* object)const
+{
+   return (object&&
+           ( (PTR_CAST(ossimImageSourceInterface, object)&&inputIndex == 0)||
+             (PTR_CAST(ossimViewController, object)&&inputIndex == 1)) );
+}
+
+ossim_uint16 ossimImageFileWriter::getOverviewCompressType() const
+{
+   return theOverviewCompressType;
+}
+
+ossim_int32  ossimImageFileWriter::getOverviewJpegCompressQuality() const
+{
+   return theOverviewJpegCompressQuality;
+}
+
+void ossimImageFileWriter::setOverviewCompressType(ossim_uint16 type)
+{
+   theOverviewCompressType = type;
+}
+
+void ossimImageFileWriter::setOverviewJpegCompressQuality(ossim_int32 quality)
+{
+   theOverviewJpegCompressQuality = quality;
+}
+
+void ossimImageFileWriter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property) return;
+   
+   if(property->getName() == ossimKeywordNames::FILENAME_KW)
+   {
+      theFilename = property->valueToString();
+   }
+   else if (property->getName() == "create_envi_hdr")
+   {
+      theWriteEnviHeaderFlag = property->valueToString().toBool();
+   }
+   else if (property->getName() ==
+            ossimKeywordNames::CREATE_EXTERNAL_GEOMETRY_KW)
+   {
+      theWriteExternalGeometryFlag = property->valueToString().toBool();
+   }
+   else if (property->getName() == "create_fgdc")
+   {
+      theWriteFgdcFlag = property->valueToString().toBool();
+   }
+   else if (property->getName() == "create_jpeg_world_file")
+   {
+      theWriteJpegWorldFileFlag = property->valueToString().toBool();
+   }
+   else if (property->getName() == "create_readme")
+   {
+      theWriteReadmeFlag = property->valueToString().toBool();
+   }
+   else if (property->getName() == "create_tiff_world_file")
+   {
+      theWriteTiffWorldFileFlag = property->valueToString().toBool();
+   }
+   else if (property->getName() == ossimKeywordNames::CREATE_IMAGE_KW)
+   {
+      theWriteImageFlag = property->valueToString().toBool();
+   }
+   else if (property->getName() == ossimKeywordNames::CREATE_OVERVIEW_KW)
+   {
+      theWriteOverviewFlag = property->valueToString().toBool();
+   }
+   else if (property->getName() == ossimKeywordNames::CREATE_HISTOGRAM_KW)
+   {
+      theWriteHistogramFlag = property->valueToString().toBool();
+   }
+   else
+   {
+      ossimImageWriter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimImageFileWriter::getProperty(const ossimString& name)const
+{
+   if(name == ossimKeywordNames::FILENAME_KW)
+   {
+      ossimFilenameProperty* filenameProp =
+         new ossimFilenameProperty(name, theFilename);
+
+      filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_OUTPUT);
+
+      return filenameProp;
+   }
+   else if (name == "create_envi_hdr")
+   {
+      return new ossimBooleanProperty(name, theWriteEnviHeaderFlag);
+   }
+   else if (name == ossimKeywordNames::CREATE_EXTERNAL_GEOMETRY_KW)
+   {
+      return new ossimBooleanProperty(name, theWriteExternalGeometryFlag);
+   }
+   else if (name == "create_fgdc")
+   {
+      return new ossimBooleanProperty(name, theWriteFgdcFlag);
+   }
+   else if (name == "create_jpeg_world_file")
+   {
+      return new ossimBooleanProperty(name, theWriteJpegWorldFileFlag);
+   }
+   else if (name == "create_readme")
+   {
+      return new ossimBooleanProperty(name, theWriteReadmeFlag);
+   }
+   else if (name == "create_tiff_world_file")
+   {
+      return new ossimBooleanProperty(name, theWriteTiffWorldFileFlag);
+   }
+   else if (name == ossimKeywordNames::CREATE_IMAGE_KW)
+   {
+      return new ossimBooleanProperty(name, theWriteImageFlag);
+   }
+   else if (name == ossimKeywordNames::CREATE_OVERVIEW_KW)
+   {
+      return new ossimBooleanProperty(name, theWriteOverviewFlag);
+   }
+   else if (name == ossimKeywordNames::CREATE_HISTOGRAM_KW)
+   {
+      return new ossimBooleanProperty(name, theWriteHistogramFlag);
+   }
+
+   return ossimImageWriter::getProperty(name);
+}
+
+void ossimImageFileWriter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageWriter::getPropertyNames(propertyNames);
+
+   propertyNames.push_back(ossimString(ossimKeywordNames::FILENAME_KW));
+   propertyNames.push_back(ossimString("create_envi_hdr"));  
+   propertyNames.push_back(ossimString(ossimKeywordNames::CREATE_EXTERNAL_GEOMETRY_KW));
+   propertyNames.push_back(ossimString("create_fgdc"));
+   propertyNames.push_back(ossimString("create_jpeg_world_file"));
+   propertyNames.push_back(ossimString("create_readme"));
+   propertyNames.push_back(ossimString("create_tiff_world_file"));
+   propertyNames.push_back(ossimString(ossimKeywordNames::CREATE_IMAGE_KW));
+   propertyNames.push_back(ossimString(ossimKeywordNames::CREATE_OVERVIEW_KW));
+   propertyNames.push_back(ossimString(ossimKeywordNames::CREATE_HISTOGRAM_KW));
+}
+
+bool ossimImageFileWriter::hasImageType(const ossimString& imageType) const
+{
+   std::vector<ossimString> imageTypeList;
+   getImageTypeList(imageTypeList);
+
+   std::vector<ossimString>::const_iterator i = imageTypeList.begin();
+
+   while (i != imageTypeList.end())
+   {
+      if ( (*i) == imageType )
+      {
+         return true;
+      }
+      ++i;
+   }
+
+   return false; // not found...
+}
+
+bool ossimImageFileWriter::addListener(ossimListener* listener)
+{
+   theProgressListener = listener;
+   return ossimImageWriter::addListener(listener);
+}
+
+bool ossimImageFileWriter::removeListener(ossimListener* listener)
+{
+   if (listener == theProgressListener)
+   {
+      theProgressListener = NULL;
+   }
+   return ossimImageWriter::removeListener(listener);
+}
+
+void ossimImageFileWriter::setTileSize(const ossimIpt& tileSize)
+{
+   if (theInputConnection)
+   {
+      theInputConnection->setTileSize(tileSize);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageFileWriter.h b/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageFileWriter.h
new file mode 100644
index 0000000000..f6774fd0f2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageFileWriter.h
@@ -0,0 +1,319 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Frank Warmerdam (warmerdam@pobox.com)
+//
+// Description:
+//
+// Contains class declaration for ossimImageWriter
+//*******************************************************************
+//  $Id: ossimImageFileWriter.h,v 1.39 2006/01/06 16:46:46 dburken Exp $
+
+#ifndef ossimImageFileWriter_HEADER
+#define ossimImageFileWriter_HEADER
+#include <fstream>
+#include <imaging/ossimImageWriter.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/common/events/ossimConnectableObjectListener.h>
+#include <base/common/ossimProcessInterface.h>
+#include <base/common/events/ossimObjectEvents.h>
+#include <base/common/events/ossimProcessProgressEvent.h>
+#include <base/common/ossimViewController.h>
+
+/**
+ * Pure virtual base class for image file writers.
+ *
+ * There is normally one subclass of this class for each format supported
+ * for writing.  This class roughly corresponds to the ImageHandler class
+ * used for reading images.  Format specific ossimImageWriter's are normally
+ * instantiated by the ossimImageWriterFactory::createWriterInstance() method.
+ * ossimImageWriters should not be directly instantiated by application code.
+ */
+
+class OSSIMDLLEXPORT ossimImageFileWriter
+   :  public ossimImageWriter,
+      public ossimProcessInterface,
+      public ossimConnectableObjectListener
+{   
+public:
+
+   /**
+    * The writer will own the sequencer.
+    */
+   ossimImageFileWriter(const ossimFilename& filename = ossimFilename(),
+                        ossimImageSource* inputSource=0,
+                        ossimObject* owner=0);
+   
+   virtual ~ossimImageFileWriter();
+   
+   virtual ossimObject* getObject();
+
+   virtual const ossimObject* getObject()const;
+
+   /**
+    * void getImageTypeList(std::vector<ossimString>& imageTypeList)const
+    *
+    * pure virtual
+    * 
+    * Appends the writers image types to the "imageTypeList".
+    * 
+    * This is the actual image type name.  So for
+    * example, ossimTiffWriter has several image types.  Some of these
+    * include TIFF_TILED, TIFF_TILED_BAND_SEPARATE ... etc.
+    * The ossimGdalWriter
+    * may include GDAL_IMAGINE_HFA, GDAL_RGB_NITF, GDAL_JPEG20000, ... etc.
+    *
+    * @param imageTypeList stl::vector<ossimString> list to append to.
+    *
+    * @note All writers should append to the list, not, clear it and then add
+    * their types.
+    */
+   virtual void getImageTypeList(std::vector<ossimString>& imageTypeList)const=0;
+
+   /**
+    * bool hasImageType(const ossimString& imageType) const
+    *
+    * @param imageType string representing image type.
+    *
+    * @return true if "imageType" is supported by writer.
+    */
+   virtual bool hasImageType(const ossimString& imageType) const;
+
+   /**
+    * Sets the output image tiling size if supported by the writer.  If not
+    * supported this simply sets the sequencer(input) tile size.
+    */
+   virtual void setTileSize(const ossimIpt& tileSize);
+
+   /**
+    * Will write an envi header file.  If "theFilename" is "foo.tif"
+    * then this will write out "foo.hdr".
+    */
+   virtual bool writeEnviHeaderFile() const;
+
+   /**
+    * Will write an external geometry file.  If "theFilename" is "foo.tif"
+    * then this will write out "foo.geom".
+    */
+   virtual bool writeExternalGeometryFile() const;
+
+   /**
+    * Will write an fgdc file.  If "theFilename" is "foo.tif"
+    * then this will write out "foo.xml".
+    */
+   virtual bool writeFgdcFile() const;
+
+   /**
+    * Returns true on success, false on error.
+    */
+   virtual bool writeHistogramFile() const;
+
+   /**
+    * Will write a jpeg world file.  If "theFilename" is "foo.tif"
+    * then this will write out "foo.jpw".
+    */
+   virtual bool writeJpegWorldFile() const;
+
+   /**
+    * Write out an ossim overview file from the source_file.
+    * If source file is "foo.tif", this will create a "foo.ovr" in
+    * the same directory.
+    *
+    * @param source_file The file to create overview from.
+    *
+    * @param tiff_compress_type valid types:
+    * - COMPRESSION_JPEG
+    * - COMPRESSION_DEFLATE
+    * - COMPRESSION_PACKBITS
+    * - COMPRESSION_NONE=1 (default)
+    *
+    * @param jpeg_compress_quality Compression quality.  Only valid with
+    * COMPRESSION_JPEG. Range 1 to 100 with 100 being the best.
+    * default = 75
+    *
+    * @return true on success, false on error.
+    */
+   virtual bool writeOverviewFile(ossim_uint16 tiff_compress_type = 1,
+                                  ossim_int32 jpeg_compress_quality = 75)const;
+
+   /**
+    * Will write a readme file.  If "theFilename" is "foo.tif"
+    * then this will write out "foo_readme.txt".
+    */
+   virtual bool writeReadmeFile() const;
+
+   /**
+    * Will write a readme file.  If "theFilename" is "foo.tif"
+    * then this will write out "foo.tfw".
+    */
+   virtual bool writeTiffWorldFile() const;
+
+   /**
+    * Convenience method that calls meta data write methods that are flagged
+    * to be called.  Attempts to write all files flagged to be written even
+    * if one file writer returns false.
+    *
+    * Currently calls these methods if flagged:
+    * writeEnviHeaderFile
+    * writeExternalGeometryFile
+    * writeFgdcFile
+    * writeJpegWorldFile
+    * writeReadmeFile
+    * writeTiffWorldFile
+    * writeOverviewFile
+    * writeHistogramFile
+    *
+    * @return true if all files flagged are written, false if not.
+    */
+   virtual bool writeMetaDataFiles() const;
+
+   virtual void setAreaOfInterest(const ossimIrect& inputRect);
+
+   virtual void changeSequencer(ossimImageSourceSequencer* sequencer);
+
+   virtual ossimImageSourceSequencer* getSequencer();
+
+   virtual void initialize();
+
+   /**
+    * Calls:
+    * writeFile()
+    * writeMetaDataFiles()
+    *
+    * @return true on success, false on error.
+    */
+   virtual bool execute();
+
+   virtual void setPercentComplete(double percentComplete);
+
+   virtual void  setOutputImageType(ossim_int32 type);
+   virtual void  setOutputImageType(const ossimString& type);
+   virtual ossim_int32 getOutputImageType() const;
+   virtual ossimString getOutputImageTypeString() const;
+   
+   virtual void setOutputName(const ossimString& outputName);
+
+   virtual void setFilename(const ossimFilename& file);
+
+   virtual const ossimFilename& getFilename()const;
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+
+   virtual bool canConnectMyInputTo(ossim_int32 inputIndex,
+                                    const ossimConnectableObject* object)const;
+   
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+   virtual void propertyEvent(ossimPropertyEvent& event);
+
+   /**
+   * Control flags...
+   */
+
+   virtual bool         getWriteImageFlag()            const;
+   virtual bool         getWriteHistogramFlag()        const;
+   virtual bool         getWriteOverviewFlag()         const;
+
+   virtual bool         getWriteEnviHeaderFlag()       const;
+   virtual bool         getWriteExternalGeometryFlag() const;
+   virtual bool         getWriteFgdcFlag()             const;
+   virtual bool         getWriteJpegWorldFileFlag()    const;
+   virtual bool         getWriteReadmeFlag()           const;
+   virtual bool         getWriteTiffWorldFileFlag()    const;
+
+   virtual void         setWriteImageFlag(bool flag);
+   virtual void         setWriteOverviewFlag(bool flag);
+   virtual void         setWriteHistogramFlag(bool flag);
+
+   virtual void         setWriteEnviHeaderFlag(bool flag);
+   virtual void         setWriteExternalGeometryFlag(bool flag);
+   virtual void         setWriteFgdcFlag(bool flag);
+   virtual void         setWriteJpegWorldFile(bool flag);
+   virtual void         setWriteReadme(bool flag);
+   virtual void         setWriteTiffWorldFile(bool flag);
+   
+   virtual ossim_uint16 getOverviewCompressType() const;
+   virtual ossim_int32  getOverviewJpegCompressQuality() const;
+
+   virtual void         setOverviewCompressType(ossim_uint16 type);
+   virtual void         setOverviewJpegCompressQuality(ossim_int32 quality);
+
+   
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   /**
+    * Overrides base "addListener" this will capture the pointer and then call
+    * the base class "addListener".  If overview building is enabled, the
+    * listener will be passed to the overview builder::addListener, and
+    * subsequently removed from the overview builder after the build overview
+    * call is complete.  This it transparent to the caller of this method.
+    *
+    * @param listener The listener to add.
+    *
+    * @return Currently always returns true.
+    *
+    * @note Callers still should call "removeListener" after the writing
+    * process is complete.
+    *
+    * @note If called more than once, theProgressListener will contain
+    * the latest listener.
+    */
+   virtual bool addListener(ossimListener* listener);
+
+   /**
+    * Overrides base "removeListener".  Calls base "removeListener which will
+    * find and removes the listener.
+    * If "theProgressListener" pointer matches listener "theProgressListener"
+    * will be set to NULL.
+    *
+    * @param listener The listener to remove.
+    *
+    * @return Currently always returns true.
+    */
+   virtual bool removeListener(ossimListener* listener);
+   
+protected:
+   /**
+    * Write out the file.
+    * @return true on success, false on error.
+    */
+   virtual bool writeFile() = 0;
+   
+   ossimImageSourceSequencer* theInputConnection;
+   ossimViewController*       theViewController;
+   ossimListener*             theProgressListener;
+   ossimFilename              theFilename;
+   ossimString                theOutputImageType;
+   bool                       theWriteImageFlag;
+   bool                       theWriteOverviewFlag;
+   bool                       theWriteHistogramFlag;
+   ossim_uint16               theOverviewCompressType;
+   ossim_int32                theOverviewJpegCompressQuality;
+
+   /**
+    * External meta data writer flags.  Not really part of an image writer, put
+    * here for convenience.  If true the writer will do the connection work
+    * for you.
+    */
+   bool                       theWriteEnviHeaderFlag;
+   bool                       theWriteExternalGeometryFlag;
+   bool                       theWriteFgdcFlag;
+   bool                       theWriteJpegWorldFileFlag;
+   bool                       theWriteReadmeFlag;
+   bool                       theWriteTiffWorldFileFlag;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageHandler.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageHandler.cpp
new file mode 100644
index 0000000000..226c2e8077
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageHandler.cpp
@@ -0,0 +1,1228 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// This class defines an abstract image handler which all loaders should
+// derive from.
+//
+//*******************************************************************
+//  $Id: ossimImageHandler.cpp,v 1.100 2005/12/06 20:58:29 dburken Exp $
+
+#include <algorithm>
+
+#include <imaging/formats/ossimImageHandler.h>
+#include <base/property/ossimStringProperty.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/events/ossimEventIds.h>
+#include <base/common/events/ossimContainerEvent.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+#include <imaging/formats/tiff/ossimTiffOverviewBuilder.h>
+#include <imaging/histogram/ossimHistogramWriter.h>
+#include <imaging/histogram/ossimImageHistogramSource.h>
+#include <base/common/ossimStdOutProgress.h>
+#include <base/data_types/ossimPolygon.h>
+#include <projections/ossimProjection.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/property/ossimFilenameProperty.h>
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+
+RTTI_DEF1(ossimImageHandler, "ossimImageHandler", ossimImageSource)
+
+//***
+// Static trace for debugging
+//***
+static ossimTrace traceDebug("ossimImageHandler:debug");
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimImageHandler.cpp,v 1.100 2005/12/06 20:58:29 dburken Exp $";
+#endif
+
+   
+ossimImageHandler::ossimImageHandler()
+      :
+      ossimImageSource(NULL,
+                       0,
+                       0,
+                       true,
+                       false),// output list is not fixed
+      theImageFile(ossimFilename::NIL),
+      theOverview(NULL),
+      theSubImageOffset(0, 0),
+      theValidImageVertices(0),
+      theMetaData(),
+      theGeometryKwl()
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandler::ossimImageHandler() DEBUG:" << std::endl;
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "OSSIM_ID:  "
+         << OSSIM_ID
+         << std::endl;
+#endif      
+   }
+}
+
+ossimImageHandler::~ossimImageHandler()
+{
+	
+   if (theOverview)
+   {
+      delete theOverview;
+      theOverview = NULL;
+   }
+   
+}
+
+void ossimImageHandler::initialize()
+{
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimImageHandler::saveState(ossimKeywordlist& kwl,
+                                  const char* prefix) const
+{
+   static const char MODULE[] = "ossimImageHandler::saveState";
+
+   ossimImageSource::saveState(kwl, prefix);
+   if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE
+         << " ERROR detected in keyword list!  State not saved."
+         << std::endl;
+      return false;
+   }
+
+   kwl.add(prefix,
+           ossimKeywordNames::FILENAME_KW,
+           theImageFile.c_str(),
+           true);
+
+   return true;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimImageHandler::loadState(const ossimKeywordlist& kwl,
+                                  const char* prefix)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandler::loadState(kwl, prefix) DEBUG: entered ..."
+         << std::endl;
+   }
+   static const char MODULE[] = "ossimImageHandler::loadState";
+
+   ossimImageSource::loadState(kwl, prefix);
+   
+   if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE
+         << "WARNING: error detected in keyword list!  State not load."
+         << std::endl;
+      
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimImageHandler::loadState(kwl, prefix) DEBUG: "
+            << "leaving with error in kwl ..." << std::endl;
+      }
+      return false;
+   }
+
+    const char* lookup = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+    if (!lookup)
+    {
+       // Deprecated...
+       lookup = kwl.find(prefix, ossimKeywordNames::IMAGE_FILE_KW);
+    }
+    
+    if (lookup)
+    {
+       theImageFile = lookup;
+
+    }
+    
+    if(traceDebug())
+    {
+       ossimNotify(ossimNotifyLevel_DEBUG)
+          << "filename = " << theImageFile << std::endl;
+    }
+
+   // Check for an valid image vetices file.
+   lookup = kwl.find(prefix, "valid_vertices_file");
+   if (lookup)
+   {
+      initVertices(lookup);
+   }
+
+   if(getNumberOfInputs())
+   {
+      theInputObjectList.clear();
+   }
+   theInputListIsFixedFlag = true;
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandler::loadState(kwl, prefix) DEBUG: Leaving Ok ..."
+         << std::endl;
+   }
+   return true;
+}
+
+bool ossimImageHandler::initVertices(const char* file)
+{
+   static const char MODULE[] = "ossimImageHandler::initVertices";
+
+   ossimFilename f = file;
+   if (!f.exists()) return false;
+
+   ossimKeywordlist kwl(file);
+   
+   if (kwl.getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimImageHandler::initVertices NOTICE:"
+            << "\nError reading valid vertice file:  " << file << std::endl;
+      }
+      return false;
+   }
+
+   // Clean out any old vertices...
+   theValidImageVertices.clear();
+
+   int32 number_of_points = kwl.numberOf("point", "x");
+
+   for (int32 i=0; i<number_of_points; ++i)
+   {
+      ossimIpt pt;
+      const char* lookup;
+      ossimString p = "point";
+      p += ossimString::toString(i);
+      
+      ossimString px = p + ".x";
+      lookup = kwl.find(px.c_str());
+      if (lookup)
+      {
+         pt.x = atoi(lookup);
+      }
+      else
+      {
+         if (traceDebug())
+         {
+            CLOG << " ERROR:"
+                 << "\nlookup failed for:  " << px.c_str()
+                 << "\nReturning..."
+                 << std::endl;
+         }
+         return false;
+      }
+         
+      ossimString py = p + ".y";
+      lookup = kwl.find(py.c_str());
+      if (lookup)
+      {
+         pt.y = atoi(lookup);
+      }
+      else
+      {
+         if (traceDebug())
+         {
+            CLOG << " ERROR:"
+                 << "\nLookup failed for:  " << py.c_str()
+                 << "\nReturning..."
+                 << std::endl;
+         }
+         return false;
+      }
+
+      theValidImageVertices.push_back(pt);
+   }
+
+   
+   if (traceDebug())
+   {
+      CLOG << " DEBUG:"
+           << "\nVertices file:  " << f
+           << "\nValid image vertices:"
+           << std::endl;
+      for (ossim_uint32 i=0; i<theValidImageVertices.size(); ++i)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "\npoint[" << i << "]:  " << theValidImageVertices[i];
+      }
+      ossimNotify(ossimNotifyLevel_DEBUG) << std::endl;
+   }
+   
+   return true;
+}
+
+ossim_uint32 ossimImageHandler::getNumberOfDecimationLevels() const
+{
+   return (theOverview?theOverview->getNumberOfDecimationLevels():1);
+}
+
+ossim_uint32 ossimImageHandler::getNumberOfReducedResSets() const
+{
+   return getNumberOfDecimationLevels();
+}
+
+ossimIrect ossimImageHandler::getImageRectangle(ossim_uint32 resLevel) const
+{
+   ossimIrect result;
+   
+   if( !isOpen() )
+   {
+      result.makeNan();
+      return result;
+   }
+   
+   if( isValidRLevel(resLevel) )
+   {
+      ossim_int32 lines   = getNumberOfLines(resLevel);
+      ossim_int32 samples = getNumberOfSamples(resLevel);
+      if(ossimIsNan(lines) || ossimIsNan(samples))
+      {
+         result.makeNan();
+      }
+      else
+      {
+         result = ossimIrect(0, 0, samples-1, lines-1);
+      }
+   }
+   
+   //---
+   // Special case to handle overviews with no R0.
+   //---
+   else if( isValidRLevel(resLevel+1) )
+   {
+      ossim_int32 lines   = getNumberOfLines(resLevel+1);
+      ossim_int32 samples = getNumberOfSamples(resLevel+1);
+      if( (ossimIsNan(lines)== false) && (ossimIsNan(samples) == false) )
+      {
+         result = ossimIrect(0, 0, samples*2-1, lines*2-1);
+      }
+      else
+      {
+         result.makeNan();
+      }
+   }
+   
+   return result;
+}
+
+ossimIrect ossimImageHandler::getBoundingRect(ossim_uint32 resLevel) const
+{
+   ossimIrect result = getImageRectangle(resLevel);
+
+   if (result.isNan() == false)
+   {
+      ossimIpt offset = getSubImageOffset(resLevel);
+      if (offset.isNan() == false)
+      {
+         result = result + offset;
+      }
+   }
+
+   return result;
+}
+
+
+void ossimImageHandler::getDecimationFactor(ossim_uint32 resLevel,
+                                            ossimDpt& result) const
+{
+   if (resLevel == 0)
+   {
+      result.x = 1.0;
+      result.y = 1.0;
+   }
+   else
+   {
+      result.x = 1.0 / pow((double)2, (double)resLevel);
+      result.y = result.x;
+   }
+}
+
+void ossimImageHandler::getDecimationFactors(vector<ossimDpt>& decimations) const
+{
+   const ossim_uint32 LEVELS = getNumberOfDecimationLevels();
+   decimations.resize(LEVELS);
+   for (ossim_uint32 level = 0; level < LEVELS; ++level)
+   {
+      getDecimationFactor(level, decimations[level]);
+   }
+}
+
+bool ossimImageHandler::buildHistogram(int numberOfRLevels)
+{
+   if(isOpen())
+   {
+      ossimFilename file =
+         getFilenameWithThisExtension(ossimString(".his"));
+      
+      ossimImageHistogramSource* histoSource = new ossimImageHistogramSource;
+      ossimHistogramWriter* writer = new ossimHistogramWriter;
+      
+      if(numberOfRLevels)
+      {
+         histoSource->setMaxNumberOfRLevels(numberOfRLevels);
+      }
+      else
+      {
+         histoSource->setMaxNumberOfRLevels(getNumberOfDecimationLevels());
+      }
+      histoSource->connectMyInputTo(0, this);
+      histoSource->enableSource();
+      writer->connectMyInputTo(0, histoSource);
+      writer->setFilename(file);
+      writer->addListener(&theStdOutProgress);
+      writer->execute();
+      
+      delete histoSource;
+      delete writer;
+   }
+   else
+   {
+      return false;
+   }
+   
+   return true;
+}
+
+bool ossimImageHandler::buildAllHistograms(int numberOfRLevels)
+{
+   ossim_uint32 currentEntry = getCurrentEntry();
+   std::vector<ossim_uint32> entryList;
+   getEntryList(entryList);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < entryList.size(); ++idx)
+   {
+      setCurrentEntry(entryList[idx]);
+      if(!buildHistogram(numberOfRLevels))
+      {
+         setCurrentEntry(currentEntry);
+         return false;
+      }
+   }
+   
+   setCurrentEntry(currentEntry);
+   return true;
+}
+
+bool ossimImageHandler::buildOverview(ossimImageHandlerOverviewCompressionType compressionType,
+                                      ossim_uint32 quality,
+                                      ossimFilterResampler::ossimFilterResamplerType resampleType,
+                                      bool includeFullResFlag)
+{
+   ossimFilename file = getFilenameWithThisExtension(ossimString(".ovr"));
+
+   if(buildOverview(file, compressionType, quality, resampleType, includeFullResFlag))
+   {
+      openOverview();
+   }
+
+   return true;
+}
+
+bool ossimImageHandler::buildAllOverviews(ossimImageHandlerOverviewCompressionType compressionType,
+                                          ossim_uint32 quality,
+                                          ossimFilterResampler::ossimFilterResamplerType resampleType,
+                                          bool includeFullResFlag)
+{
+   ossim_uint32 currentEntry = getCurrentEntry();
+   std::vector<ossim_uint32> entryList;
+   getEntryList(entryList);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < entryList.size(); ++idx)
+   {
+      setCurrentEntry(entryList[idx]);
+      if(!buildOverview(compressionType, quality, resampleType, includeFullResFlag))
+      {
+         setCurrentEntry(currentEntry);
+         return false;
+      }
+   }
+   
+   setCurrentEntry(currentEntry);
+   return true;
+}
+
+
+bool ossimImageHandler::buildOverview(const ossimFilename& filename,
+                                      ossimImageHandlerOverviewCompressionType compressionType,
+                                      ossim_uint32 quality,
+                                      ossimFilterResampler::ossimFilterResamplerType resampleType,
+                                      bool includeFullResFlag)
+{
+   closeOverview();
+   if(!isOpen())
+   {
+      return false;
+   }
+
+   ossimTiffOverviewBuilder tiffBuilder(this);
+   ossim_uint16 cType = COMPRESSION_NONE;
+   switch(compressionType)
+   {
+      case OSSIM_OVERVIEW_COMPRESSION_NONE:
+      {
+         cType = COMPRESSION_NONE;
+         break;
+      }
+      case OSSIM_OVERVIEW_COMPRESSION_JPEG:
+      {
+         cType = COMPRESSION_JPEG;
+         break;
+      }
+      case OSSIM_OVERVIEW_COMPRESSION_LZW:
+      {
+         cType = COMPRESSION_LZW;
+         break;
+      }
+      case OSSIM_OVERVIEW_COMPRESSION_DEFLATE:
+      {
+
+         cType = COMPRESSION_DEFLATE;
+         break;
+      }
+      case OSSIM_OVERVIEW_COMPRESSION_PACKBITS:
+      {
+         cType = COMPRESSION_PACKBITS;
+         break;
+      }
+   }
+   tiffBuilder.setJpegCompressionQuality(quality);
+   tiffBuilder.setCompressionType(cType);
+   tiffBuilder.setResampleType(resampleType);
+   tiffBuilder.buildOverview(filename, includeFullResFlag);
+
+   return true;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimImageHandler::getImageGeometry(ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandler::getImageGeometry DEBUG: entered..."
+         << std::endl;
+   }
+   
+   if (theGeometryKwl.getSize())
+   {
+      kwl = theGeometryKwl;
+      return true;
+   }
+   
+   bool result = false;
+   ossimProjection* proj = NULL;
+   ossimFilename filename = getFilenameWithThisExtension(ossimString(".geom"));
+   if(!filename.exists())
+   {
+      // Try tacking on the entry like "foo_e0.hdf".
+      filename = getFilenameWithThisExtension(ossimString(".geom"), true);
+   }
+   if(filename.exists())
+   {
+      if(kwl.addFile(filename))
+      {
+         ossimString tempPrefix =
+            "image"+ossimString::toString(getCurrentEntry())+".";
+         kwl.stripPrefixFromAll(tempPrefix);
+         
+         if(kwl.find(ossimKeywordNames::TYPE_KW))
+         {
+            ossimKeywordlist kwlTemp(kwl);
+            
+            kwlTemp.add(ossimKeywordNames::GEOM_FILE_KW,
+                        filename.c_str(),
+                        true);
+
+            proj = ossimProjectionFactoryRegistry::instance()->
+               createProjection(kwlTemp);
+            if(proj)
+            {
+//               proj->saveState(kwl, prefix);
+               delete proj;
+               proj = NULL;
+               
+               result = true;
+               kwl = kwlTemp;
+            }
+         }
+      }
+   }
+
+   if(!result)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimImageHandler::getImageGeometry DEBUG:"
+            << "\nCalling createProjection"
+            << "\ngetFilename():      " << getFilename()
+            << "\ngetCurrentEntry():  " << getCurrentEntry()
+            << std::endl;
+      }
+      
+      proj = ossimProjectionFactoryRegistry::instance()->
+         createProjection(getFilename(),
+                          getCurrentEntry());
+      if(proj)
+      {
+         result = proj->saveState(kwl, prefix);
+         delete proj;
+         proj = NULL;
+         
+         result = true;
+      }
+   }
+   
+   if (result == true)
+   {
+      // Capture the geometry for next time.
+      theGeometryKwl = kwl;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandler::getImageGeometry DEBUG:"
+         << "boolean return:  " << result
+         << std::endl;
+   }
+   
+   return result;
+}
+
+void ossimImageHandler::setImageGeometry(const ossimKeywordlist& kwl)
+{
+   theGeometryKwl = kwl;
+}
+
+void ossimImageHandler::saveImageGeometry() const
+{
+   ossimFilename geometryFile =
+      getFilenameWithThisExtension(ossimString(".geom"));
+   saveImageGeometry(geometryFile);
+}
+
+void ossimImageHandler::saveImageGeometry(
+   const ossimFilename& geometry_file) const
+{
+   theGeometryKwl.write(geometry_file.c_str());
+}
+
+void ossimImageHandler::closeOverview()
+{
+   if(theOverview)
+   {
+      delete theOverview;
+      theOverview = NULL;
+   }
+}
+
+// const ossimFilename& ossimImageHandler::getOverviewFile()const
+// {
+//    return theOverviewFile;
+// }
+
+bool ossimImageHandler::hasOverviews() const
+{
+   return (getNumberOfDecimationLevels() > 1);
+}
+
+bool ossimImageHandler::openOverview(const ossimFilename& overview_file)
+{
+   closeOverview();
+
+   // make sure we don't open ourselves.
+   if(theImageFile == overview_file) return false;
+   
+   theOverview = new ossimTiffTileSource;
+
+   if ( theOverview->open(overview_file) )
+   {
+      //---
+      // This is not really a container event; however, using for now.
+      //---
+      ossimContainerEvent event(this, theOverview, OSSIM_EVENT_ADD_OBJECT_ID);
+      fireEvent(event);
+
+      return true;
+   }
+
+   delete theOverview;
+   theOverview = NULL;
+   return false;
+}
+
+bool ossimImageHandler::openOverview()
+{
+   closeOverview();
+
+   ossimFilename overviewFilename = createOverviewFilename();
+   
+   // 1) If the current over file exists see if if can be opened.
+   if( overviewFilename.exists() )
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Looking for " << overviewFilename
+            << " overview file..." << std::endl;
+      }
+
+      if ( openOverview(overviewFilename) )
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "Opened overview " << overviewFilename
+               << std::endl;
+         }
+         return true;
+      }
+   }
+   
+   // For backward compatibility check if single entry and _e0.ovr
+   overviewFilename = getFilenameWithThisExtension(ossimString(".ovr"), true);
+   if ( overviewFilename.exists() )
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Looking for " << overviewFilename
+            << " overview file..." << std::endl;
+      }
+   
+      if ( openOverview(overviewFilename) )
+      {
+         return true;
+      }
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageHandler::openOverview NOTICE:"
+         << "\nCould not find an overview." << std::endl;
+   }
+
+   return false;
+}
+
+
+bool ossimImageHandler::writeValidImageVertices(const std::vector<ossimIpt>& vertices, const ossimFilename& file)
+{
+   ossimFilename tempFile = file;
+   if(tempFile == "")
+   {
+      tempFile = createValidVerticesFilename();
+   }
+   ossim_uint32 i = 0;
+   ossimKeywordlist tempKwl;
+   ossimPolygon poly(vertices);
+   
+   poly.checkOrdering();
+
+   // Capture the vertices.
+   theValidImageVertices = vertices;
+   
+   if(poly.getOrdering() == OSSIM_COUNTERCLOCKWISE_ORDER)
+   {
+      std::reverse(theValidImageVertices.begin(), theValidImageVertices.end());
+   }
+   
+   if(theValidImageVertices.size())
+   {
+      for(i = 0; i < theValidImageVertices.size(); ++i)
+      {
+         ossimString prefix = ossimString("point") + ossimString::toString(i) + ".";
+         tempKwl.add(prefix.c_str(),
+                     "x",
+                     theValidImageVertices[i].x,
+                     true);
+	 tempKwl.add(prefix.c_str(),
+                     "y",
+                     theValidImageVertices[i].y,
+                     true);
+      }
+      
+      tempKwl.write(tempFile.c_str());
+   }
+
+   if ( tempFile.exists() )
+   {
+      return true;
+   }
+
+   return false; // Write of file failed.
+}
+
+bool ossimImageHandler::openValidVertices(const ossimFilename& vertices_file)
+{
+   return initVertices(vertices_file);
+}
+
+bool ossimImageHandler::openValidVertices()
+{
+   ossimFilename vertices_file;
+   vertices_file = theImageFile.path();
+   vertices_file = vertices_file.dirCat(theImageFile.fileNoExtension());
+   if(getNumberOfEntries() > 1)
+   {
+      vertices_file += ossimString("_vertices") + "_e" + ossimString::toString(getCurrentEntry()) + ".kwl";
+   }
+   else
+   {
+      vertices_file += "_vertices.kwl";
+   }
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "Looking for " << vertices_file
+         << " vertices file..." << std::endl;
+   }
+
+   return openValidVertices(vertices_file);
+}
+
+bool ossimImageHandler::open(const ossimFilename& imageFile)
+{
+   if(isOpen())
+   {
+      close();
+   }
+
+   setFilename(imageFile);
+   
+   return open();
+}
+
+bool ossimImageHandler::open(const ossimFilename& imageFile,
+                             ossim_uint32 entryIndex)
+{
+   if(isOpen())
+   {
+      close();
+   }
+   setFilename(imageFile);
+   
+   bool result = open();
+
+   if(result)
+   {
+      return setCurrentEntry(entryIndex);
+   }
+
+   return result;
+}
+
+bool ossimImageHandler::isValidRLevel(ossim_uint32 resLevel) const
+{
+   if (resLevel < getNumberOfDecimationLevels())
+   {
+      return true;
+   }
+
+   return false;
+}
+
+void ossimImageHandler::getValidImageVertices(vector<ossimIpt>& validVertices,
+                                              ossimVertexOrdering ordering,
+                                              ossim_uint32 resLevel) const
+{
+   ossimDpt decimation;
+   getDecimationFactor(resLevel, decimation);
+   if(decimation.hasNans())
+   {
+      return;
+   }
+   if (theValidImageVertices.size() != 0)
+   {
+      validVertices.clear();
+      for (ossim_uint32 i=0; i<theValidImageVertices.size(); ++i)
+      {
+         ossimIpt pt(irint(theValidImageVertices[i].x*decimation.x),
+                     irint(theValidImageVertices[i].y*decimation.y));
+         validVertices.push_back(pt);
+      }
+
+      if(ordering == OSSIM_COUNTERCLOCKWISE_ORDER)
+      {
+         std::reverse(validVertices.begin()+1, validVertices.end());
+      }
+   }
+   else
+   {
+      // Call the base class method which will set to bounding rectangle.
+      ossimImageSource::getValidImageVertices(validVertices, ordering, resLevel);
+   }
+}
+
+void ossimImageHandler::close()
+{
+   if (theOverview)
+   {
+      delete theOverview;
+      theOverview = NULL;
+   }
+
+   theValidImageVertices.clear();
+}
+
+bool ossimImageHandler::isBandSelector() const
+{
+   return false;
+}
+
+bool ossimImageHandler::setOutputBandList(const std::vector<ossim_uint32>& band_list)
+{
+   return false;
+}
+
+bool ossimImageHandler::isImageTiled() const
+{
+   return (getImageTileWidth() && getImageTileHeight());
+}
+
+void ossimImageHandler::loadMetaData()
+{
+  theMetaData.clear();
+
+  ossimFilename filename = getFilenameWithThisExtension(ossimString(".omd"));
+  if(filename.exists())
+  {
+     ossimKeywordlist kwl;
+     
+     kwl.addFile(filename.c_str());
+     
+     theMetaData.loadState(kwl);
+  }
+  else
+  {
+     theMetaData.setScalarType(getOutputScalarType());
+  }
+}
+
+double ossimImageHandler::getMinPixelValue(ossim_uint32 band)const
+{
+   if(theMetaData.getNumberOfBands())
+   {
+      return theMetaData.getMinPix(band);
+   }
+   return ossimGetDefaultMin(getOutputScalarType());
+}
+
+double ossimImageHandler::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(theMetaData.getNumberOfBands())
+   {
+      return theMetaData.getMaxPix(band);
+   }
+   return ossimGetDefaultMax(getOutputScalarType());
+}
+
+double ossimImageHandler::getNullPixelValue(ossim_uint32 band)const
+{
+   if(theMetaData.getNumberOfBands())
+   {
+      return theMetaData.getNullPix(band);
+   }
+   
+   return ossimGetDefaultNull(getOutputScalarType());
+}
+
+
+ossim_uint32 ossimImageHandler::getCurrentEntry()const
+{
+   return 0;
+}
+
+bool ossimImageHandler::setCurrentEntry(ossim_uint32 /* entryIdx */)
+{
+   return true;
+}
+
+void ossimImageHandler::getEntryList(std::vector<ossim_uint32>& entryList)const
+{
+	entryList.push_back(0);
+}
+
+void ossimImageHandler::getEntryStringList(
+   std::vector<ossimString>& entryStringList) const
+{
+   std::vector<ossim_uint32> entryList;
+   getEntryList(entryList);
+
+   if (entryList.size())
+   {
+      entryStringList.resize(entryList.size());
+      for (ossim_uint32 i = 0; i < entryList.size(); ++i)
+      {
+         entryStringList[i] = ossimString::toString(entryList[i]);
+      }
+   }
+}
+
+ossim_uint32 ossimImageHandler::getNumberOfEntries()const
+{
+   std::vector<ossim_uint32> tempList;
+   getEntryList(tempList);
+   
+   return tempList.size();
+}
+
+
+void ossimImageHandler::completeOpen()
+{
+  loadMetaData();
+  openOverview();
+  openValidVertices();
+}
+
+bool ossimImageHandler::canConnectMyInputTo(ossim_int32 inputIndex,
+                                            const ossimConnectableObject* /* object */)const
+{      
+   return false;
+}
+
+bool ossimImageHandler::hasMetaData()const
+{
+   return theMetaData.isValid();
+}
+
+ossimIpt ossimImageHandler::getSubImageOffset(ossim_uint32 resLevel) const
+{
+   if (resLevel == 0)
+   {
+      return theSubImageOffset;
+   }
+
+   ossimIpt offset;
+   offset.makeNan();
+   if (isValidRLevel(resLevel))
+   {
+      ossimDpt decimation;
+      getDecimationFactor(resLevel, decimation);
+      if(!decimation.hasNans()) // Should never have nans...
+      {
+         offset.x = irint(theSubImageOffset.x*decimation.x);
+         offset.y = irint(theSubImageOffset.y*decimation.y);
+      }
+   }
+   return offset;
+}
+
+void ossimImageHandler::setSubImageOffset(const ossimIpt& p)
+{
+   theSubImageOffset = p;
+}
+
+void ossimImageHandler::setFilename(const ossimFilename& filename)
+{
+   theImageFile = filename;
+}
+
+const ossimFilename& ossimImageHandler::getFilename()const
+{
+   return theImageFile;
+}
+
+
+void ossimImageHandler::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(property->getName() == ossimKeywordNames::ENTRY_KW)
+   {
+      setCurrentEntry(property->valueToString().toUInt32());
+   }
+   else
+   {
+      ossimImageSource::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimImageHandler::getProperty(const ossimString& name)const
+{
+
+   if(name == ossimKeywordNames::ENTRY_KW)
+   {
+      std::vector<ossim_uint32> entryList;
+      getEntryList(entryList);
+      
+      ossimStringProperty* stringProperty = new ossimStringProperty(name,
+                                                                    ossimString::toString(getCurrentEntry()));
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < entryList.size(); ++idx)
+      {
+         stringProperty->addConstraint(ossimString::toString(entryList[idx]));
+      }
+      stringProperty->setFullRefreshBit();
+      stringProperty->setEditableFlag(false);
+
+      return stringProperty;
+   }
+   if(name == "histogram_filename")
+   {
+      ossimFilenameProperty* filenameProp =
+         new ossimFilenameProperty(name, createHistogramFilename());
+      
+      filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      filenameProp->setCacheRefreshBit();
+      
+      return filenameProp;
+      
+   }
+   if(name == "geometry_filename")
+   {
+      ossimFilenameProperty* filenameProp =
+         new ossimFilenameProperty(name, createGeometryFilename());
+      
+      filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      filenameProp->setCacheRefreshBit();
+      
+      return filenameProp;
+      
+   }
+   if(name == "valid_vertices_filename")
+   {
+      ossimFilenameProperty* filenameProp =
+         new ossimFilenameProperty(name, createValidVerticesFilename());
+      
+      filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      filenameProp->setCacheRefreshBit();
+      
+      return filenameProp;
+   }
+   if(name == "metadata_filename")
+   {
+      ossimFilenameProperty* filenameProp =
+         new ossimFilenameProperty(name, createMetadataFilename());
+      
+      filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      filenameProp->setCacheRefreshBit();
+      
+      return filenameProp;
+   }
+   if(name == "overview_filename")
+   {
+      ossimFilenameProperty* filenameProp =
+         new ossimFilenameProperty(name, createOverviewFilename());
+      
+      filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      filenameProp->setCacheRefreshBit();
+      
+      return filenameProp;
+   }
+   if(name == "filename")
+   {
+      ossimFilenameProperty* filenameProp =
+         new ossimFilenameProperty(name, getFilename());
+      
+      filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      filenameProp->setFullRefreshBit();
+      
+      return filenameProp;
+   }
+   
+   return ossimImageSource::getProperty(name);
+}
+
+void ossimImageHandler::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSource::getPropertyNames(propertyNames);
+   propertyNames.push_back(ossimKeywordNames::ENTRY_KW);
+}
+
+ossimFilename ossimImageHandler::getFilenameWithThisExtension(
+   const ossimString& ext,
+   bool set_e0_prefix) const
+{
+   // Get the image file.
+   ossimFilename f = getFilename();
+
+   // Wipe out the extension.
+   f.setExtension("");
+
+   if (set_e0_prefix || (getNumberOfEntries() > 1))
+   {
+      f += "_e";
+      f += ossimString::toString(getCurrentEntry());
+   }
+   if (ext.size())
+   {
+      if (ext[0] != '.')
+      {
+         f += ".";
+      }
+      f += ext;
+   }
+   return f;
+}
+
+ossimRefPtr<ossimNBandLutDataObject> ossimImageHandler::getLut()const
+{
+   return theLut;
+}
+
+ossimFilename ossimImageHandler::createOverviewFilename() const
+{
+   return getFilenameWithThisExtension("ovr");
+}
+   
+ossimFilename ossimImageHandler::createGeometryFilename() const
+{
+   return getFilenameWithThisExtension("geom");
+}
+
+ossimFilename ossimImageHandler::createMetadataFilename() const
+{
+   return getFilenameWithThisExtension("omd");
+}
+
+ossimFilename ossimImageHandler::createHistogramFilename() const
+{
+   return getFilenameWithThisExtension("his");
+}
+
+ossimFilename ossimImageHandler::createValidVerticesFilename() const
+{
+   ossimFilename result;
+   
+   result = theImageFile.path();
+   result = result.dirCat(theImageFile.fileNoExtension());
+   result += "_vertices";
+   if(getNumberOfEntries() > 1)
+   {
+      result += "_e";
+      result += ossimString::toString(getCurrentEntry());
+   }
+   result += ".kwl";
+   
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageHandler.h b/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageHandler.h
new file mode 100644
index 0000000000..d5bd307b1a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/ossimImageHandler.h
@@ -0,0 +1,564 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description:
+//
+// This class defines an abstract image handler which all loaders should
+// derive from.
+//
+//********************************************************************
+// $Id: ossimImageHandler.h,v 1.67 2005/10/13 13:30:33 gpotts Exp $
+#ifndef ossimImageHandler_HEADER
+#define ossimImageHandler_HEADER
+
+#include <imaging/ossimImageSource.h>
+#include <imaging/ossimImageMetaData.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimNBandLutDataObject.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <imaging/resample/ossimFilterResampler.h>
+class ossimTiffTileSource;
+
+/**
+ *  This class defines an abstract Handler which all image handlers(loaders)
+ *  should derive from.
+ */
+class OSSIMDLLEXPORT ossimImageHandler : public ossimImageSource
+{
+public:
+
+   enum ossimImageHandlerOverviewCompressionType
+   {
+      OSSIM_OVERVIEW_COMPRESSION_NONE= 0,
+      OSSIM_OVERVIEW_COMPRESSION_JPEG,
+      OSSIM_OVERVIEW_COMPRESSION_LZW,
+      OSSIM_OVERVIEW_COMPRESSION_DEFLATE,
+      OSSIM_OVERVIEW_COMPRESSION_PACKBITS
+   };
+
+   /**
+    * Constructor (default):
+    */
+   ossimImageHandler();
+
+   /**
+    * Destructor:
+    * Derived classes should implement.
+    */
+   virtual ~ossimImageHandler();
+
+   //virtual ossimObject* dup()const;
+   /**
+    * initialize
+    * Does nothing in this class.  Implemented to satisfy pure virtual.
+    */
+   virtual void initialize();
+   
+   /**
+    *  Searches for an overview.  Uses theImageFile as a key.
+    *  If theImageFile = "foo.tif" it will look for "foo.ovr" first,
+    *  then "foo_ovr.tif" next.
+    *  Calls openOverview(const ossimFilename& overview_file)
+    *  @return true on success, false on error.
+    *  @see openOverview(const ossimFilename& overview_file)
+    */
+   virtual bool openOverview();
+
+   /**
+    *  Calls closeOverview(), then attempts to open the overview_file.
+    *  On success, theOverviewFile will be set and theOverview will be
+    *  initialized.  On failure, theOverviewFile will be cleared and
+    *  theOverview deleted and set to NULL.
+    *  @param overview_file ossimFilename representing overview file.
+    *  @return true on success, false on error.
+    *  @see closeOverview()
+    */
+   virtual bool openOverview(const ossimFilename& overview_file);
+
+   /**
+    *  If theOverview is initialized it will be deleted and set to NULL. Also
+    *  clears theOverviewFile.
+    *  @return void
+    */
+   virtual void closeOverview();
+   
+   /**
+    *  @return true if getNumberOfReducedResSets > 1, false if not.
+    *  @see getNumberOfReducedResSets()
+    */
+   virtual bool hasOverviews() const;
+
+   /**
+    *  @return ossimFilename represents an external OSSIM overview filename.
+    */
+   virtual ossimFilename createOverviewFilename() const;
+   
+   /**
+    *  @return ossimFilename represents an external OSSIM geometry filename.
+    */
+   virtual ossimFilename createGeometryFilename() const;
+
+   /**
+    *  @return ossimFilename represents an external OSSIM metadata filename.
+    */
+   virtual ossimFilename createMetadataFilename() const;
+
+   
+
+   /**
+    *  @return ossimFilename represents an external OSSIM histogram filename.
+    */
+   virtual ossimFilename createHistogramFilename() const;
+
+   /**
+    *  @return ossimFilename represents an external OSSIM valid vertices filename.
+    */
+   virtual ossimFilename createValidVerticesFilename() const;
+   
+
+   /**
+    *  Outputs vertices to file and updates the internal vertex
+    *  array variable "theValidImageVertices".
+    *  @param vertices Array of ossimIpts to write.
+    *  @param file Name of output file to write to.  If file is empty, the
+    *  output file will be the image file with no extension + _vertices.kwl.
+    *  So if the image is "foo.tif" you'll get "foo_vertices.kwl".
+    *  @return true on success, false on error.
+    */
+   virtual bool writeValidImageVertices(const std::vector<ossimIpt>& vertices, 
+					const ossimFilename& file=ossimFilename(""));
+
+   /**
+    *  Opens the valid image vertices file and sets theValidImageVerticesFile
+    *  variable.
+    *  @param vertices_file File name containing valid vertices for image.
+    *  @return true on success, false on error.
+    */
+   virtual bool openValidVertices(const ossimFilename& vertices_file);
+
+   /**
+    *  Creates vertices file name based on image, then tries to open.
+    *  If theImageFile = "foo.tif" it will look for "foo_vertices.kwl".
+    *  @return true on success, false on error.
+    */
+   virtual bool openValidVertices();
+
+
+   /**
+    *  Pure virtual open.  Derived classes must implement.
+    *  
+    *  @return Returns true on success, false on error.
+    *
+    *  @note This method relies on the data member ossimImageData::theImageFile
+    *  being set.  Callers should do a "setFilename" prior to calling this
+    *  method or use the ossimImageHandler::open that takes a file name and an
+    *  entry index.
+    */
+   virtual bool open() = 0;
+
+   /**
+    *  Opens the image file.
+    *  
+    *  @param imageFile File to open.
+    *
+    *  @param entryIndex
+    *  @return true on success, false on error.
+    */
+   virtual bool open(const ossimFilename& imageFile,
+                     ossim_uint32 entryIndex);
+
+   virtual bool open(const ossimFilename& imageFile);
+
+   /**
+    *  Deletes the overview and clears the valid image vertices.  Derived
+    *  classes should implement.
+    */
+   virtual void close();
+
+   /**
+    *  Derived classes must implement this method to be concrete.
+    *
+    *  @return true if open, false if not.
+    */
+   virtual bool isOpen()const=0;
+
+   /**
+    *  Build a histogram for image file.
+    *
+    *  @param numberOfRLevels sets the maximum number of reduced resolution
+    *  level to compute histogram for.
+    *
+    *  @return true on success, false if not open.
+    */
+   virtual bool buildHistogram(int numberOfRLevels=0);
+   virtual bool buildAllHistograms(int numberOfRLevels=0);
+   
+   /**
+    *  Will build over file for theImageFile.
+    *
+    *  @param includeFullResFlag if true the full resolution layer will also
+    *  be put in the overview format.  This is handly for inefficeint formats.
+    */
+   virtual bool buildOverview(ossimImageHandlerOverviewCompressionType compressionType = OSSIM_OVERVIEW_COMPRESSION_NONE,
+                              ossim_uint32 quality = 75,
+                              ossimFilterResampler::ossimFilterResamplerType resampleType = ossimFilterResampler::ossimFilterResampler_BOX,
+                              bool includeFullResFlag=false);
+
+   virtual bool buildAllOverviews(ossimImageHandlerOverviewCompressionType compressionType = OSSIM_OVERVIEW_COMPRESSION_NONE,
+                                  ossim_uint32 quality = 75,
+                                  ossimFilterResampler::ossimFilterResamplerType resampleType = ossimFilterResampler::ossimFilterResampler_BOX,
+                                  bool includeFullResFlag=false);
+   
+   /**
+    *  Will build an over file for filename.
+    *  @param filename Name of image file.
+    *
+    *  @param includeFullResFlag if true the full resolution layer will also
+    *  be put in the overview format.  This is handly for inefficeint formats.
+    */
+   virtual bool buildOverview(const ossimFilename& filename,
+                              ossimImageHandlerOverviewCompressionType compressionType = OSSIM_OVERVIEW_COMPRESSION_NONE,
+                              ossim_uint32 quality = 75,
+                              ossimFilterResampler::ossimFilterResamplerType resampleType = ossimFilterResampler::ossimFilterResampler_BOX,
+                              bool includeFullResFlag=false);
+   
+   /**
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *
+    *  @param kwl Keyword list that will be initialized with geometry info.
+    *  Returns true if geometry info is present, false if not.
+    *
+    *  @param prefix The prefix is added to the resulting keyword list
+    *  keywords.  So is you if you pass in a prefix of "image01.", the
+    *  keyword ul_lat will be like:  "image01.ul_lat:  -40.00000"
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+
+   /**
+    * Sets the image geometry keyword list.
+    *
+    * @note Callers should note that this will override any existing
+    *       geometry.
+    *
+    * @note This does not write the geometry to disk, to do so call
+    *       one of the saveImageGeometry methods. 
+    */
+   virtual void setImageGeometry(const ossimKeywordlist& kwl);
+
+   /**
+    * Saves the image geometry to a file that will be made based on the image
+    * file name.
+    */
+   virtual void saveImageGeometry() const;
+   
+   /**
+    * Saves the image geometry to a file that will be made based on the image
+    * file name.
+    */
+   virtual void saveImageGeometry(const ossimFilename& geometry_file) const;   
+   
+   /**
+    *  Pure virtual, derived classes must implement.
+    *
+    *  @param resLevel Reduced resolution level to return lines of.
+    *  Default = 0
+    *
+    *  @return The number of lines for specified reduced resolution level.
+    */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel = 0) const = 0;
+
+   /**
+    *  Pure virtual, derived classes must implement.
+    *
+    *  @param resLevel Reduced resolution level to return samples of.
+    *  Default = 0
+    *
+    *  @return The number of samples for specified reduced resolution level.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel = 0) const = 0;
+   
+   /**
+    * Returns the zero-based (relative) image rectangle for the reduced
+    * resolution data set (rrds) passed in.  Note that rrds 0 is the highest
+    * resolution rrds.
+    */
+   virtual ossimIrect getImageRectangle(ossim_uint32 resLevel = 0) const; 
+
+   /**
+    * Returns the absolute bounding rectangle of the image. The upper left
+    * corner may be non-zero if this is a subimage.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel = 0) const;
+
+   /**
+    * @param resLevel Reduced resolution set for requested decimation.
+    *
+    * @param result ossimDpt to initialize with requested decimation.
+    * 
+    * @note Initialized "result" with the decimation factor for the passed in
+    * resLevel.
+    * Most of the time the returned factor is a square decimation along x
+    * and y indicated by result.x and .y  = 1.0/(resLevel^2) where ^
+    * means rasing to the power of.  If the resLevel is 1 then the return
+    * decimation .5, .5. this is not the decimation to each resolution
+    * level but the total decimation from res level 0.
+    * So if resLevel is 2 then the return is .25, .25.
+    *
+    * @note Derived classes should override if the decimation is anything other
+    * than a power of two change in each direction per res level.
+    */
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result) const;
+
+   /**
+    * This returns all decimation for all levels.
+    */
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations) const;
+
+   /**
+    * This returns the total number of decimation levels.  It is important to
+    * note that res level 0 or full resolution is included in the list and has
+    * decimation values 1.0, 1.0
+    */
+   virtual ossim_uint32 getNumberOfDecimationLevels()const;
+
+   /**
+    * This method is obsolete.  Please use getNumberOfDecimationLevels.
+    *
+    * For backwards compatibility this calls getNumberOfDecimationLevels.
+    */
+   virtual ossim_uint32 getNumberOfReducedResSets()const;
+   
+   /**
+    * @param resLevel Reduced resolution set for requested offset.
+    * 
+    * @return Returns the offset between the relative image rectangle and
+    * the absolute, or full, image rectangle. This is typically (0,0) unless
+    * this is a sub-image.  If a resLevel other than zero is requested the
+    * decimation factor will be applied to offset.  If resLevel is not valid
+    * an the ossimIpt returned will be nan's.
+    */
+   ossimIpt getSubImageOffset(ossim_uint32 resLevel) const;
+
+   /**
+    * Permits initializing this sub-image's offset relative to full image space.
+    */
+   void setSubImageOffset(const ossimIpt& p);
+
+   /**
+    * Sets the filename
+    */
+   virtual void setFilename(const ossimFilename& filename);
+
+   /**
+    * Returns the filename
+    */
+   virtual const ossimFilename& getFilename()const;
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * Determines if the passed in reslution level is valid
+    */
+   virtual bool isValidRLevel(ossim_uint32 resLevel) const;
+
+   /**
+    * Connection rule.  Since image handler currently don't have any
+    * inputs this will just return false saying we can't connect anything
+    * to an image handler.
+    */
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object) const;
+      
+   /**
+    * ordering specifies how the vertices should be arranged.
+    * valid image vertices is basically the tightly fit convex hull
+    * of the image.  Usually an image has NULL values and are
+    * internally not upright rectangular.  This can cause
+    * problems some spatial filters.
+    *
+    * The default implementation is to return the bounding rect.
+    */
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const;
+
+   /**
+    * Indicates whether or not the image handler can control output
+    * band selection via the setOutputBandList method.
+    */
+   virtual bool isBandSelector() const;
+
+   /**
+    * If the image handler "isBandSeletor()" then the band selection
+    * of the output chip can be controlled.
+    * Returns true on success, false on error.
+    */
+   virtual bool setOutputBandList(const std::vector<ossim_uint32>& band_list);
+
+   /**
+    * Indicates whether or not the image is tiled internally.
+    * This implementation returns true if (getImageTileWidth() &&
+    * getImageTileHeight()) are both non zero.
+    * Override in the image handler if something else is desired.
+    * Returns true if tiled, false if not.
+    */
+   virtual bool isImageTiled() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const = 0;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const = 0;
+
+   virtual bool hasMetaData() const;
+
+   virtual ossimRefPtr<ossimNBandLutDataObject> getLut()const;
+   
+   /**
+    * There is an external file with an omd extension.  this file contains
+    * additional information about the image such as the null pixel, min and
+    * max values.
+    * For general raster it will contain much more than that.
+    */
+   void loadMetaData();
+
+   /**
+    * Retuns the min pixel value.  If there was an external eta data file
+    * then use the meta data from that file.  If not given then we will
+    * return the default min
+    */
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+
+   /**
+    * @return The current entry number.
+    *
+    * @note This implementation returns 0.  Derived classes should override
+    * if of multiple entry image type.
+    */
+   virtual ossim_uint32 getCurrentEntry()const;
+
+   /**
+    * @return The number of entries (images) in the image file.
+    */
+   virtual ossim_uint32 getNumberOfEntries()const;
+
+   /**
+    * @param entryList This is the list to initialize with entry indexes.
+    *
+    * @note This implementation returns puts one entry "0" in the list.
+    */
+   virtual void getEntryList(std::vector<ossim_uint32>& entryList) const;
+
+   /**
+    * @param entryStringList List to initialize with strings associated with
+    * entries.
+    *
+    * @note This implementation calls getEntryList and converts entries in
+    * the list to strings.  Derived classes that support multiple entries
+    * with associated strings should re-implement.
+    */
+   virtual void getEntryStringList(
+      std::vector<ossimString>& entryStringList) const;
+   
+   /**
+    * @param entryIdx Entry number to select.
+    *
+    * @note The implementation does nothing.  Derived classes that handle
+    * multiple images should override.
+    *
+    * @return true if it was able to set the current entryadn false otherwise
+    */
+   virtual bool setCurrentEntry(ossim_uint32 entryIdx);
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   /**
+   * Returns the image file with extension set.
+   *
+   * Examples:
+   * 
+   * - theImageFile          = "foo.hdf"
+   * - The number of entries = 1
+   * - ext parameter         = "geom"
+   * - return of method will = "foo.geom"
+   *
+   * - theImageFile          = "foo.hdf"
+   * - The number of entries = 12
+   * - The current entry     = 3
+   * - ext parameter         = "geom"
+   * - return of method will = "foo_e3.geom"
+   *
+   * @param ext Extension to tack onto file.  Can have or have not ".", it will
+   * be added if "." is not the first character.
+   *
+   * @param set_e0_prefix If true and the number of entries = 1 then
+   * "foo.geom" would come out "foo_e0.geom" instead. Default = false.
+   * 
+   * @return theImageFile with sent extension.
+   */
+  ossimFilename getFilenameWithThisExtension(const ossimString& ext,
+                                             bool set_e0_prefix=false) const;
+   
+protected:
+   /**
+    *  Opens file and attempts to initialize the valid image vertices.
+    *  Returns true on success, false on error.
+    */
+  bool initVertices(const char* file);
+  
+  /**
+   * Will complete the opening process.  
+   * If there are overviews it will open them. 
+   * If there is meta data it will open that and if there
+   * is valid vertices it will open that.
+   */
+  void completeOpen();
+
+   ossimFilename        theImageFile;
+   ossimTiffTileSource* theOverview;
+   ossimIpt             theSubImageOffset;
+   vector<ossimIpt>     theValidImageVertices;
+   ossimImageMetaData   theMetaData;
+   ossimKeywordlist     theGeometryKwl;
+   ossimRefPtr<ossimNBandLutDataObject> theLut;
+   
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimImageHandler_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/srtm/ossimSrtmTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/srtm/ossimSrtmTileSource.cpp
new file mode 100644
index 0000000000..4e9b3adad7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/srtm/ossimSrtmTileSource.cpp
@@ -0,0 +1,145 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Image handler class for a Shuttle Radar Topography Mission (SRTM) file.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimSrtmTileSource.cpp,v 1.4 2005/06/15 14:15:22 gpotts Exp $
+
+#include <imaging/formats/srtm/ossimSrtmTileSource.h>
+#include <base/data_types/ossimDirectory.h>
+#include <base/common/ossimTrace.h>
+#include <support_data/srtm/ossimSrtmSupportData.h>
+
+RTTI_DEF1_INST(ossimSrtmTileSource,
+               "ossimSrtmTileSource",
+               ossimGeneralRasterTileSource)
+
+static ossimTrace traceDebug("ossimSrtmTileSource:debug");
+
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimSrtmTileSource::ossimSrtmTileSource()
+   :
+   ossimGeneralRasterTileSource(),
+   theSrtmSupportData()
+{
+}
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimSrtmTileSource::ossimSrtmTileSource(const ossimKeywordlist& kwl,
+                                               const char* prefix)
+   :
+   ossimGeneralRasterTileSource(),
+   theSrtmSupportData()
+{
+   if (loadState(kwl, prefix) == false)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+}
+
+//*******************************************************************
+// Destructor:
+//*******************************************************************
+ossimSrtmTileSource::~ossimSrtmTileSource()
+{
+}
+
+bool ossimSrtmTileSource::open()
+{
+   static const char MODULE[] = "ossimSrtmTileSource::open";
+   
+   if (traceDebug())
+   {
+      CLOG << " Entered..." << endl
+           << " trying to open file " << theImageFile << std::endl;
+   }
+   
+   if (!theSrtmSupportData.setFilename(theImageFile, true))
+   {
+      if (traceDebug()) CLOG << " Unable to set filename"<< std::endl;
+      
+      return false;
+   }
+
+   bool result =  ossimGeneralRasterTileSource::open();
+   
+   if (traceDebug()) CLOG << " Exited with " << (result?"true":"false") << " ..."<< std::endl;
+   
+   return result;
+}
+   
+bool ossimSrtmTileSource::getImageGeometry(ossimKeywordlist& kwl,
+                                              const char* prefix)
+{
+   // Check for override for an external geometry file, or a previous save.
+   if(ossimImageHandler::getImageGeometry(kwl, prefix))
+   {
+      return true;
+   }
+
+   if (theSrtmSupportData.getImageGeometry(kwl, prefix))
+   {
+      // Capture for next time...
+      setImageGeometry(kwl);
+      return true;
+   }
+
+   return false;
+}
+
+bool ossimSrtmTileSource::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix)const
+{
+   if (theSrtmSupportData.saveState(kwl, prefix))
+   {
+      return ossimImageHandler::saveState(kwl,prefix);
+   }
+   return false;
+}
+
+bool ossimSrtmTileSource::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   if (theSrtmSupportData.loadState(kwl, prefix))
+   {
+      setFilename(theSrtmSupportData.getFilename());
+
+      if (ossimGeneralRasterTileSource::open())
+      {
+         // Must call to pick up id for connections.
+         return ossimImageSource::loadState(kwl, prefix);
+      }
+   }
+
+   return false;
+}
+
+ossimString ossimSrtmTileSource::getShortName() const
+{
+   return ossimString("SRTM");
+}
+   
+ossimString ossimSrtmTileSource::getLongName() const
+{
+   return ossimString("SRTM reader");
+}
+
+ossimString  ossimSrtmTileSource::className() const
+{
+   return ossimString("ossimSrtmTileSource");
+}
+ 
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/srtm/ossimSrtmTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/srtm/ossimSrtmTileSource.h
new file mode 100644
index 0000000000..bf74e6a484
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/srtm/ossimSrtmTileSource.h
@@ -0,0 +1,72 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Image handler class for a Shuttle Radar Topography Mission (SRTM) file.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimSrtmTileSource.h,v 1.2 2005/03/14 21:47:33 dburken Exp $
+#ifndef ossimSrtmTileSource_HEADER
+#define ossimSrtmTileSource_HEADER
+
+#include <imaging/formats/general_raster/ossimGeneralRasterTileSource.h>
+#include <support_data/srtm/ossimSrtmSupportData.h>
+
+
+class OSSIMDLLEXPORT ossimSrtmTileSource : public ossimGeneralRasterTileSource
+{
+public:
+   ossimSrtmTileSource();
+
+   ossimSrtmTileSource(const ossimKeywordlist& kwl,
+                       const char* prefix=0);
+   
+   virtual ~ossimSrtmTileSource();
+
+   virtual ossimString getShortName() const;
+   
+   virtual ossimString getLongName() const;
+
+   virtual ossimString  className() const;
+
+   virtual bool open();
+   
+   /**
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *
+    *  @return true if geometry info is present, false if not.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+
+   /**
+    * Method to save the state of an object to a keyword list.
+    * @return true on success, false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.
+    *
+    * @return true on success, false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = NULL);
+
+private:
+   ossimSrtmSupportData theSrtmSupportData;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/tiff/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimQuickbirdTiffTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimQuickbirdTiffTileSource.cpp
new file mode 100644
index 0000000000..c9da02fc88
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimQuickbirdTiffTileSource.cpp
@@ -0,0 +1,88 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+// 
+// Copied from ossimQuickbirdTiffTileSource written by Garrett Potts.
+//
+// Description:
+//
+// Class definition for specialized image handler to pick up offsets from
+// Quick Bird ".TIL" files.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimQuickbirdTiffTileSource.cpp,v 1.3 2006/01/06 16:46:46 dburken Exp $
+
+#include <imaging/formats/tiff/ossimQuickbirdTiffTileSource.h>
+#include <support_data/qb/ossimQuickbirdTile.h>
+#include <base/common/ossimTrace.h>
+
+RTTI_DEF1(ossimQuickbirdTiffTileSource,
+          "ossimQuickbirdTiffTileSource",
+          ossimTiffTileSource);
+
+static const ossimTrace traceDebug("ossimQuickbirdTiffTileSource:debug");
+
+bool ossimQuickbirdTiffTileSource::open()
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimQuickbirdTiffTileSource::open() DEBUG: entered ..."
+         << std::endl;
+   }
+   
+   ossimFilename file = theImageFile;
+   file = file.replaceAllThatMatch("_R[0-9]+C[0-9]+");
+   ossimQuickbirdTile tileFile;
+
+   file.setExtension("TIL");
+   if(!tileFile.open(file))
+   {
+      file.setExtension("til");
+      if(!tileFile.open(file))
+      {
+         return false;
+      }
+   }
+   
+   // Call the base class open...
+   if(!ossimTiffTileSource::open())
+   {
+      return false;
+   }
+   
+   ossimQuickbirdTileInfo info;
+   
+   // try upcase...
+   if(!tileFile.getInfo(info, theImageFile.file().upcase()))
+   {
+      // try downcase...
+      if(!tileFile.getInfo(info, theImageFile.file().downcase()))
+      {
+         return false;
+      }
+   }
+
+   if((info.theUlXOffset != OSSIM_INT_NAN) &&
+      (info.theUlYOffset != OSSIM_INT_NAN))
+   {
+      theSubImageOffset = ossimIpt(info.theUlXOffset, info.theUlYOffset);
+   }
+   else
+   {
+      theSubImageOffset = ossimIpt(0,0);
+   }
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimQuickbirdTiffTileSource::open() DEBUG:"
+         << "\nSub image offset  = " << theSubImageOffset
+         << std::endl;
+   }
+   
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimQuickbirdTiffTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimQuickbirdTiffTileSource.h
new file mode 100644
index 0000000000..b4e8a0bd45
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimQuickbirdTiffTileSource.h
@@ -0,0 +1,33 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+// 
+// Copied from ossimQuickbirdNitfTileSource written by Garrett Potts.
+//
+// Description:
+//
+// Class declaration for specialized image handler to pick up offsets from
+// Quick Bird ".TIL" files.
+// 
+//----------------------------------------------------------------------------
+// $Id: ossimQuickbirdTiffTileSource.h,v 1.1 2005/11/08 21:52:47 dburken Exp $
+#ifndef ossimQuickbirdTiffTileSource_HEADER
+#define ossimQuickbirdTiffTileSource_HEADER
+
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+
+class ossimQuickbirdTiffTileSource : public ossimTiffTileSource
+{
+public:
+  virtual bool open();
+
+ protected:
+
+TYPE_DATA   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffOverviewBuilder.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffOverviewBuilder.cpp
new file mode 100644
index 0000000000..a89d1a271c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffOverviewBuilder.cpp
@@ -0,0 +1,1580 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for TiffOverviewBuilder
+//*******************************************************************
+//  $Id: ossimTiffOverviewBuilder.cpp,v 1.44 2005/09/27 10:57:36 gpotts Exp $
+
+#include <cstring>
+#include <sstream>
+using namespace std;
+
+#include <tiffio.h>
+
+#include <imaging/formats/tiff/ossimTiffOverviewBuilder.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimErrorCodes.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/common/ossimStdOutProgress.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt3d.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageMetaData.h>
+#include <base/common/ossimTrace.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+
+RTTI_DEF3(ossimTiffOverviewBuilder, "ossimTiffOverviewBuilder", ossimSource, ossimProcessInterface, ossimConnectableObjectListener)
+
+static ossimTrace traceDebug("ossimTiffOverviewBuilder:degug");
+
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimTiffOverviewBuilder::
+ossimTiffOverviewBuilder(ossimImageHandler* imageHandler)
+   :
+      ossimSource(),
+      ossimProcessInterface(),
+      ossimConnectableObjectListener(),
+      theImageHandler(imageHandler),
+      theOutputFile(ossimFilename::NIL),
+      theNullDataBuffer(NULL),
+      theBytesPerPixel(1),
+      theBitsPerSample(8),
+      theTileWidth(0),
+      theTileHeight(0),
+      theTileSizeInBytes(0),
+      theSampleFormat(0),
+      theCurrentTiffDir(0),
+      theTiffCompressType(COMPRESSION_NONE),
+      theJpegCompressQuality(DEFAULT_COMPRESS_QUALITY),
+      theResampleType(ossimFilterResampler::ossimFilterResampler_BOX)
+{
+   static const char MODULE[]
+      = "ossimTiffOverviewBuilder::ossimTiffOverviewBuilder";
+   
+   if (!theImageHandler)
+   {
+      // Set the error...
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "\nNull image handler pointer passed to constructor! Returning..."
+         << endl;
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "%s File %s line %d\nNULL pointer passed to constructor!",
+                    MODULE,
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   else if (theImageHandler->getErrorStatus() ==
+            ossimErrorCodes::OSSIM_ERROR)
+   {
+      // Set the error...
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "\nError detected in image handler!  Returning..."
+         << endl;
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "%s file %s line %d\nImageHandler error detected!",
+                    MODULE,
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+
+   // Note:  Need a default overview tile size in preferences...
+   ossimIpt tileSize;
+   ossimGetDefaultTileSize(tileSize);
+   theTileWidth  = tileSize.x;
+   theTileHeight = tileSize.y;
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\ntheTileWidth:   " << theTileWidth
+           << "\ntheTileHeight:  " << theTileHeight
+           << "\nSource image is tiled:  "
+           << (theImageHandler->isImageTiled()?"true":"false")
+           << "\ntheImageHandler->getTileWidth():  "
+           << theImageHandler->getTileWidth()
+           << "\ntheImageHandler->getTileHeight():  "
+           << theImageHandler->getTileHeight()
+           << "\ntheImageHandler->getImageTileWidth():  "
+           << theImageHandler->getImageTileWidth()
+           << "\ntheImageHandler->getImageTileHeight():  "
+           << theImageHandler->getImageTileHeight()
+           << endl;
+   }
+
+   switch(theImageHandler->getOutputScalarType())
+   {
+      case OSSIM_UINT8:
+         theBitsPerSample = 8;
+         theBytesPerPixel = 1;
+         theSampleFormat  = SAMPLEFORMAT_UINT;
+         break;
+         
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+         theBitsPerSample = 16;
+         theBytesPerPixel = 2;
+         theSampleFormat  = SAMPLEFORMAT_UINT;
+         break;
+      
+      case OSSIM_SINT16:
+         theBitsPerSample = 16;
+         theBytesPerPixel = 2;
+         theSampleFormat  = SAMPLEFORMAT_INT;
+         break;
+
+      case OSSIM_UINT32:
+         theBitsPerSample = 32;
+         theBytesPerPixel = 4;
+         theSampleFormat  = SAMPLEFORMAT_UINT;
+         break;
+      
+      case OSSIM_FLOAT32:
+         theBitsPerSample = 32;
+         theBytesPerPixel = 4;
+         theSampleFormat  = SAMPLEFORMAT_IEEEFP;
+         break;
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         theBitsPerSample = 64;
+         theBytesPerPixel = 8;
+         theSampleFormat  = SAMPLEFORMAT_IEEEFP;
+         break;
+         
+      default:
+         // Set the error...
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " ERROR:"
+            << "\nUnknow pixel type:  "
+            << (ossimScalarTypeLut::instance()->
+                getEntryString(theImageHandler->getOutputScalarType()))
+            << endl;
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "Unknown pixel type!",
+                       __FILE__,
+                       __LINE__);
+         return;
+   }
+
+   theTileSizeInBytes = theTileWidth * theTileHeight * theBytesPerPixel;
+
+   //***
+   // Make a buffer to pass to pass to the write tile methods when an image
+   // handler returns a null tile.
+   //***
+   theNullDataBuffer = new ossim_uint8[theTileSizeInBytes];
+   
+   memset(theNullDataBuffer, 0, theTileSizeInBytes); // Fill it with zeroes.
+
+   // Set the output filename to a default.
+   theOutputFile = theImageHandler->getFilename();
+   if(theImageHandler->getNumberOfEntries() > 1)
+   {
+      ossim_uint32 currentEntry = theImageHandler->getCurrentEntry();
+      theOutputFile.setExtension("");
+      theOutputFile += "_e";
+      theOutputFile += ossimString::toString(currentEntry);
+      
+      //---
+      // Note:  Set extension was not used here deliberately to avoid messing
+      // up a MODIS file in hdf format with multiple '.'s in the file
+      // name.
+      //---
+      theOutputFile += ".ovr";
+   }
+   else
+   {
+      theOutputFile.setExtension("ovr");
+   }
+
+   if (theOutputFile == theImageHandler->getFilename())
+   {
+      // Don't allow this.
+      theOutputFile = ossimFilename::NIL;
+   }
+}
+
+//*******************************************************************
+// Destructor:
+//*******************************************************************
+ossimTiffOverviewBuilder::~ossimTiffOverviewBuilder()
+{
+   if (theNullDataBuffer)
+   {
+      delete [] theNullDataBuffer;
+      theNullDataBuffer = NULL;
+   }
+}
+
+void ossimTiffOverviewBuilder::setResampleType(ossimFilterResampler::ossimFilterResamplerType resampleType)
+{
+   theResampleType = resampleType;
+}
+
+//*******************************************************************
+// Public Method:
+//*******************************************************************
+bool
+ossimTiffOverviewBuilder::buildOverview(const ossimFilename& overview_file,
+                                        bool copy_all)
+{
+   static const char MODULE[] = "ossimTiffOverviewBuilder::buildOverview";
+
+   if (theErrorStatus == ossimErrorCodes::OSSIM_ERROR)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "\nError status has been previously set!  Returning..."
+         << endl;
+      return false;
+   }
+
+   if (overview_file == theImageHandler->getFilename() ||
+       overview_file == ossimFilename::NIL)
+   {
+      return false;
+   }
+   else
+   {
+      theOutputFile = overview_file;
+   }
+   
+   //***
+   // See if the file can be opened for writing.
+   // Note:  If this file existed previously it will be overwritten.
+   //***
+   TIFF* tif = TIFFOpen(overview_file.c_str(), "w");
+   if (!tif)
+   {
+      // Set the error...
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_OPEN_FILE_ERROR,
+                    "%s file %s line %d\nCannot open file:  %s",
+                    MODULE,
+                    __FILE__,
+                    __LINE__,
+                    overview_file.c_str());      
+      return false;
+   }
+
+   //---
+   // Check for a listeners.  If the list is empty, add a standard out listener
+   // so that command line apps like img2rr will get some progress.
+   //---
+   ossimStdOutProgress* progressListener = NULL;
+   if (theListenerList.empty())
+   {
+      progressListener = new ossimStdOutProgress(0, true);
+      addListener(progressListener);
+   }
+   
+   setProcessStatus(ossimProcessInterface::PROCESS_STATUS_EXECUTING);
+   setPercentComplete(0.0);
+
+   if (copy_all)
+   {
+      if (!writeR0(tif))
+      {
+         // Set the error...
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "File %s line %d\nError copying image!",
+                       __FILE__,
+                       __LINE__);
+         TIFFClose(tif);
+         if (progressListener)
+         {
+            removeListener(progressListener);
+            delete progressListener;
+            progressListener = NULL;
+         }
+         return false;
+      }
+   }   
+
+   if (needsAborting())
+   {
+      TIFFClose(tif);
+      if (progressListener)
+      {
+         removeListener(progressListener);
+         delete progressListener;
+         progressListener = NULL;
+      }
+      return false;
+   }
+   
+   //***
+   // Calculate the number of reduced resolution data sets (rrds).
+   // The image will be reduced until the smallest dimension is
+   // It will go all the way to a 1x1 pixel.
+   //***
+   ossim_int32 number_of_sets = getNumberOfSets();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " Number of reduced res sets:  " << number_of_sets
+         << endl;
+   }
+   
+   if (!number_of_sets)
+   {
+      ossimNotify(ossimNotifyLevel_INFO)
+         << MODULE << " NOTICE:"
+         << "\nFile size not large enough to require reduced resolution"
+         << " data sets."
+         << "\nReturning..." << endl;
+      TIFFClose(tif);
+      if (progressListener)
+      {
+         removeListener(progressListener);
+         delete progressListener;
+         progressListener = NULL;
+      }
+      return false;
+   }
+
+   if (!writeR1(tif))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error copying image!" << endl;
+      TIFFClose(tif);
+      if (progressListener)
+      {
+         removeListener(progressListener);
+         delete progressListener;
+         progressListener = NULL;
+      }
+      return false;
+   }
+   
+   if (needsAborting())
+   {
+      TIFFClose(tif);
+      if (progressListener)
+      {
+         removeListener(progressListener);
+         delete progressListener;
+         progressListener = NULL;
+      }
+      return false;
+   }
+   
+   if (number_of_sets > 1)
+   {
+      for (ossim_int32 i=2; i<=number_of_sets; ++i)
+      {
+         if (!writeRn(tif, overview_file, i))
+         {
+            // Set the error...
+            ossimSetError(getClassName(),
+                          ossimErrorCodes::OSSIM_WRITE_FILE_ERROR,
+                          "\
+%s file %s line %d\nError creating reduced res set!",
+                          MODULE,
+                          __FILE__,
+                          __LINE__);            
+            TIFFClose(tif);
+            if (progressListener)
+            {
+               removeListener(progressListener);
+               delete progressListener;
+               progressListener = NULL;
+            }
+            return false;
+         }
+         if (needsAborting())
+         {
+            TIFFClose(tif);
+            if (progressListener)
+            {
+               removeListener(progressListener);
+               delete progressListener;
+               progressListener = NULL;
+            }
+            return false;
+         }
+      }
+   }
+
+   // Close the tif file out.
+   TIFFClose(tif);
+   
+   ossimFilename file=overview_file;
+   file = file.setExtension("omd");
+   ossimKeywordlist kwl;
+   if(file.exists())
+   {
+      kwl.addFile(file.c_str());
+      
+   }
+   ossimImageMetaData metaData(theImageHandler->getOutputScalarType(),
+			       theImageHandler->getNumberOfInputBands());
+   
+   uint32 i= 0;
+   
+   for(i = 0; i < metaData.getNumberOfBands(); ++i)
+   {
+      metaData.setMinPix(i,  theImageHandler->getMinPixelValue(i));
+      metaData.setMaxPix(i,  theImageHandler->getMaxPixelValue(i));
+      metaData.setNullPix(i, theImageHandler->getNullPixelValue(i));
+   }
+   metaData.saveState(kwl);
+   kwl.write(file.c_str());
+
+   setCurrentMessage(ossimString("Finished..."));
+   
+   // Remove the listener if we had one.
+   if (progressListener)
+   {
+      removeListener(progressListener);
+      delete progressListener;
+      progressListener = NULL;
+   }
+
+   return true;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimTiffOverviewBuilder::writeR0(TIFF* tif)
+{
+   static const char MODULE[] = "ossimTiffOverviewBuilder::writeR0";
+
+   if (!setTags(tif, 0))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error writing tags!" << endl;
+      return false;
+   }
+   
+   ossim_int32 samples         = theImageHandler->getNumberOfSamples();
+   ossim_int32 lines           = theImageHandler->getNumberOfLines();
+   ossim_int32 tilesWide       = samples % theTileWidth ?
+                           samples / theTileWidth + 1 : samples / theTileWidth;
+   ossim_int32 tilesHigh       = lines % theTileHeight ?
+                           lines / theTileHeight + 1 : lines / theTileHeight;
+   ossim_int32 numberOfTiles   = tilesWide * tilesHigh;
+
+   int tileNumber = 0;
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimTiffOverviewBuilder::writeR0 DEBUG:"
+         << "\nsamples:        " << samples
+         << "\nlines:          " << lines
+         << "\ntilesWide:      " << tilesWide
+         << "\ntilesHigh:      " << tilesHigh
+         << "\nnumberOfTiles:  " << numberOfTiles
+         << endl;
+   }
+
+   setCurrentMessage(ossimString("Copying r0..."));
+   
+   //***
+   // Tile loop in the line direction.
+   //***
+   for(int i = 0; i < tilesHigh; ++i)
+   {
+      ossimIpt origin(0, 0);
+      origin.y = i * theTileHeight;
+      
+      //***
+      // Tile loop in the sample (width) direction.
+      //***
+      for(int j = 0; j < tilesWide; ++j)
+      {
+         origin.x = j * theTileWidth;
+
+         ossimRefPtr<ossimImageData> t =
+            theImageHandler->getTile(ossimIrect(origin.x,
+                                                origin.y,
+                                                origin.x +(theTileWidth-1),
+                                                origin.y +(theTileHeight-1)));
+	 
+         //***
+         // Band loop.
+         //***
+         for (uint32 band=0;
+              band<theImageHandler->getNumberOfInputBands();
+              ++band)
+         {
+            tdata_t data;
+            
+            if ( t.valid() && (t->getDataObjectStatus() != OSSIM_NULL) )
+            {
+               // Grab a pointer to the tile for the band.
+               data = static_cast<tdata_t>(t->getBuf(band));
+            }
+            else
+            {
+               data = static_cast<tdata_t>(theNullDataBuffer);
+            }
+
+            // Write the tile.
+            int bytesWritten = 0;
+            bytesWritten = TIFFWriteTile(tif,
+                                         data,
+                                         origin.x,
+                                         origin.y,
+                                         0,        // z
+                                         band);    // sample
+
+            if (bytesWritten != theTileSizeInBytes)
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << MODULE << " ERROR:"
+                  << "Error returned writing tiff tile:  " << i
+                  << "\nExpected bytes written:  " << theTileSizeInBytes
+                  << "\nBytes written:  " << bytesWritten
+                  << endl;
+               theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+               return false;
+            }
+
+         } // End of band loop.  
+        
+         ++tileNumber;
+
+      } // End of tile loop in the sample (width) direction.
+
+      if (needsAborting())
+      {
+         setPercentComplete(100.0);
+         break;
+      }
+      else
+      {
+         double tile = tileNumber;
+         double numTiles = numberOfTiles;
+         setPercentComplete(tile / numTiles * 100.0);
+      }
+
+   } // End of tile loop in the line (height) direction.
+
+   //***
+   // Write the current dirctory.
+   //***
+   if (!TIFFWriteDirectory(tif))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error writing directory!" << endl;
+      return false;
+   }
+
+   ++theCurrentTiffDir;
+
+   return true;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimTiffOverviewBuilder::writeR1(TIFF* tif)
+{
+   static const char MODULE[] = "ossimTiffOverviewBuilder::writeR1";
+
+   //---
+   // Resample the original full res data from the ImageHandler to the
+   // first reduced res set.
+   //---
+   setCurrentMessage(ossimString("creating r1..."));
+   if (!setTags(tif, 1))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error writing tags!" << endl;
+      return false;
+   }
+
+   ossimRefPtr<ossimImageData> imageBuffer = ossimImageDataFactory::instance()->create(0, theImageHandler);
+   if(!imageBuffer.valid())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "Error returned allocating tile buffer at line " << __LINE__ << " in file " << __FILE__ 
+         << endl;
+      return false;
+   }
+//   ossimIrect rect = theImageHandler->getBoundingRect(1);
+   ossimIrect rect             = theImageHandler->getBoundingRect();
+   ossim_int32 samples         = theImageHandler->getNumberOfSamples();
+   ossim_int32 lines           = theImageHandler->getNumberOfLines();
+   ossim_int32 outputSamples   = samples / 2;
+   ossim_int32 outputLines     = lines   / 2;
+   ossim_int32 outputTilesWide = (outputSamples % theTileWidth ?
+                                  outputSamples / theTileWidth + 1 :
+                                  outputSamples / theTileWidth);
+   ossim_int32 outputTilesHigh = (outputLines % theTileHeight ?
+                                  outputLines / theTileHeight + 1 :
+                                  outputLines / theTileHeight);
+
+   ossim_int32 numberOfTiles   = outputTilesWide * outputTilesHigh;
+   imageBuffer->initialize();
+   imageBuffer->setImageRectangle(ossimIrect(0, 0, theTileWidth-1, theTileHeight-1));
+   // Allocate buffers for the output tiles.
+//   ossim_uint8** buf = new ossim_uint8*[theImageHandler->getNumberOfInputBands()];
+   uint32 band;
+//    for(band=0; band<theImageHandler->getNumberOfInputBands(); ++band)
+//    {
+//       buf[band] = new ossim_uint8[theTileSizeInBytes];
+//    }
+
+//    if (outputLines < theTileHeight || outputSamples < theTileWidth)
+//    {
+//       // The full tile will not be filled so make sure it's blank.
+//       for(band=0; band<theImageHandler->getNumberOfInputBands(); ++band)
+//       {
+//          memset((void*)buf[band], 0, theTileSizeInBytes);
+//       }
+//    }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimTiffOverviewBuilder::writeR1 DEBUG:"
+         << "\nsamples:          " << samples
+         << "\nlines:            " << lines
+         << "\noutputTilesWide:  " << outputTilesWide
+         << "\noutputTilesHigh:  " << outputTilesHigh
+         << "\nnumberOfTiles:    " << numberOfTiles
+         << "\nrect:             " << rect
+         << endl;
+   }
+
+   theNullPixelValues.resize(theImageHandler->getNumberOfOutputBands());
+   int tileNumber = 0;
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theNullPixelValues.size(); ++idx)
+   {
+      theNullPixelValues[idx] = theImageHandler->getNullPixelValue(idx);
+      
+   }
+   //***
+   // Tile loop in the line direction.
+   //***
+   for(int i = 0; i < outputTilesHigh; ++i)
+   {
+      //***
+      // Tile loop in the sample (width) direction.
+      //***
+      for(int j = 0; j < outputTilesWide; ++j)
+      {
+         //***
+         // For each output tile, four source tiles must be grabbed.
+         //***
+
+         // Get the upper left tile.
+         ossimIpt origin(j * 2 * theTileWidth,
+                         i * 2 * theTileHeight);
+
+         origin = origin + rect.ul();
+         ossimRefPtr<ossimImageData> t =
+            theImageHandler->getTile(ossimIrect(origin.x,
+                                                origin.y,
+                                                origin.x +(theTileWidth-1),
+                                                origin.y +(theTileHeight-1)));
+         imageBuffer->setDataObjectStatus(OSSIM_FULL);
+         imageBuffer->makeBlank();
+         if(t.valid()&&(t->getBuf())&&(t->getDataObjectStatus()!=OSSIM_EMPTY))
+         {
+            // Band loop.
+            for (band=0; band<theImageHandler->getNumberOfInputBands(); band++)
+            {
+               tdata_t data;
+               data = static_cast<tdata_t>(t->getBuf(band));
+               resampleTile(data,
+                            imageBuffer->getBuf(band),
+                            UL,
+                            theNullPixelValues[band]);
+            }
+         }
+         origin.x += theTileWidth;
+
+         t = theImageHandler->getTile(ossimIrect(origin.x,
+                                                 origin.y,
+                                                 origin.x +(theTileWidth-1),
+                                                 origin.y +(theTileHeight-1)));
+
+         if(t.valid()&&(t->getBuf())&&(t->getDataObjectStatus()!=OSSIM_EMPTY))
+         {
+            // Band loop.
+            for (band=0; band<theImageHandler->getNumberOfInputBands(); ++band)
+            {
+               tdata_t data;
+               
+               // Grab a pointer to the tile for the band.
+               data = static_cast<tdata_t>(t->getBuf(band));
+               resampleTile(data,
+                            imageBuffer->getBuf(band),
+                            UR,
+                            theNullPixelValues[band]);
+            }
+         }
+
+         // Get the lower left tile.
+         origin.x -= theTileWidth;
+         origin.y += theTileHeight;
+
+         t = theImageHandler->getTile(ossimIrect(origin.x,
+                                                 origin.y,
+                                                 origin.x +(theTileWidth-1),
+                                                 origin.y +(theTileHeight-1)));
+         
+         // Band loop.
+         if(t.valid()&&(t->getBuf())&&(t->getDataObjectStatus()!=OSSIM_EMPTY))
+         {
+            for (band=0; band<theImageHandler->getNumberOfInputBands(); ++band)
+            {
+               tdata_t data;
+               
+               data = static_cast<tdata_t>(t->getBuf(band));
+               
+               resampleTile(data,
+                            imageBuffer->getBuf(band),
+                            LL,
+                            theNullPixelValues[band]);
+            }
+         }
+
+         // Get the lower right tile.
+         origin.x += theTileWidth;
+
+         t = theImageHandler->getTile(ossimIrect(origin.x,
+                                                 origin.y,
+                                                 origin.x +(theTileWidth-1),
+                                                 origin.y +(theTileHeight-1)));
+
+         //
+         // Band loop.
+         // Since this is the last quadrant the tile can be written to the
+         // tif file in the band loop.
+         //
+         for (band=0; band<theImageHandler->getNumberOfInputBands(); ++band)
+         {
+            tdata_t data;
+            
+            if ( t.valid() && t->getBuf() &&(t->getDataObjectStatus() != OSSIM_EMPTY))
+            {
+               // Grab a pointer to the tile for the band.
+               data = static_cast<tdata_t>(t->getBuf(band));
+               resampleTile(data,
+                            imageBuffer->getBuf(band),
+                            LR,
+                            theNullPixelValues[band]);
+            }
+            
+            
+            // Write the tile.
+            int bytesWritten = 0;
+            bytesWritten = TIFFWriteTile(tif,
+                                         imageBuffer->getBuf(band),
+                                         j*theTileWidth,
+                                         i*theTileHeight,
+                                         0,        // z
+                                         band);    // sample
+            
+            if (bytesWritten != theTileSizeInBytes)
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << MODULE << " ERROR:"
+                  << "Error returned writing tiff tile:  " << i
+                  << "\nExpected bytes written:  " << theTileSizeInBytes
+                  << "\nBytes written:  " << bytesWritten
+                  << endl;
+               theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+               
+               return false;
+            }
+            
+         }
+         
+         ++tileNumber;
+
+      } // End of tile loop in the sample (width) direction.
+
+      if (needsAborting())
+      {
+         setPercentComplete(100.0);
+         break;
+      }
+      else
+      {
+         double tile = tileNumber;
+         double numTiles = numberOfTiles;
+         setPercentComplete(tile / numTiles * 100.0);
+      }
+
+   } // End of tile loop in the line (height) direction.
+
+   //***
+   // Write the current dirctory.
+   //***
+   if (!TIFFWriteDirectory(tif))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error writing directory!" << endl;
+      return false;
+   }
+
+   theCurrentTiffDir++;
+
+   return true;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimTiffOverviewBuilder::writeRn(TIFF* tif,
+                                       const ossimFilename& overview_file,
+                                       ossim_int32 rrds_level)
+{
+   static const char MODULE[] = "ossimTiffOverviewBuilder::writeRn";
+
+   //---
+   // Resample a previous reduced res level to the next level from the
+   // same tif file.
+   //---
+   ostringstream os;
+   os << "creating r" << rrds_level << "...";
+   setCurrentMessage(os.str());
+
+   TIFF* tifr = NULL;
+   
+    ossimRefPtr<ossimImageData> imageBuffer = ossimImageDataFactory::instance()->create(0, theImageHandler);
+   if(!imageBuffer.valid())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "Error returned allocating tile buffer at line " << __LINE__ << " in file " << __FILE__ 
+         << endl;
+      return false;
+   }
+  if (theCurrentTiffDir)
+   {
+      //***
+      // Open up the same tif file being written to read only to grab the
+      // tiles from the previous reduced res set.
+      //
+      // NOTE:  The 'm' in "rm" is to not memory map the image; hence,
+      // saving memory.
+      //***
+      tifr = TIFFOpen(overview_file.c_str(), "rm");
+      if (!tifr)
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " ERROR!"
+            << "\nCannot open file:  " << overview_file.c_str()
+            << "\nReturning..." << endl;
+         return false;
+      }
+
+      //***
+      // Set the directory of the read only tiff.
+      //***
+      if (!TIFFSetDirectory(tifr, theCurrentTiffDir - 1))
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " ERROR setting directory "
+            << ossim_int32(theCurrentTiffDir - 1) << "!" << endl;
+         TIFFClose(tifr);
+         return false;
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "No previous reduced res set to copy from!"
+         << endl;
+      return false;
+   }
+
+   if (!setTags(tif, rrds_level))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error writing tags!" << endl;
+      TIFFClose(tifr);
+      return false;
+   }
+  
+   ossim_int32 samples;
+   ossim_int32 lines;
+   TIFFGetField( tifr, TIFFTAG_IMAGEWIDTH, &samples );
+   TIFFGetField( tifr, TIFFTAG_IMAGELENGTH, &lines );
+   
+//    ossim_int32 outputSamples   = (ossim_int32)ceil(samples / 2.0);
+//    ossim_int32 outputLines     = (ossim_int32)ceil(lines / 2.0);
+   ossim_int32 outputSamples   = samples / 2;
+   ossim_int32 outputLines     = lines   / 2;
+   ossim_int32 outputTilesWide = outputSamples % theTileWidth ?
+                           outputSamples / theTileWidth + 1 :
+                                outputSamples / theTileWidth;
+   ossim_int32 outputTilesHigh = outputLines % theTileHeight ?
+                           outputLines / theTileHeight + 1 :
+                           outputLines / theTileHeight;
+
+   ossim_int32 numberOfTiles   = outputTilesWide * outputTilesHigh;
+
+   imageBuffer->initialize();
+   imageBuffer->setImageRectangle(ossimIrect(0, 0, theTileWidth-1, theTileHeight-1));
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_INFO)
+         << MODULE << " DEBUG:"
+         << "\nrrds_level:     " << rrds_level
+         << "\noutputSamples:  " << outputSamples
+         << "\noutputLines:    " << outputLines
+         << "\nnumberOfTiles:  " << numberOfTiles
+         << endl;
+   }
+      
+   // Allocate buffers for the output tiles.
+//    ossim_uint8** buf =
+//       new ossim_uint8*[theImageHandler->getNumberOfInputBands()];
+   ossim_uint32 band;
+//    for(band=0; band<theImageHandler->getNumberOfInputBands(); band++)
+//    {
+//       buf[band] = new ossim_uint8[theTileSizeInBytes];
+//    }
+
+    ossim_uint8* tbuf = new ossim_uint8[theTileSizeInBytes];
+
+//    if (outputLines < theTileHeight || outputSamples < theTileWidth)
+//    {
+//       // The full tile will not be filled so make sure it's blank.
+//       for(band=0; band<theImageHandler->getNumberOfInputBands(); band++)
+//       {
+//          memset((void*)buf[band], 0, theTileSizeInBytes);
+//       }
+//    }
+   
+   int tileNumber = 0;
+   
+   //***
+   // Tile loop in the line direction.
+   //***
+   for(int i = 0; i < outputTilesHigh; i++)
+   {
+      //***
+      // Tile loop in the sample (width) direction.
+      //***
+      for(int j = 0; j < outputTilesWide; j++)
+      {
+         //***
+         // For each output tile, four source tiles must be grabbed.
+         //
+         // NOTE:
+         // Because the output tile bounds can be greater than the source
+         // data grabbed from, the origin bounds must be checked after
+         // the upper left tile is copied.
+         //***
+
+         // Get the upper left tile.
+         ossimIpt origin(j * 2 * theTileWidth, i * 2 * theTileHeight);
+
+         // Get the tiles.
+         
+         // Band loop.
+         for (band=0; band<theImageHandler->getNumberOfInputBands(); band++)
+         {
+            // Grab the upper left source tile for the band.
+            int bytes = TIFFReadTile(tifr,
+                                     (void*)tbuf,
+                                     origin.x,
+                                     origin.y,
+                                     0,
+                                     band);
+            
+            if (bytes != theTileSizeInBytes)
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << MODULE << " Read Error!"
+                  << "\nBytes expected:  " << theTileSizeInBytes
+                  << "\nBytes read:      " << bytes
+                  << "\nReturning error..." << endl;
+               TIFFClose(tifr);
+               delete [] tbuf;
+               tbuf = NULL;
+               return false;
+            }
+            
+            resampleTile((void*)tbuf,
+                         imageBuffer->getBuf(band),
+                         UL,
+			 theNullPixelValues[band]);
+         }
+
+         // Get the upper right tile.
+         origin.x += theTileWidth;
+
+         if (origin.x < samples && origin.y < lines)
+         {
+            // Get the tiles.
+            
+            // Band loop.
+            for (band=0; band<theImageHandler->getNumberOfInputBands(); band++)
+            {
+               // Grab the upper right source tile for the band.
+               int bytes = TIFFReadTile(tifr,
+                                        (void*)tbuf,
+                                        origin.x,
+                                        origin.y,
+                                        0,
+                                        band);
+               
+               if (bytes != theTileSizeInBytes)
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << MODULE << " Read Error!"
+                     << "\nBytes expected:  " << theTileSizeInBytes
+                     << "\nBytes read:      " << bytes
+                     << "\nReturning error..." << endl;
+                  TIFFClose(tifr);
+                  delete [] tbuf;
+                  tbuf = NULL;
+                  return false;
+               }
+               
+               resampleTile((void*)tbuf,
+                            imageBuffer->getBuf(band),
+                            UR,
+			    theNullPixelValues[band]);
+            }
+
+         }  // End of if (origin.x <= samples && origin.y <= lines)
+
+         // Get the lower left tile.
+         origin.x -= theTileWidth;
+         origin.y += theTileHeight;
+
+         if (origin.x < samples && origin.y < lines)
+         {
+            // Get the tiles.
+            
+            // Band loop.
+            for (band=0; band<theImageHandler->getNumberOfInputBands(); band++)
+            {
+               // Grab the lower left source tile for the band.
+               int bytes = TIFFReadTile(tifr,
+                                        (void*)tbuf,
+                                        origin.x,
+                                        origin.y,
+                                        0,
+                                        band);
+               
+               if (bytes != theTileSizeInBytes)
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << MODULE << " Read Error!"
+                     << "\nBytes expected:  " << theTileSizeInBytes
+                     << "\nBytes read:      " << bytes
+                     << "\nReturning error..." << endl;
+                  delete [] tbuf;
+                  tbuf = NULL;
+                  TIFFClose(tifr);
+                  return false;
+               }
+
+               resampleTile((void*)tbuf,
+                            imageBuffer->getBuf(band),
+                            LL,
+			    theNullPixelValues[band]);
+            }
+
+         }  // End of if (origin.x <= samples && origin.y <= lines)
+
+         // Get the lower right tile.
+         origin.x += theTileWidth;
+
+         if (origin.x < samples && origin.y < lines)
+         {
+            // Get the tiles.
+            
+            // Band loop.
+            for (band=0; band<theImageHandler->getNumberOfInputBands(); band++)
+            {
+               // Grab the lower right source tile for the band.
+               int bytes = TIFFReadTile(tifr,
+                                        (void*)tbuf,
+                                        origin.x,
+                                        origin.y,
+                                        0,
+                                        band);
+               
+               if (bytes != theTileSizeInBytes)
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << MODULE << " Read Error!"
+                     << "\nBytes expected:  " << theTileSizeInBytes
+                     << "\nBytes read:      " << bytes
+                     << "\nReturning error..." << endl;
+
+                  // Free memory.
+                  delete [] tbuf;
+                  tbuf = NULL;
+                  
+                  TIFFClose(tifr);
+                  return false;
+               }
+               
+               resampleTile((void*)tbuf,
+                            imageBuffer->getBuf(band),
+                            LR,
+			    theNullPixelValues[band]);
+            }
+
+         }  // End of if (origin.x <= samples && origin.y <= lines)
+
+         for (band=0; band<theImageHandler->getNumberOfInputBands(); band++)
+         {
+            // Write the tile.
+            int bytesWritten = 0;
+            bytesWritten = TIFFWriteTile(tif,
+                                         imageBuffer->getBuf(band),
+                                         j*theTileWidth,
+                                         i*theTileHeight,
+                                         0,        // z
+                                         band);    // sample
+
+            if (bytesWritten != theTileSizeInBytes)
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << MODULE << " ERROR:"
+                  << "Error returned writing tiff tile:  " << i
+                  << "\nExpected bytes written:  " << theTileSizeInBytes
+                  << "\nBytes written:  " << bytesWritten
+                  << endl;
+
+               delete [] tbuf;
+               tbuf = NULL;
+               
+               TIFFClose(tifr);
+               return false;
+            }
+         }
+         
+         tileNumber++;
+
+      } // End of tile loop in the sample (width) direction.
+
+      
+      if (needsAborting())
+      {
+         setPercentComplete(100.0);
+         break;
+      }
+      else
+      {
+         double tile = tileNumber;
+         double numTiles = numberOfTiles;
+         setPercentComplete(tile / numTiles * 100.0);
+      }
+   } // End of tile loop in the line (height) direction.
+
+   delete [] tbuf;
+   tbuf = NULL;
+   TIFFClose(tifr);
+         
+   //***
+   // Write the current dirctory.
+   //***
+   if (!TIFFWriteDirectory(tif))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error writing directory!" << endl;
+      return false;
+   }
+
+   theCurrentTiffDir++;
+   
+   return true;
+}
+   
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+ossim_int32 ossimTiffOverviewBuilder::getNumberOfSets() const
+{
+   ossim_int32 a = theImageHandler->getNumberOfSamples(0) <
+             theImageHandler->getNumberOfLines(0) ?
+             theImageHandler->getNumberOfSamples(0) :
+             theImageHandler->getNumberOfLines(0);
+
+   ossim_int32 n = 0;
+
+   while(a > 2)
+   {
+      a /= 2;
+      ++n;
+   }
+
+   return n;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimTiffOverviewBuilder::setTags(TIFF* tif, ossim_int32 rrds_level) const
+{
+   ossim_int32 imageWidth      = theImageHandler->getNumberOfSamples();
+   ossim_int32 imageHeight     = theImageHandler->getNumberOfLines();
+   int16 samplesPerPixel = theImageHandler->getNumberOfOutputBands();
+   ossim_float64   minSampleValue  = theImageHandler->getMinPixelValue();
+   ossim_float64   maxSampleValue  = theImageHandler->getMaxPixelValue();
+
+   if (rrds_level)
+   {
+      imageWidth  = imageWidth  >> rrds_level;
+      imageHeight = imageHeight >> rrds_level;
+      TIFFSetField( tif, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE );
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimTiffOverviewBuilder::setTags DEBUG:"
+         << "\nrrds_level:      " << rrds_level
+         << "\nimageWidth:      " << imageWidth
+         << "\nimageHeight:     " << imageHeight
+         << "\nminSampleValue:  " << minSampleValue
+         << "\nmaxSampleValue:  " << maxSampleValue
+         << endl;
+   }
+   TIFFSetField( tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_SEPARATE );
+   TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, imageWidth);
+   TIFFSetField( tif, TIFFTAG_IMAGELENGTH, imageHeight);
+   TIFFSetField( tif, TIFFTAG_BITSPERSAMPLE, theBitsPerSample );
+   TIFFSetField( tif, TIFFTAG_SAMPLEFORMAT, theSampleFormat );
+   TIFFSetField( tif, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel );
+
+   if( theImageHandler->getNumberOfInputBands() == 3 )
+      TIFFSetField( tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
+   else
+      TIFFSetField( tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK );
+   
+   TIFFSetField( tif, TIFFTAG_TILEWIDTH,  theTileWidth  );
+   TIFFSetField( tif, TIFFTAG_TILELENGTH, theTileHeight );
+   
+   // Set the compression related tags...
+   TIFFSetField( tif, TIFFTAG_COMPRESSION, theTiffCompressType );
+   if (theTiffCompressType == COMPRESSION_JPEG)
+   {
+      TIFFSetField( tif, TIFFTAG_JPEGQUALITY,  theJpegCompressQuality);
+   }
+   
+   // Set the min/max values.
+   switch( theImageHandler->getOutputScalarType() )
+   {
+      case OSSIM_SINT16:
+      case OSSIM_FLOAT32:
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+         TIFFSetField( tif, TIFFTAG_SMINSAMPLEVALUE, minSampleValue );
+         TIFFSetField( tif, TIFFTAG_SMAXSAMPLEVALUE, maxSampleValue );
+         break;
+
+      case OSSIM_UINT8:
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      case OSSIM_UINT32:
+      default:
+         TIFFSetField( tif, TIFFTAG_MINSAMPLEVALUE,
+                       static_cast<int>(minSampleValue) );
+         TIFFSetField( tif, TIFFTAG_MAXSAMPLEVALUE,
+                       static_cast<int>(maxSampleValue) );
+         break;
+   }
+   
+    return true;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+void ossimTiffOverviewBuilder::resampleTile(void*    source_tile,
+                                            void*    output_tile,
+                                            Quadrant quadrant,
+					    double   nullPix)
+{
+   static const char MODULE[] = "ossimTiffOverviewBuilder::resampleTile";
+   
+   switch(theImageHandler->getOutputScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         resampleTile((ossim_uint8*)source_tile,
+                      (ossim_uint8*)output_tile,
+                      quadrant,
+                      (ossim_uint8)nullPix);
+         break;
+      }
+
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         resampleTile((ossim_uint16*)source_tile,
+                      (ossim_uint16*)output_tile,
+                      quadrant,
+                      (ossim_uint16)nullPix);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         resampleTile((ossim_sint16*)source_tile,
+                      (ossim_sint16*)output_tile,
+                      quadrant,
+                      (ossim_sint16)nullPix);
+         break;
+      }
+
+      case OSSIM_UINT32:
+      {
+         resampleTile((ossim_uint32*)source_tile,
+                      (ossim_uint32*)output_tile,
+                      quadrant,
+                      (ossim_uint32)nullPix);
+         break;
+      }
+      
+      case OSSIM_FLOAT32:
+      {
+         resampleTile((ossim_float32*)source_tile,
+                      (ossim_float32*)output_tile,
+                      quadrant,
+                      (ossim_float32)nullPix);
+         break;
+      }
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         resampleTile((ossim_float64*)source_tile,
+                      (ossim_float64*)output_tile,
+                      quadrant,
+                      (ossim_float64)nullPix);
+         break;
+      }
+      default:
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " Unkown pixel type!" << endl;
+         return;
+   }
+}
+
+template <class T>
+void  ossimTiffOverviewBuilder::resampleTile(T* source_tile,
+					     T* output_tile,
+					     Quadrant quadrant,
+					     T  nullPixel)
+{
+   //***
+   // Buffers are assumed to be tiles.  This will fill one quarter of the
+   // output tile
+   //***
+   ossim_int32 lines   = theTileHeight / 2;
+   ossim_int32 samples = theTileWidth  / 2;
+
+   T* s = (T*)source_tile; // source buffer
+   T* d = (T*)output_tile; // destination buffer
+
+   // Adjust the d pointer to the start of data.
+   switch (quadrant)
+   {
+      case ossimTiffOverviewBuilder::UR:
+         d += theTileWidth / 2;
+         break;
+      case ossimTiffOverviewBuilder::LL:
+         d += theTileHeight / 2 * theTileWidth;
+         break;
+      case ossimTiffOverviewBuilder::LR:
+         d += theTileHeight / 2 * theTileWidth + theTileWidth / 2;
+      case ossimTiffOverviewBuilder::UL:
+      default:
+         break;
+   }
+
+   double weight=0.0;
+   double value=0.0;
+   for (ossim_int32 i=0; i<lines; i++)
+   {
+      for (ossim_int32 j=0; j<samples; j++)
+      {
+         switch(theResampleType)
+         {
+            case ossimFilterResampler::ossimFilterResampler_NEAREST_NEIGHBOR:
+            {
+               weight = 1.0;
+               value  = *(s + i*2*theTileWidth     + j*2);
+               break;
+            }
+            case ossimFilterResampler::ossimFilterResampler_BOX:
+            {
+               weight = 0;
+               value  = 0;
+               
+               // Grab four pixels from the source, average, and assign to output.
+               ossim_float64 ul = *(s + i*2*theTileWidth     + j*2);
+               ossim_float64 ur = *(s + i*2*theTileWidth     + j*2+1);
+               ossim_float64 ll = *(s + (i*2+1)*theTileWidth + j*2);
+               ossim_float64 lr = *(s + (i*2+1)*theTileWidth + j*2+1);
+               
+               if(ul != nullPixel)
+               {
+                  ++weight;
+                  value += ul;
+               }
+               if(ur != nullPixel)
+               {
+                  ++weight;
+                  value += ur;
+               }
+               if(ll != nullPixel)
+               {
+                  ++weight;
+                  value += ll;
+               }
+               if(lr != nullPixel)
+               {
+                  ++weight;
+                  value += lr;
+               }
+               break;
+            }
+            default:
+            {
+               weight = 1.0;
+               value  = *(s + i*2*theTileWidth     + j*2);
+               break;
+            }
+            
+         }
+         if(weight)
+         {
+            d[j] = (T)( value/weight  );
+         }
+         else
+         {
+            d[j] = nullPixel;
+         }
+      }
+      d += theTileWidth;
+   }
+}
+
+void ossimTiffOverviewBuilder::setCompressionType(ossim_uint16 compression_type)
+{
+   switch (compression_type)
+   {
+   case COMPRESSION_JPEG:
+   case COMPRESSION_LZW:
+   case COMPRESSION_DEFLATE:
+   case COMPRESSION_PACKBITS:
+      theTiffCompressType = compression_type;
+      break;
+   default:
+      theTiffCompressType = COMPRESSION_NONE;
+      if (traceDebug())
+      {
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_WARNING,
+                       "\
+ossimTiffOverviewBuilder::setCompressionType\nfile %s line %d\n\
+Unsupported compression type: %d  Defaulting to none.",
+                       __FILE__,
+                       __LINE__,
+                       compression_type);
+      }
+      break;
+   }
+}
+
+void ossimTiffOverviewBuilder::setJpegCompressionQuality(ossim_int32 quality)
+{
+   if (quality > 1 && quality < 101)
+   {
+      theJpegCompressQuality = quality;
+   }
+   else
+   {
+      theJpegCompressQuality = DEFAULT_COMPRESS_QUALITY;
+
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_WARNING,
+                    "\
+ossimTiffOverviewBuilder::setJpegCompressionQuality\n%s file %s \
+line %d Compression quality of %d is out of range!\nis out of range!\n\
+Range is 100 to 1.  Current quality set to default of 75.",
+                    __FILE__,
+                    __LINE__,
+                    quality);
+   }
+}
+
+ossimObject* ossimTiffOverviewBuilder::getObject()
+{
+   return this;
+}
+
+const ossimObject* ossimTiffOverviewBuilder::getObject() const
+{
+   return this;
+}
+
+bool ossimTiffOverviewBuilder::execute()
+{
+   return buildOverview(theOutputFile);
+}
+
+ossimFilename ossimTiffOverviewBuilder::getOutputFile() const
+{
+   return theOutputFile;
+}
+
+void ossimTiffOverviewBuilder::setOutputFile(const ossimFilename& file)
+{
+   
+   theOutputFile = file;
+}
+
+bool ossimTiffOverviewBuilder::canConnectMyInputTo(
+   ossim_int32 index,
+   const ossimConnectableObject* obj) const
+{
+   if ( (index == 0) &&
+        PTR_CAST(ossimImageHandler, obj) )
+   {
+      return true;
+   }
+
+   return false;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffOverviewBuilder.h b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffOverviewBuilder.h
new file mode 100644
index 0000000000..4326f41f50
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffOverviewBuilder.h
@@ -0,0 +1,208 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for TiffOverviewBuilder.
+//
+//*******************************************************************
+//  $Id: ossimTiffOverviewBuilder.h,v 1.14 2005/08/29 18:47:40 gpotts Exp $
+
+#ifndef ossimTiffOverviewBuilder_HEADER
+#define ossimTiffOverviewBuilder_HEADER
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimSource.h>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/common/ossimProcessInterface.h>
+#include <base/common/events/ossimConnectableObjectListener.h>
+#include <imaging/resample/ossimFilterResampler.h>
+#include <base/data_types/ossimFilename.h>
+#include <tiffio.h>
+#include <tiff.h>
+
+class ossimImageHandler;
+class ossimFilename;
+class ossimConnectableObject;
+
+class OSSIM_DLL ossimTiffOverviewBuilder
+   :
+      public ossimSource,
+      public ossimProcessInterface,
+      public ossimConnectableObjectListener
+{
+public:
+
+   enum
+   {
+      DEFAULT_COMPRESS_QUALITY=75
+   };
+   
+   ossimTiffOverviewBuilder(ossimImageHandler* imageHanderler);
+   
+   ~ossimTiffOverviewBuilder();
+
+   enum Quadrant
+   {
+      UL,
+      UR,
+      LL,
+      LR
+   };
+
+   /**
+    * Supports BOX or NEAREST NEIGHBOR.  When indexed you should probably use nearest neighbor
+    */ 
+   void setResampleType(ossimFilterResampler::ossimFilterResamplerType resampleType);
+   
+   /*!
+    *  Builds overview file and sets "theOutputFile" to that of
+    *  the overview_file.
+    *
+    *  @param overview_file The overview file name to output.
+    *
+    *  @param copy_all  If set to true the entire image will be
+    *  copied.  This can be used to convert an image to a tiled tif.
+    *  
+    *  @return true on success, false on error.
+    */
+   bool buildOverview(const ossimFilename& overview_file,
+                      bool copy_all=false);
+
+   /*!
+    * Calls buildOverview.  This method uses "theOutputFile" for the file
+    * name.
+    *
+    * If the copy_all flag is set the entire image will be copied.  This can
+    * be used to convert an image to a tiled tif.
+    *
+    * @return true on success, false on error.
+    *
+    * @note If setOutputFile was not called the output name will be derived
+    * from the image name.  If image was "foo.tif" the overview file will
+    * be "foo.ovr".
+    */
+   virtual bool execute();
+
+   /*!
+    *  Sets the compression type to use when building overviews.
+    *  
+    *  @param compression_type Current supported types:
+    * - COMPRESSION_JPEG
+    * - COMPRESSION_LZW
+    * - COMPRESSION_DEFLATE
+    * - COMPRESSION_PACKBITS
+    * - COMPRESSION_NONE (default)
+    */
+   void setCompressionType(uint16 compression_type);
+
+   /*!
+    *  Sets the compression quality for use when using a compression type
+    *  of COMPRESSION_JPEG.
+    *
+    *  @param quality Range 1 to 100 with 100 being best quality.
+    */
+   void setJpegCompressionQuality(ossim_int32 quality);
+
+   /*!
+    * @return ossimObject* to this object.
+    */
+   virtual ossimObject* getObject();
+
+   /*!
+    * @return const ossimObject* to this object.
+    */
+   virtual const ossimObject* getObject() const;
+
+   /*!
+    * @return The output filename.  This will be derived from the image
+    * handlers filename unless the method buildOverview has been called which
+    * takes a filename.
+    */
+   ossimFilename getOutputFile() const;
+
+   /*!
+    * Sets the output filename.
+    */
+   void  setOutputFile(const ossimFilename& file);
+
+   /*!
+    * @return true if input is an image handler.
+    */
+   virtual bool canConnectMyInputTo(ossim_int32 index,
+                                    const ossimConnectableObject* obj) const;
+   
+private:
+   
+   /*!
+    *  Returns the number of reduced resolution data sets to get the smallest
+    *  dimension >= 32 && < 64.
+    */
+  ossim_int32 getNumberOfSets() const;
+
+   /*!
+    *  Copy the full resolution image data to the output tif image.
+    */
+  bool writeR0(TIFF* tif);
+
+   /*!
+    *  Write the first reduced resolution data set to the tif file.
+    */
+   bool writeR1(TIFF* tif);
+
+   /*!
+    *  Write reduced resolution data set to the tif file.  "rrds_level" must
+    *  be greater than 1 for this method as it uses subsequent rrds_levels
+    *  from the tif file.
+    */
+   bool writeRn(TIFF* tif,
+                const ossimFilename& overview_file,
+                ossim_int32 rrds_level);
+
+   /*!
+    *  Resamples a patch of data.
+    */
+   void resampleTile(void*     source_tile,
+                     void*     output_tile,
+                     Quadrant quadrant,
+		     double    nullPix);
+
+   template <class T> void  resampleTile(T* source_tile,
+                                         T* output_tile,
+                                         Quadrant quadrant,
+                                         T  nullPixel);
+   
+   /*!
+    *  Set the tiff tags for the appropriate rrds_level.  Level zero is the
+    *  full resolution image.
+    */
+   bool setTags(TIFF* tif, ossim_int32 rrds_level) const;
+
+   // Disallow these...
+   ossimTiffOverviewBuilder(const ossimTiffOverviewBuilder& source);
+   ossimTiffOverviewBuilder& operator=(const ossimTiffOverviewBuilder& rhs); 
+
+   ossimImageHandler* theImageHandler;
+   ossimFilename      theOutputFile;
+   ossim_uint8*       theNullDataBuffer;
+   ossim_int32        theBytesPerPixel;
+   ossim_int32        theBitsPerSample;
+   ossim_int32        theTileWidth;
+   ossim_int32        theTileHeight;
+   ossim_int32        theTileSizeInBytes;
+   ossim_int32        theSampleFormat;
+   ossim_int32        theCurrentTiffDir;
+   ossim_uint16       theTiffCompressType;
+   ossim_int32        theJpegCompressQuality;
+   ossimFilterResampler::ossimFilterResamplerType theResampleType;
+   vector<double>      theNullPixelValues;
+TYPE_DATA   
+};
+   
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffTileSource.cpp
new file mode 100644
index 0000000000..e0cdeeabff
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffTileSource.cpp
@@ -0,0 +1,1825 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author:  David Burken
+//          Frank Warmerdam (warmerdam@pobox.com)
+//
+// Description:
+//
+// Contains class definition for TiffTileSource.
+//
+//*******************************************************************
+//  $Id: ossimTiffTileSource.cpp,v 1.104 2006/01/05 14:59:29 dburken Exp $
+
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+#include <support_data/tiff/ossimGeoTiff.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/property/ossimBooleanProperty.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <projections/map_projections/ossimAlbersProjection.h>
+#include <projections/map_projections/ossimCylEquAreaProjection.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <projections/map_projections/ossimVanDerGrintenProjection.h>
+#include <projections/map_projections/ossimLambertConformalConicProjection.h>
+#include <projections/map_projections/ossimMercatorProjection.h>
+#include <projections/map_projections/ossimMillerProjection.h>
+#include <projections/map_projections/ossimOrthoGraphicProjection.h>
+#include <projections/map_projections/ossimPolyconicProjection.h>
+#include <projections/map_projections/ossimSinusoidalProjection.h>
+#include <projections/map_projections/ossimTransMercatorProjection.h>
+#include <projections/map_projections/ossimCassiniProjection.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+
+RTTI_DEF1(ossimTiffTileSource, "ossimTiffTileSource", ossimImageHandler)
+
+static ossimTrace traceDebug("ossimTiffTileSource:degug");
+
+#ifndef MAX
+#  define MIN(a,b)      ((a<b) ? a : b)
+#  define MAX(a,b)      ((a>b) ? a : b)
+#endif
+
+#define OSSIM_TIFF_UNPACK_R4(value) ( (value)&0x000000FF)
+#define OSSIM_TIFF_UNPACK_G4(value) ( ((value)>>8)&0x000000FF)
+#define OSSIM_TIFF_UNPACK_B4(value) ( ((value)>>16)&0x000000FF)
+#define OSSIM_TIFF_UNPACK_A4(value) ( ((value)>>24)&0x000000FF)
+
+//*******************************************************************
+// Public Constructor:
+//*******************************************************************
+ossimTiffTileSource::ossimTiffTileSource()
+   :
+      ossimImageHandler(),
+      theTile(0),
+      theBuffer(0),
+      theBufferSize(0),
+      theBufferRect(0, 0, 0, 0),
+      theBufferRLevel(0),
+      theTiffPtr(0),
+      theSamplesPerPixel(0),
+      theBitsPerSample(0),
+      theSampleFormatUnit(0),
+      theMaxSampleValue(0),
+      theMinSampleValue(0),
+      theNumberOfDirectories(0),
+      theCurrentDirectory(0),
+      theR0isFullRes(false),
+      theBytesPerPixel(0),
+      theScalarType(OSSIM_SCALAR_UNKNOWN),
+      theApplyColorPaletteFlag(true),
+      theImageWidth(0),
+      theImageLength(0),
+      theReadMethod(0),
+      thePlanarConfig(0),
+      thePhotometric(0),
+      theRowsPerStrip(0),
+      theImageTileWidth(0),
+      theImageTileLength(0)
+{}
+
+ossimTiffTileSource::~ossimTiffTileSource()
+{
+   close();
+}
+
+ossimRefPtr<ossimImageData> ossimTiffTileSource::getTile(
+   const  ossimIrect& tile_rect,
+   ossim_uint32 resLevel)
+{
+   static const char MODULE[] ="ossimTiffTileSource::getTile(rect, res)";
+
+   //---
+   // Not open, this tile source bypassed, or invalid res level,
+   // return a blank tile.
+   //---
+   if( !isOpen() || !isSourceEnabled() || !isValidRLevel(resLevel) )
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   //---
+   // Subtract an sub image offset to work in zero based image space from
+   // here on out.
+   //---
+   ossimIrect zeroBasedTileRect = tile_rect - getSubImageOffset(resLevel);
+   
+   //---
+   // If there is an overview and the current rr level is not at "0" then
+   // send the getTile call to the overview image handler.
+   //---
+   if (resLevel&&theOverview)
+   {
+      //---
+      // Overviews are not aware of sub image offsets so request a zero based
+      // rectangle.
+      //---
+      ossimRefPtr<ossimImageData> tile =
+         theOverview->getTile(zeroBasedTileRect, resLevel);
+      if (tile.valid())
+      {
+         //---
+         // Since the overview request was zero based we must reset the
+         // rectangle to be relative to any sub image offset.
+         //---
+         tile->setImageRectangle(tile_rect);
+      }
+
+      if(getOutputScalarType() == OSSIM_USHORT11)
+      {
+         //---
+         // Temp fix:
+         // The overview handler could return a tile of OSSIM_UINT16 if
+         // the max sample value was not set to 2047.
+         //---
+         tile->setScalarType(OSSIM_USHORT11);
+      }
+
+      return tile;
+   }
+
+   bool reallocateBuffer = false;   
+   if ( (tile_rect.width()  != theTile->getWidth()) ||
+        (tile_rect.height() != theTile->getHeight()) )
+   {
+      reallocateBuffer = true;
+   }
+   
+   if (getCurrentTiffRLevel() != resLevel)
+   {
+      // Change the tiff directory to the requested level.
+      ossim_uint32 dir = 0;
+      if (resLevel)
+      {
+         dir = theR0isFullRes ? resLevel : resLevel - 1;
+      }
+
+      if (setTiffDirectory(dir) == false)
+      {
+         return ossimRefPtr<ossimImageData>();
+      }
+      reallocateBuffer = true;
+   }
+
+   //---
+   // The tile's internal rectangle should be relative to any sub image.
+   // 
+   // Note:
+   //
+   // Since the allocate buffer method relies on theTile->getHeight() it is
+   // important to do this prior to the allocateBuffer call.
+   //---
+   theTile->setImageRectangle(tile_rect);
+
+   if (reallocateBuffer)
+   {
+      allocateBuffer();
+   }
+
+   // This should be the zero base image rectangle for this res level.
+   ossimIrect image_rect = getImageRectangle(resLevel);
+        
+   //---
+   // See if any point of the requested tile is in the image.
+   //---
+   if ( zeroBasedTileRect.intersects(image_rect) )
+   {
+      ossimIrect clip_rect = zeroBasedTileRect.clipToRect(image_rect);
+
+      if ( !zeroBasedTileRect.completely_within(clip_rect) )
+      {
+         // Start with a blank tile.
+         theTile->makeBlank();
+      }
+
+      // Load the tile buffer with data from the tif.
+      if (loadTile(zeroBasedTileRect, clip_rect))
+      {
+         theTile->validate();
+         return theTile;
+      }
+      else
+      {
+         // Error in filling buffer.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " Returning blank tile..." << endl;
+         return ossimRefPtr<ossimImageData>();
+      }
+   }
+
+   // No part of requested tile within the image rectangle.
+   return ossimRefPtr<ossimImageData>();
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimTiffTileSource::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix) const
+{
+   kwl.add(prefix,
+           "apply_color_palette_flag",
+           theApplyColorPaletteFlag,
+           true);
+   // Currently nothing to do here.
+   return ossimImageHandler::saveState(kwl, prefix);
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+bool ossimTiffTileSource::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   if (ossimImageHandler::loadState(kwl, prefix))
+   {
+      ossimString flag = kwl.find(prefix,
+                                  "apply_color_palette_flag");
+      if(flag != "")
+      {
+         theApplyColorPaletteFlag = flag.toBool();
+      }
+      else
+      {
+         theApplyColorPaletteFlag = true;
+      }
+      
+     return open(theImageFile);
+   }
+
+   return false;
+}
+
+bool ossimTiffTileSource::open(const ossimFilename& image_file)
+{
+   if (theTiffPtr)
+   {
+     close();
+   }
+   theImageFile = image_file;
+   return open();
+}
+
+void ossimTiffTileSource::close()
+{
+   if(theTiffPtr)
+   {
+      TIFFClose(theTiffPtr);
+      theTiffPtr = 0;
+   }
+   theImageWidth.clear();
+   theImageLength.clear();
+   theReadMethod.clear();
+   thePlanarConfig.clear();
+   thePhotometric.clear();
+   theRowsPerStrip.clear();
+   theImageTileWidth.clear();
+   theImageTileLength.clear();
+   if (theBuffer)
+   {
+      delete [] theBuffer;
+      theBuffer = NULL;
+   }
+}
+
+bool ossimTiffTileSource::open()
+{
+   static const char MODULE[] = "ossimTiffTileSource::open";
+
+   if(isOpen())
+   {
+     close();
+   }
+   //***
+   // First we do a quick test to see if the file looks like a tiff file.
+   //***
+   FILE		*fp;
+   unsigned char header[2];
+
+   fp = fopen( theImageFile.c_str(), "rb" );
+   if( fp == NULL )
+       return false;
+
+   fread( header, 2, 1, fp );
+   fclose( fp );
+
+   if( (header[0] != 'M' || header[1] != 'M')
+       && (header[0] != 'I' || header[1] != 'I') )
+       return false;
+
+   //---
+   // Note:  The 'm' in "rm" is to tell TIFFOpen to not memory map the file.
+   //---
+   theTiffPtr = TIFFOpen(theImageFile.c_str(), "rm");
+
+   // Check for errors.
+   if (!theTiffPtr)
+   {
+      return false;
+   }
+
+   if (!theTiffPtr)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:\n"
+         << "Object has null tiff descriptor." << endl;
+      return false;
+   }
+
+   //***
+   // Get the general tiff info.
+   //***
+   
+   //***
+   // See if the first directory is of FILETYPE_REDUCEDIMAGE; if not,
+   // the first level is considered to be full resolution data.
+   // Note:  If the tag is not present, consider the first level full
+   // resolution.
+   //***
+   long sub_file_type;
+   if ( !TIFFGetField( theTiffPtr,
+                       TIFFTAG_SUBFILETYPE ,
+                       &sub_file_type ) )
+   {
+      sub_file_type = 0;
+   }
+
+   if (sub_file_type == FILETYPE_REDUCEDIMAGE)
+   {
+      theR0isFullRes = false;
+   }
+   else
+   {
+      theR0isFullRes = true;
+   }
+   
+   if( !TIFFGetField(theTiffPtr, TIFFTAG_BITSPERSAMPLE, &(theBitsPerSample)) )
+   {
+      theBitsPerSample = 8;
+   }
+
+   if( !TIFFGetField(theTiffPtr,
+                     TIFFTAG_SAMPLESPERPIXEL,
+                     &theSamplesPerPixel ) )
+   {
+      theSamplesPerPixel = 1; 
+   }
+
+   if ( !TIFFGetField( theTiffPtr,
+                       TIFFTAG_SAMPLEFORMAT,
+                       &theSampleFormatUnit ) )
+   {
+      theSampleFormatUnit = 0;
+   }
+
+   if ( !TIFFGetField( theTiffPtr,
+                       TIFFTAG_SMAXSAMPLEVALUE,
+                       &theMaxSampleValue ) )
+   {
+      uint16 maxValue = 0;
+      if(!TIFFGetField( theTiffPtr,
+                        TIFFTAG_MAXSAMPLEVALUE,
+                        &maxValue))
+      {
+         theMaxSampleValue = OSSIM_DBL_NAN;
+      }
+      else
+      {
+         theMaxSampleValue = maxValue;
+      }
+   }
+
+   if ( !TIFFGetField( theTiffPtr,
+                       TIFFTAG_SMINSAMPLEVALUE,
+                       &theMinSampleValue ) )
+   {
+      uint16 minValue = 0;
+      if(!TIFFGetField( theTiffPtr,
+                        TIFFTAG_MINSAMPLEVALUE,
+                        &minValue))
+      {
+         theMinSampleValue = OSSIM_DBL_NAN;
+      }
+      else
+      {
+         theMinSampleValue = minValue;
+      }
+   }
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\ntheMinSampleValue:  " << theMinSampleValue
+           << "\ntheMaxSampleValue:  " << theMaxSampleValue
+           << endl;
+   }
+
+   //***
+   // Get the number of directories.
+   //***
+   theNumberOfDirectories = 0;
+   do
+   {
+      theNumberOfDirectories++;
+   } while (TIFFReadDirectory(theTiffPtr));
+
+   theImageWidth.resize(theNumberOfDirectories);
+   theImageLength.resize(theNumberOfDirectories);
+   theReadMethod.resize(theNumberOfDirectories);
+   thePlanarConfig.resize(theNumberOfDirectories);
+   thePhotometric.resize(theNumberOfDirectories);
+   theRowsPerStrip.resize(theNumberOfDirectories);
+   theImageTileWidth.resize(theNumberOfDirectories);
+   theImageTileLength.resize(theNumberOfDirectories);
+   
+   for (ossim_uint32 dir=0; dir<theNumberOfDirectories; ++dir)
+   {
+      if (setTiffDirectory(dir) == false)
+      {
+         return false;
+      }
+      
+      if( !TIFFGetField( theTiffPtr, TIFFTAG_PLANARCONFIG,
+                         &(thePlanarConfig[dir]) ) )
+      {
+         thePlanarConfig[dir] = PLANARCONFIG_CONTIG;
+      }
+      
+      if( !TIFFGetField( theTiffPtr, TIFFTAG_PHOTOMETRIC,
+                         &(thePhotometric[dir]) ) )
+      {
+         thePhotometric[dir] = PHOTOMETRIC_MINISBLACK;
+      }
+      theLut = 0;
+      // Check for palette.
+      uint16* red;
+      uint16* green;
+      uint16* blue;
+      if(TIFFGetField(theTiffPtr, TIFFTAG_COLORMAP, &red, &green, &blue))
+      {
+         if(theApplyColorPaletteFlag)
+         {
+            thePhotometric[dir] = PHOTOMETRIC_PALETTE;
+            theSamplesPerPixel = 3;
+         }
+         populateLut();
+      }
+
+      if( TIFFIsTiled(theTiffPtr))
+      {
+         theRowsPerStrip[dir] = 0;
+         if ( !TIFFGetField( theTiffPtr,
+                             TIFFTAG_TILEWIDTH,
+                             &theImageTileWidth[dir] ) )
+         {
+            theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "ossimTiffTileSource::getTiffTileWidth ERROR:"
+               << "\nCannot determine tile width." << endl;
+            theImageTileWidth[dir] = 0;
+         }
+         if ( !TIFFGetField( theTiffPtr,
+                             TIFFTAG_TILELENGTH,
+                             &theImageTileLength[dir] ) )
+         {
+            theErrorStatus = ossimErrorCodes::OSSIM_ERROR;   
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "ossimTiffTileSource::getTiffTileLength ERROR:"
+               << "\nCannot determine tile length." << endl;
+             theImageTileLength[dir] = 0;
+         }
+      }
+      else
+      {
+         theImageTileWidth[dir]  = 0;
+         theImageTileLength[dir] = 0;
+         if( !TIFFGetField( theTiffPtr, TIFFTAG_ROWSPERSTRIP,
+                            &(theRowsPerStrip[dir]) ) )
+         {
+            theRowsPerStrip[dir] = 1;
+         }
+      }
+      
+      if ( !TIFFGetField( theTiffPtr,
+                          TIFFTAG_IMAGELENGTH,
+                          &theImageLength[dir] ) )
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " Cannot determine image length."
+            << endl;
+      }
+
+      if ( !TIFFGetField( theTiffPtr,
+                          TIFFTAG_IMAGEWIDTH,
+                          &theImageWidth[dir] ) )
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " Cannot determine image width."
+            << endl;
+      }
+      
+   }  // End of "for (ossim_uint32 dir=0; dir<theNumberOfDirectories; dir++)"
+
+   // Reset the directory back to "0".
+   if (setTiffDirectory(0) == false)
+   {
+      return false;
+   }
+
+   //---
+   // Get the scalar type.
+   //---
+   theScalarType = OSSIM_SCALAR_UNKNOWN;
+   
+   if (theBitsPerSample == 16)
+   {
+      theBytesPerPixel = 2;
+      theScalarType = OSSIM_USHORT16; // Default to unsigned...
+      
+      if (theMaxSampleValue == 2047) // 2^11-1
+      {
+         theScalarType = OSSIM_USHORT11; // IKONOS probably...
+      }
+      else if (theSampleFormatUnit == SAMPLEFORMAT_INT)
+      {
+         theScalarType = OSSIM_SSHORT16;
+      }
+   }
+   else if ( (theBitsPerSample == 32) &&
+             (theSampleFormatUnit == SAMPLEFORMAT_UINT) )
+   {
+      theBytesPerPixel = 4;
+      theScalarType = OSSIM_UINT32;
+   }
+   else if (theBitsPerSample == 32 &&
+            theSampleFormatUnit == SAMPLEFORMAT_IEEEFP)
+   {
+      theBytesPerPixel = 4;
+      theScalarType = OSSIM_FLOAT;
+   }
+   else if(theBitsPerSample == 64 &&
+	   theSampleFormatUnit == SAMPLEFORMAT_IEEEFP)
+     {
+       theBytesPerPixel = 8;
+       theScalarType = OSSIM_DOUBLE;
+     }
+   else if (theBitsPerSample <= 8)
+   {
+      theBytesPerPixel = 1;
+      theScalarType = OSSIM_UCHAR;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error:\nCannot determine scalar type.\n"
+         << "Trace dump follows:\n";
+      print(ossimNotify(ossimNotifyLevel_WARN));
+      
+      return false;
+   }
+   double tempMax = ossimGetDefaultMax(theScalarType);
+   double tempMin = ossimGetDefaultMin(theScalarType);
+
+   if(theMinSampleValue == OSSIM_DBL_NAN)
+   {
+      theMinSampleValue = tempMin;
+   }
+   if(theMaxSampleValue == OSSIM_DBL_NAN)
+   {
+      theMaxSampleValue = tempMax;
+   }
+   
+   setReadMethod();
+   
+   // Check for an overview file...
+   if (theOverview == NULL)
+   {
+      openOverview();
+   }
+
+   openValidVertices();
+   loadMetaData();
+
+   initializeBuffers();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " Debug:";
+      print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+   
+   // Finished...
+   return true;
+}
+   
+ossim_uint32 ossimTiffTileSource::getNumberOfLines(ossim_uint32 reduced_res_level) const
+{
+   if(!theTiffPtr) return OSSIM_ULONG_NAN;
+   
+   if (isValidRLevel(reduced_res_level))
+   {
+      if (reduced_res_level && theOverview)
+      {
+         return theOverview->getNumberOfLines(reduced_res_level);
+      }
+      
+      return (theR0isFullRes ?
+              theImageLength[reduced_res_level] :
+              theImageLength[reduced_res_level - 1]);
+   }
+
+   return OSSIM_ULONG_NAN;
+}
+
+ossim_uint32
+ossimTiffTileSource::getNumberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   if(!theTiffPtr) return OSSIM_ULONG_NAN;
+   if (isValidRLevel(reduced_res_level))
+   {
+      if (reduced_res_level && theOverview)
+      {
+         return theOverview->getNumberOfSamples(reduced_res_level);
+      }
+      
+      return (theR0isFullRes ?
+              theImageWidth[reduced_res_level] :
+              theImageWidth[reduced_res_level-1]);
+   }
+   
+   return OSSIM_ULONG_NAN;
+}
+
+ossim_uint32 ossimTiffTileSource::getNumberOfDecimationLevels() const
+{
+   if (theOverview)
+   {
+      return theOverview->getNumberOfDecimationLevels();
+   }
+   
+   return ( theR0isFullRes ? theNumberOfDirectories :
+            theNumberOfDirectories+1 );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossimScalarType ossimTiffTileSource::getOutputScalarType() const
+{
+   return theScalarType;
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimTiffTileSource::getTileWidth() const
+{
+   return ( theTile.valid() ? theTile->getWidth() : 0 );
+}
+
+//*******************************************************************
+// Public method:
+//*******************************************************************
+ossim_uint32 ossimTiffTileSource::getTileHeight() const
+{
+   return ( theTile.valid() ? theTile->getHeight() : 0 );
+}
+
+bool ossimTiffTileSource::loadTile(const ossimIrect& tile_rect,
+                                   const ossimIrect& clip_rect)
+{
+   static const char MODULE[] = "ossimTiffTileSource::loadTile";
+
+   bool status = false;
+   
+   switch(theReadMethod[theCurrentDirectory])
+   {
+      case READ_TILE:
+         status = loadFromTile(clip_rect);
+         break;
+         
+      case READ_SCAN_LINE:
+         status = loadFromScanLine(clip_rect);
+         break;
+         
+      case READ_RGBA_U8_TILE:
+         status = loadFromRgbaU8Tile(tile_rect, clip_rect);
+         break;
+         
+      case READ_RGBA_U8_STRIP:
+         status = loadFromRgbaU8Strip(tile_rect, clip_rect);
+         break;
+         
+      case READ_RGBA_U8A_STRIP:
+         status = loadFromRgbaU8aStrip(tile_rect, clip_rect);
+         break;
+         
+      default:
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " Unsupported tiff type!" << endl;
+         status = false;
+         break;
+   }
+   
+   return status;
+}
+
+bool ossimTiffTileSource::loadFromScanLine(const ossimIrect& clip_rect)
+{
+   ossimInterleaveType type =
+      (thePlanarConfig[theCurrentDirectory] == PLANARCONFIG_CONTIG) ?
+       OSSIM_BIP : OSSIM_BIL;
+   
+   if ( theBufferRLevel != getCurrentTiffRLevel() ||
+        !clip_rect.completely_within(theBufferRect) )
+   {
+      //***
+      // Must reload the buffer.  Grab enough lines to fill the depth of the
+      // clip rectangle.
+      //***
+      theBufferRLevel = getCurrentTiffRLevel();
+      theBufferRect   = getImageRectangle(theBufferRLevel);
+      theBufferRect.set_uly(clip_rect.ul().y);
+      theBufferRect.set_lry(clip_rect.lr().y);
+      ossim_uint32 startLine = clip_rect.ul().y;
+      ossim_uint32 stopLine  = clip_rect.lr().y;
+      ossim_uint8* buf = theBuffer;
+
+      if (thePlanarConfig[theCurrentDirectory] == PLANARCONFIG_CONTIG)
+      {
+         ossim_uint32 lineSizeInBytes = getNumberOfSamples(theBufferRLevel) *
+                                  theBytesPerPixel * theSamplesPerPixel;
+
+         for (ossim_uint32 line = startLine; line <= stopLine; ++line)
+         {
+            TIFFReadScanline(theTiffPtr, (void*)buf, line, 0);
+            buf += lineSizeInBytes;
+         }
+      }
+      else
+      {
+         ossim_uint32 lineSizeInBytes = getNumberOfSamples(theBufferRLevel) *
+                                  theBytesPerPixel;
+
+         for (ossim_uint32 line = startLine; line <= stopLine; ++line)
+         {
+            for (ossim_uint32 band = 0; band < theSamplesPerPixel; ++band)
+            {
+               TIFFReadScanline(theTiffPtr, (void*)buf, line, band);
+               buf += lineSizeInBytes;
+            }
+         }
+      }
+   }
+
+   theTile->loadTile(theBuffer,
+                     theBufferRect,
+                     clip_rect,
+                     type);
+   return true;
+}
+
+bool ossimTiffTileSource::loadFromTile(const ossimIrect& clip_rect)
+{
+   static const char MODULE[] = "ossimTiffTileSource::loadFromTile";
+   
+   //***
+   // Shift the upper left corner of the "clip_rect" to the an even tile
+   // boundary.  Note this will shift in the upper left direction.
+   //***
+   ossimIpt tileOrigin = clip_rect.ul();
+   adjustToStartOfTile(tileOrigin);
+   
+   //---
+   // Calculate the number of tiles needed in the line/sample directions.
+   //---
+
+        
+   ossim_uint32 tiles_in_v_dir = (clip_rect.lr().x-tileOrigin.x+1) /
+      theImageTileWidth[theCurrentDirectory];
+   ossim_uint32 tiles_in_u_dir = (clip_rect.lr().y-tileOrigin.y+1) /
+      theImageTileLength[theCurrentDirectory];
+
+   if ( (clip_rect.lr().x-tileOrigin.x+1) %
+        theImageTileWidth[theCurrentDirectory]  ) ++tiles_in_v_dir;
+   if ( (clip_rect.lr().y-tileOrigin.y+1) %
+        theImageTileLength[theCurrentDirectory] ) ++tiles_in_u_dir;
+
+   ossimInterleaveType type =
+   (thePlanarConfig[theCurrentDirectory] == PLANARCONFIG_CONTIG) ?
+   OSSIM_BIP : OSSIM_BIL;
+
+   ossimIpt ulTilePt = tileOrigin;
+   
+   // Tile loop in line direction.
+   for (ossim_uint32 u=0; u<tiles_in_u_dir; ++u)
+   {
+      ulTilePt.x = tileOrigin.x;
+
+      // Tile loop in sample direction.
+      for (ossim_uint32 v=0; v<tiles_in_v_dir; ++v)
+      {
+         ossimIrect tiff_tile_rect(ulTilePt.x,
+                                   ulTilePt.y,
+                                   ulTilePt.x +
+                                   theImageTileWidth[theCurrentDirectory]  - 1,
+                                   ulTilePt.y +
+                                   theImageTileLength[theCurrentDirectory] - 1);
+         
+         if (tiff_tile_rect.intersects(clip_rect))
+         {
+            ossimIrect tiff_tile_clip_rect
+               = tiff_tile_rect.clipToRect(clip_rect);
+            
+            if  (thePlanarConfig[theCurrentDirectory] == PLANARCONFIG_CONTIG)
+            {
+               if (TIFFReadTile(theTiffPtr,
+                                theBuffer,
+                                ulTilePt.x,
+                                ulTilePt.y,
+                                0,
+                                0) == -1)
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << MODULE << " Read Error!"
+                     << "\nReturning error...  " << endl;
+                  theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+                  return false;
+               }
+
+               theTile->loadTile(theBuffer,
+                                 tiff_tile_rect,
+                                 tiff_tile_clip_rect,
+                                 type);
+            }
+            else
+            {
+               // band separate tiles...
+               for (ossim_uint32 band=0; band<theSamplesPerPixel; ++band)
+               {
+                  // Read a tile into the buffer.
+                  if (TIFFReadTile(theTiffPtr,
+                                   theBuffer,
+                                   ulTilePt.x,
+                                   ulTilePt.y,
+                                   0,
+                                   band) == -1)
+                  {
+                     ossimNotify(ossimNotifyLevel_WARN)
+                        << MODULE << " Read Error!"
+                        << "\nReturning error...  " << endl;
+                     theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+                     return false;
+                  }
+                  
+                  theTile->loadBand(theBuffer,
+                                    tiff_tile_rect,
+                                    tiff_tile_clip_rect,
+                                    band);
+               }
+            }
+
+         } // End of if (tiff_tile_rect.intersects(clip_rect))
+         
+         ulTilePt.x += theImageTileWidth[theCurrentDirectory];
+         
+      }  // End of tile loop in the sample direction.
+
+      ulTilePt.y += theImageTileLength[theCurrentDirectory];
+      
+   }  // End of tile loop in the line direction.
+
+   return true;
+}
+
+bool ossimTiffTileSource::loadFromRgbaU8Tile(const ossimIrect& tile_rect,
+                                             const ossimIrect& clip_rect)
+{
+   static const char MODULE[] = "ossimTiffTileSource::loadFromRgbaTile";
+
+   if (theSamplesPerPixel != 3 || theBytesPerPixel!=1)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error:"
+         << "\nInvalid number of bands or bytes per pixel!" << endl;
+   }
+   
+   //***
+   // Shift the upper left corner of the "clip_rect" to the an even tile
+   // boundary.  Note this will shift in the upper left direction.
+   //***
+   ossimIpt tileOrigin = clip_rect.ul();
+   adjustToStartOfTile(tileOrigin);
+
+   //---
+   // Calculate the number of tiles needed in the line/sample directions
+   // to fill the tile.
+   //---
+   ossim_uint32 tiles_in_v_dir = (clip_rect.lr().x-tileOrigin.x+1) /
+      theImageTileWidth[theCurrentDirectory];
+   ossim_uint32 tiles_in_u_dir = (clip_rect.lr().y-tileOrigin.y+1) /
+      theImageTileLength[theCurrentDirectory];
+
+   if ( (clip_rect.lr().x-tileOrigin.x+1) %
+        theImageTileWidth[theCurrentDirectory]  ) ++tiles_in_v_dir;
+   if ( (clip_rect.lr().y-tileOrigin.y+1) %
+        theImageTileLength[theCurrentDirectory] ) ++tiles_in_u_dir;
+   
+   ossimIpt ulTilePt = tileOrigin;
+
+#if 0
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\ntile_rect:  " << tile_rect
+           << "\nclip_rect:  " << clip_rect
+           << "\ntiles_in_v_dir:  " << tiles_in_v_dir
+           << "\ntiles_in_u_dir:  " << tiles_in_u_dir
+           << endl;
+   }
+#endif
+   
+   
+   // Tile loop in line direction.
+   for (ossim_uint32 u=0; u<tiles_in_u_dir; u++)
+   {
+      ulTilePt.x = tileOrigin.x;
+
+      // Tile loop in sample direction.
+      for (ossim_uint32 v=0; v<tiles_in_v_dir; v++)
+      {
+         ossimIrect tiff_tile_rect
+            = ossimIrect(ulTilePt.x,
+                         ulTilePt.y,
+                         ulTilePt.x +
+                         theImageTileWidth[theCurrentDirectory]  - 1,
+                         ulTilePt.y +
+                         theImageTileLength[theCurrentDirectory] - 1);
+         
+         if ( getCurrentTiffRLevel() != theBufferRLevel ||
+              tiff_tile_rect     != theBufferRect)
+         {
+            // Need to grab a new tile.
+            // Read a tile into the buffer.
+            if ( !TIFFReadRGBATile(theTiffPtr,
+                                   ulTilePt.x,
+                                   ulTilePt.y,
+                                   (uint32*)theBuffer) ) // use tiff typedef
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << MODULE << " Read Error!"
+                  << "\nReturning error..." << endl;
+               theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+               return false;
+            }
+
+            // Capture the rectangle.
+            theBufferRect   = tiff_tile_rect;
+            theBufferRLevel = getCurrentTiffRLevel();
+         }
+
+         ossimIrect tile_clip_rect = clip_rect.clipToRect(theBufferRect);
+         
+         //***
+         // Get the offset to the first valid pixel.
+         // 
+         // Note: The data in the tile buffer is organized bottom up.  So the
+         //       coordinate must be negated in the line direction since
+         //       the met assumes an origin of upper left.
+         //***
+         ossim_uint32 in_buf_offset =
+              (tiff_tile_rect.lr().y-tile_clip_rect.ul().y)*
+              theImageTileWidth[theCurrentDirectory]*4 +
+              ((tile_clip_rect.ul().x - ulTilePt.x)*4);
+         
+         ossim_uint32 out_buf_offset =
+            (tile_clip_rect.ul().y - tile_rect.ul().y) *
+            ((ossim_int32)theTile->getWidth()) +
+            tile_clip_rect.ul().x - tile_rect.ul().x;
+         
+         //
+         // Get a pointer positioned at the first valid pixel in buffers.
+         //
+         ossim_uint32* s = (ossim_uint32*)(theBuffer + in_buf_offset);  // s for source...
+//         ossim_uint8* s = theBuffer + in_buf_offset;  // s for source...
+         ossim_uint8* r = static_cast<ossim_uint8*>(theTile->getBuf(0))+
+            out_buf_offset;
+         ossim_uint8* g = static_cast<ossim_uint8*>(theTile->getBuf(1))+
+            out_buf_offset;
+         ossim_uint8* b = static_cast<ossim_uint8*>(theTile->getBuf(2))+
+            out_buf_offset;
+         
+         ossim_uint32 lines2copy = tile_clip_rect.lr().y-tile_clip_rect.ul().y+1;
+         ossim_uint32 samps2copy = tile_clip_rect.lr().x-tile_clip_rect.ul().x+1;
+         
+         // Line loop through valid portion of the tiff tile.         
+         for (ossim_uint32 line = 0; line < lines2copy; line++)
+         {
+            // Sample loop through the tiff tile.
+            ossim_uint32 i=0;
+            ossim_uint32 j=0;
+            
+            // note the bands from the TIFF READ are stored in a, b, g, r ordering.
+            // we must reverse the bands and skip the first byte.
+            for (ossim_uint32 sample = 0; sample < samps2copy; sample++)
+            {
+               r[i] = (ossim_uint8)OSSIM_TIFF_UNPACK_R4(s[j]);
+               g[i] = (ossim_uint8)OSSIM_TIFF_UNPACK_G4(s[j]);
+               b[i] = (ossim_uint8)OSSIM_TIFF_UNPACK_B4(s[j]);
+               i++;
+               ++j;
+            }
+            
+            // Increment the pointers by one line.
+            const ossim_uint32 OUTPUT_TILE_WIDTH = theTile->getWidth();
+            r += OUTPUT_TILE_WIDTH;
+            g += OUTPUT_TILE_WIDTH;
+            b += OUTPUT_TILE_WIDTH;
+            s -= theImageTileWidth[theCurrentDirectory];
+         }
+      
+         ulTilePt.x += theImageTileWidth[theCurrentDirectory];
+      
+      }  // End of tile loop in the sample direction.
+      
+      ulTilePt.y += theImageTileLength[theCurrentDirectory];
+      
+   }  // End of tile loop in the line direction.
+   
+   return true;
+}
+
+bool ossimTiffTileSource::loadFromRgbaU8Strip(const ossimIrect& tile_rect,
+                                              const ossimIrect& clip_rect)
+{
+   static const char MODULE[] = "ossimTiffTileSource::loadFromRgbaU8Strip";
+
+   if (theSamplesPerPixel > 4 || theBytesPerPixel != 1)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error:"
+         << "\nInvalid number of bands or bytes per pixel!" << endl;
+   }
+   
+   //***
+   // Calculate the number of strips to read.
+   //***
+   const ossim_uint32 OUTPUT_TILE_WIDTH = theTile->getWidth();
+
+   ossim_uint32 starting_strip = clip_rect.ul().y /
+      theRowsPerStrip[theCurrentDirectory];
+   ossim_uint32 ending_strip   = clip_rect.lr().y /
+      theRowsPerStrip[theCurrentDirectory];
+   ossim_uint32 strip_width    = theImageWidth[theCurrentDirectory]*4;   
+   ossim_uint32 output_tile_offset = (clip_rect.ul().y - tile_rect.ul().y) *
+                                OUTPUT_TILE_WIDTH + clip_rect.ul().x -
+                                tile_rect.ul().x;
+
+#if 0
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\nsamples:         " << theSamplesPerPixel
+           << "\ntile_rect:       " << tile_rect
+           << "\nclip_rect:       " << clip_rect
+           << "\nstarting_strip:  " << starting_strip
+           << "\nending_strip:    " << ending_strip
+           << "\nstrip_width:     " << strip_width
+           << "\noutput_tile_offset:  " << output_tile_offset
+
+           << endl;
+   }
+#endif
+   
+   //***
+   // Get the pointers positioned at the first valid pixel in the buffers.
+   // s = source
+   // d = destination
+   //***
+   ossim_uint32 band;
+
+   ossim_uint8** d = new ossim_uint8*[theSamplesPerPixel];
+   for (band = 0; band < theSamplesPerPixel; band++)
+   {
+      d[band] = static_cast<ossim_uint8*>(theTile->getBuf(band))+output_tile_offset;
+   }
+
+   // Loop through strips...
+   for (ossim_uint32 strip=starting_strip; strip<=ending_strip; strip++)
+   {
+      if (TIFFReadRGBAStrip(theTiffPtr,
+                            (strip*theRowsPerStrip[theCurrentDirectory]),
+                            (uint32*)theBuffer) == 0) // use tiff typedef
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " Error reading strip!" <<endl;
+         delete [] d;
+         return false;
+      }
+
+      //***
+      // If the last strip is a partial strip then the first line of the
+      // strip will be the last line of the image.
+      //***
+      ossim_uint32 last_line = theImageLength[theCurrentDirectory] - 1;
+
+      ossim_uint32 strip_offset
+         = ((strip * theRowsPerStrip[theCurrentDirectory]) +
+            theRowsPerStrip[theCurrentDirectory] - 1) <
+         last_line ?  0 :
+         ((strip * theRowsPerStrip[theCurrentDirectory]) +
+          theRowsPerStrip[theCurrentDirectory] - 1) - last_line;
+
+      ossim_uint32 total_rows = theRowsPerStrip[theCurrentDirectory] -
+         strip_offset;
+      
+      for (ossim_uint32 row=0; row<total_rows; row++)
+      {
+         // Write the line if it's in the clip rectangle.
+         ossim_int32 current_line = strip * theRowsPerStrip[theCurrentDirectory]
+            + row;
+         if  (current_line >= clip_rect.ul().y &&
+              current_line <= clip_rect.lr().y)
+         {
+            //
+            // Position the stip pointer to the correct spot.
+            // 
+            // Note:
+            // A strip is organized from bottom to top and the raster buffer is
+            // orgainized from top to bottom so the lineBuf must be offset
+            // accordingly.
+            //
+               ossim_uint32* s = (ossim_uint32*)(theBuffer+ ((theRowsPerStrip[theCurrentDirectory] - row -
+                                                              strip_offset - 1) * strip_width + clip_rect.ul().x * 4));
+            
+            // Copy the data to the output buffer.
+            ossim_uint32 i=0;
+                                                 
+            for (int32 sample=clip_rect.ul().x;
+                 sample<=clip_rect.lr().x;
+                 sample++)
+            {
+               d[0][i] = OSSIM_TIFF_UNPACK_R4(*s);
+               d[1][i] = OSSIM_TIFF_UNPACK_G4(*s);
+               d[2][i] = OSSIM_TIFF_UNPACK_B4(*s);
+               ++i;
+               ++s;
+            }
+
+            for (band = 0; band < theSamplesPerPixel; band++)
+            {
+               d[band] += OUTPUT_TILE_WIDTH;
+            }
+         }
+      }  // End of loop through rows in a strip.
+
+   }  // End of loop through strips.
+
+   delete [] d;
+               
+   return true;
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+bool ossimTiffTileSource::loadFromRgbaU8aStrip(const ossimIrect& tile_rect,
+                                               const ossimIrect& clip_rect)
+{
+   static const char MODULE[] = "ossimTiffTileSource::loadFromRgbaU8aStrip";
+
+   //***
+   // Specialized for one bit data to handle null values.
+   //***
+   const ossim_uint32 OUTPUT_TILE_WIDTH = theTile->getWidth();
+   const ossim_uint8 NULL_PIX = static_cast<ossim_uint8>(theTile->getNullPix(0));
+   const ossim_uint8 MIN_PIX  = static_cast<ossim_uint8>(theTile->getMinPix(0));
+
+   if (theSamplesPerPixel > 4 || theBytesPerPixel!= 1)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " Error:"
+         << "\nInvalid number of bands or bytes per pixel!" << endl;
+   }
+   
+   //***
+   // Calculate the number of strips to read.
+   //***
+   ossim_uint32 starting_strip = clip_rect.ul().y /
+        theRowsPerStrip[theCurrentDirectory];
+   ossim_uint32 ending_strip   = clip_rect.lr().y /
+      theRowsPerStrip[theCurrentDirectory];
+   ossim_uint32 output_tile_offset = (clip_rect.ul().y - tile_rect.ul().y) *
+                                OUTPUT_TILE_WIDTH + clip_rect.ul().x -
+                                tile_rect.ul().x;
+
+#if 0
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\ntile_rect:       " << tile_rect
+           << "\nclip_rect:       " << clip_rect
+           << "\nstarting_strip:  " << starting_strip
+           << "\nending_strip:    " << ending_strip
+           << "\nstrip_width:     " << strip_width
+           << "\noutput_tile_offset:     " << output_tile_offset
+           << "\nsamples:         " << theSamplesPerPixel
+           << endl;
+   }
+#endif
+   
+   //***
+   // Get the pointers positioned at the first valid pixel in the buffers.
+   // s = source
+   // d = destination
+   //***
+   ossim_uint32 band;
+
+   ossim_uint8** d = new ossim_uint8*[theSamplesPerPixel];
+   for (band = 0; band < theSamplesPerPixel; band++)
+   {
+      d[band] = static_cast<ossim_uint8*>(theTile->getBuf(band))+output_tile_offset;
+   }
+
+   // Loop through strips...
+   for (ossim_uint32 strip=starting_strip; strip<=ending_strip; strip++)
+   {
+      if (TIFFReadRGBAStrip(theTiffPtr,
+                            (strip*theRowsPerStrip[theCurrentDirectory]),
+                            (uint32*)theBuffer) == 0) // use tiff typedef
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " Error reading strip!" <<endl;
+         delete [] d;
+         return false;
+      }
+
+      //***
+      // If the last strip is a partial strip then the first line of the
+      // strip will be the last line of the image.
+      //***
+      ossim_uint32 last_line = theImageLength[theCurrentDirectory] - 1;
+
+      ossim_uint32 strip_offset
+         = ((strip * theRowsPerStrip[theCurrentDirectory]) +
+            theRowsPerStrip[theCurrentDirectory] - 1) < last_line ?  0 :
+         ((strip * theRowsPerStrip[theCurrentDirectory]) +
+          theRowsPerStrip[theCurrentDirectory] - 1) - last_line;
+
+      ossim_uint32 total_rows = theRowsPerStrip[theCurrentDirectory] -
+         strip_offset;
+      
+      for (ossim_uint32 row=0; row<total_rows; row++)
+      {
+         // Write the line if it's in the clip rectangle.
+         ossim_int32 current_line = strip * theRowsPerStrip[theCurrentDirectory]
+            + row;
+         if  (current_line >= clip_rect.ul().y &&
+              current_line <= clip_rect.lr().y)
+         {
+            //***
+            // Position the stip pointer to the correct spot.
+            // 
+            // Note:
+            // A strip is organized from bottom to top and the raster buffer is
+            // orgainized from top to bottom so the lineBuf must be offset
+            // accordingly.
+            //***
+            ossim_uint8* s = theBuffer;
+            s += (theRowsPerStrip[theCurrentDirectory] - row -
+                  strip_offset - 1) *
+                 theImageWidth[theCurrentDirectory] * 4 +
+                 clip_rect.ul().x * 4;
+            
+            // Copy the data to the output buffer.
+            ossim_uint32 i=0;
+            ossim_uint32 j=0;
+            for (int32 sample=clip_rect.ul().x;
+                 sample<=clip_rect.lr().x;
+                 sample++)
+            {
+               for (band = 0; band < theSamplesPerPixel; band++)
+               {
+                  ossim_uint8 pix = s[j + band];
+                  d[band][i] = pix != NULL_PIX ? pix : MIN_PIX;
+               }
+               ++i;
+               j += 4;
+            }
+
+            for (band = 0; band < theSamplesPerPixel; band++)
+            {
+               d[band] += OUTPUT_TILE_WIDTH;
+            }
+         }
+      }  // End of loop through rows in a strip.
+
+   }  // End of loop through strips.
+
+   delete [] d;
+               
+   return true;
+}
+
+void ossimTiffTileSource::adjustToStartOfTile(ossimIpt& pt) const
+{
+   //***
+   // Notes:
+   // - Assumes an origin of (0,0)
+   // - Shifts in to the upper left direction.
+   //***
+   ossim_int32 tw =
+      static_cast<ossim_int32>(theImageTileWidth[theCurrentDirectory]);
+   ossim_int32 th =
+      static_cast<ossim_int32>(theImageTileLength[theCurrentDirectory]);
+   
+   if (pt.x > 0)
+   {
+      pt.x = (pt.x/tw) * tw;
+   }
+   else if (pt.x < 0)
+   {
+      pt.x = ossimAbs(pt.x) < tw ? -tw : (pt.x/tw)*tw;
+   }
+
+   if (pt.y > 0)
+   {
+      pt.y = (pt.y/th) * th;
+   }
+   else if (pt.y < 0)
+   {
+      pt.y = ossimAbs(pt.y) < th ? -th : (pt.y/th)*th;
+   }
+}
+
+bool ossimTiffTileSource::isValidRLevel(ossim_uint32 reduced_res_level) const
+{
+   if ( ( reduced_res_level > getHighestReducedResSet()  ) ||
+        ( !theR0isFullRes && (reduced_res_level == 0) ) )
+   {
+#if 0
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimTiffTileSource::isValidRLevel Invalid reduced_res_level:  "
+         << reduced_res_level
+         << "\nHighest available:  " << getHighestReducedResSet()
+         << "\nR0 is "
+         << (theR0isFullRes ? "valid level." : "not a valid level.") 
+         << endl;
+#endif
+      return false;
+   }
+
+   return true;
+}
+
+ossim_uint32 ossimTiffTileSource::getHighestReducedResSet() const
+{
+   if (theOverview)
+   {
+      return theOverview->getHighestReducedResSet();
+   }
+   
+   return (theR0isFullRes ?
+           theNumberOfDirectories-1 :
+           theNumberOfDirectories);
+}
+
+ossim_uint32 ossimTiffTileSource::getCurrentTiffRLevel() const
+{
+   return (theR0isFullRes ? theCurrentDirectory : theCurrentDirectory + 1);
+}
+
+ossimString ossimTiffTileSource::getReadMethod(ossim_uint32 directory) const
+{
+   switch (theReadMethod[directory])
+   {
+      case READ_RGBA_U8_TILE:
+         return ossimString("READ_RGBA_U8_TILE");
+      case READ_RGBA_U8_STRIP:
+         return ossimString("READ_RGBA_U8_STRIP");
+      case READ_RGBA_U8A_STRIP:
+         return ossimString("READ_RGBA_U8A_STRIP");
+      case READ_SCAN_LINE:
+         return ossimString("READ_SCAN_LINE");
+      case READ_TILE:
+         return ossimString("READ_TILE");
+      case UNKNOWN:
+      default:
+         return ossimString("UNKNOWN");
+   }
+}      
+
+bool ossimTiffTileSource::allocateBuffer()
+{
+   //***
+   // Allocate memory for a buffer to hold data grabbed from the tiff file.
+   //***
+   ossim_uint32 buffer_size=0;
+   switch (theReadMethod[theCurrentDirectory])
+   {
+      case READ_RGBA_U8_TILE:
+         buffer_size = theImageTileWidth[theCurrentDirectory]*
+            theImageTileWidth[theCurrentDirectory]*theBytesPerPixel*4;
+         break;
+         
+      case READ_TILE:
+         if (thePlanarConfig[theCurrentDirectory] == PLANARCONFIG_CONTIG)
+         {
+            buffer_size = theImageTileWidth[theCurrentDirectory] *
+               theImageTileLength[theCurrentDirectory] *
+               theBytesPerPixel * theSamplesPerPixel;
+         }
+         else
+         {
+            buffer_size = theImageTileWidth[theCurrentDirectory] *
+               theImageTileLength[theCurrentDirectory] *
+               theBytesPerPixel;
+         }
+         break;
+         
+      case READ_RGBA_U8_STRIP:
+      case READ_RGBA_U8A_STRIP:
+         buffer_size = theImageWidth[0]*theRowsPerStrip[theCurrentDirectory]*
+            theBytesPerPixel*4;
+         break;
+         
+      case READ_SCAN_LINE:
+         buffer_size = theImageWidth[0] * theBytesPerPixel *
+            theSamplesPerPixel * theTile->getHeight();
+         break;
+         
+      default:
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Unknown read method!" << endl;
+         print(ossimNotify(ossimNotifyLevel_WARN));
+         return false;
+         break;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimTiffTileSource::allocateBuffer DEBUG:"
+         << "\nbuffer_size:  " << buffer_size
+         << endl;
+   }
+
+   theBufferRect.makeNan();
+   theBufferRLevel = theCurrentDirectory;
+
+   if (buffer_size != theBufferSize)
+   {
+      theBufferSize = buffer_size;
+      if (theBuffer)
+      {
+         delete [] theBuffer;
+      }
+      theBuffer = new ossim_uint8[buffer_size];
+   }
+
+   return true;
+}
+
+ossim_uint32 ossimTiffTileSource::getNumberOfDirectories() const
+{
+   return theNumberOfDirectories;
+}
+
+ossim_uint32 ossimTiffTileSource::getImageTileWidth() const
+{
+   return theImageTileLength[theCurrentDirectory];
+}
+
+ossim_uint32 ossimTiffTileSource::getImageTileHeight() const
+{
+   return theImageTileLength[theCurrentDirectory];
+}
+
+void ossimTiffTileSource::setApplyColorPaletteFlag(bool flag)
+{
+   theApplyColorPaletteFlag = flag;
+   
+   if(isColorMapped())
+   {
+      if(theApplyColorPaletteFlag)
+      {
+         thePhotometric[0] = PHOTOMETRIC_PALETTE;
+         theSamplesPerPixel = 3;
+      }
+      else
+      {
+         thePhotometric[0] = PHOTOMETRIC_MINISBLACK;
+         theSamplesPerPixel = 1; 
+      }
+      
+      setReadMethod();
+
+      initializeBuffers();
+   }
+}
+
+bool ossimTiffTileSource::getApplyColorPaletteFlag()const
+{
+   return theApplyColorPaletteFlag;
+}
+
+ossimString ossimTiffTileSource::getLongName()const
+{
+   return ossimString("TIFF Image Handler");
+}
+
+ossimString ossimTiffTileSource::getShortName()const
+{
+   return ossimString("TIFF Image Handler");
+}
+
+
+std::ostream& ossimTiffTileSource::print(std::ostream& os) const
+{
+   //***
+   // Use a keyword format.
+   //***
+   os << "image_file:                    " << theImageFile
+      << "\nsamples_per_pixel:           " << theSamplesPerPixel
+      << "\nbits_per_sample:             " << theBitsPerSample
+      << "\nsample_format_unit:          " << theSampleFormatUnit
+      << "\nmin_sample_value:            " << theMinSampleValue
+      << "\nmax_sample_value:            " << theMaxSampleValue
+      << "\ntheNumberOfDirectories:      " << theNumberOfDirectories
+      << "\nr0_is_full_res:              " << theR0isFullRes;
+
+   
+   for (ossim_uint32 i=0; i<theNumberOfDirectories; ++i)
+   {
+      os << "\ndirectory[" << i << "]"
+         << "\nimage width:     " << theImageWidth[i]
+         << "\nimage_length:    " << theImageLength[i]
+         << "\nread method:     " << getReadMethod(i).c_str()
+         << "\nplanar:          " << thePlanarConfig[i]
+         << "\nphotometric:     " << thePhotometric[i];
+      if (theRowsPerStrip[i])
+      {
+         os << "\nrows per strip:  " << theRowsPerStrip[i];
+      }
+      if (theImageTileWidth[i])
+      {
+         os << "\ntile_width:      " << theImageTileWidth[i];
+      }
+      if (theImageTileLength[i])
+      {
+         os << "\ntile_length:     " << theImageTileLength[i];
+      }
+      os << endl;
+   }
+
+   if (theTile.valid())
+   {
+      os << "\nOutput tile dump:\n" << *theTile << endl;
+   }
+
+   if (theOverview)
+   {
+      os << "\nOverview file:\n";
+      theOverview->print(os);
+   }
+
+   os << endl;
+   
+   return ossimSource::print(os);
+}
+
+ossim_uint32 ossimTiffTileSource::getNumberOfInputBands() const
+{
+   return theSamplesPerPixel;
+}
+
+ossim_uint32 ossimTiffTileSource::getNumberOfOutputBands () const
+{
+   return getNumberOfInputBands();
+}
+
+bool ossimTiffTileSource::isOpen()const
+{
+   return (theTiffPtr!=NULL);
+}
+
+bool ossimTiffTileSource::hasR0() const
+{
+   return theR0isFullRes;
+}
+
+double ossimTiffTileSource::getMinPixelValue(ossim_uint32 band)const
+{
+   if(theMetaData.getNumberOfBands())
+   {
+      return ossimImageHandler::getMinPixelValue(band);
+   }
+   return theMinSampleValue;
+}
+
+double ossimTiffTileSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(theMetaData.getNumberOfBands())
+   {
+      return ossimImageHandler::getMaxPixelValue(band);
+   }
+   return theMaxSampleValue;
+}
+
+bool ossimTiffTileSource::isColorMapped() const
+{
+   uint16* red;
+   uint16* green;
+   uint16* blue;
+   
+   return static_cast<bool>(TIFFGetField(theTiffPtr,
+                                         TIFFTAG_COLORMAP,
+                                         &red, &green, &blue));
+}
+
+void ossimTiffTileSource::setReadMethod()
+{
+   for (ossim_uint32 dir=0; dir<theNumberOfDirectories; ++dir)
+   {
+      if (setTiffDirectory(dir) == false)
+      {
+         return;
+      }
+      
+      //---
+      // Establish how this tiff directory will be read.
+      //---
+      if (TIFFIsTiled(theTiffPtr)) 
+      {
+         if ( ( thePhotometric[dir] == PHOTOMETRIC_YCBCR ||
+                thePhotometric[dir] == PHOTOMETRIC_PALETTE ) &&
+              (theSamplesPerPixel <= 3) &&
+              (theBitsPerSample   <= 8 ))
+         {
+            theReadMethod[dir] = READ_RGBA_U8_TILE;
+         }
+         else
+         {
+            theReadMethod[dir] = READ_TILE;
+         }
+      }
+      else // Not tiled...
+      {
+         if ( (thePhotometric[dir] == PHOTOMETRIC_PALETTE ||
+               thePhotometric[dir] == PHOTOMETRIC_YCBCR ) &&
+              theSamplesPerPixel <= 3 &&
+              theBitsPerSample   <= 8 )
+         {
+            theReadMethod[dir] = READ_RGBA_U8_STRIP;
+         }
+         else if (theSamplesPerPixel <= 3 && theBitsPerSample == 1)
+         {
+            //---
+            // Note:  One bit data expands to zeroes and 255's so run it through
+            //        a specialized method to flip zeroes to one's since zeroes
+            //        are usually reserved for null value.
+            //---
+            theReadMethod[dir] = READ_RGBA_U8A_STRIP;
+         }
+         else
+         {
+            theReadMethod[dir] = READ_SCAN_LINE;
+         }
+      }
+      
+   } // End of loop through directories.
+
+   // Reset the directory back to "0".
+   setTiffDirectory(0);
+}
+
+void ossimTiffTileSource::initializeBuffers()
+{
+   if(theBuffer)
+   {
+      delete [] theBuffer;
+      theBuffer = 0;
+   }
+
+   ossimImageDataFactory* idf = ossimImageDataFactory::instance();
+
+   theTile = idf->create(this,
+                         this);
+   
+   //
+   // Tiles are constructed with no buffer storage.  Call initialize for
+   // "theTile" to allocate memory.  Leave "theBlankTile" with a
+   // ossimDataObjectStatus of OSSIM_NULL since no data will ever be
+   // stuffed in it.
+   //
+   theTile->initialize();
+   allocateBuffer();
+}
+
+
+void ossimTiffTileSource::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property.valid())
+   {
+      return;
+   }
+   if(property->getName() == "apply_color_palette_flag")
+   {
+      // Assuming first directory...
+      setApplyColorPaletteFlag(property->valueToString().toBool());
+   }
+   else
+   {
+      ossimImageHandler::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimTiffTileSource::getProperty(const ossimString& name)const
+{
+   if(name == "apply_color_palette_flag")
+   {
+      ossimBooleanProperty* property = new ossimBooleanProperty("apply_color_palette_flag",
+                                                                theApplyColorPaletteFlag);
+      property->clearChangeType();
+      property->setFullRefreshBit();
+      return property;
+   }
+   
+   return ossimImageHandler::getProperty(name);
+}
+
+void ossimTiffTileSource::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageHandler::getPropertyNames(propertyNames);
+
+   // Assuming first directory...
+   if(isColorMapped())
+   {
+      propertyNames.push_back("apply_color_palette_flag");
+   }
+}
+
+bool ossimTiffTileSource::setTiffDirectory(ossim_uint32 directory)
+{
+   bool status = TIFFSetDirectory(theTiffPtr, directory);
+   if (status == true)
+   {
+      theCurrentDirectory = directory;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimTiffTileSource::setTiffDirectory ERROR setting directory "
+         << directory << "!" << endl;
+   }
+   return status;
+}
+
+void ossimTiffTileSource::populateLut()
+{
+   ossim_uint16* r;
+   ossim_uint16* g;
+   ossim_uint16* b;
+   if(TIFFGetField(theTiffPtr, TIFFTAG_COLORMAP, &r, &g, &b))
+   {
+      ossim_uint32 numEntries = 256;
+      ossimScalarType scalarType = OSSIM_UINT8;
+      if(theBitsPerSample == 16)
+      {
+         numEntries = 65536;
+         scalarType = OSSIM_UINT16;
+      }
+      theLut = new ossimNBandLutDataObject(numEntries,
+                                           3,
+                                           scalarType,
+                                           0);
+      ossim_uint32 entryIdx = 0;
+      for(entryIdx = 0; entryIdx < numEntries; ++entryIdx)
+      {
+         if(scalarType == OSSIM_UINT8)
+         {
+            (*theLut)[entryIdx][0] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(((*r)/65535.0)*255.0);
+            (*theLut)[entryIdx][1] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(((*g)/65535.0)*255.0);
+            (*theLut)[entryIdx][2] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(((*b)/65535.0)*255.0);
+         }
+         else
+         {
+            (*theLut)[entryIdx][0] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(*r);
+            (*theLut)[entryIdx][1] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(*g);
+            (*theLut)[entryIdx][2] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(*b);
+         }
+         ++r;++g;++b;
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffTileSource.h
new file mode 100644
index 0000000000..799f7a2325
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffTileSource.h
@@ -0,0 +1,268 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//          Frank Warmerdam (warmerdam@pobox.com)
+//
+// Description:
+//
+// Contains class declaration for ossimTiffTileSource.
+// ossimTiffTileSource  is derived from ImageHandler which is derived from
+// TileSource.
+//*******************************************************************
+//  $Id: ossimTiffTileSource.h,v 1.37 2005/11/08 21:50:21 dburken Exp $
+
+#ifndef ossimTiffTileSource_HEADER
+#define ossimTiffTileSource_HEADER
+
+#include <tiffio.h>
+
+#include <imaging/formats/ossimImageHandler.h>
+#include <base/data_types/ossimIrect.h>
+
+class ossimImageData;
+class ossimTiffOverviewTileSource;
+
+class OSSIMDLLEXPORT ossimTiffTileSource : public ossimImageHandler
+{
+public:
+
+   enum ReadMethod
+   {
+      UNKNOWN,
+      READ_RGBA_U8_TILE,
+      READ_RGBA_U8_STRIP,
+      READ_RGBA_U8A_STRIP,
+      READ_SCAN_LINE,
+      READ_TILE
+   };
+
+   ossimTiffTileSource();
+	
+   virtual ~ossimTiffTileSource();
+
+   virtual ossimString getLongName()  const;
+   virtual ossimString getShortName() const;
+
+   /*!
+    *  Returns true if the image_file can be opened and is a valid tiff file.
+    */
+  virtual bool open(const ossimFilename& image_file);
+  virtual void close();
+
+   /*!
+    *  Returns a pointer to a tile given an origin representing the upper left
+    *  corner of the tile to grab from the image.
+    *  Satisfies pure virtual from TileSource class.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+   
+   /*!
+     *  Returns the number of bands in the image.
+     *  Satisfies pure virtual from ImageHandler class.
+     */
+   virtual ossim_uint32 getNumberOfInputBands() const;
+   virtual ossim_uint32 getNumberOfOutputBands () const;
+   
+   /*!
+     *  Returns the number of lines in the image.
+     *  Satisfies pure virtual from ImageHandler class.
+     */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
+
+   /*!
+    *  Returns the number of samples in the image.
+    *  Satisfies pure virtual from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
+
+   /*!
+    *  Returns the number of image file directories in the tiff image.
+    */
+   virtual ossim_uint32 getNumberOfDirectories() const;
+   
+   /*!
+    * Returns the number of reduced resolution data sets (rrds).
+    * Notes:
+    *
+    * - The full res image is counted as a data set so an image with no
+    *   reduced resolution data set will have a count of one.
+    * - This method counts R0 as a res set even if it does not have one.
+    *   This was done deliberately so as to not screw up code down the
+    *   line.
+    */
+   virtual ossim_uint32 getNumberOfDecimationLevels() const;
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual bool isOpen()const;
+
+   /*!
+    * Returns the output pixel type of the tile source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /*!
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32 getTileWidth() const;
+   
+   /*!
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   /*!
+    *  Returns true if the first directory of the tiff image did not have
+    *  the reduced resolution file type set.
+    */
+   bool hasR0() const;
+  
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   
+   virtual bool isValidRLevel(ossim_uint32 reduced_res_level) const;
+   
+   /*!
+    * Returns the highest available reduced resolution data sets (rrds).
+    * Note:  zero based
+    */
+   ossim_uint32 getHighestReducedResSet() const;
+
+   /*!
+    * @return The tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width, which can be different than the
+    * internal image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /*!
+    * @return The tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileHeight which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;
+
+   void setApplyColorPaletteFlag(bool flag);
+   bool getApplyColorPaletteFlag()const;
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   bool isColorMapped() const;
+   
+   virtual std::ostream& print(std::ostream& os) const;
+
+protected:
+   /*!
+    *  Returns true if no errors initializing object.
+    *
+    *  Notes:
+    *  - Callers of this method must ensure "theTiffPtr" data member
+    *    is initialized.
+    *  - This method was added to consolidate object initialization code
+    *    between constructor and public open method.
+    */
+   bool open();
+   
+private:
+
+   /*!
+    *  Adjust point to even tile boundary.  Assumes 0,0 origin.
+    *  Shifts in the upper left direction.
+    */
+   void adjustToStartOfTile(ossimIpt& pt) const;
+
+   /*!
+    *  If the tiff source has R0 then this returns the current tiff directory
+    *  that the tiff pointer is pointing to; else, it returns the current
+    *  directory + 1.
+    */
+   ossim_uint32 getCurrentTiffRLevel() const;
+   
+   ossimString getReadMethod(ossim_uint32 directory) const;
+
+   bool allocateBuffer();
+   
+   bool loadTile(const ossimIrect& tile_rect,
+                 const ossimIrect& clip_rect);
+   
+   bool loadFromRgbaU8Tile(const ossimIrect& tile_rect,
+                           const ossimIrect& clip_rect);
+   
+   bool loadFromRgbaU8Strip(const ossimIrect& tile_rect,
+                            const ossimIrect& clip_rect);
+
+   bool loadFromRgbaU8aStrip(const ossimIrect& tile_rect,
+                             const ossimIrect& clip_rect);
+   
+   bool loadFromScanLine(const ossimIrect& clip_rect);
+
+   bool loadFromTile(const ossimIrect& clip_rect);
+
+   void setReadMethod();
+   virtual void initializeBuffers();
+
+   /**
+    * Change tiff directory and sets theCurrentDirectory.
+    *
+    * @return true on success, false on error.
+    */
+   bool setTiffDirectory(ossim_uint32 directory);
+
+   void populateLut();
+   
+   ossimRefPtr<ossimImageData> theTile;
+   
+   ossim_uint8*         theBuffer;
+   ossim_uint32         theBufferSize;
+   ossimIrect           theBufferRect;
+   ossim_uint32         theBufferRLevel;
+   TIFF*                theTiffPtr;
+
+   ossim_uint16         theSamplesPerPixel;
+   ossim_uint16         theBitsPerSample;
+   ossim_uint16         theSampleFormatUnit;
+   double               theMaxSampleValue;
+   double               theMinSampleValue;
+   ossim_uint32         theNumberOfDirectories;
+   ossim_uint32         theCurrentDirectory;
+   bool                 theR0isFullRes;
+   ossim_uint32         theBytesPerPixel;
+   ossimScalarType      theScalarType;
+   bool                 theApplyColorPaletteFlag;
+
+   // Things we need from each directory as they can be different.
+   vector<ossim_uint32> theImageWidth;
+   vector<ossim_uint32> theImageLength;
+   vector<ReadMethod>   theReadMethod;
+   vector<ossim_uint16> thePlanarConfig;
+   vector<ossim_uint16> thePhotometric;
+   vector<ossim_uint32> theRowsPerStrip;
+   vector<ossim_uint32> theImageTileWidth;
+   vector<ossim_uint32> theImageTileLength;
+   
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffWriter.cpp
new file mode 100644
index 0000000000..ee06f77eca
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffWriter.cpp
@@ -0,0 +1,2316 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Frank Warmerdam (warmerda@home.com)
+//
+//*******************************************************************
+//  $Id: ossimTiffWriter.cpp,v 1.145 2006/01/06 16:46:46 dburken Exp $
+
+#include <algorithm>
+#include <sstream>
+
+#include <ossimConfig.h>
+
+#include <imaging/formats/tiff/ossimTiffWriter.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/common/ossimTrace.h>
+#include <base/property/ossimNumericProperty.h>
+#include <base/property/ossimStringProperty.h>
+#include <base/property/ossimBooleanProperty.h>
+#include <base/property/ossimFilenameProperty.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSource.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/misc/lookup_tables/ossimUnitTypeLut.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/property/ossimFilenameProperty.h>
+
+static ossimTrace traceDebug("ossimTiffWriter:debug");
+
+#ifdef OSSIM_HAS_GEOTIFF
+#  if OSSIM_HAS_GEOTIFF
+#    include <xtiffio.h>
+#    include <geotiff.h>
+#    include <geo_normalize.h>
+#    include <geovalues.h>
+#  endif
+#endif
+
+static const char* TIFF_WRITER_OUTPUT_TILE_SIZE_X_KW = "output_tile_size_x";
+static const char* TIFF_WRITER_OUTPUT_TILE_SIZE_Y_KW = "output_tile_size_y";
+static const int   PCS_BRITISH_NATIONAL_GRID = 27700;
+static const long  DEFAULT_JPEG_QUALITY = 75;
+
+RTTI_DEF1(ossimTiffWriter, "ossimTiffWriter", ossimImageFileWriter);
+
+ossimTiffWriter::ossimTiffWriter()
+   :
+      ossimImageFileWriter(),
+      theTif(NULL),
+      thePixelType(OSSIM_PIXEL_IS_POINT),
+      theProjectionUnits(OSSIM_METERS),
+      theCompressionType("none"),
+      theJpegQuality(DEFAULT_JPEG_QUALITY),
+      theOutputGeotiffTagsFlag(true),
+      theImagineNad27Flag(false),
+      theColorLutFlag(false),
+      theProjectionInfo(NULL),
+      theOutputTileSize(OSSIM_DEFAULT_TILE_WIDTH, OSSIM_DEFAULT_TILE_HEIGHT)
+{
+   ossimGetDefaultTileSize(theOutputTileSize);
+   theOutputImageType = "tiff_tiled_band_separate";
+}
+
+ossimTiffWriter::~ossimTiffWriter()
+{
+   if(isOpen())
+   {
+      closeTiff();
+   }
+   if(theProjectionInfo)
+   {
+      delete theProjectionInfo;
+      theProjectionInfo = NULL;
+   }
+}
+
+bool ossimTiffWriter::openTiff()
+{
+   static const char* MODULE = "ossimTiffWriter::openTiff()";
+
+   if (theTif) // Close the existing file pointer.
+   {
+      
+#ifdef OSSIM_HAS_GEOTIFF
+#  if OSSIM_HAS_GEOTIFF 
+      XTIFFClose( theTif );
+#  else
+      TIFFClose( theTif );
+#  endif
+#else
+      TIFFClose( theTif );   
+#endif
+
+   }
+
+   // Open the new file.
+#ifdef OSSIM_HAS_GEOTIFF
+#  if OSSIM_HAS_GEOTIFF
+   theTif = XTIFFOpen( theFilename.c_str(), "w" );
+#  else
+   theTif = TIFFOpen( theFilename.c_str(), "w" );
+#  endif
+#else
+   theTif = TIFFOpen( theFilename.c_str(), "w" );
+#endif
+
+   if (!theTif)
+   {
+      setErrorStatus(); // base class
+      ossimSetError(getClassName().c_str(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "File %s line %d Module %s Error:\n\
+Error opening file:  %s\n",
+                    __FILE__,
+                    __LINE__,
+                    MODULE,
+                    theFilename.c_str());
+
+      return false;
+   }
+   return true;
+}
+
+bool ossimTiffWriter::closeTiff()
+{
+   if (theTif)
+   {
+#ifdef OSSIM_HAS_GEOTIFF
+#  if OSSIM_HAS_GEOTIFF
+      XTIFFClose( theTif );
+#  else
+      TIFFClose( theTif );
+#  endif
+#else
+      TIFFClose( theTif );
+#endif
+      theTif = NULL;
+   }
+
+   return true;
+}
+
+bool ossimTiffWriter::writeTiffTags()
+{
+   static const char MODULE[] = "ossimTiffWriter::writeTiffTags";
+
+   if (!theTif)
+   {
+      setErrorStatus(); // base class
+      ossimSetError(getClassName().c_str(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "File %s line %d %s\nError:  Tiff pointer is null!\n\
+Call setFilename method.\n",
+                    __FILE__,
+                    __LINE__,
+                    MODULE);
+      return false;
+   }
+
+   //***
+   // NOTE:
+   // Since the tiff library uses the variable argument list function "va_arg"
+   // it is important to use the correct data type.  If in doubt see the
+   // code for libtiff's _TIFFVSetField in "tif_dir.c" in the libtiff package.
+   //***
+
+   int bitsPerSample  = 0;
+   int sampleFormat   = 0;
+   switch( theInputConnection->getOutputScalarType() )
+   {
+   case OSSIM_UINT8:
+      bitsPerSample = 8;
+      sampleFormat = SAMPLEFORMAT_UINT;
+      break;
+
+   case OSSIM_UINT16:
+   case OSSIM_USHORT11:
+      bitsPerSample = 16;
+      sampleFormat = SAMPLEFORMAT_UINT;
+      break;
+
+   case OSSIM_SINT16:
+      bitsPerSample = 16;
+      sampleFormat = SAMPLEFORMAT_INT;
+      break;
+
+   case OSSIM_FLOAT32:
+   case OSSIM_NORMALIZED_FLOAT:
+      bitsPerSample = 32;
+      sampleFormat = SAMPLEFORMAT_IEEEFP;
+      break;
+
+   case OSSIM_NORMALIZED_DOUBLE:
+   case OSSIM_FLOAT64:
+      bitsPerSample = 64;
+      sampleFormat = SAMPLEFORMAT_IEEEFP;
+      break;
+
+   default:
+      return false;
+   }
+
+   // Set the pixel type.
+   TIFFSetField( theTif, TIFFTAG_BITSPERSAMPLE, bitsPerSample );
+   TIFFSetField( theTif, TIFFTAG_SAMPLEFORMAT, sampleFormat );
+
+   // Set the image dimensions.
+   ossim_uint32  width  = theAreaOfInterest.width();
+   ossim_uint32  height = theAreaOfInterest.height();
+   TIFFSetField( theTif, TIFFTAG_IMAGEWIDTH, width);
+   TIFFSetField( theTif, TIFFTAG_IMAGELENGTH, height);
+   if (isTiled())
+   {
+      ossim_uint32 tileXSize = theOutputTileSize.x;
+      ossim_uint32 tileYSize = theOutputTileSize.y;
+      TIFFSetField(theTif, TIFFTAG_TILEWIDTH,  tileXSize);
+      TIFFSetField(theTif, TIFFTAG_TILELENGTH, tileYSize);
+   }
+   else
+   {
+      TIFFSetField(theTif, TIFFTAG_ROWSPERSTRIP, ossim_uint32(1));
+   }
+
+   ossim_uint32 numberOfBands = theInputConnection->getNumberOfOutputBands();
+
+   // Set the min/max values.
+   std::vector<ossim_float64> minBand(numberOfBands);
+   std::vector<ossim_float64> maxBand(numberOfBands);
+   for(ossim_uint32 idx = 0; idx < numberOfBands; ++idx)
+   {
+      maxBand[idx] = theInputConnection->getMaxPixelValue(idx);
+      minBand[idx] = theInputConnection->getMinPixelValue(idx);
+   }
+   
+   writeMinMaxTags(minBand, maxBand);
+   
+   // Set the planar configuration.
+   if ( (theOutputImageType == "tiff_strip") ||
+        (theOutputImageType == "tiff_tiled") ||
+        (theOutputImageType == "image/tiff") ||
+        (theOutputImageType == "image/tif") ||
+        (theOutputImageType == "image/gtif") ||
+        (theOutputImageType == "image/gtiff") )
+   {
+      TIFFSetField( theTif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+   }
+   else
+   {
+      TIFFSetField( theTif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_SEPARATE);
+   }
+
+   // Set the compression type:
+   uint16 tiffCompressType = COMPRESSION_NONE;
+   theCompressionType.downcase();
+   if( theCompressionType == "jpeg")
+   {
+      tiffCompressType  = COMPRESSION_JPEG;
+
+      // Set the jpeg quality.
+      TIFFSetField( theTif, TIFFTAG_JPEGQUALITY,  theJpegQuality);
+   }
+   else if(theCompressionType == "packbits")
+   {
+      tiffCompressType = COMPRESSION_PACKBITS;
+   }
+   else if((theCompressionType == "deflate") ||
+           (theCompressionType == "zip"))
+   {
+      tiffCompressType  = COMPRESSION_DEFLATE;
+   }
+   TIFFSetField( theTif, TIFFTAG_COMPRESSION, tiffCompressType);
+   TIFFSetField(theTif, TIFFTAG_SAMPLESPERPIXEL, (int)theInputConnection->getNumberOfOutputBands());
+
+   ossimScalarType scalarType = theInputConnection->getOutputScalarType();
+   bool lutEnabled = (theColorLutFlag&&
+                      ((scalarType == OSSIM_UINT8)||
+                       (scalarType == OSSIM_UINT16)||
+                       (scalarType == OSSIM_USHORT11))&&
+                      (theColorLut.getNumberOfEntries() > 0)&&
+                      (theInputConnection->getNumberOfOutputBands() == 1));
+   if(lutEnabled)
+   {
+      TIFFSetField( theTif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE );
+      TIFFSetField( theTif, TIFFTAG_INDEXED, (ossim_uint16)1);
+
+      if(scalarType == OSSIM_UINT8)
+      {
+         ossim_uint16 r[256], g[256], b[256];
+         
+         memset(r, '\0', sizeof(ossim_uint16)*256);
+         memset(g, '\0', sizeof(ossim_uint16)*256);
+         memset(b, '\0', sizeof(ossim_uint16)*256);
+         
+         for(ossim_uint32 i = 0; i < theColorLut.getNumberOfEntries(); i++)
+         {
+            r[i] = (ossim_uint16) ((theColorLut[i][0]/255.0)*65535);
+            g[i] = (ossim_uint16) ((theColorLut[i][1]/255.0)*65535);
+            b[i] = (ossim_uint16) ((theColorLut[i][2]/255.0)*65535);
+         }
+         TIFFSetField(theTif, TIFFTAG_COLORMAP, r, g ,b);
+      }
+      else
+      {
+         ossim_uint16 r[65536], g[65536], b[65536];
+         memset(r, '\0', sizeof(ossim_uint16)*65536);
+         memset(g, '\0', sizeof(ossim_uint16)*65536);
+         memset(b, '\0', sizeof(ossim_uint16)*65536);
+         
+         for(ossim_uint32 i = 0; i < theColorLut.getNumberOfEntries(); i++)
+         {
+            r[i] = (ossim_uint16) (theColorLut[i][0]);
+            g[i] = (ossim_uint16) (theColorLut[i][1]);
+            b[i] = (ossim_uint16) (theColorLut[i][2]);
+         }
+         TIFFSetField(theTif, TIFFTAG_COLORMAP, r, g ,b);
+      }
+   }
+   else if( (theInputConnection->getNumberOfOutputBands() == 3 ||
+             theInputConnection->getNumberOfOutputBands() == 4 ||
+             (thePhotoMetric == "rgb"))&&
+            (scalarType == OSSIM_UCHAR))
+   {
+      TIFFSetField( theTif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
+   }
+   else
+   {
+      TIFFSetField( theTif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK );
+   }
+
+   return true;
+}
+
+bool ossimTiffWriter::writeGeotiffTags(ossimMapProjectionInfo* projectionInfo)
+{
+   static const char MODULE[] = "ossimTiffWriter::writeGeotiffTags";
+	
+   if (!theTif)
+   {
+      setErrorStatus(); // base class
+      ossimSetError(getClassName().c_str(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "File %s line %d %s\nError:  Tiff pointer is null!\n\
+Call setFilename method.\n",
+                    __FILE__,
+                    __LINE__,
+                    MODULE);
+      return false;
+   }
+
+#ifdef OSSIM_HAS_GEOTIFF
+#  if OSSIM_HAS_GEOTIFF
+
+   ossimKeywordlist kwl;
+   projectionInfo->setPixelType(thePixelType);
+
+   if(projectionInfo && projectionInfo->getProjection())
+   {
+      projectionInfo->getProjection()->saveState(kwl);
+   }
+   const char* pcs_code     = kwl.find(ossimKeywordNames::PCS_CODE_KW);
+   const char* stdParallel1 = kwl.find(ossimKeywordNames::STD_PARALLEL_1_KW);
+   const char* stdParallel2 = kwl.find(ossimKeywordNames::STD_PARALLEL_2_KW);
+   const char* scaleFactor  = kwl.find(ossimKeywordNames::SCALE_FACTOR_KW);
+   const char* origin  = kwl.find(ossimKeywordNames::ORIGIN_LATITUDE_KW);
+   const char* false_easting  = kwl.find(ossimKeywordNames::FALSE_EASTING_KW);
+   const char* false_northing  = kwl.find(ossimKeywordNames::FALSE_NORTHING_KW);
+   const char* central_meridian  = kwl.find(ossimKeywordNames::CENTRAL_MERIDIAN_KW);
+
+   GTIF* gtif = GTIFNew(theTif);
+
+   // Get a pointer to the projection.
+   const ossimMapProjection* proj = projectionInfo->getProjection();
+   if(theProjectionUnits == OSSIM_US_SURVEY_FEET)
+   {
+      projectionInfo->setOutputFeetFlag(true);
+   }
+   ossimString proj_name = proj->getClassName();
+
+   UnitType units = LINEAR_METER;
+
+   if (projectionInfo->unitsInFeet())
+   {
+      units = LINEAR_FOOT_US_SURVEY;
+   }
+   else if ( ( proj_name == "ossimCylEquAreaProjection" ) ||
+             ( proj_name == "ossimEquDistCylProjection" ) ||
+             ( proj_name == "ossimLlxyProjection" ) )
+   {
+      units = ANGULAR_DEGREES;
+   }
+
+   // Set the model type.
+   if (units == ANGULAR_DEGREES)
+   {
+      GTIFKeySet(gtif,
+                 GTModelTypeGeoKey,
+                 TYPE_SHORT,
+                 1,
+                 ModelTypeGeographic);
+
+      // Set the units key.
+      GTIFKeySet(gtif,
+                 GeogAngularUnitsGeoKey,
+                 TYPE_SHORT,
+                 1,
+                 units);
+   }
+   else
+   {
+      GTIFKeySet(gtif,
+                 GTModelTypeGeoKey,
+                 TYPE_SHORT,
+                 1,
+                 ModelTypeProjected);
+
+      // Set the units key.
+      GTIFKeySet(gtif,
+                 ProjLinearUnitsGeoKey,
+                 TYPE_SHORT,
+                 1,
+                 units);
+   }
+
+   // Set the tie point and scale.
+   double   tiePoints[6]  = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+   double   pixScale[3]   = { 0.0, 0.0, 0.0 };
+
+   switch (units)
+   {
+   case LINEAR_METER:
+   {
+      tiePoints[3] = projectionInfo->ulEastingNorthingPt().x;
+      tiePoints[4] = projectionInfo->ulEastingNorthingPt().y;
+      pixScale[0]  = projectionInfo->getMetersPerPixel().x;
+      pixScale[1]  = projectionInfo->getMetersPerPixel().y;
+      break;
+   }
+   case LINEAR_FOOT_US_SURVEY:
+   {
+      tiePoints[3] = projectionInfo->ulEastingNorthingPtInFt().x;
+      tiePoints[4] = projectionInfo->ulEastingNorthingPtInFt().y;
+      pixScale[0]  = projectionInfo->getUsSurveyFeetPerPixel().x;
+      pixScale[1]  = projectionInfo->getUsSurveyFeetPerPixel().y;
+      break;
+   }
+   case ANGULAR_DEGREES:
+   {
+      tiePoints[3] = projectionInfo->ulGroundPt().lond();
+      tiePoints[4] = projectionInfo->ulGroundPt().latd();
+      pixScale[0]  = projectionInfo->getDecimalDegreesPerPixel().x;
+      pixScale[1]  = projectionInfo->getDecimalDegreesPerPixel().y;
+      break;
+   }
+   } // End of "switch (units)"
+
+   TIFFSetField( theTif, TIFFTAG_GEOTIEPOINTS, 6, tiePoints );
+   TIFFSetField( theTif, TIFFTAG_GEOPIXELSCALE, 3, pixScale );
+
+   if (projectionInfo->getPixelType() == OSSIM_PIXEL_IS_POINT)
+   {
+      // Tie point relative to center of pixel.
+      GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsPoint);
+   }
+   else
+   {
+      // Tie point relative to upper left corner of pixel
+      GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
+   }
+
+   ossimString datumCode = "WGE";
+   ossimString datumName = "WGE";
+   // Attemp to get the datum code
+   const ossimDatum* datum = proj->getDatum();
+   if(datum)
+   {
+      datumCode = datum->code();
+      datumName = datum->name();
+   }
+
+   short gcs = USER_DEFINED;
+
+   if (datumCode == "WGE") gcs = GCS_WGS_84;
+   else if (datumCode == "WGD") gcs = GCS_WGS_72;
+   else if (datumCode == "NAR-C") gcs = GCS_NAD83;
+   else if (datumCode == "NAR") gcs = GCS_NAD83;
+   else if (datumCode == "NAS-C") gcs = GCS_NAD27;
+   else if (datumCode == "NAS") gcs = GCS_NAD27;
+   else if (datumCode == "ADI-M") gcs = GCS_Adindan;
+   else if (datumCode == "ARF-M") gcs = GCS_Arc_1950;
+   else if (datumCode == "ARS-M") gcs = GCS_Arc_1960;
+   else if (datumCode == "EUR-7" || datumCode == "EUR-M") gcs = GCS_ED50;
+   else if ((datumCode == "OGB-7") ||
+            (datumCode == "OGB-M") ||
+            (datumCode == "OGB-A") ||
+            (datumCode == "OGB-B") ||
+            (datumCode == "OGB-C") ||
+            (datumCode == "OGB-D")) gcs = GCS_OSGB_1936;
+   else if (datumCode == "TOY-M") gcs = GCS_Tokyo;
+   else
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DATUM = " << datumCode << " tag not written " << std::endl
+            << "Please let us know so we can add it"          << std::endl;
+      }
+   }
+
+   GTIFKeySet( gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, gcs );
+
+   // ***
+   // ERDAS Imagine < v8.7 has a NAD27 Conus Bug.  They are not using the
+   // proper GCS code.  They use user-defined fields and Geog cititaion tag to
+   // define.  Sucks!  It is an open issue at Leica.  This is a work around
+   // flag for this issue.
+   // ***
+   if((datumCode == "NAS-C") && theImagineNad27Flag)
+   {
+      gcs = USER_DEFINED;
+
+      std::ostringstream os;
+      os << "IMAGINE GeoTIFF Support\nCopyright 1991 -  2001 by ERDAS, Inc. All Rights Reserved\n@(#)$RCSfile: ossimTiffWriter.cpp,v $ $Revision: 1.145 $ $Date: 2006/01/06 16:46:46 $\nUnable to match Ellipsoid (Datum) to a GeographicTypeGeoKey value\nEllipsoid = Clarke 1866\nDatum = NAD27 (CONUS)";
+
+      GTIFKeySet(gtif,
+                 GeogCitationGeoKey,
+                 TYPE_ASCII,
+                 1,
+                 os.str().c_str());
+
+      // User-Defined
+      GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1,
+                 KvUserDefined );
+      // User-Defined
+      GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1,
+                 KvUserDefined );
+   }
+   else
+      GTIFKeySet( gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, gcs );
+
+   // Set the ellipsoid major/minor axis.
+   GTIFKeySet(gtif,
+              GeogSemiMajorAxisGeoKey,
+              TYPE_DOUBLE,
+              1,
+              proj->getA());
+
+   GTIFKeySet(gtif,
+              GeogSemiMinorAxisGeoKey,
+              TYPE_DOUBLE,
+              1,
+              proj->getB());
+
+   // Write the projection parameters.
+
+
+
+   if (proj_name == "ossimUtmProjection")
+   {
+      //***
+      // UTM tags needed example from the geo tiff spec page:
+      // ModelTiepointTag       = (0, 0, 0,  350807.4, 5316081.3, 0.0)
+      // ModelPixelScaleTag     = (100.0, 100.0, 0.0)
+      // GeoKeyDirectoryTag:
+      //       GTModelTypeGeoKey        =  1      (ModelTypeProjected)
+      //       GTRasterTypeGeoKey       =  1      (RasterPixelIsArea)
+      //       ProjectedCSTypeGeoKey    =  32660  (PCS_WGS84_UTM_zone_60N)
+      //       PCSCitationGeoKey        =  "UTM Zone 60 N with WGS84"
+      //
+      // NOTE:
+      // The "ProjectedCSTypeGeoKey" can be constructed using the map zone
+      // and the datum.
+      //***
+      const ossimUtmProjection* utmProjection
+         = PTR_CAST(ossimUtmProjection, proj);
+
+      // Attempt to get the pcs key.
+      int mapZone = utmProjection->getZone();
+      ossimString hemisphere = utmProjection->getHemisphere();
+      bool use_pcs_key = true;
+      short projSysCode=0;
+
+      switch ( gcs )
+      {
+      case GCS_WGS_84:
+      {
+         if (hemisphere == "N") // Northern hemisphere.
+         {
+            projSysCode = 32600 + mapZone;
+         }
+         else // Southern hemisphere.
+         {
+            projSysCode = 32700 + mapZone;
+         }
+         break;
+      }
+
+      case GCS_WGS_72:
+      {
+         if (hemisphere == "N") // Northern hemisphere.
+         {
+            projSysCode = 32200 + mapZone;
+         }
+         else // Southern hemisphere.
+         {
+            projSysCode = 32300 + mapZone;
+         }
+         break;
+      }
+
+      case GCS_NAD27:
+      {
+         if (hemisphere == "N") // Northern hemisphere.
+         {
+            projSysCode = 26700 + mapZone;
+         }
+         else // Southern hemisphere.
+         {
+            projSysCode = 32000 + mapZone;
+         }
+         break;
+      }
+
+      case GCS_NAD83:
+         if (hemisphere == "N") // Northern hemisphere.
+         {
+            projSysCode = 26900 + mapZone;
+         }
+         else // Southern hemisphere.
+         {
+            projSysCode = 32100 + mapZone;
+         }
+         break;
+
+      default:
+      {
+         //***
+         // Use a projection code that does not imply a datum.
+         // See section "6.3.3.2 Projection Codes" for definition.
+         //***
+         use_pcs_key = false;
+         if (mapZone > 0) // Northern hemisphere.
+         {
+            projSysCode = 16000 + mapZone;
+         }
+         else if (mapZone < 0) // Southern hemisphere.
+         {
+            hemisphere = "S";
+            projSysCode = 16100 + abs(mapZone);
+         }
+
+         // Set the Projected Coordinate System Type to be user defined.
+         GTIFKeySet(gtif,
+                    ProjectedCSTypeGeoKey,
+                    TYPE_SHORT,
+                    1,
+                    USER_DEFINED);
+
+         // Set the geographic type to be user defined.
+         GTIFKeySet(gtif,
+                    GeographicTypeGeoKey,
+                    TYPE_SHORT,
+                    1,
+                    USER_DEFINED);
+
+         // Set the ProjectionGeoKey in place of the ProjectedCSTypeGeoKey.
+         GTIFKeySet(gtif,
+                    ProjectionGeoKey,
+                    TYPE_SHORT,
+                    1,
+                    projSysCode);
+         break;
+      }
+
+      } // End of "switch ( gcs )"
+
+      if (use_pcs_key)
+      {
+         GTIFKeySet(gtif,
+                    ProjectedCSTypeGeoKey,
+                    TYPE_SHORT,
+                    1,
+                    projSysCode);
+      }
+
+      if (traceDebug())
+      {
+         CLOG << " DEBUG:\n"
+              << "Geotiff ProjectedCSTypeGeoKey:  " << projSysCode
+              << std::endl;
+      }
+
+      std::ostringstream os;
+      os << "UTM Zone " << dec << mapZone << hemisphere.c_str()
+         << " with " << datumName << " datum";
+
+      GTIFKeySet(gtif,
+                 PCSCitationGeoKey,
+                 TYPE_ASCII,
+                 1,
+                 os.str().c_str());
+
+   } // End of "if (proj_name == "ossimUtmProjection")"
+   else if(proj_name == "ossimBngProjection")
+   {
+      // User-Defined
+      GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
+		 PCS_BRITISH_NATIONAL_GRID);//KvUserDefined );
+
+      // User-Defined
+      GTIFKeySet(gtif, ProjectionGeoKey, TYPE_SHORT, 1,
+		 KvUserDefined );
+
+      GTIFKeySet(gtif,
+                 PCSCitationGeoKey,
+                 TYPE_ASCII,
+                 26,
+                 "PCS_British_National_Grid");
+
+      GTIFKeySet(gtif,
+                 ProjCoordTransGeoKey,
+                 TYPE_SHORT,
+                 1,
+                 (uint16)CT_TransverseMercator);
+
+      double clon = ossimString(central_meridian).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjNatOriginLongGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 clon);
+
+      double olat = ossimString(origin).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjNatOriginLatGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 olat);
+
+      double fe = ossimString(false_easting).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjFalseEastingGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 fe);
+
+      double fn = ossimString(false_northing).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjFalseNorthingGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 fn);
+
+      double scale = ossimString(scaleFactor).toDouble();
+
+      GTIFKeySet(gtif,
+                 ProjScaleAtNatOriginGeoKey,
+                 TYPE_DOUBLE,
+                 1,
+                 scale);
+   }
+   else if( (proj_name == "ossimEquDistCylProjection")||
+       (proj_name == "ossimLlxyProjection"))
+   {
+      double clon = ossimString(central_meridian).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjNatOriginLongGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 clon);
+
+      double olat = ossimString(origin).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjNatOriginLatGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 olat);
+      if(proj_name == "ossimLlxyProjection")
+      {
+         double fe = ossimString(false_easting).toDouble();
+
+         GTIFKeySet(gtif,
+                    ProjFalseEastingGeoKey,
+                    TYPE_DOUBLE,
+                    1,
+                    fe);  // False Easting
+
+         double fn = ossimString(false_northing).toDouble();
+
+         GTIFKeySet(gtif,
+                    ProjFalseNorthingGeoKey,
+                    TYPE_DOUBLE,
+                    1,
+                    fn);  // False Northing
+      }
+   }
+   else if ( (proj_name == "ossimLambertConformalConicProjection") ||
+        (proj_name == "ossimAlbersProjection") )
+   {
+      //***
+      // Lambert Conformal Conic:
+      // tags needed example from the geo tiff spec page:
+      // ModelTiepointTag     = (  80,  100, 0,  200000,  1500000, 0)
+      // ModelPixelScaleTag         = (1000, 1000, 0)
+          // GeoKeyDirectoryTag:
+          //       GTModelTypeGeoKey           =  1     (ModelTypeProjected)
+          //       GTRasterTypeGeoKey          =  1     (RasterPixelIsArea)
+          //       GeographicTypeGeoKey        =  4267  (GCS_NAD27)
+          //       ProjectedCSTypeGeoKey       =  32767 (user-defined)
+          //       ProjectionGeoKey            =  32767 (user-defined)
+          //       ProjLinearUnitsGeoKey       =  9001     (Linear_Meter)
+          //       ProjCoordTransGeoKey        =  8 (CT_LambertConfConic_2SP)
+          //            ProjStdParallel1GeoKey     =  41.333
+          //            ProjStdParallel2GeoKey     =  48.666
+          //            ProjCenterLongGeoKey       =-120.0
+          //            ProjNatOriginLatGeoKey     =  45.0
+          //            ProjFalseEastingGeoKey,    = 200000.0
+          //            ProjFalseNorthingGeoKey,   = 1500000.0
+          //
+          // NOTE: Albers Same as Lambert with the exception of the
+          //       ProjCoordTransGeoKey which is:  CT_AlbersEqualArea.
+          //***
+
+          //***
+          // The easting/northing is the distance from the origin plus the
+          // false easting/northing.  In other words if line 0 is 5,000
+          // meters from the origin and the false northing is 5,000 meters,
+          // then the northing would be 10,000.  The same goes for the easting.
+          //***
+      if (proj_name == "ossimLambertConformalConicProjection")
+      {
+             GTIFKeySet(gtif,
+                        ProjCoordTransGeoKey,
+                        TYPE_SHORT,
+                        1,
+                        (uint16)CT_LambertConfConic_2SP );
+          }
+          else // Albers
+          {
+             GTIFKeySet(gtif,
+                        ProjCoordTransGeoKey,
+                        TYPE_SHORT,
+                        1,
+                        (uint16)CT_AlbersEqualArea);
+          }
+
+      // Only set a pcs code if one is explicitly given in the map projection
+      if(pcs_code)
+      {
+         ossim_uint16 value = ossimString(pcs_code).toULong();
+         if(value != 0)
+         {
+            GTIFKeySet(gtif,
+                       ProjectedCSTypeGeoKey,
+                       TYPE_SHORT,
+                       1,
+                       value);
+	 }
+      }
+      else
+      {
+         // User-Defined
+         GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
+                    KvUserDefined );
+      }
+
+      // User-Defined
+      GTIFKeySet(gtif, ProjectionGeoKey, TYPE_SHORT, 1,
+		 KvUserDefined );
+
+      double phi1 = ossimString(stdParallel1).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjStdParallel1GeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 phi1);  // 1st parallel
+
+      double phi2 = ossimString(stdParallel2).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjStdParallel2GeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 phi2);  // 2nd parallel
+
+      double centerLon = ossimString(central_meridian).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjCenterLongGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 centerLon);  // Longitude at the origin.
+
+      double org = ossimString(origin).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjNatOriginLatGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 org);  // Origin
+
+      double fe = ossimString(false_easting).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjFalseEastingGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 fe);  // False Easting
+
+      double fn = ossimString(false_northing).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjFalseNorthingGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 fn);  // False Northing
+
+   }  // End of Lambert.
+   else if (proj_name == "ossimTransMercatorProjection")
+   {
+      //***
+      // Transverse Mercator ( no example in the geo tiff spec.
+      // Requires:
+      //    - latitude/longitude of the origin
+      //    - easting/northing of some tie point(line/sample 0,0)
+      //    - false easting/northing
+      //    - The scale factor.
+      //***
+
+      //***
+      // The easting/northing is the distance from the origin plus the
+      // false easting/northing.  In other words if line 0 is 5,000
+      // meters from the origin and the false northing is 5,000 meters,
+      // then the northing would be 10,000.  The same goes for the easting.
+      //***
+      GTIFKeySet(gtif,
+                 ProjCoordTransGeoKey,
+                 TYPE_SHORT,
+                 1,
+                 (uint16)CT_TransverseMercator);
+
+      // Only set a pcs code if one is explicitly given in the map projection
+      if(pcs_code)
+      {
+         ossim_uint16 value = ossimString(pcs_code).toULong();
+         if(value != 0)
+         {
+            GTIFKeySet(gtif,
+                       ProjectedCSTypeGeoKey,
+                       TYPE_SHORT,
+                       1,
+                       value);
+	 }
+      }
+      else
+      {
+         // User-Defined
+         GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
+                    KvUserDefined );
+      }
+
+      // User-Defined
+      GTIFKeySet(gtif, ProjectionGeoKey, TYPE_SHORT, 1,
+		 KvUserDefined );
+
+      double clon = ossimString(central_meridian).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjNatOriginLongGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 clon);
+
+      double olat = ossimString(origin).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjNatOriginLatGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 olat);
+
+      double fe = ossimString(false_easting).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjFalseEastingGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 fe);
+
+      double fn = ossimString(false_northing).toDouble();
+
+      GTIFKeySet(gtif,
+		 ProjFalseNorthingGeoKey,
+		 TYPE_DOUBLE,
+		 1,
+		 fn);
+
+      double scale = ossimString(scaleFactor).toDouble();
+
+      GTIFKeySet(gtif,
+                 ProjScaleAtNatOriginGeoKey,
+                 TYPE_DOUBLE,
+                 1,
+                 scale);
+   } // End of TM
+
+
+   GTIFWriteKeys(gtif); // Write out geotiff tags.
+   GTIFFree(gtif);
+
+   return true;
+#  endif
+#endif // #ifdef OSSIM_HAS_GEOTIFF
+
+   return true;
+}
+
+bool ossimTiffWriter::writeFile()
+
+{
+   static const char MODULE[] = "ossimTiffWriter::writeFile";
+
+   if (traceDebug()) CLOG << "Entered..." << std::endl;
+
+   if(isLutEnabled())
+   {
+      theNBandToIndexFilter = new ossimNBandToIndexFilter;
+      theNBandToIndexFilter->connectMyInputTo(0, theInputConnection->getInput());
+      theNBandToIndexFilter->setLut(theColorLut);
+      theNBandToIndexFilter->initialize();
+      theInputConnection->disconnect();
+      theInputConnection->connectMyInputTo(0, theNBandToIndexFilter.get());
+      theInputConnection->initialize();
+   }
+   else
+   {
+      theNBandToIndexFilter = 0;
+   }
+   
+   if (traceDebug() && theInputConnection)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << "DEBUG:"
+         << "\nnull:  " << theInputConnection->getNullPixelValue()
+         << "\nmin:   " << theInputConnection->getMinPixelValue()
+         << "\nmax:   " << theInputConnection->getMaxPixelValue()
+         << std::endl;
+   }
+   
+   if (isTiled())
+   {
+      if ( (theInputConnection->getTileWidth()  !=
+            static_cast<ossim_uint32>(theOutputTileSize.x)) ||
+           (theInputConnection->getTileHeight() !=
+            static_cast<ossim_uint32>(theOutputTileSize.y)) )
+      {
+         theInputConnection->setTileSize(theOutputTileSize);
+      }
+   }
+   
+   if(!theInputConnection->isMaster())
+   {
+      theInputConnection->slaveProcessTiles();
+
+      if(theNBandToIndexFilter.valid())
+      {
+         theInputConnection->connectMyInputTo(0, theNBandToIndexFilter->getInput());
+         theNBandToIndexFilter = 0;
+      }
+      
+      return true;
+   }
+
+   // this might be called from writeFile(projection infoamrtion) method
+   // we will check to see if the tiff is open.  If not then call the open.
+   //
+   if(isOpen())
+   {
+      close();
+   }
+
+   open();
+
+   if (!isOpen())
+   {
+      if (traceDebug())
+      {
+         CLOG << " ERROR:  Could not open!  Returning..." << std::endl;
+      }
+
+      return false;
+   }
+
+   if(!theInputConnection)
+   {
+      if (traceDebug())
+      {
+         CLOG << " ERROR:  No input connection!  Returning..." << std::endl;
+      }
+
+      return false;
+   }
+
+   // First write the tiff tags.
+   if (writeTiffTags() == false)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " ERROR:"
+            << "\nError detected writing tiff tags.  Returning..." << std::endl;
+         return false;
+      }
+   }
+
+   // Write the geotiff tags.
+   if (theOutputGeotiffTagsFlag)
+   {
+      if(theViewController) // let this override
+      {                     // found in ossimImageWriter base
+         ossimMapProjection* proj = PTR_CAST(ossimMapProjection,
+                                             theViewController->getView());
+         if(proj)
+         {
+            ossimMapProjectionInfo* projectionInfo
+               = new ossimMapProjectionInfo(proj, theAreaOfInterest);
+
+            if (writeGeotiffTags(projectionInfo) == false)
+            {
+               if(traceDebug())
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG)
+                     << MODULE << " ERROR:"
+                     << "\nError detected writing geotiff tags.  Returning..."
+                     << std::endl;
+               }
+               delete projectionInfo;
+               return false;
+            }
+
+            delete projectionInfo;
+         }
+      }
+      else if(theProjectionInfo)
+      {
+         if (writeGeotiffTags(theProjectionInfo) == false)
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << MODULE << " ERROR:"
+                  << "\nError detected writing geotiff tags.  Returning..."
+                  << std::endl;
+            }
+            return false;
+         }
+      }
+      else
+      {
+         ossimKeywordlist kwl;
+         theInputConnection->getImageGeometry(kwl);
+         
+         ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->
+            createProjection(kwl);
+         ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj);
+         if(mapProj)
+         {
+            ossimMapProjectionInfo* projectionInfo
+               = new ossimMapProjectionInfo(mapProj, theAreaOfInterest);
+
+            if (writeGeotiffTags(projectionInfo) == false)
+            {
+               if(traceDebug())
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG)
+                     << MODULE << " ERROR:"
+                     << "\nError detected writing geotiff tags.  Returning..."
+                     << std::endl;
+               }
+               if(proj)
+               {
+                  delete proj;
+               }
+               delete projectionInfo;
+               return false;
+            }
+
+            delete projectionInfo;
+
+         }
+         if(proj)
+         {
+            delete proj;
+            proj = NULL;
+         }
+      }
+
+   } // End of "if (theOutputGeotiffTagsFlag)"
+
+   // Write the file with the image data.
+   bool status = false;
+   if(theOutputImageType == "tiff_strip")
+   {
+      status = writeToStrips();
+   }
+   else if(theOutputImageType == "tiff_strip_band_separate")
+   {
+      status = writeToStripsBandSep();
+   }
+   else if((theOutputImageType == "tiff_tiled")||
+           (ossimString::downcase(theOutputImageType) == "image/tiff")||
+           (ossimString::downcase(theOutputImageType) == "image/tif")||
+           (ossimString::downcase(theOutputImageType) == "image/gtif")||
+           (ossimString::downcase(theOutputImageType) == "image/gtiff"))
+   {
+      status = writeToTiles();
+   }
+   else if(theOutputImageType == "tiff_tiled_band_separate")
+   {
+      status = writeToTilesBandSep();
+   }
+   else
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " ERROR:"
+            << "\nUnsupported output type:  " << theOutputImageType
+            << std::endl;
+      }
+   }
+
+   close();
+
+   if (traceDebug()) CLOG << " Exited..." << std::endl;
+
+   if(theNBandToIndexFilter.valid())
+   {
+      theInputConnection->connectMyInputTo(0, theNBandToIndexFilter->getInput());
+      theNBandToIndexFilter = 0;
+   }
+   
+   return status;
+}
+
+void ossimTiffWriter::setLut(const ossimNBandLutDataObject& lut)
+{
+   theColorLut = lut;
+}
+
+bool ossimTiffWriter::saveState(ossimKeywordlist& kwl,
+                                const char* prefix)const
+{
+   ossimUnitTypeLut unitLut;
+
+   // Set the pixel type.
+   ossimString pixelType;
+   getPixelTypeString(pixelType);
+   kwl.add(prefix,
+           ossimKeywordNames::PIXEL_TYPE_KW,
+           pixelType.c_str(),
+           true);
+
+   kwl.add(prefix,
+           "output_geotiff_flag",
+           (int)theOutputGeotiffTagsFlag,
+           true);
+
+   kwl.add(ossimString(prefix)+"projection.",
+           ossimKeywordNames::UNITS_KW,
+           unitLut.getEntryString(theProjectionUnits),
+           true);
+
+   kwl.add(prefix,
+           TIFF_WRITER_OUTPUT_TILE_SIZE_X_KW,
+           theOutputTileSize.x,
+           true);
+
+   kwl.add(prefix,
+           TIFF_WRITER_OUTPUT_TILE_SIZE_Y_KW,
+           theOutputTileSize.y,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::COMPRESSION_QUALITY_KW,
+           theJpegQuality,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::COMPRESSION_TYPE_KW,
+           theCompressionType,
+           true);
+
+   kwl.add(prefix,
+           "color_lut_flag",
+           (ossim_uint32)theColorLutFlag,
+           true);
+
+   if(theColorLutFlag)
+   {
+      if(theLutFilename != "")
+      {
+         kwl.add(prefix,
+                 "lut_filename",
+                 theLutFilename.c_str(),
+                 true);
+      }
+      else
+      {
+         ossimString newPrefix = ossimString(prefix) + "lut.";
+         theColorLut.saveState(kwl, newPrefix.c_str());
+      }
+   }
+
+
+   return ossimImageFileWriter::saveState(kwl,
+                                          prefix);
+}
+
+bool ossimTiffWriter::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   const char *value;
+   ossimUnitTypeLut unitLut;
+   theProjectionUnits = (ossimUnitType)unitLut.getEntryNumber(kwl, prefix, true);
+
+   value = kwl.find(prefix, ossimKeywordNames::PIXEL_TYPE_KW);
+
+   if(value)
+   {
+      if(ossimString(value).downcase().contains("area"))
+      {
+         thePixelType = OSSIM_PIXEL_IS_AREA;
+      }
+      else
+      {
+         thePixelType = OSSIM_PIXEL_IS_POINT;
+      }
+   }
+
+   ossimIpt defaultTileSize;
+   ossimGetDefaultTileSize(defaultTileSize);
+
+   value = kwl.find(prefix,
+                    TIFF_WRITER_OUTPUT_TILE_SIZE_X_KW);
+   if(value)
+   {
+      theOutputTileSize.x = ossimString(value).toLong();
+      if(theOutputTileSize.x<1)
+      {
+         theOutputTileSize.x = defaultTileSize.x;
+      }
+   }
+
+   value = kwl.find(prefix,
+                    TIFF_WRITER_OUTPUT_TILE_SIZE_Y_KW);
+   if(value)
+   {
+      theOutputTileSize.y = ossimString(value).toLong();
+      if(theOutputTileSize.y<1)
+      {
+         theOutputTileSize.y = defaultTileSize.y;
+      }
+   }
+
+
+   value = kwl.find(prefix, ossimKeywordNames::COMPRESSION_TYPE_KW);
+   if(value)
+   {
+      theCompressionType = ossimString(value).downcase();
+   }
+   else
+   {
+      theCompressionType = "none";
+   }
+
+   value = kwl.find(prefix, ossimKeywordNames::COMPRESSION_QUALITY_KW);
+   if(value)
+   {
+      setJpegQuality(ossimString(value).toLong());
+   }
+
+   value = kwl.find(prefix, ossimKeywordNames::PHOTOMETRIC_KW);
+   if(value)
+   {
+      thePhotoMetric = ossimString(value).downcase();
+   }
+
+   value = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   if(value)
+   {
+      setFilename(ossimFilename(value));
+   }
+
+   const char* flag              = kwl.find(prefix, "output_geotiff_flag");
+   const char* img_nad27_flag    = kwl.find(prefix, "imagine_nad27_flag");
+
+   if(flag)
+   {
+      theOutputGeotiffTagsFlag = ossimString(flag).toBool();
+   }
+
+   if(img_nad27_flag)
+   {
+      theImagineNad27Flag = ossimString(img_nad27_flag).toBool();
+   }
+
+   ossimString newPrefix = ossimString(prefix) + "lut.";
+
+   const char* colorLutFlag = kwl.find(prefix, "color_lut_flag");
+   if(colorLutFlag)
+   {
+      theColorLutFlag = ossimString(colorLutFlag).toBool();
+   }
+   else
+   {
+      theColorLutFlag = false;
+   }
+   theLutFilename = ossimFilename(kwl.find(prefix, "lut_filename"));
+
+   theLutFilename = ossimFilename(theLutFilename.trim());
+   if(theLutFilename != "")
+   {
+      theColorLut.open(theLutFilename);
+   }
+   else
+   {
+      theColorLut.loadState(kwl, newPrefix.c_str());
+   }
+
+   if(ossimImageFileWriter::loadState(kwl,
+                                      prefix))
+   {
+      if((theOutputImageType!="tiff_tiled") &&
+         (theOutputImageType!="tiff_tiled_band_separate") &&
+         (theOutputImageType!="tiff_strip") &&
+         (theOutputImageType!="tiff_strip_band_separate")&&
+         (theOutputImageType!="image/tiff")&&
+         (theOutputImageType!="image/tif")&&
+         (theOutputImageType!="image/gtif")&&
+         (theOutputImageType!="image/gtiff"))
+      {
+
+         theOutputImageType = "tiff_tiled_band_separate";;
+      }
+   }
+   else
+   {
+      return false;
+   }
+
+   return true;
+}
+
+bool ossimTiffWriter::isTiled() const
+{
+   return ( theOutputImageType == "tiff_tiled" ||
+            theOutputImageType == "image/tiff" ||
+            theOutputImageType == "image/tif" ||
+            theOutputImageType == "image/gtif" ||
+            theOutputImageType == "image/gtiff" ||
+            theOutputImageType == "tiff_tiled_band_separate" );
+}
+
+bool ossimTiffWriter::writeToTiles()
+{
+   static const char* const MODULE = "ossimTiffWriter::writeToTiles";
+
+   if (traceDebug()) CLOG << " Entered." << std::endl;
+
+   // Start the sequence at the first tile.
+   theInputConnection->setToStartOfSequence();
+
+   ossimRefPtr<ossimImageData> tempTile = 0;
+
+   if(theColorLutFlag)
+   {
+      tempTile = ossimImageDataFactory::instance()->create(this, 1, theInputConnection);
+   }
+   else
+   {
+      tempTile = ossimImageDataFactory::instance()->create(this, theInputConnection);
+   }
+   if(tempTile.valid())
+   {
+      tempTile->initialize();
+   }
+   ossim_uint32 tilesWide       = theInputConnection->getNumberOfTilesHorizontal();
+   ossim_uint32 tilesHigh       = theInputConnection->getNumberOfTilesVertical();
+   ossim_uint32 tileWidth       = theInputConnection->getTileWidth();
+   ossim_uint32 tileHeight      = theInputConnection->getTileHeight();
+   ossim_uint32 numberOfTiles   = theInputConnection->getNumberOfTiles();
+
+   // Tile loop in the height direction.
+   ossim_uint32 tileNumber = 0;
+   vector<ossim_float64> minBands;
+   vector<ossim_float64> maxBands;
+   for(ossim_uint32 i = 0; i < tilesHigh; i++)
+   {
+      ossimIpt origin(0,0);
+      origin.y = i * tileHeight;
+
+      // Tile loop in the sample (width) direction.
+      for(ossim_uint32 j = 0; j < tilesWide; j++)
+      {
+         origin.x = j * tileWidth;
+
+         // Grab the tile.
+         ossimRefPtr<ossimImageData> id = theInputConnection->getNextTile();
+         if (!id)
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << MODULE << " ERROR:"
+               << "Error returned writing tiff tile:  " << tileNumber
+               << "\nNULL Tile encountered"
+               << std::endl;
+            return false;
+         }
+
+         ossimDataObjectStatus  tileStatus      = id->getDataObjectStatus();
+	 ossim_uint32           tileSizeInBytes = id->getSizeInBytes();
+         if (tileStatus != OSSIM_FULL)
+         {
+            // Clear out the buffer since it won't be filled all the way.
+            tempTile->setImageRectangle(id->getImageRectangle());
+            tempTile->makeBlank();
+         }
+
+         if ((tileStatus == OSSIM_PARTIAL || tileStatus == OSSIM_FULL))
+         {
+            // Stuff the tile into the tileBuffer.
+            id->unloadTile(tempTile->getBuf(),
+                           id->getImageRectangle(),
+                           OSSIM_BIP);
+            tempTile->setDataObjectStatus(id->getDataObjectStatus());
+            if(!theColorLutFlag)
+            {
+               id->computeMinMaxPix(minBands, maxBands);
+            }
+         }
+
+         //***
+         // Write the tile to disk.
+         //***
+         ossim_uint32 bytesWritten = 0;
+         bytesWritten = TIFFWriteTile(theTif,
+                                      tempTile->getBuf(),
+                                      origin.x,
+                                      origin.y,
+                                      0,            // z
+                                      0);           // s
+
+         if (bytesWritten != tileSizeInBytes)
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << MODULE << " ERROR:"
+                  << "Error returned writing tiff tile:  " << i
+                  << "\nExpected bytes written:  " << tileSizeInBytes
+                  << "\nBytes written:  " << bytesWritten
+                  << std::endl;
+            }
+            setErrorStatus();
+            return false;
+         }
+
+         ++tileNumber;
+
+      } // End of tile loop in the sample (width) direction.
+
+      double tile = tileNumber;
+      double numTiles = numberOfTiles;
+      setPercentComplete(tile / numTiles * 100);
+
+   } // End of tile loop in the line (height) direction.
+
+   if(!theColorLutFlag)
+   {
+      writeMinMaxTags(minBands, maxBands);
+   }
+
+   if (traceDebug()) CLOG << " Exited." << std::endl;
+
+   return true;
+}
+
+bool ossimTiffWriter::writeToTilesBandSep()
+{
+   static const char* const MODULE = "ossimTiffWriter::writeToTilesBandSep";
+
+   if (traceDebug()) CLOG << " Entered." << std::endl;
+
+   // Start the sequence at the first tile.
+   theInputConnection->setToStartOfSequence();
+
+   ossim_uint32 bands     = theInputConnection->getNumberOfOutputBands();
+   ossim_uint32 tilesWide = theInputConnection->getNumberOfTilesHorizontal();
+   ossim_uint32 tilesHigh = theInputConnection->getNumberOfTilesVertical();
+   ossim_uint32 tileWidth     = theInputConnection->getTileWidth();
+   ossim_uint32 tileHeight    = theInputConnection->getTileHeight();
+   ossim_uint32 numberOfTiles = theInputConnection->getNumberOfTiles();
+
+#if 0
+   if(traceDebug())
+   {
+      ossimIrect   boundingRect  = theInputConnection->getBoundingRect();
+      ossimNotify(ossimNotifyLevel_NOTICE)
+         << "Bounding rect = " << boundingRect
+         << "\nBands         = " << bands
+         << "\ntilesWide     = " << tilesWide
+         << "\ntilesHigh     = " << tilesHigh
+         << "\ntileWidth     = " << tileWidth
+         << "\ntileHeight    = " << tileHeight << std::endl;
+   }
+#endif
+
+   ossim_uint32 tileNumber = 0;
+   vector<ossim_float64> minBands;
+   vector<ossim_float64> maxBands;
+   for(ossim_uint32 i = 0; ((i < tilesHigh)&&!needsAborting()); ++i)
+   {
+      ossimIpt origin;
+      origin.y = i * tileHeight;
+
+      //***
+      // Tile loop in the sample (width) direction.
+      //***
+      for(ossim_uint32 j = 0; ((j < tilesWide)&!needsAborting()); ++j)
+      {
+         origin.x = j * tileWidth;
+
+         ossimRefPtr<ossimImageData> id = theInputConnection->getNextTile();
+	 if(!id)
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << MODULE << " ERROR:"
+               << "Error returned writing tiff tile:  " << i
+               << "\nNULL Tile encountered"
+               << std::endl;
+            return false;
+         }
+	 ossim_int32 tileSizeInBytes = id->getSizePerBandInBytes();
+
+         if(!theColorLutFlag)
+         {
+            id->computeMinMaxPix(minBands, maxBands);
+         }
+
+         //***
+         // Band loop.
+         //***
+         for (ossim_uint32 band=0; ((band<bands)&&(!needsAborting())); ++band)
+         {
+            // Grab a pointer to the tile for the band.
+            tdata_t* data = (tdata_t*)id->getBuf(band);
+            // Write the tile.
+            tsize_t bytesWritten = 0;
+            bytesWritten = TIFFWriteTile(theTif,
+                                         data,
+                                         (ossim_uint32)origin.x,
+                                         (ossim_uint32)origin.y,
+                                         (ossim_uint32)0,        // z
+                                         (tsample_t)band);    // sample
+
+	    if (bytesWritten != tileSizeInBytes)
+	      {
+               if(traceDebug())
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG)
+                     << MODULE << " ERROR:"
+                     << "Error returned writing tiff tile:  " << i
+                     << "\nExpected bytes written:  " << tileSizeInBytes
+                     << "\nBytes written:  " << bytesWritten
+                     << std::endl;
+               }
+		setErrorStatus();
+		return false;
+	      }
+
+         } // End of band loop.
+
+         ++tileNumber;
+
+      } // End of tile loop in the sample (width) direction.
+
+      double tile = tileNumber;
+      double numTiles = numberOfTiles;
+      setPercentComplete(tile / numTiles * 100);
+      if(needsAborting())
+      {
+         setPercentComplete(100);
+      }
+
+   } // End of tile loop in the line (height) direction.
+
+   if(!theColorLutFlag)
+   {
+      writeMinMaxTags(minBands, maxBands);
+   }
+    
+   if (traceDebug()) CLOG << " Exited." << std::endl;
+
+   return true;
+}
+
+bool ossimTiffWriter::writeToStrips()
+{
+   static const char* const MODULE = "ossimTiffWriter::writeToStrips";
+
+   if (traceDebug()) CLOG << " Entered." << std::endl;
+
+   // Start the sequence at the first tile.
+   theInputConnection->setToStartOfSequence();
+
+   ossim_uint32 bands = theInputConnection->getNumberOfOutputBands();
+   ossim_uint32 tilesWide = theInputConnection->getNumberOfTilesHorizontal();
+   ossim_uint32 tilesHigh = theInputConnection->getNumberOfTilesVertical();
+   ossim_uint32 tileHeight = theInputConnection->getTileHeight();
+   ossim_uint32 numberOfTiles = theInputConnection->getNumberOfTiles();
+   ossim_uint32 width = theAreaOfInterest.width();
+   ossim_uint32 bytesInLine =
+      ossimGetScalarSizeInBytes(theInputConnection->getOutputScalarType()) *
+      width * bands;
+
+   //***
+   // Buffer to hold one line x tileHeight
+   //***
+   ossim_uint32 bufferSizeInBytes = bytesInLine * tileHeight;
+   unsigned char* buffer = new unsigned char[bufferSizeInBytes];
+
+   int tileNumber = 0;
+   vector<ossim_float64> minBands;
+   vector<ossim_float64> maxBands;
+   for(ossim_uint32 i = 0; ((i < tilesHigh)&&(!needsAborting())); ++i)
+   {
+      // Clear the buffer.
+      memset(buffer, 0, bufferSizeInBytes);
+
+      // Set the buffer rectangle.
+      ossimIrect bufferRect(theAreaOfInterest.ul().x,
+                            theAreaOfInterest.ul().y + i * tileHeight,
+                            theAreaOfInterest.ul().x + width - 1,
+                            theAreaOfInterest.ul().y + i * tileHeight +
+                            tileHeight - 1);
+
+      // Tile loop in the sample (width) direction.
+      for(ossim_uint32 j = 0; ((j < tilesWide)&&(!needsAborting())); ++j)
+      {
+         // Get the tile and copy it to the buffer.
+         ossimRefPtr<ossimImageData> id = theInputConnection->getNextTile();
+         if (!id)
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << MODULE << " ERROR:"
+               << "Error returned writing tiff tile:  " << tileNumber
+               << "\nNULL Tile encountered"
+               << std::endl;
+            delete [] buffer;
+            return false;
+         }
+         id->unloadTile(buffer, bufferRect, OSSIM_BIP);
+         if(!theColorLutFlag)
+         {
+            id->computeMinMaxPix(minBands, maxBands);
+         }
+         ++tileNumber;
+      }
+
+      // Get the number of lines to write from the buffer.
+      ossim_uint32 linesToWrite = min(tileHeight, static_cast<ossim_uint32>(theAreaOfInterest.lr().y - bufferRect.ul().y + 1));
+
+      // Write the buffer out to disk.
+      ossim_uint32 row = static_cast<ossim_uint32>(bufferRect.ul().y -
+                                                   theAreaOfInterest.ul().y);
+      ossim_uint8* buf = buffer;
+      for (ossim_uint32 ii=0; ((ii<linesToWrite)&&(!needsAborting())); ++ii)
+      {
+        ossim_int32 status = TIFFWriteScanline(theTif,
+                                               buf,
+                                               row,
+                                               0);
+         if (status == -1)
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << MODULE << " ERROR:"
+               << "Error returned writing tiff scanline:  " << row
+               << std::endl;
+            setErrorStatus();
+            delete [] buffer;
+            return false;
+         }
+
+         ++row;  // Increment the line number.
+         buf += bytesInLine;
+
+      } // End of loop to write lines from buffer to tiff file.
+
+      double tile = tileNumber;
+      double numTiles = numberOfTiles;
+      setPercentComplete(tile / numTiles * 100);
+      if(needsAborting())
+      {
+         setPercentComplete(100);
+      }
+
+   } // End of loop in the line (height) direction.
+
+   if(!theColorLutFlag)
+   {
+      writeMinMaxTags(minBands, maxBands);
+   }
+   
+   // Free the memory.
+   delete [] buffer;
+
+   if (traceDebug()) CLOG << " Exited." << std::endl;
+
+   return true;
+}
+
+bool ossimTiffWriter::writeToStripsBandSep()
+{
+   static const char* const MODULE = "ossimTiffWriter::writeToStripsBandSep";
+
+   if (traceDebug()) CLOG << " Entered." << std::endl;
+
+   // Start the sequence at the first tile.
+   theInputConnection->setToStartOfSequence();
+
+   ossim_uint32 bands = theInputConnection->getNumberOfOutputBands();
+   ossim_uint32 tilesWide = theInputConnection->getNumberOfTilesHorizontal();
+   ossim_uint32 tilesHigh = theInputConnection->getNumberOfTilesVertical();
+   ossim_uint32 tileHeight      = theInputConnection->getTileHeight();
+   ossim_uint32 numberOfTiles   = theInputConnection->getNumberOfTiles();
+   ossim_uint32 width           = theAreaOfInterest.width();
+   ossim_uint32 bytesInLine     =
+      ossimGetScalarSizeInBytes(theInputConnection->getOutputScalarType()) *
+      width;
+
+   //***
+   // Buffer to hold one line x tileHeight
+   //***
+   ossim_uint32 bufferSizeInBytes = bytesInLine * tileHeight * bands;
+
+   unsigned char* buffer = new unsigned char[bufferSizeInBytes];
+
+   // Tile loop in height direction.
+   ossim_uint32 tileNumber = 0;
+   vector<ossim_float64> minBands;
+   vector<ossim_float64> maxBands;
+   for(ossim_uint32 i = 0; ((i < tilesHigh)&&(!needsAborting())); ++i)
+   {
+      // Clear the buffer.
+      memset(buffer, 0, bufferSizeInBytes);
+
+      // Set the buffer rectangle.
+      ossimIrect bufferRect(theAreaOfInterest.ul().x,
+                            theAreaOfInterest.ul().y + i * tileHeight,
+                            theAreaOfInterest.ul().x + width - 1,
+                            theAreaOfInterest.ul().y + i * tileHeight +
+                            tileHeight - 1);
+
+      // Tile loop in the sample (width) direction.
+      for(ossim_uint32 j = 0; ((j < tilesWide)&&(!needsAborting())); ++j)
+      {
+         // Get the tile and copy it to the buffer.
+         ossimRefPtr<ossimImageData> id = theInputConnection->getNextTile();
+         if (!id)
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << MODULE << " ERROR:"
+               << "Error returned writing tiff tile:  " << tileNumber
+               << "\nNULL Tile encountered"
+               << std::endl;
+            delete [] buffer;
+            return false;
+         }
+         id->unloadTile(buffer, bufferRect, OSSIM_BIL);
+         if(!theColorLutFlag)
+         {
+            id->computeMinMaxPix(minBands, maxBands);
+         }
+         ++tileNumber;
+      }
+
+      // Get the number of lines to write from the buffer.
+      ossim_uint32 linesToWrite = min(tileHeight, static_cast<ossim_uint32>(theAreaOfInterest.lr().y - bufferRect.ul().y + 1));
+
+      // Write the buffer out to disk.
+      ossim_uint32 row = static_cast<ossim_uint32>(bufferRect.ul().y -
+                                       theAreaOfInterest.ul().y);
+      ossim_uint8* buf = buffer;
+      for (ossim_uint32 ii=0; ((ii<linesToWrite)&&(!needsAborting())); ++ii)
+      {
+         for (ossim_uint32 band =0; ((band<bands)&&(!needsAborting())); ++band)
+         {
+           ossim_int32 status = TIFFWriteScanline(theTif,
+                                                  buf,
+                                                  row,
+                                                  band);
+            if (status == -1)
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << MODULE << " ERROR:"
+                  << "Error returned writing tiff scanline:  " << row
+                  << std::endl;
+               delete [] buffer;
+               return false;
+            }
+            buf += bytesInLine;
+         }
+
+         ++row;  // Increment the line number.
+
+      } // End of loop to write lines from buffer to tiff file.
+
+      double tile = tileNumber;
+      double numTiles = numberOfTiles;
+      setPercentComplete(tile / numTiles * 100);
+      if(needsAborting())
+      {
+         setPercentComplete(100);
+      }
+   } // End of loop in the line (height) direction.
+
+   if(!theColorLutFlag)
+   {
+      writeMinMaxTags(minBands, maxBands);
+   }
+
+   // Free the memory.
+   delete [] buffer;
+
+   if (traceDebug()) CLOG << " Exited." << std::endl;
+
+   return true;
+}
+
+void ossimTiffWriter::setTileSize(const ossimIpt& tileSize)
+{
+   if (tileSize.x % 32 || tileSize.y % 32)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimTiffWriter::changeTileSize ERROR:"
+            << "\nTile size must be a multiple of 32!"
+            << "\nSize remains:  " << theOutputTileSize
+            << std::endl;
+      }
+      return;
+   }
+
+   theOutputTileSize = tileSize;
+}
+
+void ossimTiffWriter::writeMinMaxTags(const vector<ossim_float64>& minBand,
+                                      const vector<ossim_float64>& maxBand)
+{
+   if(minBand.size() && maxBand.size())
+   {
+      ossim_float64 minValue =
+         *std::min_element(minBand.begin(), minBand.end());
+      ossim_float64 maxValue =
+         *std::max_element(maxBand.begin(), maxBand.end());
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimTiffWriter::writeMinMaxTags DEBUG:"
+            << "\nminValue:  " << minValue
+            << "\nmaxValue:  " << maxValue
+            << std::endl;
+      }
+
+      switch( theInputConnection->getOutputScalarType() )
+      {
+         case OSSIM_USHORT11:
+         {
+            TIFFSetField( theTif, TIFFTAG_MINSAMPLEVALUE,
+                          static_cast<ossim_sint16>(0) );
+            TIFFSetField( theTif, TIFFTAG_MAXSAMPLEVALUE,
+                          static_cast<ossim_sint16>(2047) );
+            break;
+         }
+         case OSSIM_UINT8:
+         case OSSIM_UINT16:
+         {
+            TIFFSetField( theTif, TIFFTAG_MINSAMPLEVALUE,
+                          static_cast<ossim_sint16>(minValue) );
+            TIFFSetField( theTif, TIFFTAG_MAXSAMPLEVALUE,
+                          static_cast<ossim_sint16>(maxValue) );
+            break;
+         }
+         
+         case OSSIM_SINT16: 
+         case OSSIM_UINT32:
+         case OSSIM_FLOAT32:
+         case OSSIM_FLOAT64:
+         case OSSIM_NORMALIZED_FLOAT:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            TIFFSetField( theTif, TIFFTAG_SMINSAMPLEVALUE,
+                          static_cast<ossim_float32>(minValue) );
+            TIFFSetField( theTif, TIFFTAG_SMAXSAMPLEVALUE,
+                          static_cast<ossim_float32>(maxValue) );
+            break;
+         }
+         default:
+         {
+            break;
+         }
+      }
+   }
+}
+
+void ossimTiffWriter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property)
+   {
+      return;
+   }
+
+   if(property->getName() == ossimKeywordNames::COMPRESSION_QUALITY_KW)
+   {
+      ossimNumericProperty* numericProperty = PTR_CAST(ossimNumericProperty,
+                                                       property.get());
+      if (numericProperty)
+      {
+         setJpegQuality( numericProperty->asInt32() );
+      }
+   }
+   else if (property->getName() == ossimKeywordNames::COMPRESSION_TYPE_KW)
+   {
+      ossimStringProperty* stringProperty = PTR_CAST(ossimStringProperty,
+                                                     property.get());
+      if (stringProperty)
+      {
+         ossimString s;
+         stringProperty->valueToString(s);
+         setCompressionType(s);
+      } 
+   }
+   else if(property->getName() == ossimKeywordNames::PIXEL_TYPE_KW)
+   {
+      ossimStringProperty* stringProperty = PTR_CAST(ossimStringProperty,
+                                                     property.get());
+      if (stringProperty)
+      {
+         ossimString s;
+         stringProperty->valueToString(s);
+         setPixelType(s);
+      }
+   }
+   else if(property->getName() == "lut_file")
+   {
+      theLutFilename = ossimFilename(property->valueToString());
+      theColorLut.open(theLutFilename);
+   }
+   else if(property->getName() == "color_lut_flag")
+   {
+      theColorLutFlag = property->valueToString().toBool();
+   }
+   else
+   {
+      ossimImageFileWriter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimTiffWriter::getProperty(const ossimString& name)const
+{
+   if(name == "Filename")
+   {
+      ossimRefPtr<ossimProperty> tempProp = ossimImageFileWriter::getProperty(name);
+      if(tempProp.valid())
+      {
+         ossimFilenameProperty* filenameProp = PTR_CAST(ossimFilenameProperty,
+                                                        tempProp.get());
+
+         if(filenameProp)
+         {
+            filenameProp->addFilter("*.tif");
+         }
+
+         return tempProp;
+      }
+   }
+   else if (name == ossimKeywordNames::COMPRESSION_QUALITY_KW)
+   {
+      ossimNumericProperty* numericProp =
+         new ossimNumericProperty(name,
+                                  ossimString::toString(theJpegQuality),
+                                  1.0,
+                                  100.0);
+      numericProp->
+         setNumericType(ossimNumericProperty::ossimNumericPropertyType_INT);
+      return numericProp;
+   }
+   else if (name == ossimKeywordNames::COMPRESSION_TYPE_KW)
+   {
+      ossimStringProperty* stringProp =
+         new ossimStringProperty(name,
+                                 getCompressionType(),
+                                 false); // editable flag
+      stringProp->addConstraint(ossimString("none"));
+      stringProp->addConstraint(ossimString("jpeg"));
+      stringProp->addConstraint(ossimString("packbits"));
+      stringProp->addConstraint(ossimString("deflate"));
+      stringProp->addConstraint(ossimString("zip"));      
+      return stringProp;
+   }
+   else if (name == ossimKeywordNames::PIXEL_TYPE_KW)
+   {
+      ossimString value;
+      getPixelTypeString(value);
+      ossimStringProperty* stringProp =
+         new ossimStringProperty(name,
+                                 value,
+                                 false); // editable flag
+      stringProp->addConstraint(ossimString("point"));
+      stringProp->addConstraint(ossimString("area"));
+      return stringProp;
+   }
+   else if (name == "lut_file")
+   {
+      ossimFilenameProperty* property = new ossimFilenameProperty(name, theLutFilename);
+      property->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+
+      return property;
+   }
+   else if (name == "color_lut_flag")
+   {
+      ossimBooleanProperty* boolProperty = new ossimBooleanProperty(name,
+                                                                    theColorLutFlag);
+      return boolProperty;
+   }
+   return ossimImageFileWriter::getProperty(name);
+}
+
+void ossimTiffWriter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   propertyNames.push_back(ossimString(
+                              ossimKeywordNames::COMPRESSION_QUALITY_KW));
+   propertyNames.push_back(ossimString(
+                              ossimKeywordNames::COMPRESSION_TYPE_KW));
+   propertyNames.push_back(ossimString(ossimKeywordNames::PIXEL_TYPE_KW));
+   propertyNames.push_back(ossimString("lut_file"));
+   propertyNames.push_back(ossimString("color_lut_flag"));
+   
+   ossimImageFileWriter::getPropertyNames(propertyNames);
+}
+
+bool ossimTiffWriter::isOpen()const
+{
+   return (theTif!=NULL);
+}
+
+bool ossimTiffWriter::open()
+{
+   if(theTif)
+   {
+      closeTiff();
+   }
+   return openTiff();
+}
+
+void ossimTiffWriter::close()
+{
+   closeTiff();
+}
+
+void ossimTiffWriter::setJpegQuality(ossim_int32 quality)
+{
+   // Range 1 to 100 with 100 being best.
+   if (quality > 0 && quality < 101)
+   {
+      theJpegQuality = quality;
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimTiffWriter::setJpegQuality DEBUG:"
+            << "\nquality out of range:  " << quality
+            << "\nquality has been set to default:  " 
+            << DEFAULT_JPEG_QUALITY
+            << "\nvalid range:  1 to 100 with 100 being best."
+            << std::endl;
+      }
+      
+      theJpegQuality = DEFAULT_JPEG_QUALITY;
+   }
+}
+
+ossim_int32 ossimTiffWriter::getJpegQuality()const
+{
+   
+   return theJpegQuality;
+}
+
+void ossimTiffWriter::setCompressionType(const ossimString& type)
+{
+   theCompressionType = type;
+}
+
+ossimString ossimTiffWriter::getCompressionType()const
+{
+   return theCompressionType;
+}
+
+bool ossimTiffWriter::getGeotiffFlag()const
+{
+   return theOutputGeotiffTagsFlag;
+}
+
+void ossimTiffWriter::setGeotiffFlag(bool flag)
+{
+   theOutputGeotiffTagsFlag = flag;
+}
+
+ossimIpt ossimTiffWriter::getOutputTileSize()const
+{
+   return theOutputTileSize;
+}
+
+ossim_int32 ossimTiffWriter::setProjectionInfo(const ossimMapProjectionInfo& proj)
+{
+   if(theProjectionInfo)
+   {
+      delete theProjectionInfo;
+   }
+   theProjectionInfo = new ossimMapProjectionInfo(proj);
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimTiffWriter::setPixelType(ossimPixelType type)
+{
+   thePixelType = type;
+}
+
+void ossimTiffWriter::setPixelType(const ossimString& type)
+{
+   ossimString s = type;
+   s.downcase();
+   if (s == "point")
+   {
+      setPixelType(OSSIM_PIXEL_IS_POINT);
+   }
+   else if (s == "area")
+   {
+      setPixelType(OSSIM_PIXEL_IS_AREA);
+   }
+}
+
+ossimPixelType ossimTiffWriter::getPixelType() const
+{
+   return thePixelType;
+}
+
+void ossimTiffWriter::getPixelTypeString(ossimString& type) const
+{
+   if (thePixelType == OSSIM_PIXEL_IS_POINT)
+   {
+      type = "point";
+   }
+   else
+   {
+      type = "area";
+   }
+}
+
+void ossimTiffWriter::getImageTypeList(std::vector<ossimString>& imageTypeList)const
+{
+   imageTypeList.push_back(ossimString("tiff_strip"));
+   imageTypeList.push_back(ossimString("tiff_strip_band_separate"));
+   imageTypeList.push_back(ossimString("tiff_tiled"));
+   imageTypeList.push_back(ossimString("tiff_tiled_band_separate"));
+}
+
+bool ossimTiffWriter::hasImageType(const ossimString& imageType) const
+{
+   // check for non image type list types
+   // We will support mime type
+   //
+   if((imageType == "image/tiff")||
+      (imageType == "image/gtiff")||
+      (imageType == "image/tif")||
+      (imageType == "image/gtif"))
+   {
+      return true;
+   }
+
+   return ossimImageFileWriter::hasImageType(imageType);
+}
+
+bool ossimTiffWriter::isLutEnabled()const
+{
+   return (theColorLutFlag);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffWriter.h b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffWriter.h
new file mode 100644
index 0000000000..9dc030a1df
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/tiff/ossimTiffWriter.h
@@ -0,0 +1,257 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Frank Warmerdam (warmerda@home.com)
+//
+// Description:
+//
+// Contains class declaration for TiffWriter.
+//
+//*******************************************************************
+//  $Id: ossimTiffWriter.h,v 1.49 2006/01/06 16:46:46 dburken Exp $
+#ifndef ossimTiffWriter_HEADER
+#define ossimTiffWriter_HEADER
+
+#include <tiffio.h>
+#include <imaging/formats/ossimImageFileWriter.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <base/common/ossimNBandLutDataObject.h>
+#include <imaging/tile_sources/ossimNBandToIndexFilter.h>
+
+class ossimMapProjectionInfo;
+
+class OSSIMDLLEXPORT ossimTiffWriter : public ossimImageFileWriter
+{
+public:
+
+   ossimTiffWriter();
+   
+   virtual ~ossimTiffWriter();
+   
+   enum UnitType
+   {
+      LINEAR_METER                 =  9001,
+      LINEAR_FOOT_US_SURVEY        =  9003,
+      ANGULAR_DEGREES              =  9102
+   };
+
+   enum
+   {
+      USER_DEFINED = 32767
+   };
+
+   /**
+    * void getImageTypeList(std::vector<ossimString>& imageTypeList)const
+    *
+    * Appends this writer image types to list "imageTypeList".
+    *
+    * This writer has the following types:
+    * tiff_strip
+    * tiff_strip_band_separate
+    * tiff_tiled
+    * tiff_tiled_band_separate
+    *
+    * @param imageTypeList stl::vector<ossimString> list to append to.
+    */   
+   virtual void getImageTypeList(std::vector<ossimString>& imageTypeList)const;
+   
+   virtual bool isOpen()const;
+   virtual bool open();
+   virtual void close();
+   
+   /**
+    * Ranges from 1 to 100 with 100 being the best.  This value is only used
+    * if the compression type is set to jpeg.  (default = 75) 
+    *
+    * @param quality Value to set theJpegQuality to.
+    *
+    * @note If quality is out of range it will be set to DEFAULT_JPEG_QUALITY.
+    */
+   virtual void setJpegQuality(ossim_int32 quality);
+
+   /**
+    * @return theJpegQuality
+    */
+   virtual ossim_int32 getJpegQuality()const;
+
+   /**
+    * compression type can be JPEG, PACKBITS, or ZIP/DEFLATE
+    */
+   virtual void setCompressionType(const ossimString& type);
+
+   virtual ossimString getCompressionType()const;
+
+   virtual bool getGeotiffFlag()const;
+
+   virtual void setGeotiffFlag(bool flag);
+
+   virtual void setTileSize(const ossimIpt& tileSize);
+
+   virtual ossimIpt getOutputTileSize()const;
+   
+   virtual ossim_int32 setProjectionInfo(const ossimMapProjectionInfo& proj);
+
+   void setLut(const ossimNBandLutDataObject& lut);
+      
+   /**
+    * saves the state of the object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * Will set the property whose name matches the argument
+    * "property->getName()".
+    *
+    * @param property Object containing property to set.
+    */
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+
+   /**
+    * @param name Name of property to return.
+    * 
+    * @returns A pointer to a property object which matches "name".  Returns
+    * NULL if no match is found.
+    */
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+
+   /**
+    * Pushes this's names onto the list of property names.
+    *
+    * @param propertyNames array to add this's property names to.
+    */
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   /**
+    * This sets the tiff geotiff key: GTRasterTypeGeoKey
+    * If "point" the coordinate tie points are relative to the center of the
+    * pixel.  If "area" the coordinate tie points are relative to the upper
+    * left corner of the pixel.
+    *
+    * Default in this writer is:  OSSIM_PIXEL_IS_POINT
+    * 
+    * @param type
+    * OSSIM_PIXEL_IS_POINT = center of pixel
+    * OSSIM_PIXEL_IS_AREA  = upper left corner of pixel
+    */
+   virtual void setPixelType(ossimPixelType type);
+
+   /**
+    * This sets the tiff geotiff key: GTRasterTypeGeoKey
+    * If "point" the coordinate tie points are relative to the center of the
+    * pixel.  If "area" the coordinate tie points are relative to the upper
+    * left corner of the pixel.
+    *
+    * Default in this writer is:  OSSIM_PIXEL_IS_POINT
+    * 
+    * @param type
+    * "point" = center of pixel
+    * "area"  = upper left corner of pixel
+    *
+    * @note If the downcased "type" is not equal to "point" or "area" pixel
+    * type will remain unchanged.
+    */
+   virtual void setPixelType(const ossimString& type);
+
+   /**
+    * @return The pixel type as either OSSIM_PIXEL_IS_POINT or
+    * OSSIM_PIXEL_IS_AREA.
+    */
+   virtual ossimPixelType getPixelType() const;
+   
+   /**
+    * @param type ossimString to initialize which will either be "point" or
+    * "area".
+    */
+   virtual void getPixelTypeString(ossimString& type) const;
+   bool hasImageType(const ossimString& imageType) const;
+   
+protected:
+   
+   virtual bool writeFile();
+
+   /**
+    *  @return true on success, false on error.
+    */
+   bool openTiff();
+
+   /**
+    *  @return true on success, false on error.
+    */
+   bool closeTiff();
+
+   /**
+    *  Writes image data to a tiled tiff format.
+    *  @return true on success, false on error.
+    */
+   bool writeToTiles();
+
+   /**
+    *  Writes image data to a tiled tiff band separate format.
+    *  @return true on success, false on error.
+    */
+   bool writeToTilesBandSep();
+   
+   /**
+    *  Writes image data to a strip tiff format.
+    *  @return true on success, false on error.
+    */
+   bool writeToStrips();
+
+   /**
+    *  Writes image data to a strip tiff band separate format.
+    *  @return true on success, false on error.
+    */
+   bool writeToStripsBandSep();
+   
+   /**
+    *  Writes tiff tags from ossimMapProjectionInfo to tiff file.
+    *  @return true on success, false on error.
+    */
+   bool writeTiffTags();
+
+   /**
+    *  Writes geotiff tags from ossimMapProjectionInfo to tiff file.
+    *  @return true on success, false on error.
+    */
+   bool writeGeotiffTags(ossimMapProjectionInfo* projectionInfo);
+
+   /**
+    *  @return true if the output type is tiled, false if not.
+    */
+   bool isTiled() const;
+
+   void writeMinMaxTags(const vector<ossim_float64>& minBand,
+                        const vector<ossim_float64>& maxBand);
+
+   bool isLutEnabled()const;
+   
+   TIFF*                   theTif;
+   ossimPixelType          thePixelType;
+   ossimUnitType           theProjectionUnits;
+   ossimString             theCompressionType;
+   ossimString             thePhotoMetric;
+   long                    theJpegQuality;
+   bool                    theOutputGeotiffTagsFlag;
+   bool                    theImagineNad27Flag;
+   bool                    theColorLutFlag;
+   ossimMapProjectionInfo* theProjectionInfo;
+   ossimIpt                theOutputTileSize;
+   ossimNBandLutDataObject theColorLut;
+   ossimFilename           theLutFilename;
+   mutable ossimRefPtr<ossimNBandToIndexFilter> theNBandToIndexFilter;
+TYPE_DATA
+};
+
+#endif /* End of "#ifndef ossimTiffWriter_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/ossimUsgsDemTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/ossimUsgsDemTileSource.cpp
new file mode 100644
index 0000000000..c8915b0e35
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/ossimUsgsDemTileSource.cpp
@@ -0,0 +1,648 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimUsgsDemTileSource.
+//
+//********************************************************************
+// $Id: ossimUsgsDemTileSource.cpp,v 1.26 2006/01/10 16:19:38 dburken Exp $
+
+#include <iostream>
+#include <fstream>
+
+#include <imaging/formats/usgs_dem/ossimUsgsDemTileSource.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimS16ImageData.h>
+#include <support_data/usgs_dem/ossimDemHeader.h>
+#include <support_data/usgs_dem/ossimDemProfile.h>
+#include <support_data/usgs_dem/ossimDemGrid.h>
+
+
+RTTI_DEF1(ossimUsgsDemTileSource, "ossimUsgsDemTileSource", ossimImageHandler)
+
+// Static trace for debugging
+static ossimTrace traceDebug("ossimUsgsDemTileSource:debug");
+
+static const char DEM_TYPE_KW[] = "dem_type";
+static const char USGS_DEM_KW[] = "usgs_dem";
+
+
+ossimUsgsDemTileSource::ossimUsgsDemTileSource()
+   :
+      ossimImageHandler(),
+      theDem(NULL),
+      theTile(NULL),
+      theNullValue(0.0),
+      theMinHeight(0.0),
+      theMaxHeight(0.0),
+      theFeetFlag(false),
+      theIsDemFlag(false),
+      theScalarType(OSSIM_SINT16)
+{
+   // Construction not complete.  Users should call "open" method.
+}
+
+ossimUsgsDemTileSource::~ossimUsgsDemTileSource()
+{
+   if (theDem)
+   {
+      delete theDem;
+      theDem = NULL;
+   }
+   theTile = NULL;
+}
+
+ossimRefPtr<ossimImageData> ossimUsgsDemTileSource::getTile(
+   const  ossimIrect& tile_rect, ossim_uint32 resLevel)
+{
+   // This tile source bypassed, or invalid res level, return a blank tile.
+   if (!isOpen() || !isSourceEnabled() || !isValidRLevel(resLevel))
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   if (theOverview)
+   {
+      if (theOverview->hasR0() || resLevel)
+      {
+         ossimRefPtr<ossimImageData> temp = theOverview->getTile(tile_rect,
+                                                                 resLevel);
+         if(temp.valid() && temp->getBuf())
+         {
+            temp->setMinPix(theTile->getMinPix(), theTile->getNumberOfBands());
+            temp->setMaxPix(theTile->getMaxPix(), theTile->getNumberOfBands());
+            temp->setNullPix(theTile->getNullPix(), theTile->getNumberOfBands());
+         }
+         else
+         {
+            return ossimRefPtr<ossimImageData>();
+         }
+         return temp;
+      }
+   }
+
+   if (!theTile.valid())
+   {
+      return theTile;
+   }
+
+   theTile->setImageRectangle(tile_rect);
+   
+   ossimIrect image_rect = getImageRectangle(resLevel);
+   
+   //***
+   // See if any point of the requested tile is in the image.
+   //***
+   if ( tile_rect.intersects(image_rect) )
+   {
+      ossimIrect clip_rect = tile_rect.clipToRect(image_rect);
+      
+      if ( !tile_rect.completely_within(clip_rect) )
+      {
+         // Start with a blank tile.
+         theTile->makeBlank();
+      }
+
+      // Load the tile buffer with data from the dem cell.
+      bool status;
+      if (theScalarType == OSSIM_FLOAT32)
+      {
+         status = fillBuffer(ossim_float32(0.0), tile_rect, clip_rect);
+      }
+      else
+      {
+         status = fillBuffer(ossim_sint16(0), tile_rect, clip_rect);
+  
+      }
+      if (status == true)
+      {
+         theTile->validate();
+         return theTile;
+      }
+      else
+      {
+         return ossimRefPtr<ossimImageData>();
+      }
+      
+   } // End of if ( tile_rect.intersects(image_rect) )
+
+   // No part of requested tile within the image rectangle.
+   return ossimRefPtr<ossimImageData>();
+   
+}
+
+//*******************************************************************
+// Private Method:
+//*******************************************************************
+template <class T>
+bool ossimUsgsDemTileSource::fillBuffer(T,
+                                        const ossimIrect& tile_rect,
+                                        const ossimIrect& clip_rect)
+{
+   const uint32 TILE_WIDTH = theTile->getWidth();
+
+   T* d = static_cast<T*>(theTile->getBuf());
+   
+   ossim_float32 spatialResZ = theDem->getHeader().getSpatialResZ();
+   if (spatialResZ == 0.0) spatialResZ = 1.0;
+
+   // Compute the starting offset.
+   uint32 offset = (clip_rect.ul().y - tile_rect.ul().y) * TILE_WIDTH +
+                   clip_rect.ul().x - tile_rect.ul().x;
+
+   for (int32 line = clip_rect.ul().y; line <= clip_rect.lr().y; ++line)
+   {
+      // Loop in the longitude or sample direction.
+      int samp_offset = 0;
+      for (int32 samp = clip_rect.ul().x; samp <= clip_rect.lr().x; ++samp)
+      {
+         ossim_float32 p = theDem->getElevation(samp, line);
+         if (p != theNullValue)
+         {
+            p *= spatialResZ;
+            if (theFeetFlag) p = p * MTRS_PER_FT;
+         }
+         d[offset + samp_offset] = static_cast<T>(p);
+         ++samp_offset;
+      }
+      offset += TILE_WIDTH;
+   }
+
+   return true;
+}
+
+ossimIrect
+ossimUsgsDemTileSource::getImageRectangle(ossim_uint32 reduced_res_level) const
+{
+   return ossimIrect(0,
+                     0,
+                     getNumberOfSamples(reduced_res_level) - 1,
+                     getNumberOfLines(reduced_res_level)   - 1);
+}
+
+bool ossimUsgsDemTileSource::open()
+{
+   static const char MODULE[] = "ossimUsgsDemTileSource::open";
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\nAttempting to parse file:  " << theImageFile.c_str()
+           << std::endl;
+   }
+   
+   if (!theImageFile.exists()) // See if file exists.
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nFile " << theImageFile.c_str() << " does not exist!"
+              << std::endl;
+      }
+      return false;
+   }
+
+   //---
+   // Open checks:
+   // 1) Check extension for .dem
+   //
+   // 2) Look for file.omd (ossim meta data) file containing keyword
+   //    "dem_type" with value of "usgs_dem".
+   //
+   // 3) Look for file.kwl (keyword list) file containing keyword
+   //    "dem_type" with value of "usgs_dem".
+   //
+   // NOTE:
+   // There is a keyword list template stored in the templates directory:
+   // "ossim/etc/templates/usgs_dem_template.kwl"
+   //---
+   ossimString ext = theImageFile.ext();
+   ext.downcase();
+   if ( (ext == "kwl") || (ext == "omd") )
+   {
+      // Don't allow keyword list to be fed to open.  Only image files.
+      return false;
+   }
+      
+   if (ext == "dem")
+   {
+      theIsDemFlag = true;
+   }
+
+   // Look for filename.omd
+   ossimFilename kwl_file = theImageFile;
+   kwl_file.setExtension("omd");
+   if (kwl_file.exists()) // See if file exists.
+   {
+      ossimKeywordlist kwl(kwl_file);
+      if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_OK)
+      {
+         const char* lookup;
+         
+         if (!theIsDemFlag)
+         {
+            const char* lookup = kwl.find(DEM_TYPE_KW);
+            if (lookup)
+            {
+               ossimString s = lookup;
+               s.downcase();
+               if (s == USGS_DEM_KW)
+               {
+                  theIsDemFlag = true;
+               }
+            }
+         }
+
+         //---
+         // Look for scalar type override.
+         //
+         // Note: We only allow float or signed 16 bit.
+         //---
+         lookup = kwl.find(ossimKeywordNames::SCALAR_TYPE_KW);
+         if (lookup)
+         {
+            ossimScalarType st =
+               static_cast<ossimScalarType>(ossimScalarTypeLut::instance()->
+                                            getEntryNumber(lookup));
+            if ( (st == OSSIM_FLOAT32) || (st == OSSIM_SINT16))
+            {
+               theScalarType = st;
+            }
+            else
+            {
+               if (traceDebug())
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << "ossimUsgsDemTileSource::loadState WARNING:"
+                     << "\nInvalid scalar type: "
+                     << ossimScalarTypeLut::instance()->
+                     getEntryString(st)
+                     << std::endl;
+               }
+            }
+         }
+      }
+   }
+
+   if (!theIsDemFlag)
+   {
+      return false;
+   }
+
+   // Open up the file for reading.
+   std::ifstream is(theImageFile.c_str(), ios::in | ios::binary);
+   if (!is)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      
+      cerr << MODULE << " ERROR!"
+           << "\nCould not open file:  " << theImageFile.c_str()
+           << "\nReturning..." << std::endl;
+      if (traceDebug())  CLOG << "returning with error..." << std::endl;
+      theIsDemFlag = false;
+      return false;
+   }
+
+   //---
+   // SPECIAL HACK (drb):
+   // Check some bytes and make sure there is no binary data.  There are
+   // files out there with .dem extension that are binary rasters.
+   //---
+   ossim_uint8* ubuf = new ossim_uint8[512];
+   is.read((char*)ubuf, 512);
+   if (is)
+   {
+      for (int i = 0; i < 512; ++i)
+      {
+         if (ubuf[i] > 0x7f)
+         {
+            theIsDemFlag = false;
+            break;
+         }
+      }
+   }
+   else
+   {
+      theIsDemFlag = false;
+   }
+   delete [] ubuf;
+   ubuf = NULL;
+   if (theIsDemFlag == false)
+   {
+      is.close();
+      return false;
+   }
+   is.seekg(0, ios::beg);
+   // End of "SPECIAL HACK".
+
+   // Start out with a fresh dem.
+   if (theDem) delete theDem;
+   
+   // Read the dem.
+   theDem = new ossimDemGrid();
+   theDem->read(is);
+
+   is.close();
+
+   theFeetFlag  = (theDem->getHeader().getElevationUnits() == 1) ?
+                  true : false;
+
+   theNullValue = theDem->getMissingDataValue();
+   theMinHeight = theFeetFlag ? theDem->getHeader().getMinimumElev() *
+                  MTRS_PER_FT : theDem->getHeader().getMinimumElev();
+   theMaxHeight = theFeetFlag ? theDem->getHeader().getMaximumElev() *
+                  MTRS_PER_FT : theDem->getHeader().getMaximumElev();
+
+   completeOpen();
+
+   //***
+   // Set up the tiles.  Note the blank tile will not get initialized to save
+   // memory.  This includes setting the min and max pixel value gathered
+   // from the statistics.
+   //***
+   theTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile->initialize();
+
+   if (traceDebug())
+   {
+      CLOG << setiosflags(ios::fixed) << setprecision(5) << "DEBUG:"
+           << "\nNull pix:  " << (theTile->getNullPix(0))
+           << "\nMin  pix:  " << (theTile->getMinPix(0))
+           << "\nMax  pix:  " << (theTile->getMaxPix(0))
+           << "\nlines:     " << theDem->getHeight()
+           << "\nsamples:   " << theDem->getWidth()
+           << std::endl;
+   }
+
+   return true;
+}
+
+bool ossimUsgsDemTileSource::saveState(ossimKeywordlist& kwl,
+                                       const char* prefix) const
+{
+   // Save of the dem type keyword.
+   kwl.add(prefix, DEM_TYPE_KW, USGS_DEM_KW, true);
+
+   // Save the scalar type.
+   kwl.add(prefix,
+           ossimKeywordNames::SCALAR_TYPE_KW,
+           ossimScalarTypeLut::instance()->getEntryString(theScalarType));
+   
+   return ossimImageHandler::saveState(kwl, prefix);
+}
+
+bool ossimUsgsDemTileSource::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   if (ossimImageHandler::loadState(kwl, prefix))
+   {
+      //***
+      // Look for "dem_type: usgs_dem" key value pair.
+      // Note:  If not in the keyword list the "open" will look for it on
+      //        disk.
+      //***
+      const char* lookup = kwl.find(prefix, DEM_TYPE_KW);
+      if (lookup)
+      {
+         ossimString s = lookup;
+         s.downcase();
+         if (s == USGS_DEM_KW) theIsDemFlag = true;
+      }
+
+      //---
+      // Look for scalar type override.
+      //
+      // Note: We only allow float or signed 16 bit.
+      //---
+      lookup = kwl.find(prefix, ossimKeywordNames::SCALAR_TYPE_KW);
+      if (lookup)
+      {
+         ossimScalarType st =
+            static_cast<ossimScalarType>(ossimScalarTypeLut::instance()->
+                                         getEntryNumber(lookup));
+         if ( (st == OSSIM_FLOAT32) || (st == OSSIM_SINT16))
+         {
+            theScalarType = st;
+         }
+         else
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "ossimUsgsDemTileSource::loadState WARNING:"
+                  << "\nInvalid scalar type: "
+                  << ossimScalarTypeLut::instance()->
+                  getEntryString(st)
+                  << std::endl;
+            }
+         }
+      }
+
+      if (ossimImageHandler::open(theImageFile))
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+bool ossimUsgsDemTileSource::getImageGeometry(ossimKeywordlist& kwl,
+                                              const char* prefix)
+{
+   if (!theDem)
+   {
+      return false;
+   }
+
+   // Previously saved...
+   if (theGeometryKwl.getSize())
+   {
+      kwl = theGeometryKwl;
+      return true;
+   }  
+      
+   const ossimDemHeader HDR = theDem->getHeader();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimUsgsDemTileSource::getImageGeometry DEBUG:"
+         << "\nDEM Header:"
+         << std::endl;
+      HDR.print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+
+   if (HDR.getImageGeometry(kwl, prefix) == false)
+   {
+      return false;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimUsgsDemTileSource::getImageGeometry DEBUG:"
+         << "keyword list:\n" << kwl
+         << std::endl;
+   }
+
+   // Capture for next time.
+   setImageGeometry(kwl);
+
+   return true;
+}
+
+ossimScalarType
+ossimUsgsDemTileSource::getOutputScalarType() const
+{
+   return theScalarType;
+}
+
+ossim_uint32 ossimUsgsDemTileSource::getTileWidth() const
+{
+   return ( theTile.valid() ? theTile->getWidth() : 0 );
+}
+
+ossim_uint32 ossimUsgsDemTileSource::getTileHeight() const
+{
+   return ( theTile.valid() ? theTile->getHeight() : 0 );
+}
+
+ossim_uint32 ossimUsgsDemTileSource::getNumberOfLines(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      if (theDem)
+      {
+         return theDem->getHeight();
+      }
+      else
+      {
+         cerr << "ossimUsgsDemTileSource::getNumberOfLines ERROR:"
+              << "\nNot initialized!" << std::endl;
+         return 0;
+      }
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfLines(reduced_res_level);
+   }
+
+   return 0;
+}
+
+ossim_uint32 ossimUsgsDemTileSource::getNumberOfSamples(ossim_uint32 reduced_res_level) const
+{
+   if (reduced_res_level == 0)
+   {
+      if (theDem)
+      {
+         return theDem->getWidth();
+      }
+      else
+      {
+         cerr << "ossimUsgsDemTileSource::getNumberOfSamples ERROR:"
+              << "\nNot initialized!" << std::endl;
+         return 0;
+      }
+   }
+   else if (theOverview)
+   {
+      return theOverview->getNumberOfSamples(reduced_res_level);
+   }
+
+   return 0;
+}
+
+ossim_uint32 ossimUsgsDemTileSource::getImageTileWidth() const
+{
+   return 0;
+}
+
+ossim_uint32 ossimUsgsDemTileSource::getImageTileHeight() const
+{
+   return 0;
+}
+
+ossimString ossimUsgsDemTileSource::getShortName() const
+{
+   return ossimString("usgs dem");
+}
+
+ossimString ossimUsgsDemTileSource::getLongName() const
+{
+   return ossimString("usgs dem reader");
+}
+
+ossimString ossimUsgsDemTileSource::className() const
+{
+   return ossimString("ossimUsgsDemTileSource");
+}
+
+ossim_uint32 ossimUsgsDemTileSource::getNumberOfInputBands() const
+{
+   return 1;
+}
+
+ossim_uint32 ossimUsgsDemTileSource::getNumberOfOutputBands()const
+{
+   return 1;
+}
+
+double ossimUsgsDemTileSource::getNullPixelValue(ossim_uint32 band)const 
+{
+   if(theMetaData.getNumberOfBands())
+   {
+      return theMetaData.getNullPix(band);
+   }
+   return theNullValue;
+}
+
+double ossimUsgsDemTileSource::getMinPixelValue(ossim_uint32 band)const 
+{ 
+   if(theMetaData.getNumberOfBands())
+   {
+      return theMetaData.getMinPix(band);
+   }
+   return theMinHeight; 
+}
+
+double ossimUsgsDemTileSource::getMaxPixelValue(ossim_uint32 band)const 
+{ 
+   if(theMetaData.getNumberOfBands())
+   {
+      return theMetaData.getMaxPix(band);
+   }
+   return theMaxHeight; 
+}
+
+bool ossimUsgsDemTileSource::isOpen()const
+{
+   return (theDem ? true : false );
+}
+
+const ossimUsgsDemTileSource& ossimUsgsDemTileSource::operator=(const  ossimUsgsDemTileSource& rhs)
+{
+   return rhs;
+} 
+
+ossimUsgsDemTileSource::ossimUsgsDemTileSource(const ossimUsgsDemTileSource&)
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/ossimUsgsDemTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/ossimUsgsDemTileSource.h
new file mode 100644
index 0000000000..cde4512f09
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/usgs_dem/ossimUsgsDemTileSource.h
@@ -0,0 +1,173 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: David Burken
+//
+// Description:
+//
+// Contains class declaration of ossimUsgsDemTileSource.
+// The ossimUsgsDemTileSource class is derived from ossimImageHandler and
+// is intended to be an image handler for USGS dem files.
+//
+//********************************************************************
+// $Id: ossimUsgsDemTileSource.h,v 1.17 2006/01/10 16:19:38 dburken Exp $
+
+#ifndef ossimUsgsDemTileSource_HEADER
+#define ossimUsgsDemTileSource_HEADER
+
+  // #include <fstream>
+#include "imaging/formats/ossimImageHandler.h"
+
+class ossimImageData;
+class ossimDemGrid;
+
+class OSSIM_DLL ossimUsgsDemTileSource : public ossimImageHandler
+{
+public:
+      
+   ossimUsgsDemTileSource();
+   
+   virtual ~ossimUsgsDemTileSource();
+
+   virtual ossimString getShortName() const;
+   virtual ossimString getLongName()  const;
+   virtual ossimString className()    const;
+
+   /**
+    *  Returns true if the "theImageFile can be opened.
+    *
+    *  If the extension is not equal to ".dem" this will attempt to look for
+    *  an ".omd" file with the keyword pair "dem_type:  usgs_dem" in it.
+    *
+    *  Optionally users can change the scalar type from signed 16 bit to
+    *  float with the keyword pair "scalar_type: ossim_float32"
+    */
+   virtual bool open();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+   
+   /**
+    *  Returns the number of bands in the image.
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfInputBands()  const;
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+   
+   /**
+    *  Returns the number of lines in the image.
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    *  Returns the number of samples in the image.  
+    *  Satisfies pure virtual requirement from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
+
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   /**
+    * Returns the zero based image rectangle for the reduced resolution data
+    * set (rrds) passed in.  Note that rrds 0 is the highest resolution rrds.
+    */
+   virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level = 0) const;
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    *
+    * Keywords picked up by this method:
+    * dem_type: usgs_dem
+    * scalar_type: ossim_sint16 (default)
+    * or
+    * scalar_type: ossim_float32
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /**
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *  Returns true if geometry info is present, false if not.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+   
+   /**
+    * Returns the output pixel type of the tile source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32 getTileWidth() const;
+
+   /**
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /**
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;   
+
+   virtual bool isOpen()const;
+   
+private:
+   // Disallow operator= and copy constrution...
+   const ossimUsgsDemTileSource& operator=(const  ossimUsgsDemTileSource& rhs);
+   ossimUsgsDemTileSource(const ossimUsgsDemTileSource&);
+   
+   /**
+    *  Returns true on success, false on error.
+    */
+   template <class T> bool fillBuffer(T, // dummy template variable
+                                      const ossimIrect& tile_rect,
+                                      const ossimIrect& clip_rect);
+
+   void gatherStatistics();
+
+   ossimDemGrid*               theDem;
+   ossimRefPtr<ossimImageData> theTile;
+   ossim_float64               theNullValue;
+   ossim_float64               theMinHeight;
+   ossim_float64               theMaxHeight;
+   bool                        theFeetFlag;  // elevation units = feet
+   bool                        theIsDemFlag;
+
+   /**
+    * This can be either OSSIM_SINT16 or OSSIM_FLOAT32.  Default = OSSIM_SINT16
+    * Can be changed via ".omd" file keyword:
+    */
+   ossimScalarType             theScalarType;
+   
+TYPE_DATA
+};
+
+#endif  // #ifndef ossimUsgsDemTileSource_HEADER
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/.cvsignore
new file mode 100644
index 0000000000..7df3918588
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+Makefile
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationCoverageInfo.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationCoverageInfo.cpp
new file mode 100644
index 0000000000..507e16c9d1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationCoverageInfo.cpp
@@ -0,0 +1,217 @@
+//*************************************************************************
+// Copyright (C) 2004 Intelligence Data Systems, Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+//**************************************************************************
+// $Id: ossimVpfAnnotationCoverageInfo.cpp,v 1.6 2004/11/22 19:35:59 dburken Exp $
+
+#include <vector>
+#include <algorithm>
+#include <imaging/formats/vpf/ossimVpfAnnotationCoverageInfo.h>
+#include <vec/vpf/ossimVpfLibrary.h>
+#include <vec/vpf/ossimVpfFeatureClassSchema.h>
+
+bool ossimVpfAnnotationCoverageInfo::hasRenderableFeature()const
+{
+  for(ossim_uint32 idx = 0; idx < theFeatureInfoArray.size();++idx)
+  {
+     if(theFeatureInfoArray[idx]->getEnabledFlag())
+     {
+        return true;
+     }
+  }
+
+  return false;
+}
+
+void ossimVpfAnnotationCoverageInfo::getEnabledFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& result)
+{
+  for(ossim_uint32 idx = 0; idx < theFeatureInfoArray.size();++idx)
+    {
+      if(theFeatureInfoArray[idx]->getEnabledFlag())
+	{
+	  result.push_back(theFeatureInfoArray[idx]);
+	}
+    }
+}
+
+void ossimVpfAnnotationCoverageInfo::getAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& result)
+{
+  for(ossim_uint32 idx = 0; idx < theFeatureInfoArray.size();++idx)
+  {
+     result.push_back(theFeatureInfoArray[idx]);
+  }
+}
+
+ossimIrect ossimVpfAnnotationCoverageInfo::getBoundingProjectedRect()const
+{
+  ossimIrect result;
+  result.makeNan();
+
+  for(ossim_uint32 idx = 0; idx < theFeatureInfoArray.size();++idx)
+    {
+      ossimIrect tempRect = theFeatureInfoArray[idx]->getBoundingProjectedRect();
+      if(!tempRect.hasNans())
+	{
+	  if(result.hasNans())
+	    {
+	      result = tempRect;
+	    }
+	  else
+	    {
+	      result = result.combine(tempRect);
+	    }
+	}
+    }
+
+  return result;
+}
+
+
+void ossimVpfAnnotationCoverageInfo::transform(ossimProjection* proj)
+{
+  for(ossim_uint32 idx = 0; idx < theFeatureInfoArray.size();++idx)
+  {
+     theFeatureInfoArray[idx]->transform(proj);
+  }
+}
+
+void ossimVpfAnnotationCoverageInfo::buildCoverage()
+{
+   buildCoverage( "" );
+}
+
+void ossimVpfAnnotationCoverageInfo::buildCoverage(const ossimString& feature)
+{
+   deleteAllFeatures();
+   if(theLibrary)
+   {
+      ossimVpfCoverage coverage;
+      
+      if(theLibrary->getCoverage(theName, coverage))
+      {
+         ossimVpfFeatureClassSchema schema;
+         if(coverage.openFeatureClassSchema(schema))
+         {
+            std::vector<ossimString> featureClassArray;
+            schema.getFeatureClasses(featureClassArray);
+            schema.closeTable();
+            for(ossim_uint32  idx = 0; idx < featureClassArray.size(); ++idx)
+            {
+               ossimString s1 = feature;
+               ossimString s2 = featureClassArray[idx];
+               s1.downcase();
+               s2.downcase();
+               if (! feature.length() || (s1 == s2) )
+               {
+                  ossimVpfAnnotationFeatureInfo* featureInfo =
+                     new ossimVpfAnnotationFeatureInfo;
+                  featureInfo->setName(featureClassArray[idx]);
+                  featureInfo->setCoverage(coverage);
+                  theFeatureInfoArray.push_back(featureInfo);
+                  featureInfo->buildFeature();
+               }
+            }
+         }
+      }
+   }
+}
+
+void ossimVpfAnnotationCoverageInfo::drawAnnotations(ossimRgbImage* tile)
+{
+   for(ossim_uint32 idx = 0; idx < theFeatureInfoArray.size();++idx)
+   {
+      if(theFeatureInfoArray[idx]->getEnabledFlag())
+      {
+         theFeatureInfoArray[idx]->drawAnnotations(tile);
+      }
+   }
+}
+
+void ossimVpfAnnotationCoverageInfo::deleteAllFeatures()
+{
+   for(ossim_uint32 idx = 0; idx < theFeatureInfoArray.size();++idx)
+   {
+      theFeatureInfoArray[idx];
+   }
+   
+   theFeatureInfoArray.clear();
+}
+
+
+
+bool ossimVpfAnnotationCoverageInfo::saveState(ossimKeywordlist& kwl,
+					       const char* prefix)const
+{
+   kwl.add(prefix,
+           "name",
+           theName,
+           true);
+   
+   for(ossim_uint32 idx = 0; idx < theFeatureInfoArray.size(); ++idx)
+   {
+      theFeatureInfoArray[idx]->saveState(kwl,
+					  (ossimString(prefix) + "feature" +
+					   ossimString::toString(idx) + ".").c_str());
+   }
+   
+   return true;
+}
+
+bool ossimVpfAnnotationCoverageInfo::loadState(const ossimKeywordlist& kwl,
+					       const char* prefix)
+{
+  deleteAllFeatures();
+
+  if(!theLibrary)
+    {
+      return false;
+    }
+
+  theName = kwl.find(prefix, "name");
+  ossimVpfCoverage coverage;
+
+  if(theLibrary->getCoverage(theName, coverage))
+    {
+      ossimString regExpression =  ossimString("^(") + ossimString(prefix) + "feature[0-9]+.)";
+      vector<ossimString> keys =
+	kwl.getSubstringKeyList( regExpression );
+      std::vector<int> theNumberList(keys.size());
+      int offset = (ossimString(prefix)+"feature").size();
+      int idx = 0;
+      for(idx = 0; idx < (int)theNumberList.size();++idx)
+	{
+	  ossimString numberStr(keys[idx].begin() + offset,
+				keys[idx].end());
+	  theNumberList[idx] = numberStr.toInt();
+	}
+      std::sort(theNumberList.begin(), theNumberList.end());
+      
+      for(idx=0;idx < (int)keys.size();++idx)
+	{
+	  ossimString newPrefix = ossimString(prefix);
+	  newPrefix += ossimString("feature");
+	  newPrefix += ossimString::toString(theNumberList[idx]);
+	  newPrefix += ossimString(".");
+	  ossimVpfAnnotationFeatureInfo* featureInfo = new ossimVpfAnnotationFeatureInfo;
+	  featureInfo->setCoverage(coverage);
+	  theFeatureInfoArray.push_back(featureInfo);
+	  if(!featureInfo->loadState(kwl,
+				     newPrefix))
+	    {
+	      return false;
+	    }
+	}
+    }
+  else
+    {
+      return false;
+    }
+
+  return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationCoverageInfo.h b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationCoverageInfo.h
new file mode 100644
index 0000000000..60256d296d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationCoverageInfo.h
@@ -0,0 +1,77 @@
+//*************************************************************************
+// Copyright (C) 2004 Intelligence Data Systems, Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+//**************************************************************************
+// $Id: ossimVpfAnnotationCoverageInfo.h,v 1.8 2004/12/21 20:12:40 gpotts Exp $
+#ifndef ossimVpfAnnotationCoverageInfo_HEADER
+#define ossimVpfAnnotationCoverageInfo_HEADER
+#include <imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.h>
+#include <vec/vpf/ossimVpfCoverage.h>
+class ossimVpfLibrary;
+
+class ossimRgbImage;
+
+class ossimVpfAnnotationCoverageInfo
+{
+public:
+  ossimVpfAnnotationCoverageInfo(const ossimString& name="")
+    :theName(name)
+  {
+    
+  }
+  virtual ~ossimVpfAnnotationCoverageInfo()
+  {
+    deleteAllFeatures();
+  }
+  bool hasRenderableFeature()const;
+  void getEnabledFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& result);
+  void getAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& result);
+
+  void transform(ossimProjection* proj);
+  ossimIrect getBoundingProjectedRect()const;
+  void buildCoverage();
+  void buildCoverage(const ossimString& feature);
+  void setName(const ossimString& name)
+  {
+    theName = name;
+  }
+  ossimString getName()const
+     {
+        return theName;
+     }
+  void setLibrary(ossimVpfLibrary* library)
+  {
+    theLibrary = library;
+  }
+  ossimVpfLibrary* getLibrary()
+  {
+    return theLibrary;
+  }
+  const ossimVpfLibrary* getLibrary()const
+  {
+    return theLibrary;
+  }
+  void drawAnnotations(ossimRgbImage* tile);
+   void deleteAllFeatures();
+
+  virtual bool saveState(ossimKeywordlist& kwl,
+			 const char* prefix=0)const;
+  virtual bool loadState(const ossimKeywordlist& kwl,
+			 const char* prefix=0);
+protected:
+  ossimString theName;
+
+  /*!
+   * Not owned.
+   */
+  ossimVpfLibrary* theLibrary;
+  std::vector<ossimVpfAnnotationFeatureInfo*>           theFeatureInfoArray;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.cpp
new file mode 100644
index 0000000000..7e0ce4dd8f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.cpp
@@ -0,0 +1,1451 @@
+#include <sstream>
+
+#include "ossimVpfAnnotationFeatureInfo.h"
+#include "vec/vpf/ossimVpfCoverage.h"
+#include "vec/vpf/ossimVpfLibrary.h"
+#include "vec/vpf/ossimVpfFeatureClassSchema.h"
+#include "projections/ossimProjection.h"
+#include "base/data_types/ossimPolyLine.h"
+#include "base/data_types/ossimGeoPolygon.h"
+#include "imaging/annotation/ossimGeoAnnotationSource.h"
+#include "imaging/annotation/ossimAnnotationObject.h"
+#include "imaging/annotation/ossimGeoAnnotationMultiPolyLineObject.h"
+#include "imaging/annotation/ossimGeoAnnotationMultiEllipseObject.h"
+#include "imaging/annotation/ossimGeoAnnotationFontObject.h"
+#include "imaging/annotation/ossimGeoAnnotationMultiPolyObject.h"
+#include "imaging/ossimRgbImage.h"
+#include "fonts/ossimFont.h"
+#include "fonts/factory/ossimFontFactoryRegistry.h"
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug("ossimVpfAnnotationFeatureInfo:debug");
+
+RTTI_DEF1(ossimVpfAnnotationFeatureInfo, "ossimVpfAnnotationFeatureInfo", ossimObject);
+
+ossimVpfAnnotationFeatureInfo::ossimVpfAnnotationFeatureInfo(const ossimString& featureName,
+                                                             const ossimRgbVector& penColor,
+                                                             const ossimRgbVector& brushColor,
+                                                             const ossimDpt& pointRadius,
+                                                             int   thickness,
+                                                             bool enabledFlag)
+   :theName(featureName),
+    thePenColor(penColor),
+    theBrushColor(brushColor),
+    thePointRadius(pointRadius),
+    theThickness(thickness),
+    theFillEnabledFlag(false),
+    theEnabledFlag(enabledFlag),
+    theFeatureType(ossimVpfAnnotationFeatureType_UNKNOWN)
+{
+   ossimFont* font = ossimFontFactoryRegistry::instance()->getDefaultFont();
+
+   if(font)
+   {
+      std::vector<ossimFontInformation> fontInfoArray;
+
+      font->getFontInformation(fontInfoArray);
+
+      if(fontInfoArray.size())
+      {
+         theFontInformation = fontInfoArray[0];
+      }
+   }
+}
+
+
+ossimVpfAnnotationFeatureInfo::~ossimVpfAnnotationFeatureInfo()
+{
+   deleteAllObjects();
+}
+
+void ossimVpfAnnotationFeatureInfo::transform(ossimProjection* proj)
+{
+   if(theEnabledFlag)
+   {
+      for(int idx = 0; idx < (int)theAnnotationArray.size();++idx)
+      {
+         if(theAnnotationArray[idx])
+         {
+            theAnnotationArray[idx]->transform(proj);
+            theAnnotationArray[idx]->computeBoundingRect();
+         }
+      }
+   }
+}
+ossimIrect ossimVpfAnnotationFeatureInfo::getBoundingProjectedRect()const
+{
+  ossimIrect result;
+  result.makeNan();
+
+  if(theEnabledFlag)
+  {
+     for(int idx = 0; idx < (int)theAnnotationArray.size();++idx)
+     {
+        if(theAnnotationArray[idx])
+	{
+           ossimIrect tempRect = theAnnotationArray[idx]->getBoundingRect();
+           if(!tempRect.hasNans())
+           {
+	      if(result.hasNans())
+              {
+                 result = tempRect;
+              }
+	      else
+              {
+                 result = result.combine(tempRect);
+              }
+           }
+	}
+     }
+  }
+  
+  return result;
+}
+
+void ossimVpfAnnotationFeatureInfo::setEnabledFlag(bool flag)
+{
+   if(!flag && theEnabledFlag)
+   {
+      deleteAllObjects();
+   }
+   else if(flag&&(!theEnabledFlag))
+   {
+      theEnabledFlag = flag;
+      buildFeature();
+   }
+   theEnabledFlag = flag;
+}
+
+void ossimVpfAnnotationFeatureInfo::buildFeature()
+{
+  deleteAllObjects();
+  
+  ossimVpfFeatureClassSchemaNode node;
+
+  ossimVpfFeatureClassSchema schema;
+  theCoverage.openFeatureClassSchema(schema);
+  if(schema.getFeatureClassNode(theName,
+				node))
+    {
+      if(node.thePrimitiveTable.contains("edg"))
+      {
+         theFeatureType = ossimVpfAnnotationFeatureType_LINE;
+	 if(theEnabledFlag)
+	   {
+	     buildEdgFeature(node.theTable.trim(),
+			     node.theTableKey.trim(),
+			     node.thePrimitiveTable.trim(),
+			     node.thePrimitiveTableKey.trim());
+	   }
+	}
+      else if(node.thePrimitiveTable.contains("txt"))
+	{
+            theFeatureType = ossimVpfAnnotationFeatureType_TEXT;
+	    if(theEnabledFlag)
+	      {
+		buildTxtFeature(node.theTable.trim(),
+				node.theTableKey.trim(),
+				node.thePrimitiveTable.trim(),
+				node.thePrimitiveTableKey.trim());
+	      }
+	}
+      else if(node.thePrimitiveTable.contains("fac"))
+	{
+            theFeatureType = ossimVpfAnnotationFeatureType_POLYGON;
+	    if(theEnabledFlag)
+	      {
+		buildFaceFeature(node.theTable.trim(),
+				 node.theTableKey.trim(),
+				 node.thePrimitiveTable.trim(),
+				 node.thePrimitiveTableKey.trim());
+	      }
+	}
+      else if(node.thePrimitiveTable.contains("cnd"))
+	{
+            theFeatureType = ossimVpfAnnotationFeatureType_POINT;
+	    if(theEnabledFlag)
+	      {
+		buildPointFeature("cnd",
+				  node.theTable.trim(),
+				  node.theTableKey.trim(),
+				  node.thePrimitiveTable.trim(),
+				  node.thePrimitiveTableKey.trim());
+	      }
+	}
+      else if(node.thePrimitiveTable.contains("end"))
+	{
+            theFeatureType = ossimVpfAnnotationFeatureType_POINT;
+	    if(theEnabledFlag)
+	      {
+		buildPointFeature("end",
+				  node.theTable.trim(),
+				  node.theTableKey.trim(),
+				  node.thePrimitiveTable.trim(),
+				  node.thePrimitiveTableKey.trim());
+	      }
+	}
+      else
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "Primitive \""<<node.thePrimitiveTable<<"\" not handled yet" << endl;
+         }
+      }
+    }
+}
+
+void ossimVpfAnnotationFeatureInfo::drawAnnotations(ossimRgbImage* tile)
+{
+   if(theEnabledFlag)
+   {
+      int idx = 0;
+      for(idx = 0; idx < (int)theAnnotationArray.size(); ++idx)
+      {
+         theAnnotationArray[idx]->draw(*tile);
+      }
+   }
+}
+
+bool ossimVpfAnnotationFeatureInfo::saveState(ossimKeywordlist& kwl,
+					      const char* prefix)const
+{
+  kwl.add(prefix,
+	  "name",
+	  theName.c_str(),
+	  true);
+  kwl.add(prefix,
+	  "description",
+	  theDescription.c_str(),
+	  true);
+  ossimString penColor = (ossimString::toString((int)thePenColor.getR())+ " " +
+			  ossimString::toString((int)thePenColor.getG())+ " " +
+			  ossimString::toString((int)thePenColor.getB()));
+  ossimString brushColor = (ossimString::toString((int)theBrushColor.getR())+ " " +
+			    ossimString::toString((int)theBrushColor.getG())+ " " +
+			    ossimString::toString((int)theBrushColor.getB()));
+  kwl.add(prefix,
+	  "pen_color",
+	  penColor,
+	  true);
+  kwl.add(prefix,
+	  "brush_color",
+	  brushColor,
+	  true);
+
+  if(theFeatureType == ossimVpfAnnotationFeatureType_POINT)
+    {
+      kwl.add(prefix,
+	      "point_radius",
+	      ossimString::toString(thePointRadius.x) + " " +
+	      ossimString::toString(thePointRadius.y),
+	      true);
+      kwl.add(prefix,
+	      "fill_enabled",
+	      theFillEnabledFlag,
+	      true);
+    }
+  else if(theFeatureType == ossimVpfAnnotationFeatureType_LINE)
+    {
+      kwl.add(prefix,
+	      "thickness",
+	      theThickness,
+	      true);
+    }
+  else if(theFeatureType == ossimVpfAnnotationFeatureType_POLYGON)
+    {
+      kwl.add(prefix,
+	      "fill_enabled",
+	      theFillEnabledFlag,
+	      true);
+      kwl.add(prefix,
+	      "thickness",
+	      theThickness,
+	      true);
+    }
+  else if(theFeatureType == ossimVpfAnnotationFeatureType_TEXT)
+    {
+      theFontInformation.saveState(kwl,
+				   (ossimString(prefix)+"font.").c_str());
+    }
+  kwl.add(prefix,
+	  "enabled",
+	  theEnabledFlag,
+	  true);
+  kwl.add(prefix,
+	  "feature_type",
+	  getFeatureTypeAsString(),
+	  true);
+
+  return true;
+}
+
+bool ossimVpfAnnotationFeatureInfo::loadState(const ossimKeywordlist& kwl,
+					      const char* prefix)
+{
+  const char* name        = kwl.find(prefix, "name");
+  const char* description = kwl.find(prefix, "description");
+  const char* enabled     = kwl.find(prefix, "enabled");
+  const char* fillEnabled = kwl.find(prefix, "fill_enabled");
+  const char* thickness   = kwl.find(prefix, "thickness");
+  const char* pointRadius = kwl.find(prefix, "point_radius");
+  const char* brushColor  = kwl.find(prefix, "brush_color");
+  const char* penColor    = kwl.find(prefix, "pen_color");
+  
+  theFontInformation.loadState(kwl,
+			       (ossimString(prefix)+"font.").c_str());
+
+  if(name)
+    {
+      if(theName != name)
+	{
+	  deleteAllObjects();
+	}
+      theName = name;
+    }
+  if(description)
+    {
+      theDescription = description;
+    }
+  if(enabled)
+    {
+      theEnabledFlag = ossimString(enabled).toBool();
+
+      if(!theEnabledFlag)
+	{
+	  deleteAllObjects();
+	}
+    }
+  
+  if(fillEnabled)
+    {
+      theFillEnabledFlag = ossimString(fillEnabled).toBool();
+    }
+  if(thickness)
+    {
+      theThickness = ossimString(thickness).toInt();
+    }
+  if(pointRadius)
+    {
+      stringstream ptRadiusStream(pointRadius);
+      ptRadiusStream >> thePointRadius.x >> thePointRadius.y;
+    }
+  if(brushColor)
+    {
+      int r, g, b;
+      stringstream colorStream(brushColor);
+      colorStream >> r >> g >> b;
+
+      theBrushColor.setR((ossim_uint8)r);
+      theBrushColor.setG((ossim_uint8)g);
+      theBrushColor.setB((ossim_uint8)b);
+    }
+  if(penColor)
+    {
+      int r, g, b;
+      stringstream colorStream(brushColor);
+      colorStream >> r >> g >> b;
+
+      thePenColor.setR((ossim_uint8)r);
+      thePenColor.setG((ossim_uint8)g);
+      thePenColor.setB((ossim_uint8)b);
+    }
+  
+  if(theEnabledFlag&&(theAnnotationArray.size() < 1))
+    {
+      buildFeature();
+    }
+  else
+    {
+      setDrawingFeaturesToAnnotation();
+    }
+
+  return true;
+}
+
+ossimString ossimVpfAnnotationFeatureInfo::getFeatureTypeAsString()const
+{
+   switch(theFeatureType)
+   {
+      case ossimVpfAnnotationFeatureType_POINT:
+      {
+         return "point";
+      }
+      case ossimVpfAnnotationFeatureType_LINE:
+      {
+         return "line";
+      }
+      case ossimVpfAnnotationFeatureType_POLYGON:
+      {
+         return "polygon";
+      }
+      case ossimVpfAnnotationFeatureType_TEXT:
+      {
+         return "text";
+      }
+      default:
+         break;
+   }
+   
+  return "unknown";
+}
+
+ossimVpfAnnotationFeatureInfo::ossimVpfAnnotationFeatureType ossimVpfAnnotationFeatureInfo::getFeatureTypeFromString(const ossimString& featureType)const
+{
+  ossimString downCased = featureType;
+  downCased = downCased.downcase();
+
+  if(downCased.contains("point"))
+    {
+      return ossimVpfAnnotationFeatureType_POINT;
+    }
+  else if(downCased.contains("line"))
+    {
+      return ossimVpfAnnotationFeatureType_LINE;
+    }
+  else if(downCased.contains("polygon"))
+    {
+      return ossimVpfAnnotationFeatureType_POLYGON;
+    }
+  else if(downCased.contains("text"))
+    {
+      return ossimVpfAnnotationFeatureType_TEXT;
+    }
+
+  return ossimVpfAnnotationFeatureType_UNKNOWN;
+
+}
+
+void ossimVpfAnnotationFeatureInfo::deleteAllObjects()
+{
+  for(int idx = 0; idx < (int)theAnnotationArray.size();++idx)
+    {
+      delete theAnnotationArray[idx];
+    }
+
+  theAnnotationArray.clear();
+}
+
+void ossimVpfAnnotationFeatureInfo::setDrawingFeaturesToAnnotation()
+{
+   switch(theFeatureType)
+   {
+   case ossimVpfAnnotationFeatureType_POINT:
+   {
+      ossimGeoAnnotationMultiEllipseObject* annotation = NULL;
+      for(int idx = 0; idx < (int)theAnnotationArray.size();++idx)
+      {
+         annotation = (ossimGeoAnnotationMultiEllipseObject*)theAnnotationArray[idx];
+
+         annotation->setColor(thePenColor.getR(),
+                              thePenColor.getG(),
+                              thePenColor.getB());
+         annotation->setThickness(theThickness);
+         annotation->setFillFlag(theFillEnabledFlag);
+         annotation->setWidthHeight(thePointRadius);
+      }
+      
+      break;
+   }
+   case ossimVpfAnnotationFeatureType_TEXT:
+   {
+      ossimGeoAnnotationFontObject* annotation = NULL;
+      ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(theFontInformation);
+
+      for(int idx = 0; idx < (int)theAnnotationArray.size();++idx)
+      {
+         annotation = (ossimGeoAnnotationFontObject*)theAnnotationArray[idx];
+         annotation->setColor(thePenColor.getR(),
+                              thePenColor.getG(),
+                              thePenColor.getB());
+         annotation->setThickness(theThickness);
+         
+         if(font)
+         {
+            annotation->setFont((ossimFont*)font->dup());
+         }
+         annotation->setPointSize(theFontInformation.thePointSize);
+         annotation->setScale(theFontInformation.theScale);
+         annotation->setShear(theFontInformation.theShear);
+         annotation->setRotation(theFontInformation.theRotation);
+      }
+      if(font)
+      {
+         delete font;
+         font = NULL;
+      }
+      break;
+   }
+   case ossimVpfAnnotationFeatureType_LINE:
+   {
+      ossimGeoAnnotationMultiPolyLineObject* annotation = NULL;
+      for(int idx = 0; idx < (int)theAnnotationArray.size();++idx)
+      {
+         annotation = (ossimGeoAnnotationMultiPolyLineObject*)theAnnotationArray[idx];
+         annotation->setColor(thePenColor.getR(),
+                              thePenColor.getG(),
+                              thePenColor.getB());
+         annotation->setThickness(theThickness);
+      }
+      
+      break;
+   }
+   case ossimVpfAnnotationFeatureType_POLYGON:
+   {
+      ossimGeoAnnotationMultiPolyObject* annotation = NULL;
+      for(int idx = 0; idx < (int)theAnnotationArray.size();++idx)
+      {
+         annotation = (ossimGeoAnnotationMultiPolyObject*)theAnnotationArray[idx];
+         annotation->setColor(thePenColor.getR(),
+                              thePenColor.getG(),
+                              thePenColor.getB());
+         annotation->setThickness(theThickness);
+         annotation->setFillFlag(theFillEnabledFlag);
+      }
+      break;
+   }
+   default:
+   {
+      break;
+   }
+   }
+}
+
+
+void ossimVpfAnnotationFeatureInfo::buildTxtFeature(const ossimFilename& tableName,
+						    const ossimString&   tableKey,
+						    const ossimFilename& primitiveName,
+						    const ossimString&   primitiveKey)
+{
+  ossimFilename tableFileName      = theCoverage.getPath().dirCat(tableName);
+  ossimFilename primitiveTableName;
+  ossimVpfTable table;
+  ossimVpfTable primitiveTable;
+
+  if(table.openTable(tableFileName))
+    {
+      table.reset();
+      vector<ossimString> columnValues = table.getColumnValues(tableKey.trim());
+      
+      primitiveTableName = theCoverage.getPath().dirCat("txt");
+      
+      vector<ossimString> tileIds;
+      ossim_int32 stringValuePosition = 0;
+      ossim_int32 shapeLinePosition = 0;
+      bool isTiled = false;
+      if(table.getColumnPosition("tile_id") >= 0)
+	{
+	  tileIds = table.getColumnValues("tile_id");
+	  isTiled = true;
+	}
+      if(!isTiled)
+	{
+	  primitiveTableName = theCoverage.getPath().dirCat("txt");
+	  if(!primitiveTable.openTable(primitiveTableName))
+	    {
+	      return;
+	    }
+	  stringValuePosition = primitiveTable.getColumnPosition("string");
+	  shapeLinePosition   = primitiveTable.getColumnPosition("shape_line");
+	}
+      ossim_int32 tileId = -1;
+      for(ossim_uint32 idx = 0; idx < columnValues.size();++idx)
+	{
+	  if(isTiled)
+	    {
+	      if(tileId != tileIds[idx].toInt())
+		{
+		  tileId = tileIds[idx].toInt();
+		  ossimFilename filename = theCoverage.getLibrary()->getTileName(tileIds[idx].toInt());
+		  if(theCoverage.getPath().dirCat(filename).dirCat("txt").exists())
+		    {
+		      primitiveTableName = theCoverage.getPath().dirCat(filename).dirCat("txt");
+		    }
+		  else if(theCoverage.getPath().dirCat(filename.downcase()).dirCat("txt").exists())
+		    {
+		      primitiveTableName = theCoverage.getPath().dirCat(filename.downcase()).dirCat("txt");
+		    }
+		  if(!primitiveTable.openTable(primitiveTableName))
+		    {
+		      return;
+		    }
+		  stringValuePosition = primitiveTable.getColumnPosition("string");
+		  shapeLinePosition   = primitiveTable.getColumnPosition("shape_line");
+		}
+	    }
+	  row_type row = read_row( columnValues[idx].toInt(), 
+				   *primitiveTable.getVpfTableData());
+	  long count = 0;
+	  ossimDpt* ptArray = getXy(*primitiveTable.getVpfTableData(),
+				    row,
+				    shapeLinePosition,
+				    &count);
+	  ossimDpt midPoint;
+	  if(ptArray)
+	    {
+	      midPoint = *ptArray;
+	      
+	      delete [] ptArray;
+	    }
+	  ossimString stringValue = primitiveTable.getColumnValueAsString(row,
+									  stringValuePosition);
+	  free_row(row,  *primitiveTable.getVpfTableData());
+	  
+	  if(!midPoint.hasNans())
+	    {
+	      ossimGpt centerPoint(midPoint.lat,
+				   midPoint.lon,
+				   OSSIM_DBL_NAN);
+              ossimFont* font = ossimFontFactoryRegistry::instance()->createFont(theFontInformation);
+	      ossimGeoAnnotationFontObject* annotation = new ossimGeoAnnotationFontObject(centerPoint,
+											  stringValue);
+              annotation->setColor(thePenColor.getR(),
+                                   thePenColor.getG(),
+                                   thePenColor.getB());
+              annotation->setThickness(theThickness);
+                 
+              annotation->setFont(font);
+	      annotation->setPointSize(theFontInformation.thePointSize);
+	      annotation->setScale(theFontInformation.theScale);
+	      annotation->setShear(theFontInformation.theShear);
+	      annotation->setRotation(theFontInformation.theRotation);
+	      theAnnotationArray.push_back(annotation);
+	    }
+	}  
+    }
+}
+
+void ossimVpfAnnotationFeatureInfo::buildEdgFeature(const ossimFilename& tableName,
+						    const ossimString&   tableKey,
+						    const ossimFilename& primitiveName,
+						    const ossimString&   primitiveKey)
+{
+   ossimFilename tableFileName      = theCoverage.getPath().dirCat(tableName);
+   ossimFilename primitiveTableName;
+   ossimVpfTable table;
+   ossimVpfTable primitiveTable;
+  
+   std::vector<ossimPolyLine> polyLineArray;
+
+   if(table.openTable(tableFileName))
+   {
+      
+      vector<ossimString> columnValues = table.getColumnValues(tableKey.trim());
+      vector<ossimString> tileIds;
+      bool isTiled = false;
+      if(table.getColumnPosition("tile_id") >= 0)
+      {
+         tileIds = table.getColumnValues("tile_id");
+         isTiled = true;
+      }
+      ossim_int32 coordinateValuePosition = 0;
+      if(!isTiled)
+      {
+         primitiveTableName = theCoverage.getPath().dirCat("edg");
+         if(!primitiveTable.openTable(primitiveTableName))
+         {
+            return;
+         }
+         coordinateValuePosition = primitiveTable.getColumnPosition("coordinates");
+      }
+      ossim_int32 tileId = -1;
+      for(ossim_uint32 idx = 0; idx < columnValues.size();++idx)
+      {
+         if(isTiled)
+         {
+            if(tileId != tileIds[idx].toInt())
+            {
+               tileId = tileIds[idx].toInt();
+               ossimFilename filename = theCoverage.getLibrary()->getTileName(tileIds[idx].toInt());
+               if(theCoverage.getPath().dirCat(filename).dirCat("edg").exists())
+               {
+                  primitiveTableName = theCoverage.getPath().dirCat(filename).dirCat("edg");
+               }
+               else if(theCoverage.getPath().dirCat(filename.downcase()).dirCat("edg").exists())
+               {
+                  primitiveTableName = theCoverage.getPath().dirCat(filename.downcase()).dirCat("edg");
+               }
+               if(!primitiveTable.openTable(primitiveTableName))
+               {
+                  return;
+               }
+               coordinateValuePosition = primitiveTable.getColumnPosition("coordinates");
+            }
+         }
+         ossimPolyLine polyLine;
+	  
+         readEdge(polyLine,
+                  columnValues[idx].toInt(),
+                  coordinateValuePosition,
+                  primitiveTable);
+
+	 readAttributes(polyLine, table, idx + 1); // third parm is one-based row
+	  
+         polyLineArray.push_back(polyLine);
+      }
+   }
+   ossimGeoAnnotationMultiPolyLineObject* annotation = new ossimGeoAnnotationMultiPolyLineObject(polyLineArray);
+   annotation->setColor(thePenColor.getR(),
+                        thePenColor.getG(),
+                        thePenColor.getB());
+   annotation->setThickness(theThickness);
+   theAnnotationArray.push_back(annotation);
+}
+
+void ossimVpfAnnotationFeatureInfo::readAttributes(ossimPolyLine& polyLine, ossimVpfTable& table, int row) {
+  int numCols = table.getNumberOfColumns();
+
+  for (int col = 0; col < numCols; col ++) {
+    polyLine.addAttribute( table.getColumnValueAsString( row, col ));
+  }
+}
+
+void ossimVpfAnnotationFeatureInfo::buildPointFeature(const ossimString& primitiveName,
+						      const ossimFilename& tableName,
+						      const ossimString&   tableKey,
+						      const ossimFilename& primitive,
+						      const ossimString&   primitiveKey)
+{
+  ossimFilename tableFileName      = theCoverage.getPath().dirCat(tableName);
+  ossimFilename primitiveTableName;
+  ossimVpfTable table;
+  ossimVpfTable primitiveTable;
+  
+  std::vector<ossimGpt> centerPointArray;
+
+  if(table.openTable(tableFileName))
+    {
+      
+      vector<ossimString> columnValues = table.getColumnValues(tableKey.trim());
+      vector<ossimString> tileIds;
+      bool isTiled = false;
+      if(table.getColumnPosition("tile_id") >= 0)
+	{
+	  tileIds = table.getColumnValues("tile_id");
+	  isTiled = true;
+	}
+      ossim_int32 coordinateValuePosition = 0;
+      if(!isTiled)
+	{
+	  primitiveTableName = theCoverage.getPath().dirCat(primitiveName);
+	  if(!primitiveTable.openTable(primitiveTableName))
+	    {
+	      return;
+	    }
+	  coordinateValuePosition = primitiveTable.getColumnPosition("coordinate");
+	}
+      ossim_int32 tileId = -1;
+      for(ossim_uint32 idx = 0; idx < columnValues.size();++idx)
+	{
+	  if(isTiled)
+	    {
+	      if(tileId != tileIds[idx].toInt())
+		{
+		  tileId = tileIds[idx].toInt();
+		  ossimFilename filename = theCoverage.getLibrary()->getTileName(tileIds[idx].toInt());
+		  if(theCoverage.getPath().dirCat(filename).dirCat(primitiveName).exists())
+		    {
+		      primitiveTableName = theCoverage.getPath().dirCat(filename).dirCat(primitiveName);
+		    }
+		  else if(theCoverage.getPath().dirCat(filename.downcase()).dirCat(primitiveName).exists())
+		    {
+		      primitiveTableName = theCoverage.getPath().dirCat(filename.downcase()).dirCat(primitiveName);
+		    }
+		  if(!primitiveTable.openTable(primitiveTableName))
+		    {
+		      return;
+		    }
+		  coordinateValuePosition = primitiveTable.getColumnPosition("coordinate");
+		}
+	    }
+	  row_type row = read_row( columnValues[idx].toInt(), 
+				   *primitiveTable.getVpfTableData());
+
+	  long count = 0;
+	  ossimDpt* ptArray = getXy(*primitiveTable.getVpfTableData(),
+				    row,
+				    coordinateValuePosition,
+				    &count);
+	  
+	  if(ptArray)
+	    {
+	      for(int i = 0; i < count; ++i)
+		{
+		  if((fabs(ptArray[i].x) <= 180.0)&&
+		     (fabs(ptArray[i].y) <= 90.0))
+		    {
+		      centerPointArray.push_back(ossimGpt(ptArray[i].lat,
+							  ptArray[i].lon,
+							  OSSIM_DBL_NAN));
+		    }
+		}
+	      delete [] ptArray;
+	    }
+	  free_row(row,  *primitiveTable.getVpfTableData());
+	}
+    }
+  ossimGeoAnnotationMultiEllipseObject* annotation = new ossimGeoAnnotationMultiEllipseObject(centerPointArray,
+											      ossimDpt(2,2));
+  annotation->setColor(thePenColor.getR(),
+                       thePenColor.getG(),
+                       thePenColor.getB());
+  annotation->setThickness(theThickness);
+  annotation->setFillFlag(theFillEnabledFlag);
+  annotation->setWidthHeight(thePointRadius);
+  theAnnotationArray.push_back(annotation);
+}
+
+int myFaceCount = 0;
+
+void ossimVpfAnnotationFeatureInfo::buildFaceFeature(const ossimFilename& tableName,
+						     const ossimString&   tableKey, // face_id
+						     const ossimFilename& primitive, //face
+						     const ossimString&   primitiveKey) // id
+{
+  ossimFilename tableFileName      = theCoverage.getPath().dirCat(tableName);
+  ossimFilename primitiveTableName;
+  ossimFilename rngTableName;
+  ossimFilename edgTableName;
+  ossimVpfTable table;
+  ossimVpfTable primitiveTable;
+  ossimVpfTable rngTable;
+  ossimVpfTable edgTable;
+  vector<ossimGeoPolygon> thePolyList;
+  
+  if(table.openTable(tableFileName))
+    {
+      vector<ossimString> columnValues = table.getColumnValues(tableKey.trim()); // fac_id
+      vector<ossimString> tileIds;
+      bool isTiled = false;
+      if(table.getColumnPosition("tile_id") >= 0)
+	{
+	  tileIds = table.getColumnValues("tile_id");
+	  isTiled = true;
+	}
+      ossim_int32 coordinateValuePosition = 0;
+      ossim_int32 startEdgePosition = 0;
+      ossim_int32 rngPtrPosition = 0;
+      if(!isTiled)
+	{
+	  primitiveTableName = theCoverage.getPath().dirCat("fac");
+	  rngTableName = theCoverage.getPath().dirCat("rng");
+	  edgTableName = theCoverage.getPath().dirCat("edg");
+	  if(!primitiveTable.openTable(primitiveTableName)||
+	     !rngTable.openTable(rngTableName)||
+	     !edgTable.openTable(edgTableName))
+	    {
+	      return;
+	    }
+	  coordinateValuePosition = edgTable.getColumnPosition("coordinates");
+	  startEdgePosition = rngTable.getColumnPosition("start_edge");
+	  rngPtrPosition = primitiveTable.getColumnPosition("ring_ptr");
+	} // else will get for each face in loop below
+
+      ossim_int32 tileId = -1;
+
+      for(ossim_uint32 idx = 0; idx < columnValues.size();++idx) // for each face feature
+	{
+	  if(isTiled)		// then get table names because we didn't get them above
+	    {
+	      if((tileId != tileIds[idx].toInt())||
+		 (tileId < 0))
+		{
+		  tileId = tileIds[idx].toInt();
+		  ossimFilename filename = theCoverage.getLibrary()->getTileName(tileIds[idx].toInt());
+		  if(theCoverage.getPath().dirCat(filename).dirCat("fac").exists())
+		    {
+		      primitiveTableName = theCoverage.getPath().dirCat(filename).dirCat("fac");
+		      rngTableName = theCoverage.getPath().dirCat(filename).dirCat("rng");
+		      edgTableName = theCoverage.getPath().dirCat(filename).dirCat("edg");
+		    }
+		  else if(theCoverage.getPath().dirCat(filename.downcase()).dirCat("fac").exists())
+		    {
+		      primitiveTableName = theCoverage.getPath().dirCat(filename.downcase()).dirCat("fac");
+		      rngTableName = theCoverage.getPath().dirCat(filename.downcase()).dirCat("rng");
+		      edgTableName = theCoverage.getPath().dirCat(filename.downcase()).dirCat("edg");
+		    }
+		  if(!primitiveTable.openTable(primitiveTableName)||
+		     !rngTable.openTable(rngTableName)||
+		     !edgTable.openTable(edgTableName))
+		    {
+		      return;
+		    }
+		  coordinateValuePosition = edgTable.getColumnPosition("coordinates");
+		  startEdgePosition = rngTable.getColumnPosition("start_edge");
+		  rngPtrPosition = primitiveTable.getColumnPosition("ring_ptr");
+		}
+	    } // if(isTiled)
+
+	  // get the outer ring id for this face
+	  int thisFaceId = columnValues[idx].toInt();
+	  int rngId = -1;
+
+	  if (thisFaceId <= primitiveTable.getNumberOfRows())
+	    rngId = readRngId(thisFaceId,
+			      rngPtrPosition,
+			      primitiveTable);           // face table
+	  else
+             if(traceDebug())
+             {
+                ossimNotify(ossimNotifyLevel_DEBUG) << "not getting face " << thisFaceId << " from tile " << tileId << " " << primitiveTableName <<
+                   " bacause it has only " << primitiveTable.getNumberOfRows() << " rows" << endl;
+             }
+
+	  if(rngId > 0)
+	    {
+	      int startEdge = readStartEdgeId(rngId,
+					      startEdgePosition,
+					      rngTable);
+	      int outerStartEdge = startEdge;
+	      if(startEdge > 0 )
+              {
+                 ossimGeoPolygon polygon;
+                 
+                 myFaceCount ++;
+                 
+                 int ringTableFaceIdColumn = rngTable.getColumnPosition("face_id");
+                 int ringFaceId = readTableCellAsInt(rngId, ringTableFaceIdColumn, rngTable);
+                 
+                 if (thisFaceId != ringFaceId) {
+		    // as of Mon Dec 20 2004, this has not been observed in vmap0 or vmap1
+                    if(traceDebug())
+                    {
+                       ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting face " << thisFaceId << " from " << tableFileName <<
+                       " because it's ring (" << rngId << ") has face " << ringFaceId << " and startEdgeId " << startEdge << endl;
+                    }
+                 } else {
+		    readGeoPolygon( polygon,
+				    thisFaceId,
+				    startEdge,
+				    edgTable );
+                    
+		    // get the inner rings (holes)
+		    int faceIdPosition = rngTable.getColumnPosition("face_id");
+		    int innerRingOffset = 1;
+		    int rowFaceId = -1;
+		    if (rngId + innerRingOffset <= rngTable.getNumberOfRows())
+		      rowFaceId = rngTable.getColumnValueAsString( rngId + innerRingOffset, faceIdPosition ).toInt();
+		    while (rowFaceId == thisFaceId && rngId + innerRingOffset <= rngTable.getNumberOfRows()) {	// while there are more inner rings
+		      startEdge = readStartEdgeId(rngId + innerRingOffset, startEdgePosition, rngTable);
+
+		      if (startEdge == outerStartEdge) {
+			// as of Mon Dec 20 2004, this has not been observed in vmap0 or vmap1
+                         if(traceDebug())
+                         {
+                            ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting hole in face "
+                                                                << thisFaceId << " because inner ring "
+                                                                << rngId + innerRingOffset
+                                                                << " touches outer ring " << rngId << endl;
+                         }
+
+			innerRingOffset ++;
+			rowFaceId = rngTable.getColumnValueAsString( rngId + innerRingOffset, faceIdPosition ).toInt();
+			continue;
+		      }
+
+		      if(startEdge > 0 )
+			{
+			  ossimGeoPolygon holePolygon;
+		  
+			  readGeoPolygon( holePolygon,
+					  thisFaceId,
+					  startEdge,
+					  edgTable );
+			  if(holePolygon.size())
+			    polygon.addHole( holePolygon );
+			}
+
+		      innerRingOffset ++;
+		    if (rngId + innerRingOffset <= rngTable.getNumberOfRows())
+		      rowFaceId = rngTable.getColumnValueAsString( rngId + innerRingOffset, faceIdPosition ).toInt();
+		    }
+
+		    readAttributes(polygon, table, idx + 1); // third parm is one-based row
+
+		    thePolyList.push_back(polygon);
+		  }
+		}
+	    }
+	} // each fac_id
+    }
+  ossimGeoAnnotationMultiPolyObject* annotation = new ossimGeoAnnotationMultiPolyObject(thePolyList);
+  annotation->setColor(thePenColor.getR(),
+                       thePenColor.getG(),
+                       thePenColor.getB());
+  annotation->setThickness(theThickness);
+  annotation->setFillFlag(theFillEnabledFlag);
+  
+  theAnnotationArray.push_back(annotation);
+}
+
+void ossimVpfAnnotationFeatureInfo::readAttributes(ossimGeoPolygon& polygon, ossimVpfTable& table, int row) {
+  int numCols = table.getNumberOfColumns();
+
+  for (int col = 0; col < numCols; col ++) {
+    ossimString s = table.getColumnValueAsString( row, col );
+    polygon.addAttribute( s );
+  }
+}
+
+/* GET_XY                                                                    */
+/*****************************************************************************/
+ossimDpt *ossimVpfAnnotationFeatureInfo::getXy(vpf_table_type table, 
+					       row_type row, 
+					       long pos, 
+					       long *count)
+{
+  long i;
+  ossimDpt *coord = NULL;
+  
+  switch (table.header[pos].type)
+    {
+    case 'C':
+      {
+	coordinate_type temp, *ptr;
+	ptr = (coordinate_type*)get_table_element(pos, row, table, &temp, count);
+	coord = new ossimDpt[*count];
+	if ((*count == 1) && (ptr == (coordinate_type*)NULL))
+	  {
+            coord->x = (double)temp.x;
+            coord->y = (double)temp.y;
+	  }
+	else 
+	  {
+	    for (i=0; i<*count; i++)
+	      {
+		coord[i].x = (double)ptr[i].x;
+		coord[i].y = (double)ptr[i].y;
+	      }
+	  }
+	if (ptr)
+	  {
+            free((char *)ptr);
+	  }
+	break;
+      }
+    case 'Z':
+      {
+         tri_coordinate_type temp, *ptr;
+         ptr = (tri_coordinate_type*)get_table_element (pos, row, table, &temp, count);
+	 coord = new ossimDpt[*count];
+         if ((*count == 1) && (ptr == (tri_coordinate_type*)NULL))
+	   {
+	     coord->x = (double)temp.x;
+	     coord->y = (double)temp.y;
+	   }
+         else
+	   {
+	     for (i=0; i<*count; i++)
+               {
+		 coord[i].x = (double)ptr[i].x;
+		 coord[i].y = (double)ptr[i].y;
+               }
+	   }
+         if (ptr)
+	   {
+	     free ((char*)ptr);
+	   }
+         break;
+      }
+    case 'B':
+      {
+	double_coordinate_type temp, *ptr;
+	ptr = (double_coordinate_type*)get_table_element (pos, row, table, &temp, count);
+	coord = new ossimDpt[*count];
+	if ((*count == 1) && (ptr == (double_coordinate_type*)NULL))
+	  {
+            coord->x = temp.x;
+            coord->y = temp.y;
+	  }
+	else
+	  {
+	    for (i=0; i<*count; i++)
+	      {
+		coord[i].x = ptr[i].x;
+		coord[i].y = ptr[i].y;
+	      }
+	  }
+	if (ptr)
+	  {
+	    free ((char*)ptr);
+	  }
+	break;
+      }
+    case 'Y':
+      {
+	double_tri_coordinate_type temp, *ptr;
+	ptr = (double_tri_coordinate_type*)get_table_element (pos, row, table, &temp, count);
+	coord = new ossimDpt[*count];
+	if ((*count == 1) && (ptr == (double_tri_coordinate_type*)NULL))
+	  {
+            coord->x = temp.x;
+            coord->y = temp.y;
+	  }
+	else
+	  {
+            for (i=0; i<*count; i++)
+	      {
+		coord[i].x = ptr[i].x;
+		coord[i].y = ptr[i].y;
+	      }
+	  }
+	if (ptr)
+	  {
+	    free((char*)ptr);
+	  }
+	break;
+      }
+      
+    default:
+      break;
+    } /* switch type */
+  return (coord);
+}
+
+int ossimVpfAnnotationFeatureInfo::readTableCellAsInt (int rowNumber,
+						       int colNumber,
+						       ossimVpfTable& table)
+{
+  int result = -1;
+  row_type row = read_row( rowNumber, *table.getVpfTableData());
+  
+  result = table.getColumnValueAsString(row, colNumber).toInt();
+  
+  free_row(row, *table.getVpfTableData());
+  
+  return result;
+}
+
+int ossimVpfAnnotationFeatureInfo::readRngId(int rowNumber,
+					     int colNumber,
+					     ossimVpfTable& faceTable)
+{
+  int idResult = -1;
+  row_type row = read_row( rowNumber, 
+			   *faceTable.getVpfTableData());
+  
+  idResult = faceTable.getColumnValueAsString(row,
+					      colNumber).toInt();
+  
+  free_row(row, *faceTable.getVpfTableData());
+  
+  return idResult;
+}
+
+int ossimVpfAnnotationFeatureInfo::readStartEdgeId(int rowNumber,
+						   int colNumber,
+						   ossimVpfTable& rngTable)
+{
+  int idResult = -1;
+
+  row_type row = read_row( rowNumber, 
+			   *rngTable.getVpfTableData());
+  
+  idResult = rngTable.getColumnValueAsString(row,
+					     colNumber).toInt();
+  
+  free_row(row, *rngTable.getVpfTableData());
+  
+  return idResult;
+  
+}
+
+int ossimVpfAnnotationFeatureInfo::getEdgeKeyId (vpf_table_type& table, row_type& row, int col) {
+    id_triplet_type key;
+    long keyCount;
+    get_table_element( col,
+		       row,
+		       table,
+		       & key,
+		       & keyCount );
+    return key.id;
+}
+
+void ossimVpfAnnotationFeatureInfo::readGeoPolygon(ossimGeoPolygon& polygon,
+						   int faceId,
+						   int startEdgeId,
+						   ossimVpfTable& edgTable) {
+
+  ossim_int32 coordinatesCol = edgTable.getColumnPosition( "coordinates" );
+  ossim_int32 startNodeCol = edgTable.getColumnPosition( "start_node" );
+  ossim_int32 endNodeCol = edgTable.getColumnPosition( "end_node" );
+  ossim_int32 rightEdgeCol = edgTable.getColumnPosition( "right_edge" );
+  ossim_int32 leftEdgeCol = edgTable.getColumnPosition( "left_edge" );
+  ossim_int32 rightFaceCol = edgTable.getColumnPosition( "right_face" );
+  ossim_int32 leftFaceCol = edgTable.getColumnPosition( "left_face" );
+
+  // collect edges
+  vector < int > edges;
+  int lastEdge = startEdgeId;
+  edges.push_back( lastEdge );
+
+  row_type row = read_row( startEdgeId, *edgTable.getVpfTableData() );
+  int startNode = edgTable.getColumnValueAsString( row, startNodeCol ).toInt();
+  int endNode = edgTable.getColumnValueAsString( row, endNodeCol ).toInt();
+
+  if (startNode != endNode) { // there's more than one edge to this ring
+    int rightFace = getEdgeKeyId( *edgTable.getVpfTableData(), row, rightFaceCol );
+    int leftFace = getEdgeKeyId( *edgTable.getVpfTableData(), row, leftFaceCol );
+    int rightEdge = getEdgeKeyId( *edgTable.getVpfTableData(), row, rightEdgeCol );
+    int leftEdge = getEdgeKeyId( *edgTable.getVpfTableData(), row, leftEdgeCol );
+    int nextEdge;
+    int firstNode, lastNode;
+
+    if (rightFace == leftFace) {
+      if (rightEdge == leftEdge) {
+	free_row(row,  *edgTable.getVpfTableData());
+	// as of Mon Dec 20 2004, this has not been observed in vmap0 or vmap1
+	// cout << "rejecting floating line face " << faceId << " line " << __LINE__ << endl;
+	return;
+      }
+
+      // this is a dangling start edge; find a non dangling edge to use as the start edge
+      int dirRight = 1;
+      int nextEdge = startEdgeId;
+      int nextLeftFace = leftFace;
+      int nextRightFace = rightFace;
+      int mobiusLimit = 1000;
+
+      while (nextLeftFace == nextRightFace) {
+	if (-- mobiusLimit < 0) {
+	    free_row(row,  *edgTable.getVpfTableData());
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting mobius face " << faceId << " line " << __LINE__ << endl;
+            }
+	    return;
+	}
+
+	int thisEdge = nextEdge;
+	if (dirRight) {
+	  nextEdge = getEdgeKeyId( *edgTable.getVpfTableData(), row, rightEdgeCol );
+	  if (nextEdge == thisEdge)
+	    dirRight = 0;
+	  else if (nextEdge == startEdgeId) {
+	    free_row(row,  *edgTable.getVpfTableData());
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting mobius face " << faceId << " line " << __LINE__ << endl;
+            }
+	    return;
+	  }
+	} else {
+	  nextEdge = getEdgeKeyId( *edgTable.getVpfTableData(), row, leftEdgeCol );
+	  if (nextEdge == thisEdge) {
+	    free_row(row,  *edgTable.getVpfTableData());
+	    // as of Mon Dec 20 2004, this has not been observed in vmap0 or vmap1
+	    // cout << "rejecting multi floating line face " << faceId << " line " << __LINE__ << endl;
+	    return;
+	  } else if (nextEdge == startEdgeId) {
+	    free_row(row,  *edgTable.getVpfTableData());
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting mobius face " << faceId << " line " << __LINE__ << endl;
+            }
+	    return;
+	  }
+	}
+	free_row(row,  *edgTable.getVpfTableData());
+	row = read_row( nextEdge, *edgTable.getVpfTableData() );
+	nextRightFace = getEdgeKeyId( *edgTable.getVpfTableData(), row, rightFaceCol );
+	nextLeftFace = getEdgeKeyId( *edgTable.getVpfTableData(), row, leftFaceCol );
+      }
+
+      startEdgeId = nextEdge;
+      rightFace = nextRightFace;
+      leftFace = nextLeftFace;
+      free_row(row,  *edgTable.getVpfTableData());
+      row = read_row( startEdgeId, *edgTable.getVpfTableData() );
+      startNode = edgTable.getColumnValueAsString( row, startNodeCol ).toInt();
+      endNode = edgTable.getColumnValueAsString( row, endNodeCol ).toInt();
+    }
+
+    if (rightFace == faceId) {
+      nextEdge = getEdgeKeyId( *edgTable.getVpfTableData(), row, rightEdgeCol );
+      firstNode = startNode;
+      lastNode = endNode;
+    } else if (leftFace == faceId) {
+      nextEdge = getEdgeKeyId( *edgTable.getVpfTableData(), row, leftEdgeCol );
+      firstNode = endNode;
+      lastNode = startNode;
+    }
+    else
+    {
+       if(traceDebug())
+       {
+          ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting face " << faceId << " line " << __LINE__ << endl;
+       }
+       return;
+    }
+
+    row_type nextRow;
+    while (true) {
+      nextRow = read_row( nextEdge, *edgTable.getVpfTableData() );
+      int nextLeftEdge = getEdgeKeyId( *edgTable.getVpfTableData(), nextRow, leftEdgeCol );
+      int nextRightEdge = getEdgeKeyId( *edgTable.getVpfTableData(), nextRow, rightEdgeCol );
+      int nextLeftFace = getEdgeKeyId( *edgTable.getVpfTableData(), nextRow, leftFaceCol );
+      int nextRightFace = getEdgeKeyId( *edgTable.getVpfTableData(), nextRow, rightFaceCol );
+      int nextStartNode = edgTable.getColumnValueAsString( nextRow, startNodeCol ).toInt();
+      int nextEndNode = edgTable.getColumnValueAsString( nextRow, endNodeCol ).toInt();
+
+      while (nextLeftFace == nextRightFace) {
+	int lastEnd;
+	if (rightFace == faceId)
+	  lastEnd = edgTable.getColumnValueAsString( row, endNodeCol ).toInt();
+	else
+	  lastEnd = edgTable.getColumnValueAsString( row, startNodeCol ).toInt();
+
+	if (lastEnd == nextStartNode)
+	  nextEdge = nextLeftEdge;
+	else if (lastEnd == nextEndNode)
+	  nextEdge = nextRightEdge;
+	else {			// bad face
+           if(traceDebug())
+           {
+              ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting face " << faceId << " line " << __LINE__ << endl;
+           }
+	  return;
+	}
+	if (lastEdge == nextEdge)
+        { // bad face
+           if(traceDebug())
+           {
+              ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting face " << faceId << " line " << __LINE__ << endl;
+           }
+           return;
+	}
+
+	free_row(nextRow,  *edgTable.getVpfTableData());
+	nextRow = read_row( nextEdge, *edgTable.getVpfTableData() );
+	nextLeftEdge = getEdgeKeyId( *edgTable.getVpfTableData(), nextRow, leftEdgeCol );
+	nextRightEdge = getEdgeKeyId( *edgTable.getVpfTableData(), nextRow, rightEdgeCol );
+	nextLeftFace = getEdgeKeyId( *edgTable.getVpfTableData(), nextRow, leftFaceCol );
+	nextRightFace = getEdgeKeyId( *edgTable.getVpfTableData(), nextRow, rightFaceCol );
+	nextStartNode = edgTable.getColumnValueAsString( nextRow, startNodeCol ).toInt();
+	nextEndNode = edgTable.getColumnValueAsString( nextRow, endNodeCol ).toInt();
+      }
+	
+      lastEdge = nextEdge;
+      edges.push_back( lastEdge );
+
+      {
+	int lastEnd;
+	if (nextRightFace == faceId) {
+	  if (lastNode != nextStartNode) {
+             if(traceDebug())
+             {
+                ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting face " << faceId << " line " << __LINE__ << endl;
+             }
+	    return;
+	  }
+	  lastEnd = nextEndNode;
+	} else if (nextLeftFace == faceId) {
+	  if (lastNode != nextEndNode) {
+             if(traceDebug())
+             {
+                ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting face " << faceId << " line " << __LINE__ << endl;
+             }
+	    return;
+	  }
+	  lastEnd = nextStartNode;
+	} else {
+           if(traceDebug())
+           {
+              ossimNotify(ossimNotifyLevel_DEBUG) << "rejecting face " << faceId << " line " << __LINE__ << endl;
+           }
+	  return;
+	}
+
+	if (lastEnd == firstNode)
+	  break;
+      }
+
+      free_row(row,  *edgTable.getVpfTableData());
+      row = nextRow;
+      startNode = nextStartNode;
+      endNode = nextEndNode;
+      rightFace = nextRightFace;
+      leftFace = nextLeftFace;
+
+      if (rightFace == faceId) {
+	nextEdge = nextRightEdge;
+	lastNode = endNode;
+      } else {
+	nextEdge = nextLeftEdge;
+	lastNode = startNode;
+      }
+    }
+
+    free_row(nextRow,  *edgTable.getVpfTableData());
+    nextRow = 0;
+  }
+
+  for (vector< int >::iterator i = edges.begin(); i != edges.end(); i++) {
+    long count = 0;
+    free_row(row,  *edgTable.getVpfTableData());
+    row = read_row( *i, *edgTable.getVpfTableData() );
+    ossimDpt* ptArray = getXy(*edgTable.getVpfTableData(),
+			      row,
+			      coordinatesCol,
+			      &count);
+  
+    if(ptArray)
+      {
+	int rightFace = getEdgeKeyId( *edgTable.getVpfTableData(), row, rightFaceCol );
+
+	if (rightFace == faceId) {
+	  for(int p = 0; p < count; ++p)
+	    {
+	      if((fabs(ptArray[p].x) <= 180.0)&&
+		 (fabs(ptArray[p].y) <= 90.0))
+		{
+		  polygon.addPoint(ptArray[p].y, ptArray[p].x);
+		}
+	    }
+	} else {
+	  for(int p = count - 1; p >= 0; --p)
+	    {
+	      if((fabs(ptArray[p].x) <= 180.0)&&
+		 (fabs(ptArray[p].y) <= 90.0))
+		{
+		  polygon.addPoint(ptArray[p].y, ptArray[p].x);
+		}
+	    }
+	}
+	delete [] ptArray;
+      }
+  }
+  free_row(row,  *edgTable.getVpfTableData());
+}
+
+void ossimVpfAnnotationFeatureInfo::readEdge(ossimPolyLine& polyLine,
+					     int rowNumber,
+					     int colPosition,
+					     ossimVpfTable& edgeTable)
+{
+  polyLine.clear();
+  row_type row = read_row( rowNumber, 
+			   *edgeTable.getVpfTableData());
+
+  long count = 0;
+  ossimDpt* ptArray = getXy(*edgeTable.getVpfTableData(),
+			    row,
+			    colPosition,
+			    &count);
+  
+  if(ptArray)
+    {
+      for(int i = 0; i < count; ++i)
+	{
+	  if((fabs(ptArray[i].x) <= 180.0)&&
+	     (fabs(ptArray[i].y) <= 90.0))
+	    {
+	      polyLine.addPoint(ossimDpt(ptArray[i].x,
+					 ptArray[i].y));
+	    }
+	}
+      delete [] ptArray;
+    }
+  free_row(row,  *edgeTable.getVpfTableData());
+}
+
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.h b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.h
new file mode 100644
index 0000000000..700aa574e8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.h
@@ -0,0 +1,218 @@
+#ifndef ossimVpfAnnotationFeatureInfo_HEADER
+#define ossimVpfAnnotationFeatureInfo_HEADER
+#include "base/data_types/color_space/ossimRgbVector.h"
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimGeoPolygon.h"
+#include "imaging/annotation/ossimGeoAnnotationObject.h"
+#include "vec/vpf/ossimVpfCoverage.h"
+#include "base/common/ossimFontInformation.h"
+
+class ossimGeoAnnotationObject;
+class ossimVpfCoverage;
+class ossimVpfFeatureClassSchema;
+class ossimPolyLine;
+
+class OSSIMDLLEXPORT ossimVpfAnnotationFeatureInfo : public ossimObject
+{
+public:
+  enum ossimVpfAnnotationFeatureType
+    {
+      ossimVpfAnnotationFeatureType_UNKNOWN  = 0,
+      ossimVpfAnnotationFeatureType_POINT    = 1,
+      ossimVpfAnnotationFeatureType_LINE     = 2,
+      ossimVpfAnnotationFeatureType_POLYGON  = 3,
+      ossimVpfAnnotationFeatureType_TEXT     = 4,
+    };
+
+  ossimVpfAnnotationFeatureInfo(const ossimString& featureName   = "",
+				const ossimRgbVector& penColor   = ossimRgbVector(255,255,255),
+				const ossimRgbVector& brushColor = ossimRgbVector(255,255,255),
+                                const ossimDpt& pointRadius=ossimDpt(1,1),
+                                int   thickness=0,
+				bool enabledFlag = true);
+  ossimVpfAnnotationFeatureInfo::~ossimVpfAnnotationFeatureInfo();
+
+  void setCoverage(const ossimVpfCoverage& coverage)
+  {
+    theCoverage = coverage;
+  }
+
+  const ossimVpfCoverage& getCoverage()const
+  {
+    return theCoverage;
+  }
+  ossimVpfCoverage& getCoverage()
+  {
+    return theCoverage;
+  }
+
+   void setColor(const ossimRgbVector& color)
+      {
+         setPenColor(color);
+         setBrushColor(color);
+      }
+  void setPenColor(const ossimRgbVector& penColor)
+  {
+    thePenColor = penColor;
+  }
+
+  ossimRgbVector getPenColor()const
+  {
+    return thePenColor;
+  }
+
+  void setBrushColor(const ossimRgbVector& brushColor)
+  {
+    theBrushColor = brushColor;
+  }
+
+  ossimRgbVector getBrushColor()const
+  {
+    return theBrushColor;
+  }
+
+  void setFillEnabledFlag(bool flag)
+  {
+     theFillEnabledFlag = flag;
+  }
+  bool getFillEnabledFlag()const
+  {
+     return theFillEnabledFlag;
+  }
+  void setEnabledFlag(bool flag);
+  bool getEnabledFlag()const
+  {
+    return theEnabledFlag;
+  }
+
+  void setThickness(int thickness)
+  {
+     theThickness = thickness;
+  }
+
+  int getThickness()const
+  {
+     return theThickness;
+  }
+  
+  void setName(const ossimString& name)
+  {
+    theName = name;
+  }
+  const ossimString& getName()const
+  {
+    return theName;
+  }
+   
+  bool isPoint()const
+  {
+     return (theFeatureType == ossimVpfAnnotationFeatureType_POINT);
+  }
+  bool isLine()const
+  {
+     return (theFeatureType == ossimVpfAnnotationFeatureType_LINE);
+  }
+  bool isPolygon()const
+  {
+     return (theFeatureType == ossimVpfAnnotationFeatureType_POLYGON);
+  }
+  bool isText()const
+  {
+     return (theFeatureType == ossimVpfAnnotationFeatureType_TEXT);
+  }
+  void getFontInformation(ossimFontInformation& fontInfo)const
+  {
+     fontInfo = theFontInformation;
+  }
+  void setFontInformation(const ossimFontInformation& fontInfo)
+  {
+     theFontInformation = fontInfo;
+  }
+
+  void setPointRadius(const ossimDpt& radius)
+  {
+    thePointRadius = radius;
+  }
+  ossimDpt getPointRadius()const
+  {
+    return thePointRadius;
+  }
+  void setDrawingFeaturesToAnnotation();
+  ossimIrect getBoundingProjectedRect()const;
+  void transform(ossimProjection* proj);
+  void buildFeature();
+  void deleteAllObjects();
+  void drawAnnotations(ossimRgbImage* tile);
+
+  bool saveState(ossimKeywordlist& kwl,
+		 const char* prefix=0)const;
+  bool loadState(const ossimKeywordlist& kwl,
+		 const char* prefix=0);
+  ossimString getFeatureTypeAsString()const;
+  ossimVpfAnnotationFeatureType getFeatureTypeFromString(const ossimString& featureType)const;
+
+private:
+  void readAttributes(ossimPolyLine& polyLine, ossimVpfTable& table, int row);
+  void readAttributes(ossimGeoPolygon& polygon, ossimVpfTable& table, int row);
+
+protected:
+  ossimString                   theName;
+  ossimString                   theDescription;
+  ossimRgbVector                thePenColor;
+  ossimRgbVector                theBrushColor;
+  ossimVpfCoverage              theCoverage;
+  ossimDpt                      thePointRadius;
+  int                          theThickness; 
+  bool                         theFillEnabledFlag;
+  bool                         theEnabledFlag;
+  ossimVpfAnnotationFeatureType theFeatureType;
+  ossimFontInformation          theFontInformation;
+   
+  std::vector<ossimGeoAnnotationObject*> theAnnotationArray;
+
+  void buildTxtFeature(const ossimFilename& table,
+                       const ossimString&   tableKey,
+                       const ossimFilename& primitive,
+                       const ossimString&   primitiveKey);
+   
+  void buildEdgFeature(const ossimFilename& table,
+                       const ossimString&   tableKey,
+		       const ossimFilename& primitive,
+		       const ossimString&   primitiveKey);
+
+  void buildPointFeature(const ossimString& primitiveName,
+			 const ossimFilename& table,
+			 const ossimString&   tableKey,
+			 const ossimFilename& primitive,
+			 const ossimString&   primitiveKey);
+  void buildFaceFeature(const ossimFilename& table,
+                        const ossimString&   tableKey,
+                        const ossimFilename& primitive,
+			const ossimString&   primitiveKey);
+  
+
+  void readEdge(ossimPolyLine& polyLine,
+		int rowNumber,
+		int colPosition,
+		ossimVpfTable& edgeTable);
+  int readTableCellAsInt (int rowNumber, // should replace calls to readRngId, readStartEdgeId with this
+			  int colNumber,
+			  ossimVpfTable& table);
+  int readRngId(int rowNumber,
+		int colNumber,
+		ossimVpfTable& faceTable);
+  int readStartEdgeId(int rowNumber,
+		      int colNumber,
+		      ossimVpfTable& rngTable);
+  void readGeoPolygon(ossimGeoPolygon& polygon,
+		      int faceId,
+		      int startEdgeId,
+		      ossimVpfTable& edgTable);
+
+  ossimDpt* getXy(vpf_table_type table, row_type row, long pos, long* count);
+  int getEdgeKeyId (vpf_table_type& table, row_type& row, int col);
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.cpp
new file mode 100644
index 0000000000..8fe71c8129
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.cpp
@@ -0,0 +1,260 @@
+//*************************************************************************
+// Copyright (C) 2004 Intelligence Data Systems, Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+//**************************************************************************
+// $Id: ossimVpfAnnotationLibraryInfo.cpp,v 1.12 2004/12/21 20:12:40 gpotts Exp $
+
+#include <algorithm>
+
+#include <imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.h>
+#include <imaging/formats/vpf/ossimVpfAnnotationFeatureInfo.h>
+#include <vec/vpf/ossimVpfLibrary.h>
+#include <vec/vpf/ossimVpfDatabase.h>
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug("ossimVpfAnnotationLibraryInfo:debug");
+
+
+ossimVpfAnnotationLibraryInfo::ossimVpfAnnotationLibraryInfo(const ossimString& libraryName, bool enabledFlag)
+   :
+      theName(libraryName),
+      theEnabledFlag(enabledFlag),
+      theDatabase(NULL)
+{
+}
+
+ossimVpfAnnotationLibraryInfo::~ossimVpfAnnotationLibraryInfo()
+{
+   deleteAllCoverage();
+}
+
+bool ossimVpfAnnotationLibraryInfo::getEnabledFlag()const
+{
+   return theEnabledFlag;
+}
+
+void ossimVpfAnnotationLibraryInfo::setEnabledFlag(bool flag)
+{
+   theEnabledFlag = flag;
+}
+
+const ossimString& ossimVpfAnnotationLibraryInfo::getName()const
+{
+   return theName;
+}
+
+void ossimVpfAnnotationLibraryInfo::setName(const ossimString& libraryName)
+{
+   theName = libraryName;
+}
+
+void ossimVpfAnnotationLibraryInfo::setDatabase(ossimVpfDatabase* database)
+{
+   theDatabase = database;
+}
+
+ossimVpfDatabase* ossimVpfAnnotationLibraryInfo::getDatabase()
+{
+   return theDatabase;
+}
+
+ossimIrect ossimVpfAnnotationLibraryInfo::getBoundingProjectedRect()const
+{
+   ossimIrect result;
+   result.makeNan();
+   
+   for(ossim_uint32 idx = 0; idx < theCoverageLayerList.size(); ++idx)
+   {
+      ossimIrect tempRect = theCoverageLayerList[idx]->getBoundingProjectedRect();
+      if(!tempRect.hasNans())
+      {
+         if(result.hasNans())
+         {
+            result = tempRect;
+         }
+         else
+         {
+            result = result.combine(tempRect);
+         }
+      }
+   }
+   
+   return result;
+}
+
+void ossimVpfAnnotationLibraryInfo::getAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& features)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationLibraryInfo::getAllFeatures DEBUG: entered..." << std::endl;
+   }
+   
+   for(ossim_uint32 idx = 0; idx < theCoverageLayerList.size(); ++idx)
+   {
+      theCoverageLayerList[idx]->getAllFeatures(features);
+   }
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationLibraryInfo::getAllFeatures DEBUG: leaving..." << std::endl;
+   }
+}
+
+void ossimVpfAnnotationLibraryInfo::transform(ossimProjection* proj)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationLibraryInfo::transform DEBUG: entered..." << std::endl;
+   }
+   
+   
+   for(ossim_uint32 idx = 0; idx < theCoverageLayerList.size(); ++idx)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "transforming coverage = " << theCoverageLayerList[idx]->getName() << std::endl;
+      }
+      
+      theCoverageLayerList[idx]->transform(proj);
+   }
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationLibraryInfo::transform DEBUG: leaving..." << std::endl;
+   }
+}
+
+void ossimVpfAnnotationLibraryInfo::buildLibrary()
+{
+   buildLibrary( "", "");
+}
+
+void ossimVpfAnnotationLibraryInfo::buildLibrary(const ossimString& coverageName, const ossimString& feature)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationLibraryInfo::buildLibrary DEBUG: entered..." << std::endl;
+   }
+   deleteAllCoverage();
+   if(!theDatabase)
+   {
+      return;
+   }
+   
+   ossimVpfLibrary* library = theDatabase->getLibrary(theName);
+   if(library)
+   {
+      std::vector<ossimString> coverageNames;
+      library->getCoverageNames(coverageNames);
+      for(ossim_uint32 idx = 0; idx < coverageNames.size(); ++idx)
+      {
+         ossimString s1 = coverageName;
+         ossimString s2 = coverageNames[idx];
+         s1.downcase();
+         s2.downcase();
+         if ( ! coverageName.length() || (s1 == s2) )
+         {
+            ossimVpfAnnotationCoverageInfo* coverageInfo =
+               new ossimVpfAnnotationCoverageInfo;
+            coverageInfo->setName(coverageNames[idx]);
+            coverageInfo->setLibrary(library);
+            theCoverageLayerList.push_back(coverageInfo);
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "coverage name = " << coverageNames[idx] << std::endl;
+            }
+            coverageInfo->buildCoverage(feature);
+         }
+      }
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationLibraryInfo::buildLibrary DEBUG: leaving..." << std::endl;
+   }
+}
+
+
+void ossimVpfAnnotationLibraryInfo::drawAnnotations(ossimRgbImage* tile)
+{
+  for(ossim_uint32 idx = 0; idx < theCoverageLayerList.size(); ++idx)
+    {
+      theCoverageLayerList[idx]->drawAnnotations(tile);
+    }
+}
+
+void ossimVpfAnnotationLibraryInfo::deleteAllCoverage()
+{
+  for(ossim_uint32 idx = 0; idx < theCoverageLayerList.size(); ++idx)
+    {
+      delete theCoverageLayerList[idx];
+    }
+
+  theCoverageLayerList.clear();
+}
+
+bool ossimVpfAnnotationLibraryInfo::saveState(ossimKeywordlist& kwl,
+					      const char* prefix)const
+{
+   ossim_uint32 idx;
+   
+   kwl.add(prefix,
+           "name",
+           theName,
+           true);
+   
+   for(idx = 0; idx < theCoverageLayerList.size(); ++idx)
+   {
+      theCoverageLayerList[idx]->saveState(kwl,
+					   (ossimString(prefix) + "coverage" + ossimString::toString(idx) + ".").c_str());
+   }
+   
+   return true;
+}
+
+bool ossimVpfAnnotationLibraryInfo::loadState(const ossimKeywordlist& kwl,
+					      const char* prefix)
+{
+  deleteAllCoverage();
+  theName = kwl.find(prefix, "name");
+  
+  ossimVpfLibrary* library = theDatabase->getLibrary(theName);
+
+  if(!library)
+    {
+      return false;
+    }
+  ossimString regExpression =  ossimString("^(") + ossimString(prefix) + "coverage[0-9]+.)";
+  vector<ossimString> keys =
+    kwl.getSubstringKeyList( regExpression );
+  std::vector<int> theNumberList(keys.size());
+  int offset = (ossimString(prefix)+"coverage").size();
+  int idx = 0;
+  for(idx = 0; idx < (int)theNumberList.size();++idx)
+    {
+      ossimString numberStr(keys[idx].begin() + offset,
+			    keys[idx].end());
+      theNumberList[idx] = numberStr.toInt();
+    }
+  std::sort(theNumberList.begin(), theNumberList.end());
+  
+  for(idx = 0; idx < (int)keys.size(); ++idx)
+    {
+      ossimString newPrefix = ossimString(prefix);
+      newPrefix += ossimString("coverage");
+      newPrefix += ossimString::toString(theNumberList[idx]);
+      newPrefix += ossimString(".");
+      ossimVpfAnnotationCoverageInfo* coverageInfo = new ossimVpfAnnotationCoverageInfo;
+      coverageInfo->setLibrary(library);
+      theCoverageLayerList.push_back(coverageInfo);
+      coverageInfo->loadState(kwl,
+			      newPrefix);
+    }
+  
+  return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.h b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.h
new file mode 100644
index 0000000000..a9bf66a48e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.h
@@ -0,0 +1,52 @@
+#ifndef ossimVpfAnnotationLibraryInfo_HEADER
+#define ossimVpfAnnotationLibraryInfo_HEADER
+#include <map>
+#include "base/data_types/ossimString.h"
+#include "ossimVpfAnnotationCoverageInfo.h"
+
+class ossimVpfDatabase;
+class ossimRgbImage;
+class ossimVpfAnnotationFeatureInfo;
+
+class OSSIMDLLEXPORT ossimVpfAnnotationLibraryInfo
+{
+public:
+  ossimVpfAnnotationLibraryInfo(const ossimString& libraryName = "",
+				bool enabledFlag=true);
+
+  virtual ~ossimVpfAnnotationLibraryInfo();
+
+  bool getEnabledFlag()const;
+
+  void setEnabledFlag(bool flag);
+
+  const ossimString& getName()const;
+
+  void setName(const ossimString& libraryName);
+
+  void setDatabase(ossimVpfDatabase* database);
+
+  ossimVpfDatabase* getDatabase();
+
+  ossimIrect getBoundingProjectedRect()const;
+  
+  void transform(ossimProjection* proj);
+  void buildLibrary();
+  void buildLibrary(const ossimString& coverageName, const ossimString& feature);
+  void deleteAllCoverage();
+  void drawAnnotations(ossimRgbImage* tile);
+  void getAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& features);
+
+  virtual bool saveState(ossimKeywordlist& kwl,
+			 const char* prefix=0)const;
+  virtual bool loadState(const ossimKeywordlist& kwl,
+			 const char* prefix=0);
+  
+protected:
+   ossimString theName;
+   bool theEnabledFlag;
+   ossimVpfDatabase* theDatabase;
+   std::vector<ossimVpfAnnotationCoverageInfo*> theCoverageLayerList;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationSource.cpp
new file mode 100644
index 0000000000..2e3819922d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationSource.cpp
@@ -0,0 +1,267 @@
+#include <algorithm>
+
+#include <imaging/formats/vpf/ossimVpfAnnotationSource.h>
+#include <imaging/formats/vpf/ossimVpfAnnotationLibraryInfo.h>
+#include <vec/vpf/ossimVpfExtent.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <imaging/ossimRgbImage.h>
+#include <imaging/ossimU8ImageData.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimKeywordNames.h>
+
+static ossimTrace traceDebug("ossimVpfAnnotationSource:debug");
+
+ossimVpfAnnotationSource::ossimVpfAnnotationSource()
+   :ossimGeoAnnotationSource()
+{
+  if(!theProjection)
+    {
+      theProjection = new ossimEquDistCylProjection;
+      theOwnsProjectionFlag = true;
+    }
+   ossimMapProjection* mapProj = (ossimMapProjection*) theProjection;
+
+   if(mapProj)
+     {
+       mapProj->setMetersPerPixel(ossimDpt(30, 30));
+     }
+}
+
+ossimVpfAnnotationSource::~ossimVpfAnnotationSource()
+{
+   close();
+}
+
+bool ossimVpfAnnotationSource::open(const ossimFilename& file)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationSource::open DEBUG: entering..." << std::endl;
+   }
+   bool result = false;
+   
+   if(file.file().downcase() == "dht")
+   {
+      if(openDatabase(file))
+      {
+         vector<ossimString> libraryNames = theDatabase.getLibraryNames();
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "Library names list size = " << libraryNames.size() << std::endl;
+         }
+         
+         for(int idx = 0; idx < (int)libraryNames.size();++idx)
+         {
+            ossimVpfAnnotationLibraryInfo* info = new ossimVpfAnnotationLibraryInfo;
+            info->setName(libraryNames[idx]);
+            theLibraryInfo.push_back(info);
+            info->setDatabase(&theDatabase);
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "loading library " << libraryNames[idx] << std::endl;
+            }
+            info->buildLibrary();
+            info->getAllFeatures(theFeatureList);
+         }
+         transformObjects();
+         result = true;
+      }
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationSource::open DEBUG: leaving..." << std::endl;
+   }
+   return result;
+}
+
+void ossimVpfAnnotationSource::close()
+{
+   theDatabase.closeDatabase();
+   for(int idx = 0; idx < (int)theLibraryInfo.size(); ++idx)
+   {
+      delete theLibraryInfo[idx];
+   }
+   
+   theLibraryInfo.clear();
+}
+
+ossimFilename ossimVpfAnnotationSource::getFilename()const
+{
+   return theFilename;
+}
+
+void ossimVpfAnnotationSource::transformObjects(ossimProjection* projection)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationSource::transformObjects DEBUG: entered..." << std::endl;
+   }
+   ossimProjection* proj = projection;
+   
+   if(!proj)
+   {
+      proj = theProjection;
+   }
+   
+   if(!proj) return;
+   for(int idx = 0; idx < (int)theLibraryInfo.size(); ++idx)
+   {
+      theLibraryInfo[idx]->transform(proj);
+   }
+   computeBoundingRect();
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimVpfAnnotationSource::transformObjects DEBUG: leaving..." << std::endl;
+   }
+}
+
+void ossimVpfAnnotationSource::computeBoundingRect()
+
+{
+  ossimIrect result;
+  result.makeNan();
+  for(int i = 0; i < (int)theLibraryInfo.size();++i)
+    {
+      ossimIrect tempRect = theLibraryInfo[i]->getBoundingProjectedRect();
+      if(!tempRect.hasNans())
+	{
+	  if(result.hasNans())
+	    {
+	      result = tempRect;
+	    }
+	  else
+	    {
+	      result = result.combine(tempRect);
+	    }
+	}
+    }
+
+  theRectangle = result;
+}
+
+
+void ossimVpfAnnotationSource::deleteAllLibraries()
+{
+  for(int idx = 0; idx < (int)theLibraryInfo.size();++idx)
+    {
+      delete theLibraryInfo[idx];
+    }
+  
+  theLibraryInfo.clear();
+}
+
+void ossimVpfAnnotationSource::getAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& features)
+{
+   features = theFeatureList;
+}
+
+void ossimVpfAnnotationSource::setAllFeatures(const std::vector<ossimVpfAnnotationFeatureInfo*>& features)
+{
+  theFeatureList = features;
+  
+  computeBoundingRect();
+  
+}
+
+
+void ossimVpfAnnotationSource::drawAnnotations(ossimRefPtr<ossimImageData> tile)
+{
+   theImage->setCurrentImageData(tile);
+   if(theImage->getImageData().valid())
+   {
+      for(ossim_uint32 idx = 0; idx < theFeatureList.size();++idx)
+      {
+         if(theFeatureList[idx]->getEnabledFlag())
+         {
+            theFeatureList[idx]->drawAnnotations(theImage);
+         }
+      }
+   }  
+}
+
+bool ossimVpfAnnotationSource::openDatabase(const ossimFilename& file)
+{
+  ossimAnnotationSource::deleteAll();
+  deleteAllLibraries();
+  theFeatureList.clear();
+  if(theDatabase.isOpened())
+    {
+      theDatabase.closeDatabase();
+    }
+
+  theFilename = file;
+  return theDatabase.openDatabase(file);
+}
+
+
+bool ossimVpfAnnotationSource::saveState(ossimKeywordlist& kwl,
+                                         const char* prefix)const
+{
+  kwl.add(prefix,
+	  ossimKeywordNames::FILENAME_KW,
+	  theFilename,
+	  true);
+  for(ossim_uint32 idx = 0; idx < theLibraryInfo.size(); ++idx)
+    {
+       theLibraryInfo[idx]->saveState(kwl,
+ 				     (ossimString(prefix) + "library" + ossimString::toString(idx) + ".").c_str());
+    }
+   return true;
+}
+
+bool ossimVpfAnnotationSource::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+  bool result = false;
+  deleteAllLibraries();
+  const char* filename    = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+  if(filename)
+    {
+      if(openDatabase(filename))
+	{
+	  int idx = 0;
+	  ossimString regExpression =  ossimString("^(") + ossimString(prefix) + "library[0-9]+.)";
+	  vector<ossimString> keys =
+	    kwl.getSubstringKeyList( regExpression );
+	  std::vector<int> theNumberList(keys.size());
+	  int offset = (ossimString(prefix)+"library").size();
+
+	  for(idx = 0; idx < (int)theNumberList.size();++idx)
+	    {
+	      ossimString numberStr(keys[idx].begin() + offset,
+				    keys[idx].end());
+	      theNumberList[idx] = numberStr.toInt();
+	    }
+	  std::sort(theNumberList.begin(), theNumberList.end());
+
+	  for(idx=0;idx < (int)keys.size();++idx)
+	    {
+	      ossimString newPrefix = ossimString(prefix);
+	      newPrefix += ossimString("library");
+	      newPrefix += ossimString::toString(theNumberList[idx]);
+	      newPrefix += ossimString(".");
+
+	      ossimVpfAnnotationLibraryInfo* info = new ossimVpfAnnotationLibraryInfo;
+	      theLibraryInfo.push_back(info);
+	      info->setDatabase(&theDatabase);
+	      info->loadState(kwl,
+			      newPrefix);
+	      info->getAllFeatures(theFeatureList);
+	    }
+	  transformObjects();
+	  result = true;
+	}
+    }
+  
+  return result;
+}
+
+bool ossimVpfAnnotationSource::open()
+{
+   return open(theFilename);
+}
+
+bool ossimVpfAnnotationSource::isOpen()const
+{
+   return (theDatabase.isOpened());
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationSource.h
new file mode 100644
index 0000000000..b3631e8497
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfAnnotationSource.h
@@ -0,0 +1,45 @@
+#ifndef ossimVpfAnnotationSource_HEADER
+#define ossimVpfAnnotationSource_HEADER
+#include "vec/vpf/ossimVpfDatabase.h"
+#include "imaging/formats/ossimImageHandler.h"
+#include "base/data_types/ossimIrect.h"
+#include "imaging/annotation/ossimGeoAnnotationSource.h"
+#include "projections/ossimProjection.h"
+#include "ossimVpfAnnotationLibraryInfo.h"
+class ossimVpfAnnotationFeatureInfo;
+class ossimVpfAnnotationSource : public ossimGeoAnnotationSource
+{
+public:
+   ossimVpfAnnotationSource();
+   virtual ~ossimVpfAnnotationSource();
+   virtual bool open();
+   virtual bool open(const ossimFilename& file);
+   virtual bool isOpen()const;
+
+   virtual void close();
+   virtual ossimFilename getFilename()const;
+  virtual void computeBoundingRect();
+
+   virtual void transformObjects(ossimProjection* projection=0);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+
+   virtual void drawAnnotations(ossimRefPtr<ossimImageData> tile);
+   virtual void getAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& features);
+  virtual void setAllFeatures(const std::vector<ossimVpfAnnotationFeatureInfo*>& features);
+ 
+protected:
+   ossimVpfDatabase theDatabase;
+   ossimFilename    theFilename;
+   std::vector<ossimVpfAnnotationLibraryInfo*> theLibraryInfo;
+   std::vector<ossimVpfAnnotationFeatureInfo*> theFeatureList;
+
+  void deleteAllLibraries();
+  bool openDatabase(const ossimFilename& file);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfTileSource.cpp
new file mode 100644
index 0000000000..b4de266425
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfTileSource.cpp
@@ -0,0 +1,217 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2004 Garrett Potts, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description: 
+//
+// $Id: ossimVpfTileSource.cpp,v 1.9 2005/02/11 15:07:32 dburken Exp $
+//----------------------------------------------------------------------------
+#include "ossimVpfTileSource.h"
+
+RTTI_DEF2(ossimVpfTileSource, "ossimVpfTileSource", ossimImageHandler, ossimViewInterface);
+
+ossimVpfTileSource::ossimVpfTileSource()
+   :
+      ossimViewInterface()
+{
+   theObject = this;
+   theAnnotationSource = new ossimVpfAnnotationSource;
+   theAnnotationSource->setNumberOfBands(3);
+}
+
+ossimVpfTileSource::~ossimVpfTileSource()
+{
+   if(theAnnotationSource)
+   {
+      delete theAnnotationSource;
+      theAnnotationSource = NULL;
+   }
+}
+
+bool ossimVpfTileSource::saveState(ossimKeywordlist& kwl,
+				   const char* prefix)const
+{
+   return theAnnotationSource->saveState(kwl, prefix);
+}
+
+bool ossimVpfTileSource::loadState(const ossimKeywordlist& kwl,
+				   const char* prefix)
+{
+   return theAnnotationSource->loadState(kwl, prefix);
+}
+
+void ossimVpfTileSource::close()
+{
+   theAnnotationSource->close();
+}
+
+bool ossimVpfTileSource::open()
+{
+   return theAnnotationSource->open(theImageFile);
+}
+
+ossimRefPtr<ossimImageData> ossimVpfTileSource::getTile(
+   const ossimIrect& tileRect, ossim_uint32 resLevel)
+{
+   return theAnnotationSource->getTile(tileRect, resLevel);
+}
+
+ossim_uint32 ossimVpfTileSource::getNumberOfInputBands() const
+{
+   return theAnnotationSource->getNumberOfOutputBands();
+}
+
+ossim_uint32 ossimVpfTileSource::getNumberOfOutputBands() const
+{
+   return theAnnotationSource->getNumberOfOutputBands();
+}
+
+ossim_uint32 ossimVpfTileSource::getNumberOfLines(ossim_uint32 /* reduced_res_level */) const
+{
+   ossimIrect theBounds = theAnnotationSource->getBoundingRect();
+   
+   if(theBounds.hasNans())
+   {
+      return theBounds.ul().x;
+   }
+   
+   return theBounds.height();
+}
+
+ossim_uint32 ossimVpfTileSource::getNumberOfSamples(ossim_uint32 /* reduced_res_level */) const
+{
+   ossimIrect theBounds = theAnnotationSource->getBoundingRect();
+   
+   if(theBounds.hasNans())
+   {
+      return theBounds.ul().x;
+   }
+   
+   return theBounds.height();
+}
+
+ossim_uint32 ossimVpfTileSource::getNumberOfDecimationLevels() const
+{
+   return 32;
+}
+
+ossimIrect ossimVpfTileSource::getImageRectangle(ossim_uint32 /* reduced_res_level */) const
+{
+   return theAnnotationSource->getBoundingRect();
+}
+
+bool ossimVpfTileSource::getImageGeometry(ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   if (theGeometryKwl.getSize())
+   {
+      kwl = theGeometryKwl;
+      return true;
+   }
+   
+   ossimObject* view = theAnnotationSource->getView();
+   if(view)
+   {
+      bool result = view->saveState(kwl, prefix);
+      if (result)
+      {
+         // Capture for next time...
+         setImageGeometry(kwl);
+      }
+      return result;
+   }
+   
+   return false;
+}
+
+ossimScalarType ossimVpfTileSource::getOutputScalarType() const
+{
+   return theAnnotationSource->getOutputScalarType();
+}
+
+ossim_uint32 ossimVpfTileSource::getTileWidth() const
+{
+   return theAnnotationSource->getTileWidth();         
+}
+
+ossim_uint32 ossimVpfTileSource::getTileHeight() const
+{
+   return theAnnotationSource->getTileHeight();
+}
+
+ossim_uint32 ossimVpfTileSource::getImageTileWidth() const
+{
+   return 0;
+}
+
+ossim_uint32 ossimVpfTileSource::getImageTileHeight() const
+{
+   return 0;
+}
+
+bool ossimVpfTileSource::isOpen()const
+{
+   return theAnnotationSource->isOpen();
+}
+   
+double ossimVpfTileSource::getNullPixelValue(ossim_uint32 band)const
+{
+   return theAnnotationSource->getNullPixelValue(band);
+}
+
+double ossimVpfTileSource::getMinPixelValue(ossim_uint32 band)const
+{
+   return theAnnotationSource->getMinPixelValue(band);
+}
+      
+double ossimVpfTileSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   return theAnnotationSource->getMaxPixelValue(band);
+}
+
+ossimObject* ossimVpfTileSource::getView()
+{
+   return theAnnotationSource->getView();
+}
+
+const ossimObject* ossimVpfTileSource::getView()const
+{
+   return theAnnotationSource->getView();
+}
+   
+bool ossimVpfTileSource::setView(ossimObject*  baseObject,
+                                 bool ownsTheView)
+{
+   return theAnnotationSource->setView(baseObject, ownsTheView);
+}
+
+void ossimVpfTileSource::getAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& featureList)
+{
+   if(theAnnotationSource)
+   {
+      theAnnotationSource->getAllFeatures(featureList);
+   }
+}
+
+void ossimVpfTileSource::setAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& featureList)
+{
+   if(theAnnotationSource)
+   {
+      theAnnotationSource->setAllFeatures(featureList);
+   }
+}
+
+void ossimVpfTileSource::transformObjects()
+{
+   theAnnotationSource->transformObjects();
+}
+
+void ossimVpfTileSource::computeBoundingRect()
+{
+   theAnnotationSource->computeBoundingRect();
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfTileSource.h b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfTileSource.h
new file mode 100644
index 0000000000..73c283f0ac
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/formats/vpf/ossimVpfTileSource.h
@@ -0,0 +1,168 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2004 Garrett Potts, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// $Id: ossimVpfTileSource.h,v 1.12 2005/02/11 15:07:32 dburken Exp $
+//----------------------------------------------------------------------------
+#ifndef ossimVpfTileSource_HEADER
+#define ossimVpfTileSource_HEADER
+
+#include <imaging/formats/vpf/ossimVpfAnnotationSource.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <base/common/ossimViewInterface.h>
+
+
+class OSSIMDLLEXPORT ossimVpfTileSource : public ossimImageHandler,
+                                          public ossimViewInterface
+{
+public:
+   
+   ossimVpfTileSource();
+   virtual ~ossimVpfTileSource();
+
+   virtual void close();
+
+   /**
+    *  @return Returns true on success, false on error.
+    *
+    *  @note This method relies on the data member ossimImageData::theImageFile
+    *  being set.  Callers should do a "setFilename" prior to calling this
+    *  method or use the ossimImageHandler::open that takes a file name and an
+    *  entry index.
+    */   
+   virtual bool open();
+
+   /*!
+    *  Returns a pointer to a tile given an origin representing the upper
+    *  left corner of the tile to grab from the image.
+    *  Satisfies pure virtual from TileSource class.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+   /*!
+    *  Returns the number of bands in the image.
+    *  Satisfies pure virtual from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfInputBands() const;
+
+    /*!
+    * Returns the number of bands in a tile returned from this TileSource.
+    * Note: we are supporting sources that can have multiple data objects.
+    * If you want to know the scalar type of an object you can pass in the 
+    */
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+  
+   /*!
+    *  Returns the number of bands in the image.
+    *  Satisfies pure virtual from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
+
+   /*!
+    *  Returns the number of bands available from an image.
+    *  Satisfies pure virtual from ImageHandler class.
+    */
+   virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
+
+   /*!
+    * Returns the number of reduced resolution data sets (rrds).
+    * Note:  The full res image is counted as a data set so an image with no
+    *        reduced resolution data set will have a count of one.
+    */
+   virtual ossim_uint32 getNumberOfDecimationLevels() const;
+
+   /*!
+    * Returns the zero based image rectangle for the reduced resolution data
+    * set (rrds) passed in.  Note that rrds 0 is the highest resolution rrds.
+    */
+   virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level = 0) const;
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix);
+   
+   /*!
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection/model information to users.
+    *  Returns true if geometry info is present, false if not.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+
+   /*!
+    * Returns the output pixel type of the tile source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /*!
+    * Returns the width of the output tile.
+    */
+   virtual ossim_uint32 getTileWidth() const;
+   
+   /*!
+    * Returns the height of the output tile.
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   /*!
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileWidth() const;
+
+   /*!
+    * Returns the tile width of the image or 0 if the image is not tiled.
+    * Note: this is not the same as the ossimImageSource::getTileWidth which
+    * returns the output tile width which can be different than the internal
+    * image tile width on disk.
+    */
+   virtual ossim_uint32 getImageTileHeight() const;
+
+   virtual bool isOpen()const;
+   
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+      
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   virtual ossimObject* getView();
+
+   virtual const ossimObject* getView()const;
+   
+   virtual bool setView(ossimObject*  baseObject, bool ownsTheView = false);
+
+   void getAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& featureList);
+  
+   void setAllFeatures(std::vector<ossimVpfAnnotationFeatureInfo*>& featureList);
+
+   void transformObjects();
+
+   void computeBoundingRect();
+
+protected:
+   ossimVpfAnnotationSource* theAnnotationSource;
+   
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/histogram/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/histogram/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/histogram/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/histogram/ossimHistogramWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/histogram/ossimHistogramWriter.cpp
new file mode 100644
index 0000000000..91853d24c0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/histogram/ossimHistogramWriter.cpp
@@ -0,0 +1,154 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHistogramWriter.cpp,v 1.25 2005/09/02 18:02:25 gpotts Exp $
+#include <base/common/events/ossimProcessListener.h>
+#include <imaging/histogram/ossimHistogramWriter.h>
+#include <imaging/ossimImageSource.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <imaging/ossimImageSourceSequencer.h>
+#include <base/data_types/ossimMultiResLevelHistogram.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+
+class ossimHistogramWriterProcessListener : public ossimProcessListener
+{
+public:
+   ossimHistogramWriterProcessListener(ossimConnectableObject* passon)
+      :thePassonTo(passon)
+      {
+      }
+   virtual void processProgressEvent(ossimProcessProgressEvent& event)
+      {
+         if(thePassonTo)
+         {
+            event.setObject(thePassonTo);
+            thePassonTo->fireEvent(event);
+         }
+      }
+
+   ossimConnectableObject* thePassonTo;  
+   
+};
+
+RTTI_DEF3(ossimHistogramWriter,
+          "ossimHistogramWriter",
+          ossimOutputSource,
+          ossimProcessInterface,
+          ossimConnectableObjectListener);
+
+ossimHistogramWriter::ossimHistogramWriter(ossimImageSource* inputSource,
+                                           ossimObject* owner)
+   : ossimOutputSource(owner,
+                       1,
+                       0,
+                       true,
+                       false),
+     theFileStream(NULL)
+{
+   theProcessListener = new ossimHistogramWriterProcessListener(this);
+   
+   theAreaOfInterest.makeNan();
+   connectMyInputTo(0, inputSource);
+}
+
+ossimHistogramWriter::~ossimHistogramWriter()
+{
+   if(isOpen())
+   {
+      close();
+   }
+   if(theProcessListener)
+   {
+      delete theProcessListener;
+      theProcessListener = 0;
+   }
+   
+}
+
+bool ossimHistogramWriter::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix)const
+{
+   bool result = ossimOutputSource::saveState(kwl, prefix);
+
+
+   return result;
+}
+
+bool ossimHistogramWriter::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   bool result = ossimOutputSource::loadState(kwl, prefix);
+
+   if(result)
+   {
+      if(!getNumberOfInputs())
+      {
+         setNumberOfInputs(1);
+      }
+   }
+
+   return result;
+}
+
+bool ossimHistogramWriter::execute()
+{
+   writeHistogram();
+   
+   return true;
+}
+
+void ossimHistogramWriter::writeHistogram()
+{
+   if(!isOpen())
+   {
+      open();
+      if(!isOpen())
+      {
+          cerr << "unable to open file " << theFilename << endl;
+          return;
+       }
+    }
+    if(!getInput(0))
+    {
+       cerr << "ossimHistogramWriter::writeHistogram is not connected" << endl;
+       return;
+    }
+   ossimHistogramSource* histoSource = PTR_CAST(ossimHistogramSource, getInput(0));
+   bool deleteHistoSource = false;
+   if(!histoSource)
+   {
+     histoSource = new ossimImageHistogramSource;
+     histoSource->connectMyInputTo(0, getInput(0));
+     histoSource->enableSource();
+     deleteHistoSource = true;
+   }
+   
+   histoSource->addListener( theProcessListener);
+   
+   ossimMultiResLevelHistogram* histo = histoSource->getHistogram();
+
+   if(histo)
+   {
+      ossimKeywordlist kwl;
+      histo->saveState(kwl);
+
+      kwl.writeToStream(*theFileStream);
+   }
+   histoSource->removeListener(theProcessListener);
+   
+   if(deleteHistoSource)
+   {
+      delete histoSource;
+      histoSource = NULL;
+   }
+   
+   close();
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/histogram/ossimHistogramWriter.h b/Utilities/OSSIM/ossim_core/imaging/histogram/ossimHistogramWriter.h
new file mode 100644
index 0000000000..a92a42b437
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/histogram/ossimHistogramWriter.h
@@ -0,0 +1,178 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimHistogramWriter.h,v 1.28 2005/09/02 18:06:31 dburken Exp $
+#ifndef ossimHistogramWriter_HEADER
+#define ossimHistogramWriter_HEADER
+#include "base/common/ossimOutputSource.h"
+#include "base/data_types/ossimIrect.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/common/ossimProcessInterface.h"
+#include "base/common/events/ossimObjectEvents.h"
+#include "base/common/events/ossimProcessProgressEvent.h"
+#include "base/common/events/ossimProcessListener.h"
+#include "base/common/events/ossimConnectableObjectListener.h"
+#include "base/common/events/ossimConnectionEvent.h"
+#include "base/common/ossimHistogramSource.h"
+#include "imaging/histogram/ossimImageHistogramSource.h"
+
+#include "imaging/ossimImageSource.h"
+
+#include <fstream>
+
+class ossimImageSource;
+class ossimHistogramWriterProcessListener;
+
+class OSSIMDLLEXPORT ossimHistogramWriter : public ossimOutputSource,
+                                            public ossimProcessInterface,
+                                            public ossimConnectableObjectListener
+{
+public:
+   friend class ossimHistogramWriterProcessListener;
+   
+   ossimHistogramWriter(ossimImageSource* inputSource=NULL,
+                        ossimObject* owner=NULL);
+
+   virtual ~ossimHistogramWriter();
+   void setAreaOfInterest(const ossimIrect& rect)
+      {
+         theAreaOfInterest = rect;
+      }
+
+  virtual ossimObject* getObject()
+  {
+    return this;
+  }
+  virtual const ossimObject* getObject()const
+  {
+    return this;
+  }
+
+   virtual bool execute();
+   
+   virtual bool isOpen()const
+      {
+         return (theFileStream != NULL);
+         
+      }
+   /*!
+    * open the histogram file for output.  Note if the file was
+    * previously open then it will close it and re-opens the
+    * file.
+    */
+   virtual bool open()
+      {
+         if(isOpen())
+         {
+            close();
+         }
+         
+         theFileStream = new std::ofstream(theFilename.c_str());
+         
+         return theFileStream->good();
+      }
+
+   virtual bool open(const ossimFilename& filename)
+      {
+         return ossimOutputSource::open(filename);
+      }
+   virtual void close()
+      {
+         delete theFileStream;
+         theFileStream = NULL;
+      }
+
+   /*!
+    * Overrides the base class and maps the outputName to a filename.
+    */
+   virtual void setOutputName(const ossimString& outputName)
+      {
+	ossimOutputSource::setOutputName(outputName);
+	setFilename(outputName);
+      }
+   
+   virtual void setFilename(const ossimFilename& filename)
+      {
+         theFilename = filename;
+      }
+   
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const
+      {
+         return (object&&(inputIndex == 0)&& 
+                 (PTR_CAST(ossimHistogramSource, object)||
+		  PTR_CAST(ossimImageSourceInterface, object)));
+      }
+
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual void processProgressEvent(ossimProcessProgressEvent& event)
+      {
+         // we will raise the event if its coming from our
+         // input.  This means that we are connected to a
+         // ossimHistogramSource.
+         //
+	if(event.getObject() != this)
+         {
+	   ossimProcessInterface::setCurrentMessage(event.getMessage());
+            setPercentComplete(event.getPercentComplete());
+         }
+      }
+
+   virtual void connectInputEvent(ossimConnectionEvent& event)
+      {
+         if(event.getObject() == this)
+         {
+            if(event.getOldObject())
+            {
+               event.getOldObject()->removeListener((ossimProcessListener*)this);
+            }
+            if(getInput(0)&&
+	       PTR_CAST(ossimHistogramSource, getInput(0)))
+            {
+               getInput(0)->addListener( (ossimProcessListener*)this);
+            }
+         }
+      }
+
+   virtual void disconnectInputEvent(ossimConnectionEvent& event)
+      {
+         if(event.getOldObject()&&
+	    PTR_CAST(ossimHistogramSource, getInput(0)))
+         {
+            event.getOldObject()->removeListener((ossimProcessListener*)this);
+         }
+      }
+protected:
+   virtual void writeHistogram();
+   ossimIrect     theAreaOfInterest;
+   ossimFilename  theFilename;
+   std::ofstream*  theFileStream;
+   ossimHistogramWriterProcessListener* theProcessListener;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/histogram/ossimImageHistogramSource.cpp b/Utilities/OSSIM/ossim_core/imaging/histogram/ossimImageHistogramSource.cpp
new file mode 100644
index 0000000000..53be2adf49
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/histogram/ossimImageHistogramSource.cpp
@@ -0,0 +1,373 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageHistogramSource.cpp,v 1.21 2006/01/10 13:10:29 gpotts Exp $
+#include <imaging/histogram/ossimImageHistogramSource.h>
+#include <base/data_types/ossimMultiResLevelHistogram.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <imaging/ossimImageSourceSequencer.h>
+
+RTTI_DEF3(ossimImageHistogramSource, "ossimImageHistogramSource", ossimHistogramSource, ossimConnectableObjectListener, ossimProcessInterface);
+
+ossimImageHistogramSource::ossimImageHistogramSource(ossimObject* owner)
+   :ossimHistogramSource(owner,
+                         1,     // one input
+                         0,     // no outputs
+                         true,  // input list is fixed
+                         false),// output can still grow though
+    theHistogramRecomputeFlag(true),
+    theMaxNumberOfResLevels(1)
+{
+   theAreaOfInterest.makeNan();
+   addListener((ossimConnectableObjectListener*)this);
+   disableSource();
+
+   theMinValueOverride     = OSSIM_DBL_NAN;
+   theMaxValueOverride     = OSSIM_DBL_NAN;
+   theNumberOfBinsOverride = -1;
+}
+
+ossimImageHistogramSource::ossimImageHistogramSource(ossimObject* owner,
+                                                     ossim_uint32 numberOfInputs,
+                                                     ossim_uint32 numberOfOutputs,
+                                                     ossim_uint32 inputListFixedFlag,
+                                                     ossim_uint32 outputListFixedFlag)
+   :ossimHistogramSource(owner,
+                         numberOfInputs,
+                         numberOfOutputs,
+                         inputListFixedFlag,
+                         outputListFixedFlag),
+    theHistogramRecomputeFlag(true)
+{
+   theAreaOfInterest.makeNan();
+   addListener((ossimConnectableObjectListener*)this);
+   disableSource();
+}
+
+ossimImageHistogramSource::~ossimImageHistogramSource()
+{
+   removeListener((ossimConnectableObjectListener*)this);
+}
+
+ossimObject* ossimImageHistogramSource::getObject()
+{
+   return this;
+}
+
+const ossimObject* ossimImageHistogramSource::getObject()const
+{
+   return this;
+}
+
+void ossimImageHistogramSource::setAreaOfInterest(const ossimIrect& rect)
+{
+   if(rect != theAreaOfInterest)
+   {
+      theHistogramRecomputeFlag = true;
+   }
+   theAreaOfInterest = rect;
+}
+
+ossimIrect ossimImageHistogramSource::getAreaOfInterest()const
+{
+   return theAreaOfInterest;
+}
+
+void ossimImageHistogramSource::getAreaOfInterest(ossimIrect& rect)const
+{
+   rect = theAreaOfInterest;
+}
+
+ossim_uint32 ossimImageHistogramSource::getMaxNumberOfRLevels()const
+{
+   return theMaxNumberOfResLevels;
+}
+
+void ossimImageHistogramSource::setMaxNumberOfRLevels(ossim_uint32 number)
+{
+   if(number != theMaxNumberOfResLevels)
+   {
+      theHistogramRecomputeFlag = true;
+   }
+   theMaxNumberOfResLevels = number;
+}
+
+ossimMultiResLevelHistogram* ossimImageHistogramSource::getHistogram(const ossimIrect& rect)
+{
+   if((theAreaOfInterest != rect)||
+      (theAreaOfInterest.hasNans()))
+   {
+      theAreaOfInterest = rect;
+      theHistogramRecomputeFlag = true;
+   }
+
+   return getHistogram();
+}
+
+bool ossimImageHistogramSource::execute()
+{
+   if(!isSourceEnabled())
+   {
+      return theHistogram;
+   }
+   setProcessStatus(ossimProcessInterface::PROCESS_STATUS_EXECUTING);
+   if(theHistogramRecomputeFlag)
+   {
+      if(theAreaOfInterest.hasNans())
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface, getInput(0));
+         if(interface)
+         {
+            theAreaOfInterest = interface->getBoundingRect();
+         }
+      }
+      computeHistogram();
+      if(getProcessStatus() != ossimProcessInterface::PROCESS_STATUS_ABORTED)
+      {
+         theHistogramRecomputeFlag = false;
+         disableSource();
+      }
+   }
+   setProcessStatus(ossimProcessInterface::PROCESS_STATUS_NOT_EXECUTING);
+   
+   return true;
+}
+
+bool ossimImageHistogramSource::canConnectMyInputTo(ossim_int32 myInputIndex,
+                                                    const ossimConnectableObject* object)const
+{
+   return ((myInputIndex==0)&&PTR_CAST(ossimImageSourceInterface,
+                                       object));
+}
+
+void ossimImageHistogramSource::setNumberOfBinsOverride(ossim_int32 numberOfBinsOverride)
+{
+   theNumberOfBinsOverride = numberOfBinsOverride;
+}
+
+void ossimImageHistogramSource::setMinValueOverride(ossim_float32 minValueOverride)
+{
+   theMinValueOverride = minValueOverride;
+}
+void ossimImageHistogramSource::setMaxValueOverride(ossim_float32 maxValueOverride)
+{
+   theMaxValueOverride = maxValueOverride;
+}
+
+void ossimImageHistogramSource::propertyEvent(ossimPropertyEvent& /* event */)
+{
+   theHistogramRecomputeFlag = true;
+}
+
+void ossimImageHistogramSource::connectInputEvent(ossimConnectionEvent& /* event */)
+{
+   theHistogramRecomputeFlag = true;
+}
+
+ossimMultiResLevelHistogram* ossimImageHistogramSource::getHistogram()
+{
+  execute();
+  return theHistogram;
+}
+
+void ossimImageHistogramSource::computeHistogram()
+{
+   if(theHistogram)
+   {
+      delete theHistogram;
+      theHistogram = NULL;
+   }   
+   theHistogram = new ossimMultiResLevelHistogram;
+
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(!input)
+   {
+      setPercentComplete(100.0);
+      return;
+   }
+   
+   if(getInput(0))
+   {
+      // sum up all tiles needing processing.  We will use the sequncer.
+//      ossim_uint32 numberOfResLevels = input->getNumberOfDecimationLevels();
+      ossim_uint32 index = 0;
+      double tileCount   = 0.0;
+      double totalTiles  = 0.0;
+      ossim_uint32 numberOfBands = input->getNumberOfOutputBands();
+      ossim_uint32 numberOfBins  = 0;
+      float minValue     = 0;
+      float maxValue     = 0;
+      
+      ossimImageSourceSequencer* sequencer = new ossimImageSourceSequencer;
+      sequencer->connectMyInputTo(0, getInput(0));
+      sequencer->initialize();
+      
+      vector<ossimDpt> decimationFactors;
+      input->getDecimationFactors(decimationFactors);
+
+      if( decimationFactors.size() < theMaxNumberOfResLevels)
+      {
+         cerr << "Number Decimations is smaller than the request number of r-levels" << endl;
+         return;
+      }
+      theHistogram->create(theMaxNumberOfResLevels);//numberOfResLevels);
+      for(index = 0; index < theMaxNumberOfResLevels; ++index)
+      {
+         sequencer->setAreaOfInterest(theAreaOfInterest*decimationFactors[index]);
+         
+         totalTiles += sequencer->getNumberOfTiles();
+      }
+      
+      switch(input->getOutputScalarType())
+      {
+         case OSSIM_UINT8:
+         {
+            minValue     = 0;
+            maxValue     = OSSIM_DEFAULT_MAX_PIX_UCHAR;
+            numberOfBins = 256;
+            
+            break;
+         }
+         case OSSIM_USHORT11:
+         {
+            minValue     = 0;
+            maxValue     = OSSIM_DEFAULT_MAX_PIX_UINT11;
+            numberOfBins = OSSIM_DEFAULT_MAX_PIX_UINT11 + 1;
+            
+            break;
+         }
+         case OSSIM_UINT16:
+         case OSSIM_UINT32:
+         {
+            minValue     = 0;
+            maxValue     = OSSIM_DEFAULT_MAX_PIX_UINT16;
+            numberOfBins = OSSIM_DEFAULT_MAX_PIX_UINT16 + 1;
+            
+            break;
+         }
+         case OSSIM_SINT16:
+         case OSSIM_SINT32:
+         case OSSIM_FLOAT32:
+         case OSSIM_FLOAT64:
+         {
+            minValue     = OSSIM_DEFAULT_MIN_PIX_SINT16;
+            maxValue     = OSSIM_DEFAULT_MAX_PIX_SINT16;
+            numberOfBins = (OSSIM_DEFAULT_MAX_PIX_SINT16-OSSIM_DEFAULT_MIN_PIX_SINT16) + 1;
+            
+            break;
+         }
+         case OSSIM_NORMALIZED_FLOAT:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            minValue     = 0;
+            maxValue     = 1.0;
+            numberOfBins = OSSIM_DEFAULT_MAX_PIX_UINT16+1;
+            break;
+         }
+      default:
+      {
+         cerr << "Unsupported scalar type in ossimImageHistogramSource::computeHistogram()" << endl;
+         return;
+      }
+      }
+
+      if(theMinValueOverride != OSSIM_DBL_NAN)
+      {
+         minValue = (float)theMinValueOverride;
+      }
+      if(theMaxValueOverride != OSSIM_DBL_NAN)
+      {
+         maxValue = (float)theMaxValueOverride;
+      }
+      if(theNumberOfBinsOverride > 0)
+      {
+         numberOfBins = theNumberOfBinsOverride;
+      }
+      ossimProcessInterface::ossimProcessStatus processStatus = getProcessStatus();
+      if(numberOfBins > 0)
+      {
+	setPercentComplete(0.0);
+	for(index = 0;
+	    ((index < theMaxNumberOfResLevels)&&//numberOfResLevels)&&
+	     (processStatus != ossimProcessInterface::PROCESS_STATUS_ABORTED));
+	    ++index)
+         {
+            //sequencer->setAreaOfInterest(input->getBoundingRect(index));
+            sequencer->setAreaOfInterest(theAreaOfInterest*decimationFactors[index]);
+            
+            sequencer->setToStartOfSequence();
+            theHistogram->getMultiBandHistogram(index)->create(numberOfBands,
+                                                               numberOfBins,
+                                                               minValue,
+                                                               maxValue);
+            
+            processStatus = getProcessStatus();
+            if(processStatus!=ossimProcessInterface::PROCESS_STATUS_ABORTED)
+            {
+               ossimRefPtr<ossimImageData> data =
+                  sequencer->getNextTile(index);
+               ++tileCount;
+               setPercentComplete((100.0*(tileCount/totalTiles)));
+               processStatus = getProcessStatus();
+               long resLevelTotalTiles = sequencer->getNumberOfTiles();
+               long resLevelTileCount  = 1;
+               while((resLevelTileCount < resLevelTotalTiles)&&
+                     (processStatus!=ossimProcessInterface::PROCESS_STATUS_ABORTED))
+               {
+                  if(data.valid())
+                  {
+                     data->populateHistogram(theHistogram->getMultiBandHistogram(index));
+                  }
+                  data = sequencer->getNextTile(index);
+                  processStatus = getProcessStatus();
+                  ++tileCount;
+                  ++resLevelTileCount;
+                  setPercentComplete((100.0*(tileCount/totalTiles)));
+               }
+            }
+         }
+      }
+      delete sequencer;
+      sequencer = NULL;
+   }
+   //setPercentComplete(100);
+}
+
+bool ossimImageHistogramSource::loadState(const ossimKeywordlist& kwl,
+					  const char* prefix)
+{
+  ossimHistogramSource::loadState(kwl,
+				  prefix);  
+
+  ossimString newPrefix = ossimString(prefix) + "rect.";
+  theAreaOfInterest.loadState(kwl, newPrefix);
+  
+  if(getNumberOfInputs()!=1)
+    {
+      setNumberOfInputs(1);
+    }
+  theInputListIsFixedFlag = true;
+  theOutputListIsFixedFlag = false;
+  
+  return true;
+}
+
+bool ossimImageHistogramSource::saveState(ossimKeywordlist& kwl,
+					  const char* prefix)const
+{
+   bool result = ossimHistogramSource::saveState(kwl,
+                                                 prefix);
+   
+   if(result)
+   {
+      ossimString newPrefix = ossimString(prefix) + "rect.";
+      theAreaOfInterest.saveState(kwl, newPrefix);
+   }
+   
+  return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/histogram/ossimImageHistogramSource.h b/Utilities/OSSIM/ossim_core/imaging/histogram/ossimImageHistogramSource.h
new file mode 100644
index 0000000000..4ae355a86b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/histogram/ossimImageHistogramSource.h
@@ -0,0 +1,101 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageHistogramSource.h,v 1.16 2005/11/27 17:07:12 dburken Exp $
+#ifndef ossimImageHistogramSource_HEADER
+#define ossimImageHistogramSource_HEADER
+#include <base/common/ossimHistogramSource.h>
+#include <imaging/ossimImageSourceInterface.h>
+#include <base/common/ossimProcessInterface.h>
+#include <base/common/events/ossimConnectableObjectListener.h>
+#include <base/common/events/ossimObjectEvents.h>
+#include <base/data_types/ossimIrect.h>
+
+/*!
+ * This source expects as input an ossimImageSourceInterface.
+ * it will slice up the requested region into tiles and compute
+ * the histogram of the passed in rectangle.
+ */
+class OSSIMDLLEXPORT ossimImageHistogramSource : public ossimHistogramSource,
+                                                 public ossimConnectableObjectListener,
+                                                 public ossimProcessInterface
+{
+public:
+   ossimImageHistogramSource(ossimObject* owner = NULL);
+   ossimImageHistogramSource(ossimObject* owner,
+                             ossim_uint32 numberOfInputs,
+                             ossim_uint32 numberOfOutputs,
+                             ossim_uint32 inputListFixedFlag,
+                             ossim_uint32 outputListFixedFlag);
+   virtual ~ossimImageHistogramSource();
+
+   virtual ossimObject* getObject();
+   virtual const ossimObject* getObject()const;
+
+   void setAreaOfInterest(const ossimIrect& rect);
+
+   ossimIrect getAreaOfInterest()const;
+
+   void getAreaOfInterest(ossimIrect& rect)const;
+
+   virtual ossim_uint32 getMaxNumberOfRLevels()const;
+
+   virtual void setMaxNumberOfRLevels(ossim_uint32 number);
+
+   /*!
+    * The first argument is the region of interest that you wish to
+    * use for the histogram.  If the region is different than
+    * what it has already computed before then the histogram is considered
+    * dirty and will be re-computed.  The returned object is a
+    * multi-reslevel histogram
+    */
+   virtual ossimMultiResLevelHistogram* getHistogram(const ossimIrect& rect);
+
+   virtual ossimMultiResLevelHistogram* getHistogram();
+   virtual bool execute();
+   
+   virtual bool canConnectMyInputTo(ossim_int32 myInputIndex,
+                                    const ossimConnectableObject* object)const;
+
+   void setNumberOfBinsOverride(ossim_int32 numberOfBinsOverride);
+
+   void setMinValueOverride(ossim_float32 minValueOverride);
+
+   void setMaxValueOverride(ossim_float32 maxValueOverride);
+
+   virtual void propertyEvent(ossimPropertyEvent& event);
+   
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+protected:
+   virtual void computeHistogram();
+   
+   /*!
+    * Initialized to ossimNAN'S
+    */
+   ossimIrect theAreaOfInterest;
+   bool       theHistogramRecomputeFlag;
+
+   /*!
+    * Will default to 1.  This means it will use up to max
+    * number of res levels for the histogram.
+    */
+   ossim_uint32     theMaxNumberOfResLevels;
+
+   ossim_float64    theMinValueOverride;
+   ossim_float64    theMaxValueOverride;
+   ossim_int32      theNumberOfBinsOverride;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/metadata/.cvsignore
new file mode 100644
index 0000000000..7df3918588
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+Makefile
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimEnviHeaderFileWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimEnviHeaderFileWriter.cpp
new file mode 100644
index 0000000000..60cacc25a5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimEnviHeaderFileWriter.cpp
@@ -0,0 +1,107 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Class definition for ossimEnviHeaderFileWriter.  Meta data class for
+// writing an ENVI (The Environment for Visualizing Images) header file.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimEnviHeaderFileWriter.cpp,v 1.6 2005/08/08 22:00:24 dburken Exp $
+
+#include <imaging/metadata/ossimEnviHeaderFileWriter.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimIrect.h>
+#include <imaging/ossimImageSourceInterface.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+
+
+RTTI_DEF1(ossimEnviHeaderFileWriter,
+          "ossimEnviHeaderFileWriter",
+          ossimMetadataFileWriter)
+
+ossimEnviHeaderFileWriter::ossimEnviHeaderFileWriter()
+   :
+   ossimMetadataFileWriter(),
+   theHdr()
+{
+}
+
+ossimEnviHeaderFileWriter::~ossimEnviHeaderFileWriter()
+{
+}
+
+bool ossimEnviHeaderFileWriter::loadState(const ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   bool result = false;
+   
+   if (ossimMetadataFileWriter::loadState(kwl, prefix))
+   {
+      result = theHdr.loadState(kwl, prefix);
+   }
+   
+   return result;
+}
+
+bool writeFile()
+{
+   bool result = true;
+
+   return result;
+}
+
+bool ossimEnviHeaderFileWriter::writeFile()
+{
+   theHdr.setLines(theAreaOfInterest.height());
+   theHdr.setSamples(theAreaOfInterest.width());
+   theHdr.setBands(theInputConnection->getNumberOfOutputBands());
+   
+   // Get the geometry from the input.
+   ossimKeywordlist kwl;
+   theInputConnection->getImageGeometry(kwl);
+
+   // Create the projection.
+   ossimMapProjection* mapProj =  NULL;
+   ossimRefPtr<ossimProjection> proj =
+      ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+   if (proj.valid())
+   {
+      mapProj = PTR_CAST(ossimMapProjection, proj.get());
+
+      if (mapProj)
+      {
+         // Create the projection info.
+         ossimRefPtr<ossimMapProjectionInfo> projectionInfo
+            = new ossimMapProjectionInfo(mapProj, theAreaOfInterest);
+         
+         // Set the tie points in the keyword list.
+         projectionInfo->getGeom(kwl);
+         
+         // Pass it on to envi header to set the map info string from geometry.
+         theHdr.setMapInfo(kwl);
+      }
+   }
+
+   return theHdr.writeFile(theFilename);
+}
+
+void ossimEnviHeaderFileWriter::getMetadatatypeList(
+   std::vector<ossimString>& metadatatypeList) const
+{
+   metadatatypeList.push_back(ossimString("envi_header")); 
+}
+
+bool ossimEnviHeaderFileWriter::hasMetadataType(
+   const ossimString& metadataType)const
+{
+   return (metadataType == "envi_header");
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimEnviHeaderFileWriter.h b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimEnviHeaderFileWriter.h
new file mode 100644
index 0000000000..fdb66523f7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimEnviHeaderFileWriter.h
@@ -0,0 +1,77 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Class declaration for ossimEnviHeaderFileWriter.  Meta data class for
+// writing an ENVI (The Environment for Visualizing Images) header file.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimEnviHeaderFileWriter.h,v 1.4 2005/08/08 22:00:24 dburken Exp $
+
+#ifndef ossimEnviHeaderFileWriter_H
+#define ossimEnviHeaderFileWriter_H
+
+#include <fstream>
+#include <imaging/metadata/ossimMetadataFileWriter.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <support_data/envi/ossimEnviHeader.h>
+
+/**
+ * Class for writing a "ENVI" style header.
+ */
+class OSSIMDLLEXPORT ossimEnviHeaderFileWriter : public ossimMetadataFileWriter
+{
+public:
+
+   /** default constructor */
+   ossimEnviHeaderFileWriter();
+
+   /** virtual destructor */
+   virtual ~ossimEnviHeaderFileWriter();
+
+   /**
+    * Initializes the state of the writer.  Users should use this to set
+    * the envi header fields that are not taken from theInputConnection prior
+    * to calling execute.
+    *
+    * @return true on success, false on failure.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix = 0);
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * Appends the writers image types to the "metadatatypeList".
+    * 
+    * @param metadatatypeList stl::vector<ossimString> list to append to.
+    *
+    * @note Appends to the list, does not clear it first.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList) const;
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * @param imageType string representing image type.
+    *
+    * @return true if "metadataType" is supported by writer.
+    */
+   virtual bool hasMetadataType(const ossimString& metadataType)const;   
+   
+private:
+   
+   virtual bool writeFile();
+
+   ossimEnviHeader theHdr;
+   
+TYPE_DATA
+};
+#endif /* End of #ifndef ossimEnviHeaderFileWriter_H */
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimFgdcFileWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimFgdcFileWriter.cpp
new file mode 100644
index 0000000000..404a15ecd8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimFgdcFileWriter.cpp
@@ -0,0 +1,972 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description: Class to write out meta data in a Federal Geographic Data
+// Committe (FGDC) format.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimFgdcFileWriter.cpp,v 1.1 2005/08/09 19:08:32 dburken Exp $
+
+#include <fstream>
+using namespace std;
+
+#include <imaging/metadata/ossimFgdcFileWriter.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimXmlNode.h>
+#include <imaging/ossimImageSourceInterface.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+
+RTTI_DEF1(ossimFgdcFileWriter, "ossimFgdcFileWriter", ossimMetadataFileWriter)
+
+static ossimTrace traceDebug("ossimFgdcFileWriter:debug");
+
+   
+ossimFgdcFileWriter::ossimFgdcFileWriter()
+   :
+   theIndentionLevel(0),
+   theTabString("\t"),
+   theTemplate(),
+   theSourceImageFilename()
+{
+}
+
+ossimFgdcFileWriter::~ossimFgdcFileWriter()
+{
+}
+
+bool ossimFgdcFileWriter::writeFile()
+{
+   if(theFilename == ossimFilename::NIL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimFgdcFileWriter::writeFile no filename set!" << endl;
+      return false;
+   }
+   
+   if( !theInputConnection )
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimFgdcFileWriter::writeFile no input connection!" << endl;
+      return false;
+   }
+
+   ofstream os(theFilename.c_str());
+   if (!os)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimFgdcFileWriter::writeFile no input connection!" << endl;
+      return false;
+   }
+
+   // Get the geometry from the input.
+   ossimKeywordlist kwl;
+   theInputConnection->getImageGeometry(kwl);
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimFgdcFileWriter::writeFile debug:\n"
+         << "Geometry file:  " << kwl << endl;
+   }
+   
+   // Create the projection.
+   ossimRefPtr<ossimProjection> proj =
+      ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+   if (!proj.valid())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimFgdcFileWriter::writeFile Could not create projection."
+         << endl;
+      return false;
+   }
+   
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj.get());
+   if (!mapProj)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimFgdcFileWriter::writeFile Not map projected."
+         << endl;
+      return false;
+   }
+
+   ossimMapProjectionInfo mpi(mapProj, theInputConnection->getBoundingRect());
+
+   
+
+   os << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
+      << "<?xml-stylesheet type=\"text/xsl\" href=\"/common/fgdc_classic.xsl\" ?>\n";
+   openTag(os, ossimString("metadata"),  true);
+   openTag(os, ossimString("idinfo"),    true);
+   openTag(os, ossimString("citation"),  true);
+   openTag(os, ossimString("citeinfo"),  true);
+   
+   openTag(os, ossimString("origin"),    false);
+   os << find(ossimString("/metadata/idinfo/citation/citeinfo/origin"));
+   closeTag(os, ossimString("origin"),   false);
+   
+   openTag(os, ossimString("pubdate"),    false);
+   os << find(ossimString("/metadata/idinfo/citation/citeinfo/pubdate"));
+   closeTag(os, ossimString("pubdate"),   false);
+
+   openTag(os, ossimString("title"),    false);
+   // os << find(ossimString("/metadata/idinfo/citation/citeinfo/title"));
+   os << theSourceImageFilename.c_str();
+   closeTag(os, ossimString("title"),   false);
+
+   openTag(os, ossimString("edition"),    false);
+   os << find(ossimString("/metadata/idinfo/citation/citeinfo/edition"));
+   closeTag(os, ossimString("edition"),   false);
+
+   openTag(os, ossimString("geoform"),    false);
+   os << find(ossimString("/metadata/idinfo/citation/citeinfo/geoform"));
+   closeTag(os, ossimString("geoform"),   false);
+
+   openTag(os, ossimString("serinfo"),  true);
+   openTag(os, ossimString("sername"),    false);
+   os << find(ossimString("/metadata/idinfo/citation/citeinfo/serinfo/sername"));
+   closeTag(os, ossimString("sername"),   false);
+
+   openTag(os, ossimString("issue"),    false);
+   os << theSourceImageFilename.c_str();
+   closeTag(os, ossimString("issue"),   false);
+
+   closeTag(os, ossimString("serinfo"),  true);
+
+   openTag(os, ossimString("pubinfo"),  true);
+
+   openTag(os, ossimString("pubplace"),    false);
+   os << find(ossimString("/metadata/idinfo/citation/citeinfo/pubinfo/pubplace"));
+   closeTag(os, ossimString("pubplace"),   false);
+
+   openTag(os, ossimString("publish"),    false);
+   os << find(ossimString("/metadata/idinfo/citation/citeinfo/pubinfo/publish"));
+   closeTag(os, ossimString("publish"),   false);
+
+   closeTag(os, ossimString("pubinfo"),  true);
+   closeTag(os, ossimString("citeinfo"),  true);
+   closeTag(os, ossimString("citation"),  true);
+
+   openTag(os, ossimString("descript"),  true);
+
+   openTag(os, ossimString("abstract"),    false);
+   os << find(ossimString("/metadata/idinfo/descript/abstract"));
+   closeTag(os, ossimString("abstract"),   false);
+
+   openTag(os, ossimString("purpose"),    false);
+   os << find(ossimString("/metadata/idinfo/descript/purpose"));
+   closeTag(os, ossimString("purpose"),   false);
+
+   openTag(os, ossimString("supplinf"),    false);
+   os << find(ossimString("/metadata/idinfo/descript/supplinf"));
+   closeTag(os, ossimString("supplinf"),   false);
+
+   closeTag(os, ossimString("descript"),  true);
+
+   openTag(os, ossimString("timeperd"),  true);
+   openTag(os, ossimString("timeinfo"),  true);
+   openTag(os, ossimString("sngdate"),  true);
+
+   openTag(os, ossimString("caldate"),    false);
+   os << find(ossimString("/metadata/idinfo/timeperd/timeinfo/sngdate/caldate"));
+   closeTag(os, ossimString("caldate"),   false);
+   
+   closeTag(os, ossimString("sngdate"),  true);
+   closeTag(os, ossimString("timeinfo"),  true);
+
+   
+   openTag(os, ossimString("current"),    false);
+   os << find(ossimString("/metadata/idinfo/timeperd/current"));
+   closeTag(os, ossimString("current"),   false);
+
+   closeTag(os, ossimString("timeperd"),  true);
+
+   openTag(os, ossimString("status"),  true);
+
+   openTag(os, ossimString("progress"),    false);
+   os << find(ossimString("/metadata/idinfo/status/progress"));
+   closeTag(os, ossimString("progress"),   false);
+
+   openTag(os, ossimString("update"),    false);
+   os << find(ossimString("/metadata/idinfo/status/update"));
+   closeTag(os, ossimString("update"),   false);
+
+   closeTag(os, ossimString("status"),  true);
+
+   openTag(os, ossimString("spdom"),  true);
+   openTag(os, ossimString("bounding"),  true);
+
+   if (mapProj->isGeographic())
+   {
+      openTag(os, ossimString("westbc"),    false);
+      os << ossimString::toString(mpi.ulGroundPt().lon);
+      closeTag(os, ossimString("westbc"),   false);
+      
+      openTag(os, ossimString("eastbc"),    false);
+      os << ossimString::toString(mpi.lrGroundPt().lon);
+      closeTag(os, ossimString("eastbc"),   false);
+      
+      openTag(os, ossimString("northbc"),    false);
+      os << ossimString::toString(mpi.ulGroundPt().lat);
+      closeTag(os, ossimString("northbc"),   false);
+      
+      openTag(os, ossimString("southbc"),    false);
+      os << ossimString::toString(mpi.lrGroundPt().lat);
+      closeTag(os, ossimString("southbc"),   false);
+   }
+   else
+   {
+      openTag(os, ossimString("westbc"),    false);
+      os << ossimString::toString(mpi.ulEastingNorthingPt().x);
+      closeTag(os, ossimString("westbc"),   false);
+      
+      openTag(os, ossimString("eastbc"),    false);
+      os << ossimString::toString(mpi.lrEastingNorthingPt().x);
+      closeTag(os, ossimString("eastbc"),   false);
+      
+      openTag(os, ossimString("northbc"),    false);
+      os << ossimString::toString(mpi.ulEastingNorthingPt().y);
+      closeTag(os, ossimString("northbc"),   false);
+      
+      openTag(os, ossimString("southbc"),    false);
+      os << ossimString::toString(mpi.ulEastingNorthingPt().y);
+      closeTag(os, ossimString("southbc"),   false);
+   }
+   
+   closeTag(os, ossimString("bounding"),  true);
+   closeTag(os, ossimString("spdom"),    true);
+
+   openTag(os, ossimString("keywords"), true);
+
+   openTag(os, ossimString("theme"), true);
+
+   openTag(os, ossimString("themekt"), false);
+   os << find(ossimString("/metadata/idinfo/keywords/theme/themekt"));
+   closeTag(os, ossimString("themekt"), false);
+
+   openTag(os, ossimString("themekey"), false);
+   os << find(ossimString("/metadata/idinfo/keywords/theme/themekey"));
+   closeTag(os, ossimString("themekey"), false);
+   
+   closeTag(os, ossimString("theme"), true);
+
+   closeTag(os, ossimString("keywords"), true);
+
+   openTag(os, ossimString("accconst"), false);
+   os << find(ossimString("/metadata/idinfo/accconst"));
+   closeTag(os, ossimString("accconst"), false);
+
+   openTag(os, ossimString("useconst"), false);
+   os << find(ossimString("/metadata/idinfo/useconst"));
+   closeTag(os, ossimString("useconst"), false);
+
+   openTag(os, ossimString("ptcontac"), true);
+   
+   openTag(os, ossimString("cntinfo"), true);
+   
+   openTag(os, ossimString("cntperp"), true);
+   openTag(os, ossimString("cntper"), false);
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntperp/cntper"));
+   closeTag(os, ossimString("cntper"), false);
+   closeTag(os, ossimString("cntperp"), true);
+
+   openTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("addrtype"), false);
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntaddr/addrtype"));
+   closeTag(os, ossimString("addrtype"), false);
+
+   openTag(os, ossimString("address"), false);
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntaddr/address"));
+   closeTag(os, ossimString("address"), false);
+
+   openTag(os, ossimString("city"), false);
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntaddr/city"));
+   closeTag(os, ossimString("city"), false);
+
+   openTag(os, ossimString("state"), false);
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntaddr/state"));
+   closeTag(os, ossimString("state"), false);
+
+   openTag(os, ossimString("postal"), false);
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntaddr/postal"));
+   closeTag(os, ossimString("postal"), false);
+
+   openTag(os, ossimString("country"), false);
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntaddr/country"));
+   closeTag(os, ossimString("country"), false);
+
+   closeTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("cntvoice"), false);
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntvoice"));
+   closeTag(os, ossimString("cntvoice"), false);
+  
+   openTag(os, ossimString("cntfax"), false);
+
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntfax"));
+   closeTag(os, ossimString("cntfax"), false);
+  
+   openTag(os, ossimString("cntemail"), false);
+   os << find(ossimString("/metadata/idinfo/ptcontac/cntinfo/cntemail"));
+   closeTag(os, ossimString("cntemail"), false);
+   
+   closeTag(os, ossimString("cntinfo"), true);
+   closeTag(os, ossimString("ptcontac"), true);
+
+   openTag(os, ossimString("secinfo"), true);
+
+   openTag(os, ossimString("secclass"), false);
+   os << find(ossimString("/metadata/idinfo/secinfo/secclass"));
+   closeTag(os, ossimString("secclass"), false);
+
+   openTag(os, ossimString("secsys"), false);
+   os << find(ossimString("/metadata/idinfo/secinfo/secsys"));
+   closeTag(os, ossimString("secsys"), false);
+
+   openTag(os, ossimString("sechandl"), false);
+   os << find(ossimString("/metadata/idinfo/secinfo/sechandl"));
+   closeTag(os, ossimString("sechandl"), false);
+
+   closeTag(os, ossimString("secinfo"), true);
+   closeTag(os, ossimString("idinfo"), true);
+   
+   openTag(os, ossimString("distinfo"), true);
+   openTag(os, ossimString("distrib"), true);
+   openTag(os, ossimString("cntinfo"), true);
+   openTag(os, ossimString("cntperp"), true);
+   openTag(os, ossimString("cntper"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntperp/cntper"));
+
+   closeTag(os, ossimString("cntper"), false);
+   closeTag(os, ossimString("cntperp"), true);
+
+   openTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("addrtype"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntaddr/addrtype"));
+   closeTag(os, ossimString("addrtype"), false);
+
+   openTag(os, ossimString("address"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntaddr/address"));
+   closeTag(os, ossimString("address"), false);
+
+   openTag(os, ossimString("city"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntaddr/city"));
+   closeTag(os, ossimString("city"), false);
+
+   openTag(os, ossimString("state"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntaddr/state"));
+   closeTag(os, ossimString("state"), false);
+
+   openTag(os, ossimString("postal"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntaddr/postal"));
+   closeTag(os, ossimString("postal"), false);
+
+   openTag(os, ossimString("country"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntaddr/country"));
+   closeTag(os, ossimString("country"), false);
+
+   closeTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("cntvoice"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntvoice"));
+   closeTag(os, ossimString("cntvoice"), false);
+  
+   openTag(os, ossimString("cntfax"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntfax"));
+   closeTag(os, ossimString("cntfax"), false);
+  
+   openTag(os, ossimString("cntemail"), false);
+   os << find(ossimString("/metadata/distinfo/distrib/cntinfo/cntemail"));
+   closeTag(os, ossimString("cntemail"), false);
+   
+   closeTag(os, ossimString("cntinfo"), true);
+   closeTag(os, ossimString("distrib"), true);
+
+   openTag(os, ossimString("resdesc"), false);
+   os << find(ossimString("/metadata/distinfo/resdesc"));
+   closeTag(os, ossimString("resdesc"), false);
+
+   openTag(os, ossimString("distliab"), false);
+   os << find(ossimString("/metadata/distinfo/distliab"));
+   closeTag(os, ossimString("distliab"), false);
+
+   openTag(os, ossimString("stdorder"), true);
+   openTag(os, ossimString("digform"), true);
+   openTag(os, ossimString("digtinfo"), true);
+   
+   openTag(os, ossimString("formname"), false);
+   os << find(ossimString("/metadata/distinfo/stdorder/digform/digtinfo/formname"));
+   closeTag(os, ossimString("formname"), false);
+
+   closeTag(os, ossimString("digtinfo"), true);
+
+   openTag(os, ossimString("digtopt"), true);
+   openTag(os, ossimString("onlinopt"), true);   
+   openTag(os, ossimString("computer"), true);
+   openTag(os, ossimString("networka"), true);
+
+   openTag(os, ossimString("networkr"), false);
+   os << find(ossimString("/metadata/distinfo/stdorder/digform/digtopt/onlinopt/computer/networka/networkr"));
+   closeTag(os, ossimString("networkr"), false);
+
+   closeTag(os, ossimString("networka"), true);
+   closeTag(os, ossimString("computer"), true);
+   closeTag(os, ossimString("onlinopt"), true);
+   closeTag(os, ossimString("digtopt"), true);
+   closeTag(os, ossimString("digform"), true);
+
+   openTag(os, ossimString("fees"), false);
+   os << find(ossimString("/metadata/distinfo/stdorder/fees"));
+   closeTag(os, ossimString("fees"), false);
+
+   closeTag(os, ossimString("stdorder"), true);
+   closeTag(os, ossimString("distinfo"), true);
+
+   openTag(os, ossimString("metainfo"), true);
+
+   openTag(os, ossimString("metd"), false);
+   os << find(ossimString("/metadata/metainfo/metd"));
+   closeTag(os, ossimString("metd"), false);
+
+   openTag(os, ossimString("metc"), true);
+   openTag(os, ossimString("cntinfo"), true);
+   openTag(os, ossimString("cntperp"), true);
+   
+   openTag(os, ossimString("cntper"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntperp/cntper"));
+   closeTag(os, ossimString("cntper"), false);
+
+   closeTag(os, ossimString("cntperp"), true);
+   
+   openTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("addrtype"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntaddr/addrtype"));
+   closeTag(os, ossimString("addrtype"), false);
+
+   openTag(os, ossimString("address"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntaddr/address"));
+   closeTag(os, ossimString("address"), false);
+
+   openTag(os, ossimString("city"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntaddr/city"));
+   closeTag(os, ossimString("city"), false);
+
+   openTag(os, ossimString("state"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntaddr/state"));
+   closeTag(os, ossimString("state"), false);
+
+   openTag(os, ossimString("postal"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntaddr/postal"));
+   closeTag(os, ossimString("postal"), false);
+
+   openTag(os, ossimString("country"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntaddr/country"));
+   closeTag(os, ossimString("country"), false);
+
+   closeTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("cntvoice"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntvoice"));
+   closeTag(os, ossimString("cntvoice"), false);
+  
+   openTag(os, ossimString("cntfax"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntfax"));
+   closeTag(os, ossimString("cntfax"), false);
+  
+   openTag(os, ossimString("cntemail"), false);
+   os << find(ossimString("/metadata/metainfo/metc/cntinfo/cntemail"));
+   closeTag(os, ossimString("cntemail"), false);
+   
+   closeTag(os, ossimString("cntinfo"), true);
+   closeTag(os, ossimString("metc"), true);
+
+   openTag(os, ossimString("metstdn"), false);
+   os << find(ossimString("/metadata/metainfo/metstdn"));
+   closeTag(os, ossimString("metstdn"), false);
+
+   openTag(os, ossimString("metstdv"), false);
+   os << find(ossimString("/metadata/metainfo/metstdv"));
+   closeTag(os, ossimString("metstdv"), false);
+
+   closeTag(os, ossimString("metainfo"), true);
+   closeTag(os, ossimString("metadata"), true);
+
+   os.close();
+
+   return true;
+}
+
+bool ossimFgdcFileWriter::writeTemplate(const ossimFilename& file) const
+{
+   ofstream os(file.c_str());
+   if (!os)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimFgdcFileWriter::writeTemplate Could not open: " << file
+         << endl;
+      return false;
+   }
+
+   os << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
+      << "<?xml-stylesheet type=\"text/xsl\" href=\"/common/fgdc_classic.xsl\" ?>\n";
+   openTag(os, ossimString("metadata"),  true);
+   openTag(os, ossimString("idinfo"),    true);
+   openTag(os, ossimString("citation"),  true);
+   openTag(os, ossimString("citeinfo"),  true);
+   
+   openTag(os, ossimString("origin"),    false);
+   closeTag(os, ossimString("origin"),   false);
+   
+   openTag(os, ossimString("pubdate"),    false);
+   closeTag(os, ossimString("pubdate"),   false);
+
+   openTag(os, ossimString("title"),    false);
+   closeTag(os, ossimString("title"),   false);
+
+   openTag(os, ossimString("edition"),    false);
+   closeTag(os, ossimString("edition"),   false);
+
+   openTag(os, ossimString("geoform"),    false);
+   closeTag(os, ossimString("geoform"),   false);
+
+   openTag(os, ossimString("serinfo"),  true);
+   openTag(os, ossimString("sername"),    false);
+
+   closeTag(os, ossimString("sername"),   false);
+
+   openTag(os, ossimString("issue"),    false);
+   closeTag(os, ossimString("issue"),   false);
+
+   closeTag(os, ossimString("serinfo"),  true);
+
+   openTag(os, ossimString("pubinfo"),  true);
+
+   openTag(os, ossimString("pubplace"),    false);
+
+   closeTag(os, ossimString("pubplace"),   false);
+
+   openTag(os, ossimString("publish"),    false);
+   closeTag(os, ossimString("publish"),   false);
+
+   closeTag(os, ossimString("pubinfo"),  true);
+   closeTag(os, ossimString("citeinfo"),  true);
+   closeTag(os, ossimString("citation"),  true);
+
+   openTag(os, ossimString("descript"),  true);
+
+   openTag(os, ossimString("abstract"),    false);
+   closeTag(os, ossimString("abstract"),   false);
+
+   openTag(os, ossimString("purpose"),    false);
+   closeTag(os, ossimString("purpose"),   false);
+
+   openTag(os, ossimString("supplinf"),    false);
+   closeTag(os, ossimString("supplinf"),   false);
+
+   closeTag(os, ossimString("descript"),  true);
+
+   openTag(os, ossimString("timeperd"),  true);
+   openTag(os, ossimString("timeinfo"),  true);
+   openTag(os, ossimString("sngdate"),  true);
+
+   openTag(os, ossimString("caldate"),    false);
+   closeTag(os, ossimString("caldate"),   false);
+   
+   closeTag(os, ossimString("sngdate"),  true);
+   closeTag(os, ossimString("timeinfo"),  true);
+
+   
+   openTag(os, ossimString("current"),    false);
+   closeTag(os, ossimString("current"),   false);
+
+   closeTag(os, ossimString("timeperd"),  true);
+
+   openTag(os, ossimString("status"),  true);
+
+   openTag(os, ossimString("progress"),    false);
+   closeTag(os, ossimString("progress"),   false);
+
+   openTag(os, ossimString("update"),    false);
+   closeTag(os, ossimString("update"),   false);
+
+   closeTag(os, ossimString("status"),  true);
+
+   openTag(os, ossimString("spdom"),  true);
+   openTag(os, ossimString("bounding"),  true);
+
+   openTag(os, ossimString("westbc"),    false);
+   closeTag(os, ossimString("westbc"),   false);
+   openTag(os, ossimString("eastbc"),    false);
+
+   closeTag(os, ossimString("eastbc"),   false);
+   openTag(os, ossimString("northbc"),    false);
+
+   closeTag(os, ossimString("northbc"),   false);
+   openTag(os, ossimString("southbc"),    false);
+
+   closeTag(os, ossimString("southbc"),   false);
+
+   closeTag(os, ossimString("bounding"),  true);
+   closeTag(os, ossimString("spdom"),    true);
+
+   openTag(os, ossimString("keywords"), true);
+
+   openTag(os, ossimString("theme"), true);
+
+   openTag(os, ossimString("themekt"), false);
+   closeTag(os, ossimString("themekt"), false);
+
+   openTag(os, ossimString("themekey"), false);
+   closeTag(os, ossimString("themekey"), false);
+   
+   closeTag(os, ossimString("theme"), true);
+
+   closeTag(os, ossimString("keywords"), true);
+
+   openTag(os, ossimString("accconst"), false);
+   closeTag(os, ossimString("accconst"), false);
+
+   openTag(os, ossimString("useconst"), false);
+   closeTag(os, ossimString("useconst"), false);
+
+   openTag(os, ossimString("ptcontac"), true);
+   
+   openTag(os, ossimString("cntinfo"), true);
+   
+   openTag(os, ossimString("cntperp"), true);
+   openTag(os, ossimString("cntper"), false);
+   closeTag(os, ossimString("cntper"), false);
+   closeTag(os, ossimString("cntperp"), true);
+
+   openTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("addrtype"), false);
+   closeTag(os, ossimString("addrtype"), false);
+
+   openTag(os, ossimString("address"), false);
+   closeTag(os, ossimString("address"), false);
+
+   openTag(os, ossimString("city"), false);
+   closeTag(os, ossimString("city"), false);
+
+   openTag(os, ossimString("state"), false);
+   closeTag(os, ossimString("state"), false);
+
+   openTag(os, ossimString("postal"), false);
+   closeTag(os, ossimString("postal"), false);
+
+   openTag(os, ossimString("country"), false);
+   closeTag(os, ossimString("country"), false);
+
+   closeTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("cntvoice"), false);
+   closeTag(os, ossimString("cntvoice"), false);
+  
+   openTag(os, ossimString("cntfax"), false);
+   closeTag(os, ossimString("cntfax"), false);
+  
+   openTag(os, ossimString("cntemail"), false);
+   closeTag(os, ossimString("cntemail"), false);
+   
+   closeTag(os, ossimString("cntinfo"), true);
+   
+   closeTag(os, ossimString("ptcontac"), true);
+
+   openTag(os, ossimString("secinfo"), true);
+   openTag(os, ossimString("secclass"), false);
+   closeTag(os, ossimString("secclass"), false);
+   openTag(os, ossimString("secsys"), false);
+   closeTag(os, ossimString("secsys"), false);
+   openTag(os, ossimString("sechandl"), false);
+   closeTag(os, ossimString("sechandl"), false);
+   closeTag(os, ossimString("secinfo"), true);
+
+   closeTag(os, ossimString("idinfo"), true);
+
+   openTag(os, ossimString("distinfo"), true);
+   openTag(os, ossimString("distrib"), true);
+   openTag(os, ossimString("cntinfo"), true);
+   openTag(os, ossimString("cntperp"), true);
+   openTag(os, ossimString("cntper"), false);
+   closeTag(os, ossimString("cntper"), false);
+   closeTag(os, ossimString("cntperp"), true);
+
+   openTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("addrtype"), false);
+   closeTag(os, ossimString("addrtype"), false);
+
+   openTag(os, ossimString("address"), false);
+   closeTag(os, ossimString("address"), false);
+
+   openTag(os, ossimString("city"), false);
+   closeTag(os, ossimString("city"), false);
+
+   openTag(os, ossimString("state"), false);
+   closeTag(os, ossimString("state"), false);
+
+   openTag(os, ossimString("postal"), false);
+   closeTag(os, ossimString("postal"), false);
+
+   openTag(os, ossimString("country"), false);
+   closeTag(os, ossimString("country"), false);
+
+   closeTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("cntvoice"), false);
+   closeTag(os, ossimString("cntvoice"), false);
+  
+   openTag(os, ossimString("cntfax"), false);
+   closeTag(os, ossimString("cntfax"), false);
+  
+   openTag(os, ossimString("cntemail"), false);
+   closeTag(os, ossimString("cntemail"), false);
+   
+   closeTag(os, ossimString("cntinfo"), true);
+   closeTag(os, ossimString("distrib"), true);
+
+   openTag(os, ossimString("resdesc"), false);
+   closeTag(os, ossimString("resdesc"), false);
+
+   openTag(os, ossimString("distliab"), false);
+   closeTag(os, ossimString("distliab"), false);
+
+   openTag(os, ossimString("stdorder"), true);
+   openTag(os, ossimString("digform"), true);
+   openTag(os, ossimString("digtinfo"), true);
+   
+   openTag(os, ossimString("formname"), false);
+   closeTag(os, ossimString("formname"), false);
+
+   closeTag(os, ossimString("digtinfo"), true);
+
+   openTag(os, ossimString("digtopt"), true);
+   openTag(os, ossimString("onlinopt"), true);   
+   openTag(os, ossimString("computer"), true);
+   openTag(os, ossimString("networka"), true);
+
+   openTag(os, ossimString("networkr"), false);
+   closeTag(os, ossimString("networkr"), false);
+
+   closeTag(os, ossimString("networka"), true);
+   closeTag(os, ossimString("computer"), true);
+   closeTag(os, ossimString("onlinopt"), true);
+   closeTag(os, ossimString("digtopt"), true);
+   closeTag(os, ossimString("digform"), true);
+
+   openTag(os, ossimString("fees"), false);
+   closeTag(os, ossimString("fees"), false);
+
+   closeTag(os, ossimString("stdorder"), true);
+   closeTag(os, ossimString("distinfo"), true);
+
+   openTag(os, ossimString("metainfo"), true);
+
+   openTag(os, ossimString("metd"), false);
+   closeTag(os, ossimString("metd"), false);
+
+   openTag(os, ossimString("metc"), true);
+   openTag(os, ossimString("cntinfo"), true);
+   openTag(os, ossimString("cntperp"), true);
+   
+   openTag(os, ossimString("cntper"), false);
+   closeTag(os, ossimString("cntper"), false);
+
+   closeTag(os, ossimString("cntperp"), true);
+   
+   openTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("addrtype"), false);
+   closeTag(os, ossimString("addrtype"), false);
+
+   openTag(os, ossimString("address"), false);
+   closeTag(os, ossimString("address"), false);
+
+   openTag(os, ossimString("city"), false);
+   closeTag(os, ossimString("city"), false);
+
+   openTag(os, ossimString("state"), false);
+   closeTag(os, ossimString("state"), false);
+
+   openTag(os, ossimString("postal"), false);
+   closeTag(os, ossimString("postal"), false);
+
+   openTag(os, ossimString("country"), false);
+   closeTag(os, ossimString("country"), false);
+
+   closeTag(os, ossimString("cntaddr"), true);
+
+   openTag(os, ossimString("cntvoice"), false);
+   closeTag(os, ossimString("cntvoice"), false);
+  
+   openTag(os, ossimString("cntfax"), false);
+   closeTag(os, ossimString("cntfax"), false);
+  
+   openTag(os, ossimString("cntemail"), false);
+   closeTag(os, ossimString("cntemail"), false);
+   
+   closeTag(os, ossimString("cntinfo"), true);
+   closeTag(os, ossimString("metc"), true);
+
+   openTag(os, ossimString("metstdn"), false);
+   closeTag(os, ossimString("metstdn"), false);
+
+   openTag(os, ossimString("metstdv"), false);
+   closeTag(os, ossimString("metstdv"), false);
+
+   closeTag(os, ossimString("metainfo"), true);
+   closeTag(os, ossimString("metadata"), true);
+
+   os.close();
+
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "Wrote file:  " << file.c_str() << endl;
+   
+   return true;
+}
+   
+bool ossimFgdcFileWriter::loadState (const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   const char* lookup = kwl.find(prefix, "template");
+   if (lookup)
+   {
+      setTemplate(ossimFilename(lookup));
+   }
+   lookup = kwl.find(prefix, "source_image_filename");
+   if (lookup)
+   {
+      theSourceImageFilename = lookup;
+   }
+   lookup = kwl.find(prefix, "tab_string");
+   if (lookup)
+   {
+      theTabString = lookup;
+   }
+   lookup = kwl.find(prefix, "fgdc_template_doc");
+   if (lookup)
+   {
+      setTemplate(ossimFilename(lookup));
+   }
+   
+   return ossimMetadataFileWriter::loadState(kwl, prefix);
+}
+
+ossim_uint32 ossimFgdcFileWriter::getIndentionLevel() const
+{
+   return theIndentionLevel;
+}
+
+void ossimFgdcFileWriter::setIndentionLevel(ossim_uint32 level)
+{
+   theIndentionLevel = level;
+}
+
+ossimString ossimFgdcFileWriter::getTabString() const
+{
+   return theTabString;
+}
+
+void ossimFgdcFileWriter::setTabString(const ossimString& tabString)
+{
+   theTabString = tabString;
+}
+
+void ossimFgdcFileWriter::openTag(std::ostream& os,
+                                  const ossimString& tag,
+                                  bool newLine) const
+{
+   if ( theIndentionLevel && theTabString.size() )
+   {
+      ossimString tab;
+      for (ossim_uint32 i = 0; i < theIndentionLevel; ++i)
+      {
+         tab += theTabString;
+      }
+
+      os << tab.c_str();
+   }
+   
+   os << "<" << tag.c_str() << ">";
+
+   if (newLine)
+   {
+      os << "\n";
+      ++theIndentionLevel;
+   }
+}
+
+void ossimFgdcFileWriter::closeTag(std::ostream& os,
+                                   const ossimString& tag,
+                                   bool decrementLevel) const
+{
+   if ( decrementLevel && (theIndentionLevel > 1) && theTabString.size() )
+   {
+      ossimString tab;
+      for (ossim_uint32 i = 0; i < theIndentionLevel-1; ++i)
+      {
+         tab += theTabString;
+      }
+
+      os << tab.c_str();
+   }
+   
+   os << "</" << tag.c_str() << ">\n";
+
+   if (theIndentionLevel && decrementLevel)
+   {
+      --theIndentionLevel;
+   }
+}
+
+void ossimFgdcFileWriter::setTemplate(const ossimFilename& xmlTemplateFile)
+{
+   theTemplate.openFile(xmlTemplateFile);
+}
+
+ossimString ossimFgdcFileWriter::find(const ossimString& xpath) const
+{
+   ossimString result;
+
+   if (theTemplate.getErrorStatus())
+   {
+      return result;
+   }
+   
+   vector< ossimRefPtr<ossimXmlNode> > xml_nodes;
+   theTemplate.findNodes(xpath, xml_nodes);
+
+   if (xml_nodes.size())
+   {
+      if (xml_nodes[0].valid())
+      {
+         result = xml_nodes[0]->getText();
+      }
+   }
+   return result;
+}
+
+void ossimFgdcFileWriter::getMetadatatypeList(
+   std::vector<ossimString>& metadatatypeList) const
+{
+   metadatatypeList.push_back(ossimString("ossim_fgdc")); 
+}
+
+bool ossimFgdcFileWriter::hasMetadataType(
+   const ossimString& metadataType)const
+{
+   return (metadataType == "ossim_fgdc");
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimFgdcFileWriter.h b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimFgdcFileWriter.h
new file mode 100644
index 0000000000..dae3e8ecae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimFgdcFileWriter.h
@@ -0,0 +1,157 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:  Class to write out meta data in a Federal Geographic Data
+// Committe (FGDC) format.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimFgdcFileWriter.h,v 1.2 2005/08/11 18:58:33 gpotts Exp $
+#ifndef ossimFgdcFileWriter_HEADER
+#define ossimFgdcFileWriter_HEADER
+
+#include <imaging/metadata/ossimMetadataFileWriter.h>
+#include <base/data_types/ossimXmlNode.h>
+#include <base/data_types/ossimXmlDocument.h>
+
+/**
+ * Class to write out meta data in a Federal Geographic Data
+ * Committe (FGDC) format.
+ */
+class OSSIMDLLEXPORT ossimFgdcFileWriter : public ossimMetadataFileWriter
+{
+public:
+   
+   /** constructor */
+   ossimFgdcFileWriter();
+
+   /** destructor */
+   virtual ~ossimFgdcFileWriter();
+   
+   /**
+    * Method to load the state from a keyword list.
+    *
+    * @param kwl Keyword list to load state from.
+    *
+    * @param prefix Prefix to attatch to keyword (like "object1.").
+    * default=NULL
+    *
+    * @return true if ok or false on error.
+    *
+    * Keywords picked up by this loadState:
+    * 
+    * source_image_filename: foo.ntf
+    * tab_string:            "\t"
+    * fgdc_template_doc:     fgdc_template.xml
+    * 
+    */
+   virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0);
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * Appends the writers image types to the "metadatatypeList".
+    * 
+    * @param metadatatypeList stl::vector<ossimString> list to append to.
+    *
+    * @note Appends to the list, does not clear it first.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList) const;
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * @param imageType string representing image type.
+    *
+    * @return true if "metadataType" is supported by writer.
+    */
+   virtual bool hasMetadataType(const ossimString& metadataType)const;
+
+   
+   /** @return Returns the current indentation level. */
+   ossim_uint32 getIndentionLevel() const;
+
+   /**
+    * Sets the current indentation level.
+    *
+    * @param level Indentation level.  "0" equals no indentation.
+    */
+   void setIndentionLevel(ossim_uint32 level);
+
+   /**
+    * @return The current tab string e.g.: "\t".
+    */
+   ossimString getTabString() const;
+
+   /**
+    * Sets the tab string.  Usually "\t" or spaces "  ".
+    *
+    * @param tabString  String to use for indentation.
+    */
+   void setTabString(const ossimString& tabString);
+
+   /**
+    * @param title Tile of data usually the image file name.
+    */
+   void setTitle(const ossimString& pubDate);
+
+   void setTemplate(const ossimFilename& xmlTemplateFile);
+
+   ossimString find(const ossimString& xpath) const;
+
+   bool writeTemplate(const ossimFilename& file) const;
+
+protected:
+
+   /**
+    * Writes file to disk.
+    *
+    * @return true on success, false on failure.
+    */
+   virtual bool writeFile();
+
+private:
+
+   /**
+    * Writes openning tag adding any indentation and brackets.  Increments
+    * indentation level.
+    *
+    * @param os otream to write to.
+    *
+    * @param tag String representing tag with no brackets, i.e. "metadata".
+    *
+    * @param newLine If true a new line "\n" is added.
+    */
+   void openTag(std::ostream& os,
+                const ossimString& tag,
+                bool newLine) const;
+
+   /**
+    * Closes tag decrementing indentation.
+    * e.g.: <metadata>
+    *
+    * @param os otream to write to.
+    *
+    * @param tag String representing tag with no brackets.
+    *
+    * @param decrementLevel If true indentation level is decremented.
+    */
+   void closeTag(std::ostream& os,
+                 const ossimString& tag,
+                 bool decrementLevel) const;
+   
+   mutable ossim_uint32 theIndentionLevel;
+   ossimString          theTabString;
+   ossimXmlDocument     theTemplate;
+   ossimFilename        theSourceImageFilename;
+
+TYPE_DATA
+};
+
+#endif /* End of "#ifndef ossimFgdcFileWriter_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimGeomFileWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimGeomFileWriter.cpp
new file mode 100644
index 0000000000..e53cff2eec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimGeomFileWriter.cpp
@@ -0,0 +1,96 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimGeomFileWriter.cpp,v 1.9 2006/01/06 16:57:04 dburken Exp $
+
+#include <imaging/metadata/ossimGeomFileWriter.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSource.h>
+
+RTTI_DEF1(ossimGeomFileWriter,
+          "ossimGeomFileWriter",
+          ossimMetadataFileWriter)
+
+static const char DEFAULT_FILE_NAME[] = "output.geom";
+
+static ossimTrace traceDebug("ossimGeomFileWriter:debug");
+
+ossimGeomFileWriter::ossimGeomFileWriter()
+   :
+      ossimMetadataFileWriter()
+{}
+
+ossimGeomFileWriter::~ossimGeomFileWriter()
+{}
+
+bool ossimGeomFileWriter::writeFile()
+{
+   // Get the geometry from the input.
+   ossimKeywordlist kwl;
+   theInputConnection->getImageGeometry(kwl);
+
+   // Create the projection.
+   ossimRefPtr<ossimProjection> proj =
+      ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+   if (!proj.valid())
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimGeomFileWriter::writeFile DEBUG:"
+            << "\nCreate projection failed!"
+            << "\nGeometry kwl: " << kwl
+            << endl;
+      }
+
+      return false;
+   }
+   
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj.get());
+   if (!mapProj)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimGeomFileWriter::writeFile DEBUG:"
+            << "\nNot a map projection!"
+            << endl;
+      }
+
+      return false;
+   }
+
+   // Create the projection info.
+   ossimRefPtr<ossimMapProjectionInfo> projectionInfo
+      = new ossimMapProjectionInfo(mapProj, theAreaOfInterest);
+   
+   // Set the tie points.
+   projectionInfo->getGeom(kwl);
+
+   // Write it to disk.
+   return kwl.write(theFilename.c_str());
+}
+
+void ossimGeomFileWriter::getMetadatatypeList(
+   std::vector<ossimString>& metadatatypeList) const
+{
+   metadatatypeList.push_back(ossimString("ossim_geometry")); 
+}
+
+bool ossimGeomFileWriter::hasMetadataType(
+   const ossimString& metadataType)const
+{
+   return (metadataType == "ossim_geometry");
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimGeomFileWriter.h b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimGeomFileWriter.h
new file mode 100644
index 0000000000..24b53f3a46
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimGeomFileWriter.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimGeomFileWriter.h,v 1.7 2005/08/08 22:00:24 dburken Exp $
+
+#ifndef ossimGeomFileWriter_H
+#define ossimGeomFileWriter_H
+
+#include <imaging/metadata/ossimMetadataFileWriter.h>
+
+/** ossimGeomFileWriter */
+class OSSIMDLLEXPORT ossimGeomFileWriter : public ossimMetadataFileWriter
+{
+public:
+   /** default constructor */
+   ossimGeomFileWriter();
+
+   /** virtual destructor */
+   virtual ~ossimGeomFileWriter();
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * Appends the writers image types to the "metadatatypeList".
+    * 
+    * @param metadatatypeList stl::vector<ossimString> list to append to.
+    *
+    * @note Appends to the list, does not clear it first.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList) const;
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * @param imageType string representing image type.
+    *
+    * @return true if "metadataType" is supported by writer.
+    */
+   virtual bool hasMetadataType(const ossimString& metadataType)const;
+
+private:
+
+   /** Write a geometry file to "theFilename". */
+   virtual bool writeFile();
+   
+TYPE_DATA
+};
+
+#endif /* End of #ifndef ossimGeomFileWriter_H */
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimJpegWorldFileWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimJpegWorldFileWriter.cpp
new file mode 100644
index 0000000000..14d52e775b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimJpegWorldFileWriter.cpp
@@ -0,0 +1,119 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero
+//
+//*******************************************************************
+//  $Id: ossimJpegWorldFileWriter.cpp,v 1.7 2005/08/08 22:00:24 dburken Exp $
+
+#include <stdio.h>
+#include <imaging/metadata/ossimJpegWorldFileWriter.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSource.h>
+
+RTTI_DEF1(ossimJpegWorldFileWriter,
+          "ossimJpegWorldFileWriter",
+          ossimMetadataFileWriter)
+
+static const char DEFAULT_FILE_NAME[] = "output.jgw";
+static ossimTrace traceDebug("ossimJpegWorldFileWriter:debug");
+
+ossimJpegWorldFileWriter::ossimJpegWorldFileWriter()
+   :
+      ossimMetadataFileWriter()
+{
+}
+
+ossimJpegWorldFileWriter::~ossimJpegWorldFileWriter()
+{
+}
+
+bool ossimJpegWorldFileWriter::writeFile()
+{
+   if(!theInputConnection)
+   {
+      return false;
+   }
+
+   std::ofstream out(theFilename.c_str(), ios_base::out);
+   if (!out)
+   {
+      return false;
+   }
+
+   // Get the geometry.
+   ossimKeywordlist kwl;
+   if (!theInputConnection->getImageGeometry(kwl))
+   {
+      return false;
+   }
+
+   // Make the projection.
+   ossimRefPtr<ossimProjection> proj =
+      ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+   if (!proj)
+   {
+      return false;
+   }
+
+   // Cast to map projection.
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj.get());
+   if (!mapProj)
+   {
+      return false;
+   }
+
+   // Create the map projection info.
+   ossimRefPtr<ossimMapProjectionInfo> projectionInfo
+      = new ossimMapProjectionInfo(mapProj, theAreaOfInterest);
+
+   ossimDpt gsd;
+   ossimDpt ul;
+   
+   if(projectionInfo->getProjection()->isGeographic())
+   {
+      gsd = projectionInfo->getDecimalDegreesPerPixel();
+      ul  = projectionInfo->ulGroundPt();
+   }
+   else
+   {
+      gsd = projectionInfo->getMetersPerPixel();
+      ul  = projectionInfo->ulEastingNorthingPt();
+   }
+         
+   out << setiosflags(ios::fixed) << setprecision(15)
+       << gsd.x  << endl
+       << 0.0    << endl // rotation value X
+       << 0.0    << endl // rotation value y
+       << -gsd.y << endl
+       << ul.u   << endl
+       << ul.v   << endl;
+
+   out.close();
+   
+   return true;
+}
+
+void ossimJpegWorldFileWriter::getMetadatatypeList(
+   std::vector<ossimString>& metadatatypeList) const
+{
+   metadatatypeList.push_back(ossimString("jpeg_world_file")); 
+}
+
+bool ossimJpegWorldFileWriter::hasMetadataType(
+   const ossimString& metadataType)const
+{
+   return (metadataType == "jpeg_world_file");
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimJpegWorldFileWriter.h b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimJpegWorldFileWriter.h
new file mode 100644
index 0000000000..313a931d2e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimJpegWorldFileWriter.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimJpegWorldFileWriter.h,v 1.4 2005/08/08 22:00:24 dburken Exp $
+
+#ifndef ossimJpegWorldFileWriter_H
+#define ossimJpegWorldFileWriter_H
+
+#include <fstream>
+#include <imaging/metadata/ossimMetadataFileWriter.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+
+/** ossimJpegWorldFileWriter */
+class OSSIMDLLEXPORT ossimJpegWorldFileWriter : public ossimMetadataFileWriter
+{
+public:
+
+   ossimJpegWorldFileWriter();
+   
+   virtual ~ossimJpegWorldFileWriter();
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * Appends the writers image types to the "metadatatypeList".
+    * 
+    * @param metadatatypeList stl::vector<ossimString> list to append to.
+    *
+    * @note Appends to the list, does not clear it first.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList) const;   
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * @param imageType string representing image type.
+    *
+    * @return true if "metadataType" is supported by writer.
+    */
+   virtual bool hasMetadataType(const ossimString& metadataType)const;
+   
+private:
+   virtual bool writeFile();
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimMetadataFileWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimMetadataFileWriter.cpp
new file mode 100644
index 0000000000..9305bce923
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimMetadataFileWriter.cpp
@@ -0,0 +1,240 @@
+//*******************************************************************
+// Copyright (C) 2003 Stroage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimMetadataFileWriter.cpp,v 1.8 2005/06/19 16:07:29 dburken Exp $
+
+#include <imaging/metadata/ossimMetadataFileWriter.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimViewController.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+#include <imaging/formats/ossimImageHandler.h>
+
+
+RTTI_DEF3(ossimMetadataFileWriter,
+          "ossimMetadataFileWriter",
+          ossimConnectableObject,
+          ossimProcessInterface,
+          ossimConnectableObjectListener);
+
+static ossimTrace traceDebug("ossimMetadataFileWriter:degug");
+
+ossimMetadataFileWriter::ossimMetadataFileWriter()
+   :
+      ossimProcessInterface(),
+      ossimConnectableObjectListener(),
+      theInputConnection(NULL),
+      theFilename(),
+      thePixelType(OSSIM_PIXEL_IS_POINT),
+      theAreaOfInterest()
+{
+   theAreaOfInterest.makeNan();
+}
+
+ossimMetadataFileWriter::~ossimMetadataFileWriter()
+{
+}
+
+void ossimMetadataFileWriter::initialize()
+{
+   theInputConnection = PTR_CAST(ossimImageSourceInterface,
+                                 getInput());
+}
+
+bool ossimMetadataFileWriter::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   bool result = ossimConnectableObject::loadState(kwl, prefix);
+
+   // Get the filename...
+   const char* lookup = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   if(lookup)
+   {
+      ossimString filename = lookup;
+
+      setFilename(filename);
+   }
+
+   // Note: Defaulted to point in constructor.
+   lookup = kwl.find(prefix, ossimKeywordNames::PIXEL_TYPE_KW);
+   if (lookup)
+   {
+      ossimString s = lookup;
+      s.downcase();
+      if (s.contains("area"))
+      {
+         thePixelType = OSSIM_PIXEL_IS_AREA;
+      }
+      else if (s.contains("point"))
+      {
+         thePixelType = OSSIM_PIXEL_IS_POINT;
+      }
+   }
+   
+   if(theInputObjectList.size() != 1)
+   {
+      theInputObjectList.resize(1);
+      theInputListIsFixedFlag = true;
+   }
+   
+   theOutputListIsFixedFlag = false;
+      
+   return result;
+}
+
+void ossimMetadataFileWriter::disconnectInputEvent(ossimConnectionEvent& event)
+{
+   initialize();
+}
+
+void ossimMetadataFileWriter::connectInputEvent(ossimConnectionEvent& event)
+{
+   theInputConnection = PTR_CAST(ossimImageSourceInterface, getInput());
+   initialize();
+}
+
+void ossimMetadataFileWriter::propertyEvent(ossimPropertyEvent& event)
+{
+   initialize();
+}
+
+void ossimMetadataFileWriter::setPixelType(ossimPixelType pixelType)
+{
+   thePixelType = pixelType;
+}
+
+ossimPixelType ossimMetadataFileWriter::getPixelType()const
+{
+   return thePixelType;
+}
+
+ossimObject* ossimMetadataFileWriter::getObject()
+{
+   return this;
+}
+
+const ossimObject* ossimMetadataFileWriter::getObject() const
+{
+   return this;
+}
+
+bool ossimMetadataFileWriter::execute()
+{
+   bool result = false;
+   
+   if (!theInputConnection)
+   {
+      initialize();
+      if (!theInputConnection)
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "ossimMetadataFileWriter::execute DEBUG:\n"
+               << "theInputConnection is null!"
+               << endl;
+         }
+         return result;
+      }
+   }
+   
+   if(theFilename == ossimFilename::NIL)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimMetadataFileWriter::execute DEBUG:\n"
+            << "theFilename is not set!"
+            << endl;
+      }
+      return result;
+   }
+   
+   //---
+   // If theAreaOfInterest hasNans then it was probably not set so use
+   // the bounding rectangle of the input source.
+   //---
+   if (theAreaOfInterest.hasNans())
+   {
+      theAreaOfInterest = theInputConnection->getBoundingRect();
+      if (theAreaOfInterest.hasNans())
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "ossimMetadataFileWriter::execute DEBUG:\n"
+               << "theAreaOfInterest is not set!"
+               << endl;
+         }
+         return result;
+      }
+   }
+
+   setProcessStatus(ossimProcessInterface::PROCESS_STATUS_EXECUTING);
+
+   setPercentComplete(0.0);
+
+   result = writeFile();
+
+   setProcessStatus(ossimProcessInterface::PROCESS_STATUS_NOT_EXECUTING);
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimMetadataFileWriter::execute DEBUG:\n"
+         << (result?"successful":"unsuccessful") << " write of file:  "
+         << theFilename
+         << endl;
+   }
+   
+   return result;
+}
+
+void ossimMetadataFileWriter::setPercentComplete(double percentComplete)
+{
+   ossimProcessInterface::setPercentComplete(percentComplete);
+   ossimProcessProgressEvent event(this,
+                                   percentComplete);
+   fireEvent(event);      
+}
+
+void ossimMetadataFileWriter::setFilename(const ossimFilename& file)
+{
+   theFilename = file;
+}
+
+const ossimFilename& ossimMetadataFileWriter::getFilename() const
+{
+   return theFilename;
+}
+
+bool ossimMetadataFileWriter::canConnectMyInputTo(ossim_int32 inputIndex,
+                                                  const ossimConnectableObject* object) const
+{
+   return (object &&
+           ((PTR_CAST(ossimImageSourceInterface, object) &&
+             inputIndex == 0)||
+            (PTR_CAST(ossimViewController, object) &&
+             inputIndex == 1)));
+}
+
+void ossimMetadataFileWriter::setAreaOfInterest(
+   const ossimIrect& areaOfInterest)
+{
+   theAreaOfInterest = areaOfInterest;
+}
+
+ossimIrect ossimMetadataFileWriter::getAreaOfInterest() const
+{
+   return theAreaOfInterest;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimMetadataFileWriter.h b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimMetadataFileWriter.h
new file mode 100644
index 0000000000..e220df010e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimMetadataFileWriter.h
@@ -0,0 +1,149 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimMetadataFileWriter.h,v 1.12 2005/08/08 22:00:24 dburken Exp $
+
+#ifndef ossimMetadataFileWriter_H
+#define ossimMetadataFileWriter_H
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimConnectableObject.h>
+#include <base/common/ossimProcessInterface.h>
+#include <base/common/events/ossimConnectableObjectListener.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/common/events/ossimObjectEvents.h>
+#include <base/common/events/ossimProcessProgressEvent.h>
+
+class ossimImageSourceInterface;
+
+/**
+ * ossimMetadataFileWriter
+ *
+ * Typical usage something like this:
+ *
+ * ossimObject* obj = ossimImageMetaDataWriterRegistry::instance()->
+ *     createObject(ossimString("ossimReadmeFileWriter"));
+ * if (!obj)
+ * {
+ *    return;
+ * }
+ * ossimMetadataFileWriter* mw = PTR_CAST(ossimMetadataFileWriter, obj);
+ * if (!mw)
+ * {
+ *    return;
+ * }
+ * 
+ * mw->setFilename(xmlFile);
+ * mw->loadState(kwl);
+ * mw->connectMyInputTo(ih.get());
+ * mw->execute();
+ * delete mw;
+ */
+class OSSIMDLLEXPORT ossimMetadataFileWriter :
+   public ossimConnectableObject,
+   public ossimProcessInterface,
+   public ossimConnectableObjectListener
+{   
+public:
+   ossimMetadataFileWriter();
+   
+   virtual ~ossimMetadataFileWriter();
+
+   virtual ossimObject*       getObject();
+   virtual const ossimObject* getObject() const;
+
+   virtual void initialize();
+   
+   virtual bool execute();
+   
+   virtual void setPercentComplete(double percentComplete);
+   
+   virtual void setFilename(const ossimFilename& file);
+   
+   const ossimFilename& getFilename()const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix = 0);
+   
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object) const;
+   
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+   virtual void propertyEvent(ossimPropertyEvent& event);
+
+   /**
+    * Ossim uses a concept of "pixel is point" internally.
+    * 
+    * This means that if you say a tie point is 30.0N -81.0W, the center of
+    * the pixel at the tie point is 30.0N -81.0W.
+    *
+    */ 
+   virtual void setPixelType(ossimPixelType pixelType);
+   virtual ossimPixelType getPixelType() const;
+
+   /**
+    * Sets the area of interest to write the meta data for.
+    * 
+    * @param areaOfInterest Sets theAreaOfInterest.
+    *
+    * @note By default the writers will use
+    * "theInputConnection->getBoundingRect()" if theAreaOfInterest has nans.
+    */
+   virtual void setAreaOfInterest(const ossimIrect& areaOfInterest);
+
+   /**
+    * @returns theAreaOfInterest.
+    */
+   virtual ossimIrect getAreaOfInterest() const;
+
+   /**
+    * void getMetadatatypeList(std::vector<ossimString>& metadatatypeList)const
+    *
+    * pure virtual
+    * 
+    * Appends the writers metadata types to the "metadatatypeList".
+    * 
+    * This is the actual image type name.  So for
+    * example, ossimTiffWorldFileWriter has tiff_world_file type.
+    *
+    * @param metadatatypeList stl::vector<ossimString> list to append to.
+    *
+    * @note All writers should append to the list, not, clear it and then add
+    * their types.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList)const=0;
+
+   /**
+    * bool hasMetadataType(const ossimString& metadataType) const
+    *
+    * @param imageType string representing image type.
+    *
+    * @return true if "metadataType" is supported by writer.
+    */
+   virtual bool hasMetadataType(const ossimString& metadataType)const=0;
+   
+protected:
+   /**
+    * Write out the file.
+    * @return true on success, false on error.
+    */
+   virtual bool writeFile() = 0;
+
+   ossimImageSourceInterface* theInputConnection;
+   ossimFilename              theFilename;
+   ossimPixelType             thePixelType;
+   ossimIrect                 theAreaOfInterest;
+   
+TYPE_DATA
+};
+
+#endif /* End of #ifndef ossimMetadataFileWriter_H */
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimReadmeFileWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimReadmeFileWriter.cpp
new file mode 100644
index 0000000000..c7fa067eaa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimReadmeFileWriter.cpp
@@ -0,0 +1,476 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimReadmeFileWriter.cpp,v 1.8 2005/08/08 22:00:24 dburken Exp $
+
+#include <iostream>
+using namespace std;
+
+#include <imaging/metadata/ossimReadmeFileWriter.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSource.h>
+
+RTTI_DEF1(ossimReadmeFileWriter,
+          "ossimReadmeFileWriter",
+          ossimMetadataFileWriter)
+
+static const char DEFAULT_FILE_NAME[] = "output_readme.txt";
+static ossimTrace traceDebug("ossimReadmeFileWriter:debug");
+
+ossimReadmeFileWriter::ossimReadmeFileWriter()
+   :
+      ossimMetadataFileWriter()
+{
+}
+
+ossimReadmeFileWriter::~ossimReadmeFileWriter()
+{
+}
+
+bool ossimReadmeFileWriter::writeFile()
+{
+   static const char MODULE[] = "ossimReadmeFileWriter::writeFile";
+
+   if(!theInputConnection)
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nNo input connection!  Returning..."
+              << endl;
+      }
+
+      return false;
+   }
+
+   std::ofstream out(theFilename.c_str(), ios_base::out);
+   if (!out)
+   {
+      return false;
+   }
+
+   ossimKeywordlist kwl;
+   theInputConnection->getImageGeometry(kwl);
+   
+   ossimProjection* proj;
+   proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+   if (!proj)
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nCould not create projection from geometry!"
+              << "\nGeometry keyword list dump:\n"
+              << kwl
+              << "\nReturning..."
+              << endl;
+      }
+      return false;
+   }
+   
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj);
+   if (!mapProj)
+   {
+      if (traceDebug())
+      {
+         CLOG << "DEBUG:"
+              << "\nCould not create map projection from geometry!"
+              << "\nGeometry keyword list dump:\n"
+              << kwl
+              << "\nReturning..."
+              << endl;
+      }
+
+      delete proj;
+      return false;
+   }
+
+   ossimMapProjectionInfo* projectionInfo
+      = new ossimMapProjectionInfo(mapProj, theAreaOfInterest);
+
+   if(projectionInfo)
+   {
+	   
+      out << setiosflags(ios::fixed)
+          << setiosflags(ios::left)
+          << setw(16) << "Image: "
+          << projectionInfo->getImageInfoString();
+      
+      out << setw(17) << "\nLines:"
+          << projectionInfo->linesPerImage()
+          << setw(17) << "\nSamples:"
+          << projectionInfo->pixelsPerLine()
+          << setw(17) << "\nPixel Size x:"
+          << setprecision(8) 
+          << projectionInfo->getMetersPerPixel().x 
+          << " meters";
+      
+      out << ", " 
+          << setprecision(8) 
+          << projectionInfo->getUsSurveyFeetPerPixel().x
+          << " U.S. feet";
+      
+      out << setw(17) << "\nPixel Size y:"
+          << setprecision(8) 
+          << projectionInfo->getMetersPerPixel().y 
+          << " meters";
+      
+      out << ", " 
+          << setprecision(8) 
+          << projectionInfo->getUsSurveyFeetPerPixel().y
+          << " U.S. feet";
+      
+      const char* type  = kwl.find(ossimKeywordNames::TYPE_KW);
+      const char* zone  = kwl.find(ossimKeywordNames::ZONE_KW);
+      const char* datum = kwl.find(ossimKeywordNames::DATUM_KW);
+      const char* ellipsoid = kwl.find(ossimKeywordNames::ELLIPSE_CODE_KW);
+      
+      if(type)
+         out << setw(17) << "\nProjection:" << type;
+      
+      if(zone)
+         out << setw(17) << "\nUTM map zone:" << zone;
+      
+      if(datum && ellipsoid)
+         out << setw(17) << "\nDatum:"      << datum
+             << setw(17) << "\nEllipsoid:"
+             << ellipsoid;
+      
+      out << resetiosflags(ios::left) << endl;
+      
+      const ossimString NORTH = "N";
+      const ossimString SOUTH = "S";
+      const ossimString EAST  = "E";
+      const ossimString WEST  = "W";
+      
+      ossimString tmpString;
+      double tmpDouble;
+      
+      const char* falseEasting 
+         = kwl.find(ossimKeywordNames::FALSE_EASTING_KW);
+      const char* falseNorthing
+         = kwl.find(ossimKeywordNames::FALSE_NORTHING_KW);
+      const char* parallel1
+         = kwl.find(ossimKeywordNames::STD_PARALLEL_1_KW);
+      const char* parallel2
+         = kwl.find(ossimKeywordNames::STD_PARALLEL_2_KW);
+      const char* scaleFactor
+         = kwl.find(ossimKeywordNames::SCALE_FACTOR_KW);
+      
+      ossimString proj_name = mapProj->getClassName();
+      
+      if ( ( proj_name.contains("Lambert")           ) ||
+           ( proj_name.contains("Albers")            ) ||
+           ( proj_name.contains("TransverseMercator" ) ) )
+      {
+         
+         double origin_lat = mapProj->origin().latd();
+         tmpDouble = fabs(origin_lat);
+         tmpString = (origin_lat < 0.0) ? SOUTH : NORTH;
+         out << setiosflags(ios::left)
+             << "\n"
+             << setw(18) << "Origin Latitude:"
+             << resetiosflags(ios::left)
+             << setw(21) << setprecision(12) << tmpDouble 
+             << tmpString << endl;
+         
+         double origin_lon = mapProj->origin().lond();
+         tmpDouble = fabs(origin_lon);
+         tmpString = (origin_lon < 0.0) ? WEST : EAST;
+         out << setiosflags(ios::left)
+             << setw(18) << "Origin Longitude:"
+             << resetiosflags(ios::left)
+             << setw(21) << tmpDouble << tmpString
+             << setiosflags(ios::left)
+             << "\n"
+             << setw(23) << "False Easting:"
+             << resetiosflags(ios::left)
+             << setw(17) << setprecision(4) 
+             << ossimString(falseEasting).toDouble();
+         
+         out << " meters, " << setprecision(4)
+             << mtrs2usft(ossimString(falseEasting).toDouble()) 
+             << " U.S. feet";
+         
+         out << endl;
+	 
+         out << setiosflags(ios::left)
+             << setw(23) << "False Northing:"
+             << resetiosflags(ios::left)
+             << setw(17) << setprecision(4) 
+             << ossimString(falseNorthing).toDouble();
+         
+         out << " meters, " << setprecision(4)
+             << mtrs2usft(ossimString(falseNorthing).toDouble()) 
+             << " U.S. feet";
+         
+         out << endl;
+	 
+      } // End of if "Alber Lambert or TM.
+      
+      if (proj_name.contains("TransverseMercator"))
+      {
+         out << setiosflags(ios::left)
+             << "\n"
+             << setw(18) << "Scale Factor:"
+             << resetiosflags(ios::left)
+             << setw(21) << setprecision(10) 
+             << ossimString(scaleFactor).toDouble()
+             << "\n" << endl;
+      }
+      
+      if ( (proj_name.contains("Lambert") ) ||
+           (proj_name.contains("Albers")  ) )
+      {
+         double stdpar1 = ossimString(parallel1).toDouble();
+         tmpDouble = fabs(stdpar1);
+         tmpString = (stdpar1 < 0.0) ? SOUTH : NORTH;
+         out << setiosflags(ios::left) 
+             << setw(23) << "Standard Parallel #1:"
+             << resetiosflags(ios::left)
+             << setw(16) << setprecision(12) << tmpDouble
+             << tmpString << endl;
+         
+         double stdpar2 = ossimString(parallel2).toDouble();
+         tmpDouble = fabs(stdpar2);
+         tmpString = (stdpar2 < 0.0) ? SOUTH : NORTH;
+         out << setiosflags(ios::left)
+             << setw(23) << "Standard Parallel #2:"
+             << resetiosflags(ios::left)
+             << setw(16) << setprecision(12) 
+             << tmpDouble << tmpString
+             << "\n" << endl;
+      }
+      
+      ossimString cornerString[4] = { "Upper Left",
+                                      "Upper Right",
+                                      "Lower Right",
+                                      "Lower Left" };
+	
+      //---
+      // Add a note to the readme file stating what the corner coordinates
+      // are relative to.
+      //---
+      if (projectionInfo->getPixelType() == OSSIM_PIXEL_IS_AREA)
+      {
+         out 
+            << "\nCorner coordinates relative to outer edge of pixel.\n\n";
+      }
+      else
+      {
+         out
+            << "\nCorner coordinates relative to center of pixel.\n\n";
+      }
+      
+      out << "Corner Coordinates:\n\n";
+      
+      //---
+      // Upper Left Corner Points
+      //---
+      tmpDouble = fabs(projectionInfo->ulGroundPt().latd());
+      tmpString = (projectionInfo->ulGroundPt().latd() < 0.0) ? SOUTH : NORTH; 
+      out << cornerString[0]  << endl;
+      out << setw(14) << "Latitude:  "
+          << setw(16) << setprecision(12) << tmpDouble 
+          << tmpString << endl;
+      tmpDouble = fabs(projectionInfo->ulGroundPt().lond());
+      tmpString = (projectionInfo->ulGroundPt().lond() < 0.0) ? WEST : EAST;
+      out << setw(14) << "Longitude:  "
+          << setw(16) << tmpDouble << tmpString << endl;
+      
+      out << setw(14) << "Easting:  "
+          << setw(17) << setprecision(4) 
+          << projectionInfo->ulEastingNorthingPt().x;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->ulEastingNorthingPt().x)
+          << " U.S. feet";
+      
+      out << endl
+          << setw(14) << "Northing:  "
+          << setw(17) << projectionInfo->ulEastingNorthingPt().y;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->ulEastingNorthingPt().y)
+          << " U.S. feet";
+      
+      out << endl << endl;
+      
+      //---
+      // Upper Right Corner Points
+      //---
+      tmpDouble = fabs(projectionInfo->urGroundPt().latd());
+      tmpString = (projectionInfo->urGroundPt().latd() < 0.0) ? SOUTH : NORTH; 
+      out << cornerString[1]  << endl;
+      out << setw(14) << "Latitude:  "
+          << setw(16) << setprecision(12) << tmpDouble
+          << tmpString << endl;
+      tmpDouble = fabs(projectionInfo->urGroundPt().lond());
+      tmpString = (projectionInfo->urGroundPt().lond() < 0.0) ? WEST : EAST;
+      out << setw(14) << "Longitude:  "
+          << setw(16) << tmpDouble << tmpString << endl;
+      
+      out << setw(14) << "Easting:  "
+          << setw(17) << setprecision(4)
+          << projectionInfo->urEastingNorthingPt().x;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->urEastingNorthingPt().x)
+          << " U.S. feet";
+      
+      out << endl
+          << setw(14) << "Northing:  "
+          << setw(17) << projectionInfo->urEastingNorthingPt().y;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->urEastingNorthingPt().y)
+          << " U.S. feet";
+      
+      out << endl << endl;
+      
+      //---
+      // Lower Right Corner Points
+      //---
+      tmpDouble = fabs(projectionInfo->lrGroundPt().latd());
+      tmpString = (projectionInfo->lrGroundPt().latd() < 0.0) ? SOUTH : NORTH; 
+      out << cornerString[2]  << endl;
+      out << setw(14) << "Latitude:  "
+          << setw(16) << setprecision(12) << tmpDouble 
+          << tmpString << endl;
+      tmpDouble = fabs(projectionInfo->lrGroundPt().lond());
+      tmpString = (projectionInfo->lrGroundPt().lond() < 0.0) ? WEST : EAST;
+      out << setw(14) << "Longitude:  "
+          << setw(16) << tmpDouble << tmpString << endl;
+      
+      out << setw(14) << "Easting:  "
+          << setw(17) << setprecision(4) 
+          << projectionInfo->lrEastingNorthingPt().x;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->lrEastingNorthingPt().x)
+          << " U.S. feet";
+      
+      out << endl
+          << setw(14) << "Northing:  "
+          << setw(17) << projectionInfo->lrEastingNorthingPt().y;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->lrEastingNorthingPt().y)
+          << " U.S. feet";
+      
+      out << endl << endl;
+      
+      //---
+      // Lower Left Corner Points
+      //---
+      tmpDouble = fabs(projectionInfo->llGroundPt().latd());
+      tmpString = (projectionInfo->llGroundPt().latd() < 0.0) ? SOUTH : NORTH; 
+      out << cornerString[3]  << endl;
+      out << setw(14) << "Latitude:  "
+          << setw(16) << setprecision(12) << tmpDouble
+          << tmpString << endl;
+      tmpDouble = fabs(projectionInfo->llGroundPt().lond());
+      tmpString = (projectionInfo->llGroundPt().lond() < 0.0) ? WEST : EAST;
+      out << setw(14) << "Longitude:  "
+          << setw(16) << tmpDouble << tmpString << endl;
+      
+      out << setw(14) << "Easting:  "
+          << setw(17) << setprecision(4)
+          <<  projectionInfo->llEastingNorthingPt().x;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->llEastingNorthingPt().x)
+          << " U.S. feet";
+      
+      out << endl
+          << setw(14) << "Northing:  "
+          << setw(17) << projectionInfo->llEastingNorthingPt().y;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->llEastingNorthingPt().y)
+          << " U.S. feet";
+      
+      out << endl << endl;
+      
+      out << "Center Coordinates:\n\n";
+      
+      tmpDouble = fabs(projectionInfo->centerGroundPt().latd());
+      
+      tmpString = (projectionInfo->centerGroundPt().latd() < 0.0) ? SOUTH : NORTH;
+      
+      out << setw(14) << "Latitude:  "
+          << setw(16) << setprecision(12) << tmpDouble
+          << tmpString << endl;
+      
+      tmpDouble = fabs(projectionInfo->centerGroundPt().lond());
+      
+      tmpString = (projectionInfo->centerGroundPt().lond() < 0.0) ? WEST : EAST;
+      
+      out << setw(14) << "Longitude:  "
+          << setw(16) << tmpDouble << tmpString << endl;
+      
+      out << setw(14) << "Easting:  "
+          << setw(17) << setprecision(4)
+          << projectionInfo->centerEastingNorthingPt().x;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->centerEastingNorthingPt().x)
+          << " U.S. feet";
+      
+      out << endl
+          << setw(14) << "Northing:  "
+          << setw(17) << projectionInfo->centerEastingNorthingPt().y;
+      
+      out << " meters, " << setprecision(4)
+          << mtrs2usft(projectionInfo->centerEastingNorthingPt().y)
+          << " U.S. feet";
+      
+      out << endl << endl;
+      
+      out 
+         << "\nNOTE:  Lat/Lon values are in decimal degrees.";
+      
+      out 
+         << "\n       Eastings/Northings are in meters.";
+      
+      out << endl;
+      
+      delete projectionInfo;
+   }
+   
+   if(proj)
+   {
+      delete proj;
+      proj = NULL;
+   }
+
+   out.close();
+   
+   return true;
+}
+
+void ossimReadmeFileWriter::getMetadatatypeList(
+   std::vector<ossimString>& metadatatypeList) const
+{
+   metadatatypeList.push_back(ossimString("ossim_readme")); 
+}
+
+bool ossimReadmeFileWriter::hasMetadataType(
+   const ossimString& metadataType)const
+{
+   return (metadataType == "ossim_readme");
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimReadmeFileWriter.h b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimReadmeFileWriter.h
new file mode 100644
index 0000000000..2461f66ed0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimReadmeFileWriter.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimReadmeFileWriter.h,v 1.5 2005/08/08 22:00:24 dburken Exp $
+
+#ifndef ossimReadmeFileWriter_H
+#define ossimReadmeFileWriter_H
+
+#include <fstream>
+#include <imaging/metadata/ossimMetadataFileWriter.h>
+
+/** ossimReadmeFileWriter */
+class OSSIMDLLEXPORT ossimReadmeFileWriter : public ossimMetadataFileWriter
+{
+public:
+
+   /** default constructor */
+   ossimReadmeFileWriter();
+
+   /** virtual destructor */
+   virtual ~ossimReadmeFileWriter();
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * Appends the writers image types to the "metadatatypeList".
+    * 
+    * @param metadatatypeList stl::vector<ossimString> list to append to.
+    *
+    * @note Appends to the list, does not clear it first.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList) const;
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * @param imageType string representing image type.
+    *
+    * @return true if "metadataType" is supported by writer.
+    */
+   virtual bool hasMetadataType(const ossimString& metadataType)const;
+   
+private:
+   virtual bool writeFile();
+   
+TYPE_DATA
+};
+
+#endif /* End of #ifndef ossimReadmeFileWriter_H */
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimTiffWorldFileWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimTiffWorldFileWriter.cpp
new file mode 100644
index 0000000000..02a97d28b5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimTiffWorldFileWriter.cpp
@@ -0,0 +1,121 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimTiffWorldFileWriter.cpp,v 1.8 2005/08/08 22:00:24 dburken Exp $
+
+#include <imaging/metadata/ossimTiffWorldFileWriter.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSource.h>
+
+RTTI_DEF1(ossimTiffWorldFileWriter,
+          "ossimTiffWorldFileWriter",
+          ossimMetadataFileWriter)
+
+static const char DEFAULT_FILE_NAME[] = "output.tfw";
+static ossimTrace traceDebug("ossimTiffWorldFileWriter:debug");
+
+ossimTiffWorldFileWriter::ossimTiffWorldFileWriter()
+   :
+      ossimMetadataFileWriter()
+{
+}
+
+ossimTiffWorldFileWriter::~ossimTiffWorldFileWriter()
+{
+}
+
+bool ossimTiffWorldFileWriter::writeFile()
+{
+   bool result = true;
+   if(!theInputConnection)
+   {
+      return false;
+   }
+
+   std::ofstream out(theFilename.c_str(), ios_base::out);
+   if (!out)
+   {
+      return false;
+   }
+   
+   ossimKeywordlist kwl;
+
+   theInputConnection->getImageGeometry(kwl);
+   ossimProjection* proj;
+   proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj);
+
+   if(mapProj)
+   {
+      ossimMapProjectionInfo* projectionInfo
+         = new ossimMapProjectionInfo(mapProj, theAreaOfInterest);
+
+      projectionInfo->setPixelType(thePixelType);
+      
+      if(projectionInfo)
+      {
+         ossimDpt gsd;
+         ossimDpt ul;
+
+         if(projectionInfo->getProjection()->isGeographic())
+         {
+            gsd = projectionInfo->getDecimalDegreesPerPixel();
+            ul  = projectionInfo->ulGroundPt();
+         }
+         else
+         {
+            gsd = projectionInfo->getMetersPerPixel();
+            ul  = projectionInfo->ulEastingNorthingPt();
+         }
+
+         out << setiosflags(ios::fixed) << setprecision(15)
+             << gsd.x  << endl
+             << 0.0    << endl // rotation value X
+             << 0.0    << endl // rotation value y
+             << -gsd.y << endl
+             << ul.x   << endl
+             << ul.y   << endl;
+         
+         delete projectionInfo;
+      }
+   }
+   else
+   {
+      result = false;
+   }
+   if(proj)
+   {
+      delete proj;
+      proj = NULL;
+   }
+
+   out.close();
+   
+   return result;
+}
+
+void ossimTiffWorldFileWriter::getMetadatatypeList(
+   std::vector<ossimString>& metadatatypeList) const
+{
+   metadatatypeList.push_back(ossimString("tiff_world_file")); 
+}
+
+bool ossimTiffWorldFileWriter::hasMetadataType(
+   const ossimString& metadataType)const
+{
+   return (metadataType == "tiff_world_file");
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/metadata/ossimTiffWorldFileWriter.h b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimTiffWorldFileWriter.h
new file mode 100644
index 0000000000..58c34e8660
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/metadata/ossimTiffWorldFileWriter.h
@@ -0,0 +1,56 @@
+//*******************************************************************
+// Copyright (C) 2003 Storage Area Networks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Kenneth Melero (kmelero@sanz.com)
+//
+//*******************************************************************
+//  $Id: ossimTiffWorldFileWriter.h,v 1.7 2005/08/08 22:00:24 dburken Exp $
+
+#ifndef ossimTiffWorldFileWriter_H
+#define ossimTiffWorldFileWriter_H
+
+#include <imaging/metadata/ossimMetadataFileWriter.h>
+
+/** ossimTiffWorldFileWriter */
+class OSSIMDLLEXPORT ossimTiffWorldFileWriter : public ossimMetadataFileWriter
+{
+public:
+   
+   /** default constructor */
+   ossimTiffWorldFileWriter();
+
+   /** default constructor */
+   virtual ~ossimTiffWorldFileWriter();
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * Appends the writers image types to the "metadatatypeList".
+    * 
+    * @param metadatatypeList stl::vector<ossimString> list to append to.
+    *
+    * @note Appends to the list, does not clear it first.
+    */
+   virtual void getMetadatatypeList(
+      std::vector<ossimString>& metadatatypeList) const;
+
+   /**
+    * Satisfies pure virtual from ossimMetadataWriter base.
+    *
+    * @param imageType string representing image type.
+    *
+    * @return true if "metadataType" is supported by writer.
+    */
+   virtual bool hasMetadataType(const ossimString& metadataType)const;
+   
+private:
+   virtual bool writeFile();
+
+TYPE_DATA
+};
+
+#endif /* End of #ifndef ossimTiffWorldFileWriter_H */
diff --git a/Utilities/OSSIM/ossim_core/imaging/misc/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/misc/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/misc/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/misc/ossimPixelFlipper.cpp b/Utilities/OSSIM/ossim_core/imaging/misc/ossimPixelFlipper.cpp
new file mode 100644
index 0000000000..b2f16ac5e8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/misc/ossimPixelFlipper.cpp
@@ -0,0 +1,1216 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Filter to toggle pixel values.
+//
+//*************************************************************************
+// $Id: ossimPixelFlipper.cpp,v 1.23 2006/01/11 15:57:43 dburken Exp $
+
+#include <imaging/misc/ossimPixelFlipper.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimScopedLock.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/property/ossimStringProperty.h>
+#include <base/property/ossimNumericProperty.h>
+#include <base/common/ossimKeywordNames.h>
+
+RTTI_DEF1(ossimPixelFlipper, "ossimPixelFlipper", ossimImageSourceFilter)
+
+static ossimTrace traceDebug("ossimPixelFlipper:debug");
+
+static const char TARGET_VALUE_KW[]      = "target_value";
+static const char REPLACEMENT_VALUE_KW[] = "replacement_value";
+static const char CLAMP_VALUE_KW[]       = "clamp_value";
+static const char REPLACEMENT_MODE_KW[]  = "replacement_mode";
+static const char CLIP_MODE_KW[]  = "clip_mode";
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimPixelFlipper.cpp,v 1.23 2006/01/11 15:57:43 dburken Exp $";
+#endif
+
+ossimPixelFlipper::ossimPixelFlipper(ossimObject* owner)
+   :
+      ossimImageSourceFilter(owner),
+      theTargetValue(0.0),
+      theReplacementValue(1.0),
+      theClampValue(0.0),
+      theReplacementMode(ossimPixelFlipper::REPLACE_ALL_TARGETS),
+      theClipMode(ossimPixelFlipper::ossimPixelFlipperClipMode_NONE),
+      theMutex()
+
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimPixelFlipper::ossimPixelFlipper entered...\n";
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "OSSIM_ID:  " << OSSIM_ID << "\n";
+#endif      
+   }
+   
+   setDescription(ossimString("Pixel Flipper"));
+   enableSource();
+}
+
+ossimPixelFlipper::~ossimPixelFlipper()
+{}
+
+ossimRefPtr<ossimImageData> ossimPixelFlipper::getTile(
+   const ossimIrect& tile_rect, ossim_uint32 resLevel)
+{
+
+   if(!theInputConnection)
+   {
+      return 0;
+   }
+   // Fetch tile from pointer from the input source.
+   ossimRefPtr<ossimImageData> inputTile =
+      theInputConnection->getTile(tile_rect, resLevel);
+   
+   if (!inputTile.valid() || !isSourceEnabled()) return inputTile;
+   
+   if (!inputTile->getBuf()) return inputTile;
+   
+   // Lock for the length of this method.
+   ossimScopedLock<ossimMutex> scopeLock(theMutex);
+   
+   // Call the appropriate load method.
+   switch (inputTile->getScalarType())
+   {
+      
+      case OSSIM_UCHAR:
+      {
+         flipPixels(ossim_uint8(0), inputTile.get(), resLevel);
+         break;
+      }
+      
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         flipPixels(ossim_uint16(0), inputTile.get(), resLevel);
+         break;
+      }
+      
+      case OSSIM_SSHORT16:
+      {
+         flipPixels(ossim_sint16(0), inputTile.get(), resLevel);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         flipPixels(ossim_uint32(0), inputTile.get(), resLevel);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         flipPixels(ossim_sint32(0), inputTile.get(), resLevel);
+         break;
+      }
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         flipPixels(float(0), inputTile.get(), resLevel);
+         break;
+      }
+      
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         flipPixels(ossim_float64(0), inputTile.get(), resLevel);
+         break;
+      }
+      
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimPixelFlipper::getTile Unsupported scalar type!" << endl;
+         break;
+      }
+   }
+   
+   return inputTile;
+}
+
+template <class T>
+void ossimPixelFlipper::flipPixels(T dummy,
+                                   ossimImageData* inputTile,
+                                   ossim_uint32 resLevel)
+{
+   if (!inputTile) return;
+
+   T target      = static_cast<T>(theTargetValue);
+   T replacement = static_cast<T>(theReplacementValue);
+   T clamp       = static_cast<T>(theClampValue);
+   ossim_uint32 size   = inputTile->getSizePerBand();
+   ossim_uint32 bands  = inputTile->getNumberOfBands();
+   ossim_uint32 band;
+
+   bool do_clamp = (clamp > 0) ? true : false;
+
+   // Get pointers to data for each band.
+   T** buf = new T*[bands];
+
+   for(band=0; band<bands; ++band)
+   {
+      buf[band] = static_cast<T*>(inputTile->getBuf(band));
+   }
+
+   ossimIrect rect = inputTile->getImageRectangle();
+   ossimIpt ul = rect.ul();
+   ossimIpt origin = ul;
+   ossim_uint32 x=0;
+   ossim_uint32 y=0;
+   ossim_uint32 w = rect.width();
+   ossim_uint32 h = rect.height();
+   ossim_uint32 i = 0;   
+   bool replace = false;
+   bool needsTesting = false;
+   switch(theClipMode)
+   {
+      case  ossimPixelFlipperClipMode_BOUNDING_RECT:
+      {
+         if(resLevel < theBoundingRects.size())
+         {
+            if(!rect.intersects(theBoundingRects[resLevel]))
+            {
+               return;
+            }
+            else
+            {
+               needsTesting = !rect.completely_within(theBoundingRects[resLevel]);
+            }
+         }
+         break;
+      }
+      case  ossimPixelFlipperClipMode_VALID_VERTICES:
+      {
+         if(resLevel < theValidVertices.size())
+         {
+            bool ulFlag = theValidVertices[resLevel].isPointWithin(rect.ul());
+            bool urFlag = theValidVertices[resLevel].isPointWithin(rect.ur());
+            bool lrFlag = theValidVertices[resLevel].isPointWithin(rect.lr());
+            bool llFlag = theValidVertices[resLevel].isPointWithin(rect.ll());
+            if((!ulFlag)&&
+               (!urFlag)&&
+               (!lrFlag)&&
+               (!llFlag))
+            {
+               return; // none of the tile is inside so return
+            }
+            else
+            {
+               needsTesting = !(ulFlag&&urFlag&&lrFlag&&llFlag);
+            }
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+   switch (theReplacementMode)
+   {
+      case ossimPixelFlipper::REPLACE_PARTIAL_TARGETS:
+      {
+         i = 0;
+         if((theClipMode == ossimPixelFlipperClipMode_NONE)||(!needsTesting))
+         {
+            for (i=0; i<size; ++i)
+            {
+               // At least one band must NOT have target for replace to = true;
+               replace = false;
+               for (band=0; band<bands; ++band)
+               {
+                  if (buf[band][i] != target)
+                  {
+                     replace = true;
+                     break;
+                  }
+               }
+               if (replace)
+               {
+                  for (band=0; band<bands; ++band)
+                  {
+                     if (buf[band][i] == target) buf[band][i] = replacement;
+                  }
+               }
+            }
+         }
+         else
+         {
+            bool active;
+            origin.y = ul.y;
+            for(y = 0; y < h; ++y)
+            {
+               origin.x = ul.x;
+               for(x =0; x < w; ++x)
+               {
+                  active = true;
+                  switch(theClipMode)
+                  {
+                     case  ossimPixelFlipperClipMode_BOUNDING_RECT:
+                     {
+                        if(resLevel < theBoundingRects.size())
+                        {
+                           active = theBoundingRects[resLevel].pointWithin(origin);
+                        }
+                        break;
+                     }
+                     case  ossimPixelFlipperClipMode_VALID_VERTICES:
+                     {
+                        if(resLevel < theValidVertices.size())
+                        {
+                           active = theValidVertices[resLevel].isPointWithin(origin);
+                        }
+                        break;
+                     }
+                     default:
+                     {
+                        break;
+                     }
+                  }
+                  replace = false;
+                  if(active)
+                  {
+                     for (band=0; band<bands; ++band)
+                     {
+                        if (buf[band][i] != target)
+                        {
+                           replace = true;
+                           break;
+                        }
+                     }
+                  }
+                  if (replace)
+                  {
+                     for (band=0; band<bands; ++band)
+                     {
+                        if (buf[band][i] == target) buf[band][i] = replacement;
+                     }
+                  }
+                  
+                  ++i;
+                  ++origin.x;
+               }
+               ++origin.y;
+            }
+         }
+         break;
+      }
+      case ossimPixelFlipper::REPLACE_PARTIAL_TARGETS_ALL_BANDS:
+      {
+         i = 0;
+         if((theClipMode == ossimPixelFlipperClipMode_NONE)||(!needsTesting))
+         {
+            for (i=0; i<size; ++i)
+            {
+               // Must be at least one target but not all to replace all bands.
+               bool has_a_target = false;
+               replace      = false;
+               for (band=0; band<bands; ++band)
+               {
+                  if (buf[band][i] == target)
+                  {
+                     has_a_target = true;
+                     break;
+                  }
+               }
+               if (has_a_target)
+               {
+                  for (band=0; band<bands; ++band)
+                  {
+                     if (buf[band][i] != target)
+                     {
+                        replace = true;
+                        break;
+                     }
+                  }
+                  if (replace)
+                  {
+                     for (band=0; band<bands; ++band)
+                     {
+                        buf[band][i] = replacement;
+                     }
+                  }
+               }
+            }
+         }
+         else
+         {
+            bool active = true;
+            origin.y = ul.y;
+            for(y = 0; y < h; ++y)
+            {
+               origin.x = ul.x;
+               for(x =0; x < w; ++x)
+               {
+                  switch(theClipMode)
+                  {
+                     case  ossimPixelFlipperClipMode_BOUNDING_RECT:
+                     {
+                        if(resLevel < theBoundingRects.size())
+                        {
+                           active = theBoundingRects[resLevel].pointWithin(origin);
+                        }
+                        break;
+                     }
+                     case  ossimPixelFlipperClipMode_VALID_VERTICES:
+                     {
+                        if(resLevel < theValidVertices.size())
+                        {
+                           active = theValidVertices[resLevel].isPointWithin(origin);
+                        }
+                        break;
+                     }
+                     default:
+                     {
+                        break;
+                     }
+                  }
+                  bool has_a_target = false;
+                  replace      = false;
+                  if(active)
+                  {
+                     for (band=0; band<bands; ++band)
+                     {
+                        if (buf[band][i] == target)
+                        {
+                           has_a_target = true;
+                           break;
+                        }
+                     }
+                  }
+                  if (has_a_target)
+                  {
+                     for (band=0; band<bands; ++band)
+                     {
+                        if (buf[band][i] != target)
+                        {
+                           replace = true;
+                           break;
+                        }
+                     }
+                     if (replace)
+                     {
+                        for (band=0; band<bands; ++band)
+                        {
+                           buf[band][i] = replacement;
+                        }
+                     }
+                  }
+                  
+                  ++i;
+                  ++origin.x;
+               }
+               ++origin.y;
+            }
+         }
+         break;
+      }
+      case ossimPixelFlipper::REPLACE_FULL_TARGETS:
+      {
+         i = 0;
+         if((theClipMode == ossimPixelFlipperClipMode_NONE)||(!needsTesting))
+         {
+            for (i=0; i<size; ++i)
+            {
+               // All bands must have target for replace to = true.
+               replace = true;
+               
+               for (band=0; band<bands; ++band)
+               {
+                  if (buf[band][i] != target)
+                  {
+                     replace = false;
+                     break;
+                  }
+               }
+               if (replace)
+               {
+                  for (band=0; band<bands; ++band)
+                  {
+                     buf[band][i] = replacement;
+                  }
+               }
+            }
+         }
+         else
+         {
+            origin.y = ul.y;
+            for(y = 0; y < h; ++y)
+            {
+               origin.x = ul.x;
+               for(x =0; x < w; ++x)
+               {
+                  replace = true;
+                  switch(theClipMode)
+                  {
+                     case  ossimPixelFlipperClipMode_BOUNDING_RECT:
+                     {
+                        if(resLevel < theBoundingRects.size())
+                        {
+                           replace = theBoundingRects[resLevel].pointWithin(origin);
+                        }
+                        break;
+                     }
+                     case  ossimPixelFlipperClipMode_VALID_VERTICES:
+                     {
+                        if(resLevel < theValidVertices.size())
+                        {
+                           replace = theValidVertices[resLevel].isPointWithin(origin);
+                        }
+                        break;
+                     }
+                     default:
+                     {
+                        break;
+                     }
+                  }
+                  if(replace)
+                  {
+                     for (band=0; band<bands; ++band)
+                     {
+                        if (buf[band][i] != target)
+                        {
+                           replace = false;
+                           break;
+                        }
+                     }
+                  }
+                  
+                  if (replace)
+                  {
+                     for (band=0; band<bands; ++band)
+                     {
+                        buf[band][i] = replacement;
+                     }
+                  }
+                  ++i;
+                  ++origin.x;
+               }
+               ++origin.y;
+            }
+         }
+            
+         break;
+      }
+      default:  // REPLACE_ALL_TARGETS
+      {
+         i = 0;
+         if((theClipMode == ossimPixelFlipperClipMode_NONE)||(!needsTesting))
+         {
+            for(i = 0; i < size;++i)
+            {
+               for (band=0; band<bands; ++band)
+               {
+                  if (buf[band][i] == target) buf[band][i] = replacement;
+               }
+            }
+         }
+         else
+         {
+            origin.y = ul.y;
+            for(y = 0; y < h; ++y)
+            {
+               origin.x = ul.x;
+               for(x =0; x < w; ++x)
+               {
+                  replace = true;
+                  
+                  switch(theClipMode)
+                  {
+                     case  ossimPixelFlipperClipMode_BOUNDING_RECT:
+                     {
+                        if(resLevel < theBoundingRects.size())
+                        {
+                           replace = theBoundingRects[resLevel].pointWithin(origin);
+                        }
+                        break;
+                     }
+                     case  ossimPixelFlipperClipMode_VALID_VERTICES:
+                     {
+                        if(resLevel < theValidVertices.size())
+                        {
+                           replace = theValidVertices[resLevel].isPointWithin(origin);
+                        }
+                        break;
+                     }
+                     default:
+                     {
+                        break;
+                     }
+                  }
+                  if(replace)
+                  {
+                     for (band=0; band<bands; ++band)
+                     {
+                        if (buf[band][i] == target) buf[band][i] = replacement;
+                     }
+                  }
+                  ++i;
+                  ++origin.x;
+               }
+               ++origin.y;
+            }
+         }
+         break;
+      }
+
+      if (do_clamp)
+      {
+         for (i=0; i<size; ++i)
+         { 
+            for (band=0; band<bands; ++band)
+            {
+               if (buf[band][i] > clamp)
+               {
+                  buf[band][i] = clamp;
+               }
+            }
+         }
+      }
+   }
+   
+   delete [] buf;
+   inputTile->validate();
+}
+
+template <class T> void ossimPixelFlipper::clipTile(T dummy,
+                                                    ossimImageData* inputTile,
+                                                    ossim_uint32 resLevel)
+{
+   if(theClipMode == ossimPixelFlipperClipMode_NONE)
+   {
+      theClipTileBuffer = 0;
+      return;
+   }
+   if(!inputTile) return;
+   if(!inputTile->getBuf()||
+      (inputTile->getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return;
+   }
+   allocateClipTileBuffer(inputTile);
+
+
+   if(theClipTileBuffer.valid())
+   {
+      ossimIrect tileRect = inputTile->getImageRectangle();
+      // force to all nulls
+      theClipTileBuffer->setDataObjectStatus(OSSIM_FULL);
+      theClipTileBuffer->makeBlank();
+      
+      switch(theClipMode)
+      {
+         case ossimPixelFlipperClipMode_NONE:
+         {
+            break;
+         }
+         case ossimPixelFlipperClipMode_BOUNDING_RECT:
+         {
+            if(resLevel < theBoundingRects.size())
+            {
+               if(tileRect.completely_within(theBoundingRects[resLevel])||
+                  theBoundingRects[resLevel].hasNans())
+               {
+                  return;
+               }
+               else
+               {
+                  if(tileRect.intersects(theBoundingRects[resLevel]))
+                  {
+                     ossimIrect clipRect = tileRect.clipToRect(theBoundingRects[resLevel]);
+
+                     theClipTileBuffer->setImageRectangle(clipRect);
+                     
+                     theClipTileBuffer->loadTile(inputTile);
+                     inputTile->makeBlank();
+                     inputTile->loadTile(theClipTileBuffer.get());
+                     inputTile->validate();
+                  }
+                  else
+                  {
+                     inputTile->makeBlank();
+                  }
+               }
+            }
+            break;
+         }
+         case ossimPixelFlipperClipMode_VALID_VERTICES:
+         {
+            if(resLevel < theValidVertices.size())
+            {
+               const ossimPolygon& p = theValidVertices[resLevel];
+               bool ulWithin = p.isPointWithin(tileRect.ul());
+               bool urWithin = p.isPointWithin(tileRect.ur());
+               bool lrWithin = p.isPointWithin(tileRect.lr());
+               bool llWithin = p.isPointWithin(tileRect.ll());
+               
+               if(ulWithin&&
+                  urWithin&&
+                  lrWithin&&
+                  llWithin)
+               {
+                  return;
+               }
+               else if(!(ulWithin|| // if none are in
+                         urWithin||
+                         lrWithin||
+                         llWithin))
+               {
+                  inputTile->makeBlank();
+                  return;
+               }
+               else
+               {
+                  ossimIpt ul = tileRect.ul();
+                  ossimIpt origin;
+                  ossim_uint32 x = 0;
+                  ossim_uint32 y = 0;
+                  ossim_uint32 w = inputTile->getWidth();
+                  ossim_uint32 h = inputTile->getHeight();
+                  ossim_uint32 offset = 0;
+                  origin.y = ul.y;
+                  for(y = 0; y < h; ++y)
+                  {
+                     origin.x = ul.x;
+                     for(x = 0; x < w; ++x)
+                     {
+                        
+                        if(!p.isPointWithin(origin))
+                        {
+                           inputTile->setNull(offset);
+                        }
+                        ++offset;
+                        ++origin.x;
+                     }
+                     ++origin.y;
+                  }
+               }
+            }
+            break;
+         }
+      }
+   }
+}
+
+
+void ossimPixelFlipper::allocateClipTileBuffer(ossimRefPtr<ossimImageData> inputImage)
+{
+   if(inputImage.valid())
+   {
+      bool needDupFlag = false;
+      if(theClipTileBuffer.valid())
+      {
+         if((theClipTileBuffer->getScalarType() != inputImage->getScalarType())||
+            theClipTileBuffer->getNumberOfBands() != theClipTileBuffer->getNumberOfBands())
+         {
+            needDupFlag = true;
+         }
+         else
+         {
+            theClipTileBuffer->setImageRectangle(inputImage->getImageRectangle());
+         }
+      }
+      else
+      {
+         needDupFlag = true;
+      }
+      if(needDupFlag)
+      {
+         theClipTileBuffer = (ossimImageData*)inputImage->dup();
+      }
+   }
+}
+
+void ossimPixelFlipper::initialize()
+{
+   theMutex.lock();
+   ossimImageSourceFilter::initialize();
+   theValidVertices.clear();
+   theBoundingRects.clear();
+
+   ossim_uint32 rlevels = getNumberOfDecimationLevels();
+   ossim_uint32 idx = 0;
+
+   if(rlevels)
+   {
+      if(theValidVertices.size() != rlevels)
+      {
+         theValidVertices.resize(rlevels);
+      }
+      if(theBoundingRects.size() != rlevels)
+      {
+         theBoundingRects.resize(rlevels);
+      }
+      for(idx = 0; idx < rlevels; ++idx)
+      {
+         std::vector<ossimIpt> validVertices;
+         getValidImageVertices(validVertices,
+                               OSSIM_CLOCKWISE_ORDER,
+                               idx);
+         theValidVertices[idx] = ossimPolygon(validVertices);
+         theBoundingRects[idx] = getBoundingRect(idx);
+      }
+   }
+   
+   theMutex.unlock();
+}
+
+ossimScalarType ossimPixelFlipper::getOutputScalarType() const
+{
+   if(theInputConnection)
+   {
+      ossimScalarType scalar = theInputConnection->getOutputScalarType();
+      {
+         if (scalar == OSSIM_USHORT16 && theClampValue == 2047.0)
+         {
+            //---
+            // Special case:
+            // We have an unsigned 16 bit type but we want to call it
+            // USHORT11 ( (2^11- 1) = 2047 ).
+            //---
+            return OSSIM_USHORT11;
+         }
+         return scalar;
+      }
+   }
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+ossim_float64 ossimPixelFlipper::getMaxPixelValue (ossim_uint32 band) const
+{
+   const ossim_float64 MIN = ossimImageSourceFilter::getMinPixelValue(band);
+   const ossim_float64 MAX = ossimImageSourceFilter::getMaxPixelValue(band);
+
+   if (theClampValue > MIN && theClampValue < MAX)
+   {
+      return theClampValue;
+   }
+
+   return MAX;
+}
+
+bool ossimPixelFlipper::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   const char* lookupReturn;
+   
+   lookupReturn = kwl.find(prefix, TARGET_VALUE_KW);
+   if(lookupReturn)
+   {
+      setTargetValue(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(prefix, REPLACEMENT_VALUE_KW);
+   if(lookupReturn)
+   {
+      setReplacementValue(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(prefix, CLAMP_VALUE_KW);
+   if(lookupReturn)
+   {
+      setClampValue(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(prefix, REPLACEMENT_MODE_KW);
+   if(lookupReturn)
+   {
+      ossimString modeString = lookupReturn;
+      setReplacementMode(modeString);
+   }
+   lookupReturn = kwl.find(prefix, CLIP_MODE_KW);
+   if(lookupReturn)
+   {
+      ossimString modeString = lookupReturn;
+      setClipMode(modeString);
+   }
+
+   bool status = ossimImageSourceFilter::loadState(kwl, prefix);
+
+   if (traceDebug())
+   {
+      print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+
+   return status;
+}
+
+bool ossimPixelFlipper::saveState(ossimKeywordlist& kwl,
+                                 const char* prefix) const
+{
+   // Call the base class saveState.
+   ossimImageSourceFilter::saveState(kwl, prefix);
+
+   kwl.add(prefix, TARGET_VALUE_KW,      theTargetValue);
+   kwl.add(prefix, REPLACEMENT_VALUE_KW, theReplacementValue);
+   kwl.add(prefix, CLAMP_VALUE_KW,       theClampValue);
+   kwl.add(prefix, REPLACEMENT_MODE_KW,  getReplacementModeString().c_str());
+   kwl.add(prefix, CLIP_MODE_KW,  getClipModeString().c_str());
+   
+   return true;
+}
+
+void ossimPixelFlipper::setTargetValue(ossim_float64 target_value)
+{
+   theMutex.lock();
+   
+   if (inRange(target_value))
+   {
+      theTargetValue = target_value;
+   }
+
+   theMutex.unlock();
+}
+
+void ossimPixelFlipper::setReplacementValue(ossim_float64 replacement_value)
+{
+   theMutex.lock();
+   
+   if (inRange(replacement_value))
+   {
+      theReplacementValue = replacement_value;
+   }
+
+   theMutex.unlock();
+}
+
+void ossimPixelFlipper::setClampValue(ossim_float64 clamp_value)
+{
+   theMutex.lock();
+   
+   if (inRange(clamp_value))
+   {
+      theClampValue = clamp_value;
+   }
+
+   theMutex.unlock();
+}
+
+void ossimPixelFlipper::setReplacementMode(
+   ossimPixelFlipper::ReplacementMode mode)
+{
+   theMutex.lock();
+   theReplacementMode = mode;
+   theMutex.unlock();
+}
+
+void ossimPixelFlipper::setReplacementMode(const ossimString& modeString)
+{
+   theMutex.lock();
+
+   ossimString mode = modeString;
+   mode.downcase();
+   if (mode == "replace_partial_targets")
+   {
+      theReplacementMode = ossimPixelFlipper::REPLACE_PARTIAL_TARGETS;
+   }
+   else if (mode == "replace_partial_targets_all_bands")
+   {
+      theReplacementMode =
+         ossimPixelFlipper::REPLACE_PARTIAL_TARGETS_ALL_BANDS;
+   }
+   else if (mode == "replace_full_targets")
+   {
+      theReplacementMode = ossimPixelFlipper::REPLACE_FULL_TARGETS;
+   }
+   else if (mode == "replace_all_targets")
+   {
+      theReplacementMode = ossimPixelFlipper::REPLACE_ALL_TARGETS;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimPixelFlipper::setReplacementMode warning:\n"
+         << "Invalide mode:  " << modeString
+         << endl;
+   }
+
+   theMutex.unlock();
+}
+
+void ossimPixelFlipper::setClipMode(ossimPixelFlipper::ClipMode mode)
+{
+   theMutex.lock();
+   theClipMode = mode;
+   theMutex.unlock();
+}
+
+void ossimPixelFlipper::setClipMode(const ossimString& modeString)
+{
+   ossimString mode = modeString;
+   mode.downcase();
+   if (mode == "none")
+   {
+      setClipMode(ossimPixelFlipperClipMode_NONE);
+   }
+   else if (mode == "bounding_rect")
+   {
+      setClipMode(ossimPixelFlipperClipMode_BOUNDING_RECT);
+   }
+   else if (mode == "valid_vertices")
+   {
+      setClipMode(ossimPixelFlipperClipMode_VALID_VERTICES);
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimPixelFlipper::setClipMode warning:\n"
+         << "Invalide mode:  " << modeString
+         << endl;
+   }
+}
+
+ossim_float64 ossimPixelFlipper::getClampValue() const
+{
+   return theClampValue;
+}
+
+
+ossim_float64 ossimPixelFlipper::getTargetValue() const
+{
+   return theTargetValue;
+}
+
+ossim_float64 ossimPixelFlipper::getReplacementValue() const
+{
+   return theReplacementValue;
+}
+
+ossimPixelFlipper::ReplacementMode ossimPixelFlipper::getReplacementMode()  const
+{
+   return theReplacementMode;
+}
+   
+ossimString ossimPixelFlipper::getReplacementModeString()  const
+{
+   switch(theReplacementMode)
+   {
+      case REPLACE_ALL_TARGETS:
+         return ossimString("replace_all_targets");
+      case REPLACE_PARTIAL_TARGETS:
+         return ossimString("replace_partial_targets");
+      case REPLACE_PARTIAL_TARGETS_ALL_BANDS:
+         return ossimString("replace_partial_targets_all_bands");
+      case REPLACE_FULL_TARGETS:
+         return ossimString("replace_full_targets");
+      default:
+         break;
+   }
+
+   return ossimString("UNKNOWN_MODE");
+}
+
+ossimString ossimPixelFlipper::getClipModeString()  const
+{
+   switch(theClipMode)
+   {
+      case ossimPixelFlipperClipMode_NONE:
+      {
+         return ossimString("none");
+      }
+      case ossimPixelFlipperClipMode_BOUNDING_RECT:
+      {
+         return ossimString("bounding_rect");
+      }
+      case REPLACE_PARTIAL_TARGETS_ALL_BANDS:
+      {
+         return ossimString("valid_vertices");
+      }
+      default:
+      {
+         break;
+      }
+   }
+
+   return ossimString("none");
+}
+
+ossimPixelFlipper::ClipMode ossimPixelFlipper::getClipMode() const
+{
+   return theClipMode;
+}
+
+std::ostream& ossimPixelFlipper::print(std::ostream& out) const
+{
+   out << "ossimPixelFlipper::print:"
+       << "\ntarget value:       " << theTargetValue
+       << "\nreplacement value:  " << theReplacementValue
+       << "\nclamp value:        " << theClampValue
+       << "\nreplacement mode:   " << getReplacementModeString().c_str()
+       << "\nclip_mode:          " << getClipModeString().c_str()
+      << endl;
+   return out;
+}
+
+ossimRefPtr<ossimProperty> ossimPixelFlipper::getProperty(
+   const ossimString& name)const
+{
+   // Lock for the length of this method.
+   ossimScopedLock<ossimMutex> scopeLock(theMutex);
+
+   if (name == TARGET_VALUE_KW)
+   {
+      ossimProperty* p =
+         new ossimNumericProperty(name,
+                                  ossimString::toString(theTargetValue));
+      p->setCacheRefreshBit();
+      return ossimRefPtr<ossimProperty>(p);
+   }
+   else if (name == REPLACEMENT_VALUE_KW)
+   {
+      ossimProperty* p =
+         new ossimNumericProperty(name,
+                                  ossimString::toString(theReplacementValue));
+       p->setCacheRefreshBit();
+      return ossimRefPtr<ossimProperty>(p);
+   }
+   else if (name == CLAMP_VALUE_KW)
+   {
+      ossimProperty* p =
+         new ossimNumericProperty(name, ossimString::toString(theClampValue));
+       p->setCacheRefreshBit();
+      return ossimRefPtr<ossimProperty>(p);
+   }
+   else if (name == REPLACEMENT_MODE_KW)
+   {
+      vector<ossimString> constraintList(4);
+      constraintList[0] = "replace_all_targets";
+      constraintList[1] = "replace_partial_targets";
+      constraintList[2] = "replace_partial_targets_all_bands";
+      constraintList[3] = "replace_full_targets";
+      
+      ossimStringProperty* p =
+         new ossimStringProperty(name,
+                                 getReplacementModeString(),
+                                 false,
+                                 constraintList);
+      p->setCacheRefreshBit();
+      return ossimRefPtr<ossimProperty>(p);
+   }
+   else if (name == CLIP_MODE_KW)
+   {
+      vector<ossimString> constraintList(3);
+      constraintList[0] = "none";
+      constraintList[1] = "bounding_rect";
+      constraintList[2] = "valid_vertices";
+      
+      ossimStringProperty* p =
+         new ossimStringProperty(name,
+                                 getClipModeString(),
+                                 false,
+                                 constraintList);
+      p->setCacheRefreshBit();
+      return ossimRefPtr<ossimProperty>(p);
+   }
+   ossimRefPtr<ossimProperty> result = ossimSource::getProperty(name);
+
+   if(result.valid())
+   {
+      if(result->getName() == ossimKeywordNames::ENABLED_KW)
+      {
+         result->clearChangeType();
+         
+         // we will at least say its a radiometric change
+         //
+         result->setCacheRefreshBit();
+      }
+   }
+
+   return result;
+}
+
+void ossimPixelFlipper::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if (!property) return;
+
+   ossimString os = property->valueToString();
+   
+   ossimString name = property->getName();
+   if (name == TARGET_VALUE_KW)
+   {
+      setTargetValue(os.toDouble());
+   }
+   else if  (name == REPLACEMENT_VALUE_KW)
+   {
+      setReplacementValue(os.toDouble());
+   }
+   else if  (name == CLAMP_VALUE_KW)
+   {
+      setClampValue(os.toDouble());
+   }
+   else if  (name == REPLACEMENT_MODE_KW)
+   {
+      setReplacementMode(os);
+   }
+   else if  (name == CLIP_MODE_KW)
+   {
+      setClipMode(os);
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+void ossimPixelFlipper::getPropertyNames(
+   std::vector<ossimString>& propertyNames)const
+{
+   propertyNames.push_back(TARGET_VALUE_KW);
+   propertyNames.push_back(REPLACEMENT_VALUE_KW);
+   propertyNames.push_back(CLAMP_VALUE_KW);
+   propertyNames.push_back(REPLACEMENT_MODE_KW);
+   propertyNames.push_back(CLIP_MODE_KW);
+   
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+}
+
+ossimString ossimPixelFlipper::getShortName()const
+{
+   return ossimString("Pixel flipper");
+}
+
+bool ossimPixelFlipper::inRange(ossim_float64 value) const
+{
+   if (!theInputConnection)
+   {
+      //---
+      // Not initialized yet...  We're going to return true so that things
+      // like loadState work with the assumption that the caller know's
+      // the correct range.  This check is really intended for an uncheck
+      // range on the gui side.
+      //---
+      return true;
+   }
+   
+   const ossim_float64 NULL_PIX = ossimImageSourceFilter::getNullPixelValue();
+   const ossim_float64 MIN_PIX  = ossimImageSourceFilter::getMinPixelValue();
+   const ossim_float64 MAX_PIX  = ossimImageSourceFilter::getMaxPixelValue();
+
+   if ( (value == NULL_PIX) || ((value >= MIN_PIX) && (value <= MAX_PIX)) )
+   {
+      return true;
+   }
+
+   ossimNotify(ossimNotifyLevel_WARN)
+      << "\nossimPixelFlipper::inRange WARNING:"
+      << "\nvalue \"" << value
+      << "\" is out of range!"
+      << "\nInput source null = " << NULL_PIX
+      << "\nInput source min  = " << MIN_PIX
+      << "\nInput source max  = " << MAX_PIX
+      << endl;
+
+   return false;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/misc/ossimPixelFlipper.h b/Utilities/OSSIM/ossim_core/imaging/misc/ossimPixelFlipper.h
new file mode 100644
index 0000000000..d9b8f42ad7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/misc/ossimPixelFlipper.h
@@ -0,0 +1,246 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class to scan pixels and flip target dn pixel value to new dn pixel value.
+// This was written to fix partial null pixels.
+// 
+//*************************************************************************
+// $Id: ossimPixelFlipper.h,v 1.16 2005/12/09 12:43:39 gpotts Exp $
+#ifndef ossimPixelFlipper_HEADER
+#define ossimPixelFlipper_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <base/data_types/ossimPolygon.h>
+#include <base/common/ossimMutex.h>
+
+/**
+ *  Class to scan pixels and flip target dn value to a replacement dn
+ *  value.
+ *
+ *  This was written to fix problems with null pixels, i.e. an image has a
+ *  digital number(dn) of 255 for null and it is desired to use a dn of 0 as
+ *  a null.  This can really be used to flip any pixel value to another.
+ *
+ *  @note This filter currently works on the input tile directly and does
+ *  not copy the data.
+ *
+ *  @see theReplacementMode data member documentation for more info.
+ */
+class ossimPixelFlipper : public ossimImageSourceFilter
+{
+public:
+   
+   enum ReplacementMode
+   {
+      /**
+       * Any pixel with dn of target will be replaced. (default)
+       */
+      REPLACE_ALL_TARGETS                = 0,
+      
+      /**
+       * Target will be replaced only at least one subpixel(band) does not have
+       * the target.
+       */
+      REPLACE_PARTIAL_TARGETS            = 1,
+
+      /**
+       * All bands will be replaced if any band has target but not all.
+       */
+      REPLACE_PARTIAL_TARGETS_ALL_BANDS  = 2,
+
+      /**
+       * Target will be repaced only if all subpixels(bands) have the target.
+       */
+      REPLACE_FULL_TARGETS               = 3
+   };
+   enum ClipMode
+   {
+      ossimPixelFlipperClipMode_NONE = 0,
+      ossimPixelFlipperClipMode_BOUNDING_RECT  = 1,
+      ossimPixelFlipperClipMode_VALID_VERTICES = 2
+   };
+   /** default constructor */
+   ossimPixelFlipper(ossimObject* owner=NULL);
+
+   /** destructor */
+   virtual ~ossimPixelFlipper();
+
+   /** @return "Pixel flipper" as an ossimString. */
+   virtual ossimString getShortName()const;
+
+   /** Initializes the state of the object from theInputConnection. */
+   virtual void initialize();
+
+   /**
+    * @param tile_rect Rectangle to fill tile with.
+    * 
+    * @param resLevel Reduced resolution level to grab from.
+    * 
+    * @return ossimRefPtr<ossimImageData> This is tile that was filled with
+    * tile_rect.
+    *
+    * @note Callers should check the ossimRefPtr::valid method.
+    * The internal pointer of the ossimRefPtr<ossimImageData> can be
+    * null if the tile_rect did not intersect the input connection's
+    * bounding rectangle.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual ossimScalarType getOutputScalarType() const;
+   virtual ossim_float64 getMaxPixelValue (ossim_uint32 band = 0 ) const;
+      
+   virtual std::ostream& print(std::ostream& out) const;
+
+   /** @param target_value This is the value to flip. */
+   void setTargetValue(ossim_float64 target_value);
+
+   /** @param replacement_value This is the value to flip target to. */
+   void setReplacementValue(ossim_float64 replacement_value);
+
+
+   /** @see enum ReplacementMode */
+   void setReplacementMode(ossimPixelFlipper::ReplacementMode mode);
+   void setReplacementMode(const ossimString& modeString);
+
+   void setClipMode(const ossimString& modeString);
+   void setClipMode(ossimPixelFlipper::ClipMode mode);
+   
+   /**
+    * @param clamp_value If set all pixel values above this range will
+    * be clamped to clamp_value.  Must be less than max pixel value of the
+    * input and cannot be null.
+    */
+   void setClampValue(ossim_float64 clamp_value);
+
+   ossim_float64 getTargetValue()      const;
+   ossim_float64 getReplacementValue() const;
+   ossim_float64 getClampValue() const;
+   ossimPixelFlipper::ReplacementMode getReplacementMode()  const;
+   ossimString getReplacementModeString() const;
+   ossimString getClipModeString() const;
+   ossimPixelFlipper::ClipMode getClipMode() const;
+
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   
+protected:
+   template <class T> void flipPixels(T dummy,
+                                      ossimImageData* inpuTile,
+                                      ossim_uint32 resLevel);
+
+   template <class T> void clipTile(T dummy,
+                                    ossimImageData* inpuTile,
+                                    ossim_uint32 resLevel);
+
+   /**
+    * Verifies pixel is in range.
+    * @return Returns true if in range else false.
+    */
+   bool inRange(ossim_float64 value) const;
+
+   void allocateClipTileBuffer(ossimRefPtr<ossimImageData> inputImage);
+   /** The value to replace. */
+   ossim_float64 theTargetValue;
+
+   /** The replacement value. */
+   ossim_float64 theReplacementValue;
+
+   /**
+    * If set and not > max pixel values any values higher than theClampValue
+    * will be clamped to theClampValue.
+    */
+   ossim_float64 theClampValue;
+
+   
+   /**
+    * Target Replacement Mode:
+    * 
+    * If mode is REPLACE_ALL_TARGETS (default):
+    * Any pixel with dn of target will be replaced.
+    *
+    * If mode is REPLACE_PARTIAL_TARGETS:
+    * Target will be replaced only at least one subpixel(band) does not have
+    * the target.
+    *
+    * If mode is REPLACE_BANDS_PARTIAL_TARGETS_ALL_BANDS:
+    * All bands will be replaced if any band has target but not all.
+    *
+    * If mode is REPLACE_FULL_TARGETS:
+    * Target will be repaced only if all subpixels(bands) have the target.
+    *
+    * Example:
+    * target      = 0
+    * replacement = 1
+    * Pixel at (0, 0) r=0, g=0,  b=0
+    * Pixel at (0, 1) r=0, g=30, b=21
+    * 
+    * Mode is REPLACE_ALL_TARGETS:
+    * Pixel at (0, 0) becomes  r=1, g=1,  b=1
+    * Pixel at (0, 1) becomes  r=1, g=30, b=21
+    * 
+    * Mode is REPLACE_PARTIAL_TARGETS:
+    * Pixel at (0, 0) remains  r=0, g=0,  b=0
+    * Pixel at (0, 1) becomes  r=1, g=30, b=21
+    *
+    * Mode is REPLACE_PARTIAL_TARGETS_ALL_BANDS:
+    * Pixel at (0, 0) remains  r=0, g=0,  b=0
+    * Pixel at (0, 1) becomes  r=1, g=1,  b=1
+    *
+    * Mode is REPLACE_FULL_TARGETS:
+    * Pixel at (0, 0) becomes  r=1, g=1,  b=1
+    * Pixel at (0, 1) remains  r=0, g=30, b=21
+    *
+    * Default mode is REPLACE_ALL_TARGETS.
+    */
+   ReplacementMode theReplacementMode;
+
+   /**
+    * Clip mode
+    *
+    * This will flip nulls any pixel value outside the specified mode.
+    *
+    * Valid modes are:
+    *
+    * none
+    * bounding_rect
+    * valid_vertices
+    *
+    * if the mode is "none" then nothing is done.
+    * if the mode is "bounding_rect" then the bounding rect for the requested rlevel
+    *                is used and every pixel outside that   
+    */
+   ClipMode        theClipMode;
+   
+   /** For lock and unlock. */
+   mutable ossimMutex      theMutex;
+
+   mutable std::vector<ossimPolygon> theValidVertices;
+   mutable std::vector<ossimIrect>   theBoundingRects;
+
+   ossimRefPtr<ossimImageData> theClipTileBuffer;
+   
+   TYPE_DATA
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/misc/ossimVertexExtractor.cpp b/Utilities/OSSIM/ossim_core/imaging/misc/ossimVertexExtractor.cpp
new file mode 100644
index 0000000000..e65e027786
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/misc/ossimVertexExtractor.cpp
@@ -0,0 +1,1962 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: David Burken
+// TR # 136 kminear      Fix extractVertices method
+//
+//*************************************************************************
+// $Id: ossimVertexExtractor.cpp,v 1.30 2005/02/11 15:07:32 dburken Exp $
+
+#include <fstream>
+using namespace std;
+
+#include <imaging/misc/ossimVertexExtractor.h>
+#include <imaging/ossimImageSource.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+static ossimTrace traceDebug("ossimVertexExtractor:degug");
+
+RTTI_DEF2(ossimVertexExtractor, "ossimVertexExtractor",
+          ossimSource, ossimProcessInterface);
+
+ossimVertexExtractor::ossimVertexExtractor(ossimImageSource* inputSource)
+      :
+      ossimOutputSource(NULL, // owner
+                        1,
+                        0,
+                        true,
+                        true),
+      ossimProcessInterface(),
+      theAreaOfInterest(),
+      theFilename(ossimFilename::NIL),
+      theFileStream(),
+      theVertice(4),
+      theLeftEdge(NULL),
+      theRightEdge(NULL)
+{
+   if (inputSource == NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimVertexExtractor::ossimVertexExtractor ERROR"
+                                         << "\nNULL input image source passed to constructor!"
+                                         << std::endl;
+   }
+
+   connectMyInputTo(0, inputSource);
+//   theInputObjectList[0] = inputSource;
+   theAreaOfInterest.makeNan();
+}
+
+ossimVertexExtractor::~ossimVertexExtractor()
+{
+   if (theLeftEdge)
+   {
+      delete [] theLeftEdge;
+      theLeftEdge = NULL;
+   }
+   if (theRightEdge)
+   {
+      delete [] theRightEdge;
+      theRightEdge = NULL;
+   }
+}
+
+bool ossimVertexExtractor::execute()
+{
+   static const char MODULE[] = "ossimVertexExtractor::execute";
+
+   if (traceDebug()) CLOG << " Entered..." << endl;
+   
+   if (theFilename == ossimFilename::NIL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimVertexExtractor::execute WARNING:"
+                                         << "\nOutput file name is empty.  Use setFilename method..."
+                                         << std::endl;
+      return false;
+   }
+
+   if (theAreaOfInterest.isNan())
+   {
+      ossimNotify(ossimNotifyLevel_NOTICE) << MODULE << " NOTICE ossimVertexExtractor::execute:"
+                                           << "\nArea of interest is not set.  Use setAreaOfInterest method..."
+                                           << "\nDefaulting to bounding rectangle of input source."
+                                           << std::endl;
+      ossimImageSource* src = reinterpret_cast<ossimImageSource*>(getInput(0));
+      theAreaOfInterest = src->getBoundingRect(0);
+   }
+
+   setProcessStatus(ossimProcessInterface::PROCESS_STATUS_EXECUTING);
+   
+   if (scanForEdges())
+   {
+      if (extractVertices())
+      {
+         writeVertices();
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   setProcessStatus(ossimProcessInterface::PROCESS_STATUS_NOT_EXECUTING);
+
+   if (traceDebug()) CLOG << " Exited..." << endl;
+
+   return true;
+}
+
+bool ossimVertexExtractor::scanForEdges()
+{
+   static const char MODULE[] = "ossimVertexExtractor::scanForEdges";
+
+   if (traceDebug()) CLOG << " Entered..." << endl;
+
+   ossimImageSource* src = reinterpret_cast<ossimImageSource*>(getInput(0));
+   if (!src)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "WARN ossimVertexExtractor::scanForEdges():"
+         << "\nInput source is null.  Returning..." << std::endl;
+      return false;
+   }
+   
+   // Allocate the arrays to hold the edges.
+   if (theLeftEdge)  delete [] theLeftEdge;
+   if (theRightEdge) delete [] theRightEdge;
+   theLeftEdge  = new ossim_int32[theAreaOfInterest.height()];
+   theRightEdge = new ossim_int32[theAreaOfInterest.height()];
+   for (ossim_int32 i=0; i<(int)theAreaOfInterest.height(); ++i)
+   {
+      theLeftEdge[i]  = OSSIM_INT_NAN;
+      theRightEdge[i] = OSSIM_INT_NAN;
+   }
+   
+   // Some constants needed throughout...
+   const ossim_int32 TILE_HEIGHT    = src->getTileHeight();
+   const ossim_int32 TILE_WIDTH     = src->getTileWidth();
+   const ossim_int32 START_LINE = theAreaOfInterest.ul().y;
+   const ossim_int32 STOP_LINE  = theAreaOfInterest.lr().y;
+   const ossim_int32 START_SAMP = theAreaOfInterest.ul().x;
+   const ossim_int32 STOP_SAMP  = theAreaOfInterest.lr().x;
+
+   // For percent complete status.
+   double total_tiles_y_dir = theAreaOfInterest.height() / TILE_HEIGHT;
+   if (theAreaOfInterest.height() % TILE_HEIGHT) total_tiles_y_dir += 1.0;
+   double tiles_processed = 0.0;
+
+   // Set the status message to be "scanning source for edges..."
+   ossimNotify(ossimNotifyLevel_INFO) << "Scanning image source for edges..." << std::endl;
+   
+   // Start off with a percent complete at 0...
+   setPercentComplete(0.0);
+
+   // Start of loop to get the left edges.
+   
+   // Tile loop in line direction through area of interest.
+
+   for (ossim_int32 line = START_LINE; line < STOP_LINE; line += TILE_HEIGHT)
+   {
+      const ossim_int32 START_INDEX = line - START_LINE;
+      const ossim_int32 STOP_INDEX  = ( (line+TILE_HEIGHT-1) < STOP_LINE ) ?
+         (START_INDEX+TILE_HEIGHT-1) :
+         (theAreaOfInterest.height()-1);
+      const ossim_int32 TILE_LINE_STOP = ((line+TILE_HEIGHT-1) < STOP_LINE) ?
+         (line+TILE_HEIGHT-1) :  STOP_LINE;
+      
+      // See if all the edges have been found for these tile lines.
+      bool all_edges_found  = true;
+      for (ossim_int32 i = START_INDEX; i <= STOP_INDEX; ++i)
+      {
+         if (theLeftEdge[i] == OSSIM_INT_NAN)
+         {
+            all_edges_found = false;
+            break;
+         }
+      }
+      
+      // Extract the left edges...
+      if (all_edges_found == false)
+      {
+         //***
+         // Tile loop in sample direction through area of interest
+         // (left edges).
+         //***
+         for (ossim_int32 samp = START_SAMP; samp < STOP_SAMP; samp += TILE_WIDTH)
+         {
+            // Get the tile.
+            ossimRefPtr<ossimImageData> id =
+               src->getTile(ossimIpt(samp, line));
+            
+            if (!id.valid() || id->getDataObjectStatus() == OSSIM_NULL ||
+                id->getDataObjectStatus() == OSSIM_EMPTY)
+            {
+               continue; // Nothing to do...
+            }
+            
+            // Line loop through tile.
+            const ossim_int32 TILE_SAMP_STOP = ((samp+TILE_WIDTH-1) < STOP_SAMP) ?
+               (samp+TILE_WIDTH-1) : STOP_SAMP;
+            
+            for (ossim_int32 y = line; y <= TILE_LINE_STOP; ++y)
+            {
+               ossim_int32 edge_index = y - START_LINE;
+               if (theLeftEdge[edge_index] == OSSIM_INT_NAN)
+               {
+                  for (ossim_int32 x = samp; x <= TILE_SAMP_STOP; ++x)
+                  {
+                     if (! (id->isNull(ossimIpt(x,y))))
+                     {
+                        // Capture the first valid pixel.
+                        theLeftEdge[edge_index] = x - START_SAMP;
+                        break;
+                     }
+                  }
+               }
+            }
+         }  // End of tile loop in sample direction through area of interest.
+      }  // End of (all_lines_checked == false) (left edges)
+
+      // See if all the right edges have been found for these tile lines.
+      all_edges_found = true;
+      for (ossim_int32 i = START_INDEX; i <= STOP_INDEX; ++i)
+      {
+         if (theRightEdge[i] == OSSIM_INT_NAN)
+         {
+            all_edges_found = false;
+            break;
+         }
+      }
+
+      // Extract the right edges...
+      if (all_edges_found == false)
+      {
+         //***
+         // Tile loop in sample direction through area of interest
+         // (right edges).
+         //***
+
+         // Get the x origin of the last tile in a row.
+         const ossim_int32 END_TILE_X = START_SAMP + ((theAreaOfInterest.width()/
+                                                 TILE_WIDTH)*TILE_WIDTH);
+         
+
+         for (ossim_int32 samp = END_TILE_X; samp >= START_SAMP; samp -= TILE_WIDTH)
+         {
+            // Get the tile.
+            ossimRefPtr<ossimImageData> id =
+               src->getTile(ossimIpt(samp, line));
+            
+            if (!id.valid() || id->getDataObjectStatus() == OSSIM_NULL ||
+                id->getDataObjectStatus() == OSSIM_EMPTY)
+            {
+               continue; // Nothing to do...
+            }
+            
+            // Line loop through tile.
+            const ossim_int32 TILE_SAMP_STOP = ((samp+TILE_WIDTH-1) < STOP_SAMP) ?
+               (samp+TILE_WIDTH-1) : STOP_SAMP;
+            
+            for (ossim_int32 y = line; y <= TILE_LINE_STOP; ++y)
+            {
+               ossim_int32 edge_index = y - START_LINE;
+               if (theRightEdge[edge_index] == OSSIM_INT_NAN)
+               {
+                  for (ossim_int32 x = TILE_SAMP_STOP; x >= samp; --x)
+                  {
+                     if (! (id->isNull(ossimIpt(x,y))))
+                     {
+                        // Capture the first valid pixel.
+                        theRightEdge[edge_index] = x - START_SAMP;
+                        break;
+                     }
+                  }
+               }
+            }
+            
+         }  // End of tile loop in sample direction through area of interest.
+         
+      }  // End of (all_lines_checked == false)
+
+      // Set the percent complete.
+      tiles_processed += 1.0;
+      setPercentComplete(tiles_processed/total_tiles_y_dir*100.0);
+   }  // End of loop through tiles in line direction.
+
+   setPercentComplete(100.0);
+      
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:" << endl;
+      for (ossim_int32 i=0; i<(int)theAreaOfInterest.height(); ++i)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: left[" << i << "]:  "
+                                             << theLeftEdge[i]
+                                             << " right[" << i << "]:  "
+                                             << theRightEdge[i]
+                                             << std::endl;
+      }
+   }
+
+   
+   return true;
+}
+
+bool ossimVertexExtractor::extractVertices()
+{
+   //***
+   // This method returns the non-null vertexes of the image corners.
+   // This can be used to initialize the "ValidImageVertices" for an 
+   // image.
+   // This method does not handle images that have more than four vertexes.
+   //***
+   static const char MODULE[] = "ossimVertexExtractor::extractVertices";
+
+   if (traceDebug()) CLOG << " Entered..." << endl;
+
+   if (!theLeftEdge || !theRightEdge)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ERROR ossimVertexExtractor::extractVertices():"
+                                         << "\nEdges not initialized!" << std::endl;
+      return false;
+   }
+
+   // Image must be quadrilateral (i.e. 4 sided polygon)
+   
+   ossim_int32   total_lines = theAreaOfInterest.height();
+   
+   ossim_int32   topLine             = 0;    
+   ossim_int32   bottomLine          = 0;
+   
+   ossim_int32   firstLeftSample     = 0;
+   ossim_int32   firstRightSample    = 0;
+   
+   ossim_int32   lastLeftSample      = 0;
+   ossim_int32   lastRightSample     = 0;
+   
+   ossim_int32   leftMostSample      = 0;
+   ossim_int32   leftMostSampleLine  = 0;
+   
+   ossim_int32   rightMostSample     = 0;
+   ossim_int32   rightMostSampleLine = 0;
+   
+   ossim_int32   leftCorner_A        = 0;
+   ossim_int32   leftCornerLine_A    = 0;
+   ossim_int32   leftCorner_B        = 0;
+   ossim_int32   leftCornerLine_B    = 0;
+   
+   ossim_int32   rightCorner_A       = 0;
+   ossim_int32   rightCornerLine_A   = 0;
+   ossim_int32   rightCorner_B       = 0;
+   ossim_int32   rightCornerLine_B   = 0;
+
+
+   bool found_first_non_null_line = 0;
+   bool found_last_non_null_line = 0;
+
+   bool rhombus = false;
+   bool square = false;
+   bool left = false;
+   bool right = false;
+
+   ossim_int32 first_non_null_line = 0;
+   ossim_int32 last_non_null_line = 0;
+
+   ossim_int32 i = 0;
+   while(found_last_non_null_line == 0)
+   {  
+      // Look for the first row with a valid DN
+      // Nulls are negative
+         
+      if(    (theLeftEdge[i] >= 0) 
+             && (found_first_non_null_line == 0) )
+      {
+         // Found first valid pixel at row i 
+         found_first_non_null_line = 1;        
+         first_non_null_line = i;
+            
+         // Finish walking down the rows of the image
+         while(  (found_first_non_null_line == 1)
+                 && (theLeftEdge[i] >= 0)
+                 && (found_last_non_null_line == 0)
+                 && (i <= total_lines) )
+         {
+            i = i+1;
+         }
+         found_last_non_null_line = 1;
+         last_non_null_line = i-1;
+      }
+
+      i = i+1;
+         
+   }//end  while "found_last_non_null_line == 0"
+   
+   last_non_null_line = last_non_null_line -1;
+
+   topLine = first_non_null_line;
+   bottomLine = last_non_null_line;
+
+   // Record the slope searching from the right edge
+   ossim_int32 k = 0;
+   ossim_int32 start = first_non_null_line;
+   ossim_int32 end = last_non_null_line;
+   ossim_int32 sizeDeltaSlope = last_non_null_line - first_non_null_line;
+   double* rightSlope = new double[sizeDeltaSlope];
+  
+   for(ossim_int32 i = start; i <= (end - 100); i += 100)
+   {
+      ossim_int32  run = theRightEdge[i] - theRightEdge[i + 100];
+      if(run != 0)
+      {
+         rightSlope[k] =  100.0 / run;
+      }
+      else
+      {
+         rightSlope[k]= OSSIM_INT_NAN;
+      }
+      
+      k = k + 1;
+   }
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:" << endl;
+      for (ossim_int32 i=0; i<= k-1; i++)
+      {
+          ossimNotify(ossimNotifyLevel_DEBUG)<< setprecision(15) << "rightSlope[" << i << "]:  "
+                                             << rightSlope[i]
+                                             << std::endl;
+      }
+   }
+
+   // Record the slope searching from the left edge
+   k = 0;
+   double* leftSlope = new double[sizeDeltaSlope];
+  
+   for(ossim_int32 i = start; i <= (end - 100); i += 100)
+   {
+      ossim_int32  run = theLeftEdge[i] - theLeftEdge[i + 100];
+      if(run != 0)
+      {
+         leftSlope[k] =  100.0 / run;
+      }
+      else
+      {
+         leftSlope[k] = OSSIM_INT_NAN;
+      }
+      
+      k = k + 1;
+   }
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:" << endl;
+      for (ossim_int32 i=0; i<= k-1; i++)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << setprecision(15) << "leftSlope[" << i << "]:  "
+                                             << leftSlope[i]
+                                             << std::endl;
+      }
+   }
+   ossim_int32 sizeOftheSlope = k-1;
+   ossim_int32 counter = 0;
+
+
+      // Find the right most sample
+   ossim_int32 rightMostEdgeTemp = theRightEdge[topLine];
+   ossim_int32 rightMostEdgeTempLine = 0;
+
+   for(ossim_int32 i= (topLine+1); i<bottomLine; i++)
+   {     
+      if(theRightEdge[i] >= rightMostEdgeTemp)         
+      {
+         rightMostEdgeTemp = theRightEdge[i];
+         rightMostEdgeTempLine = i;
+      }
+   }
+   rightMostSample = rightMostEdgeTemp;
+   rightMostSampleLine = rightMostEdgeTempLine-1;
+   lastLeftSample = theLeftEdge[bottomLine];
+
+   // Find the left most sample
+   ossim_int32 leftMostEdgeTemp = theLeftEdge[topLine];
+   ossim_int32 leftMostEdgeTempLine = 0;
+
+   for(ossim_int32 i= (topLine+1); i<bottomLine; i++)
+   {     
+      if(theLeftEdge[i] <= leftMostEdgeTemp)         
+      {
+         leftMostEdgeTemp = theLeftEdge[i];
+         leftMostEdgeTempLine = i;
+      }
+   }
+   leftMostSample = leftMostEdgeTemp;
+   leftMostSampleLine = leftMostEdgeTempLine-1;
+   firstLeftSample = theLeftEdge[topLine];
+   
+   // Case: Check for square
+   for(ossim_int32 i=0; i < sizeOftheSlope; ++i)
+   {
+      if(leftSlope[i]==rightSlope[i])
+      {
+         counter = counter + 1;
+      }
+   }
+   
+   if(counter == sizeOftheSlope)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)<<"\n\n***Case = SQUARE***"<<endl<<endl;
+      }
+      
+      square  = 1;
+      
+      leftCornerLine_A = topLine;
+      //leftCorner_A = theLeftEdge[topLine]; //0
+      leftCorner_A = leftMostSample;
+
+      rightCornerLine_A = topLine;
+      //rightCorner_A = theRightEdge[topLine]; //1
+      rightCorner_A = rightMostSample; //1
+
+      rightCornerLine_B =  bottomLine;
+      //rightCorner_B = theRightEdge[bottomLine]; //2
+      rightCorner_B = rightMostSample;
+        
+      leftCornerLine_B = bottomLine;
+      //leftCorner_B = theLeftEdge[bottomLine]; //3
+      leftCorner_B = leftMostSample;
+   }
+   
+   firstRightSample = theRightEdge[topLine];
+   lastRightSample  = theRightEdge[bottomLine];
+
+
+   
+   ossim_int32 halfsamps = (rightMostSample - leftMostSample ) / 2;
+
+   if(square == 0)     
+   { 
+      if( (firstRightSample - firstLeftSample) > halfsamps )
+      {
+         // Case is rhombus (clipped or not clipped)
+
+         rhombus = 1;
+         if (traceDebug())
+         { 
+            ossimNotify(ossimNotifyLevel_DEBUG)<<"\n\n***Case = RHOMBUS***"<<endl;
+            ossimNotify(ossimNotifyLevel_DEBUG)<<"here"<<endl;
+         }
+         
+         leftCornerLine_A = topLine;
+         leftCorner_A = firstLeftSample; //0
+      
+         rightCornerLine_A = topLine;
+         rightCorner_A= firstRightSample; //1
+       
+         rightCornerLine_B = bottomLine;
+         rightCorner_B = lastRightSample; //2
+      
+         leftCornerLine_B = bottomLine;
+         leftCorner_B = lastLeftSample; //3
+
+      } 
+   }
+   
+   
+   if(square == 0 && rhombus == 0)
+   {//if not square or rhombus
+      
+      if(firstLeftSample < lastLeftSample)
+      {//if tilted right
+
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)<<"\n\n***Case = TILTED RIGHT***"<<endl<<endl;
+         }
+         
+         right = true;
+         
+         // Regression line 2 is the right side
+         // Regression line 4 is the left side
+         // These are handled differently
+         // These sides may be 'uneven' or 'torn' or 'louvered'
+         // This code finds the best regression line that 'cuts off'
+         // this edge fringe
+         
+         //Regression Line 1
+         
+         ossim_int32 line1_pt4 = rightMostSampleLine;
+         ossim_int32 line1_pt0 = topLine;
+         ossim_int32 line1_pt2 = (line1_pt0 + line1_pt4)/2;
+         ossim_int32 line1_pt1 = (line1_pt2 + line1_pt0)/2;
+         ossim_int32 line1_pt3 = (line1_pt2 + line1_pt4)/2;
+         
+         double line1RegPtsSamples[] = {theRightEdge[line1_pt1],
+                                        theRightEdge[line1_pt2],
+                                        theRightEdge[line1_pt3]};
+         double line1RegPtsLines[] = {-line1_pt1,
+                                      -line1_pt2,
+                                      -line1_pt3};
+         
+         double sum_xy_line1 = 0.0;
+         double sum_x_line1 = 0.0;
+         double sum_y_line1 = 0.0;
+         double mean_x_line1 = 0.0;
+         double mean_y_line1 = 0.0;
+         double sum_x_squared_line1 = 0.0;
+         double sum_squared_x_line1 = 0.0;   
+         double b_line1;
+         double a_line1;
+         double num_elements_line1 = 3.0;
+         
+         for(ossim_int32 i = 0; i < num_elements_line1; ++i)
+         {
+            sum_xy_line1 = sum_xy_line1
+               + (line1RegPtsSamples[i]*line1RegPtsLines[i]);
+            
+            sum_x_line1 = sum_x_line1 + line1RegPtsSamples[i];
+            sum_y_line1 = sum_y_line1 + line1RegPtsLines[i];
+            
+            sum_squared_x_line1 = sum_squared_x_line1
+               + line1RegPtsSamples[i]*line1RegPtsSamples[i];
+         }
+         
+         sum_x_squared_line1 = sum_x_line1*sum_x_line1; 
+         mean_y_line1 = sum_y_line1/num_elements_line1;
+         mean_x_line1 = sum_x_line1/num_elements_line1;
+         b_line1 = (sum_xy_line1 - (sum_x_line1*sum_y_line1)/num_elements_line1)
+            / (sum_squared_x_line1 - (sum_x_squared_line1/num_elements_line1));
+         a_line1 = mean_y_line1 - b_line1*mean_x_line1;
+         
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)<<" a_line1:  "<< a_line1 <<std::endl;
+            ossimNotify(ossimNotifyLevel_DEBUG)<<" b_line1:  "<< b_line1 <<std::endl;
+            
+            
+            for(ossim_int32 i = 0; i < num_elements_line1; ++i)
+            {
+               
+               ossimNotify(ossimNotifyLevel_DEBUG) << setprecision(15) << "line1RegPtsLines[" << i
+                                                   << "]:  " <<line1RegPtsLines[i]
+                                                   << "\nline1RegPtsSamples[" << i << "]:  "
+                                                   <<line1RegPtsSamples[i]
+                                                   << std::endl;  
+               
+            }
+         }
+         
+         //Regression Line 2
+         ossim_int32 line2_pt0 = rightMostSampleLine;
+         ossim_int32 line2_pt4 = bottomLine;
+         ossim_int32 line2_pt2 = (line2_pt0 + line2_pt4)/2;
+         ossim_int32 line2_pt1 = (line2_pt2 + line2_pt0)/2;
+         ossim_int32 line2_pt3 = (line2_pt2 + line2_pt4)/2;
+ 
+         
+         ossim_int32 minValuePt1;
+         ossim_int32 minOffsetPt1;
+         getMinAndIndex(&theRightEdge[line2_pt1-100],
+                        &theRightEdge[line2_pt1+100],
+                        minValuePt1, minOffsetPt1 );
+         line2_pt1 = line2_pt1-100 + minOffsetPt1;
+         
+         ossim_int32 minValuePt2;
+         ossim_int32 minOffsetPt2;
+         getMinAndIndex(&theRightEdge[line2_pt2-100],
+                        &theRightEdge[line2_pt2+100],
+                        minValuePt2, minOffsetPt2 );
+         line2_pt2 = line2_pt2-100 + minOffsetPt2;
+         
+         
+         ossim_int32 minValuePt3;
+         ossim_int32 minOffsetPt3;
+         getMinAndIndex(&theRightEdge[line2_pt3-100],&theRightEdge[line2_pt3+100],
+                        minValuePt3, minOffsetPt3 );
+         line2_pt3 = line2_pt3-100 + minOffsetPt3;
+         
+         //***
+            // Find the line within 100 lines of line2_ptx that has the
+            // minimum sample.  This will cut off the 'fringe'
+            //***
+            
+            double line2RegPtsSamples[] = {theRightEdge[line2_pt1],
+                                           theRightEdge[line2_pt2],
+                                           theRightEdge[line2_pt3]};
+            double line2RegPtsLines[] = {-line2_pt1,
+                                         -line2_pt2,
+                                         -line2_pt3};
+            
+            double sum_xy_line2 = 0.0;
+            double sum_x_line2 = 0.0;
+            double sum_y_line2 = 0.0;
+            double mean_x_line2 = 0.0;
+            double mean_y_line2 = 0.0;
+            double sum_x_squared_line2 = 0.0;
+            double sum_squared_x_line2 = 0.0;   
+            double b_line2;
+            double a_line2;
+            double num_elements_line2 = 3.0;
+         
+            for(ossim_int32 i = 0; i < num_elements_line2; ++i)
+            {
+               sum_xy_line2 = sum_xy_line2
+                  + (line2RegPtsSamples[i]*line2RegPtsLines[i]);
+            
+               sum_x_line2 = sum_x_line2 + line2RegPtsSamples[i];
+               sum_y_line2 = sum_y_line2 + line2RegPtsLines[i];
+            
+               sum_squared_x_line2 = sum_squared_x_line2
+                  + line2RegPtsSamples[i]*line2RegPtsSamples[i];
+            }
+
+            sum_x_squared_line2 = sum_x_line2*sum_x_line2; 
+            mean_y_line2 = sum_y_line2/num_elements_line2;
+            mean_x_line2 = sum_x_line2/num_elements_line2;
+            b_line2 = (sum_xy_line2 - (sum_x_line2*sum_y_line2)/num_elements_line2)
+               / (sum_squared_x_line2 - (sum_x_squared_line2/num_elements_line2));
+            a_line2 = mean_y_line2 - b_line2*mean_x_line2;
+
+            if(traceDebug())
+            {
+               for(ossim_int32 i = 0; i < num_elements_line2; ++i)
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG) << setprecision(15) << "line2RegPtsLines[" << i << "]:  "
+                                                      <<line2RegPtsLines[i]
+                                                      << "\nline2RegPtsSamples[" << i << "]:  "
+                                                      <<line2RegPtsSamples[i]
+                                                      <<std::endl;
+               }
+               ossimNotify(ossimNotifyLevel_DEBUG) << "\na_line2:  " << a_line2
+                                                   << "\nb_line2:  " << b_line2 << std::endl;
+               
+            }
+         
+            //End regression line2
+            
+            //Intersect lines 1 and 2 to get the ur corner vertex
+
+            double ur_x = (a_line1 - a_line2)/(b_line2 - b_line1);
+            double ur_y = -(a_line1 + b_line1*ur_x);
+            
+            //Regression Line 3
+            
+            ossim_int32 line3_pt0 = leftMostSampleLine;
+            ossim_int32 line3_pt4 = bottomLine;
+            ossim_int32 line3_pt2 = (line3_pt0 + line3_pt4)/2;
+            ossim_int32 line3_pt1 = (line3_pt2 + line3_pt0)/2;
+            ossim_int32 line3_pt3 = (line3_pt2 + line3_pt4)/2;
+            
+            double line3RegPtsSamples[] = {theLeftEdge[line3_pt1],
+                                           theLeftEdge[line3_pt2],
+                                           theLeftEdge[line3_pt3]};
+            double line3RegPtsLines[] = {-line3_pt1,
+                                         -line3_pt2,
+                                         -line3_pt3};
+            
+            double sum_xy_line3 = 0.0;
+            double sum_x_line3 = 0.0;
+            double sum_y_line3 = 0.0;
+            double mean_x_line3 = 0.0;
+            double mean_y_line3 = 0.0;
+            double sum_x_squared_line3 = 0.0;
+            double sum_squared_x_line3 = 0.0;   
+            double b_line3;
+            double a_line3;
+            double num_elements_line3 = 3.0;
+            
+            for(ossim_int32 i = 0; i < num_elements_line3; ++i)
+            {
+               sum_xy_line3 = sum_xy_line3
+                  + (line3RegPtsSamples[i]*line3RegPtsLines[i]);
+               
+               sum_x_line3 = sum_x_line3 + line3RegPtsSamples[i];
+               sum_y_line3 = sum_y_line3 + line3RegPtsLines[i];
+               
+               sum_squared_x_line3 = sum_squared_x_line3
+                  + line3RegPtsSamples[i]*line3RegPtsSamples[i];
+               
+            }
+            
+            sum_x_squared_line3 = sum_x_line3*sum_x_line3; 
+            mean_y_line3 = sum_y_line3/num_elements_line3;
+            mean_x_line3 = sum_x_line3/num_elements_line3;
+            b_line3 = (sum_xy_line3 - (sum_x_line3*sum_y_line3)/num_elements_line3)
+               / (sum_squared_x_line3 - (sum_x_squared_line3/num_elements_line3));
+            a_line3 = mean_y_line3 - b_line3*mean_x_line3;
+            
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "\n\n a_line3:  " << a_line3 <<std::endl;
+               ossimNotify(ossimNotifyLevel_DEBUG) << " b_line3:  " << b_line3 <<std::endl;
+               
+               
+               for(ossim_int32 i = 0; i < num_elements_line3; ++i)
+               {
+                  
+                  ossimNotify(ossimNotifyLevel_DEBUG) << setprecision(15) << "line3RegPtsLines[" << i << "]:  "
+                                                      <<line3RegPtsLines[i]
+                                                      << "\nline3RegPtsSamples[" << i << "]:  "
+                                                      <<line3RegPtsSamples[i]
+                                                      << std::endl;
+               }
+            }
+            //End regression line3
+            
+            //Intersect lines 2 and 3 to get the lr corner vertex
+            
+            double lr_x = (a_line3 - a_line2)/(b_line2 - b_line3);
+            double lr_y = -(a_line3 + b_line3*lr_x);
+            
+            //End Regression Line3
+            
+            //Regression Line 4
+            
+            ossim_int32 line4_pt0 = leftMostSampleLine;
+            ossim_int32 line4_pt4 = topLine;
+            ossim_int32 line4_pt2 = (line4_pt0 + line4_pt4)/2;
+            ossim_int32 line4_pt1 = (line4_pt2 + line4_pt0)/2;
+            ossim_int32 line4_pt3 = (line4_pt2 + line4_pt4)/2;
+            
+//             //***
+//                // Find the line within 100 lines of line2_ptx that has the maximum
+//                // sample.  This will cut off the 'fringe'.
+//                //***
+            
+            ossim_int32 maxValueLine4Pt1;
+            ossim_int32 maxOffsetLine4Pt1;
+            getMaxAndIndex(&theLeftEdge[line4_pt1-100],&theLeftEdge[line4_pt1+100],
+                           maxValueLine4Pt1, maxOffsetLine4Pt1 );
+            line4_pt1 = line4_pt1-100 + maxOffsetLine4Pt1;
+            
+            
+            ossim_int32 maxValueLine4Pt2;
+            ossim_int32 maxOffsetLine4Pt2;
+            getMaxAndIndex(&theLeftEdge[line4_pt2-100],&theLeftEdge[line4_pt2+100],
+                           maxValueLine4Pt2, maxOffsetLine4Pt2 );
+            line4_pt2 = line4_pt2-100 + maxOffsetLine4Pt2;
+            
+            
+            ossim_int32 maxValueLine4Pt3;
+            ossim_int32 maxOffsetLine4Pt3;
+            getMaxAndIndex(&theLeftEdge[line4_pt3-100],&theLeftEdge[line4_pt3+100],
+                           maxValueLine4Pt3, maxOffsetLine4Pt3 );
+            line4_pt3 = line4_pt3-100 + maxOffsetLine4Pt3;
+            
+            
+            
+            
+            double line4RegPtsSamples[] = {theLeftEdge[line4_pt1],
+                                           theLeftEdge[line4_pt2],
+                                           theLeftEdge[line4_pt3]};
+            double line4RegPtsLines[] = {-line4_pt1,
+                                         -line4_pt2,
+                                         -line4_pt3};
+            
+            double sum_xy_line4 = 0.0;
+            double sum_x_line4 = 0.0;
+            double sum_y_line4 = 0.0;
+            double mean_x_line4 = 0.0;
+            double mean_y_line4 = 0.0;
+            double sum_x_squared_line4 = 0.0;
+            double sum_squared_x_line4 = 0.0;   
+            double b_line4;
+            double a_line4;
+            double num_elements_line4 = 3.0;
+            for(ossim_int32 i = 0; i < num_elements_line4; ++i)
+            {
+               sum_xy_line4 = sum_xy_line4
+                  + (line4RegPtsSamples[i]*line4RegPtsLines[i]);
+               
+               sum_x_line4 = sum_x_line4 + line4RegPtsSamples[i];
+               sum_y_line4 = sum_y_line4 + line4RegPtsLines[i];
+               
+               sum_squared_x_line4 = sum_squared_x_line4
+                  + line4RegPtsSamples[i]*line4RegPtsSamples[i];
+               
+               
+            }
+            
+            sum_x_squared_line4 = sum_x_line4*sum_x_line4; 
+            mean_y_line4 = sum_y_line4/num_elements_line4;
+            mean_x_line4 = sum_x_line4/num_elements_line4;
+            b_line4 = (sum_xy_line4 - (sum_x_line4*sum_y_line4)/num_elements_line4)
+               / (sum_squared_x_line4 - (sum_x_squared_line4/num_elements_line4));
+            a_line4 = mean_y_line4 - b_line4*mean_x_line4;
+            
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)<<"\na_line4:  "<< a_line4
+                                                  <<"\nb_line4:  "<< b_line4 <<std::endl;
+               
+               for(ossim_int32 i = 0; i < num_elements_line4; ++i)
+               {
+                  
+                  ossimNotify(ossimNotifyLevel_DEBUG) << setprecision(15) << "line4RegPtsLines[" << i << "]:  "
+                                                      <<line4RegPtsLines[i]
+                                                      << "\nline4RegPtsSamples[" << i << "]:  "
+                                                      <<line4RegPtsSamples[i]
+                                                      << std::endl;  
+                  
+               }
+            }
+            //End regression line4
+            
+            //Intersect lines 3 and 4 to get the ll corner vertex
+            
+            double ll_x = (a_line4 - a_line3)/(b_line3 - b_line4);
+            double ll_y = -(a_line4 + b_line4*ll_x);
+            
+            //End Regression Line4
+            
+            //Intersect lines 4 and 1 to get the ul corner vertex
+            
+            double ul_x = (a_line4 - a_line1)/(b_line1 - b_line4);
+            double ul_y = -(a_line4 + b_line4*ul_x);
+            
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)<<"\n\nInitial corners for tilted right:   "
+                                                  <<"\ncorner0:  ("<<ul_x<<", "<<ul_y<<")"
+                                                  <<"\ncorner1:  ("<<ur_x<<", "<<ur_y<<")"
+                                                  <<"\ncorner2:  ("<<lr_x<<", "<<lr_y<<")"
+                                                  <<"\ncorner3:  ("<<ll_x<<", "<<ll_y<<")"<<std::endl<<std::endl;
+            }
+            
+            leftCornerLine_A = (ossim_int32)ul_y;
+            leftCorner_A = (ossim_int32)ul_x; //0
+            
+            rightCornerLine_A = (ossim_int32)ur_y;
+            rightCorner_A = (ossim_int32)ur_x; //1
+            
+            rightCornerLine_B = (ossim_int32)lr_y;
+            rightCorner_B =(ossim_int32)lr_x; //2
+            
+            leftCornerLine_B = (ossim_int32)ll_y;
+            leftCorner_B =(ossim_int32)ll_x; //3
+            
+            
+            // Check for bad corner points due to irregular shape image
+            
+            //for corner 0 (ul), sample should be between left and right most samples
+            //                   line can go negative due to jagged edges 
+            
+            //for corner 1 (ur), sample can go > than num samples
+            //                   line should be between top and bottom lines
+            
+            //for corner 2 (lr), line should be between top and bottom line + 200
+            //                   sample should be between left and right most sample
+            
+            //for corner 3 (ll), line should be between top and bottom line
+            //                   sample should can go negative due to jagged edges
+            
+            if(        (leftCornerLine_A < (topLine - 300))
+                       || (leftCornerLine_A > total_lines)
+                       || (leftCorner_A > rightMostSample)
+                       || (leftCorner_A < leftMostSample)
+                       
+                       || (rightCornerLine_A < topLine)
+                       || (rightCornerLine_A > bottomLine)
+                       || (rightCorner_A < leftMostSample)
+                       || (rightCorner_A > (rightMostSample + 200))
+                       
+                       
+                       || (rightCornerLine_B < topLine)
+                       || (rightCornerLine_B > (bottomLine + 200))
+                       || (rightCorner_B < leftMostSample)
+                       || (rightCorner_B > rightMostSample)
+                       
+                       || (leftCornerLine_B > bottomLine)   
+                       || (leftCornerLine_B < topLine)
+                       || (leftCorner_B > rightMostSample)   
+                       || (leftCorner_B < (leftMostSample - 200))    )
+               
+               
+               
+            {
+               right = false;
+               if (traceDebug())
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG) <<"\n\n***Case = NOT TILTED RIGHT...***"<<std::endl;
+               }
+            }
+      }           
+      
+      //tilted left
+      if(firstRightSample > lastRightSample)
+      {//begin tilted left
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) <<"\n\n***Case = TILTED LEFT***"<<std::endl;
+         }
+         left = true;
+         
+         // Regression line 1 is the right side
+         // Regression line 3 is the left side
+         // These are handled differently
+         // These sides may be 'uneven' or 'torn' or 'louvered'
+         // This code finds the best regression line that 'cuts off' this edge fringe
+         
+         
+         //Regression Line 1
+         
+         ossim_int32 line1_pt4 = rightMostSampleLine;
+         ossim_int32 line1_pt0 = topLine;
+         ossim_int32 line1_pt2 = (line1_pt0 + line1_pt4)/2;
+         ossim_int32 line1_pt1 = (line1_pt2 + line1_pt0)/2;
+         ossim_int32 line1_pt3 = (line1_pt2 + line1_pt4)/2;
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)<<" line1_pt1:   "<<line1_pt0<<std::endl;
+            ossimNotify(ossimNotifyLevel_DEBUG)<<" line1_pt2:   "<<line1_pt1<<std::endl;
+            ossimNotify(ossimNotifyLevel_DEBUG)<<" line1_pt3:   "<<line1_pt2<<std::endl;
+            ossimNotify(ossimNotifyLevel_DEBUG)<<" line1_pt4:   "<<line1_pt3<<std::endl;
+         }
+         
+         ossim_int32 minValueLine1Pt1;
+         ossim_int32 minOffsetLine1Pt1;
+         getMinAndIndex(&theLeftEdge[line1_pt1-100],&theLeftEdge[line1_pt1+100],
+                        minValueLine1Pt1, minOffsetLine1Pt1 );
+         line1_pt1 = line1_pt1-100 + minOffsetLine1Pt1;
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << " line1_pt1:  "<< line1_pt1
+                                                <<"   minValueLine1Pt1:  "<<minValueLine1Pt1<<"\n\n";
+         }
+         
+         ossim_int32 minValueLine1Pt2;
+         ossim_int32 minOffsetLine1Pt2;
+         getMinAndIndex(&theLeftEdge[line1_pt2-100],&theLeftEdge[line1_pt2+100],
+                        minValueLine1Pt2, minOffsetLine1Pt2 );
+         line1_pt2 = line1_pt2-100 + minOffsetLine1Pt2;
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << " line1_pt2:  "<< line1_pt2
+                                                <<"   minValueLine1Pt2:  "<<minValueLine1Pt2<<"\n\n";
+         }
+         
+         
+         ossim_int32 minValueLine1Pt3;
+         ossim_int32 minOffsetLine1Pt3;
+         getMinAndIndex(&theLeftEdge[line1_pt3-100],&theLeftEdge[line1_pt3+100],
+                        minValueLine1Pt3, minOffsetLine1Pt3 );
+         line1_pt3 = line1_pt3-100 + minOffsetLine1Pt3;
+         
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << " line1_pt3:  "<< line1_pt3
+                                                <<"   minValueLine1Pt3:  "<<minValueLine1Pt3<<std::endl<<std::endl;
+         }
+         
+         double line1RegPtsSamples[] = {theRightEdge[line1_pt1],
+                                        theRightEdge[line1_pt2],
+                                        theRightEdge[line1_pt3]};
+         double line1RegPtsLines[] = {-line1_pt1,
+                                      -line1_pt2,
+                                      -line1_pt3};
+         
+         double sum_xy_line1 = 0.0;
+         double sum_x_line1 = 0.0;
+         double sum_y_line1 = 0.0;
+         double mean_x_line1 = 0.0;
+         double mean_y_line1 = 0.0;
+         double sum_x_squared_line1 = 0.0;
+         double sum_squared_x_line1 = 0.0;   
+         double b_line1;
+         double a_line1;
+         double num_elements_line1 = 3.0;
+         
+         for(ossim_int32 i = 0; i < num_elements_line1; ++i)
+         {
+            sum_xy_line1 = sum_xy_line1
+               + (line1RegPtsSamples[i]*line1RegPtsLines[i]);
+            
+            sum_x_line1 = sum_x_line1 + line1RegPtsSamples[i];
+            sum_y_line1 = sum_y_line1 + line1RegPtsLines[i];
+            
+            sum_squared_x_line1 = sum_squared_x_line1
+               + line1RegPtsSamples[i]*line1RegPtsSamples[i];
+            
+            
+         }
+         
+         sum_x_squared_line1 = sum_x_line1*sum_x_line1; 
+         mean_y_line1 = sum_y_line1/num_elements_line1;
+         mean_x_line1 = sum_x_line1/num_elements_line1;
+         b_line1 = (sum_xy_line1 - (sum_x_line1*sum_y_line1)/num_elements_line1)
+            / (sum_squared_x_line1 - (sum_x_squared_line1/num_elements_line1));
+         a_line1 = mean_y_line1 - b_line1*mean_x_line1;
+         
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)<<"a_line1:  "<< a_line1
+                                               <<"\nb_line1:  "<< b_line1 <<std::endl;
+            
+            for(ossim_int32 i = 0; i < num_elements_line1; ++i)
+            {
+               
+               ossimNotify(ossimNotifyLevel_DEBUG) << setprecision(15) << "line1RegPtsLines[" << i << "]:  "
+                                                   <<line1RegPtsLines[i]
+                                                   << "\nline1RegPtsSamples[" << i << "]:  "
+                                                   <<line1RegPtsSamples[i]
+                                                   << std::endl;
+            }
+         }
+         
+         
+         //Regression Line 2
+         
+         ossim_int32 line2_pt0 = rightMostSampleLine;
+         ossim_int32 line2_pt4 = bottomLine;
+         ossim_int32 line2_pt2 = (line2_pt0 + line2_pt4)/2;
+         ossim_int32 line2_pt1 = (line2_pt2 + line2_pt0)/2;
+         ossim_int32 line2_pt3 = (line2_pt2 + line2_pt4)/2;
+      
+         double line2RegPtsSamples[] = {theRightEdge[line2_pt1],
+                                        theRightEdge[line2_pt2],
+                                        theRightEdge[line2_pt3]};
+         double line2RegPtsLines[] = {-line2_pt1,
+                                      -line2_pt2,
+                                      -line2_pt3};
+      
+         double sum_xy_line2 = 0.0;
+         double sum_x_line2 = 0.0;
+         double sum_y_line2 = 0.0;
+         double mean_x_line2 = 0.0;
+         double mean_y_line2 = 0.0;
+         double sum_x_squared_line2 = 0.0;
+         double sum_squared_x_line2 = 0.0;   
+         double b_line2;
+         double a_line2;
+         double num_elements_line2 = 3.0;
+         for(ossim_int32 i = 0; i < num_elements_line2; ++i)
+         {
+            sum_xy_line2 = sum_xy_line2
+               + (line2RegPtsSamples[i]*line2RegPtsLines[i]);
+         
+            sum_x_line2 = sum_x_line2 + line2RegPtsSamples[i];
+            sum_y_line2 = sum_y_line2 + line2RegPtsLines[i];
+         
+            sum_squared_x_line2 = sum_squared_x_line2
+               + line2RegPtsSamples[i]*line2RegPtsSamples[i];
+         }
+      
+         sum_x_squared_line2 = sum_x_line2*sum_x_line2; 
+         mean_y_line2 = sum_y_line2/num_elements_line2;
+         mean_x_line2 = sum_x_line2/num_elements_line2;
+         b_line2 = (sum_xy_line2 - (sum_x_line2*sum_y_line2)/num_elements_line2)
+            / (sum_squared_x_line2 - (sum_x_squared_line2/num_elements_line2));
+         a_line2 = mean_y_line2 - b_line2*mean_x_line2;
+      
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "a_line2:  "<< a_line2
+                                                << "\nb_line2:  "<< b_line2 <<std::endl;
+         
+            for(ossim_int32 i = 0; i < num_elements_line2; ++i)
+            {
+            
+               ossimNotify(ossimNotifyLevel_DEBUG) << setprecision(15) << "line2RegPtsLines[" << i << "]:  "
+                                                   <<line2RegPtsLines[i]
+                                                   << "\nline2RegPtsSamples[" << i << "]:  "
+                                                   <<line2RegPtsSamples[i]
+                                                   << std::endl;
+            } 
+         }
+         //End regression line2
+      
+         //Intersect lines 1 and 2 to get the lr corner vertex
+      
+         double lr_x = (a_line1 - a_line2)/(b_line2 - b_line1);
+         double lr_y = -(a_line1 + b_line1*lr_x);
+      
+         //Regression Line 3
+      
+         ossim_int32 line3_pt0 = leftMostSampleLine;
+         ossim_int32 line3_pt4 = bottomLine;
+         ossim_int32 line3_pt2 = (line3_pt0 + line3_pt4)/2;
+         ossim_int32 line3_pt1 = (line3_pt2 + line3_pt0)/2;
+         ossim_int32 line3_pt3 = (line3_pt2 + line3_pt4)/2;
+      
+         ossim_int32 maxValueLine3Pt1;
+         ossim_int32 maxOffsetLine3Pt1;
+         getMaxAndIndex(&theLeftEdge[line3_pt1-100],&theLeftEdge[line3_pt1+100],
+                        maxValueLine3Pt1, maxOffsetLine3Pt1 );
+         line3_pt1 = line3_pt1-100 + maxOffsetLine3Pt1;
+      
+      
+         ossim_int32 maxValueLine3Pt2;
+         ossim_int32 maxOffsetLine3Pt2;
+         getMaxAndIndex(&theLeftEdge[line3_pt2-100],&theLeftEdge[line3_pt2+100],
+                        maxValueLine3Pt2, maxOffsetLine3Pt2 );
+         line3_pt2 = line3_pt2-100 + maxOffsetLine3Pt2;
+      
+      
+         ossim_int32 maxValueLine3Pt3;
+         ossim_int32 maxOffsetLine3Pt3;
+         getMaxAndIndex(&theLeftEdge[line3_pt3-100],&theLeftEdge[line3_pt3+100],
+                        maxValueLine3Pt3, maxOffsetLine3Pt3 );
+         line3_pt3 = line3_pt3-100 + maxOffsetLine3Pt3;
+      
+      
+         double line3RegPtsSamples[] = {theLeftEdge[line3_pt1],
+                                        theLeftEdge[line3_pt2],
+                                        theLeftEdge[line3_pt3]};
+         double line3RegPtsLines[] = {-line3_pt1,
+                                      -line3_pt2,
+                                      -line3_pt3};
+      
+         double sum_xy_line3 = 0.0;
+         double sum_x_line3 = 0.0;
+         double sum_y_line3 = 0.0;
+         double mean_x_line3 = 0.0;
+         double mean_y_line3 = 0.0;
+         double sum_x_squared_line3 = 0.0;
+         double sum_squared_x_line3 = 0.0;   
+         double b_line3;
+         double a_line3;
+         double num_elements_line3 = 3.0;
+         for(ossim_int32 i = 0; i < num_elements_line3; ++i)
+         {
+            sum_xy_line3 = sum_xy_line3
+               + (line3RegPtsSamples[i]*line3RegPtsLines[i]);
+         
+            sum_x_line3 = sum_x_line3 + line3RegPtsSamples[i];
+            sum_y_line3 = sum_y_line3 + line3RegPtsLines[i];
+         
+            sum_squared_x_line3 = sum_squared_x_line3
+               + line3RegPtsSamples[i]*line3RegPtsSamples[i];
+         
+         
+         }
+      
+         sum_x_squared_line3 = sum_x_line3*sum_x_line3; 
+         mean_y_line3 = sum_y_line3/num_elements_line3;
+         mean_x_line3 = sum_x_line3/num_elements_line3;
+         b_line3 = (sum_xy_line3 - (sum_x_line3*sum_y_line3)/num_elements_line3)
+            / (sum_squared_x_line3 - (sum_x_squared_line3/num_elements_line3));
+         a_line3 = mean_y_line3 - b_line3*mean_x_line3;
+      
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)<<"\n\n a_line3:  "<< a_line3 <<std::endl
+                                               <<" b_line3:  "<< b_line3 <<endl;
+            for(ossim_int32 i = 0; i < num_elements_line3; ++i)
+            {
+            
+               ossimNotify(ossimNotifyLevel_DEBUG) << setprecision(15) << "line3RegPtsLines[" << i << "]:  "
+                                                   << line3RegPtsLines[i]
+                                                   << "\nline3RegPtsSamples[" << i << "]:  "
+                                                   << line3RegPtsSamples[i]
+                                                   << std::endl;
+            }   
+         }
+         //End regression line3
+      
+         //Intersect lines 2 and 3 to get the ll corner vertex
+      
+         double ll_x = (a_line3 - a_line2)/(b_line2 - b_line3);
+         double ll_y = -(a_line3 + b_line3*ll_x);      
+      
+         //End Regression Line3
+      
+         //Regression Line 4
+      
+         ossim_int32 line4_pt0 = leftMostSampleLine;
+         ossim_int32 line4_pt4 = topLine;
+         ossim_int32 line4_pt2 = (line4_pt0 + line4_pt4)/2;
+         ossim_int32 line4_pt1 = (line4_pt2 + line4_pt0)/2;
+         ossim_int32 line4_pt3 = (line4_pt2 + line4_pt4)/2;
+      
+      
+         double line4RegPtsSamples[] = {theLeftEdge[line4_pt1],
+                                        theLeftEdge[line4_pt2],
+                                        theLeftEdge[line4_pt3]};
+         double line4RegPtsLines[] = {-line4_pt1,
+                                      -line4_pt2,
+                                      -line4_pt3};
+      
+         double sum_xy_line4 = 0.0;
+         double sum_x_line4 = 0.0;
+         double sum_y_line4 = 0.0;
+         double mean_x_line4 = 0.0;   
+         double mean_y_line4 = 0.0;
+         double sum_x_squared_line4 = 0.0;
+         double sum_squared_x_line4 = 0.0;   
+         double b_line4;
+         double a_line4;
+         double num_elements_line4 = 3.0;
+         for(ossim_int32 i = 0; i < num_elements_line4; ++i)
+         {
+            sum_xy_line4 = sum_xy_line4
+               + (line4RegPtsSamples[i]*line4RegPtsLines[i]);
+         
+            sum_x_line4 = sum_x_line4 + line4RegPtsSamples[i];
+            sum_y_line4 = sum_y_line4 + line4RegPtsLines[i];
+         
+            sum_squared_x_line4 = sum_squared_x_line4
+               + line4RegPtsSamples[i]*line4RegPtsSamples[i];
+         
+         
+         }
+      
+         sum_x_squared_line4 = sum_x_line4*sum_x_line4; 
+         mean_y_line4 = sum_y_line4/num_elements_line4;
+         mean_x_line4 = sum_x_line4/num_elements_line4;
+         b_line4 = (sum_xy_line4 - (sum_x_line4*sum_y_line4)/num_elements_line4)
+            / (sum_squared_x_line4 - (sum_x_squared_line4/num_elements_line4));
+         a_line4 = mean_y_line4 - b_line4*mean_x_line4;
+      
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)<< "\n\n a_line4:  "<< a_line4 <<std::endl;
+            ossimNotify(ossimNotifyLevel_DEBUG)<< " b_line4:  "<< b_line4 <<std::endl;
+         
+            for(ossim_int32 i = 0; i < num_elements_line4; ++i)
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << setprecision(15) << "line4RegPtsLines[" << i << "]:  "
+                                                   <<line4RegPtsLines[i]
+                                                   << "\nline4RegPtsSamples[" << i << "]:  "
+                                                   <<line4RegPtsSamples[i]
+                                                   << std::endl;
+            }                  
+         
+         }
+         //End regression line 4
+      
+         //Intersect lines 3 and 4 to get the ul corner vertex
+      
+         double ul_x = (a_line4 - a_line3)/(b_line3 - b_line4);
+         double ul_y = -(a_line4 + b_line4*ul_x);
+         //End Regression Line4
+      
+         //Intersect lines 4 and 1 to get the ur corner vertex
+      
+         double ur_x = (a_line4 - a_line1)/(b_line1 - b_line4);
+         double ur_y = -(a_line4 + b_line4*ur_x);
+      
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) <<"Initial corners for tilted left:   "
+                                                <<"\ncorner0:  ("<<ul_x<<", "<<ul_y<<")"
+                                                <<"\ncorner1:  ("<<ur_x<<", "<<ur_y<<")"
+                                                <<"\ncorner2:  ("<<lr_x<<", "<<lr_y<<")"
+                                                <<"\ncorner3:  ("<<ll_x<<", "<<ll_y<<")" <<std::endl;
+         }
+      
+         leftCornerLine_A = (ossim_int32)ul_y;
+         leftCorner_A = (ossim_int32)ul_x; //0
+      
+         rightCornerLine_A = (ossim_int32)ur_y;
+         rightCorner_A = (ossim_int32)ur_x; //1
+      
+         rightCornerLine_B = (ossim_int32)lr_y;
+         rightCorner_B =(ossim_int32)lr_x; //2
+      
+         leftCornerLine_B = (ossim_int32)ll_y;
+         leftCorner_B =(ossim_int32)ll_x; //3
+      
+         // Check for bad corner points due to irregular shape image
+      
+         //for corner 0 (ul), line should be between top and bottom line
+         //                   sample should can go negative due to jagged edges 
+      
+         //for corner 1 (ur), sample should be between left and right most samples
+         //                    line can go negative due to jagged edges 
+      
+         //for corner 2 (lr), line should be between top and bottom lines
+         //                   sample can be greater than rightMost samp due to jagged edges
+      
+         //for corner 3 (ll), line should be between top and bottom line + 200
+         //                   sample should be between left and right most sample
+         if(        (leftCornerLine_A  > bottomLine)
+                    || (leftCornerLine_A  < topLine)
+                    || (leftCorner_A > rightMostSample)
+                    || (leftCorner_A < (leftMostSample - 300))
+                 
+                    || (rightCornerLine_A < (topLine - 300))
+                    || (rightCornerLine_A > total_lines)
+                    || (rightCorner_A > rightMostSample)
+                    || (rightCorner_A < leftMostSample)
+                 
+                 
+                    || (rightCornerLine_B < topLine)
+                    || (rightCornerLine_B > bottomLine)
+                    || (rightCorner_B < leftMostSample)
+                    || (rightCorner_B > (rightMostSample + 200))
+                 
+                    || (leftCornerLine_B > (bottomLine + 200))   
+                    || (leftCornerLine_B < topLine)
+                    || (leftCorner_B < leftMostSample)   
+                    || (leftCorner_B > rightMostSample)    )
+         
+         {
+            left = false;
+         
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) <<"\n\n***Case = NOT TILTED LEFT..***"<<std::endl;
+            }
+         }
+      }
+   }
+
+   if( (square == 0) && (rhombus == 0) && (right == 0) && (left == 0))
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)<<"\nDefault case"<<std::endl;
+      }
+      
+      //Suboptimal UL Corner:
+      leftCornerLine_A = (topLine);
+      leftCorner_A =(leftMostSample); //0
+      
+      //Look for non-null starting at topLine and going down
+      //Starting at left most samp and moving right
+      
+      bool foundULcornera = false;
+      bool foundULcornerb = false;
+      ossimImageHandler* src = reinterpret_cast<ossimImageHandler*>(getInput(0));
+      
+      ossimIrect tileRectUL(leftMostSample,
+                            topLine,
+                            leftMostSample+50,
+                            (topLine + 50) );
+      
+      ossimRefPtr<ossimImageData> dataUL = src->getTile(tileRectUL);
+      // ossimIrect imageRectangleUL = dataUL->getImageRectangle();
+      
+      ossim_int32 tempSamp_corner0a = 0;
+      ossim_int32 tempLine_corner0a = 0;
+      if (dataUL.valid())
+      {
+         for (ossim_int32 line = tileRectUL.ul().y; line <= tileRectUL.lr().y; ++line)
+         {
+            for (ossim_int32 samp = tileRectUL.ul().x; samp <=tileRectUL.ur().x; ++samp)
+            {
+               // uses band 0 corner points
+               if(!(dataUL->isNull(ossimIpt(samp,line),0)))
+               {
+                  
+                  foundULcornera = true;
+                  
+                  //Optimal Corner:
+                  leftCornerLine_A = line;//0
+                  leftCorner_A = samp;
+                  tempLine_corner0a = line;
+                  tempSamp_corner0a = samp;
+                  
+                  if (traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+                        <<"\nFound non null in ul corner pass 1 "<<std::endl
+                        <<"line:  "<<line<<std::endl
+                        <<"samp:  "<<samp<<std::endl;
+                  }
+               }
+               if(foundULcornera == true){break;}
+            }
+            if(foundULcornera == true){break;}
+         }
+
+         // Search in the other direction to handle the case of 'jaggered' edges.
+         ossim_int32 tempSamp_corner0b = 0;
+         ossim_int32 tempLine_corner0b = 0;
+         for (ossim_int32 samp = tileRectUL.ul().x; samp <=tileRectUL.ur().x; ++samp)
+         {
+            for (ossim_int32 line = tileRectUL.ul().y; line <= tileRectUL.lr().y; ++line)
+            {
+               // uses band 0 corner points
+               if(!(dataUL->isNull(ossimIpt(samp,line),0)))
+               {
+                  
+                  foundULcornerb = true;
+                  
+                  //Optimal Corner:
+                  leftCornerLine_A = line;//0
+                  leftCorner_A = samp;
+                  tempLine_corner0b = line;
+                  tempSamp_corner0b = samp;
+                  
+                  if (traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+                        <<"\nFound non null in ul corner pass 2 "<<std::endl
+                        <<"line:  "<<line<<std::endl
+                        <<"samp:  "<<samp<<std::endl;
+                  }
+               }
+               if(foundULcornerb == true){break;}
+            }
+            if(foundULcornerb == true){break;}
+         }
+         
+         //Better corner
+         if(foundULcornerb == true && foundULcornera ==true)
+         {
+            leftCornerLine_B = (tempLine_corner0a + tempLine_corner0b)/2;
+            leftCorner_B     = (tempSamp_corner0a + tempSamp_corner0b)/2;
+         }
+         
+         
+         // Suboptimal UR corner:
+         rightCornerLine_A = (topLine);
+         rightCorner_A = (rightMostSample); //1
+
+      }
+         //Look for non-null starting at topLine and going down
+         //Starting at right most samp and moving left 
+         
+      bool foundURcornera = false;
+      bool foundURcornerb = false;
+      
+      ossimIrect tileRectUR((rightMostSample - 50),
+                            topLine,
+                            rightMostSample,
+                            (topLine + 50) );
+      
+      ossimRefPtr<ossimImageData> dataUR = src->getTile(tileRectUR);
+      // ossimIrect imageRectangleUR = dataUR->getImageRectangle();
+
+      ossim_int32 tempSamp_corner1a = 0;
+      ossim_int32 tempLine_corner1a = 0;
+
+      if (dataUR.valid())
+      {
+         for (ossim_int32 line = tileRectUR.ul().y; line <= tileRectUR.lr().y; ++line)
+         {
+            for (ossim_int32 samp = tileRectUR.ur().x; samp > tileRectUR.ul().x; --samp)
+            {
+               
+               if(!(dataUR->isNull(ossimIpt(samp,line),0)))
+               {
+                  
+                  foundURcornera = true;
+                  rightCornerLine_A = line;
+                  rightCorner_A = samp;
+                  tempLine_corner1a = line;
+                  tempSamp_corner1a = samp;
+                  
+                  if (traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+                        <<"\nFound non null in ur corner pass 1 "<<std::endl
+                        <<"line:  "<<line<<std::endl
+                        <<"samp:  "<<samp<<std::endl;
+                  }
+               }
+               if(foundURcornera == true){break;}
+            }
+            if(foundURcornera == true){break;}
+         }
+         
+         // Search in the other direction to handle the case of 'jaggered' edges.
+         ossim_int32 tempSamp_corner1b = 0;
+         ossim_int32 tempLine_corner1b = 0;
+         
+         for (ossim_int32 samp = tileRectUR.ur().x; samp > tileRectUR.ul().x; --samp)
+         {
+            for (ossim_int32 line = tileRectUR.ul().y; line <= tileRectUR.lr().y; ++line)
+               
+            {
+               if(!(dataUR->isNull(ossimIpt(samp,line),0)))
+               {
+                  
+                  foundURcornerb = true;
+                  rightCornerLine_A = line;
+                  rightCorner_A = samp;
+                  tempLine_corner1b = line;
+                  tempSamp_corner1b = samp;
+                  
+                  if (traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+                        <<"\nFound non null in ur corner pass 2 "<<std::endl
+                        <<"line:  "<<line<<std::endl
+                        <<"samp:  "<<samp<<std::endl;
+                  }
+               }
+               if(foundURcornerb == true){break;}
+            }
+            if(foundURcornerb == true){break;}
+         }
+         
+         //Better corner
+         if(foundURcornerb == true && foundURcornera ==true)
+         {
+            rightCornerLine_B = (tempLine_corner1a + tempLine_corner1b)/2;
+            rightCorner_B     = (tempSamp_corner1a + tempSamp_corner1b)/2;
+         }
+         
+         // Suboptimal LR corner:
+         rightCornerLine_B =  (bottomLine);
+         rightCorner_B = (rightMostSample); //2
+
+      }
+
+      //Look for non-null starting at bottomLine and going up
+      //Starting at right most samp and moving left 
+      
+      bool foundLRcornera = false;
+      bool foundLRcornerb = false;
+
+      ossimIrect tileRectLR((rightMostSample - 50),
+                            bottomLine - 50,
+                            rightMostSample,
+                            (bottomLine) );
+      
+      ossimRefPtr<ossimImageData> dataLR = src->getTile(tileRectLR);
+      // ossimIrect imageRectangleLR = dataLR->getImageRectangle();
+      
+      ossim_int32 tempSamp_corner2a = 0;
+      ossim_int32 tempLine_corner2a = 0;
+
+      if (dataLR.valid())
+      {
+         for (ossim_int32 line = tileRectLR.lr().y; line >= tileRectLR.ur().y; --line)
+         {
+            for (ossim_int32 samp = tileRectLR.lr().x; samp > tileRectLR.ul().x; --samp)
+            {
+               
+               if(!(dataLR->isNull(ossimIpt(samp,line),0)))
+               {
+                  
+                  foundLRcornera = true;
+                  rightCornerLine_B = line;
+                  rightCorner_B = samp;
+                  tempLine_corner2a = line;
+                  tempSamp_corner2a = samp;
+                  
+                  if (traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+                        <<"\nFound non null in lr corner pass 1 "<<std::endl
+                        <<"line:  "<<line<<std::endl
+                        <<"samp:  "<<samp<<std::endl;
+                  }
+               }
+               if(foundLRcornera == true){break;}
+            }
+            if(foundLRcornera == true){break;}
+         }
+         // Search in the other direction to handle the case of 'jaggered' edges.
+         
+         ossim_int32 tempSamp_corner2b = 0;
+         ossim_int32 tempLine_corner2b = 0;
+         
+         for (ossim_int32 samp = tileRectLR.lr().x; samp > tileRectLR.ul().x; --samp)
+         {
+            for (ossim_int32 line = tileRectLR.lr().y; line >= tileRectLR.ur().y; --line)
+            { 
+               if(!(dataLR->isNull(ossimIpt(samp,line),0)))
+               {
+                  
+                  foundLRcornerb = true;
+                  rightCornerLine_B = line;
+                  rightCorner_B = samp;
+                  tempLine_corner2b = line;
+                  tempSamp_corner2b = samp;
+                  
+                  if (traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+                        <<"\nFound non null in lr corner pass 2"<<std::endl
+                        <<"line:  "<<line<<std::endl
+                        <<"samp:  "<<samp<<std::endl;
+                  }
+               }
+               if(foundLRcornerb == true){break;}
+            }
+            if(foundLRcornerb == true){break;}
+         }
+         //Better corner
+         if(foundLRcornerb == true && foundLRcornera ==true)
+         {
+            rightCornerLine_B = (tempLine_corner2a + tempLine_corner2b)/2;
+            rightCorner_B     = (tempSamp_corner2a + tempSamp_corner2b)/2;
+         }
+         // Suboptimal LL corner:
+         leftCornerLine_B = (bottomLine);
+         leftCorner_B = (leftMostSample); //3
+
+      }
+
+      //Look for non-null starting at bottomLine and going up
+      //Starting at left most samp and moving right 
+      
+      bool foundLLcornera = false;
+      bool foundLLcornerb = false;
+      
+      ossimIrect tileRectLL((leftMostSample),
+                            (bottomLine - 50),
+                            (leftMostSample +50),
+                            (bottomLine) );
+      
+      ossimRefPtr<ossimImageData> dataLL = src->getTile(tileRectLL);
+      // ossimIrect imageRectangleLL = dataLL->getImageRectangle();
+      
+      ossim_int32 tempSamp_corner3a = 0;
+      ossim_int32 tempLine_corner3a = 0;
+
+      if (dataLL.valid())
+      {
+         for (ossim_int32 samp = tileRectLL.ul().x; samp <= tileRectLL.ur().x; ++samp)
+         {
+            
+            for (ossim_int32 line = tileRectLL.lr().y; line >= tileRectLL.ul().y; --line)
+               
+            {
+               
+               if(!(dataLL->isNull(ossimIpt(samp,line),0)))
+               {
+                  
+                  foundLLcornera = true;
+                  leftCornerLine_B = line;
+                  leftCorner_B = samp;
+                  tempLine_corner3a = line;
+                  tempSamp_corner3a = samp;
+                  
+                  if (traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+                        <<"\nFound non null in ll corner pass 1"<<std::endl
+                        <<"line:  "<<line<<std::endl
+                        <<"samp:  "<<samp<<std::endl;
+                  }
+               }
+               if(foundLLcornera == true){break;}
+            }
+            if(foundLLcornera == true){break;}
+         }
+         
+         // Search in the other direction to handle the case of 'jaggered' edges.
+         
+         ossim_int32 tempSamp_corner3b = 0;
+         ossim_int32 tempLine_corner3b = 0;
+         for (ossim_int32 line = tileRectLL.lr().y; line >= tileRectLL.ul().y; --line)
+         {
+            
+            for (ossim_int32 samp = tileRectLL.ul().x; samp <= tileRectLL.ur().x; ++samp)
+               
+            {
+               
+               if(!(dataLL->isNull(ossimIpt(samp,line),0)))
+               {
+                  
+                  foundLLcornerb = true;
+                  leftCornerLine_B = line;
+                  leftCorner_B = samp;
+                  tempLine_corner3b = line;
+                  tempSamp_corner3b = samp;
+                  
+                  if (traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+                        <<"\nFound non null in ll corner pass 2 "<<std::endl
+                        <<"line:  "<<line<<std::endl
+                        <<"samp:  "<<samp<<std::endl;
+                  }
+               }
+               if(foundLLcornerb == true){break;}
+            }
+            if(foundLLcornerb == true){break;}
+         }
+         
+         //Better corner
+         if(foundLLcornerb == true && foundLLcornera ==true)
+         {
+            leftCornerLine_B = (tempLine_corner3a + tempLine_corner3b)/2;
+            leftCorner_B     = (tempSamp_corner3a + tempSamp_corner3b)/2;
+         }
+      }
+   }
+   
+   theVertice[0].x = leftCorner_A;
+   theVertice[0].y = leftCornerLine_A;
+   
+   theVertice[1].x = rightCorner_A;
+   theVertice[1].y = rightCornerLine_A;
+   
+   theVertice[3].x = leftCorner_B;
+   theVertice[3].y = leftCornerLine_B;
+   
+   theVertice[2].x = rightCorner_B;
+   theVertice[2].y = rightCornerLine_B;
+   
+   if (leftSlope)
+   {
+      delete [] leftSlope;
+      leftSlope = NULL;
+   }
+   if (rightSlope)
+   {
+      delete [] rightSlope;
+      rightSlope = NULL;
+   }
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)<<"\nleftMostSample:      " << leftMostSample
+                                         <<"\nleftMostSampleLine:  " << leftMostSampleLine
+                                         <<"\n\nrightMostSample:   " << rightMostSample
+                                         <<"\nrightMostSampleLine: " << rightMostSampleLine
+         
+                                         <<"\n\nfirstLeftSample:   " << firstLeftSample
+                                         <<"\nfirstRightSample:    " << firstRightSample
+         
+                                         <<"\n\nlastLeftSample:    " << lastLeftSample 
+                                         <<"\nlastRightSample:     " << lastRightSample
+         
+                                         <<"\n\ntopLine:           " << topLine
+                                         <<"\nbottomLine:          " << bottomLine           
+                                         <<"\ntotal_lines:         " << total_lines
+         
+                                         << "\n\n\ntheVertice[0]:      " << theVertice[0]
+                                         << "\ntheVertice[1]:      " << theVertice[1]
+                                         << "\ntheVertice[2]:      " << theVertice[2]
+                                         << "\ntheVertice[3]:      " << theVertice[3]
+                                         << "\n\nreturning..." << std::endl;
+   }
+   
+   return true;
+}
+
+bool ossimVertexExtractor::writeVertices()
+{
+   static const char MODULE[] = "ossimVertexExtractor::writeVertices";
+
+   if (traceDebug()) CLOG << " Entered..." << endl;
+   
+   if (!isOpen())
+   {
+      // Try to open.
+      if (!open()) return false;
+   }
+
+   // Write the points...
+   theFileStream << "point0.x:  " << theVertice[0].x
+                 << "\npoint0.y:  " << theVertice[0].y
+                 << "\npoint1.x:  " << theVertice[1].x
+                 << "\npoint1.y:  " << theVertice[1].y
+                 << "\npoint2.x:  " << theVertice[2].x
+                 << "\npoint2.y:  " << theVertice[2].y
+                 << "\npoint3.x:  " << theVertice[3].x
+                 << "\npoint3.y:  " << theVertice[3].y
+                 << endl;
+
+   // Close the file...
+   close();
+
+   return true;
+}
+
+
+void ossimVertexExtractor::setOutputName(const ossimString& filename)
+{
+   ossimOutputSource::setOutputName(filename);
+
+   if (isOpen()) close();
+   
+   theFilename = filename;
+}
+
+void ossimVertexExtractor::setAreaOfInterest(const ossimIrect& rect)
+{
+   theAreaOfInterest = rect;
+}
+
+bool ossimVertexExtractor::isOpen()const
+{
+   return const_cast<ofstream*>(&theFileStream)->is_open();
+}
+
+bool ossimVertexExtractor::open()
+{
+   if(isOpen())
+   {
+      close();
+   }
+
+   if (theFilename == ossimFilename::NIL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimVertexExtractor::open WARNING:"
+                                          << "\nOutput file has not been set.  Call setFilename() method..."
+                                          << std::endl;
+      return false;
+   }
+   
+   theFileStream.open(theFilename.c_str());
+         
+   return theFileStream.good();
+}
+
+void ossimVertexExtractor::close()
+{
+   if (isOpen()) theFileStream.close();
+}
+
+template<class T1>
+void ossimVertexExtractor::getMinAndIndex(T1* start, T1* end,
+                                          T1& minValue, ossim_int32& offsetFromStart)
+{
+   
+   offsetFromStart =0;
+   ossim_int32 currentOffset = 0;
+   minValue  = *start;
+   while(start < end)
+   {
+      if(*start < minValue)
+      {
+         
+         minValue = *start;
+         offsetFromStart = currentOffset;
+      }
+      ++start;
+      ++currentOffset;
+   }
+}
+
+template<class T2>
+void ossimVertexExtractor::getMaxAndIndex(T2* start, T2* end,
+                                          T2& maxValue, ossim_int32& offsetFromStart)
+{
+   
+   offsetFromStart =0;
+   ossim_int32 currentOffset = 0;
+   maxValue  = *start;
+   while(start < end)
+   {
+      if(*start > maxValue)
+      {
+         maxValue = *start;
+         offsetFromStart = currentOffset;
+      }
+      ++start;
+      ++currentOffset;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/misc/ossimVertexExtractor.h b/Utilities/OSSIM/ossim_core/imaging/misc/ossimVertexExtractor.h
new file mode 100644
index 0000000000..352a27405a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/misc/ossimVertexExtractor.h
@@ -0,0 +1,173 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: David Burken (dburken@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimVertexExtractor.h,v 1.15 2004/04/09 19:11:34 gpotts Exp $
+
+#ifndef ossimVertexExtractor_HEADER
+#define ossimVertexExtractor_HEADER
+
+#include <fstream>
+
+#include <base/common/ossimOutputSource.h>
+#include <base/common/ossimProcessInterface.h>
+#include <base/common/events/ossimProcessProgressEvent.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <imaging/ossimImageSource.h>
+
+class ossimImageSource;
+
+
+//! Class ossimVertexExtractor
+
+/*!
+ *  Class designed to scan the area of interest and detect the valid vertices
+ *  of non null image data.
+ */
+class OSSIMDLLEXPORT ossimVertexExtractor : public ossimOutputSource,
+    public ossimProcessInterface
+{
+public:
+   ossimVertexExtractor(ossimImageSource* inputSource=NULL);
+
+   virtual ~ossimVertexExtractor();
+
+  virtual ossimObject* getObject()
+  {
+    return this;
+  }
+  virtual const ossimObject* getObject()const
+  {
+    return this;
+  }
+   /*!
+    *  Sets the area of interest in the source to extract the vertices from.
+    *  @param rect ossimIrec representing source area of interest.
+    */
+   void setAreaOfInterest(const ossimIrect& rect);
+
+   /*!
+    *  Sets the name of the output keyword list file which the vertices will
+    *  be dumped to.
+    *  @param filename ossimFilename representing the output file.
+    *
+    *  Note:
+    *  - If "theFileStream" is open it will be closed.
+    */
+   virtual void setOutputName(const ossimString& filename);
+
+   /*!
+    *  Returns true if "theFileStream" is open, false if not.
+    */
+   virtual bool isOpen() const;
+
+   /*!
+    * Opens "theFilename" for output.
+    * Returns true on success, false on error.
+    * Notes:
+    * - If the file was previously open then it will close it and re-opens the
+    *   file.
+    * - Returns false if "theFilename" has not been set.
+    */
+   virtual bool open();
+
+   /*!
+    *  Closes "theFileStream".
+    */
+   virtual void close();
+
+   /*!
+    *  Calls protected methods scanForEdges, extractVertices, and
+    *  writeVertices.  Will error out if "theFilename" or "theAreaOfInterest
+    *  has not been set or "theFilename" could not be opened.
+    */
+   virtual bool execute();
+
+   virtual ossimObject* getObjectInterface() { return this; }
+
+   virtual ossimListenerManager* getListenerManagerInterface()
+      {
+         return this;
+      }
+   
+   
+   virtual void setPercentComplete(double percentComplete)
+      {
+         ossimProcessInterface::setPercentComplete(percentComplete);
+         ossimProcessProgressEvent event(this,
+                                         percentComplete);
+         fireEvent(event);      
+      }
+
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const
+      {
+         
+         return (object&& PTR_CAST(ossimImageSourceInterface, object));
+      }
+
+   vector<ossimIpt> getVertices() { return theVertice; }
+   
+private:
+   /*!
+    *  Walks each line from left and right side detecting first non null pixel.
+    *  Returns true on success, false on error.
+    */
+   bool scanForEdges();
+
+   /*!
+    *  Extracts the vertices of the source.  Uses "theLeftEdge" and
+    *  "theRightEdge" data members.
+    *  Returns true on success, false on error.
+    */
+   bool extractVertices();
+
+   template<class T1>
+   void getMinAndIndex(T1* start, T1* end,
+                       T1& minValue, ossim_int32& offsetFromStart);
+   template<class T2>
+   void getMaxAndIndex(T2* start, T2* end,
+                       T2& maxValue, ossim_int32& offsetFromStart);
+   
+   /*!
+    *  Writes the result to the output file (theFilename).
+    *  Returns true on success, false on error.
+    */
+
+   
+   bool writeVertices();
+
+   ossimIrect       theAreaOfInterest;
+   ossimFilename    theFilename;
+   std::ofstream    theFileStream;
+   vector<ossimIpt> theVertice;
+   ossim_int32*     theLeftEdge;
+   ossim_int32*     theRightEdge;
+
+   //! Disallow copy constructor and operator=
+   ossimVertexExtractor(const ossimVertexExtractor&) {}
+   const ossimVertexExtractor& operator=(const ossimVertexExtractor& rhs)
+      {return rhs;}
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimIgenGenerator.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimIgenGenerator.cpp
new file mode 100644
index 0000000000..8fb88bec5f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimIgenGenerator.cpp
@@ -0,0 +1,703 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimIgenGenerator.cpp,v 1.33 2005/05/09 12:39:38 dburken Exp $
+#include <imaging/ossimIgenGenerator.h>
+#include <base/common/ossimKeywordNames.h>
+#include <imaging/ossimImageSourceInterface.h>
+#include <imaging/ossimImageChain.h>
+#include <imaging/tile_sources/ossimGeoPolyCutter.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/misc/ossimUsgsQuad.h>
+
+void ossimIgenGenerator::generateSpecList(bool outputToFileFlag)
+{
+   if(theTilingFlag&&
+      (theTileSpacingUnits!=OSSIM_UNIT_UNKNOWN)&&
+      (!theTileSpacing.hasNans()))
+   {
+      generateTiledSpecList(outputToFileFlag);
+   }
+   else
+   {
+      generateNoTiledSpecList(outputToFileFlag);
+   }
+   
+}
+
+void ossimIgenGenerator::getImageFilenamesFromSpecList(std::vector<ossimFilename>& filenameList)
+{
+   if(!theSpecList.size())
+   {
+      generateSpecList();
+   }
+   if(theSpecList.size())
+   {
+      filenameList.clear();
+      for(ossim_uint32 i = 0; i < theSpecList.size(); ++i)
+      {
+         const char* filename = theSpecList[i].find("object2.",  ossimKeywordNames::FILENAME_KW);
+
+         if(filename)
+         {
+            filenameList.push_back(ossimFilename(filename));
+         }
+         else
+         {
+            filenameList.clear();
+            return;
+         }
+      }
+   }
+   
+}
+
+ossimGrect ossimIgenGenerator::getBoundingGround()const
+{
+   return ossimGrect(theOutputGeoPolygon[0],
+                     theOutputGeoPolygon[1],
+                     theOutputGeoPolygon[2],
+                     theOutputGeoPolygon[3]);
+}
+
+void ossimIgenGenerator::executeSpecList()
+{
+}
+
+void ossimIgenGenerator::setInput(ossimConnectableObject* input)
+{
+   theSpecList.clear();
+   generateInputKwl(input);
+   ossimImageSourceInterface* inputInterface = PTR_CAST(ossimImageSourceInterface,
+                                                        input);
+   if(inputInterface)
+   {
+      theInputBoundingRect = inputInterface->getBoundingRect();
+   }
+}
+
+
+void ossimIgenGenerator::generateChainForMultiInput(ossimConnectableObject* connectable)
+{
+   std::stack<ossimConnectableObject*> aStack;
+
+   generateChainForMultiInputRecurse(aStack, connectable);
+
+   ossim_int32 objectIndex = 1;
+   while(!aStack.empty())
+   {
+      ossimConnectableObject* current = aStack.top();
+      aStack.pop();
+      ossimString prefix = ossimString("object") + ossimString::toString(objectIndex) + ".";
+
+      current->saveState(theInputKwl, prefix.c_str());
+
+      ++objectIndex;
+   }
+   theInputKwl.add("type",
+                   "ossimImageChain",
+                   true);
+   
+}
+
+void ossimIgenGenerator::generateChainForMultiInputRecurse(std::stack<ossimConnectableObject*>& aStack,
+                                                           ossimConnectableObject* connectable)
+{
+   
+
+   if(connectable)
+   {
+      aStack.push(connectable);
+      for(ossim_uint32 i = 0; i < connectable->getNumberOfInputs(); ++i)
+      {
+         generateChainForMultiInputRecurse(aStack,
+                                           connectable->getInput(i));
+      }
+   }   
+}
+
+
+ossimProjection* ossimIgenGenerator::createProductProjection()const
+{
+   return ossimProjectionFactoryRegistry::instance()->createProjection(theViewKwl);
+}
+
+ossimObject* ossimIgenGenerator::createOutput()const
+{
+   return ossimObjectFactoryRegistry::instance()->createObject(theOutputKwl);
+}
+
+ossimObject* ossimIgenGenerator::createInput()const
+{
+   return ossimObjectFactoryRegistry::instance()->createObject(theInputKwl);
+}
+
+void ossimIgenGenerator::generateInputKwl(ossimConnectableObject* connectable)
+{
+   theInputKwl.clear();
+   if(connectable)
+   {
+      // if it has at least one non null input
+      // then  we must build a chain and save it out
+      if(connectable->getInput())
+      {
+         generateChainForMultiInput(connectable);
+      }
+      else // it is a single input
+      {
+         connectable->saveState(theInputKwl);
+      }
+   }
+}
+
+void ossimIgenGenerator::generateOutputKwl(ossimConnectableObject* connectable)
+{
+   theOutputKwl.clear();
+   if(connectable)
+   {
+      connectable->saveState(theOutputKwl);
+   }
+}
+
+void ossimIgenGenerator::generateViewKwl(ossimObject* view)
+{
+   theViewKwl.clear();
+   if(view)
+   {
+      view->saveState(theViewKwl);
+   }
+}
+   
+void ossimIgenGenerator::setDefaultOutput()
+{
+   
+}
+
+void ossimIgenGenerator::generateTiledSpecList(bool outputToFileFlag)
+{
+   theSpecList.clear();
+   theSpecFileList.clear();
+   ossimDpt spacing = theTileSpacing;
+
+   switch(theTileSpacingUnits)
+   {
+      case OSSIM_MINUTES:
+      {
+         spacing.x /= 60;
+         spacing.y /= 60;
+         generateGeoTiledSpecList(spacing, outputToFileFlag);
+         break;
+      }
+      case OSSIM_SECONDS:
+      {
+         spacing.x /= 3600;
+         spacing.y /= 3600;
+         generateGeoTiledSpecList(spacing, outputToFileFlag);
+         break;
+      }
+      case OSSIM_DEGREES:
+      {
+         generateGeoTiledSpecList(spacing, outputToFileFlag);
+         break;
+      }
+      case OSSIM_PIXEL:
+      {
+         generatePixelTiledSpecList(outputToFileFlag);
+         break;
+      }
+      default:
+         break;
+   }
+}
+
+void ossimIgenGenerator::generatePixelTiledSpecList(bool outputToFileFlag)
+{
+   ossimProjection* proj = createProductProjection();
+
+   if((!proj)||(theOutputGeoPolygon.size() != 4))
+   {
+      return;
+   }
+   
+   ossimIrect inputRect = getInputBoundingRect();
+   inputRect.stretchToTileBoundary(theTileSpacing);
+   ossimGeoPolygon tempPoly;
+   ossimObject* obj = createInput();
+   ossimImageChain* chain = PTR_CAST(ossimImageChain,
+                                     obj);
+   ossimGeoPolyCutter* cutter = new ossimGeoPolyCutter;
+   chain->add(cutter);
+   
+   ossimKeywordlist kwl;
+   ossimFilename outfile = theOutputKwl.find(ossimKeywordNames::FILENAME_KW);
+   
+   if(outfile == "")
+   {
+      cerr << "Valid filename not given, returning!" << endl;
+   }
+   
+   kwl.add("object2.", theOutputKwl, true);
+   kwl.add("product.projection.",theViewKwl, true);
+   addPixelType(kwl, "product.");   
+   ossimDpt p1;
+   ossimDpt p2;
+   ossimDpt p3;
+   ossimDpt p4;
+
+   
+   proj->worldToLineSample(theOutputGeoPolygon[0], p1);
+   proj->worldToLineSample(theOutputGeoPolygon[1], p2);
+   proj->worldToLineSample(theOutputGeoPolygon[2], p3);
+   proj->worldToLineSample(theOutputGeoPolygon[3], p4);
+
+   ossimIrect bounds(p1, p2, p3, p4);
+   if(inputRect.completely_within(bounds))
+   {
+      inputRect = bounds;
+   }
+
+   bounds.stretchToTileBoundary(theTileSpacing);
+   
+   ossim_sint32 i = 1;
+   for(ossim_sint32 ulY = bounds.ul().y; ulY < bounds.lr().y; ulY+=(ossim_sint32)theTileSpacing.y)
+   {
+      for(ossim_sint32 ulX = bounds.ul().x; ulX < bounds.lr().x; ulX+=(ossim_sint32)theTileSpacing.x)
+      {
+         ossimDrect rect(ulX,
+                         ulY,
+                         ulX + (theTileSpacing.x - 1),
+                         ulY + (theTileSpacing.y - 1));
+         ossimGpt gpt1;
+         ossimGpt gpt2;
+         ossimGpt gpt3;
+         ossimGpt gpt4;
+
+         proj->lineSampleToWorld(rect.ul(), gpt1);
+         proj->lineSampleToWorld(rect.ur(), gpt2);
+         proj->lineSampleToWorld(rect.lr(), gpt3);
+         proj->lineSampleToWorld(rect.ll(), gpt4);
+         
+         tempPoly.clear();
+         tempPoly.addPoint(gpt1);
+         tempPoly.addPoint(gpt2);
+         tempPoly.addPoint(gpt3);
+         tempPoly.addPoint(gpt4);
+         addPadding(tempPoly, tempPoly);
+         cutter->setPolygon(tempPoly);
+         chain->saveState(kwl, "object1.");
+         
+         ossimFilename specName(theSpecFileLocation);
+         specName = specName.dirCat(ossimFilename("igen" + ossimString::toString(i) + ".spec"));
+         ossimFilename tilename = outfile.path();
+         if(theTileNamingConvention == "id")
+         {
+            int tileId = getTileId(inputRect, ossimDpt(ulX+theTileSpacing.x/2, ulY+theTileSpacing.y/2), theTileSpacing);
+            tilename = tilename.dirCat(ossimFilename(outfile.fileNoExtension() + "_" +
+                                                     ossimString::toString(tileId)));
+            tilename.setExtension(outfile.ext());
+         }
+         
+         kwl.add("object2.",
+                 ossimKeywordNames::FILENAME_KW,
+                 tilename,
+                 true);
+         kwl.add("object2.input_connection1",
+                 kwl.find("object1.id"),
+                 true);
+         theSpecFileList.push_back(specName);
+         if(outputToFileFlag)
+         {
+            kwl.write(specName.c_str());
+         }
+         else
+         {
+            theSpecList.push_back(kwl);
+         }
+         i++;
+      }
+   }
+   if(proj)
+   {
+      delete proj;
+      proj = NULL;
+   }
+   
+}
+
+void ossimIgenGenerator::generateGeoTiledSpecList(const ossimDpt& spacing, bool outputToFileFlag)
+{
+   ossimProjection* proj = createProductProjection();
+   if((proj)&&(theOutputGeoPolygon.size() == 4))
+   {
+      ossimDrect rect;
+
+      ossimIrect inputRect = getInputBoundingRect();
+      ossimGpt gpt1;
+      ossimGpt gpt2;
+      ossimGpt gpt3;
+      ossimGpt gpt4;
+      proj->lineSampleToWorld(inputRect.ul(), gpt1);
+      proj->lineSampleToWorld(inputRect.ur(), gpt2);
+      proj->lineSampleToWorld(inputRect.lr(), gpt3);
+      proj->lineSampleToWorld(inputRect.ll(), gpt4);
+
+      ossimDrect inputGroundRect(gpt1,
+                                 gpt2,
+                                 gpt3,
+                                 gpt4,
+                                 OSSIM_RIGHT_HANDED);
+      
+      rect = ossimDrect(theOutputGeoPolygon[0],
+                        theOutputGeoPolygon[1],
+                        theOutputGeoPolygon[2],
+                        theOutputGeoPolygon[3],
+                        OSSIM_RIGHT_HANDED);
+
+      rect.stretchToTileBoundary(spacing);
+      inputGroundRect.stretchToTileBoundary(spacing);
+      double ulLat = rect.ul().lat;
+      double ulLon = rect.ul().lon;
+      ossimGeoPolygon tempPoly;
+      ossimObject* obj = createInput();
+      ossimImageChain* chain = PTR_CAST(ossimImageChain,
+                                        obj);
+      ossimGeoPolyCutter* cutter = new ossimGeoPolyCutter;
+      chain->add(cutter);
+      
+      ossimKeywordlist kwl;
+      ossimFilename outfile = theOutputKwl.find(ossimKeywordNames::FILENAME_KW);
+
+      if(outfile == "")
+      {
+         cerr << "Valid filename not given, returning!" << endl;
+      }
+      
+      kwl.add("object2.", theOutputKwl, true);
+      kwl.add("object2.input_connection1",
+              kwl.find("object1.id"),
+              true);
+      kwl.add("product.projection.",theViewKwl, true);
+      addPixelType(kwl, "product.");   
+      int i = 1;
+      int row = 0;
+      int col = 0;
+      //      int tileId = 0;
+      while(ulLat > rect.ll().lat)
+      {
+         ulLon = rect.ul().lon;
+         col = 0;
+         while(ulLon < rect.ur().lon)
+         {
+            tempPoly.clear();
+            tempPoly.addPoint(ulLat, ulLon, OSSIM_DBL_NAN, theOutputGeoPolygon[0].datum());
+            tempPoly.addPoint(ulLat, ulLon+spacing.lon, OSSIM_DBL_NAN, theOutputGeoPolygon[0].datum());
+            tempPoly.addPoint(ulLat-spacing.lat, ulLon+spacing.lon, OSSIM_DBL_NAN, theOutputGeoPolygon[0].datum());
+            tempPoly.addPoint(ulLat-spacing.lat, ulLon, OSSIM_DBL_NAN, theOutputGeoPolygon[0].datum());
+            
+            addPadding(tempPoly, tempPoly);
+            cutter->setPolygon(tempPoly);
+            chain->saveState(kwl, "object1.");
+
+            ossimFilename specName(theSpecFileLocation);
+            specName = specName.dirCat(ossimFilename("igen" + ossimString::toString(i) + ".spec"));
+	    ossimFilename tilename = outfile.path();
+	    if(theTileNamingConvention == "id")
+	      {
+		int tileId = getTileId(inputGroundRect, ossimDpt(ulLon, ulLat), spacing);
+		tilename = tilename.dirCat(ossimFilename(outfile.fileNoExtension() + "_" +
+							 ossimString::toString(tileId)));
+		tilename.setExtension(outfile.ext());
+	      }
+	    else
+	      {
+                 ossimUsgsQuad quad(ossimGpt(ulLat - (spacing.x), ulLon+(spacing.x), 0.0));
+                 if(spacing.x == 7.5/60.0)
+                 {
+                    tilename = tilename.dirCat(ossimFilename(quad.quarterQuadName().downcase().trim()));
+                 }
+                 else
+                 {
+                    tilename = tilename.dirCat(ossimFilename(quad.quarterQuadSegName().downcase().trim()));
+                 }
+                 
+                 tilename.setExtension(outfile.ext());
+	      }
+
+	    kwl.add("object2.",
+		    ossimKeywordNames::FILENAME_KW,
+		    tilename,
+		    true);
+            kwl.add("object2.input_connection1",
+                    kwl.find("object1.id"),
+                    true);
+            theSpecFileList.push_back(specName);
+            if(outputToFileFlag)
+            {
+               kwl.write(specName.c_str());
+            }
+            else
+            {
+               theSpecList.push_back(kwl);
+            }
+            ulLon += spacing.lon;
+            ++i;
+            ++col;
+         }
+         ++row;
+         ulLat -= spacing.lat;
+      }
+
+      if(proj)
+      {
+         delete proj;
+         proj = NULL;
+      }
+   }   
+}
+
+
+void ossimIgenGenerator::generateNoTiledSpecList(bool outputToFileFlag)
+{
+   theSpecList.clear();
+   theSpecFileList.clear();
+   
+   if(theViewKwl.getSize()&&
+      theInputKwl.getSize()&&
+      theOutputKwl.getSize())
+   {
+      ossimKeywordlist kwl;
+      long id = 0;
+      if(theOutputGeoPolygon.size())
+      {
+         ossimObject* obj = createInput();
+         ossimImageChain* chain = PTR_CAST(ossimImageChain,
+                                           obj);
+         if(chain)
+         {
+            ossimGeoPolyCutter* cutter = new ossimGeoPolyCutter;
+            
+            cutter->setPolygon(theOutputGeoPolygon);
+            
+            chain->add(cutter);
+            chain->saveState(kwl, "object1.");
+            id = chain->getId().getId();
+         }
+         else
+         {
+            kwl.add("object1.",theInputKwl, true);
+         }
+
+         if(obj)
+         {
+            delete obj;
+         }
+      }
+      else
+      {
+         kwl.add("object1.",theInputKwl, true);
+      }
+      kwl.add("object2.", theOutputKwl, true);
+      kwl.add("object2.input_connection1",
+              kwl.find("object1.id"),
+              true);
+      kwl.add("product.projection.",theViewKwl, true);
+      addPixelType(kwl, "product.");   
+
+      ossimFilename specName(theSpecFileLocation +
+                             "/"+
+                             "igen1.spec");
+      
+      theSpecFileList.push_back(specName);
+      if(outputToFileFlag)
+      {
+         kwl.write(specName.c_str());
+      }
+      else
+      {
+         theSpecList.push_back(kwl);
+      }
+      
+      kwl.clear();
+   }
+}
+
+int ossimIgenGenerator::getTileId(const ossimDrect& rect,
+				  const ossimDpt& currentPt,
+				  const ossimDpt& spacing)const
+{
+   ossimDpt ul(rect.ul());
+   
+   double relY = fabs(ul.y - currentPt.y);
+   double relX = fabs(ul.x - currentPt.x);
+   
+   
+   ossim_int32 spacingY           = (ossim_int32)(relY/spacing.y);
+   ossim_int32 spacingX           = (ossim_int32)(relX/spacing.x);
+   ossim_int32 maxHorizontalTiles = (ossim_int32)( (rect.width()-1)/spacing.x);
+   
+   return spacingY*maxHorizontalTiles + spacingX;
+}
+
+
+ossimIrect ossimIgenGenerator::getInputBoundingRect()const
+{
+   ossimObject* obj = createInput();
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface, obj);
+   ossimIrect result;
+
+   result.makeNan();
+   if(inter)
+   {
+      result = inter->getBoundingRect();
+   }
+   if(obj)
+   {
+      delete obj;
+   }
+   return result;
+}
+
+void ossimIgenGenerator::addPadding(ossimGeoPolygon& output,
+                                    const ossimGeoPolygon& input)const
+{
+   output = input;
+   switch(theTilePaddingUnits)
+   {
+      case OSSIM_PIXEL:
+      {
+         ossimProjection* proj = createProductProjection();
+         if(proj)
+         {
+            ossimDpt ul;
+            ossimDpt ur;
+            ossimDpt lr;
+            ossimDpt ll;
+
+            if(input.getOrdering() == OSSIM_CLOCKWISE_ORDER)
+            {
+               proj->worldToLineSample(input[0], ul);
+               proj->worldToLineSample(input[1], ur);
+               proj->worldToLineSample(input[2], lr);
+               proj->worldToLineSample(input[3], ll);
+            }
+            else
+            {
+               proj->worldToLineSample(input[0], ul);
+               proj->worldToLineSample(input[1], ll);
+               proj->worldToLineSample(input[2], lr);
+               proj->worldToLineSample(input[3], ur);
+            
+            }
+            
+            ul -= theTilePadding;
+            ur += ossimDpt(theTilePadding.x,
+                           -theTilePadding.y);
+            lr += theTilePadding;
+            ll += ossimDpt(-theTilePadding.x,
+                           theTilePadding.y);
+
+            proj->lineSampleToWorld(ul, output[0]);
+            proj->lineSampleToWorld(ur, output[1]);
+            proj->lineSampleToWorld(lr, output[2]);
+            proj->lineSampleToWorld(ll, output[3]);
+
+            output.setOrdering(OSSIM_CLOCKWISE_ORDER);
+         
+            delete proj;
+         }
+         break;
+      }
+      case OSSIM_DEGREES:
+      case OSSIM_MINUTES:
+      case OSSIM_SECONDS:
+      {
+         ossimGpt ul;
+         ossimGpt ur;
+         ossimGpt lr;
+         ossimGpt ll;
+         ossimDpt spacing = theTilePadding;
+
+         if(theTilePaddingUnits==OSSIM_MINUTES)
+         {
+            spacing.x /= 60;
+            spacing.y /= 60;
+         }
+         else if(theTilePaddingUnits==OSSIM_MINUTES)
+         {
+            spacing.x /= 3600;
+            spacing.y /= 3600;
+         }
+      
+         if(input.getOrdering() == OSSIM_CLOCKWISE_ORDER)
+         {
+            ul = input[0];
+            ur = input[1];
+            lr = input[2];
+            ll = input[3];
+         }
+         else
+         {
+            ul = input[0];
+            ll = input[1];
+            lr = input[2];
+            ur = input[3];
+         }
+         ul.lat += spacing.lat;
+         ul.lon -= spacing.lon;
+         ur.lat += spacing.lat;
+         ur.lon += spacing.lon;
+         lr.lat -= spacing.lat;
+         lr.lon += spacing.lon;
+         ll.lat -= spacing.lat;
+         ll.lon -= spacing.lon;
+
+         output[0] = ul;
+         output[1] = ur;
+         output[2] = lr;
+         output[3] = ll;
+         output.setOrdering(OSSIM_CLOCKWISE_ORDER);
+      
+         break;
+      }
+      case OSSIM_METERS:
+      {
+         break;
+      }
+      default:
+         break;
+   }
+}
+
+void ossimIgenGenerator::addPixelType(ossimKeywordlist& kwl, const char* prefix)
+{
+   if(thePixelType == OSSIM_PIXEL_IS_POINT)
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::PIXEL_TYPE_KW,
+              "PIXEL_IS_POINT",
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::PIXEL_TYPE_KW,
+              "PIXEL_IS_AREA",
+              true);
+   }
+}
+
+void ossimIgenGenerator::setOutput(const ossimKeywordlist& kwl)
+{
+   theOutputKwl.clear();
+
+   theOutputKwl = kwl;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimIgenGenerator.h b/Utilities/OSSIM/ossim_core/imaging/ossimIgenGenerator.h
new file mode 100644
index 0000000000..182c17dc98
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimIgenGenerator.h
@@ -0,0 +1,319 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimIgenGenerator.h,v 1.23 2003/09/17 20:42:57 dburken Exp $
+#ifndef ossimIgenGenerator_HEADER
+#define ossimIgenGenerator_HEADER
+#include <stack>
+
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimGrect.h"
+#include "base/data_types/ossimGeoPolygon.h"
+#include "ossimImageSource.h"
+#include "projections/ossimProjection.h"
+#include "imaging/formats/ossimImageFileWriter.h"
+
+class OSSIMDLLEXPORT ossimIgenGenerator
+{
+public:
+   ossimIgenGenerator(ossimConnectableObject* input=NULL,
+                      ossimConnectableObject*  output=NULL,
+                      ossimObject* view=NULL)
+      :thePixelType(OSSIM_PIXEL_IS_POINT),
+       theTilingFlag(false),
+       theTileSpacing(7.5, 7.5),
+       theTileSpacingUnits(OSSIM_MINUTES),
+       theTilePadding(0,0),
+       theTilePaddingUnits(OSSIM_PIXEL),
+       theNamingConvention("DEFAULT"),
+       theSpecFileLocation(""),
+       theIgenExecutable("igen"),
+       theSpecFileIndex(0),
+       theSpecListIndex(0),
+       theTileNamingConvention("id")
+      {
+         theUpperLeftTileStart.makeNan();
+         setInput(input);
+         setOutput(output);
+         setView(view);
+         theInputBoundingRect.makeNan();
+      }
+   
+   ~ossimIgenGenerator()
+      {
+      }
+   void setOutput(ossimConnectableObject* output)
+      {
+         theSpecList.clear();
+         generateOutputKwl(output);
+      }
+
+   void setOutput(const ossimKeywordlist& kwl);
+
+    void setInput(ossimConnectableObject* input);
+   
+   void setView(ossimObject* view)
+      {
+         generateViewKwl(view);
+      }
+   
+   void generateSpecList(bool outputToFileFlag = false);
+   void getImageFilenamesFromSpecList(std::vector<ossimFilename>& filenameList);
+   ossimGrect getBoundingGround()const;
+   
+   void executeSpecList();
+
+   void setIteratorsToStart()
+      {
+         theSpecFileIndex = 0;
+         theSpecListIndex = 0;
+      }
+   bool nextSpecFile(ossimFilename& specFile)
+      {
+         if(theSpecFileIndex >= theSpecFileList.size())
+         {
+            return false;
+         }
+         specFile = theSpecFileList[theSpecFileIndex];
+         ++theSpecFileIndex;
+         return true;
+      }
+   void getSpecs(vector<ossimKeywordlist>& specList)const
+      {
+         specList = theSpecList;
+      }
+   
+   ossim_uint32 getNumberOfSpecFiles()const
+      {
+         return theSpecFileList.size();
+      }
+
+   ossimFilename getSpecFilename(ossim_uint32 specFileIndex = 0)const
+      {
+         if(specFileIndex < theSpecFileList.size())
+         {
+            return theSpecFileList[specFileIndex];
+         }
+
+         return ossimFilename("");
+      }
+   ossimFilename buildExe(ossim_uint32 i = 0)const
+      {
+         ossimFilename igenExe  = getIgenExecutable();
+         ossimFilename specFile = getSpecFilename(i);
+
+         return ossimFilename( igenExe + " " + specFile);
+      }
+   
+   void getSpec(ossimKeywordlist& kwl,
+                ossim_uint32 specIndex=0)
+      {
+         kwl.clear();
+
+         if(specIndex < theSpecList.size())
+         {
+            kwl = theSpecList[specIndex];
+         }
+      }
+   void getInput(ossimKeywordlist& kwl,
+                 const char* prefix=NULL)const
+      {
+         kwl.add(prefix,
+                 theInputKwl,
+                 true);
+      }
+   void getOutput(ossimKeywordlist& kwl,
+                  const char* prefix=NULL)const
+      {
+         kwl.add(prefix,
+                 theOutputKwl,
+                 true);
+      }
+   
+   void getView(ossimKeywordlist& kwl,
+                const char* prefix=NULL)const
+      {
+         kwl.add(prefix,
+                 theViewKwl,
+                 true);
+      }
+
+   void setView(ossimKeywordlist& kwl,
+                const char* prefix = NULL)
+      {
+         theViewKwl.clear();
+         theViewKwl.add(prefix,
+                        kwl,
+                        true);
+      }
+   void setOutput(ossimKeywordlist& kwl,
+                  const char* prefix = NULL)
+      {
+         theOutputKwl.clear();
+         theOutputKwl.add(prefix,
+                          kwl,
+                          true);
+      }
+   void setSpecFileLocation(const ossimFilename& filename)
+      {
+         theSpecFileLocation = filename;
+      }
+   const ossimFilename& getSpecFileLocation()const
+      {
+         return theSpecFileLocation;
+      }
+   void setIgenExecutable(const ossimFilename& igenExecutable)
+      {
+         theIgenExecutable = igenExecutable;
+      }
+   const ossimFilename& getIgenExecutable()const
+      {
+         return theIgenExecutable;
+      }
+   void setOutputPolygon(const ossimGeoPolygon& poly)
+      {
+         theOutputGeoPolygon = poly;
+      }
+   void setPixelType(ossimPixelType pixelType)
+      {
+         thePixelType = pixelType;
+      }
+   void getOutputGeoPolygon(ossimGeoPolygon& poly)const
+      {
+         poly = theOutputGeoPolygon;
+      }
+   const ossimGeoPolygon& getOutputGeoPolygon()const
+      {
+         return theOutputGeoPolygon;
+      }
+   void setTilingFlag(bool flag)
+      {
+         theTilingFlag = flag;
+      }
+   void setTileSpacing(const ossimDpt& spacing)
+      {
+         theTileSpacing = spacing;
+      }
+   void setTilePadding(const ossimDpt& padding)
+      {
+         theTilePadding = padding;
+      }
+   void setTileSpacingUnits(ossimUnitType unitType)
+      {
+         theTileSpacingUnits = unitType;
+      }
+   void setTilePaddingUnits(ossimUnitType unitType)
+      {
+         theTilePaddingUnits = unitType;
+      }
+   bool getTilingFlag()const
+      {
+         return theTilingFlag;
+      }
+   const ossimDpt& getTileSpacing()const
+      {
+         return theTileSpacing;
+      }
+   const ossimDpt& getTilePadding()const
+      {
+         return theTilePadding;
+      }
+   ossimUnitType getTileSpacingUnits()const
+      {
+         return theTileSpacingUnits;
+      }
+   ossimUnitType getTilePaddingUnits()const
+      {
+         return theTilePaddingUnits;
+      }
+   ossimPixelType getPixelType()const
+      {
+         return thePixelType;
+      }
+  /*!
+   * Tile naming convention is a string that can be "id" or "usgs".
+   * this is used if tiling is enabled.  If id is used it will use the filename
+   * as the prefix and then add to it the id's.  If usgs is used it will name 
+   * it based on the USGS name.
+   */
+  void setTileNamingConvention(const ossimString& namingConvention)
+  {
+    theTileNamingConvention = namingConvention;
+    theTileNamingConvention = theTileNamingConvention.downcase();
+
+  }
+   const ossimString& getTileNamingConvention()const
+      {
+         return theTileNamingConvention;
+      }
+   ossimIrect getInputBoundingRect()const;
+   
+   ossimProjection* createProductProjection()const;
+   ossimObject*     createOutput()const;
+   ossimObject*     createInput()const;
+   
+protected:
+   ossimKeywordlist  theInputKwl;
+   ossimKeywordlist  theOutputKwl;
+   ossimKeywordlist  theViewKwl;
+   ossimPixelType    thePixelType;
+   bool              theTilingFlag;
+   ossimDpt          theUpperLeftTileStart;
+   ossimDpt          theTileSpacing;
+   ossimUnitType     theTileSpacingUnits;
+   ossimDpt          theTilePadding;
+   ossimUnitType     theTilePaddingUnits;
+   ossimString       theNamingConvention;
+   ossimFilename     theSpecFileLocation;
+   ossimFilename     theIgenExecutable;
+   ossim_uint32      theSpecFileIndex;
+   ossim_uint32      theSpecListIndex;
+   ossimIrect        theInputBoundingRect;
+   ossimGeoPolygon   theOutputGeoPolygon;
+   ossimString       theTileNamingConvention;
+  
+   vector<ossimKeywordlist> theSpecList;
+   vector<ossimFilename>    theSpecFileList;
+
+   void generateInputKwl(ossimConnectableObject* connectable);
+   void generateOutputKwl(ossimConnectableObject* connectable);
+   void generateViewKwl(ossimObject* view);
+   void setDefaultOutput();
+   void generateTiledSpecList(bool outputToFileFlag);
+   void generateGeoTiledSpecList(const ossimDpt& spacing, bool outputToFileFlag);
+   void generatePixelTiledSpecList(bool outputToFileFlag);
+   void generateNoTiledSpecList(bool outputToFileFlag);
+
+   void generateChainForMultiInput(ossimConnectableObject* connectable);
+   void generateChainForMultiInputRecurse(std::stack<ossimConnectableObject*>& aStack,
+                                          ossimConnectableObject* connectable);
+
+   int getTileId(const ossimDrect& rect,
+                 const ossimDpt& currentPt,
+                 const ossimDpt& spacing)const;
+   void addPadding(ossimGeoPolygon& output,
+                   const ossimGeoPolygon& input)const;
+   void addPixelType(ossimKeywordlist& kwl, const char* prefix="product.");
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageChain.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageChain.cpp
new file mode 100644
index 0000000000..a87661c8bc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageChain.cpp
@@ -0,0 +1,1809 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageChain.cpp,v 1.109 2005/11/22 19:46:46 dburken Exp $
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+
+#include <imaging/ossimImageChain.h>
+#include <base/common/ossimCommon.h>
+#include <base/context/ossimNotifyContext.h>
+#include <imaging/ossimImageData.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/events/ossimEventIds.h>
+#include <base/common/events/ossimObjectEvents.h>
+#include <base/common/ossimIdManager.h>
+
+static ossimTrace traceDebug("ossimImageChain");
+
+
+RTTI_DEF3(ossimImageChain, "ossimImageChain", ossimImageSource,
+          ossimConnectableObjectListener, ossimConnectableContainerInterface);
+
+class ossimImageChainChildListener : public ossimConnectableObjectListener
+{
+public:
+   ossimImageChainChildListener(ossimImageChain* owner)
+      :theChain(owner)
+      {
+      }
+   virtual void propertyEvent(ossimPropertyEvent& event);
+
+   ossimImageChain* theChain;
+};
+
+void ossimImageChainChildListener::propertyEvent(ossimPropertyEvent& event)
+{
+   ossimConnectableObject* obj = PTR_CAST(ossimConnectableObject,
+                                          event.getObject());
+   
+   // if it originated from within my chain then propagate up to parent
+   // only if I have no outputs
+   //
+   if(obj)
+   {
+      if(!theChain->findObject(PTR_CAST(ossimConnectableObject,event.getObject())))
+      {
+         ossimConnectableObject* interface = theChain->findObject(obj->getId(), false);
+         
+         if(interface)
+         {
+            ossimConnectableObject* parent = PTR_CAST(ossimConnectableObject,
+                                                      theChain->getOwner());
+            if(parent&&
+               !theChain->getNumberOfOutputs())
+            {
+               parent->propagateEventToOutputs(event);
+            }
+         }
+      }
+      else
+      {
+         if(!theChain->thePropagateEventFlag)
+         {
+            theChain->propagateEventToOutputs(event);
+         }
+      }
+   }
+}
+
+ossimImageChain::ossimImageChain()
+   :ossimImageSource(),
+    ossimConnectableContainerInterface((ossimObject*)NULL),
+    theBlankTile(NULL),
+    theLoadStateFlag(false)
+{
+   ossimConnectableContainerInterface::theBaseObject = this;
+   thePropagateEventFlag = false;
+   addListener((ossimConnectableObjectListener*)this);
+   theChildListener = new ossimImageChainChildListener(this);
+}
+
+ossimImageChain::~ossimImageChain()
+{
+   removeListener((ossimConnectableObjectListener*)this);
+   deleteList();
+
+   if(theChildListener)
+   {
+      delete theChildListener;
+      theChildListener = NULL;
+   }
+}
+
+bool ossimImageChain::addFirst(ossimConnectableObject* obj)
+{
+   ossimConnectableObject* rightOfThisObj =
+      (ossimConnectableObject*)getFirstObject();
+
+   return insertRight(obj, rightOfThisObj);
+}
+
+bool ossimImageChain::addLast(ossimConnectableObject* obj)
+{
+   if(theImageChainList.size() > 0)
+   {
+      ossimConnectableObject* lastSource = theImageChainList[ theImageChainList.size() -1];
+      if(PTR_CAST(ossimImageSourceInterface, obj)&&lastSource)
+      {
+         obj->disconnect();
+         vector<ossimConnectableObject*> tempIn = getInputList();
+         lastSource->disconnectAllInputs();
+         lastSource->connectMyInputTo(obj);
+         obj->changeOwner(this);
+         obj->connectInputList(tempIn);
+
+         tempIn = obj->getInputList();
+         theInputListIsFixedFlag = obj->getInputListIsFixedFlag();
+         setNumberOfInputs(obj->getNumberOfInputs());
+         theImageChainList.push_back(obj);
+         
+         obj->addListener((ossimConnectableObjectListener*)this);
+         return true;
+      }
+   }
+   else
+   {
+      return add(obj);
+   }
+
+   return false;;
+}
+
+ossimImageSourceInterface* ossimImageChain::getFirstSource()
+{
+   if(theImageChainList.size()>0)
+   {
+      return PTR_CAST(ossimImageSourceInterface,
+                      theImageChainList[0]);
+   }
+
+   return NULL;
+}
+
+ossimObject* ossimImageChain::getFirstObject()
+{
+   if(theImageChainList.size()>0)
+   {
+      return PTR_CAST(ossimObject,
+                      theImageChainList[0]);
+   }
+
+   return NULL;
+}
+
+ossimImageSourceInterface* ossimImageChain::getLastSource()
+{
+   if(theImageChainList.size()>0)
+   {
+      return PTR_CAST(ossimImageSourceInterface,
+                      *(theImageChainList.end()-1));
+   }
+
+   return NULL;
+}
+
+ossimObject* ossimImageChain::getLastObject()
+{
+   if(theImageChainList.size()>0)
+   {
+      return PTR_CAST(ossimObject,
+                      *(theImageChainList.end()-1));
+   }
+
+   return NULL;
+}
+
+ossimConnectableObject* ossimImageChain::findObject(const ossimId& id,
+                                                    bool recurse)
+{
+   vector<ossimConnectableObject*>::iterator current =  theImageChainList.begin();
+   
+   while(current != theImageChainList.end())
+   {
+      if((*current))
+      {
+	 if(id == (*current)->getId())
+         {
+            return (*current);
+         }
+      }
+
+      ++current;
+   }
+
+   current =  theImageChainList.begin();
+   
+   while(current != theImageChainList.end())
+   {
+      ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface,
+                                                         (*current));
+      
+      if(child)
+      {
+         ossimConnectableObject* object = child->findObject(id, true);
+
+         if(object) return object;
+      }
+      ++current;
+   }
+   
+   return NULL;
+}
+
+ossimConnectableObject* ossimImageChain::findObject(const ossimConnectableObject* obj,
+                                                    bool recurse)
+{
+   vector<ossimConnectableObject*>::iterator current =  theImageChainList.begin();
+   
+   while(current != theImageChainList.end())
+   {
+      if(*current)
+      {
+	 if(obj == (*current))
+         {
+            return (*current);
+         }
+      }
+
+      ++current;
+   }
+
+   current =  theImageChainList.begin();
+   
+   while(current != theImageChainList.end())
+   {
+      ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current));
+      
+      if(child)
+      {
+         ossimConnectableObject* object = child->findObject(obj, true);
+
+         if(object) return object;
+      }
+      ++current;
+   }
+   
+   return NULL;
+}
+
+// ossimImageSourceInterface* ossimImageChain::findSource(const ossimId& id)
+// {
+//    ossimImageSourceInterface* result = NULL;
+//    for(unsigned long index = 0; index < theImageChainList.size();++index)
+//    {
+//      ossimConnectableObject* obj = PTR_CAST(ossimConnectableObject, theImageChainList[index]);
+//      if(obj)
+//        {
+// 	 if(id == obj->getId())
+// 	   {
+//               return PTR_CAST(ossimImageSourceInterface,
+//                               theImageChainList[index];
+// 	   }
+//        }
+//    }
+//    // now lets search children of type ossimImageChain
+//    for(unsigned long index = 0; index < theImageChainList.size();++index)
+//    {
+//       ossimImageChain* child=PTR_CAST(ossimImageChain, theImageChainList[index]->getObject());
+//       if(child)
+//       {
+//          result = child->findSource(id);
+//          if(result)
+//          {
+//             return result;
+//          }
+//       }
+//    }
+   
+//    return result;
+// }
+
+// ossimImageSourceInterface* ossimImageChain::findFirstSourceOfType(const RTTItypeid& typeInfo)
+// {
+//    ossimImageSourceInterface* result = NULL;
+//    long index = 0;
+   
+//    for(index = 0; index < (long)theImageChainList.size();++index)
+//    {
+//       if(typeInfo.can_cast(TYPE_INFO(theImageChainList[index])))
+//       {
+//          return PTR_CAST(ossimImageSourceInterface,
+//                          theImageChainList[index]);
+//       }
+//    }
+
+//    // if still not found then search children.  It will
+//    // see if one of its children is another container of
+//    // type ossimImageChain.  If so, then it will call
+//    // its method.
+//    if(!result)
+//    {
+//       for(index = 0; index < (long)theImageChainList.size();++index)
+//       {
+//          ossimImageChain* child=PTR_CAST(ossimImageChain,
+//                                          theImageChainList[index]);
+         
+//          if(child)
+//          {
+//             result = child->findFirstSourceOfType(typeInfo);
+//             if(result)
+//             {
+//                return result;
+//             }
+//          }
+//       }
+//    }
+   
+//    return result;
+// }
+
+ossimConnectableObject* ossimImageChain::findFirstObjectOfType(const RTTItypeid& typeInfo,
+                                                               bool recurse)
+{
+   vector<ossimConnectableObject*>::iterator current =  theImageChainList.begin();
+   
+   while(current != theImageChainList.end())
+   {
+      if((*current)&&
+         (*current)->canCastTo(typeInfo))
+      {
+         return (*current);
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current =  theImageChainList.begin();
+      while(current != theImageChainList.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current));
+         
+         if(child)
+         {
+            ossimConnectableObject* temp = child->findFirstObjectOfType(typeInfo, recurse);
+            if(temp)
+            {
+               return temp;
+            }
+         }
+         ++current;
+      }
+   }
+   
+   return (ossimConnectableObject*)NULL;   
+}
+
+ossimConnectableObject* ossimImageChain::findFirstObjectOfType(const ossimString& className,
+                                                               bool recurse)
+{
+   vector<ossimConnectableObject*>::iterator current =  theImageChainList.begin();
+   
+   while(current != theImageChainList.end())
+   {
+      if((*current)&&
+         (*current)->canCastTo(className) )
+      {
+         return (*current);
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current =  theImageChainList.begin();
+      while(current != theImageChainList.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, *current);
+         
+         if(child)
+         {
+            ossimConnectableObject* temp = child->findFirstObjectOfType(className, recurse);
+            if(temp)
+            {
+               return temp;
+            }
+         }
+         ++current;
+      }
+   }
+   
+   return (ossimConnectableObject*)NULL;   
+}
+
+std::vector<ossimConnectableObject*> ossimImageChain::findAllObjectsOfType(const RTTItypeid& typeInfo,
+                                                                           bool recurse)
+{
+   std::vector<ossimConnectableObject*> result;
+   vector<ossimConnectableObject*>::iterator current =  theImageChainList.begin();
+   
+   while(current != theImageChainList.end())
+   {
+      if((*current)&&
+         (*current)->canCastTo(typeInfo))
+      {
+         vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), *current);
+         if(iter == result.end())
+         {
+            result.push_back(*current);
+         }
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current =  theImageChainList.begin();
+      while(current != theImageChainList.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, (*current));
+         
+         if(child)
+         {
+            vector<ossimConnectableObject*> temp;
+            temp = child->findAllObjectsOfType(typeInfo, recurse);
+            for(long index=0; index < (long)temp.size();++index)
+            {
+               std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), temp[index]);
+               if(iter == result.end())
+               {
+                  result.push_back(temp[index]);
+               }
+            }
+         }
+         ++current;
+      }
+   }
+   
+   return result;
+   
+}
+
+std::vector<ossimConnectableObject*> ossimImageChain::findAllObjectsOfType(const ossimString& className,
+                                                                           bool recurse)
+{
+   std::vector<ossimConnectableObject*> result;
+   vector<ossimConnectableObject*>::iterator current =  theImageChainList.begin();
+   
+   while(current != theImageChainList.end())
+   {
+      if((*current)&&
+         (*current)->canCastTo(className))
+      {
+         std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), (*current));
+         if(iter == result.end())
+         {
+            result.push_back(*current);
+         }
+      }
+      ++current;
+   }
+
+   if(recurse)
+   {
+      current =  theImageChainList.begin();
+      while(current != theImageChainList.end())
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, *current);
+         
+         if(child)
+         {
+            vector<ossimConnectableObject*> temp;
+            temp = child->findAllObjectsOfType(className, recurse);
+            for(long index=0; index < (long)temp.size();++index)
+            {
+               std::vector<ossimConnectableObject*>::iterator iter = std::find(result.begin(), result.end(), temp[index]);
+               if(iter == result.end())
+               {
+                  result.push_back(temp[index]);
+               }
+            }
+         }
+         ++current;
+      }
+   }
+   
+   return result;
+   
+}
+
+// vector<ossimImageSourceInterface*> ossimImageChain::findAllSourcesOfType(const RTTItypeid& typeInfo)
+// {
+//    vector<ossimImageSourceInterface*> result;
+//    long index = 0;
+
+//    for(index = 0; index < (long)theImageChainList.size();++index)
+//    {
+//       if(typeInfo.can_cast(TYPE_INFO(theImageChainList[index]->getObject())))
+//       {
+//          result.push_back( theImageChainList[index]);
+//       }
+//    }
+//    // go through other image chains.
+//    for(index = 0; index < (long)theImageChainList.size();++index)
+//    {
+//       ossimImageChain* child=PTR_CAST(ossimImageChain, theImageChainList[index]->getObject());
+      
+//       if(child)
+//       {
+//          vector<ossimImageSourceInterface*> temp;
+         
+//          temp =  child->findAllSourcesOfType(typeInfo);
+//          for(long index2=0; index2 < (long)temp.size();index2++)
+//          {
+//             result.push_back(temp[index2]);
+//          }
+//       }
+//    }   
+   
+//    return result;
+// }
+
+void ossimImageChain::makeUniqueIds()
+{
+   setId(ossimIdManager::instance()->generateId());
+   for(long index = 0; index < (long)theImageChainList.size(); ++index)
+   {
+      ossimConnectableContainerInterface* container = PTR_CAST(ossimConnectableContainerInterface,
+                                                               theImageChainList[index]);
+      if(container)
+      {
+         container->makeUniqueIds();
+      }
+      else
+      {
+         if(theImageChainList[index])
+         {
+            theImageChainList[index]->setId(ossimIdManager::instance()->generateId());
+         }
+      }
+   }
+}
+
+ossim_uint32 ossimImageChain::getNumberOfObjects(bool recurse)const
+{
+   ossim_uint32 result = theImageChainList.size();
+   
+   if(recurse)
+   {
+      for(ossim_uint32 i = 0; i < theImageChainList.size(); ++i)
+      {
+         ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, theImageChainList[i]);
+         if(child)
+         {
+            result += child->getNumberOfObjects(true);
+         }
+      }
+   }
+   
+   return result;   
+}
+
+ossim_uint32 ossimImageChain::getNumberOfSources() const
+{
+   ossimNotify(ossimNotifyLevel_NOTICE)
+      << "ossimImageChain::getNumberOfSources is deprecated!"
+      << "\nUse: ossimImageChain::getNumberOfObjects(false)"
+      << std::endl;
+   return getNumberOfObjects(false);
+}
+
+bool ossimImageChain::addChild(ossimConnectableObject* object)
+{
+   return add(object);
+}
+
+bool ossimImageChain::removeChild(ossimConnectableObject* object)
+{
+   vector<ossimConnectableObject*>::iterator current =  theImageChainList.begin();
+   ossim_uint32 i = 0;
+   while(current != theImageChainList.end())
+   {
+      if(*current)
+      {
+	 if(object == (*current))
+         {
+            // Send an event to any listeners.
+            ossimContainerEvent event((ossimObject*)this,
+                                      (ossimObject*)object,
+                                      OSSIM_EVENT_REMOVE_OBJECT_ID);
+            fireEvent(event);
+            object->changeOwner(NULL);
+
+            object->removeListener((ossimConnectableObjectListener*)this);
+            object->removeListener((ossimConnectableObjectListener*)theChildListener);
+
+            std::vector<ossimConnectableObject*> input  = object->getInputList();
+            std::vector<ossimConnectableObject*> output = object->getOutputList();
+
+            // remeber the old size before removing
+            ossim_uint32 chainSize = theImageChainList.size();
+            current = theImageChainList.erase(current);
+            // fix pointers
+            //
+            object->disconnect();
+            
+            if(i == 0) // is it the first in the chain
+            {
+               theImageChainList[0]->removeListener(theChildListener);
+               theImageChainList[0]->addListener(theChildListener);
+            }
+            else if(i == (chainSize-1)) // is it the last
+            {
+               if(chainSize > 1)
+               {
+                  ossimConnectableObject* tempObj = theImageChainList[theImageChainList.size()-1];
+                  if(tempObj)
+                  {
+                     tempObj->connectInputList(input);
+                  }
+               }
+            }
+            else // must be an interior
+            {
+               ossim_uint32 inIndex  = 0;
+
+               for(inIndex = 0; inIndex < input.size(); ++inIndex)
+               {
+                  if(input[inIndex])
+                  {
+                     input[inIndex]->disconnectAllOutputs();
+                     input[inIndex]->connectOutputList(output);
+                  }
+               }
+            }
+
+            return true;
+         }
+      }
+      ++current;
+      ++i;
+   }
+
+   current =  theImageChainList.begin();
+   
+   while(current != theImageChainList.end())
+   {
+      ossimConnectableContainerInterface* child=PTR_CAST(ossimConnectableContainerInterface, *current);
+      
+      if(child)
+      {
+         bool result = child->removeChild(object);
+         if(result)
+         {
+            return result;
+         }
+      }
+      ++current;
+   }
+   
+   return false;
+}
+
+ossimConnectableObject* ossimImageChain::removeChild(const ossimId& id)
+{
+   ossimConnectableObject* obj = findObject(id, true);
+
+   removeChild(obj);
+   
+   return obj;
+}
+
+void ossimImageChain::getChildren(vector<ossimConnectableObject*>& children,
+                                  bool immediateChildrenOnlyFlag)
+{
+   ossim_uint32 i = 0;
+   
+   vector<ossimConnectableObject*> temp;
+   for(i = 0; i < theImageChainList.size();++i)
+   {
+      temp.push_back(theImageChainList[i]);
+   }
+
+   for(i = 0; i < temp.size();++i)
+   {
+      ossimConnectableContainerInterface* interface = PTR_CAST(ossimConnectableContainerInterface,
+                                                               temp[i]);
+      if(immediateChildrenOnlyFlag)
+      {
+         children.push_back(temp[i]);
+      }
+      else if(!interface)
+      {
+         children.push_back(temp[i]);         
+      }
+   }
+   
+   if(!immediateChildrenOnlyFlag)
+   {
+      for(i = 0; i < temp.size();++i)
+      {
+         ossimConnectableContainerInterface* interface = PTR_CAST(ossimConnectableContainerInterface,
+                                                                  temp[i]);
+         if(interface)
+         {
+            interface->getChildren(children, false);
+         }
+      }
+   }
+}
+
+bool ossimImageChain::add(ossimConnectableObject* source)
+{
+   bool result = false;
+   if(PTR_CAST(ossimImageSourceInterface, source))
+   {
+     source->changeOwner(this);
+     if(theImageChainList.size() > 0)
+     {
+        source->disconnectAllOutputs();
+        theOutputListIsFixedFlag = source->getOutputListIsFixedFlag();
+        theImageChainList[0]->removeListener(theChildListener);
+        theImageChainList.insert(theImageChainList.begin(), source);
+        theImageChainList[0]->addListener(theChildListener);
+        source->addListener((ossimConnectableObjectListener*)this);
+        theImageChainList[0]->connectMyInputTo(theImageChainList[1]);
+        result = true;
+     }
+     else
+     {
+        theInputObjectList = source->getInputList();
+        theInputListIsFixedFlag = source->getInputListIsFixedFlag();
+        
+        theOutputObjectList      = source->getOutputList();
+        theOutputListIsFixedFlag = source->getOutputListIsFixedFlag();
+   
+        theImageChainList.push_back(source);
+        source->addListener((ossimConnectableObjectListener*)this);
+        theImageChainList[0]->addListener(theChildListener);
+        result = true;
+     }
+   }
+
+   if (result && source)
+   {
+      ossimContainerEvent event(this, source, OSSIM_EVENT_ADD_OBJECT_ID);
+      fireEvent(event);
+   }
+   
+   return result;
+}
+
+bool ossimImageChain::insertRight(ossimConnectableObject* newObj,
+                                  ossimConnectableObject* rightOfThisObj)
+{
+   if(!theImageChainList.size())
+   {
+      return add(newObj);
+   }
+   
+   if(findObject(rightOfThisObj, false))
+   {
+      vector<ossimConnectableObject*>::iterator iter = theImageChainList.begin();
+      while(iter != theImageChainList.end())
+      {
+         if( (*iter) == rightOfThisObj)
+         {
+            break;
+         }
+         ++iter;
+      }
+      if(rightOfThisObj == theImageChainList[0])
+      {
+         return add(newObj);
+      }
+      else if(PTR_CAST(ossimImageSourceInterface, newObj))
+      {
+         vector<ossimConnectableObject*> outputList = rightOfThisObj->getOutputList();
+         rightOfThisObj->disconnectAllOutputs();
+
+         // Core dump fix.  Connect input prior to outputs. (drb)
+         newObj->connectMyInputTo(rightOfThisObj); 
+         newObj->connectOutputList(outputList);
+         newObj->changeOwner(this);
+         newObj->addListener((ossimConnectableObjectListener*)this);
+         theImageChainList.insert(iter, newObj);
+         if (newObj)
+         {
+            // Send event to any listeners.
+            ossimContainerEvent event(this, newObj, OSSIM_EVENT_ADD_OBJECT_ID);
+            fireEvent(event);
+         }
+         return true;
+      }
+   }
+
+   return false;
+}
+
+bool ossimImageChain::insertRight(ossimConnectableObject* newObj,
+                                  const ossimId& id)
+{
+   ossimConnectableObject* obj = findObject(id, false);
+   if(obj)
+   {
+      return insertRight(newObj, obj);
+   }
+
+   return false;
+}
+
+bool ossimImageChain::insertLeft(ossimConnectableObject* newObj,
+                                 ossimConnectableObject* leftOfThisObj)
+{
+   if(!theImageChainList.size())
+   {
+      return add(newObj);
+   }
+   
+   if(findObject(leftOfThisObj, false))
+   {
+      vector<ossimConnectableObject*>::iterator iter = theImageChainList.begin();
+
+      while(iter != theImageChainList.end())
+      {
+         if( (*iter) == leftOfThisObj)
+         {
+            break;
+         }
+         ++iter;
+      }
+      if(leftOfThisObj==theImageChainList[theImageChainList.size()-1])
+      {
+         return addLast(newObj);
+      }
+      else if(PTR_CAST(ossimImageSourceInterface, newObj))
+      {
+         vector<ossimConnectableObject*> inputList = leftOfThisObj->getInputList();
+         leftOfThisObj->disconnectAllInputs();
+         newObj->connectInputList(inputList);
+         leftOfThisObj->connectMyInputTo(newObj);
+         newObj->changeOwner(this);
+         newObj->addListener((ossimConnectableObjectListener*)this);
+         theImageChainList.insert(iter+1, newObj);
+         if (newObj)
+         {
+            // Send an event to any listeners.
+            ossimContainerEvent event(this, newObj, OSSIM_EVENT_ADD_OBJECT_ID);
+            fireEvent(event);
+         }
+         return true;
+      }
+   }
+
+   return false;
+}
+
+bool ossimImageChain::insertLeft(ossimConnectableObject* newObj,
+                                  const ossimId& id)
+{
+   ossimConnectableObject* obj = findObject(id, false);
+   if(obj)
+   {
+      return insertLeft(newObj, obj);
+   }
+
+   return false;
+}
+
+ossimRefPtr<ossimImageData> ossimImageChain::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         theImageChainList[0]);
+
+         if(interface)
+         {
+            // make sure we initialize in reverse order.
+            // some source may depend on the initialization of
+            // its inputs
+            return interface->getTile(tileRect, resLevel);
+         }
+      
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getTile(tileRect,
+                                      resLevel);
+         }
+      }
+   }
+
+   if(theBlankTile.get())
+   {
+      theBlankTile->setOrigin(tileRect.ul());
+      theBlankTile->setWidthHeight(tileRect.width(),
+                                   tileRect.height());
+   }
+   
+   return theBlankTile;
+}
+
+ossim_uint32 ossimImageChain::getNumberOfInputBands() const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      theImageChainList[0]);
+      if(interface)
+      {
+         return interface->getNumberOfOutputBands();
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getNumberOfOutputBands();
+         }
+      }
+   }
+
+   return 0;
+}
+
+double ossimImageChain::getNullPixelValue(ossim_uint32 band)const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      theImageChainList[0]);
+      if(interface)
+      {
+         return interface->getNullPixelValue(band);
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getNullPixelValue(band);
+         }
+      }
+   }
+   
+   return ossimGetDefaultNull(getOutputScalarType());
+}
+
+double ossimImageChain::getMinPixelValue(ossim_uint32 band)const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      theImageChainList[0]);
+      if(interface)
+      {
+         return interface->getMinPixelValue(band);
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getMinPixelValue(band);
+         }
+      }
+   }
+
+   return ossimGetDefaultMin(getOutputScalarType());
+}
+
+double ossimImageChain::getMaxPixelValue(ossim_uint32 band)const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                                  theImageChainList[0]);
+      if(inter)
+      {
+         return inter->getMaxPixelValue(band);
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getMaxPixelValue(band);
+         }
+      }
+   }
+
+   return ossimGetDefaultMax(getOutputScalarType());
+}
+
+void ossimImageChain::getOutputBandList(std::vector<ossim_uint32>& bandList) const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                                  theImageChainList[0]);
+      if(inter)
+      {
+         return inter->getOutputBandList(bandList);
+      }
+   }
+}
+   
+ossimScalarType ossimImageChain::getOutputScalarType() const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      theImageChainList[0]);
+      if(interface)
+      {
+         return interface->getOutputScalarType();
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getOutputScalarType();
+         }
+      }
+   }
+   
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+ossim_uint32 ossimImageChain::getTileWidth()const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         theImageChainList[0]);
+         if(interface)
+         {
+            return interface->getTileWidth();;
+         }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getTileWidth();
+         }
+      }
+   }
+   
+   return 0;   
+}
+
+ossim_uint32 ossimImageChain::getTileHeight()const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         theImageChainList[0]);
+         if(interface)
+         {
+            return interface->getTileHeight();
+         }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getTileHeight();
+         }
+      }
+   }
+   
+   return 0;   
+}
+   
+ossimIrect ossimImageChain::getBoundingRect(ossim_uint32 resLevel)const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      theImageChainList[0]);
+
+      if(interface)
+      {
+         return interface->getBoundingRect(resLevel);
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getBoundingRect();
+         }
+      }
+   }
+   ossimDrect rect;
+   rect.makeNan();
+   
+   return rect;
+   
+}
+
+void ossimImageChain::getValidImageVertices(vector<ossimIpt>& validVertices,
+                                            ossimVertexOrdering ordering,
+                                            ossim_uint32 resLevel)const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* interface =PTR_CAST(ossimImageSourceInterface,
+                                                     theImageChainList[0]);
+
+      if(interface)
+      {
+         interface->getValidImageVertices(validVertices,
+                                          ordering,
+                                          resLevel);
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            interface->getValidImageVertices(validVertices,
+                                             ordering,
+                                             resLevel);
+         }
+      }
+   }
+}
+
+bool ossimImageChain::getImageGeometry(ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      theImageChainList[0]);
+      if(interface)
+      {
+         return interface->getImageGeometry(kwl,
+                                            prefix);
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getImageGeometry(kwl,
+                                               prefix);
+         }
+      }
+      
+   }
+   return false;
+}
+
+void ossimImageChain::getDecimationFactor(ossim_uint32 resLevel,
+                                          ossimDpt& result) const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      theImageChainList[0]);
+      if(interface)
+      {
+         interface->getDecimationFactor(resLevel,
+                                        result);
+         return;
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            interface->getDecimationFactor(resLevel, result);
+            return;
+         }
+      }
+   }
+
+   result.makeNan();
+}
+
+void ossimImageChain::getDecimationFactors(vector<ossimDpt>& decimations) const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      theImageChainList[0]);
+      if(interface)
+      {
+         interface->getDecimationFactors(decimations);
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            interface->getDecimationFactors(decimations);
+            return;
+         }
+      }
+   }
+}
+
+ossim_uint32 ossimImageChain::getNumberOfDecimationLevels()const
+{
+   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      theImageChainList[0]);
+
+      if(interface)
+      {
+         return interface->getNumberOfDecimationLevels();
+      }
+   }
+   else
+   {
+      if(getInput(0))
+      {
+         ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                         getInput(0));
+         if(interface)
+         {
+            return interface->getNumberOfDecimationLevels();
+         }
+      }
+   }
+
+   return 1;
+}
+
+bool ossimImageChain::addAllSources(map<ossimId, vector<ossimId> >& idMapping,
+                                    const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   static const char* MODULE = "ossimImageChain::addAllSources";
+   ossimString copyPrefix = prefix;
+   bool result =  ossimImageSource::loadState(kwl, copyPrefix.c_str());
+
+   if(!result)
+   {
+      return result;
+   }
+   long index = 0;
+
+//   ossimSource* source = NULL;
+
+   vector<ossimId> inputConnectionIds;
+   ossimString regExpression =  ossimString("^(") + copyPrefix + "object[0-9]+.)";
+   vector<ossimString> keys =
+      kwl.getSubstringKeyList( regExpression );
+   long numberOfSources = keys.size();//kwl.getNumberOfSubstringKeys(regExpression);
+
+   int offset = (copyPrefix+"object").size();
+   int idx = 0;
+   std::vector<int> theNumberList(numberOfSources);
+   for(idx = 0; idx < (int)theNumberList.size();++idx)
+     {
+       ossimString numberStr(keys[idx].begin() + offset,
+			     keys[idx].end());
+       theNumberList[idx] = numberStr.toInt();
+     }
+   std::sort(theNumberList.begin(), theNumberList.end());
+   for(idx=0;idx < (int)theNumberList.size();++idx)
+   {
+      ossimString newPrefix = copyPrefix;
+      newPrefix += ossimString("object");
+      newPrefix += ossimString::toString(theNumberList[idx]);
+      newPrefix += ossimString(".");
+
+      if(traceDebug())
+      {
+         CLOG << "trying to create source with prefix: " << newPrefix
+              << std::endl;
+      }
+      ossimObject* object = ossimObjectFactoryRegistry::instance()->createObject(kwl,
+                                                                                 newPrefix.c_str());
+      ossimConnectableObject* source = PTR_CAST(ossimConnectableObject, object);
+      
+      if(source)
+      {
+         // we did find a source so include it in the count
+         if(traceDebug())
+         {
+            CLOG << "Created source with prefix: " << newPrefix << std::endl;
+         }
+         if(PTR_CAST(ossimImageSourceInterface, source))
+         {
+            ossimId id = source->getId();
+            inputConnectionIds.clear();
+            
+            findInputConnectionIds(inputConnectionIds,
+                                   kwl,
+                                   newPrefix);
+            if(inputConnectionIds.size() == 0)
+            {
+               // we will try to do a default connection
+               //
+               
+               if(theImageChainList.size())
+               {
+                  if(traceDebug())
+                  {
+                     CLOG << "connecting " << source->getClassName() << " to "
+                          << theImageChainList[0]->getClassName() << std::endl;
+                  }
+                  source->connectMyInputTo(0, theImageChainList[0]);
+               }
+            }
+            else
+            {
+               // we remember the connection id's so we can connect this later.
+               // this way we make sure all sources were actually
+               // allocated.
+               //
+               idMapping.insert(std::make_pair(id, inputConnectionIds));
+            }
+            add(source);
+         }
+         else
+         {
+            delete source;
+            source = NULL;
+         }
+      }
+      else
+      {
+         delete object;
+         object = NULL;
+         source = NULL;
+      }
+      
+      ++index;
+   }
+   if(theImageChainList.size())
+   {
+     ossimConnectableObject* obj = theImageChainList[(long)theImageChainList.size()-1];
+     if(obj)
+     {
+        setNumberOfInputs(obj->getNumberOfInputs());
+     }
+   }
+   
+   return result;
+}
+
+void ossimImageChain::findInputConnectionIds(vector<ossimId>& result,
+                                             const ossimKeywordlist& kwl,
+                                             const char* prefix)
+{
+   ossimString copyPrefix = prefix;
+   ossim_uint32 idx = 0;
+   
+   ossimString regExpression =  ossimString("^") + ossimString(prefix) + "input_connection[0-9]+";
+   vector<ossimString> keys =
+      kwl.getSubstringKeyList( regExpression );
+   
+   ossim_int32 offset = (copyPrefix+"input_connection").size();
+   ossim_uint32 numberOfKeys = keys.size();
+   std::vector<int> theNumberList(numberOfKeys);
+   for(idx = 0; idx < theNumberList.size();++idx)
+   {
+      ossimString numberStr(keys[idx].begin() + offset,
+                            keys[idx].end());
+      theNumberList[idx] = numberStr.toInt();
+   }
+   std::sort(theNumberList.begin(), theNumberList.end());
+   copyPrefix += ossimString("input_connection");
+   for(idx=0;idx < theNumberList.size();++idx)
+   {
+      const char* lookup = kwl.find(copyPrefix,ossimString::toString(theNumberList[idx]));
+      if(lookup)
+      {
+         long id = ossimString(lookup).toLong();
+         result.push_back(ossimId(id));
+      }
+   }
+}
+                                             
+bool ossimImageChain::connectAllSources(const map<ossimId, vector<ossimId> >& idMapping)
+{
+   if(idMapping.size())
+   {
+      map<ossimId, vector<ossimId> >::const_iterator iter = idMapping.begin();
+
+      while(iter != idMapping.end())
+      {
+         ossimConnectableObject* currentSource = findObject((*iter).first);
+
+         if(currentSource)
+         {
+            long upperBound = (*iter).second.size();
+            for(long index = 0; index < upperBound; ++index)
+            {
+               if((*iter).second[index].getId() > -1)
+               {
+                  ossimConnectableObject* inputSource = PTR_CAST(ossimConnectableObject, findObject((*iter).second[index]));
+                  currentSource->connectMyInputTo(index, inputSource);
+                  
+               }
+               else
+               {
+                  currentSource->disconnectMyInput((ossim_int32)index);
+               }
+            }
+         }
+         else
+         {
+            cerr << "Could not find " << (*iter).first << " for source: ";
+            return false;
+         }
+         ++iter;
+      }
+   }
+
+   return true;
+}
+
+bool ossimImageChain::saveState(ossimKeywordlist& kwl,
+                                const char* prefix)const
+{
+   bool result = true;
+   
+   result = ossimImageSource::saveState(kwl, prefix);
+
+   if(!result)
+   {
+      return result;
+   }
+   long upper = theImageChainList.size();
+   long counter = 1;
+
+   // start with the tail and go to the head fo the list.
+   for(long index = upper - 1; ((index >= 0)&&result); --index, ++counter)
+   {
+      ossimString newPrefix = prefix;
+
+      newPrefix += (ossimString("object") +
+                    ossimString::toString(counter) +
+                    ossimString("."));
+      result = theImageChainList[index]->saveState(kwl, newPrefix.c_str());
+   }
+
+   return result;
+}
+
+bool ossimImageChain::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   static const char* MODULE = "ossimImageChain::loadState(kwl, prefix)";
+   deleteList();
+
+   ossimImageSource::loadState(kwl, prefix);
+   
+   
+   theLoadStateFlag = true;
+   bool result = true;
+   
+   map<ossimId, vector<ossimId> > idMapping;
+   result = addAllSources(idMapping, kwl, prefix);
+   if(!result)
+   {
+      CLOG << "problems adding sources" << std::endl;
+   }
+   result = connectAllSources(idMapping);
+   if(!result)
+   {
+      CLOG << "problems connecting sources" << std::endl;
+   }
+   
+   theLoadStateFlag = false;
+   return result;
+}
+
+
+void ossimImageChain::initialize()
+{
+   static const char* MODULE = "ossimImageChain::initialize()";
+   if (traceDebug()) CLOG << " Entered..." << std::endl;
+   
+   long upper = theImageChainList.size();
+   
+   for(long index = upper - 1; index >= 0; --index)
+   {
+      if(traceDebug())
+      {
+         CLOG << "initilizing source: "
+              << theImageChainList[index]->getClassName()
+              << std::endl;
+      }
+      if(theImageChainList[index])
+      {
+         ossimImageSourceInterface* interface =
+            PTR_CAST(ossimImageSourceInterface, theImageChainList[index]);
+
+         if(interface)
+         {
+            // make sure we initialize in reverse order.
+            // some source may depend on the initialization of
+            // its inputs
+            interface->initialize();
+         }
+      }
+   }
+   if (traceDebug()) CLOG << " Exited..." << std::endl;
+}
+
+void ossimImageChain::enableSource()
+{
+   long upper = theImageChainList.size();
+   
+   for(long index = upper - 1; index >= 0; --index)
+   {
+      // make sure we initialize in reverse order.
+      // some source may depend on the initialization of
+      // its inputs
+     ossimSource* source = PTR_CAST(ossimSource, theImageChainList[index]);
+     if(source)
+     {
+        source->enableSource();
+     }
+   }
+   
+   theEnableFlag = true;
+}
+
+void ossimImageChain::disableSource()
+{
+   long upper = theImageChainList.size();
+   
+   for(long index = upper - 1; index >= 0; --index)
+   {
+      // make sure we initialize in reverse order.
+      // some source may depend on the initialization of
+      // its inputs
+     ossimSource* source = PTR_CAST(ossimSource, theImageChainList[index]);
+     if(source)
+     {
+        source->disableSource();
+     }
+   }
+   
+   theEnableFlag = false;
+}
+
+
+vector<ossimConnectableObject*>& ossimImageChain::getChildren()
+{
+   return theImageChainList;
+}
+
+bool ossimImageChain::deleteFirst()
+{
+   if (theImageChainList.size() == 0) return false;
+
+   // Clear any listeners, memory.
+   ossim_uint32 index = 0;
+   theImageChainList[index]->
+      removeListener((ossimConnectableObjectListener*)this);
+   theImageChainList[index]->removeListener(theChildListener);
+   theImageChainList[index]->changeOwner(NULL);
+   delete theImageChainList[index];
+   
+   // Remove from the vector.
+   vector<ossimConnectableObject*>::iterator i = theImageChainList.begin();
+   theImageChainList.erase(i);
+   return true;
+}
+
+bool ossimImageChain::deleteLast()
+{
+   if (theImageChainList.size() == 0) return false;
+
+   // Clear any listeners, memory.
+   ossim_uint32 index = theImageChainList.size() - 1;
+   theImageChainList[index]->
+      removeListener((ossimConnectableObjectListener*)this);
+   theImageChainList[index]->removeListener(theChildListener);
+   theImageChainList[index]->changeOwner(NULL);
+   delete theImageChainList[index];
+   
+   // Remove from the vector.
+   theImageChainList.pop_back();
+   return true; 
+}
+
+void ossimImageChain::deleteList()
+{
+   long upper = theImageChainList.size();
+
+   
+   for(long index = 0; index < upper; ++index)
+   {
+      theImageChainList[index]->removeListener((ossimConnectableObjectListener*)this);
+      theImageChainList[index]->removeListener(theChildListener);
+      theImageChainList[index]->changeOwner(NULL);
+      delete theImageChainList[index];
+   }
+
+   theImageChainList.clear();
+}
+
+void ossimImageChain::disconnectInputEvent(ossimConnectionEvent& event)
+{
+   if(theImageChainList.size())
+   {
+      if(event.getObject()==this)
+      {
+         if(theImageChainList[theImageChainList.size()-1])
+         {
+            for(ossim_uint32 i = 0; i < event.getNumberOfOldObjects(); ++i)
+            {
+               theImageChainList[theImageChainList.size()-1]->disconnectMyInput(event.getOldObject(i));
+            }
+         }
+      }
+   }
+}
+
+void ossimImageChain::disconnectOutputEvent(ossimConnectionEvent& event)
+{
+}
+
+void ossimImageChain::connectInputEvent(ossimConnectionEvent& event)
+{
+   if(theImageChainList.size())
+   {
+      if(event.getObject()==this)
+      {
+         if(theImageChainList[theImageChainList.size()-1])
+         {
+            for(ossim_uint32 i = 0; i < event.getNumberOfNewObjects(); ++i)
+            {
+               ossimConnectableObject* obj = event.getNewObject(i);
+               theImageChainList[theImageChainList.size()-1]->connectMyInputTo(findInputIndex(obj),
+                                                                               obj,
+                                                                               false);
+            }
+         }
+      }
+      else if(event.getObject() == theImageChainList[0])
+      {
+         if(!theLoadStateFlag)
+         {
+//            theInputObjectList = theImageChainList[0]->getInputList();
+         }
+      }
+      initialize();
+   }
+}
+
+void ossimImageChain::connectOutputEvent(ossimConnectionEvent& event)
+{
+} 
+
+// void ossimImageChain::propertyEvent(ossimPropertyEvent& event)
+// {
+//    if(theImageChainList.size())
+//    {
+//       ossimConnectableObject* obj = PTR_CAST(ossimConnectableObject,
+//                                              event.getObject());
+      
+//       if(obj)
+//       {
+//          ossimImageSourceInterface* interface = findSource(obj->getId());
+         
+//          if(interface)
+//          {
+//             ossimConnectableObject* obj = PTR_CAST(ossimConnectableObject,
+//                                                    interface.getObject());
+//             if(obj)
+//             {
+               
+//             }
+//          }
+//       }
+//    }
+// }
+
+void ossimImageChain::objectDestructingEvent(ossimObjectDestructingEvent& event)
+{
+   if(!event.getObject()) return;
+
+   if(theImageChainList.size()&&(event.getObject()!=this))
+   {
+     removeChild(PTR_CAST(ossimConnectableObject,
+			  event.getObject()));
+   }
+}
+
+void ossimImageChain::propagateEventToOutputs(ossimEvent& event)
+{
+   if(thePropagateEventFlag) return;
+
+   thePropagateEventFlag = true;
+   if(theImageChainList.size())
+   {
+      if(theImageChainList[theImageChainList.size()-1])
+      {
+         theImageChainList[theImageChainList.size()-1]->fireEvent(event);
+         theImageChainList[theImageChainList.size()-1]->propagateEventToOutputs(event);
+      }
+   }
+   ossimConnectableObject::propagateEventToOutputs(event);
+   thePropagateEventFlag = false;
+}
+
+void ossimImageChain::propagateEventToInputs(ossimEvent& event)
+{
+   if(thePropagateEventFlag) return;
+
+   thePropagateEventFlag = true;
+   if(theImageChainList.size())
+   {
+      if(theImageChainList[0])
+      {
+         theImageChainList[0]->fireEvent(event);
+         theImageChainList[0]->propagateEventToOutputs(event);
+      }
+   }
+   thePropagateEventFlag = false;
+}
+
+ossimConnectableObject* ossimImageChain::operator[](ossim_uint32 index)
+{
+   return getConnectableObject(index);
+}
+
+ossimConnectableObject* ossimImageChain::getConnectableObject(
+   ossim_uint32 index)
+{
+   if(theImageChainList.size() && (index < theImageChainList.size()))
+   {
+      return theImageChainList[index];
+   }
+   
+   return (ossimConnectableObject*)NULL; 
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageChain.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageChain.h
new file mode 100644
index 0000000000..4d3859cc8f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageChain.h
@@ -0,0 +1,358 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageChain.h,v 1.52 2005/11/22 19:45:06 dburken Exp $
+#ifndef ossimImageChain_HEADER
+#define ossimImageChain_HEADER
+#include <vector>
+#include <map>
+using namespace std;
+
+#include <imaging/ossimImageSource.h>
+#include <base/common/events/ossimConnectableObjectListener.h>
+#include <base/common/ossimId.h>
+#include <base/common/ossimConnectableContainerInterface.h>
+
+class ossimImageChainChildListener;
+
+class OSSIMDLLEXPORT ossimImageChain : public ossimImageSource,
+                                       public ossimConnectableObjectListener,
+                                       public ossimConnectableContainerInterface
+{
+public:
+   ossimImageChain();
+   virtual ~ossimImageChain();
+
+   /**
+    * @param index Index of object to get.
+    *
+    * @see getNumberOfObjects(false) to get the number of objects inside
+    * the container.
+    *
+    * @return Container's object at that index or NULL if out of range.
+    */
+   ossimConnectableObject* operator[](ossim_uint32 index);
+
+   /**
+    * Same as operator[](ossim_uint32 i)
+    * 
+    * @param index Index of object to get.
+    *
+    * @see getNumberOfObjects(false) to get the number of objects inside
+    * the container.
+    *
+    * @return Container's object at that index or NULL if out of range.
+    *
+    * @note This does not recurse into other containers.
+    */
+   virtual ossimConnectableObject* getConnectableObject(ossim_uint32 index);
+   
+   /**
+    * Return the first source which is the one that first receives the
+    * getTile request
+    */
+   virtual ossimImageSourceInterface* getFirstSource();
+   virtual ossimObject* getFirstObject();
+
+   /**
+    * Return the last source which is the one that last receives the
+    * getTile request.
+    */
+   virtual ossimImageSourceInterface* getLastSource();
+   virtual ossimObject* getLastObject();
+
+
+   /**
+    * Adds it to the start of the chain.  This is the first one to receive
+    * the getTile request.  This basically inserts it to the right of the
+    * right most filter.
+    * Returns true on success, false on error.
+    */
+   bool addFirst(ossimConnectableObject* obj);
+
+   /**
+    * Adds it to the end.  this is the last one to receive the getTile
+    * request.  This basically inserts it to the left of the left most filter.
+    * Returns true on success, false on error.
+    */
+   bool addLast(ossimConnectableObject* obj);
+
+   /**
+    * Deletes the first object.
+    * Note this is really most right of the chain.
+    * Returns true if deletion occurred, false if the chain is empty.
+    */
+   bool deleteFirst();
+
+   /**
+    * Deletes the last object.
+    * Note this is really most left of the chain.
+    * Returns true if deletion occurred, false if the chain is empty.
+    */
+   bool deleteLast();
+
+   /**
+    * 
+    */
+   bool insertRight(ossimConnectableObject* newObj,
+                    ossimConnectableObject* rightOfThisObj);
+
+   /**
+    *
+    */
+   bool insertRight(ossimConnectableObject* newObj,
+                    const ossimId& id);
+
+   /**
+    *
+    */
+   bool insertLeft(ossimConnectableObject* newObj,
+                   const ossimId& id);
+   /**
+    *
+    */
+   bool insertLeft(ossimConnectableObject* newObj,
+                   ossimConnectableObject* leftOfThisObj);
+
+   
+   /**
+    * Will return true or false if an image source was
+    * added to the chain.  It will add and do a connection
+    * to the previous source automatically.  This is a
+    * chain and the order of insertion matters. It adds it to the beginning
+    * of the list.  The last one added is the first one to receive
+    * the getTile.  Basically inserts to the right of the rightmost filter
+    *
+    */
+   virtual bool add(ossimConnectableObject* source);
+
+   /**
+    * Within the image chain will pass the head of the
+    * list.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   
+   /**
+    * this call is passed to the head of the list.
+    */
+   virtual ossim_uint32 getNumberOfInputBands() const;
+   
+   /**
+    * This call is passed to the head of the list.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   
+   virtual void getOutputBandList(std::vector<ossim_uint32>& bandList) const;
+
+   /**
+    * This call is passed to the head of the list.
+    */
+   virtual ossim_uint32 getTileWidth()const;
+
+   /**
+    * This call is passed to the head of the list.
+    */
+   virtual ossim_uint32 getTileHeight()const;
+   
+   /**
+    * Will pass this call to the head of the list.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const;
+   
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=NULL);
+
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result) const;
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations) const;
+   virtual ossim_uint32 getNumberOfDecimationLevels()const;
+   
+   /**
+    * Will save the state of the chain.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+
+   /**
+    * Will load the state.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+   
+   virtual void initialize();
+   virtual void enableSource();
+   virtual void disableSource();
+   vector<ossimConnectableObject*>& getChildren();
+   
+   bool canConnectMyInputTo(ossim_int32 myInputIndex,
+                            const ossimConnectableObject* object)const
+      {
+         if(theImageChainList.size()&&
+            theImageChainList[theImageChainList.size()-1])
+         {
+            ossimConnectableObject* obj = PTR_CAST(ossimConnectableObject, theImageChainList[theImageChainList.size()-1]);
+            if(obj)
+            {
+               return obj->canConnectMyInputTo(myInputIndex,
+                                               object);
+            }
+         }
+         
+         return false;
+      }
+      
+//    bool canConnectMyOutputTo(int32 myOutputIndex,
+//                              const ossimConnectableObject* object)const
+//       {
+//          if(theImageChainList.size()&&theImageChainList[0])
+//          {
+// 	   ossimConnectableObject* obj = PTR_CAST(ossimConnectableObject, theImageChainList[0]);
+// 	   if(obj)
+// 	     {
+// 	       return obj->canConnectMyOutputTo(myOutputIndex,
+// 						object);
+// 	     }
+//          }
+         
+//          return false;
+//       }
+   
+   // ________________________CONNECTABLE CONTAINER DEFINTIONS_________________
+   //
+   
+   /**
+    * Will find all objects of the past in type.  Use the RTTI type info.  An optional
+    * recurse flag will say if there is another container then recurse it to
+    * find the type you are looking for else it just looks within its immediate
+    * children
+    * 
+    * Example: passing STATIC_TYPE_INFO(ossimImageRenderer) as an argument will
+    *          look for all ossimImageRenderer's and return the list.
+    */
+   virtual std::vector<ossimConnectableObject*> findAllObjectsOfType(const RTTItypeid& typeInfo,
+                                                                     bool recurse=true);
+   virtual std::vector<ossimConnectableObject*> findAllObjectsOfType(const ossimString& className,
+                                                                     bool recurse=true);
+
+   /**
+    * Will find the firt object of the past in type.  Use the RTTI type info.An optional
+    * recurse flag will say if there is another container then recurse it to
+    * find the type you are looking for else it just looks within its immediate
+    * children
+    * 
+    * Example: passing STATIC_TYPE_INFO(ossimImageRenderer) as an argument will
+    *          look for the first ossimImageRenderer and return that object.
+    */
+   virtual ossimConnectableObject* findFirstObjectOfType(const RTTItypeid& typeInfo,
+                                                         bool recurse=true);
+   virtual ossimConnectableObject* findFirstObjectOfType(const ossimString& className,
+                                                         bool recurse=true);
+
+   /**
+    * will search for the object given an id.  If recurse is true it will
+    * recurse to other containers.
+    */ 
+   virtual ossimConnectableObject* findObject(const ossimId& id,
+                                              bool recurse=true);
+
+   virtual ossimConnectableObject* findObject(const ossimConnectableObject* obj,
+                                              bool recurse=true);
+
+   /**
+    * Will cycle through all sources setting their ids. the idLast wlil
+    * be updated
+    * so we can recurse into other containers.
+    */
+   virtual void makeUniqueIds();
+
+   /**
+    * Returns the number of objects within this container and all child
+    * containers.
+    *
+    * @param recurse If true and object is a contains containers; all objects
+    * will be conter.  If false only the objects of this container will be
+    * counted (theImageChainList.size()).
+    */
+   virtual ossim_uint32 getNumberOfObjects(bool recurse=true)const;
+
+   /**
+    * Deprecated! Please use getNumberOfObjects(false).
+    *
+    * @return The number of objects in this container or
+    * (theImageChainList.size()).
+    */
+   virtual ossim_uint32 getNumberOfSources() const;
+   
+   /**
+    * Will add an object to the container and then set the added objects owner
+    * to this.
+    */
+   virtual bool addChild(ossimConnectableObject* attachableObject);
+
+   /**
+    * Will remove the child from the container.  Changes the owner of the
+    * child to be NULL;
+    */
+   virtual bool removeChild(ossimConnectableObject* object);
+   virtual ossimConnectableObject* removeChild(const ossimId& id);
+   
+   virtual void getChildren(vector<ossimConnectableObject*>& children,
+                            bool immediateChildrenOnlyFlag);
+   //______________END CONNECTABLE CONTAINER INTERFACE____________
+   
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+   virtual void disconnectOutputEvent(ossimConnectionEvent& event);
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+   virtual void connectOutputEvent(ossimConnectionEvent& event);
+   virtual void objectDestructingEvent(ossimObjectDestructingEvent& event);
+
+   virtual void propagateEventToOutputs(ossimEvent& event);
+   virtual void propagateEventToInputs(ossimEvent& event);
+   
+protected:
+   friend class ossimImageChainChildListener;
+   /**
+    * This will hold a sequence of image sources.
+    * theFirst one in the list will be the head of the
+    * list and the last one is the tail.
+    */
+   vector<ossimConnectableObject*> theImageChainList;
+   
+   ossimRefPtr<ossimImageData>     theBlankTile;
+   ossimImageChainChildListener*   theChildListener;
+   mutable bool                    thePropagateEventFlag;
+   mutable bool                    theLoadStateFlag;
+   /**
+    * For dynamic loading to take place we must allocate all objects first and
+    * then assign id's later.  We must remember the id's so we can do this.
+    * we will create a map that takes the id of the source as a key and a
+    * vector of input id's to connect it's inputs to.
+    */
+   bool addAllSources(map<ossimId, vector<ossimId> >& idMapping,
+                      const ossimKeywordlist& kwl,
+                      const char* prefix = NULL);
+   void findInputConnectionIds(vector<ossimId>& result,
+                               const ossimKeywordlist& kwl,
+                               const char* prefix=NULL);
+   bool connectAllSources(const map<ossimId, vector<ossimId> >& idMapping);
+   
+   void deleteList();
+   
+TYPE_DATA
+};
+#endif /* #ifndef ossimImageChain_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageData.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageData.cpp
new file mode 100644
index 0000000000..b2a093dc0a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageData.cpp
@@ -0,0 +1,5662 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageData.cpp,v 1.149 2006/01/04 22:31:15 dburken Exp $
+
+#include <iterator>
+
+#include <imaging/ossimImageData.h>
+#include <base/common/ossimSource.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+
+RTTI_DEF1(ossimImageData, "ossimImageData", ossimRectilinearDataObject)
+
+ossimImageData::ossimImageData()
+   : ossimRectilinearDataObject(2,            // 2d
+                                NULL,         // owner
+                                1,            // bands
+                                OSSIM_UINT8), // scalar
+      theNullPixelValue(NULL),
+      theMinPixelValue(NULL),
+      theMaxPixelValue(NULL),
+      theOrigin(0, 0)
+{
+   ossimIpt defaultTileSize;
+   ossimGetDefaultTileSize(defaultTileSize);
+   theSpatialExtents[0] = defaultTileSize.x;
+   theSpatialExtents[1] = defaultTileSize.y;
+}
+
+ossimImageData::ossimImageData(ossimSource*    owner,
+                               ossimScalarType scalar,
+                               ossim_uint32    bands)
+   : ossimRectilinearDataObject(2,
+                                owner,
+                                bands,
+                                scalar),
+     theNullPixelValue(NULL),
+     theMinPixelValue(NULL),
+     theMaxPixelValue(NULL),
+     theOrigin(0, 0)
+{
+   ossimIpt defaultTileSize;
+   ossimGetDefaultTileSize(defaultTileSize);
+   theSpatialExtents[0] = defaultTileSize.x;
+   theSpatialExtents[1] = defaultTileSize.y;
+   initializeDefaults();
+}
+
+ossimImageData::ossimImageData(ossimSource* owner,
+                               ossimScalarType scalar,
+                               ossim_uint32 bands,
+                               ossim_uint32 width,
+                               ossim_uint32 height)
+   :ossimRectilinearDataObject(owner,
+                               bands,
+                               width, // 2-D array
+                               height,
+                               scalar),
+      theNullPixelValue(NULL),
+      theMinPixelValue(NULL),
+      theMaxPixelValue(NULL),
+      theOrigin(0, 0)
+{   
+   theSpatialExtents[0] = width;
+   theSpatialExtents[1] = height;
+   initializeDefaults();
+}
+
+ossimImageData::ossimImageData(const ossimImageData &rhs)
+   :ossimRectilinearDataObject(rhs),
+   theNullPixelValue(NULL),
+   theMinPixelValue(NULL),
+   theMaxPixelValue(NULL),
+   theOrigin(rhs.theOrigin)
+{   
+   if(rhs.theNullPixelValue)
+   {
+      theNullPixelValue = new ossim_float64[getNumberOfBands()];
+      
+      memcpy((void*)theNullPixelValue,
+             (const void*)rhs.theNullPixelValue,
+             (sizeof(ossim_float64)*(int)getNumberOfBands()));
+   }
+   if(rhs.theMinPixelValue)
+   {
+      theMinPixelValue = new ossim_float64[getNumberOfBands()];
+      
+      memcpy((void*)theMinPixelValue,
+             (const void*)rhs.theMinPixelValue,
+             (sizeof(ossim_float64)*(int)getNumberOfBands()));
+   }
+   if(rhs.theMaxPixelValue)
+   {
+      theMaxPixelValue = new ossim_float64[getNumberOfBands()];
+      
+      memcpy((void*)theMaxPixelValue,
+             (const void*)rhs.theMaxPixelValue,
+             (sizeof(ossim_float64)*(int)getNumberOfBands()));
+   }
+}
+
+ossimImageData::~ossimImageData()
+{
+   if(theMinPixelValue)
+   {
+      delete [] theMinPixelValue;
+      theMinPixelValue = NULL;
+   }
+   if(theMaxPixelValue)
+   {
+      delete [] theMaxPixelValue;
+      theMaxPixelValue = NULL;
+   }
+   if(theNullPixelValue)
+   {
+      delete [] theNullPixelValue;
+      theNullPixelValue = NULL;
+   }
+}
+
+bool ossimImageData::isValidBand(ossim_uint32 band) const
+{
+   return (band<getNumberOfDataComponents());
+}
+
+ossim_uint32 ossimImageData::getSize() const
+{
+   return (getSizePerBand() * getNumberOfDataComponents());
+}
+
+ossim_uint32 ossimImageData::getSizePerBand() const
+{
+   return (getHeight() * getWidth());
+}
+
+ossim_uint32 ossimImageData::getSizeInBytes() const
+{
+   return (getSizePerBandInBytes() * getNumberOfDataComponents());
+}
+
+ossim_uint32 ossimImageData::getSizePerBandInBytes() const
+{
+   return (getHeight() * getWidth() * getScalarSizeInBytes());
+}
+
+const void* ossimImageData::getBuf() const
+{
+   return static_cast<const void*>(theDataBuffer);
+}
+
+void* ossimImageData::getBuf()
+{
+   return static_cast<void*>(theDataBuffer);
+}
+
+const void* ossimImageData::getBuf(ossim_uint32 band) const
+{
+   const ossim_uint8* b = theDataBuffer;
+   
+   if (isValidBand(band) && b != NULL)
+   {
+      b += (band * getSizePerBandInBytes());
+      return static_cast<const void*>(b);
+   }
+   return NULL;
+}
+
+void* ossimImageData::getBuf(ossim_uint32 band)
+{
+   ossim_uint8* b = theDataBuffer;
+   
+   if (isValidBand(band) && b != NULL)
+   {
+      b += (band * getSizePerBandInBytes());
+      return static_cast<void*>(b);
+   }
+   return NULL;
+}
+
+const ossim_uint8* ossimImageData::getUcharBuf() const
+{
+   if (theScalarType == OSSIM_UINT8)
+   {
+      return static_cast<const ossim_uint8*>(theDataBuffer);
+   }
+   return NULL;
+}
+
+const ossim_uint16* ossimImageData::getUshortBuf() const
+{
+   if (theScalarType == OSSIM_UINT16 ||
+       theScalarType == OSSIM_USHORT11)
+   {
+      return static_cast<const ossim_uint16*>(getBuf());
+   }
+   return NULL;
+}
+
+const ossim_sint16* ossimImageData::getSshortBuf() const
+{
+   if (theScalarType == OSSIM_SINT16)
+   {
+      return static_cast<const ossim_sint16*>(getBuf());
+   }
+   return NULL;
+}
+
+const ossim_float32* ossimImageData::getFloatBuf() const
+{
+   if (theScalarType == OSSIM_FLOAT32 ||
+       theScalarType == OSSIM_NORMALIZED_FLOAT)
+   {
+      return static_cast<const ossim_float32*>(getBuf());
+   }
+   return NULL;
+}
+
+const ossim_float64* ossimImageData::getDoubleBuf() const
+{
+   if (theScalarType == OSSIM_FLOAT64 ||
+       theScalarType == OSSIM_NORMALIZED_DOUBLE)
+   {
+      return static_cast<const ossim_float64*>(getBuf());
+   }
+   return NULL;
+}
+
+ossim_uint8* ossimImageData::getUcharBuf() 
+{
+   if (theScalarType == OSSIM_UINT8)
+   {
+      return theDataBuffer;
+   }
+   return NULL;
+}
+
+ossim_uint16* ossimImageData::getUshortBuf() 
+{
+   if (theScalarType == OSSIM_UINT16 ||
+       theScalarType == OSSIM_USHORT11)
+   {
+      return static_cast<ossim_uint16*>(getBuf());
+   }
+   return NULL;
+}
+
+ossim_sint16* ossimImageData::getSshortBuf() 
+{
+   if (theScalarType == OSSIM_SINT16)
+   {
+      return static_cast<ossim_sint16*>(getBuf());
+   }
+   return NULL;
+}
+
+ossim_float32* ossimImageData::getFloatBuf() 
+{
+   if (theScalarType == OSSIM_FLOAT32 ||
+       theScalarType == OSSIM_NORMALIZED_FLOAT)
+   {
+      return static_cast<ossim_float32*>(getBuf());
+   }
+   return NULL;
+}
+
+ossim_float64* ossimImageData::getDoubleBuf() 
+{
+   if (theScalarType == OSSIM_FLOAT64 ||
+       theScalarType == OSSIM_NORMALIZED_DOUBLE)
+   {
+      return static_cast<ossim_float64*>(getBuf());
+   }
+   return NULL;
+}
+
+const ossim_uint8* ossimImageData::getUcharBuf(ossim_uint32 band) const
+{
+   if (theScalarType == OSSIM_UINT8)
+   {
+      return static_cast<const ossim_uint8*>(getBuf(band));
+   }
+   return NULL;
+}
+
+const ossim_uint16* ossimImageData::getUshortBuf(ossim_uint32 band) const
+{
+   if (theScalarType == OSSIM_UINT16 ||
+       theScalarType == OSSIM_USHORT11)
+   {
+      return static_cast<const ossim_uint16*>(getBuf(band));
+   }
+   return NULL;
+}
+
+const ossim_sint16* ossimImageData::getSshortBuf(ossim_uint32 band) const
+{
+   if (theScalarType == OSSIM_SINT16)
+   {
+      return static_cast<const ossim_sint16*>(getBuf(band));
+   }
+   return NULL;
+}
+
+const ossim_float32* ossimImageData::getFloatBuf(ossim_uint32 band) const
+{
+   if (theScalarType == OSSIM_FLOAT32 ||
+       theScalarType == OSSIM_NORMALIZED_FLOAT)
+   {
+      return static_cast<const ossim_float32*>(getBuf(band));
+   }
+   return NULL;
+}
+
+const ossim_float64* ossimImageData::getDoubleBuf(ossim_uint32 band) const
+{
+   if (theScalarType == OSSIM_FLOAT64 ||
+       theScalarType == OSSIM_NORMALIZED_DOUBLE)
+   {
+      return static_cast<const ossim_float64*>(getBuf(band));
+   }
+   return NULL;
+}
+
+ossim_uint8* ossimImageData::getUcharBuf(ossim_uint32 band) 
+{
+   if (theScalarType == OSSIM_UINT8)
+   {
+      return static_cast<ossim_uint8*>(getBuf(band));
+   }
+   return NULL;
+}
+
+ossim_uint16* ossimImageData::getUshortBuf(ossim_uint32 band) 
+{
+   if (theScalarType == OSSIM_UINT16 ||
+       theScalarType == OSSIM_USHORT11)
+   {
+      return static_cast<ossim_uint16*>(getBuf(band));
+   }
+   return NULL;
+}
+
+ossim_sint16* ossimImageData::getSshortBuf(ossim_uint32 band) 
+{
+   if (theScalarType == OSSIM_SINT16)
+   {
+      return static_cast<ossim_sint16*>(getBuf(band));
+   }
+   return NULL;
+}
+
+ossim_float32* ossimImageData::getFloatBuf(ossim_uint32 band) 
+{
+   if (theScalarType == OSSIM_FLOAT32 ||
+       theScalarType == OSSIM_NORMALIZED_FLOAT)
+   {
+      return static_cast<ossim_float32*>(getBuf(band));
+   }
+   return NULL;
+}
+
+ossim_float64* ossimImageData::getDoubleBuf(ossim_uint32 band) 
+{
+   if (theScalarType == OSSIM_FLOAT64 ||
+       theScalarType == OSSIM_NORMALIZED_DOUBLE)
+   {
+      return static_cast<ossim_float64*>(getBuf(band));
+   }
+   return NULL;
+}
+
+void ossimImageData::getNormalizedFloat(ossim_uint32 offset,
+                                        ossim_uint32 bandNumber,
+                                        ossim_float32& result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   
+   // Make sure that the types and width and height are good.
+   if( (getDataObjectStatus() == OSSIM_NULL) &&
+       (bandNumber < getNumberOfDataComponents()) )
+   {
+      return;
+   }
+   
+   ossim_float32 delta =  theMaxPixelValue[bandNumber] - theMinPixelValue[bandNumber];
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         const unsigned char* sourceBuf = getUcharBuf(bandNumber);
+         result = (sourceBuf[offset] - theMinPixelValue[bandNumber])/delta;
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         const ossim_sint8* sourceBuf = static_cast<const ossim_sint8*>(getBuf(bandNumber));
+         result = (sourceBuf[offset] - theMinPixelValue[bandNumber])/delta;
+         break;
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         const ossim_uint16* sourceBuf = getUshortBuf(bandNumber);
+         result = (sourceBuf[offset] - theMinPixelValue[bandNumber])/delta;
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         const ossim_sint16* sourceBuf = getSshortBuf(bandNumber);
+         result = (sourceBuf[offset] - theMinPixelValue[bandNumber])/delta;
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         const ossim_uint32* sourceBuf =
+            static_cast<const ossim_uint32*>(getBuf(bandNumber));
+         result = (sourceBuf[offset] - theMinPixelValue[bandNumber])/delta;
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         const ossim_sint32* sourceBuf = static_cast<const ossim_sint32*>(getBuf(bandNumber));
+         result = (sourceBuf[offset] - theMinPixelValue[bandNumber])/delta;
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+      {
+         const ossim_float32* sourceBuf = getFloatBuf(bandNumber);
+         result = (sourceBuf[offset] - theMinPixelValue[bandNumber])/delta;
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         const ossim_float64* sourceBuf = getDoubleBuf(bandNumber);
+         result = (sourceBuf[offset] - theMinPixelValue[bandNumber])/delta;
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         // Shouldn't hit this.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::setNormalizedFloat Unsupported scalar type!"
+            << std::endl;
+         
+         result = 0;
+      }
+   }
+}
+
+void ossimImageData::setNormalizedFloat(ossim_uint32 offset,
+                                        ossim_uint32 bandNumber,
+                                        ossim_float32 inputValue)
+{
+   // Make sure that the types and width and height are good.
+   if( (getDataObjectStatus() == OSSIM_NULL)&&
+       (bandNumber < getNumberOfDataComponents()) )
+   {
+      return;
+   }
+   
+   ossim_float32 delta =  theMaxPixelValue[bandNumber] - theMinPixelValue[bandNumber];
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         unsigned char* sourceBuf = getUcharBuf(bandNumber);
+         sourceBuf[offset] =
+            static_cast<ossim_uint8>(theMinPixelValue[bandNumber] +
+                                     delta*inputValue);
+         
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         ossim_sint8* sourceBuf = static_cast<ossim_sint8*>(getBuf(bandNumber));
+         sourceBuf[offset] =
+            static_cast<ossim_sint8>(theMinPixelValue[bandNumber] +
+                                     delta*inputValue);
+         break;
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         ossim_uint16* sourceBuf = getUshortBuf(bandNumber);
+         sourceBuf[offset] =
+            static_cast<ossim_uint16>(theMinPixelValue[bandNumber] +
+                                      delta*inputValue);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         ossim_sint16* sourceBuf = getSshortBuf(bandNumber);
+         sourceBuf[offset] =
+            static_cast<ossim_sint16>(theMinPixelValue[bandNumber] +
+                                      delta*inputValue);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         ossim_uint32* sourceBuf =
+            static_cast<ossim_uint32*>(getBuf(bandNumber));
+         sourceBuf[offset] =
+            static_cast<ossim_uint32>(theMinPixelValue[bandNumber] +
+                                      delta*inputValue);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         ossim_sint32* sourceBuf = static_cast<ossim_sint32*>(getBuf(bandNumber));
+         sourceBuf[offset] =
+            static_cast<ossim_sint32>(theMinPixelValue[bandNumber] +
+                                      delta*inputValue);
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+      {
+         ossim_float32* sourceBuf = getFloatBuf(bandNumber);
+         sourceBuf[offset] =
+            static_cast<ossim_float32>(theMinPixelValue[bandNumber] +
+                                       delta*inputValue);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         ossim_float64* sourceBuf = getDoubleBuf(bandNumber);
+         sourceBuf[offset] =
+            static_cast<ossim_float64>(theMinPixelValue[bandNumber]
+                                       + delta*inputValue);
+      break;
+   }
+   case OSSIM_SCALAR_UNKNOWN:
+   default:
+      // Shouldn't hit this.
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::setNormalizedFloat Unsupported scalar type!"
+         << std::endl;
+   }
+}
+
+void ossimImageData::convertToNormalizedFloat(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_FLOAT) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   copyTileToNormalizedBuffer((ossim_float32*)result->getBuf());
+   result->setDataObjectStatus(getDataObjectStatus());
+}
+
+ossimRefPtr<ossimImageData> ossimImageData::newNormalizedFloat()const
+{
+   ossimRefPtr<ossimImageData> result =
+      new ossimImageData(NULL,
+                         OSSIM_NORMALIZED_FLOAT,
+                         this->getNumberOfBands(),
+                         this->getWidth(),
+                         this->getHeight());
+   
+   result->initialize();
+   
+   convertToNormalizedFloat(result.get());
+   
+   return result;
+}
+
+void ossimImageData::convertToNormalizedDouble(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_DOUBLE) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   copyTileToNormalizedBuffer((ossim_float64*)result->getBuf());
+   result->setDataObjectStatus(getDataObjectStatus());
+}
+
+ossimImageData* ossimImageData::newNormalizedDouble()const
+{
+   ossimImageData* result = new ossimImageData(NULL,
+                                               OSSIM_NORMALIZED_DOUBLE,
+                                               this->getNumberOfBands(),
+                                               this->getWidth(),
+                                               this->getHeight());
+   result->initialize();
+
+   convertToNormalizedDouble(result);
+   
+   return result;   
+}
+
+
+void ossimImageData::unnormalizeInput(ossimImageData* normalizedInput)
+{
+   if((normalizedInput->getScalarType() != OSSIM_NORMALIZED_FLOAT) &&
+      (normalizedInput->getScalarType() != OSSIM_NORMALIZED_DOUBLE) )
+   {
+      //ERROR
+      return;
+   }
+
+   if(normalizedInput->getScalarType() == OSSIM_NORMALIZED_DOUBLE)
+   {
+      copyNormalizedBufferToTile((ossim_float64*)normalizedInput->getBuf());
+   }
+   else
+   {
+      copyNormalizedBufferToTile((ossim_float32*)normalizedInput->getBuf());
+   }
+}
+
+ossim_float64 ossimImageData::computeMeanSquaredError(
+   ossim_float64 meanValue,
+   ossim_uint32 bandNumber) const
+{
+   ossim_float64 result = -1; // invalid MSE
+   
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         result = computeMeanSquaredError(ossim_uint8(0),
+                                          meanValue,
+                                          bandNumber);
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         result = computeMeanSquaredError(ossim_sint8(0),
+                                          meanValue,
+                                          bandNumber);
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         result = computeMeanSquaredError(ossim_uint16(0),
+                                          meanValue,
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_SINT16:
+      {
+         result = computeMeanSquaredError(ossim_sint16(0),
+                                          meanValue,
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_UINT32:
+      {
+         result = computeMeanSquaredError(ossim_uint32(0),
+                                          meanValue,
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_SINT32:
+      {
+         result = computeMeanSquaredError(ossim_sint32(0),
+                                          meanValue,
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         result = computeMeanSquaredError(ossim_float32(0.0),
+                                          meanValue,
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         result = computeMeanSquaredError(ossim_float64(0.0),
+                                          meanValue,
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         setDataObjectStatus(OSSIM_STATUS_UNKNOWN);
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::computeMeanSquaredError File %s line %d\n\
+Invalid scalar type:  %d",
+                       __FILE__,
+                       __LINE__,
+                       getScalarType());
+         break;
+      }
+   }
+
+   return result;
+}
+   
+template <class T> ossim_float64 ossimImageData::computeMeanSquaredError(
+   T, /* dummyTemplate */
+   ossim_float64 meanValue,
+   ossim_uint32 bandNumber) const
+{
+   ossim_float64  result               = -1.0; // invalid MSE
+
+   if ( (getDataObjectStatus() == OSSIM_NULL) ||
+        (getDataObjectStatus() == OSSIM_EMPTY) )
+   {
+      return result;
+   }
+   
+   ossim_uint32  index           = 0;
+   ossim_float64 delta           = 0.0;
+   ossim_uint32  validPixelCount = 0;
+
+   const T* BUFFER = static_cast<const T*>(getBuf(bandNumber));
+   if(BUFFER)
+   {
+      const ossim_uint32 BOUNDS = getSizePerBand();
+      for(index = 0; index < BOUNDS; ++index)
+      {
+         if(!isNull(index))
+         {
+            delta = BUFFER[index] - meanValue;
+            result += (delta*delta);
+            ++validPixelCount;
+         }
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+
+//******************************************************************
+//
+// NOTE: I was checking for null and not adding it to the histogram.
+//       this was messing up the equalization algorithms since the
+//       accumulation histogram did not represent the area of the
+//       image.  For now I will leave out the check for "is null" and
+//       add this to the count so that the total accumulation is the
+//       area of the image.
+//
+//******************************************************************
+void ossimImageData::populateHistogram(ossimMultiBandHistogram* histo)
+{
+   ossim_uint32 numberOfBands = getNumberOfBands();
+
+   if( (getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_EMPTY)||
+       (!histo))
+   {
+      return;
+   }
+   switch(getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            ossimHistogram* currentHisto = histo->getHistogram(band);
+            ossim_uint8* buffer = (ossim_uint8*)getBuf(band);
+         
+            if(currentHisto)
+            {
+               ossimHistogram* currentHisto = histo->getHistogram(band);
+               
+               if(currentHisto)
+               {
+                  ossim_uint32 upperBound = getWidth()*getHeight();
+                  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+                  {
+                     currentHisto->UpCount((float)buffer[offset]);
+                  }
+               }
+            }
+         }
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            ossimHistogram* currentHisto = histo->getHistogram(band);
+	 
+             ossim_uint16* buffer = (ossim_uint16*)getBuf(band);
+             if(currentHisto)
+             {
+                ossim_uint32 upperBound = getWidth()*getHeight();
+                for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+                {
+                  currentHisto->UpCount((float)buffer[offset]);
+                }
+             }
+         }
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            ossimHistogram* currentHisto = histo->getHistogram(band);
+            ossim_sint16* buffer = (ossim_sint16*)getBuf(band);
+            
+            if(currentHisto)
+            {
+               ossim_uint32 upperBound = getWidth()*getHeight();
+               for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+               {
+                  currentHisto->UpCount((float)buffer[offset]);
+               }
+            }
+         }
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            ossimHistogram* currentHisto = histo->getHistogram(band);
+            ossim_sint32* buffer = (ossim_sint32*)getBuf(band);
+            
+            if(currentHisto)
+            {
+               ossim_uint32 upperBound = getWidth()*getHeight();
+               for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+               {
+                  currentHisto->UpCount((float)buffer[offset]);
+               }
+            }
+         }
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            ossimHistogram* currentHisto = histo->getHistogram(band);
+            ossim_uint32* buffer = (ossim_uint32*)getBuf(band);
+            
+            if(currentHisto)
+            {
+               ossim_uint32 upperBound = getWidth()*getHeight();
+               for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+               {
+                  currentHisto->UpCount((float)buffer[offset]);
+               }
+            }
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            ossimHistogram* currentHisto = histo->getHistogram(band);
+            ossim_float64* buffer = (ossim_float64*)getBuf(band);
+            
+            if(currentHisto)
+            {
+               ossim_uint32 upperBound = getWidth()*getHeight();
+               for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+               {
+                  currentHisto->UpCount((float)buffer[offset]);
+               }
+            }
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            ossimHistogram* currentHisto = histo->getHistogram(band);
+            ossim_float32* buffer = (ossim_float32*)getBuf(band);
+            
+            if(currentHisto)
+            {
+               ossim_uint32 upperBound = getWidth()*getHeight();
+               for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+               {
+                  currentHisto->UpCount((float)buffer[offset]);
+               }
+            }
+         }
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         //ERROR
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::populateHistogram\n"
+            << "Unknown scalar type." << std::endl;
+      }
+   }  // end of switch
+}
+
+ossim_float64 ossimImageData::computeAverageBandValue(ossim_uint32 bandNumber) const
+{
+   ossim_float64 result = 0.0;
+   
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         result = computeAverageBandValue(ossim_uint8(0),
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_SINT8:
+      {
+         result = computeAverageBandValue(ossim_sint8(0),
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         result = computeAverageBandValue(ossim_uint16(0),
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_SINT16:
+      {
+         result = computeAverageBandValue(ossim_sint16(0),
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_UINT32:
+      {
+         result = computeAverageBandValue(ossim_uint32(0),
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_SINT32:
+      {
+         result = computeAverageBandValue(ossim_sint32(0),
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         result = computeAverageBandValue(ossim_float32(0.0),
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         result = computeAverageBandValue(ossim_float64(0.0),
+                                          bandNumber);
+         break;
+      }  
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         setDataObjectStatus(OSSIM_STATUS_UNKNOWN);
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::computeAverageBandValue File %s line %d\n\
+Invalid scalar type:  %d",
+                       __FILE__,
+                       __LINE__,
+                       getScalarType());
+         break;
+      }
+   }
+
+   return result;
+}
+
+template <class T> ossim_float64 ossimImageData::computeAverageBandValue(
+   T, /* dummy */
+   ossim_uint32 bandNumber) const
+{
+   ossim_float64  result = 0.0;
+
+   if ( (getDataObjectStatus() == OSSIM_NULL) ||
+        (getDataObjectStatus() == OSSIM_EMPTY) )
+   {
+      return result;
+   }
+   
+   ossim_uint32 index = 0;
+   ossim_uint32 validPixelCount = 0;
+
+   const T* BUFFER = static_cast<const T*>(getBuf(bandNumber));
+   if(BUFFER)
+   {
+      const ossim_uint32 BOUNDS = getSizePerBand();
+      for(index = 0; index < BOUNDS; ++index)
+      {
+         if(!isNull(index))
+         {
+            result += BUFFER[index];
+            ++validPixelCount;
+         }
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+ossimDataObjectStatus ossimImageData::validate() const
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         return validate(ossim_uint8(0));
+      }
+      case OSSIM_SINT8:
+      {
+         return validate(ossim_sint8(0));
+      }
+         
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         return validate(ossim_uint16(0));
+      }  
+      case OSSIM_SINT16:
+      {
+         return validate(ossim_sint16(0));
+      }
+         
+      case OSSIM_UINT32:
+      {
+         return validate(ossim_uint32(0));
+      }  
+      case OSSIM_SINT32:
+      {
+         return validate(ossim_sint32(0));
+      }  
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         return validate(ossim_float32(0.0));
+      }
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         return validate(ossim_float64(0.0));
+      }  
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         setDataObjectStatus(OSSIM_STATUS_UNKNOWN);
+         break;
+      }
+   }
+
+   return OSSIM_STATUS_UNKNOWN;
+}
+
+template <class T>
+ossimDataObjectStatus ossimImageData::validate(T /* dummyTemplate */ ) const
+{
+   if (theDataBuffer == NULL)
+   {
+      setDataObjectStatus(OSSIM_NULL);
+      return OSSIM_NULL;
+   }
+
+   ossim_uint32       count           = 0;
+   const ossim_uint32 SIZE            = getSize();
+   const ossim_uint32 BOUNDS          = getSizePerBand();
+   const ossim_uint32 NUMBER_OF_BANDS = getNumberOfBands();
+   
+   for(ossim_uint32 band = 0; band < NUMBER_OF_BANDS; ++band)
+   {
+      const T NP = static_cast<T>(theNullPixelValue[band]);
+      const T* p = static_cast<const T*>(getBuf(band));
+      
+      for (ossim_uint32 i = 0; i < BOUNDS; ++i)
+      {
+         // check if the band is null
+         if (p[i] != NP) ++count;         
+      }
+   }
+
+   if (!count)
+      setDataObjectStatus(OSSIM_EMPTY);
+   else if (count == SIZE)
+      setDataObjectStatus(OSSIM_FULL);
+   else
+      setDataObjectStatus(OSSIM_PARTIAL);
+
+   return getDataObjectStatus();
+}
+
+void ossimImageData::makeBlank()
+{
+   if ( (theDataBuffer == NULL) || (getDataObjectStatus() == OSSIM_EMPTY) )
+   {
+      return; // nothing to do...
+   }
+
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         makeBlank(ossim_uint8(0));
+         return;
+      }  
+      case OSSIM_SINT8:
+      {
+         makeBlank(ossim_sint8(0));
+         return;
+      }  
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         makeBlank(ossim_uint16(0));
+         return;
+      }  
+      case OSSIM_SINT16:
+      {
+         makeBlank(ossim_sint16(0));
+         return;
+      }  
+      case OSSIM_UINT32:
+      {
+         makeBlank(ossim_uint32(0));
+         return;
+      }
+      case OSSIM_SINT32:
+      {
+         makeBlank(ossim_sint32(0));
+         return;
+      }  
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         makeBlank(ossim_float32(0.0));
+         return;
+      }  
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         makeBlank(ossim_float64(0.0));
+         return;
+      }  
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         setDataObjectStatus(OSSIM_STATUS_UNKNOWN);
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::makeBlank File %s line %d\n\
+Invalid scalar type:  %d",
+                       __FILE__,
+                       __LINE__,
+                       getScalarType());
+         break;
+      }
+   }
+}
+
+template <class T> void ossimImageData::makeBlank(T /* dummyTemplate */ )
+{
+   if ( (theDataBuffer == NULL) || (getDataObjectStatus() == OSSIM_EMPTY) )
+   {
+      return; // nothing to do...
+   }
+   
+   const ossim_uint32 BANDS = getNumberOfBands();
+   const ossim_uint32 SPB   = getSizePerBand();
+   
+   for(ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      const T NP = static_cast<T>(theNullPixelValue[band]);
+      T* p = static_cast<T*>(getBuf(band));
+      for (ossim_uint32 i = 0; i < SPB; ++i)
+      {
+         p[i] = NP;
+      }
+   }
+   
+   setDataObjectStatus(OSSIM_EMPTY);
+}
+
+void ossimImageData::initialize()
+{
+   // let the base class allocate a buffer
+   ossimRectilinearDataObject::initialize();
+   
+   if(!theMinPixelValue)
+   {
+      initializeDefaults();
+   }
+   
+   if (theDataBuffer)
+   {
+      makeBlank();  // Make blank will set the status.
+   }
+}
+
+bool ossimImageData::isWithin(ossim_int32 x, ossim_int32 y)
+{
+   return ((x >= theOrigin.x) &&
+           (x <  theOrigin.x + static_cast<ossim_int32>(theSpatialExtents[0])) &&
+           (y >= theOrigin.y) &&
+           (y <  theOrigin.y + static_cast<ossim_int32>(theSpatialExtents[1])));
+           
+}
+
+void ossimImageData::setValue(ossim_int32 x, ossim_int32 y, ossim_float64 color)
+{
+   if(theDataBuffer&&isWithin(x, y))
+   {
+      ossim_uint32 band=0;
+
+      //***
+      // Compute the offset into the buffer for (x,y).  This should always
+      // come out positive.
+      //***
+      ossim_uint32 ux = static_cast<ossim_uint32>(x - theOrigin.x);
+      ossim_uint32 uy = static_cast<ossim_uint32>(y - theOrigin.y);
+      
+      ossim_uint32 offset = uy * theSpatialExtents[0] + ux;
+      
+      switch (getScalarType())
+      {
+         case OSSIM_UINT8:
+         {
+            for(band = 0; band < theNumberOfDataComponents; band++)
+            {
+               unsigned char* buf = static_cast<unsigned char*>(getBuf(band))+
+                  offset;
+               *buf = (unsigned char)color;
+            }
+            break;
+         }
+         case OSSIM_SINT8:
+         {
+            for(band = 0; band < theNumberOfDataComponents; band++)
+            {
+               ossim_sint8* buf = static_cast<ossim_sint8*>(getBuf(band))+
+                  offset;
+               *buf = (ossim_sint8)color;
+            }
+            break;
+         }
+         case OSSIM_UINT16:
+         case OSSIM_USHORT11:
+         {
+            for(band = 0; band < theNumberOfDataComponents; band++)
+            {
+               ossim_uint16* buf = static_cast<ossim_uint16*>(getBuf(band))+
+                  offset;
+               *buf = (ossim_uint16)color;
+            }
+            break;
+         }
+         case OSSIM_SINT16:
+         {
+            for(band = 0; band < theNumberOfDataComponents; band++)
+            {
+               signed short* buf = static_cast<signed short*>(getBuf(band))+
+                  offset;
+               *buf = (signed short)color;
+            }
+            break;
+         }
+         case OSSIM_UINT32:
+         {
+            for(band = 0; band < theNumberOfDataComponents; band++)
+            {
+               ossim_uint32* buf = static_cast<ossim_uint32*>(getBuf(band))+
+                  offset;
+               *buf = (ossim_uint32)color;
+            }
+            break;
+         }
+         case OSSIM_SINT32:
+         {
+            for(band = 0; band < theNumberOfDataComponents; band++)
+            {
+               ossim_sint32* buf = static_cast<ossim_sint32*>(getBuf(band))+
+                  offset;
+               *buf = (ossim_sint32)color;
+            }
+            break;
+         }
+         case OSSIM_NORMALIZED_FLOAT:
+         case OSSIM_FLOAT32:
+         {
+            for(band = 0; band < theNumberOfDataComponents; band++)
+            {
+               ossim_float32* buf = static_cast<ossim_float32*>(getBuf(band))+offset;
+               *buf = (ossim_float32)color;
+            }
+            break;
+         }
+         case OSSIM_FLOAT64:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            for(band = 0; band < theNumberOfDataComponents; band++)
+            {
+               ossim_float64* buf = static_cast<ossim_float64*>(getBuf(band))+offset;
+               *buf = color;
+            }
+            break;
+         }
+         case OSSIM_SCALAR_UNKNOWN:
+         default:
+         {
+            //ERROR
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "ossimImageData::setValue Unsupported scalar type!"
+               << std::endl;
+            
+         }
+         
+      } // End of:  switch (getScalarType())
+   }
+}
+
+void ossimImageData::initializeDefaults()
+{
+   ossim_uint32 numberOfBands = getNumberOfBands();
+   if(numberOfBands < 1)
+   {
+      return;
+   }
+   if(theMinPixelValue)
+   {
+      delete [] theMinPixelValue;
+      theMinPixelValue = NULL;
+   }
+   if(theMaxPixelValue)
+   {
+      delete [] theMaxPixelValue;
+      theMaxPixelValue = NULL;
+   }
+   if(theNullPixelValue)
+   {
+      delete [] theNullPixelValue;
+      theNullPixelValue = NULL;
+   }
+   theMinPixelValue  = new ossim_float64[numberOfBands];
+   theMaxPixelValue  = new ossim_float64[numberOfBands];
+   theNullPixelValue = new ossim_float64[numberOfBands];
+   ossim_uint32 band;
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = 0.0;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_UCHAR;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_UCHAR;
+         }
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = OSSIM_DEFAULT_MIN_PIX_SINT8-1;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_SINT8;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_SINT8;
+         }
+         break;
+      }
+      case OSSIM_UINT16:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = OSSIM_USHORT_NAN;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_UINT16;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_UINT16;
+         }
+         break;
+      }
+      case OSSIM_USHORT11:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = OSSIM_USHORT_NAN;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_UINT11;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_UINT11;
+         }
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = OSSIM_SSHORT_NAN;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_SINT16;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_SINT16;
+         }
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = OSSIM_UINT_NAN;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_UINT32;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_UINT32;
+         }
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = OSSIM_DEFAULT_MIN_PIX_SINT32-1;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_SINT32;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_SINT32;
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = 0.0;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_NORM_FLOAT;
+         }
+         break;
+      }
+      case OSSIM_FLOAT32:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = OSSIM_FLT_NAN;         
+            theMinPixelValue[band]  =  OSSIM_DEFAULT_MIN_PIX_FLOAT;
+            theMaxPixelValue[band]  =  OSSIM_DEFAULT_MAX_PIX_FLOAT;
+         }
+         break;
+      }
+      case OSSIM_FLOAT64:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = OSSIM_DBL_NAN;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_DOUBLE;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_DOUBLE;
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = 0.0;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_NORM_DOUBLE;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_NORM_DOUBLE;
+         }
+         break;
+      }
+      default:
+      {
+         for(band = 0; band < numberOfBands; ++band)
+         {
+            theNullPixelValue[band] = 0.0;
+            theMinPixelValue[band]  = OSSIM_DEFAULT_MIN_PIX_UCHAR;
+            theMaxPixelValue[band]  = OSSIM_DEFAULT_MAX_PIX_UCHAR;
+         }
+         break;
+      }
+   }
+}
+
+bool ossimImageData::isEqualTo(const ossimDataObject& rhs,
+                               bool deepTest)const
+{
+   ossimImageData* rhsPtr = PTR_CAST(ossimImageData, &rhs);
+   if(!(&rhs)||(!rhsPtr)) return false;
+   bool result = ( (theScalarType         == rhsPtr->theScalarType)&&
+                   (theNumberOfDataComponents == rhsPtr->theNumberOfDataComponents)&&
+                   (theOrigin             == rhsPtr->theOrigin)&&
+                   (getWidth()            == rhsPtr->getWidth())&&
+                   (getHeight()           == rhsPtr->getHeight()));
+
+   if(result)
+   {
+      bool test=true;
+      for(ossim_uint32 index = 0; index < theNumberOfDataComponents; ++index)
+      {
+         if(theMinPixelValue[index] != rhsPtr->theMinPixelValue[index])
+         {
+            test = false;
+            break;
+         }
+         if(theMaxPixelValue[index] != rhsPtr->theMaxPixelValue[index])
+         {
+            test = false;
+            break;
+         }
+         if(theNullPixelValue[index] != rhsPtr->theNullPixelValue[index])
+         {
+            test = false;
+            break;
+         }
+      }
+      result = test;
+   }
+   if(deepTest&&result)
+   {
+      if(theDataBuffer && rhsPtr->theDataBuffer)
+      {
+         if(memcmp(theDataBuffer, rhsPtr->theDataBuffer, getSizeInBytes()) != 0)
+         {
+            result = false;
+         }
+      }
+      else if(!theDataBuffer&&!rhsPtr->theDataBuffer)
+      {
+         // nothing both are null so don't change the result.
+      }
+      else // one is null so not equal.
+      {
+         result = false;
+      }
+   }
+
+   return result;
+}
+
+ossimString ossimImageData::getScalarTypeAsString() const
+{
+   return ossimScalarTypeLut::instance()->getEntryString(getScalarType());
+}
+
+ossim_uint32 ossimImageData::getNumberOfBands() const
+{
+   return getNumberOfDataComponents();
+}
+
+ossim_float64 ossimImageData::getPix(const ossimIpt& position,
+                              ossim_uint32 band) const
+{
+   ossimIpt relative( position.x - theOrigin.x,
+                      position.y - theOrigin.y);
+   return getPix((theSpatialExtents[0])*relative.y + relative.x, band);
+}
+
+ossim_float64 ossimImageData::getPix(ossim_uint32 offset, ossim_uint32 band) const
+{
+   switch(theScalarType)
+   {
+      case OSSIM_UINT8:
+      {
+         const ossim_uint8* buf = getUcharBuf(band);
+         if(buf)
+         {
+            return (ossim_float64)buf[offset];
+         }
+      }
+      case OSSIM_SINT8:
+      {
+         const ossim_sint8* buf = static_cast<const ossim_sint8*>(getBuf(band));
+         if(buf)
+         {
+            return (ossim_float64)buf[offset];
+         }
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         const ossim_uint16* buf = getUshortBuf(band);
+         if(buf)
+         {
+            return (ossim_float64)buf[offset];
+         }
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         const ossim_sint16* buf = getSshortBuf(band);
+         if(buf)
+         {
+            return (ossim_float64)buf[offset];
+         }
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         const ossim_sint32* buf = static_cast<const ossim_sint32*>(getBuf(band));
+         if(buf)
+         {
+            return (ossim_float64)buf[offset];
+         }
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         const ossim_uint32* buf = static_cast<const ossim_uint32*>(getBuf(band));
+         if(buf)
+         {
+            return (ossim_float64)buf[offset];
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         const ossim_float64* buf = getDoubleBuf(band);
+         if(buf)
+         {
+            return (ossim_float64)buf[offset];
+         }      
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+      {
+         const ossim_float32* buf = getFloatBuf(band);
+         if(buf)
+         {
+            return (ossim_float64)buf[offset];
+         }
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         // Shouldn't hit this.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::fill Unsupported scalar type!"
+            << std::endl;   
+   }
+
+   return 0.0;
+}
+
+void ossimImageData::fill(ossim_uint32 band, ossim_float64 value)
+{
+   void* s         = getBuf(band);
+
+   if (s == NULL) return; // nothing to do...
+
+   ossim_uint32 size_in_pixels = getWidth()*getHeight();
+   
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         ossim_uint8* p = getUcharBuf(band);
+         ossim_uint8 np = static_cast<ossim_uint8>(value);
+         for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+         
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         ossim_sint8* p = static_cast<ossim_sint8*>(getBuf(band));
+         ossim_sint8 np = static_cast<ossim_sint8>(value);
+         for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+         
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         ossim_uint16* p = getUshortBuf(band);
+         ossim_uint16 np = static_cast<ossim_uint16>(value);
+         for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+         
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         ossim_sint16* p = getSshortBuf(band);
+         ossim_sint16 np = static_cast<ossim_sint16>(value);
+         for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+         
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         ossim_uint32* p = static_cast<ossim_uint32*>(getBuf(band));
+         ossim_uint32 np = static_cast<ossim_uint32>(value);
+         for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+         
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         ossim_sint32* p = static_cast<ossim_sint32*>(getBuf(band));
+         ossim_sint32 np = static_cast<ossim_sint32>(value);
+         for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+         
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+      {
+         ossim_float32* p = getFloatBuf(band);
+         ossim_float32 np = static_cast<ossim_float32>(value);
+         for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+         
+         break;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         ossim_float64* p = getDoubleBuf(band);
+         ossim_float64 np = static_cast<ossim_float64>(value);
+         for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+         
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::makeBlank File %s line %d\n\
+Invalid scalar type:  %d",
+                       __FILE__,
+                       __LINE__,
+                       getScalarType());
+         return;
+   }
+   
+   setDataObjectStatus(OSSIM_EMPTY);
+   
+}
+
+void ossimImageData::fill(ossim_float64 value)
+{
+   ossim_uint32 valueNullCount= 0;
+   for(ossim_uint32 band=0; band < getNumberOfBands(); ++band)
+   {
+      if (value == theNullPixelValue[band])
+      {
+         ++valueNullCount;
+      }
+      
+      fill(band, value);
+   }
+
+   if (valueNullCount==0)
+   {
+      setDataObjectStatus(OSSIM_FULL);
+   }
+   else if(valueNullCount==getNumberOfBands())
+   {
+      setDataObjectStatus(OSSIM_EMPTY);
+   }
+   else
+   {
+      setDataObjectStatus(OSSIM_PARTIAL);
+   }
+}
+
+bool ossimImageData::isNull(ossim_uint32 offset)const
+{
+   ossim_uint32 numberOfBands = getNumberOfBands();
+   ossim_uint32 band=0;
+   if(!getBuf())
+   {
+      return true;
+   }
+
+   switch(getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         for(band = 0; band < numberOfBands; ++band)  
+         {
+            const ossim_uint8* buf = static_cast<const ossim_uint8*>(getBuf(band))+offset;
+            if((*buf) != (ossim_uint8)getNullPix(band))
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         for(band = 0; band < numberOfBands; ++band)  
+         {
+            const ossim_sint8* buf = static_cast<const ossim_sint8*>(getBuf(band))+offset;
+            if((*buf) != (ossim_uint8)getNullPix(band))
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            const ossim_uint16* buf = static_cast<const ossim_uint16*>(getBuf(band))+offset;
+            if((*buf) != (ossim_uint16)getNullPix(band))
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            const ossim_sint16* buf = static_cast<const ossim_sint16*>(getBuf(band))+offset;
+            if((*buf) != (ossim_sint16)getNullPix(band))
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            const ossim_uint32* buf = static_cast<const ossim_uint32*>(getBuf(band))+offset;
+            if((*buf) != (ossim_uint32)getNullPix(band))
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            const ossim_sint32* buf = static_cast<const ossim_sint32*>(getBuf(band))+offset;
+            if((*buf) != (ossim_sint32)getNullPix(band))
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            const ossim_float32* buf = static_cast<const ossim_float32*>(getBuf(band))+offset;
+            if((*buf) != 0.0)
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_FLOAT32:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            const ossim_float32* buf = static_cast<const ossim_float32*>(getBuf(band))+offset;
+            if((*buf) != (ossim_float32)getNullPix(band))
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            const ossim_float64* buf = static_cast<const ossim_float64*>(getBuf(band))+offset;
+            if((*buf) != 0.0)
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_FLOAT64:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            const ossim_float64* buf = static_cast<const ossim_float64*>(getBuf(band))+offset;
+            if((*buf) != getNullPix(band))
+            {
+               return false;
+            }
+         }
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         //ERROR
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::isNull Unsupported scalar type!"
+            << std::endl;
+      }
+   }
+   return true;
+}
+
+bool ossimImageData::isNull(ossim_uint32 offset, ossim_uint32 band)const
+{
+   switch(getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         const ossim_uint8* buf =
+            static_cast<const ossim_uint8*>(getBuf(band))+offset;
+         
+         if((*buf) != (ossim_uint8)getNullPix(band))
+         {
+            return false;
+         }
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         const ossim_sint8* buf =
+            static_cast<const ossim_sint8*>(getBuf(band))+offset;
+         
+         if((*buf) != (ossim_sint8)getNullPix(band))
+         {
+            return false;
+         }
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         const ossim_uint16* buf =
+            static_cast<const ossim_uint16*>(getBuf(band))+offset;
+         if((*buf) != (ossim_uint16)getNullPix(band))
+         {
+            return false;
+         }
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         const ossim_sint16* buf =
+            static_cast<const ossim_sint16*>(getBuf(band))+offset;
+         if((*buf) != (ossim_sint16)getNullPix(band))
+         {
+            return false;
+         }
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         const ossim_uint32* buf =
+            static_cast<const ossim_uint32*>(getBuf(band))+offset;
+         if((*buf) != (ossim_uint32)getNullPix(band))
+         {
+            return false;
+         }
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         const ossim_sint32* buf =
+            static_cast<const ossim_sint32*>(getBuf(band))+offset;
+         if((*buf) != (ossim_sint32)getNullPix(band))
+         {
+            return false;
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+      {
+         const ossim_float32* buf = static_cast<const ossim_float32*>(getBuf(band))+offset;
+         if((*buf) != (ossim_float32)getNullPix(band))
+         {
+            return false;
+         }
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         const ossim_float64* buf = static_cast<const ossim_float64*>(getBuf(band))+offset;
+         if((*buf) != getNullPix(band))
+         {
+            return false;
+         }
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         //ERROR
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::isNull Unsupported scalar type!"
+            << std::endl;
+      }
+   }
+   return true;
+}
+
+bool ossimImageData::isNull(const ossimIpt& pt)const
+{
+   ossim_int32 xNew = (pt.x - theOrigin.x);
+   ossim_int32 yNew = (pt.y - theOrigin.y);
+   if(xNew < 0 || xNew >= (int)theSpatialExtents[0] ||
+      yNew < 0 || yNew >= (int)theSpatialExtents[1])
+   {
+      return true;
+   }
+   ossim_uint32 offset = getWidth()*yNew + xNew;
+   
+   return isNull(offset);
+}
+
+bool ossimImageData::isNull(const ossimIpt& pt, ossim_uint32 band)const
+{
+   ossim_int32 xNew = (pt.x - theOrigin.x);
+   ossim_int32 yNew = (pt.y - theOrigin.y);
+   if(xNew < 0 || xNew >= (int)theSpatialExtents[0] ||
+      yNew < 0 || yNew >= (int)theSpatialExtents[1])
+   {
+      return true;
+   }
+   ossim_uint32 offset = getWidth()*yNew + xNew;
+
+   return isNull(offset, band);
+}
+
+void ossimImageData::setNull(ossim_uint32 offset)
+{
+   ossim_uint32 numberOfBands = getNumberOfBands();
+   ossim_uint32 band=0;
+   switch(getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         for(band = 0; band < numberOfBands; ++band)  
+         {
+            ossim_uint8* buf = static_cast<ossim_uint8*>(getBuf(band))+offset;
+            *buf       = (ossim_uint8)getNullPix(band);
+         }
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         for(band = 0; band < numberOfBands; ++band)  
+         {
+            ossim_sint8* buf = static_cast<ossim_sint8*>(getBuf(band))+offset;
+            *buf       = (ossim_sint8)getNullPix(band);
+         }
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            ossim_uint16* buf = static_cast<ossim_uint16*>(getBuf(band))+
+               offset;
+            *buf = (ossim_uint16)getNullPix(band);
+         }
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            ossim_sint16* buf = static_cast<ossim_sint16*>(getBuf(band))+
+               offset;
+            *buf = (ossim_sint16)getNullPix(band);
+         }
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            ossim_uint32* buf = static_cast<ossim_uint32*>(getBuf(band))+
+               offset;
+            *buf = (ossim_uint32)getNullPix(band);
+         }
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            ossim_sint32* buf = static_cast<ossim_sint32*>(getBuf(band))+
+               offset;
+            *buf = (ossim_sint32)getNullPix(band);
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            ossim_float32* buf = static_cast<ossim_float32*>(getBuf(band))+offset;
+            *buf = (ossim_float32)getNullPix(band);
+         }
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         for(band = 0; band < numberOfBands; band++)
+         {
+            ossim_float64* buf = static_cast<ossim_float64*>(getBuf(band))+offset;
+            *buf = getNullPix(band);
+         }
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         //ERROR
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::isNull Unsupported scalar type!"
+            << std::endl;
+      }
+   }
+}
+
+void ossimImageData::setNull(ossim_uint32 offset, ossim_uint32 band)
+{
+   switch(getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         ossim_uint8* buf = static_cast<ossim_uint8*>(getBuf(band))+offset;
+         *buf       = (ossim_uint8)getNullPix(band);
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         ossim_sint8* buf = static_cast<ossim_sint8*>(getBuf(band))+offset;
+         *buf       = (ossim_sint8)getNullPix(band);
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         ossim_uint16* buf = static_cast<ossim_uint16*>(getBuf(band))+offset;
+         *buf = (ossim_uint16)getNullPix(band);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         ossim_sint16* buf = static_cast<ossim_sint16*>(getBuf(band))+offset;
+         *buf = (ossim_sint16)getNullPix(band);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         ossim_uint32* buf = static_cast<ossim_uint32*>(getBuf(band))+offset;
+         *buf       = (ossim_uint32)getNullPix(band);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         ossim_sint32* buf = static_cast<ossim_sint32*>(getBuf(band))+offset;
+         *buf       = (ossim_sint32)getNullPix(band);
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+      {
+         ossim_float32* buf = static_cast<ossim_float32*>(getBuf(band))+offset;
+         *buf = (ossim_float32)getNullPix(band);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         ossim_float64* buf = static_cast<ossim_float64*>(getBuf(band))+offset;
+         *buf = getNullPix(band);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         //ERROR
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::isNull Unsupported scalar type!"
+            << std::endl;
+      }
+   }
+}
+
+void ossimImageData::setNull(const ossimIpt& pt)
+{
+   ossim_int32 xNew = (pt.x - theOrigin.x);
+   ossim_int32 yNew = (pt.y - theOrigin.y);
+   
+   if(xNew < 0 || xNew >= (int)theSpatialExtents[0] ||
+      yNew < 0 || yNew >= (int)theSpatialExtents[1])
+   {
+      return;
+   }
+   ossim_uint32 offset = ((int)getWidth())*yNew + xNew;
+   
+   setNull(offset);
+}
+
+void ossimImageData::setNull(const ossimIpt& pt, ossim_uint32 band)
+{
+   ossim_int32 xNew = (pt.x - theOrigin.x);
+   ossim_int32 yNew = (pt.y - theOrigin.y);
+   
+   if(xNew < 0 || xNew >= (int)theSpatialExtents[0] ||
+      yNew < 0 || yNew >= (int)theSpatialExtents[1])
+   {
+      return;
+   }
+   ossim_uint32 offset = ((int)getWidth())*yNew + xNew;
+   
+   setNull(offset, band);
+}
+
+void ossimImageData::setNullPix(ossim_float64 null_pix)
+{
+   if(!theNullPixelValue) initializeDefaults();
+   if(!theNullPixelValue) return;
+   ossim_uint32 num = getNumberOfBands();
+   for(ossim_uint32 band = 0; band < num; ++band)
+   {
+      theNullPixelValue[band] = null_pix;
+   }
+}
+
+void ossimImageData::setNullPix(ossim_float64 null_pix, ossim_uint32 band)
+{
+   if(!theNullPixelValue) initializeDefaults();
+   if(!theNullPixelValue) return;
+   theNullPixelValue[band] = null_pix;
+}
+
+void ossimImageData::setNullPix(const ossim_float64* nullPixArray, ossim_uint32 numberOfValues)
+{
+   if(!nullPixArray) return;
+   if(!theNullPixelValue) initializeDefaults();
+   if(!theNullPixelValue) return;
+   for(ossim_uint32 band = 0;
+       (band < numberOfValues)&&(band < theNumberOfDataComponents); ++band)
+   {
+      theNullPixelValue[band] = nullPixArray[band];
+   }
+}
+
+void ossimImageData::setMinPix(ossim_float64 min_pix, ossim_uint32 band)
+{
+   if(!theMinPixelValue) initializeDefaults();
+   if(!theMinPixelValue) return;
+   theMinPixelValue[band] = min_pix;
+}
+
+void ossimImageData::setMinPix(const ossim_float64* minPixArray, ossim_uint32 numberOfValues)
+{
+   if(!minPixArray) return;
+   if(!theMinPixelValue) initializeDefaults();
+   if(!theMinPixelValue) return;
+   for(ossim_uint32 band = 0; (band < numberOfValues)&&(band < theNumberOfDataComponents); ++band)
+   {
+      theMinPixelValue[band] = minPixArray[band];
+   }
+}
+
+void ossimImageData::setMinPix(ossim_float64 min_pix)
+{
+   if(!theMinPixelValue) initializeDefaults();
+   if(!theMinPixelValue) return;
+   ossim_uint32 num = getNumberOfBands();
+   for(ossim_uint32 band = 0; band < num; ++band)
+   {
+      theMinPixelValue[band] = min_pix;
+   }
+}
+
+void ossimImageData::setMaxPix(ossim_float64 max_pix)
+{
+   if(!theMaxPixelValue) initializeDefaults();
+   if(!theMaxPixelValue) return;
+   ossim_uint32 num = getNumberOfBands();
+   for(ossim_uint32 band = 0; band < num; ++band)
+   {
+      theMaxPixelValue[band] = max_pix;
+   }
+}
+
+void ossimImageData::setMaxPix(ossim_float64 max_pix, ossim_uint32 band)
+{
+   if(!theMaxPixelValue) initializeDefaults();
+   if(!theMaxPixelValue) return;
+   theMaxPixelValue[band] = max_pix;
+}
+
+void ossimImageData::setMaxPix(const ossim_float64* maxPixArray, ossim_uint32 numberOfValues)
+{
+   if(!maxPixArray) return;
+   if(!theMaxPixelValue) initializeDefaults();
+   if(!theMaxPixelValue) return;
+   for(ossim_uint32 band = 0; (band < numberOfValues)&&(band < theNumberOfDataComponents); ++band)
+   {
+      theMaxPixelValue[band] = maxPixArray[band];
+   }
+}
+
+void ossimImageData::setNumberOfBands(ossim_uint32 bands,
+                                      bool reallocate)
+{
+   ossim_uint32 b  = getNumberOfBands();
+   if((b != bands)&&
+      bands&&
+      theNullPixelValue&&
+      theMinPixelValue&&
+      theMaxPixelValue)
+   {
+      setNumberOfDataComponents(bands);
+      if(reallocate)
+      {
+         ossimRectilinearDataObject::initialize();
+      }
+      
+      ossim_uint32 minBands = ossimMin(b, bands);
+      ossim_float64 *newNull = new ossim_float64[bands];
+      ossim_float64 *newMin  = new ossim_float64[bands];
+      ossim_float64 *newMax  = new ossim_float64[bands];
+      
+      std::copy(theNullPixelValue,
+                theNullPixelValue + minBands,
+                newNull);
+      std::copy(theMinPixelValue,
+                theMinPixelValue + minBands,
+                newMin);
+      std::copy(theMaxPixelValue,
+                theMaxPixelValue + minBands,
+                newMax);
+      
+      if(bands > minBands)
+      {
+         std::fill(newNull+minBands,
+                   newNull+bands,
+                   theNullPixelValue[b - 1]);
+         std::fill(newMin+minBands,
+                   newMin+bands,
+                   theMinPixelValue[b - 1]);
+         std::fill(newMax+minBands,
+                   newMax+bands,
+                   theMaxPixelValue[b - 1]);
+      }
+      
+      delete [] theNullPixelValue;
+      delete [] theMinPixelValue;
+      delete [] theMaxPixelValue;
+      
+      theNullPixelValue = newNull;
+      theMinPixelValue  = newMin;
+      theMaxPixelValue  = newMax;
+      
+   }
+}
+
+void ossimImageData::setImageRectangleAndBands(const ossimIrect& rect,
+                                               ossim_uint32 numberOfBands)
+{
+   if(rect.hasNans())
+   {
+      return;
+   }
+   
+   ossim_uint32 bands   = getNumberOfBands();
+   ossim_uint32 w       = getWidth();
+   ossim_uint32 h       = getHeight();
+   ossim_uint32 nw      = rect.width();
+   ossim_uint32 nh      = rect.height();
+
+   setOrigin(rect.ul());
+   setWidthHeight(nw, nh);
+   setNumberOfBands(numberOfBands, false);
+   
+   // we will try to be non destructive on the resize of the number of bands
+   if( ( (w*h != nw*nh)  || ( bands != numberOfBands) ) &&
+       (theDataObjectStatus != OSSIM_NULL) )
+   {
+      initialize();
+   }
+}
+
+void ossimImageData::setImageRectangle(const ossimIrect& rect)
+{
+   if(rect.hasNans())
+   {
+      return;
+   }
+   
+   ossim_uint32 w  = getWidth();
+   ossim_uint32 h  = getHeight();
+   ossim_uint32 nw = rect.width();
+   ossim_uint32 nh = rect.height();
+
+   setOrigin(rect.ul());
+   setWidthHeight(nw, nh);
+
+   // we will try to be non destructive on the resize of the number of bands
+   if ( (w*h != nw*nh) && (theDataObjectStatus != OSSIM_NULL) )
+   {
+      initialize();
+   }
+}
+
+void ossimImageData::assign(const ossimDataObject* data)
+{
+   if(!data) return;
+   ossimImageData* d = PTR_CAST(ossimImageData, data);
+   if(d)
+   {
+      assign(d);
+   }
+}
+
+void ossimImageData::assign(const ossimImageData* data)
+{
+   ossimSource* tmp_owner = getOwner();
+   
+   ossimRectilinearDataObject::assign(data);
+
+   //***
+   // The data member "theSource" will be overwritten so capture it and then
+   // set it back.
+   //***
+   setOwner(tmp_owner);
+
+   if(this != data)
+   {
+      if(theMinPixelValue)
+      {
+         delete [] theMinPixelValue;
+         theMinPixelValue = NULL;
+      }
+      if(theMaxPixelValue)
+      {
+         delete [] theMaxPixelValue;
+         theMaxPixelValue = NULL;
+      }
+      if(theNullPixelValue)
+      {
+         delete [] theNullPixelValue;
+         theNullPixelValue = NULL;
+      }
+      ossim_uint32 numberOfBands = getNumberOfBands();
+      if(!numberOfBands)
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::assign\n"
+            << "Number of components is 0, can't assign" << std::endl;
+         return;
+      }
+      theOrigin = data->theOrigin;
+      theMinPixelValue  = new ossim_float64[numberOfBands];
+      theMaxPixelValue  = new ossim_float64[numberOfBands];
+      theNullPixelValue = new ossim_float64[numberOfBands];
+      if(data->theMinPixelValue&&
+         data->theMaxPixelValue&&
+         data->theNullPixelValue)
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            theMinPixelValue[band]  = data->theMinPixelValue[band];
+            theMaxPixelValue[band]  = data->theMaxPixelValue[band];
+            theNullPixelValue[band] = data->theNullPixelValue[band];
+         }
+      }
+      else
+      {
+         initializeDefaults();
+      }
+   }
+}
+
+void ossimImageData::assignBand(const ossimImageData* data,
+                                ossim_uint32 source_band,
+                                ossim_uint32 output_band)
+{
+   //***
+   // This method requires this image data to be initialized to the same
+   // size as the source data being copied.
+   //***
+
+   // Some basic error checking...
+   if ( !data->isValidBand(source_band) )
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::assignBand ERROR:"
+         << "\nInvalid source band!" << std::endl;
+      return;
+   }
+   if ( !isValidBand(output_band) )
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::assignBand ERROR:"
+         << "\nInvalid output band!" << std::endl;
+      return;
+   }
+   if (data->getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::assignBand ERROR:"
+         << "\nSource data status is null!" << std::endl;
+      return;
+   }
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::assignBand ERROR:"
+         << "\nThis status is null!" << std::endl;
+      return;
+   }
+   
+   //***
+   // Make sure this buffer is the same size; if not, return.
+   //***
+   ossim_uint32 source_size = data->getSizePerBandInBytes();
+      
+   if ( source_size != getSizePerBandInBytes() )
+   {
+      return;
+   }
+
+   // Get the pointers to the bands.
+   const void*  s = data->getBuf(source_band);
+   void*        d = getBuf(output_band);
+
+   // One last check.
+   if (s == NULL || d == NULL)
+   {
+      return;
+   }
+
+   // Ok copy the image data...
+   memcpy(d, s, source_size);
+}
+
+void ossimImageData::loadBand(const void* src,
+                              const ossimIrect& src_rect,
+                              ossim_uint32 band)
+{
+   // Call the appropriate load method.
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         loadBand(ossim_uint8(0), src, src_rect, band);
+         return;
+
+      case OSSIM_SINT8:
+         loadBand(ossim_sint8(0), src, src_rect, band);
+         return;
+         
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         loadBand(ossim_uint16(0), src, src_rect, band);
+         return;
+         
+      case OSSIM_SINT16:
+         loadBand(ossim_sint16(0), src, src_rect, band);
+         return;
+         
+      case OSSIM_UINT32:
+         loadBand(ossim_uint32(0), src, src_rect, band);
+         return;
+
+      case OSSIM_SINT32:
+         loadBand(ossim_sint32(0), src, src_rect, band);
+         return;
+         
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+         loadBand(ossim_float32(0), src, src_rect, band);
+         return;
+      
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         loadBand(ossim_float64(0), src, src_rect, band);
+         return;
+         
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::loadBand\n\
+File %s line %d\nUnknown scalar type!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+void ossimImageData::loadBand(const void* src,
+                              const ossimIrect& src_rect,
+                              const ossimIrect& clip_rect,
+                              ossim_uint32 band)
+{
+   // Call the appropriate load method.
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         loadBand(ossim_uint8(0), src, src_rect, clip_rect, band);
+         return;
+
+      case OSSIM_SINT8:
+         loadBand(ossim_sint8(0), src, src_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         loadBand(ossim_uint16(0), src, src_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_SINT16:
+         loadBand(ossim_sint16(0), src, src_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_UINT32:
+         loadBand(ossim_uint32(0), src, src_rect, clip_rect, band);
+         return;
+
+      case OSSIM_SINT32:
+         loadBand(ossim_sint32(0), src, src_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+         loadBand(ossim_float32(0), src, src_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         loadBand(ossim_float64(0), src, src_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::loadBand\n\
+File %s line %d\nUnknown scalar type!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+template <class T> void ossimImageData::loadBand(T, // dummy template variable
+                                                 const void* src,
+                                                 const ossimIrect& src_rect,
+                                                 ossim_uint32 band)
+{
+   const ossimIrect img_rect = getImageRectangle();
+
+   // Get the clip rect.
+   const ossimIrect clip_rect = img_rect.clipToRect(src_rect);
+
+   
+   loadBand(T(0), src, src_rect, clip_rect, band);
+}
+
+template <class T> void ossimImageData::loadBand(T, // dummy template variable
+                                                 const void* src,
+                                                 const ossimIrect& src_rect,
+                                                 const ossimIrect& clip_rect,
+                                                 ossim_uint32 band)
+{
+   static const char  MODULE[] = "ossimImageData::loadBand";
+   
+   // Check the pointer.
+   if (!src)
+   {
+      // Set the error...
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "%s File %s line %d\nNULL pointer passed to method!",
+                    MODULE,
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   // Check the band.
+   if (!isValidBand(band))
+   {
+      // Set the error...
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "%s File %s line %d\nInvalid band:  %d",
+                    MODULE,
+                    __FILE__,
+                    __LINE__,
+                    band);
+      return;
+   }
+   
+   const ossimIrect img_rect = getImageRectangle();
+   
+   // Check for intersect.
+   if ( ! img_rect.intersects(src_rect) )
+   {
+//      cerr <<"Doing nothing" << std::endl;
+      return; // Nothing to do here.
+   }
+
+   // Check the clip rect.
+   if (!clip_rect.completely_within(img_rect))
+   {
+//       cerr << MODULE
+//            << " ERROR: clip rect does not fall within tile rect!"
+//            << std::endl;
+      return;
+   }
+   
+   // Check the status and allocate memory if needed.
+   if (getDataObjectStatus() == OSSIM_NULL) initialize();
+
+   // Get the width of the buffers.
+   ossim_uint32 s_width = src_rect.width();
+   ossim_uint32 d_width = getWidth();
+   
+   const T* s = static_cast<const T*>(src);
+   T* d = static_cast<T*>(getBuf(band));
+
+   // Move the pointers to the first valid pixel.
+   s += (clip_rect.ul().y - src_rect.ul().y) * s_width +
+        clip_rect.ul().x - src_rect.ul().x;
+   
+   d += (clip_rect.ul().y - img_rect.ul().y) * d_width +
+        clip_rect.ul().x - img_rect.ul().x;
+   
+   // Copy the data.
+   ossim_uint32 clipHeight = clip_rect.height();
+   ossim_uint32 clipWidth  = clip_rect.width();
+  
+   for (ossim_uint32 line = 0; line < clipHeight; ++line)
+   {
+      for (ossim_uint32 sample = 0; sample < clipWidth; ++sample)
+      {
+         d[sample] = s[sample];
+      }
+
+      s += s_width;
+      d += d_width;
+   }
+}
+
+void ossimImageData::loadTile(const ossimImageData* src)
+{
+   if (!src)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::loadTile ERROR:"
+         << "Null tile passed to method!" << std::endl;
+      return;
+   }
+
+   if (!src->getBuf())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::loadTile ERROR:"
+         << "Source tile buff is null!" << std::endl;
+      return;
+   }
+
+   if (!this->getBuf())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::loadTile ERROR:"
+         << "This tile not initialized!" << std::endl;
+      return;
+   }
+
+   if (src->getNumberOfBands() != this->getNumberOfBands())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::loadTile ERROR:"
+         << "Tiles do not have same number of bands!" << std::endl;
+      return;
+   }
+
+   //***
+   // Set the status of this tile to the status of the source tile.
+   // Do this in place of validate.
+   //***
+   setDataObjectStatus(src->getDataObjectStatus());
+   
+   if(getScalarType() == src->getScalarType())
+   {      
+      loadTile((void*)(src->getBuf()),
+               src->getImageRectangle(),
+               OSSIM_BSQ);
+      setNullPix(src->getNullPix(), src->getNumberOfBands());
+   }
+   else // do a slow generic normalize to unnormalize copy
+   {
+      // Check the pointer.
+      ossimIrect src_rect = src->getImageRectangle();
+      const ossimIrect img_rect = getImageRectangle();
+      
+      // Check for intersect.
+      if ( !img_rect.intersects(src_rect) )
+      {
+         return; // Nothing to do here.
+      }
+
+      // Get the clip rect.
+      const ossimIrect clip_rect = img_rect.clipToRect(src_rect);
+
+      // Check the status and allocate memory if needed.
+      if (getDataObjectStatus() == OSSIM_NULL) initialize();
+      
+      // Get the width of the buffers.
+      ossim_uint32 num_bands     = getNumberOfBands();
+      ossim_uint32 s_width       = src_rect.width();
+      ossim_uint32 d_width       = getWidth();
+            
+      ossim_uint32 band;
+      
+      ossim_uint32 sourceOffset = (clip_rect.ul().y - src_rect.ul().y) *
+         s_width + (clip_rect.ul().x - src_rect.ul().x);      
+      
+      ossim_uint32 destinationOffset = (clip_rect.ul().y - img_rect.ul().y) *
+         d_width + (clip_rect.ul().x - img_rect.ul().x);
+      
+      ossim_uint32 clipHeight = clip_rect.height();
+      ossim_uint32 clipWidth  = clip_rect.width();
+
+      // Copy the data.
+      for (band=0; band<num_bands; ++band)
+      {
+         ossim_uint32 sourceIndex      = sourceOffset;
+         ossim_uint32 destinationIndex = destinationOffset;
+         ossim_float32 tempResult      = 0.0;
+
+         for (ossim_uint32 line = 0; line < clipHeight; ++line)
+         {
+            for (ossim_uint32 sample = 0; sample < clipWidth; ++sample)
+            {
+               src->getNormalizedFloat(sourceIndex + sample,
+                                       band,
+                                       tempResult);
+               
+               this->setNormalizedFloat(destinationIndex + sample,
+                                        band,
+                                        tempResult);
+            }
+            sourceIndex      += s_width;
+            destinationIndex += d_width;
+         }
+      }
+   }
+}
+
+void ossimImageData::loadTile(const void* src,
+                              const ossimIrect& src_rect,
+                              ossimInterleaveType il_type)
+{
+   switch (il_type)
+   {
+   case OSSIM_BIP:
+      loadTileFromBip(src, src_rect);
+      return;
+   case OSSIM_BIL:
+      loadTileFromBil(src, src_rect);
+      return;
+   case OSSIM_BSQ:
+      loadTileFromBsq(src, src_rect);
+      return;
+   default:
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::loadTile ERROR:  unsupported interleave type!"
+         << std::endl;
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimImageData::loadTile\n\
+File %s line %d\nUnknown interleave type!",
+                    __FILE__,
+                    __LINE__);      
+      return;
+   } // End of "switch (type)"
+}
+
+void ossimImageData::loadTile(const void* src,
+                              const ossimIrect& src_rect,
+                              const ossimIrect& clip_rect,
+                              ossimInterleaveType il_type)
+{
+   switch (il_type)
+   {
+   case OSSIM_BIP:
+      loadTileFromBip(src, src_rect, clip_rect);
+      return;
+   case OSSIM_BIL:
+      loadTileFromBil(src, src_rect, clip_rect);
+      return;
+   case OSSIM_BSQ:
+      loadTileFromBsq(src, src_rect, clip_rect);
+      return;
+   default:
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::loadTile ERROR:  unsupported interleave type!"
+         << std::endl;
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimImageData::loadTile\n\
+File %s line %d\nUnknown interleave type!",
+                    __FILE__,
+                    __LINE__);      
+      return;
+   } // End of "switch (type)"
+}
+
+void ossimImageData::loadTileFromBip(const void* src,
+                                     const ossimIrect& src_rect)
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         loadTileFromBip(ossim_uint8(0), src, src_rect);
+         return;
+
+      case OSSIM_SINT8:
+         loadTileFromBip(ossim_sint8(0), src, src_rect);
+         return;
+         
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         loadTileFromBip(ossim_uint16(0), src, src_rect);
+         return;
+         
+      case OSSIM_SINT16:
+         loadTileFromBip(ossim_sint16(0), src, src_rect);
+         return;
+         
+      case OSSIM_UINT32:
+         loadTileFromBip(ossim_uint32(0), src, src_rect);
+         return;
+
+      case OSSIM_SINT32:
+         loadTileFromBip(ossim_sint32(0), src, src_rect);
+         return;
+         
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         loadTileFromBip(ossim_float32(0), src, src_rect);
+         return;
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         loadTileFromBip(ossim_float64(0), src, src_rect);
+         return;
+         
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::loadTileFromBip\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+void ossimImageData::loadTileFromBip(const void* src,
+                                     const ossimIrect& src_rect,
+                                     const ossimIrect& clip_rect)
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         loadTileFromBip(ossim_uint8(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT8:
+         loadTileFromBip(ossim_sint8(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         loadTileFromBip(ossim_uint16(0), src, src_rect, clip_rect);
+         return;
+      
+      case OSSIM_SINT16:
+         loadTileFromBip(ossim_sint16(0), src, src_rect, clip_rect);
+         return;
+      
+      case OSSIM_UINT32:
+         loadTileFromBip(ossim_uint32(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT32:
+         loadTileFromBip(ossim_sint32(0), src, src_rect, clip_rect);
+         return;
+      
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         loadTileFromBip(ossim_float32(0), src, src_rect, clip_rect);
+         return;
+      
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         loadTileFromBip(ossim_float64(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::loadTileFromBip\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+void ossimImageData::loadTileFromBil(const void* src,
+                                     const ossimIrect& src_rect)
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         loadTileFromBil(ossim_uint8(0), src, src_rect);
+         return;
+
+      case OSSIM_SINT8:
+         loadTileFromBil(ossim_sint8(0), src, src_rect);
+         return;
+
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         loadTileFromBil(ossim_uint16(0), src, src_rect);
+         return;
+      
+      case OSSIM_SINT16:
+         loadTileFromBil(ossim_sint16(0), src, src_rect);
+         return;
+      
+      case OSSIM_UINT32:
+         loadTileFromBil(ossim_uint32(0), src, src_rect);
+         return;
+
+      case OSSIM_SINT32:
+         loadTileFromBil(ossim_sint32(0), src, src_rect);
+         return;
+      
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         loadTileFromBil(ossim_float32(0), src, src_rect);
+         return;
+      
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         loadTileFromBil(ossim_float64(0), src, src_rect);
+         return;
+
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::loadTileFromBil\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+void ossimImageData::loadTileFromBil(const void* src,
+                                     const ossimIrect& src_rect,
+                                     const ossimIrect& clip_rect)
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         loadTileFromBil(ossim_uint8(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT8:
+         loadTileFromBil(ossim_sint8(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         loadTileFromBil(ossim_uint16(0), src, src_rect, clip_rect);
+         return;
+      
+      case OSSIM_SINT16:
+         loadTileFromBil(ossim_sint16(0), src, src_rect, clip_rect);
+         return;
+      
+      case OSSIM_UINT32:
+         loadTileFromBil(ossim_uint32(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT32:
+         loadTileFromBil(ossim_sint32(0), src, src_rect, clip_rect);
+         return;
+      
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         loadTileFromBil(ossim_float32(0), src, src_rect, clip_rect);
+         return;
+      
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         loadTileFromBil(ossim_float64(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::loadTileFromBil\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+void ossimImageData::loadTileFromBsq(const void* src,
+                                     const ossimIrect& src_rect)
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         loadTileFromBsq(ossim_uint8(0), src, src_rect);
+         return;
+
+      case OSSIM_SINT8:
+         loadTileFromBsq(ossim_sint8(0), src, src_rect);
+         return;
+
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         loadTileFromBsq(ossim_uint16(0), src, src_rect);
+         return;
+      
+      case OSSIM_SINT16:
+         loadTileFromBsq(ossim_sint16(0), src, src_rect);
+         return;
+      
+      case OSSIM_UINT32:
+         loadTileFromBsq(ossim_uint32(0), src, src_rect);
+         return;
+
+      case OSSIM_SINT32:
+         loadTileFromBsq(ossim_sint32(0), src, src_rect);
+         return;
+      
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         loadTileFromBsq(ossim_float32(0), src, src_rect);
+         return;
+      
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         loadTileFromBsq(ossim_float64(0), src, src_rect);
+         return;
+      
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::loadTileFromBsq\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+void ossimImageData::loadTileFromBsq(const void* src,
+                                     const ossimIrect& src_rect,
+                                     const ossimIrect& clip_rect)
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         loadTileFromBsq(ossim_uint8(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT8:
+         loadTileFromBsq(ossim_sint8(0), src, src_rect, clip_rect);
+         return;
+         
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         loadTileFromBsq(ossim_uint16(0), src, src_rect, clip_rect);
+         return;
+         
+      case OSSIM_SINT16:
+         loadTileFromBsq(ossim_sint16(0), src, src_rect, clip_rect);
+         return;
+         
+      case OSSIM_UINT32:
+         loadTileFromBsq(ossim_uint32(0), src, src_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT32:
+         loadTileFromBsq(ossim_sint32(0), src, src_rect, clip_rect);
+         return;
+      
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         loadTileFromBsq(ossim_float32(0), src, src_rect, clip_rect);
+         return;
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         loadTileFromBsq(ossim_float64(0), src, src_rect, clip_rect);
+         return;
+         
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::loadTileFromBsq\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+
+void ossimImageData::computeMinMaxPix(vector<ossim_float64>& minBands,
+                                      vector<ossim_float64>& maxBands)
+{
+   if ( (getDataObjectStatus() == OSSIM_NULL) || 
+        (getDataObjectStatus() == OSSIM_EMPTY) )
+   {
+      return;
+   }
+
+   switch(theScalarType)
+   {
+      case OSSIM_UINT8:
+      {
+         computeMinMaxPix((ossim_uint8)0,
+                          minBands,
+                          maxBands);
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         computeMinMaxPix((ossim_sint8)0,
+                          minBands,
+                          maxBands);
+         break;
+         
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         computeMinMaxPix((ossim_uint16)0,
+                          minBands,
+                          maxBands);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         computeMinMaxPix((ossim_sint16)0,
+                          minBands,
+                          maxBands);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         computeMinMaxPix((ossim_uint32)0,
+                          minBands,
+                          maxBands);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         computeMinMaxPix((ossim_sint32)0,
+                          minBands,
+                          maxBands);
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+      {
+         computeMinMaxPix((ossim_float32)0.0,
+                          minBands,
+                          maxBands);
+         break;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+      {
+         computeMinMaxPix((ossim_float64)0.0,
+                          minBands,
+                          maxBands);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         // Shouldn't hit this.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::computeMinPix Unsupported scalar type!"
+            << std::endl;
+         break;
+      }
+   }
+}
+
+template <class T>
+void ossimImageData::computeMinMaxPix(T dummyValue,
+                                      vector<ossim_float64>& minBands,
+                                      vector<ossim_float64>& maxBands)
+{
+   const ossim_uint32 BANDS = getNumberOfBands();
+   const ossim_uint32 SPB   = getSizePerBand(); 
+   
+   if( minBands.size() != BANDS ||
+       maxBands.size() != BANDS )
+   {
+      minBands.resize(BANDS);
+      maxBands.resize(BANDS);
+      for (ossim_uint32 band = 0; band < BANDS; ++band)
+      {
+         // Set min to max and max to min for starters.
+         minBands[band] = getMaxPix(band);
+         maxBands[band] = getMinPix(band);
+      }
+   }
+   
+   for(ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      const T* bandBuffer = (const T*)getBuf(band);
+      if(bandBuffer)
+      {
+         const T NP   = static_cast<T>(getNullPix(band));
+         ossim_float64 currentMin = minBands[band];
+         ossim_float64 currentMax = maxBands[band];
+         for(ossim_uint32 offset = 0; offset < SPB; ++offset)
+         {
+            T p = bandBuffer[offset];
+            if(p != NP)
+            {
+               if(p < currentMin)
+               {
+                  currentMin = p;
+               }
+               else if(p > currentMax)
+               {
+                  currentMax = p;
+               }
+            }
+         }
+         minBands[band] = currentMin;
+         maxBands[band] = currentMax;
+      }
+   }
+}
+
+template <class T>
+void ossimImageData::loadTileFromBip(T, // dummy template variable
+                                     const void* src,
+                                     const ossimIrect& src_rect)
+{
+   const ossimIrect img_rect = getImageRectangle();
+   
+   // Get the clip rect.
+   const ossimIrect clip_rect = img_rect.clipToRect(src_rect);
+
+   loadTileFromBip(T(0), src, src_rect, clip_rect);
+}
+
+template <class T>
+void ossimImageData::loadTileFromBip(T, // dummy template variable
+                                     const void* src,
+                                     const ossimIrect& src_rect,
+                                     const ossimIrect& clip_rect)
+{
+   static const char  MODULE[] = "ossimImageData::loadTileFromBip";
+   
+   // Check the pointer.
+   if (!src)
+   {
+      // Set the error...
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "%s File %s line %d\nNULL pointer passed to method!",
+                    MODULE,
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   const ossimIrect img_rect = getImageRectangle();
+   
+   // Check for intersect.
+   if ( ! img_rect.intersects(src_rect) )
+   {
+      return; // Nothing to do here.
+   }
+   
+   // Check the clip rect.
+   if (!clip_rect.completely_within(img_rect))
+   {
+//       cerr << MODULE
+//            << " ERROR: clip rect does not fall within tile rect!"
+//            << std::endl;
+      return;
+   }
+   
+   // Check the status and allocate memory if needed.
+   if (getDataObjectStatus() == OSSIM_NULL) initialize();
+
+   // Get the width of the buffers.
+   ossim_uint32 num_bands  = getNumberOfBands();
+   ossim_uint32 s_width    = (src_rect.width()) * num_bands;
+   ossim_uint32 d_width    = getWidth();
+   ossim_uint32 band       = 0;
+   const T* s        = static_cast<const T*>(src);
+   T** d             = new T*[num_bands];
+   
+   // Make destination pointers to each one.
+   for (band=0; band<num_bands; band++)
+   {
+      d[band] = static_cast<T*>(getBuf(band));
+      
+      // Move the pointers to the first valid pixel.
+      d[band] += (clip_rect.ul().y - img_rect.ul().y) * d_width +
+                 clip_rect.ul().x - img_rect.ul().x;
+   }
+   
+   // Move the source pointer to the first valid pixel.
+   s += (clip_rect.ul().y - src_rect.ul().y) * s_width +
+        (clip_rect.ul().x - src_rect.ul().x) * num_bands;
+   
+   // Copy the data.
+   ossim_uint32 clipHeight = clip_rect.height();
+   ossim_uint32 clipWidth  = clip_rect.width();
+   
+   for (ossim_uint32 line = 0; line < clipHeight; ++line)
+   {
+      ossim_uint32 j = 0;
+      for (ossim_uint32 sample = 0; sample < clipWidth; ++sample)
+      {
+         for (band=0; band<num_bands; band++)
+         {
+            d[band][sample] = s[j+band];
+         }
+         j += num_bands;
+      }
+      
+      s += s_width;
+      for (band=0; band<num_bands; band++)
+      {
+         d[band] += d_width;
+      }
+   }
+   
+   delete [] d;
+}
+   
+template <class T>
+void ossimImageData::loadTileFromBil(T, // dummy template variable
+                                     const void* src,
+                                     const ossimIrect& src_rect)
+{
+   const ossimIrect img_rect = getImageRectangle();
+   
+   // Get the clip rect.
+   const ossimIrect clip_rect = img_rect.clipToRect(src_rect);
+
+   loadTileFromBil(T(0), src, src_rect, clip_rect);
+}
+   
+template <class T>
+void ossimImageData::loadTileFromBil(T, // dummy template variable
+                                     const void* src,
+                                     const ossimIrect& src_rect,
+                                     const ossimIrect& clip_rect)
+{
+   static const char  MODULE[] = "ossimImageData::loadTileFromBil";
+   
+   // Check the pointer.
+   if (!src)
+   {
+      // Set the error...
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "%s File %s line %d\nNULL pointer passed to method!",
+                    MODULE,
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   const ossimIrect img_rect = getImageRectangle();
+   
+   // Check for intersect.
+   if ( ! img_rect.intersects(src_rect) )
+   {
+      return; // Nothing to do here.
+   }
+   
+   // Check the clip rect.
+   if (!clip_rect.completely_within(img_rect))
+   {
+//       cerr << MODULE
+//            << " ERROR: clip rect does not fall within tile rect!"
+//            << std::endl;
+      return;
+   }
+
+   // Check the status and allocate memory if needed.
+   if (getDataObjectStatus() == OSSIM_NULL) initialize();
+   
+   // Get the width of the buffers.
+   ossim_uint32 num_bands = getNumberOfBands();
+   ossim_uint32 s_width = (src_rect.lr().x - src_rect.ul().x + 1);
+   ossim_uint32 d_width = getWidth();
+   ossim_uint32 band = 0;
+   ossim_uint32 d_offset = (clip_rect.ul().y - img_rect.ul().y) * d_width +
+                     clip_rect.ul().x - img_rect.ul().x;
+   
+   const T* s = static_cast<const T*>(src);
+
+   // Get the number of bands and make destination pointers to each one.
+   T** d = new T*[num_bands];
+   
+   for (band=0; band<num_bands; band++)
+   {
+      d[band] = static_cast<T*>(getBuf(band));
+      
+      // Move the pointers to the first valid pixel.
+      d[band] += d_offset;
+   }
+   
+   // Move the source pointer to the first valid pixel.
+   s += (clip_rect.ul().y - src_rect.ul().y) * s_width * num_bands +
+        clip_rect.ul().x - src_rect.ul().x;
+   
+   // Copy the data.
+   ossim_uint32 clipHeight = clip_rect.height();
+   ossim_uint32 clipWidth  = clip_rect.width();
+
+   for (ossim_uint32 line = 0; line < clipHeight; ++line)
+   {
+      for (band = 0; band < num_bands; ++band)
+      {
+         for (ossim_uint32 sample = 0; sample < clipWidth; ++sample)
+         {
+            d[band][sample] = s[sample];
+         }
+         s       += s_width;
+         d[band] += d_width;
+      }
+   }
+
+   delete [] d;
+}
+   
+template <class T>
+void ossimImageData::loadTileFromBsq(T, // dummy template variable
+                                     const void* src,
+                                     const ossimIrect& src_rect)
+{
+   const ossimIrect img_rect = getImageRectangle();
+   
+   // Get the clip rect.
+   const ossimIrect clip_rect = img_rect.clipToRect(src_rect);
+
+   loadTileFromBsq(T(0), src, src_rect, clip_rect);
+}
+
+template <class T>
+void ossimImageData::loadTileFromBsq(T, // dummy template variable
+                                     const void* src,
+                                     const ossimIrect& src_rect,
+                                     const ossimIrect& clip_rect)
+{
+   static const char  MODULE[] = "ossimImageData::loadTileFromBsq";
+   
+   // Check the pointer.
+   if (!src)
+   {
+      // Set the error...
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "%s File %s line %d\nNULL pointer passed to method!",
+                    MODULE,
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   const ossimIrect img_rect = getImageRectangle();
+   
+   // Check for intersect.
+   if ( ! img_rect.intersects(src_rect) )
+   {
+      return; // Nothing to do here.
+   }
+
+   // Check the clip rect.
+   if (!clip_rect.completely_within(img_rect))
+   {
+//       cerr << MODULE
+//            << " ERROR: clip rect does not fall within tile rect!"
+//            << std::endl;
+      return;
+   }
+   
+   // Check the status and allocate memory if needed.
+   if (getDataObjectStatus() == OSSIM_NULL) initialize();
+   
+   // Get the width of the buffers.
+   ossim_uint32 num_bands = getNumberOfBands();
+   ossim_uint32 s_width = src_rect.width();
+   ossim_uint32 d_width = getWidth();
+   ossim_uint32 s_band_offset = s_width * src_rect.height();
+   
+   const T* s = static_cast<const T*>(src);
+   
+   ossim_uint32 band;
+   ossim_uint32 destinationOffset = (clip_rect.ul().y - img_rect.ul().y) * d_width +
+                              (clip_rect.ul().x - img_rect.ul().x);
+   ossim_uint32 destinationIndex = destinationOffset;
+   ossim_uint32 sourceOffset = (clip_rect.ul().y - src_rect.ul().y) * s_width +
+                         (clip_rect.ul().x - src_rect.ul().x);
+   ossim_uint32 sourceIndex = sourceOffset;
+   ossim_uint32 clipHeight = clip_rect.height();
+   ossim_uint32 clipWidth = clip_rect.width();
+
+   // Copy the data.
+   for (band=0; band<num_bands; band++)
+   {
+      T* destinationBand = static_cast<T*>(getBuf(band));
+      destinationIndex = destinationOffset;
+      sourceIndex = sourceOffset + s_band_offset*band;
+      
+      for (ossim_uint32 line = 0; line < clipHeight; ++line)
+      {
+         for (ossim_uint32 sample = 0; sample < clipWidth; ++sample)
+         {
+            destinationBand[destinationIndex + sample]
+               = s[sourceIndex+sample];
+         }
+         sourceIndex += s_width;
+         destinationIndex += d_width;
+      }
+   }
+}
+
+void ossimImageData::loadTileFrom1Band(const void* src,
+				       const ossimIrect& src_rect)
+{
+   ossim_uint32 bands = getNumberOfBands();
+   for(ossim_uint32 band = 0; band < bands; ++band)
+   {
+      loadBand(src, src_rect, band);
+   }
+}
+
+void ossimImageData::loadTileFrom1Band(const ossimImageData* src)
+{
+  if(!src) return;
+  loadTileFrom1Band((const void*)src->getBuf(),
+		    src->getImageRectangle());
+}
+
+void ossimImageData::loadShortBand(const void* src,
+                                   const ossimIrect& src_rect,
+                                   ossim_uint32 band,
+                                   bool swap_bytes)
+{
+   static const char  MODULE[] = "ossimImageData::loadShortBand";
+
+   // Check the pointer.
+   if (!src)
+   {
+      // Set the error...
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "%s File %s line %d\nNULL pointer passed to method!",
+                    MODULE,
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+
+   // Check the band.
+   if (!isValidBand(band))
+   {
+      // Set the error...
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "%s File %s line %d\nInvalid band:  %d",
+                    MODULE,
+                    __FILE__,
+                    __LINE__,
+                    band);
+      return;
+   }
+
+   const ossimIrect img_rect = getImageRectangle();
+   
+   // Check for intersect.
+   if ( ! img_rect.intersects(src_rect) )
+   {
+      return; // Nothing to do here.
+   }
+
+   // Get the clip rect.
+   const ossimIrect clip_rect = img_rect.clipToRect(src_rect);
+
+   // Check the status and allocate memory if needed.
+   if (getDataObjectStatus() == OSSIM_NULL) initialize();
+
+   // Get the width of the buffers.
+   ossim_uint32 s_width = src_rect.width();
+   ossim_uint32 d_width = getWidth();
+
+   const ossim_uint16* s = static_cast<const ossim_uint16*>(src);
+   ossim_uint16* d = getUshortBuf(band);
+
+   // Move the pointers to the first valid pixel.
+   s += (clip_rect.ul().y - src_rect.ul().y) * s_width +
+        clip_rect.ul().x - src_rect.ul().x;
+   
+   d += (clip_rect.ul().y - img_rect.ul().y) * d_width +
+        clip_rect.ul().x - img_rect.ul().x;
+   
+   // Copy the data.
+   for (ossim_int32 line=clip_rect.ul().y; line<=clip_rect.lr().y; line++)
+   {
+      ossim_uint32 i = 0;
+      for (ossim_int32 sample=clip_rect.ul().x; sample<=clip_rect.lr().x; sample++)
+      {
+         d[i] = (swap_bytes ? ( (s[i] << 8) | (s[i] >> 8) ) :
+                 s[i]);
+         ++i;
+      }
+
+      s += s_width;
+      d += d_width;
+   }
+
+   validate();
+}
+
+bool ossimImageData::isPointWithin(const ossimIpt& point)const
+{
+   return ((point.x >= theOrigin.x)&&
+           (point.y >= theOrigin.y)&&
+           ((point.x - theOrigin.x)<static_cast<long>(theSpatialExtents[0]))&&
+           ((point.y - theOrigin.y)<static_cast<long>(theSpatialExtents[1])));
+}
+
+bool ossimImageData::isPointWithin(ossim_int32 x, ossim_int32 y)const
+{
+   return ((x >= theOrigin.x)&&
+           (y >= theOrigin.y)&&
+           ((x - theOrigin.x) < static_cast<long>(theSpatialExtents[0]))&&
+           ((y - theOrigin.y) < static_cast<long>(theSpatialExtents[1])));
+}
+
+void ossimImageData::unloadTile(void* dest,
+                                const ossimIrect& dest_rect,
+                                ossimInterleaveType type) const
+{
+   unloadTile(dest, dest_rect, getImageRectangle(), type);
+}
+
+void ossimImageData::unloadTile(void* dest,
+                                const ossimIrect& dest_rect,
+                                const ossimIrect& clip_rect,
+                                ossimInterleaveType type) const
+{
+   switch (type)
+   {
+      case OSSIM_BIP:
+         unloadTileToBip(dest, dest_rect, clip_rect);
+         return;
+      case OSSIM_BIL:
+         unloadTileToBil(dest, dest_rect, clip_rect);
+         return;
+      case OSSIM_BSQ:
+         unloadTileToBsq(dest, dest_rect, clip_rect);
+         return;
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::unloadTile\n\
+File %s line %d\nUnknown scalar type!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   } // End of "switch (getScalarType())"
+}
+
+void ossimImageData::unloadTileToBip(void* dest,
+                                     const ossimIrect& dest_rect,
+                                     const ossimIrect& clip_rect) const
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         unloadTileToBip(ossim_uint8(0), dest, dest_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT8:
+         unloadTileToBip(ossim_sint8(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         unloadTileToBip(ossim_uint16(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_SINT16:
+         unloadTileToBip(ossim_sint16(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_UINT32:
+         unloadTileToBip(ossim_uint32(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_SINT32:
+         unloadTileToBip(ossim_sint32(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         unloadTileToBip(ossim_float32(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         unloadTileToBip(ossim_float64(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::unloadTileToBip\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+void ossimImageData::unloadTileToBil(void* dest,
+                                     const ossimIrect& dest_rect,
+                                     const ossimIrect& clip_rect) const
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         unloadTileToBil(ossim_uint8(0), dest, dest_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT8:
+         unloadTileToBil(ossim_sint8(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         unloadTileToBil(ossim_uint16(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_SINT16:
+         unloadTileToBil(ossim_sint16(0), dest, dest_rect, clip_rect);
+         return;
+
+      case OSSIM_UINT32:
+         unloadTileToBil(ossim_uint32(0), dest, dest_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT32:
+         unloadTileToBil(ossim_sint32(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         unloadTileToBil(ossim_float32(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         unloadTileToBil(ossim_float64(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::unloadTileToBil\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+void ossimImageData::unloadTileToBsq(void* dest,
+                                     const ossimIrect& dest_rect,
+                                     const ossimIrect& clip_rect) const
+{
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         unloadTileToBsq(ossim_uint8(0), dest, dest_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT8:
+         unloadTileToBsq(ossim_sint8(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         unloadTileToBsq(ossim_uint16(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_SINT16:
+         unloadTileToBsq(ossim_sint16(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_UINT32:
+         unloadTileToBsq(ossim_uint32(0), dest, dest_rect, clip_rect);
+         return;
+
+      case OSSIM_SINT32:
+         unloadTileToBsq(ossim_sint32(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         unloadTileToBsq(ossim_float32(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         unloadTileToBsq(ossim_float64(0), dest, dest_rect, clip_rect);
+         return;
+         
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::unloadTileToBsq\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+void ossimImageData::unloadBand(void* dest,
+                                const ossimIrect& dest_rect,
+                                ossim_uint32 band) const
+{
+   unloadBand(dest, dest_rect, getImageRectangle(), band);
+}
+
+void ossimImageData::unloadBand(void* dest,
+                                const ossimIrect& dest_rect,
+                                const ossimIrect& clip_rect,
+                                ossim_uint32 band) const
+{
+   // Call the appropriate load method.
+   switch (getScalarType())
+   {
+      case OSSIM_UINT8:
+         unloadBand(ossim_uint8(0), dest, dest_rect, clip_rect, band);
+         return;
+
+      case OSSIM_SINT8:
+         unloadBand(ossim_sint8(0), dest, dest_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+         unloadBand(ossim_uint16(0), dest, dest_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_SINT16:
+         unloadBand(ossim_sint16(0), dest, dest_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_UINT32:
+         unloadBand(ossim_uint32(0), dest, dest_rect, clip_rect, band);
+         return;
+
+      case OSSIM_SINT32:
+         unloadBand(ossim_sint32(0), dest, dest_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT32:
+         unloadBand(ossim_float32(0), dest, dest_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_FLOAT64:
+         unloadBand(ossim_float64(0), dest, dest_rect, clip_rect, band);
+         return;
+         
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         ossimSetError(getClassName(),
+                       ossimErrorCodes::OSSIM_ERROR,
+                       "ossimImageData::unloadBand\n\
+File %s line %d\nUnsupported scalar type for method!",
+                       __FILE__,
+                       __LINE__);      
+         return;
+   }
+}
+
+template <class T>
+void ossimImageData::unloadBand(T, // dummy tmeplate variable
+                                void* dest,
+                                const ossimIrect& dest_rect,
+                                const ossimIrect& clip_rect,
+                                ossim_uint32 band) const
+{
+   static const char  MODULE[] = "ossimImageData::unloadBand";
+
+   // Check the pointers.
+   if (!dest)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "\nNULL pointer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "\nThis object is null! Returning..." << std::endl;
+      return;
+   }
+   
+   ossimIrect img_rect = getImageRectangle();
+   
+   // Clip the clip_rect to the tile rect.
+   ossimIrect output_clip_rect = clip_rect.clipToRect(img_rect);
+
+   // Clip it again to the destination rect.
+   output_clip_rect = dest_rect.clipToRect(output_clip_rect);
+   
+   // Check the output clip rect for intersection.
+   if (!output_clip_rect.intersects(img_rect))
+   {
+      return;
+   }
+   if ( !(output_clip_rect.intersects(dest_rect)) )
+   {
+      return;
+   }
+
+   // Check for valid band.
+   if (!isValidBand(band))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " NOTICE:"
+         << "\nInvalid band:  " << band << "  Returning..."
+         << std::endl;
+      return;
+   }
+   
+   ossim_uint32 num_bands = getNumberOfBands();
+
+   ossim_uint32 buf_width = dest_rect.lr().x - dest_rect.ul().x + 1;
+
+   // Get a pointer to the source band buffer.
+   const T* s = reinterpret_cast<const T*>(getBuf(band));
+
+   // Get the offset for each source band.
+   ossim_uint32 src_offset = (output_clip_rect.ul().y - img_rect.ul().y) *
+      getWidth() + output_clip_rect.ul().x - img_rect.ul().x;
+   
+   // Move the pointers to the start.
+   T* d = reinterpret_cast<T*>(dest);
+   
+   d += (output_clip_rect.ul().y - dest_rect.ul().y) * buf_width * num_bands +
+      output_clip_rect.ul().x - dest_rect.ul().x;
+   
+   s += src_offset;
+   
+   for (ossim_int32 line=output_clip_rect.ul().y;
+        line<=output_clip_rect.lr().y; ++line)
+   {
+      ossim_uint32 i=0;
+      for (ossim_int32 samp=clip_rect.ul().x;
+           samp<=output_clip_rect.lr().x; ++samp)
+      {
+         d[i] = s[i];
+         ++i;
+      }
+      d += buf_width;
+      s += getWidth();
+   }
+}
+
+template <class T> void
+ossimImageData::unloadTileToBip(T, // dummy template variable
+                                void* dest,
+                                const ossimIrect& dest_rect,
+                                const ossimIrect& clip_rect) const
+{
+   static const char  MODULE[] = "ossimImageData::unloadTileToBip";
+   
+   // Check the pointer.
+   if (!dest)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "\nNULL pointer passed to method!  Returning..." << std::endl;
+      return;
+   }
+   
+   bool  dataIsNull = false;
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      dataIsNull = true;
+   }
+   
+   ossimIrect img_rect = getImageRectangle();
+   
+   // Clip the clip_rect to the tile rect.
+   ossimIrect output_clip_rect = clip_rect.clipToRect(img_rect);
+
+   // Clip it again to the destination rect.
+   output_clip_rect = dest_rect.clipToRect(output_clip_rect);
+   
+   // Check the output clip rect for intersection.
+   if (output_clip_rect.hasNans())
+   {
+      return;
+   }
+   if ( !(output_clip_rect.intersects(dest_rect)) )
+   {
+      return;
+   }
+   
+   ossim_int32 num_bands = getNumberOfBands();
+   
+   ossim_int32 buf_width = dest_rect.width() * num_bands;
+
+   if(!dataIsNull)
+   {
+      // Get the number of bands and grab a pointers to each one.
+      const T** s = new const T*[num_bands];
+      
+      ossim_int32 band;
+      ossim_int32 s_width = getWidth();
+      
+      for (band=0; band<num_bands; band++)
+      {
+         s[band] = reinterpret_cast<const T*>(getBuf(band));
+      }
+      
+      // Move the pointers to the start.
+      T* d = reinterpret_cast<T*>(dest);      
+      
+      d += (output_clip_rect.ul().y - dest_rect.ul().y) * buf_width +
+           (output_clip_rect.ul().x - dest_rect.ul().x) * num_bands;
+      
+      // Get the offset for each source band.
+      ossim_int32 src_offset = (output_clip_rect.ul().y - img_rect.ul().y) *
+         s_width + (output_clip_rect.ul().x - img_rect.ul().x);
+      
+      ossim_int32 output_clip_width  = output_clip_rect.width();
+      ossim_int32 output_clip_height = output_clip_rect.height();
+      
+      for (band=0; band<(ossim_int32)getNumberOfBands(); band++)
+      {
+         s[band] += src_offset;
+      }
+      
+      ossim_int32 j;
+      for (ossim_int32 line=0; line<output_clip_height; ++line)
+      {
+         j = 0;
+         for (ossim_int32 samp=0; samp<output_clip_width; ++samp, j+=num_bands)
+         {
+            for (band=0; band<num_bands; ++band)
+            {
+               d[j+band] = s[band][samp];
+            }
+         }
+         
+         // increment to next line...
+         d += buf_width;
+         for (band=0; band<num_bands; ++band)
+         {
+            s[band] += s_width;
+         }
+      
+      }
+      delete [] s;
+   }
+   else
+   {
+      ossim_int32 band = 0;
+      T* nulls = new T[num_bands];
+      for(band = 0; band < num_bands; ++band)
+      {
+         nulls[band] = static_cast<T>(theNullPixelValue[band]);
+      }
+      // Move the pointers to the start.
+      T* d = reinterpret_cast<T*>(dest);
+      
+      d += (output_clip_rect.ul().y - dest_rect.ul().y) * buf_width +
+           (output_clip_rect.ul().x - dest_rect.ul().x) * num_bands;
+
+      for (ossim_int32 line=output_clip_rect.ul().y;
+           line<=output_clip_rect.lr().y; ++line)
+      {
+         ossim_int32 i=0;
+         ossim_int32 j=0;
+         for (ossim_int32 samp=output_clip_rect.ul().x;
+              samp<=output_clip_rect.lr().x; ++samp)
+         {
+            for (band=0; band<num_bands; ++band)
+            {
+               d[j+band] = nulls[band];
+            }
+            ++i;  // increment to next pixel...
+            j+= num_bands;
+         }
+         
+         // increment to next line...
+         d += buf_width;
+      }
+      delete [] nulls;
+      nulls = NULL;;
+   }
+}
+
+template <class T> void
+ossimImageData::unloadTileToBil(T,  // dummy template arg...
+                                void* dest,
+                                const ossimIrect& dest_rect,
+                                const ossimIrect& clip_rect) const
+{
+  static const char  MODULE[] = "ossimImageData::unloadTileToBil";
+
+   // Check the pointers.
+   if (!dest)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "\nNULL pointer passed to method!  Returning..." << std::endl;
+      return;
+   }
+   bool dataIsNull = false;
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      dataIsNull = true;
+   }
+
+   ossimIrect img_rect = getImageRectangle();
+   
+   // Clip the clip_rect to the tile rect.
+   ossimIrect output_clip_rect = clip_rect.clipToRect(img_rect);
+
+   // Clip it again to the destination rect.
+   output_clip_rect = dest_rect.clipToRect(output_clip_rect);
+   
+   // Check the output clip rect for intersection.
+   if (output_clip_rect.hasNans())
+   {
+      return;
+   }
+   if ( !(output_clip_rect.intersects(dest_rect)) )
+   {
+      return;
+   }
+
+   ossim_uint32 num_bands = getNumberOfBands();
+
+   ossim_uint32 buf_width = dest_rect.width();
+
+   if(!dataIsNull)
+   {
+      // Get the number of bands and grab a pointers to each one.
+      const T** s = new const T*[num_bands];
+      
+      ossim_uint32 band;
+      
+      for (band=0; band<num_bands; band++)
+      {
+         s[band] = reinterpret_cast<const T*>(getBuf(band));
+      }
+      
+      // Get the offset for each source band.
+      ossim_uint32 src_offset = (output_clip_rect.ul().y - img_rect.ul().y) *
+         getWidth() + (output_clip_rect.ul().x - img_rect.ul().x);
+      
+      // Move the pointers to the start.
+      T* d = reinterpret_cast<T*>(dest);
+
+      d += (output_clip_rect.ul().y - dest_rect.ul().y) *
+         buf_width * num_bands +
+         (output_clip_rect.ul().x-dest_rect.ul().x);
+      
+      for (band=0; band<num_bands; ++band)
+      {
+         s[band] += src_offset;
+      }
+      
+      for (ossim_int32 line=output_clip_rect.ul().y;
+           line<=output_clip_rect.lr().y; ++line)
+      {
+         for (band=0; band<num_bands; ++band)
+         {
+            ossim_uint32 i=0;
+            for (ossim_int32 samp=output_clip_rect.ul().x;
+                 samp<=output_clip_rect.lr().x; ++samp)
+            {
+               d[i] = s[band][i];
+               ++i;
+            }
+            d       += buf_width;
+            s[band] += getWidth();
+         }
+      }
+      // Free up memory allocated for pointers.
+      delete [] s;
+   }
+   else
+   {
+      ossim_uint32 band = 0;
+      T* nulls = new T[num_bands];
+      for(band = 0; band < num_bands; ++band)
+      {
+         nulls[band] = static_cast<T>(theNullPixelValue[band]);
+      }
+      
+      // Move the pointers to the start.
+      T* d = reinterpret_cast<T*>(dest);
+
+      d += (output_clip_rect.ul().y - dest_rect.ul().y) *
+           buf_width * num_bands + (output_clip_rect.ul().x - dest_rect.ul().x);
+      
+      for (ossim_int32 line=output_clip_rect.ul().y;
+           line<=output_clip_rect.lr().y; ++line)
+      {
+         for (band=0; band<num_bands; ++band)
+         {
+            ossim_uint32 i=0;
+            for (ossim_int32 samp=output_clip_rect.ul().x;
+                 samp<=output_clip_rect.lr().x; ++samp)
+            {
+               d[i] = nulls[band];
+               ++i;
+            }
+            d += buf_width;
+         }
+      }
+   }
+}
+
+template <class T> void
+ossimImageData::unloadTileToBsq(T,  // dummy template arg...
+                                void* dest,
+                                const ossimIrect& dest_rect,
+                                const ossimIrect& clip_rect) const
+{
+   static const char  MODULE[] = "ossimImageData::unloadTileToBsq";
+   
+   // Check the pointers.
+   if (!dest)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "\nNULL pointer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   bool dataIsNull = false;
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      dataIsNull = true;
+   }
+
+   ossimIrect img_rect = getImageRectangle();
+   
+   // Clip the clip_rect to the tile rect.
+   ossimIrect output_clip_rect = clip_rect.clipToRect(img_rect);
+
+   // Clip it again to the destination rect.
+   output_clip_rect = dest_rect.clipToRect(output_clip_rect);
+   
+   // Check the output clip rect for intersection.
+   if (output_clip_rect.hasNans())
+   {
+      return;
+   }
+   if ( !(output_clip_rect.intersects(dest_rect)) )
+   {
+      return;
+   }
+
+   ossim_uint32 num_bands     = getNumberOfBands();
+   ossim_uint32 band          = 0;
+   if(!dataIsNull)
+   {
+      ossim_uint32 num_bands     = getNumberOfBands();
+      ossim_uint32 d_width       = dest_rect.lr().x - dest_rect.ul().x + 1;
+      ossim_uint32 d_band_offset = d_width * (dest_rect.lr().y-dest_rect.ul().y+1);
+      ossim_uint32 s_width       = getWidth();
+      ossim_uint32 s_offset      = (output_clip_rect.ul().y - img_rect.ul().y) *
+                             s_width + (output_clip_rect.ul().x - img_rect.ul().x);
+      
+      T* d        = static_cast<T*>(dest);
+      const T** s = new const T*[num_bands];
+      
+      // Grab a pointers to each one.
+      for (band=0; band<num_bands; ++band)
+      {
+         s[band] = reinterpret_cast<const T*>(getBuf(band));
+         
+         // Move to first valid pixel.
+         s[band] += s_offset;
+      }
+      
+      // Move to first valid pixel.
+      d += (output_clip_rect.ul().y - dest_rect.ul().y) * d_width +
+           (output_clip_rect.ul().x - dest_rect.ul().x);
+      
+      for (band=0; band<num_bands; ++band)
+      {
+         ossim_uint32 d_buf_offset = 0;
+         
+         for (ossim_int32 line=output_clip_rect.ul().y;
+              line<=output_clip_rect.lr().y; ++line)
+         {
+            ossim_int32 i=0;
+            for (ossim_int32 samp=output_clip_rect.ul().x;
+                 samp<=output_clip_rect.lr().x; ++samp)
+            {
+               d[d_buf_offset+i] = s[band][i];
+               ++i;
+            }
+         
+            d_buf_offset += d_width;
+            s[band]      += s_width;
+         }
+         d += d_band_offset;
+      }
+      
+      // Free up memory allocated for pointers.
+      delete [] s;
+   }
+   else
+   {
+      ossim_uint32 d_width       = dest_rect.lr().x - dest_rect.ul().x + 1;
+      ossim_uint32 d_band_offset = d_width * (dest_rect.lr().y-dest_rect.ul().y+1);
+      
+      ossim_uint8* d = static_cast<ossim_uint8*>(dest);
+            
+      // Move to first valid pixel.
+      d += (output_clip_rect.ul().y - dest_rect.ul().y) * d_width +
+           (output_clip_rect.ul().x - dest_rect.ul().x);
+      
+      for (band=0; band<num_bands; ++band)
+      {
+         ossim_uint8 np = static_cast<ossim_uint8>(theNullPixelValue[band]);
+         ossim_uint32 d_buf_offset = 0;
+         
+         for (ossim_int32 line=output_clip_rect.ul().y;
+              line<=output_clip_rect.lr().y; ++line)
+         {
+            ossim_int32 i=0;
+            for (ossim_int32 samp=output_clip_rect.ul().x;
+                 samp<=output_clip_rect.lr().x; ++samp)
+            {
+               d[d_buf_offset+i] = np;
+               ++i;
+            }
+            
+            d_buf_offset += d_width;
+         }
+         d += d_band_offset;
+      }
+   }
+}
+
+ossimObject* ossimImageData::dup() const
+{
+   return new ossimImageData(*this);
+}
+
+void ossimImageData::copyTileToNormalizedBuffer(ossim_float64* buf)const
+{
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyTileToNormalizedBuffer ERROR:"
+         << "\nNull buffer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyTileToNormalizedBuffer ERROR:"
+         << "\nThis object is null! Returning..." << std::endl;
+      return;
+   }
+   
+   switch(getScalarType())
+   {
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         memmove(buf, getBuf(), getDataSizeInBytes());
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         ossim_uint32 upperBound = getWidth()*getHeight()*getNumberOfBands();
+         const ossim_float32* inputBuf = static_cast<const ossim_float32*>(getBuf());
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            buf[offset] = inputBuf[offset];
+         }
+         break;
+      }
+      case OSSIM_FLOAT32:
+      {
+         copyTileToNormalizedBuffer((ossim_float32)0, buf);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      {
+         copyTileToNormalizedBuffer((ossim_float64)0, buf);
+         break;
+      }
+      case OSSIM_UINT8:
+      {
+         copyTileToNormalizedBuffer((ossim_uint8)0, buf);
+         break;
+      
+      }
+      case OSSIM_SINT8:
+      {
+         copyTileToNormalizedBuffer((ossim_sint8)0, buf);
+         break;
+      
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         copyTileToNormalizedBuffer((ossim_uint16)0, buf);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         copyTileToNormalizedBuffer((ossim_sint16)0, buf);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         copyTileToNormalizedBuffer((ossim_uint32)0, buf);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         copyTileToNormalizedBuffer((ossim_sint32)0, buf);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "NOTICE:  copyTileToNormalizedBuffer not implemented yet"
+            << std::endl;
+      }
+      
+   }  // End of "switch(getScalarType())"
+}
+
+template <class T>
+void ossimImageData::copyTileToNormalizedBuffer(T dummyTemplate,
+                                                ossim_float64* buf) const
+{
+   const ossim_uint32 SIZE  = getSizePerBand();
+   const ossim_uint32 BANDS = getNumberOfBands();
+   
+   for(ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      const ossim_float64 MIN_PIX = getMinPix(band);
+      const ossim_float64 MAX_PIX = getMaxPix(band);
+      const ossim_float64 RANGE   = (MAX_PIX-MIN_PIX);
+      const ossim_float64 NP      = getNullPix(band);
+
+      const T* s = (T*)getBuf(band);  // source
+      ossim_float64* d = (ossim_float64*)(buf + (band*SIZE));  // destination
+      
+      for(ossim_uint32 offset = 0; offset < SIZE; ++offset)
+      {
+         ossim_float64 p = s[offset];
+         if(p != NP)
+         {
+            if( p == MIN_PIX)
+            {
+               d[offset] = OSSIM_DEFAULT_MIN_PIX_NORM_DOUBLE;
+            }
+            else
+            {
+               d[offset] = (p-MIN_PIX)/RANGE;
+            }
+         }
+         else
+         {
+            d[offset] = 0.0;
+         }
+      }
+   }   
+}
+
+template <class T>
+void ossimImageData::copyTileToNormalizedBuffer(T dummyTemplate,
+                                                ossim_float32* buf) const
+{
+   const ossim_uint32 SIZE  = getSizePerBand();
+   const ossim_uint32 BANDS = getNumberOfBands();
+   
+   for(ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      const ossim_float64 MIN_PIX = getMinPix(band);
+      const ossim_float64 MAX_PIX = getMaxPix(band);
+      const ossim_float64 RANGE   = (MAX_PIX-MIN_PIX);
+      const ossim_float64 NP      = getNullPix(band);
+      
+      const T* s = (T*)getBuf(band);  // source
+      ossim_float32* d = (ossim_float32*)(buf + (band*SIZE));  // destination
+      
+      for(ossim_uint32 offset = 0; offset < SIZE; ++offset)
+      {
+         ossim_float64 p = s[offset];
+         if(p != NP)
+         {
+            if( p == MIN_PIX)
+            {
+               d[offset] = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
+            }
+            else
+            {
+               d[offset] = (p-MIN_PIX)/RANGE;
+            }
+         }
+         else
+         {
+            d[offset] = 0.0;
+         }
+      }
+   }   
+}
+
+template <class T>
+void ossimImageData::copyTileToNormalizedBuffer(T dummyTemplate,
+                                                ossim_uint32 band,
+                                                ossim_float64* buf) const
+{
+   const ossim_uint32  SIZE    = getSizePerBand();
+   const ossim_float64 MIN_PIX = getMinPix(band);
+   const ossim_float64 MAX_PIX = getMaxPix(band);
+   const ossim_float64 RANGE   = (MAX_PIX-MIN_PIX);
+   const ossim_float64 NP      = getNullPix(band);
+   
+   const T* s = (T*)getBuf(band);  // source
+   ossim_float64* d = (ossim_float64*)(buf);  // destination
+   
+   for(ossim_uint32 offset = 0; offset < SIZE; ++offset)
+   {
+         ossim_float64 p = s[offset];
+         if(p != NP)
+         {
+            if( p == MIN_PIX)
+            {
+               d[offset] = OSSIM_DEFAULT_MIN_PIX_NORM_DOUBLE;
+            }
+            else
+            {
+               d[offset] = (p-MIN_PIX)/RANGE;
+            }
+         }
+         else
+         {
+            d[offset] = 0.0;
+         }
+   }   
+}
+
+template <class T>
+void ossimImageData::copyTileToNormalizedBuffer(T dummyTemplate,
+                                                ossim_uint32 band,
+                                                ossim_float32* buf) const
+{
+   const ossim_uint32  SIZE    = getSizePerBand();
+   const ossim_float64 MIN_PIX = getMinPix(band);
+   const ossim_float64 MAX_PIX = getMaxPix(band);
+   const ossim_float64 RANGE   = (MAX_PIX-MIN_PIX);
+   const ossim_float64 NP      = getNullPix(band);
+   
+   const T* s = (T*)getBuf(band);  // source
+   ossim_float32* d     = (ossim_float32*)(buf);  // destination
+   
+   for(ossim_uint32 offset = 0; offset < SIZE; ++offset)
+   {
+      ossim_float64 p = s[offset];
+      if(p != NP)
+      {
+         if( p == MIN_PIX)
+         {
+            d[offset] = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
+         }
+         else
+         {
+            d[offset] = (p-MIN_PIX)/RANGE;
+         }
+      }
+      else
+      {
+         d[offset] = 0.0;
+      }
+   }   
+}
+
+template <class T>
+void ossimImageData::copyNormalizedBufferToTile(T dummyTemplate,
+                                                ossim_float64* buf)
+{
+   const ossim_uint32 SIZE  = getSizePerBand();
+   const ossim_uint32 BANDS = getNumberOfBands();
+   
+   for(ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      const ossim_float64 MIN_PIX = getMinPix(band);
+      const ossim_float64 MAX_PIX = getMaxPix(band);
+      const ossim_float64 RANGE   = (MAX_PIX-MIN_PIX);
+      const T NP                  = (T)getNullPix(band);
+      
+      ossim_float64* s = buf + (band*SIZE); // source
+      T* d   = (T*)getBuf(band); // destination
+      
+      for(ossim_uint32 offset = 0; offset < SIZE; ++offset)
+      {
+         const ossim_float64 P = s[offset];
+         if(P != 0.0)
+         {
+            d[offset] = (T)(MIN_PIX + RANGE*P);
+         }
+         else
+         {
+            d[offset] = NP;
+         }
+      }
+   }
+}
+
+template <class T>
+void ossimImageData::copyNormalizedBufferToTile(T dummyTemplate,
+                                                ossim_float32* buf)
+{
+   const ossim_uint32 SIZE  = getSizePerBand();
+   const ossim_uint32 BANDS = getNumberOfBands();
+   
+   for(ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      const ossim_float64 MIN_PIX = getMinPix(band);
+      const ossim_float64 MAX_PIX = getMaxPix(band);
+      const ossim_float64 RANGE   = (MAX_PIX-MIN_PIX);
+      const T             NP      = (T)getNullPix(band);
+      
+      ossim_float32* s = buf + (band*SIZE); // source
+      T* d   = (T*)getBuf(band); // destination
+      
+      for(ossim_uint32 offset = 0; offset < SIZE; ++offset)
+      {
+         const ossim_float64 P = s[offset];
+         if(P != 0.0)
+         {
+	   ossim_float64 test = MIN_PIX + RANGE*P;
+	   if(test > MAX_PIX) test = MAX_PIX;
+	   d[offset] = (T)test;
+         }
+         else
+         {
+            d[offset] = NP;
+         }
+      }
+   }
+}
+
+template <class T>
+void ossimImageData::copyNormalizedBufferToTile(T dummyTemplate,
+                                                ossim_uint32 band,
+                                                ossim_float64* buf)
+{
+   const ossim_uint32  SIZE    = getSizePerBand();
+   const ossim_float64 MIN_PIX = getMinPix(band);
+   const ossim_float64 MAX_PIX = getMaxPix(band);
+   const ossim_float64 RANGE   = (MAX_PIX-MIN_PIX);
+   const T             NP      = (T)getNullPix(band);
+   
+   ossim_float64* s = buf; // source
+   T* d   = (T*)getBuf(band); // destination
+   
+   for(ossim_uint32 offset = 0; offset < SIZE; ++offset)
+   {
+      const ossim_float64 P = s[offset];
+      if(P != 0.0)
+      {
+	   ossim_float64 test = MIN_PIX + RANGE*P;
+	   if(test > MAX_PIX) test = MAX_PIX;
+	   d[offset] = (T)test;
+      }
+      else
+      {
+         d[offset] = NP;
+      }
+   }
+}
+
+template <class T>
+void ossimImageData::copyNormalizedBufferToTile(T dummyTemplate,
+                                                ossim_uint32 band,
+                                                ossim_float32* buf)
+{
+   const ossim_uint32 SIZE     = getSizePerBand();
+   const ossim_float64 MIN_PIX = getMinPix(band);
+   const ossim_float64 MAX_PIX = getMaxPix(band);
+   const ossim_float64 RANGE   = (MAX_PIX-MIN_PIX);
+   const T NP                  = (T)getNullPix(band);
+   
+   ossim_float32* s = buf; // source
+   T* d   = (T*)getBuf(band); // destination
+   
+   for(ossim_uint32 offset = 0; offset < SIZE; ++offset)
+   {
+      const ossim_float64 P = s[offset];
+      if(P != 0.0)
+      {
+	   ossim_float64 test = MIN_PIX + RANGE*P;
+	   if(test > MAX_PIX) test = MAX_PIX;
+	   d[offset] = (T)test;
+      }
+      else
+      {
+         d[offset] = NP;
+      }
+   }
+}
+
+void ossimImageData::copyTileBandToNormalizedBuffer(ossim_uint32 band,
+                                                    ossim_float64* buf) const
+{
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyTileBandToNormalizedBuffer ERROR:"
+         << "\nNull buffer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyTileBandToNormalizedBuffer ERROR:"
+         << "\nThis object is null! Returning..." << std::endl;
+      return;
+   }
+   
+   if(!getBuf(band)) return;
+
+   switch(getScalarType())
+   {
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         memmove(buf, getBuf(band), getDataSizeInBytes());
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         ossim_uint32 upperBound = getWidth()*getHeight();
+         const ossim_float32* inputBuf = static_cast<const ossim_float32*>(getBuf(band));
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            buf[offset] = inputBuf[offset];
+         }
+         break;
+      }
+      case OSSIM_FLOAT32:
+      {
+         copyTileToNormalizedBuffer((ossim_float32)0, band, buf);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      {
+         copyTileToNormalizedBuffer((ossim_float64)0, band, buf);
+         break;
+      }
+      case OSSIM_UINT8:
+      {
+         copyTileToNormalizedBuffer((ossim_uint8)0, band, buf);
+         break;
+      
+      }
+      case OSSIM_SINT8:
+      {
+         copyTileToNormalizedBuffer((ossim_sint8)0, band, buf);
+         break;
+      
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         copyTileToNormalizedBuffer((ossim_uint16)0, band, buf);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         copyTileToNormalizedBuffer((ossim_sint16)0, band, buf);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         copyTileToNormalizedBuffer((ossim_uint32)0, band, buf);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         copyTileToNormalizedBuffer((ossim_sint32)0, band, buf);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::copyTileBandToNormalizedBuffer ERROR:"
+            << " Unknown scalar type!"
+            << std::endl;
+      }
+      
+   }  // End of "switch(getScalarType())"
+   
+}
+
+void ossimImageData::copyTileToNormalizedBuffer(ossim_float32* buf)const
+{
+   
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyTileToNormalizedBuffer ERROR:"
+         << "\nNull buffer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyTileToNormalizedBuffer ERROR:"
+         << "\nThis object is null! Returning..." << std::endl;
+      return;
+   }
+
+   switch(getScalarType())
+   {
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         ossim_uint32 upperBound = getWidth()*getHeight()*getNumberOfBands();
+         const ossim_float32* inputBuf = static_cast<const ossim_float32*>(getBuf());
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            buf[offset] = inputBuf[offset];
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         memmove(buf, getBuf(), getDataSizeInBytes());
+         break;
+      }
+      case OSSIM_FLOAT32:
+      {
+         copyTileToNormalizedBuffer((ossim_float32)0, buf);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      {
+         copyTileToNormalizedBuffer((ossim_float64)0, buf);
+         break;
+      }
+      case OSSIM_UINT8:
+      {
+         copyTileToNormalizedBuffer((ossim_uint8)0, buf);
+         break;
+      
+      }
+      case OSSIM_SINT8:
+      {
+         copyTileToNormalizedBuffer((ossim_sint8)0, buf);
+         break;
+      
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         copyTileToNormalizedBuffer((ossim_uint16)0, buf);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         copyTileToNormalizedBuffer((ossim_sint16)0, buf);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         copyTileToNormalizedBuffer((ossim_uint32)0, buf);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         copyTileToNormalizedBuffer((ossim_sint32)0, buf);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "NOTICE:  copyTileToNormalizedBuffer not implemented yet"
+            << std::endl;
+      }
+      
+   }  // End of "switch(getScalarType())"
+}
+
+void ossimImageData::copyTileBandToNormalizedBuffer(ossim_uint32 band,
+                                                    ossim_float32* buf)const
+{
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyTileBandToNormalizedBuffer ERROR:"
+         << "\nNull buffer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyTileBandToNormalizedBuffer ERROR:"
+         << "\nThis object is null! Returning..." << std::endl;
+      return;
+   }
+
+   switch(getScalarType())
+   {
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         ossim_uint32 upperBound = getWidth()*getHeight();
+         const ossim_float32* inputBuf = static_cast<const ossim_float32*>(getBuf(band));
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            buf[offset] = inputBuf[offset];
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         memmove(buf, getBuf(band), getSizePerBandInBytes());
+         break;
+      }
+      case OSSIM_FLOAT32:
+      {
+         copyTileToNormalizedBuffer((ossim_float32)0, band, buf);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      {
+         copyTileToNormalizedBuffer((ossim_float64)0, band, buf);
+         break;
+      }
+      case OSSIM_UINT8:
+      {
+         copyTileToNormalizedBuffer((ossim_uint8)0, band, buf);
+         break;
+      
+      }
+      case OSSIM_SINT8:
+      {
+         copyTileToNormalizedBuffer((ossim_sint8)0, band, buf);
+         break;
+      
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         copyTileToNormalizedBuffer((ossim_uint16)0, band, buf);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         copyTileToNormalizedBuffer((ossim_sint16)0, band, buf);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         copyTileToNormalizedBuffer((ossim_uint32)0, band, buf);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         copyTileToNormalizedBuffer((ossim_sint32)0, band, buf);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::copyTileBandToNormalizedBuffer ERROR:"
+            << " Unknown scalar type"
+            << std::endl;
+      }
+
+   }  // End of "switch(getScalarType())"
+}
+
+
+void ossimImageData::copyNormalizedBufferToTile(ossim_float64* buf)
+{
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyNormalizedBufferToTile ERROR:"
+         << "\nNull buffer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyNormalizedBufferToTile ERROR:"
+         << "\nThis object is null! Returning..." << std::endl;
+      return;
+   }
+   
+   switch(getScalarType())
+   {
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         memmove(getBuf(), buf, getDataSizeInBytes());
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         ossim_uint32 upperBound = getWidth()*getHeight()*getNumberOfBands();
+         ossim_float32* inputBuf = static_cast<ossim_float32*>(getBuf());
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            inputBuf[offset] = static_cast<ossim_float32>(buf[offset]);
+         }
+         break;
+      }
+      case OSSIM_FLOAT32:
+      {
+         copyNormalizedBufferToTile((ossim_float32)0, buf);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      {
+         copyNormalizedBufferToTile((ossim_float64)0, buf);
+         break;
+      }
+      case OSSIM_UINT8:
+      {
+         copyNormalizedBufferToTile((ossim_uint8)0, buf);
+         break;
+      
+      }
+      case OSSIM_SINT8:
+      {
+         copyNormalizedBufferToTile((ossim_sint8)0, buf);
+         break;
+      
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         copyNormalizedBufferToTile((ossim_uint16)0, buf);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         copyNormalizedBufferToTile((ossim_sint16)0, buf);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         copyNormalizedBufferToTile((ossim_uint32)0, buf);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         copyNormalizedBufferToTile((ossim_sint32)0, buf);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::copyNormalizedBufferToTile\n"
+            << "Unknown scalar type!" << std::endl;
+      }
+      
+   } // End of "switch(getScalarType())".
+}
+
+void ossimImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                ossim_float64* buf)
+{
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyNormalizedBufferToTile ERROR:"
+         << "\nNull buffer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyNormalizedBufferToTile ERROR:"
+         << "\nThis object is null! Returning..." << std::endl;
+      return;
+   }
+
+   if(band < getNumberOfBands())
+   {
+      switch(getScalarType())
+      {
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            memmove(getBuf(band), buf, getSizePerBandInBytes());
+            break;
+         }
+         case OSSIM_NORMALIZED_FLOAT:
+         {
+            ossim_uint32 upperBound = getWidth()*getHeight();
+            ossim_float32* inputBuf = static_cast<ossim_float32*>(getBuf(band));
+            for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+            {
+               inputBuf[offset] = static_cast<ossim_float32>(buf[offset]);
+            }
+            break;
+         }
+         case OSSIM_FLOAT32:
+         {
+            copyNormalizedBufferToTile((ossim_float32)0, band, buf);
+            break;
+         }
+         case OSSIM_FLOAT64:
+         {
+            copyNormalizedBufferToTile((ossim_float64)0, band, buf);
+            break;
+         }
+         case OSSIM_UINT8:
+         {
+            copyNormalizedBufferToTile((ossim_uint8)0, band, buf);
+            break;
+         
+         }
+         case OSSIM_SINT8:
+         {
+            copyNormalizedBufferToTile((ossim_sint8)0, band, buf);
+            break;
+         
+         }
+         case OSSIM_USHORT11:
+         case OSSIM_UINT16:
+         {
+            copyNormalizedBufferToTile((ossim_uint16)0, band, buf);
+            break;
+         }
+         case OSSIM_SINT16:
+         {
+            copyNormalizedBufferToTile((ossim_sint16)0, band, buf);
+            break;
+         }
+         case OSSIM_UINT32:
+         {
+            copyNormalizedBufferToTile((ossim_uint32)0, band, buf);
+            break;
+         }
+         case OSSIM_SINT32:
+         {
+            copyNormalizedBufferToTile((ossim_sint32)0, band, buf);
+            break;
+         }
+         case OSSIM_SCALAR_UNKNOWN:
+         default:
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "ossimImageData::copyNormalizedBufferToTile\n"
+               << "Unknown scalar type." << std::endl;
+         }
+         
+      } // End of "switch(getScalarType())".
+   }
+}
+
+void ossimImageData::copyNormalizedBufferToTile(ossim_float32* buf)
+{
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyNormalizedBufferToTile ERROR:"
+         << "\nNull buffer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyNormalizedBufferToTile ERROR:"
+         << "\nThis object is null! Returning..." << std::endl;
+      return;
+   }
+
+   switch(getScalarType())
+   {
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         ossim_uint32 upperBound = getWidth()*getHeight()*getNumberOfBands();
+         ossim_float64* inputBuf = static_cast<ossim_float64*>(getBuf());
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            inputBuf[offset] = buf[offset];
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         memmove(getBuf(), buf, getDataSizeInBytes());
+         break;
+      }
+      case OSSIM_FLOAT32:
+      {
+         copyNormalizedBufferToTile((ossim_float32)0, buf);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      {
+         copyNormalizedBufferToTile((ossim_float64)0, buf);
+         break;
+      }
+      case OSSIM_UINT8:
+      {
+         copyNormalizedBufferToTile((ossim_uint8)0, buf);
+         break;
+         
+      }
+      case OSSIM_SINT8:
+      {
+         copyNormalizedBufferToTile((ossim_sint8)0, buf);
+         break;
+         
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         copyNormalizedBufferToTile((ossim_uint16)0, buf);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         copyNormalizedBufferToTile((ossim_sint16)0, buf);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         copyNormalizedBufferToTile((ossim_uint32)0, buf);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         copyNormalizedBufferToTile((ossim_sint32)0, buf);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageDatacopyNormalizedBufferToTile\n"
+            << "Unknown scalar type!" << std::endl;
+      }
+      
+   }  // End of "switch(getScalarType())".
+}
+
+void ossimImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                ossim_float32* buf)
+{
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyNormalizedBufferToTile ERROR:"
+         << "\nNull buffer passed to method!  Returning..." << std::endl;
+      return;
+   }
+
+   if (getDataObjectStatus() == OSSIM_NULL)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimImageData::copyNormalizedBufferToTile ERROR:"
+         << "\nThis object is null! Returning..." << std::endl;
+      return;
+   }
+
+   switch(getScalarType())
+   {
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         ossim_uint32 upperBound = getWidth()*getHeight();
+         ossim_float64* inputBuf = static_cast<ossim_float64*>(getBuf(band));
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            inputBuf[offset] = buf[offset];
+         }
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         memmove(getBuf(band), buf, getSizePerBandInBytes());
+         break;
+      }
+      case OSSIM_FLOAT32:
+      {
+         copyNormalizedBufferToTile((ossim_float32)0, band, buf);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      {
+         copyNormalizedBufferToTile((ossim_float64)0, band, buf);
+         break;
+      }
+      case OSSIM_UINT8:
+      {
+         copyNormalizedBufferToTile((ossim_uint8)0, band, buf);
+         break;
+         
+      }
+      case OSSIM_SINT8:
+      {
+         copyNormalizedBufferToTile((ossim_sint8)0, band, buf);
+         break;
+         
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         copyNormalizedBufferToTile((ossim_uint16)0, band, buf);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         copyNormalizedBufferToTile((ossim_sint16)0, band, buf);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         copyNormalizedBufferToTile((ossim_uint32)0, band, buf);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         copyNormalizedBufferToTile((ossim_sint32)0, band, buf);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageData::copyNormalizedBufferToTile\n"
+            << "Unknown scalar type!" << std::endl;
+      }
+
+   }  // End of "switch(getScalarType())".
+}
+
+ossim_float64 ossimImageData::getMinNormalizedPix() const
+{
+   if (theScalarType == OSSIM_NORMALIZED_DOUBLE ||
+       theScalarType == OSSIM_NORMALIZED_FLOAT)
+   {
+      return theMinPixelValue[0];  // Already normalized.
+   }
+   return (1.0 / (theMaxPixelValue[0] - theMinPixelValue[0] + 1.0));
+}
+
+std::ostream& ossimImageData::print(std::ostream& out) const
+{
+   out << "ossimImageData::print:"
+      << "\ntheOrigin:  " << theOrigin << std::endl;
+   if(theNullPixelValue)
+   {
+      out << "Null values: ";
+      
+      copy(theNullPixelValue,
+           theNullPixelValue + getNumberOfBands(),
+           std::ostream_iterator<ossim_float64>(out, " "));
+      out << "\n";
+   }
+   if(theMinPixelValue)
+   {
+      out << "Min values:  ";
+      
+      copy(theMinPixelValue,
+           theMinPixelValue + getNumberOfBands(),
+           std::ostream_iterator<ossim_float64>(out, " "));
+      out << "\n";
+   }
+   if(theMaxPixelValue)
+   {
+      out << "Max values:  ";
+      
+      copy(theMaxPixelValue,
+           theMaxPixelValue + getNumberOfBands(),
+           std::ostream_iterator<ossim_float64>(out, " "));
+      out << "\n";
+   }
+   out << "width:            " << getWidth()
+       << "\nheight:           " << getHeight()
+       << "\nimage rectangle:  " << getImageRectangle()
+       << std::endl;
+
+   return ossimRectilinearDataObject::print(out);
+}
+
+ossim_uint32 ossimImageData::getWidth()const
+{
+   if(theSpatialExtents) return theSpatialExtents[0];
+   return 0;
+}
+
+ossim_uint32 ossimImageData::getHeight()const
+{
+   if(theSpatialExtents) return theSpatialExtents[1];
+   return 0;
+}
+
+void ossimImageData::getWidthHeight(ossim_uint32& w, ossim_uint32& h)
+{
+   if(theSpatialExtents)
+   {
+      w = theSpatialExtents[0];
+      h = theSpatialExtents[1];
+   }
+}
+
+void ossimImageData::setWidth(ossim_uint32 width)
+{
+   if(theSpatialExtents)
+   {
+      theSpatialExtents[0] = width;
+   }
+}
+
+void ossimImageData::setHeight(ossim_uint32 height)
+{
+   if(theSpatialExtents)
+   {
+      theSpatialExtents[1] = height;
+   }
+}
+
+void ossimImageData::setWidthHeight(ossim_uint32 w, ossim_uint32 h)
+{
+   if(theSpatialExtents)
+   {
+      theSpatialExtents[0] = w;
+      theSpatialExtents[1] = h;
+   }
+}
+
+void ossimImageData::setOrigin(const ossimIpt& origin)
+{
+   theOrigin = origin;
+}
+
+ossim_uint32 ossimImageData::getDataSizeInBytes()const
+{
+   return getSizeInBytes();
+}
+
+const ossimImageData& ossimImageData::operator=(const ossimImageData& /* rhs */)
+{
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageData.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageData.h
new file mode 100644
index 0000000000..0d89bc4f4e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageData.h
@@ -0,0 +1,930 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: A brief description of the contents of the file.
+//
+//*******************************************************************
+// $Id: ossimImageData.h,v 1.72 2005/11/14 21:38:01 dburken Exp $
+#ifndef ossimImageData_HEADER
+#define ossimImageData_HEADER
+
+#include <vector>
+using namespace std;
+
+#include <base/common/ossimRectilinearDataObject.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/common/ossimRefPtr.h>
+
+class ossimMultiBandHistogram;
+
+class OSSIMDLLEXPORT ossimImageData : public ossimRectilinearDataObject
+{
+public:
+   ossimImageData(const ossimImageData &rhs);
+   
+   ossimImageData(ossimSource* source,
+                  ossimScalarType scalar,
+                  ossim_uint32 bands = 1);
+
+   ossimImageData(ossimSource* source,
+                  ossimScalarType scalar,
+                  ossim_uint32 bands,
+                  ossim_uint32 width,
+                  ossim_uint32 height);
+
+   virtual ~ossimImageData();
+
+   /**
+    * @return The width of the data object.
+    */
+   virtual ossim_uint32 getWidth()const;
+
+   /**
+    * @return The height of the data object.
+    */
+   virtual ossim_uint32 getHeight()const;
+
+   /**
+    * @return The image rectangle relative to origin, height and width.
+    */
+   virtual ossimIrect getImageRectangle() const;
+   virtual void getWidthHeight(ossim_uint32& w, ossim_uint32& h);
+   virtual void setWidth(ossim_uint32 width);
+   virtual void setHeight(ossim_uint32 height);
+   virtual void setWidthHeight(ossim_uint32 w, ossim_uint32 h);
+   virtual void setImageRectangleAndBands(const ossimIrect& rect,
+                                          ossim_uint32 numberOfBands);
+   virtual void setImageRectangle(const ossimIrect& rect);
+   virtual void setOrigin(const ossimIpt& origin);   
+                                    
+   virtual void assign(const ossimDataObject* data);
+   virtual void assign(const ossimImageData* data);
+   virtual void assignBand(const ossimImageData* data,
+                           ossim_uint32 source_band,
+                           ossim_uint32 output_band);
+   
+   virtual ossimObject* dup() const;
+
+  /**
+   * Uses prime numbers as coefficients for this summation.  
+   * Take the the fours bytes of each origin and multiply 
+   * by the prime numbers and sum together.  This has
+   * been proven by others to give nicely distributed 
+   * id number.
+   */
+   virtual ossim_uint32 getHashId()const;
+   
+   virtual void setNullPix(ossim_float64 null_pix);
+   virtual void setNullPix(ossim_float64 null_pix, ossim_uint32 band);
+   virtual void setNullPix(const ossim_float64* nullPixArray,
+                           ossim_uint32 numberOfValues);
+   virtual void setMinPix(ossim_float64 min_pix);
+   virtual void setMinPix(ossim_float64 min_pix, ossim_uint32 band);
+   virtual void setMinPix(const ossim_float64* minPixArray,
+                          ossim_uint32 numberOfValues);
+   virtual void setMaxPix(ossim_float64 max_pix);
+   virtual void setMaxPix(ossim_float64 max_pix, ossim_uint32 band);
+   virtual void setMaxPix(const ossim_float64* maxPixArray,
+                          ossim_uint32 numberOfValues);
+
+   virtual const ossimIpt& getOrigin()const{return theOrigin;}
+
+   /**
+    * If the minBands and maxBands are empty or not equal to the imageData's
+    * current number of bands it will erase the contents, resize, and then
+    * replace the values in the passed in array with this objects min max
+    * values.  If the arrays are the same size as this objects number of
+    * bands it will just update the values and use the current values in the
+    * arrays as initial min max values.
+    *
+    * If the status of this object(getDataObjectStatus()) is OSSIM_NULL or
+    * OSSIM_EMPTY no action is performed.
+    */
+   virtual void computeMinMaxPix(vector<ossim_float64>& minBands,
+                                 vector<ossim_float64>& maxBands);
+   
+   virtual const ossim_float64* getNullPix()const;
+   virtual const ossim_float64* getMinPix()const;
+   virtual const ossim_float64* getMaxPix()const;
+   virtual ossim_float64        getNullPix(ossim_uint32 band) const;
+   virtual ossim_float64        getMinPix(ossim_uint32 band)  const;
+   virtual ossim_float64        getMaxPix(ossim_uint32 band)  const;
+
+   /**
+    * returns normalized minimum pixel value of band zero.
+    */
+   virtual ossim_float64   getMinNormalizedPix() const;
+   virtual ossimString     getScalarTypeAsString()const;
+   virtual ossim_uint32    getNumberOfBands() const;
+   virtual void            setNumberOfBands(ossim_uint32 bands,
+                                            bool reallocate=false);
+
+   /**
+    * Will return the pixel at location position.  Note it will first get
+    * the passed in position relative to the origin or upper left
+    * corner of this tile and then return the result.
+    */
+   virtual ossim_float64 getPix(const ossimIpt& position,
+                                ossim_uint32 band=0) const;
+
+   /**
+    * Will return the pixel at offset and band number.
+    */
+   virtual ossim_float64 getPix(ossim_uint32 offset,
+                                ossim_uint32 band = 0) const;
+   
+   /**
+    * will fill the entire band with
+    * the value.
+    */
+   void fill(ossim_uint32 band, ossim_float64 value);
+
+   /**
+    * will fill all bands with the passed in
+    * value.
+    */
+   void fill(ossim_float64 value);
+   bool isNull(ossim_uint32 offset)const;
+   bool isNull(ossim_uint32 offset, ossim_uint32 band)const;
+   void setNull(ossim_uint32 offset);
+   void setNull(ossim_uint32 offset, ossim_uint32 band);
+
+   bool isNull(const ossimIpt& pt)const;
+   void setNull(const ossimIpt& pt);
+   bool isNull(const ossimIpt& pt, ossim_uint32 band)const;
+   void setNull(const ossimIpt& pt, ossim_uint32 band);
+   
+   virtual bool   isValidBand(ossim_uint32 band) const;
+   virtual ossimDataObjectStatus validate() const;
+
+   /**
+    * Will take this tile and normalize it to a newly
+    * allocated floating point tile.
+    */
+   virtual ossimRefPtr<ossimImageData> newNormalizedFloat()const;
+
+   /**
+    * will go to the band and offset and compute the
+    * normalized float and return it back to the
+    * caller through the result argument.
+    */
+   virtual void getNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   ossim_float32& result)const;
+
+   /**
+    * This will assign to this object a normalized
+    * value by unnormalizing to its native type.
+    */
+   virtual void setNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   ossim_float32 input);
+
+   /**
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedFloat(ossimImageData* result)const;
+
+   /**
+    * Will take this tile and normalize it to a newly
+    * allocated double point tile.
+    */
+   virtual ossimImageData* newNormalizedDouble()const;
+
+   /**
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedDouble(ossimImageData* result)const;
+
+   /**
+    * Will take the normalized input and convert it
+    * to this tile's data type.  Example:  if this
+    * tile is of type UCHAR and its input is of type
+    * NORALIZED_FLOAT it will unnormalize the data by
+    * doing:
+    *
+    * minPix + normalizedInput*(maxPix-minPix)
+    *
+    * on a per band basis.
+    */
+   virtual void unnormalizeInput(ossimImageData* normalizedInput);
+
+   /**
+    * This will compute the average value for the band.
+    */
+   virtual ossim_float64 computeAverageBandValue(
+      ossim_uint32 bandNumber = 0) const;
+
+   /**
+    * This will call the compute average band value and then
+    * use that in the calculation of:
+    
+    * It will then do a SUM[(Mean - Actual)^2]/width*height.
+    *
+    * This is the average variance from the passed in
+    * mean.  
+    */
+   virtual ossim_float64 computeMeanSquaredError(
+      ossim_float64 meanValue,
+      ossim_uint32 bandNumber = 0) const;
+  
+   virtual void populateHistogram(ossimMultiBandHistogram* histo);
+
+   /**
+    * @return const void* to theDataBuffer
+    */
+   virtual const void* getBuf() const;
+   
+   /**
+    * @return const ossim_uint8* to theDataBuffer if scalar is of type
+    * OSSIM_UCHAR; else, NULL.
+    */
+   virtual const ossim_uint8*    getUcharBuf()  const;
+
+   /**
+    * @return const ossim_uint16* to theDataBuffer if scalar is of type
+    * OSSIM_USHORT16 or USHORT11; else, NULL.
+    */
+   virtual const ossim_uint16*   getUshortBuf() const;
+
+   /**
+    * @return const ossim_sint16* to theDataBuffer if scalar is of type
+    * OSSIM_SSHORT16; else, NULL.
+    */
+   virtual const ossim_sint16*   getSshortBuf() const;
+
+   /**
+    * @return const ossim_float32* to theDataBuffer if scalar is of type
+    * OSSIM_FLOAT or OSSIM_NORMALIZED_FLOAT; else, NULL.
+    */
+   virtual const ossim_float32*  getFloatBuf()  const;
+
+   /**
+    * @return const ossim_float64* to theDataBuffer if scalar is of type
+    * OSSIM_DOUBLE or OSSIM_NORMALIZED_DOUBLE; else, NULL.
+    */
+   virtual const ossim_float64*  getDoubleBuf() const;
+
+   /**
+    * @return void* to theDataBuffer
+    */
+   virtual void* getBuf();
+   
+   /**
+    * @return ossim_uint8* to theDataBuffer if scalar is of type
+    * OSSIM_UCHAR; else, NULL.
+    */
+   virtual ossim_uint8*    getUcharBuf();
+   
+   /**
+    * @return ossim_uint16* to theDataBuffer if scalar is of type
+    * OSSIM_USHORT16 or OSSIM_USHORT11; else, NULL.
+    */
+   virtual ossim_uint16*   getUshortBuf();
+   
+   /**
+    * @return ossim_sint16* to theDataBuffer if scalar is of type
+    * OSSIM_SSHORT16; else, NULL.
+    */
+   virtual ossim_sint16*   getSshortBuf();
+
+   /**
+    * @return ossim_float32* to theDataBuffer if scalar is of type
+    * OSSIM_FLOAT or OSSIM_NORMALIZED_FLOAT; else, NULL.
+    */
+   virtual ossim_float32*  getFloatBuf();
+   
+   /**
+    * @return float64* to theDataBuffer if scalar is of type OSSIM_DOUBLE or
+    * OSSIM_NORMALIZED_DOUBLE; else, NULL.
+    */
+   virtual ossim_float64*  getDoubleBuf();
+
+   /**
+    * @param band (zero based)
+    * @return void* to theDataBuffer positioned at band.
+    */
+   virtual const void*           getBuf(ossim_uint32 band) const;
+   
+   /**
+    * @param band (zero based)
+    * @return ossim_uint8* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_UCHAR; else, NULL.
+    */
+   virtual const ossim_uint8*    getUcharBuf(ossim_uint32 band) const;
+
+   /**
+    * @param band (zero based)
+    * @return ossim_uint16* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_USHORT16 or OSSIM_USHORT11; else, NULL.
+    */
+   virtual const ossim_uint16*   getUshortBuf(ossim_uint32 band) const;
+   
+   /**
+    * @param band (zero based)
+    * @return ossim_sint16* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_SSHORT16; else, NULL.
+    */
+   virtual const ossim_sint16*   getSshortBuf(ossim_uint32 band) const;
+   
+   /**
+    * @param band (zero based)
+    * @return ossim_float32* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_FLOAT or OSSIM_NORMALIZED_FLOAT; else, NULL.
+    */
+   virtual const ossim_float32*  getFloatBuf(ossim_uint32 band) const;
+   
+   /**
+    * @param band (zero based)
+    * @return ossim_float64* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_DOUBLE or OSSIM_NORMALIZED_DOUBLE; else, NULL.
+    */
+   virtual const ossim_float64*  getDoubleBuf(ossim_uint32 band) const;
+
+   /**
+    * @param band (zero based)
+    * @return void* to theDataBuffer positioned at band.
+    */
+   virtual void*           getBuf(ossim_uint32 band);
+   
+   /**
+    * @param band (zero based)
+    * @return ossim_uint8* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_UCHAR; else, NULL.
+    */
+   virtual ossim_uint8*    getUcharBuf(ossim_uint32 band);
+   
+   /**
+    * @param band (zero based)
+    * @return ossim_uint16* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_USHORT16 or OSSIM_USHORT11; else, NULL.
+    */
+   virtual ossim_uint16*   getUshortBuf(ossim_uint32 band);
+   
+   /**
+    * @param band (zero based)
+    * @return ossim_sint16* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_SSHORT16; else, NULL.
+    */
+   virtual ossim_sint16*   getSshortBuf(ossim_uint32 band);
+   
+   /**
+    * @param band (zero based)
+    * @return ossim_float32* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_FLOAT or OSSIM_NORMALIZED_FLOAT; else, NULL.
+    */
+   virtual ossim_float32*  getFloatBuf(ossim_uint32 band);
+   
+   /**
+    * @param band (zero based)
+    * @return ossim_float64* to theDataBuffer positioned at band if scalar is
+    * of type OSSIM_DOUBLE or OSSIM_NORMALIZED_DOUBLE; else, NULL.
+    */
+   virtual ossim_float64*  getDoubleBuf(ossim_uint32 band);
+   
+   /**
+    *  Returns the total number of pixels in a tile for all bands.
+    *  Note:  This is not in bytes but in pixels.
+    */
+   virtual ossim_uint32 getSize() const;
+
+   /**
+    *  Returns the number of pixels in a single band in a tile.
+    *  Note:  This is not in bytes but in pixels.
+    */
+   virtual ossim_uint32 getSizePerBand()const;
+
+   /**
+    *  Returns the number of bytes in single band of the tile.
+    */
+   virtual ossim_uint32 getSizePerBandInBytes() const;
+
+   virtual ossim_uint32 getDataSizeInBytes()const;
+
+   /**
+    * Returns the total number of bytes for all bands.
+    */
+   virtual ossim_uint32  getSizeInBytes() const;
+
+   /**
+    *  Initializes data to null pixel values.
+    */
+   virtual void makeBlank();
+
+   /**
+    *  Initialize the data buffer.
+    */
+   virtual void initialize();
+
+   /**
+    * Copies entire tile to buf passed in.  Data put in buf is normalized.
+    * The "buf" passed to method is assumed to be at least as big as:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyTileToNormalizedBuffer(ossim_float64* buf) const;
+   virtual void copyTileToNormalizedBuffer(ossim_float32* buf)const;
+
+   /**
+    * Will copy this tiles specified band number to the normalized buffer.
+    * if the band is out of range then nothing is done and returns.
+    *
+    * @param band Zero based band to copy.
+    *
+    * @param buf Buffer to copy to.
+    */
+   virtual void copyTileBandToNormalizedBuffer(ossim_uint32 band,
+                                               ossim_float64* buf) const;
+   
+   /**
+    * Will copy this tiles specified band number to the normalized buffer.
+    * if the band is out of range then nothing is done and returns.
+    *
+    * @param band Zero based band to copy.
+    *
+    * @param buf Buffer to copy to.
+    */
+   virtual void copyTileBandToNormalizedBuffer(ossim_uint32 band,
+                                               ossim_float32* buf)const;
+
+   /**
+    * Copies buf passed in to tile.  Data is unnormalized to the tile's
+    * scalar type.
+    * The "buf" passed to method is assumed to be at least as big as the tiles:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyNormalizedBufferToTile(ossim_float64* buf);
+   virtual void copyNormalizedBufferToTile(ossim_float32* buf);
+
+   /**
+    * Will copy the normalized buffer to this tiles
+    * specified band.  If band is out of range then nothing
+    *
+    * is done and returns.
+    */
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           ossim_float64* buf);
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           ossim_float32* buf);
+
+   virtual bool isWithin(ossim_int32 x, ossim_int32 y);
+   virtual void setValue(ossim_int32 x, ossim_int32 y, ossim_float64 color);
+
+   virtual void loadBand(const void* src,
+                         const ossimIrect& src_rect,
+                         ossim_uint32 band);
+
+   virtual void loadBand(const void* src,
+                         const ossimIrect& src_rect,
+                         const ossimIrect& clip_rect,
+                         ossim_uint32 band);
+   
+   virtual void loadTile(const void* src,
+                         const ossimIrect& src_rect,
+                         ossimInterleaveType il_type);
+
+   virtual void loadTile(const void* src,
+                         const ossimIrect& src_rect,
+                         const ossimIrect& clip_rect,                         
+                         ossimInterleaveType il_type);
+
+   /**
+    * Will load a tile of different types.  If they
+    * are the same then it will call loadTile(void*...)
+    * method.  Note if they are of different types we
+    * will have to go through a much slower assign
+    * process by normalizing the right side and then
+    * unnormalizing to the destination type. For this
+    * method to work they both must have the same
+    * number of bands.
+    */
+   virtual void loadTile(const ossimImageData* src);
+   
+   virtual void loadTileFrom1Band(const ossimImageData* data);
+
+   virtual void loadTileFrom1Band(const void* src,
+                                  const ossimIrect& src_rect);
+   /**
+    * Specialized to load a tile from a short (16 bit scalar type) buffer.
+    * Performs byte swapping if swap_bytes is set to true.
+    */
+   virtual void loadShortBand(const void* src,
+                              const ossimIrect& src_rect,
+                              ossim_uint32 band,
+                              bool swap_bytes=false);
+   
+   virtual void unloadTile(void* dest,
+                           const ossimIrect& dest_rect,
+                           ossimInterleaveType il_type) const;
+   
+   virtual void unloadTile(void* dest,
+                           const ossimIrect& dest_rect,
+                           const ossimIrect& clip_rect,
+                           ossimInterleaveType il_type) const;
+
+   virtual void unloadBand(void* dest,
+                           const ossimIrect& dest_rect,
+                           ossim_uint32 band) const;
+   
+   virtual void unloadBand(void* dest,
+                           const ossimIrect& dest_rect,
+                           const ossimIrect& clip_rect,
+                           ossim_uint32 band) const;
+   
+   
+   virtual bool isPointWithin(const ossimIpt& point)const;
+   virtual bool isPointWithin(ossim_int32 x,
+                              ossim_int32 y)const;
+
+   virtual std::ostream& print(std::ostream& out) const;
+   
+protected:
+   ossimImageData();
+
+   /**
+    * Templated valide method.
+    *
+    * @return The status of the ossimImageDataMethod.
+    *
+    * @note See ossimConstants.h for ossimDataObjectStatus enumerations.
+    */
+   template <class T> ossimDataObjectStatus validate(T dummyTemplate) const;
+
+   /**
+    * Templated makeBlank method.
+    */
+   template <class T> void makeBlank(T dummyTemplate);
+
+   /**
+    * Templated computeMeanSquaredError method.
+    */
+   template <class T>
+      ossim_float64 computeMeanSquaredError(T dummyTemplate,
+                                            ossim_float64 meanValue,
+                                            ossim_uint32 bandNumber) const;
+
+   /**
+    * Templated computeAverageBandValue method.
+    */
+   template <class T>
+      ossim_float64 computeAverageBandValue(T dummyTemplate,
+                                            ossim_uint32 bandNumber) const;
+   
+   /**
+    *  
+    *  Takes normPix, unnormalizes and initializes pixel.
+    *  "band" is used as index to get the min/max/null values.
+    */
+   void getPixFromNorm(ossim_int32& pixel,
+                       ossim_float32  normPix,
+                       ossim_uint32 band) const;
+
+   
+   /**
+    *  Takes normPix, unnormalizes and initializes pixel.
+    *  "band" is used as index to get the min/max/null values.
+    */
+   void getPixFromNorm(ossim_int32& pixel,
+                       ossim_float64 normPix,
+                       ossim_uint32 band) const;
+
+   /**
+    *  Take pixel, normalizes and initializes normPix.
+    *  "band" is used as index to get the min/max/null values.
+    */
+   void getNormFromPix  (ossim_int32  pixel,
+                         ossim_float32& normPix,
+                         ossim_uint32 band) const;
+
+   /**
+    *  Take pixel, normalizes and initializes normPix.
+    *  "band" is used as index to get the min/max/null values.
+    */
+   void getNormFromPix (ossim_int32  pixel,
+                        ossim_float64& normPix,
+                        ossim_uint32 band) const;
+
+   void loadTileFromBip(const void* src, const ossimIrect& src_rect);
+   void loadTileFromBil(const void* src, const ossimIrect& src_rect);
+   void loadTileFromBsq(const void* src, const ossimIrect& src_rect);
+
+   void loadTileFromBip(const void* src,
+                        const ossimIrect& src_rect,
+                        const ossimIrect& clip_rect);
+   void loadTileFromBil(const void* src,
+                        const ossimIrect& src_rect,
+                        const ossimIrect& clip_rect);
+   void loadTileFromBsq(const void* src,
+                        const ossimIrect& src_rect,
+                        const ossimIrect& clip_rect);
+
+   void unloadTileToBip(void* dest,
+                        const ossimIrect& dest_rect,
+                        const ossimIrect& clip_rect) const;
+   void unloadTileToBil(void* dest,
+                        const ossimIrect& dest_rect,
+                        const ossimIrect& clip_rect) const;
+   void unloadTileToBsq(void* dest,
+                        const ossimIrect& dest_rect,
+                        const ossimIrect& clip_rect) const;
+
+   /**
+    * Copies entire tile to buf passed in.  Data put in buf is normalized.
+    * The "buf" passed to method is assumed to be at least as big as:
+    * "getSize() * sizeof(double)"
+    */
+   template <class T>
+   void copyTileToNormalizedBuffer(T dummyTemplate,
+                                   ossim_float64* buf) const;
+   template <class T>
+   void copyTileToNormalizedBuffer(T dummyTemplate,
+                                   ossim_float32* buf)const;
+
+   /**
+    * Will copy this tiles specified band number to the normalized buffer.
+    * if the band is out of range then nothing is done and returns.
+    */
+   template <class T>
+   void copyTileToNormalizedBuffer(T dummyTemplate,
+                                   ossim_uint32 band, ossim_float64* buf) const;
+   template <class T>
+   void copyTileToNormalizedBuffer(T dummyTemplate,
+                                   ossim_uint32 band, ossim_float32* buf)const;
+
+   /**
+    * Copies buf passed in to tile.  Data is unnormalized to the tile's
+    * scalar type.
+    * The "buf" passed to method is assumed to be at least as big as the tiles:
+    * "getSize() * sizeof(double)"
+    */
+   template <class T>
+   void copyNormalizedBufferToTile(T dummyTemplate,
+                                   ossim_float64* buf);
+   template <class T>
+   void copyNormalizedBufferToTile(T dummyTemplate,
+                                   ossim_float32* buf);
+   template <class T>
+   void copyNormalizedBufferToTile(T dummyTemplate,
+                                   ossim_uint32 band,
+                                   ossim_float64* buf);
+   template <class T>
+   void copyNormalizedBufferToTile(T dummyTemplate,
+                                   ossim_uint32 band,
+                                   ossim_float32* buf);
+
+   
+   template <class T> void computeMinMaxPix(T dummyValue,
+                                            vector<ossim_float64>& minBands,
+                                            vector<ossim_float64>& maxBands);
+   
+   template <class T> void loadBand(T, // dummy template variable
+                                    const void* src,
+                                    const ossimIrect& src_rect,
+                                    ossim_uint32 band);
+
+   template <class T> void loadBand(T, // dummy template variable
+                                    const void* src,
+                                    const ossimIrect& src_rect,
+                                    const ossimIrect& clip_rect,
+                                    ossim_uint32 band);
+
+   template <class T> void loadTileFromBip(T, // dummy template variable
+                                           const void* src,
+                                           const ossimIrect& src_rect);
+
+   template <class T> void loadTileFromBip(T, // dummy template variable
+                                           const void* src,
+                                           const ossimIrect& src_rect,
+                                           const ossimIrect& clip_rect);
+   
+   template <class T> void loadTileFromBil(T, // dummy template variable
+                                           const void* src,
+                                           const ossimIrect& src_rect);
+
+   template <class T> void loadTileFromBil(T, // dummy template variable
+                                           const void* src,
+                                           const ossimIrect& src_rect,
+                                           const ossimIrect& clip_rect);
+   
+   template <class T> void loadTileFromBsq(T, // dummy template variable
+                                           const void* src,
+                                           const ossimIrect& src_rect);
+
+   template <class T> void loadTileFromBsq(T, // dummy template variable
+                                           const void* src,
+                                           const ossimIrect& src_rect,
+                                           const ossimIrect& clip_rect);
+   
+   template <class T> void unloadTileToBip(T, // dummy tmeplate variable
+                                           void* dest,
+                                           const ossimIrect& dest_rect,
+                                           const ossimIrect& clip_rect) const;
+
+   template <class T> void unloadTileToBil(T, // dummy tmeplate variable
+                                           void* dest,
+                                           const ossimIrect& dest_rect,
+                                           const ossimIrect& clip_rect) const;
+
+   template <class T> void unloadTileToBsq(T, // dummy tmeplate variable
+                                           void* dest,
+                                           const ossimIrect& dest_rect,
+                                           const ossimIrect& clip_rect) const;
+
+   template <class T> void unloadBand(T, // dummy tmeplate variable
+                                      void* dest,
+                                      const ossimIrect& dest_rect,
+                                      const ossimIrect& clip_rect,
+                                      ossim_uint32 band) const;
+   
+   virtual void initializeDefaults();
+
+   virtual bool isEqualTo(const ossimDataObject& rhs,
+                          bool deepTest=false)const;
+   
+   bool hasSameDimensionsAs(ossimImageData* data)const
+   {
+      if(!data) return false;
+      return ((theNumberOfSpatialComponents ==
+               data->theNumberOfSpatialComponents)&
+              (theSpatialExtents[0] == data->theSpatialExtents[0])&&
+              (theSpatialExtents[1] == data->theSpatialExtents[1])&&
+              (theScalarType == data->theScalarType));
+   }
+   
+   /**
+    * Have a null pixel value per band.
+    */
+   ossim_float64* theNullPixelValue;
+
+   /**
+    * Have a min pixel value per band.
+    */
+   ossim_float64* theMinPixelValue;
+
+   /**
+    * Have a max pixel value per band.
+    */
+   ossim_float64* theMaxPixelValue;
+   
+   ossimIpt       theOrigin;
+   
+private:
+   /**
+    * @note disallow 
+    */
+   const ossimImageData& operator=(const ossimImageData &rhs);
+   
+TYPE_DATA
+};
+
+inline void ossimImageData::getPixFromNorm(ossim_int32& pixel,
+                                           ossim_float32 normPix,
+                                           ossim_uint32 band) const
+{
+   // If norm pix is 0.0 or negative make if null.
+   ossim_float32 p = theNullPixelValue[band]; 
+   
+   if (normPix > 0.0)
+   {
+      // un-normalize...
+      p = normPix * (theMaxPixelValue[band]-theMinPixelValue[band]+1.0);
+      
+      // handle negative min values.
+      p = p + theMinPixelValue[band] - 1.0;  
+      
+      // Clamp to  max.
+      if (p > theMaxPixelValue[band]) p = theMaxPixelValue[band];
+   
+      //***
+      // If p is less than min, make it min as it wasn't a null before.
+      // Add or subtract 0.5 to p otherwise as it will be cast to an
+      // int for proper rounding.
+      //***
+      p = p > theMinPixelValue[band] ?
+          ( p<0.0 ? p-0.5 : p+0.5 ) :
+          theMinPixelValue[band];
+   }
+
+   // Cast back to an int.
+   pixel = static_cast<ossim_int32>(p);
+}
+
+inline void ossimImageData::getPixFromNorm(ossim_int32& pixel,
+                                           ossim_float64 normPix,
+                                           ossim_uint32 band) const
+{
+   // If norm pix is 0.0 or negative make if null.
+   ossim_float64 p = theNullPixelValue[band]; 
+   
+   if (normPix > 0.0)
+   {
+      // un-normalize...
+      p = normPix * (theMaxPixelValue[band]-theMinPixelValue[band]+1.0);
+      
+      // handle negative min values.
+      p = p + theMinPixelValue[band] - 1.0;  
+      
+      // Clamp to  max.
+      if (p > theMaxPixelValue[band]) p = theMaxPixelValue[band];
+   
+      //***
+      // If p is less than min, make it min as it wasn't a null before.
+      // Add or subtract 0.5 to p otherwise as it will be cast to an
+      // int for proper rounding.
+      //***
+      p = p > theMinPixelValue[band] ?
+          ( p<0.0 ? p-0.5 : p+0.5 ) :
+          theMinPixelValue[band];
+   }
+
+   // Cast back to an int.
+   pixel = static_cast<ossim_int32>(p);
+}
+
+inline void ossimImageData::getNormFromPix(ossim_int32 pixel,
+                                           ossim_float32&  normPix,
+                                           ossim_uint32 band) const
+{
+   if      (pixel == theNullPixelValue[band]) normPix = 0.0;
+   else if (pixel >= theMaxPixelValue[band])  normPix = 1.0;
+
+   //***
+   // Normalize...
+   // Note that this will shift any negatives to positive prior to dividing.
+   //***
+   else normPix = ( (pixel-theMinPixelValue[band]+1) /
+                    (theMaxPixelValue[band] - theMinPixelValue[band] + 1.0) );
+}
+
+inline void ossimImageData::getNormFromPix(ossim_int32  pixel,
+                                           ossim_float64&   normPix,
+                                           ossim_uint32 band) const
+{
+   if      (pixel == theNullPixelValue[band]) normPix = 0.0;
+   else if (pixel >= theMaxPixelValue[band])  normPix = 1.0;
+
+   //***
+   // Normalize...
+   // Note that this will shift any negatives to positive prior to dividing.
+   //***
+   else normPix = ( (pixel-theMinPixelValue[band]+1) /
+                    (theMaxPixelValue[band] - theMinPixelValue[band] + 1.0) );
+}
+
+inline ossimIrect ossimImageData::getImageRectangle() const
+{
+   ossimIpt lr(theOrigin.x + getWidth()  - 1,
+               theOrigin.y + getHeight() - 1);
+   
+   return ossimIrect(theOrigin, lr);
+}
+
+inline const ossim_float64* ossimImageData::getNullPix()const
+{
+   return theNullPixelValue;
+}
+
+inline const ossim_float64* ossimImageData::getMinPix()const
+{
+   return theMinPixelValue;
+}
+
+inline const ossim_float64* ossimImageData::getMaxPix()const
+{
+   return theMaxPixelValue;
+}
+
+inline ossim_float64 ossimImageData::getNullPix(ossim_uint32 band) const
+{
+   return theNullPixelValue[band];
+}
+
+inline ossim_float64 ossimImageData::getMinPix(ossim_uint32 band) const
+{
+   return theMinPixelValue[band];
+}
+
+inline ossim_float64 ossimImageData::getMaxPix(ossim_uint32 band) const
+{
+   return theMaxPixelValue[band];
+}
+
+inline ossim_uint32 ossimImageData::getHashId()const
+{
+   const unsigned char *bufx = (unsigned char*)(&theOrigin.x);
+   const unsigned char *bufy = (unsigned char*)(&theOrigin.y);
+   return (ossim_uint32)(bufx[0]*101 + bufx[1]*103 +
+                         bufx[2]*107 + bufx[3]*109 +
+                         bufy[0]*139 + bufy[1]*149 +
+                         bufy[2]*151 + bufy[3]*157);
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageDataHelper.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageDataHelper.cpp
new file mode 100644
index 0000000000..32803b4921
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageDataHelper.cpp
@@ -0,0 +1,604 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageDataHelper.cpp,v 1.6 2005/05/09 12:39:38 dburken Exp $
+#include "ossimImageDataHelper.h"
+#include "base/data_types/ossimPolyArea2d.h"
+#include "base/data_types/ossimLine.h"
+#include <vector>
+#include <algorithm>
+
+ossimImageDataHelper::ossimImageDataHelper(ossimImageData* imageData)
+{
+   setImageData(imageData);
+}
+
+
+void ossimImageDataHelper::setImageData(ossimImageData* imageData)
+{
+   theImageData = imageData;
+   if(theImageData)
+   {
+      theImageRectangle     = theImageData->getImageRectangle();
+      thePolyImageRectangle = ossimPolyArea2d(theImageRectangle.ul(),
+                                              theImageRectangle.ur(),
+                                              theImageRectangle.lr(),
+                                              theImageRectangle.ll());
+      theOrigin = theImageRectangle.ul();
+   }
+}
+
+void ossimImageDataHelper::copyInputToThis(const void* input,
+                                           const ossimPolygon& region,
+                                           bool clipPoly)
+{
+   switch(theImageData->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         copyInputToThis(reinterpret_cast<const ossim_uint8*>(input),
+                         region,
+                         clipPoly);
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         copyInputToThis(reinterpret_cast<const ossim_uint16*>(input),
+                         region,
+                         clipPoly);
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         copyInputToThis(reinterpret_cast<const ossim_sint16*>(input),
+                         region,
+                         clipPoly);
+         break;
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         copyInputToThis(reinterpret_cast<const float*>(input),
+                         region,
+                         clipPoly);
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         copyInputToThis(reinterpret_cast<const double*>(input),
+                         region,
+                         clipPoly);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         break;
+      }
+   }   
+}
+
+void ossimImageDataHelper::fill(const ossimRgbVector& color,
+                                std::vector<ossimPolygon>& regionList,
+                                bool clipPoly)
+{
+   int i = 0;
+
+   for(i = 0; i < (int)regionList.size();++i)
+   {
+      fill(color,
+           regionList[i],
+           clipPoly);
+   }
+}
+
+
+void ossimImageDataHelper::fill(const double* values,
+                                std::vector<ossimPolygon>& regionList,
+                                bool clipPoly)
+{
+   int i = 0;
+
+   for(i = 0; i < (int)regionList.size();++i)
+   {
+      fill(values,
+           regionList[i],
+           clipPoly);
+   }
+}
+
+void ossimImageDataHelper::fill(const ossimRgbVector& color,
+                                const ossimPolygon& region,
+                                bool clipPoly)
+{
+   double colorArray[3];
+
+   colorArray[0] = color.getR();
+   colorArray[1] = color.getG();
+   colorArray[2] = color.getB();
+   switch(theImageData->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         if(theImageData->getNumberOfBands() <= 3)
+         {
+            fill(static_cast<ossim_uint8>(0),
+                 (const double*)colorArray,
+                 region,
+                 clipPoly);
+            
+         }
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      case OSSIM_SSHORT16:
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      default:
+      {
+         break;
+      }
+   }
+}
+
+void ossimImageDataHelper::fill(const ossimRgbVector& color,
+                                const ossimIrect& region,
+                                bool clipPoly)
+{
+   double colorArray[3];
+
+   colorArray[0] = color.getR();
+   colorArray[1] = color.getG();
+   colorArray[2] = color.getB();
+
+   switch(theImageData->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         if(theImageData->getNumberOfBands() <= 3)
+         {
+            fill(static_cast<ossim_uint8>(0),
+                 colorArray,
+                 region,
+                 clipPoly);
+            
+         }
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      case OSSIM_SSHORT16:
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         break;
+      }
+      default:
+         break;
+   }
+}
+
+void ossimImageDataHelper::fill(const double*  values,
+                                const ossimPolygon& region,
+                                bool clipPoly)
+{
+   switch(theImageData->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         fill(static_cast<ossim_uint8>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         fill(static_cast<ossim_uint16>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         fill(static_cast<ossim_sint16>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         fill(static_cast<float>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         fill(static_cast<double>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         break;
+      }
+   }
+}
+
+void ossimImageDataHelper::fill(const double*  values,
+                                const ossimIrect& region,
+                                bool clipPoly)
+{
+   switch(theImageData->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         fill(static_cast<ossim_uint8>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         fill(static_cast<ossim_uint16>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         fill(static_cast<ossim_sint16>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         fill(static_cast<float>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         fill(static_cast<double>(0),
+              values,
+              region,
+              clipPoly);
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         break;
+      }
+   }
+}
+
+
+
+template <class T>
+void ossimImageDataHelper::copyInputToThis(const T* inputBuf,
+                                           const ossimPolygon& region,
+                                           bool clipPoly)
+{
+   if(clipPoly)
+   {
+      ossimPolyArea2d polyArea(region);
+      ossimPolyArea2d clipArea = polyArea&thePolyImageRectangle;
+      
+      vector<ossimPolygon> clipList;
+      clipArea.getAllVisiblePolygons(clipList);
+      int i = 0;
+            
+      for(i = 0; i < (int)clipList.size();++i)
+      {
+         copyInputToThis(inputBuf,
+                         clipList[i]);
+      }
+   }
+   else
+   {
+      copyInputToThis(inputBuf,
+                      region);
+   }
+}
+
+template <class T>
+void ossimImageDataHelper::copyInputToThis(const T* inputBuf,
+                                           const ossimPolygon& region)
+{ 
+   int n;
+   int i;
+   int y;
+   ossim_int32 miny, maxy, minx, maxx;
+   int x1, y1;
+   int x2, y2;
+   int ind1, ind2;
+   int ints;
+   vector<int> polyInts;
+   T* buf = reinterpret_cast<T*>(theImageData->getBuf());
+   
+   ossim_int32 blockLength=theImageData->getWidth()*theImageData->getHeight();
+   ossim_int32 bandOffset = 0;
+   
+   region.getIntegerBounds(minx, miny, maxx, maxy);
+   ossim_int32 rowOffset = (miny-theOrigin.y)*theImageData->getWidth();
+   n = region.getVertexCount();
+   /* Fix in 1.3: count a vertex only once */
+   for (y = miny; (y <= maxy); y++)
+   {
+      polyInts.clear();
+      ints = 0;
+      for (i = 0; (i < n); i++)
+      {
+         if (!i)
+         {
+            ind1 = n - 1;
+            ind2 = 0;
+         }
+         else
+         {
+            ind1 = i - 1;
+            ind2 = i;
+         }
+         y1 = irint(region[ind1].y);
+         y2 = irint(region[ind2].y);
+         if (y1 < y2)
+         {
+            x1 = irint(region[ind1].x);
+            x2 = irint(region[ind2].x);
+         }
+         else if (y1 > y2)
+         {
+            y2 = irint(region[ind1].y);
+            y1 = irint(region[ind2].y);
+            x2 = irint(region[ind1].x);
+            x1 = irint(region[ind2].x);
+         }
+         else
+         {
+            continue;
+         }
+         if ((y >= y1) && (y < y2))
+         {
+            polyInts.push_back((y - y1) * (x2 - x1) / (y2 - y1) + x1);
+         }
+         else if ((y == maxy) && (y > y1) && (y <= y2))
+         {
+            polyInts.push_back((y - y1) * (x2 - x1) / (y2 - y1) + x1);
+         }
+      }
+      std::sort(polyInts.begin(), polyInts.end());
+      
+      for (i = 0; (i < (int)polyInts.size()); i += 2)
+      {
+         ossim_int32 startX = polyInts[i]-theOrigin.x;
+         ossim_int32 endX   = polyInts[i+1]-theOrigin.x;
+         while(startX <= endX)
+         {
+            bandOffset = 0;
+	    int band;
+            for(band = 0; band < (ossim_int32)theImageData->getNumberOfBands();++band)
+            {
+               buf[rowOffset+bandOffset+startX] = (inputBuf[rowOffset+bandOffset+startX]);
+               bandOffset += blockLength;
+            }
+            ++startX;
+         }
+      }
+      rowOffset += theImageData->getWidth();
+   }
+}
+
+template <class T>
+void ossimImageDataHelper::fill(T dummyVariable,
+                                const double* values,
+                                const ossimPolygon& region,
+                                bool clipPoly)
+{
+   if(clipPoly)
+   {
+      ossimPolyArea2d polyArea(region);
+      ossimPolyArea2d clipArea = polyArea&thePolyImageRectangle;
+      
+      vector<ossimPolygon> clipList;
+      clipArea.getAllVisiblePolygons(clipList);
+            
+      int i = 0;
+      for(i = 0; i < (int)clipList.size();++i)
+      {
+         fill(dummyVariable,
+              values,
+              clipList[i]);
+      }
+   }
+   else
+   {
+      fill(dummyVariable,
+           values,
+           region);
+   }
+}
+
+template <class T>
+void ossimImageDataHelper::fill(T dummyVariable,
+                                const double* values,
+                                const ossimIrect& region,
+                                bool clipPoly)
+{
+   if(clipPoly)
+   {
+      fill(dummyVariable,
+           values,
+           region.clipToRect(theImageData->getImageRectangle()));
+   }
+   else
+   {
+      fill(dummyVariable,
+           values,
+           region);
+   }
+}
+
+template <class T>
+void ossimImageDataHelper::fill(T dummyVariable,
+                                const double* values,
+                                const ossimPolygon& region)
+{
+   int n;
+   int i;
+   int y;
+   ossim_int32 miny, maxy, minx, maxx;
+   int x1, y1;
+   int x2, y2;
+   int ind1, ind2;
+   int ints;
+   vector<int> polyInts;
+   T* buf = reinterpret_cast<T*>(theImageData->getBuf());
+   
+   ossim_int32 blockLength=theImageData->getWidth()*theImageData->getHeight();
+   ossim_int32 bandOffset = 0;
+   
+   region.getIntegerBounds(minx, miny, maxx, maxy);
+   ossim_int32 rowOffset = (miny-theOrigin.y)*theImageData->getWidth();
+   n = region.getVertexCount();
+   /* Fix in 1.3: count a vertex only once */
+   for (y = miny; (y <= maxy); y++)
+   {
+      polyInts.clear();
+      ints = 0;
+      for (i = 0; (i < n); i++)
+      {
+         if (!i)
+         {
+            ind1 = n - 1;
+            ind2 = 0;
+         }
+         else
+         {
+            ind1 = i - 1;
+            ind2 = i;
+         }
+         y1 = irint(region[ind1].y);
+         y2 = irint(region[ind2].y);
+         if (y1 < y2)
+         {
+            x1 = irint(region[ind1].x);
+            x2 = irint(region[ind2].x);
+         }
+            else if (y1 > y2)
+            {
+               y2 = irint(region[ind1].y);
+               y1 = irint(region[ind2].y);
+               x2 = irint(region[ind1].x);
+               x1 = irint(region[ind2].x);
+            }
+         else
+         {
+            continue;
+         }
+         if ((y >= y1) && (y < y2))
+         {
+            polyInts.push_back((y - y1) * (x2 - x1) / (y2 - y1) + x1);
+         }
+         else if ((y == maxy) && (y > y1) && (y <= y2))
+         {
+            polyInts.push_back((y - y1) * (x2 - x1) / (y2 - y1) + x1);
+         }
+      }
+      std::sort(polyInts.begin(), polyInts.end());
+      
+      for (i = 0; (i < (int)polyInts.size()); i += 2)
+      {
+         ossim_int32 startX = ossimAbs(polyInts[i]-theOrigin.x);
+         ossim_int32 endX   = ossimAbs(polyInts[i+1]-theOrigin.x);
+         while(startX <= endX)
+         {
+            bandOffset = 0;
+	    int band;
+            for(band = 0; band < (int)theImageData->getNumberOfBands();++band)
+            {
+               buf[rowOffset+bandOffset+startX] = (T)(values[band]);
+               bandOffset += blockLength;
+            }
+            ++startX;
+         }
+      }
+      rowOffset += theImageData->getWidth();
+   }
+}
+
+template <class T>
+void ossimImageDataHelper::fill(T dummyVariable,
+                                const double* values,
+                                const ossimIrect& region)
+{
+   T* buf = reinterpret_cast<T*>(theImageData->getBuf());
+   
+   ossim_int32 blockLength=theImageData->getWidth()*theImageData->getHeight();
+   ossim_int32 bandOffset = 0;
+   ossim_int32 miny,maxy;
+   ossim_int32 minx, maxx;
+   ossim_int32 y = 0;
+   miny = region.ul().y-theOrigin.y;
+   maxy = region.lr().y-theOrigin.y;
+   minx = region.ul().x-theOrigin.x;
+   maxx = region.lr().x-theOrigin.x;
+   
+   ossim_int32 rowOffset = (miny)*theImageData->getWidth();
+   ossim_int32 startX = minx;
+   ossim_int32 endX   = maxx;
+   ossim_int32 bands  = (ossim_int32)theImageData->getNumberOfBands();
+
+   for (y = miny; (y <= maxy); ++y)
+   {
+      startX=minx;
+      while(startX <= endX)
+      {
+         bandOffset = 0;
+	 int band = 0;
+         for(band = 0; band < bands;++band)
+         {
+            buf[rowOffset+bandOffset+startX] = (T)(values[band]);
+            bandOffset += blockLength;
+         }
+         ++startX;
+      }
+      rowOffset += theImageData->getWidth();
+   }
+}
+ 
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageDataHelper.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageDataHelper.h
new file mode 100644
index 0000000000..defe2e39bf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageDataHelper.h
@@ -0,0 +1,115 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimImageDataHelper.h,v 1.2 2002/05/03 16:41:25 gpotts Exp $
+#ifndef ossimImageDataHelper_HEADER
+#define ossimImageDataHelper_HEADER
+
+#include "ossimImageData.h"
+#include "base/data_types/ossimPolyArea2d.h"
+#include "base/data_types/color_space/ossimRgbVector.h"
+
+class ossimImageDataHelper
+{
+public:
+   /*!
+    * This must be a valid image data object
+    */
+   ossimImageDataHelper(ossimImageData* imageData);
+
+   void setImageData(ossimImageData* imageData);
+
+   void fill(const double* values,
+             const ossimIrect& rect,
+             bool clipPoly=true);
+
+   void fill(const double* values,
+             std::vector<ossimPolygon>& regionList,
+             bool clipPoly=true);
+   
+   void fill(const ossimRgbVector& color,
+             std::vector<ossimPolygon>& regionList,
+             bool clipPoly=true);
+   
+   void fill(const ossimRgbVector& color,
+             const ossimIrect& rect,
+             bool clipPoly=true);
+   /*!
+    * Values must be of the same type as the image data that
+    * we are writing to.
+    */
+   void fill(const double*  values,
+             const ossimPolygon& region,
+             bool clipPoly=true);
+
+   void fill(const ossimRgbVector& color,
+             const ossimPolygon& region,
+             bool clipPoly=true);
+   /*!
+    * The input is assumed to have the same origin, size and scalar
+    * as this object.  This will implement a selection
+    */
+   void copyInputToThis(const void* input,
+                        const ossimPolygon& region,
+                        bool clipPoly=true);
+
+   ossimImageData* theImageData;
+   
+
+protected:
+   ossimIpt        theOrigin;
+   ossimIrect      theImageRectangle;
+   ossimPolyArea2d thePolyImageRectangle;
+   
+   template <class T>
+   void fill(T dummyVariable,
+             const double* values,
+             const ossimPolygon& region,
+             bool clipPoly);
+
+   template <class T>
+   void fill(T dummyVariable,
+             const double* values,
+             const ossimIrect& region,
+             bool clipPoly);
+   
+   template <class T>
+   void copyInputToThis(const T* inputBuf,
+                        const ossimPolygon& region,
+                        bool clipPoly);
+
+   template <class T>
+   void fill(T dummyVariable,
+             const double* values,
+             const ossimPolygon& region);
+   template <class T>
+   void fill(T dummyVariable,
+             const double* values,
+             const ossimIrect& region);
+   
+   template <class T>
+   void copyInputToThis(const T* inputBuf,
+                        const ossimPolygon& region);
+
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageDisplayWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageDisplayWriter.cpp
new file mode 100644
index 0000000000..80c87cb5a8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageDisplayWriter.cpp
@@ -0,0 +1,52 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Frank Warmerdam (warmerdam@pobox.com)
+//
+// Description:
+//
+// Contains class declaration for ossimImageWriter
+//*******************************************************************
+//  $Id: ossimImageDisplayWriter.cpp,v 1.3 2003/05/13 11:31:03 dburken Exp $
+#include "ossimImageDisplayWriter.h"
+
+RTTI_DEF3(ossimImageDisplayWriter, "ossimImageDisplayWriter", ossimImageWriter, ossimDisplayInterface, ossimConnectableObjectListener);
+
+ossimImageDisplayWriter::ossimImageDisplayWriter(ossimObject* owner)
+   :ossimImageWriter(owner,
+                     1,
+                     0,
+                     true,
+                     true),
+    ossimConnectableObjectListener()
+{
+}
+
+ossimImageDisplayWriter::ossimImageDisplayWriter(ossimObject* owner,
+                                                 ossim_uint32 numberOfInputs,
+                                                 ossim_uint32 numberOfOutputs,
+                                                 bool inputListIsFixed,
+                                                 bool outputListIsFixed)
+   : ossimImageWriter(owner,
+                      numberOfInputs,
+                      numberOfOutputs,
+                      inputListIsFixed,
+                      outputListIsFixed),
+     ossimConnectableObjectListener()
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageDisplayWriter.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageDisplayWriter.h
new file mode 100644
index 0000000000..4e969fc789
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageDisplayWriter.h
@@ -0,0 +1,90 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Frank Warmerdam (warmerdam@pobox.com)
+//
+// Description:
+//
+// Contains class declaration for ossimImageWriter
+//*******************************************************************
+//  $Id: ossimImageDisplayWriter.h,v 1.13 2003/05/13 11:31:03 dburken Exp $
+#ifndef ossimImageDisplayWriter_HEADER
+#define ossimImageDisplayWriter_HEADER
+
+#include "imaging/ossimImageWriter.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/common/events/ossimConnectableObjectListener.h"
+#include "base/common/ossimDisplayInterface.h"
+#include "base/common/events/ossimObjectEvents.h"
+#include "base/common/events/ossimProcessProgressEvent.h"
+
+class ossimImageDisplayWriter :  public ossimImageWriter,
+                                 public ossimDisplayInterface,
+                                 public ossimConnectableObjectListener
+
+{
+public:
+   virtual ~ossimImageDisplayWriter(){}
+   
+
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const
+      {
+         
+         return (object&& PTR_CAST(ossimImageSourceInterface, object));
+      }
+   virtual void setOutputName(const ossimString& out)
+      {
+         setTitle(out);
+      }
+
+   /*!
+    * Sets the title of a display.
+    */
+   virtual void setTitle( const ossimString& title )=0;
+
+   /*!
+    * will return true if its minimized
+    */
+   virtual bool isMinimized()const=0;
+
+   virtual bool isMaximized()const=0;
+   /*!
+    * Will repaint the display
+    */
+   virtual void refreshDisplay()=0;
+
+   
+   virtual void minimize()=0;
+
+   virtual void maximize()=0;
+   /*!
+    * Will show a display
+    */
+   virtual void show()=0;
+   
+protected:
+   ossimImageDisplayWriter(ossimObject* owner=NULL);
+   ossimImageDisplayWriter(ossimObject* owner,
+                           ossim_uint32 numberOfInputs,
+                           ossim_uint32 numberOfOutputs,
+                           bool inputListIsFixed,
+                           bool outputListIsFixed);
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageMetaData.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageMetaData.cpp
new file mode 100644
index 0000000000..34b5c3e4ba
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageMetaData.cpp
@@ -0,0 +1,476 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class definition for ossimImageMetaData.
+// 
+//*******************************************************************
+//  $Id: ossimImageMetaData.cpp,v 1.14 2005/10/16 21:18:58 dburken Exp $
+#include <vector>
+#include <algorithm>
+#include <imaging/ossimImageMetaData.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimString.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug("ossimImageMetaData:debug");
+
+ossimImageMetaData::ossimImageMetaData()
+   :theNullPixelArray(NULL),
+    theMinPixelArray(NULL),
+    theMaxPixelArray(NULL),
+    theScalarType(OSSIM_SCALAR_UNKNOWN),
+    theNumberOfBands(0)
+{
+}
+
+ossimImageMetaData::ossimImageMetaData(ossimScalarType aType,
+				       ossim_uint32 numberOfBands)
+   :theNullPixelArray(NULL),
+    theMinPixelArray(NULL),
+    theMaxPixelArray(NULL),
+    theScalarType(aType),
+    theNumberOfBands(numberOfBands)
+{
+   if(theNumberOfBands)
+   {
+      theNullPixelArray = new double[theNumberOfBands];
+      theMinPixelArray  = new double[theNumberOfBands];
+      theMaxPixelArray  = new double[theNumberOfBands];
+      
+      setDefaultsForArrays();
+   }
+}
+
+ossimImageMetaData::ossimImageMetaData(const ossimImageMetaData& rhs)
+{
+   assign(rhs);
+}
+
+ossimImageMetaData::~ossimImageMetaData()
+{
+  clear();
+}
+
+void ossimImageMetaData::clear()
+{
+   if(theNullPixelArray)
+   {
+      delete [] theNullPixelArray;
+      theNullPixelArray = NULL;
+   }
+   if(theMinPixelArray)
+   {
+      delete [] theMinPixelArray;
+      theMinPixelArray = NULL;
+   }
+   if(theMaxPixelArray)
+   {
+      delete [] theMaxPixelArray;
+      theMaxPixelArray = NULL;
+   }
+   theScalarType    = OSSIM_SCALAR_UNKNOWN;
+   theNumberOfBands = 0;
+}
+
+void ossimImageMetaData::clearBandInfo()
+{
+   if(theNullPixelArray)
+   {
+      delete [] theNullPixelArray;
+      theNullPixelArray = NULL;
+   }
+   if(theMinPixelArray)
+   {
+      delete [] theMinPixelArray;
+      theMinPixelArray = NULL;
+   }
+   if(theMaxPixelArray)
+   {
+      delete [] theMaxPixelArray;
+      theMaxPixelArray = NULL;
+   }
+   theScalarType    = OSSIM_SCALAR_UNKNOWN;
+   theNumberOfBands = 0;
+}
+
+void ossimImageMetaData::setDefaultsForArrays()
+{
+   ossim_uint32 i=0;
+   
+   for(i = 0; i < theNumberOfBands; ++i)
+   {
+      theNullPixelArray[i] = ossimGetDefaultNull(theScalarType);
+      theMinPixelArray[i]  = ossimGetDefaultMin(theScalarType);
+      theMaxPixelArray[i]  = ossimGetDefaultMax(theScalarType);
+   }
+}
+
+void ossimImageMetaData::setNumberOfBands(ossim_uint32 numberOfBands)
+{
+   if(theNullPixelArray)
+   {
+      delete [] theNullPixelArray;
+      theNullPixelArray = NULL;
+   }
+   if(theMinPixelArray)
+   {
+      delete [] theMinPixelArray;
+      theMinPixelArray = NULL;
+   }
+   if(theMaxPixelArray)
+   {
+      delete [] theMaxPixelArray;
+      theMaxPixelArray = NULL;
+   }
+   
+   theNumberOfBands = numberOfBands;
+
+   if(theNumberOfBands)
+   {
+      theNullPixelArray = new double[theNumberOfBands];
+      theMinPixelArray  = new double[theNumberOfBands];
+      theMaxPixelArray  = new double[theNumberOfBands];
+   
+      setDefaultsForArrays();
+   }
+}
+
+void ossimImageMetaData::assign(const ossimImageMetaData& rhs)
+{
+   if(this != &rhs)
+   {
+      clear();
+      theNumberOfBands = rhs.getNumberOfBands();
+      theScalarType    = rhs.getScalarType();
+      
+      if(theNumberOfBands)
+      {
+         theNullPixelArray = new double[theNumberOfBands];
+         theMinPixelArray  = new double[theNumberOfBands];
+         theMaxPixelArray  = new double[theNumberOfBands];
+         
+         std::copy(rhs.getNullPixelArray(),
+                   rhs.getNullPixelArray()+theNumberOfBands,
+                   theNullPixelArray);
+         std::copy(rhs.getMinPixelArray(),
+                   rhs.getMinPixelArray()+theNumberOfBands,
+                   theMinPixelArray);
+         std::copy(rhs.getMaxPixelArray(),
+                   rhs.getMaxPixelArray()+theNumberOfBands,
+                   theMaxPixelArray);
+      }
+   }
+}
+
+bool ossimImageMetaData::loadState(const ossimKeywordlist& kwl,
+				   const char* prefix)
+{
+   static const char MODULE[] = "ossimImageMetaData::loadState";
+
+   if (traceDebug())
+   {
+      CLOG << " Entered..."
+           << "\nkwl:\n" << kwl
+           << "\nprefix:  " << (prefix?prefix:"") << endl;
+   }
+   
+   bool result = true;
+   clear();
+  
+   ossim_int32 scalar =
+      ossimScalarTypeLut::instance()->getEntryNumber(kwl, prefix);
+   if (scalar == ossimLookUpTable::NOT_FOUND)
+   {
+      theScalarType = OSSIM_SCALAR_UNKNOWN;
+   }
+   else
+   {
+      theScalarType = static_cast<ossimScalarType>(scalar);
+   }
+
+   if (traceDebug())
+   {
+      CLOG << "DEBUG:"
+           << "\ntheScalarType:  " << theScalarType << endl;
+   }
+   
+   const char* kwlLookup = kwl.find(prefix, ossimKeywordNames::NUMBER_BANDS_KW);
+   if (kwlLookup)
+   {
+      theNumberOfBands = ossimString(kwlLookup).toInt();
+      setNumberOfBands(theNumberOfBands);
+   }
+  
+   loadBandInfo(kwl, prefix);
+
+   if(!theNumberOfBands)
+   {
+      result = false;
+   }
+   return result;
+}
+
+void ossimImageMetaData::loadBandInfo(const ossimKeywordlist& kwl,
+                                      const char* prefix)
+{
+   ossimString copyPrefix = prefix;
+   ossimString regExpression =  ossimString("^(") + copyPrefix + "band[0-9]+.)";
+   vector<ossimString> keys =
+      kwl.getSubstringKeyList( regExpression );
+   
+   ossim_uint32 numberOfBands = keys.size();
+   theMinValuesValidFlag  = true;
+   theMaxValuesValidFlag  = true;
+   theNullValuesValidFlag = true;
+
+   if(!numberOfBands)
+   {
+      theMinValuesValidFlag  = false;
+      theMaxValuesValidFlag  = false;
+      theNullValuesValidFlag = false;
+      return;
+   }
+   if((!theNumberOfBands)||
+      (theNumberOfBands != numberOfBands))
+   {
+      setNumberOfBands(numberOfBands);
+   }
+   
+   int offset = (copyPrefix+"band").size();
+   int idx = 0;
+   std::vector<int> theNumberList(numberOfBands);
+   for(idx = 0; idx < (int)theNumberList.size();++idx)
+     {
+       ossimString numberStr(keys[idx].begin() + offset,
+			     keys[idx].end());
+       theNumberList[idx] = numberStr.toInt();
+     }
+   std::sort(theNumberList.begin(), theNumberList.end());
+   for(idx=0;idx < (int)theNumberList.size();++idx)
+   {
+      ossimString newPrefix = copyPrefix;
+      newPrefix += ossimString("band");
+      newPrefix += ossimString::toString(theNumberList[idx]);
+      newPrefix += ossimString(".");
+
+      const char* minValue = kwl.find(newPrefix.c_str(),
+                                      ossimKeywordNames::MIN_VALUE_KW);
+      const char* maxValue = kwl.find(newPrefix.c_str(),
+                                      ossimKeywordNames::MAX_VALUE_KW);
+      const char* nullValue = kwl.find(newPrefix.c_str(),
+                                       ossimKeywordNames::NULL_VALUE_KW);
+
+      if(minValue)
+      {
+         theMinPixelArray[idx] = ossimString(minValue).toDouble();
+      }
+      else
+      {
+         theMinValuesValidFlag = false;
+         theMinPixelArray[idx] = ossimGetDefaultMin(theScalarType);
+      }
+      if(maxValue)
+      {
+         theMaxPixelArray[idx] = ossimString(maxValue).toDouble();
+      }
+      else
+      {
+         theMaxValuesValidFlag = false;
+         theMaxPixelArray[idx] = ossimGetDefaultMax(theScalarType);
+      }
+      if(nullValue)
+      {
+         theNullPixelArray[idx] = ossimString(nullValue).toDouble();
+      }
+      else
+      {
+         theNullValuesValidFlag = false;
+         theNullPixelArray[idx] = ossimGetDefaultNull(theScalarType);
+      }
+   }
+}
+
+bool ossimImageMetaData::saveState(ossimKeywordlist& kwl,
+				   const char* prefix)const
+{
+   if(theNullPixelArray&&theMinPixelArray&&theMaxPixelArray)
+   {
+      ossim_int32 band = 0;
+      
+      for (band=0; band<(ossim_int32)theNumberOfBands; ++band)
+      {
+         ossimString kwMin = (ossimKeywordNames::BAND_KW +
+                              ossimString::toString(band+1) + "." +
+                              ossimKeywordNames::MIN_VALUE_KW);
+         ossimString kwMax = (ossimKeywordNames::BAND_KW +
+                              ossimString::toString(band+1) + "." +
+                              ossimKeywordNames::MAX_VALUE_KW);
+         ossimString kwNull = (ossimKeywordNames::BAND_KW +
+                               ossimString::toString(band+1) + "." +
+                               ossimKeywordNames::NULL_VALUE_KW);
+         
+         kwl.add(prefix,
+                 kwMin.c_str(),
+                 theMinPixelArray[band],
+                 true);
+         kwl.add(prefix,
+                 kwMax.c_str(),
+                 theMaxPixelArray[band],
+                 true);
+         kwl.add(prefix,
+                 kwNull.c_str(),
+                 theNullPixelArray[band],
+                 true);
+      }
+      kwl.add(prefix,
+	      ossimKeywordNames::NUMBER_BANDS_KW,
+	      (ossim_int32)theNumberOfBands,
+	      true);
+      kwl.add(prefix,
+	      ossimKeywordNames::SCALAR_TYPE_KW,
+	      (ossimScalarTypeLut::instance()->getEntryString(theScalarType)),
+	      true);
+   }
+   
+   return true;
+}
+
+ossim_uint32 ossimImageMetaData::getNumberOfBands()const
+{
+   return theNumberOfBands;
+}
+
+void ossimImageMetaData::setScalarType(ossimScalarType aType)
+{
+   theScalarType = aType;
+}
+
+ossimScalarType ossimImageMetaData::getScalarType()const
+{
+   return theScalarType;
+}
+
+double ossimImageMetaData::getMinPix(ossim_uint32 band)const
+{
+   if(theNumberOfBands&&theMinPixelArray)
+   {
+      ossim_uint32 i = ossimMin(band, (ossim_uint32)(theNumberOfBands-1));
+      
+      return theMinPixelArray[i];
+   }
+   return ossimGetDefaultMin(theScalarType);
+}
+
+void ossimImageMetaData::setMinPix(ossim_uint32 band, double pix)
+{
+   if((band < theNumberOfBands)&&(theMinPixelArray))
+   {
+      theMinPixelArray[band] = pix;
+   }
+}
+
+void ossimImageMetaData::setMaxPix(ossim_uint32 band, double pix)
+{
+   if((band < theNumberOfBands)&&
+      (theMaxPixelArray))
+   {
+      theMaxPixelArray[band] = pix;
+   }
+}
+
+void ossimImageMetaData::setNullPix(ossim_uint32 band, double pix)
+{
+   if((band < theNumberOfBands)&&(theNullPixelArray))
+   {
+      theNullPixelArray[band] = pix;
+   }
+}
+
+double ossimImageMetaData::getMaxPix(ossim_uint32 band)const
+{
+   if(theNumberOfBands&&theMaxPixelArray)
+   {
+      ossim_uint32 i = ossimMin(band, (ossim_uint32)(theNumberOfBands-1));
+      
+      return theMaxPixelArray[i];
+   }
+   return ossimGetDefaultMax(theScalarType);
+}
+
+double ossimImageMetaData::getNullPix(ossim_uint32 band)const
+{
+   if(theNumberOfBands&&theNullPixelArray)
+   {
+      ossim_uint32 i = ossimMin(band, (ossim_uint32)(theNumberOfBands-1));
+      
+      return theNullPixelArray[i];
+   }
+   return ossimGetDefaultNull(theScalarType);
+}
+
+const double* ossimImageMetaData::getMinPixelArray()const
+{
+   return theMinPixelArray;
+}
+const double* ossimImageMetaData::getMaxPixelArray()const
+{
+   return theMaxPixelArray;
+}
+
+const double* ossimImageMetaData::getNullPixelArray()const
+{
+   return theNullPixelArray;
+}
+
+void ossimImageMetaData::setMinValuesValid(bool flag)
+{
+   theMinValuesValidFlag = flag;
+}
+
+void ossimImageMetaData::setMaxValuesValid(bool flag)
+{
+   theMaxValuesValidFlag = flag;
+}
+
+void ossimImageMetaData::setNullValuesValid(bool flag)
+{
+   theNullValuesValidFlag = flag;
+}
+
+bool ossimImageMetaData::getMinValuesValidFlag()const
+{
+   return theMinValuesValidFlag;
+}
+
+bool ossimImageMetaData::getMaxValuesValidFlag()const
+{
+   return theMaxValuesValidFlag;
+}
+
+bool ossimImageMetaData::getNullValuesValidFlag()const
+{
+   return theNullValuesValidFlag;
+}
+
+const ossimImageMetaData& ossimImageMetaData::operator=(
+   const ossimImageMetaData& rhs)
+{
+   assign(rhs);
+   
+   return *this;
+}
+
+bool ossimImageMetaData::isValid()const
+{
+   return ((theNumberOfBands>0)&&
+           (theScalarType != OSSIM_SCALAR_UNKNOWN));
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageMetaData.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageMetaData.h
new file mode 100644
index 0000000000..3d987f95b5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageMetaData.h
@@ -0,0 +1,102 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class declaration for ossimImageMetaData.
+// 
+//*******************************************************************
+//  $Id: ossimImageMetaData.h,v 1.11 2005/08/11 13:41:12 gpotts Exp $
+#ifndef ossimImageMetaData_HEADER
+#define ossimImageMetaData_HEADER
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+
+class OSSIM_DLL ossimImageMetaData
+{
+public:
+   ossimImageMetaData();
+   ossimImageMetaData(ossimScalarType aType,
+                      ossim_uint32 numberOfBands);
+   ossimImageMetaData(const ossimImageMetaData& rhs);
+   
+   virtual ~ossimImageMetaData();
+   
+   void clear();
+   void clearBandInfo();
+   void setDefaultsForArrays();
+   
+   void setNumberOfBands(ossim_uint32 numberOfBands);
+   
+   ossim_uint32 getNumberOfBands()const;
+   
+   void setScalarType(ossimScalarType aType);
+   
+   ossimScalarType getScalarType()const;
+   
+   double getMinPix(ossim_uint32 band)const;
+   
+   void setMinPix(ossim_uint32 band, double pix);
+   
+   void setMaxPix(ossim_uint32 band, double pix);
+   
+   void setNullPix(ossim_uint32 band, double pix);
+   
+   double getMaxPix(ossim_uint32 band)const;
+   
+   double getNullPix(ossim_uint32 band)const;
+   
+   const double* getMinPixelArray()const;
+   
+   const double* getMaxPixelArray()const;
+   
+   const double* getNullPixelArray()const;
+   
+   void setMinValuesValid(bool flag);
+   
+   void setMaxValuesValid(bool flag);
+   
+   void setNullValuesValid(bool flag);
+
+   bool getMinValuesValidFlag()const;
+
+   bool getMaxValuesValidFlag()const;
+
+   bool getNullValuesValidFlag()const;
+   
+   const ossimImageMetaData& operator=(const ossimImageMetaData& rhs);
+
+   bool isValid()const;
+
+   void assign(const ossimImageMetaData& rhs);
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix=0);
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix=0)const;
+
+protected:
+  double*         theNullPixelArray;
+  double*         theMinPixelArray;
+  double*         theMaxPixelArray;
+  
+  bool            theMinValuesValidFlag;
+  bool            theMaxValuesValidFlag;
+  bool            theNullValuesValidFlag;
+  
+  ossimScalarType theScalarType;
+  ossim_uint32    theNumberOfBands;
+  
+  
+  void loadBandInfo(const ossimKeywordlist& kwl, const char* prefix = 0);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageShapeFileIndex.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageShapeFileIndex.cpp
new file mode 100644
index 0000000000..f280765c7c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageShapeFileIndex.cpp
@@ -0,0 +1,197 @@
+#include "ossimImageShapeFileIndex.h"
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/ossimProjection.h>
+#include <base/common/ossimTrace.h>
+
+#include <vec/shape/shapefil.h>
+
+static ossimTrace traceDebug("ossimImageShapeFileIndex:debug");
+
+ossimImageShapeFileIndex::ossimImageShapeFileIndex(const ossimFilename& shapeFilename)
+   :theGlobalMinx(OSSIM_INFINITY),
+    theGlobalMiny(OSSIM_INFINITY),
+    theGlobalMaxx(-OSSIM_INFINITY),
+    theGlobalMaxy(-OSSIM_INFINITY)
+{
+   setFilename(shapeFilename);
+}
+
+void ossimImageShapeFileIndex::setFilename(const ossimFilename& shapeFilename)
+{
+   theFilename = shapeFilename;
+   theFilename = theFilename.setExtension("");
+}
+
+void ossimImageShapeFileIndex::add(const ossimFilename& filename,
+                                   const ossim_int32 entry, // default to all entries
+                                   const ossimString& groupName)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageShapeFileIndex::add: Entered ...." << std::endl;
+   }
+   ossimRefPtr<ossimImageHandler> h = ossimImageHandlerRegistry::instance()->open(filename);
+   ossimRefPtr<ossimProjection> proj;
+
+   if(h.valid())
+   {
+      std::vector<ossim_uint32> entryList;
+      if(entry < 0)
+      {
+         h->getEntryList(entryList);
+      }
+      else
+      {
+         entryList.push_back(static_cast<ossim_uint32>(entry));
+      }
+
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < entryList.size(); ++idx)
+      {
+         ossimKeywordlist kwl;
+         if(h->setCurrentEntry(entryList[idx]))
+         {
+            ossimIrect bounds = h->getBoundingRect();
+            
+            h->getImageGeometry(kwl);
+            proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+            
+            if(proj.valid())
+            {
+               if(traceDebug())
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG) << "Adding file:  " << filename << std::endl
+                                                      << "       entry: " << entryList[idx] << std::endl;
+               }
+               std::vector<ossimDpt> points;
+               ossim_float64 minx;
+               ossim_float64 miny;
+               ossim_float64 maxx;
+               ossim_float64 maxy;
+               ossimGpt ulgpt;
+               ossimGpt urgpt;
+               ossimGpt lrgpt;
+               ossimGpt llgpt;
+               const ossimDatum* datum = ossimDatumFactory::instance()->wgs84();
+               proj->lineSampleToWorld(bounds.ul(), ulgpt);
+               proj->lineSampleToWorld(bounds.ur(), urgpt);
+               proj->lineSampleToWorld(bounds.lr(), lrgpt);
+               proj->lineSampleToWorld(bounds.ll(), llgpt);
+
+               ulgpt.changeDatum(datum);
+               urgpt.changeDatum(datum);
+               lrgpt.changeDatum(datum);
+               llgpt.changeDatum(datum);
+               
+               points.push_back(ossimDpt(ulgpt));
+               points.push_back(ossimDpt(urgpt));
+               points.push_back(ossimDpt(lrgpt));
+               points.push_back(ossimDpt(llgpt));
+
+               ossimDrect rect(points, OSSIM_RIGHT_HANDED);
+
+               minx = rect.ll().x;
+               miny = rect.ll().y;
+               maxx = rect.ur().x;
+               maxy = rect.ur().y;
+
+               if(minx < theGlobalMinx) theGlobalMinx = minx;
+               if(maxx > theGlobalMaxx) theGlobalMaxx = maxx;
+               if(miny < theGlobalMiny) theGlobalMiny = miny;
+               if(maxy > theGlobalMaxy) theGlobalMaxy = maxy;
+
+               theRecords.push_back(new ossimImageShapeFileIndexRecord(filename,
+                                                                       entryList[idx],
+                                                                       groupName,
+                                                                       minx,
+                                                                       miny,
+                                                                       maxx,
+                                                                       maxy));
+            }
+         }
+      }
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageShapeFileIndex::add: Leaving ...." << std::endl;
+   }
+}
+
+void ossimImageShapeFileIndex::build(ossim_uint32 maxDepth)const
+{
+   if(theRecords.size())
+   {
+      SHPHandle hSHP = SHPCreate( theFilename.c_str(), SHPT_POLYGON);
+      DBFHandle hDBF = DBFCreate( theFilename.c_str());
+      
+      DBFAddField(hDBF, "GROUP", FTString, 256, 0);
+      DBFAddField(hDBF, "FILENAME", FTString, 256, 0);
+      DBFAddField(hDBF, "ENTRY", FTInteger, 10, 0);
+      DBFAddField(hDBF, "DATUM", FTString, 16, 0);
+      
+      double* x = new double[4];
+      double* y = new double[4];
+      int nVertices = 4;
+      ossim_uint32 idx = 0;
+      int iRecord = 0;
+      for(idx = 0; idx < theRecords.size(); ++idx)
+      {
+         x[0] = theRecords[idx]->theMinx;
+         x[1] = theRecords[idx]->theMaxx;
+         x[2] = theRecords[idx]->theMaxx;
+         x[3] = theRecords[idx]->theMinx;
+
+         y[0] = theRecords[idx]->theMaxy;
+         y[1] = theRecords[idx]->theMaxy;
+         y[2] = theRecords[idx]->theMiny;
+         y[3] = theRecords[idx]->theMiny;
+         
+         SHPObject* obj = SHPCreateSimpleObject(SHPT_POLYGON,
+                                                nVertices,
+                                                x,
+                                                y,
+                                                0);
+         SHPWriteObject( hSHP, -1, obj );
+         iRecord = DBFGetRecordCount( hDBF );
+         DBFWriteStringAttribute(hDBF, iRecord, 0, theRecords[idx]->theGroupName.c_str());
+         DBFWriteStringAttribute(hDBF, iRecord, 1, theRecords[idx]->theFilename.c_str());
+         DBFWriteIntegerAttribute(hDBF, iRecord, 2, (int)(theRecords[idx]->theEntry));
+         DBFWriteStringAttribute(hDBF, iRecord, 3, "WGE");
+         SHPDestroyObject(obj);
+      }
+
+      DBFClose(hDBF);
+      SHPTree * shpTree = 0;
+      double minV[4] = {0.0,0.0,0.0,0.0};
+      double maxV[4] = {0.0,0.0,0.0,0.0};
+      
+      minV[0] = theGlobalMinx;
+      minV[1] = theGlobalMiny;
+      
+      maxV[0] = theGlobalMaxx;
+      maxV[1] = theGlobalMaxy;
+      if(maxDepth>1)
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "building quadtree with " << maxDepth << " levels." << std::endl
+                                                << "minx = " << theGlobalMinx << std::endl
+                                                << "miny = " << theGlobalMiny << std::endl
+                                                << "maxx = " << theGlobalMaxx << std::endl
+                                                << "maxy = " << theGlobalMaxy << std::endl;
+         }
+         shpTree = SHPCreateTree(hSHP, 2, maxDepth, minV, maxV);
+      }
+
+      if(shpTree)
+      {
+         SHPWriteTree(shpTree, (theFilename+".qtree").c_str());
+         SHPDestroyTree(shpTree);
+      }
+      SHPClose(hSHP);
+   }
+   
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageShapeFileIndex.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageShapeFileIndex.h
new file mode 100644
index 0000000000..29ef7e090e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageShapeFileIndex.h
@@ -0,0 +1,61 @@
+#ifndef ossimImageShapeFileIndex_HEADER
+#define ossimImageShapeFileIndex_HEADER
+#include <base/common/ossimObject.h>
+#include <base/common/ossimReferenced.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimFilename.h>
+
+class OSSIM_DLL ossimImageShapeFileIndex : public ossimObject
+{
+public:
+   ossimImageShapeFileIndex(const ossimFilename& shapeFilename = "");
+   void setFilename(const ossimFilename& shapeFilename);
+   
+   void add(const ossimFilename& filename,
+            const ossim_int32 entry=-1, // default to all entries
+            const ossimString& groupName="RASTER");
+   /**
+    *
+    */ 
+   void build(ossim_uint32 maxDepth=1)const;
+   
+protected:
+   class ossimImageShapeFileIndexRecord : public ossimReferenced
+   {
+   public:
+      ossimImageShapeFileIndexRecord(const ossimFilename& filename="",
+                                     ossim_uint32 entry=0,
+                                     const ossimString& groupName="",
+                                     ossim_float64 minx=0.0,
+                                     ossim_float64 miny=0.0,
+                                     ossim_float64 maxx=0.0,
+                                     ossim_float64 maxy=0.0)
+         :theFilename(filename),
+         theEntry(entry),
+         theGroupName(groupName),
+         theMinx(minx),
+         theMiny(miny),
+         theMaxx(maxx),
+         theMaxy(maxy)
+      {
+      }
+
+      ossimFilename theFilename;
+      ossim_uint32  theEntry;
+      ossimString   theGroupName;
+      ossim_float64 theMinx;
+      ossim_float64 theMiny;
+      ossim_float64 theMaxx;
+      ossim_float64 theMaxy;
+   };
+
+   std::vector<ossimRefPtr<ossimImageShapeFileIndexRecord> > theRecords;
+
+   ossimFilename theFilename;
+   ossim_float64 theGlobalMinx;
+   ossim_float64 theGlobalMiny;
+   ossim_float64 theGlobalMaxx;
+   ossim_float64 theGlobalMaxy;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageSource.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageSource.cpp
new file mode 100644
index 0000000000..e6d8a00f86
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageSource.cpp
@@ -0,0 +1,336 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageSource.cpp,v 1.48 2005/12/09 12:19:04 gpotts Exp $
+
+#include <imaging/ossimImageSource.h>
+#include <imaging/ossimImageData.h>
+#include <base/property/ossimProperty.h>
+#include <base/common/ossimKeywordNames.h>
+
+RTTI_DEF2(ossimImageSource,
+          "ossimImageSource" ,
+          ossimSource,
+          ossimImageSourceInterface)
+
+ossimImageSource::ossimImageSource(ossimObject* owner)
+   :ossimSource(owner, 0,0,false,false)
+{
+}
+
+ossimImageSource::ossimImageSource(ossimObject* owner,
+                                   ossim_uint32 inputListSize,
+                                   ossim_uint32 outputListSize,
+                                   bool inputListIsFixedFlag,
+                                   bool outputListIsFixedFlag)
+   :
+      ossimSource(owner, inputListSize, outputListSize,
+                  inputListIsFixedFlag, outputListIsFixedFlag)
+{
+}
+
+ossimImageSource::~ossimImageSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimImageSource::getTile(const ossimIpt& origin,
+                                                      ossim_uint32 resLevel)
+{
+   ossimIrect tile_rect(origin.x,
+                        origin.y,
+                        origin.x + getTileWidth()  - 1,
+                        origin.y + getTileHeight() - 1);
+   
+   return getTile(tile_rect, resLevel);
+}
+
+ossimRefPtr<ossimImageData> ossimImageSource::getTile(const ossimIrect& rect,
+                                                      ossim_uint32 resLevel)
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      return inter->getTile(rect, resLevel);
+   }
+   return NULL;
+}
+
+void ossimImageSource::getDecimationFactor(ossim_uint32 resLevel,
+                                           ossimDpt& result)const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      inter->getDecimationFactor(resLevel, result);
+   }
+}
+
+void ossimImageSource::getDecimationFactors(vector<ossimDpt>& decimations)const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      inter->getDecimationFactors(decimations);
+   }
+}
+
+ossim_uint32 ossimImageSource::getNumberOfDecimationLevels() const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      return inter->getNumberOfDecimationLevels();
+   }
+   return 0;
+}
+
+ossimScalarType ossimImageSource::getOutputScalarType() const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      return inter->getOutputScalarType();
+   }
+   
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+ossim_uint32 ossimImageSource::getTileWidth()  const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      return inter->getTileWidth();
+   }
+   ossimIpt defaultTileSize;
+   ossimGetDefaultTileSize(defaultTileSize);
+   
+   return defaultTileSize.x;
+}
+
+ossim_uint32 ossimImageSource::getTileHeight() const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      return inter->getTileHeight();
+   }
+   
+   ossimIpt defaultTileSize;
+   ossimGetDefaultTileSize(defaultTileSize);
+   
+   return defaultTileSize.y;
+}
+
+ossimIrect ossimImageSource::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      return inter->getBoundingRect(resLevel);
+   }
+   ossimIrect rect;
+   rect.makeNan();
+   return rect;
+}
+
+bool ossimImageSource::saveState(ossimKeywordlist& kwl,
+                                 const char* prefix)const
+{
+   return ossimSource::saveState(kwl, prefix);
+}
+
+bool ossimImageSource::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   return ossimSource::loadState(kwl, prefix);
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageSource::getValidImageVertices()
+//*****************************************************************************
+void ossimImageSource::getValidImageVertices(vector<ossimIpt>& validVertices,
+                                             ossimVertexOrdering ordering,
+                                             ossim_uint32 resLevel)const
+{
+  ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+					      getInput(0));
+  if(inter)
+    {
+      return inter->getValidImageVertices(validVertices,
+					  ordering,
+                                          resLevel);
+    }
+   ossimIrect boundingRect = getBoundingRect(resLevel);
+   validVertices.clear();
+   
+   if(ordering == OSSIM_CLOCKWISE_ORDER)
+   {
+      validVertices.push_back(boundingRect.ul());
+      validVertices.push_back(boundingRect.ur());
+      validVertices.push_back(boundingRect.lr());
+      validVertices.push_back(boundingRect.ll());
+   }
+   else
+   {
+      validVertices.push_back(boundingRect.ul());
+      validVertices.push_back(boundingRect.ll());
+      validVertices.push_back(boundingRect.lr());
+      validVertices.push_back(boundingRect.ur());
+   }
+}
+
+double ossimImageSource::getNullPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      return inter->getNullPixelValue(band);
+   }
+   
+   return ossimGetDefaultNull(getOutputScalarType());
+}
+
+double ossimImageSource::getMinPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      return inter->getMinPixelValue(band);
+   }
+   return ossimGetDefaultMin(getOutputScalarType());
+}
+
+double ossimImageSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(inter)
+   {
+      return inter->getMaxPixelValue(band);
+   }
+   
+   return ossimGetDefaultMax(getOutputScalarType());
+}
+
+
+bool ossimImageSource::getImageGeometry(ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   int i = 0;
+   for(i = 0; i < (int)getNumberOfInputs(); ++i)
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      getInput(i));
+      if(interface)
+      {
+         return interface->getImageGeometry(kwl, prefix);
+      }
+   }
+   
+   return false;
+}
+
+void ossimImageSource::setImageGeometry(const ossimKeywordlist& kwl)
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if (inter)
+   {
+      setImageGeometry(kwl);
+   }
+}
+
+void ossimImageSource::saveImageGeometry() const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if (inter)
+   {
+      saveImageGeometry();
+   }
+}
+
+void ossimImageSource::saveImageGeometry(const ossimFilename& geometry_file) const
+{
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if (inter)
+   {
+      saveImageGeometry(geometry_file);
+   }
+}
+
+void ossimImageSource::getOutputBandList(std::vector<ossim_uint32>& bandList) const
+{
+   bandList.clear();
+   const ossim_uint32 BANDS = getNumberOfOutputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      bandList.push_back(band);
+   }
+}
+
+ossim_uint32 ossimImageSource::getNumberOfOutputBands() const
+{
+   return getNumberOfInputBands();
+}
+
+ossimRefPtr<ossimProperty> ossimImageSource::getProperty(const ossimString& name)const
+{
+   ossimRefPtr<ossimProperty> result = ossimSource::getProperty(name);
+
+   ossimString tempName = name;
+   if(result.valid())
+   {
+      if(tempName.downcase() == ossimKeywordNames::ENABLED_KW)
+      {
+         result->clearChangeType();
+         
+         // we will at least say its a radiometric change
+         //
+         result->setFullRefreshBit();
+      }
+   }
+
+   return result;
+}
+
+void ossimImageSource::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   ossimSource::setProperty(property);
+}
+
+void ossimImageSource::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimSource::getPropertyNames(propertyNames);
+}
+
+// Protected to hide from use...
+ossimImageSource::ossimImageSource (const ossimImageSource& rhs)
+   :ossimSource(),
+    ossimImageSourceInterface(rhs)
+{}
+
+// Protected to hide from use...
+const ossimImageSource& ossimImageSource::operator=(const ossimImageSource&)
+{
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageSource.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageSource.h
new file mode 100644
index 0000000000..0dbdd81c8e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageSource.h
@@ -0,0 +1,202 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageSource.h,v 1.48 2005/09/15 12:28:44 gpotts Exp $
+#ifndef ossimImageSource_HEADER
+#define ossimImageSource_HEADER
+
+#include <base/common/ossimSource.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimDrect.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSourceInterface.h>
+
+class ossimDpt;
+
+class OSSIMDLLEXPORT ossimImageSource : public ossimSource,
+			                public ossimImageSourceInterface
+{
+public:
+   ossimImageSource(ossimObject* owner = 0);
+   ossimImageSource(ossimObject* owner,
+                    ossim_uint32 inputListSize,
+                    ossim_uint32 outputListSize,
+                    bool inputListIsFixedFlag=true,
+                    bool outputListIsFixedFlag=true);
+
+   virtual ~ossimImageSource();
+
+   /**
+    * @return from origin out to tile_width-1, and tile_height-1.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIpt& origin,
+                                               ossim_uint32 resLevel=0);
+   
+  /**
+   * @return the requested region of interest
+   */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+   
+  /**
+   * For RTTI support. overrides ossimImageSourceInterface
+   * get object to return the correct casted base pointer
+   * for RTTI casting
+   */
+   virtual ossimObject* getObject() { return this; }
+   
+   /**
+    * For RTTI support. overrides ossimImageSourceInterface
+    * get object to return the correct casted base pointer
+    * for RTTI casting
+    */
+   virtual const ossimObject* getObject() const { return this; }
+
+ 
+  /**
+   * Will return the decimation factor for the given resolution 
+   * level.  the decimation is the scale from Resolution 0 or full 
+   * res.  Usually this is a power of 2 decimation where
+   * the decimation result is 1.0/2^resoltion.
+   */
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result)const;
+  
+   /**
+    * Will return an array of all decimations for each resolution level.
+    */
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations) const;
+
+   /**
+    * Will return the number of resolution levels.  Note: resolution
+    * level 0 is included in the return count.
+    */
+   virtual ossim_uint32 getNumberOfDecimationLevels() const;
+   
+   /**
+    * Returns the number of bands in a tile returned from this TileSource.
+    */
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+
+   /**
+    * Initializes bandList to the zero based order of output bands.
+    */
+   virtual void getOutputBandList(std::vector<ossim_uint32>& bandList) const;
+
+   /**
+    * This will be used to query the output pixel type of the tile source.
+    * Please ignore the argument.  It will soon be removed.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * Returns the default processing tile width
+    */
+   virtual ossim_uint32 getTileWidth() const;
+
+   /**
+    * Returns the default processing tile height
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   /**
+    * Each band has a null pixel associated with it.  The null pixel 
+    * represents an invalid value.
+    */ 
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   
+   
+   /**
+    * Returns the min pixel of the band.
+    */
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   
+   /**
+    * Returns the max pixel of the band.
+    */
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   
+   /**
+    * This will return the bounding rect of the source.  We can have several
+    * sources which are in a chain to modify the bounding image rect.
+    * lets say you are next to an image handler then it will return the
+    * bounding rect for that image.  If you are at the right side of a
+    * resampler then you will get a bounding rect along the image view plane.
+    * This is going to be a very import method for both image writers,
+    * mosaics or anything that needs to operate only within the bounds of an
+    * image.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const;
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * ordering specifies how the vertices should be arranged.
+    * valid image vertices is basically the tightly fit convex hull
+    * of the image.  Usually an image has NULL values and are
+    * internally not upright rectangular.  This can cause
+    * problems some spatial filters.
+    *
+    * The default implementation is to return the bounding rect.
+    */
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const;
+
+   /**
+    * the default is to find the first input source that is of
+    * type ossimImageSourceInterface and return its input geometry.
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+
+   /**
+    * Default method to call input's setImageGeometry.
+    */
+   virtual void setImageGeometry(const ossimKeywordlist& kwl);
+
+   /**
+    * Default method to call input's saveImageGeometry.
+    */
+   virtual void saveImageGeometry() const;
+   
+   /**
+    * Default method to call input's saveImageGeometry.
+    */
+   virtual void saveImageGeometry(const ossimFilename& geometry_file) const;
+   
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   
+protected:
+   ossimImageSource (const ossimImageSource& rhs);
+   const ossimImageSource& operator= (const ossimImageSource&);
+
+private:
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimImageSource_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceInterface.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceInterface.cpp
new file mode 100644
index 0000000000..676d70c4a1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceInterface.cpp
@@ -0,0 +1,18 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageSourceInterface.cpp,v 1.3 2005/07/15 19:49:48 dburken Exp $
+#include <imaging/ossimImageSourceInterface.h>
+
+RTTI_DEF(ossimImageSourceInterface, "ossimImageSourceInterface");
+
+ossimImageSourceInterface::~ossimImageSourceInterface()
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceInterface.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceInterface.h
new file mode 100644
index 0000000000..749eb30adf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceInterface.h
@@ -0,0 +1,109 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageSourceInterface.h,v 1.21 2005/09/15 12:28:44 gpotts Exp $
+#ifndef ossimImageSourceInterface_HEADER
+#define ossimImageSourceInterface_HEADER
+
+#include <base/context/ossimErrorContext.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+
+class ossimImageData;
+class ossimObject;
+
+class OSSIMDLLEXPORT ossimImageSourceInterface
+{
+public:
+   virtual ~ossimImageSourceInterface();
+   
+   virtual ossimObject* getObject()=0;
+   virtual const ossimObject* getObject()const=0;
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIpt& origin,
+                                               ossim_uint32 resLevel=0) = 0;
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0) = 0;
+   
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result)const=0;
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations)const=0;
+   virtual ossim_uint32 getNumberOfDecimationLevels()const=0;
+
+   /*!
+    * Returns the number of bands available from the input.
+    */
+   virtual ossim_uint32 getNumberOfInputBands() const = 0;
+
+   /*!
+    * Returns the number of bands in output.
+    */
+   virtual ossim_uint32 getNumberOfOutputBands() const = 0;
+
+   /*!
+    * Initializes bandList to the zero based order of output bands.
+    */
+   virtual void getOutputBandList(std::vector<ossim_uint32>& bandList) const=0;
+   
+   virtual ossimScalarType getOutputScalarType() const = 0;
+
+   virtual ossim_uint32 getTileWidth()  const = 0;
+   virtual ossim_uint32 getTileHeight() const = 0;
+
+   virtual double getNullPixelValue(ossim_uint32 band=0)const=0;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const=0;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const=0;
+
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const=0;
+   
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const=0;
+   
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0)=0;
+
+   /**
+    * Sets the image geometry keyword list.
+    *
+    * @note Callers should note that this will override any existing
+    *       geometry.
+    *
+    * @note This does not write the geometry to disk, to do so call
+    *       one of the saveImageGeometry methods. 
+    */
+   virtual void setImageGeometry(const ossimKeywordlist& kwl)=0;
+
+   /**
+    * Saves the image geometry to a file that will be made based on the image
+    * file name.
+    */
+   virtual void saveImageGeometry()const=0;
+
+   /**
+    * Saves the image geomety to geom_file.
+    */
+   virtual void saveImageGeometry(const ossimFilename& geometry_file)const=0;
+
+   virtual void initialize()=0;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0)=0;
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const=0;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceSequencer.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceSequencer.cpp
new file mode 100644
index 0000000000..98e03e0118
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceSequencer.cpp
@@ -0,0 +1,424 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimImageSourceSequencer.cpp,v 1.34 2005/11/17 12:40:30 gpotts Exp $
+#include <imaging/ossimImageSourceSequencer.h>
+#include <imaging/ossimImageData.h>
+#include <base/data_types/ossimIrect.h>
+#include <imaging/ossimImageWriter.h>
+#include <base/common/ossimTrace.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF2(ossimImageSourceSequencer, "ossimImageSourceSequencer",
+          ossimImageSource, ossimConnectableObjectListener);
+
+static ossimTrace traceDebug("ossimImageSourceSequencer:debug");
+   
+ossimImageSourceSequencer::ossimImageSourceSequencer(ossimImageSource* inputSource,
+                                                     ossimObject* owner)
+   :ossimImageSource(owner,
+                     1,
+                     1,
+                     true,
+                     true),
+    theBlankTile(NULL),
+    theAreaOfInterest(0,0,0,0),
+    theTileSize(OSSIM_DEFAULT_TILE_WIDTH, OSSIM_DEFAULT_TILE_HEIGHT),
+    theNumberOfTilesHorizontal(0),
+    theNumberOfTilesVertical(0),
+    theCurrentTileNumber(0)
+{
+   ossimGetDefaultTileSize(theTileSize);
+   theAreaOfInterest.makeNan();
+   theInputConnection    = inputSource;
+   if(inputSource)
+   {
+     connectMyInputTo(0, inputSource);
+     initialize();
+   }
+   addListener( (ossimConnectableObjectListener*)this);
+}
+
+ossimImageSourceSequencer::~ossimImageSourceSequencer()
+{
+   removeListener((ossimConnectableObjectListener*)this);
+}
+
+ossim_uint32 ossimImageSourceSequencer::getNumberOfTiles()const
+{
+   return (theNumberOfTilesHorizontal*theNumberOfTilesVertical);
+}
+
+
+ossim_uint32 ossimImageSourceSequencer::getNumberOfTilesHorizontal()const
+{
+   return theNumberOfTilesHorizontal;
+}
+
+ossim_uint32 ossimImageSourceSequencer::getNumberOfTilesVertical()const
+{
+   return theNumberOfTilesVertical;
+}
+
+ossimScalarType ossimImageSourceSequencer::getOutputScalarType() const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getOutputScalarType();
+   }
+   
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+ossimIpt ossimImageSourceSequencer::getTileSize()const
+{
+   return theTileSize;
+}
+
+void ossimImageSourceSequencer::setTileSize(const ossimIpt& tileSize)
+{
+   theTileSize = tileSize;
+   updateTileDimensions();
+//   initialize();
+}
+
+void ossimImageSourceSequencer::setTileSize(int width, int height)
+{
+   setTileSize(ossimIpt(width, height));
+}
+
+void ossimImageSourceSequencer::updateTileDimensions()
+{
+   if(theAreaOfInterest.hasNans() ||
+      theTileSize.hasNans())
+   {
+      theNumberOfTilesHorizontal = 0;
+      theNumberOfTilesVertical   = 0;
+   }
+   else
+   {
+      ossim_int32 width  = theAreaOfInterest.width();
+      ossim_int32 height = theAreaOfInterest.height();
+
+      theNumberOfTilesHorizontal = static_cast<ossim_uint32>(ceil((double)width/(double)theTileSize.x));
+      theNumberOfTilesVertical   = static_cast<ossim_uint32>(ceil((double)height/(double)theTileSize.y));
+   }
+}
+
+void ossimImageSourceSequencer::initialize()
+{
+   theInputConnection = PTR_CAST(ossimImageSourceInterface, getInput(0));
+
+   if(theInputConnection)
+   {
+      if(theTileSize.hasNans())
+      {
+         theTileSize.x = theInputConnection->getTileWidth();
+         theTileSize.y = theInputConnection->getTileHeight();
+      }
+
+      ossimDrect rect = theInputConnection->getBoundingRect();
+      if(rect.hasNans())
+      {
+         theAreaOfInterest.makeNan();
+      }
+      else
+      {
+         rect.stretchOut();
+         setAreaOfInterest(rect);
+      }
+      updateTileDimensions();
+      
+      theBlankTile  = ossimImageDataFactory::instance()->create(this,
+                                                                this);
+      if(theBlankTile.valid())
+      {
+         theBlankTile->initialize();
+      }
+   }
+}
+
+bool ossimImageSourceSequencer::canConnectMyInputTo(ossim_int32 inputIndex,
+						    const ossimConnectableObject* object)const
+{      
+  return (object&& PTR_CAST(ossimImageSourceInterface, object));
+}
+
+void ossimImageSourceSequencer::connectInputEvent(ossimConnectionEvent& event)
+{
+  theInputConnection = PTR_CAST(ossimImageSourceInterface, getInput(0));
+  initialize();
+}
+
+void ossimImageSourceSequencer::disconnectInputEvent(ossimConnectionEvent& event)
+{
+  theInputConnection = PTR_CAST(ossimImageSourceInterface, getInput(0));
+}
+
+ossimIrect ossimImageSourceSequencer::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimDrect temp;
+   temp.makeNan();
+
+   if(!theInputConnection) return temp;
+   
+   if(theAreaOfInterest.hasNans())
+   {
+      return theInputConnection->getBoundingRect(resLevel);
+   }
+      
+   return theAreaOfInterest;
+}
+
+void ossimImageSourceSequencer::getDecimationFactor(ossim_uint32 resLevel,
+                                                    ossimDpt& result) const
+{
+   if(theInputConnection)
+   {
+      theInputConnection->getDecimationFactor(resLevel,
+                                              result);
+   }
+   result.makeNan();
+}
+
+void ossimImageSourceSequencer::getDecimationFactors(vector<ossimDpt>& decimations) const
+{
+   if(theInputConnection)
+   {
+      theInputConnection->getDecimationFactors(decimations);
+   }   
+}
+
+ossim_uint32 ossimImageSourceSequencer::getNumberOfDecimationLevels()const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getNumberOfDecimationLevels();
+   }
+
+   return 0;
+}
+
+void ossimImageSourceSequencer::setAreaOfInterest(const ossimIrect& areaOfInterest)
+{
+   if(areaOfInterest.hasNans())
+   {
+      theAreaOfInterest.makeNan();
+      theNumberOfTilesHorizontal = 0;
+      theNumberOfTilesVertical   = 0;
+   }
+
+   // let's round it to the nearest pixel value before setting it.
+   theAreaOfInterest = areaOfInterest;
+   updateTileDimensions();
+}
+
+const ossimIrect& ossimImageSourceSequencer::getAreaOfInterest()const
+{
+   return theAreaOfInterest;
+}
+
+void ossimImageSourceSequencer::setToStartOfSequence()
+{
+   theCurrentTileNumber = 0;
+}
+
+ossimRefPtr<ossimImageData> ossimImageSourceSequencer::getTile(
+   const ossimIrect& rect, ossim_uint32 resLevel)
+{
+   if(theInputConnection)
+   {
+      ossimRefPtr<ossimImageData> tile =
+         theInputConnection->getTile(rect, resLevel);
+      if (tile.valid())
+      {
+         return tile;
+      }
+      else
+      {
+         // We should return a valid tile for the writers.
+         theBlankTile->setImageRectangle(rect);
+         return theBlankTile;
+      }
+   }
+
+   return NULL;
+}
+
+ossimRefPtr<ossimImageData> ossimImageSourceSequencer::getNextTile(
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;
+   }
+   ossimIpt origin;
+   if(getTileOrigin(theCurrentTileNumber, origin))
+   {
+      ++theCurrentTileNumber;
+      ossimIrect tileRect(origin.x,
+			  origin.y,
+			  origin.x + (theTileSize.x - 1),
+			  origin.y + (theTileSize.y - 1));
+      ossimRefPtr<ossimImageData> data = theInputConnection->getTile(tileRect,
+                                                                     resLevel);
+      if(!data.valid() || !data->getBuf())
+      {
+         theBlankTile->setImageRectangle(tileRect);
+         return theBlankTile;
+      }
+      
+      return data;
+   }
+
+   
+   return ossimRefPtr<ossimImageData>();
+}
+
+ossimRefPtr<ossimImageData> ossimImageSourceSequencer::getTile(
+   ossim_int32 id, ossim_uint32 resLevel)
+{
+   static const char* MODULE= "ossimImageSourceSequencer::getTile(id, resLevel)";
+   if(traceDebug())
+   {
+      CLOG << "entering.."<<endl;
+   }
+   if(!theInputConnection)
+   {
+      if(traceDebug())
+      {
+         CLOG << "No input connection so returing NULL" << endl;
+      }
+      return NULL;
+   }
+   // if we have no tiles try to initialize.
+   if(getNumberOfTiles() == 0)
+   {
+      initialize();
+   }
+   ossimIpt origin;
+   
+   if(getTileOrigin(id, origin))
+   {
+      if(traceDebug())
+      {
+         CLOG << "returning tile" << endl;
+      }
+      ossimIrect tRect(origin.x,
+                       origin.y,
+                       origin.x + theTileSize.x - 1,
+                       origin.y + theTileSize.y - 1);
+      
+      ossimRefPtr<ossimImageData> temp = theInputConnection->getTile(tRect,
+                                                                     resLevel);
+
+
+      theBlankTile->setImageRectangle(tRect);
+      
+      if(temp.valid())
+      {
+         if(!temp->getBuf())
+         {
+            return theBlankTile;
+         }
+      }
+      else
+      {
+         return theBlankTile;
+      }
+      return temp;
+   }
+   else
+   {
+      if(traceDebug())
+      {
+         CLOG << "was not able to get an origin for id = " << id << endl;
+      }
+   }
+   if(traceDebug())
+   {
+      CLOG << "leaving.."<<endl;
+   }
+   return NULL;
+}
+
+
+bool ossimImageSourceSequencer::getTileOrigin(ossim_int32 id,
+                                              ossimIpt& origin)const
+{
+   if(id < 0)
+   {
+      return false;
+   }
+   if((theNumberOfTilesHorizontal > 0)&&
+      (theCurrentTileNumber < getNumberOfTiles()))
+   {
+      ossim_int32 y = id/static_cast<ossim_int32>(theNumberOfTilesHorizontal);
+      ossim_int32 x = id%static_cast<ossim_int32>(theNumberOfTilesHorizontal);
+      if((x < static_cast<ossim_int32>(theNumberOfTilesHorizontal)) &&
+         (y < static_cast<ossim_int32>(theNumberOfTilesVertical)))
+      {           
+         origin.x = theAreaOfInterest.ul().x + x*theTileSize.x;
+         origin.y = theAreaOfInterest.ul().y + y*theTileSize.y;
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   return true;
+}
+
+double ossimImageSourceSequencer::getNullPixelValue(ossim_uint32 band)const
+{
+   if (theInputConnection)
+   {
+      return theInputConnection->getNullPixelValue(band);
+   }
+
+   return ossimImageSource::getNullPixelValue(band);
+}
+
+double ossimImageSourceSequencer::getMinPixelValue(ossim_uint32 band)const
+{
+   if (theInputConnection)
+   {
+      return theInputConnection->getMinPixelValue(band);
+   }
+   
+   return ossimImageSource::getMinPixelValue(band);  
+}
+
+double ossimImageSourceSequencer::getMaxPixelValue(ossim_uint32 band)const
+{
+   if (theInputConnection)
+   {
+      return theInputConnection->getMaxPixelValue(band);
+   }
+   
+   return ossimImageSource::getMaxPixelValue(band);  
+}
+
+ossim_uint32 ossimImageSourceSequencer::getNumberOfInputBands()const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getNumberOfOutputBands();
+   }
+
+   return 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceSequencer.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceSequencer.h
new file mode 100644
index 0000000000..b04d9c9ec6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageSourceSequencer.h
@@ -0,0 +1,160 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimImageSourceSequencer.h,v 1.30 2005/11/17 12:43:52 gpotts Exp $
+#ifndef ossimImageSourceSequencer_HEADER
+#define ossimImageSourceSequencer_HEADER
+#include "ossimImageSource.h"
+#include "base/data_types/ossimIpt.h"
+#include "base/common/events/ossimConnectableObjectListener.h"
+
+
+class OSSIMDLLEXPORT ossimImageSourceSequencer
+   :
+      public ossimImageSource,
+      public ossimConnectableObjectListener
+{
+public:
+   ossimImageSourceSequencer(ossimImageSource* inputSource=NULL,
+                             ossimObject* owner=NULL);
+
+   virtual ~ossimImageSourceSequencer();
+  /*!
+    * This will return the number of tiles within the
+    * area of interest.
+    */
+   ossim_uint32 getNumberOfTiles()const;
+
+   /*!
+    * Will return the number of tiles along the
+    * x or horizontal direction.
+    */
+   ossim_uint32 getNumberOfTilesHorizontal()const;
+
+   /*!
+    * Will return the number of tiles along the
+    * y or vertical direction.
+    */
+   ossim_uint32 getNumberOfTilesVertical()const;
+
+   /*!
+    * This must be called.  We can only initialize this
+    * object completely if we know all connections
+    * are valid.  Some other object drives this and so the
+    * connection's initialize will be called after.  The job
+    * of this connection is to set up the sequence.  It will
+    * default to the bounding rect.  The area of interest can be
+    * set to some other rectagle (use setAreaOfInterest).
+    */
+   virtual void initialize();
+
+   /*!
+    * Will set the current area of interest.
+    */
+   virtual void setAreaOfInterest(const ossimIrect& areaOfInterest);
+
+   /*!
+    * Just returns the current area of interest.
+    */
+   const ossimIrect& getAreaOfInterest()const;
+
+   /*!
+    * Will set the internal pointers to the upperleft
+    * tile number.  To go to the next tile in the sequence
+    * just call getNextTile.
+    */
+   virtual void setToStartOfSequence();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                   ossim_uint32 resLevel=0);
+
+   /*!
+    * Will allow you to get the next tile in the sequence.
+    * Note the last tile returned will be an invalid
+    * ossimRefPtr<ossimImageData>.  Callers should be able to do:
+    * 
+    * ossimRefPtr<ossimImageData> id = sequencer->getNextTile();
+    * while (id.valid())
+    * {
+    *    doSomething;
+    *    id = sequencer->getNextTile();
+    * }
+    * 
+    */
+   virtual ossimRefPtr<ossimImageData> getNextTile(ossim_uint32 resLevel=0);
+
+   virtual bool getTileOrigin(ossim_int32 id,
+                              ossimIpt& origin)const;
+   virtual ossimRefPtr<ossimImageData> getTile(ossim_int32 id,
+                                               ossim_uint32 resLevel=0);
+
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result) const;
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations) const;
+   virtual ossim_uint32 getNumberOfDecimationLevels()const;
+   
+   /*!
+    * Returns the number of bands available from the input.
+    */
+   virtual ossim_uint32 getNumberOfInputBands()const;   
+
+   virtual ossimScalarType getOutputScalarType() const;
+      
+   virtual ossim_uint32 getTileWidth()const  { return theTileSize.x; }
+   virtual ossim_uint32 getTileHeight()const { return theTileSize.y; }
+   
+   virtual void slaveProcessTiles()
+      {
+         return;
+      }
+   virtual bool isMaster()const
+      {
+         return true;
+      }
+
+   virtual ossimIpt getTileSize()const;
+   virtual void setTileSize(const ossimIpt& tileSize);
+   virtual void setTileSize(int width, int height);
+   
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+   
+   virtual bool canConnectMyInputTo(ossim_int32 inputIndex,
+                                    const ossimConnectableObject* object)const;
+   
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   
+protected:
+   ossimImageSourceInterface*  theInputConnection;
+   ossimRefPtr<ossimImageData> theBlankTile;
+   /*!
+    * Is the area of interest.  The default will
+    * 
+    */
+   ossimIrect theAreaOfInterest;
+
+   /*!
+    * Called during initialize.
+    */
+   ossimIpt theTileSize;
+   
+   ossim_uint32 theNumberOfTilesHorizontal;
+   ossim_uint32 theNumberOfTilesVertical;
+   ossim_uint32 theCurrentTileNumber;
+
+   void updateTileDimensions();
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageStatisticsSource.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageStatisticsSource.cpp
new file mode 100644
index 0000000000..f50dc104fa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageStatisticsSource.cpp
@@ -0,0 +1,180 @@
+//*******************************************************************
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+#include <imaging/ossimImageStatisticsSource.h>
+#include <imaging/ossimImageSourceInterface.h>
+#include <imaging/ossimImageSourceSequencer.h>
+
+
+ossimImageStatisticsSource::ossimImageStatisticsSource()
+      :ossimSource(0,
+                   1,
+                   0,
+                   true,
+                   false)
+{
+}
+
+ossimImageStatisticsSource::~ossimImageStatisticsSource()
+{
+   
+}
+
+void ossimImageStatisticsSource::computeStatistics()
+{
+   ossimImageSourceInterface* anInterface = PTR_CAST(ossimImageSourceInterface,
+                                                     getInput());
+
+   if(anInterface&&isSourceEnabled())
+   {
+      clearStatistics();
+      ossimScalarType outputScalarType = anInterface->getOutputScalarType();
+
+      switch(outputScalarType)
+      {
+         case OSSIM_UCHAR:
+         {
+            computeStatisticsTemplate((ossim_uint8)0);
+            break;
+         }
+         case OSSIM_USHORT16:
+         case OSSIM_USHORT11:
+         {
+            computeStatisticsTemplate((ossim_uint16)0);
+            break;
+         }
+         case OSSIM_SSHORT16:
+         {
+            computeStatisticsTemplate((ossim_sint16)0);
+            break;
+         }
+         case OSSIM_DOUBLE:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            computeStatisticsTemplate((ossim_float64)0);
+            break;
+         }
+         case OSSIM_FLOAT:
+         case OSSIM_NORMALIZED_FLOAT:
+         {
+            computeStatisticsTemplate((ossim_float32)0);
+            break;
+         }
+		 default :
+		 {
+			 break;
+		 }
+      }
+   }
+}
+
+bool ossimImageStatisticsSource::canConnectMyInputTo(ossim_int32 inputIndex,
+                                                     const ossimConnectableObject* object)const
+{
+   return (PTR_CAST(ossimImageSourceInterface, object)&&(inputIndex < 1));
+}
+
+template <class T>
+void ossimImageStatisticsSource::computeStatisticsTemplate(T dummyVariable)
+{
+   ossimImageSourceSequencer* sequencer = new ossimImageSourceSequencer;
+
+   sequencer->connectMyInputTo(getInput());
+   sequencer->setToStartOfSequence();
+   ossim_uint32 bands = sequencer->getNumberOfOutputBands();
+
+   if(bands)
+   {
+      setStatsSize(bands);
+      ossimRefPtr<ossimImageData> dataObject;
+      
+      while( (dataObject=sequencer->getNextTile()).valid() )
+      {
+		  ossim_uint32 bandIdx = 0;
+		  bands                = dataObject->getNumberOfBands();
+		  ossimDataObjectStatus status = dataObject->getDataObjectStatus();
+		  if((status != OSSIM_EMPTY)&&
+			 (dataObject->getBuf()))
+		  {
+			  ossim_uint32 offsetMax = dataObject->getWidth()*dataObject->getHeight();
+			  for(bandIdx = 0; bandIdx < bands; ++bandIdx)
+			  {
+				  ossim_float64 pixelCount = 0.0;
+				  ossim_uint32 offset = 0;
+				  T* dataPtr   = static_cast<T*>(dataObject->getBuf(bandIdx));
+				  T nullPixel = static_cast<T>(dataObject->getNullPix(bandIdx)); 
+				  for(offset = 0; offset < offsetMax; ++offset)
+				  {
+					  if((*dataPtr) != nullPixel)
+					  {
+						  theMean[bandIdx] += *dataPtr;
+						  if((*dataPtr) < theMin[bandIdx])
+						  {
+							  theMin[bandIdx] = (*dataPtr);
+						  }
+						  if((*dataPtr) > theMax[bandIdx])
+						  {
+							  theMax[bandIdx] = (*dataPtr);
+						  }
+						  ++pixelCount;
+					  }
+					  ++dataPtr;
+				  }
+				  if(pixelCount > 0)
+				  {
+					  theMean[bandIdx] /= pixelCount;
+				  }
+			  }
+		  }
+      }
+   }
+   
+   sequencer->disconnect();
+   delete sequencer;
+   sequencer = 0;
+}
+
+const std::vector<ossim_float64>& ossimImageStatisticsSource::getMean()const
+{
+   return theMean;
+}
+
+const std::vector<ossim_float64>& ossimImageStatisticsSource::getMin()const
+{
+   return theMin;
+}
+
+const std::vector<ossim_float64>& ossimImageStatisticsSource::getMax()const
+{
+   return theMax;
+}
+
+void ossimImageStatisticsSource::clearStatistics()
+{
+   theMean.clear();
+   theMin.clear();
+   theMax.clear();
+}
+
+void ossimImageStatisticsSource::setStatsSize(ossim_uint32 size)
+{
+   theMean.resize(size);
+   theMin.resize(size);
+   theMax.resize(size);
+
+   std::fill(theMean.begin(),
+             theMean.end(),
+             (ossim_float64)0.0);
+   std::fill(theMin.begin(),
+             theMin.end(),
+             OSSIM_DEFAULT_MAX_PIX_DOUBLE);
+   std::fill(theMax.begin(),
+             theMax.end(),
+             (ossim_float64)OSSIM_DEFAULT_MIN_PIX_DOUBLE);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageStatisticsSource.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageStatisticsSource.h
new file mode 100644
index 0000000000..1c78bac8af
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageStatisticsSource.h
@@ -0,0 +1,32 @@
+#ifndef ossimImageStatistics_HEADER
+#define ossimImageStatistics_HEADER
+#include <base/common/ossimSource.h>
+
+class OSSIMDLLEXPORT ossimImageStatisticsSource : public ossimSource
+{
+public:
+   ossimImageStatisticsSource();
+   virtual ~ossimImageStatisticsSource();
+   
+   
+   virtual void computeStatistics();
+   
+   virtual bool canConnectMyInputTo(ossim_int32 inputIndex,
+                                    const ossimConnectableObject* object)const;
+   
+   const std::vector<ossim_float64>& getMean()const;
+   const std::vector<ossim_float64>& getMin()const;
+   const std::vector<ossim_float64>& getMax()const;
+   
+protected:
+   void clearStatistics();
+   template <class T>
+   void computeStatisticsTemplate(T dummyVariable);
+   void setStatsSize(ossim_uint32 size);
+   
+   std::vector<ossim_float64> theMean;
+   std::vector<ossim_float64> theMin;
+   std::vector<ossim_float64> theMax;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageWriter.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimImageWriter.cpp
new file mode 100644
index 0000000000..84d7046c99
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageWriter.cpp
@@ -0,0 +1,81 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Frank Warmerdam (warmerdam@pobox.com)
+//
+// Description:
+//
+// Contains class declaration for ossimImageWriter.
+//*******************************************************************
+//  $Id: ossimImageWriter.cpp,v 1.14 2006/01/03 13:24:18 dburken Exp $
+
+#include <imaging/ossimImageWriter.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimErrorContext.h>
+#include <imaging/formats/tiff/ossimTiffOverviewBuilder.h>
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+#include <imaging/formats/ossimImageHandler.h>
+
+RTTI_DEF1(ossimImageWriter, "ossimImageWriter", ossimOutputSource);
+
+ossimImageWriter::ossimImageWriter(ossimObject* owner)
+   : ossimOutputSource(owner,
+                       1,
+                       0,
+                       true,
+                       true)
+{
+   theAreaOfInterest.makeNan();
+}
+
+ossimImageWriter::ossimImageWriter(ossimObject* owner,
+                    ossim_uint32 numberOfInputs,
+                    ossim_uint32 numberOfOutputs,
+                    bool inputListIsFixed,
+                    bool outputListIsFixed)
+   :ossimOutputSource(owner,
+                      numberOfInputs,
+                      numberOfOutputs,
+                      inputListIsFixed,
+                      outputListIsFixed)
+{
+   theAreaOfInterest.makeNan();
+}
+
+ossimImageWriter::~ossimImageWriter()
+{
+}
+
+bool ossimImageWriter::setViewingRect(const ossimIrect &aRect)
+{
+   setAreaOfInterest(aRect);
+   
+   return true;
+}
+
+ossimIrect ossimImageWriter::getAreaOfInterest() const
+{
+   return theAreaOfInterest;
+}
+ 
+void ossimImageWriter::setAreaOfInterest(const ossimIrect& inputAreaOfInterest)
+{
+   theAreaOfInterest = inputAreaOfInterest;
+}
+
+bool ossimImageWriter::saveState(ossimKeywordlist& kwl,
+                                 const char* prefix)const
+{
+   return ossimOutputSource::saveState(kwl, prefix);
+}
+
+bool ossimImageWriter::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   return ossimOutputSource::loadState(kwl, prefix);
+}
+   
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimImageWriter.h b/Utilities/OSSIM/ossim_core/imaging/ossimImageWriter.h
new file mode 100644
index 0000000000..834fd791f4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimImageWriter.h
@@ -0,0 +1,71 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  Frank Warmerdam (warmerdam@pobox.com)
+//
+// Description:
+//
+// Contains class declaration for ossimImageWriter
+//*******************************************************************
+//  $Id: ossimImageWriter.h,v 1.19 2006/01/03 15:43:40 gpotts Exp $
+
+#ifndef ossimImageWriter_HEADER
+#define ossimImageWriter_HEADER
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimOutputSource.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimIrect.h>
+
+class ossimImage;
+class ossimImageSource;
+class ossimImageWriter;
+class ossimImageWriterFactory;
+class ossimKeywordlist;
+class ossimFilename;
+
+#include <imaging/ossimImageSourceSequencer.h>
+
+
+class OSSIM_DLL ossimImageWriter :  public ossimOutputSource
+{   
+public:
+   ossimImageWriter(ossimObject* owner=NULL);
+   
+   ossimImageWriter(ossimObject* owner,
+                    ossim_uint32 numberOfInputs,
+                    ossim_uint32 numberOfOutputs,
+                    bool inputListIsFixed,
+                    bool outputListIsFixed);
+   
+   virtual ~ossimImageWriter();
+
+   /**
+    * @param aRect the rectangle to write.
+    * 
+    * @return true on success, false if the rectangle is invalid.
+    */
+   virtual bool setViewingRect(const ossimIrect &aRect);
+
+   /**
+    * @return Returns theAreaOfInterest.
+    */
+   virtual ossimIrect getAreaOfInterest() const;
+ 
+   virtual void setAreaOfInterest(const ossimIrect& inputAreaOfInterest);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+      
+protected:
+
+   ossimIrect theAreaOfInterest;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimRgbImage.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimRgbImage.cpp
new file mode 100644
index 0000000000..b794510275
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimRgbImage.cpp
@@ -0,0 +1,1910 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// Description:
+//
+//
+// Credits:
+//        Much of the implementation within this file was taken from gd
+//        We can use it but we need to give credit to the people who wrote
+//        the algorithms.
+//
+// COPYRIGHT STATEMENT FOLLOWS THIS LINE
+
+//      Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+//      by Cold Spring Harbor Laboratory. Funded under Grant P41-RR02188 by
+//      the National Institutes of Health.
+     
+//      Portions copyright 1996, 1997, 1998, 1999, 2000, 2001 by
+//      Boutell.Com, Inc.
+     
+//      Portions relating to GD2 format copyright 1999, 2000 Philip Warner.
+     
+//      Portions relating to PNG copyright 1999, 2000 Greg Roelofs.
+     
+//      Portions relating to libttf copyright 1999, 2000 John Ellson
+//      (ellson@lucent.com).
+     
+//      Portions relating to JPEG and to color quantization copyright 2000,
+//      Doug Becker and copyright (C) 1994-1998, Thomas G. Lane. This
+//      software is based in part on the work of the Independent JPEG
+//      Group. See the file README-JPEG.TXT for more information.
+     
+//      Portions relating to WBMP copyright 2000 Maurice Szmurlo and Johan
+//      Van den Brande.
+     
+//      _Permission has been granted to copy, distribute and modify gd in
+//      any context without fee, including a commercial application,
+//      provided that this notice is present in user-accessible supporting
+//      documentation._
+     
+//      This does not affect your ownership of the derived work itself, and
+//      the intent is to assure proper credit for the authors of gd, not to
+//      interfere with your productive use of gd. If you have questions,
+//      ask. "Derived works" includes all programs that utilize the
+//      library. Credit must be given in user-accessible documentation.
+     
+//      _This software is provided "AS IS."_ The copyright holders disclaim
+//      all warranties, either express or implied, including but not
+//      limited to implied warranties of merchantability and fitness for a
+//      particular purpose, with respect to this code and accompanying
+//      documentation.
+     
+//      Although their code does not appear in gd 2.0.1, the authors wish
+//      to thank David Koblas, David Rowley, and Hutchison Avenue Software
+//      Corporation for their prior contributions.
+     
+// END OF COPYRIGHT STATEMENT
+//*************************************************************************
+// $Id: ossimRgbImage.cpp,v 1.18 2005/07/18 11:20:06 gpotts Exp $
+#include <iostream>
+using namespace std;
+#include <stdlib.h>
+#include <imaging/ossimRgbImage.h>
+#include <stddef.h>
+#include <math.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/common/ossimCommon.h>
+
+// this should be in another file.  This is from gd's gdtable.c file and has
+// precomputations for sine and cosine.  It looks like they multiply the cos and
+// sign by 1024 and store the rounded int. 
+static const int gdCosT[] =
+{
+  1024,
+  1023,
+  1023,
+  1022,
+  1021,
+  1020,
+  1018,
+  1016,
+  1014,
+  1011,
+  1008,
+  1005,
+  1001,
+  997,
+  993,
+  989,
+  984,
+  979,
+  973,
+  968,
+  962,
+  955,
+  949,
+  942,
+  935,
+  928,
+  920,
+  912,
+  904,
+  895,
+  886,
+  877,
+  868,
+  858,
+  848,
+  838,
+  828,
+  817,
+  806,
+  795,
+  784,
+  772,
+  760,
+  748,
+  736,
+  724,
+  711,
+  698,
+  685,
+  671,
+  658,
+  644,
+  630,
+  616,
+  601,
+  587,
+  572,
+  557,
+  542,
+  527,
+  512,
+  496,
+  480,
+  464,
+  448,
+  432,
+  416,
+  400,
+  383,
+  366,
+  350,
+  333,
+  316,
+  299,
+  282,
+  265,
+  247,
+  230,
+  212,
+  195,
+  177,
+  160,
+  142,
+  124,
+  107,
+  89,
+  71,
+  53,
+  35,
+  17,
+  0,
+  -17,
+  -35,
+  -53,
+  -71,
+  -89,
+  -107,
+  -124,
+  -142,
+  -160,
+  -177,
+  -195,
+  -212,
+  -230,
+  -247,
+  -265,
+  -282,
+  -299,
+  -316,
+  -333,
+  -350,
+  -366,
+  -383,
+  -400,
+  -416,
+  -432,
+  -448,
+  -464,
+  -480,
+  -496,
+  -512,
+  -527,
+  -542,
+  -557,
+  -572,
+  -587,
+  -601,
+  -616,
+  -630,
+  -644,
+  -658,
+  -671,
+  -685,
+  -698,
+  -711,
+  -724,
+  -736,
+  -748,
+  -760,
+  -772,
+  -784,
+  -795,
+  -806,
+  -817,
+  -828,
+  -838,
+  -848,
+  -858,
+  -868,
+  -877,
+  -886,
+  -895,
+  -904,
+  -912,
+  -920,
+  -928,
+  -935,
+  -942,
+  -949,
+  -955,
+  -962,
+  -968,
+  -973,
+  -979,
+  -984,
+  -989,
+  -993,
+  -997,
+  -1001,
+  -1005,
+  -1008,
+  -1011,
+  -1014,
+  -1016,
+  -1018,
+  -1020,
+  -1021,
+  -1022,
+  -1023,
+  -1023,
+  -1024,
+  -1023,
+  -1023,
+  -1022,
+  -1021,
+  -1020,
+  -1018,
+  -1016,
+  -1014,
+  -1011,
+  -1008,
+  -1005,
+  -1001,
+  -997,
+  -993,
+  -989,
+  -984,
+  -979,
+  -973,
+  -968,
+  -962,
+  -955,
+  -949,
+  -942,
+  -935,
+  -928,
+  -920,
+  -912,
+  -904,
+  -895,
+  -886,
+  -877,
+  -868,
+  -858,
+  -848,
+  -838,
+  -828,
+  -817,
+  -806,
+  -795,
+  -784,
+  -772,
+  -760,
+  -748,
+  -736,
+  -724,
+  -711,
+  -698,
+  -685,
+  -671,
+  -658,
+  -644,
+  -630,
+  -616,
+  -601,
+  -587,
+  -572,
+  -557,
+  -542,
+  -527,
+  -512,
+  -496,
+  -480,
+  -464,
+  -448,
+  -432,
+  -416,
+  -400,
+  -383,
+  -366,
+  -350,
+  -333,
+  -316,
+  -299,
+  -282,
+  -265,
+  -247,
+  -230,
+  -212,
+  -195,
+  -177,
+  -160,
+  -142,
+  -124,
+  -107,
+  -89,
+  -71,
+  -53,
+  -35,
+  -17,
+  0,
+  17,
+  35,
+  53,
+  71,
+  89,
+  107,
+  124,
+  142,
+  160,
+  177,
+  195,
+  212,
+  230,
+  247,
+  265,
+  282,
+  299,
+  316,
+  333,
+  350,
+  366,
+  383,
+  400,
+  416,
+  432,
+  448,
+  464,
+  480,
+  496,
+  512,
+  527,
+  542,
+  557,
+  572,
+  587,
+  601,
+  616,
+  630,
+  644,
+  658,
+  671,
+  685,
+  698,
+  711,
+  724,
+  736,
+  748,
+  760,
+  772,
+  784,
+  795,
+  806,
+  817,
+  828,
+  838,
+  848,
+  858,
+  868,
+  877,
+  886,
+  895,
+  904,
+  912,
+  920,
+  928,
+  935,
+  942,
+  949,
+  955,
+  962,
+  968,
+  973,
+  979,
+  984,
+  989,
+  993,
+  997,
+  1001,
+  1005,
+  1008,
+  1011,
+  1014,
+  1016,
+  1018,
+  1020,
+  1021,
+  1022,
+  1023,
+  1023
+};
+
+static const int gdSinT[] =
+{
+  0,
+  17,
+  35,
+  53,
+  71,
+  89,
+  107,
+  124,
+  142,
+  160,
+  177,
+  195,
+  212,
+  230,
+  247,
+  265,
+  282,
+  299,
+  316,
+  333,
+  350,
+  366,
+  383,
+  400,
+  416,
+  432,
+  448,
+  464,
+  480,
+  496,
+  512,
+  527,
+  542,
+  557,
+  572,
+  587,
+  601,
+  616,
+  630,
+  644,
+  658,
+  671,
+  685,
+  698,
+  711,
+  724,
+  736,
+  748,
+  760,
+  772,
+  784,
+  795,
+  806,
+  817,
+  828,
+  838,
+  848,
+  858,
+  868,
+  877,
+  886,
+  895,
+  904,
+  912,
+  920,
+  928,
+  935,
+  942,
+  949,
+  955,
+  962,
+  968,
+  973,
+  979,
+  984,
+  989,
+  993,
+  997,
+  1001,
+  1005,
+  1008,
+  1011,
+  1014,
+  1016,
+  1018,
+  1020,
+  1021,
+  1022,
+  1023,
+  1023,
+  1024,
+  1023,
+  1023,
+  1022,
+  1021,
+  1020,
+  1018,
+  1016,
+  1014,
+  1011,
+  1008,
+  1005,
+  1001,
+  997,
+  993,
+  989,
+  984,
+  979,
+  973,
+  968,
+  962,
+  955,
+  949,
+  942,
+  935,
+  928,
+  920,
+  912,
+  904,
+  895,
+  886,
+  877,
+  868,
+  858,
+  848,
+  838,
+  828,
+  817,
+  806,
+  795,
+  784,
+  772,
+  760,
+  748,
+  736,
+  724,
+  711,
+  698,
+  685,
+  671,
+  658,
+  644,
+  630,
+  616,
+  601,
+  587,
+  572,
+  557,
+  542,
+  527,
+  512,
+  496,
+  480,
+  464,
+  448,
+  432,
+  416,
+  400,
+  383,
+  366,
+  350,
+  333,
+  316,
+  299,
+  282,
+  265,
+  247,
+  230,
+  212,
+  195,
+  177,
+  160,
+  142,
+  124,
+  107,
+  89,
+  71,
+  53,
+  35,
+  17,
+  0,
+  -17,
+  -35,
+  -53,
+  -71,
+  -89,
+  -107,
+  -124,
+  -142,
+  -160,
+  -177,
+  -195,
+  -212,
+  -230,
+  -247,
+  -265,
+  -282,
+  -299,
+  -316,
+  -333,
+  -350,
+  -366,
+  -383,
+  -400,
+  -416,
+  -432,
+  -448,
+  -464,
+  -480,
+  -496,
+  -512,
+  -527,
+  -542,
+  -557,
+  -572,
+  -587,
+  -601,
+  -616,
+  -630,
+  -644,
+  -658,
+  -671,
+  -685,
+  -698,
+  -711,
+  -724,
+  -736,
+  -748,
+  -760,
+  -772,
+  -784,
+  -795,
+  -806,
+  -817,
+  -828,
+  -838,
+  -848,
+  -858,
+  -868,
+  -877,
+  -886,
+  -895,
+  -904,
+  -912,
+  -920,
+  -928,
+  -935,
+  -942,
+  -949,
+  -955,
+  -962,
+  -968,
+  -973,
+  -979,
+  -984,
+  -989,
+  -993,
+  -997,
+  -1001,
+  -1005,
+  -1008,
+  -1011,
+  -1014,
+  -1016,
+  -1018,
+  -1020,
+  -1021,
+  -1022,
+  -1023,
+  -1023,
+  -1024,
+  -1023,
+  -1023,
+  -1022,
+  -1021,
+  -1020,
+  -1018,
+  -1016,
+  -1014,
+  -1011,
+  -1008,
+  -1005,
+  -1001,
+  -997,
+  -993,
+  -989,
+  -984,
+  -979,
+  -973,
+  -968,
+  -962,
+  -955,
+  -949,
+  -942,
+  -935,
+  -928,
+  -920,
+  -912,
+  -904,
+  -895,
+  -886,
+  -877,
+  -868,
+  -858,
+  -848,
+  -838,
+  -828,
+  -817,
+  -806,
+  -795,
+  -784,
+  -772,
+  -760,
+  -748,
+  -736,
+  -724,
+  -711,
+  -698,
+  -685,
+  -671,
+  -658,
+  -644,
+  -630,
+  -616,
+  -601,
+  -587,
+  -572,
+  -557,
+  -542,
+  -527,
+  -512,
+  -496,
+  -480,
+  -464,
+  -448,
+  -432,
+  -416,
+  -400,
+  -383,
+  -366,
+  -350,
+  -333,
+  -316,
+  -299,
+  -282,
+  -265,
+  -247,
+  -230,
+  -212,
+  -195,
+  -177,
+  -160,
+  -142,
+  -124,
+  -107,
+  -89,
+  -71,
+  -53,
+  -35,
+  -17
+};
+
+ossimRgbImage::ossimRgbImage()
+   : theImageData(NULL),
+     theOffsets(NULL),
+     theThickness(1),
+     theRed(255),
+     theGreen(255),
+     theBlue(255)
+{
+}
+
+ossimRgbImage::ossimRgbImage(ossimRefPtr<ossimImageData>& currentImageData)
+   : theImageData(NULL),
+     theOffsets(NULL),
+     theThickness(1),
+     theRed(255),
+     theGreen(255),
+     theBlue(255)
+{
+   setCurrentImageData(currentImageData);
+}
+
+
+ossimRgbImage::~ossimRgbImage()
+{
+   if(theOffsets)
+   {
+      delete [] theOffsets;
+      theOffsets = NULL;
+   }
+}
+
+const ossimRefPtr<ossimImageData> ossimRgbImage::getImageData()const
+{
+   return theImageData;
+}
+
+void ossimRgbImage::createNewGrey(long width, long height)
+{
+   theImageData = new ossimImageData(NULL,
+                                     OSSIM_UCHAR,
+                                     1,
+                                     width,
+                                     height);
+   theImageData->initialize();
+
+   setCurrentImageData(theImageData);
+
+}
+
+void ossimRgbImage::createNewTrueColor(long width, long height)
+{
+   theImageData = new ossimImageData(NULL,
+                                     OSSIM_UCHAR,
+                                     3,
+                                     width,
+                                     height);
+   theImageData->initialize();   
+}
+
+void ossimRgbImage::initialize()
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   if(theOffsets)
+   {
+      delete [] theOffsets;
+      theOffsets = NULL;
+   }
+   theWidth  = theImageData->getWidth();
+   theHeight = theImageData->getHeight();
+   
+   theOffsets = new long[theHeight];
+   for(long row = 0; row < theHeight; ++row)
+   {
+      theOffsets[row] = row*theWidth;
+   }
+   
+   // make it work for 1, 2, or 3 band data.
+   // we assume the fourth band is for the alpha channel
+   if(theImageData->getNumberOfBands() == 3)
+   { // point each band to r, g, b.
+      theBands[0] = static_cast<unsigned char*>(theImageData->getBuf(0));
+      theBands[1] = static_cast<unsigned char*>(theImageData->getBuf(1));
+      theBands[2] = static_cast<unsigned char*>(theImageData->getBuf(2));
+   }
+   else if(theImageData->getNumberOfBands() == 2)
+   {//point r and g to the same place
+      theBands[0] = static_cast<unsigned char*>(theImageData->getBuf(0));
+      theBands[1] = static_cast<unsigned char*>(theImageData->getBuf(0));
+      theBands[2] = static_cast<unsigned char*>(theImageData->getBuf(1));
+   }
+   else if(theImageData->getNumberOfBands() == 1)
+   {// point all band s to the first band
+      theBands[0] = static_cast<unsigned char*>(theImageData->getBuf(0));
+      theBands[1] = static_cast<unsigned char*>(theImageData->getBuf(0));
+      theBands[2] = static_cast<unsigned char*>(theImageData->getBuf(0));
+   }
+}
+
+void ossimRgbImage::setCurrentImageData(ossimRefPtr<ossimImageData>& imageData)
+{
+   if(imageData.valid())
+   {
+      if((imageData->getScalarType() == OSSIM_UCHAR)&&
+         (imageData->getDataObjectStatus()!=OSSIM_NULL))
+      {
+         theImageData = imageData;
+         initialize();
+      }
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimRgbImage::getImageData()
+{
+   return theImageData;
+}
+
+
+void ossimRgbImage::drawPolygon(ossimIpt *p,
+                                int n)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   int i;
+   int lx, ly;
+   
+   if (!n)
+   {
+      return;
+   }
+   lx = p->x;
+   ly = p->y;
+   drawLine (lx, ly, p[n - 1].x, p[n - 1].y);
+   
+   for (i = 1; (i < n); i++)
+   {
+      p++;
+      drawLine (lx, ly, p->x, p->y);
+      lx = p->x;
+      ly = p->y;
+   }
+}
+
+void ossimRgbImage::drawPolygon(ossimDpt *p,
+                                int n)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   int i;
+   double lx, ly;
+   
+   if (!n)
+   {
+      return;
+   }
+   lx = p->x;
+   ly = p->y;
+   drawLine (lx, ly, p[n - 1].x, p[n - 1].y);
+   
+   for (i = 1; (i < n); i++)
+   {
+      p++;
+      drawLine (lx, ly, p->x, p->y);
+      lx = p->x;
+      ly = p->y;
+   }
+}
+
+void ossimRgbImage::drawPolygon(const vector<ossimIpt> &p)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   int n = p.size();
+   
+   int i;
+   int lx, ly;
+   
+   if (!n)
+   {
+      return;
+   }
+   lx = p[0].x;
+   ly = p[0].y;
+   drawLine (lx, ly, p[n - 1].x, p[n - 1].y);
+   
+   for (i = 1; (i < n); i++)
+   {
+      drawLine (lx, ly, p[i].x, p[i].y);
+      lx = p[i].x;
+      ly = p[i].y;
+   }
+}
+
+void ossimRgbImage::drawPolygon(const vector<ossimDpt> &p)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   int n = p.size();
+   
+   int i;
+   double lx, ly;
+   
+   if (!n)
+   {
+      return;
+   }
+   lx = p[0].x;
+   ly = p[0].y;
+   drawLine (lx, ly, p[n - 1].x, p[n - 1].y);
+   
+   for (i = 1; (i < n); i++)
+   {
+      drawLine (lx, ly, p[i].x, p[i].y);
+      lx = p[i].x;
+      ly = p[i].y;
+   }
+}
+
+inline int gdCompareInt (const void *a, const void *b)
+{
+  return (*(const int *) a) - (*(const int *) b);
+}
+
+void ossimRgbImage::drawFilledArc (double cx,
+                                   double cy,
+                                   double w,
+                                   double h,
+                                   double s,
+                                   double e)
+{
+//    drawFilledArc((int)irint(cx), // center x
+//                  (int)irint(cy), // center y
+//                  (int)irint(w), // width
+//                  (int)irint(h), // height
+//                  (int)irint(s), // start angle
+//                  (int)irint(e)); // end angle
+   drawFilledArc((int)(cx), // center x
+                 (int)(cy), // center y
+                 (int)(w), // width
+                 (int)(h), // height
+                 (int)(s), // start angle
+                 (int)(e)); // end angle
+}
+
+void ossimRgbImage::drawFilledArc (int cx,
+                                   int cy,
+                                   int w,
+                                   int h,
+                                   int s,
+                                   int e)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   ossimIpt pts[3];
+   int i;
+   int lx = 0, ly = 0;
+   int fx, fy;
+   int w2, h2;
+   w2 = w / 2;
+   h2 = h / 2;
+   while (e < s)
+   {
+      e += 360;
+   }
+   for (i = s; (i <= e); i++)
+   {
+      int x, y;
+      x = ((long) gdCosT[i % 360] * (long) w2 / 1024) + cx;
+      y = ((long) gdSinT[i % 360] * (long) h2 / 1024) + cy;
+      if (i != s)
+      {
+         /* This is expensive! */
+         pts[0].x = lx;
+         pts[0].y = ly;
+         pts[1].x = x;
+         pts[1].y = y;
+         pts[2].x = cx;
+         pts[2].y = cy;
+         drawFilledPolygon (pts, 3);
+      }
+      else
+      {
+         fx = x;
+         fy = y;
+      }
+      lx = x;
+      ly = y;
+   }
+}
+
+void ossimRgbImage::drawArc (int cx,
+                             int cy,
+                             int w,
+                             int h,
+                             int s,
+                             int e)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   int i;
+   int lx = 0, ly = 0;
+   int fx, fy;
+   int w2, h2;
+   w2 = w / 2;
+   h2 = h / 2;
+   while (e < s)
+   {
+      e += 360;
+   }
+   for (i = s; (i <= e); i++)
+   {
+      int x, y;
+      x = ((long) gdCosT[i % 360] * (long) w2 / 1024) + cx;
+      y = ((long) gdSinT[i % 360] * (long) h2 / 1024) + cy;
+      if (i != s)
+      {
+         drawLine (lx, ly, x, y);
+      }
+      else
+      {
+         fx = x;
+         fy = y;
+      }
+      lx = x;
+      ly = y;
+   }
+}
+
+void ossimRgbImage::drawFilledPolygon(ossimIpt *p,
+                                      int n)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   int i;
+   int y;
+   int miny, maxy;
+   int minx, maxx;
+   int x1, y1;
+   int x2, y2;
+   int ind1, ind2;
+   int ints;
+   int *polyInts = NULL;
+   
+   if(!n)
+   {
+      return;
+   }
+   polyInts = new int[n];
+   
+   miny = p[0].y;
+   maxy = p[0].y;
+   minx = p[0].x;
+   maxx = p[0].x;
+   for (i = 1; (i < n); i++)
+   {
+      miny = std::min((int)p[i].y, miny);
+      minx = std::min((int)p[i].x, minx);
+      maxy = std::max((int)p[i].y, maxy);
+      maxx = std::max((int)p[i].x, maxx);
+   }
+   /* Fix in 1.3: count a vertex only once */
+   for (y = miny; (y <= maxy); y++)
+   {
+      ints = 0;
+      for (i = 0; (i < n); i++)
+      {
+         if (!i)
+         {
+            ind1 = n - 1;
+            ind2 = 0;
+         }
+         else
+         {
+            ind1 = i - 1;
+            ind2 = i;
+         }
+         y1 = p[ind1].y;
+         y2 = p[ind2].y;
+         if (y1 < y2)
+         {
+            x1 = p[ind1].x;
+            x2 = p[ind2].x;
+         }
+         else if (y1 > y2)
+         {
+            y2 = p[ind1].y;
+            y1 = p[ind2].y;
+            x2 = p[ind1].x;
+            x1 = p[ind2].x;
+         }
+         else
+         {
+            continue;
+         }
+         if ((y >= y1) && (y < y2))
+         {
+            polyInts[ints++] = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
+         }
+         else if ((y == maxy) && (y > y1) && (y <= y2))
+         {
+            polyInts[ints++] = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
+         }
+      }
+      qsort (polyInts, ints, sizeof (int), gdCompareInt);
+
+      if(ints)
+      {
+         for (i = 0; (i < (ints)); i += 2)
+         {
+            drawLine (polyInts[i], y,
+                      polyInts[i + 1], y);
+         }
+      }
+      else
+      {
+         if((miny == maxy) && (minx==maxx))
+         {
+            drawLine((int)p[0].x, (int)p[0].y, (int)p[0].x, (int)p[0].y);
+         }
+      }
+   }
+
+   if (polyInts) delete [] polyInts;
+}
+
+void ossimRgbImage::drawFilledPolygon(ossimDpt *p,
+                                      int n)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   int i;
+   int y;
+   int miny, maxy;
+   int x1, y1;
+   int x2, y2;
+   int ind1, ind2;
+   int ints;
+   int *polyInts = NULL;
+   
+   if(!n)
+   {
+      return;
+   }
+   polyInts = new int[n];
+   
+//   miny = irint(p[0].y);
+//   maxy = irint(p[0].y);
+   miny = (int)(p[0].y);
+   maxy = (int)(p[0].y);
+   for (i = 1; (i < n); i++)
+   {
+//      int testPy = irint(p[i].y);
+      int testPy = (int)(p[i].y);
+      if (testPy < miny)
+      {
+         miny = testPy;
+      }
+      if (testPy > maxy)
+      {
+         maxy = testPy;
+      }
+   }
+   /* Fix in 1.3: count a vertex only once */
+   for (y = miny; (y <= maxy); y++)
+   {
+      ints = 0;
+      for (i = 0; (i < n); i++)
+      {
+         if (!i)
+         {
+            ind1 = n - 1;
+            ind2 = 0;
+         }
+         else
+         {
+            ind1 = i - 1;
+            ind2 = i;
+         }
+//         y1 = irint(p[ind1].y);
+//         y2 = irint(p[ind2].y);
+         y1 = (int)(p[ind1].y);
+         y2 = (int)(p[ind2].y);
+         if (y1 < y2)
+         {
+            x1 = irint(p[ind1].x);
+            x2 = irint(p[ind2].x);
+         }
+         else if (y1 > y2)
+         {
+//            y2 = irint(p[ind1].y);
+//            y1 = irint(p[ind2].y);
+//            x2 = irint(p[ind1].x);
+//            x1 = irint(p[ind2].x);
+            y2 = (int)(p[ind1].y);
+            y1 = (int)(p[ind2].y);
+            x2 = (int)(p[ind1].x);
+            x1 = (int)(p[ind2].x);
+         }
+         else
+         {
+            continue;
+         }
+         if ((y >= y1) && (y < y2))
+         {
+            polyInts[ints++] = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
+         }
+         else if ((y == maxy) && (y > y1) && (y <= y2))
+         {
+            polyInts[ints++] = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
+         }
+      }
+      qsort (polyInts, ints, sizeof (int), gdCompareInt);
+      
+      for (i = 0; (i < (ints)); i += 2)
+      {
+         drawLine (polyInts[i], y,
+                   polyInts[i + 1], y);
+      }
+   }
+
+   if (polyInts) delete [] polyInts;
+}
+
+void ossimRgbImage::drawFilledPolygon(const vector<ossimIpt> &p)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   int n = p.size();
+   int i;
+   int y;
+   int miny, maxy;
+   int x1, y1;
+   int x2, y2;
+   int ind1, ind2;
+   int ints;
+   int *polyInts = NULL;
+   
+   if(!n)
+   {
+      return;
+   }
+   polyInts = new int[n];
+   
+   miny = p[0].y;
+   maxy = p[0].y;
+   for (i = 1; (i < n); i++)
+   {
+      if (p[i].y < miny)
+      {
+         miny = p[i].y;
+      }
+      if (p[i].y > maxy)
+      {
+         maxy = p[i].y;
+      }
+   }
+   /* Fix in 1.3: count a vertex only once */
+   for (y = miny; (y <= maxy); y++)
+   {
+      ints = 0;
+      for (i = 0; (i < n); i++)
+      {
+         if (!i)
+         {
+            ind1 = n - 1;
+            ind2 = 0;
+         }
+         else
+         {
+            ind1 = i - 1;
+            ind2 = i;
+         }
+         y1 = p[ind1].y;
+         y2 = p[ind2].y;
+         if (y1 < y2)
+         {
+            x1 = p[ind1].x;
+            x2 = p[ind2].x;
+         }
+         else if (y1 > y2)
+         {
+            y2 = p[ind1].y;
+            y1 = p[ind2].y;
+            x2 = p[ind1].x;
+            x1 = p[ind2].x;
+         }
+         else
+         {
+            continue;
+         }
+         if ((y >= y1) && (y < y2))
+         {
+            polyInts[ints++] = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
+         }
+         else if ((y == maxy) && (y > y1) && (y <= y2))
+         {
+            polyInts[ints++] = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
+         }
+      }
+      qsort (polyInts, ints, sizeof (int), gdCompareInt);
+      
+      for (i = 0; (i < (ints)); i += 2)
+      {
+         drawLine (polyInts[i], y,
+                   polyInts[i + 1], y);
+      }
+   }
+
+   if (polyInts) delete [] polyInts;
+}
+
+void ossimRgbImage::drawFilledPolygon(const vector<ossimDpt> &p)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   int n = p.size();
+   int i;
+   int y;
+   int miny, maxy;
+   int x1, y1;
+   int x2, y2;
+   int ind1, ind2;
+   int ints;
+   int *polyInts = NULL;
+   
+   if(!n)
+   {
+      return;
+   }
+   polyInts = new int[n];
+   
+   miny = (int)p[0].y;//irint(p[0].y);
+   maxy = (int)p[0].y;//irint(p[0].y);
+   for (i = 1; (i < n); i++)
+   {
+      int testPy = (int)p[i].y;//irint(p[i].y);
+      if (testPy < miny)
+      {
+         miny = testPy;
+      }
+      if (testPy > maxy)
+      {
+         maxy = testPy;
+      }
+   }
+   /* Fix in 1.3: count a vertex only once */
+   for (y = miny; (y <= maxy); y++)
+   {
+      ints = 0;
+      for (i = 0; (i < n); i++)
+      {
+         if (!i)
+         {
+            ind1 = n - 1;
+            ind2 = 0;
+         }
+         else
+         {
+            ind1 = i - 1;
+            ind2 = i;
+         }
+//          y1 = irint(p[ind1].y);
+//          y2 = irint(p[ind2].y);
+         y1 = (int)(p[ind1].y);
+         y2 = (int)(p[ind2].y);
+         if (y1 < y2)
+         {
+//            x1 = irint(p[ind1].x);
+//            x2 = irint(p[ind2].x);
+            x1 = (int)(p[ind1].x);
+            x2 = (int)(p[ind2].x);
+         }
+         else if (y1 > y2)
+         {
+//             y2 = irint(p[ind1].y);
+//             y1 = irint(p[ind2].y);
+//             x2 = irint(p[ind1].x);
+//             x1 = irint(p[ind2].x);
+            y2 = (int)(p[ind1].y);
+            y1 = (int)(p[ind2].y);
+            x2 = (int)(p[ind1].x);
+            x1 = (int)(p[ind2].x);
+         }
+         else
+         {
+            continue;
+         }
+         if ((y >= y1) && (y < y2))
+         {
+            polyInts[ints++] = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
+         }
+         else if ((y == maxy) && (y > y1) && (y <= y2))
+         {
+            polyInts[ints++] = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
+         }
+      }
+      qsort (polyInts, ints, sizeof (int), gdCompareInt);
+      
+      for (i = 0; (i < (ints)); i += 2)
+      {
+         drawLine (polyInts[i], y,
+                   polyInts[i + 1], y);
+      }
+   }
+
+   if (polyInts) delete [] polyInts;
+}
+
+void ossimRgbImage::drawLine(const ossimIpt& start,
+                             const ossimIpt& end)
+{
+   drawLine((int)start.x,
+            (int)start.y,
+            (int)end.x,
+            (int)end.y);
+   
+}
+
+void ossimRgbImage::drawLine(const ossimDpt& start,
+                             const ossimDpt& end)
+{
+//    drawLine((int)irint(start.x),
+//             (int)irint(start.y),
+//             (int)irint(end.x),
+//             (int)irint(end.y));
+
+   drawLine((int)(start.x),
+            (int)(start.y),
+            (int)(end.x),
+            (int)(end.y));
+   
+}
+
+void ossimRgbImage::drawLine(double x1,
+                             double y1,
+                             double x2,
+                             double y2)
+{
+//    drawLine((int)irint(x1),
+//             (int)irint(y1),
+//             (int)irint(x2),
+//             (int)irint(y2));
+   drawLine((int)(x1),
+            (int)(y1),
+            (int)(x2),
+            (int)(y2));
+   
+}
+void ossimRgbImage::drawLine(int x1,
+                             int y1,
+                             int x2,
+                             int y2)
+{
+   if(!theImageData)
+   {
+      return;
+   }
+
+   // we need to shift x and y relative to the image data
+   // origin.  That way we are doing the algorithm relative to
+   // the 0,0
+   //
+   ossimIpt origin = ossimDpt(theImageData->getOrigin());
+   x1 += (-origin.x);
+   y1 += (-origin.y);
+   x2 += (-origin.x);
+   y2 += (-origin.y);
+
+//   ossimDpt start(x1, y1);
+//   ossimDpt end(x2,y2);
+//   ossimDrect bounds(0,0,theWidth-1, theHeight-1);
+
+//   if(bounds.clip(start, end)) return;
+
+//   x1 = (int)start.x;
+//   y1 = (int)start.y;
+//   x2 = (int)end.x;
+//   y2 = (int)end.y;
+   
+   int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
+   int wid;
+   int w, wstart;
+   int thick = theThickness;
+   
+  dx = abs (x2 - x1);
+  dy = abs (y2 - y1);
+  if (dy <= dx)
+    {
+      /* More-or-less horizontal. use wid for vertical stroke */
+      /* Doug Claar: watch out for NaN in atan2 (2.0.5) */
+      if ((dx == 0) && (dy == 0))
+	{
+	  wid = 1;
+	}
+      else
+	{
+	  /* 2.0.12: Michael Schwartz: divide rather than multiply;
+	     TBB: but watch out for /0! */
+	  double ac = cos (atan2 ((double)dy, (double)dx));
+	  if (ac != 0)
+	    {
+	      wid = irint(thick / ac);
+	    }
+	  else
+	    {
+	      wid = 1;
+	    }
+	  if (wid == 0)
+	    {
+	      wid = 1;
+	    }
+	}
+      d = 2 * dy - dx;
+      incr1 = 2 * dy;
+      incr2 = 2 * (dy - dx);
+      if (x1 > x2)
+	{
+	  x = x2;
+	  y = y2;
+	  ydirflag = (-1);
+	  xend = x1;
+	}
+      else
+	{
+	  x = x1;
+	  y = y1;
+	  ydirflag = 1;
+	  xend = x2;
+	}
+
+      /* Set up line thickness */
+      wstart = y - wid / 2;
+      for (w = wstart; w < wstart + wid; w++)
+	slowPlotPixel(x, w, theRed, theGreen, theBlue);
+
+      if (((y2 - y1) * ydirflag) > 0)
+	{
+	  while (x < xend)
+	    {
+	      x++;
+	      if (d < 0)
+		{
+		  d += incr1;
+		}
+	      else
+		{
+		  y++;
+		  d += incr2;
+		}
+	      wstart = y - wid / 2;
+	      for (w = wstart; w < wstart + wid; w++)
+		slowPlotPixel(x, w, theRed, theGreen, theBlue);
+	    }
+	}
+      else
+	{
+	  while (x < xend)
+	    {
+	      x++;
+	      if (d < 0)
+		{
+		  d += incr1;
+		}
+	      else
+		{
+		  y--;
+		  d += incr2;
+		}
+	      wstart = y - wid / 2;
+	      for (w = wstart; w < wstart + wid; w++)
+		slowPlotPixel(x, w, theRed, theGreen, theBlue);
+	    }
+	}
+    }
+  else
+    {
+      /* More-or-less vertical. use wid for horizontal stroke */
+      /* 2.0.12: Michael Schwartz: divide rather than multiply;
+         TBB: but watch out for /0! */
+      double as = sin (atan2 ((double)dy, (double)dx));
+      if (as != 0)
+	{
+	  wid = irint(thick / as);
+	}
+      else
+	{
+	  wid = 1;
+	}
+      if (wid == 0)
+	wid = 1;
+
+      d = 2 * dx - dy;
+      incr1 = 2 * dx;
+      incr2 = 2 * (dx - dy);
+      if (y1 > y2)
+	{
+	  y = y2;
+	  x = x2;
+	  yend = y1;
+	  xdirflag = (-1);
+	}
+      else
+	{
+	  y = y1;
+	  x = x1;
+	  yend = y2;
+	  xdirflag = 1;
+	}
+
+      /* Set up line thickness */
+      wstart = x - wid / 2;
+      for (w = wstart; w < wstart + wid; w++)
+	slowPlotPixel(w, y, theRed, theGreen, theBlue);
+
+      if (((x2 - x1) * xdirflag) > 0)
+	{
+	  while (y < yend)
+	    {
+	      y++;
+	      if (d < 0)
+		{
+		  d += incr1;
+		}
+	      else
+		{
+		  x++;
+		  d += incr2;
+		}
+	      wstart = x - wid / 2;
+	      for (w = wstart; w < wstart + wid; w++)
+		slowPlotPixel(w, y, theRed, theGreen, theBlue);
+	    }
+	}
+      else
+	{
+	  while (y < yend)
+	    {
+	      y++;
+	      if (d < 0)
+		{
+		  d += incr1;
+		}
+	      else
+		{
+		  x--;
+		  d += incr2;
+		}
+	      wstart = x - wid / 2;
+	      for (w = wstart; w < wstart + wid; w++)
+		slowPlotPixel(w, y, theRed, theGreen, theBlue);
+	    }
+	}
+    }
+}
+void ossimRgbImage::drawRectangle(double x1,
+                                  double y1,
+                                  double x2,
+                                  double y2)
+{
+//    drawRectangle(irint(x1),
+//                  irint(y1),
+//                  irint(x2),
+//                  irint(y2));
+   drawRectangle((int)(x1),
+                 (int)(y1),
+                 (int)(x2),
+                 (int)(y2));
+}
+
+void ossimRgbImage::drawRectangle(int x1,
+                                  int y1,
+                                  int x2,
+                                  int y2)
+{
+  if(x1 > x2)
+  {
+     swap(x1, x2);
+  }
+  if(y1 > y2)
+  {
+     swap(y1, y2);
+  }
+  int x1h = x1,
+      x1v = x1,
+      y1h = y1,
+      y1v = y1,
+      x2h = x2,
+      x2v = x2,
+      y2h = y2,
+      y2v = y2;
+  
+  int thick = theThickness;
+  
+  
+  if (thick > 1)
+    {
+      int half = thick / 2;
+      int half1 = thick - half;
+
+      if (y1 < y2)
+	{
+	  y1v = y1h - half;
+	  y2v = y2h + half1 - 1;
+	}
+      else
+	{
+	  y1v = y1h + half1 - 1;
+	  y2v = y2h - half;
+	}
+    }
+
+  drawLine (x1h, y1h, x2h, y1h);
+  drawLine (x1h, y2h, x2h, y2h);
+  drawLine (x1v, y1v, x1v, y2v);
+  drawLine (x2v, y1v, x2v, y2v);
+}
+
+
+void ossimRgbImage::drawFilledRectangle(double x1,
+                                        double y1,
+                                        double x2,
+                                        double y2)
+{
+//   drawFilledRectangle((int)irint(x1),
+//                       (int)irint(y1),
+//                       (int)irint(x2),
+//                       (int)irint(y2));
+   drawFilledRectangle((int)(x1),
+                       (int)(y1),
+                       (int)(x2),
+                       (int)(y2));
+}
+
+void ossimRgbImage::drawFilledRectangle(int x1,
+                                        int y1,
+                                        int x2,
+                                        int y2)
+{
+   int x, y;
+
+   if(x1 > x2)
+   {
+      swap(x1, x2);
+   }
+   if(y1 > y2)
+   {
+      swap(y1, y2);
+   }
+   for (y = y1; (y <= y2); y++)
+   {
+      for (x = x1; (x <= x2); x++)
+      {
+         slowPlotPixel (x, y, theRed, theGreen, theBlue);
+      }
+   }
+}
+
+void ossimRgbImage::fill()
+{
+   if(!theImageData)
+   {
+      return;
+   }
+   long width = theWidth;
+   long height = theHeight;
+   
+   for(long row = 0; row < height; ++row)
+   {
+      for(long col = 0; col < width; ++col)
+      {
+         fastPlotPixel(col, row,
+                       theRed, theGreen, theBlue);
+      }
+   }
+}
+
+void ossimRgbImage::setDrawColor(unsigned char r,
+                                 unsigned char g,
+                                 unsigned char b)
+{
+   theRed   = r;
+   theGreen = g;
+   theBlue  = b;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimRgbImage.h b/Utilities/OSSIM/ossim_core/imaging/ossimRgbImage.h
new file mode 100644
index 0000000000..da9af0bb98
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimRgbImage.h
@@ -0,0 +1,370 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbImage.h,v 1.14 2005/05/20 20:22:41 dburken Exp $
+#ifndef ossimRgbImage_HEADER
+#define ossimRgbImage_HEADER
+#include <base/data_types/ossimIpt.h>
+#include <imaging/ossimImageData.h>
+
+#include <vector>
+using namespace std;
+
+class OSSIM_DLL ossimRgbImage
+{
+public:
+   ossimRgbImage();
+   ossimRgbImage(ossimRefPtr<ossimImageData>& currentImageData);
+   
+   virtual ~ossimRgbImage();
+
+   /**
+    * Will construct a new single band image data object.
+    */
+   virtual void createNewGrey(long width, long height);
+
+   /**
+    * Will construct a new 3 band rgb data object.
+    */
+   virtual void createNewTrueColor(long width, long height);
+
+   /**
+    * Will initilize any pre-computations that are needed.
+    * Example: setting up the origin for adjustments and
+    *          setting up the offsets.
+    */
+    virtual void initialize();
+    
+   /**
+    * This will plot a pixel and will do inside outside compares.
+    * This assumes the pixel has already been put into a relative
+    * 0,0 to the upper left corner of the image data.
+    *
+    * example: if the upperleft corner or origin of the image was
+    *          34, 55 then it assumes that the points passed in are
+    *          already relative to that corner not absolute.
+    */
+   inline void slowPlotPixel(long x,
+                             long y,
+                             unsigned char r,
+                             unsigned char g,
+                             unsigned char b);
+
+   /**
+    * same thing as slowPlotPixel but without the inside outside compare
+    */
+   inline void fastPlotPixel(long x,
+                             long y,
+                             unsigned char r,
+                             unsigned char g,
+                             unsigned char b);
+   
+   /**
+    * All the drawing algorithms have thickness.  So you can draw a line
+    * that has thickness of 3 pixels if you want.  Note: the thickness is in
+    * pixels
+    */
+   void setThickness(long thickness){theThickness = thickness;}
+                         
+
+   /**
+    * Allows you to change the image data that this RgbImage object
+    * operates on.  You can specify if the image owns the data or not.
+    * if it doesn't own the data then it will not destroy it when the
+    * data is changed to a different data object or if this object
+    * is deleted.
+    */ 
+   void setCurrentImageData(ossimRefPtr<ossimImageData>& imageData);
+   /**
+    * Will return the image data.
+    */
+   ossimRefPtr<ossimImageData> getImageData();
+
+   /**
+    * We will cut and paste the code from
+    * drawFilledPolygon(ossimIpt *p, int n).
+    */
+   void drawFilledPolygon(const vector<ossimDpt>& p);
+   /**
+    * We will cut and paste the code from
+    * drawFilledPolygon(ossimIpt *p, int n).
+    */
+   void drawFilledPolygon(const vector<ossimIpt>& p);
+
+   
+   /**
+    * This will draw a polygon and fill it with the specified color.
+    */
+   void drawFilledPolygon(ossimDpt *p,
+                          int n);
+   /**
+    * This will draw a polygon and fill it with the specified color.
+    */
+   void drawFilledPolygon(ossimIpt *p,
+                          int n);
+
+   /**
+    * will draw an arc.  The cx and cy specifies the center point in image
+    * space.  The parameters w, h are the width and height of the arc.
+    * The s and e are the starting and ending angles.  So if I want to
+    * draw a complete circle at point 45, 45 with width 10 and height 23 then
+    * we set the angles s =0 and e = 360:
+    * drawArc(45, 45, 10, 23, 0, 360).
+    *
+    */
+   void drawArc(double cx,
+                double cy,
+                double w,
+                double h,
+                double s,
+                double e);
+
+   /**
+    * will draw an arc.  The cx and cy specifies the center point in image
+    * space.  The parameters w, h are the width and height of the arc.
+    * The s and e are the starting and ending angles.  So if I want to
+    * draw a complete circle at point 45, 45 with width 10 and height 23 then
+    * we set the angles s =0 and e = 360:
+    * drawArc(45, 45, 10, 23, 0, 360).
+    *
+    */
+   void drawArc(int cx,
+                int cy,
+                int w,
+                int h,
+                int s,
+                int e);
+   
+   /**
+    * This will draw a filled arc.  See drawArc for documentation of
+    * parameters.
+    */
+   void drawFilledArc(double cx,
+                      double cy,
+                      double w,
+                      double h,
+                      double s,
+                      double e);
+
+   /**
+    * This will draw a filled arc.  See drawArc for documentation of
+    * parameters.
+    */
+   void drawFilledArc(int cx,
+                      int cy,
+                      int w,
+                      int h,
+                      int s,
+                      int e);
+   
+   void drawPolygon(const vector<ossimDpt>& p);
+   void drawPolygon(const vector<ossimIpt>& p);
+   
+   /**
+    * Draws a polygon.  The first argument is an array of points.  The second
+    * argument is the number of points and the rest are the rgb color values.
+    * theColor used is set by the setDrawColor.
+    */
+   void drawPolygon(ossimDpt *p,
+                    int n);
+
+   /**
+    * Draws a polygon.  The first argument is an array of points.  The second
+    * argument is the number of points and the rest are the rgb color values.
+    * theColor used is set by the setDrawColor.
+    */
+   void drawPolygon(ossimIpt *p,
+                    int n);
+   
+   /**
+    * About all the draw routines will call draw line.  it takes a start and
+    * an end point and a color value.
+    * theColor used is set by the setDrawColor.
+    */
+   void drawLine(double x1,
+                 double y1,
+                 double x2,
+                 double y2);
+
+   /**
+    * About all the draw routines will call draw line.  it takes a start and
+    * an end point and a color value.
+    * theColor used is set by the setDrawColor.
+    */
+   void drawLine(int x1,
+                 int y1,
+                 int x2,
+                 int y2);
+
+   /**
+    * About all the draw routines will call draw line.  it takes a start and
+    * an end point and a color value.
+    * theColor used is set by the setDrawColor.
+    */
+   void drawLine(const ossimIpt& start,
+                 const ossimIpt& end);
+   /**
+    * About all the draw routines will call draw line.  it takes a start and
+    * an end point and a color value.
+    * theColor used is set by the setDrawColor.
+    */
+   void drawLine(const ossimDpt& start,
+                 const ossimDpt& end);
+
+
+   /**
+    * Will draw a rectangle.  The color used is set by setDrawColor.
+    */
+   void drawRectangle(double x1,
+                      double y1,
+                      double x2,
+                      double y2);
+
+   /**
+    * Will draw a rectangle.  The color used is set by setDrawColor.
+    */
+   void drawRectangle(int x1,
+                      int y1,
+                      int x2,
+                      int y2);
+   
+   /**
+    * Will draw a filled rectangle with the current draw color.
+    * Use setDrawColor to set it.
+    */
+   void drawFilledRectangle(double x1,
+                            double y1,
+                            double x2,
+                            double y2);
+
+   /**
+    * Will draw a filled rectangle with the current draw color.
+    * Use setDrawColor to set it.
+    */
+   void drawFilledRectangle(int x1,
+                            int y1,
+                            int x2,
+                            int y2);
+   
+   /**
+    * Will fill the entire data object with the specified color set in
+    * setDrawColor.
+    */ 
+   void fill();
+
+   void setDrawColor(unsigned char r = 255,
+                     unsigned char g = 255,
+                     unsigned char b = 255);
+   /**
+    * Will take the point passed in and translate
+    * to a 0,0.
+    * Example:
+    *   Let's say that we have origin 45,34 for the
+    *   image's upper left corner. then a call to this
+    *   method will translate the point passed in
+    *   x-45, y-34
+    */
+//   inline void translateToOrigin(long& x, long& y);
+
+   /**
+    * Will take the point passed in and translate
+    * to a 0,0.
+    * Example:
+    *   Let's say that we have origin 45,34 for the
+    *   image's upper left corner. then a call to this
+    *   method will translate the point passed in
+    *   x-45, y-34
+    */
+//   inline void translateToOrigin(ossimDpt& pt);
+   const ossimRefPtr<ossimImageData> getImageData()const;
+
+protected:
+
+   /**
+    * This object operates on the ossimImageData.  Note the
+    * ossimImageData is a band separate so the bands follow sequentially:
+    * all the reds followed by all the blues followed by all greens
+    */
+   ossimRefPtr<ossimImageData> theImageData;
+
+   /**
+    * This will hold precomputed offsets to the
+    * start of each row.  This will get rid of a multiplication
+    * per access. Since we will be accessing on a per pixel basis
+    * this will be needed.
+    */
+   long            *theOffsets;
+
+   /**
+    * This is a fast access to the start of each band.
+    */
+   unsigned char*   theBands[3];
+
+   /**
+    * This is here so we don't have to call theWidth and theHeight
+    * of the ossimImageData.  
+    */ 
+   long             theWidth;
+
+   /**
+    * This is here so we don't have to call theWidth and theHeight
+    * of the ossimImageData.  
+    */ 
+   long             theHeight;
+
+   /**
+    * Holds the draw thickness.
+    */
+   long             theThickness;
+
+
+   /**
+    * The red component of the color used in drawing the shapes
+    */
+   unsigned char theRed;
+
+   /**
+    * The green component of the color used in drawing the shapes
+    */
+   unsigned char theGreen;
+
+   /**
+    * The blue component of the color used in drawing the shapes
+    */
+   unsigned char theBlue;
+};
+
+inline void ossimRgbImage::slowPlotPixel(long x,
+                                         long y,
+                                         unsigned char r,
+                                         unsigned char g,
+                                         unsigned char b)
+{
+   if((x > -1) && (x < theWidth) &&
+      (y > -1) && (y < theHeight))
+   {
+      theBands[0][theOffsets[y]+x] = r;
+      theBands[1][theOffsets[y]+x] = g;
+      theBands[2][theOffsets[y]+x] = b;
+   }
+}
+
+inline void ossimRgbImage::fastPlotPixel(long x,
+                                         long y,
+                                         unsigned char r,
+                                         unsigned char g,
+                                         unsigned char b)
+{
+   theBands[0][theOffsets[y]+x] = r;
+   theBands[1][theOffsets[y]+x] = g;
+   theBands[2][theOffsets[y]+x] = b;
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimS16ImageData.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimS16ImageData.cpp
new file mode 100644
index 0000000000..4921c3a5be
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimS16ImageData.cpp
@@ -0,0 +1,716 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class definition of ossimU16ImageData.  Specialized image data object for
+// signed short data.
+//
+//*************************************************************************
+// $Id: ossimS16ImageData.cpp,v 1.19 2004/09/02 13:59:03 dburken Exp $
+
+#include <imaging/ossimS16ImageData.h>
+#include <base/common/ossimErrorCodes.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+
+RTTI_DEF1(ossimS16ImageData, "ossimS16ImageData", ossimImageData)
+
+ossimS16ImageData::ossimS16ImageData()
+   :
+      ossimImageData()
+{
+}
+
+ossimS16ImageData::ossimS16ImageData(ossimSource* source,
+                                     ossim_uint32 bands)
+   :
+      ossimImageData(source,
+                     OSSIM_SSHORT16,
+                     bands)
+{
+}
+
+ossimS16ImageData::ossimS16ImageData(ossimSource* source,
+                                     ossim_uint32 bands,
+                                     ossim_uint32 width,
+                                     ossim_uint32 height)
+   :
+      ossimImageData(source,
+                     OSSIM_SSHORT16,
+                     bands,
+                     width,
+                     height)
+{
+}
+
+ossimS16ImageData::ossimS16ImageData(const ossimS16ImageData &rhs)
+   :
+      ossimImageData(rhs)
+{
+}
+
+ossimS16ImageData::~ossimS16ImageData()
+{
+}
+
+ossimObject* ossimS16ImageData::dup()const
+{
+   return new ossimS16ImageData(*this);
+}
+
+ossimDataObjectStatus ossimS16ImageData::validate() const
+{
+   if (theDataBuffer == NULL)
+   {
+      setDataObjectStatus(OSSIM_NULL);
+      return OSSIM_NULL;
+   }
+   
+   ossim_uint32 count = 0;
+   const ossim_uint32 SIZE = getSize();
+   const ossim_uint32 BOUNDS = getSizePerBand();
+   const ossim_uint32 NUMBER_OF_BANDS = getNumberOfBands();
+   
+   for(ossim_uint32 band = 0; band < NUMBER_OF_BANDS; ++band)
+   {
+      ossim_sint16 np = (ossim_sint16)theNullPixelValue[band];
+      const ossim_sint16* p  = getSshortBuf(band);
+      for (ossim_uint32 i=0; i<BOUNDS; i++)
+      {
+         // check if the band is null
+         if (p[i] != np) count++;         
+      }
+   }
+   
+   if (!count)
+      setDataObjectStatus(OSSIM_EMPTY);
+   else if (count == SIZE)
+      setDataObjectStatus(OSSIM_FULL);
+   else
+      setDataObjectStatus(OSSIM_PARTIAL);
+
+   return getDataObjectStatus();
+}
+
+void ossimS16ImageData::getNormalizedFloat(ossim_uint32 offset,
+                                           ossim_uint32 bandNumber,
+                                           float& result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   
+   // make sure that the types and width and height are good.
+   if( (getDataObjectStatus() == OSSIM_NULL) && isValidBand(bandNumber) )
+   {
+      return;
+   }
+   
+   ossim_int32 p = getSshortBuf(bandNumber)[offset];
+
+   getNormFromPix(p, result, bandNumber);
+}
+
+void ossimS16ImageData::setNormalizedFloat(ossim_uint32 offset,
+                                           ossim_uint32 bandNumber,
+                                           float inputValue)
+{
+   // make sure that the types and width and height are
+   // good.
+   if((getDataObjectStatus() == OSSIM_NULL)&&
+      (bandNumber < getNumberOfBands()))
+   {
+      return;
+   }
+
+   ossim_int32 p;
+
+   getPixFromNorm(p, inputValue, bandNumber);
+   
+   getSshortBuf(bandNumber)[offset] = static_cast<ossim_sint16>(p);
+}
+
+void
+ossimS16ImageData::convertToNormalizedFloat(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_FLOAT) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 bandCount = 0; bandCount < theNumberOfDataComponents;
+          ++bandCount)
+      {
+         const ossim_sint16* sourceBuf = getSshortBuf(bandCount);
+         ossim_float32* resultBuf = static_cast<ossim_float32*>(result->getBuf(bandCount));
+         for(ossim_uint32 counter = 0; counter <  size; ++counter)
+         {
+            getNormFromPix(sourceBuf[counter], resultBuf[counter], bandCount);
+         }
+      }
+   }
+}
+
+void ossimS16ImageData::convertToNormalizedDouble(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_FLOAT) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 bandCount = 0; bandCount < theNumberOfDataComponents;
+          ++bandCount)
+      {
+         const ossim_sint16* sourceBuf = getSshortBuf(bandCount);
+         ossim_float64* resultBuf = static_cast<ossim_float64*>(result->getBuf(bandCount));
+         for(ossim_uint32 counter = 0; counter <  size; ++counter)
+         {
+            getNormFromPix(sourceBuf[counter],
+                           resultBuf[counter],
+                           bandCount);
+         }
+      }
+   }
+
+}
+
+void ossimS16ImageData::unnormalizeInput(ossimImageData* normalizedInput)
+{
+   if((normalizedInput->getScalarType() != OSSIM_NORMALIZED_FLOAT) &&
+      (normalizedInput->getScalarType() != OSSIM_NORMALIZED_DOUBLE) )
+   {
+      //ERROR
+      return;
+   }
+   
+   ossim_uint32 counter = 0;
+   ossim_uint32 bandCount = 0;
+   ossim_uint32 size = getSizePerBand();
+   ossimScalarType scalarType = normalizedInput->getScalarType();
+
+   if(size > 0)
+   {
+      if(scalarType == OSSIM_NORMALIZED_FLOAT)
+      {
+         for(bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+         {
+            ossim_float32* sourceBuf =
+               static_cast<ossim_float32*>(normalizedInput->getBuf(bandCount));
+            ossim_sint16* resultBuf = getSshortBuf(bandCount);
+            for(counter = 0; counter <  size; ++counter)
+            {
+               ossim_float32 f = sourceBuf[counter];
+               ossim_int32 p;
+               getPixFromNorm(p, f, bandCount);
+               resultBuf[counter] = static_cast<ossim_sint16>(p);
+            }
+         }
+      }
+      else // Double
+      {
+         for(bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+         {
+            ossim_float64* sourceBuf =
+               static_cast<ossim_float64*>(normalizedInput->getBuf(bandCount));
+            ossim_sint16* resultBuf = getSshortBuf(bandCount);
+            for(counter = 0; counter <  size; ++counter)
+            {
+               ossim_int32 p;
+               getPixFromNorm(p, sourceBuf[counter], bandCount);
+               resultBuf[counter] = static_cast<ossim_sint16>(p);
+            }
+         }
+      }
+   }   
+}
+
+double ossimS16ImageData::computeMeanSquaredError(double meanValue,
+                                                  ossim_uint32 bandNumber)
+{
+   double result = -1; // invalid MSE
+   ossim_uint32 index = 0;
+   double delta = 0;
+   ossim_uint32 validPixelCount=0;
+   
+   ossim_sint16* buffer = getSshortBuf(bandNumber);
+   if(buffer)
+   {
+      ossim_uint32 bounds = getWidth()*getHeight();
+      for(index = 0; index < bounds; ++index)
+      {
+         if(!isNull(index))
+         {
+            delta = *buffer - meanValue;
+            result += (delta*delta);
+            ++validPixelCount;
+         }
+         ++buffer;
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+//******************************************************************
+//
+// NOTE: I was checking for null and not adding it to the histogram.
+//       this was messing up the equalization algorithms since the
+//       accumulation histogram did not represent the area of the
+//       image.  For now I will leave out the check for "is null" and
+//       add this to the count so that the total accumulation is the
+//       area of the image.
+//
+//******************************************************************
+void ossimS16ImageData::populateHistogram(ossimMultiBandHistogram* histo)
+{
+   ossim_uint32 numberOfBands = getNumberOfBands();
+
+   if( (getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return;
+   }
+
+   for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+   {
+      ossimHistogram* currentHisto = histo->getHistogram(band);
+      ossim_sint16* buffer = getSshortBuf(band);
+      
+      if(currentHisto)
+      {
+         float *counts = currentHisto->GetCounts();
+         ossim_uint32 upperBound = getWidth()*getHeight();
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            counts[buffer[offset]]++;
+         }
+      }
+   }
+}
+
+double ossimS16ImageData::computeAverageBandValue(ossim_uint32 bandNumber)
+{
+   double result = 0.0;
+   ossim_uint32 index = 0;
+   ossim_uint32 validPixelCount=0;
+   
+   ossim_sint16* buffer = getSshortBuf(bandNumber);
+   if(buffer)
+   {
+      ossim_uint32 bounds = getSizePerBand();
+      for(index = 0; index < bounds; ++index)
+      {
+         if(!isNull(index))
+         {
+            result += *buffer;
+            ++validPixelCount;
+         }
+         ++buffer;
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+void ossimS16ImageData::makeBlank()
+{
+   void* s = getBuf();
+
+   if (s == NULL) return; // nothing to do...
+   
+   ossim_uint32 size_in_pixels = getSizePerBand();
+   
+   for(ossim_uint32 band =0; band < getNumberOfBands(); ++band)
+   {
+      ossim_sint16 np = (ossim_sint16)theNullPixelValue[band];
+      ossim_sint16* p = getSshortBuf(band);
+      for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+   }
+
+   setDataObjectStatus(OSSIM_EMPTY);
+}
+
+void ossimS16ImageData::setValue(ossim_int32 x, ossim_int32 y, double color)
+{
+   if(theDataBuffer&&isWithin(x, y))
+   {
+      //***
+      // Compute the offset into the buffer for (x,y).  This should always
+      // come out positive.
+      //***
+      ossim_uint32 ux = static_cast<ossim_uint32>(x - theOrigin.x);
+      ossim_uint32 uy = static_cast<ossim_uint32>(y - theOrigin.y);
+
+      ossim_uint32 offset = uy * theSpatialExtents[0] + ux;
+      
+      for(ossim_uint32 band = 0; band < theNumberOfDataComponents; band++)
+      {
+         ossim_sint16* buf = getSshortBuf(band)+offset;
+         *buf = (ossim_sint16)color;
+      }
+   }
+}
+
+void ossimS16ImageData::fill(ossim_uint32 band, double value)
+{
+   void* s         = getBuf(band);
+
+   if (s == NULL) return; // nothing to do...
+
+   ossim_uint32 size_in_pixels = getSizePerBand();
+   ossim_sint16* p = getSshortBuf(band);
+
+   for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = (ossim_sint16)value;
+
+   // Set the status to unknown since we don't know about the other bands.
+   setDataObjectStatus(OSSIM_STATUS_UNKNOWN);
+}
+
+
+bool ossimS16ImageData::isNull(ossim_uint32 offset)const
+{
+   for(ossim_uint32 band = 0; band < getNumberOfBands(); ++band)  
+   {
+      const ossim_sint16* buf = getSshortBuf(band)+offset;
+      
+      if((*buf) != theNullPixelValue[band])
+      {
+         return false;
+      }
+   }
+
+   return true;
+}
+
+void ossimS16ImageData::setNull(ossim_uint32 offset)
+{
+   for(ossim_uint32 band = 0; band < getNumberOfBands(); ++band)  
+   {
+      ossim_sint16* buf = getSshortBuf(band)+offset;
+      *buf       = static_cast<ossim_sint16>(theNullPixelValue[band]);
+   }
+}
+
+void ossimS16ImageData::loadBand(const void* src,
+                                 const ossimIrect& src_rect,
+                                 ossim_uint32 band)
+{
+   ossimImageData::loadBand(ossim_sint16(0), src, src_rect, band);
+}
+
+void ossimS16ImageData::loadTile(void* src,
+                                const ossimIrect& src_rect,
+                                ossimInterleaveType il_type)
+{
+   // Load the tile from the buffer.
+   switch (il_type)
+   {
+      case OSSIM_BIP:
+         ossimImageData::loadTileFromBip(ossim_sint16(0), src, src_rect);
+         break;
+      case OSSIM_BIL:
+         ossimImageData::loadTileFromBil(ossim_sint16(0), src, src_rect);
+         break;
+      case OSSIM_BSQ:
+         ossimImageData::loadTileFromBsq(ossim_sint16(0), src, src_rect);
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimS16ImageData::loadTile"
+            << "\nUnknown interleave type passed to method.  Returning..."
+            << endl;
+         break;
+   } 
+}
+
+void ossimS16ImageData::unloadBand(void* dest,
+                                   const ossimIrect& dest_rect,
+                                   ossim_uint32 band) const
+{
+   ossimImageData::unloadBand(ossim_sint16(0), dest, dest_rect,
+                              getImageRectangle(), band);
+}
+
+void ossimS16ImageData::copyTileToNormalizedBuffer(double* buf) const
+{
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimS16ImageData::copyTileToNormalizedBuffer ERROR:"
+           << "\nBuffer passed to method is NULL!"
+           << endl;
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         const ossim_sint16* s = getSshortBuf(band);  // source
+         ossim_float64*      d = buf + (band*size);   // destination
+
+         for(ossim_uint32 index = 0; index < size; index++)
+         {
+            getNormFromPix(s[index], d[index], band);
+         }
+      }
+   }
+}
+
+void ossimS16ImageData::copyTileToNormalizedBuffer(ossim_uint32 band,
+                                                   double* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf(band)) return;
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      const ossim_sint16* s = getSshortBuf(band);  // source
+      double* d = buf;   // destination
+      
+      for(ossim_uint32 index = 0; index < size; index++)
+      {
+         getNormFromPix(*s, *d, band);
+      }
+   }
+}
+
+void ossimS16ImageData::copyNormalizedBufferToTile(double* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimS16ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         ossim_float64* s = buf + (band*size);  // source
+         ossim_sint16*  d = getSshortBuf(band); // destination
+
+         for(ossim_uint32 index = 0; index < size; index++)
+         {
+            ossim_int32 p;
+            getPixFromNorm(p, s[index], band);
+            d[index] = static_cast<ossim_sint16>(p);
+         }
+      }
+   }
+}
+
+void ossimS16ImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                   double* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if((size > 0)&&getBuf(band))
+   {
+      double* s = buf; // source
+      ossim_sint16* d = getSshortBuf(band); // destination
+      
+      for(ossim_uint32 index = 0; index <  size; index++)
+      {
+         ossim_int32 p;
+         getPixFromNorm(p, *s, band);
+         *d = static_cast<ossim_sint16>(p);
+         ++d;
+         ++s;
+      }
+   }
+}
+
+void ossimS16ImageData::copyTileToNormalizedBuffer(float* buf) const
+{
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimS16ImageData::copyTileToNormalizedBuffer ERROR:"
+         << "\nBuffer passed to method is NULL!" << endl;
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         const ossim_sint16* s = getSshortBuf(band);  // source
+         float*    d = buf + (band*size);   // destination
+
+         for(ossim_uint32 index = 0; index < size; index++)
+         {
+            getNormFromPix(s[index], d[index], band);
+         }
+      }
+   }
+}
+
+void ossimS16ImageData::copyTileToNormalizedBuffer(ossim_uint32 band,
+                                                   float* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf(band)) return;
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      const ossim_sint16* s = getSshortBuf(band);  // source
+      float* d = buf;   // destination
+      
+      for(ossim_uint32 index = 0; index < size; index++)
+      {
+         getNormFromPix(*s, *d, band);
+      }
+   }
+}
+
+void ossimS16ImageData::copyNormalizedBufferToTile(float* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimS16ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         float*    s = buf + (band*size);  // source
+         ossim_sint16* d = getSshortBuf(band); // destination
+
+         for(ossim_uint32 index = 0; index < size; index++)
+         {
+            ossim_int32 p;
+            getPixFromNorm(p, s[index], band);
+            d[index] = static_cast<ossim_sint16>(p);
+         }
+      }
+   }
+}
+
+void ossimS16ImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                   float* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if((size > 0)&&getBuf(band))
+   {
+      float* s = buf; // source
+      ossim_sint16* d = getSshortBuf(band); // destination
+      
+      for(ossim_uint32 index = 0; index <  size; index++)
+      {
+         ossim_int32 p;
+         getPixFromNorm(p, *s, band);
+         *d = static_cast<ossim_sint16>(p);
+         ++d;
+         ++s;
+      }
+   }
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimS16ImageData.h b/Utilities/OSSIM/ossim_core/imaging/ossimS16ImageData.h
new file mode 100644
index 0000000000..3dc5b3ad13
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimS16ImageData.h
@@ -0,0 +1,195 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class declaration of ossimS16ImageData.  Specialized image data object for
+// signed short data.
+//
+//*************************************************************************
+// $Id: ossimS16ImageData.h,v 1.15 2004/09/02 13:59:03 dburken Exp $
+
+#ifndef ossimS16ImageData_HEADER
+#define ossimS16ImageData_HEADER
+
+#include "ossimImageData.h"
+
+class OSSIMDLLEXPORT ossimS16ImageData : public ossimImageData
+{
+public:
+   ossimS16ImageData(ossimSource* source,
+                     ossim_uint32 bands = 1);
+
+   ossimS16ImageData(ossimSource* source,
+                    ossim_uint32 bands,
+                    ossim_uint32 width,
+                    ossim_uint32 height);
+
+   ossimS16ImageData(const ossimS16ImageData &rhs);
+   
+   virtual ~ossimS16ImageData();
+
+   /*!
+    * Perform object duplication.
+    */
+   virtual ossimObject* dup()const;
+
+   /*!
+    * will fill the entire band with
+    * the value.
+    */
+   void fill(ossim_uint32 band, double value);
+
+
+   bool isNull(ossim_uint32 offset)const;
+   void setNull(ossim_uint32 offset);
+
+   virtual ossimDataObjectStatus validate() const;
+
+   /*!
+    * will go to the band and offset and compute the
+    * normalized float and return it back to the
+    * caller through the result argument.
+    */
+   virtual void getNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   float& result)const;
+
+   /*!
+    * This will assign to this object a normalized
+    * value by unnormalizing to its native type.
+    */
+   virtual void setNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   float input);
+   
+   /*!
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedFloat(ossimImageData* result)const;
+   
+   /*!
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedDouble(ossimImageData* result)const;
+
+   /*!
+    * Will take the normalized input and convert it
+    * to this tile's data type.  Example:  if this
+    * tile is of type UCHAR and its input is of type
+    * NORALIZED_FLOAT it will unnormalize the data by
+    * doing:
+    *
+    * minPix + normalizedInput*(maxPix-minPix)
+    *
+    * on a per band basis.
+    */
+   virtual void unnormalizeInput(ossimImageData* normalizedInput);
+
+   /*!
+    * This will compute the average value for the band.
+    */
+   virtual double computeAverageBandValue(ossim_uint32 bandNumber = 0);
+
+   /*!
+    * This will call the compute average band value and then
+    * use that in the calculation of:
+    
+    * It will then do a SUM[(Mean - Actual)^2]/width*height.
+    *
+    * This is the average variance from the passed in
+    * mean.  Basically think of the mean as a completely
+    * grey image and we would like to see how this
+    * image varies from the passed in mean.
+    */
+   virtual double computeMeanSquaredError(double meanValue,
+                                          ossim_uint32 bandNumber = 0);
+  
+   virtual void populateHistogram(ossimMultiBandHistogram* histo);
+
+   /*!
+    *  Initializes data to null pixel values.
+    */
+   virtual void makeBlank();
+
+   virtual void setValue(ossim_int32 x, ossim_int32 y, double color);
+
+   virtual void loadBand(const void* src,
+                         const ossimIrect& src_rect,
+                         ossim_uint32 band);
+   
+   virtual void loadTile(void* src,
+                         const ossimIrect& src_rect,
+                         ossimInterleaveType il_type);
+
+   virtual void unloadBand(void* dest,
+                           const ossimIrect& dest_rect,
+                           ossim_uint32 band) const;
+
+   /*!
+    * Copies entire tile to buf passed in.  Data put in buf is normalized.
+    * The "buf" passed to method is assumed to be at least as big as:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyTileToNormalizedBuffer(double* buf) const;
+   
+   /*!
+    * Copies buf passed in to tile.  Data is unnormalized to the tile's
+    * scalar type.
+    * The "buf" passed to method is assumed to be at least as big as the tiles:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyNormalizedBufferToTile(double* buf);
+
+   /*!
+    * Will copy this tiles specified band number to the normalized buffer.
+    * if the band is out of range then nothing is done and returns.
+    */
+   virtual void copyTileToNormalizedBuffer(ossim_uint32 band, double* buf) const;
+   virtual void copyTileToNormalizedBuffer(ossim_uint32 band, float* buf)const;
+   
+   /*!
+    * Copies entire tile to buf passed in.  Data put in buf is normalized.
+    * The "buf" passed to method is assumed to be at least as big as:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyTileToNormalizedBuffer(float* buf) const;
+   
+   /*!
+    * Copies buf passed in to tile.  Data is unnormalized to the tile's
+    * scalar type.
+    * The "buf" passed to method is assumed to be at least as big as the tiles:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyNormalizedBufferToTile(float* buf);
+   
+   /*!
+    * Will copy the normalized buffer to this tiles
+    * specified band.  If band is out of range then nothing
+    * is done and returns.
+    */
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           double* buf);
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           float* buf);
+protected:
+   ossimS16ImageData();
+
+private:
+
+   // Disallow from use...
+   const ossimS16ImageData& operator =(const ossimS16ImageData &rhs)
+                                     {return *this;}
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimTiling.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimTiling.cpp
new file mode 100644
index 0000000000..3303d712cf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimTiling.cpp
@@ -0,0 +1,854 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: implementation for image generator
+//
+//*************************************************************************
+// $Id: ossimTiling.cpp,v 1.10 2005/08/18 19:43:28 gpotts Exp $
+
+#include <sstream>
+#include <iomanip>
+#include <imaging/ossimTiling.h>
+#include <base/misc/lookup_tables/ossimUnitTypeLut.h>
+#include <base/misc/ossimUnitConversionTool.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug("ossimTiling:debug");
+
+RTTI_DEF1(ossimTiling, "ossimTiling", ossimObject);
+
+ossimTiling::ossimTiling()
+      :theTilingDistance(0,0),
+       theTilingDistanceUnitType(OSSIM_UNIT_UNKNOWN),
+       theDelta(0,0),
+       theDeltaType(ossimTilingDeltaType_TOTAL_PIXELS),
+       thePaddingSizeInPixels(0.0, 0.0),
+       theMapProjection(),
+       theImageRect(),
+       theTilingRect(),
+       theTileId(-1),
+       theTotalHorizontalTiles(0),
+       theTotalVerticalTiles(0),
+       theTotalTiles(0),
+       theTileNameMask()
+{
+}
+
+bool ossimTiling::initialize(const ossimMapProjection& proj,
+                             const ossimIrect& boundingRect)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimTiling::initialize DEBUG: Entered..."
+         << "\nBounding rect === " << boundingRect
+         << std::endl;
+   }
+   
+   bool result = true;
+   theMapProjection = (ossimMapProjection*)proj.dup();
+   theImageRect     = boundingRect;
+
+   result = validate();
+
+   ossimDpt convertedTilingDistance = theTilingDistance;
+
+   if(result)
+   {
+      // Let's setup the bounding tile rect.
+      if(theTilingDistanceUnitType != OSSIM_PIXEL)
+      {
+         getConvertedTilingDistance(convertedTilingDistance);
+         
+         if(theMapProjection->isGeographic())
+         {
+            ossimGpt ul;
+            ossimGpt ur;
+            ossimGpt lr;
+            ossimGpt ll;
+
+            theMapProjection->lineSampleToWorld(theImageRect.ul(),
+                                                ul);
+            theMapProjection->lineSampleToWorld(theImageRect.ur(),
+                                                ur);
+            theMapProjection->lineSampleToWorld(theImageRect.lr(),
+                                                lr);
+            theMapProjection->lineSampleToWorld(theImageRect.ll(),
+                                                ll);
+
+            theTilingRect = ossimDrect(ossimDpt(ul),
+                                       ossimDpt(ur),
+                                       ossimDpt(lr),
+                                       ossimDpt(ll),
+                                       OSSIM_RIGHT_HANDED);
+
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "DEBUG: Geographic input bounds =  "
+                  << theTilingRect
+                  << std::endl;
+            }
+            
+            theTilingRect.stretchToTileBoundary(convertedTilingDistance);
+            
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "DEBUG: Geographic input bounds stretched =  "
+                  << theTilingRect << std::endl;
+            }
+            
+            clampGeographic(theTilingRect);
+
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "DEBUG: Geographic input bounds clamped =  "
+                  << theTilingRect << std::endl;
+            }
+
+         }  // End "if(theMapProjection->isGeographic())"
+         
+         else // meters
+         {
+            ossimDpt ul;
+            ossimDpt ur;
+            ossimDpt lr;
+            ossimDpt ll;
+            
+            theMapProjection->lineSampleToEastingNorthing(theImageRect.ul(),
+                                                          ul);
+            theMapProjection->lineSampleToEastingNorthing(theImageRect.ur(),
+                                                          ur);
+            theMapProjection->lineSampleToEastingNorthing(theImageRect.lr(),
+                                                          lr);
+            theMapProjection->lineSampleToEastingNorthing(theImageRect.ll(),
+                                                          ll);
+            theTilingRect = ossimDrect(ul,
+                                       ur,
+                                       lr,
+                                       ll,
+                                       OSSIM_RIGHT_HANDED);
+            
+            theTilingRect.stretchToTileBoundary(convertedTilingDistance);
+         }
+      }
+      else
+      {
+         ossim_int32 remainderX = (ossim_int32)((theImageRect.width()%((ossim_int32)theDelta.x)) != 0);
+         ossim_int32 remainderY = (ossim_int32)((theImageRect.height()%((ossim_int32)theDelta.y)) != 0);
+         
+         ossim_int32 w = (ossim_int32)((theImageRect.width()/(ossim_int32)theDelta.x)*theDelta.x +
+                                       (remainderX*theDelta.x));
+         ossim_int32 h = (ossim_int32)((theImageRect.height()/(ossim_int32)theDelta.y)*theDelta.y +
+                                       (remainderY*theDelta.y));
+         theTilingRect = ossimDrect(theImageRect.ul().x,
+                                    theImageRect.ul().y,
+                                    theImageRect.ul().x + (w-1),
+                                    theImageRect.ul().y + (h-1));
+
+         // since we are pixel space we force delta to be 1 pixel unit
+         //
+         theDelta.x   = 1.0;
+         theDelta.y   = 1.0;
+         theDeltaType = ossimTilingDeltaType_PER_PIXEL;
+      }
+   }
+   
+   theTotalHorizontalTiles = irint(fabs(theTilingRect.ur().x - theTilingRect.ul().x)/convertedTilingDistance.x);
+   theTotalVerticalTiles   = irint(fabs(theTilingRect.ur().y - theTilingRect.lr().y)/convertedTilingDistance.y);
+   theTotalTiles           = theTotalHorizontalTiles*theTotalVerticalTiles;
+
+   // reset the tile id to the beginning
+   //
+   reset();
+   
+   if(traceDebug())
+   {
+      print(ossimNotify(ossimNotifyLevel_DEBUG));
+      
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nossimTiling::initialize DEBUG: Leaving..." << std::endl;
+   }
+   return result;
+}
+
+bool ossimTiling::next(ossimRefPtr<ossimMapProjection>& resultProjection,
+                       ossimIrect& resultingBounds,
+                       ossimString& resultingName)const
+{
+   bool result = true;
+   
+   if(theTileId < theTotalTiles)
+   {
+      ossimDpt origin;
+      ossim_int64 row;
+      ossim_int64 col;
+
+      getRowCol(row, col, theTileId);
+
+      getTileName(resultingName,
+                  row, col, theTileId);
+      
+      getOrigin(origin, row, col);
+
+      if(theTilingDistanceUnitType == OSSIM_PIXEL)
+      {
+         ossimIpt ul = origin;
+
+         resultingBounds =
+            ossimIrect(ul.x - (ossim_int32)thePaddingSizeInPixels.x,
+                       ul.y - (ossim_int32)thePaddingSizeInPixels.y,
+                       ul.x + ((ossim_int32)theTilingDistance.x-1) +
+                       (ossim_int32)thePaddingSizeInPixels.x,
+                       ul.y + ((ossim_int32)theTilingDistance.y-1) +
+                       (ossim_int32)thePaddingSizeInPixels.y);
+      }
+      else
+      {
+         
+         ossimDpt deltaPerPixel = getDeltaPerPixel();
+         ossimIpt pixels;
+
+         if(theDeltaType == ossimTilingDeltaType_TOTAL_PIXELS)
+         {
+            pixels =   theDelta;
+         }
+         else
+         {
+            pixels =   ossimDpt(theTilingDistance.x/theDelta.x,
+                                theTilingDistance.y/theDelta.y);
+         }
+
+         if(theMapProjection->isGeographic())
+         {
+            theMapProjection->setUlGpt(ossimGpt(origin.lat,
+                                                origin.lon,
+                                                0.0,
+                                                theMapProjection->origin().datum()));
+            theMapProjection->setDecimalDegreesPerPixel(deltaPerPixel);
+         }
+         else
+         {
+            theMapProjection->setUlEastingNorthing(ossimDpt(origin.x,
+                                                            origin.y));
+            theMapProjection->setMetersPerPixel(deltaPerPixel);
+         }
+         resultingBounds = ossimIrect(-(ossim_int32)thePaddingSizeInPixels.x,
+                                      -(ossim_int32)thePaddingSizeInPixels.y,
+                                      (pixels.x-1) + (ossim_int32)thePaddingSizeInPixels.x,
+                                      (pixels.y-1) + (ossim_int32)thePaddingSizeInPixels.y);
+      }
+      resultProjection = theMapProjection;
+
+      ++theTileId;
+      if(traceDebug()&&resultProjection.valid())
+      {
+         ossimKeywordlist projKwl;
+         
+         resultProjection->saveState(projKwl);
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimTiling::next DEBUG: rect = " << resultingBounds
+            << "\nproj                          = " << projKwl
+            << "\ntileName                      = " << resultingName
+            << "\norigin                        = " << origin << std::endl;
+      }
+   }
+   else
+   {
+      result = false;
+   }
+
+   
+   return result;
+}
+
+
+void ossimTiling::reset()
+{
+   theTileId = 0;
+}
+
+void ossimTiling::setTilingDistance(const ossimDpt& tilingDistance,
+                                    ossimUnitType unitType)
+{
+   theTilingDistance         = tilingDistance;
+   theTilingDistanceUnitType = unitType;
+}
+
+void ossimTiling::setDelta(const ossimDpt& delta,
+                           ossimTilingDeltaType deltaType)
+{
+   theDelta     = delta;
+   theDeltaType = deltaType;
+}
+
+bool ossimTiling::validate()const
+{
+   bool result = true;
+
+   if(theMapProjection.valid())
+   {
+      if(theMapProjection->isGeographic())
+      {
+         switch(theTilingDistanceUnitType)
+         {
+            case OSSIM_DEGREES:
+            case OSSIM_RADIANS:
+            case OSSIM_SECONDS:
+            case OSSIM_MINUTES:
+            case OSSIM_PIXEL:
+            {
+               break;
+            }
+            default:
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "ossimTiling::validate()\n"
+                  << "Map projeciton requires tiling in angular units but the"
+                  << "\nspacing is in non angular" << std::endl;
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         switch(theTilingDistanceUnitType)
+         {
+            case OSSIM_METERS:
+            case OSSIM_FEET:
+            case OSSIM_US_SURVEY_FEET:
+            case OSSIM_NAUTICAL_MILES:
+            case OSSIM_PIXEL:
+            case OSSIM_MILES:
+            case OSSIM_MILLIMETERS:
+            {
+               break;
+            }
+            default:
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "ossimTiling::validate()"
+                  << "\nMap projeciton requires tiling using linear spacing"
+                  << " but the spacing is in non linear" << std::endl;
+               result = false;
+            }
+         }
+      }
+   }
+   else
+   {
+      result = false;
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimTiling::validate()"
+         << "\nthe image projection is null and so not valid"
+         << std::endl;
+   }
+   if((theDelta.x <= FLT_EPSILON) ||
+      (theDelta.y <= FLT_EPSILON))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimTiling::validate() the delta is too small or is negative"
+         << "value = " << theDelta << std::endl;
+      result = false;
+   }
+   if((theTilingDistance.x <= FLT_EPSILON)||
+      (theTilingDistance.y <= FLT_EPSILON))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimTiling::validate()"
+         << "\nthe tiling distance is too small or is negative"
+         << "Value = " << theTilingDistance << std::endl;
+   }
+   
+   if(theImageRect.hasNans())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimTiling::validate() the image rect has nans"
+         << std::endl;
+      result = false;
+   }
+   
+   return result;
+}
+
+bool ossimTiling::isAngularUnit(ossimUnitType unitType)const
+{
+   bool result = false;
+   
+   switch(unitType)
+   {
+      case OSSIM_DEGREES:
+      case OSSIM_RADIANS:
+      case OSSIM_SECONDS:
+      case OSSIM_MINUTES:
+      {
+         result = true;
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   return result;
+}
+
+bool ossimTiling::isLinearUnit(ossimUnitType unitType)const
+{
+   bool result = false;
+   
+   switch(unitType)
+   {
+      case OSSIM_METERS:
+      case OSSIM_FEET:
+      case OSSIM_US_SURVEY_FEET:
+      case OSSIM_NAUTICAL_MILES:
+      case OSSIM_MILES:
+      case OSSIM_MILLIMETERS:
+      {
+         result = true;
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   return result;
+   
+}
+
+void ossimTiling::setTileNameMask(const ossimString& mask)
+{
+   if(theTileNameMask == "")
+   {
+      theTileNameMask = "tile%i%";
+   }
+   if(mask.contains("%i%")||
+      mask.contains("%oc%")||
+      mask.contains("%or%")||
+      mask.contains("%r%")||
+      mask.contains("%c%")||
+      mask.contains("%SRTM%"))
+   {
+      theTileNameMask = mask;
+   }
+   else
+   {
+      theTileNameMask += "%i%";
+   }
+}
+
+ossimString ossimTiling::getTileNameMask()const
+{
+   return theTileNameMask;
+}
+
+bool ossimTiling::getRowCol(ossim_int64& row,
+                            ossim_int64& col,
+                            ossim_int64 tileId)const
+{
+   bool result = true;
+   
+   if((theTotalHorizontalTiles > 0)&&
+      (tileId < theTotalTiles))
+   {
+      row = tileId/static_cast<ossim_int64>(theTotalHorizontalTiles);
+      col = tileId%static_cast<ossim_int64>(theTotalHorizontalTiles);
+      if((col >= static_cast<ossim_int32>(theTotalHorizontalTiles)) &&
+         (row >= static_cast<ossim_int32>(theTotalVerticalTiles)))
+      {           
+         result = false;
+      }
+   }
+   return result;
+}
+
+bool ossimTiling::getOrigin(ossimDpt& origin,
+                            ossim_int64 tileId)const
+{
+   ossim_int64 row;
+   ossim_int64 col;
+   
+   bool result = getRowCol(row, col, tileId);
+   if(result)
+   {
+      result = getOrigin(origin, row, col);
+   }
+
+   return result;
+}
+
+bool ossimTiling::getOrigin(ossimDpt& origin,
+                            ossim_int64 row,
+                            ossim_int64 col)const
+{
+   bool result = false;
+
+   if((col < static_cast<ossim_int64>(theTotalHorizontalTiles)) &&
+      (row < static_cast<ossim_int64>(theTotalVerticalTiles)))
+   {
+      ossimDpt convertedTilingDistance;
+      getConvertedTilingDistance(convertedTilingDistance);
+
+      result = true;
+      if(theTilingRect.orientMode() == OSSIM_RIGHT_HANDED)
+      {
+         origin.x = theTilingRect.ul().x + col*convertedTilingDistance.x;
+         origin.y = theTilingRect.ul().y - row*convertedTilingDistance.y;
+      }
+      else
+      {
+         origin.x = theTilingRect.ul().x + col*convertedTilingDistance.x;
+         origin.y = theTilingRect.ul().y + row*convertedTilingDistance.y;
+      }
+   }
+
+   return result;
+}
+
+ossimDpt ossimTiling::getDeltaPerPixel()const
+{
+   
+   ossimDpt result = theDelta;
+
+   if (!theMapProjection)
+   {
+      return result;
+   }
+
+   if(theDeltaType == ossimTilingDeltaType_TOTAL_PIXELS)
+   {
+      result = ossimDpt(theTilingDistance.x/theDelta.x,
+                        theTilingDistance.y/theDelta.y);
+   }
+
+   ossimUnitConversionTool unitConverter(theMapProjection->origin(),
+                                         1.0,
+                                         theTilingDistanceUnitType);
+   if(theMapProjection->isGeographic())
+   {
+      unitConverter.setValue(result.x, theTilingDistanceUnitType);
+      result.x = unitConverter.getValue(OSSIM_DEGREES);
+      
+      unitConverter.setValue(result.y,
+                             theTilingDistanceUnitType);
+      result.y = unitConverter.getValue(OSSIM_DEGREES);
+   }
+   else
+   {
+      unitConverter.setValue(result.x,
+                             theTilingDistanceUnitType);
+      result.x = unitConverter.getValue(OSSIM_METERS);
+      
+      unitConverter.setValue(result.y,
+                             theTilingDistanceUnitType);
+      result.y = unitConverter.getValue(OSSIM_METERS);
+   }
+
+   return result;
+}
+
+void ossimTiling::getTileName(ossimString& resultingName,
+                              ossim_int64 row,
+                              ossim_int64 col,
+                              ossim_int64 id)const
+{
+   if(theTileNameMask == "")
+   {
+      ostringstream idString;
+      idString << id;
+      resultingName = ossimString("tile") + idString.str().c_str();
+   }
+   else if(theTileNameMask.contains("%SRTM%"))
+   {
+      // must be a 1x1 degree tiling distance
+      //
+      if((theTilingDistanceUnitType == OSSIM_DEGREES)&&
+         (theTilingDistance.x == 1.0)&&
+         (theTilingDistance.x == 1.0))
+      {
+         ostringstream latString;
+         ostringstream lonString;
+         
+         resultingName = "";
+         ossimDpt origin;
+         getOrigin(origin, row, col);
+         // the name is lower left and not upper left 
+         // subtract one degree
+         //
+         origin.lat -=1;
+         latString << setfill('0') << setw(2) << fabs(origin.lat);
+         lonString << setfill('0') << setw(3) << fabs(origin.lon);
+         
+         if(origin.lat < 0.0)
+         {
+            resultingName += "S";
+         }
+         else 
+         {
+            resultingName += "N";
+         }
+         resultingName += latString.str().c_str();
+         if(origin.lon < 0.0)
+         {
+            resultingName += "W";
+         }
+         else
+         {
+            resultingName += "E";
+         }
+         resultingName += lonString.str().c_str();
+         resultingName += ".hgt";
+      }
+   }
+   else
+   {
+      ostringstream rowString;
+      ostringstream colString;
+      ostringstream idString;
+      ostringstream oRowString;
+      ostringstream oColString;
+      ossimDpt      origin;
+      getOrigin(origin, row, col);
+      
+      rowString << row;
+      colString << col;
+      idString  << id;
+      oRowString << row;
+      oColString << col;
+      
+      resultingName = theTileNameMask;
+      resultingName = resultingName.substitute("%r%",
+                                               rowString.str().c_str());
+      resultingName = resultingName.substitute("%c%",
+                                               colString.str().c_str());
+      resultingName = resultingName.substitute("%i%",
+                                               idString.str().c_str());
+      resultingName = resultingName.substitute("%oc",
+                                               oColString.str().c_str());
+      resultingName = resultingName.substitute("%or",
+                                               oRowString.str().c_str());
+   }
+}
+
+void ossimTiling::clampGeographic(ossimDrect& rect)const
+{
+   ossimDpt ul = rect.ul();
+   ossimDpt lr = rect.lr();
+
+   if(ul.lat > 90) ul.lat = 90.0;
+   if(lr.lat < -90.0) lr.lat = -90.0;
+
+   if(ul.lon < -180) ul.lon = -180;
+   if(lr.lon > 180)  lr.lon = 180;
+
+   rect = ossimDrect(ul, lr, rect.orientMode());
+}
+
+bool ossimTiling::saveState(ossimKeywordlist& kwl,
+                            const char* prefix)const
+{
+   std::stringstream tilingDistance;
+   ossimUnitTypeLut unitLut;
+
+   tilingDistance << theTilingDistance.x << " " << theTilingDistance.y << std::endl;
+   
+   kwl.add(prefix,
+           "tiling_distance",
+           tilingDistance.str().c_str(),
+           true);
+
+   
+   kwl.add(prefix,
+           "tiling_distance_type",
+           unitLut.getTableIndexString(theTilingDistanceUnitType),
+           true);
+   std::ostringstream delta;
+   delta << theDelta.x << " " << theDelta.y;
+   kwl.add(prefix,
+           "delta",
+           delta.str().c_str(),
+           true);
+   
+   if(theDeltaType == ossimTilingDeltaType_TOTAL_PIXELS)
+   {
+      kwl.add(prefix,
+              "delta_type",
+              "total_pixels",
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              "delta_type",
+              "delta_per_pixels",
+              true);
+   }
+   std::ostringstream padding;
+
+   padding << thePaddingSizeInPixels.x << " " << thePaddingSizeInPixels.y;
+   kwl.add(prefix,
+           "padding_size_in_pixels",
+           padding.str().c_str(),
+           true);
+
+   kwl.add(prefix,
+           "tile_name_mask",
+           theTileNameMask.c_str(),
+           true);
+   
+   return true;
+}
+
+bool ossimTiling::loadState(const ossimKeywordlist& kwl,
+                            const char* prefix)
+{
+   ossimUnitTypeLut unitLut;
+   const char* tilingDistance = kwl.find(prefix,
+                                         "tiling_distance");
+   const char* tilingDistanceType = kwl.find(prefix,
+                                             "tiling_distance_type");
+   const char* delta = kwl.find(prefix,
+                                "delta");
+
+   const char* deltaType = kwl.find(prefix,
+                                    "delta_type");
+   const char* paddingSizeInPixels = kwl.find(prefix,
+                                              "padding_size_in_pixels");
+   theTileNameMask = kwl.find(prefix,
+                              "tile_name_mask");
+
+   setTileNameMask(theTileNameMask);
+   
+   bool result = tilingDistance&&tilingDistanceType&&delta&&deltaType&&paddingSizeInPixels;
+
+   std::istringstream distance(ossimString(tilingDistance).c_str());
+   distance >> theTilingDistance.x >> theTilingDistance.y;
+
+   if(theTilingDistance.x <= 0.0)
+   {
+      theTilingDistance.x = 1.0;
+   }
+   if(theTilingDistance.y<=0.0)
+   {
+      theTilingDistance.y = theTilingDistance.x;
+   }
+
+   unitLut.getTableIndexString(theTilingDistanceUnitType),
+   theTilingDistanceUnitType = (ossimUnitType) unitLut.getEntryNumber(ossimString(tilingDistanceType).c_str());
+
+
+   theDelta = ossimDpt(0,0);
+   
+   std::istringstream deltaValues(ossimString(delta).c_str());
+   deltaValues >> theDelta.x >> theDelta.y;
+
+   if(theDelta.x <= 0.0)
+   {
+      theDelta.x = 1.0;
+   }
+
+   if(theDelta.y <= 0.0)
+   {
+      theDelta.y = theDelta.x;
+   }
+
+   if(ossimString(deltaType).downcase().contains("total"))
+   {
+      theDeltaType = ossimTilingDeltaType_TOTAL_PIXELS;
+   }
+   else
+   {
+      theDeltaType = ossimTilingDeltaType_PER_PIXEL;
+   }
+
+   std::istringstream padding(ossimString(paddingSizeInPixels).c_str());
+   padding >> thePaddingSizeInPixels.x >> thePaddingSizeInPixels.y;
+
+   if (traceDebug())
+   {
+      print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+
+   return result;
+}
+
+std::ostream& ossimTiling::print(std::ostream& out) const
+{
+   out << "theTilingDistance:  " << theTilingDistance
+       << "\ntheTilingDistanceUnitType:  " << theTilingDistanceUnitType
+       << "\ntheDelta: " << theDelta
+       << "\ntheDeltaType:  " << theDeltaType
+       << "\nthePaddingSizeInPixels:  " << thePaddingSizeInPixels
+       << "\ntheImageRect:  " << theImageRect
+       << "\ntheTilingRect:  " << theTilingRect
+       << "\ntheTileId:      " << theTileId
+       << "\ntheTotalHorizontalTiles: " << theTotalHorizontalTiles
+       << "\ntheTotalVerticalTiles:  " << theTotalVerticalTiles
+       << "\ntheTotalTiles: " << theTotalTiles
+       << "\ntheTileNameMask:  " << theTileNameMask;
+
+   if (theMapProjection.valid())
+   {
+      out << "\ntheMapProjection:\n" << theMapProjection->print(out);
+   }
+   else
+   {
+      out << "theMapProjection is not set.";
+   }
+   out << endl;
+
+   return out;
+}
+
+void ossimTiling::getConvertedTilingDistance(ossimDpt& pt) const
+{
+   if(theTilingDistanceUnitType == OSSIM_PIXEL)
+   {
+      pt = theTilingDistance;
+      return;
+   }
+   if (!theMapProjection)
+   {
+      // This should not happen...
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimTiling::getConvertedTilingDistance WARNING"
+         << " projection not set!" << endl;
+      pt = theTilingDistance;
+      return;
+   }
+   ossimUnitConversionTool unitConverter(theMapProjection->origin(),
+                                         1.0,
+                                         theTilingDistanceUnitType);
+
+   if(theMapProjection->isGeographic())
+   {
+      unitConverter.setValue(theTilingDistance.x,
+                             theTilingDistanceUnitType);
+      pt.x = unitConverter.getValue(OSSIM_DEGREES);
+      
+      unitConverter.setValue(theTilingDistance.y,
+                             theTilingDistanceUnitType);
+      pt.y = unitConverter.getValue(OSSIM_DEGREES);
+   }
+   else
+   {
+      unitConverter.setValue(theTilingDistance.x,
+                             theTilingDistanceUnitType);
+      pt.x = unitConverter.getValue(OSSIM_METERS);
+      
+      unitConverter.setValue(theTilingDistance.y,
+                             theTilingDistanceUnitType);
+      pt.y = unitConverter.getValue(OSSIM_METERS);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimTiling.h b/Utilities/OSSIM/ossim_core/imaging/ossimTiling.h
new file mode 100644
index 0000000000..d220bff3ff
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimTiling.h
@@ -0,0 +1,161 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: implementation for image generator
+//
+//*************************************************************************
+// $Id: ossimTiling.h,v 1.5 2005/08/02 19:43:27 dburken Exp $
+#ifndef ossimTiling_HEADER
+#define ossimTiling_HEADER
+#include <base/common/ossimObject.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <base/common/ossimRefPtr.h>
+
+class OSSIM_DLL ossimTiling : public ossimObject
+{
+public:
+   typedef enum ossimTilingDeltaType
+      {
+         ossimTilingDeltaType_TOTAL_PIXELS,
+         ossimTilingDeltaType_PER_PIXEL
+      };
+   ossimTiling();
+
+   
+
+   bool initialize(const ossimMapProjection& proj,
+                   const ossimIrect& boundingRect);
+
+   bool next(ossimRefPtr<ossimMapProjection>& resultProjection,
+             ossimIrect& resultingBounds,
+             ossimString& resultingName)const;
+   
+   void reset();
+   
+   /**
+    * 
+    * @param tilingDistance Distance in the specified units.
+    * @param unitType Currently only angular unit degrees,
+    *                 and linear unit meters are supported.
+    *                 If unitType is pixel unit then the
+    *                 delta per unit will be set to 1.
+    *                 
+    */
+   void setTilingDistance(const ossimDpt& tilingDistance,
+                          ossimUnitType unitType);
+
+   /**
+    * This sets the pixel delta.  The delta can either be TOTAL_PIXELS or
+    * UNIT_PER_PIXEL.
+    *
+    * If the delta type is TOTAL_PIXELS then the unit per pixel is calculated
+    * from the theTilingDistance.  This is very useful when wanting to be on
+    * even geographic boundaries and would like to have a fixed width and
+    * height for
+    * the pixels.  Flight simulators use this tiling scheme for power of 2
+    * outputs.
+    *
+    * if the delta type is unit per pixel then the total pixels is computed
+    * form the
+    * theTilingDistance.  This is useful when you might want whole number
+    * GSD's and whole numbered tile boundaries.
+    */
+   void setDelta(const ossimDpt& delta,
+                 ossimTilingDeltaType deltaType);
+
+   /**
+    * This sets the tilename mask.  The key tokens that are supported are.
+    *
+    * %r%         Replaces with the row number of the current tile
+    * %c%         Replaces with the column number of the current tile
+    * %i%         Replaces with the current tile id.
+    * %or%        Replaces with the origin of the row
+    * %oc%        Replaces with the origin of the col
+    * %SRTM%      Replaces all filenames with the SRTM file name convention
+    *
+    * 
+    * Examples:
+    *   tile%r%_%c%  assume r = 0 and c = 100 then
+    *              this is replaced with tile0_100
+    *   
+    */
+   void setTileNameMask(const ossimString& mask);
+   ossimString getTileNameMask()const;
+   
+   bool getRowCol(ossim_int64& row,
+                  ossim_int64& col,
+                  ossim_int64 tileId)const;
+   bool getOrigin(ossimDpt& origin,
+                  ossim_int64 tileId)const;
+   bool getOrigin(ossimDpt& origin,
+                  ossim_int64 row,
+                  ossim_int64 col)const;
+   
+   void setPaddingSizeInPixels(const ossimIpt& pizelOverlap);
+   ossimDpt getDeltaPerPixel()const;
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual std::ostream& print(std::ostream& out) const;
+
+protected:
+
+   /**
+    * @return The tiling distance converted to either degrees or meters.
+    */
+   void getConvertedTilingDistance(ossimDpt& pt) const;
+
+   /** The size of a tile in theTilingDistanceUnitType. */
+   ossimDpt             theTilingDistance;
+
+   /** The unit type for "theDelta", and "theTilingDistance". */
+   ossimUnitType        theTilingDistanceUnitType;
+
+   /**
+    * If (theDeltaType == ossimTilingDeltaType_TOTAL_PIXELS) then
+    * this is the size of the tile in pixels like 1024 x 1024.
+    *
+    * If (theDeltaType == ossimTilingDeltaType_PER_PIXEL) then
+    * this is the size of a single pixel like 1.0 meter.
+    */
+   ossimDpt             theDelta;
+
+   /** @see theDelta */
+   ossimTilingDeltaType theDeltaType;
+   
+   ossimDpt             thePaddingSizeInPixels;
+   mutable ossimRefPtr<ossimMapProjection>  theMapProjection;
+   ossimIrect                       theImageRect;
+   ossimDrect                       theTilingRect;
+   mutable ossim_int64 theTileId;
+   ossim_int64         theTotalHorizontalTiles;
+   ossim_int64         theTotalVerticalTiles;
+   ossim_int64         theTotalTiles;
+   ossimString         theTileNameMask;
+   
+   bool validate()const;
+   bool isAngularUnit(ossimUnitType unitType)const;
+   bool isLinearUnit(ossimUnitType unitType)const;
+   void getTileName(ossimString& resultingName,
+                    ossim_int64 row,
+                    ossim_int64 col,
+                    ossim_int64 id)const;
+   void clampGeographic(ossimDrect& rect)const;
+                    
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimU11ImageData.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimU11ImageData.cpp
new file mode 100644
index 0000000000..ab16abb802
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimU11ImageData.cpp
@@ -0,0 +1,724 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class definition of ossimU11ImageData.  Specialized image data object for
+// unsigned short data with an 11 bit depth.
+//
+// NOTE:  This object is optimized for unsigned short data and assumes the
+//        following:  null pixel value  = 0.0
+//                    min  pixel value  = 1.0
+//                    max  pixel value  = 2047.0  (2^11 - 1)
+//
+//        If you want anything else use the less efficient ossimImageData.
+//
+//*************************************************************************
+// $Id: ossimU11ImageData.cpp,v 1.18 2006/01/10 13:10:29 gpotts Exp $
+
+#include <cstring>  // for memset function
+using namespace std;
+
+#include <imaging/ossimU11ImageData.h>
+#include <base/common/ossimSource.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+
+RTTI_DEF1(ossimU11ImageData, "ossimU11ImageData", ossimImageData)
+
+const ossimNormalizedU11RemapTable ossimU11ImageData::theRemapTable;
+   
+ossimU11ImageData::ossimU11ImageData()
+   :
+      ossimImageData()
+{
+}
+
+ossimU11ImageData::ossimU11ImageData(ossimSource* source,
+                                     ossim_uint32 bands)
+   :
+      ossimImageData(source,
+                     OSSIM_USHORT11,
+                     bands)
+{
+}
+
+ossimU11ImageData::ossimU11ImageData(ossimSource* source,
+                                     ossim_uint32 bands,
+                                     ossim_uint32 width,
+                                     ossim_uint32 height)
+   :
+      ossimImageData(source,
+                     OSSIM_USHORT11,
+                     bands,
+                     width,
+                     height)
+{
+}
+
+ossimU11ImageData::ossimU11ImageData(const ossimU11ImageData &rhs)
+   :
+      ossimImageData(rhs)
+{}
+
+ossimU11ImageData::~ossimU11ImageData()
+{
+}
+
+ossimObject* ossimU11ImageData::dup()const
+{
+   return new ossimU11ImageData(*this);
+}
+
+ossimDataObjectStatus ossimU11ImageData::validate() const
+{
+   if (theDataBuffer == NULL)
+   {
+      setDataObjectStatus(OSSIM_NULL);
+      return OSSIM_NULL;
+   }
+   
+   ossim_uint32 count = 0;
+   const ossim_uint32 SIZE = getSize();
+   const ossim_uint32 BOUNDS = getSizePerBand();
+   const ossim_uint32 NUMBER_OF_BANDS = getNumberOfBands();
+   
+   for(ossim_uint32 band = 0; band < NUMBER_OF_BANDS; ++band)
+   {
+      const ossim_uint16* p  = getUshortBuf(band);
+      for (ossim_uint32 i=0; i<BOUNDS; i++)
+      {
+         // check if the band is null
+         if (p[i] != 0) count++;         
+      }
+   }
+   
+   if (!count)
+      setDataObjectStatus(OSSIM_EMPTY);
+   else if (count == SIZE)
+      setDataObjectStatus(OSSIM_FULL);
+   else
+      setDataObjectStatus(OSSIM_PARTIAL);
+
+   return getDataObjectStatus();
+}
+
+void ossimU11ImageData::getNormalizedFloat(ossim_uint32 offset,
+                                           ossim_uint32 bandNumber,
+                                           float& result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   
+   // make sure that the types and width and height are good.
+   if( (getDataObjectStatus() == OSSIM_NULL) && isValidBand(bandNumber) )
+   {
+      return;
+   }
+   
+   const ossim_uint16* sourceBuf = getUshortBuf(bandNumber);
+   result = static_cast<float>(theRemapTable.normFromPix(sourceBuf[offset]));
+}
+
+void ossimU11ImageData::setNormalizedFloat(ossim_uint32 offset,
+                                           ossim_uint32 bandNumber,
+                                           float inputValue)
+{
+   // make sure that the types and width and height are
+   // good.
+   if((getDataObjectStatus() == OSSIM_NULL)&&
+      (bandNumber < getNumberOfBands()))
+   {
+      return;
+   }
+
+   ossim_uint16* sourceBuf = getUshortBuf(bandNumber);
+   sourceBuf[offset]
+      = static_cast<ossim_uint16>(theRemapTable.pixFromNorm(inputValue));
+}
+
+void
+ossimU11ImageData::convertToNormalizedFloat(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_FLOAT) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+      {
+         const ossim_uint16* sourceBuf = getUshortBuf(bandCount);
+         float* resultBuf = static_cast<float*>(result->getBuf(bandCount));
+         for(ossim_uint32 counter = 0; counter <  size; ++counter)
+         {
+            resultBuf[counter]
+               = static_cast<float>(theRemapTable.
+                                    normFromPix(sourceBuf[counter]));
+         }
+      }
+   }
+}
+
+void ossimU11ImageData::convertToNormalizedDouble(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_FLOAT) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+      {
+         const ossim_uint16* sourceBuf = getUshortBuf(bandCount);
+         double* resultBuf = static_cast<double*>(result->getBuf(bandCount));
+         for(ossim_uint32 counter = 0; counter <  size; ++counter)
+         {
+            resultBuf[counter] = theRemapTable.normFromPix(sourceBuf[counter]);
+         }
+      }
+   }
+
+}
+
+void ossimU11ImageData::unnormalizeInput(ossimImageData* normalizedInput)
+{
+   if((normalizedInput->getScalarType() != OSSIM_NORMALIZED_FLOAT) &&
+      (normalizedInput->getScalarType() != OSSIM_NORMALIZED_DOUBLE) )
+   {
+      //ERROR
+      return;
+   }
+   
+   ossim_uint32 counter = 0;
+   ossim_uint32 bandCount = 0;
+   ossim_uint32 size = getSizePerBand();
+   ossimScalarType scalarType = normalizedInput->getScalarType();
+
+   if(size > 0)
+   {
+      if(scalarType == OSSIM_NORMALIZED_FLOAT)
+      {
+         for(bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+         {
+            float* sourceBuf =
+               static_cast<float*>(normalizedInput->getBuf(bandCount));
+            ossim_uint16* resultBuf = getUshortBuf(bandCount);
+            for(counter = 0; counter <  size; ++counter)
+            {
+               resultBuf[counter]
+                  = static_cast<ossim_uint16>(theRemapTable.
+                                              pixFromNorm(sourceBuf[counter]));
+            }
+         }
+      }
+      else // Double
+      {
+         for(bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+         {
+            double* sourceBuf =
+               static_cast<double*>(normalizedInput->getBuf(bandCount));
+            ossim_uint16* resultBuf = getUshortBuf(bandCount);
+            for(counter = 0; counter <  size; ++counter)
+            {
+               resultBuf[counter]
+                  = static_cast<ossim_uint16>(theRemapTable.
+                                              pixFromNorm(sourceBuf[counter]));
+            }
+         }
+      }
+   }   
+}
+
+double ossimU11ImageData::computeMeanSquaredError(double meanValue,
+                                                  ossim_uint32 bandNumber)
+{
+   double result = -1; // invalid MSE
+   ossim_uint32 index = 0;
+   double delta = 0;
+   ossim_uint32 validPixelCount=0;
+   
+   ossim_uint16* buffer = getUshortBuf(bandNumber);
+   if(buffer)
+   {
+      ossim_uint32 bounds = getWidth()*getHeight();
+      for(index = 0; index < bounds; ++index)
+      {
+         if(!isNull(index))
+         {
+            delta = *buffer - meanValue;
+            result += (delta*delta);
+            ++validPixelCount;
+         }
+         ++buffer;
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+//******************************************************************
+//
+// NOTE: I was checking for null and not adding it to the histogram.
+//       this was messing up the equalization algorithms since the
+//       accumulation histogram did not represent the area of the
+//       image.  For now I will leave out the check for "is null" and
+//       add this to the count so that the total accumulation is the
+//       area of the image.
+//
+//******************************************************************
+void ossimU11ImageData::populateHistogram(ossimMultiBandHistogram* histo)
+{
+   ossim_uint32 numberOfBands = getNumberOfBands();
+
+   if( (getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return;
+   }
+
+   for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+   {
+      ossimHistogram* currentHisto = histo->getHistogram(band);
+      ossim_uint16* buffer = getUshortBuf(band);
+      
+      if(currentHisto)
+      {
+	//float *counts = currentHisto->GetCounts();
+         ossim_uint32 upperBound = getWidth()*getHeight();
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+	   currentHisto->UpCount((float)buffer[offset]);
+         }
+      }
+   }
+}
+
+double ossimU11ImageData::computeAverageBandValue(ossim_uint32 bandNumber)
+{
+   double result = 0.0;
+   ossim_uint32 index = 0;
+   ossim_uint32 validPixelCount=0;
+   
+   ossim_uint16* buffer = getUshortBuf(bandNumber);
+   if(buffer)
+   {
+      ossim_uint32 bounds = getSizePerBand();
+      for(index = 0; index < bounds; ++index)
+      {
+         if(!isNull(index))
+         {
+            result += *buffer;
+            ++validPixelCount;
+         }
+         ++buffer;
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+void ossimU11ImageData::makeBlank()
+{
+   void* s = getBuf();
+
+   if (s == NULL) return; // nothing to do...
+   
+   ossim_uint32 size_in_pixels = getSizePerBand();
+   
+   for(ossim_uint32 band =0; band < getNumberOfBands(); ++band)
+   {
+      ossim_uint16* p = getUshortBuf(band);
+      for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = 0;
+   }
+
+   setDataObjectStatus(OSSIM_EMPTY);
+}
+
+void ossimU11ImageData::setValue(long x, long y, double color)
+{
+   if(theDataBuffer&&isWithin(x, y))
+   {
+      //***
+      // Compute the offset into the buffer for (x,y).  This should always
+      // come out positive.
+      //***
+      ossim_uint32 ux = static_cast<ossim_uint32>(x - theOrigin.x);
+      ossim_uint32 uy = static_cast<ossim_uint32>(y - theOrigin.y);
+      
+      ossim_uint32 offset = uy * theSpatialExtents[0] + ux;
+      
+      for(ossim_uint32 band = 0; band < theNumberOfDataComponents; band++)
+      {
+         ossim_uint16* buf = getUshortBuf(band)+offset;
+         *buf = (ossim_uint16)color;
+      }
+   }
+}
+
+void ossimU11ImageData::fill(ossim_uint32 band, double value)
+{
+   void* s         = getBuf(band);
+
+   if (s == NULL) return; // nothing to do...
+
+   ossim_uint32 size_in_pixels = getSizePerBand();
+   ossim_uint16* p = getUshortBuf(band);
+   ossim_uint16 np = static_cast<ossim_uint16>(value);
+
+   for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+
+   // Set the status to unknown since we don't know about the other bands.
+   setDataObjectStatus(OSSIM_STATUS_UNKNOWN);
+}
+
+
+bool ossimU11ImageData::isNull(ossim_uint32 offset)const
+{
+   for(ossim_uint32 band = 0; band < getNumberOfBands(); ++band)  
+   {
+      const ossim_uint16* buf = getUshortBuf(band)+offset;
+      
+      if((*buf) != theNullPixelValue[band])
+      {
+         return false;
+      }
+   }
+
+   return true;
+}
+
+void ossimU11ImageData::setNull(ossim_uint32 offset)
+{
+   ossim_uint32 bands = getNumberOfBands();
+   for(ossim_uint32 band = 0; band < bands; ++band)  
+   {
+      ossim_uint16* buf = getUshortBuf(band)+offset;
+      *buf          = (ossim_uint16)theNullPixelValue[band];
+   }
+}
+
+void ossimU11ImageData::loadBand(const void* src,
+                                 const ossimIrect& src_rect,
+                                 ossim_uint32 band)
+{
+   ossimImageData::loadBand(ossim_uint16(0), src, src_rect, band);
+}
+
+void ossimU11ImageData::loadTile(void* src,
+                                const ossimIrect& src_rect,
+                                ossimInterleaveType il_type)
+{
+   // Load the tile from the buffer.
+   switch (il_type)
+   {
+   case OSSIM_BIP:
+      ossimImageData::loadTileFromBip(ossim_uint16(0), src, src_rect);
+      break;
+   case OSSIM_BIL:
+      ossimImageData::loadTileFromBil(ossim_uint16(0), src, src_rect);
+      break;
+   case OSSIM_BSQ:
+      ossimImageData::loadTileFromBsq(ossim_uint16(0), src, src_rect);
+      break;
+   default:
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimU11ImageData::loadTile"
+         << "\nUnknown interleave type passed to method.  Returning..."
+         << endl;
+      break;
+   } 
+}
+
+void ossimU11ImageData::unloadBand(void* dest,
+                                   const ossimIrect& dest_rect,
+                                   ossim_uint32 band) const
+{
+   ossimImageData::unloadBand(ossim_uint16(0), dest, dest_rect,
+                              getImageRectangle(), band);
+}
+
+void ossimU11ImageData::copyTileToNormalizedBuffer(double* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         const ossim_uint16* s = getUshortBuf(band);  // source
+         double* d = buf + (band*size);   // destination
+
+         for(ossim_uint32 index = 0; index < size; index++)
+         {
+            d[index] = theRemapTable.
+                       normFromPix(static_cast<ossim_int32>(s[index]));
+         }
+      }
+   }
+}
+
+void ossimU11ImageData::copyTileToNormalizedBuffer(ossim_uint32 band,
+                                                   double* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf(band)) return;
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      const ossim_uint16* s = getUshortBuf(band);  // source
+      double* d = buf;   // destination
+      
+      for(ossim_uint32 index = 0; index < size; index++)
+      {
+         *d = theRemapTable.
+              normFromPix(static_cast<ossim_int32>(*s));
+      }
+   }
+}
+
+
+void ossimU11ImageData::copyNormalizedBufferToTile(double* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         double* s = buf + (band*size); // source
+         ossim_uint16* d = getUshortBuf(band); // destination
+
+         for(ossim_uint32 index = 0; index <  size; index++)
+         {
+            d[index] = theRemapTable.pixFromNorm(s[index]);
+         }
+      }
+   }
+}
+
+void ossimU11ImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                   double* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if((size > 0)&&getBuf(band))
+   {
+      double* s = buf; // source
+      ossim_uint16* d = getUshortBuf(band); // destination
+      
+      for(ossim_uint32 index = 0; index <  size; ++index)
+      {
+         *d = theRemapTable.pixFromNorm(*s);
+         ++d;
+         ++s;
+      }
+   }
+}
+
+
+void ossimU11ImageData::copyTileToNormalizedBuffer(float* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         const ossim_uint16* s = getUshortBuf(band);  // source
+         float* d = buf + (band*size);   // destination
+
+         for(ossim_uint32 index = 0; index < size; index++)
+         {
+            d[index] = theRemapTable.
+                       normFromPix(static_cast<ossim_int32>(s[index]));
+         }
+      }
+   }
+}
+
+void ossimU11ImageData::copyTileToNormalizedBuffer(ossim_uint32 band,
+                                                   float* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf(band)) return;
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      const ossim_uint16* s = getUshortBuf(band);  // source
+      float* d = buf;   // destination
+      
+      for(ossim_uint32 index = 0; index < size; index++)
+      {
+         *d = theRemapTable.
+              normFromPix(static_cast<ossim_int32>(*s));
+      }
+   }
+}
+
+void ossimU11ImageData::copyNormalizedBufferToTile(float* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         float* s = buf + (band*size); // source
+         ossim_uint16* d = getUshortBuf(band); // destination
+
+         for(ossim_uint32 index = 0; index <  size; index++)
+         {
+            d[index] = theRemapTable.pixFromNorm(s[index]);
+         }
+      }
+   }
+}
+
+
+void ossimU11ImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                   float* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if((size > 0)&&getBuf(band))
+   {
+      float* s = buf; // source
+      ossim_uint16* d = getUshortBuf(band); // destination
+      
+      for(ossim_uint32 index = 0; index <  size; ++index)
+      {
+         *d = theRemapTable.pixFromNorm(*s);
+         ++d;
+         ++s;
+      }
+   }
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimU11ImageData.h b/Utilities/OSSIM/ossim_core/imaging/ossimU11ImageData.h
new file mode 100644
index 0000000000..f6cd7943b0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimU11ImageData.h
@@ -0,0 +1,204 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class declaration of ossimU16ImageData.  Specialized image data object for
+// unsigned short data with an 11 bit depth.
+//
+// NOTE:  This object is optimized for unsigned short data and assumes the
+//        following:  null pixel value  = 0.0
+//                    min  pixel value  = 1.0
+//                    max  pixel value  = 2047.0  (2^11 - 1)
+//
+//        If you want anything else use the less efficient ossimImageData.
+//
+//*************************************************************************
+// $Id: ossimU11ImageData.h,v 1.16 2004/09/02 13:59:03 dburken Exp $
+
+#ifndef ossimU11ImageData_HEADER
+#define ossimU11ImageData_HEADER
+
+#include "ossimImageData.h"
+#include "imaging/remap_tables/ossimNormalizedU11RemapTable.h"
+
+class OSSIMDLLEXPORT ossimU11ImageData : public ossimImageData
+{
+public:
+   ossimU11ImageData(ossimSource* source,
+                     ossim_uint32 bands = 1);
+
+   ossimU11ImageData(ossimSource* source,
+                     ossim_uint32 bands,
+                     ossim_uint32 width,
+                     ossim_uint32 height);
+
+   ossimU11ImageData(const ossimU11ImageData &rhs);
+   
+   virtual ~ossimU11ImageData();
+
+   virtual ossimObject* dup()const;
+
+   /*!
+    * will fill the entire band with
+    * the value.
+    */
+   void fill(ossim_uint32 band, double value);
+
+   bool isNull(ossim_uint32 offset)const;
+   void setNull(ossim_uint32 offset);
+
+   virtual ossimDataObjectStatus validate() const;
+
+   /*!
+    * will go to the band and offset and compute the
+    * normalized float and return it back to the
+    * caller through the result argument.
+    */
+   virtual void getNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   float& result)const;
+
+   /*!
+    * This will assign to this object a normalized
+    * value by unnormalizing to its native type.
+    */
+   virtual void setNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   float input);
+   
+   /*!
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedFloat(ossimImageData* result)const;
+   
+   /*!
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedDouble(ossimImageData* result)const;
+
+   /*!
+    * Will take the normalized input and convert it
+    * to this tile's data type.  Example:  if this
+    * tile is of type UCHAR and its input is of type
+    * NORALIZED_FLOAT it will unnormalize the data by
+    * doing:
+    *
+    * minPix + normalizedInput*(maxPix-minPix)
+    *
+    * on a per band basis.
+    */
+   virtual void unnormalizeInput(ossimImageData* normalizedInput);
+
+   /*!
+    * This will compute the average value for the band.
+    */
+   virtual double computeAverageBandValue(ossim_uint32 bandNumber = 0);
+
+   /*!
+    * This will call the compute average band value and then
+    * use that in the calculation of:
+    
+    * It will then do a SUM[(Mean - Actual)^2]/width*height.
+    *
+    * This is the average variance from the passed in
+    * mean.  Basically think of the mean as a completely
+    * grey image and we would like to see how this
+    * image varies from the passed in mean.
+    */
+   virtual double computeMeanSquaredError(double meanValue,
+                                          ossim_uint32 bandNumber = 0);
+  
+   virtual void populateHistogram(ossimMultiBandHistogram* histo);
+
+   /*!
+    *  Initializes data to null pixel values.
+    */
+   virtual void makeBlank();
+
+   virtual void setValue(long x, long y, double color);
+
+   virtual void loadBand(const void* src,
+                         const ossimIrect& src_rect,
+                         ossim_uint32 band);
+   
+   virtual void loadTile(void* src,
+                         const ossimIrect& src_rect,
+                         ossimInterleaveType il_type);
+
+   virtual void unloadBand(void* dest,
+                           const ossimIrect& dest_rect,
+                           ossim_uint32 band) const;
+
+   /*!
+    * Copies entire tile to buf passed in.  Data put in buf is normalized.
+    * The "buf" passed to method is assumed to be at least as big as:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyTileToNormalizedBuffer(double* buf) const;
+   
+   /*!
+    * Copies buf passed in to tile.  Data is unnormalized to the tile's
+    * scalar type.
+    * The "buf" passed to method is assumed to be at least as big as the tiles:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyNormalizedBufferToTile(double* buf);
+
+   /*!
+    * Will copy this tiles specified band number to the normalized buffer.
+    * if the band is out of range then nothing is done and returns.
+    */
+   virtual void copyTileToNormalizedBuffer(ossim_uint32 band,
+                                           double* buf) const;
+   virtual void copyTileToNormalizedBuffer(ossim_uint32 band,
+                                           float* buf)const;
+
+      /*!
+    * Copies entire tile to buf passed in.  Data put in buf is normalized.
+    * The "buf" passed to method is assumed to be at least as big as:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyTileToNormalizedBuffer(float* buf) const;
+   
+   /*!
+    * Copies buf passed in to tile.  Data is unnormalized to the tile's
+    * scalar type.
+    * The "buf" passed to method is assumed to be at least as big as the tiles:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyNormalizedBufferToTile(float* buf);
+
+   /*!
+    * Will copy the normalized buffer to this tiles
+    * specified band.  If band is out of range then nothing
+    * is done and returns.
+    */
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           double* buf);
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           float* buf);
+
+protected:
+   ossimU11ImageData();
+
+private:
+
+   // Disallow from use...
+   const ossimU11ImageData& operator =(const ossimU11ImageData &rhs)
+                                     {return *this;}
+
+   static const ossimNormalizedU11RemapTable theRemapTable;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimU16ImageData.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimU16ImageData.cpp
new file mode 100644
index 0000000000..1d5943479b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimU16ImageData.cpp
@@ -0,0 +1,695 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class definition of ossimU16ImageData.  Specialized image data object for
+// unsigned short data.
+//
+// NOTE:  This object is optimized for unsigned short data and assumes the
+//        following:  null pixel value  = 0.0
+//                    min  pixel value  = 1.0
+//                    max  pixel value  = 65535.0  (2^16 - 1)
+//
+//        If you want anything else use the less efficient ossimImageData.
+//
+//*************************************************************************
+// $Id: ossimU16ImageData.cpp,v 1.17 2004/09/02 13:59:03 dburken Exp $
+
+#include <string.h>  // for memset function
+
+#include "ossimU16ImageData.h"
+#include "base/common/ossimSource.h"
+#include "base/context/ossimErrorContext.h"
+#include "base/data_types/ossimIrect.h"
+#include "base/data_types/ossimMultiBandHistogram.h"
+#include "base/data_types/ossimHistogram.h"
+
+RTTI_DEF1(ossimU16ImageData, "ossimU16ImageData", ossimImageData)
+
+const ossimNormalizedU16RemapTable ossimU16ImageData::theRemapTable;
+   
+ossimU16ImageData::ossimU16ImageData()
+   :
+      ossimImageData()
+{
+}
+
+ossimU16ImageData::ossimU16ImageData(ossimSource* source,
+                                     ossim_uint32 bands)
+   :
+      ossimImageData(source,
+                     OSSIM_USHORT16,
+                     bands)
+{
+}
+
+ossimU16ImageData::ossimU16ImageData(ossimSource* source,
+                                     ossim_uint32 bands,
+                                     ossim_uint32 width,
+                                     ossim_uint32 height)
+   :
+      ossimImageData(source,
+                     OSSIM_USHORT16,
+                     bands,
+                     width,
+                     height)
+{
+}
+
+ossimU16ImageData::ossimU16ImageData(const ossimU16ImageData &rhs)
+   :
+      ossimImageData(rhs)
+{
+}
+
+ossimU16ImageData::~ossimU16ImageData()
+{
+}
+
+ossimObject* ossimU16ImageData::dup()const
+{
+   return new ossimU16ImageData(*this);
+}
+
+ossimDataObjectStatus ossimU16ImageData::validate() const
+{
+   if (theDataBuffer == NULL)
+   {
+      setDataObjectStatus(OSSIM_NULL);
+      return OSSIM_NULL;
+   }
+   
+   ossim_uint32 count = 0;
+   const ossim_uint32 SIZE = getSize();
+   const ossim_uint32 BOUNDS = getSizePerBand();
+   const ossim_uint32 NUMBER_OF_BANDS = getNumberOfBands();
+   
+   for(ossim_uint32 band = 0; band < NUMBER_OF_BANDS; ++band)
+   {
+      const ossim_uint16* p  = getUshortBuf(band);
+      for (ossim_uint32 i=0; i<BOUNDS; i++)
+      {
+         // check if the band is null
+         if (p[i] != 0) count++;         
+      }
+   }
+   
+   if (!count)
+      setDataObjectStatus(OSSIM_EMPTY);
+   else if (count == SIZE)
+      setDataObjectStatus(OSSIM_FULL);
+   else
+      setDataObjectStatus(OSSIM_PARTIAL);
+
+   return getDataObjectStatus();
+}
+
+void ossimU16ImageData::getNormalizedFloat(ossim_uint32 offset,
+                                           ossim_uint32 bandNumber,
+                                           float& result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   
+   // make sure that the types and width and height are good.
+   if( (getDataObjectStatus() == OSSIM_NULL) && isValidBand(bandNumber) )
+   {
+      return;
+   }
+   
+   const ossim_uint16* sourceBuf = getUshortBuf(bandNumber);
+   result = static_cast<float>(theRemapTable.normFromPix(sourceBuf[offset]));
+}
+
+void ossimU16ImageData::setNormalizedFloat(ossim_uint32 offset,
+                                           ossim_uint32 bandNumber,
+                                           float inputValue)
+{
+   // make sure that the types and width and height are
+   // good.
+   if((getDataObjectStatus() == OSSIM_NULL)&&
+      (bandNumber < getNumberOfBands()))
+   {
+      return;
+   }
+
+   ossim_uint16* sourceBuf = getUshortBuf(bandNumber);
+   sourceBuf[offset]
+      = static_cast<ossim_uint16>(theRemapTable.pixFromNorm(inputValue));
+}
+
+void
+ossimU16ImageData::convertToNormalizedFloat(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_FLOAT) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+      {
+         const ossim_uint16* sourceBuf = getUshortBuf(bandCount);
+         float* resultBuf = static_cast<float*>(result->getBuf(bandCount));
+         for(ossim_uint32 counter = 0; counter <  size; ++counter)
+         {
+            resultBuf[counter]
+               = static_cast<float>(theRemapTable.
+                                    normFromPix(sourceBuf[counter]));
+         }
+      }
+   }
+}
+
+void ossimU16ImageData::convertToNormalizedDouble(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_FLOAT) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+      {
+         const ossim_uint16* sourceBuf = getUshortBuf(bandCount);
+         double* resultBuf = static_cast<double*>(result->getBuf(bandCount));
+         for(ossim_uint32 counter = 0; counter <  size; ++counter)
+         {
+            resultBuf[counter] = theRemapTable.normFromPix(sourceBuf[counter]);
+         }
+      }
+   }
+
+}
+
+void ossimU16ImageData::unnormalizeInput(ossimImageData* normalizedInput)
+{
+   if((normalizedInput->getScalarType() != OSSIM_NORMALIZED_FLOAT) &&
+      (normalizedInput->getScalarType() != OSSIM_NORMALIZED_DOUBLE) )
+   {
+      //ERROR
+      return;
+   }
+   
+   ossim_uint32 counter = 0;
+   ossim_uint32 bandCount = 0;
+   ossim_uint32 size = getSizePerBand();
+   ossimScalarType scalarType = normalizedInput->getScalarType();
+
+   if(size > 0)
+   {
+      if(scalarType == OSSIM_NORMALIZED_FLOAT)
+      {
+         for(bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+         {
+            float* sourceBuf =
+               static_cast<float*>(normalizedInput->getBuf(bandCount));
+            ossim_uint16* resultBuf = getUshortBuf(bandCount);
+            for(counter = 0; counter <  size; ++counter)
+            {
+               resultBuf[counter]
+                  = static_cast<ossim_uint16>(theRemapTable.
+                                          pixFromNorm(sourceBuf[counter]));
+            }
+         }
+      }
+      else // Double
+      {
+         for(bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+         {
+            double* sourceBuf =
+               static_cast<double*>(normalizedInput->getBuf(bandCount));
+            ossim_uint16* resultBuf = getUshortBuf(bandCount);
+            for(counter = 0; counter <  size; ++counter)
+            {
+               resultBuf[counter]
+                  = static_cast<ossim_uint16>(theRemapTable.
+                                          pixFromNorm(sourceBuf[counter]));
+            }
+         }
+      }
+   }   
+}
+
+double ossimU16ImageData::computeMeanSquaredError(double meanValue,
+                                                  ossim_uint32 bandNumber)
+{
+   double result = -1; // invalid MSE
+   ossim_uint32 index = 0;
+   double delta = 0;
+   ossim_uint32 validPixelCount=0;
+   
+   ossim_uint16* buffer = getUshortBuf(bandNumber);
+   if(buffer)
+   {
+      ossim_uint32 bounds = getWidth()*getHeight();
+      for(index = 0; index < bounds; ++index)
+      {
+         if(!isNull(index))
+         {
+            delta = *buffer - meanValue;
+            result += (delta*delta);
+            ++validPixelCount;
+         }
+         ++buffer;
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+//******************************************************************
+//
+// NOTE: I was checking for null and not adding it to the histogram.
+//       this was messing up the equalization algorithms since the
+//       accumulation histogram did not represent the area of the
+//       image.  For now I will leave out the check for "is null" and
+//       add this to the count so that the total accumulation is the
+//       area of the image.
+//
+//******************************************************************
+void ossimU16ImageData::populateHistogram(ossimMultiBandHistogram* histo)
+{
+   ossim_uint32 numberOfBands = getNumberOfBands();
+
+   if( (getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return;
+   }
+
+   for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+   {
+      ossimHistogram* currentHisto = histo->getHistogram(band);
+      ossim_uint16* buffer = getUshortBuf(band);
+      
+      if(currentHisto)
+      {
+         float *counts = currentHisto->GetCounts();
+         ossim_uint32 upperBound = getWidth()*getHeight();
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            counts[buffer[offset]]++;
+         }
+      }
+   }
+}
+
+double ossimU16ImageData::computeAverageBandValue(ossim_uint32 bandNumber)
+{
+   double result = 0.0;
+   ossim_uint32 index = 0;
+   ossim_uint32 validPixelCount=0;
+   
+   ossim_uint16* buffer = getUshortBuf(bandNumber);
+   if(buffer)
+   {
+      ossim_uint32 bounds = getSizePerBand();
+      for(index = 0; index < bounds; ++index)
+      {
+         if(!isNull(index))
+         {
+            result += *buffer;
+            ++validPixelCount;
+         }
+         ++buffer;
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+void ossimU16ImageData::makeBlank()
+{
+   void* s = getBuf();
+
+   if (s == NULL) return; // nothing to do...
+   
+   ossim_uint32 size_in_pixels = getSizePerBand();
+   
+   for(ossim_uint32 band =0; band < getNumberOfBands(); ++band)
+   {
+      ossim_uint16* p = getUshortBuf(band);
+      for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = 0;
+   }
+
+   setDataObjectStatus(OSSIM_EMPTY);
+}
+
+void ossimU16ImageData::setValue(long x, long y, double color)
+{
+   if(theDataBuffer&&isWithin(x, y))
+   {
+      //***
+      // Compute the offset into the buffer for (x,y).  This should always
+      // come out positive.
+      //***
+      ossim_uint32 ux = static_cast<ossim_uint32>(x - theOrigin.x);
+      ossim_uint32 uy = static_cast<ossim_uint32>(y - theOrigin.y);
+
+      ossim_uint32 offset = uy * theSpatialExtents[0] + ux;
+      
+      for(ossim_uint32 band = 0; band < theNumberOfDataComponents; band++)
+      {
+         ossim_uint16* buf = getUshortBuf(band)+offset;
+         *buf = (ossim_uint16)color;
+      }
+   }
+}
+
+void ossimU16ImageData::fill(ossim_uint32 band, double value)
+{
+   void* s         = getBuf(band);
+
+   if (s == NULL) return; // nothing to do...
+
+   ossim_uint32 size_in_pixels = getSizePerBand();
+   ossim_uint16* p = getUshortBuf(band);
+   ossim_uint16 np = static_cast<ossim_uint16>(value);
+
+   for (ossim_uint32 i=0; i<size_in_pixels; i++) p[i] = np;
+
+   // Set the status to unknown since we don't know about the other bands.
+   setDataObjectStatus(OSSIM_STATUS_UNKNOWN);
+}
+
+
+void ossimU16ImageData::loadBand(const void* src,
+                                 const ossimIrect& src_rect,
+                                 ossim_uint32 band)
+{
+   ossimImageData::loadBand(ossim_uint16(0), src, src_rect, band);
+}
+
+void ossimU16ImageData::loadTile(void* src,
+                                const ossimIrect& src_rect,
+                                ossimInterleaveType il_type)
+{
+   // Load the tile from the buffer.
+   switch (il_type)
+   {
+   case OSSIM_BIP:
+      ossimImageData::loadTileFromBip(ossim_uint16(0), src, src_rect);
+      break;
+   case OSSIM_BIL:
+      ossimImageData::loadTileFromBil(ossim_uint16(0), src, src_rect);
+      break;
+   case OSSIM_BSQ:
+      ossimImageData::loadTileFromBsq(ossim_uint16(0), src, src_rect);
+      break;
+   default:
+      cout << " NOTICE:"
+           << "\nUnknown interleave type passed to method.  Returning..."
+           << endl;
+      break;
+   } 
+}
+
+void ossimU16ImageData::unloadBand(void* dest,
+                                   const ossimIrect& dest_rect,
+                                   ossim_uint32 band) const
+{
+   ossimImageData::unloadBand(ossim_uint16(0), dest, dest_rect,
+                              getImageRectangle(), band);
+}
+
+void ossimU16ImageData::copyTileToNormalizedBuffer(double* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU16ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         const ossim_uint16* s = getUshortBuf(band);  // source
+         double* d = buf + (band*size);   // destination
+
+         for(ossim_uint32 index = 0; index < size; index++)
+         {
+            d[index] = theRemapTable.
+                       normFromPix(static_cast<ossim_int32>(s[index]));
+         }
+      }
+   }
+}
+
+void ossimU16ImageData::copyTileToNormalizedBuffer(ossim_uint32 band,
+                                                   double* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf(band)) return;
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      const ossim_uint16* s = getUshortBuf(band);  // source
+      double* d = buf;   // destination
+      
+      for(ossim_uint32 index = 0; index < size; index++)
+      {
+         *d = theRemapTable.
+              normFromPix(static_cast<ossim_int32>(*s));
+      }
+   }
+}
+
+void ossimU16ImageData::copyNormalizedBufferToTile(double* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU16ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         double* s = buf + (band*size); // source
+         ossim_uint16* d = getUshortBuf(band); // destination
+
+         for(ossim_uint32 index = 0; index <  size; index++)
+         {
+            d[index] = theRemapTable.pixFromNorm(s[index]);
+         }
+      }
+   }
+}
+
+void ossimU16ImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                   double* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if((size > 0)&&getBuf(band))
+   {
+      double* s = buf; // source
+      ossim_uint16* d = getUshortBuf(band); // destination
+      
+      for(ossim_uint32 index = 0; index <  size; index++)
+      {
+         *d = theRemapTable.pixFromNorm(*s);
+         ++d;
+         ++s;
+      }
+   }
+}
+
+void ossimU16ImageData::copyTileToNormalizedBuffer(float* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU16ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         const ossim_uint16* s = getUshortBuf(band);  // source
+         float* d = buf + (band*size);   // destination
+
+         for(ossim_uint32 index = 0; index < size; index++)
+         {
+            d[index] = theRemapTable.
+                       normFromPix(static_cast<ossim_int32>(s[index]));
+         }
+      }
+   }
+}
+
+void ossimU16ImageData::copyTileToNormalizedBuffer(ossim_uint32 band,
+                                                   float* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf(band)) return;
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      const ossim_uint16* s = getUshortBuf(band);  // source
+      float* d = buf;   // destination
+      
+      for(ossim_uint32 index = 0; index < size; index++)
+      {
+         *d = theRemapTable.
+              normFromPix(static_cast<ossim_int32>(*s));
+      }
+   }
+}
+
+void ossimU16ImageData::copyNormalizedBufferToTile(float* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU16ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); band++)
+      {
+         float* s = buf + (band*size); // source
+         ossim_uint16* d = getUshortBuf(band); // destination
+
+         for(ossim_uint32 index = 0; index <  size; index++)
+         {
+            d[index] = theRemapTable.pixFromNorm(s[index]);
+         }
+      }
+   }
+}
+
+void ossimU16ImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                   float* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU11ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   
+   ossim_uint32 size = getSizePerBand();
+   
+   if((size > 0)&&getBuf(band))
+   {
+      float* s = buf; // source
+      ossim_uint16* d = getUshortBuf(band); // destination
+      
+      for(ossim_uint32 index = 0; index <  size; index++)
+      {
+         *d = theRemapTable.pixFromNorm(*s);
+         ++d;
+         ++s;
+      }
+   }
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimU16ImageData.h b/Utilities/OSSIM/ossim_core/imaging/ossimU16ImageData.h
new file mode 100644
index 0000000000..582a2ab47a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimU16ImageData.h
@@ -0,0 +1,208 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class declaration of ossimU16ImageData.  Specialized image data object for
+// unsigned short data.
+//
+// NOTE:  This object is optimized for unsigned short data and assumes the
+//        following:  null pixel value  = 0.0
+//                    min  pixel value  = 1.0
+//                    max  pixel value  = 65536.0  (2^16 - 1)
+//
+//        If you want anything else use the less efficient ossimImageData.
+//
+//*************************************************************************
+// $Id: ossimU16ImageData.h,v 1.16 2004/09/02 13:59:03 dburken Exp $
+
+#ifndef ossimU16ImageData_HEADER
+#define ossimU16ImageData_HEADER
+
+#include "ossimImageData.h"
+#include "imaging/remap_tables/ossimNormalizedU16RemapTable.h"
+
+class OSSIMDLLEXPORT ossimU16ImageData : public ossimImageData
+{
+public:
+   ossimU16ImageData(ossimSource* source,
+                     ossim_uint32 bands = 1);
+
+   ossimU16ImageData(ossimSource* source,
+                    ossim_uint32 bands,
+                    ossim_uint32 width,
+                    ossim_uint32 height);
+
+   ossimU16ImageData(const ossimU16ImageData &rhs);
+
+   virtual ~ossimU16ImageData();
+
+   /*!
+    * Perform object duplication.
+    */
+   virtual ossimObject* dup()const;
+
+   /*!
+    * will fill the entire band with
+    * the value.
+    */
+   void fill(ossim_uint32 band, double value);
+
+   /*!
+    * will fill all bands with the passed in
+    * value.
+    */
+   void fill(double value);
+
+   virtual ossimDataObjectStatus validate() const;
+
+   /*!
+    * will go to the band and offset and compute the
+    * normalized float and return it back to the
+    * caller through the result argument.
+    */
+   virtual void getNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   float& result)const;
+
+   /*!
+    * This will assign to this object a normalized
+    * value by unnormalizing to its native type.
+    */
+   virtual void setNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   float input);
+   
+   /*!
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedFloat(ossimImageData* result)const;
+   
+   /*!
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedDouble(ossimImageData* result)const;
+
+   /*!
+    * Will take the normalized input and convert it
+    * to this tile's data type.  Example:  if this
+    * tile is of type UCHAR and its input is of type
+    * NORALIZED_FLOAT it will unnormalize the data by
+    * doing:
+    *
+    * minPix + normalizedInput*(maxPix-minPix)
+    *
+    * on a per band basis.
+    */
+   virtual void unnormalizeInput(ossimImageData* normalizedInput);
+
+   /*!
+    * This will compute the average value for the band.
+    */
+   virtual double computeAverageBandValue(ossim_uint32 bandNumber = 0);
+
+   /*!
+    * This will call the compute average band value and then
+    * use that in the calculation of:
+    
+    * It will then do a SUM[(Mean - Actual)^2]/width*height.
+    *
+    * This is the average variance from the passed in
+    * mean.  Basically think of the mean as a completely
+    * grey image and we would like to see how this
+    * image varies from the passed in mean.
+    */
+   virtual double computeMeanSquaredError(double meanValue,
+                                          ossim_uint32 bandNumber = 0);
+  
+   virtual void populateHistogram(ossimMultiBandHistogram* histo);
+
+   /*!
+    *  Initializes data to null pixel values.
+    */
+   virtual void makeBlank();
+
+   virtual void setValue(long x, long y, double color);
+
+   virtual void loadBand(const void* src,
+                         const ossimIrect& src_rect,
+                         ossim_uint32 band);
+   
+   virtual void loadTile(void* src,
+                         const ossimIrect& src_rect,
+                         ossimInterleaveType il_type);
+
+   virtual void unloadBand(void* dest,
+                           const ossimIrect& dest_rect,
+                           ossim_uint32 band) const;
+   
+   /*!
+    * Copies entire tile to buf passed in.  Data put in buf is normalized.
+    * The "buf" passed to method is assumed to be at least as big as:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyTileToNormalizedBuffer(double* buf) const;
+   
+   /*!
+    * Copies buf passed in to tile.  Data is unnormalized to the tile's
+    * scalar type.
+    * The "buf" passed to method is assumed to be at least as big as the tiles:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyNormalizedBufferToTile(double* buf);
+
+   /*!
+    * Will copy this tiles specified band number to the normalized buffer.
+    * if the band is out of range then nothing is done and returns.
+    */
+   virtual void copyTileToNormalizedBuffer(ossim_uint32 band, double* buf) const;
+   virtual void copyTileToNormalizedBuffer(ossim_uint32 band, float* buf)const;
+
+   /*!
+    * Copies entire tile to buf passed in.  Data put in buf is normalized.
+    * The "buf" passed to method is assumed to be at least as big as:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyTileToNormalizedBuffer(float* buf) const;
+   
+   /*!
+    * Copies buf passed in to tile.  Data is unnormalized to the tile's
+    * scalar type.
+    * The "buf" passed to method is assumed to be at least as big as the tiles:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyNormalizedBufferToTile(float* buf);
+
+   /*!
+    * Will copy the normalized buffer to this tiles
+    * specified band.  If band is out of range then nothing
+    * is done and returns.
+    */
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           double* buf);
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           float* buf);
+protected:
+   ossimU16ImageData();
+
+
+private:
+
+   // Disallow from use...
+   const ossimU16ImageData& operator =(const ossimU16ImageData &rhs)
+                                     {return *this;}
+
+   static const ossimNormalizedU16RemapTable theRemapTable;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimU8ImageData.cpp b/Utilities/OSSIM/ossim_core/imaging/ossimU8ImageData.cpp
new file mode 100644
index 0000000000..b10a547c6d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimU8ImageData.cpp
@@ -0,0 +1,738 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class definition of ossimU8ImageData.  Specialized image data object for
+// unsigned char data.
+//
+// NOTE:  This object is optimized for unsigned char data and assumes the
+//        following:  null pixel value  = 0.0
+//                    min  pixel value  = 1.0
+//                    max  pixel value  = 255.0
+//
+//        If you want anything else use the less efficient ossimImageData.
+//
+//*************************************************************************
+// $Id: ossimU8ImageData.cpp,v 1.26 2005/08/11 14:31:25 dburken Exp $
+
+#include <cstring>  // for memset function
+using namespace std;
+
+#include <imaging/ossimU8ImageData.h>
+#include <base/common/ossimSource.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+
+RTTI_DEF1(ossimU8ImageData, "ossimU8ImageData", ossimImageData)
+
+const ossimNormalizedU8RemapTable ossimU8ImageData::theRemapTable;
+   
+ossimU8ImageData::ossimU8ImageData(ossimSource* source,
+                                   ossim_uint32 bands)
+   :
+      ossimImageData(source,
+                     OSSIM_UCHAR,
+                     bands)
+{
+}
+
+ossimU8ImageData::ossimU8ImageData(ossimSource* source,
+                                   ossim_uint32 bands,
+                                   ossim_uint32 width,
+                                   ossim_uint32 height)
+   :
+      ossimImageData(source,
+                     OSSIM_UCHAR,
+                     bands,
+                     width,
+                     height)
+{
+}
+
+ossimU8ImageData::~ossimU8ImageData()
+{
+}
+
+ossimObject* ossimU8ImageData::dup()const
+{
+   return new ossimU8ImageData(*this);
+}
+
+void ossimU8ImageData::fill(double value)
+{
+   ossimImageData::fill(value);
+}
+
+ossimDataObjectStatus ossimU8ImageData::validate() const
+{
+   if (theDataBuffer == NULL)
+   {
+      setDataObjectStatus(OSSIM_NULL);
+      return OSSIM_NULL;
+   }
+   
+   ossim_uint32 count = 0;
+   const ossim_uint32 SIZE = getSize();
+   const ossim_uint32 BOUNDS = getSizePerBand();
+   const ossim_uint32 NUMBER_OF_BANDS = getNumberOfBands();
+   
+   for(ossim_uint32 band = 0; band < NUMBER_OF_BANDS; ++band)
+   {
+      const ossim_uint8* p  = getUcharBuf(band);
+      ossim_uint8 np = (ossim_uint8)getNullPix(band);
+      for (ossim_uint32 i=0; i<BOUNDS; ++i)
+      {
+         // check if the band is null
+         if (p[i] != np) ++count;         
+      }
+   }
+   
+   if (!count)
+      setDataObjectStatus(OSSIM_EMPTY);
+   else if (count == SIZE)
+      setDataObjectStatus(OSSIM_FULL);
+   else
+      setDataObjectStatus(OSSIM_PARTIAL);
+
+   return getDataObjectStatus();
+}
+
+void ossimU8ImageData::getNormalizedFloat(ossim_uint32 offset,
+                                          ossim_uint32 bandNumber,
+                                          float& result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   
+   // make sure that the types and width and height are good.
+   if( (getDataObjectStatus() == OSSIM_NULL) && isValidBand(bandNumber) )
+   {
+      return;
+   }
+   
+   const ossim_uint8* sourceBuf = getUcharBuf(bandNumber);
+   result = static_cast<float>(theRemapTable.normFromPix(sourceBuf[offset]));
+}
+
+void ossimU8ImageData::setNormalizedFloat(ossim_uint32 offset,
+                                          ossim_uint32 bandNumber,
+                                          float inputValue)
+{
+   // make sure that the types and width and height are
+   // good.
+   if((getDataObjectStatus() == OSSIM_NULL)&&
+      (bandNumber < getNumberOfBands()))
+   {
+      return;
+   }
+
+   ossim_uint8* sourceBuf = getUcharBuf(bandNumber);
+   sourceBuf[offset]
+      = static_cast<ossim_uint8>(theRemapTable.pixFromNorm(inputValue));
+}
+
+void ossimU8ImageData::convertToNormalizedFloat(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_FLOAT) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+      {
+         const ossim_uint8* sourceBuf = getUcharBuf(bandCount);
+         float* resultBuf = static_cast<float*>(result->getBuf(bandCount));
+         for(ossim_uint32 counter = 0; counter <  size; ++counter)
+         {
+            resultBuf[counter]
+               = static_cast<float>(theRemapTable.
+                                    normFromPix(sourceBuf[counter]));
+         }
+      }
+   }
+}
+
+void ossimU8ImageData::convertToNormalizedDouble(ossimImageData* result)const
+{
+   if(!result)
+   {
+      return;
+   }
+   
+   // make sure that the types and width and height are
+   // good.
+   if( (result->getScalarType() != OSSIM_NORMALIZED_FLOAT) ||
+       (result->getNumberOfBands() != this->getNumberOfBands())||
+       (result->getWidth() != this->getWidth()) ||
+       (result->getHeight() != this->getHeight())||
+       (result->getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_NULL))
+   {
+      return;
+   }
+
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+      {
+         const ossim_uint8* sourceBuf = getUcharBuf(bandCount);
+         double* resultBuf = static_cast<double*>(result->getBuf(bandCount));
+         for(ossim_uint32 counter = 0; counter <  size; ++counter)
+         {
+            resultBuf[counter] = theRemapTable.normFromPix(sourceBuf[counter]);
+         }
+      }
+   }
+}
+
+void ossimU8ImageData::unnormalizeInput(ossimImageData* normalizedInput)
+{
+   if((normalizedInput->getScalarType() != OSSIM_NORMALIZED_FLOAT) &&
+      (normalizedInput->getScalarType() != OSSIM_NORMALIZED_DOUBLE) )
+   {
+      //ERROR
+      return;
+   }
+   
+   ossim_uint32 counter = 0;
+   ossim_uint32 bandCount = 0;
+   ossim_uint32 size = getSizePerBand();
+   ossimScalarType scalarType = normalizedInput->getScalarType();
+
+   if(size > 0)
+   {
+      if(scalarType == OSSIM_NORMALIZED_FLOAT)
+      {
+         for(bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+         {
+            float* sourceBuf =
+               static_cast<float*>(normalizedInput->getBuf(bandCount));
+            ossim_uint8* resultBuf = getUcharBuf(bandCount);
+            for(counter = 0; counter <  size; ++counter)
+            {
+               resultBuf[counter]
+                  = static_cast<ossim_uint8>(theRemapTable.
+                                       pixFromNorm(sourceBuf[counter]));
+            }
+         }
+      }
+      else // Double
+      {
+         for(bandCount = 0; bandCount < theNumberOfDataComponents; ++bandCount)
+         {
+            double* sourceBuf =
+               static_cast<double*>(normalizedInput->getBuf(bandCount));
+            ossim_uint8* resultBuf = getUcharBuf(bandCount);
+            for(counter = 0; counter <  size; ++counter)
+            {
+               resultBuf[counter]
+                  = static_cast<ossim_uint8>(theRemapTable.
+                                       pixFromNorm(sourceBuf[counter]));
+            }
+         }
+      }
+   }   
+}
+
+double ossimU8ImageData::computeMeanSquaredError(double meanValue,
+                                                 ossim_uint32 bandNumber)
+{
+   double result = -1; // invalid MSE
+   ossim_uint32 index = 0;
+   double delta = 0;
+   ossim_uint32 validPixelCount=0;
+   
+   ossim_uint8* buffer = getUcharBuf(bandNumber);
+   if(buffer)
+   {
+      ossim_uint32 bounds = getWidth()*getHeight();
+      for(index = 0; index < bounds; ++index)
+      {
+         if(!isNull(index))
+         {
+            delta = *buffer - meanValue;
+            result += (delta*delta);
+            ++validPixelCount;
+         }
+         ++buffer;
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+//******************************************************************
+//
+// NOTE: I was checking for null and not adding it to the histogram.
+//       this was messing up the equalization algorithms since the
+//       accumulation histogram did not represent the area of the
+//       image.  For now I will leave out the check for "is null" and
+//       add this to the count so that the total accumulation is the
+//       area of the image.
+//
+//******************************************************************
+void ossimU8ImageData::populateHistogram(ossimMultiBandHistogram* histo)
+{
+   ossim_uint32 numberOfBands = getNumberOfBands();
+
+   if( (getDataObjectStatus() == OSSIM_NULL) ||
+       (getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return;
+   }
+
+   for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+   {
+      ossimHistogram* currentHisto = histo->getHistogram(band);
+      ossim_uint8* buffer = getUcharBuf(band);
+      
+      if(currentHisto)
+      {
+         float *counts = currentHisto->GetCounts();
+         ossim_uint32 upperBound = getWidth()*getHeight();
+         for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            counts[buffer[offset]]++;
+         }
+      }
+   }
+}
+
+double ossimU8ImageData::computeAverageBandValue(ossim_uint32 bandNumber)
+{
+   double result = 0.0;
+   ossim_uint32 index = 0;
+   ossim_uint32 validPixelCount=0;
+   
+   ossim_uint8* buffer = getUcharBuf(bandNumber);
+   if(buffer)
+   {
+      ossim_uint32 bounds = getWidth()*getHeight();
+      for(index = 0; index < bounds; ++index)
+      {
+         if(!isNull(index))
+         {
+            result += *buffer;
+            ++validPixelCount;
+         }
+         ++buffer;
+      }
+      if(validPixelCount > 0)
+      {
+         result /= validPixelCount;
+      }
+   }
+
+   return result;
+}
+
+void ossimU8ImageData::makeBlank()
+{
+   if ( (theDataBuffer == NULL) || (getDataObjectStatus() == OSSIM_EMPTY) )
+   {
+      return; // nothing to do...
+   }
+
+   const ossim_uint32 BANDS = getNumberOfBands();
+   int n = static_cast<int>(getSizePerBand());
+   for(ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      int c = static_cast<int>(theNullPixelValue[band]);
+      void* p = getBuf(band);
+      memset(p, c, n);
+   }
+   
+   setDataObjectStatus(OSSIM_EMPTY);
+}
+
+void ossimU8ImageData::setValue(ossim_int32 x, ossim_int32 y, double color)
+{
+   if(theDataBuffer&&isWithin(x, y))
+   {
+      //***
+      // Compute the offset into the buffer for (x,y).  This should always
+      // come out positive.
+      //***
+      ossim_uint32 ux = static_cast<ossim_uint32>(x - theOrigin.x);
+      ossim_uint32 uy = static_cast<ossim_uint32>(y - theOrigin.y);
+
+      ossim_uint32 offset = uy * theSpatialExtents[0] + ux;
+      
+      for(ossim_uint32 band = 0; band < theNumberOfDataComponents; ++band)
+      {
+         ossim_uint8* buf = getUcharBuf(band)+offset;
+         *buf = (ossim_uint8)color;
+      }
+   }
+}
+
+void ossimU8ImageData::fill(ossim_uint32 band, double value)
+{
+   void* s         = getBuf(band);
+
+   if (s == NULL) return; // nothing to do...
+
+   ossim_uint32 size_in_pixels = getSizePerBand();
+   ossim_uint8* p = getUcharBuf(band);
+   ossim_uint8 np = static_cast<ossim_uint8>(value);
+
+   for (ossim_uint32 i=0; i<size_in_pixels; ++i) p[i] = np;
+
+   // Set the status to unknown since we don't know about the other bands.
+   setDataObjectStatus(OSSIM_STATUS_UNKNOWN);
+}
+
+
+bool ossimU8ImageData::isNull(ossim_uint32 offset)const
+{
+   for(ossim_uint32 band = 0; band < getNumberOfBands(); ++band)  
+   {
+      const ossim_uint8* buf = getUcharBuf(band)+offset;
+      
+      if((*buf) != theNullPixelValue[band])
+      {
+         return false;
+      }
+   }
+
+   return true;
+}
+
+void ossimU8ImageData::setNull(ossim_uint32 offset)
+{
+   for(ossim_uint32 band = 0; band < getNumberOfBands(); ++band)  
+   {
+      ossim_uint8* buf = (getUcharBuf(band))+offset;
+      *buf       = (ossim_uint8)theNullPixelValue[band];
+   }
+}
+
+void ossimU8ImageData::loadBand(const void* src,
+                                const ossimIrect& src_rect,
+                                ossim_uint32 band)
+{
+   ossimImageData::loadBand(ossim_uint8(0), src, src_rect, band);
+}
+
+void ossimU8ImageData::loadTile(void* src,
+                                const ossimIrect& src_rect,
+                                ossimInterleaveType il_type)
+{
+   // Load the tile from the buffer.
+   switch (il_type)
+   {
+      case OSSIM_BIP:
+         ossimImageData::loadTileFromBip(ossim_uint8(0), src, src_rect);
+         break;
+      case OSSIM_BIL:
+         ossimImageData::loadTileFromBil(ossim_uint8(0), src, src_rect);
+         break;
+      case OSSIM_BSQ:
+         ossimImageData::loadTileFromBsq(ossim_uint8(0), src, src_rect);
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimU8ImageData::loadTile"
+            << "\nUnknown interleave type passed to method.  Returning..."
+            << endl;
+         break;
+   } 
+}
+
+void ossimU8ImageData::unloadBand(void* dest,
+                                  const ossimIrect& dest_rect,
+                                  ossim_uint32 band) const
+{
+   ossimImageData::unloadBand(ossim_uint8(0), dest, dest_rect,
+                              getImageRectangle(), band);
+}
+
+void ossimU8ImageData::copyTileToNormalizedBuffer(double* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU8ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   ossim_uint32 size = getSizePerBand();
+   if(!getBuf())
+   {
+      memset(buf, '\0', size);
+      return;
+   }
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); ++band)
+      {
+         const ossim_uint8*  s = getUcharBuf(band);   // source
+         double* d = buf + (band*size);   // destination
+         if(s&&d)
+         {
+            for(ossim_uint32 index = 0; index < size; ++index)
+            {
+               d[index] = theRemapTable.
+                          normFromPix(static_cast<ossim_int32>(s[index]));
+            }
+         }
+      }
+   }
+}
+
+void ossimU8ImageData::copyTileToNormalizedBuffer(float* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU8ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   ossim_uint32 size = getSizePerBand();
+   if(!getBuf())
+   {
+      memset(buf, '\0', size);
+      return;
+   }
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); ++band)
+      {
+         const ossim_uint8*  s = getUcharBuf(band);   // source
+         float* d = buf + (band*size);   // destination
+         if(s&&d)
+         {
+            for(ossim_uint32 index = 0; index < size; ++index)
+            {
+               d[index] = theRemapTable.
+                          normFromPix(static_cast<ossim_int32>(s[index]));
+            }
+         }
+      }
+   }
+}
+
+void ossimU8ImageData::copyTileToNormalizedBuffer(ossim_uint32 band,
+                                                  double* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU8ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   ossim_uint32 size = getSizePerBand();
+   if(!getBuf(band))
+   {
+      memset(buf, '\0', size);
+      return;
+   }
+   
+   if(size > 0)
+   {
+      const ossim_uint8*  s = getUcharBuf(band);   // source
+      double* d = buf;   // destination
+      for(ossim_uint32 index = 0; index < size; ++index)
+      {
+         *d = theRemapTable.
+              normFromPix(static_cast<ossim_int32>(*s));
+         ++d;
+         ++s;
+      }
+   }
+}
+
+void ossimU8ImageData::copyTileToNormalizedBuffer(ossim_uint32 band,
+                                                  float* buf) const
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU8ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   ossim_uint32 size = getSizePerBand();
+   if(!getBuf(band))
+   {
+      memset(buf, '\0', size);
+      return;
+   }
+   
+   if(size > 0)
+   {
+      const ossim_uint8*  s = getUcharBuf(band);   // source
+      float* d = buf;   // destination
+      for(ossim_uint32 index = 0; index < size; ++index)
+      {
+         *d = theRemapTable.
+              normFromPix(static_cast<ossim_int32>(*s));
+         ++d;
+         ++s;
+      }
+   }
+}
+
+void ossimU8ImageData::copyNormalizedBufferToTile(double* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU8ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf()) return;
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); ++band)
+      {
+         double* s = buf + (band*size);  // source
+         ossim_uint8*  d = getUcharBuf(band);  // destination
+
+         for(ossim_uint32 index = 0; index <  size; ++index)
+         {
+            d[index] = theRemapTable.pixFromNorm(s[index]);
+         }
+      }
+   }
+}
+
+void ossimU8ImageData::copyNormalizedBufferToTile(float* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU8ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf()) return;
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      for(ossim_uint32 band = 0; band < getNumberOfBands(); ++band)
+      {
+         float* s = buf + (band*size);  // source
+         ossim_uint8*  d = getUcharBuf(band);  // destination
+
+         for(ossim_uint32 index = 0; index < size; ++index)
+         {
+            d[index] = theRemapTable.pixFromNorm(s[index]);
+         }
+      }
+   }
+}
+
+void ossimU8ImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                  double* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU8ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf(band)) return;
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      double* s = buf;  // source
+      ossim_uint8*  d = getUcharBuf(band);  // destination
+      
+      for(ossim_uint32 index = 0; index <  size; ++index)
+      {
+         d[index] = theRemapTable.pixFromNorm(s[index]);
+      }
+   }
+}
+
+void ossimU8ImageData::copyNormalizedBufferToTile(ossim_uint32 band,
+                                                  float* buf)
+{
+   if (!buf)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "ossimU8ImageData::copyTileToNormalizedBuffer File %s line %d\nNull pointer passed to method!",
+                    __FILE__,
+                    __LINE__);
+      return;
+   }
+   if(!getBuf(band)) return;
+   ossim_uint32 size = getSizePerBand();
+   
+   if(size > 0)
+   {
+      float* s = buf;  // source
+      ossim_uint8*  d = getUcharBuf(band);  // destination
+      
+      for(ossim_uint32 index = 0; index <  size; ++index)
+      {
+         d[index] = theRemapTable.pixFromNorm(s[index]);
+      }
+   }
+}
+
+
+const ossimU8ImageData& ossimU8ImageData::operator=(
+   const ossimU8ImageData& /* rhs */)
+{
+   return *this;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/ossimU8ImageData.h b/Utilities/OSSIM/ossim_core/imaging/ossimU8ImageData.h
new file mode 100644
index 0000000000..ad772cc4e0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/ossimU8ImageData.h
@@ -0,0 +1,189 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Class declaration of ossimU8ImageData.  Specialized image data object for
+// unsigned char data.
+//
+// NOTE:  This object is optimized for unsigned char data and assumes the
+//        following:  null pixel value  = 0.0
+//                    min  pixel value  = 1.0
+//                    max  pixel value  = 255.0
+//
+//        If you want anything else use the less efficient ossimImageData.
+//
+//*************************************************************************
+// $Id: ossimU8ImageData.h,v 1.19 2005/07/23 15:54:50 dburken Exp $
+
+#ifndef ossimU8ImageData_HEADER
+#define ossimU8ImageData_HEADER
+
+#include "ossimImageData.h"
+#include "imaging/remap_tables/ossimNormalizedU8RemapTable.h"
+
+class OSSIMDLLEXPORT ossimU8ImageData : public ossimImageData
+{
+public:
+   ossimU8ImageData(ossimSource* source=NULL,
+                    ossim_uint32 bands = 1);
+   
+   ossimU8ImageData(ossimSource* source,
+                    ossim_uint32 bands,
+                    ossim_uint32 width,
+                    ossim_uint32 height);
+   
+   ossimU8ImageData(const ossimU8ImageData& rhs)
+      :ossimImageData(rhs)
+      {}
+
+   virtual ~ossimU8ImageData();
+
+   virtual ossimObject* dup()const;
+
+   /*!
+    * will fill the entire band with
+    * the value.
+    */
+   void fill(ossim_uint32 band, double value);
+   void fill(double value);
+
+   bool isNull(ossim_uint32 offset)const;
+   void setNull(ossim_uint32 offset);
+
+   virtual ossimDataObjectStatus validate() const;
+
+   /*!
+    * will go to the band and offset and compute the
+    * normalized float and return it back to the
+    * caller through the result argument.
+    */
+   virtual void getNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   float& result)const;
+
+   /*!
+    * This will assign to this object a normalized
+    * value by unnormalizing to its native type.
+    */
+   virtual void setNormalizedFloat(ossim_uint32 offset,
+                                   ossim_uint32 bandNumber,
+                                   float input);
+   
+   /*!
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedFloat(ossimImageData* result)const;
+   
+   /*!
+    * Will use the memory that you pass in to normalize
+    * this data object.
+    */
+   virtual void convertToNormalizedDouble(ossimImageData* result)const;
+
+   /*!
+    * Will take the normalized input and convert it
+    * to this tile's data type.  Example:  if this
+    * tile is of type UCHAR and its input is of type
+    * NORALIZED_FLOAT it will unnormalize the data by
+    * doing:
+    *
+    * minPix + normalizedInput*(maxPix-minPix)
+    *
+    * on a per band basis.
+    */
+   virtual void unnormalizeInput(ossimImageData* normalizedInput);
+
+   /*!
+    * This will compute the average value for the band.
+    */
+   virtual double computeAverageBandValue(ossim_uint32 bandNumber = 0);
+
+   /*!
+    * This will call the compute average band value and then
+    * use that in the calculation of:
+    
+    * It will then do a SUM[(Mean - Actual)^2]/width*height.
+    *
+    * This is the average variance from the passed in
+    * mean.  Basically think of the mean as a completely
+    * grey image and we would like to see how this
+    * image varies from the passed in mean.
+    */
+   virtual double computeMeanSquaredError(double meanValue,
+                                          ossim_uint32 bandNumber = 0);
+  
+   virtual void populateHistogram(ossimMultiBandHistogram* histo);
+
+   /*!
+    *  Initializes data to null pixel values.
+    */
+   virtual void makeBlank();
+
+   virtual void setValue(ossim_int32 x, ossim_int32 y, double color);
+
+   virtual void loadBand(const void* src,
+                         const ossimIrect& src_rect,
+                         ossim_uint32 band);
+   
+   virtual void loadTile(void* src,
+                         const ossimIrect& src_rect,
+                         ossimInterleaveType il_type);
+
+   virtual void unloadBand(void* dest,
+                           const ossimIrect& dest_rect,
+                           ossim_uint32 band) const;
+
+   /*!
+    * Copies entire tile to buf passed in.  Data put in buf is normalized.
+    * The "buf" passed to method is assumed to be at least as big as:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyTileToNormalizedBuffer(double* buf) const;
+   virtual void copyTileToNormalizedBuffer(float* buf) const;
+
+   /*!
+    * Will copy this tiles specified band number to the normalized buffer.
+    * if the band is out of range then nothing is done and returns.
+    */
+   virtual void copyTileToNormalizedBuffer(ossim_uint32 band, double* buf) const;
+   virtual void copyTileToNormalizedBuffer(ossim_uint32 band, float* buf)const;
+
+   /*!
+    * Copies buf passed in to tile.  Data is unnormalized to the tile's
+    * scalar type.
+    * The "buf" passed to method is assumed to be at least as big as the tiles:
+    * "getSize() * sizeof(double)"
+    */
+   virtual void copyNormalizedBufferToTile(double* buf);
+   virtual void copyNormalizedBufferToTile(float* buf);
+
+   /*!
+    * Will copy the normalized buffer to this tiles
+    * specified band.  If band is out of range then nothing
+    * is done and returns.
+    */
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           double* buf);
+   virtual void copyNormalizedBufferToTile(ossim_uint32 band,
+                                           float* buf);
+   
+   virtual ossim_float64 getMinNormalizedPix() const { return theRemapTable[1]; }
+   
+private:
+
+   const ossimU8ImageData& operator =(const ossimU8ImageData &rhs);
+
+   static const ossimNormalizedU8RemapTable theRemapTable;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/patch/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/patch/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/patch/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/patch/ossimTilePatch.cpp b/Utilities/OSSIM/ossim_core/imaging/patch/ossimTilePatch.cpp
new file mode 100644
index 0000000000..a78765b3e6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/patch/ossimTilePatch.cpp
@@ -0,0 +1,518 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimTilePatch.cpp,v 1.36 2005/02/11 15:07:32 dburken Exp $
+
+#include <vector>
+using namespace std;
+
+#include <imaging/patch/ossimTilePatch.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/ossimImageSource.h>
+#include <base/common/ossimErrorCodes.h>
+ossimDiscreteNearestNeighbor ossimTilePatch::nearestNeighborKernel;
+
+ossimTilePatch::ossimTilePatch(ossimImageSourceInterface* input)
+{
+   thePatchData = ossimImageDataFactory::instance()->create(NULL, input);
+   thePatchData->initialize();
+}
+
+ossimTilePatch::ossimTilePatch(ossimScalarType scalarType,
+                               long numberOfComponents,
+                               long width,
+                               long height)
+   :thePatchData(NULL)
+{
+   thePatchData = ossimImageDataFactory::instance()->create(NULL,
+                                                            scalarType,
+                                                            numberOfComponents,
+                                                            width,
+                                                            height);
+
+   thePatchData->initialize();
+}
+
+ossimTilePatch::~ossimTilePatch()
+{
+}
+
+ossimIrect ossimTilePatch::getRect()const
+{
+   return thePatchData->getImageRectangle();
+}
+
+ossimDrect ossimTilePatch::findBoundingRect(const ossimDpt &p1,
+                                            const ossimDpt &p2,
+                                            const ossimDpt &p3,
+                                            const ossimDpt &p4)
+{
+   vector<ossimDpt> points(4);
+   
+   points[0] = p1;
+   points[1] = p2;
+   points[2] = p3;
+   points[3] = p4;
+
+   return ossimDrect(points);
+}
+
+void ossimTilePatch::fillPatch(ossimImageSourceInterface* tileSource,
+                               long resLevel)
+{
+   // long w = tileSource->getTileWidth();
+   // long h = tileSource->getTileHeight();
+   
+   if(thePatchData.valid())
+   {
+      ossimIrect rect   = thePatchData->getImageRectangle();
+      thePatchData->makeBlank();
+      // ossimIpt origin(rect.ul());
+      ossimRefPtr<ossimImageData> aTile = tileSource->getTile(rect, resLevel);
+      thePatchData->loadTile(aTile.get());
+   }
+}
+
+void ossimTilePatch::setData(ossimRefPtr<ossimImageData>& patchData)
+{
+   thePatchData = patchData;
+}
+
+void ossimTilePatch::convolve(ossimDiscreteConvolutionKernel* kernel)
+{
+   if(!kernel) return;
+
+   long w = thePatchData->getWidth();
+   long h = thePatchData->getHeight();
+
+   long kW = kernel->getWidth();
+   long kH = kernel->getHeight();
+   ossimIpt origin = thePatchData->getOrigin();
+   
+   if( (w < kW) || (h < kH))
+   {
+      cerr << " Error ossimTilePatch::convolve(kernel): patch is smaller than kernel size" << endl;
+      return;
+   }
+   ossimRefPtr<ossimImageData> kernelBuffer =(ossimImageData*) thePatchData->dup();
+
+   // now let's make the buffer just fit the convolution filter
+   //
+   kernelBuffer->setWidth(w - kW);
+   kernelBuffer->setHeight(h - kH);
+   kernelBuffer->setOrigin(ossimDpt(origin.x + kW/2.0,
+                                    origin.y + kH/2.0));
+   kernelBuffer->initialize();
+
+   fillTile(kernelBuffer, kernel);
+
+   kernelBuffer->validate();
+   // now copy the data back to the buffer
+   //
+   thePatchData->loadTile(kernelBuffer.get());
+
+   // now make sure we validate the buffer.
+   thePatchData->validate();
+}
+
+void ossimTilePatch::fillTile(ossimRefPtr<ossimImageData>& aTile)const
+{
+   if(aTile.valid() &&
+      (aTile->getNumberOfBands()==thePatchData->getNumberOfBands())&&
+      (aTile->getBuf())&&
+      (thePatchData->getBuf())&&
+      (thePatchData->getScalarType()==aTile->getScalarType()))
+   {
+      aTile->loadTile(thePatchData.get());
+   }
+}
+
+void ossimTilePatch::fillTile(ossimRefPtr<ossimImageData>& result,
+                              ossimDiscreteConvolutionKernel* kernel)const
+{
+   if(!kernel)
+   {
+      cerr << "Error: Kernel is NULL in  ossimTilePatch::fillTile(tile, kernel)!!" << endl;
+   }
+   if(thePatchData->getScalarType() != result->getScalarType())
+   {
+      //ERROR
+      return;
+   }
+   else
+   {
+      switch(thePatchData->getScalarType())
+      {
+      case OSSIM_UCHAR:
+      {
+         fillTileTemplate(static_cast<ossim_uint8>(0),
+                          result,
+                          kernel);
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         fillTileTemplate(static_cast<ossim_uint16>(0),
+                          result,
+                          kernel);
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         fillTileTemplate(static_cast<ossim_sint16>(0),
+                          result,
+                          kernel);
+         break;
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         fillTileTemplate(static_cast<float>(0),
+                          result,
+                          kernel);
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         fillTileTemplate(static_cast<double>(0),
+                          result,
+                          kernel);
+         break;
+      }
+      default:
+	{
+	  ossimSetError("ossimTilePatch",
+			ossimErrorCodes::OSSIM_ERROR,
+			"unhandled scalar type %d",
+			(int)thePatchData->getScalarType());
+	  break;
+	}
+      }
+   }
+}
+
+
+
+void ossimTilePatch::fillTile(ossimRefPtr<ossimImageData>& result,
+                              const ossimDpt   &ul,
+                              const ossimDpt   &ur,
+                              const ossimDpt   &deltaUl,
+                              const ossimDpt   &deltaUr,
+                              const ossimDpt   &length)const
+{   
+   result->setNullPix(thePatchData->getNullPix(), thePatchData->getNumberOfBands());
+   result->setMinPix(thePatchData->getMinPix(), thePatchData->getNumberOfBands());
+   result->setMaxPix(thePatchData->getMaxPix(), thePatchData->getNumberOfBands());
+   result->makeBlank();
+   if(thePatchData->getScalarType() != result->getScalarType())
+   {
+      //ERROR
+      return;
+   }
+   else
+   {
+      switch(thePatchData->getScalarType())
+      {
+      case OSSIM_UCHAR:
+      {
+         fillTileTemplate(static_cast<ossim_uint8>(0),
+                          result,
+                          ul,
+                          ur,
+                          deltaUl,
+                          deltaUr,
+                          length);
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         fillTileTemplate(static_cast<ossim_uint16>(0),
+                          result,
+                          ul,
+                          ur,
+                          deltaUl,
+                          deltaUr,
+                          length);
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         fillTileTemplate(static_cast<ossim_sint16>(0),
+                          result,
+                          ul,
+                          ur,
+                          deltaUl,
+                          deltaUr,
+                          length);
+         break;
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         fillTileTemplate(static_cast<float>(0),
+                          result,
+                          ul,
+                          ur,
+                          deltaUl,
+                          deltaUr,
+                          length);
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         fillTileTemplate(static_cast<double>(0),
+                          result,
+                          ul,
+                          ur,
+                          deltaUl,
+                          deltaUr,
+                          length);
+         break;
+      }
+      default:
+	{
+	  ossimSetError("ossimTilePatch",
+			ossimErrorCodes::OSSIM_ERROR,
+			"unhandled scalar type %d",
+			(int)thePatchData->getScalarType());
+	  break;
+	}
+      }
+   }
+
+}
+
+
+template<class T>
+void ossimTilePatch::fillTileTemplate(T dummyVariable,
+                              ossimRefPtr<ossimImageData>& result,
+                              ossimDiscreteConvolutionKernel* kernel)const
+{
+   // get the origin.  The convolution could be
+   // an offset into the patch.
+   //
+   ossimIpt startOrigin   = result->getOrigin();
+
+   // Make sure that the patch is not empty or NULL
+   //
+   ossimDataObjectStatus status = thePatchData->getDataObjectStatus();
+   if((status==OSSIM_EMPTY)||
+      (status == OSSIM_NULL))
+   {
+      return;
+   }
+   ossimDpt startDelta(fabs((double)startOrigin.x - thePatchData->getOrigin().x),
+                       fabs((double)startOrigin.y - thePatchData->getOrigin().y));
+   
+   // let's setup some variables that we will need to do the
+   // convolution algorithm.
+   //
+   ossimIrect patchRect   = thePatchData->getImageRectangle();
+   long tileHeight        = result->getHeight();
+   long tileWidth         = result->getWidth();
+   long outputBands       = result->getNumberOfBands();
+   long convolutionWidth  = kernel->getWidth();
+   long convolutionHeight = kernel->getHeight();
+   long convolutionOffsetX= convolutionWidth/2;
+   long convolutionOffsetY= convolutionHeight/2;
+   long patchWidth        = patchRect.width();
+   long patchCenterOffset = (long)(patchWidth*startDelta.y + startDelta.x);
+   long patchConvolutionOffsetDelta = patchWidth*convolutionOffsetY + convolutionOffsetX;
+   long patchLineStartOffset        = patchCenterOffset  - patchConvolutionOffsetDelta;
+   long outputOffset                = 0;
+   double min = 1.0;
+   double max = 255.0;
+   if(status == OSSIM_PARTIAL) // must check for NULLS
+   {
+      for(long y = 0; y <tileHeight; y++)
+      {
+         patchCenterOffset = patchLineStartOffset;
+         
+         for(long x =0; x < tileWidth; x++)
+         {  
+            if(!thePatchData->isNull(patchCenterOffset))
+            {
+               double convolveResult = 0;
+               for(long b = 0; b < outputBands; ++b)
+               {                  
+                  min=result->getMinPix(b);
+                  max=result->getMaxPix(b);
+                  T* buf    = (T*)(thePatchData->getBuf(b)) + patchCenterOffset;
+                  T* outBuf = (T*)(result->getBuf(b));
+
+                  kernel->convolveSubImage(buf,
+                                           patchWidth,
+                                           convolveResult);
+                  convolveResult = convolveResult < min?min:convolveResult;
+                  convolveResult = convolveResult > max?max:convolveResult;
+                  outBuf[outputOffset] = (ossim_uint8)convolveResult;
+               }
+            }
+            else
+            {
+               result->setNull(outputOffset);
+            }
+            ++outputOffset;
+            ++patchCenterOffset;
+         }
+         patchLineStartOffset += patchWidth;
+      }
+    }
+    else
+    {
+       for(long b = 0; b < outputBands; ++b)
+       {                  
+          double convolveResult = 0;
+          const T* buf    = (const T*)thePatchData->getBuf(b);
+          T* outBuf = (T*)(result->getBuf(b));
+          outputOffset = 0;
+          patchCenterOffset = (long)(patchWidth*startDelta.y + startDelta.x);
+          patchLineStartOffset  = patchCenterOffset - patchConvolutionOffsetDelta;
+          min=result->getMinPix(b);
+          max=result->getMaxPix(b);
+          
+          for(long y = 0; y <tileHeight; y++)
+          {
+             patchCenterOffset = patchLineStartOffset;
+             
+             for(long x =0; x < tileWidth; x++)
+             {
+                kernel->convolveSubImage(&buf[patchCenterOffset],
+                                         patchWidth,
+                                         convolveResult);
+                convolveResult = convolveResult < min? min:convolveResult;
+                convolveResult = convolveResult > max?max:convolveResult;
+                outBuf[outputOffset] = (T)convolveResult;
+                ++outputOffset;
+                ++patchCenterOffset;
+             }
+             patchLineStartOffset += patchWidth;
+          }
+       }
+    }
+}
+
+
+template <class T>
+void ossimTilePatch::fillTileTemplate(T dummyVariable,
+                              ossimRefPtr<ossimImageData>& result,
+                              const ossimDpt   &ul,
+                              const ossimDpt   &ur,
+                              const ossimDpt   &deltaUl,
+                              const ossimDpt   &deltaUr,
+                              const ossimDpt   &length)const
+{
+   double stepSizeWidth  = 1.0/length.x;
+   double stepSizeHeight = 1.0/length.y;
+   long patchWidth = thePatchData->getWidth();
+   long patchHeight = thePatchData->getHeight();
+
+   
+   ossimIrect rect = thePatchData->getImageRectangle();
+   
+   ossimDpt startSave(ul.x - rect.ul().x,
+                      ul.y - rect.ul().y );
+   ossimDpt endSave(ur.x - rect.ul().x,
+                    ur.y - rect.ul().y);
+   for(ossim_uint32 band = 0; band < thePatchData->getNumberOfBands(); ++band)
+   {
+      T *resultBuf = (T*)result->getBuf(band);
+      const T *sourceBuf = (T*)thePatchData->getBuf(band);
+      ossimDpt start = startSave;
+      ossimDpt end   = endSave;
+      T nullPix = static_cast<T>(result->getNullPix(band));
+      for(long y = 0; y < length.y; y++)
+      {
+         double deltaX = (end.x - start.x)*stepSizeWidth;
+         double deltaY = (end.y - start.y)*stepSizeHeight;
+         ossimDpt pointXY = start;
+         for(long x = 0; x < length.x; x++)
+         {
+            int xPixel = pointXY.x<0?(int)floor(pointXY.x):(int)pointXY.x;
+            int yPixel = pointXY.y<0?(int)floor(pointXY.y):(int)pointXY.y;
+            if( (xPixel >=0) && (xPixel < patchWidth) &&
+                (yPixel >=0) && (yPixel < patchHeight))
+            {              
+               *resultBuf = sourceBuf[yPixel*patchWidth + xPixel];
+            }
+            else
+            {
+               *resultBuf = nullPix;
+            }
+            
+            resultBuf++;
+            pointXY.y += deltaY;
+            pointXY.x += deltaX;
+         }
+         
+         start.x += deltaUl.x;
+         start.y += deltaUl.y;
+         end.x   += deltaUr.x;
+         end.y   += deltaUr.y;
+      }
+   }
+}
+
+
+void ossimTilePatch::setRect(const ossimDpt &p1,
+                             const ossimDpt &p2,
+                             const ossimDpt &p3,
+                             const ossimDpt &p4,
+                             const ossimDpt &tile_size,
+                             const ossimDpt &padding)
+{
+   setRect(findBoundingRect(p1, p2, p3, p4),
+           tile_size,
+           padding);
+}
+
+void ossimTilePatch::setRect(const ossimDpt &center,
+                             const ossimDpt &rect_size,
+                             const ossimDpt &tile_size,
+                             const ossimDpt &padding)
+{
+   ossimDpt ul (center - rect_size/2.0);
+   ossimDpt lr (center + rect_size/2.0);
+   ossimDrect rect (ul, lr);
+   setRect(rect, tile_size, padding);
+}
+
+void ossimTilePatch::setRect(const ossimDrect &aRect,
+                             const ossimDpt &tile_size,
+                             const ossimDpt &padding)
+{
+   ossimDpt   ul(aRect.ul().x - padding.x,
+                 aRect.ul().y - padding.y);
+   ossimDpt   lr(aRect.lr().x + padding.x,
+                 aRect.lr().y + padding.y);
+
+   ossimDrect rect(ul, lr);
+   rect.stretchOut();
+   
+//   rect   = alignRectToBoundary(rect, tile_size);
+
+   if(thePatchData.valid())
+   {
+      if(  ((long)thePatchData->getWidth()  != (long)rect.width()) ||
+           ((long)thePatchData->getHeight() != (long)rect.height()))
+      {
+         thePatchData->setWidth((long)rect.width());
+         thePatchData->setHeight((long)rect.height());
+      }
+      thePatchData->setOrigin(rect.ul());
+      thePatchData->initialize();
+   }
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/patch/ossimTilePatch.h b/Utilities/OSSIM/ossim_core/imaging/patch/ossimTilePatch.h
new file mode 100644
index 0000000000..ce0beafaf5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/patch/ossimTilePatch.h
@@ -0,0 +1,135 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimTilePatch.h,v 1.24 2005/02/18 15:59:25 dburken Exp $
+
+#ifndef ossimTilePatch_HEADER
+#define ossimTilePatch_HEADER
+#include <base/common/ossimObject.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimDrect.h>
+#include <imaging/filters/ossimDiscreteNearestNeighbor.h>
+#include <imaging/ossimImageData.h>
+
+class ossimImageSourceInterface;
+
+class ossimTilePatch : public ossimObject
+{
+public:
+   ossimTilePatch(ossimImageSourceInterface* input);
+   /*!
+    * The rect is assumed up right and all we need
+    * to do is compute the even tile boundary rect
+    */
+   ossimTilePatch(ossimScalarType scalarType = OSSIM_UCHAR,
+                  long numberOfComponents = 1,
+                  long width=128,
+                  long height=128);
+   virtual ~ossimTilePatch();
+   
+   /*!
+    * return the tile boundary aligned rectangle for this
+    * patch.
+    */
+   virtual ossimIrect getRect()const;
+
+   /*!
+    * The padding is for any convolution that must take
+    * place.  
+    */
+   virtual void setRect(const ossimDpt &p1,
+                        const ossimDpt &p2,
+                        const ossimDpt &p3,
+                        const ossimDpt &p4,
+                        const ossimDpt &tile_size,
+                        const ossimDpt &padding=ossimDpt(0,0));
+
+   virtual void setRect(const ossimDrect &aRect,
+                        const ossimDpt &tile_size,
+                        const ossimDpt &padding=ossimDpt(0,0));
+
+   virtual void setRect(const ossimDpt &center_of_rect,
+                        const ossimDpt &rect_size,
+                        const ossimDpt &tile_size,
+                        const ossimDpt &padding=ossimDpt(0,0));
+
+   /*!
+    * This will fill the tile from the tile patch.
+    */
+   virtual void fillTile(ossimRefPtr<ossimImageData>& aTile)const;
+
+   /*!
+    * This will fill the tile from the tile patch and apply the convolution
+    * kernel.  This is optimized for upright rectangles.  Use the bilinear
+    * fill tile bellow for arbitrary 4-sided polygons.
+    */
+   virtual void fillTile(ossimRefPtr<ossimImageData>& result,
+                         ossimDiscreteConvolutionKernel* kernel)const;
+
+   /*!
+    * We will assume that the patch is already
+    * big enough to satisfy the kernel size.
+    */
+   virtual void fillTile(ossimRefPtr<ossimImageData>& result,
+                         const ossimDpt   &ul,
+                         const ossimDpt   &ur,
+                         const ossimDpt   &deltaUl,
+                         const ossimDpt   &deltaUr,
+                         const ossimDpt   &length)const;
+
+
+   virtual void fillPatch(ossimImageSourceInterface *imageSource,
+                          long resLevel = 0);
+   
+   
+   
+//    static ossimIrect alignRectToBoundary(const ossimDrect &aRect,
+//                                          const ossimDpt &tile_size);
+   static ossimDrect findBoundingRect(const ossimDpt &p1,
+                                      const ossimDpt &p2,
+                                      const ossimDpt &p3,
+                                      const ossimDpt &p4);
+   /*!
+    * Do not delete this data.  We give raw access to the buffer
+    * if there are special things you wish to have done.
+    */
+   ossimRefPtr<ossimImageData> getData(){return thePatchData;}
+
+   void setData(ossimRefPtr<ossimImageData>& patchData);
+   /*!
+    *  This will implement an in place convolution.  It will
+    *  allocate a buffer pass it to the convolution algorithm
+    * and then replace the internal buffer.
+    */
+   void convolve(ossimDiscreteConvolutionKernel* kernel);
+   
+protected:
+   ossimRefPtr<ossimImageData>         thePatchData;
+   static ossimDiscreteNearestNeighbor nearestNeighborKernel;
+   
+
+
+   template<class T>
+   void fillTileTemplate(T dummyVariable,
+                         ossimRefPtr<ossimImageData>& result,
+                         const ossimDpt   &ul,
+                         const ossimDpt   &ur,
+                         const ossimDpt   &deltaUl,
+                         const ossimDpt   &deltaUr,
+                         const ossimDpt   &length)const;
+   
+   template<class T>
+   void fillTileTemplate(T dummyVariable,
+                         ossimRefPtr<ossimImageData>& result,
+                         ossimDiscreteConvolutionKernel* kernel)const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/reconstruction/ossimMeanMedianFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/reconstruction/ossimMeanMedianFilter.cpp
new file mode 100644
index 0000000000..e50a11ee83
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/reconstruction/ossimMeanMedianFilter.cpp
@@ -0,0 +1,929 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimMeanMedianFilter.cpp,v 1.11 2005/05/22 13:33:12 dburken Exp $
+
+#include <vector>
+#include <algorithm>
+#include <numeric>
+using namespace std;
+
+#include <imaging/reconstruction/ossimMeanMedianFilter.h>
+#include <base/property/ossimNumericProperty.h>
+#include <base/property/ossimBooleanProperty.h>
+#include <base/property/ossimStringProperty.h>
+
+RTTI_DEF1(ossimMeanMedianFilter,
+          "ossimMeanMedianFilter",
+          ossimImageSourceFilter);
+
+// Keywords used throughout.
+static const ossimString WINDOW_SIZE_KW = "window_size";
+static const ossimString FILTER_TYPE_KW = "filter_type";
+static const ossimString AUTO_GROW_KW   = "auto_grow_rectangle_flag";
+
+ossimMeanMedianFilter::ossimMeanMedianFilter(ossimObject* owner)
+   :ossimImageSourceFilter(owner),
+    theTile(0),
+    theFilterType(OSSIM_MEDIAN),
+    theWindowSize(3),
+    theEnableFillNullFlag(false),
+    theAutoGrowRectFlag(false)
+{
+   setDescription(ossimString("Mean Median Filter"));
+}
+
+ossimMeanMedianFilter::~ossimMeanMedianFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimMeanMedianFilter::getTile(
+   const ossimIrect& rect, ossim_uint32 resLevel)
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getTile(rect, resLevel);
+   }
+
+   ossim_uint32 halfSize = getWindowSize()>>1;
+
+   ossimIrect requestRect(rect.ul().x - halfSize,
+                          rect.ul().y - halfSize,
+                          rect.lr().x + halfSize,
+                          rect.lr().y + halfSize);
+
+   ossimRefPtr<ossimImageData> inputData =
+      ossimImageSourceFilter::getTile(requestRect, resLevel);
+   if(!inputData.valid() || !inputData->getBuf())
+   {
+      return inputData;
+   }
+
+   if(!theTile.valid())
+   {
+      theTile = (ossimImageData*)inputData->dup();
+      theTile->setImageRectangle(rect);
+   }
+   else
+   {
+      theTile->setImageRectangleAndBands(rect, inputData->getNumberOfBands());
+   }
+
+   applyFilter(inputData);
+
+   theTile->setDataObjectStatus(inputData->getDataObjectStatus());
+   if(theEnableFillNullFlag)
+   {
+      theTile->validate();
+   }
+
+   return theTile;
+}
+
+void ossimMeanMedianFilter::setWindowSize(ossim_uint32 windowSize)
+{
+   theWindowSize = windowSize;
+}
+
+ossim_uint32 ossimMeanMedianFilter::getWindowSize()const
+{
+   return theWindowSize;
+}
+
+void ossimMeanMedianFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   theTile = NULL;
+}
+
+void ossimMeanMedianFilter::applyFilter(ossimRefPtr<ossimImageData>& input)
+{
+   switch(input->getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         switch (theFilterType)
+         {
+            case OSSIM_MEDIAN:
+            case OSSIM_MEDIAN_FILL_NULLS:
+               applyMedian(ossim_uint8(0), input);
+               break;
+               
+            case OSSIM_MEDIAN_NULL_CENTER_ONLY:
+               applyMedianNullCenterOnly(ossim_uint8(0), input);
+               break;
+               
+            case OSSIM_MEAN:
+            case OSSIM_MEAN_FILL_NULLS:
+               applyMean(ossim_uint8(0), input);
+               break;
+
+            case OSSIM_MEAN_NULL_CENTER_ONLY:
+               applyMeanNullCenterOnly(ossim_uint8(0), input);
+               
+            default:
+               break;
+         }
+         break;
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         switch (theFilterType)
+         {
+            case OSSIM_MEDIAN:
+            case OSSIM_MEDIAN_FILL_NULLS:
+               applyMedian(ossim_uint16(0), input);
+               break;
+               
+            case OSSIM_MEDIAN_NULL_CENTER_ONLY:
+               applyMedianNullCenterOnly(ossim_uint16(0), input);
+               break;
+               
+            case OSSIM_MEAN:
+            case OSSIM_MEAN_FILL_NULLS:
+               applyMean(ossim_uint16(0), input);
+               break;
+
+            case OSSIM_MEAN_NULL_CENTER_ONLY:
+               applyMeanNullCenterOnly(ossim_uint16(0), input);
+               break;
+               
+            default:
+               break;
+         }
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         switch (theFilterType)
+         {
+            case OSSIM_MEDIAN:
+            case OSSIM_MEDIAN_FILL_NULLS:
+               applyMedian(ossim_sint16(0), input);
+               break;
+               
+            case OSSIM_MEDIAN_NULL_CENTER_ONLY:
+               applyMedianNullCenterOnly(ossim_sint16(0), input);
+               break;
+               
+            case OSSIM_MEAN:
+            case OSSIM_MEAN_FILL_NULLS:
+               applyMean(ossim_sint16(0), input);
+               break;
+
+            case OSSIM_MEAN_NULL_CENTER_ONLY:
+               applyMeanNullCenterOnly(ossim_sint16(0), input);
+               break;
+               
+            default:
+               break;
+         }
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         switch (theFilterType)
+         {
+            case OSSIM_MEDIAN:
+            case OSSIM_MEDIAN_FILL_NULLS:
+               applyMedian(ossim_uint32(0), input);
+               break;
+               
+            case OSSIM_MEDIAN_NULL_CENTER_ONLY:
+               applyMedianNullCenterOnly(ossim_uint32(0), input);
+               break;
+               
+            case OSSIM_MEAN:
+            case OSSIM_MEAN_FILL_NULLS:
+               applyMean(ossim_uint32(0), input);
+               break;
+
+            case OSSIM_MEAN_NULL_CENTER_ONLY:
+               applyMeanNullCenterOnly(ossim_uint32(0), input);
+               break;
+               
+            default:
+               break;
+         }
+      }
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         switch (theFilterType)
+         {
+            case OSSIM_MEDIAN:
+            case OSSIM_MEDIAN_FILL_NULLS:
+               applyMedian(ossim_float32(0.0), input);
+               break;
+               
+            case OSSIM_MEDIAN_NULL_CENTER_ONLY:
+               applyMedianNullCenterOnly(ossim_float32(0.0), input);
+               break;
+               
+            case OSSIM_MEAN:
+            case OSSIM_MEAN_FILL_NULLS:
+               applyMean(ossim_float32(0.0), input);
+               break;
+
+            case OSSIM_MEAN_NULL_CENTER_ONLY:
+               applyMeanNullCenterOnly(ossim_float32(0.0), input);
+               break;
+               
+            default:
+               break;
+         }
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         switch (theFilterType)
+         {
+            case OSSIM_MEDIAN:
+            case OSSIM_MEDIAN_FILL_NULLS:
+               applyMedian(ossim_float64(0.0), input);
+               break;
+               
+            case OSSIM_MEDIAN_NULL_CENTER_ONLY:
+               applyMedianNullCenterOnly(ossim_float64(0.0), input);
+               break;
+               
+            case OSSIM_MEAN:
+            case OSSIM_MEAN_FILL_NULLS:
+               applyMean(ossim_float64(0.0), input);
+               break;
+
+            case OSSIM_MEAN_NULL_CENTER_ONLY:
+               applyMeanNullCenterOnly(ossim_float64(0.0), input);
+               break;
+               
+            default:
+               break;
+         }
+         break;
+      }
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimMeanMedianFilter::applyFilter WARNING:\n"
+            << "Unhandled scalar type!" << endl;
+      }
+   }
+}
+
+template <class T>
+void ossimMeanMedianFilter::applyMean(T dummyVariable,
+                                      ossimRefPtr<ossimImageData>& inputData)
+{
+   ossim_uint32 halfWindow = (theWindowSize >> 1);
+   ossim_uint32 bandIdx = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+   ossim_uint32 kernelX   = 0;
+   ossim_uint32 kernelY   = 0;
+   ossim_uint32 kernelIdx = 0;
+   ossim_uint32 iw  = inputData->getWidth();
+   ossim_uint32 ow  = theTile->getWidth();
+   ossim_uint32 oh = theTile->getHeight();
+   ossim_uint32 numberOfBands = ossimMin(theTile->getNumberOfBands(),
+                                         inputData->getNumberOfBands());
+   ossimDataObjectStatus status = inputData->getDataObjectStatus();
+   std::vector<double> values(theWindowSize*theWindowSize);
+
+   if(status == OSSIM_FULL)
+   {
+      for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+      {
+         T* inputBuf     = (T*)inputData->getBuf(bandIdx);
+         T* outputBuf    = (T*)theTile->getBuf(bandIdx);
+
+         if(inputBuf&&outputBuf)
+         {
+            for(y = 0; y < oh; ++y)
+            {
+               for(x = 0; x < ow; ++x)
+               {
+                  kernelIdx = 0;
+                  for(kernelY = 0; kernelY < theWindowSize; ++kernelY)
+                  {
+                     for(kernelX = 0; kernelX < theWindowSize;++kernelX)
+                     {
+                        values[kernelIdx] = *(inputBuf+kernelX + kernelY*iw);
+                        ++kernelIdx;
+                     }
+                  }
+
+
+                  if(values.size() > 0)
+                  {
+                     double sum = std::accumulate(values.begin(),
+                                                  values.end(),
+                                                  0.0);
+                     double average = sum/(double)values.size();
+                     (*outputBuf) = (T)average;
+                  }
+                  ++inputBuf;
+                  ++outputBuf;
+               }
+
+               inputBuf+=(halfWindow<<1);
+            }
+         }
+      }
+   }
+   else
+   {
+      for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+      {
+         T* inputBuf     = (T*)inputData->getBuf(bandIdx);
+         T* outputBuf    = (T*)theTile->getBuf(bandIdx);
+         T np            = (T)inputData->getNullPix(bandIdx);
+         if(inputBuf&&outputBuf)
+         {
+            for(y = 0; y < oh; ++y)
+            {
+               for(x = 0; x < ow; ++x)
+               {
+                  values.clear();
+                  for(kernelY = 0; kernelY < theWindowSize; ++kernelY)
+                  {
+                     for(kernelX = 0; kernelX < theWindowSize;++kernelX)
+                     {
+                        T tempValue = *(inputBuf+kernelX + kernelY*iw);
+
+                        if(tempValue != np)
+                        {
+                           values.push_back((double)tempValue);
+                        }
+                     }
+                  }
+
+
+                  if(values.size() > 0)
+                  {
+                     double accumulate = std::accumulate(values.begin(),
+                                                         values.end(),
+                                                         0.0);
+                     double average = accumulate/(double)values.size();
+                     if(*(inputBuf+halfWindow + halfWindow*iw) == np)
+                     {
+                        if(theEnableFillNullFlag)
+                        {
+                           (*outputBuf) = (T)average;
+                        }
+                        else
+                        {
+                           (*outputBuf) = np;
+                        }
+                     }
+                     else
+                     {
+                        (*outputBuf) = (T)average;
+                     }
+                  }
+                  else
+                  {
+                     *outputBuf = np;
+                  }
+                  ++inputBuf;
+                  ++outputBuf;
+               }
+
+               inputBuf+=(halfWindow<<1);
+            }
+         }
+      }
+   }
+}
+
+template <class T> void ossimMeanMedianFilter::applyMeanNullCenterOnly(
+   T dummyVariable,
+   ossimRefPtr<ossimImageData>& inputData)
+{
+   ossim_uint32 halfWindow = (theWindowSize >> 1);
+   ossim_uint32 bandIdx = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+   ossim_uint32 kernelX   = 0;
+   ossim_uint32 kernelY   = 0;
+   ossim_uint32 iw  = inputData->getWidth();
+   ossim_uint32 ow  = theTile->getWidth();
+   ossim_uint32 oh = theTile->getHeight();
+   ossim_uint32 numberOfBands = ossimMin(theTile->getNumberOfBands(),
+                                         inputData->getNumberOfBands());
+   ossimDataObjectStatus status = inputData->getDataObjectStatus();
+   std::vector<double> values;
+
+   if(status == OSSIM_FULL)
+   {
+      // Nothing to do just copy the tile.
+      theTile->loadTile(inputData.get());
+   }
+   else
+   {
+      // Partial tile with nulls in it.
+      for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+      {
+         T* inputBuf     = (T*)inputData->getBuf(bandIdx);
+         T* outputBuf    = (T*)theTile->getBuf(bandIdx);
+         if (!inputBuf || !outputBuf)
+         {
+            return; // Shouldn't happen...
+         }
+         
+         const T NP = (T)inputData->getNullPix(bandIdx);
+
+         for(y = 0; y < oh; ++y)
+         {
+            for(x = 0; x < ow; ++x)
+            {
+               // Get the center input pixel.
+               const T CP = *(inputBuf+halfWindow + halfWindow*iw);
+               if (CP == NP)
+               {
+                  values.clear();
+                  for(kernelY = 0; kernelY < theWindowSize; ++kernelY)
+                  {
+                     for(kernelX = 0; kernelX < theWindowSize;++kernelX)
+                     {
+                        T tempValue = *(inputBuf+kernelX + kernelY*iw);
+                        
+                        if(tempValue != NP)
+                        {
+                           values.push_back((double)tempValue);
+                        }
+                     }
+                  }
+                  
+                  if(values.size() > 0)
+                  {
+                     double accumulate = std::accumulate(values.begin(),
+                                                         values.end(),
+                                                         0.0);
+                     double average = accumulate/(double)values.size();
+                     (*outputBuf) = (T)average;
+                  }
+                  else
+                  {
+                     (*outputBuf) = NP;
+                  }
+                  
+               }
+               else // Center pixel (CP) not null.
+               {
+                  (*outputBuf) = CP;
+               }
+               
+               // Move over...
+               ++inputBuf;
+               ++outputBuf;
+               
+            } // End of loop in x direction.
+
+            // Move down...
+            inputBuf+=(halfWindow<<1);
+            
+         }  // End of loop in y direction.
+         
+      }  // End of band loop.
+      
+   }  // End of else "partial tile" block.
+}
+
+template <class T>
+void ossimMeanMedianFilter::applyMedian(T dummyVariable,
+                                        ossimRefPtr<ossimImageData>& inputData)
+{
+   ossim_uint32 halfWindow = (theWindowSize >> 1);
+   ossim_uint32 bandIdx = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+   ossim_uint32 kernelX   = 0;
+   ossim_uint32 kernelY   = 0;
+   ossim_uint32 kernelIdx = 0;
+   ossim_uint32 iw  = inputData->getWidth();
+   ossim_uint32 ow  = theTile->getWidth();
+   ossim_uint32 oh = theTile->getHeight();
+   ossim_uint32 numberOfBands = ossimMin(theTile->getNumberOfBands(),
+                                         inputData->getNumberOfBands());
+   ossimDataObjectStatus status = inputData->getDataObjectStatus();
+   std::vector<T> values(theWindowSize*theWindowSize);
+
+   if(status == OSSIM_FULL)
+   {
+      for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+      {
+         T* inputBuf     = (T*)inputData->getBuf(bandIdx);
+         T* outputBuf    = (T*)theTile->getBuf(bandIdx);
+
+         if(inputBuf&&outputBuf)
+         {
+            for(y = 0; y < oh; ++y)
+            {
+               for(x = 0; x < ow; ++x)
+               {
+                  kernelIdx = 0;
+                  for(kernelY = 0; kernelY < theWindowSize; ++kernelY)
+                  {
+                     for(kernelX = 0; kernelX < theWindowSize;++kernelX)
+                     {
+                        values[kernelIdx] = *(inputBuf+kernelX + kernelY*iw);
+                        ++kernelIdx;
+                     }
+                  }
+
+                  std::sort(values.begin(),
+                            values.end());
+
+                  if(values.size() > 0)
+                  {
+                     (*outputBuf) = values[values.size()>>1];
+                  }
+                  ++inputBuf;
+                  ++outputBuf;
+               }
+
+               inputBuf+=(halfWindow<<1);
+            }
+         }
+      }
+   }
+   else
+   {
+      for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+      {
+         T* inputBuf     = (T*)inputData->getBuf(bandIdx);
+         T* outputBuf    = (T*)theTile->getBuf(bandIdx);
+         T np            = (T)inputData->getNullPix(bandIdx);
+         if(inputBuf&&outputBuf)
+         {
+            for(y = 0; y < oh; ++y)
+            {
+               for(x = 0; x < ow; ++x)
+               {
+                  values.clear();
+                  for(kernelY = 0; kernelY < theWindowSize; ++kernelY)
+                  {
+                     for(kernelX = 0; kernelX < theWindowSize;++kernelX)
+                     {
+                        T tempValue = *(inputBuf+kernelX + kernelY*iw);
+
+                        if(tempValue != np)
+                        {
+                           values.push_back(tempValue);
+                        }
+                     }
+                  }
+
+                  std::sort(values.begin(),
+                            values.end());
+
+                  if(values.size() > 0)
+                  {
+                     if(*(inputBuf+halfWindow + halfWindow*iw) == np)
+                     {
+                        if(theEnableFillNullFlag)
+                        {
+                           (*outputBuf) = values[values.size()>>1];
+                        }
+                        else
+                        {
+                           (*outputBuf) = np;
+                        }
+                     }
+                     else
+                     {
+                        (*outputBuf) = values[values.size()>>1];
+                     }
+                  }
+                  else
+                  {
+                     *outputBuf = np;
+                  }
+                  ++inputBuf;
+                  ++outputBuf;
+               }
+
+               inputBuf+=(halfWindow<<1);
+            }
+         }
+      }
+   }
+}
+
+template <class T> void ossimMeanMedianFilter::applyMedianNullCenterOnly (
+   T dummyVariable,
+   ossimRefPtr<ossimImageData>& inputData)
+{
+   ossim_uint32 halfWindow = (theWindowSize >> 1);
+   ossim_uint32 bandIdx = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+   ossim_uint32 kernelX   = 0;
+   ossim_uint32 kernelY   = 0;
+   ossim_uint32 iw  = inputData->getWidth();
+   ossim_uint32 ow  = theTile->getWidth();
+   ossim_uint32 oh = theTile->getHeight();
+   ossim_uint32 numberOfBands = ossimMin(theTile->getNumberOfBands(),
+                                         inputData->getNumberOfBands());
+   ossimDataObjectStatus status = inputData->getDataObjectStatus();
+   std::vector<T> values;
+
+   if(status == OSSIM_FULL)
+   {
+      // Nothing to do just copy the tile.
+      theTile->loadTile(inputData.get());
+   }
+   else
+   {
+       // Partial tile with nulls in it.
+      for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+      {
+         T* inputBuf     = (T*)inputData->getBuf(bandIdx);
+         T* outputBuf    = (T*)theTile->getBuf(bandIdx);
+         if (!inputBuf || !outputBuf)
+         {
+            return; // Shouldn't happen...
+         }
+         
+         const T NP = (T)inputData->getNullPix(bandIdx);
+
+         for(y = 0; y < oh; ++y)
+         {
+            for(x = 0; x < ow; ++x)
+            {
+               // Get the center input pixel.
+               const T CP = *(inputBuf+halfWindow + halfWindow*iw);
+               if (CP == NP)
+               {
+                  values.clear();
+                  for(kernelY = 0; kernelY < theWindowSize; ++kernelY)
+                  {
+                     for(kernelX = 0; kernelX < theWindowSize;++kernelX)
+                     {
+                        T tempValue = *(inputBuf+kernelX + kernelY*iw);
+                        
+                        if(tempValue != NP)
+                        {
+                           values.push_back(tempValue);
+                        }
+                     }
+                  }
+
+                  std::sort(values.begin(),
+                            values.end());
+                  
+                  if(values.size() > 0)
+                  {
+                     (*outputBuf) = values[values.size()>>1];
+                  }
+                  else
+                  {
+                     (*outputBuf) = NP;
+                  }
+               }
+               else // Center pixel (CP) not null.
+               {
+                  (*outputBuf) = CP;
+               }
+
+               // Move over...
+               ++inputBuf;
+               ++outputBuf;
+               
+            }  // End of loop in x direction.
+
+            // Move down...
+            inputBuf+=(halfWindow<<1);
+            
+         }  // End of loop in y direction.
+         
+      }  // End of band loop.
+      
+   }  // End of else "partial tile" block.
+}
+
+void ossimMeanMedianFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property.valid())
+   {
+      return;
+   }
+
+   ossimString name = property->getName();
+
+   if (name == WINDOW_SIZE_KW)
+   {
+      theWindowSize = property->valueToString().toUInt32();
+   }
+   else if (name == FILTER_TYPE_KW)
+   {
+      ossimString value = property->valueToString();
+      setFilterType(value);
+   }
+   else if (name == AUTO_GROW_KW)
+   {
+      ossimString value;
+      property->valueToString(value);
+      setAutoGrowRectFlag(value.toBool());
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimMeanMedianFilter::getProperty(const ossimString& name)const
+{
+   if (name == WINDOW_SIZE_KW)
+   {
+      ossimProperty* prop =
+         new ossimNumericProperty(WINDOW_SIZE_KW,
+                                  ossimString::toString(theWindowSize),
+                                  3,
+                                  25);
+      prop->setCacheRefreshBit();
+
+      return prop;
+   }
+   else if (name == FILTER_TYPE_KW)
+   {
+      std::vector<ossimString> constraintList;
+      getFilterTypeList(constraintList);
+      ossimString value = getFilterTypeString();
+      ossimProperty* prop = new ossimStringProperty(FILTER_TYPE_KW,
+                                                    value,
+                                                    false,
+                                                    constraintList);
+      prop->setCacheRefreshBit();
+      
+      return prop;
+   }
+   else if (name == AUTO_GROW_KW)
+   {
+      ossimRefPtr<ossimProperty> p = new ossimBooleanProperty(
+         AUTO_GROW_KW, getAutoGrowRectFlag());
+      p->setFullRefreshBit();
+      return p;
+   }
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimMeanMedianFilter::getPropertyNames(
+   std::vector<ossimString>& propertyNames)const
+{
+   propertyNames.push_back(WINDOW_SIZE_KW);
+   propertyNames.push_back(FILTER_TYPE_KW);
+   propertyNames.push_back(AUTO_GROW_KW);
+
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+}
+
+bool ossimMeanMedianFilter::saveState(ossimKeywordlist& kwl,
+                                      const char* prefix)const
+{
+   kwl.add(prefix,
+           WINDOW_SIZE_KW.c_str(),
+           theWindowSize,
+           true);
+   kwl.add(prefix,
+           FILTER_TYPE_KW.c_str(),
+           getFilterTypeString(),
+           true);
+   kwl.add(prefix,
+           AUTO_GROW_KW.c_str(),
+           (theAutoGrowRectFlag?"true":"false"),
+           true);   
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimMeanMedianFilter::loadState(const ossimKeywordlist& kwl,
+                                      const char* prefix)
+{
+   const char* lookup = NULL;
+   
+   lookup = kwl.find(prefix, WINDOW_SIZE_KW.c_str());
+   if(lookup)
+   {
+      theWindowSize = ossimString(lookup).toUInt32();
+   }
+   
+   lookup = kwl.find(prefix, FILTER_TYPE_KW.c_str());
+   if(lookup)
+   {
+      ossimString type = lookup;
+      setFilterType(type);
+   }
+
+   lookup = kwl.find(prefix, AUTO_GROW_KW.c_str());
+   if(lookup)
+   {
+      ossimString flag = lookup;
+      setAutoGrowRectFlag(flag.toBool());
+   }
+
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+void ossimMeanMedianFilter::setFilterType(ossimMeanMedianFilterType type)
+{
+   theFilterType = type;
+}
+
+void ossimMeanMedianFilter::setFilterType(const ossimString& type)
+{
+   ossimString s = type;
+   s.downcase();
+
+   std::vector<ossimString> list;
+   getFilterTypeList(list);
+   
+   for (ossim_uint32 i = 0; i < list.size(); ++i)
+   {
+      if (s == list[i])
+      {
+         theFilterType = static_cast<ossimMeanMedianFilterType>(i);
+      }
+   }
+
+   if ( (theFilterType == OSSIM_MEDIAN_FILL_NULLS) ||
+        (theFilterType == OSSIM_MEAN_FILL_NULLS) )
+   {
+      theEnableFillNullFlag = true;
+   }
+   else
+   {
+      theEnableFillNullFlag = false;
+   }
+}
+
+void ossimMeanMedianFilter::setAutoGrowRectFlag(bool flag)
+{
+   theAutoGrowRectFlag = flag;
+}
+
+bool ossimMeanMedianFilter::getAutoGrowRectFlag() const
+{
+   return theAutoGrowRectFlag;
+}
+
+ossimString ossimMeanMedianFilter::getFilterTypeString() const
+{
+   std::vector<ossimString> list;
+   getFilterTypeList(list);
+   return list[theFilterType];
+}
+
+void ossimMeanMedianFilter::getFilterTypeList(
+   std::vector<ossimString>& list) const
+{
+   list.resize(OSSIM_MEAN_NULL_CENTER_ONLY+1);
+
+   list[0] = ossimString("median");
+   list[1] = ossimString("median_fill_nulls");
+   list[2] = ossimString("median_null_center_only");
+   list[3] = ossimString("mean");
+   list[4] = ossimString("mean_fill_nulls");
+   list[5] = ossimString("mean_null_center_only");
+}
+
+ossimIrect ossimMeanMedianFilter::getBoundingRect(ossim_uint32 resLevel)const
+{
+   // Get the input rectangle.
+   ossimIrect rect = ossimImageSourceFilter::getBoundingRect(resLevel);
+   if (!theAutoGrowRectFlag || rect.hasNans())
+   {
+      return rect; // Not in autogrow mode or no input connection yet...
+   }
+
+   if ( (theFilterType == OSSIM_MEDIAN_FILL_NULLS)       ||
+        (theFilterType == OSSIM_MEDIAN_NULL_CENTER_ONLY) ||
+        (theFilterType == OSSIM_MEAN_FILL_NULLS)         ||
+        (theFilterType == OSSIM_MEAN_NULL_CENTER_ONLY) )
+   {
+      ossimIpt pt = rect.ul();
+      const ossim_int32 HW = (theWindowSize >> 1); // half window size.
+
+      // Adjust the upper left.
+      pt.x = pt.x-HW;
+      pt.y = pt.y-HW;
+      rect.set_ul(pt);
+
+      // Adjust the lower right.
+      pt = rect.lr();
+      pt.x = pt.x+HW;
+      pt.y = pt.y+HW;
+      rect.set_lr(pt);
+   }
+
+   return rect;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/reconstruction/ossimMeanMedianFilter.h b/Utilities/OSSIM/ossim_core/imaging/reconstruction/ossimMeanMedianFilter.h
new file mode 100644
index 0000000000..cdf007f467
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/reconstruction/ossimMeanMedianFilter.h
@@ -0,0 +1,129 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimMeanMedianFilter.h,v 1.7 2005/04/26 19:37:08 dburken Exp $
+#ifndef ossimMeanMedianFilter_HEADER
+#define ossimMeanMedianFilter_HEADER
+
+#include "imaging/tile_sources/ossimImageSourceFilter.h"
+
+/*!
+ * class ossimMeanMedianFilter
+ *
+ * Allows you to change between a median or mean filter.  You can
+ * also specify a window size which the median or mean is computed and
+ * the center pixel is replaced.
+ *
+ */
+class ossimMeanMedianFilter : public ossimImageSourceFilter
+{
+public:
+
+   enum ossimMeanMedianFilterType
+   {
+      /** Applies filter to any non-null center pixel. */
+      OSSIM_MEDIAN                  = 0,
+
+      /** Applies filter to all pixels including null center pixels. */
+      OSSIM_MEDIAN_FILL_NULLS       = 1,
+
+      /** Applies filter to only null center pixels. */
+      OSSIM_MEDIAN_NULL_CENTER_ONLY = 2,
+
+      /** Applies filter to any non-null center pixel. */
+      OSSIM_MEAN                    = 3,
+
+      /* Applies filter to all pixels including null center pixels. */
+      OSSIM_MEAN_FILL_NULLS         = 4,
+
+      /** Applies filter to only null center pixels. */
+      OSSIM_MEAN_NULL_CENTER_ONLY   = 5
+   };
+
+   ossimMeanMedianFilter(ossimObject* owner=NULL);
+   virtual ~ossimMeanMedianFilter();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+   virtual void initialize();
+
+   void setWindowSize(ossim_uint32 windowSize);
+   ossim_uint32 getWindowSize()const;
+
+   /**
+    * @param flag Set "theAutoGrowRectFlag".  This only affects filter types
+    * that set nulls.  Will have a growing affect on the edges.
+    */
+   void setAutoGrowRectFlag(bool flag);
+   bool getAutoGrowRectFlag() const;
+
+   void setFilterType(ossimMeanMedianFilterType type);
+   void setFilterType(const ossimString& type);
+   ossimString getFilterTypeString() const;
+   void getFilterTypeList(std::vector<ossimString>& list) const;
+   
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * @return Returns the bounding rectangle which is the input bounding
+    * rectangle with any expansion (from autogrow) added in.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+
+protected:
+   
+   ossimRefPtr<ossimImageData> theTile;
+   ossimMeanMedianFilterType   theFilterType;
+   ossim_uint32                theWindowSize;
+
+   /** Used by applyMean and applyMedian for "fill null" modes. */
+   bool theEnableFillNullFlag;
+
+   /**
+    * If true rectangle is expanded by half filter in each direction if the
+    * theFilterType fills nulls.
+    */
+   bool theAutoGrowRectFlag;
+
+   void applyFilter(ossimRefPtr<ossimImageData>& input);
+
+   template <class T>
+      void applyMean(T dummyVariable,
+                     ossimRefPtr<ossimImageData>& inputData);
+   template <class T>
+      void applyMeanNullCenterOnly(T dummyVariable,
+                                   ossimRefPtr<ossimImageData>& inputData);
+
+   template <class T>
+      void applyMedian(T dummyVariable,
+                       ossimRefPtr<ossimImageData>& inputData);
+   template <class T>
+      void applyMedianNullCenterOnly(T dummyVariable,
+                                     ossimRefPtr<ossimImageData>& inputData);
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/remap_tables/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/remap_tables/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/remap_tables/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedRemapTable.cpp b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedRemapTable.cpp
new file mode 100644
index 0000000000..6a83789e09
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedRemapTable.cpp
@@ -0,0 +1,29 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+// Description:
+//
+// Contains class definition for NormalizedRemapTable.
+//*******************************************************************
+//  $Id: ossimNormalizedRemapTable.cpp,v 1.2 2001/10/11 15:39:42 dburken Exp $
+
+#include "ossimNormalizedRemapTable.h"
+
+ossimNormalizedRemapTable::ossimNormalizedRemapTable()
+{}
diff --git a/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedRemapTable.h b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedRemapTable.h
new file mode 100644
index 0000000000..9cb76452dd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedRemapTable.h
@@ -0,0 +1,68 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for  NormalizedRemapTable.  Table for
+// normalizing unsigned 8 bit data.
+//*******************************************************************
+//  $Id: ossimNormalizedRemapTable.h,v 1.3 2003/05/13 11:31:06 dburken Exp $
+
+
+#ifndef ossimNormalizedRemapTable_HEADER
+#define ossimNormalizedRemapTable_HEADER
+
+#include "base/common/ossimConstants.h"
+
+//*******************************************************************
+// CLASS:  ossimNormalizedRemapTable
+//*******************************************************************
+class ossimNormalizedRemapTable
+{
+public:
+   ossimNormalizedRemapTable();
+
+   virtual ~ossimNormalizedRemapTable(){}
+
+   /*!
+    *  Returns a normalized value (between '0.0' and '1.0') from
+    *  a pixel value.
+    */
+   virtual ossim_float64 normFromPix(ossim_int32 pix) const = 0; 
+
+   /*!
+    *  Returns an pixel value as an int from a normalized value.
+    */
+   virtual ossim_int32 pixFromNorm(ossim_float64 normPix) const = 0;
+
+   /*!
+    *  Returns a normalized value (between '0.0' and '1.0') from a
+    *  pixel value.
+    */
+   virtual ossim_float64 operator[](ossim_int32 pix) const = 0;
+   
+private:
+   // Forbid copy constructor and asignment operator.
+   ossimNormalizedRemapTable(const ossimNormalizedRemapTable& source);
+   ossimNormalizedRemapTable& operator=(const ossimNormalizedRemapTable&);  
+
+ };
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU11RemapTable.cpp b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU11RemapTable.cpp
new file mode 100644
index 0000000000..2aabe883bc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU11RemapTable.cpp
@@ -0,0 +1,45 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+// Description:
+//
+// Contains class definition for ossimNormalizedU11RemapTable.
+//*******************************************************************
+//  $Id: ossimNormalizedU11RemapTable.cpp,v 1.3 2003/05/13 11:31:06 dburken Exp $
+
+#include "ossimNormalizedU11RemapTable.h"
+
+double ossimNormalizedU11RemapTable::theTable[TABLE_ENTRIES];
+bool   ossimNormalizedU11RemapTable::theTableIsInitialized = false;
+
+ossimNormalizedU11RemapTable::ossimNormalizedU11RemapTable()
+{
+   if (!theTableIsInitialized)
+   {
+      //***
+      // Initialize the remap table.
+      //***
+      for (ossim_int32 i = 0; i < TABLE_ENTRIES; i++)
+      {
+         ossim_float64 tmp = i;
+         theTable[i] = tmp / 2047.0;
+      }
+      theTableIsInitialized = true;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU11RemapTable.h b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU11RemapTable.h
new file mode 100644
index 0000000000..0aacd3ae17
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU11RemapTable.h
@@ -0,0 +1,102 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for  ossimNormalizedU11RemapTable.  Table for
+// normalizing unsigned 11 bit data.
+//
+//*******************************************************************
+//  $Id: ossimNormalizedU11RemapTable.h,v 1.3 2003/05/13 11:31:06 dburken Exp $
+
+#ifndef ossimNormalizedU11RemapTable_HEADER
+#define ossimNormalizedU11RemapTable_HEADER
+
+#include "ossimNormalizedRemapTable.h"
+
+class ossimNormalizedU11RemapTable : public ossimNormalizedRemapTable
+{
+public:
+   ossimNormalizedU11RemapTable();
+
+   virtual ~ossimNormalizedU11RemapTable(){}
+
+   enum
+   {
+      TABLE_ENTRIES = 2048
+   };
+   
+   virtual ossim_float64 normFromPix(ossim_int32 pix) const;
+      //> Returns a normalized value (between '0.0' and '1.0') from an eight
+      //  bit unsigned char.
+      //<
+   
+   virtual ossim_int32 pixFromNorm(ossim_float64 normPix) const;
+      //> Returns a pixel value from a normalized value.
+      //  Notes:
+      //  - Valid returns range from '0' to '255' so given a
+      //    value greater than '1.0' method returns '255' and given a
+      //    value less than '0.0' method returns '0.0'.
+      //<
+
+   virtual ossim_float64 operator[](ossim_int32 pix) const;
+      //> Returns a normalized value (between '0.0' and '1.0') from an eight
+      //  bit unsigned char.
+      //<
+   
+private:
+   // Forbid copy constructor and asignment operator.
+   ossimNormalizedU11RemapTable(const ossimNormalizedU11RemapTable& source){}
+   ossimNormalizedU11RemapTable&
+   operator=(const ossimNormalizedU11RemapTable&);  
+
+   static ossim_float64  theTable[TABLE_ENTRIES];
+   static bool theTableIsInitialized;
+};
+
+inline ossim_float64 ossimNormalizedU11RemapTable::operator[](ossim_int32 pix) const
+{
+   return (pix < TABLE_ENTRIES ? (pix > 0 ? theTable[pix] : 0.0) : 1.0);  
+}
+
+inline ossim_float64 ossimNormalizedU11RemapTable::normFromPix(ossim_int32 pix) const
+{
+   return (pix < TABLE_ENTRIES ? (pix > 0 ? theTable[pix] : 0.0) : 1.0);
+}
+
+inline ossim_int32 ossimNormalizedU11RemapTable::pixFromNorm(ossim_float64 normPix) const
+{
+   // un-normalize...
+   ossim_float64 p = normPix * 2047.0;
+
+   // Ensure pixel is between 0 and 2047.
+   p = p < 2047.0 ? (p > 0.0 ? p : 0.0) : 2047.0;
+
+   //***
+   // If p is between greater than zero and less than one, make it one as it
+   // wasn't a null before.
+   // Add 0.5 to p otherwise as it will be cast to an int for proper rounding.
+   //***
+   p = p > 1.0 ? (p+0.5) : ( !p ? 0.0 : 1.0);
+       
+   return static_cast<ossim_int32>(p);
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU16RemapTable.cpp b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU16RemapTable.cpp
new file mode 100644
index 0000000000..4c05d55e41
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU16RemapTable.cpp
@@ -0,0 +1,45 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+// Description:
+//
+// Contains class definition for ossimNormalizedU16RemapTable.
+//*******************************************************************
+//  $Id: ossimNormalizedU16RemapTable.cpp,v 1.3 2003/05/13 11:31:06 dburken Exp $
+
+#include "ossimNormalizedU16RemapTable.h"
+
+double ossimNormalizedU16RemapTable::theTable[TABLE_ENTRIES];
+bool   ossimNormalizedU16RemapTable::theTableIsInitialized = false;
+
+ossimNormalizedU16RemapTable::ossimNormalizedU16RemapTable()
+{
+   if (!theTableIsInitialized)
+   {
+      //***
+      // Initialize the remap table.
+      //***
+      for (ossim_int32 i = 0; i < TABLE_ENTRIES; i++)
+      {
+         ossim_float64 tmp = i;
+         theTable[i] = tmp / 65535.0;
+      }
+      theTableIsInitialized = true;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU16RemapTable.h b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU16RemapTable.h
new file mode 100644
index 0000000000..b165b1e9b5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU16RemapTable.h
@@ -0,0 +1,101 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for  ossimNormalizedU16RemapTable.  Table for
+// normalizing unsigned 16 bit data.
+//*******************************************************************
+//  $Id: ossimNormalizedU16RemapTable.h,v 1.3 2003/05/13 11:31:06 dburken Exp $
+
+#ifndef ossimNormalizedU16RemapTable_HEADER
+#define ossimNormalizedU16RemapTable_HEADER
+
+#include "ossimNormalizedRemapTable.h"
+
+class ossimNormalizedU16RemapTable : public ossimNormalizedRemapTable
+{
+public:
+   ossimNormalizedU16RemapTable();
+
+   virtual ~ossimNormalizedU16RemapTable(){}
+
+   enum
+   {
+      TABLE_ENTRIES   = 65536
+   };
+   
+   virtual ossim_float64 normFromPix(ossim_int32 pix) const;
+      //> Returns a normalized value (between '0.0' and '1.0') from an eight
+      //  bit unsigned char.
+      //<
+   
+   virtual ossim_int32 pixFromNorm(ossim_float64 normPix) const;
+      //> Returns a pixel value from a normalized value.
+      //  Notes:
+      //  - Valid returns range from '0' to '255' so given a
+      //    value greater than '1.0' method returns '255' and given a
+      //    value less than '0.0' method returns '0.0'.
+      //<
+
+   virtual ossim_float64 operator[](ossim_int32 pix) const;
+      //> Returns a normalized value (between '0.0' and '1.0') from an eight
+      //  bit unsigned char.
+      //<
+   
+private:
+   // Forbid copy constructor and asignment operator.
+   ossimNormalizedU16RemapTable(const ossimNormalizedU16RemapTable& source){}
+   ossimNormalizedU16RemapTable&
+   operator=(const ossimNormalizedU16RemapTable&);  
+
+   static ossim_float64  theTable[TABLE_ENTRIES];
+   static bool theTableIsInitialized;
+};
+
+inline ossim_float64 ossimNormalizedU16RemapTable::operator[](ossim_int32 pix) const
+{
+   return (pix < TABLE_ENTRIES ? (pix > 0 ? theTable[pix] : 0.0) : 1.0);  
+}
+
+inline ossim_float64 ossimNormalizedU16RemapTable::normFromPix(ossim_int32 pix) const
+{
+   return (pix < TABLE_ENTRIES ? (pix > 0 ? theTable[pix] : 0.0) : 1.0);
+}
+
+inline ossim_int32 ossimNormalizedU16RemapTable::pixFromNorm(ossim_float64 normPix) const
+{
+   // un-normalize...
+   ossim_float64 p = normPix * 65535.0;
+
+   // Ensure pixel is between 0 and 65535.
+   p = p < 65535.0 ? (p > 0.0 ? p : 0.0) : 65535.0;
+
+   //***
+   // If p is between greater than zero and less than one, make it one as it
+   // wasn't a null before.
+   // Add 0.5 to p otherwise as it will be cast to an int for proper rounding.
+   //***
+   p = p > 1.0 ? (p+0.5) : ( !p ? 0.0 : 1.0);
+       
+   return static_cast<ossim_int32>(p);
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU8RemapTable.cpp b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU8RemapTable.cpp
new file mode 100644
index 0000000000..3f05bb8318
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU8RemapTable.cpp
@@ -0,0 +1,45 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+// Description:
+//
+// Contains class definition for ossimNormalizedU8RemapTable.
+//*******************************************************************
+//  $Id: ossimNormalizedU8RemapTable.cpp,v 1.3 2003/05/13 11:31:06 dburken Exp $
+
+#include "ossimNormalizedU8RemapTable.h"
+
+double ossimNormalizedU8RemapTable::theTable[TABLE_ENTRIES];
+bool   ossimNormalizedU8RemapTable::theTableIsInitialized = false;
+
+ossimNormalizedU8RemapTable::ossimNormalizedU8RemapTable()
+{
+   if (!theTableIsInitialized)
+   {
+      //***
+      // Initialize the remap table.
+      //***
+      for (ossim_int32 i = 0; i < TABLE_ENTRIES; i++)
+      {
+         ossim_float64 tmp = i;
+         theTable[i] = tmp / 255.0;
+      }
+      theTableIsInitialized = true;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU8RemapTable.h b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU8RemapTable.h
new file mode 100644
index 0000000000..982e4d8359
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/remap_tables/ossimNormalizedU8RemapTable.h
@@ -0,0 +1,104 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Contains class declaration for  ossimNormalizedU8RemapTable.  Table for
+// normalizing unsigned 8 bit data.
+//*******************************************************************
+//  $Id: ossimNormalizedU8RemapTable.h,v 1.3 2003/05/13 11:31:06 dburken Exp $
+
+#ifndef ossimNormalizedU8RemapTable_HEADER
+#define ossimNormalizedU8RemapTable_HEADER
+
+#include "ossimNormalizedRemapTable.h"
+
+//*******************************************************************
+// CLASS:  ossimNormalizedU8RemapTable
+//*******************************************************************
+class ossimNormalizedU8RemapTable : public ossimNormalizedRemapTable
+{
+public:
+   ossimNormalizedU8RemapTable();
+
+   virtual ~ossimNormalizedU8RemapTable(){}
+
+   enum
+   {
+      TABLE_ENTRIES   = 256,
+      MAX_TABLE_INDEX = 255
+   };
+   
+   virtual ossim_float64 normFromPix(ossim_int32 pix) const;
+      //> Returns a normalized value (between '0.0' and '1.0') from an eight
+      //  bit unsigned char.
+      //<
+   
+   virtual ossim_int32 pixFromNorm(ossim_float64 normPix) const;
+      //> Returns a pixel value from a normalized value.
+      //  Notes:
+      //  - Valid returns range from '0' to '255' so given a
+      //    value greater than '1.0' method returns '255' and given a
+      //    value less than '0.0' method returns '0.0'.
+      //<
+
+   virtual ossim_float64 operator[](ossim_int32 pix) const;
+      //> Returns a normalized value (between '0.0' and '1.0') from an eight
+      //  bit unsigned char.
+      //<
+   
+private:
+   // Forbid copy constructor and asignment operator.
+   ossimNormalizedU8RemapTable(const ossimNormalizedU8RemapTable& source);
+   ossimNormalizedU8RemapTable& operator=(const ossimNormalizedU8RemapTable&);  
+
+   static ossim_float64  theTable[TABLE_ENTRIES];
+   static bool theTableIsInitialized;
+};
+
+inline ossim_float64 ossimNormalizedU8RemapTable::operator[](ossim_int32 pix) const
+{
+   return (pix < TABLE_ENTRIES ? (pix > 0 ? theTable[pix] : 0.0) : 1.0);  
+}
+
+inline ossim_float64 ossimNormalizedU8RemapTable::normFromPix(ossim_int32 pix) const
+{
+   return (pix < TABLE_ENTRIES ? (pix > 0 ? theTable[pix] : 0.0) : 1.0);
+}
+
+inline ossim_int32 ossimNormalizedU8RemapTable::pixFromNorm(ossim_float64 normPix) const
+{
+   // un-normalize...
+   ossim_float64 p = normPix * 255.0;
+
+   // Ensure pixel is between 0 and 255.
+   p = p < 255.0 ? (p > 0.0 ? p : 0.0) : 255.0;
+
+   //***
+   // If p is between greater than zero and less than one, make it one as it
+   // wasn't a null before.
+   // Add 0.5 to p otherwise as it will be cast to an int for proper rounding.
+   //***
+   p = p > 1.0 ? (p+0.5) : ( !p ? 0.0 : 1.0);
+       
+   return static_cast<ossim_int32>(p);
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/resample/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/resample/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/resample/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/resample/ossimFilterResampler.cpp b/Utilities/OSSIM/ossim_core/imaging/resample/ossimFilterResampler.cpp
new file mode 100644
index 0000000000..7c62e37b64
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/resample/ossimFilterResampler.cpp
@@ -0,0 +1,921 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+
+// Contributor:
+//         David A. Horner (DAH) http://dave.thehorners.com
+//
+//*************************************************************************
+// $Id: ossimFilterResampler.cpp,v 1.43 2006/01/11 13:37:26 gpotts Exp $
+
+#include <imaging/resample/ossimFilterResampler.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimPreferences.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDrect.h>
+#include <imaging/filters/ossimFilterTable.h>
+ossimFilterResampler::ossimFilterResampler()
+   :theMinifyFilter(new ossimNearestNeighborFilter()),
+    theMagnifyFilter(new ossimNearestNeighborFilter()),
+    theMinifyFilterType(ossimFilterResampler_NEAREST_NEIGHBOR),
+    theMagnifyFilterType(ossimFilterResampler_NEAREST_NEIGHBOR),
+    theScaleFactor(1.0, 1.0),
+    theInverseScaleFactor(1.0, 1.0),
+    theBlurFactor(1.0)
+{
+   setScaleFactor(ossimDpt(1.0, 1.0));
+   loadState(ossimPreferences::instance()->preferencesKWL(),"resampler.");
+
+}
+
+ossimFilterResampler::~ossimFilterResampler()
+{
+   if(theMinifyFilter)
+   {
+      delete theMinifyFilter;
+      theMinifyFilter = NULL;
+   }
+   if(theMagnifyFilter)
+   {
+      delete theMagnifyFilter;
+      theMagnifyFilter = NULL;
+   }
+}
+
+
+void ossimFilterResampler::resample(const ossimRefPtr<ossimImageData>& input,
+				    ossimRefPtr<ossimImageData>& output,
+				    const ossimDpt& ul,
+				    const ossimDpt& ur,
+				    const ossimDpt& deltaUl,
+				    const ossimDpt& deltaUr,
+				    const ossimDpt& length)
+{
+   resample(input,
+            output,
+            output->getImageRectangle(),
+            ul,
+            ur,
+            deltaUl,
+            deltaUr,
+            length);
+}
+
+void ossimFilterResampler::resample(const ossimRefPtr<ossimImageData>& input,
+				    ossimRefPtr<ossimImageData>& output,
+				    const ossimIrect& outputSubRect,
+				    const ossimDpt& ul,
+				    const ossimDpt& ur,
+				    const ossimDpt& deltaUl,
+				    const ossimDpt& deltaUr,
+				    const ossimDpt& length)
+{
+   if(!input.valid()   ||
+      !output.valid()  ||
+      !input->getBuf() ||
+      !output->getBuf())
+   {
+      return;
+   }
+   
+   ossimScalarType scalarType = input->getScalarType();
+   switch(scalarType)
+   {
+      case OSSIM_UINT8:
+      {
+         resampleBilinearTile(ossim_uint8(0), // dummy template variable
+			      input,
+			      output,
+			      outputSubRect,
+			      ul,
+			      ur,
+			      deltaUl,
+			      deltaUr,
+			      length);
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         resampleBilinearTile(ossim_sint8(0), // dummy template variable
+			      input,
+			      output,
+			      outputSubRect,
+			      ul,
+			      ur,
+			      deltaUl,
+			      deltaUr,
+			      length);
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+	 resampleBilinearTile(ossim_uint16(0), // dummy template variable
+			      input,
+			      output,
+			      outputSubRect,
+			      ul,
+			      ur,
+			      deltaUl,
+			      deltaUr,
+			      length);
+	 break;
+      }
+      case OSSIM_SINT16:
+      {
+	 resampleBilinearTile(ossim_sint16(0), // dummy template variable
+			      input,
+			      output,
+			      outputSubRect,
+			      ul,
+			      ur,
+			      deltaUl,
+			      deltaUr,
+			      length);
+	 break;
+      }      
+      case OSSIM_UINT32:
+      {
+	 resampleBilinearTile(ossim_uint32(0), // dummy template variable
+			      input,
+			      output,
+			      outputSubRect,
+			      ul,
+			      ur,
+			      deltaUl,
+			      deltaUr,
+			      length);
+	 break;
+      }      
+      case OSSIM_SINT32:
+      {
+	 resampleBilinearTile(ossim_sint32(0), // dummy template variable
+			      input,
+			      output,
+			      outputSubRect,
+			      ul,
+			      ur,
+			      deltaUl,
+			      deltaUr,
+			      length);
+	 break;
+      }      
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+	 resampleBilinearTile(ossim_float32(0.0), // dummy template variable
+			      input,
+			      output,
+			      outputSubRect,
+			      ul,
+               ur,
+			      deltaUl,
+			      deltaUr,
+			      length);
+	 break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+	 resampleBilinearTile(ossim_float64(0.0), // dummy template variable
+			      input,
+			      output,
+			      outputSubRect,
+			      ul,
+			      ur,
+			      deltaUl,
+			      deltaUr,
+			      length);
+         break;
+      }
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimFilterResampler::resample error: unknown scalar type:  "
+            << scalarType << endl;
+      }
+   }
+}
+
+
+ossimFilter* ossimFilterResampler::createNewFilter(
+   ossimFilterResamplerType filterType,
+   ossimFilterResamplerType& result)
+{
+   switch(filterType)
+   {
+      case ossimFilterResampler_NEAREST_NEIGHBOR:
+      {
+         return new ossimNearestNeighborFilter();
+      }
+      case ossimFilterResampler_BOX:
+      {
+         return new ossimBoxFilter();
+      }
+      case ossimFilterResampler_GAUSSIAN:
+      {
+         return new ossimGaussianFilter();
+      }
+      case ossimFilterResampler_CUBIC:
+      {
+         return new ossimCubicFilter();
+      }
+      case ossimFilterResampler_HANNING:
+      {
+         return new ossimHanningFilter();
+      }
+      case ossimFilterResampler_HAMMING:
+      {
+         return new ossimHammingFilter();
+      }
+      case ossimFilterResampler_LANCZOS:
+      {
+         return new ossimLanczosFilter();
+      }
+      case ossimFilterResampler_CATROM:
+      {
+         return new ossimCatromFilter();
+      }
+      case ossimFilterResampler_MITCHELL:
+      {
+         return new ossimMitchellFilter();
+      }
+      case ossimFilterResampler_BLACKMAN:
+      {
+         return new ossimBlackmanFilter();
+      }
+      case ossimFilterResampler_BLACKMAN_SINC:
+      {
+         return new ossimBlackmanSincFilter();
+      }
+      case ossimFilterResampler_BLACKMAN_BESSEL:
+      {
+         return new ossimBlackmanBesselFilter();
+      }
+      case ossimFilterResampler_QUADRATIC:
+      {
+         return new ossimQuadraticFilter();
+      }
+      case ossimFilterResampler_TRIANGLE:
+      {
+         return new ossimTriangleFilter();
+      }
+      case ossimFilterResampler_HERMITE:
+      {
+         return new ossimHermiteFilter();
+      }
+      case ossimFilterResampler_BELL:
+      {
+         return new ossimGaussianFilter();
+      }
+      case ossimFilterResampler_BSPLINE:
+      {
+         return new ossimBSplineFilter();
+      }
+   }
+
+   result = ossimFilterResampler_NEAREST_NEIGHBOR;
+   return new ossimNearestNeighborFilter();
+}
+
+void ossimFilterResampler::setScaleFactor(const ossimDpt& scale)
+{
+   theScaleFactor = scale;
+   if(fabs(theScaleFactor.x) <= FLT_EPSILON)
+   {
+      theScaleFactor.x = 1.0;
+   }
+   if(fabs(theScaleFactor.y) <= FLT_EPSILON)
+   {
+      theScaleFactor.y = 1.0;
+   }
+
+   theInverseScaleFactor.x = 1.0/theScaleFactor.x;
+   theInverseScaleFactor.y = 1.0/theScaleFactor.y;
+}
+
+template <class T> void ossimFilterResampler::resampleBilinearTile(
+   T dummy,
+   const ossimRefPtr<ossimImageData>& input,
+   ossimRefPtr<ossimImageData>& output,
+   const ossimIrect& outputSubRect,
+   const ossimDpt& inputUl,
+   const ossimDpt& inputUr,
+   const ossimDpt& deltaUl,
+   const ossimDpt& deltaUr,
+   const ossimDpt& outLength)
+{
+//    std::cout << "INPUT  = \n" << *input << std::endl
+//              << "OUTPUT = \n" << *output << std::endl
+//              << "inputUL= " << inputUl << std::endl
+//              << "inputUR= " << inputUr << std::endl
+//              << "deltaUL= " << deltaUl << std::endl
+//              << "deltaUr= " << deltaUr << std::endl
+//              << "outlength= " << outLength << std::endl;
+   ossim_uint32  band,centerOffset;
+   ossim_float64 tmpFlt64,stepSizeWidth,stepSizeHeight;
+
+   if(outLength.x>1) {
+      stepSizeWidth  = 1.0/(outLength.x-1.0);
+   } else {
+      stepSizeWidth   = 1.0;
+   }
+
+   if(outLength.y>1) {
+      stepSizeHeight = 1.0/(outLength.y-1.0);   
+   } else {
+      stepSizeHeight = 1.0;
+   }
+
+   // INPUT INFORMATION
+   ossim_uint32       inWidth      = input->getWidth();
+   ossim_uint32       inBandSize   = input->getSizePerBand();  // fix for out-of-bounds check OLK 06/2005
+   ossim_uint32       BANDS        = input->getNumberOfBands();
+   ossimIrect         inputRect    = input->getImageRectangle();
+
+   // OUTPUT INFORMATION
+   const ossim_float64* NULL_PIX      = output->getNullPix(); 
+   const ossim_float64* MIN_PIX       = output->getMinPix(); 
+   const ossim_float64* MAX_PIX       = output->getMaxPix(); 
+   ossimIrect           outputRect    = output->getImageRectangle();
+   ossim_uint32         resultRectH   = outputSubRect.height();
+   ossim_uint32         resultRectW   = outputSubRect.width();
+   ossim_uint32         outputRectW   = outputRect.width();
+
+   // calculate the offset into the data so we can refer to it at 0 index.
+   ossim_uint32 resultOffset=(outputSubRect.ul().y - outputRect.ul().y)*outputRectW +
+                             (outputSubRect.ul().x - outputRect.ul().x);
+
+   // make a local copy of the band pointers (at resultOffset)
+   ossim_float64 *densityvals=new ossim_float64[BANDS];
+   ossim_float64 *pixelvals=new ossim_float64[BANDS];
+   const T* *inputBuf  = new const T*[BANDS];
+   T* *resultBuf = new T*[BANDS];
+   if(!pixelvals||!inputBuf||!resultBuf)
+   {
+      return;
+   }
+   
+   for(band = 0; band < BANDS; ++band)
+   {
+      inputBuf[band] = static_cast<const T*>(input->getBuf(band));
+      resultBuf[band] = static_cast<T*>(output->getBuf(band))+resultOffset;
+   }
+
+   // FILTER INFORMAION
+   ossim_uint32 xkernel_width  = theFilterTable.getWidth();;
+   ossim_uint32 ykernel_height = theFilterTable.getHeight();
+   double xkernel_half_width   = theFilterTable.getXSupport();
+   double ykernel_half_height  = theFilterTable.getYSupport();
+
+   double initialx  = inputUl.x-inputRect.ul().x;
+   double initialy  = inputUl.y-inputRect.ul().y;
+   double terminalx = inputUr.x-inputRect.ul().x;
+   double terminaly = inputUr.y-inputRect.ul().y;
+   double pointx,pointy,deltaX,deltaY;
+   ossim_int32 starty,startx; 
+
+   // USING NEAREST NEIGHBOR
+   if(xkernel_width==0 || ykernel_height==0)
+   {
+      for(ossim_uint32 resultY = 0; resultY < resultRectH; ++resultY)
+      {
+//          deltaX = (terminalx-initialx) * stepSizeWidth;
+//          deltaY = (terminaly-initialy) * stepSizeHeight;
+         // this should be stepsize width for both since we are traversing horizontal
+         deltaX = (terminalx-initialx) * stepSizeWidth;
+         deltaY = (terminaly-initialy) * stepSizeWidth;
+         pointx = initialx;
+         pointy = initialy;
+         for(ossim_uint32 resultX = 0; resultX < resultRectW; ++resultX)
+         {
+            // just sample center in input space.
+            centerOffset = irint(pointy)*inWidth + irint(pointx);
+            for(band=0;band<BANDS;++band)
+            {
+               resultBuf[band][resultX] = inputBuf[band][centerOffset];
+            }
+            pointy += deltaY;
+            pointx += deltaX;
+         } // End of loop in x direction.
+         
+         // increment pointers to where we are now.
+         for(band=0;band<BANDS;++band)
+         {
+            resultBuf[band] += outputRectW;
+         }
+         initialx += deltaUl.x;
+         initialy += deltaUl.y;
+         terminalx  += deltaUr.x;
+         terminaly  += deltaUr.y;
+      } // End of loop in y direction.
+      
+   // USING A KERNEL
+   }
+   else
+   {
+      const double* kernel;
+      ossim_uint32 iy,ix,sourceIndex,nullCount;
+      for(ossim_uint32 resultY = 0; resultY < resultRectH; ++resultY)
+      {
+         deltaX = (terminalx-initialx) * stepSizeWidth;
+         deltaY = (terminaly-initialy) * stepSizeWidth;
+         pointx = initialx;
+         pointy = initialy;
+         for(ossim_uint32 resultX = 0; resultX < resultRectW; ++resultX)
+         {
+            starty  = irint(pointy - ykernel_half_height + .5);
+            startx  = irint(pointx - xkernel_half_width + .5);
+            centerOffset = (ossim_uint32)((starty+ykernel_half_height)*inWidth +
+                                          (startx+xkernel_half_width));
+            sourceIndex = starty*inWidth+startx;
+
+            // look at center pixel, make sure they aren't all null.
+            nullCount=0;
+            if(centerOffset<inBandSize)
+            {
+               for (band=0;band<BANDS;++band)
+               {
+                  if(inputBuf[band][centerOffset]==static_cast<T>(NULL_PIX[band]))
+                  {
+                     ++nullCount;
+                  }
+               }
+               // the center of the kernel is outside the input space, just set null.
+            }
+            else
+            {
+               nullCount=BANDS;
+            }
+
+            // make sure we have non-null data and we fit within the inputBuf.
+            if ( nullCount==BANDS || (sourceIndex>=inBandSize))
+            {
+               // we don't need to continue, just assign null!
+               for (band=0;band<BANDS;++band)
+               {
+                  resultBuf[band][resultX] = static_cast<T>(NULL_PIX[band]);
+               }
+            }
+            else
+            {  
+               kernel = theFilterTable.getClosestWeights(pointx,pointy);
+               if(kernel)
+               {
+                  // reset the pixel/density sums for each band to zero.
+                  memset(densityvals,'\0',sizeof(ossim_float64)*BANDS);
+                  memset(pixelvals,'\0',sizeof(ossim_float64)*BANDS);
+
+                  // apply kernel to input space.
+                  for (iy=0;((iy<ykernel_height)&&(sourceIndex<inBandSize));++iy)
+                  {
+                     for (ix = 0;((ix<xkernel_width)&&(sourceIndex<inBandSize));++ix)
+                     {
+                        tmpFlt64=*kernel; // pixel weight;
+                        for(band=0;band<BANDS;++band)
+                        {
+                           if(inputBuf[band][sourceIndex]!=NULL_PIX[band])
+                           {
+                              densityvals[band] += tmpFlt64;
+                              pixelvals[band] += (inputBuf[band][sourceIndex]*tmpFlt64);
+                           }
+                        }
+                        ++sourceIndex;
+                        ++kernel;
+                        if(sourceIndex>=inBandSize)
+                        {
+                           break;
+                        }
+                     }
+                     sourceIndex+=(inWidth-xkernel_width);
+                  }
+
+                  // actually assign the value to the output
+                  for (band = 0; band < BANDS; ++band)
+                  {
+                     if(densityvals[band]<=FLT_EPSILON)
+                     {
+                        tmpFlt64 = pixelvals[band];
+                     }
+                     else
+                     {
+                        // normalize
+                        tmpFlt64 = pixelvals[band]/densityvals[band];
+                     }
+                     // clamp
+                     tmpFlt64 = (tmpFlt64>=MIN_PIX[band]?(tmpFlt64<MAX_PIX[band]?tmpFlt64:MAX_PIX[band]):MIN_PIX[band]); 
+                     // set resultant pixel value.
+                     resultBuf[band][resultX] = static_cast<T>(tmpFlt64);
+                  }
+
+                  // we didn't get a filter kernel, just set NULL in this disaster.
+               }
+               else
+               {
+                  for (band=0;band<BANDS;++band)
+                  {
+                     resultBuf[band][resultX] = static_cast<T>(NULL_PIX[band]);
+                  }
+               }                  
+            }
+            pointy += deltaY;
+            pointx += deltaX;
+         } // End of loop in x direction.
+
+         // increment pointers to where we are now.
+         for(band=0;band<BANDS;++band)
+         {
+            resultBuf[band] += outputRectW;
+         }
+         initialx += deltaUl.x;
+         initialy += deltaUl.y;
+         terminalx  += deltaUr.x;
+         terminaly  += deltaUr.y;
+      } // End of loop in y direction.
+   } // USING A KERNEL END
+
+   delete [] densityvals;
+   delete [] pixelvals;
+   delete [] resultBuf;
+   delete [] inputBuf;
+}
+
+ossimString ossimFilterResampler::getFilterTypeAsString(ossimFilterResamplerType type)const
+{
+   switch(type)
+   {
+      case ossimFilterResampler_NEAREST_NEIGHBOR:
+      {
+         return "nearest neighbor";
+      }
+      case ossimFilterResampler_BOX:
+      {
+         return "box";
+      }
+      case ossimFilterResampler_GAUSSIAN:
+      {
+         return "gaussian";
+      }
+      case ossimFilterResampler_CUBIC:
+      {
+         return "cubic";
+      }
+      case ossimFilterResampler_HANNING:
+      {
+         return "hanning";
+      }
+      case ossimFilterResampler_HAMMING:
+      {
+         return "hamming";
+      }
+      case ossimFilterResampler_LANCZOS:
+      {
+         return "lanczos";
+      }
+      case ossimFilterResampler_MITCHELL:
+      {
+         return "mitchell";
+      }
+      case ossimFilterResampler_CATROM:
+      {
+         return "catrom";
+      }
+      case ossimFilterResampler_BLACKMAN:
+      {
+         return "blackman";
+      }
+      case ossimFilterResampler_BLACKMAN_SINC:
+      {
+         return "sinc";
+      }
+      case ossimFilterResampler_BLACKMAN_BESSEL:
+      {
+         return "bessel";
+      }
+      case ossimFilterResampler_QUADRATIC:
+      {
+         return "quadratic";
+      }
+      case ossimFilterResampler_TRIANGLE:
+      {
+         return "bilinear";
+      }
+      case ossimFilterResampler_HERMITE:
+      {
+         return "hermite";
+      }
+      case ossimFilterResampler_BELL:
+      {
+         return "gaussian";
+      }
+      case ossimFilterResampler_BSPLINE:
+      {
+         return "bspline";
+      }
+   }
+
+   return "nearest neighbor";
+}
+
+void ossimFilterResampler::getFilterTypes(std::vector<ossimString>& filterTypes)const
+{
+  filterTypes.push_back("nearest neighbor");
+  filterTypes.push_back("bilinear");
+  filterTypes.push_back("cubic");
+//  filterTypes.push_back("bell");
+  filterTypes.push_back("bessel");
+  filterTypes.push_back("blackman");
+  filterTypes.push_back("box");
+  filterTypes.push_back("bspline");
+  filterTypes.push_back("catrom");
+  filterTypes.push_back("gaussian");
+  filterTypes.push_back("hanning");
+  filterTypes.push_back("hamming");
+  filterTypes.push_back("hermite");
+  filterTypes.push_back("lanczos");
+  filterTypes.push_back("mitchell");
+  filterTypes.push_back("quadratic");
+  filterTypes.push_back("sinc");
+}
+
+
+ossimFilterResampler::ossimFilterResamplerType ossimFilterResampler::getFilterType(const ossimString& type)const
+{
+   ossimString typeUpper = type;
+   typeUpper = typeUpper.upcase();
+
+   if(typeUpper.contains("BOX"))
+   {
+      return ossimFilterResampler_BOX;
+   }
+   else if(typeUpper.contains("NEAREST"))
+   {
+      return ossimFilterResampler_NEAREST_NEIGHBOR;
+   }
+   else if(typeUpper.contains("GAUSSIAN"))
+   {
+      return ossimFilterResampler_GAUSSIAN;
+   }
+   else if(typeUpper.contains("HANNING"))
+   {
+      return ossimFilterResampler_HANNING;
+   }
+   else if(typeUpper.contains("HAMMING"))
+   {
+      return ossimFilterResampler_HAMMING;
+   }
+   else if(typeUpper.contains("LANCZOS"))
+   {
+      return ossimFilterResampler_LANCZOS;
+   }
+   else if(typeUpper.contains("MITCHELL"))
+   {
+      return ossimFilterResampler_MITCHELL;
+   }
+   else if(typeUpper.contains("CATROM"))
+   {
+      return ossimFilterResampler_CATROM;
+   }
+   else if(typeUpper.contains("CUBIC"))
+   {
+      return ossimFilterResampler_CUBIC;
+   }
+   else if(typeUpper.contains("BESSEL"))
+   {
+      return ossimFilterResampler_BLACKMAN_BESSEL;
+   }
+   else if(typeUpper.contains("SINC"))
+   {
+      return ossimFilterResampler_BLACKMAN_SINC;
+   }
+   else if(typeUpper.contains("BLACKMAN"))
+   {
+      return ossimFilterResampler_BLACKMAN;
+   }
+   else if(typeUpper.contains("QUADRATIC"))
+   {
+      return ossimFilterResampler_QUADRATIC;
+   }
+   else if(typeUpper.contains("TRIANGLE"))
+   {
+      return ossimFilterResampler_TRIANGLE;
+   }
+   else if(typeUpper.contains("BILINEAR"))
+   {
+      return ossimFilterResampler_TRIANGLE;
+   }
+   else if(typeUpper.contains("HERMITE"))
+   {
+      return ossimFilterResampler_HERMITE;
+   }
+//    else if(typeUpper.contains("BELL"))
+//    {
+//       return ossimFilterResampler_BELL;
+//    }
+   else if(typeUpper.contains("BSPLINE"))
+   {
+      return ossimFilterResampler_BSPLINE;
+   }
+   
+   return ossimFilterResampler_NEAREST_NEIGHBOR;
+}
+
+void ossimFilterResampler::getKernelSupport(double& x, double& y)const
+{
+   const ossimFilter* horizontalFilter = getHorizontalFilter();
+   const ossimFilter* verticalFilter   = getVerticalFilter();
+
+   if(!horizontalFilter)
+   {
+      x = 0.0;
+   }
+   else
+   {
+//       x = theBlurFactor*ossimMax(1.0/theScaleFactor.x, 1.0)*
+//           horizontalFilter->getSupport();
+      x = horizontalFilter->getSupport();
+   }
+
+   if(!verticalFilter)
+   {
+      y = 0.0;
+   }
+   else
+   {
+//       y = theBlurFactor*ossimMax(1.0/theScaleFactor.y, 1.0)*
+//           verticalFilter->getSupport();
+      y = verticalFilter->getSupport();
+   }
+}
+
+const ossimFilter* ossimFilterResampler::getHorizontalFilter()const
+{
+   if(theScaleFactor.x < 1)
+   {
+      return theMinifyFilter;
+   }
+
+   return theMagnifyFilter;
+}
+
+const ossimFilter* ossimFilterResampler::getVerticalFilter()const
+{
+   if(theScaleFactor.y < 1)
+   {
+      return theMinifyFilter;
+   }
+
+   return theMagnifyFilter;
+}
+
+void ossimFilterResampler::setFilterType(const ossimString& type)
+{
+   setFilterType(type, type);
+}
+
+void ossimFilterResampler::setFilterType(ossimFilterResamplerType filterType)
+{
+   setFilterType(filterType, filterType);
+}
+void ossimFilterResampler::setFilterType(const ossimString& minifyType,
+                                         const ossimString& magnifyType)
+{
+   setFilterType(getFilterType(minifyType),
+                 getFilterType(magnifyType));
+}
+
+void ossimFilterResampler::setMinifyFilterType(const ossimString& minifyType)
+{
+   setMinifyFilterType(getFilterType(minifyType));
+}
+
+void ossimFilterResampler::setMagnifyFilterType(const ossimString& magnifyType)
+{
+   setMagnifyFilterType(getFilterType(magnifyType));
+}
+
+void ossimFilterResampler::setMinifyFilterType(ossimFilterResamplerType filterType)
+{
+   setFilterType(filterType,
+                 theMagnifyFilterType);
+}
+
+void ossimFilterResampler::setMagnifyFilterType(ossimFilterResamplerType filterType)
+{
+   setFilterType(theMinifyFilterType,filterType);
+}
+
+ossimString ossimFilterResampler::getMinifyFilterTypeAsString()const
+{
+   return getFilterTypeAsString(theMinifyFilterType);
+}
+
+ossimString ossimFilterResampler::getMagnifyFilterTypeAsString()const
+{
+   return getFilterTypeAsString(theMagnifyFilterType);
+}
+
+void ossimFilterResampler::setFilterType(
+   ossimFilterResamplerType minifyFilterType,
+   ossimFilterResamplerType magnifyFilterType)
+{
+   if(theMinifyFilter)
+   {
+      delete theMinifyFilter;
+      theMinifyFilter = NULL;
+   }
+   if(theMagnifyFilter)
+   {
+      delete theMagnifyFilter;
+      theMagnifyFilter = NULL;
+   }
+   
+   theMinifyFilterType  = minifyFilterType;
+   theMagnifyFilterType = magnifyFilterType;
+   
+   theMinifyFilter  = createNewFilter(minifyFilterType, theMinifyFilterType);
+   theMagnifyFilter = createNewFilter(magnifyFilterType, theMagnifyFilterType);
+   computeTable();
+}
+
+ossim_float64 ossimFilterResampler::getBlurFactor()const
+{
+   return theBlurFactor;
+}
+
+void ossimFilterResampler::setBlurFactor(ossim_float64 blur)
+{
+   theBlurFactor = blur;
+}
+
+bool ossimFilterResampler::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_X_KW,
+           theScaleFactor.x,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_Y_KW,
+           theScaleFactor.y,
+           true);
+   kwl.add(prefix,
+           "minify_type",
+           getFilterTypeAsString(theMinifyFilterType),
+           true);
+   kwl.add(prefix,
+           "magnify_type",
+           getFilterTypeAsString(theMagnifyFilterType),
+           true);
+
+   return true;
+}
+
+bool ossimFilterResampler::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   ossimString scalex  = kwl.find(prefix,
+                                 ossimKeywordNames::SCALE_X_KW);
+   theScaleFactor.x = scalex.toDouble();
+
+   ossimString scaley  = kwl.find(prefix,
+                                  ossimKeywordNames::SCALE_Y_KW);
+   theScaleFactor.y = scaley.toDouble();
+   
+   ossimString minify  = kwl.find(prefix,
+                                  "minify_type");
+   ossimString magnify = kwl.find(prefix,
+                                  "magnify_type");
+   
+
+   if(fabs(theScaleFactor.x) <= FLT_EPSILON)
+   {
+      theScaleFactor.x = 1.0;
+   }
+   if(fabs(theScaleFactor.y) <= FLT_EPSILON)
+   {
+      theScaleFactor.y = 1.0;
+   }
+
+   theInverseScaleFactor.x = 1.0/theScaleFactor.x;
+   theInverseScaleFactor.y = 1.0/theScaleFactor.y;
+   
+   setFilterType(getFilterType(minify),
+                 getFilterType(magnify));
+
+   return true;
+}
+
+void ossimFilterResampler::computeTable()
+{
+  theFilterTable.buildTable(32, *theMagnifyFilter);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/resample/ossimFilterResampler.h b/Utilities/OSSIM/ossim_core/imaging/resample/ossimFilterResampler.h
new file mode 100644
index 0000000000..6e3ae12c5a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/resample/ossimFilterResampler.h
@@ -0,0 +1,151 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+// Contributor:
+//         David A. Horner (DAH) http://dave.thehorners.com
+//
+//*************************************************************************
+// $Id: ossimFilterResampler.h,v 1.13 2005/09/21 14:15:59 gpotts Exp $
+#ifndef ossimFilterResampler_HEADER
+#define ossimFilterResampler_HEADER
+
+#include <vector>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimIrect.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/filters/ossimFilter.h>
+#include <imaging/filters/ossimFilterTable.h>
+
+class OSSIMDLLEXPORT ossimFilterResampler
+{
+public:
+   enum ossimFilterResamplerType
+   {
+      ossimFilterResampler_NEAREST_NEIGHBOR = 0,
+      ossimFilterResampler_BOX              = 1,
+      ossimFilterResampler_GAUSSIAN         = 2,
+      ossimFilterResampler_CUBIC            = 3,
+      ossimFilterResampler_HANNING          = 4,
+      ossimFilterResampler_HAMMING          = 5,
+      ossimFilterResampler_LANCZOS          = 6,
+      ossimFilterResampler_MITCHELL         = 7,
+      ossimFilterResampler_CATROM           = 8,
+      ossimFilterResampler_BLACKMAN         = 9,
+      ossimFilterResampler_BLACKMAN_SINC    = 10,
+      ossimFilterResampler_BLACKMAN_BESSEL  = 11,
+      ossimFilterResampler_QUADRATIC        = 12,
+      ossimFilterResampler_TRIANGLE         = 13,
+      ossimFilterResampler_HERMITE          = 14,
+      ossimFilterResampler_BELL             = 15,
+      ossimFilterResampler_BSPLINE          = 16
+      
+   };
+   ossimFilterResampler();
+   virtual ~ossimFilterResampler();
+
+  virtual void resample(const ossimRefPtr<ossimImageData>& input,
+			ossimRefPtr<ossimImageData>& output,
+			const ossimDpt& ul,
+			const ossimDpt& ur,
+			const ossimDpt& deltaUl,
+			const ossimDpt& deltaUr,
+			const ossimDpt& length);
+
+  virtual void resample(const ossimRefPtr<ossimImageData>& input,
+			ossimRefPtr<ossimImageData>& output,
+			const ossimIrect& outputSubRect,
+			const ossimDpt& ul,
+			const ossimDpt& ur,
+			const ossimDpt& deltaUl,
+			const ossimDpt& deltaUr,
+			const ossimDpt& length);
+
+  void setFilterType(ossimFilterResamplerType filterType);
+  void setFilterType(ossimFilterResamplerType minifyFilterType,
+		     ossimFilterResamplerType magnifyFilterType);
+  void setFilterType(const ossimString& type);
+  void setFilterType(const ossimString& minifyType,
+		     const ossimString& magnifyType);
+
+  void setMinifyFilterType(const ossimString& minifyType);
+  void setMagnifyFilterType(const ossimString& magnifyType);
+  void setMinifyFilterType(ossimFilterResamplerType filterType);
+  void setMagnifyFilterType(ossimFilterResamplerType filterType);
+  ossimString getMinifyFilterTypeAsString()const;
+  ossimString getMagnifyFilterTypeAsString()const;
+  void setScaleFactor(const ossimDpt& scale);
+  void setBlurFactor(ossim_float64 blur);
+
+  void setBoundingInputRect(const ossimIrect& rect)
+  {
+    theInputRect = rect;
+  }
+  ossimIrect getBoundingInputRect()const
+  {
+    return theInputRect;
+  }
+
+  ossim_float64 getBlurFactor()const;
+
+  const ossimDpt& getScaleFactor()const
+  {
+    return theScaleFactor;
+  }
+  /*!
+   * Saves the state of this object.
+   */
+  virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0)const;
+  
+  /*!
+   * Loads the state of this object.
+   */
+  virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+  
+  virtual void getKernelSupport(double& x,
+				double & y)const;
+
+  virtual void getFilterTypes(std::vector<ossimString>& filterTypes)const;
+
+private:
+  const ossimFilter* getHorizontalFilter()const;
+  const ossimFilter* getVerticalFilter()const;
+
+  template <class T>
+  void resampleBilinearTile(T dummy,
+			    const ossimRefPtr<ossimImageData>& input,
+			    ossimRefPtr<ossimImageData>& output,
+			    const ossimIrect& outputSubRect,
+			    const ossimDpt& inputUl,
+			    const ossimDpt& inputUr,
+			    const ossimDpt& deltaUl,
+			    const ossimDpt& deltaUr,
+			    const ossimDpt& outLength);
+  
+   void computeTable();
+   ossimString getFilterTypeAsString(ossimFilterResamplerType type)const;
+   ossimFilterResamplerType getFilterType(const ossimString& type)const;
+   ossimFilter* createNewFilter(ossimFilterResamplerType filterType,
+                                ossimFilterResamplerType& result);
+
+
+   ossimFilter*             theMinifyFilter;
+   ossimFilter*             theMagnifyFilter;
+   ossimFilterTable         theFilterTable;
+   
+   ossimFilterResamplerType theMinifyFilterType;
+   ossimFilterResamplerType theMagnifyFilterType;
+   ossimDpt                 theScaleFactor;
+   ossimDpt                 theInverseScaleFactor;
+   
+   ossimIrect               theInputRect;
+   ossim_float64            theBlurFactor;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/resample/ossimResampler.cpp b/Utilities/OSSIM/ossim_core/imaging/resample/ossimResampler.cpp
new file mode 100644
index 0000000000..e53582f371
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/resample/ossimResampler.cpp
@@ -0,0 +1,1259 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//
+// Description:
+//
+// Contains class definition for ossimResampler.
+// 
+//*******************************************************************
+//  $Id: ossimResampler.cpp,v 1.51 2005/06/07 19:20:22 dburken Exp $
+
+
+#include <iostream>
+using namespace std;
+#include <imaging/resample/ossimResampler.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDpt3d.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/filters/ossimFilter.h>
+#include <imaging/patch/ossimTilePatch.h>
+#include <imaging/formats/ossimImageHandler.h>
+
+RTTI_DEF1(ossimResampler, "ossimResampler", ossimConnectableObject)
+
+
+static const char* RESAMPLER_CONVOLUTION_TYPE_KW = "convolution_type";
+static const char* RESAMPLER_SCALE_X_KW          = "scale_x";
+static const char* RESAMPLER_SCALE_Y_KW          = "scale_y";
+static const char* RESAMPLER_CUBIC_PARAMETER_KW  = "cubic_parameter";
+
+ossimResampler::ossimResampler()
+   :ossimConnectableObject(NULL,0,0,true, false),
+    theOutputToInputRatio(1,1),
+    theResamplerType(ossimResampler_NONE),
+    theTableWidthX(0),
+    theTableWidthY(0),
+    theTableHeight(0),
+    theKernelWidth(0),
+    theKernelHeight(0),
+    theWeightTableX(NULL),
+    theWeightTableY(NULL),
+    theCubicAdjustableParameter(-.5)
+{
+}
+
+ossimResampler::~ossimResampler()
+{
+   deleteWeightTable();
+}
+
+void ossimResampler::resample(ossimImageData* input,
+                              ossimImageData* output)
+{
+   if(!input||
+      !output ||
+      !input->getBuf() ||
+      !output->getBuf())
+   {
+      return;
+   }
+
+   if(theWeightTableX&&theWeightTableY)
+   {
+      ossimScalarType scalarType = input->getScalarType();
+      switch(scalarType)
+      {
+         case OSSIM_UINT8:
+         {
+            resampleTile(ossim_uint8(0), // dummy template variable
+                         input,
+                         output);
+            break;
+         }
+         case OSSIM_UINT16:
+         case OSSIM_USHORT11:
+         {
+            resampleTile(ossim_uint16(0), // dummy template variable
+                         input,
+                         output);
+            break;
+         }
+         case OSSIM_SSHORT16:
+         {
+            resampleTile(ossim_sint16(0), // dummy template variable
+                         input,
+                         output);
+            break;
+         }      
+         case OSSIM_UINT32:
+         {
+            resampleTile(ossim_uint32(0), // dummy template variable
+                         input,
+                         output);
+            break;
+         }      
+         case OSSIM_FLOAT32:
+         case OSSIM_NORMALIZED_FLOAT:
+         {
+            resampleTile(ossim_float32(0.0), // dummy template variable
+                         input,
+                         output);
+            break;
+         }
+         case OSSIM_FLOAT64:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            resampleTile(ossim_float64(0.0), // dummy template variable
+                         input,
+                         output);
+            break;
+         }
+         default:
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "ossimResampler::resample error: unknown scalar type:  "
+               << scalarType
+               << endl;
+            
+         }
+      }
+   }      
+   // convolve the input and copy to output.
+}
+
+void ossimResampler::resample(ossimImageData* input,
+                              ossimImageData* output,
+                              const ossimDpt& ul,
+                              const ossimDpt& ur,
+                              const ossimDpt& deltaUl,
+                              const ossimDpt& deltaUr,
+                              const ossimDpt& length)
+{
+   resample(input,
+            output,
+            output->getImageRectangle(),
+            ul,
+            ur,
+            deltaUl,
+            deltaUr,
+            length);
+}
+
+void ossimResampler::resample(ossimImageData* input,
+                              ossimImageData* output,
+                              const ossimIrect& outputSubRect,
+                              const ossimDpt& ul,
+                              const ossimDpt& ur,
+                              const ossimDpt& deltaUl,
+                              const ossimDpt& deltaUr,
+                              const ossimDpt& length)
+{
+   if(!input||
+      !output ||
+      !input->getBuf() ||
+      !output->getBuf())
+   {
+      return;
+   }
+   
+   if(theWeightTableX&&theWeightTableY)
+   {
+      ossimScalarType scalarType = input->getScalarType();
+      switch(scalarType)
+      {
+         case OSSIM_UINT8:
+         {
+            resampleTile(ossim_uint8(0), // dummy template variable
+                         input,
+                         output,
+                         outputSubRect,
+                         ul,
+                         ur,
+                         deltaUl,
+                         deltaUr,
+                         length);
+            break;
+         }
+         case OSSIM_UINT16:
+         case OSSIM_USHORT11:
+         {
+            resampleTile(ossim_uint16(0), // dummy template variable
+                         input,
+                         output,
+                         outputSubRect,
+                         ul,
+                         ur,
+                         deltaUl,
+                         deltaUr,
+                         length);
+            break;
+         }
+         case OSSIM_SINT16:
+         {
+            resampleTile(ossim_sint16(0), // dummy template variable
+                         input,
+                         output,
+                         outputSubRect,
+                         ul,
+                         ur,
+                         deltaUl,
+                         deltaUr,
+                         length);
+            break;
+         }      
+         case OSSIM_UINT32:
+         {
+            resampleTile(ossim_uint32(0), // dummy template variable
+                         input,
+                         output,
+                         outputSubRect,
+                         ul,
+                         ur,
+                         deltaUl,
+                         deltaUr,
+                         length);
+            break;
+         }      
+         case OSSIM_FLOAT32:
+         case OSSIM_NORMALIZED_FLOAT:
+         {
+            resampleTile(ossim_float32(0.0), // dummy template variable
+                         input,
+                         output,
+                         outputSubRect,
+                         ul,
+                         ur,
+                         deltaUl,
+                         deltaUr,
+                         length);
+            break;
+         }
+         case OSSIM_FLOAT64:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            resampleTile(ossim_float64(0.0), // dummy template variable
+                         input,
+                         output,
+                         outputSubRect,
+                         ul,
+                         ur,
+                         deltaUl,
+                         deltaUr,
+                         length);
+            break;
+         }
+         default:
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "ossimResampler::resample error: unknown scalar type:  "
+               << scalarType
+               << endl;
+         }
+      }
+   }
+   
+}
+
+void ossimResampler::resampleNearestNeighbor(ossimImageData* input,
+                                             ossimImageData* output,
+                                             const ossimIrect& outputSubRect,
+                                             const ossimDpt& ul,
+                                             const ossimDpt& ur,
+                                             const ossimDpt& deltaUl,
+                                             const ossimDpt& deltaUr,
+                                             const ossimDpt& length)
+{
+   if(!input||
+      !output ||
+      !input->getBuf() ||
+      !output->getBuf())
+   {
+      return;
+   }
+   
+   ossimScalarType scalarType = input->getScalarType();
+   switch(scalarType)
+   {
+      case OSSIM_UINT8:
+      {
+         resampleTileNearestNeighbor(ossim_uint8(0),// dummy template variable
+                                     input,
+                                     output,
+                                     outputSubRect,
+                                     ul,
+                                     ur,
+                                     deltaUl,
+                                     deltaUr,
+                                     length);
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         resampleTileNearestNeighbor(ossim_uint16(0),// dummy template variable
+                                     input,
+                                     output,
+                                     outputSubRect,
+                                     ul,
+                                     ur,
+                                     deltaUl,
+                                     deltaUr,
+                                     length);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         resampleTileNearestNeighbor(ossim_sint16(0),// dummy template variable
+                                     input,
+                                     output,
+                                     outputSubRect,
+                                     ul,
+                                     ur,
+                                     deltaUl,
+                                     deltaUr,
+                                     length);
+         break;
+      }      
+      case OSSIM_UINT32:
+      {
+         resampleTileNearestNeighbor(ossim_uint32(0),// dummy template variable
+                                     input,
+                                     output,
+                                     outputSubRect,
+                                     ul,
+                                     ur,
+                                     deltaUl,
+                                     deltaUr,
+                                     length);
+         break;
+      }      
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         resampleTileNearestNeighbor(ossim_float32(0.0),
+                                     input,
+                                     output,
+                                     outputSubRect,
+                                     ul,
+                                     ur,
+                                     deltaUl,
+                                     deltaUr,
+                                     length);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         resampleTileNearestNeighbor(ossim_float64(0.0),
+                                     input,
+                                     output,
+                                     outputSubRect,
+                                     ul,
+                                     ur,
+                                     deltaUl,
+                                     deltaUr,
+                                     length);
+         break;
+      }
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimResampler::resample error: unknown scalar type:  "
+            << scalarType
+            << endl;
+      }
+   }   
+}
+
+void ossimResampler::resampleNearestNeighbor(ossimImageData* input,
+                                             ossimImageData* output,
+                                             const ossimDpt& ul,
+                                             const ossimDpt& ur,
+                                             const ossimDpt& deltaUl,
+                                             const ossimDpt& deltaUr,
+                                             const ossimDpt& length)
+{
+   resampleNearestNeighbor(input,
+                           output,
+                           output->getImageRectangle(),
+                           ul,
+                           ur,
+                           deltaUl,
+                           deltaUr,
+                           length);
+}
+
+
+template <class T>
+void ossimResampler::resampleTile(T,// not used
+                                  ossimImageData* input,
+                                  ossimImageData* output)
+{
+   switch(input->getDataObjectStatus())
+   {
+      case OSSIM_FULL:
+      {
+         resampleFullTile((T)0, input, output);
+         break;
+      }
+      case OSSIM_PARTIAL:
+      {      
+         resamplePartialTile((T)0, input, output);
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+}
+
+template <class T>
+void ossimResampler::resamplePartialTile(T,// not used
+                                         ossimImageData* input,
+                                         ossimImageData* output)
+{   
+   ossim_int32 maxInputSize  = std::max(input->getWidth(),  input->getHeight());
+   ossim_int32 maxOutputSize = std::max(output->getWidth(), output->getHeight());
+   ossim_int32 k;
+   double *h  = new double[maxInputSize];
+   int    *Lx = new int[maxOutputSize];
+   int    *Ly = new int[maxOutputSize];
+   ossim_int32 out_height = output->getHeight();
+   ossim_int32 out_width  = output->getWidth();
+   ossim_int32 in_width   = input->getWidth();
+   ossim_int32 in_height  = input->getHeight();
+   ossim_int32 j;
+   ossim_int32 l;
+
+   ossimIpt origin=output->getOrigin();
+   ossimIpt scaledOriginShift(input->getOrigin()*-1);
+
+   ossim_int32 evenKernelW = (ossim_int32)(!(theKernelWidth%2));
+   ossim_int32 evenKernelH = (ossim_int32)(!(theKernelHeight%2));
+   ossim_int32 kernelHorizontalShift = (ossim_int32)(-theKernelWidth/2.0+evenKernelW);
+   ossim_int32 kernelVerticalShift   = (ossim_int32)(-theKernelHeight/2.0+evenKernelH);
+   
+   for (k = 0; k < maxOutputSize; k++)
+   {
+      Lx[k] = (ossim_int32)(scaledOriginShift.x+((k+origin.x)/
+                                           theOutputToInputRatio.x));
+   }
+   for (k = 0; k < maxOutputSize; k++)
+   {
+      Ly[k] = (ossim_int32)(scaledOriginShift.y+((k+origin.y)/
+                                           theOutputToInputRatio.y));
+   }
+   for(ossim_int32 band = 0; band < (ossim_int32)input->getNumberOfBands();++band)
+   {
+      const T* inputBuf  = static_cast<T*>(input->getBuf(band));
+      T*       outputBuf = static_cast<T*>(output->getBuf(band));
+      T        minPix    = static_cast<T>(input->getMinPix(band));
+      T        maxPix    = static_cast<T>(input->getMaxPix(band));
+      T        np        = static_cast<T>(input->getNullPix(band));
+      
+      for (k = 0; k < out_height; k++)
+      {
+         ossim_int32 indexMod = (ossim_int32)fmod((k+origin.y), theOutputToInputRatio.y);
+         if(indexMod >= theTableWidthY) indexMod = theTableWidthY - 1;
+         if(indexMod <0) indexMod = 0;
+         for (j = 0; j < in_width; j++)
+         {
+            h[j] = 0.0;
+            ossim_int32 count = 0;
+            double lastValue = OSSIM_DBL_NAN;
+            for (l = 0; l < theKernelHeight; l++)
+            {
+               ossim_int32 index = Ly[k] + l + kernelVerticalShift;
+               if ((index >= 0) && (index < in_height))
+               {
+                  ossim_int32 offset = index*in_width +j;
+                  if(!input->isNull(offset))
+                  {
+                     lastValue = (double)inputBuf[offset];
+                     h[j] += lastValue *
+                             theWeightTableY[theKernelHeight - l-1][indexMod];
+                     ++count;
+                  }
+                  // I think instead of skipping to next value I'll just assume 0
+                  
+                  // this was code to skip to next non-null value and use it
+                  // 
+//                   else
+//                   {
+//                      for(ossim_int32 templ = l; templ < theKernelHeight; ++templ)
+//                      {
+//                         index = Ly[k] + templ + kernelVerticalShift;
+//                         offset = index*in_width +j;
+//                         if(!input->isNull(offset))
+//                         {
+//                            lastValue = (double)inputBuf[offset];
+//                            break;
+//                         }
+//                      }
+//                      if(lastValue != OSSIM_DBL_NAN)
+//                      {
+//                         h[j] += lastValue *
+//                                 theWeightTableY[theKernelHeight - l-1][indexMod];
+                        
+//                         ++count;
+//                      }
+//                      else
+//                      {
+//                         break;
+//                      }
+//                   }
+               }
+            }
+            if(!count)
+            {
+               h[j] = OSSIM_DBL_NAN;
+            }
+         }
+         for (ossim_int32 m = 0; m < out_width; m++)
+         {
+            double x = 0.0;
+            ossim_int32 indexMod = (ossim_int32)fmod((m+origin.x), theOutputToInputRatio.x);
+            if(indexMod >= theTableWidthX) indexMod = theTableWidthX-1;
+            if(indexMod <0) indexMod = 0;
+            
+            if(input->isNull(ossimIpt(Lx[m]-scaledOriginShift.x, Ly[k]-scaledOriginShift.y)))
+            {
+               outputBuf[k*out_width +m] = np;
+            }
+            else
+            {
+               double lastValue = OSSIM_DBL_NAN;
+               for (l = 0; l < theKernelWidth; l++)
+               {
+                  ossim_int32 index = Lx[m] + l + kernelHorizontalShift;
+                  if ((index >= 0) && (index < in_width))
+                  {
+                     if(h[index] != OSSIM_DBL_NAN)
+                     {
+                        lastValue = h[index];
+                        x += h[index] * theWeightTableX[theKernelWidth - l-1][indexMod];
+                     }
+
+                     // I am commenting out the code that searches for the next
+                     // non null value with the kernel range.  This will have the
+                     // same effect as multiplying by 0.0 for the NULL value.
+                     //
+//                      else
+//                      {
+//                         for(ossim_int32 templ = l; templ < l; ++templ)
+//                         {
+//                            ossim_int32 index = Lx[m] + templ + kernelHorizontalShift;
+//                            if(h[index] != OSSIM_DBL_NAN)
+//                            {
+//                               lastValue = h[index];
+//                               break;
+//                            }
+//                         }
+//                         if(lastValue != OSSIM_DBL_NAN)
+//                         {
+//                            x += lastValue * theWeightTableX[theKernelWidth - l-1][indexMod];
+//                         }
+//                      }
+                  }
+               }
+               if (x < minPix)
+               {
+                  outputBuf[k*out_width +m] = static_cast<T>(minPix);
+               }
+               else if (x > maxPix)
+               {
+                  outputBuf[k*out_width +m] = static_cast<T>(maxPix);
+               }
+               else
+               {
+                  outputBuf[k*out_width +m] = static_cast<T>(x);
+               }
+            }
+         }
+      }
+   }
+   
+   delete [] h;
+   delete [] Lx;   
+   delete [] Ly;
+}
+
+template <class T>
+void ossimResampler::resampleFullTile(T,// not used
+                                      ossimImageData* input,
+                                      ossimImageData* output)
+{
+   ossim_int32 maxInputSize  = std::max(input->getWidth(),  input->getHeight());
+   ossim_int32 maxOutputSize = std::max(output->getWidth(), output->getHeight());
+   ossim_int32 k;
+   double *h     = new double[maxInputSize];
+   ossim_int32 *Lx        = new ossim_int32[maxOutputSize];
+   ossim_int32 *Ly        = new ossim_int32[maxOutputSize];
+   ossim_int32 out_height = output->getHeight();
+   ossim_int32 out_width  = output->getWidth();
+   ossim_int32 in_width   = input->getWidth();
+   ossim_int32 in_height  = input->getHeight();
+   ossim_int32 j;
+   ossim_int32 l;
+   
+   ossimIpt origin=output->getOrigin();
+   ossimIpt scaledOriginShift(input->getOrigin()*-1);
+
+   ossim_int32 evenKernelW = (ossim_int32)(!(theKernelWidth%2));
+   ossim_int32 evenKernelH = (ossim_int32)(!(theKernelHeight%2));
+   ossim_int32 kernelHorizontalShift = (ossim_int32)(-theKernelWidth/2.0+evenKernelW);
+   ossim_int32 kernelVerticalShift   = (ossim_int32)(-theKernelHeight/2.0+evenKernelH);
+   
+   for (k = 0; k < maxOutputSize; k++)
+   {
+      Lx[k] = (ossim_int32)(scaledOriginShift.x+((k+origin.x)/
+                                           theOutputToInputRatio.x));
+   }
+   for (k = 0; k < maxOutputSize; k++)
+   {
+      Ly[k] = (ossim_int32)(scaledOriginShift.y+((k+origin.y)/
+                                           theOutputToInputRatio.y));
+   }
+   for(ossim_int32 band = 0; band < (ossim_int32)input->getNumberOfBands();++band)
+   {
+      const T* inputBuf  = (const T*)(input->getBuf(band));
+      T*       outputBuf = (T*)(output->getBuf(band));
+      double  minPix    = static_cast<T>(input->getMinPix()[band]);
+      double  maxPix    = static_cast<T>(input->getMaxPix()[band]);
+      
+      for (k = 0; k < out_height; k++)
+      {
+         int indexMod = (int)fmod((k+origin.y), theOutputToInputRatio.y);
+         if(indexMod >= theTableWidthY) indexMod = theTableWidthY - 1;
+         if(indexMod <0) indexMod = 0;
+         for (j = 0; j < in_width; j++)
+         {
+            h[j] = 0.0;
+            for (l = 0; l < theKernelHeight; l++)
+            {
+               ossim_int32 index = Ly[k] + l + kernelVerticalShift;
+               if ((index >= 0) && (index < in_height))
+               {
+                  h[j] += ((double)inputBuf[index*in_width +j]) *
+                          theWeightTableY[theKernelHeight - l-1][indexMod];
+               }
+            }
+         }
+         for (ossim_int32 m = 0; m < out_width; m++)
+         {
+            double x = 0.0;
+            int indexMod = (int)fmod((m+origin.x), theOutputToInputRatio.x);
+            if(indexMod >= theTableWidthX) indexMod = theTableWidthX-1;
+            if(indexMod <0) indexMod = 0;
+            
+            for (l = 0; l < theKernelWidth; l++)
+            {
+               ossim_int32 index = Lx[m] + l + kernelHorizontalShift;
+               if ((index >= 0) && (index < in_width))
+               {
+         
+                  x += h[index] * theWeightTableX[theKernelWidth - l-1][indexMod];
+               }
+            }
+            if (x < minPix)
+            {
+               outputBuf[k*out_width +m] = static_cast<T>(minPix);
+            }
+            else if (x > maxPix)
+            {
+               outputBuf[k*out_width +m] = static_cast<T>(maxPix);
+            }
+            else
+            {
+               outputBuf[k*out_width +m] = static_cast<T>(x);
+            }
+         }
+      }
+   }
+   
+   delete [] h;
+   delete [] Lx;   
+   delete [] Ly;
+}
+
+
+
+template <class T>
+void ossimResampler::resampleTile(T,// not used
+                                  ossimImageData* input,
+                                  ossimImageData* output,
+                                  const ossimIrect& outputSubRect,
+                                  const ossimDpt& inputUl,
+                                  const ossimDpt& inputUr,
+                                  const ossimDpt& deltaUl,
+                                  const ossimDpt& deltaUr,
+                                  const ossimDpt& outLength)
+{
+   ossimImageData* dupIn = input;
+   ossimDpt origin = input->getOrigin();
+   ossimDpt newInputUl = inputUl;
+   ossimDpt newInputUr = inputUr;
+   ossimDpt newDeltaUl = deltaUl;
+   ossimDpt newDeltaUr = deltaUr;
+
+   if(theResamplerType != ossimResampler_NEAREST_NEIGHBOR)
+   {
+      newInputUl = ossimDpt(inputUl.x * theOutputToInputRatio.x,
+                            inputUl.y * theOutputToInputRatio.y);
+      newInputUr = ossimDpt(inputUr.x * theOutputToInputRatio.x,
+                            inputUr.y * theOutputToInputRatio.y);
+      newDeltaUl = ossimDpt(deltaUl.x * theOutputToInputRatio.x,
+                            deltaUl.y * theOutputToInputRatio.y);
+      newDeltaUr = ossimDpt(deltaUr.x * theOutputToInputRatio.x,
+                            deltaUr.y * theOutputToInputRatio.y);
+
+      ossimDpt newLl = newInputUl + newDeltaUl*outLength.y;
+      ossimDpt newLr = newInputUr + newDeltaUr*outLength.y;
+      
+      ossimDrect newBoundingRect(newInputUl,
+                                 newInputUr,
+                                 newLl,
+                                 newLr);
+      
+
+      newBoundingRect = ossimDrect(newBoundingRect.ul() - ossimDpt(theKernelWidth, theKernelHeight),
+                                   newBoundingRect.lr() + ossimDpt(theKernelWidth, theKernelHeight));
+      ossimIrect roundedRect = newBoundingRect;
+      origin = roundedRect.ul();
+
+      dupIn = new ossimImageData(NULL,
+                                 input->getScalarType(),
+                                 input->getNumberOfBands(),
+                                 roundedRect.width(),
+                                 roundedRect.height());
+      dupIn->setOrigin(roundedRect.ul());
+      dupIn->initialize();
+      resampleTile(static_cast<T>(0), input, dupIn);
+   }
+   long    inWidth        = dupIn->getWidth();
+   long    inHeight       = dupIn->getHeight();
+   double  stepSizeWidth  = 1.0/outLength.x;
+   double  stepSizeHeight = 1.0/outLength.y;   
+   ossimIrect rect = dupIn->getImageRectangle();
+   
+   ossimDpt startSave(newInputUl.x - rect.ul().x,
+                      newInputUl.y - rect.ul().y );
+   ossimDpt endSave(newInputUr.x - rect.ul().x,
+                    newInputUr.y - rect.ul().y);
+
+   ossimIrect outputRect = output->getImageRectangle();
+   ossimIpt subRectUl = outputSubRect.ul();
+   long     subRectH  = outputSubRect.height();
+   long     subRectW  = outputSubRect.width();
+   
+   ossimIpt outputRectUl    = outputRect.ul();
+   long outputRectW         = outputRect.width();
+   long resultOffset = (subRectUl.y - outputRectUl.y)*outputRectW + (subRectUl.x - outputRectUl.x);
+
+   for(ossim_uint32 band = 0; band < input->getNumberOfBands(); band++)
+   {
+      T* resultBuf       = static_cast<T*>(output->getBuf(band))+resultOffset;
+      const T *sourceBuf = static_cast<T*>(dupIn->getBuf(band));
+      ossimDpt start = startSave;
+      ossimDpt end   = endSave;
+      T np = (T)output->getNullPix(band);
+                        
+      for(long y = 0; y < subRectH; y++)
+      {
+         double deltaX = (end.x - start.x)*stepSizeWidth;
+         double deltaY = (end.y - start.y)*stepSizeHeight;
+         ossimDpt pointXY = start;
+         
+         for(long x = 0; x < subRectW; x++)
+         {
+            int xPixel = pointXY.x<0?(int)floor(pointXY.x):(int)pointXY.x;
+            int yPixel = pointXY.y<0?(int)floor(pointXY.y):(int)pointXY.y;
+
+            
+            if( (xPixel >=0) && (xPixel < inWidth) &&
+                (yPixel >=0) && (yPixel < inHeight))
+            {
+               resultBuf[x] = sourceBuf[yPixel*inWidth + xPixel];
+            }
+            else
+            {
+               resultBuf[x] = np;
+            }
+            
+            pointXY.y += deltaY;
+            pointXY.x += deltaX;
+         }
+         resultBuf += outputRectW;
+         
+         start.x += newDeltaUl.x;
+         start.y += newDeltaUl.y;
+         end.x   += newDeltaUr.x;
+         end.y   += newDeltaUr.y;
+      }
+   }
+   if(theResamplerType != ossimResampler_NEAREST_NEIGHBOR)
+   {
+      delete dupIn;
+   }
+}
+
+template <class T>
+void ossimResampler::resampleTileNearestNeighbor(T, // dummy template variable
+                                                 ossimImageData* input,
+                                                 ossimImageData* output,
+                                                 const ossimDpt& ul,
+                                                 const ossimDpt& ur,
+                                                 const ossimDpt& deltaUl,
+                                                 const ossimDpt& deltaUr,
+                                                 const ossimDpt& length)
+{
+   resampleTileNearestNeighbor((T)0,
+                               input,
+                               output,
+                               output->getImageRectangle(),
+                               ul,
+                               ur,
+                               deltaUl,
+                               deltaUr,
+                               length);
+}
+
+template <class T>
+void ossimResampler::resampleTileNearestNeighbor(T, // dummy template variable
+                                                 ossimImageData* input,
+                                                 ossimImageData* output,
+                                                 const ossimIrect& outputSubRect,
+                                                 const ossimDpt& ul,
+                                                 const ossimDpt& ur,
+                                                 const ossimDpt& deltaUl,
+                                                 const ossimDpt& deltaUr,
+                                                 const ossimDpt& length)
+{   
+   long    inWidth        = input->getWidth();
+   long    inHeight       = input->getHeight();
+   double  stepSizeWidth  = 1.0/length.x;
+   double  stepSizeHeight = 1.0/length.y;
+   ossimIrect rect        = input->getImageRectangle();
+   
+   ossimDpt startSave(ul.x - rect.ul().x,
+                      ul.y - rect.ul().y );
+   
+   ossimDpt endSave(ur.x - rect.ul().x,
+                    ur.y - rect.ul().y);
+
+   ossimIrect outputRect = output->getImageRectangle();
+   ossimIpt subRectUl = outputSubRect.ul();
+//   ossimIpt subRectUl((int)outputSubRect.ul().x,
+//                      (int)outputSubRect.ul().y);
+   long     subRectH  = outputSubRect.height();
+   long     subRectW  = outputSubRect.width();
+   
+   ossimIpt outputRectUl    = outputRect.ul();
+   long outputRectW         = outputRect.width();
+
+   long resultOffset = (subRectUl.y - outputRectUl.y)*outputRectW + (subRectUl.x - outputRectUl.x);
+   for(ossim_uint32 band = 0; band < input->getNumberOfBands(); band++)
+   {
+      T* resultBuf       = static_cast<T*>(output->getBuf(band))+resultOffset;
+      const T *sourceBuf = static_cast<T*>(input->getBuf(band));
+      ossimDpt start = startSave;
+      ossimDpt end   = endSave;
+      T inNp  = (T)input->getNullPix(band);
+      T outNp = (T)output->getNullPix(band);
+                        
+      for(long y = 0; y < subRectH; y++)
+      {
+         double deltaX = (end.x - start.x)*stepSizeWidth;
+         double deltaY = (end.y - start.y)*stepSizeHeight;
+         ossimDpt pointXY = start;
+         
+         for(long x = 0; x < subRectW; x++)
+         {
+            int xPixel = pointXY.x<0?(int)floor(pointXY.x):(int)pointXY.x;
+            int yPixel = pointXY.y<0?(int)floor(pointXY.y):(int)pointXY.y;
+
+            
+             if( (xPixel >=0) && (xPixel < inWidth) &&
+                 (yPixel >=0) && (yPixel < inHeight))
+             {
+                T value = sourceBuf[yPixel*inWidth + xPixel];
+
+                if(value != inNp)
+                {
+                   resultBuf[x] = value;
+                }
+                else
+                {
+                   resultBuf[x] = outNp;
+                }
+            }
+            else
+            {
+               resultBuf[x] = outNp;
+            }
+            
+            pointXY.y += deltaY;
+            pointXY.x += deltaX;
+         }
+         resultBuf += outputRectW;
+         
+         start.x += deltaUl.x;
+         start.y += deltaUl.y;
+         end.x   += deltaUr.x;
+         end.y   += deltaUr.y;
+      }
+   }
+}
+
+ossim_int32 ossimResampler::getKernelWidth()const
+{
+   return theKernelWidth;
+}
+
+ossim_int32 ossimResampler::getKernelHeight()const
+{
+   return theKernelHeight;
+}
+
+void ossimResampler::deleteWeightTable()
+{
+   if(theWeightTableX)
+   {
+      for(ossim_int32 index = 0; index < theTableHeight; ++index)
+      {
+         delete [] theWeightTableX[index];
+      }
+      delete [] theWeightTableX;
+
+      theWeightTableX = NULL;
+   }
+   if(theWeightTableY)
+   {
+      for(ossim_int32 index = 0; index < theTableHeight; ++index)
+      {
+         delete [] theWeightTableY[index];
+      }
+      delete [] theWeightTableY;
+
+      theWeightTableY = NULL;
+   }
+}
+
+void ossimResampler::allocateWeightTable()//uint32 outWidth)
+{
+   if(theWeightTableX||
+      theWeightTableY)
+   {
+      deleteWeightTable();
+   }
+   
+   switch(theResamplerType)
+   {
+   case ossimResampler_BICUBIC:
+   {
+      theTableHeight = 4;
+      break;
+   }
+   case ossimResampler_BILINEAR:
+   {
+      theTableHeight = 2;
+      break;
+   }
+   case ossimResampler_NEAREST_NEIGHBOR:
+   {
+      theTableHeight = 1;
+      break;
+   }
+   case ossimResampler_NONE:
+     {
+       theResamplerType = ossimResampler_NEAREST_NEIGHBOR;
+      theTableHeight = 1;
+      break;
+     }
+   }
+   theTableWidthX = (ossim_int32)irint(theOutputToInputRatio.x);
+   theTableWidthY = (ossim_int32)irint(theOutputToInputRatio.y);
+   if(theTableWidthX&&theTableHeight)
+   {
+      theWeightTableX = new double*[theTableHeight];
+      
+      for(ossim_int32 index = 0; index < theTableHeight; ++index)
+      {
+         theWeightTableX[index] = new double[theTableWidthX];
+      }
+   }
+   if(theTableWidthY&&theTableHeight)
+   {
+      theWeightTableY = new double*[theTableHeight];
+      
+      for(ossim_int32 index = 0; index < theTableHeight; ++index)
+      {
+         theWeightTableY[index] = new double[theTableWidthY];
+      }
+   }
+}
+
+void ossimResampler::generateWeightTable()
+{
+   if(theWeightTableX&&
+      theWeightTableY)
+   {
+//      ossim_int32 d = theOutputToInputRatio.theDen;
+//      ossim_int32 n = theOutputToInputRatio.theNum;
+      ossim_int32 i = 0;
+      
+      double x = 0.0;
+      
+      switch(theResamplerType)
+      {
+   case ossimResampler_NONE:
+     {
+       theResamplerType = ossimResampler_NEAREST_NEIGHBOR;
+       for (i = 0; i < theTableWidthY; i++)
+         {
+	   theWeightTableY[0][i] = 1;
+         }
+       for (i = 0; i < theTableWidthX; i++)
+         {
+	   theWeightTableX[0][i] = 1;
+         }
+      break;
+     }
+      case ossimResampler_NEAREST_NEIGHBOR:
+      {         
+         for (i = 0; i < theTableWidthY; i++)
+         {
+            theWeightTableY[0][i] = 1;
+         }
+         for (i = 0; i < theTableWidthX; i++)
+         {
+            theWeightTableX[0][i] = 1;
+         }
+         break;
+      }
+      case ossimResampler_BILINEAR:
+      {
+         for (i = 0; i < theTableWidthX; i++)
+         {
+            x = (double)i/(double)(theTableWidthX);
+            theWeightTableX[0][i] = x;
+            theWeightTableX[1][i] = 1-x;
+         }
+         for (i = 0; i < theTableWidthY; i++)
+         {
+            x = (double)i/(double)(theTableWidthY);
+            theWeightTableY[0][i] = x;
+            theWeightTableY[1][i] = 1-x;
+         }
+         break;
+      }
+      case ossimResampler_BICUBIC:
+      {         
+         for (i = 0; i < theTableWidthX; i++)
+         {
+            x = (double)i/(double)(theTableWidthX);
+            theWeightTableX[0][i] = getCubicC0(x);
+            theWeightTableX[1][i] = getCubicC1(x);
+            theWeightTableX[2][i] = getCubicC2(x);
+            theWeightTableX[3][i] = getCubicC3(x);               
+         }
+         for (i = 0; i < theTableWidthY; i++)
+         {
+            x = (double)i/(double)(theTableWidthY);
+            theWeightTableY[0][i] = getCubicC0(x);
+            theWeightTableY[1][i] = getCubicC1(x);
+            theWeightTableY[2][i] = getCubicC2(x);
+            theWeightTableY[3][i] = getCubicC3(x);               
+         }
+         break;
+      }
+      }
+   }
+}
+
+void ossimResampler::setResamplerType(ossimResLevelResamplerType type)
+{
+   if(theResamplerType != type)
+   {
+      theResamplerType = type;
+      
+      switch(theResamplerType)
+      {
+      case ossimResampler_NONE:
+      {
+	theResamplerType = ossimResampler_NEAREST_NEIGHBOR;
+         theKernelWidth  = 1;
+         theKernelHeight = 1;
+
+         break;
+      }
+      case ossimResampler_NEAREST_NEIGHBOR:
+      {
+         theKernelWidth  = 1;
+         theKernelHeight = 1;
+
+         break;
+      }
+      case ossimResampler_BILINEAR:
+      {
+         theKernelWidth  = 2;
+         theKernelHeight = 2;
+
+         break;
+      }
+      case ossimResampler_BICUBIC:
+      {
+         theKernelWidth  = 4;
+         theKernelHeight = 4;
+         
+         break;
+      }
+      }
+      
+      allocateWeightTable();
+      generateWeightTable();
+   }
+}
+
+void ossimResampler::setRatio(double outputToInputRatio)
+{
+   // make it square
+   setRatio(ossimDpt(outputToInputRatio, outputToInputRatio));
+}
+
+void ossimResampler::setRatio(const ossimDpt& outputToInputRatio)
+{
+   // make it square
+   theOutputToInputRatio.x = (outputToInputRatio.x);
+   theOutputToInputRatio.y = (outputToInputRatio.y);
+
+   if((theTableWidthX != irint(outputToInputRatio.x))||
+      (theTableWidthY != irint(outputToInputRatio.y)))
+   {
+      allocateWeightTable();
+      generateWeightTable();
+   }
+}
+
+double ossimResampler::getCubicC0(double t)const
+{
+   return ((-theCubicAdjustableParameter * t * t * t) +
+           (theCubicAdjustableParameter * t * t));
+}
+
+double ossimResampler::getCubicC1(double t)const
+{
+   return (-(theCubicAdjustableParameter + 2.0) * t * t * t +
+           (2.0 * theCubicAdjustableParameter + 3.0) * t * t -
+           theCubicAdjustableParameter * t);
+}
+
+double ossimResampler::getCubicC2(double t)const
+{
+   return ((theCubicAdjustableParameter + 2.0) * t * t * t -
+           (theCubicAdjustableParameter + 3.0) * t * t + 1.0);
+}
+
+double ossimResampler::getCubicC3(double t)const
+{
+   return ((theCubicAdjustableParameter * t * t * t) -
+           (2.0f * theCubicAdjustableParameter * t * t) +
+           (theCubicAdjustableParameter * t));
+}
+
+bool ossimResampler::loadState(const ossimKeywordlist& kwl,
+                               const char* prefix)
+{   
+   const char* resamplerType = kwl.find(prefix, RESAMPLER_CONVOLUTION_TYPE_KW);
+   const char* scaleX        = kwl.find(prefix, RESAMPLER_SCALE_X_KW);
+   const char* scaleY        = kwl.find(prefix, RESAMPLER_SCALE_Y_KW);
+   const char* cubicParameter= kwl.find(prefix, RESAMPLER_CUBIC_PARAMETER_KW);
+   
+   if(cubicParameter)
+   {
+      theCubicAdjustableParameter = ossimString(cubicParameter).toDouble();
+      if(theCubicAdjustableParameter < -1) theCubicAdjustableParameter = -1;
+      if(theCubicAdjustableParameter > 0)  theCubicAdjustableParameter = 0;
+   }
+   else
+   {
+      theCubicAdjustableParameter = -.5;
+   }
+   if(resamplerType)
+   {
+      ossimString test =ossimString(resamplerType).upcase().trim();
+      
+      if( test == "BICUBIC")
+      {
+         setResamplerType(ossimResampler::ossimResampler_BICUBIC);
+      }
+      else if( test == "BILINEAR")
+      {
+         setResamplerType(ossimResampler::ossimResampler_BILINEAR);
+      }
+      else
+      {
+         setResamplerType(ossimResampler::ossimResampler_NEAREST_NEIGHBOR);
+      }
+   }
+   if(scaleX&&scaleY)
+   {
+      setRatio(ossimDpt(ossimString(scaleX).toDouble(),
+                        ossimString(scaleY).toDouble()));
+   }
+   allocateWeightTable();
+   generateWeightTable();
+   
+   return ossimConnectableObject::loadState(kwl, prefix);
+}
+
+bool ossimResampler::saveState(ossimKeywordlist& kwl,
+                               const char* prefix)const
+{
+   ossimString resamplerType;
+   if(getResamplerType() == ossimResampler_BICUBIC)
+   {
+      resamplerType = "BICUBIC";
+   }
+   else if(getResamplerType() == ossimResampler_BILINEAR)
+   {
+      resamplerType = "BILINEAR";
+   }
+   else 
+   {
+      resamplerType = "NEAREST_NEIGHBOR";
+   }
+   kwl.add(prefix,
+           RESAMPLER_CONVOLUTION_TYPE_KW,
+           resamplerType.c_str(),
+           true);
+
+   kwl.add(prefix,
+           RESAMPLER_SCALE_X_KW,
+           theOutputToInputRatio.x,
+           true);
+
+   kwl.add(prefix,
+           RESAMPLER_SCALE_Y_KW,
+           theOutputToInputRatio.y,
+           true);
+
+   kwl.add(prefix,
+           RESAMPLER_CUBIC_PARAMETER_KW,
+           theCubicAdjustableParameter,
+           true);
+   
+   return ossimConnectableObject::saveState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/resample/ossimResampler.h b/Utilities/OSSIM/ossim_core/imaging/resample/ossimResampler.h
new file mode 100644
index 0000000000..93fcea6751
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/resample/ossimResampler.h
@@ -0,0 +1,240 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//*******************************************************************
+//  $Id: ossimResampler.h,v 1.23 2003/05/13 11:31:06 dburken Exp $
+
+#ifndef ossimResampler_HEADER
+#define ossimResampler_HEADER
+
+#include "base/common/ossimConnectableObject.h"
+#include "base/data_types/ossimIpt.h"
+#include "base/data_types/ossimDrect.h"
+#include "base/data_types/ossimRationalNumber.h"
+
+class ossimImageData;
+
+/*!
+ * This is currently implemented as a  symmetric kernel resampler.
+ * It will use a lookup table idea to precompute
+ *
+ * The resampler will support Nearest neighbor, Bilinear and Bicubic
+ *
+ * The lookup table approach will be borrowed from Michael J. Aramini
+ * implementation of the Bicubic convolution:
+ *
+ *       http://www.ultranet.com/~aramini/
+ *       under:
+ *        Efficient Image Magnification by Bicubic Spline Interpolation.
+ */
+class ossimResampler : public ossimConnectableObject
+{   
+public:
+   enum ossimResLevelResamplerType
+   {
+      ossimResampler_NONE             = 0,
+      ossimResampler_NEAREST_NEIGHBOR = 1,
+      ossimResampler_BILINEAR         = 2,
+      ossimResampler_BICUBIC          = 3
+   };
+   ossimResampler();
+   
+   virtual ~ossimResampler();
+
+   
+   /*!
+    * Will apply the kernel to the input and write it to the output.
+    *
+    * Note: theTable is re-generated if the Max(out_width, out_height).
+    *       changes from the previous call.
+    */
+   virtual void resample(ossimImageData* input, // input buffer
+                         ossimImageData* output);
+
+
+   virtual void resample(ossimImageData* input,
+                         ossimImageData* output,
+                         const ossimDpt& ul,
+                         const ossimDpt& ur,
+                         const ossimDpt& deltaUl,
+                         const ossimDpt& deltaUr,
+                         const ossimDpt& length);
+
+   virtual void resample(ossimImageData* input,
+                         ossimImageData* output,
+                         const ossimIrect& outputSubRect,
+                         const ossimDpt& ul,
+                         const ossimDpt& ur,
+                         const ossimDpt& deltaUl,
+                         const ossimDpt& deltaUr,
+                         const ossimDpt& length);
+
+   virtual void resampleNearestNeighbor(ossimImageData* input,
+                                        ossimImageData* output,
+                                        const ossimIrect& outputSubRect,
+                                        const ossimDpt& ul,
+                                        const ossimDpt& ur,
+                                        const ossimDpt& deltaUl,
+                                        const ossimDpt& deltaUr,
+                                        const ossimDpt& length);
+
+   virtual void resampleNearestNeighbor(ossimImageData* input,
+                                        ossimImageData* output,
+                                        const ossimDpt& ul,
+                                        const ossimDpt& ur,
+                                        const ossimDpt& deltaUl,
+                                        const ossimDpt& deltaUr,
+                                        const ossimDpt& length);
+   /*!
+    * Will re-allocate the table
+    */
+   virtual void setResamplerType(ossimResLevelResamplerType type);
+
+   virtual ossimResLevelResamplerType getResamplerType()const
+      {
+         return theResamplerType;
+      }
+
+   virtual double getCubicParameter()const
+      {
+         return theCubicAdjustableParameter;
+      }
+   virtual void setCubicParameter(double parameter)
+      {
+         theCubicAdjustableParameter = parameter;
+         theCubicAdjustableParameter = theCubicAdjustableParameter<-1?-1:theCubicAdjustableParameter;
+         theCubicAdjustableParameter = theCubicAdjustableParameter>0?0:theCubicAdjustableParameter;
+         if(theResamplerType ==  ossimResampler_BICUBIC)
+         {
+            generateWeightTable();
+         }
+      }
+   /*!
+    * Will reallocate the table
+    */
+   void setRatio(double outputToInputRatio);
+   void setRatio(const ossimDpt& outputToInputRatio);
+   ossimDpt getRatio()const
+      {
+         return theOutputToInputRatio;
+      }
+   virtual ossim_int32 getKernelWidth()const;
+   virtual ossim_int32 getKernelHeight()const;
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const
+      {
+         return false;
+      }
+protected:
+
+   ossimDpt                   theOutputToInputRatio;
+   ossimResLevelResamplerType theResamplerType;  
+
+   ossim_int32                     theTableWidthX;
+   ossim_int32                     theTableWidthY;
+   ossim_int32                     theTableHeight;
+   ossim_int32                     theKernelWidth;
+   ossim_int32                     theKernelHeight;
+   /*!
+    */
+   double **theWeightTableX;
+   double **theWeightTableY;
+
+   /*!
+    * This adjustable parameter can vary between
+    * -1 to 0.  as the paramter goes from 0
+    * to -1 the output goes from blocky to smooth.
+    * The default value is -.5
+    */
+   double   theCubicAdjustableParameter;
+
+   template <class T>
+   void resampleTile(T, // dummy tmeplate variable
+                     ossimImageData* input,
+                     ossimImageData* output);
+   
+   template <class T>
+   void resampleFullTile(T, // dummy tmeplate variable
+                         ossimImageData* input,
+                         ossimImageData* output);
+   template <class T>
+   void resamplePartialTile(T, // dummy tmeplate variable
+                            ossimImageData* input,
+                            ossimImageData* output);
+   
+   template <class T>
+   void resampleTile(T, // dummy template variable
+                     ossimImageData* input,
+                     ossimImageData* output,
+                     const ossimIrect& outputSubRect,
+                     const ossimDpt& ul,
+                     const ossimDpt& ur,
+                     const ossimDpt& deltaUl,
+                     const ossimDpt& deltaUr,
+                     const ossimDpt& length);
+
+   template <class T>
+   void resampleTileNearestNeighbor(T, // dummy template variable
+                                    ossimImageData* input,
+                                    ossimImageData* output,
+                                    const ossimDpt& ul,
+                                    const ossimDpt& ur,
+                                    const ossimDpt& deltaUl,
+                                    const ossimDpt& deltaUr,
+                                    const ossimDpt& length);
+
+   template <class T>
+   void resampleTileNearestNeighbor(T, // dummy template variable
+                                    ossimImageData* input,
+                                    ossimImageData* output,
+                                    const ossimIrect& subRect,
+                                    const ossimDpt& ul,
+                                    const ossimDpt& ur,
+                                    const ossimDpt& deltaUl,
+                                    const ossimDpt& deltaUr,
+                                    const ossimDpt& length);
+   
+   virtual void deleteWeightTable();
+   virtual void allocateWeightTable();
+   virtual void generateWeightTable();
+
+   double getCubicC0(double t)const;
+   double getCubicC1(double t)const;
+   double getCubicC2(double t)const;
+   double getCubicC3(double t)const;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/tile_sources/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossim3x3ConvolutionFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossim3x3ConvolutionFilter.cpp
new file mode 100644
index 0000000000..f80cfce18b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossim3x3ConvolutionFilter.cpp
@@ -0,0 +1,632 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossim3x3ConvolutionFilter.cpp,v 1.15 2005/08/17 19:18:12 gpotts Exp $
+
+#include <imaging/tile_sources/ossim3x3ConvolutionFilter.h>
+#include <base/data_types/ossimIrect.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/property/ossimMatrixProperty.h>
+
+RTTI_DEF1(ossim3x3ConvolutionFilter, "ossim3x3ConvolutionFilter", ossimImageSourceFilter);
+
+ossim3x3ConvolutionFilter::ossim3x3ConvolutionFilter(ossimObject* owner)
+   :ossimImageSourceFilter(owner),
+    theTile(NULL),
+    theNullPixValue(0),
+    theMinPixValue(0),
+    theMaxPixValue(0)
+{
+   theKernel[0][0] = 0.0; theKernel[0][1] = 0.0; theKernel[0][2] = 0.0;
+   theKernel[1][0] = 0.0; theKernel[1][1] = 1.0; theKernel[1][2] = 0.0;
+   theKernel[2][0] = 0.0; theKernel[2][1] = 0.0; theKernel[2][2] = 0.0;
+   
+}
+
+ossim3x3ConvolutionFilter::~ossim3x3ConvolutionFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossim3x3ConvolutionFilter::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return theTile;
+   }
+
+   if(!isSourceEnabled())
+   {
+      return theInputConnection->getTile(tileRect, resLevel);
+   }
+
+   //---
+   // We have a 3x3 matrix so stretch the rect out to cover
+   // the required pixels.  We only need 1 pixel to the left
+   // and right of the center pixel.
+   //---
+   ossimIrect newRect(ossimIpt(tileRect.ul().x - 1,
+                               tileRect.ul().y - 1),
+                      ossimIpt(tileRect.lr().x + 1,
+                               tileRect.lr().y + 1));
+   
+   ossimRefPtr<ossimImageData> data = theInputConnection->getTile(newRect,
+                                                                  resLevel);
+
+   if(!data.valid() || !data->getBuf())
+   {
+      return data;
+   }
+
+    // First time through or after an initialize()...
+   if (!theTile.valid())
+   {
+      allocate();
+      if (!theTile.valid()) // Should never happen!
+      {
+         return data;
+      }
+   }
+
+   // First time through, after an initialize() or a setKernel()...
+   if (!theNullPixValue.size())
+   {
+      computeNullMinMax();
+      if (!theNullPixValue.size()) // Should never happen!
+      {
+         return data;
+      }
+   }
+
+   theTile->setImageRectangle(tileRect);
+   theTile->makeBlank();
+   
+   switch(data->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<ossim_uint8>(0), data, theTile);
+         }
+         else
+         {
+            convolvePartial(static_cast<ossim_uint8>(0), data, theTile);
+         }
+         break;
+      }
+      case OSSIM_FLOAT: 
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<float>(0), data, theTile);
+         }
+         else
+         {
+            convolvePartial(static_cast<float>(0), data, theTile);
+         }
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<ossim_uint16>(0), data, theTile);
+         }
+         else
+         {
+            convolvePartial(static_cast<ossim_uint16>(0), data, theTile);
+         }
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<ossim_sint16>(0), data, theTile);
+         }
+         else
+         {
+            convolvePartial(static_cast<ossim_sint16>(0), data, theTile);
+         }
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<double>(0), data, theTile);
+      }
+      else
+      {
+         convolvePartial(static_cast<double>(0), data, theTile);
+      }
+         break;
+      }
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossim3x3ConvolutionFilter::getTile WARNING:\n"
+            << "Scalar type = " << theTile->getScalarType()
+            << " Not supported by ossim3x3ConvolutionFilter" << endl;
+         break;
+      }
+   }
+   theTile->validate();
+   
+   return theTile;
+}
+
+
+template<class T> void ossim3x3ConvolutionFilter::convolvePartial(
+   T,
+   ossimRefPtr<ossimImageData> inputData,
+   ossimRefPtr<ossimImageData> outputData)
+{
+   // let's set up some temporary variables so we don't
+   // have to call the functions in loops.  Iknow that compilers
+   // typically optimize this out but if we are in debug mode 
+   // with no optimization it will still run fast
+   //
+   double sum = 0.0;
+   ossim_int32 inputW          = (ossim_int32)inputData->getWidth();
+   ossim_int32 outputW         = (ossim_int32)outputData->getWidth();
+   ossim_int32 outputH         = (ossim_int32)outputData->getHeight();
+   ossim_int32 numberOfBands   = (ossim_int32)inputData->getNumberOfBands();
+   ossimIpt outputOrigin  = outputData->getOrigin();
+   ossimIpt inputOrigin   = inputData->getOrigin();
+   
+   ossim_int32 startInputOffset = ossimAbs(outputOrigin.y - inputOrigin.y)*
+      inputW + ossimAbs(outputOrigin.x - inputOrigin.x);
+   ossim_int32 ulKernelStart    = -inputW - 1;
+   ossim_int32 leftKernelStart  = -1;
+   ossim_int32 llKernelStart    = inputW  - 1;
+   
+   T* ulKernelStartBuf    = NULL;
+   T* leftKernelStartBuf  = NULL;
+   T* llKernelStartBuf    = NULL;
+   
+   for(ossim_int32 band = 0; band < numberOfBands; ++band)
+   {
+      T* inputBuf  = static_cast<T*>(inputData->getBuf(band))+startInputOffset;
+      T* outputBuf = static_cast<T*>(outputData->getBuf(band));
+      T maxPix     = static_cast<T>(getMaxPixelValue(band));
+      T minPix     = static_cast<T>(getMinPixelValue(band));      
+      T nullPix    = static_cast<T>(inputData->getNullPix(band));
+      T oNullPix   = static_cast<T>(getNullPixelValue(band));
+      
+      if(inputBuf&&outputBuf)
+      {
+         for(ossim_int32 row = 0; row < outputW; ++row)
+         {
+            ossim_int32 rowOffset    = inputW*row;
+            ulKernelStartBuf   = inputBuf + (rowOffset + ulKernelStart);
+            leftKernelStartBuf = inputBuf + (rowOffset + leftKernelStart);
+            llKernelStartBuf   = inputBuf + (rowOffset + llKernelStart);
+            for(ossim_int32 col = 0; col < outputH; ++col)
+            {
+
+               if((ulKernelStartBuf[0]   != nullPix)&&
+                  (ulKernelStartBuf[1]   != nullPix)&&
+                  (ulKernelStartBuf[2]   != nullPix)&&
+                  (leftKernelStartBuf[0] != nullPix)&&
+                  (leftKernelStartBuf[1] != nullPix)&&
+                  (leftKernelStartBuf[2] != nullPix)&&
+                  (llKernelStartBuf[0]   != nullPix)&&
+                  (llKernelStartBuf[1]   != nullPix)&&
+                  (llKernelStartBuf[2]   != nullPix))
+               {
+                  sum = theKernel[0][0]*(double)ulKernelStartBuf[0] +
+                        theKernel[0][1]*(double)ulKernelStartBuf[1] +
+                        theKernel[0][2]*(double)ulKernelStartBuf[2] +
+                        theKernel[1][0]*(double)leftKernelStartBuf[0] +
+                        theKernel[1][1]*(double)leftKernelStartBuf[1] +
+                        theKernel[1][2]*(double)leftKernelStartBuf[2] +
+                        theKernel[2][0]*(double)llKernelStartBuf[0] +
+                        theKernel[2][1]*(double)llKernelStartBuf[1] +
+                        theKernel[2][2]*(double)llKernelStartBuf[2];
+                  
+                  if(sum > maxPix)
+                  {
+                     *outputBuf = maxPix;
+                  }
+                  else if(sum < minPix)
+                  {
+                     *outputBuf = minPix;
+                  }
+                  else
+                  {
+                     *outputBuf = static_cast<T>(sum);
+                  }
+               }
+               else {
+                  *outputBuf = oNullPix;
+               }
+               //
+               // Need to implement the convolution here
+               //
+               
+               ++ulKernelStartBuf;
+               ++leftKernelStartBuf;
+               ++llKernelStartBuf;
+               ++outputBuf;
+            }
+         }
+      }
+   }
+}
+
+template<class T> void ossim3x3ConvolutionFilter::convolveFull(
+   T,
+   ossimRefPtr<ossimImageData> inputData,
+   ossimRefPtr<ossimImageData> outputData)
+{
+   // let's set up some temporary variables so we don't
+   // have to call the functions in loops.  Iknow that compilers
+   // typically optimize this out but if we are in debug mode 
+   // with no optimization it will still run fast
+   //
+   double sum = 0.0;
+   ossim_int32 inputW = static_cast<ossim_int32>(inputData->getWidth());
+   ossim_uint32 outputW       = outputData->getWidth();
+   ossim_uint32 outputH       = outputData->getHeight();
+   ossim_uint32 numberOfBands = inputData->getNumberOfBands();
+   ossimIpt outputOrigin = outputData->getOrigin();
+   ossimIpt inputOrigin  = inputData->getOrigin();
+   
+   ossim_int32 startInputOffset = ossimAbs(outputOrigin.y - inputOrigin.y)*
+      inputW + ossimAbs(outputOrigin.x - inputOrigin.x);
+   ossim_int32 ulKernelStart    = -inputW - 1;
+   ossim_int32 leftKernelStart  = -1;
+   ossim_int32 llKernelStart    = inputW  - 1;
+   
+   T* ulKernelStartBuf   = NULL;
+   T* leftKernelStartBuf = NULL;
+   T* llKernelStartBuf   = NULL;
+   
+   for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+   {
+      T* inputBuf  = static_cast<T*>(inputData->getBuf(band))+startInputOffset;
+      T* outputBuf = static_cast<T*>(outputData->getBuf(band));
+      T maxPix     = static_cast<T>(getMaxPixelValue(band));
+      T minPix     = static_cast<T>(getMinPixelValue(band));
+      
+      if(inputBuf&&outputBuf)
+      {
+         for(ossim_uint32 row = 0; row < outputW; ++row)
+         {
+            ossim_int32 rowOffset    = inputW*row;
+            ulKernelStartBuf   = inputBuf + (rowOffset + ulKernelStart);
+            leftKernelStartBuf = inputBuf + (rowOffset + leftKernelStart);
+            llKernelStartBuf   = inputBuf + (rowOffset + llKernelStart);
+            for(ossim_uint32 col = 0; col < outputH; ++col)
+            {
+               sum = theKernel[0][0]*(double)ulKernelStartBuf[0] +
+                     theKernel[0][1]*(double)ulKernelStartBuf[1] +
+                     theKernel[0][2]*(double)ulKernelStartBuf[2] +
+                     theKernel[1][0]*(double)leftKernelStartBuf[0] +
+                     theKernel[1][1]*(double)leftKernelStartBuf[1] +
+                     theKernel[1][2]*(double)leftKernelStartBuf[2] +
+                     theKernel[2][0]*(double)llKernelStartBuf[0] +
+                     theKernel[2][1]*(double)llKernelStartBuf[1] +
+                     theKernel[2][2]*(double)llKernelStartBuf[2];
+               
+               if(sum > maxPix)
+               {
+                  *outputBuf = maxPix;
+               }
+               else if(sum < minPix)
+               {
+                  *outputBuf = minPix;
+               }
+               else
+               {
+                  *outputBuf = static_cast<T>(sum);
+               }
+               //
+               // Need to implement the convolution here.
+               //
+
+               
+               ++ulKernelStartBuf;
+               ++leftKernelStartBuf;
+               ++llKernelStartBuf;
+               ++outputBuf;
+            }
+         }
+      }
+   }
+}
+
+void ossim3x3ConvolutionFilter::initialize()
+{
+   //---
+   // NOTE:
+   // Since initialize get called often sequentially we will wipe things slick
+   // but not reallocate to avoid multiple delete/allocates.
+   //
+   // On the first getTile call things will be reallocated/computed.
+   //---
+   theTile = NULL;
+   clearNullMinMax();
+}
+
+void ossim3x3ConvolutionFilter::allocate()
+{   
+   if(theInputConnection)
+   {
+      ossimImageDataFactory* idf = ossimImageDataFactory::instance();
+      
+      theTile = idf->create(this,
+                            this);
+      
+      theTile->initialize();
+   }
+}
+
+void ossim3x3ConvolutionFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property) return;
+   if(property->getName() == "Kernel")
+   {
+      ossimMatrixProperty* matrixProperty = PTR_CAST(ossimMatrixProperty,
+                                                     property.get());
+      if(matrixProperty)
+      {
+         theKernel[0][0] = (*matrixProperty)(0,0);
+         theKernel[1][0] = (*matrixProperty)(1,0);
+         theKernel[2][0] = (*matrixProperty)(2,0);
+         theKernel[0][1] = (*matrixProperty)(0,1);
+         theKernel[1][1] = (*matrixProperty)(1,1);
+         theKernel[2][1] = (*matrixProperty)(2,1);
+         theKernel[0][2] = (*matrixProperty)(0,2);
+         theKernel[1][2] = (*matrixProperty)(1,2);
+         theKernel[2][2] = (*matrixProperty)(2,2);
+
+      }
+      else
+      {
+         ossimImageSourceFilter::setProperty(property);
+      }
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossim3x3ConvolutionFilter::getProperty(const ossimString& name)const
+{
+   if(name == "Kernel")
+   {
+      ossimMatrixProperty* property = new ossimMatrixProperty(name);
+      property->resize(3,3);
+      (*property)(0,0) = theKernel[0][0];
+      (*property)(1,0) = theKernel[1][0];
+      (*property)(2,0) = theKernel[2][0];
+      (*property)(0,1) = theKernel[0][1];
+      (*property)(1,1) = theKernel[1][1];
+      (*property)(2,1) = theKernel[2][1];
+      (*property)(0,2) = theKernel[0][2];
+      (*property)(1,2) = theKernel[1][2];
+      (*property)(2,2) = theKernel[2][2];
+      property->setCacheRefreshBit();
+
+      return property;
+   }
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossim3x3ConvolutionFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   propertyNames.push_back("Kernel");
+}
+
+bool ossim3x3ConvolutionFilter::saveState(ossimKeywordlist& kwl,
+                                          const char* prefix)const
+{   
+   kwl.add(prefix,
+           "rows",
+           3,
+           true);
+   
+   kwl.add(prefix,
+           "cols",
+           3,
+           true);
+   
+   for(long row = 0; row < 3; ++row)
+   {
+      for(long col =0; col < 3; ++col)
+      {
+         ossimString newPrefix = "m" +
+                                 ossimString::toString(row+1) + "_" +
+                                 ossimString::toString(col+1);
+         kwl.add(prefix,
+                 newPrefix,
+                 theKernel[row][col],
+                 true);          
+      }
+   }
+
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+
+bool ossim3x3ConvolutionFilter::loadState(const ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   ossimString newPrefix = prefix;
+   newPrefix += ossimString("m");
+   
+   for(long r = 0; r < 3; r++)
+   {
+      for(long c = 0; c < 3; c++)
+      {
+         theKernel[r][c] = 0.0;
+         
+         ossimString value = ossimString::toString(r+1);
+         value += "_";
+         value += ossimString::toString(c+1);
+         
+         const char* v = kwl.find(newPrefix.c_str(),
+                                  value.c_str());
+         if(v)
+         {
+            theKernel[r][c] = ossimString(v).toDouble();
+         }
+      }
+   }
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+void ossim3x3ConvolutionFilter::getKernel(double kernel[3][3])
+{
+   kernel[0][0] = theKernel[0][0];
+   kernel[0][1] = theKernel[0][1];
+   kernel[0][2] = theKernel[0][2];
+   kernel[1][0] = theKernel[1][0];
+   kernel[1][1] = theKernel[1][1];
+   kernel[1][2] = theKernel[1][2];
+   kernel[2][0] = theKernel[2][0];
+   kernel[2][1] = theKernel[2][1];
+   kernel[2][2] = theKernel[2][2];
+}
+
+void ossim3x3ConvolutionFilter::setKernel(double kernel[3][3])
+{
+   theKernel[0][0] = kernel[0][0];
+   theKernel[0][1] = kernel[0][1];
+   theKernel[0][2] = kernel[0][2];
+   theKernel[1][0] = kernel[1][0];
+   theKernel[1][1] = kernel[1][1];
+   theKernel[1][2] = kernel[1][2];
+   theKernel[2][0] = kernel[2][0];
+   theKernel[2][1] = kernel[2][1];
+   theKernel[2][2] = kernel[2][2];
+
+   // Will be recomputed first getTile call.
+   clearNullMinMax();
+}
+
+double ossim3x3ConvolutionFilter::getNullPixelValue(ossim_uint32 band)const
+{
+   if( isSourceEnabled() && (band < theNullPixValue.size()) )
+   {
+      return theNullPixValue[band];
+   }
+
+   return ossimGetDefaultNull(getOutputScalarType());
+}
+
+double ossim3x3ConvolutionFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   if( isSourceEnabled() && (band < theMinPixValue.size()) )
+   {
+      return theMinPixValue[band];
+   }
+   
+   return ossimImageSource::getMinPixelValue(band);
+}
+
+double ossim3x3ConvolutionFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   if( isSourceEnabled() && (band < theMaxPixValue.size()) )
+   {
+      return theMaxPixValue[band];
+   }
+
+   return ossimImageSource::getMaxPixelValue(band);
+}
+
+void ossim3x3ConvolutionFilter::clearNullMinMax()
+{
+   theNullPixValue.clear();
+   theMinPixValue.clear();
+   theMaxPixValue.clear();
+}
+
+void ossim3x3ConvolutionFilter::computeNullMinMax()
+{
+   const ossim_uint32 BANDS = getNumberOfOutputBands();
+
+   theNullPixValue.resize(BANDS);
+   theMinPixValue.resize(BANDS);
+   theMaxPixValue.resize(BANDS);
+
+   ossim_float64 defaultNull = ossimGetDefaultNull(getOutputScalarType());
+   ossim_float64 defaultMin = ossimGetDefaultMin(getOutputScalarType());
+   ossim_float64 defaultMax = ossimGetDefaultMax(getOutputScalarType());
+  
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      if(theInputConnection)
+      {
+         ossim_float64 inputNull = theInputConnection->getNullPixelValue(band);
+         ossim_float64 inputMin  = theInputConnection->getMinPixelValue(band);
+         ossim_float64 inputMax  = theInputConnection->getMaxPixelValue(band);
+         ossim_float64 tempMin   = 0.0;
+         ossim_float64 tempMax   = 0.0;
+         ossim_float64 k         = 0.0;
+         for(int i=0;i<3;++i)
+         {
+            for(int j=0;j<3;++j)
+            {
+               k=theKernel[i][j];
+               tempMin += (k<0.0) ? k*inputMax : k*inputMin;
+               tempMax += (k>0.0) ? k*inputMax : k*inputMin;
+            }
+         }
+
+         if((inputNull < getMinPixelValue(band)) ||
+            (inputNull > getMaxPixelValue(band)))
+         {
+            theNullPixValue[band] = inputNull;
+         }
+         else
+         {
+            theNullPixValue[band] = defaultNull;
+         }
+
+         if((tempMin >= defaultMin) && (tempMin <= defaultMax))
+         {
+            theMinPixValue[band] = tempMin;
+         }
+         else
+         {
+            theMinPixValue[band] = defaultMin;
+         }
+
+         if((tempMax >= defaultMin) && (tempMax <= defaultMax))
+         {
+            theMaxPixValue[band] = tempMax;
+         }
+         else
+         {
+            theMaxPixValue[band] = defaultMax;
+         }
+         
+      }
+      else // No input connection...
+      {
+         theNullPixValue[band] = defaultNull;
+         theMinPixValue[band]  = defaultMin;
+         theMaxPixValue[band]  = defaultMax;
+      }
+      
+   } // End of band loop.
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossim3x3ConvolutionFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossim3x3ConvolutionFilter.h
new file mode 100644
index 0000000000..3facf1c1f6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossim3x3ConvolutionFilter.h
@@ -0,0 +1,97 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossim3x3ConvolutionFilter.h,v 1.9 2005/08/17 19:18:12 gpotts Exp $
+#ifndef ossim3x3ConvolutionFilter_HEADER
+#define ossim3x3ConvolutionFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+
+class ossim3x3ConvolutionFilter : public ossimImageSourceFilter
+{
+public:
+   ossim3x3ConvolutionFilter(ossimObject* owner=NULL);
+   virtual ~ossim3x3ConvolutionFilter();
+
+   virtual ossimString getShortName()const{return ossimString("3x3 Convolution");}
+   virtual ossimString getLongName()const{return ossimString("Convolves the input image with a 3x3 kernel");}
+
+   virtual void getKernel(double kernel[3][3]);
+   
+   virtual void setKernel(double kernel[3][3]);
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+
+   virtual double getNullPixelValue(ossim_uint32 band=0) const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)  const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)  const;
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = 0);
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = 0)const;
+   
+protected:
+
+   /**
+    * Allocates theTile.
+    */
+   void allocate();
+
+   /**
+    * Clears data members theNullPixValue, theMinPixValue, and
+    * theMaxPixValue.
+    */
+   void clearNullMinMax();
+
+   /**
+    * Computes null, min, and max considering input connection and theKernel.
+    */
+   void computeNullMinMax();
+   
+   ossimRefPtr<ossimImageData> theTile;
+   double theKernel[3][3];
+
+   vector<double> theNullPixValue;
+   vector<double> theMinPixValue;
+   vector<double> theMaxPixValue;   
+   
+   /*!
+    * Convolve full means that the input data is full and has
+    * no null data.  We don't have to compare for nulls here
+    */
+   template<class T>
+   void convolveFull(T,
+                     ossimRefPtr<ossimImageData> inputData,
+                     ossimRefPtr<ossimImageData> outputData);
+   
+   /*!
+    * Convolve partial means that the input data is has some
+    * null data.  We will have to compare nulls
+    */
+   template<class T>
+   void convolvePartial(T,
+                        ossimRefPtr<ossimImageData> inputData,
+                        ossimRefPtr<ossimImageData> outputData);
+                       
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossim3x3ConvolutionFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandAverageFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandAverageFilter.cpp
new file mode 100644
index 0000000000..7847cffdf1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandAverageFilter.cpp
@@ -0,0 +1,394 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBandAverageFilter.cpp,v 1.9 2005/08/17 19:18:12 gpotts Exp $
+#include "ossimBandAverageFilter.h"
+
+// used for constructing and an ossimImageData object
+#include "imaging/factory/ossimImageDataFactory.h"
+
+// used for error reporting and for general info reporting such as warnings
+#include "base/context/ossimErrorContext.h"
+
+#include <sstream>
+#include <iterator>
+
+static const char* WEIGHTS_KW = "weights";
+
+RTTI_DEF1(ossimBandAverageFilter,
+          "ossimBandAverageFilter",
+          ossimImageSourceFilter);
+
+ossimBandAverageFilter::ossimBandAverageFilter()
+   :ossimImageSourceFilter(),
+    theTile(NULL)
+{
+}
+
+ossimBandAverageFilter::ossimBandAverageFilter(ossimImageSource* input,
+                                               const std::vector<double>& weights)
+   :ossimImageSourceFilter(input),
+    theTile(NULL),
+    theWeights(weights)
+{
+}
+
+ossimBandAverageFilter::~ossimBandAverageFilter()
+{
+}
+
+ossim_uint32 ossimBandAverageFilter::getNumberOfOutputBands()const
+{
+   if(isSourceEnabled())
+   {
+      return 1;
+   }
+   
+   return ossimImageSourceFilter::getNumberOfOutputBands();
+}
+
+ossimRefPtr<ossimImageData> ossimBandAverageFilter::getTile(const ossimIrect& rect, ossim_uint32 resLevel)
+{
+   // first we will check to see if we have an input connection
+   //
+   if(!theInputConnection)
+   {
+      // this will probably be null since we aren't initialized.
+      // we really need to creae a default blank tile in OSSIM that is returned
+      return theTile;
+   }
+
+   ossimRefPtr<ossimImageData> inputData =
+      theInputConnection->getTile(rect, resLevel);
+
+   if(!inputData.valid())
+   {
+      return inputData;
+   }
+   
+   // If we are disabled or if the data object is empty or NULL or
+   // not enough bands we don't need to run our algorithm so return the input
+   // tile.
+   if(!isSourceEnabled() ||
+      (inputData->getDataObjectStatus() == OSSIM_NULL)||
+      (inputData->getDataObjectStatus() == OSSIM_EMPTY)||
+      (inputData->getNumberOfBands() < 2))
+   {
+      return inputData;
+   }
+
+   // check to see if we are initialized
+   if(!theTile.valid())
+   {
+      initialize();
+   }
+   
+   theTile->setImageRectangle(rect);
+
+   // now lets set up the template method to operate in native type and run
+   // the algorithm
+   //
+   switch(inputData->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      averageInput((ossim_uint8)0, // setup template variable
+                   inputData);
+      break;
+   }
+   case OSSIM_USHORT11:
+   case OSSIM_USHORT16:
+   {
+      averageInput((ossim_uint16)0, // setup template variable
+                   inputData);
+      break;
+   }
+   case OSSIM_SSHORT16:
+   {
+      averageInput((ossim_sint16)0, // setup template variable
+                   inputData);
+      break;
+   }
+   case OSSIM_NORMALIZED_FLOAT:
+   case OSSIM_FLOAT:
+   {
+      averageInput((float)0, // setup template variable
+                   inputData);
+      break;
+   }
+   case OSSIM_NORMALIZED_DOUBLE:
+   case OSSIM_DOUBLE:
+   {
+      averageInput((double)0, // setup template variable
+                   inputData);
+      break;
+   }
+   default:
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "Unsupported scalar type in file %d at line %d",
+                    __FILE__,
+                    __LINE__);
+
+      
+      theTile->makeBlank();
+      break;
+   }
+   }
+   
+   theTile->validate();
+
+   
+   return theTile;
+}
+
+
+
+void ossimBandAverageFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+   
+   // theInputConnection is defined in ossimImageSourceFilter
+   // It is automatically set when an input is connected to this
+   // object
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+
+      // now initialize the tile
+      theTile->initialize();
+      checkWeights();
+   }
+}
+
+double ossimBandAverageFilter::getNullPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getNullPixelValue(band);
+   }
+   // lets use the first band's null value as our null
+   return ossimImageSourceFilter::getMinPixelValue(0);
+}
+
+double ossimBandAverageFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled()||!theInputConnection)
+   {
+      return ossimImageSourceFilter::getMinPixelValue(band);
+   }
+
+   // loop through each band and find the min pix value
+   ossim_uint32 bandIndex = 0;
+   ossim_uint32 inputBands = theInputConnection->getNumberOfOutputBands();
+   double minValue = ossimGetDefaultMax(OSSIM_DOUBLE);
+   for(bandIndex = 0; bandIndex < inputBands; ++bandIndex)
+   {
+      double minPix = theInputConnection->getMinPixelValue(bandIndex);
+
+      if(minPix < minValue)
+      {
+         minValue = minPix;
+      }
+   }
+
+   return minValue;
+}
+
+double ossimBandAverageFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getMaxPixelValue(band);
+   }
+   
+   // loop through each band and find the max pix value
+   ossim_uint32 bandIndex = 0;
+   ossim_uint32 inputBands = theInputConnection->getNumberOfOutputBands();
+   double maxValue = ossimGetDefaultMin(OSSIM_DOUBLE);
+   for(bandIndex = 0; bandIndex < inputBands; ++bandIndex)
+   {
+      double maxPix = theInputConnection->getMaxPixelValue(bandIndex);
+
+      if(maxPix > maxValue)
+      {
+         maxValue = maxPix;
+      }
+   }
+   
+   return maxValue;
+}
+
+void ossimBandAverageFilter::checkWeights()
+{
+   // we have not been initialzed yet
+   //
+   if(!theTile)
+   {
+      return;
+   }
+
+   // Check to see if the weights array is the same size as the input
+   // list.  If not then resize it and populate them with the same weight
+   // value.  It does not matter if they sum to one since we will perform
+   // a weighted average in the execution of the algorithm
+   //
+   if(theWeights.size() != theTile->getNumberOfBands())
+   {
+      theWeights.resize(theTile->getNumberOfBands());
+
+      std::fill(theWeights.begin(), theWeights.end(), 1);
+   }
+}
+
+
+template<class T> void ossimBandAverageFilter::averageInput(
+   T dummyVariable, // used only for template type, value ignored
+   ossimRefPtr<ossimImageData> inputDataObject)
+{
+   // since we have already checked the input for empty or
+   // null we will now execute the algorithm.  We will make
+   //
+   // 
+   std::vector<T*> inputBands(inputDataObject->getNumberOfBands());
+   std::vector<double> nullValues(inputDataObject->getNumberOfBands());
+   ossim_uint32 i = 0;
+
+   // for efficiency we will copy the band pointers and
+   // null values so we don't have extra function calls
+   // on a per band basis
+   //
+   for(i = 0; i < inputDataObject->getNumberOfBands(); ++i)
+   {
+      inputBands[i] = static_cast<T*>(inputDataObject->getBuf(i));
+      nullValues[i] = inputDataObject->getNullPix(i);
+   }
+
+   // store the output buffer pointer
+   T* outputBuf = static_cast<T*>(theTile->getBuf(0));
+
+   // setup index values and boundary values
+   ossim_uint32 upperBound = theTile->getWidth()*theTile->getHeight();
+   ossim_uint32 bandIndex = 0;
+   ossim_uint32 numberOfBands = inputDataObject->getNumberOfBands();
+   double outputNullPix = theTile->getNullPix(0);
+   
+   for(i = 0; i < upperBound; ++i)
+   {
+      double value=0.0;
+      double sumWeights=0.0;
+
+      // loop over each band only using the valid pixel data
+      // in the weighted average.
+      //
+      for(bandIndex = 0; bandIndex < numberOfBands; ++bandIndex)
+      {
+         // if valid then muliply the value by the weight and add it to
+         // current pixel value
+         if(*inputBands[bandIndex] != nullValues[bandIndex])
+         {
+            value += theWeights[bandIndex]*((double)*inputBands[bandIndex]);
+            sumWeights += theWeights[bandIndex];
+         }
+         // increment to the next pixel for the next time around
+         ++inputBands[bandIndex];
+      }
+
+      // check to see if we had any valid data.  If we did the weight
+      // should be greater than 0
+      if(sumWeights != 0.0)
+      {
+         value /= sumWeights;
+      }
+      else
+      {
+         // else we set the pixel to the output null value
+         value = outputNullPix;
+      }
+      // store the result in the outputBuffer.
+      *outputBuf = static_cast<T>(value);
+
+      // advance the output buffer to the next pixel value
+      ++outputBuf;
+   }
+}
+
+
+bool ossimBandAverageFilter::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   // get the value of the stored keyword
+   ossimString weightString = kwl.find(prefix, WEIGHTS_KW);
+   weightString = weightString.trim();
+   
+
+   theWeights.clear();
+   if(weightString != "")
+   {
+      // split the string list into an array of strings
+      std::vector<ossimString> weightList = weightString.split(" ");
+
+      // resize the weights to the size of the weight list
+      //
+      theWeights.resize(weightList.size());
+      ossim_uint32 i = 0;
+
+      // now store the weights to the array
+      for(i = 0; i < theWeights.size(); ++i)
+      {
+         theWeights[i] = weightList[i].toDouble();
+      }
+   }
+
+   // call base class to continue the load state
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimBandAverageFilter::saveState(ossimKeywordlist& kwl,
+                                       const char* prefix)const
+{
+   std::stringstream out;
+
+   // copy the weights  to a memory stream separated by space
+   std::copy(theWeights.begin(),
+             theWeights.end(),
+             ostream_iterator<double>(out, " "));
+
+   ossimString weightString = out.str();
+   weightString = weightString.trim();
+
+   
+   kwl.add(prefix, // prefix to help uniquely id or attributes
+           WEIGHTS_KW, // the keyword to identity our attribute
+           weightString.c_str(),     // the value 
+           true); // overwrite if already in the keywordlist
+   
+   // call base classes save to allow us to pass the information up
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+double ossimBandAverageFilter::getWeight(ossim_uint32 band)const
+{
+   if(band < theWeights.size())
+   {
+      return theWeights[band];
+   }
+   
+   return 0.0;
+}
+
+void ossimBandAverageFilter::setWeight(ossim_uint32 band, double weight)
+{
+   if(band < theWeights.size())
+   {
+      theWeights[band] = fabs(weight);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandAverageFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandAverageFilter.h
new file mode 100644
index 0000000000..cff28204d2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandAverageFilter.h
@@ -0,0 +1,109 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBandAverageFilter.h,v 1.5 2005/08/17 19:18:12 gpotts Exp $
+#ifndef ossimBandAverageFilter_HEADER
+#define ossimBandAverageFilter_HEADER
+#include <vector>
+#include "imaging/tile_sources/ossimImageSourceFilter.h"
+
+/**
+ * This filter outputs a single band that is the weighted average of all the
+ * input bands retrieved from the getTile.  This filter will work with any
+ * input scalar type.  Note the OSSIMDLLEXPORT is used for the different
+ * compilers that require importing and exporting symbols for shared library
+ * support.
+ */
+class OSSIMDLLEXPORT ossimBandAverageFilter : public ossimImageSourceFilter
+{
+public:
+   ossimBandAverageFilter();
+   ossimBandAverageFilter(ossimImageSource* input,
+                          const std::vector<double>& weights);
+   virtual ~ossimBandAverageFilter();
+
+   /**
+    * The data object argument is deprecated and should not be used.
+    * eventually we will remove it from the base classes.  This method will
+    * return 1 if our source is enabled else it calls the base class
+    * getNumberOfOutputBands.
+    */
+   virtual ossim_uint32 getNumberOfOutputBands()const;
+   
+   /**
+    * Since this filter is going to operate in native pixel type we will use
+    * a tmeplate method to do this.  It will check the scalar tpe of the input
+    * and then cat it to set the template variabel to be used within the
+    * template method averageInput.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+
+   /**
+    * Since we are merging all bands we will use the null pix of the
+    * first input band as our null pix.  If we are disabled we just
+    * return the input s null
+    */
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+
+   /**
+    * We will use the min of all bands as our min.  If we aredisabled
+    * we just return the inputs min
+    */
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   
+   /**
+    * We will use the max of all bands as our max.  If we aredisabled
+    * we just return the inputs max
+    */
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   /**
+    * simple access method to get a weight
+    */
+   double getWeight(ossim_uint32 band)const;
+
+   /**
+    * Sinple access method to set the weight of a band,
+    * We make sure that it is a positive weight
+    */
+   void setWeight(ossim_uint32 band, double weight);
+
+   /**
+    * allocates its tile buffer
+    */
+   virtual void initialize();
+
+   /**
+    * loads its weights to a keywordlist
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   /**
+    * Saves its weights to a keywordlist
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+protected:
+   ossimRefPtr<ossimImageData> theTile;
+   std::vector<double>         theWeights;
+
+   void checkWeights();
+   
+   template<class T> void averageInput(
+      T dummyVariable, // used only for template type, value ignored
+      ossimRefPtr<ossimImageData> inputDataObject);
+
+// for Runtime Type Info (RTTI)
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandClipFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandClipFilter.cpp
new file mode 100644
index 0000000000..53ca44e45e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandClipFilter.cpp
@@ -0,0 +1,697 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBandClipFilter.cpp,v 1.16 2005/02/11 15:07:32 dburken Exp $
+
+#include <imaging/tile_sources/ossimBandClipFilter.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimBandClipFilter, "ossimBandClipFilter", ossimImageSourceFilter);
+
+ossimBandClipFilter::ossimBandClipFilter()
+   :ossimImageSourceFilter(),
+    theClipType(ossimBandClipType_NONE),
+    theTile(NULL)
+{
+   theTile = new ossimImageData(this, // I am the owner,
+                                OSSIM_NORMALIZED_FLOAT,
+                                1);
+   theTile->initialize();
+}
+
+ossimBandClipFilter::ossimBandClipFilter(ossimImageSource* inputSource,
+                                           const vector<double>& minPix,
+                                           const vector<double>& maxPix,
+                                           ossimBandClipType clipType)
+   :ossimImageSourceFilter(inputSource),
+    theClipType(clipType),
+    theTile(NULL)
+{
+   theTile = new ossimImageData(this, // I am the owner,
+                                OSSIM_NORMALIZED_FLOAT,
+                                1);
+   theTile->initialize();
+   setMinMaxPix(minPix, maxPix);
+}
+
+ossimBandClipFilter::ossimBandClipFilter(ossimImageSource* inputSource,
+                                         double minPix,
+                                         double maxPix,
+                                         ossimBandClipType clipType)
+   :ossimImageSourceFilter(inputSource),
+    theClipType(clipType),
+    theTile(NULL)
+{
+   theTile = new ossimImageData(this, // I am the owner,
+                                OSSIM_NORMALIZED_FLOAT,
+                                1);
+   theTile->initialize();
+   
+   theMinPix.push_back(minPix);
+   theMaxPix.push_back(maxPix);
+}
+
+ossimBandClipFilter::~ossimBandClipFilter()
+{
+}
+
+void ossimBandClipFilter::setClipType(ossimBandClipType clipType)
+{
+   theClipType = clipType;
+}
+
+ossimBandClipFilter::ossimBandClipType ossimBandClipFilter::getClipType()const
+{
+   return theClipType;
+}
+
+ossim_uint32 ossimBandClipFilter::getNumberOfValues()const
+{
+   // We make sure that all arrays have the same number
+   // of elements so we can use the size of any of them.
+   return theMinPix.size();
+}
+
+void ossimBandClipFilter::setNumberOfValues(ossim_uint32 size)
+{
+
+   // lets do a non destructive set.  That way we can
+   // grow or shrink the list without destroying
+   // the original values.
+   //
+   if(!size)
+   {
+      theMinPix.clear();
+      theMaxPix.clear();
+      theMedian.clear();
+      return;
+   }
+
+   
+   vector<double> tempMin    = theMinPix;
+   vector<double> tempMax    = theMaxPix;
+   
+   theMinPix.resize(size);
+   theMaxPix.resize(size);
+   theMedian.resize(size);
+    
+   ossim_uint32 upperBound = min(theMinPix.size(), tempMin.size());
+   ossim_uint32 index = 0;
+
+   for(index = 0; index < upperBound; ++index)
+   {
+      theMinPix[index] = tempMin[index];
+      theMaxPix[index] = tempMax[index];
+      
+      theMinPix[index] = theMinPix[index]>1?1:theMinPix[index];
+      theMinPix[index] = theMinPix[index]<0?0:theMinPix[index];
+      theMaxPix[index] = theMaxPix[index]>1?1:theMaxPix[index];
+      theMaxPix[index] = theMaxPix[index]<0?0:theMaxPix[index];
+      
+      theMedian[index] = (theMaxPix[index] + theMinPix[index])/2.0;
+   }
+   
+   for(;index < theMinPix.size();++index)
+   {
+      theMinPix[index] = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
+      theMaxPix[index] = OSSIM_DEFAULT_MAX_PIX_NORM_FLOAT;
+      theMedian[index] = (theMaxPix[index] + theMinPix[index])/2.0;
+            
+      theMedian[index] = (theMaxPix[index] + theMinPix[index])/2.0;
+   }
+}
+
+void ossimBandClipFilter::setMinMaxPix(const vector<double>& minPix,
+                                       const vector<double>& maxPix)
+{
+   theMinPix = minPix;
+   theMaxPix = maxPix;
+
+   setNumberOfValues(max(theMinPix.size(), theMaxPix.size()));
+}
+
+const std::vector<double>& ossimBandClipFilter::getMinPixList()const
+{
+   return theMinPix;
+}
+
+const std::vector<double> ossimBandClipFilter::getMaxPixList()const
+{
+   return theMaxPix;
+}
+
+double ossimBandClipFilter::getMinPix(ossim_uint32 index)const
+{
+   return index<theMinPix.size()?theMinPix[index]:0;
+}
+
+double ossimBandClipFilter::getMaxPix(ossim_uint32 index)const
+{
+   return index<theMaxPix.size()?theMaxPix[index]:0;
+}
+
+ossimRefPtr<ossimImageData> ossimBandClipFilter::getTile(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;
+   }
+   
+   ossimRefPtr<ossimImageData> data =
+      theInputConnection->getTile(rect, resLevel);
+   if(!data.get())
+   {
+      return data;
+   }
+   ossimDataObjectStatus status = data->getDataObjectStatus();
+   if((status != OSSIM_NULL) &&
+      (status != OSSIM_EMPTY))
+   {
+      ossim_uint32 dw = data->getWidth();
+      ossim_uint32 dh = data->getHeight();
+      ossim_uint32 db = data->getNumberOfBands();
+
+      ossim_uint32 tw = theTile->getWidth();
+      ossim_uint32 th = theTile->getHeight();
+      ossim_uint32 tb = theTile->getNumberOfBands();
+
+      if(((tw*th)!=(dw*dh))||
+         (tb != db))
+      {
+         theTile = new ossimImageData(this,
+                                      OSSIM_NORMALIZED_FLOAT,
+                                      db,
+                                      dw,
+                                      dh);
+         theTile->initialize();
+      }
+
+      if(getNumberOfValues() != theTile->getNumberOfBands())
+      {
+         // Should this go on??? (drb)
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimBandClipFilter::getTile\n"
+            << "getNumberOfValues() != theTile->getNumberOfBands"
+            << endl;
+      }
+      
+      data->copyTileToNormalizedBuffer(static_cast<float*>(theTile->getBuf()));
+      theTile->setDataObjectStatus(data->getDataObjectStatus());
+      
+      switch(theClipType)
+      {
+         case ossimBandClipType_CLIP:
+         {
+            runClip();
+            break;
+         }
+         case ossimBandClipType_CLAMP:
+         {
+            runClamp();
+            break;
+         }
+         case ossimBandClipType_LINEAR_STRETCH:
+         {
+            runLinearStretch();
+            break;
+         }
+         case ossimBandClipType_MEDIAN_STRETCH:
+         {
+            runMedianStretch();
+            break;
+         }
+         default:
+            break;
+      }
+      data->copyNormalizedBufferToTile(static_cast<float*>(theTile->getBuf()));
+   }
+   
+   return data;
+}
+
+void ossimBandClipFilter::runClip()
+{
+   ossim_uint32 offset = 0;
+   ossim_uint32 upperBound = theTile->getWidth()*theTile->getHeight();
+   for(ossim_uint32 band =0; band < theTile->getNumberOfBands(); ++band)
+   {
+      float *buf     = static_cast<float*>(theTile->getBuf(band));
+      float  minPix  = theMinPix[band];
+      float  maxPix  = theMaxPix[band];
+      float  nullPix = theTile->getNullPix(band);
+      
+      if(buf)
+      {
+         for(offset = 0; offset < upperBound; ++offset)
+         {
+            if((*buf < minPix)||
+               (*buf > maxPix))
+            {
+               *buf = nullPix;
+            }
+            ++buf;
+         }
+      }
+   }
+   theTile->validate();
+}
+
+void ossimBandClipFilter::runClamp()
+{
+   ossim_uint32 offset = 0;
+   ossim_uint32 upperBound = theTile->getWidth()*theTile->getHeight();
+   for(ossim_uint32 band =0; band < theTile->getNumberOfBands(); ++band)
+   {
+      float *buf     = static_cast<float*>(theTile->getBuf(band));
+      float  minPix  = theMinPix[band];
+      float  maxPix  = theMaxPix[band];
+      float  nullPix = theTile->getNullPix(band);
+      
+      if(buf)
+      {
+         if(theTile->getDataObjectStatus() == OSSIM_PARTIAL)
+         {
+            for(offset = 0; offset < upperBound; ++offset)
+            {
+               if(*buf != nullPix)
+               {
+                  if(*buf < minPix)
+                  {
+                     *buf = minPix;
+                  }
+                  else if(*buf > maxPix)
+                  {
+                     *buf = maxPix;
+                  }
+               }
+               ++buf;
+            }
+         }
+         else
+         {
+            for(offset = 0; offset < upperBound; ++offset)
+            {
+               if(*buf < minPix)
+               {
+                  *buf = minPix;
+               }
+               else if(*buf > maxPix)
+               {
+                  *buf = maxPix;
+               }
+               ++buf;
+            }
+         }
+      }
+   }
+}
+
+void ossimBandClipFilter::runLinearStretch()
+{   
+   ossim_uint32 bands = min(theTile->getNumberOfBands(), (ossim_uint32)theMinPix.size());
+   ossim_uint32 w     = theTile->getWidth();
+   ossim_uint32 h     = theTile->getHeight();
+   ossim_uint32 upperBound = w*h;
+   const double* minPixArray = theTile->getMinPix();
+   const double* maxPixArray = theTile->getMaxPix();
+      
+   float* *bandArray = new float*[bands];
+   ossim_uint32 band = 0;
+   for(band = 0; band < bands; ++band)
+   {
+      bandArray[band] = static_cast<float*>(theTile->getBuf(band));
+   }
+   
+   if(theTile->getDataObjectStatus() == OSSIM_PARTIAL)
+   {
+      for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+      {
+         if(!theTile->isNull(offset))
+         {
+            for(band = 0; band < bands; ++band)
+            {
+               double delta = theMaxPix[band] - theMinPix[band];
+               double t     = (bandArray[band][offset] - theMinPix[band])/delta;
+               if(t < 0)
+               {
+                 bandArray[band][offset] = minPixArray[band];
+               }
+               else if(t > 1)
+               {
+                 bandArray[band][offset] = maxPixArray[band];
+               }
+               else
+               {
+                  bandArray[band][offset] = t;
+               }
+            }
+         }
+      }
+   }
+   else if(theTile->getDataObjectStatus() == OSSIM_FULL)
+   {
+      for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+         {
+            for(band = 0; band < bands; ++band)
+            {
+               double delta = theMaxPix[band] - theMinPix[band];
+               double t     = (bandArray[band][offset] - theMinPix[band])/delta;
+               
+              if(t < 0)
+              {
+                 bandArray[band][offset] = minPixArray[band];
+              }
+              else if(t > 1)
+              {
+                 bandArray[band][offset] = maxPixArray[band];
+              }
+              else
+              {
+                 bandArray[band][offset] = t;
+              }
+            }
+         }
+   }
+   delete [] bandArray;
+   
+}
+
+void ossimBandClipFilter::runMedianStretch()
+{
+   ossim_uint32 bands = theTile->getNumberOfBands();
+   float* *bandArray = new float*[bands];
+   ossim_uint32 band = 0;
+
+   for(band = 0; band < bands; ++band)
+   {
+      bandArray[band] = static_cast<float*>(theTile->getBuf(band));
+   }
+   ossim_uint32 upperBound = theTile->getWidth()*theTile->getHeight();
+   
+   if(theTile->getDataObjectStatus() == OSSIM_PARTIAL)
+   {
+      for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+      {
+         if(!theTile->isNull(offset))
+         {
+            for(band = 0; band < bands; ++band)
+            {
+               double side = (theMedian[band] - (double)bandArray[band][offset]);
+               
+               if(side > 0) // on the left
+               {
+                  double delta = fabs(theMedian[band] - theMinPix[band]);
+                  double t     = ((double)bandArray[band][offset] - theMinPix[band])/delta;
+                  if(t < 0)
+                  {
+                     bandArray[band][offset] = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
+                  }
+                  else if(t > 1)
+                  {
+                     bandArray[band][offset] = theMedian[band];
+                  }
+                  else
+                  {
+                     bandArray[band][offset] = theMedian[band]*t;
+                  }
+               }
+               else // on the right
+               {
+                  double delta = theMaxPix[band] - theMedian[band];
+                  double t = ((double)bandArray[band][offset] - theMedian[band])/delta;
+                  
+                  if(t < 0)
+                  {
+                     bandArray[band][offset] = theMedian[band];
+                  }
+                  else if(t > 1)
+                  {
+                     bandArray[band][offset] = OSSIM_DEFAULT_MAX_PIX_NORM_FLOAT;
+                  }
+                  else
+                  {
+                     bandArray[band][offset] = theMedian[band]+delta*t;
+                  }
+               }
+            }
+         }
+      }
+   }
+   else if(theTile->getDataObjectStatus() == OSSIM_FULL)
+   {
+      for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+      {
+         for(band = 0; band < bands; ++band)
+         {
+            double side = (theMedian[band] - (double)bandArray[band][offset]);
+            
+            if(side > 0) // on the left
+            {
+               double delta = fabs(theMedian[band] - theMinPix[band]);
+               double t     = ((double)bandArray[band][offset] - theMinPix[band])/delta;
+               if(t < 0)
+               {
+                  bandArray[band][offset] = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
+               }
+               else if(t > 1)
+               {
+                  bandArray[band][offset] = theMedian[band];
+               }
+               else
+               {
+                  bandArray[band][offset] = theMedian[band]*t;
+               }
+            }
+            else // on the right
+            {
+               double delta = theMaxPix[band] - theMedian[band];
+               double t = ((double)bandArray[band][offset] - theMedian[band])/delta;
+               
+               if(t < 0)
+               {
+                  bandArray[band][offset] = theMedian[band];
+               }
+               else if(t > 1)
+               {
+                  bandArray[band][offset] = OSSIM_DEFAULT_MAX_PIX_NORM_FLOAT;
+               }
+               else
+               {
+                  bandArray[band][offset] = theMedian[band]+delta*t;
+               }
+            }
+         }
+      }
+   }
+
+   delete [] bandArray;
+}   
+
+void ossimBandClipFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+   
+   if(theInputConnection)
+   {
+      ossim_uint32 bands = theInputConnection->getNumberOfOutputBands();
+
+      if(bands)
+      {
+         if(theMinPix.size() != bands)
+         {
+            setNumberOfValues(bands);
+         }
+      }
+   }
+}
+
+bool ossimBandClipFilter::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   bool result = ossimImageSourceFilter::loadState(kwl, prefix);
+
+   if(result)
+   {
+      ossimString minRegExpression    = ossimString("^(") +
+                                        ossimString(prefix) +
+                                        "min[0-9]+)";
+      ossimString maxRegExpression    = ossimString("^(") +
+                                        ossimString(prefix) +
+                                        "max[0-9]+)";
+      ossimString medianRegExpression = ossimString("^(") +
+                                        ossimString(prefix) +
+                                        "median[0-9]+)";
+      
+      ossim_uint32 numberOfMins    = kwl.getNumberOfSubstringKeys(minRegExpression);
+      ossim_uint32 numberOfMaxs    = kwl.getNumberOfSubstringKeys(maxRegExpression);
+      ossim_uint32 numberOfMedians = kwl.getNumberOfSubstringKeys(medianRegExpression);
+      theMinPix.clear();
+      theMaxPix.clear();
+      theMedian.clear();
+
+      if(numberOfMins != numberOfMaxs)
+      {
+         ossim_int32 temp = min(numberOfMins, numberOfMaxs);
+         numberOfMins = temp;
+         numberOfMaxs = temp;
+      }
+      if(numberOfMins> 0)
+      {
+         ossimString prefixMin    = ossimString(prefix) + "min";
+         ossimString prefixMax    = ossimString(prefix) + "max";
+         ossimString prefixMedian = ossimString(prefix) + "median";
+         
+         ossim_uint32 numberOfMatches = 0;
+         ossim_uint32 index = 0;
+         const char* value=(const char*)NULL;
+         
+         while(numberOfMatches < numberOfMins)
+         {
+            value = kwl.find(prefixMin.c_str(),
+                             ossimString::toString(index).c_str());
+            if(value)
+            {
+               theMinPix.push_back(ossimString(value).toDouble());
+               ++numberOfMatches;
+            }
+            ++index;
+         }
+         index = 0;
+         numberOfMatches = 0;
+         while(numberOfMatches < numberOfMaxs)
+         {
+            value = kwl.find(prefixMax.c_str(),
+                             ossimString::toString(index).c_str());
+            if(value)
+            {
+               theMaxPix.push_back(ossimString(value).toDouble());
+               ++numberOfMatches;
+            }
+            ++index;
+         }
+         if(numberOfMedians != numberOfMins)
+         {
+            for(index = 0; index <  theMaxPix.size(); ++index)
+            {
+               theMedian.push_back((theMinPix[index]+theMaxPix[index])/2.0);
+            }
+         }
+         else
+         {
+            index = 0;
+            numberOfMatches = 0;
+            while(numberOfMatches < numberOfMedians)
+            {
+               value = kwl.find(prefixMedian.c_str(),
+                                ossimString::toString(index).c_str());
+               if(value)
+               {
+                  theMedian.push_back(ossimString(value).toDouble());
+                  ++numberOfMatches;
+               }
+               ++index;
+            }
+         }
+      }
+   }
+   const char* clip_type = kwl.find(prefix, "clip_type");
+   if(clip_type)
+   {
+     ossimString clipType = clip_type;
+      clipType = clipType.upcase().trim();
+
+      if(clipType == "NONE")
+      {
+         theClipType = ossimBandClipType_NONE;
+      }
+      else if(clipType == "CLIP")
+      {
+         theClipType = ossimBandClipType_CLIP;
+      }
+      else if(clipType == "LINEAR_STRETCH")
+      {
+         theClipType = ossimBandClipType_LINEAR_STRETCH;
+      }
+      else if(clipType == "MEDIAN_STRETCH")
+      {
+         theClipType = ossimBandClipType_MEDIAN_STRETCH;
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_NOTICE)
+         << "ossimBandClipFilter::loadState NOTICE:\n"
+         << "Clip type not given defaulting to NONE" << endl;
+      theClipType = ossimBandClipType_NONE;
+   }
+
+   return result;
+}
+
+bool ossimBandClipFilter::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix)const
+{
+   ossimString minPrefix    = ossimString("min");
+   ossimString maxPrefix    = ossimString("max");
+   ossimString medianPrefix = ossimString("median");
+
+   for(ossim_uint32 index = 1; index <= getNumberOfValues(); ++index)
+   {
+      ossimString value = (minPrefix+ossimString::toString(index));
+      kwl.add(prefix,
+              value.c_str(),
+              theMinPix[index-1],
+              true);
+      value = (maxPrefix+ossimString::toString(index));
+      kwl.add(prefix,
+              value.c_str(),
+              theMaxPix[index-1],
+              true);
+      value = (medianPrefix+ossimString::toString(index));
+      kwl.add(prefix,
+              value.c_str(),
+              theMedian[index-1],
+              true);
+   }
+   ossimString clipType;
+   switch(theClipType)
+   {
+      case ossimBandClipType_NONE:
+      {
+         clipType = "NONE";
+         break;
+      }
+      case ossimBandClipType_CLIP:
+      {
+         clipType = "CLIP";
+         break;
+      }
+      case ossimBandClipType_LINEAR_STRETCH:
+      {
+         clipType = "LINEAR_STRETCH";
+         break;
+      }
+      case ossimBandClipType_MEDIAN_STRETCH:
+      {
+         clipType = "MEDIAN_STRETCH";
+         break;
+      }
+      default:
+         break;
+   }
+   kwl.add(prefix,
+           "clip_type",
+           clipType.c_str(),
+           true);
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandClipFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandClipFilter.h
new file mode 100644
index 0000000000..b0cde29bff
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandClipFilter.h
@@ -0,0 +1,92 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBandClipFilter.h,v 1.12 2005/02/11 15:07:32 dburken Exp $
+#ifndef ossimBandClipFilter_HEADER
+#define ossimBandClipFilter_HEADER
+#include <vector>
+using namespace std;
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimBandClipFilter : public ossimImageSourceFilter
+{
+public:
+   /*!
+    * Specifies the type of clipping.  The first will
+    * just clip and 
+    */
+   enum ossimBandClipType
+   {
+      ossimBandClipType_NONE             = 0,
+      ossimBandClipType_CLIP             = 1,
+      ossimBandClipType_CLAMP            = 2,
+      ossimBandClipType_LINEAR_STRETCH   = 3,
+      ossimBandClipType_MEDIAN_STRETCH   = 4 
+   };
+
+   ossimBandClipFilter();
+   ossimBandClipFilter(ossimImageSource*,
+                        const vector<double>& minPix,
+                        const vector<double>& maxPix,
+                        ossimBandClipType clipType=ossimBandClipType_NONE);
+   
+   ossimBandClipFilter(ossimImageSource*,
+                        double minPix,
+                        double maxPix,
+                        ossimBandClipType clipType=ossimBandClipType_NONE);
+
+   virtual ~ossimBandClipFilter();
+
+   void setClipType(ossimBandClipType clipType);
+
+   ossimBandClipType getClipType()const;
+
+   virtual ossim_uint32 getNumberOfValues()const;
+
+   void setNumberOfValues(ossim_uint32 size);
+   
+   void setMinMaxPix(const vector<double>& minPix,
+                     const vector<double>& maxPix);
+
+   const std::vector<double>& getMinPixList()const;
+   const std::vector<double>  getMaxPixList()const;
+
+   double getMinPix(ossim_uint32 index)const;
+   double getMaxPix(ossim_uint32 index)const;
+
+   ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                       ossim_uint32 resLevel=0);
+   
+   virtual void initialize();
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = NULL);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = NULL)const;
+protected:
+
+   void runClip();
+   void runClamp();
+   void runLinearStretch();
+   void runMedianStretch();
+
+   std::vector<double> theMinPix; // normalized min
+   std::vector<double> theMaxPix; // normalized max
+   std::vector<double> theMedian; // normalized median.
+
+   ossimBandClipType           theClipType;
+   ossimRefPtr<ossimImageData> theTile;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandMergeSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandMergeSource.cpp
new file mode 100644
index 0000000000..8abc394d3b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandMergeSource.cpp
@@ -0,0 +1,274 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBandMergeSource.cpp,v 1.19 2005/08/16 17:35:59 gpotts Exp $
+#include <imaging/tile_sources/ossimBandMergeSource.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/data_types/ossimIrect.h>
+
+RTTI_DEF1(ossimBandMergeSource, "ossimBandMergeSource", ossimImageCombiner)
+
+ossimBandMergeSource::ossimBandMergeSource()
+   :ossimImageCombiner(),
+    theNumberOfOutputBands(0),
+    theTile(NULL)
+{
+}
+
+ossimBandMergeSource::ossimBandMergeSource(vector<ossimImageSource*>& inputSources)
+   :ossimImageCombiner(inputSources),
+    theNumberOfOutputBands(0),
+    theTile(NULL)
+{
+   initialize();
+}
+
+ossimBandMergeSource::~ossimBandMergeSource()
+{
+   theNumberOfOutputBands = 0;
+}
+
+ossimRefPtr<ossimImageData> ossimBandMergeSource::getTile(const ossimIrect& tileRect,
+                                              ossim_uint32 resLevel)
+{
+   if( ( getNumberOfInputs() == 1) || !isSourceEnabled() )
+   {
+      return getNextTile(0, tileRect, resLevel);
+   }
+
+   // test if initialized
+   if(!theTile.get())
+   {
+      allocate();
+   }
+   
+   if(!theTile.get())
+   {
+      return getNextTile(0, tileRect, resLevel);
+   }
+   
+   long w     = tileRect.width();
+   long h     = tileRect.height();
+   long tileW = theTile->getWidth();
+   long tileH = theTile->getHeight();
+   if((w != tileW)||
+      (h != tileH))
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+      }
+      else
+      {
+         theTile->makeBlank();
+      }
+   }
+   else
+   {
+      theTile->makeBlank();
+   }
+   theTile->setOrigin(tileRect.ul());
+   ossim_uint32 currentBand = 0;
+   ossim_uint32 maxBands = theTile->getNumberOfBands();
+   ossim_uint32 inputIdx = 0;
+   for(inputIdx = 0; inputIdx < getNumberOfInputs(); ++inputIdx)
+   {
+      ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                                  getInput(inputIdx));
+      ossimRefPtr<ossimImageData> currentTile = 0;
+
+      if(input)
+      {
+         currentTile = input->getTile(tileRect, resLevel);
+      }
+      else
+      {
+         currentTile = 0;
+      }
+      ossim_uint32 maxInputBands = 0;
+
+      if(!currentTile.get())
+      {
+         maxInputBands = 1;
+      }
+      else if(currentTile->getNumberOfBands() == 0)
+      {
+         maxInputBands = 1;
+      }
+      else
+      {
+         maxInputBands = currentTile->getNumberOfBands();
+      }
+      for(ossim_uint32 band = 0;
+          ( (band < maxInputBands) &&
+            (currentBand < maxBands));
+          ++band)
+      {
+         // clear the band with the actual NULL
+         theTile->fill(currentBand, theTile->getNullPix(band));
+
+         if(currentTile.valid())
+         {
+            if((currentTile->getDataObjectStatus() != OSSIM_NULL) &&
+               (currentTile->getDataObjectStatus() != OSSIM_EMPTY))
+            {
+               memmove(theTile->getBuf(currentBand),
+                       currentTile->getBuf(band),
+                       currentTile->getSizePerBandInBytes());
+            }
+         }
+         ++currentBand;
+      }
+   }
+   theTile->validate();
+
+   return theTile;
+}
+
+double ossimBandMergeSource::getNullPixelValue(ossim_uint32 band)const
+{
+   ossim_uint32 currentBandCount = 0;
+   ossim_uint32 idx              = 0;
+
+   ossim_uint32 maxBands = getNumberOfOutputBands();
+   if(!maxBands) return 0.0;
+   
+   while((currentBandCount < maxBands)&&
+	 (idx < getNumberOfInputs()))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(idx));
+      if(temp)
+      {
+	ossim_uint32 previousCount = currentBandCount;
+	currentBandCount += temp->getNumberOfOutputBands();
+
+         if(band < currentBandCount)
+         {
+            return temp->getNullPixelValue(band - previousCount);
+         }
+      }
+      ++idx;
+   }
+   
+   return OSSIM_DBL_NAN;
+}
+
+double ossimBandMergeSource::getMinPixelValue(ossim_uint32 band)const
+{
+   ossim_uint32 currentBandCount = 0;
+   ossim_uint32 idx              = 0;
+
+   ossim_uint32 maxBands = getNumberOfOutputBands();
+   if(!maxBands) return 0.0;
+   
+   while((currentBandCount < maxBands)&&
+	 (idx < getNumberOfInputs()))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(idx));
+      if(temp)
+      {
+	ossim_uint32 previousCount = currentBandCount;
+	currentBandCount += temp->getNumberOfOutputBands();
+
+         if(band < currentBandCount)
+         {
+            return temp->getMinPixelValue(band - previousCount); 
+         }
+      }
+      ++idx;
+   }
+   
+   return 0.0;
+}
+
+double ossimBandMergeSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   ossim_uint32 currentBandCount = 0;
+   ossim_uint32 idx              = 0;
+
+   ossim_uint32 maxBands = getNumberOfOutputBands();
+   if(!maxBands) return 0.0;
+   
+   while((currentBandCount < maxBands)&&
+	 (idx < getNumberOfInputs()))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(idx));
+      if(temp)
+      {
+	ossim_uint32 previousCount = currentBandCount;
+	currentBandCount += temp->getNumberOfOutputBands();
+
+         if(band < currentBandCount)
+         {
+            return temp->getMaxPixelValue(band - previousCount);
+         }
+      }
+      ++idx;
+   }
+   
+   return OSSIM_DBL_NAN;
+}
+
+void ossimBandMergeSource::initialize()
+{
+   ossimImageCombiner::initialize();
+
+   if(theTile.get())
+   {
+      theTile = NULL;
+   }
+   
+   theNumberOfOutputBands = computeNumberOfInputBands();
+}
+
+void ossimBandMergeSource::allocate()
+{
+   if(theNumberOfOutputBands)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,
+                                                          this);
+      theTile->initialize();
+   }
+}
+
+ossim_uint32 ossimBandMergeSource::computeNumberOfInputBands()const
+{
+   ossim_uint32 result = 0;
+   ossim_uint32 size   = getNumberOfInputs();
+   for(ossim_uint32 index = 0; index < size; ++index)
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(index));
+      if(temp)
+      {
+         if(temp->getNumberOfOutputBands() == 0)
+         {
+            ++result;
+         }
+         else
+         {
+            result += temp->getNumberOfOutputBands();
+         }
+      }
+   }
+   return result;
+}
+
+ossim_uint32 ossimBandMergeSource::getNumberOfOutputBands() const
+{
+   if(!theNumberOfOutputBands)
+   {
+      return computeNumberOfInputBands();
+   }
+   
+   return theNumberOfOutputBands;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandMergeSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandMergeSource.h
new file mode 100644
index 0000000000..55e1170185
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandMergeSource.h
@@ -0,0 +1,62 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBandMergeSource.h,v 1.12 2005/07/22 21:55:37 dburken Exp $
+#ifndef ossimBandMergeSource_HEADER
+#define ossimBandMergeSource_HEADER
+#include <imaging/tile_sources/ossimImageCombiner.h>
+
+class ossimImageSourceConnection;
+class ossimImageSource;
+
+class OSSIM_DLL ossimBandMergeSource : public ossimImageCombiner
+{
+public:
+   ossimBandMergeSource();
+   ossimBandMergeSource(vector<ossimImageSource*>& inputSources);
+   virtual ~ossimBandMergeSource();
+   
+   /**
+    * This will merge all the bands from the input source list
+    * into one contiguous ossimImageData object.  This is very
+    * useful when you want to split off an intesity channel in
+    * HSI and then run some algorithms on it and then merge it back.
+    * You can also try to do fusions by converting to an YCbCr and
+    * replace the Y or intensity channel with maybe a high-pass
+    * convolution on the pan.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+   
+   /**
+    * Returns the number of bands in a tile returned from this TileSource.
+    * Note: we are supporting sources that can have multiple data objects.
+    * If you want to know the scalar type of an object you can pass in the 
+    */
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   
+protected:
+   /** Performs allocation of "theTile". */
+   void allocate();
+   
+   ossim_uint32                theNumberOfOutputBands;
+   ossimRefPtr<ossimImageData> theTile;
+   
+   ossim_uint32 computeNumberOfInputBands()const;
+
+TYPE_DATA
+};
+#endif /* #ifndef ossimBandMergeSource_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandSelector.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandSelector.cpp
new file mode 100644
index 0000000000..758f964319
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandSelector.cpp
@@ -0,0 +1,428 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class declaration for ossimBandSelector.
+// 
+//*******************************************************************
+//  $Id: ossimBandSelector.cpp,v 1.23 2005/12/20 16:29:48 dburken Exp $
+
+#include <iostream>
+#include <algorithm>
+
+#include <imaging/tile_sources/ossimBandSelector.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/property/ossimStringProperty.h>
+
+RTTI_DEF1(ossimBandSelector,"ossimBandSelector", ossimImageSourceFilter)
+
+ossimBandSelector::ossimBandSelector()
+   :
+      ossimImageSourceFilter(),
+      theTile(NULL)
+{
+   theEnableFlag = false; // Start off disabled.
+}
+
+ossimBandSelector::~ossimBandSelector()
+{
+   theTile = NULL;
+}
+
+ossimRefPtr<ossimImageData> ossimBandSelector::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if (!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   // Get the tile from the source.
+   ossimRefPtr<ossimImageData> t = theInputConnection->getTile(tileRect,
+                                                               resLevel);
+
+   if (!theEnableFlag)
+   {
+      return t;  // This tile source bypassed, return the input tile source.
+   }
+
+   if (isOrderedCorrectly())
+   {
+      return t; // Input band order same as output band order.
+   }
+
+   if(!theTile.valid()) // First time through, might not be initialized...
+   {
+      allocate();
+      if (!theTile.valid())
+      {
+         // Should never happen...
+         return t; // initialize failed.
+      }
+   }
+
+   theTile->setImageRectangle(tileRect);
+
+   if ( !t.valid() ||
+        (t->getDataObjectStatus() == OSSIM_EMPTY) ||
+        (t->getDataObjectStatus() == OSSIM_NULL) )
+   {
+      //---
+      // Since we're enabled, we must return our tile not "t" so the
+      // correct number of bands goes through the chain.
+      //---
+      theTile->makeBlank();
+      return theTile;
+   }
+
+   // Copy selected bands to our tile.
+   for (ossim_uint32 i=0; i<theOutputBandList.size(); i++)
+   {
+      theTile->assignBand(t.get(), theOutputBandList[i], i);
+   }
+   
+   theTile->validate();
+
+   return theTile;
+}
+
+void ossimBandSelector::setOutputBandList(
+   const vector<ossim_uint32>& outputBandList)
+{
+   theOutputBandList = outputBandList;  // Assign the new list.
+   if(outputBandsWithinInputRange())
+   {
+      theEnableFlag = true; // Enable
+      theTile = NULL;       // Force an allocate call next getTile.
+   }
+   else if(theInputConnection)
+   {
+      theInputConnection->getOutputBandList(theOutputBandList);
+   }
+   else
+   {
+      theOutputBandList.clear();
+   }
+}
+
+ossim_uint32 ossimBandSelector::getNumberOfOutputBands() const
+{
+   if(theEnableFlag)
+   {
+      return theOutputBandList.size();
+   }
+   
+   return getNumberOfInputBands();
+}
+
+void ossimBandSelector::initialize()
+{   
+   // Base class will recapture "theInputConnection".
+   ossimImageSourceFilter::initialize();
+   
+   if(theInputConnection)
+   {
+      if ( !theOutputBandList.size() ||
+           (outputBandsWithinInputRange() == false ) )
+      {
+         //---
+         // First time through set the output band list to input.
+         //---
+         theInputConnection->getOutputBandList(theOutputBandList);
+      }
+
+      if ( theEnableFlag )
+      {
+         if ( theTile.valid() )
+         {
+            //---
+            // Check for:
+            // - ordered correctly
+            // - band change
+            // - scalar change
+            //---
+            if( isOrderedCorrectly() ||
+                ( theTile->getNumberOfBands() != theOutputBandList.size() ) ||
+                ( theTile->getScalarType() !=
+                  theInputConnection->getOutputScalarType() ) )
+            {
+               theTile = NULL; // Don't need it.
+            }
+         }
+      }
+      else
+      {
+         theTile = NULL;
+      }
+   }
+   else // No input connection.
+   {
+      theTile = NULL;
+   }
+}
+
+void ossimBandSelector::allocate()
+{
+   initialize(); // Update the connection.
+
+   theTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile->initialize();
+}
+
+double ossimBandSelector::getMinPixelValue(ossim_uint32 band)const
+{
+   if(theInputConnection)
+   {
+      if (theEnableFlag)
+      {
+         if(band < theOutputBandList.size())
+         {
+            return theInputConnection->
+               getMinPixelValue(theOutputBandList[band]);
+         }
+      }
+      else
+      {
+         return theInputConnection->getMinPixelValue(band);
+      }
+   }
+   return 0;
+}
+
+double ossimBandSelector::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(theInputConnection)
+   {
+      if (theEnableFlag)
+      {
+         if(band < theOutputBandList.size())
+         {
+            return theInputConnection->
+               getMaxPixelValue(theOutputBandList[band]);
+         }
+      }
+      else
+      {
+        return theInputConnection->getMaxPixelValue(band);
+      }
+   }
+   return 1.0/DBL_EPSILON;
+}
+
+bool ossimBandSelector::saveState(ossimKeywordlist& kwl,
+                                  const char* prefix)const
+{
+   ossimString temp;
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_OUTPUT_BANDS_KW,
+           theOutputBandList.size(),
+           true);
+   
+   for(ossim_uint32 counter = 0; counter < theOutputBandList.size();counter++)
+   {
+      temp  = ossimKeywordNames::BAND_KW;
+      temp += ossimString::toString(counter+1);
+      
+      kwl.add(prefix,
+              temp.c_str(),
+              ossimString::toString(theOutputBandList[counter]+1).c_str());
+   }
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimBandSelector::loadState(const ossimKeywordlist& kwl,
+                                                  const char* prefix)
+{
+   ossimImageSourceFilter::loadState(kwl, prefix);
+
+   // call ossimSource method to delete the list of objects   
+   theOutputBandList.clear();
+   ossimString copyPrefix = prefix;
+
+   
+   ossimString regExpression =  ossimString("^(") + copyPrefix + "band[0-9]+)";
+
+   vector<ossimString> keys =
+      kwl.getSubstringKeyList( regExpression );
+   long numberOfBands = (long)keys.size();
+   int offset = (copyPrefix+"band").size();
+   int idx = 0;
+   std::vector<int> numberList(numberOfBands);
+   for(idx = 0; idx < (int)keys.size();++idx)
+     {
+       ossimString numberStr(keys[idx].begin() + offset,
+			     keys[idx].end());
+       numberList[idx] = numberStr.toInt();
+     }
+   std::sort(numberList.begin(), numberList.end());
+   for(idx=0;idx < (int)numberList.size();++idx)
+   {
+      const char* bandValue = kwl.find(copyPrefix, ("band"+ossimString::toString(numberList[idx])).c_str());
+      theOutputBandList.push_back( ossimString(bandValue).toLong()-1);
+   }
+
+   initialize();
+   
+   return true;
+}
+
+bool ossimBandSelector::isOrderedCorrectly() const
+{
+   if(theInputConnection)
+   {
+      std::vector<ossim_uint32> inputList;
+      theInputConnection->getOutputBandList(inputList);
+      
+      ossim_uint32 output_bands = theOutputBandList.size();
+
+      if(inputList.size() != output_bands) return false;
+      
+      for (ossim_uint32 i=0; i<output_bands; ++i)
+      {
+         if (inputList[i] != theOutputBandList[i]) return false;
+      }
+      return true;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimBandSelector::isOrderedCorrectly() ERROR:"
+         << "Method called prior to initialization!\n";
+   }
+
+   return false;
+}
+
+bool ossimBandSelector::outputBandsWithinInputRange() const
+{
+   if(theInputConnection)
+   {
+      const ossim_uint32 HIGHEST_BAND =
+         theInputConnection->getNumberOfOutputBands() - 1;
+      
+      const ossim_uint32 OUTPUT_BANDS = theOutputBandList.size();
+      
+      for (ossim_uint32 i=0; i<OUTPUT_BANDS; ++i)
+      {
+         if (theOutputBandList[i] > HIGHEST_BAND)
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "ossimBandSelector::outputBandsWithinInputRange() ERROR:"
+               << "Output band great than highest input band."
+               << std::endl;
+            return false;
+         }
+      }
+      return true;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimBandSelector::outputBandsWithinInputRange() ERROR:"
+         << "Method called prior to initialization!" << std::endl;
+   }
+
+   return false;
+}
+
+void ossimBandSelector::getOutputBandList(
+   std::vector<ossim_uint32>& bandList) const
+{
+   if ( theOutputBandList.size() )
+   {
+      bandList = theOutputBandList;
+   }
+   else if (theInputConnection)
+   {
+      theInputConnection->getOutputBandList(bandList);
+   }
+   else
+   {
+      bandList.clear();
+   }
+}
+
+ossimString ossimBandSelector::getLongName()const
+{
+   return ossimString("Band Selector, maps an input band to the output band.");
+}
+
+ossimString ossimBandSelector::getShortName()const
+{
+   return ossimString("Band Selector");
+}
+
+void ossimBandSelector::setProperty(ossimRefPtr<ossimProperty> property)
+{
+	ossim_uint32 i =0;
+   if(!property) return;
+
+   if(property->getName() == "Selected bands")
+   {
+     ossimString str = property->valueToString();
+     std::vector<ossimString> str_vec;
+     std::vector<ossim_uint32> int_vec;
+     
+     str.split( str_vec, "," );
+     
+     for ( i = 0; i < str_vec.size(); ++i )
+     {
+        int_vec.push_back( str_vec[i].toUInt32() );
+     }
+     setOutputBandList( int_vec );
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimBandSelector::getProperty(const ossimString& name)const
+{
+   ossim_uint32 i = 0;
+   if(name == "Selected bands")
+   {
+      std::vector<ossim_uint32> bands;
+	  
+	  getOutputBandList( bands );
+	  	  
+      std::vector<ossimString> bandNames;
+
+      for(i = 0; i < bands.size(); i++)
+      {
+         bandNames.push_back( ossimString::toString( bands[i] ) );
+      }
+	  
+	  ossimString str;
+	  
+	  str.join( bandNames, "," );
+	  
+      ossimStringProperty* stringProp = new ossimStringProperty("Selected bands", str);
+									
+      stringProp->clearChangeType();
+      stringProp->setReadOnlyFlag(false);
+      stringProp->setCacheRefreshBit();
+      
+      return stringProp;
+   }
+
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimBandSelector::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   propertyNames.push_back("Selected bands");
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandSelector.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandSelector.h
new file mode 100644
index 0000000000..a8f464120f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBandSelector.h
@@ -0,0 +1,119 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt.
+// 
+// Author:  Garrett Potts
+//
+// Description:  Contains class declaration for ossimBandSelector.
+// 
+//*******************************************************************
+//  $Id: ossimBandSelector.h,v 1.10 2005/12/19 20:01:37 dburken Exp $
+#ifndef ossimBandSelector_HEADER
+#define ossimBandSelector_HEADER
+
+#include <vector>
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimImageData;
+
+class OSSIMDLLEXPORT ossimBandSelector : public ossimImageSourceFilter
+{
+   
+public:
+   ossimBandSelector();
+   
+   virtual ~ossimBandSelector();
+   
+   virtual ossimString getLongName()  const;
+   virtual ossimString getShortName() const;
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+   /**
+    * Initializes bandList to the zero based order of output bands.
+    */
+   virtual void getOutputBandList(std::vector<ossim_uint32>& bandList) const;
+
+   /**
+    * Sets the output band list.
+    *
+    * @param outputBandList List of zero based bands.
+    *
+    * @note The input connection should be established prior to calling this.
+    *
+    * @note Bands can be duplicated.  So if you have a single band input you
+    * can do a band list like "1, 1, 1".   Any band within the list must be
+    * available from the input.  So if you have a 3 band input bands must be
+    * constrained to zero based bands "0, 1, or 2".
+    *
+    * @note Calling this method does not enable filter so callers should do:
+    * theBandSelector->enableSource();
+    * theBandSelector->setOutputBandList(bandList);
+    */
+   virtual void setOutputBandList(const vector<ossim_uint32>& outputBandList);
+   
+   /**
+    * Returns the number of bands in a tile returned from this TileSource.
+    */
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+
+   virtual void initialize();
+   
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+   /**
+    *   Override base class so that a disableSource event does not
+    *   reinitialize the object and enable itself.
+    */
+   //virtual void propertyEvent(ossimPropertyEvent& event);
+   //virtual void refreshEvent(ossimRefreshEvent& event);   
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;						  
+						  
+   
+private:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+
+   /**
+    * @return true if theInputConnection->getOutputBandList is equal to
+    * this->theOutputBandList, false if not.
+    */
+   bool isOrderedCorrectly() const;
+
+   /**
+    * @return true if all bands in theOutputBandList are less than the
+    * number of input's bands.
+    */
+   bool outputBandsWithinInputRange() const;
+   
+   
+   ossimRefPtr<ossimImageData> theTile;
+   vector<ossim_uint32>        theOutputBandList;
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBlendMosaic.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBlendMosaic.cpp
new file mode 100644
index 0000000000..657f2dd40f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBlendMosaic.cpp
@@ -0,0 +1,624 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBlendMosaic.cpp,v 1.37 2005/06/30 15:14:57 gpotts Exp $
+
+#include <imaging/tile_sources/ossimBlendMosaic.h>
+#include <imaging/ossimImageData.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF1(ossimBlendMosaic, "ossimBlendMosaic", ossimImageMosaic)
+
+ossimBlendMosaic::ossimBlendMosaic()
+   : ossimImageMosaic(),
+     theNormResult(NULL)
+{
+}
+
+ossimBlendMosaic::ossimBlendMosaic(vector<ossimImageSource*>& inputSources)
+   : ossimImageMosaic(inputSources),
+     theNormResult(NULL)
+{
+   initialize();
+}
+
+ossimBlendMosaic::~ossimBlendMosaic()
+{
+}
+
+void ossimBlendMosaic::initialize()
+{   
+   ossimImageMosaic::initialize();
+
+   allocate();
+
+   //   if(theTile)
+   //   {
+   // let's first check to see if all input scalars are the same.
+   // if they are then we will not have to normalize.  Normalizing
+   // is slow and I only want to do it if we have to.
+   //
+      
+   // only allocate this space if we have to
+   if(hasDifferentInputs())
+   {
+      theNormResult = new ossimImageData(this,
+                                         OSSIM_NORMALIZED_FLOAT,
+                                         theLargestNumberOfInputBands);
+      theNormResult->initialize();
+   }
+      
+   if(theWeights.size() < theInputObjectList.size())
+   {
+      for(ossim_uint32 index =theWeights.size();
+          index < theInputObjectList.size();
+          ++index)
+      {
+         theWeights.push_back(1.0);
+      }
+   }
+   //   }
+}
+
+ossimRefPtr<ossimImageData> ossimBlendMosaic::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{   
+   long w = tileRect.width();
+   long h = tileRect.height();
+   ossimIpt origin = tileRect.ul();
+   if(!isSourceEnabled())
+   {
+      return ossimImageMosaic::getTile(tileRect, resLevel);
+   }
+   
+   ossim_uint32 size = getNumberOfInputs();
+   if(!theTile.get())
+   {
+      // try to initialize
+      initialize();
+
+      // if we still don't have a buffer
+      // then we will leave
+      if(!theTile.get())
+      {
+         return theTile;
+      }
+   }
+
+   if(size == 0)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+   if(size == 1)
+   {
+      return ossimImageMosaic::getTile(tileRect, resLevel);
+   }
+
+   long tileW = theTile->getWidth();
+   long tileH = theTile->getHeight();
+   if((w != tileW)||
+      (h != tileH))
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if(hasDifferentInputs())
+      {
+         theNormResult->setWidthHeight(w, h);
+      }
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+            
+         if(hasDifferentInputs())
+         {
+            theNormResult->initialize();
+         }
+      }
+   }
+   theTile->setOrigin(origin);
+   theTile->makeBlank();
+   
+   switch(theTile->getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_uint8>(0), tileRect, resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_uint8>(0), tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SINT8:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_sint8>(0), tileRect, resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_sint8>(0), tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_FLOAT32: 
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<float>(0), tileRect, resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<float>(0), tileRect, resLevel);
+         }
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_uint16>(0), tileRect, resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_uint16>(0), tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SINT16:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_sint16>(0), tileRect, resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_sint16>(0), tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SINT32:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_sint32>(0), tileRect, resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_sint32>(0), tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_UINT32:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_uint32>(0), tileRect, resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_uint32>(0), tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<double>(0), tileRect, resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<double>(0), tileRect, resLevel);
+         }
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimBlendMosaic::getTile NOTICE:\n"
+            << "Scalar type = " << theTile->getScalarType()
+            << " Not supported by ossimImageMosaic" << endl;
+       }
+   }
+
+   return ossimRefPtr<ossimImageData>();   
+}
+
+template <class T> ossimRefPtr<ossimImageData> ossimBlendMosaic::combine(
+   T,
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+  ossimRefPtr<ossimImageData> currentImageData=NULL;
+  ossim_uint32 band;
+  double currentWeight = 1.0;
+  double previousWeight = 1.0;
+  double sumOfWeights   = 1;
+  long offset = 0;
+  long row    = 0;
+  long col    = 0;
+  
+  currentImageData = getNextTile(0, tileRect, resLevel);
+  
+  if(!currentImageData.get()) // if we don't have one then return theTile
+    {
+      return theTile;
+    }
+
+  T** srcBands  = new T*[theLargestNumberOfInputBands];
+  T** destBands = new T*[theLargestNumberOfInputBands];
+  T*  nullPix   = new T[theTile->getNumberOfBands()];
+  
+  previousWeight = theWeights[theCurrentIndex];
+  //    // now get the previous weight and then combine the two into one.
+	 // let's assign the bands
+  for(band = 0; band < theLargestNumberOfInputBands; ++band)
+  {
+     destBands[band] = static_cast<T*>(theTile->getBuf(band));
+     nullPix[band]   = static_cast<T>(theTile->getNullPix(band));
+  }
+  while(currentImageData.get())
+  {
+      ossimDataObjectStatus currentStatus =
+         currentImageData->getDataObjectStatus();
+      
+      // set the current weight for the current tile.
+      currentWeight = theWeights[theCurrentIndex];
+
+      sumOfWeights = previousWeight+currentWeight;
+      if( (currentStatus != OSSIM_EMPTY) &&
+	  (currentStatus != OSSIM_NULL))
+       {	 
+	 long h = (long)currentImageData->getHeight();
+	 long w = (long)currentImageData->getWidth();
+	 offset = 0;
+	 ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
+	 
+	 // let's assign the bands
+	 for(band = 0; band < minNumberOfBands; ++band)
+	   {
+	     srcBands[band]  = static_cast<T*>(currentImageData->getBuf(band));
+	   }
+	 for(;band < theLargestNumberOfInputBands; ++band)
+	   {
+	     srcBands[band]  = srcBands[minNumberOfBands - 1];
+	   }
+
+ 	 if(currentStatus == OSSIM_PARTIAL)
+         {
+            for(row = 0; row < h; ++row)
+            {
+               for(col = 0; col < w; ++col)
+               {
+                  if(!currentImageData->isNull(offset))
+                  {
+                     for(band = 0; band < theLargestNumberOfInputBands; ++band)
+                     {
+                        if(destBands[band][offset] != nullPix[band])
+                        {
+//                            destBands[band][offset] = static_cast<T>((destBands[band][offset]*(1.0-currentWeight) +  
+//                                                                      srcBands[band][offset]*currentWeight));
+                           destBands[band][offset] = static_cast<T>((destBands[band][offset]*previousWeight + 
+                                                                     srcBands[band][offset]*currentWeight)/(previousWeight+currentWeight));
+                        }
+                        else
+                        {
+                           destBands[band][offset] = srcBands[band][offset];
+                        }
+                     }	 
+                  }
+                  ++offset;
+               }
+            }
+         }
+	 else
+         {
+            for(row = 0; row < h; ++row)
+            {
+               for(col = 0; col < w; ++col)
+               {
+                  for(band = 0; band < theLargestNumberOfInputBands; ++band)
+                  {			
+                     if(destBands[band][offset] != nullPix[band])
+                     {
+                        destBands[band][offset] = static_cast<T>((destBands[band][offset]*previousWeight+ 
+                                                                  srcBands[band][offset]*currentWeight)/(previousWeight + currentWeight));
+                     }
+                     else
+                     {
+                        destBands[band][offset] = srcBands[band][offset];
+                     }
+                  }
+                  ++offset;
+               }
+            }
+         }
+       }
+      currentImageData = getNextTile(tileRect, resLevel);
+      previousWeight   = (previousWeight+currentWeight)/2.0;
+    }
+  delete [] srcBands;
+  delete [] destBands;
+  delete [] nullPix;
+  theTile->validate();
+
+  return theTile;   
+}
+
+template <class T> ossimRefPtr<ossimImageData> ossimBlendMosaic::combineNorm(
+   T,
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+  ossimRefPtr<ossimImageData> currentImageData=NULL;
+  ossim_uint32 band;
+  double currentWeight = 1.0;
+  double previousWeight = 1.0;
+  double sumOfWeights   = 1;
+  long offset = 0;
+  long row    = 0;
+  long col    = 0;
+  
+  currentImageData = getNextNormTile(0, tileRect, resLevel);
+  
+  if(!currentImageData.get()) // if we don't have one then return theTile
+  {
+     return theTile;
+  }
+  theNormResult->makeBlank();
+  float** srcBands  = new float*[theLargestNumberOfInputBands];
+  float** destBands = new float*[theLargestNumberOfInputBands];
+  float*  nullPix   = new float[theTile->getNumberOfBands()];
+  
+  previousWeight = theWeights[theCurrentIndex];
+  //    // now get the previous weight and then combine the two into one.
+  // let's assign the bands
+  for(band = 0; band < theLargestNumberOfInputBands; ++band)
+  {
+     destBands[band] = static_cast<float*>(theNormResult->getBuf(band));
+     nullPix[band]   = static_cast<float>(theNormResult->getNullPix(band));
+  }
+  while(currentImageData.get())
+  {
+     ossimDataObjectStatus currentStatus     = currentImageData->getDataObjectStatus();
+     
+     // set the current weight for the current tile.
+     currentWeight = theWeights[theCurrentIndex];
+     
+     sumOfWeights = previousWeight+currentWeight;
+     if( (currentStatus != OSSIM_EMPTY) &&
+         (currentStatus != OSSIM_NULL))
+     {	 
+        long h = (long)currentImageData->getHeight();
+        long w = (long)currentImageData->getWidth();
+        offset = 0;
+        ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
+        
+        // let's assign the bands
+        for(band = 0; band < minNumberOfBands; ++band)
+        {
+           srcBands[band]  = static_cast<float*>(currentImageData->getBuf(band));
+        }
+        for(;band < theLargestNumberOfInputBands; ++band)
+        {
+           srcBands[band]  = srcBands[minNumberOfBands - 1];
+        }
+        
+        if(currentStatus == OSSIM_PARTIAL)
+        {
+           for(row = 0; row < h; ++row)
+           {
+              for(col = 0; col < w; ++col)
+              {
+                 if(!currentImageData->isNull(offset))
+                 {
+                    for(band = 0; band < theLargestNumberOfInputBands; ++band)
+                    {
+                       if(destBands[band][offset] != nullPix[band])
+                       {
+                          destBands[band][offset] = static_cast<float>((destBands[band][offset]*previousWeight + 
+                                                                        srcBands[band][offset]*currentWeight)/(previousWeight+currentWeight));
+                       }
+                       else
+                       {
+                          destBands[band][offset] = srcBands[band][offset];
+                       }
+                    }	 
+                 }
+                 ++offset;
+              }
+           }
+        }
+        else
+        {
+           for(row = 0; row < h; ++row)
+           {
+              for(col = 0; col < w; ++col)
+              {
+                 for(band = 0; band < theLargestNumberOfInputBands; ++band)
+                 {			
+                    if(destBands[band][offset] != nullPix[band])
+                    {
+                       destBands[band][offset] = static_cast<float>((destBands[band][offset]*previousWeight+ 
+                                                                     srcBands[band][offset]*currentWeight)/(previousWeight + currentWeight));
+                    }
+                    else
+                    {
+                       destBands[band][offset] = srcBands[band][offset];
+                    }
+                 }
+                  ++offset;
+              }
+           }
+        }
+     }
+     currentImageData = getNextNormTile(tileRect, resLevel);
+     previousWeight   = (previousWeight+currentWeight)/2.0;
+  }
+  theNormResult->validate();
+  theTile->copyNormalizedBufferToTile((float*)theNormResult->getBuf());
+  delete [] srcBands;
+  delete [] destBands;
+  delete [] nullPix;
+  theTile->validate();
+
+  return theTile;   
+}
+
+bool ossimBlendMosaic::saveState(ossimKeywordlist& kwl,
+                                 const char* prefix)const
+{
+   bool result = ossimImageMosaic::saveState(kwl, prefix);
+
+   ossimString copyPrefix    = prefix;
+   for(ossim_uint32 index = 0; index < theWeights.size(); ++index)
+   {
+      ossimString weightStr = ossimString("weight") +
+                              ossimString::toString(index);
+      kwl.add(copyPrefix.c_str(),
+              weightStr.c_str(),
+              theWeights[index],
+              true);
+   }
+   
+   return result;
+}
+
+bool ossimBlendMosaic::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   bool result = ossimImageMosaic::loadState(kwl, prefix);
+   long count = 0;
+   theWeights.clear();
+   if(result)
+   {
+      ossimString copyPrefix    = prefix;
+      ossimString regExpression =  ossimString("^(") + copyPrefix + "weight[0-9]+)";
+      long result = kwl.getNumberOfSubstringKeys(regExpression);
+            
+      long numberOfMatches = 0;
+      while(numberOfMatches < result)
+      {
+         ossimString value = ossimString("weight") + ossimString::toString(count);
+
+         const char* lookup = kwl.find(copyPrefix.c_str(),
+                                       value.c_str());
+         
+         if(lookup)
+         {
+            ++numberOfMatches;
+            theWeights.push_back(ossimString(lookup).toDouble());
+         }
+
+         ++count;
+      }
+   }
+   
+   return result;
+}
+
+
+void ossimBlendMosaic::setNumberOfWeights(ossim_uint32 numberOfWeights)
+{
+   if(numberOfWeights > theWeights.size())
+   {
+      ossim_uint32 length = numberOfWeights - theWeights.size();
+      for(ossim_uint32 index= 0; index < length; ++ index)
+      {
+         theWeights.push_back(1.0);
+      }
+   }
+   else if(numberOfWeights < theWeights.size())
+   {
+      // copy the list
+      vector<double> temp(theWeights.begin(),
+                          theWeights.begin()+numberOfWeights);
+      // now shrink
+      theWeights = temp;
+   }
+}
+
+void ossimBlendMosaic::setAllWeightsTo(double value)
+{
+   for(ossim_uint32 index = 0; index < theWeights.size(); ++index)
+   {
+      theWeights[index] = value;
+   }
+}
+
+void ossimBlendMosaic::normalizeWeights()
+{
+  double sumWeights=0.0;
+  ossim_uint32 index = 0;
+  for(index = 0; index < theWeights.size(); ++index)
+    {
+      sumWeights+=theWeights[index];
+    }
+  if(sumWeights > 0.0)
+    {
+      for(index = 0; index < theWeights.size(); ++index)
+	{
+	  theWeights[index] /= sumWeights;
+	}
+    }
+}
+
+void ossimBlendMosaic::findMinMax(double& minValue, double& maxValue)const
+{
+   if(theWeights.size() > 0)
+   {
+      minValue = maxValue = theWeights[0];
+
+      for(ossim_uint32 index = 1; index < theWeights.size(); ++index)
+      {
+         minValue = minValue < theWeights[index]?minValue:theWeights[index];
+         maxValue = maxValue > theWeights[index]?maxValue:theWeights[index];
+      }
+   }
+}
+
+void ossimBlendMosaic::setWeight(ossim_uint32 index, double weight)
+{
+   if(index < theWeights.size())
+   {
+      theWeights[index] = weight;
+   }
+}
+
+void ossimBlendMosaic::setWeights(const std::vector<double>& weights)
+{
+   theWeights = weights;
+}
+
+const vector<double>& ossimBlendMosaic::getWeights()const
+{
+   return theWeights;
+}
+
+double ossimBlendMosaic::getWeight(ossim_uint32 index) const
+{
+   if(index < theWeights.size())
+   {
+      return theWeights[index];
+   }
+   if(theWeights.size())
+   {
+      return theWeights[theWeights.size()-1];
+   }
+   return 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBlendMosaic.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBlendMosaic.h
new file mode 100644
index 0000000000..9a6b1a9efe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBlendMosaic.h
@@ -0,0 +1,78 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBlendMosaic.h,v 1.22 2005/02/11 15:07:32 dburken Exp $
+#ifndef ossimBlendMosaic_HEADER
+#define ossimBlendMosaic_HEADER
+#include <imaging/tile_sources/ossimImageMosaic.h>
+
+class OSSIMDLLEXPORT ossimBlendMosaic : public ossimImageMosaic
+{
+public:
+   ossimBlendMosaic();
+   ossimBlendMosaic(vector<ossimImageSource*>& inputSources);
+   virtual ~ossimBlendMosaic();
+   virtual void initialize();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                               ossim_uint32 resLevel=0);
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+
+   void setWeight(ossim_uint32 index, double weight);
+   void setWeights(const std::vector<double>& weights);
+   
+   double getWeight(ossim_uint32 index) const;
+   const std::vector<double>& getWeights()const;
+
+
+   void setNumberOfWeights(ossim_uint32 numberOfWeights);
+   void setAllWeightsTo(double value);
+   
+   /**
+    * Will find the min and max values and then
+    * normalize all weights to be from 0 to 1
+    */
+   void normalizeWeights();
+   void findMinMax(double& minValue, double& maxValue)const;
+   
+protected:
+   vector<double>              theWeights;
+   ossimRefPtr<ossimImageData> theNormResult;
+   /**
+    * If our inputs have output of different scalar
+    * types then we must normalize so we can blend
+    * different scalar data together.
+    */
+   
+
+   template <class T>
+      ossimRefPtr<ossimImageData> combine(T,
+                                          const ossimIrect& tileRect,
+                                          ossim_uint32);
+   template <class T>
+      ossimRefPtr<ossimImageData> combineNorm(T,
+                                              const ossimIrect& tileRect,
+                                              ossim_uint32);
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimBlendMosaic_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessContrastSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessContrastSource.cpp
new file mode 100644
index 0000000000..a34273f751
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessContrastSource.cpp
@@ -0,0 +1,314 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+// 
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimBrightnessContrastSource.cpp,v 1.21 2005/12/02 20:03:46 dburken Exp $
+
+#include <imaging/tile_sources/ossimBrightnessContrastSource.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/color_space/ossimHsiVector.h>
+#include <base/data_types/color_space/ossimNormRgbVector.h>
+#include <base/property/ossimContainerProperty.h>
+#include <base/property/ossimNumericProperty.h>
+
+RTTI_DEF1(ossimBrightnessContrastSource,
+          "ossimBrightnessContrastSource",
+          ossimImageSourceFilter)
+   
+ossimBrightnessContrastSource::ossimBrightnessContrastSource()
+   :ossimImageSourceFilter(),
+    theBrightness(0.0),
+    theContrast(1.0)
+{  
+}
+
+
+ossimBrightnessContrastSource::~ossimBrightnessContrastSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimBrightnessContrastSource::getTile(
+   const ossimIrect& tileRect, ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> tile = NULL;
+
+   if(theInputConnection)
+   {
+      tile = theInputConnection->getTile(tileRect, resLevel);
+      
+      if(!tile.valid())
+      {
+         return tile;
+      }
+
+      if(!isSourceEnabled() ||
+         (tile->getDataObjectStatus()==OSSIM_NULL)||
+         (tile->getDataObjectStatus()==OSSIM_EMPTY)||
+         ( (theBrightness == 0.0) && (theContrast   == 1.0) ) )
+      {
+         return tile;
+      }
+
+      if(!theTile.valid() || !theNormTile.valid())
+      {
+         allocate();
+      }
+      
+      if(!theTile.valid() || !theNormTile.valid())
+      {
+         return tile;
+      }
+
+      theTile->setImageRectangle(tileRect);
+      theNormTile->setImageRectangle(tileRect);
+
+      tile->copyTileToNormalizedBuffer((ossim_float32*)theNormTile->getBuf());
+      theNormTile->setDataObjectStatus(tile->getDataObjectStatus());
+
+      if (theNormTile->getNumberOfBands() == 3)
+      {
+         processRgbTile();
+      }
+      else
+      {
+         processNBandTile();
+      }
+      
+      theTile->copyNormalizedBufferToTile((ossim_float32*)
+                                          theNormTile->getBuf());
+      theTile->validate();
+      return theTile;
+   }
+   
+   return tile;
+}
+
+void ossimBrightnessContrastSource::processRgbTile()
+{
+   ossim_float32* bands[3];
+
+   bands[0] = (ossim_float32*)theNormTile->getBuf(0);
+   bands[1] = (ossim_float32*)theNormTile->getBuf(1);
+   bands[2] = (ossim_float32*)theNormTile->getBuf(2);
+
+   ossim_uint32 offset = 0;
+   ossim_uint32 maxIdx = theNormTile->getWidth()*theNormTile->getHeight();
+   ossimHsiVector hsi;
+   ossim_float32 i;
+   if(theNormTile->getDataObjectStatus() == OSSIM_FULL)
+   {
+      for(offset = 0; offset < maxIdx; ++offset)
+      {
+         ossimNormRgbVector rgb(bands[0][offset], bands[1][offset], bands[2][offset]);
+         hsi = rgb;
+         i = (hsi.getI()*theContrast + theBrightness);
+         if(i < OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT) i = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
+         if(i > 1.0) i = 1.0;
+         hsi.setI(i);
+         rgb = hsi;
+         bands[0][offset] = rgb.getR();
+         bands[1][offset] = rgb.getG();
+         bands[2][offset] = rgb.getB();
+      }
+   }
+   else
+   {
+      for(offset = 0; offset < maxIdx; ++offset)
+      {
+         if((bands[0][offset] != 0.0)&&
+            (bands[1][offset] != 0.0)&&
+            (bands[2][offset] != 0.0))
+         {
+            ossimNormRgbVector rgb(bands[0][offset], bands[1][offset], bands[2][offset]);
+            hsi = rgb;
+            i = (hsi.getI()*theContrast + theBrightness);
+            if(i < OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT) i = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
+            if(i > 1.0) i = 1.0;
+            hsi.setI(i);
+            rgb = hsi;
+            bands[0][offset] = rgb.getR();
+            bands[1][offset] = rgb.getG();
+            bands[2][offset] = rgb.getB();
+         }
+      }
+   }
+}
+
+void ossimBrightnessContrastSource::processNBandTile()
+{
+   const ossim_uint32  BANDS = theNormTile->getNumberOfBands();
+   const ossim_uint32  PPB   = theNormTile->getSizePerBand();
+   const ossim_float32 MP    = theNormTile->getMinNormalizedPix();
+   
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      ossim_float32* buf = theNormTile->getFloatBuf(band);
+
+      for (ossim_uint32 i = 0; i < PPB; ++i)
+      {
+         if (buf[i] != 0.0)
+         {
+            ossim_float32 p = buf[i] * theContrast + theBrightness;
+            buf[i] = (p < 1.0) ? ( (p > MP) ? p : 0.0 ) : 1.0;
+         }
+      }
+   }
+}
+
+void ossimBrightnessContrastSource::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   theTile     = 0;
+   theNormTile = 0;
+}
+
+void ossimBrightnessContrastSource::allocate()
+{
+   if( isSourceEnabled() && theInputConnection )
+   {
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+      if(theTile.valid())
+      {
+         theNormTile = ossimImageDataFactory::instance()->create(this,
+                                                                 OSSIM_FLOAT32,
+                                                                 theTile->getNumberOfBands());
+      }
+      if(theTile.valid() && theNormTile.valid())
+      {
+         theTile->initialize();
+         theNormTile->initialize();
+      }
+      else
+      {
+         theTile     = 0;
+         theNormTile = 0;
+      }
+   }
+}
+
+void ossimBrightnessContrastSource::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property)
+   {
+      return;
+   }
+   ossimString name = property->getName();
+   if(name == "brightness")
+   {
+      theBrightness = property->valueToString().toDouble();
+   }
+   else if(name == "contrast")
+   {
+      theContrast = property->valueToString().toDouble();
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimBrightnessContrastSource::getProperty(const ossimString& name)const
+{
+   if(name == "brightness")
+   {
+      ossimNumericProperty* numeric = new ossimNumericProperty(name,
+                                                               ossimString::toString(getBrightness()),
+                                                               -1.0, 1.0);
+      numeric->setNumericType(ossimNumericProperty::ossimNumericPropertyType_FLOAT64);
+      numeric->setCacheRefreshBit();
+      return numeric;
+   }
+   else if(name == "contrast")
+   {
+      ossimNumericProperty* numeric = new ossimNumericProperty(name,
+                                                               ossimString::toString(getContrast()),
+                                                               0.0, 20.0);
+      numeric->setNumericType(ossimNumericProperty::ossimNumericPropertyType_FLOAT64);
+      numeric->setCacheRefreshBit();
+      return numeric;
+   }
+
+    return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimBrightnessContrastSource::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   
+   propertyNames.push_back("brightness");
+   propertyNames.push_back("contrast");
+}
+
+
+bool ossimBrightnessContrastSource::loadState(const ossimKeywordlist& kwl,
+                                              const char* prefix)
+{
+   const char* brightness = kwl.find(prefix, "brightness");
+   const char* contrast = kwl.find(prefix, "contrast");
+
+   if(brightness)
+   {
+      theBrightness = ossimString(brightness).toDouble();
+   }
+   if(contrast)
+   {
+      theContrast   = ossimString(contrast).toDouble();
+   }
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimBrightnessContrastSource::saveState(ossimKeywordlist& kwl,
+                                              const char* prefix)const
+{
+   kwl.add(prefix,
+           "brightness",
+           theBrightness,
+           true);
+   kwl.add(prefix,
+           "contrast",
+           theContrast,
+           true);
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);   
+}
+
+
+void ossimBrightnessContrastSource::setBrightnessContrast(
+   ossim_float64 brightness, ossim_float64 contrast)
+{
+   theBrightness = brightness;
+   theContrast   = contrast;
+}
+
+void ossimBrightnessContrastSource::setBrightness(ossim_float64 brightness)
+{
+   setBrightnessContrast(brightness, getContrast());
+}
+
+void ossimBrightnessContrastSource::setContrast(ossim_float64 contrast)
+{
+   setBrightnessContrast(getBrightness(), contrast);
+}
+
+ossim_float64 ossimBrightnessContrastSource::getBrightness()const
+{
+   return theBrightness;
+}
+
+ossim_float64 ossimBrightnessContrastSource::getContrast()const
+{
+   return theContrast;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessContrastSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessContrastSource.h
new file mode 100644
index 0000000000..6c2d1bc28b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessContrastSource.h
@@ -0,0 +1,132 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// Author: Garrett Potts
+// 
+//*************************************************************************
+// $Id: ossimBrightnessContrastSource.h,v 1.18 2005/12/02 20:01:15 dburken Exp $
+#ifndef ossimBrightnessContrastSource_HEADER
+#define ossimBrightnessContrastSource_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class OSSIM_DLL ossimBrightnessContrastSource : public ossimImageSourceFilter
+{
+public:
+
+   /**
+    * Currently works in hsi space so must be one or three bands.
+    *
+    * Todo: Make work with nband.
+    */
+   ossimBrightnessContrastSource();
+
+   virtual ~ossimBrightnessContrastSource();
+
+   /**
+    * Will apply the algorithm:
+    *       i*c + b
+    *           where b is brightnes
+    *                 c is contrast
+    *                 i is the input value.
+    *
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+   /**
+    * @param brightness Value between -1.0 and +1.0 with zero being no
+    * brightness offset.
+    *
+    * @param contrast Value between 0.0 and 2.0 with 1.0 being no contrast
+    * adjustment.
+    */
+   virtual void setBrightnessContrast(ossim_float64 brightness,
+                                      ossim_float64 contrast);
+   
+   /**
+    * @param brightness Value between -1.0 and +1.0 with zero being no
+    * brightness offset.
+    */
+   virtual void setBrightness(ossim_float64 brightness);
+
+   /**
+    * @param contrast Value between 0.0 and 2.0 with 1.0 being no contrast
+    * adjustment.
+    */
+   virtual void setContrast(ossim_float64 contrast);
+
+   /** @return Brightness value between -1.0 and +1.0. */
+   virtual ossim_float64 getBrightness()const;
+
+   /** @return Contrast value between 0.0 and +2.0. */
+   virtual ossim_float64 getContrast()const;
+
+   /**
+    * Calls base ossimImageSourceFilter::initialize() to reset connection if
+    * needed then nulls out tiles.
+    *
+    * @note This does not initialize tiles intentionally to avoid repeated
+    * deletes and news.  Tiles will be initialized by allocate() method on
+    * the first getTile call after an initialize.
+    */
+   virtual void initialize();
+   
+   /*---------------------- PROPERTY INTERFACE ---------------------------*/
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   /*--------------------- PROPERTY INTERFACE END ------------------------*/
+
+   /**
+    * Keywords searched for by this method.
+    *
+    * brightness: 0.0
+    *
+    * contrast:  1.0
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * Keywords saved to list by this method.
+    *
+    * brightness: 0.0
+    *
+    * contrast:  1.0
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+protected:
+
+   /**
+    * Called to initialize tiles by first get tile when theTile or theNormTile
+    * are not initialized.
+    */
+   void allocate();
+
+   /**
+    * Applies the brightness contrast to tile.  This method works in hsi
+    * space on the intensity channel; thus, preserving hue and saturation
+    * of an rgb pixel.  Called if input has three bands.
+    */
+   void processRgbTile();
+
+   /**
+    * Applies the brightness contrast to tile.  This method simply applies
+    * brightness contrast to all bands.  Called if input does not have
+    * three bands.
+    */
+   void processNBandTile();
+   
+   
+   ossim_float64               theBrightness;  
+   ossim_float64               theContrast;  
+   ossimRefPtr<ossimImageData> theTile;
+   ossimRefPtr<ossimImageData> theNormTile;
+   
+TYPE_DATA
+};
+
+#endif /* End of "#ifndef ossimBrightnessContrastSource_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessMatch.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessMatch.cpp
new file mode 100644
index 0000000000..a85c3553ea
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessMatch.cpp
@@ -0,0 +1,247 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimBrightnessMatch.cpp,v 1.2 2005/09/08 14:14:55 gpotts Exp $
+
+#include <imaging/tile_sources/ossimBrightnessMatch.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/color_space/ossimNormRgbVector.h>
+#include <base/data_types/color_space/ossimHsiVector.h>
+#include <base/property/ossimContainerProperty.h>
+#include <base/property/ossimNumericProperty.h>
+
+RTTI_DEF1(ossimBrightnessMatch,
+          "ossimBrightnessMatch",
+          ossimImageSourceFilter)
+   
+ossimBrightnessMatch::ossimBrightnessMatch()
+   :ossimImageSourceFilter(),
+    theTargetBrightness(0.5),
+    theInputBrightness(0.5)
+{
+   theInputBrightness = OSSIM_DBL_NAN;
+   theBrightnessContrastSource = new ossimBrightnessContrastSource;
+}
+
+
+ossimBrightnessMatch::~ossimBrightnessMatch()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimBrightnessMatch::getTile(
+   const ossimIrect& tileRect, ossim_uint32 resLevel)
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getTile(tileRect, resLevel);
+   }
+   if(theInputConnection)
+   {
+      if(theInputBrightness == OSSIM_DBL_NAN)
+      {
+         computeInputBrightness();
+      }
+      return theBrightnessContrastSource->getTile(tileRect, resLevel);
+   }
+   return 0;
+}
+
+void ossimBrightnessMatch::initialize()
+{
+   theBrightnessContrastSource->connectMyInputTo(0, getInput());
+   theNormTile = 0;
+}
+
+void ossimBrightnessMatch::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property)
+   {
+      return;
+   }
+   ossimString name = property->getName();
+   if(name == "input_brightness")
+   {
+      theInputBrightness = property->valueToString().toDouble();
+      theBrightnessContrastSource->setBrightness(theTargetBrightness-theInputBrightness);
+   }
+   else if(name == "target_brightness")
+   {
+      theTargetBrightness = property->valueToString().toDouble();
+      theBrightnessContrastSource->setBrightness(theTargetBrightness-theInputBrightness);
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimBrightnessMatch::getProperty(const ossimString& name)const
+{
+   if(name == "target_brightness")
+   {
+      ossimNumericProperty* numeric = new ossimNumericProperty(name,
+                                                               ossimString::toString(theTargetBrightness),
+                                                               0.0, 1.0);
+      numeric->setNumericType(ossimNumericProperty::ossimNumericPropertyType_FLOAT64);
+      numeric->setCacheRefreshBit();
+      return numeric;
+   }
+   else if(name == "input_brightness")
+   {
+      ossimNumericProperty* numeric = new ossimNumericProperty(name,
+                                                               ossimString::toString(theInputBrightness),
+                                                               0.0, 1.0);
+      numeric->setNumericType(ossimNumericProperty::ossimNumericPropertyType_FLOAT64);
+      numeric->setCacheRefreshBit();
+      return numeric;
+   }
+
+    return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimBrightnessMatch::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   
+   propertyNames.push_back("input_brightness");
+   propertyNames.push_back("target_brightness");
+}
+
+
+bool ossimBrightnessMatch::loadState(const ossimKeywordlist& kwl,
+                                              const char* prefix)
+{
+   const char* input_brightness = kwl.find(prefix, "input_brightness");
+   const char* target_brightness = kwl.find(prefix, "target_brightness");
+
+   if(input_brightness)
+   {
+      theInputBrightness = ossimString(input_brightness).toDouble();
+   }
+   if(target_brightness)
+   {
+      theTargetBrightness = ossimString(target_brightness).toDouble();
+   }
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimBrightnessMatch::saveState(ossimKeywordlist& kwl,
+                                              const char* prefix)const
+{
+   kwl.add(prefix,
+           "input_brightness",
+           theInputBrightness,
+           true);
+   kwl.add(prefix,
+           "target_brightness",
+           theTargetBrightness,
+            true);
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);   
+}
+
+
+void ossimBrightnessMatch::computeInputBrightness()
+{
+   if(theInputConnection)
+   {
+      ossimIrect inputRect = getBoundingRect();
+      ossim_uint32 rlevel = 0;
+      ossim_uint32 nlevels = getNumberOfDecimationLevels();
+      if(nlevels>1)
+      {
+         while((ossimMax(inputRect.width(), inputRect.height()) > 2048)&&
+               (rlevel < nlevels))
+         {
+            ++rlevel;
+            inputRect = getBoundingRect(rlevel);
+         }
+      }
+      ossimIpt centerPt = inputRect.midPoint();
+      centerPt.x -= 1024;
+      centerPt.y -= 1024;
+      ossimIrect reqRect(centerPt.x,
+                         centerPt.y,
+                         centerPt.x + 2047,
+                         centerPt.x + 2047);
+      reqRect = reqRect.clipToRect(inputRect);
+      ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(reqRect, rlevel);
+
+      if(inputTile.valid())
+      {
+         theNormTile = new ossimImageData(0,
+                                          OSSIM_FLOAT32,
+                                          inputTile->getNumberOfBands());
+         theNormTile->initialize();
+         theNormTile->setImageRectangle(reqRect);
+         inputTile->copyTileToNormalizedBuffer((ossim_float32*)theNormTile->getBuf());
+         theNormTile->setDataObjectStatus(inputTile->getDataObjectStatus());
+         ossim_uint32 maxIdx = theNormTile->getWidth()*theNormTile->getHeight();
+         ossim_float32* bands[3];
+         double averageI = 0.0;
+         double count = 0.0;
+         ossim_uint32 offset = 0;
+         
+         bands[0] = (ossim_float32*)theNormTile->getBuf();
+         if(theNormTile->getNumberOfBands()>2)
+         {
+            bands[1] = (ossim_float32*)theNormTile->getBuf(1);
+            bands[2] = (ossim_float32*)theNormTile->getBuf(2);
+         }
+         else
+         {
+            bands[1] = bands[0];
+            bands[2] = bands[0];
+         }
+         ossimHsiVector hsi;
+         if(theNormTile->getDataObjectStatus() == OSSIM_FULL)
+         {
+            count = maxIdx;
+            
+            for(offset = 0; offset < maxIdx; ++offset)
+            {
+               hsi = ossimNormRgbVector(bands[0][offset], bands[1][offset], bands[2][offset]);
+               
+               averageI += hsi.getI();
+            }
+         }
+         else
+         {
+            for(offset = 0; offset < maxIdx; ++offset)
+            {
+               if((bands[0][offset] != 0.0)&&
+                  (bands[1][offset] != 0.0)&&
+                  (bands[2][offset] != 0.0))
+               {
+                  hsi = ossimNormRgbVector(bands[0][offset], bands[1][offset], bands[2][offset]);
+                  averageI += hsi.getI();
+                  
+                  ++count;
+               }
+            }
+         }
+         theInputBrightness = averageI / count;
+         theBrightnessContrastSource->setBrightness(theTargetBrightness-theInputBrightness);
+      }
+      else
+      {
+         theInputBrightness = .5;
+      }
+   }
+   theNormTile = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessMatch.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessMatch.h
new file mode 100644
index 0000000000..81bf871ff6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBrightnessMatch.h
@@ -0,0 +1,56 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimBrightnessMatch.h,v 1.1 2005/09/08 13:06:37 gpotts Exp $
+#ifndef ossimBrightnessMatch_HEADER
+#define ossimBrightnessMatch_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include "ossimBrightnessContrastSource.h"
+
+class ossimBrightnessMatch : public ossimImageSourceFilter
+{
+public:
+   ossimBrightnessMatch();
+
+
+   virtual ~ossimBrightnessMatch();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+
+   virtual void initialize();
+   /*---------------------- PROPERTY INTERFACE ---------------------------*/
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   /*--------------------- PROPERTY INTERFACE END ------------------------*/
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+protected:
+   double          theTargetBrightness;
+   double          theInputBrightness;
+   ossimRefPtr<ossimImageData> theNormTile;
+
+   ossimRefPtr<ossimBrightnessContrastSource> theBrightnessContrastSource;
+   
+   ossimRefPtr<ossimImageData> runBrightnessMatch();
+
+   void computeInputBrightness();
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBumpShadeTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBumpShadeTileSource.cpp
new file mode 100644
index 0000000000..8e51597273
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBumpShadeTileSource.cpp
@@ -0,0 +1,507 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBumpShadeTileSource.cpp,v 1.43 2005/07/22 14:57:09 dburken Exp $
+
+#include <imaging/tile_sources/ossimBumpShadeTileSource.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/patch/ossimTilePatch.h>
+#include <imaging/ossimImageData.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeyword.h>
+#include <base/data_types/ossimMatrix3x3.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+#include <imaging/tile_sources/ossimImageToPlaneNormalFilter.h>
+
+RTTI_DEF1(ossimBumpShadeTileSource,
+          "ossimBumpShadeTileSource",
+          ossimImageCombiner);
+
+
+ossimBumpShadeTileSource::ossimBumpShadeTileSource()
+   :ossimImageCombiner(NULL, 2, 0, true, false),
+    theTile(NULL),
+    theLightSourceElevationAngle(45.0),
+    theLightSourceAzimuthAngle(45.0),
+    theLightDirection(3)
+{
+   initialize();
+}
+
+ossimBumpShadeTileSource::~ossimBumpShadeTileSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimBumpShadeTileSource::getTile(
+   const  ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!getInput(0)) return NULL;
+
+   if(!theTile.get())
+   {
+      initialize();
+   }
+   
+   ossimImageSourceInterface* normalSource =
+      PTR_CAST(ossimImageSourceInterface, getInput(0));
+   ossimImageSourceInterface* colorSource =
+      PTR_CAST(ossimImageSourceInterface, getInput(1));
+   
+   if(!theTile.get())
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   long w = tileRect.width();
+   long h = tileRect.height();
+   ossimIpt origin = tileRect.ul();
+   
+   theTile->setOrigin(origin);
+
+   long tileW = theTile->getWidth();
+   long tileH = theTile->getHeight();
+   if((w != tileW)||
+      (h != tileH))
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+      }
+   }
+ 
+   ossimRefPtr<ossimImageData> inputTile = NULL;
+
+   if(isSourceEnabled())
+   {
+      theTile->makeBlank();
+      
+      if(colorSource)
+      {
+         
+         inputTile = colorSource->getTile(tileRect, resLevel);
+      }
+      ossimRefPtr<ossimImageData> normalData = normalSource->getTile(tileRect, resLevel);
+      if(!normalData)
+      {
+         return ossimRefPtr<ossimImageData>();
+      }
+      if ( (normalData->getDataObjectStatus() == OSSIM_NULL) ||
+           (normalData->getDataObjectStatus() == OSSIM_EMPTY)||
+           (normalData->getNumberOfBands() != 3)||
+           (normalData->getScalarType() != OSSIM_DOUBLE))
+      {
+         return ossimRefPtr<ossimImageData>();
+      }
+      ossim_float64* normalBuf[3];
+      normalBuf[0] = static_cast<ossim_float64*>(normalData->getBuf(0));
+      normalBuf[1] = static_cast<ossim_float64*>(normalData->getBuf(1));
+      normalBuf[2] = static_cast<ossim_float64*>(normalData->getBuf(2));
+      ossim_float64 normalNp = normalData->getNullPix(0);
+      // if we have some color data then use it for the bump
+      // else we will default to a grey scale bump shade
+      //
+      if(inputTile.get() &&
+         (inputTile->getDataObjectStatus() != OSSIM_EMPTY) &&
+         (inputTile->getDataObjectStatus() != OSSIM_NULL))
+         
+      {
+         switch(inputTile->getScalarType())
+         {
+            case OSSIM_UCHAR:
+            {
+               ossim_uint8* resultBuf[3];
+               ossim_uint8* colorBuf[3];
+               resultBuf[0] = static_cast<ossim_uint8*>(theTile->getBuf(0));
+               resultBuf[1] = static_cast<ossim_uint8*>(theTile->getBuf(1));
+               resultBuf[2] = static_cast<ossim_uint8*>(theTile->getBuf(2));
+               colorBuf[0]  = static_cast<ossim_uint8*>(inputTile->getBuf(0));
+               if(inputTile->getBuf(1))
+               {
+                  colorBuf[1] = static_cast<ossim_uint8*>(inputTile->getBuf(1));
+               }
+               else
+               {
+                  colorBuf[1] = colorBuf[0];
+               }
+               if(inputTile->getBuf(2))
+               {
+                  colorBuf[2] = static_cast<ossim_uint8*>(inputTile->getBuf(2));
+               }
+               else
+               {
+                  colorBuf[2] = colorBuf[0];
+               }
+            
+               long h = theTile->getHeight();
+               long w = theTile->getWidth();
+               for(long y = 0; y < h; ++y)
+               {
+                  for(long x = 0; x < w; ++x)
+                  {
+                     if((*normalBuf[0] != normalNp) &&
+                        (*normalBuf[1] != normalNp) &&
+                        (*normalBuf[2] != normalNp) )
+                     {
+                        if((*colorBuf[0])||(*colorBuf[1])||(*colorBuf[2]))
+                        {
+                           computeColor(*resultBuf[0],
+                                        *resultBuf[1],
+                                        *resultBuf[2],
+                                        *normalBuf[0],
+                                        *normalBuf[1],
+                                        *normalBuf[2],
+                                        *colorBuf[0],
+                                        *colorBuf[1],
+                                        *colorBuf[2]);
+                        }
+                        else 
+                        {
+                           computeColor(*resultBuf[0],
+                                        *resultBuf[1],
+                                        *resultBuf[2],
+                                        *normalBuf[0],
+                                        *normalBuf[1],
+                                        *normalBuf[2],
+                                        255,
+                                        255,
+                                        255);
+                        }
+                     }
+                     else
+                     {
+                        *resultBuf[0] = *colorBuf[0];
+                        *resultBuf[1] = *colorBuf[1];
+                        *resultBuf[2] = *colorBuf[2];
+                     }
+                     resultBuf[0]++;
+                     resultBuf[1]++;
+                     resultBuf[2]++;
+                     colorBuf[0]++;
+                     colorBuf[1]++;
+                     colorBuf[2]++;
+                     normalBuf[0]++;
+                     normalBuf[1]++;
+                     normalBuf[2]++;
+                  }
+               }
+               break;
+            }
+            default:
+            {
+               ossimNotify(ossimNotifyLevel_NOTICE)
+                  << "ossimBumpShadeTileSource::getTile NOTICE:\n"
+                  << "only 8-bit unsigned char is supported." << endl;
+            }
+         }
+      }
+      else
+      {
+         ossim_uint8* resultBuf[3];
+         resultBuf[0] = static_cast<ossim_uint8*>(theTile->getBuf(0));
+         resultBuf[1] = static_cast<ossim_uint8*>(theTile->getBuf(1));
+         resultBuf[2] = static_cast<ossim_uint8*>(theTile->getBuf(2));
+         long h = theTile->getHeight();
+         long w = theTile->getWidth();
+         for(long y = 0; y < h; ++y)
+         {
+            for(long x = 0; x < w; ++x)
+            {
+               if((*normalBuf[0] != normalNp) &&
+                  (*normalBuf[1] != normalNp) &&
+                  (*normalBuf[2] != normalNp) )
+               {
+                     computeColor(*resultBuf[0],
+                                  *resultBuf[1],
+                                  *resultBuf[2],
+                                  *normalBuf[0],
+                                  *normalBuf[1],
+                                  *normalBuf[2],
+                                  (ossim_uint8)255,
+                                  (ossim_uint8)255,
+                                  (ossim_uint8)255);
+               }
+               else
+               {
+                  *resultBuf[0] = 0;
+                  *resultBuf[1] = 0;
+                  *resultBuf[2] = 0;
+               }
+               resultBuf[0]++;
+               resultBuf[1]++;
+               resultBuf[2]++;
+               normalBuf[0]++;
+               normalBuf[1]++;
+               normalBuf[2]++;
+            }
+         }
+      }      
+   }
+   theTile->validate();
+   return theTile;
+}
+
+void ossimBumpShadeTileSource::computeColor(ossim_uint8& r,
+                                            ossim_uint8& g,
+                                            ossim_uint8& b,
+                                            ossim_float64 normalX,
+                                            ossim_float64 normalY,
+                                            ossim_float64 normalZ,
+                                            ossim_uint8 dr,
+                                            ossim_uint8 dg,
+                                            ossim_uint8 db)const
+{
+   double c = normalX*theLightDirection[0] +
+              normalY*theLightDirection[1] +
+              normalZ*theLightDirection[2];
+   
+   if(fabs(c) > FLT_EPSILON)
+   {
+      r = ossimRgbVector::clamp(irint(c*dr), 1, 255);
+      g = ossimRgbVector::clamp(irint(c*dg), 1, 255);
+      b = ossimRgbVector::clamp(irint(c*db), 1, 255);
+   }
+   else
+   {
+      r = 1;
+      g = 1;
+      b = 1;
+   }
+}
+
+ossimIrect ossimBumpShadeTileSource::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimImageSourceInterface* source = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(source)
+   {
+      return source->getBoundingRect(resLevel);
+   }
+   ossimDrect rect;
+   rect.makeNan();
+   return rect;
+}
+
+
+void ossimBumpShadeTileSource::getDecimationFactor(ossim_uint32 resLevel,
+                                                   ossimDpt& result) const
+{
+   ossimImageSourceInterface* source = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(source)
+   {
+      return source->getDecimationFactor(resLevel, result);
+   }
+   
+   result.makeNan();
+}
+
+void ossimBumpShadeTileSource::getDecimationFactors(vector<ossimDpt>& decimations) const
+{
+   ossimImageSourceInterface* source = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   
+   if(source)
+   {
+      return source->getDecimationFactors(decimations);
+   }
+}
+
+ossim_uint32 ossimBumpShadeTileSource::getNumberOfDecimationLevels()const
+{
+   ossimImageSourceInterface* source = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   
+   if(source)
+   {
+      return source->getNumberOfDecimationLevels();
+   }
+   
+   return 0;
+}
+
+ossim_uint32 ossimBumpShadeTileSource::getTileWidth()const
+{
+   ossimImageSourceInterface* source = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(source)
+   {
+      return source->getTileWidth();
+   }
+   
+   return 128;
+}
+
+ossim_uint32 ossimBumpShadeTileSource::getTileHeight()const
+{
+   ossimImageSourceInterface* source = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(source)
+   {
+      return source->getTileHeight();
+   }
+   
+   return 128;
+}
+
+void ossimBumpShadeTileSource::initialize()
+{
+  ossimImageCombiner::initialize();
+  
+  theTile = ossimImageDataFactory::instance()->create(this, this);
+  theTile->initialize();
+  computeLightDirection();
+  
+}
+
+void ossimBumpShadeTileSource::computeLightDirection()
+{
+   NEWMAT::Matrix m = ossimMatrix3x3::createRotationMatrix(theLightSourceElevationAngle,
+                                                           0.0,
+                                                           theLightSourceAzimuthAngle);
+   NEWMAT::ColumnVector v(3);
+   v[0] = 0;
+   v[1] = 1;
+   v[2] = 0;
+   v = m*v;
+   // reflect Z.  We need the Z pointing up from the surface and not into it.
+   //
+   ossimColumnVector3d d(v[0], v[1], -v[2]);
+   d = d.unit();
+   theLightDirection[0] = d[0];
+   theLightDirection[1] = d[1];
+   theLightDirection[2] = d[2];
+}
+
+bool ossimBumpShadeTileSource::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   const char* elevationAngle = kwl.find(prefix, ossimKeywordNames::ELEVATION_ANGLE_KW);
+   const char* azimuthAngle   = kwl.find(prefix, ossimKeywordNames::AZIMUTH_ANGLE_KW);
+
+   
+   if(elevationAngle)
+   {
+      theLightSourceElevationAngle = ossimString(elevationAngle).toDouble();
+   }
+
+   if(azimuthAngle)
+   {
+      theLightSourceAzimuthAngle = ossimString(azimuthAngle).toDouble();
+   }
+
+   computeLightDirection();
+
+   bool result = ossimImageSource::loadState(kwl, prefix);
+
+   theInputListIsFixedFlag  = true;
+   theOutputListIsFixedFlag = false;
+   if(!getNumberOfInputs()) setNumberOfInputs(2);
+   
+   return result;
+}
+
+bool ossimBumpShadeTileSource::saveState(ossimKeywordlist& kwl,
+                                         const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::ELEVATION_ANGLE_KW,
+           theLightSourceElevationAngle,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::AZIMUTH_ANGLE_KW,
+           theLightSourceAzimuthAngle,
+           true);
+   
+   return ossimImageSource::saveState(kwl, prefix);
+}
+
+ossimString ossimBumpShadeTileSource::getShortName()const
+{
+   return ossimString("bump shader");
+}
+
+ossimString ossimBumpShadeTileSource::getLongName()const
+{
+   return ossimString("Blinn's bump map filter");
+}
+
+ossim_uint32 ossimBumpShadeTileSource::getNumberOfOutputBands() const
+{
+   return 3;
+}
+
+ossimScalarType ossimBumpShadeTileSource::getOutputScalarType() const
+{
+   return OSSIM_UCHAR;
+}
+
+double ossimBumpShadeTileSource::getNullPixelValue()const
+{
+   return 0.0;
+}
+
+double ossimBumpShadeTileSource::getMinPixelValue(ossim_uint32 /* band */)const
+{
+   return 1.0;
+}
+
+double ossimBumpShadeTileSource::getMaxPixelValue(ossim_uint32 /* band */)const
+{
+   return 255.0;
+}
+
+double ossimBumpShadeTileSource::getAzimuthAngle()const
+{
+   return theLightSourceAzimuthAngle;
+}
+
+double ossimBumpShadeTileSource::getElevationAngle()const
+{
+   return theLightSourceElevationAngle;
+}
+
+void ossimBumpShadeTileSource::setAzimuthAngle(double angle)
+{
+   theLightSourceAzimuthAngle = angle;
+}
+
+void ossimBumpShadeTileSource::setElevationAngle(double angle)
+{
+   theLightSourceElevationAngle = angle;
+}
+
+bool ossimBumpShadeTileSource::canConnectMyInputTo(ossim_int32 inputIndex,
+                                                   const ossimConnectableObject* object)const
+{
+   return (object&&
+           ( (inputIndex>=0) && inputIndex < 2)&&
+           PTR_CAST(ossimImageSourceInterface, object));
+   
+}
+
+void ossimBumpShadeTileSource::connectInputEvent(ossimConnectionEvent& event)
+{
+   initialize();
+}
+
+void ossimBumpShadeTileSource::disconnectInputEvent(ossimConnectionEvent& event)
+{
+   initialize();
+}
+
+void ossimBumpShadeTileSource::propertyEvent(ossimPropertyEvent& event)
+{
+   initialize();
+}
+
+void ossimBumpShadeTileSource::refreshEvent(ossimRefreshEvent& event)
+{
+   initialize();
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBumpShadeTileSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBumpShadeTileSource.h
new file mode 100644
index 0000000000..5b0e40b466
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimBumpShadeTileSource.h
@@ -0,0 +1,271 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimBumpShadeTileSource.h,v 1.32 2005/02/11 15:07:32 dburken Exp $
+#ifndef ossimBumpShadeTileSource_HEADER
+#define ossimBumpShadeTileSource_HEADER
+#include "ossimImageCombiner.h"
+#include "matrix/newmat.h"
+#include "base/data_types/ossimColumnVector3d.h"
+#include "base/common/events/ossimConnectableObjectListener.h"
+#include "base/common/events/ossimPropertyEvent.h"
+#include "ossimImageToPlaneNormalFilter.h"
+
+class ossimImageData;
+
+class ossimImageSourceConnection;
+
+/**
+ * This uses a derivative of Blinn's bump function to compute a 3-D
+ * looking image.  The elevation data can be from Grey Scale image or from
+ * a Dted file.  This class can take one or two inputs.  The First input is an
+ * elevation input that is used to compute a perturbed Normal which is
+ * used in a simple lambertian shading equation.  The second input is some
+ * color source (Grey or RGB) that defines the diffuse color used within
+ * the illumination equation for each pixel. If the diffuse color input is not
+ * supplied then an all white color is used for the color.  There are several
+ * adjustable parameters that can be set:
+ * 1) the Incident light vector described by the Azimuth and Elevation Angle,
+ * 2) the pixel scale used along the x and y direction, and
+ * 3) the partial derivative matrix used for the partial derivative
+ * computation along the x and y direction.
+ *
+ * <pre>
+ * 
+ * Some examples of good values:
+ *
+ * If we are using dted 90 meters as input for shading then:
+ * 1) set pixel scale to 180.  Since the partials do 2*dx and 2*dy then
+ *    the scale is 2*90meters = 180.
+ * 2) set azimuth angle to 45 and set elevation angle to 45 degrees.  Change
+ *    them to see the effects.
+ * 3) use the following matrix -1 0 1
+ *                             -1 0 1
+ *                             -1 0 1
+ *                                &
+ *                              1  1  1
+ *                              0  0  0
+ *                             -1 -1 -1
+ * 
+ *    for the partials along x and y directions respectively.  These matrices
+ *
+ *    (f(x+dx, y) - f(x-dx, y))/2*dx and
+ *    (f(x, y+dy) - f(x, y-dy))/2*dy
+ *
+ *    for an apprximate derivative about some point x, y
+ *
+ * If we are using pixel intesity (1 - 255) then set the scales to around
+ * 100.
+ *
+ *  Note: varying the scales will vary the smoothness/roughness of the surface
+ *        Smaller the scale the rougher the surface will look.
+ *
+ * The output of this source is always a 3-band 8-bit image.
+ *
+ * Keywords:
+ *   type:               ossimBumpShadeTileSource
+ *   azimuth_angle:      45.000000000000000
+ *   elevation_angle:    45.000000000000000
+ *   scale_per_pixel_x:  180.000000000000000  // this is the 2*dx defined above
+ *   scale_per_pixel_y:  180.000000000000000  // this is the 2*dy defined above
+ *
+ *   the next set of keywords are optional and the default is as defined above.
+ *   these define the matrix.
+ *
+ *
+ * A typical chain would look something like this:
+ * 
+ * OrthoMosaicOfElevation-->Normals-->Renderer-->|
+ *                                               |--> BumpShade-->Output 
+ * ColorSource----------------------->Renderer-->|
+ *
+ * NOTE:  "Normals" is an ossimImageToPlaneNormalFilter class
+ * 
+ * </pre>
+ * 
+ */
+class OSSIMDLLEXPORT ossimBumpShadeTileSource : public ossimImageCombiner
+{
+public:
+   ossimBumpShadeTileSource();
+
+   /**
+    * The bump map  input source is used to bump or shade the input color
+    * source.  The input color source currently must be a 1 or 3 band
+    * image.  Note that the output of this source is always
+    * 3 bands (r, g, b).
+    */
+   ossimBumpShadeTileSource(ossimImageSource* colorSource,
+                            ossimImageSource* bumpMapSource);
+   virtual ~ossimBumpShadeTileSource();
+      
+   ossimString getShortName()const;
+   ossimString getLongName()const;
+
+   ossimRefPtr<ossimImageData> getTile(const  ossimIrect& tileRect,
+                                       ossim_uint32 resLevel=0);
+
+   /**
+    * Since the input bump souce is not used for bounding rect computation
+    * this call is passed on to theColorInputSource.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result) const;
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations) const;
+   virtual ossim_uint32 getNumberOfDecimationLevels()const;
+   
+   /**
+    * This should always return 3
+    */
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+
+   /**
+    * The output scalar type should always be 8-bit
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+   
+   /**
+    * the null pixel is 0.0.
+    * \return null pixel value is always 0
+    *
+    */
+   virtual double getNullPixelValue()const;
+
+   /**
+    * the min pixel is 1.0.
+    * \return min pixel value is always 1
+    *
+    */
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+
+   /**
+    * the max pixel is 255.
+    * \return max pixel value is always 255
+    *
+    */
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   /**
+    * Returns the current tile width.  This is passed to first input.
+    * \return Returns the tile width.
+    */
+   virtual ossim_uint32 getTileWidth()const;
+
+   /**
+    * Returns the current tile height.  This is passed to first input.
+    * \return Returns the tile height..
+    */
+   virtual ossim_uint32 getTileHeight()const;
+
+   /**
+    * \return Returns the rotation of the incident vector..
+    */
+   virtual double getAzimuthAngle()const;
+
+   /**
+    * \return Returns the elevation of the incident vector.
+    */
+   virtual double getElevationAngle()const;
+
+   /**
+    *
+    */
+   virtual void setAzimuthAngle(double angle);
+
+   /**
+    *
+    */
+   virtual void setElevationAngle(double angle);
+
+   /**
+    *
+    */
+   virtual void initialize();
+
+   /**
+    *
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    *
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    *
+    */
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const;
+      
+   /**
+    *
+    */
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+
+   /**
+    *
+    */
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+
+   /**
+    *
+    */
+   virtual void propertyEvent(ossimPropertyEvent& event);
+
+   virtual void refreshEvent(ossimRefreshEvent& event);
+
+   /**
+    * Will re-compute the light direction given the elevation angle and
+    * azimuth angle.
+    */
+   void computeLightDirection();
+
+protected:
+   /**
+    * The result of the illumination equation is stored in
+    * here.  This is populated on each call to getTile.
+    */
+   ossimRefPtr<ossimImageData> theTile;
+
+   /**
+    * Used for the light vector computation.
+    */
+   double theLightSourceElevationAngle;
+
+   /**
+    * Used for the light vector computation.
+    */
+   double theLightSourceAzimuthAngle;
+
+   /**
+    * This is computed from the elevation and
+    * azimuth angles of the light source.
+    */
+   NEWMAT::ColumnVector theLightDirection;
+
+   void computeColor(ossim_uint8& r,
+                     ossim_uint8& g,
+                     ossim_uint8& b,
+                     ossim_float64 normalX,
+                     ossim_float64 normalY,
+                     ossim_float64 normalZ,
+                     ossim_uint8 dr,
+                     ossim_uint8 dg,
+                     ossim_uint8 db)const;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCacheTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCacheTileSource.cpp
new file mode 100644
index 0000000000..af08946116
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCacheTileSource.cpp
@@ -0,0 +1,357 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts 
+//
+// Description:
+//
+// ossimCacheTileSource.
+//*******************************************************************
+//  $Id: ossimCacheTileSource.cpp,v 1.55 2005/08/17 19:18:12 gpotts Exp $
+#include <base/common/ossimTrace.h>
+#include <imaging/tile_sources/ossimCacheTileSource.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+#ifndef NULL
+#  include <stddef.h>
+#endif
+static ossimTrace traceDebug("ossimCacheTileSource:debug");
+
+RTTI_DEF1(ossimCacheTileSource, "ossimCacheTileSource", ossimImageSourceFilter);
+   
+ossimCacheTileSource::ossimCacheTileSource()
+   : ossimImageSourceFilter(),
+     theCacheId(ossimAppFixedTileCache::instance()->newTileCache()),
+     theTile(0),
+     theCachingEnabled(true),
+     theEventProgressFlag(false)
+{
+   theBoundingRect.makeNan();
+   theFixedTileSize = ossimAppFixedTileCache::instance()->getTileSize(theCacheId);
+   theCacheRLevel = 0;
+}
+
+ossimCacheTileSource::ossimCacheTileSource(ossimImageSource* inputSource)
+   : ossimImageSourceFilter(inputSource),
+     theCacheId(ossimAppFixedTileCache::instance()->newTileCache()),
+     theTile(0),
+     theCachingEnabled(true),
+     theEventProgressFlag(false)
+{
+   theBoundingRect.makeNan();
+   theFixedTileSize = ossimAppFixedTileCache::instance()->getTileSize(theCacheId);
+   theCacheRLevel = 0;
+}
+
+ossimCacheTileSource::~ossimCacheTileSource()
+{
+   ossimAppFixedTileCache::instance()->deleteCache(theCacheId);
+   
+   theCacheId = -1;
+   theBoundingRect.makeNan();
+}
+
+void ossimCacheTileSource::flush()
+{
+   ossimAppFixedTileCache::instance()->flush(theCacheId);
+}
+
+void ossimCacheTileSource::initialize()
+{
+   ossimImageSourceFilter::initialize();
+   flush();
+   theCacheRLevel = 999999999;
+
+   theTile = NULL;
+}
+   
+void ossimCacheTileSource::allocate()
+{
+   theTile = NULL;
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,
+                                                          this);
+      theTile->initialize();
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimCacheTileSource::getTile(const ossimIrect& tileRect,
+                                              ossim_uint32 resLevel)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimCacheTileSource::getTile DEBUG: Entered ..." << std::endl;
+   }
+   if(!theInputConnection)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimCacheTileSource::getTile DEBUG: Leaving with theInputConnection NULL ..." << std::endl;
+      }
+      return 0;
+   }
+   
+   if(!isSourceEnabled())
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimCacheTileSource::getTile DEBUG: Source not enabled so leaving ..." << std::endl;
+      }
+      return theInputConnection->getTile(tileRect, resLevel);
+   }
+   
+   if(!theTile.get())
+   {
+      allocate();
+   }
+
+   if(!theTile.get())
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimCacheTileSource::getTile DEBUG: Unable to allocate tile so leaving ..." << std::endl;
+      }
+      return 0;
+   }
+
+   if(resLevel != theCacheRLevel)
+   {
+      flush();
+      theCacheRLevel = 9999999;
+      allocate();
+      theBoundingRect = getBoundingRect(resLevel);
+      if(theBoundingRect.hasNans())
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "ossimCacheTileSource::getTile DEBUG: bounding rect has nans so leaving ..." << std::endl;
+         }
+         return 0;
+      }
+      theFixedTileSize = ossimAppFixedTileCache::instance()->getTileSize(theCacheId);
+      theBoundingRect.stretchToTileBoundary(theFixedTileSize);
+      ossimAppFixedTileCache::instance()->setRect(theCacheId,
+                                                  theBoundingRect);
+      theCacheRLevel = resLevel;
+   }
+
+   theTile->setImageRectangle(tileRect);
+   theTile->makeBlank();
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimCacheTileSource::getTile DEBUG: filling tile and leaving ..." << std::endl;
+   }
+   return fillTile(resLevel);
+}
+
+ossimRefPtr<ossimImageData> ossimCacheTileSource::fillTile(
+   ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> tempTile = NULL;
+   fireProgressEvent(0.0);
+   ossimIrect boundingRect = theBoundingRect;
+   ossimIrect tileRect = theTile->getImageRectangle();
+   
+   ossimIrect allignedRect = tileRect.clipToRect(boundingRect);
+   
+   if (allignedRect.hasNans())
+   {
+      theTile->makeBlank();
+      return theTile;
+   }
+   
+   allignedRect.stretchToTileBoundary(theFixedTileSize);
+   ossimAppFixedTileCache::ossimAppFixedCacheId cacheId = theCacheId;
+   
+   // check to see if we need to loop
+   if((allignedRect == tileRect)&&
+      (static_cast<ossim_int32>(tileRect.width())  == theFixedTileSize.x)&&
+      (static_cast<ossim_int32>(tileRect.height()) == theFixedTileSize.y))
+   {
+      ossimIpt origin = tileRect.ul();
+      if(theCachingEnabled)
+      {
+         tempTile = ossimAppFixedTileCache::instance()->getTile(cacheId, origin);
+      }
+      if(!tempTile.valid())
+      {
+         tempTile = theInputConnection->getTile(tileRect, resLevel);
+         
+         if(tempTile.valid())
+         {
+            if((tempTile->getBuf())&&
+               (tempTile->getDataObjectStatus()!=OSSIM_EMPTY)&&
+               theCachingEnabled)
+            {
+               ossimAppFixedTileCache::instance()->addTile(cacheId, tempTile);
+            }
+         }
+      }
+      
+      if(tempTile.valid())
+      {
+         if((tempTile->getDataObjectStatus() != OSSIM_NULL)&&
+            (tempTile->getDataObjectStatus() != OSSIM_EMPTY))
+         {
+            
+            theTile->setDataObjectStatus(tempTile->getDataObjectStatus());
+            theTile->loadTile(tempTile.get());
+         }
+      }
+      fireProgressEvent(100.0);
+   }
+   else
+   {
+      long boundaryHeight = allignedRect.height();
+      long boundaryWidth  = allignedRect.width();
+      ossimIpt origin(allignedRect.ul());
+      long totalTiles  = (boundaryHeight/theFixedTileSize.y)*
+         (boundaryWidth/theFixedTileSize.x);
+      long currentTile = 0;
+      for(long row = 0; row < boundaryHeight; row+=theFixedTileSize.y)
+      {
+         origin.x  =  allignedRect.ul().x;
+         for(long col = 0; col < boundaryWidth; col+=theFixedTileSize.x)
+         {
+            ++currentTile;
+            if(theCachingEnabled)
+            {
+               tempTile = ossimAppFixedTileCache::instance()->getTile(cacheId,
+                                                                      origin);
+            }
+            else
+            {
+               tempTile = 0;
+            }
+            if(!tempTile.valid())
+            {
+               ossimIrect rect(origin.x,
+                               origin.y,
+                               origin.x + theFixedTileSize.x-1,
+                               origin.y + theFixedTileSize.y-1);
+
+               tempTile = theInputConnection->getTile(rect, resLevel);
+               
+               if(tempTile.valid())
+               {
+                  if(theTile->getBuf()&&
+                     (tempTile->getDataObjectStatus()!=OSSIM_EMPTY)&&
+                     theCachingEnabled)
+                  {
+                     ossimAppFixedTileCache::instance()->addTile(cacheId, tempTile);
+                  }
+               }
+            }
+            if(tempTile.valid())
+            {
+               if(tempTile->getBuf()&&
+                  (tempTile->getDataObjectStatus()!=OSSIM_EMPTY))
+               {
+                  theTile->loadTile(tempTile.get());
+               }
+            }
+            double percent = 100.0*((double)currentTile/(double)totalTiles);
+            fireProgressEvent(percent);
+            origin.x   += theFixedTileSize.x;
+         }
+         origin.y += theFixedTileSize.y;
+      }
+      fireProgressEvent(100);
+   }
+   
+   theTile->validate();
+   
+   return theTile;
+}
+
+ossim_uint32 ossimCacheTileSource::getTileWidth() const
+{
+   return theFixedTileSize.x;
+}
+
+ossim_uint32 ossimCacheTileSource::getTileHeight() const
+{
+   return theFixedTileSize.y;  
+}
+
+bool ossimCacheTileSource::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   ossimAppFixedTileCache::instance()->deleteCache(theCacheId);
+   theCacheId = ossimAppFixedTileCache::instance()->newTileCache();
+   const char* cachingEnabled = kwl.find(prefix, ossimKeywordNames::ENABLE_CACHE_KW);
+   
+   if(cachingEnabled)
+   {
+      theCachingEnabled = ossimString(cachingEnabled).toBool();
+   }
+   
+   bool result = ossimImageSourceFilter::loadState(kwl, prefix);
+   initialize();
+   return result;
+}
+
+bool ossimCacheTileSource::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::ENABLE_CACHE_KW,
+           (long)theCachingEnabled,
+           true);
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+
+ossimString ossimCacheTileSource::getLongName()const
+{
+   return ossimString("Tile Cache , cache for ossimImageData objects.");
+}
+
+ossimString ossimCacheTileSource::getShortName()const
+{
+   return ossimString("Tile Cache");
+}
+
+void ossimCacheTileSource::setCachingEnabledFlag(bool value)
+{
+   if(!value && theCachingEnabled)
+   {
+      flush();
+   }
+   theCachingEnabled = value;
+}
+
+void ossimCacheTileSource::setEventProgressFlag(bool value)
+{
+   theEventProgressFlag = value;
+}
+
+ossimIpt ossimCacheTileSource::getTileSize()
+{
+   return theFixedTileSize;
+}
+
+void ossimCacheTileSource::setTileSize(const ossimIpt& size)
+{
+   theFixedTileSize = size;
+}
+
+void ossimCacheTileSource::fireProgressEvent(double percentComplete)
+{
+   if(theEventProgressFlag)
+   {
+      ossimProcessProgressEvent event(this, percentComplete);
+      fireEvent(event);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCacheTileSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCacheTileSource.h
new file mode 100644
index 0000000000..b0dadcd8fa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCacheTileSource.h
@@ -0,0 +1,75 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// ossimCacheTileSource.
+//*******************************************************************
+//  $Id: ossimCacheTileSource.h,v 1.27 2005/02/11 15:07:32 dburken Exp $
+#ifndef ossimCacheTileSource_HEADER
+#define ossimCacheTileSource_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <imaging/cache/ossimAppFixedTileCache.h>
+#include <base/common/events/ossimProcessProgressEvent.h>
+
+/** Cache Tile Source */
+class OSSIMDLLEXPORT ossimCacheTileSource : public ossimImageSourceFilter
+{
+public:
+   /**
+    * Will construct a new Application cache
+    */
+   ossimCacheTileSource();
+   ossimCacheTileSource(ossimImageSource* inputSource);
+   virtual ~ossimCacheTileSource();
+
+   virtual ossimString getLongName()  const;
+   virtual ossimString getShortName() const;
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   virtual void initialize();
+   virtual void flush();
+   virtual void setCachingEnabledFlag(bool value);
+   virtual void setEventProgressFlag(bool value);
+
+   void     changeTileSize(const ossimIpt& size);
+   ossimIpt getTileSize();
+   void     setTileSize(const ossimIpt& size);
+   
+   virtual ossim_uint32 getTileWidth() const;
+   virtual ossim_uint32 getTileHeight() const;
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix=0);
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix=0)const;
+
+protected:
+
+   void allocate();
+   
+   ossimAppFixedTileCache::ossimAppFixedCacheId theCacheId;
+
+   ossimRefPtr<ossimImageData> theTile;
+   ossimIpt                    theFixedTileSize;
+   bool                        theCachingEnabled;
+   bool                        theEventProgressFlag;
+   ossim_uint32                theCacheRLevel;
+   ossimIrect                  theBoundingRect;
+   
+   virtual void fireProgressEvent(double percentComplete);
+   
+   virtual ossimRefPtr<ossimImageData> fillTile(ossim_uint32 resLevel);
+
+TYPE_DATA
+};
+
+
+#endif /* end of "#ifndef ossimCacheTileSource_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCastTileSourceFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCastTileSourceFilter.cpp
new file mode 100644
index 0000000000..fafc5a5b11
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCastTileSourceFilter.cpp
@@ -0,0 +1,688 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimCastTileSourceFilter.cpp,v 1.30 2005/08/17 19:18:12 gpotts Exp $
+#include <imaging/tile_sources/ossimCastTileSourceFilter.h>
+#include <imaging/ossimU8ImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/property/ossimStringProperty.h>
+
+RTTI_DEF1( ossimCastTileSourceFilter,
+           "ossimCastTileSourceFilter",
+           ossimImageSourceFilter );
+
+ossimCastTileSourceFilter::ossimCastTileSourceFilter(ossimImageSource* input,
+						     ossimScalarType scalarType)
+   :ossimImageSourceFilter(NULL,input),
+    theTile(NULL),
+    theOutputScalarType(scalarType)
+{
+}
+
+ossimCastTileSourceFilter::~ossimCastTileSourceFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimCastTileSourceFilter::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> inputTile;
+   
+   if(theInputConnection)
+   {
+      inputTile = theInputConnection->getTile(tileRect, resLevel);
+   }
+   return applyCast(inputTile);
+}
+
+ossimScalarType ossimCastTileSourceFilter::getOutputScalarType() const
+{
+   if(isSourceEnabled())
+   {
+      return theOutputScalarType;
+   }
+   else if(theInputConnection)
+   {
+      return theInputConnection->getOutputScalarType();
+   }
+
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+double ossimCastTileSourceFilter::getNullPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      if(theInputConnection)
+      {
+         return theInputConnection->getNullPixelValue(band);
+      }
+   }
+   return ossimGetDefaultNull(getOutputScalarType());
+}
+
+double ossimCastTileSourceFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      if(theInputConnection)
+      {
+         return theInputConnection->getMinPixelValue(band);
+      }
+   }
+
+   if(theInputConnection)
+   {
+      double tempMin    = theInputConnection->getMinPixelValue(band);
+      
+      double defaultMin = ossimGetDefaultMin(theOutputScalarType);
+      double defaultMax = ossimGetDefaultMax(theOutputScalarType);
+
+      if((tempMin >= defaultMin) && (tempMin <= defaultMax))
+      {
+         defaultMin = tempMin;
+      }
+
+      return defaultMin;
+   }
+   
+   return ossimImageSource::getMinPixelValue(band);
+}
+
+double ossimCastTileSourceFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      if(theInputConnection)
+      {
+         return theInputConnection->getMaxPixelValue(band);
+      }
+   }
+   if(theInputConnection)
+   {
+      double tempMax    = theInputConnection->getMaxPixelValue(band);
+      
+      double defaultMax = ossimGetDefaultMax(theOutputScalarType);
+      double defaultMin = ossimGetDefaultMin(theOutputScalarType);
+
+      if((tempMax >= defaultMin) && (tempMax <= defaultMax))
+      {
+         defaultMax = tempMax;
+      }
+
+      return defaultMax;
+   }
+   return ossimImageSource::getMaxPixelValue(band);
+}
+
+ossimRefPtr<ossimImageData> ossimCastTileSourceFilter::applyCast(
+   ossimRefPtr<ossimImageData> inputTile)
+{
+   if(!inputTile.valid())
+   {
+      return inputTile;
+   }
+   
+   if(!theTile.valid() ||
+      (theTile->getNumberOfBands() != inputTile->getNumberOfBands()))
+   {
+      allocate(inputTile);
+   }
+   else
+   {
+      ossim_int32 tw =inputTile->getWidth(); 
+      ossim_int32 th =inputTile->getHeight(); 
+      ossim_int32 w = theTile->getWidth();
+      ossim_int32 h = theTile->getHeight();
+      theTile->setWidthHeight(tw, th);
+      
+      if((w*h != tw*th))
+      {
+         theTile->initialize();
+      }
+      else
+      {
+         theTile->makeBlank();
+      }
+      theTile->setOrigin(inputTile->getOrigin());
+   }
+   
+   if( (inputTile->getDataObjectStatus()==OSSIM_EMPTY) ||
+       (inputTile->getDataObjectStatus()==OSSIM_NULL))
+   {
+      return theTile;
+   }
+   
+   switch(inputTile->getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         ossim_uint8** bands = new ossim_uint8*[inputTile->getNumberOfBands()];
+         
+         for(ossim_uint32 band = 0;
+             band < inputTile->getNumberOfBands();
+             ++band)
+         {
+            bands[band] = static_cast<ossim_uint8*>(inputTile->getBuf(band));
+         }
+         castInputToOutput(bands,
+                           inputTile->getNullPix(),
+                           inputTile->getDataObjectStatus()==OSSIM_PARTIAL);
+         delete [] bands;
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         ossim_sint8** bands = new ossim_sint8*[inputTile->getNumberOfBands()];
+         
+         for(ossim_uint32 band = 0;
+             band < inputTile->getNumberOfBands();
+             ++band)
+         {
+            bands[band] = static_cast<ossim_sint8*>(inputTile->getBuf(band));
+         }
+         castInputToOutput(bands,
+                           inputTile->getNullPix(),
+                           inputTile->getDataObjectStatus()==OSSIM_PARTIAL);
+         delete [] bands;
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         ossim_uint16** bands =
+            new ossim_uint16*[inputTile->getNumberOfBands()];
+         
+         for(ossim_uint32 band = 0;
+             band < inputTile->getNumberOfBands();
+             ++band)
+         {
+            bands[band] = static_cast<ossim_uint16*>(inputTile->getBuf(band));
+         }
+         castInputToOutput(bands,
+                           inputTile->getNullPix(),
+                           inputTile->getDataObjectStatus()==OSSIM_PARTIAL);
+         delete [] bands;
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         ossim_sint16** bands =
+            new ossim_sint16*[inputTile->getNumberOfBands()];
+         
+         for(ossim_uint32 band = 0;
+             band < inputTile->getNumberOfBands();
+             ++band)
+         {
+            bands[band] = static_cast<ossim_sint16*>(inputTile->getBuf(band));
+         }
+         castInputToOutput(bands,
+                           inputTile->getNullPix(),
+                           inputTile->getDataObjectStatus()==OSSIM_PARTIAL);
+         delete [] bands;
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         ossim_sint32** bands =
+            new ossim_sint32*[inputTile->getNumberOfBands()];
+         
+         for(ossim_uint32 band = 0;
+             band < inputTile->getNumberOfBands();
+             ++band)
+         {
+            bands[band] = static_cast<ossim_sint32*>(inputTile->getBuf(band));
+         }
+         castInputToOutput(bands,
+                           inputTile->getNullPix(),
+                           inputTile->getDataObjectStatus()==OSSIM_PARTIAL);
+         delete [] bands;
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         ossim_uint32** bands =
+            new ossim_uint32*[inputTile->getNumberOfBands()];
+         
+         for(ossim_uint32 band = 0;
+             band < inputTile->getNumberOfBands();
+             ++band)
+         {
+            bands[band] = static_cast<ossim_uint32*>(inputTile->getBuf(band));
+         }
+         castInputToOutput(bands,
+                           inputTile->getNullPix(),
+                           inputTile->getDataObjectStatus()==OSSIM_PARTIAL);
+         delete [] bands;
+         break;
+      }
+      case OSSIM_FLOAT32: 
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         float** bands = new float*[inputTile->getNumberOfBands()];
+         
+         for(ossim_uint32 band = 0;
+             band < inputTile->getNumberOfBands();
+             ++band)
+         {
+            bands[band] = static_cast<float*>(inputTile->getBuf(band));
+         }
+         castInputToOutput(bands,
+                           inputTile->getNullPix(),
+                           inputTile->getDataObjectStatus()==OSSIM_PARTIAL);
+         delete [] bands;
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         double** bands = new double*[inputTile->getNumberOfBands()];
+         
+         for(ossim_uint32 band = 0;
+             band < inputTile->getNumberOfBands();
+             ++band)
+         {
+            bands[band] = static_cast<double*>(inputTile->getBuf(band));
+         }
+         castInputToOutput(bands,
+                           inputTile->getNullPix(),
+                           inputTile->getDataObjectStatus()==OSSIM_PARTIAL);
+         delete [] bands;
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         break;
+      }
+   }
+
+//   theTile->setDataObjectStatus(inputTile->getDataObjectStatus());
+   theTile->validate();
+   return theTile;
+}
+
+void ossimCastTileSourceFilter::setOutputScalarType(ossimScalarType scalarType)
+{
+   ossimScalarType old_type = theOutputScalarType;
+   theOutputScalarType = scalarType;
+
+   if ( (theOutputScalarType != old_type))
+   {
+      // must reinitialize...
+      theTile = NULL;
+      initialize();
+   }
+}
+
+void ossimCastTileSourceFilter::setOutputScalarType(ossimString scalarType)
+{
+   int scalar =
+      ossimScalarTypeLut::instance()->getEntryNumber(scalarType.c_str());
+   
+   if (scalar != ossimLookUpTable::NOT_FOUND)
+   {
+      setOutputScalarType(static_cast<ossimScalarType>(scalar));
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimCastTileSourceFilter::setOutputScalarType WARN:"
+         << "\nUnknown scalar type:  " << scalarType.c_str() << endl;
+   }
+}
+
+ossimString ossimCastTileSourceFilter::getOutputScalarTypeString()const
+{
+   return ossimScalarTypeLut::instance()->getEntryString(theOutputScalarType);
+}
+
+void ossimCastTileSourceFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   if (theOutputScalarType == OSSIM_SCALAR_UNKNOWN)
+   {
+      // default to OSSIM_UCHAR
+      theOutputScalarType = OSSIM_UCHAR;
+   }
+}
+
+bool ossimCastTileSourceFilter::saveState(ossimKeywordlist& kwl,
+                                          const char* prefix) const
+{
+   ossimImageSourceFilter::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           ossimKeywordNames::SCALAR_TYPE_KW,
+           ossimScalarTypeLut::instance()->getEntryString(theOutputScalarType),
+           true);
+
+   return true;
+}
+
+bool ossimCastTileSourceFilter::loadState(const ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   ossimImageSourceFilter::loadState(kwl, prefix);
+
+   if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimScalarRemapper::loadState WARN:\n"
+         << " ERROR detected in keyword list!  State not loaded."
+         << endl;
+      return false;
+   }
+
+   int scalar = ossimScalarTypeLut::instance()->getEntryNumber(kwl, prefix);
+
+   if (scalar != ossimLookUpTable::NOT_FOUND)
+   {
+      theOutputScalarType = static_cast<ossimScalarType>(scalar);
+   }
+
+   return true;
+}
+
+template<class inType>
+void ossimCastTileSourceFilter::castInputToOutput(inType **inBuffer,
+                                                  const double  *nullPix,
+                                                  bool   inPartialFlag)
+{
+   switch(theTile->getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         ossim_uint8** bands = new ossim_uint8*[theTile->getNumberOfBands()];
+
+         for(ossim_uint32 band = 0; band < theTile->getNumberOfBands(); ++band)
+         {
+            bands[band] = static_cast<ossim_uint8*>(theTile->getBuf(band));
+         }
+      
+         castInputToOutput(inBuffer,
+                           nullPix,
+                           inPartialFlag,
+                           bands,
+                           theTile->getNullPix(),
+                           theTile->getNumberOfBands());
+         delete [] bands;
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         ossim_sint8** bands = new ossim_sint8*[theTile->getNumberOfBands()];
+
+         for(ossim_uint32 band = 0; band < theTile->getNumberOfBands(); ++band)
+         {
+            bands[band] = static_cast<ossim_sint8*>(theTile->getBuf(band));
+         }
+      
+         castInputToOutput(inBuffer,
+                           nullPix,
+                           inPartialFlag,
+                           bands,
+                           theTile->getNullPix(),
+                           theTile->getNumberOfBands());
+         delete [] bands;
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         ossim_sint16** bands = new ossim_sint16*[theTile->getNumberOfBands()];
+
+         for(ossim_uint32 band = 0; band < theTile->getNumberOfBands(); ++band)
+         {
+            bands[band] = static_cast<ossim_sint16*>(theTile->getBuf(band));
+         }
+      
+         castInputToOutput(inBuffer,
+                           nullPix,
+                           inPartialFlag,
+                           bands,
+                           theTile->getNullPix(),
+                           theTile->getNumberOfBands());
+         delete [] bands;
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         ossim_uint16** bands = new ossim_uint16*[theTile->getNumberOfBands()];
+
+         for(ossim_uint32 band = 0; band < theTile->getNumberOfBands(); ++band)
+         {
+            bands[band] = static_cast<ossim_uint16*>(theTile->getBuf(band));
+         }
+      
+         castInputToOutput(inBuffer,
+                           nullPix,
+                           inPartialFlag,
+                           bands,
+                           theTile->getNullPix(),
+                           theTile->getNumberOfBands());
+         delete [] bands;
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         ossim_uint32** bands = new ossim_uint32*[theTile->getNumberOfBands()];
+
+         for(ossim_uint32 band = 0; band < theTile->getNumberOfBands(); ++band)
+         {
+            bands[band] = static_cast<ossim_uint32*>(theTile->getBuf(band));
+         }
+      
+         castInputToOutput(inBuffer,
+                           nullPix,
+                           inPartialFlag,
+                           bands,
+                           theTile->getNullPix(),
+                           theTile->getNumberOfBands());
+         delete [] bands;
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         ossim_sint32** bands = new ossim_sint32*[theTile->getNumberOfBands()];
+
+         for(ossim_uint32 band = 0; band < theTile->getNumberOfBands(); ++band)
+         {
+            bands[band] = static_cast<ossim_sint32*>(theTile->getBuf(band));
+         }
+      
+         castInputToOutput(inBuffer,
+                           nullPix,
+                           inPartialFlag,
+                           bands,
+                           theTile->getNullPix(),
+                           theTile->getNumberOfBands());
+         delete [] bands;
+         break;
+      }
+      
+      case OSSIM_FLOAT32: 
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         float** bands = new float*[theTile->getNumberOfBands()];
+
+         for(ossim_uint32 band = 0; band < theTile->getNumberOfBands(); ++band)
+         {
+            bands[band] = static_cast<float*>(theTile->getBuf(band));
+         }
+      
+         castInputToOutput(inBuffer,
+                           nullPix,
+                           inPartialFlag,
+                           bands,
+                           theTile->getNullPix(),
+                           theTile->getNumberOfBands());
+         delete [] bands;
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         double** bands = new double*[theTile->getNumberOfBands()];
+
+         for(ossim_uint32 band = 0; band < theTile->getNumberOfBands(); ++band)
+         {
+            bands[band] = static_cast<double*>(theTile->getBuf(band));
+         }
+      
+         castInputToOutput(inBuffer,
+                           nullPix,
+                           inPartialFlag,
+                           bands,
+                           theTile->getNullPix(),
+                           theTile->getNumberOfBands());
+         delete [] bands;
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimCastTileSourceFilter::castInputToOutput WARN:\n"
+            << "Scalar not set in ossimCastTileSourceFilter" << endl;
+         break;
+      }
+   }
+}
+
+template<class inType, class outType>
+void ossimCastTileSourceFilter::castInputToOutput(inType *inBuffer[],
+                                                  const double  *nullInPix,
+                                                  bool   inPartialFlag,
+                                                  outType *outBuffer[],
+                                                  const double  *nullOutPix,
+                                                  ossim_uint32   numberOfBands)
+{
+   ossim_uint32 size = theTile->getWidth()*theTile->getHeight();
+   if(!inPartialFlag)
+   {
+      for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+      {
+         outType outMin = static_cast<outType>(theTile->getMinPix(band));
+         outType outMax = static_cast<outType>(theTile->getMaxPix(band));
+         
+         for(ossim_uint32 offset = 0; offset < size; ++offset)
+         {
+            double temp = inBuffer[band][offset];
+            if(temp < outMin) temp = outMin;
+            if(temp > outMax) temp = outMax;
+            outBuffer[band][offset] = static_cast<outType>(temp);
+         }
+      }
+   }
+   else
+   {
+      for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+      {
+         inType np      = static_cast<inType>(nullInPix[band]);
+	 outType outNp  = static_cast<outType>(nullOutPix[band]);
+         outType outMin = static_cast<outType>(theTile->getMinPix(band));
+         outType outMax = static_cast<outType>(theTile->getMaxPix(band));
+         
+         for(ossim_uint32 offset = 0; offset < size; ++offset)
+         {
+            if(inBuffer[band][offset] != np)
+            {
+               double temp = inBuffer[band][offset];
+               if(temp < outMin) temp = outMin;
+               if(temp > outMax) temp = outMax;
+               outBuffer[band][offset] = static_cast<outType>(temp);
+            }
+	    else
+	    {
+		outBuffer[band][offset] = static_cast<outType>(outNp);
+		
+	    }
+         }
+      }
+   }
+}
+
+void ossimCastTileSourceFilter::allocate(const ossimRefPtr<ossimImageData> inputTile)
+{
+   theTile = ossimImageDataFactory::instance()->create(
+      this,
+      getOutputScalarType(),
+      inputTile->getNumberOfBands(),
+      inputTile->getWidth(),
+      inputTile->getHeight());
+   theTile->initialize();
+   theTile->setOrigin(inputTile->getOrigin());
+}
+
+void ossimCastTileSourceFilter::propertyEvent(ossimPropertyEvent& event)
+{
+}
+
+void ossimCastTileSourceFilter::refreshEvent(ossimRefreshEvent& event)
+{
+}
+
+void ossimCastTileSourceFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(property->getName() == ossimKeywordNames::SCALAR_TYPE_KW)
+   {
+      int scalar = ossimScalarTypeLut::instance()->getEntryNumber(property->valueToString());
+      
+      if (scalar != ossimLookUpTable::NOT_FOUND)
+      {
+         setOutputScalarType(static_cast<ossimScalarType>(scalar));
+      }
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimCastTileSourceFilter::getProperty(const ossimString& name)const
+{
+   ossimRefPtr<ossimProperty> resultProperty;
+   if(name == ossimKeywordNames::SCALAR_TYPE_KW)
+   {
+      ossimStringProperty* stringProperty = new ossimStringProperty(name,
+                                                                    ossimScalarTypeLut::instance()->getEntryString(theOutputScalarType),
+                                                                    false);
+
+      stringProperty->addConstraint(ossimScalarTypeLut::instance()->getEntryString(OSSIM_UINT8));
+      stringProperty->addConstraint(ossimScalarTypeLut::instance()->getEntryString(OSSIM_SINT8));
+      stringProperty->addConstraint(ossimScalarTypeLut::instance()->getEntryString(OSSIM_UINT16));
+      stringProperty->addConstraint(ossimScalarTypeLut::instance()->getEntryString(OSSIM_SINT16));
+      stringProperty->addConstraint(ossimScalarTypeLut::instance()->getEntryString(OSSIM_UINT32));
+      stringProperty->addConstraint(ossimScalarTypeLut::instance()->getEntryString(OSSIM_SINT32));
+      stringProperty->addConstraint(ossimScalarTypeLut::instance()->getEntryString(OSSIM_FLOAT32));
+      stringProperty->addConstraint(ossimScalarTypeLut::instance()->getEntryString(OSSIM_FLOAT64));
+
+      stringProperty->setCacheRefreshBit();
+      resultProperty = stringProperty;
+   }
+   else
+   {
+      resultProperty = ossimImageSourceFilter::getProperty(name);
+   }
+   return resultProperty;
+}
+
+void ossimCastTileSourceFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   
+   propertyNames.push_back(ossimKeywordNames::SCALAR_TYPE_KW);
+}
+   
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCastTileSourceFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCastTileSourceFilter.h
new file mode 100644
index 0000000000..38dac7c45a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimCastTileSourceFilter.h
@@ -0,0 +1,93 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimCastTileSourceFilter.h,v 1.16 2005/08/17 19:18:12 gpotts Exp $
+#ifndef ossimCastTileSourceFilter_HEADER
+#define ossimCastTileSourceFilter_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimCastTileSourceFilter : public ossimImageSourceFilter
+{
+public:
+   ossimCastTileSourceFilter(ossimImageSource* inputSource=NULL,
+			     ossimScalarType scalarType=OSSIM_UCHAR);
+   virtual ~ossimCastTileSourceFilter();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   virtual void initialize();
+   virtual ossimScalarType getOutputScalarType() const;
+
+   virtual ossimString getOutputScalarTypeString()const;
+
+   /**
+    *  Sets the output scalar type.
+    */
+   virtual void setOutputScalarType(ossimScalarType scalarType);
+   virtual void setOutputScalarType(ossimString scalarType);
+   
+   /**
+    *  Sets the current resolution level.  Returns true on success, false
+    *  on error.
+    */
+   virtual double getNullPixelValue(ossim_uint32 band)const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   ossimRefPtr<ossimImageData> applyCast(ossimRefPtr<ossimImageData> input);
+   
+   /**
+    *  Method to save the state of an object to a keyword list.
+    *  Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+
+   /**
+    *   Override base class so that a disableSource event does not
+    *   reinitialize the object and enable itself.
+    */
+   virtual void propertyEvent(ossimPropertyEvent& event);
+   virtual void refreshEvent(ossimRefreshEvent& event);   
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+     
+protected:
+
+   void allocate(const ossimRefPtr<ossimImageData> inputTile);
+   
+   ossimRefPtr<ossimImageData> theTile;
+   ossimScalarType             theOutputScalarType;
+
+   template<class inType>
+   void castInputToOutput(inType **inBuffer,
+                          const double  *nullPix,
+                          bool   inPartialFlag);
+   
+   template<class inType, class outType>
+   void castInputToOutput(inType *inBuffer[],
+                          const double  *nullInPix,
+                          bool   inPartialFlag,
+                          outType *outBuffer[],
+                          const double  *nullOutPix,
+                          ossim_uint32   numberOfBands);
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimCastTileSourceFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimClosestToCenterCombiner.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimClosestToCenterCombiner.cpp
new file mode 100644
index 0000000000..ebef27ba0e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimClosestToCenterCombiner.cpp
@@ -0,0 +1,141 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimClosestToCenterCombiner.cpp,v 1.2 2005/09/22 17:20:56 gpotts Exp $
+#include "ossimClosestToCenterCombiner.h"
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF1(ossimClosestToCenterCombiner, "ossimClosestToCenterCombiner", ossimImageMosaic);
+
+ossimClosestToCenterCombiner::ossimClosestToCenterCombiner()
+   :ossimImageMosaic()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimClosestToCenterCombiner::getTile(const ossimIrect& rect,
+                                                                  ossim_uint32 resLevel)
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageMosaic::getTile(rect, resLevel);
+   }
+   if(!theTile.valid())
+   {
+      allocate();
+      if(!theTile.valid())
+      {
+         return 0;
+      }
+   }
+   theTile->setImageRectangle(rect);
+   theTile->makeBlank();
+   std::vector<ossimClosestToCenterCombinerInfo > normTileList;
+   ossimRefPtr<ossimImageData> currentTile = getNextNormTile(0, rect);
+   while(currentTile.valid())
+   {
+      normTileList.push_back(ossimClosestToCenterCombinerInfo((ossimImageData*)currentTile->dup(),
+                                                              theCurrentIndex));
+      currentTile = getNextNormTile(rect, resLevel);
+   }
+
+   
+   if(normTileList.size() == 1)
+   {
+      theTile->copyNormalizedBufferToTile((ossim_float32*)normTileList[0].theTile->getBuf());
+   }
+   else if(normTileList.size() > 1)
+   {
+      ossimRefPtr<ossimImageData> copyTile    = ossimImageDataFactory::instance()->create(0,
+                                                                                          OSSIM_NORMALIZED_FLOAT);
+      copyTile->setImageRectangleAndBands(rect,
+                                          getNumberOfOutputBands());
+      copyTile->initialize();
+                                                                                          
+      ossim_int32 idx   = 0;
+      ossim_uint32 w     = rect.width();
+      ossim_uint32 h     = rect.height();
+      ossim_uint32 idxW  = 0;
+      ossim_uint32 idxH  = 0;
+      ossimIpt origin    = rect.ul();
+      ossimIpt ulPt      = rect.ul();
+      ossim_uint32 band  = 0;
+      ossim_uint32 bands = copyTile->getNumberOfBands();
+      ossim_uint32 srcBandIdx = 0;
+      std::vector<ossim_float32*> bandList(bands);
+
+      for(band = 0; band < bands; ++band)
+      {
+         bandList[band] = (ossim_float32*)copyTile->getBuf(band);
+      }
+      ossim_uint32 offset   = 0;
+      origin.y = ulPt.y;
+      for(idxH = 0; idxH < h; ++idxH)
+      {
+         origin.x = ulPt.x;
+         for(idxW = 0; idxW < w;++idxW)
+         {
+            idx = findIdx(normTileList, origin, offset);
+
+            if(idx >=0)
+            {
+               for(band = 0; band < bands; ++band)
+               {
+                  srcBandIdx = ossimMin(normTileList[idx].theTile->getNumberOfBands(), band);
+                  
+                  bandList[band][offset] = *(((ossim_float32*)normTileList[idx].theTile->getBuf(srcBandIdx))+offset);
+               }
+            }
+            ++offset;
+            ++origin.x;
+         }
+         ++origin.y;
+      }
+      theTile->copyNormalizedBufferToTile((ossim_float32*)copyTile->getBuf());
+   }
+
+   theTile->validate();
+   
+   return theTile;
+
+}
+
+ossim_int32 ossimClosestToCenterCombiner::findIdx(const std::vector<ossimClosestToCenterCombinerInfo >& normTileList,
+                                                  const ossimIpt& pt, ossim_uint32 offset)const
+{
+   ossim_float32 distance = 1000000;
+   ossim_int32 returnIdx = -1;
+   ossim_float32 tempDistance;
+   ossim_int32 idx = 0;
+   ossim_int32 maxIdx = normTileList.size();
+   ossimIpt midPt;
+   ossimIrect rect;
+   for(idx = 0; idx < maxIdx; ++ idx)
+   {
+      rect = theFullResBounds[ normTileList[idx].theIndex ];
+      midPt = rect.midPoint();
+      
+      tempDistance = (pt-midPt).length();
+      if(tempDistance < distance)
+      {
+         if(normTileList[idx].theTile->getDataObjectStatus() == OSSIM_FULL)
+         {
+            distance = tempDistance;
+            returnIdx = idx;
+         }
+         else if(!normTileList[idx].theTile->isNull(offset))
+         {
+            distance = tempDistance;
+            returnIdx = idx;
+         }
+      }
+   }
+
+   return returnIdx;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimClosestToCenterCombiner.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimClosestToCenterCombiner.h
new file mode 100644
index 0000000000..4365ed9952
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimClosestToCenterCombiner.h
@@ -0,0 +1,60 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimClosestToCenterCombiner.h,v 1.2 2005/09/22 17:20:47 gpotts Exp $
+#ifndef ossimClosestToCenterCombiner_HEADER
+#define ossimClosestToCenterCombiner_HEADER
+#include <vector>
+#include "ossimImageMosaic.h"
+/**
+  * This implements a closest to center combiner.
+  *
+  * It will first grab all images overlapping a given rectangle query.  The first non-null
+  * closest pixel to the center of the image is used.  This basically uses only pixels along
+  * the "sweet" spot of the image.  This combiner is typically used when there is overlapping
+  * sensor data.
+  * 
+  */
+class ossimClosestToCenterCombiner : public ossimImageMosaic
+{
+public:
+   ossimClosestToCenterCombiner();
+
+   /**
+    * Executes the ossimClosestToCenterCombiner algorithm. sets the pixels to the closest
+    * Valid value.  This simulates a sweet spot cutter.
+    * 
+    * @param rect The region of interest.
+    * @param resLevel.  For this combiner this is assumed to always be 0
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+protected:
+   class ossimClosestToCenterCombinerInfo
+   {
+   public:
+      ossimClosestToCenterCombinerInfo(ossimRefPtr<ossimImageData> tile,
+                                       ossim_int32 idx)
+         :theTile(tile),
+         theIndex(idx)
+         {
+         }
+      ossimRefPtr<ossimImageData> theTile;
+      ossim_int32                 theIndex;
+   };
+
+   
+   ossim_int32 findIdx(const std::vector<ossimClosestToCenterCombinerInfo >& normTileList,
+                       const ossimIpt& pt, ossim_uint32 offset)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimColorNormalizedFusion.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimColorNormalizedFusion.cpp
new file mode 100644
index 0000000000..976da1cf36
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimColorNormalizedFusion.cpp
@@ -0,0 +1,144 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: Color normalized fusion
+//
+//*************************************************************************
+// $Id: ossimColorNormalizedFusion.cpp,v 1.6 2005/02/11 15:07:32 dburken Exp $
+
+#include <imaging/tile_sources/ossimColorNormalizedFusion.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/common/ossimErrorCodes.h>
+
+RTTI_DEF1(ossimColorNormalizedFusion,
+          "ossimColorNormalizedFusion",
+          ossimFusionCombiner);
+
+ossimColorNormalizedFusion::ossimColorNormalizedFusion()
+   : ossimFusionCombiner()
+{
+}
+
+ossimColorNormalizedFusion::ossimColorNormalizedFusion(ossimObject* owner)
+   : ossimFusionCombiner(owner)
+{
+}
+
+ossimColorNormalizedFusion::~ossimColorNormalizedFusion()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimColorNormalizedFusion::getTile(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> inputTile = getNormTile(rect, resLevel);
+
+   if(!inputTile.valid())
+   {
+      return NULL;
+   }
+   if(!theInputConnection||!theIntensityConnection)
+   {
+      return NULL;
+   }
+   
+   if((inputTile->getDataObjectStatus() == OSSIM_NULL)||
+      (inputTile->getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return NULL;
+   }
+
+   if(theTile.valid())
+   {
+      theTile->setImageRectangleAndBands(rect, inputTile->getNumberOfBands());
+   }
+
+   
+   ossim_float32* redBuff = (ossim_float32*)inputTile->getBuf(0);
+   ossim_float32* grnBuff = (ossim_float32*)inputTile->getBuf(1);
+   ossim_float32* bluBuff = (ossim_float32*)inputTile->getBuf(2);
+
+   if(!redBuff||!grnBuff||!bluBuff)
+   {
+      return inputTile;
+   }
+   ossimRefPtr<ossimImageData> inputIntensity = getNormIntensity(rect, resLevel);
+
+   if((!inputIntensity.valid()) ||
+      (!inputIntensity->getBuf()) ||
+      (inputIntensity->getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return inputTile;
+   }
+   
+   ossim_float32* mono_buff = (ossim_float32*)inputIntensity->getBuf(0);
+
+   // Since NULL_PIX_VALUE is only used for Pix8 comparisons cast it now.
+   const float NULL_PIX_VALUE = (ossim_float32)inputIntensity->getNullPix(0);
+   const float MIN_PIX_VALUE = (ossim_float32)inputIntensity->getMinPix(0);
+   const float MAX_PIX_VALUE = (ossim_float32)inputIntensity->getMaxPix(0);
+
+   float  rgb_sum;
+   float  r_wt; // Weight of red to rgb_sum.
+   float  g_wt; // Weight of green to rgb_sum.
+   float  b_wt; // Weight of blue to rgb_sum.
+   float  iVal;
+   float  redVal;
+   float  greenVal;
+   float  blueVal;
+
+   int size = theTile->getWidth()*theTile->getHeight();
+   
+   for (int i = 0; i < size;  i++)
+   {
+      //***
+      // If no intensity source, or, no rgb source make output pixels null.
+      //***
+      if ( (mono_buff[i] == NULL_PIX_VALUE) ||
+           (redBuff[i]   == NULL_PIX_VALUE &&
+            grnBuff[i]   == NULL_PIX_VALUE &&
+            bluBuff[i]   == NULL_PIX_VALUE) )
+           
+      {
+         redBuff[i] = NULL_PIX_VALUE;
+         grnBuff[i] = NULL_PIX_VALUE;
+         bluBuff[i] = NULL_PIX_VALUE;
+      }
+      else
+      {
+         redVal    = redBuff[i];
+         greenVal  = grnBuff[i];
+         blueVal   = bluBuff[i];
+         rgb_sum   = redVal + greenVal + blueVal + 3;
+	 r_wt      = 3 * (redVal + 1)   / rgb_sum;
+	 g_wt      = 3 * (greenVal + 1) / rgb_sum;
+	 b_wt      = 3 * (blueVal + 1)  / rgb_sum;
+         iVal      = mono_buff[i] + 1;
+	 
+	 redVal    = r_wt * iVal - 1;
+         greenVal  = g_wt * iVal - 1;
+	 blueVal   = b_wt * iVal - 1;
+
+         // Clip to max pixel value of radiometry.
+         if (redVal   > MAX_PIX_VALUE) redVal   = MAX_PIX_VALUE;
+         if (greenVal > MAX_PIX_VALUE) greenVal = MAX_PIX_VALUE;
+         if (blueVal  > MAX_PIX_VALUE) blueVal  = MAX_PIX_VALUE;
+
+         // Assign chip value, clamp to min pixel value of radiometry if zero.
+         redBuff[i] = (float)(redVal>0.0 ? redVal : MIN_PIX_VALUE);
+         grnBuff[i] = (float)(greenVal>0.0 ? greenVal : MIN_PIX_VALUE);
+         bluBuff[i] = (float)(blueVal>0.0 ? blueVal : MIN_PIX_VALUE);
+      }
+   } // End of loop through pixels in chip.
+   theTile->copyNormalizedBufferToTile((float*)inputTile->getBuf());
+   theTile->validate();
+
+   return theTile;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimColorNormalizedFusion.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimColorNormalizedFusion.h
new file mode 100644
index 0000000000..f73f6a9fed
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimColorNormalizedFusion.h
@@ -0,0 +1,32 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: Color normalized fusion
+//
+//*************************************************************************
+// $Id: ossimColorNormalizedFusion.h,v 1.4 2005/02/11 15:07:32 dburken Exp $
+#ifndef ossimColorNormalizedFusion_HEADER
+#define ossimColorNormalizedFusion_HEADER
+#include "ossimFusionCombiner.h"
+
+class ossimColorNormalizedFusion : public ossimFusionCombiner
+{
+public:
+
+   ossimColorNormalizedFusion();
+   ossimColorNormalizedFusion(ossimObject* owner);
+   virtual ~ossimColorNormalizedFusion();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+
+protected:
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionFilter1D.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionFilter1D.cpp
new file mode 100644
index 0000000000..29c00d5afc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionFilter1D.cpp
@@ -0,0 +1,638 @@
+//*******************************************************************
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//*************************************************************************
+// $Id: ossimConvolutionFilter1D.cpp,v 1.1 2005/09/12 11:35:39 gpotts Exp $
+
+
+#include <imaging/tile_sources/ossimConvolutionFilter1D.h>
+#include <base/data_types/ossimIrect.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/property/ossimMatrixProperty.h>
+#include <base/property/ossimBooleanProperty.h>
+#include <base/property/ossimNumericProperty.h>
+
+RTTI_DEF1(ossimConvolutionFilter1D, "ossimConvolutionFilter1D", ossimImageSourceFilter);
+
+#define PROPNAME_KERNELSIZE "KernelSize"
+#define PROPNAME_KERNEL "Kernel"
+#define PROPNAME_ISHZ   "Horizontal"
+#define PROPNAME_CENTEROFFSET "CenterOffset"
+
+
+ossimConvolutionFilter1D::ossimConvolutionFilter1D(ossimObject* owner)
+   :ossimImageSourceFilter(owner),
+    theCenterOffset(0),
+    theTile(NULL),
+    theIsHz(true),
+    theNullPixValue(0),
+    theMinPixValue(0),
+    theMaxPixValue(0)
+{
+   //sets up an identity convolution
+   theKernel.push_back(1.0);
+}
+
+ossimConvolutionFilter1D::~ossimConvolutionFilter1D()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimConvolutionFilter1D::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return theTile;
+   }
+
+   if(!isSourceEnabled())
+   {
+      return theInputConnection->getTile(tileRect, resLevel);
+   }
+
+   //---
+   // We have a 1xn or nx1 matrix, + a center offset
+   // so stretch the input rect out to cover the required pixels
+   //---
+   ossimIrect  newRect;
+   ossim_int32 kl = theKernel.size(); //kernel length
+   if (theIsHz)
+   {
+      //horizontal kernel (row kernel)
+      newRect = ossimIrect(ossimIpt(tileRect.ul().x - theCenterOffset,
+                                    tileRect.ul().y),
+                           ossimIpt(tileRect.lr().x - theCenterOffset + kl -1,
+                                    tileRect.lr().y));
+   } else {
+      //vertical kernel
+      newRect = ossimIrect(ossimIpt(tileRect.ul().x,
+                                    tileRect.ul().y - theCenterOffset),
+                           ossimIpt(tileRect.lr().x,
+                                    tileRect.lr().y - theCenterOffset + kl -1));
+   }
+   ossimRefPtr<ossimImageData> data = theInputConnection->getTile(newRect,
+                                                                  resLevel);
+
+   if(!data.valid() || !data->getBuf())
+   {
+      return data;
+   }
+
+    // First time through or after an initialize()...
+   if (!theTile.valid())
+   {
+      allocate();
+      if (!theTile.valid()) // Should never happen!
+      {
+         return data;
+      }
+   }
+
+   // First time through, after an initialize() or a setKernel()...
+   if (!theNullPixValue.size())
+   {
+      computeNullMinMax();
+      if (!theNullPixValue.size()) // Should never happen!
+      {
+         return data;
+      }
+   }
+
+   theTile->setImageRectangle(tileRect);
+   theTile->makeBlank();
+   
+   switch(data->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<ossim_uint8>(0), data, theTile);
+         }
+         else
+         {
+            convolvePartial(static_cast<ossim_uint8>(0), data, theTile);
+         }
+         break;
+      }
+      case OSSIM_FLOAT: 
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<float>(0), data, theTile);
+         }
+         else
+         {
+            convolvePartial(static_cast<float>(0), data, theTile);
+         }
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<ossim_uint16>(0), data, theTile);
+         }
+         else
+         {
+            convolvePartial(static_cast<ossim_uint16>(0), data, theTile);
+         }
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<ossim_sint16>(0), data, theTile);
+         }
+         else
+         {
+            convolvePartial(static_cast<ossim_sint16>(0), data, theTile);
+         }
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         if(data->getDataObjectStatus() == OSSIM_FULL)
+         {
+            convolveFull(static_cast<double>(0), data, theTile);
+      }
+      else
+      {
+         convolvePartial(static_cast<double>(0), data, theTile);
+      }
+         break;
+      }
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimConvolutionFilter1D::getTile WARNING:\n"
+            << "Scalar type = " << theTile->getScalarType()
+            << " Not supported by ossimConvolutionFilter1D" << endl;
+         break;
+      }
+   }
+   theTile->validate();
+   
+   return theTile;
+}
+
+
+template<class T> void ossimConvolutionFilter1D::convolvePartial(
+   T,
+   ossimRefPtr<ossimImageData> inputData,
+   ossimRefPtr<ossimImageData> outputData)
+{
+   // there may be NULL pixels in the input
+   ossim_int32 inputW = static_cast<ossim_int32>(inputData->getWidth());
+   ossim_uint32 outputW       = outputData->getWidth();
+   ossim_uint32 outputH       = outputData->getHeight();
+   ossim_uint32 numberOfBands = inputData->getNumberOfBands();
+   
+   ossim_uint32 klength=theKernel.size(),k;
+   ossim_int32 incrK = theIsHz ? 1 : inputW; //kernel increment in input : one col or one row
+   ossim_int32 iRow  = inputW - outputW; //jump to go to next row
+
+   double sum=0.0;
+   T* iKP; //kernel covered input pointer
+
+   ossim_int32 iCo = incrK*theCenterOffset; //center  pixel offset within the input buffer
+
+   for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+   {
+      T* inputBuf  = static_cast<T*>(inputData->getBuf(band));
+      T* outputBuf = static_cast<T*>(outputData->getBuf(band));
+      T maxPix     = static_cast<T>(getMaxPixelValue(band));
+      T minPix     = static_cast<T>(getMinPixelValue(band));
+      T nullPix    = static_cast<T>(inputData->getNullPix(band));
+      T oNullPix   = static_cast<T>(getNullPixelValue(band));
+      
+      if(inputBuf&&outputBuf)
+      {
+         for(ossim_uint32 row = 0; row < outputH; ++row)
+         {
+            for(ossim_uint32 col = 0; col < outputW; ++col)
+            {
+               //center pixel may not be NULL
+               if (inputBuf[iCo] != nullPix)
+               {
+                  iKP = inputBuf; 
+                  sum = 0.0;
+                  for(k=0;k<klength;++k)
+                  {
+                     if (*iKP != nullPix) //just sum on non-NULL pixels (potential normailzation issue)
+                     {
+                        sum += theKernel[k] * (double)(*iKP);                   
+                     }
+                     iKP += incrK;
+                  }
+                  
+                  if(sum > maxPix)
+                  {
+                     *outputBuf = maxPix;
+                  }
+                  else if(sum < minPix)
+                  {
+                     *outputBuf = minPix;
+                  }
+                  else
+                  {
+                     *outputBuf = static_cast<T>(sum);
+                  }
+               } else {
+                  *outputBuf = oNullPix;
+               }
+               // move curent center position
+               inputBuf  += 1;
+               outputBuf += 1;
+            }
+            //move current center position
+            inputBuf  += iRow;
+            //outputBuf += 0;
+         }
+      }
+   }
+    
+   
+}
+
+template<class T> void ossimConvolutionFilter1D::convolveFull(
+   T,
+   ossimRefPtr<ossimImageData> inputData,
+   ossimRefPtr<ossimImageData> outputData)
+{
+   //inputData must be displaced according to the Kernel size and theCenterOffset +isHz
+   ossim_int32 inputW = static_cast<ossim_int32>(inputData->getWidth());
+   ossim_uint32 outputW       = outputData->getWidth();
+   ossim_uint32 outputH       = outputData->getHeight();
+   ossim_uint32 numberOfBands = inputData->getNumberOfBands();
+   
+   ossim_uint32 klength=theKernel.size(), k;
+   ossim_int32 incrK = theIsHz ? 1 : inputW; //kernel increment in input : one col or one row
+   ossim_int32 iRow  = inputW - outputW; //jump to go to next row
+
+   double sum=0.0;
+   T* iKP; //kernel covered input pointer
+
+   for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+   {
+      T* inputBuf  = static_cast<T*>(inputData->getBuf(band));
+      T* outputBuf = static_cast<T*>(outputData->getBuf(band));
+      T maxPix     = static_cast<T>(getMaxPixelValue(band));
+      T minPix     = static_cast<T>(getMinPixelValue(band));
+      
+      if(inputBuf&&outputBuf)
+      {
+         for(ossim_uint32 row = 0; row < outputH; ++row)
+         {
+            for(ossim_uint32 col = 0; col < outputW; ++col)
+            {
+               sum = 0.0;
+               iKP = inputBuf;
+               for(k=0;k<klength;++k)
+               {
+                  sum += theKernel[k] * (double)(*iKP);
+                  iKP += incrK;
+               }
+               
+               if(sum > maxPix)
+               {
+                  *outputBuf = maxPix;
+               }
+               else if(sum < minPix)
+               {
+                  *outputBuf = minPix;
+               }
+               else
+               {
+                  *outputBuf = static_cast<T>(sum);
+               }
+               // move curent center position
+               inputBuf  += 1;
+               outputBuf += 1;
+            }
+            //move current center position
+            inputBuf  += iRow;
+            //outputBuf += 0;
+         }
+      }
+   }
+}
+
+void ossimConvolutionFilter1D::initialize()
+{
+   //---
+   // NOTE:
+   // Since initialize get called often sequentially we will wipe things slick
+   // but not reallocate to avoid multiple delete/allocates.
+   //
+   // On the first getTile call things will be reallocated/computed.
+   //---
+   theTile = NULL;
+   clearNullMinMax();
+}
+
+void ossimConvolutionFilter1D::allocate()
+{   
+   if(theInputConnection)
+   {
+      ossimImageDataFactory* idf = ossimImageDataFactory::instance();
+      
+      theTile = idf->create(this,
+                            this);
+      
+      theTile->initialize();
+   }
+}
+
+void ossimConvolutionFilter1D::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property) return;
+
+   if(property->getName() == PROPNAME_KERNEL)
+   {
+      ossimMatrixProperty* matrixProperty = PTR_CAST(ossimMatrixProperty,
+                                                     property.get());
+      if(matrixProperty)
+      {
+         ossim_uint32 nc=matrixProperty->getNumberOfCols();
+         theKernel.resize(nc);
+         for(ossim_uint32 i=0;i<nc;++i)
+         {
+             theKernel[i] = (*matrixProperty)(0,i);
+         }
+         clearNullMinMax();
+      }
+      else
+      {
+         ossimImageSourceFilter::setProperty(property);
+      }
+   } else if (property->getName() == PROPNAME_ISHZ)  {
+      ossimBooleanProperty* booleanProperty = PTR_CAST(ossimBooleanProperty,
+                                                     property.get());
+      if(booleanProperty)
+      {
+         theIsHz = booleanProperty->getBoolean();
+      }
+   } else if (property->getName() == PROPNAME_CENTEROFFSET)  {
+      ossimNumericProperty* numProperty = PTR_CAST(ossimNumericProperty,
+                                                     property.get());
+      if(numProperty)
+      {
+         theCenterOffset = numProperty->asInt32();
+      }
+   } else if (property->getName() == PROPNAME_KERNELSIZE)  {
+      ossimNumericProperty* numProperty = PTR_CAST(ossimNumericProperty,
+                                                     property.get());
+      if(numProperty)
+      {
+         theKernel.resize(numProperty->asUInt32());
+         clearNullMinMax();
+      }
+   } else {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimConvolutionFilter1D::getProperty(const ossimString& name)const
+{
+   if(name == PROPNAME_KERNEL)
+   {
+      ossimMatrixProperty* property = new ossimMatrixProperty(name);
+      property->resize(1,theKernel.size());
+      for(ossim_uint32 i=0;i<theKernel.size();++i)
+      {
+        (*property)(0,i) = theKernel[i];
+      }
+      property->setCacheRefreshBit();
+      return property;
+   } else if (name==PROPNAME_ISHZ) {
+      ossimBooleanProperty* property = new ossimBooleanProperty(name,theIsHz);
+      property->setCacheRefreshBit();
+      return property;
+   } else if (name==PROPNAME_CENTEROFFSET) {
+      ossimNumericProperty* property = new ossimNumericProperty(name,ossimString::toString(theCenterOffset));
+      property->setNumericType(ossimNumericProperty::ossimNumericPropertyType_INT); //restrict to int type
+      property->setCacheRefreshBit();
+      return property;
+   } else if (name == PROPNAME_KERNELSIZE) {
+      ossimNumericProperty* property = new ossimNumericProperty(name,ossimString::toString(theKernel.size()),1.0,100.0);
+      property->setNumericType(ossimNumericProperty::ossimNumericPropertyType_INT); //restrict to int type
+      property->setCacheRefreshBit();
+      return property;
+   }
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimConvolutionFilter1D::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   propertyNames.push_back(PROPNAME_KERNELSIZE);
+   propertyNames.push_back(PROPNAME_KERNEL);
+   propertyNames.push_back(PROPNAME_CENTEROFFSET);
+   propertyNames.push_back(PROPNAME_ISHZ);
+}
+
+bool ossimConvolutionFilter1D::saveState(ossimKeywordlist& kwl,
+                                          const char* prefix)const
+{   
+   kwl.add(prefix,
+           PROPNAME_KERNELSIZE,
+           theKernel.size(),
+           true);
+   kwl.add(prefix,
+          PROPNAME_CENTEROFFSET,
+           theCenterOffset,
+           true);
+   kwl.add(prefix,
+          PROPNAME_ISHZ,
+           theIsHz?"true":"false", //use string instead of boolean
+           true);
+
+   for(ossim_uint32 row = 0; row < theKernel.size(); ++row)
+   {
+         ossimString newPrefix = "k" + ossimString::toString(row);
+         kwl.add(prefix,
+                 newPrefix,
+                 theKernel[row],
+                 true);          
+   }
+
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+
+bool ossimConvolutionFilter1D::loadState(const ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   //find kernel size
+   ossim_uint32 iks=0;
+   const char* ks = kwl.find(prefix, PROPNAME_KERNELSIZE);
+   if(ks)
+   {
+      iks = ossimString(ks).toUInt32();
+      if (iks<1)
+      {
+         cerr<<"ossimConvolutionFilter1D : warning bad "<< PROPNAME_KERNELSIZE <<" in state"<<endl;
+         iks=0;
+      }
+   } else {
+      iks=0;
+      cerr<<"ossimConvolutionFilter1D : warning no "<< PROPNAME_KERNELSIZE <<" in state"<<endl;
+   }
+
+   //load other props
+   const char* co = kwl.find(prefix, PROPNAME_CENTEROFFSET);
+   if(co)
+   {      
+      setCenterOffset(ossimString(co).toUInt32());
+   } else {
+      cerr<<"ossimConvolutionFilter1D : warning no "<< PROPNAME_CENTEROFFSET<<" in state"<<endl;
+   }
+   const char* ih = kwl.find(prefix, PROPNAME_ISHZ);
+   if(ih)
+   {      
+      setIsHorizontal(ossimString(ih).toBool());
+   } else {
+      cerr<<"ossimConvolutionFilter1D : warning no "<<PROPNAME_ISHZ<<" in state"<<endl;
+   }
+
+   //load kernel values
+   ossimString newPrefix = prefix;
+   newPrefix += ossimString("k");
+   theKernel.resize(iks);
+   for(ossim_uint32 r=0; r<iks; ++r)
+   {      
+      ossimString value = ossimString::toString(r);
+      
+      const char* v = kwl.find(newPrefix.c_str(),
+                               value.c_str());
+      if(v)
+      {
+         theKernel[r] = ossimString(v).toDouble();
+      } else {
+         cerr<<"ossimConvolutionFilter1D : warning no value for "<<newPrefix<<" in state"<<endl;
+         theKernel[r] = 0.0;
+      }
+   }
+   clearNullMinMax();
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+void ossimConvolutionFilter1D::setKernel(const std::vector<ossim_float64>& aKernel)
+{
+   theKernel = aKernel;
+   // Will be recomputed first getTile call.
+   clearNullMinMax();
+}
+
+double ossimConvolutionFilter1D::getNullPixelValue(ossim_uint32 band)const
+{
+   if( isSourceEnabled() && (band < theNullPixValue.size()) )
+   {
+      return theNullPixValue[band];
+   }
+
+   return ossimGetDefaultNull(getOutputScalarType());
+}
+
+double ossimConvolutionFilter1D::getMinPixelValue(ossim_uint32 band)const
+{
+   if( isSourceEnabled() && (band < theMinPixValue.size()) )
+   {
+      return theMinPixValue[band];
+   }
+   
+   return ossimImageSource::getMinPixelValue(band);
+}
+
+double ossimConvolutionFilter1D::getMaxPixelValue(ossim_uint32 band)const
+{
+   if( isSourceEnabled() && (band < theMaxPixValue.size()) )
+   {
+      return theMaxPixValue[band];
+   }
+
+   return ossimImageSource::getMaxPixelValue(band);
+}
+
+void ossimConvolutionFilter1D::clearNullMinMax()
+{
+   theNullPixValue.clear();
+   theMinPixValue.clear();
+   theMaxPixValue.clear();
+}
+
+void ossimConvolutionFilter1D::computeNullMinMax()
+{
+   const ossim_uint32 BANDS = getNumberOfOutputBands();
+
+   theNullPixValue.resize(BANDS);
+   theMinPixValue.resize(BANDS);
+   theMaxPixValue.resize(BANDS);
+
+   ossim_float64 defaultNull = ossimGetDefaultNull(getOutputScalarType());
+   ossim_float64 defaultMin = ossimGetDefaultMin(getOutputScalarType());
+   ossim_float64 defaultMax = ossimGetDefaultMax(getOutputScalarType());
+  
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      if(theInputConnection)
+      {
+         ossim_float64 inputNull = theInputConnection->getNullPixelValue(band);
+         ossim_float64 inputMin  = theInputConnection->getMinPixelValue(band);
+         ossim_float64 inputMax  = theInputConnection->getMaxPixelValue(band);
+         ossim_float64 tempMin   = 0.0;
+         ossim_float64 tempMax   = 0.0;
+         ossim_float64 k         = 0.0;
+         for(ossim_uint32 i=0;i<theKernel.size();++i)
+         {          
+               k=theKernel[i];
+               tempMin += (k<0.0) ? k*inputMax : k*inputMin;
+               tempMax += (k>0.0) ? k*inputMax : k*inputMin;          
+         }
+         
+         if((tempMin >= defaultMin) && (tempMin <= defaultMax))
+         {
+            theMinPixValue[band] = tempMin;
+         }
+         else
+         {
+            theMinPixValue[band] = defaultMin;
+         }
+
+         if((tempMax >= defaultMin) && (tempMax <= defaultMax))
+         {
+            theMaxPixValue[band] = tempMax;
+         }
+         else
+         {
+            theMaxPixValue[band] = defaultMax;
+         }
+         if((inputNull < theMinPixValue[band]) ||
+            (inputNull > theMaxPixValue[band]))
+         {
+            theNullPixValue[band] = inputNull;
+         }
+         else
+         {
+            theNullPixValue[band] = defaultNull;
+         }
+         
+      }
+      else // No input connection...
+      {
+         theNullPixValue[band] = defaultNull;
+         theMinPixValue[band]  = defaultMin;
+         theMaxPixValue[band]  = defaultMax;
+      }
+      
+   } // End of band loop.
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionFilter1D.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionFilter1D.h
new file mode 100644
index 0000000000..66602919dc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionFilter1D.h
@@ -0,0 +1,102 @@
+//*******************************************************************
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// class ossimImageGaussianFilter : tile source
+// class ossimConvolutionFilter1D
+// one dimensional convolution
+//
+// efficient for gradients & separable convolution kernels (like gaussian)
+//*******************************************************************
+// $Id: ossimConvolutionFilter1D.h,v 1.2 2005/09/12 13:39:07 gpotts Exp $
+
+#ifndef ossimConvolutionFilter1D_HEADER
+#define ossimConvolutionFilter1D_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class OSSIM_DLL ossimConvolutionFilter1D : public ossimImageSourceFilter
+{
+public:
+   //! own class methods
+   ossimConvolutionFilter1D(ossimObject* owner=NULL);
+   virtual ~ossimConvolutionFilter1D();
+
+   virtual inline const std::vector<ossim_float64>& getKernel()const { return theKernel; }
+   virtual void setKernel(const std::vector<ossim_float64>& aKernel);
+
+   virtual inline bool isHorizontal()const         { return theIsHz; }
+   virtual inline void setIsHorizontal(bool aIsHz) { theIsHz = aIsHz; }
+
+   virtual inline ossim_int32 getCenterOffset()const              { return theCenterOffset; }
+   virtual inline void setCenterOffset(ossim_int32 aCenterOffset) { theCenterOffset = aCenterOffset; }
+   
+   //! inherited methods
+   virtual ossimString getShortName()const{return ossimString("1D Convolution");}
+   virtual ossimString getLongName()const{return ossimString("Convolves the input image with a one dimensional convolution kernel");}
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+
+   virtual double getNullPixelValue(ossim_uint32 band=0) const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)  const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)  const;
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,const char* prefix = 0);
+   virtual bool saveState(ossimKeywordlist& kwl,const char* prefix = 0)const;
+   
+protected:
+
+   /**
+    * Allocates theTile.
+    */
+   void allocate();
+
+   /**
+    * Clears data members theNullPixValue, theMinPixValue, and
+    * theMaxPixValue.
+    */
+   void clearNullMinMax();
+
+   /**
+    * Computes null, min, and max considering input connection and theKernel.
+    */
+   void computeNullMinMax();
+      
+   /*!
+    * Convolve full means that the input data is full and has
+    * no null data.  We don't have to compare for nulls here
+    */
+   template<class T>
+   void convolveFull(T,
+                     ossimRefPtr<ossimImageData> inputData,
+                     ossimRefPtr<ossimImageData> outputData);
+   
+   /*!
+    * Convolve partial means that the input data is has some
+    * null data.  We will have to compare nulls
+    */
+   template<class T>
+   void convolvePartial(T,
+                        ossimRefPtr<ossimImageData> inputData,
+                        ossimRefPtr<ossimImageData> outputData);
+
+   //! offset of center point in the Kernel
+   ossim_int32                theCenterOffset;
+   ossimRefPtr<ossimImageData> theTile;
+   std::vector<ossim_float64>  theKernel;
+   bool                        theIsHz; //! isHorizontal convolution?
+
+   std::vector<double> theNullPixValue;
+   std::vector<double> theMinPixValue;
+   std::vector<double> theMaxPixValue;
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimConvolutionFilter1D_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionSource.cpp
new file mode 100644
index 0000000000..d2405e22ce
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionSource.cpp
@@ -0,0 +1,525 @@
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimConvolutionSource.cpp,v 1.17 2005/12/08 13:56:23 gpotts Exp $
+
+#include <imaging/tile_sources/ossimConvolutionSource.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/filters/ossimDiscreteConvolutionKernel.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimKeyword.h>
+
+static const ossimKeyword NUMBER_OF_MATRICES = ossimKeyword("number_of_matrices", "");
+static const ossimKeyword NUMBER_OF_ROWS = ossimKeyword("rows", "");
+static const ossimKeyword NUMBER_OF_COLS = ossimKeyword("cols", "");
+
+RTTI_DEF1(ossimConvolutionSource, "ossimConvolutionSource", ossimImageSourceFilter);
+
+ossimConvolutionSource::ossimConvolutionSource()
+   : ossimImageSourceFilter(),
+     theTile(NULL)
+{
+}
+
+ossimConvolutionSource::ossimConvolutionSource(ossimImageSource* inputSource,
+                                               const NEWMAT::Matrix& convolutionMatrix)
+   : ossimImageSourceFilter(inputSource),
+     theTile(NULL)
+{
+   theConvolutionKernelList.push_back(new ossimDiscreteConvolutionKernel(convolutionMatrix));
+   setKernelInformation();
+   initialize();
+}
+
+ossimConvolutionSource::ossimConvolutionSource(ossimImageSource* inputSource,
+                                               const vector<NEWMAT::Matrix>& convolutionList)
+   : ossimImageSourceFilter(inputSource),
+     theTile(NULL)
+{
+   setConvolutionList(convolutionList);
+}
+
+ossimConvolutionSource::~ossimConvolutionSource()
+{
+   deleteConvolutionList();
+}
+
+void ossimConvolutionSource::setConvolution(const double* kernel,
+                                            int nrows,
+                                            int ncols,
+                                            bool doWeightedAverage)
+{
+   NEWMAT::Matrix m(nrows, ncols);
+   const double* tempPtr = kernel;
+   for(int row = 0; row < nrows; ++row)
+   {
+      for(int col = 0; col < ncols; ++col)
+      {
+         m[row][col] =*tempPtr;
+         ++tempPtr;
+      }
+   }
+   
+   setConvolution(m, doWeightedAverage);
+}
+
+void ossimConvolutionSource::setConvolutionList(const vector<NEWMAT::Matrix>& convolutionList,
+                                                bool doWeightedAverage)
+{
+   deleteConvolutionList();
+   ossim_uint32 idx;
+   for(idx = 0; idx < convolutionList.size(); ++idx)
+   {
+      theConvolutionKernelList.push_back(new ossimDiscreteConvolutionKernel(convolutionList[idx],
+                                                                            doWeightedAverage));
+   }
+
+   setKernelInformation();
+}
+
+ossimRefPtr<ossimImageData> ossimConvolutionSource::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection) return ossimRefPtr<ossimImageData>();
+
+   if((!isSourceEnabled())||
+      (theConvolutionKernelList.size() < 1))
+   {
+      return theInputConnection->getTile(tileRect, resLevel);
+   }
+   
+   if(!theTile.valid())
+   {
+      allocate();
+      if(!theTile.valid())  // Throw exception???
+      {
+         return theInputConnection->getTile(tileRect, resLevel);
+      }
+   }
+   
+   ossim_uint32 w  = tileRect.width();
+   ossim_uint32 h  = tileRect.height();
+   ossim_uint32 tw = theTile->getWidth();
+   ossim_uint32 th = theTile->getHeight();
+   theTile->setWidth(w);
+   theTile->setHeight(h);
+   if((w*h)!=(tw*th))
+   {
+      theTile->initialize();
+      theTile->makeBlank();
+   }
+   else
+   {
+      theTile->makeBlank();
+   }
+   theTile->setOrigin(tileRect.ul());
+   long offsetX = (theMaxKernelWidth)/2;
+   long offsetY = (theMaxKernelHeight)/2;
+   ossimIrect requestRect(tileRect.ul().x - offsetX,
+                          tileRect.ul().y - offsetY,
+                          tileRect.lr().x + offsetX,
+                          tileRect.lr().y + offsetY);
+   
+   ossimRefPtr<ossimImageData> input = theInputConnection->getTile(requestRect,
+                                                                   resLevel);
+
+   if(!input.valid() ||
+      (input->getDataObjectStatus() == OSSIM_NULL)||
+      (input->getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return input;
+   }
+   switch(theTile->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      if(theConvolutionKernelList.size() == 1)
+      {
+         convolve(static_cast<ossim_uint8>(0),
+                  input,
+                  theConvolutionKernelList[0]);
+      }
+      else
+      {
+         ossim_uint32 upperBound = theConvolutionKernelList.size();
+         ossim_uint32 idx;
+         for(idx = 0; idx < upperBound; ++idx)
+         {
+            convolve(static_cast<ossim_uint8>(0),
+                     input,
+                     theConvolutionKernelList[idx]);
+            input->loadTile(theTile.get());
+         }
+      }
+      break;
+   }
+   case OSSIM_USHORT16:
+   case OSSIM_USHORT11:
+   {
+      if(theConvolutionKernelList.size() == 1)
+      {
+         convolve(static_cast<ossim_uint16>(0),
+                  input,
+                  theConvolutionKernelList[0]);
+      }
+      else
+      {
+         ossim_uint32 upperBound = theConvolutionKernelList.size();
+         ossim_uint32 idx;
+         for(idx = 0; idx < upperBound; ++idx)
+         {
+            convolve(static_cast<ossim_uint16>(0),
+                     input,
+                     theConvolutionKernelList[idx]);
+            input->loadTile(theTile.get());
+         }
+      }
+      break;
+   }
+   case OSSIM_SSHORT16:
+   {
+      if(theConvolutionKernelList.size() == 1)
+      {
+         convolve(static_cast<ossim_sint16>(0),
+                  input,
+                  theConvolutionKernelList[0]);
+      }
+      else
+      {
+         ossim_uint32 upperBound = theConvolutionKernelList.size();
+         ossim_uint32 idx;
+         for(idx = 0; idx < upperBound; ++idx)
+         {
+            convolve(static_cast<ossim_sint16>(0),
+                     input,
+                     theConvolutionKernelList[idx]);
+            input->loadTile(theTile.get());
+         }
+      }
+      break;
+   }
+   case OSSIM_FLOAT:
+   case OSSIM_NORMALIZED_FLOAT:
+   {
+      if(theConvolutionKernelList.size() == 1)
+      {
+         convolve(static_cast<float>(0),
+                  input,
+                  theConvolutionKernelList[0]);
+      }
+      else
+      {
+         ossim_uint32 upperBound = theConvolutionKernelList.size();
+         ossim_uint32 idx;
+         for(idx = 0; idx < upperBound; ++idx)
+         {
+            convolve(static_cast<float>(0),
+                     input,
+                     theConvolutionKernelList[idx]);
+            input->loadTile(theTile.get());
+         }
+      }
+      break;
+   }
+   case OSSIM_DOUBLE:
+   case OSSIM_NORMALIZED_DOUBLE:
+   {
+      if(theConvolutionKernelList.size() == 1)
+      {
+         convolve(static_cast<double>(0),
+                  input,
+                  theConvolutionKernelList[0]);
+      }
+      else
+      {
+         ossim_uint32 upperBound = theConvolutionKernelList.size();
+         ossim_uint32 idx;
+         for(idx = 0; idx < upperBound; ++idx)
+         {
+            convolve(static_cast<double>(0),
+                     input,
+                     theConvolutionKernelList[idx]);
+            input->loadTile(theTile.get());
+         }
+      }
+      break;
+   }
+   default:
+   {
+      theTile->loadTile(input.get());
+   }
+   }
+   theTile->validate();
+   return theTile;
+}
+   
+template <class T>
+void ossimConvolutionSource::convolve(T dummyVariable,
+                                      ossimRefPtr<ossimImageData> inputTile,
+                                      ossimDiscreteConvolutionKernel* kernel)
+{
+   ossimIpt startOrigin   = theTile->getOrigin();
+
+   // Make sure that the patch is not empty or NULL
+   //
+   ossimIpt startDelta(startOrigin.x - inputTile->getOrigin().x,
+                       startOrigin.y - inputTile->getOrigin().y);
+
+   ossimDataObjectStatus status = inputTile->getDataObjectStatus();
+   // let's setup some variables that we will need to do the
+   // convolution algorithm.
+   //
+   ossimIrect patchRect   = inputTile->getImageRectangle();
+   long tileHeight        = theTile->getHeight();
+   long tileWidth         = theTile->getWidth();
+   long outputBands       = theTile->getNumberOfBands();
+   long convolutionWidth  = kernel->getWidth();
+   long convolutionHeight = kernel->getHeight();
+   long convolutionOffsetX= convolutionWidth/2;
+   long convolutionOffsetY= convolutionHeight/2;
+   long patchWidth        = patchRect.width();
+   long convolutionTopLeftOffset = 0;
+   long convolutionCenterOffset  = 0;
+   
+   long outputOffset          = 0;
+   T min = 0;
+   T max = 0;
+   T np = 0;
+   const double* minPix  = inputTile->getMinPix();
+   const double* maxPix  = inputTile->getMaxPix();
+   const double* nullPix = inputTile->getNullPix();
+   double convolveResult = 0;
+   
+   if(status == OSSIM_PARTIAL) // must check for NULLS
+   {
+      for(long y = 0; y <tileHeight; y++)
+      {
+         convolutionCenterOffset  = patchWidth*(startDelta.y + y) + startDelta.x;
+         convolutionTopLeftOffset = patchWidth*(startDelta.y + y - convolutionOffsetY) + startDelta.x-convolutionOffsetX;
+         
+         for(long x =0; x < tileWidth; x++)
+         {
+            if(!inputTile->isNull(convolutionCenterOffset))
+            {
+               for(long b = 0; b < outputBands; ++b)
+               {
+                  T* buf    = (T*)(inputTile->getBuf(b)) + convolutionTopLeftOffset;
+                  T* outBuf = (T*)(theTile->getBuf(b));
+                  kernel->convolveSubImage(buf,
+                                           patchWidth,
+                                           convolveResult,
+                                           (T)nullPix[b]);
+                  convolveResult = convolveResult < minPix[b]? minPix[b]:convolveResult;
+                  convolveResult = convolveResult > maxPix[b]? maxPix[b]:convolveResult;
+                  
+                  outBuf[outputOffset] = (T)convolveResult;
+               }
+            }
+            else
+            {
+               theTile->setNull(outputOffset);
+               
+            }
+            ++convolutionCenterOffset;
+            ++convolutionTopLeftOffset;
+            ++outputOffset;
+         }
+      }
+   }
+   else  // do not need to check for nulls here.
+   {
+      for(long b = 0; b < outputBands; ++b)
+      {                  
+         double convolveResult = 0;
+         const T* buf = (const T*)inputTile->getBuf(b);
+         T* outBuf    = (T*)(theTile->getBuf(b));
+         min=(T)minPix[b];
+         max=(T)maxPix[b];
+         np =(T)nullPix[b];
+         outputOffset = 0;
+         
+         for(long y = 0; y <tileHeight; y++)
+         {
+            convolutionTopLeftOffset = patchWidth*(startDelta.y + y - convolutionOffsetY) + startDelta.x-convolutionOffsetX;
+            
+            for(long x =0; x < tileWidth; x++)
+            {
+               kernel->convolveSubImage(&buf[convolutionTopLeftOffset],
+                                        patchWidth,
+                                        convolveResult,
+                                        np);
+               convolveResult = convolveResult < min? min:convolveResult;
+               convolveResult = convolveResult > max?max:convolveResult;
+               outBuf[outputOffset] = (T)convolveResult;
+               ++outputOffset;
+               ++convolutionTopLeftOffset;
+            }
+         }
+      }
+   }
+}
+
+void ossimConvolutionSource::initialize()
+{
+   ossimImageSourceFilter::initialize();
+   theTile = NULL;
+}
+
+void ossimConvolutionSource::allocate()
+{
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,
+                                                          theInputConnection);
+      theTile->initialize();
+   }
+}
+
+bool ossimConvolutionSource::saveState(ossimKeywordlist& kwl,
+                                       const char* prefix)const
+{
+   long numberOfMatrices = 0;
+   for(long m = 0; m < (long)theConvolutionKernelList.size();++m)
+   {
+      if(theConvolutionKernelList[m])
+      {
+         ++numberOfMatrices;
+         const NEWMAT::Matrix& kernel = theConvolutionKernelList[m]->getKernel();
+         ossimString mPrefix = "m" +
+                               ossimString::toString(numberOfMatrices) +
+                               ".";
+         kwl.add(prefix,
+                 (mPrefix + "rows").c_str(),
+                 kernel.Nrows(),
+                 true);
+         
+         kwl.add(prefix,
+                 (mPrefix + "cols").c_str(),
+                 kernel.Ncols(),
+                 true);
+         
+         for(long row = 0; row < kernel.Nrows(); ++row)
+         {
+            for(long col =0; col < kernel.Ncols(); ++col)
+            {
+               ossimString newPrefix = mPrefix +
+                                       ossimString::toString(row+1) + "_" +
+                                       ossimString::toString(col+1);
+               kwl.add(prefix,
+                       newPrefix,
+                       kernel[row][col],
+                       true);          
+            }
+         }
+      }
+   }
+
+   
+   kwl.add(prefix,
+           NUMBER_OF_MATRICES,
+           numberOfMatrices,
+           true);
+      
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+
+bool ossimConvolutionSource::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   deleteConvolutionList();
+
+   const char* numberOfMatrices = kwl.find(prefix, NUMBER_OF_MATRICES);
+
+   long matrixCount = ossimString(numberOfMatrices).toLong();
+   long numberOfMatches = 0;
+   long index = 0;
+   while(numberOfMatches < matrixCount)
+   {
+      ossimString newPrefix = prefix;
+      newPrefix += ossimString("m");
+      newPrefix += ossimString::toString(index);
+      newPrefix += ossimString(".");
+
+      const char* rows = kwl.find((newPrefix+NUMBER_OF_ROWS.key()).c_str());
+      const char* cols = kwl.find((newPrefix+NUMBER_OF_COLS.key()).c_str());
+
+      if(rows&&cols)
+      {
+         ++numberOfMatches;
+         long numberOfRows = ossimString(rows).toLong();
+         long numberOfCols = ossimString(cols).toLong();
+         NEWMAT::Matrix convolutionMatrix(numberOfRows, numberOfCols);
+         
+         
+         for(long r = 1; r <= numberOfRows; r++)
+         {
+            for(long c = 1; c <= numberOfCols; c++)
+            {
+               convolutionMatrix[r-1][c-1] = 0.0;
+               
+               ossimString value = ossimString::toString(r);
+               value += "_";
+               value += ossimString::toString(c);
+
+               const char* v = kwl.find(newPrefix.c_str(),
+                                        value.c_str());
+               if(v)
+               {
+                  convolutionMatrix[r-1][c-1] = ossimString(v).toDouble();
+               }
+            }
+         }
+         theConvolutionKernelList.push_back(new ossimDiscreteConvolutionKernel(convolutionMatrix));
+      }
+      ++index;
+   }
+   setKernelInformation();
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+void ossimConvolutionSource::setKernelInformation()
+{
+   long index;
+   
+   if(theConvolutionKernelList.size() > 0)
+   {
+      theMaxKernelWidth  = theConvolutionKernelList[0]->getWidth();
+      theMaxKernelHeight = theConvolutionKernelList[0]->getHeight();
+      
+      for(index = 1; index < (long)theConvolutionKernelList.size(); ++index)
+      {
+         long w = theConvolutionKernelList[index]->getWidth();
+         long h = theConvolutionKernelList[index]->getHeight();
+         theMaxKernelWidth  = theMaxKernelWidth < w?w:theMaxKernelWidth;
+         theMaxKernelHeight = theMaxKernelHeight < h?h:theMaxKernelHeight;
+      }
+   }
+}
+
+void ossimConvolutionSource::deleteConvolutionList()
+{
+   for(long index = 0; index < (long)theConvolutionKernelList.size(); ++index)
+   {
+      delete theConvolutionKernelList[index];
+   }
+
+   theConvolutionKernelList.clear();
+}
+
+void ossimConvolutionSource::setConvolution(const NEWMAT::Matrix& convolutionMatrix, bool doWeightedAverage)
+{
+   std::vector<NEWMAT::Matrix> m;
+   
+   m.push_back(convolutionMatrix);
+   
+   setConvolutionList(m, doWeightedAverage);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionSource.h
new file mode 100644
index 0000000000..ce07a7f226
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimConvolutionSource.h
@@ -0,0 +1,72 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimConvolutionSource.h,v 1.13 2005/12/07 20:21:17 gpotts Exp $
+#ifndef ossimConvolutionSource_HEADER
+#define ossimConvolutionSource_HEADER
+#include <vector>
+#include <iostream>
+#include <matrix/newmat.h>
+using namespace std;
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimTilePatch;
+class ossimDiscreteConvolutionKernel;
+
+class ossimConvolutionSource : public ossimImageSourceFilter
+{
+public:
+   ossimConvolutionSource();
+   ossimConvolutionSource(ossimImageSource* inputSource,
+                          const NEWMAT::Matrix& convolutionMatix);
+   ossimConvolutionSource(ossimImageSource* inputSource,
+                          const vector<NEWMAT::Matrix>& convolutionList);
+   virtual ~ossimConvolutionSource();
+   
+   virtual void setConvolution(const double* kernel, int nrows, int ncols, bool doWeightedAverage=false);
+   virtual void setConvolution(const NEWMAT::Matrix& convolutionMatrix, bool doWeightedAverage=false);
+   virtual void setConvolutionList(const vector<NEWMAT::Matrix>& convolutionList, bool doWeightedAverage=false);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+
+   ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect, ossim_uint32 resLevel=0);
+   
+   virtual void initialize();
+   
+protected:
+
+   void allocate();
+   
+   ossimRefPtr<ossimImageData> theTile;
+   long                        theMaxKernelWidth;
+   long                        theMaxKernelHeight;
+   
+   vector<ossimDiscreteConvolutionKernel*> theConvolutionKernelList;
+   virtual void setKernelInformation();
+   virtual void deleteConvolutionList();
+
+   template<class T>
+   void convolve(T dummyVariable,
+                 ossimRefPtr<ossimImageData> inputTile,
+                 ossimDiscreteConvolutionKernel* kernel);
+   
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimConvolutionSource_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEastingNorthingCutter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEastingNorthingCutter.cpp
new file mode 100644
index 0000000000..cf55781626
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEastingNorthingCutter.cpp
@@ -0,0 +1,209 @@
+//----------------------------------------------------------------------------
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// $Id: ossimEastingNorthingCutter.cpp,v 1.5 2005/10/03 13:16:40 gpotts Exp $
+//----------------------------------------------------------------------------
+
+#include <sstream>
+#include <imaging/tile_sources/ossimEastingNorthingCutter.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+
+RTTI_DEF2(ossimEastingNorthingCutter, "ossimEastingNorthingCutter", ossimRectangleCutFilter, ossimViewInterface);
+
+static ossimTrace traceDebug(ossimString("ossimEastingNorthingCutter:debug"));
+
+
+ossimEastingNorthingCutter::ossimEastingNorthingCutter(ossimObject* owner,
+                                                       ossimImageSource* inputSource)
+   :ossimRectangleCutFilter(owner,
+                            inputSource),
+    ossimViewInterface(0),
+    theViewProjection(0)
+{
+   theUlEastingNorthing.makeNan();
+   theLrEastingNorthing.makeNan();
+   theCutType = OSSIM_RECTANGLE_NULL_OUTSIDE;
+}
+
+ossimEastingNorthingCutter::ossimEastingNorthingCutter(ossimImageSource* inputSource)
+   :ossimRectangleCutFilter(inputSource),
+    ossimViewInterface(0),
+    theViewProjection(0)
+{
+   theUlEastingNorthing.makeNan();
+   theLrEastingNorthing.makeNan();
+   theCutType = OSSIM_RECTANGLE_NULL_OUTSIDE;
+}
+
+ossimEastingNorthingCutter::~ossimEastingNorthingCutter()
+{
+   if(theViewProjection)
+   {
+      delete theViewProjection;
+      theViewProjection = 0;
+   }
+}
+
+void ossimEastingNorthingCutter::setEastingNorthingRectangle(const ossimDpt& ul,
+                                                             const ossimDpt& lr)
+{
+   theUlEastingNorthing = ul;
+   theLrEastingNorthing = lr;
+
+   transformVertices();
+}
+
+ossimDpt ossimEastingNorthingCutter::getUlEastingNorthing()const
+{
+   return theUlEastingNorthing;
+}
+
+ossimDpt ossimEastingNorthingCutter::getLrEastingNorthing()const
+{
+   return theLrEastingNorthing;
+}
+
+
+void ossimEastingNorthingCutter::initialize()
+{
+   ossimRectangleCutFilter::initialize();
+   transformVertices();
+}
+
+bool ossimEastingNorthingCutter::saveState(ossimKeywordlist& kwl,
+                                           const char* prefix)const
+{
+   kwl.add(prefix,
+           "ul_en",
+           ossimString::toString(theUlEastingNorthing.x) + " " +
+           ossimString::toString(theUlEastingNorthing.y),
+           true);
+   kwl.add(prefix,
+           "lr_en",
+           ossimString::toString(theLrEastingNorthing.x) + " " +
+           ossimString::toString(theLrEastingNorthing.y),
+           true);
+
+   return ossimRectangleCutFilter::saveState(kwl, prefix);
+}
+
+bool ossimEastingNorthingCutter::loadState(const ossimKeywordlist& kwl,
+                                           const char* prefix)
+{
+   const char *ul = kwl.find(prefix,
+                             "ul_en");
+   const char *lr = kwl.find(prefix,
+                             "lr_en");
+
+   theUlEastingNorthing.makeNan();
+   theLrEastingNorthing.makeNan();
+   
+   if(ul)
+   {
+      istringstream in(ul);
+
+      in >> theUlEastingNorthing.x >> theUlEastingNorthing.y;
+   }
+   
+   if(lr)
+   {
+      istringstream in(lr);
+
+      in >> theLrEastingNorthing.x >> theLrEastingNorthing.y;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimEastingNorthingCutter::loadState DEBUG:"
+         << "\ntheUlEastingNorthing:  " << theUlEastingNorthing
+         << "\ntheLrEastingNorthing:  " << theLrEastingNorthing
+         << endl;
+   }
+
+   return ossimRectangleCutFilter::loadState(kwl, prefix);
+}
+
+bool ossimEastingNorthingCutter::setView(ossimObject* baseObject,
+                                         bool ownsTheView)
+{
+   ossimProjection* tempProj = PTR_CAST(ossimProjection,
+                                        baseObject);
+   if(!tempProj)
+   {
+      return false;
+   }
+   
+   if(theViewProjection)
+   {
+      delete theViewProjection;
+      theViewProjection = 0;
+   }
+
+   if(ownsTheView)
+   {
+      theViewProjection = tempProj;
+   }
+   else
+   {
+      theViewProjection = (ossimProjection*)tempProj->dup();
+   }
+
+   transformVertices();
+
+   return true;
+}
+
+ossimObject* ossimEastingNorthingCutter::getView()
+{
+   return theViewProjection;
+}
+
+const ossimObject* ossimEastingNorthingCutter::getView()const
+{
+   return theViewProjection;
+}
+
+void ossimEastingNorthingCutter::transformVertices()
+{
+   theRectangle.makeNan();
+
+   if(theUlEastingNorthing.hasNans()||
+      theLrEastingNorthing.hasNans()||
+      (!theViewProjection))
+   {
+      return;
+   }
+
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection,
+                                          theViewProjection);
+   ossimDpt ul;
+   ossimDpt lr;
+   ossimDpt easting;
+   ossimDpt northing;
+   if(mapProj)
+   {
+      mapProj->eastingNorthingToLineSample(theUlEastingNorthing, ul);
+      mapProj->eastingNorthingToLineSample(theLrEastingNorthing, lr);
+
+      ossimDrect drect(ul.x, ul.y, lr.x, lr.y);
+
+      theRectangle = drect;
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimEastingNorthingCutter::transformVertices DEBUG:"
+            << "original drect:  " << drect
+            << "\ntheRectangle:  " << theRectangle
+            << endl;
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEastingNorthingCutter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEastingNorthingCutter.h
new file mode 100644
index 0000000000..b2d8ca115e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEastingNorthingCutter.h
@@ -0,0 +1,45 @@
+#ifndef ossimEastingNorthingCutter_HEADER
+#define ossimEastingNorthingCutter_HEADER
+#include "ossimRectangleCutFilter.h"
+#include "base/common/ossimViewInterface.h"
+
+class ossimProjection;
+class ossimEastingNorthingCutter : public ossimRectangleCutFilter,
+                                   public ossimViewInterface
+{
+public:
+   ossimEastingNorthingCutter(ossimObject* owner,
+                              ossimImageSource* inputSource=NULL);
+   ossimEastingNorthingCutter(ossimImageSource* inputSource=NULL);
+   virtual ~ossimEastingNorthingCutter();
+   
+   void setEastingNorthingRectangle(const ossimDpt& ul,
+                                    const ossimDpt& lr);
+   ossimDpt getUlEastingNorthing()const;
+   ossimDpt getLrEastingNorthing()const;
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual bool setView(ossimObject* baseObject,
+                        bool ownsTheView = false);
+
+   virtual ossimObject* getView();
+   virtual const ossimObject* getView()const;
+
+   virtual void initialize();
+   
+protected:
+   ossimDpt theUlEastingNorthing;
+   ossimDpt theLrEastingNorthing;
+   
+   ossimProjection* theViewProjection;
+
+
+   void transformVertices();
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEdgeFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEdgeFilter.cpp
new file mode 100644
index 0000000000..c74109e89a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEdgeFilter.cpp
@@ -0,0 +1,545 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimEdgeFilter.cpp,v 1.9 2005/08/17 19:18:12 gpotts Exp $
+#include <imaging/tile_sources/ossimEdgeFilter.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/ossimImageData.h>
+#include <base/property/ossimStringProperty.h>
+
+RTTI_DEF1(ossimEdgeFilter, "ossimEdgeFilter", ossimImageSourceFilter);
+
+ossimEdgeFilter::ossimEdgeFilter(ossimObject* owner)
+   :ossimImageSourceFilter(owner),
+    theTile(NULL),
+    theFilterType("Sobel")
+{
+}
+
+ossimEdgeFilter::ossimEdgeFilter(ossimImageSource* inputSource)
+   :ossimImageSourceFilter(inputSource),
+    theTile(NULL),
+    theFilterType("Sobel")
+{
+}
+
+ossimEdgeFilter::ossimEdgeFilter(ossimObject* owner,
+                                   ossimImageSource* inputSource)
+   :ossimImageSourceFilter(owner, inputSource),
+    theTile(NULL),
+    theFilterType("Sobel")
+{
+}
+
+ossimRefPtr<ossimImageData> ossimEdgeFilter::getTile(const ossimIrect& rect,
+                                                     ossim_uint32 resLevel)
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getTile(rect, resLevel);
+   }
+
+   // expand the rect out to cver the 3x3 horizontal and vertical
+   // kernel.
+   //
+   ossimIrect requestRect = rect;
+
+   adjustRequestRect(requestRect);
+   
+   ossimRefPtr<ossimImageData> inputData =
+      ossimImageSourceFilter::getTile(requestRect, resLevel);
+
+   if(!inputData.valid() || (!inputData->getBuf()))
+   {
+      return inputData;
+   }
+
+   if(!theTile.valid()) initialize();
+   if(!theTile.valid()) return theTile;
+      
+   theTile->setImageRectangleAndBands(rect, inputData->getNumberOfBands());
+
+   switch(theTile->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      runFilter((ossim_uint8)0,
+                inputData);
+      break;
+   }
+   case OSSIM_FLOAT:
+   case OSSIM_NORMALIZED_FLOAT:
+   {
+      runFilter((ossim_float32)0,
+                inputData);
+      break;
+   }
+   case OSSIM_USHORT16:
+   case OSSIM_USHORT11:
+   {
+      runFilter((ossim_uint16)0,
+                inputData);
+      break;
+   }
+   case OSSIM_SSHORT16:
+   {
+      runFilter((ossim_sint16)0,
+                inputData);
+      break;
+   }
+   case OSSIM_DOUBLE:
+   case OSSIM_NORMALIZED_DOUBLE:
+   {
+      runFilter((ossim_float64)0,
+                inputData);
+      break;
+   }
+   default:
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimEdgeFilter::getTile WARN: Scalar type = " << theTile->getScalarType()
+                                         << " Not supported by ossimEdgeFilter" << std::endl;
+      break;
+   }
+   }
+
+   return theTile;
+}
+
+void ossimEdgeFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   theTile = NULL;
+
+   if(!isSourceEnabled())
+   {
+      return;
+   }
+   
+   theTile = ossimImageDataFactory::instance()->create(this, this);
+   if(theTile.valid())
+   {
+      theTile->initialize();
+   }
+}
+
+void ossimEdgeFilter::getFilterTypeNames(
+   std::vector<ossimString>& filterNames)const
+{
+   filterNames.push_back("Laplacian");
+   filterNames.push_back("Prewitt");
+   filterNames.push_back("Roberts");
+   filterNames.push_back("Sobel");
+}
+
+ossimString ossimEdgeFilter::getFilterType()const
+{
+   return theFilterType;
+}
+
+void ossimEdgeFilter::setFilterType(const ossimString& filterType)
+{
+   ossimString tempFilterType = filterType;
+   tempFilterType = tempFilterType.downcase();
+   
+   if(tempFilterType.contains("sob"))
+   {
+      tempFilterType = "Sobel";
+   }
+   else if(tempFilterType.contains("lap"))
+   {
+      tempFilterType = "Laplacian";
+   }
+   else if(tempFilterType.contains("prew"))
+   {
+      tempFilterType = "Prewitt";
+   }
+   else if(tempFilterType.contains("rob"))
+   {
+      tempFilterType = "Roberts";
+   }
+   else
+   {
+      tempFilterType = "Sobel";
+   }
+}
+
+void ossimEdgeFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property) return;
+   
+   if(property->getName() == "Edge type")
+   {
+      theFilterType = property->valueToString();
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimEdgeFilter::getProperty(const ossimString& name)const
+{
+   if(name == "Edge type")
+   {
+      std::vector<ossimString> filterNames;
+      
+      getFilterTypeNames(filterNames);
+      ossimStringProperty* stringProp = new ossimStringProperty("Edge type",
+								theFilterType,
+								false,
+								filterNames);
+      stringProp->clearChangeType();
+      stringProp->setReadOnlyFlag(false);
+      stringProp->setCacheRefreshBit();
+
+      return stringProp;
+   }
+
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimEdgeFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   
+   propertyNames.push_back("Edge type");
+}
+
+
+void ossimEdgeFilter::adjustRequestRect(ossimIrect& requestRect)const
+{
+   ossimString filterType = theFilterType;
+   filterType = filterType.downcase();
+   ossimIrect rect = requestRect;
+   if(filterType.contains("sob")||
+      filterType.contains("lap")||
+      filterType.contains("pre"))
+   {
+      requestRect = ossimIrect(rect.ul().x - 1,
+                               rect.ul().y - 1,
+                               rect.lr().x + 1,
+                               rect.lr().y + 1);
+   }
+   else if(filterType.contains("rob"))
+   {
+      requestRect = ossimIrect(rect.ul().x,
+                               rect.ul().y,
+                               rect.lr().x + 1,
+                               rect.lr().y + 1);
+   }
+   else
+   {
+      requestRect = ossimIrect(rect.ul().x - 1,
+                               rect.ul().y - 1,
+                               rect.lr().x + 1,
+                               rect.lr().y + 1);
+   }
+}
+
+template <class T>
+void ossimEdgeFilter::runFilter(T dummyVariable,
+                                ossimRefPtr<ossimImageData> inputData)
+{
+   ossimString filterType = theFilterType;
+   filterType = filterType.downcase();
+   
+   if(filterType.contains("sobel"))
+   {
+      runSobelFilter(dummyVariable, inputData);
+   }
+   else if(filterType.contains("lap"))
+   {
+      runLaplacianFilter(dummyVariable, inputData);
+   }
+   else if(filterType.contains("pre"))
+   {
+      runPrewittFilter(dummyVariable, inputData);
+   }
+   else if(filterType.contains("rob"))
+   {
+      runRobertsFilter(dummyVariable, inputData);
+   }
+   else 
+   {
+      theTile->makeBlank();
+   }
+}
+
+template <class T>
+void ossimEdgeFilter::runSobelFilter(T dummyVariable,
+                                     ossimRefPtr<ossimImageData> inputData)
+{
+   ossim_uint32 bandIdx = 0;
+   ossim_uint32 numberOfBands = inputData->getNumberOfBands();
+   double horizontalValue = 0.0;
+   double verticalValue = 0.0;
+   double value = 0.0;
+   // ossim_uint32 valueIdx = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+   ossim_uint32 width  = theTile->getWidth();
+   ossim_uint32 height = theTile->getHeight();
+   ossim_int32 rowIncrement  = inputData->getWidth();
+   ossim_int32 rowIncrement2 = 2*inputData->getWidth();
+   
+   for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+   {
+      T* inputBuf  = static_cast<T*>(inputData->getBuf(bandIdx));
+      T* outputBuf = static_cast<T*>(theTile->getBuf(bandIdx));
+      T np         = static_cast<T>(theTile->getNullPix(bandIdx));
+      T minP       = static_cast<T>(theTile->getMinPix(bandIdx));
+      T maxP       = static_cast<T>(theTile->getMaxPix(bandIdx));
+
+      if(inputBuf&&outputBuf)
+      {
+         for(y = 0; y < height; ++y)
+         {
+            for(x = 0; x < width; ++x)
+            {
+               if( (*(inputBuf + rowIncrement + 1) != np))
+               {
+                  horizontalValue = ((double)inputBuf[0] - (double)inputBuf[rowIncrement2]) +
+                                    ((double)(inputBuf[1]*2.0) - (double)( inputBuf[rowIncrement2+1]*2.0)) +
+                                    ((double)(inputBuf[2]) - (double)(inputBuf[rowIncrement2+2]));
+
+                   verticalValue   = ((double)(inputBuf[2]) + (double)inputBuf[rowIncrement+2]*2.0 + (double)inputBuf[rowIncrement2+2]) -
+                                     (double)(inputBuf[0] + 2.0*(double)inputBuf[rowIncrement] + (double)inputBuf[rowIncrement2]);
+                  
+                  value = sqrt(horizontalValue*horizontalValue +  verticalValue*verticalValue);
+
+                  if((value == np) ||
+                     (value < minP))
+                  {
+                     *outputBuf = (static_cast<T>(minP));
+                  }
+                  else if(value > maxP)
+                  {
+                     *outputBuf = (static_cast<T>(maxP));
+                  }
+                  else
+                  {
+                     *outputBuf = (static_cast<T>(value));
+                  }
+                  
+               }
+               else
+               {
+                  *outputBuf = np;
+               }
+               ++outputBuf;
+               ++inputBuf;
+            }
+            inputBuf+=2;
+         }
+      }
+   }
+   theTile->validate();
+}
+
+template <class T>
+void ossimEdgeFilter::runPrewittFilter(T dummyVariable,
+                                       ossimRefPtr<ossimImageData> inputData)
+{
+   ossim_uint32 bandIdx = 0;
+   ossim_uint32 numberOfBands = inputData->getNumberOfBands();
+   double horizontalValue = 0.0;
+   double verticalValue = 0.0;
+   double value = 0.0;
+   // ossim_uint32 valueIdx = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+   ossim_uint32 width  = theTile->getWidth();
+   ossim_uint32 height = theTile->getHeight();
+   ossim_int32 rowIncrement  = inputData->getWidth();
+   ossim_int32 rowIncrement2 = 2*inputData->getWidth();
+   
+   for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+   {
+      T* inputBuf  = static_cast<T*>(inputData->getBuf(bandIdx));
+      T* outputBuf = static_cast<T*>(theTile->getBuf(bandIdx));
+      T np         = static_cast<T>(theTile->getNullPix(bandIdx));
+      T minP       = static_cast<T>(theTile->getMinPix(bandIdx));
+      T maxP       = static_cast<T>(theTile->getMaxPix(bandIdx));
+
+      if(inputBuf&&outputBuf)
+      {
+         for(y = 0; y < height; ++y)
+         {
+            for(x = 0; x < width; ++x)
+            {
+               if( (*(inputBuf + rowIncrement + 1) != np))
+               {
+                  horizontalValue = ((double)inputBuf[0] - (double)inputBuf[rowIncrement2]) +
+                                    ((double)(inputBuf[1]) - (double)( inputBuf[rowIncrement2+1])) +
+                                    ((double)(inputBuf[2]) - (double)(inputBuf[rowIncrement2+2]));
+
+                   verticalValue   = ((double)(inputBuf[2]) + (double)inputBuf[rowIncrement+2] + (double)inputBuf[rowIncrement2+2]) -
+                                     ((double)inputBuf[0] + (double)inputBuf[rowIncrement] + (double)inputBuf[rowIncrement2]);
+                  
+                  value = sqrt(horizontalValue*horizontalValue +  verticalValue*verticalValue);
+
+                  if((value == np) ||
+                     (value < minP))
+                  {
+                     *outputBuf = (static_cast<T>(minP));
+                  }
+                  else if(value > maxP)
+                  {
+                     *outputBuf = (static_cast<T>(maxP));
+                  }
+                  else
+                  {
+                     *outputBuf = (static_cast<T>(value));
+                  }
+                  
+               }
+               else
+               {
+                  *outputBuf = np;
+               }
+               ++outputBuf;
+               ++inputBuf;
+            }
+            inputBuf+=2;
+         }
+      }
+   }
+   theTile->validate();
+}
+
+template <class T>
+void ossimEdgeFilter::runRobertsFilter(T dummyVariable,
+                                       ossimRefPtr<ossimImageData> inputData)
+{
+   ossim_uint32 bandIdx = 0;
+   ossim_uint32 numberOfBands = inputData->getNumberOfBands();
+   double v1 = 0.0;
+   double v2 = 0.0;
+   double value = 0.0;
+   // ossim_uint32 valueIdx = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+   ossim_uint32 width  = theTile->getWidth();
+   ossim_uint32 height = theTile->getHeight();
+   ossim_int32 rowIncrement  = inputData->getWidth();
+   
+   for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+   {
+      T* inputBuf  = static_cast<T*>(inputData->getBuf(bandIdx));
+      T* outputBuf = static_cast<T*>(theTile->getBuf(bandIdx));
+      T np         = static_cast<T>(theTile->getNullPix(bandIdx));
+      T minP       = static_cast<T>(theTile->getMinPix(bandIdx));
+      T maxP       = static_cast<T>(theTile->getMaxPix(bandIdx));
+
+      if(inputBuf&&outputBuf)
+      {
+         for(y = 0; y < height; ++y)
+         {
+            for(x = 0; x < width; ++x)
+            {
+               if( (*inputBuf) != np)
+               {
+                  v1 = (double)inputBuf[0] - (double)(inputBuf[rowIncrement+1]);
+
+                  v2   = (double)inputBuf[1] - (double)inputBuf[rowIncrement];
+                  
+                  value = sqrt(v1*v1 +  v2*v2);
+
+                  if((value == np) ||
+                     (value < minP))
+                  {
+                     *outputBuf = (static_cast<T>(minP));
+                  }
+                  else if(value > maxP)
+                  {
+                     *outputBuf = (static_cast<T>(maxP));
+                  }
+                  else
+                  {
+                     *outputBuf = (static_cast<T>(value));
+                  }
+                  
+               }
+               else
+               {
+                  *outputBuf = np;
+               }
+               ++outputBuf;
+               ++inputBuf;
+            }
+            ++inputBuf;
+         }
+      }
+   }
+   theTile->validate();
+}
+
+template <class T>
+void ossimEdgeFilter::runLaplacianFilter(T dummyVariable,
+                                         ossimRefPtr<ossimImageData> inputData)
+{
+   ossim_uint32 bandIdx = 0;
+   ossim_uint32 numberOfBands = inputData->getNumberOfBands();
+   // double horizontalValue = 0.0;
+   // double verticalValue = 0.0;
+   double value = 0.0;
+   // ossim_uint32 valueIdx = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+   ossim_uint32 width  = theTile->getWidth();
+   ossim_uint32 height = theTile->getHeight();
+   ossim_int32 rowIncrement  = inputData->getWidth();
+   ossim_int32 rowIncrement2 = 2*inputData->getWidth();
+   
+   for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+   {
+      T* inputBuf  = static_cast<T*>(inputData->getBuf(bandIdx));
+      T* outputBuf = static_cast<T*>(theTile->getBuf(bandIdx));
+      T np         = static_cast<T>(theTile->getNullPix(bandIdx));
+      T minP       = static_cast<T>(theTile->getMinPix(bandIdx));
+      T maxP       = static_cast<T>(theTile->getMaxPix(bandIdx));
+
+      if(inputBuf&&outputBuf)
+      {
+         for(y = 0; y < height; ++y)
+         {
+            for(x = 0; x < width; ++x)
+            {
+               if( (*(inputBuf + rowIncrement + 1) != np))
+               {
+                  
+                  value = fabs(((double)inputBuf[rowIncrement + 1]*4.0) -
+                               ((double)inputBuf[1] + (double)inputBuf[rowIncrement] + (double)inputBuf[rowIncrement + 2] + (double)inputBuf[rowIncrement2+1]));
+
+                  if((value == np) ||
+                     (value < minP))
+                  {
+                     *outputBuf = (static_cast<T>(minP));
+                  }
+                  else if(value > maxP)
+                  {
+                     *outputBuf = (static_cast<T>(maxP));
+                  }
+                  else
+                  {
+                     *outputBuf = (static_cast<T>(value));
+                  }
+                  
+               }
+               else
+               {
+                  *outputBuf = np;
+               }
+               ++outputBuf;
+               ++inputBuf;
+            }
+            inputBuf+=2;
+         }
+      }
+   }
+   theTile->validate();
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEdgeFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEdgeFilter.h
new file mode 100644
index 0000000000..7f422e6c0c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEdgeFilter.h
@@ -0,0 +1,77 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimEdgeFilter.h,v 1.4 2005/08/17 19:18:12 gpotts Exp $
+#ifndef ossimEdgeFilter_HEADER
+#define ossimEdgeFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+/**
+ * class ossimEdgeFilter
+ *
+ * This has default implementation for the certain filter types.  For the
+ * different filter type please see method setFilterType.
+ *
+ *
+ */
+class ossimEdgeFilter : public ossimImageSourceFilter
+{
+public:
+   ossimEdgeFilter(ossimObject* owner=NULL);
+   ossimEdgeFilter(ossimImageSource* inputSource);
+   ossimEdgeFilter(ossimObject* owner,
+                    ossimImageSource* inputSource);
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+   virtual void initialize();
+   virtual void getFilterTypeNames(std::vector<ossimString>& filterNames)const;
+   virtual ossimString getFilterType()const;
+   /**
+    * The filter type can be one of the following strings.  It is
+    * case insensitive for the compares.
+    *
+    *  Sobel
+    *  Laplacian
+    *  Prewitt
+    *  
+    */
+   virtual void setFilterType(const ossimString& filterType);
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+protected:
+   ossimRefPtr<ossimImageData> theTile;
+   ossimString                 theFilterType;
+   
+   void adjustRequestRect(ossimIrect& requestRect)const;
+   
+   template <class T>
+   void runFilter(T dummyVariable,
+                  ossimRefPtr<ossimImageData> inputData);
+   template <class T>
+   void runSobelFilter(T dummyVariable,
+                       ossimRefPtr<ossimImageData> inputData);
+   template <class T>
+   void runPrewittFilter(T dummyVariable,
+                         ossimRefPtr<ossimImageData> inputData);
+   template <class T>
+   void runLaplacianFilter(T dummyVariable,
+                           ossimRefPtr<ossimImageData> inputData);
+   template <class T>
+   void runRobertsFilter(T dummyVariable,
+                         ossimRefPtr<ossimImageData> inputData);
+   
+TYPE_DATA
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEquationCombiner.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEquationCombiner.cpp
new file mode 100644
index 0000000000..9955b7187d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEquationCombiner.cpp
@@ -0,0 +1,3555 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimEquationCombiner.cpp,v 1.47 2005/07/01 13:32:24 dburken Exp $
+
+#include <sstream>
+using namespace std;
+
+#include <imaging/tile_sources/ossimEquationCombiner.h>
+#include <imaging/tile_sources/ossimCastTileSourceFilter.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/tile_sources/ossimConvolutionSource.h>
+#include <imaging/tile_sources/ossimSubImageTileSource.h>
+#include <base/property/ossimStringProperty.h>
+#include <matrix/newmatio.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimEquationCombiner, "ossimEquationCombiner", ossimImageCombiner);
+
+static const char* EQUATION_KW = "equation";
+
+
+class ossimBinaryOpAdd : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return v1 + v2;
+      }
+};
+
+class ossimBinaryOpAnd : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return (double)(((ossim_uint32)v1) & ((ossim_uint32)v2));
+      }
+};
+
+class ossimBinaryOpOr : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return (double)(((ossim_uint32)v1) | ((ossim_uint32)v2));
+      }
+};
+
+class ossimBinaryOpXor : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return (double)(((ossim_uint32)v1) ^ ((ossim_uint32)v2));
+      }
+};
+
+class ossimBinaryOpSub : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return v1 - v2;
+      }
+};
+
+class ossimBinaryOpMax : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return std::max(v1, v2);
+      }
+};
+
+class ossimBinaryOpMin : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return std::min(v1, v2);
+      }
+};
+
+class ossimBinaryOpMul : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return v1 * v2;
+      }
+};
+
+class ossimBinaryOpDiv : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         if(fabs(v2)>FLT_EPSILON)
+            return v1 / v2;
+         
+         return 1.0/FLT_EPSILON;
+      }
+};
+
+class ossimBinaryOpMod : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         if(fabs(v2)>FLT_EPSILON)
+            return fmod(v1,v2);
+         
+         return 1.0/FLT_EPSILON;
+      }
+};
+
+class ossimBinaryOpPow : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return pow(v1, v2);
+      }
+};
+// boolean operators
+class ossimBinaryOpEqual : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return (v1==v2)?1.0:0.0;
+      }
+};
+class ossimBinaryOpGreater : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return (v1>v2)?1.0:0.0;
+      }
+};
+class ossimBinaryOpGreaterOrEqual : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return (v1>=v2)?1.0:0.0;
+      }
+};
+class ossimBinaryOpLess : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return (v1<v2)?1.0:0.0;
+      }
+};
+class ossimBinaryOpLessOrEqual : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return (v1<=v2)?1.0:0.0;
+      }
+};
+class ossimBinaryOpDifferent : public ossimEquationCombiner::ossimBinaryOp
+{
+public:
+   virtual double apply(double v1, double v2)const
+      {
+         return (v1!=v2)?1.0:0.0;
+      }
+};
+class ossimUnaryOpNot : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return 1-v;
+      }
+};
+
+class ossimUnaryOpAbs : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return fabs(v);
+      }
+};
+
+class ossimUnaryOpOnesComplement : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return (double)((ossim_uint8)~((ossim_uint8)v));
+      }
+};
+
+class ossimUnaryOpLog : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return log(v);
+      }
+};
+
+class ossimUnaryOpLog10 : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return log10(v);
+      }
+};
+
+class ossimUnaryOpNeg : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return -v;
+      }
+};
+
+class ossimUnaryOpSqrt : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         if(v >= 0)
+         {
+            return sqrt(v);
+         }
+         
+         return -1;
+      }
+};
+
+class ossimUnaryOpExp : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return exp(v);
+      }
+};
+
+class ossimUnaryOpSin : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return sin(v);
+      }
+};
+
+class ossimUnaryOpSind : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return sin(v*M_PI/180.0);
+      }
+};
+
+class ossimUnaryOpASin : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         if(v > 1) v = 1;
+         if(v < -1) v = -1;
+         return asin(v);
+      }
+};
+
+class ossimUnaryOpASind : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         if(v > 1) v = 1;
+         if(v < -1) v = -1;
+         return (180/M_PI)*asin(v);
+      }
+};
+
+class ossimUnaryOpACos : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         if(v > 1) v = 1;
+         if(v < -1) v = -1;
+         return acos(v);
+      }
+};
+
+class ossimUnaryOpACosd : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         if(v > 1) v = 1;
+         if(v < -1) v = -1;
+         return (180/M_PI)*acos(v);
+      }
+};
+
+class ossimUnaryOpCos : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return cos(v);
+      }
+};
+
+class ossimUnaryOpCosd : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return cos(v*M_PI/180.0);
+      }
+};
+
+class ossimUnaryOpTan : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return tan(v);
+      }
+};
+
+class ossimUnaryOpTand : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return tan(v*M_PI/180.0);
+      }
+};
+
+class ossimUnaryOpATan : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return atan(v);
+      }
+};
+
+class ossimUnaryOpATand : public ossimEquationCombiner::ossimUnaryOp
+{
+public:
+   virtual double apply(double v)const
+      {
+         return (180/M_PI)*atan(v);
+      }
+};
+
+
+ossimEquationCombiner::ossimEquationCombiner()
+   :ossimImageCombiner(),
+    theOutputScalarType(OSSIM_FLOAT),
+    theEquation(""),
+    theLexer(NULL),
+    theTile(NULL),
+    theCastFilter(NULL),
+    theCastOutputFilter(NULL)
+{
+   theLexer      = new ossimEquTokenizer;
+   theCastFilter = new ossimCastTileSourceFilter;
+   theCastFilter->setOutputScalarType(OSSIM_FLOAT);
+}
+
+ossimEquationCombiner::~ossimEquationCombiner()
+{
+   if(theLexer)
+   {
+      delete theLexer;
+      theLexer = NULL;
+   }
+
+   if(theCastFilter)
+   {
+      delete theCastFilter;
+      theCastFilter = (ossimCastTileSourceFilter*)NULL;
+   }
+
+   if(theCastOutputFilter)
+   {
+      delete theCastOutputFilter;
+      theCastOutputFilter = NULL;
+   }
+   // make sure they are cleared
+   clearStacks();
+}
+
+double ossimEquationCombiner::getNullPixelValue(ossim_uint32 band)const
+{
+   
+   if(theEquation == "")
+   {
+      if(getInput())
+      {
+         ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface, getInput());
+         if(inter)
+         {
+            return inter->getNullPixelValue(band);
+         }
+      }
+   }
+   return ossimImageSource::getNullPixelValue(band);
+}   
+
+double ossimEquationCombiner::getMinPixelValue(ossim_uint32 band)const
+{
+   if(theEquation == "")
+   {
+      if(getInput())
+      {
+         ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface, getInput());
+         if(inter)
+         {
+            return inter->getMinPixelValue(band);
+         }
+      }
+   }
+   return ossimImageSource::getMinPixelValue(band);
+}
+
+double ossimEquationCombiner::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(theEquation == "")
+   {
+      if(getInput())
+      {
+         ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface, getInput());
+         if(inter)
+         {
+            return inter->getMaxPixelValue(band);
+         }
+      }
+   }
+   return ossimImageSource::getMaxPixelValue(band);         
+}
+
+ossimScalarType ossimEquationCombiner::getOutputScalarType() const
+{
+
+   if(theEquation == "")
+   {
+      if(getInput())
+      {
+         ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface, getInput());
+         if(inter)
+         {
+            return inter->getOutputScalarType();
+         }
+      }
+   }
+   
+   return theOutputScalarType;
+}
+
+
+ossimRefPtr<ossimImageData> ossimEquationCombiner::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theTile)
+   {
+      initialize();
+   }
+   long w = tileRect.width();
+   long h = tileRect.height();
+   long tw = theTile->getWidth();
+   long th = theTile->getHeight();
+   
+   if(theEquation != "")
+   {
+      theTile->setImageRectangle(tileRect);
+      
+      if(w*h != tw*th)
+      {
+         theTile->initialize();
+      }
+      else
+      {
+         theTile->makeBlank();
+      }
+      theCurrentResLevel = resLevel;
+      
+      ossimRefPtr<ossimImageData> outputTile =  parseEquation();
+
+      if(theCastOutputFilter)
+      {
+         outputTile = theCastOutputFilter->applyCast(outputTile);
+      }
+      
+      return outputTile;
+   }
+   else
+   {
+      if(getInput())
+      {
+         ossimImageSourceInterface* inter =
+            PTR_CAST(ossimImageSourceInterface, getInput());
+         if(inter)
+         {
+            return inter->getTile(tileRect, resLevel);
+         }
+      }
+   }
+
+   return ossimRefPtr<ossimImageData>();
+}
+
+void ossimEquationCombiner::setOutputScalarType(ossimScalarType scalarType)
+{
+   if(theOutputScalarType != scalarType)
+   {
+      theOutputScalarType = scalarType;
+
+      if(theOutputScalarType == OSSIM_SCALAR_UNKNOWN)
+      {
+         theOutputScalarType = OSSIM_FLOAT;
+      }
+      if(theCastOutputFilter)
+      {
+         delete theCastOutputFilter;
+         theCastOutputFilter = NULL;
+      }
+
+      if(theOutputScalarType != OSSIM_FLOAT)
+      {
+         theCastOutputFilter = new ossimCastTileSourceFilter;
+         theCastOutputFilter->setOutputScalarType(theOutputScalarType);
+         theCastOutputFilter->connectMyInputTo(0, this);
+         theCastOutputFilter->initialize();
+      }
+   }
+}
+
+void ossimEquationCombiner::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property) return;
+   
+   if(property->getName() == "Equation")
+   {
+      theEquation = property->valueToString();
+   }
+   else if(property->getName() == "Output scalar type")
+   {
+      setOutputScalarType(ossimScalarTypeLut::instance()->
+                          getScalarTypeFromString(property->valueToString()));
+   }
+   else
+   {
+      ossimImageCombiner::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimEquationCombiner::getProperty(const ossimString& name)const
+{
+   if(name == "Equation")
+   {
+      ossimStringProperty* stringProp = new ossimStringProperty("Equation",
+								theEquation,
+								false);
+      stringProp->clearChangeType();
+      stringProp->setReadOnlyFlag(false);
+      stringProp->setCacheRefreshBit();
+      
+      return stringProp;
+   }
+   else if(name == "Output scalar type")
+   {
+      ossimScalarTypeLut* sl = ossimScalarTypeLut::instance();
+      
+      std::vector<ossimString> scalarNames;
+
+      ossim_int32 tableSize = (ossim_int32)sl->getTableSize();
+      ossim_int32 idx;
+
+      for(idx = 0; idx < tableSize; ++idx)
+      {
+         scalarNames.push_back(sl->getEntryString(idx));
+      }
+      ossimStringProperty* stringProp = new ossimStringProperty("Output scalar type",
+								sl->getEntryString((ossim_int32)theOutputScalarType),
+								false,
+								scalarNames);
+      stringProp->clearChangeType();
+      stringProp->setReadOnlyFlag(false);
+      stringProp->setCacheRefreshBit();
+      
+      return stringProp;
+      
+   }
+
+   return ossimImageCombiner::getProperty(name);
+}
+
+void ossimEquationCombiner::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageCombiner::getPropertyNames(propertyNames);
+   propertyNames.push_back("Equation");
+   propertyNames.push_back("Output scalar type");
+}
+
+
+void ossimEquationCombiner::initialize()
+{
+   ossimImageCombiner::initialize();
+
+   theTile = ossimImageDataFactory::instance()->create(this, OSSIM_FLOAT, getNumberOfOutputBands(), getTileWidth(), getTileHeight());
+   theTile->initialize();
+   if(theCastOutputFilter)
+   {
+      theCastOutputFilter->initialize();
+   }
+}
+
+void ossimEquationCombiner::assignValue()
+{
+   if(!theValueStack.empty())
+   {
+      if(theValueStack.top().type == OSSIM_EQU_IMAGE_DATA_TYPE)
+      {
+         ossimImageData* topData = theValueStack.top().d.imageDataValue;
+         ossim_uint32 minBands = std::min(theTile->getNumberOfBands(),
+                                    topData->getNumberOfBands());
+         ossim_uint32 maxBands = theTile->getNumberOfBands();
+         ossim_uint32 band   = 0;
+         ossim_uint32 offset = 0;
+         ossim_uint32 size = theTile->getWidth()*theTile->getHeight();
+
+         if(topData->getDataObjectStatus() == OSSIM_PARTIAL)
+         {
+            for(band = 0; band < minBands; ++band)
+            {
+               float* inBuf  = (float*)topData->getBuf(band);
+               float* outBuf = (float*)theTile->getBuf(band);
+               float np      = topData->getNullPix(band);
+               if(outBuf && inBuf)
+               {
+                  for(offset = 0; offset < size; ++offset)
+                  {
+                     if(*inBuf != np)
+                     {
+                        *outBuf = *inBuf;
+                     }
+                     ++outBuf;
+                     ++inBuf;
+                  }
+               }
+            }
+            for(;band < maxBands; ++band)
+            {
+               float* inBuf  = (float*)topData->getBuf(minBands-1);
+               float* outBuf = (float*)theTile->getBuf(band);
+               float np      = topData->getNullPix(band);
+               
+               if(outBuf && inBuf)
+               {
+                  for(offset = 0; offset < size; ++offset)
+                  {
+                     if(*inBuf != np)
+                     {
+                        *outBuf = *inBuf;
+                     }
+                     ++outBuf;
+                     ++inBuf;
+                  }
+               }
+            }
+
+         }
+         else if(topData->getDataObjectStatus() == OSSIM_FULL)
+         {
+            for(band = 0; band < minBands; ++band)
+            {
+               float* inBuf  = (float*)theValueStack.top().d.imageDataValue->getBuf(band);
+               float* outBuf = (float*)theTile->getBuf(band);
+               if(outBuf && inBuf)
+               {
+                  for(offset = 0; offset < size; ++offset)
+                  {
+                     *outBuf = *inBuf;
+                     ++outBuf;
+                     ++inBuf;
+                  }
+               }
+            }
+            for(;band < maxBands; ++band)
+            {
+               float* inBuf  = (float*)theValueStack.top().d.imageDataValue->getBuf(minBands-1);
+               float* outBuf = (float*)theTile->getBuf(band);
+               
+               if(outBuf && inBuf)
+               {
+                  for(offset = 0; offset < size; ++offset)
+                  {
+                     *outBuf = *inBuf;
+                     ++outBuf;
+                     ++inBuf;
+                  }
+               }
+            }
+         }
+         
+         // Delete the object indirectly through an ossimRefPtr.
+         ossimRefPtr<ossimImageData> id = theValueStack.top().d.imageDataValue;
+         id = NULL;
+      }
+      else
+      {
+         float* buf  = static_cast<float*>(theTile->getBuf());
+         ossim_uint32 size = theTile->getSize();
+         float value = (float)theValueStack.top().d.doubleValue;
+         
+         for(ossim_uint32 offset = 0; offset < size; ++offset)
+         {
+            *buf = value;
+            ++buf;
+         }
+      }
+      
+      theValueStack.pop();
+   }
+}
+
+void ossimEquationCombiner::clearStacks()
+{
+
+   while(!theValueStack.empty())
+   {
+      if(theValueStack.top().type == OSSIM_EQU_IMAGE_DATA_TYPE)
+      {
+         // Delete the object indirectly through an ossimRefPtr.
+         ossimRefPtr<ossimImageData> id = theValueStack.top().d.imageDataValue;
+         id = NULL;
+      }
+
+      theValueStack.pop();
+   }
+}
+
+void ossimEquationCombiner::clearArgList(vector<ossimEquValue>& argList)
+{
+   for(ossim_uint32 i = 0; i < argList.size(); ++i)
+   {
+      if(argList[i].type == OSSIM_EQU_IMAGE_DATA_TYPE)
+      {
+         if(argList[i].d.imageDataValue)
+         {
+            // Delete the object indirectly through an ossimRefPtr.
+            ossimRefPtr<ossimImageData> id = argList[i].d.imageDataValue;
+            id = NULL;
+            argList[i].d.imageDataValue = (ossimImageData*)NULL;
+         }
+      }
+   }
+   argList.clear();
+}
+
+void ossimEquationCombiner::deleteArgList(vector<ossimEquValue>& args)
+{
+   int i = 0;
+
+   for(i = 0; i < (int)args.size(); ++i)
+   {
+      if(args[i].type == OSSIM_EQU_IMAGE_DATA_TYPE)
+      {
+         if(args[i].d.imageDataValue)
+         {
+            // Delete the object indirectly through an ossimRefPtr.
+            ossimRefPtr<ossimImageData> id = args[i].d.imageDataValue;
+            id = NULL;
+            args[i].d.imageDataValue = NULL;
+         }
+      }
+   }
+   
+   args.clear();
+}
+
+bool ossimEquationCombiner::parseArgList(vector<ossimEquValue>& args,
+                                         bool popValueStack)
+{
+   bool result = true;
+   
+   if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+   {
+      theCurrentId = theLexer->yylex();
+      do
+      {
+         if(parseExpression())
+         {
+            if(!theValueStack.empty())
+            {
+               args.push_back(theValueStack.top());
+               if(popValueStack)
+               {
+                  theValueStack.pop();
+               }
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "The expression at  arg " << (args.size()+1)
+                  << " is empty" << endl;
+               
+               result = false;
+            }
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               <<"Unable to parse expression" << endl;
+            result = false;
+         }
+         
+         if(theCurrentId == OSSIM_EQU_TOKEN_COMMA)
+         {
+            theCurrentId = theLexer->yylex();
+         }
+         else if(theCurrentId != OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               <<"Missing comma in argument list" << endl;
+            result = false;
+         }
+         
+      }while(result&&(theCurrentId != OSSIM_EQU_TOKEN_RIGHT_PAREN));
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "Starting left parenthesis missing from arg list" << endl;
+      result = false;
+   }
+   
+   if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+   {
+      theCurrentId = theLexer->yylex(); // skip past right parenthesis
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         <<"No matching right parenthesis for arg list" << endl;
+      result = false;
+   }
+
+   if(!result && popValueStack)
+   {
+      clearArgList(args);
+   }
+   return result;
+}
+
+bool ossimEquationCombiner::parseAssignBand()
+{
+   bool result = true;
+   
+   vector<ossimEquValue> argList;
+
+   if(parseArgList(argList))
+   {
+      if((argList.size() == 3) ||
+         (argList.size() == 4))
+      {
+         ossimEquValue v3 = argList[2];
+         ossimEquValue v2 = argList[1];
+         ossimEquValue v1 = argList[0];
+         
+         if(argList.size() == 3)
+         {
+            if((v1.type == OSSIM_EQU_IMAGE_DATA_TYPE) &&
+               (v2.type == OSSIM_EQU_DOUBLE_TYPE))
+            {
+               ossimImageData *data = (ossimImageData*)v1.d.imageDataValue->dup();
+               ossimEquValue v;
+               
+               if(v3.type == OSSIM_EQU_IMAGE_DATA_TYPE)
+               {
+                  if(data->getBuf()&&
+                     v3.d.imageDataValue->getBuf())
+                  {
+                     if((ossim_uint32)(v2.d.doubleValue) < data->getNumberOfBands())
+                     {
+                        data->assignBand(v3.d.imageDataValue,
+                                         0,
+                                         (ossim_uint32)v2.d.doubleValue);
+                        
+                     }
+                  }
+               }
+               else
+               {
+                  if(data->getBuf()&&
+                     (ossim_uint32)v2.d.doubleValue < data->getNumberOfBands())
+                  {  
+                     ossim_uint32 upper = data->getWidth()*data->getHeight();
+                     float* buf = (float*)data->getBuf((ossim_uint32)v2.d.doubleValue);
+                     float value = v3.d.doubleValue;
+                     if(buf)
+                     {
+                        for(ossim_uint32 i = 0; i < upper; ++i)
+                        {
+                           *buf = value;
+                           ++buf;
+                        }  
+                     }
+                     else
+                     {
+                        result = false;
+                     }
+                  }
+               }
+               if(result)
+               {
+                  data->validate();
+                  v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+                  v.d.imageDataValue = data;
+                  theValueStack.push(v);
+               }
+            }
+            else
+            {
+               result = false;
+            }
+         }
+         else 
+         {
+            ossimEquValue v4 = argList[3];
+            if((v1.type == OSSIM_EQU_IMAGE_DATA_TYPE) &&
+               (v2.type == OSSIM_EQU_DOUBLE_TYPE)&&
+               (v3.type == OSSIM_EQU_IMAGE_DATA_TYPE)&&
+               (v4.type == OSSIM_EQU_DOUBLE_TYPE))
+            {
+               ossimImageData *data = (ossimImageData*)v1.d.imageDataValue->dup();
+               ossimEquValue v;
+               v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+               v.d.imageDataValue = data;
+               if(data->getBuf()&&v3.d.imageDataValue->getBuf())
+               {
+                  
+                  ossim_uint32 index1 = (ossim_uint32)v4.d.doubleValue;
+                  ossim_uint32 index2 = (ossim_uint32)v2.d.doubleValue;
+                  
+                  if((index1 > data->getNumberOfBands()) ||
+                     (index1 > v3.d.imageDataValue->getNumberOfBands()))
+                  {
+                     result = false;
+                  }
+                  else
+                  {     
+                     data->assignBand(v3.d.imageDataValue,
+                                      index1,
+                                      index2);
+                     data->validate();
+                  }
+                  
+               }
+               
+               theValueStack.push(v);
+            }
+         }
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Invalid number of arguments to assign_band" << endl;
+         result = false;
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "unable to parse arguments for assign band" << endl;
+      result = false;
+   }
+
+   clearArgList(argList);
+
+   return result;
+}
+
+bool ossimEquationCombiner::parseStdFuncs()
+{
+   bool result = true;
+
+   switch(theCurrentId)
+   {
+   case OSSIM_EQU_TOKEN_ASSIGN_BAND:
+   {
+      theCurrentId = theLexer->yylex();
+      if(!parseAssignBand())
+      {
+         result = false;
+      }
+      
+      break;
+   }
+   case OSSIM_EQU_TOKEN_CONV:
+   {
+      theCurrentId = theLexer->yylex();
+      vector<ossimEquValue> args;
+      if(parseArgList(args))
+      {
+         ossimImageData* resultImage = (ossimImageData*)NULL;
+         if(applyConvolution(resultImage,
+                              args))
+         {
+            if(resultImage)
+            {
+               ossimEquValue v;
+               v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+               v.d.imageDataValue = resultImage;
+               
+               theValueStack.push(v);
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "function conv error: resulting image is NULL" << endl;
+               result = false;
+            }
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Unable to apply convolution" << endl;
+            result = false;
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      
+      break;
+   }
+   case OSSIM_EQU_TOKEN_CLAMP:
+   {
+      theCurrentId = theLexer->yylex();
+      vector<ossimEquValue> args;
+      if(parseArgList(args))
+      {
+         ossimImageData* resultImage = (ossimImageData*)NULL;
+         if(applyClamp(resultImage,
+                       args))
+         {
+            if(resultImage)
+            {
+               ossimEquValue v;
+               v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+               v.d.imageDataValue = resultImage;
+               
+               theValueStack.push(v);
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "function clamp error: resulting image is NULL" << endl;
+               result = false;
+            }
+            
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Unable to apply clamp" << endl;
+            result = false;
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      
+      break;
+   }
+   case OSSIM_EQU_TOKEN_BAND:
+   {
+    // need to parse the following rule for blurr function
+      //
+      // band(image data, number)
+      theCurrentId = theLexer->yylex();
+
+
+      vector<ossimEquValue> argList;
+
+      if(parseArgList(argList))
+      {
+         if(argList.size() == 2)
+         {
+            ossimEquValue v1 = argList[0];
+            ossimEquValue v2 = argList[1];
+            ossimImageData* tempData = NULL;
+            ossim_uint32 bandNumber           = 0;
+            if(v1.type == OSSIM_EQU_IMAGE_DATA_TYPE)
+            {
+               tempData = v1.d.imageDataValue;
+            }
+            else
+            {
+               result = false;
+            }
+            if(v2.type == OSSIM_EQU_DOUBLE_TYPE)
+            {
+               bandNumber = (ossim_uint32)(v2.d.doubleValue);
+            }
+            else
+            {
+               result = false;
+            }
+            if(bandNumber > tempData->getNumberOfBands())
+            {
+               result = false;
+            }
+            if(result)
+            {
+               ossimImageData* data = new ossimImageData(this,
+                                                         OSSIM_FLOAT,
+                                                         1);
+               data->setWidthHeight(tempData->getWidth(),
+                                    tempData->getHeight());
+               data->setOrigin(tempData->getOrigin());
+               data->setNullPix(tempData->getNullPix(bandNumber),
+                                0);
+               data->setMinPix(tempData->getMinPix(bandNumber),
+                               0);
+               data->setMaxPix(tempData->getMaxPix(bandNumber),
+                               0);
+               data->initialize();
+               
+               if((tempData->getBuf())&&
+                  (bandNumber < tempData->getNumberOfBands()))
+               {
+                  data->assignBand(tempData,
+                                   bandNumber,
+                                   0);                           
+                  data->validate();
+               }
+               ossimEquValue v;
+               v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+               v.d.imageDataValue = data;
+               theValueStack.push(v);
+            }
+            
+            if(tempData)
+            {
+               // Delete the object indirectly through an ossimRefPtr.
+               ossimRefPtr<ossimImageData> id = tempData;
+               tempData = NULL;
+            }
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Invalid number of args in function band" << endl;
+            
+            result = false;
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      
+      break;
+   }
+   case OSSIM_EQU_TOKEN_BLURR:
+   {
+      theCurrentId = theLexer->yylex();
+      vector<ossimEquValue> args;
+      if(parseArgList(args))
+      {
+         ossimImageData* resultImage = (ossimImageData*)NULL;
+         if(applyBlurr(resultImage,
+                       args))
+         {
+            if(resultImage)
+            {
+               ossimEquValue v;
+               v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+               v.d.imageDataValue = resultImage;
+               
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+         else
+         {
+            result = false;
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      
+      break;
+   }
+   case OSSIM_EQU_TOKEN_SHIFT:
+   {
+      theCurrentId = theLexer->yylex();
+      vector<ossimEquValue> args;
+      if(parseArgList(args))
+      {
+         ossimImageData* resultImage = (ossimImageData*)NULL;
+         if(applyShift(resultImage,
+                       args))
+         {
+            if(resultImage)
+            {
+               ossimEquValue v;
+               v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+               v.d.imageDataValue = resultImage;
+               
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+         else
+         {
+            result = false;
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      
+      break;
+   }
+   case OSSIM_EQU_TOKEN_MAX:
+   case OSSIM_EQU_TOKEN_MIN:
+   {
+      ossimBinaryOp* op = NULL;
+      if(theCurrentId == OSSIM_EQU_TOKEN_MIN) op = new ossimBinaryOpMin;
+      else op = new ossimBinaryOpMax;
+      
+      int argCount = 0;
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         bool done = false;
+         while(!done)
+         {
+            if(parseExpression())
+            {
+               
+               ++argCount;
+               if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+               {
+                  theCurrentId = theLexer->yylex();
+                  
+                  done = true;
+               }
+               else if(theCurrentId == OSSIM_EQU_TOKEN_COMMA)
+               {
+                  theCurrentId = theLexer->yylex();
+               }
+               else
+               {
+                  result = false;
+                  done = true;
+               }
+            }
+            else
+            {
+               done = true;
+               result = false;
+            }
+         }
+         if((argCount > 1)&&result)
+         {
+            result = true;
+            
+            ossimEquValue v;
+            ossimEquValue v1;
+            ossimEquValue v2;
+
+            v2 = theValueStack.top();
+            theValueStack.pop();
+            v1 = theValueStack.top();
+            theValueStack.pop();
+            argCount -=2;
+
+            do
+            {
+               if(applyOp(*op,
+                          v,
+                          v1,
+                          v2))
+               {
+                  theValueStack.push(v);
+               }
+               else
+               {
+                  result = false;
+                  argCount = 0;
+                  
+               }
+               --argCount;
+               
+               if((argCount>0)&&result)
+               {
+                  v2 = theValueStack.top();
+                  theValueStack.pop();
+                  v1 = theValueStack.top();
+                  theValueStack.pop();
+               }
+               
+            }while((argCount > 0)&&(result));
+         }
+         else
+         {
+            result = false;
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      if(op)
+      {
+         delete op;
+         op = NULL;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_ABS:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpAbs(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_SIN:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpSin(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_SIND:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpSind(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_ASIN:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpASin(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_ASIND:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpASind(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_COS:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpCos(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_COSD:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpCosd(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_ACOS:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpACos(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_ACOSD:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpACosd(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_TAN:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpTan(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_TAND:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpTand(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_ATAN:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpATan(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_ATAND:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpATand(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_LOG:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpLog(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_LOG10:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpLog10(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_SQRT:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpSqrt(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   case OSSIM_EQU_TOKEN_EXP:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_PAREN)
+      {
+         theCurrentId = theLexer->yylex();
+         result = parseExpression();
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            if(theValueStack.size() > 0)
+            {
+               theCurrentId = theLexer->yylex();
+               ossimEquValue v;
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+               
+               applyOp(ossimUnaryOpExp(),
+                       v,
+                       v1);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      break;
+   }
+   default:
+   {
+      result = false;
+   }
+   }
+
+   return result;
+}
+
+bool ossimEquationCombiner::parseUnaryFactor()
+{
+   bool result = false;
+
+   
+   if(theCurrentId == OSSIM_EQU_TOKEN_MINUS)
+   {
+      theCurrentId = theLexer->yylex();
+
+      if(parseFactor())
+      {
+         if(theValueStack.size() > 0)
+         {
+            ossimEquValue v;
+            ossimEquValue v1 = theValueStack.top();
+            theValueStack.pop();
+            
+            applyOp(ossimUnaryOpNeg(),
+                    v,
+                    v1);
+            
+            theValueStack.push(v);
+         }
+         else
+         {
+            result = false;
+         }
+
+         result = true;
+      }
+      else
+      {
+         result = false;
+      }
+   }
+   else if(theCurrentId == OSSIM_EQU_TOKEN_TILDE)
+   {
+      theCurrentId = theLexer->yylex();
+
+      if(parseFactor())
+      {
+         if(theValueStack.size() > 0)
+         {
+            ossimEquValue v;
+            ossimEquValue v1 = theValueStack.top();
+            theValueStack.pop();
+            
+            applyOp(ossimUnaryOpOnesComplement(),
+                    v,
+                    v1);
+            
+            theValueStack.push(v);
+         }
+         else
+         {
+            result = false;
+         }
+
+         result = true;
+      }
+      else
+      {
+         result = false;
+      }
+   }
+   return result;
+}
+
+bool ossimEquationCombiner::parseFactor()
+{
+   bool result = false;
+
+   switch(theCurrentId)
+   {
+   case OSSIM_EQU_TOKEN_CONSTANT:
+   {
+      ossimEquValue v;
+
+      v.type = OSSIM_EQU_DOUBLE_TYPE;
+      v.d.doubleValue = atof(theLexer->YYText());
+      theValueStack.push(v);
+      
+      theCurrentId = theLexer->yylex();
+      
+      result =  true;
+      break;
+   }
+   case OSSIM_EQU_TOKEN_PI:
+   {
+      ossimEquValue v;
+
+      v.type = OSSIM_EQU_DOUBLE_TYPE;
+      v.d.doubleValue = M_PI;
+      theValueStack.push(v);
+      
+      theCurrentId = theLexer->yylex();
+      
+      result =  true;
+      break;      
+   }
+   case OSSIM_EQU_TOKEN_IMAGE_VARIABLE:
+   {
+      theCurrentId = theLexer->yylex();
+      if(theCurrentId == OSSIM_EQU_TOKEN_LEFT_ARRAY_BRACKET)
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseExpression())
+         {
+            if(!theValueStack.empty())
+            {
+               if(theValueStack.top().type == OSSIM_EQU_DOUBLE_TYPE)
+               {
+                  if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_ARRAY_BRACKET)
+                  {
+                     theCurrentId = theLexer->yylex();
+                     ossim_uint32 index = (ossim_uint32)theValueStack.top().d.doubleValue;
+                     theValueStack.pop();
+                     ossimRefPtr<ossimImageData> data = getNewImageData(index);
+                     result = true;
+                     if(data.valid())
+                     {
+                        ossimEquValue v;
+                        v.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+                        v.d.imageDataValue = data.release();
+                        theValueStack.push(v);
+
+                     }
+                     else
+                     {
+                        ossimNotify(ossimNotifyLevel_WARN)
+                           <<"Data is NULL for array operation" << endl;
+                     }
+                     result = true;
+                  }
+                  else
+                  {
+                     ossimNotify(ossimNotifyLevel_WARN)
+                        << "Mismatched Right array bracket" << endl;
+                  }
+               }
+               else
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << "Expression between array brackets is not a number"
+                     << endl;
+               }
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "no expression within array brackets" << endl;
+            }
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Unabel to parse expression"<<endl;
+         }
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            <<"Need left array brackets to access an input source"<<endl;
+      }
+      
+      break;
+   }
+   case OSSIM_EQU_TOKEN_LEFT_PAREN:
+   {
+      theCurrentId = theLexer->yylex();
+      if(parseExpression())
+      {
+         if(theCurrentId == OSSIM_EQU_TOKEN_RIGHT_PAREN)
+         {
+            result       =  true;
+            theCurrentId = theLexer->yylex();
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "Right parenthesis missing" << endl;
+            result = false;
+         }
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Unable to parse expression within parenthesis" << endl;
+         result = false;
+      }
+      
+      break;
+   }
+   }
+   if(!result) result = parseUnaryFactor();
+   
+   if(!result) result = parseStdFuncs();
+   
+   return result;
+}
+
+bool ossimEquationCombiner::parseRestOfTerm()
+{
+   //---
+   // Parse the following rule:
+   // RestOfTerm: * Factor RestOfTerm | / Factor RestOfTerm |
+   // ^ Factor RestOfTerm
+   //---
+   bool result = true;
+   
+   switch(theCurrentId)
+   {
+      case OSSIM_EQU_TOKEN_MULT:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpMul(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_WARN)
+                  << "Multiplication requires two arguments" << endl;
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+         break;
+      }
+      case OSSIM_EQU_TOKEN_DIV:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpDiv(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_XOR:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpXor(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_AMPERSAND:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpAnd(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_OR_BAR:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpOr(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_MOD:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpMod(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_POWER:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpPow(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+         break;
+      }
+      case OSSIM_EQU_TOKEN_BEQUAL:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpEqual(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_BGREATER:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpGreater(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_BGREATEROREQUAL:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpGreaterOrEqual(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_BLESS:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpLess(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_BLESSOREQUAL:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpLessOrEqual(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+      case OSSIM_EQU_TOKEN_BDIFFERENT:
+      {
+         theCurrentId = theLexer->yylex();
+         if(parseFactor())
+         {
+            if(theValueStack.size() > 1)
+            {
+               ossimEquValue v;
+            
+               ossimEquValue v2 = theValueStack.top();
+               theValueStack.pop();
+               ossimEquValue v1 = theValueStack.top();
+               theValueStack.pop();
+            
+               applyOp(ossimBinaryOpDifferent(),
+                       v,
+                       v1,
+                       v2);
+            
+               theValueStack.push(v);
+            }
+            else
+            {
+               result = false;
+            }
+            if(result)
+            {
+               result = parseRestOfTerm();
+            }
+         }
+         else
+         {
+            result = false;
+         }
+
+         break;
+      }
+   }
+   
+   return result;
+}
+
+bool ossimEquationCombiner::parseTerm()
+{
+   // parse the following rule:
+   //
+   // Term : Factor RestOfTerm
+   
+   bool result = false;
+
+   result = parseFactor();
+   
+   if(result)
+   {
+      result = parseRestOfTerm();
+   }
+   
+   return result;
+}
+
+bool ossimEquationCombiner::parseRestOfExp()
+{
+   // parse the following rule:
+   // RestOfExpression : + Term RestOfExpression | - Term RestOfExpression | epsilon
+   //
+   bool result = true;
+   
+   if(theCurrentId == OSSIM_EQU_TOKEN_PLUS)
+   {
+      theCurrentId = theLexer->yylex();
+      if(parseTerm())
+      {
+
+         if(theValueStack.size() > 1)
+         {
+            ossimEquValue v;
+            
+            ossimEquValue v2 = theValueStack.top();
+            theValueStack.pop();
+            ossimEquValue v1 = theValueStack.top();
+            theValueStack.pop();
+            
+            
+            applyOp(ossimBinaryOpAdd(),
+                    v,
+                    v1,
+                    v2);              
+            
+            theValueStack.push(v);
+         }
+         else
+         {
+            result = false;
+         }
+         if(result)
+         {
+            result = parseRestOfExp();
+         }
+      }
+      else
+      {
+        result =  false;
+      }
+   }
+   else if(theCurrentId == OSSIM_EQU_TOKEN_MINUS)
+   {
+      theCurrentId = theLexer->yylex();
+      if(parseTerm())
+      {
+         if(theValueStack.size() > 1)
+         {
+            ossimEquValue v;
+            
+            ossimEquValue v2 = theValueStack.top();
+            theValueStack.pop();
+            ossimEquValue v1 = theValueStack.top();
+            theValueStack.pop();
+            
+            applyOp(ossimBinaryOpSub(),
+                    v,
+                    v1,
+                    v2);
+            
+            theValueStack.push(v);
+         }
+         else
+         {
+            result = false;
+         }
+         if(result)
+         {
+            result = parseRestOfExp();
+         }
+      }
+      else
+      {
+         result =  false;
+      }
+   }
+   
+   return result;
+}
+
+ossimRefPtr<ossimImageData> ossimEquationCombiner::getImageData(ossim_uint32 index)
+{
+   ossimRefPtr<ossimImageData> result;
+   ossimConnectableObject* obj = getInput(index);
+   
+   if(obj)
+   {
+      theCastFilter->connectMyInputTo(0, obj);
+      result= (theCastFilter->getTile(theTile->getImageRectangle(),
+                                      theCurrentResLevel));
+      
+      if(result.valid())
+      {
+         result->setMinPix(theTile->getMinPix(), theTile->getNumberOfBands());
+         result->setMaxPix(theTile->getMaxPix(), theTile->getNumberOfBands());
+      }
+   }
+
+   return result;
+}
+
+ossimRefPtr<ossimImageData> ossimEquationCombiner::getNewImageData(
+   ossim_uint32 index)
+{
+   ossimRefPtr<ossimImageData> result = getImageData(index);
+
+   if(result.valid())
+   {
+      if(result->getBuf())
+      {
+         result = (ossimImageData*)result->dup();
+      }
+   }
+
+   return result;
+}
+
+bool ossimEquationCombiner::parseExpression()
+{
+   // parse the following rule:
+   // expression : Term ResOfExpression
+   //
+   
+   bool result = false;
+   
+   if(parseTerm())
+   {
+      result =  parseRestOfExp();
+   }
+
+   return result;
+}
+
+ossimRefPtr<ossimImageData> ossimEquationCombiner::parseEquation()
+{
+   ostringstream s;
+
+   s << theEquation;
+
+   istringstream inS(s.str());
+   theLexer->switch_streams(&inS, &ossimNotify(ossimNotifyLevel_WARN));
+
+   theCurrentId = theLexer->yylex();
+
+   while(theCurrentId)
+   {
+      if(!parseExpression())
+      {
+         break;
+      }
+   }
+
+   if(!theValueStack.empty())
+   {
+      assignValue();
+      theTile->validate();
+      clearStacks();
+   }
+   
+   return theTile;
+}    
+
+bool ossimEquationCombiner::applyClamp(ossimImageData* &result,
+                                       const vector<ossimEquValue>& argList)
+{
+   if(result)
+   {
+      // Delete the object indirectly through an ossimRefPtr.
+      ossimRefPtr<ossimImageData> id = result;
+      id = NULL;
+      result = (ossimImageData*) NULL;
+   }
+   if(argList.size() <3)
+   {
+      return false;
+   }
+
+   if(argList[0].type == OSSIM_EQU_DOUBLE_TYPE)
+   {
+      return false;
+   }
+   else if( (argList[1].type == OSSIM_EQU_DOUBLE_TYPE)&&
+            (argList[2].type == OSSIM_EQU_DOUBLE_TYPE))
+   {
+      result = argList[0].d.imageDataValue;
+      
+      if(argList[0].d.imageDataValue)
+      {
+         ossimDataObjectStatus status = result->getDataObjectStatus();
+         if((status != OSSIM_NULL) &&
+            (status != OSSIM_EMPTY))
+         {
+            double minValue = argList[1].d.doubleValue;
+            double maxValue = argList[2].d.doubleValue;
+            
+            if(minValue > maxValue)
+            {
+               std::swap(minValue, maxValue);
+            }
+            
+            int band   = 0;
+            int offset = 0;
+            
+            int upperBoundBand   = result->getNumberOfBands();
+            int offsetUpperBound = result->getWidth()*result->getHeight();
+
+            if(status == OSSIM_PARTIAL)
+            {
+               for(band = 0; band < upperBoundBand; ++band)
+               {
+                  float np = static_cast<float>(result->getNullPix(band));
+                  float *buf = static_cast<float*>(result->getBuf(band));
+                  for(offset = 0; offset < offsetUpperBound; ++ offset)
+                  {
+                     if( *buf != np )
+                     {
+                        if( (*buf) < minValue) *buf = minValue;
+                        else if( (*buf) >maxValue) *buf = maxValue;
+                     }
+                     ++buf;
+                  }
+               }
+            }
+            else
+            {
+               for(band = 0; band < upperBoundBand; ++band)
+               {
+                  float *buf = static_cast<float*>(result->getBuf(band));
+                  for(offset = 0; offset < offsetUpperBound; ++ offset)
+                  {
+                     if( (*buf) < minValue) *buf = minValue;
+                     else if( (*buf) >maxValue) *buf = maxValue;
+                     ++buf;
+                  }
+               }
+            }
+         }
+      }
+         
+      return true;
+   }
+   return false;
+}
+
+bool ossimEquationCombiner::applyConvolution(ossimImageData* &result,
+                                             const vector<ossimEquValue>& argList)
+{
+   if(result)
+   {
+      // Delete the object indirectly through an ossimRefPtr.
+      ossimRefPtr<ossimImageData> id = result;
+      id = NULL;
+      result = (ossimImageData*) NULL;
+   }
+   if(argList.size() <4) return false;
+   
+   for(ossim_uint32 i = 0; i < argList.size(); ++i)
+   {
+      if(argList[i].type != OSSIM_EQU_DOUBLE_TYPE)
+      {
+         return false;
+      }
+   }
+
+   ossim_uint32 index = (ossim_uint32)argList[0].d.doubleValue;
+   int rows = (int)argList[1].d.doubleValue;
+   int cols = (int)argList[2].d.doubleValue;
+   
+   if((rows*cols) != (int)(argList.size()-3))
+   {
+      return false;
+   }
+   
+   NEWMAT::Matrix m(rows,cols);
+
+    int count = 3;
+    for(int r = 0; r< rows;++r)
+    {
+       for(int c=0;c<cols;++c)
+       {
+          m[r][c] = argList[count].d.doubleValue;
+          ++count;
+       }
+    }
+   ossimConnectableObject* obj = getInput(index);
+   if(obj)
+   {
+      ossimConvolutionSource* conv = new ossimConvolutionSource(NULL, m);
+
+      conv->connectMyInputTo(0, obj);
+      theCastFilter->connectMyInputTo(0, conv);
+      
+      ossimRefPtr<ossimImageData> tempData =
+         theCastFilter->getTile(theTile->getImageRectangle(),
+                                theCurrentResLevel);
+      if(tempData.valid())
+      {
+         result = (ossimImageData*)tempData->dup();
+      }
+      else
+      {
+         result = (ossimImageData*)theTile->dup();
+      }
+
+      delete conv;
+   }
+   if(result)
+   {
+      return true;
+   }
+
+   return false;
+}
+
+bool ossimEquationCombiner::applyBlurr(ossimImageData* &result,
+                                       const vector<ossimEquValue>& argList)
+{
+   if(result)
+   {
+      // Delete the object indirectly through an ossimRefPtr.
+      ossimRefPtr<ossimImageData> id = result;
+      id = NULL;
+      result = (ossimImageData*) NULL;
+   }
+   if(argList.size() !=3) return false;
+   
+   for(ossim_uint32 i = 0; i < argList.size(); ++i)
+   {
+      if(argList[i].type != OSSIM_EQU_DOUBLE_TYPE)
+      {
+         return false;
+      }
+   }
+
+   ossim_uint32 index = (ossim_uint32)argList[0].d.doubleValue;
+   int rows = (int)argList[1].d.doubleValue;
+   int cols = (int)argList[2].d.doubleValue;
+   
+   NEWMAT::Matrix m(rows, cols);
+
+   m = 1.0/(rows*cols);
+
+   ossimConnectableObject* obj = getInput(index);
+   if(obj)
+   {
+      ossimConvolutionSource* conv = new ossimConvolutionSource(NULL,
+                                                                m);
+
+      conv->connectMyInputTo(0, obj);
+      theCastFilter->connectMyInputTo(0, conv);
+      theCastFilter->initialize();
+
+      ossimRefPtr<ossimImageData> tempData =
+         theCastFilter->getTile(theTile->getImageRectangle(),
+                                theCurrentResLevel);
+      if(tempData.valid())
+      {
+         result = (ossimImageData*)tempData->dup();
+      }
+      delete conv;
+   }
+
+   if(result)
+   {
+      return true;
+   }
+
+   return false;
+}
+
+bool ossimEquationCombiner::applyShift(ossimImageData* &result,
+                                       const vector<ossimEquValue>& argList)
+{
+   if(result)
+   {
+      // Delete the object indirectly through an ossimRefPtr.
+      ossimRefPtr<ossimImageData> id = result;
+      id = NULL;
+      result = (ossimImageData*) NULL;
+   }
+   if(argList.size() !=3) return false;
+   
+   for(ossim_uint32 i = 0; i < argList.size(); ++i)
+   {
+      if(argList[i].type != OSSIM_EQU_DOUBLE_TYPE)
+      {
+         return false;
+      }
+   }
+
+   ossim_uint32 index = (ossim_uint32)argList[0].d.doubleValue;
+   int x = (int)argList[1].d.doubleValue;
+   int y = (int)argList[2].d.doubleValue;
+
+   ossimConnectableObject* obj = getInput(index);
+   if(obj)
+   {
+      ossimSubImageTileSource* shiftSource =
+         new ossimSubImageTileSource(NULL, ossimIpt(x, y));
+
+      shiftSource->connectMyInputTo(0, obj);
+      theCastFilter->connectMyInputTo(0, shiftSource);
+
+       ossimRefPtr<ossimImageData> tempData =
+          theCastFilter->getTile(theTile->getImageRectangle(),
+                                 theCurrentResLevel);
+       if(tempData.valid())
+       {
+          result = (ossimImageData*)tempData->dup();
+       }
+       delete shiftSource;
+   }
+
+   if(result)
+   {
+      return true;
+   }
+
+   return false;
+}
+
+bool ossimEquationCombiner::applyOp(const ossimBinaryOp& op,
+                                    ossimEquValue& result,
+                                    ossimEquValue& v1,
+                                    ossimEquValue& v2)
+{
+   bool returnValue = true;
+   
+   if(v1.type == OSSIM_EQU_DOUBLE_TYPE)
+   {
+      if(v2.type == OSSIM_EQU_DOUBLE_TYPE)
+      {
+         result.type = OSSIM_EQU_DOUBLE_TYPE;
+         result.d.doubleValue = op.apply(v1.d.doubleValue, v2.d.doubleValue);
+      }
+      else if(v2.type == OSSIM_EQU_IMAGE_DATA_TYPE)
+      {
+         returnValue = applyOp(op,
+                               v1.d.doubleValue,
+                               v2.d.imageDataValue);
+         
+         result.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+         result.d.imageDataValue = v2.d.imageDataValue;
+      }
+      else
+      {
+         returnValue = false;
+      }
+   }
+   else if(v1.type == OSSIM_EQU_IMAGE_DATA_TYPE)
+   {
+      if(v2.type == OSSIM_EQU_DOUBLE_TYPE)
+      {
+         
+         returnValue = applyOp(op,
+                               v1.d.imageDataValue,
+                               v2.d.doubleValue);
+         
+         result.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+         result.d.imageDataValue = v1.d.imageDataValue;
+         returnValue = true;
+      }
+      else if(v2.type == OSSIM_EQU_IMAGE_DATA_TYPE)
+      {
+         returnValue = applyOp(op,
+                               v1.d.imageDataValue,
+                               v2.d.imageDataValue);
+         result.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+         result.d.imageDataValue = v1.d.imageDataValue;
+
+         // Delete the object indirectly through an ossimRefPtr.
+         ossimRefPtr<ossimImageData> id = v2.d.imageDataValue;
+         id = NULL;
+         v2.d.imageDataValue = (ossimImageData*)NULL;
+         returnValue = true;
+      }
+      else
+      {
+         returnValue = false;
+      }
+   }
+   else
+   {
+      returnValue = false;
+   }
+   
+   return returnValue;
+}
+
+bool ossimEquationCombiner::applyOp(const ossimBinaryOp& op,
+                                    ossimImageData* v1,
+                                    double          v2)
+{   
+   float* buf = static_cast<float*>(v1->getBuf());
+   if(!buf) return true;
+   ossimDataObjectStatus status = v1->getDataObjectStatus();
+
+   if(status == OSSIM_EMPTY || status == OSSIM_NULL)
+   {
+      return true;
+   }
+
+   if(status == OSSIM_FULL )
+   {
+      ossim_uint32 size = v1->getSize();
+      float value = (static_cast<float>(v2));
+     
+      for(ossim_uint32 i = 0; i < size; ++i)
+      {
+         *buf = (float)op.apply(*buf, value);
+         ++buf;
+      }
+   }
+   else
+   {
+      ossim_uint32 sizePerBand = v1->getSizePerBand();
+      ossim_uint32 numberOfBands = v1->getNumberOfBands();
+
+      if(numberOfBands)
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            float* buf = static_cast<float*>(v1->getBuf(band));
+
+            if(buf)
+            {
+               float  np  = static_cast<float>(v1->getNullPix()[band]);
+               
+               for(ossim_uint32 offset = 0; offset < sizePerBand;++offset)
+               {
+                  if(*buf != np)
+                  {
+                     *buf = (float)op.apply(*buf, v2);
+                  }
+                  ++buf;
+               }
+            }
+         }
+      }
+   }
+   return true;
+}
+
+bool ossimEquationCombiner::applyOp(const ossimBinaryOp& op,
+                                    double          v1,
+                                    ossimImageData* v2)
+{   
+   float* buf = static_cast<float*>(v2->getBuf());
+   if(!buf) return true;
+   ossimDataObjectStatus status = v2->getDataObjectStatus();
+
+   if(status == OSSIM_EMPTY || status == OSSIM_NULL)
+   {
+      return true;
+   }
+
+   if(status == OSSIM_FULL )
+   {
+      ossim_uint32 size = v2->getSize();
+      float value = (static_cast<float>(v1));
+     
+      for(ossim_uint32 i = 0; i < size; ++i)
+      {
+         *buf = (float)op.apply(value, *buf);
+         ++buf;
+      }
+   }
+   else
+   {
+      ossim_uint32 sizePerBand = v2->getSizePerBand();
+      ossim_uint32 numberOfBands = v2->getNumberOfBands();
+
+      if(numberOfBands)
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            float* buf = static_cast<float*>(v2->getBuf(band));
+
+            if(buf)
+            {
+               float  np  = static_cast<float>(v2->getNullPix()[band]);
+               
+               for(ossim_uint32 offset = 0; offset < sizePerBand; ++offset)
+               {
+                  if(*buf != np)
+                  {
+                     *buf = (float)op.apply((float)v1, *buf);
+                  }
+                  ++buf;
+               }
+            }
+         }
+      }
+   }
+   
+   return true;
+}
+
+bool ossimEquationCombiner::applyOp(const ossimBinaryOp& op,
+                                    ossimImageData* v1,
+                                    ossimImageData* v2)
+{
+   ossim_uint32 minNumberOfBands = std::min(v1->getNumberOfBands(), v2->getNumberOfBands());
+   ossim_uint32 maxNumberOfBands = std::max(v1->getNumberOfBands(), v2->getNumberOfBands());
+   
+   ossim_uint32 size = v1->getWidth()*v1->getHeight();
+   ossimDataObjectStatus status1 = v1->getDataObjectStatus();
+   ossimDataObjectStatus status2 = v2->getDataObjectStatus();
+
+   float** bandV1   = new float*[maxNumberOfBands];
+   float** bandV2   = new float*[maxNumberOfBands];
+   float* bandV1Np  = new float[maxNumberOfBands];
+   float* bandV2Np  = new float[maxNumberOfBands];
+   ossim_uint32 band = 0;
+   for(band = 0; band < minNumberOfBands; ++band)
+   {
+      bandV1[band]   = (float*)v1->getBuf(band);
+      bandV2[band]   = (float*)v2->getBuf(band);
+      bandV1Np[band] = (float)v1->getNullPix(band);
+      bandV2Np[band] = (float)v2->getNullPix(band);
+   }
+   if(v1->getNumberOfBands() < v2->getNumberOfBands())
+   {
+      for(band = 0; band < maxNumberOfBands; ++band)
+      {
+         bandV1[band]   = (float*)v1->getBuf(minNumberOfBands-1);
+         bandV2[band]   = (float*)v2->getBuf(band);
+         bandV1Np[band] = (float)v1->getNullPix(minNumberOfBands-1);
+         bandV2Np[band] = (float)v2->getNullPix(band);
+      }
+   }
+   else if(v2->getNumberOfBands() < v1->getNumberOfBands())
+   {
+      for(band = 0; band < maxNumberOfBands; ++band)
+      {
+         bandV1[band]   = (float*)v1->getBuf(band);
+         bandV2[band]   = (float*)v2->getBuf(minNumberOfBands-1);
+         bandV1Np[band] = (float)v1->getNullPix(band);
+         bandV2Np[band] = (float)v2->getNullPix(minNumberOfBands-1);
+      }
+   }
+
+   if(status1 == OSSIM_EMPTY)
+   {
+      if(status2 == OSSIM_FULL)
+      {
+         for(band = 0; band < maxNumberOfBands; ++band)
+         {
+            float* buf1 = bandV1[band];
+            float* buf2 = bandV2[band];
+            
+            for(ossim_uint32 i = 0; i < size; ++i)
+            {
+               *buf1 = *buf2;
+               ++buf1;
+               ++buf2;
+            }
+         }
+      }
+      else if(status2 == OSSIM_PARTIAL)
+      {
+         for(band = 0; band < maxNumberOfBands; ++band)
+         {
+            float* buf1 = bandV1[band];
+            float* buf2 = bandV2[band];
+            float  nullPix2 = bandV2Np[band];
+            for(ossim_uint32 i = 0; i < size; ++i)
+            {
+               if(*buf2 != nullPix2)
+               {
+                  *buf1 = *buf2;
+               }
+               ++buf1;
+               ++buf2;
+            }
+         }
+      }
+      v1->setDataObjectStatus(status2);
+   }
+   else if((status1 == OSSIM_FULL)&&
+           (status2 == OSSIM_FULL))
+   { 
+      for(band = 0; band < maxNumberOfBands; ++band)
+      {
+         float* buf1 = bandV1[band];
+         float* buf2 = bandV2[band];
+         
+         for(ossim_uint32 i = 0; i < size; ++i)
+         {
+            *buf1 = op.apply(*buf1, *buf2);
+            ++buf1;
+            ++buf2;
+         }
+      }
+   }
+   else if((status1 == OSSIM_FULL)&&
+           (status2 == OSSIM_PARTIAL))
+   {
+      for(band = 0; band < maxNumberOfBands; ++band)
+      {
+         float* buf1 = bandV1[band];
+         float* buf2 = bandV2[band];
+         float  nullPix2 = bandV2Np[band];
+         for(ossim_uint32 i = 0; i < size; ++i)
+         {
+            if(*buf2 != nullPix2)
+            {
+               *buf1 = op.apply(*buf1, *buf2);
+            }
+               
+            ++buf1;
+            ++buf2;
+         }
+      }
+   }
+   else if((status1 == OSSIM_PARTIAL)&&
+           (status2 == OSSIM_FULL))
+   {
+      for(band = 0; band < maxNumberOfBands; ++band)
+      {
+         float* buf1 = bandV1[band];
+         float* buf2 = bandV2[band];
+         float  nullPix1 = bandV1Np[band];
+         for(ossim_uint32 i = 0; i < size; ++i)
+         {
+            if(*buf1 != nullPix1)
+            {
+               *buf1 = op.apply(*buf1, *buf2);
+            }
+               
+            ++buf1;
+            ++buf2;
+         }
+      }
+   }
+   else if((status1 == OSSIM_PARTIAL)&&
+           (status2 == OSSIM_PARTIAL))
+   {
+      for(band = 0; band < maxNumberOfBands; ++band)
+      {
+         float* buf1 = bandV1[band];
+         float* buf2 = bandV2[band];
+         float  nullPix1 = bandV1Np[band];
+         float  nullPix2 = bandV2Np[band];
+         for(ossim_uint32 i = 0; i < size; ++i)
+         {
+            if((*buf1 != nullPix1)&&
+               (*buf2 != nullPix2))
+            {
+               *buf1 = op.apply(*buf1, *buf2);
+            }
+               
+            ++buf1;
+            ++buf2;
+         }
+      }
+   }
+
+   delete [] bandV1;
+   delete [] bandV2;
+   delete [] bandV1Np;
+   delete [] bandV2Np;
+   
+   return true;
+}
+
+
+bool ossimEquationCombiner::applyOp(const ossimUnaryOp& op,
+                                    ossimEquValue& result,
+                                    ossimEquValue& v)
+{
+   bool returnValue = true;
+   
+   if(v.type == OSSIM_EQU_DOUBLE_TYPE)
+   {
+      result.type = OSSIM_EQU_DOUBLE_TYPE;
+      result.d.doubleValue = op.apply(v.d.doubleValue);
+   }
+   else if(v.type == OSSIM_EQU_IMAGE_DATA_TYPE)
+   {
+      returnValue = applyOp(op,
+                            v.d.imageDataValue);
+      result.type = OSSIM_EQU_IMAGE_DATA_TYPE;
+      result.d.imageDataValue = v.d.imageDataValue;
+      returnValue = true;
+   }
+   else
+   {
+      returnValue = false;
+   }
+   
+   return returnValue;
+}
+
+bool ossimEquationCombiner::applyOp(const ossimUnaryOp& op,
+                                    ossimImageData* v)
+{   
+   float* buf = static_cast<float*>(v->getBuf());
+   if(!buf) return true;
+   ossimDataObjectStatus status = v->getDataObjectStatus();
+
+   if(status == OSSIM_EMPTY || status == OSSIM_NULL)
+   {
+      return true;
+   }
+
+   if(status == OSSIM_FULL )
+   {
+      ossim_uint32 size = v->getSize();
+     
+      for(ossim_uint32 i = 0; i < size; ++i)
+      {
+         *buf = (float)op.apply(*buf);
+         ++buf;
+      }
+   }
+   else
+   {
+      ossim_uint32 sizePerBand   = v->getSizePerBand();
+      ossim_uint32 numberOfBands = v->getNumberOfBands();
+
+      if(numberOfBands)
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            float* buf = static_cast<float*>(v->getBuf(band));
+
+            if(buf)
+            {
+               float  np  = static_cast<float>(v->getNullPix()[band]);
+               
+               for(ossim_uint32 offset = 0; offset < sizePerBand;++offset)
+               {
+                  if(*buf != np)
+                  {
+                     *buf = (float)op.apply(*buf);
+                  }
+                  ++buf;
+               }
+            }
+         }
+      }
+   }
+   
+   return true;
+}
+
+bool ossimEquationCombiner::saveState(ossimKeywordlist& kwl,
+                                      const char* prefix)const
+{
+   ossimString outputScalarType =
+      ossimScalarTypeLut::instance()->getEntryString(theOutputScalarType);
+   
+   kwl.add(prefix,
+           EQUATION_KW,
+           theEquation.c_str(),
+           true);
+
+   kwl.add(prefix,
+           "output_scalar_type",
+           outputScalarType.c_str(),
+           true);
+   
+   return ossimImageCombiner::saveState(kwl,
+                                        prefix);
+}
+
+bool ossimEquationCombiner::loadState(const ossimKeywordlist& kwl,
+                                      const char* prefix)
+{
+   const char* equ    = kwl.find(prefix, EQUATION_KW);
+   const char* scalar = kwl.find(prefix, "output_scalar_type");
+   
+   bool result = ossimImageCombiner::loadState(kwl,
+                                               prefix);
+   
+   if(equ)
+   {
+      theEquation = equ;
+   }
+
+   if(scalar)
+   {      
+      setOutputScalarType(ossimScalarTypeLut::instance()->
+                          getScalarTypeFromString(scalar));
+   }
+
+   return result;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEquationCombiner.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEquationCombiner.h
new file mode 100644
index 0000000000..f0c8775531
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEquationCombiner.h
@@ -0,0 +1,311 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimEquationCombiner.h,v 1.29 2005/09/12 12:02:42 dburken Exp $
+#ifndef ossimEquationCombiner_HEADER
+#define ossimEquationCombiner_HEADER
+#include <imaging/tile_sources/ossimImageCombiner.h>
+#include <base/misc/ossimEquTokenizer.h>
+#include <stack>
+
+class ossimCastTileSourceFilter;
+
+/**
+ * Will combine the input data based on a supplied equation.
+ *
+ * This combiner uses the ossimEquTokenizer to create unique id's
+ * for all tokens in the formula.  The parser is based on the following
+ * rules:
+ *
+ * <pre>
+ * 
+ * Prog -> Expr EOF 
+ * Expr -> Term RestExpr 
+ * RestExpr -> + Term RestExpr | - Term RestExpr | <null> 
+ * Term -> Storable RestTerm 
+ * RestTerm -> * Factor RestTerm | / Factor RestTerm | <null> 
+ * Factor -> number | R | ( Expr )
+ *
+ *
+ * We support the following tokens:
+ *
+ * sin(x)                 takes the sine of the input
+ * sind(x)                takes the sin of the input and assumes degree input
+ * cos(x)                 takes cosine of input
+ * cosd(x)                takes the cosine of input and assumes input in degrees
+ * sqrt(x)                takes square root of input
+ * log(x)                 takes the natural log of input
+ * log10(x)               takes the log base 10 of the input
+ * exp(x)                 takes the e raised to the passed in argument
+ * abs(x)                 takes the absolute value of the passed in value
+ * min(x1, x2, ... xn)    takes the min of all values in the list
+ * max(x1, x2, ... xn)    takes the max of all values in the list.
+ *
+ * clamp(image_data, min, max)
+ *                        will clamp all data to be between the min max values.
+ *                        will set anything less than min to min and anythin
+ *                        larger than max to max
+ *
+ * band(image_data, num)  returns a single band image object
+ *                        by selecting band num from input image i1.  Note
+ *                        the first argument must be an image
+ *                        and the second argument must be a number
+ *
+ * shift(index, num_x, num_y)
+ *                        currently, the first argument must be an image
+ *                        variable(i1, i2, ... in) and x, and y must b numbers
+ *                        indicating the delta in that direction to shift the
+ *                        input.
+ *
+ * blurr(index, rows, cols)
+ *                        Will blurr the input image i with a
+ *                        rows-by-cols kernel.  All values are equal
+ *                        weight.  Note the fist argument must by an image
+ *                        variable (ex: i1, i2,....in).
+ *
+ * conv(index, rows, cols, <row ordered list of values> )
+ *                        this allows you to define an arbitrary matrix.  The
+ *                        <row ordered list of values> is a comma separated
+ *                        list of constant values.
+ *
+ * assign_band(image_data, num1, data2, num2)
+ *                        will take band num2 from image data2 and assign it to
+ *                        band num1 in data 1.
+ *
+ * assign_band(image_data, num1, data2)
+ *                        will take band 1 from image data2 and assign it to
+ *                        band num1 in data 1.
+ *
+ * assign_band(image_data, num1, num2)
+ *                        will assin to band num1 of data 1 the value of num2
+ *
+ * x1 * x2                will multiply x1 and x2
+ * x1 + x2                will add x1 and x2
+ * x1 - x2                will subtract x1 and x2
+ * x1 / x2                will divide x1 and x2
+ * x1 ^ x2                will do a power, raises x1 to x2
+ * x1 | x2                will do a bitwise or operation
+ *                        ( will do it in unisgned char precision)
+ *
+ * x1 & x2                will do a bitwise and operation
+ *                        ( will do it in unsigned char precision)
+ *
+ * ~x1                    will do the ones complement of the input
+ *
+ * x1 xor x2              will do an xclusive or operation
+ *                        (will do it in unsigned char precision)
+ *
+ * - x1                   will negative of x1
+ *
+ * Boolean ops: 1=true, 0=false
+ * x1 > x2
+ * x1 >= x2
+ * x1 == x2
+ * x1 <= x2
+ * x1 < x2
+ * x1 <> x2
+ *
+ * Note:
+ *
+ * Currently an image input is reference by the variable i followed by
+ * the input image index from 1.  So 1 referes to the first image
+ * all result are promoted to an image object.
+ *
+ * Bands are accesible with in[B], B starts from 0
+ *
+ * Some examples:
+ *
+ *  (in[0] + in[1])/2
+ *  Will take image 1 and add it to image 2 and average them.
+ *
+ *  exp(sqrt(in[0])/4)
+ *  Will take the root of the image and divide by 4 and then raise e to that
+ *  amount.
+ *
+ *  128
+ *  Will return a constant value of 128 for all input bands.
+ *
+ * min(1,in[3],in[4], max(in[2],in[1]))
+ *
+ * shift(0, 1, 1) - i1
+ * Will shift input 0 by 1 pixel along the diagonal  and then subtract it
+ * from input 1.
+ *
+ * assign_band(i1, 1, blurr(i1, 5, 5), 2)
+ * Will assign to the first band of i1 the 2nd band of the 5x5 blurr of i1.
+ *
+ * conv(0, 3, 3, -1, -2, -1, 0, 0, 0, 1, 2, 1)
+ * Will convolve the first input connection with a 3x3 matrix.
+ * The args are row ordered:
+ *                          -1, -2, -1
+ *                           0,  0,  0
+ *                           1,  2,  1
+ *
+ * NDVI:
+ * N=(in[0]-in[1])/(in[0]+in[1])
+ *
+ * For indexed-type values,like NDVI, (with limited values) it is better
+ * to rescale between 0.0 and 1.0 and use type NormalizedFloat.
+ * 
+ * Rescaled NDVI between 0 and 1:
+ * (N+1)/2 = in[0]/(in[0]+in[1])
+ * 
+ * </pre>
+ */
+class OSSIMDLLEXPORT ossimEquationCombiner : public ossimImageCombiner
+{
+public:
+   ossimEquationCombiner();
+   virtual ~ossimEquationCombiner();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual void initialize();
+
+   virtual void setEquation(const ossimString& equ)
+      {
+         theEquation = equ;
+      }
+   virtual ossimString getEquation()const
+      {
+         return theEquation;
+      }
+   
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   virtual ossimScalarType getOutputScalarType() const;
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   
+   
+   virtual void setOutputScalarType(ossimScalarType scalarType);
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   class ossimBinaryOp
+   {
+   public:
+      virtual ~ossimBinaryOp(){}
+      virtual double apply(double v1, double v2)const=0;
+   };
+   class ossimUnaryOp
+   {
+   public:
+      virtual ~ossimUnaryOp(){}
+      virtual double apply(double v)const=0;
+   };
+   
+protected:
+   enum ossimEquValueType
+   {
+      OSSIM_EQU_TYPE_UNKNOWN    = 0,
+      OSSIM_EQU_DOUBLE_TYPE     = 1,
+      OSSIM_EQU_IMAGE_DATA_TYPE = 2
+   };
+   
+   union ossimEquDataType
+   {
+      double           doubleValue;
+      ossimImageData* imageDataValue;
+   };
+   
+   struct ossimEquValue
+   {
+      int              type;
+      ossimEquDataType d;
+   };
+
+   ossimScalarType             theOutputScalarType;
+   ossimString                 theEquation;
+   mutable ossimEquTokenizer  *theLexer;
+   ossimRefPtr<ossimImageData> theTile;
+   ossimCastTileSourceFilter  *theCastFilter;
+   ossimCastTileSourceFilter  *theCastOutputFilter;
+   
+   mutable int                theCurrentId;
+   mutable std::stack<ossimEquValue> theValueStack;
+   ossim_uint32                     theCurrentResLevel;
+   virtual void assignValue();
+   virtual void clearStacks();
+   virtual void clearArgList(vector<ossimEquValue>& argList);
+
+   virtual ossimRefPtr<ossimImageData> getImageData(ossim_uint32 index);
+   virtual ossimRefPtr<ossimImageData> getNewImageData(ossim_uint32 index);
+
+   virtual void deleteArgList(vector<ossimEquValue>& args);
+   virtual bool parseArgList(vector<ossimEquValue>& args,
+                             bool popValueStack = true);
+   
+   virtual ossimRefPtr<ossimImageData> parseEquation();
+  
+   virtual bool parseAssignBand();
+   virtual bool parseExpression();
+   virtual bool parseRestOfExp();
+   virtual bool parseTerm();
+   virtual bool parseRestOfTerm();
+   virtual bool parseFactor();
+   virtual bool parseStdFuncs();
+   virtual bool parseUnaryFactor();
+
+   virtual bool applyClamp(ossimImageData* &result,
+                           const vector<ossimEquValue>& argList);
+                           
+   virtual bool applyConvolution(ossimImageData* &result,
+                                 const vector<ossimEquValue>& argList);
+   
+   virtual bool applyBlurr(ossimImageData* &result,
+                           const vector<ossimEquValue>& argList);
+   
+   virtual bool applyShift(ossimImageData* &result,
+                           const vector<ossimEquValue>& argList);
+   
+   virtual bool applyOp(const ossimBinaryOp& op,
+                        ossimEquValue& result,
+                        ossimEquValue& v1,
+                        ossimEquValue& v2);
+   
+   virtual bool applyOp(const ossimBinaryOp& op,
+                        ossimImageData* v1,
+                        double          v2);
+
+   virtual bool applyOp(const ossimBinaryOp& op,
+                        double          v1,
+                        ossimImageData* v2);
+
+   virtual bool applyOp(const ossimBinaryOp& op,
+                        ossimImageData* v1,
+                        ossimImageData* v2);      
+
+   
+   virtual bool applyOp(const ossimUnaryOp& op,
+                        ossimEquValue& result,
+                        ossimEquValue& v1);
+   
+   virtual bool applyOp(const ossimUnaryOp& op,
+                        ossimImageData* v);
+   
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEsriShapeFileCutter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEsriShapeFileCutter.cpp
new file mode 100644
index 0000000000..77483974e4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEsriShapeFileCutter.cpp
@@ -0,0 +1,323 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimEsriShapeFileCutter.cpp,v 1.6 2005/09/15 12:28:44 gpotts Exp $
+#include <imaging/tile_sources/ossimEsriShapeFileCutter.h>
+
+RTTI_DEF2(ossimEsriShapeFileCutter,
+          "ossimEsriShapeFileCutter",
+          ossimImageSourceFilter,
+          ossimViewInterface);
+
+ossimEsriShapeFileCutter::ossimEsriShapeFileCutter()
+   :ossimImageSourceFilter(),
+    ossimViewInterface(),
+    theEsriShapeFile(NULL),
+    theMaskFilter(NULL)
+{
+   theObject = this;
+   theEsriShapeFile = new ossimEsriShapeFileFilter;
+   theEsriShapeFile->setFillFlag(true);
+
+   theMaskFilter    = new ossimMaskFilter;
+
+   theMaskFilter->connectMyInputTo(1,
+                                   theEsriShapeFile);
+}
+
+ossimEsriShapeFileCutter::~ossimEsriShapeFileCutter()
+{
+   if(theEsriShapeFile)
+   {
+      delete theEsriShapeFile;
+      theEsriShapeFile = NULL;
+   }
+
+   if(theMaskFilter)
+   {
+      delete theMaskFilter;
+      theMaskFilter = NULL;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimEsriShapeFileCutter::getTile(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   if(isSourceEnabled())
+   {
+      if(theMaskFilter)
+      {
+         return theMaskFilter->getTile(rect, resLevel);
+      }
+   }
+   else
+   {
+      if(getInput())
+      {
+         ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                                     getInput());
+         
+         if(input)
+         {
+            return input->getTile(rect, resLevel);
+         }
+      }
+   }
+   
+   return NULL;
+}
+
+void ossimEsriShapeFileCutter::initialize()
+{
+   if(theEsriShapeFile)
+   {
+      theEsriShapeFile->initialize();
+   }
+
+   
+   if(theMaskFilter)
+   {
+      theMaskFilter->disconnectMyInput((ossim_int32)0);
+      theMaskFilter->disconnectMyInput((ossim_int32)1);
+      theMaskFilter->connectMyInputTo((int)0,
+                                      getInput(0));
+      theMaskFilter->connectMyInputTo(1,
+                                      theEsriShapeFile);
+   }
+}
+
+bool ossimEsriShapeFileCutter::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   ossimString shapeFilePrefix = ossimString(prefix) + "shape_file_filter.";
+   ossimString maskPrefix      = ossimString(prefix) + "mask.";
+                                 
+   theEsriShapeFile->loadState(kwl, shapeFilePrefix.c_str());
+   theMaskFilter->loadState(kwl, maskPrefix.c_str());
+
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimEsriShapeFileCutter::saveState(ossimKeywordlist& kwl,
+                                         const char* prefix)const
+{
+   ossimString shapeFilePrefix = ossimString(prefix) + "shape_file_filter.";
+   ossimString maskPrefix      = ossimString(prefix) + "mask.";
+                                 
+   theEsriShapeFile->saveState(kwl, shapeFilePrefix.c_str());
+   theMaskFilter->saveState(kwl, maskPrefix.c_str());
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+void ossimEsriShapeFileCutter::getDecimationFactor(ossim_uint32 resLevel,
+                                                   ossimDpt& result)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(input)
+   {
+      input->getDecimationFactor(resLevel, result);
+   }
+}
+
+ossimIrect ossimEsriShapeFileCutter::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimIrect result;
+   result.makeNan();
+   
+   if(theMaskFilter)
+   {
+      result = theMaskFilter->getBoundingRect(resLevel);
+   }
+   
+   return result;
+}
+
+void ossimEsriShapeFileCutter::getDecimationFactors(
+   vector<ossimDpt>& decimations)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      input->getDecimationFactors(decimations);
+   }     
+}
+
+ossim_uint32 ossimEsriShapeFileCutter::getNumberOfDecimationLevels()const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getNumberOfDecimationLevels();
+   } 
+   return 0;
+}
+
+ossim_uint32 ossimEsriShapeFileCutter::getNumberOfOutputBands() const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getNumberOfOutputBands();
+   }
+   return 0;
+}
+
+ossimScalarType ossimEsriShapeFileCutter::getOutputScalarType() const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getOutputScalarType();
+   }
+   
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+void ossimEsriShapeFileCutter::getValidImageVertices(
+   vector<ossimIpt>& validVertices,
+   ossimVertexOrdering ordering,
+   ossim_uint32 resLevel) const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      input->getValidImageVertices(validVertices, ordering, resLevel);
+   }
+}
+
+ossim_uint32 ossimEsriShapeFileCutter::getTileWidth() const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getTileWidth();
+   }
+   
+   return 0;
+}
+
+ossim_uint32 ossimEsriShapeFileCutter::getTileHeight() const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getTileHeight();
+   }
+   return 0;
+}
+
+double ossimEsriShapeFileCutter::getNullPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getNullPixelValue(band);
+   }
+   return 0;
+}
+   
+double ossimEsriShapeFileCutter::getMinPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getMinPixelValue(band);
+   }
+   return 0;
+}
+   
+double ossimEsriShapeFileCutter::getMaxPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(input)
+   {
+      return input->getMaxPixelValue(band);
+   }
+   return 0;
+}
+
+void ossimEsriShapeFileCutter::loadFile(const ossimFilename& filename)
+{
+   if(theEsriShapeFile)
+   {
+      theEsriShapeFile->loadShapeFile(filename);
+   }
+}
+
+bool ossimEsriShapeFileCutter::setView(ossimObject* baseObject,
+                                       bool ownsTheView)
+{
+   if(theEsriShapeFile)
+   {
+      return theEsriShapeFile->setView(baseObject, ownsTheView);
+   }
+   
+   return false;
+}
+
+ossimObject* ossimEsriShapeFileCutter::getView()
+{
+   if(theEsriShapeFile)
+   {
+      return theEsriShapeFile->getView();
+   }
+   
+   return NULL;;
+}
+
+const ossimObject* ossimEsriShapeFileCutter::getView()const
+{
+   if(theEsriShapeFile)
+   {
+      return theEsriShapeFile->getView();
+   }
+   
+   return NULL;;
+}
+
+ossimFilename ossimEsriShapeFileCutter::getFilename()const
+{
+   if(theEsriShapeFile)
+   {
+      return theEsriShapeFile->getFilename();
+   }
+   
+   return ossimFilename();
+}
+
+void ossimEsriShapeFileCutter::setMaskType(
+   ossimMaskFilter::ossimFileSelectionMaskType type)
+{
+   if(theMaskFilter)
+   {
+      theMaskFilter->setMaskType(type);
+   }
+}
+
+ossimMaskFilter::ossimFileSelectionMaskType ossimEsriShapeFileCutter::getMaskType()const
+{
+   if(theMaskFilter)
+   {
+      return theMaskFilter->getMaskType();
+   }
+   
+   return ossimMaskFilter::OSSIM_MASK_TYPE_SELECT;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEsriShapeFileCutter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEsriShapeFileCutter.h
new file mode 100644
index 0000000000..afc7e2da88
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimEsriShapeFileCutter.h
@@ -0,0 +1,200 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimEsriShapeFileCutter.h,v 1.10 2005/09/15 12:28:44 gpotts Exp $
+#ifndef ossimEsriShapeFileCutter_HEADER
+#define ossimEsriShapeFileCutter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <base/common/ossimViewInterface.h>
+#include <imaging/tile_sources/ossimMaskFilter.h>
+#include <imaging/annotation/ossimEsriShapeFileFilter.h>
+
+/**
+ * This class wraps the ossimEsriShapeFileFilter and ossimMaskFilter to implement
+ * a composite cutter.
+ *
+ * the ossimEsriShapeFileFilter is saved with a shape_file_filter. prefix and the
+ * ossimMaskFilter is saved with a mask. prefix.  Please see ossimEsriShapeFileFilter
+ * and ossimMaskFilter classes for their keywords. theborder size has an optional units
+ * associated with it. 
+ * <pre>
+ *
+ * The border size can be us-feet, feet, meters, or degrees and is only applied
+ * to polygons.
+ *
+ * Example keyword list
+ *
+ * shape_file_filter.brush_color:  255 255 255
+ * shape_file_filter.feature_name:  
+ * shape_file_filter.filename:  
+ * shape_file_filter.fill_flag:  0
+ * shape_file_filter.max_quadtree_levels:  10
+ * shape_file_filter.pen_color:  255 255 255
+ * shape_file_filter.point_width_height:  1 1 
+ * shape_file_filter.thickness:  1
+ * shape_file_filter.border_size: 50 meters
+ * shape_file_filter.type:  ossimEsriShapeFileFilter
+ * mask.mask_type: select
+ * mask.type: ossimMaskFilter
+ 
+ * </pre>
+ *
+ */
+class ossimEsriShapeFileCutter : public ossimImageSourceFilter,
+                                 public ossimViewInterface
+{
+public:
+   /**
+    * allocates the mask and esri loader
+    */
+   ossimEsriShapeFileCutter();
+   
+   /**
+    * destroys the data members
+    */
+   virtual ~ossimEsriShapeFileCutter();
+   
+   /**
+    * Sent to the input
+    */
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result)const;
+
+   /**
+    * The bounding rect call is passed to the mask filter
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+
+   /**
+    * The get tile call is passed to the mask filter
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+
+   /**
+    * is passed to the filter and the shape file loader
+    */
+   virtual void initialize();
+
+   /**
+    * passed to the input source.
+    */
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations)const;
+
+   /**
+    * passed to the input source.
+    */
+   virtual ossim_uint32 getNumberOfDecimationLevels()const;
+
+   /**
+    * passed to the input source.
+    */
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+   
+   /**
+    * passed to the input source.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    * passed to the input source.
+    */
+   virtual void getValidImageVertices(
+      vector<ossimIpt>& validVertices,
+      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+      ossim_uint32 resLevel=0)const;
+
+   /**
+    * passed to the input source.
+    */
+   virtual ossim_uint32 getTileWidth() const;
+
+   /**
+    * passed to the input source.
+    */
+   virtual ossim_uint32 getTileHeight() const;
+
+   /**
+    * passed to the input source.
+    */
+   virtual double getNullPixelValue(ossim_uint32 band)const;
+   
+   /**
+    * passed to the input source.
+    */
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   
+   /**
+    * passed to the input source.
+    */
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   /**
+    * passed to the shape file to load the shape file that will be used
+    * by the mask filter as input.
+    */
+   void loadFile(const ossimFilename& filename);
+
+   /**
+    * this is here to support the view interface of the esri shape file.
+    * it passes view calls to the esri filter
+    */
+   virtual bool setView(ossimObject* baseObject,
+                        bool ownsTheView = false);
+   
+   /**
+    * this is here to support the view interface of the esri shape file.
+    * Will return the view setting for the esri shape file.
+    */
+   virtual ossimObject* getView();
+
+   /**
+    * this is here to support the view interface of the esri shape file.
+    * Will return the view setting for the esri shape file.
+    */
+   virtual const ossimObject* getView()const;
+
+   /**
+    * Return the current esri shape file being used
+    */
+   ossimFilename getFilename()const;
+
+   /**
+    * Sets the mask type.  Passes the call to the Mask filter.
+    */
+   void setMaskType(ossimMaskFilter::ossimFileSelectionMaskType type);
+
+   /**
+    * returns the mask type from the maks filter.
+    */
+   ossimMaskFilter::ossimFileSelectionMaskType getMaskType()const;
+
+   /**
+    * Passes load state call to the esri shape file loader with prefix
+    * shape_file_filter.  Then passes the load state cll to the mask
+    * filter with prefix = mask.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * Passes save state call to the esri shape file loader with prefix
+    * shape_file_filter.  Then passes the load state cll to the mask
+    * filter with prefix = mask.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+protected:
+   ossimEsriShapeFileFilter* theEsriShapeFile;
+   ossimMaskFilter*          theMaskFilter;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFeatherMosaic.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFeatherMosaic.cpp
new file mode 100644
index 0000000000..53f36fcddf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFeatherMosaic.cpp
@@ -0,0 +1,474 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimFeatherMosaic.cpp,v 1.33 2005/05/09 12:39:40 dburken Exp $
+
+#include <imaging/tile_sources/ossimFeatherMosaic.h>
+#include <base/data_types/ossimDpt.h>
+#include <imaging/ossimImageData.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimLine.h>
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug("ossimFeatherMosaic:debug");
+
+RTTI_DEF1(ossimFeatherMosaic, "ossimFeatherMosaic", ossimImageMosaic);
+
+ossimFeatherMosaic::ossimFeatherMosaic()
+   :ossimImageMosaic(),
+    theInputFeatherInformation(NULL),
+    theAlphaSum(NULL),
+    theResult(NULL),
+    theFeatherInfoSize(0)
+{
+}
+
+ossimFeatherMosaic::ossimFeatherMosaic(std::vector<ossimImageSource*>& inputSources)
+   :ossimImageMosaic(inputSources),
+    theInputFeatherInformation(NULL),
+    theAlphaSum(NULL),
+    theResult(NULL),
+    theFeatherInfoSize(0)
+{
+   initialize();
+}
+
+ossimFeatherMosaic::~ossimFeatherMosaic()
+{
+   if(theInputFeatherInformation)
+   {
+      delete [] theInputFeatherInformation;
+      theInputFeatherInformation = NULL;
+   }
+   theFeatherInfoSize = 0;
+}
+
+ossimRefPtr<ossimImageData> ossimFeatherMosaic::getTile(const ossimIrect& tileRect,
+                                            ossim_uint32 resLevel)
+{
+   long w = tileRect.width();
+   long h = tileRect.height();
+   ossimIpt origin = tileRect.ul();
+   
+   if(!isSourceEnabled())
+   {
+      return ossimImageMosaic::getTile(tileRect, resLevel);
+   }
+   if(!theTile||!theAlphaSum||!theResult||!theInputFeatherInformation)
+   {
+      initialize();
+
+      if(!theTile||!theAlphaSum||!theResult||!theInputFeatherInformation)
+      {
+         return ossimImageMosaic::getTile(tileRect, resLevel);
+      }
+   }
+   ossim_uint32 size = getNumberOfInputs();
+   theAlphaSum->setImageRectangle(tileRect);
+   theResult->setImageRectangle(tileRect);
+   
+   if(size == 0)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   if(size == 1)
+   {
+      return ossimImageMosaic::getTile(tileRect, resLevel);
+   }
+
+   long tileW = theTile->getWidth();
+   long tileH = theTile->getHeight();
+   if((w != tileW)||
+      (h != tileH))
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+      }
+   }
+   theTile->setOrigin(origin);
+   theTile->makeBlank();
+      
+   switch(theTile->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         return combine(static_cast<ossim_uint8>(0),
+                        tileRect, resLevel);
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         return combine(static_cast<ossim_uint16>(0),
+                        tileRect, resLevel);
+      }
+      case OSSIM_SSHORT16:
+      {
+         return combine(static_cast<ossim_sint16>(0),
+                        tileRect, resLevel);
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         return combine(static_cast<double>(0),
+                        tileRect, resLevel);
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         return combine(static_cast<float>(0),
+                        tileRect, resLevel);
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimFeatherMosaic::getTile: error, unknown scalar type!!!"
+            << std::endl;
+      }
+   }
+   return ossimRefPtr<ossimImageData>();
+}
+
+
+template <class T> ossimRefPtr<ossimImageData> ossimFeatherMosaic::combine(
+   T,
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> currentImageData;
+   ossim_uint32 band;
+   long upperBound = theTile->getWidth()*theTile->getHeight();
+   long offset = 0;
+   long row    = 0;
+   long col    = 0;
+   long numberOfTilesProcessed = 0;
+   float *sumBand       = static_cast<float*>(theAlphaSum->getBuf());
+   float         *bandRes = NULL;
+   ossimIpt point;
+   
+   theAlphaSum->fill(0.0);
+   theResult->fill(0.0);
+   
+   T** srcBands  = new T*[theLargestNumberOfInputBands];
+   T** destBands = new T*[theLargestNumberOfInputBands];
+
+   currentImageData  = getNextTile(0,
+                                   tileRect,
+                                   resLevel);
+   if(!currentImageData.valid())
+   {
+      delete [] srcBands;
+      delete [] destBands;
+      return currentImageData;
+   }
+   ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
+   for(band = 0; band < minNumberOfBands; ++band)
+   {
+      srcBands[band]  = static_cast<T*>(currentImageData->getBuf(band));
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+   }
+   // if the src is smaller than the destination in number
+   // of bands we will just duplicate the last band.
+   for(;band < theLargestNumberOfInputBands; ++band)
+   {
+      srcBands[band]  = srcBands[minNumberOfBands - 1];
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+   }
+
+   // most of the time we will not overlap so let's
+   // copy the first tile into destination and check later.
+   //
+   for(band = 0; band < theTile->getNumberOfBands();++band)
+   {
+      T* destBand = destBands[band];
+      T* srcBand  = srcBands[band];
+      if(destBand&&srcBand)
+      {
+         for(offset = 0; offset < upperBound;++offset)
+         {
+            *destBand = *srcBand;
+            ++srcBand; ++destBand;
+         }
+      }
+   }
+   theTile->setDataObjectStatus(currentImageData->getDataObjectStatus());
+
+   while(currentImageData.valid())
+   {
+      ossimDataObjectStatus currentStatus     = currentImageData->getDataObjectStatus();
+      point = currentImageData->getOrigin();
+      long h = (long)currentImageData->getHeight();
+      long w = (long)currentImageData->getWidth();
+      if( (currentStatus != OSSIM_EMPTY) &&
+          (currentStatus != OSSIM_NULL))
+      {
+         ++numberOfTilesProcessed;
+         offset = 0;
+         minNumberOfBands = currentImageData->getNumberOfBands();
+         for(band = 0; band < minNumberOfBands; ++band)
+         {
+            srcBands[band]  = static_cast<T*>(currentImageData->getBuf(band));
+         }
+         // if the src is smaller than the destination in number
+         // of bands we will just duplicate the last band.
+         for(;band < theLargestNumberOfInputBands; ++band)
+         {
+            srcBands[band]  = srcBands[minNumberOfBands - 1];
+         }
+          if(currentStatus == OSSIM_PARTIAL)
+          {
+            for(row = 0; row < h; ++row)
+            {
+               for(col = 0; col < w; ++col)
+               {
+                  if(!currentImageData->isNull(offset))
+                  {
+                     double weight = computeWeight(theCurrentIndex,
+                                                   ossimDpt(point.x+col,
+                                                            point.y+row));
+                     
+                     for(band = 0; band < theLargestNumberOfInputBands; ++band)
+                     {
+                        bandRes = static_cast<float*>(theResult->getBuf(band));
+                        bandRes[offset] += (srcBands[band][offset]*weight);
+                     }
+                     sumBand[offset] += weight;
+                  }
+                  ++offset;
+               }
+            }
+         }
+         else
+         {
+            offset = 0;
+            
+            for(row = 0; row < h; ++row)
+            {
+               for(col = 0; col < w; ++col)
+               {
+                     double weight = computeWeight(theCurrentIndex,
+                                                   ossimDpt(point.x+col,
+                                                            point.y+row));
+                     
+                     for(band = 0; band < theLargestNumberOfInputBands; ++band)
+                     {
+                        bandRes     = static_cast<float*>(theResult->getBuf(band));
+                        
+                        bandRes[offset] += (srcBands[band][offset]*weight);
+                     }
+                     sumBand[offset] += weight;
+                     ++offset;
+               }
+            }
+         }
+      }
+      currentImageData = getNextTile(tileRect, resLevel);
+   }
+   upperBound = theTile->getWidth()*theTile->getHeight();
+
+   if(numberOfTilesProcessed > 1)
+   {
+      const double* minPix = theTile->getMinPix();
+      const double* maxPix = theTile->getMaxPix();
+      const double* nullPix= theTile->getNullPix();
+      for(offset = 0; offset < upperBound;++offset)
+      {
+         for(band = 0; band < theTile->getNumberOfBands();++band)
+         {
+            T* destBand      = static_cast<T*>(theTile->getBuf(band));
+            float* weightedBand = static_cast<float*>(theResult->getBuf(band));
+
+            // this should be ok to test 0.0 instead of
+            // FLT_EPSILON range for 0 since we set it.
+            if(sumBand[offset] != 0.0)
+            {            
+               weightedBand[offset] = (weightedBand[offset])/sumBand[offset];
+               if(weightedBand[offset]<minPix[band])
+               {
+                  weightedBand[offset] = minPix[band];   
+               }
+               else if(weightedBand[offset] > maxPix[band])
+               {
+                  weightedBand[offset] = maxPix[band];                   
+               }
+            }
+            else
+            {
+               weightedBand[offset] = nullPix[band];
+            }
+            destBand[offset] = static_cast<T>(weightedBand[offset]);
+         }
+      }
+      theTile->validate();
+   }
+
+   delete [] srcBands;
+   delete [] destBands;
+
+   return theTile;
+}
+
+double ossimFeatherMosaic::computeWeight(long index,
+                                         const ossimDpt& point)const
+{
+   ossimFeatherInputInformation& info = theInputFeatherInformation[index];
+   double result = 0.0;
+   ossimDpt delta = point-info.theCenter;
+   
+   double length1 = fabs(delta.x*info.theAxis1.x + delta.y*info.theAxis1.y)/info.theAxis1Length;
+   double length2 = fabs(delta.x*info.theAxis2.x + delta.y*info.theAxis2.y)/info.theAxis2Length;
+
+   if(length1 > length2)
+   {
+      result = (1.0 - length1);
+   }
+   else
+   {
+      result = (1.0 - length2);
+   }
+   if(result < 0) result = 0;
+   
+   return result;
+}
+
+void ossimFeatherMosaic::initialize()
+{
+   ossimImageMosaic::initialize();
+
+   allocate();
+   if(theTile.valid())
+   {
+      theAlphaSum = new ossimImageData(this,
+                                       OSSIM_FLOAT,
+                                       1,
+                                       theTile->getWidth(),
+                                       theTile->getHeight());
+      theResult = new ossimImageData(this,
+                                     OSSIM_FLOAT,
+                                     theLargestNumberOfInputBands,
+                                     theTile->getWidth(),
+                                     theTile->getHeight());
+      theAlphaSum->initialize();
+      theResult->initialize();
+   }
+   std::vector<ossimIpt> validVertices;
+   if(!getNumberOfInputs()) return;
+
+   if(theInputFeatherInformation)
+   {
+      delete [] theInputFeatherInformation;
+      theInputFeatherInformation = NULL;
+   }
+   theFeatherInfoSize = getNumberOfInputs();
+   theInputFeatherInformation = new ossimFeatherInputInformation[theFeatherInfoSize];
+   for(long index = 0; index < theFeatherInfoSize; ++ index)
+   {
+      validVertices.clear();
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(index));
+      if(temp)
+      {
+         temp->getValidImageVertices(validVertices, OSSIM_CLOCKWISE_ORDER);
+         theInputFeatherInformation[index].setVertexList(validVertices);
+      }
+   }
+}
+
+
+ossimFeatherMosaic::ossimFeatherInputInformation::ossimFeatherInputInformation(const std::vector<ossimIpt>& validVertices)
+{
+   setVertexList(validVertices);
+}
+
+
+void ossimFeatherMosaic::ossimFeatherInputInformation::setVertexList(const std::vector<ossimIpt>& validVertices)
+{
+   const char* MODULE = "ossimFeatherMosaic::ossimFeatherInputInformation::setVertexList()";
+   
+   theValidVertices = validVertices;
+
+   theCenter       = ossimDpt(0,0);
+   theAxis1        = ossimDpt(1, 0);
+   theAxis2        = ossimDpt(0, 1);
+   theAxis1Length  = 1;
+   theAxis2Length  = 1;
+
+   double xSum=0.0, ySum=0.0;
+   long upperBound = validVertices.size();
+   if(upperBound)
+   {
+      for(long index = 0; index < upperBound; ++index)
+      {
+         xSum += validVertices[index].x;
+         ySum += validVertices[index].y;
+      }
+
+      theCenter.x = xSum/upperBound;
+      theCenter.y = ySum/upperBound;
+
+      // for now we just want a quick implementation of something
+      // and we know that we have 4 vertices for the bounding valid
+      // vertices.
+      //
+      if(upperBound == 4)
+      {
+         ossimDpt edgeDirection1 = validVertices[1] - validVertices[0];
+         ossimDpt edgeDirection2 = validVertices[2] - validVertices[1];
+
+         theAxis1 = ossimDpt(-edgeDirection1.y, edgeDirection1.x);
+         
+         theAxis2 = ossimDpt(-edgeDirection2.y, edgeDirection2.x);
+
+         theAxis1 = theAxis1/theAxis1.length();
+         theAxis2 = theAxis2/theAxis2.length();
+
+         ossimLine line1(theCenter,
+                         theCenter + theAxis1*2);
+         ossimLine line2(validVertices[1],
+                         validVertices[0]);
+         ossimLine line3(theCenter,
+                         theCenter + theAxis2*2);
+         ossimLine line4(validVertices[2],
+                         validVertices[1]);
+         
+         ossimDpt intersectionPoint1 = line1.intersectInfinite(line2);
+         ossimDpt intersectionPoint2 = line3.intersectInfinite(line4);
+
+         
+         theAxis1Length = irint((theCenter-intersectionPoint1).length());
+         theAxis2Length = irint((theCenter-intersectionPoint2).length());
+
+          if(traceDebug())
+          {
+             CLOG << "theAxis1Length:       " << theAxis1Length << endl
+                  << "theAxis2Length:       " << theAxis2Length << endl
+                  << "center:               " << theCenter      << endl;
+          }
+      }
+   }
+}
+
+ostream& operator<<(ostream& out,
+                    const ossimFeatherMosaic::ossimFeatherInputInformation& data)
+{
+   out << "center: " << data.theCenter << endl
+       << "axis1:  " << data.theAxis1  << endl
+       << "axis2:  " << data.theAxis2  << endl
+       << "axis1_length: " << data.theAxis1Length << endl
+       << "axis2_length: " << data.theAxis2Length << endl
+       << "valid vertices: " << endl;
+   std::copy(data.theValidVertices.begin(),
+             data.theValidVertices.end(),
+             std::ostream_iterator<ossimDpt>(out, "\n"));
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFeatherMosaic.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFeatherMosaic.h
new file mode 100644
index 0000000000..7f8dfdbe19
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFeatherMosaic.h
@@ -0,0 +1,87 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimFeatherMosaic.h,v 1.13 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimFeatherMosaic_HEADER
+#define ossimFeatherMosaic_HEADER
+#include <vector>
+#include <iterator>
+
+#include <imaging/tile_sources/ossimImageMosaic.h>
+#include <base/data_types/ossimDpt.h>
+
+
+/**
+ * Performs a spatial blend accross overlapping regions
+ */
+class OSSIMDLLEXPORT ossimFeatherMosaic : public ossimImageMosaic
+{
+public:
+   ossimFeatherMosaic();
+   ossimFeatherMosaic(vector<ossimImageSource*>& inputSources);
+   virtual ~ossimFeatherMosaic();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                   ossim_uint32 resLevel=0);
+   virtual void initialize();
+       
+protected:
+   /**
+    * This is only visible by this class and will remain here
+    * unless we want to move it later.
+    */
+   class ossimFeatherInputInformation
+   {
+      
+   public:
+      ossimFeatherInputInformation(const vector<ossimIpt>& validVertices=vector<ossimIpt>());
+
+      void setVertexList(const vector<ossimIpt>& validVertices);
+      
+      ossimDpt        theCenter;
+      ossimDpt        theAxis1;
+      ossimDpt        theAxis2;
+      double          theAxis1Length;
+      double          theAxis2Length;
+      std::vector<ossimIpt> theValidVertices;
+      
+   };
+
+   friend ostream& operator<<(ostream& out,
+                              const ossimFeatherInputInformation& data);
+   
+
+   /**
+    * will hold an array of input information
+    *
+    */
+   ossimFeatherInputInformation* theInputFeatherInformation;
+   ossimRefPtr<ossimImageData> theAlphaSum;
+   ossimRefPtr<ossimImageData> theResult;
+   
+   /**
+    * Will hold the count for the feather information list.
+    */
+   long                          theFeatherInfoSize;
+
+   /**
+    * The dummy variable is used for the template type.  See the getTile
+    * method for the call.
+    */
+   template <class T>
+   ossimRefPtr<ossimImageData> combine(T dummyVariableNotUsed,
+                                       const ossimIrect& tileRect,
+                                       ossim_uint32 resLevel);
+   
+   virtual double computeWeight(long index,
+                                const ossimDpt& point)const;
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimFeatherMosaic_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFftFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFftFilter.cpp
new file mode 100644
index 0000000000..78edddaacd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFftFilter.cpp
@@ -0,0 +1,472 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimFftFilter.cpp,v 1.4 2005/02/11 15:07:33 dburken Exp $
+
+#include <imaging/tile_sources/ossimFftFilter.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <matrix/newmat.h>
+#include <matrix/newmatap.h>
+#include <imaging/tile_sources/ossimScalarRemapper.h>
+#include <base/property/ossimStringProperty.h>
+
+RTTI_DEF1(ossimFftFilter, "ossimFftFilter", ossimImageSourceFilter);
+
+ossimFftFilter::ossimFftFilter(ossimObject* owner)
+   :ossimImageSourceFilter(owner),
+    theTile(0),
+    theDirectionType(ossimFftFilterDirectionType_FORWARD),
+    theScalarRemapper(new ossimScalarRemapper())
+{
+   theScalarRemapper->setOutputScalarType(OSSIM_DOUBLE);
+}
+
+ossimFftFilter::ossimFftFilter(ossimImageSource* inputSource)
+   :ossimImageSourceFilter(inputSource),
+    theTile(0),
+    theDirectionType(ossimFftFilterDirectionType_FORWARD),
+    theScalarRemapper(new ossimScalarRemapper())
+{
+   theScalarRemapper->setOutputScalarType(OSSIM_DOUBLE);
+}
+
+ossimFftFilter::ossimFftFilter(ossimObject* owner,
+                               ossimImageSource* inputSource)
+   :ossimImageSourceFilter(owner, inputSource),
+    theTile(0),
+    theDirectionType(ossimFftFilterDirectionType_FORWARD),
+    theScalarRemapper(new ossimScalarRemapper())
+{
+   theScalarRemapper->setOutputScalarType(OSSIM_DOUBLE);
+}
+
+ossimFftFilter::~ossimFftFilter()
+{
+   if(theScalarRemapper)
+   {
+      delete theScalarRemapper;
+      theScalarRemapper = 0;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimFftFilter::getTile(const ossimIrect& rect,
+                                                    ossim_uint32 resLevel)
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getTile(rect, resLevel);
+   }
+   
+   ossimIrect tempRequest = rect;
+
+   ossim_uint32 w = rect.width();
+   ossim_uint32 h = rect.height();
+   
+   if(w & 1)
+   {
+      ++w;
+   }
+   if(h&1)
+   {
+      ++h;
+   }
+
+   tempRequest = ossimIrect(rect.ul().x,
+                            rect.ul().y,
+                            rect.ul().x + (w-1),
+                            rect.ul().y + (h-1));
+   
+   ossimRefPtr<ossimImageData> input;
+   input  = theScalarRemapper->getTile(tempRequest, resLevel);
+
+   if(!input.valid()) return input;
+   
+   if(!theTile.valid()) initialize();
+   if(!theTile.valid()) return theTile;
+   
+   theTile->setImageRectangle(rect);
+   ossimRefPtr<ossimImageData> tempTile = theTile;
+   
+   if(!input->getBuf())
+   {
+      return theTile;
+   }
+
+   if(rect != tempRequest)
+   {
+      tempTile = (ossimImageData*)theTile->dup();
+      tempTile->setImageRectangle(tempRequest);
+   }
+
+   runFft((ossim_float64)0, input, tempTile);
+          
+   if(tempTile != theTile)
+   {
+      theTile->loadTile(tempTile.get());
+   }
+   
+   theTile->validate();
+
+   return theTile;
+}
+
+void ossimFftFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   theTile = ossimImageDataFactory::instance()->create(this, this);
+   
+   if(theTile.valid())
+   {
+      theTile->initialize();
+   }
+   if(theDirectionType == ossimFftFilterDirectionType_FORWARD)
+   {
+      theScalarRemapper->setOutputScalarType(OSSIM_NORMALIZED_DOUBLE);
+   }
+   else
+   {
+      theScalarRemapper->setOutputScalarType(OSSIM_DOUBLE);
+   }
+   theScalarRemapper->connectMyInputTo(0, getInput());
+}
+
+ossimScalarType ossimFftFilter::getOutputScalarType() const
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getOutputScalarType();
+   }
+   
+   if(theDirectionType == ossimFftFilterDirectionType_FORWARD)
+   {
+      return OSSIM_DOUBLE;
+   }
+   
+   return OSSIM_NORMALIZED_DOUBLE;
+}
+
+double ossimFftFilter::getNullPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getNullPixelValue(band);
+   }
+   if(theDirectionType == ossimFftFilterDirectionType_FORWARD)
+   {
+      return OSSIM_DBL_NAN;
+   }
+
+   // it will invert to a normalized float output
+   return 0.0;
+}
+
+double ossimFftFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getMinPixelValue(band);
+   }
+   if(theDirectionType == ossimFftFilterDirectionType_FORWARD)
+   {
+      return OSSIM_DEFAULT_MIN_PIX_DOUBLE;
+   }
+   return OSSIM_DEFAULT_MIN_PIX_NORM_DOUBLE;
+}
+
+double ossimFftFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getMaxPixelValue(band);
+   }
+   if(theDirectionType == ossimFftFilterDirectionType_FORWARD)
+   {
+      return OSSIM_DEFAULT_MAX_PIX_DOUBLE;
+   }
+   return OSSIM_DEFAULT_MAX_PIX_NORM_DOUBLE;
+}
+
+ossim_uint32 ossimFftFilter::getNumberOfOutputBands() const
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getNumberOfOutputBands();
+   }
+   ossim_uint32 bands = ossimImageSourceFilter::getNumberOfOutputBands();
+   
+   if(theDirectionType == ossimFftFilterDirectionType_FORWARD)
+   {
+      bands *=2;
+   }
+   else 
+   {
+      bands /=2;
+   }
+
+   return bands;
+}
+
+void ossimFftFilter::setForward()
+{
+   theDirectionType = ossimFftFilterDirectionType_FORWARD;
+}
+
+void ossimFftFilter::setInverse()
+{
+   theDirectionType = ossimFftFilterDirectionType_INVERSE;
+}
+
+ossimString ossimFftFilter::getDirectionTypeAsString()const
+{
+   if(theDirectionType == ossimFftFilterDirectionType_FORWARD)
+   {
+      return "Forward";
+   }
+
+   return "Inverse";
+}
+
+void ossimFftFilter::setDirectionType(const ossimString& directionType)
+{
+   ossimString tempDirectionType = directionType;
+   tempDirectionType = tempDirectionType.downcase();
+   
+   if(tempDirectionType.contains("forward"))
+   {
+      setDirectionType(ossimFftFilterDirectionType_FORWARD);
+   }
+   else
+   {
+      setDirectionType(ossimFftFilterDirectionType_INVERSE);
+   }
+}
+
+void ossimFftFilter::setDirectionType(ossimFftFilterDirectionType directionType)
+{
+   theDirectionType = directionType;
+   if(theTile.valid())
+   {
+      theTile = NULL;
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimFftFilter::getProperty(const ossimString& name)const
+{
+   if(name == "FFT Direction")
+   {
+      std::vector<ossimString> filterNames;
+      filterNames.push_back("Forward");
+      filterNames.push_back("Inverse");
+      ossimStringProperty* stringProp = new ossimStringProperty("FFT Direction",
+								getDirectionTypeAsString(),
+								false,
+								filterNames);
+      stringProp->setCacheRefreshBit();
+
+      return stringProp;
+   }
+
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimFftFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property) return;
+   
+   if(property->getName() == "FFT Direction")
+   {
+      if(theTile.valid())
+      {
+         theTile = NULL;
+      }
+      setDirectionType(property->valueToString());
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+void ossimFftFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   propertyNames.push_back("FFT Direction");
+}
+
+
+template <class T>
+void ossimFftFilter::runFft(T dummy,
+                            ossimRefPtr<ossimImageData>& input,
+                            ossimRefPtr<ossimImageData>& output)
+{
+   // T*             inputBand  = 0;
+
+   NEWMAT::Matrix* realIn = new NEWMAT::Matrix(input->getHeight(),
+                                               input->getWidth());
+   NEWMAT::Matrix* imgIn = new NEWMAT::Matrix(input->getHeight(),
+                                              input->getWidth());
+   NEWMAT::Matrix* realOut = new NEWMAT::Matrix(input->getHeight(),
+                                                input->getWidth());
+   NEWMAT::Matrix* imgOut = new NEWMAT::Matrix(input->getHeight(),
+                                               input->getWidth());
+   ossim_uint32 bandIdx = 0;
+   ossim_uint32 w = input->getWidth();
+   ossim_uint32 h = input->getHeight();
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+   if(theDirectionType == ossimFftFilterDirectionType_FORWARD)
+   {
+      ossim_uint32 bands = input->getNumberOfBands();
+      for(bandIdx = 0; bandIdx < bands; ++bandIdx)
+      {
+         ossim_float64* bandReal = 0;
+         ossim_float64* bandImg  = 0;
+         fillMatrixForward((T*)input->getBuf(bandIdx),
+                           (T)input->getNullPix(bandIdx),
+                           *realIn,
+                           *imgIn);
+         NEWMAT::FFT2(*realIn, *imgIn, *realOut, *imgOut);
+         bandReal = (ossim_float64*)output->getBuf(2*bandIdx);
+         bandImg  = (ossim_float64*)output->getBuf(2*bandIdx + 1);
+         if(bandReal&&bandImg)
+         {
+            for(y = 0; y < h; ++y)
+            {
+               for(x = 0; x < w; ++x)
+               {
+                  *bandReal = (ossim_float64)((*realOut)[y][x]);
+                  *bandImg  = (ossim_float64)((*imgOut)[y][x]);
+                  ++bandReal;
+                  ++bandImg;
+               }
+            }
+         }
+      }
+   }
+   else
+   {
+      ossim_float64* bandReal = 0;
+      ossim_uint32 bands = input->getNumberOfBands();
+      for(bandIdx = 0; bandIdx < bands; bandIdx+=2)
+      {
+         bandReal = (ossim_float64*)output->getBuf(bandIdx/2);
+         if(input->getBuf(bandIdx)&&
+            input->getBuf(bandIdx+1))
+         {
+            fillMatrixInverse((T*)input->getBuf(bandIdx),
+                              (T*)input->getBuf(bandIdx+1),
+                              *realIn,
+                              *imgIn);
+            NEWMAT::FFT2I(*realIn, *imgIn, *realOut, *imgOut);
+            for(y = 0; y < h; ++y)
+            {
+               for(x = 0; x < w; ++x)
+               {
+                  *bandReal = (ossim_float64)((*realOut)[y][x]);
+                  if(*bandReal > 1.0)
+                  {
+                     *bandReal = 1.0;
+               }
+                  if(*bandReal < 0.0)
+                  {
+                     *bandReal = 0.0;
+                  }
+                  ++bandReal;
+               }
+            }
+         }
+      }
+   }
+   
+   delete realIn;
+   delete imgIn;
+   delete realOut;
+   delete imgOut;
+}
+
+template <class T>
+void ossimFftFilter::fillMatrixForward(T *realPart,
+                                       T nullPix,
+                                       NEWMAT::Matrix& real,
+                                       NEWMAT::Matrix& img)const
+{
+   ossim_uint32 w = real.Ncols();
+   ossim_uint32 h = real.Nrows();
+   ossim_uint32 yIdx = 0;
+   ossim_uint32 xIdx = 0;
+   
+   for(yIdx = 0; yIdx < h; ++yIdx)
+   {
+      for(xIdx = 0; xIdx < w; ++xIdx)
+      {
+         if((double)(*realPart) != nullPix)
+         {
+            real[yIdx][xIdx] = (double)(*realPart);
+         }
+         else
+         {
+            real[yIdx][xIdx] = 0.0;
+         }
+         
+         img[yIdx][xIdx]  = 0.0;
+         
+         ++realPart;
+      }
+   }
+}
+
+template <class T>
+void ossimFftFilter::fillMatrixInverse(T *realPart,
+                                       T *imgPart,
+                                       NEWMAT::Matrix& real,
+                                       NEWMAT::Matrix& img)const
+{
+   ossim_uint32 w = real.Ncols();
+   ossim_uint32 h = real.Nrows();
+   ossim_uint32 yIdx = 0;
+   ossim_uint32 xIdx = 0;
+   
+   for(yIdx = 0; yIdx < h; ++yIdx)
+   {
+      for(xIdx = 0; xIdx < w; ++xIdx)
+      {
+         real[yIdx][xIdx] = (double)(*realPart);
+         img[yIdx][xIdx]  = (double)(*imgPart);
+         
+         ++realPart;
+         ++imgPart;
+      }
+   }
+}
+
+
+bool ossimFftFilter::loadState(const ossimKeywordlist& kwl,
+                               const char* prefix)
+{
+   const char* direction = kwl.find(prefix, "fft_direction");
+   if(direction)
+   {
+      setDirectionType(ossimString(direction));
+   }
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimFftFilter::saveState(ossimKeywordlist& kwl,
+                               const char* prefix)const
+{
+   kwl.add(prefix,
+           "fft_direction",
+           getDirectionTypeAsString(),
+           true);
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFftFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFftFilter.h
new file mode 100644
index 0000000000..006f591004
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFftFilter.h
@@ -0,0 +1,86 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimFftFilter.h,v 1.3 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimFftFilter_HEADER
+#define ossimFftFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimScalarRemapper;
+
+class ossimFftFilter : public ossimImageSourceFilter
+{
+public:
+   enum ossimFftFilterDirectionType
+      {
+         ossimFftFilterDirectionType_FORWARD = 0,
+         ossimFftFilterDirectionType_INVERSE
+      };
+   ossimFftFilter(ossimObject* owner=NULL);
+   ossimFftFilter(ossimImageSource* inputSource);
+   ossimFftFilter(ossimObject* owner,
+                  ossimImageSource* inputSource);
+   virtual ~ossimFftFilter();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                   ossim_uint32 resLevel=0);
+   virtual void initialize();
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+  /*!
+   * Returns the max pixel of the band.
+   */
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+  /*!
+   * Each band has a null pixel associated with it.  The null pixel 
+   * represents an invalid value.
+   */ 
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   
+   virtual ossimScalarType ossimFftFilter::getOutputScalarType() const;
+   
+   void setForward();
+   void setInverse();
+   ossimString getDirectionTypeAsString()const;
+   void setDirectionType(const ossimString& directionType);
+   void setDirectionType(ossimFftFilterDirectionType directionType);
+      
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = 0);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = 0)const;
+protected:
+   ossimRefPtr<ossimImageData> theTile;
+   ossimFftFilterDirectionType theDirectionType;
+   ossimScalarRemapper*        theScalarRemapper;
+   template <class T>
+   void runFft(T dummy,
+               ossimRefPtr<ossimImageData>& input,
+               ossimRefPtr<ossimImageData>& output);
+
+   template <class T>
+   void fillMatrixForward(T *realPart,
+                          T nullPix,
+                          NEWMAT::Matrix& real,
+                          NEWMAT::Matrix& img)const;
+   template <class T>
+   void fillMatrixInverse(T *realPart,
+                          T *imgPart,
+                          NEWMAT::Matrix& real,
+                          NEWMAT::Matrix& img)const;
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFusionCombiner.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFusionCombiner.cpp
new file mode 100644
index 0000000000..ccbabbef9a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFusionCombiner.cpp
@@ -0,0 +1,191 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Garrett Potts
+// 
+// Description: implementation for base fusion
+//
+//*************************************************************************
+// $Id: ossimFusionCombiner.cpp,v 1.10 2005/12/08 21:12:10 dburken Exp $
+
+#include <imaging/tile_sources/ossimFusionCombiner.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+RTTI_DEF1(ossimFusionCombiner, "ossimFusionCombiner", ossimImageCombiner);
+
+ossimFusionCombiner::ossimFusionCombiner()
+  :ossimImageCombiner(NULL, 2, 0, true, false),
+   theTile(NULL),
+   theNormTile(NULL),
+   theNormIntensity(NULL),
+   theInputConnection(NULL),
+   theIntensityConnection(NULL)
+{
+}
+
+ossimFusionCombiner::ossimFusionCombiner(ossimObject* owner)
+  :ossimImageCombiner(owner, 2, 0, true, false),
+   theTile(NULL),
+   theNormTile(NULL),
+   theNormIntensity(NULL),
+   theInputConnection(NULL),
+   theIntensityConnection(NULL)
+{}
+
+ossimFusionCombiner::~ossimFusionCombiner()
+{
+   theInputConnection     = NULL;
+   theIntensityConnection = NULL;
+}
+
+ossimIrect ossimFusionCombiner::getBoundingRect(ossim_uint32 resLevel) const
+{
+  ossimIrect result;
+  result.makeNan();
+  if(theIntensityConnection)
+    {
+      result = theIntensityConnection->getBoundingRect(resLevel);
+    }
+  else if(theInputConnection)
+    {
+      result = theInputConnection->getBoundingRect(resLevel);
+    }
+  
+  return result;
+}
+
+bool ossimFusionCombiner::canConnectMyInputTo(ossim_int32 inputIndex,
+					      const ossimConnectableObject* object)const
+{
+  return ((inputIndex<2)&&
+	  (PTR_CAST(ossimImageSourceInterface, object)||!object));
+}
+
+ossimScalarType ossimFusionCombiner::getOutputScalarType() const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getOutputScalarType();
+   }
+
+   return ossimImageCombiner::getOutputScalarType();
+}
+
+
+ossimRefPtr<ossimImageData> ossimFusionCombiner::getNormIntensity(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   if(theIntensityConnection)
+   {
+      ossimRefPtr<ossimImageData> data =
+         theIntensityConnection->getTile(rect, resLevel);
+      if(data.valid() && data->getBuf())
+      {
+         if(!theNormIntensity.valid())
+         {
+            theNormIntensity = new ossimImageData(this,
+                                                  OSSIM_NORMALIZED_FLOAT,
+                                                  data->getNumberOfBands(),
+                                                  rect.width(),
+                                                  rect.height());
+            theNormIntensity->initialize();
+         }
+
+         theNormIntensity->setImageRectangleAndBands(rect,
+                                                     data->getNumberOfBands());
+
+         data->copyTileToNormalizedBuffer((float*)theNormIntensity->getBuf());
+         theNormIntensity->setDataObjectStatus(data->getDataObjectStatus());
+         return theNormIntensity;
+      }
+   }
+   return ossimRefPtr<ossimImageData>();
+}
+
+ossimRefPtr<ossimImageData> ossimFusionCombiner::getNormTile(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   if(theInputConnection)
+   {
+      ossimRefPtr<ossimImageData> data = theInputConnection->getTile(rect,
+                                                                     resLevel);
+      if(data.valid() && data->getBuf())
+      {
+         // make sure the tile result is updated if changed.
+         //
+         if((data->getNumberOfBands() != theTile->getNumberOfBands())||
+            (data->getScalarType()    != theTile->getScalarType()))
+         {
+            theTile = ossimImageDataFactory::instance()->create(this,
+                                                                theInputConnection);
+            theTile->initialize();
+         }
+
+         if(!theNormTile.valid())
+         {
+            theNormTile = new ossimImageData(this,
+                                             OSSIM_NORMALIZED_FLOAT,
+                                             data->getNumberOfBands(),
+                                             rect.width(),
+                                             rect.height());
+            theNormTile->initialize();
+         }
+         else if(theNormTile->getNumberOfBands() != data->getNumberOfBands())
+         {
+            theNormTile = new ossimImageData(this,
+                                             OSSIM_NORMALIZED_FLOAT,
+                                             data->getNumberOfBands(),
+                                             rect.width(),
+                                             rect.height());
+            theNormTile->initialize();
+            
+         }
+
+         theNormTile->setImageRectangleAndBands(rect,
+                                                data->getNumberOfBands());
+
+         data->copyTileToNormalizedBuffer((float*)theNormTile->getBuf());
+         theNormTile->setDataObjectStatus(data->getDataObjectStatus());
+         return theNormTile;
+      }
+   }
+   return ossimRefPtr<ossimImageData>();
+}
+
+void ossimFusionCombiner::initialize()
+{
+   ossimImageCombiner::initialize();
+   
+   theInputConnection     = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   theIntensityConnection = PTR_CAST(ossimImageSourceInterface, getInput(1));
+
+   if(getInput(0)&&getInput(1))
+   {
+      ossimImageSourceInterface* temp  = PTR_CAST(ossimImageSourceInterface,
+                                                  getInput(0));
+      ossimImageSourceInterface* temp2 = PTR_CAST(ossimImageSourceInterface,
+                                                  getInput(1));
+
+      if(temp&&temp2)
+      {
+         if((temp->getNumberOfOutputBands()==1)&&
+            (temp2->getNumberOfOutputBands()!=1))
+         {
+            theIntensityConnection = PTR_CAST(ossimImageSourceInterface,
+                                              getInput(0));
+            theInputConnection     = PTR_CAST(ossimImageSourceInterface,
+                                              getInput(1));
+         }
+      }
+   }
+   
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,
+                                                          theInputConnection);
+      theTile->initialize();
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFusionCombiner.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFusionCombiner.h
new file mode 100644
index 0000000000..6991c191e5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimFusionCombiner.h
@@ -0,0 +1,47 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: Implementation for Base fusion.
+//              This base class assumes two inputs where the second input is
+//              the intensity source.
+//
+//*************************************************************************
+// $Id: ossimFusionCombiner.h,v 1.7 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimFusionCombiner_HEADER
+#define ossimFusionCombiner_HEADER
+
+#include <imaging/tile_sources/ossimImageCombiner.h>
+
+class OSSIMDLLEXPORT ossimFusionCombiner : public ossimImageCombiner
+{
+public:
+  ossimFusionCombiner();
+  ossimFusionCombiner(ossimObject* owner);
+  virtual ~ossimFusionCombiner();   
+  virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const;
+  bool canConnectMyInputTo(ossim_int32 inputIndex,
+			   const ossimConnectableObject* object)const;
+   ossimScalarType getOutputScalarType() const;
+   
+  virtual void initialize();
+protected:
+  ossimRefPtr<ossimImageData> theTile;
+  ossimRefPtr<ossimImageData> theNormTile;
+  ossimRefPtr<ossimImageData> theNormIntensity;
+  ossimImageSourceInterface*  theInputConnection;
+  ossimImageSourceInterface*  theIntensityConnection;
+  
+  ossimRefPtr<ossimImageData> getNormIntensity(const ossimIrect& rect,
+                                               ossim_uint32 resLevel);
+  ossimRefPtr<ossimImageData> getNormTile(const ossimIrect& rect,
+                                          ossim_uint32 resLevel);
+TYPE_DATA  
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimGeoPolyCutter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimGeoPolyCutter.cpp
new file mode 100644
index 0000000000..c5fa786645
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimGeoPolyCutter.cpp
@@ -0,0 +1,353 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//*************************************************************************
+// $Id: ossimGeoPolyCutter.cpp,v 1.18 2003/12/01 22:11:37 gpotts Exp $
+#include <algorithm>
+#include "ossimGeoPolyCutter.h"
+#include "projections/ossimProjection.h"
+#include "base/common/ossimCommon.h"
+#include "projections/factory/ossimProjectionFactoryRegistry.h"
+
+static const char* NUMBER_POLYGONS_KW = "number_polygons";
+
+RTTI_DEF2(ossimGeoPolyCutter, "ossimGeoPolyCutter", ossimPolyCutter, ossimViewInterface)
+
+ossimGeoPolyCutter::ossimGeoPolyCutter()
+   : ossimPolyCutter(),
+     ossimViewInterface(NULL)
+{
+   ossimViewInterface::theObject = this;
+   theGeoPolygonList.push_back(ossimGeoPolygon());
+   theViewProjection = NULL;
+   theOwnsViewFlag = false;
+}
+
+ossimGeoPolyCutter::~ossimGeoPolyCutter()
+{
+   if(theOwnsViewFlag && theViewProjection)
+   {
+      delete theViewProjection;
+      
+      theViewProjection = NULL;
+      theOwnsViewFlag = false;
+   }
+}
+
+bool ossimGeoPolyCutter::saveState(ossimKeywordlist& kwl,
+                                const char* prefix)const
+{
+    ossimString newPrefix = prefix;
+
+    for(int i = 0; i < (int)thePolygonList.size();++i)
+    {
+       newPrefix = ossimString(prefix) + "geo_polygon" + ossimString::toString(i)+".";
+
+       theGeoPolygonList[i].saveState(kwl, newPrefix.c_str());
+    }
+    kwl.add(prefix,
+            NUMBER_POLYGONS_KW,
+            (int)theGeoPolygonList.size(),
+            true);
+   
+    ossimString fillType = "null_inside";
+    if(theCutType == OSSIM_POLY_NULL_OUTSIDE)
+    {
+       fillType = "null_outside";
+    }
+    kwl.add(prefix,
+            "cut_type",
+            fillType.c_str(),
+            true);   
+
+    if(theViewProjection)
+    {
+       ossimString viewPrefix = prefix;
+       viewPrefix += "view.";
+
+       theViewProjection->saveState(kwl, viewPrefix.c_str());
+    }
+  
+   return ossimImageSourceFilter::saveState(kwl, prefix);;
+}
+
+bool ossimGeoPolyCutter::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   ossimString copyPrefix(prefix);
+   ossimString polygons =  ossimString("^(") + copyPrefix + "geo_polygon[0-9]+.)";
+   vector<ossimString> keys =
+      kwl.getSubstringKeyList( polygons );
+   int offset = (copyPrefix+"geo_polygon").size();
+   
+   std::vector<int> numberList(keys.size());
+   for(int idx = 0; idx < (int)numberList.size();++idx)
+   {
+      ossimString numberStr(keys[idx].begin() + offset,
+                            keys[idx].end());
+      numberList[idx] = numberStr.toInt();
+   }
+   std::sort(numberList.begin(), numberList.end());
+   
+   ossimString newPrefix;
+   thePolygonList.clear();
+   for(int i = 0; i < (int)numberList.size();++i)
+   {
+      theGeoPolygonList.push_back(ossimGeoPolygon());
+      newPrefix = copyPrefix+"geo_polygon"+ossimString::toString(numberList[i])+".";
+      theGeoPolygonList[i].loadState(kwl, newPrefix.c_str());
+   }
+   
+   const char* lookup = kwl.find(prefix,
+                                 "cut_type");
+   if(lookup)
+   {
+      theCutType = OSSIM_POLY_NULL_INSIDE;
+      ossimString test = lookup;
+      if(test == "null_outside")
+      {
+         theCutType = OSSIM_POLY_NULL_OUTSIDE;
+      }
+   }
+   else
+   {
+      theCutType = OSSIM_POLY_NULL_OUTSIDE;
+   }
+
+   ossimString viewPrefix = prefix;
+   viewPrefix += "view.";
+   ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl,
+                                                                                        viewPrefix);
+   if(proj)
+   {
+      if(theViewProjection&&theOwnsViewFlag)
+      {
+         delete theViewProjection;
+      }
+      theViewProjection = proj;
+      theOwnsViewFlag = true;
+   }
+   
+   transformVertices();
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+
+void ossimGeoPolyCutter::setPolygon(const vector<ossimDpt>& polygon,
+                                 ossim_uint32 index)
+{
+   if(theViewProjection)
+   {
+      ossimPolyCutter::setPolygon(polygon);
+      invertPolygon(index);
+   }
+}
+
+void ossimGeoPolyCutter::setPolygon(const vector<ossimIpt>& polygon,
+                                 ossim_uint32 index)
+{
+   if(theViewProjection)
+   {
+      ossimPolyCutter::setPolygon(polygon);
+      invertPolygon(index);
+   }
+}
+
+void ossimGeoPolyCutter::setPolygon(const vector<ossimGpt>& polygon,
+                                    ossim_uint32 i)
+{
+   if(i < theGeoPolygonList.size())
+   {
+      theGeoPolygonList[i] = polygon;
+
+      transformVertices(i);
+   }
+}
+
+void ossimGeoPolyCutter::setPolygon(const ossimGeoPolygon& polygon,
+                                    ossim_uint32 i)
+{
+   if(i < theGeoPolygonList.size())
+   {
+      theGeoPolygonList[i] = polygon.getVertexList();
+
+      transformVertices(i);
+   }
+}
+
+
+void ossimGeoPolyCutter::addPolygon(const vector<ossimGpt>& polygon)
+{
+   theGeoPolygonList.push_back(polygon);
+   thePolygonList.push_back(ossimPolygon());
+
+   if(theViewProjection)
+   {
+      transformVertices(((int)theGeoPolygonList.size())-1);
+   }
+}
+
+void ossimGeoPolyCutter::addPolygon(const vector<ossimIpt>& polygon)
+{
+   if(theViewProjection)
+   {
+      ossimPolyCutter::addPolygon(polygon);
+      theGeoPolygonList.push_back(ossimGeoPolygon());
+      invertPolygon(thePolygonList.size()-1);
+   }
+}
+
+void ossimGeoPolyCutter::addPolygon(const vector<ossimDpt>& polygon)
+{
+   if(theViewProjection)
+   {
+      ossimPolyCutter::addPolygon(polygon);
+      theGeoPolygonList.push_back(ossimGeoPolygon());
+      invertPolygon(thePolygonList.size()-1);
+   }
+}
+
+void ossimGeoPolyCutter::addPolygon(const ossimPolygon& polygon)
+{
+   if(theViewProjection)
+   {
+      ossimPolyCutter::addPolygon(polygon);
+      theGeoPolygonList.push_back(ossimGeoPolygon());
+      invertPolygon(thePolygonList.size()-1);
+   }
+}
+
+void ossimGeoPolyCutter::addPolygon(const ossimGeoPolygon& polygon)
+{
+   ossimPolyCutter::addPolygon(ossimPolygon());
+   theGeoPolygonList.push_back(polygon);
+   
+   if(theViewProjection)
+   {
+      transformVertices(((int)theGeoPolygonList.size())-1);
+   }
+}
+
+void ossimGeoPolyCutter::invertPolygon(int polygonNumber)
+{
+   if(!theViewProjection) return;
+   
+   
+   ossimPolygon& poly      = thePolygonList[polygonNumber];
+   ossimGeoPolygon& gpoly  = theGeoPolygonList[polygonNumber];
+   
+   gpoly.clear();
+   gpoly.resize(poly.getVertexCount());
+   int j = 0;
+   for(j = 0; j < (int)poly.getVertexCount(); ++j)
+   {
+      theViewProjection->lineSampleToWorld(poly[j], gpoly[j]);
+   }
+}
+
+bool ossimGeoPolyCutter::setView(ossimObject* baseObject,
+                                 bool ownsTheView)
+{
+   if(PTR_CAST(ossimProjection, baseObject))
+   {
+      if(theViewProjection && theOwnsViewFlag)
+      {
+         delete theViewProjection;
+      }
+      theViewProjection = PTR_CAST(ossimProjection, baseObject);
+      theOwnsViewFlag   = ownsTheView;
+
+      transformVertices();
+
+      return true;
+   }
+
+   return false;
+}
+
+ossimObject* ossimGeoPolyCutter::getView()
+{
+   return theViewProjection;
+}
+
+const ossimObject* ossimGeoPolyCutter::getView()const
+{
+   return theViewProjection;
+}
+
+void ossimGeoPolyCutter::transformVertices()
+{
+   if(!theViewProjection) return;
+   
+   if(theGeoPolygonList.size())
+   {
+      if(theGeoPolygonList.size() != thePolygonList.size())
+      {
+         thePolygonList.resize(theGeoPolygonList.size());
+      }
+      int i = 0;
+      int j = 0;
+      for(i = 0; i < (int)theGeoPolygonList.size(); ++i)
+      {
+         ossimGeoPolygon& gpoly = theGeoPolygonList[i];
+         ossimPolygon&    poly  = thePolygonList[i];
+         int nvert = (int)gpoly.size();
+         if((int)poly.getVertexCount() != nvert)
+         {
+            poly.resize(nvert);
+         }
+         for(j = 0; j < nvert; ++j)
+         {
+//	   ossimDpt error;
+            theViewProjection->worldToLineSample(gpoly[j], poly[j]);
+//	    theViewProjection->getRoundTripError(ossimIpt(poly[j]), error);
+//	    poly[j] = poly[j] + error;
+            poly[j] = ossimDpt(irint(poly[j].x),
+                               irint(poly[j].y));
+         }
+      }
+      computeBoundingRect();
+   }
+}
+
+void ossimGeoPolyCutter::transformVertices(int i)
+{
+   if(!theViewProjection) return;
+   
+   ossimGeoPolygon& gpoly = theGeoPolygonList[i];
+   ossimPolygon&    poly  = thePolygonList[i];
+   int nvert = (int)gpoly.size();
+   if((int)poly.getVertexCount() != nvert)
+   {
+      poly.resize(nvert);
+   }
+   int j = 0;
+   for(j = 0; j < nvert; ++j)
+   {
+//     ossimDpt error;
+     theViewProjection->worldToLineSample(gpoly[j], poly[j]);
+//     theViewProjection->getRoundTripError(poly[j], error);
+//     poly[j] = poly[j] + error;
+     poly[j] = ossimDpt(irint(poly[j].x),
+			irint(poly[j].y));
+   }
+   
+   computeBoundingRect();
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimGeoPolyCutter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimGeoPolyCutter.h
new file mode 100644
index 0000000000..0e868c64d6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimGeoPolyCutter.h
@@ -0,0 +1,251 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimGeoPolyCutter.h,v 1.6 2006/01/03 20:47:12 gpotts Exp $
+#ifndef ossimGeoPolyCutter_HEADER
+#define ossimGeoPolyCutter_HEADER
+#include "ossimPolyCutter.h"
+#include "base/common/ossimViewInterface.h"
+#include "base/data_types/ossimGeoPolygon.h"
+#include <vector>
+
+class ossimImageData;
+class ossimProjection;
+
+/*!
+ * ossimGeoPolyCutter.
+ *
+ * This classes overrides the 2-d counter part ossimPolyCutter. It will automatically
+ * map 2-D to 3-D (ground) polygons if you add 2-D polygons and will automatically
+ * compute the forward transform when adding a ground polygon.
+ *
+ * you can set the view trough the ossimViewInterface by calling setView(object, true);
+ * it will cast to an ossimProjection and use that as the transformation.  For igen this is
+ * set automatically and does not need to be set by the user.
+ *
+ * This class has no keywords but does use 2 prefix values to store out the view
+ * and the ground polygon for example if we have only one polygon then here is a sample
+ * keyword list for the polygons: NOTE we can have any number of polygons just increment
+ * the geo_polygon0 to geo_polygon1 .. geo_polygonN for the Nth one
+ *
+ * <pre>
+ *
+ * geo_polygon0.datum:  WGE
+ * geo_polygon0.number_vertices:  18
+ * geo_polygon0.type:  ossimGeoPolygon
+ * geo_polygon0.v0:  38.023634368488452 -122.542245818545709 nan
+ * geo_polygon0.v1:  38.016619667868909 -122.548990722987568 nan
+ * geo_polygon0.v2:  38.018238444934966 -122.546292761210807 nan
+ * geo_polygon0.v3:  38.012932453440698 -122.547911538276864 nan
+ * geo_polygon0.v4:  38.014731094625191 -122.542065954427244 nan
+ * geo_polygon0.v5:  38.007446597827986 -122.541796158249582 nan
+ * geo_polygon0.v6:  38.009694899308606 -122.537569351466018 nan
+ * geo_polygon0.v7:  38.005108364288141 -122.537119691169892 nan
+ * geo_polygon0.v8:  38.008255986361007 -122.532353292030976 nan
+ * geo_polygon0.v9:  38.003039926925965 -122.531274107320272 nan
+ * geo_polygon0.v10:  38.013292181677599 -122.529565398195004 nan
+ * geo_polygon0.v11:  38.009874763427050 -122.526867436418243 nan
+ * geo_polygon0.v12:  38.019587425823332 -122.528306349365849 nan
+ * geo_polygon0.v13:  38.023904164666128 -122.537299555288328 nan
+ * geo_polygon0.v14:  38.024983349376825 -122.544584052085540 nan
+ * geo_polygon0.v15:  38.023904164666128 -122.548720926809878 nan
+ * geo_polygon0.v16:  38.022195455540853 -122.562210735693611 nan
+ * geo_polygon0.v17:  38.019317629645663 -122.562930192167400 nan
+ *
+ *
+ * the example for the view information is
+ *
+ * view.central_meridian:  -123.000000000000000
+ * view.datum:  WGE
+ * view.decimal_degrees_per_pixel_lat:  0.000089932059225
+ * view.decimal_degrees_per_pixel_lon:  0.000089932059225
+ * view.ellipse_code:  WE
+ * view.ellipse_name:  WGS 84
+ * view.false_easting:  0.000000000000000
+ * view.false_northing:  0.000000000000000
+ * view.major_axis:  6378137.000000000000000
+ * view.meters_per_pixel_x:  10.000000000000000
+ * view.meters_per_pixel_y:  10.000000000000000
+ * view.minor_axis:  6356752.314199999906123
+ * view.origin_latitude:  0.000000000000000
+ * view.rotation:  0.000000000000000
+ * view.scale_x:  1.000000000000000
+ * view.scale_y:  1.000000000000000
+ * view.tie_point_easting:  0.000000000000000
+ * view.tie_point_lat:  0.000000000000000
+ * view.tie_point_lon:  -123.000000000000000
+ * view.tie_point_northing:  0.000000000000000
+ * view.translation_x:  0.000000000000000
+ * view.translation_y:  0.000000000000000
+ * view.type:  ossimEquDistCylProjection
+ *
+ * </pre> 
+ */
+class OSSIM_DLL ossimGeoPolyCutter : public ossimPolyCutter,
+                                     public ossimViewInterface
+{
+public:
+   ossimGeoPolyCutter();
+   virtual ~ossimGeoPolyCutter();
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /*!
+    * Sets the polygon to the specified polygon index.
+    * /param polygon A vector of points in projected 2-D.
+    * /param i index of the polygon to change.
+    */
+   virtual void setPolygon(const vector<ossimDpt>& polygon,
+                           ossim_uint32 i = 0);
+   
+   /*!
+    * Sets the polygon to the specified polygon index.
+    * /param polygon A vector of points in projected 2-D.
+    * /param i index of the polygon to change.
+    */
+   virtual void setPolygon(const vector<ossimIpt>& polygon,
+                           ossim_uint32 i = 0);
+
+   /*!
+    * Sets the polygon to the specified polygon index.
+    * /param polygon A Ground polygon.
+    * /param i index of the polygon to change.
+    */
+    virtual void setPolygon(const vector<ossimGpt>& polygon,
+                            ossim_uint32 i = 0);
+
+   virtual void setPolygon(const ossimGeoPolygon& polygon,
+                           ossim_uint32 i = 0);
+   /*!
+    * Will invert this polygon out to world space and add it to the
+    * polygon list
+    */
+   virtual void addPolygon(const vector<ossimIpt>& polygon);
+
+   /*!
+    * Will invert the passed in polygon to world space and add to the
+    * polygon list
+    */
+   virtual void addPolygon(const vector<ossimDpt>& polygon);
+
+   /*!
+    * Will add the ground polygon to the list
+    */
+   virtual void addPolygon(const vector<ossimGpt>& polygon);
+
+   /*!
+    * Will invert te polygon to ground and add.
+    */
+   virtual void addPolygon(const ossimPolygon& polygon);
+
+   /*!
+    * Will add the passed in polygon.
+    */
+   virtual void addPolygon(const ossimGeoPolygon& polygon);
+
+   /*!
+    * Will set the number of polygons and will call the base
+    * class set number of polygons.
+    */
+   virtual void setNumberOfPolygons(ossim_uint32 count)
+      {
+         if(!count)
+         {
+            theGeoPolygonList.clear();
+         }
+         else
+         {
+            theGeoPolygonList.resize(count);
+         }
+         ossimPolyCutter::setNumberOfPolygons(count);
+      }
+   /*!
+    * This should only be used for informational uses only.  If updates
+    * are to be made please go through the access methods that change
+    * the polygon data.
+    */
+   virtual std::vector<ossimGeoPolygon>& getGeoPolygonList()
+      {
+         return theGeoPolygonList;
+      }
+   virtual const std::vector<ossimGeoPolygon>& getGeoPolygonList()const
+      {
+         return theGeoPolygonList;
+      }
+
+   /*!
+    * Will set the view to the passed in object.  Once set it will project the
+    * ground polygon relative to the passed in view.
+    */
+   virtual bool setView(ossimObject* baseObject,
+                        bool ownsTheView = false);
+
+   /*!
+    * \return The current view for this object.
+    */
+   virtual ossimObject* getView();
+   
+   /*!
+    * \return The constant pointer to the current view for this object.
+    */
+   virtual const ossimObject* getView()const;
+   
+protected:
+   /*!
+    * The view projection used to project the ground coordinates.
+    */
+   ossimProjection* theViewProjection;
+
+   /*!
+    * Specifies whether the view is owned by this object or not.
+    */
+   bool           theOwnsViewFlag;
+
+   std::vector<ossimGeoPolygon> theGeoPolygonList;
+
+   /*!
+    * Utility method used to invert any passed in projected polygons to
+    * be changed or added to the list.
+    * \param polygonNumber the index of the polygon to invert to ground.
+    */ 
+   void invertPolygon(int polygonNumber);
+
+   /*!
+    * Transforms all vertices based on the current theViewProjection.
+    */
+   void transformVertices();
+
+   /*!
+    * Transforms the specified polygon index.
+    * \param i The polygon index to project.
+    */
+   void transformVertices(int i);
+   
+TYPE_DATA  
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistoMatchRemapper.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistoMatchRemapper.cpp
new file mode 100644
index 0000000000..39adc99724
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistoMatchRemapper.cpp
@@ -0,0 +1,349 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimHistoMatchRemapper.cpp,v 1.11 2005/02/11 15:07:33 dburken Exp $
+#include <imaging/tile_sources/ossimHistoMatchRemapper.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSource.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+ossimHistoMatchRemapper::ossimHistoMatchRemapper()
+   : ossimImageSourceFilter()
+{
+   theBlankTile = NULL;
+}
+
+ossimHistoMatchRemapper::ossimHistoMatchRemapper(ossimImageSource* inputSource,
+                                                 const vector<double>& targetMeanPerBand,
+                                                 const vector<double>& targetSigmaPerBand,
+                                                 const vector<double>& inputMeanPerBand,
+                                                 const vector<double>& inputSigmaPerBand)
+   : ossimImageSourceFilter(inputSource),
+     theTargetMeanPerBand(targetMeanPerBand),
+     theTargetSigmaPerBand(targetSigmaPerBand),
+     theInputMeanPerBand(inputMeanPerBand),
+     theInputSigmaPerBand(inputSigmaPerBand)
+{
+   theBlankTile = NULL;
+}
+
+
+ossimHistoMatchRemapper::~ossimHistoMatchRemapper()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimHistoMatchRemapper::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> tile;
+   if(theInputConnection)
+   {
+      tile = theInputConnection->getTile(tileRect, resLevel);
+   }
+   if(!tile.valid())
+   {
+      return NULL;
+   }
+   if((tile.valid() &&
+       ((tile->getDataObjectStatus()==OSSIM_NULL) ||
+        (tile->getDataObjectStatus()==OSSIM_EMPTY))))
+      
+   {
+      return tile;
+   }
+
+   theBlankTile->setOrigin(tileRect.ul());
+   ossim_uint32 numberOfBands = theInputMeanPerBand.size();
+
+   numberOfBands = numberOfBands>tile->getNumberOfBands()?tile->getNumberOfBands():numberOfBands;
+   double result = 0;
+   if(isSourceEnabled())
+   {
+      long offsetBound = (long)(tile->getWidth()*tile->getHeight());
+      if(tile->getScalarType() == OSSIM_UCHAR)
+      {
+         for(ossim_uint32 band = 0; band < numberOfBands; ++band)
+         {
+            unsigned char* buf = static_cast<unsigned char*>(tile->getBuf(band));
+            for(long offset=0; offset < offsetBound;++offset)
+            {
+               // if the input has no deviation we will just
+               // do a shift to the target mean
+               if(fabs(theInputSigmaPerBand[band]) < FLT_EPSILON)
+               {
+                  result = transLean(buf[offset],
+                                     theInputMeanPerBand[band],
+                                     theTargetMeanPerBand[band],
+                                     0,
+                                     255);
+               }
+               else
+               {
+                  result = transLeanStretch(buf[offset],
+                                            theInputMeanPerBand[band],
+                                            theInputSigmaPerBand[band],
+                                            theTargetMeanPerBand[band],
+                                            theTargetSigmaPerBand[band],
+                                            0,
+                                            255);
+               }
+               result = ((result>255)?255:result);
+               result = ((result<0)?0:result);
+               
+               buf[offset] = (unsigned char)result;
+            }
+         }
+      }
+   }
+
+   return tile;
+}
+
+void ossimHistoMatchRemapper::initialize()
+{
+   if(!theInputConnection)
+   {
+      return;
+   }
+   theBlankTile = new ossimImageData(this,
+                                     theInputConnection->getOutputScalarType(),
+                                     theInputConnection->getNumberOfOutputBands());
+}
+
+const vector<double>& ossimHistoMatchRemapper::getInputMeanValues()const
+{
+   return theInputMeanPerBand;
+}
+
+const vector<double>& ossimHistoMatchRemapper::getInputSigmaValues()const
+{
+   return theInputSigmaPerBand;
+}
+
+const vector<double>& ossimHistoMatchRemapper::getTargetMeanValues()const
+{
+   return theTargetMeanPerBand;
+}
+
+const vector<double>& ossimHistoMatchRemapper::getTargetSigmaValues()const
+{
+   return theTargetSigmaPerBand;
+}
+
+void ossimHistoMatchRemapper::setInputMeanValues(const vector<double>& newValues)
+{
+   theInputMeanPerBand = newValues;
+}
+
+void ossimHistoMatchRemapper::setInputSigmaValues(const vector<double>& newValues)
+{
+   theInputSigmaPerBand = newValues;
+}
+
+void ossimHistoMatchRemapper::setTargetMeanValues(const vector<double>& newValues)
+{
+   theTargetMeanPerBand = newValues;
+}
+
+void ossimHistoMatchRemapper::setTargetSigmaValues(const vector<double>& newValues)
+{
+   theTargetSigmaPerBand = newValues;
+}
+
+double  ossimHistoMatchRemapper::transLean   // returns vOut
+(
+   double vIn         //!< input value to be transformed
+   , double vBias       //!< bias value to be removed
+   , double vTarget     //!< value that will replace bias
+   , double vMin        //!< minimum valid value of vIn (inclusive)
+   , double vMax        //!< maximum valid value of vIn (inclusive)
+)
+{
+   // max change
+   const double vDelta = vTarget - vBias;
+   double weight=0.0;
+   
+   // weight max change dependend on proximity to end points
+   if (vIn <= vBias)
+   {
+      weight = fabs((vIn - vMin) / (vBias - vMin));
+   }
+   else
+   {
+      weight = fabs((vMax - vIn) / (vMax - vBias));
+   }
+   return  (vIn + (vDelta * weight));
+};
+
+double  ossimHistoMatchRemapper::transLeanStretch   // returns vOut
+        (
+          double vIn              //!< input value to be transformed
+        , double vBias            //!< bias value to be removed
+        , double vBiasStretch     //!< dispersion (+/-) about vBias
+        , double vTarget          //!< value that will replace bias
+        , double vTargetStretch   //!< dispersion (+/-) about vTarget
+        , double vMin             //!< minimum valid value of vIn (inclusive)
+        , double vMax             //!< maximum valid value of vIn (inclusive)
+        )
+{
+
+        // line segment end points
+        const double x1 = vMin;
+        const double x2 = vBias - vBiasStretch;
+        const double x3 = vBias + vBiasStretch;
+        const double x4 = vMax;
+        const double y1 = 0.0;
+        const double y2 = (vTarget + vTargetStretch) - (vBias + vBiasStretch);
+        const double y3 = (vTarget - vTargetStretch) - (vBias - vBiasStretch);
+        const double y4 = 0.0;
+
+
+        // perform appropriate linear lookup operation based on input value
+        double vOut = vIn;
+        if (vIn <= x2)
+        {
+                vOut = (vIn - x1) * (y2-y1)/(x2-x1) + y1 + vIn;
+        }
+        else
+        if (vIn <= x3)
+        {
+                vOut = (vIn - x2) * (y3-y2)/(x3-x2) + y2 + vIn;
+        }
+        else
+        {
+                vOut = (vIn - x3) * (y4-y3)/(x4-x3) + y3 + vIn;
+        }
+        
+        return vOut;
+}
+
+bool ossimHistoMatchRemapper::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   theTargetMeanPerBand.clear();
+   theTargetSigmaPerBand.clear();
+   theInputMeanPerBand.clear();
+   theInputSigmaPerBand.clear();
+   long result = kwl.getNumberOfSubstringKeys(ossimString(prefix) + "target_mean[0-9]");
+   ossim_uint32 numberOfMatches=0;
+   long index=0;
+
+   // load target mean
+   while(numberOfMatches < static_cast<ossim_uint32>(result))
+   {
+      ossimString key = prefix;
+      key += ossimString("target_mean");
+      key += ossimString::toString(index);
+      const char* lookup = kwl.find(key.c_str());
+      if(lookup)
+      {
+         theTargetMeanPerBand.push_back(ossimString(lookup).toDouble());
+         ++numberOfMatches;
+      }
+      ++index;
+   }
+   numberOfMatches = 0;
+   index = 0;
+   result = kwl.getNumberOfSubstringKeys(ossimString(prefix) + "target_sigma[0-9]");
+   // load target sigma
+   while(numberOfMatches < static_cast<ossim_uint32>(result))
+   {
+      ossimString key = prefix;
+      key += ossimString("target_sigma");
+      key += ossimString::toString(index);
+      const char* lookup = kwl.find(key.c_str());
+      if(lookup)
+      {
+         theTargetSigmaPerBand.push_back(ossimString(lookup).toDouble());
+         ++numberOfMatches;
+      }
+      ++index;
+   }
+
+   numberOfMatches = 0;
+   index = 0;
+   result = kwl.getNumberOfSubstringKeys(ossimString(prefix) + "input_mean[0-9]");
+   // load input mean
+   while(numberOfMatches < static_cast<ossim_uint32>(result))
+   {
+      ossimString key = prefix;
+      key += ossimString("input_mean");
+      key += ossimString::toString(index);
+      const char* lookup = kwl.find(key.c_str());
+      if(lookup)
+      {
+         theInputMeanPerBand.push_back(ossimString(lookup).toDouble());
+         ++numberOfMatches;
+      }
+      ++index;
+   }
+
+   numberOfMatches = 0;
+   index = 0;
+   result = kwl.getNumberOfSubstringKeys(ossimString(prefix) + "input_sigma[0-9]");
+   // load input sigma
+   while(numberOfMatches < static_cast<ossim_uint32>(result))
+   {
+      ossimString key = prefix;
+      key += ossimString("input_sigma");
+      key += ossimString::toString(index);
+      const char* lookup = kwl.find(key.c_str());
+      if(lookup)
+      {
+         theInputSigmaPerBand.push_back(ossimString(lookup).toDouble());
+         ++numberOfMatches;
+      }
+      ++index;
+   }
+   
+   return true;
+}
+
+bool ossimHistoMatchRemapper::saveState(ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   long index = 1;
+   for(index=1;index <= (long)theTargetMeanPerBand.size();++index)
+   {
+      ossimString key = ossimString("target_mean") + ossimString::toString(index);
+      kwl.add(prefix,
+              key.c_str(),
+              theTargetMeanPerBand[index-1],
+              true);
+   }
+   for(index=1;index <= (long)theTargetSigmaPerBand.size();++index)
+   {
+      ossimString key = ossimString("target_sigma") + ossimString::toString(index);
+      kwl.add(prefix,
+              key.c_str(),
+              theTargetSigmaPerBand[index-1],
+              true);
+   }
+   for(index=1;index <= (long)theInputMeanPerBand.size();++index)
+   {
+      ossimString key = ossimString("input_mean") + ossimString::toString(index);
+      kwl.add(prefix,
+              key.c_str(),
+              theInputMeanPerBand[index-1],
+              true);
+   }
+   for(index=1;index <= (long)theInputSigmaPerBand.size();++index)
+   {
+      ossimString key = ossimString("input_sigma") + ossimString::toString(index);
+      kwl.add(prefix,
+              key.c_str(),
+              theInputSigmaPerBand[index-1],
+              true);
+   }
+   return true;  
+}
+                       
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistoMatchRemapper.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistoMatchRemapper.h
new file mode 100644
index 0000000000..e0270dedf3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistoMatchRemapper.h
@@ -0,0 +1,95 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimHistoMatchRemapper.h,v 1.8 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimHistoMatchRemapper_HEADER
+#define ossimHistoMatchRemapper_HEADER
+#include <vector>
+using namespace std;
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimHistoMatchRemapper: public ossimImageSourceFilter
+{
+public:
+   ossimHistoMatchRemapper();
+   ossimHistoMatchRemapper(ossimImageSource* inputSource,
+                           const vector<double>& targetMeanPerBand  = vector<double>(),
+                           const vector<double>& targetSigmaPerBand = vector<double>(),
+                           const vector<double>& inputMeanPerBand   = vector<double>(),
+                           const vector<double>& inputSigmaPerBand  = vector<double>()
+                           );
+   virtual ~ossimHistoMatchRemapper();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   virtual void initialize();
+   
+   const vector<double>& getInputMeanValues()const;
+   const vector<double>& getInputSigmaValues()const;
+   const vector<double>& getTargetMeanValues()const;
+   const vector<double>& getTargetSigmaValues()const;
+
+   void setInputMeanValues(const vector<double>& newValues);
+   void setInputSigmaValues(const vector<double>& newValues);
+   void setTargetMeanValues(const vector<double>& newValues);
+   void setTargetSigmaValues(const vector<double>& newValues);
+   
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+
+protected:
+   ossimRefPtr<ossimImageData> theBlankTile;
+   
+   vector<double> theTargetMeanPerBand;
+   vector<double> theTargetSigmaPerBand;
+   vector<double> theInputMeanPerBand;
+   vector<double> theInputSigmaPerBand;
+
+   /**
+    * transLean
+    * @param vIn input value to be transformed
+    * @param vBias bias value to be removed
+    * @param vTarget value that will replace bias
+    * @param vMin minimum valid value of vIn (inclusive)
+    * @param vMax maximum valid value of vIn (inclusive)
+    * @return vOut
+    */
+   double transLean(double vIn,
+                    double vBias,
+                    double vTarget,
+                    double vMin,
+                    double vMax);
+
+   /**
+    * transLeanStretch
+    * @param vin Input value to be transformed.
+    * @param vBias Bias value to be removed.
+    * @param vBiasStretch dispersion (+/-) about vBias
+    * @param vTarget value that will replace bias
+    * @param vTargetStretch dispersion (+/-) about vTarget
+    * @param vMin minimum valid value of vIn (inclusive)
+    * @param vMax maximum valid value of vIn (inclusive)
+    * @return vOut
+    */
+   double transLeanStretch(double vIn,
+                           double vBias,
+                           double vBiasStretch,
+                           double vTarget,
+                           double vTargetStretch,
+                           double vMin,
+                           double vMax);
+   
+};
+
+#endif /* #ifndef ossimHistoMatchRemapper_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramEqualization.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramEqualization.cpp
new file mode 100644
index 0000000000..ccf576e8ad
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramEqualization.cpp
@@ -0,0 +1,537 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHistogramEqualization.cpp,v 1.45 2005/09/09 11:14:07 gpotts Exp $
+#include <imaging/tile_sources/ossimHistogramEqualization.h>
+#include <base/data_types/ossimMultiResLevelHistogram.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+#include <base/common/ossimCommon.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimKeyword.h>
+
+RTTI_DEF1(ossimHistogramEqualization, "ossimHistogramEqualization", ossimImageSourceHistogramFilter)
+   
+static const ossimKeyword HISTOGRAM_INVERSE_FLAG_KW("inverse_flag",
+                                                    "specifies whether the inverse should be done for the getTile");
+
+static ossimTrace traceDebug("ossimHistogramEqualization:debug");
+
+ossimHistogramEqualization::ossimHistogramEqualization()
+   : ossimImageSourceHistogramFilter(),
+     theTile(NULL),
+     theAccumulationHistogram(NULL),
+     theInverseFlag(false)
+{
+}
+
+ossimHistogramEqualization::ossimHistogramEqualization(ossimImageSource* inputSource,
+                                                       ossimMultiResLevelHistogram* histogram)
+   : ossimImageSourceHistogramFilter(inputSource, histogram),
+     theTile(NULL),
+     theAccumulationHistogram(NULL),
+     theInverseFlag(false)
+{
+   if(getHistogram())
+   {
+      theAccumulationHistogram = getHistogram()->createAccumulationLessThanEqual();
+      initializeLuts();
+   }
+}
+
+ossimHistogramEqualization::ossimHistogramEqualization(ossimImageSource* inputSource,
+                                                       ossimMultiResLevelHistogram* histogram,
+                                                       bool inverseFlag)
+   : ossimImageSourceHistogramFilter(inputSource, histogram),
+     theTile(NULL),
+     theAccumulationHistogram(NULL),
+     theInverseFlag(inverseFlag)
+{
+   if(getHistogram())
+   {
+      theAccumulationHistogram = getHistogram()->createAccumulationLessThanEqual();
+      initializeLuts();
+   }
+}
+
+ossimHistogramEqualization::~ossimHistogramEqualization()
+{
+   if(theAccumulationHistogram)
+   {
+      delete theAccumulationHistogram;
+      theAccumulationHistogram = NULL;
+   }
+   deleteLuts();
+}
+
+ossimRefPtr<ossimImageData> ossimHistogramEqualization::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;
+   }
+   
+   ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(tileRect,
+                                                                       resLevel);
+
+   if(!inputTile.valid()) return inputTile;
+   
+   if (!isSourceEnabled())
+   {
+      return inputTile;
+   }
+   
+   if(!theTile.valid())
+   {
+      allocate(); // First time through...
+   }
+   
+   // if (!theTile) throw exception!
+   
+   // Set the origin, resize if needed of the output tile.
+   theTile->setImageRectangleAndBands(inputTile->getImageRectangle(),
+				      inputTile->getNumberOfBands());
+   
+   if( !inputTile.valid() ||
+       inputTile->getDataObjectStatus() == OSSIM_NULL ||
+       inputTile->getDataObjectStatus() == OSSIM_EMPTY )
+   {
+      return theTile;
+   }
+
+   if(!theAccumulationHistogram)
+   {
+      computeAccumulationHistogram();
+   }
+   if(theForwardLut.size() == 0 ||
+      theInverseLut.size() == 0)
+   {
+      initializeLuts();
+   }
+   if((theForwardLut.size() == 0) ||
+      (theInverseLut.size() == 0))
+   {
+      return inputTile;
+   }
+   
+   switch(inputTile->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         return runEqualizationAlgorithm(static_cast<ossim_uint8>(0),
+                                         inputTile);
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         return runEqualizationAlgorithm(static_cast<ossim_uint16>(0),
+                                         inputTile);
+      }
+      case OSSIM_SINT16:
+      {
+         return runEqualizationAlgorithm(static_cast<ossim_sint16>(0),
+                                         inputTile);
+      }
+      case OSSIM_UINT32:
+      {
+         return runEqualizationAlgorithm(static_cast<ossim_uint32>(0),
+                                         inputTile);
+      }
+      case OSSIM_SINT32:
+      {
+         return runEqualizationAlgorithm(static_cast<ossim_sint32>(0),
+                                         inputTile);
+      }
+      case OSSIM_FLOAT32:
+      {
+         return runEqualizationAlgorithm(static_cast<ossim_float32>(0),
+                                         inputTile);
+      }
+      case OSSIM_FLOAT64:
+      {
+         return runEqualizationAlgorithm(static_cast<ossim_float64>(0),
+                                         inputTile);
+      }
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHistogramEqualization::getTile WARNING: Unsupported scalar type."
+            << endl;
+         break;
+      }
+   }
+   
+   return inputTile;
+}
+
+void ossimHistogramEqualization::setHistogram(ossimMultiResLevelHistogram* histogram)
+{
+   ossimImageSourceHistogramFilter::setHistogram(histogram);
+   computeAccumulationHistogram();
+   initializeLuts();
+}
+
+bool ossimHistogramEqualization::saveState(ossimKeywordlist& kwl,
+                                           const char* prefix)const
+{
+   bool result = ossimImageSourceHistogramFilter::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           HISTOGRAM_INVERSE_FLAG_KW,
+           (long)theInverseFlag,
+           true);
+   
+   return result;
+}
+
+bool ossimHistogramEqualization::loadState(const ossimKeywordlist& kwl,
+                                           const char* prefix)
+{
+   static const char MODULE[] = "ossimHistogramEqualization::loadState";
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << " Entered..."
+         << "\nprefix:  " << prefix << endl;
+   }
+
+   const char* lookup = kwl.find(prefix,
+                                 HISTOGRAM_INVERSE_FLAG_KW);
+   if(lookup)
+   {
+      theInverseFlag = ossimString(lookup).toBool();
+   }
+   if(ossimImageSourceHistogramFilter::loadState(kwl, prefix))
+   {
+//      computeAccumulationHistogram();
+//      initializeLuts();
+   }
+   else
+   {
+      return false;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG:" << MODULE;
+      this->print(ossimNotify(ossimNotifyLevel_DEBUG));
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\nExited..." << endl;
+   }
+   
+   return true;
+}
+
+void ossimHistogramEqualization::computeAccumulationHistogram()
+{
+   if(theAccumulationHistogram)
+   {
+      delete theAccumulationHistogram;
+      theAccumulationHistogram = NULL;
+   }
+
+   if(getHistogram())
+   {
+      theAccumulationHistogram = getHistogram()->createAccumulationLessThanEqual();
+   }
+}
+
+template <class T>
+ossimRefPtr<ossimImageData> ossimHistogramEqualization::runEqualizationAlgorithm(T, ossimRefPtr<ossimImageData> tile)
+{
+   
+   if(!theAccumulationHistogram ||
+      !getHistogram())
+   {
+      return tile;
+   }
+
+   // for now we will always pull from res 0 information
+   ossimMultiBandHistogram* histo = getHistogram()->getMultiBandHistogram(0);
+
+   if(histo)
+   {
+      ossim_uint32 maxBands = ( (histo->getNumberOfBands() >
+                                 tile->getNumberOfBands())?
+                                tile->getNumberOfBands():
+                                histo->getNumberOfBands());
+      
+      long offsetUpperBound = tile->getHeight()*tile->getWidth();
+
+      for(ossim_uint32 band = 0; band < maxBands; ++band)
+      {
+         ossimHistogram* bandHisto = histo->getHistogram(band);
+         T* buf = static_cast<T*>(tile->getBuf(band));
+         double *histoLut = band<theForwardLut.size()?theForwardLut[band]:NULL;
+         ossim_uint32 actualBand = theBandList[band];
+         if(bandHisto)
+         {
+            if(buf&&histoLut&&(actualBand <  histo->getNumberOfBands()))
+            {
+               if(theInverseFlag)
+               {
+                  histoLut = theInverseLut[actualBand];
+               }
+               if(histoLut)
+               {
+                  if(tile->getDataObjectStatus() == OSSIM_FULL)
+                  {
+                     T minPix = (T)tile->getMinPix(actualBand);
+                     T maxPix = (T)tile->getMaxPix(actualBand);
+                     for(long offset = 0; offset < offsetUpperBound; ++offset)
+                     {
+                        ossim_int32 idx = bandHisto->GetIndex(buf[offset]);
+                           
+                        if(idx>=0)
+                        {
+                           T value = (T)(histoLut[idx]);
+                           buf[offset] = value>maxPix?maxPix:value;
+                           buf[offset] = value<minPix?minPix:value;
+                        }
+                     }
+                  }
+                  else
+                  {
+                     T minPix  = (T)tile->getMinPix(actualBand);
+                     T maxPix  = (T)tile->getMaxPix(actualBand);
+                     T nullPix = (T)tile->getNullPix(actualBand);
+                     for(long offset = 0; offset < offsetUpperBound; ++offset)
+                     {
+                        ossim_int32 idx = bandHisto->GetIndex(buf[offset]);
+                        
+                        if((buf[offset]!=nullPix)&&(idx>=0))
+                        {
+                           T value = (T)(histoLut[idx]);
+                           buf[offset] = value>maxPix?maxPix:value;
+                           buf[offset] = value<minPix?minPix:value;
+                        }
+                        else
+                        {
+                           buf[offset] = nullPix;
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+      
+      tile->validate();
+   }
+   
+   return tile;
+}
+
+void ossimHistogramEqualization::initialize()
+{
+   // Base class will recapture "theInputConnection".
+   ossimImageSourceHistogramFilter::initialize();
+   if(theTile.valid())
+   {
+      theTile = NULL;
+   }
+}
+
+void ossimHistogramEqualization::allocate()
+{
+   theBandList.clear();
+   
+   if(theTile.valid())
+   {
+      theTile = NULL;
+   }
+   
+   if(theInputConnection)
+   {
+      theInputConnection->getOutputBandList(theBandList);
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+      if(theTile.valid())
+      {
+         theTile->initialize();
+      }
+   }
+}
+
+void ossimHistogramEqualization::initializeLuts()
+{
+   if(theForwardLut.size() != 0 ||
+      theInverseLut.size() != 0)
+   {
+      deleteLuts();
+   }
+   if(!theAccumulationHistogram||!getHistogram())
+   {
+      return;
+   }
+   ossimMultiBandHistogram* accumHisto = theAccumulationHistogram->getMultiBandHistogram(0);
+   ossimMultiBandHistogram* histogram  = getHistogram()->getMultiBandHistogram(0);
+   ossimKeywordlist kwl;
+   theAccumulationHistogram->saveState(kwl);
+
+   if(accumHisto&&histogram)
+   {
+      long maxBands = accumHisto->getNumberOfBands();
+      
+      for(long band = 0; band < maxBands; ++band)
+      {
+         // first we grab pointers to the histogram and the accumulation
+         // histogram
+         ossimHistogram* h  = accumHisto->getHistogram(band);
+         ossimHistogram* h2 = histogram->getHistogram(band);
+
+         if(h&&h2)
+         {
+            // lets get the number of indices.
+            ossim_uint32 numberOfIndices = (ossim_uint32)h2->GetRes();
+            vector<double> countForInverse(numberOfIndices);
+            
+            theForwardLut.push_back(new double[numberOfIndices]);
+            theInverseLut.push_back(new double[numberOfIndices]);
+            
+            // let's grab the counts array
+            const float* histoCounts = h->GetCounts();
+
+//         double maxIntensity      = h2->GetMaxVal();
+            double maxIntensity      = h2->GetRangeMax();
+            double maxCount          = h->GetMaxCount();
+            
+            // now pre compute the transforms
+            double *forwardLut = theForwardLut[band];
+            double *inverseLut = theInverseLut[band];
+            
+//         double minIntensity  = h2->GetMinVal();
+            double minIntensity  = h2->GetRangeMin();
+            double delta = maxIntensity-minIntensity;
+            ossim_uint32 idx = 0;
+            
+            // clear out the inverse
+            //
+            for(idx = 0; idx < numberOfIndices; ++ idx)
+            {
+               inverseLut[idx] = OSSIM_DBL_NAN;
+            }
+            for(idx = 0; idx < numberOfIndices; ++ idx)
+            {
+               forwardLut[idx]   = minIntensity + (histoCounts[idx]/maxCount)*delta;
+               
+               ossim_int32 inverseIdx = h2->GetIndex(forwardLut[idx]);
+               if(inverseIdx >= 0)
+               {
+                  inverseLut[inverseIdx]   = minIntensity + delta*(idx/(ossim_float32)numberOfIndices);
+               }
+            }
+            
+            // now solve the inverse lut
+            //
+            ossim_uint32 idxStart = 0;
+            ossim_uint32 idxEnd = 0;
+            
+            while((inverseLut[idxEnd] == OSSIM_DBL_NAN)&&(idxEnd <numberOfIndices)){ ++idxEnd;}
+            if((idxStart!=idxEnd)&&(idxEnd<numberOfIndices))
+            {
+               std::fill(inverseLut,
+                         inverseLut+idxEnd,
+                         inverseLut[idxEnd]);
+            }
+            idxStart = numberOfIndices-1;
+            while((inverseLut[idxStart] == OSSIM_DBL_NAN)&&(idxStart > 0)){ --idxStart;}
+            if(idxStart !=0)
+            {
+               std::fill(inverseLut+idxStart,
+                         inverseLut+numberOfIndices,
+                         inverseLut[idxStart]);
+            }
+            
+            idxStart = 0;
+            idxEnd   = 0;
+            ossim_float32 valueStart = 0.0;
+            ossim_float32 valueEnd = 0.0;
+            
+            while(idxStart < numberOfIndices)
+            {
+               idxEnd = idxStart;
+               if(inverseLut[idxStart] == OSSIM_DBL_NAN)
+               {
+                  while((inverseLut[idxEnd] == OSSIM_DBL_NAN)&&(idxEnd < (numberOfIndices-1))) ++idxEnd;
+                  double length = (idxEnd-idxStart)+1;
+                  valueEnd = inverseLut[idxEnd];
+                  double deltaVal = (valueEnd-valueStart);
+                  ossim_uint32 tempIdx = idxStart;
+                  ossim_float32 count = 1.0;
+                  double t = 0.0;
+                  while(tempIdx < idxEnd)
+                  {
+                     t = (count/length);
+                     t = t>1.0?1.0:t;
+                     inverseLut[tempIdx] = valueStart + deltaVal*t;
+                     ++count;
+                     ++tempIdx;
+                  }
+                  idxStart = idxEnd;
+                  valueStart = valueEnd;
+               }
+               else
+               {
+                  valueStart = inverseLut[idxStart];
+                  ++idxStart;
+               }
+            }
+         }
+      }
+   }
+}
+
+bool ossimHistogramEqualization::setHistogram(const ossimFilename& filename)
+{
+   return ossimImageSourceHistogramFilter::setHistogram(filename);
+}
+
+bool ossimHistogramEqualization::getInverseFlag()const
+{
+   return theInverseFlag;
+}
+
+void ossimHistogramEqualization::setInverseFlag(bool inverseFlag)
+{
+   theInverseFlag = inverseFlag;
+}
+
+void ossimHistogramEqualization::deleteLuts()
+{
+   long band = 0;
+   
+   for(band = 0; band < (long)theForwardLut.size(); ++band)
+   {
+      delete [] theForwardLut[band];
+   }
+   theForwardLut.clear();
+   
+   for(band = 0; band < (long)theInverseLut.size(); ++band)
+   {
+      delete [] theInverseLut[band];      
+   }
+   
+   theInverseLut.clear();
+}
+
+const ossimFilename& ossimImageSourceHistogramFilter::getHistogramFilename() const
+{
+   return theFilename;
+}
+
+std::ostream& ossimHistogramEqualization::print(std::ostream& out) const
+{
+   // Base class...
+   return ossimImageSourceHistogramFilter::print(out);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramEqualization.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramEqualization.h
new file mode 100644
index 0000000000..ce10c69677
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramEqualization.h
@@ -0,0 +1,99 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHistogramEqualization.h,v 1.19 2005/09/02 13:31:24 gpotts Exp $
+#ifndef ossimHistogramEqualization_HEADER
+#define ossimHistogramEqualization_HEADER
+#include <imaging/tile_sources/ossimImageSourceHistogramFilter.h>
+
+class OSSIMDLLEXPORT ossimHistogramEqualization : public ossimImageSourceHistogramFilter
+{
+public:
+   ossimHistogramEqualization();
+   ossimHistogramEqualization(ossimImageSource* inputSource,
+                              ossimMultiResLevelHistogram* histogram);
+   ossimHistogramEqualization(ossimImageSource* inputSource,
+                              ossimMultiResLevelHistogram* histogram,
+                              bool inverseFlag);
+   virtual ~ossimHistogramEqualization();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual void setHistogram(ossimMultiResLevelHistogram* histogram);
+   virtual bool setHistogram(const ossimFilename& filename);
+
+   virtual bool getInverseFlag()const;
+   virtual void initialize();
+   virtual void setInverseFlag(bool inverseFlag);
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+
+   virtual std::ostream& print(std::ostream& out) const;
+
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+   
+  ossimRefPtr<ossimImageData> theTile;
+   /*!
+    * This will be used in some of the histogram
+    * based operations.
+    */
+   ossimMultiResLevelHistogram* theAccumulationHistogram;
+
+   /*!
+    * Indicates if you should equalize or unequalize an input stream.
+    * If the inverse flag is true then it will indicate that we should
+    * assume that the input stream is already equalized and we should
+    * invert based on the current accumulation histogram.
+    *
+    *
+    * This flag is defaulted to false.
+    */
+   bool                         theInverseFlag;
+   /*!
+    * We will create a LUT for each band that directly maps
+    * an input value to an equalized output.
+    */
+   vector<double*> theForwardLut;
+   
+   /*!
+    * We will create a LUT for each band that directly maps
+    * an input value to an un-equalized output.
+    */
+   vector<double*> theInverseLut;
+
+   
+  std::vector<ossim_uint32> theBandList;
+   virtual void computeAccumulationHistogram();
+
+  template<class T>
+  ossimRefPtr<ossimImageData> runEqualizationAlgorithm(T dummyVariable,
+                                                       ossimRefPtr<ossimImageData> tile);
+
+   /*!
+    * We will pre-compute the luts for the forward and inverse
+    * equalization.  Note: the inverse is a little more tricky
+    * and since we must fill the empty spots missed by the
+    * inverse.  We use a linear interpolation between valid
+    * values for this.
+    */
+   virtual void initializeLuts();
+   virtual void deleteLuts();
+
+TYPE_DATA
+};
+#endif /* #ifndef ossimHistogramEqualization_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramMatchFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramMatchFilter.cpp
new file mode 100644
index 0000000000..6e81b0e8c7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramMatchFilter.cpp
@@ -0,0 +1,248 @@
+#include "ossimHistogramMatchFilter.h"
+#include <base/property/ossimFilenameProperty.h>
+#include <base/property/ossimBooleanProperty.h>
+
+RTTI_DEF1(ossimHistogramMatchFilter, "ossimHistogramMatchFilter", ossimImageSourceFilter);
+ossimHistogramMatchFilter::ossimHistogramMatchFilter()
+   :ossimImageSourceFilter(),
+    theAutoLoadInputHistogramFlag(false)
+{
+   theInputHistogramEqualizer = new ossimHistogramEqualization;
+   theTargetHistogramEqualizer = new ossimHistogramEqualization;
+
+   theInputHistogramEqualizer->setInverseFlag(false);
+   theTargetHistogramEqualizer->setInverseFlag(true);
+   theTargetHistogramEqualizer->connectMyInputTo(0, theInputHistogramEqualizer.get());
+}
+
+ossimRefPtr<ossimImageData> ossimHistogramMatchFilter::getTile(const ossimIrect& tileRect,
+                                                               ossim_uint32 resLevel)
+{
+   if(isSourceEnabled())
+   {
+      return theTargetHistogramEqualizer->getTile(tileRect, resLevel);
+   }
+   if(theAutoLoadInputHistogramFlag&&
+      (theInputHistogramFilename==""))
+   {
+      autoLoadInputHistogram();
+   }
+   if(theInputConnection)
+   {
+      return theInputConnection->getTile(tileRect, resLevel);
+   }
+
+   return 0;
+}
+
+
+void ossimHistogramMatchFilter::setInputHistogram(const ossimFilename& inputHistogram)
+{
+   theInputHistogramFilename = inputHistogram;
+   theInputHistogramEqualizer->setHistogram(inputHistogram);
+   theInputHistogramEqualizer->initialize();
+}
+
+void ossimHistogramMatchFilter::setTargetHistogram(const ossimFilename& targetHistogram)
+{
+   theTargetHistogramFilename = targetHistogram;
+   theTargetHistogramEqualizer->setHistogram(targetHistogram);
+   theTargetHistogramEqualizer->initialize();
+}
+
+void ossimHistogramMatchFilter::connectInputEvent(ossimConnectionEvent& event)
+{
+   ossimImageSourceFilter::connectInputEvent(event);
+   if(getInput())
+   {
+      theInputHistogramEqualizer->connectMyInputTo(0, getInput());
+      theInputHistogramEqualizer->initialize();
+      theTargetHistogramEqualizer->initialize();
+   }
+   else
+   {
+      theInputHistogramEqualizer->disconnectMyInput(0, false, false);
+      theInputHistogramEqualizer->initialize();
+      theTargetHistogramEqualizer->initialize();
+   }
+}
+
+void ossimHistogramMatchFilter::disconnectInputEvent(ossimConnectionEvent& event)
+{
+   ossimImageSourceFilter::disconnectInputEvent(event);
+   if(getInput())
+   {
+      theInputHistogramEqualizer->connectMyInputTo(0, getInput());
+      theInputHistogramEqualizer->initialize();
+      theTargetHistogramEqualizer->initialize();
+   }
+   else
+   {
+      theInputHistogramEqualizer->disconnectMyInput(0, false, false);
+      theInputHistogramEqualizer->initialize();
+      theTargetHistogramEqualizer->initialize();
+   }
+}
+
+void ossimHistogramMatchFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+   if(theAutoLoadInputHistogramFlag)
+   {
+      if(theInputHistogramFilename == "")
+      {
+         autoLoadInputHistogram();
+      }
+   }
+
+   theInputHistogramEqualizer->initialize();
+   theTargetHistogramEqualizer->initialize();
+}
+
+void ossimHistogramMatchFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property.valid()) return;
+   
+   ossimString name = property->getName();
+   if(name == "input_histogram_filename")
+   {
+      setInputHistogram(ossimFilename(property->valueToString()));
+      return;
+   }
+   else if(name == "target_histogram_filename")
+   {
+      setTargetHistogram(ossimFilename(property->valueToString()));
+      return;
+   }
+   else if(name == "auto_load_input_histogram_flag")
+   {
+      theAutoLoadInputHistogramFlag = property->valueToString().toBool();
+      if(theAutoLoadInputHistogramFlag)
+      {
+         initialize();
+      }
+      return;
+   }
+   ossimImageSourceFilter::setProperty(property);
+}
+
+ossimRefPtr<ossimProperty> ossimHistogramMatchFilter::getProperty(const ossimString& name)const
+{
+   if(name == "input_histogram_filename")
+   {
+      ossimFilenameProperty* filenameProp =
+         new ossimFilenameProperty(name, theInputHistogramFilename);
+      
+      filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      filenameProp->setCacheRefreshBit();
+      return filenameProp;
+   }
+   else if(name == "target_histogram_filename")
+   {
+      ossimFilenameProperty* filenameProp =
+         new ossimFilenameProperty(name, theTargetHistogramFilename);
+      
+      filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      filenameProp->setCacheRefreshBit();
+
+      return filenameProp;
+   }
+   if(name == "auto_load_input_histogram_flag")
+   {
+      ossimBooleanProperty* boolProp = new ossimBooleanProperty(name,
+                                                                theAutoLoadInputHistogramFlag);
+      boolProp->setCacheRefreshBit();
+      return boolProp;
+   }
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimHistogramMatchFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   
+   propertyNames.push_back("auto_load_input_histogram_flag");
+   propertyNames.push_back("input_histogram_filename");
+   propertyNames.push_back("target_histogram_filename");
+}
+
+bool ossimHistogramMatchFilter::loadState(const ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   const char* inputFilename     = kwl.find(prefix, "input_histogram_filename");
+   const char* targetFilename    = kwl.find(prefix, "target_histogram_filename");
+   const char* autoLoadInputFlag = kwl.find(prefix, "auto_load_input_histogram_flag");
+
+   if(autoLoadInputFlag)
+   {
+      theAutoLoadInputHistogramFlag = ossimString(autoLoadInputFlag).toBool();
+   }
+   
+   if(inputFilename&&!theAutoLoadInputHistogramFlag)
+   {
+      setInputHistogram(ossimFilename(inputFilename));
+   }
+   else
+   {
+      setInputHistogram(ossimFilename(""));
+   }
+
+   if(targetFilename)
+   {
+      setTargetHistogram(ossimFilename(targetFilename));
+   }
+   else
+   {
+      setTargetHistogram(ossimFilename(""));
+   }
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimHistogramMatchFilter::saveState(ossimKeywordlist& kwl,
+                                          const char* prefix)const
+{
+   if(theAutoLoadInputHistogramFlag)
+   {
+      kwl.add(prefix,
+              "input_histogram_filename",
+              "",
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              "input_histogram_filename",
+              theInputHistogramFilename.c_str(),
+              true);
+   }
+   kwl.add(prefix,
+           "target_histogram_filename",
+           theTargetHistogramFilename.c_str(),
+           true);
+   kwl.add(prefix,
+           "auto_load_input_histogram_flag",
+           theAutoLoadInputHistogramFlag,
+           true);
+   
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+void ossimHistogramMatchFilter::autoLoadInputHistogram()
+{
+   ossimConnectableObject* obj = findObjectOfType("ossimImageHandler",
+                                                  CONNECTABLE_DIRECTION_INPUT);
+   if(obj)
+   {
+      ossimRefPtr<ossimProperty> prop = obj->getProperty("histogram_filename");
+      if(prop.valid())
+      {
+         ossimFilename inputHisto = ossimFilename(prop->valueToString());
+         if(inputHisto.exists())
+         {
+            setInputHistogram(inputHisto);
+         }
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramMatchFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramMatchFilter.h
new file mode 100644
index 0000000000..3ccc897b71
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramMatchFilter.h
@@ -0,0 +1,173 @@
+#ifndef ossimHistogramMatchFilter_HEADER
+#define ossimHistogramMatchFilter_HEADER
+#include "ossimImageSourceFilter.h"
+#include "ossimHistogramEqualization.h"
+
+/**
+ * class ossimHistogramMatchFilter
+ *
+ * <pre>
+ *
+ * This class owns two ossimHistogramEqualization filters and will chain them together.  It will
+ * make the left most filter the forward transform by transforming the input input to an equalized
+ * space defined by the input histogram.  The right filter is the target histogram to match.  It will
+ * take the equalized space and invert it to a target histogram.
+ *
+ * There is an auto load input histogram flag that if set true will always try to search for an input handler
+ * and get the input handlers histogram file. and set it.  If this is enabled then the only other field that
+ * is required is to specify the target histogram.  If a target histogram is not specified then the output
+ *
+ * will be an equalized image without the target applied.
+ *
+ * </pre>
+ */ 
+class OSSIM_DLL ossimHistogramMatchFilter : public ossimImageSourceFilter
+{
+public:
+   ossimHistogramMatchFilter();
+
+   /**
+    * Calls the owned equalizers to create a match composite image.
+    *
+    * @return Histogram matched composite image
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   /**
+    * Initializes the input and target equalizer filters.
+    */ 
+   virtual void initialize();
+
+   /**
+    * @param inputHistogram Input histogram to load
+    */ 
+   void setInputHistogram(const ossimFilename& inputHistogram);
+
+   /**
+    * @param targetHistogram Target histogram to match
+    */ 
+   void setTargetHistogram(const ossimFilename& targetHistogram);
+
+   /**
+    * @param event Connection event
+    */ 
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+   
+   /**
+    * @param event Connection event
+    */ 
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+
+   /**
+    * <pre>
+    *
+    * Valid properties are:
+    *
+    * auto_load_input_histogram_flag
+    *                   Is a boolean property and specifes whether or not the input histogram will be auto searched from
+    *                   the conected input source chain.
+    *
+    * input_histogram_filename
+    *                   Holds the input histogram filename
+    *
+    * output_histogram_filename
+    *                   holds the output histogram filename
+    *                   
+    * </pre>
+    * @param property Is the property to set.
+    */
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+
+   /**
+    * Returns a property given the name
+    *
+    * Valid names are:
+    * auto_load_input_histogram_flag
+    * input_histogram_filename
+    * output_histogram_filename
+    *
+    * Example:
+    *
+    * ossimRefPtr<ossimProperty> prop = obj->getProperty("auto_load_input_histogram_flag");
+    *
+    */ 
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+
+   /**
+    * Returns a list of proeprties.
+    *
+    * <pre>
+    *
+    * Valid properties are:
+    *
+    * auto_load_input_histogram_flag
+    *                   Is a boolean property and specifes whether or not the input histogram will be auto searched from
+    *                   the conected input source chain.
+    *
+    * input_histogram_filename
+    *                   Holds the input histogram filename
+    *
+    * output_histogram_filename
+    *                   holds the output histogram filename
+    *                  
+    * </pre>
+    */ 
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   /**
+    *
+    * <pre>
+    * Keywords to search and load:
+    *
+    * auto_load_input_histogram_flag
+    * input_histogram_filename
+    * output_histogram_filename
+    *
+    * </pre>
+    * 
+    * @param kwl  Holds the keywords for this object to load prefixed by the passed in prefix parameter
+    * @param prefix Is the prefix value prepended to all keywords
+    * 
+    * @return True if succesful or flase otherwise
+    * 
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+
+   /**
+    *
+    * <pre>
+    * Keywords:
+    *
+    * auto_load_input_histogram_flag
+    * input_histogram_filename
+    * output_histogram_filename
+    *
+    * </pre>
+    * 
+    * @param kwl  This object will store the keywords in kwl and prefix by the parameter prefix
+    * @param prefix Is the prefix value prepended to all keywords
+    * @return True if succesful or flase otherwise
+    * 
+    */
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+   
+protected:
+   /**
+    * Will search the input chain and get the histogram_filename property of the image handler.
+    * Once retrieved it calls the setInputHistogram with the found histogram filename.  It does nothing
+    * if the histogram filename does not exist
+    * 
+    */
+   void autoLoadInputHistogram();
+   
+   ossimRefPtr<ossimHistogramEqualization> theInputHistogramEqualizer;
+   ossimRefPtr<ossimHistogramEqualization> theTargetHistogramEqualizer;
+   ossimFilename theInputHistogramFilename;
+   ossimFilename theTargetHistogramFilename;
+   bool          theAutoLoadInputHistogramFlag;
+TYPE_DATA   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramRemapper.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramRemapper.cpp
new file mode 100644
index 0000000000..755e6f2f9b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramRemapper.cpp
@@ -0,0 +1,1694 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Histogram remapper class declaration.  Derived from ossimTableRemapper.
+//
+// Remaps a tile based on mode and histogram clip points.
+//
+//*************************************************************************
+// $Id: ossimHistogramRemapper.cpp,v 1.34 2005/09/27 11:03:17 gpotts Exp $
+
+#include <imaging/tile_sources/ossimHistogramRemapper.h>
+#include <base/data_types/ossimMultiResLevelHistogram.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimKeywordNames.h>
+
+RTTI_DEF1(ossimHistogramRemapper, "ossimHistogramRemapper", ossimTableRemapper)
+
+static ossimTrace traceDebug("ossimHistogramRemapper:debug");
+
+static const char* STRETCH_MODE[] = { "linear_one_piece",
+                                      "linear_1std_from_mean",
+                                      "linear_2std_from_mean",
+                                      "linear_3std_from_mean",
+                                      "linear_auto_min_max",
+                                      "stretch_unknown" };
+
+static const char NORMALIZED_LOW_CLIP_POINT_KW[] = "normalized_low_clip_point";
+static const char NORMALIZED_HIGH_CLIP_POINT_KW[]="normalized_high_clip_point";
+static const char MID_POINT_KW[] = "mid_point";
+static const char MIN_OUTPUT_VALUE_KW[] = "min_output_value";
+static const char MAX_OUTPUT_VALUE_KW[] = "max_output_value";
+static const char STRETCH_MODE_KW[] = "stretch_mode";
+static const char HISTOGRAM_FILENAME_KW[] = "histogram_filename";
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimHistogramRemapper.cpp,v 1.34 2005/09/27 11:03:17 gpotts Exp $";
+#endif
+
+ossimHistogramRemapper::ossimHistogramRemapper(ossimObject* owner)
+   :
+      ossimTableRemapper(owner),  // base class
+      theStretchMode(ossimHistogramRemapper::LINEAR_ONE_PIECE),
+      theDirtyFlag(false),
+      theHistogramOwnerFlag(false),
+      theHistogram(NULL),
+      theTableSizeInBytes(0),
+      theNormalizedLowClipPoint(),
+      theNormalizedHighClipPoint(),
+      theMidPoint(),
+      theBandList()
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimHistogramRemapper::ossimHistogramRemapper entered...\n";
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "OSSIM_ID:  " << OSSIM_ID << "\n";
+#endif      
+   }
+
+   disableSource();
+
+   //---
+   // We will control the allocation and deletion of "theTable" so set the
+   // base class ownership flag to false (ossimTableRemapper does not own).
+   //---
+   setTableOwnership(false);
+}
+
+ossimHistogramRemapper::ossimHistogramRemapper(ossimImageSource* inputSource)
+   :
+      ossimTableRemapper(NULL, inputSource),  // base class
+      theStretchMode(ossimHistogramRemapper::LINEAR_ONE_PIECE),
+      theDirtyFlag(false),
+      theHistogramOwnerFlag(false),
+      theHistogram(NULL),
+      theTableSizeInBytes(0),
+      theNormalizedLowClipPoint(),
+      theNormalizedHighClipPoint(),
+      theMidPoint(),
+      theMinOutputValue(),
+      theMaxOutputValue(),
+      theBandList()
+{
+   initializeClips();
+
+   //---
+   // We will control the allocation and deletion of "theTable" so set the
+   // base class ownership flag to false (ossimTableRemapper does not own).
+   //---
+   setTableOwnership(false);   
+}
+
+ossimHistogramRemapper::ossimHistogramRemapper(ossimImageSource* inputSource,
+                                               ossimMultiResLevelHistogram* histogram,
+                                               bool own_histogram,
+                                               ossim_float64 low_clip,
+                                               ossim_float64 high_clip)
+   : 
+      ossimTableRemapper(NULL, inputSource),  // base class
+      theStretchMode(ossimHistogramRemapper::LINEAR_ONE_PIECE),
+      theDirtyFlag(false),
+      theHistogramOwnerFlag(own_histogram),
+      theHistogram(NULL),
+      theTableSizeInBytes(0),
+      theNormalizedLowClipPoint(),
+      theNormalizedHighClipPoint(),
+      theMidPoint(),
+      theMinOutputValue(),
+      theMaxOutputValue(),
+      theBandList()
+{
+   setHistogram(histogram);
+   setLowNormalizedClipPoint(low_clip);
+   setHighNormalizedClipPoint(high_clip);
+
+   if (theDirtyFlag)
+   {
+      // Set the enable flag but let the table to be build on first getTile.
+      enableSource();
+   }
+
+   //---
+   // We will control the allocation and deletion of "theTable" so set the
+   // base class ownership flag to false (ossimTableRemapper does not own).
+   //---
+   setTableOwnership(false);
+}
+
+ossimHistogramRemapper::~ossimHistogramRemapper()
+{
+   if (theHistogram && theHistogramOwnerFlag)
+   {
+      delete theHistogram;
+      theHistogram = NULL;
+   }
+   if (theTable)
+   {
+      delete [] theTable;
+      theTable = NULL;
+   }
+}
+
+void ossimHistogramRemapper::initialize()
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimHistogramRemapper::initialize entered..." << endl;
+   }
+
+   //---
+   // Call the base class initialize.
+   // Note:  This will reset "theInputConnection" if it changed...
+   //---
+   ossimTableRemapper::initialize();
+
+   // Check the band list to see if it's changes.
+   vector<ossim_uint32> bandList;
+   getOutputBandList(bandList);
+
+   if (theBandList.size() != 0 && bandList.size())
+   {
+      if (theBandList.size() != bandList.size())
+      {
+         // Somethings changed.  Set everthing back.
+         initializeClips();
+         setNullCount();
+         if (theTable)
+         {
+            delete [] theTable;
+            theTable = NULL;
+         }
+      }
+      else
+      {
+         // Sizes same check the order.
+         for(ossim_uint32 band = 0; band < theBandList.size(); ++band)
+         {
+            if (theBandList[band] != bandList[band])
+            {
+               initializeClips();
+               setNullCount();
+               break;
+            }            
+         }
+      }
+   }
+
+   // Update the band list with the latest.
+   theBandList = bandList;
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimHistogramRemapper::initialize exited..." << endl;
+   }
+}
+
+void ossimHistogramRemapper::reset()
+{
+   // We could delete theTable to free up memory???
+   initializeClips();
+}
+
+void
+ossimHistogramRemapper::setHistogram(ossimMultiResLevelHistogram* histogram,
+                                     bool own_histogram)
+{
+   if (theHistogram && theHistogramOwnerFlag)
+   {
+      // Clear out all the values.
+      reset();
+      
+      delete theHistogram;
+   }
+   theHistogram = histogram;
+   theHistogramOwnerFlag = own_histogram;
+   setNullCount();
+
+   // Note: initializeClips before setNullCount since it relies on clips.
+   initializeClips();
+
+   if (theTable)
+   {
+      delete [] theTable;
+      theTable = NULL;
+   }
+}
+
+bool ossimHistogramRemapper::openHistogram(const ossimFilename& histogram_file)
+{
+   ossimMultiResLevelHistogram* h = new ossimMultiResLevelHistogram();
+   if (h->importHistogram(histogram_file))
+   {
+      setHistogram(h, true); // True for, "I own it!"
+      return true;
+   }
+
+   // Import failed if here!
+   delete h;
+   return false;
+}
+
+ossimRefPtr<ossimImageData> ossimHistogramRemapper::getTile(
+   const ossimIrect& tile_rect,
+   ossim_uint32 resLevel)
+{
+   if ( theEnableFlag && (theDirtyFlag || !theTable) )
+   {
+      buildTable();
+   }
+
+   return ossimTableRemapper::getTile(tile_rect, resLevel);
+}
+
+void ossimHistogramRemapper::setLowNormalizedClipPoint(const ossim_float64& clip)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      setLowNormalizedClipPoint(clip, band);
+   }
+}
+
+void
+ossimHistogramRemapper::setLowNormalizedClipPoint(const ossim_float64& clip,
+                                                  ossim_uint32 zero_based_band)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+
+   if (zero_based_band >= BANDS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::setLowNormalizedClipPoint ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (BANDS-1) << endl;
+   }
+
+   if (theNormalizedLowClipPoint.size() != BANDS)
+   {
+      initializeClips();
+   }
+
+   if ( clip != theNormalizedLowClipPoint[zero_based_band] &&
+        clip < theNormalizedHighClipPoint[zero_based_band] )
+   {
+      theDirtyFlag = true;
+      theNormalizedLowClipPoint[zero_based_band] = clip;
+   }
+
+   if (theDirtyFlag)
+   {
+      verifyEnabled();
+   }
+}
+
+void
+ossimHistogramRemapper::setHighNormalizedClipPoint(const ossim_float64& clip)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      setHighNormalizedClipPoint(clip, band);
+   }
+}
+
+void ossimHistogramRemapper::setHighNormalizedClipPoint(const ossim_float64& clip, ossim_uint32 zero_based_band)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+
+   if (zero_based_band >= BANDS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::setHighNormalizedClipPoint ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (BANDS-1) << endl;
+   }
+
+   if (theNormalizedHighClipPoint.size() != BANDS)
+   {
+      initializeClips();
+   }
+
+   if ( clip != theNormalizedHighClipPoint[zero_based_band] &&
+        clip > theNormalizedLowClipPoint[zero_based_band] )
+   {
+      theDirtyFlag = true;
+      theNormalizedHighClipPoint[zero_based_band] = clip;
+   }
+
+   if (theDirtyFlag)
+   {
+      verifyEnabled();
+   }
+}
+
+void ossimHistogramRemapper::setLowClipPoint(const ossim_float64& clip)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      setLowClipPoint(clip, band);
+   }
+}
+
+void ossimHistogramRemapper::setLowClipPoint(const ossim_float64& clip,
+                                             ossim_uint32 zero_based_band)
+{
+   if (!theHistogram) return;
+
+   ossimHistogram* h = getHistogram(zero_based_band);
+   if (h)
+   {
+      ossim_float64 d = h->getLowFractionFromValue(clip);
+      if (d != OSSIM_FLT_NAN)
+      {
+         setLowNormalizedClipPoint(d, zero_based_band);
+      }
+   }
+}
+
+void ossimHistogramRemapper::setHighClipPoint(const ossim_float64& clip)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      setHighClipPoint(clip, band);
+   }
+}
+
+void ossimHistogramRemapper::setHighClipPoint(const ossim_float64& clip,
+                                              ossim_uint32 zero_based_band)
+{
+   if (!theHistogram) return;
+
+   ossimHistogram* h = getHistogram(zero_based_band);
+   if (h)
+   {
+      ossim_float64 d = h->getHighFractionFromValue(clip);
+      if (d != OSSIM_FLT_NAN)
+      {
+         d = 1.0-d;
+         setHighNormalizedClipPoint(d, zero_based_band);
+      }
+   }
+}
+
+void ossimHistogramRemapper::setMidPoint(const ossim_float64& value)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      setMidPoint(value, band);
+   }
+}
+
+void ossimHistogramRemapper::setMidPoint(const ossim_float64& value,
+                                         ossim_uint32 zero_based_band)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+
+   if (zero_based_band >= BANDS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::setMidPoint ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (BANDS-1) << endl;
+   }
+
+   if (theMidPoint.size() != BANDS)
+   {
+      initializeClips();
+   }
+
+   if (theMidPoint[zero_based_band] != value)
+   {
+      theDirtyFlag = true;
+      theMidPoint[zero_based_band] = value;
+   }
+
+   if (theDirtyFlag)
+   {
+      verifyEnabled();
+   }
+}
+
+void ossimHistogramRemapper::setMinOutputValue(const ossim_float64& value)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      setMinOutputValue(value, band);
+   }
+}
+
+void ossimHistogramRemapper::setMinOutputValue(const ossim_float64& value,
+                                               ossim_uint32 zero_based_band)
+{
+   if (!theInputConnection)
+   {
+      return;
+   }
+   
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+
+   if (zero_based_band >= BANDS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::setMinOutputValue ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (BANDS-1) << endl;
+   }
+
+   if (theMinOutputValue.size() != BANDS)
+   {
+      initializeClips();
+   }
+
+   if ( value != theMinOutputValue[zero_based_band] &&
+        value >= theInputConnection->getMinPixelValue(zero_based_band) &&
+        value < theMaxOutputValue[zero_based_band] )
+   {
+      theDirtyFlag = true;
+      theMinOutputValue[zero_based_band] = value;
+   }
+
+   if (theDirtyFlag)
+   {
+      verifyEnabled();
+   }
+}
+
+void ossimHistogramRemapper::setMaxOutputValue(const ossim_float64& value)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      setMaxOutputValue(value, band);
+   }
+}
+
+void ossimHistogramRemapper::setMaxOutputValue(const ossim_float64& value,
+                                               ossim_uint32 zero_based_band)
+{
+   if (!theInputConnection)
+   {
+      return;
+   }
+
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   
+   if (zero_based_band >= BANDS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::setMidPoint ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (BANDS-1) << endl;
+   }
+   
+   if (theMaxOutputValue.size() != BANDS)
+   {
+      initializeClips();
+   }
+
+   if ( value != theMaxOutputValue[zero_based_band] &&
+        value <= theInputConnection->getMaxPixelValue(zero_based_band) &&
+        value >  theMinOutputValue[zero_based_band] )
+   {
+      theDirtyFlag = true;
+      theMaxOutputValue[zero_based_band] = value;
+   }
+
+   if (theDirtyFlag)
+   {
+      verifyEnabled();
+   }
+}
+
+ossim_float64 ossimHistogramRemapper::getLowNormalizedClipPoint(ossim_uint32 zero_based_band) const
+{
+   if (theNormalizedLowClipPoint.size() == 0 ||
+       zero_based_band >= getNumberOfInputBands())
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   if (zero_based_band >= theNormalizedLowClipPoint.size())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::getLowNormalizedClipPoint ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (theNormalizedLowClipPoint.size()-1)
+         << endl;
+      return OSSIM_DBL_NAN;
+   }
+
+   return theNormalizedLowClipPoint[zero_based_band];
+}
+
+ossim_float64 ossimHistogramRemapper::getLowNormalizedClipPoint() const
+{
+   if (theNormalizedLowClipPoint.size() == 0)
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   ossim_float64 d = 0.0;
+   const ossim_uint32 BANDS = theNormalizedLowClipPoint.size();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      d += getLowNormalizedClipPoint(band);
+   }
+   
+   return (d / BANDS);
+}
+
+ossim_float64 ossimHistogramRemapper::getHighNormalizedClipPoint(ossim_uint32 zero_based_band) const
+{
+   if (theNormalizedHighClipPoint.size() == 0 ||
+       zero_based_band >= getNumberOfInputBands())
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   if (zero_based_band >= theNormalizedHighClipPoint.size())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::getHighNormalizedClipPoint ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (theNormalizedHighClipPoint.size()-1)
+         << endl;
+      return OSSIM_DBL_NAN;
+   }
+
+   return theNormalizedHighClipPoint[zero_based_band];
+}
+
+ossim_float64 ossimHistogramRemapper::getHighNormalizedClipPoint() const
+{
+   if (theNormalizedHighClipPoint.size() == 0)
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   ossim_float64 d = 0.0;
+   const ossim_uint32 BANDS = theNormalizedHighClipPoint.size();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      d += getHighNormalizedClipPoint(band);
+   }
+   
+   return (d / BANDS);
+}
+
+ossim_float64 ossimHistogramRemapper::getLowClipPoint(ossim_uint32 zero_based_band) const
+{
+   if(zero_based_band >= getNumberOfInputBands() ||
+      !theHistogram || zero_based_band >= theNormalizedLowClipPoint.size())
+   {
+      return OSSIM_DBL_NAN;
+   }
+
+   if (theNormalizedLowClipPoint[zero_based_band] == 0.0)
+   {
+      return getMinPixelValue(zero_based_band);
+   }   
+
+   ossimHistogram* h = getHistogram(zero_based_band);
+   if (h)
+   {
+      ossim_float64 d =
+         h->LowClipVal(theNormalizedLowClipPoint[zero_based_band]);
+         
+      return floor(d);
+   }
+
+   return OSSIM_DBL_NAN;
+}
+
+ossim_float64 ossimHistogramRemapper::getLowClipPoint() const
+{
+   if (theNormalizedLowClipPoint.size() == 0 || !theHistogram)
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   ossim_float64 d = 0.0;
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      d += getLowClipPoint(band);
+   }
+   
+   return (d / BANDS);
+}
+
+ossim_float64 ossimHistogramRemapper::getHighClipPoint(ossim_uint32 zero_based_band) const
+{
+   if(zero_based_band >= getNumberOfInputBands() ||
+      !theHistogram || zero_based_band >= theNormalizedHighClipPoint.size())
+   {
+      return OSSIM_DBL_NAN;
+   }
+
+   if (theNormalizedHighClipPoint[zero_based_band] == 1.0)
+   {
+      return getMaxPixelValue(zero_based_band);
+   }
+
+   ossimHistogram* h = getHistogram(zero_based_band);
+   if (h)
+   {
+      ossim_float64 d =
+         h->HighClipVal(1.0-theNormalizedHighClipPoint[zero_based_band]);
+      return ceil(d);
+   }
+   
+   return OSSIM_DBL_NAN;
+}
+
+ossim_float64 ossimHistogramRemapper::getHighClipPoint() const
+{
+   if (theNormalizedHighClipPoint.size() == 0 || !theHistogram)
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   ossim_float64 d = 0.0;
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      d += getHighClipPoint(band);
+   }
+   
+   return (d / BANDS);
+}
+
+ossim_float64 ossimHistogramRemapper::getMidPoint(ossim_uint32 zero_based_band) const
+{
+   if (theMidPoint.size() == 0 ||
+       zero_based_band >= getNumberOfInputBands())
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   if (zero_based_band >= theMidPoint.size())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::getMidPoint ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (theMidPoint.size()-1)
+         << endl;
+      return OSSIM_DBL_NAN;
+   }
+
+   return theMidPoint[zero_based_band];
+}
+
+ossim_float64 ossimHistogramRemapper::getMidPoint() const
+{
+   if (theMidPoint.size() == 0)
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   ossim_float64 d = 0.0;
+   const ossim_uint32 BANDS = theMidPoint.size();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      d += getMidPoint(band);
+   }
+   
+   return (d / BANDS);
+}
+
+ossim_float64 ossimHistogramRemapper::getMinOutputValue(ossim_uint32 zero_based_band) const
+{
+   if (theMinOutputValue.size() == 0 ||
+       zero_based_band >= getNumberOfInputBands())
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   if (zero_based_band >= theMinOutputValue.size())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::getMinOutputValue ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (theMinOutputValue.size()-1)
+         << endl;
+      return OSSIM_DBL_NAN;
+   }
+
+   return theMinOutputValue[zero_based_band];
+}
+
+ossim_float64 ossimHistogramRemapper::getMinOutputValue() const
+{
+   if (theMinOutputValue.size() == 0)
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   ossim_float64 d = 0.0;
+   const ossim_uint32 BANDS = theMinOutputValue.size();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      d += getMinOutputValue(band);
+   }
+   
+   return (d / BANDS);
+}
+
+ossim_float64 ossimHistogramRemapper::getMaxOutputValue(ossim_uint32 zero_based_band) const
+{
+   if (theMaxOutputValue.size() == 0 ||
+       zero_based_band >= getNumberOfInputBands())
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   if (zero_based_band >= theMaxOutputValue.size())
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::getMaxOutputValue ERROR:"
+         << "\nband " << zero_based_band << " is out of range!"
+         << "\nhighest band:  " << (theMaxOutputValue.size()-1)
+         << endl;
+      return OSSIM_DBL_NAN;
+   }
+
+   return theMaxOutputValue[zero_based_band];
+}
+
+ossim_float64 ossimHistogramRemapper::getMaxOutputValue() const
+{
+   if (theMaxOutputValue.size() == 0)
+   {
+      return OSSIM_DBL_NAN;
+   }
+   
+   ossim_float64 d = 0.0;
+   const ossim_uint32 BANDS = theMaxOutputValue.size();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      d += getMaxOutputValue(band);
+   }
+   
+   return (d / BANDS); 
+}
+
+bool ossimHistogramRemapper::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   static const char MODULE[] = "ossimHistogramRemapper::loadState";
+
+   if (traceDebug())
+   {
+      CLOG << " Entered..."
+           << "\nprefix:  " << prefix << endl;
+   }
+
+   const char* lookup = NULL;
+   ossimString keyword;
+
+   lookup = kwl.find(prefix, HISTOGRAM_FILENAME_KW);
+   if (lookup)
+   {
+      if ( !openHistogram(ossimFilename(lookup)) )
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHistogramRemapper::loadState ERROR!"
+            << "\nCould not open file:  " << lookup
+            << "\nReturning..." << endl;
+         return false;
+      }
+   }
+   
+   //---
+   // Get the band specific keywords.
+   // NOTES:
+   // -  This loadState assumes the all keywords will have the same number
+   //    of bands.
+   // -  The set methods cannot be used here as there may not be a connection
+   //    yet that they need.
+   //---
+   ossim_uint32 bands = 0;
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_BANDS_KW);
+   if (lookup)
+   {
+      bands = ossimString::toUInt32(lookup);
+   }
+   else  // For backwards compatibility.
+   {
+      // Use the low clip to find number of bands...
+      keyword = NORMALIZED_LOW_CLIP_POINT_KW;
+      bands = kwl.numberOf(prefix, keyword);
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimHistogramRemapper::loadState DEBUG:"
+         << "\nBands:  " << bands
+         << endl;
+   }
+
+   // Start with fresh clips.
+   initializeClips(bands);
+   
+   for (ossim_uint32 band = 0; band < bands; ++band)
+   {
+      // Get the low clip.
+      keyword = NORMALIZED_LOW_CLIP_POINT_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      lookup = kwl.find(prefix, keyword);
+      if(lookup)
+      {
+         theNormalizedLowClipPoint[band] = atof(lookup);
+      }
+
+      // Get the high clip.
+      keyword = NORMALIZED_HIGH_CLIP_POINT_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      lookup = kwl.find(prefix, keyword);
+      if(lookup)
+      {
+         theNormalizedHighClipPoint[band] = atof(lookup);
+      }
+
+      // Get the mid point.
+      keyword = MID_POINT_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      lookup = kwl.find(prefix, keyword);
+      if(lookup)
+      {
+         theMidPoint[band] = atof(lookup);
+      }
+
+      // Get the min output value.
+      keyword = MIN_OUTPUT_VALUE_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      lookup = kwl.find(prefix, keyword);
+      if(lookup)
+      {
+         theMinOutputValue[band] = atof(lookup);
+      }
+
+      // Get the max output value.
+      keyword = MAX_OUTPUT_VALUE_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      lookup = kwl.find(prefix, keyword);
+      if(lookup)
+      {
+         theMaxOutputValue[band] = atof(lookup);
+      }      
+   }
+   
+   lookup = kwl.find(prefix, STRETCH_MODE_KW);
+   if (lookup)
+   {
+      ossimString s = lookup;
+      s.downcase();
+      if (s == STRETCH_MODE[ossimHistogramRemapper::LINEAR_ONE_PIECE])
+      {
+         theStretchMode = ossimHistogramRemapper::LINEAR_ONE_PIECE;
+      }
+      else if (s == STRETCH_MODE[ossimHistogramRemapper::LINEAR_1STD_FROM_MEAN])
+      {
+         theStretchMode = ossimHistogramRemapper::LINEAR_1STD_FROM_MEAN;
+      }
+      else if (s == STRETCH_MODE[ossimHistogramRemapper::LINEAR_2STD_FROM_MEAN])
+      {
+         theStretchMode = ossimHistogramRemapper::LINEAR_2STD_FROM_MEAN;
+      }
+      else if (s == STRETCH_MODE[ossimHistogramRemapper::LINEAR_3STD_FROM_MEAN])
+      {
+         theStretchMode = ossimHistogramRemapper::LINEAR_3STD_FROM_MEAN;
+      }
+      else if (s == STRETCH_MODE[ossimHistogramRemapper::LINEAR_AUTO_MIN_MAX])
+      {
+         theStretchMode = ossimHistogramRemapper::LINEAR_AUTO_MIN_MAX;
+      }
+      else
+      {
+         theStretchMode = ossimHistogramRemapper::STRETCH_UNKNOWN;
+      }
+   }
+
+   // Load the base class states...
+   bool status = ossimTableRemapper::loadState(kwl, prefix);
+
+   //---
+   // Check for the enable flag which would have been loaded be the base class
+   // loadState.  If enabled, set the dirty flag so that the first getTile
+   // will cause a "buildTable()" call.
+   //---
+   if (theEnableFlag)
+   {
+      theDirtyFlag = true;
+   }
+   
+   if (traceDebug())
+   {
+      CLOG << "ossimHistogramRemapper::loadState DEBUG:"
+           << *this
+           << "\nExited..." << endl;
+   }
+
+   return status;
+}
+
+bool ossimHistogramRemapper::saveState(ossimKeywordlist& kwl,
+                                       const char* prefix) const
+{
+   if (theHistogram)
+   {
+      kwl.add(prefix,
+              HISTOGRAM_FILENAME_KW,
+              theHistogram->getHistogramFile().c_str(),
+              true);
+   }
+      
+   kwl.add(prefix,
+           STRETCH_MODE_KW,
+           getStretchModeString().c_str(),
+           true);
+
+   const ossim_uint32 BANDS = theNormalizedLowClipPoint.size();
+   
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_BANDS_KW,
+           BANDS,
+           true);
+
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      ossimString keyword;
+         
+      // Save the low clip.
+      keyword = NORMALIZED_LOW_CLIP_POINT_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      kwl.add(prefix,
+              keyword,
+              theNormalizedLowClipPoint[band],
+              true);
+
+      // Save the high clip.
+      keyword = NORMALIZED_HIGH_CLIP_POINT_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      kwl.add(prefix,
+              keyword,
+              theNormalizedHighClipPoint[band],
+              true);
+
+      // Save the mid point.
+      keyword = MID_POINT_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      kwl.add(prefix,
+              keyword,
+              theMidPoint[band],
+              true);
+
+      // Save the min output value.
+      keyword = MIN_OUTPUT_VALUE_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      kwl.add(prefix,
+              keyword,
+              theMinOutputValue[band],
+              true);
+
+      // Save the max output value.
+      keyword = MAX_OUTPUT_VALUE_KW;
+      keyword += ".";
+      keyword += ossimKeywordNames::BAND_KW;
+      keyword += ossimString::toString(band+1);
+      kwl.add(prefix,
+              keyword,
+              theMaxOutputValue[band],
+              true);
+   }
+   
+   return ossimTableRemapper::saveState(kwl, prefix);
+}
+
+void ossimHistogramRemapper::setStretchMode(StretchMode mode)
+{
+   if (theStretchMode != mode)
+   {
+      theDirtyFlag = true;
+      theStretchMode = mode;
+   }
+}
+
+void ossimHistogramRemapper::buildTable()
+{
+   setupTable();
+   
+   switch(theStretchMode)
+   {
+      case ossimHistogramRemapper::LINEAR_ONE_PIECE:
+      {
+         buildLinearTable();
+         break;
+      }
+      case ossimHistogramRemapper::LINEAR_AUTO_MIN_MAX:
+      {
+         buildAutoLinearMinMaxTable();
+         break;
+      }
+      case ossimHistogramRemapper::LINEAR_1STD_FROM_MEAN:
+      case ossimHistogramRemapper::LINEAR_2STD_FROM_MEAN:
+      case ossimHistogramRemapper::LINEAR_3STD_FROM_MEAN:
+         buildLinearTableStdFromMean();
+         break;
+         
+      default:
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHistogramRemapper::buildTable ERROR!"
+            << "\nUnknown stretch type!" << endl;
+         break;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimHistogramRemapper::buildTable DEBUG:\n" << endl;
+      print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+}
+
+void ossimHistogramRemapper::buildLinearTable()
+{
+   switch (getOutputScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         buildLinearTable(ossim_uint8(0));
+         break;
+      }
+      
+      case OSSIM_USHORT11:
+      case OSSIM_USHORT16:
+      {
+         buildLinearTable(ossim_uint16(0));
+         break;
+      }
+      
+      case OSSIM_SSHORT16:
+      {
+         buildLinearTable(ossim_sint16(0));
+         break;
+      }
+
+      case OSSIM_NORMALIZED_FLOAT:      
+      case OSSIM_FLOAT:
+      {
+         buildLinearTable(ossim_float32(0));
+         break;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_DOUBLE:
+      {
+         buildLinearTable(ossim_float64(0));
+         break;
+      }
+      
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         // Shouldn't hit this.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimTableRemapper::buildTable OSSIM_SCALAR_UNKNOWN!"
+            << endl;
+         break;
+      }
+
+   } // End of "switch (theTableType)"
+}
+
+void ossimHistogramRemapper::buildAutoLinearMinMaxTable()
+{
+   switch (getOutputScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         buildAutoLinearMinMaxTableTemplate(ossim_uint8(0));
+         break;
+      }
+      
+      case OSSIM_USHORT11:
+      case OSSIM_USHORT16:
+      {
+         buildAutoLinearMinMaxTableTemplate(ossim_uint16(0));
+         break;
+      }
+      
+      case OSSIM_SSHORT16:
+      {
+         buildAutoLinearMinMaxTableTemplate(ossim_sint16(0));
+         break;
+      }
+
+      case OSSIM_NORMALIZED_FLOAT:      
+      case OSSIM_FLOAT:
+      {
+         buildAutoLinearMinMaxTableTemplate(ossim_float32(0));
+         break;
+      }
+      
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_DOUBLE:
+      {
+         buildAutoLinearMinMaxTableTemplate(ossim_float64(0));
+         break;
+      }
+      
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         // Shouldn't hit this.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimTableRemapper::buildTable OSSIM_SCALAR_UNKNOWN!"
+            << endl;
+         break;
+      }
+
+   } // End of "switch (theTableType)"
+}
+
+template <class T> void ossimHistogramRemapper::buildLinearTable(T /* dummy */)
+{
+   // This builds a native table.
+   theTableType = ossimTableRemapper::NATIVE;
+   
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+
+   // Sanity check.
+   if (theNormalizedLowClipPoint.size() != BANDS || !theHistogram)
+   {
+      theEnableFlag = false;
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::buildTable ERROR!"
+         << " Line:  " << __LINE__ << endl;
+      return;
+   }
+   
+   T* table = reinterpret_cast<T*>(theTable);
+   ossim_uint32 index = 0;
+   
+   // Finally, build the table...
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      ossimHistogram* h  = getHistogram(band);
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimHistogramRemapper::buildLinearTable DEBUG:"
+            << "\nband:  " << band
+            << "\nmean:  " << h->GetMean()
+            << "\nstddev:  " << h->GetStandardDev()
+            << endl;
+      }
+
+      if (!h)
+      {
+         theEnableFlag = false;
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHistogramRemapper::buildTable ERROR!"
+            << " Line:  " << __LINE__ << endl;
+         return; 
+      }
+
+      const T NULL_PIX = static_cast<T>(getNullPixelValue(band));
+      const T MIN_PIX  = static_cast<T>(theMinOutputValue[band]);
+      const T MAX_PIX  = static_cast<T>(theMaxOutputValue[band]);
+      
+      ossim_float64 min_clip_value =
+         h->LowClipVal(theNormalizedLowClipPoint[band]);
+      ossim_float64 max_clip_value =
+         h->HighClipVal(1.0-theNormalizedHighClipPoint[band]);
+      min_clip_value = floor(min_clip_value);
+      max_clip_value = ceil(max_clip_value);
+      ossim_float64 gain = (MAX_PIX-MIN_PIX+1)/(max_clip_value-min_clip_value);
+      
+      table[index] = NULL_PIX;
+      ++index;
+      for (ossim_uint32 pix = 1; pix < theTableBinCount; ++pix)
+      {
+         ossim_float64 p = pix;
+         if (p <= min_clip_value)
+         {
+            p = MIN_PIX;
+         }
+         else if (p >= max_clip_value)
+         {
+            p = MAX_PIX;
+         }
+         else
+         {
+            p = ((p - min_clip_value) * gain) + MIN_PIX - 1.0;
+         }
+         
+         table[index] = static_cast<T>(p+0.5);
+
+         ++index;
+      }
+   } // End of band loop.
+
+   // Clear the dirty flag so the table's not rebuilt on the next getTile.
+   theDirtyFlag = false;
+}
+
+template <class T> void ossimHistogramRemapper::buildAutoLinearMinMaxTableTemplate(T /* dummy */)
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+
+   // Sanity check.
+   if (theNormalizedLowClipPoint.size() != BANDS || !theHistogram)
+   {
+      theEnableFlag = false;
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::buildTable ERROR!"
+         << " Line:  " << __LINE__ << endl;
+      return;
+   }
+
+
+   // Finally, build the table...
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      ossimHistogram* h      = getHistogram(band);
+      if(h)
+      {
+         setLowClipPoint(h->GetMinVal());
+         setHighClipPoint(h->GetMaxVal());
+      }
+   }
+   
+   buildLinearTable();
+}
+
+void ossimHistogramRemapper::buildLinearTableStdFromMean()
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+
+   // Sanity check.
+   if (theNormalizedLowClipPoint.size() != BANDS || !theHistogram)
+   {
+      theEnableFlag = false;
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHistogramRemapper::buildTable ERROR!"
+         << " Line:  " << __LINE__ << endl;
+      return;
+   }
+
+   ossim_float64 multiplier = 1.0;
+   if (theStretchMode == LINEAR_2STD_FROM_MEAN)
+   {
+      multiplier =  2.0;
+   }
+   else if (theStretchMode == LINEAR_3STD_FROM_MEAN)
+   {
+      multiplier =  3.0;
+   }
+
+   // Finally, build the table...
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      ossimHistogram* h      = getHistogram(band);
+      ossim_float64 mean     = h->GetMean();
+      ossim_float64 stdDev   = h->GetStandardDev();
+      ossim_float64 lowClip  = mean - (stdDev * multiplier);
+      ossim_float64 highClip = mean + (stdDev * multiplier);
+
+      // Clamp to min/max.
+      if (lowClip < theMinOutputValue[band])
+      {
+         lowClip = theMinOutputValue[band];
+      }
+      if (highClip > theMaxOutputValue[band])
+      {
+         highClip = theMaxOutputValue[band];
+      }
+      
+      setLowClipPoint(lowClip, band);
+      setMidPoint(mean, band);
+      setHighClipPoint(highClip, band);
+      
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimHistogramRemapper::buildLinearStdFromMean DEBUG:"
+            << "\nband:       " << band
+            << "\nmean:       " << mean
+            << "\nstddev:     " << stdDev
+            << "\nlow clip:   " << lowClip
+            << "\nhigh clip:  " << highClip
+            << endl;
+      }
+   }
+   
+   buildLinearTable();
+}
+
+void ossimHistogramRemapper::initializeClips()
+{
+   initializeClips(getNumberOfInputBands());
+}
+
+void ossimHistogramRemapper::initializeClips(ossim_uint32 bands)
+{
+   theEnableFlag = false;
+   theDirtyFlag  = false;
+
+   if (bands == 0)
+   {
+      return;
+   }
+
+   theNormalizedLowClipPoint.resize(bands);
+   theNormalizedHighClipPoint.resize(bands);
+   theMidPoint.resize(bands);
+   theMinOutputValue.resize(bands);
+   theMaxOutputValue.resize(bands);
+   
+   for (ossim_uint32 band = 0; band < bands; ++band)
+   {
+      theNormalizedLowClipPoint[band]  = 0.0;
+      theNormalizedHighClipPoint[band] = 1.0;
+      theMidPoint[band] = 0.0;
+      theMinOutputValue[band] = getMinPixelValue(band);
+      theMaxOutputValue[band] = getMaxPixelValue(band);
+   }
+}
+
+void ossimHistogramRemapper::setNullCount() const
+{
+   // This will set the null bucket for all res zero bands to zero!
+   if (theHistogram)
+   {
+      const ossim_uint32 BANDS = theHistogram->getNumberOfBands();//getNumberOfInputBands();
+      for (ossim_uint32 band = 0; band < BANDS; ++band)
+      {
+         ossimHistogram* h = theHistogram->getHistogram(band);
+         if (h)
+         {
+            h->SetCount(0, 0);
+         }
+      }
+   }
+}
+
+ossimHistogramRemapper::StretchMode ossimHistogramRemapper::getStretchMode() const
+{
+   return theStretchMode;
+}
+
+ossimString ossimHistogramRemapper::getStretchModeString() const
+{
+   return ossimString(STRETCH_MODE[theStretchMode]);
+}
+
+ossim_uint32 ossimHistogramRemapper::getNumberOfStretchModes() const
+{
+   return ossimHistogramRemapper::STRETCH_UNKNOWN; // last index
+}
+
+ossimString
+ossimHistogramRemapper::getStretchModeString(ossim_uint32 index) const
+{
+   if (index < ossimHistogramRemapper::STRETCH_UNKNOWN)
+   {
+      return ossimString(STRETCH_MODE[index]);
+   }
+
+   return ossimString(STRETCH_MODE[ossimHistogramRemapper::STRETCH_UNKNOWN]);
+   
+}
+
+ostream& ossimHistogramRemapper::print(ostream& os) const
+{
+   os << setiosflags(ios::fixed) << setprecision(15)
+      << "\nossimHistogramRemapper::print:"
+      << "\ntheStretchMode:         " << getStretchModeString().c_str()
+      << "\ntheDirtyFlag:           " << (theDirtyFlag?"true":"false")
+      << "\ntheHistogramOwnerFlag:  "
+      << (theHistogramOwnerFlag?"true":"false")
+      << "\ntheHistogram:           " << (theHistogram?"initialized":"null")
+      << "\ntheTableSizeInBytes:    " << theTableSizeInBytes
+      << endl;
+
+   const ossim_uint32 BANDS = theNormalizedLowClipPoint.size();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      os << "\ntheNormalizedLowClipPoint[" << band << "]:   "
+         << theNormalizedLowClipPoint[band]
+         << "\ntheNormalizedHighClipPoint[" << band << "]:  "
+         << theNormalizedHighClipPoint[band]
+         << "\ntheMidPoint[" << band << "]:                 "
+         << theMidPoint[band]
+         << "\ntheMinOutputValue[" << band << "]:           "
+         << theMinOutputValue[band]
+         << "\ntheMaxOutputValue[" << band << "]:           "
+         << theMaxOutputValue[band]
+         << endl;
+   }
+
+   for (ossim_uint32 i = 0; i < theBandList.size(); ++i)
+   {
+      os << "theBandList[" << i << "]:  " << theBandList[i] << endl;
+   }
+
+   return ossimTableRemapper::print(os);
+}
+
+void ossimHistogramRemapper::setupTable()
+{
+   const ossim_uint32 BANDS = getNumberOfInputBands();
+   
+   if (theNormalizedLowClipPoint.size() == 0)
+   {
+      initializeClips(BANDS);
+   }
+   
+   ossim_uint32 values_per_band = 0;
+   ossim_uint32 bytes_per_pixel = 0;
+   
+   switch (theOutputScalarType)
+   {
+      case OSSIM_UCHAR:
+         values_per_band = 256;  // 2 ^ 8
+         bytes_per_pixel = 1;
+         theTableType = ossimTableRemapper::NATIVE;
+         break;
+      
+      case OSSIM_USHORT11:
+         values_per_band = 2048; // 2 ^ 11
+         bytes_per_pixel = 2;
+         theTableType = ossimTableRemapper::NATIVE;
+         
+         break;
+         
+      case OSSIM_USHORT16:
+      case OSSIM_SSHORT16:
+         values_per_band = 65536; // 2 ^ 16
+         bytes_per_pixel = 2;
+         theTableType = ossimTableRemapper::NATIVE;
+         break;
+      
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT:
+         bytes_per_pixel = 4;
+         break;
+
+      case OSSIM_NORMALIZED_DOUBLE:         
+      case OSSIM_DOUBLE:
+         bytes_per_pixel = 8;
+         theTableType = ossimTableRemapper::NORMALIZED;
+         break;
+         
+      default:
+         break;
+   }
+
+   if ( theOutputScalarType == OSSIM_FLOAT ||
+        theOutputScalarType == OSSIM_DOUBLE ||
+        theOutputScalarType == OSSIM_NORMALIZED_FLOAT ||
+        theOutputScalarType == OSSIM_NORMALIZED_DOUBLE )
+   {
+      for (ossim_uint32 band = 0; band < BANDS; ++band)
+      {
+         ossimHistogram* h  = getHistogram(band);
+            
+         if (h)
+         {
+            if (h->GetRes() > static_cast<ossim_int32>(values_per_band))
+            {
+               values_per_band = h->GetRes();
+            }
+         }
+      }
+   }      
+   
+   theTableBinCount  = values_per_band;
+   theTableBandCount = BANDS;
+
+   // Check the size of the table prior to deletion and making a new one.
+   ossim_uint32 size_in_bytes = values_per_band * BANDS * bytes_per_pixel;
+
+   if (!theTable || (theTableSizeInBytes != size_in_bytes))
+   {
+      if (theTable)
+      {
+         delete [] theTable;
+      }
+      theTable = new ossim_uint8[size_in_bytes];
+      theTableSizeInBytes = size_in_bytes;
+   }
+
+   //---
+   // Last check for NaNs in key data members and set to some default if so.
+   // This could occur if someone stripped a keyword list down to a minimal
+   // set of keywords.
+   //---
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      const double MIN = getMinPixelValue(band);
+      const double MAX = getMaxPixelValue(band);
+      
+      if ( theMinOutputValue[band] == OSSIM_DBL_NAN )
+      {
+         theMinOutputValue[band] = MIN;
+      }
+      if ( theMaxOutputValue[band] == OSSIM_DBL_NAN )
+      {
+         theMaxOutputValue[band] = MAX;
+      }
+   }   
+}
+
+void ossimHistogramRemapper::verifyEnabled()
+{
+   theEnableFlag = false;
+
+   if (!theInputConnection)
+   {
+      //***
+      // Since this filter can be constructed with no input connection do not
+      // output and error, simply return.
+      //***
+      return;
+   }
+
+   const ossim_uint32 BANDS = theNormalizedLowClipPoint.size();
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      const double MIN = getMinPixelValue(band);
+      const double MAX = getMaxPixelValue(band);
+      
+      if ( theNormalizedLowClipPoint[band]  != 0.0   ||
+           theNormalizedHighClipPoint[band] != 1.0   ||
+           // theMidPoint != 0.0 || ????
+           theMinOutputValue[band] != MIN ||
+           theMaxOutputValue[band] != MAX )
+      {
+         theEnableFlag = true;
+         break;
+      }
+   }
+}
+
+ossimHistogram*
+ossimHistogramRemapper::getHistogram(ossim_uint32 zero_based_band,
+                                     ossim_uint32 res_level) const
+{
+   ossim_uint32 histogram_band = getHistogramBand(zero_based_band);
+   ossimHistogram* h = NULL;
+   
+   if (theHistogram)
+   {
+      if (histogram_band < theHistogram->getNumberOfBands())
+      {
+         h = theHistogram->getHistogram(histogram_band, res_level);
+      }
+   }
+
+   return h;
+}
+
+ossimFilename ossimHistogramRemapper::getHistogramFile() const
+{
+   if (theHistogram)
+   {
+      return theHistogram->getHistogramFile();
+   }
+
+   return ossimFilename::NIL;
+}
+
+ossim_uint32
+ossimHistogramRemapper::getHistogramBand(ossim_uint32 input_band) const
+{
+   vector<ossim_uint32> bandList;
+   getOutputBandList(bandList);
+   
+   const ossim_uint32 BANDS = bandList.size();
+
+   if (BANDS == 0)
+   {
+      return 0;
+   }
+
+   return bandList[input_band];
+}
+
+ossimString ossimHistogramRemapper::getLongName()const
+{
+   return ossimString("Histogram Remapper, filter with controls for histogram stretching.");
+}
+
+ossimString ossimHistogramRemapper::getShortName()const
+{
+   return ossimString("Histogram Remapper");
+}
+
+ostream& operator<<(ostream& os, const ossimHistogramRemapper& hr)
+{
+   return hr.print(os);
+}
+
+
+// Private to disallow use...
+ossimHistogramRemapper::ossimHistogramRemapper(const ossimHistogramRemapper&)
+{
+}
+
+// Private to disallow use...
+ossimHistogramRemapper& ossimHistogramRemapper::operator=(const ossimHistogramRemapper&)
+{
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramRemapper.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramRemapper.h
new file mode 100644
index 0000000000..89e89d12bd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramRemapper.h
@@ -0,0 +1,529 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Histogram remapper class declaration.  Derived from ossimTableRemapper.
+//
+// Remaps a tile based on mode and histogram clip points.  This object uses
+// a precomputed remap table for speed; hence, derived from the
+// ossimTableRemapper
+//
+// NOTE on bands:
+// 
+// - All methods take zero based bands.  In other words the first
+//   band is band "0".  
+//
+// - This objects band 0 is the same band 0 as it's input connection.  If
+//   the band order was changed by a ossimBandSelector then this band 0 will
+//   not map to the histogram files band 0.  To handle this,
+//   the "getOutputBandList()" method is used to get the correct histogram for
+//   the input band.
+//   
+// - The "get" methods that do not take a band, simply return the average of
+//   all bands.  This really only makes sense if all bands are the same
+//   but is provided for convenience.
+//   
+//*************************************************************************
+// $Id: ossimHistogramRemapper.h,v 1.17 2005/09/12 13:15:52 gpotts Exp $
+#ifndef ossimHistogramRemapper_HEADER
+#define ossimHistogramRemapper_HEADER
+
+#include <imaging/tile_sources/ossimTableRemapper.h>
+
+class ossimMultiResLevelHistogram;
+class ossimHistogram;
+
+class OSSIMDLLEXPORT ossimHistogramRemapper : public ossimTableRemapper
+{
+public:
+   enum StretchMode
+   {
+      LINEAR_ONE_PIECE      = 0,
+      LINEAR_1STD_FROM_MEAN = 1,
+      LINEAR_2STD_FROM_MEAN = 2,
+      LINEAR_3STD_FROM_MEAN = 3,
+      LINEAR_AUTO_MIN_MAX   = 4,
+      STRETCH_UNKNOWN = 5 // Alway last as used for number of modes method.
+      
+   };
+   
+   ossimHistogramRemapper(ossimObject* owner=NULL);
+   ossimHistogramRemapper(ossimImageSource* inputSource);
+
+   /**
+    * NOTE:
+    * - If input chip source is mutiband this will set all band to same
+    *   percentage of clip.
+    * - low_clip  is a normalized percentage, 0.01 = one percent low clip.
+    * - high_clip is a normalized percentage, 0.99 = one percent high clip.
+    */
+   ossimHistogramRemapper(ossimImageSource* inputSource,
+                          ossimMultiResLevelHistogram* histogram,
+                          bool own_histogram = true,
+                          ossim_float64 low_clip = 0.0,
+                          ossim_float64 high_clip = 1.0);
+   
+   
+   virtual ~ossimHistogramRemapper();
+
+   virtual ossimString getLongName()  const;
+   virtual ossimString getShortName() const;
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+
+   /**
+    * - Disables this source.
+    * - Sets all clip points to default.
+    * - Removes current table.
+    */
+   void reset();
+   
+   /**
+    * Sets remap mode to mode.
+    */
+   void setStretchMode(StretchMode mode);
+
+   /**
+    * Returns the current enumerated node.
+    */
+   StretchMode   getStretchMode() const;
+
+   /**
+    * Returns the string for current remap mode.
+    */
+   ossimString getStretchModeString() const;
+
+   /**
+    * Returns the number of stretch modes.
+    */
+   ossim_uint32 getNumberOfStretchModes() const;
+
+   /**
+    * Returns the mode string for a given index.
+    * Returns "stretch_unknown" if index is out of range.
+    * 
+    * NOTE:
+    * - If you're building gui buttons you can:
+    *   // pseudo code...
+    *   ossim_uint32 number_of_modes = remapper->getNumberOfModes()
+    *   for (ossim_uint32 i = 0; i < number_of_modes; ++i)
+    *   {
+    *      addButton(getModeString(i).c_str());
+    *   }
+    */
+   ossimString getStretchModeString(ossim_uint32 index) const;
+   
+   /**
+    * Sets the low clip point.
+    *
+    * Note on null bin:
+    * - The null bin is ignored when considering a percent of penetration from
+    *   the low end.
+    *
+    * Notes on clip point:
+    * - If input chip source is mutiband this will set all band to same
+    *   percentage of clip.
+    * - Clip points should be normalized between zero and one.
+    * - A low clip point of 0.0 means no penetration.
+    * - A low clip point of 0.02 means penetrate in two percent.
+    */
+   void setLowNormalizedClipPoint(const ossim_float64& clip);
+
+   /**
+    * Sets the low clip point for band.
+    *
+    * Note on null bin:
+    * - The null bin is ignored when considering a percent of penetration from
+    *   the low end.
+    *
+    * Notes on clip points:
+    * - Clip point should be normalized between zero and one.
+    * - A low clip point of 0.0 means no penetration.
+    * - A low clip point of 0.02 means penetrate in two percent.
+    */
+   void setLowNormalizedClipPoint(const ossim_float64& clip,
+                                  ossim_uint32 zero_based_band);
+
+   /**
+    * Sets the high clip point.
+    * 
+    * Notes on clip points:
+    * - If input chip source is mutiband this will set all band to same
+    *   percentage of clip.
+    * - Clip point should be normalized between zero and one.
+    * - A high clip point of 1.0 means no penetration.
+    * - A high clip point of .98 mean a 2 % penetration from the high end.
+    */
+   void setHighNormalizedClipPoint(const ossim_float64& clip);
+
+   /**
+    * Sets the high clip point.
+    *
+    * Notes on clip points:
+    * - Clip point should be normalized between zero and one.
+    * - A high clip point of 1.0 means no penetration.
+    * - A high clip point of .98 mean a 2 % penetration from the high end.
+    */
+   void setHighNormalizedClipPoint(const ossim_float64& clip,
+                                   ossim_uint32 zero_based_band);
+
+   /**
+    * Sets the low clip point.
+    *
+    * Notes on clip point:
+    * - If input chip source is mutiband this will set all band to same
+    *   percentage of clip.
+    * - Clip points are in DN values.
+    * - If histogram is not set no action is taken. 
+    */
+   void setLowClipPoint(const ossim_float64& clip);
+
+   /**
+    * Sets the low clip point for band.
+    *
+    * Notes on clip points:
+    * - Clip points are DN values.
+    * - If histogram is not set no action is taken. 
+    */
+   void setLowClipPoint(const ossim_float64& clip,
+                        ossim_uint32 zero_based_band);
+
+   /**
+    * Sets the high clip point.
+    * 
+    * Notes on clip points:
+    * - If input chip source is mutiband this will set all band to same
+    *   percentage of clip.
+    * - Clip points are DN values.
+    * - If histogram is not set no action is taken. 
+    */
+   void setHighClipPoint(const ossim_float64& clip);
+
+   /**
+    * Sets the high clip point.
+    *
+    * Notes on clip points:
+    * - Clip points are DN values.
+    * - If histogram is not set no action is taken. 
+    */
+   void setHighClipPoint(const ossim_float64& clip,
+                         ossim_uint32 zero_based_band);
+
+   /**
+    * Sets the mid clip point.
+    * 
+    * Notes on clip points:
+    * - If input chip source is mutiband this will set all band to same
+    *   percentage of clip.
+    */
+   void setMidPoint(const ossim_float64& value);
+
+   /**
+    * Sets the mid clip point for band.
+    */
+   void setMidPoint(const ossim_float64& value,
+                    ossim_uint32 zero_based_band);
+
+   /**
+    * Sets the min output value.
+    * 
+    * Notes on clip points:
+    * - If input chip source is mutiband this will set all band to same
+    *   percentage of clip.
+    */
+   void setMinOutputValue(const ossim_float64& value);
+
+   /**
+    * Sets the min output value for band.
+    */
+   void setMinOutputValue(const ossim_float64& value,
+                          ossim_uint32 zero_based_band);
+
+   /**
+    * Sets the max output value.
+    * 
+    * Notes on clip points:
+    * - If input chip source is mutiband this will set all band to same
+    *   percentage of clip.
+    */
+   void setMaxOutputValue(const ossim_float64& value);
+
+   /**
+    * Sets the min output value for band.
+    */
+   void setMaxOutputValue(const ossim_float64& value,
+                          ossim_uint32 zero_based_band);
+   
+   /**
+    * Returns the normalized low clip point for band.
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getLowNormalizedClipPoint(ossim_uint32 zero_based_band) const;
+
+   /**
+    * Returns the normalized low clip point which is the average of all bands.
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getLowNormalizedClipPoint() const;
+
+   /**
+    * Returns the normalized high clip point for band.
+    *
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getHighNormalizedClipPoint(ossim_uint32 zero_based_band) const;
+   /**
+    * Returns the normalized High clip point which is the average of all bands.
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getHighNormalizedClipPoint() const;
+
+   /**
+    * Returns the low clip point for band.
+    * Clip points are DN values relative to the scalar type.
+    *
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getLowClipPoint(ossim_uint32 zero_based_band) const;
+
+   /**
+    * Returns the low clip point which is the average of all bands.
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getLowClipPoint() const;
+
+   /**
+    * Returns the high clip point for band.
+    * Clip points are DN values relative to the scalar type.
+    *
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getHighClipPoint(ossim_uint32 zero_based_band) const;
+
+   /**
+    * Returns the high clip point which is the average of all bands.
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getHighClipPoint() const;
+
+   
+   /**
+    * Returns the mid point for band
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getMidPoint(ossim_uint32 zero_based_band) const;
+   
+   /**
+    * Returns the mid clip point which is the average of all bands.
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    * - Histogram has not been set.
+    */
+   ossim_float64 getMidPoint() const;
+   
+   /**
+    * Returns the minimum output value for band.
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    */
+   ossim_float64 getMinOutputValue(ossim_uint32 zero_based_band) const;
+
+   /**
+    * Returns the minimum output value which is the average of all bands.
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    */
+   ossim_float64 getMinOutputValue() const;
+
+   /**
+    * Returns the maximum output value for band.
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    */
+   ossim_float64 getMaxOutputValue(ossim_uint32 zero_based_band) const;
+
+   /**
+    * Returns the maximum output value which is the average of all bands.
+    * 
+    * Will return OSSIM_DBL_NAN if:
+    * - Band is out of range.
+    * - Connection is not complete.
+    */
+   ossim_float64 getMaxOutputValue() const;
+   
+   /**
+    * Sets the histogram.
+    * If (own_histogram == true) this object will delete theHistogram
+    * on destruction.
+    */
+   void setHistogram(ossimMultiResLevelHistogram* histogram,
+                     bool own_histogram = true);
+
+   /**
+    * Returns pointer to histogram for band and reduced res level.
+    * - Band is zero based relative to the input connection.  This will be
+    *   remapped to the histogram band using the "getOutputBandList()" to
+    *   get the correct histogram band.
+    *   
+    * Will return NULL if:
+    * - band is out range
+    * - res_level is out of range
+    * - theHistogram has not been initialized yet.
+    */
+   ossimHistogram* getHistogram(ossim_uint32 zero_based_band,
+                                ossim_uint32 res_level=0) const;
+
+   /**
+    * Open the histogram file.
+    * With this method the histogram is owned by this object.
+    * Returns true on success, false on error.
+    */
+   bool openHistogram(const ossimFilename& histogram_file);
+
+   /**
+    * Returns the currently opened histogram.
+    * Returns ossimFilename::NIL if no histogram is loaded.
+    */
+   ossimFilename getHistogramFile() const;
+   
+   /**
+    * Method to the save the state to a keyword list.
+    * Returns true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.
+    * Returns true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   
+   virtual ostream& print(ostream& os) const;
+
+   friend ostream& operator <<(ostream& os, const ossimHistogramRemapper& hr);
+   
+private:
+   // Do not allow copy constructor, operator=.
+   ossimHistogramRemapper(const ossimHistogramRemapper& hr);
+   ossimHistogramRemapper& operator=(const ossimHistogramRemapper& hr);
+
+   void buildTable();
+   void buildLinearTable();
+   void buildAutoLinearMinMaxTable();
+   template <class T> void buildLinearTable(T dummy);
+   template <class T> void buildAutoLinearMinMaxTableTemplate(T dummy);
+
+   /**
+    * Sets clip points using mean and standard deviations then calls
+    * buildLinearTable method.
+    */
+   void buildLinearTableStdFromMean();
+   
+   /**
+    * Uses getNumberOfInputBands() to determine BANDS then calls
+    * initializeClips(BANDS)
+    */
+   void initializeClips();
+
+   /**
+    * Initializes data members to some default state and size.
+    */
+   void initializeClips(ossim_uint32 bands);
+
+   /*
+    * Sets the count of the null bin to 0 so that clips from the low end
+    * ignore the null bin.
+    */
+   void setNullCount() const;
+
+   /**
+    * Initialized base class (ossimTableRemapper) values:
+    * - theTableBinCount
+    * - theTableBandCount
+    * - theTableType
+    * - theTable (resizes if not correct size.
+    */
+   void setupTable();
+
+   void verifyEnabled();
+
+   /**
+    * Returns the histogram band that maps to the input band.
+    * Note:
+    * - This uses the current band list from "getOutputBandList()".
+    */
+   ossim_uint32 getHistogramBand(ossim_uint32 input_band) const;
+
+
+   StretchMode                   theStretchMode;
+   bool                          theDirtyFlag;
+   bool                          theHistogramOwnerFlag;
+   ossimMultiResLevelHistogram*  theHistogram;
+   ossim_uint32                  theTableSizeInBytes;
+   vector<ossim_float64>         theNormalizedLowClipPoint;
+   vector<ossim_float64>         theNormalizedHighClipPoint;
+   vector<ossim_float64>         theMidPoint;
+   vector<ossim_float64>         theMinOutputValue;
+   vector<ossim_float64>         theMaxOutputValue;
+
+   // Maps zero based band to histogram band.
+   vector<ossim_uint32>          theBandList;
+   
+   TYPE_DATA
+};
+
+#endif  /* #ifndef ossimHistogramRemapper_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramThreshholdFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramThreshholdFilter.cpp
new file mode 100644
index 0000000000..3b8a714177
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramThreshholdFilter.cpp
@@ -0,0 +1,259 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHistogramThreshholdFilter.cpp,v 1.15 2005/05/09 12:39:40 dburken Exp $
+#include <imaging/tile_sources/ossimHistogramThreshholdFilter.h>
+#include <base/data_types/ossimMultiResLevelHistogram.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimKeyword.h>
+#include <base/common/ossimCommon.h>
+#include <imaging/ossimImageData.h>
+#include <base/context/ossimErrorContext.h>
+
+static const ossimKeyword MIN_VALUE_PERCENT_KW("min_percent",
+                                               "min percentage clip");
+
+static const ossimKeyword MAX_VALUE_PERCENT_KW("max_percent",
+                                               "max percentage value");
+
+
+RTTI_DEF1(ossimHistogramThreshholdFilter, "ossimHistogramThreshholdFilter", ossimImageSourceHistogramFilter)
+   
+ossimHistogramThreshholdFilter::ossimHistogramThreshholdFilter()
+   : ossimImageSourceHistogramFilter(),
+     theMinValuePercent(0.0),
+     theMaxValuePercent(0.0)
+{
+}
+
+ossimHistogramThreshholdFilter::ossimHistogramThreshholdFilter(double minValuePercent,
+                                                               double maxValuePercent,
+                                                               ossimImageSource* inputSource,
+                                                               ossimMultiResLevelHistogram* histogram)
+   : ossimImageSourceHistogramFilter(inputSource, histogram),
+     theMinValuePercent(minValuePercent),
+     theMaxValuePercent(maxValuePercent)
+{
+}
+
+ossimHistogramThreshholdFilter::~ossimHistogramThreshholdFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimHistogramThreshholdFilter::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection) return NULL;
+   
+   ossimRefPtr<ossimImageData> inputTile =
+      theInputConnection->getTile(tileRect, resLevel);
+
+   if(!isSourceEnabled())
+   {
+      return inputTile;
+   }
+   if(inputTile.valid()  &&
+      inputTile->getBuf() &&
+      (inputTile->getDataObjectStatus()!=OSSIM_EMPTY))
+   {
+      switch(inputTile->getScalarType())
+      {
+         case OSSIM_UCHAR:
+         {
+            return runThreshholdStretchAlgorithm((ossim_uint8)0,
+                                                 inputTile);
+         }
+         case OSSIM_USHORT16:
+         case OSSIM_USHORT11:
+         {
+            return runThreshholdStretchAlgorithm((ossim_uint16)0,
+                                                 inputTile);
+         }
+         case OSSIM_SSHORT16:
+         {
+            return runThreshholdStretchAlgorithm(static_cast<ossim_sint16>(0),
+                                                 inputTile);
+         }
+         case OSSIM_DOUBLE:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            return runThreshholdStretchAlgorithm(static_cast<double>(0),
+                                                 inputTile);
+         }
+         case OSSIM_FLOAT:
+         case OSSIM_NORMALIZED_FLOAT:
+         {
+            return runThreshholdStretchAlgorithm(static_cast<float>(0),
+                                                 inputTile);
+         }
+         case OSSIM_SCALAR_UNKNOWN:
+         default:
+         {
+            ossimSetError("ossimHistogramThreshholdFilter",
+                          ossimErrorCodes::OSSIM_ERROR,
+                          "Unknown scalar type");
+            break;
+         }
+      }
+   }
+
+   return inputTile;
+}
+
+
+bool ossimHistogramThreshholdFilter::loadState(const ossimKeywordlist& kwl,
+                                           const char* prefix)
+{
+   if(ossimImageSourceHistogramFilter::loadState(kwl, prefix))
+   {
+      const char* minPercent = kwl.find(prefix, MIN_VALUE_PERCENT_KW);
+      const char* maxPercent = kwl.find(prefix, MAX_VALUE_PERCENT_KW);
+
+      if(minPercent)
+      {
+         theMinValuePercent = ossimString(minPercent).toDouble();
+      }
+      else
+      {
+         theMinValuePercent = 0.0;
+      }
+      if(maxPercent)
+      {
+         theMaxValuePercent = ossimString(maxPercent).toDouble();
+      }
+      else
+      {
+         theMaxValuePercent = 0.0;
+      }
+   }
+   else
+   {
+      return false;
+   }
+
+   return true;
+}
+
+bool ossimHistogramThreshholdFilter::saveState(ossimKeywordlist& kwl,
+                                           const char* prefix)const
+{
+   if(ossimImageSourceHistogramFilter::saveState(kwl, prefix))
+   {
+      kwl.add(prefix,
+              MIN_VALUE_PERCENT_KW,
+              theMinValuePercent,
+              true);
+      kwl.add(prefix,
+              MAX_VALUE_PERCENT_KW,
+              theMaxValuePercent,
+              true);
+   }
+   else
+   {
+      return false;
+   }
+
+   return true;
+}
+
+void ossimHistogramThreshholdFilter::initialize()
+{
+   ossimImageSourceHistogramFilter::initialize();
+}
+
+template <class T>
+ossimRefPtr<ossimImageData> ossimHistogramThreshholdFilter::runThreshholdStretchAlgorithm(T dummyVariable,
+                                                                              ossimRefPtr<ossimImageData>& tile)
+{
+   if(!getHistogram())
+   {
+      return tile;
+   }
+   
+   ossimMultiBandHistogram* histo    = getHistogram()->getMultiBandHistogram(0);
+   if(histo)
+   {
+      ossim_uint32 maxBands = ( (histo->getNumberOfBands() >
+                                 tile->getNumberOfBands())?
+                                tile->getNumberOfBands():
+                                histo->getNumberOfBands());
+      
+      long offsetUpperBound = tile->getHeight()*tile->getWidth();
+
+      for(ossim_uint32 band = 0; band < maxBands; ++band)
+      {
+         ossimHistogram* h  = histo->getHistogram(band);
+         T* buf   = static_cast<T*>(tile->getBuf(band));
+         
+         if(h&&buf)
+         {
+            T np     = static_cast<T>(tile->getNullPix(band));
+            T minPix = static_cast<T>(tile->getMinPix(band));
+            T maxPix = static_cast<T>(tile->getMaxPix(band));
+            double range  = (maxPix - minPix);
+            double maxClip = (h->HighClipVal(theMaxValuePercent/100.0)/(double)h->GetRes());
+            double minClip = (h->LowClipVal(theMinValuePercent/100.0)/(double)h->GetRes());
+            ossim_float64 normPix;
+            double delta   = fabs(maxClip - minClip);
+            if(delta > 0.0)
+            {
+               for(long offset = 0; offset < offsetUpperBound; ++offset)
+               {
+                  if(buf[offset] != np)
+                  {
+                     normPix = ((double)buf[offset]-minPix)/range;
+                     if(normPix <= minClip)
+                     {
+                        buf[offset] = minPix;
+                     }
+                     else if(normPix >= maxClip)
+                     {
+                        buf[offset] = maxPix;
+                     }
+                     else 
+                     {
+                        double t = (normPix - minClip)/delta;
+                        T value = static_cast<T>(minPix + range*t);
+                        buf[offset] = value;
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+      tile->validate();
+   }
+   
+   return tile;
+}
+
+void ossimHistogramThreshholdFilter::setMinValuePercent(double minValue)
+{
+   theMinValuePercent = minValue;
+}
+
+void ossimHistogramThreshholdFilter::setMaxValuePercent(double maxValue)
+{
+   theMaxValuePercent = maxValue;
+}
+
+double ossimHistogramThreshholdFilter::getMinValuePercent()const
+{
+   return theMinValuePercent;
+}
+
+double ossimHistogramThreshholdFilter::getMaxValuePercent()const
+{
+   return theMaxValuePercent;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramThreshholdFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramThreshholdFilter.h
new file mode 100644
index 0000000000..c687292ef3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHistogramThreshholdFilter.h
@@ -0,0 +1,51 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHistogramThreshholdFilter.h,v 1.8 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimHistogramThreshholdFilter_HEADER
+#define ossimHistogramThreshholdFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceHistogramFilter.h>
+
+class ossimHistogramThreshholdFilter : public ossimImageSourceHistogramFilter
+{
+public:
+   ossimHistogramThreshholdFilter();
+   ossimHistogramThreshholdFilter(double minValuePercent,
+                                  double maxValuePercent,
+                                  ossimImageSource* inputSource,
+                                  ossimMultiResLevelHistogram* histogram);
+   virtual ~ossimHistogramThreshholdFilter();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual void setMinValuePercent(double minValue);
+   virtual void setMaxValuePercent(double maxValue);
+   
+   virtual double getMinValuePercent()const;
+   virtual double getMaxValuePercent()const;
+
+   virtual void initialize();
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+protected:
+   
+   double theMinValuePercent;
+   double theMaxValuePercent;
+   template <class T>
+   ossimRefPtr<ossimImageData> runThreshholdStretchAlgorithm(
+      T dummyVariable,
+      ossimRefPtr<ossimImageData>& tile);
+   
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiRemapper.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiRemapper.cpp
new file mode 100644
index 0000000000..e0a1b0e820
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiRemapper.cpp
@@ -0,0 +1,2751 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Remapper to adjust hue, saturation and intensity.
+//
+//*************************************************************************
+// $Id: ossimHsiRemapper.cpp,v 1.34 2005/11/14 21:48:37 dburken Exp $
+
+#include <imaging/tile_sources/ossimHsiRemapper.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/color_space/ossimNormRgbVector.h>
+#include <base/data_types/color_space/ossimHsiVector.h>
+#include <base/context/ossimNotifyContext.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF1(ossimHsiRemapper, "ossimHsiRemapper", ossimImageSourceFilter)
+
+static ossimTrace traceDebug("ossimHsiRemapper:debug");
+
+//***
+// State keywords:
+//***
+static const char MASTER_HUE_OFFSET_KW[] = "hsi_master_hue_offset";
+static const char MASTER_SATURATION_OFFSET_KW[] = "hsi_master_saturation_offset";
+static const char MASTER_INTENSITY_OFFSET_KW[] = "hsi_master_intensity_offset";
+static const char MASTER_INTENSITY_LOW_CLIP_KW[] = "hsi_master_intensity_low_clip";
+static const char MASTER_INTENSITY_HIGH_CLIP_KW[] = "hsi_master_intensity_high_clip";
+
+static const char RED_HUE_OFFSET_KW[] = "hsi_red_hue_offset";
+static const char RED_HUE_LOW_RANGE_KW[] = "hsi_red_hue_low_range";
+static const char RED_HUE_HIGH_RANGE_KW[] = "hsi_red_hue_high_range";
+static const char RED_HUE_BLEND_RANGE_KW[] = "hsi_red_hue_blend_range";
+static const char RED_SATURATION_OFFSET_KW[] = "hsi_red_saturation_offset";
+static const char RED_INTENSITY_OFFSET_KW[] = "hsi_red_intensity_offset";
+
+static const char YELLOW_HUE_OFFSET_KW[] = "hsi_yellow_hue_offset";
+static const char YELLOW_HUE_LOW_RANGE_KW[] = "hsi_yellow_hue_low_range";
+static const char YELLOW_HUE_HIGH_RANGE_KW[] = "hsi_yellow_hue_high_range";
+static const char YELLOW_HUE_BLEND_RANGE_KW[] = "hsi_yellow_hue_blend_range";
+static const char YELLOW_SATURATION_OFFSET_KW[] = "hsi_yellow_saturation_offset";
+static const char YELLOW_INTENSITY_OFFSET_KW[] = "hsi_yellow_intensity_offset";
+
+static const char GREEN_HUE_OFFSET_KW[] = "hsi_green_hue_offset";
+static const char GREEN_HUE_LOW_RANGE_KW[] = "hsi_green_hue_low_range";
+static const char GREEN_HUE_HIGH_RANGE_KW[] = "hsi_green_hue_high_range";
+static const char GREEN_HUE_BLEND_RANGE_KW[] = "hsi_green_hue_blend_range";
+static const char GREEN_SATURATION_OFFSET_KW[] = "hsi_green_saturation_offset";
+static const char GREEN_INTENSITY_OFFSET_KW[] = "hsi_green_intensity_offset";
+
+static const char CYAN_HUE_OFFSET_KW[] = "hsi_cyan_hue_offset";
+static const char CYAN_HUE_LOW_RANGE_KW[] = "hsi_cyan_hue_low_range";
+static const char CYAN_HUE_HIGH_RANGE_KW[] = "hsi_cyan_hue_high_range";
+static const char CYAN_HUE_BLEND_RANGE_KW[] = "hsi_cyan_hue_blend_range";
+static const char CYAN_SATURATION_OFFSET_KW[] = "hsi_cyan_saturation_offset";
+static const char CYAN_INTENSITY_OFFSET_KW[] = "hsi_cyan_intensity_offset";
+
+static const char BLUE_HUE_OFFSET_KW[] = "hsi_blue_hue_offset";
+static const char BLUE_HUE_LOW_RANGE_KW[] = "hsi_blue_hue_low_range";
+static const char BLUE_HUE_HIGH_RANGE_KW[] = "hsi_blue_hue_high_range";
+static const char BLUE_HUE_BLEND_RANGE_KW[] = "hsi_blue_hue_blend_range";
+static const char BLUE_SATURATION_OFFSET_KW[] = "hsi_blue_saturation_offset";
+static const char BLUE_INTENSITY_OFFSET_KW[] = "hsi_blue_intensity_offset";
+
+static const char MAGENTA_HUE_OFFSET_KW[] = "hsi_magenta_hue_offset";
+static const char MAGENTA_HUE_LOW_RANGE_KW[] = "hsi_magenta_hue_low_range";
+static const char MAGENTA_HUE_HIGH_RANGE_KW[] = "hsi_magenta_hue_high_range";
+static const char MAGENTA_HUE_BLEND_RANGE_KW[] = "hsi_magenta_hue_blend_range";
+static const char MAGENTA_SATURATION_OFFSET_KW[] = "hsi_magenta_saturation_offset";
+static const char MAGENTA_INTENSITY_OFFSET_KW[] = "hsi_magenta_intensity_offset";
+
+static const char WHITE_OBJECT_CLIP_KW[] = "hsi_white_object_clip";
+
+static const double DEFAULT_BLEND = 15.0;
+static const double MAX_BLEND     = 30.0;
+
+ossimHsiRemapper::ossimHsiRemapper()
+   :
+      ossimImageSourceFilter      (),  // base class
+      
+      theTile                     (NULL),
+      theBuffer                   (NULL),
+      theNormalizedMinPix         (0.0),
+
+      theMasterHueOffset          (0.0),
+      theMasterSaturationOffset   (0.0),
+      theMasterIntensityOffset    (0.0),
+      theMasterIntensityLowClip   (0.0),
+      theMasterIntensityHighClip  (1.0),
+      
+      theRedHueOffset             (0.0),
+      theRedHueLowRange           (-30.0),
+      theRedHueHighRange          (30.0),
+      theRedHueBlendRange         (DEFAULT_BLEND),
+      theRedSaturationOffset      (0.0),
+      theRedIntensityOffset       (0.0),
+      
+      theYellowHueOffset          (0.0),
+      theYellowHueLowRange        (30.0),
+      theYellowHueHighRange       (90.0),
+      theYellowHueBlendRange      (DEFAULT_BLEND),
+      theYellowSaturationOffset   (0.0),
+      theYellowIntensityOffset    (0.0),
+      
+      theGreenHueOffset           (0.0),
+      theGreenHueLowRange         (90.0),
+      theGreenHueHighRange        (150.0),
+      theGreenHueBlendRange       (DEFAULT_BLEND),
+      theGreenSaturationOffset    (0.0),
+      theGreenIntensityOffset     (0.0),
+      
+      theCyanHueOffset            (0.0),
+      theCyanHueLowRange          (150.0),
+      theCyanHueHighRange         (210.0),
+      theCyanHueBlendRange        (DEFAULT_BLEND),
+      theCyanSaturationOffset     (0.0),
+      theCyanIntensityOffset      (0.0),
+      
+      theBlueHueOffset            (0.0),
+      theBlueHueLowRange          (210.0),
+      theBlueHueHighRange         (270.0),
+      theBlueHueBlendRange        (DEFAULT_BLEND),
+      theBlueSaturationOffset     (0.0),
+      theBlueIntensityOffset      (0.0),
+      
+      theMagentaHueOffset         (0.0),
+      theMagentaHueLowRange       (270.0),
+      theMagentaHueHighRange      (330.0),
+      theMagentaHueBlendRange     (DEFAULT_BLEND),
+      theMagentaSaturationOffset  (0.0),
+      theMagentaIntensityOffset   (0.0),
+
+      theWhiteObjectClip          (1.0)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+
+   // Construction not complete.
+}
+
+ossimHsiRemapper::~ossimHsiRemapper()
+{
+   theTile = NULL;
+   if (theBuffer)
+   {
+      delete [] theBuffer;
+      theBuffer = NULL;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimHsiRemapper::getTile(
+   const ossimIrect& tile_rect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   // Fetch tile from pointer from the input source.
+   ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(
+      tile_rect, resLevel);
+
+   // Check for remap bypass or a null tile return from input:
+   if (!theEnableFlag || !inputTile)
+   {
+      return inputTile;
+   }
+
+   // Check for first time through or size change.
+   if ( !theTile.valid() ||  
+        tile_rect.height() != theTile->getHeight() ||
+        tile_rect.width()  != theTile->getWidth() )
+   {
+      allocate(tile_rect);
+   }
+
+   //---
+   // Set the image rectangle of the tile.
+   // Note that this will resize the tiles buffers if 
+   theTile->setImageRectangle(tile_rect);
+
+   // Get its status.
+   ossimDataObjectStatus tile_status = inputTile->getDataObjectStatus();
+   if ( (tile_status == OSSIM_NULL) || (tile_status == OSSIM_EMPTY) )
+   {
+      theTile->makeBlank();
+      return theTile;
+   }
+
+   double* rgbBuf[3];
+   const ossim_uint32 PPT = theTile->getSizePerBand();  // Pixels Per Tile
+
+   rgbBuf[0] = theBuffer;
+   rgbBuf[1] = &(theBuffer[PPT]);
+   rgbBuf[2] = &(rgbBuf[1][PPT]);
+   
+   switch(inputTile->getNumberOfBands())
+   {
+      case 1:
+      case 2:
+      {
+         // Copy the first band only.
+         inputTile->copyTileBandToNormalizedBuffer(0, rgbBuf[0]);
+         memcpy(rgbBuf[1], rgbBuf[0], PPT*sizeof(double));
+         memcpy(rgbBuf[2], rgbBuf[0], PPT*sizeof(double));
+	 break;
+      }
+      case 3:
+      {
+         inputTile->copyTileToNormalizedBuffer(theBuffer);
+         break;
+      }
+      default:
+      {
+         inputTile->copyTileBandToNormalizedBuffer(0, rgbBuf[0]);
+         inputTile->copyTileBandToNormalizedBuffer(1, rgbBuf[1]);
+         inputTile->copyTileBandToNormalizedBuffer(2, rgbBuf[2]);
+	 break;
+      }
+   }   
+
+   ossimNormRgbVector rgb;
+   ossimHsiVector     hsi;
+   double r = 0.0;
+   double g = 0.0;
+   double b = 0.0;
+   double h = 0.0;
+   double s = 0.0;
+   double i = 0.0;
+   ossim_uint32 idx;
+   // Convert the rgb value to hsi and adjust values.
+   for (idx=0; idx<PPT; ++idx)
+   {
+      r = rgbBuf[0][idx];
+      g = rgbBuf[1][idx];
+      b = rgbBuf[2][idx];
+      
+      rgb = ossimNormRgbVector(r,g,b);
+      hsi = rgb;
+
+      h   = hsi.getH();
+      s   = hsi.getS();
+      i   = hsi.getI();
+      
+      if(i > FLT_EPSILON)
+      {
+         double h_offset = theMasterHueOffset;
+         double s_offset = theMasterSaturationOffset;
+         double i_offset = theMasterIntensityOffset;
+
+         //***
+         // Note:  For the purpose of checking to see if in the red range,
+         //        make the hue negative if it's >= 315.0 and < 360.0.
+         //        The red low and high ranges are stored in the same manner.
+         //***
+         double red_hue  = h;
+         if (red_hue  >= 315.0 && red_hue  < 360.0) red_hue  = red_hue - 360.0;
+                          
+         if ( red_hue >= theRedHueLowRange && red_hue <= theRedHueHighRange)
+         {
+            // Adjust the reds.
+            
+            double bf = 1.0; // blend factor
+            if ( red_hue < (theRedHueLowRange + theRedHueBlendRange) )
+            {
+               bf = (red_hue - theRedHueLowRange) / theRedHueBlendRange;
+            }
+            else if ( red_hue > (theRedHueHighRange - theRedHueBlendRange) )
+            {
+               bf = (theRedHueHighRange - red_hue) / theRedHueBlendRange;
+            }
+            
+            h_offset += (theRedHueOffset        * bf);
+            s_offset += (theRedSaturationOffset * bf);
+            i_offset += (theRedIntensityOffset  * bf);
+         }
+            
+         if (h >= theYellowHueLowRange && h <= theYellowHueHighRange) 
+         {
+            // Adjust the yellows.
+            
+            double bf = 1.0; // blend factor
+            if ( h < (theYellowHueLowRange + theYellowHueBlendRange) )
+            {
+               bf = (h - theYellowHueLowRange) / theYellowHueBlendRange;
+            }
+            else if ( h > (theYellowHueHighRange - theYellowHueBlendRange) )
+            {
+               bf = (theYellowHueHighRange - h) / theYellowHueBlendRange;
+            }
+            
+            h_offset += (theYellowHueOffset        * bf);
+            s_offset += (theYellowSaturationOffset * bf);
+            i_offset += (theYellowIntensityOffset  * bf);
+         }
+         
+         if (h >= theGreenHueLowRange && h <= theGreenHueHighRange) 
+         {
+            // Adjust the greens. 
+
+            double bf = 1.0; // blend factor
+            if ( h < (theGreenHueLowRange + theGreenHueBlendRange) )
+            {
+               bf = (h - theGreenHueLowRange) / theGreenHueBlendRange;
+            }
+            else if ( h > (theGreenHueHighRange - theGreenHueBlendRange) )
+            {
+               bf = (theGreenHueHighRange - h) / theGreenHueBlendRange;
+            }
+            
+            h_offset += (theGreenHueOffset        * bf);
+            s_offset += (theGreenSaturationOffset * bf);
+            i_offset += (theGreenIntensityOffset  * bf);
+         }
+
+         if (h >= theCyanHueLowRange && h <= theCyanHueHighRange) 
+         {
+            // Adjust the cyans.
+            
+            double bf = 1.0; // blend factor
+            if ( h < (theCyanHueLowRange + theCyanHueBlendRange) )
+            {
+               bf = (h - theCyanHueLowRange) / theCyanHueBlendRange;
+            }
+            else if ( h > (theCyanHueHighRange - theCyanHueBlendRange) )
+            {
+               bf = (theCyanHueHighRange - h) / theCyanHueBlendRange;
+            }
+            
+            h_offset += (theCyanHueOffset        * bf);
+            s_offset += (theCyanSaturationOffset * bf);
+            i_offset += (theCyanIntensityOffset  * bf);
+         }
+
+         if (h >= theBlueHueLowRange && h <= theBlueHueHighRange) 
+         {
+            // Adjust the blues.
+            
+            double bf = 1.0; // blend factor
+            if ( h < (theBlueHueLowRange + theBlueHueBlendRange) )
+            {
+               bf = (h - theBlueHueLowRange) / theBlueHueBlendRange;
+            }
+            else if ( h > (theBlueHueHighRange - theBlueHueBlendRange) )
+            {
+               bf = (theBlueHueHighRange - h) / theBlueHueBlendRange;
+            }
+            
+            h_offset += (theBlueHueOffset        * bf);
+            s_offset += (theBlueSaturationOffset * bf);
+            i_offset += (theBlueIntensityOffset  * bf);
+         }
+
+         if (h >= theMagentaHueLowRange && h <= theMagentaHueHighRange) 
+         {
+            // Adjust the magentas.
+            
+            double bf = 1.0; // blend factor
+            if ( h < (theMagentaHueLowRange + theMagentaHueBlendRange) )
+            {
+               bf = (h - theMagentaHueLowRange) / theMagentaHueBlendRange;
+            }
+            else if ( h > (theMagentaHueHighRange - theMagentaHueBlendRange) )
+            {
+               bf = (theMagentaHueHighRange - h) / theMagentaHueBlendRange;
+            }
+            
+            h_offset += (theMagentaHueOffset        * bf);
+            s_offset += (theMagentaSaturationOffset * bf);
+            i_offset += (theMagentaIntensityOffset  * bf);
+         }
+         
+         // Apply the hue offset.
+         h += h_offset;
+
+         // Make sure the hue is between 0 and 360...
+         if (h < 0.0) h += 360.0;
+         else if (h >= 360) h -= 360.0;
+
+         // Apply the saturation offset clamping/clipping to 0.0/1.0.
+         s += s_offset;
+         s = (s > 0.0 ? (s < 1.0 ? s : 1.0) : 0.0);
+         
+         // Apply the intensity offset clamping/clipping to 0.0/1.0.
+         i += i_offset;
+         i = (i > 0.0 ? (i < 1.0 ? i : 1.0) : 0.0);
+
+         // Stretch the intensity channel.
+//          i = (i - theMasterIntensityLowClip) *
+//              ( 1.0 / (theMasterIntensityHighClip -
+//                       theMasterIntensityLowClip) );
+         i = (i - theMasterIntensityLowClip)/(theMasterIntensityHighClip -
+                                              theMasterIntensityLowClip);
+         
+         hsi.setH(h);
+         hsi.setS(s);
+         hsi.setI(i);
+
+         rgb = hsi;
+         
+         r = rgb.getR();
+         g = rgb.getG();
+         b = rgb.getB();
+         if ( (theWhiteObjectClip < 1.0) &&
+              (r > theWhiteObjectClip)   &&
+              (g > theWhiteObjectClip)   &&
+              (b > theWhiteObjectClip) )
+         {
+            r = theWhiteObjectClip;
+            g = theWhiteObjectClip;
+            b = theWhiteObjectClip;
+         }
+         // Do min/max range check and assign back to buffer.
+         rgbBuf[0][idx] = r > theNormalizedMinPix ? (r < 1.0 ? r : 1.0) :
+            theNormalizedMinPix;
+         rgbBuf[1][idx] = g > theNormalizedMinPix ? (g < 1.0 ? g : 1.0) :
+            theNormalizedMinPix;
+         rgbBuf[2][idx] = b > theNormalizedMinPix ? (b < 1.0 ? b : 1.0) :
+            theNormalizedMinPix;
+      } // End of "if(i > FLT_EPSILON)"
+      else
+      {
+         rgbBuf[0][idx] = 0.0;
+         rgbBuf[1][idx] = 0.0;
+         rgbBuf[2][idx] = 0.0;
+      }
+         
+   }  // End of loop through pixels in a tile.
+   // Copy the buffer to the output tile.
+   theTile->copyNormalizedBufferToTile(theBuffer);
+   
+   // Update the tile status.
+   theTile->validate();
+
+   return theTile;
+}
+
+void ossimHsiRemapper::initialize()
+{
+   ossimImageSourceFilter::initialize();
+   if (theTile.valid())
+   {
+      theTile = NULL;
+      if(theBuffer)
+      {
+         delete []theBuffer;
+         theBuffer = NULL;
+      }
+   }
+}
+
+void ossimHsiRemapper::allocate(const ossimIrect& rect)
+{
+   
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,this);
+      theTile->initialize();
+
+      ossim_uint32 width  = rect.width();
+      ossim_uint32 height = rect.height();
+      ossim_uint32 size = width * height * 3; // Buffer always 3 bands.
+      theBuffer = new double[size];
+      memset(theBuffer, '\0', sizeof(double) * size);
+      
+      // Get the minimum normalized pixel value.
+      theNormalizedMinPix = calculateMinNormValue();
+   }
+}
+
+bool ossimHsiRemapper::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   static const char MODULE[] = "ossimHsiRemapper::loadState()";
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " entering..." << endl;
+   }
+
+   // Make a prefix.
+   ossimString tmpPrefix;
+   if (prefix) tmpPrefix += prefix;
+   
+   const char* lookupReturn;
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MASTER_HUE_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setMasterHueOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MASTER_SATURATION_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setMasterSaturationOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MASTER_INTENSITY_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setMasterIntensityOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MASTER_INTENSITY_LOW_CLIP_KW);
+   if(lookupReturn)
+   {
+      setMasterIntensityLowClip(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MASTER_INTENSITY_HIGH_CLIP_KW);
+   if(lookupReturn)
+   {
+      setMasterIntensityHighClip(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), RED_HUE_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setRedHueOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), RED_HUE_LOW_RANGE_KW);
+   if(lookupReturn)
+   {
+      setRedHueLowRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), RED_HUE_HIGH_RANGE_KW);
+   if(lookupReturn)
+   {
+      setRedHueHighRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), RED_HUE_BLEND_RANGE_KW);
+   if(lookupReturn)
+   {
+      setRedHueBlendRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), RED_SATURATION_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setRedSaturationOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), RED_INTENSITY_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setRedIntensityOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), YELLOW_HUE_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setYellowHueOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), YELLOW_HUE_LOW_RANGE_KW);
+   if(lookupReturn)
+   {
+      setYellowHueLowRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), YELLOW_HUE_HIGH_RANGE_KW);
+   if(lookupReturn)
+   {
+      setYellowHueHighRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), YELLOW_HUE_BLEND_RANGE_KW);
+   if(lookupReturn)
+   {
+      setYellowHueBlendRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), YELLOW_SATURATION_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setYellowSaturationOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), YELLOW_INTENSITY_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setYellowIntensityOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), GREEN_HUE_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setGreenHueOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), GREEN_HUE_LOW_RANGE_KW);
+   if(lookupReturn)
+   {
+      setGreenHueLowRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), GREEN_HUE_HIGH_RANGE_KW);
+   if(lookupReturn)
+   {
+      setGreenHueHighRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), GREEN_HUE_BLEND_RANGE_KW);
+   if(lookupReturn)
+   {
+      setGreenHueBlendRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), GREEN_SATURATION_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setGreenSaturationOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), GREEN_INTENSITY_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setGreenIntensityOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), CYAN_HUE_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setCyanHueOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), CYAN_HUE_LOW_RANGE_KW);
+   if(lookupReturn)
+   {
+      setCyanHueLowRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), CYAN_HUE_HIGH_RANGE_KW);
+   if(lookupReturn)
+   {
+      setCyanHueHighRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), CYAN_HUE_BLEND_RANGE_KW);
+   if(lookupReturn)
+   {
+      setCyanHueBlendRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), CYAN_SATURATION_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setCyanSaturationOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), CYAN_INTENSITY_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setCyanIntensityOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), BLUE_HUE_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setBlueHueOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), BLUE_HUE_LOW_RANGE_KW);
+   if(lookupReturn)
+   {
+      setBlueHueLowRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), BLUE_HUE_HIGH_RANGE_KW);
+   if(lookupReturn)
+   {
+      setBlueHueHighRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), BLUE_HUE_BLEND_RANGE_KW);
+   if(lookupReturn)
+   {
+      setBlueHueBlendRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), BLUE_SATURATION_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setBlueSaturationOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), BLUE_INTENSITY_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setBlueIntensityOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MAGENTA_HUE_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setMagentaHueOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MAGENTA_HUE_LOW_RANGE_KW);
+   if(lookupReturn)
+   {
+      setMagentaHueLowRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MAGENTA_HUE_HIGH_RANGE_KW);
+   if(lookupReturn)
+   {
+      setMagentaHueHighRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MAGENTA_HUE_BLEND_RANGE_KW);
+   if(lookupReturn)
+   {
+      setMagentaHueBlendRange(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MAGENTA_SATURATION_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setMagentaSaturationOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), MAGENTA_INTENSITY_OFFSET_KW);
+   if(lookupReturn)
+   {
+      setMagentaIntensityOffset(atof(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(tmpPrefix.c_str(), WHITE_OBJECT_CLIP_KW);
+   if(lookupReturn)
+   {
+      setWhiteObjectClip(atof(lookupReturn));
+   }
+
+   //***
+   // Initialize the base class.  Do this last so that the enable/disable
+   // doesn't get overridden by the "set*" methods.
+   //***
+   ossimImageSourceFilter::loadState(kwl, tmpPrefix.c_str());
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << ""
+         << *this
+         << "\nreturning..."
+         << endl;
+   }
+
+   return true;
+}
+
+bool ossimHsiRemapper::saveState(ossimKeywordlist& kwl,
+                                 const char* prefix) const
+{
+   static const char MODULE[] = "ossimHsiRemapper::saveStateTo()";
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << "entering..." << endl;
+   }
+
+   // Call the base class getStateFrom.
+   ossimImageSourceFilter::saveState(kwl, prefix);
+
+   kwl.add(prefix, MASTER_HUE_OFFSET_KW, theMasterHueOffset);
+
+   kwl.add(prefix, MASTER_SATURATION_OFFSET_KW, theMasterSaturationOffset);
+
+   kwl.add(prefix, MASTER_INTENSITY_OFFSET_KW, theMasterIntensityOffset);
+
+   kwl.add(prefix, MASTER_INTENSITY_LOW_CLIP_KW, theMasterIntensityLowClip);
+
+   kwl.add(prefix, MASTER_INTENSITY_HIGH_CLIP_KW, theMasterIntensityHighClip);
+
+   kwl.add(prefix, RED_HUE_OFFSET_KW, theRedHueOffset);
+
+   kwl.add(prefix, RED_HUE_LOW_RANGE_KW, theRedHueLowRange);
+
+   kwl.add(prefix, RED_HUE_HIGH_RANGE_KW, theRedHueHighRange);
+
+   kwl.add(prefix, RED_HUE_BLEND_RANGE_KW, theRedHueBlendRange);
+
+   kwl.add(prefix, RED_SATURATION_OFFSET_KW, theRedSaturationOffset);
+           
+   kwl.add(prefix, RED_INTENSITY_OFFSET_KW, theRedIntensityOffset);
+
+   kwl.add(prefix, YELLOW_HUE_OFFSET_KW, theYellowHueOffset);
+
+   kwl.add(prefix, YELLOW_HUE_LOW_RANGE_KW, theYellowHueLowRange);
+
+   kwl.add(prefix, YELLOW_HUE_HIGH_RANGE_KW, theYellowHueHighRange);
+           
+   kwl.add(prefix, YELLOW_HUE_BLEND_RANGE_KW, theYellowHueBlendRange);
+
+   kwl.add(prefix, YELLOW_SATURATION_OFFSET_KW, theYellowSaturationOffset);
+
+   kwl.add(prefix, YELLOW_INTENSITY_OFFSET_KW, theYellowIntensityOffset);
+
+   kwl.add(prefix, GREEN_HUE_OFFSET_KW, theGreenHueOffset);
+
+   kwl.add(prefix, GREEN_HUE_LOW_RANGE_KW, theGreenHueLowRange);
+
+   kwl.add(prefix, GREEN_HUE_HIGH_RANGE_KW, theGreenHueHighRange);
+
+   kwl.add(prefix, GREEN_HUE_BLEND_RANGE_KW, theGreenHueBlendRange);
+           
+   kwl.add(prefix, GREEN_SATURATION_OFFSET_KW, theGreenSaturationOffset);
+           
+   kwl.add(prefix, GREEN_INTENSITY_OFFSET_KW, theGreenIntensityOffset);
+
+   kwl.add(prefix, CYAN_HUE_OFFSET_KW, theCyanHueOffset);
+
+   kwl.add(prefix, CYAN_HUE_LOW_RANGE_KW, theCyanHueLowRange);
+
+   kwl.add(prefix, CYAN_HUE_HIGH_RANGE_KW, theCyanHueHighRange);
+           
+   kwl.add(prefix, CYAN_HUE_BLEND_RANGE_KW, theCyanHueBlendRange);
+           
+   kwl.add(prefix, CYAN_SATURATION_OFFSET_KW, theCyanSaturationOffset);
+           
+   kwl.add(prefix, CYAN_INTENSITY_OFFSET_KW, theCyanIntensityOffset);
+
+   kwl.add(prefix, BLUE_HUE_OFFSET_KW, theBlueHueOffset);
+
+   kwl.add(prefix, BLUE_HUE_LOW_RANGE_KW, theBlueHueLowRange);
+
+   kwl.add(prefix, BLUE_HUE_HIGH_RANGE_KW, theBlueHueHighRange);
+
+   kwl.add(prefix, BLUE_HUE_BLEND_RANGE_KW, theBlueHueBlendRange);
+
+   kwl.add(prefix, BLUE_SATURATION_OFFSET_KW, theBlueSaturationOffset);
+           
+   kwl.add(prefix, BLUE_INTENSITY_OFFSET_KW, theBlueIntensityOffset);
+           
+   kwl.add(prefix, MAGENTA_HUE_OFFSET_KW, theMagentaHueOffset);
+           
+   kwl.add(prefix, MAGENTA_HUE_LOW_RANGE_KW, theMagentaHueLowRange);
+           
+   kwl.add(prefix, MAGENTA_HUE_HIGH_RANGE_KW, theMagentaHueHighRange);
+           
+   kwl.add(prefix, MAGENTA_HUE_BLEND_RANGE_KW, theMagentaHueBlendRange);
+           
+   kwl.add(prefix, MAGENTA_SATURATION_OFFSET_KW, theMagentaSaturationOffset);
+
+   kwl.add(prefix, MAGENTA_INTENSITY_OFFSET_KW, theMagentaIntensityOffset);
+
+   kwl.add(prefix, WHITE_OBJECT_CLIP_KW, theWhiteObjectClip);
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << "returning..." << endl;
+   }
+
+   return true;
+}
+
+void ossimHsiRemapper::resetGroup(int color_group)
+{
+   switch (color_group)
+   {
+      case RED:
+         resetRed();
+         break;
+      case YELLOW:
+         resetYellow();
+         break;
+      case GREEN:
+         resetGreen();
+         break;
+      case CYAN:
+         resetCyan();
+         break;
+      case BLUE:
+         resetBlue();
+         break;
+      case MAGENTA:
+         resetMagenta();
+         break;
+      case ALL:
+         resetMaster();
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::setSaturationOffset NOTICE:  Range error!"
+            << endl;
+         break;
+   }
+   verifyEnabled();
+}
+
+void ossimHsiRemapper::resetAll()
+{
+   theMasterHueOffset          = 0.0;
+   theMasterSaturationOffset   = 0.0;
+   theMasterIntensityOffset    = 0.0;
+   theMasterIntensityLowClip   = 0.0;
+   theMasterIntensityHighClip  = 1.0;
+   
+   theRedHueOffset             = 0.0;
+   theRedHueLowRange           = -30.0;
+   theRedHueHighRange          = 30.0;
+   theRedHueBlendRange         = DEFAULT_BLEND;
+   theRedSaturationOffset      = 0.0;
+   theRedIntensityOffset       = 0.0;
+   
+   theYellowHueOffset          = 0.0;
+   theYellowHueLowRange        = 30.0;
+   theYellowHueHighRange       = 90.0;
+   theYellowHueBlendRange      = DEFAULT_BLEND;
+   theYellowSaturationOffset   = 0.0;
+   theYellowIntensityOffset    = 0.0;
+   
+   theGreenHueOffset           = 0.0;
+   theGreenHueLowRange         = 90.0;
+   theGreenHueHighRange        = 150.0;
+   theGreenHueBlendRange       = DEFAULT_BLEND;
+   theGreenSaturationOffset    = 0.0;
+   theGreenIntensityOffset     = 0.0;
+   
+   theCyanHueOffset            = 0.0;
+   theCyanHueLowRange          = 150.0;
+   theCyanHueHighRange         = 210.0;
+   theCyanHueBlendRange        = DEFAULT_BLEND;
+   theCyanSaturationOffset     = 0.0;
+   theCyanIntensityOffset      = 0.0;
+   
+   theBlueHueOffset            = 0.0;
+   theBlueHueLowRange          = 210.0;
+   theBlueHueHighRange         = 270.0;
+   theBlueHueBlendRange        = DEFAULT_BLEND;
+   theBlueSaturationOffset     = 0.0;
+   theBlueIntensityOffset      = 0.0;
+   
+   theMagentaHueOffset         = 0.0;
+   theMagentaHueLowRange       = 270.0;
+   theMagentaHueHighRange      = 330.0;
+   theMagentaHueBlendRange     = DEFAULT_BLEND;
+   theMagentaSaturationOffset  = 0.0;
+   theMagentaIntensityOffset   = 0.0;
+
+   theWhiteObjectClip          = 1.0;
+   
+   disableSource();
+}
+
+void ossimHsiRemapper::resetMaster()
+{
+   theMasterHueOffset          = 0.0;
+   theMasterSaturationOffset   = 0.0;
+   theMasterIntensityOffset    = 0.0;
+   theMasterIntensityLowClip   = 0.0;
+   theMasterIntensityHighClip  = 1.0;
+
+   verifyEnabled();
+}
+
+void ossimHsiRemapper::resetRed()
+{
+   theRedHueOffset             = 0.0;
+   theRedHueLowRange           = -30.0;
+   theRedHueHighRange          = 30.0;
+   theRedHueBlendRange         = DEFAULT_BLEND;
+   theRedSaturationOffset      = 0.0;
+   theRedIntensityOffset       = 0.0;
+
+   verifyEnabled();
+}
+
+void ossimHsiRemapper::resetYellow()
+{
+   theYellowHueOffset          = 0.0;
+   theYellowHueLowRange        = 30.0;
+   theYellowHueHighRange       = 90.0;
+   theYellowHueBlendRange      = DEFAULT_BLEND;
+   theYellowSaturationOffset   = 0.0;
+   theYellowIntensityOffset    = 0.0;
+
+   verifyEnabled();
+}
+
+void ossimHsiRemapper::resetGreen()
+{
+   theGreenHueOffset           = 0.0;
+   theGreenHueLowRange         = 90.0;
+   theGreenHueHighRange        = 150.0;
+   theGreenHueBlendRange       = DEFAULT_BLEND;
+   theGreenSaturationOffset    = 0.0;
+   theGreenIntensityOffset     = 0.0;
+
+   verifyEnabled();
+}
+
+void ossimHsiRemapper::resetCyan()
+{
+   theCyanHueOffset            = 0.0;
+   theCyanHueLowRange          = 150.0;
+   theCyanHueHighRange         = 210.0;
+   theCyanHueBlendRange        = DEFAULT_BLEND;
+   theCyanSaturationOffset     = 0.0;
+   theCyanIntensityOffset      = 0.0;
+
+   verifyEnabled();
+}
+
+void ossimHsiRemapper::resetBlue()
+{
+   theBlueHueOffset            = 0.0;
+   theBlueHueLowRange          = 210.0;
+   theBlueHueHighRange         = 270.0;
+   theBlueHueBlendRange        = DEFAULT_BLEND;
+   theBlueSaturationOffset     = 0.0;
+   theBlueIntensityOffset      = 0.0;
+
+   verifyEnabled();
+}
+
+void ossimHsiRemapper::resetMagenta()
+{
+   theMagentaHueOffset         = 0.0;
+   theMagentaHueLowRange       = 270.0;
+   theMagentaHueHighRange      = 330.0;
+   theMagentaHueBlendRange     = DEFAULT_BLEND;
+   theMagentaSaturationOffset  = 0.0;
+   theMagentaIntensityOffset   = 0.0;
+
+   verifyEnabled();
+}
+
+void ossimHsiRemapper::verifyEnabled()
+{
+   // Start off disabled...
+   disableSource();
+
+   if (!theInputConnection)
+   {
+      //***
+      // Since this filter can be constructed with no input connection do not
+      // output and error, simply return.
+      //***
+      return;
+   }
+      
+   if (theInputConnection->getNumberOfOutputBands() > 3)
+   {
+      // Only work on three band (rgb) images.
+      setErrorStatus();
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::ossimHsiRemapper ERROR:"
+         << "\nRequires an RGB input source!"
+         << "\nInput source has "
+         << theInputConnection->getNumberOfOutputBands()
+         << " bands..."
+         << endl;
+      return;
+   }
+
+   //***
+   // Add all the offsets and the low clips.
+   // If greater than zero enable getTile method.
+   //***
+   double d = theMasterHueOffset         +
+           theMasterSaturationOffset  +
+           theMasterIntensityOffset   +
+           theMasterIntensityLowClip  +
+           theRedHueOffset            +
+           theRedSaturationOffset     +
+           theRedIntensityOffset      +
+           theYellowHueOffset         +
+           theYellowSaturationOffset  +
+           theYellowIntensityOffset   +
+           theGreenHueOffset          +
+           theGreenSaturationOffset   +
+           theGreenIntensityOffset    +
+           theCyanHueOffset           +
+           theCyanSaturationOffset    +
+           theCyanIntensityOffset     +
+           theBlueHueOffset           +
+           theBlueSaturationOffset    +
+           theBlueIntensityOffset     +
+           theMagentaHueOffset        +
+           theMagentaSaturationOffset +
+           theMagentaIntensityOffset;
+   
+   if ( d != 0.0 ||
+        theMasterIntensityHighClip != 1.0 ||
+        theWhiteObjectClip != 1.0 )
+   {
+      enableSource();
+   }
+}
+
+void ossimHsiRemapper::setMasterHueOffset(double offset)
+{
+   if (offset >= -180.0 && offset <= 180.0)
+   {
+      theMasterHueOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMasterHueOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -180.0 and less than"
+         << "\nor equal to 180.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMasterSaturationOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theMasterSaturationOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMasterSaturationOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMasterIntensityOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theMasterIntensityOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMasterIntensityOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMasterIntensityLowClip(double clip)
+{
+   if (clip >= 0.0 && clip < theMasterIntensityHighClip)
+   {
+      theMasterIntensityLowClip = clip;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMasterIntensityClip range error:"
+         << "\nLow clip of " << clip << " is out of range!"
+         << "\nMust be equal to or greater than 0.0 and less than"
+         << "\nthe high clip of " << theMasterIntensityHighClip
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMasterIntensityHighClip(double clip)
+{
+   if (clip <= 1.0 && clip > theMasterIntensityLowClip)
+   {
+      theMasterIntensityHighClip = clip;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMasterIntensityHighClip range error:"
+         << "\nHigh clip of " << clip << " is out of range!"
+         << "\nMust be greater than low clip of "
+         << theMasterIntensityLowClip << " and less than 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setRedHueOffset(double offset)
+{
+   if (offset >= -180.0 && offset <= 180.0)
+   {
+      theRedHueOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setRedHueOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -180.0 and less than"
+         << "\nor equal to 180.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setRedHueLowRange(double range)
+{
+   //***
+   // Default red range: 330 - 30
+   // Allow 315 to 15 as long as it's less than the high range.
+   // Note:  Store the range as a negative if it's between 315 and 360.
+   //***
+   double r  = range;
+   double h  = theRedHueHighRange;
+
+   if (r >= 315.0 && r < 360.0) r = r - 360.0;
+   if (h >= 315.0 && h < 360.0) h = h - 360.0;
+
+   if (r >= -45.0 && r <= 15.0 && r < h)
+   {
+      theRedHueLowRange = r;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setRedHueLow range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setRedHueHighRange(double range)
+{
+   if (range == 360.0) range = 0.0;
+   
+   //***
+   // Default red range: 330 - 30
+   // Allow 345 to 45 as long as it's greater than the low range.
+   // Note:  Store the range as a negative if it's between 345 and 360.
+   //***
+
+   double r = range;
+   double l = theRedHueLowRange;
+
+   if (r >= 315.0 && r < 360.0) r = r - 360.0;
+   if (l >= 315.0 && l < 360.0) l = l - 360.0;
+
+   if (r >= -15.0 && r <= 45 && l < r)
+   {
+      theRedHueHighRange = r;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setRedHueHigh range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setRedHueBlendRange(double range)
+{
+   //***
+   // Allowable range: 0.0 to 30.0 as long as it's not greater than the
+   // half range.  If so snap it to half range.
+   //***
+   if ( range >= 0.0  &&
+        range <= MAX_BLEND )
+   {
+      double half_range = (theRedHueHighRange - theRedHueLowRange) / 2.0;
+
+      if (range <= half_range)
+      {
+         theRedHueBlendRange = range;
+      }
+      else
+      {
+         // Put it in the middle of the range.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHsiRemapper::setRedHueBlendRange range error:"
+            << "\nRange of " << range << " is greater than the full range"
+            << "\ndivided by 2!"
+            << endl;
+         
+         theRedHueBlendRange = half_range;
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setRedHueBlendRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setRedSaturationOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theRedSaturationOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setRedSaturationOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setRedIntensityOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theRedIntensityOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setRedIntensityOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setYellowHueOffset(double offset)
+{
+   if (offset >= -180.0 && offset <= 180.0)
+   {
+      theYellowHueOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setYellowHueOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -180.0 and less than"
+         << "\nor equal to 180.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setYellowHueLowRange(double range)
+{
+   //***
+   // Default yellow range: 30 - 90
+   // Allow 15 to 75 as long as it's less than the high range.
+   //***
+   if ( range >= 15.0 &&
+        range <= 75.0 &&
+        range < theYellowHueHighRange )
+   {
+      theYellowHueLowRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setYellowHueLowRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setYellowHueHighRange(double range)
+{
+   //***
+   // Default yellow range: 30 - 90
+   // Allow 45 to 105 as long as it's greater than the low range.
+   //***
+   if ( range >= 45.0  &&
+        range <= 105.0 &&
+        range > theYellowHueLowRange )
+   {
+      theYellowHueHighRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setYellowHueHighRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setYellowHueBlendRange(double range)
+{
+   //***
+   // Allowable range: 0.0 to 30.0 as long as it's not greater than the
+   // half range.  If so snap it to half range.
+   //***
+   if ( range >= 0.0  &&
+        range <= MAX_BLEND )
+   {
+      double half_range = (theYellowHueHighRange - theYellowHueLowRange) / 2.0;
+      
+      if (range <= half_range)
+      {
+         theYellowHueBlendRange = range;
+      }
+      else
+      {
+         // Put it in the middle of the range.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHsiRemapper::setYellowHueBlendRange range error:"
+            << "\nRange of " << range << " is greater than the full range"
+            << "\ndivided by 2!"
+            << endl;
+         
+         theYellowHueBlendRange = half_range;
+      } 
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setYellowHueBlendRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setYellowSaturationOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theYellowSaturationOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setYellowSaturationOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setYellowIntensityOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theYellowIntensityOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setYellowIntensityOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setGreenHueOffset(double offset)
+{
+   if (offset >= -180.0 && offset <= 180.0)
+   {
+      theGreenHueOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setGreenHueOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -180.0 and less than"
+         << "\nor equal to 180.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setGreenHueLowRange(double range)
+{
+   //***
+   // Default green range:  90 - 150
+   // Allow 75 to 135 as long as it's less than the high range.
+   //***
+
+   if ( range >= 75.0 &&
+        range <= 135.0 &&
+        range < theGreenHueHighRange )
+   {
+      theGreenHueLowRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setGreenHueLowRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setGreenHueHighRange(double range)
+{
+   //***
+   // Default green range:  90 - 150
+   // Allow 105 to 165 as long as it's greater than the low range.
+   //***
+
+   if ( range >= 105.0  &&
+        range <= 165.0 &&
+        range > theGreenHueLowRange )
+   {
+      theGreenHueHighRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setGreenHueHighRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setGreenHueBlendRange(double range)
+{
+   //***
+   // Allowable range: 0.0 to 30.0 as long as it's not greater than the
+   // half range.  If so snap it to half range.
+   //***
+   if ( range >= 0.0  &&
+        range <= MAX_BLEND )
+   {
+      double half_range = (theGreenHueHighRange - theGreenHueLowRange) / 2.0;
+
+      if (range <= half_range)
+      {
+         theGreenHueBlendRange = range;
+      }
+      else
+      {
+         // Put it in the middle of the range.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHsiRemapper::setGreenHueBlendRange range error:"
+            << "\nRange of " << range << " is greater than the full range"
+            << "\ndivided by 2!"
+            << endl;
+         
+         theGreenHueBlendRange = half_range;
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setGreenHueBlendRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setGreenSaturationOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theGreenSaturationOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setGreenSaturationOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setGreenIntensityOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theGreenIntensityOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setGreenIntensityOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setCyanHueOffset(double offset)
+{
+   if (offset >= -180.0 && offset <= 180.0)
+   {
+      theCyanHueOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setCyanHueOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -180.0 and less than"
+         << "\nor equal to 180.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setCyanHueLowRange(double range)
+{
+   //***
+   // Default cyan range: 150 - 210
+   // Allow 135 to 195 as long as it's less than the high range.
+   //***
+   
+   if ( range >= 135.0 &&
+        range <= 195.0 &&
+        range < theCyanHueHighRange )
+   {
+      theCyanHueLowRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setCyanHueLowRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setCyanHueHighRange(double range)
+{
+   //***
+   // Default cyan range: 150 - 210
+   // Allow 165 to 225 as long as it's greater than the low range.
+   //***
+   
+   if ( range >= 165.0 &&
+        range <= 225.0 &&
+        range > theCyanHueLowRange )
+   {
+      theCyanHueHighRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setCyanHueHighRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setCyanHueBlendRange(double range)
+{
+   //***
+   // Allowable range: 0.0 to 30.0 as long as it's not greater than the
+   // half range.  If so snap it to half range.
+   //***
+   if ( range >= 0.0  &&
+        range <= MAX_BLEND )
+   {
+      double half_range = (theCyanHueHighRange - theCyanHueLowRange) / 2.0;
+      
+      if (range <= half_range)
+      {
+         theCyanHueBlendRange = range;
+      }
+      else
+      {
+         // Put it in the middle of the range.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHsiRemapper::setCyanHueBlendRange range error:"
+            << "\nRange of " << range << " is greater than the full range"
+            << "\ndivided by 2!"
+            << endl;
+         
+         theCyanHueBlendRange = half_range;
+      } 
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setCyanHueBlendRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setCyanSaturationOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theCyanSaturationOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setCyanSaturationOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setCyanIntensityOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theCyanIntensityOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setCyanIntensityOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setBlueHueOffset(double offset)
+{
+   if (offset >= -180.0 && offset <= 180.0)
+   {
+      theBlueHueOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setBlueHueOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -180.0 and less than"
+         << "\nor equal to 180.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setBlueHueLowRange(double range)
+{
+   //***
+   // Default blue range: 210 - 270
+   // Allow 195 to 255 as long as it's less than the high range.
+   //***
+   if ( range >= 195.0 &&
+        range <= 255.0 &&
+        range < theBlueHueHighRange )
+   {
+      theBlueHueLowRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setBlueHueLowRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setBlueHueHighRange(double range)
+{
+   //***
+   // Default blue range: 210 - 270
+   // Allow 225 to 285 as long as it's greater than the low range.
+   //***
+   if ( range >= 225.0  &&
+        range <= 285.0 &&
+        range > theBlueHueLowRange )
+   {
+      theBlueHueHighRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setBlueHueHighRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setBlueHueBlendRange(double range)
+{
+   //***
+   // Allowable range: 0.0 to 30.0 as long as it's not greater than the
+   // half range.  If so snap it to half range.
+   //***
+   if ( range >= 0.0  &&
+        range <= MAX_BLEND )
+   {
+      double half_range = (theBlueHueHighRange - theBlueHueLowRange) / 2.0;
+
+      if (range <= half_range)
+      {
+         theBlueHueBlendRange = range;
+      }
+      else
+      {
+         // Put it in the middle of the range.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHsiRemapper::setBlueHueBlendRange range error:"
+            << "\nRange of " << range << " is greater than the full range"
+            << "\ndivided by 2!"
+            << endl;
+         
+         theBlueHueBlendRange = half_range;
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setBlueHueBlendRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setBlueSaturationOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theBlueSaturationOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setBlueSaturationOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setBlueIntensityOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theBlueIntensityOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setBlueIntensityOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMagentaHueOffset(double offset)
+{
+   if (offset >= -180.0 && offset <= 180.0)
+   {
+      theMagentaHueOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMagentaHueOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -180.0 and less than"
+         << "\nor equal to 180.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMagentaHueLowRange(double range)
+{
+   //***
+   // Default magenta range:  270 - 330
+   // Allow 255 to 315 as long as it's less than the high range.
+   //***
+   if ( range >= 255.0 &&
+        range <= 315.0 &&
+        range < theMagentaHueHighRange )
+   {
+      theMagentaHueLowRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMagentaHueLowRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMagentaHueHighRange(double range)
+{
+   //***
+   // Default magenta range:  270 - 330
+   // Allow 285 to 345 as long as it's greater than the low range.
+   //***
+   if ( range >= 285.0  &&
+        range <= 345.0 &&
+        range > theMagentaHueLowRange )
+   {
+      theMagentaHueHighRange = range;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMagentaHueHighRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMagentaHueBlendRange(double range)
+{
+   //***
+   // Allowable range: 0.0 to 30.0 as long as it's not greater than the
+   // half range.  If so snap it to half range.
+   //***
+   if ( range >= 0.0  &&
+        range <= MAX_BLEND )
+   {
+      double half_range = (theMagentaHueHighRange-theMagentaHueLowRange)/2.0;
+
+      if (range <= half_range)
+      {
+         theMagentaHueBlendRange = range;
+      }
+      else
+      {
+         // Put it in the middle of the range.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimHsiRemapper::setMagentaHueBlendRange range error:"
+            << "\nRange of " << range << " is greater than the full range"
+            << "\ndivided by 2!"
+            << endl;
+         
+         theMagentaHueBlendRange = half_range;
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMagentaHueBlendRange range error:"
+         << "\nRange of " << range << " is out of range!"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMagentaSaturationOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theMagentaSaturationOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMagentaSaturationOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+void ossimHsiRemapper::setMagentaIntensityOffset(double offset)
+{
+   if (offset >= -1.0 && offset <= 1.0)
+   {
+      theMagentaIntensityOffset = offset;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimHsiRemapper::setMagentaIntensityOffset range error:"
+         << "\nOffset of " << offset << " is out of range!"
+         << "\nMust be equal to or greater than -1.0 and less than"
+         << "\nor equal to 1.0"
+         << endl;
+   }
+}
+
+double ossimHsiRemapper::calculateMinNormValue()
+{
+   static const char MODULE[] = "ossimHsiRemapper::calculateMinNormValue";
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " Entered..." << endl;
+   }
+   
+   if (!theTile)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << MODULE << " ERROR:"
+         << "\nClass not initialized!"
+         << endl;
+      return 0.0;
+   }
+
+   double min_pix = theTile->getMinPix(0);
+   double max_pix = theTile->getMaxPix(0);
+
+   for (ossim_uint32 band=1; band<theTile->getNumberOfBands(); ++band)
+   {
+      if (min_pix != theTile->getMinPix(band))
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " Warning:"
+            << "\nMixed minimum values for bands..."
+            << endl;
+      }
+      if (max_pix != theTile->getMaxPix(band))
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << " Warning:"
+              << "\nMixed maximum values for bands..."
+              << endl;
+      }
+   }
+
+   if (min_pix < 0.0)
+   {
+      //
+      // Assigning some arbituary number for float data.
+      // This should really come from the normalizer (ossimImageData) of
+      // the data.
+      //
+      return OSSIM_DEFAULT_MIN_PIX_NORM_DOUBLE;
+   }
+
+   return (min_pix / max_pix);
+}
+
+ossim_uint32 ossimHsiRemapper::getNumberOfOutputBands() const
+{
+   if (theEnableFlag) // Always rgb tile out...
+   {
+      return 3;
+   }
+
+   // Filter bypassed so getTile will return input tile.
+   return ossimImageSourceFilter::getNumberOfInputBands();
+}
+
+
+double ossimHsiRemapper::getMasterHueOffset () const
+{
+   return theMasterHueOffset;
+}
+
+double ossimHsiRemapper::getMasterSaturationOffset() const
+{
+   return theMasterSaturationOffset;
+}
+
+double ossimHsiRemapper::getMasterIntensityOffset() const
+{
+   return theMasterIntensityOffset;
+}
+
+double ossimHsiRemapper::getMasterIntensityLowClip() const
+{
+   return theMasterIntensityLowClip;
+}
+
+double ossimHsiRemapper::getMasterIntensityHighClip() const
+{
+   return theMasterIntensityHighClip;
+}
+
+double ossimHsiRemapper::getRedHueOffset() const
+{
+   return theRedHueOffset;
+}
+
+double ossimHsiRemapper::getRedHueLowRange() const
+{
+   return theRedHueLowRange;
+}
+
+double ossimHsiRemapper::getRedHueHighRange() const
+{
+   return theRedHueHighRange;
+}
+
+double ossimHsiRemapper::getRedHueBlendRange() const
+{
+   return theRedHueBlendRange;
+}
+
+double ossimHsiRemapper::getRedSaturationOffset() const
+{
+   return theRedSaturationOffset;
+}
+
+double ossimHsiRemapper::getRedIntensityOffset() const
+{
+   return theRedIntensityOffset;
+}
+
+double ossimHsiRemapper::getYellowHueOffset () const
+{
+   return theYellowHueOffset;
+}
+
+double ossimHsiRemapper::getYellowHueLowRange() const
+{
+   return theYellowHueLowRange;
+}
+
+double ossimHsiRemapper::getYellowHueHighRange() const
+{
+   return theYellowHueHighRange;
+}
+
+double ossimHsiRemapper::getYellowHueBlendRange() const
+{
+   return theYellowHueBlendRange;
+}
+
+double ossimHsiRemapper::getYellowSaturationOffset() const
+{
+   return theYellowSaturationOffset;
+}
+
+double ossimHsiRemapper::getYellowIntensityOffset() const
+{
+   return theYellowIntensityOffset;
+}
+
+double ossimHsiRemapper::getGreenHueOffset () const
+{
+   return theGreenHueOffset;
+}
+
+double ossimHsiRemapper::getGreenHueLowRange() const
+{
+   return theGreenHueLowRange;
+}
+
+double ossimHsiRemapper::getGreenHueHighRange() const
+{
+   return theGreenHueHighRange;
+}
+
+double ossimHsiRemapper::getGreenHueBlendRange() const
+{
+   return theGreenHueBlendRange;
+}
+
+double ossimHsiRemapper::getGreenSaturationOffset() const
+{
+   return theGreenSaturationOffset;
+}
+
+double ossimHsiRemapper::getGreenIntensityOffset() const
+{
+   return theGreenIntensityOffset;
+}
+
+double ossimHsiRemapper::getCyanHueOffset () const
+{
+   return theCyanHueOffset;
+}
+
+double ossimHsiRemapper::getCyanHueLowRange() const
+{
+   return theCyanHueLowRange;
+}
+
+double ossimHsiRemapper::getCyanHueHighRange() const
+{
+   return theCyanHueHighRange;
+}
+
+double ossimHsiRemapper::getCyanHueBlendRange() const
+{
+   return theCyanHueBlendRange;
+}
+
+double ossimHsiRemapper::getCyanSaturationOffset() const
+{
+   return theCyanSaturationOffset;
+}
+
+double ossimHsiRemapper::getCyanIntensityOffset() const
+{
+   return theCyanIntensityOffset;
+}
+
+double ossimHsiRemapper::getBlueHueOffset () const
+{
+   return theBlueHueOffset;
+}
+
+double ossimHsiRemapper::getBlueHueLowRange() const
+{
+   return theBlueHueLowRange;
+}
+
+double ossimHsiRemapper::getBlueHueHighRange() const
+{
+   return theBlueHueHighRange;
+}
+
+double ossimHsiRemapper::getBlueHueBlendRange() const
+{
+   return theBlueHueBlendRange;
+}
+
+double ossimHsiRemapper::getBlueSaturationOffset() const
+{
+   return theBlueSaturationOffset;
+}
+
+double ossimHsiRemapper::getBlueIntensityOffset() const
+{
+   return theBlueIntensityOffset;
+}
+
+double ossimHsiRemapper::getMagentaHueOffset () const
+{
+   return theMagentaHueOffset;
+}
+
+double ossimHsiRemapper::getMagentaHueLowRange() const
+{
+   return theMagentaHueLowRange;
+}
+
+double ossimHsiRemapper::getMagentaHueHighRange() const
+{
+   return theMagentaHueHighRange;
+}
+
+double ossimHsiRemapper::getMagentaHueBlendRange() const
+{
+   return theMagentaHueBlendRange;
+}
+
+double ossimHsiRemapper::getMagentaSaturationOffset() const
+{
+   return theMagentaSaturationOffset;
+}
+
+double ossimHsiRemapper::getMagentaIntensityOffset() const
+{
+   return theMagentaIntensityOffset;
+}
+
+void ossimHsiRemapper::setHueOffset(int color_group, double offset)
+{
+   switch (color_group)
+   {
+      case RED:
+         setRedHueOffset(offset);
+         break;
+      case YELLOW:
+         setYellowHueOffset(offset);
+         break;
+      case GREEN:
+         setGreenHueOffset(offset);
+         break;
+      case CYAN:
+         setCyanHueOffset(offset);
+         break;
+      case BLUE:
+         setBlueHueOffset(offset);
+         break;
+      case MAGENTA:
+         setMagentaHueOffset(offset);
+         break;
+      case ALL:
+         setMasterHueOffset(offset);
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::setHueOffset NOTICE:  Range error!" << endl;
+   }
+}
+
+void ossimHsiRemapper::setHueLowRange(int color_group, double range)
+{
+   switch (color_group)
+   {
+      case RED:
+         setRedHueLowRange(range);
+         break;
+      case YELLOW:
+         setYellowHueLowRange(range);
+         break;
+      case GREEN:
+         setGreenHueLowRange(range);
+         break;
+      case CYAN:
+         setCyanHueLowRange(range);
+         break;
+      case BLUE:
+         setBlueHueLowRange(range);
+         break;
+      case MAGENTA:
+         setMagentaHueLowRange(range);
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::setHueLowRange NOTICE:  Range error!"
+            << endl;
+   }
+}
+
+void ossimHsiRemapper::setHueHighRange(int color_group, double range)
+{
+   switch (color_group)
+   {
+      case RED:
+         setRedHueHighRange(range);
+         break;
+      case YELLOW:
+         setYellowHueHighRange(range);
+         break;
+      case GREEN:
+         setGreenHueHighRange(range);
+         break;
+      case CYAN:
+         setCyanHueHighRange(range);
+         break;
+      case BLUE:
+         setBlueHueHighRange(range);
+         break;
+      case MAGENTA:
+         setMagentaHueHighRange(range);
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::setHueHighRange NOTICE:  Range error!"
+            << endl;
+   }
+}
+
+void ossimHsiRemapper::setHueBlendRange(int color_group, double range)
+{
+   switch (color_group)
+   {
+      case RED:
+         setRedHueBlendRange(range);
+         break;
+      case YELLOW:
+         setYellowHueBlendRange(range);
+         break;
+      case GREEN:
+         setGreenHueBlendRange(range);
+         break;
+      case CYAN:
+         setCyanHueBlendRange(range);
+         break;
+      case BLUE:
+         setBlueHueBlendRange(range);
+         break;
+      case MAGENTA:
+         setMagentaHueBlendRange(range);
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::setHueBlendRange NOTICE:  Range error!"
+            << endl;
+   }
+}
+
+void ossimHsiRemapper::setSaturationOffset(int color_group, double offset)
+{
+   switch (color_group)
+   {
+      case RED:
+         setRedSaturationOffset(offset);
+         break;
+      case YELLOW:
+         setYellowSaturationOffset(offset);
+         break;
+      case GREEN:
+         setGreenSaturationOffset(offset);
+         break;
+      case CYAN:
+         setCyanSaturationOffset(offset);
+         break;
+      case BLUE:
+         setBlueSaturationOffset(offset);
+         break;
+      case MAGENTA:
+         setMagentaSaturationOffset(offset);
+         break;
+      case ALL:
+         setMasterSaturationOffset(offset);
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::setSaturationOffset NOTICE:  Range error!"
+            << endl;
+         break;
+   }
+}
+
+void ossimHsiRemapper::setIntensityOffset(int color_group, double offset)
+{
+   switch (color_group)
+   {
+      case RED:
+         setRedIntensityOffset(offset);
+         break;
+      case YELLOW:
+         setYellowIntensityOffset(offset);
+         break;
+      case GREEN:
+         setGreenIntensityOffset(offset);
+         break;
+      case CYAN:
+         setCyanIntensityOffset(offset);
+         break;
+      case BLUE:
+         setBlueIntensityOffset(offset);
+         break;
+      case MAGENTA:
+         setMagentaIntensityOffset(offset);
+         break;
+      case ALL:
+         setMasterIntensityOffset(offset);
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::setIntensityOffset NOTICE:  Range error!"
+            << endl;
+         break;
+   }
+}
+
+double ossimHsiRemapper::getHueOffset(int color_group) const
+{
+   switch (color_group)
+   {
+      case RED:
+         return getRedHueOffset();
+         break;
+      case YELLOW:
+         return getYellowHueOffset();
+         break;
+      case GREEN:
+         return getGreenHueOffset();
+         break;
+      case CYAN:
+         return getCyanHueOffset();
+         break;
+      case BLUE:
+         return getBlueHueOffset();
+         break;
+      case MAGENTA:
+         return getMagentaHueOffset();
+         break;
+      case ALL:
+         return getMasterHueOffset();
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::getHueOffset NOTICE:  Range error!"
+            << endl;
+         break;
+   }
+   return 0.0;
+}
+
+double ossimHsiRemapper::getHueLowRange(int color_group) const
+{
+   switch (color_group)
+   {
+      case RED:
+         return getRedHueLowRange();
+         break;
+      case YELLOW:
+         return getYellowHueLowRange();
+         break;
+      case GREEN:
+         return getGreenHueLowRange();
+         break;
+      case CYAN:
+         return getCyanHueLowRange();
+         break;
+      case BLUE:
+         return getBlueHueLowRange();
+         break;
+      case MAGENTA:
+         return getMagentaHueLowRange();
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::getHueLowRange NOTICE:  Range error!"
+            << endl;
+         break;
+   }
+   return 0.0;
+}
+
+double ossimHsiRemapper::getHueHighRange(int color_group) const
+{
+   switch (color_group)
+   {
+      case RED:
+         return getRedHueHighRange();
+         break;
+      case YELLOW:
+         return getYellowHueHighRange();
+         break;
+      case GREEN:
+         return getGreenHueHighRange();
+         break;
+      case CYAN:
+         return getCyanHueHighRange();
+         break;
+      case BLUE:
+         return getBlueHueHighRange();
+         break;
+      case MAGENTA:
+         return getMagentaHueHighRange();
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::getHueHighRange NOTICE:  Range error!"
+            << endl;
+         break;
+   }
+   return 0.0;
+}
+
+double ossimHsiRemapper::getHueBlendRange(int color_group) const
+{
+   switch (color_group)
+   {
+      case RED:
+         return getRedHueBlendRange();
+         break;
+      case YELLOW:
+         return getYellowHueBlendRange();
+         break;
+      case GREEN:
+         return getGreenHueBlendRange();
+         break;
+      case CYAN:
+         return getCyanHueBlendRange();
+         break;
+      case BLUE:
+         return getBlueHueBlendRange();
+         break;
+      case MAGENTA:
+         return getMagentaHueBlendRange();
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::getHueBlendRange NOTICE:  Range error!"
+            << endl;
+         break;
+   }
+   return 0.0;
+}
+
+double ossimHsiRemapper::getSaturationOffset(int color_group) const
+{
+   switch (color_group)
+   {
+      case RED:
+         return getRedSaturationOffset();
+         break;
+      case YELLOW:
+         return getYellowSaturationOffset();
+         break;
+      case GREEN:
+         return getGreenSaturationOffset();
+         break;
+      case CYAN:
+         return getCyanSaturationOffset();
+         break;
+      case BLUE:
+         return getBlueSaturationOffset();
+         break;
+      case MAGENTA:
+         return getMagentaSaturationOffset();
+         break;
+      case ALL:
+         return getMasterSaturationOffset();
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::getSaturationOffset NOTICE:  Range error!"
+            << endl;
+         break;
+   }
+   return 0.0;
+}
+
+double ossimHsiRemapper::getIntensityOffset(int color_group) const
+{
+   switch (color_group)
+   {
+      case RED:
+         return getRedIntensityOffset();
+         break;
+      case YELLOW:
+         return getYellowIntensityOffset();
+         break;
+      case GREEN:
+         return getGreenIntensityOffset();
+         break;
+      case CYAN:
+         return getCyanIntensityOffset();
+         break;
+      case BLUE:
+         return getBlueIntensityOffset();
+         break;
+      case MAGENTA:
+         return getMagentaIntensityOffset();
+         break;
+      case ALL:
+         return getMasterIntensityOffset();
+         break;
+      default:
+         ossimNotify(ossimNotifyLevel_NOTICE)
+            << "ossimHsiRemapper::getIntensityOffset NOTICE:  Range error!"
+            << endl;
+         break;
+   }
+   return 0.0;
+}
+
+void ossimHsiRemapper::setWhiteObjectClip(double clip)
+{
+   if ( (clip >= .8) && (clip <= 1.0) )
+   {
+      theWhiteObjectClip = clip;
+      verifyEnabled();
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "HsiRemapper::setWhiteObjectClip range error:"
+         << "\nClip of " << clip << " is out of range!"
+         << "\nMust be between .8 and 1.0"
+         << endl;
+   }
+}
+
+double ossimHsiRemapper::getWhiteObjectClip() const
+{
+   return theWhiteObjectClip;
+}
+
+void ossimHsiRemapper::resetWhiteObjectClip()
+{
+   theWhiteObjectClip = 1.0;
+   verifyEnabled();
+}
+
+ossimString ossimHsiRemapper::getLongName()const
+{
+   return ossimString("HSI Remapper, filter with controls for all HSI(Hue, Saturation, and Intensity) adjustments.");
+}
+
+ossimString ossimHsiRemapper::getShortName()const
+{
+   return ossimString("HSI Remapper");
+}
+
+ostream& ossimHsiRemapper::print(ostream& os) const
+{
+   os << setiosflags(ios::fixed) << setprecision(2)
+      << "\nossimHsiRemapper:"
+      << "\ntheEnableFlag:                " << theEnableFlag
+
+      << "\ntheMasterHueOffset:           " << theMasterHueOffset
+      << "\ntheMasterSaturationOffset:    " << theMasterSaturationOffset
+      << "\ntheMasterIntensityOffset:     " << theMasterIntensityOffset
+      << "\ntheMasterIntensityLowClip:    " << theMasterIntensityLowClip
+      << "\ntheMasterIntensityHighClip:   " << theMasterIntensityHighClip
+      
+      << "\ntheRedHueOffset:              " << theRedHueOffset
+      << "\ntheRedHueLowRange:            " << theRedHueLowRange
+      << "\ntheRedHueHighRange:           " << theRedHueHighRange
+      << "\ntheRedSaturationOffset:       " << theRedSaturationOffset
+      << "\ntheRedIntensityOffset:        " << theRedIntensityOffset
+      
+      << "\ntheYellowHueOffset:           " << theYellowHueOffset
+      << "\ntheYellowHueLowRange:         " << theYellowHueLowRange
+      << "\ntheYellowHueHighRange:        " << theYellowHueHighRange
+      << "\ntheYellowSaturationOffset:    " << theYellowSaturationOffset
+      << "\ntheYellowIntensityOffset:     " << theYellowIntensityOffset
+      
+      << "\ntheGreenHueOffset:            " << theGreenHueOffset
+      << "\ntheGreenHueLowRange:          " << theGreenHueLowRange
+      << "\ntheGreenHueHighRange:         " << theGreenHueHighRange
+      << "\ntheGreenSaturationOffset:     " << theGreenSaturationOffset
+      << "\ntheGreenIntensityOffset:      " << theGreenIntensityOffset
+      
+      << "\ntheCyanHueOffset:             " << theCyanHueOffset
+      << "\ntheCyanHueLowRange:           " << theCyanHueLowRange
+      << "\ntheCyanHueHighRange:          " << theCyanHueHighRange
+      << "\ntheCyanSaturationOffset:      " << theCyanSaturationOffset
+      << "\ntheCyanIntensityOffset:       " << theCyanIntensityOffset
+      
+      << "\ntheBlueHueOffset:             " << theBlueHueOffset
+      << "\ntheBlueHueLowRange:           " << theBlueHueLowRange
+      << "\ntheBlueHueHighRange:          " << theBlueHueHighRange
+      << "\ntheBlueSaturationOffset:      " << theBlueSaturationOffset
+      << "\ntheBlueIntensityOffset:       " << theBlueIntensityOffset
+      
+      << "\ntheMagentaHueOffset:          " << theMagentaHueOffset
+      << "\ntheMagentaHueLowRange:        " << theMagentaHueLowRange
+      << "\ntheMagentaHueHighRange:       " << theMagentaHueHighRange
+      << "\ntheMagentaSaturationOffset:   " << theMagentaSaturationOffset
+      << "\ntheMagentaIntensityOffset:    " << theMagentaIntensityOffset
+
+      << "\ntheWhiteObjectClip:           " << theWhiteObjectClip
+      << endl;
+   
+   return os;
+}
+
+ostream& operator<<(ostream& os, const ossimHsiRemapper& hr)
+{
+   return hr.print(os);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiRemapper.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiRemapper.h
new file mode 100644
index 0000000000..209f0c8f87
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiRemapper.h
@@ -0,0 +1,251 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Remapper to adjust hue, saturation and intensity.
+//
+//*************************************************************************
+// $Id: ossimHsiRemapper.h,v 1.19 2005/11/14 21:48:37 dburken Exp $
+
+#ifndef ossimHsiRemapper_HEADER
+#define ossimHsiRemapper_HEADER
+
+#include "ossimImageSourceFilter.h"
+
+class OSSIMDLLEXPORT ossimHsiRemapper : public ossimImageSourceFilter
+{
+public:
+   enum
+   {
+      RED      = 0,
+      YELLOW   = 1,
+      GREEN    = 2,
+      CYAN     = 3,      
+      BLUE     = 4,
+      MAGENTA  = 5,
+      ALL      = 6
+   };
+   
+   ossimHsiRemapper();
+
+   virtual ~ossimHsiRemapper();
+
+   virtual ossimString getLongName()  const;
+   virtual ossimString getShortName() const;
+
+   virtual void initialize();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                   ossim_uint32 resLevel=0);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   
+   ossim_uint32 getNumberOfOutputBands() const;
+
+   virtual ostream& print(ostream& os) const;
+
+   friend ostream& operator << (ostream& os,  const ossimHsiRemapper& hr);
+   
+   void setHueOffset               (int color_group, double offset);
+   void setHueLowRange             (int color_group, double range);
+   void setHueHighRange            (int color_group, double range);
+   void setHueBlendRange           (int color_group, double range);
+   void setSaturationOffset        (int color_group, double offset);
+   void setIntensityOffset         (int color_group, double offset);
+   
+   void setMasterHueOffset         (double offset);
+   void setMasterSaturationOffset  (double offset);
+   void setMasterIntensityOffset   (double offset);
+   void setMasterIntensityLowClip  (double clip);
+   void setMasterIntensityHighClip (double clip);
+
+   void setRedHueOffset            (double offset);
+   void setRedHueLowRange          (double range);
+   void setRedHueHighRange         (double range);
+   void setRedHueBlendRange        (double range);
+   void setRedSaturationOffset     (double offset);
+   void setRedIntensityOffset      (double offset);
+
+   void setYellowHueOffset         (double offset);
+   void setYellowHueLowRange       (double range);
+   void setYellowHueHighRange      (double range);
+   void setYellowHueBlendRange     (double range);
+   void setYellowSaturationOffset  (double offset);
+   void setYellowIntensityOffset   (double offset);
+
+   void setGreenHueOffset          (double offset);
+   void setGreenHueLowRange        (double range);
+   void setGreenHueHighRange       (double range);
+   void setGreenHueBlendRange      (double range);
+   void setGreenSaturationOffset   (double offset);
+   void setGreenIntensityOffset    (double offset);
+
+   void setCyanHueOffset           (double offset);
+   void setCyanHueLowRange         (double range);
+   void setCyanHueHighRange        (double range);
+   void setCyanHueBlendRange       (double range);
+   void setCyanSaturationOffset    (double offset);
+   void setCyanIntensityOffset     (double offset);
+
+   void setBlueHueOffset           (double offset);
+   void setBlueHueLowRange         (double range);
+   void setBlueHueHighRange        (double range);
+   void setBlueHueBlendRange       (double range);
+   void setBlueSaturationOffset    (double offset);
+   void setBlueIntensityOffset     (double offset);
+
+   void setMagentaHueOffset        (double offset);
+   void setMagentaHueLowRange      (double range);
+   void setMagentaHueHighRange     (double range);
+   void setMagentaHueBlendRange    (double range);
+   void setMagentaSaturationOffset (double offset);
+   void setMagentaIntensityOffset  (double offset);
+
+   double getHueOffset             (int color_group) const;
+   double getHueLowRange           (int color_group) const;
+   double getHueHighRange          (int color_group) const;
+   double getHueBlendRange         (int color_group) const;
+   double getSaturationOffset      (int color_group) const;
+   double getIntensityOffset       (int color_group) const;
+   
+   double getMasterHueOffset          () const;
+   double getMasterSaturationOffset   () const;
+   double getMasterIntensityOffset    () const;
+   double getMasterIntensityLowClip   () const;
+   double getMasterIntensityHighClip  () const;
+   
+   double getRedHueOffset             () const;
+   double getRedHueLowRange           () const;
+   double getRedHueHighRange          () const;
+   double getRedHueBlendRange         () const;
+   double getRedSaturationOffset      () const;
+   double getRedIntensityOffset       () const;
+
+   double getYellowHueOffset          () const;
+   double getYellowHueLowRange        () const;
+   double getYellowHueHighRange       () const;
+   double getYellowHueBlendRange      () const;
+   double getYellowSaturationOffset   () const;
+   double getYellowIntensityOffset    () const;
+
+   double getGreenHueOffset           () const;
+   double getGreenHueLowRange         () const;
+   double getGreenHueHighRange        () const;
+   double getGreenHueBlendRange       () const;
+   double getGreenSaturationOffset    () const;
+   double getGreenIntensityOffset     () const;
+
+   double getCyanHueOffset            () const;
+   double getCyanHueLowRange          () const;
+   double getCyanHueHighRange         () const;
+   double getCyanHueBlendRange        () const;
+   double getCyanSaturationOffset     () const;
+   double getCyanIntensityOffset      () const;
+
+   double getBlueHueOffset            () const;
+   double getBlueHueLowRange          () const;
+   double getBlueHueHighRange         () const;
+   double getBlueHueBlendRange        () const;
+   double getBlueSaturationOffset     () const;
+   double getBlueIntensityOffset      () const;
+
+   double getMagentaHueOffset         () const;
+   double getMagentaHueLowRange       () const;
+   double getMagentaHueHighRange      () const;
+   double getMagentaHueBlendRange     () const;
+   double getMagentaSaturationOffset  () const;
+   double getMagentaIntensityOffset   () const;
+
+   void   setWhiteObjectClip          (double clip);
+   double getWhiteObjectClip          () const;
+   void   resetWhiteObjectClip        ();
+
+   void resetGroup(int color_group);
+   void resetAll();
+   void resetMaster();
+   void resetRed();
+   void resetYellow();
+   void resetGreen();
+   void resetCyan();
+   void resetBlue();
+   void resetMagenta();
+   
+protected:
+   void   allocate(const ossimIrect& rect);
+   void   verifyEnabled();
+   double calculateMinNormValue();
+
+   ossimRefPtr<ossimImageData> theTile;
+   double*                     theBuffer;
+   double                      theNormalizedMinPix;
+
+   double theMasterHueOffset;
+   double theMasterSaturationOffset;
+   double theMasterIntensityOffset;
+   double theMasterIntensityLowClip;
+   double theMasterIntensityHighClip;
+
+   double theRedHueOffset;
+   double theRedHueLowRange;
+   double theRedHueHighRange;
+   double theRedHueBlendRange;
+   double theRedSaturationOffset;
+   double theRedIntensityOffset;
+
+   double theYellowHueOffset;
+   double theYellowHueLowRange;
+   double theYellowHueHighRange;
+   double theYellowHueBlendRange;
+   double theYellowSaturationOffset;
+   double theYellowIntensityOffset;
+
+   double theGreenHueOffset;
+   double theGreenHueLowRange;
+   double theGreenHueHighRange;
+   double theGreenHueBlendRange;
+   double theGreenSaturationOffset;
+   double theGreenIntensityOffset;
+
+   double theCyanHueOffset;
+   double theCyanHueLowRange;
+   double theCyanHueHighRange;
+   double theCyanHueBlendRange;
+   double theCyanSaturationOffset;
+   double theCyanIntensityOffset;
+
+   double theBlueHueOffset;
+   double theBlueHueLowRange;
+   double theBlueHueHighRange;
+   double theBlueHueBlendRange;
+   double theBlueSaturationOffset;
+   double theBlueIntensityOffset;
+
+   double theMagentaHueOffset;
+   double theMagentaHueLowRange;
+   double theMagentaHueHighRange;
+   double theMagentaHueBlendRange;
+   double theMagentaSaturationOffset;
+   double theMagentaIntensityOffset;
+
+   double theWhiteObjectClip;
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiToRgbSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiToRgbSource.cpp
new file mode 100644
index 0000000000..96a5c8c347
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiToRgbSource.cpp
@@ -0,0 +1,147 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHsiToRgbSource.cpp,v 1.8 2005/02/11 15:07:33 dburken Exp $
+#include <imaging/tile_sources/ossimHsiToRgbSource.h>
+#include <imaging/ossimImageData.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/color_space/ossimHsiVector.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF1(ossimHsiToRgbSource, "ossimHsiToRgbSource", ossimImageSourceFilter)
+
+ossimHsiToRgbSource::ossimHsiToRgbSource()
+   :ossimImageSourceFilter(),
+    theBlankTile(NULL),
+    theTile(NULL)
+{
+}
+
+ossimHsiToRgbSource::ossimHsiToRgbSource(ossimImageSource* inputSource)
+   : ossimImageSourceFilter(inputSource),
+    theBlankTile(NULL),
+    theTile(NULL)
+{
+}
+
+ossimHsiToRgbSource::~ossimHsiToRgbSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimHsiToRgbSource::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;  // This filter requires an input.
+   }
+   
+   ossimRefPtr<ossimImageData> inputTile =
+      theInputConnection->getTile(tileRect, resLevel);   
+   if(!isSourceEnabled())
+   {
+      return inputTile;
+   }
+   
+   if(!theTile.valid())
+   {
+      allocate(); // First time through...
+   }
+   
+   if( !inputTile.valid() ||
+       inputTile->getDataObjectStatus() == OSSIM_NULL ||
+       inputTile->getDataObjectStatus() == OSSIM_EMPTY )
+   {
+      theBlankTile->setImageRectangle(tileRect);
+      return theBlankTile;
+   }
+
+   if((inputTile->getNumberOfBands()==3)&&
+      (inputTile->getScalarType()==OSSIM_NORMALIZED_FLOAT)&&
+      (inputTile->getDataObjectStatus()!=OSSIM_NULL))
+   {
+      // Set the origin, resize if needed of the output tile.
+      theTile->setImageRectangle(tileRect);
+      
+      ossim_uint8* outputBands[3];
+      float* inputBands[3];
+      outputBands[0] = static_cast<ossim_uint8*>(theTile->getBuf(0));
+      outputBands[1] = static_cast<ossim_uint8*>(theTile->getBuf(1));
+      outputBands[2] = static_cast<ossim_uint8*>(theTile->getBuf(2));
+      inputBands[0] = static_cast<float*>(inputTile->getBuf(0));
+      inputBands[1] = static_cast<float*>(inputTile->getBuf(1));
+      inputBands[2] = static_cast<float*>(inputTile->getBuf(2));
+      
+      long height = inputTile->getHeight();
+      long width  = inputTile->getWidth();
+      long offset = 0;
+      for(long row = 0; row < height; ++row)
+      {
+         for(long col = 0; col < width; ++col)
+         {
+            ossimHsiVector hsi(inputBands[0][offset],
+                               inputBands[1][offset],
+                               inputBands[2][offset]);
+            
+            ossimRgbVector rgb(hsi);
+            
+            
+            outputBands[0][offset] = rgb.getR();
+            outputBands[1][offset] = rgb.getG();
+            outputBands[2][offset] = rgb.getB();
+            
+            ++offset;
+         }
+      }
+   }
+   else
+   {
+      return inputTile;
+   }
+
+   theTile->validate();
+
+   return theTile;
+}
+
+void ossimHsiToRgbSource::initialize()
+{
+   ossimImageSourceFilter::initialize();
+}
+
+void ossimHsiToRgbSource::allocate()
+{
+   theBlankTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile = (ossimImageData*)theBlankTile->dup();
+   theTile->initialize();
+}
+
+ossimScalarType ossimHsiToRgbSource::getOutputScalarType() const
+{
+   return OSSIM_UCHAR;
+}
+
+double ossimHsiToRgbSource::getNullPixelValue()const
+{
+   return 0.0;
+}
+
+double ossimHsiToRgbSource::getMinPixelValue(ossim_uint32 band)const
+{
+   return OSSIM_DEFAULT_MIN_PIX_UCHAR;
+}
+
+double ossimHsiToRgbSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   return OSSIM_DEFAULT_MAX_PIX_UCHAR;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiToRgbSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiToRgbSource.h
new file mode 100644
index 0000000000..f0cf88e6cd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsiToRgbSource.h
@@ -0,0 +1,49 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHsiToRgbSource.h,v 1.9 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimHsiToRgbSource_HEADER
+#define ossimHsiToRgbSource_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimHsiToRgbSource : public ossimImageSourceFilter
+{
+public:
+   ossimHsiToRgbSource();
+   ossimHsiToRgbSource(ossimImageSource* inputSource);
+   virtual ~ossimHsiToRgbSource();
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual ossimScalarType getOutputScalarType() const;
+
+   virtual double getNullPixelValue()const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   virtual void initialize();
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+   
+   ossimRefPtr<ossimImageData> theBlankTile;
+   ossimRefPtr<ossimImageData> theTile;
+
+   void initializeBuffers(ossimRefPtr<ossimImageData>& data);
+   
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimHsiToRgbSource_HEADER */
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsvToRgbSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsvToRgbSource.cpp
new file mode 100644
index 0000000000..220d813c7d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsvToRgbSource.cpp
@@ -0,0 +1,159 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHsvToRgbSource.cpp,v 1.8 2005/05/10 21:06:47 dburken Exp $
+#include <imaging/tile_sources/ossimHsvToRgbSource.h>
+#include <imaging/ossimImageData.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/color_space/ossimHsvVector.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF1(ossimHsvToRgbSource, "ossimHsvToRgbSource", ossimImageSourceFilter)
+
+ossimHsvToRgbSource::ossimHsvToRgbSource()
+   :ossimImageSourceFilter(),
+    theBlankTile(NULL),
+    theTile(NULL)
+{
+}
+
+ossimHsvToRgbSource::ossimHsvToRgbSource(ossimImageSource* inputSource)
+   : ossimImageSourceFilter(inputSource),
+     theBlankTile(NULL),
+     theTile(NULL)
+{
+}
+
+ossimHsvToRgbSource::~ossimHsvToRgbSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimHsvToRgbSource::getTile(
+   const  ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(theInputConnection)
+   {
+      ossimRefPtr<ossimImageData> imageData =
+         theInputConnection->getTile(tileRect, resLevel);
+
+      if(!imageData.valid()) return theBlankTile;
+      
+      if(!isSourceEnabled())
+      {
+         return imageData;
+      }
+
+      if(!theTile.valid()) allocate();
+      if(!theTile.valid())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Unable to initialize ossimHsvToRgbSource in getTile"
+            << std::endl;
+         return ossimRefPtr<ossimImageData>();
+      }
+      
+      long w  = tileRect.width();
+      long h  = tileRect.height();
+      long tw = theTile->getWidth();
+      long th = theTile->getHeight();
+      
+      theBlankTile->setOrigin(tileRect.ul());
+      theBlankTile->setWidthHeight(w, h);
+      theTile->setWidthHeight(w, h);
+      theTile->setOrigin(tileRect.ul());
+      if( (tw*th) != (w*h))
+      {
+         theTile->initialize();
+      }
+      else
+      {
+         theTile->makeBlank();
+      }
+      
+      if((imageData->getNumberOfBands()==3)&&
+         (imageData->getScalarType()==OSSIM_NORMALIZED_FLOAT)&&
+         (imageData->getDataObjectStatus()!=OSSIM_NULL))
+      {
+         ossim_uint8* outputBands[3];
+         float* inputBands[3];
+         outputBands[0] = static_cast<ossim_uint8*>(theTile->getBuf(0));
+         outputBands[1] = static_cast<ossim_uint8*>(theTile->getBuf(1));
+         outputBands[2] = static_cast<ossim_uint8*>(theTile->getBuf(2));
+         inputBands[0] = static_cast<float*>(imageData->getBuf(0));
+         inputBands[1] = static_cast<float*>(imageData->getBuf(1));
+         inputBands[2] = static_cast<float*>(imageData->getBuf(2));
+         
+         long height = imageData->getHeight();
+         long width  = imageData->getWidth();
+         long offset = 0;
+         for(long row = 0; row < height; ++row)
+         {
+            for(long col = 0; col < width; ++col)
+            {
+               ossimHsvVector hsv(inputBands[0][offset],
+                                  inputBands[1][offset],
+                                  inputBands[2][offset]);
+               
+               ossimRgbVector rgb(hsv);
+
+               outputBands[0][offset] = rgb.getR();
+               outputBands[1][offset] = rgb.getG();
+               outputBands[2][offset] = rgb.getB();
+
+               ++offset;
+            }
+         }
+      }
+      else
+      {
+         return imageData;
+      }
+      theTile->validate();
+      return theTile;
+   }
+   
+   return theBlankTile;
+}
+
+void ossimHsvToRgbSource::initialize()
+{
+   theBlankTile = NULL;
+   theTile      = NULL;
+}
+
+void ossimHsvToRgbSource::allocate()
+{
+   theBlankTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile = (ossimImageData*)theBlankTile->dup();
+   theTile->initialize();
+}
+
+ossimScalarType ossimHsvToRgbSource::getOutputScalarType() const
+{
+   return OSSIM_UINT8;
+}
+
+double ossimHsvToRgbSource::getNullPixelValue()const
+{
+   return 0;
+}
+
+double ossimHsvToRgbSource::getMinPixelValue(ossim_uint32 band)const
+{
+   return OSSIM_DEFAULT_MIN_PIX_UCHAR;
+}
+
+double ossimHsvToRgbSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   return OSSIM_DEFAULT_MAX_PIX_UCHAR;
+}  
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsvToRgbSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsvToRgbSource.h
new file mode 100644
index 0000000000..94b7649ceb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimHsvToRgbSource.h
@@ -0,0 +1,42 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimHsvToRgbSource.h,v 1.6 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimHsvToRgbSource_HEADER
+#define ossimJpegRgbToYCbCrSource_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimHsvToRgbSource : public ossimImageSourceFilter
+{
+public:
+   ossimHsvToRgbSource();
+   ossimHsvToRgbSource(ossimImageSource* inputSource);
+   virtual ~ossimHsvToRgbSource();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual ossimScalarType getOutputScalarType() const;
+   virtual double          getNullPixelValue()const;
+   virtual double          getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double          getMaxPixelValue(ossim_uint32 band=0)const;
+
+   virtual void initialize();
+
+protected:
+
+   virtual void allocate();
+
+   ossimRefPtr<ossimImageData> theBlankTile;
+   ossimRefPtr<ossimImageData> theTile;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageCombiner.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageCombiner.cpp
new file mode 100644
index 0000000000..1cf50affac
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageCombiner.cpp
@@ -0,0 +1,689 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageCombiner.cpp,v 1.70 2005/10/13 20:17:49 gpotts Exp $
+#include <imaging/tile_sources/ossimImageCombiner.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimIrect.h>
+#include <imaging/ossimImageData.h>
+#include <base/common/ossimTrace.h>
+
+using namespace std;
+
+RTTI_DEF2(ossimImageCombiner, "ossimImageCombiner", ossimImageSource, ossimConnectableObjectListener)
+static ossimTrace traceDebug ("ossimImageCombiner:debug");
+
+ossimImageCombiner::ossimImageCombiner()
+   :ossimImageSource(NULL,
+                     0,
+                     0,
+                     false,
+                     false),
+    theLargestNumberOfInputBands(0),
+    theInputToPassThrough(0),
+    theHasDifferentInputs(false),
+    theNormTile(NULL),
+
+    theCurrentIndex(0)
+{
+	theComputeFullResBoundsFlag = true;
+   // until something is set we will just set the blank tile
+   // to a 1 band unsigned char type
+   addListener((ossimConnectableObjectListener*)this);
+}
+ossimImageCombiner::ossimImageCombiner(ossimObject* owner,
+                                       int numberOfInputs,
+                                       int numberOfOutputs,
+                                       bool inputListIsFixedFlag,
+                                       bool outputListIsFixedFlag)
+   :ossimImageSource(owner,
+                     numberOfInputs,
+                     numberOfOutputs,
+                     inputListIsFixedFlag,
+                     outputListIsFixedFlag),
+    theLargestNumberOfInputBands(0),
+    theInputToPassThrough(0),
+    theHasDifferentInputs(false),
+    theNormTile(NULL),
+    theCurrentIndex(0)
+{
+   addListener((ossimConnectableObjectListener*)this);
+   theComputeFullResBoundsFlag = true;
+}
+
+ossimImageCombiner::ossimImageCombiner(const std::vector<ossimImageSource*>& inputSources)
+   :ossimImageSource(NULL,
+                     inputSources.size(),
+                     0,
+                     false,
+                     false),
+    theLargestNumberOfInputBands(0),
+    theInputToPassThrough(0),
+    theHasDifferentInputs(false),
+    theNormTile(NULL),
+    theCurrentIndex(0)
+{
+	theComputeFullResBoundsFlag = true;
+   for(ossim_uint32 index = 0; index < inputSources.size(); ++index)
+   {
+      connectMyInputTo(index, inputSources[index]);
+   }
+   addListener((ossimConnectableObjectListener*)this);
+   initialize();
+}
+
+ossimImageCombiner::~ossimImageCombiner()
+{
+   removeListener((ossimConnectableObjectListener*)this);
+}
+
+void ossimImageCombiner::getDecimationFactor(ossim_uint32 resLevel,
+                                             ossimDpt& result) const
+{
+   if(getInput(0))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(0));
+      if(temp)
+      {
+         temp->getDecimationFactor(resLevel, result);
+      }     
+   }
+   else
+   {
+      result.x = 1;
+      result.y = 1;
+   }
+}
+
+void ossimImageCombiner::getDecimationFactors(vector<ossimDpt>& decimations) const
+{
+   if(getInput(0))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(0));
+      if(temp)
+      {
+         temp->getDecimationFactors(decimations);
+      }     
+   }
+   else
+   {
+      decimations.push_back(ossimDpt(1,1));
+   }
+}
+
+ossim_uint32 ossimImageCombiner::getNumberOfDecimationLevels()const
+{
+   if(getInput(0))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(0));
+      if(temp)
+      {
+         return temp->getNumberOfDecimationLevels();
+      }     
+   }
+   
+   return 1;
+}
+
+ossimIrect ossimImageCombiner::getBoundingRect(ossim_uint32 resLevel)const
+{
+   static const char* MODULE = "ossimImageCombiner::getBoundingRect";
+   ossimIrect result;
+   if(theComputeFullResBoundsFlag)
+   {
+      precomputeBounds();
+   }
+   
+   double scale = 1.0/std::pow(2.0, (double)resLevel);
+   ossimDpt scalar(scale, scale);
+   result.makeNan();
+   
+   ossim_uint32 inputIndex = 0;
+   ossimImageSourceInterface* interface;
+   for(inputIndex = 0;inputIndex < getNumberOfInputs(); ++inputIndex)
+   {
+      interface = PTR_CAST(ossimImageSourceInterface, getInput(inputIndex));
+      if(interface)
+      {
+         ossimIrect rect  = theFullResBounds[inputIndex];
+         if(result.hasNans())
+         {
+            result = rect;
+         }
+         else if(!rect.hasNans())
+         {
+            if(traceDebug())
+            {
+               CLOG << "rect " << inputIndex << " = " << result << endl;
+            }
+            rect = rect*scale;
+            result = result.combine(rect);
+         }
+      }
+   }
+   if(traceDebug())
+   {
+      CLOG << "resulting bounding rect =  " << result << endl;
+   }
+   
+   return result;
+}
+
+ossim_uint32 ossimImageCombiner::getNumberOfInputBands() const
+{
+   return theLargestNumberOfInputBands;
+}
+
+ossimScalarType ossimImageCombiner::getOutputScalarType() const
+{
+   if(getInput(theInputToPassThrough))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(theInputToPassThrough));
+      if(temp)
+      {
+         return temp->getOutputScalarType();
+      }
+   }
+
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+ossim_uint32 ossimImageCombiner::getTileWidth()const
+{
+   if(getInput(theInputToPassThrough))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(theInputToPassThrough));
+      if(temp)
+      {
+         return temp->getTileWidth();
+      }     
+   }
+   
+   return 1;
+}
+
+ossim_uint32 ossimImageCombiner::getTileHeight()const
+{
+   if(getInput(theInputToPassThrough))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(theInputToPassThrough));
+      if(temp)
+      {
+         return temp->getTileHeight();
+      }     
+   }
+   
+   return 1;
+}
+
+double ossimImageCombiner::getNullPixelValue(ossim_uint32 band)const
+{
+   if(getInput(theInputToPassThrough))
+   {
+      ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(theInputToPassThrough));
+      if(temp)
+      {
+         ossim_uint32 bands = temp->getNumberOfOutputBands();
+         if(band < bands)
+         {
+            return temp->getNullPixelValue(band);
+         }
+         else
+         {
+            return temp->getNullPixelValue(bands-1);
+         }
+      }     
+   }
+   
+   return 0.0;
+}
+
+double ossimImageCombiner::getMinPixelValue(ossim_uint32 band)const
+{
+   const char* MODULE = "ossimImageCombiner::getMinPixelValue";
+   
+   if(traceDebug())
+   {
+      CLOG <<"entered..." << endl;
+   }
+   if(!getNumberOfInputs())
+   {
+      return OSSIM_DBL_NAN;
+   }
+   double result = 1.0/DBL_EPSILON;
+   
+   for(ossim_uint32 index = 0; index < getNumberOfInputs();++index)
+   {
+      ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface, getInput(index));
+      if(input)
+      {
+         ossim_uint32 bands = input->getNumberOfOutputBands();
+         double temp = 0;
+         if(band < bands)
+         {
+            temp = input->getMinPixelValue(band);
+         }
+         else
+         {
+            temp = input->getMinPixelValue(bands-1);
+         }
+         
+         if(temp < result)
+         {
+            result = temp;
+         }
+      }
+   }
+   if(traceDebug())
+   {
+      CLOG << "min pixel returned is = " << result;
+   }
+   if(traceDebug())
+   {
+      CLOG <<"leaving..." << endl;
+   }
+   return result;
+}
+
+double ossimImageCombiner::getMaxPixelValue(ossim_uint32 band)const
+{
+   const char* MODULE = "ossimImageCombiner::getMaxPixelValue";
+   if(traceDebug())
+   {
+      CLOG <<"entered..." << endl;
+   }
+   if(!getNumberOfInputs())
+   {
+      return OSSIM_DBL_NAN;
+   }
+   double result = -1.0/DBL_EPSILON;
+   
+   for(ossim_uint32 idx = 0; idx < getNumberOfInputs();++idx)
+   {
+      ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface, getInput(idx));
+      if(input)
+      {
+         ossim_uint32 bands = input->getNumberOfOutputBands();
+         double temp = 0;
+         if(band < bands)
+         {
+            temp = input->getMaxPixelValue(band);
+         }
+         else
+         {
+            temp = input->getMaxPixelValue(bands-1);
+         }
+         if(temp > result)
+         {
+            result = temp;
+         }
+      }
+   }
+
+   if(traceDebug())
+   {
+      CLOG << "max pixel returned is = " << result;
+   }
+   if(traceDebug())
+   {
+      CLOG <<"leaving..." << endl;
+   }
+   
+   return result;
+}
+
+void ossimImageCombiner::initialize()
+{
+   
+   theLargestNumberOfInputBands = 0;
+   theComputeFullResBoundsFlag = true;
+   
+   // now find the largest number of bands
+   //
+   ossim_uint32 size = getNumberOfInputs();
+   ossimScalarType scalarType = OSSIM_SCALAR_UNKNOWN;
+   ossim_uint32 scalarSizeInBytes = 0;
+   theInputToPassThrough = 0;
+   theHasDifferentInputs= false;
+   if(size > 0)
+   {
+      for(ossim_uint32 idx = 0; idx < size; ++idx)
+      {
+         ossimImageSourceInterface* temp = PTR_CAST(ossimImageSourceInterface, getInput(idx));
+         if(temp)
+         {
+            ossim_uint32 numberOfBands = temp->getNumberOfOutputBands();
+            if(numberOfBands > theLargestNumberOfInputBands)
+            {
+               theLargestNumberOfInputBands = numberOfBands;
+            }
+            ossimScalarType current = temp->getOutputScalarType();
+            if(current != scalarType)
+            {
+               if(scalarType == OSSIM_SCALAR_UNKNOWN)
+               {
+                  scalarType = current;
+                  scalarSizeInBytes = ossimGetScalarSizeInBytes(scalarType);
+                  theInputToPassThrough = idx;
+               }
+               else
+               {
+                  theHasDifferentInputs = true;
+                  if(scalarSizeInBytes < ossimGetScalarSizeInBytes(current))
+                  {
+                     scalarType        = current;
+                     scalarSizeInBytes = ossimGetScalarSizeInBytes(current);
+                     theInputToPassThrough = idx;
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+
+bool ossimImageCombiner::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   bool result = ossimImageSource::loadState(kwl, prefix);
+
+   return result;
+}
+
+void ossimImageCombiner::updateRects()
+{
+	theComputeFullResBoundsFlag = true;
+}
+
+ossimRefPtr<ossimImageData> ossimImageCombiner::getNextTile(
+   ossim_uint32 index,
+   const ossimIpt& origin,
+   ossim_uint32 resLevel)
+{
+   theCurrentIndex = (ossim_int32)index - 1;
+   return getNextTile(origin, resLevel);
+}
+
+ossimRefPtr<ossimImageData> ossimImageCombiner::getNextTile(
+   ossim_uint32 index,
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   theCurrentIndex = (ossim_int32)index-1;
+   return getNextTile(tileRect, resLevel);
+}
+
+ossimRefPtr<ossimImageData> ossimImageCombiner::getNextTile(
+   const ossimIpt& origin,
+   ossim_uint32 resLevel)
+{
+   ossim_int32 w = getTileWidth();
+   ossim_int32 h = getTileHeight();
+   
+   return getNextTile(ossimIrect(origin.x,
+                                 origin.y,
+                                 origin.x + w-1,
+                                 origin.y + h-1),
+                      resLevel);
+}
+
+ossimRefPtr<ossimImageData> ossimImageCombiner::getNextTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(theComputeFullResBoundsFlag)
+   {
+      precomputeBounds();
+   }
+   ossim_int32 size = getNumberOfInputs();
+
+   
+   if((theCurrentIndex+1) >= size) return NULL;
+   double scale = 1.0/std::pow(2.0, (double)resLevel);
+   ossimDpt scalar(scale, scale);
+
+   ossimImageSourceInterface* temp = NULL;
+   ossimRefPtr<ossimImageData> result;
+   ossimDataObjectStatus status = OSSIM_NULL;
+   do
+   {
+      ++theCurrentIndex;
+      ossimIrect rect = theFullResBounds[theCurrentIndex];
+      if(!rect.hasNans())
+      {
+         rect = rect * scalar;
+         temp = PTR_CAST(ossimImageSourceInterface,
+                         getInput(theCurrentIndex));
+         if(rect.intersects(tileRect)&&temp)
+         {
+            
+            result = temp->getTile(tileRect, resLevel);
+            status = (result.valid() ?
+                      result->getDataObjectStatus():OSSIM_NULL);
+            if((status == OSSIM_NULL)||
+               (status == OSSIM_EMPTY))
+            {
+               result = NULL;
+            }
+         }
+         else
+         {
+            status = OSSIM_NULL;
+            result = NULL;
+         }
+      }
+      else
+      {
+         status = OSSIM_NULL;
+         result = NULL;
+      }
+
+   }while(!result&&(theCurrentIndex<size));
+
+   return result;
+}
+
+
+ossimRefPtr<ossimImageData> ossimImageCombiner::getNextNormTile(
+   ossim_uint32 index,
+   const ossimIpt& origin,
+   ossim_uint32 resLevel)
+{
+   theCurrentIndex = (ossim_int32)index - 1;
+   return getNextNormTile(origin, resLevel);
+}
+
+ossimRefPtr<ossimImageData> ossimImageCombiner::getNextNormTile(
+   ossim_uint32 index,
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   theCurrentIndex = (ossim_int32)index-1;
+   return getNextNormTile(tileRect, resLevel);
+}
+
+ossimRefPtr<ossimImageData> ossimImageCombiner::getNextNormTile(
+   const ossimIpt& origin,
+   ossim_uint32 resLevel)
+{
+   ossim_int32 w = getTileWidth();
+   ossim_int32 h = getTileHeight();
+   
+   return getNextNormTile(ossimIrect(origin.x,
+                                     origin.y,
+                                     origin.x + w-1,
+                                     origin.y + h-1),
+                          resLevel);
+}
+
+ossimRefPtr<ossimImageData> ossimImageCombiner::getNextNormTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   ossim_int32 size = getNumberOfInputs();
+
+   if(!theNormTile)
+   {
+      theNormTile = new ossimImageData(this,
+                                       OSSIM_NORMALIZED_FLOAT);
+      theNormTile->initialize();
+   }
+   if((theCurrentIndex+1) >= size) return NULL;
+
+   ossimRefPtr<ossimImageData> result = getNextTile(tileRect, resLevel);
+
+   if(result.valid())
+   {
+      theNormTile->setImageRectangleAndBands(result->getImageRectangle(),
+                                             result->getNumberOfBands());
+      result->copyTileToNormalizedBuffer((float*)theNormTile->getBuf());
+
+      theNormTile->setDataObjectStatus(result->getDataObjectStatus());
+      result = theNormTile;
+   }
+   
+   return result;
+}
+
+ossim_uint32 ossimImageCombiner::getNumberOfOverlappingImages(const ossimIrect& rect,
+                                                         ossim_uint32 resLevel)const
+{
+   if(theComputeFullResBoundsFlag)
+   {
+      precomputeBounds();
+   }
+   double scale = 1.0/std::pow(2.0, (double)resLevel);
+   ossimDpt scalar(scale, scale);
+   ossim_uint32 result = 0;
+   ossim_uint32 maxIndex = getNumberOfInputs();
+   for(ossim_uint32 inputIndex = 0; inputIndex < maxIndex; ++inputIndex)
+   {
+      if(!theFullResBounds[inputIndex].hasNans())
+      {
+         ossimIrect boundingRect = theFullResBounds[inputIndex] * scalar;
+         if(rect.intersects(boundingRect))
+         {
+            ++result;
+         }
+      }
+   }
+   
+   return result;
+}
+
+void ossimImageCombiner::getOverlappingImages(std::vector<ossim_uint32>& result,
+					      const ossimIrect& rect,
+                                              ossim_uint32 resLevel)const
+{
+   if(theComputeFullResBoundsFlag)
+   {
+      precomputeBounds();
+   }
+   double scale = 1.0/std::pow(2.0, (double)resLevel);
+   ossimDpt scalar(scale, scale);
+   
+   ossim_uint32 inputIndex;
+   ossimIrect boundingRect;
+   for(inputIndex = 0; inputIndex < getNumberOfInputs(); ++inputIndex)
+   {
+      if(!theFullResBounds[inputIndex].hasNans())
+      {
+         boundingRect = theFullResBounds[inputIndex]*scalar;
+         if(rect.intersects(boundingRect))
+         {
+            result.push_back(inputIndex);
+         }
+      }
+   }
+}
+
+void ossimImageCombiner::connectInputEvent(ossimConnectionEvent& event)
+{
+   initialize();
+}
+
+void ossimImageCombiner::disconnectInputEvent(ossimConnectionEvent& event)
+{ 
+   initialize();
+}
+
+void ossimImageCombiner::propertyEvent(ossimPropertyEvent& event)
+{
+   initialize();
+}
+
+void ossimImageCombiner::refreshEvent(ossimRefreshEvent& event)
+{
+   initialize();
+}
+
+bool ossimImageCombiner::hasDifferentInputs()const
+{
+   return theHasDifferentInputs;
+}
+
+bool ossimImageCombiner::getImageGeometry(ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   if(getInput(0))
+   {
+      ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                                  getInput(0));
+      if(inter)
+      {
+         return inter->getImageGeometry(kwl, prefix);
+      }
+   }
+   
+   return false;
+}
+
+bool ossimImageCombiner::saveState(ossimKeywordlist& kwl,
+                                   const char* prefix) const
+{
+   return ossimImageSource::saveState(kwl, prefix);
+}
+
+bool ossimImageCombiner::canConnectMyInputTo(ossim_int32 inputIndex,
+                                             const ossimConnectableObject* object)const
+{
+   return (object&& PTR_CAST(ossimImageSourceInterface, object));
+}
+
+void ossimImageCombiner::precomputeBounds()const
+{
+   
+   ossim_uint32 inputSize = getNumberOfInputs();
+
+   if(inputSize)
+   {
+      ossimImageSourceInterface* tempInterface=0;
+      if(theFullResBounds.size() != inputSize)
+      {
+         theFullResBounds.resize(inputSize);
+      }
+      for(ossim_uint32 inputIndex = 0; inputIndex < inputSize; ++inputIndex)
+      {
+         tempInterface = PTR_CAST(ossimImageSourceInterface, getInput(inputIndex));
+         if(tempInterface)
+         {
+            theFullResBounds[inputIndex] = tempInterface->getBoundingRect();
+         }
+         else
+         {
+            theFullResBounds[inputIndex].makeNan();
+         }
+      }
+      theComputeFullResBoundsFlag = false;
+   }
+   else
+   {
+      theFullResBounds.clear();
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageCombiner.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageCombiner.h
new file mode 100644
index 0000000000..6f1a9ed310
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageCombiner.h
@@ -0,0 +1,132 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageCombiner.h,v 1.54 2005/10/17 19:18:05 gpotts Exp $
+#ifndef ossimImageCombiner_HEADER
+#define ossimImageCombiner_HEADER
+#include <vector>
+
+#include <imaging/ossimImageSource.h>
+#include <base/common/events/ossimConnectableObjectListener.h>
+#include <base/common/events/ossimPropertyEvent.h>
+
+/**
+ * This will be a base for all combiners.  Combiners take N inputs and
+ * will produce a single output.
+ */
+class OSSIMDLLEXPORT ossimImageCombiner : public ossimImageSource,
+                                          public ossimConnectableObjectListener
+{
+public:
+   ossimImageCombiner();
+   ossimImageCombiner(ossimObject* owner,
+                      int numberOfInputs,
+                      int numberOfOutputs,
+                      bool inputListIsFixedFlag,
+                      bool outputListIsFixedFlag);
+   
+   ossimImageCombiner(const std::vector<ossimImageSource*>& inputSources);
+   virtual ~ossimImageCombiner();   
+
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result) const;
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations) const;
+   virtual ossim_uint32 getNumberOfDecimationLevels() const;
+
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const;
+
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=NULL);
+
+   virtual void initialize();
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=NULL);
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=NULL)const;
+
+   /**
+    * This will go through and precompute the
+    * bounding rects of each input image.
+    */
+   virtual void updateRects();
+
+   /**
+    * Returns the number of bands available from the input.
+    */
+   virtual ossim_uint32 getNumberOfInputBands()const;   
+   virtual ossimScalarType getOutputScalarType() const;
+   virtual ossim_uint32 getTileWidth()const;  
+   virtual ossim_uint32 getTileHeight()const;
+
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+  /**
+   * Used to retrieve the number of overlapping images withint the given
+   * rect.
+   */
+  virtual ossim_uint32 getNumberOfOverlappingImages(const ossimIrect& rect,
+                                                    ossim_uint32 resLevel=0)const;
+
+  /**
+   * Used to populate the result with the index of the overlapping images.
+   */
+  virtual void getOverlappingImages(std::vector<ossim_uint32>& result,
+				    const ossimIrect& rect,
+                                    ossim_uint32 resLevel=0)const;
+   
+   virtual ossimRefPtr<ossimImageData> getNextTile(ossim_uint32 index,
+                                                   const ossimIpt& origin,
+                                                   ossim_uint32 resLevel=0);
+   
+   virtual ossimRefPtr<ossimImageData> getNextTile(const ossimIpt& origin,
+                                                   ossim_uint32 resLevel=0);
+   
+   virtual ossimRefPtr<ossimImageData> getNextTile(ossim_uint32 index,
+                                                   const ossimIrect& origin,
+                                                   ossim_uint32 resLevel=0);
+
+   virtual ossimRefPtr<ossimImageData> getNextTile(const ossimIrect& origin,
+                                                   ossim_uint32 resLevel=0);
+   
+   virtual ossimRefPtr<ossimImageData> getNextNormTile(ossim_uint32 index,
+                                                       const ossimIpt& origin,
+                                                       ossim_uint32 resLevel=0);
+   virtual ossimRefPtr<ossimImageData> getNextNormTile(const ossimIpt& origin,
+                                                       ossim_uint32 resLevel=0);
+   
+   virtual ossimRefPtr<ossimImageData> getNextNormTile(ossim_uint32 index,
+                                                       const ossimIrect& origin,
+                                                       ossim_uint32 resLevel=0);
+   virtual ossimRefPtr<ossimImageData> getNextNormTile(const ossimIrect& origin,
+                                                       ossim_uint32 resLevel=0);
+   
+   virtual bool canConnectMyInputTo(ossim_int32 inputIndex,
+                                    const ossimConnectableObject* object)const;
+         
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+   virtual void propertyEvent(ossimPropertyEvent& event);
+   virtual void refreshEvent(ossimRefreshEvent& event);
+   virtual bool hasDifferentInputs()const;
+   
+protected:
+   ossim_uint32                theLargestNumberOfInputBands;
+   ossim_uint32                theInputToPassThrough;
+   bool                        theHasDifferentInputs;
+   ossimRefPtr<ossimImageData> theNormTile;
+   ossim_int32                 theCurrentIndex;
+   mutable std::vector<ossimIrect>     theFullResBounds;
+   mutable bool                theComputeFullResBoundsFlag;
+   void precomputeBounds()const;
+   
+TYPE_DATA  
+};
+
+#endif /* #ifndef ossimImageCombiner_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageGaussianFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageGaussianFilter.cpp
new file mode 100644
index 0000000000..e1efef7305
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageGaussianFilter.cpp
@@ -0,0 +1,198 @@
+//*******************************************************************
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// class ossimImageGaussianFilter : tile source
+//*******************************************************************
+// $Id: ossimImageGaussianFilter.cpp,v 1.2 2005/09/13 10:46:50 gpotts Exp $
+#include <cmath>
+#include <imaging/tile_sources/ossimImageGaussianFilter.h>
+#include <base/property/ossimNumericProperty.h>
+
+RTTI_DEF1(ossimImageGaussianFilter, "ossimImageGaussianFilter", ossimImageSourceFilter);
+
+//! property names
+static const char* PROPERTYNAME_GAUSSSTD      = "GaussStd";
+
+ossimImageGaussianFilter::ossimImageGaussianFilter()
+   : ossimImageSourceFilter(),
+     theGaussStd(0.5)
+{
+   // ingredients: 
+   // 2x  ConvolutionFilter1D
+   theHF=new ossimConvolutionFilter1D();
+   theVF=new ossimConvolutionFilter1D();
+
+   theHF->setIsHorizontal(true);
+   theVF->setIsHorizontal(false);
+   updateKernels();
+
+   //tie them up
+   theVF->connectMyInputTo(0,theHF);
+}
+
+ossimImageGaussianFilter::~ossimImageGaussianFilter()
+{
+   delete theHF;
+   delete theVF;
+}
+
+void ossimImageGaussianFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property) return;
+
+   if (property->getName() == PROPERTYNAME_GAUSSSTD) {
+      ossimNumericProperty* sProperty = PTR_CAST(ossimNumericProperty,
+                                                     property.get());
+      if(sProperty)
+      {
+         setGaussStd(sProperty->asFloat64());
+      }
+   } else {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimImageGaussianFilter::getProperty(const ossimString& name)const
+{
+   if (name == PROPERTYNAME_GAUSSSTD) {
+      ossimNumericProperty* property = new ossimNumericProperty(name,ossimString::toString(getGaussStd()),1e-13,100.0);
+      property->setCacheRefreshBit();
+      return property;
+   }
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimImageGaussianFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   propertyNames.push_back(PROPERTYNAME_GAUSSSTD);
+}
+
+bool ossimImageGaussianFilter::saveState(ossimKeywordlist& kwl,
+                                          const char* prefix)const
+{   
+   kwl.add(prefix,
+           PROPERTYNAME_GAUSSSTD,
+           theGaussStd,
+           true);   
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+
+bool ossimImageGaussianFilter::loadState(const ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   const char* gs = kwl.find(prefix, PROPERTYNAME_GAUSSSTD);
+   if(gs)
+   {      
+      setGaussStd(ossimString(gs).toUInt32());
+   } else {
+      cerr<<"ossimImageGaussianFilter : warning no "<< PROPERTYNAME_GAUSSSTD<<" in loadState"<<endl;
+   }
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+void ossimImageGaussianFilter::setGaussStd(const ossim_float64& v)
+{
+   theGaussStd = v;
+   updateKernels();
+}
+
+void
+ossimImageGaussianFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+   initializeProcesses();
+}
+
+ossimRefPtr<ossimImageData>
+ossimImageGaussianFilter::getTile(const ossimIrect &tileRect,ossim_uint32 resLevel)
+{
+    if(isSourceEnabled())
+    {
+       return theVF->getTile(tileRect, resLevel);
+    }
+    if(theInputConnection)
+    {
+       return theInputConnection->getTile(tileRect, resLevel);
+    }
+
+    return 0;
+}
+
+void
+ossimImageGaussianFilter::initializeProcesses()
+{
+   theHF->initialize();
+   theVF->initialize();
+}
+
+void
+ossimImageGaussianFilter::connectInputEvent(ossimConnectionEvent &event)
+{
+    ossimImageSourceFilter::connectInputEvent(event);
+    if(getInput())
+    {
+       theHF->connectMyInputTo(0, getInput());
+       initializeProcesses();
+    }
+    else
+    {
+       theHF->disconnectMyInput(0, false, false);
+       initializeProcesses();
+    }
+}
+
+void
+ossimImageGaussianFilter::disconnectInputEvent(ossimConnectionEvent &event)
+{
+    ossimImageSourceFilter::disconnectInputEvent(event);
+    if(getInput())
+    {
+       theHF->connectMyInputTo(0, getInput());
+       initializeProcesses();
+    }
+    else
+    {
+       theHF->disconnectMyInput(0, false, false);
+       initializeProcesses();
+    }
+}
+void
+ossimImageGaussianFilter::updateKernels()
+{
+   //update kernels based on GaussStd value :2.5 sigma on each side
+   // symetric kernel
+   static const ossim_float64 sigmaN = 2.5;
+   ossim_float64 sig22   = getGaussStd()*getGaussStd()*2.0;
+
+   ossim_uint32 halfw   = (ossim_uint32)(std::floor(getGaussStd() * sigmaN + 0.5));
+   ossim_uint32 supsize = 2*halfw + 1;
+
+   //fill with sym. gaussian (unnormalized)
+   vector<ossim_float64> newk(supsize);
+   ossim_float64 sum=1.0;
+   ossim_float64 v;
+   newk[halfw] = 1.0;
+   for(ossim_int32 i=(ossim_int32)halfw; i>0 ;--i) //reverse for summing
+   {
+      newk[halfw + i] = newk[halfw - i] = v = std::exp(-i*i/sig22);
+      sum += 2.0 * v;
+   }
+
+   //normalize
+   ossim_float64   invsum=1.0/sum;
+   for(ossim_uint32 i=0; i<supsize ;++i)
+   {
+      newk[i] *= invsum;
+   }
+
+   //send to 1d conv filters
+   theHF->setKernel(newk);
+   theVF->setKernel(newk);
+   theHF->setCenterOffset(halfw);
+   theVF->setCenterOffset(halfw);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageGaussianFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageGaussianFilter.h
new file mode 100644
index 0000000000..138b22c81f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageGaussianFilter.h
@@ -0,0 +1,54 @@
+//*******************************************************************
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// class ossimImageGaussianFilter : tile source
+//*******************************************************************
+// $Id: ossimImageGaussianFilter.h,v 1.2 2005/09/12 13:39:07 gpotts Exp $
+#ifndef ossimImageGaussianFilter_HEADER
+#define ossimImageGaussianFilter_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <imaging/tile_sources/ossimConvolutionFilter1D.h>
+
+class OSSIM_DLL ossimImageGaussianFilter : public ossimImageSourceFilter
+{
+public:
+   //! own methods
+   ossimImageGaussianFilter();
+   virtual ~ossimImageGaussianFilter();
+
+   inline ossim_float64 getGaussStd()const { return theGaussStd; }
+   void setGaussStd(const ossim_float64& v);
+
+   //! inherited methods
+   virtual void initialize();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect &tileRect,ossim_uint32 resLevel=0);
+
+   virtual void connectInputEvent(ossimConnectionEvent &event);
+   virtual void disconnectInputEvent(ossimConnectionEvent &event);
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,const char* prefix = 0);   
+   virtual bool saveState(ossimKeywordlist& kwl,const char* prefix = 0)const;
+   
+protected:
+   //! protected methods
+   void initializeProcesses();
+   void updateKernels();
+
+   //! parameters
+   ossim_float64 theGaussStd;
+
+   //! subprocesses
+   ossimConvolutionFilter1D* theHF; //horizontal filter
+   ossimConvolutionFilter1D* theVF; //vertical filter
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimImageGaussianFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageMosaic.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageMosaic.cpp
new file mode 100644
index 0000000000..1b51ac096a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageMosaic.cpp
@@ -0,0 +1,532 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: implementation for image mosaic
+//
+//*************************************************************************
+// $Id: ossimImageMosaic.cpp,v 1.65 2005/06/30 15:14:57 gpotts Exp $
+
+#include <imaging/tile_sources/ossimImageMosaic.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimTrace.h>
+static const ossimTrace traceDebug("ossimImageMosaic:debug");
+
+using namespace std;
+
+RTTI_DEF1(ossimImageMosaic, "ossimImageMosaic", ossimImageCombiner)
+ossimImageMosaic::ossimImageMosaic()
+   :ossimImageCombiner(),
+    theTile(NULL)
+{
+}
+
+ossimImageMosaic::ossimImageMosaic(const vector<ossimImageSource*>& inputSources)
+    : ossimImageCombiner(inputSources),
+      theTile(NULL)
+{
+}
+
+
+ossimImageMosaic::~ossimImageMosaic()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimImageMosaic::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   long size = getNumberOfInputs();
+   
+   // If there is only one in the mosaic then just return it.
+   if(size == 1)
+   {
+      return getNextTile(0, tileRect, resLevel);
+   }
+   
+   ossimIpt origin = tileRect.ul();
+   ossim_uint32 w = tileRect.width();
+   ossim_uint32 h = tileRect.height();
+   
+   if(!theTile.valid())
+   {
+      // try to initialize
+      allocate();
+
+      // if we still don't have a buffer
+      // then we will leave
+      if(!theTile.valid())
+      {
+         return ossimRefPtr<ossimImageData>();
+      }
+   }
+   
+   ossim_uint32 tileW = theTile->getWidth();
+   ossim_uint32 tileH = theTile->getHeight();
+   if((w != tileW)||
+      (h != tileH))
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+      }
+   }
+   theTile->setOrigin(origin);
+
+   //---
+   // General Note:
+   //
+   // Note: I will not check for disabled or enabled since we have
+   // no clear way to handle this within a mosaic. The default will be
+   // to do a simple a A over B type mosaic.  Derived classes should
+   // check for the enabled and disabled and always
+   // use this default implementation if they are disabled.
+   //---
+
+   theTile->setOrigin(origin);
+   theTile->makeBlank();
+   switch(theTile->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_uint8>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_uint8>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SINT8:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_sint8>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_sint8>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_FLOAT: 
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<float>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<float>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_uint16>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_uint16>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SSHORT16:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_sint16>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_sint16>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SINT32:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_sint32>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_sint32>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_UINT32:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_uint32>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_uint32>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<double>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<double>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Scalar type = " << theTile->getScalarType()
+            << " Not supported by ossimImageMosaic" << endl;
+      }
+   }
+
+   return ossimRefPtr<ossimImageData>();
+}
+
+void ossimImageMosaic::initialize()
+{
+  ossimImageCombiner::initialize();
+  theTile = NULL;
+}
+
+void ossimImageMosaic::allocate()
+{
+   theTile = NULL;
+   
+   if( (getNumberOfInputs() > 0) && getInput(0) )
+   {
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+      theTile->initialize();
+   }
+}
+
+bool ossimImageMosaic::saveState(ossimKeywordlist& kwl,
+                                 const char* prefix)const
+{
+   return ossimImageCombiner::saveState(kwl, prefix);
+}
+
+bool ossimImageMosaic::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   return ossimImageCombiner::loadState(kwl, prefix);
+}
+
+template <class T> ossimRefPtr<ossimImageData> ossimImageMosaic::combineNorm(
+   T,// dummy template variable 
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> destination = theTile;
+   
+   ossimRefPtr<ossimImageData> currentImageData =
+      getNextNormTile(0, tileRect, resLevel);
+      
+   if(!currentImageData)
+   {
+      return currentImageData;
+   }
+   
+   float** srcBands        = new float*[theLargestNumberOfInputBands];
+   float* srcBandsNullPix  = new float[theLargestNumberOfInputBands];
+   T** destBands = new T*[theLargestNumberOfInputBands];
+   T* destBandsNullPix = new T[theLargestNumberOfInputBands];
+   T* destBandsMinPix = new T[theLargestNumberOfInputBands];
+   T* destBandsMaxPix = new T[theLargestNumberOfInputBands];
+      
+   ossim_uint32 band;
+   ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
+   ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
+   for(band = 0; band < minNumberOfBands; ++band)
+   {
+      srcBands[band]  = static_cast<float*>(currentImageData->getBuf(band));
+      srcBandsNullPix[band]  = static_cast<float>(currentImageData->getNullPix(band));
+      
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+      destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
+      destBandsMinPix[band] = static_cast<T>(theTile->getMinPix(band));
+      destBandsMaxPix[band] = static_cast<T>(theTile->getMaxPix(band));
+   }
+   // if the src is smaller than the destination in number
+   // of bands we will just duplicate the last band.
+   for(;band < theLargestNumberOfInputBands; ++band)
+   {
+      srcBands[band]  = static_cast<float*>(srcBands[minNumberOfBands - 1]);
+      srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(minNumberOfBands - 1));
+      
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+      destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
+      destBandsMinPix[band] = static_cast<T>(theTile->getMinPix(band));
+      destBandsMaxPix[band] = static_cast<T>(theTile->getMaxPix(band));
+   }
+   // most of the time we will not overlap so let's
+   // copy the first tile into destination and check later.
+   //
+   ossim_uint32 tempBandIdx = 0;
+   for(band = 0; band < theTile->getNumberOfBands();++band)
+   {
+      if(band < currentImageData->getNumberOfBands())
+      {
+         theTile->copyNormalizedBufferToTile(band,
+                                             (float*)currentImageData->getBuf(band));
+         ++tempBandIdx;
+      }
+      else
+      {
+         if(tempBandIdx)
+         {
+            theTile->copyNormalizedBufferToTile(band,
+                                                (float*)currentImageData->getBuf(tempBandIdx-1));
+         }
+      }
+   }
+   destination->validate();
+   
+   currentImageData = getNextNormTile(tileRect, resLevel);
+
+   while(currentImageData.valid())
+   {  
+      ossim_uint32 minNumberOfBands           = currentImageData->getNumberOfBands();
+      ossimDataObjectStatus currentStatus     = currentImageData->getDataObjectStatus();
+      ossimDataObjectStatus destinationStatus = destination->getDataObjectStatus();
+      
+      if(destinationStatus == OSSIM_FULL)
+      {
+         return destination;
+      }
+      for(band = 0; band < minNumberOfBands; ++band)
+      {
+         srcBands[band]        = static_cast<float*>(currentImageData->getBuf(band));
+         srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(band));
+      }
+      // if the src is smaller than the destination in number
+      // of bands we will just duplicate the last band.
+      for(;band < theLargestNumberOfInputBands; ++band)
+      {
+         srcBands[band] = srcBands[minNumberOfBands - 1];
+         srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
+      }
+
+      if((destinationStatus == OSSIM_EMPTY)&&
+         (currentStatus     != OSSIM_EMPTY)&&
+         (currentStatus     != OSSIM_NULL))
+      {
+         ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
+         for(band=0; band < theLargestNumberOfInputBands; ++band)
+         {
+            float delta = destBandsMaxPix[band] - destBandsMinPix[band];
+            float minP  = destBandsMinPix[band];
+            for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+            {
+               destBands[band][offset] = (T)( minP + delta*srcBands[band][offset]);
+            }
+         }
+      }
+      else if((destinationStatus == OSSIM_PARTIAL)&&
+              (currentStatus     != OSSIM_EMPTY)&&
+              (currentStatus     != OSSIM_NULL))
+      {
+         for(band = 0; band < theLargestNumberOfInputBands; ++band)
+         {
+            
+            float delta = destBandsMaxPix[band] - destBandsMinPix[band];
+            float minP  = destBandsMinPix[band];
+            for(ossim_uint32 offset = 0;
+                offset < upperBound;
+                ++offset)
+            {
+               
+               if(destBands[band][offset] == destBandsNullPix[band])
+               {
+                  destBands[band][offset] = (T)(minP + delta*srcBands[band][offset]);
+               }
+            }
+         }
+      }
+      destination->validate();
+      
+      currentImageData = getNextNormTile(tileRect, resLevel);
+   }
+   // Cleanup...
+   delete [] srcBands;
+   delete [] destBands;
+   delete [] srcBandsNullPix;
+   delete [] destBandsNullPix;
+   delete [] destBandsMinPix;
+   delete [] destBandsMaxPix;
+   return destination;
+}
+
+template <class T> ossimRefPtr<ossimImageData> ossimImageMosaic::combine(
+   T,// dummy template variable 
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> destination = theTile;
+
+   ossimRefPtr<ossimImageData> currentImageData =
+      getNextTile(0, tileRect, resLevel);
+      
+   T** srcBands         = new T*[theLargestNumberOfInputBands];
+   T*  srcBandsNullPix  = new T[theLargestNumberOfInputBands];
+   T** destBands        = new T*[theLargestNumberOfInputBands];
+   T*  destBandsNullPix = new T[theLargestNumberOfInputBands];
+      
+   ossim_uint32 band;
+   ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
+   ossim_uint32 bandIndex  = 0;
+   if(!currentImageData)
+   {
+      return currentImageData;
+   }
+   ossim_uint32 offset=0;
+   ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
+   for(band = 0; band < minNumberOfBands; ++band)
+   {
+      srcBands[band]  = static_cast<T*>(currentImageData->getBuf(band));
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+      srcBandsNullPix[band]  = static_cast<T>(currentImageData->getNullPix(band));
+      destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
+   }
+   // if the src is smaller than the destination in number
+   // of bands we will just duplicate the last band.
+   for(;band < theLargestNumberOfInputBands; ++band)
+   {
+      srcBands[band]  = static_cast<T*>(srcBands[minNumberOfBands - 1]);
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+      srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
+      destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
+   }
+   // most of the time we will not overlap so let's
+   // copy the first tile into destination and check later.
+   //
+   for(band = 0; band < theTile->getNumberOfBands();++band)
+   {
+      T* destBand = destBands[band];
+      T* srcBand  = srcBands[band];
+      if(destBand&&srcBand)
+      {
+         for(offset = 0; offset < upperBound;++offset)
+         {
+            *destBand = *srcBand;
+            ++srcBand; ++destBand;
+         }
+      }
+   }
+   destination->setDataObjectStatus(currentImageData->getDataObjectStatus());
+
+   currentImageData = getNextTile(tileRect,
+                                  resLevel);
+
+   while(currentImageData.valid())
+   {  
+      ossim_uint32 minNumberOfBands           = currentImageData->getNumberOfBands();
+      ossimDataObjectStatus currentStatus     = currentImageData->getDataObjectStatus();
+      ossimDataObjectStatus destinationStatus = destination->getDataObjectStatus();
+      
+      if(destinationStatus == OSSIM_FULL)
+      {
+         return destination;
+      }
+      for(band = 0; band < minNumberOfBands; ++band)
+      {
+         srcBands[band]        = static_cast<T*>(currentImageData->getBuf(band));
+         srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(band));
+      }
+      // if the src is smaller than the destination in number
+      // of bands we will just duplicate the last band.
+      for(;band < theLargestNumberOfInputBands; ++band)
+      {
+         srcBands[band] = srcBands[minNumberOfBands - 1];
+         srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
+      }
+
+      if((destinationStatus == OSSIM_EMPTY)&&
+         (currentStatus     != OSSIM_EMPTY)&&
+         (currentStatus     != OSSIM_NULL))
+      {
+         ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
+         for(ossim_uint32 band=0; band < theLargestNumberOfInputBands; ++band)
+         {
+            for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+            {
+               destBands[band][offset] = srcBands[band][offset];
+            }
+         }
+      }
+      else if((destinationStatus == OSSIM_PARTIAL)&&
+              (currentStatus     != OSSIM_EMPTY)&&
+              (currentStatus     != OSSIM_NULL))
+      {
+         for(bandIndex = 0; bandIndex < theLargestNumberOfInputBands; ++bandIndex)
+         {
+            
+            for(ossim_uint32 offset = 0;
+                offset < upperBound;
+                ++offset)
+            {
+               if(destBands[bandIndex][offset] == destBandsNullPix[bandIndex])
+               {
+                  destBands[bandIndex][offset] = srcBands[bandIndex][offset];
+               }
+            }
+         }
+      }
+      destination->validate();
+      
+      currentImageData = getNextTile(tileRect, resLevel);
+   }
+   // Cleanup...
+   delete [] srcBands;
+   delete [] destBands;
+   delete [] srcBandsNullPix;
+   delete [] destBandsNullPix;
+   return destination;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageMosaic.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageMosaic.h
new file mode 100644
index 0000000000..c11dab6103
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageMosaic.h
@@ -0,0 +1,73 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageMosaic.h,v 1.28 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimImageMosaic_HEADER
+#define ossimImageMosaic_HEADER
+#include <vector>
+using namespace std;
+
+#include <imaging/tile_sources/ossimImageCombiner.h>
+
+
+/**
+ * An image mosaic is a simple combiner that will
+ * just do a simple mosaic.  It just checks NULL pix values until it finds a
+ * pixel that is not empty and copies it out to the output.  The list will
+ * have same size tiles and have the same number of bands.
+ */
+class OSSIMDLLEXPORT ossimImageMosaic : public ossimImageCombiner
+{
+public:
+   ossimImageMosaic();
+   ossimImageMosaic(const std::vector<ossimImageSource*>& inputSources);
+   virtual ~ossimImageMosaic();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual void initialize();
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+   
+   ossimRefPtr<ossimImageData> theTile;
+
+   template <class T> ossimRefPtr<ossimImageData> combine(
+      T, // dummy template variable not used
+      const ossimIrect& tileRect,
+      ossim_uint32 resLevel=0);
+   template <class T> ossimRefPtr<ossimImageData> combineNorm(
+      T, // dummy template variable not used
+      const ossimIrect& tileRect,
+      ossim_uint32 resLevel=0);
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimImageMosaic_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageRenderer.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageRenderer.cpp
new file mode 100644
index 0000000000..7cdfe53c26
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageRenderer.cpp
@@ -0,0 +1,1866 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimImageRenderer.cpp,v 1.259 2006/01/11 13:37:49 gpotts Exp $
+
+#include <iostream>
+using namespace std;
+
+#include <imaging/tile_sources/ossimImageRenderer.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDpt3d.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/events/ossimProcessProgressEvent.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimConnectableContainerInterface.h>
+#include <base/common/ossimViewController.h>
+#include <base/property/ossimStringProperty.h>
+#include <base/property/ossimNumericProperty.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/filters/ossimDiscrete3x3HatFilter.h>
+#include <imaging/filters/ossimDiscreteNearestNeighbor.h>
+#include <imaging/resample/ossimFilterResampler.h>
+#include <imaging/resample/ossimResampler.h>
+#include <projections/ossimImageViewTransform.h>
+#include <projections/ossimImageViewProjectionTransform.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/factory/ossimImageViewTransformFactory.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimImageRenderer.cpp,v 1.259 2006/01/11 13:37:49 gpotts Exp $";
+#endif
+
+static ossimTrace traceDebug("ossimImageRenderer:debug");
+
+RTTI_DEF2(ossimImageRenderer, "ossimImageRenderer", ossimImageSourceFilter, ossimViewInterface);
+
+
+void ossimImageRenderer::ossimRendererSubRectInfo::splitView(ossimImageViewTransform* transform,
+                                                             ossimRendererSubRectInfo& ulRect,
+                                                             ossimRendererSubRectInfo& urRect,
+                                                             ossimRendererSubRectInfo& lrRect,
+                                                             ossimRendererSubRectInfo& llRect)const
+{
+#if 0
+   ossimNotify(ossimNotifyLevel_DEBUG)
+      << "ulRect = " << ulRect
+      << "\nurRect = " << urRect
+      << "\nlrRect = " << lrRect
+      << "\nllRect = " << llRect << endl;
+#endif
+   
+   ossimIrect vrect(theVul,
+                    theVur,
+                    theVlr,
+                    theVll);
+   
+   ossimIrect tempUlRect;
+   ossimIrect tempUrRect;
+   ossimIrect tempLrRect;
+   ossimIrect tempLlRect;
+   
+   if((vrect.width() == 1)&&
+      (vrect.height() == 1))
+   {
+      tempUlRect = vrect;
+      tempUrRect = vrect;
+      tempLrRect = vrect;
+      tempLlRect = vrect;
+   }
+   else
+   {
+      ossim_int32 w  = vrect.width();
+      ossim_int32 h  = vrect.height();
+      ossim_int32 w2 = w>>1;
+      ossim_int32 h2 = h>>1;
+      
+      if((w%2) == 0) // if even
+      {
+         if((h%2) == 0) // if even
+         {
+            tempUlRect = ossimIrect(theVul.x,
+                                    theVul.y,
+                                    theVul.x + (w2 - 1),
+                                    theVul.y + (h2 - 1));
+            
+            tempUrRect = ossimIrect(theVul.x + w2,
+                                    theVul.y,
+                                    theVul.x + w2 + (w2 - 1),
+                                    theVul.y + (h2 - 1));
+            
+            tempLrRect = ossimIrect(theVul.x + w2,
+                                    theVul.y + h2,
+                                    theVul.x + w2 + (w2 - 1),
+                                    theVul.y + h2 + (h2 - 1));
+            
+            tempLlRect = ossimIrect(theVul.x,
+                                    theVul.y + h2,
+                                    theVul.x + (w2 - 1),
+                                    theVul.y + h2 + (h2 - 1));
+         }
+         else // odd
+         {
+            tempUlRect = ossimIrect(theVul.x,
+                                    theVul.y,
+                                    theVul.x + (w2 - 1),
+                                    theVul.y + (h2));
+            
+            tempUrRect = ossimIrect(theVul.x + w2,
+                                    theVul.y,
+                                    theVul.x + w2 + (w2 - 1),
+                                    theVul.y + (h2));
+            
+            tempLrRect = ossimIrect(theVul.x + w2,
+                                    theVul.y + h2 + 1,
+                                    theVul.x + w2 + (w2 - 1),
+                                    theVul.y + h2 + (h2));
+            
+            tempLlRect = ossimIrect(theVul.x,
+                                    theVul.y + h2 + 1,
+                                    theVul.x + (w2 - 1),
+                                    theVul.y + h2 + (h2));
+         }
+      }
+      else // odd
+      {
+         if((h%2) == 0) // if even
+         {
+            tempUlRect = ossimIrect(theVul.x,
+                                    theVul.y,
+                                    theVul.x + (w2),
+                                    theVul.y + (h2 - 1));
+            
+            tempUrRect = ossimIrect(theVul.x + w2 + 1,
+                                    theVul.y,
+                                    theVul.x + w2 + (w2),
+                                    theVul.y + (h2 - 1));
+            
+            tempLrRect = ossimIrect(theVul.x + w2+1,
+                                    theVul.y + h2,
+                                    theVul.x + w2 + (w2),
+                                    theVul.y + h2 + (h2 - 1));
+            
+            tempLlRect = ossimIrect(theVul.x,
+                                    theVul.y + h2,
+                                    theVul.x + (w2),
+                                    theVul.y + h2 + (h2 - 1));
+            
+         }
+         else // odd
+         {
+            tempUlRect = ossimIrect(theVul.x,
+                                    theVul.y,
+                                    theVul.x + (w2),
+                                    theVul.y + (h2));
+            
+            tempUrRect = ossimIrect(theVul.x + w2+1,
+                                    theVul.y,
+                                    theVul.x + w2 + (w2),
+                                    theVul.y + (h2));
+            
+            tempLrRect = ossimIrect(theVul.x + w2+1,
+                                    theVul.y + h2+1,
+                                    theVul.x + w2 + (w2),
+                                    theVul.y + h2 + (h2));
+            
+            tempLlRect = ossimIrect(theVul.x,
+                                    theVul.y + h2+1,
+                                    theVul.x + (w2),
+                                    theVul.y + h2 + (h2));
+         }
+      }
+   }
+#if 0
+   ossimNotify(ossimNotifyLevel_DEBUG)
+      << "SPLIT++++++++++++++++++++++++++++++++++++++++++++" << endl
+      << "current = " << vrect << endl
+      << "ul      = " << tempUlRect << endl
+      << "ur      = " << tempUrRect << endl
+      << "lr      = " << tempLrRect << endl
+      << "ll      = " << tempLlRect << endl;
+#endif
+
+   ulRect.theVul = tempUlRect.ul();
+   ulRect.theVur = tempUlRect.ur();
+   ulRect.theVlr = tempUlRect.lr();
+   ulRect.theVll = tempUlRect.ll();
+   
+   urRect.theVul = tempUrRect.ul();
+   urRect.theVur = tempUrRect.ur();
+   urRect.theVlr = tempUrRect.lr();
+   urRect.theVll = tempUrRect.ll();
+   
+   lrRect.theVul = tempLrRect.ul();
+   lrRect.theVur = tempLrRect.ur();
+   lrRect.theVlr = tempLrRect.lr();
+   lrRect.theVll = tempLrRect.ll();
+
+   llRect.theVul = tempLlRect.ul();
+   llRect.theVur = tempLlRect.ur();
+   llRect.theVlr = tempLlRect.lr();
+   llRect.theVll = tempLlRect.ll();
+   
+   ulRect.transformViewToImage(transform);
+   urRect.transformViewToImage(transform);
+   lrRect.transformViewToImage(transform);
+   llRect.transformViewToImage(transform);
+}
+
+void ossimImageRenderer::ossimRendererSubRectInfo::transformImageToView(ossimImageViewTransform* transform)
+{
+   ossimDpt vul;
+   ossimDpt vur;
+   ossimDpt vlr;
+   ossimDpt vll;
+   transform->imageToView(theIul,
+                          vul);
+   transform->imageToView(theIur,
+                          vur);
+   transform->imageToView(theIlr,
+                          vlr);
+   transform->imageToView(theIll,
+                          vll);
+   
+   theVul = vul;
+   theVur = vur;
+   theVlr = vlr;
+   theVll = vll;
+   
+}
+
+void ossimImageRenderer::ossimRendererSubRectInfo::transformViewToImage(ossimImageViewTransform* transform)
+{
+   
+   ossimDpt nvul = theVul;
+   ossimDpt nvur = theVur;;
+   ossimDpt nvlr = theVlr;
+   ossimDpt nvll = theVll;
+
+   transform->viewToImage(nvul,
+                          theIul);
+   transform->viewToImage(nvur,
+                          theIur);
+   transform->viewToImage(nvlr,
+                          theIlr);
+   transform->viewToImage(nvll,
+                          theIll);
+   
+   
+   if(imageHasNans())
+   {
+      theViewToImageScale.makeNan();
+   }
+   else
+   {
+      theViewToImageScale = ossimDpt(1.0, 1.0);
+      
+      ossimDpt topDelta    = theIur - theIul;
+      ossimDpt rightDelta  = theIlr - theIur;
+      ossimDpt bottomDelta = theIll - theIlr;
+      ossimDpt leftDelta   = theIul - theIll;
+      double topLen    = topDelta.length();
+      double bottomLen = bottomDelta.length();
+      double rightLen  = rightDelta.length();
+      double leftLen   = leftDelta.length();
+      
+//       double averageHoriz = ((topLen + 1)  + (bottomLen+1))*.5;
+//       double averageVert  = ((leftLen+1) + (rightLen+1))*.5;
+      double averageHoriz = ((topLen)  + (bottomLen))*.5;
+      double averageVert  = ((leftLen) + (rightLen))*.5;
+      
+      
+      ossimDpt deltaViewP1P2 = theVul - theVur;
+      ossimDpt deltaViewP1P3 = theVul - theVll;
+      
+      double lengthViewP1P2 = deltaViewP1P2.length();//+1;
+      double lengthViewP1P3 = deltaViewP1P3.length();//+1;
+
+      if(lengthViewP1P2 > FLT_EPSILON)
+      {
+         theViewToImageScale.x = averageHoriz/lengthViewP1P2;
+      }
+      else
+      {
+         theViewToImageScale.makeNan();
+      }
+      if(lengthViewP1P3 > FLT_EPSILON)
+      {
+         theViewToImageScale.y = averageVert/lengthViewP1P3;
+          
+      }
+      else
+      {
+         theViewToImageScale.makeNan();
+      }
+
+      if(!theViewToImageScale.hasNans())
+      {
+         theImageToViewScale.x = 1.0/theViewToImageScale.x;
+         theImageToViewScale.y = 1.0/theViewToImageScale.y;
+      }
+      else
+      {
+         theImageToViewScale.makeNan();
+      }
+  }
+}
+
+void ossimImageRenderer::ossimRendererSubRectInfo::stretchImageOut(bool enableRound)
+{
+   ossimDpt topDelta    = theIur - theIul;
+   ossimDpt rightDelta  = theIlr - theIur;
+   ossimDpt bottomDelta = theIll - theIlr;
+   ossimDpt leftDelta   = theIul - theIll;
+
+   topDelta = topDelta*(1.0/topDelta.length());
+   rightDelta = rightDelta*(1.0/rightDelta.length());
+   bottomDelta = bottomDelta*(1.0/bottomDelta.length());
+   leftDelta = leftDelta*(1.0/leftDelta.length());
+
+   theIul = theIul + ((leftDelta - topDelta)*.5);
+   theIur = theIur + ((topDelta - rightDelta)*.5);
+   theIlr = theIlr + ((rightDelta - bottomDelta)*.5);
+   theIll = theIll + ((bottomDelta - leftDelta)*.5);
+
+   if(enableRound)
+   {
+      theIul = ossimIpt(irint(theIul.x),
+                        irint(theIul.y));
+      theIur = ossimIpt(irint(theIur.x),
+                        irint(theIur.y));
+      theIlr = ossimIpt(irint(theIlr.x),
+                        irint(theIlr.y));
+      theIll = ossimIpt(irint(theIll.x),
+                        irint(theIll.y));
+   }
+}
+
+
+bool ossimImageRenderer::ossimRendererSubRectInfo::isIdentity()const
+{
+//    ossimDpt deltaP1P2 = theIul - theIur;
+//    ossimDpt deltaP1P3 = theIul - theIll;
+   
+//    ossimDpt deltaViewP1P2 = theVul - theVur;
+//    ossimDpt deltaViewP1P3 = theVul - theVll;
+   
+//    bool horizontalSigns = ossimGetSign(deltaP1P2.x)==ossimGetSign(deltaViewP1P2.x);
+//    bool verticalSigns   = ossimGetSign(deltaP1P3.y)==ossimGetSign(deltaViewP1P3.y);
+
+//    // check first to see if any horizontal or vertical flipping
+//    //
+//    if(horizontalSigns && verticalSigns)
+//    {
+//       // check scales to see if they are 1
+//       if(fabs(1-theViewToImageScale.x) <= FLT_EPSILON &&
+//          fabs(1-theViewToImageScale.y) <= FLT_EPSILON)
+//       {
+//          return true;
+//       }
+//    }
+
+    double iulDelta = (theIul-theVul).length();
+    double iurDelta = (theIur-theVur).length();
+    double ilrDelta = (theIlr-theVlr).length();
+    double illDelta = (theIll-theVll).length();
+
+    return ((iulDelta <= FLT_EPSILON)&&
+            (iurDelta <= FLT_EPSILON)&&
+            (ilrDelta <= FLT_EPSILON)&&
+            (illDelta <= FLT_EPSILON));
+}
+
+bool ossimImageRenderer::ossimRendererSubRectInfo::canBilinearInterpolate(ossimImageViewTransform* transform,
+									  double error)const
+{
+   if(imageHasNans())
+   {
+      return false;
+   }
+  ossimDpt imageToViewScale = getAbsValueImageToViewScales();
+
+  if(imageToViewScale.hasNans()) return false;
+  ossimDpt vUpper, vRight, vBottom, vLeft, vCenter;
+  ossimDpt iUpper, iRight, iBottom, iLeft, iCenter;
+
+  getViewMids(vUpper, vRight, vBottom, vLeft, vCenter);
+  getImageMids(iUpper, iRight, iBottom, iLeft, iCenter);
+
+  ossimDpt testCenter;
+
+  ossimDpt iFullRes(iCenter.x*imageToViewScale.x,
+		    iCenter.y*imageToViewScale.y);
+
+  transform->viewToImage(vCenter, testCenter);
+
+  if(testCenter.hasNans())
+  {
+     return false;
+  }
+  ossimDpt testFullRes(testCenter.x*imageToViewScale.x,
+		       testCenter.y*imageToViewScale.y);
+
+  double errorCheck1 = (testFullRes - iFullRes).length();
+
+  iFullRes = ossimDpt(iUpper.x*imageToViewScale.x,
+		      iUpper.y*imageToViewScale.y);
+
+  transform->viewToImage(vUpper, testCenter);
+  if(testCenter.hasNans())
+  {
+     return false;
+  }
+  testFullRes = ossimDpt(testCenter.x*imageToViewScale.x,
+			 testCenter.y*imageToViewScale.y);
+  double errorCheck2 = (testFullRes - iFullRes).length();
+
+  iFullRes = ossimDpt(iRight.x*imageToViewScale.x,
+		      iRight.y*imageToViewScale.y);
+
+  transform->viewToImage(vRight, testCenter);
+  if(testCenter.hasNans())
+  {
+     return false;
+  }
+  testFullRes = ossimDpt(testCenter.x*imageToViewScale.x,
+			 testCenter.y*imageToViewScale.y);
+  double errorCheck3 = (testFullRes - iFullRes).length();
+
+  iFullRes = ossimDpt(iBottom.x*imageToViewScale.x,
+		      iBottom.y*imageToViewScale.y);
+
+  transform->viewToImage(vBottom, testCenter);
+  if(testCenter.hasNans())
+  {
+     return false;
+  }
+  testFullRes = ossimDpt(testCenter.x*imageToViewScale.x,
+			 testCenter.y*imageToViewScale.y);
+  double errorCheck4 = (testFullRes - iFullRes).length();
+
+  iFullRes = ossimDpt(iLeft.x*imageToViewScale.x,
+		      iLeft.y*imageToViewScale.y);
+
+  transform->viewToImage(vLeft, testCenter);
+  testFullRes = ossimDpt(testCenter.x*imageToViewScale.x,
+			 testCenter.y*imageToViewScale.y);
+  double errorCheck5 = (testFullRes - iFullRes).length();
+
+
+  return ((errorCheck1 < error)&&
+	  (errorCheck2 < error)&&
+	  (errorCheck3 < error)&&
+	  (errorCheck4 < error)&&
+	  (errorCheck5 < error));
+	  
+}
+
+
+void ossimImageRenderer::ossimRendererSubRectInfo::getViewMids(ossimDpt& upperMid,
+				     ossimDpt& rightMid,
+				     ossimDpt& bottomMid,
+				     ossimDpt& leftMid,
+				     ossimDpt& center)const
+{
+  
+  upperMid  = (theVul + theVur)*.5;
+  rightMid  = (theVur + theVlr)*.5;
+  bottomMid = (theVlr + theVll)*.5;
+  leftMid   = (theVul + theVll)*.5;
+  center    = (theVul + theVur + theVlr + theVll)*.25;
+}
+
+void ossimImageRenderer::ossimRendererSubRectInfo::getImageMids(ossimDpt& upperMid,
+				      ossimDpt& rightMid,
+				      ossimDpt& bottomMid,
+				      ossimDpt& leftMid,
+				      ossimDpt& center)const
+{
+  if(imageHasNans())
+    {
+      upperMid.makeNan();
+      rightMid.makeNan();
+      bottomMid.makeNan();
+      leftMid.makeNan();
+      center.makeNan();
+    }
+  else
+    {
+      upperMid  = (theIul + theIur)*.5;
+      rightMid  = (theIur + theIlr)*.5;
+      bottomMid = (theIlr + theIll)*.5;
+      leftMid   = (theIul + theIll)*.5;
+      center    = (theIul + theIur + theIlr + theIll)*.25;
+    }
+}
+
+ossimDpt ossimImageRenderer::ossimRendererSubRectInfo::getParametricCenter(const ossimDpt& ul, const ossimDpt& ur, 
+									   const ossimDpt& lr, const ossimDpt& ll)const
+{
+  ossimDpt top    = ur - ul;
+  ossimDpt bottom = lr - ll;
+  
+  ossimDpt centerTop = ul + top * .5;
+  ossimDpt centerBottom = ll + bottom * .5;
+
+  return centerBottom + (centerBottom - centerTop)*.5;
+}
+
+ossimImageRenderer::ossimImageRenderer()
+   :
+      ossimImageSourceFilter(),
+      ossimViewInterface(NULL),
+      theResampler(NULL),
+      theBlankTile(NULL),
+      theTile(NULL),
+      theTemporaryBuffer(NULL),
+      theCachedTile(NULL),
+      theStartingResLevel(0),
+      theImageViewTransform(NULL),
+      theMaxRecursionLevel(5),
+      theAutoUpdateInputTransform(true)
+{
+   ossimViewInterface::theObject = this;
+   theResampler = new ossimFilterResampler();
+   theImageViewTransform = new ossimImageViewProjectionTransform;
+   theBoundingRect.makeNan();
+//    theInputRect.makeNan();
+//    theOutputRect.makeNan();
+}
+
+ossimImageRenderer::ossimImageRenderer(ossimImageSource* inputSource,
+                                       ossimImageViewTransform* imageViewTrans)
+   : ossimImageSourceFilter(inputSource),
+     ossimViewInterface(NULL),
+     theResampler(NULL),
+     theBlankTile(NULL),
+     theTile(NULL),
+     theTemporaryBuffer(NULL),
+     theCachedTile(NULL),
+     theStartingResLevel(0),
+     theImageViewTransform(imageViewTrans),
+     theMaxRecursionLevel(5),
+     theAutoUpdateInputTransform(true)
+{
+   ossimViewInterface::theObject = this;
+   theResampler = new ossimFilterResampler();
+   if(!theImageViewTransform)
+   {
+      theImageViewTransform = new ossimImageViewProjectionTransform;
+   }
+}
+
+ossimImageRenderer::~ossimImageRenderer()
+{
+   if (theImageViewTransform)
+   {
+      delete theImageViewTransform;
+      theImageViewTransform = NULL;
+   }
+   
+   if(theResampler)
+   {
+      delete theResampler;
+      theResampler = NULL;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimImageRenderer::getTile(
+   const  ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+#if 0
+   static const char MODULE[] = "ossimImageRenderer::getTile";
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << "Requesting view rect = "
+         << tileRect << endl;
+   }
+#endif
+
+   // long w = tileRect.width();
+   // long h = tileRect.height();
+   // ossimIpt origin = tileRect.ul();
+   
+   if(!theBlankTile.valid() || !theTile.valid())
+   {
+      allocate();
+   }
+
+   if(!theTile.valid())
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimImageRenderer::getTile tile allocation failure!\n"
+            << endl;
+      }
+      return ossimImageSourceFilter::getTile(tileRect, resLevel);
+   }
+
+   if(theBlankTile.valid())
+   {
+      theBlankTile->setImageRectangle(tileRect);
+   }
+
+   if(!theInputConnection)
+   {
+      return theBlankTile;
+   }
+   
+   if ( !isSourceEnabled()||(!theImageViewTransform)||
+        (!theImageViewTransform->isValid()) )
+   {
+      // This tile source bypassed, return the input tile source.
+      return theInputConnection->getTile(tileRect, resLevel);  
+   }
+
+   if(theBoundingViewRect.hasNans())
+   {
+      theBoundingViewRect = getBoundingRect();
+   }
+   if(theBoundingViewRect.width() < 4 &&
+      theBoundingViewRect.height() < 4)
+   {
+      return theBlankTile;
+   }
+   ossimIrect rect = theBoundingViewRect;
+   if( !theInputConnection || !rect.intersects(tileRect) )
+   {
+      return theBlankTile;
+   }
+   
+   if(!theTile)
+   {
+      return theInputConnection->getTile(tileRect, resLevel);
+   }
+   
+   // long tw = theTile->getWidth();
+   // long th = theTile->getHeight();
+   
+   theTile->setImageRectangle(tileRect);
+   theTile->makeBlank();
+   
+   ossimRendererSubRectInfo subRectInfo(tileRect.ul(),
+                                        tileRect.ur(),
+                                        tileRect.lr(),
+                                        tileRect.ll());
+   
+   subRectInfo.transformViewToImage(theImageViewTransform);
+//   std::cout << subRectInfo << std::endl;
+   if(subRectInfo.imageIsNan())
+   {
+      return theBlankTile;
+   }
+   
+   
+//    if(subRectInfo.isIdentity()&&
+//       !subRectInfo.imageHasNans())
+//    {
+//       return theInputConnection->getTile(tileRect, resLevel);
+//    }
+//    else
+//    {
+   recursiveResample(theTile, subRectInfo, 1);
+   theTile->validate();
+//   }
+   return theTile;
+}
+
+void ossimImageRenderer::recursiveResample(ossimRefPtr<ossimImageData> outputData,
+                                           const ossimRendererSubRectInfo& rectInfo,
+                                           ossim_uint32 level)
+{
+   ossimIrect tempViewRect = rectInfo.getViewRect();
+   if(rectInfo.imageIsNan())
+   {
+      return;
+   } 
+   
+   if(tempViewRect.width() <2 &&
+      tempViewRect.height() <2)
+   {
+      if(!rectInfo.imageHasNans())
+      {
+         fillTile(outputData,
+                  rectInfo);
+      }
+      return;
+   }
+   const double error = 1;
+   if(rectInfo.canBilinearInterpolate(theImageViewTransform, error))
+   {                                // then draw the tile
+      fillTile(outputData,
+	       rectInfo);
+      return;
+   }
+   else
+   {
+      // split into four subtiles
+      ossimRendererSubRectInfo ulRectInfo;
+      ossimRendererSubRectInfo urRectInfo;
+      ossimRendererSubRectInfo lrRectInfo;
+      ossimRendererSubRectInfo llRectInfo;
+      
+      rectInfo.splitView(theImageViewTransform,
+			 ulRectInfo,
+			 urRectInfo,
+			 lrRectInfo,
+			 llRectInfo);   
+      
+      ossimDrect vrect = rectInfo.getViewRect();
+      
+#if 0
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "vrect  = " << vrect
+         << "\nwidth  = " << vrect.width()
+         << "\nheight = " << vrect.height()
+         << "\nlevel  = " << level << endl;
+#endif
+      bool scaleUlNeedsSplit = ((!ulRectInfo.canBilinearInterpolate(theImageViewTransform, error))||
+				ulRectInfo.imageHasNans());
+      bool scaleUrNeedsSplit = ((!urRectInfo.canBilinearInterpolate(theImageViewTransform, error))||
+				urRectInfo.imageHasNans());
+      bool scaleLrNeedsSplit = ((!lrRectInfo.canBilinearInterpolate(theImageViewTransform, error))||
+				lrRectInfo.imageHasNans());
+      bool scaleLlNeedsSplit = ((!llRectInfo.canBilinearInterpolate(theImageViewTransform, error))||
+				llRectInfo.imageHasNans());
+      
+      bool tooSmall = (vrect.width() < 4) && (vrect.height()<4);
+      //
+      if(!tooSmall)
+      {
+         if(scaleUlNeedsSplit||
+            scaleUrNeedsSplit||
+            scaleLrNeedsSplit||
+            scaleLlNeedsSplit)
+         {
+            if(scaleUlNeedsSplit)
+            {
+               recursiveResample(outputData,
+                                 ulRectInfo,
+                                 level + 1);
+            }
+            else
+            {
+               fillTile(outputData, ulRectInfo);
+            }
+            if(scaleUrNeedsSplit)
+            {
+               recursiveResample(outputData,
+                                 urRectInfo,
+                                 level + 1);
+            }
+            else
+            {
+               fillTile(outputData, urRectInfo);
+            }
+            
+            if(scaleLrNeedsSplit)
+            {
+               recursiveResample(outputData,
+                                 lrRectInfo,
+                                 level + 1);
+            }
+            else
+            {
+               fillTile(outputData, lrRectInfo);
+            }
+            
+            if(scaleLlNeedsSplit)
+            {
+               recursiveResample(outputData,
+                                 llRectInfo,
+                                 level + 1);
+            }
+            else
+            {
+               fillTile(outputData, llRectInfo);
+            }
+         }
+         else
+         {
+            fillTile(outputData,
+                     rectInfo);
+         }
+      }
+      else if(!rectInfo.imageHasNans())
+      {
+         fillTile(outputData,
+                  rectInfo);
+      }
+   }
+}
+
+void ossimImageRenderer::fillTile(ossimRefPtr<ossimImageData> outputData,
+                                  const ossimRendererSubRectInfo& rectInfo)
+{
+   if(!outputData.valid() || !outputData->getBuf() || rectInfo.imageHasNans())
+   {
+      return;
+   }
+   ossimIrect vrect = rectInfo.getViewRect();
+
+   ossimDpt imageToViewScale = rectInfo.getAbsValueImageToViewScales();
+
+   if(imageToViewScale.hasNans()) return;
+   
+   ossimDpt tile_size = ossimDpt(vrect.width(), vrect.height());
+   double kernelSupportX, kernelSupportY;
+   double averageScale = (imageToViewScale.x + imageToViewScale.y)/2.0;
+   long   closestFitResLevel = (long)floor(log(1.0/averageScale)/
+                                           log(2.0));
+   
+   ossim_uint32 resLevel = closestFitResLevel<0?0:closestFitResLevel;
+   resLevel += theStartingResLevel;
+   double closestScale = 1.0/pow((double)2.0,(double)resLevel);
+   
+   ossimDrect requestRect = rectInfo.getImageRect()*ossimDpt(closestScale,closestScale);
+   
+   ossimDpt nul(rectInfo.theIul.x*closestScale,
+                rectInfo.theIul.y*closestScale);
+   ossimDpt nll(rectInfo.theIll.x*closestScale,
+                rectInfo.theIll.y*closestScale);
+   ossimDpt nlr(rectInfo.theIlr.x*closestScale,
+                rectInfo.theIlr.y*closestScale);
+   ossimDpt nur(rectInfo.theIur.x*closestScale,
+                rectInfo.theIur.y*closestScale);
+   
+   ossimDpt newScale(imageToViewScale.x/closestScale,
+                     imageToViewScale.y/closestScale);
+   
+   theResampler->setScaleFactor(newScale);
+
+   theResampler->getKernelSupport(kernelSupportX,
+                                  kernelSupportY);
+   
+   ossimDrect boundingRect = ossimDrect(nul,
+ 					nll,
+ 					nlr,
+ 					nur);
+   
+   boundingRect = ossimIrect((ossim_int32)floor(boundingRect.ul().x - (kernelSupportX)-.5),
+                             (ossim_int32)floor(boundingRect.ul().y - (kernelSupportY)-.5),
+                             (ossim_int32)ceil(boundingRect.lr().x + (kernelSupportX)+.5),
+                             (ossim_int32)ceil(boundingRect.lr().y + (kernelSupportY)+.5));
+//    boundingRect = ossimIrect((ossim_int32)floor(boundingRect.ul().x - (kernelSupportX)),
+//                              (ossim_int32)floor(boundingRect.ul().y - (kernelSupportY)),
+//                              (ossim_int32)ceil(boundingRect.lr().x + (kernelSupportX)),
+//                              (ossim_int32)ceil(boundingRect.lr().y + (kernelSupportY)));
+   
+   requestRect = boundingRect;
+
+   // ossimIrect reqRect = requestRect;
+   
+   ossimRefPtr<ossimImageData> data;
+   if(theCachedTile.valid())
+   {
+      ossimIrect cachedTileRect = theCachedTile->getImageRectangle();
+#if 0
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "cached tile rect = " << cachedTileRect << endl
+         << "requestRect      = " << requestRect << endl;
+#endif
+#if 0      
+      if(requestRect.completely_within(cachedTileRect)&&
+         resLevel == theCachedTileResLevel)
+      {
+         // ossimNotify(ossimNotifyLevel_DEBUG)
+         // << "SETTING TO CACHED RECT" << endl;
+         data = theCachedTile;
+      }
+#endif
+   }
+   
+   if(!data.valid())
+   {
+#if 0
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "--------------------Wiping out old cached rect" << endl;
+#endif
+//       if( (requestRect.width() < 64 ) || (requestRect.height() < 64) )
+//       {
+// 	 requestRect.stretchToTileBoundary(ossimIpt(64, 64));
+//       }
+      data = getTileAtResLevel(requestRect, resLevel);
+      if(theCachedTile.valid())
+      {
+         theCachedTile = NULL;
+      }
+//       if(data)
+//       {
+//          theCachedTileResLevel = resLevel;
+//          theCachedTile = (ossimImageData*)data->dup();
+//       }
+   }
+   
+   ossimDataObjectStatus status = OSSIM_NULL;
+   if(data.valid())
+   {
+      status = data->getDataObjectStatus();
+   }
+   if( (status == OSSIM_NULL) ||
+       (status == OSSIM_EMPTY))
+   {
+      return;
+   }
+   
+   ossimDrect bounds = theBoundingRect;
+   // setup the clamp for the resampler
+   //
+//    if(static_cast<ossim_uint32>(resLevel) < theInputDecimationFactors.size())
+//    {
+//      bounds = bounds*theInputDecimationFactors[resLevel];
+//    }
+//    else if(theInputDecimationFactors.size() > 0)
+//    {
+                           
+//       bounds = bounds*theInputDecimationFactors[theInputDecimationFactors.size()-1];
+//    }
+
+//   theResampler->setBoundingInputRect(bounds);
+
+   bounds = bounds*ossimDpt(closestScale, closestScale);
+   theResampler->setBoundingInputRect(bounds);
+   
+   double denominatorX = 1.0;
+   double denominatorY = 1.0;
+   
+   if(tile_size.x > 2)
+   {
+      denominatorX = tile_size.x-1.0;
+   }
+   if(tile_size.y > 2)
+   {
+      denominatorY = tile_size.y-1.0;
+   }
+   theResampler->setScaleFactor(newScale);
+   theResampler->resample(data,
+			  outputData,
+			  rectInfo.getViewRect(),
+			  nul,
+			  nur,
+			  ossimDpt( ( (nll.x - nul.x)/denominatorY ),
+				    ( (nll.y - nul.y)/denominatorY ) ),
+			  ossimDpt( ( (nlr.x - nur.x)/denominatorY ),
+				    ( (nlr.y - nur.y)/denominatorY ) ),
+// 			  ossimDpt( ( (nll.x - nul.x)/denominatorX ),
+// 				    ( (nll.y - nul.y)/denominatorY ) ),
+// 			  ossimDpt( ( (nlr.x - nur.x)/denominatorX ),
+// 				    ( (nlr.y - nur.y)/denominatorY ) ),
+			  tile_size);
+//   outputData->validate();
+}
+
+long ossimImageRenderer::computeClosestResLevel(const std::vector<ossimDpt>& decimationFactors,
+                                                double scale)const
+{
+   long result = 0;
+   long upper  = (long)decimationFactors.size();
+   bool done   = false;
+   
+   if(upper > 1)
+   {
+      while((result < upper)&&!done)
+      {
+         if(scale < decimationFactors[result].x)
+         {
+            ++result;
+         }
+         else
+         {
+            done = true;
+         }
+      }
+      
+      // now use the higher res level and resample down
+      //
+      if(result)
+      {
+         --result;
+      }
+   }
+   return result;
+}
+
+ossimIrect ossimImageRenderer::getBoundingRect(ossim_uint32 resLevel)const
+{
+   static const char* MODULE = "ossimImageRenderer::getBoundingRect()";
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << "entered..." << endl;
+   }
+   if(!theBoundingViewRect.hasNans())
+   {
+      return theBoundingViewRect;
+   }
+   
+   vector<ossimDpt> points(4);
+   
+//   if(!theOutputRect.hasNans()) return theOutputRect;
+   ossimDrect inputRect;
+   ossimIrect outputRect;
+   
+   inputRect.makeNan();
+   outputRect.makeNan();
+
+   if(theInputConnection&&theImageViewTransform)
+   {
+      inputRect = theInputConnection->getBoundingRect(resLevel);
+      
+      if(isSourceEnabled()&&theImageViewTransform->isValid())
+      {
+//          inputRect = ossimDrect(inputRect.ul().x,
+//                                 inputRect.ul().y,
+//                                 inputRect.lr().x,
+//                                 inputRect.lr().y); 
+         
+// 	 theImageViewTransform->imageToView(inputRect.ul(), points[0]);
+//          theImageViewTransform->imageToView(inputRect.ur(), points[1]);
+//          theImageViewTransform->imageToView(inputRect.lr(), points[2]);
+//          theImageViewTransform->imageToView(inputRect.ll(), points[3]);
+
+         
+         ossimDrect tempRect = theImageViewTransform->getImageToViewBounds(inputRect);
+         
+         theBoundingViewRect = ossimIrect(static_cast<int>(floor(tempRect.ul().x + 0.5)),
+                                          static_cast<int>(floor(tempRect.ul().y + 0.5)),
+                                          static_cast<int>(floor(tempRect.lr().x + 0.5)),
+                                          static_cast<int>(floor(tempRect.lr().y + 0.5)));
+      }
+      else
+      {
+         theBoundingViewRect = inputRect;
+      }
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " bounds  = "
+         << outputRect
+         << "\n w, h    = " << outputRect.width() << ", "
+         << outputRect.height()
+         << endl;
+   }
+   
+   return theBoundingViewRect;
+}
+
+void ossimImageRenderer::initialize()
+{
+   //---
+   // Call the base class initialize.
+   // Note:  This will reset "theInputConnection" if it changed...
+   //---
+   ossimImageSourceFilter::initialize();
+
+   theBoundingViewRect.makeNan();
+   theBoundingRect.makeNan();
+
+   if (theInputConnection)
+   {
+      theBoundingRect = theInputConnection->getBoundingRect();
+   }
+
+   if (theImageViewTransform)
+   {
+      ossimImageViewProjectionTransform* trans
+         = PTR_CAST(ossimImageViewProjectionTransform,
+                    theImageViewTransform);
+      if(trans)
+      {
+         if(PTR_CAST(ossimMapProjection, trans->getImageProjection()) ||
+            (!trans->getImageProjection())||
+            (!trans->getViewProjection()))
+         {
+            checkTransform();
+         }
+      }
+   }
+
+   if (theResampler)
+   {
+      theResampler->setBoundingInputRect(theBoundingRect);
+   }
+   
+   theInputDecimationFactors.clear();
+
+   deallocate();
+//    if (theInputConnection && theTile.valid())
+//    {
+//       if ( theInputConnection->getNumberOfOutputBands() !=
+//            theTile->getNumberOfBands())
+//       {
+//          //---
+//          // This will wide things slick and force an allocate() call on first
+//          // getTile().
+//          //---
+//          deallocate();
+//       }
+//    }
+}
+
+void ossimImageRenderer::deallocate()
+{
+   theTile            = NULL;
+   theBlankTile       = NULL;
+   theTemporaryBuffer = NULL;
+   theCachedTile      = NULL;
+}
+
+void ossimImageRenderer::allocate()
+{
+   deallocate();
+
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+      theBlankTile  = ossimImageDataFactory::instance()->create(this, this);
+      
+      theTile->initialize();
+      theBoundingRect = theInputConnection->getBoundingRect();
+   }
+}
+
+bool ossimImageRenderer::saveState(ossimKeywordlist& kwl,
+                                   const char* prefix)const
+{
+   if(theImageViewTransform)
+   {
+      ossimString newPrefix = ossimString(prefix) + ossimString("image_view_trans.");
+      
+      theImageViewTransform->saveState(kwl, newPrefix.c_str());
+   }
+   if(theResampler)
+   {
+      theResampler->saveState(kwl,
+                              (ossimString(prefix)+"resampler.").c_str());
+   }
+   return ossimImageSource::saveState(kwl, prefix);
+}
+
+bool ossimImageRenderer::loadState(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimImageRenderer::loadState entered..." << endl;
+      
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "OSSIM_ID:  " << OSSIM_ID << endl;
+#endif      
+   }
+   
+   ossimString newPrefix = ossimString(prefix) + ossimString("image_view_trans.");
+   bool result = ossimImageSourceFilter::loadState(kwl, prefix);
+   theInputDecimationFactors.clear();
+   
+   if(theResampler)
+   {
+      theResampler->loadState(kwl,
+                              (ossimString(prefix)+"resampler.").c_str());
+   }
+   if(theImageViewTransform)
+   {
+      delete theImageViewTransform;
+      theImageViewTransform = NULL;
+   }
+   theImageViewTransform = ossimImageViewTransformFactory::instance()->createTransform(kwl, newPrefix.c_str());
+   if(!theImageViewTransform)
+   {
+      theImageViewTransform = new ossimImageViewProjectionTransform;
+   }
+   return result;
+}
+
+void ossimImageRenderer::setImageViewTransform(ossimImageViewTransform* transform)
+{
+   if(theImageViewTransform)
+   {
+      delete theImageViewTransform;
+   }
+   theImageViewTransform = transform;
+
+   ossimImageViewProjectionTransform* trans = PTR_CAST(ossimImageViewProjectionTransform,
+                                                       theImageViewTransform);
+   if(trans)
+   {
+      if(!trans->getImageProjection())
+      {
+         checkTransform();
+      }
+   }
+   
+}
+
+bool ossimImageRenderer::setView(ossimObject* baseObject,
+                                 bool ownsTheView)
+{
+   bool result = false;
+   theBoundingViewRect.makeNan();
+   if(theImageViewTransform)
+   {
+      result = theImageViewTransform->setView(baseObject,
+                                              ownsTheView);
+   }
+
+   return result;
+}
+
+ossimObject* ossimImageRenderer::getView()
+{
+   if(theImageViewTransform)
+   {
+      return theImageViewTransform->getView();
+   }
+   return NULL;
+}
+
+const ossimObject* ossimImageRenderer::getView()const
+{
+   if(theImageViewTransform)
+   {
+      return theImageViewTransform->getView();
+   }
+   return NULL;
+}
+
+void ossimImageRenderer::getValidImageVertices(vector<ossimIpt>& validVertices,
+                                               ossimVertexOrdering ordering,
+                                               ossim_uint32 resLevel)const
+{
+   if(theInputConnection&&theImageViewTransform&&theImageViewTransform->isValid())
+   {
+      theInputConnection->getValidImageVertices(validVertices, ordering, resLevel);
+      if(isSourceEnabled())
+      {
+         long inputSize = validVertices.size();
+         if(inputSize)
+         {
+            ossimDpt viewPt;
+            // transform each point to the view
+            for(long index = 0; index < inputSize; ++index)
+            {
+               theImageViewTransform->imageToView(validVertices[index], viewPt);
+               
+               // round it to the nearest pixel
+               //
+               validVertices[index] = ossimIpt(viewPt);
+            }
+         }
+      }
+   }
+}
+
+bool ossimImageRenderer::getImageGeometry(ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   if(isSourceEnabled()&&getView())
+   {
+      const ossimObject* view = getView();
+      
+      bool result = view->saveState(kwl, prefix);
+
+      return result;
+   }
+   else
+   {
+      if(theInputConnection)
+      {
+         return theInputConnection->getImageGeometry(kwl, prefix);
+      }
+   }
+
+   return false;
+}
+
+void ossimImageRenderer::connectInputEvent(ossimConnectionEvent& event)
+{
+   theInputConnection = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   // All this code in here will change after the demo.  For now we need a
+   // way to bring every one up with a projection.  Later we will have to
+   // tie to a projection source.
+   //
+   if(!theImageViewTransform)
+   {
+      theImageViewTransform  = new ossimImageViewProjectionTransform;
+   }
+   
+   checkTransform();
+
+   initialize();
+   
+}
+
+void ossimImageRenderer::disconnectInputEvent(ossimConnectionEvent& event)
+{
+   ossimImageViewProjectionTransform* transform = PTR_CAST(ossimImageViewProjectionTransform,
+                                                           theImageViewTransform);
+   if(transform)
+   {
+      transform->setImageProjection(NULL, true);
+   }
+   
+   theInputConnection = NULL;
+   theInputDecimationFactors.clear();
+}
+
+void ossimImageRenderer::propertyEvent(ossimPropertyEvent& event)
+{
+   checkTransform();
+   initialize();
+}
+
+
+void ossimImageRenderer::setProperty(ossimRefPtr<ossimProperty> property)
+{
+  ossimString tempName = property->getName();
+  
+  if(tempName == "Filter type")
+    {
+      if(theResampler)
+	{
+	  theResampler->setFilterType(property->valueToString());
+	}
+    }
+//   else if(tempName == "Blur factor")
+//     {
+//       if(theResampler)
+// 	{
+// 	  theResampler->setBlurFactor(property->valueToString().toDouble());
+// 	}
+//     }
+  else
+    {
+      ossimImageSourceFilter::setProperty(property);
+    }
+}
+
+ossimRefPtr<ossimProperty> ossimImageRenderer::getProperty(const ossimString& name)const
+{
+  ossimString tempName = name;
+
+  if(tempName == "Filter type")
+    {
+      std::vector<ossimString> filterNames;
+      theResampler->getFilterTypes(filterNames);
+      
+      ossimStringProperty* stringProp = new ossimStringProperty("Filter type",
+								theResampler->getMinifyFilterTypeAsString(),
+								false,
+								filterNames);
+      stringProp->clearChangeType();
+      stringProp->setReadOnlyFlag(false);
+      stringProp->setCacheRefreshBit();
+      
+      return stringProp;
+    }
+//   else if(tempName == "Blur factor")
+//   {
+//      ossimNumericProperty* numericProperty = new ossimNumericProperty("Blur factor",
+//                                                                       ossimString::toString((double)theResampler->getBlurFactor()));
+     
+//      numericProperty->setConstraints(0.0, 50.0);
+//      numericProperty->setNumericType(ossimNumericProperty::ossimNumericPropertyType_FLOAT64);
+//      numericProperty->setCacheRefreshBit();
+
+//      return numericProperty;
+//   }
+
+  return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimImageRenderer::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+  ossimImageSourceFilter::getPropertyNames(propertyNames);
+
+  propertyNames.push_back("Filter type");
+//  propertyNames.push_back("Blur factor");
+}
+
+
+void ossimImageRenderer::checkTransform()
+{
+  theBoundingViewRect.makeNan();
+   if(!isSourceEnabled())
+   {
+      return;
+   }
+
+   
+      
+   // All this code in here might change after the demo.  For now we need a
+   // way to bring every one up with a projection.  Later we will have to
+   // tie to a projection source.
+   ossimImageViewProjectionTransform* transform = PTR_CAST(ossimImageViewProjectionTransform,
+                                                           theImageViewTransform);
+   ossimImageSourceInterface* inter = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+
+   // we will only check for projection transforms
+   if(!transform||!inter) return;
+
+   ossimProjection* proj = NULL;
+   
+//   if(theAutoUpdateInputTransform)//||
+//      (!transform->getImageProjection()))
+//    {
+      if(!transform->getImageProjection()||
+         PTR_CAST(ossimMapProjection, transform->getImageProjection()))
+      {
+         ossimKeywordlist kwl;
+         inter->getImageGeometry(kwl);
+         
+         proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+         transform->setImageProjection(proj, true);
+      }
+      else
+      {
+         proj = transform->getImageProjection();
+      }
+//    }
+   
+   if(proj)
+   {
+         if(!transform->getView()) // check to see if we found a view controller and the view was set
+         {                         // if not then we will create a default output projection
+	   ossimProjection* newProj = (ossimProjection*)NULL;
+	   ossimMapProjection* mapProj = (ossimMapProjection*)NULL;
+	   if(PTR_CAST(ossimMapProjection, proj))
+	     {
+	       newProj = (ossimProjection*)proj->dup(); // Make a copy...
+	      
+            }
+            else
+            {
+               newProj = new ossimEquDistCylProjection;
+	    }
+	   mapProj = PTR_CAST(ossimMapProjection, newProj);
+	   if(mapProj) 
+	     {
+	       ossimDpt meters = proj->getMetersPerPixel();
+	       
+	       double GSD = (meters.x + meters.y)/2.0;
+	       meters.x = GSD;
+	       meters.y = GSD;
+	       mapProj->setUlGpt(proj->origin());
+	       mapProj->setOrigin(proj->origin());
+	       mapProj->setMetersPerPixel(meters);
+	     }
+	   transform->setViewProjection(newProj);
+         }
+//       }
+   }
+   else
+   {
+      transform->setImageProjection(NULL, true);
+   }
+}
+
+
+void ossimImageRenderer::getDecimationFactor(ossim_uint32 resLevel,
+					     ossimDpt& result)const
+{
+  if(isSourceEnabled())
+    {
+      result = ossimDpt(1,1);
+    }
+  else
+    {
+      ossimImageSourceFilter::getDecimationFactor(resLevel,
+						  result);
+    }
+}
+
+void ossimImageRenderer::getDecimationFactors(vector<ossimDpt>& decimations)const
+{
+  if(isSourceEnabled())
+    {
+      decimations.push_back(ossimDpt(1,1));
+    }
+  else
+    {
+      ossimImageSourceFilter::getDecimationFactors(decimations);
+    }
+}
+
+ossim_uint32 ossimImageRenderer::getNumberOfDecimationLevels()const
+{
+  if(isSourceEnabled())
+    {
+      return 1;
+    }
+
+  return ossimImageSourceFilter::getNumberOfDecimationLevels();
+}
+void ossimImageRenderer::stretchQuadOut(const ossimDpt& amount,
+                                        ossimDpt& ul,
+                                        ossimDpt& ur,
+                                        ossimDpt& lr,
+                                        ossimDpt& ll)
+{
+      ossimDpt upper  = ur - ul;
+      ossimDpt right  = lr - ur;
+      ossimDpt bottom = ll - lr;
+      ossimDpt left   = ul - ll;
+
+      upper = (upper*(1.0 / upper.length()));
+      upper.x *= amount.x;
+      upper.y *= amount.y;
+      right = (right*(1.0 / right.length()));
+      right.x *= amount.x;
+      right.y *= amount.y;
+      bottom = (bottom*(1.0 / bottom.length()));
+      bottom.x *= amount.x;
+      bottom.y *= amount.y;
+      left = (left*(1.0 / left.length()));
+      left.x *= amount.x;
+      left.y *= amount.y;
+      
+
+      ul = ul - upper + left;
+      ur = ur + upper - right;
+      lr = lr + left - bottom;
+      ll = ll - left + bottom;
+}
+
+ossimRefPtr<ossimImageData>  ossimImageRenderer::getTileAtResLevel(const ossimIrect& boundingRect,
+                                                       ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      theBlankTile->setImageRectangle(boundingRect);
+      
+      return theBlankTile;
+   }
+   
+   ossim_uint32 levels = theInputConnection->getNumberOfDecimationLevels();
+   
+   // ossim_uint32 maxValue = (ossim_uint32)ossimMax((ossim_uint32)theBoundingRect.width(),
+   //                                            (ossim_uint32)theBoundingRect.height());
+   
+   if(resLevel == 0)
+   {
+      return theInputConnection->getTile(boundingRect);
+   }
+   if(resLevel < levels)
+   {
+      if(theInputConnection)
+      {
+         return theInputConnection->getTile(boundingRect,
+                                            resLevel);
+      }
+      else
+      {
+         return theBlankTile;
+      }
+   }
+   else
+   {
+      // check to see how many decimations we must achiev for the
+      // request
+      //
+      int decimations = (resLevel - (levels-1));
+      ossimIpt tileSize(theInputConnection->getTileWidth(),
+                        theInputConnection->getTileHeight());
+      
+      ossim_int32 multiplier = (1 << decimations);
+      
+      ossim_int32 xIndex = 0;
+      ossim_int32 yIndex = 0;
+      
+      // adjust the tilesize so it at least will cover the multiplier
+      // We will probably come up with something better later but for now
+      // this will do.
+      if(multiplier > tileSize.x)
+      {
+         tileSize.x = multiplier;
+      }
+      if(multiplier > tileSize.y)
+      {
+         tileSize.y = multiplier;
+      }
+      
+      // set the rect that covers the requested RLevel to the valid RLevel. 
+      // the valid RLevel is what is available on the input side.
+      //
+      ossimIrect requestedRectAtValidRLevel = boundingRect;
+      requestedRectAtValidRLevel.stretchToTileBoundary(tileSize);
+      ossimIrect mappedRequestedRect = requestedRectAtValidRLevel;
+      requestedRectAtValidRLevel  = requestedRectAtValidRLevel*((double)multiplier);
+      
+      if(!theTemporaryBuffer)
+      {
+         theTemporaryBuffer = (ossimImageData*)theBlankTile->dup();
+         theTemporaryBuffer->setImageRectangle(mappedRequestedRect);
+         theTemporaryBuffer->initialize();
+      }
+      else
+      {
+         theTemporaryBuffer->setImageRectangle(mappedRequestedRect);
+         theTemporaryBuffer->makeBlank();
+      }
+      
+      ossim_uint32 totalCount   = ((requestedRectAtValidRLevel.lr().y-requestedRectAtValidRLevel.ul().y)*
+                                   (requestedRectAtValidRLevel.lr().x-requestedRectAtValidRLevel.ul().x));
+      ossim_uint32 currentCount = 0;
+      ossimIrect boundingRect = theInputConnection->getBoundingRect(levels-1);
+      for(yIndex = requestedRectAtValidRLevel.ul().y;yIndex < requestedRectAtValidRLevel.lr().y; yIndex += tileSize.y)
+      {
+         for(xIndex = requestedRectAtValidRLevel.ul().x; xIndex < requestedRectAtValidRLevel.lr().x; xIndex+=tileSize.x)
+         {
+            ossimIrect request(xIndex,
+                               yIndex,
+                               xIndex + (tileSize.x-1),
+                               yIndex + (tileSize.y-1));
+            ossimRefPtr<ossimImageData> data = theInputConnection->getTile(request, levels-1);
+            
+            if(data.valid() && (data->getDataObjectStatus()!=OSSIM_EMPTY)&&
+               data->getBuf()&&
+               boundingRect.intersects(request))
+            {
+               switch(data->getScalarType())
+               {
+                  case OSSIM_UINT8:
+                  {
+                     resampleTileToDecimation((ossim_uint8)0,
+                                              theTemporaryBuffer,
+                                              data,
+                                              multiplier);
+                     break;
+                  }
+                  case OSSIM_SINT16:
+                  {
+                     resampleTileToDecimation((ossim_sint16)0,
+                                              theTemporaryBuffer,
+                                              data,
+                                              multiplier);
+                     break;
+                  }
+                  case OSSIM_UINT16:
+                  case OSSIM_USHORT11:
+                  {
+                     resampleTileToDecimation((ossim_uint16)0,
+                                              theTemporaryBuffer,
+                                              data,
+                                              multiplier);
+                     break;
+                  }
+                  case OSSIM_FLOAT32:
+                  case OSSIM_NORMALIZED_FLOAT:
+                  {
+                     resampleTileToDecimation((ossim_float32)0,
+                                              theTemporaryBuffer,
+                                              data,
+                                              multiplier);
+                     break;
+                  }
+                  case OSSIM_FLOAT64:
+                  case OSSIM_NORMALIZED_DOUBLE:
+                  {
+                     resampleTileToDecimation((ossim_float64)0,
+                                              theTemporaryBuffer,
+                                              data,
+                                              multiplier);
+                     break;
+                  }
+                  case OSSIM_SCALAR_UNKNOWN:
+                  default:
+                  {
+                     break;
+                  }
+               }
+            }
+            ++currentCount;
+            fireProgressEvent((double)currentCount/
+                              (double)totalCount);
+            
+         }
+      }
+   }
+   theTemporaryBuffer->validate();
+   return theTemporaryBuffer;
+}
+
+template <class T>
+void ossimImageRenderer::resampleTileToDecimation(T dummyVariable,
+						  ossimRefPtr<ossimImageData> result,
+						  ossimRefPtr<ossimImageData> tile,
+						  ossim_uint32 multiplier)
+{
+  if(tile->getDataObjectStatus() == OSSIM_EMPTY ||
+     !tile->getBuf())
+    {
+      return;
+    }
+
+  ossim_int32 maxX     = (ossim_int32)tile->getWidth();
+  ossim_int32 maxY     = (ossim_int32)tile->getHeight();
+  ossim_int32 resultHeight = result->getHeight();
+  ossim_int32* offsetX = new ossim_int32[maxX];
+  ossim_int32* offsetY = new ossim_int32[maxY];
+  ossim_int32 i        = 0;
+  ossim_int32 resultWidth     = (ossim_int32)result->getWidth();
+  ossimIpt tileOrigin   = tile->getOrigin();
+  ossimIpt resultOrigin = result->getOrigin();
+
+  // create a lookup table. that maps the tile to the result
+  for(i = 0; i < maxX; ++i)
+    {
+       offsetX[i] = (i+tileOrigin.x)/(ossim_int32)multiplier - resultOrigin.x;
+       if(offsetX[i] < 0 )
+       {
+          offsetX[i] = 0;
+       }
+       else if(offsetX[i] >= resultWidth)
+       {
+          offsetX[i] = resultWidth-1;
+       }
+    }
+  for(i = 0; i < maxY; ++i)
+    {
+      offsetY[i] = ( ((i+tileOrigin.y)/(ossim_int32)multiplier) - resultOrigin.y);
+      if(offsetY[i] < 0 )
+      {
+         offsetY[i] = 0;
+      }
+      else if(offsetY[i] >= resultHeight)
+      {
+         offsetY[i] = resultHeight-1;
+      }
+      offsetY[i] *= resultWidth;
+    }
+  
+  if(tile->getDataObjectStatus() == OSSIM_FULL)
+    {
+      ossim_int32 numberOfBands = (ossim_int32)std::min(result->getNumberOfBands(),
+					    tile->getNumberOfBands());
+      ossim_int32 band = 0;
+      for(band = 0; band < numberOfBands; ++band)
+	{
+	  T* tileBuf   = static_cast<T*>(tile->getBuf(band));
+	  T* resultBuf = static_cast<T*>(result->getBuf(band));
+	  ossim_int32 dx = 0;
+	  ossim_int32 dy = 0;
+	  ossim_int32 boxAverageX = 0;
+	  ossim_int32 boxAverageY = 0;
+	  for(dy = 0; dy < maxY; dy+=multiplier)
+	    {
+	      for(dx = 0; dx < maxX; dx+=multiplier)
+		{
+		  double sum = 0.0;
+		  for(boxAverageY = 0; 
+		      ((boxAverageY < (ossim_int32)multiplier)&& 
+		       ((boxAverageY+dy)<maxY)); ++boxAverageY)
+		    {
+		      for(boxAverageX = 0; 
+			  ((boxAverageX < (ossim_int32)multiplier)&& 
+			   ((boxAverageX+dx)<maxX)); ++boxAverageX)
+			{
+			  sum += tileBuf[((boxAverageY+dy)*maxX + boxAverageX + dx)];
+			}
+		    }
+		  sum /= (double)(multiplier*multiplier);
+		  resultBuf[ offsetX[dx] + offsetY[dy] ] = (T)sum;
+		}
+	    }
+	}
+    }
+  else
+    {
+      ossim_int32 numberOfBands = (ossim_int32)std::min(result->getNumberOfBands(),
+					    tile->getNumberOfBands());
+      ossim_int32 band = 0;
+      for(band = 0; band < numberOfBands; ++band)
+	{
+	  T* tileBuf   = static_cast<T*>(tile->getBuf(band));
+	  T* resultBuf = static_cast<T*>(result->getBuf(band));
+	  T tileBufNp  = static_cast<T>(tile->getNullPix(band));
+	  ossim_int32 dx = 0;
+	  ossim_int32 dy = 0;
+	  ossim_int32 boxAverageX = 0;
+	  ossim_int32 boxAverageY = 0;
+	  for(dy = 0; dy < maxY; dy+=multiplier)
+	    {
+	      for(dx = 0; dx < maxX; dx+=multiplier)
+		{
+		  double sum = 0.0;
+		  if(tileBuf[((dy+(multiplier>>1))*maxX + dx+(multiplier>>1))] != tileBufNp)
+		    {
+		      ossim_uint32 nullCount = 0;
+		      for(boxAverageY = 0; 
+			  ((boxAverageY < (ossim_int32)multiplier)&& 
+			   ((boxAverageY+dy)<maxY)); ++boxAverageY)
+			{
+			  for(boxAverageX = 0; 
+			      ((boxAverageX < (ossim_int32)multiplier)&& 
+			       ((boxAverageX+dx)<maxX)); ++boxAverageX)
+			    {
+			      T value = tileBuf[((boxAverageY+dy)*maxX + boxAverageX + dx)];
+			      if(value != tileBufNp)
+				{
+				  sum += value;
+				}
+			      else
+				{
+				  ++nullCount;
+				}
+			    }
+			}
+		      ossim_uint32 area = multiplier*multiplier;
+		      sum /= (double)(area);
+		      if(nullCount!= area)
+			{
+			  resultBuf[ offsetX[dx] + offsetY[dy] ] = (T)sum;
+			}
+		    }
+		}
+	    }
+	}
+      
+    }
+
+  delete [] offsetX;
+  delete [] offsetY;
+}
+
+ossimString ossimImageRenderer::getLongName() const
+{
+   return ossimString("Image Renderer");
+}
+
+ossimString ossimImageRenderer::getShortName() const
+{
+   return ossimString("Image Renderer"); 
+}
+
+ void ossimImageRenderer::enableSource()
+{
+   ossimImageSourceFilter::enableSource();
+   checkTransform();
+   initialize();
+}
+
+void ossimImageRenderer::fireProgressEvent(double percentComplete)
+{
+   ossimProcessProgressEvent event(this, percentComplete);
+   fireEvent(event);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageRenderer.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageRenderer.h
new file mode 100644
index 0000000000..c47386ede4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageRenderer.h
@@ -0,0 +1,402 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*******************************************************************
+// $Id: ossimImageRenderer.h,v 1.63 2005/11/09 14:31:23 gpotts Exp $
+
+#ifndef ossimImageRenderer_HEADER
+#define ossimImageRenderer_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <base/common/ossimViewInterface.h>
+#include <base/data_types/ossimRationalNumber.h>
+
+class ossimImageViewTransform;
+class ossimImageData;
+class ossimDiscreteConvolutionKernel;
+class ossimFilterResampler;
+
+class OSSIMDLLEXPORT ossimImageRenderer : public ossimImageSourceFilter,
+                                          public ossimViewInterface
+{
+public:
+   ossimImageRenderer();
+   ossimImageRenderer(ossimImageSource* inputSource,
+                      ossimImageViewTransform* imageViewTrans = NULL);
+   virtual ~ossimImageRenderer();
+
+   virtual ossimString getLongName()  const;
+   virtual ossimString getShortName() const;
+
+   virtual void enableSource();
+   
+   /**
+    * the resampler will need the tile request to come from the view.
+    * It will use the view to transoform this to world and then use the
+    * image's projection to get it into final line sample.  This way
+    * the resampler can fill a tile width by height on the screen
+    * correctly.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                               ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+
+   /**
+    * TheResampler will adjust the rect to whatever the view is.  So it
+    * will project the full image rect onto the view and return the upright
+    * bounding rect.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   void setImageViewTransform(ossimImageViewTransform* transform);
+   ossimImageViewTransform* getImageViewTransform(){return theImageViewTransform;}
+
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+   virtual bool setView(ossimObject* baseObject,
+                        bool ownsTheView = false);
+   ossimFilterResampler* getResampler()
+      {
+         return theResampler;
+      }
+   virtual ossimObject* getView();
+   virtual const ossimObject* getView()const;
+
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result)const;
+  virtual void getDecimationFactors(vector<ossimDpt>& decimations)const;
+  virtual ossim_uint32 getNumberOfDecimationLevels()const;
+  
+
+   virtual void setAutoUpdateInputTransformFlag(bool flag)
+      {
+         theAutoUpdateInputTransform = flag;
+      }
+   /**
+    * ordering specifies how the vertices should be arranged.
+    * valid image vertices is basically the tightly fit convex hull
+    * of the image.  Usually an image has NULL values and are
+    * internally not upright rectangular.  This can cause
+    * problems some spatial filters.
+    *
+    * We need to make sure that the resampler overrides this method.
+    * it needs to transform the vertices to the view's side.
+    */
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const;
+
+   void connectInputEvent(ossimConnectionEvent& event);
+   void disconnectInputEvent(ossimConnectionEvent& event);
+   void propertyEvent(ossimPropertyEvent& event);
+   
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+private:
+   
+
+   class ossimRendererSubRectInfo
+   {
+   public:
+      friend std::ostream& operator <<(std::ostream& out,
+                                       const ossimRendererSubRectInfo& rhs)
+         {
+            return out << "vul:   " << rhs.theVul << endl
+                       << "vur:   " << rhs.theVur << endl
+                       << "vlr:   " << rhs.theVlr << endl
+                       << "vll:   " << rhs.theVll << endl
+                       << "iul:   " << rhs.theIul << endl
+                       << "iur:   " << rhs.theIur << endl
+                       << "ilr:   " << rhs.theIlr << endl
+                       << "ill:   " << rhs.theIll << endl
+                       << "scale: " << rhs.theViewToImageScale << endl;
+               
+         }
+      ossimRendererSubRectInfo()
+         {
+            theVul.makeNan();
+            theVur.makeNan();
+            theVlr.makeNan();
+            theVll.makeNan();
+            theIul.makeNan();
+            theIur.makeNan();
+            theIlr.makeNan();
+            theIll.makeNan();
+            theViewToImageScale.makeNan();
+            theImageToViewScale.makeNan();            
+         }
+      ossimRendererSubRectInfo(const ossimDpt& vul,
+                               const ossimDpt& vur,
+                               const ossimDpt& vlr,
+                               const ossimDpt& vll)
+         :theVul(vul),
+          theVur(vur),
+          theVlr(vlr),
+          theVll(vll)
+         {
+            theIul.makeNan();
+            theIur.makeNan();
+            theIlr.makeNan();
+            theIll.makeNan();
+            theViewToImageScale.makeNan();
+            theImageToViewScale.makeNan();            
+         }
+         
+      bool imageHasNans()const
+         {
+            return ( theIul.hasNans()||
+                     theIur.hasNans()||
+                     theIlr.hasNans()||
+                     theIll.hasNans());
+         }
+      
+      bool imageIsNan()const
+         {
+            return ( theIul.hasNans()&&
+                     theIur.hasNans()&&
+                     theIlr.hasNans()&&
+                     theIll.hasNans());
+         }
+      bool viewHasNans()const
+      {
+         return ( theVul.hasNans()||
+                  theVur.hasNans()||
+                  theVlr.hasNans()||
+                  theVll.hasNans());
+      }
+      bool viewIsNan()const
+      {
+         return ( theVul.hasNans()&&
+                  theVur.hasNans()&&
+                  theVlr.hasNans()&&
+                  theVll.hasNans());
+      }
+      void splitView(ossimImageViewTransform* transform,
+                     ossimRendererSubRectInfo& ulRect,
+                     ossimRendererSubRectInfo& urRect,
+                     ossimRendererSubRectInfo& lrRect,
+                     ossimRendererSubRectInfo& llRect)const;
+      
+      void transformViewToImage(ossimImageViewTransform* transform);
+      void transformImageToView(ossimImageViewTransform* transform);
+      
+      void roundToInteger()
+         {
+            theIul = ossimIpt(theIul);
+            theIur = ossimIpt(theIur);
+            theIlr = ossimIpt(theIlr);
+            theIll = ossimIpt(theIll);
+
+            theVul = ossimIpt(theVul);
+            theVur = ossimIpt(theVur);
+            theVlr = ossimIpt(theVlr);
+            theVll = ossimIpt(theVll);
+         }
+      void stretchImageOut(bool enableRound=false);
+      ossimDrect getViewRect()const
+         {
+            return ossimDrect(theVul,
+                              theVur,
+                              theVlr,
+                              theVll);            
+         }
+      ossimDrect getImageRect()const
+         {
+            return ossimDrect(theIul,
+                              theIur,
+                              theIlr,
+                              theIll);
+         }
+      void roundImageToInteger()
+         {
+            theIul = ossimIpt(theIul);
+            theIur = ossimIpt(theIur);
+            theIlr = ossimIpt(theIlr);
+            theIll = ossimIpt(theIll);
+         }
+      void roundViewToInteger()
+         {
+            theVul = ossimIpt(theVul);
+            theVur = ossimIpt(theVur);
+            theVlr = ossimIpt(theVlr);
+            theVll = ossimIpt(theVll);
+         }
+      bool isViewEqual(const ossimRendererSubRectInfo& infoRect)const
+         {
+            return ( (theVul == infoRect.theVul)&&
+                     (theVur == infoRect.theVur)&&
+                     (theVlr == infoRect.theVlr)&&
+                     (theVll == infoRect.theVll));
+         }
+      bool isViewEqual(const ossimDrect& viewRect)const
+         {
+            return ( (theVul == viewRect.ul())&&
+                     (theVur == viewRect.ur())&&
+                     (theVlr == viewRect.lr())&&
+                     (theVll == viewRect.ll()));
+         }
+      ossimDpt getAbsValueViewToImageScales()const
+         {
+            if(theViewToImageScale.hasNans())
+            {
+               return theImageToViewScale;
+            }
+            return ossimDpt(fabs(theViewToImageScale.x),
+                            fabs(theViewToImageScale.y));
+         }
+      ossimDpt getAbsValueImageToViewScales()const
+         {
+            if(theImageToViewScale.hasNans())
+            {
+               return theImageToViewScale;
+            }
+            
+            return ossimDpt(fabs(theImageToViewScale.x),
+                            fabs(theImageToViewScale.y));
+         }
+      bool isViewAPoint()const
+         {
+            return ((theVul == theVur)&&
+                    (theVul == theVlr)&&
+                    (theVul == theVll));
+         }
+      bool isIdentity()const;
+      bool canBilinearInterpolate(ossimImageViewTransform* transform,
+				  double error)const;
+
+      ossimDpt getParametricCenter(const ossimDpt& ul, const ossimDpt& ur, 
+				    const ossimDpt& lr, const ossimDpt& ll)const;
+
+     void getViewMids(ossimDpt& upperMid,
+		      ossimDpt& rightMid,
+		      ossimDpt& bottomMid,
+		      ossimDpt& leftMid,
+		      ossimDpt& center)const;
+
+     void getImageMids(ossimDpt& upperMid,
+		       ossimDpt& rightMid,
+		       ossimDpt& bottomMid,
+		       ossimDpt& leftMid,
+		       ossimDpt& center)const;
+
+      ossimDpt theIul;
+      ossimDpt theIur;
+      ossimDpt theIlr;
+      ossimDpt theIll;
+
+      ossimIpt theVul;
+      ossimIpt theVur;
+      ossimIpt theVlr;
+      ossimIpt theVll;
+
+      ossimDpt theViewToImageScale;
+      ossimDpt theImageToViewScale;
+      
+   };
+
+   void recursiveResample(ossimRefPtr<ossimImageData> outputData,
+                          const ossimRendererSubRectInfo& rectInfo,
+			  ossim_uint32 level);
+   
+
+   void fillTile(ossimRefPtr<ossimImageData> outputData,
+                 const ossimRendererSubRectInfo& rectInfo);
+                 
+   ossimIrect getBoundingImageRect()const;
+
+   
+   /**
+    *this is called on a property event and on input connection changes.
+    */
+   void checkTransform();
+
+   void computeRects();
+
+   ossimRefPtr<ossimImageData> getTileAtResLevel(const ossimIrect& boundingRect,
+                                     ossim_uint32 resLevel);
+  template <class T>
+  void resampleTileToDecimation(T dummyVariable,
+				ossimRefPtr<ossimImageData> result,
+				ossimRefPtr<ossimImageData> tile,
+				ossim_uint32 multiplier);
+
+   long computeClosestResLevel(const std::vector<ossimDpt>& decimationFactors,
+                               double scale)const;
+   void stretchQuadOut(const ossimDpt& amount,
+                       ossimDpt& ul,
+                       ossimDpt& ur,
+                       ossimDpt& lr,
+                       ossimDpt& ll);
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+
+   /**
+    *  Deletes all allocated tiles.
+    */
+   void deallocate();
+
+   virtual void fireProgressEvent(double percentComplete);
+   
+   ossimFilterResampler*       theResampler;
+   ossimRefPtr<ossimImageData> theBlankTile;
+   ossimRefPtr<ossimImageData> theTile;
+   ossimRefPtr<ossimImageData> theTemporaryBuffer;
+   ossimRefPtr<ossimImageData> theCachedTile;
+   ossim_uint32                theCachedTileResLevel;
+
+   /**
+    * This is going to allow us to chain multiple
+    * renderers together.  So if we have one
+    * renderer doing a scale and they pass an r-level
+    * down and we have another renderer within the
+    * chain he will be starting at a different r-level.
+    * The default will be r-level 0 request coming
+    * from the right.
+    */
+   ossim_uint32             theStartingResLevel;
+   ossimImageViewTransform *theImageViewTransform;
+   mutable ossimIrect               theBoundingRect;
+   mutable ossimIrect               theBoundingViewRect;
+
+   /**
+    * Holds a pre-computed input rect.
+    */
+//   ossimIrect                theInputRect;
+
+   /**
+    * Holds a precomputed output rect.
+    */
+//   ossimIrect                theOutputRect;
+
+   ossim_uint32               theMaxRecursionLevel;
+   bool                       theAutoUpdateInputTransform;
+   vector<ossimDpt>           theInputDecimationFactors;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSharpenFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSharpenFilter.cpp
new file mode 100644
index 0000000000..f63054cada
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSharpenFilter.cpp
@@ -0,0 +1,368 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageSharpenFilter.cpp,v 1.8 2005/02/11 15:07:33 dburken Exp $
+#include <imaging/tile_sources/ossimImageSharpenFilter.h>
+#include <base/data_types/ossimIrect.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF1(ossimImageSharpenFilter, "ossimImageSharpenFilter", ossimImageSourceFilter);
+
+ossimImageSharpenFilter::ossimImageSharpenFilter(ossimObject* owner)
+   :ossimImageSourceFilter(owner),
+    theTile(NULL)
+{
+}
+
+ossimImageSharpenFilter::~ossimImageSharpenFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimImageSharpenFilter::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;
+   }
+
+   if(!isSourceEnabled())
+   {
+      return theInputConnection->getTile(tileRect, resLevel);
+   }
+   
+   // we have a 3x3 matrix so stretch the rect out to cover
+   // the required pixels
+   //
+   ossimIrect newRect(ossimIpt(tileRect.ul().x - 1,
+                               tileRect.ul().y - 1),
+                      ossimIpt(tileRect.lr().x + 1,
+                               tileRect.lr().y + 1));
+   
+   ossimRefPtr<ossimImageData> data =
+      theInputConnection->getTile(newRect, resLevel);
+
+   if ( !data.valid() ||
+        ( data->getDataObjectStatus() == OSSIM_NULL ) ||
+        ( data->getDataObjectStatus() == OSSIM_EMPTY ) )
+   {
+      // Caller wants tileRect, not newRect so don't return "data".
+      return theInputConnection->getTile(tileRect, resLevel);
+   }
+
+   if (!theTile)
+   {
+      allocate(); // First time through...
+   }
+   
+   long w     = tileRect.width();
+   long h     = tileRect.height();
+   long tileW = theTile->getWidth();
+   long tileH = theTile->getHeight();
+   if((w != tileW)||
+      (h != tileH))
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+      }
+      else
+      {
+         theTile->makeBlank();
+      }
+   }
+   else
+   {
+      theTile->makeBlank();
+   }
+   theTile->setOrigin(tileRect.ul());
+   
+   switch(data->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      if(data->getDataObjectStatus() == OSSIM_FULL)
+      {
+         sharpenFull(static_cast<ossim_uint8>(0),
+                     data,
+                     theTile);
+      }
+      else
+      {
+         sharpenPartial(static_cast<ossim_uint8>(0),
+                        data,
+                        theTile);
+      }
+      break;
+   }
+   case OSSIM_FLOAT: 
+   case OSSIM_NORMALIZED_FLOAT:
+   {
+      if(data->getDataObjectStatus() == OSSIM_FULL)
+      {
+         sharpenFull(static_cast<float>(0),
+                     data,
+                     theTile);
+      }
+      else
+      {
+         sharpenPartial(static_cast<float>(0),
+                        data,
+                        theTile);
+      }
+      break;
+   }
+   case OSSIM_USHORT16:
+   case OSSIM_USHORT11:
+   {
+      if(data->getDataObjectStatus() == OSSIM_FULL)
+      {
+         sharpenFull(static_cast<ossim_uint16>(0),
+                     data,
+                     theTile);
+      }
+      else
+      {
+         sharpenPartial(static_cast<ossim_uint16>(0),
+                        data,
+                        theTile);
+      }
+      break;
+   }
+   case OSSIM_SSHORT16:
+   {
+      if(data->getDataObjectStatus() == OSSIM_FULL)
+      {
+         sharpenFull(static_cast<ossim_sint16>(0),
+                     data,
+                     theTile);
+      }
+      else
+      {
+         sharpenPartial(static_cast<ossim_sint16>(0),
+                        data,
+                        theTile);
+      }
+      break;
+   }
+   case OSSIM_DOUBLE:
+   case OSSIM_NORMALIZED_DOUBLE:
+   {
+      if(data->getDataObjectStatus() == OSSIM_FULL)
+      {
+         sharpenFull(static_cast<double>(0),
+                     data,
+                     theTile);
+      }
+      else
+      {
+         sharpenPartial(static_cast<double>(0),
+                        data,
+                        theTile);
+      }
+      break;
+   }
+   default:
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimImageSharpenFilter::getTile WARNING: Scalar type = " << theTile->getScalarType() << " Not supported!" << std::endl;
+      break;
+   }
+   }
+   theTile->validate();
+   
+   return theTile;
+}
+
+
+template<class T> void ossimImageSharpenFilter::sharpenPartial(
+   T,
+   const ossimRefPtr<ossimImageData>& inputData,
+   ossimRefPtr<ossimImageData>& outputData)
+{
+   double sum = 0.0;
+   ossim_int32 inputW        = (ossim_int32)inputData->getWidth();
+   ossim_int32 outputW       = (ossim_int32)outputData->getWidth();
+   ossim_int32 outputH       = (ossim_int32)outputData->getHeight();
+   ossim_int32 numberOfBands = (ossim_int32)inputData->getNumberOfBands();
+   ossimIpt outputOrigin = outputData->getOrigin();
+   ossimIpt inputOrigin  = inputData->getOrigin();
+   
+   ossim_int32 startInputOffset = ossimAbs(outputOrigin.y - inputOrigin.y)*
+      inputW + ossimAbs(outputOrigin.x - inputOrigin.x);
+   ossim_int32 ulKernelStart    = -inputW - 1;
+   ossim_int32 leftKernelStart  = -1;
+   ossim_int32 llKernelStart    = inputW  - 1;
+   
+   const T* ulKernelStartBuf   = NULL;
+   const T* leftKernelStartBuf = NULL;
+   const T* llKernelStartBuf   = NULL;
+   
+   for(ossim_int32 band = 0; band < numberOfBands; ++band)
+   {
+      const T* inputBuf  = static_cast<const T*>(inputData->getBuf(band)) +
+         startInputOffset;
+      T* outputBuf = static_cast<T*>(outputData->getBuf(band));
+      T maxPix     = static_cast<T>(inputData->getMaxPix(band));
+      T minPix     = static_cast<T>(inputData->getMinPix(band));
+      T nullPix    = static_cast<T>(inputData->getNullPix(band));
+      
+      if(inputBuf&&outputBuf)
+      {
+         for(ossim_int32 row = 0; row < outputW; ++row)
+         {
+            ossim_int32 rowOffset    = inputW*row;
+            ulKernelStartBuf   = inputBuf + (rowOffset + ulKernelStart);
+            leftKernelStartBuf = inputBuf + (rowOffset + leftKernelStart);
+            llKernelStartBuf   = inputBuf + (rowOffset + llKernelStart);
+            for(ossim_int32 col = 0; col < outputH; ++col)
+            {
+               if((ulKernelStartBuf[0]   != nullPix)&&
+                  (ulKernelStartBuf[1]   != nullPix)&&
+                  (ulKernelStartBuf[2]   != nullPix)&&
+                  (leftKernelStartBuf[0] != nullPix)&&
+                  (leftKernelStartBuf[1] != nullPix)&&
+                  (leftKernelStartBuf[2] != nullPix)&&
+                  (llKernelStartBuf[0]   != nullPix)&&
+                  (llKernelStartBuf[1]   != nullPix)&&
+                  (llKernelStartBuf[2]   != nullPix))
+               {
+                  sum = -1.0*(double)ulKernelStartBuf[0]  + -2.0*(double)ulKernelStartBuf[1] + -1.0*(double)ulKernelStartBuf[2] +
+                        -2.0*(double)leftKernelStartBuf[0]  + 16.0*(double)leftKernelStartBuf[1] + -2.0*(double)leftKernelStartBuf[2] +
+                        -1.0*(double)llKernelStartBuf[0]  + -2.0*(double)llKernelStartBuf[1] + -1.0*(double)llKernelStartBuf[2];
+                  sum /= 4.0;
+                  
+                  if(sum > maxPix)
+                  {
+                     *outputBuf = maxPix;
+                  }
+                  else if(sum < minPix || ((T)sum == nullPix))
+                  {
+                     *outputBuf = minPix;
+                  }
+                  else
+                  {
+                     *outputBuf = static_cast<T>(sum);
+                  }
+               }
+               else
+               {
+                  *outputBuf = nullPix;
+               }
+               
+               ++ulKernelStartBuf;
+               ++leftKernelStartBuf;
+               ++llKernelStartBuf;
+               ++outputBuf;
+            }
+         }
+      }
+   }
+}
+
+template<class T> void ossimImageSharpenFilter::sharpenFull(
+   T,
+   const ossimRefPtr<ossimImageData>& inputData,
+   ossimRefPtr<ossimImageData>& outputData)
+{
+   double sum = 0.0;
+   ossim_int32 inputW        = (ossim_int32)inputData->getWidth();
+   ossim_int32 outputW       = (ossim_int32)outputData->getWidth();
+   ossim_int32 outputH       = (ossim_int32)outputData->getHeight();
+   ossim_int32 numberOfBands = (ossim_int32)inputData->getNumberOfBands();
+   ossimIpt outputOrigin = outputData->getOrigin();
+   ossimIpt inputOrigin  = inputData->getOrigin();
+   
+   ossim_int32 startInputOffset = ossimAbs(outputOrigin.y - inputOrigin.y)*
+      inputW + ossimAbs(outputOrigin.x - inputOrigin.x);
+   ossim_int32 ulKernelStart    = -inputW - 1;
+   ossim_int32 leftKernelStart  = -1;
+   ossim_int32 llKernelStart    = inputW  - 1;
+   
+   const T* ulKernelStartBuf   = NULL;
+   const T* leftKernelStartBuf = NULL;
+   const T* llKernelStartBuf   = NULL;
+   
+   for(ossim_int32 band = 0; band < numberOfBands; ++band)
+   {
+      const T* inputBuf  = static_cast<const T*>(inputData->getBuf(band)) +
+         startInputOffset;
+      T* outputBuf = static_cast<T*>(outputData->getBuf(band));
+      T maxPix     = static_cast<T>(inputData->getMaxPix(band));
+      T minPix     = static_cast<T>(inputData->getMinPix(band));
+      T nullPix    = static_cast<T>(inputData->getNullPix(band));
+      
+      if(inputBuf&&outputBuf)
+      {
+         for(ossim_int32 row = 0; row < outputW; ++row)
+         {
+            ossim_int32 rowOffset    = inputW*row;
+            ulKernelStartBuf   = inputBuf + (rowOffset + ulKernelStart);
+            leftKernelStartBuf = inputBuf + (rowOffset + leftKernelStart);
+            llKernelStartBuf   = inputBuf + (rowOffset + llKernelStart);
+            for(ossim_int32 col = 0; col < outputH; ++col)
+            {
+               sum = -1.0*(double)ulKernelStartBuf[0]  + -2.0*(double)ulKernelStartBuf[1] + -1.0*(double)ulKernelStartBuf[2] +
+                     -2.0*(double)leftKernelStartBuf[0]  + 16.0*(double)leftKernelStartBuf[1] + -2.0*(double)leftKernelStartBuf[2] +
+                     -1.0*(double)llKernelStartBuf[0]  + -2.0*(double)llKernelStartBuf[1] + -1.0*(double)llKernelStartBuf[2];
+               sum /= 4.0;
+               
+               if(sum > maxPix)
+               {
+                  *outputBuf = maxPix;
+               }
+               else if((sum < minPix) || (sum == nullPix))
+               {
+                  *outputBuf = minPix;
+               }
+               else
+               {
+                  *outputBuf = static_cast<T>(sum);
+               }
+               
+               ++ulKernelStartBuf
+                  ;
+               ++leftKernelStartBuf;
+               ++llKernelStartBuf;
+               ++outputBuf;
+            }
+         }
+      }
+   }
+}
+
+void ossimImageSharpenFilter::initialize()
+{
+   // Hmmm... (drb)
+}
+
+void ossimImageSharpenFilter::allocate()
+{   
+   theTile = NULL;
+   if(theInputConnection)
+   {
+      ossimImageDataFactory* idf = ossimImageDataFactory::instance();
+      theTile = idf->create(this, this);
+      theTile->initialize();
+   }
+}
+
+ossimString ossimImageSharpenFilter::getShortName() const
+{
+   return ossimString("Sharpen");
+}
+
+ossimString ossimImageSharpenFilter::getLongName() const
+{
+   return ossimString("Sharpens the input input");
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSharpenFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSharpenFilter.h
new file mode 100644
index 0000000000..185b08a14b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSharpenFilter.h
@@ -0,0 +1,60 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageSharpenFilter.h,v 1.6 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimImageSharpenFilter_HEADER
+#define ossimImageSharpenFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class OSSIMDLLEXPORT ossimImageSharpenFilter : public ossimImageSourceFilter
+{
+public:
+   ossimImageSharpenFilter(ossimObject* owner=NULL);
+   virtual ~ossimImageSharpenFilter();
+
+   virtual ossimString getShortName()const;
+   virtual ossimString getLongName()const;
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual void initialize();
+   
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   virtual void allocate();
+   
+   ossimRefPtr<ossimImageData> theTile;
+
+   /*!
+    * Convolve full means that the input data is full and has
+    * no null data.  We don't have to compare for nulls here
+    */
+   template<class T>
+   void sharpenFull(T,
+                    const ossimRefPtr<ossimImageData>& inputData,
+                    ossimRefPtr<ossimImageData>& outputData);
+   
+   /*!
+    * Convolve partial means that the input data is has some
+    * null data.  We will have to compare nulls
+    */
+   template<class T>
+   void sharpenPartial(T,
+                       const ossimRefPtr<ossimImageData>& inputData,
+                       ossimRefPtr<ossimImageData>& outputData);
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimImageSharpenFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceFilter.cpp
new file mode 100644
index 0000000000..7e9c1326e8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceFilter.cpp
@@ -0,0 +1,340 @@
+
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimImageSourceFilter.cpp,v 1.49 2005/09/15 12:28:44 gpotts Exp $
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <base/common/ossimTrace.h>
+#include <base/property/ossimProperty.h>
+ 
+static ossimTrace traceDebug("ossimImageSourceFilter:degug");
+
+RTTI_DEF2(ossimImageSourceFilter, "ossimImageSourceFilter", ossimImageSource, ossimConnectableObjectListener)
+
+ossimImageSourceFilter::ossimImageSourceFilter(ossimObject* owner)
+   : ossimImageSource(owner,
+                      1, // number of inputs
+                      0, // number of outputs
+                      true, // input's fixed
+                      false), // outputs ar not fixed
+     theInputConnection(NULL)
+{
+   addListener((ossimConnectableObjectListener*)this);
+}
+
+ossimImageSourceFilter::ossimImageSourceFilter(ossimImageSource* inputSource)
+   : ossimImageSource(NULL,
+                      1,
+                      0,
+                      true,
+                      false),
+     theInputConnection(inputSource)
+{
+   if(inputSource)
+   {
+     connectMyInputTo(0, inputSource);
+   }
+   addListener((ossimConnectableObjectListener*)this);
+}
+
+ossimImageSourceFilter::ossimImageSourceFilter(ossimObject* owner,
+                                               ossimImageSource* inputSource)
+   : ossimImageSource(owner,
+                      1,
+                      0,
+                      true,
+                      false),
+     theInputConnection(inputSource)
+{
+   if(inputSource)
+   {
+      theInputObjectList[0] = inputSource;
+      inputSource->connectMyOutputTo(this, false);
+   }
+   addListener((ossimConnectableObjectListener*)this);
+}
+
+
+ossimImageSourceFilter::~ossimImageSourceFilter()
+{
+   removeListener((ossimConnectableObjectListener*)this);
+   theInputConnection = NULL;
+}
+
+ossimRefPtr<ossimImageData> ossimImageSourceFilter::getTile(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getTile(rect, resLevel);
+   }
+   
+   return ossimRefPtr<ossimImageData>(NULL);
+}
+
+ossimIrect ossimImageSourceFilter::getBoundingRect(ossim_uint32 resLevel) const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getBoundingRect(resLevel);
+   }
+   ossimIrect rect;
+   rect.makeNan();
+   
+   return rect;
+}
+
+void ossimImageSourceFilter::getDecimationFactor(ossim_uint32 resLevel,
+                                                 ossimDpt& result) const
+{
+   if(theInputConnection)
+   {
+      theInputConnection->getDecimationFactor(resLevel,
+                                              result);
+   }
+   else // Ok assume square and powers of 2
+   {
+      double dec = 1.0/pow((double)2.0,(double)resLevel);
+      result.x = dec;
+      result.y = dec;
+   }
+}
+
+void ossimImageSourceFilter::getDecimationFactors(vector<ossimDpt>& decimations) const
+{
+   if(theInputConnection)
+   {
+      theInputConnection->getDecimationFactors(decimations);
+   }   
+}
+
+ossim_uint32 ossimImageSourceFilter::getNumberOfDecimationLevels()const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getNumberOfDecimationLevels();
+   }
+
+   return 0;
+}
+
+ossim_uint32 ossimImageSourceFilter::getNumberOfInputBands()const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getNumberOfOutputBands();
+   }
+
+   return 0;
+}
+
+ossimScalarType ossimImageSourceFilter::getOutputScalarType() const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getOutputScalarType();
+   }
+
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+void ossimImageSourceFilter::getValidImageVertices(vector<ossimIpt>& validVertices,
+                                                   ossimVertexOrdering ordering,
+                                                   ossim_uint32 resLevel)const
+{
+   if(theInputConnection)
+   {
+      theInputConnection->getValidImageVertices(validVertices, ordering, resLevel);
+   }
+}
+
+ossim_uint32 ossimImageSourceFilter::getTileWidth() const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getTileWidth();
+   }
+   
+   return 0;
+}
+
+ossim_uint32 ossimImageSourceFilter::getTileHeight() const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getTileHeight();
+   }
+
+   return 0;
+}
+
+void ossimImageSourceFilter::initialize()
+{
+   theInputConnection = PTR_CAST(ossimImageSourceInterface, getInput(0));
+}
+
+bool ossimImageSourceFilter::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   bool result = ossimImageSource::loadState(kwl, prefix);
+
+   // make sure we have 1 input.
+   setNumberOfInputs(1);
+
+   // we will fix the input
+   if(!theInputListIsFixedFlag)
+   {
+      theInputListIsFixedFlag = true;
+   }
+   
+   return result;
+}
+
+bool ossimImageSourceFilter::saveState(ossimKeywordlist& kwl,
+                                       const char* prefix)const
+{
+   return ossimImageSource::saveState(kwl, prefix);
+}
+
+
+bool ossimImageSourceFilter::canConnectMyInputTo(ossim_int32 inputIndex,
+						 const ossimConnectableObject* object)const
+{
+  
+  return ((PTR_CAST(ossimImageSourceInterface, object)||!object) && ( inputIndex == 0 ) );
+}
+
+void ossimImageSourceFilter::connectInputEvent(ossimConnectionEvent& event)
+{
+  if(traceDebug())
+    {
+       ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageSourceFilter::connectInputEvent: ";
+
+       if(getInput())
+       {
+          ossimNotify(ossimNotifyLevel_DEBUG) << "to" <<  getInput()->getClassName() << std::endl;
+       }
+       else
+       {
+          ossimNotify(ossimNotifyLevel_DEBUG) << "to NULL" << std::endl;
+       }
+    }
+  theInputConnection = PTR_CAST(ossimImageSourceInterface, getInput(0));
+  initialize();
+  if(traceDebug())
+  {
+     if(theInputConnection)
+     {
+        ossimNotify(ossimNotifyLevel_DEBUG) << "theInputConnection was set to " << getInput()->getClassName() << std::endl;
+     }
+     else
+     {
+        ossimNotify(ossimNotifyLevel_DEBUG) << "theInputConnection was set to NULL" <<  std::endl;
+     }
+     ossimNotify(ossimNotifyLevel_DEBUG) << "Leaving ossimImageSourceFilter::connectInput" << std::endl;
+  }
+}
+void ossimImageSourceFilter::disconnectInputEvent(ossimConnectionEvent& event)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageSourceFilter::disconnectInputEvent" << std::endl;
+   }
+   theInputConnection = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   initialize();
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "Leaving ossimImageSourceFilter::disconnectInput" << std::endl;
+   }
+}
+void ossimImageSourceFilter::propertyEvent(ossimPropertyEvent& event)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageSourceFilter::propertyEvent DEBUG: Entering..." << std::endl;
+   }
+   initialize();
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageSourceFilter::propertyEvent DEBUG: Leaving..." << std::endl;
+   }
+}
+
+void ossimImageSourceFilter::refreshEvent(ossimRefreshEvent& event)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageSourceFilter::refreshEvent " << std::endl;
+   }
+   initialize();
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageSourceFilter::refreshEvent " << std::endl;
+   }
+}
+
+double ossimImageSourceFilter::getNullPixelValue(ossim_uint32 band)const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getNullPixelValue(band);
+   }
+   return ossimImageSource::getNullPixelValue(band);
+}
+
+double ossimImageSourceFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getMinPixelValue(band);
+   }
+   return ossimImageSource::getMinPixelValue(band);
+}
+
+double ossimImageSourceFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getMaxPixelValue(band);
+   }
+   return ossimImageSource::getMaxPixelValue(band);
+}
+
+void ossimImageSourceFilter::getOutputBandList(std::vector<ossim_uint32>& bandList) const
+{
+   if(theInputConnection)
+   {
+      return theInputConnection->getOutputBandList(bandList);
+   }
+
+   return ossimImageSource::getOutputBandList(bandList);
+}
+
+void ossimImageSourceFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   ossimImageSource::setProperty(property);
+}
+
+ossimRefPtr<ossimProperty> ossimImageSourceFilter::getProperty(const ossimString& name)const
+{
+   return ossimImageSource::getProperty(name);
+   
+}
+
+void ossimImageSourceFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSource::getPropertyNames(propertyNames);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceFilter.h
new file mode 100644
index 0000000000..04e1900c38
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceFilter.h
@@ -0,0 +1,115 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimImageSourceFilter.h,v 1.49 2005/09/15 12:28:44 gpotts Exp $
+#ifndef ossimImageSourceFilter_HEADER
+#define ossimImageSourceFilter_HEADER
+#include <imaging/ossimImageSource.h>
+#include <base/common/events/ossimConnectableObjectListener.h>
+#include <base/common/events/ossimConnectionEvent.h>
+
+class OSSIMDLLEXPORT ossimImageSourceFilter : public ossimImageSource,
+     public ossimConnectableObjectListener
+{
+public:
+   ossimImageSourceFilter(ossimObject* owner=NULL);
+   ossimImageSourceFilter(ossimImageSource* inputSource);
+   ossimImageSourceFilter(ossimObject* owner,
+                          ossimImageSource* inputSource);
+   virtual ~ossimImageSourceFilter();
+
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result)const;
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations)const;
+   virtual ossim_uint32 getNumberOfDecimationLevels()const;
+
+   /*!
+    * Returns the input connection's output band list.
+    * If not connected calls ossimImageSource::getOutputBandList.
+    */
+   virtual void getOutputBandList(std::vector<ossim_uint32>& bandList) const;
+   
+   /*!
+    * Returns the number of bands available from the input.
+    */
+   virtual ossim_uint32 getNumberOfInputBands()const;   
+
+   virtual ossimScalarType getOutputScalarType() const;
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+
+   /*!
+    * ordering specifies how the vertices should be arranged.
+    * valid image vertices is basically the tightly fit convex hull
+    * of the image.  Usually an image has NULL values and are
+    * internally not upright rectangular.  This can cause
+    * problems some spatial filters.
+    *
+    * The default implementation is to return the bounding rect.
+    */
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const;
+   
+   virtual ossim_uint32 getTileWidth() const;
+   
+   virtual ossim_uint32 getTileHeight() const;
+
+   virtual void initialize();
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * getNullPixelValue
+    * Returns the null pixel value of input connection if connected.
+    * Returns OSSIM_DBL_NAN if not connected.
+    */
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+
+   /*!
+    * getMinPixelValue
+    * Returns the null pixel value of input connection if connected.
+    * Returns OSSIM_DBL_NAN if not connected.
+    */
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+
+   /*!
+    * getMaxPixelValue
+    * Returns the null pixel value of input connection if connected.
+    * Returns OSSIM_DBL_NAN if not connected.
+    */
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const;
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+   virtual void propertyEvent(ossimPropertyEvent& event);
+   virtual void refreshEvent(ossimRefreshEvent& event);
+   
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   
+protected:
+   ossimImageSourceInterface* theInputConnection;
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimImageSourceFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceHistogramFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceHistogramFilter.cpp
new file mode 100644
index 0000000000..c374f5c36b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceHistogramFilter.cpp
@@ -0,0 +1,238 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimImageSourceHistogramFilter.cpp,v 1.12 2005/08/31 15:47:42 gpotts Exp $
+#include "ossimImageSourceHistogramFilter.h"
+#include "base/common/ossimHistogramSource.h"
+#include "base/data_types/ossimMultiResLevelHistogram.h"
+#include "base/data_types/ossimMultiBandHistogram.h"
+#include "base/data_types/ossimHistogram.h"
+#include "base/common/ossimCommon.h"
+#include "imaging/ossimImageData.h"
+#include "base/data_types/ossimKeyword.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+static const ossimKeyword PROPRIETARY_FILENAME_KW("proprietary_filename",
+                                                  "imports a proprietary file");
+
+static const ossimKeyword HISTOGRAM_FILENAME_KW("histogram_filename",
+                                                "read an OSSIM histogram file");
+
+
+RTTI_DEF1(ossimImageSourceHistogramFilter, "ossimImageSourceHistogramFilter", ossimImageSourceFilter)
+   
+ossimImageSourceHistogramFilter::ossimImageSourceHistogramFilter()
+   :ossimImageSourceFilter(),
+    theCurrentResLevel(0),
+    theHistogram(NULL),
+    theFilename("")
+{
+   setNumberOfInputs(2);
+   theInputListIsFixedFlag = true;
+}
+
+ossimImageSourceHistogramFilter::ossimImageSourceHistogramFilter(ossimImageSource* inputSource,
+                                                                 ossimMultiResLevelHistogram* histogram)
+   : ossimImageSourceFilter(inputSource),
+     theCurrentResLevel(0),
+     theHistogram(histogram),
+     theFilename("")
+{
+   setNumberOfInputs(2);
+   theInputListIsFixedFlag = true;
+}
+
+ossimImageSourceHistogramFilter::~ossimImageSourceHistogramFilter()
+{
+   if(theHistogram)
+   {
+      delete theHistogram;
+      theHistogram = NULL;
+   }   
+}
+
+
+void ossimImageSourceHistogramFilter::setHistogram(ossimMultiResLevelHistogram* histogram)
+{
+   if(theHistogram&&
+      theHistogram!=histogram)
+   {
+      delete theHistogram;
+      theHistogram = NULL;
+      
+   }
+   theHistogram = histogram;
+   
+   if(theHistogram)
+   {
+      theHistogram->setBinCount(0, 0);
+   }
+}
+
+bool ossimImageSourceHistogramFilter::setHistogram(const ossimFilename& filename)
+{
+   ossimMultiResLevelHistogram* histogram = new ossimMultiResLevelHistogram;
+
+   bool result = histogram->importHistogram(filename);
+
+   if(result)
+   {
+      theFilename = filename;
+      setHistogram(histogram);
+   }
+   else
+   {
+      delete histogram;
+      histogram = 0;
+   }
+   
+   return result;
+}
+
+ossimMultiResLevelHistogram* ossimImageSourceHistogramFilter::getHistogram()
+{
+   if(!getInput(1))
+   {
+      return theHistogram;
+   }
+   else
+   {
+      ossimHistogramSource* histoSource = PTR_CAST(ossimHistogramSource, getInput(1));
+      if(histoSource)
+      {
+         return histoSource->getHistogram();
+      }
+   }
+
+   return (ossimMultiResLevelHistogram*)NULL;
+}
+
+const ossimMultiResLevelHistogram* ossimImageSourceHistogramFilter::getHistogram()const
+{
+   if(!getInput(1))
+   {
+      return theHistogram;
+   }
+   else
+   {
+      ossimHistogramSource* histoSource = PTR_CAST(ossimHistogramSource, getInput(1));
+      if(histoSource)
+      {
+         return histoSource->getHistogram();
+      }
+   }
+
+   return (ossimMultiResLevelHistogram*)NULL;
+}
+
+bool ossimImageSourceHistogramFilter::canConnectMyInputTo(ossim_int32 inputIndex,
+                                                          const ossimConnectableObject* object)const
+{
+   if(object)
+   {
+      if(PTR_CAST(ossimImageSourceInterface, object) && ( inputIndex == 0 ))
+      {
+         return true;
+      }
+      else if(PTR_CAST(ossimHistogramSource, object) && ( inputIndex == 1 ))
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+void ossimImageSourceHistogramFilter::connectInputEvent(ossimConnectionEvent& event)
+{
+   theInputConnection = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(PTR_CAST(ossimHistogramSource, event.getNewObject()))
+   {
+      // only initialize if it's a new object
+      initialize();
+   }
+}
+
+bool ossimImageSourceHistogramFilter::saveState(ossimKeywordlist& kwl,
+                                                const char* prefix)const
+{
+   bool result = ossimImageSourceFilter::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           HISTOGRAM_FILENAME_KW,
+           theFilename,
+           true);
+   
+   return result;
+}
+
+bool ossimImageSourceHistogramFilter::loadState(const ossimKeywordlist& kwl,
+                                                const char* prefix)
+{
+   const char* proprietaryName = kwl.find(prefix, PROPRIETARY_FILENAME_KW);
+   const char* ossimName       = kwl.find(prefix, HISTOGRAM_FILENAME_KW);
+   bool result = true;
+   ossimFilename file;
+
+   if(proprietaryName)
+   {
+       theFilename = ossimFilename(proprietaryName);
+   }
+   else if(ossimName)
+   {
+      if(!theHistogram)
+      {
+         theHistogram = new ossimMultiResLevelHistogram;
+      }
+      theFilename = ossimFilename(ossimName);
+      
+   }
+
+   if(theFilename.exists()&&(theFilename!=""))
+   {
+      if(!theHistogram)
+      {
+         theHistogram = new ossimMultiResLevelHistogram;
+      }
+      result = theHistogram->importHistogram(theFilename);
+   }
+   if(theHistogram)
+   {
+      theHistogram->setBinCount(0, 0);
+   }
+   
+   result =  ossimImageSourceFilter::loadState(kwl, prefix);
+
+   setNumberOfInputs(2);
+   theInputListIsFixedFlag = true;
+   
+   return result;
+}
+
+std::ostream& ossimImageSourceHistogramFilter::print(std::ostream& out) const
+{
+
+   out << "ossimImageSourceHistogramFilter::print:\n"
+       << "theFilename:  " << endl;
+
+   return ossimImageSourceFilter::print(out);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceHistogramFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceHistogramFilter.h
new file mode 100644
index 0000000000..27f24fee29
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageSourceHistogramFilter.h
@@ -0,0 +1,65 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageSourceHistogramFilter.h,v 1.7 2004/05/19 17:53:29 dburken Exp $
+#ifndef ossimImageSourceHistogramFilter_HEADER
+#define ossimImageSourceHistogramFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <base/data_types/ossimFilename.h>
+class ossimMultiResLevelHistogram;
+
+class OSSIMDLLEXPORT ossimImageSourceHistogramFilter : public ossimImageSourceFilter
+{
+public:
+   ossimImageSourceHistogramFilter();
+   ossimImageSourceHistogramFilter(ossimImageSource* inputSource,
+                        ossimMultiResLevelHistogram* histogram);
+   virtual ~ossimImageSourceHistogramFilter();
+   virtual void setHistogram(ossimMultiResLevelHistogram* histogram);
+   virtual bool setHistogram(const ossimFilename& filename);
+   virtual const ossimFilename& getHistogramFilename()const;
+   virtual ossimMultiResLevelHistogram* getHistogram();
+   virtual const ossimMultiResLevelHistogram* getHistogram()const;
+   
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const;
+
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = NULL);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = NULL)const;
+
+   virtual std::ostream& print(std::ostream& out) const;
+
+protected:
+   long                         theCurrentResLevel;
+
+private:
+   ossimMultiResLevelHistogram* theHistogram;
+   ossimFilename                theFilename;
+   
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimImageSourceHistogramFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageToPlaneNormalFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageToPlaneNormalFilter.cpp
new file mode 100644
index 0000000000..e430e8d382
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageToPlaneNormalFilter.cpp
@@ -0,0 +1,432 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageToPlaneNormalFilter.cpp,v 1.9 2005/05/09 12:39:40 dburken Exp $
+#include <imaging/tile_sources/ossimImageToPlaneNormalFilter.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/ossimProjection.h>
+#include <base/common/ossimKeywordNames.h>
+
+static const char* SMOOTHNESS_FACTOR_KW="smoothness_factor";
+
+RTTI_DEF1(ossimImageToPlaneNormalFilter, "ossimImageToPlaneNormalFilter", ossimImageSourceFilter);
+
+ossimImageToPlaneNormalFilter::ossimImageToPlaneNormalFilter()
+   :ossimImageSourceFilter(),
+    theTile(NULL),
+    theBlankTile(NULL),
+    theTrackScaleFlag(true),
+    theXScale(1.0),
+    theYScale(1.0),
+    theSmoothnessFactor(1.0)
+{
+}
+
+ossimImageToPlaneNormalFilter::ossimImageToPlaneNormalFilter(ossimImageSource* inputSource)
+   :ossimImageSourceFilter(inputSource),
+    theTile(NULL),
+    theBlankTile(NULL),
+    theTrackScaleFlag(true),
+    theXScale(1.0),
+    theYScale(1.0),
+    theSmoothnessFactor(1.0)
+{
+}
+
+ossimRefPtr<ossimImageData> ossimImageToPlaneNormalFilter::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+
+   if(!isSourceEnabled()||!theInputConnection)
+   {
+      return ossimImageSourceFilter::getTile(tileRect, resLevel);
+   }
+
+   if(!theTile.valid())
+   {
+      initialize();
+   }
+
+   if(!theTile.valid())
+   {
+      return ossimImageSourceFilter::getTile(tileRect, resLevel);
+   }
+
+   theTile->setImageRectangle(tileRect);
+   theBlankTile->setImageRectangle(tileRect);
+
+   ossimIrect requestRect(tileRect.ul().x - 1,
+                          tileRect.ul().y - 1,
+                          tileRect.lr().x + 1,
+                          tileRect.lr().y + 1);
+   ossimRefPtr<ossimImageData> input =
+      theInputConnection->getTile(requestRect, resLevel);
+
+   if(!input||(input->getDataObjectStatus()==OSSIM_EMPTY)||!input->getBuf())
+   {
+      return theBlankTile;
+   }
+
+   double oldScaleX = theXScale;
+   double oldScaleY = theYScale;
+
+   if(resLevel > 0)
+   {
+      ossimDpt scaleFactor;
+      theInputConnection->getDecimationFactor(resLevel, scaleFactor);
+
+      if(!scaleFactor.hasNans())
+      {
+         theXScale /= scaleFactor.x;
+         theYScale /= scaleFactor.y;
+      }
+   }
+
+   computeNormals(input,
+                  theTile);
+
+   theXScale = oldScaleX;
+   theYScale = oldScaleY;
+
+   theTile->validate();
+
+   return theTile;
+}
+
+
+void ossimImageToPlaneNormalFilter::initialize()
+{
+   if(theInputConnection)
+   {
+      theTile      = ossimImageDataFactory::instance()->create(this, this);
+      theBlankTile = (ossimImageData*)(theTile->dup());
+      theTile->initialize();
+
+
+      if(theTrackScaleFlag)
+      {
+         ossimKeywordlist kwl;
+         theInputConnection->getImageGeometry(kwl);
+
+         ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->
+            createProjection(kwl);
+
+         if(proj)
+         {
+            ossimDpt pt = proj->getMetersPerPixel();
+
+            if(!pt.hasNans())
+            {
+               theXScale = pt.x;
+               theYScale = pt.y;
+            }
+         }
+      }
+   }
+}
+
+void ossimImageToPlaneNormalFilter::computeNormals(
+   ossimRefPtr<ossimImageData>& inputTile,
+   ossimRefPtr<ossimImageData>& outputTile)
+{
+   switch(inputTile->getScalarType())
+   {
+      case OSSIM_SSHORT16:
+      {
+         computeNormalsTemplate((ossim_sint16)0,
+                                inputTile,
+                                outputTile);
+         break;
+      }
+      case OSSIM_UCHAR:
+      {
+         computeNormalsTemplate((ossim_uint8)0,
+                                inputTile,
+                                outputTile);
+         break;
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_USHORT16:
+      {
+         computeNormalsTemplate((ossim_uint16)0,
+                                inputTile,
+                                outputTile);
+         break;
+      }
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_DOUBLE:
+      {
+         computeNormalsTemplate((ossim_float64)0,
+                                inputTile,
+                                outputTile);
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT:
+      {
+         computeNormalsTemplate((ossim_float32)0,
+                                inputTile,
+                                outputTile);
+         break;
+      }
+      default:
+         break;
+   }
+}
+
+template <class T> void ossimImageToPlaneNormalFilter::computeNormalsTemplate(
+   T inputScalarTypeDummy,
+   ossimRefPtr<ossimImageData>& inputTile,
+   ossimRefPtr<ossimImageData>& outputTile)
+{
+   T np = (T)inputTile->getNullPix(0);
+   double outNp1 = outputTile->getNullPix(0);
+   double outNp2 = outputTile->getNullPix(1);
+   double outNp3 = outputTile->getNullPix(2);
+
+   double* outX = (double*)outputTile->getBuf(0);
+   double* outY = (double*)outputTile->getBuf(1);
+   double* outZ = (double*)outputTile->getBuf(2);
+   ossim_int32 y = 0;
+   ossim_int32 x = 0;
+   ossim_int32 iw = inputTile->getWidth();
+   ossim_int32 ow = outputTile->getWidth();
+   ossim_int32 oh = outputTile->getHeight();
+   T* row1 = (T*)inputTile->getBuf();
+   T* row2 = row1+iw;
+   T* row3 = row2+iw;
+   ossimColumnVector3d pX;
+   ossimColumnVector3d pY;
+   ossimColumnVector3d leftX;
+   ossimColumnVector3d rightX;
+   ossimColumnVector3d topY;
+   ossimColumnVector3d bottomY;
+
+   ossimColumnVector3d normal;
+
+
+   for(y = 0; y < oh; ++y)
+   {
+      for(x = 0; x < ow; ++x)
+      {
+         if((row1[0] == np)||
+            (row1[1] == np)||
+            (row1[2] == np)||
+            (row2[0] == np)||
+            (row2[1] == np)||
+            (row2[2] == np)||
+            (row3[0] == np)||
+            (row3[1] == np)||
+            (row3[2] == np))
+         {
+            *outX = outNp1;
+            *outY = outNp2;
+            *outZ = outNp3;
+         }
+         else
+         {
+//             dhX = ((double)row1[2] - (double)row1[0])+
+//                   ((double)row2[2] - (double)row2[0])+
+//                   ((double)row3[2]  - (double)row3[0]);
+
+//             dhY = ((double)row1[0] - (double)row3[0])+
+//                   ((double)row1[1] - (double)row3[1])+
+//                   ((double)row1[2] - (double)row3[2]);
+
+//             dhX = (-(double)row1[2] + (double)row1[0])+
+//                   (-(double)row2[2] + (double)row2[0])+
+//                   (-(double)row3[2] + (double)row3[0]);
+
+//             dhY = (-(double)row1[0] + (double)row3[0])+
+//                   (-(double)row1[1] + (double)row3[1])+
+//                   (-(double)row1[2] + (double)row3[2]);
+
+            leftX[0] = -theXScale*theSmoothnessFactor;
+            leftX[1] = 0.0;
+            leftX[2] = ((double)row1[0] + (double)row2[0]+ (double)row3[0])/3.0;
+
+            rightX[0] = theXScale*theSmoothnessFactor;
+            rightX[1] = 0.0;
+            rightX[2] = ((double)row1[2] + (double)row2[2]+ (double)row3[2])/3.0;
+
+            topY[0]   = 0.0;
+            topY[1]   = theYScale*theSmoothnessFactor;
+            topY[2]   = ((double)row1[0] + (double)row1[1] + (double)row1[2])/3.0;
+
+            bottomY[0]   = 0.0;
+            bottomY[1]   = -theYScale*theSmoothnessFactor;
+            bottomY[2]   = ((double)row3[0] + (double)row3[1] + (double)row3[2])/3.0;
+
+            pX = (rightX - leftX).unit();
+            pY = (topY - bottomY).unit();
+//             pX[0] = theXScale*theSmoothnessFactor;
+//             pX[1] = 0.0;
+//             pX[2] = dhX;
+
+//             pY[0] = 0.0;
+//             pY[1] = theYScale*theSmoothnessFactor;
+//             pY[2] = dhY;
+
+//             pX = pX.unit();
+//             pY = pY.unit();
+            normal = pX.cross(pY).unit();
+
+            normal = normal.unit();
+            *outX = normal[0];
+            *outY = normal[1];
+            *outZ = normal[2];
+         }
+
+         ++outX;
+         ++outZ;
+         ++outY;
+
+         ++row1;
+         ++row2;
+         ++row3;
+      }
+      row1+=2;
+      row2+=2;
+      row3+=2;
+   }
+}
+
+bool ossimImageToPlaneNormalFilter::loadState(const ossimKeywordlist& kwl,
+                                              const char* prefix)
+{
+   ossimString scaleX     = kwl.find(prefix, ossimKeywordNames::SCALE_PER_PIXEL_X_KW);
+   ossimString scaleY     = kwl.find(prefix, ossimKeywordNames::SCALE_PER_PIXEL_Y_KW);
+   ossimString trackFlag  = kwl.find(prefix, "track_scale_flag");
+   ossimString smoothness = kwl.find(prefix, SMOOTHNESS_FACTOR_KW);
+
+   if(scaleX != "")
+   {
+      theXScale = scaleX.toDouble();
+   }
+   if(scaleY != "")
+   {
+      theYScale = scaleY.toDouble();
+   }
+   if(trackFlag != "")
+   {
+      theTrackScaleFlag = trackFlag.toBool();
+   }
+   if(smoothness!="")
+   {
+      theSmoothnessFactor = smoothness.toDouble();
+   }
+
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimImageToPlaneNormalFilter::saveState(ossimKeywordlist& kwl,
+                                              const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_PER_PIXEL_X_KW,
+           theXScale,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_PER_PIXEL_Y_KW,
+           theXScale,
+           true);
+
+   kwl.add(prefix,
+           "track_scale_flag",
+           (ossim_uint32)theTrackScaleFlag,
+           true);
+
+   kwl.add(prefix,
+           SMOOTHNESS_FACTOR_KW,
+           theSmoothnessFactor,
+           true);
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+double ossimImageToPlaneNormalFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getMinPixelValue(band);
+   }
+   return -1;
+}
+
+double ossimImageToPlaneNormalFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getMaxPixelValue(band);
+   }
+   return 1.0;
+}
+
+ossimScalarType ossimImageToPlaneNormalFilter::getOutputScalarType() const
+{
+   if(isSourceEnabled())
+   {
+      return OSSIM_DOUBLE;
+   }
+   
+   return ossimImageSourceFilter::getOutputScalarType();
+}
+
+ossim_uint32 ossimImageToPlaneNormalFilter::getNumberOfOutputBands() const
+{
+   if(isSourceEnabled())
+   {
+      return 3;
+   }
+   return ossimImageSourceFilter::getNumberOfOutputBands();
+}
+
+void ossimImageToPlaneNormalFilter::setXScale(const double& scale)
+{
+   theXScale = scale;
+}
+
+double ossimImageToPlaneNormalFilter::getXScale()const
+{
+   return theXScale;
+}
+
+double ossimImageToPlaneNormalFilter::getYScale()const
+{
+   return theYScale;
+}
+
+void ossimImageToPlaneNormalFilter::setYScale(const double& scale)
+{
+   theYScale = scale;
+}
+
+void ossimImageToPlaneNormalFilter::setTrackScaleFlag(bool flag)
+{
+   theTrackScaleFlag = flag;
+}
+
+bool ossimImageToPlaneNormalFilter::getTrackScaleFlag()const
+{
+   return theTrackScaleFlag;
+}
+
+void ossimImageToPlaneNormalFilter::setSmoothnessFactor(double value)
+{
+   theSmoothnessFactor = value;
+}
+
+double ossimImageToPlaneNormalFilter::getSmoothnessFactor()const
+{
+   return theSmoothnessFactor;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageToPlaneNormalFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageToPlaneNormalFilter.h
new file mode 100644
index 0000000000..d997c6536e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimImageToPlaneNormalFilter.h
@@ -0,0 +1,67 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimImageToPlaneNormalFilter.h,v 1.5 2005/02/25 21:20:54 dburken Exp $
+#ifndef ossimImageToPlaneNormalFilter_HEADER
+#define ossimImageToPlaneNormalFilter_HEADER
+#include "ossimImageSourceFilter.h"
+
+class OSSIMDLLEXPORT ossimImageToPlaneNormalFilter : public ossimImageSourceFilter
+{
+public:
+   ossimImageToPlaneNormalFilter();
+   ossimImageToPlaneNormalFilter(ossimImageSource* inputSource);
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   virtual ossimScalarType getOutputScalarType() const;
+   virtual ossim_uint32    getNumberOfOutputBands() const;
+   
+   void setXScale(const double& scale);
+   void setYScale(const double& scale);
+   
+   double getXScale()const;
+   double getYScale()const;
+
+   void setTrackScaleFlag(bool flag);
+   bool getTrackScaleFlag()const;
+   
+   void   setSmoothnessFactor(double value);
+   double getSmoothnessFactor()const;
+   
+   bool loadState(const ossimKeywordlist& kwl,
+                  const char* prefix);
+   bool saveState(ossimKeywordlist& kwl,
+                  const char* prefix)const;
+   virtual void initialize();
+   
+protected:
+   ossimRefPtr<ossimImageData> theTile;
+   ossimRefPtr<ossimImageData> theBlankTile;
+
+   bool            theTrackScaleFlag;
+   double          theXScale;
+   double          theYScale;
+   double          theSmoothnessFactor;
+   virtual void computeNormals(ossimRefPtr<ossimImageData>& inputTile,
+                               ossimRefPtr<ossimImageData>& outputTile);
+
+   template <class T>
+   void computeNormalsTemplate(T inputScalarTypeDummy,
+                               ossimRefPtr<ossimImageData>& inputTile,
+                               ossimRefPtr<ossimImageData>& outputTile);
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIndexToRgbLutFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIndexToRgbLutFilter.cpp
new file mode 100644
index 0000000000..137c425cf0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIndexToRgbLutFilter.cpp
@@ -0,0 +1,626 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimIndexToRgbLutFilter.cpp,v 1.26 2005/08/30 15:08:51 gpotts Exp $
+#include <imaging/tile_sources/ossimIndexToRgbLutFilter.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimTrace.h>
+#include <base/property/ossimFilenameProperty.h>
+#include <base/property/ossimStringProperty.h>
+
+static const ossimTrace traceDebug("ossimIndexToRgbLutFilter:debug");
+
+RTTI_DEF1(ossimIndexToRgbLutFilter, "ossimIndexToRgbLutFilter", ossimImageSourceFilter);
+
+static const char* MIN_VALUE_KW          = "min_value";
+static const char* MAX_VALUE_KW          = "max_value";
+static const char* INTERPOLATION_TYPE_KW = "interpolation_type";
+
+ossimIndexToRgbLutFilter::ossimIndexToRgbLutFilter()
+   :ossimImageSourceFilter(),
+    theMinValue(OSSIM_DBL_NAN),
+    theMaxValue(OSSIM_DBL_NAN),
+    theMinMaxDeltaLength(OSSIM_DBL_NAN),
+    theMinValueOverride(false),
+    theMaxValueOverride(false),
+    theInterpolationType(ossimIndexToRgbLutFilter_NEAREST),
+    theTile(NULL),
+    theLutFile("")
+{
+}
+
+ossimIndexToRgbLutFilter::ossimIndexToRgbLutFilter(ossimImageSource* inputSource,
+                                                 const ossimRgbLutDataObject& lut,
+                                                 double minValue,
+                                                 double maxValue,
+                                                 ossimIndexToRgbLutFilterInterpolationType interpolationType)
+   :ossimImageSourceFilter(inputSource),
+    theLut(lut),
+    theMinValue(minValue),
+    theMaxValue(maxValue),
+    theMinValueOverride(false),
+    theMaxValueOverride(false),
+    theInterpolationType(interpolationType),
+    theTile(NULL),
+    theLutFile("")
+{ 
+   if(theMinValue > theMaxValue)
+   {
+      double temp = theMinValue;
+      theMinValue = theMaxValue;
+      theMaxValue = temp;
+   }
+   theMinMaxDeltaLength = theMaxValue - theMinValue;
+   
+}
+
+ossimIndexToRgbLutFilter::~ossimIndexToRgbLutFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimIndexToRgbLutFilter::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+   ossimRefPtr<ossimImageData> tile = theInputConnection->getTile(tileRect,
+                                                                  resLevel);
+   if(!tile)
+   {
+      return 0;
+   }
+   
+   if(!theTile)
+   {
+      allocate();
+      if (!theTile)
+      {
+         return theTile;
+      }
+   }
+
+   theTile->setImageRectangle(tileRect);
+
+   theTile->setDataObjectStatus(OSSIM_FULL);
+   theTile->makeBlank();
+
+   if(tile->getBuf()&&
+      tile->getDataObjectStatus() != OSSIM_EMPTY)
+   {
+      return convertInputTile(tile);
+   }
+
+   return theTile;
+   
+//    if ( theTile->getDataObjectStatus() != OSSIM_EMPTY )
+//    {
+//       theTile->makeBlank();
+//    }
+
+}
+
+ossimRefPtr<ossimImageData> ossimIndexToRgbLutFilter::convertInputTile(const ossimRefPtr<ossimImageData>& tile)
+{
+   ossim_uint8* outBuf[3];
+   outBuf[0] = (ossim_uint8*)(theTile->getBuf(0));
+   outBuf[1] = (ossim_uint8*)(theTile->getBuf(1));
+   outBuf[2] = (ossim_uint8*)(theTile->getBuf(2));
+   long numberOfEntries = (long)theLut.getNumberOfEntries();
+
+   if(!numberOfEntries)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+   
+   long maxLength = tile->getWidth()*tile->getHeight();
+   ossimRgbVector color;
+
+   switch(tile->getScalarType())
+   {
+      case OSSIM_SSHORT16:
+      {      
+         ossim_sint16* buf = (ossim_sint16*)(tile->getBuf());
+
+         for(long index = 0; index < maxLength; ++index)
+         {
+            if(!tile->isNull(index))
+            {
+               double colorIndex;
+               normalizeValue(*buf, colorIndex);            
+               getColorNormIndex(colorIndex, color);
+               outBuf[0][index]  = color.getR();
+               outBuf[1][index]  = color.getG();
+               outBuf[2][index]  = color.getB();
+            }
+            else
+            {
+               outBuf[0][index] = 0;
+               outBuf[1][index] = 0;
+               outBuf[2][index] = 0;
+            }
+            ++buf;
+         }
+         break;
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {      
+         float* buf = (float*)(tile->getBuf());
+       
+         for(long index = 0; index < maxLength; ++index)
+	 {
+            if(!tile->isNull(index))
+            {
+	       double colorIndex;
+	       normalizeValue(*buf, colorIndex);            
+	       getColorNormIndex(colorIndex, color);
+	       outBuf[0][index]  = color.getR();
+	       outBuf[1][index]  = color.getG();
+	       outBuf[2][index]  = color.getB();
+            }
+            else
+            {
+	       outBuf[0][index] = 0;
+	       outBuf[1][index] = 0;
+	       outBuf[2][index] = 0;
+            }
+            ++buf;
+	 }
+         break;
+      }
+      case OSSIM_UCHAR:
+      {
+         ossim_uint8* buf = (ossim_uint8*)(tile->getBuf());
+
+         for(long index = 0; index < maxLength; ++index)
+         {
+            if(!tile->isNull(index))
+            {
+               double colorIndex;
+               normalizeValue(*buf, colorIndex);
+               getColorNormIndex(colorIndex, color);
+	    
+               outBuf[0][index]  = color.getR();
+               outBuf[1][index]  = color.getG();
+               outBuf[2][index]  = color.getB();
+            }
+            else
+            {
+               outBuf[0][index] = 0;
+               outBuf[1][index] = 0;
+               outBuf[2][index] = 0;
+            }
+            ++buf;
+         }
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         ossim_uint16* buf = (ossim_uint16*)(tile->getBuf());
+
+         for(long index = 0; index < maxLength; ++index)
+         {
+            if(!tile->isNull(index))
+            {
+               double colorIndex;
+               normalizeValue(*buf, colorIndex);            
+               getColorNormIndex(colorIndex, color);
+               outBuf[0][index]  = color.getR();
+               outBuf[1][index]  = color.getG();
+               outBuf[2][index]  = color.getB();
+            }
+            else
+            {
+               outBuf[0][index] = 0;
+               outBuf[1][index] = 0;
+               outBuf[2][index] = 0;
+            }
+            ++buf;
+         }
+         break;
+      }
+      default:
+         break;
+   }
+   theTile->validate();
+   return theTile;
+}
+
+void ossimIndexToRgbLutFilter::allocate()
+{
+   if(!theInputConnection) return;
+
+   theTile = ossimImageDataFactory::instance()->create(this, 3, this);
+   if(theTile.valid())
+   {
+      theTile->initialize();
+   }
+}
+
+void ossimIndexToRgbLutFilter::initialize()
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimIndexToRgbLutFilter::initialize() DEBUG: Entered .... " << std::endl;
+   }
+   ossimImageSourceFilter::initialize();
+   
+   theTile      = NULL;
+   if(!theInputConnection)
+   {
+      return;
+   }
+   if(!theMinValueOverride)
+   {
+      theMinValue = theInputConnection->getMinPixelValue(0);
+   }
+   if(!theMaxValueOverride)
+   {
+      theMaxValue = theInputConnection->getMaxPixelValue(0);
+   }
+   if(theMinValue > theMaxValue)
+   {
+      swap(theMinValue, theMaxValue);
+   }
+   theMinMaxDeltaLength = theMaxValue - theMinValue;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "theInputConnection Pointer = " << theInputConnection
+         << "\nossimIndexToRgbLutFilter::initialize() DEBUG: Leaving .... "
+         << std::endl;
+   }
+
+}
+
+void ossimIndexToRgbLutFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(property.valid())
+   {
+      ossimString value = property->valueToString();
+      value = value.trim();
+      
+      if(property->getName() == "Lut file")
+      {
+         setLut(ossimFilename(property->valueToString()));
+      }
+      else if(property->getName() == "Interpolation type")
+      {
+         value=value.downcase();
+         if(value == "linear")
+         {
+            setInterpolationType(ossimIndexToRgbLutFilter_LINEAR);
+         }
+         else
+         {
+            setInterpolationType(ossimIndexToRgbLutFilter_NEAREST);
+         }
+      }
+      else
+      {
+         ossimImageSourceFilter::setProperty(property);
+      }
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimIndexToRgbLutFilter::getProperty(const ossimString& name)const
+{
+   if(name == "Lut file")
+   {
+      ossimFilenameProperty* filenameProperty = new ossimFilenameProperty(name, theLutFile);
+      if(filenameProperty)
+      {
+         filenameProperty->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+         filenameProperty->clearChangeType();
+         filenameProperty->setCacheRefreshBit();
+         filenameProperty->setReadOnlyFlag(false);
+
+         return filenameProperty;
+      }
+   }
+   else if(name == "Interpolation type")
+   {
+      std::vector<ossimString> options;
+      options.push_back("nearest");
+      options.push_back("linear");
+      ossimString value = "nearest";
+      if(theInterpolationType == ossimIndexToRgbLutFilter_LINEAR)
+      {
+         value = "linear";
+      }
+      
+      ossimStringProperty* stringProperty = new ossimStringProperty(name,
+                                                                    value,
+                                                                    false,
+                                                                    options);
+      
+      stringProperty->clearChangeType();
+      stringProperty->setCacheRefreshBit();
+      stringProperty->setReadOnlyFlag(false);
+
+      return stringProperty;
+   }
+
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimIndexToRgbLutFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   propertyNames.push_back("Lut file");
+   propertyNames.push_back("Interpolation type");
+}
+
+void ossimIndexToRgbLutFilter::normalizeValue(double value,
+                                              double& normalizedValue)
+{
+   // map to normalized elevation within our range of values
+   normalizedValue = (value - theMinValue)/theMinMaxDeltaLength;
+   if(normalizedValue > 1) normalizedValue = 1;
+   if(normalizedValue < 0) normalizedValue = 0;   
+}
+
+void ossimIndexToRgbLutFilter::getColorNormIndex(double index,
+                                                 ossimRgbVector& result)
+{
+   long numberOfEntries = theLut.getNumberOfEntries();
+   index*=numberOfEntries;
+   if(theInterpolationType == ossimIndexToRgbLutFilter_LINEAR)
+   {
+      int lutIndex = (long)index;
+      
+      double lutT   = index - lutIndex;
+      
+      int lutIndex2 = lutIndex+1;
+      if(lutIndex2>=numberOfEntries) lutIndex2 = numberOfEntries-1;
+      
+      result = theLut[lutIndex]*(1.0-lutT) +
+               theLut[lutIndex2]*(lutT);
+      
+   }
+   else
+   {
+      int i = irint(index);
+      i = i < 0?0:i;
+      i = i >numberOfEntries?numberOfEntries:i;
+      result = theLut[i];
+   }
+}
+
+void ossimIndexToRgbLutFilter::getColor(double index,
+                                        ossimRgbVector& result)
+{
+   if(theInterpolationType == ossimIndexToRgbLutFilter_LINEAR)
+   {
+      long numberOfEntries = theLut.getNumberOfEntries();
+      int lutIndex = (int)index;
+      
+      double lutT   = index - lutIndex;
+      int lutIndex2 = lutIndex+1;
+      
+      if(lutIndex2>=numberOfEntries) lutIndex2 = numberOfEntries-1;
+      
+      result = theLut[lutIndex]*(1.0-lutT) +
+               theLut[lutIndex2]*(lutT);
+   }
+   else
+   {
+      result = theLut[irint(index)];
+   }
+}
+
+bool ossimIndexToRgbLutFilter::saveState(ossimKeywordlist& kwl,
+                                         const char* prefix)const
+{
+   kwl.add(prefix,
+           MIN_VALUE_KW,
+           theMinValue,
+           true);
+   
+   kwl.add(prefix,
+           MAX_VALUE_KW,
+           theMaxValue,
+           true);
+   
+   ossimString interpolationType = "nearest";
+   switch(theInterpolationType)
+   {
+      case ossimIndexToRgbLutFilter_LINEAR:
+      {
+         interpolationType = "linear";
+      }
+      default:
+         break;
+   }
+   kwl.add(prefix,
+           INTERPOLATION_TYPE_KW,
+           interpolationType.c_str(),
+           true);
+   
+   ossimString newPrefix = ossimString(prefix)+ "lut.";
+   if(theLutFile != "")
+   {
+      kwl.add(newPrefix.c_str(), "lut_file", theLutFile.c_str(), true);
+      ossimKeywordlist kwl2;
+      theLut.saveState(kwl2);
+   }
+   else
+   {
+      theLut.saveState(kwl, newPrefix.c_str());
+   }
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimIndexToRgbLutFilter::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   const char* minValue = kwl.find(prefix,
+                                   MIN_VALUE_KW);
+   const char* maxValue = kwl.find(prefix,
+                                   MAX_VALUE_KW);
+
+   const char* interpolationType =  kwl.find(prefix,
+                                             INTERPOLATION_TYPE_KW);
+   
+   theInterpolationType = ossimIndexToRgbLutFilter_NEAREST;
+   if(interpolationType)
+   {
+      ossimString interp = ossimString(interpolationType).trim().upcase();
+      if(interp == "LINEAR")
+      {
+         theInterpolationType = ossimIndexToRgbLutFilter_LINEAR;
+      }
+   }
+   if(minValue)
+   {
+      theMinValue = ossimString(minValue).toDouble();
+      theMinValueOverride = true;
+      
+   }
+   else
+   {
+      theMinValueOverride = false;
+   }
+   
+   if(maxValue)
+   {
+      theMaxValue = ossimString(maxValue).toDouble();
+      theMaxValueOverride = true;
+   }
+   else
+   {
+      theMaxValueOverride = false;
+   }
+   if((theMinValue != OSSIM_DBL_NAN) &&
+      (theMaxValue != OSSIM_DBL_NAN))
+   {
+      if(theMinValue > theMaxValue)
+      {
+         double temp = theMinValue;
+         theMinValue = theMaxValue;
+         theMaxValue = temp;
+      }
+      theMinMaxDeltaLength = theMaxValue - theMinValue;
+   }
+   else
+   {
+      theMinMaxDeltaLength = OSSIM_DBL_NAN;
+   }
+   ossimString newPrefix = ossimString(prefix)+ "lut.";
+
+   const char* file = kwl.find(newPrefix.c_str(), "lut_file");
+   if(file)
+   {
+      theLutFile = file;
+   }
+   else
+   {
+      theLutFile = "";
+   }
+   theLut.loadState(kwl, newPrefix.c_str());
+
+   bool result = ossimImageSourceFilter::loadState(kwl, prefix);
+
+   return result;
+}
+
+ossim_uint32 ossimIndexToRgbLutFilter::getNumberOfOutputBands() const
+{
+   if(isSourceEnabled())
+   {
+      return 3;
+   }
+   return ossimImageSourceFilter::getNumberOfOutputBands();
+}
+
+ossimScalarType ossimIndexToRgbLutFilter::getOutputScalarType() const
+{
+   if(isSourceEnabled())
+   {
+      return OSSIM_UCHAR;
+   }
+
+   return ossimImageSourceFilter::getOutputScalarType();
+}
+
+void ossimIndexToRgbLutFilter::setLut(ossimRgbLutDataObject& lut)
+{
+   theLut = lut;
+}
+
+void ossimIndexToRgbLutFilter::setLut(const ossimFilename& file)
+{
+   theLutFile = file;
+   if(file.exists())
+   {
+      ossimKeywordlist kwl(file.c_str());
+      theLut.loadState(kwl);
+   }
+}
+
+ossimFilename ossimIndexToRgbLutFilter::getLutFile()const
+{
+   return theLutFile;
+}
+
+double ossimIndexToRgbLutFilter::getMinValue()const
+{
+   return theMinValue;
+}
+
+double ossimIndexToRgbLutFilter::getMaxValue()const
+{
+   return theMaxValue;
+}
+
+void ossimIndexToRgbLutFilter::setMinValue(double value)
+{
+   theMinValue = value;
+}
+
+void ossimIndexToRgbLutFilter::setMaxValue(double value)
+{
+   theMaxValue = value;
+}
+
+double ossimIndexToRgbLutFilter::getNullPixelValue()const
+{
+   return 0.0;
+}
+
+double ossimIndexToRgbLutFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   return 1.0;
+}
+
+double ossimIndexToRgbLutFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   return 255.0;
+}
+
+ossimIndexToRgbLutFilter::ossimIndexToRgbLutFilterInterpolationType ossimIndexToRgbLutFilter::getInterpolationType()const
+{
+   return theInterpolationType;
+}
+
+void ossimIndexToRgbLutFilter::setInterpolationType(ossimIndexToRgbLutFilterInterpolationType type)
+{
+   theInterpolationType = type;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIndexToRgbLutFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIndexToRgbLutFilter.h
new file mode 100644
index 0000000000..6eddc44a5d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIndexToRgbLutFilter.h
@@ -0,0 +1,205 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimIndexToRgbLutFilter.h,v 1.17 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimIndexToRgbLutFilter_HEADER
+#define ossimIndexToRgbLutFilter_HEADER
+#include <base/data_types/color_space/ossimRgbVector.h>
+#include <base/common/ossimRgbLutDataObject.h>
+#include <base/data_types/ossimFilename.h>
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <vector>
+
+class ossimImageData;
+
+/**
+ * The output is an 8-bit pseudo color of the input
+ * data.  This class implements a generic way to color code
+ * any form of input data.  It will use theMinValue
+ * theMaxValue to color code the input data.  Note
+ * this class only operates on one input band since
+ * it assumes the input is an index.  It also uses
+ * an ossimRgbLutDataObject that is an array of color
+ * data or ossimRgbVector data.  It will convert
+ * the input into normalized form and then map
+ * it uniformly to the color in the RGB Lut (Lookup Table).
+ * <pre>
+ *
+ * Note:  You can tell this filter if it should use the
+ *        nearest entry for the output color or linearly
+ *        interpolate the entries for smooth coloring.
+ *
+ * Example keyword list:
+ *
+ * type:  ossimIndexToRgbLutFilter
+ * // if the max_value and min_value is given it will use these for normalizing the
+ * // input data to be between 0 and 1.  If not given it will query the min max
+ * // from the input
+ *
+ * max_value:  2164.000000000000000
+ * min_value:  -3.000000000000000
+ *
+ * // it owns an ossimRgbLutDataObject and has prefix value lut.
+ *
+ * // the value can be nearest or linear.  This describes how the
+ * // color value is computed.  If it falls bewteen 2 color values
+ * // for example, 1.4 it will go to entries 1 and 2 and interpolate
+ * // if linear is set else it will return the color at entry 1 if
+ * // nearest is set.
+ * 
+ * interpolation_type:  linear 
+ *
+ * // the rest of the keywords is the lookup table.
+ * // NOTE: you do not have to have the same number of entries as you do
+ * //       input range indices.  Just know that the lowest value is mapped
+ * //       to 0 and the highest value is mapped to number of entires -1.
+ *
+ * If you want to load from a file then just do:
+ *
+ * lut.lut_file: <full path to lut file>
+ *
+ * If you have the lut table in line then it must look like this:
+ *
+ * lut.entry0.b:  204
+ * lut.entry0.g:  102
+ * lut.entry0.r:  1
+ * lut.entry1.b:  255
+ * lut.entry1.g:  204
+ * lut.entry1.r:  153
+ * lut.entry2.b:  204
+ * lut.entry2.g:  204
+ * lut.entry2.r:  51
+ * lut.entry3.b:  255
+ * lut.entry3.g:  1
+ * lut.entry3.r:  1
+ * lut.entry4.b:  204
+ * lut.entry4.g:  1
+ * lut.entry4.r:  204
+ * lut.entry5.b:  204
+ * lut.entry5.g:  51
+ * lut.entry5.r:  255
+ * lut.entry6.b:  51
+ * lut.entry6.g:  1
+ * lut.entry6.r:  102
+ * lut.entry7.b:  255
+ * lut.entry7.g:  255
+ * lut.entry7.r:  255
+ * lut.number_of_entries:  8
+ * lut.type:  ossimRgbLutDataObject
+ *
+ *
+ * 
+ * </pre>
+ */
+class ossimIndexToRgbLutFilter : public ossimImageSourceFilter
+{
+public:
+   enum ossimIndexToRgbLutFilterInterpolationType
+   {
+      ossimIndexToRgbLutFilter_NEAREST = 0,
+      ossimIndexToRgbLutFilter_LINEAR  = 1
+   };
+   /**
+    * Initializes the min value to 0 and the max value to 4000.
+    */
+   ossimIndexToRgbLutFilter();
+   ossimIndexToRgbLutFilter(ossimImageSource* inputSource,
+                           const ossimRgbLutDataObject& rgbLut,
+                           double minValue,
+                           double maxValue,
+                           ossimIndexToRgbLutFilterInterpolationType interpolationType);
+   virtual ~ossimIndexToRgbLutFilter();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                               ossim_uint32 resLevel=0);
+   
+   ossim_uint32 getNumberOfOutputBands() const;
+   
+   virtual ossimScalarType getOutputScalarType() const;
+   
+   void           setLut(ossimRgbLutDataObject& lut);
+   void           setLut(const ossimFilename& file);
+   
+   ossimFilename  getLutFile()const;
+   
+   double         getMinValue()const;
+   double         getMaxValue()const;
+   
+   void           setMinValue(double value);
+   void           setMaxValue(double value);
+   
+   virtual double getNullPixelValue()const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   ossimIndexToRgbLutFilterInterpolationType getInterpolationType()const;
+   void setInterpolationType(ossimIndexToRgbLutFilterInterpolationType type);
+
+   virtual void initialize();
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   
+   /**
+    * Saves the state of this object.
+    *
+    * Keywords are:    min_value 
+    *                  max_value
+    *                  lut.<lut keywords> -> look at the
+    *                  ossimRgbLutDataObject for the keywords that
+    *                                         follow after the "." .
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+
+   /**
+    * Loads the state of this object.
+    *
+    * looks for keywords:
+    *                  min_value 
+    *                  max_value
+    *                  lut.<lut keywords> -> look at the
+    *                  ossimRgbLutDataObject for the keywords that
+    *                                         follow after the "." .
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+   
+   ossimRgbLutDataObject theLut;
+   double theMinValue;
+   double theMaxValue;
+   double theMinMaxDeltaLength;
+   bool theMinValueOverride;
+   bool theMaxValueOverride;
+      
+   ossimIndexToRgbLutFilterInterpolationType theInterpolationType;
+   ossimRefPtr<ossimImageData> theTile;
+   ossimFilename   theLutFile;
+   
+   virtual void normalizeValue(double value,
+                               double& normalizedValue);
+   virtual void getColorNormIndex(double index, ossimRgbVector& result);
+   virtual void getColor(double index, ossimRgbVector& result);
+   virtual ossimRefPtr<ossimImageData> convertInputTile(const ossimRefPtr<ossimImageData>& tile);
+   /**
+    * Precomputed from the theMaxValue - theMinValue
+    */
+   
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimIndexToRgbLutFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIntensityAdjustmentFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIntensityAdjustmentFilter.cpp
new file mode 100644
index 0000000000..9232895cb1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIntensityAdjustmentFilter.cpp
@@ -0,0 +1,287 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+// $Id: ossimIntensityAdjustmentFilter.cpp,v 1.5 2005/02/11 15:07:33 dburken Exp $
+#include "ossimIntensityAdjustmentFilter.h"
+#include "imaging/factory/ossimImageDataFactory.h"
+#include "base/data_types/color_space/ossimHsvVector.h"
+#include "base/data_types/color_space/ossimRgbVector.h"
+
+RTTI_DEF1(ossimIntensityAdjustmentFilter, "ossimIntensityAdjustmentFilter", ossimImageSourceFilter);
+
+ossimIntensityAdjustmentFilter::ossimIntensityAdjustmentFilter()
+   :ossimImageSourceFilter(),
+    theMeanIntensityTarget(OSSIM_DBL_NAN),
+    theNormTile(NULL),
+    theTile(NULL),
+    theBlankTile(NULL)
+{
+   theGridBounds.makeNan();
+}
+
+ossimIntensityAdjustmentFilter::~ossimIntensityAdjustmentFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimIntensityAdjustmentFilter::getTile(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   if (!theTile.valid())
+   {
+      allocate(); // first time through.
+   }
+   
+   if(theBlankTile.valid())
+   {
+      theBlankTile->setImageRectangle(rect);
+   }
+   if(!theInputConnection)
+   {
+      return theBlankTile;
+   }
+   ossimRefPtr<ossimImageData> data =
+      theInputConnection->getTile(rect, resLevel);
+   
+   if(!isSourceEnabled())
+   {
+      return data;
+   }
+   theTile->setImageRectangle(rect);
+   theNormTile->setImageRectangle(rect);
+   loadNormTile(data);
+
+   if(theMeanIntensityTarget == OSSIM_DBL_NAN)
+   {
+      theMeanIntensityTarget = theMeanIntensityGrid.meanValue();
+   }
+
+   loadNormTile(data);
+   
+   if((theNormTile->getDataObjectStatus()!=OSSIM_NULL)&&
+      (theNormTile->getDataObjectStatus()!=OSSIM_EMPTY))
+   {
+      float* buf[3];
+      if(data->getNumberOfBands() == 3)
+      {
+         buf[0] = (float*)theNormTile->getBuf(0);
+         buf[1] = (float*)theNormTile->getBuf(1);
+         buf[2] = (float*)theNormTile->getBuf(2);
+      }
+      else
+      {
+         buf[0] = (float*)theNormTile->getBuf(0);
+         buf[1] = (float*)theNormTile->getBuf(0);
+         buf[2] = (float*)theNormTile->getBuf(0);
+         
+      }
+      ossim_int32 y = 0;
+      ossim_int32 x = 0;
+      ossim_int32 upperY = theNormTile->getHeight();
+      ossim_int32 upperX = theNormTile->getWidth();
+      ossimIpt origin = rect.ul();
+      
+      for(y = 0; y < upperY; ++y)
+      {
+         for(x = 0; x < upperX; ++x)
+         {
+            ossimIpt pt = ossimIpt(origin.x + x,
+                                   origin.y + y) - theGridBounds.ul();
+
+            if((buf[0] != 0) &&
+               (buf[1] != 0) &&
+               (buf[2] != 0))
+            {
+               
+               ossimRgbVector rgb((ossim_uint8)(*(buf[0])*255.0),
+                                  (ossim_uint8)(*(buf[1])*255.0),
+                                  (ossim_uint8)(*(buf[2])*255.0));
+               ossimHsvVector hsv(rgb);
+               
+               hsv.setV(matchTargetMean(hsv.getV(),
+                                        theMeanIntensityGrid(pt.x, pt.y),
+                                        theMeanIntensityTarget,
+                                        theNormTile->getMinPix(0),
+                                        theNormTile->getMaxPix(0)));
+               ossimRgbVector result(hsv);
+               
+               *buf[0] = result.getR()/255.0;
+               *buf[1] = result.getG()/255.0;
+               *buf[2] = result.getB()/255.0;
+            }
+            
+            ++buf[0];
+            ++buf[1];
+            ++buf[2];
+         }
+      }
+   }
+   theTile->copyNormalizedBufferToTile((float*)theNormTile->getBuf());
+   theTile->validate();
+   
+   return theTile;
+}
+
+void ossimIntensityAdjustmentFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   theNormTile = NULL;
+   theBlankTile = NULL;
+   
+   if(theInputConnection)
+   {
+      theGridBounds = theInputConnection->getBoundingRect();
+   }
+   else
+   {
+      theGridBounds.makeNan();
+   }
+}
+
+void ossimIntensityAdjustmentFilter::allocate()
+{
+   theBlankTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile = (ossimImageData*)theBlankTile->dup();
+   theTile->initialize();
+}
+
+void ossimIntensityAdjustmentFilter::createAndPopulateGrid(const ossimIpt& spacing,
+                                                           double targetMean)
+{
+   if(theInputConnection)
+   {
+      ossim_uint32 x = 0;
+      ossim_uint32 y = 0;
+
+      theGridBounds        = theInputConnection->getBoundingRect();
+
+      ossimDrect rect(0,
+                      0,
+                      theGridBounds.width()-1,
+                      theGridBounds.height()-1);
+                      
+      theMeanIntensityGrid = ossimDblGrid(rect,
+                                          ossimDpt(spacing),
+                                          0);
+
+      for(y = 0; y <= theGridBounds.height(); y+=spacing.y)
+      {
+         for(x = 0; x <= theGridBounds.width(); x+=spacing.x)
+         {
+            ossimIpt ul(x - 16,
+                        y - 16);
+            
+            ossimIrect sampleRect(ul.x,
+                                  ul.y,
+                                  ul.x + 31,
+                                  ul.y + 31);
+            ossimRefPtr<ossimImageData> data = theInputConnection->getTile(sampleRect);
+            double mean = computeMeanIntensity(data);
+            theMeanIntensityGrid.setNearestNode(ossimDpt(x, y), mean);
+         }
+      }
+//      theMeanIntensityGrid.interpolateNullValuedNodes();
+   }
+   theMeanIntensityTarget = targetMean;
+}
+
+double ossimIntensityAdjustmentFilter::computeMeanIntensity(
+   ossimRefPtr<ossimImageData>& data)
+{
+   double result  = 0;
+   double divisor = 0;
+
+   if(data.valid() &&
+      (data->getDataObjectStatus()!=OSSIM_NULL)&&
+      (data->getDataObjectStatus()!=OSSIM_EMPTY))
+   {
+      loadNormTile(data);
+
+      int i = 0;
+      int upper = data->getWidth()*data->getHeight();
+      float* buf[3];
+      if(data->getNumberOfBands() == 3)
+      {
+         buf[0] = (float*)theNormTile->getBuf(0);
+         buf[1] = (float*)theNormTile->getBuf(1);
+         buf[2] = (float*)theNormTile->getBuf(2);
+      }
+      else
+      {
+         buf[0] = (float*)theNormTile->getBuf();
+         buf[1] = (float*)theNormTile->getBuf();
+         buf[2] = (float*)theNormTile->getBuf();
+      }
+      for(i = 0; i < upper; ++i)
+      {
+         ossimRgbVector rgb((ossim_uint8)(*(buf[0])*255.0),
+                            (ossim_uint8)(*(buf[1])*255.0),
+                            (ossim_uint8)(*(buf[2])*255.0));
+         ossimHsvVector hsv(rgb);
+         if(hsv.getV() > 0.0)
+         {
+            result += hsv.getV();
+            divisor += 1.0;
+         }
+         ++buf[0];
+         ++buf[1];
+         ++buf[2];
+      }
+   }
+
+   if(divisor > 0.0)
+   {
+      result /= divisor;
+   }
+   return result;
+}
+
+void ossimIntensityAdjustmentFilter::loadNormTile(ossimRefPtr<ossimImageData>& data)
+{
+   if(!theNormTile)
+   {
+      theNormTile = ossimImageDataFactory::instance()->create(this,
+                                                              OSSIM_NORMALIZED_FLOAT,
+                                                              data->getNumberOfBands(),
+                                                              data->getWidth(),
+                                                              data->getHeight());
+      theNormTile->initialize();
+   }
+   else
+   {
+      theNormTile->setImageRectangle(data->getImageRectangle());
+   }
+   data->copyTileToNormalizedBuffer((float*)theNormTile->getBuf());
+   theNormTile->validate();
+}
+
+double ossimIntensityAdjustmentFilter::matchTargetMean(double inputValue,
+                                                       double meanValue,
+                                                       double targetMean,
+                                                       double minValue,
+                                                       double maxValue)
+{
+    // max change
+   const double delta = targetMean - meanValue;
+   double weight=0.0;
+   
+   // weight max change dependend on proximity to end points
+   if (inputValue <= meanValue)
+   {
+      weight = fabs((inputValue - minValue) / (meanValue - minValue));
+   }
+   else
+   {
+      weight = fabs((maxValue - inputValue) / (maxValue - meanValue));
+   }
+
+   return  (inputValue + (delta * weight));
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIntensityAdjustmentFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIntensityAdjustmentFilter.h
new file mode 100644
index 0000000000..3401870c00
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimIntensityAdjustmentFilter.h
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+// $Id: ossimIntensityAdjustmentFilter.h,v 1.3 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimIntensityAdjustmentFilter_HEADER
+#define ossimIntensityAdjustmentFilter_HEADER
+#include "ossimImageSourceFilter.h"
+#include "base/data_types/ossimDblGrid.h"
+
+class ossimIntensityAdjustmentFilter : public ossimImageSourceFilter
+{
+public:
+   ossimIntensityAdjustmentFilter();
+   virtual ~ossimIntensityAdjustmentFilter();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+
+   const ossimIrect& getGridBounds()const
+      {
+         return theGridBounds;
+      }
+   virtual void setIntensityGrid(const ossimDblGrid& grid)
+      {
+         theMeanIntensityGrid = grid;
+      }
+   void setMeanIntensityTarget(double targetMean)
+      {
+         theMeanIntensityTarget = targetMean;
+      }
+   double getMeanIntensityTarget()const
+      {
+         return theMeanIntensityTarget;
+      }
+   ossimDblGrid& getMeanIntensityGrid()
+      {
+         return theMeanIntensityGrid;
+      }
+   const ossimDblGrid& getMeanIntensityGrid()const
+      {
+         return theMeanIntensityGrid;
+      }
+   void createAndPopulateGrid(const ossimIpt& spacing, double targetMean = .5);
+   
+   virtual void initialize();
+protected:
+
+   virtual void allocate();
+   
+   ossimDblGrid                theMeanIntensityGrid;
+   double                      theMeanIntensityTarget;
+   ossimRefPtr<ossimImageData> theNormTile;
+   ossimRefPtr<ossimImageData> theTile;
+   ossimRefPtr<ossimImageData> theBlankTile;
+
+   ossimIrect   theGridBounds;
+
+   double computeMeanIntensity(ossimRefPtr<ossimImageData>& data);
+   void loadNormTile(ossimRefPtr<ossimImageData>& data);
+   double matchTargetMean(double inputValue,
+                          double meanValue,
+                          double targetMean,
+                          double minValue,
+                          double maxValue);
+   
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimJpegYCbCrToRgbSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimJpegYCbCrToRgbSource.cpp
new file mode 100644
index 0000000000..4d3390ade0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimJpegYCbCrToRgbSource.cpp
@@ -0,0 +1,114 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimJpegYCbCrToRgbSource.cpp,v 1.6 2005/02/11 15:07:33 dburken Exp $
+#include <imaging/tile_sources/ossimJpegYCbCrToRgbSource.h>
+#include <imaging/ossimImageData.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/color_space/ossimJpegYCbCrVector.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+
+RTTI_DEF1(ossimJpegYCbCrToRgbSource,
+          "ossimJpegYCbCrToRgbSource" ,
+          ossimImageSourceFilter)
+
+ossimJpegYCbCrToRgbSource::ossimJpegYCbCrToRgbSource()
+   :ossimImageSourceFilter(),
+    theBlankTile()
+{
+}
+
+ossimJpegYCbCrToRgbSource::ossimJpegYCbCrToRgbSource(ossimImageSource* inputSource)
+   : ossimImageSourceFilter(inputSource),
+     theBlankTile()
+{
+}
+
+ossimJpegYCbCrToRgbSource::~ossimJpegYCbCrToRgbSource()
+{
+}
+
+void ossimJpegYCbCrToRgbSource::initialize()
+{
+   ossimImageSourceFilter::initialize();
+}
+
+void ossimJpegYCbCrToRgbSource::allocate()
+{
+   theBlankTile = new ossimImageData(this,
+                                     OSSIM_UCHAR,
+                                     3);
+}
+
+ossimRefPtr<ossimImageData> ossimJpegYCbCrToRgbSource::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if (!theBlankTile.valid())
+   {
+      allocate(); // first time through.
+   }
+   
+   if(theBlankTile.valid())
+   {
+      theBlankTile->setOrigin(tileRect.ul());
+      theBlankTile->setWidthHeight(tileRect.width(), tileRect.height());
+   }
+   
+   if(theInputConnection)
+   {
+      ossimRefPtr<ossimImageData> imageData =
+         theInputConnection->getTile(tileRect, resLevel);
+
+      if(!imageData.valid())
+      {
+         return theBlankTile;
+      }
+      if((isSourceEnabled())&&
+         (imageData->getNumberOfBands()==3)&&
+         (imageData->getScalarType()==OSSIM_UCHAR)&&
+         (imageData->getDataObjectStatus()!=OSSIM_NULL)&&
+         (imageData->getDataObjectStatus()!=OSSIM_EMPTY))
+      {
+         ossim_uint8* bands[3];
+         
+         bands[0] = static_cast<ossim_uint8*>(imageData->getBuf(0));
+         bands[1] = static_cast<ossim_uint8*>(imageData->getBuf(1));
+         bands[2] = static_cast<ossim_uint8*>(imageData->getBuf(2));
+         
+         long height = imageData->getHeight();
+         long width  = imageData->getWidth();
+         long offset = 0;
+         for(long row = 0; row < height; ++row)
+         {
+            for(long col = 0; col < width; ++col)
+            {
+               
+               ossimJpegYCbCrVector ycbcr(bands[0][offset],
+                                          bands[1][offset],
+                                          bands[2][offset]);
+               ossimRgbVector rgb(ycbcr);
+               
+               
+               bands[0][offset] = rgb.getR();
+               bands[1][offset] = rgb.getG();
+               bands[2][offset] = rgb.getB();
+               
+               ++offset;
+            }
+         }
+         imageData->validate();
+      }
+      return imageData;
+   }
+   
+   return theBlankTile;
+}  
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimJpegYCbCrToRgbSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimJpegYCbCrToRgbSource.h
new file mode 100644
index 0000000000..4fe2c8ddad
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimJpegYCbCrToRgbSource.h
@@ -0,0 +1,37 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimJpegYCbCrToRgbSource.h,v 1.5 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimJpegYCbCrToRgbSource_HEADER
+#define ossimJpegYCbCrToRgbSource_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimJpegYCbCrToRgbSource : public ossimImageSourceFilter
+{
+public:
+   ossimJpegYCbCrToRgbSource();
+   ossimJpegYCbCrToRgbSource(ossimImageSource* inputSource);
+   virtual ~ossimJpegYCbCrToRgbSource();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                               ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+       
+protected:
+
+   virtual void allocate();
+   
+   ossimRefPtr<ossimImageData> theBlankTile;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLandsatTopoCorrectionFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLandsatTopoCorrectionFilter.cpp
new file mode 100644
index 0000000000..9729ed9457
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLandsatTopoCorrectionFilter.cpp
@@ -0,0 +1,361 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimLandsatTopoCorrectionFilter.cpp,v 1.6 2005/05/09 12:39:40 dburken Exp $
+#include <imaging/tile_sources/ossimLandsatTopoCorrectionFilter.h>
+#include <imaging/tile_sources/ossimImageToPlaneNormalFilter.h>
+#include <support_data/ff_l7/ossimFfL7.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <base/data_types/ossimDirectory.h>
+#include <base/misc/ossim2dLinearRegression.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimKeywordNames.h>
+
+#include <iostream>
+
+RTTI_DEF1(ossimLandsatTopoCorrectionFilter, "ossimLandsatTopoCorrectionFilter",ossimTopographicCorrectionFilter);
+ossimLandsatTopoCorrectionFilter::ossimLandsatTopoCorrectionFilter()
+   :ossimTopographicCorrectionFilter(),
+    theLandsatHeader("")
+{
+}
+
+ossimLandsatTopoCorrectionFilter::~ossimLandsatTopoCorrectionFilter()
+{
+}
+
+ossimLandsatTopoCorrectionFilter::ossimLandsatTopoCorrectionFilter(ossimImageSource* colorSource,
+                                                                   ossimImageSource* elevSource,
+                                                                   const ossimFilename& landsatFileName)
+   :ossimTopographicCorrectionFilter(colorSource,
+                                     elevSource),
+    theLandsatHeader(landsatFileName)
+{
+}
+
+void ossimLandsatTopoCorrectionFilter::initialize()
+{
+   
+   ossimTopographicCorrectionFilter::initialize();
+   if(theLandsatHeader == "")
+   {
+      setLandsatHeader(findLandsatHeader());
+   }
+   else
+   {
+      setLandsatHeader(theLandsatHeader);
+   }
+}
+
+void ossimLandsatTopoCorrectionFilter::setLandsatHeader(const ossimFilename& header)
+{
+   if(header != "")
+   {
+      theLandsatHeader = header;
+      ossimFfL7 headerL7(header.c_str());
+      theGain = headerL7.theGain;
+      theBias = headerL7.theBias;
+      theLightSourceElevationAngle = headerL7.theSunElevation;
+      theLightSourceAzimuthAngle   = headerL7.theSunAzimuth;
+      computeLightDirection();
+      theJulianDay = headerL7.getJulianDay();
+   }
+}
+
+ossimFilename ossimLandsatTopoCorrectionFilter::findLandsatHeader()
+{
+   ossimFilename result;
+
+   if(!getInput(0))
+   {
+      return result;
+   }
+   vector<ossimConnectableObject*> handlerList;
+
+   getInput(0)->findAllInputsOfType(handlerList,
+                                    STATIC_TYPE_INFO(ossimImageHandler),
+                                    true,
+                                    true);
+   
+   ossimImageHandler* handler = NULL;
+
+   if(handlerList.size())
+   {
+      handler = (ossimImageHandler*)handlerList[0];
+   }
+
+   if(handler)
+   {
+      ossimFilename imageFile = handler->getFilename();
+      imageFile.setExtension("fst");
+      if(imageFile.exists())
+      {
+         result = imageFile;
+      }
+      else
+      {
+         imageFile.setExtension("FST");
+         if(imageFile.exists())
+         {
+            result = imageFile;
+         }
+         else
+         {
+            ossimDirectory dir;
+
+            if(dir.open(imageFile.path()))
+            {
+               vector<ossimFilename> fileList;
+
+               dir.findAllFilesThatMatch(fileList,
+                                         ".*.fst");
+               if(fileList.size() <1)
+               {
+                  dir.findAllFilesThatMatch(fileList,
+                                            ".*.FST");
+               }
+               for(int i = 0; i < (int)fileList.size(); ++i)
+               {
+                  if(fileList[i].contains("_hpn")||
+                     fileList[i].contains("_hrf")||
+                     fileList[i].contains("_htm"))
+                  {
+                     result = fileList[i];
+                     break;
+                  }
+               }
+            }
+         }
+      }
+   }
+   return result;
+}
+
+// void ossimLandsatTopoCorrectionFilter::addRegressionPoints(std::vector<ossim2dLinearRegression>& regressionPoints,
+//                                                            ossimImageData* colorData,
+//                                                            ossimImageData* normalData)
+// {
+//    ossim_uint32 b = 0;
+   
+//    for(b = 0; b < colorData->getNumberOfBands(); ++b)
+//    {
+//       ossim_float64* normalBands[3];
+//       normalBands[0] = normalData->getBuf(0);
+//       normalBands[1] = normalData->getBuf(1);
+//       normalBands[2] = normalData->getBuf(2);
+//       ossim_float64* colorData = 
+// }
+
+#if 0
+void ossimLandsatTopoCorrectionFilter::computeC()
+{
+   theCComputedFlag = false;
+   ossim_uint32 totalNumberOfPixelsUsed = 0;
+   if(getInput(0)&&getInput(1))
+   {
+      std::vector<ossim2dLinearRegression> linearRegression(6);
+      
+      ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+      ossimImageSourceInterface* normalSource  = PTR_CAST(ossimImageSourceInterface, getInput(1));
+      ossimFfL7 headerL7(theLandsatHeader.c_str());
+
+      if(theLandsatHeader == "")
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "No landsat header found " << std::endl;
+         return;
+      }
+      if(colorSource->getNumberOfOutputBands() < 6)
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "The color source needs all the vir bands from the landsat" << std::endl
+                                            << "Not enough bands to process the request" << std::endl;
+         return;
+      }
+      
+      ossimIrect normalRect = normalSource->getBoundingRect();
+      ossimIrect colorRect  = colorSource->getBoundingRect();
+      ossimIrect clipRect   = normalRect.clipToRect(colorRect);
+      ossimIpt ul = clipRect.ul();
+      ossimIpt lr = clipRect.lr();
+      long julianDay = headerL7.getJulianDay();
+      double d2 =pow( (double)(1 - 0.01674 * cosd(0.9856*(julianDay-4)) ), 2.0);
+      ossim_uint32 numberOfPixelsUsedForTile = 0;
+      for(int y = ul.y; ((y < lr.y)&&(totalNumberOfPixelsUsed<1000));++y)
+      {
+         for(int x = ul.x; ((x < lr.x)&&(totalNumberOfPixelsUsed<1000)); ++x)
+         {
+            ossimIrect reqRect(x,
+                               y,
+                               x + 127,
+                               y + 127);
+            ossimIrect reqClip = reqRect.clipToRect(clipRect);
+            ossimImageData* colorData  = colorSource->getTile(reqClip, 0);
+            ossimImageData* normalData = normalSource->getTile(reqClip, 0);
+            ossim_uint8* colorBands[6];
+            double* normalBands[3];
+            double normalBandsNp[3];
+            ossim_uint8 colorBandsNp[6];
+            colorBands[0] = (ossim_uint8*)colorData->getBuf(0);
+            colorBands[1] = (ossim_uint8*)colorData->getBuf(1);
+            colorBands[2] = (ossim_uint8*)colorData->getBuf(2);
+            colorBands[3] = (ossim_uint8*)colorData->getBuf(3);
+            colorBands[4] = (ossim_uint8*)colorData->getBuf(4);
+            colorBands[5] = (ossim_uint8*)colorData->getBuf(5);
+            colorBandsNp[0] = (ossim_uint8)colorData->getNullPix(0);
+            colorBandsNp[1] = (ossim_uint8)colorData->getNullPix(1);
+            colorBandsNp[2] = (ossim_uint8)colorData->getNullPix(2);
+            colorBandsNp[3] = (ossim_uint8)colorData->getNullPix(3);
+            colorBandsNp[4] = (ossim_uint8)colorData->getNullPix(4);
+            colorBandsNp[5] = (ossim_uint8)colorData->getNullPix(5);
+            normalBands[0] = (double*)normalData->getBuf(0);
+            normalBands[1] = (double*)normalData->getBuf(1);
+            normalBands[2] = (double*)normalData->getBuf(2);
+            normalBandsNp[0] = normalData->getNullPix(0);
+            normalBandsNp[1] = normalData->getNullPix(1);
+            normalBandsNp[2] = normalData->getNullPix(2);
+            ossim_uint32 offset = 0;
+            ossim_uint32 numberOfPixels = reqClip.width()*reqClip.height();
+            numberOfPixelsUsedForTile = 0;
+            for(offset = 0; ((offset < numberOfPixels)&&(numberOfPixelsUsedForTile < 10)); ++offset)
+            {
+               if((*colorBands[0] != colorBandsNp[0])&&
+                  (*colorBands[1] != colorBandsNp[1])&&
+                  (*colorBands[2] != colorBandsNp[2])&&
+                  (*colorBands[3] != colorBandsNp[3])&&
+                  (*colorBands[4] != colorBandsNp[4])&&
+                  (*colorBands[5] != colorBandsNp[5])&&
+                  (*normalBands[0] != normalBandsNp[0])&&
+                  (*normalBands[1] != normalBandsNp[1])&&
+                  (*normalBands[2] != normalBandsNp[2]))
+               {
+                  double ndviTest = (((double)*colorBands[3] - (double)*colorBands[2])/
+                                     ((double)*colorBands[3] + (double)*colorBands[2]));
+                  if(ndviTest > 0.0)
+                  {
+                     double radiance5 = theBias[5]+(*colorBands[5]*theGain[5]);
+//                     double p = (M_PI*radiance5*d2)/(esun[5]*cosd(90-theLightSourceAzimuthAngle));
+
+//                    if(p < .05)
+                     {
+                        double cosineI = ((*normalBands[0])*theLightDirection[0] +
+                                          (*normalBands[1])*theLightDirection[1] +
+                                          (*normalBands[2])*theLightDirection[2]);
+
+                        double radiance0 = theBias[0]+(*colorBands[0]*theGain[0]);
+                        double radiance1 = theBias[1]+(*colorBands[1]*theGain[1]);
+                        double radiance2 = theBias[2]+(*colorBands[2]*theGain[2]);
+                        double radiance3 = theBias[3]+(*colorBands[3]*theGain[3]);
+                        double radiance4 = theBias[4]+(*colorBands[4]*theGain[4]);
+                        cosineI = fabs(cosineI);
+                        if(cosineI > 1.0) cosineI = 1.0;
+                        if(cosineI < 0.0) cosineI = 0.0;
+                       cosineI = acos(cosineI);
+// //                         linearRegression[0].addPoint(ossimDpt( cosineI,(double)(*colorBands[0])));
+// //                         linearRegression[1].addPoint(ossimDpt( cosineI,(double)(*colorBands[1])));
+// //                         linearRegression[2].addPoint(ossimDpt( cosineI,(double)(*colorBands[2])));
+// //                         linearRegression[3].addPoint(ossimDpt( cosineI,(double)(*colorBands[3])));
+// //                         linearRegression[4].addPoint(ossimDpt( cosineI,(double)(*colorBands[4])));
+// //                         linearRegression[5].addPoint(ossimDpt( cosineI,(double)(*colorBands[5])));
+
+                        linearRegression[0].addPoint(ossimDpt( cosineI,radiance0));
+                        linearRegression[1].addPoint(ossimDpt( cosineI,radiance1));
+                        linearRegression[2].addPoint(ossimDpt( cosineI,radiance2));
+                        linearRegression[3].addPoint(ossimDpt( cosineI,radiance3));
+                        linearRegression[4].addPoint(ossimDpt( cosineI,radiance4));
+                        linearRegression[5].addPoint(ossimDpt( cosineI,radiance5));
+                        
+                        ++numberOfPixelsUsedForTile;
+                        ++totalNumberOfPixelsUsed;
+                     }
+                  }
+               }
+               ++colorBands[0];
+               ++colorBands[1];
+               ++colorBands[2];
+               ++colorBands[3];
+               ++colorBands[4];
+               ++colorBands[5];
+               ++normalBands[0];
+               ++normalBands[1];
+               ++normalBands[2];
+            }
+         }
+      }
+      if(totalNumberOfPixelsUsed > 2)
+      {
+         linearRegression[0].solve();
+         linearRegression[1].solve();
+         linearRegression[2].solve();
+         linearRegression[3].solve();
+         linearRegression[4].solve();
+         linearRegression[5].solve();
+         
+         ossimNotify(ossimNotifyLevel_INFO) << "linear regression results = " << endl
+                                             << linearRegression[0] << endl
+                                             << linearRegression[1] << endl
+                                             << linearRegression[2] << endl
+                                             << linearRegression[3] << endl
+                                             << linearRegression[4] << endl
+                                             << linearRegression[5] << endl;
+         double b,m;
+         linearRegression[0].getEquation(m, b);
+         theC[0] = b/m;
+         linearRegression[1].getEquation(m, b);
+         theC[1] = b/m;
+         linearRegression[2].getEquation(m, b);
+         theC[2] = b/m;
+         linearRegression[3].getEquation(m, b);
+         theC[3] = b/m;
+         linearRegression[4].getEquation(m, b);
+         theC[4] = b/m;
+         linearRegression[5].getEquation(m, b);
+         theC[5] = b/m;
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_INFO) << "No points found in regression test" << endl;
+      }
+               
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "No input connected to the ossimLandsatTopoCorrectionFilter" << std::endl;
+      return;
+   }
+   
+   theCComputedFlag = true;
+}
+#endif
+
+bool ossimLandsatTopoCorrectionFilter::loadState(const ossimKeywordlist& kwl,
+                                                 const char* prefix)
+{
+   ossimTopographicCorrectionFilter::loadState(kwl, prefix);
+   const char* filename = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+
+   if(filename)
+   {
+      setLandsatHeader(filename);
+   }
+
+   return true;
+}
+
+bool ossimLandsatTopoCorrectionFilter::saveState(ossimKeywordlist& kwl,
+                                                 const char* prefix)const
+{
+   ossimTopographicCorrectionFilter::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FILENAME_KW,
+           theLandsatHeader.c_str(),
+           true);
+   
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLandsatTopoCorrectionFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLandsatTopoCorrectionFilter.h
new file mode 100644
index 0000000000..21be0287ac
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLandsatTopoCorrectionFilter.h
@@ -0,0 +1,54 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimLandsatTopoCorrectionFilter.h,v 1.5 2004/04/09 19:11:34 gpotts Exp $
+#ifndef ossimLandsatTopoCorrectionFilter_HEADER
+#define ossimLandsatTopoCorrectionFilter_HEADER
+#include <base/data_types/ossimFilename.h>
+#include <imaging/tile_sources/ossimTopographicCorrectionFilter.h>
+
+class OSSIMDLLEXPORT ossimLandsatTopoCorrectionFilter : public ossimTopographicCorrectionFilter
+{
+public:
+   ossimLandsatTopoCorrectionFilter();
+   virtual ~ossimLandsatTopoCorrectionFilter();
+   ossimLandsatTopoCorrectionFilter(ossimImageSource* colorSource,
+                                    ossimImageSource* elevSource,
+                                    const ossimFilename& landsatFileName=ossimFilename(""));
+   virtual void initialize();
+   virtual void setLandsatHeader(const ossimFilename& header);
+   virtual ossimFilename getLandsatHeader()const
+      {
+         return theLandsatHeader;
+      }
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+protected:
+   ossimFilename theLandsatHeader;
+   ossimFilename findLandsatHeader();
+//   virtual void computeC();
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLocalCorrelationFusion.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLocalCorrelationFusion.cpp
new file mode 100644
index 0000000000..54e8e0b256
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLocalCorrelationFusion.cpp
@@ -0,0 +1,432 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LICENSE:  See top level LICENSE.txt
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimLocalCorrelationFusion.cpp,v 1.13 2005/12/12 12:57:28 gpotts Exp $
+#include "ossimLocalCorrelationFusion.h"
+#include <matrix/newmat.h>
+#include <matrix/newmatio.h>
+#include <base/misc/ossim2dLinearRegression.h>
+#include <base/data_types/color_space/ossimNormRgbVector.h>
+#include <base/data_types/color_space/ossimHsiVector.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF2(ossimLocalCorrelationFusion, "ossimLocalCorrelationFusion", ossimFusionCombiner, ossimAdjustableParameterInterface);
+
+
+static const ossim_uint32 REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET = 0;
+static const ossim_uint32 REGRESSION_COEFFICIENT_CLAMP_OFFSET = 1;
+static const ossim_uint32 HIGH_PASS_GAIN_OFFSET = 2;
+static const ossim_uint32 PAN_BLURR_WIDTH_OFFSET = 3;
+static const ossim_uint32  NUMBER_OF_ADJUSTABLE_PARAMETERS = 4;
+
+ossimLocalCorrelationFusion::ossimLocalCorrelationFusion()
+   :theBlurrKernelWidth(1.5),
+    theHighPassKernelWidth(3),
+    theRegressionWidth(5)
+{
+   theLowPassFilter  = new ossimImageGaussianFilter;
+   theHighPassFilter = new ossimConvolutionSource;
+
+   setFilters();
+
+   initAdjustableParameters();
+}
+
+ossimLocalCorrelationFusion::~ossimLocalCorrelationFusion()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimLocalCorrelationFusion::getTile(const ossimIrect& rect,
+                                                                 ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   if (!theIntensityConnection)
+   {
+      return theInputConnection->getTile(rect, resLevel);
+   }
+
+   ossim_int32 regressionW2 = (ossim_int32)ceil(theRegressionWidth/2.0);
+   
+   ossimIrect expandedRegressionRect(rect.ul().x - regressionW2,
+                                     rect.ul().y - regressionW2,
+                                     rect.lr().x + regressionW2,
+                                     rect.lr().y + regressionW2);
+   
+   if(!theNormLowPassTile.valid())
+   {
+      theNormLowPassTile = new ossimImageData(this,
+                                              OSSIM_NORMALIZED_FLOAT,
+                                              1,
+                                              expandedRegressionRect.width(),
+                                              expandedRegressionRect.height());
+      theNormHighPassTile = new ossimImageData(this,
+                                              OSSIM_NORMALIZED_FLOAT,
+                                               1,
+                                               expandedRegressionRect.width(),
+                                               expandedRegressionRect.height());
+      theNormLowPassTile->initialize();
+      theNormHighPassTile->initialize();
+      theNormLowPassTile->makeBlank();
+      theNormHighPassTile->makeBlank();
+   }
+
+   theNormLowPassTile->setImageRectangle(expandedRegressionRect);
+   theNormHighPassTile->setImageRectangle(expandedRegressionRect);
+   theNormLowPassTile->makeBlank();
+   theNormHighPassTile->makeBlank();
+
+   if(!theLowPassFilter->getInput() && getInput())
+   {
+      initialize();
+   }
+
+   ossimRefPtr<ossimImageData> lowTile  = theLowPassFilter->getTile(expandedRegressionRect, resLevel);
+   ossimRefPtr<ossimImageData> highTile = theHighPassFilter->getTile(expandedRegressionRect, resLevel);
+//   ossimRefPtr<ossimImageData> highTile = getNormIntensity(expandedRegressionRect, resLevel);
+   ossimIpt ul = rect.ul();
+   ossimIpt origin;
+
+   // if we don't have valid low and high pass then return the input color tile
+   // in its original format
+   //
+   if(!lowTile.valid()||!highTile.valid())
+   {
+      return theInputConnection->getTile(rect, resLevel);
+   }
+
+   if((lowTile->getDataObjectStatus() == OSSIM_EMPTY)||
+      (!lowTile->getBuf()) ||
+      (highTile->getDataObjectStatus() == OSSIM_EMPTY)||
+      (!highTile->getBuf()))
+   {
+      return theInputConnection->getTile(rect, resLevel);
+   }
+
+   ossimRefPtr<ossimImageData> normColorData = getNormTile(expandedRegressionRect, resLevel);
+   
+   ossim_uint32 y = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 w = theTile->getWidth();
+   ossim_uint32 h = theTile->getHeight();
+
+   theTile->makeBlank();
+   theTile->setImageRectangle(rect);
+   
+   if(!normColorData.valid())
+   {
+      return 0;
+//      return theTile;
+   }
+
+   if((normColorData->getDataObjectStatus() == OSSIM_EMPTY)||
+      !normColorData->getBuf())
+   {
+      return theTile;
+   }
+   ossimRefPtr<ossimImageData> normColorOutputData = (ossimImageData*)normColorData->dup();
+   normColorOutputData->setImageRectangle(rect);
+   normColorOutputData->loadTile(normColorData.get());
+   
+   ossim_float64 slopeResult = 0.0;
+   ossim_uint32 idx = 0;
+   std::vector<ossim_float32*> bands(normColorData->getNumberOfBands());
+   
+   lowTile->copyTileToNormalizedBuffer((ossim_float32*)theNormLowPassTile->getBuf());
+   
+   highTile->copyTileToNormalizedBuffer((ossim_float32*)theNormHighPassTile->getBuf());
+   theNormLowPassTile->validate();
+   theNormHighPassTile->validate();
+   ossimRefPtr<ossimImageData> lowPan = (ossimImageData*)theNormLowPassTile->dup();
+   lowPan->setImageRectangle(rect);
+   lowPan->loadTile(theNormLowPassTile.get());
+   ossimRefPtr<ossimImageData> highPan = (ossimImageData*)theNormHighPassTile->dup();
+   highPan->setImageRectangle(rect);
+   highPan->loadTile(theNormHighPassTile.get());
+   
+   ossim_float32* panHigh = (ossim_float32*)highPan->getBuf();
+   ossim_float32* panLow  = (ossim_float32*)lowPan->getBuf();
+   for(idx = 0; idx < bands.size(); ++idx)
+   {
+      bands[idx] = (ossim_float32*)normColorOutputData->getBuf(idx);
+   }
+   double panAttenuator = computeParameterOffset(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET);
+   double delta = 0.0;
+   ossim_uint32 bandsSize = bands.size();
+   ossim_float64 slopeClamp = computeParameterOffset(REGRESSION_COEFFICIENT_CLAMP_OFFSET);
+   ossim_float64 minSlope = -slopeClamp;
+   ossim_float64 maxSlope = slopeClamp;
+   for(y = 0; y < h; ++y)
+   {
+      origin.y = ul.y + y;
+      for(x = 0; x < w; ++x)
+      {
+         origin.x = ul.x + x;
+         
+//          if(computeRegression(slopeResult,
+//                               origin,
+//                               theNormLowPassTile,
+//                               normColorData,
+//                               0))
+//          {
+//             delta = panAttenuator*slopeResult*(*panHigh - *panLow);
+            
+         for(idx = 0; idx < bandsSize; ++idx)
+         {
+            if(*bands[idx] != 0.0) // if band is not null
+            {
+               if(computeRegression(slopeResult,
+                                    origin,
+                                    theNormLowPassTile,
+                                    normColorData,
+                                    idx))
+               {
+                  if(slopeResult < minSlope) slopeResult = minSlope;
+                  if(slopeResult > maxSlope) slopeResult = maxSlope;
+                  delta = panAttenuator*slopeResult*(*panHigh - *panLow);
+                  ossim_float32 normMinPix = (ossim_float32)normColorOutputData->getMinPix(idx);
+                  *bands[idx] += delta;
+                  if(*bands[idx] > 1.0) *bands[idx] = 1.0;
+                  if(*bands[idx] < normMinPix) *bands[idx] = normMinPix;
+               }
+            }
+            ++bands[idx];
+         }
+         ++panHigh;
+         ++panLow;
+      }
+   }
+
+   theTile->copyNormalizedBufferToTile((ossim_float32*)normColorOutputData->getBuf());
+   theTile->validate();
+   
+   return theTile;
+}
+
+void ossimLocalCorrelationFusion::initialize()
+{
+   ossimFusionCombiner::initialize();
+   if(!theIntensityConnection)
+   {
+      theLowPassFilter->disconnect();
+      theHighPassFilter->disconnect();
+   }
+   else
+   {
+      theLowPassFilter->connectMyInputTo(0, PTR_CAST(ossimConnectableObject,
+                                                     theIntensityConnection->getObject()));
+      theHighPassFilter->connectMyInputTo(0, PTR_CAST(ossimConnectableObject,
+                                                      theIntensityConnection->getObject()));
+      setFilters();
+      theLowPassFilter->initialize();
+      theHighPassFilter->initialize();
+   }
+}
+
+void ossimLocalCorrelationFusion::setFilters()
+{
+   theLowPassFilter->setGaussStd(theBlurrKernelWidth);
+   
+   theHighPassMatrix = NEWMAT::Matrix(theHighPassKernelWidth, theHighPassKernelWidth);
+   theHighPassMatrix = 0;
+   theHighPassMatrix[theHighPassKernelWidth>>1][theHighPassKernelWidth>>1] = 1;
+   
+   // adjust the gain for the high pass filter
+   //
+   NEWMAT::Matrix high =  theHighPassMatrix;
+
+   ossim_float64 kernelW2 = theHighPassKernelWidth*theHighPassKernelWidth;
+   double gain = computeParameterOffset(HIGH_PASS_GAIN_OFFSET)*(kernelW2);
+   double multiplier = gain/(kernelW2);
+   high = -multiplier;
+   ossim_int32 cx = theHighPassKernelWidth>>1;
+   ossim_int32 cy = theHighPassKernelWidth>>1;
+
+   if(gain > FLT_EPSILON)
+   {
+      high[cy][cx] = multiplier* ( (kernelW2-1)+kernelW2/gain);
+   }
+   else
+   {
+      high = 0.0;
+      high[cy][cx] = 1.0;
+   }
+
+   theHighPassFilter->setConvolution(high);
+}
+
+bool ossimLocalCorrelationFusion::computeRegression(ossim_float64& slopeResult,
+                                                    const ossimIpt& origin,
+                                                    const ossimRefPtr<ossimImageData> panData,
+                                                    const ossimRefPtr<ossimImageData> colorData,
+                                                    ossim_uint32 colorBandIdx)
+{
+   bool result = false;
+   slopeResult = 0.0;
+   if(panData.valid()&&colorData.valid())
+   {
+      ossim_int32 regW2 = (ossim_int32)(theRegressionWidth>>1);
+      ossimIrect rect = panData->getImageRectangle();
+      const ossim_float32* colorDataPtr  = (const ossim_float32*)colorData->getBuf(colorBandIdx);
+      const ossim_float32* colorDataPtr2 = (const ossim_float32*)colorData->getBuf(colorBandIdx);
+      
+//      const ossim_float32* colorDataPtrBands[3]={0};
+      
+//       if(colorData->getNumberOfBands() <2)
+//       {
+//          colorDataPtrBands[0] = (ossim_float32*)colorData->getBuf(0);
+//       }
+//       else if(colorData->getNumberOfBands() <3)
+//       {
+//          colorDataPtrBands[0] = (ossim_float32*)colorData->getBuf(0);
+//          colorDataPtrBands[1] = (ossim_float32*)colorData->getBuf(1);
+//       }
+//       else
+//       {
+//          colorDataPtrBands[0] = (ossim_float32*)colorData->getBuf(0);
+//          colorDataPtrBands[1] = (ossim_float32*)colorData->getBuf(1);
+//          colorDataPtrBands[2] = (ossim_float32*)colorData->getBuf(2);
+//       }
+      const ossim_float32* panDataPtr  = (const ossim_float32*)panData->getBuf();
+      const ossim_float32* panDataPtr2 = (const ossim_float32*)panData->getBuf();
+//      if(!panDataPtr || !colorDataPtrBands[0]) return result;
+      if(!panDataPtr || !colorDataPtr) return result;
+      
+      ossim_float64 panNp   = panData->getNullPix(0);
+      ossim_float64 colorNp = colorData->getNullPix(0);
+      ossim_int32 w = (ossim_int32)rect.width();
+      ossim_int32 offset = (ossim_int32)( ((origin.y-rect.ul().y) - regW2)*w +
+                                          ((origin.x-rect.ul().x) - regW2));
+
+      ossim_uint32 y = 0;
+      ossim_uint32 x = 0;
+      ossim_uint32 idx = 0;
+      ossim2dLinearRegression regression;
+      ossim_uint32 offsetColorBand;
+
+      for(y = 0; y < theRegressionWidth; ++y)
+      {
+         offsetColorBand = (offset + y*w);
+         panDataPtr   = panDataPtr2   + offsetColorBand;
+         colorDataPtr = colorDataPtr2 + offsetColorBand;
+         for(x = 0; x < theRegressionWidth; ++x)
+         {
+//             if((*panDataPtr != panNp)&&
+//                (colorDataPtrBands[0][offsetColorBand] != colorNp)&&
+//                (colorDataPtrBands[1][offsetColorBand] != colorNp)&&
+//                (colorDataPtrBands[2][offsetColorBand] != colorNp))
+//             {
+            if((*panDataPtr != panNp)&&
+               (*colorDataPtr != colorNp))
+            {
+//                ossimNormRgbVector rgbV(colorDataPtrBands[0][offsetColorBand],
+//                                        colorDataPtrBands[1][offsetColorBand],
+//                                        colorDataPtrBands[2][offsetColorBand]);
+//                ossimHsiVector hsi(rgbV);
+               
+               regression.addPoint(ossimDpt(*panDataPtr, *colorDataPtr));
+//               regression.addPoint(ossimDpt(*panDataPtr, hsi.getI()));
+               ++idx;
+            }
+            ++panDataPtr;
+//            ++offsetColorBand;
+               ++colorDataPtr;
+         }
+      }
+      if(idx > 2)
+      {
+         double slope, intercept;
+         result = true;
+         regression.solve();
+         regression.getEquation(slope,
+                                intercept);
+         
+         slopeResult = slope;
+      }
+   }
+
+   return result;
+}
+
+void ossimLocalCorrelationFusion::initAdjustableParameters()
+{
+   resizeAdjustableParameterArray(NUMBER_OF_ADJUSTABLE_PARAMETERS);
+
+   setAdjustableParameter(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET,
+                          0.0);
+   setParameterDescription(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET,
+                           "Attenuator");
+   setParameterSigma(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET,
+                     2.0);
+   setParameterCenter(REGRESSION_COEFFICIENT_ATTENUATOR_OFFSET,
+                      1.0);
+
+   
+   setAdjustableParameter(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
+                          0.0);
+   setParameterDescription(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
+                           "Regression clamp");
+   setParameterSigma(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
+                     10.0);
+   setParameterCenter(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
+                      10.0);
+   
+   
+   setAdjustableParameter(HIGH_PASS_GAIN_OFFSET,
+                          -1.0);
+   setParameterDescription(HIGH_PASS_GAIN_OFFSET,
+                           "High pass gain");
+   setParameterSigma(HIGH_PASS_GAIN_OFFSET,
+                     1);
+   setParameterCenter(HIGH_PASS_GAIN_OFFSET,
+                      1.0);
+
+   setAdjustableParameter(PAN_BLURR_WIDTH_OFFSET,
+                          -1);
+   setParameterDescription(PAN_BLURR_WIDTH_OFFSET,
+                           "Blurring kernel width");
+   setParameterSigma(PAN_BLURR_WIDTH_OFFSET,
+                     7);
+   setParameterCenter(PAN_BLURR_WIDTH_OFFSET,
+                      7.5);
+   
+
+   setParameterOffset(PAN_BLURR_WIDTH_OFFSET,
+                      1.5);
+   setParameterOffset(REGRESSION_COEFFICIENT_CLAMP_OFFSET,
+                      4.0);
+}
+
+void ossimLocalCorrelationFusion::adjustableParametersChanged()
+{
+//   std::cout << "Parameter offset = " << computeParameterOffset(2) << std::endl;
+   theBlurrKernelWidth = (ossim_uint32)(irint(computeParameterOffset(PAN_BLURR_WIDTH_OFFSET)));
+}
+
+
+bool ossimLocalCorrelationFusion::saveState(ossimKeywordlist& kwl,
+                                            const char* prefix) const
+{
+   ossimFusionCombiner::saveState(kwl, prefix);
+   saveAdjustments(kwl, prefix);
+
+   return true;
+}
+
+bool ossimLocalCorrelationFusion::loadState(const ossimKeywordlist& kwl,
+                                            const char* prefix)
+{
+   ossimFusionCombiner::loadState(kwl, prefix);
+   loadAdjustments(kwl, prefix);
+
+   
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLocalCorrelationFusion.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLocalCorrelationFusion.h
new file mode 100644
index 0000000000..48e2dbb737
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimLocalCorrelationFusion.h
@@ -0,0 +1,88 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LICENSE:  See top level LICENSE.txt
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimLocalCorrelationFusion.h,v 1.5 2005/12/12 12:50:16 gpotts Exp $
+#ifndef ossimLocalCorrelationFusion_HEADER
+#define ossimLocalCorrelationFusion_HEADER
+#include "ossimFusionCombiner.h"
+#include "ossimConvolutionSource.h"
+#include "ossimImageGaussianFilter.h"
+#include <base/misc/ossimAdjustableParameterInterface.h>
+
+/**
+  * This implements a Local correlation fusion based on the paper:
+  *
+  *  "A Local Correlation Approach For the Fusion of Remote Sensing Data With Different
+  *   Spatial Resolution In Forestry Applications"
+  *   by J. Hill, C. Diemer, O. Stover, and Th. Udelhoven
+  *   Published in:
+  *       International Archives of Photogrammetry and Remote Sensing, Vol 32, Part 7-4-3 W6,
+  *       Valladolid, Spain, 3-4 June, 1999
+  *
+  *   A new band is computed by the formula:
+  *
+  *   ColorHigh = ColorLow + RegressionSlope*(PanHigh-PanLow);
+  *
+  *   Adjustable paraemters have been added to clamp the regression slope and attenuate
+  *   colorLowOffset value and blurring the Pan.
+  *
+  *   ColorHigh = ColorLow + Clamp(RegressionSlope)*Attenuator(PanHigh-PanLow);
+  *
+  *   The regression coefficient is coputed for each color band.
+  */
+class OSSIM_DLL ossimLocalCorrelationFusion : public ossimFusionCombiner,
+                                              public ossimAdjustableParameterInterface
+{
+public:
+   ossimLocalCorrelationFusion();
+   virtual ~ossimLocalCorrelationFusion();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+   virtual void initialize();
+
+   virtual ossimObject* getBaseObject()
+   {
+      return this;
+   }
+   virtual const ossimObject* getBaseObject()const
+   {
+      return this;
+   }
+   virtual void initAdjustableParameters();
+   virtual void adjustableParametersChanged();
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+protected:
+   void setFilters();
+   bool computeRegression(ossim_float64& slopeResult,
+                          const ossimIpt& origin,
+                          ossimRefPtr<ossimImageData> panData,
+                          ossimRefPtr<ossimImageData> colorData,
+                          ossim_uint32 colorBandIdx);
+   
+   ossim_float64 theBlurrKernelWidth;
+   ossim_uint32 theHighPassKernelWidth;
+   ossim_uint32 theRegressionWidth;
+   // These are low and high pass filters for the single pan band
+   //
+   ossimRefPtr<ossimImageGaussianFilter> theLowPassFilter;
+   ossimRefPtr<ossimConvolutionSource> theHighPassFilter;
+   ossimRefPtr<ossimImageData>         theNormLowPassTile;
+   ossimRefPtr<ossimImageData>         theNormHighPassTile;
+   ossimRefPtr<ossimImageData>         theNormColorData;
+
+   NEWMAT::Matrix                      theHighPassMatrix;
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaskFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaskFilter.cpp
new file mode 100644
index 0000000000..9b2a05ad9d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaskFilter.cpp
@@ -0,0 +1,798 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimMaskFilter.cpp,v 1.15 2005/09/15 12:28:44 gpotts Exp $
+
+#include <imaging/tile_sources/ossimMaskFilter.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageSourceInterface.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/context/ossimNotifyContext.h>
+
+static const char * MASK_FILTER_MASK_TYPE_KW = "mask_type";
+
+RTTI_DEF1(ossimMaskFilter, "ossimMaskFilter", ossimImageCombiner);
+
+ossimMaskFilter::ossimMaskFilter(ossimObject* owner)
+  : ossimImageCombiner(owner,
+                       2,
+                       0,
+                       true,
+                       false),
+    theMaskType(OSSIM_MASK_TYPE_SELECT),
+    theTile(NULL)
+{
+}
+
+ossimMaskFilter::ossimMaskFilter(ossimImageSource* imageSource,
+				 ossimImageSource* maskSource)
+  :ossimImageCombiner(NULL,
+                      2,
+                      0,
+                      true,
+                      false),
+   theMaskType(OSSIM_MASK_TYPE_SELECT),
+   theTile(NULL)
+{
+  connectMyInputTo(0, imageSource);
+  connectMyInputTo(1, maskSource);
+} 
+
+ossimMaskFilter::ossimMaskFilter(ossimObject* owner,
+				 ossimImageSource* imageSource,
+				 ossimImageSource* maskSource)
+  :ossimImageCombiner(owner,
+                      2,
+                      0,
+                      true,
+                      false),
+   theMaskType(OSSIM_MASK_TYPE_SELECT),
+   theTile(NULL)
+
+{
+  connectMyInputTo(0, imageSource);
+  connectMyInputTo(1, maskSource);
+}
+
+ossimMaskFilter::~ossimMaskFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimMaskFilter::getTile(const ossimIrect& rect,
+                                                     ossim_uint32 resLevel)
+{
+   ossimImageSourceInterface* imageSource = PTR_CAST(ossimImageSourceInterface,
+                                                     getInput(0));
+   
+   // we will check to see if it's a fileMaskSource
+   //
+   ossimImageSourceInterface* maskSource = PTR_CAST(ossimImageSourceInterface,
+                                                    getInput(1));
+   
+   ossimRefPtr<ossimImageData> imageSourceData;
+   ossimRefPtr<ossimImageData> maskSourceData;
+   
+   if(imageSource)
+   {
+      imageSourceData = imageSource->getTile(rect, resLevel);
+   }
+
+   if(!isSourceEnabled())
+   {
+      return imageSourceData;
+   }
+   
+   if(maskSource)
+   {
+      maskSourceData = maskSource->getTile(rect, resLevel);
+   }
+
+   if (!theTile.valid())
+   {
+      allocate();
+   }
+
+   if(!imageSourceData.valid() || !theTile.valid())
+   {
+      ossimRefPtr<ossimImageData>();
+   }
+   
+   theTile->setOrigin(rect.ul());
+   if(theTile->getImageRectangle() != rect)
+   {
+      theTile->setImageRectangle(rect);
+      theTile->initialize();
+   }
+   if(!imageSourceData.valid())
+   {
+      return theTile;
+   }
+   if(!maskSourceData.valid()) 
+   {
+      return imageSourceData;
+   }
+   
+   if(imageSourceData->getDataObjectStatus() != OSSIM_NULL)
+   {
+      return executeMaskFilter(imageSourceData, maskSourceData);  
+   }
+   
+   return theTile;
+}
+
+bool ossimMaskFilter::canConnectMyInputTo(ossim_int32 index,
+                                          const ossimConnectableObject* object)const
+{
+   return (PTR_CAST(ossimImageSourceInterface, object)!= NULL);
+}
+
+void ossimMaskFilter::initialize()
+{
+   ossimImageCombiner::initialize();
+   if(getInput(0))
+   {
+      // Force an allocate on the next getTile.
+      theTile = NULL;
+   }
+}
+
+void ossimMaskFilter::allocate()
+{
+   if(getInput(0))
+   {
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+      theTile->initialize();
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimMaskFilter::executeMaskFilter(ossimRefPtr<ossimImageData> imageSourceData,
+                                                               ossimRefPtr<ossimImageData> maskSourceData)
+{
+   if(!theTile)
+   {
+      theTile = (ossimImageData*)imageSourceData->dup();
+      if(!theTile->getBuf())
+      {
+         theTile->initialize();
+      }
+   }
+   else
+   {
+      ossim_uint32 tw = theTile->getWidth();
+      ossim_uint32 th = theTile->getHeight();
+      ossim_uint32 dw = imageSourceData->getWidth();
+      ossim_uint32 dh = imageSourceData->getHeight();
+      
+      theTile->setWidthHeight(imageSourceData->getWidth(),
+			      imageSourceData->getHeight());
+      theTile->setOrigin(imageSourceData->getOrigin());
+      if((tw*th) != (dw*dh))
+      {
+         theTile->initialize();
+      }
+     theTile->setDataObjectStatus(imageSourceData->getDataObjectStatus());
+   }
+   theTile->loadTile(imageSourceData.get());
+   theTile->setDataObjectStatus(imageSourceData->getDataObjectStatus());
+  switch(theMaskType)
+  {
+  case OSSIM_MASK_TYPE_SELECT:
+  {
+     return executeMaskFilterSelect(theTile,
+                                    maskSourceData);
+  }
+  case OSSIM_MASK_TYPE_INVERT:
+  {
+     return executeMaskFilterInvertSelect(theTile,
+                                          maskSourceData);
+  }
+  case OSSIM_MASK_TYPE_WEIGHTED:
+  {
+     return executeMaskFilterWeighted(theTile,
+                                      maskSourceData);
+  }
+  }
+  
+  return imageSourceData;
+}
+
+ossimRefPtr<ossimImageData> ossimMaskFilter::executeMaskFilterSelect(ossimRefPtr<ossimImageData> imageSourceData,
+                                                                     ossimRefPtr<ossimImageData> maskSourceData)
+{
+   if(maskSourceData->getScalarType() != OSSIM_UCHAR)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimMaskFilter::executeMaskFilterSelect WARNING: Only uchar masks are supported" << endl;
+      return imageSourceData;
+   }
+
+   switch(imageSourceData->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      executeMaskFilterSelection((ossim_uint8)0,
+                                 (ossim_uint8)0,
+                                 imageSourceData,
+                                 maskSourceData);
+      break;
+   }
+   case OSSIM_USHORT11:
+   case OSSIM_USHORT16:
+   {
+      executeMaskFilterSelection((ossim_uint16)0,
+                                 (ossim_uint8)0,
+                                 imageSourceData,
+                                 maskSourceData);
+      break;
+   }
+   case OSSIM_SSHORT16:
+   {
+      executeMaskFilterSelection((ossim_sint16)0,
+                                 (ossim_uint8)0,
+                                 imageSourceData,
+                                 maskSourceData);
+      break;
+   }
+   case OSSIM_FLOAT:
+   case OSSIM_NORMALIZED_FLOAT:
+   {
+      executeMaskFilterSelection((float)0,
+                                 (ossim_uint8)0,
+                                 imageSourceData,
+                                 maskSourceData);
+      break;
+   }
+   case OSSIM_DOUBLE:
+   case OSSIM_NORMALIZED_DOUBLE:
+   {
+      executeMaskFilterSelection((double)0,
+                                 (ossim_uint8)0,
+                                 imageSourceData,
+                                 maskSourceData);
+      break;
+   }
+   default:
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimMaskFilter::executeMaskFilterSelect WARNING: Unknown scalar type" << endl;
+      break;
+   }   
+   }
+
+   return theTile;
+}
+
+ossimRefPtr<ossimImageData> ossimMaskFilter::executeMaskFilterInvertSelect(ossimRefPtr<ossimImageData> imageSourceData,
+                                                                           ossimRefPtr<ossimImageData> maskSourceData)
+{
+   if(maskSourceData->getScalarType() != OSSIM_UCHAR)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimMaskFilter::executeMaskFilterSelect WARNING: Only uchar masks are supported" << endl;
+      return imageSourceData;
+   }
+
+   switch(imageSourceData->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      executeMaskFilterInvertSelection((ossim_uint8)0,
+                                       (ossim_uint8)0,
+                                       imageSourceData,
+                                       maskSourceData);
+      break;
+   }
+   case OSSIM_USHORT11:
+   case OSSIM_USHORT16:
+   {
+      executeMaskFilterInvertSelection((ossim_uint16)0,
+                                       (ossim_uint8)0,
+                                       imageSourceData,
+                                       maskSourceData);
+      break;
+   }
+   case OSSIM_SSHORT16:
+   {
+      executeMaskFilterInvertSelection((ossim_sint16)0,
+                                       (ossim_uint8)0,
+                                       imageSourceData,
+                                       maskSourceData);
+      break;
+   }
+   case OSSIM_FLOAT:
+   case OSSIM_NORMALIZED_FLOAT:
+   {
+      executeMaskFilterInvertSelection((float)0,
+                                       (ossim_uint8)0,
+                                       imageSourceData,
+                                       maskSourceData);
+      break;
+   }
+   case OSSIM_DOUBLE:
+   case OSSIM_NORMALIZED_DOUBLE:
+   {
+      executeMaskFilterInvertSelection((double)0,
+                                       (ossim_uint8)0,
+                                       imageSourceData,
+                                       maskSourceData);
+      break;
+   }
+   default:
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimMaskFilter::executeMaskFilterSelect WARNING: Unknown scalar type" << endl;
+      break;
+   }   
+   }
+
+   return theTile;
+}
+
+ossimRefPtr<ossimImageData> ossimMaskFilter::executeMaskFilterWeighted(ossimRefPtr<ossimImageData> imageSourceData,
+                                                                       ossimRefPtr<ossimImageData> maskSourceData)
+{
+   if(maskSourceData->getScalarType() != OSSIM_UCHAR)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimMaskFilter::executeMaskFilterSelect WARNING: Only uchar masks are supported" << endl;
+      return imageSourceData;
+   }
+
+   switch(imageSourceData->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      executeMaskFilterWeighted((ossim_uint8)0,
+                                (ossim_uint8)0,
+                                imageSourceData,
+                                maskSourceData);
+      break;
+   }
+   case OSSIM_USHORT11:
+   case OSSIM_USHORT16:
+   {
+      executeMaskFilterWeighted((ossim_uint16)0,
+                                (ossim_uint8)0,
+                                imageSourceData,
+                                maskSourceData);
+      break;
+   }
+   case OSSIM_SSHORT16:
+   {
+      executeMaskFilterWeighted((ossim_sint16)0,
+                                (ossim_uint8)0,
+                                imageSourceData,
+                                maskSourceData);
+      break;
+   }
+   case OSSIM_FLOAT:
+   case OSSIM_NORMALIZED_FLOAT:
+   {
+      executeMaskFilterWeighted((float)0,
+                                (ossim_uint8)0,
+                                imageSourceData,
+                                maskSourceData);
+      break;
+   }
+   case OSSIM_DOUBLE:
+   case OSSIM_NORMALIZED_DOUBLE:
+   {
+      executeMaskFilterWeighted((double)0,
+                                (ossim_uint8)0,
+                                imageSourceData,
+                                maskSourceData);
+      break;
+   }
+   default:
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimMaskFilter::executeMaskFilterSelect WARNING: Unknown scalar type" << endl;
+      break;
+   }   
+   }
+
+   return theTile;
+}
+
+template <class inputT, class maskT>
+ossimRefPtr<ossimImageData> ossimMaskFilter::executeMaskFilterSelection(inputT dummyInput,
+                                                            maskT  dummyMask,
+                                                            ossimRefPtr<ossimImageData> imageSourceData,
+                                                            ossimRefPtr<ossimImageData> maskSourceData)
+{
+   ossimDataObjectStatus maskDataStatus  = maskSourceData->getDataObjectStatus();
+   ossimDataObjectStatus inputDataStatus = imageSourceData->getDataObjectStatus();
+
+   if( (maskDataStatus == OSSIM_NULL)||
+       (maskDataStatus == OSSIM_EMPTY))
+   {
+      theTile->makeBlank();
+      return theTile;
+      
+   }
+   if( (inputDataStatus == OSSIM_NULL)||
+       (inputDataStatus == OSSIM_EMPTY)||
+       (maskDataStatus == OSSIM_FULL))
+   {
+      return theTile;
+   }
+   if(maskDataStatus == OSSIM_FULL)
+   {
+      return theTile;
+   }
+   
+   ossim_uint32 maskBands  = maskSourceData->getNumberOfBands();
+   ossim_uint32 inputBands = imageSourceData->getNumberOfBands();
+   if(maskBands&&inputBands)
+   {
+      ossim_uint32 maxOffset = theTile->getWidth()*theTile->getHeight();
+      for(ossim_uint32 band = 0; band < inputBands; ++band)
+      {
+         maskT*    bufMask = (maskT*)maskSourceData->getBuf();
+         inputT* bufIn     = (inputT*)imageSourceData->getBuf(band);
+         inputT* bufOut    = (inputT*)theTile->getBuf(band);
+         inputT  np        = (inputT)theTile->getNullPix(band);
+         ossim_uint32 offset = 0;
+         for(offset = 0; offset < maxOffset; ++offset)
+         {
+            if(*bufMask)
+            {
+               *bufOut = *bufIn;
+            }
+            else
+            {
+               *bufOut = np;
+            }
+            ++bufOut;
+            ++bufIn;
+            ++bufMask;
+         }
+      }
+      theTile->validate();
+   }
+   
+   return theTile;
+}
+
+template <class inputT, class maskT>
+ossimRefPtr<ossimImageData> ossimMaskFilter::executeMaskFilterInvertSelection(inputT dummyInput,
+                                                                  maskT  dummyMask,
+                                                                  ossimRefPtr<ossimImageData> imageSourceData,
+                                                                  ossimRefPtr<ossimImageData> maskSourceData)
+{
+   ossimDataObjectStatus maskDataStatus  = maskSourceData->getDataObjectStatus();
+   ossimDataObjectStatus inputDataStatus = imageSourceData->getDataObjectStatus();
+
+   if((maskDataStatus == OSSIM_NULL) ||
+      (maskDataStatus == OSSIM_EMPTY))
+   {
+      return theTile;
+   }
+   if( (inputDataStatus == OSSIM_NULL)||
+       (inputDataStatus == OSSIM_EMPTY))
+   {
+      return theTile;
+   }
+      
+   if(maskDataStatus == OSSIM_FULL)
+   {
+      theTile->makeBlank();
+      
+      return theTile;
+   }
+   
+   ossim_uint32 maskBands  = maskSourceData->getNumberOfBands();
+   ossim_uint32 inputBands = imageSourceData->getNumberOfBands();
+   if(maskBands&&inputBands)
+   {
+      ossim_uint32 maxOffset = theTile->getWidth()*theTile->getHeight();
+      for(ossim_uint32 band = 0; band < inputBands; ++band)
+      {
+         maskT*    bufMask = (maskT*)maskSourceData->getBuf();
+         inputT* bufIn     = (inputT*)imageSourceData->getBuf(band);
+         inputT* bufOut    = (inputT*)theTile->getBuf(band);
+         inputT  np        = (inputT)theTile->getNullPix(band);
+         ossim_uint32 offset = 0;
+         for(offset = 0; offset < maxOffset; ++offset)
+         {
+            if(!*bufMask)
+            {
+               *bufOut = *bufIn;
+            }
+            else
+            {
+               *bufOut = np;
+            }
+            ++bufOut;
+            ++bufIn;
+            ++bufMask;
+         }
+      }
+      theTile->validate();
+   }
+   
+   return theTile;
+}
+
+template <class inputT, class maskT>
+ossimRefPtr<ossimImageData> ossimMaskFilter::executeMaskFilterWeighted(inputT dummyInput,
+                                                           maskT  dummyMask,
+                                                           ossimRefPtr<ossimImageData> imageSourceData,
+                                                           ossimRefPtr<ossimImageData> maskSourceData)
+{
+   ossimDataObjectStatus maskDataStatus  = maskSourceData->getDataObjectStatus();
+   ossimDataObjectStatus inputDataStatus = imageSourceData->getDataObjectStatus();
+
+   if( (maskDataStatus == OSSIM_NULL)||
+       (maskDataStatus == OSSIM_EMPTY))
+   {
+      theTile->makeBlank();
+      return theTile;
+      
+   }
+   if( (inputDataStatus == OSSIM_NULL)||
+       (inputDataStatus == OSSIM_EMPTY))
+   {
+      return theTile;
+   }
+   
+   ossim_uint32 maskBands  = maskSourceData->getNumberOfBands();
+   ossim_uint32 inputBands = imageSourceData->getNumberOfBands();
+   if(maskBands&&inputBands)
+   {
+      ossim_uint32 maxOffset = theTile->getWidth()*theTile->getHeight();
+      for(ossim_uint32 band = 0; band < inputBands; ++band)
+      {
+         maskT*    bufMask = (maskT*)maskSourceData->getBuf();
+         inputT* bufIn     = (inputT*)imageSourceData->getBuf(band);
+         inputT* bufOut    = (inputT*)theTile->getBuf(band);
+         inputT  np        = (inputT)theTile->getNullPix(band);
+         inputT  minp      = (inputT)theTile->getMinPix(band);
+         ossim_uint32 offset = 0;
+
+         if(inputDataStatus == OSSIM_PARTIAL)
+         {
+            for(offset = 0; offset < maxOffset; ++offset)
+            {
+               if(*bufIn != np)
+               {
+                  *bufOut = (inputT)((*bufIn)*((double)(*bufMask)/255.0));
+                  if((*bufOut != np)&&
+                     (*bufOut < minp))
+                  {
+                     *bufOut = minp;
+                  }
+               }
+               else
+               {
+                  *bufOut = np;
+               }
+               ++bufOut;
+               ++bufIn;
+               ++bufMask;
+            }
+         }
+         else
+         {
+            for(offset = 0; offset < maxOffset; ++offset)
+            {
+               *bufOut = (inputT)((*bufIn)*((double)(*bufMask)/255.0));
+               if((*bufOut != np)&&
+                  (*bufOut < minp))
+               {
+                  *bufOut = minp;
+               }
+               ++bufOut;
+               ++bufIn;
+               ++bufMask;
+            }
+         }
+      }
+      theTile->validate();
+   }
+   
+   return theTile;
+}
+
+
+ossimIrect ossimMaskFilter::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimIrect result;
+   result.makeNan();
+
+   ossimImageSourceInterface* imageSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(imageSource)
+   {
+      result = imageSource->getBoundingRect(resLevel);
+   }
+   return result;
+}
+
+bool ossimMaskFilter::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   bool result = ossimImageCombiner::loadState(kwl, prefix);
+   
+   theInputListIsFixedFlag  = true;
+   theOutputListIsFixedFlag = false;
+   setNumberOfInputs(2);
+
+   ossimString selectionType = kwl.find(prefix, MASK_FILTER_MASK_TYPE_KW);
+
+   selectionType = selectionType.upcase();
+   if(selectionType != "")
+   {
+      if(selectionType == "SELECT")
+      {
+         theMaskType = OSSIM_MASK_TYPE_SELECT;
+      }
+      else if(selectionType == "INVERT")
+      {
+         theMaskType = OSSIM_MASK_TYPE_INVERT;
+      }
+      else if(selectionType == "WEIGHTED")
+      {
+         theMaskType = OSSIM_MASK_TYPE_WEIGHTED;
+      }
+   }
+
+   return result;
+}
+
+bool ossimMaskFilter::saveState(ossimKeywordlist& kwl,
+                                const char* prefix)const
+{
+   ossimString maskType;
+
+   switch(theMaskType)
+   {
+   case OSSIM_MASK_TYPE_SELECT:
+   {
+      maskType = "select";
+      break;
+   }
+   case OSSIM_MASK_TYPE_INVERT:
+   {
+      maskType = "invert";
+      break;
+   }
+   case OSSIM_MASK_TYPE_WEIGHTED:
+   {
+      maskType = "weighted";
+      break;
+   }
+   }
+   
+   kwl.add(prefix,
+           MASK_FILTER_MASK_TYPE_KW,
+           maskType.c_str(),
+           true);
+   
+   return ossimImageCombiner::saveState(kwl, prefix);
+}
+void ossimMaskFilter::getDecimationFactor(ossim_uint32 resLevel,
+                                          ossimDpt& result)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      input->getDecimationFactor(resLevel, result);
+   }
+}
+
+void ossimMaskFilter::getDecimationFactors(vector<ossimDpt>& decimations)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      input->getDecimationFactors(decimations);
+   }     
+}
+
+ossim_uint32 ossimMaskFilter::getNumberOfDecimationLevels()const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getNumberOfDecimationLevels();
+   } 
+   return 0;
+}
+
+ossim_uint32 ossimMaskFilter::getNumberOfOutputBands() const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getNumberOfOutputBands();
+   }
+   return 0;
+}
+
+ossimScalarType ossimMaskFilter::getOutputScalarType() const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getOutputScalarType();
+   }
+   
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+void ossimMaskFilter::getValidImageVertices(
+   vector<ossimIpt>& validVertices,
+   ossimVertexOrdering ordering,
+   ossim_uint32 resLevel)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      input->getValidImageVertices(validVertices, ordering, resLevel);
+   }
+}
+
+ossim_uint32 ossimMaskFilter::getTileWidth() const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getTileWidth();
+   }
+   
+   return 0;
+}
+
+ossim_uint32 ossimMaskFilter::getTileHeight() const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getTileHeight();
+   }
+   return 0;
+}
+
+double ossimMaskFilter::getNullPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getNullPixelValue(band);
+   }
+   return 0;
+}
+
+double ossimMaskFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getMinPixelValue(band);
+   }
+   return 0;
+}
+
+double ossimMaskFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* input = PTR_CAST(ossimImageSourceInterface,
+                                               getInput(0));
+   if(input)
+   {
+      return input->getMaxPixelValue(band);
+   }
+   return 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaskFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaskFilter.h
new file mode 100644
index 0000000000..ebfdc842bd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaskFilter.h
@@ -0,0 +1,234 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: A brief description of the contents of the file.
+//
+//*************************************************************************
+// $Id: ossimMaskFilter.h,v 1.13 2005/09/15 12:28:44 gpotts Exp $
+#ifndef  ossimMaskFilter_HEADER
+#define  ossimMaskFilter_HEADER
+#include <imaging/tile_sources/ossimImageCombiner.h>
+
+/**
+ * <pre>
+ * class ossimMaskFilter
+ *
+ *    Requires 2 inputs.  The first input is assumed to be the image input
+ *    and the second input is assumed to be the mask data.  It will only
+ *    use one band of the mask and multi band masks are not supported.
+ *
+ *    the number of bands, min pix, max pix, null pix ...etc are mapped
+ *    to the first input.
+ *
+ * Keywords:
+ *      mask_type:
+ *
+ * keywords description
+ *      mask_type  This keyword can have the following values:
+ *                 select, invert, or weighted.
+ *                  - select will use the input data and every where
+ *                    the mask is greater than 0 it will copy the input to the output.
+ *                  - invert will use the input data and every where the mask is 0 it
+ *                    will copy the input to the output else it will place a null in
+ *                    the output.
+ *                  - weighted will normalize the mask between 0 and 1 and then multiply
+ *                    the input by that normalized value and copy to the output.
+ *
+ * example of keywords:
+ *
+ *      mask_type: select
+ *
+ * </pre>
+ */
+class OSSIMDLLEXPORT ossimMaskFilter : public ossimImageCombiner
+{
+public:
+   /**
+    * Enumeration used to identify what the selection type for this mask is to be
+    *  A list of events:
+    *    - OSSIM_MASK_TYPE_SELECT
+    *      is used as a true false mask.  If the mask is non zero
+    *      then the input is kept if it's 0 then the input is nulled out.
+    *    - OSSIM_MASK_TYPE_INVERT
+    *      has the inverted rule of the above.  If the input is tru then the output is nulled
+    *      else the input is kept
+    *    - OSSIM_MASK_TYPE_WEIGHTED
+    *      works as a multiplier of the input data.  The mask is normalized to be between 0 and 1
+    *      and multiplies the input by that normalized value.
+    */
+  enum ossimFileSelectionMaskType
+  {
+     OSSIM_MASK_TYPE_SELECT   = 1, /**< standard select if mask is true then keep */
+     OSSIM_MASK_TYPE_INVERT   = 2, /**< standard invert if mask is true the don't keep */
+     OSSIM_MASK_TYPE_WEIGHTED = 3  /**< weighted operation.  Normalize the mask and multiply the input */
+  };
+
+   /**
+    * Constructor.
+    */
+  ossimMaskFilter(ossimObject* owner=NULL);
+
+   /**
+    * Constructs with two inputs
+    */
+  ossimMaskFilter(ossimImageSource* imageSource,
+		  ossimImageSource* maskSource);
+
+   
+   /**
+    * Constructs with two inputs and an owner
+    */
+  ossimMaskFilter(ossimObject* owner,
+		  ossimImageSource* imageSource,
+		  ossimImageSource* maskSource);
+
+   /**
+    * Will delete its owned tile.
+    */
+   virtual ~ossimMaskFilter();
+
+   /**
+    * Sets the mask type.
+    * \param type The mask algorithm type to be used.  see ossimFileSelectionMaskType
+    */
+   virtual void setMaskType(ossimFileSelectionMaskType type)
+      {
+         theMaskType = type;
+      }
+
+   /**
+    * Returns the current mask algorithm used.
+    * \return the current ossimFileSelectionMaskType used.
+    */
+   virtual ossimFileSelectionMaskType getMaskType()const
+      {
+         return theMaskType;
+      }
+
+   /**
+    * Returns the bounding rect in pixel space for this object.
+    * \param resLevel optional res level argument is given.
+    * \return The bounding rect.  It will pass the inputs bounding
+    *         rect since it does not update the bounds.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+
+   /**
+    * Main entry point for the algorithm.
+    * \param rect 
+    *
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                   ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result)const;
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations)const;
+
+   virtual ossim_uint32 getNumberOfDecimationLevels()const;
+
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+   
+   virtual ossimScalarType getOutputScalarType() const;
+
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const;
+
+   virtual ossim_uint32 getTileWidth() const;
+
+   virtual ossim_uint32 getTileHeight() const;
+
+   virtual double getNullPixelValue(ossim_uint32 band)const;
+   
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   virtual bool canConnectMyInputTo(ossim_int32 index,
+                                    const ossimConnectableObject* object)const;
+   
+   virtual ossimRefPtr<ossimImageData> executeMaskFilter(
+      ossimRefPtr<ossimImageData> imageSourceData,
+      ossimRefPtr<ossimImageData> maskSourceData);
+   
+protected:
+   
+   void allocate();
+   
+   /**
+    * will execute the section algorithm.  everywhere the mask is not 0 it
+    * copies the input data to the output and everywhere the input is null it
+    * writes a null pixel to the output.
+    */
+   ossimRefPtr<ossimImageData> executeMaskFilterSelect(
+      ossimRefPtr<ossimImageData> imageSourceData,
+      ossimRefPtr<ossimImageData> maskSourceData);
+
+   /**
+    * will execute the invert selection algorithm.  everywhere the mask is 0
+    * it copies the input data to the output else it outputs null.
+    */
+   ossimRefPtr<ossimImageData> executeMaskFilterInvertSelect(
+      ossimRefPtr<ossimImageData> imageSourceData,
+      ossimRefPtr<ossimImageData> maskSourceData);
+
+   /**
+    * will execute the weighted algorithm.  It normalizes the mask value to
+    * be between 0 and 1 and multiplies the input data by that value and
+    * outputs it.  
+    */
+   ossimRefPtr<ossimImageData> executeMaskFilterWeighted(
+      ossimRefPtr<ossimImageData> imageSourceData,
+      ossimRefPtr<ossimImageData> maskSourceData);
+
+   
+   template <class inputT, class maskT>
+   ossimRefPtr<ossimImageData> executeMaskFilterSelection(
+      inputT dummyInput,
+      maskT  dummyMask,
+      ossimRefPtr<ossimImageData> imageSourceData,
+      ossimRefPtr<ossimImageData> maskSourceData);
+   
+   template <class inputT, class maskT>
+   ossimRefPtr<ossimImageData> executeMaskFilterInvertSelection(
+      inputT dummyInput,
+      maskT  dummyMask,
+      ossimRefPtr<ossimImageData> imageSourceData,
+      ossimRefPtr<ossimImageData> maskSourceData);
+   
+   template <class inputT, class maskT>
+   ossimRefPtr<ossimImageData> executeMaskFilterWeighted(
+      inputT dummyInput,
+      maskT  dummyMask,
+      ossimRefPtr<ossimImageData> imageSourceData,
+      ossimRefPtr<ossimImageData> maskSourceData);
+
+   /**
+    * Member variable that holds the algorithm type to run on the calls to getTile.
+    */
+   ossimFileSelectionMaskType  theMaskType;
+
+   /**
+    * Member used to store the result of the applied algorithm type.  This is returned
+    * from the call to getTile.
+    */
+   ossimRefPtr<ossimImageData> theTile;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaxMosaic.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaxMosaic.cpp
new file mode 100644
index 0000000000..30fb01031b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaxMosaic.cpp
@@ -0,0 +1,547 @@
+//*******************************************************************
+// Copyright (C) 2005 SANZ Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Kenneth Melero (kmelero@sanz.com)
+//
+// Description: This combiner is designed to "float" the maximum pixel value
+//              of all inputs to top of the mosaic output. 
+//
+//*************************************************************************
+// $Id: ossimMaxMosaic.cpp,v 1.3 2005/06/30 15:14:57 gpotts Exp $
+
+#include <imaging/tile_sources/ossimMaxMosaic.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimTrace.h>
+
+static const ossimTrace traceDebug("ossimMaxMosaic:debug");
+
+using namespace std;
+
+RTTI_DEF1(ossimMaxMosaic, "ossimMaxMosaic", ossimImageCombiner)
+ossimMaxMosaic::ossimMaxMosaic()
+   :ossimImageCombiner(),
+    theTile(NULL)
+{
+}
+
+ossimMaxMosaic::ossimMaxMosaic(const vector<ossimImageSource*>& inputSources)
+    : ossimImageCombiner(inputSources),
+      theTile(NULL)
+{
+}
+
+
+ossimMaxMosaic::~ossimMaxMosaic()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimMaxMosaic::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   long size = getNumberOfInputs();
+   
+   // If there is only one in the mosaic then just return it.
+   if(size == 1)
+   {
+      return getNextTile(0, tileRect, resLevel);
+   }
+   
+   ossimIpt origin = tileRect.ul();
+   ossim_uint32 w = tileRect.width();
+   ossim_uint32 h = tileRect.height();
+   
+   if(!theTile.valid())
+   {
+      // First time through...
+      allocate();
+
+      // If we still don't have a buffer then we will leave.
+      if(!theTile.valid())
+      {
+         return ossimRefPtr<ossimImageData>();
+      }
+   }
+   
+   ossim_uint32 tileW = theTile->getWidth();
+   ossim_uint32 tileH = theTile->getHeight();
+   if((w != tileW)||
+      (h != tileH))
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+      }
+   }
+   theTile->setOrigin(origin);
+
+   //---
+   // General Note:
+   //
+   // Note: I will not check for disabled or enabled since we have
+   // no clear way to handle this within a mosaic. The default will be
+   // to do a simple a A over B type mosaic.  Derived classes should
+   // check for the enabled and disabled and always
+   // use this default implementation if they are disabled.
+   //---
+   theTile->setOrigin(origin);
+   theTile->makeBlank();
+   switch(theTile->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_uint8>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_uint8>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SINT8:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_sint8>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_sint8>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_FLOAT: 
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<float>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<float>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_uint16>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_uint16>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SSHORT16:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_sint16>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_sint16>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SINT32:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_sint32>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_sint32>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_UINT32:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<ossim_uint32>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<ossim_uint32>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         if(!hasDifferentInputs())
+         {
+            return combine(static_cast<double>(0),
+                           tileRect,
+                           resLevel);
+         }
+         else
+         {
+            return combineNorm(static_cast<double>(0),
+                               tileRect,
+                               resLevel);
+         }
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Scalar type = " << theTile->getScalarType()
+            << " Not supported by ossimMaxMosaic" << endl;
+      }
+   }
+
+   return ossimRefPtr<ossimImageData>();
+}
+
+void ossimMaxMosaic::initialize()
+{
+  ossimImageCombiner::initialize();
+  theTile = NULL;
+}
+
+void ossimMaxMosaic::allocate()
+{
+   theTile = NULL;
+   
+   if( (getNumberOfInputs() > 0) && getInput(0) )
+   {
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+      theTile->initialize();
+   }
+}
+
+bool ossimMaxMosaic::saveState(ossimKeywordlist& kwl,
+                                 const char* prefix)const
+{
+   return ossimImageCombiner::saveState(kwl, prefix);
+}
+
+bool ossimMaxMosaic::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   return ossimImageCombiner::loadState(kwl, prefix);
+}
+
+template <class T> ossimRefPtr<ossimImageData> ossimMaxMosaic::combineNorm(
+   T,// dummy template variable 
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> destination = theTile;
+   
+   ossimRefPtr<ossimImageData> currentImageData =
+      getNextNormTile(0, tileRect, resLevel);
+      
+   if(!currentImageData)
+   {
+      return currentImageData;
+   }
+   
+   float** srcBands        = new float*[theLargestNumberOfInputBands];
+   float* srcBandsNullPix  = new float[theLargestNumberOfInputBands];
+   T** destBands = new T*[theLargestNumberOfInputBands];
+   T* destBandsNullPix = new T[theLargestNumberOfInputBands];
+   T* destBandsMinPix = new T[theLargestNumberOfInputBands];
+   T* destBandsMaxPix = new T[theLargestNumberOfInputBands];
+      
+   ossim_uint32 band;
+   ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
+   ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
+   for(band = 0; band < minNumberOfBands; ++band)
+   {
+      srcBands[band]  = static_cast<float*>(currentImageData->getBuf(band));
+      srcBandsNullPix[band]  = static_cast<float>(currentImageData->getNullPix(band));
+      
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+      destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
+      destBandsMinPix[band] = static_cast<T>(theTile->getMinPix(band));
+      destBandsMaxPix[band] = static_cast<T>(theTile->getMaxPix(band));
+   }
+   // if the src is smaller than the destination in number
+   // of bands we will just duplicate the last band.
+   for(;band < theLargestNumberOfInputBands; ++band)
+   {
+      srcBands[band]  = static_cast<float*>(srcBands[minNumberOfBands - 1]);
+      srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(minNumberOfBands - 1));
+      
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+      destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
+      destBandsMinPix[band] = static_cast<T>(theTile->getMinPix(band));
+      destBandsMaxPix[band] = static_cast<T>(theTile->getMaxPix(band));
+   }
+   // most of the time we will not overlap so let's
+   // copy the first tile into destination and check later.
+   //
+   ossim_uint32 tempBandIdx = 0;
+   for(band = 0; band < theTile->getNumberOfBands();++band)
+   {
+      if(band < currentImageData->getNumberOfBands())
+      {
+         theTile->copyNormalizedBufferToTile(band,
+                                             (float*)currentImageData->getBuf(band));
+         ++tempBandIdx;
+      }
+      else
+      {
+         if(tempBandIdx)
+         {
+            theTile->copyNormalizedBufferToTile(band,
+                                                (float*)currentImageData->getBuf(tempBandIdx-1));
+         }
+      }
+   }
+   destination->validate();
+   
+   currentImageData = getNextNormTile(tileRect, resLevel);
+
+   while(currentImageData.valid())
+   {  
+      ossim_uint32 minNumberOfBands           = currentImageData->getNumberOfBands();
+      ossimDataObjectStatus currentStatus     = currentImageData->getDataObjectStatus();
+      ossimDataObjectStatus destinationStatus = destination->getDataObjectStatus();
+      
+      if(destinationStatus == OSSIM_FULL)
+      {
+         return destination;
+      }
+      for(band = 0; band < minNumberOfBands; ++band)
+      {
+         srcBands[band]        = static_cast<float*>(currentImageData->getBuf(band));
+         srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(band));
+      }
+      // if the src is smaller than the destination in number
+      // of bands we will just duplicate the last band.
+      for(;band < theLargestNumberOfInputBands; ++band)
+      {
+         srcBands[band] = srcBands[minNumberOfBands - 1];
+         srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
+      }
+
+      if((destinationStatus == OSSIM_EMPTY)&&
+         (currentStatus     != OSSIM_EMPTY)&&
+         (currentStatus     != OSSIM_NULL))
+      {
+         ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
+         for(band=0; band < theLargestNumberOfInputBands; ++band)
+         {
+            float delta = destBandsMaxPix[band] - destBandsMinPix[band];
+            float minP  = destBandsMinPix[band];
+            for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+            {
+               destBands[band][offset] = (T)( minP + delta*srcBands[band][offset]);
+            }
+         }
+      }
+      else if((destinationStatus == OSSIM_PARTIAL)&&
+              (currentStatus     != OSSIM_EMPTY)&&
+              (currentStatus     != OSSIM_NULL))
+      {
+         for(band = 0; band < theLargestNumberOfInputBands; ++band)
+         {
+            
+            float delta = destBandsMaxPix[band] - destBandsMinPix[band];
+            float minP  = destBandsMinPix[band];
+            for(ossim_uint32 offset = 0;
+                offset < upperBound;
+                ++offset)
+            {
+               
+               if(destBands[band][offset] == destBandsNullPix[band])
+               {
+                  destBands[band][offset] = (T)(minP + delta*srcBands[band][offset]);
+               }
+            }
+         }
+      }
+      destination->validate();
+      
+      currentImageData = getNextNormTile(tileRect, resLevel);
+   }
+   // Cleanup...
+   delete [] srcBands;
+   delete [] srcBandsNullPix;
+   delete [] destBands;
+   delete [] destBandsNullPix;
+   delete [] destBandsMinPix;
+   delete [] destBandsMaxPix;
+
+   return destination;
+}
+
+template <class T> ossimRefPtr<ossimImageData> ossimMaxMosaic::combine(
+   T,// dummy template variable 
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   ossimRefPtr<ossimImageData> destination = theTile;
+
+   ossimRefPtr<ossimImageData> currentImageData =
+      getNextTile(0, tileRect, resLevel);
+      
+   T** srcBands         = new T*[theLargestNumberOfInputBands];
+   T*  srcBandsNullPix  = new T[theLargestNumberOfInputBands];
+   T** destBands        = new T*[theLargestNumberOfInputBands];
+   T*  destBandsNullPix = new T[theLargestNumberOfInputBands];
+      
+   ossim_uint32 band;
+   ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
+   ossim_uint32 bandIndex  = 0;
+   if(!currentImageData)
+   {
+      return currentImageData;
+   }
+   ossim_uint32 offset=0;
+   ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
+   for(band = 0; band < minNumberOfBands; ++band)
+   {
+      srcBands[band]  = static_cast<T*>(currentImageData->getBuf(band));
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+      srcBandsNullPix[band]  = static_cast<T>(currentImageData->getNullPix(band));
+      destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
+   }
+   // if the src is smaller than the destination in number
+   // of bands we will just duplicate the last band.
+   for(;band < theLargestNumberOfInputBands; ++band)
+   {
+      srcBands[band]  = static_cast<T*>(srcBands[minNumberOfBands - 1]);
+      destBands[band] = static_cast<T*>(theTile->getBuf(band));
+      srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
+      destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
+   }
+   // most of the time we will not overlap so let's
+   // copy the first tile into destination and check later.
+   //
+   for(band = 0; band < theTile->getNumberOfBands();++band)
+   {
+      T* destBand = destBands[band];
+      T* srcBand  = srcBands[band];
+      if(destBand&&srcBand)
+      {
+         for(offset = 0; offset < upperBound;++offset)
+         {
+	   *destBand = *srcBand;
+	   ++srcBand; ++destBand;
+         }
+      }
+   }
+   destination->setDataObjectStatus(currentImageData->getDataObjectStatus());
+
+   currentImageData = getNextTile(tileRect,
+                                  resLevel);
+
+   while(currentImageData.valid())
+   {  
+      ossim_uint32 minNumberOfBands           = currentImageData->getNumberOfBands();
+      ossimDataObjectStatus currentStatus     = currentImageData->getDataObjectStatus();
+      ossimDataObjectStatus destinationStatus = destination->getDataObjectStatus();
+      
+      for(band = 0; band < minNumberOfBands; ++band)
+      {
+         srcBands[band]        = static_cast<T*>(currentImageData->getBuf(band));
+         srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(band));
+      }
+      // if the src is smaller than the destination in number
+      // of bands we will just duplicate the last band.
+      for(;band < theLargestNumberOfInputBands; ++band)
+      {
+         srcBands[band] = srcBands[minNumberOfBands - 1];
+         srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
+      }
+
+
+      if((destinationStatus == OSSIM_PARTIAL)&&
+	 (currentStatus     != OSSIM_EMPTY)&&
+	 (currentStatus     != OSSIM_NULL))
+	{
+	  for(bandIndex = 0; bandIndex < theLargestNumberOfInputBands; ++bandIndex)
+	    {
+	      
+	      for(ossim_uint32 offset = 0;
+		  offset < upperBound;
+		  ++offset)
+		{
+		  if(srcBands[bandIndex][offset] > destBands[bandIndex][offset])
+		    {
+		      destBands[bandIndex][offset] = srcBands[bandIndex][offset];
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
+	  for(ossim_uint32 band=0; band < theLargestNumberOfInputBands; ++band)
+	    {
+	      for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
+		{
+		  if(srcBands[band][offset] > destBands[band][offset])
+		    {
+		      destBands[band][offset] = srcBands[band][offset];
+		    }
+		}
+	    }
+	}
+      
+      destination->validate();
+      
+      currentImageData = getNextTile(tileRect, resLevel);
+   }
+   // Cleanup...
+   delete [] srcBands;
+   delete [] srcBandsNullPix;
+   delete [] destBands;
+   delete [] destBandsNullPix;
+   return destination;
+}
+
+ossimString ossimMaxMosaic::getShortName()const
+{
+   return ossimString("ossimMaxMosaic");
+}
+
+ossimString ossimMaxMosaic::getLongName()const
+{
+   return ossimString("Max Mosaic");
+}
+
+ossimString ossimMaxMosaic::getDescription()const
+{
+   return ossimString("Combiner which puts maximum dn value on image.");
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaxMosaic.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaxMosaic.h
new file mode 100644
index 0000000000..a53de26926
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMaxMosaic.h
@@ -0,0 +1,79 @@
+//*******************************************************************
+// Copyright (C) 2005 SANZ Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Kenneth Melero (kmelero@sanz.com)
+//
+// Description: This combiner is designed to "float" the maximum pixel value
+//              of all inputs to the top of the mosaic output. 
+//
+//*************************************************************************
+// $Id: ossimMaxMosaic.h,v 1.1 2005/04/15 14:49:10 dburken Exp $
+#ifndef ossimMaxMosaic_HEADER
+#define ossimMaxMosaic_HEADER
+
+#include <vector>
+#include <imaging/tile_sources/ossimImageCombiner.h>
+
+
+/**
+ * An image mosaic is a simple combiner that will
+ * just do a simple mosaic.  It just checks NULL pix values until it finds a
+ * pixel that is not empty and copies it out to the output.  The list will
+ * have same size tiles and have the same number of bands.
+ */
+class OSSIMDLLEXPORT ossimMaxMosaic : public ossimImageCombiner
+{
+public:
+   ossimMaxMosaic();
+   ossimMaxMosaic(const std::vector<ossimImageSource*>& inputSources);
+   virtual ~ossimMaxMosaic();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual void initialize();
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual ossimString getShortName() const;
+   virtual ossimString getLongName()  const;
+   virtual ossimString getDescription()const;
+
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+   
+   ossimRefPtr<ossimImageData> theTile;
+
+   template <class T> ossimRefPtr<ossimImageData> combine(
+      T, // dummy template variable not used
+      const ossimIrect& tileRect,
+      ossim_uint32 resLevel=0);
+   template <class T> ossimRefPtr<ossimImageData> combineNorm(
+      T, // dummy template variable not used
+      const ossimIrect& tileRect,
+      ossim_uint32 resLevel=0);
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMultiBandHistogramTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMultiBandHistogramTileSource.cpp
new file mode 100644
index 0000000000..8f29cb8003
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMultiBandHistogramTileSource.cpp
@@ -0,0 +1,371 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimMultiBandHistogramTileSource.cpp,v 1.6 2005/05/09 12:39:40 dburken Exp $
+#include <imaging/tile_sources/ossimMultiBandHistogramTileSource.h>
+#include <base/data_types/ossimMultiResLevelHistogram.h>
+#include <base/data_types/ossimMultiBandHistogram.h>
+#include <base/data_types/ossimHistogram.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimKeyword.h>
+#include <base/common/ossimCommon.h>
+#include <imaging/ossimImageData.h>
+#include <base/context/ossimNotifyContext.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <algorithm>
+
+static const char* MIN_VALUE_PERCENT_KW = "min_percent";
+static const char* MAX_VALUE_PERCENT_KW = "max_percent";
+static const char* ALGORITHM_KW         = "algorithm";
+
+RTTI_DEF1(ossimMultiBandHistogramTileSource,
+          "ossimMultiBandHistogramTileSource",
+          ossimImageSourceHistogramFilter)
+   
+ossimMultiBandHistogramTileSource::ossimMultiBandHistogramTileSource()
+   : ossimImageSourceHistogramFilter(),
+     theTile(NULL),
+     theAlgorithm(OSSIM_HISTOGRAM_LINEAR_STRETCH_ALGORITHM)
+{
+   disableSource();
+}
+
+ossimMultiBandHistogramTileSource::ossimMultiBandHistogramTileSource(double minValuePercent,
+                                                               double maxValuePercent,
+                                                               ossimImageSource* inputSource,
+                                                               ossimMultiResLevelHistogram* histogram)
+   : ossimImageSourceHistogramFilter(inputSource, histogram),
+     theTile(NULL),
+     theAlgorithm(OSSIM_HISTOGRAM_LINEAR_STRETCH_ALGORITHM)
+{
+   disableSource();
+}
+
+ossimMultiBandHistogramTileSource::~ossimMultiBandHistogramTileSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimMultiBandHistogramTileSource::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection) return NULL;
+   
+   ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(tileRect,
+                                                                       resLevel);
+   
+   if(!isSourceEnabled() || !inputTile.valid())
+   {
+      return inputTile;
+   }
+
+   if(!theTile.valid())
+   {
+      allocate(); // First time through...
+   }
+   
+   if( !theTile.valid() ||
+       !theMinValuePercentArray.size() ||
+       !theMaxValuePercentArray.size() )
+   {
+      return inputTile;
+   }
+   
+   theTile->setImageRectangle(tileRect);
+   if(inputTile->getBuf()&&
+      (inputTile->getDataObjectStatus()!=OSSIM_EMPTY))
+   {
+      theTile->loadTile(inputTile.get());
+      switch(inputTile->getScalarType())
+      {
+         case OSSIM_UCHAR:
+         {
+            return runLinearStretchAlgorithm((ossim_uint8)0,
+                                             theTile);
+         }
+         case OSSIM_USHORT16:
+         case OSSIM_USHORT11:
+         {
+            return runLinearStretchAlgorithm((ossim_uint16)0,
+                                             theTile);
+         }
+         case OSSIM_SSHORT16:
+         {
+            return runLinearStretchAlgorithm(static_cast<ossim_sint16>(0),
+                                             theTile);
+         }
+         case OSSIM_DOUBLE:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            return runLinearStretchAlgorithm(static_cast<double>(0),
+                                             theTile);
+         }
+         case OSSIM_FLOAT:
+         case OSSIM_NORMALIZED_FLOAT:
+         {
+            return runLinearStretchAlgorithm(static_cast<float>(0),
+                                             theTile);
+         }
+         case OSSIM_SCALAR_UNKNOWN:
+         default:
+         {
+            ossimSetError("ossimMultiBandHistogramTileSource",
+                          ossimErrorCodes::OSSIM_ERROR,
+                          "Unknown scalar type");
+            break;
+         }
+      }
+      theTile->validate();
+      return theTile;
+   }
+   
+   return inputTile;
+}
+
+void ossimMultiBandHistogramTileSource::initialize()
+{
+   ossimImageSourceHistogramFilter::initialize();
+
+   // Force an allocate on the next getTile.
+   theTile = NULL;
+}
+
+void ossimMultiBandHistogramTileSource::allocate()
+{
+   theTile = ossimImageDataFactory::instance()->create(this, this);
+
+   if(theTile.valid())
+   {
+      theTile->initialize();
+
+      ossim_uint32 numberOfBands = theTile->getNumberOfBands();
+      ossim_uint32 i = 0;
+      if(numberOfBands)
+      {
+         std::vector<double> copyArray;
+         
+         if(numberOfBands > theMinValuePercentArray.size())
+         {
+            copyArray = theMinValuePercentArray;
+            theMinValuePercentArray.resize(numberOfBands);
+            if(numberOfBands < copyArray.size())
+            {
+               std::copy(copyArray.begin(),
+                         copyArray.end(),
+                         theMinValuePercentArray.begin());
+            }
+            else
+            {
+               std::copy(copyArray.begin(),
+                         copyArray.begin() + copyArray.size(),
+                         theMinValuePercentArray.begin());
+            }
+         }
+         if(numberOfBands != theMaxValuePercentArray.size())
+         {
+            copyArray = theMaxValuePercentArray;
+            theMaxValuePercentArray.resize(numberOfBands);
+            if(numberOfBands < copyArray.size())
+            {
+               std::copy(copyArray.begin(),
+                         copyArray.end(),
+                         theMaxValuePercentArray.begin());
+            }
+            else
+            {
+               std::copy(copyArray.begin(),
+                         copyArray.begin() + copyArray.size(),
+                         theMaxValuePercentArray.begin());
+            }
+         }
+         if(numberOfBands > theMinValuePercentArray.size())
+         {
+            for(i = theMinValuePercentArray.size(); i < numberOfBands; ++i)
+            {
+               theMinValuePercentArray[i] = 0.0;
+               theMaxValuePercentArray[i] = 0.0;
+            }
+         }
+      }
+   }
+}
+
+bool ossimMultiBandHistogramTileSource::loadState(const ossimKeywordlist& kwl,
+                                           const char* prefix)
+{
+   theMinValuePercentArray.clear();
+   theMaxValuePercentArray.clear();
+   if(ossimImageSourceHistogramFilter::loadState(kwl, prefix))
+   {
+      ossimNotify(ossimNotifyLevel_INFO) << "ossimMultiBandHistogramTileSource::loadState INFO: histogram filter was loaded" << std::endl;
+      ossimString regExpression = ossimString("^(") + ossimString(prefix) + ossimString(MIN_VALUE_PERCENT_KW) + ossimString("[0-9]+)");
+
+      long numberOfSources = kwl.getNumberOfSubstringKeys(regExpression);
+      
+      unsigned long numberOfMatches = 0;
+      ossim_uint32 i = 0;
+      while(numberOfMatches < static_cast<unsigned long>(numberOfSources))
+      {
+         ossimString key = ossimString(MIN_VALUE_PERCENT_KW) + ossimString::toString(i);
+         const char* value = kwl.find(prefix, key); 
+         if(value)
+         {
+            theMinValuePercentArray.push_back(ossimString(value).toDouble());
+            ++numberOfMatches;
+         }      
+         ++i;
+      }
+
+      numberOfMatches = 0;
+      i               = 0;
+      regExpression = ossimString("^(") + ossimString(prefix) + ossimString(MAX_VALUE_PERCENT_KW) + ossimString("[0-9]+)");
+      numberOfSources = kwl.getNumberOfSubstringKeys(regExpression);
+      while(numberOfMatches < static_cast<unsigned long>(numberOfSources))
+      {
+         ossimString key = ossimString(MAX_VALUE_PERCENT_KW) + ossimString::toString(i);
+         const char* value = kwl.find(prefix, key); 
+
+         if(value)
+         {
+            theMaxValuePercentArray.push_back(ossimString(value).toDouble());
+            ++numberOfMatches;
+         }      
+         ++i;
+      }
+
+      ossimString algorithm = kwl.find(prefix,
+                                       ALGORITHM_KW);
+      algorithm = algorithm.downcase();
+      theAlgorithm = OSSIM_HISTOGRAM_LINEAR_STRETCH_ALGORITHM;
+      if(algorithm != "")
+      {
+         if(algorithm.contains("linear"))
+         {
+           theAlgorithm = OSSIM_HISTOGRAM_LINEAR_STRETCH_ALGORITHM;
+         }
+      }
+   }
+   return true;
+}
+
+bool ossimMultiBandHistogramTileSource::saveState(ossimKeywordlist& kwl,
+                                           const char* prefix)const
+{
+   ossimImageSourceHistogramFilter::saveState(kwl, prefix);
+   ossim_int32 i = 0;
+
+   for(i = 0; i< (ossim_int32)theMinValuePercentArray.size();++i)
+   {
+      kwl.add(prefix,
+              ossimString(MIN_VALUE_PERCENT_KW) + ossimString::toString(i),
+              theMinValuePercentArray[i],
+              true);
+   }
+   for(i = 0; i< (ossim_int32)theMaxValuePercentArray.size();++i)
+   {
+      kwl.add(prefix,
+              ossimString(MAX_VALUE_PERCENT_KW) + ossimString::toString(i),
+              theMaxValuePercentArray[i],
+              true);
+   }
+   ossimString algorithmString;
+
+   switch(theAlgorithm)
+   {
+   case OSSIM_HISTOGRAM_LINEAR_STRETCH_ALGORITHM:
+   {
+      algorithmString = "linear_stretch";
+      break;
+   }
+   case OSSIM_HISTOGRAM_NO_ALGORITHM:
+   {
+      algorithmString = "none";
+      break;
+   }
+   default:
+   {
+      algorithmString = "none";
+      break;
+   }
+   }
+
+   kwl.add(prefix,
+           ALGORITHM_KW,
+           algorithmString.c_str(),
+           true);
+   
+   return true;
+}
+
+template <class T>
+ossimRefPtr<ossimImageData> ossimMultiBandHistogramTileSource::runLinearStretchAlgorithm(T dummyVariable,
+                                                                              ossimRefPtr<ossimImageData>& tile)
+{
+   if(!getHistogram())
+   {
+      return tile;
+   }
+
+   ossimMultiBandHistogram* histo    = getHistogram()->getMultiBandHistogram(theCurrentResLevel);
+   if(histo)
+   {
+      ossim_uint32 maxBands = ( (histo->getNumberOfBands() >
+                           tile->getNumberOfBands())?
+                          tile->getNumberOfBands():
+                          histo->getNumberOfBands());
+
+      long offsetUpperBound = tile->getHeight()*tile->getWidth();
+
+      for(ossim_uint32 band = 0; band < maxBands; ++band)
+      {
+         ossimHistogram* h  = histo->getHistogram(band);
+         
+         T* buf   = static_cast<T*>(tile->getBuf(band));
+         T np     = static_cast<T>(tile->getNullPix(band));
+         T minPix = static_cast<T>(tile->getMinPix(band));
+         T maxPix = static_cast<T>(tile->getMaxPix(band));
+         T range  = (maxPix - minPix);
+         if(h&&buf)
+         {
+            
+            double maxClip = minPix + (h->HighClipVal(theMaxValuePercentArray[band])/(double)h->GetRes())*range;
+            double minClip = minPix + (h->LowClipVal(theMinValuePercentArray[band])/(double)h->GetRes())*range;
+            double delta   = (maxClip - minClip);
+            
+            if(fabs(delta) > 0.0)
+            {
+               for(long offset = 0; offset < offsetUpperBound; ++offset)
+               {
+                  if(buf[offset] != np)
+                  {
+                     if(buf[offset] < minClip)
+                     {
+                        buf[offset] = minPix;
+                     }
+                     else if(buf[offset] > maxClip)
+                     {
+                        buf[offset] = maxPix;
+                     }
+                     else
+                     {
+                        T value = static_cast<T>(minPix + ((buf[offset] - minClip)/delta)*range);
+                        buf[offset] = value>maxPix?maxPix:value;
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+      tile->validate();
+   }
+   
+   return tile;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMultiBandHistogramTileSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMultiBandHistogramTileSource.h
new file mode 100644
index 0000000000..72e4b5bad5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimMultiBandHistogramTileSource.h
@@ -0,0 +1,103 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimMultiBandHistogramTileSource.h,v 1.4 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimMultiBandHistogramTileSource_HEADER
+#define ossimMultiBandHistogramTileSource_HEADER
+#include "ossimImageSourceHistogramFilter.h"
+#include <vector>
+class OSSIMDLLEXPORT ossimMultiBandHistogramTileSource : public ossimImageSourceHistogramFilter
+{
+public:
+   enum ossimMultiBandHistogramAlgorithm
+   {
+      OSSIM_HISTOGRAM_NO_ALGORITHM             = 0,
+      OSSIM_HISTOGRAM_LINEAR_STRETCH_ALGORITHM = 1
+   };
+   ossimMultiBandHistogramTileSource();
+   ossimMultiBandHistogramTileSource(double minValuePercent,
+                                  double maxValuePercent,
+                                  ossimImageSource* inputSource,
+                                  ossimMultiResLevelHistogram* histogram);
+   virtual ~ossimMultiBandHistogramTileSource();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual void setMinValuePercent(const std::vector<double>& arrayPercents)
+      {
+         theMinValuePercentArray = arrayPercents;
+      }
+   virtual void setMaxValuePercent(const std::vector<double>& arrayPercents)
+      {
+         theMaxValuePercentArray = arrayPercents;
+      }
+   virtual void setMinValuePercent(ossim_uint32 arrayIndex,
+                                   double minValue)
+      {
+         if(arrayIndex < theMinValuePercentArray.size())
+         {
+            theMinValuePercentArray[arrayIndex] = minValue;
+         }
+      }
+   virtual void setMaxValuePercent(ossim_uint32 arrayIndex,
+                                   double maxValue)
+      {
+         if(arrayIndex < theMaxValuePercentArray.size())
+         {
+            theMaxValuePercentArray[arrayIndex] = maxValue;
+         }
+      }
+   virtual double getMinValuePercent(ossim_uint32 arrayIndex)const
+      {
+         if(arrayIndex < theMinValuePercentArray.size())
+         {
+            return theMinValuePercentArray[arrayIndex];
+         }
+         return OSSIM_DBL_NAN;
+      }
+   virtual double getMaxValuePercent(ossim_uint32 arrayIndex)const
+      {
+         if(arrayIndex < theMaxValuePercentArray.size())
+         {
+            return theMaxValuePercentArray[arrayIndex];
+         }
+         return OSSIM_DBL_NAN;
+      }
+   virtual ossim_uint32 getNumberOfMinValues()const
+      {
+         return theMinValuePercentArray.size();
+      }
+   virtual ossim_uint32 getNumberOfMaxValues()const
+      {
+         return theMinValuePercentArray.size();
+      }
+   virtual void initialize();
+      
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+protected:
+
+   void allocate();
+   
+   ossimRefPtr<ossimImageData>      theTile;
+   ossimMultiBandHistogramAlgorithm theAlgorithm;
+   std::vector<double>              theMinValuePercentArray;
+   std::vector<double>              theMaxValuePercentArray;
+   
+   template <class T> ossimRefPtr<ossimImageData> runLinearStretchAlgorithm(
+      T dummyVariable,
+      ossimRefPtr<ossimImageData>& tile);
+
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimNBandToIndexFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimNBandToIndexFilter.cpp
new file mode 100644
index 0000000000..1155004034
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimNBandToIndexFilter.cpp
@@ -0,0 +1,551 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimNBandToIndexFilter.cpp,v 1.4 2005/11/09 14:31:23 gpotts Exp $
+
+#include <imaging/tile_sources/ossimNBandToIndexFilter.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/property/ossimFilenameProperty.h>
+#include <base/property/ossimBooleanProperty.h>
+#include <base/context/ossimNotifyContext.h>
+
+
+static const char* KEEP_QUANTIZED_VALUE_FLAG_KW = "keep_quantized_value_flag";
+
+RTTI_DEF1(ossimNBandToIndexFilter,
+          "ossimNBandToIndexFilter",
+          ossimImageSourceFilter);
+
+ossimNBandToIndexFilter::ossimNBandToIndexFilter()
+   :ossimImageSourceFilter(),
+    theLut(0),
+    theTile(0),
+    theKeepQuantizedValueFlag(false)
+{
+}
+
+ossimNBandToIndexFilter::~ossimNBandToIndexFilter()
+{
+}
+
+void ossimNBandToIndexFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   // Force allocate on next getTile.
+   theTile      = 0;
+   if(theLut.valid())
+   {
+      if(theKeepQuantizedValueFlag)
+      {
+         ossimNBandLutDataObject::LUT_ENTRY_TYPE minValue;
+         ossimNBandLutDataObject::LUT_ENTRY_TYPE maxValue;
+         ossim_uint32 bands = theLut->getNumberOfBands();
+         ossim_uint32 idx   = 0;
+         if(theMinValues.size() != bands)
+         {
+            theMinValues.resize(bands);
+            theMaxValues.resize(bands);
+            theNullValues.resize(bands);
+         }
+         std::fill(theNullValues.begin(),
+                   theNullValues.end(), 0);
+         for(idx = 0; idx < bands; ++idx)
+         {
+            theLut->getMinMax(idx, minValue, maxValue);
+            theMinValues[idx] = minValue;
+            theMaxValues[idx] = maxValue;
+            theNullValues[idx] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(ossimImageSourceFilter::getNullPixelValue(idx));
+         }
+      }
+      else
+      {
+         if(theMinValues.size() != 1)
+         {
+            theMinValues.resize(1);
+            theMaxValues.resize(1);
+            theNullValues.resize(1);
+         }
+         theMinValues[0]  = 0;
+         theMaxValues[0]  = theLut->getNumberOfEntries()-1;
+         theNullValues[0] = theLut->getNullPixelIndex();
+      }
+   }
+}
+
+void ossimNBandToIndexFilter::allocate()
+{
+   theTile      = 0;
+   
+   if(isSourceEnabled()&&theInputConnection)
+   {
+      theTile      = ossimImageDataFactory::instance()->create(this, this);
+      if(theTile.valid())
+      {
+         theTile->initialize();
+      }
+   }
+}
+
+void ossimNBandToIndexFilter::disableSource()
+{
+   ossimImageSourceFilter::disableSource();
+   theTile = 0;
+}
+
+ossimRefPtr<ossimImageData> ossimNBandToIndexFilter::getTile(const ossimIrect& origin,
+                                                             ossim_uint32 resLevel)
+{
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getTile(origin, resLevel);
+   }
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   if(!theTile.valid())
+   {
+      allocate();
+   }
+   
+   ossimRefPtr<ossimImageData> input = theInputConnection->getTile(origin,
+                                                                   resLevel);
+
+   if(!theTile.valid() || !input.valid())
+   {
+      return input;
+   }
+
+   theTile->setImageRectangle(origin);
+   theTile->setDataObjectStatus(OSSIM_FULL);
+   theTile->makeBlank();
+
+   return convertInputTile(input.get());
+}
+
+ossimRefPtr<ossimImageData> ossimNBandToIndexFilter::convertInputTile(ossimImageData* tile)
+{
+   switch(getOutputScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         return convertOutputTileTemplate((ossim_uint8)0,
+                                          tile);
+         break;
+      }
+      case OSSIM_UINT16:
+      {
+         return convertOutputTileTemplate((ossim_uint16)0,
+                                          tile);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         return convertOutputTileTemplate((ossim_uint32)0,
+                                         tile);
+         break;
+      }
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "ossimNBandToIndexFilter::convertInputTile: Unsupported scalar type for conversion" << std::endl;
+      }
+   }
+
+   return theTile;
+}
+
+template <class T>
+ossimRefPtr<ossimImageData> ossimNBandToIndexFilter::convertOutputTileTemplate(T outputDummy,
+                                                                               ossimImageData* inputTile)
+{
+   switch(inputTile->getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         return convertInputTileToOutputTemplate((ossim_uint8)0,
+                                                 outputDummy,
+                                                 inputTile);
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         return convertInputTileToOutputTemplate((ossim_sint8)0,
+                                                 outputDummy,
+                                                 inputTile);
+      }
+      case OSSIM_UINT16:
+      {
+         return convertInputTileToOutputTemplate((ossim_uint16)0,
+                                                 outputDummy,
+                                                 inputTile);
+      }
+      case OSSIM_SINT32:
+      {
+         return convertInputTileToOutputTemplate((ossim_sint32)0,
+                                                 outputDummy,
+                                                 inputTile);
+      }
+      case OSSIM_UINT32:
+      {
+         return convertInputTileToOutputTemplate((ossim_uint32)0,
+                                                 outputDummy,
+                                                 inputTile);
+      }
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "convertInputTileToOutputTemplate::convertOutputTileTemplate: Unsupported scalar type for conversion." << std::endl;
+      }
+   }
+
+   return theTile;
+}
+
+template <class T1, class T2>
+ossimRefPtr<ossimImageData> ossimNBandToIndexFilter::convertInputTileToOutputTemplate(T1 inputDummy,
+                                                                                      T2 outputDummy,
+                                                                                      ossimImageData* inputTile)
+{
+   if (!inputTile)
+   {
+      return theTile;
+   }
+   
+   const ossim_uint32 BANDS = inputTile->getNumberOfBands();
+
+   if (!BANDS)
+   {
+      return theTile;
+   }
+//   T2** outBand = (T2*)theTile->getBuf();
+
+   ossim_uint32 numberOfBands = theLut->getNumberOfBands();
+   
+   ossimNBandLutDataObject::LUT_ENTRY_TYPE* bandValues = new ossimNBandLutDataObject::LUT_ENTRY_TYPE[numberOfBands];
+
+   memset(bandValues, 0, sizeof(ossimNBandLutDataObject::LUT_ENTRY_TYPE)*numberOfBands);
+   numberOfBands = ossimMin(BANDS,
+                            numberOfBands);
+   if(!numberOfBands) return theTile;
+   T1** band = new T1*[numberOfBands];
+   T2** outBand = new T2*[numberOfBands];
+   ossim_int32 idx   = 0;
+
+   for(idx = 0; idx < (ossim_int32)numberOfBands; ++idx)
+   {
+      band[idx] = (T1*)inputTile->getBuf(idx);
+      outBand[idx] = (T2*)theTile->getBuf(idx);
+   }
+   if(band[0])
+   {
+      if(inputTile->getDataObjectStatus() == OSSIM_FULL)
+      {
+         ossim_uint32 upper = inputTile->getWidth()*inputTile->getHeight();
+         ossim_uint32 idx2=0;
+         for(ossim_uint32 offset = 0; offset < upper; ++offset)
+         {
+            for(idx2 = 0; idx2 < numberOfBands; ++idx2)
+            {
+               bandValues[idx2] = *band[idx2];
+               ++band[idx2];
+            }
+            idx = theLut->findIndex(bandValues);
+
+            if(!theKeepQuantizedValueFlag)
+            {
+               *outBand[0] = (T2)idx;
+               ++outBand[0];
+            }
+            else
+            {
+               for(idx2 = 0; idx2 < numberOfBands; ++idx2)
+               {
+                  if(idx >=0)
+                  {
+                     *outBand[idx2] = (T2)(*theLut)[idx][idx2];
+                     ++outBand[idx2];
+                  }
+               }
+            }
+         }
+      }
+      else if(inputTile->getDataObjectStatus() == OSSIM_PARTIAL)
+      {
+         ossim_uint32 upper = inputTile->getWidth()*inputTile->getHeight();
+         ossim_uint32 idx2=0;
+         for(ossim_uint32 offset = 0; offset < upper; ++offset)
+         {
+            for(idx2 = 0; idx2 < numberOfBands; ++idx2)
+            {
+               bandValues[idx2] = *band[idx2];
+               ++band[idx2];
+            }
+            idx = -1;
+            if(!inputTile->isNull(offset))
+            {
+               idx = theLut->findIndex(bandValues);
+            }
+            if(!theKeepQuantizedValueFlag)
+            {
+               if(idx>=0)
+               {
+                  *outBand[0] = (T2)idx;
+               }
+               ++outBand[0];
+            }
+            else
+            {
+               for(idx2 = 0; idx2 < numberOfBands; ++idx2)
+               {
+                  if(idx >=0)
+                  {
+                     if(idx>=0)
+                     {
+                        *outBand[idx2] = (T2)(*theLut)[idx][idx2];
+                     }
+                  }
+                  ++outBand[idx2];
+               }
+            }
+         }
+      }
+   }
+   if(theKeepQuantizedValueFlag)
+   {
+      theTile->validate();
+   }
+   else
+   {
+      theTile->setDataObjectStatus(OSSIM_FULL);
+   }
+   return theTile;
+}
+
+bool ossimNBandToIndexFilter::saveState(ossimKeywordlist& kwl,
+                                      const char* prefix)const
+{
+   ossimString newPrefix = prefix;
+   newPrefix = newPrefix + "lut.";
+
+   if(theLut.valid())
+   {
+      theLut->saveState(kwl, newPrefix.c_str());
+   }
+
+   kwl.add(prefix,
+           KEEP_QUANTIZED_VALUE_FLAG_KW,
+           theKeepQuantizedValueFlag?"true":"false",
+           true);
+           
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimNBandToIndexFilter::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   ossimString newPrefix = prefix;
+   newPrefix = newPrefix + "lut.";
+
+   if(!theLut.valid())
+   {
+      theLut = new ossimNBandLutDataObject;
+   }
+   theLut->loadState(kwl, newPrefix.c_str());
+
+   const char* flag = kwl.find(prefix, KEEP_QUANTIZED_VALUE_FLAG_KW);
+   if(flag)
+   {
+      theKeepQuantizedValueFlag = ossimString(flag).toBool();
+   }
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimNBandToIndexFilter::isSourceEnabled()const
+{
+   bool result = ossimSource::isSourceEnabled()&&theInputConnection;
+
+   // only support 3 band integral values, no floating point for now.
+   //
+   if(result)
+   {
+      
+      ossimScalarType inputScalarType = theInputConnection->getOutputScalarType();
+      if(!theLut.valid() ||
+         (theLut->getNumberOfEntries()<1)||
+         (inputScalarType==OSSIM_FLOAT32)||
+         (inputScalarType==OSSIM_FLOAT64)||
+         (theInputConnection->getNumberOfOutputBands()!=3))
+      {
+         result = false;
+      }
+   }
+   
+   return result;
+}
+
+ossim_uint32 ossimNBandToIndexFilter::getNumberOfOutputBands() const
+{
+   if(isSourceEnabled())
+   {
+      if(theKeepQuantizedValueFlag)
+      {
+         if(theLut.valid())
+         {
+            return theLut->getNumberOfBands();
+         }
+      }
+      else
+      {
+         return 1;
+      }
+   }
+   
+   return ossimImageSourceFilter::getNumberOfOutputBands();
+}
+   
+ossimScalarType ossimNBandToIndexFilter::getOutputScalarType() const
+{
+   if(isSourceEnabled())
+   {
+      
+      ossim_uint32 numberOfEntries = theLut->getNumberOfEntries();
+      
+      if(numberOfEntries < 257)
+      {
+         return OSSIM_UCHAR;
+      }
+      else if(numberOfEntries < 65537)
+      {
+         return OSSIM_UINT16;
+      }
+      else
+      {
+         return OSSIM_UINT32;
+      }
+   }
+   
+   return ossimImageSourceFilter::getOutputScalarType();
+}
+
+void ossimNBandToIndexFilter::setLut(ossimNBandLutDataObject& lut)
+{
+   theLut = new ossimNBandLutDataObject(lut);
+}
+
+double ossimNBandToIndexFilter::getNullPixelValue(ossim_uint32 band)const
+{
+   if(isSourceEnabled())
+   {
+      if(theLut->getNullPixelIndex() >= 0)
+      {
+         std::cout << "RETURNING NULL" << std::endl;
+         return theLut->getNullPixelIndex();
+      }
+   }
+   
+   return ossimImageSourceFilter::getNullPixelValue(band);
+}
+
+double ossimNBandToIndexFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   if(isSourceEnabled())
+   {
+      if(band < theMinValues.size())
+      {
+         return (double)theMinValues[band];
+      }
+   }
+//    if(isSourceEnabled())
+//    {
+//       if(getNullPixelValue() != 0)
+//       {
+//          return 0;
+//       }
+//       else
+//       {
+//          return 1;
+//       }
+//       return 0;
+//    }
+   
+   return ossimImageSourceFilter::getMinPixelValue();
+}
+
+double ossimNBandToIndexFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(isSourceEnabled())
+   {
+      if(band < theMaxValues.size())
+      {
+         return (double)theMaxValues[band];
+      }
+//       if(theLut->getNullPixelIndex() != ((ossim_int32)(theLut->getNumberOfEntries())-1))
+//       {
+//          return theLut->getNumberOfEntries();
+//       }
+//       else
+//       {
+//          return (theLut->getNumberOfEntries()-1);
+//       }
+   }
+   
+   return ossimImageSourceFilter::getMaxPixelValue();
+}
+
+void ossimNBandToIndexFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(property->getName() == ossimKeywordNames::FILENAME_KW)
+   {
+      ossimKeywordlist kwl;
+      if(kwl.addFile(ossimFilename(property->valueToString())))
+      {
+         theLut = new ossimNBandLutDataObject;
+         theLut->loadState(kwl);
+      }
+   }
+   else if(property->getName() == KEEP_QUANTIZED_VALUE_FLAG_KW)
+   {
+      theKeepQuantizedValueFlag = property->valueToString().toBool();
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimNBandToIndexFilter::getProperty(const ossimString& name)const
+{
+   if(name == ossimKeywordNames::FILENAME_KW)
+   {
+      ossimFilenameProperty* property = new ossimFilenameProperty(name, theLutFilename);
+      property->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      property->setCacheRefreshBit();
+      
+      return property;
+   }
+   else if(name == KEEP_QUANTIZED_VALUE_FLAG_KW)
+   {
+      ossimBooleanProperty* property = new ossimBooleanProperty(name, theKeepQuantizedValueFlag);
+      property->setCacheRefreshBit();
+
+      return property;
+   }
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimNBandToIndexFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+
+   propertyNames.push_back(ossimKeywordNames::FILENAME_KW);
+   propertyNames.push_back(KEEP_QUANTIZED_VALUE_FLAG_KW);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimNBandToIndexFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimNBandToIndexFilter.h
new file mode 100644
index 0000000000..4581952afa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimNBandToIndexFilter.h
@@ -0,0 +1,129 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimNBandToIndexFilter.h,v 1.3 2005/11/09 14:31:23 gpotts Exp $
+#ifndef ossimNBandToIndexFilter_HEADER
+#define ossimNBandToIndexFilter_HEADER
+#include <base/common/ossimNBandLutDataObject.h>
+#include <base/data_types/ossimFilename.h>
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <vector>
+
+class ossimImageData;
+
+/*!
+ * It will map the input data to an 8-bit index table.  The table
+ * <pre>
+ *
+ * Example keyword list:
+ *
+ * type:  ossimNBandToIndexFilter
+ *
+ * If you want to load from a file then just do:
+ *
+ * lut.filename: <full path to lut file>
+ *
+ * If you have the lut table in line then it must look like this:
+ *
+ * lut.entry0:  204 102 1
+ * lut.entry1:  255 204 153
+ * lut.entry2:  51 204 204
+ * lut.number_of_entries:  3
+ * lut.type:  ossimNBandLutDataObject
+ *
+ * </pre>
+ */
+class OSSIM_DLL ossimNBandToIndexFilter : public ossimImageSourceFilter
+{
+public:
+   /*!
+    * Initializes the min value to 0 and the max value to 4000.
+    */
+   ossimNBandToIndexFilter();
+   virtual ~ossimNBandToIndexFilter();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+   
+   virtual ossimScalarType getOutputScalarType() const;
+   
+   void setLut(ossimNBandLutDataObject& lut);
+
+   void setLut(const ossimFilename& file);
+
+   virtual bool isSourceEnabled()const;
+   virtual void disableSource();
+   
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   
+   virtual void initialize();
+
+   /*!
+    * Saves the state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0)const;
+
+   /*!
+    * Loads the state of this object.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+
+   /**
+    * Will set the property whose name matches the argument
+    * "property->getName()".
+    *
+    * @param property Object containing property to set.
+    */
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+
+   /**
+    * @param name Name of property to return.
+    * 
+    * @returns A pointer to a property object which matches "name".  Returns
+    * NULL if no match is found.
+    */
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+
+   /**
+    * Pushes this's names onto the list of property names.
+    *
+    * @param propertyNames array to add this's property names to.
+    */
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   
+protected:
+   void allocate();
+
+   
+   virtual ossimRefPtr<ossimImageData> convertInputTile(ossimImageData* inputTile);
+
+   template <class T> ossimRefPtr<ossimImageData> convertOutputTileTemplate(T inputDummy,
+                                                                            ossimImageData* inputTile);
+   template <class T1, class T2> ossimRefPtr<ossimImageData> convertInputTileToOutputTemplate(T1 inputDummy,
+                                                                                              T2 outputDummy,
+                                                                                              ossimImageData* inputTile);
+   
+   ossimRefPtr<ossimNBandLutDataObject> theLut;
+   ossimRefPtr<ossimImageData>          theTile;
+   ossimFilename                        theLutFilename;
+   bool                                 theKeepQuantizedValueFlag;
+   std::vector<ossimNBandLutDataObject::LUT_ENTRY_TYPE> theMinValues;
+   std::vector<ossimNBandLutDataObject::LUT_ENTRY_TYPE> theMaxValues;
+   std::vector<ossimNBandLutDataObject::LUT_ENTRY_TYPE> theNullValues;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimOrthoImageMosaic.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimOrthoImageMosaic.cpp
new file mode 100644
index 0000000000..1f36e5f70c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimOrthoImageMosaic.cpp
@@ -0,0 +1,416 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimOrthoImageMosaic.cpp,v 1.26 2005/05/12 01:19:54 dburken Exp $
+#include <imaging/tile_sources/ossimOrthoImageMosaic.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+
+
+static ossimTrace traceDebug ("ossimOrthoImageMosaic:debug");
+
+RTTI_DEF1(ossimOrthoImageMosaic, "ossimOrthoImageMosaic", ossimImageMosaic);
+
+ossimOrthoImageMosaic::ossimOrthoImageMosaic()
+   :ossimImageMosaic()
+{
+   theDelta.makeNan();
+   theUpperLeftTie.makeNan();
+}
+
+ossimOrthoImageMosaic::ossimOrthoImageMosaic(const std::vector<ossimImageSource*>& inputSources)
+   :ossimImageMosaic(inputSources)
+{
+   theDelta.makeNan();
+   theUpperLeftTie.makeNan();
+}
+
+ossimOrthoImageMosaic::~ossimOrthoImageMosaic()
+{
+}
+
+ossim_uint32 ossimOrthoImageMosaic::getNumberOfOverlappingImages(const ossimIrect& rect,
+                                                           ossim_uint32 resLevel)const
+{
+   ossim_uint32 result = 0;
+   for(ossim_uint32 i = 0; i < theInputTiePoints.size(); ++i)
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      getInput(i));
+      if(interface&&
+         !theInputTiePoints[i].hasNans())
+      {
+         ossimIrect tempRect = getRelativeRect(i, resLevel);
+
+         if(!tempRect.hasNans())
+         {
+            if(tempRect.intersects(rect))
+            {
+               ++result;
+            }
+         }
+      }
+   }
+   
+   return 0;
+}
+
+void ossimOrthoImageMosaic::getOverlappingImages(std::vector<ossim_uint32>& result,
+                                                 const ossimIrect& rect,
+                                                 ossim_uint32 resLevel)const
+{
+   result.clear();
+   for(ossim_uint32 i = 0; i < theInputTiePoints.size(); ++i)
+   {
+      ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                      getInput(i));
+      if(interface&&
+         !theInputTiePoints[i].hasNans())
+      {
+         ossimIrect tempRect = getRelativeRect(i, resLevel);
+
+         if(!tempRect.hasNans())
+         {
+            if(tempRect.intersects(rect))
+            {
+               result.push_back(i);
+            }
+         }
+      }
+   }
+}
+
+bool ossimOrthoImageMosaic::getImageGeometry(ossimKeywordlist& kwl,
+                                             const char* prefix)
+{
+   bool result = true;
+   ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                   getInput(0));
+   if(interface)
+   {
+      interface->getImageGeometry(kwl, prefix);
+      if(theUnits == "degrees")
+      {
+          kwl.add(prefix,
+                 ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+                 theDelta.y,
+                 true);
+          kwl.add(prefix,
+                 ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+                 theDelta.x,
+                  true);
+          kwl.add(prefix,
+                  ossimKeywordNames::TIE_POINT_LAT_KW,
+                  theUpperLeftTie.y,
+                  true);
+          kwl.add(prefix,
+                  ossimKeywordNames::TIE_POINT_LON_KW,
+                  theUpperLeftTie.x,
+                  true);
+          kwl.remove(prefix, ossimKeywordNames::TIE_POINT_EASTING_KW);
+          kwl.remove(prefix, ossimKeywordNames::TIE_POINT_NORTHING_KW);
+                 
+      }
+      else if(theUnits == "meters")
+      {
+          kwl.add(prefix,
+                 ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+                 theDelta.x,
+                 true);
+          kwl.add(prefix,
+                 ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+                 theDelta.x,
+                  true);
+          kwl.add(prefix,
+                  ossimKeywordNames::TIE_POINT_EASTING_KW,
+                  theUpperLeftTie.x,
+                  true);
+          kwl.add(prefix,
+                  ossimKeywordNames::TIE_POINT_NORTHING_KW,
+                  theUpperLeftTie.y,
+                  true);
+          kwl.remove(prefix, ossimKeywordNames::TIE_POINT_LAT_KW);
+          kwl.remove(prefix, ossimKeywordNames::TIE_POINT_LON_KW);
+      }
+      else
+      {
+         result = false;
+      }
+   }
+
+   return result;
+}
+
+ossimIrect ossimOrthoImageMosaic::getBoundingRect(ossim_uint32 resLevel) const
+{
+   ossimDpt decimation;
+
+   decimation.makeNan();
+
+   ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                   getInput(0));
+   if(interface)
+   {
+      interface->getDecimationFactor(resLevel,
+                                     decimation);
+   }
+   if(decimation.hasNans())
+   {
+      return theBoundingRect;
+   }
+   return theBoundingRect*decimation;
+}
+
+void ossimOrthoImageMosaic::initialize()
+{
+   theInputTiePoints.clear();
+   theDelta.makeNan();
+   theUpperLeftTie.makeNan();
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimOrthoImageMosaic::initialize() DEBUG: Entered..."
+         << "Number of inputs = " << getNumberOfInputs()
+         << std::endl;
+   }
+   if(getNumberOfInputs())
+   {
+      theInputTiePoints.resize(getNumberOfInputs());
+      for(ossim_uint32 i = 0; i < getNumberOfInputs(); ++i)
+      {
+         ossimImageSourceInterface *interface =
+            PTR_CAST(ossimImageSourceInterface, getInput(i));
+         theInputTiePoints[i].makeNan();
+         if(interface)
+         {
+            ossimKeywordlist kwl;
+
+            bool status = interface->getImageGeometry(kwl);
+            if(status)
+            {
+               ossimProjection* prj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+               ossimMapProjection* mapPrj = PTR_CAST(ossimMapProjection, prj);
+               if(mapPrj)
+               {
+                  if(!mapPrj->isGeographic())
+                  {
+                     theUnits = "meters";
+                     theDelta = mapPrj->getMetersPerPixel();
+                  }
+                  else
+                  {
+                     theUnits = "degrees";
+                     theDelta = mapPrj->getDecimalDegreesPerPixel();
+                  }
+                  if(theUnits == "degrees")
+                  {
+                     theInputTiePoints[i].x = mapPrj->getUlGpt().lond();
+                     theInputTiePoints[i].y = mapPrj->getUlGpt().latd();
+                  }
+                  else if(theUnits == "meters")
+                  {
+                     theInputTiePoints[i].x = mapPrj->getUlEastingNorthing().x;;
+                     theInputTiePoints[i].y = mapPrj->getUlEastingNorthing().y;
+                  }
+
+                  if(traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+                        << "tie points for input " << i << " = "
+                        << theInputTiePoints[i] << std::endl;
+                  }
+
+               }
+               if(prj)
+               {
+                  delete prj;
+                  prj = NULL;
+                  mapPrj = NULL;
+               }
+            }
+            if(!theInputTiePoints[i].hasNans())
+            {
+               if(theUpperLeftTie.hasNans())
+               {
+                  theUpperLeftTie = theInputTiePoints[i];
+               }
+               else if(!theInputTiePoints[i].hasNans())
+               {
+                  if(theUnits == "meters")
+                  {
+                     theUpperLeftTie.x = std::min(theUpperLeftTie.x, theInputTiePoints[i].x);
+                     theUpperLeftTie.y = std::max(theUpperLeftTie.y, theInputTiePoints[i].y);
+                  }
+                  else
+                  {
+                     theUpperLeftTie.lon = std::min(theUpperLeftTie.lon, theInputTiePoints[i].lon);
+                     theUpperLeftTie.lat = std::max(theUpperLeftTie.lat, theInputTiePoints[i].lat);
+                  }
+               }
+            }
+         }
+         else
+         {
+            theInputTiePoints[i].makeNan();
+//            CLOG << "Input " << i << " will not be used since no ortho information exists" << endl;
+         }
+      }
+   }
+
+   computeBoundingRect();
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "theUpperLeftTie = " << theUpperLeftTie << std::endl
+         << "delta per pixel = " << theDelta        << std::endl
+         << "bounding rect   = " << theBoundingRect << std::endl;
+   }
+   ossimImageMosaic::initialize();
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimOrthoImageMosaic::initialize() DEBUG: Leaving..." << std::endl;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimOrthoImageMosaic::getNextTile(
+   const ossimIrect& origin,
+   ossim_uint32 resLevel)
+{
+   const char *MODULE="ossimOrthoImageMosaic::getNextTile";
+   
+   ossim_int32 size = getNumberOfInputs();
+   
+   if((theCurrentIndex+1) >= size)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+   
+   ossimImageSourceInterface* temp = NULL;
+   ossimRefPtr<ossimImageData> result;
+   ossimDataObjectStatus status = OSSIM_NULL;
+   
+   do
+   {
+      ++theCurrentIndex;
+      temp = PTR_CAST(ossimImageSourceInterface, getInput(theCurrentIndex));
+      if(temp)
+      {
+         ossimIrect relRect = getRelativeRect(theCurrentIndex, resLevel);
+
+         if(traceDebug())
+         {
+            CLOG << "Rel rect for input " << theCurrentIndex
+                 << " = " << relRect
+                 << "\nRes level:  " << resLevel
+                 << endl;
+         }
+
+         if(origin.intersects(relRect))
+         {
+            // get the rect relative to the input rect
+            //
+            ossimIrect shiftedRect = origin + (ossimIpt(-relRect.ul().x,
+                                                        -relRect.ul().y));
+
+            // request that tile from the input space.
+            result = temp->getTile(shiftedRect, resLevel);
+
+            // now change the origin to the output origin.
+            if (result.valid())
+            {
+               result->setOrigin(origin.ul());
+               
+               status = result->getDataObjectStatus();
+
+               if((status == OSSIM_NULL)||(status == OSSIM_EMPTY))
+               {
+                  result = NULL;
+               }
+            }
+         }
+         else
+         {
+            result = NULL;
+         }
+      }
+      
+   } while(!result.valid() && (theCurrentIndex<size));
+
+   return result;
+}
+
+void ossimOrthoImageMosaic::computeBoundingRect(ossim_uint32 resLevel)
+{
+   const char* MODULE = "ossimOrthoImageMosaic::computeBoundingRect";
+   
+   theBoundingRect.makeNan();
+
+   for(ossim_uint32 i = 0; i < theInputTiePoints.size(); ++ i)
+   {
+      ossimIrect shiftedRect = getRelativeRect(i, resLevel);
+
+      if(traceDebug())
+      {
+         CLOG << "bounding rect for input " << (i+1)
+              << ":" << shiftedRect << endl;
+      }
+      if(!shiftedRect.hasNans())
+      {
+         if(theBoundingRect.hasNans())
+         {
+            theBoundingRect = shiftedRect;
+         }
+         else
+         {
+            theBoundingRect = theBoundingRect.combine(shiftedRect);
+         }
+      }
+   }
+}
+
+ossimIrect ossimOrthoImageMosaic::getRelativeRect(ossim_uint32 index,
+                                                  ossim_uint32 resLevel)const
+{
+   ossimIrect result;
+   ossimImageSourceInterface* interface = PTR_CAST(ossimImageSourceInterface,
+                                                   getInput(index));
+   result.makeNan();
+   if(interface&&
+      !theInputTiePoints[index].hasNans())
+   {
+      ossimIrect inputRect = interface->getBoundingRect();
+      result = inputRect;
+      
+      if(!inputRect.hasNans())
+      {
+         ossimDpt shift = (theInputTiePoints[index] - theUpperLeftTie);
+         
+         shift.x/= theDelta.x;
+         shift.y/=-theDelta.y;
+         
+	 result = result + shift;
+         if(!resLevel)
+         {
+            return result;
+         }
+ 	 ossimDpt decimation;
+ 	 interface->getDecimationFactor(resLevel, decimation);
+	 if(!decimation.hasNans())
+         {
+            result = result * decimation;
+         }
+      }
+   }
+   
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimOrthoImageMosaic.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimOrthoImageMosaic.h
new file mode 100644
index 0000000000..0e4f68e049
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimOrthoImageMosaic.h
@@ -0,0 +1,65 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimOrthoImageMosaic.h,v 1.7 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimOrthoImageMosaic_HEADER
+#define ossimOrthoImageMosaic_HEADER
+#include <imaging/tile_sources/ossimImageMosaic.h>
+
+class OSSIMDLLEXPORT ossimOrthoImageMosaic : public ossimImageMosaic
+{
+public:
+   ossimOrthoImageMosaic();
+   ossimOrthoImageMosaic(const std::vector<ossimImageSource*>& inputSources);
+   virtual ~ossimOrthoImageMosaic();   
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const;
+   virtual void initialize();
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=0);
+  /*!
+   * Used to retrieve the number of overlapping images withint the given
+   * rect.
+   */
+   virtual ossim_uint32 getNumberOfOverlappingImages(const ossimIrect& rect, ossim_uint32 resLevel=0)const;
+
+  /*!
+   * Used to populate the result with the index of the overlapping images.
+   */
+   virtual void getOverlappingImages(std::vector<ossim_uint32>& result,
+                                     const ossimIrect& rect,
+                                     ossim_uint32 resLevel=0)const;
+   
+   virtual ossimRefPtr<ossimImageData> getNextTile(const ossimIrect& origin,
+                                                   ossim_uint32 resLevel=0);
+   
+   ossimIrect getRelativeRect(ossim_uint32 index,
+                              ossim_uint32 resLevel = 0)const;
+protected:
+   std::vector<ossimDpt>  theInputTiePoints;
+   
+   /*!
+    * Holds R0 delta and will be scaled for different r-level requests
+    *
+    */
+   ossimDpt          theDelta;
+   
+   /*!
+    * Will hold the upper left tie of the mosaic.
+    */
+   ossimDpt          theUpperLeftTie;
+
+   ossimIrect        theBoundingRect;
+   ossimString       theUnits;
+   
+   void computeBoundingRect(ossim_uint32 resLevel=0);
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimPolyCutter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimPolyCutter.cpp
new file mode 100644
index 0000000000..3b3a61bf5f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimPolyCutter.cpp
@@ -0,0 +1,373 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimPolyCutter.cpp,v 1.28 2005/02/11 15:07:33 dburken Exp $
+#include <imaging/tile_sources/ossimPolyCutter.h>
+#include <base/data_types/ossimPolyArea2d.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageDataHelper.h>
+#include <base/common/ossimCommon.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/data_types/ossimActiveEdgeTable.h>
+
+static const char* NUMBER_POLYGONS_KW = "number_polygons";
+
+RTTI_DEF1(ossimPolyCutter, "ossimPolyCutter", ossimImageSourceFilter)
+
+ossimPolyCutter::ossimPolyCutter()
+   : ossimImageSourceFilter(),
+     theTile(NULL),
+     theCutType(OSSIM_POLY_NULL_OUTSIDE)
+{
+   thePolygonList.push_back(ossimPolygon());
+   theBoundingRect.makeNan();
+}
+
+// ossimPolyCutter::ossimPolyCutter(ossimImageSource* inputSource,
+//                                  ossimPolyArea2d* polygon)
+ossimPolyCutter::ossimPolyCutter(ossimImageSource* inputSource,
+                                 const ossimPolygon& polygon)
+   : ossimImageSourceFilter(inputSource),
+     theTile(NULL),
+     theCutType(OSSIM_POLY_NULL_INSIDE)
+{
+   thePolygonList.push_back(polygon);
+   computeBoundingRect();
+   initialize();
+}
+
+ossimPolyCutter::~ossimPolyCutter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimPolyCutter::getTile(const ossimIrect& tileRect,
+                                                     ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return theTile;
+   }
+   ossimRefPtr<ossimImageData> input = theInputConnection->getTile(tileRect,
+                                                                   resLevel);
+   
+   if(!isSourceEnabled() || theBoundingRect.hasNans() || !input.valid())
+   {
+      return input;
+   }
+   
+   if((input->getDataObjectStatus() == OSSIM_EMPTY) ||
+      (input->getDataObjectStatus() == OSSIM_NULL))
+   {
+      return input;
+   }
+
+   if(!theTile.valid())
+   {
+      allocate(); // First time through...
+   }
+
+   if(!theTile.valid())
+   {
+      return input;
+   }
+   
+   theTile->setImageRectangle(tileRect);
+   
+   theTile->loadTile(input.get());
+   theTile->setDataObjectStatus(input->getDataObjectStatus());
+   vector<ossimPolygon>* polyList = &thePolygonList;
+   vector<ossimPolygon>  scaledPoly;
+   
+   ossimIrect boundingRect = getBoundingRect(resLevel);
+   if(resLevel)
+   {
+      ossimDpt decimation;
+      getDecimationFactor(resLevel, decimation);
+
+      if(!decimation.hasNans())
+      {
+         for(int polyIndex = 0;
+             polyIndex < (int)thePolygonList.size();
+             ++polyIndex)
+         {
+            scaledPoly.push_back(thePolygonList[polyIndex]*decimation);
+         }
+         polyList = &scaledPoly;
+      }
+   }
+   
+   if(polyList->size()&&
+      theTile->getDataObjectStatus()!=OSSIM_NULL)
+   {
+      ossimActiveEdgeTable aet;
+      
+      
+      if((theCutType == OSSIM_POLY_NULL_OUTSIDE))
+      {
+         if(boundingRect.intersects(tileRect))
+         {
+            theTile->makeBlank();
+            ossimImageDataHelper helper(theTile.get());
+            for(int polyIndex = 0; polyIndex < (int)thePolygonList.size(); ++polyIndex)
+            {
+               helper.copyInputToThis(input->getBuf(),
+                                      (*polyList)[polyIndex]);
+            }
+            theTile->validate();
+         }
+         else
+         {
+            theTile->makeBlank();
+         }
+      }
+      else if(theCutType == OSSIM_POLY_NULL_INSIDE)
+      {
+         if(boundingRect.intersects(tileRect))
+         {
+            ossimImageDataHelper helper(theTile.get());
+            for(int polyIndex = 0;
+                polyIndex < (int)thePolygonList.size();
+                ++polyIndex)
+            {
+               helper.fill(theTile->getNullPix(),
+                           (*polyList)[polyIndex]);
+            }
+         }
+         theTile->validate();
+      }
+      
+   }
+   
+   return theTile;
+}
+
+ossimIrect ossimPolyCutter::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimIrect result;
+
+   result.makeNan();
+   if(!theInputConnection)
+   {
+      return result;
+   }
+   if(!isSourceEnabled())
+   {
+      return ossimImageSourceFilter::getBoundingRect(resLevel);
+   }
+   
+   result = theInputConnection->getBoundingRect(resLevel);
+
+   if(isSourceEnabled()&&(!theBoundingRect.hasNans()))
+   {
+      if(theCutType == OSSIM_POLY_NULL_OUTSIDE)
+      {
+         ossimDpt decimation;
+         getDecimationFactor(resLevel, decimation);
+         if(decimation.hasNans())
+         {
+            result =  theBoundingRect;
+         }
+         else
+         {
+            result = theBoundingRect*decimation;
+         }
+      }
+   }
+   return result;
+}
+
+void ossimPolyCutter::initialize()
+{
+   // Capture the input connection.
+   ossimImageSourceFilter::initialize();
+
+   // Force an allocate on next getTile.
+   theTile = NULL;
+}
+
+void ossimPolyCutter::allocate()
+{
+   theTile=NULL;
+   if(theInputConnection)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,
+                                                          theInputConnection);
+      theTile->initialize();
+
+   }
+}
+
+bool ossimPolyCutter::saveState(ossimKeywordlist& kwl,
+                                const char* prefix)const
+{
+   ossimString newPrefix = prefix;
+
+   for(int i = 0; i < (int)thePolygonList.size();++i)
+   {
+      newPrefix = ossimString(prefix) + "polygon" + ossimString::toString(i)+".";
+
+      thePolygonList[i].saveState(kwl, newPrefix.c_str());
+   }
+   kwl.add(prefix,
+           NUMBER_POLYGONS_KW,
+           (int)thePolygonList.size(),
+           true);
+   
+   ossimString fillType = "null_inside";
+   if(theCutType == OSSIM_POLY_NULL_OUTSIDE)
+   {
+      fillType = "null_outside";
+   }
+   kwl.add(prefix,
+           "cut_type",
+           fillType.c_str(),
+           true);   
+  
+   return ossimImageSourceFilter::saveState(kwl, prefix);;
+}
+
+bool ossimPolyCutter::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   const char* numberPolygons = kwl.find(prefix, NUMBER_POLYGONS_KW);
+
+   ossimString newPrefix;
+   if(numberPolygons)
+   {
+      thePolygonList.clear();
+      int npolys = ossimString(numberPolygons).toLong();
+      for(int i = 0; i < npolys;++i)
+      {
+         thePolygonList.push_back(ossimPolygon());
+         
+         newPrefix = ossimString(prefix) + "polygon" + ossimString::toString(i)+".";
+         
+         thePolygonList[i].loadState(kwl, newPrefix.c_str());
+      }
+   }
+
+   const char* lookup = kwl.find(prefix,
+                                 "cut_type");
+   if(lookup)
+   {
+      theCutType = OSSIM_POLY_NULL_INSIDE;
+      ossimString test = lookup;
+      if(test == "null_outside")
+      {
+         theCutType = OSSIM_POLY_NULL_OUTSIDE;
+      }
+   }
+   else
+   {
+      theCutType = OSSIM_POLY_NULL_OUTSIDE;
+   }
+
+   computeBoundingRect();
+
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+
+void ossimPolyCutter::setPolygon(const vector<ossimDpt>& polygon,
+                                 ossim_uint32 index)
+{
+   if(index < polygon.size())
+   {
+      thePolygonList[index] = polygon;
+
+      computeBoundingRect();
+   }
+
+}
+
+void ossimPolyCutter::setPolygon(const vector<ossimIpt>& polygon,
+                                 ossim_uint32 index)
+{
+   if(polygon.size())
+   {
+      thePolygonList[index] = polygon;
+      computeBoundingRect();
+   }
+}
+
+void ossimPolyCutter::addPolygon(const vector<ossimIpt>& polygon)
+{
+   thePolygonList.push_back(ossimPolygon(polygon));
+   computeBoundingRect();
+}
+
+void ossimPolyCutter::addPolygon(const vector<ossimDpt>& polygon)
+{
+   thePolygonList.push_back(ossimPolygon(polygon));
+   computeBoundingRect();
+}
+
+void ossimPolyCutter::addPolygon(const ossimPolygon& polygon)
+{
+   thePolygonList.push_back(ossimPolygon(polygon));
+   computeBoundingRect();
+}
+
+
+void ossimPolyCutter::setCutType(ossimPolyCutterCutType cutType)
+{
+   theCutType = cutType;
+}
+
+ossimPolyCutter::ossimPolyCutterCutType ossimPolyCutter::getCutType()const
+{
+   return theCutType;
+}
+
+void ossimPolyCutter::computeBoundingRect()
+{
+   ossimIrect bounds;
+   theBoundingRect.makeNan();
+   
+   for(int i = 0; i < (int)thePolygonList.size(); ++i)
+   {
+      thePolygonList[i].getBoundingRect(bounds);
+
+      if(!bounds.hasNans())
+      {
+         if(theBoundingRect.hasNans())
+         {
+            theBoundingRect = bounds;
+         }
+         else
+         {
+            theBoundingRect = theBoundingRect.combine(bounds);
+         }
+      }
+   }
+}
+void ossimPolyCutter::setNumberOfPolygons(ossim_uint32 count)
+{
+   if(!count)
+   {
+      thePolygonList.clear();
+   }
+   else
+   {
+      thePolygonList.resize(count);
+   }
+}
+
+std::vector<ossimPolygon>& ossimPolyCutter::getPolygonList()
+{
+   return thePolygonList;
+}
+
+const std::vector<ossimPolygon>& ossimPolyCutter::getPolygonList()const
+{
+   return thePolygonList;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimPolyCutter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimPolyCutter.h
new file mode 100644
index 0000000000..b7cd9a6801
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimPolyCutter.h
@@ -0,0 +1,96 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimPolyCutter.h,v 1.15 2005/04/05 18:48:29 gpotts Exp $
+#ifndef ossimPolyCutter_HEADER
+#define ossimPolyCutter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <base/data_types/ossimPolygon.h>
+#include <vector>
+
+//class ossimPolyArea2d;
+class ossimImageData;
+
+class OSSIMDLLEXPORT ossimPolyCutter : public ossimImageSourceFilter
+{
+public:
+   enum ossimPolyCutterCutType
+   {
+      OSSIM_POLY_NULL_INSIDE  = 0,
+      OSSIM_POLY_NULL_OUTSIDE = 1
+   };
+   
+   ossimPolyCutter();
+    ossimPolyCutter(ossimImageSource* inputSource,
+                    const ossimPolygon& polygon);
+   virtual ~ossimPolyCutter();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+
+   virtual void initialize();
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual void setPolygon(const vector<ossimDpt>& polygon,
+                           ossim_uint32 i = 0);
+   
+   virtual void setPolygon(const vector<ossimIpt>& polygon,
+                           ossim_uint32 i = 0);
+   
+   virtual void addPolygon(const vector<ossimIpt>& polygon);
+   virtual void addPolygon(const vector<ossimDpt>& polygon);
+   virtual void addPolygon(const ossimPolygon& polygon);
+   
+   virtual void setNumberOfPolygons(ossim_uint32 count);
+   
+   virtual std::vector<ossimPolygon>& getPolygonList();
+
+   virtual const std::vector<ossimPolygon>& getPolygonList()const;
+   
+   void setCutType(ossimPolyCutterCutType cutType);
+   
+   ossimPolyCutterCutType getCutType()const;
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+
+   ossimRefPtr<ossimImageData> theTile;
+
+   /*!
+    * Will hold a pre-computed bounding rect of the
+    * polygon data.
+    */
+   ossimIrect theBoundingRect;
+
+   std::vector<ossimPolygon> thePolygonList;
+
+   /*!
+    * theDefault fill will be outside.
+    */
+   ossimPolyCutterCutType theCutType;
+
+   void computeBoundingRect();
+
+TYPE_DATA  
+};
+#endif /* #ifndef ossimPolyCutter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRLevelFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRLevelFilter.cpp
new file mode 100644
index 0000000000..ec5352a8ba
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRLevelFilter.cpp
@@ -0,0 +1,265 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRLevelFilter.cpp,v 1.14 2005/12/25 17:14:57 dburken Exp $
+#include <imaging/tile_sources/ossimRLevelFilter.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/common/ossimTrace.h>
+
+static const char* CURRENT_RLEVEL_KW    = "current_rlevel";
+static const char* OVERRIDE_GEOMETRY_KW = "override_geometry";
+
+static ossimTrace traceDebug("ossimRLevelFilter:debug");
+
+RTTI_DEF1(ossimRLevelFilter, "ossimRLevelFilter", ossimImageSourceFilter);
+
+ossimRLevelFilter::ossimRLevelFilter(ossimObject* owner,
+                                     ossimImageSource* inputSource,
+                                     ossim_uint32 resLevel,
+                                     bool overrideGeometry)
+      : ossimImageSourceFilter(owner),
+        theCurrentRLevel(resLevel),
+        theOverrideGeometryFlag(overrideGeometry)
+{
+}
+
+ossimRLevelFilter::ossimRLevelFilter(ossimImageSource* inputSource,
+                                     ossim_uint32 resLevel,
+                                     bool overrideGeometry)
+      : ossimImageSourceFilter(NULL, inputSource),
+        theCurrentRLevel(resLevel),
+        theOverrideGeometryFlag(overrideGeometry)
+{
+}
+
+ossimRLevelFilter::~ossimRLevelFilter()
+{
+}
+
+void ossimRLevelFilter::getDecimationFactor(ossim_uint32 resLevel,
+                                            ossimDpt& result) const
+{
+   if(!theInputConnection)
+   {
+      result.makeNan();
+   }
+
+   theInputConnection->getDecimationFactor(resLevel,
+                                           result);
+}
+
+bool ossimRLevelFilter::getOverrideGeometryFlag() const
+{
+   return theOverrideGeometryFlag;
+}
+
+void ossimRLevelFilter::setOverrideGeometryFlag(bool override)
+{
+   theOverrideGeometryFlag = override;
+}
+
+void ossimRLevelFilter::setCurrentRLevel(ossim_uint32 rlevel)
+{
+   theCurrentRLevel = rlevel;
+}
+
+ossim_uint32 ossimRLevelFilter::getCurrentRLevel()const
+{
+   return theCurrentRLevel;
+}
+
+bool ossimRLevelFilter::getImageGeometry(ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   if (!theInputConnection)
+   {
+      return false;
+   }
+
+   ossim_uint32 rlevel = getCurrentRLevel();
+   bool status = theInputConnection->getImageGeometry(kwl, prefix);
+
+   if (!theOverrideGeometryFlag || (status == false) ||
+       (rlevel == 0) || (getEnableFlag() == false) )
+   {
+      return status;
+   }
+
+   ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->
+      createProjection(kwl);
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj);;
+   if(mapProj)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimRLevelFilter::getImageGeometry DEBUG:"
+            << "\nOriginal projection:\n";
+         mapProj->print(ossimNotify(ossimNotifyLevel_DEBUG));
+      }
+
+      //---
+      // We must adjust both the scale and the tie point to account for
+      // decimation.
+      //---
+      ossimDpt summed_decimation;
+      getSummedDecimation(summed_decimation);
+      if (!summed_decimation.hasNans())
+      {
+         if (mapProj->isGeographic())
+         {
+            // Adjust the upper left geographic tie point.
+            ossimDpt degPerPix = mapProj->getDecimalDegreesPerPixel();
+            ossimGpt ulGpt     = mapProj->getUlGpt();
+            ulGpt.lat         -= degPerPix.lat * summed_decimation.lat;
+            ulGpt.lon         += degPerPix.lon * summed_decimation.lon;
+            mapProj->setUlGpt(ulGpt);
+         }
+         else
+         {
+            // Adjust the upper left easting northing tie point.
+            ossimDpt meterPerPix = mapProj->getMetersPerPixel();
+            ossimDpt ulEnPt      = mapProj->getUlEastingNorthing();
+            ulEnPt.y            -= meterPerPix.y * summed_decimation.y;
+            ulEnPt.x            += meterPerPix.x * summed_decimation.x;
+            mapProj->setUlEastingNorthing(ulEnPt);
+         }
+      }
+
+      // Apply the scale.
+      ossimDpt decimation;
+      getDecimationFactor(rlevel, decimation);
+      decimation.x = 1.0/decimation.x;
+      decimation.y = 1.0/decimation.y;
+      mapProj->applyScale(decimation, true);
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimRLevelFilter::getImageGeometry DEBUG:"
+            << "\nUpdated projection:\n";
+         mapProj->print(ossimNotify(ossimNotifyLevel_DEBUG));
+      }
+
+      // Save off the changes back to the keyword list.
+      mapProj->saveState(kwl, prefix);
+
+      return true;
+
+   } // End of "if(mapProj))"
+
+   return status;
+}
+
+void ossimRLevelFilter::getSummedDecimation(ossimDpt& result) const
+{
+   // Start with fresh values.
+   result.x = 0.0;
+   result.y = 0.0;
+
+   ossim_uint32 rlevel = getCurrentRLevel();
+
+   if (rlevel == 0)
+   {
+      return; // no decimation.
+   }
+
+   // Sum the decimations from rlevel one to the current rlevel.
+   for (ossim_uint32 i = 1; i <= rlevel; ++i)
+   {
+      ossimDpt dpt;
+      getDecimationFactor(i, dpt);
+      if (dpt.hasNans())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimRLevelFilter::getSummedDecimation WARNING:"
+            << "\nNans returned from getDecimationFactor!"
+            << std::endl;
+         result.makeNan();
+         return;
+      }
+      result.x += dpt.x;
+      result.y += dpt.y;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimRLevelFilter::getSummedDecimation result: " << result
+         << std::endl;
+   }
+}
+
+ossimIrect ossimRLevelFilter::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimIrect rect;
+   rect.makeNan();
+   if(!theInputConnection) return rect;
+
+   if (isSourceEnabled())
+   {
+      return theInputConnection->getBoundingRect(theCurrentRLevel);
+   }
+   return theInputConnection->getBoundingRect(resLevel);
+}
+
+ossimRefPtr<ossimImageData> ossimRLevelFilter::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;
+   }
+
+   if(!isSourceEnabled())
+   {
+      return theInputConnection->getTile(tileRect, resLevel);
+   }
+
+   // Ignoring resLevel as we're in charge of it here!
+   return theInputConnection->getTile(tileRect, theCurrentRLevel);
+}
+
+bool ossimRLevelFilter::loadState(const ossimKeywordlist& kwl,
+                                  const char* prefix)
+{
+   const char* current  = kwl.find(prefix, CURRENT_RLEVEL_KW);
+   const char* override = kwl.find(prefix, OVERRIDE_GEOMETRY_KW);
+
+   if(current)
+   {
+      theCurrentRLevel = ossimString(current).toULong();
+   }
+
+   if(override)
+   {
+      theOverrideGeometryFlag = ossimString(override).toBool();
+   }
+
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimRLevelFilter::saveState(ossimKeywordlist& kwl,
+                                  const char* prefix)const
+{
+   kwl.add(prefix,
+           CURRENT_RLEVEL_KW,
+           theCurrentRLevel,
+           true);
+
+   kwl.add(prefix,
+           OVERRIDE_GEOMETRY_KW,
+           (ossim_uint32)theOverrideGeometryFlag,
+           true);
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRLevelFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRLevelFilter.h
new file mode 100644
index 0000000000..970d46b7b8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRLevelFilter.h
@@ -0,0 +1,84 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRLevelFilter.h,v 1.9 2005/02/11 15:07:33 dburken Exp $
+#ifndef ossimRLevelFilter_HEADER
+#define ossimRLevelFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+/*!
+ * This filter is used to adjust the RLevel.  If you would like to
+ * continually change between RLevels or Reslolutions then you can use this
+ * filter to do so.  You can also specify whether or not the rLevel
+ * passed in from the getTile request is added to this classes current
+ * Rlevel.  This is so if you concatenate multiple filters that reduce
+ * the RLevels then it will keep reducing.  For example if I have
+ * 2 filters that both go to RLevel 1 then it actually will go to
+ * 2 since there are 2 decimations happening.  This can be turned off
+ * by specifying the Rlevel not to be additive.
+ */
+class OSSIMDLLEXPORT ossimRLevelFilter : public ossimImageSourceFilter
+{
+public:
+
+   ossimRLevelFilter(ossimObject* owner,
+                     ossimImageSource* inputSource = NULL,
+                     ossim_uint32 resLevel         = 0,
+                     bool   overrideGeometry       = false);
+
+   ossimRLevelFilter(ossimImageSource* inputSource = NULL,
+                     ossim_uint32 resLevel         = 0,
+                     bool   overrideGeometry       = false);
+
+   virtual ~ossimRLevelFilter();
+
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result)const;
+
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix=NULL);
+
+   virtual void setCurrentRLevel(ossim_uint32 rlevel);
+
+   virtual ossim_uint32 getCurrentRLevel()const;
+
+   /*!
+    * Get/set of the data member "theOverrideGeometryFlag".
+    * If set this will override the "getImageGeometry" method and adjust
+    * the getMetersPerPixel or the getDecimalDegreesPerPixel.
+    * Default behavior is to not override method.
+    */
+   virtual bool getOverrideGeometryFlag() const;
+   virtual void setOverrideGeometryFlag(bool override);
+
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const;
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+protected:
+   /*!
+    * Initializes result with the sum of decimations from rlevel one to
+    * theCurrentRLevel.
+    */
+   void getSummedDecimation(ossimDpt& result) const;
+   
+   ossim_uint32 theCurrentRLevel;
+   bool         theOverrideGeometryFlag;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRectangleCutFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRectangleCutFilter.cpp
new file mode 100644
index 0000000000..1d018a6bfc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRectangleCutFilter.cpp
@@ -0,0 +1,295 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRectangleCutFilter.cpp,v 1.21 2005/09/15 12:28:44 gpotts Exp $
+#include <imaging/tile_sources/ossimRectangleCutFilter.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+static ossimTrace traceDebug("ossimRectangleCutFilter:debug");
+
+RTTI_DEF1(ossimRectangleCutFilter,
+          "ossimRectangleCutFilter",
+          ossimImageSourceFilter);
+
+ossimRectangleCutFilter::ossimRectangleCutFilter(ossimObject* owner,
+                                     ossimImageSource* inputSource)
+   :ossimImageSourceFilter(owner, inputSource),
+    theCutType(OSSIM_RECTANGLE_NULL_OUTSIDE)
+{
+   theRectangle.makeNan();
+}
+
+ossimRectangleCutFilter::ossimRectangleCutFilter(ossimImageSource* inputSource)
+   :ossimImageSourceFilter(NULL, inputSource),
+    theCutType(OSSIM_RECTANGLE_NULL_OUTSIDE)
+{
+   theRectangle.makeNan();
+}
+
+
+ossimRefPtr<ossimImageData> ossimRectangleCutFilter::getTile(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;
+   }
+   
+   ossimRefPtr<ossimImageData> tile =
+      theInputConnection->getTile(rect, resLevel);
+   if(!isSourceEnabled()||theRectangle.hasNans()||!tile.valid())
+   {
+      return tile;
+   }
+   if(tile->getDataObjectStatus() == OSSIM_NULL ||
+      tile->getDataObjectStatus() == OSSIM_EMPTY)
+   {
+      return tile;
+   }
+   ossim_int32 decimationIndex = min((ossim_int32)resLevel,
+                                     (ossim_int32)theDecimationList.size()-1);
+
+   ossimIrect cutRect = theRectangle*theDecimationList[decimationIndex];
+   
+   ossimIrect inputRectangle = tile->getImageRectangle();
+   if(theCutType==OSSIM_RECTANGLE_NULL_INSIDE)
+   {
+      if(cutRect.intersects(inputRectangle))
+      {
+         if(!inputRectangle.completely_within(cutRect))
+         {
+            ossim_int32 ulx = inputRectangle.ul().x;
+            ossim_int32 uly = inputRectangle.ul().y;
+            ossim_int32 w   = tile->getWidth();
+            ossim_int32 h   = tile->getHeight();
+            ossim_int32 offset = 0;
+            ossimIpt tempPoint(ulx, uly);
+            
+            for(ossim_int32 y = 0;  y < h; ++tempPoint.y,++y)
+            {
+               tempPoint.x = ulx;
+               for(ossim_int32 x = 0; x < w; ++tempPoint.x,++x)
+               {
+                  if(cutRect.pointWithin(tempPoint))
+                  {
+                     tile->setNull(offset);
+                  }
+                  ++offset;
+               }
+            }
+            tile->validate();
+         }
+         else
+         {
+            tile->makeBlank();
+         }
+      }
+   }
+   else // cut out the outide
+   {      
+      if(cutRect.intersects(inputRectangle))
+      {
+         if(!inputRectangle.completely_within(cutRect))
+         {
+            ossim_int32 ulx = inputRectangle.ul().x;
+            ossim_int32 uly = inputRectangle.ul().y;
+            ossim_int32 w   = tile->getWidth();
+            ossim_int32 h   = tile->getHeight();
+            ossim_int32 offset = 0;
+            ossimIpt tempPoint(ulx, uly);
+            
+            for(ossim_int32 y = 0;  y < h; ++tempPoint.y,++y)
+            {
+               tempPoint.x = ulx;
+               for(ossim_int32 x = 0; x < w; ++tempPoint.x,++x)
+               {
+                  if(!cutRect.pointWithin(tempPoint))
+                  {
+                     tile->setNull(offset);
+                  }
+                  ++offset;
+               }
+            }
+            tile->validate();
+         }
+      }
+      else
+      {
+         tile->makeBlank();
+      }
+   }
+   
+   return tile;
+}
+
+void ossimRectangleCutFilter::setRectangle(const ossimIrect& rect)
+{
+   theRectangle = rect;
+
+   if(theRectangle.hasNans())
+   {
+      if(theInputConnection)
+      {
+         theRectangle = theInputConnection->getBoundingRect();
+      }
+   }
+}
+
+void ossimRectangleCutFilter::getValidImageVertices(
+   vector<ossimIpt>& validVertices,
+   ossimVertexOrdering ordering,
+   ossim_uint32 resLevel)const
+{
+   ossimIrect rect = getBoundingRect();
+
+   if(ordering == OSSIM_CLOCKWISE_ORDER)
+   {
+      validVertices.push_back(rect.ul());
+      validVertices.push_back(rect.ur());
+      validVertices.push_back(rect.lr());
+      validVertices.push_back(rect.ll());
+   }
+   else
+   {
+      validVertices.push_back(rect.ul());
+      validVertices.push_back(rect.ll());
+      validVertices.push_back(rect.lr());
+      validVertices.push_back(rect.ur());
+   }
+}
+
+ossimIrect ossimRectangleCutFilter::getBoundingRect(ossim_uint32 resLevel)const
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRectangleCutFilter::getBoundingRect DEBUG: entered..." << std::endl;
+   }
+   ossimIrect result;
+
+   result.makeNan();
+   if(!theInputConnection)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRectangleCutFilter::getBoundingRect DEBUG: Input connection was not valid so leaving" << std::endl;
+      }
+      return result;
+   }
+
+   result = theInputConnection->getBoundingRect(resLevel);
+   if(isSourceEnabled())
+   {
+      if(theCutType == OSSIM_RECTANGLE_NULL_OUTSIDE)
+      {
+         ossimDpt decimation;
+         getDecimationFactor(resLevel, decimation);
+         ossimIrect cutRect = theRectangle;
+         if(!decimation.hasNans())
+         {
+            cutRect = theRectangle*decimation;
+         }
+         result = cutRect;
+      }
+   }
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRectangleCutFilter::getBoundingRect DEBUG: cut rect = " << result  << std::endl;
+   }
+   return result;
+}
+
+void ossimRectangleCutFilter::initialize()
+{
+   theDecimationList.clear();
+   if(theInputConnection)
+   {
+      getDecimationFactors(theDecimationList);
+   }
+   if(theDecimationList.empty())
+   {
+      theDecimationList.push_back(ossimDpt(1,1));
+   }
+   if(theRectangle.hasNans())
+   {
+      setRectangle(theRectangle);
+   }
+}
+
+bool ossimRectangleCutFilter::saveState(ossimKeywordlist& kwl,
+                                        const char* prefix)const
+{
+   ossimString newPrefix = prefix;
+   newPrefix+="clip_rect.";
+   
+   theRectangle.saveState(kwl, newPrefix);
+
+   if(theCutType == OSSIM_RECTANGLE_NULL_INSIDE)
+   {
+      kwl.add(prefix,
+              "cut_type",
+              "null_inside",
+              true);
+   }
+   else if(theCutType == OSSIM_RECTANGLE_NULL_OUTSIDE)
+   {
+      kwl.add(prefix,
+              "cut_type",
+              "null_outside",
+              true);      
+   }
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimRectangleCutFilter::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   ossimString newPrefix = prefix;
+   newPrefix+="clip_rect.";
+
+   theRectangle.loadState(kwl, newPrefix.c_str());
+   const char* cutType = kwl.find(prefix, "cut_type");
+   if(cutType)
+   {
+      ossimString c = cutType;
+      if(c == "null_inside")
+      {
+         theCutType = OSSIM_RECTANGLE_NULL_INSIDE;
+      }
+      else if(c == "null_outside")
+      {
+         theCutType = OSSIM_RECTANGLE_NULL_OUTSIDE;         
+      }
+      else
+      {
+         theCutType = static_cast<ossimRectangleCutType>(ossimString(cutType).toLong());
+      }
+   }
+
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+const ossimIrect& ossimRectangleCutFilter::getRectangle()const
+{
+   return theRectangle;
+}
+
+ossimRectangleCutFilter::ossimRectangleCutType ossimRectangleCutFilter::getCutType()const
+{
+   return theCutType;
+}
+
+void ossimRectangleCutFilter::setCutType(ossimRectangleCutType cutType)
+{
+   theCutType = cutType;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRectangleCutFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRectangleCutFilter.h
new file mode 100644
index 0000000000..65ce6341f0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRectangleCutFilter.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRectangleCutFilter.h,v 1.12 2005/10/28 14:01:03 gpotts Exp $
+#ifndef ossimRectangleCutFilter_HEADER
+#define ossimRectangleCutFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class OSSIM_DLL ossimRectangleCutFilter : public ossimImageSourceFilter
+{
+public:
+   enum ossimRectangleCutType
+   {
+      OSSIM_RECTANGLE_NULL_INSIDE  = 0,
+      OSSIM_RECTANGLE_NULL_OUTSIDE = 1
+   };
+
+   ossimRectangleCutFilter(ossimObject* owner,
+                     ossimImageSource* inputSource=NULL);
+   ossimRectangleCutFilter(ossimImageSource* inputSource=NULL);
+
+   void setRectangle(const ossimIrect& rect);
+
+   const ossimIrect&     getRectangle()const;
+   ossimRectangleCutType getCutType()const;
+   void                  setCutType(ossimRectangleCutType cutType);
+   
+   ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const;
+
+   ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                       ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+   
+protected:
+   ossimIrect            theRectangle;
+   ossimRectangleCutType theCutType;
+   vector<ossimDpt>      theDecimationList;
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimRectangleCutFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToGreyFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToGreyFilter.cpp
new file mode 100644
index 0000000000..20085888b9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToGreyFilter.cpp
@@ -0,0 +1,249 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToGreyFilter.cpp,v 1.21 2005/02/11 15:07:34 dburken Exp $
+
+#include <imaging/tile_sources/ossimRgbToGreyFilter.h>
+#include <imaging/ossimU8ImageData.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+RTTI_DEF1(ossimRgbToGreyFilter, "ossimRgbToGreyFilter", ossimImageSourceFilter)
+
+ossimRgbToGreyFilter::ossimRgbToGreyFilter(ossimObject* owner)
+   :ossimImageSourceFilter(owner),
+    theBlankTile(NULL),
+    theTile(NULL),
+    theC1(1.0/3.0),
+    theC2(1.0/3.0),
+    theC3(1.0/3.0)
+{
+}
+
+ossimRgbToGreyFilter::ossimRgbToGreyFilter(ossimImageSource* inputSource,
+                                           double c1,
+                                           double c2,
+                                           double c3)
+   : ossimImageSourceFilter(NULL, inputSource),
+     theBlankTile(NULL),
+     theTile(NULL),
+     theC1(c1),
+     theC2(c2),
+     theC3(c3)
+{
+}
+
+ossimRgbToGreyFilter::ossimRgbToGreyFilter(ossimObject* owner,
+                                           ossimImageSource* inputSource,
+                                           double c1,
+                                           double c2,
+                                           double c3)
+   : ossimImageSourceFilter(owner, inputSource),
+     theBlankTile(NULL),
+     theTile(NULL),
+     theC1(c1),
+     theC2(c2),
+     theC3(c3)
+{
+}
+ossimRgbToGreyFilter::~ossimRgbToGreyFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimRgbToGreyFilter::getTile(const ossimIrect& tileRect,
+                                              ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;  // This filter requires an input.
+   }
+
+   ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(tileRect,
+                                                           resLevel);   
+   if(!isSourceEnabled() || !inputTile.valid())
+   {
+      return inputTile;
+   }
+
+   if(!theTile)
+   {
+      allocate(); // First time through...
+   }
+
+   // if (!theTile) // throw exeption...
+
+   if( inputTile->getDataObjectStatus() == OSSIM_NULL ||
+       inputTile->getDataObjectStatus() == OSSIM_EMPTY )
+   {
+      theBlankTile->setImageRectangle(tileRect);
+      return theBlankTile;
+   }
+
+   // Set the origin, resize if needed of the output tile.
+   theTile->setImageRectangle(tileRect);
+
+   // Filter the tile.
+   runUcharTransformation(inputTile);
+
+   // Always validate to set the status.
+   theTile->validate();
+   
+   return theTile;
+}
+
+
+void ossimRgbToGreyFilter::initialize()
+{
+   // Base class will recapture "theInputConnection".
+   ossimImageSourceFilter::initialize();
+}
+
+void ossimRgbToGreyFilter::allocate()
+{
+   if(theInputConnection)
+   {
+      theTile      = NULL;
+      theBlankTile = NULL;
+
+      if(isSourceEnabled())
+      {
+         theBlankTile = new ossimU8ImageData(this,
+                                             1,
+                                             theInputConnection->getTileWidth(),
+                                             theInputConnection->getTileHeight());  
+         
+         
+         theTile = (ossimImageData*)theBlankTile->dup();
+         theTile->initialize();
+      }
+   }
+}
+
+ossim_uint32 ossimRgbToGreyFilter::getNumberOfOutputBands() const
+{
+   if(isSourceEnabled())
+   {
+      return 1;
+   }
+
+   return ossimImageSourceFilter::getNumberOfOutputBands();
+}
+
+bool ossimRgbToGreyFilter::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix)const
+{
+   ossimImageSourceFilter::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           "c1",
+           theC1,
+           true);
+   kwl.add(prefix,
+           "c2",
+           theC2,
+           true);
+   kwl.add(prefix,
+           "c3",
+           theC2,
+           true);
+   
+   return true;
+}
+
+bool ossimRgbToGreyFilter::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   ossimImageSourceFilter::loadState(kwl, prefix);
+
+   const char* lookup = kwl.find(prefix, "c1");
+   if(lookup)
+   {
+      theC1 = ossimString(lookup).toDouble();
+   }
+   lookup = kwl.find(prefix, "c2");
+   if(lookup)
+   {
+      theC2 = ossimString(lookup).toDouble();
+   }
+   lookup = kwl.find(prefix, "c3");
+   if(lookup)
+   {
+      theC3 = ossimString(lookup).toDouble();
+   }
+   return true;
+}
+
+void ossimRgbToGreyFilter::runUcharTransformation(ossimRefPtr<ossimImageData>& tile)
+{   
+   unsigned char** bandSrc = new unsigned char*[tile->getNumberOfBands()];
+   unsigned char* bandDest;
+   
+   if(tile->getNumberOfBands() == 1)
+   {
+      bandSrc[0]  = static_cast<unsigned char*>(tile->getBuf(0));
+      bandSrc[1]  = static_cast<unsigned char*>(tile->getBuf(0));
+      bandSrc[2]  = static_cast<unsigned char*>(tile->getBuf(0));
+   }
+   else if(tile->getNumberOfBands() == 2)
+   {
+      bandSrc[0]  = static_cast<unsigned char*>(tile->getBuf(0));
+      bandSrc[1]  = static_cast<unsigned char*>(tile->getBuf(1));
+      bandSrc[2]  = static_cast<unsigned char*>(tile->getBuf(1));      
+   }
+   else if(tile->getNumberOfBands() == 3)
+   {
+      bandSrc[0]  = static_cast<unsigned char*>(tile->getBuf(0));
+      bandSrc[1]  = static_cast<unsigned char*>(tile->getBuf(1));
+      bandSrc[2]  = static_cast<unsigned char*>(tile->getBuf(2));      
+   }
+   
+   bandDest = static_cast<unsigned char*>(theTile->getBuf());
+   
+   long offset;
+
+   long upperBound = tile->getWidth()*tile->getHeight();
+   for(offset = 0; offset < upperBound; ++offset)
+   {
+      long value;
+      
+      value = irint(theC1*(bandSrc[0][offset]) +
+                    theC2*(bandSrc[1][offset]) +
+                    theC3*(bandSrc[2][offset]));
+      
+      value = value<255?value:255;
+      value = value>0?value:0;
+
+      bandDest[offset] = value;
+   }
+   
+
+   delete [] bandSrc;
+}
+
+ossimString ossimRgbToGreyFilter::getShortName()const
+{
+   return ossimString("grey");
+}
+
+ossimString ossimRgbToGreyFilter::getLongName()const
+{
+   return ossimString("rgb to grey scale filter");
+}
+
+ossimScalarType ossimRgbToGreyFilter::getOutputScalarType() const
+{
+   if(isSourceEnabled())
+   {
+      return OSSIM_UCHAR;
+   }
+   
+   return ossimImageSourceFilter::getOutputScalarType();
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToGreyFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToGreyFilter.h
new file mode 100644
index 0000000000..fe3180f75d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToGreyFilter.h
@@ -0,0 +1,70 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToGreyFilter.h,v 1.13 2005/02/11 15:07:34 dburken Exp $
+#ifndef ossimRgbToGreyFilter_HEADER
+#define ossimRgbToGreyFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimRgbToGreyFilter : public ossimImageSourceFilter
+{
+public:
+   ossimRgbToGreyFilter(ossimObject* owner=NULL);
+   ossimRgbToGreyFilter(ossimImageSource* inputSource,
+                        double c1 = 1.0/3.0,
+                        double c2 = 1.0/3.0,
+                        double c3 = 1.0/3.0);
+   ossimRgbToGreyFilter(ossimObject* owner,
+                        ossimImageSource* inputSource,
+                        double c1 = 1.0/3.0,
+                        double c2 = 1.0/3.0,
+                        double c3 = 1.0/3.0);
+   virtual ~ossimRgbToGreyFilter();
+   
+   virtual ossimString getShortName()const;
+   virtual ossimString getLongName()const;
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual void initialize();
+   
+   virtual ossimScalarType getOutputScalarType() const;
+   
+   ossim_uint32 getNumberOfOutputBands() const;
+ 
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+   
+   ossimRefPtr<ossimImageData> theBlankTile;
+   ossimRefPtr<ossimImageData> theTile;
+   void runUcharTransformation(ossimRefPtr<ossimImageData>& tile);
+   double theC1;
+   double theC2;
+   double theC3;
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimRgbToGreyFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsiSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsiSource.cpp
new file mode 100644
index 0000000000..f8ad925cd2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsiSource.cpp
@@ -0,0 +1,162 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToHsiSource.cpp,v 1.10 2005/02/11 15:07:34 dburken Exp $
+
+#include <imaging/tile_sources/ossimRgbToHsiSource.h>
+#include <imaging/ossimImageData.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/color_space/ossimHsiVector.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF1(ossimRgbToHsiSource, "ossimRgbToHsiSource", ossimImageSourceFilter)
+
+ossimRgbToHsiSource::ossimRgbToHsiSource()
+   :ossimImageSourceFilter(),
+    theBlankTile(NULL),
+    theTile(NULL)
+{
+}
+
+ossimRgbToHsiSource::ossimRgbToHsiSource(ossimImageSource* inputSource)
+   : ossimImageSourceFilter(inputSource),
+     theBlankTile(NULL),
+     theTile(NULL)
+{
+}
+
+ossimRgbToHsiSource::~ossimRgbToHsiSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimRgbToHsiSource::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();  // This filter requires an input.
+   }
+   
+   ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(tileRect,
+                                                                       resLevel);   
+   if(!isSourceEnabled() || !inputTile.valid())
+   {
+      return inputTile;
+   }
+
+   if(!theTile)
+   {
+      allocate(); // First time through...
+   }
+
+   if (!theTile.valid())
+   {
+      return inputTile;
+   }
+   
+   if( inputTile->getDataObjectStatus() == OSSIM_NULL ||
+       inputTile->getDataObjectStatus() == OSSIM_EMPTY )
+   {
+      theBlankTile->setImageRectangle(tileRect);
+      return theBlankTile;
+   }
+   
+   if((inputTile->getNumberOfBands()==3)&&
+      (inputTile->getScalarType()==OSSIM_UCHAR)&&
+      (inputTile->getDataObjectStatus()!=OSSIM_NULL))
+   {
+      // Set the origin, resize if needed of the output tile.
+      theTile->setImageRectangle(tileRect);
+
+      float* outputBands[3];
+      ossim_uint8* inputBands[3];
+      outputBands[0] = static_cast<float*>(theTile->getBuf(0));
+      outputBands[1] = static_cast<float*>(theTile->getBuf(1));
+      outputBands[2] = static_cast<float*>(theTile->getBuf(2));
+      inputBands[0]  = static_cast<ossim_uint8*>(inputTile->getBuf(0));
+      inputBands[1]  = static_cast<ossim_uint8*>(inputTile->getBuf(1));
+      inputBands[2]  = static_cast<ossim_uint8*>(inputTile->getBuf(2));
+      
+      long height = inputTile->getHeight();
+      long width  = inputTile->getWidth();
+      long offset = 0;
+      for(long row = 0; row < height; ++row)
+      {
+         for(long col = 0; col < width; ++col)
+         {
+            ossimRgbVector rgb(inputBands[0][offset],
+                               inputBands[1][offset],
+                               inputBands[2][offset]);
+            
+            ossimHsiVector hsi(rgb);
+            
+            
+            outputBands[0][offset] = hsi.getH();
+            outputBands[1][offset] = hsi.getS();
+            outputBands[2][offset] = hsi.getI();
+            
+            ++offset;
+         }
+      }
+   }
+   else // Input tile not of correct type to process...
+   {
+      return inputTile;
+   }
+
+   theTile->validate();
+   return theTile;
+}
+
+ossimScalarType ossimRgbToHsiSource::getOutputScalarType() const
+{
+   return OSSIM_NORMALIZED_FLOAT;
+}
+
+void ossimRgbToHsiSource::initialize()
+{
+   // Base class will recapture "theInputConnection".
+   ossimImageSourceFilter::initialize();   
+}
+
+void ossimRgbToHsiSource::allocate()
+{
+   theBlankTile = NULL;
+   theTile = NULL;
+
+   if(!theInputConnection) return;
+   
+   theBlankTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile      = (ossimImageData*)theBlankTile->dup();
+   theTile->initialize();
+}
+
+ossim_uint32 ossimRgbToHsiSource::getNumberOfOutputBands()const
+{
+   return 3;
+}
+
+double ossimRgbToHsiSource::getNullPixelValue()const
+{
+   return OSSIM_FLT_NAN;
+}
+
+double ossimRgbToHsiSource::getMinPixelValue(ossim_uint32 band)const
+{
+   return 0.0;
+}
+
+double ossimRgbToHsiSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   return 1.0;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsiSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsiSource.h
new file mode 100644
index 0000000000..1a2d77f905
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsiSource.h
@@ -0,0 +1,47 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToHsiSource.h,v 1.10 2005/02/11 15:07:34 dburken Exp $
+#ifndef ossimRgbToHsiSource_HEADER
+#define ossimRgbToHsiSource_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimRgbToHsiSource : public ossimImageSourceFilter
+{
+public:
+   ossimRgbToHsiSource();
+   ossimRgbToHsiSource(ossimImageSource* inputSource);
+   virtual ~ossimRgbToHsiSource();
+
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual ossimScalarType getOutputScalarType() const;
+   virtual ossim_uint32    getNumberOfOutputBands()const;
+   virtual double          getNullPixelValue()const;
+   virtual double          getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double          getMaxPixelValue(ossim_uint32 band=0)const;
+
+   virtual void initialize();
+
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+   
+   ossimRefPtr<ossimImageData> theBlankTile;
+   ossimRefPtr<ossimImageData> theTile;
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimRgbToHsiSource_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsvSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsvSource.cpp
new file mode 100644
index 0000000000..9a16125242
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsvSource.cpp
@@ -0,0 +1,155 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToHsvSource.cpp,v 1.8 2005/02/11 15:07:34 dburken Exp $
+#include "ossimRgbToHsvSource.h"
+#include "imaging/ossimImageData.h"
+#include "base/common/ossimConstants.h"
+#include "base/common/ossimCommon.h"
+#include "base/data_types/color_space/ossimHsvVector.h"
+#include "base/data_types/color_space/ossimRgbVector.h"
+#include "imaging/factory/ossimImageDataFactory.h"
+
+RTTI_DEF1(ossimRgbToHsvSource, "ossimRgbToHsvSource", ossimImageSourceFilter)
+
+ossimRgbToHsvSource::ossimRgbToHsvSource()
+   :ossimImageSourceFilter(),
+    theBlankTile(NULL),
+    theTile(NULL)
+{
+}
+
+
+ossimRgbToHsvSource::ossimRgbToHsvSource(ossimImageSource* inputSource)
+   : ossimImageSourceFilter(inputSource),
+    theBlankTile(NULL),
+    theTile(NULL)
+{
+}
+
+ossimRgbToHsvSource::~ossimRgbToHsvSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimRgbToHsvSource::getTile(
+   const  ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();  // This filter requires an input.
+   }
+
+   ossimRefPtr<ossimImageData> inputTile =
+      theInputConnection->getTile(tileRect, resLevel);   
+   if(!isSourceEnabled() || !inputTile.valid())
+   {
+      return inputTile;
+   }
+
+   if(!theTile.valid())
+   {
+      allocate(); // First time through...
+   }
+   
+   if (!theTile.valid()) // throw exeption...
+   {
+      return inputTile;
+   }
+   
+   if( inputTile->getDataObjectStatus() == OSSIM_NULL ||
+       inputTile->getDataObjectStatus() == OSSIM_EMPTY )
+   {
+      theBlankTile->setImageRectangle(tileRect);
+      return theBlankTile;
+   }
+
+   if((inputTile->getNumberOfBands()==3)&&
+      (inputTile->getScalarType()==OSSIM_UCHAR)&&
+      (inputTile->getDataObjectStatus()!=OSSIM_NULL))
+   {
+      // Set the origin, resize if needed of the output tile.
+      theTile->setImageRectangle(tileRect);
+
+      float* outputBands[3];
+      ossim_uint8* inputBands[3];
+      outputBands[0] = static_cast<float*>(theTile->getBuf(0));
+      outputBands[1] = static_cast<float*>(theTile->getBuf(1));
+      outputBands[2] = static_cast<float*>(theTile->getBuf(2));
+      inputBands[0] = static_cast<ossim_uint8*>(inputTile->getBuf(0));
+      inputBands[1] = static_cast<ossim_uint8*>(inputTile->getBuf(1));
+      inputBands[2] = static_cast<ossim_uint8*>(inputTile->getBuf(2));
+      
+      long height = inputTile->getHeight();
+      long width  = inputTile->getWidth();
+      long offset = 0;
+      for(long row = 0; row < height; ++row)
+      {
+         for(long col = 0; col < width; ++col)
+         {
+            ossimRgbVector rgb(inputBands[0][offset],
+                               inputBands[1][offset],
+                               inputBands[2][offset]);
+            
+            ossimHsvVector hsv(rgb);
+            
+            outputBands[0][offset] = hsv.getH();
+            outputBands[1][offset] = hsv.getS();
+            outputBands[2][offset] = hsv.getV();
+            
+            ++offset;
+         }
+      }
+   }
+   else // Input tile not of correct type to process...
+   {
+      return inputTile;
+   }
+   theTile->validate();
+   return theTile;
+}
+
+void ossimRgbToHsvSource::initialize()
+{
+   // Base class will recapture "theInputConnection".
+   ossimImageSourceFilter::initialize();
+}
+
+void ossimRgbToHsvSource::allocate()
+{
+   theBlankTile = ossimImageDataFactory::instance()->create(this, this);
+   theTile      = (ossimImageData*)theBlankTile->dup();
+   theTile->initialize();
+}
+
+ossimScalarType ossimRgbToHsvSource::getOutputScalarType() const
+{
+   return OSSIM_NORMALIZED_FLOAT;
+}
+
+ossim_uint32 ossimRgbToHsvSource::getNumberOfOutputBands()const
+{
+   return 3;
+}
+
+double ossimRgbToHsvSource::getNullPixelValue()const
+{
+   return OSSIM_FLT_NAN;
+}
+
+double ossimRgbToHsvSource::getMinPixelValue(ossim_uint32 band)const
+{
+   return 0.0;
+}
+
+double ossimRgbToHsvSource::getMaxPixelValue(ossim_uint32 band)const
+{
+   return 1.0;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsvSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsvSource.h
new file mode 100644
index 0000000000..67029d0b41
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToHsvSource.h
@@ -0,0 +1,47 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToHsvSource.h,v 1.8 2005/02/11 15:07:34 dburken Exp $
+#ifndef ossimRgbToHsvSource_HEADER
+#define ossimJpegRgbToYCbCrSource_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimRgbToHsvSource : public ossimImageSourceFilter
+{
+public:
+   ossimRgbToHsvSource();
+   ossimRgbToHsvSource(ossimImageSource* inputSource);
+   virtual ~ossimRgbToHsvSource();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual ossimScalarType getOutputScalarType() const;
+   virtual ossim_uint32    getNumberOfOutputBands()const;
+   virtual double getNullPixelValue()const;
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   virtual void initialize();
+       
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+   
+   ossimRefPtr<ossimImageData> theBlankTile;
+   ossimRefPtr<ossimImageData> theTile;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToIndexFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToIndexFilter.cpp
new file mode 100644
index 0000000000..9133713d75
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToIndexFilter.cpp
@@ -0,0 +1,227 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToIndexFilter.cpp,v 1.5 2005/07/16 14:28:03 dburken Exp $
+
+#include <imaging/tile_sources/ossimRgbToIndexFilter.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+
+RTTI_DEF1(ossimRgbToIndexFilter,
+          "ossimRgbToIndexFilter",
+          ossimImageSourceFilter);
+
+ossimRgbToIndexFilter::ossimRgbToIndexFilter()
+   :ossimImageSourceFilter(),
+    theLut(0),
+    theTile(NULL)
+{
+}
+
+ossimRgbToIndexFilter::ossimRgbToIndexFilter(ossimImageSource* inputSource,
+                                             const ossimRgbLutDataObject& rgbLut)
+   :ossimImageSourceFilter(inputSource),
+    theLut(rgbLut),
+    theTile(NULL)
+{
+}
+
+ossimRgbToIndexFilter::~ossimRgbToIndexFilter()
+{
+}
+
+void ossimRgbToIndexFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   // Force allocate on next getTile.
+   theTile      = NULL;
+}
+
+void ossimRgbToIndexFilter::allocate()
+{
+   theTile      = NULL;
+   
+   if(isSourceEnabled())
+   {
+      theTile      = ossimImageDataFactory::instance()->create(this, this);
+      theTile->initialize();
+   }
+}
+
+void ossimRgbToIndexFilter::disableSource()
+{
+   ossimImageSourceFilter::disableSource();
+   theTile = NULL;
+}
+
+ossimRefPtr<ossimImageData> ossimRgbToIndexFilter::getTile(
+   const ossimIrect& origin,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   if(!theTile.valid())
+   {
+      allocate();
+   }
+   
+   ossimRefPtr<ossimImageData> input = theInputConnection->getTile(origin,
+                                                                   resLevel);
+
+   if(!theTile.valid() || !input.valid())
+   {
+      return input;
+   }
+
+   theTile->setImageRectangle(origin);
+
+   if(input->getScalarType() == OSSIM_UCHAR)
+   {
+      theTile->setDataObjectStatus(OSSIM_FULL);
+      return convertInputTile(input);
+   }
+   else
+   {
+      theTile->makeBlank();
+   }
+
+   theTile->setDataObjectStatus(OSSIM_FULL);
+   
+   return theTile;
+}
+
+ossimRefPtr<ossimImageData> ossimRgbToIndexFilter::convertInputTile(ossimRefPtr<ossimImageData>& tile)
+{
+   if (!tile)
+   {
+      return theTile;
+   }
+   
+   const ossim_uint32 BANDS = tile->getNumberOfBands();
+
+   if (!BANDS)
+   {
+      return theTile;
+   }
+   
+   ossim_uint8* band[3];
+   ossim_uint8* outBand = (ossim_uint8*)theTile->getBuf();
+
+   if(BANDS >= 3)
+   {
+      band[0] = (ossim_uint8*)(tile->getBuf(0));
+      band[1] = (ossim_uint8*)(tile->getBuf(1));
+      band[2] = (ossim_uint8*)(tile->getBuf(2));
+   }
+   else
+   {
+      band[0] = (ossim_uint8*)(tile->getBuf(0));
+      band[1] = (ossim_uint8*)(tile->getBuf(0));
+      band[2] = (ossim_uint8*)(tile->getBuf(0));
+   }
+
+   if(band[0])
+   {
+      ossim_uint32 upper = tile->getWidth()*tile->getHeight();
+
+      for(ossim_uint32 offset = 0; offset < upper; ++offset)
+      {
+         *outBand = theLut.findIndex(*band[0], *band[1], *band[2]);
+         
+         ++outBand;
+         ++band[0];
+         ++band[1];
+         ++band[2];
+      }
+   }
+   
+   return theTile;
+}
+
+bool ossimRgbToIndexFilter::saveState(ossimKeywordlist& kwl,
+                                      const char* prefix)const
+{
+   ossimString newPrefix = prefix;
+   newPrefix = newPrefix + "lut.";
+
+   theLut.saveState(kwl, newPrefix.c_str());
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimRgbToIndexFilter::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   ossimString newPrefix = prefix;
+   newPrefix = newPrefix + "lut.";
+
+   theLut.loadState(kwl, newPrefix.c_str());
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+ossim_uint32 ossimRgbToIndexFilter::getNumberOfOutputBands() const
+{
+   if(isSourceEnabled())
+   {
+      return 1;
+   }
+   
+   return ossimImageSourceFilter::getNumberOfOutputBands();
+}
+   
+ossimScalarType ossimRgbToIndexFilter::getOutputScalarType() const
+{
+   if(isSourceEnabled())
+   {
+      return OSSIM_UCHAR;
+   }
+   
+   return ossimImageSourceFilter::getOutputScalarType();
+}
+
+void ossimRgbToIndexFilter::setLut(ossimRgbLutDataObject& lut)
+{
+   theLut = lut;
+}
+
+double ossimRgbToIndexFilter::getNullPixelValue(ossim_uint32 band)const
+{
+   if(isSourceEnabled())
+   {
+      return 0.0;
+   }
+   
+   return ossimImageSourceFilter::getNullPixelValue(band);
+}
+
+double ossimRgbToIndexFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   if(isSourceEnabled())
+   {
+      return 1.0;
+   }
+   
+   return ossimImageSourceFilter::getMinPixelValue();
+}
+
+double ossimRgbToIndexFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   if(isSourceEnabled())
+   {
+      return 255.0;
+   }
+   
+   return ossimImageSourceFilter::getMaxPixelValue();
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToIndexFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToIndexFilter.h
new file mode 100644
index 0000000000..452b731ce7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToIndexFilter.h
@@ -0,0 +1,96 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToIndexFilter.h,v 1.4 2005/02/11 15:07:34 dburken Exp $
+#ifndef ossimRgbToIndexFilter_HEADER
+#define ossimRgbToIndexFilter_HEADER
+#include <base/data_types/color_space/ossimRgbVector.h>
+#include <base/common/ossimRgbLutDataObject.h>
+#include <base/data_types/ossimFilename.h>
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <vector>
+
+class ossimImageData;
+
+/*!
+ * It will map the input data to an 8-bit index table.  The table
+ * <pre>
+ *
+ * Example keyword list:
+ *
+ * type:  ossimRgbToIndexFilter
+ *
+ * If you want to load from a file then just do:
+ *
+ * lut.filename: <full path to lut file>
+ *
+ * If you have the lut table in line then it must look like this:
+ *
+ * lut.entry0:  204 102 1
+ * lut.entry1:  255 204 153
+ * lut.entry2:  51 204 204
+ * lut.number_of_entries:  3
+ * lut.type:  ossimRgbLutDataObject
+ *
+ * </pre>
+ */
+class ossimRgbToIndexFilter : public ossimImageSourceFilter
+{
+public:
+   /*!
+    * Initializes the min value to 0 and the max value to 4000.
+    */
+   ossimRgbToIndexFilter();
+   ossimRgbToIndexFilter(ossimImageSource* inputSource,
+                           const ossimRgbLutDataObject& rgbLut);
+   virtual ~ossimRgbToIndexFilter();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& origin,
+                                               ossim_uint32 resLevel=0);
+   
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+   
+   virtual ossimScalarType getOutputScalarType() const;
+   
+   void setLut(ossimRgbLutDataObject& lut);
+
+   void setLut(const ossimFilename& file);
+
+   virtual void disableSource();
+   
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+   
+   virtual void initialize();
+
+   /*!
+    * Saves the state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0)const;
+
+   /*!
+    * Loads the state of this object.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+protected:
+   void allocate();
+   
+   virtual ossimRefPtr<ossimImageData> convertInputTile(ossimRefPtr<ossimImageData>& tile);
+
+   ossimRgbLutDataObject       theLut;
+   ossimRefPtr<ossimImageData> theTile;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToJpegYCbCrSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToJpegYCbCrSource.cpp
new file mode 100644
index 0000000000..da82a7002b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToJpegYCbCrSource.cpp
@@ -0,0 +1,93 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToJpegYCbCrSource.cpp,v 1.6 2005/02/11 15:07:34 dburken Exp $
+#include <imaging/tile_sources/ossimRgbToJpegYCbCrSource.h>
+#include <imaging/ossimImageData.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/color_space/ossimJpegYCbCrVector.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+
+RTTI_DEF1(ossimRgbToJpegYCbCrSource,
+          "ossimRgbToJpegYCbCrSource",
+          ossimImageSourceFilter)
+
+ossimRgbToJpegYCbCrSource::ossimRgbToJpegYCbCrSource()
+   :ossimImageSourceFilter()
+{
+   theBlankTile = new ossimImageData(this,
+                                     OSSIM_UCHAR,
+                                     3);
+}
+
+ossimRgbToJpegYCbCrSource::ossimRgbToJpegYCbCrSource(ossimImageSource* inputSource)
+   : ossimImageSourceFilter(inputSource)
+{
+}
+
+ossimRgbToJpegYCbCrSource::~ossimRgbToJpegYCbCrSource()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimRgbToJpegYCbCrSource::getTile(const  ossimIrect& tileRect,
+                                                   ossim_uint32 resLevel)
+{
+   theBlankTile->setOrigin(tileRect.ul());
+   theBlankTile->setWidthHeight(tileRect.width(), tileRect.height());
+   
+   if(theInputConnection)
+   {
+      ossimRefPtr<ossimImageData> imageData = theInputConnection->getTile(tileRect,
+                                                              resLevel);
+      if(!imageData.valid())
+      {
+         return theBlankTile;
+      }
+      if((isSourceEnabled())&&
+         (imageData->getNumberOfBands()==3)&&
+         (imageData->getScalarType()==OSSIM_UCHAR)&&
+         (imageData->getDataObjectStatus()!=OSSIM_NULL)&&
+         (imageData->getDataObjectStatus()!=OSSIM_EMPTY))
+      {
+         ossim_uint8* bands[3];
+         
+         bands[0] = static_cast<ossim_uint8*>(imageData->getBuf(0));
+         bands[1] = static_cast<ossim_uint8*>(imageData->getBuf(1));
+         bands[2] = static_cast<ossim_uint8*>(imageData->getBuf(2));
+         
+         long height = imageData->getHeight();
+         long width  = imageData->getWidth();
+         long offset = 0;
+         
+         for(long row = 0; row < height; ++row)
+         {
+            for(long col = 0; col < width; ++col)
+            {
+               ossimRgbVector rgb(bands[0][offset],
+                                  bands[1][offset],
+                                  bands[2][offset]);
+               
+               ossimJpegYCbCrVector ycbcr(rgb);
+               
+               
+               bands[0][offset] = ycbcr.getY();
+               bands[1][offset] = ycbcr.getCb();
+               bands[2][offset] = ycbcr.getCr();
+               ++offset;
+            }
+         }
+         imageData->validate();
+      }
+      return imageData;
+   }
+   
+   return theBlankTile;
+}  
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToJpegYCbCrSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToJpegYCbCrSource.h
new file mode 100644
index 0000000000..d4412ad064
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimRgbToJpegYCbCrSource.h
@@ -0,0 +1,32 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimRgbToJpegYCbCrSource.h,v 1.6 2005/02/11 15:07:34 dburken Exp $
+#ifndef ossimRgbToJpegYCbCrSource_HEADER
+#define ossimRgbToJpegYCbCrSource_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class ossimRgbToJpegYCbCrSource : public ossimImageSourceFilter
+{
+public:
+   
+   ossimRgbToJpegYCbCrSource();
+   ossimRgbToJpegYCbCrSource(ossimImageSource* inputSource);
+   virtual ~ossimRgbToJpegYCbCrSource();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                               ossim_uint32 resLevel=0);
+       
+protected:
+   ossimRefPtr<ossimImageData> theBlankTile;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSFIMFusion.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSFIMFusion.cpp
new file mode 100644
index 0000000000..39050c914a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSFIMFusion.cpp
@@ -0,0 +1,285 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LICENSE:  See top level LICENSE.txt
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimSFIMFusion.cpp,v 1.2 2005/12/22 17:03:41 dburken Exp $
+#include "ossimSFIMFusion.h"
+#include <matrix/newmat.h>
+#include <matrix/newmatio.h>
+#include <base/misc/ossim2dLinearRegression.h>
+#include <base/data_types/color_space/ossimNormRgbVector.h>
+#include <base/data_types/color_space/ossimHsiVector.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF2(ossimSFIMFusion, "ossimSFIMFusion", ossimFusionCombiner, ossimAdjustableParameterInterface);
+
+
+static const ossim_uint32 HIGH_PASS_GAIN_OFFSET = 0;
+static const ossim_uint32 PAN_BLURR_WIDTH_OFFSET = 1;
+static const ossim_uint32  NUMBER_OF_ADJUSTABLE_PARAMETERS = 2;
+
+ossimSFIMFusion::ossimSFIMFusion()
+   :theBlurrKernelWidth(1.5),
+    theHighPassKernelWidth(3)
+{
+   theLowPassFilter  = new ossimImageGaussianFilter;
+   theHighPassFilter = new ossimConvolutionSource;
+
+   setFilters();
+
+   initAdjustableParameters();
+}
+
+ossimSFIMFusion::~ossimSFIMFusion()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimSFIMFusion::getTile(const ossimIrect& rect,
+                                                                 ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   if (!theIntensityConnection)
+   {
+      return theInputConnection->getTile(rect, resLevel);
+   }
+
+   
+   
+   if(!theNormLowPassTile.valid())
+   {
+      theNormLowPassTile = new ossimImageData(this,
+                                              OSSIM_NORMALIZED_FLOAT,
+                                              1,
+                                              rect.width(),
+                                              rect.height());
+      theNormHighPassTile = new ossimImageData(this,
+                                              OSSIM_NORMALIZED_FLOAT,
+                                               1,
+                                               rect.width(),
+                                               rect.height());
+      theNormLowPassTile->initialize();
+      theNormHighPassTile->initialize();
+      theNormLowPassTile->makeBlank();
+      theNormHighPassTile->makeBlank();
+   }
+
+   theNormLowPassTile->setImageRectangle(rect);
+   theNormHighPassTile->setImageRectangle(rect);
+   theNormLowPassTile->makeBlank();
+   theNormHighPassTile->makeBlank();
+
+   if(!theLowPassFilter->getInput() && getInput())
+   {
+      initialize();
+   }
+
+   ossimRefPtr<ossimImageData> lowTile  = theLowPassFilter->getTile(rect, resLevel);
+   ossimRefPtr<ossimImageData> highTile = theHighPassFilter->getTile(rect, resLevel);
+//   ossimRefPtr<ossimImageData> highTile = getNormIntensity(rect, resLevel);
+
+   // if we don't have valid low and high pass then return the input color tile
+   // in its original format
+   //
+   if(!lowTile.valid()||!highTile.valid())
+   {
+      return theInputConnection->getTile(rect, resLevel);
+   }
+
+   if((lowTile->getDataObjectStatus() == OSSIM_EMPTY)||
+      (!lowTile->getBuf()) ||
+      (highTile->getDataObjectStatus() == OSSIM_EMPTY)||
+      (!highTile->getBuf()))
+   {
+      return theInputConnection->getTile(rect, resLevel);
+   }
+
+   ossimRefPtr<ossimImageData> normColorData = getNormTile(rect, resLevel);
+   
+   ossim_uint32 y = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 w = theTile->getWidth();
+   ossim_uint32 h = theTile->getHeight();
+
+   theTile->makeBlank();
+   theTile->setImageRectangle(rect);
+   
+   if(!normColorData.valid())
+   {
+     return 0;
+//      return theTile;
+   }
+
+   if((normColorData->getDataObjectStatus() == OSSIM_EMPTY)||
+      !normColorData->getBuf())
+   {
+      return theTile;
+   }
+   ossimRefPtr<ossimImageData> normColorOutputData = (ossimImageData*)normColorData->dup();
+   normColorOutputData->setImageRectangle(rect);
+   normColorOutputData->loadTile(normColorData.get());
+   
+   // ossim_float64 slopeResult = 0.0;
+   ossim_uint32 idx = 0;
+   std::vector<ossim_float32*> bands(normColorData->getNumberOfBands());
+   
+   lowTile->copyTileToNormalizedBuffer((ossim_float32*)theNormLowPassTile->getBuf());
+   
+   highTile->copyTileToNormalizedBuffer((ossim_float32*)theNormHighPassTile->getBuf());
+   theNormLowPassTile->validate();
+   theNormHighPassTile->validate();
+   ossimRefPtr<ossimImageData> lowPan = (ossimImageData*)theNormLowPassTile->dup();
+   lowPan->setImageRectangle(rect);
+   lowPan->loadTile(theNormLowPassTile.get());
+   ossimRefPtr<ossimImageData> highPan = (ossimImageData*)theNormHighPassTile->dup();
+   highPan->setImageRectangle(rect);
+   highPan->loadTile(theNormHighPassTile.get());
+   
+   ossim_float32* panHigh = (ossim_float32*)highPan->getBuf();
+   ossim_float32* panLow  = (ossim_float32*)lowPan->getBuf();
+   for(idx = 0; idx < bands.size(); ++idx)
+   {
+      bands[idx] = (ossim_float32*)normColorOutputData->getBuf(idx);
+   }
+   // double delta = 0.0;
+   ossim_uint32 bandsSize = bands.size();
+   double normMinPix = 0.0;
+   for(y = 0; y < h; ++y)
+     {
+       for(x = 0; x < w; ++x)
+	 {
+	   for(idx = 0; idx < bandsSize; ++idx)
+	     {
+	       if((*bands[idx] != 0.0)&&
+		  (*panLow > FLT_EPSILON) ) // if band is not null and not divide by 0
+		 {
+		   normMinPix = (ossim_float32)normColorOutputData->getMinPix(idx);
+		   *bands[idx] = ((*bands[idx])*(*panHigh))/
+		                 (*panLow);
+		   if(*bands[idx] > 1.0) *bands[idx] = 1.0;
+		   if(*bands[idx] < normMinPix) *bands[idx] = normMinPix;
+		 }
+	       ++bands[idx];
+	     }
+	   ++panHigh;
+	   ++panLow;
+         }
+     }
+   
+   theTile->copyNormalizedBufferToTile((ossim_float32*)normColorOutputData->getBuf());
+   theTile->validate();
+   
+   return theTile;
+}
+
+void ossimSFIMFusion::initialize()
+{
+   ossimFusionCombiner::initialize();
+   if(!theIntensityConnection)
+   {
+      theLowPassFilter->disconnect();
+      theHighPassFilter->disconnect();
+   }
+   else
+   {
+      theLowPassFilter->connectMyInputTo(0, PTR_CAST(ossimConnectableObject,
+                                                     theIntensityConnection->getObject()));
+      theHighPassFilter->connectMyInputTo(0, PTR_CAST(ossimConnectableObject,
+                                                      theIntensityConnection->getObject()));
+      setFilters();
+      theLowPassFilter->initialize();
+      theHighPassFilter->initialize();
+   }
+}
+
+void ossimSFIMFusion::setFilters()
+{
+   theLowPassFilter->setGaussStd(theBlurrKernelWidth);
+   
+   theHighPassMatrix = NEWMAT::Matrix(theHighPassKernelWidth, theHighPassKernelWidth);
+   theHighPassMatrix = 0;
+   theHighPassMatrix[theHighPassKernelWidth>>1][theHighPassKernelWidth>>1] = 1;
+   
+   // adjust the gain for the high pass filter
+   //
+   NEWMAT::Matrix high =  theHighPassMatrix;
+
+   ossim_float64 kernelW2 = theHighPassKernelWidth*theHighPassKernelWidth;
+   double gain = computeParameterOffset(HIGH_PASS_GAIN_OFFSET)*(kernelW2);
+   double multiplier = gain/(kernelW2);
+   high = -multiplier;
+   ossim_int32 cx = theHighPassKernelWidth>>1;
+   ossim_int32 cy = theHighPassKernelWidth>>1;
+
+   if(gain > FLT_EPSILON)
+   {
+      high[cy][cx] = multiplier* ( (kernelW2-1)+kernelW2/gain);
+   }
+   else
+   {
+      high = 0.0;
+      high[cy][cx] = 1.0;
+   }
+
+   theHighPassFilter->setConvolution(high);
+}
+
+void ossimSFIMFusion::initAdjustableParameters()
+{
+   resizeAdjustableParameterArray(NUMBER_OF_ADJUSTABLE_PARAMETERS);
+
+   setAdjustableParameter(HIGH_PASS_GAIN_OFFSET,
+                          -1.0);
+   setParameterDescription(HIGH_PASS_GAIN_OFFSET,
+                           "High pass gain");
+   setParameterSigma(HIGH_PASS_GAIN_OFFSET,
+                     1);
+   setParameterCenter(HIGH_PASS_GAIN_OFFSET,
+                      1.0);
+
+   setAdjustableParameter(PAN_BLURR_WIDTH_OFFSET,
+                          -1);
+   setParameterDescription(PAN_BLURR_WIDTH_OFFSET,
+                           "Blurring kernel width");
+   setParameterSigma(PAN_BLURR_WIDTH_OFFSET,
+                     7);
+   setParameterCenter(PAN_BLURR_WIDTH_OFFSET,
+                      7.5);
+   
+
+   setParameterOffset(PAN_BLURR_WIDTH_OFFSET,
+                      1.5);
+}
+
+void ossimSFIMFusion::adjustableParametersChanged()
+{
+//   std::cout << "Parameter offset = " << computeParameterOffset(2) << std::endl;
+   theBlurrKernelWidth = (ossim_uint32)(irint(computeParameterOffset(PAN_BLURR_WIDTH_OFFSET)));
+}
+
+
+bool ossimSFIMFusion::saveState(ossimKeywordlist& kwl,
+                                            const char* prefix) const
+{
+   ossimFusionCombiner::saveState(kwl, prefix);
+   saveAdjustments(kwl, prefix);
+
+   return true;
+}
+
+bool ossimSFIMFusion::loadState(const ossimKeywordlist& kwl,
+                                            const char* prefix)
+{
+   ossimFusionCombiner::loadState(kwl, prefix);
+   loadAdjustments(kwl, prefix);
+
+   
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSFIMFusion.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSFIMFusion.h
new file mode 100644
index 0000000000..4b4486597c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSFIMFusion.h
@@ -0,0 +1,76 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LICENSE:  See top level LICENSE.txt
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimSFIMFusion.h,v 1.3 2005/12/22 18:47:19 gpotts Exp $
+#ifndef ossimSFIMFusion_HEADER
+#define ossimSFIMFusion_HEADER
+#include "ossimFusionCombiner.h"
+#include "ossimConvolutionSource.h"
+#include "ossimImageGaussianFilter.h"
+#include <base/misc/ossimAdjustableParameterInterface.h>
+
+/**
+ * This class imlements the fusion algorithm from the paper:
+ *
+ * "Smoothing Filter-based Intesity Modulation: a spectral preserve
+ *  image fusion technique for improving spatial details"
+ *
+ *  Pulished in INT. J. Remote Sensing, 2000, Vol. 21 NO. 18, 3461-3472
+ *
+ *  By J. G. LIU
+ */
+class OSSIM_DLL ossimSFIMFusion : public ossimFusionCombiner,
+                                  public ossimAdjustableParameterInterface
+{
+public:
+   ossimSFIMFusion();
+   virtual ~ossimSFIMFusion();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32 resLevel=0);
+   virtual void initialize();
+
+   virtual ossimObject* getBaseObject()
+   {
+      return this;
+   }
+   virtual const ossimObject* getBaseObject()const
+   {
+      return this;
+   }
+   virtual void initAdjustableParameters();
+   virtual void adjustableParametersChanged();
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+protected:
+   void setFilters();
+   bool computeRegression(ossim_float64& slopeResult,
+                          const ossimIpt& origin,
+                          ossimRefPtr<ossimImageData> panData,
+                          ossimRefPtr<ossimImageData> colorData,
+                          ossim_uint32 colorBandIdx);
+   
+   ossim_float64 theBlurrKernelWidth;
+   ossim_uint32 theHighPassKernelWidth;
+   // These are low and high pass filters for the single pan band
+   //
+   ossimRefPtr<ossimImageGaussianFilter> theLowPassFilter;
+   ossimRefPtr<ossimConvolutionSource>   theHighPassFilter;
+   ossimRefPtr<ossimImageData>           theNormLowPassTile;
+   ossimRefPtr<ossimImageData>           theNormHighPassTile;
+   ossimRefPtr<ossimImageData>           theNormColorData;
+
+   NEWMAT::Matrix                        theHighPassMatrix;
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScalarRemapper.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScalarRemapper.cpp
new file mode 100644
index 0000000000..072573e56a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScalarRemapper.cpp
@@ -0,0 +1,554 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+// 
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for ossimScalarRemapper.
+// This class is used to remap image data from one scalar type to another.
+//
+//*******************************************************************
+//  $Id: ossimScalarRemapper.cpp,v 1.68 2005/12/20 17:55:56 dburken Exp $
+
+#include <iostream>
+
+#include <imaging/tile_sources/ossimScalarRemapper.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/common/events/ossimPropertyEvent.h>
+#include <base/common/events/ossimRefreshEvent.h>
+#include <base/common/ossimTrace.h>
+#include <base/property/ossimStringProperty.h>
+
+RTTI_DEF1(ossimScalarRemapper,
+          "ossimScalarRemapper",
+          ossimImageSourceFilter)
+
+static const ossimTrace traceDebug("ossimScalarRemapper:debug");
+   
+ossimScalarRemapper::ossimScalarRemapper()
+   :
+      ossimImageSourceFilter(),
+      theNormBuf(NULL),
+      theTile(NULL),
+      theOutputScalarType(OSSIM_UINT8),
+      theByPassFlag(false)
+{
+}
+
+ossimScalarRemapper::ossimScalarRemapper(ossimImageSource* inputSource,
+                                         ossimScalarType outputScalarType)
+   :
+      ossimImageSourceFilter(inputSource),
+      theNormBuf(NULL),
+      theTile(NULL),
+      theOutputScalarType(outputScalarType),
+      theByPassFlag(false)
+{
+   if(inputSource)
+   {
+      if (inputSource->getOutputScalarType() == outputScalarType)
+      {
+         // Disable this filter simply return the inputSource's data.
+         theByPassFlag = true;
+         
+         // Nothing else to do.
+      }
+      else
+      {
+         theByPassFlag = false;
+      }
+   }
+   else
+   {
+      theByPassFlag = true;
+   }
+}
+
+ossimScalarRemapper::~ossimScalarRemapper()
+{
+   destroy();
+}
+
+void ossimScalarRemapper::destroy()
+{
+   if (theNormBuf)
+   {
+      delete [] theNormBuf;
+      theNormBuf = NULL;
+   }
+   theTile      = NULL;
+}
+
+ossimRefPtr<ossimImageData> ossimScalarRemapper::getTile(
+   const ossimIrect& tileRect, ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   // Fetch tile from pointer from the input source.
+   ossimRefPtr<ossimImageData> inputTile =
+      theInputConnection->getTile(tileRect, resLevel);
+
+   // Check for remap bypass:
+   if ( !isSourceEnabled()||theByPassFlag )
+   {
+      return inputTile;
+   }
+
+   // Check for first time through.
+   if ( !theTile.valid() )
+   {
+      allocate();
+      
+      if ( !theTile.valid() )
+      {
+         // This can happen if input/output scalars are the same.
+         return inputTile;
+      }
+   }
+
+   // Capture the size prior to a possible resize.
+   ossim_uint32 oldSize = theTile->getSize();
+
+   // Set the origin,bands of the output tile.
+   theTile->setImageRectangle(tileRect);
+
+   ossim_uint32 newSize = theTile->getSize();
+
+   // Check for size change before possible return.
+   if(newSize != oldSize)
+   {
+      if(theNormBuf)
+      {
+         //---
+         // Delete the current buffer since it is the wrong size.
+         // 
+         // NOTE:
+         // We won't reallocate it yet since we could return without using it.
+         // It will be checked prior to using later.
+         //---
+         delete [] theNormBuf;
+         theNormBuf = NULL;
+      }
+   }
+   
+   if ( !inputTile.valid() ||
+        (inputTile->getDataObjectStatus() == OSSIM_NULL) ||
+        (inputTile->getDataObjectStatus() == OSSIM_EMPTY) )
+   {
+      //---
+      // Since the filter is enabled, return theTile which is of the
+      // correct scalar type.
+      //---
+      theTile->makeBlank();
+      return theTile;
+   }
+
+   if (!theNormBuf) // First time through or size changed and was deleted...
+   {
+      theNormBuf = new double[newSize];
+      memset(theNormBuf, '\0', newSize);
+   }
+
+   if (inputTile->getScalarType() == theOutputScalarType)
+   {
+      // Scalar types already the same.  Nothing to do...
+      return inputTile;
+   }
+   
+   switch(inputTile->getScalarType())
+   {
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         // Un-normalize and copy the buffer to the destination tile.
+         theTile->copyNormalizedBufferToTile(static_cast<double*>(
+                                                inputTile->getBuf()));
+         break;
+      }
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         // Un-normalize and copy the buffer to the destination tile.
+         theTile->copyNormalizedBufferToTile(static_cast<float*>(
+                                                inputTile->getBuf()));
+         break;
+      }
+      default:
+      {
+         // Normalize and copy the source tile to a buffer.
+         inputTile->copyTileToNormalizedBuffer(theNormBuf);
+         
+         // Un-normalize and copy the buffer to the destination tile.
+         theTile->copyNormalizedBufferToTile(theNormBuf);
+      }
+   }
+   
+   theTile->validate();
+   
+   return theTile;
+}
+
+ossimScalarType ossimScalarRemapper::getOutputScalarType() const
+{
+   if(isSourceEnabled()&&!theByPassFlag)
+   {
+      return theOutputScalarType;
+   }
+
+   return ossimImageSourceFilter::getOutputScalarType();
+}
+
+void ossimScalarRemapper::setOutputScalarType(ossimScalarType scalarType)
+{
+   if (scalarType == OSSIM_SCALAR_UNKNOWN)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimScalarRemapper::setOutputScalarType WARN:\n"
+         << "OSSIM_SCALAR_UNKNOWN passed to method.  No action taken..."
+         << std::endl;
+      return;
+   }
+   
+   if (theInputConnection)
+   {
+      if ( scalarType == theInputConnection->getOutputScalarType() )
+      {
+         // Input same as output, nothing for us to do...
+         theByPassFlag = true;
+      }
+      else // Types not equal...
+      {
+         theByPassFlag = false;
+         destroy();
+      }
+   }
+   else // No input source, disable.
+   {
+      theByPassFlag = true;
+   }
+
+   theOutputScalarType = scalarType;
+}
+
+void ossimScalarRemapper::setOutputScalarType(ossimString scalarType)
+{
+   int scalar =
+      ossimScalarTypeLut::instance()->getEntryNumber(scalarType.c_str());
+   
+   if (scalar != ossimLookUpTable::NOT_FOUND)
+   {
+      setOutputScalarType(static_cast<ossimScalarType>(scalar));
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimScalarRemapper ERROR:"
+         << "\nUnknown scalar type:  " << scalarType.c_str() << std::endl;
+   }
+}
+
+void ossimScalarRemapper::initialize()
+{
+   //---
+   // Call the base class initialize.
+   // Note:  This will reset "theInputConnection" if it changed...
+   //---
+   ossimImageSourceFilter::initialize();
+
+   if (theInputConnection)
+   {
+      // Set the bypass flag accordingly...
+      if ( theInputConnection->getOutputScalarType() == 
+           theOutputScalarType )
+      {
+         theByPassFlag = true;
+      }
+      else
+      {
+         theByPassFlag = false;
+      }
+      
+      if (theTile.valid())
+      {
+         //---
+         // Check for:
+         // - bypass
+         // - disabled(!enabled)
+         // - scalar change
+         // - band count change
+         //---
+         if ( theByPassFlag ||
+              !theEnableFlag ||
+              ( theInputConnection->getOutputScalarType() !=
+                theOutputScalarType ) ||
+              ( theInputConnection->getNumberOfOutputBands() !=
+                theTile->getNumberOfBands() ) )
+         {
+            destroy();  // Reallocated first unbypassed getTile.
+         }
+      }
+   }
+}
+
+void ossimScalarRemapper::allocate()
+{
+   destroy();
+
+   if(!theInputConnection) // Nothing to do here.
+   {
+      setInitializedFlag(false);
+      theByPassFlag = true;
+      return;
+   }
+   
+   if (theOutputScalarType == OSSIM_SCALAR_UNKNOWN)
+   {
+      // default to OSSIM_UINT8
+      theOutputScalarType = OSSIM_UINT8;
+   }
+   
+   if(theInputConnection &&
+      (getOutputScalarType() != theInputConnection->getOutputScalarType())&&
+      (theInputConnection->getOutputScalarType() != OSSIM_SCALAR_UNKNOWN)&&
+      (getOutputScalarType() != OSSIM_SCALAR_UNKNOWN))
+   {
+      theByPassFlag = false;
+      
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+
+      // Initialize the tile.
+      theTile->initialize();
+      
+      // Set the base class flags to be initialized and enabled.
+      setInitializedFlag(true);
+      
+   } // End of "if(theInputConnection->isConnected()..."
+   else
+   {
+      // Set to not initialized and disabled.
+      setInitializedFlag(false);
+      theByPassFlag = true;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimScalarRemapper::allocate() DEBUG"
+         << "\ninput scalar:  " << theInputConnection->getOutputScalarType()
+         << "\noutput scalar: " << getOutputScalarType()
+         << "\nenabled:  " << (isSourceEnabled()?"true":"false")
+         << std::endl;
+   }
+}
+
+void ossimScalarRemapper::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property) return;
+
+   if(property->getName() == "Output scalar type")
+   {
+      theOutputScalarType = ossimScalarTypeLut::instance()->
+         getScalarTypeFromString(property->valueToString());
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimScalarRemapper::getProperty(const ossimString& name)const
+{
+   if(name == "Output scalar type")
+   {
+      std::vector<ossimString> scalarNames;
+
+      ossim_int32 tableSize = (ossim_int32)ossimScalarTypeLut::instance()->
+         getTableSize();
+      ossim_int32 idx;
+
+      for(idx = 0; idx < tableSize; ++idx)
+      {
+         scalarNames.push_back(ossimScalarTypeLut::instance()->
+                               getEntryString(idx));
+      }
+      ossimStringProperty* stringProp =
+         new ossimStringProperty("Output scalar type",
+                                 ossimScalarTypeLut::instance()->getEntryString((ossim_int32)theOutputScalarType),
+                                 false,
+                                 scalarNames);
+      stringProp->clearChangeType();
+      stringProp->setReadOnlyFlag(false);
+      stringProp->setCacheRefreshBit();
+      
+      return stringProp;
+   }
+
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimScalarRemapper::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+   propertyNames.push_back("Output scalar type");
+}
+
+bool ossimScalarRemapper::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix) const
+{
+   ossimImageSourceFilter::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           ossimKeywordNames::SCALAR_TYPE_KW,
+           ossimScalarTypeLut::instance()->getEntryString(theOutputScalarType),
+           true);
+
+   return true;
+}
+
+bool ossimScalarRemapper::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   ossimImageSourceFilter::loadState(kwl, prefix);
+
+   if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimScalarRemapper::loadState\n"
+         << " ERROR detected in keyword list!  State not loaded."
+         << std::endl;
+      return false;
+   }
+
+   int scalar = ossimScalarTypeLut::instance()->getEntryNumber(kwl, prefix);
+
+   if (scalar != ossimLookUpTable::NOT_FOUND)
+   {
+      setOutputScalarType(static_cast<ossimScalarType>(scalar));
+   }
+
+   return true;
+}
+
+ossimString ossimScalarRemapper::getOutputScalarTypeString() const
+{
+   return ossimScalarTypeLut::instance()->getEntryString(theOutputScalarType);
+}
+
+void ossimScalarRemapper::propertyEvent(ossimPropertyEvent& event)
+{
+   // if my properties have changed then just initialize
+   //
+   if(event.getObject() == this)
+   {
+      initialize();
+   }
+   else // if an input property has changed just check to see if the number
+   {    // of bands has changed
+      
+      if(!theTile)
+      {
+         initialize();
+      }
+      else
+      {
+         int b = theInputConnection->getNumberOfOutputBands();
+         if((int)theTile->getNumberOfBands() != b)
+         {
+            initialize();
+         }
+      }
+   }
+}
+
+void ossimScalarRemapper::refreshEvent(ossimRefreshEvent& event)
+{
+   // if my properties have changed then just initialize
+   if(event.getObject() == this)
+   {
+      initialize();
+   }
+   else // if an input property has changed just check to see if the number
+   {    // of bands has changed
+      
+      if(!theTile)
+      {
+         initialize();
+      }
+      else
+      {
+         int b = theInputConnection->getNumberOfOutputBands();
+         if((int)theTile->getNumberOfBands() != b)
+         {
+            initialize();
+         }
+      }
+   }
+}
+
+double ossimScalarRemapper::getNullPixelValue(ossim_uint32 band) const
+{
+   if(!isSourceEnabled()||theByPassFlag)
+   {
+      if(theInputConnection)
+      {
+         return theInputConnection->getNullPixelValue(band);
+      }
+   }
+   else if(theTile.valid())
+   {
+      theTile->getNullPix(band);
+   }
+   
+   return ossimGetDefaultNull(theOutputScalarType);
+}
+
+double ossimScalarRemapper::getMinPixelValue(ossim_uint32 band) const
+{
+   if(!isSourceEnabled()||theByPassFlag)
+   {
+      if(theInputConnection)
+      {
+         return theInputConnection->getMinPixelValue(band);
+      }
+   }
+   else if(theTile.valid())
+   {
+      theTile->getMinPix(band);
+   }
+   
+   return ossimGetDefaultMin(theOutputScalarType);
+}
+
+double ossimScalarRemapper::getMaxPixelValue(ossim_uint32 band) const
+{
+   if(!isSourceEnabled()||theByPassFlag)
+   {
+      if(theInputConnection)
+      {
+         return theInputConnection->getMaxPixelValue(band);
+      }
+   }
+   else if(theTile.valid())
+   {
+      theTile->getMaxPix(band);
+   }
+   
+   return ossimGetDefaultMax(theOutputScalarType);
+}
+
+ossimString ossimScalarRemapper::getLongName()const
+{
+   return ossimString("Scalar Remapper, filters between different scalar types.");
+}
+
+ossimString ossimScalarRemapper::getShortName()const
+{
+   return ossimString("Scalar Remapper");
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScalarRemapper.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScalarRemapper.h
new file mode 100644
index 0000000000..f3c3d1a96e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScalarRemapper.h
@@ -0,0 +1,108 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// License:  See top level LICENSE.txt file.
+// 
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declartion for ossimScalarRemapper.
+// This class is used to remap image data from one scalar type to another.
+//
+//*******************************************************************
+//  $Id: ossimScalarRemapper.h,v 1.22 2005/12/20 17:55:24 dburken Exp $
+#ifndef ossimScalarRemapper_HEADER
+#define ossimScalarRemapper_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class OSSIMDLLEXPORT ossimScalarRemapper : public ossimImageSourceFilter
+{
+public:
+   ossimScalarRemapper();
+   ossimScalarRemapper(ossimImageSource* inputSource,
+                       ossimScalarType outputScalarType);
+
+   virtual ~ossimScalarRemapper();
+
+   virtual void initialize();
+
+   virtual ossimString getLongName()  const;
+   virtual ossimString getShortName() const;
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+
+   /**
+    *  Returns the output pixel type of the tile source.  This override the
+    *  base class since it simply returns it's input scalar type which is
+    *  not correct with this object.
+    */
+   virtual ossimScalarType getOutputScalarType() const;
+
+   /**
+    *  Returns the output pixel type of the tile source as a string.
+    */
+   virtual ossimString getOutputScalarTypeString() const;
+   
+   /**
+    *  Sets the output scalar type.
+    */
+   virtual void setOutputScalarType(ossimScalarType scalarType);
+   virtual void setOutputScalarType(ossimString scalarType);
+     
+   /**
+    *  Sets the current resolution level.  Returns true on success, false
+    *  on error.
+    */
+   virtual double getNullPixelValue(ossim_uint32 band)  const;
+   virtual double getMinPixelValue(ossim_uint32 band=0) const;
+   virtual double getMaxPixelValue(ossim_uint32 band=0) const;
+
+   /**
+    *  Method to save the state of an object to a keyword list.
+    *  Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+
+   /**
+    *   Override base class so that a disableSource event does not
+    *   reinitialize the object and enable itself.
+    */
+   virtual void propertyEvent(ossimPropertyEvent& event);
+   virtual void refreshEvent(ossimRefreshEvent& event);   
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+   
+private:
+
+   /**
+    *  Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+
+   /**
+    *  Deletes allocated memory.  Used by both allocate and destructor.
+    */
+   void destroy();
+   
+   double*                     theNormBuf;
+   ossimRefPtr<ossimImageData> theTile;
+   ossimScalarType             theOutputScalarType;
+
+   bool                        theByPassFlag;
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimScalarRemapper_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScaleFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScaleFilter.cpp
new file mode 100644
index 0000000000..f35f2c3984
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScaleFilter.cpp
@@ -0,0 +1,908 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimScaleFilter.cpp,v 1.19 2005/12/25 17:14:57 dburken Exp $
+#include <imaging/tile_sources/ossimScaleFilter.h>
+#include <imaging/filters/ossimFilter.h>
+#include <imaging/filters/ossimDiscreteConvolutionKernel.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <base/common/ossimKeywordNames.h>
+
+RTTI_DEF1(ossimScaleFilter, "ossimScaleFilter", ossimImageSourceFilter);
+
+ossimScaleFilter::ossimScaleFilter()
+   :ossimImageSourceFilter(),
+    theBlankTile(NULL),
+    theTile(NULL),
+    theMinifyFilter(NULL),
+    theMagnifyFilter(NULL),
+    theMinifyFilterType(ossimScaleFilter_NEAREST_NEIGHBOR),
+    theMagnifyFilterType(ossimScaleFilter_NEAREST_NEIGHBOR),
+    theScaleFactor(1.0, 1.0),
+    theInverseScaleFactor(1.0, 1.0),
+    theTileSize(64, 64),
+    theBlurFactor(1.0)
+{
+   theInputRect.makeNan();
+   theMinifyFilter  = new ossimNearestNeighborFilter();
+   theMagnifyFilter = new ossimNearestNeighborFilter();
+}
+
+ossimScaleFilter::ossimScaleFilter(ossimImageSource* inputSource,
+                                   const ossimDpt& scaleFactor)
+   :ossimImageSourceFilter(inputSource),
+    theBlankTile(NULL),
+    theTile(NULL),
+    theMinifyFilter(NULL),
+    theMagnifyFilter(NULL),
+    theMinifyFilterType(ossimScaleFilter_NEAREST_NEIGHBOR),
+    theMagnifyFilterType(ossimScaleFilter_NEAREST_NEIGHBOR),
+    theScaleFactor(scaleFactor),
+    theTileSize(64, 64),
+    theBlurFactor(1.0)
+{
+   theInputRect.makeNan();
+   theMinifyFilter  = new ossimNearestNeighborFilter();
+   theMagnifyFilter = new ossimNearestNeighborFilter();
+}
+
+ossimScaleFilter::~ossimScaleFilter()
+{
+   if(theMinifyFilter)
+   {
+      delete theMinifyFilter;
+      theMinifyFilter = NULL;
+   }
+   
+   if(theMagnifyFilter)
+   {
+      delete theMagnifyFilter;
+      theMagnifyFilter = NULL;
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimScaleFilter::getTile(
+   const ossimIrect& tileRect, ossim_uint32 resLevel)
+{
+   
+   if((!isSourceEnabled())||
+      (!theInputConnection)||
+      ((theScaleFactor.x == 1.0)&&
+       (theScaleFactor.y == 1.0)&&
+       (theBlurFactor == 1.0)))
+   {
+      return ossimImageSourceFilter::getTile(tileRect, resLevel);
+   }
+   if(!theTile.valid())
+   {
+      allocate();
+   }
+
+   if(!theTile)
+   {
+      return ossimImageSourceFilter::getTile(tileRect, resLevel);
+   }
+
+   theTile->makeBlank();
+
+                       
+   ossimIrect imageRect = tileRect*theInverseScaleFactor;
+
+   theTile->setImageRectangle(tileRect);
+   theBlankTile->setImageRectangle(tileRect);
+
+
+   double xSupport;
+   double ySupport;
+
+   getSupport(xSupport, ySupport);
+   
+   ossimIpt deltaPt;
+   deltaPt.x = (ossim_int32)ceil(xSupport);
+   deltaPt.y = (ossim_int32)ceil(ySupport);
+
+   imageRect = ossimIrect(imageRect.ul().x - (deltaPt.x),
+                          imageRect.ul().y - (deltaPt.y),
+                          imageRect.lr().x + (deltaPt.x),
+                          imageRect.lr().y + (deltaPt.y));
+
+   
+   runFilter(imageRect, tileRect);
+   
+   theTile->validate();
+   
+   return theTile;
+}
+
+void ossimScaleFilter::runFilter(const ossimIrect& imageRect,
+                                 const ossimIrect& viewRect)
+{
+   switch(theTile->getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         runFilterTemplate((ossim_uint8)0,
+                           imageRect,
+                           viewRect);
+         break;
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         runFilterTemplate((ossim_uint16)0,
+                           imageRect,
+                           viewRect);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         runFilterTemplate((ossim_sint16)0,
+                           imageRect,
+                           viewRect);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         runFilterTemplate((ossim_uint32)0,
+                           imageRect,
+                           viewRect);
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         runFilterTemplate((ossim_float64)0,
+                           imageRect,
+                           viewRect);
+         break;
+      }
+      case OSSIM_FLOAT:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         runFilterTemplate((ossim_float32)0,
+                           imageRect,
+                           viewRect);
+         break;
+      }
+      default:
+         break;
+   }
+}
+
+template <class T>
+void ossimScaleFilter::runFilterTemplate(T dummy,
+                                         const ossimIrect& imageRect,
+                                         const ossimIrect& viewRect)
+{
+   ossimRefPtr<ossimImageData> inputData =
+      theInputConnection->getTile(imageRect);
+
+   if(!inputData.valid()   ||
+      !inputData->getBuf() ||
+      (inputData->getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return;
+   }
+
+   ossim_int32 h = imageRect.height();
+   ossimRefPtr<ossimImageData> tempData =
+      ossimImageDataFactory::instance()->create(NULL,
+                                                inputData->getScalarType(),
+                                                inputData->getNumberOfBands(),
+                                                viewRect.width(),
+                                                h);
+   tempData->setOrigin(ossimIpt(viewRect.ul().x,
+                                imageRect.ul().y));
+   
+   tempData->initialize();
+   
+   if((theScaleFactor.x != 1.0)||
+      (theBlurFactor != 1.0))
+   {
+      runHorizontalFilterTemplate(dummy,
+                                  inputData,
+                                  tempData);
+      tempData->validate();
+   }
+   else
+   {
+      tempData->loadTile(inputData.get());
+   }
+   
+   if((theScaleFactor.y != 1.0)||
+      (theBlurFactor != 1.0))
+   {
+      runVerticalFilterTemplate(dummy,
+                                tempData,
+                                theTile);
+   }
+   else
+   {
+      theTile->loadTile(tempData.get());
+   }
+   
+   theTile->validate();
+}
+
+ossimIrect ossimScaleFilter::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimIrect result = ossimImageSourceFilter::getBoundingRect(resLevel);
+
+   if(!result.hasNans())
+   {
+      result = ossimIrect(result.ul().x,
+                          result.ul().y,
+                          result.lr().x+1,
+                          result.lr().y+1);
+      result *= theScaleFactor;
+   }
+   
+   return result;
+}
+
+void ossimScaleFilter::setFilterType(ossimScaleFilterType filterType)
+{
+   setFilterType(filterType, filterType);
+}
+
+
+void ossimScaleFilter::setFilterType(ossimScaleFilterType minifyFilterType,
+                                     ossimScaleFilterType magnifyFilterType)
+{
+   if(theMinifyFilter)
+   {
+      delete theMinifyFilter;
+      theMinifyFilter = NULL;
+   }
+   if(theMagnifyFilter)
+   {
+      delete theMagnifyFilter;
+      theMagnifyFilter = NULL;
+   }
+   
+   theMinifyFilterType  = minifyFilterType;
+   theMagnifyFilterType = magnifyFilterType;
+   
+   theMinifyFilter  = createNewFilter(minifyFilterType, theMinifyFilterType);
+   theMagnifyFilter = createNewFilter(magnifyFilterType, theMagnifyFilterType);
+}
+
+ossimFilter* ossimScaleFilter::createNewFilter(ossimScaleFilterType filterType,
+                                               ossimScaleFilterType& result)
+{
+   switch(filterType)
+   {
+   case ossimScaleFilter_NEAREST_NEIGHBOR:
+   {
+      return new ossimNearestNeighborFilter();
+   }
+   case ossimScaleFilter_BOX:
+   {
+      return new ossimBoxFilter();
+   }
+   case ossimScaleFilter_GAUSSIAN:
+   {
+      return new ossimGaussianFilter();
+   }
+   case ossimScaleFilter_CUBIC:
+   {
+      return new ossimCubicFilter();
+   }
+   case ossimScaleFilter_HANNING:
+   {
+      return new ossimHanningFilter();
+   }
+   case ossimScaleFilter_HAMMING:
+   {
+      return new ossimHammingFilter();
+   }
+   case ossimScaleFilter_LANCZOS:
+   {
+      return new ossimLanczosFilter();
+   }
+   case ossimScaleFilter_CATROM:
+   {
+      return new ossimCatromFilter();
+   }
+   case ossimScaleFilter_MITCHELL:
+   {
+      return new ossimMitchellFilter();
+   }
+   case ossimScaleFilter_BLACKMAN:
+   {
+      return new ossimBlackmanFilter();
+   }
+   case ossimScaleFilter_BLACKMAN_SINC:
+   {
+      return new ossimBlackmanSincFilter();
+   }
+   case ossimScaleFilter_BLACKMAN_BESSEL:
+   {
+      return new ossimBlackmanBesselFilter();
+   }
+   case ossimScaleFilter_QUADRATIC:
+   {
+      return new ossimQuadraticFilter();
+   }
+   case ossimScaleFilter_TRIANGLE:
+   {
+      return new ossimTriangleFilter();
+   }
+   case ossimScaleFilter_HERMITE:
+   {
+      return new ossimHermiteFilter();
+   }
+   
+   }
+
+   result = ossimScaleFilter_NEAREST_NEIGHBOR;
+   return new ossimNearestNeighborFilter();
+}
+
+void ossimScaleFilter::setScaleFactor(const ossimDpt& scale)
+{
+   theScaleFactor = scale;
+   if(fabs(theScaleFactor.x) <= FLT_EPSILON)
+   {
+      theScaleFactor.x = 1.0;
+   }
+   if(fabs(theScaleFactor.y) <= FLT_EPSILON)
+   {
+      theScaleFactor.y = 1.0;
+   }
+
+   theInverseScaleFactor.x = 1.0/theScaleFactor.x;
+   theInverseScaleFactor.y = 1.0/theScaleFactor.y;
+}
+
+
+template <class T> void ossimScaleFilter::runHorizontalFilterTemplate(
+   T dummy,
+   const ossimRefPtr<ossimImageData>& input,
+   ossimRefPtr<ossimImageData>& output)
+{
+   ossimIrect viewRect  = output->getImageRectangle();
+   ossimIrect imageRect = input->getImageRectangle();
+   ossim_int32 vw = viewRect.width();
+   ossim_int32 vh = viewRect.height();
+   ossim_int32 iw = imageRect.width();
+   ossimIpt origin(viewRect.ul());
+   ossimIpt imageOrigin(imageRect.ul());
+   ossimIpt inputUl = theInputRect.ul();
+   ossimIpt inputLr = theInputRect.lr();
+   
+   double scale = 0.0;
+   double support = 0.0;
+   ossim_int32 x = 0;
+   ossim_int32 y = 0;
+   ossim_int32 start = 0;
+   ossim_int32 stop  = 0;
+   ossim_int32 kernelIdx = 0;
+   const ossimFilter* filter = getHorizontalFilter();
+   ossim_float64 center = 0.0;
+   ossim_int32 bandIdx = 0;
+   ossim_int32 numberOfBands = theTile->getNumberOfBands();
+   
+   scale = theBlurFactor*ossimMax(1.0/theScaleFactor.x, 1.0);
+   
+   support=scale*filter->getSupport();
+   if (support <= 0.5)
+   {
+      support = 0.5 + FLT_EPSILON;
+      scale = 1.0;
+   }
+   scale=1.0/scale;
+   for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+   {
+      T* imageBuf = (T*)input->getBuf(bandIdx);
+      T* viewBuf  = (T*)output->getBuf(bandIdx);
+      T np        = (T)input->getNullPix(bandIdx);
+      T outNp     = (T)output->getNullPix(bandIdx);
+      T outMinPix = (T)output->getMinPix(bandIdx);
+      T outMaxPix = (T)output->getMaxPix(bandIdx);
+      
+      for(x = 0; x < vw; ++x)
+      {
+         center=(origin.x + x+ .5)/theScaleFactor.x;
+         start=ossimMax((ossim_int32)irint(center-support), (ossim_int32)inputUl.x);
+         stop=ossimMin((ossim_int32)irint(center+support), (ossim_int32)inputLr.x);
+         ossim_int32 delta = stop-start;
+         if (delta <= 0)
+         {
+            break;
+         }
+         vector<double> kernel(delta);
+         double density=0.0;
+         
+         for(kernelIdx = 0; kernelIdx < delta; ++kernelIdx)
+         {
+            double t = scale*(start + kernelIdx -
+                              center + .5);
+            kernel[kernelIdx] = filter->filter(t,
+                                               filter->getSupport());
+            density += kernel[kernelIdx];
+         }
+         if ((density != 0.0) && (density != 1.0))
+         {
+            /*
+              Normalize.
+            */
+            density=1.0/density;
+            for (kernelIdx=0; kernelIdx < delta; kernelIdx++)
+               kernel[kernelIdx]*=density;
+         }
+         ossim_int32 offset       = start  - imageOrigin.x;
+         
+         T* xptr         = imageBuf + offset;
+         T* xCenterptr   = imageBuf + offset;
+         T* outptr       = viewBuf  + x;
+         
+         for(y = 0; y < vh; ++y)
+         {
+            double result = 0.0;
+            density = 0.0;
+            if((*xCenterptr) == np)
+            {
+               *outptr = outNp;
+            }
+            else
+            {
+               for(kernelIdx = 0; kernelIdx < (int)kernel.size(); ++kernelIdx)
+               {
+                  if((*xptr != np)&&
+                     (kernel[kernelIdx] != 0.0))
+                  {
+                     result  += ((double)(*(xptr+kernelIdx))*kernel[kernelIdx]);
+                     density += kernel[kernelIdx];
+                  }
+               }
+               if(density != 0.0)
+               {
+                  result /= density;
+                  
+                  if(result < outMinPix) result = outMinPix;
+                  if(result > outMaxPix) result = outMaxPix;
+                  
+                  *outptr = (T)result;
+               }
+               else
+               {
+                  *outptr = outNp;
+               }
+            }
+            xCenterptr += iw;
+            xptr   += iw;
+            outptr += vw;
+         }
+      }
+   }
+}
+
+template <class T> void ossimScaleFilter::runVerticalFilterTemplate(
+   T dummy,
+   const ossimRefPtr<ossimImageData>& input,
+   ossimRefPtr<ossimImageData>& output)
+{
+   ossimIrect viewRect  = output->getImageRectangle();
+   ossimIrect imageRect = input->getImageRectangle();
+   ossim_int32 vw = viewRect.width();
+   ossim_int32 vh = viewRect.height();
+   ossim_int32 iw = imageRect.width();
+   ossimIpt origin(viewRect.ul());
+   ossimIpt imageOrigin(imageRect.ul());
+   ossimIpt inputUl = theInputRect.ul();
+   ossimIpt inputLr = theInputRect.lr();
+   double scale = 0.0;
+   double support = 0.0;
+   ossim_int32 x = 0;
+   ossim_int32 y = 0;
+   ossim_int32 start = 0;
+   ossim_int32 stop  = 0;
+   ossim_int32 kernelIdx = 0;
+   const ossimFilter* filter = getVerticalFilter();
+   ossim_float64 center = 0.0;
+   ossim_int32 bandIdx = 0;
+   ossim_int32 numberOfBands = theTile->getNumberOfBands();
+   
+   scale = theBlurFactor*ossimMax(1.0/theScaleFactor.y, 1.0);
+   
+   support=scale*filter->getSupport();
+   if (support <= 0.5)
+   {
+      support = .5 + FLT_EPSILON;
+      scale = 1.0;
+   }
+   scale=1.0/scale;
+
+   for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
+   {
+      T* imageBuf = (T*)input->getBuf(bandIdx);
+      T* viewBuf  = (T*)output->getBuf(bandIdx);
+      T np        = (T)input->getNullPix(bandIdx);
+      T outNp     = (T)output->getNullPix(bandIdx);
+      T outMinPix = (T)output->getMinPix(bandIdx);
+      T outMaxPix = (T)output->getMaxPix(bandIdx);
+     
+      for(y = 0; y < vh; ++y)
+      {
+         center=(double) ((y + origin.y+0.5)/theScaleFactor.y);
+         start=ossimMax((ossim_int32)irint(center-support), (ossim_int32)inputUl.y);
+         stop=ossimMin((ossim_int32)irint(center+support), (ossim_int32)inputLr.y);
+         ossim_int32 delta = stop-start;
+         if (delta <= 0)
+         {
+            break;
+         }
+         vector<double> kernel(delta);
+         double density = 0.0;
+         for(kernelIdx = 0; kernelIdx < delta; ++kernelIdx)
+         {
+            kernel[kernelIdx] = filter->filter(scale*(start + kernelIdx - center + .5),
+                                               filter->getSupport());
+            density += kernel[kernelIdx];
+         }
+         if ((density != 0.0) && (density != 1.0))
+         {
+            /*
+              Normalize.
+            */
+            density=1.0/density;
+            for (kernelIdx=0; kernelIdx < delta; kernelIdx++)
+               kernel[kernelIdx]*=density;
+         }
+
+         ossim_int32 offset       = ((start  - imageOrigin.y)*iw);
+         ossim_int32 offsetCenter = ((((ossim_int32)center) - imageOrigin.y)*iw);
+        
+         for(x = 0; x < vw; ++x)
+         {
+            T* yptr         = imageBuf + offset       + x;
+            T* yCenterptr   = imageBuf + offsetCenter + x;
+            double result = 0.0;
+            density = 0.0;
+
+            if((*yCenterptr) == np)
+            {
+               *viewBuf = outNp;
+            }
+            else
+            {
+               for(kernelIdx = 0; kernelIdx < delta; ++kernelIdx)
+               {
+                  if((*yptr != np)&&
+                     (kernel[kernelIdx] != 0.0))
+                  {
+                     result  += ((*yptr)*kernel[kernelIdx]);
+                     density += kernel[kernelIdx];
+                  }
+                  yptr += iw;
+               }
+               if(density != 0.0)
+               {
+                  result /= density;
+                 
+                  if(result < outMinPix) result = outMinPix;
+                  if(result > outMaxPix) result = outMaxPix;
+                 
+                  *viewBuf = (T)result;
+               }
+               else
+               {
+                  *viewBuf = outNp;
+               }
+            }
+            ++viewBuf;
+         }
+      }
+   }
+}
+
+void ossimScaleFilter::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   // Force an allocate next getTile.
+   theTile = NULL;
+   theBlankTile = NULL;
+   theInputRect.makeNan();
+}
+
+void ossimScaleFilter::allocate()
+{
+   theTile      = NULL;
+   theBlankTile = NULL;
+   theInputRect.makeNan();
+
+   if(theInputConnection&&isSourceEnabled())
+   {
+      theTile      = ossimImageDataFactory::instance()->create(this, this);
+      theBlankTile = ossimImageDataFactory::instance()->create(this, this);
+      
+      theTile->initialize();
+
+      theInputRect = theInputConnection->getBoundingRect();
+   }
+}
+
+bool ossimScaleFilter::getImageGeometry(ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   if(theInputConnection)
+   {
+      theInputConnection->getImageGeometry(kwl, prefix);
+
+      ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl,
+                                                                                           prefix);
+
+      if(proj)
+      {
+         ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection,
+                                                proj);
+
+         if(mapProj)
+         {
+            mapProj->applyScale(theInverseScaleFactor, true);
+
+            mapProj->saveState(kwl, prefix);
+         }
+         
+         delete proj;
+
+         return true;
+      }
+   }
+   return false;
+}
+
+ossimIrect ossimScaleFilter::scaleRect(const ossimIrect input,
+                                       const ossimDpt& scaleFactor)const
+{
+   ossimIpt origin(irint(input.ul().x*scaleFactor.x),
+                   irint(input.ul().y*scaleFactor.y));
+   ossim_int32 w = irint(input.width()*scaleFactor.x);
+   ossim_int32 h = irint(input.height()*scaleFactor.y);
+
+   if(w < 1) w = 1;
+   if(h < 1) h = 1;
+   
+   return ossimIrect(origin.x,
+                     origin.y,
+                     origin.x + (w-1),
+                     origin.y + (h-1));
+}
+
+ossimString ossimScaleFilter::getFilterTypeAsString(ossimScaleFilterType type)const
+{
+   switch(type)
+   {
+   case ossimScaleFilter_NEAREST_NEIGHBOR:
+   {
+      return "nearest_neighbor";
+   }
+   case ossimScaleFilter_BOX:
+   {
+      return "box";
+   }
+   case ossimScaleFilter_GAUSSIAN:
+   {
+      return "gaussian";
+   }
+   case ossimScaleFilter_CUBIC:
+   {
+      return "cubic";
+   }
+   case ossimScaleFilter_HANNING:
+   {
+      return "hanning";
+   }
+   case ossimScaleFilter_HAMMING:
+   {
+      return "hamming";
+   }
+   case ossimScaleFilter_LANCZOS:
+   {
+      return "lanczos";
+   }
+   case ossimScaleFilter_MITCHELL:
+   {
+      return "mitchell";
+   }
+   case ossimScaleFilter_CATROM:
+   {
+      return "catrom";
+   }
+   case ossimScaleFilter_BLACKMAN:
+   {
+      return "blackman";
+   }
+   case ossimScaleFilter_BLACKMAN_SINC:
+   {
+      return "blackman_sinc";
+   }
+   case ossimScaleFilter_BLACKMAN_BESSEL:
+   {
+      return "blackman_bessel";
+   }
+   case ossimScaleFilter_QUADRATIC:
+   {
+      return "quadratic";
+   }
+   case ossimScaleFilter_TRIANGLE:
+   {
+      return "triangle";
+   }
+   case ossimScaleFilter_HERMITE:
+   {
+      return "hermite";
+   }
+   }
+
+   return "nearest_neighbor";
+}
+
+ossimScaleFilter::ossimScaleFilterType ossimScaleFilter::getFilterType(const ossimString& type)const
+{
+   ossimString typeUpper = type;
+   typeUpper = typeUpper.upcase();
+
+   if(typeUpper.contains("BOX"))
+   {
+      return ossimScaleFilter_BOX;
+   }
+   else if(typeUpper.contains("NEAREST_NEIGHBOR"))
+   {
+      return ossimScaleFilter_NEAREST_NEIGHBOR;
+   }
+   else if(typeUpper.contains("GAUSSIAN"))
+   {
+      return ossimScaleFilter_GAUSSIAN;
+   }
+   else if(typeUpper.contains("HANNING"))
+   {
+      return ossimScaleFilter_HANNING;
+   }
+   else if(typeUpper.contains("HAMMING"))
+   {
+      return ossimScaleFilter_HAMMING;
+   }
+   else if(typeUpper.contains("LANCZOS"))
+   {
+      return ossimScaleFilter_LANCZOS;
+   }
+   else if(typeUpper.contains("MITCHELL"))
+   {
+      return ossimScaleFilter_MITCHELL;
+   }
+   else if(typeUpper.contains("CATROM"))
+   {
+      return ossimScaleFilter_CATROM;
+   }
+   else if(typeUpper.contains("CUBIC"))
+   {
+      return ossimScaleFilter_CUBIC;
+   }
+   else if(typeUpper.contains("BLACKMAN_BESSEL"))
+   {
+      return ossimScaleFilter_BLACKMAN_BESSEL;
+   }
+   else if(typeUpper.contains("BLACKMAN_SINC"))
+   {
+      return ossimScaleFilter_BLACKMAN_SINC;
+   }
+   else if(typeUpper.contains("BLACKMAN"))
+   {
+      return ossimScaleFilter_BLACKMAN;
+   }
+   else if(typeUpper.contains("QUADRATIC"))
+   {
+      return ossimScaleFilter_QUADRATIC;
+   }
+   else if(typeUpper.contains("TRIANGLE"))
+   {
+      return ossimScaleFilter_TRIANGLE;
+   }
+   else if(typeUpper.contains("HERMITE"))
+   {
+      return ossimScaleFilter_HERMITE;
+   }
+   
+   return ossimScaleFilter_NEAREST_NEIGHBOR;
+}
+
+void ossimScaleFilter::getSupport(double& x, double& y)
+{
+   const ossimFilter* horizontalFilter = getHorizontalFilter();
+   const ossimFilter* verticalFilter   = getVerticalFilter();
+   
+   x = theBlurFactor*ossimMax(1.0/theScaleFactor.x, 1.0)*
+       horizontalFilter->getSupport();
+   y = theBlurFactor*ossimMax(1.0/theScaleFactor.y, 1.0)*
+       verticalFilter->getSupport();
+}
+
+const ossimFilter* ossimScaleFilter::getHorizontalFilter()const
+{
+   if(theScaleFactor.x < 1)
+   {
+      return theMinifyFilter;
+   }
+
+   return theMagnifyFilter;
+}
+
+const ossimFilter* ossimScaleFilter::getVerticalFilter()const
+{
+   if(theScaleFactor.y < 1)
+   {
+      return theMinifyFilter;
+   }
+
+   return theMagnifyFilter;
+}
+
+
+
+bool ossimScaleFilter::saveState(ossimKeywordlist& kwl, const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_X_KW,
+           theScaleFactor.x,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_Y_KW,
+           theScaleFactor.y,
+           true);
+   kwl.add(prefix,
+           "minify_type",
+           getFilterTypeAsString(theMinifyFilterType),
+           true);
+   kwl.add(prefix,
+           "magnify_type",
+           getFilterTypeAsString(theMagnifyFilterType),
+           true);
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimScaleFilter::loadState(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   ossimString scalex  = kwl.find(prefix,
+                                 ossimKeywordNames::SCALE_X_KW);
+   ossimString scaley  = kwl.find(prefix,
+                                  ossimKeywordNames::SCALE_Y_KW);
+   ossimString minify  = kwl.find(prefix,
+                                  "minify_type");
+   ossimString magnify = kwl.find(prefix,
+                                  "magnify_type");
+   
+   theScaleFactor.x = scalex.toDouble();
+   theScaleFactor.y = scaley.toDouble();
+
+   if(fabs(theScaleFactor.x) <= FLT_EPSILON)
+   {
+      theScaleFactor.x = 1.0;
+   }
+   if(fabs(theScaleFactor.y) <= FLT_EPSILON)
+   {
+      theScaleFactor.y = 1.0;
+   }
+
+   theInverseScaleFactor.x = 1.0/theScaleFactor.x;
+   theInverseScaleFactor.y = 1.0/theScaleFactor.y;
+   
+   setFilterType(getFilterType(minify),
+                 getFilterType(magnify));
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScaleFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScaleFilter.h
new file mode 100644
index 0000000000..92dd9aeb21
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimScaleFilter.h
@@ -0,0 +1,179 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimScaleFilter.h,v 1.12 2005/02/11 15:07:34 dburken Exp $
+#ifndef ossimScaleFilter_HEADER
+#define ossimScaleFilter_HEADER
+#include <vector>
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include <matrix/newmat.h>
+#include <matrix/newmatio.h>
+#include <imaging/filters/ossimFilter.h>
+
+/*!
+ */
+class ossimScaleFilter : public ossimImageSourceFilter
+{
+public:
+   enum ossimScaleFilterType
+   {
+      ossimScaleFilter_NEAREST_NEIGHBOR = 0,
+      ossimScaleFilter_BOX              = 1,
+      ossimScaleFilter_GAUSSIAN         = 2,
+      ossimScaleFilter_CUBIC            = 3,
+      ossimScaleFilter_HANNING          = 4,
+      ossimScaleFilter_HAMMING          = 5,
+      ossimScaleFilter_LANCZOS          = 6,
+      ossimScaleFilter_MITCHELL         = 7,
+      ossimScaleFilter_CATROM           = 8,
+      ossimScaleFilter_BLACKMAN         = 9,
+      ossimScaleFilter_BLACKMAN_SINC    = 10,
+      ossimScaleFilter_BLACKMAN_BESSEL  = 11,
+      ossimScaleFilter_QUADRATIC        = 12,
+      ossimScaleFilter_TRIANGLE         = 13,
+      ossimScaleFilter_HERMITE          = 14
+   };
+   
+   ossimScaleFilter();
+   ossimScaleFilter(ossimImageSource* inputSource,
+                    const ossimDpt& scaleFactor);
+   virtual ~ossimScaleFilter();
+   
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                   ossim_uint32 resLevel=0);
+   
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+   virtual bool getImageGeometry(ossimKeywordlist& kwl,
+                                 const char* prefix);
+   virtual void initialize();
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result)const
+      {
+         result.makeNan();
+
+         if(resLevel == 0)
+         {
+            result.x = 1.0;
+            result.y = 1.0;
+         }
+      }
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations)const
+      {
+         decimations.push_back(ossimDpt(1.0, 1.0));
+      }
+   virtual ossim_uint32 getNumberOfDecimationLevels()const
+      {
+         // only full res output since we are scaling
+         //
+         return 1;
+      }
+   void setFilterType(ossimScaleFilterType filterType);
+   void setFilterType(ossimScaleFilterType minifyFilterType,
+                      ossimScaleFilterType magnifyFilterType);
+   
+   void setFilterType(const ossimString& minifyType,
+                      const ossimString& magnifyType)
+      {
+         setFilterType(getFilterType(minifyType),
+                       getFilterType(magnifyType));
+      }
+   void setMinifyFilterType(const ossimString& minifyType)
+      {
+         setMinifyFilterType(getFilterType(minifyType));
+      }
+   void setMagnifyFilterType(const ossimString& magnifyType)
+      {
+         setMagnifyFilterType(getFilterType(magnifyType));
+      }
+   void setMinifyFilterType(ossimScaleFilterType filterType)
+      {
+         setFilterType(filterType,
+                       theMagnifyFilterType);
+      }
+   void setMagnifyFilterType(ossimScaleFilterType filterType)
+      {
+         setFilterType(theMinifyFilterType,filterType);
+      }
+   ossimString getMinifyFilterTypeAsString()const
+      {
+         return getFilterTypeAsString(theMinifyFilterType);
+      }
+   ossimString getMagnifyFilterTypeAsString()const
+      {
+         return getFilterTypeAsString(theMagnifyFilterType);
+      }
+   void setScaleFactor(const ossimDpt& scale);
+   void setBlurFactor(ossim_float64 blur)
+      {
+         theBlurFactor = blur;
+      }
+   ossim_float64 getBlurFactor()const
+      {
+         return theBlurFactor;
+      }
+   const ossimDpt& getScaleFactor()const
+      {
+         return theScaleFactor;
+      }
+   /*!
+    * Saves the state of this object.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0)const;
+
+   /*!
+    * Loads the state of this object.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+   
+protected:
+   void allocate();
+   
+   ossimRefPtr<ossimImageData> theBlankTile;
+   ossimRefPtr<ossimImageData> theTile;
+   ossimFilter*                theMinifyFilter;
+   ossimFilter*                theMagnifyFilter;
+   ossimScaleFilterType        theMinifyFilterType;
+   ossimScaleFilterType        theMagnifyFilterType;
+   ossimDpt                    theScaleFactor;
+   ossimDpt                    theInverseScaleFactor;
+   ossimIpt                    theTileSize;
+   ossimIrect                  theInputRect;
+   ossim_float64               theBlurFactor;
+   
+   template <class T>
+   void runFilterTemplate(T dummy,
+                          const ossimIrect& imageRect,
+                          const ossimIrect& viewRect);
+   template <class T>
+   void runHorizontalFilterTemplate(T dummy,
+                                    const ossimRefPtr<ossimImageData>& input,
+                                    ossimRefPtr<ossimImageData>& output);
+   template <class T>
+   void runVerticalFilterTemplate(T dummy,
+                                  const ossimRefPtr<ossimImageData>& input,
+                                  ossimRefPtr<ossimImageData>& output);
+    void runFilter(const ossimIrect& imageRect,
+                   const ossimIrect& viewRect);
+
+   void getSupport(double& x, double& y);
+   const ossimFilter* getHorizontalFilter()const;
+   const ossimFilter* getVerticalFilter()const;
+   
+   ossimString getFilterTypeAsString(ossimScaleFilterType type)const;
+   ossimScaleFilterType getFilterType(const ossimString& type)const;
+   
+   ossimIrect scaleRect(const ossimIrect input,
+                        const ossimDpt& scaleFactor)const;
+   ossimFilter* createNewFilter(ossimScaleFilterType filterType,
+                                ossimScaleFilterType& result);
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSubImageTileSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSubImageTileSource.cpp
new file mode 100644
index 0000000000..6b15916043
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSubImageTileSource.cpp
@@ -0,0 +1,224 @@
+//*****************************************************************************
+// FILE: ossimSubImageTileSource.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class ossimSubImageTileSource.
+//   This tile source permits specifying an offset that is to be applied to the
+//   tile origin for all getTile() requests. It is intended for converting
+//   a full-image space coordinate to a sub-image coordinate.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimSubImageTileSource.cpp,v 1.17 2005/09/15 12:28:44 gpotts Exp $
+
+#include <imaging/tile_sources/ossimSubImageTileSource.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <imaging/ossimImageData.h>
+
+RTTI_DEF1(ossimSubImageTileSource,
+          "ossimSubImageTileSource",
+          ossimImageSourceFilter);
+
+static const char* SUBIMAGE_OFFSET_X = "offset_x";
+static const char* SUBIMAGE_OFFSET_Y = "offset_y";
+
+ossimSubImageTileSource::ossimSubImageTileSource()
+   : ossimImageSourceFilter(),
+     theSubImageOffset(0, 0),
+     theTile(0)
+{
+}
+
+ossimSubImageTileSource::ossimSubImageTileSource(ossimImageSource* inputSource)
+   : ossimImageSourceFilter(inputSource), theSubImageOffset(0, 0),
+     theTile(0)
+{
+}
+
+ossimSubImageTileSource::ossimSubImageTileSource(ossimImageSource* inputSource,
+                                                 const ossimIpt&   offset)
+   : ossimImageSourceFilter(inputSource), theSubImageOffset(offset),
+     theTile(0)
+{
+}
+
+ossimSubImageTileSource::~ossimSubImageTileSource()
+{
+}
+
+//*****************************************************************************
+//  METHOD: ossimSubImageTileSource::getTile()
+//  
+//*****************************************************************************
+ossimRefPtr<ossimImageData> ossimSubImageTileSource::getTile(
+   const ossimIrect& rect,
+   ossim_uint32  res_level)
+{
+   ossimIpt offset = theSubImageOffset;
+
+   if(res_level)
+   {
+      //***
+      // Determine the offset for the particular rr level requested:
+      //***
+      ossimDpt decimation_factor;
+      theInputConnection->getDecimationFactor(res_level, decimation_factor);
+      
+      if(!decimation_factor.hasNans())
+      {
+         offset = ossimIpt((int)(theSubImageOffset.x*decimation_factor.x + 0.5),
+                           (int)(theSubImageOffset.y*decimation_factor.y + 0.5));
+      }
+      else
+      {
+         offset = theSubImageOffset;
+      }
+   }
+   //
+   // Apply the offset to the requested rect and fetch tile. The tile's origin
+   // needs to be adjusted to reflect the requested origin:
+   //
+   ossimIrect rect_prime (rect - offset);
+
+   ossimRefPtr<ossimImageData> tile =
+      ossimImageSourceFilter::getTile(rect_prime, res_level);
+   
+   if(theTile.valid())
+   {
+      theTile->setImageRectangle(rect_prime);
+
+      if(tile.valid())
+      {
+         theTile->loadTile(tile.get());
+      }
+      else
+      {
+         theTile->makeBlank();
+      }
+   }
+   else
+   {
+      if(tile.valid())
+      {
+         theTile = (ossimImageData*)tile->dup();
+      }
+   }
+   if(theTile.valid())
+   {
+      theTile->setOrigin(rect.ul());
+      theTile->validate();
+   }
+   
+   return theTile;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSubImageTileSource::getBoundingRect()
+//  
+//*****************************************************************************
+ossimIrect ossimSubImageTileSource::getBoundingRect(ossim_uint32 resLevel) const
+{
+   ossimDrect result;
+
+   result.makeNan();
+   if(!theInputConnection)
+      return result;
+   ossimDpt offset = theSubImageOffset;
+   
+   ossimDrect rect (theInputConnection->getBoundingRect(resLevel));
+   if(resLevel)
+   {
+      ossimDpt decimation_factor;
+      theInputConnection->getDecimationFactor(resLevel, decimation_factor);
+
+      if(!decimation_factor.hasNans())
+      {
+         rect*=decimation_factor;
+         offset= ossimDpt(theSubImageOffset.x*decimation_factor.x,
+                          theSubImageOffset.y*decimation_factor.y);
+      }
+   }
+   ossimDrect rect_prime (rect + offset);
+   
+   return rect_prime;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSubImageTileSource::getValidImageVertices()
+//  
+//*****************************************************************************
+void ossimSubImageTileSource::getValidImageVertices(vector<ossimIpt>& vertices,
+                                                    ossimVertexOrdering ordering,
+                                                    ossim_uint32 resLevel) const
+{
+   if(!theInputConnection)
+   {
+      vertices.clear();
+      return;
+   }
+
+   ossimDpt offset (theSubImageOffset);
+
+   theInputConnection->getValidImageVertices(vertices, ordering);
+   vector<ossimIpt>::iterator vertex = vertices.begin();
+
+   while (vertex != vertices.end())
+   {
+      (*vertex) += offset;
+      vertex++;
+   }
+   
+   return;
+}
+
+void ossimSubImageTileSource::initialize()
+{
+   ossimImageSourceFilter::initialize();
+
+   theTile = NULL;
+}
+
+bool ossimSubImageTileSource::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   const char* offset_x = kwl.find(prefix, SUBIMAGE_OFFSET_X);
+   const char* offset_y = kwl.find(prefix, SUBIMAGE_OFFSET_Y);
+
+   if(offset_x)
+   {
+      theSubImageOffset.x = ossimString(offset_x).toLong();
+      
+   }
+   if(offset_y)
+   {
+      theSubImageOffset.y = ossimString(offset_y).toLong();      
+   }
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimSubImageTileSource::saveState(ossimKeywordlist& kwl,
+                                        const char* prefix)const
+{
+   bool result = ossimImageSourceFilter::saveState(kwl, prefix);
+   
+   kwl.add(prefix,
+           SUBIMAGE_OFFSET_X,
+           theSubImageOffset.x,
+           true);
+
+   kwl.add(prefix,
+           SUBIMAGE_OFFSET_Y,
+           theSubImageOffset.y,
+           true);
+   
+   return result;        
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSubImageTileSource.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSubImageTileSource.h
new file mode 100644
index 0000000000..70c27df1f0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimSubImageTileSource.h
@@ -0,0 +1,89 @@
+//*****************************************************************************
+// FILE: ossimSubImageTileSource.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains declaration of class ossimSubImageTileSource.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimSubImageTileSource.h,v 1.11 2005/09/15 12:28:44 gpotts Exp $
+
+#ifndef ossimSubImageTileSource_HEADER
+#define ossimSubImageTileSource_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+/*!****************************************************************************
+ *
+ *  CLASS: ossimSubImageTileSource
+ *
+ *  This tile source permits specifying an offset that is to be applied to the
+ *  tile origin for all getTile() requests. It is intended for converting
+ *  a full-image space coordinate to a sub-image coordinate.
+ *
+ *****************************************************************************/
+class ossimSubImageTileSource : public ossimImageSourceFilter
+{
+public:
+   /*!
+    * Default constructor initializes the sub-image offset to zero.
+    */
+   ossimSubImageTileSource();
+
+   /*!
+    * Constructor accepts an input source pointer. Offset is defaulted to (0,0).
+    */
+   ossimSubImageTileSource(ossimImageSource* inputSource);
+
+   /*!
+    * Constructs with specified input source and offset.
+    */
+   ossimSubImageTileSource(ossimImageSource* inputSource,
+                           const ossimIpt&   offset);
+
+   virtual ~ossimSubImageTileSource();
+   /*!
+    * Permits setting the image's offset relative to the full image space.
+    */
+   void setSubImageOffset(const ossimIpt& offset) { theSubImageOffset=offset; }
+
+   ossimIpt getSubImageOffset()const{ return theSubImageOffset;}
+ 
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                               ossim_uint32  rr_level=0);
+
+   /*!
+    * Fetches the sub-image's bounding rect in FULL-IMAGE SPACE.
+    */
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const;
+   
+   /*!
+    * Fetches the sub-image's valid image vertices in FULL-IMAGE SPACE.
+    */
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const;
+
+   virtual void initialize();
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+private:
+   ossimIpt                    theSubImageOffset;
+   ossimRefPtr<ossimImageData> theTile;
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTableRemapper.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTableRemapper.cpp
new file mode 100644
index 0000000000..9f724e7f01
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTableRemapper.cpp
@@ -0,0 +1,610 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Table remapper class definition.
+//
+// Takes input tile, remaps it through a table, then output tile in the desired
+// scalar type.
+//
+// Two modes one that works on native remap tables, that being of the same
+// scalar type (like ossim_uint8) of the input connection, and another that
+// uses a normalized remap table (more scalar independent).
+//
+//*************************************************************************
+// $Id: ossimTableRemapper.cpp,v 1.20 2005/09/09 14:28:19 gpotts Exp $
+
+#include <imaging/tile_sources/ossimTableRemapper.h>
+#include <base/common/ossimTrace.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/context/ossimNotifyContext.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF1(ossimTableRemapper, "ossimTableRemapper", ossimImageSourceFilter)
+
+static ossimTrace traceDebug("ossimTableRemapper:debug");
+
+static const char* TABLE_TYPE[] = { "UNKNOWN", "NATIVE", "NORMALIZED" };
+
+ossimTableRemapper::ossimTableRemapper(ossimObject* owner)
+   :
+      ossimImageSourceFilter(owner),  // base class
+      theTile(NULL),
+      theTmpTile(NULL),
+      theTable(NULL),
+      theNormBuf(NULL),
+      theTableBinCount(0),
+      theTableBandCount(0),
+      theTableType(ossimTableRemapper::UKNOWN),
+      theInputScalarType(OSSIM_SCALAR_UNKNOWN),
+      theOutputScalarType(OSSIM_SCALAR_UNKNOWN),
+      theTableOwnerFlag(true)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+}
+
+
+ossimTableRemapper::ossimTableRemapper(ossimImageSource* inputSource)
+   :
+      ossimImageSourceFilter      (NULL, inputSource),  // base class
+      theTile(NULL),
+      theTmpTile(NULL),
+      theTable(NULL),
+      theNormBuf(NULL),
+      theTableBinCount(0),
+      theTableBandCount(0),
+      theTableType(ossimTableRemapper::UKNOWN),
+      theInputScalarType(OSSIM_SCALAR_UNKNOWN),
+      theOutputScalarType(OSSIM_SCALAR_UNKNOWN),
+      theTableOwnerFlag(true)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+}
+
+
+ossimTableRemapper::ossimTableRemapper(ossimObject* owner,
+                                       ossimImageSource* inputSource)
+   :
+      ossimImageSourceFilter      (owner, inputSource),  // base class
+      theTile(NULL),
+      theTmpTile(NULL),
+      theTable(NULL),
+      theNormBuf(NULL),
+      theTableBinCount(0),
+      theTableBandCount(0),
+      theTableType(ossimTableRemapper::UKNOWN),
+      theInputScalarType(OSSIM_SCALAR_UNKNOWN),
+      theOutputScalarType(OSSIM_SCALAR_UNKNOWN),
+      theTableOwnerFlag(true)
+{
+   //***
+   // Set the base class "theEnableFlag" to off since no adjustments have been
+   // made yet.
+   //***
+   disableSource();
+}
+
+ossimTableRemapper::~ossimTableRemapper()
+{
+   destroy();
+}
+
+void ossimTableRemapper::destroy()
+{
+   if (theNormBuf)
+   {
+      delete [] theNormBuf;
+      theNormBuf = NULL;
+   }
+   if (theTableOwnerFlag && theTable)
+   {
+      delete [] theTable;
+      theTable = NULL;
+   }
+   theTmpTile = NULL;
+   theTile    = NULL;
+}
+
+void ossimTableRemapper::initialize()
+{
+   //---
+   // Call the base class initialize.
+   // Note:  This will reset "theInputConnection" if it changed...
+   //---
+   ossimImageSourceFilter::initialize();
+   if (theInputConnection)
+   {
+      // Since we override "getOutputScalarType" make sure something's set.
+      if (theOutputScalarType == OSSIM_SCALAR_UNKNOWN)
+      {
+         theOutputScalarType = theInputConnection->getOutputScalarType();
+      }
+
+      if (theTile.valid())
+      {
+         if ( theTile->getNumberOfBands() !=
+              theInputConnection->getNumberOfOutputBands() )
+         {
+            // Wipe everything slick. The next getTile will call allocate.
+            destroy();
+         }
+      }
+   }
+
+   // Nothing else to do for this...
+}
+
+void ossimTableRemapper::allocate(const ossimIrect& rect)
+{
+   //---
+   // It's either first getTile or we've had either a resize, so allocate
+   // needed stuff...
+   //---
+   destroy();
+
+   if (theInputConnection)
+   {
+      ossim_uint32 width  = rect.width();
+      ossim_uint32 height = rect.height();
+      theInputScalarType  = theInputConnection->getOutputScalarType();
+      
+      theTile =
+         ossimImageDataFactory::instance()->create(this,
+                                                   getOutputScalarType(),
+                                                   getNumberOfOutputBands(),
+                                                   width,
+                                                   height);
+
+      theTile->initialize();
+
+      if (theInputScalarType !=  getOutputScalarType() &&
+          theTableType == ossimTableRemapper::NATIVE)
+      {
+         //---
+         // We need a temp tile so we can do two remaps
+         // inputTile->remapTable->tmpTile then
+         // tmpTile->normalize->theTile(unnormalize to new scalar)...
+         //---
+         theTmpTile 
+         = ossimImageDataFactory::instance()->create(this,
+                                                     theInputScalarType,
+                                                     getNumberOfOutputBands(),
+                                                     width,
+                                                     height);
+         theTmpTile->initialize();
+      }
+
+      if (theTableType == ossimTableRemapper::NORMALIZED ||
+          theInputScalarType != theOutputScalarType)
+      {
+         theNormBuf = new ossim_float64[theTile->getSize()];
+      }
+   }
+}
+
+ossimRefPtr<ossimImageData> ossimTableRemapper::getTile(
+   const ossimIrect& tile_rect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   // Fetch tile from pointer from the input source.
+   ossimRefPtr<ossimImageData> inputTile =
+      theInputConnection->getTile(tile_rect, resLevel);
+
+   if (!inputTile.valid())  // Just in case...
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimTableRemapper::getTile ERROR:"
+            << "\nReceived null pointer to tile from input source!"
+            << "\nReturning blank tile.\n";
+      }
+      return inputTile;
+   }
+
+   // Get its status.
+   ossimDataObjectStatus tile_status = inputTile->getDataObjectStatus();
+
+   // Check for remap bypass:
+   if ( !theEnableFlag ||
+        tile_status == OSSIM_NULL ||
+        tile_status == OSSIM_EMPTY )
+   {
+      return inputTile;
+   }
+
+   // OK we have an input tile... and it's not null or empty.
+
+   // Check for first time through or size or band change.
+   if ( !theTile ||  
+        tile_rect.height() != theTile->getHeight() ||
+        tile_rect.width()  != theTile->getWidth()  ||
+        inputTile->getNumberOfBands() != theTile->getNumberOfBands())
+   {
+      allocate(tile_rect);
+   }
+
+   // Set the origin of the output tile.
+   theTile->setImageRectangle(tile_rect);
+   
+   // Think things are good.  Do the real work...
+   if (theTableType == ossimTableRemapper::NATIVE)
+   {
+      // Most efficient case...
+      remapFromNativeTable(inputTile);
+   }
+   else
+   {
+      remapFromNormalizedTable(inputTile);
+   }
+   
+   theTile->validate();
+
+   return theTile;
+}
+
+void ossimTableRemapper::remapFromNativeTable(
+   ossimRefPtr<ossimImageData>& inputTile)
+{
+   switch (theOutputScalarType)
+   {
+      case OSSIM_UCHAR:
+      {
+         remapFromNativeTable(ossim_uint8(0), inputTile);
+         break;
+      }
+      
+      case OSSIM_USHORT11:
+      case OSSIM_USHORT16:
+      {
+         remapFromNativeTable(ossim_uint16(0), inputTile);
+         break;
+      }
+      
+      case OSSIM_SSHORT16:
+      {
+         remapFromNativeTable(ossim_sint16(0), inputTile);
+         break;
+      }
+      
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT:
+      {
+         remapFromNativeTable(ossim_float32(0), inputTile);
+         break;
+      }
+      
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_DOUBLE:
+      {
+         remapFromNativeTable(ossim_float64(0), inputTile);
+         break;
+      }
+      
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         // Shouldn't hit this.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimTableRemapper::remapFromNativeTable"
+            << "\nOutput scalar type is OSSIM_SCALAR_UNKNOWN!\n";
+         break;
+      }
+
+   } // End of "switch (theTableType)"
+}
+
+template <class T> void ossimTableRemapper::remapFromNativeTable(
+   T /* dummy */,
+   ossimRefPtr<ossimImageData>& inputTile)
+{
+   
+   const ossim_uint32 BANDS = theTile->getNumberOfBands();
+   const ossim_uint32 PPB   = theTile->getSizePerBand(); // pixels per band
+
+   //---
+   // NOTE:
+   // If (theTableBandCount == one) that means we only have one band; or,
+   // the user wanted to remap all bands using the same table...
+   //---
+   const ossim_uint32 BAND_OFFSET =
+      (theTableBandCount != 1) ? theTableBinCount: 0;
+
+   const T* rt = reinterpret_cast<T*>(theTable); // remap table (rt)
+   ossimRefPtr<ossimImageData> id = NULL;
+   if (theInputScalarType == theOutputScalarType)
+   {
+      id = theTile;
+   }
+   else
+   {
+      id = theTmpTile;
+   }
+   
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      const T NULL_PIX = static_cast<T>(id->getNullPix(band));
+      const T MIN_PIX  = static_cast<T>(id->getMinPix(band));
+
+      const T* s = static_cast<T*>(inputTile->getBuf(band)); // source (s)
+      T*       d = static_cast<T*>(id->getBuf(band));   // destination (d)
+
+      for (ossim_uint32 pixel = 0; pixel < PPB; ++pixel)
+      {
+         //---
+         // Get the source pixel and use it as an index to the table.
+         // Note Null is always the "0" index, min always the "1".
+         //---
+         T p = s[pixel];
+         if (p == NULL_PIX)  // Null is not always zero (dted).
+         {
+            p = 0;
+         }
+         else
+         {
+            p = (p+1-MIN_PIX);  // If min == 1 we want that to map to index 1.
+         }
+
+         ossim_uint32 table_index = static_cast<ossim_uint32>(p);
+
+         //---
+         // If within range use to index the remap table; else, null.
+         // Note:
+         // There is no min, max range checking on value retrieved from table.
+         // Range checking should be performed when the table is built.
+         //---
+         d[pixel] =(table_index < theTableBinCount) ? rt[table_index] : NULL_PIX;
+      }
+
+      rt += BAND_OFFSET; // Go to next band in the table.
+   }
+
+   if (theInputScalarType != theOutputScalarType)
+   {
+      // Normalize and copy the temp tile to a buffer.
+      id->copyTileToNormalizedBuffer(theNormBuf);
+
+      // Un-normalize and copy the buffer to the destination tile.
+      theTile->copyNormalizedBufferToTile(theNormBuf);
+   }
+}
+
+void ossimTableRemapper::remapFromNormalizedTable(
+   ossimRefPtr<ossimImageData>& inputTile)
+{
+   if (!theNormBuf) // First time...
+   {
+      theNormBuf = new ossim_float64[theTile->getSize()];
+   }
+   
+   // Normalize and copy the source tile to a buffer.
+   inputTile->copyTileToNormalizedBuffer(theNormBuf);
+
+   const ossim_uint32 BANDS = theTile->getNumberOfBands();
+   const ossim_uint32 PPB   = theTile->getSizePerBand(); // pixels per band
+
+   //---
+   // NOTE:
+   // If (theTableBandCount == one) that means we only have one band; or,
+   // the user wanted to remap all bands using the same table...
+   //---
+   const ossim_uint32 BAND_OFFSET = (theTableBandCount == 1) ? 0 : PPB;
+
+   // remap table (rt)
+   ossim_float64* rt = reinterpret_cast<ossim_float64*>(theTable); 
+
+   ossim_float64* buf = theNormBuf;
+   
+   for (ossim_uint32 band = 0; band < BANDS; ++band)
+   {
+      for (ossim_uint32 pixel = 0; pixel < PPB; ++pixel)
+      {
+         // Get the source pixel...
+         ossim_uint32 index
+            = static_cast<ossim_uint32>(buf[pixel]*theTableBinCount+0.5);
+
+         // If within range use to index the remap table; else, null.
+         ossim_float64 p = (index < theTableBinCount) ? rt[index] : 0.0;
+
+         // Range check (in case table bad) and assign to destination pixel.
+         buf[pixel]
+            = (p >= 0.0) ? ( (p <=1.0) ? p : 1) : 0.0;
+      }
+
+      // Go to next band.
+      rt += BAND_OFFSET;
+      buf += PPB;
+   }
+   
+   // Un-normalize and copy the buffer to the destination tile.
+   theTile->copyNormalizedBufferToTile(theNormBuf);
+}
+
+ossimScalarType ossimTableRemapper::getOutputScalarType() const
+{
+   //---
+   // Need to fix this as output scalar can be different from input. (drb)
+   //---
+   return ossimImageSourceFilter::getOutputScalarType();
+   
+//    if (theEnableFlag)
+//    {
+//       return theOutputScalarType;
+//    }
+//    else if (!theEnableFlag && theInputConnection)
+//    {
+//       // disabled return input scalar.
+//       theInputConnection->getOutputScalarType();
+//    }
+
+//    // No connection and disabled!
+//    return theOutputScalarType;
+}
+
+void ossimTableRemapper::setTable(ossim_uint8* table,
+                                  ossim_uint32 table_bin_count,
+                                  ossim_uint32 table_band_count,
+                                  RemapTableType table_type,
+                                  ossimScalarType output_scalar_type,
+                                  bool own_table)
+{
+   // Start with a clean slate...
+   destroy();
+   
+   theTable            = table;
+   theTableBinCount    = table_bin_count;
+   theTableBandCount   = table_band_count;
+   theTableType        = table_type;
+   theOutputScalarType = output_scalar_type;
+
+   if (theInputConnection)
+   {
+      theEnableFlag = true;
+   }
+}
+
+bool ossimTableRemapper::loadState(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+{
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+bool ossimTableRemapper::saveState(ossimKeywordlist& kwl,
+                                   const char* prefix) const
+{
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+ostream& ossimTableRemapper::print(ostream& os) const
+{
+   ossimScalarTypeLut* sl = ossimScalarTypeLut::instance();
+
+   os << "\nossimTableRemapper::print:"
+      << "\ntheTableBinCount:    " << theTableBinCount
+      << "\ntheTableBandCount:   " << theTableBandCount
+      << "\ntheTableType:        " << TABLE_TYPE[theTableType]
+      << "\ntheInputScalarType:  " << (*sl)[theInputScalarType]
+      << "\ntheOutputScalarType: " << (*sl)[theOutputScalarType]
+      << "\ntheTableOwnerFlag:   " << (theTableOwnerFlag ? "true" : "false")
+      << endl;
+   
+   if (theTile.valid())
+   {
+      os << "theTile:\n" << *theTile << endl;
+   }
+   if (theTmpTile.valid())
+   {
+      os << "theTmpTile:\n" << *theTmpTile << endl;
+   }
+
+   switch (theOutputScalarType)
+   {
+      case OSSIM_UCHAR:
+      {
+         dumpTable(ossim_uint8(0), os);
+         break;
+      }
+      
+      case OSSIM_USHORT11:
+      case OSSIM_USHORT16:
+      {
+         dumpTable(ossim_uint16(0), os);
+         break;
+      }
+      
+      case OSSIM_SSHORT16:
+      {
+         dumpTable(ossim_sint16(0), os);
+         break;
+      }
+      
+      case OSSIM_NORMALIZED_FLOAT:
+      case OSSIM_FLOAT:
+      {
+         dumpTable(ossim_float32(0), os);
+         break;
+      }
+      
+      case OSSIM_NORMALIZED_DOUBLE:
+      case OSSIM_DOUBLE:
+      {
+         dumpTable(ossim_float64(0), os);
+         break;
+      }
+      
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         // Shouldn't hit this.
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimTableRemapper::print OSSIM_SCALAR_UNKNOWN!\n";
+         break;
+      }
+
+   } // End of "switch (theTableType)"
+
+   return os;
+}
+
+template <class T> void ossimTableRemapper::dumpTable(T /*dummy*/,
+                                                      ostream& os) const
+{
+   if (!theTable || !theTableBinCount || !theTableBandCount)
+   {
+      return;
+   }
+
+   T* table = reinterpret_cast<T*>(theTable);
+
+   ossim_uint32 table_index = 0;
+   for (ossim_uint32 band = 0; band < theTableBandCount; ++band)
+   {
+      for (ossim_uint32 index = 0; index < theTableBinCount; ++index)
+      {
+         os << "tabel[" << band << "][" << index << "]:  "
+            << static_cast<int>(table[table_index]) << endl;
+         ++table_index;
+      }
+   }
+}
+
+void ossimTableRemapper::setTableOwnership(bool flag)
+{
+   theTableOwnerFlag = flag;
+}
+
+ostream& operator<<(ostream& os, const ossimTableRemapper& tr)
+{
+   return tr.print(os);
+}
+
+// Private to disallow use...
+ossimTableRemapper::ossimTableRemapper(const ossimTableRemapper&)
+{
+}
+
+// Private to disallow use...
+ossimTableRemapper& ossimTableRemapper::operator=(const ossimTableRemapper&)
+{
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTableRemapper.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTableRemapper.h
new file mode 100644
index 0000000000..98b108cf12
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTableRemapper.h
@@ -0,0 +1,154 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  David Burken
+//
+// Description:
+//
+// Table remapper class declaration.
+// 
+// Takes input tile, remaps it through a table, then output tile in the desired
+// scalar type.
+//
+// Two modes one that works on native remap tables, that being of the same
+// scalar type (like ossim_uint8) of the input connection, and another that
+// uses a normalized remap table (more scalar independent).
+//
+//*************************************************************************
+// $Id: ossimTableRemapper.h,v 1.11 2005/02/11 15:07:34 dburken Exp $
+#ifndef ossimTableRemapper_HEADER
+#define ossimTableRemapper_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+class OSSIMDLLEXPORT ossimTableRemapper : public ossimImageSourceFilter
+{
+public:
+   enum RemapTableType
+   {
+      UKNOWN     = 0,
+      NATIVE     = 1,
+      NORMALIZED = 2
+   };
+      
+   
+   ossimTableRemapper(ossimObject* owner=NULL);
+   ossimTableRemapper(ossimImageSource* inputSource);
+   ossimTableRemapper(ossimObject* owner, ossimImageSource* inputSource);
+
+   virtual ~ossimTableRemapper();
+
+   virtual ossimScalarType getOutputScalarType() const;
+    
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+
+
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   
+   virtual ostream& print(ostream& os) const;
+
+   friend ostream& operator << (ostream& os,  const ossimTableRemapper& tr);
+
+protected:
+
+   /**
+    * Method:  setTable
+    * 
+    * @param table      - ossim_uint8* to the table
+    * @param bin_count  - number of bins in the table per band
+    * @param band_count - number of bands in the table
+    * @param table_type - Either ossimTableRemapper::NATIVE or
+    *                     ossimTableRemapper::NORMALIZED  
+    * @param own_table  - If true "this" object will destroy table on
+    *                     destruction. (default == true)
+    *
+    * Note on table:
+    * - It's alway passed in as an "ossim_uint8*" so that on destruction there
+    *   are no complaints.  You can do the math, if your table is really of
+    *   double data type it's:
+    *   "new ossim_uint8[bin_count * band_count * sizeof(double)]"...
+    * - For each band in the table:
+    *   - Table index[0] should always be the null value.
+    *   - Table index[1] should always be the min value.
+    * 
+    * Note on band_count:
+    * - If the "band_count == 1", and the input source has more than one band,
+    *   this implies that the same remap table will be used for all bands.
+    *
+    * Notes on RemapTableType:
+    * - If you want speed, use NATIVE, in which case the remap table scalar
+    *   type should match input source.
+    * - If you want to be able to handle any scalar type with one table, use
+    *   NORMALIZED, in which case, your table values should be
+    *   between 0.0 and 1.0.
+    *
+    * Note on own_table flag:
+    * - If (own_table == true) this object will delete table on destruction.
+    * - If you want to use one table to remap many image chains you might
+    *   build the table and manage the memory yourself; in which case, you
+    *   would set the own_table false; else it will be de
+    */
+   virtual void setTable(ossim_uint8*    table,
+                         ossim_uint32    table_bin_count,
+                         ossim_uint32    table_band_count,
+                         RemapTableType  table_type,
+                         ossimScalarType output_scalar_type,
+                         bool            own_table = true);
+
+   /**
+    * @param flag Should be true if this object is owner of theTable,
+    * false if derived class or user is responsible for allocation,
+    * deletion of "theTable".
+    */
+   virtual void setTableOwnership(bool flag);
+   
+   ossimRefPtr<ossimImageData> theTile;
+   ossimRefPtr<ossimImageData> theTmpTile;
+   ossim_uint8*    theTable;
+   ossim_float64*  theNormBuf;
+   ossim_uint32    theTableBinCount;
+   ossim_uint32    theTableBandCount;
+   RemapTableType  theTableType;
+   ossimScalarType theInputScalarType;
+   ossimScalarType theOutputScalarType;
+   
+   bool theTableOwnerFlag; ///< True if "this" is responsible for memory.
+   
+   void allocate(const ossimIrect& rect);
+   void destroy();
+
+   void remapFromNativeTable(ossimRefPtr<ossimImageData>& inputTile);
+
+   template <class T> void remapFromNativeTable(
+      T dummy,
+      ossimRefPtr<ossimImageData>& inputTile);
+
+   void remapFromNormalizedTable(ossimRefPtr<ossimImageData>& inputTile);
+
+   template <class T> void dumpTable(T dummy, ostream& os) const;
+
+   // Do not allow copy constructor, operator=.
+   ossimTableRemapper(const ossimTableRemapper& tr);
+   ossimTableRemapper& operator=(const ossimTableRemapper& tr);
+   
+   TYPE_DATA
+};
+
+#endif  /* #ifndef ossimTableRemapper_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTopographicCorrectionFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTopographicCorrectionFilter.cpp
new file mode 100644
index 0000000000..e205f346ab
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTopographicCorrectionFilter.cpp
@@ -0,0 +1,1297 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimTopographicCorrectionFilter.cpp,v 1.31 2005/05/09 12:39:40 dburken Exp $
+#include <algorithm>
+#include <sstream>
+#include <imaging/tile_sources/ossimTopographicCorrectionFilter.h>
+#include <imaging/tile_sources/ossimImageToPlaneNormalFilter.h>
+//#include "ossimScalarRemapper.h"
+#include <imaging/tile_sources/ossimScalarRemapper.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <matrix/newmat.h>
+#include <base/data_types/ossimMatrix3x3.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimKeywordNames.h>
+
+static const char* CORRECTION_TYPE_KW        = "correction_type";
+static const char* C_COMPUTED_FLAG_KW        = "c_computed_flag";
+static const char* NDVI_RANGE_KW             = "ndvi_range";
+
+RTTI_DEF1(ossimTopographicCorrectionFilter, "ossimTopographicCorrectionFilter", ossimImageCombiner);
+ossimTopographicCorrectionFilter::ossimTopographicCorrectionFilter()
+   :ossimImageCombiner(NULL, 2, 0, true, false),
+    theTile(NULL),
+//    theScalarRemapper(NULL),
+    theLightSourceElevationAngle(45.0),
+    theLightSourceAzimuthAngle(45.0),
+    theJulianDay(0),
+    theCComputedFlag(false),
+    theTopoCorrectionType(TOPO_CORRECTION_COSINE),
+//    theTopoCorrectionType(TOPO_CORRECTION_MINNAERT),
+    theNdviLowTest(-0.1),
+    theNdviHighTest(0.1)
+{
+//    theScalarRemapper = new ossimScalarRemapper();
+//    theScalarRemapper->setOutputScalarType(OSSIM_NORMALIZED_DOUBLE);
+//    theScalarRemapper->initialize();
+}
+
+ossimTopographicCorrectionFilter::ossimTopographicCorrectionFilter(ossimImageSource* colorSource,
+                                                                   ossimImageSource* elevSource)
+   :ossimImageCombiner(NULL, 2, 0, true, false),
+    theTile(NULL),
+    theLightSourceElevationAngle(45.0),
+    theLightSourceAzimuthAngle(45.0),
+    theJulianDay(0),
+    theCComputedFlag(false),
+    theTopoCorrectionType(TOPO_CORRECTION_COSINE),
+    theNdviLowTest(-0.1),
+    theNdviHighTest(0.1)
+{
+   connectMyInputTo(colorSource);
+   connectMyInputTo(elevSource);
+}
+
+ossimTopographicCorrectionFilter::~ossimTopographicCorrectionFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimTopographicCorrectionFilter::getTile(
+   const  ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface,
+                                                     getInput(0));
+   ossimImageSourceInterface* normalSource  = PTR_CAST(ossimImageSourceInterface,
+                                                       getInput(1));
+
+   if(!isSourceEnabled()||!normalSource||!colorSource)
+   {
+      if(colorSource)
+      {
+         return colorSource->getTile(tileRect, resLevel);
+      }
+   }
+
+   if(!theTile.valid())
+   {
+      allocate();
+   }
+
+   if(!theTile)
+   {
+      return ossimRefPtr<ossimImageData>();
+   }
+
+   long w = tileRect.width();
+   long h = tileRect.height();
+   ossimIpt origin = tileRect.ul();
+
+   theTile->setOrigin(origin);
+   long tileW = theTile->getWidth();
+   long tileH = theTile->getHeight();
+   if((w != tileW)||
+      (h != tileH))
+   {
+      theTile->setWidth(w);
+      theTile->setHeight(h);
+      if((w*h)!=(tileW*tileH))
+      {
+         theTile->initialize();
+      }
+      else
+      {
+         theTile->makeBlank();
+      }
+   }
+   else
+   {
+      theTile->makeBlank();
+   }
+
+   // ossimImageData* inputTile = NULL;
+
+   ossimRefPtr<ossimImageData> normalData = normalSource->getTile(tileRect,
+                                                                  resLevel);
+
+   ossimRefPtr<ossimImageData> colorData  = colorSource->getTile(tileRect,
+                                                                 resLevel);
+
+   if(!colorData.valid() || !normalData.valid())
+   {
+      return theTile;
+   }
+
+   if((normalData->getNumberOfBands() != 3)||
+      (normalData->getScalarType() != OSSIM_DOUBLE)||
+      !normalData->getBuf()||
+      !colorData->getBuf()||
+      (colorData->getDataObjectStatus() == OSSIM_EMPTY)||
+      (normalData->getDataObjectStatus()==OSSIM_EMPTY))
+   {
+      return colorData;
+   }
+
+   executeTopographicCorrection(theTile,
+                                colorData,
+                                normalData);
+   theTile->validate();
+   return theTile;
+}
+
+void ossimTopographicCorrectionFilter::initialize()
+{
+   ossimImageCombiner::initialize();
+
+   // Force an "allocate()" on the first getTile.
+   theTile      = NULL;
+}
+
+void ossimTopographicCorrectionFilter::allocate()
+{
+   if(!getInput(0) || !getInput(1)) return;
+   theBandMapping.clear();
+   if(isSourceEnabled())
+   {
+      // ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+
+      theTile = ossimImageDataFactory::instance()->create(this, this);
+      theTile->initialize();
+
+      int arraySize = theTile->getNumberOfBands();
+      if(theGain.size() > 0)
+      {
+         arraySize = theGain.size();
+      }
+      // we will do a non destructive resize onf the arrays
+      //
+      resizeArrays(arraySize);
+
+      ossimImageSourceInterface* input1 = PTR_CAST(ossimImageSourceInterface,
+                                                   getInput(0));
+      if(input1)
+      {
+         input1->getOutputBandList(theBandMapping);
+         for(ossim_uint32 idx = 0; idx < theBandMapping.size(); ++idx)
+         {
+            if(theBias.size())
+            {
+               if(theBandMapping[idx] >= theBias.size())
+               {
+                  theBandMapping[idx] = theBias.size()-1;
+               }
+            }
+            else
+            {
+               theBandMapping[idx] = 0;
+            }
+         }
+      }
+   }
+
+   computeLightDirection();
+}
+
+void ossimTopographicCorrectionFilter::computeLightDirection()
+{
+   NEWMAT::Matrix m = ossimMatrix3x3::createRotationMatrix(theLightSourceElevationAngle,
+                                                           0.0,
+                                                           theLightSourceAzimuthAngle);
+   NEWMAT::ColumnVector v(3);
+   v[0] = 0;
+   v[1] = 1;
+   v[2] = 0;
+   v = m*v;
+   // reflect Z.  We need the Z pointing up from the surface and not into it.
+   //
+   ossimColumnVector3d d(v[0], v[1], -v[2]);
+   d = d.unit();
+   theLightDirection[0] = d[0];
+   theLightDirection[1] = d[1];
+   theLightDirection[2] = d[2];
+}
+
+void ossimTopographicCorrectionFilter::executeTopographicCorrection(
+   ossimRefPtr<ossimImageData>& outputData,
+   ossimRefPtr<ossimImageData>& colorData,
+   ossimRefPtr<ossimImageData>& normalData)
+{
+   switch(colorData->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      if(theTopoCorrectionType!=TOPO_CORRECTION_MINNAERT)
+      {
+         executeTopographicCorrectionTemplate((ossim_uint8)0,
+                                              outputData,
+                                              colorData,
+                                              normalData);
+      }
+      else
+      {
+         executeTopographicCorrectionMinnaertTemplate((ossim_uint8)0,
+                                                      outputData,
+                                                      colorData,
+                                                      normalData);
+      }
+      break;
+   }
+   case OSSIM_USHORT11:
+   case OSSIM_USHORT16:
+   {
+      if(theTopoCorrectionType!=TOPO_CORRECTION_MINNAERT)
+      {
+         executeTopographicCorrectionTemplate((ossim_uint16)0,
+                                              outputData,
+                                              colorData,
+                                              normalData);
+      }
+      else
+      {
+         executeTopographicCorrectionMinnaertTemplate((ossim_uint16)0,
+                                                      outputData,
+                                                      colorData,
+                                                      normalData);
+      }
+      break;
+   }
+   case OSSIM_SSHORT16:
+   {
+      if(theTopoCorrectionType!=TOPO_CORRECTION_MINNAERT)
+      {
+         executeTopographicCorrectionTemplate((ossim_sint16)0,
+                                              outputData,
+                                              colorData,
+                                              normalData);
+      }
+      else
+      {
+         executeTopographicCorrectionMinnaertTemplate((ossim_sint16)0,
+                                                      outputData,
+                                                      colorData,
+                                                      normalData);
+      }
+      break;
+   }
+   case OSSIM_DOUBLE:
+   case OSSIM_NORMALIZED_DOUBLE:
+   {
+      if(theTopoCorrectionType!=TOPO_CORRECTION_MINNAERT)
+      {
+         executeTopographicCorrectionTemplate((ossim_float64)0,
+                                              outputData,
+                                              colorData,
+                                              normalData);
+      }
+      else
+      {
+         executeTopographicCorrectionMinnaertTemplate((ossim_float64)0,
+                                                      outputData,
+                                                      colorData,
+                                                      normalData);
+      }
+      break;
+   }
+   case OSSIM_FLOAT:
+   case OSSIM_NORMALIZED_FLOAT:
+   {
+      if(theTopoCorrectionType!=TOPO_CORRECTION_MINNAERT)
+      {
+         executeTopographicCorrectionTemplate((ossim_float32)0,
+                                              outputData,
+                                              colorData,
+                                              normalData);
+      }
+      else
+      {
+         executeTopographicCorrectionMinnaertTemplate((ossim_float32)0,
+                                                      outputData,
+                                                      colorData,
+                                                      normalData);
+      }
+      break;
+   }
+   default:
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimTopographicCorrectionFilter::executeTopographicCorrection WARN: Not handling scalar type"
+         << endl;
+   }
+   }
+}
+
+template <class T>
+void ossimTopographicCorrectionFilter::executeTopographicCorrectionTemplate(
+   T dummy,
+   ossimRefPtr<ossimImageData>& outputData,
+   ossimRefPtr<ossimImageData>& colorData,
+   ossimRefPtr<ossimImageData>& normalData)
+{
+   ossim_int32 y = 0;
+   ossim_int32 x = 0;
+   ossim_int32 colorW = colorData->getWidth();
+   ossim_int32 colorH = colorData->getHeight();
+
+   T* colorDataBand = 0;
+   T* outputDataBand = 0;
+   ossim_float64 colorNp = 0;
+   ossim_float64 colorMin = 0;
+   ossim_float64 colorMax = 0;
+   ossim_float64 outputDelta = 0;;
+   ossim_float64 outputMin = 0;
+   ossim_float64 outputMax = 0;
+   ossim_float64 outputNp;
+   double  normalNp = normalData->getNullPix(0);
+   double  LPrime = 0.0;
+   double  LNew   = 0.0;
+   double  dn     = 0.0;
+   double cosineZenith = cosd(90 - theLightSourceElevationAngle);
+
+   if(!colorData->getBuf()||
+      !normalData->getBuf()||
+      (colorData->getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return;
+   }
+   for(ossim_uint32 b = 0; b < outputData->getNumberOfBands();++b)
+   {
+      int mappedBand = theBandMapping[b];
+      double* normalX  = (double*)normalData->getBuf(0);
+      double* normalY  = (double*)normalData->getBuf(1);
+      double* normalZ  = (double*)normalData->getBuf(2);
+      double numerator = cosineZenith + theC[mappedBand];
+      outputNp  = (ossim_float64)outputData->getNullPix(b);
+      outputMin = (ossim_float64)outputData->getMinPix(b);
+      outputMax = (ossim_float64)outputData->getMaxPix(b);
+      outputDelta = outputMax - outputMin;
+      colorDataBand    = (T*)(colorData->getBuf(b));
+      colorNp          = (ossim_float64)(colorData->getNullPix(b));
+      colorMin         = (ossim_float64)(colorData->getMinPix(b));
+      colorMax         = (ossim_float64)(colorData->getMaxPix(b));
+      outputDataBand   = (T*)(outputData->getBuf(b));
+      bool theValuesAreGood = b < theC.size();
+      double c = theC[mappedBand];
+      if(theTopoCorrectionType != TOPO_CORRECTION_COSINE_C)
+      {
+         c = 0;
+      }
+      for(y = 0; y < colorH; ++y)
+      {
+         for(x = 0; x < colorW; ++x)
+         {
+            if((*colorDataBand) != colorNp)
+            {
+               if((*normalX != normalNp)&&
+                  (*normalY != normalNp)&&
+                  (*normalZ != normalNp)&&
+                  theValuesAreGood)
+               {
+
+                  double cosineNewI = ((*normalX)*theLightDirection[0] +
+                                       (*normalY)*theLightDirection[1] +
+                                       (*normalZ)*theLightDirection[2]);
+                  double cosineRatioDenom = (cosineNewI + c);
+                  if((fabs(cosineRatioDenom) > FLT_EPSILON)&&(cosineNewI >= 0.0))
+                  {
+                     double cosineRatio = numerator/cosineRatioDenom;
+
+                     LPrime = theGain[mappedBand]*((ossim_float64)(*colorDataBand)) + theBias[mappedBand];
+
+                     LNew = LPrime*cosineRatio;
+
+                     dn = ((LNew-theBias[mappedBand])/theGain[mappedBand]);
+
+                     if(dn < colorMin) dn = colorMin;
+                     if(dn > colorMax) dn = colorMax;
+
+                     *outputDataBand = (T)(dn);
+                  }
+                  else
+                  {
+                     *outputDataBand = (T)(*colorDataBand);
+                  }
+               }
+               else
+               {
+                  *outputDataBand = (T)(*colorDataBand);
+               }
+            }
+            else
+            {
+               *outputDataBand = (T)outputNp;
+            }
+
+            ++outputDataBand;
+            ++colorDataBand;
+            ++normalX;
+            ++normalY;
+            ++normalZ;
+         }
+      }
+   }
+}
+
+template <class T>
+void ossimTopographicCorrectionFilter::executeTopographicCorrectionMinnaertTemplate(
+   T dummy,
+   ossimRefPtr<ossimImageData>& outputData,
+   ossimRefPtr<ossimImageData>& colorData,
+   ossimRefPtr<ossimImageData>& normalData)
+{
+
+   ossim_int32 y = 0;
+   ossim_int32 x = 0;
+   ossim_int32 colorW = colorData->getWidth();
+   ossim_int32 colorH = colorData->getHeight();
+
+   T* colorDataBand = 0;
+   T* outputDataBand = 0;
+   ossim_float64 colorNp = 0;
+   ossim_float64 colorMin = 0;
+   ossim_float64 colorMax = 0;
+   ossim_float64 outputDelta = 0;;
+   ossim_float64 outputMin = 0;
+   ossim_float64 outputMax = 0;
+   ossim_float64 outputNp;
+   double  normalNp = normalData->getNullPix(0);
+   double  LPrime = 0.0;
+   double  LNew   = 0.0;
+   double  dn     = 0.0;
+
+   if(!colorData->getBuf()||
+      !normalData->getBuf()||
+      (colorData->getDataObjectStatus() == OSSIM_EMPTY))
+   {
+      return;
+   }
+   int maxBands = ossimMin((int)theK.size(), (int)outputData->getNumberOfBands());
+   for(int b = 0; b < maxBands;++b)
+   {
+      int mappedBand = theBandMapping[b];
+      double* normalX  = (double*)normalData->getBuf(0);
+      double* normalY  = (double*)normalData->getBuf(1);
+      double* normalZ  = (double*)normalData->getBuf(2);
+      outputNp  = (ossim_float64)outputData->getNullPix(b);
+      outputMin = (ossim_float64)outputData->getMinPix(b);
+      outputMax = (ossim_float64)outputData->getMaxPix(b);
+      outputDelta = outputMax - outputMin;
+      colorDataBand    = (T*)(colorData->getBuf(b));
+      colorNp          = (ossim_float64)(colorData->getNullPix(b));
+      colorMin         = (ossim_float64)(colorData->getMinPix(b));
+      colorMax         = (ossim_float64)(colorData->getMaxPix(b));
+      outputDataBand   = (T*)(outputData->getBuf(b));
+      for(y = 0; y < colorH; ++y)
+      {
+         for(x = 0; x < colorW; ++x)
+         {
+            if((*colorDataBand) != colorNp)
+            {
+               if((*normalX != normalNp)&&
+                  (*normalY != normalNp)&&
+                  (*normalZ != normalNp))
+               {
+
+//                   if(fabs(*normalZ) < FLT_EPSILON)
+//                   {
+//                      *normalZ = 0.0;
+//                   }
+                  double cosineNewI = (((*normalX)*theLightDirection[0] +
+                                        (*normalY)*theLightDirection[1] +
+                                        (*normalZ)*theLightDirection[2]));
+                  double slopeAngle = acos(*normalZ);
+                  double cosineSlope = cos(slopeAngle);
+                  double k  = theK[mappedBand];
+                  double cosineSlopeKPower = pow(cosineSlope, k);
+                  double denom = pow((double)cosineNewI, k)*cosineSlopeKPower;
+                  double numerator = cosineSlope;
+
+//                  double slopeAngle = asin(*normalZ);
+//                  double tempK = theK[mappedBand]*cosineNewI;
+//                double denom = pow((double)cosineNewI*cosineSlope, theK[mappedBand]);
+//                  double numerator = pow((double)cosineSlope, 1-tempK);
+//                  if((fabs(denom) > .0001)&&(cosineNewI >= 0.0))
+//                  if((cosineNewI >= 0.0) &&fabs(denom) > .000001)
+                  if(fabs(denom) > .00000001)
+                  {
+//                     double cosineRatio = cosineSlope/denom;
+                     double cosineRatio = numerator/denom;
+
+                     LPrime = theGain[mappedBand]*((ossim_float64)(*colorDataBand)) + theBias[mappedBand];
+
+                     LNew = LPrime*cosineRatio;
+
+                     dn = ((LNew-theBias[mappedBand])/theGain[mappedBand]);
+
+                     if(dn < colorMin) dn = colorMin;
+                     if(dn > colorMax) dn = colorMax;
+
+                     *outputDataBand = (T)(dn);
+                  }
+                  else
+                  {
+                     *outputDataBand = (T)(*colorDataBand);
+                  }
+               }
+               else
+               {
+                  *outputDataBand = (T)(*colorDataBand);
+               }
+            }
+            else
+            {
+               *outputDataBand = (T)outputNp;
+            }
+
+            ++outputDataBand;
+            ++colorDataBand;
+            ++normalX;
+            ++normalY;
+            ++normalZ;
+         }
+      }
+   }
+}
+
+
+#if 0
+void ossimTopographicCorrectionFilter::computeC()
+{
+   theCComputedFlag = false;
+   int b = 0;
+   int tileCount = 0;
+   bool done = false;
+   if(theC.size()<1) return;
+
+   for(b = 0; b < (int) theC.size(); ++b)
+   {
+      theC[b] = 0.0;
+   }
+
+
+   theNdviLowTest  = 0.1;
+   theNdviHighTest = 1;
+
+   ossimImageSourceInterface* colorSource  = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   ossimImageSourceInterface* normalSource = PTR_CAST(ossimImageSourceInterface, getInput(1));
+
+   if(!colorSource || !normalSource)
+   {
+      return;
+   }
+   std::vector<ossim2dLinearRegression> linearRegression(theC.size());
+   ossimIrect normalRect = normalSource->getBoundingRect();
+   ossimIrect colorRect  = colorSource->getBoundingRect();
+   ossimIrect clipRect   = normalRect.clipToRect(colorRect);
+   ossimIpt ul = clipRect.ul();
+   ossimIpt lr = clipRect.lr();
+   ossimIpt tileSize(128,128);
+   ossim_int32 tilesHoriz = clipRect.width()/tileSize.x;
+   ossim_int32 tilesVert  = clipRect.height()/tileSize.y;
+
+
+   if(!normalRect.intersects(colorRect))
+   {
+      return;
+   }
+   ossim_int32 maxSize = tilesHoriz*tilesVert;//ossimMin(200, );
+
+   int idx = 0;
+
+   idx = 0;
+   std::vector<int> cosineIBucketCount(10);
+   std::fill(cosineIBucketCount.begin(), cosineIBucketCount.end(), 0);
+   const int maxBucketCount = 1000;
+   bool goodCoefficients = false;
+   long numberOfRuns = 0;
+   while((!goodCoefficients)&&(numberOfRuns < 2))
+   {
+      while((idx < maxSize)&&
+            (!done))
+      {
+         ossim_int32 ty = idx/tilesHoriz;
+         ossim_int32 tx = idx%tilesHoriz;
+
+
+         ossim_int32 x = (ul.x + tx*tileSize.x);
+         ossim_int32 y = (ul.y + ty*tileSize.y);
+
+         ossimIrect requestRect(x,
+                                y,
+                                x+tileSize.x-1,
+                                y+tileSize.y-1);
+
+         ossimRefPtr<ossimImageData> colorData  = colorSource->getTile(requestRect);
+         ossimRefPtr<ossimImageData> normalData = normalSource->getTile(requestRect);
+
+         switch(colorData->getScalarType())
+         {
+         case OSSIM_UCHAR:
+         {
+            addRegressionPointsTemplate((ossim_uint8)0,
+                                        linearRegression, cosineIBucketCount, maxBucketCount, colorData, normalData);
+            break;
+         }
+         case OSSIM_USHORT11:
+         case OSSIM_USHORT16:
+         {
+            addRegressionPointsTemplate((ossim_uint16)0,
+                                        linearRegression, cosineIBucketCount, maxBucketCount, colorData, normalData);
+            break;
+         }
+         case OSSIM_SSHORT16:
+         {
+            addRegressionPointsTemplate((ossim_sint16)0,
+                                        linearRegression, cosineIBucketCount, maxBucketCount, colorData, normalData);
+            break;
+         }
+         case OSSIM_FLOAT:
+         case OSSIM_NORMALIZED_FLOAT:
+         {
+            addRegressionPointsTemplate((ossim_float32)0,
+                                        linearRegression, cosineIBucketCount, maxBucketCount, colorData, normalData);
+            break;
+         }
+         case OSSIM_DOUBLE:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            addRegressionPointsTemplate((ossim_float64)0,
+                                        linearRegression, cosineIBucketCount, maxBucketCount, colorData, normalData);
+            break;
+         }
+         }
+         if(((double)linearRegression[0].getNumberOfPoints()/(double)(maxBucketCount*10.0))>=.7)
+         {
+            done = true;
+         }
+         ++idx;
+      }
+
+      double intercept, m;
+      long numberOfPositiveSlopes=0;
+      for(b=0;b<theC.size();++b)
+      {
+         if(linearRegression[b].getNumberOfPoints()>2)
+         {
+            linearRegression[b].solve();
+            linearRegression[b].getEquation(m, intercept);
+            theC[b] = intercept/m;
+
+            ossimNotify(ossimNotifyLevel_INFO) << "equation for b = " << b <<" is y = " << m << "*x + " << intercept << endl
+                                               << "with c =         " << theC[b] << endl;
+            if(m >=0.0)
+            {
+               numberOfPositiveSlopes++;
+            }
+         }
+      }
+      for(idx = 0; idx < cosineIBucketCount.size(); ++idx)
+      {
+         ossimNotify(ossimNotifyLevel_INFO) << "bucket " << idx << " = " << cosineIBucketCount[idx] << endl;
+      }
+      if(numberOfPositiveSlopes > .5*theC.size())
+      {
+         goodCoefficients = true;
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "ossimTopographicCorrectionFilter::computeC() WARN: not enough positive slopes" << endl
+                                             << "changing test to look for dirt areas" << endl;
+         theNdviLowTest = -1.0;
+         theNdviHighTest = .1;
+         for(b=0;b<theC.size();++b)
+         {
+            linearRegression[b].clear();
+         }
+      }
+      ++numberOfRuns;
+   }
+   theCComputedFlag = true;
+}
+
+template<class T>
+void ossimTopographicCorrectionFilter::addRegressionPointsTemplate(
+   T, //dummy
+   std::vector<ossim2dLinearRegression>& regressionPoints,
+   std::vector<int>& cosineIBucketCount,
+   ossim_int32 maxCountPerBucket,
+   ossimRefPtr<ossimImageData>& colorData,
+   ossimRefPtr<ossimImageData>& normalData)
+{
+   if(!colorData||!normalData)
+   {
+      return;
+   }
+   if((colorData->getDataObjectStatus() == OSSIM_EMPTY)||
+      (!colorData->getBuf())||
+      (!normalData->getBuf())||
+      (normalData->getDataObjectStatus()==OSSIM_EMPTY))
+   {
+      return;
+   }
+
+   ossim_float64* normalBands[3];
+   ossim_float64 normalBandsNp[3];
+   ossim_uint32 count=0;
+   ossim_uint32 b = 0;
+   std::vector<T*> colorBands(colorData->getNumberOfBands());
+   std::vector<T> colorBandsNp(colorData->getNumberOfBands());
+
+   normalBands[0]   = (ossim_float64*)normalData->getBuf(0);
+   normalBands[1]   = (ossim_float64*)normalData->getBuf(1);
+   normalBands[2]   = (ossim_float64*)normalData->getBuf(2);
+   normalBandsNp[0] = normalData->getNullPix(0);
+   normalBandsNp[1] = normalData->getNullPix(1);
+   normalBandsNp[2] = normalData->getNullPix(2);
+
+   for(b=0;b<colorData->getNumberOfBands();++b)
+   {
+      colorBands[b]   = (T*)colorData->getBuf(b);
+      colorBandsNp[b] = (T)colorData->getNullPix(b);
+   }
+
+   ossim_uint32 maxOffset = colorData->getWidth()*colorData->getHeight();
+   ossim_uint32 offset=0;
+   ossim_float64 ndviTest=0.0;
+   ossim_uint32 numberOfTests = 0;
+   if(maxOffset)
+   {
+      maxOffset-=1;
+   }
+
+   ossim_int32 percent = (ossim_int32)(colorData->getWidth()*colorData->getHeight()*.2);
+   offset = 0;
+   ossim_uint32 countPixels = 0;
+   while(offset < maxOffset)
+   {
+      bool nullBandsExist = false;
+      for(b = 0; ((b < colorData->getNumberOfBands())&&(!nullBandsExist));++b)
+      {
+         if(*colorBands[b] == colorBandsNp[b])
+         {
+            nullBandsExist = true;
+         }
+      }
+
+      if((!nullBandsExist)&&
+         (*normalBands[0] != normalBandsNp[0])&&
+         (*normalBands[1] != normalBandsNp[1])&&
+         (*normalBands[2] != normalBandsNp[2]))
+      {
+         if(computeNdvi((T)0,
+                        ndviTest,
+                        offset,
+                        colorBands))
+         {
+            if((ndviTest >= theNdviLowTest) && (ndviTest <= theNdviHighTest))
+            {
+               double cosineI = ((*(normalBands[0]+offset))*theLightDirection[0] +
+                                 (*(normalBands[1]+offset))*theLightDirection[1] +
+                                 (*(normalBands[2]+offset))*theLightDirection[2]);
+               if(cosineI >= 0.0)
+               {
+                  long bucketIdx = (long)(cosineI*cosineIBucketCount.size());
+
+                  // we will try to disperse the normals out and so we don't clump everything
+                  // in one place
+                  //
+                  if(cosineIBucketCount[bucketIdx] < maxCountPerBucket)
+                  {
+                     for(b = 0; b < colorData->getNumberOfBands();++b)
+                     {
+                        regressionPoints[b].addPoint(ossimDpt(cosineI, *(colorBands[b]+offset)));
+                     }
+                     ++cosineIBucketCount[bucketIdx];
+                     ++count;
+                  }
+               }
+            }
+         }
+      }
+      ++offset;
+   }
+}
+#endif
+
+template <class T> bool ossimTopographicCorrectionFilter::computeNdvi(
+   T,
+   ossim_float64& result,
+   ossim_uint32 offset,
+   const std::vector<T*>& bands)const
+{
+   if(bands.size() > 3)
+   {
+      result = (((double)*(bands[3]+offset) - (double)*(bands[2]+offset))/
+                ((double)*(bands[3]+offset) + (double)*(bands[2]+offset)));
+      return true;
+   }
+
+   return false;
+}
+
+void ossimTopographicCorrectionFilter::resizeArrays(ossim_uint32 newSize)
+{
+  if(!getInput(0) || !getInput(1)) return;
+
+
+   vector<double> tempC    = theC;
+   vector<double> tempK    = theK;
+   vector<double> tempBias = theBias;
+   vector<double> tempGain = theGain;
+
+   theC.resize(newSize);
+   theK.resize(newSize);
+   theBias.resize(newSize);
+   theGain.resize(newSize);
+   ossim_uint32 tempIdx = 0;
+   if(tempC.size() > 0 && (theC.size() > 0))
+   {
+      int numberOfElements = ossimMin(tempC.size(), theC.size());
+
+      std::copy(tempC.begin(), tempC.begin()+numberOfElements,
+                theC.begin());
+      std::copy(tempK.begin(), tempK.begin()+numberOfElements,
+                theK.begin());
+      std::copy(tempBias.begin(), tempBias.begin()+numberOfElements,
+                theBias.begin());
+      std::copy(tempGain.begin(), tempGain.begin()+numberOfElements,
+                theGain.begin());
+
+      if(theC.size() > tempC.size())
+      {
+         std::fill(theC.begin()+numberOfElements, theC.end(), (double)0.0);
+         std::fill(theBias.begin()+numberOfElements, theBias.end(), (double)0.0);
+         std::fill(theGain.begin()+numberOfElements, theGain.end(), (double)1.0);
+         for(tempIdx = numberOfElements; tempIdx < theK.size(); ++tempIdx)
+         {
+            theK[tempIdx] = 0.3 + .4*(tempIdx/(double)(theK.size()));
+         }
+      }
+   }
+   else
+   {
+      std::fill(theC.begin(), theC.end(), (double)0.0);
+      std::fill(theBias.begin(), theBias.end(), (double)0.0);
+      std::fill(theGain.begin(), theGain.end(), (double)1.0);
+      for(tempIdx = 0; tempIdx < theK.size(); ++tempIdx)
+      {
+         theK[tempIdx] = 0.3 + .4*(tempIdx/(double)(theK.size()));
+      }
+   }
+}
+
+bool ossimTopographicCorrectionFilter::loadState(const ossimKeywordlist& kwl,
+                                                 const char* prefix)
+{
+
+   ossimString elevAngle      = kwl.find(prefix, ossimKeywordNames::ELEVATION_ANGLE_KW);
+   ossimString azimuthAngle   = kwl.find(prefix, ossimKeywordNames::AZIMUTH_ANGLE_KW);
+   ossimString bands          = kwl.find(prefix, ossimKeywordNames::NUMBER_BANDS_KW);
+   ossimString correctionType = kwl.find(prefix, CORRECTION_TYPE_KW);
+   ossimString julianDay      = kwl.find(prefix, ossimKeywordNames::JULIAN_DAY_KW);
+   ossimString cComputedFlag  = kwl.find(prefix, C_COMPUTED_FLAG_KW);
+   ossimString ndviRange      = kwl.find(prefix, NDVI_RANGE_KW);
+
+   theCComputedFlag = cComputedFlag.toBool();
+   correctionType = correctionType.downcase();
+   int numberOfBands = bands.toInt();
+   theLightSourceElevationAngle = elevAngle.toDouble();
+   theLightSourceAzimuthAngle   = azimuthAngle.toDouble();
+   theJulianDay = julianDay.toDouble();
+
+   if(ndviRange != "")
+   {
+      std::istringstream input(ndviRange.c_str());
+
+      input >> theNdviLowTest >> theNdviHighTest;
+   }
+   if(numberOfBands>0)
+   {
+     theGain.resize(numberOfBands);
+     theBias.resize(numberOfBands);
+     theC.resize(numberOfBands);
+     theK.resize(numberOfBands);
+      for(int b = 0; b < numberOfBands; ++b)
+      {
+         ossimString k    = "k"+ossimString::toString(b);
+         ossimString c    = "c"+ossimString::toString(b);
+         ossimString bias = "bias"+ossimString::toString(b);
+         ossimString gain = "gain"+ossimString::toString(b);
+
+         const char* kValue    = kwl.find(prefix, k);
+         const char* cValue    = kwl.find(prefix, c);
+         const char* biasValue = kwl.find(prefix, bias);
+         const char* gainValue = kwl.find(prefix, gain);
+	 if(kValue)
+	   {
+	     theK[b] = ossimString(kValue).toDouble();
+	   }
+	 else
+	   {
+	     theK[b] = 1.0;
+	   }
+         if(cValue)
+         {
+            theC[b] = ossimString(cValue).toDouble();
+         }
+         else
+         {
+            theC[b] = 0.0;;
+         }
+         if(biasValue)
+         {
+            theBias[b] = ossimString(biasValue).toDouble();
+         }
+         else
+         {
+            theBias[b] = 0.0;
+         }
+         if(gainValue)
+         {
+            theGain[b] = ossimString(gainValue).toDouble();
+         }
+         else
+         {
+            theGain[b] = 1.0;
+         }
+      }
+   }
+
+   if(correctionType.contains("cosine_c"))
+   {
+      theTopoCorrectionType = TOPO_CORRECTION_COSINE_C;
+   }
+   else if(correctionType.contains("minnaert"))
+   {
+      theTopoCorrectionType = TOPO_CORRECTION_MINNAERT;
+   }
+   else
+   {
+      theTopoCorrectionType = TOPO_CORRECTION_COSINE;
+   }
+
+
+   bool result =  ossimImageCombiner::loadState(kwl, prefix);
+
+   computeLightDirection();
+
+   return result;
+}
+
+bool ossimTopographicCorrectionFilter::saveState(ossimKeywordlist& kwl,
+                                                 const char* prefix)const
+{
+   // we can use any of the arrays theC, theBias, or theGain since
+   // they mirror the number of input bands
+   //
+   int numberOfBands = (int)theC.size();
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_BANDS_KW,
+           numberOfBands,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::ELEVATION_ANGLE_KW,
+           theLightSourceElevationAngle,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::AZIMUTH_ANGLE_KW,
+           theLightSourceAzimuthAngle,
+           true);
+
+   kwl.add(prefix,
+           C_COMPUTED_FLAG_KW,
+           (ossim_uint32)theCComputedFlag,
+           true);
+   kwl.add(prefix,
+           NDVI_RANGE_KW,
+           ossimString::toString(theNdviLowTest) +
+           " " + ossimString::toString(theNdviHighTest),
+           true);
+
+   if(theTopoCorrectionType == TOPO_CORRECTION_COSINE_C)
+   {
+      kwl.add(prefix,
+              CORRECTION_TYPE_KW,
+              "cosine_c",
+              true);
+   }
+   else if(theTopoCorrectionType == TOPO_CORRECTION_MINNAERT)
+   {
+      kwl.add(prefix,
+              CORRECTION_TYPE_KW,
+              "minnaert",
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              CORRECTION_TYPE_KW,
+              "cosine",
+              true);
+   }
+
+   for(int b = 0; b < numberOfBands; ++b)
+   {
+      ossimString k    = "k"+ossimString::toString(b);
+      ossimString c    = "c"+ossimString::toString(b);
+      ossimString bias = "bias"+ossimString::toString(b);
+      ossimString gain = "gain"+ossimString::toString(b);
+      kwl.add(prefix,
+              k,
+              theK[b],
+              true);
+      kwl.add(prefix,
+              c,
+              theC[b],
+              true);
+      kwl.add(prefix,
+              bias,
+              theBias[b],
+              true);
+      kwl.add(prefix,
+              gain,
+              theGain[b],
+              true);
+   }
+
+   return ossimImageCombiner::saveState(kwl, prefix);
+}
+
+ossim_uint32 ossimTopographicCorrectionFilter::getNumberOfOutputBands() const
+{
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(colorSource)
+   {
+      return colorSource->getNumberOfOutputBands();
+   }
+   return ossimImageCombiner::getNumberOfOutputBands();
+}
+
+ossimScalarType ossimTopographicCorrectionFilter::getOutputScalarType() const
+{
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(colorSource)
+   {
+      return colorSource->getOutputScalarType();
+   }
+   return ossimImageCombiner::getOutputScalarType();
+}
+
+double ossimTopographicCorrectionFilter::getNullPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(colorSource)
+   {
+      return colorSource->getNullPixelValue(band);
+   }
+   return ossimImageCombiner::getNullPixelValue(band);
+}
+
+double ossimTopographicCorrectionFilter::getMinPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(colorSource)
+   {
+      return colorSource->getMinPixelValue(band);
+   }
+   return ossimImageCombiner::getMinPixelValue(band);
+}
+
+double ossimTopographicCorrectionFilter::getMaxPixelValue(ossim_uint32 band)const
+{
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(colorSource)
+   {
+      return colorSource->getMaxPixelValue(band);
+   }
+   return ossimImageCombiner::getMaxPixelValue(band);
+}
+
+ossimIrect ossimTopographicCorrectionFilter::getBoundingRect(ossim_uint32 resLevel)const
+{
+   ossimIrect result;
+   result.makeNan();
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+
+   if(colorSource)
+   {
+      result = colorSource->getBoundingRect(resLevel);
+   }
+
+   return result;
+}
+
+void ossimTopographicCorrectionFilter::getDecimationFactor(ossim_uint32 resLevel,
+                                                           ossimDpt& result) const
+{
+   result.makeNan();
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+
+   if(colorSource)
+   {
+      colorSource->getDecimationFactor(resLevel,
+                                       result);
+   }
+}
+
+void ossimTopographicCorrectionFilter::getDecimationFactors(vector<ossimDpt>& decimations) const
+{
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(colorSource)
+   {
+      colorSource->getDecimationFactors(decimations);
+   }
+}
+
+ossim_uint32 ossimTopographicCorrectionFilter::getNumberOfDecimationLevels()const
+{
+   ossimImageSourceInterface* colorSource = PTR_CAST(ossimImageSourceInterface, getInput(0));
+   if(colorSource)
+   {
+      return colorSource->getNumberOfDecimationLevels();
+   }
+   return 0;
+}
+
+double ossimTopographicCorrectionFilter::getAzimuthAngle()const
+{
+   return theLightSourceAzimuthAngle;
+}
+
+double ossimTopographicCorrectionFilter::getElevationAngle()const
+{
+   return theLightSourceElevationAngle;
+}
+
+void ossimTopographicCorrectionFilter::setAzimuthAngle(double angle)
+{
+   theLightSourceAzimuthAngle = angle;
+}
+
+void ossimTopographicCorrectionFilter::setElevationAngle(double angle)
+{
+   theLightSourceElevationAngle = angle;
+}
+bool ossimTopographicCorrectionFilter::canConnectMyInputTo(ossim_int32 inputIndex,
+                                                           const ossimConnectableObject* object)const
+{
+   return (object&&
+           ( (inputIndex>=0) && inputIndex < 2)&&
+           PTR_CAST(ossimImageSourceInterface, object));
+
+}
+
+void ossimTopographicCorrectionFilter::connectInputEvent(ossimConnectionEvent& event)
+{
+   initialize();
+}
+
+void ossimTopographicCorrectionFilter::disconnectInputEvent(ossimConnectionEvent& event)
+{
+   initialize();
+}
+
+void ossimTopographicCorrectionFilter::propertyEvent(ossimPropertyEvent& event)
+{
+   initialize();
+}
+
+void ossimTopographicCorrectionFilter::refreshEvent(ossimRefreshEvent& event)
+{
+   initialize();
+}
+
+ossimTopographicCorrectionFilter::ossimTopoCorrectionType ossimTopographicCorrectionFilter::getTopoCorrectionType()const
+{
+   return theTopoCorrectionType;
+}
+
+void ossimTopographicCorrectionFilter::setTopoCorrectionType(ossimTopoCorrectionType topoType)
+{
+   theTopoCorrectionType = topoType;
+}
+
+const std::vector<double>& ossimTopographicCorrectionFilter::getGainValues()const
+{
+   return theGain;
+}
+
+void ossimTopographicCorrectionFilter::setGainValues(const std::vector<double>& gainValues)
+{
+   theGain = gainValues;
+}
+
+const vector<double>& ossimTopographicCorrectionFilter::getBiasValues()const
+{
+   return theBias;
+}
+
+void ossimTopographicCorrectionFilter::setBiasValues(const std::vector<double>& biasValues)
+{
+   theBias = biasValues;
+}
+
+const vector<double>& ossimTopographicCorrectionFilter::getKValues()const
+{
+   return theK;
+}
+
+double ossimTopographicCorrectionFilter::getK(int idx)const
+{
+   if(idx < (int)theK.size())
+   {
+      return theK[idx];
+   }
+   else
+   {
+      return 1.0;
+   }
+}
+
+void ossimTopographicCorrectionFilter::setK(int idx, double value)
+{
+   if(idx < (int)theK.size())
+   {
+      theK[idx] = value;
+   }
+}
+
+void ossimTopographicCorrectionFilter::setKValues(const vector<double>& kValues)
+{
+   theK = kValues;
+}
+
+double ossimTopographicCorrectionFilter::getC(int idx)const
+{
+   if(idx < (int)theC.size())
+   {
+      return theC[idx];
+   }
+   else
+   {
+      return 0.0;
+   }
+}
+
+void ossimTopographicCorrectionFilter::setC(int idx, double value)
+{
+   if(idx < (int)theC.size())
+   {
+      theC[idx] = value;
+   }
+}
+
+void ossimTopographicCorrectionFilter::setCValues(const vector<double>& cValues)
+{
+   theC = cValues;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTopographicCorrectionFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTopographicCorrectionFilter.h
new file mode 100644
index 0000000000..83fff7fe30
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTopographicCorrectionFilter.h
@@ -0,0 +1,225 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimTopographicCorrectionFilter.h,v 1.19 2005/02/11 15:07:34 dburken Exp $
+#ifndef ossimTopographicCorrectionFilter_HEADER
+#define ossimTopographicCorrectionFilter_HEADER
+#include <imaging/tile_sources/ossimImageCombiner.h>
+#include <matrix/newmat.h>
+#include <base/data_types/ossimColumnVector3d.h>
+#include <base/common/events/ossimConnectableObjectListener.h>
+#include <base/common/events/ossimPropertyEvent.h>
+#include <base/misc/ossim2dLinearRegression.h>
+
+class ossimImageData;
+
+class ossimImageSourceConnection;
+class ossimImageToPlaneNormalFilter;
+/*!
+ *
+ * class ossimTopographicCorrectionFilter
+ *
+ * This clas is used to execute terrain correction.  I t requires 2 inputs
+ * where the first input is a multi band data source to correct and the
+ * second is elevation normals used in light incident calculations.
+ *
+ * A sample chain might look like:
+ *
+ *  landsatHandler ---> Cache ---> renderer ---> cache ---------------------------------------
+ *                                                                                            |--> Topo correction filter ---> Output
+ *  ortho mosaic of elevation data----> imageToPlaneNormals --> Cache ---> Renderer -->Cache --
+ *
+ * the ossimImageToPlaneNormalsFilter is used to take a single band elevation source and compute normals at each post.  I suggest that you
+ * set the renderer to use a higher order convolution than just nearest neighbor, maybe Cubic.  This way you have smoother interpolation
+ * as you change zoom levels.
+ *
+ *
+ * Correction Types:
+ *
+ *   Cosine correction:     In order for this to run it does not need any additional informat but the multi band source and
+ *                          an normal calculation input.
+ *
+ *   Cosine-C correction:   In order for this to run it will need theC array populated for each band.  It defaults
+ *                          to 0 forcing a default Cosine correction to take place.
+ *
+ *   Minnaert correction:   In order for this to run it will need theK array populated for each band.  The defaults should work pretty good
+ *  
+ */
+class OSSIMDLLEXPORT ossimTopographicCorrectionFilter : public ossimImageCombiner
+{
+public:
+   enum ossimTopoCorrectionType
+   {
+      TOPO_CORRECTION_COSINE    = 0,
+      TOPO_CORRECTION_COSINE_C  = 1,
+      TOPO_CORRECTION_MINNAERT  = 2
+   };
+   ossimTopographicCorrectionFilter();
+
+   ossimTopographicCorrectionFilter(ossimImageSource* colorSource,
+                                    ossimImageSource* elevSource);
+   
+   virtual ~ossimTopographicCorrectionFilter();
+      
+   ossimRefPtr<ossimImageData> getTile(const  ossimIrect& tileRect,
+                                       ossim_uint32 resLevel=0);
+   
+   virtual ossim_uint32 getNumberOfOutputBands() const;
+
+   virtual ossimScalarType getOutputScalarType() const;
+
+   virtual double getNullPixelValue(ossim_uint32 band=0)const;
+
+   virtual double getMinPixelValue(ossim_uint32 band=0)const;
+
+   virtual double getMaxPixelValue(ossim_uint32 band=0)const;
+
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+
+   virtual void getDecimationFactor(ossim_uint32 resLevel,
+                                    ossimDpt& result) const;
+   
+   virtual void getDecimationFactors(vector<ossimDpt>& decimations) const;
+
+   virtual ossim_uint32 getNumberOfDecimationLevels()const;
+
+   virtual double getAzimuthAngle()const;
+
+   virtual double getElevationAngle()const;
+
+   virtual void setAzimuthAngle(double angle);
+
+   virtual void setElevationAngle(double angle);
+
+   virtual void initialize();
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   bool canConnectMyInputTo(ossim_int32 inputIndex,
+                            const ossimConnectableObject* object)const;
+      
+   virtual void connectInputEvent(ossimConnectionEvent& event);
+
+   virtual void disconnectInputEvent(ossimConnectionEvent& event);
+
+   virtual void propertyEvent(ossimPropertyEvent& event);
+
+   virtual void refreshEvent(ossimRefreshEvent& event);
+
+   virtual ossimTopoCorrectionType getTopoCorrectionType()const;
+
+   virtual void setTopoCorrectionType(ossimTopoCorrectionType topoType);
+
+   const std::vector<double>& getGainValues()const;
+
+   void setGainValues(const std::vector<double>& gainValues);
+  
+   const vector<double>& getBiasValues()const;
+
+   void setBiasValues(const std::vector<double>& biasValues);
+
+   const vector<double>& getKValues()const;
+
+   double getK(int idx)const;
+
+   void setK(int idx, double value);
+
+   void setKValues(const vector<double>& kValues);
+
+   double getC(int idx)const;
+
+   void setC(int idx, double value);
+
+   void setCValues(const vector<double>& cValues);
+   
+   void computeLightDirection();
+
+protected:
+   virtual void allocate();
+   
+   /*!
+    * The result of the illumination equation is stored in
+    * here.  This is populated on each call to getTile.
+    */
+   ossimRefPtr<ossimImageData>   theTile;
+
+   std::vector<ossim_uint32> theBandMapping;
+   
+//   ossimImageToPlaneNormalFilter* theNormalFilter;
+//   ossimScalarRemapper*           theScalarRemapper;
+   std::vector<double> theC;
+   std::vector<double> theK;
+   std::vector<double> theBias;
+   std::vector<double> theGain;
+   
+   /*!
+    * Used for the light vector computation.
+    */
+   double theLightSourceElevationAngle;
+
+   /*!
+    * Used for the light vector computation.
+    */
+   double theLightSourceAzimuthAngle;
+
+   /*!
+    * This is computed from the elevation and
+    * azimuth angles of the light source.
+    */
+   double theLightDirection[3];
+
+   double         theJulianDay;
+   mutable bool   theCComputedFlag;
+   ossimTopoCorrectionType theTopoCorrectionType;   
+   double         theNdviLowTest;
+   double         theNdviHighTest;
+   
+   virtual void executeTopographicCorrection(
+      ossimRefPtr<ossimImageData>& outputData,
+      ossimRefPtr<ossimImageData>& colorData,
+      ossimRefPtr<ossimImageData>& normalData);
+
+   template <class T> void executeTopographicCorrectionTemplate(
+      T dummy,
+      ossimRefPtr<ossimImageData>& outputData,
+      ossimRefPtr<ossimImageData>& colorData,
+      ossimRefPtr<ossimImageData>& normalData);
+
+   template <class T> void executeTopographicCorrectionMinnaertTemplate(
+      T dummy,
+      ossimRefPtr<ossimImageData>& outputData,
+      ossimRefPtr<ossimImageData>& colorData,
+      ossimRefPtr<ossimImageData>& normalData);
+  
+//    virtual void computeC();
+
+//    template<class T>
+//    void addRegressionPointsTemplate(T, //dummy
+//                                     std::vector<ossim2dLinearRegression>& regressionPoints,
+//                                     std::vector<int>& cosineIBucketCount,
+//                                     ossim_int32 maxCountPerBucket,
+//                                     ossimImageData* colorData,
+//                                     ossimImageData* normalData);
+   template <class T> bool computeNdvi(T dummy,
+                                       ossim_float64& result,
+                                       ossim_uint32 offset,
+                                       const std::vector<T*>& bands)const;
+
+   void resizeArrays(ossim_uint32 newSize);
+
+   bool setCCmputedFlag();
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTrimFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTrimFilter.cpp
new file mode 100644
index 0000000000..6f0fbdc3dd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTrimFilter.cpp
@@ -0,0 +1,352 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimTrimFilter.cpp,v 1.3 2005/09/17 19:51:11 dburken Exp $
+#include <imaging/tile_sources/ossimTrimFilter.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/property/ossimNumericProperty.h>
+#include <base/data_types/ossimDpt.h>
+
+static ossimTrace traceDebug("ossimTrimFilter:debug");
+
+RTTI_DEF1(ossimTrimFilter,
+          "ossimTrimFilter",
+          ossimImageSourceFilter);
+
+ossimTrimFilter::ossimTrimFilter()
+   :ossimImageSourceFilter(),
+    theLeftPercent(0.0),
+    theRightPercent(0.0),
+    theTopPercent(0.0),
+    theBottomPercent(0.0)
+{
+   theCutter = new ossimPolyCutter;
+}
+
+ossimRefPtr<ossimImageData> ossimTrimFilter::getTile(
+   const ossimIrect& rect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;
+   }
+
+   if(!theValidVertices.size())
+   {
+      return ossimImageSourceFilter::getTile(rect, resLevel);
+   }
+   
+   ossimRefPtr<ossimImageData> tile =
+      theCutter->getTile(rect, resLevel);
+
+   if(!isSourceEnabled()||!tile.valid())
+   {
+      return tile;
+   }
+   if(tile->getDataObjectStatus() == OSSIM_NULL ||
+      tile->getDataObjectStatus() == OSSIM_EMPTY)
+   {
+      return tile;
+   }
+
+   return theCutter->getTile(rect, resLevel);
+//    theTile->setImageRectangle(rect);
+//    theTile->setDataObjectStatus(OSSIM_FULL);
+
+//    theTile->makeBlank();
+//    ossimIrect boundingRect = getBoundingRect(resLevel);
+//    ossimIrect tileRect     = tile->getImageRectangle();
+//    ossimIrect clipRect     = boundingRect.clipToRect(tileRect);
+
+//    theTile->loadTile(tile->getBuf(),
+//                      tile->getImageRectangle(),
+//                      clipRect,
+//                      OSSIM_BSQ);
+   
+//    theTile->validate();
+   
+}
+
+void ossimTrimFilter::getValidImageVertices(
+   vector<ossimIpt>& validVertices,
+   ossimVertexOrdering ordering,
+   ossim_uint32 resLevel)const
+{
+   ossimImageSource::getValidImageVertices(validVertices,
+                                           ordering,
+                                           resLevel);
+   if(validVertices.size()==4)
+   {
+      ossimDpt averagePt((ossimDpt(validVertices[0])+
+                          ossimDpt(validVertices[1])+
+                          ossimDpt(validVertices[2])+
+                          ossimDpt(validVertices[3]))*.25);
+      ossimDpt averageTop( ( ossimDpt(validVertices[0]+
+                                      validVertices[1])*.5) );
+      ossimDpt averageBottom( ( ossimDpt(validVertices[2]+
+                                         validVertices[3])*.5 ) );
+      ossimDpt averageLeft( (ossimDpt(validVertices[0]+
+                                      validVertices[3])*.5) );
+      ossimDpt averageRight( (ossimDpt(validVertices[1]+
+                                       validVertices[2])*.5) );
+
+      ossimDpt topAxis    = (averageTop-averagePt);
+      ossimDpt rightAxis = (averageRight-averagePt);
+      ossimDpt leftAxis  = (averageLeft-averagePt);
+      ossimDpt bottomAxis = (averageBottom-averagePt);
+
+      double topLen    = topAxis.length();
+      double bottomLen = bottomAxis.length();
+      double rightLen  = rightAxis.length();
+      double leftLen   = leftAxis.length();
+
+      if((topLen > FLT_EPSILON)&&
+         (bottomLen > FLT_EPSILON)&&
+         (leftLen > FLT_EPSILON)&&
+         (rightLen > FLT_EPSILON))
+      {
+         topAxis    = topAxis*(1.0/topLen);
+         bottomAxis = bottomAxis*(1.0/bottomLen);
+         leftAxis   = leftAxis*(1.0/leftLen);
+         rightAxis  = rightAxis*(1.0/rightLen);
+
+         ossim_uint32 idx = 0;
+         ossim_uint32 count = 0;
+         for(idx = 0; idx < validVertices.size(); ++idx)
+         {
+            ossimDpt axis[2];
+            double   axisLen[2];
+            ossimDpt diff  = validVertices[idx]-averagePt;
+            double testLen = (topAxis.x*diff.x+
+                              topAxis.y*diff.y);
+            count = 0;
+            if(testLen >= -FLT_EPSILON)
+            {
+               axis[count]    = topAxis;
+               axisLen[count] = testLen*(1.0-theTopPercent);
+               ++count;
+            }
+
+            if(count < 2)
+            {
+               testLen = (bottomAxis.x*diff.x+
+                          bottomAxis.y*diff.y);
+               if(testLen >= -FLT_EPSILON)
+               {
+                  axis[count]    = bottomAxis;
+                  axisLen[count] = testLen*(1.0-theBottomPercent);
+                  ++count;
+               }
+            }
+            if(count < 2)
+            {
+               testLen = (leftAxis.x*diff.x+
+                          leftAxis.y*diff.y);
+               if(testLen >= -FLT_EPSILON)
+               {
+                  axis[count]    = leftAxis;
+                  axisLen[count] = testLen*(1.0-theLeftPercent);
+                  ++count;
+               }
+            }
+            if(count < 2)
+            {
+               testLen = (rightAxis.x*diff.x+
+                          rightAxis.y*diff.y);
+               if(testLen >= -FLT_EPSILON)
+               {
+                  axis[count]    = rightAxis;
+                  axisLen[count] = testLen*(1.0-theRightPercent);
+                  ++count;
+               }
+            }
+            if(count == 2)
+            {
+               validVertices[idx] = (averagePt + (axis[0]*axisLen[0] +
+                                                  axis[1]*axisLen[1]));
+            }
+         }
+      }
+   }
+//    ossimIrect rect = getBoundingRect();
+
+//    if(ordering == OSSIM_CLOCKWISE_ORDER)
+//    {
+//       validVertices.push_back(rect.ul());
+//       validVertices.push_back(rect.ur());
+//       validVertices.push_back(rect.lr());
+//       validVertices.push_back(rect.ll());
+//    }
+//    else
+//    {
+//       validVertices.push_back(rect.ul());
+//       validVertices.push_back(rect.ll());
+//       validVertices.push_back(rect.lr());
+//       validVertices.push_back(rect.ur());
+//    }
+}
+
+ossimIrect ossimTrimFilter::getBoundingRect(ossim_uint32 resLevel)const
+{
+
+   vector<ossimIpt> validVertices;
+   ossimIrect result;
+   result.makeNan();
+   getValidImageVertices(validVertices, OSSIM_CLOCKWISE_ORDER, resLevel);
+   
+   if(validVertices.size())
+   {
+      result = ossimIrect(validVertices);
+   }
+
+   return result;
+}
+
+void ossimTrimFilter::initialize()
+{
+   if(theInputConnection)
+   {
+      theCutter->disconnectMyInput(0, false, false);
+      if(getInput())
+      {
+         theCutter->connectMyInputTo(0, getInput());
+      }
+      theCutter->initialize();
+      getValidImageVertices(theValidVertices);
+      theCutter->setNumberOfPolygons(1);
+      theCutter->setPolygon(theValidVertices);
+   }
+}
+
+bool ossimTrimFilter::saveState(ossimKeywordlist& kwl,
+                                const char* prefix)const
+{
+   kwl.add(prefix,
+           "left_percent",
+           theLeftPercent,
+           true);
+   kwl.add(prefix,
+           "right_percent",
+           theRightPercent,
+           true);
+   kwl.add(prefix,
+           "top_percent",
+           theTopPercent,
+           true);
+   kwl.add(prefix,
+           "bottom_percent",
+           theBottomPercent,
+           true);
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimTrimFilter::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   const char* leftPerc   = kwl.find(prefix, "left_percent");
+   const char* rightPerc  = kwl.find(prefix, "right_percent");
+   const char* topPerc    = kwl.find(prefix, "top_percent");
+   const char* bottomPerc = kwl.find(prefix, "bottom_percent");
+
+   if(leftPerc)
+   {
+      theLeftPercent = ossimString(leftPerc).toDouble();
+   }
+   if(rightPerc)
+   {
+      theRightPercent = ossimString(rightPerc).toDouble();
+   }
+   if(topPerc)
+   {
+      theTopPercent = ossimString(topPerc).toDouble();
+   }
+   if(bottomPerc)
+   {
+      theBottomPercent = ossimString(bottomPerc).toDouble();
+   }
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+ossimRefPtr<ossimProperty> ossimTrimFilter::getProperty(const ossimString& name)const
+{
+   ossimProperty* prop = 0;
+   if(name == "left_percent")
+   {
+      prop = new ossimNumericProperty(name,
+                                      ossimString::toString(theLeftPercent),
+                                      0.0, 1.0);
+      prop->setFullRefreshBit();
+   }
+   else if(name == "right_percent")
+   {
+      prop = new ossimNumericProperty(name,
+                                      ossimString::toString(theRightPercent),
+                                      0.0, 1.0);
+      prop->setFullRefreshBit();
+   }
+   else if(name == "top_percent")
+   {
+      prop = new ossimNumericProperty(name,
+                                      ossimString::toString(theTopPercent),
+                                      0.0, 1.0);
+      prop->setFullRefreshBit();
+   }
+   else if(name == "bottom_percent")
+   {
+      prop = new ossimNumericProperty(name,
+                                      ossimString::toString(theBottomPercent),
+                                      0.0, 1.0);
+      prop->setFullRefreshBit();
+   }
+
+   if(prop) return prop;
+   
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimTrimFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property.valid())return;
+   ossimString name = property->getName();
+   
+   if(name == "left_percent")
+   {
+      theLeftPercent = property->valueToString().toDouble();
+   }
+   else if(name == "right_percent")
+   {
+      theRightPercent = property->valueToString().toDouble();
+   }
+   else if(name == "top_percent")
+   {
+      theTopPercent = property->valueToString().toDouble();
+   }
+   else if(name == "bottom_percent")
+   {
+      theBottomPercent = property->valueToString().toDouble();
+   }
+   else
+   {
+      return ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+void ossimTrimFilter::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   propertyNames.push_back("left_percent");
+   propertyNames.push_back("right_percent");
+   propertyNames.push_back("top_percent");
+   propertyNames.push_back("bottom_percent");
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTrimFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTrimFilter.h
new file mode 100644
index 0000000000..46ef8a091f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimTrimFilter.h
@@ -0,0 +1,70 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimTrimFilter.h,v 1.2 2005/09/15 12:28:44 gpotts Exp $
+#ifndef ossimTrimFilter_HEADER
+#define ossimTrimFilter_HEADER
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+#include "ossimPolyCutter.h"
+
+class ossimTrimFilter : public ossimImageSourceFilter
+{
+public:
+   ossimTrimFilter();
+
+   virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0)const;
+   virtual void getValidImageVertices(vector<ossimIpt>& validVertices,
+                                      ossimVertexOrdering ordering=OSSIM_CLOCKWISE_ORDER,
+                                      ossim_uint32 resLevel=0)const;
+
+   ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect,
+                                       ossim_uint32 resLevel=0);
+
+   virtual void initialize();
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+   
+
+   virtual ossimRefPtr<ossimProperty> getProperty(
+      const ossimString& name)const;
+
+   /**
+    * Set property.
+    *
+    * @param property Property to set if property->getName() matches a
+    * property name of this object.
+    */
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+
+   /**
+    * Adds this objects properties to the list.
+    *
+    * @param propertyNames Array to add to.
+    *
+    * @note This method does not clear propertyNames prior to adding it's
+    * names.
+    */
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+protected:
+   double theLeftPercent;
+   double theRightPercent;
+   double theTopPercent;
+   double theBottomPercent;
+   std::vector<ossimIpt>  theValidVertices;
+   ossimRefPtr<ossimPolyCutter> theCutter;
+   
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimTrimFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimValueAssignImageSourceFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimValueAssignImageSourceFilter.cpp
new file mode 100644
index 0000000000..8db7307535
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimValueAssignImageSourceFilter.cpp
@@ -0,0 +1,377 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimValueAssignImageSourceFilter.cpp,v 1.6 2005/02/11 15:07:34 dburken Exp $
+#include <imaging/tile_sources/ossimValueAssignImageSourceFilter.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+RTTI_DEF1(ossimValueAssignImageSourceFilter,
+          "ossimValueAssignImageSourceFilter",
+          ossimImageSourceFilter);
+
+ossimValueAssignImageSourceFilter::ossimValueAssignImageSourceFilter(ossimObject* owner)
+   :ossimImageSourceFilter(owner),
+    theAssignType(ossimValueAssignType_GROUP),
+    theTile(NULL)
+{
+}
+
+ossimValueAssignImageSourceFilter::~ossimValueAssignImageSourceFilter()
+{
+}
+
+ossimRefPtr<ossimImageData> ossimValueAssignImageSourceFilter::getTile(
+   const ossimIrect& tileRect,
+   ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+   {
+      return NULL;  // This filter requires an input.
+   }
+   
+   ossimRefPtr<ossimImageData> inputTile =
+      theInputConnection->getTile(tileRect, resLevel);
+   
+   if(!isSourceEnabled() || !inputTile.valid())
+   {
+      return inputTile;
+   }
+
+   if(!theTile.valid())
+   {
+      allocate(); // First time through...
+   }
+   
+   if (!theTile.valid()) // throw exeption...
+   {
+      return inputTile;
+   }
+
+   // Set the origin, resize if needed of the output tile.
+   theTile->setImageRectangle(tileRect);
+
+   if( inputTile->getDataObjectStatus() == OSSIM_NULL ||
+       inputTile->getDataObjectStatus() == OSSIM_EMPTY )
+   {
+      theTile->makeBlank();
+      return theTile;
+   }
+
+   if(!inputTile->getBuf())
+   {
+      theTile->makeBlank();
+   }
+   else
+   {
+      theTile->loadTile(inputTile.get());
+   }
+
+   switch(inputTile->getScalarType())
+   {
+      case OSSIM_UCHAR:
+      {
+         executeAssign(static_cast<ossim_uint8>(0),
+                       theTile);
+         break;
+      }
+      case OSSIM_FLOAT: 
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         executeAssign(static_cast<float>(0),
+                       theTile);
+         break;
+      }
+      case OSSIM_USHORT16:
+      case OSSIM_USHORT11:
+      {
+         executeAssign(static_cast<ossim_uint16>(0),
+                       theTile);
+         break;
+      }
+      case OSSIM_SSHORT16:
+      {
+         executeAssign(static_cast<ossim_sint16>(0),
+                       theTile);
+         break;
+      }
+      case OSSIM_DOUBLE:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         executeAssign(static_cast<double>(0),
+                       theTile);
+         break;
+      }
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "ossimValueAssignImageSourceFilter::getTile WARN: Scalar type = " << theTile->getScalarType()
+                                            << " Not supported!" << std::endl;
+         break;
+      }
+   }
+
+   theTile->validate();
+   
+   return theTile;
+}
+
+void ossimValueAssignImageSourceFilter::setInputOutputValues(const vector<double>& inputValues,
+                                                             const vector<double>& outputValues)
+{
+   theInputValueArray  = inputValues;
+   theOutputValueArray = outputValues;
+
+   validateArrays();
+}
+
+void ossimValueAssignImageSourceFilter::validateArrays()
+{
+   if(theOutputValueArray.size() != theInputValueArray.size())
+   {
+      ossim_uint32 index = std::min(theOutputValueArray.size(),
+                              theInputValueArray.size());
+      
+      vector<double> copyVector(theOutputValueArray.begin(),
+                                theOutputValueArray.begin() + index);
+
+      theOutputValueArray = copyVector;
+
+      for(ossim_uint32 index2 = index; index < theInputValueArray.size(); ++index)
+      {
+         theOutputValueArray.push_back(theInputValueArray[index2]);
+      }
+   }
+}
+
+template <class T> void ossimValueAssignImageSourceFilter::executeAssign(
+   T,
+   ossimRefPtr<ossimImageData>& data)
+{
+   if(!theInputValueArray.size()) return;
+   
+   if(theAssignType == ossimValueAssignType_SEPARATE)
+   {
+      executeAssignSeparate(static_cast<T>(0), data);
+   }
+   else
+   {
+      executeAssignGroup(static_cast<T>(0), data);      
+   }
+}
+
+template <class T> void ossimValueAssignImageSourceFilter::executeAssignSeparate(
+   T,
+   ossimRefPtr<ossimImageData>& data)
+{
+   ossim_uint32 numberOfBands = std::min((ossim_uint32)data->getNumberOfBands(),
+                                   (ossim_uint32)theInputValueArray.size());
+   ossim_uint32 maxOffset     = data->getWidth()*data->getHeight();
+   
+   for(ossim_uint32 band = 0; band<numberOfBands; ++band)
+   {
+      T* buf      = static_cast<T*>(data->getBuf(band));
+      T  inValue  = static_cast<T>(theInputValueArray[band]);
+      T  outValue = static_cast<T>(theOutputValueArray[band]);
+      for(ossim_uint32 count = 0; count < maxOffset; ++count)
+      {
+         if(*buf == inValue)
+         {
+            *buf = outValue;
+         }
+         ++buf;
+      }
+   }
+}
+
+template <class T> void ossimValueAssignImageSourceFilter::executeAssignGroup(
+   T,
+   ossimRefPtr<ossimImageData>& data)
+{
+   ossim_uint32 numberOfBands = std::min((ossim_uint32)data->getNumberOfBands(),
+                                   (ossim_uint32)theInputValueArray.size());
+   ossim_uint32 maxOffset     = data->getWidth()*data->getHeight();
+   ossim_uint32 band = 0;
+   bool equalFlag = false;
+
+   T** bufArray = new T*[data->getNumberOfBands()];
+   for(band = 0; band < data->getNumberOfBands(); ++band)
+   {
+      bufArray[band] = static_cast<T*>(data->getBuf(band));
+   }
+   
+   for(ossim_uint32 offset = 0; offset < maxOffset; ++offset)
+   {
+      equalFlag = true;
+      
+      for(band = 0; band<numberOfBands; ++band)
+      {
+         if(bufArray[band][offset] != theInputValueArray[band])
+         {
+            equalFlag = false;
+         }
+      }
+      if(equalFlag)
+      {
+         for(band = 0; band<numberOfBands; ++band)
+         {
+            bufArray[band][offset] = static_cast<T>(theOutputValueArray[band]);
+         }
+      }
+   }
+
+   delete [] bufArray;
+}
+
+void ossimValueAssignImageSourceFilter::initialize()
+{
+   // Base class will recapture "theInputConnection".
+   ossimImageSourceFilter::initialize();
+}
+
+void ossimValueAssignImageSourceFilter::allocate()
+{   
+   theTile = NULL;
+
+   if(theInputConnection)
+   {
+      ossimImageDataFactory* idf = ossimImageDataFactory::instance();
+      
+      theTile = idf->create(this,
+                            this);
+      
+      theTile->initialize();
+   }
+}
+
+bool ossimValueAssignImageSourceFilter::saveState(ossimKeywordlist& kwl,
+                                                  const char* prefix)const
+{
+   ossim_uint32 index = 0;
+   for(index =0; index < theInputValueArray.size(); ++index)
+   {
+      ossimString in  = ("input_band" + ossimString::toString(index));
+      ossimString out = ("output_band" + ossimString::toString(index));
+
+      kwl.add(prefix,
+              in.c_str(),
+              theInputValueArray[index],
+              true);
+      kwl.add(prefix,
+              out.c_str(),
+              theOutputValueArray[index],
+              true);
+   }
+   if(theAssignType ==  ossimValueAssignType_SEPARATE)
+   {
+      kwl.add(prefix,
+              "assign_type",
+              "separate",
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              "assign_type",
+              "group",
+              true);
+   }
+           
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+/*!
+ * Method to the load (recreate) the state of an object from a keyword
+ * list.  Return true if ok or false on error.
+ */
+bool ossimValueAssignImageSourceFilter::loadState(const ossimKeywordlist& kwl,
+                                                  const char* prefix)
+{
+   
+   ossimString inRegExpression =  ossimString("^(") +
+                                  ossimString(prefix) +
+                                  "input_band[0-9]+)";
+   ossimString outRegExpression =  ossimString("^(") +
+                                   ossimString(prefix) +
+                                   "output_band[0-9]+)";
+   ossim_uint32 numberOfInputs  = kwl.getNumberOfSubstringKeys(inRegExpression);
+   ossim_uint32 numberOfOutputs = kwl.getNumberOfSubstringKeys(outRegExpression);
+   ossim_uint32 index = 0;
+   ossim_uint32 currentIndex = 0;
+   
+   theInputValueArray.clear();
+   theOutputValueArray.clear();
+
+   while(index < numberOfInputs)
+   {
+      const char* value = kwl.find(prefix,
+                                   (ossimString("input_band") +
+                                    ossimString::toString(currentIndex)).c_str()
+                                   );
+      if(value)
+      {
+         theInputValueArray.push_back(ossimString(value).toDouble());
+         ++index;
+      }
+      ++currentIndex;
+   }
+   index = 0;
+   currentIndex = 0;
+   while(index < numberOfOutputs)
+   {
+      const char* value = kwl.find(prefix,
+                                   (ossimString("output_band") +
+                                    ossimString::toString(currentIndex)).c_str()
+                                   );
+      if(value)
+      {
+         theOutputValueArray.push_back(ossimString(value).toDouble());
+         ++index;
+      }
+      ++currentIndex;
+   }
+   validateArrays();
+   
+   const char* assignType = kwl.find(prefix, "assign_type");
+   if(assignType)
+   {
+      if(ossimString(assignType).trim().downcase() == "separate")
+      {
+         theAssignType = ossimValueAssignType_SEPARATE;
+      }
+      else
+      {
+         theAssignType = ossimValueAssignType_GROUP;
+      }
+   }
+   else
+   {
+      theAssignType = ossimValueAssignType_GROUP;
+   }
+   
+   return ossimImageSourceFilter::loadState(kwl, prefix);
+}
+
+const vector<double>& ossimValueAssignImageSourceFilter::getInputValues()const
+{
+   return theInputValueArray;
+}
+const vector<double>& ossimValueAssignImageSourceFilter::getOutputValues()const
+{
+   return theOutputValueArray;
+}
+
+ossimValueAssignImageSourceFilter::ossimValueAssignType ossimValueAssignImageSourceFilter::getValueAssignType()const
+{
+   return theAssignType;
+}
+void ossimValueAssignImageSourceFilter::setValueAssignType(ossimValueAssignType type)
+{
+   theAssignType = type;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimValueAssignImageSourceFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimValueAssignImageSourceFilter.h
new file mode 100644
index 0000000000..0e8fe92a09
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimValueAssignImageSourceFilter.h
@@ -0,0 +1,102 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimValueAssignImageSourceFilter.h,v 1.5 2005/02/11 15:07:34 dburken Exp $
+#ifndef ossimValueAssignImageSourceFilter_HEADER
+#define ossimValueAssignImageSourceFilter_HEADER
+
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+/**
+ * This allows one to assign a value to a group of bands.  It will test
+ * for equality band separate or as group. For example:
+ *
+ * if we are testing as a group then the assign will not happen unless
+ * all values equal theInputValue array
+ *
+ *  inputValue = <1, 2, 3>
+ *  outputValue = <100, 100, 100>
+ *
+ *  then it will only convert to 100, 100, 100 if the input equals all
+ *  values of the output.
+ *
+ * input <1, 55, 3>  would become <1, 55, 3>
+ * input <1, 2, 3>   would become <100, 100, 100>
+ *
+ *  Now for band separate it means you want to change on a per band and
+ *  not as a group.  For example:
+ *
+ * inputValue = <1, 2, 3>
+ * outputValue = <100, 100, 100>
+ *
+ * input <1, 55, 3>  would become <100, 55, 100>
+ *
+ */
+class OSSIMDLLEXPORT ossimValueAssignImageSourceFilter : public ossimImageSourceFilter
+{
+public:
+   enum ossimValueAssignType
+   {
+      ossimValueAssignType_SEPARATE = 1,
+      ossimValueAssignType_GROUP    = 2
+   };
+   
+   ossimValueAssignImageSourceFilter(ossimObject* owner=NULL);
+   virtual ~ossimValueAssignImageSourceFilter();
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tileRect,
+                                   ossim_uint32 resLevel=0);
+
+   void setInputOutputValues(const vector<double>& inputValues,
+                             const vector<double>& outputValues);
+
+   const vector<double>& getInputValues()const;
+   const vector<double>& getOutputValues()const;
+   ossimValueAssignType getValueAssignType()const;
+   void setValueAssignType(ossimValueAssignType type);
+
+   virtual void initialize();
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+   
+protected:
+
+   /**
+    * Called on first getTile, will initialize all data needed.
+    */
+   void allocate();
+   
+   vector<double>              theInputValueArray;
+   vector<double>              theOutputValueArray;
+   ossimValueAssignType        theAssignType;
+   ossimRefPtr<ossimImageData> theTile;
+   
+   void validateArrays();
+   
+   template <class T>
+      void executeAssign(T, ossimRefPtr<ossimImageData>& data);
+   
+   template <class T>
+      void executeAssignSeparate(T, ossimRefPtr<ossimImageData>& data);
+   
+   template <class T>
+      void executeAssignGroup(T, ossimRefPtr<ossimImageData>& data);
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimValueAssignImageSourceFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimVectorRenderer.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimVectorRenderer.cpp
new file mode 100644
index 0000000000..ffe87ffaeb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimVectorRenderer.cpp
@@ -0,0 +1,148 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken (dburken@imagelinks.com)
+//
+// Description:
+//
+// Abstract class for rendering vector data.  Derived classes should implement
+// the "rasterizeVectorData" data method.
+//
+//*******************************************************************
+//  $Id: ossimVectorRenderer.cpp,v 1.7 2003/05/13 11:31:09 dburken Exp $
+
+#include <iostream>
+using namespace std;
+
+#include "ossimVectorRenderer.h"
+#include "base/common/ossimCommon.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/common/ossimKeywordNames.h"
+#include "imaging/filters/ossimFilter.h"
+#include "projections/ossimImageViewTransform.h"
+#include "projections/factory/ossimImageViewTransformFactory.h"
+
+RTTI_DEF1(ossimVectorRenderer, "ossimVectorRenderer", ossimImageSourceFilter)
+
+
+ossimVectorRenderer::ossimVectorRenderer()
+   :
+      ossimImageSourceFilter(),
+      theImageViewTransform(NULL),
+      theBoundingRect(),
+      theAreaOfInterest(),
+      theNumberOfAoiObjects(0),
+      theNumberOfObjects(0)
+{
+}
+
+ossimVectorRenderer::ossimVectorRenderer(ossimImageSource* inputSource,
+                                         ossimImageViewTransform* transform)
+   : ossimImageSourceFilter(inputSource),
+     theImageViewTransform(transform),
+     theBoundingRect(),
+     theAreaOfInterest(),
+     theNumberOfAoiObjects(0),
+     theNumberOfObjects(0)
+{
+   
+}
+
+
+ossimVectorRenderer::~ossimVectorRenderer()
+{
+   if (theImageViewTransform)
+   {
+      delete theImageViewTransform;
+      theImageViewTransform = NULL;
+   }
+}
+
+bool ossimVectorRenderer::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix) const
+{
+   return false;
+}
+
+bool ossimVectorRenderer::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   ossimString newPrefix = prefix + ossimString("image_view_trans.");
+
+   if(theImageViewTransform)
+   {
+      delete theImageViewTransform;
+      theImageViewTransform = NULL;
+   }
+
+   theImageViewTransform
+      = ossimImageViewTransformFactory::instance()->
+      createTransform(kwl, newPrefix.c_str());
+   
+   return ossimImageSource::loadState(kwl, prefix);
+}
+
+void
+ossimVectorRenderer::setImageViewTransform(ossimImageViewTransform* transform)
+{
+   if(theImageViewTransform)
+   {
+      delete theImageViewTransform;
+   }
+   theImageViewTransform = transform;
+}
+
+void ossimVectorRenderer::setAreaOfInterest(const ossimDrect& aoi)
+{
+   theAreaOfInterest = aoi;
+}
+
+ossimDrect ossimVectorRenderer::getAreaOfInterest() const
+{
+   return theAreaOfInterest;
+}
+
+ossimDrect ossimVectorRenderer::getBoundingRect(long resLevel)const
+{
+   return theBoundingRect;
+}
+
+ossim_int32 ossimVectorRenderer::getNumberOfAoiObjects() const
+{
+   return theNumberOfAoiObjects;
+}
+
+ossim_int32 ossimVectorRenderer::getNumberOfObjects() const
+{
+   return theNumberOfObjects;
+}
+
+void ossimVectorRenderer::setBoundingRect(ossimDrect& rect)
+{
+   theBoundingRect = rect;
+}
+
+void ossimVectorRenderer::setNumberOfAoiObjects(ossim_int32 number_of_objects)
+{
+   theNumberOfAoiObjects = number_of_objects;
+}
+
+void ossimVectorRenderer::setNumberOfObjects(ossim_int32 number_of_objects)
+{
+   theNumberOfObjects = number_of_objects;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimVectorRenderer.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimVectorRenderer.h
new file mode 100644
index 0000000000..92ac7bcc30
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimVectorRenderer.h
@@ -0,0 +1,133 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken
+// 
+// Description:
+//
+// Abstract class for rendering vector data.  Derived classes should implement
+// the "rasterizeVectorData" data method.
+//               
+//*******************************************************************
+// $Id: ossimVectorRenderer.h,v 1.7 2004/04/03 20:53:18 dburken Exp $
+#ifndef ossimVectorRenderer_HEADER
+#define ossimVectorRenderer_HEADER
+
+#include "ossimImageSourceFilter.h"
+#include "base/data_types/ossimDrect.h"
+#include "base/data_types/ossimDpt3d.h"
+
+class ossimImageViewTransform;
+class ossimImageData;
+
+class ossimVectorRenderer : public ossimImageSourceFilter
+{
+public:
+   ossimVectorRenderer();
+   ossimVectorRenderer(ossimImageSource* inputSource,
+                       ossimImageViewTransform *transform = NULL);
+   virtual ~ossimVectorRenderer();
+      
+   /**
+    * Renders the vector data to a data object.  The area which is
+    * imaged is the area of interest.  The scale is determined by the output
+    * view projection of the ImageViewTransform.
+    */
+   virtual ossimImageData* renderVectorData() const = 0;
+
+   /**
+    * Returns vector of ossimDpt3d points representing the data object at
+    * the index passed in.  Implementors should set an error and return an
+    * empty vector if the index is out of range.
+    */
+   virtual vector<ossimDpt3d> getObject(ossim_uint32 index) const = 0;
+   
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * Sets the ImageViewTransform to be used for converting vector data.
+    */
+   virtual void setImageViewTransform(ossimImageViewTransform* transform);
+
+   /**
+    * Sets the area of interest.  This will be used by the renderVectorData.
+    */
+   virtual void setAreaOfInterest(const ossimDrect& aoi);
+
+   /**
+    * Returns the current area of interest as an ossimDrect.
+    */
+   virtual ossimDrect getAreaOfInterest() const;
+
+   /**
+    * Returns the full bounding rectangle of current vector data loaded.
+    */
+   virtual ossimDrect getBoundingRect(long resLevel=0)const;
+
+   /**
+    * Returns the number of vector objects in the area of interest.
+    */
+   virtual ossim_int32 getNumberOfAoiObjects() const;
+
+   /**
+    * Returns the total number of vector objects in the full bounding
+    * rectangle.
+    */
+   virtual ossim_int32 getNumberOfObjects() const;
+
+protected:
+   
+   /**
+    * Sets the bounding rectangle of current vector data loaded.
+    */
+   virtual void setBoundingRect(ossimDrect& rect);
+
+   /**
+    * Sets the number of vector objects in the area of interest.
+    */
+   virtual void setNumberOfAoiObjects(ossim_int32 number_of_objects);
+ 
+   /**
+    * Sets the number of vector objects in the full bounding rectangle.
+    */
+   virtual void setNumberOfObjects(ossim_int32 number_of_objects);
+   
+private:
+
+   ossimImageViewTransform*  theImageViewTransform;
+   ossimDrect                theBoundingRect;
+   ossimDrect                theAreaOfInterest;
+   ossim_int32               theNumberOfAoiObjects;
+   ossim_int32               theNumberOfObjects;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimWatermarkFilter.cpp b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimWatermarkFilter.cpp
new file mode 100644
index 0000000000..63353c24a9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimWatermarkFilter.cpp
@@ -0,0 +1,1167 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author:  David Burken
+//
+// Description: Class definition of ossimWatermarkFilter.
+// Applies an image or watermark to image.  Positioning is based on mode.
+// Density is base on alpha weight.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimWatermarkFilter.cpp,v 1.8 2005/12/21 15:43:36 dburken Exp $
+
+#include <vector>
+
+#include <imaging/tile_sources/ossimWatermarkFilter.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimScopedLock.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/property/ossimFilenameProperty.h>
+#include <base/property/ossimNumericProperty.h>
+#include <base/property/ossimStringProperty.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+
+#include <imaging/tile_sources/ossimScalarRemapper.h>
+
+
+RTTI_DEF1(ossimWatermarkFilter, "ossimWatermarkFilter", ossimImageSourceFilter)
+
+static ossimTrace traceDebug(ossimString("ossimWatermarkFilter:debug"));
+
+// Keywords:
+static const char WATERMARK_MODE_KW[] = "watermark_mode";
+static const char WEIGHT_KW[]         = "weight";
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimWatermarkFilter.cpp,v 1.8 2005/12/21 15:43:36 dburken Exp $";
+#endif
+
+const ossim_float64 DEFAULT_WEIGHT = 0.20;
+
+ossimWatermarkFilter::ossimWatermarkFilter()
+   :
+   theFilename(ossimFilename::NIL),
+   theWatermarkWeight(DEFAULT_WEIGHT),
+   theTile(NULL),
+   theWatermark(NULL),
+   theMode(ossimWatermarkFilter::UPPER_LEFT),
+   theInputBoundingRect(),
+   theDirtyFlag(true),
+   theMutex()
+{
+   theEnableFlag = true;
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimPixelFlipper::ossimPixelFlipper" << std::endl;
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "OSSIM_ID:  " << OSSIM_ID << std::endl;
+#endif      
+   }
+}
+
+ossimWatermarkFilter::~ossimWatermarkFilter()
+{
+   // Dereference tiles and force a delete if last reference.
+   theWatermark = NULL;
+   theTile      = NULL;
+}
+
+ossimString ossimWatermarkFilter::getShortName() const
+{
+   return ossimString("Watermark Filter");
+}
+
+ossimString ossimWatermarkFilter::getLongName() const
+{
+   return ossimString("Watermark Filter - Applies watermark image onto getTile Request.");
+}
+
+ossimString ossimWatermarkFilter::getDescription() const
+{
+   ossimString description;
+   description = getLongName();
+   description += "\n";
+   description += "Valid modes:\n";
+
+   vector<ossimString> list;
+   getModeList(list);
+
+   vector<ossimString>::const_iterator i = list.begin();
+   while (i != list.end())
+   {
+      description +=(*i);
+      description += "\n";
+      ++i;
+   }
+
+   return description;
+}
+
+ossimRefPtr<ossimImageData> ossimWatermarkFilter::getTile(
+   const ossimIrect& tile_rect, ossim_uint32 resLevel)
+{
+   // Lock for the length of this method.
+   ossimScopedLock<ossimMutex> scopeLock(theMutex);
+
+   // Check for input.
+   if (!theInputConnection)
+   {
+      if (theTile.valid())
+      {
+         theTile->setImageRectangle(tile_rect);
+         theTile->makeBlank();
+      }
+      return theTile;
+   }
+
+   // Fetch a tile from from the input source.
+   ossimRefPtr<ossimImageData> inputTile =
+      theInputConnection->getTile(tile_rect, resLevel);
+
+   // Check for bypass.
+   if (theEnableFlag == false) return inputTile;
+
+   // Check for weight being 0.0.
+   if (theWatermarkWeight == 0.0) return inputTile;
+
+   //---
+   // Check for dirty state.
+   // Note: This is set in initialize if something changes.
+   //---
+   if (theDirtyFlag == true)
+   {
+      if (allocate() == false) // Something not right if false.
+      {
+         return inputTile;
+      }
+   }   
+   
+   // We will only watermark (process) within the input bounding rectangle.
+   if (tile_rect.intersects(theInputBoundingRect) == false)
+   {
+      return inputTile;
+   }
+
+   // Capture the rectangle and blank out theTile.
+   theTile->setImageRectangle(tile_rect);
+
+   if (inputTile.valid() &&
+       (inputTile->getDataObjectStatus() != OSSIM_NULL))
+   {
+      // Copy the inputTile to theTile.
+      theTile->loadTile(inputTile.get());
+   }
+   else 
+   {
+      theTile->makeBlank();
+   }
+
+   // Write the watermarks...
+   switch(theTile->getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         fill(ossim_uint8(0));
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         fill(ossim_sint8(0));
+         break;
+      }
+      case OSSIM_USHORT11:
+      case OSSIM_UINT16:
+      {
+         fill(ossim_uint16(0));
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         fill(ossim_sint16(0));
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         fill(ossim_uint32(0));
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         fill(ossim_sint32(0));
+         break;
+      }
+      case OSSIM_FLOAT32: 
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         fill(ossim_float32(0));
+         break;
+      }
+      case OSSIM_FLOAT64: 
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         fill(ossim_float32(0));
+         break;
+      }
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Scalar type = " << theTile->getScalarType()
+            << " Not supported by ossimWatermarkFilter" << std::endl;
+         return inputTile;
+      }
+   }
+
+   return theTile;
+}
+
+template <class T> void ossimWatermarkFilter::fill(T /* dummy */)
+{
+   const ossimIrect TILE_RECT = theTile->getImageRectangle();
+
+   // We will only fill data within the input bounding rect.
+   const ossimIrect CLIPPED_TILE_RECT =
+      TILE_RECT.clipToRect(theInputBoundingRect);
+
+   // Get the bounding rectangles.
+   vector<ossimIrect> rects(0);
+   getIntersectingRects(rects);
+
+   if (rects.size() == 0)
+   {
+      return;
+   }
+
+   //---
+   // Have watermark rectangles that intersect this tile so we need to process.
+   //---
+   ossim_uint32 band = 0;
+   ossim_float64 inputPixWeight = 1.0 - theWatermarkWeight;
+
+   // Get a pointers to the watermark buffers (wmBuf) and nulls wn.
+   T** wmBuf = new T*[theWatermarkNumberOfBands];
+   for (band = 0; band < theWatermarkNumberOfBands; ++band)
+   {
+      wmBuf[band] = static_cast<T*>(theWatermark->getBuf(band));
+   }
+   
+   // Get a pointers to the output tile buffers and nulls in.
+   T** otBuf = new T*[theInputNumberOfBands];
+   for (band = 0; band < theInputNumberOfBands; ++band)
+   {
+      otBuf[band] = static_cast<T*>(theTile->getBuf(band));
+   }
+
+   // Get the width of the buffers for indexing.
+   ossim_int32 wmWidth = static_cast<ossim_int32>(theWatermark->getWidth());
+   ossim_int32 otWidth = static_cast<ossim_int32>(theTile->getWidth());
+
+   const ossim_float64* wmNull = theWatermark->getNullPix();
+   const ossim_float64* otMin  = theTile->getMinPix();
+   const ossim_float64* otMax  = theTile->getMaxPix();
+   const ossim_float64* otNull = theTile->getNullPix();
+   
+      
+   // Control loop through intersecting rectangles.
+   vector<ossimIrect>::const_iterator i = rects.begin();
+   while (i != rects.end())
+   {
+      if ( (*i).intersects(CLIPPED_TILE_RECT) )
+      {
+         //---
+         // This is the rectangle we want to fill relative to requesting
+         // image space.
+         //---
+         const ossimIrect CLIPPED_WATERMARRK_RECT =
+            (*i).clipToRect(CLIPPED_TILE_RECT);
+
+         ossim_int32 clipHeight = CLIPPED_WATERMARRK_RECT.height();
+         ossim_int32 clipWidth  = CLIPPED_WATERMARRK_RECT.width();
+
+         // Compute the starting offset into the wmBuf and otBuf.
+         ossim_int32 wmOffset =
+            (CLIPPED_WATERMARRK_RECT.ul().y - (*i).ul().y) * wmWidth +
+            CLIPPED_WATERMARRK_RECT.ul().x  - (*i).ul().x;
+         ossim_int32 otOffset =
+            (CLIPPED_WATERMARRK_RECT.ul().y - TILE_RECT.ul().y)* otWidth +
+             CLIPPED_WATERMARRK_RECT.ul().x - TILE_RECT.ul().x;
+         
+         // Line loop...
+         for (ossim_int32 line = 0; line < clipHeight; ++line)
+         {
+            // Sample loop...
+            for (ossim_int32 sample = 0; sample < clipWidth; ++sample)
+            {
+               // Output band control loop until all output bands are filled.
+               ossim_uint32 otBand = 0;
+               while (otBand < theInputNumberOfBands)
+               {
+                  // Band loop through the watermark.
+                  for (ossim_uint32 wmBand = 0;
+                       wmBand < theWatermarkNumberOfBands;
+                       ++wmBand)
+                  {
+                     if (wmBuf[wmBand][wmOffset+sample] != wmNull[wmBand])
+                     {
+                        // Apply the weight to the input pixel.
+                        ossim_float64 p1 =
+                           (otBuf[otBand][otOffset+sample] != otNull[otBand]) ?
+                           otBuf[otBand][otOffset+sample] * inputPixWeight :
+                           0.0;
+
+                        // Apply the Weight to the watermark pixel.
+                        ossim_float64 p2 =
+                           wmBuf[wmBand][wmOffset+sample]*theWatermarkWeight;
+
+                        // Add them up.
+                        ossim_float64 p3 = p1 + p2;
+
+                        // Cast to output type with range checking.
+                        otBuf[otBand][otOffset+sample] = static_cast<T>(
+                           ( (p3 >= otMin[otBand]) ?
+                             (p3 < otMax[otBand] ? p3 : otMax[otBand]) :
+                             otNull[otBand]) );
+                     }
+                     ++otBand;
+                     
+                     // We stop when we reach here.  All output bands filled.
+                     if (otBand == theInputNumberOfBands)
+                     {
+                        break;
+                     }
+                     
+                  } // End of band through watermark.
+                  
+               } // End of outer band loop.
+               
+            } // End of sample loop.
+
+            wmOffset += wmWidth;
+            otOffset += otWidth;
+            
+         } // End of line loop.
+
+      } // End "if ( (*i).intersects(TILE_RECT) )"
+      
+      ++i; // Go to next rectangle to fill if any.
+      
+   } // End of "while (i != rects.end())"
+
+   // Clean up.
+   delete [] wmBuf;
+   delete [] otBuf;
+   
+   theTile->validate();
+}
+
+void ossimWatermarkFilter::getIntersectingRects(vector<ossimIrect>& rects)
+{
+   switch(theMode)
+   {
+      case UPPER_LEFT:
+         getUpperLeftRect(rects);
+         break;
+      case UPPER_CENTER:
+         getUpperCenterRect(rects);
+         break;
+      case UPPER_RIGHT:
+         getUpperRightRect(rects);
+         break;
+      case CENTER:
+         getCenterRect(rects);
+         break;
+      case LOWER_LEFT:
+         getLowerLeftRect(rects);
+         break;
+      case LOWER_CENTER:
+         getLowerCenterRect(rects);
+         break;
+      case LOWER_RIGHT:
+         getLowerRightRect(rects);
+         break;
+      case UNIFORM_DENSE:
+         getUniformDenseRects(rects);
+         break;
+      case UNIFORM_SPARSE:
+         getUniformSparceRects(rects);
+         break;
+      default:
+         break;
+   }
+}
+
+void ossimWatermarkFilter::getUpperLeftRect(vector<ossimIrect>& rects)
+{
+   // First clip the rect to the bounding image rectangle.
+   const ossimIrect CLIP_RECT =
+      theTile->getImageRectangle().clipToRect(theInputBoundingRect);
+   theWatermark->setOrigin(theInputBoundingRect.ul());
+   ossimIrect r = theWatermark->getImageRectangle();
+   if (r.intersects(CLIP_RECT))
+   {
+      rects.push_back(r);
+   }
+}
+
+void ossimWatermarkFilter::getUpperCenterRect(vector<ossimIrect>& rects)
+{
+   // First clip the rect to the bounding image rectangle.
+   const ossimIrect CLIP_RECT =
+      theTile->getImageRectangle().clipToRect(theInputBoundingRect);
+   ossim_uint32 watermarkWidth = theWatermark->getImageRectangle().width();
+   ossim_uint32 inputWidth = theInputBoundingRect.width();
+   ossimIpt origin = theInputBoundingRect.ul();
+   
+   // Input wider than watermark so center.
+   if (inputWidth > watermarkWidth)
+   {
+      ossim_int32 offset =
+         static_cast<ossim_int32>((inputWidth - watermarkWidth) / 2);
+      origin.x = origin.x + offset;
+   }
+   
+   theWatermark->setOrigin(origin);
+   
+   ossimIrect r = theWatermark->getImageRectangle();
+   if (r.intersects(CLIP_RECT))
+   {
+      rects.push_back(r);
+   }
+}  
+
+void ossimWatermarkFilter::getUpperRightRect(vector<ossimIrect>& rects)
+{
+   // First clip the rect to the bounding image rectangle.
+   const ossimIrect CLIP_RECT =
+      theTile->getImageRectangle().clipToRect(theInputBoundingRect);
+   ossim_uint32 watermarkWidth =
+      theWatermark->getImageRectangle().width();
+   ossim_uint32 inputWidth = theInputBoundingRect.width();
+   
+   ossimIpt origin = theInputBoundingRect.ul();
+   
+   // Input wider than watermark so center.
+   if (inputWidth > watermarkWidth)
+   {
+      ossim_int32 offset =
+         static_cast<ossim_int32>(inputWidth - watermarkWidth);
+      origin.x = origin.x + offset;
+   }
+   
+   theWatermark->setOrigin(origin);
+   
+   ossimIrect r = theWatermark->getImageRectangle();
+   if (r.intersects(CLIP_RECT))
+   {
+      rects.push_back(r);
+   }
+}  
+
+void ossimWatermarkFilter::getCenterRect(vector<ossimIrect>& rects)
+{
+   // First clip the rect to the bounding image rectangle.
+   const ossimIrect CLIP_RECT =
+      theTile->getImageRectangle().clipToRect(theInputBoundingRect);
+   ossim_uint32 watermarkWidth = theWatermark->getImageRectangle().width();
+   ossim_uint32 watermarkHeight = theWatermark->getImageRectangle().height();
+   ossim_uint32 inputWidth = theInputBoundingRect.width();
+   ossim_uint32 inputHeight = theInputBoundingRect.height();
+   ossimIpt origin = theInputBoundingRect.ul();
+   
+   // Input wider than watermark so center.
+   if (inputWidth > watermarkWidth)
+   {
+      ossim_int32 offset =
+         static_cast<ossim_int32>((inputWidth - watermarkWidth) / 2);
+      origin.x = origin.x + offset;
+   }
+   // Input higher than watermark so center.
+   if (inputHeight > watermarkHeight)
+   {
+      ossim_int32 offset =
+         static_cast<ossim_int32>((inputHeight - watermarkHeight) / 2);
+      origin.y = origin.y + offset;
+   }
+   
+   theWatermark->setOrigin(origin);
+   
+   ossimIrect r = theWatermark->getImageRectangle();
+   if (r.intersects(CLIP_RECT))
+   {
+      rects.push_back(r);
+   }
+}
+
+void ossimWatermarkFilter::getLowerLeftRect(vector<ossimIrect>& rects)
+{
+   // First clip the rect to the bounding image rectangle.
+   const ossimIrect CLIP_RECT =
+      theTile->getImageRectangle().clipToRect(theInputBoundingRect);
+   ossim_uint32 watermarkHeight = theWatermark->getImageRectangle().height();
+   ossim_uint32 inputHeight = theInputBoundingRect.height();
+   ossimIpt origin = theInputBoundingRect.ul();
+   
+   // Input higher than watermark so apply offset.
+   if (inputHeight > watermarkHeight)
+   {
+      ossim_int32 offset =
+         static_cast<ossim_int32>(inputHeight - watermarkHeight);
+      origin.y = origin.y + offset;
+   }
+   
+   theWatermark->setOrigin(origin);
+   
+   ossimIrect r = theWatermark->getImageRectangle();
+   if (r.intersects(CLIP_RECT))
+   {
+      rects.push_back(r);
+   }
+}
+
+void ossimWatermarkFilter::getLowerCenterRect(vector<ossimIrect>& rects)
+{
+   // First clip the rect to the bounding image rectangle.
+   const ossimIrect CLIP_RECT =
+      theTile->getImageRectangle().clipToRect(theInputBoundingRect);
+   ossim_uint32 watermarkWidth = theWatermark->getImageRectangle().width();
+   ossim_uint32 watermarkHeight = theWatermark->getImageRectangle().height();
+   ossim_uint32 inputWidth = theInputBoundingRect.width();
+   ossim_uint32 inputHeight = theInputBoundingRect.height();
+   ossimIpt origin = theInputBoundingRect.ul();
+   
+   // Input wider than watermark so center.
+   if (inputWidth > watermarkWidth)
+   {
+      ossim_int32 offset =
+         static_cast<ossim_int32>((inputWidth - watermarkWidth) / 2);
+      origin.x = origin.x + offset;
+   }
+   // Input higher than watermark so apply offset.
+   if (inputHeight > watermarkHeight)
+   {
+      ossim_int32 offset =
+         static_cast<ossim_int32>(inputHeight - watermarkHeight);
+      origin.y = origin.y + offset;
+   }
+   
+   theWatermark->setOrigin(origin);
+   ossimIrect r = theWatermark->getImageRectangle();
+   if (r.intersects(CLIP_RECT))
+   {
+      rects.push_back(r);
+   }
+}
+
+void ossimWatermarkFilter::getLowerRightRect(vector<ossimIrect>& rects)
+{
+   // First clip the rect to the bounding image rectangle.
+   const ossimIrect CLIP_RECT =
+      theTile->getImageRectangle().clipToRect(theInputBoundingRect);
+   ossim_uint32 watermarkWidth = theWatermark->getImageRectangle().width();
+   ossim_uint32 watermarkHeight = theWatermark->getImageRectangle().height();
+   ossim_uint32 inputWidth = theInputBoundingRect.width();
+   ossim_uint32 inputHeight = theInputBoundingRect.height();
+   ossimIpt origin = theInputBoundingRect.ul();
+   
+   // Input wider than watermark so center.
+   if (inputWidth > watermarkWidth)
+   {
+      ossim_int32 offset =
+         static_cast<ossim_int32>(inputWidth - watermarkWidth);
+      origin.x = origin.x + offset;
+   }
+   // Input higher than watermark so apply offset.
+   if (inputHeight > watermarkHeight)
+   {
+      ossim_int32 offset =
+         static_cast<ossim_int32>(inputHeight - watermarkHeight);
+      origin.y = origin.y + offset;
+   }
+   
+   theWatermark->setOrigin(origin);
+   ossimIrect r = theWatermark->getImageRectangle();
+   if (r.intersects(CLIP_RECT))
+   {
+      rects.push_back(r);
+   }
+   
+}
+
+void ossimWatermarkFilter::getUniformDenseRects(vector<ossimIrect>& rects)
+{
+   // First clip the rect to the bounding image rectangle.
+   const ossimIrect CLIP_RECT =
+      theTile->getImageRectangle().clipToRect(theInputBoundingRect);
+   ossim_uint32 watermarkWidth = theWatermark->getImageRectangle().width();
+   ossim_uint32 watermarkHeight = theWatermark->getImageRectangle().height();
+   ossim_uint32 inputWidth = theInputBoundingRect.width();
+   ossim_uint32 inputHeight = theInputBoundingRect.height();
+
+   ossim_uint32 watermarksHigh = inputHeight / watermarkHeight;
+   if (inputHeight % watermarkHeight) ++watermarksHigh;
+   
+   ossim_uint32 watermarksWide = inputWidth / watermarkWidth;
+   if (inputWidth % watermarkWidth) ++watermarksWide;
+
+   ossim_int32 xOffset = static_cast<ossim_int32>(watermarkWidth);
+   ossim_int32 yOffset = static_cast<ossim_int32>(watermarkHeight);
+   
+   ossimIpt origin = theInputBoundingRect.ul();
+   
+   for (ossim_uint32 y = 0; y < watermarksHigh; ++y)
+   {
+      for (ossim_uint32 x = 0; x < watermarksWide; ++x)
+      {
+         theWatermark->setOrigin(origin);
+         ossimIrect r = theWatermark->getImageRectangle();
+         if (r.intersects(CLIP_RECT))
+         {
+            rects.push_back(r);
+         }
+         origin.x = origin.x + xOffset;
+      }
+      origin.y = origin.y + yOffset;
+      origin.x = theInputBoundingRect.ul().x;
+   }
+}
+
+void ossimWatermarkFilter::getUniformSparceRects(vector<ossimIrect>& rects)
+{
+   // First clip the rect to the bounding image rectangle.
+   const ossimIrect CLIP_RECT =
+      theTile->getImageRectangle().clipToRect(theInputBoundingRect);
+   ossim_uint32 watermarkWidth  = theWatermark->getImageRectangle().width();
+   ossim_uint32 watermarkHeight = theWatermark->getImageRectangle().height();
+   ossim_uint32 inputWidth      = theInputBoundingRect.width();
+   ossim_uint32 inputHeight     = theInputBoundingRect.height();
+   ossim_uint32 gapWidth   = watermarkWidth/2;
+   ossim_uint32 gapHeight  = watermarkHeight/2;
+
+   ossim_uint32 watermarksHigh = inputHeight/(watermarkHeight+gapHeight);
+   if (inputHeight % watermarkHeight) ++watermarksHigh;
+   
+   ossim_uint32 watermarksWide = inputWidth/(watermarkWidth+gapWidth);
+   if (inputWidth % watermarkWidth) ++watermarksWide;
+
+   ossim_int32 xOffset = static_cast<ossim_int32>(watermarkWidth  + gapWidth);
+   ossim_int32 yOffset = static_cast<ossim_int32>(watermarkHeight + gapHeight);
+
+   ossimIpt origin = theInputBoundingRect.ul();
+   
+   for (ossim_uint32 y = 0; y < watermarksHigh; ++y)
+   {
+      for (ossim_uint32 x = 0; x < watermarksWide; ++x)
+      {
+         theWatermark->setOrigin(origin);
+         ossimIrect r = theWatermark->getImageRectangle();
+         if (r.intersects(CLIP_RECT))
+         {
+            rects.push_back(r);
+         }
+         origin.x = origin.x + xOffset;
+      }
+      origin.y = origin.y + yOffset;
+      origin.x = theInputBoundingRect.ul().x;
+   }
+}
+
+void ossimWatermarkFilter::initialize()
+{
+   //---
+   // If state is not already dirty and there is an input connection
+   // check for:
+   // 
+   // 1) Scalar change
+   // 2) band number change
+   // 3) bounding box change
+   //
+   // Set state to dirty on a change.
+   //
+   // NOTE:  This method intentionally only sets the dirty state and doesn't do
+   // anything else as it is called repetitively during chain setup or chain
+   // state changes.
+   //
+   // The first getTile call will do the real work, call allocate(),
+   // if the state is dirty.
+   //---
+
+   // Lock for the length of this method.
+   ossimScopedLock<ossimMutex> scopeLock(theMutex);
+
+   // Set the input connection.
+   ossimImageSourceFilter::initialize();
+
+   // Once dirty flag is set no need to do it again.
+   if (theDirtyFlag == false)
+   {
+      if (theInputConnection)
+      {
+         // Check for scalar type change.
+         if (theInputScalarType != theInputConnection->getOutputScalarType())
+         {
+            theDirtyFlag = true;
+            return;
+         }
+
+         // Check for band change.
+         if (theInputNumberOfBands !=
+             theInputConnection->getNumberOfOutputBands())
+         {
+            theDirtyFlag = true;
+            return;
+         }
+
+         // Check for bounding rectangle change.
+         if ( theInputBoundingRect != theInputConnection->getBoundingRect() )
+         {
+            theDirtyFlag = true;
+            return;
+         }
+      }
+   }
+}
+
+bool ossimWatermarkFilter::allocate()
+{
+   // Capture the bounding rect:
+   theInputBoundingRect = theInputConnection->getBoundingRect();
+
+   // Capture the scalar type:
+   theInputScalarType = theInputConnection->getOutputScalarType();
+
+   // Capture the number of bands:
+   theInputNumberOfBands = theInputConnection->getNumberOfOutputBands();
+
+   //---
+   // Check the watermark scalar type.
+   //---
+   if (theWatermark.valid())
+   {
+      if (theWatermark->getScalarType() != theInputScalarType)
+      {
+         //---
+         // We'll need to make a new one with a scalar remapper after it.
+         //---
+         theWatermark = NULL; // We'll need to make a new one.
+      }
+   }
+
+   //---
+   // Make a new watermark tile.  This will do a scalar remap if needed.
+   // If we don't have a watermark no point in going on...
+   //---
+   if (!theWatermark)
+   {
+      if (openWatermarkFile() == false)
+      {
+         return false;
+      }
+   }
+
+   if (theTile.valid())
+   {
+      if ( (theTile->getScalarType()    != theInputScalarType) ||
+           (theTile->getNumberOfBands() != theInputNumberOfBands) )
+      {
+         theTile = NULL;  // We'll need to make a new one.
+      }
+   }
+
+   // Make a new output tile if we need to.
+   if (!theTile)
+   {
+      theTile = ossimImageDataFactory::instance()->create(this,
+                                                          theInputConnection);
+      if (theTile.valid())
+      {
+         theTile->initialize();
+      }
+      else
+      {
+         return false;
+      }
+   }
+
+   //---
+   // If we get here things are good so clear the dirty flag so we don't
+   // get called again needlessly.
+   //---
+   theDirtyFlag = false;
+   
+   return true;
+}
+
+bool ossimWatermarkFilter::openWatermarkFile()
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimWatermarkFilter::openWatermarkFile DEBUG: entered..."
+         << std::endl;
+   }
+
+   if (!theInputConnection || (theFilename == ossimFilename::NIL))
+   {
+      return false;
+   }
+
+   theWatermark = NULL; // This will destroy any previous tiles.
+
+   // Open the watermark image.
+   ossimImageHandler* ih =
+      ossimImageHandlerRegistry::instance()->open(theFilename);
+   if (!ih)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimWatermarkFilter::openWatermarkFile"
+            << "\nCould not open: " << theFilename 
+            << std::endl;
+      }
+      
+      return false;
+   }
+   if (ih->getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimWatermarkFilter::openWatermarkFile"
+            << "\nError reading image:  " << theFilename
+            << std::endl; 
+         return false;
+      }
+   }
+
+   ih->initialize();
+   ossimImageSource* imageSource = ih;
+   ossimScalarRemapper* remapper = NULL;
+   
+   if (ih->getOutputScalarType() != theInputConnection->getOutputScalarType())
+   {
+      // Remap the watemark to the same scalar type as the input.
+      remapper = new ossimScalarRemapper(imageSource,
+                                         theInputConnection->
+                                         getOutputScalarType());
+      remapper->initialize();
+      imageSource = remapper;
+   }
+   
+   // Get the full image rectangle.
+   theWatermark = imageSource->getTile(ih->getImageRectangle(), 0);
+
+   // Cleanup...
+   if (remapper)
+   {
+      delete remapper;
+      remapper = NULL;
+   }
+   if (ih)
+   {
+      delete ih;
+      ih = NULL;
+   }
+   imageSource = NULL;
+   
+   if (theWatermark.valid() == false)
+   {
+      return false;
+   }
+
+   // Capture the bands as we will need this repetitively.
+   theWatermarkNumberOfBands = theWatermark->getNumberOfBands();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimWatermarkFilter::openWatermarkFile DEBUG:"
+         << *(theWatermark.get())
+         << endl;
+   }
+
+   return true;
+}
+
+bool ossimWatermarkFilter::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FILENAME_KW,
+           theFilename.c_str());
+   kwl.add(prefix,
+           WATERMARK_MODE_KW,
+           getModeString().c_str());
+   kwl.add(prefix,
+           WEIGHT_KW,
+           theWatermarkWeight);
+
+   return ossimImageSourceFilter::saveState(kwl, prefix);
+}
+
+bool ossimWatermarkFilter::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   // Do this first so connections get set up.
+   if (ossimImageSourceFilter::loadState(kwl, prefix) == false)
+   {
+      return false;
+   }
+
+   const char* lookupReturn;
+
+   lookupReturn = kwl.find(prefix, WEIGHT_KW);
+   if(lookupReturn)
+   {
+      setWeight(ossimString(lookupReturn).toDouble());
+   }
+
+   lookupReturn = kwl.find(prefix, WATERMARK_MODE_KW);
+   if(lookupReturn)
+   {
+      setMode(ossimString(lookupReturn));
+   }
+
+   lookupReturn = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   if(lookupReturn)
+   {
+      setFilename(lookupReturn);
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimWatermarkFilter::loadState DEBUG:"
+         << std::endl;
+      print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+
+   return true;
+}
+
+ossimRefPtr<ossimProperty> ossimWatermarkFilter::getProperty(
+   const ossimString& name) const
+{
+   // Lock for the length of this method.
+   ossimScopedLock<ossimMutex> scopeLock(theMutex);
+
+   if (name == ossimKeywordNames::FILENAME_KW)
+   {
+      ossimFilenameProperty* ofp =
+         new ossimFilenameProperty(name, theFilename);
+      ofp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
+      ofp->setCacheRefreshBit();
+      return ossimRefPtr<ossimProperty>((ossimProperty*)ofp);
+   }
+   else if (name == WATERMARK_MODE_KW)
+   {
+      vector<ossimString> constraintList;
+      getModeList(constraintList);
+
+      ossimStringProperty* p =
+         new ossimStringProperty(name,
+                                 getModeString(),
+                                 false,
+                                 constraintList);
+       p->setCacheRefreshBit();
+      return ossimRefPtr<ossimProperty>(p);
+   }
+   else if (name == WEIGHT_KW)
+   {
+      ossimProperty* p =
+         new ossimNumericProperty(name,
+                                  ossimString::toString(theWatermarkWeight));
+      p->setCacheRefreshBit();
+      return ossimRefPtr<ossimProperty>(p);
+   }
+
+   return ossimImageSourceFilter::getProperty(name);
+}
+
+void ossimWatermarkFilter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if (!property) return;
+
+   ossimString os = property->valueToString();
+   
+   ossimString name = property->getName();
+   if (name == ossimKeywordNames::FILENAME_KW)
+   {
+      setFilename(os);
+   }
+   else if  (name == WATERMARK_MODE_KW)
+   {
+      setMode(os);
+   }
+   else if  (name == WEIGHT_KW)
+   {
+      setWeight(os.toDouble());
+   }
+   else
+   {
+      ossimImageSourceFilter::setProperty(property);
+   }
+}
+
+void ossimWatermarkFilter::getPropertyNames(
+   std::vector<ossimString>& propertyNames) const
+{
+   propertyNames.push_back(ossimKeywordNames::FILENAME_KW);
+   propertyNames.push_back(WATERMARK_MODE_KW);
+   propertyNames.push_back(WEIGHT_KW);
+   ossimImageSourceFilter::getPropertyNames(propertyNames);
+}
+
+void ossimWatermarkFilter::getModeList(vector<ossimString>& list) const
+{
+   list.clear();
+   list.resize(ossimWatermarkFilter::END);
+   list[0] = ossimString("upper_left");
+   list[1] = ossimString("upper_center");
+   list[2] = ossimString("upper_right");
+   list[3] = ossimString("center");
+   list[4] = ossimString("lower_left");
+   list[5] = ossimString("lower_center");
+   list[6] = ossimString("lower_right");
+   list[7] = ossimString("uniform_dense");
+   list[8] = ossimString("uniform_sparse");
+}
+
+ossimWatermarkFilter::WatermarkMode ossimWatermarkFilter::getMode() const
+{
+   return theMode;
+}
+
+ossimString ossimWatermarkFilter::getModeString() const
+{
+   switch(theMode)
+   {
+      case UPPER_LEFT:
+         return ossimString("upper_left");
+      case UPPER_CENTER:
+         return ossimString("upper_center");
+      case UPPER_RIGHT:
+         return ossimString("upper_right");
+      case CENTER:
+         return ossimString("center");
+      case LOWER_LEFT:
+         return ossimString("lower_left");
+      case LOWER_CENTER:
+         return ossimString("lower_center");
+      case LOWER_RIGHT:
+         return ossimString("lower_right");
+      case UNIFORM_DENSE:
+         return ossimString("uniform_dense");
+      case UNIFORM_SPARSE:
+         return ossimString("uniform_sparse");
+      default:
+         break;
+   }
+
+   return ossimString("UNKNOWN_MODE");
+}
+
+void ossimWatermarkFilter::setFilename(const ossimFilename& file)
+{
+   if (file != theFilename)
+   {
+      theFilename = file;
+      theWatermark = NULL; // Will be reallocated next getTile.
+      theDirtyFlag = true;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimWatermarkFilter::setFilename DEBUG:" << std::endl;
+      print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+}
+
+void ossimWatermarkFilter::setMode(const ossimString& mode)
+{
+   ossimString os = mode;
+   os.downcase();
+   
+   if (os == "upper_left")
+   {
+      theMode = UPPER_LEFT;
+   }
+   else if (os == "upper_center")
+   {
+      theMode = UPPER_CENTER;
+   }
+   else if (os == "upper_right")
+   {
+      theMode = UPPER_RIGHT;
+   }
+   else if (os == "center")
+   {
+      theMode = CENTER;
+   }
+   else if (os == "lower_left")
+   {
+      theMode = LOWER_LEFT;
+   }
+   else if (os == "lower_center")
+   {
+      theMode = LOWER_CENTER;
+   }
+   else if (os == "lower_right")
+   {
+      theMode = LOWER_RIGHT;
+   }
+   else if (os == "uniform_dense")
+   {
+      theMode = UNIFORM_DENSE;
+   }
+   else if (os == "uniform_sparse")
+   {
+      theMode = UNIFORM_SPARSE;
+   }
+   else
+   {
+      // Invalid mode...
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimWatermarkFilter::setMode DEBUG:"
+            << "\nInvalid mode!  " << mode
+            << std::endl;
+      }
+   }
+}
+
+void ossimWatermarkFilter::setWeight(ossim_float64 weight)
+{
+   if ( (weight >= 0.0) && (weight <= 1.0) )
+   {
+      theWatermarkWeight = weight;
+   }
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimWatermarkFilter::setWeight DEBUG:" << std::endl;
+      print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+   
+}
+
+std::ostream& ossimWatermarkFilter::print(std::ostream& out) const
+{
+   out << "ossimWatermarkFilter::print"
+       << "\ntheFilename:        " << theFilename
+       << "\ntheWatermarkWeight: " << theWatermarkWeight
+       << "\ntheMode:            " << getModeString()
+       << std::endl;
+   return ossimImageSourceFilter::print(out);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimWatermarkFilter.h b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimWatermarkFilter.h
new file mode 100644
index 0000000000..c668a99226
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tile_sources/ossimWatermarkFilter.h
@@ -0,0 +1,351 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description: Class declaration of ossimWatermarkFilter.
+// Applies an image or watermark to image.  Positioning is based on mode.
+// Density is base on alpha weight.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimWatermarkFilter.h,v 1.4 2005/08/31 21:07:05 dburken Exp $
+#ifndef ossimWatermarkFilter_HEADER
+#define ossimWatermarkFilter_HEADER
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimMutex.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimIrect.h>
+#include <imaging/tile_sources/ossimImageSourceFilter.h>
+
+/**
+ * class ossimWatermarkFilter
+ * Applies an image or watermark to image.
+ * Positioning is based on mode.
+ * Density is base on alpha weight.
+ */
+class OSSIMDLLEXPORT ossimWatermarkFilter : public ossimImageSourceFilter
+{
+public:
+
+   enum WatermarkMode
+   {
+      UPPER_LEFT     = 0,
+      UPPER_CENTER   = 1,
+      UPPER_RIGHT    = 2,
+      CENTER         = 3,
+      LOWER_LEFT     = 4,
+      LOWER_CENTER   = 5,
+      LOWER_RIGHT    = 6,
+      UNIFORM_DENSE  = 7,
+      UNIFORM_SPARSE = 8,
+      END            = 9 //< Number of modes.
+   };
+      
+   /** contructor */
+   ossimWatermarkFilter();
+
+   /** destructor */
+   virtual ~ossimWatermarkFilter();
+
+   /** @return Short name of filter. */
+   virtual ossimString getShortName()   const;
+
+   /** @return Long name of filter. */
+   virtual ossimString getLongName()    const;
+
+   /** @return Descriptive name of filter. */
+   virtual ossimString getDescription() const;
+
+   /**
+    * @param tile_rect Rectangle to fill tile with.
+    * 
+    * @param resLevel Reduced resolution level to grab from.
+    * 
+    * @return ossimRefPtr<ossimImageData> This is tile that was filled with
+    * tile_rect.
+    *
+    * @note Callers should check the ossimRefPtr::valid method.
+    * The internal pointer of the ossimRefPtr<ossimImageData> can be
+    * null if the tile_rect did not intersect the input connection's
+    * bounding rectangle.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& tile_rect,
+                                               ossim_uint32 resLevel=0);
+   
+   /**
+    * Initializes state of the object from the input connection.
+    */
+   virtual void initialize();
+
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    *
+    * Keywords picked saved by saveState
+    * 
+    * filename: my_colormap_file.jpg
+    *
+    * weight: .25
+    * 
+    * watermark_mode:  upper_left
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /**
+    * Method to the load (recreate) the state of the object from a keyword
+    * list.
+    *
+    * @param kwl Keyword list to initialize from.
+    *
+    * @param prefix Usually something like: "object1."
+    *
+    * @return This method will alway return true as it is intended to be
+    * used in conjuction with the set methods.
+    *
+    * Keywords picked up by loadState:
+    * 
+    * filename: my_colormap_file.jpg
+    *
+    * weight: .25
+    * 
+    * watermark_mode:  upper_left
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * @param The property to get as a string like "watermark_mode".
+    *
+    * @return ossimRefPt<ossimProperty> holding pointer to ossimProperty
+    * matching string or null pointer if string does not match.
+    *
+    * @note Internal pointer can be null so callers should check prior to
+    * accessing like:
+    * ossimRefPtr<ossimProperty> p = myFilter->getProperty(ossimString("foo"));
+    * if (p.valid() == NULL)
+    * {
+    *    some_error;
+    * }
+    */
+   virtual ossimRefPtr<ossimProperty> getProperty(
+      const ossimString& name)const;
+
+   /**
+    * Set property.
+    *
+    * @param property Property to set if property->getName() matches a
+    * property name of this object.
+    */
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+
+   /**
+    * Adds this objects properties to the list.
+    *
+    * @param propertyNames Array to add to.
+    *
+    * @note This method does not clear propertyNames prior to adding it's
+    * names.
+    */
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   /**
+    * @param list List initialized with watermark mode strings.
+    *
+    * @note This method clears the "list" prior to stuffing.
+    */
+   void getModeList(vector<ossimString>& list) const;
+
+   /** @return theMode */
+   ossimWatermarkFilter::WatermarkMode getMode() const;
+
+   /** @return theMode as a string like "upper_left". */
+   ossimString getModeString() const;
+
+   /**
+    * Sets theFilename to file.
+    *
+    * @param file The watermark image file.
+    */
+   void setFilename(const ossimFilename& file);
+
+   /**
+    * Sets the filter mode.
+    *
+    * @param mode String representing mode.
+    */
+   void setMode(const ossimString& mode);
+
+   /**
+    * Sets the weight.
+    *
+    * @param weight Weight to use for watermark pixels normalize between
+    * 0.0 and 1.0.
+    */
+   void setWeight(ossim_float64 weight);
+   
+   /**
+    * Print method.  Called by: friend operator<<
+    * 
+    * @return std::ostream&
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+private:
+
+   /**
+    * Allocates / recomputes things that are needed.  Clears theDirtyFlag
+    * by setting it to false on success.
+    *
+    * @return true on success, false on error.
+    */
+   bool allocate();
+
+   /**
+    * Attempts to open "theFilename".  This will load "theWatermark" with
+    * the image converting it to the scalar type of the input connection.
+    *
+    * @return true on success, false if no image handler is found for the
+    * image or theInputConnection has not been established.
+    */
+   bool openWatermarkFile();
+   
+   // void verifyEnable();
+
+   /**
+    * Writes watermark(s) to theTile.
+    * Performs theTile->validate() at the end if theTile was touched.
+    */
+   template <class T> void fill(T dummy);
+
+   /**
+    * Computes the bounding rectangles.  These are the rectangles in image
+    * space of the input connection to paint the watermark(s) on.  The start of
+    * each rectangle will be the start of where "theWatermark" is painted.
+    */
+   void getIntersectingRects(vector<ossimIrect>& rects);
+
+   /**
+    * Addes upper left watermark rectangle to rects if it intersects
+    * theTile rect clipped to input bounding rect.
+    *
+    * @param rects Array to add rect to.
+    */
+   void getUpperLeftRect(vector<ossimIrect>& rects);
+   
+   /**
+    * Addes upper center watermark rectangle to rects if it intersects
+    * theTile rect clipped to input bounding rect.
+    *
+    * @param rects Array to add rect to.
+    */
+   void getUpperCenterRect(vector<ossimIrect>& rects);
+   
+   /**
+    * Addes upper right watermark rectangle to rects if it intersects
+    * theTile rect clipped to input bounding rect.
+    *
+    * @param rects Array to add rect to.
+    */
+   void getUpperRightRect(vector<ossimIrect>& rects);
+
+   /**
+    * Addes center watermark rectangle to rects if it intersects
+    * theTile rect clipped to input bounding rect.
+    *
+    * @param rects Array to add rect to.
+    */
+   void getCenterRect(vector<ossimIrect>& rects);
+
+   /**
+    * Addes lower left watermark rectangle to rects if it intersects
+    * theTile rect clipped to input bounding rect.
+    *
+    * @param rects Array to add rect to.
+    */
+   void getLowerLeftRect(vector<ossimIrect>& rects);
+
+   /**
+    * Addes lower center watermark rectangle to rects if it intersects
+    * theTile rect clipped to input bounding rect.
+    *
+    * @param rects Array to add rect to.
+    */
+   void getLowerCenterRect(vector<ossimIrect>& rects);
+   
+   /**
+    * Addes lower right watermark rectangle to rects if it intersects
+    * theTile rect clipped to input bounding rect.
+    *
+    * @param rects Array to add rect to.
+    */
+   void getLowerRightRect(vector<ossimIrect>& rects);
+   
+   /**
+    * Addes rectangles to rects if it intersects
+    * theTile rect clipped to input bounding rect.
+    *
+    * This will repeat the watermark throughout the input bounding rect.
+    *
+    * @param rects Array to add rect to.
+    */
+   void getUniformDenseRects(vector<ossimIrect>& rects);
+   
+   /**
+    * Addes rectangles to rects if it intersects
+    * theTile rect clipped to input bounding rect.
+    *
+    * This will repeat the watermark sparsly throughout the input bounding
+    * rect.
+    * 
+    * @param rects Array to add rect to.
+    */
+   void getUniformSparceRects(vector<ossimIrect>& rects);
+   
+   /** File name of watermark image. */
+   ossimFilename      theFilename;
+
+   /** Normalized between 0.0 and 1.0. */
+   ossim_float64      theWatermarkWeight;
+
+   /** The returned tile. */
+   ossimRefPtr<ossimImageData> theTile;
+
+   /** Tile storage for watermark image. */
+   ossimRefPtr<ossimImageData> theWatermark;
+
+   /** The number of watermark bands. */
+   ossim_uint32 theWatermarkNumberOfBands;
+
+   /** The filter mode. */
+   WatermarkMode      theMode;
+
+   /** The bounding rectangle of the input connection. */
+   ossimIrect theInputBoundingRect;
+
+   /** The number of input bands. */
+   ossim_uint32 theInputNumberOfBands;
+
+   /** The input scalar type. */
+   ossimScalarType theInputScalarType;
+
+   /**
+    * Set in the initialize method this instructs the getTile that something
+    * has changes and it need to call initialize.
+    */
+   bool theDirtyFlag;
+
+   /** For locking for threads. */
+   mutable ossimMutex theMutex;
+
+TYPE_DATA
+      
+}; // End of class ossimWatermarkFilter.
+
+#endif /* #ifndef ossimWatermarkFilter_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/.cvsignore b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbController.cpp b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbController.cpp
new file mode 100644
index 0000000000..fec899a13a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbController.cpp
@@ -0,0 +1,594 @@
+//*****************************************************************************
+// File: ossimAtbController.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains implementation of class ossimAtbController. This is the
+//    controller managing the tonal balancing process. It's product is the
+//    initialization of specialized remappers in each of the mosaic's member
+//    images that results in a tonally balanced mosaic.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimAtbController.cpp,v 1.12 2005/09/09 19:23:58 gpotts Exp $
+
+#include "ossimAtbController.h"
+
+RTTI_DEF2(ossimAtbController, "ossimAtbController", ossimProcessInterface, ossimConnectableObject );
+
+#include <stdio.h>
+#include "ossimGridRemapEngineFactory.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "ossimAtbMatchPoint.h"
+#include "ossimGridRemapSource.h"
+#include "base/common/ossimConnectableContainer.h"
+#include "imaging/tile_sources/ossimImageCombiner.h"
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include "base/common/ossimTrace.h"
+static ossimTrace traceExec  ("ossimAtbController:exec");
+static ossimTrace traceDebug ("ossimAtbController:debug");
+
+static const ossimIpt DEFAULT_GRID_SPACING (64,64);
+static const char* DEFAULT_ATB_REMAP_ENGINE = "ossimHsvGridRemapEngine";
+
+//*****************************************************************************
+//  CONSTRUCTOR:  ossimAtbController()
+//   
+//*****************************************************************************
+ossimAtbController::ossimAtbController()
+   :
+      ossimConnectableObject(NULL, 0, 0, false, true),
+      theContainer (0),
+      theGridRemapEngine (0),
+      theGridSpacing (DEFAULT_GRID_SPACING)
+{
+   static const char MODULE[] = "ossimAtbController Default Constructor";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   //***
+   // Instantiate a default remap engine:
+   //***
+   theGridRemapEngine
+     = ossimGridRemapEngineFactory::create(DEFAULT_ATB_REMAP_ENGINE);
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR:  ossimAtbController()
+//   
+//*****************************************************************************
+ossimAtbController::ossimAtbController(ossimImageCombiner* combiner,
+                                       ossimGridRemapEngine* engine)
+   :
+      ossimConnectableObject(NULL, 0, 0, false, true),
+      theContainer (0),
+      theGridRemapEngine (0),
+      theGridSpacing (DEFAULT_GRID_SPACING)
+{
+   static const char MODULE[] = "ossimAtbController Constructor #1";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   initializeWithCombiner(combiner, engine);
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR:  ossimAtbController()
+//   
+//*****************************************************************************
+ossimAtbController::ossimAtbController(ossimGridRemapEngine* engine)
+   :
+      theContainer (0),
+      theGridRemapEngine (0),
+      theGridSpacing (DEFAULT_GRID_SPACING)
+{
+   static const char MODULE[] = "ossimAtbController Constructor #1";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   //***
+   // Assign default engine if non provided:
+   //***
+   delete theGridRemapEngine;
+   if (engine)
+      theGridRemapEngine = (ossimGridRemapEngine*)engine->dup();
+   else
+      theGridRemapEngine
+         = ossimGridRemapEngineFactory::create(DEFAULT_ATB_REMAP_ENGINE);
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimAtbController()
+//
+//  The remappers are left behind, owned by the combiner's container. If the
+//  combiner was owned by something other than a container (see initialize()),
+//  then this controller will assume ownership of the allocated remappers and
+//  delete them here.
+//
+//*****************************************************************************
+ossimAtbController::~ossimAtbController()
+{
+   if (!theContainer)
+   {
+      //***
+      // No container exists that assumed ownership of the remappers, so delete
+      // them here:
+      //***
+      for (unsigned int i=0; i<getNumberOfInputs(); i++)
+         delete getInput(i);
+   }
+   
+   delete theGridRemapEngine;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::initializeWithCombiner()
+//  
+//*****************************************************************************
+void ossimAtbController::initializeWithCombiner(ossimImageCombiner* combiner,
+						ossimGridRemapEngine* engine)
+{
+   static const char MODULE[] = "ossimAtbController::initializeWithCombiner()";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   //***
+   // Assign default engine if non provided:
+   //***
+   delete theGridRemapEngine;
+   if (engine)
+      theGridRemapEngine = (ossimGridRemapEngine*)engine->dup();
+   else
+      theGridRemapEngine
+         = ossimGridRemapEngineFactory::create(DEFAULT_ATB_REMAP_ENGINE);
+   
+   //***
+   // This is the first combiner initializing the controller. The combiner
+   // will have all of the input sources connected already. We attach to
+   // these:
+   //***
+   theContainer = PTR_CAST(ossimConnectableContainer, combiner->getOwner());
+   
+   //***
+   // Need to scan the input connections of the combiner and insert a 
+   // remapper if there is not one already at the end of the input chain:
+   //***
+   vector<ossimConnectableObject*> del_list;
+   vector<ossimConnectableObject*> add_list;
+   int numInputs = combiner->getNumberOfInputs();
+   for(int i=0; i<numInputs; i++)
+   {
+      ossimImageSource* input_image = PTR_CAST(ossimImageSource,
+                                               combiner->getInput(i));
+      
+      if (input_image)
+      {
+         ossimGridRemapSource* remapper = PTR_CAST(ossimGridRemapSource,
+                                                   input_image);
+         if (remapper)
+         {
+            //***
+            // Remapper already present, set its remap engine to this
+            // controller's remap engine:
+            //***
+            remapper->setRemapEngine(theGridRemapEngine);
+         }
+         
+         else
+         {
+            //***
+            // Need to instantiate remapper:
+            //***
+            remapper = new ossimGridRemapSource(input_image,
+                                                theGridRemapEngine);
+            if (theContainer)
+               theContainer->addChild(remapper);
+            
+            add_list.push_back(remapper);
+            del_list.push_back(input_image);
+         }
+
+         connectMyInputTo(remapper);
+      }            
+   }
+   
+   //***
+   // Need to delete the old inputs and add the new remappers to the
+   // combiner's input list:
+   //***
+   vector<ossimConnectableObject*>::iterator add_iter = add_list.begin();
+   vector<ossimConnectableObject*>::iterator del_iter = del_list.begin();
+   while (add_iter != add_list.end())
+   {
+      (*add_iter)->connectMyInputTo(*del_iter);
+      combiner->disconnect(*del_iter);
+      combiner->connectMyInputTo(*add_iter);
+      add_iter++;
+      del_iter++;
+   }
+   combiner->initialize();
+      
+   if (traceExec())  CLOG << "returning..." << endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::enableImage()
+//  
+//  Enable an image in the mosaic to be included the tonal balancing process.
+//  
+//*****************************************************************************
+bool ossimAtbController::enableImage(unsigned int index)
+{
+   if (index >= getNumberOfInputs())
+      return false;
+
+   ossimSource* remapper = PTR_CAST(ossimSource,
+                                    getInput(index));
+   if (remapper)
+      remapper->enableSource();
+                                    
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::disableImage()
+//  
+//  Disable an image in the mosaic from the tonal balancing process.
+//  
+//*****************************************************************************
+bool ossimAtbController::disableImage(unsigned int index)
+{
+   if (index >= getNumberOfInputs())
+      return false;
+
+   ossimSource* remapper = PTR_CAST(ossimSource,
+                                    getInput(index));
+   if (remapper)
+      remapper->disableSource();
+
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::lockImage()
+//  
+//  Locks a particular source for adjustment. A locked image
+//  effectively defines the target values for all overlapping imagery.
+//  
+//*****************************************************************************
+bool ossimAtbController::lockImage(unsigned int index)
+{
+   if (index >= getNumberOfInputs())
+      return false;
+   
+   ossimGridRemapSource* remapper = PTR_CAST(ossimGridRemapSource,
+                                              getInput(index));
+   if (remapper)
+      remapper->lock();
+
+   return true;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::unlockImage()
+//  
+//  Unlocks a particular source for allowing its adjustment.
+//  
+//*****************************************************************************
+bool ossimAtbController::unlockImage(unsigned int index)
+{
+   if (index >= getNumberOfInputs())
+      return false;
+   
+   ossimGridRemapSource* remapper = PTR_CAST(ossimGridRemapSource,
+                                              getInput(index));
+   if (remapper)
+      remapper->lock();
+
+   return true;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::execute()
+//  
+//*****************************************************************************
+bool ossimAtbController::execute()
+{
+   static const char MODULE[] = "ossimAtbController::execute()";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   setPercentComplete(0.0);
+
+   ossimGridRemapSource* source;
+
+   //***
+   // First verify that all objects needed are initialized:
+   //***
+   int num_images = getNumberOfInputs();
+   if ((!theGridRemapEngine) || (num_images < 2))
+     {
+     CLOG << "WARNING: execute method was called but the controller has not "
+           << "been properly initialized. Ignoring request..." << endl;
+      if (traceExec())  CLOG << "returning..." << endl;
+      return false;
+   }
+   
+   //***
+   // establish the remap grids:
+   //***
+   initializeRemappers();
+   setPercentComplete(10.0);
+   
+   //***
+   // Establish grid of matchpoints:
+   //***
+   int numPoints = 0;
+   ossimDpt mp_view_pt;
+   theMatchPoints.clear();
+   for (mp_view_pt.line  = theBoundingRect.ul().line;
+        mp_view_pt.line <= theBoundingRect.lr().line;
+        mp_view_pt.line += theGridSpacing.line)
+   {
+      for (mp_view_pt.samp  = theBoundingRect.ul().samp;
+           mp_view_pt.samp <= theBoundingRect.lr().samp;
+           mp_view_pt.samp += theGridSpacing.samp)
+      {
+         ossimAtbMatchPoint* mp = new ossimAtbMatchPoint(mp_view_pt,
+                                                         theGridRemapEngine);
+         theMatchPoints.push_back(mp);
+         numPoints++;
+      }
+   }
+   
+   //***
+   // Loop over each matchpoint to determine which images contribute statistics:
+   //***
+   setPercentComplete(20.0);
+   for (int mp=0; mp<numPoints; mp++)
+   {
+      ossimDpt view_point (theMatchPoints[mp]->viewPoint());
+      
+      //***
+      // Loop over each image source to check if point lies inside its bounding
+      // rectangle, and add its contribution to the matchpoint's collection:
+      //***
+      for (int src=0; src<num_images; src++)
+      {
+         source = PTR_CAST(ossimGridRemapSource, getInput(src));
+         if (source)
+         {
+            ossimDrect image_rect (source->getBoundingRect());
+            if (image_rect.pointWithin(view_point))
+               theMatchPoints[mp]->addImage(source);
+         }
+      }
+
+      setPercentComplete(20.0 + 50.0*(mp/numPoints));
+   }
+
+   //***
+   // All contributors have been included in all matchpoints' collections.
+   // Compute the target pixel value for each matchpoint and communicate it
+   // to the corresponding remappers:
+   //***
+   for (int mp=0; mp<numPoints; mp++)
+   {
+      setPercentComplete(70.0 + 30.0*(mp/numPoints));
+      theMatchPoints[mp]->assignRemapValues();
+   }
+
+   //***
+   // Finally, enable the remappers:
+   //***
+   for (int src=0; src<num_images; src++)
+   {
+      source = PTR_CAST(ossimGridRemapSource, getInput(src));
+      if (source)
+         source->enableSource();
+   }
+   setPercentComplete(100.0);
+         
+   if (traceExec())  CLOG << "returning..." << endl;
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::abort()
+//  
+//*****************************************************************************
+void ossimAtbController::abort()
+{
+   static const char MODULE[] = "ossimAtbController::abort()";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   CLOG << "NOTICE: this method not yet implemented." << endl;
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::saveState()
+//  
+//*****************************************************************************
+bool ossimAtbController::saveState(ossimKeywordlist& kwl) const
+{
+   static const char MODULE[] = "ossimAtbController::saveState()";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   CLOG << "NOTICE: this method not yet implemented." << endl;
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::loadState()
+//  
+//*****************************************************************************
+bool ossimAtbController::loadState(const ossimKeywordlist& kwl)
+{
+   static const char MODULE[] = "ossimAtbController::loadState()";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   CLOG << "NOTICE: this method not yet implemented." << endl;
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return true;
+}
+
+
+//*****************************************************************************
+//  METHOD:  ossimAtbController::setKernelSize(N)
+//  
+//  Hook to set the size of the kernel used by all point sources in computing
+//  their mean pixel value. The kernels will be resized to NxN.
+//  
+//*****************************************************************************
+void ossimAtbController::setKernelSize(int side_size)
+{
+   static const char MODULE[] = "ossimAtbController::setKernelSize(N)";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   vector<ossimAtbMatchPoint*>::iterator mpi = theMatchPoints.begin();
+   while (mpi != theMatchPoints.end())
+      (*mpi)->setKernelSize(side_size);
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+
+//*****************************************************************************
+//  PRIVATE METHOD:  ossimAtbController::initializeRemappers()
+//  
+//*****************************************************************************
+void ossimAtbController::initializeRemappers()
+{
+   static const char MODULE[] = "ossimAtbController::initializeRemappers()";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   int num_images = getNumberOfInputs();
+
+   //***
+   // Fetch the overall mosaic bounding rect:
+   //***
+   ossimGridRemapSource* remapper = PTR_CAST(ossimGridRemapSource,
+                                             getInput(0));
+   theBoundingRect = remapper->getBoundingRect();
+   for (int src=1; src<num_images; src++)
+   {
+      theBoundingRect = theBoundingRect.combine(remapper->getBoundingRect());
+   }
+ 
+   //***
+   // Loop over each contribution image source chain to fetch each image
+   // bounding rect:
+   //***
+   double dx_ul, dy_ul, dx_lr, dy_lr;
+   double grid_ul_x, grid_ul_y, grid_lr_x, grid_lr_y;
+   for (int src=0; src<num_images; src++)
+   {
+      remapper = PTR_CAST(ossimGridRemapSource, getInput(src));
+      ossimDrect image_rect (remapper->getBoundingRect());
+
+      //***
+      // Arrive at the number of grid posts from mosaic origin to image's grid
+      // UL and LR corners:
+      //***
+      dx_ul = (image_rect.ul().x - theBoundingRect.ul().x)/theGridSpacing.x;
+      dy_ul = (image_rect.ul().y - theBoundingRect.ul().y)/theGridSpacing.y;
+      dx_lr = (image_rect.lr().x - theBoundingRect.lr().x)/theGridSpacing.x;
+      dy_lr = (image_rect.lr().y - theBoundingRect.lr().y)/theGridSpacing.y;
+   
+      //***
+      // Establish the view coordinates for the adjusted image grid:
+      //***
+      grid_ul_x =  theBoundingRect.ul().x + ceil(dx_ul)*theGridSpacing.x;
+      grid_ul_y =  theBoundingRect.ul().y + ceil(dy_ul)*theGridSpacing.y;
+      grid_lr_x =  theBoundingRect.lr().x + floor(dx_lr)*theGridSpacing.x;
+      grid_lr_y =  theBoundingRect.lr().y + floor(dy_lr)*theGridSpacing.y;
+
+      //***
+      // Have the remapper initialize a new grid with the given rectangle and
+      // spacing:
+      //***
+      ossimDrect grid_rect (grid_ul_x, grid_ul_y, grid_lr_x, grid_lr_y);
+      remapper->initialize(grid_rect, theGridSpacing);
+   }
+      
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::setGridRemapEngine()
+//  
+//*****************************************************************************
+void ossimAtbController::setGridRemapEngine(ossimGridRemapEngine* engine)
+{
+   static const char MODULE[] = "ossimAtbController::setGridRemapEngine()";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   if (theGridRemapEngine)
+      delete theGridRemapEngine;
+
+   theGridRemapEngine = engine;
+
+   //***
+   // Communicate the new engine to all member's interested:
+   //***
+   ossimGridRemapSource* remapper;
+   vector<ossimConnectableObject*>::iterator iter=theInputObjectList.begin();
+   while (iter != theInputObjectList.end())
+   {
+      remapper = PTR_CAST(ossimGridRemapSource, *iter);
+      remapper->setRemapEngine(engine);
+      iter++;
+   }
+
+   vector<ossimAtbMatchPoint*>::iterator match_point = theMatchPoints.begin();
+   while (match_point != theMatchPoints.end())
+   {
+      (*match_point)->setGridRemapEngine(engine);
+      match_point++;
+   }
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimAtbController::canConnectMyInputTo()
+//  
+//*****************************************************************************
+bool ossimAtbController::canConnectMyInputTo(ossim_int32 myInputIndex,
+                                    const ossimConnectableObject* object) const
+{
+   return (object&& PTR_CAST(ossimGridRemapSource, object));
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbController.h b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbController.h
new file mode 100644
index 0000000000..29fe9e829d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbController.h
@@ -0,0 +1,162 @@
+//*****************************************************************************
+// FILE: ossimAtbController.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains declaration of class ossimAtbController.
+//   This is the class for the top-level object controlling the automated
+//   tonal balancing (ATB) function. The controller accepts a mosaic.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimAtbController.h,v 1.6 2005/09/12 13:15:52 gpotts Exp $
+
+#ifndef ossimAtbController_HEADER
+#define ossimAtbController_HEADER
+
+#include "base/data_types/ossimIpt.h"
+#include "base/data_types/ossimDrect.h"
+#include "base/common/ossimConnectableObject.h"
+#include "base/common/ossimProcessInterface.h"
+#include <vector>
+
+class ossimImageCombiner;
+class ossimKeywordlist;
+class ossimAtbMatchPoint;
+class ossimGridRemapSource;
+class ossimGridRemapEngine;
+class ossimConnectableContainer;
+
+/*****************************************************************************
+ *
+ * CLASS: ossimAtbController 
+ *
+ *****************************************************************************/
+class ossimAtbController :
+   public ossimConnectableObject,
+   public ossimProcessInterface
+{
+public:
+   /*!
+    * default Constructor initializes the member combiner pointer to NULL.
+    */
+   ossimAtbController();
+   
+   /*!
+    * Constructor with Combiner reference. This combiner is used for the ATB.
+    */
+   ossimAtbController(ossimImageCombiner*   combiner,
+                      ossimGridRemapEngine* engine=0);
+
+   /*!
+    * Constructor with a specified remap engine.
+    */
+   ossimAtbController(ossimGridRemapEngine* engine);
+
+   ~ossimAtbController();
+
+  virtual ossimObject* getObject()
+  {
+    return this;
+  }
+  virtual const ossimObject* getObject()const
+  {
+    return this;
+  }
+   /*!
+    * Provide alternate means of initialization in case default constructor
+    * used.
+    */
+   void initializeWithCombiner(ossimImageCombiner*   combiner,
+			       ossimGridRemapEngine* engine=0);
+   
+   /*!
+    * Enable an image in the mosaic for the tonal balancing process
+    */
+   bool enableImage (unsigned int index);
+
+   /*!
+    * Disnable an image in the mosaic from the tonal balancing process
+    */
+   bool disableImage(unsigned int index);
+
+   /*!
+    * Locks a particular source for adjustment. A locked image
+    * effectively defines the target values for all overlapping imagery. 
+    */
+   bool lockImage      (unsigned int index);
+
+   /*!
+    * Unlock a particular source for adjustment. 
+    */
+   bool unlockImage    (unsigned int index);
+
+   /*!
+    * Implementation of ossimProcessInterface pure virtual method.
+    */
+   virtual bool execute();
+   virtual void abort();
+
+   /*!
+    * Hook to set the size of the kernel used by all point sources in computing
+    * their mean pixel value. The kernels will be resized to NxN.
+    */
+   void setKernelSize(int side_size);
+
+   /*!
+    * Sets the grid spacing used in gridding the mosaic's bounding rectangle.
+    */
+   void setGridSpacing(const ossimIpt& spacing);
+
+   /*!
+    * Sets the ATB remap engine. This object implements the specific tonal
+    * balancing algorithm. The dependency on number of bands and color space,
+    * is limited only to this engine. This facilitates the implementation of
+    * various grid-based image matching schemes.
+    */
+   void setGridRemapEngine(ossimGridRemapEngine* engine);
+   
+   /*!
+    * Implementations of ossimStateInterface pure virtuals
+    */
+   virtual bool saveState(ossimKeywordlist& kwl) const;
+   virtual bool loadState(const ossimKeywordlist& kwl);
+   
+   /*!
+    * Implementation of ossimConnectableObject pure virtual.
+    */
+   virtual bool canConnectMyInputTo(ossim_int32 myInputIndex,
+                                    const ossimConnectableObject* object)const;
+
+   
+protected:
+   void initializeRemappers();
+
+   ossimDrect                    theBoundingRect;
+   ossimConnectableContainer*    theContainer;
+   ossimGridRemapEngine*         theGridRemapEngine;
+   vector<ossimAtbMatchPoint*>   theMatchPoints;
+   ossimIpt                      theGridSpacing;
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbMatchPoint.cpp b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbMatchPoint.cpp
new file mode 100644
index 0000000000..c4bc9e21df
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbMatchPoint.cpp
@@ -0,0 +1,169 @@
+//*****************************************************************************
+// FILE: ossimAtbMatchPoint.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains implementation of class 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimAtbMatchPoint.cpp,v 1.3 2001/12/14 19:45:57 okramer Exp $
+
+#include "ossimAtbMatchPoint.h"
+#include "ossimAtbPointSource.h"
+#include "ossimGridRemapEngine.h"
+#include "ossimGridRemapSource.h"
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include "base/common/ossimTrace.h"
+static ossimTrace traceExec  ("ossimAtbMatchPoint:exec");
+static ossimTrace traceDebug ("ossimAtbMatchPoint:debug");
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimAtbMatchPoint()
+//  
+//  Need to delete each instance of an ossimAtbPointSource in thePointSourceList
+//  
+//*****************************************************************************
+ossimAtbMatchPoint::~ossimAtbMatchPoint()
+{
+   vector<ossimAtbPointSource*>::iterator source = thePointSourceList.begin();
+   while (source != thePointSourceList.end())
+   {
+      delete *source;
+      source++;
+   }
+}
+   
+//*****************************************************************************
+//  METHOD: ossimAtbMatchPoint::addImage()
+//
+//  Adds a new contribution to the sample set.
+//
+//*****************************************************************************
+void ossimAtbMatchPoint::addImage(ossimGridRemapSource* remapper)
+{
+   static const char MODULE[] = "ossimAtbMatchPoint::addImage()";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // Assure that this image contains the view point corresponding to this
+   // matchpoint:
+   //***
+   if (!remapper->getBoundingRect().pointWithin(theViewPoint))
+   {
+      if (traceExec())  CLOG << "returning..." << endl;
+      return;
+   }
+
+   //***
+   // Instantiate a point source for this image at this view point and
+   // save it in the list:
+   //***
+   ossimAtbPointSource* point_source = new ossimAtbPointSource(remapper,
+                                                               theViewPoint);
+   thePointSourceList.push_back(point_source);
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimAtbMatchPoint::assignRemapValues()
+//
+//  The target parameter value computed given all contributions. The target
+//  value is then used to establish the remap parameters for each image at this
+//  points location. 
+//
+//*****************************************************************************
+bool ossimAtbMatchPoint::assignRemapValues()
+{
+   static const char MODULE[] = "ossimAtbMatchPoint::assignRemapValues()";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // Determine the number of contributors. We require minimum of two:
+   //***
+   int num_contributors = thePointSourceList.size();
+   if (num_contributors < 2)
+      return false;
+
+   //***
+   // Hand off the computation of the target pixel to the ATB engine being
+   // used. The engine implements the methods for computing targets, as these
+   // will vary according to algorithm being used:
+   //***
+   theGridRemapEngine->assignRemapValues(thePointSourceList);
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return true;
+}
+
+   
+//*****************************************************************************
+//  METHOD:  ossimAtbMatchPoint::setKernelSize(N)
+//  
+//  Hook to set the size of the kernel used by all point sources in computing
+//  their mean pixel value. The kernels will be resized to NxN.
+//  
+//*****************************************************************************
+void ossimAtbMatchPoint::setKernelSize(int side_size)
+{
+   static const char MODULE[] = "ossimAtbController::setKernelSize(N)";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   vector<ossimAtbPointSource*>::iterator psi = thePointSourceList.begin();
+   while (psi != thePointSourceList.end())
+      (*psi)->setKernelSize(side_size);
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimAtbMatchPoint::setAtbRemapEngine
+//  
+//*****************************************************************************
+void ossimAtbMatchPoint::setGridRemapEngine(ossimGridRemapEngine* engine)
+{
+   static const char MODULE[] = "ossimAtbMatchPoint::setAtbRemapEngine";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   theGridRemapEngine = engine;
+   
+   //***
+   // Need to communicate this change of engine to the point sources that use
+   // it to arrive at a "source value":
+   //***
+   vector<ossimAtbPointSource*>::iterator source = thePointSourceList.begin();
+   while (source != thePointSourceList.end())
+   {
+      (*source)->setGridRemapEngine(engine);
+      source++;
+   }
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbMatchPoint.h b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbMatchPoint.h
new file mode 100644
index 0000000000..7a987218ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbMatchPoint.h
@@ -0,0 +1,104 @@
+//*****************************************************************************
+// FILE: ossimAtbMatchPoint.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains declaration of class ossimAtbMatchPoint. This class
+//    is used by the automated tonal balancing code for bookkeeping and
+//    statistics associated with match-points. Match points are points shared in
+//    common between two or more images being adjusted. 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimAtbMatchPoint.h,v 1.4 2001/12/14 20:16:25 okramer Exp $
+
+#ifndef ossimAtbMatchPoint_HEADER
+#define ossimAtbMatchPoint_HEADER
+
+#include "base/data_types/ossimDpt.h"
+#include <vector>
+using namespace std;
+
+class ossimAtbPointSource;
+class ossimGridRemapEngine;
+class ossimGridRemapSource;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimAtbMatchPoint
+ *
+ *****************************************************************************/
+class ossimAtbMatchPoint
+{
+public:
+   ossimAtbMatchPoint()
+      : theGridRemapEngine(0) {}
+   
+   ossimAtbMatchPoint(const ossimDpt& view_point,
+                      ossimGridRemapEngine* engine)
+      : theViewPoint(view_point), theGridRemapEngine(engine) {}
+
+   ~ossimAtbMatchPoint();
+   
+   /*!
+    * Returns the point in view coordinates associated with this object.
+    */
+   const ossimDpt& viewPoint() const { return theViewPoint; }
+
+   /*!
+    * Adds a new contribution to the sample set.
+    */
+   void addImage(ossimGridRemapSource* image_source);
+
+   /*!
+    * The target parameter value computed given all contributions. Returns true
+    * if a valid quantity is returned.
+    */
+   bool assignRemapValues();
+
+   /*!
+    * Hook to set the size of the kernel used by all point sources in computing
+    * their mean pixel value. The kernels will be resized to NxN.
+    */
+   void setKernelSize(int side_size);
+
+   /*!
+    * Sets the ATB remap engine reference owned by the controller. This engine
+    * is the only object that understands how to compute remap parameters from
+    * pixel data. This permits easily modifying the ATB algorithm without
+    * the support classes such as this one.
+    */
+   void setGridRemapEngine(ossimGridRemapEngine* engine);
+
+   /*!
+    * Dumps the contents of the object to the stream in human readable format.
+    */
+//   void print(ostream& os) const;
+
+//   friend ostream& operator << (ostream& os);
+
+private:
+   ossimDpt                     theViewPoint;
+   vector<ossimAtbPointSource*> thePointSourceList; 
+   ossimGridRemapEngine*        theGridRemapEngine;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbPointSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbPointSource.cpp
new file mode 100644
index 0000000000..147b3d5355
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbPointSource.cpp
@@ -0,0 +1,206 @@
+//*****************************************************************************
+// FILE: ossimAtbPointSource.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains implementation of class ossimAtbPointSource.
+//   This object provides the statistics associated with a given point on a
+//   given image corresponding to a matchpoint. A matchpoint contains a
+//   collection of these point sources, one for each contributing image.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimAtbPointSource.cpp,v 1.5 2005/02/11 15:07:34 dburken Exp $
+
+#include "imaging/ossimImageSource.h"
+#include "imaging/ossimImageData.h"
+#include "imaging/factory/ossimImageDataFactory.h"
+#include "ossimGridRemapSource.h"
+#include "ossimGridRemapEngine.h"
+#include "ossimAtbPointSource.h"
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include "base/common/ossimTrace.h"
+static ossimTrace traceExec  ("ossimImageSource:exec");
+static ossimTrace traceDebug ("ossimImageSource:debug");
+
+static const int DEFAULT_KERNEL_SIZE = 18;  // recommend odd number
+
+//*****************************************************************************
+//  DEFAULT CONSTRUCTOR: ossimAtbPointSource
+//  
+//*****************************************************************************
+ossimAtbPointSource::ossimAtbPointSource()
+   : theRemapSource (0),
+     theGridRemapEngine (0),
+     theKernelSize (DEFAULT_KERNEL_SIZE),
+     theViewPointIsValid (false)
+{
+   static const char MODULE[] = "ossimAtbPointSource Default Constructor";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   if (traceExec())  CLOG << "returning..." << endl;
+}
+      
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimAtbPointSource(image_source)
+//  
+//*****************************************************************************
+ossimAtbPointSource::ossimAtbPointSource(ossimGridRemapSource* source,
+                                         const ossimDpt&    view_point)
+   : theRemapSource (source),
+     theGridRemapEngine (source->getRemapEngine()),
+     theKernelSize (DEFAULT_KERNEL_SIZE),
+     theViewPointIsValid (false)
+{
+   static const char MODULE[] = "ossimAtbPointSource Default Constructor";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   setViewPoint(view_point);
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+}
+
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimAtbPointSource()
+//  
+//*****************************************************************************
+ossimAtbPointSource::~ossimAtbPointSource()
+{
+}
+
+//*****************************************************************************
+//  METHOD: ossimAtbPointSource::setRemapSource()
+//  
+//  Sets the pointer to the source of pixels used to compute the stats.
+//  
+//*****************************************************************************
+void ossimAtbPointSource::setRemapSource(ossimGridRemapSource* source)
+{
+   static const char MODULE[] = "ossimAtbPointSource::setRemapSource()";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   theRemapSource = source;
+
+   //***
+   // Also fetch the remap engine which should be a derived ossimAtbRemapEngine:
+   //***
+   theGridRemapEngine = theRemapSource->getRemapEngine();
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimAtbPointSource::setViewPoint()
+//  
+//  Sets the view coordinates corresponding to this point.
+//  
+//*****************************************************************************
+void ossimAtbPointSource::setViewPoint(const ossimDpt& view_point)
+{
+   static const char MODULE[] = "ossimAtbPointSource::setViewPoint()";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   theViewPoint = view_point;
+   
+   if ((theRemapSource) &&
+       (theRemapSource->getBoundingRect().pointWithin(theViewPoint)))
+      theViewPointIsValid = true;
+   else
+      theViewPointIsValid = false;
+         
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimAtbPointSource::getSourceValue()
+//  
+//  Returns the computed value vector corresponding to the region about the
+//  view point. The definition of "value" is implemented by theGridRemapEngine.
+//
+//*****************************************************************************
+void ossimAtbPointSource::getSourceValue(void* value_vector)
+{
+   static const char MODULE[] = "ossimAtbPointSource::getSourceValue()";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // Verify that members are initialized before processing:
+   //***
+   if ((!theViewPointIsValid) || (!theRemapSource) || (!theGridRemapEngine))
+   {
+      CLOG <<"ERROR: This object was not properly initialized before attempting"
+           <<" to compute target value! Returning usassigned vector..."<<endl;
+      return;
+   }
+
+   //***
+   // Extract the data kernel from the image chain:
+   //***
+   ossimIpt kernel_2d_size (theKernelSize, theKernelSize);
+   ossimIpt kernel_ul (theViewPoint - kernel_2d_size/2.0);
+   ossimIpt kernel_lr (kernel_ul.x + kernel_2d_size.x - 1,
+                       kernel_ul.y + kernel_2d_size.y - 1);
+   ossimIrect kernel_rect (kernel_ul, kernel_lr);
+   ossimRefPtr<ossimImageData> kernel_data =
+      theRemapSource->getTile(kernel_rect);
+
+   //***
+   // Fetch the value of the data kernel. Note: this is not necessarily in
+   // the same color space as the pixels. It depends on which engine is being
+   // utilized:
+   //***
+   theGridRemapEngine->computeSourceValue(kernel_data, value_vector);
+
+//   delete kernel_data;
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimAtbPointSource:: setKernelSize(N)
+//
+//  Method to set the kernel size used in computing statistics. The kernel
+//  will be resized to NxN.
+//
+//*****************************************************************************
+void ossimAtbPointSource::setKernelSize(int side_size)
+{
+   static const char MODULE[] = "ossimAtbPointSource::setKernelSize()";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   theKernelSize = side_size;
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+ 
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbPointSource.h b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbPointSource.h
new file mode 100644
index 0000000000..f79d1fce9b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimAtbPointSource.h
@@ -0,0 +1,108 @@
+//*****************************************************************************
+// FILE: ossimAtbPointSource.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains declaration of class ossimAtbPointSource.
+//   This object provides the statistics associated with a given point on a
+//   given image corresponding to a matchpoint. A matchpoint contains a
+//   collection of these point sources, one for each contributing image.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimAtbPointSource.h,v 1.2 2001/12/14 20:10:39 okramer Exp $
+
+#ifndef ossimAtbPointSource_HEADER
+#define ossimAtbPointSource_HEADER
+
+#include "base/data_types/ossimDpt.h"
+
+class ossimImageSource;
+class ossimImageData;
+class ossimGridRemapSource;
+class ossimGridRemapEngine;
+
+/*!****************************************************************************
+ *
+ * CLASS: ossimAtbPointSource 
+ *
+ *****************************************************************************/
+class ossimAtbPointSource
+{
+public:
+   ossimAtbPointSource();
+   ossimAtbPointSource(ossimGridRemapSource* remap_source,
+                       const ossimDpt&       view_point);
+
+   ~ossimAtbPointSource();
+
+   /*!
+    * Sets the pointer of the source of pixels used to compute the stats.
+    */
+   void setRemapSource(ossimGridRemapSource* image_source);
+
+   /*!
+    * Returns the reference to the remapper feeding this source.
+    */
+   ossimGridRemapSource* getRemapSource() { return theRemapSource; }
+
+   /*!
+    * Sets the view coordinates corresponding to this point.
+    */
+   void setViewPoint(const ossimDpt& view_point);
+
+   /*!
+    * Returns the view point corresponding to this point source.
+    */
+   const ossimDpt& getViewPoint() const { return theViewPoint; }
+
+   /*!
+    * Returns the computed value vector corresponding to the region about the
+    * view point. The ATB Remap engine performs the actual computation, since
+    * the definition of "value" is algorithm dependent (the value may be in a
+    * different color space).
+    */
+   void getSourceValue(void* value);
+
+   /*!
+    * Method to set the kernel size used in computing statistics. The kernel
+    * will be resized to NxN.
+    */
+   void setKernelSize(int side_size);
+
+   /*!
+    * Sets the ATB remap engine reference owned by the controller. This engine
+    * is the only object that understands how to compute remap parameters from
+    * pixel data. This permits easily modifying the ATB algorithm without
+    * the support classes such as this one.
+    */
+   void setGridRemapEngine(ossimGridRemapEngine* engine)
+      { theGridRemapEngine = engine; }
+   
+private:
+   ossimGridRemapSource* theRemapSource;
+   ossimDpt              theViewPoint;
+   ossimGridRemapEngine* theGridRemapEngine;
+   int                   theKernelSize;
+   bool                  theViewPointIsValid;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngine.cpp b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngine.cpp
new file mode 100644
index 0000000000..37c646d179
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngine.cpp
@@ -0,0 +1,32 @@
+//*****************************************************************************
+// FILE: ossimGridRemapEngine.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains declaration of class 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimGridRemapEngine.cpp,v 1.1 2001/12/03 21:52:09 gpotts Exp $
+
+#include "ossimGridRemapEngine.h"
+
+RTTI_DEF1(ossimGridRemapEngine, "ossimGridRemapEngine", ossimObject);
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngine.h b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngine.h
new file mode 100644
index 0000000000..dffba663b5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngine.h
@@ -0,0 +1,69 @@
+//*****************************************************************************
+// FILE: ossimGridRemapEngine.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains declaration of class 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimGridRemapEngine.h,v 1.5 2005/10/17 18:42:27 gpotts Exp $
+
+#ifndef ossimGridRemapEngine_HEADER
+#define ossimGridRemapEngine_HEADER
+
+#include <vector>
+#include <base/common/ossimObject.h>
+#include <base/common/ossimRefPtr.h>
+
+class ossimDpt;
+class ossimGridRemapSource;
+class ossimImageData;
+class ossimAtbPointSource;
+
+/*!****************************************************************************
+ *
+ * CLASS: ossimGridRemapEngine 
+ *
+ *****************************************************************************/
+class ossimGridRemapEngine : public ossimObject
+{
+public:
+   virtual ossimObject* dup() const = 0;
+   
+   virtual void remapTile(const ossimDpt&       origin_point,
+                          ossimGridRemapSource* remapper,
+                          ossimRefPtr<ossimImageData>& tile) = 0;
+
+   virtual void assignRemapValues(std::vector<ossimAtbPointSource*>& sources)=0;
+
+   virtual void computeSourceValue(ossimRefPtr<ossimImageData>& source,
+                                   void* result) = 0;
+
+   int  getNumberOfParams() const { return theNumberOfParams; }
+   
+   int  getNumberOfBands()  const { return theNumberOfBands; }
+   
+protected:
+   ossimGridRemapEngine(int numParams, int numBands)
+      : theNumberOfParams(numParams), theNumberOfBands(numBands) {}
+
+   ossimGridRemapEngine() {}
+
+   virtual void computeRemapNode(ossimAtbPointSource*  point_source,
+                                 void*                 source_value,
+                                 void*                 target_value) = 0;
+   int  theNumberOfParams;
+   int  theNumberOfBands;
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngineFactory.cpp b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngineFactory.cpp
new file mode 100644
index 0000000000..0c772cb000
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngineFactory.cpp
@@ -0,0 +1,44 @@
+//*****************************************************************************
+// FILE: ossimGridRemapEngineFactory.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class ossimGridRemapEngineFactory
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimGridRemapEngineFactory.cpp,v 1.2 2005/02/11 15:07:35 dburken Exp $
+
+#include <imaging/tonal_balance/ossimGridRemapEngineFactory.h>
+#include <imaging/tonal_balance/ossimHsvGridRemapEngine.h>
+#include <imaging/tonal_balance/ossimRgbGridRemapEngine.h>
+#include <imaging/tonal_balance/ossimMonoGridRemapEngine.h>
+
+//*****************************************************************************
+//  STATIC METHOD: ossimGridRemapEngineFactory::create()
+//  
+//*****************************************************************************
+ossimGridRemapEngine* ossimGridRemapEngineFactory::create(const char* s)
+{
+   if (!s)
+      return 0;
+   
+   if (strcmp(s, "ossimHsvGridRemapEngine") == 0)
+      return new ossimHsvGridRemapEngine;
+
+   else  if (strcmp(s, "ossimRgbGridRemapEngine") == 0)
+      return new ossimRgbGridRemapEngine;
+
+   else  if (strcmp(s, "ossimMonoGridRemapEngine") == 0)
+      return new ossimMonoGridRemapEngine;
+
+   return 0;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngineFactory.h b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngineFactory.h
new file mode 100644
index 0000000000..d987b09194
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapEngineFactory.h
@@ -0,0 +1,53 @@
+//*****************************************************************************
+// FILE: ossimGridRemapEngineFactory.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains declaration of class ossimGridRemapEngineFactory
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimGridRemapEngineFactory.h,v 1.2 2001/12/05 00:04:31 okramer Exp $
+
+#ifndef ossimGridRemapEngineFactory_HEADER
+#define ossimGridRemapEngineFactory_HEADER
+
+class ossimGridRemapEngine;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimGridRemapEngineFactory (SIMPLETON)
+ *
+ *****************************************************************************/
+class ossimGridRemapEngineFactory
+{
+public:
+   /*!
+    * Attempts to create an instance of the Product given a Specifier. Returns
+    * successfully constructed product or NULL.
+    */
+   static ossimGridRemapEngine* create(const char* spec);
+   
+protected:
+   ossimGridRemapEngineFactory() {}
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapSource.cpp b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapSource.cpp
new file mode 100644
index 0000000000..39d271b53d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapSource.cpp
@@ -0,0 +1,368 @@
+//*****************************************************************************
+// FILE: ossimGridRemapper.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class ossimGridRemapper. This is
+//   a spacially variant remapper that utilizes a grid for interpolating the
+//   remap value given an image x, y. 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimGridRemapSource.cpp,v 1.10 2005/09/09 19:23:58 gpotts Exp $
+
+#include "ossimGridRemapSource.h"
+
+RTTI_DEF1(ossimGridRemapSource, "ossimGridRemapSource", ossimImageSourceFilter);
+
+#include <stdio.h>
+#include <fstream>
+#include "imaging/ossimImageData.h"
+#include "base/data_types/ossimDrect.h"
+#include "base/data_types/ossimDpt.h"
+#include "base/data_types/ossimDblGrid.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "ossimGridRemapEngineFactory.h"
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include "base/common/ossimTrace.h"
+static ossimTrace traceExec  ("ossimGridRemapSource:exec");
+static ossimTrace traceDebug ("ossimGridRemapSource:debug");
+
+static const char* GRID_FILENAME_KW        = "grid_remap_file";
+static const char* REMAP_ENGINE_KW         = "remap_engine";
+
+//*****************************************************************************
+//  DEFAULT CONSTRUCTOR #1: ossimGridRemapper()
+//  
+//*****************************************************************************
+ossimGridRemapSource::ossimGridRemapSource()
+   :
+      ossimImageSourceFilter(),
+      theGridFilename (0),
+      theRemapEngine (0),
+      theRemapIsLockedFlag(true),
+      theGridIsFilled(false)
+{
+   disableSource();
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR #2: ossimGridRemapper(inputSource)
+//  
+//*****************************************************************************
+ossimGridRemapSource::ossimGridRemapSource(ossimImageSource* inputSource,
+                                           ossimGridRemapEngine* engine)
+   :
+      ossimImageSourceFilter(inputSource),
+      theGridFilename (0),
+      theRemapEngine ((ossimGridRemapEngine*)engine->dup()),
+      theRemapIsLockedFlag(true),
+      theGridIsFilled(false)
+{
+   disableSource();
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimGridRemapSource
+//  
+//*****************************************************************************
+ossimGridRemapSource::~ossimGridRemapSource()
+{
+   deallocateGrids();
+   delete theRemapEngine;
+}
+
+//*****************************************************************************
+//  METHOD: ossimGridRemapSource::initialize
+//  
+//*****************************************************************************
+void ossimGridRemapSource::initialize(const ossimDrect& uv_rect,
+                                      const ossimDpt&   grid_spacing)
+{
+   deallocateGrids();
+   int num_params;
+   
+   if (theRemapEngine)
+   {
+      num_params = theRemapEngine->getNumberOfParams();
+      
+      for (int p=0; p<num_params; p++)
+      {
+         ossimDblGrid* grid = new ossimDblGrid(uv_rect, grid_spacing);
+         theGrids.push_back(grid);
+      }
+      
+      theGridFilename = ossimFilename(ossimString("ogrs") +
+                                      ossimString::toString((int)this) +
+                                      ossimString(".org"));
+
+      theGridIsFilled = false;
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimGridRemapSource::getTile()
+//  
+//  Implementation of virtual method to return remapped tile.
+//  
+//*****************************************************************************
+ossimRefPtr<ossimImageData> ossimGridRemapSource::getTile(
+   const ossimIrect& rect, ossim_uint32 resLevel)
+{
+   if(!theInputConnection)
+      return NULL;
+
+   //***
+   // Fetch tile from input source:
+   //***
+   ossimRefPtr<ossimImageData> tile = theInputConnection->getTile(rect,
+                                                                  resLevel);
+
+   //---
+   // Bypass this filter if it is not initialized, or if input tile is bogus:
+   //---
+   if ((!isSourceEnabled()) || (!tile.valid()) || (!theRemapEngine) ||
+       (tile->getDataObjectStatus()==OSSIM_NULL) ||
+       (tile->getDataObjectStatus()==OSSIM_EMPTY))
+   {
+      return tile;
+   }
+   
+   //***
+   // Insure that the grid has been filled in case nodes were being randomly set
+   //***
+   if (!theGridIsFilled)
+   {
+      vector<ossimDblGrid*>::iterator grid = theGrids.begin();
+      while (grid != theGrids.end())
+      {
+//         (*grid)->setInterpolationType(ossimDblGrid::BILINEAR);
+         (*grid)->interpolateNullValuedNodes();
+         grid++;
+      }
+      theGridIsFilled = true;
+   }
+   
+   //***
+   // hand off the actual remap to the ATB engine. This object knows how to
+   // interpret the grids for the particular remap algorithm selected:
+   //***
+   theRemapEngine->remapTile(rect.ul(), this, tile);
+   
+   tile->validate();
+   return tile;
+}
+
+//*****************************************************************************
+//  METHOD: ossimGridRemapSource::loadState()
+//  
+//*****************************************************************************
+bool ossimGridRemapSource::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   static const char MODULE[] = "ossimGridRemapSource::loadState()";
+   if (traceExec())  CLOG << "entering..." << endl;
+   
+   bool successful = false;
+   const char* value;
+
+   //***
+   // Reset object in preparation for reassignment:
+   //***
+   deallocateGrids();
+   delete theRemapEngine;
+   
+   //***
+   // Read the remap engine type:
+   //***
+   value = kwl.find(prefix, REMAP_ENGINE_KW);
+   theRemapEngine = ossimGridRemapEngineFactory::create(value);
+   if (!theRemapEngine)
+   {
+//      CLOG << "ERROR: could not instantiate remap engine. Aborting..." << endl;
+//      if (traceExec())  CLOG << "returning..." << endl;
+//      return false;
+   }
+   
+   //***
+   // Read the grid filename and open input stream:
+   //***
+   theGridIsFilled = false;
+   value = kwl.find(prefix, GRID_FILENAME_KW);
+   if (value)
+   {
+      theGridFilename = value;
+      ifstream is (theGridFilename.chars());
+      
+      //***
+      // Create an input stream from the grid file to pass to the
+      // corresponding grid:
+      //***
+      int num_grids = theRemapEngine->getNumberOfParams();
+      for (int i=0; (i<num_grids) && successful; i++)
+      {
+         ossimDblGrid* grid = new ossimDblGrid;
+         successful = grid->load(is);
+         if (successful)
+            theGrids.push_back(grid);
+      }
+      if (!successful)
+      {
+         CLOG << "ERROR: Encountered errorloading remap grids at file: "
+              << theGridFilename << ". Remapper disabled." << endl;
+         if (traceExec())  CLOG << "returning..." << endl;
+         return false;
+      }
+      theGridIsFilled = true;
+   }
+   
+   //***
+   // Allow base class to parse list:
+   //***
+   bool rtn_stat = ossimImageSourceFilter::loadState(kwl, prefix);
+
+   //***
+   // Enable source only if KWL read was successful:
+   //***
+   if (theRemapEngine && successful && rtn_stat)
+      enableSource();
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return rtn_stat;
+}
+
+//*****************************************************************************
+//  METHOD: ossimGridRemapSource::saveState()
+//  
+//*****************************************************************************
+bool ossimGridRemapSource::saveState(ossimKeywordlist& kwl,
+                                     const char*       prefix) const
+{
+   static const char MODULE[] = "ossimGridRemapSource::saveState()";
+
+   //***
+   // No filename indicates that this remapper has not been initialized:
+   //***
+   if (!theGridFilename)
+      return false;
+   
+   //***
+   // Write the remap engine type:
+   //***
+   if (theRemapEngine)
+      kwl.add(prefix, REMAP_ENGINE_KW, theRemapEngine->getClassName());
+
+   //***
+   // Write the filename to the KWL:
+   //***
+   if (!theGridFilename.empty())
+   {
+      kwl.add(prefix, GRID_FILENAME_KW, theGridFilename);
+
+      //***
+      // Loop over each remap component to write out the grid:
+      //***
+      ofstream os (theGridFilename);
+      bool successful = true;
+      int num_components = theRemapEngine->getNumberOfParams();
+      for (int p=0; (p<num_components)&&successful; p++)
+         successful = theGrids[p]->save(os, "Remap-Grid");
+
+      if (!successful)
+      {
+         CLOG << "ERROR: Encountered saving remap grids to file: "
+              << theGridFilename << ". State not properly saved."
+              << endl;
+         return false;
+      }
+   }
+   
+   return ossimImageSourceFilter::saveState(kwl, prefix);   
+}
+
+//*****************************************************************************
+//  METHOD: ossimGridRemapSource::setGridNode()
+//  
+//  Sets a node of the member grid to the value specified.
+//  
+//*****************************************************************************
+void ossimGridRemapSource::setGridNode(const ossimDpt& view_pt,
+                                       const double*   value)
+{
+   int numGrids = theGrids.size();
+   for (int i=0; i<numGrids; i++)
+      theGrids[i]->setNearestNode(view_pt, value[i]);
+
+   theGridIsFilled = false;
+   
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimGridRemapSource::getGrid()
+//  
+//*****************************************************************************
+ossimDblGrid* ossimGridRemapSource::getGrid(unsigned int index)
+{
+   if (index >= theGrids.size())
+      return 0;
+
+   return theGrids[index];
+}
+   
+//*****************************************************************************
+//  METHOD: ossimGridRemapSource::deallocateGrids()
+//  
+//*****************************************************************************
+void ossimGridRemapSource::deallocateGrids()
+{
+   static const char MODULE[] = "ossimGridRemapSource::deallocateMemory()";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   vector<ossimDblGrid*>::iterator grid = theGrids.begin();
+   while (grid != theGrids.end())
+   {
+      delete *grid;
+      grid++;
+   }
+   theGrids.clear();
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimGridRemapSource::setRemapEngine()
+//  
+//*****************************************************************************
+void ossimGridRemapSource::setRemapEngine(ossimGridRemapEngine* engine)
+{
+   if (theRemapEngine)
+      delete theRemapEngine;
+
+   theRemapEngine = (ossimGridRemapEngine*)engine->dup();
+   theGridIsFilled = false;
+}
+
+//*****************************************************************************
+//  METHOD: ossimGridRemapSource::setGridFilename()
+//  
+//*****************************************************************************
+void ossimGridRemapSource::setGridFilename(const ossimFilename& grid_filename)
+{
+   theGridFilename = grid_filename;
+   //***
+   // NOT COMPLETE###
+   //***
+}
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapSource.h b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapSource.h
new file mode 100644
index 0000000000..e8eb8a6dc0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimGridRemapSource.h
@@ -0,0 +1,144 @@
+//*****************************************************************************
+// FILE: ossimGridRemapSource.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains declaration of class ossimGridRemapSource. This is
+//   a spacially variant remapper that utilizes a grid for interpolating the
+//   remap value given an image x, y. 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimGridRemapSource.h,v 1.8 2005/02/11 15:07:35 dburken Exp $
+
+#ifndef ossimGridRemapSource_HEADER
+#define ossimGridRemapSource_HEADER
+
+#include "imaging/tile_sources/ossimImageSourceFilter.h"
+#include <vector>
+#include "ossimGridRemapEngine.h"
+#include "base/data_types/ossimFilename.h"
+
+class ossimDblGrid;
+class ossimDrect;
+class ossimDpt;
+class ossimImageData;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimGridRemapSource
+ *
+ *****************************************************************************/
+class ossimGridRemapSource : public ossimImageSourceFilter
+{
+public:
+   /*!
+    * Constructors: 
+    */
+   ossimGridRemapSource();
+   ossimGridRemapSource(ossimImageSource* inputSource,
+                        ossimGridRemapEngine* engine);
+
+   virtual ~ossimGridRemapSource();
+
+   /*!ossimAtbPointSource
+    * Initializes the remap engine. This object implements specific algorithms
+    * for interpreting the grids owned by this remapper. It actually performs
+    * the remapping.
+    */
+   void setRemapEngine(ossimGridRemapEngine* engine);
+   
+   /*!
+    * Provides access to the remap engine:
+    */
+   ossimGridRemapEngine* getRemapEngine() { return theRemapEngine; }
+   
+   /*!
+    * Permits initializing the remap grid after construction. 
+    */
+   virtual void initialize(const ossimDrect& uv_rect,
+			   const ossimDpt&   grid_spacing);
+
+  /*!
+   * Sets a node of the member grid to the value specified. The grid is flagged
+   * as unfilled.
+   */
+  void setGridNode(const ossimDpt& view_pt,
+		   const double*    value);
+  
+   /*!
+    * Implementation of virtual method to return remapped tile.
+    */
+   virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& origin,
+                                   ossim_uint32 resLevel=0);
+
+   /*!
+    * Restore the state of the object from a keywordlist.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /*!
+    * Save the state of the object to a keywordlist.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Locks the image to prevent grid adjustment. The remapper continues to
+    * remap given the current grid (if enabled), but all target values computed
+    * are such that no change in the grids will occur in an adjsutment. If more
+    * than one overlapping image is locked, the target will may be influenced
+    * by all locked images, but the remap grids will not be updated.
+    */
+   void lock() { theRemapIsLockedFlag = true; }
+
+   /*!
+    * Unlocks the grids for adjustment.
+    */
+   void unlock() { theRemapIsLockedFlag = false; }
+   
+   /*!
+    * Returns the status of the lock flag.
+    */
+   bool isLocked() const { return theRemapIsLockedFlag; }
+
+   /*!
+    * Provides access to individual grids (pointer) given an index. Null pointer
+    * returned if index out of range.
+    */
+   ossimDblGrid* getGrid(unsigned int index);
+
+   /*!
+    * Returns grid filename (may be empty)
+    */
+   const ossimFilename& getGridFilename() const { return theGridFilename; }
+
+   /*!
+    * Sets the grid filename and initiates read.
+    */
+   void setGridFilename(const ossimFilename& grid_filename);
+   
+protected:
+   /*!
+    * Deallocates grid memory.
+    */
+   void deallocateGrids();
+   
+   vector<ossimDblGrid*> theGrids;
+   ossimFilename         theGridFilename;
+   ossimGridRemapEngine* theRemapEngine;
+   bool                  theRemapIsLockedFlag;
+   bool                  theGridIsFilled;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimHsvGridRemapEngine.cpp b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimHsvGridRemapEngine.cpp
new file mode 100644
index 0000000000..9d2995772a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimHsvGridRemapEngine.cpp
@@ -0,0 +1,276 @@
+//*****************************************************************************
+// FILE: ossimHsvGridRemapEngine.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimHsvGridRemapEngine.cpp,v 1.7 2005/09/09 19:23:58 gpotts Exp $
+
+#include "ossimHsvGridRemapEngine.h"
+
+RTTI_DEF1(ossimHsvGridRemapEngine, "ossimHsvGridRemapEngine",
+          ossimGridRemapEngine);
+
+#include <imaging/tonal_balance/ossimGridRemapSource.h>
+#include <imaging/tonal_balance/ossimAtbPointSource.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDblGrid.h>
+#include <imaging/ossimImageData.h>
+#include <base/data_types/color_space/ossimRgbVector.h>
+#include <base/data_types/color_space/ossimHsvVector.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimHsvGridRemapEngine:exec");
+static ossimTrace traceDebug ("ossimHsvGridRemapEngine:debug");
+
+//*****************************************************************************
+//  METHOD: ossimHsvGridRemapEngine::remapTile
+//  
+//*****************************************************************************
+ossimObject* ossimHsvGridRemapEngine::dup() const
+{
+   return new ossimHsvGridRemapEngine;
+}
+
+//*****************************************************************************
+//  METHOD: ossimHsvGridRemapEngine::remapTile
+//  
+//*****************************************************************************
+void ossimHsvGridRemapEngine::remapTile(const ossimDpt&       origin,
+                                        ossimGridRemapSource* remapper,
+                                        ossimRefPtr<ossimImageData>& tile)
+{
+   static const char MODULE[] = "ossimHsvGridRemapEngine::remapTile";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // Fetch tile size and NULL pixel value:
+   //***
+   int    width         = tile->getWidth();
+   int    height        = tile->getHeight();
+   int    offset        = 0;
+   
+   void* red_buf = tile->getBuf(0);
+   void* grn_buf = tile->getBuf(1);
+   void* blu_buf = tile->getBuf(2);
+
+   ossimDblGrid& gridH = *(remapper->getGrid(0));
+   ossimDblGrid& gridS = *(remapper->getGrid(1));
+   ossimDblGrid& gridV = *(remapper->getGrid(2));
+      
+   //---
+   // Remap according to pixel type:
+   //---
+   switch(tile->getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         for (double line=origin.line; line<origin.line+height; line+=1.0)
+         {
+            for (double samp=origin.samp; samp<origin.samp+width; samp+=1.0)
+            {
+               //---
+               // Fetch pixel from the input tile band buffers and convert
+               // to HSV:
+               //---
+               ossimRgbVector rgb_pixel (((ossim_uint8*)red_buf)[offset],
+                                         ((ossim_uint8*)grn_buf)[offset],
+                                         ((ossim_uint8*)blu_buf)[offset]);
+               ossimHsvVector hsv_pixel (rgb_pixel);
+               
+               //---
+               // Remap pixel HSV  with spatially variant bias value:
+               //---
+               hsv_pixel.setH(hsv_pixel.getH() + gridH(samp,line));
+               hsv_pixel.setS(hsv_pixel.getS() + gridS(samp,line));
+               hsv_pixel.setV(hsv_pixel.getV() + gridV(samp,line));
+               
+               //---
+               // Convert back to RGB and write to the tile:
+               //---
+               rgb_pixel = hsv_pixel;  // auto-clamped
+               ((ossim_uint8*)red_buf)[offset] = rgb_pixel.getR();
+               ((ossim_uint8*)grn_buf)[offset] = rgb_pixel.getG();
+               ((ossim_uint8*)blu_buf)[offset] = rgb_pixel.getB();
+               
+               offset++;
+            }
+         }
+         break;
+      }
+      
+      case OSSIM_USHORT11:
+         break;
+         
+      case OSSIM_UINT16:
+         break;
+         
+      case OSSIM_SINT16:
+         break;	
+
+      case OSSIM_FLOAT64:
+         break;	
+
+      case OSSIM_NORMALIZED_DOUBLE:
+         break;	
+
+      case OSSIM_FLOAT32:
+         break;	
+
+      case OSSIM_NORMALIZED_FLOAT:
+         break;	
+
+      case OSSIM_SCALAR_UNKNOWN:
+      default:
+         break;
+
+   }   // end switch statement
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+};
+
+//*****************************************************************************
+//  METHOD: ossimHsvGridRemapEngine::assignRemapValues
+//
+//  This engine defines the target value as an HSV vector of doubles, computed
+//  as the mean of all contributor HSV values.
+//  
+//*****************************************************************************
+void ossimHsvGridRemapEngine::assignRemapValues (
+   vector<ossimAtbPointSource*>& sources_list)
+{
+   static const char MODULE[] = "ossimHsvGridRemapEngine::assignRemapValues";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   int i; // index to individual sources
+
+   //***
+   // Declare a 2D array that will contain all of the contributing sources'
+   // HSV mean values. Also declare the accumulator target vector.
+   //***
+   int num_contributors = sources_list.size();
+   double** contributor_pixel = new double* [num_contributors];
+   for (i=0; i<num_contributors; i++)
+      contributor_pixel[i] = new double[3];
+   double target_pixel[3] = {0.0, 0.0, 0.0};
+
+   //***
+   // Now loop over each remaining contributor and sum in its contribution:
+   //***
+   vector<ossimAtbPointSource*>::iterator source;
+   i = 0;
+   for(source  = sources_list.begin();
+       source != sources_list.end();
+       source++)
+   {
+      (*source)->getSourceValue(contributor_pixel[i]);
+
+      target_pixel[0] += contributor_pixel[i][0]/(double)num_contributors;
+      target_pixel[1] += contributor_pixel[i][1]/(double)num_contributors;
+      target_pixel[2] += contributor_pixel[i][2]/(double)num_contributors;
+
+      i++;
+   }
+
+   //***
+   // The target pixel has been established. Now need to compute the actual
+   // remap quantities that will be written to the appropriate remap grids:
+   //***
+   i = 0;
+   for(source  = sources_list.begin();
+       source != sources_list.end();
+       source++)
+   {
+      computeRemapNode(*source, contributor_pixel[i], target_pixel);
+      i++;
+   }
+
+   //***
+   // Delete locally allocated memory:
+   //***
+   for (i=0; i<num_contributors; i++)
+      delete [] contributor_pixel[i];
+   delete [] contributor_pixel;
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimHsvGridRemapEngine::computeSourceValue
+//  
+//*****************************************************************************
+void ossimHsvGridRemapEngine::computeSourceValue(
+   ossimRefPtr<ossimImageData>& source, void* result)
+{
+   static const char MODULE[]="ossimHsvGridRemapEngine::computeSourceValue";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // This engine defines "value" as the HSV vector corresponding to the mean
+   // RGB pixel value of the source data:
+   //***
+   ossimRgbVector rgb_vector;
+   rgb_vector.setR((unsigned char) source->computeAverageBandValue(0));
+   rgb_vector.setG((unsigned char) source->computeAverageBandValue(1));
+   rgb_vector.setB((unsigned char) source->computeAverageBandValue(2));
+
+   //***
+   // Assign the HSV components to the result vector:
+   //***
+   ossimHsvVector hsv_vector (rgb_vector);
+   ((double*)result)[0] = (double) hsv_vector.getH();
+   ((double*)result)[1] = (double) hsv_vector.getS();
+   ((double*)result)[2] = (double) hsv_vector.getV();
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimHsvGridRemapEngine::computeRemapNode
+//
+//  This engine defines the remap value as the difference between the target
+//  HSV vector and the individual point source's value vector.
+//
+//*****************************************************************************
+void ossimHsvGridRemapEngine::computeRemapNode(ossimAtbPointSource* ps,
+                                              void* source_value,
+                                              void* target_value)
+{
+   static const char MODULE[] = "ossimHsvGridRemapEngine::computeRemapNode";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // Compute the remap grid node value specific to this HSV implementation:
+   //***
+   double node[3];
+   node[0] = ((double*)target_value)[0] - ((double*)source_value)[0];
+   node[1] = ((double*)target_value)[1] - ((double*)source_value)[1];
+   node[2] = ((double*)target_value)[2] - ((double*)source_value)[2];
+
+   //***
+   // Fetch a pointer to the remapper feeding this point source in order to
+   // pass it the node value:
+   //***
+   ossimGridRemapSource* remapper = ps->getRemapSource();
+   remapper->setGridNode(ps->getViewPoint(), node);
+                         
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimHsvGridRemapEngine.h b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimHsvGridRemapEngine.h
new file mode 100644
index 0000000000..eb9b2311d3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimHsvGridRemapEngine.h
@@ -0,0 +1,54 @@
+//*****************************************************************************
+// FILE: ossimHsvGridRemapEngine.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains declaration of class ossimHsvGridRemapEngine
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimHsvGridRemapEngine.h,v 1.5 2005/10/17 18:42:27 gpotts Exp $
+
+#ifndef ossimHsvGridRemapEngine_HEADER
+#define ossimHsvGridRemapEngine_HEADER
+
+#include <imaging/tonal_balance/ossimGridRemapEngine.h>
+
+/*!****************************************************************************
+ *
+ * CLASS: ossimHsvGridRemapEngine 
+ *
+ *****************************************************************************/
+class ossimHsvGridRemapEngine : public ossimGridRemapEngine
+{
+public:
+   ossimHsvGridRemapEngine()
+      : ossimGridRemapEngine(3, 3) {}
+   
+   virtual ossimObject* dup() const;
+   
+   virtual void remapTile(const ossimDpt& origin_point,
+                          ossimGridRemapSource* remapper,
+                          ossimRefPtr<ossimImageData>& tile);
+
+   virtual void assignRemapValues(std::vector<ossimAtbPointSource*>& sources);
+
+   virtual void computeSourceValue(ossimRefPtr<ossimImageData>& source,
+                                   void* result);
+
+protected:
+   virtual void computeRemapNode(ossimAtbPointSource*  point_source,
+                                 void*                 source_value,
+                                 void*                 target_value);
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimMonoGridRemapEngine.cpp b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimMonoGridRemapEngine.cpp
new file mode 100644
index 0000000000..0d4729cffe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimMonoGridRemapEngine.cpp
@@ -0,0 +1,368 @@
+//*****************************************************************************
+// FILE: ossimMonoGridRemapEngine.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimMonoGridRemapEngine.cpp,v 1.8 2005/09/09 19:23:58 gpotts Exp $
+
+#include <imaging/tonal_balance/ossimMonoGridRemapEngine.h>
+
+RTTI_DEF1(ossimMonoGridRemapEngine, "ossimMonoGridRemapEngine",
+          ossimGridRemapEngine);
+
+#include <imaging/tonal_balance/ossimGridRemapSource.h>
+#include <imaging/tonal_balance/ossimAtbPointSource.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDblGrid.h>
+#include <imaging/ossimImageData.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimMonoGridRemapEngine:exec");
+static ossimTrace traceDebug ("ossimMonoGridRemapEngine:debug");
+static bool TRACE_FLAG = true;
+
+//*****************************************************************************
+//  METHOD: ossimMonoGridRemapEngine::dup
+//  
+//*****************************************************************************
+ossimObject* ossimMonoGridRemapEngine::dup() const
+{
+   return new ossimMonoGridRemapEngine;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMonoGridRemapEngine::remapTile
+//  
+//*****************************************************************************
+void ossimMonoGridRemapEngine::remapTile(const ossimDpt&       origin,
+                                        ossimGridRemapSource* remapper,
+                                        ossimRefPtr<ossimImageData>& tile)
+{
+   static const char MODULE[] = "ossimMonoGridRemapEngine::remapTile";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // Fetch tile size and NULL pixel value:
+   //***
+   int    width         = tile->getWidth();
+   int    height        = tile->getHeight();
+   int    offset        = 0;
+   double null;
+
+   //***
+   // Determine null pixel values so that we can recognize a null coming in and
+   // not remap it:
+   //***
+   null = tile->getNullPix(0);
+   ossimDblGrid& grid = *(remapper->getGrid(0));
+   
+   //***
+   // Remap according to pixel type:
+   //***
+   switch(tile->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      ossim_uint8* tile_buf  = (ossim_uint8*)tile->getBuf(0);
+      short  pixel;
+      
+      for (double line=origin.line; line<origin.line+height; line+=1.0)
+      {
+         for (double samp=origin.samp; samp<origin.samp+width; samp+=1.0)
+         {
+            //***
+            // Scan for null pixel before adding remap delta:
+            //***
+            if (tile_buf[offset] != (ossim_uint8) null)
+            {
+               //***
+               // Remap MONO pixel with spatially variant bias value:
+               //***
+               pixel = tile_buf[offset] + (short) grid(samp,line);
+
+               //***
+               // Clamp:
+               //***
+               if      (pixel<0)   tile_buf[offset] = 0;
+               else if (pixel>255) tile_buf[offset] = 255;
+               else                tile_buf[offset] = pixel;
+               
+               //***
+               // Avoid NULLS:
+               //***
+               if (tile_buf[offset] == (ossim_uint8) null) tile_buf[offset]++;
+            }
+            
+            offset++;
+         }
+      }
+      break;
+   }
+   
+   case OSSIM_USHORT11:
+   {
+      ossim_uint16* tile_buf  = (ossim_uint16*)tile->getBuf(0);
+      int  pixel;
+      
+      for (double line=origin.line; line<origin.line+height; line+=1.0)
+      {
+         for (double samp=origin.samp; samp<origin.samp+width; samp+=1.0)
+         {
+            //***
+            // Scan for null pixel before adding remap delta:
+            //***
+            if (tile_buf[offset] != (ossim_uint16) null)
+            {
+               //***
+               // Remap MONO pixel with spatially variant bias value:
+               //***
+               pixel = tile_buf[offset] + (int) grid(samp,line);
+
+               //***
+               // Clamp:
+               //***
+               if      (pixel<0)    tile_buf[offset] = 0;
+               else if (pixel>2047) tile_buf[offset] = 2047;
+               else                 tile_buf[offset] = pixel;
+               
+               //***
+               // Avoid NULLS:
+               //***
+               if (tile_buf[offset] == (ossim_uint16) null) tile_buf[offset]++;
+            }
+            
+            offset++;
+         }
+      }
+      break;
+   }
+   
+   case OSSIM_USHORT16:
+   {
+      ossim_uint16* tile_buf  = (ossim_uint16*)tile->getBuf(0);
+      int  pixel;
+      
+      for (double line=origin.line; line<origin.line+height; line+=1.0)
+      {
+         for (double samp=origin.samp; samp<origin.samp+width; samp+=1.0)
+         {
+            //***
+            // Scan for null pixel before adding remap delta:
+            //***
+            if (tile_buf[offset] != (ossim_uint16) null)
+            {
+               //***
+               // Remap MONO pixel with spatially variant bias value:
+               //***
+               pixel = tile_buf[offset] + (int) grid(samp,line);
+
+               //***
+               // Clamp:
+               //***
+               if      (pixel<0)     tile_buf[offset] = 0;
+               else if (pixel>65535) tile_buf[offset] = 65535;
+               else                  tile_buf[offset] = pixel;
+               
+               //***
+               // Avoid NULLS:
+               //***
+               if (tile_buf[offset] == (ossim_uint16) null) tile_buf[offset]++;
+            }
+            
+            offset++;
+         }
+      }
+      break;
+   }
+   
+   case OSSIM_SSHORT16:
+   {
+      short* tile_buf  = (short*)tile->getBuf(0);
+      int  pixel;
+      
+      for (double line=origin.line; line<origin.line+height; line+=1.0)
+      {
+         for (double samp=origin.samp; samp<origin.samp+width; samp+=1.0)
+         {
+            //***
+            // Scan for null pixel before adding remap delta:
+            //***
+            if (tile_buf[offset] != (short) null)
+            {
+               //***
+               // Remap MONO pixel with spatially variant bias value:
+               //***
+               pixel = tile_buf[offset] + (short) grid(samp,line);
+
+               //***
+               // Clamp:
+               //***
+               if      (pixel<-32766) tile_buf[offset] = -32766;
+               else if (pixel> 32767) tile_buf[offset] = 32767;
+               else                   tile_buf[offset] = pixel;
+               
+               //***
+               // Avoid NULLS:
+               //***
+               if (tile_buf[offset] == (short) null) tile_buf[offset]++;
+            }
+            
+            offset++;
+         }
+      }
+      break;
+   }
+   default:
+   {
+	   ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimMonoGridRemapEngine::remapTile: Scalar type not handled" << std::endl;
+	   break;
+   }
+	   
+   }   // end switch statement
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+};
+
+//*****************************************************************************
+//  METHOD: ossimMonoGridRemapEngine::assignRemapValues
+//
+//  This engine defines the target value as an MONO vector of doubles, computed
+//  as the mean of all contributor MONO values.
+//  
+//*****************************************************************************
+void ossimMonoGridRemapEngine::assignRemapValues (
+   vector<ossimAtbPointSource*>& sources_list)
+{
+   static const char MODULE[] = "ossimMonoGridRemapEngine::assignRemapValues";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   int i; // index to individual sources
+
+   //***
+   // Declare a 2D array that will contain all of the contributing sources'
+   // MONO mean values. Also declare the accumulator target vector.
+   //***
+   int num_contributors = sources_list.size();
+   double** contributor_pixel = new double* [num_contributors];
+   for (i=0; i<num_contributors; i++)
+      contributor_pixel[i] = new double[1];
+   double target_pixel = 0.0;
+
+   //***
+   // Now loop over each remaining contributor and sum in its contribution:
+   //***
+   vector<ossimAtbPointSource*>::iterator source;
+   i = 0;
+   for(source=sources_list.begin();
+       source!=sources_list.end();
+       source++)
+   {
+      (*source)->getSourceValue(contributor_pixel[i]);
+      target_pixel += contributor_pixel[i][0]/(double)num_contributors;
+      ++i;
+   }
+
+   //***
+   // The target pixel has been established. Now need to compute the actual
+   // remap quantities that will be written to the appropriate remap grids:
+   //***
+   i = 0;
+   for(source=sources_list.begin();
+       source!=sources_list.end();
+       source++)
+   {
+      computeRemapNode(*source, contributor_pixel[i], &target_pixel);
+      ++i;
+   }
+
+   // ***
+   // Delete locally allocated memory:
+   // ***
+   for (i=0; i<num_contributors; ++i)
+   {
+      delete [] contributor_pixel[i];
+   }
+   delete [] contributor_pixel;
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMonoGridRemapEngine::computeSourceValue
+//  
+//*****************************************************************************
+void ossimMonoGridRemapEngine::computeSourceValue(
+   ossimRefPtr<ossimImageData>& source, void* result)
+{
+   static const char MODULE[]="ossimMonoGridRemapEngine::computeSourceValue";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // This engine defines "value" as the MONO vector corresponding to the mean
+   // MONO pixel value of the source data:
+   //***
+   ((double*)result)[0] = source->computeAverageBandValue(0);
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMonoGridRemapEngine::computeRemapNode
+//
+//  This engine defines the remap value as the difference between the target
+//  MONO vector and the individual point source's value vector.
+//
+//*****************************************************************************
+void ossimMonoGridRemapEngine::computeRemapNode(ossimAtbPointSource* ps,
+                                              void* source_value,
+                                              void* target_value)
+{
+   static const char MODULE[] = "ossimMonoGridRemapEngine::computeRemapNode";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // Compute the remap grid node value specific to this MONO implementation:
+   //***
+   double node;
+   node = ((double*)target_value)[0] - ((double*)source_value)[0];
+
+   //***
+   // Fetch a pointer to the remapper feeding this point source in order to
+   // pass it the node value:
+   //***
+   ossimGridRemapSource* remapper = ps->getRemapSource();
+   remapper->setGridNode(ps->getViewPoint(), &node);
+                         
+   if (traceDebug() || TRACE_FLAG)
+   {
+      CLOG << "DEBUG -- "
+           << "\n\t ps->getViewPoint() = "<<ps->getViewPoint()
+           << "\n\t source_value = "<<((double*)source_value)[0]
+           << "\n\t target_value = "<<((double*)target_value)[0]
+           << "\n\t node = "<<node
+           << "\n\t remapper at "<<remapper<<endl;
+   }
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimMonoGridRemapEngine.h b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimMonoGridRemapEngine.h
new file mode 100644
index 0000000000..273bfe856f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimMonoGridRemapEngine.h
@@ -0,0 +1,54 @@
+//*****************************************************************************
+// FILE: ossimMonoGridRemapEngine.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains declaration of class ossimMonoGridRemapEngine
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimMonoGridRemapEngine.h,v 1.5 2005/10/17 18:42:27 gpotts Exp $
+
+#ifndef ossimMonoGridRemapEngine_HEADER
+#define ossimMonoGridRemapEngine_HEADER
+
+#include <imaging/tonal_balance/ossimGridRemapEngine.h>
+
+/*!****************************************************************************
+ *
+ * CLASS: ossimMonoGridRemapEngine 
+ *
+ *****************************************************************************/
+class ossimMonoGridRemapEngine : public ossimGridRemapEngine
+{
+public:
+   ossimMonoGridRemapEngine()
+      : ossimGridRemapEngine(1, 1) {}
+   
+   virtual ossimObject* dup() const;
+   
+   virtual void remapTile(const ossimDpt& origin_point,
+                          ossimGridRemapSource* remapper,
+                          ossimRefPtr<ossimImageData>& tile);
+
+   virtual void assignRemapValues(std::vector<ossimAtbPointSource*>& sources);
+
+   virtual void computeSourceValue(ossimRefPtr<ossimImageData>& source,
+                                   void* result);
+
+protected:
+   virtual void computeRemapNode(ossimAtbPointSource*  point_source,
+                                 void*                 source_value,
+                                 void*                 target_value);
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimRgbGridRemapEngine.cpp b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimRgbGridRemapEngine.cpp
new file mode 100644
index 0000000000..6b757da4b2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimRgbGridRemapEngine.cpp
@@ -0,0 +1,271 @@
+//*****************************************************************************
+// FILE: ossimRgbGridRemapEngine.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class 
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimRgbGridRemapEngine.cpp,v 1.6 2005/09/09 19:23:58 gpotts Exp $
+
+#include <imaging/tonal_balance/ossimRgbGridRemapEngine.h>
+
+RTTI_DEF1(ossimRgbGridRemapEngine, "ossimRgbGridRemapEngine",
+          ossimGridRemapEngine);
+
+#include <imaging/tonal_balance/ossimGridRemapSource.h>
+#include <imaging/tonal_balance/ossimAtbPointSource.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDblGrid.h>
+#include <imaging/ossimImageData.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimRgbGridRemapEngine:exec");
+static ossimTrace traceDebug ("ossimRgbGridRemapEngine:debug");
+
+//*****************************************************************************
+//  METHOD: ossimRgbGridRemapEngine::dup
+//  
+//*****************************************************************************
+ossimObject* ossimRgbGridRemapEngine::dup() const
+{
+   return new ossimRgbGridRemapEngine;
+}
+
+//*****************************************************************************
+//  METHOD: ossimRgbGridRemapEngine::remapTile
+//  
+//*****************************************************************************
+void ossimRgbGridRemapEngine::remapTile(const ossimDpt&       origin,
+                                        ossimGridRemapSource* remapper,
+                                        ossimRefPtr<ossimImageData>& tile)
+{
+   static const char MODULE[] = "ossimRgbGridRemapEngine::remapTile";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // Fetch tile size and NULL pixel value:
+   //***
+   int    width         = tile->getWidth();
+   int    height        = tile->getHeight();
+   int    offset        = 0;
+   double null[3];
+
+   //***
+   // Determine null pixel values so that we can recognize a null coming in and
+   // not remap it:
+   //***
+   null[0] = tile->getNullPix(0);
+   null[1] = tile->getNullPix(1);
+   null[2] = tile->getNullPix(2);
+   
+   ossimDblGrid& gridR = *(remapper->getGrid(0));
+   ossimDblGrid& gridG = *(remapper->getGrid(1));
+   ossimDblGrid& gridB = *(remapper->getGrid(2));
+      
+   //***
+   // Remap according to pixel type:
+   //***
+   switch(tile->getScalarType())
+   {
+   case OSSIM_UCHAR:
+   {
+      ossim_uint8* red_buf  = (ossim_uint8*)tile->getBuf(0);
+      ossim_uint8* grn_buf  = (ossim_uint8*)tile->getBuf(1);
+      ossim_uint8* blu_buf  = (ossim_uint8*)tile->getBuf(2);
+      short  pixel_buffer[3];
+      
+      for (double line=origin.line; line<origin.line+height; line+=1.0)
+      {
+         for (double samp=origin.samp; samp<origin.samp+width; samp+=1.0)
+         {
+            //***
+            // Scan for null pixel before adding remap delta:
+            //***
+            if ((red_buf[offset] != (ossim_uint8) null[0]) &&
+                (grn_buf[offset] != (ossim_uint8) null[1]) &&
+                (blu_buf[offset] != (ossim_uint8) null[2]))
+            {
+               //***
+               // Remap RGB pixel with spatially variant bias value:
+               //***
+               pixel_buffer[0] = red_buf[offset] + (short) gridR(samp,line);
+               pixel_buffer[1] = grn_buf[offset] + (short) gridG(samp,line);
+               pixel_buffer[2] = blu_buf[offset] + (short) gridB(samp,line);
+
+               //***
+               // Clamp:
+               //***
+               if      (pixel_buffer[0]<0)   red_buf[offset] = 0;
+               else if (pixel_buffer[0]>255) red_buf[offset] = 255;
+               else                          red_buf[offset] = pixel_buffer[0];
+               
+
+               if      (pixel_buffer[1]<0)   grn_buf[offset] = 0;
+               else if (pixel_buffer[1]>255) grn_buf[offset] = 255;
+               else                          grn_buf[offset] = pixel_buffer[1];
+               
+
+               if      (pixel_buffer[2]<0)   blu_buf[offset] = 0;
+               else if (pixel_buffer[2]>255) blu_buf[offset] = 255;
+               else                          blu_buf[offset] = pixel_buffer[2];
+               
+               //***
+               // Avoid NULLS:
+               //***
+               if (red_buf[offset] == (ossim_uint8) null[0]) red_buf[offset]++;
+               if (grn_buf[offset] == (ossim_uint8) null[1]) grn_buf[offset]++;
+               if (blu_buf[offset] == (ossim_uint8) null[2]) blu_buf[offset]++;
+            }
+            
+            offset++;
+         }
+      }
+      break;
+   }
+   
+   default:
+   {
+	   ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimRgbGridRemapEngine::remapTile: Scalar type not handled" << std::endl;
+	   break;
+   }
+
+   }   // end switch statement
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+};
+
+//*****************************************************************************
+//  METHOD: ossimRgbGridRemapEngine::assignRemapValues
+//
+//  This engine defines the target value as an RGB vector of doubles, computed
+//  as the mean of all contributor RGB values.
+//  
+//*****************************************************************************
+void ossimRgbGridRemapEngine::assignRemapValues (
+   vector<ossimAtbPointSource*>& sources_list)
+{
+   static const char MODULE[] = "ossimRgbGridRemapEngine::assignRemapValues";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   int i; // index to individual sources
+
+   //***
+   // Declare a 2D array that will contain all of the contributing sources'
+   // RGB mean values. Also declare the accumulator target vector.
+   //***
+   int num_contributors =  sources_list.size();
+   double** contributor_pixel = new double* [num_contributors];
+   for (i=0; i<num_contributors; i++)
+      contributor_pixel[i] = new double[3];
+   double target_pixel[3] = {0.0, 0.0, 0.0};
+
+   //***
+   // Now loop over each remaining contributor and sum in its contribution:
+   //***
+   vector<ossimAtbPointSource*>::iterator source;
+   i = 0;
+   for(source=sources_list.begin();
+       source!=sources_list.end();
+       source++)
+   {
+      (*source)->getSourceValue(contributor_pixel[i]);
+
+      target_pixel[0] += contributor_pixel[i][0]/(double)num_contributors;
+      target_pixel[1] += contributor_pixel[i][1]/(double)num_contributors;
+      target_pixel[2] += contributor_pixel[i][2]/(double)num_contributors;
+
+      i++;
+   }
+
+   //***
+   // The target pixel has been established. Now need to compute the actual
+   // remap quantities that will be written to the appropriate remap grids:
+   //***
+   i = 0;
+   for(source=sources_list.begin();
+       source!=sources_list.end();
+       source++)
+   {
+      computeRemapNode(*source, contributor_pixel[i], target_pixel);
+      i++;
+   }
+
+   //***
+   // Delete locally allocated memory:
+   //***
+   for (i=0; i<num_contributors; i++)
+      delete [] contributor_pixel[i];
+   delete [] contributor_pixel;
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimRgbGridRemapEngine::computeSourceValue
+//  
+//*****************************************************************************
+void ossimRgbGridRemapEngine::computeSourceValue(
+   ossimRefPtr<ossimImageData>& source, void* result)
+{
+   static const char MODULE[]="ossimRgbGridRemapEngine::computeSourceValue";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // This engine defines "value" as the RGB vector corresponding to the mean
+   // RGB pixel value of the source data:
+   //***
+   ((double*)result)[0] = source->computeAverageBandValue(0);
+   ((double*)result)[1] = source->computeAverageBandValue(1);
+   ((double*)result)[2] = source->computeAverageBandValue(2);
+   
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimRgbGridRemapEngine::computeRemapNode
+//
+//  This engine defines the remap value as the difference between the target
+//  RGB vector and the individual point source's value vector.
+//
+//*****************************************************************************
+void ossimRgbGridRemapEngine::computeRemapNode(ossimAtbPointSource* ps,
+                                              void* source_value,
+                                              void* target_value)
+{
+   static const char MODULE[] = "ossimRgbGridRemapEngine::computeRemapNode";
+   if (traceExec())  CLOG << "entering..." << endl;
+
+   //***
+   // Compute the remap grid node value specific to this RGB implementation:
+   //***
+   double node[3];
+   node[0] = ((double*)target_value)[0] - ((double*)source_value)[0];
+   node[1] = ((double*)target_value)[1] - ((double*)source_value)[1];
+   node[2] = ((double*)target_value)[2] - ((double*)source_value)[2];
+
+   //***
+   // Fetch a pointer to the remapper feeding this point source in order to
+   // pass it the node value:
+   //***
+   ossimGridRemapSource* remapper = ps->getRemapSource();
+   remapper->setGridNode(ps->getViewPoint(), node);
+
+   if (traceExec())  CLOG << "returning..." << endl;
+   return;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimRgbGridRemapEngine.h b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimRgbGridRemapEngine.h
new file mode 100644
index 0000000000..29c2ad81e9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/imaging/tonal_balance/ossimRgbGridRemapEngine.h
@@ -0,0 +1,54 @@
+//*****************************************************************************
+// FILE: ossimRgbGridRemapEngine.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains declaration of class ossimRgbGridRemapEngine
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimRgbGridRemapEngine.h,v 1.5 2005/10/17 18:42:27 gpotts Exp $
+
+#ifndef ossimRgbGridRemapEngine_HEADER
+#define ossimRgbGridRemapEngine_HEADER
+
+#include <imaging/tonal_balance/ossimGridRemapEngine.h>
+
+/*!****************************************************************************
+ *
+ * CLASS: ossimRgbGridRemapEngine 
+ *
+ *****************************************************************************/
+class ossimRgbGridRemapEngine : public ossimGridRemapEngine
+{
+public:
+   ossimRgbGridRemapEngine()
+      : ossimGridRemapEngine(3, 3) {}
+   
+   virtual ossimObject* dup() const;
+   
+   virtual void remapTile(const ossimDpt& origin_point,
+                          ossimGridRemapSource* remapper,
+                          ossimRefPtr<ossimImageData>& tile);
+
+   virtual void assignRemapValues(std::vector<ossimAtbPointSource*>& sources);
+
+   virtual void computeSourceValue(ossimRefPtr<ossimImageData>& source,
+                                   void* result);
+
+protected:
+   virtual void computeRemapNode(ossimAtbPointSource*  point_source,
+                                 void*                 source_value,
+                                 void*                 target_value);
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/init/.cvsignore b/Utilities/OSSIM/ossim_core/init/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/init/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/init/CMakeLists.txt b/Utilities/OSSIM/ossim_core/init/CMakeLists.txt
new file mode 100644
index 0000000000..14ea75c04c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/init/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_init_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_init_HDRS "*.h")
+ADD_LIBRARY(ossim_init ${ossim_init_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_init)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_init_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/init/ossimInit.cpp b/Utilities/OSSIM/ossim_core/init/ossimInit.cpp
new file mode 100644
index 0000000000..a97414ea24
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/init/ossimInit.cpp
@@ -0,0 +1,551 @@
+//*****************************************************************************
+// FILE: ossimInit.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimInit. This object handles all
+//   aspects of initialization for OSSIM applications. These tasks include:
+//
+//      1. Parsing the command line.
+//      2. Instantiating all class factories.
+//      3. Initializing the "trace" code execution tracing functionality.
+//      4. Scanning the preferences file for relevant values.
+//
+// SOFTWARE HISTORY:
+//   24Apr2001  Oscar Kramer
+//              Initial coding.
+//*****************************************************************************
+// $Id: ossimInit.cpp,v 1.66 2006/01/10 21:07:15 gpotts Exp $
+
+#include <iostream>
+using namespace std;
+#include <init/ossimInit.h>
+#include <base/common/ossimPreferences.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimArgumentParser.h>
+#include <base/common/ossimApplicationUsage.h>
+#include <base/common/ossimTraceManager.h>
+#include <algorithm>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+
+// include the image file formats
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <imaging/factory/ossimImageSourceFactoryRegistry.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <elevation/ossimElevManager.h>
+#include <base/data_types/geoid/ossimGeoidManager.h>
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+#include <imaging/factory/ossimImageWriterFactoryRegistry.h>
+#include <imaging/factory/ossimImageMetaDataWriterRegistry.h>
+#include <projections/factory/ossimProjectionViewControllerFactory.h>
+#include <base/factory/ossimBaseObjectFactory.h>
+#include <base/factory/ossimCustomEditorWindowRegistry.h>
+#include <base/data_types/ossimDirectory.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <plugin/ossimSharedPluginRegistry.h>
+#include <plugin/ossimDynamicLibrary.h>
+#include <fonts/factory/ossimFontFactoryRegistry.h>
+#include <base/context/ossimNotifyContext.h>
+
+
+static ossimTrace traceExec = ossimTrace("ossimInit:exec");
+static ossimTrace traceDebug = ossimTrace("ossimInit:debug");
+
+ossimInit* ossimInit::theInstance = NULL;
+
+ossimInit::~ossimInit()
+{
+   theInstance = NULL;
+}
+
+ossimInit::ossimInit()
+    :
+       theAppName(),
+       thePreferences(ossimPreferences::instance()),
+       theElevEnabledFlag(true),
+       thePluginLoaderEnabledFlag(true)
+{
+}
+
+ossimInit* ossimInit::instance()
+{
+   if (!theInstance)
+   {
+      theInstance = new ossimInit();
+   }
+   return theInstance;
+}
+
+void ossimInit::addOptions(ossimArgumentParser& parser)
+{
+   parser.getApplicationUsage()->addCommandLineOption("-P", "specify a preference file to load");
+   parser.getApplicationUsage()->addCommandLineOption("-K", "specify individual keywords to add to the preferences keyword list: name=value");
+   parser.getApplicationUsage()->addCommandLineOption("-T", "specify the classes to trace, ex: ossimInit|ossimImage.* \nwill trace ossimInit and all ossimImage classes");
+   parser.getApplicationUsage()->addCommandLineOption("--disable-elev", "Will disable the elevation");
+   parser.getApplicationUsage()->addCommandLineOption("--disable-plugin", "Will disable the plugin loader");
+   
+   parser.getApplicationUsage()->addCommandLineOption("--ossim-logfile", "takes a logfile as an argument.  All output messages are redirected to the specified log file.  By default there is no log file and all messages are enabled.");
+   parser.getApplicationUsage()->addCommandLineOption("--disable-notify", "Takes an argument. Arguments are ALL, WARN, NOTICE, INFO, FATAL, DEBUG.  If you want multiple disables then just do multiple --disable-notify on the command line.  All argument are case insensitive.  Default is all are enabled.");
+   
+}
+
+/*!****************************************************************************
+ * METHOD: ossimInit::initialize()
+ *  
+ *  Method called from the OSSIM application main.
+ *  
+ *****************************************************************************/
+void ossimInit::initialize(int& argc, char** argv)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::initialize(argc, argv): entering..." << std::endl;
+
+   theInstance->theAppName  = argv[0];
+
+   theInstance->thePreferences = ossimPreferences::instance();
+
+   // Parse the command line:
+   theInstance->parseOptions(argc, argv);
+
+   theInstance->initializeDefaultFactories();
+   theInstance->initializeElevation();
+   if(thePluginLoaderEnabledFlag)
+   {
+      theInstance->initializePlugins();
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::initialize(argc, argv): leaving..." << std::endl;
+   return;
+}
+
+void ossimInit::initialize(ossimArgumentParser& parser)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::initialize(parser): entering..." << endl;
+   }
+
+   theInstance->theAppName  = parser.getApplicationUsage()->getApplicationName();
+   theInstance->thePreferences = ossimPreferences::instance();
+      
+    //Parse the command line:
+   theInstance->parseOptions(parser);
+
+   theInstance->initializeDefaultFactories();
+   theInstance->initializeElevation();
+   if(thePluginLoaderEnabledFlag)
+   {
+      theInstance->initializePlugins();
+   }
+
+   if(!theElevEnabledFlag)
+   {
+      ossimElevManager::instance()->disableSource();
+      ossimElevManager::instance()->disableAutoLoad();
+   }
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::initialize(parser): leaving..." << endl;
+   }
+   return;
+}
+
+void ossimInit::initialize()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::initialize(): entering..." << std::endl;
+
+   theInstance->theAppName  = "";
+   theInstance->thePreferences = ossimPreferences::instance();
+   theInstance->initializeDefaultFactories();
+   theInstance->initializeElevation();
+
+   //---
+   // To do:
+   // We need a mechanism to register factories to the "front" or the
+   // "back" of factory list so that plugins can override things.  For
+   // now we will initialize the plugins last...
+   //---
+   if(thePluginLoaderEnabledFlag)
+   {
+      theInstance->initializePlugins();
+   }
+   
+   return;
+}
+
+void ossimInit::finalize()
+{
+   
+}
+/*!****************************************************************************
+ *  Prints to stdout the list of command line options that this object parses.
+ *****************************************************************************/
+void ossimInit::usage()
+{
+   ossimNotify(ossimNotifyLevel_INFO)
+      << "INFORMATION ossimInit::usage():\n"
+      << "Additional command-line options available are as follows: "
+      << "\n"
+      << "\n  -P<pref_filename> -- Allows the user to override the loading "
+      << "\n    of the default preferences with their own pref file."
+      << "\n"
+      << "\n  -K<keyword>[=<value>] -- Allows the user to specify additional"
+      << "\n    keyword/value pairs that are added onto the preferences "
+      << "\n    previously loaded. Keywords specified here override those in"
+      << "\n    the preferences file."
+      << "\n"
+      << "\n  -T<trace_tag> -- Lets user turn on specific trace flags."
+      << "\n"
+      << "\n  -S<session_filename> -- Allows user to specify a session file"
+      << "\n    to load."
+      << std::endl;
+   return;
+}
+
+void ossimInit::setPluginLoaderEnabledFlag(bool flag)
+{
+   thePluginLoaderEnabledFlag = flag;  
+}
+
+
+void ossimInit::parseOptions(ossimArgumentParser& parser)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::parseOptions: entering..." << endl;
+   
+   std::string tempString;
+   ossimArgumentParser::ossimParameter stringParameter(tempString);
+   while(parser.read("-P", stringParameter));
+
+   if(tempString != "")
+   {
+      thePreferences->loadPreferences(ossimFilename(tempString));
+   }
+   while(parser.read("-K", stringParameter))
+   {
+      ossimString option = tempString;
+      if (option.contains("=") )
+      {
+         ossimString delimiter = "=";
+         ossimString key (option.before(delimiter));
+         ossimString value = option.after(delimiter);
+         thePreferences->addPreference(key.c_str(), value.c_str());
+      }
+      else
+      {
+         ossimString key (option);
+         thePreferences->addPreference(key, "");
+      }
+   }
+
+   while(parser.read("-T", stringParameter))
+   {
+      ossimTraceManager::instance()->setTracePattern(ossimString(tempString));
+   }
+
+   while(parser.read("--ossim-logfile", stringParameter))
+   {
+      ossimSetLogFilename(ossimFilename(tempString));
+   }
+   while(parser.read("--disable-notify", stringParameter))
+   {
+      ossimString tempDownCase = tempString;
+      tempDownCase = tempDownCase.downcase();
+
+      if(tempDownCase == "warn")
+      {
+         ossimDisableNotify(ossimNotifyFlags_WARN);
+      }
+      else if(tempDownCase == "fatal")
+      {
+         ossimDisableNotify(ossimNotifyFlags_FATAL);
+      }
+      else if(tempDownCase == "debug")
+      {
+         ossimDisableNotify(ossimNotifyFlags_DEBUG);
+      }
+      else if(tempDownCase == "info")
+      {
+         ossimDisableNotify(ossimNotifyFlags_INFO);
+      }
+      else if(tempDownCase == "notice")
+      {
+         ossimDisableNotify(ossimNotifyFlags_NOTICE);
+      }
+      else if(tempDownCase == "all")
+      {
+         ossimDisableNotify(ossimNotifyFlags_ALL);
+      }
+   }
+   if(parser.read("--disable-elev"))
+   {
+      theElevEnabledFlag = false;
+   }
+   if(parser.read("--disable-plugin"))
+   {
+      thePluginLoaderEnabledFlag = false;
+   }
+}
+
+
+/*!****************************************************************************
+ * METHOD: ossimInit::parseOptions()
+ *  
+ *  Parses the command line options.
+ *  
+ *****************************************************************************/
+void ossimInit::parseOptions(int& argc, char** argv)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::parseOptions(argc, argv): entering..." << std::endl;
+
+   int currArgc = 1;
+   while (currArgc < argc)
+   {
+      if(argv[currArgc][0] == '-')
+      {
+         switch (argv[currArgc][1])
+         {
+         case 'P':
+         {
+            /*!
+             * OPTION_SYNTAX: -P<pref_filename>
+             * This option permits replacing the default preferences file
+             * with a different, user-specified keyword preference file:
+             */
+            ossimFilename pref_file = (&argv[currArgc][2]);
+            thePreferences->loadPreferences(pref_file);
+            removeOption (argc, argv, currArgc--);
+            break;
+         }
+
+         case 'K':
+         {
+            /*!
+             * OPTION SYNTAX: -K<keyword>[=<value>]
+             * This option used to add a keyword to the already loaded
+             * preferences KWL:
+             */
+            ossimString option = (&argv[currArgc][2]);
+            if (option.contains("=") )
+            {
+               ossimString delimiter = "=";
+               ossimString key (option.before(delimiter));
+               ossimString value = option.after(delimiter);
+               thePreferences->addPreference(key.c_str(), value.c_str());
+            }
+            else
+            {
+               ossimString key (option);
+               thePreferences->addPreference(key, "");
+               
+            }
+            removeOption (argc, argv, currArgc--);
+            break;
+         }
+   
+         case 'T':
+         {
+            /*!
+             * OPTION SYNTAX: -T<trace_tag>
+             * Turns on the trace flag for all trace objects matching
+             * the trace_tag:
+             */
+            ossimString tag = (&argv[currArgc][2]);
+            if (tag.empty())
+            {
+               // Someone did -T "some_tag" instead of -T"some_tag"
+               removeOption (argc, argv, currArgc);
+               tag = argv[currArgc];
+            }
+            ossimTraceManager::instance()->setTracePattern(tag);
+            removeOption (argc, argv, currArgc--);
+            break;
+         }
+
+         case 'S':
+         {
+            /*!
+             * OPTION SYNTAX: -S<sesion_filename>
+             * This option is specified for autoloading session KWL files:
+             */
+            ossimFilename session_file = (&argv[currArgc][2]);
+            thePreferences->loadPreferences(session_file);
+            removeOption (argc, argv, currArgc--);
+            break;
+         }
+
+         default:
+            // option unrecognized, skip
+            break;
+          }
+      }
+
+      currArgc++;
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::parseOptions(argc, argv): leaving..." << std::endl;
+}
+
+
+/*!****************************************************************************
+ * METHOD: ossimInit::removeOption()
+ *  
+ * Removes all characters associated with the indicated option from the
+ * command line string.
+ *  
+ *****************************************************************************/
+void ossimInit::removeOption(int& argc,
+                             char** argv,
+                             int argToRemove)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::removeOption(argc, argv, argToRemove): entering..."
+      << std::endl;
+   
+   // Shift the args up by one position, overwriting the arg being removed:
+   for (int i=argToRemove+1; i<argc;  i++)
+   {
+      argv[i - 1] = argv[i];
+   }
+   
+   argc--;
+   argv[argc] = 0;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::removeOption(argc, argv, argToRemove): leaving..."
+      << std::endl;
+   return;
+}
+
+void ossimInit::initializeDefaultFactories()
+{
+   ossimObjectFactoryRegistry::instance()->registerFactory(ossimImageSourceFactoryRegistry::instance());
+
+   //---
+   // Because of how the imagehandlers work off a magic number make sure
+   // we place the writer first if we don't then the imagehandler will
+   // be false and will then try to open the filename and go through a
+   // magic number and if the file already
+   // existed it will open and create a handler instead of a writer.
+   //---
+   ossimImageWriterFactoryRegistry::instance();
+   ossimImageMetaDataWriterRegistry::instance();
+   ossimImageHandlerRegistry::instance();
+   ossimObjectFactoryRegistry::instance()->addFactory(ossimBaseObjectFactory::instance());
+   
+   // initialize. projection factory.
+   ossimProjectionFactoryRegistry::instance();
+
+   // add the view controllers
+   ossimObjectFactoryRegistry::instance()->registerFactory(ossimProjectionViewControllerFactory::instance());
+
+   ossimFontFactoryRegistry::instance();
+}
+
+void ossimInit::initializePlugins()
+{
+   ossimString regExpressionDir =  ossimString("^(") + "plugin.dir[0-9]+)";
+   ossimString regExpressionFile =  ossimString("^(") + "plugin.file[0-9]+)";
+
+   const ossimKeywordlist& kwl = thePreferences->preferencesKWL();
+
+   vector<ossimString> keys = kwl.getSubstringKeyList( regExpressionDir );
+
+   ossim_uint32 numberOfDirs = keys.size();
+   ossim_uint32 offset = ossimString("plugin.dir").size();
+   int idx = 0;
+   
+   std::vector<int> numberList(numberOfDirs);
+   if(numberList.size()>0)
+   {
+      for(idx = 0; idx < (int)numberList.size();++idx)
+      {
+         ossimString numberStr(keys[idx].begin() + offset,
+                               keys[idx].end());
+         numberList[idx] = numberStr.toInt();
+      }
+      
+      std::sort(numberList.begin(), numberList.end());
+      for(idx=0;idx < (int)numberList.size();++idx)
+      {
+         ossimString newPrefix = "plugin.dir";
+         newPrefix += ossimString::toString(numberList[idx]);
+         const char* directory = kwl.find(newPrefix.c_str());
+         
+         if(directory)
+         {
+            ossimDirectory d;
+            
+            if(d.open(ossimFilename(directory)))
+            {
+               ossimFilename file;
+               
+               if(d.getFirst(file, ossimDirectory::OSSIM_DIR_FILES))
+               {
+                  do
+                  {
+                     ossimSharedPluginRegistry::instance()->registerPlugin(file);
+                  }while(d.getNext(file));
+               }
+            }
+         }
+      }
+   }
+   keys = kwl.getSubstringKeyList( regExpressionFile );
+   
+   ossim_uint32 numberOfFiles = keys.size();
+   offset = ossimString("plugin.file").size();
+   numberList.resize(numberOfFiles);
+   if(numberList.size()>0)
+   {
+      for(idx = 0; idx < (int)numberList.size();++idx)
+      {
+         ossimString numberStr(keys[idx].begin() + offset,
+                               keys[idx].end());
+         numberList[idx] = numberStr.toInt();
+      }
+      
+      std::sort(numberList.begin(), numberList.end());   
+      for(idx=0;idx < (int)numberList.size();++idx)
+      {
+         ossimString newPrefix="plugin.file";
+         newPrefix += ossimString::toString(numberList[idx]);
+         const char* file = kwl.find(newPrefix.c_str());
+         
+         if(file&&ossimFilename(file).exists())
+         {
+            ossimSharedPluginRegistry::instance()->registerPlugin(file);
+         }
+      }
+   }
+}
+
+void ossimInit::initializeElevation()
+{
+   if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::initializeElevation(): Entered..." << std::endl;
+   
+   const ossimKeywordlist& KWL = thePreferences->preferencesKWL();
+
+   ossimGeoidManager::instance()->loadState(KWL);
+   ossimElevManager::instance()->loadState(KWL);
+   
+   if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimInit::initializeElevation(): leaving..." << std::endl;
+}
diff --git a/Utilities/OSSIM/ossim_core/init/ossimInit.h b/Utilities/OSSIM/ossim_core/init/ossimInit.h
new file mode 100644
index 0000000000..8d865264bc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/init/ossimInit.h
@@ -0,0 +1,125 @@
+//*****************************************************************************
+// FILE: ossimInit.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimInit. This object handles all aspects
+//   of initialization for OSSIM applications. These tasks include:
+//
+//      1. Parsing the command line.
+//      2. Instantiating all class factories as declared in ossimFactories.h
+//      3. Initializing the "trace" code execution tracing functionality.
+//      4. Scanning the preferences file for relevant values.
+//
+// SOFTWARE HISTORY:
+//>
+//   24Apr2001  Oscar Kramer (okramer@imagelinks.com)
+//              Initial coding.
+//<
+//*****************************************************************************
+
+#ifndef ossimInit_HEADER
+#define ossimInit_HEADER
+
+#include <base/data_types/ossimString.h>
+
+class ossimPreferences;
+class ossimArgumentParser;
+
+class OSSIMDLLEXPORT ossimInit
+{
+public:
+
+   ~ossimInit();
+   /*!
+    * Returns the static instance of an ossimInit object. This is of no use
+    * until non-static methods are implemented.
+    */
+   static ossimInit* instance();
+
+   void addOptions(ossimArgumentParser& parser);
+   /*!
+    * METHOD: initialize()
+    * This method shall be called from the application's main module with
+    * the command-line arguments. Every OSSIM application should have the
+    * following line early in the main module:
+    *
+    *   ossimInit::initialize(argc, argv);
+    *
+    * OR
+    *
+    *   ossimInit::instance()->initialize(argc, argv);
+    *
+    * The two forms are functionally identical. Pick the latter form if you
+    * like to type. The argv command line options are parsed and may be
+    * stripped. the value of argc will be adjusted to account for stripped
+    * options.
+    */
+   void initialize(int& argc, char** argv);
+
+   void initialize(ossimArgumentParser& parser);
+   
+   void initialize();
+
+   void finalize();
+
+   /*!
+    * METHOD: usage()
+    * Prints to stdout the list of command line options that this object parses
+    */
+   void usage();
+
+   void setPluginLoaderEnabledFlag(bool flag);
+   
+protected:
+   ossimInit();
+   ossimInit(const ossimInit&) {}   
+
+   /*!
+    * METHOD: parseOptions()
+    * Parses the command line as passed in initialize. The options string is
+    * modified:
+    */
+   void parseOptions(int& argc, char** argv);
+
+   void parseOptions(ossimArgumentParser& parser);
+   
+   /*!
+    * METHOD: removeOptions()
+    * Utility for stripping from argv all characters associated with a
+    * particular option:
+    */
+   void removeOption(int&   argc, 
+                     char** argv,
+                     int    argToRemove);
+
+   void initializeDefaultFactories();
+
+   void initializePlugins();
+
+   void initializeElevation();
+   
+   static ossimInit*  theInstance;
+   ossimString        theAppName;
+   ossimPreferences*  thePreferences;
+   bool               theElevEnabledFlag;
+   bool               thePluginLoaderEnabledFlag;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/libpolyclip/.cvsignore b/Utilities/OSSIM/ossim_core/libpolyclip/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/libpolyclip/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/libpolyclip/CMakeLists.txt b/Utilities/OSSIM/ossim_core/libpolyclip/CMakeLists.txt
new file mode 100644
index 0000000000..7b7aec3a35
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/libpolyclip/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_polyclip_SRCS "*.c")
+FILE(GLOB_RECURSE ossim_polyclip_HDRS "*.h")
+ADD_LIBRARY(ossim_polyclip ${ossim_polyclip_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_polyclip)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_polyclip_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/libpolyclip/polyarea.h b/Utilities/OSSIM/ossim_core/libpolyclip/polyarea.h
new file mode 100644
index 0000000000..29c4c36868
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/libpolyclip/polyarea.h
@@ -0,0 +1,336 @@
+/*
+
+      poly_Boolean: a polygon clip library
+
+      Copyright (C) 1997  Alexey Nikitin, Michael Leonov
+
+      leonov@propro.iis.nsk.su
+
+
+
+      This library is free software; you can redistribute it and or
+
+      modify it under the terms of the GNU Library General Public
+
+      License as published by the Free Software Foundation; either
+
+      version 2 of the License, or (at your option) any later version.
+
+
+
+      This library is distributed in the hope that it will be useful,
+
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+
+      Library General Public License for more details.
+
+
+
+      You should have received a copy of the GNU Library General Public
+
+      License along with this library; if not, write to the Free
+
+      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+      polyarea.h
+
+      (C) 1997 Alexey Nikitin, Michael Leonov
+
+      (C) 1997 Klamer Schutte (minor patches)
+
+*/
+
+
+
+#ifndef	POLY_H
+
+#define	POLY_H
+
+
+
+#include "vectmatr.h"
+
+
+
+#ifdef __cplusplus
+
+extern "C" {
+
+#endif
+
+
+
+enum
+
+{
+
+    err_no_memory = 2,
+
+    err_bad_parm = 3,
+
+    err_ok = 0
+
+};
+
+
+
+#define PLF_STATUS      0x0003
+
+#define PLF_CYCLINK     0x0004
+
+#define PLF_MARK		0x0008
+
+#define PLF_RESERVED	0x00FF
+
+
+
+#define PLF_ORIENT      0x0100
+
+#define PLF_DIR         0x0100
+
+#define PLF_INV         0x0000
+
+
+
+typedef struct VNODE VNODE;
+
+struct VNODE
+
+{
+
+    VNODE *next, *prev;
+
+    unsigned int Flags;
+
+    Vector point;
+
+    union
+
+    {
+
+        VNODE *link;
+
+        void *v;
+
+        int i;
+
+    } t;
+
+};
+
+
+
+typedef struct PLINE PLINE;
+
+struct PLINE
+
+{
+
+   PLINE *next;
+   
+   VNODE head;
+   
+   unsigned int Count;
+   
+   unsigned int Flags;
+   
+   double xmin, ymin, xmax, ymax;
+   
+};
+
+
+
+PLINE *poly_NewContour(Vector v);
+
+
+
+void poly_IniContour(PLINE *  c);
+
+void poly_ClrContour(PLINE *  c);  /* clears list of vertices */
+
+void poly_DelContour(PLINE ** c);
+
+
+
+BOOL poly_CopyContour(PLINE ** dst, PLINE * src);
+
+
+
+void poly_PreContour(PLINE * c, BOOL optimize); /* prepare contour */
+
+void poly_InvContour(PLINE * c);  /* invert contour */
+
+
+
+VNODE *poly_CreateNode(Vector v);
+
+
+
+void poly_InclVertex(VNODE * after, VNODE * node);
+
+void poly_ExclVertex(VNODE * node);
+
+
+
+/**********************************************************************/
+
+
+
+typedef struct POLYAREA POLYAREA;
+
+struct POLYAREA
+
+{
+
+    POLYAREA *f, *b;
+
+    PLINE *contours;
+
+};
+
+
+
+/************** POLYMAP ****************/
+
+
+
+#define MAXLABEL 128
+
+
+
+typedef struct POLYMAP  POLYMAP;
+
+struct POLYMAP
+
+{
+
+    POLYMAP  *next;
+
+    POLYAREA *area;
+
+    char     *label;
+
+};
+
+
+
+BOOL LoadPOLYMAP(POLYMAP **m, char *fname);
+
+void SavePOLYMAP(POLYMAP  *m, char *fname);
+
+BOOL poly_Overlay(POLYMAP *R, POLYMAP *B, POLYMAP **r, POLYMAP **b, POLYMAP **p);
+
+/* R and B are input maps, the output maps are:
+
+r = R - B,
+
+b = B - R,
+
+p = R & B */
+
+
+
+BOOL poly_AddMap(POLYMAP **m, POLYAREA *area, char *label);
+
+void poly_DelMap(POLYMAP **m);
+
+
+
+/***************************************/
+
+
+
+BOOL poly_M_Copy0(POLYAREA ** dst, const POLYAREA * srcfst);
+
+void poly_M_Incl(POLYAREA **list, POLYAREA *a);
+
+
+
+BOOL poly_Copy0(POLYAREA **dst, const POLYAREA *src);
+
+BOOL poly_Copy1(POLYAREA  *dst, const POLYAREA *src);
+
+
+
+BOOL poly_InclContour(POLYAREA * p, PLINE * c);
+
+BOOL poly_ExclContour(POLYAREA * p, PLINE * c);
+
+
+
+
+
+BOOL poly_ChkContour(PLINE * a);
+
+
+
+BOOL poly_CheckInside(POLYAREA * c, Vector v0);
+
+
+
+/**********************************************************************/
+
+
+
+/* tools for clipping */
+
+
+
+/* checks whether point lies within contour
+
+independently of its orientation */
+
+
+
+int poly_InsideContour(PLINE *c, Vector v);
+
+int poly_ContourInContour(PLINE * poly, PLINE * inner);
+
+POLYAREA *poly_Create(void);
+
+
+
+void poly_Free(POLYAREA **p);
+
+void poly_Init(POLYAREA  *p);
+
+void poly_Clear(POLYAREA *p);
+
+BOOL poly_Valid(POLYAREA *p);
+
+
+
+enum PolygonBooleanOperation {
+
+	PBO_UNITE,
+
+	PBO_ISECT,
+
+	PBO_SUB,
+
+	PBO_XOR
+
+};
+
+
+
+int poly_Boolean(const POLYAREA * a, const POLYAREA * b, POLYAREA ** res, int action);
+
+
+
+#ifdef __cplusplus
+
+}
+
+#endif
+
+
+
+
+
+#endif /* POLY_H */
+
diff --git a/Utilities/OSSIM/ossim_core/libpolyclip/polygon0.c b/Utilities/OSSIM/ossim_core/libpolyclip/polygon0.c
new file mode 100644
index 0000000000..ab0f01335c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/libpolyclip/polygon0.c
@@ -0,0 +1,1234 @@
+/*
+
+      poly_Boolean: a polygon clip library
+
+      Copyright (C) 1997  Alexey Nikitin, Michael Leonov
+
+      leonov@propro.ru
+
+
+
+      This library is free software; you can redistribute it and/or
+
+      modify it under the terms of the GNU Library General Public
+
+      License as published by the Free Software Foundation; either
+
+      version 2 of the License, or (at your option) any later version.
+
+
+
+      This library is distributed in the hope that it will be useful,
+
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+
+      Library General Public License for more details.
+
+
+
+      You should have received a copy of the GNU Library General Public
+
+      License along with this library; if not, write to the Free
+
+      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+      polygon0.c
+
+      (C) 1997 Alexey Nikitin, Michael Leonov
+
+*/
+
+
+
+#include <assert.h>
+
+#include <math.h>
+
+#include <string.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "vectmatr.h"
+
+#include "polyarea.h"
+
+
+
+#define SETBITS(n,mask,s) (((n)->Flags & ~(mask)) | ((s) & mask))
+
+#define GETBITS(n, mask) ((n)->Flags & mask)
+
+
+
+static
+
+void cntrbox_adjust(PLINE * c, Vector p)
+
+{
+
+    c->xmin = min(c->xmin, p[0]);
+
+    c->xmax = max(c->xmax, p[0]);
+
+    c->ymin = min(c->ymin, p[1]);
+
+    c->ymax = max(c->ymax, p[1]);
+
+}
+
+
+
+static
+
+int cntrbox_pointin(PLINE * c, Vector p)
+
+{
+
+    return (p[0] >= c->xmin && p[1] >= c->ymin &&
+
+            p[0] <= c->xmax && p[1] <= c->ymax);
+
+
+
+}
+
+
+
+static
+
+int cntrbox_inside(PLINE * c1, PLINE * c2)
+
+{
+
+    assert(c1 != NULL && c2 != NULL);
+
+    return ((c1->xmin >= c2->xmin) &&
+
+            (c1->ymin >= c2->ymin) &&
+
+            (c1->xmax <= c2->xmax) &&
+
+            (c1->ymax <= c2->ymax));
+
+}
+
+
+
+static
+
+int node_neighbours(VNODE * a, VNODE * b)
+
+{
+
+    return (a == b) || (a->next == b) || (b->next == a) ||
+
+    (a->next == b->next);
+
+}
+
+
+
+VNODE *poly_CreateNode(Vector v)
+
+{
+
+    VNODE *res;
+
+
+
+    if (v == NULL)
+
+        return NULL;
+
+    res = (VNODE *) malloc(sizeof(VNODE));
+
+    if (res == NULL)
+
+        return NULL;
+
+    res->Flags = 0;
+
+    res->t.link = NULL;
+
+    vect_copy(res->point, v);
+
+    res->prev = res->next = res;
+
+    return res;
+
+}
+
+
+
+void poly_IniContour(PLINE * c)
+
+{
+
+    if (c == NULL)
+
+        return;
+
+    c->next = NULL;
+
+    c->Flags = 0;
+
+    c->Count = 0;
+
+    vect_copy(c->head.point, vect_zero);
+
+    c->head.next = c->head.prev = &c->head;
+
+    c->xmin = c->ymin = +1.0e+30f;
+
+    c->xmax = c->ymax = -1.0e+30f;
+
+}
+
+
+
+PLINE *poly_NewContour(Vector v)
+
+{
+
+    PLINE *res;
+
+
+
+    res = (PLINE *)calloc(1, sizeof(PLINE));
+
+    if (res == NULL)
+
+        return NULL;
+
+
+
+    poly_IniContour(res);
+
+
+
+    if (v != NULL)
+
+    {
+
+        vect_copy(res->head.point, v);
+
+        cntrbox_adjust(res, v);
+
+    }
+
+    
+
+    return res;
+
+}
+
+
+
+void poly_ClrContour(PLINE * c)
+
+{
+
+    VNODE *cur;
+
+
+
+    assert(c != NULL);
+
+    while ( ( cur = c->head.next ) != &c->head )
+
+    {
+
+        poly_ExclVertex(cur);
+
+        free(cur);
+
+    }
+
+    poly_IniContour(c);
+
+}
+
+
+
+void poly_DelContour(PLINE ** c)
+
+{
+
+    if (*c == NULL)
+
+        return;
+
+    poly_ClrContour(*c);
+
+    free(*c), *c = NULL;
+
+}
+
+
+
+#define IsZero(a, b) (fabs((a) - (b)) < EPSILON)
+
+
+
+void poly_PreContour(PLINE *C, BOOL optimize)
+
+{
+
+    double  area = 0;
+
+    VNODE	*p, *c;
+
+
+
+    assert(C != NULL);
+
+
+
+	if (optimize)
+
+	{
+
+		for (c = (p = &C->head)->next; c != &C->head; c = (p = c)->next)
+
+		{
+
+			if (IsZero(p->point[0], c->point[0]) &&
+
+				IsZero(p->point[1], c->point[1]))
+
+			{
+
+				poly_ExclVertex(c);
+
+				free(c);
+
+				c = p;
+
+			}
+
+		}
+
+	}
+
+	C->Count = 0;
+
+    C->xmin = C->xmax = C->head.point[0];
+
+    C->ymin = C->ymax = C->head.point[1];
+
+
+
+    p = (c = &C->head)->prev;
+
+	if (c != p)
+
+	{
+
+		do {
+
+			/* calculate area for orientation */
+
+			area += (p->point[0] - c->point[0]) * (p->point[1] + c->point[1]);
+
+			cntrbox_adjust(C, c->point);
+
+			C->Count++;
+
+		} while ((c = (p = c)->next) != &C->head);
+
+	}
+
+    if (C->Count > 2)
+
+        C->Flags = SETBITS(c, PLF_ORIENT, area < 0 ? PLF_INV : PLF_DIR);
+
+} /* poly_PreContour */
+
+
+
+void poly_InvContour(PLINE * c)
+
+{
+
+    VNODE *cur, *next;
+
+
+
+    assert(c != NULL);
+
+    cur = &c->head;
+
+    do
+
+    {
+
+        next = cur->next;
+
+        cur->next = cur->prev;
+
+        cur->prev = next;
+
+    } while ((cur = next) != &c->head);
+
+    c->Flags ^= PLF_ORIENT;
+
+}
+
+
+
+void poly_InclVertex(VNODE * after, VNODE * node)
+
+{
+
+    assert(after != NULL);
+
+    assert(node != NULL);
+
+
+
+    node->prev = after;
+
+    node->next = after->next;
+
+    after->next = after->next->prev = node;
+
+}
+
+
+
+void poly_ExclVertex(VNODE * node)
+
+{
+
+    assert (node != NULL);
+
+
+
+    node->prev->next = node->next;
+
+    node->next->prev = node->prev;
+
+}
+
+
+
+BOOL poly_CopyContour(PLINE ** dst, PLINE * src)
+
+{
+
+    VNODE *cur, *newnode;
+
+
+
+    assert(src != NULL);
+
+    *dst = NULL;
+
+    *dst = poly_NewContour(src->head.point);
+
+    if (*dst == NULL)
+
+        return FALSE;
+
+
+
+    (*dst)->Count = src->Count;
+
+    (*dst)->Flags = src->Flags;
+
+    (*dst)->xmin = src->xmin, (*dst)->xmax = src->xmax;
+
+    (*dst)->ymin = src->ymin, (*dst)->ymax = src->ymax;
+
+
+
+    for (cur = src->head.next; cur != &src->head; cur = cur->next)
+
+    {
+
+        if ( (newnode = poly_CreateNode(cur->point) ) == NULL)
+
+            return FALSE;
+
+        newnode->Flags = cur->Flags;
+
+        poly_InclVertex((*dst)->head.prev, newnode);
+
+    }
+
+    return TRUE;
+
+}
+
+
+
+/**********************************************************************/
+
+/* polygon routines */
+
+
+
+BOOL poly_Copy0(POLYAREA ** dst, const POLYAREA * src)
+
+{
+
+    *dst = NULL;
+
+    if (src != NULL)
+
+        *dst = (POLYAREA*)calloc(1, sizeof(POLYAREA));
+
+    if (*dst == NULL)
+
+        return FALSE;
+
+
+
+    return poly_Copy1(*dst, src);
+
+}
+
+
+
+BOOL poly_Copy1(POLYAREA * dst, const POLYAREA * src)
+
+{
+
+    PLINE *cur, **last = &dst->contours;
+
+
+
+    *last = NULL;
+
+    dst->f = dst->b = dst;
+
+
+
+    for (cur = src->contours; cur != NULL; cur = cur->next)
+
+    {
+
+        if (!poly_CopyContour(last, cur)) 
+
+            return FALSE;
+
+        last = &(*last)->next;
+
+    }
+
+    return TRUE;
+
+}
+
+
+
+void poly_M_Incl(POLYAREA **list, POLYAREA *a)
+
+{
+
+    if (*list == NULL)
+
+        a->f = a->b = a, *list = a;
+
+    else
+
+    {
+
+        a->f = *list;
+
+        a->b = (*list)->b;
+
+        (*list)->b = (*list)->b->f = a;
+
+    }
+
+}
+
+
+
+BOOL poly_M_Copy0(POLYAREA ** dst, const POLYAREA * srcfst)
+
+{
+
+    const POLYAREA *src = srcfst;
+
+    POLYAREA *di;
+
+
+
+    *dst = NULL;
+
+    if (src == NULL)
+
+        return FALSE;
+
+    do {
+
+        if ((di = poly_Create()) == NULL ||
+
+            !poly_Copy1(di, src))
+
+            return FALSE;
+
+        poly_M_Incl(dst, di);
+
+    } while ((src = src->f) != srcfst);
+
+    return TRUE;
+
+}
+
+
+
+BOOL poly_InclContour(POLYAREA * p, PLINE * c)
+
+{
+
+    PLINE *tmp;
+
+
+
+    if ((c == NULL) || (p == NULL))
+
+        return FALSE;
+
+    if (GETBITS(c, PLF_ORIENT) == PLF_DIR)
+
+    {
+
+        if (p->contours != NULL)
+
+            return FALSE;
+
+        p->contours = c;
+
+    }
+
+    else
+
+    {
+
+        if (p->contours == NULL)
+
+            return FALSE;
+
+        for (tmp = p->contours; tmp->next != NULL; tmp = tmp->next);
+
+        tmp->next = c;
+
+        c->next = NULL;
+
+    }
+
+    return TRUE;
+
+}
+
+
+
+BOOL poly_M_InclContour(POLYAREA ** p, PLINE * c)
+
+{
+
+    POLYAREA *a, *t;
+
+
+
+    if (c == NULL)
+
+        return FALSE;
+
+    if (GETBITS(c, PLF_ORIENT) == PLF_DIR)
+
+    {
+
+        t = poly_Create();
+
+        if (*p != NULL)
+
+        {
+
+            a = (*p)->b;
+
+            (((t->f = a->f)->b = t)->b = a)->f = t;
+
+        }
+
+        else
+
+            *p = t;
+
+        return poly_InclContour(t, c);
+
+    }
+
+    else
+
+    {
+
+        if (*p == NULL)
+
+            return FALSE;
+
+        a = *p;
+
+        t = NULL;
+
+        do {
+
+            /* find the smallest container for the hole */
+
+            if (poly_ContourInContour(a->contours, c) &&
+
+               (t == NULL ||
+
+                poly_ContourInContour(t->contours, a->contours)))
+
+                t = a;
+
+        } while ((a = a->f) != *p);
+
+        if (t == NULL)
+
+            return FALSE;
+
+        else
+
+            return poly_InclContour(t, c);
+
+    }
+
+}
+
+
+
+BOOL poly_ExclContour(POLYAREA * p, PLINE * c)
+
+{
+
+    PLINE *tmp;
+
+
+
+    if ((c == NULL) || (p == NULL) || (p->contours == NULL))
+
+        return FALSE;
+
+    if (GETBITS(c, PLF_ORIENT) == PLF_DIR)
+
+    {
+
+        if (c != p->contours)
+
+            return FALSE;
+
+        assert(c->next == NULL);
+
+        p->contours = NULL;
+
+    }
+
+    else
+
+    {
+
+        for (tmp = p->contours; (tmp->next != c) && (tmp->next != NULL);
+
+             tmp = tmp->next) {}
+
+        if (tmp->next == NULL)
+
+            return FALSE;
+
+        tmp->next = c->next;
+
+    }
+
+    return TRUE;
+
+}
+
+
+
+
+
+BOOL poly_M_ExclContour(POLYAREA * p, PLINE * c)
+
+{
+
+    POLYAREA *a = p;
+
+
+
+    if (p == NULL || c == NULL)
+
+        return FALSE;
+
+    do {
+
+        if (poly_ExclContour(a, c))
+
+            return TRUE;
+
+    } while ((a = a->f) != p);
+
+    return FALSE;
+
+}
+
+
+
+int poly_InsideContour(PLINE * c, Vector p)
+
+{
+
+    int f = 0;
+
+    VNODE *cur;
+
+
+
+    if (!cntrbox_pointin(c, p))
+
+        return FALSE;
+
+
+
+    cur = &c->head;
+
+    do
+
+    {
+
+        if ((
+
+             ((cur->point[1] <= p[1]) && (p[1] < cur->prev->point[1])) ||
+
+             ((cur->prev->point[1] <= p[1]) && (p[1] < cur->point[1]))
+
+             ) && (p[0] <
+
+           (cur->prev->point[0] - cur->point[0]) * (p[1] - cur->point[1])
+
+                 / (cur->prev->point[1] - cur->point[1]) + cur->point[0])
+
+            )
+
+            f = !f;
+
+    } while ((cur = cur->next) != &c->head);
+
+    return f;
+
+}
+
+
+
+
+
+BOOL poly_CheckInside(POLYAREA * p, Vector v0)
+
+{
+
+    PLINE *cur;
+
+
+
+    if ((p == NULL) || (v0 == NULL) || (p->contours == NULL))
+
+        return FALSE;
+
+    cur = p->contours;
+
+    if (poly_InsideContour(cur, v0))
+
+    {
+
+        for (cur = cur->next; cur != NULL; cur = cur->next)
+
+            if (poly_InsideContour(cur, v0))
+
+                return FALSE;
+
+        return TRUE;
+
+    }
+
+    return FALSE;
+
+}
+
+
+
+BOOL poly_M_CheckInside(POLYAREA * p, Vector v0)
+
+{
+
+    POLYAREA *cur;
+
+
+
+    if ((p == NULL) || (v0 == NULL))
+
+        return FALSE;
+
+    cur = p;
+
+    do {
+
+        if (poly_CheckInside(cur, v0))
+
+            return TRUE;
+
+    } while ((cur = cur->f) != p);
+
+    return FALSE;
+
+}
+
+
+
+int poly_ContourInContour(PLINE * poly, PLINE * inner)
+
+{
+
+    assert(poly != NULL);
+
+    assert(inner != NULL);
+
+    if (!cntrbox_inside(inner, poly))
+
+        return FALSE;
+
+    return poly_InsideContour(poly, inner->head.point);
+
+}
+
+
+
+void poly_Init(POLYAREA  *p)
+
+{
+
+    p->f = p->b = p;
+
+    p->contours = NULL;
+
+}
+
+
+
+POLYAREA *poly_Create(void)
+
+{
+
+    POLYAREA *res;
+
+
+
+    if ((res = (POLYAREA*)malloc(sizeof(POLYAREA))) != NULL)
+
+		poly_Init(res);
+
+    return res;
+
+}
+
+
+
+void poly_Clear(POLYAREA *P)
+
+{
+
+    PLINE *p;
+
+
+
+    assert(P != NULL);
+
+    while ((p = P->contours) != NULL)
+
+    {
+
+        P->contours = p->next;
+
+        poly_DelContour(&p);
+
+    }
+
+}
+
+
+
+void poly_Free(POLYAREA ** p)
+
+{
+
+    POLYAREA *cur;
+
+
+
+    if (*p == NULL)
+
+        return;
+
+    for (cur = (*p)->f; cur != *p; cur = (*p)->f)
+
+    {
+
+        poly_Clear(cur);
+
+        cur->f->b = cur->b;
+
+        cur->b->f = cur->f;
+
+        free(cur);
+
+    }
+
+    poly_Clear(cur);
+
+    free(*p), *p = NULL;
+
+}
+
+
+
+static
+
+BOOL inside_sector(VNODE * pn, Vector p2)
+
+{
+
+    Vector cdir, ndir, pdir;
+
+    int p_c, n_c, p_n;
+
+
+
+    assert(pn != NULL);
+
+    vect_sub(cdir, p2, pn->point);
+
+    vect_sub(pdir, pn->point, pn->prev->point);
+
+    vect_sub(ndir, pn->next->point, pn->point);
+
+
+
+    p_c = vect_det2(pdir, cdir) >= 0;
+
+    n_c = vect_det2(ndir, cdir) >= 0;
+
+    p_n = vect_det2(pdir, ndir) >= 0;
+
+
+
+    if ((p_n && p_c && n_c) || ((!p_n) && (p_c || n_c)))
+
+        return TRUE;
+
+    else
+
+        return FALSE;
+
+} /* inside_sector */
+
+
+
+/* returns TRUE if bad contour */
+
+BOOL poly_ChkContour(PLINE * a)
+
+{
+
+    VNODE *a1, *a2, *hit1, *hit2;
+
+    Vector i1, i2;
+
+    int    icnt;
+
+
+
+    assert(a != NULL);
+
+    a1 = &a->head;
+
+    do
+
+    {
+
+        a2 = a1;
+
+        do
+
+        {
+
+            if (!node_neighbours(a1, a2) &&
+
+                (icnt = vect_inters2(a1->point, a1->next->point,
+
+                              a2->point, a2->next->point, i1, i2)) > 0)
+
+            {
+
+                if (icnt > 1)
+
+                    return TRUE;
+
+
+
+                if (vect_dist2(i1, a1->point) < EPSILON)
+
+                    hit1 = a1;
+
+                else if (vect_dist2(i1, a1->next->point) < EPSILON)
+
+                    hit1 = a1->next;
+
+                else
+
+                    return TRUE;
+
+
+
+                if (vect_dist2(i1, a2->point) < EPSILON)
+
+                    hit2 = a2;
+
+                else if (vect_dist2(i1, a2->next->point) < EPSILON)
+
+                    hit2 = a2->next;
+
+                else
+
+                    return TRUE;
+
+
+
+                /* now check if they are inside each other */
+
+                if (inside_sector(hit1, hit2->prev->point) ||
+
+                    inside_sector(hit1, hit2->next->point) ||
+
+                    inside_sector(hit2, hit1->prev->point) ||
+
+                    inside_sector(hit2, hit1->next->point))
+
+                    return TRUE;
+
+            }
+
+        }
+
+        while ((a2 = a2->next) != &a->head);
+
+    }
+
+    while ((a1 = a1->next) != &a->head);
+
+    return FALSE;
+
+}
+
+
+
+
+
+BOOL poly_Valid(POLYAREA * p)
+
+{
+
+    PLINE *c;
+
+
+
+    if ((p == NULL) || (p->contours == NULL))
+
+        return FALSE;
+
+
+
+    if (GETBITS(p->contours, PLF_ORIENT) == PLF_INV ||
+
+        poly_ChkContour(p->contours))
+
+        return FALSE;
+
+    for (c = p->contours->next; c != NULL; c = c->next)
+
+    {
+
+        if (GETBITS(c, PLF_ORIENT) == PLF_DIR ||
+
+            poly_ChkContour(c) ||
+
+            !poly_ContourInContour(p->contours, c) )
+
+            return FALSE;
+
+    }
+
+    return TRUE;
+
+}
+
+
+
+/******************* POLYMAP ************************/
+
+
+
+BOOL poly_AddMap(POLYMAP **m, POLYAREA *area, char *label)
+
+{
+
+    POLYMAP *n;
+
+    if (area == NULL) return 0;
+
+    if ((n = (POLYMAP*)calloc(1, sizeof(POLYMAP))) == NULL)
+
+        return 1;
+
+    n->area = area;
+
+    n->label = strdup(label);
+
+    n->next = *m, *m = n;
+
+    return 0;
+
+} /* poly_AddMap */
+
+
+
+void poly_DelMap(POLYMAP **m)
+
+{
+
+    assert(m != NULL);
+
+    while (*m != NULL)
+
+    {
+
+        poly_Free(&(*m)->area);
+
+        free((*m)->label);
+
+        *m = (*m)->next;
+
+    }
+
+} /* poly_DelMap */
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/libpolyclip/polygon1.c b/Utilities/OSSIM/ossim_core/libpolyclip/polygon1.c
new file mode 100644
index 0000000000..7e09e38320
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/libpolyclip/polygon1.c
@@ -0,0 +1,1482 @@
+/*
+
+      poly_Boolean: a polygon clip library
+
+      Copyright (C) 1997  Alexey Nikitin, Michael Leonov
+
+      leonov@propro.ru
+
+
+
+  based on:
+
+      nclip: a polygon clip library
+
+      Copyright (C) 1993  Klamer Schutte
+
+
+
+      This library is free software; you can redistribute it and or
+
+      modify it under the terms of the GNU Library General Public
+
+      License as published by the Free Software Foundation; either
+
+      version 2 of the License, or (at your option) any later version.
+
+
+
+      This library is distributed in the hope that it will be useful,
+
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+
+      Library General Public License for more details.
+
+
+
+      You should have received a copy of the GNU Library General Public
+
+      License along with this library; if not, write to the Free
+
+      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+      polygon1.c
+
+      (C) 1997 Alexey Nikitin, Michael Leonov
+
+      (C) 1993 Klamer Schutte
+
+
+
+      all cases where original (Klamer Schutte) code is present
+
+      are marked
+
+*/
+
+
+
+#include	<assert.h>
+
+#include	<stdlib.h>
+
+#include	<string.h>
+
+#include	<setjmp.h>
+
+#include	<math.h>
+
+
+
+#include	"polyarea.h"
+
+#include	"vectmatr.h"
+
+
+
+#define ISECTED 0
+
+#define SHARED  ISECTED
+
+#define INSIDE  1
+
+#define OUTSIDE 2
+
+#define UNKNOWN 3
+
+
+
+/* this means that current polygon is B and operation is A - B */
+
+#define PBO_SUBSLAVE (-PBO_SUB)
+
+
+
+#define SETBITS(n,mask,s) (((n)->Flags & ~(mask)) | ((s) & mask))
+
+#define GETBITS(n, mask) ((n)->Flags & mask)
+
+#define PLF_ESTATE(n)   GETBITS(n, PLF_STATUS)
+
+
+
+#define error(code) longjmp(*(e), code)
+
+
+
+#define MemGet(ptr, type) \
+if (((ptr) = (type*)malloc(sizeof(type))) == NULL) \
+   error(err_no_memory);
+
+
+
+/***************************************************************/
+
+/* routines for processing intersections */
+
+
+
+/*
+
+node_add
+
+ (C) 1993 Klamer Schutte
+
+ (C) 1997 Alexey Nikitin, Michael Leonov
+
+*/
+
+static
+
+VNODE *node_add(VNODE * dest, Vector po, int *new_point)
+
+{
+
+    VNODE *chk = dest, *last, *p;
+
+    double d;
+
+
+
+    do
+
+        if (vect_equal(po, chk->point))
+
+            return chk;
+
+    while ((chk = chk->next) != dest);
+
+
+
+    d = vect_dist2(dest->point, po);
+
+    for (p = (last = dest)->next; d > vect_dist2(dest->point, p->point);
+
+         p = (last = p)->next) ;
+
+    /* Go to next node, as next node is on same side as current node */
+
+    p = poly_CreateNode(po);
+
+    if ( p == NULL ) return NULL;
+
+/*    *new_point++; */
+
+    p->prev = last;
+
+    p->next = last->next;
+
+    p->t.link = NULL;
+
+    p->Flags = UNKNOWN;
+
+    return ( last->next = last->next->prev = p );
+
+} /* node_add */
+
+
+
+#define ISECT_BAD_PARAM (-1)
+
+#define ISECT_NO_MEMORY (-2)
+
+
+
+/*
+
+node_add_point
+
+ (C) 1993 Klamer Schutte
+
+ (C) 1997 Alexey Nikitin, Michael Leonov
+
+*/
+
+
+
+static
+
+int node_add_point(VNODE * a, VNODE * b, Vector p)
+
+{
+
+    int res = 0;
+
+
+
+    VNODE *node_a = node_add(a, p, &res);
+
+    VNODE *node_b = node_add(b, p, &res);
+
+
+
+    if ( node_a == NULL || node_b == NULL )
+
+        return ISECT_NO_MEMORY;
+
+    if (node_a->t.link != 0 && node_a->t.link != node_b)
+
+        return ISECT_BAD_PARAM;
+
+    if (node_b->t.link != 0 && node_b->t.link != node_a)
+
+        return ISECT_BAD_PARAM;
+
+
+
+    node_a->t.link = node_b;
+
+    node_b->t.link = node_a;
+
+    return res;
+
+} /* node_add_point */
+
+
+
+/*
+
+
+
+intersect
+
+ (C) 1993 Klamer Schutte
+
+ (C) 1997 Alexey Nikitin, Michael Leonov
+
+
+
+ calculate all the intersections between a and b. Add the intersection points
+
+ to a and b.
+
+ returns total number of intersections found.*/
+
+static
+
+int intersect(PLINE * a, PLINE * b)
+
+{
+
+    VNODE *a_iter, *b_iter;
+
+    int res = 0, res2 = 0, cnt, errc;
+
+    Vector intersect1, intersect2;
+
+
+
+    assert(a != NULL);
+
+    assert(b != NULL);
+
+
+
+    /* if their boxes do not isect return 0 intersections */
+
+    if ( ( a->xmin > b->xmax ) || ( a->xmax < b->xmin ) ||
+
+         ( a->ymin > b->ymax ) || ( a->ymax < b->ymin ) )
+
+         return 0;
+
+
+
+    a_iter = &a->head;
+
+    do {
+
+        b_iter = &b->head;
+
+        do {
+
+            cnt = vect_inters2(a_iter->point, a_iter->next->point,
+
+                               b_iter->point, b_iter->next->point,
+
+                               intersect1, intersect2);
+
+            res += cnt;
+
+            if (cnt > 0)
+
+            {
+
+                res2 += ( errc = node_add_point(a_iter, b_iter, intersect1) );
+
+                if ( errc < 0 ) return errc;
+
+                if (cnt >= 2)
+
+                {
+
+                    res2 += ( errc = node_add_point(a_iter, b_iter, intersect2) );
+
+                    if ( errc < 0 ) return errc;
+
+                }
+
+            }
+
+        } while ((b_iter = b_iter->next) != &b->head);
+
+    } while ((a_iter = a_iter->next) != &a->head);
+
+
+
+    if (res2 != 0)
+
+    {
+
+        if ( (errc = intersect(a, b)) < 0 )
+
+            return errc;
+
+        else
+
+            return res + errc;
+
+    }
+
+
+
+    return res;
+
+} /* intersect */
+
+
+
+static
+
+void M_POLYAREA_intersect(jmp_buf *e, POLYAREA * afst, POLYAREA * bfst)
+
+{
+
+    POLYAREA *a = afst, *b = bfst;
+
+    PLINE *curcA, *curcB;
+
+    int locisect;
+
+
+
+    if ( a == NULL || b == NULL )
+
+        error(err_bad_parm);
+
+    do {
+
+        do {
+
+            for (curcA = a->contours; curcA != NULL; curcA = curcA->next)
+
+                for (curcB = b->contours; curcB != NULL; curcB = curcB->next)
+
+                    if ((locisect = intersect(curcA, curcB)) > 0)
+
+                    {
+
+                        curcA->Flags = SETBITS(curcA, PLF_STATUS, ISECTED);
+
+                        curcB->Flags = SETBITS(curcB, PLF_STATUS, ISECTED);
+
+                    }
+
+                    else if ( locisect == ISECT_BAD_PARAM )
+
+                        error(err_bad_parm);
+
+                    else if ( locisect == ISECT_NO_MEMORY )
+
+                        error(err_no_memory);
+
+        } while ((a = a->f) != afst);
+
+    } while ((b = b->f) != bfst);
+
+} /* M_POLYAREA_intersect */
+
+
+
+/*****************************************************************/
+
+/* Routines for making labels */
+
+
+
+/* cntr_in_M_POLYAREA
+
+returns poly is inside outfst ? TRUE : FALSE */
+
+static
+
+int cntr_in_M_POLYAREA(PLINE * poly, POLYAREA * outfst)
+
+{
+
+    PLINE  *curc;
+
+    POLYAREA *outer = outfst;
+
+
+
+    assert(poly != NULL);
+
+    assert(outer != NULL);
+
+
+
+    do {
+
+        if (poly_ContourInContour(outer->contours, poly))
+
+        {
+
+            for (curc = outer->contours->next; curc != NULL; curc = curc->next)
+
+                if (poly_ContourInContour(curc, poly))
+
+                    continue;
+
+            return TRUE;
+
+        }
+
+    } while ((outer = outer->f) != outfst);
+
+    return FALSE;
+
+} /* cntr_in_M_POLYAREA */
+
+
+
+/*
+
+node_label
+
+ (C) 1993 Klamer Schutte
+
+ (C) 1997 Alexey Nikitin, Michael Leonov
+
+*/
+
+
+
+static
+
+unsigned int node_label(Vector p2, VNODE * pn)
+
+{
+
+    Vector
+
+    cdir, ndir, pdir;
+
+    int p_c, n_c, p_n;
+
+
+
+    assert(pn != NULL);
+
+    vect_sub(cdir, p2, pn->point);
+
+    vect_sub(pdir, pn->point, pn->prev->point);
+
+    vect_sub(ndir, pn->next->point, pn->point);
+
+
+
+    p_c = vect_det2(pdir, cdir) >= 0;
+
+    n_c = vect_det2(ndir, cdir) >= 0;
+
+    p_n = vect_det2(pdir, ndir) >= 0;
+
+
+
+    if ((p_n && p_c && n_c) || ((!p_n) && (p_c || n_c)))
+
+        return INSIDE;
+
+    else
+
+        return OUTSIDE;
+
+
+
+} /* node_label */
+
+
+
+/*
+
+label_contour
+
+ (C) 1993 Klamer Schutte
+
+ (C) 1997 Alexey Nikitin, Michael Leonov
+
+*/
+
+
+
+static
+
+void label_contour(PLINE * a)
+
+{
+
+    VNODE *cur = &a->head, *b1, *b2;
+
+
+
+    do {
+
+        if ( PLF_ESTATE(cur) != OUTSIDE && PLF_ESTATE(cur) != UNKNOWN )
+
+            continue;
+
+
+
+        b1 = cur->t.link;
+
+        b2 = cur->next->t.link;
+
+
+
+        if ( b1 != NULL && b2 != NULL &&
+
+            /* Seems SHARED -- but check
+
+               that b1 and b2 are also connected! */
+
+           ( b1->next == b2 || b2->next == b1 ) )
+
+        {
+
+                cur->Flags = SETBITS(cur, PLF_STATUS, SHARED);
+
+                continue;
+
+        }
+
+        /* else isected by different contours */
+
+        if (b1 != NULL)
+
+            cur->Flags = SETBITS(cur, PLF_STATUS, node_label(cur->next->point, b1));
+
+        else if (b2 != NULL)
+
+            cur->Flags = SETBITS(cur, PLF_STATUS, node_label(cur->point, b2));
+
+    } while ((cur = cur->next) != &a->head);
+
+} /* label_contour */
+
+
+
+static
+
+void cntr_label_POLYAREA(PLINE * poly, POLYAREA * ppl)
+
+{
+
+    assert(ppl != NULL && ppl->contours != NULL);
+
+    if (GETBITS(poly, PLF_STATUS) == ISECTED)
+
+        label_contour(poly);
+
+    else if ( cntr_in_M_POLYAREA( poly, ppl ) )
+
+        poly->Flags = SETBITS( poly, PLF_STATUS, INSIDE);
+
+    else
+
+        poly->Flags = SETBITS( poly, PLF_STATUS, OUTSIDE);
+
+} /* cntr_label_POLYAREA */
+
+
+
+static
+
+void M_POLYAREA_label(POLYAREA * afst, POLYAREA * b)
+
+{
+
+    POLYAREA *a = afst;
+
+    PLINE *curc;
+
+
+
+    assert(a != NULL);
+
+    do {
+
+    for (curc = a->contours; curc != NULL; curc = curc->next)
+
+        cntr_label_POLYAREA(curc, b);
+
+    } while ((a = a->f) != afst);
+
+}
+
+
+
+/****************************************************************/
+
+
+
+/* routines for temporary storing resulting contours */
+
+static
+
+void InsCntr(jmp_buf *e, PLINE * c, POLYAREA ** dst)
+
+{
+
+    POLYAREA *newp;
+
+
+
+    if (*dst == NULL)
+
+    {
+
+        MemGet(*dst, POLYAREA);
+
+        (*dst)->f = (*dst)->b = *dst;
+
+        newp = *dst;
+
+    }
+
+    else
+
+    {
+
+        MemGet(newp, POLYAREA);
+
+        newp->f = *dst;
+
+        newp->b = (*dst)->b;
+
+        newp->f->b = newp->b->f = newp;
+
+    }
+
+    newp->contours = c;
+
+    c->next = NULL;
+
+} /* InsCntr */
+
+
+
+static
+
+void PutContour(jmp_buf *e, PLINE * cntr, POLYAREA ** contours, PLINE ** holes)
+
+{
+
+    PLINE *cur;
+
+
+
+    assert(cntr != NULL);
+
+    cntr->next = NULL;
+
+    if (GETBITS(cntr, PLF_ORIENT) == PLF_DIR)
+
+        InsCntr(e, cntr, contours);
+
+
+
+    /* put hole into temporary list */
+
+    else if (*holes == NULL)
+
+        *holes = cntr; /* let cntr be 1st hole in list */
+
+    else
+
+    {
+
+        for (cur = *holes; cur->next != NULL; cur = cur->next);
+
+        cur->next = cntr;
+
+    }
+
+} /* PutContour */
+
+
+
+static
+
+void InsertHoles(jmp_buf *e, POLYAREA * dest, PLINE **src)
+
+{
+
+    POLYAREA *curc, *container;
+
+    PLINE *curh, *nexth;
+
+
+
+    if (*src == NULL) return; /* empty hole list */
+
+    if (dest == NULL) error(err_bad_parm); /* empty contour list */
+
+    
+
+    while ((curh = *src) != NULL)
+
+    {
+
+        *src = curh->next;
+
+
+
+        container = NULL;
+
+        curc = dest;
+
+        do
+
+        {
+
+            /* find the smallest container for the hole */
+
+            if (poly_ContourInContour(curc->contours, curh) &&
+
+               (container == NULL ||
+
+                poly_ContourInContour(container->contours, curc->contours)))
+
+                container = curc;
+
+        } while ((curc = curc->f) != dest);
+
+        nexth = curh->next;
+
+        curh->next = NULL;
+
+        if (container == NULL)
+
+        {
+
+            /* bad input polygons were given */
+
+            poly_DelContour(&curh);
+
+            error(err_bad_parm);
+
+        }
+
+        else
+
+            poly_InclContour(container, curh);
+
+    }
+
+} /* InsertHoles */
+
+
+
+
+
+/****************************************************************/
+
+/* routines for collecting result */
+
+
+
+typedef enum
+
+{
+
+    FORW, BACKW
+
+} DIRECTION;
+
+
+
+/* Start Rule */
+
+typedef int (*S_Rule) (VNODE *, DIRECTION *);
+
+
+
+/* Jump Rule  */
+
+typedef int (*J_Rule) (VNODE *, DIRECTION *);
+
+
+
+static
+
+int UniteS_Rule(VNODE * cur, DIRECTION * initdir)
+
+{
+
+    *initdir = FORW;
+
+    return (PLF_ESTATE(cur) == OUTSIDE) ||
+
+           (PLF_ESTATE(cur) == SHARED && cur->next->t.link == cur->t.link->next);
+
+}
+
+
+
+static
+
+int IsectS_Rule(VNODE * cur, DIRECTION * initdir)
+
+{
+
+    *initdir = FORW;
+
+    return (PLF_ESTATE(cur) == INSIDE) ||
+
+           (PLF_ESTATE(cur) == SHARED && cur->next->t.link == cur->t.link->next);
+
+}
+
+
+
+
+
+static
+
+int SubS_Rule(VNODE * cur, DIRECTION * initdir)
+
+{
+
+    *initdir = FORW;
+
+    return (PLF_ESTATE(cur) == OUTSIDE) ||
+
+           (PLF_ESTATE(cur) == SHARED && cur->next->t.link == cur->t.link->prev);
+
+}
+
+
+
+static
+
+int SubSlaveS_Rule(VNODE * cur, DIRECTION * initdir)
+
+{
+
+    *initdir = BACKW;
+
+    return (PLF_ESTATE(cur) == INSIDE);
+
+}
+
+
+
+static
+
+int IsectJ_Rule(VNODE * cur, DIRECTION * cdir)
+
+{
+
+    assert(*cdir == FORW);
+
+    return (PLF_ESTATE(cur->t.link) == INSIDE);
+
+}
+
+
+
+static
+
+int UniteJ_Rule(VNODE * cur, DIRECTION * cdir)
+
+{
+
+    assert(*cdir == FORW);
+
+    return (PLF_ESTATE(cur) != OUTSIDE && PLF_ESTATE(cur->t.link) == OUTSIDE);
+
+}
+
+
+
+static
+
+int SubJ_Rule(VNODE * cur, DIRECTION * cdir)
+
+{
+
+    if (*cdir == FORW)
+
+    {
+
+        if (PLF_ESTATE(cur->t.link->prev) == INSIDE)
+
+        {
+
+            *cdir = BACKW;
+
+            return TRUE;
+
+        }
+
+    }
+
+    else if (PLF_ESTATE(cur->t.link) == OUTSIDE ||
+
+             PLF_ESTATE(cur->t.link) == SHARED)
+
+    {
+
+        *cdir = FORW;
+
+        return TRUE;
+
+    }
+
+    return FALSE;
+
+}
+
+
+
+static
+
+int Gather(VNODE * start, PLINE ** result, J_Rule j_rule, DIRECTION initdir)
+
+{
+
+    VNODE *cur = start, *newn, *cn;
+
+    DIRECTION dir = initdir;
+
+    *result = poly_NewContour(start->point);
+
+    if ( *result == NULL ) return err_no_memory;
+
+    do
+
+    {
+
+        cn = (dir == FORW ? cur : cur->prev);
+
+        cn->Flags = SETBITS( cn, PLF_MARK, PLF_MARK);
+
+
+
+        /* for SHARED edge mark its neighbour, if the direction
+
+        is the same */
+
+        if (PLF_ESTATE(cn) == SHARED && cn->t.link->next == cn->next->t.link)
+
+            cn->t.link->Flags |= PLF_MARK;
+
+
+
+        cur = (dir == FORW ? cur->next : cur->prev);
+
+
+
+        if (cur->t.link != NULL && j_rule(cur, &dir))
+
+            cur = cur->t.link; /* jump */
+
+        if (!vect_equal(cur->point, start->point))
+
+        {
+
+            if ( (newn = poly_CreateNode(cur->point)) == NULL)
+
+                return err_no_memory;
+
+            poly_InclVertex((*result)->head.prev, newn);
+
+        }
+
+    } while (!vect_equal(cur->point, start->point));
+
+    return err_ok;
+
+} /* Gather */
+
+
+
+static
+
+void Collect(jmp_buf *e, PLINE * a, POLYAREA ** contours, PLINE ** holes,
+
+              S_Rule c_rule, J_Rule j_rule)
+
+{
+
+    VNODE *cur;
+
+    PLINE *p = NULL;
+
+    int errc = err_ok;
+
+    DIRECTION dir;
+
+
+
+    cur = &a->head;
+
+    do
+
+        if ((cur->Flags & PLF_MARK) == 0 && c_rule(cur, &dir))
+
+        {
+
+            p = NULL; /* start making contour */
+
+            if ( (errc = Gather(dir == FORW ? cur : cur->next, &p, j_rule, dir)) != err_ok)
+
+            {
+
+                if (p != NULL) poly_DelContour(&p);
+
+                error(errc);
+
+            }
+
+            poly_PreContour(p, TRUE);
+
+            PutContour(e, p, contours, holes);
+
+        }
+
+    while ((cur = cur->next) != &a->head);
+
+} /* Collect */
+
+
+
+static
+
+void cntr_Collect(jmp_buf *e, PLINE * A, POLYAREA ** contours, PLINE ** holes,
+
+                   int action)
+
+{
+
+    PLINE *tmprev;
+
+
+
+    if (GETBITS(A, PLF_STATUS) == ISECTED)
+
+    {
+
+        switch (action)
+
+        {
+
+        case PBO_UNITE:
+
+            Collect(e, A, contours, holes, UniteS_Rule, UniteJ_Rule);
+
+            break;
+
+        case PBO_ISECT:
+
+            Collect(e, A, contours, holes, IsectS_Rule, IsectJ_Rule);
+
+            break;
+
+        case PBO_XOR:
+
+        case PBO_SUBSLAVE:
+
+            Collect(e, A, contours, holes, SubSlaveS_Rule, SubJ_Rule);
+
+            if (action == PBO_SUBSLAVE)
+
+                break;
+
+        case PBO_SUB:
+
+            Collect(e, A, contours, holes, SubS_Rule, SubJ_Rule);
+
+            break;
+
+        };
+
+    }
+
+    else
+
+    {
+
+        switch (action)
+
+        {
+
+        case PBO_ISECT:
+
+            if (GETBITS(A, PLF_STATUS)  == INSIDE)
+
+            {
+
+                if (!poly_CopyContour(&tmprev, A) )
+
+                    error(err_no_memory);
+
+                poly_PreContour(tmprev, TRUE);
+
+                PutContour(e, tmprev, contours, holes);
+
+            }
+
+            break;
+
+        case PBO_XOR:
+
+        case PBO_SUBSLAVE:
+
+            if (GETBITS(A, PLF_STATUS)  == INSIDE)
+
+            {
+
+                if ( !poly_CopyContour(&tmprev, A) )
+
+                    error(err_no_memory);
+
+                poly_PreContour(tmprev, TRUE);
+
+                poly_InvContour(tmprev);
+
+                PutContour(e, tmprev, contours, holes);
+
+            }
+
+            if (action == PBO_SUBSLAVE)
+
+                break;
+
+        case PBO_UNITE:
+
+        case PBO_SUB:
+
+            if (GETBITS(A, PLF_STATUS)  == OUTSIDE)
+
+            {
+
+                if ( !poly_CopyContour(&tmprev, A) )
+
+                    error(err_no_memory);
+
+                poly_PreContour(tmprev, TRUE);
+
+                PutContour(e, tmprev, contours, holes);
+
+            }
+
+            break;
+
+        }
+
+    }
+
+} /* cntr_Collect */
+
+
+
+
+
+static
+
+void M_POLYAREA_Collect(jmp_buf *e, POLYAREA * afst, POLYAREA ** contours, PLINE ** holes,
+
+                      int action)
+
+{
+
+    POLYAREA *a = afst;
+
+    PLINE *cur;
+
+
+
+    assert(a != NULL);
+
+    do {
+
+        for (cur = a->contours; cur != NULL; cur = cur->next)
+
+            cntr_Collect(e, cur, contours, holes, action);
+
+    } while ((a = a->f) != afst);
+
+}
+
+
+
+/************************************************************************/
+
+/* prepares polygon for algorithm, sets UNKNOWN labels and clears MARK bits */
+
+static
+
+void M_InitPolygon(POLYAREA * afst)
+
+{
+
+    PLINE *curc;
+
+    VNODE *curn;
+
+    POLYAREA *a = afst;
+
+
+
+    assert(a != NULL);
+
+    do {
+
+        for (curc = a->contours; curc != NULL; curc = curc->next)
+
+        {
+
+            poly_PreContour(curc, TRUE);
+
+            curc->Flags = SETBITS( curc, PLF_STATUS, UNKNOWN );
+
+            curn = &curc->head;
+
+            do {
+
+                /*
+
+                PLF_CYCLINK = 0, PLF_MARK = 0, PLF_STATUS = UNKNOWN
+
+                */
+
+                curn->Flags = SETBITS(curn, PLF_RESERVED, UNKNOWN);
+
+                curn->t.link = NULL;
+
+            } while ((curn = curn->next) != &curc->head);
+
+        }
+
+    } while ((a = a->f) != afst);
+
+} /* M_InitPolygon */
+
+
+
+/* the main clipping routine */
+
+int poly_Boolean(const POLYAREA * a_org, const POLYAREA * b_org, POLYAREA ** res, int action)
+
+{
+
+    POLYAREA    *a = NULL, *b = NULL;
+
+    PLINE       *p, *holes = NULL;
+
+    jmp_buf     e;
+
+    int         code;
+
+
+
+    *res = NULL;
+
+
+
+    if ((code = setjmp(e)) == 0)
+
+    {
+
+        if (!poly_M_Copy0(&a, a_org) || !poly_M_Copy0(&b, b_org))
+
+            longjmp(e, err_no_memory);
+
+
+
+        /* prepare polygons */
+
+        M_InitPolygon(a);
+
+        M_InitPolygon(b);
+
+
+
+        /*M_POLYAREA_cyclink(a);
+
+        M_POLYAREA_cyclink(b);*/
+
+
+
+        M_POLYAREA_intersect(&e, a, b);
+
+
+
+        M_POLYAREA_label(a, b);
+
+        M_POLYAREA_label(b, a);
+
+
+
+        M_POLYAREA_Collect(&e, a, res, &holes, action);
+
+
+
+        if (action == PBO_SUB)
+
+            action = PBO_SUBSLAVE;
+
+        M_POLYAREA_Collect(&e, b, res, &holes, action);
+
+
+
+        InsertHoles(&e, *res, &holes);
+
+    }
+
+    /* delete holes */
+
+    while ((p = holes) != NULL)
+
+    {
+
+        holes = p->next;
+
+        poly_DelContour(&p);
+
+    }
+
+    poly_Free(&a);
+
+    poly_Free(&b);
+
+
+
+    if (code)
+
+        poly_Free(res);
+
+    return code;
+
+} /* poly_Boolean */
+
+
+
+/********************* MAP OVERLAY **********************/
+
+
+
+static
+
+BOOL SubMap(POLYMAP *R, POLYMAP *B, POLYMAP **r)
+
+{
+
+    POLYMAP *ri;
+
+    for (ri = R; ri != NULL; ri = ri->next)
+
+    {
+
+        POLYAREA *sub = NULL;
+
+        POLYMAP  *bi;
+
+        if (!poly_M_Copy0(&sub, ri->area))
+
+            return 1;
+
+        for (bi = B; bi != NULL; bi = bi->next)
+
+        {
+
+            POLYAREA *t = NULL;
+
+            if (poly_Boolean(sub, bi->area, &t, PBO_SUB))
+
+                return 1;
+
+            poly_Free(&sub), sub = t;
+
+        }
+
+        if (poly_AddMap(r, sub, ri->label))
+
+            return 1;
+
+    }
+
+    return 0;
+
+} /* SubMap */
+
+
+
+BOOL poly_Overlay(POLYMAP *R, POLYMAP *B,
+
+                  POLYMAP **r, POLYMAP **b, POLYMAP **p)
+
+{
+
+    char    res[MAXLABEL + 1];
+
+    POLYMAP *ri;
+
+    if (R == NULL || B == NULL) return 1;
+
+
+
+    /* first, find the purple polygons */
+
+    for (ri = R; ri != NULL; ri = ri->next)
+
+    {
+
+        POLYMAP *bi;
+
+        for (bi = B; bi != NULL; bi = bi->next)
+
+        {
+
+            POLYAREA *rp = NULL;
+
+            if (poly_Boolean(ri->area, bi->area, &rp, PBO_ISECT))
+
+                return 1;
+
+
+
+            strcat(strcat(strcpy(res, ri->label), " & "), bi->label);
+
+            if (poly_AddMap(p, rp, res))
+
+                return 1;
+
+        }
+
+    }
+
+
+
+    /* find pure red and blue polygons */
+
+    return SubMap(R, B, r) || SubMap(B, R, b);
+
+} /* poly_Overlay */
+
diff --git a/Utilities/OSSIM/ossim_core/libpolyclip/polyio.c b/Utilities/OSSIM/ossim_core/libpolyclip/polyio.c
new file mode 100644
index 0000000000..4b0f5612fa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/libpolyclip/polyio.c
@@ -0,0 +1,306 @@
+/*
+
+      poly_Boolean: a polygon clip library
+
+      Copyright (C) 1997  Alexey Nikitin, Michael Leonov
+
+      leonov@propro.ru
+
+
+
+      This library is free software; you can redistribute it and or
+
+      modify it under the terms of the GNU Library General Public
+
+      License as published by the Free Software Foundation; either
+
+      version 2 of the License, or (at your option) any later version.
+
+
+
+      This library is distributed in the hope that it will be useful,
+
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+
+      Library General Public License for more details.
+
+
+
+      You should have received a copy of the GNU Library General Public
+
+      License along with this library; if not, write to the Free
+
+      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+      polyio.c
+
+      (C) 1997 Michael Leonov
+
+*/
+
+
+
+#include <stdio.h>
+
+#include <string.h>
+
+
+
+#include "polyarea.h"
+
+#include "vectmatr.h"
+
+
+
+static
+
+PLINE *LoadPLINE(FILE * f)
+
+{
+
+    int cnt, i;
+
+    PLINE *res = NULL;
+
+    Vector v;
+
+
+
+    fscanf(f, "%d", &cnt);
+
+    if (cnt < 3) return NULL;
+
+    for ( i = 0; i < cnt; i++ )
+
+    {
+
+        fscanf(f, "%lf %lf", v, v + 1);
+
+        v[2] = 0.0f;
+
+        if ( res == NULL )
+
+        {
+
+            if ((res = poly_NewContour(v)) == NULL)
+
+                return NULL;
+
+        }
+
+        else
+
+            poly_InclVertex(res->head.prev, poly_CreateNode(v));
+
+    }
+
+    poly_PreContour(res, TRUE);
+
+    return res;
+
+} /* LoadPLINE */
+
+
+
+static
+
+size_t til_eol(const char *str)
+
+{
+
+    char *eoln;
+
+    eoln = strchr(str, '\n');
+
+    return eoln != NULL ? (size_t)(eoln - str) : MAXLABEL;
+
+} /* til_eol */
+
+
+
+BOOL LoadPOLYMAP(POLYMAP **m, char *fname)
+
+{
+
+    int nMaps, k;
+
+    char label[MAXLABEL + 1];
+
+    FILE *f = fopen( fname, "r" );
+
+    if (f == NULL) return 1;
+
+    fscanf(f, "%d", &nMaps);
+
+    if (nMaps < 1) return 1;
+
+    for (k = 0; k < nMaps; k++)
+
+    {
+
+        int cnt, pcnt, i, j;
+
+        PLINE *cntr;
+
+        POLYAREA *p;
+
+        POLYAREA *area = NULL;
+
+
+
+        fgets(label, MAXLABEL, f);
+
+        fgets(label, MAXLABEL, f);
+
+        label[til_eol(label)] = 0;
+
+        fscanf(f, "%d", &pcnt);
+
+        if (pcnt < 1) return 1;
+
+        for (j = 0; j < pcnt; j++)
+
+        {
+
+            fscanf(f, "%d", &cnt);
+
+            if (cnt < 1) return err_bad_parm;
+
+            p = NULL;
+
+            for (i = 0; i < cnt; i++)
+
+            {
+
+                if ( (cntr = LoadPLINE(f)) == NULL)
+
+                    return err_bad_parm;
+
+                if ( (cntr->Flags & PLF_ORIENT) != (unsigned int)(i ? PLF_INV : PLF_DIR) )
+
+                    poly_InvContour(cntr);
+
+                if (p == NULL) p = poly_Create();
+
+                if (p == NULL) return 1;
+
+                poly_InclContour(p, cntr);
+
+                cntr = NULL;
+
+                if (!poly_Valid(p)) return err_bad_parm;
+
+            }
+
+            poly_M_Incl(&area, p);
+
+        }
+
+        if (poly_AddMap(m, area, label))
+
+            return 1;
+
+    }
+
+    fclose(f);
+
+    return 0;
+
+} /* LoadPOLYMAP */
+
+
+
+static
+
+void SavePLINE(FILE * f, PLINE * res)
+
+{
+
+    VNODE *cur;
+
+
+
+    fprintf(f, "%d\n", res->Count);
+
+    cur = &res->head;
+
+    do {
+
+        fprintf(f, "%f %f\n", cur->point[0], cur->point[1] );
+
+    } while ( ( cur = cur->next ) != &res->head );
+
+} /* SavePLINE */
+
+
+
+
+
+void SavePOLYMAP(POLYMAP *m, char *fname)
+
+{
+
+    POLYMAP *mi;
+
+    int     i;
+
+    FILE *f = fopen(fname, "w");
+
+    if (f == NULL) return;
+
+    for (mi = m, i = 0; mi != NULL; mi = mi->next)
+
+        i++;
+
+    fprintf(f, "%d\n", i);
+
+    for (mi = m; mi != NULL; mi = mi->next)
+
+    {
+
+        PLINE *cntr;
+
+        POLYAREA * curpa;
+
+
+
+        i = 0, curpa = mi->area;
+
+        do {
+
+            i++;
+
+        } while ( (curpa = curpa->f) != mi->area);
+
+
+
+        fprintf(f, "%s\n", mi->label);
+
+        fprintf(f, "%d\n", i);
+
+        curpa = mi->area; 
+
+        do {
+
+            for (cntr = curpa->contours, i = 0; cntr != NULL; cntr = cntr->next)
+
+                i++;
+
+            fprintf(f, "%d\n", i);
+
+            for (cntr = curpa->contours; cntr != NULL; cntr = cntr->next)
+
+                SavePLINE(f, cntr);
+
+        }  while ((curpa = curpa->f) != mi->area);
+
+    }
+
+} /* SavePOLYMAP */
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/libpolyclip/polyio.h b/Utilities/OSSIM/ossim_core/libpolyclip/polyio.h
new file mode 100644
index 0000000000..88c40c6117
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/libpolyclip/polyio.h
@@ -0,0 +1,40 @@
+/*
+      poly_Boolean: a polygon clip library
+      Copyright (C) 1997  Alexey Nikitin, Michael Leonov
+      leonov@propro.iis.nsk.su
+
+      This library is free software; you can redistribute it and/or
+      modify it under the terms of the GNU Library General Public
+      License as published by the Free Software Foundation; either
+      version 2 of the License, or (at your option) any later version.
+
+      This library is distributed in the hope that it will be useful,
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      Library General Public License for more details.
+
+      You should have received a copy of the GNU Library General Public
+      License along with this library; if not, write to the Free
+      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+      polyio.h
+      (C) 1997 Michael Leonov
+
+*/
+#ifndef _POLYIO_H
+#define _POLYIO_H
+
+#include "polyarea.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int LoadPOLYAREA( POLYAREA **PA, char * fname);
+int SavePOLYAREA( POLYAREA * PA, char * fname);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/libpolyclip/vectmatr.c b/Utilities/OSSIM/ossim_core/libpolyclip/vectmatr.c
new file mode 100644
index 0000000000..72ad959969
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/libpolyclip/vectmatr.c
@@ -0,0 +1,823 @@
+/*
+
+      poly_Boolean: a polygon clip library
+
+      Copyright (C) 1997  Alexey Nikitin, Michael Leonov
+
+      leonov@propro.iis.nsk.su
+
+
+
+  based on:
+
+      graphadd.cc: a polygon clip library
+
+      Copyright (C) 1993  Klamer Schutte
+
+
+
+      This library is free software; you can redistribute it and or
+
+      modify it under the terms of the GNU Library General Public
+
+      License as published by the Free Software Foundation; either
+
+      version 2 of the License, or (at your option) any later version.
+
+
+
+      This library is distributed in the hope that it will be useful,
+
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+
+      Library General Public License for more details.
+
+
+
+      You should have received a copy of the GNU Library General Public
+
+      License along with this library; if not, write to the Free
+
+      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+      vectmatr.c
+
+      (C) 1997 Alexey Nikitin, Michael Leonov
+
+      (C) 1993,1997 Klamer Schutte
+
+
+
+      all cases where original (Klamer Schutte) code is present
+
+      are marked
+
+*/
+
+
+
+#include <stdlib.h>
+
+#include <math.h>
+
+#include <assert.h>
+
+
+
+#include "vectmatr.h"
+
+
+
+#ifndef min
+
+double
+
+min(double x, double y)
+
+{
+
+    if (x > y)
+
+        return y;
+
+    return x;
+
+}
+
+#endif
+
+
+
+#ifndef max
+
+double
+
+max(double x, double y)
+
+{
+
+    if (y > x)
+
+        return y;
+
+    return x;
+
+} 
+
+#endif
+
+
+
+Vector vect_zero = { (double)0, (double)0, (double)0 };
+
+
+
+/*********************************************************************/
+
+/*            F l o a t   V e c t o r   S t u f f                    */
+
+/*********************************************************************/
+
+
+
+void vect_init ( Vector v, double x, double y, double z )
+
+{
+
+    v[0] = (double)x;
+
+    v[1] = (double)y;
+
+    v[2] = (double)z;
+
+} /* vect_init */
+
+
+
+#define Vcopy(a,b) {(a)[0]=(b)[0];(a)[1]=(b)[1];(a)[2]=(b)[2];}
+
+#define Vzero(a)   ((a)[0] == 0. && (a)[1] == 0. && (a)[2] == 0.)
+
+
+
+#define Vsub(a,b,c) {(a)[0]=(b)[0]-(c)[0];(a)[1]=(b)[1]-(c)[1];(a)[2]=(b)[2]-(c)[2];}
+
+
+
+void vect_copy ( Vector des, Vector sou ) { Vcopy( des, sou ) } /* vect_copy */
+
+int vect_equal ( Vector v1, Vector v2 )
+
+{
+
+    return ( v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2] );
+
+} /* vect_equal */
+
+
+
+
+
+void vect_sub ( Vector res, Vector v1, Vector v2 ) { Vsub( res, v1, v2 ) } /* vect_sub */
+
+
+
+void vect_min ( Vector v1, Vector v2, Vector v3 )
+
+{
+
+    v1[0] = (v2[0] < v3[0]) ? v2[0] : v3[0];
+
+    v1[1] = (v2[1] < v3[1]) ? v2[1] : v3[1];
+
+    v1[2] = (v2[2] < v3[2]) ? v2[2] : v3[2];
+
+} /* vect_min */
+
+
+
+void vect_max ( Vector v1, Vector v2, Vector v3 )
+
+{
+
+    v1[0] = (v2[0] > v3[0]) ? v2[0] : v3[0];
+
+    v1[1] = (v2[1] > v3[1]) ? v2[1] : v3[1];
+
+    v1[2] = (v2[2] > v3[2]) ? v2[2] : v3[2];
+
+} /* vect_max */
+
+
+
+/* ///////////////////////////////////////////////////////////////////////////// * /
+
+/ *  2-Dimentional stuff
+
+/ * ///////////////////////////////////////////////////////////////////////////// */
+
+
+
+
+
+#define Vsub2(r,a,b)	{(r)[0] = (a)[0] - (b)[0]; (r)[1] = (a)[1] - (b)[1];}
+
+#define Vadd2(r,a,b)	{(r)[0] = (a)[0] + (b)[0]; (r)[1] = (a)[1] + (b)[1];}
+
+#define Vsca2(r,a,s)	{(r)[0] = (a)[0] * (s); (r)[1] = (a)[1] * (s);}
+
+#define Vcpy2(r,a)		{(r)[0] = (a)[0]; (r)[1] = (a)[1];}
+
+#define Vequ2(a,b)		((a)[0] == (b)[0] && (a)[1] == (b)[1])
+
+
+
+#define Vadds(r,a,b,s)	{(r)[0] = ((a)[0] + (b)[0]) * (s); (r)[1] = ((a)[1] + (b)[1]) * (s);}
+
+
+
+#define Vswp2(a,b) { double t; \
+t = (a)[0], (a)[0] = (b)[0], (b)[0] = t; \
+t = (a)[1], (a)[1] = (b)[1], (b)[1] = t; \
+}
+
+
+
+double vect_len2(Vector v)
+
+{
+
+    return sqrt(v[0] * v[0] + v[1] * v[1]);
+
+}
+
+
+
+double vect_dist2(Vector v1, Vector v2)
+
+{
+
+	double dx = v1[0] - v2[0];
+
+	double dy = v1[1] - v2[1];
+
+
+
+    return sqrt(dx * dx + dy * dy);
+
+}
+
+
+
+double vect_det2(Vector v1, Vector v2)
+
+{
+
+    return ((v1[0] * v2[1]) - (v2[0] * v1[1]));
+
+}
+
+
+
+static
+
+double vect_m_dist(Vector v1, Vector v2)
+
+{
+
+	double dx = v1[0] - v2[0];
+
+	double dy = v1[1] - v2[1];
+
+    double dd = sqrt(dx * dx + dy * dy);
+
+	
+
+    if (dx > 0)  
+
+        return +dd;
+
+    if (dx < 0)
+
+        return -dd;
+
+    if (dy > 0)
+
+        return +dd;
+
+    return -dd;
+
+} /* vect_m_dist */
+
+
+
+/*
+
+RecursiveIsect
+
+ (C) 1993 Klamer Schutte
+
+ (C) 1997 Michael Leonov, Alexey Nikitin
+
+*/
+
+
+
+
+
+static 
+
+void RecursiveIsect(Vector p1, Vector p2, Vector q1, Vector q2, Vector ret)
+
+{
+
+    /* Find intersection point of p1-p2 and q1-q2 by iteratively taking
+
+       the middle of p1-p2 */
+
+
+
+    Vector q, s1, s2, m, tmp;
+
+    double inp;
+
+
+
+    Vsub2(q, q2, q1);
+
+
+
+    if (vect_len2(q) < vect_dist2(p2, p1))
+
+    {
+
+        RecursiveIsect(q1, q2, p1, p2, ret);
+
+        return;
+
+    }
+
+
+
+    Vsub2(s1, p1, q1);
+
+    Vsub2(s2, p2, q1);
+
+    Vadds(m, s1, s2, 0.5f);
+
+
+
+    inp = vect_det2(q, s1);
+
+
+
+    if (inp > 0)
+
+    {
+
+        Vcpy2(tmp, s1);
+
+        Vcpy2(s1, s2);
+
+        Vcpy2(s2, tmp);
+
+    }
+
+
+
+    while (!Vequ2(m, s1) && !Vequ2(m, s2))
+
+    {
+
+/*         assert(vect_det2(q, s1) <= 0); */
+
+/*         assert(vect_det2(q, s2) >= 0); */
+
+/*          if(vect_det2(q, s1) > 0) */
+/*          { */
+/*             break; */
+/*          } */
+
+/*          if(vect_det2(q, s2) > 0) */
+/*          { */
+/*             break; */
+/*          } */
+
+
+
+        if (vect_det2(q, m) <= 0)
+
+            Vcpy2(s1, m)
+
+        else
+
+            Vcpy2(s2, m)
+
+
+
+        Vadds(m, s1, s2, 0.5f);
+
+    }
+
+/*    assert(vect_len2(m) <= vect_dist2(q2, q1)); */
+
+
+
+    Vadd2(ret, m, q1);
+
+} /* RecursiveIsect */
+
+
+
+/*
+
+vect_inters2
+
+ (C) 1993 Klamer Schutte
+
+ (C) 1997 Michael Leonov, Alexey Nikitin
+
+*/
+
+
+
+int vect_inters2(Vector p1, Vector p2, Vector q1, Vector q2, 
+
+				 Vector S1, Vector S2)
+
+{
+
+    double rpx, rpy, rqx, rqy, t, deel;
+
+    Vector p, pq1, pq2, q, qp1, qp2, s, qs;
+
+	int c1, c2, c1s, c2s;
+
+
+
+    if (max(p1[0], p2[0]) < min(q1[0], q2[0]) ||
+
+		max(q1[0], q2[0]) < min(p1[0], p2[0]))
+
+        return 0;
+
+
+
+    S1[2] = S2[2] = 0.0F;
+
+    rpx = p2[0] - p1[0];
+
+    rpy = p2[1] - p1[1];
+
+    rqx = q2[0] - q1[0];
+
+    rqy = q2[1] - q1[1];
+
+
+
+    deel = rpx * rqy - rpy * rqx; /* vect_det(rp,rq); */
+
+
+
+	/* every value below EPSILON is considered as being 0. 
+
+	 * Hence, we do not introduce numerical inaccuracies
+
+	 */
+
+
+
+    if (fabs(deel) < EPSILON) /* parallel */
+
+    {
+
+		double inpr, dc1, dc2, d1, d2, h;	/* Check too see whether p1-p2 and q1-q2 are on the same line */
+
+	    Vector hp1, hq1, hp2, hq2, q1p1, q1q2;
+
+
+
+        Vsub2(q1p1, q1, p1);
+
+        Vsub2(q1q2, q1, q2);
+
+
+
+        inpr = vect_det2(q1p1, q1q2);
+
+
+
+        /* If this product is not zero then p1 is not on q1-q2! */
+
+        if (fabs(inpr) > EPSILON)
+
+            return 0;
+
+        dc1 = 0;  /* m_len(p1 - p1) */
+
+
+
+        dc2 = vect_m_dist(p1, p2);
+
+        d1 = vect_m_dist(p1, q1);
+
+        d2 = vect_m_dist(p1, q2);
+
+
+
+/* Sorting the independent points from small to large: */
+
+        Vcpy2(hp1, p1);
+
+        Vcpy2(hp2, p2);
+
+        Vcpy2(hq1, q1);
+
+        Vcpy2(hq2, q2);
+
+        if (dc1 > dc2)
+
+        { /* hv and h are used as help-variable. */
+
+            Vswp2(hp1, hp2);
+
+            h = dc1, dc1 = dc2, dc2 = h;
+
+        }
+
+        if (d1 > d2)
+
+        {
+
+            Vswp2(hq1, hq2);
+
+            h = d1, d1 = d2, d2 = h;
+
+        }
+
+
+
+/* Now the line-pieces are compared: */
+
+
+
+        if (dc1 < d1)
+
+        {
+
+            if (dc2 < d1)
+
+                return 0;
+
+            if (dc2 < d2)	{ Vcpy2(S1, hp2); Vcpy2(S2, hq1); }
+
+            else			{ Vcpy2(S1, hq1); Vcpy2(S2, hq2); };
+
+        }
+
+        else
+
+        {
+
+            if (dc1 > d2)
+
+                return 0;
+
+            if (dc2 < d2)	{ Vcpy2(S1, hp1); Vcpy2(S2, hp2); }
+
+            else			{ Vcpy2(S1, hp1); Vcpy2(S2, hq2); };
+
+        }
+
+        return (Vequ2(S1, S2) ? 1 : 2);
+
+    }
+
+    else
+
+    {  /* not parallel */
+
+		/*
+
+		 * We have the lines:
+
+		 * l1: p1 + s(p2 - p1)
+
+		 * l2: q1 + t(q2 - q1)
+
+		 * And we want to know the intersection point.
+
+		 * Calculate t:
+
+		 * p1 + s(p2-p1) = q1 + t(q2-q1)
+
+		 * which is similar to the two equations:
+
+		 * p1x + s * rpx = q1x + t * rqx
+
+		 * p1y + s * rpy = q1y + t * rqy
+
+		 * Multiplying these by rpy resp. rpx gives:
+
+		 * rpy * p1x + s * rpx * rpy = rpy * q1x + t * rpy * rqx
+
+		 * rpx * p1y + s * rpx * rpy = rpx * q1y + t * rpx * rqy
+
+		 * Subtracting these gives:
+
+		 * rpy * p1x - rpx * p1y = rpy * q1x - rpx * q1y + t * ( rpy * rqx - rpx * rqy )
+
+		 * So t can be isolated:
+
+		 * t = (rpy * ( p1x - q1x ) + rpx * ( - p1y + q1y )) / ( rpy * rqx - rpx * rqy )
+
+		 * and deel = rpx * rqy - rpy * rqx
+
+		 */
+
+		double inp1, inp2, inp3, inp4, inp1s, inp2s, inp3s, inp4s;
+
+
+
+
+
+        if (Vequ2(q1, p1) || Vequ2(q1, p2)) Vcpy2(S1, q1) else 
+
+		if (Vequ2(q2, p1) || Vequ2(q2, p2)) Vcpy2(S1, q2) else
+
+        {
+
+            t = -(rpy * (-q1[0] + p1[0]) + rpx * (q1[1] - p1[1])) / deel;
+
+            S1[0] = (double) (q1[0] + t * rqx);
+
+            S1[1] = (double) (q1[1] + t * rqy);
+
+        }
+
+/*
+
+ * The intersection point is valid if it is
+
+ * 1) on q1-q2 --> t >= 0 && t <= 1
+
+ * 2) on p1-p2 --> p1 must be on the other side of q1-q2 as p2
+
+ *    This is so if the difference of the x coordinate of p1-s1 has the
+
+ *    opposite sign as the x coordinate of p2-s2. So the multiplication of
+
+ *    these two must be negative. This might fail if p1-p2 is a vertical line;
+
+ *    this can be solved by adding the same product for the y coordinates
+
+ */
+
+        Vsub2(p, p2, p1);
+
+        Vsub2(pq1, q1, p1);
+
+        Vsub2(pq2, q2, p1);
+
+        inp1 = vect_det2(p, pq1);
+
+        inp2 = vect_det2(p, pq2);
+
+        c1 = inp1 * inp2 <= 0;
+
+
+
+        Vsub2(q, q2, q1);
+
+        Vsub2(qp1, p1, q1);
+
+        Vsub2(qp2, p2, q1);
+
+
+
+        inp3 = vect_det2(q, qp1);
+
+        inp4 = vect_det2(q, qp2);
+
+        c2 = inp3 * inp4 <= 0;
+
+
+
+        {
+
+			double l_q, l_p;
+
+            /* Say that *S1 equals one of the points if the relative
+
+               distance is smaller than EPSILON */
+
+            l_q = vect_dist2(q1, q2);
+
+            l_p = vect_dist2(p1, p2);
+
+            if (EPSILON > vect_dist2(S1, p2) / l_p)
+
+            {
+
+                *S1 = *p2;
+
+                c2 = 2;
+
+            }
+
+            else if (EPSILON > vect_dist2(S1, p1) / l_p)
+
+            {
+
+                *S1 = *p1;
+
+                c2 = 2;
+
+            }
+
+            else
+
+            {
+
+                if (EPSILON > vect_dist2(S1, q2) / l_q)
+
+                {
+
+                    *S1 = *q2;
+
+                    c1 = 2;
+
+                }
+
+                else if (EPSILON > vect_dist2(S1, q1) / l_q)
+
+                {
+
+                    *S1 = *q1;
+
+                    c1 = 2;
+
+                }
+
+            }
+
+        }
+
+        Vsub2(s, S1, p1);
+
+        inp1s = vect_det2(s, pq1);
+
+        inp2s = vect_det2(s, pq2);
+
+        c1s = Vequ2(S1, p1) ? -1 : inp1s * inp2s <= 0;
+
+
+
+        Vsub2(qs, S1, q1);
+
+        inp3s = vect_det2(qs, qp1);
+
+        inp4s = vect_det2(qs, qp2);
+
+        c2s = Vequ2(S1, q1) ? -1 : inp3s * inp4s <= 0;
+
+		{
+
+			int failed = 0; /* Roundig errors might make the statements below untrue */
+
+
+
+			if (!((c1 == 0) || (c2 == 0) || (c1s == (c1 != 0)) || (c1s == -1)))
+
+				failed = 1;
+
+			else if (!((c1 == 0) || (c2 == 0) || (c2s == (c2 != 0)) || (c2s == -1)))
+
+				failed = 2;
+
+			else if (c1 && c2 && (vect_dist2(S1, q1) > vect_dist2(q2, q1)))
+
+				failed = 3;
+
+			else if (c1 && c2 && (vect_dist2(S1, q2) > vect_dist2(q2, q1)))
+
+				failed = 4;
+
+			else if (c1 && c2 && (vect_dist2(S1, p1) > vect_dist2(p2, p1)))
+
+				failed = 5;
+
+			else if (c1 && c2 && (vect_dist2(S1, p2) > vect_dist2(p2, p1)))
+
+				failed = 6;
+
+			if ((failed >= 3) && (c1 == 2 || c2 == 2))
+
+			{
+
+				failed = -1;
+
+				c1 = c2 = 0;
+
+			}
+
+			if (failed > 0)
+
+				RecursiveIsect(p1, p2, q1, q2, S1);
+
+			return (c1 && c2);
+
+		}
+
+    }
+
+} /* vect_inters2 */
+
+
+
+/* end of VECTMATR.C */
+
diff --git a/Utilities/OSSIM/ossim_core/libpolyclip/vectmatr.h b/Utilities/OSSIM/ossim_core/libpolyclip/vectmatr.h
new file mode 100644
index 0000000000..2a44356da2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/libpolyclip/vectmatr.h
@@ -0,0 +1,190 @@
+/*
+
+      poly_Boolean: a polygon clip library
+
+      Copyright (C) 1997  Alexey Nikitin, Michael Leonov
+
+      leonov@propro.iis.nsk.su
+
+
+
+      This library is free software; you can redistribute it and or
+
+      modify it under the terms of the GNU Library General Public
+
+      License as published by the Free Software Foundation; either
+
+      version 2 of the License, or (at your option) any later version.
+
+
+
+      This library is distributed in the hope that it will be useful,
+
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+
+      Library General Public License for more details.
+
+
+
+      You should have received a copy of the GNU Library General Public
+
+      License along with this library; if not, write to the Free
+
+      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+      vectmatr.h
+
+      (C) 1997 Alexey Nikitin, Michael Leonov
+
+      (C) 1993,1997 Klamer Schutte
+
+
+
+*/
+
+
+
+#ifndef VECTOR_MATRIX_H
+
+#define VECTOR_MATRIX_H
+
+
+
+
+
+#ifdef __cplusplus
+
+extern "C" {
+
+#endif
+
+
+
+typedef int		BOOL;
+
+
+
+#ifndef FALSE
+
+enum {
+
+	FALSE = 0,
+
+	TRUE  = 1
+
+};
+
+#endif
+
+
+
+#ifndef min
+
+double min(double x, double y);
+
+#endif
+
+
+
+#ifndef max
+
+double max(double x, double y);
+
+#endif
+
+
+
+
+
+typedef double vertex[3];  /* floating point representation of
+
+                             coordinates */
+
+typedef vertex Vector;
+
+
+
+#define VertexEqu(a,b) (memcmp((a),(b),sizeof(Vector))==0)
+
+#define VertexCpy(a,b) memcpy((a),(b),sizeof(Vector))
+
+
+
+
+
+extern Vector vect_zero;
+
+
+
+/*********************************************************************/
+
+/*            F l o a t   V e c t o r   S t u f f                    */
+
+/*********************************************************************/
+
+
+
+int    vect_equal ( Vector v1, Vector v2 );
+
+void   vect_copy ( Vector des, Vector sou );
+
+void   vect_init ( Vector v, double x, double y, double z);
+
+void   vect_sub( Vector res, Vector v2, Vector v3 );
+
+
+
+void   vect_min( Vector res, Vector v2, Vector v3 );
+
+void   vect_max( Vector res, Vector v2, Vector v3 );
+
+
+
+#define TNY 1e-6
+
+
+
+#ifndef EPSILON
+
+#define EPSILON TNY
+
+#endif
+
+
+
+double vect_dist2(Vector v1, Vector v2);
+
+double vect_det2(Vector v1, Vector v2);
+
+double vect_len2(Vector v1);
+
+
+
+int vect_inters2(Vector A, Vector B, Vector C, Vector D, Vector S1, Vector S2);
+
+
+
+/****************************************************************************
+
+* Calcs the intersection point of AB and BC. Returns if they hit each other 
+
+* and the position of the hit(s) (S1 (and S2))
+
+*****************************************************************************/
+
+
+
+#ifdef __cplusplus
+
+}
+
+#endif
+
+
+
+#endif /* VECTOR_MATRIX_H */
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/.cvsignore b/Utilities/OSSIM/ossim_core/matrix/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/matrix/CMakeLists.txt b/Utilities/OSSIM/ossim_core/matrix/CMakeLists.txt
new file mode 100644
index 0000000000..4291125170
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_matrix_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_matrix_HDRS "*.h")
+ADD_LIBRARY(ossim_matrix ${ossim_matrix_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_matrix)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_matrix_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/matrix/bandmat.cpp b/Utilities/OSSIM/ossim_core/matrix/bandmat.cpp
new file mode 100644
index 0000000000..22ef71395d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/bandmat.cpp
@@ -0,0 +1,569 @@
+//$$ bandmat.cpp                     Band matrix definitions
+
+// Copyright (C) 1991,2,3,4,9: R B Davies
+
+#define WANT_MATH                    // include.h will get math fns
+
+//#define WANT_STREAM
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrc.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,10); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+static inline int my_min(int x, int y) { return x < y ? x : y; }
+static inline int my_max(int x, int y) { return x > y ? x : y; }
+
+
+BandMatrix::BandMatrix(const BaseMatrix& M)
+{
+   REPORT // CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::BM);
+   GetMatrix(gmx); CornerClear();
+}
+
+void BandMatrix::SetParameters(const GeneralMatrix* gmx)
+{
+   REPORT
+   MatrixBandWidth bw = gmx->BandWidth();
+   lower = bw.lower; upper = bw.upper;
+}
+
+void BandMatrix::ReSize(int n, int lb, int ub)
+{
+   REPORT
+   Tracer tr("BandMatrix::ReSize");
+   if (lb<0 || ub<0) Throw(ProgramException("Undefined bandwidth"));
+   lower = (lb<=n) ? lb : n-1; upper = (ub<=n) ? ub : n-1;
+   GeneralMatrix::ReSize(n,n,n*(lower+1+upper)); CornerClear();
+}
+
+// SimpleAddOK shows when we can add etc two matrices by a simple vector add
+// and when we can add one matrix into another
+// *gm must be the same type as *this
+// return 0 if simple add is OK
+// return 1 if we can add into *gm only
+// return 2 if we can add into *this only
+// return 3 if we can't add either way
+// For SP this will still be valid if we swap 1 and 2
+
+short BandMatrix::SimpleAddOK(const GeneralMatrix* gm)
+{
+   const BandMatrix* bm = (const BandMatrix*)gm;
+   if (bm->lower == lower && bm->upper == upper) { REPORT return 0; }
+   else if (bm->lower >= lower && bm->upper >= upper) { REPORT return 1; }
+   else if (bm->lower <= lower && bm->upper <= upper) { REPORT return 2; }
+   else { REPORT return 3; }
+}
+
+short SymmetricBandMatrix::SimpleAddOK(const GeneralMatrix* gm)
+{
+   const SymmetricBandMatrix* bm = (const SymmetricBandMatrix*)gm;
+   if (bm->lower == lower) { REPORT return 0; }
+   else if (bm->lower > lower) { REPORT return 1; }
+   else { REPORT return 2; }
+}
+
+void UpperBandMatrix::ReSize(int n, int lb, int ub)
+{
+   REPORT
+   if (lb != 0)
+   {
+      Tracer tr("UpperBandMatrix::ReSize");
+      Throw(ProgramException("UpperBandMatrix with non-zero lower band" ));
+   }
+   BandMatrix::ReSize(n, lb, ub);
+}
+
+void LowerBandMatrix::ReSize(int n, int lb, int ub)
+{
+   REPORT
+   if (ub != 0)
+   {
+      Tracer tr("LowerBandMatrix::ReSize");
+      Throw(ProgramException("LowerBandMatrix with non-zero upper band" ));
+   }
+   BandMatrix::ReSize(n, lb, ub);
+}
+
+void BandMatrix::ReSize(const GeneralMatrix& A)
+{
+   REPORT
+   int n = A.Nrows();
+   if (n != A.Ncols())
+   {
+      Tracer tr("BandMatrix::ReSize(GM)");
+      Throw(NotSquareException(*this));
+   }
+   MatrixBandWidth mbw = A.BandWidth();
+   ReSize(n, mbw.Lower(), mbw.Upper());
+}
+
+bool BandMatrix::SameStorageType(const GeneralMatrix& A) const
+{
+   if (Type() != A.Type()) { REPORT return false; }
+   REPORT
+   return BandWidth() == A.BandWidth();
+}
+
+void BandMatrix::ReSizeForAdd(const GeneralMatrix& A, const GeneralMatrix& B)
+{
+   REPORT
+   Tracer tr("BandMatrix::ReSizeForAdd");
+   MatrixBandWidth A_BW = A.BandWidth(); MatrixBandWidth B_BW = B.BandWidth();
+   if ((A_BW.Lower() < 0) | (A_BW.Upper() < 0) | (B_BW.Lower() < 0)
+      | (A_BW.Upper() < 0))
+         Throw(ProgramException("Can't ReSize to BandMatrix" ));
+   // already know A and B are square
+   ReSize(A.Nrows(), my_max(A_BW.Lower(), B_BW.Lower()),
+      my_max(A_BW.Upper(), B_BW.Upper()));
+}
+
+void BandMatrix::ReSizeForSP(const GeneralMatrix& A, const GeneralMatrix& B)
+{
+   REPORT
+   Tracer tr("BandMatrix::ReSizeForSP");
+   MatrixBandWidth A_BW = A.BandWidth(); MatrixBandWidth B_BW = B.BandWidth();
+   if ((A_BW.Lower() < 0) | (A_BW.Upper() < 0) | (B_BW.Lower() < 0)
+      | (A_BW.Upper() < 0))
+         Throw(ProgramException("Can't ReSize to BandMatrix" ));
+   // already know A and B are square
+   ReSize(A.Nrows(), my_min(A_BW.Lower(), B_BW.Lower()),
+      my_min(A_BW.Upper(), B_BW.Upper()));
+}
+
+
+void BandMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT // CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::BM); CornerClear();
+}
+
+void BandMatrix::CornerClear() const
+{
+   // set unused parts of BandMatrix to zero
+   REPORT
+   int i = lower; Real* s = store; int bw = lower + 1 + upper;
+   while (i)
+      { int j = i--; Real* sj = s; s += bw; while (j--) *sj++ = 0.0; }
+   i = upper; s = store + storage;
+   while (i)
+      { int j = i--; Real* sj = s; s -= bw; while (j--) *(--sj) = 0.0; }
+}
+
+MatrixBandWidth MatrixBandWidth::operator+(const MatrixBandWidth& bw) const
+{
+   REPORT
+   int l = bw.lower; int u = bw.upper;
+   l = (lower < 0 || l < 0) ? -1 : (lower > l) ? lower : l;
+   u = (upper < 0 || u < 0) ? -1 : (upper > u) ? upper : u;
+   return MatrixBandWidth(l,u);
+}
+
+MatrixBandWidth MatrixBandWidth::operator*(const MatrixBandWidth& bw) const
+{
+   REPORT
+   int l = bw.lower; int u = bw.upper;
+   l = (lower < 0 || l < 0) ? -1 : lower+l;
+   u = (upper < 0 || u < 0) ? -1 : upper+u;
+   return MatrixBandWidth(l,u);
+}
+
+MatrixBandWidth MatrixBandWidth::minimum(const MatrixBandWidth& bw) const
+{
+   REPORT
+   int l = bw.lower; int u = bw.upper;
+   if ((lower >= 0) && ( (l < 0) || (l > lower) )) l = lower;
+   if ((upper >= 0) && ( (u < 0) || (u > upper) )) u = upper;
+   return MatrixBandWidth(l,u);
+}
+
+UpperBandMatrix::UpperBandMatrix(const BaseMatrix& M)
+{
+   REPORT // CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UB);
+   GetMatrix(gmx); CornerClear();
+}
+
+void UpperBandMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT // CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::UB); CornerClear();
+}
+
+LowerBandMatrix::LowerBandMatrix(const BaseMatrix& M)
+{
+   REPORT // CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LB);
+   GetMatrix(gmx); CornerClear();
+}
+
+void LowerBandMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT // CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::LB); CornerClear();
+}
+
+BandLUMatrix::BandLUMatrix(const BaseMatrix& m)
+{
+   REPORT
+   Tracer tr("BandLUMatrix");
+   storage2 = 0; store2 = 0;  // in event of exception during build
+   GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate(MatrixType::BM);
+   m1 = ((BandMatrix*)gm)->lower; m2 = ((BandMatrix*)gm)->upper;
+   GetMatrix(gm);
+   if (nrows!=ncols) Throw(NotSquareException(*this));
+   d = true; sing = false;
+   indx = new int [nrows]; MatrixErrorNoSpace(indx);
+   MONITOR_INT_NEW("Index (BndLUMat)",nrows,indx)
+   storage2 = nrows * m1;
+   store2 = new Real [storage2]; MatrixErrorNoSpace(store2);
+   MONITOR_REAL_NEW("Make (BandLUMat)",storage2,store2)
+   ludcmp();
+}
+
+BandLUMatrix::~BandLUMatrix()
+{
+   REPORT
+   MONITOR_INT_DELETE("Index (BndLUMat)",nrows,indx)
+   MONITOR_REAL_DELETE("Delete (BndLUMt)",storage2,store2)
+   delete [] indx; delete [] store2;
+}
+
+MatrixType BandLUMatrix::Type() const { REPORT return MatrixType::BC; }
+
+
+LogAndSign BandLUMatrix::LogDeterminant() const
+{
+   REPORT
+   if (sing) return 0.0;
+   Real* a = store; int w = m1+1+m2; LogAndSign sum; int i = nrows;
+   // while (i--) { sum *= *a; a += w; }
+   if (i) for (;;) { sum *= *a; if (!(--i)) break; a += w; }
+   if (!d) sum.ChangeSign(); return sum;
+}
+
+GeneralMatrix* BandMatrix::MakeSolver()
+{
+   REPORT
+   GeneralMatrix* gm = new BandLUMatrix(*this);
+   MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
+}
+
+
+void BandLUMatrix::ludcmp()
+{
+   REPORT
+   Real* a = store2; int i = storage2;
+   // clear store2 - so unused locations are always zero -
+   // required by operator==
+   while (i--) *a++ = 0.0;
+   a = store;
+   i = m1; int j = m2; int k; int n = nrows; int w = m1 + 1 + m2;
+   while (i)
+   {
+      Real* ai = a + i;
+      k = ++j; while (k--) *a++ = *ai++;
+      k = i--; while (k--) *a++ = 0.0;
+   }
+
+   a = store; int l = m1;
+   for (k=0; k<n; k++)
+   {
+      Real x = *a; i = k; Real* aj = a;
+      if (l < n) l++;
+      for (j=k+1; j<l; j++)
+         { aj += w; if (fabs(x) < fabs(*aj)) { x = *aj; i = j; } }
+      indx[k] = i;
+      if (x==0) { sing = true; return; }
+      if (i!=k)
+      {
+         d = !d; Real* ak = a; Real* ai = store + i * w; j = w;
+         while (j--) { x = *ak; *ak++ = *ai; *ai++ = x; }
+      }
+      aj = a + w; Real* m = store2 + m1 * k;
+      for (j=k+1; j<l; j++)
+      {
+         *m++ = x = *aj / *a; i = w; Real* ak = a;
+	 while (--i) { Real* aj1 = aj++; *aj1 = *aj - x * *(++ak); }
+         *aj++ = 0.0;
+      }
+      a += w;
+   }
+}
+
+void BandLUMatrix::lubksb(Real* B, int mini)
+{
+   REPORT
+   Tracer tr("BandLUMatrix::lubksb");
+   if (sing) Throw(SingularException(*this));
+   int n = nrows; int l = m1; int w = m1 + 1 + m2;
+
+   for (int k=0; k<n; k++)
+   {
+      int i = indx[k];
+      if (i!=k) { Real x=B[k]; B[k]=B[i]; B[i]=x; }
+      if (l<n) l++;
+      Real* m = store2 + k*m1; Real* b = B+k; Real* bi = b;
+      for (i=k+1; i<l; i++)  *(++bi) -= *m++ * *b;
+   }
+
+   l = -m1;
+   for (int i = n-1; i>=mini; i--)
+   {
+      Real* b = B + i; Real* bk = b; Real x = *bk;
+      Real* a = store + w*i; Real y = *a;
+      int k = l+m1; while (k--) x -=  *(++a) * *(++bk);
+      *b = x / y;
+      if (l < m2) l++;
+   }
+}
+
+void BandLUMatrix::Solver(MatrixColX& mcout, const MatrixColX& mcin)
+{
+   REPORT
+   int i = mcin.skip; Real* el = mcin.data-i; Real* el1=el;
+   while (i--) *el++ = 0.0;
+   el += mcin.storage; i = nrows - mcin.skip - mcin.storage;
+   while (i--) *el++ = 0.0;
+   lubksb(el1, mcout.skip);
+}
+
+// Do we need check for entirely zero output?
+
+
+void UpperBandMatrix::Solver(MatrixColX& mcout,
+   const MatrixColX& mcin)
+{
+   REPORT
+   int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
+   while (i-- > 0) *elx++ = 0.0;
+   int nr = mcin.skip+mcin.storage;
+   elx = mcin.data+mcin.storage; Real* el = elx;
+   int j = mcout.skip+mcout.storage-nr; i = nr-mcout.skip;
+   while (j-- > 0) *elx++ = 0.0;
+
+   Real* Ael = store + (upper+1)*(i-1)+1; j = 0;
+   if (i > 0) for(;;)
+   {
+      elx = el; Real sum = 0.0; int jx = j;
+      while (jx--) sum += *(--Ael) * *(--elx);
+      elx--; *elx = (*elx - sum) / *(--Ael);
+      if (--i <= 0) break;
+      if (j<upper) Ael -= upper - (++j); else el--;
+   }
+}
+
+void LowerBandMatrix::Solver(MatrixColX& mcout,
+   const MatrixColX& mcin)
+{
+   REPORT
+   int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
+   while (i-- > 0) *elx++ = 0.0;
+   int nc = mcin.skip; i = nc+mcin.storage; elx = mcin.data+mcin.storage;
+   int nr = mcout.skip+mcout.storage; int j = nr-i; i = nr-nc;
+   while (j-- > 0) *elx++ = 0.0;
+
+   Real* el = mcin.data; Real* Ael = store + (lower+1)*nc + lower; j = 0;
+   if (i > 0) for(;;)
+   {
+      elx = el; Real sum = 0.0; int jx = j;
+      while (jx--) sum += *Ael++ * *elx++;
+      *elx = (*elx - sum) / *Ael++;
+      if (--i <= 0) break;
+      if (j<lower) Ael += lower - (++j); else el++;
+   }
+}
+
+
+LogAndSign BandMatrix::LogDeterminant() const
+{
+   REPORT
+   BandLUMatrix C(*this); return C.LogDeterminant();
+}
+
+LogAndSign LowerBandMatrix::LogDeterminant() const
+{
+   REPORT
+   int i = nrows; LogAndSign sum; Real* s = store + lower; int j = lower + 1;
+//   while (i--) { sum *= *s; s += j; }
+   if (i) for (;;) { sum *= *s; if (!(--i)) break; s += j; }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+LogAndSign UpperBandMatrix::LogDeterminant() const
+{
+   REPORT
+   int i = nrows; LogAndSign sum; Real* s = store; int j = upper + 1;
+//   while (i--) { sum *= *s; s += j; }
+   if (i) for (;;) { sum *= *s; if (!(--i)) break; s += j; }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+GeneralMatrix* SymmetricBandMatrix::MakeSolver()
+{
+   REPORT
+   GeneralMatrix* gm = new BandLUMatrix(*this);
+   MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
+}
+
+SymmetricBandMatrix::SymmetricBandMatrix(const BaseMatrix& M)
+{
+   REPORT  // CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::SB);
+   GetMatrix(gmx);
+}
+
+GeneralMatrix* SymmetricBandMatrix::Transpose(TransposedMatrix*, MatrixType mt)
+{ REPORT  return Evaluate(mt); }
+
+LogAndSign SymmetricBandMatrix::LogDeterminant() const
+{
+   REPORT
+   BandLUMatrix C(*this); return C.LogDeterminant();
+}
+
+void SymmetricBandMatrix::SetParameters(const GeneralMatrix* gmx)
+{ REPORT lower = gmx->BandWidth().lower; }
+
+void SymmetricBandMatrix::ReSize(int n, int lb)
+{
+   REPORT
+   Tracer tr("SymmetricBandMatrix::ReSize");
+   if (lb<0) Throw(ProgramException("Undefined bandwidth"));
+   lower = (lb<=n) ? lb : n-1;
+   GeneralMatrix::ReSize(n,n,n*(lower+1));
+}
+
+void SymmetricBandMatrix::ReSize(const GeneralMatrix& A)
+{
+   REPORT
+   int n = A.Nrows();
+   if (n != A.Ncols())
+   {
+      Tracer tr("SymmetricBandMatrix::ReSize(GM)");
+      Throw(NotSquareException(*this));
+   }
+   MatrixBandWidth mbw = A.BandWidth(); int b = mbw.Lower();
+   if (b != mbw.Upper())
+   {
+      Tracer tr("SymmetricBandMatrix::ReSize(GM)");
+      Throw(ProgramException("Upper and lower band-widths not equal"));
+   }
+   ReSize(n, b);
+}
+
+bool SymmetricBandMatrix::SameStorageType(const GeneralMatrix& A) const
+{
+   if (Type() != A.Type()) { REPORT return false; }
+   REPORT
+   return BandWidth() == A.BandWidth();
+}
+
+void SymmetricBandMatrix::ReSizeForAdd(const GeneralMatrix& A,
+   const GeneralMatrix& B)
+{
+   REPORT
+   Tracer tr("SymmetricBandMatrix::ReSizeForAdd");
+   MatrixBandWidth A_BW = A.BandWidth(); MatrixBandWidth B_BW = B.BandWidth();
+   if ((A_BW.Lower() < 0) | (B_BW.Lower() < 0))
+         Throw(ProgramException("Can't ReSize to SymmetricBandMatrix" ));
+   // already know A and B are square
+   ReSize(A.Nrows(), my_max(A_BW.Lower(), B_BW.Lower()));
+}
+
+void SymmetricBandMatrix::ReSizeForSP(const GeneralMatrix& A,
+   const GeneralMatrix& B)
+{
+   REPORT
+   Tracer tr("SymmetricBandMatrix::ReSizeForSP");
+   MatrixBandWidth A_BW = A.BandWidth(); MatrixBandWidth B_BW = B.BandWidth();
+   if ((A_BW.Lower() < 0) | (B_BW.Lower() < 0))
+         Throw(ProgramException("Can't ReSize to SymmetricBandMatrix" ));
+   // already know A and B are square
+   ReSize(A.Nrows(), my_min(A_BW.Lower(), B_BW.Lower()));
+}
+
+
+void SymmetricBandMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT // CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::SB);
+}
+
+void SymmetricBandMatrix::CornerClear() const
+{
+   // set unused parts of BandMatrix to zero
+   REPORT
+   int i = lower; Real* s = store; int bw = lower + 1;
+   if (i) for(;;)
+   {
+      int j = i;
+      Real* sj = s;
+      while (j--) *sj++ = 0.0;
+      if (!(--i)) break;
+      s += bw;
+   }
+}
+
+MatrixBandWidth SymmetricBandMatrix::BandWidth() const
+   { REPORT return MatrixBandWidth(lower,lower); }
+
+inline Real square(Real x) { return x*x; }
+
+
+Real SymmetricBandMatrix::SumSquare() const
+{
+   REPORT
+   CornerClear();
+   Real sum1=0.0; Real sum2=0.0; Real* s=store; int i=nrows; int l=lower;
+   while (i--)
+      { int j = l; while (j--) sum2 += square(*s++); sum1 += square(*s++); }
+   ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
+}
+
+Real SymmetricBandMatrix::SumAbsoluteValue() const
+{
+   REPORT
+   CornerClear();
+   Real sum1=0.0; Real sum2=0.0; Real* s=store; int i=nrows; int l=lower;
+   while (i--)
+      { int j = l; while (j--) sum2 += fabs(*s++); sum1 += fabs(*s++); }
+   ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
+}
+
+Real SymmetricBandMatrix::Sum() const
+{
+   REPORT
+   CornerClear();
+   Real sum1=0.0; Real sum2=0.0; Real* s=store; int i=nrows; int l=lower;
+   while (i--)
+      { int j = l; while (j--) sum2 += *s++; sum1 += *s++; }
+   ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
+}
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/bc.mak b/Utilities/OSSIM/ossim_core/matrix/bc.mak
new file mode 100644
index 0000000000..84cf701b3b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/bc.mak
@@ -0,0 +1,202 @@
+.AUTODEPEND
+
+BORLANDPATH = F:\BC5
+
+TASM = TASM
+TLIB = tlib
+TLINK = tlink
+LIBPATH = $(BORLANDPATH)\LIB
+INCLUDEPATH = $(BORLANDPATH)\INCLUDE
+
+CCX = bcc -ml -wpro -weas -wpre -I$(INCLUDEPATH) -D
+
+CC = bcc -W- -v- -H- -x- -3 -N -Og -Oi -Ov -vGd- -vGt- -ml -f -I$(INCLUDEPATH)
+
+everything: tmt.exe example.exe nl_ex.exe sl_ex.exe garch.exe test_exc.exe
+
+
+.cpp.obj:
+   $(CC) -c {$< }
+
+OBJ_LIB = bandmat.obj cholesky.obj evalue.obj fft.obj hholder.obj      \
+   jacobi.obj myexcept.obj newmat1.obj newmat2.obj newmat3.obj         \
+   newmat4.obj newmat5.obj newmat6.obj newmat7.obj newmat8.obj         \
+   newmat9.obj newmatex.obj newmatnl.obj newmatrm.obj solution.obj     \
+   sort.obj submat.obj svd.obj newfft.obj
+
+newmat.lib: $(OBJ_LIB)
+   erase newmat.lib
+   $(TLIB) newmat.lib /P32 +newmat1 +newmat2 +newmat3 +newmat4 +newmat5 +newmat6 
+   $(TLIB) newmat.lib /P32+newmat7 +newmat8 +newmat9 +svd +fft +hholder +sort 
+   $(TLIB) newmat.lib /P32+cholesky +submat +jacobi +evalue +bandmat +myexcept
+   $(TLIB) newmat.lib /P32+solution +newmatnl +newmatrm +newmatex +newfft
+
+OBJ_T = tmt.obj tmt1.obj tmt2.obj tmt3.obj tmt4.obj tmt5.obj tmt6.obj       \
+   tmt7.obj tmt8.obj tmt9.obj tmta.obj tmtb.obj tmtc.obj tmtd.obj tmte.obj  \
+   tmtf.obj tmtg.obj tmth.obj tmti.obj tmtj.obj tmtk.obj tmtl.obj
+
+
+tmt.exe: newmat.lib $(OBJ_T)
+   $(TLINK) /x/L$(LIBPATH) -Tde @&&|
+c0l.obj+tmt.obj+tmt1.obj+tmt2.obj+tmt3.obj+tmt4.obj+tmt5.obj+tmt6.obj+
+   tmt7.obj+tmt8.obj+tmt9.obj+tmta.obj+tmtb.obj+tmtc.obj+tmtd.obj+tmte.obj+
+   tmtf.obj+tmtg.obj+tmth.obj+tmti.obj+tmtj.obj+tmtk.obj+tmtl.obj+newmat.lib
+   tmt
+      # no map file
+   bidsl.lib+emu.lib+mathl.lib+cl.lib
+
+|
+
+
+example.exe: newmat.lib example.obj
+   $(TLINK) /x/L$(LIBPATH) -Tde @&&|
+c0l.obj+example.obj+newmat.lib
+   example
+      # no map file
+   bidsl.lib+emu.lib+mathl.lib+cl.lib
+
+|
+
+
+nl_ex.exe: newmat.lib nl_ex.obj
+   $(TLINK) /x/L$(LIBPATH) -Tde @&&|
+c0l.obj+nl_ex.obj+newmat.lib
+   nl_ex
+      # no map file
+   bidsl.lib+emu.lib+mathl.lib+cl.lib
+
+|
+
+
+sl_ex.exe: newmat.lib sl_ex.obj
+   $(TLINK) /x/L$(LIBPATH) -Tde @&&|
+c0l.obj+sl_ex.obj+newmat.lib
+   sl_ex
+      # no map file
+   bidsl.lib+emu.lib+mathl.lib+cl.lib
+
+|
+
+
+garch.exe: newmat.lib garch.obj
+   $(TLINK) /x/L$(LIBPATH) -Tde @&&|
+c0l.obj+garch.obj+newmat.lib
+   garch
+      # no map file
+   bidsl.lib+emu.lib+mathl.lib+cl.lib
+
+|
+
+test_exc.exe: newmat.lib test_exc.obj
+   $(TLINK) /x/L$(LIBPATH) -Tde @&&|
+c0l.obj+test_exc.obj+newmat.lib
+   test_exc
+      # no map file
+   bidsl.lib+emu.lib+mathl.lib+cl.lib
+
+|
+
+
+bandmat.obj: bandmat.cpp 
+
+cholesky.obj: cholesky.cpp 
+
+evalue.obj: evalue.cpp 
+
+myexcept.obj: myexcept.cpp 
+
+fft.obj: fft.cpp
+
+newfft.obj: newfft.cpp 
+
+hholder.obj: hholder.cpp 
+
+jacobi.obj: jacobi.cpp 
+
+newmat1.obj: newmat1.cpp 
+
+newmat2.obj: newmat2.cpp 
+
+newmat3.obj: newmat3.cpp 
+
+newmat4.obj: newmat4.cpp 
+
+newmat5.obj: newmat5.cpp 
+
+newmat6.obj: newmat6.cpp 
+
+newmat7.obj: newmat7.cpp 
+
+newmat8.obj: newmat8.cpp 
+
+newmat9.obj: newmat9.cpp 
+
+newmatex.obj: newmatex.cpp 
+
+newmatrm.obj: newmatrm.cpp 
+
+newmatnl.obj: newmatnl.cpp 
+
+sort.obj: sort.cpp 
+
+submat.obj: submat.cpp 
+
+svd.obj: svd.cpp 
+
+example.obj: example.cpp 
+
+tmt.obj: tmt.cpp 
+
+tmt1.obj: tmt1.cpp 
+
+tmt2.obj: tmt2.cpp 
+
+tmt3.obj: tmt3.cpp 
+
+tmt4.obj: tmt4.cpp 
+
+tmt5.obj: tmt5.cpp 
+
+tmt6.obj: tmt6.cpp 
+
+tmt7.obj: tmt7.cpp 
+
+tmt8.obj: tmt8.cpp 
+
+tmt9.obj: tmt9.cpp 
+
+tmta.obj: tmta.cpp 
+
+tmtb.obj: tmtb.cpp 
+
+tmtc.obj: tmtc.cpp 
+
+tmtd.obj: tmtd.cpp 
+
+tmte.obj: tmte.cpp 
+
+tmtf.obj: tmtf.cpp 
+
+tmtg.obj: tmtg.cpp 
+
+tmth.obj: tmth.cpp
+
+tmti.obj: tmti.cpp
+
+tmtj.obj: tmtj.cpp
+
+tmtk.obj: tmtk.cpp
+
+tmtl.obj: tmtl.cpp
+
+nl_ex.obj: nl_ex.cpp
+
+sl_ex.obj: sl_ex.cpp
+
+solution.obj: solution.cpp
+
+garch.obj: garch.cpp
+
+test_exc.obj: test_exc.cpp
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/bc32.mak b/Utilities/OSSIM/ossim_core/matrix/bc32.mak
new file mode 100644
index 0000000000..08251d2ba7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/bc32.mak
@@ -0,0 +1,200 @@
+.AUTODEPEND
+
+BORLANDPATH = F:\BC5
+
+TASM = TASM32
+TLIB = tlib
+TLINK = tlink32
+LIBPATH = $(BORLANDPATH)\LIB
+INCLUDEPATH = $(BORLANDPATH)\INCLUDE
+
+CC = bcc32 -W- -v- -H- -x- -3 -N -Og -Oi -Ov -f -I$(INCLUDEPATH)
+
+everything: tmt.exe example.exe nl_ex.exe sl_ex.exe garch.exe test_exc.exe
+
+
+.cpp.obj:
+   $(CC) -c {$< }
+
+OBJ_LIB = bandmat.obj cholesky.obj evalue.obj fft.obj hholder.obj      \
+   jacobi.obj myexcept.obj newmat1.obj newmat2.obj newmat3.obj         \
+   newmat4.obj newmat5.obj newmat6.obj newmat7.obj newmat8.obj         \
+   newmat9.obj newmatex.obj newmatnl.obj newmatrm.obj solution.obj     \
+   sort.obj submat.obj svd.obj newfft.obj
+
+newmat.lib: $(OBJ_LIB)
+   erase newmat.lib
+   $(TLIB) newmat.lib /P32 +newmat1 +newmat2 +newmat3 +newmat4 +newmat5 +newmat6 
+   $(TLIB) newmat.lib /P32+newmat7 +newmat8 +newmat9 +svd +fft +hholder +sort 
+   $(TLIB) newmat.lib /P32+cholesky +submat +jacobi +evalue +bandmat +myexcept
+   $(TLIB) newmat.lib /P32+solution +newmatnl +newmatrm +newmatex +newfft 
+
+OBJ_T = tmt.obj tmt1.obj tmt2.obj tmt3.obj tmt4.obj tmt5.obj tmt6.obj       \
+   tmt7.obj tmt8.obj tmt9.obj tmta.obj tmtb.obj tmtc.obj tmtd.obj tmte.obj  \
+   tmtf.obj tmtg.obj tmth.obj tmti.obj tmtj.obj tmtk.obj tmtl.obj
+
+
+tmt.exe: newmat.lib $(OBJ_T)
+   $(TLINK) /x/L$(LIBPATH) -Tpe -ap -c @&&|
+c0x32.obj+tmt.obj+tmt1.obj+tmt2.obj+tmt3.obj+tmt4.obj+tmt5.obj+tmt6.obj+
+   tmt7.obj+tmt8.obj+tmt9.obj+tmta.obj+tmtb.obj+tmtc.obj+tmtd.obj+tmte.obj+
+   tmtf.obj+tmtg.obj+tmth.obj+tmti.obj+tmtj.obj+tmtk.obj+tmtl.obj+newmat.lib
+   tmt
+      # no map file
+   bidsf.lib+import32.lib+cw32.lib
+
+|
+
+
+example.exe: newmat.lib example.obj
+   $(TLINK) /x/L$(LIBPATH) -Tpe -ap -c @&&|
+c0x32.obj+example.obj+newmat.lib
+   example
+      # no map file
+   bidsf.lib+import32.lib+cw32.lib
+
+|
+
+
+nl_ex.exe: newmat.lib nl_ex.obj
+   $(TLINK) /x/L$(LIBPATH) -Tpe -ap -c @&&|
+c0x32.obj+nl_ex.obj+newmat.lib
+   nl_ex
+      # no map file
+   bidsf.lib+import32.lib+cw32.lib
+
+|
+
+
+sl_ex.exe: newmat.lib sl_ex.obj
+   $(TLINK) /x/L$(LIBPATH) -Tpe -ap -c @&&|
+c0x32.obj+sl_ex.obj+newmat.lib
+   sl_ex
+      # no map file
+   bidsf.lib+import32.lib+cw32.lib
+
+|
+
+
+garch.exe: newmat.lib garch.obj
+   $(TLINK) /x/L$(LIBPATH) -Tpe -ap -c @&&|
+c0x32.obj+garch.obj+newmat.lib
+   garch
+      # no map file
+   bidsf.lib+import32.lib+cw32.lib
+
+|
+
+test_exc.exe: newmat.lib test_exc.obj
+   $(TLINK) /x/L$(LIBPATH) -Tpe -ap -c @&&|
+c0x32.obj+test_exc.obj+newmat.lib
+   test_exc
+      # no map file
+   bidsf.lib+import32.lib+cw32.lib
+
+|
+
+
+bandmat.obj: bandmat.cpp 
+
+cholesky.obj: cholesky.cpp 
+
+evalue.obj: evalue.cpp 
+
+myexcept.obj: myexcept.cpp 
+
+fft.obj: fft.cpp 
+
+newfft.obj: newfft.cpp 
+
+hholder.obj: hholder.cpp 
+
+jacobi.obj: jacobi.cpp 
+
+newmat1.obj: newmat1.cpp 
+
+newmat2.obj: newmat2.cpp 
+
+newmat3.obj: newmat3.cpp 
+
+newmat4.obj: newmat4.cpp 
+
+newmat5.obj: newmat5.cpp 
+
+newmat6.obj: newmat6.cpp 
+
+newmat7.obj: newmat7.cpp 
+
+newmat8.obj: newmat8.cpp 
+
+newmat9.obj: newmat9.cpp 
+
+newmatex.obj: newmatex.cpp 
+
+newmatrm.obj: newmatrm.cpp 
+
+newmatnl.obj: newmatnl.cpp 
+
+sort.obj: sort.cpp 
+
+submat.obj: submat.cpp 
+
+svd.obj: svd.cpp 
+
+example.obj: example.cpp 
+
+tmt.obj: tmt.cpp 
+
+tmt1.obj: tmt1.cpp 
+
+tmt2.obj: tmt2.cpp 
+
+tmt3.obj: tmt3.cpp 
+
+tmt4.obj: tmt4.cpp 
+
+tmt5.obj: tmt5.cpp 
+
+tmt6.obj: tmt6.cpp 
+
+tmt7.obj: tmt7.cpp 
+
+tmt8.obj: tmt8.cpp 
+
+tmt9.obj: tmt9.cpp 
+
+tmta.obj: tmta.cpp 
+
+tmtb.obj: tmtb.cpp 
+
+tmtc.obj: tmtc.cpp 
+
+tmtd.obj: tmtd.cpp 
+
+tmte.obj: tmte.cpp 
+
+tmtf.obj: tmtf.cpp 
+
+tmtg.obj: tmtg.cpp 
+
+tmth.obj: tmth.cpp
+
+tmti.obj: tmti.cpp
+
+tmtj.obj: tmtj.cpp
+
+tmtk.obj: tmtk.cpp
+
+tmtl.obj: tmtl.cpp
+
+nl_ex.obj: nl_ex.cpp
+
+sl_ex.obj: sl_ex.cpp
+
+solution.obj: solution.cpp
+
+garch.obj: garch.cpp
+
+test_exc.obj: test_exc.cpp
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/boolean.h b/Utilities/OSSIM/ossim_core/matrix/boolean.h
new file mode 100644
index 0000000000..1d7b4c8589
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/boolean.h
@@ -0,0 +1,40 @@
+//$$ boolean.h                       bool class
+
+// This is for compilers that do not have bool automatically defined
+
+#ifndef bool_LIB
+#define bool_LIB 0
+
+#ifdef use_namespace
+namespace RBD_COMMON {
+#endif
+
+
+class bool
+{
+	int value;
+public:
+	bool(const int b) { value = b ? 1 : 0; }
+	bool(const void* b) { value = b ? 1 : 0; }
+	bool() {}
+	operator int() const { return value; }
+	int operator!() const { return !value; }
+};
+
+
+const bool true = 1;
+const bool false = 0;
+
+
+
+// version for some older versions of gnu g++
+//#define false 0
+//#define true 1
+
+#ifdef use_namespace
+}
+#endif
+
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/matrix/cc.mak b/Utilities/OSSIM/ossim_core/matrix/cc.mak
new file mode 100644
index 0000000000..2c3ad5c1d3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/cc.mak
@@ -0,0 +1,160 @@
+CXX = CC
+CXXFLAGS = -O2 
+
+.SUFFIXES:
+.SUFFIXES: .a .o .c .cpp
+
+everything:   libnewmat.a tmt example nl_ex sl_ex garch test_exc
+
+
+.cpp.o:
+	      rm -f $*.cxx
+	      ln $*.cpp $*.cxx  
+	      $(CXX) $(CXXFLAGS) -c $*.cxx
+	      rm $*.cxx  
+
+OBJ_LIB = bandmat.o cholesky.o evalue.o fft.o hholder.o     \
+  jacobi.o myexcept.o newmat1.o newmat2.o newmat3.o         \
+  newmat4.o newmat5.o newmat6.o newmat7.o newmat8.o         \
+  newmat9.o newmatex.o newmatnl.o newmatrm.o solution.o     \
+  sort.o submat.o svd.o newfft.o
+
+libnewmat.a:	$(OBJ_LIB)
+	        $(AR) cr $@ $(OBJ_LIB)
+	        ranlib $@
+
+OBJ_T = tmt.o tmt1.o tmt2.o tmt3.o tmt4.o tmt5.o tmt6.o    \
+  tmt7.o tmt8.o tmt9.o tmta.o tmtb.o tmtc.o tmtd.o tmte.o  \
+  tmtf.o tmtg.o tmth.o tmti.o tmtj.o tmtk.o tmtl.o
+
+tmt:    	$(OBJ_T) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_T) -L. -lnewmat -lm
+
+OBJ_E = example.o
+
+example:    	$(OBJ_E) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_E) -L. -lnewmat -lm
+
+OBJ_N = nl_ex.o
+
+nl_ex:    	$(OBJ_N) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_N) -L. -lnewmat -lm
+
+OBJ_S = sl_ex.o
+
+sl_ex:    	$(OBJ_S) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_S) -L. -lnewmat -lm
+
+OBJ_G = garch.o
+
+garch:          $(OBJ_G) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_G) -L. -lnewmat -lm
+
+OBJ_X = test_exc.o
+
+test_exc:	$(OBJ_X) libnewmat.a
+		$(CXX) -o $@ $(OBJ_X) -L. -lnewmat -lm	
+
+newmatxx = include.h newmat.h boolean.h myexcept.h
+
+myexcept.o:   include.h boolean.h myexcept.h myexcept.cpp
+
+newmatex.o:   $(newmatxx) newmatex.cpp
+
+newmatnl.o:   $(newmatxx) newmatnl.h newmatap.h
+
+example.o:    $(newmatxx) newmatap.h example.cpp
+
+cholesky.o:   $(newmatxx) cholesky.cpp
+
+evalue.o:     $(newmatxx) newmatrm.h precisio.h evalue.cpp
+
+fft.o:        $(newmatxx) newmatap.h fft.cpp
+
+newfft.o:        $(newmatxx) newmatap.h newfft.cpp
+
+hholder.o:    $(newmatxx) newmatap.h hholder.cpp
+
+jacobi.o:     $(newmatxx) precisio.h newmatrm.h jacobi.cpp
+
+bandmat.o:    $(newmatxx) newmatrc.h controlw.h bandmat.cpp
+
+newmat1.o:    $(newmatxx) newmat1.cpp
+
+newmat2.o:    $(newmatxx) newmatrc.h controlw.h newmat2.cpp
+
+newmat3.o:    $(newmatxx) newmatrc.h controlw.h newmat3.cpp
+
+newmat4.o:    $(newmatxx) newmatrc.h controlw.h newmat4.cpp
+
+newmat5.o:    $(newmatxx) newmatrc.h controlw.h newmat5.cpp
+
+newmat6.o:    $(newmatxx) newmatrc.h controlw.h newmat6.cpp
+
+newmat7.o:    $(newmatxx) newmatrc.h controlw.h newmat7.cpp
+
+newmat8.o:    $(newmatxx) newmatap.h newmat8.cpp
+
+newmat9.o:    $(newmatxx) newmatrc.h controlw.h newmatio.h newmat9.cpp
+
+newmatrm.o:   $(newmatxx) newmatrm.h newmatrm.cpp
+
+sort.o:       $(newmatxx) newmatap.h sort.cpp
+
+submat.o:     $(newmatxx) newmatrc.h controlw.h submat.cpp
+
+svd.o:        $(newmatxx) newmatrm.h precisio.h svd.cpp
+
+tmt.o:        $(newmatxx) newmatap.h tmt.cpp 
+
+tmt1.o:       $(newmatxx) newmatap.h tmt1.cpp 
+
+tmt2.o:       $(newmatxx) newmatap.h tmt2.cpp 
+
+tmt3.o:       $(newmatxx) newmatap.h tmt3.cpp 
+
+tmt4.o:       $(newmatxx) newmatap.h tmt4.cpp 
+
+tmt5.o:       $(newmatxx) newmatap.h tmt5.cpp 
+
+tmt6.o:       $(newmatxx) newmatap.h tmt6.cpp 
+
+tmt7.o:       $(newmatxx) newmatap.h tmt7.cpp 
+
+tmt8.o:       $(newmatxx) newmatap.h tmt8.cpp 
+
+tmt9.o:       $(newmatxx) newmatap.h tmt9.cpp 
+
+tmta.o:       $(newmatxx) newmatap.h tmta.cpp 
+
+tmtb.o:       $(newmatxx) newmatap.h tmtb.cpp 
+
+tmtc.o:       $(newmatxx) newmatap.h tmtc.cpp 
+
+tmtd.o:       $(newmatxx) newmatap.h tmtd.cpp 
+
+tmte.o:       $(newmatxx) newmatap.h tmte.cpp 
+
+tmtf.o:       $(newmatxx) newmatap.h tmtf.cpp 
+
+tmtg.o:       $(newmatxx) newmatap.h tmtg.cpp 
+
+tmth.o:       $(newmatxx) newmatap.h tmth.cpp
+
+tmti.o:       $(newmatxx) newmatap.h tmti.cpp
+
+tmtj.o:       $(newmatxx) newmatap.h tmtj.cpp
+
+tmtk.o:       $(newmatxx) newmatap.h tmtk.cpp
+
+tmtl.o:       $(newmatxx) newmatap.h tmtl.cpp
+
+nl_ex.o:      $(newmatxx) newmatap.h newmatnl.h nl_ex.cpp
+
+sl_ex.o:      include.h boolean.h myexcept.h sl_ex.cpp
+
+solution.o:   include.h boolean.h myexcept.h solution.cpp
+
+garch.o:      $(newmatxx) newmatap.h newmatnl.h garch.cpp
+
+test_exc.o:   $(newmatxx) test_exc.cpp
diff --git a/Utilities/OSSIM/ossim_core/matrix/cholesky.cpp b/Utilities/OSSIM/ossim_core/matrix/cholesky.cpp
new file mode 100644
index 0000000000..00faf069a8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/cholesky.cpp
@@ -0,0 +1,280 @@
+//$$ cholesky.cpp                     cholesky decomposition
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#define WANT_MATH
+//#define WANT_STREAM
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrm.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,14); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+/********* Cholesky decomposition of a positive definite matrix *************/
+
+// Suppose S is symmetrix and positive definite. Then there exists a unique
+// lower triangular matrix L such that L L.t() = S;
+
+
+ReturnMatrix Cholesky(const SymmetricMatrix& S)
+{
+   REPORT
+   Tracer trace("Cholesky");
+   int nr = S.Nrows();
+   LowerTriangularMatrix T(nr);
+   Real* s = S.Store(); Real* t = T.Store(); Real* ti = t;
+   for (int i=0; i<nr; i++)
+   {
+      Real* tj = t; Real sum; int k;
+      for (int j=0; j<i; j++)
+      {
+         Real* tk = ti; sum = 0.0; k = j;
+         while (k--) { sum += *tj++ * *tk++; }
+         *tk = (*s++ - sum) / *tj++;
+      }
+      sum = 0.0; k = i;
+      while (k--) { sum += square(*ti++); }
+      Real d = *s++ - sum;
+      if (d<=0.0)  Throw(NPDException(S));
+      *ti++ = sqrt(d);
+   }
+   T.Release(); return T.ForReturn();
+}
+
+ReturnMatrix Cholesky(const SymmetricBandMatrix& S)
+{
+   REPORT
+   Tracer trace("Band-Cholesky");
+   int nr = S.Nrows(); int m = S.lower;
+   LowerBandMatrix T(nr,m);
+   Real* s = S.Store(); Real* t = T.Store(); Real* ti = t;
+
+   for (int i=0; i<nr; i++)
+   {
+      Real* tj = t; Real sum; int l;
+      if (i<m) { REPORT l = m-i; s += l; ti += l; l = i; }
+      else { REPORT t += (m+1); l = m; }
+
+      for (int j=0; j<l; j++)
+      {
+         Real* tk = ti; sum = 0.0; int k = j; tj += (m-j);
+         while (k--) { sum += *tj++ * *tk++; }
+         *tk = (*s++ - sum) / *tj++;
+      }
+      sum = 0.0;
+      while (l--) { sum += square(*ti++); }
+      Real d = *s++ - sum;
+      if (d<=0.0)  Throw(NPDException(S));
+      *ti++ = sqrt(d);
+   }
+
+   T.Release(); return T.ForReturn();
+}
+
+
+
+
+// Contributed by Nick Bennett of Schlumberger-Doll Research; modified by RBD
+
+// The enclosed routines can be used to update the Cholesky decomposition of
+// a positive definite symmetric matrix.  A good reference for this routines
+// can be found in
+// LINPACK User's Guide, Chapter 10, Dongarra et. al., SIAM, Philadelphia, 1979
+
+// produces the Cholesky decomposition of A + x.t() * x where A = chol.t() * chol
+void UpdateCholesky(UpperTriangularMatrix &chol, RowVector r1Modification)
+{
+   int ncols = chol.Nrows();
+   ColumnVector cGivens(ncols); cGivens = 0.0;
+   ColumnVector sGivens(ncols); sGivens = 0.0;
+	
+   for(int j = 1; j <= ncols; ++j) // process the jth column of chol
+   {
+      // apply the previous Givens rotations k = 1,...,j-1 to column j
+      for(int k = 1; k < j; ++k)
+         GivensRotation(cGivens(k), sGivens(k), chol(k,j), r1Modification(j));
+
+      // determine the jth Given's rotation
+      pythag(chol(j,j), r1Modification(j), cGivens(j), sGivens(j));
+
+      // apply the jth Given's rotation
+      {
+         Real tmp0 = cGivens(j) * chol(j,j) + sGivens(j) * r1Modification(j);
+         chol(j,j) = tmp0; r1Modification(j) = 0.0;
+      }
+
+   }
+
+}
+
+
+// produces the Cholesky decomposition of A - x.t() * x where A = chol.t() * chol
+void DowndateCholesky(UpperTriangularMatrix &chol, RowVector x)
+{
+   int nRC = chol.Nrows();
+	
+   // solve R^T a = x
+   LowerTriangularMatrix L = chol.t();
+   ColumnVector a(nRC); a = 0.0;
+   int i, j;
+	
+   for (i = 1; i <= nRC; ++i)
+   {
+      // accumulate subtr sum
+      Real subtrsum = 0.0;
+      for(int k = 1; k < i; ++k) subtrsum += a(k) * L(i,k);
+
+      a(i) = (x(i) - subtrsum) / L(i,i);
+   }
+
+   // test that l2 norm of a is < 1
+   Real squareNormA = a.SumSquare();
+   if (squareNormA >= 1.0)
+      Throw(ProgramException("DowndateCholesky() fails", chol));
+
+   Real alpha = sqrt(1.0 - squareNormA);
+
+   // compute and apply Givens rotations to the vector a
+   ColumnVector cGivens(nRC);  cGivens = 0.0;
+   ColumnVector sGivens(nRC);  sGivens = 0.0;
+   for(i = nRC; i >= 1; i--)
+      alpha = pythag(alpha, a(i), cGivens(i), sGivens(i));
+
+   // apply Givens rotations to the jth column of chol
+   ColumnVector xtilde(nRC); xtilde = 0.0;
+   for(j = nRC; j >= 1; j--)
+   {
+      // only the first j rotations have an affect on chol,0
+      for(int k = j; k >= 1; k--)
+         GivensRotation(cGivens(k), -sGivens(k), chol(k,j), xtilde(j));
+   }
+}
+
+
+
+// produces the Cholesky decomposition of EAE where A = chol.t() * chol
+// and E produces a RIGHT circular shift of the rows and columns from
+// 1,...,k-1,k,k+1,...l,l+1,...,p to
+// 1,...,k-1,l,k,k+1,...l-1,l+1,...p
+void RightCircularUpdateCholesky(UpperTriangularMatrix &chol, int k, int l)
+{
+   int nRC = chol.Nrows();
+   int i, j;
+	
+   // I. compute shift of column l to the kth position
+   Matrix cholCopy = chol;
+   // a. grab column l
+   ColumnVector columnL = cholCopy.Column(l);
+   // b. shift columns k,...l-1 to the RIGHT
+   for(j = l-1; j >= k; --j)
+      cholCopy.Column(j+1) = cholCopy.Column(j);
+   // c. copy the top k-1 elements of columnL into the kth column of cholCopy
+   cholCopy.Column(k) = 0.0;
+   for(i = 1; i < k; ++i) cholCopy(i,k) = columnL(i);
+
+    // II. determine the l-k Given's rotations
+   int nGivens = l-k;
+   ColumnVector cGivens(nGivens); cGivens = 0.0;
+   ColumnVector sGivens(nGivens); sGivens = 0.0;
+   for(i = l; i > k; i--)
+   {
+      int givensIndex = l-i+1;
+      columnL(i-1) = pythag(columnL(i-1), columnL(i),
+         cGivens(givensIndex), sGivens(givensIndex));
+      columnL(i) = 0.0;
+   }
+   // the kth entry of columnL is the new diagonal element in column k of cholCopy
+   cholCopy(k,k) = columnL(k);
+	
+   // III. apply these Given's rotations to subsequent columns
+   // for columns k+1,...,l-1 we only need to apply the last nGivens-(j-k) rotations
+   for(j = k+1; j <= nRC; ++j)
+   {
+      ColumnVector columnJ = cholCopy.Column(j);
+      int imin = nGivens - (j-k) + 1; if (imin < 1) imin = 1;
+      for(int gIndex = imin; gIndex <= nGivens; ++gIndex)
+      {
+         // apply gIndex Given's rotation
+         int topRowIndex = k + nGivens - gIndex;
+         GivensRotationR(cGivens(gIndex), sGivens(gIndex),
+            columnJ(topRowIndex), columnJ(topRowIndex+1));
+      }
+      cholCopy.Column(j) = columnJ;
+   }
+
+   chol << cholCopy;
+}
+
+
+
+// produces the Cholesky decomposition of EAE where A = chol.t() * chol
+// and E produces a LEFT circular shift of the rows and columns from
+// 1,...,k-1,k,k+1,...l,l+1,...,p to
+// 1,...,k-1,k+1,...l,k,l+1,...,p to
+void LeftCircularUpdateCholesky(UpperTriangularMatrix &chol, int k, int l)
+{
+   int nRC = chol.Nrows();
+   int i, j;
+
+   // I. compute shift of column k to the lth position
+   Matrix cholCopy = chol;
+   // a. grab column k
+   ColumnVector columnK = cholCopy.Column(k);
+   // b. shift columns k+1,...l to the LEFT
+   for(j = k+1; j <= l; ++j)
+      cholCopy.Column(j-1) = cholCopy.Column(j);
+   // c. copy the elements of columnK into the lth column of cholCopy
+   cholCopy.Column(l) = 0.0;
+   for(i = 1; i <= k; ++i)
+      cholCopy(i,l) = columnK(i);
+
+   // II. apply and compute Given's rotations
+   int nGivens = l-k;
+   ColumnVector cGivens(nGivens); cGivens = 0.0;
+   ColumnVector sGivens(nGivens); sGivens = 0.0;
+   for(j = k; j <= nRC; ++j)
+   {
+      ColumnVector columnJ = cholCopy.Column(j);
+
+      // apply the previous Givens rotations to columnJ
+      int imax = j - k; if (imax > nGivens) imax = nGivens;
+      for(int i = 1; i <= imax; ++i)
+      {
+         int gIndex = i;
+         int topRowIndex = k + i - 1;
+         GivensRotationR(cGivens(gIndex), sGivens(gIndex),
+            columnJ(topRowIndex), columnJ(topRowIndex+1));
+      }
+
+      // compute a new Given's rotation when j < l
+      if(j < l)
+      {
+         int gIndex = j-k+1;
+         columnJ(j) = pythag(columnJ(j), columnJ(j+1), cGivens(gIndex), sGivens(gIndex));
+         columnJ(j+1) = 0.0;
+      }
+
+      cholCopy.Column(j) = columnJ;
+   }
+
+   chol << cholCopy;
+	
+}
+
+
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/controlw.h b/Utilities/OSSIM/ossim_core/matrix/controlw.h
new file mode 100644
index 0000000000..76faa98549
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/controlw.h
@@ -0,0 +1,48 @@
+//$$ controlw.h                Control word class
+
+#ifndef CONTROL_WORD_LIB
+#define CONTROL_WORD_LIB 0
+
+// for organising an int as a series of bits which indicate whether an
+// option is on or off.
+
+class ControlWord
+{
+protected:
+   int cw;                                      // the control word
+public:
+   ControlWord() : cw(0) {}                     // do nothing
+   ControlWord(int i) : cw(i) {}                // load an integer
+
+      // select specific bits (for testing at least one set)
+   ControlWord operator*(ControlWord i) const
+      { return ControlWord(cw & i.cw); }
+   void operator*=(ControlWord i)  { cw &= i.cw; }
+
+      // set bits
+   ControlWord operator+(ControlWord i) const
+      { return ControlWord(cw | i.cw); }
+   void operator+=(ControlWord i)  { cw |= i.cw; }
+
+      // reset bits
+   ControlWord operator-(ControlWord i) const
+      { return ControlWord(cw - (cw & i.cw)); }
+   void operator-=(ControlWord i) { cw -= (cw & i.cw); }
+
+      // check if all of selected bits set or reset
+   bool operator>=(ControlWord i) const { return (cw & i.cw) == i.cw; }
+   bool operator<=(ControlWord i) const { return (cw & i.cw) == cw; }
+
+      // flip selected bits
+   ControlWord operator^(ControlWord i) const
+      { return ControlWord(cw ^ i.cw); }
+   ControlWord operator~() const { return ControlWord(~cw); }
+
+      // convert to integer
+   int operator+() const { return cw; }
+   int operator!() const { return cw==0; }
+   FREE_CHECK(ControlWord)
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/matrix/evalue.cpp b/Utilities/OSSIM/ossim_core/matrix/evalue.cpp
new file mode 100644
index 0000000000..ccb9c8d14a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/evalue.cpp
@@ -0,0 +1,297 @@
+//$$evalue.cpp                           eigen-value decomposition
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#define WANT_MATH
+
+#include "include.h"
+#include "newmatap.h"
+#include "newmatrm.h"
+#include "precisio.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,17); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+
+static void tred2(const SymmetricMatrix& A, DiagonalMatrix& D,
+   DiagonalMatrix& E, Matrix& Z)
+{
+   Tracer et("Evalue(tred2)");
+   REPORT
+   Real tol =
+      FloatingPointPrecision::Minimum()/FloatingPointPrecision::Epsilon();
+   int n = A.Nrows(); Z.ReSize(n,n); Z.Inject(A);
+   D.ReSize(n); E.ReSize(n);
+   Real* z = Z.Store(); int i;
+
+   for (i=n-1; i > 0; i--)                   // i=0 is excluded
+   {
+      Real f = Z.element(i,i-1); Real g = 0.0;
+      int k = i-1; Real* zik = z + i*n;
+      while (k--) g += square(*zik++);
+      Real h = g + square(f);
+      if (g <= tol) { REPORT E.element(i) = f; h = 0.0; }
+      else
+      {
+         REPORT
+         g = sign(-sqrt(h), f); E.element(i) = g; h -= f*g;
+         Z.element(i,i-1) = f-g; f = 0.0;
+         Real* zji = z + i; Real* zij = z + i*n; Real* ej = E.Store();
+         int j;
+         for (j=0; j<i; j++)
+         {
+            *zji = (*zij++)/h; g = 0.0;
+            Real* zjk = z + j*n; zik = z + i*n;
+            k = j; while (k--) g += *zjk++ * (*zik++);
+            k = i-j;
+            if (k) for(;;)
+               { g += *zjk * (*zik++); if (!(--k)) break; zjk += n; }
+            *ej++ = g/h; f += g * (*zji); zji += n;
+         }
+         Real hh = f / (h + h); zij = z + i*n; ej = E.Store();
+         for (j=0; j<i; j++)
+         {
+            f = *zij++; g = *ej - hh * f; *ej++ = g;
+            Real* zjk = z + j*n; Real* zik = z + i*n;
+            Real* ek = E.Store(); k = j+1;
+            while (k--)  *zjk++ -= ( f*(*ek++) + g*(*zik++) ); 
+         }
+      }
+      D.element(i) = h;
+   }
+
+   D.element(0) = 0.0; E.element(0) = 0.0;
+   for (i=0; i<n; i++)
+   {
+      if (D.element(i) != 0.0)
+      {
+         REPORT
+         for (int j=0; j<i; j++)
+         {
+            Real g = 0.0;
+            Real* zik = z + i*n; Real* zkj = z + j;
+            int k = i;
+            if (k) for (;;)
+               { g += *zik++ * (*zkj); if (!(--k)) break; zkj += n; }
+            Real* zki = z + i; zkj = z + j;
+            k = i;
+            if (k) for (;;)
+               { *zkj -= g * (*zki); if (!(--k)) break; zkj += n; zki += n; }
+         }
+      }
+      Real* zij = z + i*n; Real* zji = z + i;
+      int j = i;
+      if (j) for (;;)
+         { *zij++ = 0.0; *zji = 0.0; if (!(--j)) break; zji += n; }
+      D.element(i) = *zij; *zij = 1.0;
+   }
+}
+
+static void tql2(DiagonalMatrix& D, DiagonalMatrix& E, Matrix& Z)
+{
+   Tracer et("Evalue(tql2)");
+   REPORT
+   Real eps = FloatingPointPrecision::Epsilon();
+   int n = D.Nrows(); Real* z = Z.Store(); int l;
+   for (l=1; l<n; l++) E.element(l-1) = E.element(l);
+   Real b = 0.0; Real f = 0.0; E.element(n-1) = 0.0;
+   for (l=0; l<n; l++)
+   {
+      int i,j;
+      Real& dl = D.element(l); Real& el = E.element(l);
+      Real h = eps * ( fabs(dl) + fabs(el) );
+      if (b < h) { REPORT b = h; }
+      int m;
+      for (m=l; m<n; m++) if (fabs(E.element(m)) <= b) break;
+      bool test = false;
+      for (j=0; j<30; j++)
+      {
+         if (m==l) { REPORT test = true; break; }
+         Real& dl1 = D.element(l+1);
+         Real g = dl; Real p = (dl1-g) / (2.0*el); Real r = sqrt(p*p + 1.0);
+         dl = el / (p < 0.0 ? p-r : p+r); Real h = g - dl; f += h;
+         Real* dlx = &dl1; i = n-l-1; while (i--) *dlx++ -= h;
+
+         p = D.element(m); Real c = 1.0; Real s = 0.0;
+         for (i=m-1; i>=l; i--)
+         {
+            Real ei = E.element(i); Real di = D.element(i);
+            Real& ei1 = E.element(i+1);
+            g = c * ei; h = c * p;
+            if ( fabs(p) >= fabs(ei))
+            {
+               REPORT
+               c = ei / p; r = sqrt(c*c + 1.0);
+               ei1 = s*p*r; s = c/r; c = 1.0/r;
+            }
+            else
+            {
+               REPORT
+               c = p / ei; r = sqrt(c*c + 1.0);
+               ei1 = s * ei * r; s = 1.0/r; c /= r;
+            }
+            p = c * di - s*g; D.element(i+1) = h + s * (c*g + s*di);
+
+            Real* zki = z + i; Real* zki1 = zki + 1; int k = n;
+            if (k) for (;;)
+            {
+               REPORT
+               h = *zki1; *zki1 = s*(*zki) + c*h; *zki = c*(*zki) - s*h;
+               if (!(--k)) break;
+               zki += n; zki1 += n;
+            }
+         }
+         el = s*p; dl = c*p;
+         if (fabs(el) <= b) { REPORT; test = true; break; }
+      }
+      if (!test) Throw ( ConvergenceException(D) );
+      dl += f;
+   }
+/*
+   for (int i=0; i<n; i++)
+   {
+      int k = i; Real p = D.element(i);
+      for (int j=i+1; j<n; j++)
+         { if (D.element(j) < p) { k = j; p = D.element(j); } }
+      if (k != i)
+      {
+         D.element(k) = D.element(i); D.element(i) = p; int j = n;
+         Real* zji = z + i; Real* zjk = z + k;
+         if (j) for(;;)
+         {
+            p = *zji; *zji = *zjk; *zjk = p;
+            if (!(--j)) break;
+            zji += n; zjk += n;
+         }
+      }
+   }
+*/
+}
+
+static void tred3(const SymmetricMatrix& X, DiagonalMatrix& D,
+   DiagonalMatrix& E, SymmetricMatrix& A)
+{
+   Tracer et("Evalue(tred3)");
+   REPORT
+   Real tol =
+      FloatingPointPrecision::Minimum()/FloatingPointPrecision::Epsilon();
+   int n = X.Nrows(); A = X; D.ReSize(n); E.ReSize(n);
+   Real* ei = E.Store() + n;
+   for (int i = n-1; i >= 0; i--)
+   {
+      Real h = 0.0; Real f = - FloatingPointPrecision::Maximum();
+      Real* d = D.Store(); Real* a = A.Store() + (i*(i+1))/2; int k = i;
+      while (k--) { f = *a++; *d++ = f; h += square(f); }
+      if (h <= tol) { REPORT *(--ei) = 0.0; h = 0.0; }
+      else
+      {
+         REPORT
+         Real g = sign(-sqrt(h), f); *(--ei) = g; h -= f*g;
+         f -= g; *(d-1) = f; *(a-1) = f; f = 0.0;
+         Real* dj = D.Store(); Real* ej = E.Store(); int j;
+         for (j = 0; j < i; j++)
+         {
+            Real* dk = D.Store(); Real* ak = A.Store()+(j*(j+1))/2;
+            Real g = 0.0; k = j;
+            while (k--)  g += *ak++ * *dk++;
+            k = i-j; int l = j; 
+            if (k) for (;;) { g += *ak * *dk++; if (!(--k)) break; ak += ++l; }
+            g /= h; *ej++ = g; f += g * *dj++;
+         }  
+         Real hh = f / (2 * h); Real* ak = A.Store();
+         dj = D.Store(); ej = E.Store();
+         for (j = 0; j < i; j++)
+         {
+            f = *dj++; g = *ej - hh * f; *ej++ = g;
+            Real* dk = D.Store(); Real* ek = E.Store(); k = j+1;
+            while (k--) { *ak++ -= (f * *ek++ + g * *dk++); }
+         }
+      }
+      *d = *a; *a = h;
+   }
+}
+
+static void tql1(DiagonalMatrix& D, DiagonalMatrix& E)
+{
+   Tracer et("Evalue(tql1)");
+   REPORT
+   Real eps = FloatingPointPrecision::Epsilon();
+   int n = D.Nrows(); int l;
+   for (l=1; l<n; l++) E.element(l-1) = E.element(l);
+   Real b = 0.0; Real f = 0.0; E.element(n-1) = 0.0;
+   for (l=0; l<n; l++)
+   {
+      int i,j;
+      Real& dl = D.element(l); Real& el = E.element(l);
+      Real h = eps * ( fabs(dl) + fabs(el) );
+      if (b < h) b = h;
+      int m;
+      for (m=l; m<n; m++) if (fabs(E.element(m)) <= b) break;
+      bool test = false;
+      for (j=0; j<30; j++)
+      {
+         if (m==l) { REPORT test = true; break; }
+         Real& dl1 = D.element(l+1);
+         Real g = dl; Real p = (dl1-g) / (2.0*el); Real r = sqrt(p*p + 1.0);
+         dl = el / (p < 0.0 ? p-r : p+r); Real h = g - dl; f += h;
+         Real* dlx = &dl1; i = n-l-1; while (i--) *dlx++ -= h;
+
+         p = D.element(m); Real c = 1.0; Real s = 0.0;
+         for (i=m-1; i>=l; i--)
+         {
+            Real ei = E.element(i); Real di = D.element(i);
+            Real& ei1 = E.element(i+1);
+            g = c * ei; h = c * p;
+            if ( fabs(p) >= fabs(ei))
+            {
+               REPORT
+               c = ei / p; r = sqrt(c*c + 1.0);
+               ei1 = s*p*r; s = c/r; c = 1.0/r;
+            }
+            else
+            {
+               REPORT
+               c = p / ei; r = sqrt(c*c + 1.0);
+               ei1 = s * ei * r; s = 1.0/r; c /= r;
+            }
+            p = c * di - s*g; D.element(i+1) = h + s * (c*g + s*di);
+         }
+         el = s*p; dl = c*p;
+         if (fabs(el) <= b) { REPORT test = true; break; }
+      }
+      if (!test) Throw ( ConvergenceException(D) );
+      Real p = dl + f;
+      test = false;
+      for (i=l; i>0; i--)
+      {
+         if (p < D.element(i-1)) { REPORT D.element(i) = D.element(i-1); }
+         else { REPORT test = true; break; }
+      }
+      if (!test) i=0;
+      D.element(i) = p;
+   }
+}
+
+void EigenValues(const SymmetricMatrix& A, DiagonalMatrix& D, Matrix& Z)
+{ REPORT DiagonalMatrix E; tred2(A, D, E, Z); tql2(D, E, Z); SortSV(D,Z,true); }
+
+void EigenValues(const SymmetricMatrix& X, DiagonalMatrix& D)
+{ REPORT DiagonalMatrix E; SymmetricMatrix A; tred3(X,D,E,A); tql1(D,E); }
+
+void EigenValues(const SymmetricMatrix& X, DiagonalMatrix& D,
+   SymmetricMatrix& A)
+{ REPORT DiagonalMatrix E; tred3(X,D,E,A); tql1(D,E); }
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/example.txt b/Utilities/OSSIM/ossim_core/matrix/example.txt
new file mode 100644
index 0000000000..b3b733490b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/example.txt
@@ -0,0 +1,123 @@
+
+Demonstration of Matrix package
+
+Print a real number (may help lost memory test): 3.14159
+
+
+Test 1 - traditional, bad
+
+Estimates and their standard errors
+
+    1.39166     0.53188 
+    1.98310     0.20932 
+    0.95221     0.27731 
+
+
+Observations, fitted value, residual value, hat value
+    2.400     1.700     8.300     7.770     0.530     0.280 
+    1.800     0.900     5.500     5.818    -0.318     0.190 
+    2.400     1.600     8.000     7.675     0.325     0.229 
+    3.000     1.900     8.500     9.150    -0.650     0.446 
+    2.000     0.500     5.700     5.834    -0.134     0.271 
+    1.200     0.600     4.400     4.343     0.057     0.480 
+    2.000     1.100     6.300     6.405    -0.105     0.143 
+    2.700     1.000     7.900     7.698     0.202     0.153 
+    3.600     0.500     9.100     9.007     0.093     0.808 
+
+
+
+
+Test 2 - traditional, OK
+
+Estimates and their standard errors
+
+    1.39166     0.53188
+    1.98310     0.20932 
+    0.95221     0.27731 
+
+
+Observations, fitted value, residual value, hat value
+    2.400     1.700     8.300     7.770     0.530     0.280 
+    1.800     0.900     5.500     5.818    -0.318     0.190 
+    2.400     1.600     8.000     7.675     0.325     0.229 
+    3.000     1.900     8.500     9.150    -0.650     0.446 
+    2.000     0.500     5.700     5.834    -0.134     0.271 
+    1.200     0.600     4.400     4.343     0.057     0.480 
+    2.000     1.100     6.300     6.405    -0.105     0.143 
+    2.700     1.000     7.900     7.698     0.202     0.153 
+    3.600     0.500     9.100     9.007     0.093     0.808 
+
+
+
+
+Test 3 - Cholesky
+
+Estimates and their standard errors
+
+    1.39166     0.53188
+    1.98310     0.20932 
+    0.95221     0.27731 
+
+
+Observations, fitted value, residual value, hat value
+    2.400     1.700     8.300     7.770     0.530     0.280 
+    1.800     0.900     5.500     5.818    -0.318     0.190 
+    2.400     1.600     8.000     7.675     0.325     0.229 
+    3.000     1.900     8.500     9.150    -0.650     0.446 
+    2.000     0.500     5.700     5.834    -0.134     0.271 
+    1.200     0.600     4.400     4.343     0.057     0.480 
+    2.000     1.100     6.300     6.405    -0.105     0.143 
+    2.700     1.000     7.900     7.698     0.202     0.153 
+    3.600     0.500     9.100     9.007     0.093     0.808 
+
+
+
+
+Test 4 - QR triangularisation
+
+Estimates and their standard errors
+
+    1.39166     0.53188 
+    1.98310     0.20932 
+    0.95221     0.27731 
+
+
+Observations, fitted value, residual value, hat value
+    2.400     1.700     8.300     7.770     0.530     0.280 
+    1.800     0.900     5.500     5.818    -0.318     0.190 
+    2.400     1.600     8.000     7.675     0.325     0.229 
+    3.000     1.900     8.500     9.150    -0.650     0.446 
+    2.000     0.500     5.700     5.834    -0.134     0.271 
+    1.200     0.600     4.400     4.343     0.057     0.480 
+    2.000     1.100     6.300     6.405    -0.105     0.143 
+    2.700     1.000     7.900     7.698     0.202     0.153 
+    3.600     0.500     9.100     9.007     0.093     0.808 
+
+
+
+
+Test 5 - singular value
+
+Estimates and their standard errors
+
+    1.39166     0.53188 
+    1.98310     0.20932 
+    0.95221     0.27731 
+
+
+Observations, fitted value, residual value, hat value
+    2.400     1.700     8.300     7.770     0.530     0.280 
+    1.800     0.900     5.500     5.818    -0.318     0.190 
+    2.400     1.600     8.000     7.675     0.325     0.229 
+    3.000     1.900     8.500     9.150    -0.650     0.446 
+    2.000     0.500     5.700     5.834    -0.134     0.271 
+    1.200     0.600     4.400     4.343     0.057     0.480 
+    2.000     1.100     6.300     6.405    -0.105     0.143 
+    2.700     1.000     7.900     7.698     0.202     0.153 
+    3.600     0.500     9.100     9.007     0.093     0.808 
+
+
+
+
+The following test does not work with all compilers - see documentation
+Checking for lost memory: 8206652 8206652  - ok
diff --git a/Utilities/OSSIM/ossim_core/matrix/fft.cpp b/Utilities/OSSIM/ossim_core/matrix/fft.cpp
new file mode 100644
index 0000000000..08a2deb2f5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/fft.cpp
@@ -0,0 +1,474 @@
+//$$ fft.cpp                         Fast fourier transform
+
+// Copyright (C) 1991,2,3,4,8: R B Davies
+
+
+#define WANT_MATH
+// #define WANT_STREAM
+
+#include "include.h"
+
+#include "newmatap.h"
+
+// #include "newmatio.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,19); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+static void cossin(int n, int d, Real& c, Real& s)
+// calculate cos(twopi*n/d) and sin(twopi*n/d)
+// minimise roundoff error
+{
+   REPORT
+   long n4 = n * 4; int sector = (int)floor( (Real)n4 / (Real)d + 0.5 );
+   n4 -= sector * d;
+   if (sector < 0) { REPORT sector = 3 - (3 - sector) % 4; }
+   else  { REPORT sector %= 4; }
+   Real ratio = 1.5707963267948966192 * (Real)n4 / (Real)d;
+
+   switch (sector)
+   {
+   case 0: REPORT c =  cos(ratio); s =  sin(ratio); break;
+   case 1: REPORT c = -sin(ratio); s =  cos(ratio); break;
+   case 2: REPORT c = -cos(ratio); s = -sin(ratio); break;
+   case 3: REPORT c =  sin(ratio); s = -cos(ratio); break;
+   }
+}
+
+static void fftstep(ColumnVector& A, ColumnVector& B, ColumnVector& X,
+   ColumnVector& Y, int after, int now, int before)
+{
+   REPORT
+   Tracer trace("FFT(step)");
+   // const Real twopi = 6.2831853071795864769;
+   const int gamma = after * before;  const int delta = now * after;
+   // const Real angle = twopi / delta;  Real temp;
+   // Real r_omega = cos(angle);  Real i_omega = -sin(angle);
+   Real r_arg = 1.0;  Real i_arg = 0.0;
+   Real* x = X.Store();  Real* y = Y.Store();   // pointers to array storage
+   const int m = A.Nrows() - gamma;
+
+   for (int j = 0; j < now; j++)
+   {
+      Real* a = A.Store(); Real* b = B.Store(); // pointers to array storage
+      Real* x1 = x; Real* y1 = y; x += after; y += after;
+      for (int ia = 0; ia < after; ia++)
+      {
+         // generate sins & cosines explicitly rather than iteratively
+         // for more accuracy; but slower
+         cossin(-(j*after+ia), delta, r_arg, i_arg);
+
+         Real* a1 = a++; Real* b1 = b++; Real* x2 = x1++; Real* y2 = y1++;
+         if (now==2)
+         {
+            REPORT int ib = before;
+            if (ib) for (;;)
+            {
+               REPORT
+               Real* a2 = m + a1; Real* b2 = m + b1; a1 += after; b1 += after;
+               Real r_value = *a2; Real i_value = *b2;
+               *x2 = r_value * r_arg - i_value * i_arg + *(a2-gamma);
+               *y2 = r_value * i_arg + i_value * r_arg + *(b2-gamma);
+               if (!(--ib)) break;
+               x2 += delta; y2 += delta;
+            }
+         }
+         else
+         {
+            REPORT int ib = before;
+            if (ib) for (;;)
+            {
+               REPORT
+               Real* a2 = m + a1; Real* b2 = m + b1; a1 += after; b1 += after;
+               Real r_value = *a2; Real i_value = *b2;
+               int in = now-1; while (in--)
+               {
+                  // it should be possible to make this faster
+                  // hand code for now = 2,3,4,5,8
+                  // use symmetry to halve number of operations
+                  a2 -= gamma; b2 -= gamma;  Real temp = r_value;
+                  r_value = r_value * r_arg - i_value * i_arg + *a2;
+                  i_value = temp    * i_arg + i_value * r_arg + *b2;
+               }
+               *x2 = r_value; *y2 = i_value;
+               if (!(--ib)) break;
+               x2 += delta; y2 += delta;
+            }
+         }
+
+         // temp = r_arg;
+         // r_arg = r_arg * r_omega - i_arg * i_omega;
+         // i_arg = temp  * i_omega + i_arg * r_omega;
+
+      }
+   }
+}
+
+
+void FFTI(const ColumnVector& U, const ColumnVector& V,
+   ColumnVector& X, ColumnVector& Y)
+{
+   // Inverse transform
+   Tracer trace("FFTI");
+   REPORT
+   FFT(U,-V,X,Y);
+   const Real n = X.Nrows(); X /= n; Y /= (-n);
+}
+
+void RealFFT(const ColumnVector& U, ColumnVector& X, ColumnVector& Y)
+{
+   // Fourier transform of a real series
+   Tracer trace("RealFFT");
+   REPORT
+   const int n = U.Nrows();                     // length of arrays
+   const int n2 = n / 2;
+   if (n != 2 * n2)
+      Throw(ProgramException("Vector length not multiple of 2", U));
+   ColumnVector A(n2), B(n2);
+   Real* a = A.Store(); Real* b = B.Store(); Real* u = U.Store(); int i = n2;
+   while (i--) { *a++ = *u++; *b++ = *u++; }
+   FFT(A,B,A,B);
+   int n21 = n2 + 1;
+   X.ReSize(n21); Y.ReSize(n21);
+   i = n2 - 1;
+   a = A.Store(); b = B.Store();              // first els of A and B
+   Real* an = a + i; Real* bn = b + i;        // last els of A and B
+   Real* x = X.Store(); Real* y = Y.Store();  // first els of X and Y
+   Real* xn = x + n2; Real* yn = y + n2;      // last els of X and Y
+
+   *x++ = *a + *b; *y++ = 0.0;                // first complex element
+   *xn-- = *a++ - *b++; *yn-- = 0.0;          // last complex element
+
+   int j = -1; i = n2/2;
+   while (i--)
+   {
+      Real c,s; cossin(j--,n,c,s);
+      Real am = *a - *an; Real ap = *a++ + *an--;
+      Real bm = *b - *bn; Real bp = *b++ + *bn--;
+      Real samcbp = s * am + c * bp; Real sbpcam = s * bp - c * am;
+      *x++  =  0.5 * ( ap + samcbp); *y++  =  0.5 * ( bm + sbpcam);
+      *xn-- =  0.5 * ( ap - samcbp); *yn-- =  0.5 * (-bm + sbpcam);
+   }
+}
+
+void RealFFTI(const ColumnVector& A, const ColumnVector& B, ColumnVector& U)
+{
+   // inverse of a Fourier transform of a real series
+   Tracer trace("RealFFTI");
+   REPORT
+   const int n21 = A.Nrows();                     // length of arrays
+   if (n21 != B.Nrows() || n21 == 0)
+      Throw(ProgramException("Vector lengths unequal or zero", A, B));
+   const int n2 = n21 - 1;  const int n = 2 * n2;  int i = n2 - 1;
+
+   ColumnVector X(n2), Y(n2);
+   Real* a = A.Store(); Real* b = B.Store();  // first els of A and B
+   Real* an = a + n2;   Real* bn = b + n2;    // last els of A and B
+   Real* x = X.Store(); Real* y = Y.Store();  // first els of X and Y
+   Real* xn = x + i;    Real* yn = y + i;     // last els of X and Y
+
+   Real hn = 0.5 / n2;
+   *x++  = hn * (*a + *an);  *y++  = - hn * (*a - *an);
+   a++; an--; b++; bn--;
+   int j = -1;  i = n2/2;
+   while (i--)
+   {
+      Real c,s; cossin(j--,n,c,s);
+      Real am = *a - *an; Real ap = *a++ + *an--;
+      Real bm = *b - *bn; Real bp = *b++ + *bn--;
+      Real samcbp = s * am - c * bp; Real sbpcam = s * bp + c * am;
+      *x++  =  hn * ( ap + samcbp); *y++  =  - hn * ( bm + sbpcam);
+      *xn-- =  hn * ( ap - samcbp); *yn-- =  - hn * (-bm + sbpcam);
+   }
+   FFT(X,Y,X,Y);             // have done inverting elsewhere
+   U.ReSize(n); i = n2;
+   x = X.Store(); y = Y.Store(); Real* u = U.Store();
+   while (i--) { *u++ = *x++; *u++ = - *y++; }
+}
+
+void FFT(const ColumnVector& U, const ColumnVector& V,
+   ColumnVector& X, ColumnVector& Y)
+{
+   // from Carl de Boor (1980), Siam J Sci Stat Comput, 1 173-8
+   // but first try Sande and Gentleman
+   Tracer trace("FFT");
+   REPORT
+   const int n = U.Nrows();                     // length of arrays
+   if (n != V.Nrows() || n == 0)
+      Throw(ProgramException("Vector lengths unequal or zero", U, V));
+   if (n == 1) { REPORT X = U; Y = V; return; }
+
+   // see if we can use the newfft routine
+   if (!FFT_Controller::OnlyOldFFT && FFT_Controller::CanFactor(n))
+   {
+      REPORT
+      X = U; Y = V;
+      if ( FFT_Controller::ar_1d_ft(n,X.Store(),Y.Store()) ) return;
+   }
+
+   ColumnVector B = V;
+   ColumnVector A = U;
+   X.ReSize(n); Y.ReSize(n);
+   const int nextmx = 8;
+   int prime[8] = { 2,3,5,7,11,13,17,19 };
+   int after = 1; int before = n; int next = 0; bool inzee = true;
+   int now = 0; int b1;             // initialised to keep gnu happy
+
+   do
+   {
+      for (;;)
+      {
+	 if (next < nextmx) { REPORT now = prime[next]; }
+	 b1 = before / now;  if (b1 * now == before) { REPORT break; }
+	 next++; now += 2;
+      }
+      before = b1;
+
+      if (inzee) { REPORT fftstep(A, B, X, Y, after, now, before); }
+      else { REPORT fftstep(X, Y, A, B, after, now, before); }
+
+      inzee = !inzee; after *= now;
+   }
+   while (before != 1);
+
+   if (inzee) { REPORT A.Release(); X = A; B.Release(); Y = B; }
+}
+
+// Trigonometric transforms
+// see Charles Van Loan (1992) "Computational frameworks for the fast
+// Fourier transform" published by SIAM; section 4.4.
+
+void DCT_II(const ColumnVector& U, ColumnVector& V)
+{
+   // Discrete cosine transform, type II, of a real series
+   Tracer trace("DCT_II");
+   REPORT
+   const int n = U.Nrows();                     // length of arrays
+   const int n2 = n / 2; const int n4 = n * 4;
+   if (n != 2 * n2)
+      Throw(ProgramException("Vector length not multiple of 2", U));
+   ColumnVector A(n);
+   Real* a = A.Store(); Real* b = a + n; Real* u = U.Store();
+   int i = n2;
+   while (i--) { *a++ = *u++; *(--b) = *u++; }
+   ColumnVector X, Y;
+   RealFFT(A, X, Y); A.CleanUp();
+   V.ReSize(n);
+   Real* x = X.Store(); Real* y = Y.Store();
+   Real* v = V.Store(); Real* w = v + n;
+   *v = *x;
+   int k = 0; i = n2;
+   while (i--)
+   {
+      Real c, s; cossin(++k, n4, c, s);
+      Real xi = *(++x); Real yi = *(++y);
+      *(++v) = xi * c + yi * s; *(--w) = xi * s - yi * c;
+   }
+}
+
+void DCT_II_inverse(const ColumnVector& V, ColumnVector& U)
+{
+   // Inverse of discrete cosine transform, type II
+   Tracer trace("DCT_II_inverse");
+   REPORT
+   const int n = V.Nrows();                     // length of array
+   const int n2 = n / 2; const int n4 = n * 4; const int n21 = n2 + 1;
+   if (n != 2 * n2)
+      Throw(ProgramException("Vector length not multiple of 2", V));
+   ColumnVector X(n21), Y(n21);
+   Real* x = X.Store(); Real* y = Y.Store();
+   Real* v = V.Store(); Real* w = v + n;
+   *x = *v; *y = 0.0;
+   int i = n2; int k = 0;
+   while (i--)
+   {
+      Real c, s; cossin(++k, n4, c, s);
+      Real vi = *(++v); Real wi = *(--w);
+      *(++x) = vi * c + wi * s; *(++y) = vi * s - wi * c;
+   }
+   ColumnVector A; RealFFTI(X, Y, A);
+   X.CleanUp(); Y.CleanUp(); U.ReSize(n);
+   Real* a = A.Store(); Real* b = a + n; Real* u = U.Store();
+   i = n2;
+   while (i--) { *u++ = *a++; *u++ = *(--b); }
+}
+
+void DST_II(const ColumnVector& U, ColumnVector& V)
+{
+   // Discrete sine transform, type II, of a real series
+   Tracer trace("DST_II");
+   REPORT
+   const int n = U.Nrows();                     // length of arrays
+   const int n2 = n / 2; const int n4 = n * 4;
+   if (n != 2 * n2)
+      Throw(ProgramException("Vector length not multiple of 2", U));
+   ColumnVector A(n);
+   Real* a = A.Store(); Real* b = a + n; Real* u = U.Store();
+   int i = n2;
+   while (i--) { *a++ = *u++; *(--b) = -(*u++); }
+   ColumnVector X, Y;
+   RealFFT(A, X, Y); A.CleanUp();
+   V.ReSize(n);
+   Real* x = X.Store(); Real* y = Y.Store();
+   Real* v = V.Store(); Real* w = v + n;
+   *(--w) = *x;
+   int k = 0; i = n2;
+   while (i--)
+   {
+      Real c, s; cossin(++k, n4, c, s);
+      Real xi = *(++x); Real yi = *(++y);
+      *v++ = xi * s - yi * c; *(--w) = xi * c + yi * s;
+   }
+}
+
+void DST_II_inverse(const ColumnVector& V, ColumnVector& U)
+{
+   // Inverse of discrete sine transform, type II
+   Tracer trace("DST_II_inverse");
+   REPORT
+   const int n = V.Nrows();                     // length of array
+   const int n2 = n / 2; const int n4 = n * 4; const int n21 = n2 + 1;
+   if (n != 2 * n2)
+      Throw(ProgramException("Vector length not multiple of 2", V));
+   ColumnVector X(n21), Y(n21);
+   Real* x = X.Store(); Real* y = Y.Store();
+   Real* v = V.Store(); Real* w = v + n;
+   *x = *(--w); *y = 0.0;
+   int i = n2; int k = 0;
+   while (i--)
+   {
+      Real c, s; cossin(++k, n4, c, s);
+      Real vi = *v++; Real wi = *(--w);
+      *(++x) = vi * s + wi * c; *(++y) = - vi * c + wi * s;
+   }
+   ColumnVector A; RealFFTI(X, Y, A);
+   X.CleanUp(); Y.CleanUp(); U.ReSize(n);
+   Real* a = A.Store(); Real* b = a + n; Real* u = U.Store();
+   i = n2;
+   while (i--) { *u++ = *a++; *u++ = -(*(--b)); }
+}
+
+void DCT_inverse(const ColumnVector& V, ColumnVector& U)
+{
+   // Inverse of discrete cosine transform, type I
+   Tracer trace("DCT_inverse");
+   REPORT
+   const int n = V.Nrows()-1;                     // length of transform
+   const int n2 = n / 2; const int n21 = n2 + 1;
+   if (n != 2 * n2)
+      Throw(ProgramException("Vector length not multiple of 2", V));
+   ColumnVector X(n21), Y(n21);
+   Real* x = X.Store(); Real* y = Y.Store(); Real* v = V.Store();
+   Real vi = *v++; *x++ = vi; *y++ = 0.0;
+   Real sum1 = vi / 2.0; Real sum2 = sum1; vi = *v++;
+   int i = n2-1;
+   while (i--)
+   {
+      Real vi2 = *v++; sum1 += vi2 + vi; sum2 += vi2 - vi;
+      *x++ = vi2; vi2 = *v++; *y++ = vi - vi2; vi = vi2;
+   }
+   sum1 += vi; sum2 -= vi;
+   vi = *v; *x = vi; *y = 0.0; vi /= 2.0; sum1 += vi; sum2 += vi;
+   ColumnVector A; RealFFTI(X, Y, A);
+   X.CleanUp(); Y.CleanUp(); U.ReSize(n+1);
+   Real* a = A.Store(); Real* b = a + n; Real* u = U.Store(); v = u + n;
+   i = n2; int k = 0; *u++ = sum1 / n2; *v-- = sum2 / n2;
+   while (i--)
+   {
+      Real s = sin(1.5707963267948966192 * (++k) / n2);
+      Real ai = *(++a); Real bi = *(--b);
+      Real bz = (ai - bi) / 4 / s; Real az = (ai + bi) / 2;
+      *u++ = az - bz; *v-- = az + bz;
+   }
+}
+
+void DCT(const ColumnVector& U, ColumnVector& V)
+{
+   // Discrete cosine transform, type I
+   Tracer trace("DCT");
+   REPORT
+   DCT_inverse(U, V);
+   V *= (V.Nrows()-1)/2;
+}
+
+void DST_inverse(const ColumnVector& V, ColumnVector& U)
+{
+   // Inverse of discrete sine transform, type I
+   Tracer trace("DST_inverse");
+   REPORT
+   const int n = V.Nrows()-1;                     // length of transform
+   const int n2 = n / 2; const int n21 = n2 + 1;
+   if (n != 2 * n2)
+      Throw(ProgramException("Vector length not multiple of 2", V));
+   ColumnVector X(n21), Y(n21);
+   Real* x = X.Store(); Real* y = Y.Store(); Real* v = V.Store();
+   Real vi = *(++v); *x++ = 2 * vi; *y++ = 0.0;
+   int i = n2-1;
+   while (i--) { *y++ = *(++v); Real vi2 = *(++v); *x++ = vi2 - vi; vi = vi2; }
+   *x = -2 * vi; *y = 0.0;
+   ColumnVector A; RealFFTI(X, Y, A);
+   X.CleanUp(); Y.CleanUp(); U.ReSize(n+1);
+   Real* a = A.Store(); Real* b = a + n; Real* u = U.Store(); v = u + n;
+   i = n2; int k = 0; *u++ = 0.0; *v-- = 0.0;
+   while (i--)
+   {
+      Real s = sin(1.5707963267948966192 * (++k) / n2);
+      Real ai = *(++a); Real bi = *(--b);
+      Real az = (ai + bi) / 4 / s; Real bz = (ai - bi) / 2;
+      *u++ = az - bz; *v-- = az + bz;
+   }
+}
+
+void DST(const ColumnVector& U, ColumnVector& V)
+{
+   // Discrete sine transform, type I
+   Tracer trace("DST");
+   REPORT
+   DST_inverse(U, V);
+   V *= (V.Nrows()-1)/2;
+}
+
+// Two dimensional FFT
+void FFT2(const Matrix& U, const Matrix& V, Matrix& X, Matrix& Y)
+{
+   Tracer trace("FFT2");
+   REPORT
+   int m = U.Nrows(); int n = U.Ncols();
+   if (m != V.Nrows() || n != V.Ncols() || m == 0 || n == 0)
+      Throw(ProgramException("Matrix dimensions unequal or zero", U, V));
+   X = U; Y = V;
+   int i; ColumnVector CVR; ColumnVector CVI;
+   for (i = 1; i <= m; ++i)
+   {
+      FFT(X.Row(i).t(), Y.Row(i).t(), CVR, CVI);
+      X.Row(i) = CVR.t(); Y.Row(i) = CVI.t();
+   }
+   for (i = 1; i <= n; ++i)
+   {
+      FFT(X.Column(i), Y.Column(i), CVR, CVI);
+      X.Column(i) = CVR; Y.Column(i) = CVI;
+   }
+}
+
+void FFT2I(const Matrix& U, const Matrix& V, Matrix& X, Matrix& Y)
+{
+   // Inverse transform
+   Tracer trace("FFT2I");
+   REPORT
+   FFT2(U,-V,X,Y);
+   const Real n = X.Nrows() * X.Ncols(); X /= n; Y /= (-n);
+}
+
+
+#ifdef use_namespace
+}
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/gnu.mak b/Utilities/OSSIM/ossim_core/matrix/gnu.mak
new file mode 100644
index 0000000000..e1cbb19e7f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/gnu.mak
@@ -0,0 +1,154 @@
+CXX = g++
+CXXFLAGS = -O2  -Wall
+
+everything:   libnewmat.a tmt example nl_ex sl_ex garch test_exc
+
+
+%.o:          %.cpp
+	      $(CXX) $(CXXFLAGS) -c $*.cpp
+
+OBJ_LIB = bandmat.o cholesky.o evalue.o fft.o hholder.o     \
+  jacobi.o myexcept.o newmat1.o newmat2.o newmat3.o         \
+  newmat4.o newmat5.o newmat6.o newmat7.o newmat8.o         \
+  newmat9.o newmatex.o newmatnl.o newmatrm.o solution.o     \
+  sort.o submat.o svd.o newfft.o
+
+libnewmat.a:	$(OBJ_LIB)
+	        $(AR) cr $@ $(OBJ_LIB)
+	        ranlib $@
+
+OBJ_T = tmt.o tmt1.o tmt2.o tmt3.o tmt4.o tmt5.o tmt6.o    \
+  tmt7.o tmt8.o tmt9.o tmta.o tmtb.o tmtc.o tmtd.o tmte.o  \
+  tmtf.o tmtg.o tmth.o tmti.o tmtj.o tmtk.o tmtl.o
+
+tmt:    	$(OBJ_T) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_T) -L. -lnewmat -lm
+
+OBJ_E = example.o
+
+example:    	$(OBJ_E) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_E) -L. -lnewmat -lm
+
+OBJ_N = nl_ex.o
+
+nl_ex:    	$(OBJ_N) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_N) -L. -lnewmat -lm
+
+OBJ_S = sl_ex.o
+
+sl_ex:    	$(OBJ_S) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_S) -L. -lnewmat -lm
+
+OBJ_G = garch.o
+
+garch:          $(OBJ_G) libnewmat.a
+	        $(CXX) -o $@ $(OBJ_G) -L. -lnewmat -lm
+
+OBJ_X = test_exc.o
+
+test_exc:	$(OBJ_X) libnewmat.a
+		$(CXX) -o $@ $(OBJ_X) -L. -lnewmat -lm	
+
+newmatxx = include.h newmat.h boolean.h myexcept.h
+
+myexcept.o:   include.h boolean.h myexcept.h myexcept.cpp
+
+newmatex.o:   $(newmatxx) newmatex.cpp
+
+newmatnl.o:   $(newmatxx) newmatnl.h newmatap.h
+
+example.o:    $(newmatxx) newmatap.h example.cpp
+
+cholesky.o:   $(newmatxx) cholesky.cpp
+
+evalue.o:     $(newmatxx) newmatrm.h precisio.h evalue.cpp
+
+fft.o:        $(newmatxx) newmatap.h fft.cpp
+
+hholder.o:    $(newmatxx) newmatap.h hholder.cpp
+
+jacobi.o:     $(newmatxx) precisio.h newmatrm.h jacobi.cpp
+
+bandmat.o:    $(newmatxx) newmatrc.h controlw.h bandmat.cpp
+
+newfft.o:     $(newmatxx) newmatap.h newfft.cpp
+
+newmat1.o:    $(newmatxx) newmat1.cpp
+
+newmat2.o:    $(newmatxx) newmatrc.h controlw.h newmat2.cpp
+
+newmat3.o:    $(newmatxx) newmatrc.h controlw.h newmat3.cpp
+
+newmat4.o:    $(newmatxx) newmatrc.h controlw.h newmat4.cpp
+
+newmat5.o:    $(newmatxx) newmatrc.h controlw.h newmat5.cpp
+
+newmat6.o:    $(newmatxx) newmatrc.h controlw.h newmat6.cpp
+
+newmat7.o:    $(newmatxx) newmatrc.h controlw.h newmat7.cpp
+
+newmat8.o:    $(newmatxx) newmatap.h newmat8.cpp
+
+newmat9.o:    $(newmatxx) newmatrc.h controlw.h newmatio.h newmat9.cpp
+
+newmatrm.o:   $(newmatxx) newmatrm.h newmatrm.cpp
+
+sort.o:       $(newmatxx) newmatap.h sort.cpp
+
+submat.o:     $(newmatxx) newmatrc.h controlw.h submat.cpp
+
+svd.o:        $(newmatxx) newmatrm.h precisio.h svd.cpp
+
+tmt.o:        $(newmatxx) newmatap.h tmt.cpp 
+
+tmt1.o:       $(newmatxx) newmatap.h tmt1.cpp 
+
+tmt2.o:       $(newmatxx) newmatap.h tmt2.cpp 
+
+tmt3.o:       $(newmatxx) newmatap.h tmt3.cpp 
+
+tmt4.o:       $(newmatxx) newmatap.h tmt4.cpp 
+
+tmt5.o:       $(newmatxx) newmatap.h tmt5.cpp 
+
+tmt6.o:       $(newmatxx) newmatap.h tmt6.cpp 
+
+tmt7.o:       $(newmatxx) newmatap.h tmt7.cpp 
+
+tmt8.o:       $(newmatxx) newmatap.h tmt8.cpp 
+
+tmt9.o:       $(newmatxx) newmatap.h tmt9.cpp 
+
+tmta.o:       $(newmatxx) newmatap.h tmta.cpp 
+
+tmtb.o:       $(newmatxx) newmatap.h tmtb.cpp 
+
+tmtc.o:       $(newmatxx) newmatap.h tmtc.cpp 
+
+tmtd.o:       $(newmatxx) newmatap.h tmtd.cpp 
+
+tmte.o:       $(newmatxx) newmatap.h tmte.cpp 
+
+tmtf.o:       $(newmatxx) newmatap.h tmtf.cpp 
+
+tmtg.o:       $(newmatxx) newmatap.h tmtg.cpp 
+
+tmth.o:       $(newmatxx) newmatap.h tmth.cpp
+
+tmti.o:       $(newmatxx) newmatap.h tmti.cpp
+
+tmtj.o:       $(newmatxx) newmatap.h tmtj.cpp
+
+tmtk.o:       $(newmatxx) newmatap.h tmtk.cpp
+
+tmtl.o:       $(newmatxx) newmatap.h tmtl.cpp
+
+nl_ex.o:      $(newmatxx) newmatap.h newmatnl.h nl_ex.cpp
+
+sl_ex.o:      include.h boolean.h myexcept.h sl_ex.cpp
+
+solution.o:   include.h boolean.h myexcept.h solution.cpp
+
+garch.o:      $(newmatxx) newmatap.h newmatnl.h garch.cpp
+
+test_exc.o:   $(newmatxx) test_exc.cpp
diff --git a/Utilities/OSSIM/ossim_core/matrix/hholder.cpp b/Utilities/OSSIM/ossim_core/matrix/hholder.cpp
new file mode 100644
index 0000000000..1e8a2ac01a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/hholder.cpp
@@ -0,0 +1,331 @@
+//$$ hholder.cpp                                   QR decomposition
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#define WANT_MATH
+//#define WANT_STREAM
+
+#include "include.h"
+
+#include "newmatap.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,16); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+/*************************** QR decompositions ***************************/
+
+inline Real square(Real x) { return x*x; }
+
+void QRZT(Matrix& X, LowerTriangularMatrix& L)
+{
+   REPORT
+	 Tracer et("QRZT(1)");
+   int n = X.Ncols(); int s = X.Nrows(); L.ReSize(s);
+   Real* xi = X.Store(); int k;
+   for (int i=0; i<s; i++)
+   {
+      Real sum = 0.0;
+      Real* xi0=xi; k=n; while(k--) { sum += square(*xi++); }
+      sum = sqrt(sum);
+      if (sum == 0.0)
+      {
+         REPORT
+         k=n; while(k--) { *xi0++ = 0.0; }
+         for (int j=i; j<s; j++) L.element(j,i) = 0.0;
+      }
+      else
+      {
+         L.element(i,i) = sum;
+         Real* xj0=xi0; k=n; while(k--) { *xj0++ /= sum; }
+         for (int j=i+1; j<s; j++)
+         {
+            sum=0.0;
+            xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; }
+            xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; }
+            L.element(j,i) = sum;
+         }
+      }
+   }
+}
+
+void QRZT(const Matrix& X, Matrix& Y, Matrix& M)
+{
+   REPORT
+   Tracer et("QRZT(2)");
+   int n = X.Ncols(); int s = X.Nrows(); int t = Y.Nrows();
+   if (Y.Ncols() != n)
+      { Throw(ProgramException("Unequal row lengths",X,Y)); }
+   M.ReSize(t,s);
+   Real* xi = X.Store(); int k;
+   for (int i=0; i<s; i++)
+   {
+      Real* xj0 = Y.Store(); Real* xi0 = xi;
+      for (int j=0; j<t; j++)
+      {
+         Real sum=0.0;
+         xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; }
+         xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; }
+         M.element(j,i) = sum;
+      }
+   }
+}
+
+/*
+void QRZ(Matrix& X, UpperTriangularMatrix& U)
+{
+	Tracer et("QRZ(1)");
+	int n = X.Nrows(); int s = X.Ncols(); U.ReSize(s);
+	Real* xi0 = X.Store(); int k;
+	for (int i=0; i<s; i++)
+	{
+		Real sum = 0.0;
+		Real* xi = xi0; k=n; while(k--) { sum += square(*xi); xi+=s; }
+		sum = sqrt(sum);
+		U.element(i,i) = sum;
+		if (sum==0.0) Throw(SingularException(U));
+		Real* xj0=xi0; k=n; while(k--) { *xj0 /= sum; xj0+=s; }
+		xj0 = xi0;
+		for (int j=i+1; j<s; j++)
+		{
+			sum=0.0;
+			xi=xi0; k=n; xj0++; Real* xj=xj0;
+			while(k--) { sum += *xi * *xj; xi+=s; xj+=s; }
+			xi=xi0; k=n; xj=xj0;
+			while(k--) { *xj -= sum * *xi; xj+=s; xi+=s; }
+			U.element(i,j) = sum;
+		}
+		xi0++;
+	}
+}
+*/
+
+void QRZ(Matrix& X, UpperTriangularMatrix& U)
+{
+   REPORT
+   Tracer et("QRZ(1)");
+   int n = X.Nrows(); int s = X.Ncols(); U.ReSize(s); U = 0.0;
+   Real* xi0 = X.Store(); Real* u0 = U.Store(); Real* u;
+   int j, k; int J = s; int i = s;
+   while (i--)
+   {
+      Real* xj0 = xi0; Real* xi = xi0; k = n;
+      if (k) for (;;)
+      {
+         u = u0; Real Xi = *xi; Real* xj = xj0;
+         j = J; while(j--) *u++ += Xi * *xj++;
+         if (!(--k)) break;
+         xi += s; xj0 += s;
+      }
+
+      Real sum = sqrt(*u0); *u0 = sum; u = u0+1;
+      if (sum == 0.0)
+      {
+         REPORT
+         j = J - 1; while(j--) *u++ = 0.0;
+
+         xj0 = xi0++; k = n;
+         if (k) for (;;)
+         {
+            *xj0 = 0.0;
+            if (!(--k)) break;
+	          xj0 += s;
+         }
+         u0 += J--;
+      }
+      else
+      {
+         int J1 = J-1; j = J1; while(j--) *u++ /= sum;
+
+         xj0 = xi0; xi = xi0++; k = n;
+         if (k) for (;;)
+         {
+            u = u0+1; Real Xi = *xi; Real* xj = xj0;
+            Xi /= sum; *xj++ = Xi;
+            j = J1; while(j--) *xj++ -= *u++ * Xi;
+            if (!(--k)) break;
+	          xi += s; xj0 += s;
+         }
+         u0 += J--;
+      }
+   }
+}
+
+void QRZ(const Matrix& X, Matrix& Y, Matrix& M)
+{
+   REPORT
+   Tracer et("QRZ(2)");
+   int n = X.Nrows(); int s = X.Ncols(); int t = Y.Ncols();
+   if (Y.Nrows() != n)
+      { Throw(ProgramException("Unequal column lengths",X,Y)); }
+   M.ReSize(s,t); M = 0;Real* m0 = M.Store(); Real* m;
+   Real* xi0 = X.Store();
+   int j, k; int i = s;
+   while (i--)
+   {
+      Real* xj0 = Y.Store(); Real* xi = xi0; k = n;
+      if (k) for (;;)
+      {
+         m = m0; Real Xi = *xi; Real* xj = xj0;
+         j = t; while(j--) *m++ += Xi * *xj++;
+         if (!(--k)) break;
+         xi += s; xj0 += t;
+      }
+
+      xj0 = Y.Store(); xi = xi0++; k = n;
+      if (k) for (;;)
+      {
+         m = m0; Real Xi = *xi; Real* xj = xj0;
+         j = t; while(j--) *xj++ -= *m++ * Xi;
+         if (!(--k)) break;
+         xi += s; xj0 += t;
+      }
+      m0 += t;
+   }
+}
+
+/*
+
+void QRZ(const Matrix& X, Matrix& Y, Matrix& M)
+{
+	Tracer et("QRZ(2)");
+	int n = X.Nrows(); int s = X.Ncols(); int t = Y.Ncols();
+	if (Y.Nrows() != n)
+	{ Throw(ProgramException("Unequal column lengths",X,Y)); }
+	M.ReSize(s,t);
+	Real* xi0 = X.Store(); int k;
+	for (int i=0; i<s; i++)
+	{
+		Real* xj0 = Y.Store();
+		for (int j=0; j<t; j++)
+		{
+			Real sum=0.0;
+			Real* xi=xi0; Real* xj=xj0; k=n;
+			while(k--) { sum += *xi * *xj; xi+=s; xj+=t; }
+			xi=xi0; k=n; xj=xj0++;
+			while(k--) { *xj -= sum * *xi; xj+=t; xi+=s; }
+			M.element(i,j) = sum;
+		}
+		xi0++;
+	}
+}
+*/
+
+void UpdateQRZT(Matrix& X, LowerTriangularMatrix& L)
+{
+   REPORT
+	 Tracer et("UpdateQRZT");
+   int n = X.Ncols(); int s = X.Nrows();
+   if (s != L.Nrows())
+      Throw(ProgramException("Incompatible dimensions",X,L)); 
+   Real* xi = X.Store(); int k;
+   for (int i=0; i<s; i++)
+   {
+      Real r = L.element(i,i); 
+      Real sum = 0.0;
+      Real* xi0=xi; k=n; while(k--) { sum += square(*xi++); }
+      sum = sqrt(sum + square(r));
+      if (sum == 0.0)
+      {
+         REPORT
+         k=n; while(k--) { *xi0++ = 0.0; }
+         for (int j=i; j<s; j++) L.element(j,i) = 0.0;
+      }
+      else
+      {
+         Real frs = fabs(r) + sum;
+         Real a0 = sqrt(frs / sum); Real alpha = a0 / frs;
+         if (r <= 0) { REPORT L.element(i,i) = sum; alpha = -alpha; }
+         else { REPORT L.element(i,i) = -sum; }
+         Real* xj0=xi0; k=n; while(k--) { *xj0++ *= alpha; }
+         for (int j=i+1; j<s; j++)
+         {
+            sum = 0.0;
+            xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; }
+            sum += a0 * L.element(j,i);
+            xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; }
+            L.element(j,i) -= sum * a0;
+         }
+      }
+   }
+}
+
+void UpdateQRZ(Matrix& X, UpperTriangularMatrix& U)
+{
+   REPORT
+   Tracer et("UpdateQRZ");
+   int n = X.Nrows(); int s = X.Ncols();
+   if (s != U.Ncols())
+      Throw(ProgramException("Incompatible dimensions",X,U)); 
+   Real* xi0 = X.Store(); Real* u0 = U.Store(); Real* u;
+   RowVector V(s); Real* v0 = V.Store(); Real* v; V = 0.0;
+   int j, k; int J = s; int i = s;
+   while (i--)
+   {
+      Real* xj0 = xi0; Real* xi = xi0; k = n;
+      if (k) for (;;)
+      {
+         v = v0; Real Xi = *xi; Real* xj = xj0;
+         j = J; while(j--) *v++ += Xi * *xj++;
+         if (!(--k)) break;
+         xi += s; xj0 += s;
+      }
+
+      Real r = *u0;
+      Real sum = sqrt(*v0 + square(r));
+      
+      if (sum == 0.0)
+      {
+         REPORT
+         u = u0; v = v0;
+         j = J; while(j--) { *u++ = 0.0; *v++ = 0.0; }
+         xj0 = xi0++; k = n;
+         if (k) for (;;)
+         {
+            *xj0 = 0.0;
+            if (!(--k)) break;
+	          xj0 += s;
+         }
+         u0 += J--;
+      }
+      else
+      {
+         Real frs = fabs(r) + sum;
+         Real a0 = sqrt(frs / sum); Real alpha = a0 / frs;
+         if (r <= 0) { REPORT alpha = -alpha; *u0 = sum; }
+         else { REPORT *u0 = -sum; }
+      
+         j = J - 1; v = v0 + 1; u = u0 + 1;     
+         while (j--)
+            { *v = a0 * *u + alpha * *v; *u -= a0 * *v; ++v; ++u; }
+
+         xj0 = xi0; xi = xi0++; k = n;
+         if (k) for (;;)
+         {
+            v = v0 + 1; Real Xi = *xi; Real* xj = xj0;
+            Xi *= alpha; *xj++ = Xi;
+            j = J - 1; while(j--) *xj++ -= *v++ * Xi;
+            if (!(--k)) break;
+	          xi += s; xj0 += s;
+         }
+         
+         j = J; v = v0;
+         while (j--) *v++ = 0.0;
+         
+         u0 += J--;
+      }
+   }
+}
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/include.h b/Utilities/OSSIM/ossim_core/matrix/include.h
new file mode 100644
index 0000000000..5b71e266e3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/include.h
@@ -0,0 +1,313 @@
+//$$ include.h           include files required by various versions of C++
+
+#ifndef INCLUDE_LIB
+#define INCLUDE_LIB
+#define use_namespace                   // define name spaces
+#include <base/common/ossimConstants.h>
+#define SETUP_C_SUBSCRIPTS              // allow element access via A[i][j]
+
+// Activate just one of the following 3 statements
+
+//#define SimulateExceptions              // use simulated exceptions
+//#define UseExceptions                   // use C++ exceptions
+#define DisableExceptions               // do not use exceptions
+
+
+//#define TEMPS_DESTROYED_QUICKLY         // for compilers that delete
+					// temporaries too quickly
+
+//#define TEMPS_DESTROYED_QUICKLY_R       // the same thing but applied
+					// to return from functions only
+
+//#define DO_FREE_CHECK                   // check news and deletes balance
+
+#define USING_DOUBLE                    // elements of type double
+//#define USING_FLOAT                   // elements of type float
+
+#define bool_LIB 0                      // for compatibility with my older libraries
+
+//#define ios_format_flags ios::fmtflags  // for Gnu 3 and Intel for Linux
+
+
+//#define _STANDARD_                    // using standard library
+
+//#define use_float_h                   // use float.h for precision data
+
+
+//#define HAS_INT64                     // if unsigned _int64 is recognised
+                                        // used by newran03
+
+// comment out next line if Exception causes a problem
+#define TypeDefException
+
+//*********************** end of options set by user ********************
+
+
+// for Gnu C++ version 3
+#if defined __GNUG__ && __GNUG__ >= 3
+   #define _STANDARD_                   // use standard library
+   #define ios_format_flags ios::fmtflags
+#endif
+
+// for Intel C++ for Linux
+#if defined __ICC
+   #define _STANDARD_                   // use standard library
+   #define ios_format_flags ios::fmtflags
+#endif
+
+#ifdef __BORLANDC__
+#define _STANDARD_
+#endif
+
+#ifdef _STANDARD_                       // using standard library
+   #include <cstdlib>
+   #ifdef _MSC_VER
+      #include <limits>                 // for VC++6
+   #endif
+   #ifdef WANT_STREAM
+      #include <iostream>
+      #include <iomanip>
+   #endif
+   #ifdef WANT_MATH
+      #include <cmath>
+   #endif
+   #ifdef WANT_STRING
+      #include <cstring>
+   #endif
+   #ifdef WANT_TIME
+      #include <ctime>
+   #endif
+   #ifdef WANT_FSTREAM
+      #include <fstream>
+   #endif
+   using namespace std;
+#else
+
+#define DEFAULT_HEADER                  // use AT&T style header
+                                        // if no other compiler is recognised
+
+#ifdef _MSC_VER                         // Microsoft
+   #include <stdlib.h>
+
+  // reactivate these statements to run under MSC version 7.0
+//   typedef int jmp_buf[9];
+//   extern "C"
+//   {
+//      int __cdecl setjmp(jmp_buf);
+//      void __cdecl longjmp(jmp_buf, int);
+//   }
+
+   #ifdef WANT_STREAM
+      #include <iostream>
+      #include <iomanip>
+   #endif
+   #ifdef WANT_MATH
+      #include <math.h>
+      #include <float.h>
+   #endif
+   #ifdef WANT_STRING
+      #include <string.h>
+   #endif
+   #ifdef WANT_TIME
+      #include <time.h>
+   #endif
+   #ifdef WANT_FSTREAM
+      #include <fstream.h>
+   #endif
+   #undef DEFAULT_HEADER
+#endif
+
+#ifdef __ZTC__                          // Zortech
+   #include <stdlib.h>
+   #ifdef WANT_STREAM
+      #include <iostream.hpp>
+      #include <iomanip.hpp>
+      #define flush ""                  // not defined in iomanip?
+   #endif
+   #ifdef WANT_MATH
+      #include <math.h>
+      #include <float.h>
+   #endif
+   #ifdef WANT_STRING
+      #include <string.h>
+   #endif
+   #ifdef WANT_TIME
+      #include <time.h>
+   #endif
+   #ifdef WANT_FSTREAM
+      #include <fstream.h>
+   #endif
+   #undef DEFAULT_HEADER
+#endif
+
+#if defined __BCPLUSPLUS__ || defined __TURBOC__  // Borland or Turbo
+   #include <stdlib.h>
+   #ifdef WANT_STREAM
+      #include <iostream.h>
+      #include <iomanip.h>
+   #endif
+   #ifdef WANT_MATH
+      #include <math.h>
+      #include <float.h>            // Borland has both float and values
+                                    // but values.h returns +INF for
+                                    // MAXDOUBLE in BC5
+   #endif
+   #ifdef WANT_STRING
+      #include <string.h>
+   #endif
+   #ifdef WANT_TIME
+      #include <time.h>
+   #endif
+   #ifdef WANT_FSTREAM
+      #include <fstream.h>
+   #endif
+   #undef DEFAULT_HEADER
+#endif
+
+#ifdef __GNUG__                         // Gnu C++
+   #include <stdlib.h>
+   #ifdef WANT_STREAM
+      #include <iostream.h>
+      #include <iomanip.h>
+   #endif
+   #ifdef WANT_MATH
+      #include <math.h>
+      #include <float.h>
+   #endif
+   #ifdef WANT_STRING
+      #include <string.h>
+   #endif
+   #ifdef WANT_TIME
+      #include <time.h>
+   #endif
+   #ifdef WANT_FSTREAM
+      #include <fstream.h>
+   #endif
+   #undef DEFAULT_HEADER
+#endif
+
+#ifdef __WATCOMC__                      // Watcom C/C++
+   #include <stdlib.h>
+   #ifdef WANT_STREAM
+      #include <iostream.h>
+      #include <iomanip.h>
+   #endif
+   #ifdef WANT_MATH
+      #include <math.h>
+      #include <float.h>
+   #endif
+   #ifdef WANT_STRING
+      #include <string.h>
+   #endif
+   #ifdef WANT_TIME
+      #include <time.h>
+   #endif
+   #ifdef WANT_FSTREAM
+      #include <fstream.h>
+   #endif
+   #undef DEFAULT_HEADER
+#endif
+
+
+#ifdef macintosh                        // MPW C++ on the Mac
+#include <stdlib.h>
+#ifdef WANT_STREAM
+#include <iostream.h>
+#include <iomanip.h>
+#endif
+#ifdef WANT_MATH
+#include <float.h>
+#include <math.h>
+#endif
+#ifdef WANT_STRING
+#include <string.h>
+#endif
+#ifdef WANT_TIME
+#include <time.h>
+#endif
+#ifdef WANT_FSTREAM
+#include <fstream.h>
+#endif
+#undef DEFAULT_HEADER
+#endif
+
+#ifdef use_float_h                      // use float.h for precision values
+#include <stdlib.h>
+#ifdef WANT_STREAM
+#include <iostream.h>
+#include <iomanip.h>
+#endif
+#ifdef WANT_MATH
+#include <float.h>
+#include <math.h>
+#endif
+#ifdef WANT_STRING
+#include <string.h>
+#endif
+#ifdef WANT_TIME
+#include <time.h>
+#endif
+#ifdef WANT_FSTREAM
+#include <fstream.h>
+#endif
+#undef DEFAULT_HEADER
+#endif
+
+
+#ifdef DEFAULT_HEADER                   // for example AT&T
+#define ATandT
+#include <stdlib.h>
+#ifdef WANT_STREAM
+#include <iostream.h>
+#include <iomanip.h>
+#endif
+#ifdef WANT_MATH
+#include <math.h>
+#define SystemV                         // use System V
+#include <values.h>
+#endif
+#ifdef WANT_STRING
+#include <string.h>
+#endif
+#ifdef WANT_TIME
+#include <time.h>
+#endif
+#ifdef WANT_FSTREAM
+#include <fstream.h>
+#endif
+#endif                                  // DEFAULT_HEADER
+
+#endif                                  // _STANDARD_
+
+#ifdef use_namespace
+namespace RBD_COMMON {
+#endif
+
+
+#ifdef USING_FLOAT                      // set precision type to float
+typedef float Real;
+typedef double long_Real;
+#endif
+
+#ifdef USING_DOUBLE                     // set precision type to double
+typedef double Real;
+//typedef long double long_Real;
+typedef double long_Real;
+#endif
+
+
+#ifdef use_namespace
+}
+#endif
+
+
+#ifdef use_namespace
+namespace RBD_COMMON {}
+namespace RBD_LIBRARIES                 // access all my libraries
+{
+   using namespace RBD_COMMON;
+}
+#endif
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/matrix/jacobi.cpp b/Utilities/OSSIM/ossim_core/matrix/jacobi.cpp
new file mode 100644
index 0000000000..fc4b7661ff
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/jacobi.cpp
@@ -0,0 +1,123 @@
+//$$jacobi.cpp                           jacobi eigenvalue analysis
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+
+//#define WANT_STREAM
+
+
+#define WANT_MATH
+
+#include "include.h"
+#include "newmatap.h"
+#include "precisio.h"
+#include "newmatrm.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,18); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+void Jacobi(const SymmetricMatrix& X, DiagonalMatrix& D, SymmetricMatrix& A,
+   Matrix& V, bool eivec)
+{
+   Real epsilon = FloatingPointPrecision::Epsilon();
+   Tracer et("Jacobi");
+   REPORT
+   int n = X.Nrows(); DiagonalMatrix B(n), Z(n); D.ReSize(n); A = X;
+   if (eivec) { REPORT V.ReSize(n,n); D = 1.0; V = D; }
+   B << A; D = B; Z = 0.0; A.Inject(Z);
+   bool converged = false;
+   for (int i=1; i<=50; i++)
+   {
+      Real sm=0.0; Real* a = A.Store(); int p = A.Storage();
+      while (p--) sm += fabs(*a++);            // have previously zeroed diags
+      if (sm==0.0) { REPORT converged = true; break; }
+      Real tresh = (i<4) ? 0.2 * sm / square(n) : 0.0; a = A.Store();
+      for (p = 0; p < n; p++)
+      {
+         Real* ap1 = a + (p*(p+1))/2;
+         Real& zp = Z.element(p); Real& dp = D.element(p);
+         for (int q = p+1; q < n; q++)
+         {
+            Real* ap = ap1; Real* aq = a + (q*(q+1))/2;
+            Real& zq = Z.element(q); Real& dq = D.element(q);
+            Real& apq = A.element(q,p);
+            Real g = 100 * fabs(apq); Real adp = fabs(dp); Real adq = fabs(dq);
+
+            if (i>4 && g < epsilon*adp && g < epsilon*adq) { REPORT apq = 0.0; }
+            else if (fabs(apq) > tresh)
+            {
+               REPORT
+               Real t; Real h = dq - dp; Real ah = fabs(h);
+               if (g < epsilon*ah) { REPORT t = apq / h; }
+               else
+               {
+                  REPORT
+                  Real theta = 0.5 * h / apq;
+                  t = 1.0 / ( fabs(theta) + sqrt(1.0 + square(theta)) );
+                  if (theta<0.0) { REPORT t = -t; }
+               }
+               Real c = 1.0 / sqrt(1.0 + square(t)); Real s = t * c;
+               Real tau = s / (1.0 + c); h = t * apq;
+               zp -= h; zq += h; dp -= h; dq += h; apq = 0.0;
+               int j = p;
+               while (j--)
+               {
+                  g = *ap; h = *aq;
+                  *ap++ = g-s*(h+g*tau); *aq++ = h+s*(g-h*tau);
+               }
+               int ip = p+1; j = q-ip; ap += ip++; aq++;
+               while (j--)
+               {
+                  g = *ap; h = *aq;
+                  *ap = g-s*(h+g*tau); *aq++ = h+s*(g-h*tau);
+                  ap += ip++;
+               }
+               if (q < n-1)             // last loop is non-empty
+               {
+                  int iq = q+1; j = n-iq; ap += ip++; aq += iq++;
+                  for (;;)
+                  {
+                     g = *ap; h = *aq;
+                     *ap = g-s*(h+g*tau); *aq = h+s*(g-h*tau);
+                     if (!(--j)) break;
+                     ap += ip++; aq += iq++;
+                  }
+               }
+               if (eivec)
+               {
+                  REPORT
+                  RectMatrixCol VP(V,p); RectMatrixCol VQ(V,q);
+                  Rotate(VP, VQ, tau, s);
+               }
+            }
+         }
+      }
+      B = B + Z; D = B; Z = 0.0;
+   }
+   if (!converged) Throw(ConvergenceException(X));
+   if (eivec) SortSV(D, V, true);
+   else SortAscending(D);
+}
+
+void Jacobi(const SymmetricMatrix& X, DiagonalMatrix& D)
+{ REPORT SymmetricMatrix A; Matrix V; Jacobi(X,D,A,V,false); }
+
+void Jacobi(const SymmetricMatrix& X, DiagonalMatrix& D, SymmetricMatrix& A)
+{ REPORT Matrix V; Jacobi(X,D,A,V,false); }
+
+void Jacobi(const SymmetricMatrix& X, DiagonalMatrix& D, Matrix& V)
+{ REPORT SymmetricMatrix A; Jacobi(X,D,A,V,true); }
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/ms.mak b/Utilities/OSSIM/ossim_core/matrix/ms.mak
new file mode 100644
index 0000000000..398e95ddba
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/ms.mak
@@ -0,0 +1,201 @@
+.SUFFIXES: .cpp
+
+
+everything:   tmt.exe example.exe nl_ex.exe sl_ex.exe garch.exe test_exc.exe
+
+.cpp.obj:
+	      cl -AL -c  $*.cpp
+
+OBJ_LIB = bandmat.obj cholesky.obj evalue.obj fft.obj hholder.obj     \
+  jacobi.obj myexcept.obj newmat1.obj newmat2.obj newmat3.obj         \
+  newmat4.obj newmat5.obj newmat6.obj newmat7.obj newmat8.obj         \
+  newmat9.obj newmatex.obj newmatnl.obj newmatrm.obj solution.obj     \
+  sort.obj submat.obj svd.obj newfft.obj
+
+OBJ_T = tmt.obj tmt1.obj tmt2.obj tmt3.obj tmt4.obj tmt5.obj tmt6.obj      \
+  tmt7.obj tmt8.obj tmt9.obj tmta.obj tmtb.obj tmtc.obj tmtd.obj tmte.obj  \
+  tmtf.obj tmtg.obj tmth.obj tmti.obj tmtj.obj tmtk.obj tmtl.obj
+
+tmt.exe:    	$(OBJ_T) $(OBJ_LIB)
+	        echo newmat1.obj+newmat2.obj+newmat3.obj+    > link.lnk
+	        echo newmat4.obj+svd.obj+newmat5.obj+       >> link.lnk
+	        echo newmat6.obj+newmat7.obj+newmat8.obj+   >> link.lnk
+	        echo tmt.obj+tmt1.obj+tmt2.obj+tmt3.obj+    >> link.lnk
+	        echo tmt4.obj+tmt5.obj+tmt6.obj+tmt7.obj+   >> link.lnk
+	        echo tmt8.obj+tmt9.obj+tmta.obj+tmti.obj+   >> link.lnk
+	        echo tmtb.obj+tmtc.obj+tmtd.obj+tmte.obj+   >> link.lnk
+	        echo tmtf.obj+tmtg.obj+tmth.obj+tmtj.obj+   >> link.lnk
+	        echo tmtk.obj+tmtl.obj+                     >> link.lnk
+	        echo cholesky.obj+hholder.obj+sort.obj+     >> link.lnk
+	        echo submat.obj+jacobi.obj+newmatrm.obj+    >> link.lnk
+	        echo fft.obj+evalue.obj+bandmat.obj+        >> link.lnk
+	        echo newmatex.obj+myexcept.obj+newfft.obj,  >> link.lnk
+	        echo tmt.exe;                               >> link.lnk
+                link @link.lnk
+
+OBJ_E = example.obj
+
+example.exe:    $(OBJ_E) $(OBJ_LIB)
+	        echo newmat1.obj+newmat2.obj+newmat3.obj+    > link.lnk
+	        echo newmat4.obj+svd.obj+newmat5.obj+       >> link.lnk
+	        echo newmat6.obj+newmat7.obj+newmat8.obj+   >> link.lnk
+	        echo cholesky.obj+hholder.obj+sort.obj+     >> link.lnk
+	        echo submat.obj+jacobi.obj+newmatrm.obj+    >> link.lnk
+	        echo fft.obj+evalue.obj+bandmat.obj+        >> link.lnk
+	        echo newmatex.obj+myexcept.obj+newmat9+     >> link.lnk
+                echo newfft.obj+example.obj,                >> link.lnk
+	        echo example.exe;                           >> link.lnk
+                link @link.lnk
+
+OBJ_N = nl_ex.obj
+
+nl_ex.exe:    	$(OBJ_N) $(OBJ_LIB)
+	        echo newmat1.obj+newmat2.obj+newmat3.obj+    > link.lnk
+	        echo newmat4.obj+svd.obj+newmat5.obj+       >> link.lnk
+	        echo newmat6.obj+newmat7.obj+newmat8.obj+   >> link.lnk
+	        echo cholesky.obj+hholder.obj+sort.obj+     >> link.lnk
+	        echo submat.obj+jacobi.obj+newmatrm.obj+    >> link.lnk
+	        echo fft.obj+evalue.obj+bandmat.obj+        >> link.lnk
+	        echo newmatex.obj+myexcept.obj+newmat9.obj+ >> link.lnk
+                echo newmatnl.obj+nl_ex.obj+newfft.obj,     >> link.lnk
+	        echo nl_ex.exe;                             >> link.lnk
+                link @link.lnk
+
+OBJ_S = sl_ex.obj
+
+sl_ex.exe:    	$(OBJ_S) $(OBJ_LIB)
+	        echo solution.obj+myexcept.obj+sl_ex.obj,    > link.lnk
+	        echo sl_ex.exe;                             >> link.lnk
+                link @link.lnk
+
+OBJ_G = garch.obj
+
+garch.exe:      $(OBJ_G) $(OBJ_LIB)
+	        echo newmat1.obj+newmat2.obj+newmat3.obj+    > link.lnk
+	        echo newmat4.obj+svd.obj+newmat5.obj+       >> link.lnk
+	        echo newmat6.obj+newmat7.obj+newmat8.obj+   >> link.lnk
+	        echo cholesky.obj+hholder.obj+sort.obj+     >> link.lnk
+	        echo submat.obj+jacobi.obj+newmatrm.obj+    >> link.lnk
+	        echo fft.obj+evalue.obj+bandmat.obj+        >> link.lnk
+	        echo newmatex.obj+myexcept.obj+newmat9.obj+ >> link.lnk
+                echo newmatnl.obj+garch.obj+newfft.obj,     >> link.lnk
+	        echo garch.exe;                             >> link.lnk
+                link @link.lnk
+
+OBJ_X = test_exc.obj
+
+test_exc.exe:	$(OBJ_X) $(OBJ_LIB)
+	        echo newmat1.obj+newmat2.obj+newmat3.obj+    > link.lnk
+	        echo newmat4.obj+svd.obj+newmat5.obj+       >> link.lnk
+	        echo newmat6.obj+newmat7.obj+newmat8.obj+   >> link.lnk
+	        echo cholesky.obj+hholder.obj+sort.obj+     >> link.lnk
+	        echo submat.obj+jacobi.obj+newmatrm.obj+    >> link.lnk
+	        echo fft.obj+evalue.obj+bandmat.obj+        >> link.lnk
+	        echo newmatex.obj+myexcept.obj+newmat9.obj+ >> link.lnk
+                echo test_exc.obj+newfft.obj,               >> link.lnk
+	        echo test_exc.exe;                          >> link.lnk
+                link @link.lnk
+
+newmatxx = include.h newmat.h boolean.h myexcept.h
+
+myexcept.obj:   include.h boolean.h myexcept.h myexcept.cpp
+
+newmatex.obj:   $(newmatxx) newmatex.cpp
+
+newmatnl.obj:   $(newmatxx) newmatnl.h newmatap.h
+
+example.obj:    $(newmatxx) newmatap.h example.cpp
+
+cholesky.obj:   $(newmatxx) cholesky.cpp
+
+evalue.obj:     $(newmatxx) newmatrm.h precisio.h evalue.cpp
+
+fft.obj:        $(newmatxx) newmatap.h fft.cpp
+
+newfft.obj:     $(newmatxx) newmatap.h newfft.cpp
+
+hholder.obj:    $(newmatxx) newmatap.h hholder.cpp
+
+jacobi.obj:     $(newmatxx) precisio.h newmatrm.h jacobi.cpp
+
+bandmat.obj:    $(newmatxx) newmatrc.h controlw.h bandmat.cpp
+
+newmat1.obj:    $(newmatxx) newmat1.cpp
+
+newmat2.obj:    $(newmatxx) newmatrc.h controlw.h newmat2.cpp
+
+newmat3.obj:    $(newmatxx) newmatrc.h controlw.h newmat3.cpp
+
+newmat4.obj:    $(newmatxx) newmatrc.h controlw.h newmat4.cpp
+
+newmat5.obj:    $(newmatxx) newmatrc.h controlw.h newmat5.cpp
+
+newmat6.obj:    $(newmatxx) newmatrc.h controlw.h newmat6.cpp
+
+newmat7.obj:    $(newmatxx) newmatrc.h controlw.h newmat7.cpp
+
+newmat8.obj:    $(newmatxx) newmatap.h newmat8.cpp
+
+newmat9.obj:    $(newmatxx) newmatrc.h controlw.h newmatio.h newmat9.cpp
+
+newmatrm.obj:   $(newmatxx) newmatrm.h newmatrm.cpp
+
+sort.obj:       $(newmatxx) newmatap.h sort.cpp
+
+submat.obj:     $(newmatxx) newmatrc.h controlw.h submat.cpp
+
+svd.obj:        $(newmatxx) newmatrm.h precisio.h svd.cpp
+
+tmt.obj:        $(newmatxx) newmatap.h tmt.cpp 
+
+tmt1.obj:       $(newmatxx) newmatap.h tmt1.cpp 
+
+tmt2.obj:       $(newmatxx) newmatap.h tmt2.cpp 
+
+tmt3.obj:       $(newmatxx) newmatap.h tmt3.cpp 
+
+tmt4.obj:       $(newmatxx) newmatap.h tmt4.cpp 
+
+tmt5.obj:       $(newmatxx) newmatap.h tmt5.cpp 
+
+tmt6.obj:       $(newmatxx) newmatap.h tmt6.cpp 
+
+tmt7.obj:       $(newmatxx) newmatap.h tmt7.cpp 
+
+tmt8.obj:       $(newmatxx) newmatap.h tmt8.cpp 
+
+tmt9.obj:       $(newmatxx) newmatap.h tmt9.cpp 
+
+tmta.obj:       $(newmatxx) newmatap.h tmta.cpp 
+
+tmtb.obj:       $(newmatxx) newmatap.h tmtb.cpp 
+
+tmtc.obj:       $(newmatxx) newmatap.h tmtc.cpp 
+
+tmtd.obj:       $(newmatxx) newmatap.h tmtd.cpp 
+
+tmte.obj:       $(newmatxx) newmatap.h tmte.cpp 
+
+tmtf.obj:       $(newmatxx) newmatap.h tmtf.cpp 
+
+tmtg.obj:       $(newmatxx) newmatap.h tmtg.cpp 
+
+tmth.obj:       $(newmatxx) newmatap.h tmth.cpp
+
+tmti.obj:       $(newmatxx) newmatap.h tmti.cpp
+
+tmtj.obj:       $(newmatxx) newmatap.h tmtj.cpp
+
+tmtk.obj:       $(newmatxx) newmatap.h tmtk.cpp
+
+tmtl.obj:       $(newmatxx) newmatap.h tmtl.cpp
+
+nl_ex.obj:      $(newmatxx) newmatap.h newmatnl.h nl_ex.cpp
+
+sl_ex.obj:      include.h boolean.h myexcept.h sl_ex.cpp
+
+solution.obj:   include.h boolean.h myexcept.h solution.cpp
+
+garch.obj:      $(newmatxx) newmatap.h newmatnl.h garch.cpp
+
+test_exc.obj:   $(newmatxx) test_exc.cpp
diff --git a/Utilities/OSSIM/ossim_core/matrix/ms_nt.mak b/Utilities/OSSIM/ossim_core/matrix/ms_nt.mak
new file mode 100644
index 0000000000..1976a761af
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/ms_nt.mak
@@ -0,0 +1,151 @@
+!include <ntwin32.mak>
+
+.SUFFIXES: .cpp
+
+
+everything:   tmt.exe example.exe nl_ex.exe sl_ex.exe garch.exe test_exc.exe
+
+.cpp.obj:
+	      cl -c -W3 -Ox  $*.cpp
+
+OBJ_LIB = bandmat.obj cholesky.obj evalue.obj fft.obj hholder.obj     \
+  jacobi.obj myexcept.obj newmat1.obj newmat2.obj newmat3.obj         \
+  newmat4.obj newmat5.obj newmat6.obj newmat7.obj newmat8.obj         \
+  newmat9.obj newmatex.obj newmatnl.obj newmatrm.obj solution.obj     \
+  sort.obj submat.obj svd.obj newfft.obj
+
+OBJ_T = tmt.obj tmt1.obj tmt2.obj tmt3.obj tmt4.obj tmt5.obj tmt6.obj      \
+  tmt7.obj tmt8.obj tmt9.obj tmta.obj tmtb.obj tmtc.obj tmtd.obj tmte.obj  \
+  tmtf.obj tmtg.obj tmth.obj tmti.obj tmtj.obj tmtk.obj tmtl.obj
+
+tmt.exe:    	$(OBJ_T) $(OBJ_LIB)
+                link -OUT:tmt.exe $(conlflags) $(conlibs) $(OBJ_T) $(OBJ_LIB)
+
+OBJ_E = example.obj
+
+example.exe:    $(OBJ_E) $(OBJ_LIB)
+                link -OUT:example.exe $(conlflags) $(conlibs) $(OBJ_E) $(OBJ_LIB)
+
+OBJ_N = nl_ex.obj
+
+nl_ex.exe:    	$(OBJ_N) $(OBJ_LIB)
+                link -OUT:nl_ex.exe $(conlflags) $(conlibs) $(OBJ_N) $(OBJ_LIB)
+
+OBJ_S = sl_ex.obj
+
+sl_ex.exe:    	$(OBJ_S) $(OBJ_LIB)
+                link -OUT:sl_ex.exe $(conlflags) $(conlibs) $(OBJ_S) $(OBJ_LIB)
+
+OBJ_G = garch.obj
+
+garch.exe:      $(OBJ_G) $(OBJ_LIB)
+                link -OUT:garch.exe $(conlflags) $(conlibs) $(OBJ_G) $(OBJ_LIB)
+
+OBJ_X = test_exc.obj
+
+test_exc.exe:	$(OBJ_X) $(OBJ_LIB)
+		link -OUT:test_exc.exe $(conlflags) $(conlibs) $(OBJ_X) $(OBJ_LIB)	
+
+newmatxx = include.h newmat.h boolean.h myexcept.h
+
+myexcept.obj:   include.h boolean.h myexcept.h myexcept.cpp
+
+newmatex.obj:   $(newmatxx) newmatex.cpp
+
+newmatnl.obj:   $(newmatxx) newmatnl.h newmatap.h
+
+example.obj:    $(newmatxx) newmatap.h example.cpp
+
+cholesky.obj:   $(newmatxx) cholesky.cpp
+
+evalue.obj:     $(newmatxx) newmatrm.h precisio.h evalue.cpp
+
+fft.obj:        $(newmatxx) newmatap.h fft.cpp
+
+newfft.obj:     $(newmatxx) newmatap.h newfft.cpp
+
+hholder.obj:    $(newmatxx) newmatap.h hholder.cpp
+
+jacobi.obj:     $(newmatxx) precisio.h newmatrm.h jacobi.cpp
+
+bandmat.obj:    $(newmatxx) newmatrc.h controlw.h bandmat.cpp
+
+newmat1.obj:    $(newmatxx) newmat1.cpp
+
+newmat2.obj:    $(newmatxx) newmatrc.h controlw.h newmat2.cpp
+
+newmat3.obj:    $(newmatxx) newmatrc.h controlw.h newmat3.cpp
+
+newmat4.obj:    $(newmatxx) newmatrc.h controlw.h newmat4.cpp
+
+newmat5.obj:    $(newmatxx) newmatrc.h controlw.h newmat5.cpp
+
+newmat6.obj:    $(newmatxx) newmatrc.h controlw.h newmat6.cpp
+
+newmat7.obj:    $(newmatxx) newmatrc.h controlw.h newmat7.cpp
+
+newmat8.obj:    $(newmatxx) newmatap.h newmat8.cpp
+
+newmat9.obj:    $(newmatxx) newmatrc.h controlw.h newmatio.h newmat9.cpp
+
+newmatrm.obj:   $(newmatxx) newmatrm.h newmatrm.cpp
+
+sort.obj:       $(newmatxx) newmatap.h sort.cpp
+
+submat.obj:     $(newmatxx) newmatrc.h controlw.h submat.cpp
+
+svd.obj:        $(newmatxx) newmatrm.h precisio.h svd.cpp
+
+tmt.obj:        $(newmatxx) newmatap.h tmt.cpp 
+
+tmt1.obj:       $(newmatxx) newmatap.h tmt1.cpp 
+
+tmt2.obj:       $(newmatxx) newmatap.h tmt2.cpp 
+
+tmt3.obj:       $(newmatxx) newmatap.h tmt3.cpp 
+
+tmt4.obj:       $(newmatxx) newmatap.h tmt4.cpp 
+
+tmt5.obj:       $(newmatxx) newmatap.h tmt5.cpp 
+
+tmt6.obj:       $(newmatxx) newmatap.h tmt6.cpp 
+
+tmt7.obj:       $(newmatxx) newmatap.h tmt7.cpp 
+
+tmt8.obj:       $(newmatxx) newmatap.h tmt8.cpp 
+
+tmt9.obj:       $(newmatxx) newmatap.h tmt9.cpp 
+
+tmta.obj:       $(newmatxx) newmatap.h tmta.cpp 
+
+tmtb.obj:       $(newmatxx) newmatap.h tmtb.cpp 
+
+tmtc.obj:       $(newmatxx) newmatap.h tmtc.cpp 
+
+tmtd.obj:       $(newmatxx) newmatap.h tmtd.cpp 
+
+tmte.obj:       $(newmatxx) newmatap.h tmte.cpp 
+
+tmtf.obj:       $(newmatxx) newmatap.h tmtf.cpp 
+
+tmtg.obj:       $(newmatxx) newmatap.h tmtg.cpp 
+
+tmth.obj:       $(newmatxx) newmatap.h tmth.cpp
+
+tmti.obj:       $(newmatxx) newmatap.h tmti.cpp
+
+tmtj.obj:       $(newmatxx) newmatap.h tmtj.cpp
+
+tmtk.obj:       $(newmatxx) newmatap.h tmtk.cpp
+
+tmtl.obj:       $(newmatxx) newmatap.h tmtl.cpp
+
+nl_ex.obj:      $(newmatxx) newmatap.h newmatnl.h nl_ex.cpp
+
+sl_ex.obj:      include.h boolean.h myexcept.h sl_ex.cpp
+
+solution.obj:   include.h boolean.h myexcept.h solution.cpp
+
+garch.obj:      $(newmatxx) newmatap.h newmatnl.h garch.cpp
+
+test_exc.obj:   $(newmatxx) test_exc.cpp
diff --git a/Utilities/OSSIM/ossim_core/matrix/myexcept.cpp b/Utilities/OSSIM/ossim_core/matrix/myexcept.cpp
new file mode 100644
index 0000000000..8af60a6712
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/myexcept.cpp
@@ -0,0 +1,485 @@
+//$$myexcept.cpp                        Exception handler
+
+// Copyright (C) 1993,4,6: R B Davies
+
+
+#define WANT_STREAM                    // include.h will get stream fns
+#define WANT_STRING
+
+#include "include.h"                   // include standard files
+
+using namespace std;
+
+#include "myexcept.h"                  // for exception handling
+
+#ifdef use_namespace
+namespace RBD_COMMON {
+#endif
+
+
+//#define REG_DEREG                    // for print out uses of new/delete
+//#define CLEAN_LIST                   // to print entries being added to
+                                       // or deleted from cleanup list
+
+#ifdef SimulateExceptions
+
+void Throw()
+{
+   for (Janitor* jan = JumpBase::jl->janitor; jan; jan = jan->NextJanitor)
+      jan->CleanUp();
+   JumpItem* jx = JumpBase::jl->ji;    // previous jumpbase;
+   if ( !jx ) { Terminate(); }         // jl was initial JumpItem
+   JumpBase::jl = jx;                  // drop down a level; cannot be in front
+                                       // of previous line
+   Tracer::last = JumpBase::jl->trace;
+   longjmp(JumpBase::jl->env, 1);
+}
+
+#endif                                 // end of simulate exceptions
+
+
+unsigned long BaseException::Select;
+char* BaseException::what_error;
+int BaseException::SoFar;
+int BaseException::LastOne;
+
+BaseException::BaseException(const char* a_what)
+{
+   Select++; SoFar = 0;
+   if (!what_error)                   // make space for exception message
+   {
+      LastOne = 511;
+      what_error = new char[512];
+      if (!what_error)                // fail to make space
+      {
+         LastOne = 0;
+         what_error = (char *)"No heap space for exception message\n";
+      }
+   }
+   AddMessage("\n\nAn exception has been thrown\n");
+   AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+void BaseException::AddMessage(const char* a_what)
+{
+   if (a_what)
+   {
+      int l = strlen(a_what); int r = LastOne - SoFar;
+      if (l < r) { strcpy(what_error+SoFar, a_what); SoFar += l; }
+      else if (r > 0)
+      {
+         strncpy(what_error+SoFar, a_what, r);
+         what_error[LastOne] = 0;
+         SoFar = LastOne;
+      }
+   }
+}
+
+void BaseException::AddInt(int value)
+{
+   bool negative;
+   if (value == 0) { AddMessage("0"); return; }
+   else if (value < 0) { value = -value; negative = true; }
+   else negative = false;
+   int n = 0; int v = value;        // how many digits will we need?
+   while (v > 0) { v /= 10; n++; }
+   if (negative) n++;
+   if (LastOne-SoFar < n) { AddMessage("***"); return; }
+
+   SoFar += n; n = SoFar; what_error[n] = 0;
+   while (value > 0)
+   {
+      int nv = value / 10; int rm = value - nv * 10;  value = nv;
+      what_error[--n] = (char)(rm + '0');
+   }
+   if (negative) what_error[--n] = '-';
+   return;
+}
+
+void Tracer::PrintTrace()
+{
+   cout << "\n";
+   for (Tracer* et = last; et; et=et->previous)
+      cout << "  * " << et->entry << "\n";
+}
+
+void Tracer::AddTrace()
+{
+   if (last)
+   {
+      BaseException::AddMessage("Trace: ");
+      BaseException::AddMessage(last->entry);
+      for (Tracer* et = last->previous; et; et=et->previous)
+      {
+         BaseException::AddMessage("; ");
+         BaseException::AddMessage(et->entry);
+      }
+      BaseException::AddMessage(".\n");
+   }
+}
+
+#ifdef SimulateExceptions
+
+
+Janitor::Janitor()
+{
+   if (do_not_link)
+   {
+      do_not_link = false; NextJanitor = 0; OnStack = false;
+#ifdef CLEAN_LIST
+      cout << "Not added to clean-list " << (unsigned long)this << "\n";
+#endif
+   }
+   else
+   {
+      OnStack = true;
+#ifdef CLEAN_LIST
+      cout << "Add to       clean-list " << (unsigned long)this << "\n";
+#endif
+      NextJanitor = JumpBase::jl->janitor; JumpBase::jl->janitor=this;
+   }
+}
+
+Janitor::~Janitor()
+{
+   // expect the item to be deleted to be first on list
+   // but must be prepared to search list
+   if (OnStack)
+   {
+#ifdef CLEAN_LIST
+      cout << "Delete from  clean-list " << (unsigned long)this << "\n";
+#endif
+      Janitor* lastjan = JumpBase::jl->janitor;
+      if (this == lastjan) JumpBase::jl->janitor = NextJanitor;
+      else
+      {
+	 for (Janitor* jan = lastjan->NextJanitor; jan;
+	    jan = lastjan->NextJanitor)
+	 {
+	    if (jan==this)
+	       { lastjan->NextJanitor = jan->NextJanitor; return; }
+	    lastjan=jan;
+	 }
+
+	 Throw(BaseException(
+"Cannot resolve memory linked list\nSee notes in myexcept.cpp for details\n"
+         ));
+
+
+// This message occurs when a call to ~Janitor() occurs, apparently
+// without a corresponding call to Janitor(). This could happen if my
+// way of deciding whether a constructor is being called by new
+// fails.
+
+// It may happen if you are using my simulated exceptions and also have
+// your compiler s exceptions turned on.
+
+// It can also happen if you have a class derived from Janitor
+// which does not include a copy constructor [ eg X(const &X) ].
+// Possibly also if delete is applied an object on the stack (ie not
+// called by new). Otherwise, it is a bug in myexcept or your compiler.
+// If you do not #define TEMPS_DESTROYED_QUICKLY you will get this
+// error with Microsoft C 7.0. There are probably situations where
+// you will get this when you do define TEMPS_DESTROYED_QUICKLY. This
+// is a bug in MSC. Beware of "operator" statements for defining
+// conversions; particularly for converting from a Base class to a
+// Derived class.
+
+// You may get away with simply deleting this error message and Throw
+// statement if you can not find a better way of overcoming the
+// problem. In any case please tell me if you get this error message,
+// particularly for compilers apart from Microsoft C 7.0.
+
+
+      }
+   }
+}
+
+JumpItem* JumpBase::jl;              // will be set to zero
+jmp_buf JumpBase::env;
+bool Janitor::do_not_link;           // will be set to false
+
+
+int JanitorInitializer::ref_count;
+
+JanitorInitializer::JanitorInitializer()
+{
+   if (ref_count++ == 0) new JumpItem;
+                                    // need JumpItem at head of list
+}
+
+#endif                              // end of SimulateExceptions
+
+Tracer* Tracer::last;               // will be set to zero
+
+
+void Terminate()
+{
+   cout << "\n\nThere has been an exception with no handler - exiting";
+   const char* what = BaseException::what();
+   if (what) cout << what << "\n";
+   exit(1);
+}
+
+
+
+#ifdef DO_FREE_CHECK
+// Routines for tracing whether new and delete calls are balanced
+
+FreeCheckLink::FreeCheckLink() : next(FreeCheck::next)
+   { FreeCheck::next = this; }
+
+FCLClass::FCLClass(void* t, char* name) : ClassName(name) { ClassStore=t; }
+
+FCLRealArray::FCLRealArray(void* t, char* o, int s)
+  : Operation(o), size(s) { ClassStore=t; }
+
+FCLIntArray::FCLIntArray(void* t, char* o, int s)
+  : Operation(o), size(s) { ClassStore=t; }
+
+FreeCheckLink* FreeCheck::next;
+int FreeCheck::BadDelete;
+
+void FCLClass::Report()
+{ cout << "   " << ClassName << "   " << (unsigned long)ClassStore << "\n"; }
+
+void FCLRealArray::Report()
+{
+   cout << "   " << Operation << "   " << (unsigned long)ClassStore <<
+      "   " << size << "\n";
+}
+
+void FCLIntArray::Report()
+{
+   cout << "   " << Operation << "   " << (unsigned long)ClassStore <<
+      "   " << size << "\n";
+}
+
+void FreeCheck::Register(void* t, char* name)
+{
+   FCLClass* f = new FCLClass(t,name);
+   if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
+#ifdef REG_DEREG
+   cout << "Registering   " << name << "   " << (unsigned long)t << "\n";
+#endif
+}
+
+void FreeCheck::RegisterR(void* t, char* o, int s)
+{
+   FCLRealArray* f = new FCLRealArray(t,o,s);
+   if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
+#ifdef REG_DEREG
+   cout << o << "   " << s << "   " << (unsigned long)t << "\n";
+#endif
+}
+
+void FreeCheck::RegisterI(void* t, char* o, int s)
+{
+   FCLIntArray* f = new FCLIntArray(t,o,s);
+   if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
+#ifdef REG_DEREG
+   cout << o << "   " << s << "   " << (unsigned long)t << "\n";
+#endif
+}
+
+void FreeCheck::DeRegister(void* t, char* name)
+{
+   FreeCheckLink* last = 0;
+#ifdef REG_DEREG
+   cout << "Deregistering " << name << "   " << (unsigned long)t << "\n";
+#endif
+   for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
+   {
+      if (fcl->ClassStore==t)
+      {
+	 if (last) last->next = fcl->next; else next = fcl->next;
+	 delete fcl; return;
+      }
+      last = fcl;
+   }
+   cout << "\nRequest to delete non-existent object of class and location:\n";
+   cout << "   " << name << "   " << (unsigned long)t << "\n";
+   BadDelete++;
+   Tracer::PrintTrace();
+   cout << "\n";
+}
+
+void FreeCheck::DeRegisterR(void* t, char* o, int s)
+{
+   FreeCheckLink* last = 0;
+#ifdef REG_DEREG
+   cout << o << "   " << s << "   " << (unsigned long)t << "\n";
+#endif
+   for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
+   {
+      if (fcl->ClassStore==t)
+      {
+	 if (last) last->next = fcl->next; else next = fcl->next;
+	 if (s >= 0 && ((FCLRealArray*)fcl)->size != s)
+	 {
+	    cout << "\nArray sizes do not agree:\n";
+	    cout << "   " << o << "   " << (unsigned long)t
+	       << "   " << ((FCLRealArray*)fcl)->size << "   " << s << "\n";
+	    Tracer::PrintTrace();
+	    cout << "\n";
+	 }
+	 delete fcl; return;
+      }
+      last = fcl;
+   }
+   cout << "\nRequest to delete non-existent real array:\n";
+   cout << "   " << o << "   " << (unsigned long)t << "   " << s << "\n";
+   BadDelete++;
+   Tracer::PrintTrace();
+   cout << "\n";
+}
+
+void FreeCheck::DeRegisterI(void* t, char* o, int s)
+{
+   FreeCheckLink* last = 0;
+#ifdef REG_DEREG
+   cout << o << "   " << s << "   " << (unsigned long)t << "\n";
+#endif
+   for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
+   {
+      if (fcl->ClassStore==t)
+      {
+	 if (last) last->next = fcl->next; else next = fcl->next;
+	 if (s >= 0 && ((FCLIntArray*)fcl)->size != s)
+	 {
+	    cout << "\nArray sizes do not agree:\n";
+	    cout << "   " << o << "   " << (unsigned long)t
+	       << "   " << ((FCLIntArray*)fcl)->size << "   " << s << "\n";
+	    Tracer::PrintTrace();
+	    cout << "\n";
+	 }
+	 delete fcl; return;
+      }
+      last = fcl;
+   }
+   cout << "\nRequest to delete non-existent int array:\n";
+   cout << "   " << o << "   " << (unsigned long)t << "   " << s << "\n";
+   BadDelete++;
+   Tracer::PrintTrace();
+   cout << "\n";
+}
+
+void FreeCheck::Status()
+{
+   if (next)
+   {
+      cout << "\nObjects of the following classes remain undeleted:\n";
+      for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next) fcl->Report();
+      cout << "\n";
+   }
+   else cout << "\nNo objects remain undeleted\n\n";
+   if (BadDelete)
+   {
+      cout << "\nThere were " << BadDelete << 
+         " requests to delete non-existent items\n\n";
+   }
+}
+
+#endif                            // end of DO_FREE_CHECK
+
+// derived exception bodies
+
+Logic_error::Logic_error(const char* a_what) : BaseException()
+{
+   Select = BaseException::Select;
+   AddMessage("Logic error:- "); AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+Runtime_error::Runtime_error(const char* a_what)
+   : BaseException()
+{
+   Select = BaseException::Select;
+   AddMessage("Runtime error:- "); AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+Domain_error::Domain_error(const char* a_what) : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("domain error\n"); AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+Invalid_argument::Invalid_argument(const char* a_what) : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("invalid argument\n"); AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+Length_error::Length_error(const char* a_what) : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("length error\n"); AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+Out_of_range::Out_of_range(const char* a_what) : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("out of range\n"); AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+//Bad_cast::Bad_cast(const char* a_what) : Logic_error()
+//{
+//   Select = BaseException::Select;
+//   AddMessage("bad cast\n"); AddMessage(a_what);
+//   if (a_what) Tracer::AddTrace();
+//}
+
+//Bad_typeid::Bad_typeid(const char* a_what) : Logic_error()
+//{
+//   Select = BaseException::Select;
+//   AddMessage("bad type id.\n"); AddMessage(a_what);
+//   if (a_what) Tracer::AddTrace();
+//}
+
+Range_error::Range_error(const char* a_what) : Runtime_error()
+{
+   Select = BaseException::Select;
+   AddMessage("range error\n"); AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+Overflow_error::Overflow_error(const char* a_what) : Runtime_error()
+{
+   Select = BaseException::Select;
+   AddMessage("overflow error\n"); AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+Bad_alloc::Bad_alloc(const char* a_what) : BaseException()
+{
+   Select = BaseException::Select;
+   AddMessage("bad allocation\n"); AddMessage(a_what);
+   if (a_what) Tracer::AddTrace();
+}
+
+
+
+
+unsigned long Logic_error::Select;
+unsigned long Runtime_error::Select;
+unsigned long Domain_error::Select;
+unsigned long Invalid_argument::Select;
+unsigned long Length_error::Select;
+unsigned long Out_of_range::Select;
+//unsigned long Bad_cast::Select;
+//unsigned long Bad_typeid::Select;
+unsigned long Range_error::Select;
+unsigned long Overflow_error::Select;
+unsigned long Bad_alloc::Select;
+
+#ifdef use_namespace
+}
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/myexcept.h b/Utilities/OSSIM/ossim_core/matrix/myexcept.h
new file mode 100644
index 0000000000..1351ccbfb4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/myexcept.h
@@ -0,0 +1,433 @@
+//$$ myexcept.h                                  Exception handling classes
+
+
+// A set of classes to simulate exceptions in C++
+//
+//   Partially copied from Carlos Vidal s article in the C users  journal
+//   September 1992, pp 19-28
+//
+//   Operations defined
+//      Try {     }
+//      Throw ( exception object )
+//      ReThrow
+//      Catch ( exception class ) {      }
+//      CatchAll {      }
+//      CatchAndThrow
+//
+//   All catch lists must end with a CatchAll or CatchAndThrow statement
+//   but not both.
+//
+//   When exceptions are finally implemented replace Try, Throw(E), Rethrow,
+//   Catch, CatchAll, CatchAndThrow by try, throw E, throw, catch,
+//   catch(...), and {}.
+//
+//   All exception classes must be derived from BaseException, have no
+//   non-static variables and must include the statement
+//
+//      static unsigned long Select;
+//
+//   Any constructor in one of these exception classes must include
+//
+//      Select = BaseException::Select;
+//
+//   For each exceptions class, EX_1, some .cpp file must include
+//
+//      unsigned long EX_1::Select;
+//
+
+
+#ifndef EXCEPTION_LIB
+#define EXCEPTION_LIB
+
+#ifdef use_namespace
+namespace RBD_COMMON {
+#endif
+
+
+void Terminate();
+
+
+//********** classes for setting up exceptions and reporting ************//
+
+class BaseException;
+
+class Tracer                             // linked list showing how
+{                                        // we got here
+   const char* entry;
+   Tracer* previous;
+public:
+   Tracer(const char*);
+   ~Tracer();
+   void ReName(const char*);
+   static void PrintTrace();             // for printing trace
+   static void AddTrace();               // insert trace in exception record
+   static Tracer* last;                  // points to Tracer list
+   friend class BaseException;
+};
+
+
+class BaseException                          // The base exception class
+{
+protected:
+   static char* what_error;              // error message
+   static int SoFar;                     // no. characters already entered
+   static int LastOne;                   // last location in error buffer
+public:
+   static void AddMessage(const char* a_what);
+                                         // messages about exception
+   static void AddInt(int value);        // integer to error message
+   static unsigned long Select;          // for identifying exception
+   BaseException(const char* a_what = 0);
+   static const char* what() { return what_error; }
+                                         // for getting error message
+};
+
+#ifdef TypeDefException
+typedef BaseException Exception;        // for compatibility with my older libraries
+#endif
+
+inline Tracer::Tracer(const char* e)
+   : entry(e), previous(last) { last = this; }
+
+inline Tracer::~Tracer() { last = previous; }
+
+inline void Tracer::ReName(const char* e) { entry=e; }
+
+#ifdef SimulateExceptions                // SimulateExceptions
+
+#include <setjmp.h>
+
+
+//************* the definitions of Try, Throw and Catch *****************//
+
+
+class JumpItem;
+class Janitor;
+
+class JumpBase         // pointer to a linked list of jmp_buf s
+{
+public:
+   static JumpItem *jl;
+   static jmp_buf env;
+};
+
+class JumpItem         // an item in a linked list of jmp_buf s
+{
+public:
+   JumpItem *ji;
+   jmp_buf env;
+   Tracer* trace;                     // to keep check on Tracer items
+   Janitor* janitor;                  // list of items for cleanup
+   JumpItem() : ji(JumpBase::jl), trace(0), janitor(0)
+      { JumpBase::jl = this; }
+   ~JumpItem() { JumpBase::jl = ji; }
+};
+
+void Throw();
+
+inline void Throw(const BaseException&) { Throw(); }
+
+#define Try                                             \
+   if (!setjmp( JumpBase::jl->env )) {                  \
+   JumpBase::jl->trace = Tracer::last;               \
+   JumpItem JI387256156;
+
+#define ReThrow Throw()
+
+#define Catch(EXCEPTION)                                \
+   } else if (BaseException::Select == EXCEPTION::Select) {
+
+#define CatchAll } else
+
+#define CatchAndThrow  } else Throw();
+
+
+//****************** cleanup heap following Throw ***********************//
+
+class Janitor
+{
+protected:
+   static bool do_not_link;                  // set when new is called
+   bool OnStack;                             // false if created by new
+public:
+   Janitor* NextJanitor;
+   virtual void CleanUp() {}
+   Janitor();
+   virtual ~Janitor();
+};
+
+
+// The tiresome old trick for initializing the Janitor class
+// this is needed for classes derived from Janitor which have objects
+// declared globally
+
+class JanitorInitializer
+{
+public:
+   JanitorInitializer();
+private:
+   static int ref_count;
+};
+
+static JanitorInitializer JanInit;
+
+#endif                                // end of SimulateExceptions
+
+#ifdef UseExceptions
+
+#define Try try
+#define Throw(E) throw E
+#define ReThrow throw
+#define Catch catch
+#define CatchAll catch(...)
+#define CatchAndThrow {}
+
+#endif                                // end of UseExceptions
+
+
+#ifdef DisableExceptions              // Disable exceptions
+
+#define Try {
+#define ReThrow Throw()
+#define Catch(EXCEPTION) } if (false) {
+#define CatchAll } if (false)
+#define CatchAndThrow }
+
+inline void Throw() { Terminate(); }
+inline void Throw(const BaseException&) { Terminate(); }
+
+
+#endif                                // end of DisableExceptions
+
+#ifndef SimulateExceptions            // ! SimulateExceptions
+
+class Janitor                         // a dummy version
+{
+public:
+   virtual void CleanUp() {}
+   Janitor() {}
+   virtual ~Janitor() {}
+};
+
+#endif                                // end of ! SimulateExceptions
+
+
+//******************** FREE_CHECK and NEW_DELETE ***********************//
+
+#ifdef DO_FREE_CHECK                          // DO_FREE_CHECK
+// Routines for tracing whether new and delete calls are balanced
+
+class FreeCheck;
+
+class FreeCheckLink
+{
+protected:
+   FreeCheckLink* next;
+   void* ClassStore;
+   FreeCheckLink();
+   virtual void Report()=0;                   // print details of link
+   friend class FreeCheck;
+};
+
+class FCLClass : public FreeCheckLink         // for registering objects
+{
+   char* ClassName;
+   FCLClass(void* t, char* name);
+   void Report();
+   friend class FreeCheck;
+};
+
+class FCLRealArray : public FreeCheckLink     // for registering real arrays
+{
+   char* Operation;
+   int size;
+   FCLRealArray(void* t, char* o, int s);
+   void Report();
+   friend class FreeCheck;
+};
+
+class FCLIntArray : public FreeCheckLink     // for registering int arrays
+{
+   char* Operation;
+   int size;
+   FCLIntArray(void* t, char* o, int s);
+   void Report();
+   friend class FreeCheck;
+};
+
+
+class FreeCheck
+{
+   static FreeCheckLink* next;
+   static int BadDelete;
+public:
+   static void Register(void*, char*);
+   static void DeRegister(void*, char*);
+   static void RegisterR(void*, char*, int);
+   static void DeRegisterR(void*, char*, int);
+   static void RegisterI(void*, char*, int);
+   static void DeRegisterI(void*, char*, int);
+   static void Status();
+   friend class FreeCheckLink;
+   friend class FCLClass;
+   friend class FCLRealArray;
+   friend class FCLIntArray;
+};
+
+#define FREE_CHECK(Class)                                                  \
+public:                                                                    \
+   void* operator new(size_t size)                                         \
+   {                                                                       \
+      void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
+      return t;                                                            \
+   }                                                                       \
+   void operator delete(void* t)                                           \
+   { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
+
+
+#ifdef SimulateExceptions         // SimulateExceptions
+
+#define NEW_DELETE(Class)                                                  \
+public:                                                                    \
+   void* operator new(size_t size)                                         \
+   {                                                                       \
+      do_not_link=true;                                                    \
+      void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
+      return t;                                                            \
+   }                                                                       \
+   void operator delete(void* t)                                           \
+   { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
+
+
+#endif                           // end of SimulateExceptions
+
+
+#define MONITOR_REAL_NEW(Operation, Size, Pointer)                         \
+	FreeCheck::RegisterR(Pointer, Operation, Size);
+#define MONITOR_INT_NEW(Operation, Size, Pointer)                          \
+	FreeCheck::RegisterI(Pointer, Operation, Size);
+#define MONITOR_REAL_DELETE(Operation, Size, Pointer)                      \
+	FreeCheck::DeRegisterR(Pointer, Operation, Size);
+#define MONITOR_INT_DELETE(Operation, Size, Pointer)                       \
+	FreeCheck::DeRegisterI(Pointer, Operation, Size);
+
+#else                            // DO_FREE_CHECK not defined
+
+#define FREE_CHECK(Class) public:
+#define MONITOR_REAL_NEW(Operation, Size, Pointer) {}
+#define MONITOR_INT_NEW(Operation, Size, Pointer) {}
+#define MONITOR_REAL_DELETE(Operation, Size, Pointer) {}
+#define MONITOR_INT_DELETE(Operation, Size, Pointer) {}
+
+
+#ifdef SimulateExceptions         // SimulateExceptions
+
+
+#define NEW_DELETE(Class)                                                  \
+public:                                                                    \
+	void* operator new(size_t size)                                    \
+	{ do_not_link=true; void* t = ::operator new(size); return t; }    \
+	void operator delete(void* t) { ::operator delete(t); }
+
+#endif                            // end of SimulateExceptions
+
+#endif                            // end of ! DO_FREE_CHECK
+
+#ifndef SimulateExceptions        // ! SimulateExceptions
+
+#define NEW_DELETE(Class) FREE_CHECK(Class)
+
+#endif                            // end of ! SimulateExceptions
+
+
+//********************* derived exceptions ******************************//
+
+class Logic_error : public BaseException
+{
+public:
+   static unsigned long Select;
+   Logic_error(const char* a_what = 0);
+};
+
+class Runtime_error : public BaseException
+{
+public:
+   static unsigned long Select;
+   Runtime_error(const char* a_what = 0);
+};
+
+class Domain_error : public Logic_error
+{
+public:
+   static unsigned long Select;
+   Domain_error(const char* a_what = 0);
+};
+
+class Invalid_argument : public Logic_error
+{
+public:
+   static unsigned long Select;
+   Invalid_argument(const char* a_what = 0);
+};
+
+class Length_error : public Logic_error
+{
+public:
+   static unsigned long Select;
+   Length_error(const char* a_what = 0);
+};
+
+class Out_of_range : public Logic_error
+{
+public:
+   static unsigned long Select;
+   Out_of_range(const char* a_what = 0);
+};
+
+//class Bad_cast : public Logic_error
+//{
+//public:
+//   static unsigned long Select;
+//   Bad_cast(const char* a_what = 0);
+//};
+
+//class Bad_typeid : public Logic_error
+//{
+//public:
+//   static unsigned long Select;
+//   Bad_typeid(const char* a_what = 0);
+//};
+
+class Range_error : public Runtime_error
+{
+public:
+   static unsigned long Select;
+   Range_error(const char* a_what = 0);
+};
+
+class Overflow_error : public Runtime_error
+{
+public:
+   static unsigned long Select;
+   Overflow_error(const char* a_what = 0);
+};
+
+class Bad_alloc : public BaseException
+{
+public:
+   static unsigned long Select;
+   Bad_alloc(const char* a_what = 0);
+};
+
+#ifdef use_namespace
+}
+#endif
+
+
+#endif                            // end of EXCEPTION_LIB
+
+
+// body file: myexcept.cpp
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newfft.cpp b/Utilities/OSSIM/ossim_core/matrix/newfft.cpp
new file mode 100644
index 0000000000..5d0136fa63
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newfft.cpp
@@ -0,0 +1,1059 @@
+//$ newfft.cpp
+
+// This is originally by Sande and Gentleman in 1967! I have translated from
+// Fortran into C and a little bit of C++.
+
+// It takes about twice as long as fftw
+// (http://theory.lcs.mit.edu/~fftw/homepage.html)
+// but is much shorter than fftw  and so despite its age
+// might represent a reasonable
+// compromise between speed and complexity.
+// If you really need the speed get fftw.
+
+
+//    THIS SUBROUTINE WAS WRITTEN BY G.SANDE OF PRINCETON UNIVERSITY AND
+//    W.M.GENTLMAN OF THE BELL TELEPHONE LAB.  IT WAS BROUGHT TO LONDON
+//    BY DR. M.D. GODFREY AT THE IMPERIAL COLLEGE AND WAS ADAPTED FOR
+//    BURROUGHS 6700 BY D. R. BRILLINGER AND J. PEMBERTON
+//    IT REPRESENTS THE STATE OF THE ART OF COMPUTING COMPLETE FINITE
+//    DISCRETE FOURIER TRANSFORMS AS OF NOV.1967.
+//    OTHER PROGRAMS REQUIRED.
+//                                 ONLY THOSE SUBROUTINES INCLUDED HERE.
+//                      USAGE.
+//       CALL AR1DFT(N,X,Y)
+//            WHERE  N IS THE NUMBER OF POINTS IN THE SEQUENCE .
+//                   X - IS A ONE-DIMENSIONAL ARRAY CONTAINING THE REAL
+//                       PART OF THE SEQUENCE.
+//                   Y - IS A ONE-DIMENSIONAL ARRAY CONTAINING THE
+//                       IMAGINARY PART OF THE SEQUENCE.
+//    THE TRANSFORM IS RETURNED IN X AND Y.
+//            METHOD
+//               FOR A GENERAL DISCUSSION OF THESE TRANSFORMS AND OF
+//    THE FAST METHOD FOR COMPUTING THEM, SEE GENTLEMAN AND SANDE,
+//    @FAST FOURIER TRANSFORMS - FOR FUN AND PROFIT,@ 1966 FALL JOINT
+//    COMPUTER CONFERENCE.
+//    THIS PROGRAM COMPUTES THIS FOR A COMPLEX SEQUENCE Z(T) OF LENGTH
+//    N WHOSE ELEMENTS ARE STORED AT(X(I) , Y(I)) AND RETURNS THE
+//    TRANSFORM COEFFICIENTS AT (X(I), Y(I)).
+//        DESCRIPTION
+//    AR1DFT IS A HIGHLY MODULAR ROUTINE CAPABLE OF COMPUTING IN PLACE
+//    THE COMPLETE FINITE DISCRETE FOURIER TRANSFORM  OF A ONE-
+//    DIMENSIONAL SEQUENCE OF RATHER GENERAL LENGTH N.
+//       THE MAIN ROUTINE , AR1DFT ITSELF, FACTORS N. IT THEN CALLS ON
+//    ON GR 1D FT TO COMPUTE THE ACTUAL TRANSFORMS, USING THESE FACTORS.
+//    THIS GR 1D FT DOES, CALLING AT EACH STAGE ON THE APPROPRIATE KERN
+//    EL R2FTK, R4FTK, R8FTK, R16FTK, R3FTK, R5FTK, OR RPFTK TO PERFORM
+//    THE COMPUTATIONS FOR THIS PASS OVER THE SEQUENCE, DEPENDING ON
+//    WHETHER THE CORRESPONDING FACTOR IS 2, 4, 8, 16, 3, 5, OR SOME
+//    MORE GENERAL PRIME P. WHEN GR1DFT IS FINISHED THE TRANSFORM IS
+//    COMPUTED, HOWEVER, THE RESULTS ARE STORED IN "DIGITS REVERSED"
+//    ORDER. AR1DFT THEREFORE, CALLS UPON GR 1S FS TO SORT THEM OUT.
+//    TO RETURN TO THE FACTORIZATION, SINGLETON HAS POINTED OUT THAT
+//    THE TRANSFORMS ARE MORE EFFICIENT IF THE SAMPLE SIZE N, IS OF THE
+//    FORM B*A**2 AND B CONSISTS OF A SINGLE FACTOR.  IN SUCH A CASE
+//    IF WE PROCESS THE FACTORS IN THE ORDER ABA  THEN
+//    THE REORDERING CAN BE DONE AS FAST IN PLACE, AS WITH SCRATCH
+//    STORAGE.  BUT AS B BECOMES MORE COMPLICATED, THE COST OF THE DIGIT
+//    REVERSING DUE TO B PART BECOMES VERY EXPENSIVE IF WE TRY TO DO IT
+//    IN PLACE.  IN SUCH A CASE IT MIGHT BE BETTER TO USE EXTRA STORAGE
+//    A ROUTINE TO DO THIS IS, HOWEVER, NOT INCLUDED HERE.
+//    ANOTHER FEATURE INFLUENCING THE FACTORIZATION IS THAT FOR ANY FIXED
+//    FACTOR N WE CAN PREPARE A SPECIAL KERNEL WHICH WILL COMPUTE
+//    THAT STAGE OF THE TRANSFORM MORE EFFICIENTLY THAN WOULD A KERNEL
+//    FOR GENERAL FACTORS, ESPECIALLY IF THE GENERAL KERNEL HAD TO BE
+//    APPLIED SEVERAL TIMES. FOR EXAMPLE, FACTORS OF 4 ARE MORE
+//    EFFICIENT THAN FACTORS OF 2, FACTORS OF 8 MORE EFFICIENT THAN 4,ETC
+//    ON THE OTHER HAND DIMINISHING RETURNS RAPIDLY SET IN, ESPECIALLY
+//    SINCE THE LENGTH OF THE KERNEL FOR A SPECIAL CASE IS ROUGHLY
+//    PROPORTIONAL TO THE FACTOR IT DEALS WITH. HENCE THESE PROBABLY ARE
+//    ALL THE KERNELS WE WISH TO HAVE.
+//            RESTRICTIONS.
+//    AN UNFORTUNATE FEATURE OF THE SORTING PROBLEM IS THAT THE MOST
+//    EFFICIENT WAY TO DO IT IS WITH NESTED DO LOOPS, ONE FOR EACH
+//    FACTOR. THIS PUTS A RESTRICTION ON N AS TO HOW MANY FACTORS IT
+//    CAN HAVE.  CURRENTLY THE LIMIT IS 16, BUT THE LIMIT CAN BE READILY
+//    RAISED IF NECESSARY.
+//    A SECOND RESTRICTION OF THE PROGRAM IS THAT LOCAL STORAGE OF THE
+//    THE ORDER P**2 IS REQUIRED BY THE GENERAL KERNEL RPFTK, SO SOME
+//    LIMIT MUST BE SET ON P.  CURRENTLY THIS IS 19, BUT IT CAN BE INCRE
+//    INCREASED BY TRIVIAL CHANGES.
+//       OTHER COMMENTS.
+//(1) THE ROUTINE IS ADAPTED TO CHECK WHETHER A GIVEN N WILL MEET THE
+//    ABOVE FACTORING REQUIREMENTS AN, IF NOT, TO RETURN THE NEXT HIGHER
+//    NUMBER, NX, SAY, WHICH WILL MEET THESE REQUIREMENTS.
+//    THIS CAN BE ACCHIEVED BY   A STATEMENT OF THE FORM
+//            CALL FACTR(N,X,Y).
+//    IF A DIFFERENT N, SAY NX, IS RETURNED THEN THE TRANSFORMS COULD BE
+//    OBTAINED BY EXTENDING THE SIZE OF THE X-ARRAY AND Y-ARRAY TO NX,
+//    AND SETTING X(I) = Y(I) = 0., FOR I = N+1, NX.
+//(2) IF THE SEQUENCE Z IS ONLY A REAL SEQUENCE, THEN THE IMAGINARY PART
+//    Y(I)=0., THIS WILL RETURN THE COSINE TRANSFORM OF THE REAL SEQUENCE
+//    IN X, AND THE SINE TRANSFORM IN Y.
+
+
+#define WANT_STREAM
+
+#define WANT_MATH
+
+#include "newmatap.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,20); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+inline Real square(Real x) { return x*x; }
+inline int square(int x) { return x*x; }
+
+static void GR_1D_FS (int PTS, int N_SYM, int N_UN_SYM,
+   const SimpleIntArray& SYM, int P_SYM, const SimpleIntArray& UN_SYM,
+   Real* X, Real* Y);
+static void GR_1D_FT (int N, int N_FACTOR, const SimpleIntArray& FACTOR,
+   Real* X, Real* Y);
+static void R_P_FTK (int N, int M, int P, Real* X, Real* Y);
+static void R_2_FTK (int N, int M, Real* X0, Real* Y0, Real* X1, Real* Y1);
+static void R_3_FTK (int N, int M, Real* X0, Real* Y0, Real* X1, Real* Y1,
+   Real* X2, Real* Y2);
+static void R_4_FTK (int N, int M,
+   Real* X0, Real* Y0, Real* X1, Real* Y1,
+   Real* X2, Real* Y2, Real* X3, Real* Y3);
+static void R_5_FTK (int N, int M,
+   Real* X0, Real* Y0, Real* X1, Real* Y1, Real* X2, Real* Y2,
+   Real* X3, Real* Y3, Real* X4, Real* Y4);
+static void R_8_FTK (int N, int M,
+   Real* X0, Real* Y0, Real* X1, Real* Y1,
+   Real* X2, Real* Y2, Real* X3, Real* Y3,
+   Real* X4, Real* Y4, Real* X5, Real* Y5,
+   Real* X6, Real* Y6, Real* X7, Real* Y7);
+static void R_16_FTK (int N, int M,
+   Real* X0, Real* Y0, Real* X1, Real* Y1,
+   Real* X2, Real* Y2, Real* X3, Real* Y3,
+   Real* X4, Real* Y4, Real* X5, Real* Y5,
+   Real* X6, Real* Y6, Real* X7, Real* Y7,
+   Real* X8, Real* Y8, Real* X9, Real* Y9,
+   Real* X10, Real* Y10, Real* X11, Real* Y11,
+   Real* X12, Real* Y12, Real* X13, Real* Y13,
+   Real* X14, Real* Y14, Real* X15, Real* Y15);
+static int BitReverse(int x, int prod, int n, const SimpleIntArray& f);
+
+
+bool FFT_Controller::ar_1d_ft (int PTS, Real* X, Real *Y)
+{
+//    ARBITRARY RADIX ONE DIMENSIONAL FOURIER TRANSFORM
+
+   REPORT
+
+   int  F,J,N,NF,P,PMAX,P_SYM,P_TWO,Q,R,TWO_GRP;
+
+   // NP is maximum number of squared factors allows PTS up to 2**32 at least
+   // NQ is number of not-squared factors - increase if we increase PMAX
+   const int NP = 16, NQ = 10;
+   SimpleIntArray PP(NP), QQ(NQ);
+
+   TWO_GRP=16; PMAX=19;
+
+   // PMAX is the maximum factor size
+   // TWO_GRP is the maximum power of 2 handled as a single factor
+   // Doesn't take advantage of combining powers of 2 when calculating
+   // number of factors
+
+   if (PTS<=1) return true;
+   N=PTS; P_SYM=1; F=2; P=0; Q=0;
+
+   // P counts the number of squared factors
+   // Q counts the number of the rest
+   // R = 0 for no non-squared factors; 1 otherwise
+
+   // FACTOR holds all the factors - non-squared ones in the middle
+   //   - length is 2*P+Q
+   // SYM also holds all the factors but with the non-squared ones
+   //   multiplied together - length is 2*P+R
+   // PP holds the values of the squared factors - length is P
+   // QQ holds the values of the rest - length is Q
+
+   // P_SYM holds the product of the squared factors
+
+   // find the factors - load into PP and QQ
+   while (N > 1)
+   {
+      bool fail = true;
+      for (J=F; J<=PMAX; J++)
+         if (N % J == 0) { fail = false; F=J; break; }
+      if (fail || P >= NP || Q >= NQ) return false; // can't factor
+      N /= F;
+      if (N % F != 0) QQ[Q++] = F;
+      else { N /= F; PP[P++] = F; P_SYM *= F; }
+   }
+
+   R = (Q == 0) ? 0 : 1;  // R = 0 if no not-squared factors, 1 otherwise
+
+   NF = 2*P + Q;
+   SimpleIntArray FACTOR(NF + 1), SYM(2*P + R);
+   FACTOR[NF] = 0;                // we need this in the "combine powers of 2"
+
+   // load into SYM and FACTOR
+   for (J=0; J<P; J++)
+      { SYM[J]=FACTOR[J]=PP[P-1-J]; FACTOR[P+Q+J]=SYM[P+R+J]=PP[J]; }
+
+   if (Q>0)
+   {
+      REPORT
+      for (J=0; J<Q; J++) FACTOR[P+J]=QQ[J];
+      SYM[P]=PTS/square(P_SYM);
+   }
+
+   // combine powers of 2
+   P_TWO = 1;
+   for (J=0; J < NF; J++)
+   {
+      if (FACTOR[J]!=2) continue;
+      P_TWO=P_TWO*2; FACTOR[J]=1;
+      if (P_TWO<TWO_GRP && FACTOR[J+1]==2) continue;
+      FACTOR[J]=P_TWO; P_TWO=1;
+   }
+
+   if (P==0) R=0;
+   if (Q<=1) Q=0;
+
+   // do the analysis
+   GR_1D_FT(PTS,NF,FACTOR,X,Y);                 // the transform
+   GR_1D_FS(PTS,2*P+R,Q,SYM,P_SYM,QQ,X,Y);      // the reshuffling
+
+   return true;
+
+}
+
+static void GR_1D_FS (int PTS, int N_SYM, int N_UN_SYM,
+   const SimpleIntArray& SYM, int P_SYM, const SimpleIntArray& UN_SYM,
+   Real* X, Real* Y)
+{
+//    GENERAL RADIX ONE DIMENSIONAL FOURIER SORT
+
+// PTS = number of points
+// N_SYM = length of SYM
+// N_UN_SYM = length of UN_SYM
+// SYM: squared factors + product of non-squared factors + squared factors
+// P_SYM = product of squared factors (each included only once)
+// UN_SYM: not-squared factors
+
+   REPORT
+
+   Real T;
+   int  JJ,KK,P_UN_SYM;
+
+   // I have replaced the multiple for-loop used by Sande-Gentleman code
+   // by the following code which does not limit the number of factors
+
+   if (N_SYM > 0)
+   {
+      REPORT
+      SimpleIntArray U(N_SYM);
+      for(MultiRadixCounter MRC(N_SYM, SYM, U); !MRC.Finish(); ++MRC)
+      {
+         if (MRC.Swap())
+         {
+            int P = MRC.Reverse(); int JJ = MRC.Counter(); Real T;
+            T=X[JJ]; X[JJ]=X[P]; X[P]=T; T=Y[JJ]; Y[JJ]=Y[P]; Y[P]=T;
+         }
+      }
+   }
+
+   int J,JL,K,L,M,MS;
+
+   // UN_SYM contains the non-squared factors
+   // I have replaced the Sande-Gentleman code as it runs into
+   // integer overflow problems
+   // My code (and theirs) would be improved by using a bit array
+   // as suggested by Van Loan
+
+   if (N_UN_SYM==0) { REPORT return; }
+   P_UN_SYM=PTS/square(P_SYM); JL=(P_UN_SYM-3)*P_SYM; MS=P_UN_SYM*P_SYM;
+
+   for (J = P_SYM; J<=JL; J+=P_SYM)
+   {
+      K=J;
+      do K = P_SYM * BitReverse(K / P_SYM, P_UN_SYM, N_UN_SYM, UN_SYM);
+      while (K<J);
+
+      if (K!=J)
+      {
+         REPORT
+         for (L=0; L<P_SYM; L++) for (M=L; M<PTS; M+=MS)
+         {
+            JJ=M+J; KK=M+K;
+            T=X[JJ]; X[JJ]=X[KK]; X[KK]=T; T=Y[JJ]; Y[JJ]=Y[KK]; Y[KK]=T;
+         }
+      }
+   }
+
+   return;
+}
+
+static void GR_1D_FT (int N, int N_FACTOR, const SimpleIntArray& FACTOR,
+   Real* X, Real* Y)
+{
+//    GENERAL RADIX ONE DIMENSIONAL FOURIER TRANSFORM;
+
+   REPORT
+
+   int  M = N;
+
+   for (int i = 0; i < N_FACTOR; i++)
+   {
+      int P = FACTOR[i]; M /= P;
+
+      switch(P)
+      {
+      case 1: REPORT break;
+      case 2: REPORT R_2_FTK (N,M,X,Y,X+M,Y+M); break;
+      case 3: REPORT R_3_FTK (N,M,X,Y,X+M,Y+M,X+2*M,Y+2*M); break;
+      case 4: REPORT R_4_FTK (N,M,X,Y,X+M,Y+M,X+2*M,Y+2*M,X+3*M,Y+3*M); break;
+      case 5:
+         REPORT
+         R_5_FTK (N,M,X,Y,X+M,Y+M,X+2*M,Y+2*M,X+3*M,Y+3*M,X+4*M,Y+4*M);
+         break;
+      case 8:
+         REPORT
+         R_8_FTK (N,M,X,Y,X+M,Y+M,X+2*M,Y+2*M,
+            X+3*M,Y+3*M,X+4*M,Y+4*M,X+5*M,Y+5*M,
+            X+6*M,Y+6*M,X+7*M,Y+7*M);
+         break;
+      case 16:
+         REPORT
+         R_16_FTK (N,M,X,Y,X+M,Y+M,X+2*M,Y+2*M,
+            X+3*M,Y+3*M,X+4*M,Y+4*M,X+5*M,Y+5*M,
+            X+6*M,Y+6*M,X+7*M,Y+7*M,X+8*M,Y+8*M,
+            X+9*M,Y+9*M,X+10*M,Y+10*M,X+11*M,Y+11*M,
+            X+12*M,Y+12*M,X+13*M,Y+13*M,X+14*M,Y+14*M,
+            X+15*M,Y+15*M);
+         break;
+      default: REPORT R_P_FTK (N,M,P,X,Y); break;
+      }
+   }
+
+}
+
+static void R_P_FTK (int N, int M, int P, Real* X, Real* Y)
+//    RADIX PRIME FOURIER TRANSFORM KERNEL;
+// X and Y are treated as M * P matrices with Fortran storage
+{
+   REPORT
+   bool NO_FOLD,ZERO;
+   Real ANGLE,IS,IU,RS,RU,T,TWOPI,XT,YT;
+   int  J,JJ,K0,K,M_OVER_2,MP,PM,PP,U,V;
+
+   Real AA [9][9], BB [9][9];
+   Real A [18], B [18], C [18], S [18];
+   Real IA [9], IB [9], RA [9], RB [9];
+
+   TWOPI=8.0*atan(1.0);
+   M_OVER_2=M/2+1; MP=M*P; PP=P/2; PM=P-1;
+
+   for (U=0; U<PP; U++)
+   {
+      ANGLE=TWOPI*Real(U+1)/Real(P);
+      JJ=P-U-2;
+      A[U]=cos(ANGLE); B[U]=sin(ANGLE);
+      A[JJ]=A[U]; B[JJ]= -B[U];
+   }
+
+   for (U=1; U<=PP; U++)
+   {
+      for (V=1; V<=PP; V++)
+         { JJ=U*V-U*V/P*P; AA[V-1][U-1]=A[JJ-1]; BB[V-1][U-1]=B[JJ-1]; }
+   }
+
+   for (J=0; J<M_OVER_2; J++)
+   {
+      NO_FOLD = (J==0 || 2*J==M);
+      K0=J;
+      ANGLE=TWOPI*Real(J)/Real(MP); ZERO=ANGLE==0.0;
+      C[0]=cos(ANGLE); S[0]=sin(ANGLE);
+      for (U=1; U<PM; U++)
+      {
+         C[U]=C[U-1]*C[0]-S[U-1]*S[0];
+         S[U]=S[U-1]*C[0]+C[U-1]*S[0];
+      }
+      goto L700;
+   L500:
+      REPORT
+      if (NO_FOLD) { REPORT goto L1500; }
+      REPORT
+      NO_FOLD=true; K0=M-J;
+      for (U=0; U<PM; U++)
+         { T=C[U]*A[U]+S[U]*B[U]; S[U]= -S[U]*A[U]+C[U]*B[U]; C[U]=T; }
+   L700:
+      REPORT
+      for (K=K0; K<N; K+=MP)
+      {
+         XT=X[K]; YT=Y[K];
+         for (U=1; U<=PP; U++)
+         {
+            RA[U-1]=XT; IA[U-1]=YT;
+            RB[U-1]=0.0; IB[U-1]=0.0;
+         }
+         for (U=1; U<=PP; U++)
+         {
+            JJ=P-U;
+            RS=X[K+M*U]+X[K+M*JJ]; IS=Y[K+M*U]+Y[K+M*JJ];
+            RU=X[K+M*U]-X[K+M*JJ]; IU=Y[K+M*U]-Y[K+M*JJ];
+            XT=XT+RS; YT=YT+IS;
+            for (V=0; V<PP; V++)
+            {
+               RA[V]=RA[V]+RS*AA[V][U-1]; IA[V]=IA[V]+IS*AA[V][U-1];
+               RB[V]=RB[V]+RU*BB[V][U-1]; IB[V]=IB[V]+IU*BB[V][U-1];
+            }
+         }
+         X[K]=XT; Y[K]=YT;
+         for (U=1; U<=PP; U++)
+         {
+            if (!ZERO)
+            {
+               REPORT
+               XT=RA[U-1]+IB[U-1]; YT=IA[U-1]-RB[U-1];
+               X[K+M*U]=XT*C[U-1]+YT*S[U-1]; Y[K+M*U]=YT*C[U-1]-XT*S[U-1];
+               JJ=P-U;
+               XT=RA[U-1]-IB[U-1]; YT=IA[U-1]+RB[U-1];
+               X[K+M*JJ]=XT*C[JJ-1]+YT*S[JJ-1];
+               Y[K+M*JJ]=YT*C[JJ-1]-XT*S[JJ-1];
+            }
+            else
+            {
+               REPORT
+               X[K+M*U]=RA[U-1]+IB[U-1]; Y[K+M*U]=IA[U-1]-RB[U-1];
+               JJ=P-U;
+               X[K+M*JJ]=RA[U-1]-IB[U-1]; Y[K+M*JJ]=IA[U-1]+RB[U-1];
+            }
+         }
+      }
+      goto L500;
+L1500: ;
+   }
+   return;
+}
+
+static void R_2_FTK (int N, int M, Real* X0, Real* Y0, Real* X1, Real* Y1)
+//    RADIX TWO FOURIER TRANSFORM KERNEL;
+{
+   REPORT
+   bool NO_FOLD,ZERO;
+   int  J,K,K0,M2,M_OVER_2;
+   Real ANGLE,C,IS,IU,RS,RU,S,TWOPI;
+
+   M2=M*2; M_OVER_2=M/2+1;
+   TWOPI=8.0*atan(1.0);
+
+   for (J=0; J<M_OVER_2; J++)
+   {
+      NO_FOLD = (J==0 || 2*J==M);
+      K0=J;
+      ANGLE=TWOPI*Real(J)/Real(M2); ZERO=ANGLE==0.0;
+      C=cos(ANGLE); S=sin(ANGLE);
+      goto L200;
+   L100:
+      REPORT
+      if (NO_FOLD) { REPORT goto L600; }
+      REPORT
+      NO_FOLD=true; K0=M-J; C= -C;
+   L200:
+      REPORT
+      for (K=K0; K<N; K+=M2)
+      {
+         RS=X0[K]+X1[K]; IS=Y0[K]+Y1[K];
+         RU=X0[K]-X1[K]; IU=Y0[K]-Y1[K];
+         X0[K]=RS; Y0[K]=IS;
+         if (!ZERO) { X1[K]=RU*C+IU*S; Y1[K]=IU*C-RU*S; }
+         else { X1[K]=RU; Y1[K]=IU; }
+      }
+      goto L100;
+   L600: ;
+   }
+
+   return;
+}
+
+static void R_3_FTK (int N, int M, Real* X0, Real* Y0, Real* X1, Real* Y1,
+   Real* X2, Real* Y2)
+//    RADIX THREE FOURIER TRANSFORM KERNEL
+{
+   REPORT
+   bool NO_FOLD,ZERO;
+   int  J,K,K0,M3,M_OVER_2;
+   Real ANGLE,A,B,C1,C2,S1,S2,T,TWOPI;
+   Real I0,I1,I2,IA,IB,IS,R0,R1,R2,RA,RB,RS;
+
+   M3=M*3; M_OVER_2=M/2+1; TWOPI=8.0*atan(1.0);
+   A=cos(TWOPI/3.0); B=sin(TWOPI/3.0);
+
+   for (J=0; J<M_OVER_2; J++)
+   {
+      NO_FOLD = (J==0 || 2*J==M);
+      K0=J;
+      ANGLE=TWOPI*Real(J)/Real(M3); ZERO=ANGLE==0.0;
+      C1=cos(ANGLE); S1=sin(ANGLE);
+      C2=C1*C1-S1*S1; S2=S1*C1+C1*S1;
+      goto L200;
+   L100:
+      REPORT
+      if (NO_FOLD) { REPORT goto L600; }
+      REPORT
+      NO_FOLD=true; K0=M-J;
+      T=C1*A+S1*B; S1=C1*B-S1*A; C1=T;
+      T=C2*A-S2*B; S2= -C2*B-S2*A; C2=T;
+   L200:
+      REPORT
+      for (K=K0; K<N; K+=M3)
+      {
+         R0 = X0[K]; I0 = Y0[K];
+         RS=X1[K]+X2[K]; IS=Y1[K]+Y2[K];
+         X0[K]=R0+RS; Y0[K]=I0+IS;
+         RA=R0+RS*A; IA=I0+IS*A;
+         RB=(X1[K]-X2[K])*B; IB=(Y1[K]-Y2[K])*B;
+         if (!ZERO)
+         {
+            REPORT
+            R1=RA+IB; I1=IA-RB; R2=RA-IB; I2=IA+RB;
+            X1[K]=R1*C1+I1*S1; Y1[K]=I1*C1-R1*S1;
+            X2[K]=R2*C2+I2*S2; Y2[K]=I2*C2-R2*S2;
+         }
+         else { REPORT X1[K]=RA+IB; Y1[K]=IA-RB; X2[K]=RA-IB; Y2[K]=IA+RB; }
+      }
+      goto L100;
+   L600: ;
+   }
+
+   return;
+}
+
+static void R_4_FTK (int N, int M,
+   Real* X0, Real* Y0, Real* X1, Real* Y1,
+   Real* X2, Real* Y2, Real* X3, Real* Y3)
+//    RADIX FOUR FOURIER TRANSFORM KERNEL
+{
+   REPORT
+   bool NO_FOLD,ZERO;
+   int  J,K,K0,M4,M_OVER_2;
+   Real ANGLE,C1,C2,C3,S1,S2,S3,T,TWOPI;
+   Real I1,I2,I3,IS0,IS1,IU0,IU1,R1,R2,R3,RS0,RS1,RU0,RU1;
+
+   M4=M*4; M_OVER_2=M/2+1;
+   TWOPI=8.0*atan(1.0);
+
+   for (J=0; J<M_OVER_2; J++)
+   {
+      NO_FOLD = (J==0 || 2*J==M);
+      K0=J;
+      ANGLE=TWOPI*Real(J)/Real(M4); ZERO=ANGLE==0.0;
+      C1=cos(ANGLE); S1=sin(ANGLE);
+      C2=C1*C1-S1*S1; S2=S1*C1+C1*S1;
+      C3=C2*C1-S2*S1; S3=S2*C1+C2*S1;
+      goto L200;
+   L100:
+      REPORT
+      if (NO_FOLD) { REPORT goto L600; }
+      REPORT
+      NO_FOLD=true; K0=M-J;
+      T=C1; C1=S1; S1=T;
+      C2= -C2;
+      T=C3; C3= -S3; S3= -T;
+   L200:
+      REPORT
+      for (K=K0; K<N; K+=M4)
+      {
+         RS0=X0[K]+X2[K]; IS0=Y0[K]+Y2[K];
+         RU0=X0[K]-X2[K]; IU0=Y0[K]-Y2[K];
+         RS1=X1[K]+X3[K]; IS1=Y1[K]+Y3[K];
+         RU1=X1[K]-X3[K]; IU1=Y1[K]-Y3[K];
+         X0[K]=RS0+RS1; Y0[K]=IS0+IS1;
+         if (!ZERO)
+         {
+            REPORT
+            R1=RU0+IU1; I1=IU0-RU1;
+            R2=RS0-RS1; I2=IS0-IS1;
+            R3=RU0-IU1; I3=IU0+RU1;
+            X2[K]=R1*C1+I1*S1; Y2[K]=I1*C1-R1*S1;
+            X1[K]=R2*C2+I2*S2; Y1[K]=I2*C2-R2*S2;
+            X3[K]=R3*C3+I3*S3; Y3[K]=I3*C3-R3*S3;
+         }
+         else
+         {
+            REPORT
+            X2[K]=RU0+IU1; Y2[K]=IU0-RU1;
+            X1[K]=RS0-RS1; Y1[K]=IS0-IS1;
+            X3[K]=RU0-IU1; Y3[K]=IU0+RU1;
+         }
+      }
+      goto L100;
+   L600: ;
+   }
+
+   return;
+}
+
+static void R_5_FTK (int N, int M,
+   Real* X0, Real* Y0, Real* X1, Real* Y1, Real* X2, Real* Y2,
+   Real* X3, Real* Y3, Real* X4, Real* Y4)
+//    RADIX FIVE FOURIER TRANSFORM KERNEL
+
+{
+   REPORT
+   bool NO_FOLD,ZERO;
+   int  J,K,K0,M5,M_OVER_2;
+   Real ANGLE,A1,A2,B1,B2,C1,C2,C3,C4,S1,S2,S3,S4,T,TWOPI;
+   Real R0,R1,R2,R3,R4,RA1,RA2,RB1,RB2,RS1,RS2,RU1,RU2;
+   Real I0,I1,I2,I3,I4,IA1,IA2,IB1,IB2,IS1,IS2,IU1,IU2;
+
+   M5=M*5; M_OVER_2=M/2+1;
+   TWOPI=8.0*atan(1.0);
+   A1=cos(TWOPI/5.0); B1=sin(TWOPI/5.0);
+   A2=cos(2.0*TWOPI/5.0); B2=sin(2.0*TWOPI/5.0);
+
+   for (J=0; J<M_OVER_2; J++)
+   {
+      NO_FOLD = (J==0 || 2*J==M);
+      K0=J;
+      ANGLE=TWOPI*Real(J)/Real(M5); ZERO=ANGLE==0.0;
+      C1=cos(ANGLE); S1=sin(ANGLE);
+      C2=C1*C1-S1*S1; S2=S1*C1+C1*S1;
+      C3=C2*C1-S2*S1; S3=S2*C1+C2*S1;
+      C4=C2*C2-S2*S2; S4=S2*C2+C2*S2;
+      goto L200;
+   L100:
+      REPORT
+      if (NO_FOLD) { REPORT goto L600; }
+      REPORT
+      NO_FOLD=true; K0=M-J;
+      T=C1*A1+S1*B1; S1=C1*B1-S1*A1; C1=T;
+      T=C2*A2+S2*B2; S2=C2*B2-S2*A2; C2=T;
+      T=C3*A2-S3*B2; S3= -C3*B2-S3*A2; C3=T;
+      T=C4*A1-S4*B1; S4= -C4*B1-S4*A1; C4=T;
+   L200:
+      REPORT
+      for (K=K0; K<N; K+=M5)
+      {
+         R0=X0[K]; I0=Y0[K];
+         RS1=X1[K]+X4[K]; IS1=Y1[K]+Y4[K];
+         RU1=X1[K]-X4[K]; IU1=Y1[K]-Y4[K];
+         RS2=X2[K]+X3[K]; IS2=Y2[K]+Y3[K];
+         RU2=X2[K]-X3[K]; IU2=Y2[K]-Y3[K];
+         X0[K]=R0+RS1+RS2; Y0[K]=I0+IS1+IS2;
+         RA1=R0+RS1*A1+RS2*A2; IA1=I0+IS1*A1+IS2*A2;
+         RA2=R0+RS1*A2+RS2*A1; IA2=I0+IS1*A2+IS2*A1;
+         RB1=RU1*B1+RU2*B2; IB1=IU1*B1+IU2*B2;
+         RB2=RU1*B2-RU2*B1; IB2=IU1*B2-IU2*B1;
+         if (!ZERO)
+         {
+            REPORT
+            R1=RA1+IB1; I1=IA1-RB1;
+            R2=RA2+IB2; I2=IA2-RB2;
+            R3=RA2-IB2; I3=IA2+RB2;
+            R4=RA1-IB1; I4=IA1+RB1;
+            X1[K]=R1*C1+I1*S1; Y1[K]=I1*C1-R1*S1;
+            X2[K]=R2*C2+I2*S2; Y2[K]=I2*C2-R2*S2;
+            X3[K]=R3*C3+I3*S3; Y3[K]=I3*C3-R3*S3;
+            X4[K]=R4*C4+I4*S4; Y4[K]=I4*C4-R4*S4;
+         }
+         else
+         {
+            REPORT
+            X1[K]=RA1+IB1; Y1[K]=IA1-RB1;
+            X2[K]=RA2+IB2; Y2[K]=IA2-RB2;
+            X3[K]=RA2-IB2; Y3[K]=IA2+RB2;
+            X4[K]=RA1-IB1; Y4[K]=IA1+RB1;
+         }
+      }
+      goto L100;
+   L600: ;
+   }
+
+   return;
+}
+
+static void R_8_FTK (int N, int M,
+   Real* X0, Real* Y0, Real* X1, Real* Y1,
+   Real* X2, Real* Y2, Real* X3, Real* Y3,
+   Real* X4, Real* Y4, Real* X5, Real* Y5,
+   Real* X6, Real* Y6, Real* X7, Real* Y7)
+//    RADIX EIGHT FOURIER TRANSFORM KERNEL
+{
+   REPORT
+   bool NO_FOLD,ZERO;
+   int  J,K,K0,M8,M_OVER_2;
+   Real ANGLE,C1,C2,C3,C4,C5,C6,C7,E,S1,S2,S3,S4,S5,S6,S7,T,TWOPI;
+   Real R1,R2,R3,R4,R5,R6,R7,RS0,RS1,RS2,RS3,RU0,RU1,RU2,RU3;
+   Real I1,I2,I3,I4,I5,I6,I7,IS0,IS1,IS2,IS3,IU0,IU1,IU2,IU3;
+   Real RSS0,RSS1,RSU0,RSU1,RUS0,RUS1,RUU0,RUU1;
+   Real ISS0,ISS1,ISU0,ISU1,IUS0,IUS1,IUU0,IUU1;
+
+   M8=M*8; M_OVER_2=M/2+1;
+   TWOPI=8.0*atan(1.0); E=cos(TWOPI/8.0);
+
+   for (J=0;J<M_OVER_2;J++)
+   {
+      NO_FOLD= (J==0 || 2*J==M);
+      K0=J;
+      ANGLE=TWOPI*Real(J)/Real(M8); ZERO=ANGLE==0.0;
+      C1=cos(ANGLE); S1=sin(ANGLE);
+      C2=C1*C1-S1*S1; S2=C1*S1+S1*C1;
+      C3=C2*C1-S2*S1; S3=S2*C1+C2*S1;
+      C4=C2*C2-S2*S2; S4=S2*C2+C2*S2;
+      C5=C4*C1-S4*S1; S5=S4*C1+C4*S1;
+      C6=C4*C2-S4*S2; S6=S4*C2+C4*S2;
+      C7=C4*C3-S4*S3; S7=S4*C3+C4*S3;
+      goto L200;
+   L100:
+      REPORT
+      if (NO_FOLD) { REPORT goto L600; }
+      REPORT
+      NO_FOLD=true; K0=M-J;
+      T=(C1+S1)*E; S1=(C1-S1)*E; C1=T;
+      T=S2; S2=C2; C2=T;
+      T=(-C3+S3)*E; S3=(C3+S3)*E; C3=T;
+      C4= -C4;
+      T= -(C5+S5)*E; S5=(-C5+S5)*E; C5=T;
+      T= -S6; S6= -C6; C6=T;
+      T=(C7-S7)*E; S7= -(C7+S7)*E; C7=T;
+   L200:
+      REPORT
+      for (K=K0; K<N; K+=M8)
+      {
+         RS0=X0[K]+X4[K]; IS0=Y0[K]+Y4[K];
+         RU0=X0[K]-X4[K]; IU0=Y0[K]-Y4[K];
+         RS1=X1[K]+X5[K]; IS1=Y1[K]+Y5[K];
+         RU1=X1[K]-X5[K]; IU1=Y1[K]-Y5[K];
+         RS2=X2[K]+X6[K]; IS2=Y2[K]+Y6[K];
+         RU2=X2[K]-X6[K]; IU2=Y2[K]-Y6[K];
+         RS3=X3[K]+X7[K]; IS3=Y3[K]+Y7[K];
+         RU3=X3[K]-X7[K]; IU3=Y3[K]-Y7[K];
+         RSS0=RS0+RS2; ISS0=IS0+IS2;
+         RSU0=RS0-RS2; ISU0=IS0-IS2;
+         RSS1=RS1+RS3; ISS1=IS1+IS3;
+         RSU1=RS1-RS3; ISU1=IS1-IS3;
+         RUS0=RU0-IU2; IUS0=IU0+RU2;
+         RUU0=RU0+IU2; IUU0=IU0-RU2;
+         RUS1=RU1-IU3; IUS1=IU1+RU3;
+         RUU1=RU1+IU3; IUU1=IU1-RU3;
+         T=(RUS1+IUS1)*E; IUS1=(IUS1-RUS1)*E; RUS1=T;
+         T=(RUU1+IUU1)*E; IUU1=(IUU1-RUU1)*E; RUU1=T;
+         X0[K]=RSS0+RSS1; Y0[K]=ISS0+ISS1;
+         if (!ZERO)
+         {
+            REPORT
+            R1=RUU0+RUU1; I1=IUU0+IUU1;
+            R2=RSU0+ISU1; I2=ISU0-RSU1;
+            R3=RUS0+IUS1; I3=IUS0-RUS1;
+            R4=RSS0-RSS1; I4=ISS0-ISS1;
+            R5=RUU0-RUU1; I5=IUU0-IUU1;
+            R6=RSU0-ISU1; I6=ISU0+RSU1;
+            R7=RUS0-IUS1; I7=IUS0+RUS1;
+            X4[K]=R1*C1+I1*S1; Y4[K]=I1*C1-R1*S1;
+            X2[K]=R2*C2+I2*S2; Y2[K]=I2*C2-R2*S2;
+            X6[K]=R3*C3+I3*S3; Y6[K]=I3*C3-R3*S3;
+            X1[K]=R4*C4+I4*S4; Y1[K]=I4*C4-R4*S4;
+            X5[K]=R5*C5+I5*S5; Y5[K]=I5*C5-R5*S5;
+            X3[K]=R6*C6+I6*S6; Y3[K]=I6*C6-R6*S6;
+            X7[K]=R7*C7+I7*S7; Y7[K]=I7*C7-R7*S7;
+         }
+         else
+         {
+            REPORT
+            X4[K]=RUU0+RUU1; Y4[K]=IUU0+IUU1;
+            X2[K]=RSU0+ISU1; Y2[K]=ISU0-RSU1;
+            X6[K]=RUS0+IUS1; Y6[K]=IUS0-RUS1;
+            X1[K]=RSS0-RSS1; Y1[K]=ISS0-ISS1;
+            X5[K]=RUU0-RUU1; Y5[K]=IUU0-IUU1;
+            X3[K]=RSU0-ISU1; Y3[K]=ISU0+RSU1;
+            X7[K]=RUS0-IUS1; Y7[K]=IUS0+RUS1;
+         }
+      }
+      goto L100;
+   L600: ;
+   }
+
+   return;
+}
+
+static void R_16_FTK (int N, int M,
+   Real* X0, Real* Y0, Real* X1, Real* Y1,
+   Real* X2, Real* Y2, Real* X3, Real* Y3,
+   Real* X4, Real* Y4, Real* X5, Real* Y5,
+   Real* X6, Real* Y6, Real* X7, Real* Y7,
+   Real* X8, Real* Y8, Real* X9, Real* Y9,
+   Real* X10, Real* Y10, Real* X11, Real* Y11,
+   Real* X12, Real* Y12, Real* X13, Real* Y13,
+   Real* X14, Real* Y14, Real* X15, Real* Y15)
+//    RADIX SIXTEEN FOURIER TRANSFORM KERNEL
+{
+   REPORT
+   bool NO_FOLD,ZERO;
+   int  J,K,K0,M16,M_OVER_2;
+   Real ANGLE,EI1,ER1,E2,EI3,ER3,EI5,ER5,T,TWOPI;
+   Real RS0,RS1,RS2,RS3,RS4,RS5,RS6,RS7;
+   Real IS0,IS1,IS2,IS3,IS4,IS5,IS6,IS7;
+   Real RU0,RU1,RU2,RU3,RU4,RU5,RU6,RU7;
+   Real IU0,IU1,IU2,IU3,IU4,IU5,IU6,IU7;
+   Real RUS0,RUS1,RUS2,RUS3,RUU0,RUU1,RUU2,RUU3;
+   Real ISS0,ISS1,ISS2,ISS3,ISU0,ISU1,ISU2,ISU3;
+   Real RSS0,RSS1,RSS2,RSS3,RSU0,RSU1,RSU2,RSU3;
+   Real IUS0,IUS1,IUS2,IUS3,IUU0,IUU1,IUU2,IUU3;
+   Real RSSS0,RSSS1,RSSU0,RSSU1,RSUS0,RSUS1,RSUU0,RSUU1;
+   Real ISSS0,ISSS1,ISSU0,ISSU1,ISUS0,ISUS1,ISUU0,ISUU1;
+   Real RUSS0,RUSS1,RUSU0,RUSU1,RUUS0,RUUS1,RUUU0,RUUU1;
+   Real IUSS0,IUSS1,IUSU0,IUSU1,IUUS0,IUUS1,IUUU0,IUUU1;
+   Real R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15;
+   Real I1,I2,I3,I4,I5,I6,I7,I8,I9,I10,I11,I12,I13,I14,I15;
+   Real C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15;
+   Real S1,S2,S3,S4,S5,S6,S7,S8,S9,S10,S11,S12,S13,S14,S15;
+
+   M16=M*16; M_OVER_2=M/2+1;
+   TWOPI=8.0*atan(1.0);
+   ER1=cos(TWOPI/16.0); EI1=sin(TWOPI/16.0);
+   E2=cos(TWOPI/8.0);
+   ER3=cos(3.0*TWOPI/16.0); EI3=sin(3.0*TWOPI/16.0);
+   ER5=cos(5.0*TWOPI/16.0); EI5=sin(5.0*TWOPI/16.0);
+
+   for (J=0; J<M_OVER_2; J++)
+   {
+      NO_FOLD = (J==0 || 2*J==M);
+      K0=J;
+      ANGLE=TWOPI*Real(J)/Real(M16);
+      ZERO=ANGLE==0.0;
+      C1=cos(ANGLE); S1=sin(ANGLE);
+      C2=C1*C1-S1*S1; S2=C1*S1+S1*C1;
+      C3=C2*C1-S2*S1; S3=S2*C1+C2*S1;
+      C4=C2*C2-S2*S2; S4=S2*C2+C2*S2;
+      C5=C4*C1-S4*S1; S5=S4*C1+C4*S1;
+      C6=C4*C2-S4*S2; S6=S4*C2+C4*S2;
+      C7=C4*C3-S4*S3; S7=S4*C3+C4*S3;
+      C8=C4*C4-S4*S4; S8=C4*S4+S4*C4;
+      C9=C8*C1-S8*S1; S9=S8*C1+C8*S1;
+      C10=C8*C2-S8*S2; S10=S8*C2+C8*S2;
+      C11=C8*C3-S8*S3; S11=S8*C3+C8*S3;
+      C12=C8*C4-S8*S4; S12=S8*C4+C8*S4;
+      C13=C8*C5-S8*S5; S13=S8*C5+C8*S5;
+      C14=C8*C6-S8*S6; S14=S8*C6+C8*S6;
+      C15=C8*C7-S8*S7; S15=S8*C7+C8*S7;
+      goto L200;
+   L100:
+      REPORT
+      if (NO_FOLD) { REPORT goto L600; }
+      REPORT
+      NO_FOLD=true; K0=M-J;
+      T=C1*ER1+S1*EI1; S1= -S1*ER1+C1*EI1; C1=T;
+      T=(C2+S2)*E2; S2=(C2-S2)*E2; C2=T;
+      T=C3*ER3+S3*EI3; S3= -S3*ER3+C3*EI3; C3=T;
+      T=S4; S4=C4; C4=T;
+      T=S5*ER1-C5*EI1; S5=C5*ER1+S5*EI1; C5=T;
+      T=(-C6+S6)*E2; S6=(C6+S6)*E2; C6=T;
+      T=S7*ER3-C7*EI3; S7=C7*ER3+S7*EI3; C7=T;
+      C8= -C8;
+      T= -(C9*ER1+S9*EI1); S9=S9*ER1-C9*EI1; C9=T;
+      T= -(C10+S10)*E2; S10=(-C10+S10)*E2; C10=T;
+      T= -(C11*ER3+S11*EI3); S11=S11*ER3-C11*EI3; C11=T;
+      T= -S12; S12= -C12; C12=T;
+      T= -S13*ER1+C13*EI1; S13= -(C13*ER1+S13*EI1); C13=T;
+      T=(C14-S14)*E2; S14= -(C14+S14)*E2; C14=T;
+      T= -S15*ER3+C15*EI3; S15= -(C15*ER3+S15*EI3); C15=T;
+   L200:
+      REPORT
+      for (K=K0; K<N; K+=M16)
+      {
+         RS0=X0[K]+X8[K]; IS0=Y0[K]+Y8[K];
+         RU0=X0[K]-X8[K]; IU0=Y0[K]-Y8[K];
+         RS1=X1[K]+X9[K]; IS1=Y1[K]+Y9[K];
+         RU1=X1[K]-X9[K]; IU1=Y1[K]-Y9[K];
+         RS2=X2[K]+X10[K]; IS2=Y2[K]+Y10[K];
+         RU2=X2[K]-X10[K]; IU2=Y2[K]-Y10[K];
+         RS3=X3[K]+X11[K]; IS3=Y3[K]+Y11[K];
+         RU3=X3[K]-X11[K]; IU3=Y3[K]-Y11[K];
+         RS4=X4[K]+X12[K]; IS4=Y4[K]+Y12[K];
+         RU4=X4[K]-X12[K]; IU4=Y4[K]-Y12[K];
+         RS5=X5[K]+X13[K]; IS5=Y5[K]+Y13[K];
+         RU5=X5[K]-X13[K]; IU5=Y5[K]-Y13[K];
+         RS6=X6[K]+X14[K]; IS6=Y6[K]+Y14[K];
+         RU6=X6[K]-X14[K]; IU6=Y6[K]-Y14[K];
+         RS7=X7[K]+X15[K]; IS7=Y7[K]+Y15[K];
+         RU7=X7[K]-X15[K]; IU7=Y7[K]-Y15[K];
+         RSS0=RS0+RS4; ISS0=IS0+IS4;
+         RSS1=RS1+RS5; ISS1=IS1+IS5;
+         RSS2=RS2+RS6; ISS2=IS2+IS6;
+         RSS3=RS3+RS7; ISS3=IS3+IS7;
+         RSU0=RS0-RS4; ISU0=IS0-IS4;
+         RSU1=RS1-RS5; ISU1=IS1-IS5;
+         RSU2=RS2-RS6; ISU2=IS2-IS6;
+         RSU3=RS3-RS7; ISU3=IS3-IS7;
+         RUS0=RU0-IU4; IUS0=IU0+RU4;
+         RUS1=RU1-IU5; IUS1=IU1+RU5;
+         RUS2=RU2-IU6; IUS2=IU2+RU6;
+         RUS3=RU3-IU7; IUS3=IU3+RU7;
+         RUU0=RU0+IU4; IUU0=IU0-RU4;
+         RUU1=RU1+IU5; IUU1=IU1-RU5;
+         RUU2=RU2+IU6; IUU2=IU2-RU6;
+         RUU3=RU3+IU7; IUU3=IU3-RU7;
+         T=(RSU1+ISU1)*E2; ISU1=(ISU1-RSU1)*E2; RSU1=T;
+         T=(RSU3+ISU3)*E2; ISU3=(ISU3-RSU3)*E2; RSU3=T;
+         T=RUS1*ER3+IUS1*EI3; IUS1=IUS1*ER3-RUS1*EI3; RUS1=T;
+         T=(RUS2+IUS2)*E2; IUS2=(IUS2-RUS2)*E2; RUS2=T;
+         T=RUS3*ER5+IUS3*EI5; IUS3=IUS3*ER5-RUS3*EI5; RUS3=T;
+         T=RUU1*ER1+IUU1*EI1; IUU1=IUU1*ER1-RUU1*EI1; RUU1=T;
+         T=(RUU2+IUU2)*E2; IUU2=(IUU2-RUU2)*E2; RUU2=T;
+         T=RUU3*ER3+IUU3*EI3; IUU3=IUU3*ER3-RUU3*EI3; RUU3=T;
+         RSSS0=RSS0+RSS2; ISSS0=ISS0+ISS2;
+         RSSS1=RSS1+RSS3; ISSS1=ISS1+ISS3;
+         RSSU0=RSS0-RSS2; ISSU0=ISS0-ISS2;
+         RSSU1=RSS1-RSS3; ISSU1=ISS1-ISS3;
+         RSUS0=RSU0-ISU2; ISUS0=ISU0+RSU2;
+         RSUS1=RSU1-ISU3; ISUS1=ISU1+RSU3;
+         RSUU0=RSU0+ISU2; ISUU0=ISU0-RSU2;
+         RSUU1=RSU1+ISU3; ISUU1=ISU1-RSU3;
+         RUSS0=RUS0-IUS2; IUSS0=IUS0+RUS2;
+         RUSS1=RUS1-IUS3; IUSS1=IUS1+RUS3;
+         RUSU0=RUS0+IUS2; IUSU0=IUS0-RUS2;
+         RUSU1=RUS1+IUS3; IUSU1=IUS1-RUS3;
+         RUUS0=RUU0+RUU2; IUUS0=IUU0+IUU2;
+         RUUS1=RUU1+RUU3; IUUS1=IUU1+IUU3;
+         RUUU0=RUU0-RUU2; IUUU0=IUU0-IUU2;
+         RUUU1=RUU1-RUU3; IUUU1=IUU1-IUU3;
+         X0[K]=RSSS0+RSSS1; Y0[K]=ISSS0+ISSS1;
+         if (!ZERO)
+         {
+            REPORT
+            R1=RUUS0+RUUS1; I1=IUUS0+IUUS1;
+            R2=RSUU0+RSUU1; I2=ISUU0+ISUU1;
+            R3=RUSU0+RUSU1; I3=IUSU0+IUSU1;
+            R4=RSSU0+ISSU1; I4=ISSU0-RSSU1;
+            R5=RUUU0+IUUU1; I5=IUUU0-RUUU1;
+            R6=RSUS0+ISUS1; I6=ISUS0-RSUS1;
+            R7=RUSS0+IUSS1; I7=IUSS0-RUSS1;
+            R8=RSSS0-RSSS1; I8=ISSS0-ISSS1;
+            R9=RUUS0-RUUS1; I9=IUUS0-IUUS1;
+            R10=RSUU0-RSUU1; I10=ISUU0-ISUU1;
+            R11=RUSU0-RUSU1; I11=IUSU0-IUSU1;
+            R12=RSSU0-ISSU1; I12=ISSU0+RSSU1;
+            R13=RUUU0-IUUU1; I13=IUUU0+RUUU1;
+            R14=RSUS0-ISUS1; I14=ISUS0+RSUS1;
+            R15=RUSS0-IUSS1; I15=IUSS0+RUSS1;
+            X8[K]=R1*C1+I1*S1; Y8[K]=I1*C1-R1*S1;
+            X4[K]=R2*C2+I2*S2; Y4[K]=I2*C2-R2*S2;
+            X12[K]=R3*C3+I3*S3; Y12[K]=I3*C3-R3*S3;
+            X2[K]=R4*C4+I4*S4; Y2[K]=I4*C4-R4*S4;
+            X10[K]=R5*C5+I5*S5; Y10[K]=I5*C5-R5*S5;
+            X6[K]=R6*C6+I6*S6; Y6[K]=I6*C6-R6*S6;
+            X14[K]=R7*C7+I7*S7; Y14[K]=I7*C7-R7*S7;
+            X1[K]=R8*C8+I8*S8; Y1[K]=I8*C8-R8*S8;
+            X9[K]=R9*C9+I9*S9; Y9[K]=I9*C9-R9*S9;
+            X5[K]=R10*C10+I10*S10; Y5[K]=I10*C10-R10*S10;
+            X13[K]=R11*C11+I11*S11; Y13[K]=I11*C11-R11*S11;
+            X3[K]=R12*C12+I12*S12; Y3[K]=I12*C12-R12*S12;
+            X11[K]=R13*C13+I13*S13; Y11[K]=I13*C13-R13*S13;
+            X7[K]=R14*C14+I14*S14; Y7[K]=I14*C14-R14*S14;
+            X15[K]=R15*C15+I15*S15; Y15[K]=I15*C15-R15*S15;
+         }
+         else
+         {
+            REPORT
+            X8[K]=RUUS0+RUUS1; Y8[K]=IUUS0+IUUS1;
+            X4[K]=RSUU0+RSUU1; Y4[K]=ISUU0+ISUU1;
+            X12[K]=RUSU0+RUSU1; Y12[K]=IUSU0+IUSU1;
+            X2[K]=RSSU0+ISSU1; Y2[K]=ISSU0-RSSU1;
+            X10[K]=RUUU0+IUUU1; Y10[K]=IUUU0-RUUU1;
+            X6[K]=RSUS0+ISUS1; Y6[K]=ISUS0-RSUS1;
+            X14[K]=RUSS0+IUSS1; Y14[K]=IUSS0-RUSS1;
+            X1[K]=RSSS0-RSSS1; Y1[K]=ISSS0-ISSS1;
+            X9[K]=RUUS0-RUUS1; Y9[K]=IUUS0-IUUS1;
+            X5[K]=RSUU0-RSUU1; Y5[K]=ISUU0-ISUU1;
+            X13[K]=RUSU0-RUSU1; Y13[K]=IUSU0-IUSU1;
+            X3[K]=RSSU0-ISSU1; Y3[K]=ISSU0+RSSU1;
+            X11[K]=RUUU0-IUUU1; Y11[K]=IUUU0+RUUU1;
+            X7[K]=RSUS0-ISUS1; Y7[K]=ISUS0+RSUS1;
+            X15[K]=RUSS0-IUSS1; Y15[K]=IUSS0+RUSS1;
+         }
+      }
+      goto L100;
+   L600: ;
+   }
+
+   return;
+}
+
+// can the number of points be factorised sufficiently
+// for the fft to run
+
+bool FFT_Controller::CanFactor(int PTS)
+{
+   REPORT
+   const int NP = 16, NQ = 10, PMAX=19;
+
+   if (PTS<=1) { REPORT return true; }
+
+   int N = PTS, F = 2, P = 0, Q = 0;
+
+   while (N > 1)
+   {
+      bool fail = true;
+      for (int J = F; J <= PMAX; J++)
+         if (N % J == 0) { fail = false; F=J; break; }
+      if (fail || P >= NP || Q >= NQ) { REPORT return false; }
+      N /= F;
+      if (N % F != 0) Q++; else { N /= F; P++; }
+   }
+
+   return true;    // can factorise
+
+}
+
+bool FFT_Controller::OnlyOldFFT;         // static variable
+
+// **************************** multi radix counter **********************
+
+MultiRadixCounter::MultiRadixCounter(int nx, const SimpleIntArray& rx,
+   SimpleIntArray& vx)
+   : Radix(rx), Value(vx), n(nx), reverse(0),
+      product(1), counter(0), finish(false)
+{
+   REPORT for (int k = 0; k < n; k++) { Value[k] = 0; product *= Radix[k]; }
+}
+
+void MultiRadixCounter::operator++()
+{
+   REPORT
+   counter++; int p = product;
+   for (int k = 0; k < n; k++)
+   {
+      Value[k]++; int p1 = p / Radix[k]; reverse += p1;
+      if (Value[k] == Radix[k]) { REPORT Value[k] = 0; reverse -= p; p = p1; }
+      else { REPORT return; }
+   }
+   finish = true;
+}
+
+
+static int BitReverse(int x, int prod, int n, const SimpleIntArray& f)
+{
+   // x = c[0]+f[0]*(c[1]+f[1]*(c[2]+...
+   // return c[n-1]+f[n-1]*(c[n-2]+f[n-2]*(c[n-3]+...
+   // prod is the product of the f[i]
+   // n is the number of f[i] (don't assume f has the correct length)
+
+   REPORT
+   const int* d = f.Data() + n; int sum = 0; int q = 1;
+   while (n--)
+   {
+      prod /= *(--d);
+      int c = x / prod; x-= c * prod;
+      sum += q * c; q *= *d;
+   }
+   return sum;
+}
+
+
+#ifdef use_namespace
+}
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat.h b/Utilities/OSSIM/ossim_core/matrix/newmat.h
new file mode 100644
index 0000000000..3bc64194b6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat.h
@@ -0,0 +1,1805 @@
+//$$ newmat.h           definition file for new version of matrix package
+
+// Copyright (C) 1991,2,3,4,7,2000,2,3: R B Davies
+
+#ifndef NEWMAT_LIB
+#define NEWMAT_LIB 0
+
+#include "include.h"
+
+#include "myexcept.h"
+
+
+#ifdef use_namespace
+namespace NEWMAT { using namespace RBD_COMMON; }
+namespace RBD_LIBRARIES { using namespace NEWMAT; }
+namespace NEWMAT {
+#endif
+
+//#define DO_REPORT                     // to activate REPORT
+
+#ifdef NO_LONG_NAMES
+#define UpperTriangularMatrix UTMatrix
+#define LowerTriangularMatrix LTMatrix
+#define SymmetricMatrix SMatrix
+#define DiagonalMatrix DMatrix
+#define BandMatrix BMatrix
+#define UpperBandMatrix UBMatrix
+#define LowerBandMatrix LBMatrix
+#define SymmetricBandMatrix SBMatrix
+#define BandLUMatrix BLUMatrix
+#endif
+
+// ************************** general utilities ****************************/
+
+class GeneralMatrix;
+
+void MatrixErrorNoSpace(const void*);                 // no space handler
+
+class LogAndSign
+// Return from LogDeterminant function
+//    - value of the log plus the sign (+, - or 0)
+{
+   Real log_value;
+   int sign;
+public:
+   LogAndSign() { log_value=0.0; sign=1; }
+   LogAndSign(Real);
+   void operator*=(Real);
+   void PowEq(int k);  // raise to power of k
+   void ChangeSign() { sign = -sign; }
+   Real LogValue() const { return log_value; }
+   int Sign() const { return sign; }
+   Real Value() const;
+   FREE_CHECK(LogAndSign)
+};
+
+// the following class is for counting the number of times a piece of code
+// is executed. It is used for locating any code not executed by test
+// routines. Use turbo GREP locate all places this code is called and
+// check which ones are not accessed.
+// Somewhat implementation dependent as it relies on "cout" still being
+// present when ExeCounter objects are destructed.
+
+#ifdef DO_REPORT
+
+class ExeCounter
+{
+   int line;                                    // code line number
+   int fileid;                                  // file identifier
+   long nexe;                                   // number of executions
+   static int nreports;                         // number of reports
+public:
+   ExeCounter(int,int);
+   void operator++() { nexe++; }
+   ~ExeCounter();                               // prints out reports
+};
+
+#endif
+
+
+// ************************** class MatrixType *****************************/
+
+// Is used for finding the type of a matrix resulting from the binary operations
+// +, -, * and identifying what conversions are permissible.
+// This class must be updated when new matrix types are added.
+
+class GeneralMatrix;                            // defined later
+class BaseMatrix;                               // defined later
+class MatrixInput;                              // defined later
+
+class OSSIM_DLL MatrixType
+{
+public:
+   enum Attribute {  Valid     = 1,
+                     Diagonal  = 2,             // order of these is important
+                     Symmetric = 4,
+                     Band      = 8,
+                     Lower     = 16,
+                     Upper     = 32,
+                     Square    = 64,
+                     Skew      = 128,
+                     LUDeco    = 256,
+                     Ones      = 512 };
+
+   enum            { US = 0,
+                     UT = Valid + Upper + Square,
+                     LT = Valid + Lower + Square,
+                     Rt = Valid,
+                     Sq = Valid + Square,
+                     Sm = Valid + Symmetric + Square,
+                     Sk = Valid + Skew + Square,
+                     Dg = Valid + Diagonal + Band + Lower + Upper + Symmetric
+                        + Square,
+                     Id = Valid + Diagonal + Band + Lower + Upper + Symmetric
+                        + Square + Ones,
+                     RV = Valid,     //   do not separate out
+                     CV = Valid,     //   vectors
+                     BM = Valid + Band + Square,
+                     UB = Valid + Band + Upper + Square,
+                     LB = Valid + Band + Lower + Square,
+                     SB = Valid + Band + Symmetric + Square,
+                     Ct = Valid + LUDeco + Square,
+                     BC = Valid + Band + LUDeco + Square,
+                     Mask = ~Square
+                   };
+
+
+   static int nTypes() { return 12; }          // number of different types
+					       // exclude Ct, US, BC
+public:
+   int attribute;
+   bool DataLossOK;                            // true if data loss is OK when
+                                               // this represents a destination
+public:
+   MatrixType () : DataLossOK(false) {}
+   MatrixType (int i) : attribute(i), DataLossOK(false) {}
+   MatrixType (int i, bool dlok) : attribute(i), DataLossOK(dlok) {}
+   MatrixType (const MatrixType& mt)
+      : attribute(mt.attribute), DataLossOK(mt.DataLossOK) {}
+   void operator=(const MatrixType& mt)
+      { attribute = mt.attribute; DataLossOK = mt.DataLossOK; }
+   void SetDataLossOK() { DataLossOK = true; }
+   int operator+() const { return attribute; }
+   MatrixType operator+(MatrixType mt) const
+      { return MatrixType(attribute & mt.attribute); }
+   MatrixType operator*(const MatrixType&) const;
+   MatrixType SP(const MatrixType&) const;
+   MatrixType KP(const MatrixType&) const;
+   MatrixType operator|(const MatrixType& mt) const
+      { return MatrixType(attribute & mt.attribute & Valid); }
+   MatrixType operator&(const MatrixType& mt) const
+      { return MatrixType(attribute & mt.attribute & Valid); }
+   bool operator>=(MatrixType mt) const
+      { return ( attribute & ~mt.attribute & Mask ) == 0; }
+   bool operator<(MatrixType mt) const         // for MS Visual C++ 4
+      { return ( attribute & ~mt.attribute & Mask ) != 0; }
+   bool operator==(MatrixType t) const
+      { return (attribute == t.attribute); }
+   bool operator!=(MatrixType t) const
+      { return (attribute != t.attribute); }
+   bool operator!() const { return (attribute & Valid) == 0; }
+   MatrixType i() const;                       // type of inverse
+   MatrixType t() const;                       // type of transpose
+   MatrixType AddEqualEl() const               // Add constant to matrix
+      { return MatrixType(attribute & (Valid + Symmetric + Square)); }
+   MatrixType MultRHS() const;                 // type for rhs of multiply
+   MatrixType sub() const                      // type of submatrix
+      { return MatrixType(attribute & Valid); }
+   MatrixType ssub() const                     // type of sym submatrix
+      { return MatrixType(attribute); }        // not for selection matrix
+   GeneralMatrix* New() const;                 // new matrix of given type
+   GeneralMatrix* New(int,int,BaseMatrix*) const;
+                                               // new matrix of given type
+   const char* Value() const;                  // to print type
+   friend bool Rectangular(MatrixType a, MatrixType b, MatrixType c);
+   friend bool Compare(const MatrixType&, MatrixType&);
+                                               // compare and check conv.
+   bool IsBand() const { return (attribute & Band) != 0; }
+   bool IsDiagonal() const { return (attribute & Diagonal) != 0; }
+   bool IsSymmetric() const { return (attribute & Symmetric) != 0; }
+   bool CannotConvert() const { return (attribute & LUDeco) != 0; }
+                                               // used by operator== 
+   FREE_CHECK(MatrixType)
+};
+
+
+// *********************** class MatrixBandWidth ***********************/
+
+class OSSIM_DLL MatrixBandWidth
+{
+public:
+   int lower;
+   int upper;
+   MatrixBandWidth(const int l, const int u) : lower(l), upper (u) {}
+   MatrixBandWidth(const int i) : lower(i), upper(i) {}
+   MatrixBandWidth operator+(const MatrixBandWidth&) const;
+   MatrixBandWidth operator*(const MatrixBandWidth&) const;
+   MatrixBandWidth minimum(const MatrixBandWidth&) const;
+   MatrixBandWidth t() const { return MatrixBandWidth(upper,lower); }
+   bool operator==(const MatrixBandWidth& bw) const
+      { return (lower == bw.lower) && (upper == bw.upper); }
+   bool operator!=(const MatrixBandWidth& bw) const { return !operator==(bw); }
+   int Upper() const { return upper; }
+   int Lower() const { return lower; }
+   FREE_CHECK(MatrixBandWidth)
+};
+
+
+// ********************* Array length specifier ************************/
+
+// This class is introduced to avoid constructors such as
+//   ColumnVector(int)
+// being used for conversions
+
+class OSSIM_DLL ArrayLengthSpecifier
+{
+   int value;
+public:
+   int Value() const { return value; }
+   ArrayLengthSpecifier(int l) : value(l) {}
+};
+
+// ************************* Matrix routines ***************************/
+
+
+class MatrixRowCol;                             // defined later
+class MatrixRow;
+class MatrixCol;
+class MatrixColX;
+
+class GeneralMatrix;                            // defined later
+class AddedMatrix;
+class MultipliedMatrix;
+class SubtractedMatrix;
+class SPMatrix;
+class KPMatrix;
+class ConcatenatedMatrix;
+class StackedMatrix;
+class SolvedMatrix;
+class ShiftedMatrix;
+class NegShiftedMatrix;
+class ScaledMatrix;
+class TransposedMatrix;
+class ReversedMatrix;
+class NegatedMatrix;
+class InvertedMatrix;
+class RowedMatrix;
+class ColedMatrix;
+class DiagedMatrix;
+class MatedMatrix;
+class GetSubMatrix;
+class ReturnMatrix;
+class Matrix;
+class SquareMatrix;
+class nricMatrix;
+class RowVector;
+class ColumnVector;
+class SymmetricMatrix;
+class UpperTriangularMatrix;
+class LowerTriangularMatrix;
+class DiagonalMatrix;
+class CroutMatrix;
+class BandMatrix;
+class LowerBandMatrix;
+class UpperBandMatrix;
+class SymmetricBandMatrix;
+class LinearEquationSolver;
+class GenericMatrix;
+
+
+#define MatrixTypeUnSp 0
+//static MatrixType MatrixTypeUnSp(MatrixType::US);
+//						// AT&T needs this
+
+class OSSIM_DLL BaseMatrix : public Janitor               // base of all matrix classes
+{
+protected:
+   virtual int search(const BaseMatrix*) const = 0;
+						// count number of times matrix
+   						// is referred to
+
+public:
+   virtual GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp) = 0;
+						// evaluate temporary
+   // for old version of G++
+   //   virtual GeneralMatrix* Evaluate(MatrixType mt) = 0;
+   //   GeneralMatrix* Evaluate() { return Evaluate(MatrixTypeUnSp); }
+   AddedMatrix operator+(const BaseMatrix&) const;    // results of operations
+   MultipliedMatrix operator*(const BaseMatrix&) const;
+   SubtractedMatrix operator-(const BaseMatrix&) const;
+   ConcatenatedMatrix operator|(const BaseMatrix&) const;
+   StackedMatrix operator&(const BaseMatrix&) const;
+   ShiftedMatrix operator+(Real) const;
+   ScaledMatrix operator*(Real) const;
+   ScaledMatrix operator/(Real) const;
+   ShiftedMatrix operator-(Real) const;
+   TransposedMatrix t() const;
+//   TransposedMatrix t;
+   NegatedMatrix operator-() const;                   // change sign of elements
+   ReversedMatrix Reverse() const;
+   InvertedMatrix i() const;
+//   InvertedMatrix i;
+   RowedMatrix AsRow() const;
+   ColedMatrix AsColumn() const;
+   DiagedMatrix AsDiagonal() const;
+   MatedMatrix AsMatrix(int,int) const;
+   GetSubMatrix SubMatrix(int,int,int,int) const;
+   GetSubMatrix SymSubMatrix(int,int) const;
+   GetSubMatrix Row(int) const;
+   GetSubMatrix Rows(int,int) const;
+   GetSubMatrix Column(int) const;
+   GetSubMatrix Columns(int,int) const;
+   Real AsScalar() const;                      // conversion of 1 x 1 matrix
+   virtual LogAndSign LogDeterminant() const;
+   Real Determinant() const;
+   virtual Real SumSquare() const;
+   Real NormFrobenius() const;
+   virtual Real SumAbsoluteValue() const;
+   virtual Real Sum() const;
+   virtual Real MaximumAbsoluteValue() const;
+   virtual Real MaximumAbsoluteValue1(int& i) const;
+   virtual Real MaximumAbsoluteValue2(int& i, int& j) const;
+   virtual Real MinimumAbsoluteValue() const;
+   virtual Real MinimumAbsoluteValue1(int& i) const;
+   virtual Real MinimumAbsoluteValue2(int& i, int& j) const;
+   virtual Real Maximum() const;
+   virtual Real Maximum1(int& i) const;
+   virtual Real Maximum2(int& i, int& j) const;
+   virtual Real Minimum() const;
+   virtual Real Minimum1(int& i) const;
+   virtual Real Minimum2(int& i, int& j) const;
+   virtual Real Trace() const;
+   Real Norm1() const;
+   Real NormInfinity() const;
+   virtual MatrixBandWidth BandWidth() const;  // bandwidths of band matrix
+   virtual void CleanUp() {}                   // to clear store
+   void IEQND() const;                         // called by ineq. ops
+//   virtual ReturnMatrix Reverse() const;       // reverse order of elements
+//protected:
+//   BaseMatrix() : t(this), i(this) {}
+
+   friend class GeneralMatrix;
+   friend class Matrix;
+   friend class SquareMatrix;
+   friend class nricMatrix;
+   friend class RowVector;
+   friend class ColumnVector;
+   friend class SymmetricMatrix;
+   friend class UpperTriangularMatrix;
+   friend class LowerTriangularMatrix;
+   friend class DiagonalMatrix;
+   friend class CroutMatrix;
+   friend class BandMatrix;
+   friend class LowerBandMatrix;
+   friend class UpperBandMatrix;
+   friend class SymmetricBandMatrix;
+   friend class AddedMatrix;
+   friend class MultipliedMatrix;
+   friend class SubtractedMatrix;
+   friend class SPMatrix;
+   friend class KPMatrix;
+   friend class ConcatenatedMatrix;
+   friend class StackedMatrix;
+   friend class SolvedMatrix;
+   friend class ShiftedMatrix;
+   friend class NegShiftedMatrix;
+   friend class ScaledMatrix;
+   friend class TransposedMatrix;
+   friend class ReversedMatrix;
+   friend class NegatedMatrix;
+   friend class InvertedMatrix;
+   friend class RowedMatrix;
+   friend class ColedMatrix;
+   friend class DiagedMatrix;
+   friend class MatedMatrix;
+   friend class GetSubMatrix;
+   friend class ReturnMatrix;
+   friend class LinearEquationSolver;
+   friend class GenericMatrix;
+   NEW_DELETE(BaseMatrix)
+};
+
+
+// ***************************** working classes **************************/
+
+class OSSIM_DLL GeneralMatrix : public BaseMatrix         // declarable matrix types
+{
+   virtual GeneralMatrix* Image() const;        // copy of matrix
+protected:
+   int tag;                                     // shows whether can reuse
+   int nrows, ncols;                            // dimensions
+   int storage;                                 // total store required
+   Real* store;                                 // point to store (0=not set)
+   GeneralMatrix();                             // initialise with no store
+   GeneralMatrix(ArrayLengthSpecifier);         // constructor getting store
+   void Add(GeneralMatrix*, Real);              // sum of GM and Real
+   void Add(Real);                              // add Real to this
+   void NegAdd(GeneralMatrix*, Real);           // Real - GM
+   void NegAdd(Real);                           // this = this - Real
+   void Multiply(GeneralMatrix*, Real);         // product of GM and Real
+   void Multiply(Real);                         // multiply this by Real
+   void Negate(GeneralMatrix*);                 // change sign
+   void Negate();                               // change sign
+   void ReverseElements();                      // internal reverse of elements
+   void ReverseElements(GeneralMatrix*);        // reverse order of elements
+   void operator=(Real);                        // set matrix to constant
+   Real* GetStore();                            // get store or copy
+   GeneralMatrix* BorrowStore(GeneralMatrix*, MatrixType);
+                                                // temporarily access store
+   void GetMatrix(const GeneralMatrix*);        // used by = and initialise
+   void Eq(const BaseMatrix&, MatrixType);      // used by =
+   void Eq(const GeneralMatrix&);               // version with no conversion
+   void Eq(const BaseMatrix&, MatrixType, bool);// used by <<
+   void Eq2(const BaseMatrix&, MatrixType);     // cut down version of Eq
+   int search(const BaseMatrix*) const;
+   virtual GeneralMatrix* Transpose(TransposedMatrix*, MatrixType);
+   void CheckConversion(const BaseMatrix&);     // check conversion OK
+   void ReSize(int, int, int);                  // change dimensions
+   virtual short SimpleAddOK(const GeneralMatrix* /* gm */ ) { return 0; }
+             // see bandmat.cpp for explanation
+   virtual void MiniCleanUp() { store = 0; storage = 0; nrows = 0; ncols = 0; tag = -1;}
+             // CleanUp when the data array has already been deleted
+   void PlusEqual(const GeneralMatrix& gm);
+   void MinusEqual(const GeneralMatrix& gm);
+   void PlusEqual(Real f);
+   void MinusEqual(Real f);
+public:
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   virtual MatrixType Type() const = 0;         // type of a matrix
+   int Nrows() const { return nrows; }          // get dimensions
+   int Ncols() const { return ncols; }
+   int Storage() const { return storage; }
+   Real* Store() const { return store; }
+   virtual ~GeneralMatrix();                    // delete store if set
+   void tDelete();                              // delete if tag permits
+   bool reuse();                                // true if tag allows reuse
+   void Protect() { tag=-1; }                   // cannot delete or reuse
+   int Tag() const { return tag; }
+   bool IsZero() const;                         // test matrix has all zeros
+   void Release() { tag=1; }                    // del store after next use
+   void Release(int t) { tag=t; }               // del store after t accesses
+   void ReleaseAndDelete() { tag=0; }           // delete matrix after use
+   void operator<<(const Real*);                // assignment from an array
+   void operator<<(const int*);                // assignment from an array
+   void operator<<(const BaseMatrix& X)
+      { Eq(X,this->Type(),true); }              // = without checking type
+   void Inject(const GeneralMatrix&);           // copy stored els only
+   void operator+=(const BaseMatrix&);
+   void operator-=(const BaseMatrix&);
+   void operator*=(const BaseMatrix&);
+   void operator|=(const BaseMatrix&);
+   void operator&=(const BaseMatrix&);
+   void operator+=(Real);
+   void operator-=(Real r) { operator+=(-r); }
+   void operator*=(Real);
+   void operator/=(Real r) { operator*=(1.0/r); }
+   virtual GeneralMatrix* MakeSolver();         // for solving
+   virtual void Solver(MatrixColX&, const MatrixColX&) {}
+   virtual void GetRow(MatrixRowCol&) = 0;      // Get matrix row
+   virtual void RestoreRow(MatrixRowCol&) {}    // Restore matrix row
+   virtual void NextRow(MatrixRowCol&);         // Go to next row
+   virtual void GetCol(MatrixRowCol&) = 0;      // Get matrix col
+   virtual void GetCol(MatrixColX&) = 0;        // Get matrix col
+   virtual void RestoreCol(MatrixRowCol&) {}    // Restore matrix col
+   virtual void RestoreCol(MatrixColX&) {}      // Restore matrix col
+   virtual void NextCol(MatrixRowCol&);         // Go to next col
+   virtual void NextCol(MatrixColX&);           // Go to next col
+   Real SumSquare() const;
+   Real SumAbsoluteValue() const;
+   Real Sum() const;
+   Real MaximumAbsoluteValue1(int& i) const;
+   Real MinimumAbsoluteValue1(int& i) const;
+   Real Maximum1(int& i) const;
+   Real Minimum1(int& i) const;
+   Real MaximumAbsoluteValue() const;
+   Real MaximumAbsoluteValue2(int& i, int& j) const;
+   Real MinimumAbsoluteValue() const;
+   Real MinimumAbsoluteValue2(int& i, int& j) const;
+   Real Maximum() const;
+   Real Maximum2(int& i, int& j) const;
+   Real Minimum() const;
+   Real Minimum2(int& i, int& j) const;
+   LogAndSign LogDeterminant() const;
+   virtual bool IsEqual(const GeneralMatrix&) const;
+                                                // same type, same values
+   void CheckStore() const;                     // check store is non-zero
+   virtual void SetParameters(const GeneralMatrix*) {}
+                                                // set parameters in GetMatrix
+   operator ReturnMatrix() const;               // for building a ReturnMatrix
+   ReturnMatrix ForReturn() const;
+   virtual bool SameStorageType(const GeneralMatrix& A) const;
+   virtual void ReSizeForAdd(const GeneralMatrix& A, const GeneralMatrix& B);
+   virtual void ReSizeForSP(const GeneralMatrix& A, const GeneralMatrix& B);
+   virtual void ReSize(const GeneralMatrix& A);
+   MatrixInput operator<<(Real);                // for loading a list
+   MatrixInput operator<<(int f);
+//   ReturnMatrix Reverse() const;                // reverse order of elements
+   void CleanUp();                              // to clear store
+
+   friend class Matrix;
+   friend class SquareMatrix;
+   friend class nricMatrix;
+   friend class SymmetricMatrix;
+   friend class UpperTriangularMatrix;
+   friend class LowerTriangularMatrix;
+   friend class DiagonalMatrix;
+   friend class CroutMatrix;
+   friend class RowVector;
+   friend class ColumnVector;
+   friend class BandMatrix;
+   friend class LowerBandMatrix;
+   friend class UpperBandMatrix;
+   friend class SymmetricBandMatrix;
+   friend class BaseMatrix;
+   friend class AddedMatrix;
+   friend class MultipliedMatrix;
+   friend class SubtractedMatrix;
+   friend class SPMatrix;
+   friend class KPMatrix;
+   friend class ConcatenatedMatrix;
+   friend class StackedMatrix;
+   friend class SolvedMatrix;
+   friend class ShiftedMatrix;
+   friend class NegShiftedMatrix;
+   friend class ScaledMatrix;
+   friend class TransposedMatrix;
+   friend class ReversedMatrix;
+   friend class NegatedMatrix;
+   friend class InvertedMatrix;
+   friend class RowedMatrix;
+   friend class ColedMatrix;
+   friend class DiagedMatrix;
+   friend class MatedMatrix;
+   friend class GetSubMatrix;
+   friend class ReturnMatrix;
+   friend class LinearEquationSolver;
+   friend class GenericMatrix;
+   NEW_DELETE(GeneralMatrix)
+};
+
+
+
+class OSSIM_DLL Matrix : public GeneralMatrix             // usual rectangular matrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   Matrix():GeneralMatrix() {}
+   ~Matrix() {}
+   Matrix(int, int);                            // standard declaration
+   Matrix(const BaseMatrix&);                   // evaluate BaseMatrix
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const Matrix& m) { Eq(m); }
+   MatrixType Type() const;
+   Real& operator()(int, int);                  // access element
+   Real& element(int, int);                     // access element
+   Real operator()(int, int) const;            // access element
+   Real element(int, int) const;               // access element
+#ifdef SETUP_C_SUBSCRIPTS
+   Real* operator[](int m) { return store+m*ncols; }
+   const Real* operator[](int m) const { return store+m*ncols; }
+#endif
+   Matrix(const Matrix& gm):GeneralMatrix(gm) { GetMatrix(&gm); }
+   GeneralMatrix* MakeSolver();
+   Real Trace() const;
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX&);
+   void RestoreCol(MatrixRowCol&);
+   void RestoreCol(MatrixColX&);
+   void NextRow(MatrixRowCol&);
+   void NextCol(MatrixRowCol&);
+   void NextCol(MatrixColX&);
+   virtual void ReSize(int,int);           // change dimensions
+      // virtual so we will catch it being used in a vector called as a matrix
+   void ReSize(const GeneralMatrix& A);
+   Real MaximumAbsoluteValue2(int& i, int& j) const;
+   Real MinimumAbsoluteValue2(int& i, int& j) const;
+   Real Maximum2(int& i, int& j) const;
+   Real Minimum2(int& i, int& j) const;
+   void operator+=(const Matrix& M) { PlusEqual(M); }
+   void operator-=(const Matrix& M) { MinusEqual(M); }
+   void operator+=(Real f) { GeneralMatrix::Add(f); }
+   void operator-=(Real f) { GeneralMatrix::Add(-f); }
+   friend Real DotProduct(const Matrix& A, const Matrix& B);
+   NEW_DELETE(Matrix)
+};
+
+class OSSIM_DLL SquareMatrix : public Matrix              // square matrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   SquareMatrix() {}
+   ~SquareMatrix() {}
+   SquareMatrix(ArrayLengthSpecifier);          // standard declaration
+   SquareMatrix(const BaseMatrix&);             // evaluate BaseMatrix
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const SquareMatrix& m) { Eq(m); }
+   void operator=(const Matrix& m);
+   MatrixType Type() const;
+   SquareMatrix(const SquareMatrix& gm):Matrix(gm) { GetMatrix(&gm); }
+   SquareMatrix(const Matrix& gm);
+   void ReSize(int);                            // change dimensions
+   virtual void ReSize(int,int);                // change dimensions
+      // virtual so we will catch it being used in a vector called as a matrix
+   void ReSize(const GeneralMatrix& A);
+   void operator+=(const Matrix& M) { PlusEqual(M); }
+   void operator-=(const Matrix& M) { MinusEqual(M); }
+   void operator+=(Real f) { GeneralMatrix::Add(f); }
+   void operator-=(Real f) { GeneralMatrix::Add(-f); }
+   NEW_DELETE(SquareMatrix)
+};
+
+class OSSIM_DLL nricMatrix : public Matrix                // for use with Numerical
+                                                // Recipes in C
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+   Real** row_pointer;                          // points to rows
+   void MakeRowPointer();                       // build rowpointer
+   void DeleteRowPointer();
+public:
+   nricMatrix():Matrix() {}
+   nricMatrix(int m, int n)                     // standard declaration
+      :  Matrix(m,n) { MakeRowPointer(); }
+   nricMatrix(const BaseMatrix& bm)             // evaluate BaseMatrix
+      :  Matrix(bm) { MakeRowPointer(); }
+   void operator=(const BaseMatrix& bm)
+      { DeleteRowPointer(); Matrix::operator=(bm); MakeRowPointer(); }
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const nricMatrix& m)
+      { DeleteRowPointer(); Eq(m); MakeRowPointer(); }
+   void operator<<(const BaseMatrix& X)
+      { DeleteRowPointer(); Eq(X,this->Type(),true); MakeRowPointer(); }
+   nricMatrix(const nricMatrix& gm):Matrix(gm) { GetMatrix(&gm); MakeRowPointer(); }
+   void ReSize(int m, int n)               // change dimensions
+      { DeleteRowPointer(); Matrix::ReSize(m,n); MakeRowPointer(); }
+   void ReSize(const GeneralMatrix& A);
+   ~nricMatrix() { DeleteRowPointer(); }
+   Real** nric() const { CheckStore(); return row_pointer-1; }
+   void CleanUp();                                // to clear store
+   void MiniCleanUp();
+   void operator+=(const Matrix& M) { PlusEqual(M); }
+   void operator-=(const Matrix& M) { MinusEqual(M); }
+   void operator+=(Real f) { GeneralMatrix::Add(f); }
+   void operator-=(Real f) { GeneralMatrix::Add(-f); }
+   NEW_DELETE(nricMatrix)
+};
+
+class OSSIM_DLL SymmetricMatrix : public GeneralMatrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   SymmetricMatrix():GeneralMatrix() {}
+   ~SymmetricMatrix() {}
+   SymmetricMatrix(ArrayLengthSpecifier);
+   SymmetricMatrix(const BaseMatrix&);
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const SymmetricMatrix& m) { Eq(m); }
+   Real& operator()(int, int);                  // access element
+   Real& element(int, int);                     // access element
+   Real operator()(int, int) const;             // access element
+   Real element(int, int) const;                // access element
+#ifdef SETUP_C_SUBSCRIPTS
+   Real* operator[](int m) { return store+(m*(m+1))/2; }
+   const Real* operator[](int m) const { return store+(m*(m+1))/2; }
+#endif
+   MatrixType Type() const;
+   SymmetricMatrix(const SymmetricMatrix& gm):GeneralMatrix(gm) { GetMatrix(&gm); }
+   Real SumSquare() const;
+   Real SumAbsoluteValue() const;
+   Real Sum() const;
+   Real Trace() const;
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX&);
+   void RestoreCol(MatrixRowCol&) {}
+   void RestoreCol(MatrixColX&);
+	GeneralMatrix* Transpose(TransposedMatrix*, MatrixType);
+   void ReSize(int);                       // change dimensions
+   void ReSize(const GeneralMatrix& A);
+   void operator+=(const SymmetricMatrix& M) { PlusEqual(M); }
+   void operator-=(const SymmetricMatrix& M) { MinusEqual(M); }
+   void operator+=(Real f) { GeneralMatrix::Add(f); }
+   void operator-=(Real f) { GeneralMatrix::Add(-f); }
+   NEW_DELETE(SymmetricMatrix)
+};
+
+class OSSIM_DLL UpperTriangularMatrix : public GeneralMatrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   UpperTriangularMatrix():GeneralMatrix() {}
+   ~UpperTriangularMatrix() {}
+   UpperTriangularMatrix(ArrayLengthSpecifier);
+   void operator=(const BaseMatrix&);
+   void operator=(const UpperTriangularMatrix& m) { Eq(m); }
+   UpperTriangularMatrix(const BaseMatrix&);
+   UpperTriangularMatrix(const UpperTriangularMatrix& gm):GeneralMatrix(gm) { GetMatrix(&gm); }
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   Real& operator()(int, int);                  // access element
+   Real& element(int, int);                     // access element
+   Real operator()(int, int) const;             // access element
+   Real element(int, int) const;                // access element
+#ifdef SETUP_C_SUBSCRIPTS
+   Real* operator[](int m) { return store+m*ncols-(m*(m+1))/2; }
+   const Real* operator[](int m) const { return store+m*ncols-(m*(m+1))/2; }
+#endif
+   MatrixType Type() const;
+   GeneralMatrix* MakeSolver() { return this; } // for solving
+   void Solver(MatrixColX&, const MatrixColX&);
+   LogAndSign LogDeterminant() const;
+   Real Trace() const;
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX&);
+   void RestoreCol(MatrixRowCol&);
+   void RestoreCol(MatrixColX& c) { RestoreCol((MatrixRowCol&)c); }
+   void NextRow(MatrixRowCol&);
+   void ReSize(int);                       // change dimensions
+   void ReSize(const GeneralMatrix& A);
+   MatrixBandWidth BandWidth() const;
+   void operator+=(const UpperTriangularMatrix& M) { PlusEqual(M); }
+   void operator-=(const UpperTriangularMatrix& M) { MinusEqual(M); }
+   void operator+=(Real f) { GeneralMatrix::operator+=(f); }
+   void operator-=(Real f) { GeneralMatrix::operator-=(f); }
+   NEW_DELETE(UpperTriangularMatrix)
+};
+
+class OSSIM_DLL LowerTriangularMatrix : public GeneralMatrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   LowerTriangularMatrix():GeneralMatrix() {}
+   ~LowerTriangularMatrix() {}
+   LowerTriangularMatrix(ArrayLengthSpecifier);
+   LowerTriangularMatrix(const LowerTriangularMatrix& gm):GeneralMatrix(gm) { GetMatrix(&gm); }
+   LowerTriangularMatrix(const BaseMatrix& M);
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const LowerTriangularMatrix& m) { Eq(m); }
+   Real& operator()(int, int);                  // access element
+   Real& element(int, int);                     // access element
+   Real operator()(int, int) const;             // access element
+   Real element(int, int) const;                // access element
+#ifdef SETUP_C_SUBSCRIPTS
+   Real* operator[](int m) { return store+(m*(m+1))/2; }
+   const Real* operator[](int m) const { return store+(m*(m+1))/2; }
+#endif
+   MatrixType Type() const;
+   GeneralMatrix* MakeSolver() { return this; } // for solving
+   void Solver(MatrixColX&, const MatrixColX&);
+   LogAndSign LogDeterminant() const;
+   Real Trace() const;
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX&);
+   void RestoreCol(MatrixRowCol&);
+   void RestoreCol(MatrixColX& c) { RestoreCol((MatrixRowCol&)c); }
+   void NextRow(MatrixRowCol&);
+   void ReSize(int);                       // change dimensions
+   void ReSize(const GeneralMatrix& A);
+   MatrixBandWidth BandWidth() const;
+   void operator+=(const LowerTriangularMatrix& M) { PlusEqual(M); }
+   void operator-=(const LowerTriangularMatrix& M) { MinusEqual(M); }
+   void operator+=(Real f) { GeneralMatrix::operator+=(f); }
+   void operator-=(Real f) { GeneralMatrix::operator-=(f); }
+   NEW_DELETE(LowerTriangularMatrix)
+};
+
+class OSSIM_DLL DiagonalMatrix : public GeneralMatrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   DiagonalMatrix():GeneralMatrix() {}
+   ~DiagonalMatrix() {}
+   DiagonalMatrix(ArrayLengthSpecifier);
+   DiagonalMatrix(const BaseMatrix&);
+   DiagonalMatrix(const DiagonalMatrix& gm):GeneralMatrix(gm) { GetMatrix(&gm); }
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const DiagonalMatrix& m) { Eq(m); }
+   Real& operator()(int, int);                  // access element
+   Real& operator()(int);                       // access element
+   Real operator()(int, int) const;             // access element
+   Real operator()(int) const;
+   Real& element(int, int);                     // access element
+   Real& element(int);                          // access element
+   Real element(int, int) const;                // access element
+   Real element(int) const;                     // access element
+#ifdef SETUP_C_SUBSCRIPTS
+   Real& operator[](int m) { return store[m]; }
+   const Real& operator[](int m) const { return store[m]; }
+#endif
+   MatrixType Type() const;
+
+   LogAndSign LogDeterminant() const;
+   Real Trace() const;
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX&);
+   void NextRow(MatrixRowCol&);
+   void NextCol(MatrixRowCol&);
+   void NextCol(MatrixColX&);
+   GeneralMatrix* MakeSolver() { return this; } // for solving
+   void Solver(MatrixColX&, const MatrixColX&);
+   GeneralMatrix* Transpose(TransposedMatrix*, MatrixType);
+   void ReSize(int);                       // change dimensions
+   void ReSize(const GeneralMatrix& A);
+   Real* nric() const
+      { CheckStore(); return store-1; }         // for use by NRIC
+   MatrixBandWidth BandWidth() const;
+//   ReturnMatrix Reverse() const;                // reverse order of elements
+   void operator+=(const DiagonalMatrix& M) { PlusEqual(M); }
+   void operator-=(const DiagonalMatrix& M) { MinusEqual(M); }
+   void operator+=(Real f) { GeneralMatrix::operator+=(f); }
+   void operator-=(Real f) { GeneralMatrix::operator-=(f); }
+   NEW_DELETE(DiagonalMatrix)
+};
+
+class OSSIM_DLL RowVector : public Matrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   RowVector():Matrix() { nrows = 1; }
+   ~RowVector() {}
+   RowVector(ArrayLengthSpecifier n) : Matrix(1,n.Value()) {}
+   RowVector(const BaseMatrix&);
+   RowVector(const RowVector& gm):Matrix(gm) { GetMatrix(&gm); }
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const RowVector& m) { Eq(m); }
+   Real& operator()(int);                       // access element
+   Real& element(int);                          // access element
+   Real operator()(int) const;                  // access element
+   Real element(int) const;                     // access element
+#ifdef SETUP_C_SUBSCRIPTS
+   Real& operator[](int m) { return store[m]; }
+   const Real& operator[](int m) const { return store[m]; }
+#endif
+   MatrixType Type() const;
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX&);
+   void NextCol(MatrixRowCol&);
+   void NextCol(MatrixColX&);
+   void RestoreCol(MatrixRowCol&) {}
+   void RestoreCol(MatrixColX& c);
+   GeneralMatrix* Transpose(TransposedMatrix*, MatrixType);
+   void ReSize(int);                       // change dimensions
+   void ReSize(int,int);                   // in case access is matrix
+   void ReSize(const GeneralMatrix& A);
+   Real* nric() const
+      { CheckStore(); return store-1; }         // for use by NRIC
+   void CleanUp();                              // to clear store
+   void MiniCleanUp() { store = 0; storage = 0; nrows = 1; ncols = 0; tag = -1; }
+   // friend ReturnMatrix GetMatrixRow(Matrix& A, int row);
+   void operator+=(const Matrix& M) { PlusEqual(M); }
+   void operator-=(const Matrix& M) { MinusEqual(M); }
+   void operator+=(Real f) { GeneralMatrix::Add(f); }
+   void operator-=(Real f) { GeneralMatrix::Add(-f); }
+   NEW_DELETE(RowVector)
+};
+
+class OSSIM_DLL ColumnVector : public Matrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   ColumnVector():Matrix() { ncols = 1; }
+   ~ColumnVector() {}
+   ColumnVector(ArrayLengthSpecifier n) : Matrix(n.Value(),1) {}
+   ColumnVector(const BaseMatrix&);
+   ColumnVector(const ColumnVector& gm):Matrix(gm) { GetMatrix(&gm); }
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const ColumnVector& m) { Eq(m); }
+   Real& operator()(int);                       // access element
+   Real& element(int);                          // access element
+   Real operator()(int) const;                  // access element
+   Real element(int) const;                     // access element
+#ifdef SETUP_C_SUBSCRIPTS
+   Real& operator[](int m) { return store[m]; }
+   const Real& operator[](int m) const { return store[m]; }
+#endif
+   MatrixType Type() const;
+   GeneralMatrix* Transpose(TransposedMatrix*, MatrixType);
+   void ReSize(int);                       // change dimensions
+   void ReSize(int,int);                   // in case access is matrix
+   void ReSize(const GeneralMatrix& A);
+   Real* nric() const
+      { CheckStore(); return store-1; }         // for use by NRIC
+   void CleanUp();                              // to clear store
+   void MiniCleanUp() { store = 0; storage = 0; nrows = 0; ncols = 1; tag = -1; }
+//   ReturnMatrix Reverse() const;                // reverse order of elements
+   void operator+=(const Matrix& M) { PlusEqual(M); }
+   void operator-=(const Matrix& M) { MinusEqual(M); }
+   void operator+=(Real f) { GeneralMatrix::Add(f); }
+   void operator-=(Real f) { GeneralMatrix::Add(-f); }
+   NEW_DELETE(ColumnVector)
+};
+
+class OSSIM_DLL CroutMatrix : public GeneralMatrix        // for LU decomposition
+{
+   int* indx;
+   bool d;
+   bool sing;
+   void ludcmp();
+   void operator=(const CroutMatrix& /* m */) {}     // not allowed
+public:
+   CroutMatrix(const BaseMatrix&);
+   MatrixType Type() const;
+   void lubksb(Real*, int=0);
+   ~CroutMatrix();
+   GeneralMatrix* MakeSolver() { return this; } // for solving
+   LogAndSign LogDeterminant() const;
+   void Solver(MatrixColX&, const MatrixColX&);
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX& c) { GetCol((MatrixRowCol&)c); }
+   void CleanUp();                                // to clear store
+   void MiniCleanUp();
+   bool IsEqual(const GeneralMatrix&) const;
+   bool IsSingular() const { return sing; }
+   NEW_DELETE(CroutMatrix)
+};
+
+// ***************************** band matrices ***************************/
+
+class OSSIM_DLL BandMatrix : public GeneralMatrix         // band matrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+protected:
+   void CornerClear() const;                    // set unused elements to zero
+   short SimpleAddOK(const GeneralMatrix* gm);
+public:
+   int lower, upper;                            // band widths
+   BandMatrix():GeneralMatrix() { lower=0; upper=0; CornerClear(); }
+   ~BandMatrix() {}
+   BandMatrix(int n,int lb,int ub) { ReSize(n,lb,ub); CornerClear(); }
+                                                // standard declaration
+   BandMatrix(const BaseMatrix&);               // evaluate BaseMatrix
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const BandMatrix& m) { Eq(m); }
+   MatrixType Type() const;
+   Real& operator()(int, int);                  // access element
+   Real& element(int, int);                     // access element
+   Real operator()(int, int) const;             // access element
+   Real element(int, int) const;                // access element
+#ifdef SETUP_C_SUBSCRIPTS
+   Real* operator[](int m) { return store+(upper+lower)*m+lower; }
+   const Real* operator[](int m) const { return store+(upper+lower)*m+lower; }
+#endif
+   BandMatrix(const BandMatrix& gm):GeneralMatrix(gm) { GetMatrix(&gm); }
+   LogAndSign LogDeterminant() const;
+   GeneralMatrix* MakeSolver();
+   Real Trace() const;
+   Real SumSquare() const { CornerClear(); return GeneralMatrix::SumSquare(); }
+   Real SumAbsoluteValue() const
+      { CornerClear(); return GeneralMatrix::SumAbsoluteValue(); }
+   Real Sum() const
+      { CornerClear(); return GeneralMatrix::Sum(); }
+   Real MaximumAbsoluteValue() const
+      { CornerClear(); return GeneralMatrix::MaximumAbsoluteValue(); }
+   Real MinimumAbsoluteValue() const
+      { int i, j; return GeneralMatrix::MinimumAbsoluteValue2(i, j); }
+   Real Maximum() const { int i, j; return GeneralMatrix::Maximum2(i, j); }
+   Real Minimum() const { int i, j; return GeneralMatrix::Minimum2(i, j); }
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX&);
+   void RestoreCol(MatrixRowCol&);
+   void RestoreCol(MatrixColX& c) { RestoreCol((MatrixRowCol&)c); }
+   void NextRow(MatrixRowCol&);
+   virtual void ReSize(int, int, int);             // change dimensions
+   void ReSize(const GeneralMatrix& A);
+   bool SameStorageType(const GeneralMatrix& A) const;
+   void ReSizeForAdd(const GeneralMatrix& A, const GeneralMatrix& B);
+   void ReSizeForSP(const GeneralMatrix& A, const GeneralMatrix& B);
+   MatrixBandWidth BandWidth() const;
+   void SetParameters(const GeneralMatrix*);
+   MatrixInput operator<<(Real);                // will give error
+   MatrixInput operator<<(int f);
+   void operator<<(const Real* r);              // will give error
+   void operator<<(const int* r);               // will give error
+      // the next is included because Zortech and Borland
+      // cannot find the copy in GeneralMatrix
+   void operator<<(const BaseMatrix& X) { GeneralMatrix::operator<<(X); }
+   NEW_DELETE(BandMatrix)
+};
+
+class OSSIM_DLL UpperBandMatrix : public BandMatrix       // upper band matrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   UpperBandMatrix():BandMatrix() {}
+   ~UpperBandMatrix() {}
+   UpperBandMatrix(int n, int ubw)              // standard declaration
+      : BandMatrix(n, 0, ubw) {}
+   UpperBandMatrix(const BaseMatrix&);          // evaluate BaseMatrix
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const UpperBandMatrix& m) { Eq(m); }
+   MatrixType Type() const;
+   UpperBandMatrix(const UpperBandMatrix& gm):BandMatrix(gm) { GetMatrix(&gm); }
+   GeneralMatrix* MakeSolver() { return this; }
+   void Solver(MatrixColX&, const MatrixColX&);
+   LogAndSign LogDeterminant() const;
+   void ReSize(int, int, int);             // change dimensions
+   void ReSize(int n,int ubw)              // change dimensions
+      { BandMatrix::ReSize(n,0,ubw); }
+   void ReSize(const GeneralMatrix& A) { BandMatrix::ReSize(A); }
+   Real& operator()(int, int);
+   Real operator()(int, int) const;
+   Real& element(int, int);
+   Real element(int, int) const;
+#ifdef SETUP_C_SUBSCRIPTS
+   Real* operator[](int m) { return store+upper*m; }
+   const Real* operator[](int m) const { return store+upper*m; }
+#endif
+   NEW_DELETE(UpperBandMatrix)
+};
+
+class OSSIM_DLL LowerBandMatrix : public BandMatrix       // upper band matrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+public:
+   LowerBandMatrix():BandMatrix() {}
+   ~LowerBandMatrix() {}
+   LowerBandMatrix(int n, int lbw)              // standard declaration
+      : BandMatrix(n, lbw, 0) {}
+   LowerBandMatrix(const BaseMatrix&);          // evaluate BaseMatrix
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const LowerBandMatrix& m) { Eq(m); }
+   MatrixType Type() const;
+   LowerBandMatrix(const LowerBandMatrix& gm):BandMatrix(gm) { GetMatrix(&gm); }
+   GeneralMatrix* MakeSolver() { return this; }
+   void Solver(MatrixColX&, const MatrixColX&);
+   LogAndSign LogDeterminant() const;
+   void ReSize(int, int, int);             // change dimensions
+   void ReSize(int n,int lbw)             // change dimensions
+      { BandMatrix::ReSize(n,lbw,0); }
+   void ReSize(const GeneralMatrix& A) { BandMatrix::ReSize(A); }
+   Real& operator()(int, int);
+   Real operator()(int, int) const;
+   Real& element(int, int);
+   Real element(int, int) const;
+#ifdef SETUP_C_SUBSCRIPTS
+   Real* operator[](int m) { return store+lower*(m+1); }
+   const Real* operator[](int m) const { return store+lower*(m+1); }
+#endif
+   NEW_DELETE(LowerBandMatrix)
+};
+
+class OSSIM_DLL SymmetricBandMatrix : public GeneralMatrix
+{
+   GeneralMatrix* Image() const;                // copy of matrix
+   void CornerClear() const;                    // set unused elements to zero
+   short SimpleAddOK(const GeneralMatrix* gm);
+public:
+   int lower;                                   // lower band width
+   SymmetricBandMatrix():GeneralMatrix() { lower=0; CornerClear(); }
+   ~SymmetricBandMatrix() {}
+   SymmetricBandMatrix(int n, int lb) { ReSize(n,lb); CornerClear(); }
+   SymmetricBandMatrix(const BaseMatrix&);
+   void operator=(const BaseMatrix&);
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   void operator=(const SymmetricBandMatrix& m) { Eq(m); }
+   Real& operator()(int, int);                  // access element
+   Real& element(int, int);                     // access element
+   Real operator()(int, int) const;             // access element
+   Real element(int, int) const;                // access element
+#ifdef SETUP_C_SUBSCRIPTS
+   Real* operator[](int m) { return store+lower*(m+1); }
+   const Real* operator[](int m) const { return store+lower*(m+1); }
+#endif
+   MatrixType Type() const;
+   SymmetricBandMatrix(const SymmetricBandMatrix& gm):GeneralMatrix(gm) { GetMatrix(&gm); }
+   GeneralMatrix* MakeSolver();
+   Real SumSquare() const;
+   Real SumAbsoluteValue() const;
+   Real Sum() const;
+   Real MaximumAbsoluteValue() const
+      { CornerClear(); return GeneralMatrix::MaximumAbsoluteValue(); }
+   Real MinimumAbsoluteValue() const
+      { int i, j; return GeneralMatrix::MinimumAbsoluteValue2(i, j); }
+   Real Maximum() const { int i, j; return GeneralMatrix::Maximum2(i, j); }
+   Real Minimum() const { int i, j; return GeneralMatrix::Minimum2(i, j); }
+   Real Trace() const;
+   LogAndSign LogDeterminant() const;
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX&);
+   void RestoreCol(MatrixRowCol&) {}
+   void RestoreCol(MatrixColX&);
+   GeneralMatrix* Transpose(TransposedMatrix*, MatrixType);
+   void ReSize(int,int);                       // change dimensions
+   void ReSize(const GeneralMatrix& A);
+   bool SameStorageType(const GeneralMatrix& A) const;
+   void ReSizeForAdd(const GeneralMatrix& A, const GeneralMatrix& B);
+   void ReSizeForSP(const GeneralMatrix& A, const GeneralMatrix& B);
+   MatrixBandWidth BandWidth() const;
+   void SetParameters(const GeneralMatrix*);
+   void operator<<(const Real* r);              // will give error
+   void operator<<(const int* r);               // will give error
+   void operator<<(const BaseMatrix& X) { GeneralMatrix::operator<<(X); }
+   NEW_DELETE(SymmetricBandMatrix)
+};
+
+class OSSIM_DLL BandLUMatrix : public GeneralMatrix
+// for LU decomposition of band matrix
+{
+   int* indx;
+   bool d;
+   bool sing;                                   // true if singular
+   Real* store2;
+   int storage2;
+   void ludcmp();
+   int m1,m2;                                   // lower and upper
+   void operator=(const BandLUMatrix& /* m */) {}     // no allowed
+public:
+   BandLUMatrix(const BaseMatrix&);
+   MatrixType Type() const;
+   void lubksb(Real*, int=0);
+   ~BandLUMatrix();
+   GeneralMatrix* MakeSolver() { return this; } // for solving
+   LogAndSign LogDeterminant() const;
+   void Solver(MatrixColX&, const MatrixColX&);
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX& c) { GetCol((MatrixRowCol&)c); }
+   void CleanUp();                                // to clear store
+   void MiniCleanUp();
+   bool IsEqual(const GeneralMatrix&) const;
+   bool IsSingular() const { return sing; }
+   NEW_DELETE(BandLUMatrix)
+};
+
+// ************************** special matrices ****************************
+
+class OSSIM_DLL IdentityMatrix : public GeneralMatrix
+{
+   GeneralMatrix* Image() const;          // copy of matrix
+public:
+   IdentityMatrix():GeneralMatrix() {}
+   ~IdentityMatrix() {}
+   IdentityMatrix(ArrayLengthSpecifier n) : GeneralMatrix(1)
+      { nrows = ncols = n.Value(); *store = 1; }
+   IdentityMatrix(const IdentityMatrix& gm):GeneralMatrix(gm) { GetMatrix(&gm); }
+   IdentityMatrix(const BaseMatrix&);
+   void operator=(const BaseMatrix&);
+   void operator=(const IdentityMatrix& m) { Eq(m); }
+   void operator=(Real f) { GeneralMatrix::operator=(f); }
+   MatrixType Type() const;
+
+   LogAndSign LogDeterminant() const;
+   Real Trace() const;
+   Real SumSquare() const;
+   Real SumAbsoluteValue() const;
+   Real Sum() const { return Trace(); }
+   void GetRow(MatrixRowCol&);
+   void GetCol(MatrixRowCol&);
+   void GetCol(MatrixColX&);
+   void NextRow(MatrixRowCol&);
+   void NextCol(MatrixRowCol&);
+   void NextCol(MatrixColX&);
+   GeneralMatrix* MakeSolver() { return this; } // for solving
+   void Solver(MatrixColX&, const MatrixColX&);
+   GeneralMatrix* Transpose(TransposedMatrix*, MatrixType);
+   void ReSize(int n);
+   void ReSize(const GeneralMatrix& A);
+   MatrixBandWidth BandWidth() const;
+//   ReturnMatrix Reverse() const;                // reverse order of elements
+   NEW_DELETE(IdentityMatrix)
+};
+
+
+
+
+// ************************** GenericMatrix class ************************/
+
+class OSSIM_DLL GenericMatrix : public BaseMatrix
+{
+   GeneralMatrix* gm;
+   int search(const BaseMatrix* bm) const;
+   friend class BaseMatrix;
+public:
+   GenericMatrix() : gm(0) {}
+   GenericMatrix(const BaseMatrix& bm)
+      { gm = ((BaseMatrix&)bm).Evaluate(); gm = gm->Image(); }
+   GenericMatrix(const GenericMatrix& bm) : BaseMatrix(bm)
+      { gm = bm.gm->Image(); }
+   void operator=(const GenericMatrix&);
+   void operator=(const BaseMatrix&);
+   void operator+=(const BaseMatrix&);
+   void operator-=(const BaseMatrix&);
+   void operator*=(const BaseMatrix&);
+   void operator|=(const BaseMatrix&);
+   void operator&=(const BaseMatrix&);
+   void operator+=(Real);
+   void operator-=(Real r) { operator+=(-r); }
+   void operator*=(Real);
+   void operator/=(Real r) { operator*=(1.0/r); }
+   ~GenericMatrix() { delete gm; }
+   void CleanUp() { delete gm; gm = 0; }
+   void Release() { gm->Release(); }
+   GeneralMatrix* Evaluate(MatrixType = MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(GenericMatrix)
+};
+
+// *************************** temporary classes *************************/
+
+class OSSIM_DLL MultipliedMatrix : public BaseMatrix
+{
+protected:
+   // if these union statements cause problems, simply remove them
+   // and declare the items individually
+   union { const BaseMatrix* bm1; GeneralMatrix* gm1; };
+						  // pointers to summands
+   union { const BaseMatrix* bm2; GeneralMatrix* gm2; };
+   MultipliedMatrix(const BaseMatrix* bm1x, const BaseMatrix* bm2x)
+      : bm1(bm1x),bm2(bm2x) {}
+   int search(const BaseMatrix*) const;
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~MultipliedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(MultipliedMatrix)
+};
+
+class OSSIM_DLL AddedMatrix : public MultipliedMatrix
+{
+protected:
+   AddedMatrix(const BaseMatrix* bm1x, const BaseMatrix* bm2x)
+      : MultipliedMatrix(bm1x,bm2x) {}
+
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~AddedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(AddedMatrix)
+};
+
+class OSSIM_DLL SPMatrix : public AddedMatrix
+{
+protected:
+   SPMatrix(const BaseMatrix* bm1x, const BaseMatrix* bm2x)
+      : AddedMatrix(bm1x,bm2x) {}
+
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~SPMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+
+   friend SPMatrix SP(const BaseMatrix&, const BaseMatrix&);
+
+   NEW_DELETE(SPMatrix)
+};
+
+class OSSIM_DLL KPMatrix : public MultipliedMatrix
+{
+protected:
+   KPMatrix(const BaseMatrix* bm1x, const BaseMatrix* bm2x)
+      : MultipliedMatrix(bm1x,bm2x) {}
+
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~KPMatrix() {}
+   MatrixBandWidth BandWidth() const;
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   friend KPMatrix KP(const BaseMatrix&, const BaseMatrix&);
+   NEW_DELETE(KPMatrix)
+};
+
+class OSSIM_DLL ConcatenatedMatrix : public MultipliedMatrix
+{
+protected:
+   ConcatenatedMatrix(const BaseMatrix* bm1x, const BaseMatrix* bm2x)
+      : MultipliedMatrix(bm1x,bm2x) {}
+
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~ConcatenatedMatrix() {}
+   MatrixBandWidth BandWidth() const;
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   NEW_DELETE(ConcatenatedMatrix)
+};
+
+class OSSIM_DLL StackedMatrix : public ConcatenatedMatrix
+{
+protected:
+   StackedMatrix(const BaseMatrix* bm1x, const BaseMatrix* bm2x)
+      : ConcatenatedMatrix(bm1x,bm2x) {}
+
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~StackedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   NEW_DELETE(StackedMatrix)
+};
+
+class OSSIM_DLL SolvedMatrix : public MultipliedMatrix
+{
+   SolvedMatrix(const BaseMatrix* bm1x, const BaseMatrix* bm2x)
+      : MultipliedMatrix(bm1x,bm2x) {}
+   friend class BaseMatrix;
+   friend class InvertedMatrix;                        // for operator*
+public:
+   ~SolvedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(SolvedMatrix)
+};
+
+class OSSIM_DLL SubtractedMatrix : public AddedMatrix
+{
+   SubtractedMatrix(const BaseMatrix* bm1x, const BaseMatrix* bm2x)
+      : AddedMatrix(bm1x,bm2x) {}
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~SubtractedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   NEW_DELETE(SubtractedMatrix)
+};
+
+class OSSIM_DLL ShiftedMatrix : public BaseMatrix
+{
+protected:
+   union { const BaseMatrix* bm; GeneralMatrix* gm; };
+   Real f;
+   ShiftedMatrix(const BaseMatrix* bmx, Real fx) : bm(bmx),f(fx) {}
+   int search(const BaseMatrix*) const;
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~ShiftedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   friend ShiftedMatrix operator+(Real f, const BaseMatrix& BM);
+   NEW_DELETE(ShiftedMatrix)
+};
+
+class OSSIM_DLL NegShiftedMatrix : public ShiftedMatrix
+{
+protected:
+   NegShiftedMatrix(Real fx, const BaseMatrix* bmx) : ShiftedMatrix(bmx,fx) {}
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~NegShiftedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   friend NegShiftedMatrix operator-(Real, const BaseMatrix&);
+   NEW_DELETE(NegShiftedMatrix)
+};
+
+class OSSIM_DLL ScaledMatrix : public ShiftedMatrix
+{
+   ScaledMatrix(const BaseMatrix* bmx, Real fx) : ShiftedMatrix(bmx,fx) {}
+   friend class BaseMatrix;
+   friend class GeneralMatrix;
+   friend class GenericMatrix;
+public:
+   ~ScaledMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   friend ScaledMatrix operator*(Real f, const BaseMatrix& BM);
+   NEW_DELETE(ScaledMatrix)
+};
+
+class OSSIM_DLL NegatedMatrix : public BaseMatrix
+{
+protected:
+   union { const BaseMatrix* bm; GeneralMatrix* gm; };
+   NegatedMatrix(const BaseMatrix* bmx) : bm(bmx) {}
+   int search(const BaseMatrix*) const;
+private:
+   friend class BaseMatrix;
+public:
+   ~NegatedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(NegatedMatrix)
+};
+
+class OSSIM_DLL TransposedMatrix : public NegatedMatrix
+{
+   TransposedMatrix(const BaseMatrix* bmx) : NegatedMatrix(bmx) {}
+   friend class BaseMatrix;
+public:
+   ~TransposedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(TransposedMatrix)
+};
+
+class OSSIM_DLL ReversedMatrix : public NegatedMatrix
+{
+   ReversedMatrix(const BaseMatrix* bmx) : NegatedMatrix(bmx) {}
+   friend class BaseMatrix;
+public:
+   ~ReversedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   NEW_DELETE(ReversedMatrix)
+};
+
+class OSSIM_DLL InvertedMatrix : public NegatedMatrix
+{
+   InvertedMatrix(const BaseMatrix* bmx) : NegatedMatrix(bmx) {}
+public:
+   ~InvertedMatrix() {}
+   SolvedMatrix operator*(const BaseMatrix&) const;       // inverse(A) * B
+   ScaledMatrix operator*(Real t) const { return BaseMatrix::operator*(t); }
+   friend class BaseMatrix;
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(InvertedMatrix)
+};
+
+class OSSIM_DLL RowedMatrix : public NegatedMatrix
+{
+   RowedMatrix(const BaseMatrix* bmx) : NegatedMatrix(bmx) {}
+   friend class BaseMatrix;
+public:
+   ~RowedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(RowedMatrix)
+};
+
+class OSSIM_DLL ColedMatrix : public NegatedMatrix
+{
+   ColedMatrix(const BaseMatrix* bmx) : NegatedMatrix(bmx) {}
+   friend class BaseMatrix;
+public:
+   ~ColedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(ColedMatrix)
+};
+
+class OSSIM_DLL DiagedMatrix : public NegatedMatrix
+{
+   DiagedMatrix(const BaseMatrix* bmx) : NegatedMatrix(bmx) {}
+   friend class BaseMatrix;
+public:
+   ~DiagedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(DiagedMatrix)
+};
+
+class OSSIM_DLL MatedMatrix : public NegatedMatrix
+{
+   int nr, nc;
+   MatedMatrix(const BaseMatrix* bmx, int nrx, int ncx)
+      : NegatedMatrix(bmx), nr(nrx), nc(ncx) {}
+   friend class BaseMatrix;
+public:
+   ~MatedMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(MatedMatrix)
+};
+
+class OSSIM_DLL ReturnMatrix : public BaseMatrix    // for matrix return
+{
+   GeneralMatrix* gm;
+   int search(const BaseMatrix*) const;
+public:
+   ~ReturnMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   friend class BaseMatrix;
+   ReturnMatrix(const ReturnMatrix& tm) :BaseMatrix(tm), gm(tm.gm) {}
+   ReturnMatrix(const GeneralMatrix* gmx) : gm((GeneralMatrix*&)gmx) {}
+//   ReturnMatrix(GeneralMatrix&);
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(ReturnMatrix)
+};
+
+
+// ************************** submatrices ******************************/
+
+class OSSIM_DLL GetSubMatrix : public NegatedMatrix
+{
+   int row_skip;
+   int row_number;
+   int col_skip;
+   int col_number;
+   bool IsSym;
+
+   GetSubMatrix
+      (const BaseMatrix* bmx, int rs, int rn, int cs, int cn, bool is)
+      : NegatedMatrix(bmx),
+      row_skip(rs), row_number(rn), col_skip(cs), col_number(cn), IsSym(is) {}
+   void SetUpLHS();
+   friend class BaseMatrix;
+
+public:
+
+   GetSubMatrix(const GetSubMatrix& g)
+      : NegatedMatrix(g.bm), row_skip(g.row_skip), row_number(g.row_number),
+      col_skip(g.col_skip), col_number(g.col_number), IsSym(g.IsSym) {}
+
+   ~GetSubMatrix() {}
+   GeneralMatrix* Evaluate(MatrixType mt=MatrixTypeUnSp);
+   void operator=(const BaseMatrix&);
+   void operator+=(const BaseMatrix&);
+   void operator-=(const BaseMatrix&);
+   void operator=(const GetSubMatrix& m) { operator=((const BaseMatrix&)m); }
+   void operator<<(const BaseMatrix&);
+   void operator<<(const Real*);                // copy from array
+   void operator<<(const int*);                 // copy from array
+   MatrixInput operator<<(Real);                // for loading a list
+   MatrixInput operator<<(int f);
+   void operator=(Real);                        // copy from constant
+   void operator+=(Real);                       // add constant
+   void operator-=(Real r) { operator+=(-r); }  // subtract constant
+   void operator*=(Real);                       // multiply by constant
+   void operator/=(Real r) { operator*=(1.0/r); } // divide by constant
+   void Inject(const GeneralMatrix&);           // copy stored els only
+   MatrixBandWidth BandWidth() const;
+   NEW_DELETE(GetSubMatrix)
+};
+
+// ******************** linear equation solving ****************************/
+
+class OSSIM_DLL LinearEquationSolver : public BaseMatrix
+{
+   GeneralMatrix* gm;
+   int search(const BaseMatrix*) const { return 0; }
+   friend class BaseMatrix;
+public:
+   LinearEquationSolver(const BaseMatrix& bm);
+   ~LinearEquationSolver() { delete gm; }
+   void CleanUp() { delete gm; } 
+   GeneralMatrix* Evaluate(MatrixType) { return gm; }
+   // probably should have an error message if MatrixType != UnSp
+   NEW_DELETE(LinearEquationSolver)
+};
+
+// ************************** matrix input *******************************/
+
+class MatrixInput          // for reading a list of values into a matrix
+                           // the difficult part is detecting a mismatch
+                           // in the number of elements
+{
+   int n;                  // number values still to be read
+   Real* r;                // pointer to next location to be read to
+public:
+   MatrixInput(const MatrixInput& mi) : n(mi.n), r(mi.r) {}
+   MatrixInput(int nx, Real* rx) : n(nx), r(rx) {}
+   ~MatrixInput();
+   MatrixInput operator<<(Real);
+   MatrixInput operator<<(int f);
+   friend class GeneralMatrix;
+};
+
+
+
+// **************** a very simple integer array class ********************/
+
+// A minimal array class to imitate a C style array but giving dynamic storage
+// mostly intended for internal use by newmat
+
+class OSSIM_DLL SimpleIntArray : public Janitor
+{
+protected:
+   int* a;                    // pointer to the array
+   int n;                     // length of the array
+public:
+   SimpleIntArray(int xn);    // build an array length xn
+   ~SimpleIntArray();         // return the space to memory
+   int& operator[](int i);    // access element of the array - start at 0
+   int operator[](int i) const;
+			      // access element of constant array
+   void operator=(int ai);    // set the array equal to a constant
+   void operator=(const SimpleIntArray& b);
+			      // copy the elements of an array
+   SimpleIntArray(const SimpleIntArray& b);
+			      // make a new array equal to an existing one
+   int Size() const { return n; }
+			      // return the size of the array
+   int* Data() { return a; }  // pointer to the data
+   const int* Data() const { return a; }
+			      // pointer to the data
+   void ReSize(int i, bool keep = false);
+                              // change length, keep data if keep = true
+   void CleanUp() { ReSize(0); }
+   NEW_DELETE(SimpleIntArray)
+};
+
+// *************************** exceptions ********************************/
+
+class OSSIM_DLL NPDException : public Runtime_error     // Not positive definite
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   NPDException(const GeneralMatrix&);
+};
+
+class OSSIM_DLL ConvergenceException : public Runtime_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   ConvergenceException(const GeneralMatrix& A);
+   ConvergenceException(const char* c);
+};
+
+class OSSIM_DLL SingularException : public Runtime_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   SingularException(const GeneralMatrix& A);
+};
+
+class OSSIM_DLL OverflowException : public Runtime_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   OverflowException(const char* c);
+};
+
+class OSSIM_DLL ProgramException : public Logic_error
+{
+protected:
+   ProgramException();
+public:
+   static unsigned long Select;          // for identifying exception
+   ProgramException(const char* c);
+   ProgramException(const char* c, const GeneralMatrix&);
+   ProgramException(const char* c, const GeneralMatrix&, const GeneralMatrix&);
+   ProgramException(const char* c, MatrixType, MatrixType);
+};
+
+class OSSIM_DLL IndexException : public Logic_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   IndexException(int i, const GeneralMatrix& A);
+   IndexException(int i, int j, const GeneralMatrix& A);
+   // next two are for access via element function
+   IndexException(int i, const GeneralMatrix& A, bool);
+   IndexException(int i, int j, const GeneralMatrix& A, bool);
+};
+
+class OSSIM_DLL VectorException : public Logic_error    // cannot convert to vector
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   VectorException();
+   VectorException(const GeneralMatrix& A);
+};
+
+class OSSIM_DLL NotSquareException : public Logic_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   NotSquareException(const GeneralMatrix& A);
+   NotSquareException();
+};
+
+class OSSIM_DLL SubMatrixDimensionException : public Logic_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   SubMatrixDimensionException();
+};
+
+class OSSIM_DLL IncompatibleDimensionsException : public Logic_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   IncompatibleDimensionsException();
+   IncompatibleDimensionsException(const GeneralMatrix&, const GeneralMatrix&);
+};
+
+class OSSIM_DLL NotDefinedException : public Logic_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   NotDefinedException(const char* op, const char* matrix);
+};
+
+class OSSIM_DLL CannotBuildException : public Logic_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   CannotBuildException(const char* matrix);
+};
+
+
+class OSSIM_DLL InternalException : public Logic_error
+{
+public:
+   static unsigned long Select;          // for identifying exception
+   InternalException(const char* c);
+};
+
+// ************************ functions ************************************ //
+
+bool operator==(const GeneralMatrix& A, const GeneralMatrix& B);
+bool operator==(const BaseMatrix& A, const BaseMatrix& B);
+inline bool operator!=(const GeneralMatrix& A, const GeneralMatrix& B)
+   { return ! (A==B); }
+inline bool operator!=(const BaseMatrix& A, const BaseMatrix& B)
+   { return ! (A==B); }
+
+   // inequality operators are dummies included for compatibility
+   // with STL. They throw an exception if actually called.
+inline bool operator<=(const BaseMatrix& A, const BaseMatrix&)
+   { A.IEQND(); return true; }
+inline bool operator>=(const BaseMatrix& A, const BaseMatrix&)
+   { A.IEQND(); return true; }
+inline bool operator<(const BaseMatrix& A, const BaseMatrix&)
+   { A.IEQND(); return true; }
+inline bool operator>(const BaseMatrix& A, const BaseMatrix&)
+   { A.IEQND(); return true; }
+
+bool IsZero(const BaseMatrix& A);
+
+Matrix CrossProduct(const Matrix& A, const Matrix& B);
+ReturnMatrix CrossProductRows(const Matrix& A, const Matrix& B);
+ReturnMatrix CrossProductColumns(const Matrix& A, const Matrix& B);
+
+
+// ********************* inline functions ******************************** //
+
+
+inline LogAndSign LogDeterminant(const BaseMatrix& B)
+   { return B.LogDeterminant(); }
+inline Real Determinant(const BaseMatrix& B)
+   { return B.Determinant(); }
+inline Real SumSquare(const BaseMatrix& B) { return B.SumSquare(); }
+inline Real NormFrobenius(const BaseMatrix& B) { return B.NormFrobenius(); }
+inline Real Trace(const BaseMatrix& B) { return B.Trace(); }
+inline Real SumAbsoluteValue(const BaseMatrix& B)
+   { return B.SumAbsoluteValue(); }
+inline Real Sum(const BaseMatrix& B)
+   { return B.Sum(); }
+inline Real MaximumAbsoluteValue(const BaseMatrix& B)
+   { return B.MaximumAbsoluteValue(); }
+inline Real MinimumAbsoluteValue(const BaseMatrix& B)
+   { return B.MinimumAbsoluteValue(); }
+inline Real Maximum(const BaseMatrix& B) { return B.Maximum(); }
+inline Real Minimum(const BaseMatrix& B) { return B.Minimum(); }
+inline Real Norm1(const BaseMatrix& B) { return B.Norm1(); }
+inline Real Norm1(RowVector& RV) { return RV.MaximumAbsoluteValue(); }
+inline Real NormInfinity(const BaseMatrix& B) { return B.NormInfinity(); }
+inline Real NormInfinity(ColumnVector& CV)
+   { return CV.MaximumAbsoluteValue(); }
+inline bool IsZero(const GeneralMatrix& A) { return A.IsZero(); }
+
+
+inline MatrixInput MatrixInput::operator<<(int f) { return *this << (Real)f; }
+inline MatrixInput GeneralMatrix::operator<<(int f) { return *this << (Real)f; }
+inline MatrixInput BandMatrix::operator<<(int f) { return *this << (Real)f; }
+inline MatrixInput GetSubMatrix::operator<<(int f) { return *this << (Real)f; }
+
+
+
+#ifdef use_namespace
+}
+#endif
+
+
+#endif
+
+// body file: newmat1.cpp
+// body file: newmat2.cpp
+// body file: newmat3.cpp
+// body file: newmat4.cpp
+// body file: newmat5.cpp
+// body file: newmat6.cpp
+// body file: newmat7.cpp
+// body file: newmat8.cpp
+// body file: newmatex.cpp
+// body file: bandmat.cpp
+// body file: submat.cpp
+
+
+
+
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat.txt b/Utilities/OSSIM/ossim_core/matrix/newmat.txt
new file mode 100644
index 0000000000..2cba65433a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat.txt
@@ -0,0 +1,3235 @@
+
+
+        DOCUMENTATION FOR NEWMAT10, A MATRIX LIBRARY IN C++
+
+Copyright (C) 1991,2,3,4,5,6,7,8,9: R B Davies
+
+Beta version of 26 December, 1999
+
+        Introduction                                 1
+        Getting started                              2
+        Reference manual                             3
+        Error messages                               4
+        Bugs                                         5
+        Files in newmat10                            6
+        Problem report form                          7
+        Design of the library                        8
+
+This is the "how to use" documentation for newmat plus the background
+information on its design.
+
+This document is available as an ascii file, newmat.txt, and in hypertext
+format for reading with an HTML browser such as Netscape or Internet Explorer.
+Cross-references in the ascii version are given as section numbers. The HTML
+version can be downloaded from the same site [1.5] as the source files. There
+is also a version in RTF format.
+
+There is additional support material on my web site [1.5].
+
+Be sure to read the section on customising [2.3] before attempting to compile
+newmat.
+
+
+        1  Introduction
+        =  ============
+
+        Conditions of use                            1.1
+        Description                                  1.2
+        Is this the library for you?                 1.3
+        Other matrix libraries                       1.4
+        Where to find this library                   1.5
+        How to contact the author                    1.6
+        Change history                               1.7
+        References                                   1.8
+
+
+        1.1  Conditions of use
+        ===  ========== == ===
+
+Copyright (C) 1991,2,3,4,5,6,7: R B Davies.
+
+Permission is granted to use and distribute but not to sell except for costs
+of distribution. Distribution as part of low cost CD-ROM collections is
+welcomed.
+
+You can use it in your commercial projects. However if you distribute the
+source, please make it clear which parts are mine and that they are available
+essentially for free over the internet.
+
+ -----------------------------------------------------------------------------
+Please understand that there may still be bugs and errors. Use at your own
+risk. I take no responsibility for any errors or omissions in this package or
+for any misfortune that may befall you or others as a result of its use.
+ -----------------------------------------------------------------------------
+
+Please report bugs to me at
+
+    robertd@netlink.co.nz
+
+
+When reporting a bug please tell me which C++ compiler you are using (if
+known), and what version. Also give me details of your computer (if known).
+And tell me which version of Newmat (eg newmat03 or newmat04) you are using.
+Note any changes you have made to my code. If at all possible give me a piece
+of code illustrating the bug. See the problem report form [7].
+
+"Please do report bugs to me."
+
+
+
+        1.2  General description
+        ===  ======= ===========
+
+The package is intended for scientists and engineers who need to manipulate a
+variety of types of matrices using standard matrix operations. Emphasis is on
+the kind of operations needed in statistical calculations such as least
+squares, linear equation solve and eigenvalues.
+
+It supports matrix types
+
+    Matrix                       (rectangular matrix)
+    nricMatrix                   (variant of rectangular matrix)
+    UpperTriangularMatrix
+    LowerTriangularMatrix
+    DiagonalMatrix
+    SymmetricMatrix
+    BandMatrix
+    UpperBandMatrix              (upper triangular band matrix)
+    LowerBandMatrix              (lower triangular band matrix)
+    SymmetricBandMatrix
+    RowVector                    (derived from Matrix)
+    ColumnVector                 (derived from Matrix).
+
+Only one element type (float or double) is supported.
+
+The package includes the operations '*', '+', '-', concatenation, inverse,
+transpose, conversion between types, submatrix, determinant, Cholesky
+decomposition, QR triangularisation, singular value decomposition, eigenvalues
+of a symmetric matrix, sorting, fast Fourier transform, printing and an
+interface with "Numerical Recipes in C".
+
+It is intended for matrices in the range 15 x 15 to the maximum size your
+machine will accommodate in a single array. On a PC using the large model,
+this is 90 x 90 (125 x 125 for triangular matrices). For Unix machines or PCs
+running under a 32 bit flat model the limit is set by the size of available
+memory. The number of elements in an array cannot exceed the maximum size of
+an "int". The package will work for very small matrices but becomes rather
+inefficient. Some of the factorisation functions are not (yet) optimised for
+paged memory and so become inefficient when used with very large matrices.
+
+A "lazy evaluation" approach to evaluating matrix expressions is used to
+improve efficiency and reduce the use of temporary storage.
+
+I have tested the package on variety of compilers and platforms including
+AT&T, Borland, Gnu, HP, Microsoft, Sun and Watcom. For more details see the
+section on compiler performance [2.4].
+
+
+
+
+        1.3  Is this the library for you?
+        ===  == ==== === ======= === ====
+
+Do you
+
+1:  understand '*' to mean matrix multiply and not element by element multiply
+
+2:  need matrix operators such as '*' and '+' defined as operators so you can
+write things like
+
+    X  = A * (B + C);
+
+3:  need a variety of types of matrices (but not sparse);
+
+4:  need only one element type (float or double);
+
+5:  work with matrices in the range 10 x 10 up to what can be stored in
+memory;
+
+6:  tolerate a large package.
+
+
+Then maybe this is the right package for you. 
+
+
+
+        1.4  Other matrix libraries
+        ===  ===== ====== =========
+
+For details of other C++ matrix libraries look at
+http://webnz.com/robert/cpp_site.html or
+http://webnz.co.nz/robert/cpp_site.html or download the text file
+ftp://webnz.com/robert/cpp_site.txt or ftp://webnz.co.nz/robert/cpp_site.txt .
+Look at the section "lists of libraries" which gives the locations of several
+very comprehensive lists of matrix and other C++ libraries and at the section
+"source code".
+
+
+
+
+        1.5  Where to find this library
+        ===  ===== == ==== ==== =======
+
+
+*   http://webnz.com/robert/
+
+*   http://webnz.co.nz/robert/
+
+*   ftp://webnz.com/robert/newmat10.zip
+
+*   ftp://webnz.com/robert/newmat10.tar.gz
+
+*   ftp://webnz.co.nz/robert/newmat10.zip
+
+*   ftp://webnz.co.nz/robert/newmat10.tar.gz
+
+
+For the HTML version of the documentation download either nm10html.zip or
+nm10html.tar.gz from the same sites.
+
+
+
+
+        1.6  How to contact the author
+        ===  === == ======= === ======
+
+
+   Robert Davies
+   16 Gloucester Street
+   Wilton
+   Wellington
+   New Zealand
+
+   "email:" robertd@netlink.co.nz
+
+(don't forget the "d" in "robertd").
+
+
+
+        1.7  Change history
+        ===  ====== =======
+
+Newmat10 - August, 1999:
+
+Improve compatibility with GCC, fix errors in FFT and GenericMatrix, update
+simulated exceptions, maxima and minima functions, Determinant function,
+update make files for CC and GCC, faster FFT, 'A.ReSize(B)'.
+
+Newmat09 - September, 1997:
+
+Operator '==', '!=', '+=', '-=', '*=', '/=', '|=', '&='. Follow new rules for
+"for (int i; ... )" construct. Change Boolean, TRUE, FALSE to bool, true,
+false. Change ReDimension to ReSize. SubMatrix allows zero rows and columns.
+Scalar '+', '-' or '*' matrix is OK. Simplify simulated exceptions. Fix
+non-linear programs for AT&T compilers. Dummy inequality operators. Improve
+internal row/column operations. Improve matrix LU decomposition. Improve sort.
+Reverse function. IsSingular function. Fast trig transforms. Namespace
+definitions.
+
+Newmat08A - July, 1995:
+
+Fix error in SVD.
+
+Newmat08 - January, 1995:
+
+Corrections to improve compatibility with Gnu, Watcom. Concatenation of
+matrices. Elementwise products. Option to use compilers supporting exceptions.
+Correction to exception module to allow global declarations of matrices. Fix
+problem with inverse of symmetric matrices. Fix divide-by-zero problem in SVD.
+Include new QR routines. Sum function. Non-linear optimisation.
+GenericMatrices.
+
+Newmat07 - January, 1993
+
+Minor corrections to improve compatibility with Zortech, Microsoft and Gnu.
+Correction to exception module. Additional FFT functions. Some minor increases
+in efficiency. Submatrices can now be used on RHS of =. Option for allowing C
+type subscripts. Method for loading short lists of numbers.
+
+
+Newmat06 - December 1992:
+
+Added band matrices; 'real' changed to 'Real' (to avoid potential conflict in
+complex class); Inject doesn't check for no loss of information;  fixes for
+AT&T C++ version 3.0; real(A) becomes A.AsScalar(); CopyToMatrix becomes
+AsMatrix, etc; .c() is no longer required (to be deleted in next version);
+option for version 2.1 or later. Suffix for include files changed to .h; BOOL
+changed to Boolean (BOOL doesn't work in g++ v 2.0); modifications to allow
+for compilers that destroy temporaries very quickly; (Gnu users - see the
+section of compiler performance). Added CleanUp, LinearEquationSolver,
+primitive version of exceptions.
+
+
+Newmat05 - June 1992:
+
+For private release only 
+
+
+Newmat04 - December 1991:
+
+Fix problem with G++1.40, some extra documentation
+
+
+Newmat03 - November 1991:
+
+Col and Cols become Column and Columns. Added Sort, SVD, Jacobi, Eigenvalues,
+FFT, real conversion of 1x1 matrix, "Numerical Recipes in C" interface, output
+operations, various scalar functions. Improved return from functions.
+Reorganised setting options in "include.hxx".
+
+
+Newmat02 - July 1991:
+
+Version with matrix row/column operations and numerous additional functions.
+
+
+Matrix - October 1990:
+
+Early version of package.
+
+
+
+
+        1.8  References
+        ===  ==========
+
+The matrix LU decomposition is from Golub, G.H. & Van Loan, C.F. (1996),
+"Matrix Computations", published by John Hopkins University Press.
+
+Part of the matrix inverse/solve routine is adapted from Press, Flannery,
+Teukolsky, Vetterling (1988), "Numerical Recipes in C", published by the
+Cambridge University Press.
+
+Many of the advanced matrix routines are adapted from routines in Wilkinson
+and Reinsch (1971), "Handbook for Automatic Computation, Vol II, Linear
+Algebra" published by Springer Verlag.
+
+The fast Fourier transform is adapted from Carl de Boor (1980), "Siam J Sci
+Stat Comput", pp173-8 and the fast trigonometric transforms from Charles Van
+Loan (1992) in "Computational frameworks for the fast Fourier transform"
+published by SIAM.
+
+The sort function is derived from Sedgewick, Robert (1992), "Algorithms in
+C++" published by Addison Wesley.
+
+For references about "Newmat" see
+
+Davies, R.B. (1994) Writing a matrix package in C++. In OON-SKI'94: The second
+annual object-oriented numerics conference, pp 207-213. Rogue Wave Software,
+Corvallis.
+
+Eddelbuttel, Dirk (1996) Object-oriented econometrics: matrix programming in
+C++ using GCC and Newmat. Journal of Applied Econometrics, Vol 11, No 2, pp
+199-209.
+
+
+
+
+
+        2  Getting started
+        =  ======= =======
+
+        Overview                                     2.1
+        Make files                                   2.2
+        Customising                                  2.3
+        Compiler performance                         2.4
+        Updating from previous versions              2.5
+        Example                                      2.6
+        Testing                                      2.7
+
+
+
+
+
+        2.1  Overview
+        ===  ========
+
+I use .h as the suffix of definition files and .cpp as the suffix of C++
+source files.
+
+You will need to compile all the *.cpp files listed as program files in the
+files section [6] to get the complete package. Ideally you should store the
+resulting object files as a library. The tmt*.cpp files are used for testing
+[2.7], example.cpp is an example [2.6] and sl_ex.cpp, nl_ex.cpp and garch.cpp
+are examples of the non-linear [3.27] solve and optimisation routines. A
+demonstration of the exception mechanism is in test_exc.cpp.
+
+I include a number of "make" files for compiling the example and the test
+package. See the section on make files [2.2] for details. But with the PC
+compilers, its pretty quick just to load all the files in the interactive
+environments by pointing and clicking.
+
+Use the large or win32 console model when you are using a PC. Do not "outline"
+inline functions. You may need to increase the stack size.
+
+Your source files that access the newmat will need to #include one or more of
+the following files.
+
+include.h:
+   if you want to access just the compiler options
+
+newmat.h:
+   to access just the main matrix library (includes include.h)
+
+newmatap.h:
+   to access the advanced matrix routines such as Cholesky decomposition, QR
+triangularisation etc (includes newmat.h)
+
+newmatio.h:
+   to access the output routines (includes newmat.h) You can use this only
+with compilers that support the standard input/output routines including
+manipulators.
+
+newmatnl.h:
+   to access the non-linear optimisation routines (includes newmat.h)
+
+
+
+See the section on customising [2.3] to see how to edit include.h for your
+environment and the section on compilers [2.4] for any special problems with
+the compiler you are using.
+
+
+
+
+        2.2  Make files
+        ===  ==== =====
+
+I have included "make" files for a number of compilers. These provide an
+alternative way of compiling your programs than with the IDE that comes with
+PC compilers. See the files section [6] for details. See the example [2.6] for
+how to use them. Leave out the target name to compile and link all my examples
+and test files.
+
+PC
+
+I include make files for some of PC compilers I have access to. They all use
+the make utility that comes with the compiler. I don't know whether they work
+with versions of the compilers other than the ones I have. The make files for
+Borland need editing to show where you have stored your Borland compiler.
+
+Unix
+
+The "make" file for the Unix  CC compilers link a .cxx file to each .cpp file
+since some of these compilers do not recognise .cpp as a legitimate extension
+for a C++ file. I suggest you delete this part of the "make" file and, if
+necessary, rename the .cpp files to something your compiler recognises.
+
+My "make" file for Gnu GCC on Unix systems are for use with 'gmake' rather
+than 'make'. This defines BOOL_LIB so there is no need to do this in
+'include.h'. I assume your compiler recognises the .cpp extension. Ordinary
+'make' works with it on the Sun but not the Silicon Graphics or HP machines.
+On Linux use 'make'.
+
+My make file for the CC compilers works with the ordinary make.
+
+To compile everything with the CC compiler use
+
+   make -f cc.mak
+
+or for the gnu compiler use
+
+   gmake -f gnu.mak
+
+
+There is a line in the make file for CC 'rm -f $*.cxx'. Some systems won't
+accept this line and you will need to delete it. In this case, if you have a
+bad compile and you are using my scheme for linking .cxx files, you will need
+to delete the .cxx file link generated by that compile before you can do the
+next one.
+
+
+
+
+        2.3  Customising
+        ===  ===========
+
+The file "include.h" sets a variety of options including several compiler
+dependent options. You may need to edit include.h to get the options you
+require. If you are using a compiler different from one I have worked with you
+may have to set up a new section in  include.h  appropriate for your compiler.
+
+Borland, Turbo, Gnu, Microsoft and Watcom are recognised automatically. If
+none of these are recognised a default set of options is used. These are fine
+for AT&T, HPUX and Sun C++. If you using a compiler I don't know about you may
+have to write a new set of options.
+
+There is an option in include.h for selecting whether you use compiler
+supported exceptions, simulated exceptions, or disable exceptions. Use the
+option for compiler supported exceptions if and only if you have set the
+option on your compiler to recognise exceptions. Disabling exceptions
+sometimes helps with compilers that are incompatible with my exception
+simulation scheme.
+
+If your compiler recognises bool as required by the standard activate the
+statement '#define bool_LIB'. This will deactivate my Boolean class. If you
+are using my make file with the Gnu compiler, then this #define is
+automatically activated.
+
+Activate the appropriate statement to make the element type float or double.
+
+I suggest you leave the option TEMPS_DESTROYED_QUICKLY activated, even though
+the Gnu compiler (<2.6) is the only one I know about that requires it (C-Set
+also requires it?). This stores the "trees" describing matrix expressions on
+the heap rather than the stack and, surprisingly, seems to give better
+performance. See the discussion on destruction of temporaries [8.8] for more
+explanation.
+
+Leave the option TEMPS_DESTROYED_QUICKLY_R not activated unless you are using
+the Gnu G++ [2.4.3] compiler earlier than version 2.6. This option controls
+whether the ReturnMatrix [3.13] construct uses the stack or the heap. The heap
+version is rather kludgy and probably should be avoided where possible.
+
+The option DO_FREE_CHECK [2.7] is used for tracking memory leaks and normally
+should not be activated.
+
+Activate SETUP_C_SUBSCRIPTS if you want to use traditional C style element
+access [3.2]. 
+
+Activate '#define use_namespace' if you want to use namespaces [3.29]. Do this
+only if you are sure your compiler supports namespaces. If you do turn this
+option on, be prepared to turn it off again if the linker reports missing
+links.
+
+Activate '#define _STANDARD_' to use the standard names for the included files
+and to find the floating point precision data using the floating point
+standard. Assume that this doesn't work at present.
+
+If you are using a compiler that "include.h" does not recognise and you want
+to pick up the floating point precision data from "float.h" then activate
+'#define use_float_h'. Otherwise the floating point precision data will be
+accessd from "values.h". You will may need to do this with computers from
+Digital, in particular. 
+
+
+
+
+        2.4  Compiler performance
+        ===  ======== ===========
+
+I have tested this library on a number of compilers. Here are the levels of
+success and any special considerations. In most cases I have chosen code that
+works under all the compilers I have access to, but I have had to include some
+specific work-arounds for some compilers. For the PC versions, I use a 486dx
+computer running windows 95, a Pentium computer running windows NT or Linux
+(Red Hat 4.1) and a 386sx running MSDOS 5. The unix versions are on a Sun
+Sparc station or a HP unix workstation. Thanks to Victoria University and
+Industrial Research Ltd for access to the Unix machines.
+
+I have set up a block of code for each of the compilers in include.h. Turbo,
+Borland, Gnu, Microsoft and Watcom are recognised automatically. There is a
+default option that works for AT&T, Sun C++ 4.0.1 and HPUX. So you don't have
+to make any changes for these compilers. Otherwise you may have to build your
+own set of options in include.h.
+
+        AT&T                                         2.4.1
+        Borland                                      2.4.2
+        Gnu G++                                      2.4.3
+        HPUX                                         2.4.4
+        Microsoft                                    2.4.5
+        Sun                                          2.4.6
+        Watcom                                       2.4.7
+        Zortech                                      2.4.8
+
+
+
+
+        2.4.1  AT&T
+        =====  ====
+
+AT&T C++ 2.1;3.0.1 on a Sun: Previous versions worked on these compilers,
+which I no longer have access to.
+
+In AT&T 2.1 you may get an error when you use an expression for the single
+argument when constructing a Vector or DiagonalMatrix or one of the Triangular
+Matrices. You need to evaluate the expression separately.
+
+
+
+
+        2.4.2  Borland
+        =====  =======
+
+Borland C++ 3.1, 4.5, 5.02: Recently this has been my main development
+platform, so naturally everything works with this compiler. There was a
+problem with the library utility in version 2.0 which is now fixed. You will
+need to use the large or 32 bit flat model. If you are not debugging, turn off
+the options that collect debugging information. Make sure you don't run
+Borland's exceptions and my simulated exceptions at the same time.
+
+If you are using version 5 remember to edit include.h to deactivate my Boolean
+class.
+
+When running my test program under ms-dos you may run out of memory. Either
+compile the test routine to run under "easywin" or use simulated exceptions
+rather than the built in exceptions. Under "easywin" the test program
+indicates a memory leak. I presume this is partly because of the way windows
+organises its heap rather than there being a real problem.
+
+If you can, upgrade to windows 95 or window NT and use the 32 bit console
+model.
+
+If you are using the 16 bit large model, don't forget to keep all matrices
+less than 64K bytes in length (90x90 for a rectangular matrix if you are using
+'double' as your element type). Otherwise your program will crash without
+warning or explanation. You may need to break the tmt [2.7] set of test files
+into two parts to get the program to fit into your computer. 
+
+In version 4.5, under "easywin" the automatic clean-up of objects by the
+exception mechanism does not seem to work correctly. Use my simulated
+exceptions if this is a problem.
+
+One version of Borland had DBL_MIN incorrectly defined. If you are using an
+older version of Borland and are getting strange numerical errors in the test
+programs reinstate the commented out statements in precision.h.
+
+I include make files that work under Borland 4.5 and 5. You will need to edit
+these to correctly locate the directories for the include and library files.
+Both assume you are using simulated exceptions. 'BC.MAK' also works with
+version 3.1 if you delete the options that are not recognised and the
+reference to the library file that is not recognised.
+
+C++ Builder version 4: I have successfully used this using the console wizard
+(menu item file/new - select new tab). Either use namespace or rename a couple
+of my exception names that conflict with Borland. Use compiler exceptions.
+Suppose you are compiling my test program tmt. Rename my "main()" function in
+"tmt.cpp" to "my_main()". Rename "tmt.cpp" to "tmt_main.cpp". Borland will
+generate a new file "tmt.cpp" containing their "main()" function. Put the line
+'int my_main();' above this function and put 'return my_main();' into the body
+of "main()". 
+
+
+
+
+        2.4.3  Gnu G++
+        =====  === ===
+
+Gnu G++ 2.6.0, 2.7.2, 2.8.1:  These work OK.
+
+If you are using 2.7 or later remember to edit include.h to deactivate my
+Boolean class - not necessary if you are using my make [2.2] file. But if you
+are using a version earlier than 2.7 edit the second line of gnu.mak to
+'CXXFLAGS = -O2 -Wall'
+
+For versions earlier than 2.6.0 you must enable the options
+TEMPS_DESTROYED_QUICKLY and TEMPS_DESTROYED_QUICKLY_R. You can't use
+expressions like 'Matrix(X*Y)' in the middle of an expression and
+'(Matrix)(X*Y)' is unreliable. If you write a function returning a matrix, you
+MUST use the ReturnMatrix [3.13] method described in this documentation. This
+is because g++ destroys temporaries occurring in an expression too soon for
+the two stage way of evaluating expressions that newmat uses. You will have
+problems with versions of Gnu earlier than 2.3.1.
+
+Gnu seems to leave some rubbish on the stack. Possibly this is a buffer or
+dynamically loaded subprogram so may not be a bug.
+
+Linux: It works fine on my copy of G++ 2.7.2. In 2.6.?, 'fabs(*X++)' causes a
+problem. You may need to write you own non-inlined version.
+
+
+
+
+
+        2.4.4  HP-UX
+        =====  =====
+
+HP 9000 series HP-UX. I no longer have access to this compiler. Newmat09
+worked without problems with the simulated exceptions; haven't tried the
+built-in exceptions.
+ With recent versions of the compiler you may get warning messages like
+'Unsafe cast between pointers/references to incomplete classes'. At present, I
+think these can be ignored.
+
+Here are comments I made two years ago.
+
+I have tried the library on two versions of HP-UX. (I don't know the version
+numbers, the older is a clone of AT&T 3, the newer is HP's version with
+exceptions). Both worked after the modifications described in this section.
+
+With the older version of the compiler I needed to edit the math.h library
+file to remove a duplicate definition of abs.
+
+With the newer version you can set the +eh option to enable exceptions and
+activate the UseExceptions option in include.h. If you are using my make file,
+you will need to replace CC with CC +eh where ever CC occurs. I recommend that
+you do not do this and either disable exceptions or use my simulated
+exceptions. I get core dumps when I use the built-in exceptions and suspect
+they are not sufficiently debugged as yet.
+
+If you are using my simulated exceptions you may get a mass of error messages
+from the linker about __EH_JMPBUF_TEMP. In this case get file setjmp.h (in
+directory /usr/include/CC ?) and put extern in front of the line
+
+   jmp_buf * __EH_JMPBUF_TEMP;
+
+The file setjmp.h is accessed in my file myexcept.h. You may want to change
+the #include statement to access your edited copy of setjmp.h.
+
+
+
+        2.4.5  Microsoft
+        =====  =========
+
+Microsoft Visual C++ 2.0: Seems to work OK. You can use the makefile
+'ms_nt.mak'.
+
+You must '#define TEMPS_DESTROYED_QUICKLY' owing to a bug in version 7 (at
+least) of MSC. There are some notes in the file 'include.h' on changes to run
+under version 7. I haven't tried newmat10 on version 7.
+
+Microsoft Visual C++ 1.51. Disable exceptions, comment out the line in
+include.h '#define TEMPS_DESTROYED_QUICKLY_R'. In 'tmt.cpp', comment out the
+'Try' and 'CatchAll' lines at the beginning of 'main()' and the line
+'trymati()'. You can use the makefile 'ms.mak'. You will probably need to
+break the tmt [2.7] test files into two parts to get the program to link.
+
+If you can, upgrade to windows 95, 98 or window NT and use the 32 bit console
+model.
+
+If you are using the 16 bit large model, don't forget to keep all matrices
+less than 64K bytes in length (90x90 for a rectangular matrix if you are using
+'double' as your element type). Otherwise your program will crash without
+warning or explanation. You may need to break the tmt [2.7] set of test files
+into two parts to get the program to fit into your computer. 
+
+Microsoft Visual C++ 4: I haven't tried this - a correspondent reports: I use
+Microsoft Visual C++ Version 4. there is only one minor problem. In all files
+you must include '#include "stdafx.h"' (presumably if you are using MFC). This
+file contains essential information for VC++. Leave it out and you get
+"Unexpected end of file".
+
+Microsoft Visual C++ 5: I have tried this in console mode and it seems to work
+satisfactorily. There may be a problem with namespace [3.29] (fixed by Service
+Pack 3?). Turn optimisation off. Edit 'include.h' to use the compiler
+supported exceptions. If you want to work under MFC '#include "stdafx.h"' at
+the beginning of each .cpp file.
+
+Microsoft Visual C++ 6: Get the latest service pack. I have tried this in
+console mode and it seems to work satisfactorily. Edit 'include.h' to use the
+compiler supported exceptions. If you want to work under MFC '#include
+"stdafx.h"' at the beginning of each .cpp file.
+
+
+
+
+        2.4.6  Sun
+        =====  ===
+
+Sun C++ (version 4.2): This seems to work fine.
+
+Sun C++ (version 5): There seems to be a problem with exceptions. If you my
+simulated exceptions the non-linear optimsation programs hang. If you use the
+compiler supported exceptions my test_exc program crashes. So take your
+choice.
+
+
+
+
+        2.4.7  Watcom & Optima++
+        =====  ====== = ========
+
+Watcom C++ (version 10): this works fine. Don't try to run Watcom's exceptions
+and my simulated exceptions at the same time.
+
+But best don't use Watcom's exceptions at all in this version as they do seem
+to cause problems; even when not used.
+
+It seems fine on Optima++ 1.0 in console mode. I haven't tested it in gui
+mode. Optima++ provides some stuff to insert in the main program.  
+
+
+
+        2.4.8  Zortech
+        =====  =======
+
+I don't support Zortech any more and haven't tried the Symantec successors to
+Zortech.
+
+
+
+
+
+        2.5  Updating from previous versions
+        ===  ======== ==== ======== ========
+
+Newmat10 includes new maxima, minima and Determinant [3.8] functions, a faster
+FFT [3.22], revised make [2.2] files for GCC and CC compilers and several
+corrections, new ReSize [3.10] function. The program files include a new file,
+'newfft.cpp', so you will need to include this in the list of files in your
+IDE and make files. If you are updating from a beta version of newmat09 look
+through the next section as there were some late changes to newmat09.
+
+If you are upgrading from newmat08 note the following:
+
+*  Boolean, TRUE, FALSE are now bool, true, false. See customising [2.3] if
+your compiler supports the bool class.
+
+*  ReDimension is now ReSize [3.10].
+
+*  The simulated exception [3.25] package has been updated.
+
+*  Operators '==', '!=', '+=', '-=', '*=', '|=', '&=' are now supported as
+binary [3.6] matrix operators.
+
+*  'A+=f', 'A-=f', 'A*=f', 'A/=f', 'f+A', 'f-A', 'f*A' are supported for  A
+matrix, f scalar [3.7].
+
+*  Fast trigonometric transforms [3.23].
+
+*  Reverse [3.5] function for reversing order of elements in a vector or
+matrix.
+
+*  IsSingular [3.8] function.
+
+*  An option is included for defining namespaces [3.29].
+
+*  Dummy inequality operators are defined for compatibiity with the STL.
+
+*  The row/column classes in newmat3.cpp have been modified to improve
+efficiency and correct an invalid use of pointer arithmetic. Most users won't
+be using these classes explicitly; if you are, please contact me for details
+of the changes.
+
+*  Matrix LU decomposition rewritten (faster for large arrays).
+
+*  The sort function rewritten (faster).
+
+*  The documentation files newmata.txt and newmatb.txt have been amalgamated
+and both are included in the hypertext version. 
+
+*  Some of the make [2.2] files reorganised again. 
+
+
+If you are upgrading from newmat07 note the following:
+
+*  .cxx files are now .cpp files. Some versions of won't accept .cpp. The
+"make" files for Gnu and AT&T link the .cpp files to .cxx files before
+compilation and delete the links after compilation.
+
+*  An option [2.3] in include.h allows you to use compiler supported
+exceptions, simulated exceptions or disable exceptions. Edit the file
+include.h to select one of these three options. Don't simulate exceptions if
+you have set your compiler's option to implement exceptions.
+
+*  New QR decomposition [3.18] functions.
+
+*  A non-linear least squares [3.27] class.
+
+*  No need to explicitly set the AT&T option in include.h.
+
+*  Concatenation and elementwise multiplication [3.6].
+
+*  A new GenericMatrix [3.16] class.
+
+*  Sum [3.8] function.
+
+*  Some of the make [2.2] files reorganised. 
+
+
+If you are upgrading from newmat06 note the following:
+
+*  If you are using << to load a Real into a submatrix change this to =.
+
+
+If you are upgrading from newmat03 or newmat04 note the following
+
+*  .hxx files are now .h files
+
+*  real changed to Real
+
+*  BOOL changed to Boolean
+
+*  CopyToMatrix changed to AsMatrix, etc
+
+*  real(A) changed to A.AsScalar()
+
+
+The current version is quite a bit longer that newmat04, so if you are almost
+out of space with newmat04, don't throw newmat04 away until you have checked
+your program will work under this version.
+
+See the change history [1.7] for other changes.
+
+
+
+        2.6  Example
+        ===  =======
+
+An example is given in 'example.cpp'.  This gives a simple linear regression
+example using five different algorithms. The correct output is given in
+'example.txt'. The program carries out a rough check that no memory is left
+allocated on the heap when it terminates. See the section on testing [2.7] for
+a comment on the reliability of this check and the use of the DO_FREE_CHECK
+option.
+
+I include a variety of make files. To compile the example use a command like
+
+   gmake example -f gnu.mak               (Gnu G++)
+   gmake example -f cc.mak                (AT&T, HPUX, Sun)
+   nmake example.exe -f ms_nt.mak         (Microsoft Visual C++ 2.0)
+   nmake example.exe -f ms.mak            (Microsoft Visual C++ 1.51)
+   make -f bc.mak example.exe             (Borland C++ 4.5, 5)
+   make -f bc32.mak example.exe           (Borland C++ 4.5, 5, 32 bit)
+   wmake example.exe -f watcom.mak        (Watcom C++ 10A)
+   wmake example.exe -f watco_nt.mak      (Watcom C++ 10A, for win NT)
+
+To compile all the example and test files use a command like
+
+   gmake -f gnu.mak                       (Gnu G++)
+
+
+ -----------------------------------------------------------------------------
+The example uses io manipulators. It will not work with a compiler that does
+not support the standard io manipulators.
+ -----------------------------------------------------------------------------
+
+Other example files are 'nl_ex.cpp' and 'garch.cpp' for demonstrating the
+non-linear fitting routines, 'sl_ex' for demonstrating the solve function and
+'test_exc' for demonstrating the exceptions.
+
+
+
+
+        2.7  Testing
+        ===  =======
+
+The library package contains a comprehensive test program in the form of a
+series of files with names of the form tmt?.cxx. The files consist of a large
+number of matrix formulae all of which evaluate to zero (except the first one
+which is used to check that we are detecting non-zero matrices). The printout
+should state that it has found just one non-zero matrix.
+
+The test program should be run with "Real" typedefed to "double" rather than
+"float" in include.h [2.3].
+
+Make sure the C subscripts [3.2] are enabled if you want to test these.
+
+Various versions of the make file (extension .mak) are included with the
+package. See the section on make files [2.2].
+
+The program also allocates and deletes a large block and small block of memory
+before it starts the main testing and then at the end of the test. It then
+checks that the blocks of memory were allocated in the same place. If not then
+one suspects that there has been a memory leak. i.e. a piece of memory has
+been allocated and not deleted.
+
+This is not completely foolproof. Programs may allocate extra print buffers
+while the program is running. I have tried to overcome this by doing a print
+before I allocate the first memory block. Programs may allocate memory for
+different sized items in different places, or might not allocate items
+consecutively. Or they might mix the items with memory blocks from other
+programs. Nevertheless, I seem to get consistent answers from many of the
+compilers I am working with, so I think this is a worthwhile test.
+
+If the DO_FREE_CHECK [2.3] option in include.h is activated, the program
+checks that each 'new' is balanced with exactly one 'delete'. This provides a
+more definitive test of no memory leaks. There are additional statements in
+myexcept.cpp which can be activated to print out details of the memory being
+allocated and released.
+
+I have included a facility for checking that each piece of code in the library
+is really exercised by the test routines. Each block of code in the main part
+of the library contains a word 'REPORT'. 'newmat.h' has a line defining
+'REPORT' that can be activated (deactivate the dummy version). This gives a
+printout of the number of times each of the 'REPORT' statements in the '.cpp'
+files is accessed. Use a grep with line numbers to locate the lines on which
+'REPORT' occurs and compare these with the lines that the printout shows were
+actually accessed. One can then see which lines of code were not accessed.
+
+
+        3  Reference manual
+        =  ========= ======
+
+        Constructors                                 3.1
+        Accessing elements                           3.2
+        Assignment and copying                       3.3
+        Entering values                              3.4
+        Unary operations                             3.5
+        Binary operations                            3.6
+        Matrix and scalar ops                        3.7
+        Scalar functions                             3.8
+        Submatrices                                  3.9 
+        Change dimension                             3.10 
+        Change type                                  3.11 
+        Multiple matrix solve                        3.12 
+        Memory management                            3.13 
+        Efficiency                                   3.14 
+        Output                                       3.15 
+        Accessing unspecified type                   3.16 
+        Cholesky decomposition                       3.17 
+        QR decomposition                             3.18 
+        Singular value decomposition                 3.19
+        Eigenvalue decomposition                     3.20 
+        Sorting                                      3.21
+        Fast Fourier transform                       3.22
+        Fast trigonometric transforms                3.23 
+        Numerical recipes in C                       3.24
+        Exceptions                                   3.25 
+        Cleanup following exception                  3.26
+        Non-linear applications                      3.27 
+        Standard template library                    3.28
+        Namespace                                    3.29
+
+
+
+        3.1  Constructors
+        ===  ============
+
+To construct an m x n matrix, 'A', (m and n are integers) use
+
+    Matrix A(m,n);
+
+The UpperTriangularMatrix, LowerTriangularMatrix, SymmetricMatrix and
+DiagonalMatrix types are square. To construct an n x n matrix use, for example
+
+    UpperTriangularMatrix UT(n);
+    LowerTriangularMatrix LT(n);
+    SymmetricMatrix S(n);
+    DiagonalMatrix D(n);
+
+Band matrices need to include bandwidth information in their constructors.
+
+    BandMatrix BM(n, lower, upper);
+    UpperBandMatrix UB(n, upper);
+    LowerBandMatrix LB(n, lower);
+    SymmetricBandMatrix SB(n, lower);
+
+The integers upper and lower are the number of non-zero diagonals above and
+below the diagonal (excluding the diagonal) respectively.
+
+The RowVector and ColumnVector types take just one argument in their
+constructors:
+
+    RowVector RV(n);
+    ColumnVector CV(n);
+
+These constructors do *not* initialise the elements of the matrices. To set
+all the elements to zero use, for example,
+
+    Matrix A(m, n); A = 0.0;
+
+You can also construct vectors and matrices without specifying the dimension.
+For example
+
+    Matrix A;
+
+In this case the dimension must be set by an assignment statement [3.3] or a
+re-dimension statement [3.10].
+
+You can also use a constructor to set a matrix equal to another matrix or
+matrix expression.
+
+    Matrix A = UT;
+    Matrix A = UT * LT;
+
+Only conversions that don't lose information are supported - eg you cannot
+convert an upper triangular matrix into a diagonal matrix using =.
+
+
+
+
+        3.2  Accessing elements
+        ===  ========= ========
+
+Elements are accessed by expressions of the form 'A(i,j)' where i and j run
+from 1 to the appropriate dimension. Access elements of vectors with just one
+argument. Diagonal matrices can accept one or two subscripts.
+
+This is different from the earliest version of the package in which the
+subscripts ran from 0 to one less than the appropriate dimension. Use
+'A.element(i,j)' if you want this earlier convention.
+
+'A(i,j)' and 'A.element(i,j)' can appear on either side of an = sign.
+
+If you activate the '#define SETUP_C_SUBSCRIPTS' in 'include.h' you can also
+access elements using the traditional C style notation. That is 'A[i][j]' for
+matrices (except diagonal) and 'V[i]' for vectors and diagonal matrices. The
+subscripts start at zero (ie like element) and there is no range checking.
+Because of the possibility of confusing 'V(i)' and 'V[i]', I suggest you do
+not activate this option unless you really want to use it.
+
+Symmetric matrices are stored as lower triangular matrices. It is important to
+remember this if you are using the 'A[i][j]' method of accessing elements.
+Make sure the first subscript is greater than or equal to the second
+subscript. However, if you are using the 'A(i,j)' method the program will swap
+'i' and 'j' if necessary; so it doesn't matter if you think of the storage as
+being in the upper triangle (but it "does" matter in some other situations
+such as when entering [3.4] data).
+
+
+        3.3  Assignment and copying
+        ===  ========== === =======
+
+The operator '=' is used for copying matrices, converting matrices, or
+evaluating expressions. For example
+
+    A = B;  A = L;  A = L * U;
+
+Only conversions that don't lose information are supported. The dimensions of
+the matrix on the left hand side are adjusted to those of the matrix or
+expression on the right hand side. Elements on the right hand side which are
+not present on the left hand side are set to zero.
+
+The operator '<<' can be used in place of '=' where it is permissible for
+information to be lost.
+
+For example
+
+    SymmetricMatrix S; Matrix A;
+    ......
+    S << A.t() * A;
+
+is acceptable whereas
+
+    S = A.t() * A;                            // error
+
+will cause a runtime error since the package does not (yet?) recognise
+'A.t()*A' as symmetric.
+
+Note that you can not use '<<' with constructors. For example
+
+    SymmetricMatrix S << A.t() * A;           // error
+
+does not work.
+
+Also note that '<<' cannot be used to load values from a full matrix into a
+band matrix, since it will be unable to determine the bandwidth of the band
+matrix.
+
+A third copy routine is used in a similar role to '='. Use
+
+    A.Inject(D);
+
+to copy the elements of 'D' to the corresponding elements of 'A' but leave the
+elements of 'A' unchanged if there is no corresponding element of 'D' (the '='
+operator would set them to 0). This is useful, for example, for setting the
+diagonal elements of a matrix without disturbing the rest of the matrix.
+Unlike '=' and '<<', Inject does not reset the dimensions of 'A', which must
+match those of 'D'. Inject does not test for no loss of information.
+
+You cannot replace 'D' by a matrix expression. The effect of 'Inject(D)'
+depends on the type of 'D'. If 'D' is an expression it might not be obvious to
+the user what type it would have. So I thought it best to disallow
+expressions.
+
+Inject can be used for loading values from a regular matrix into a band
+matrix. (Don't forget to zero any elements of the left hand side that will not
+be set by the loading operation).
+
+Both '<<' and Inject can be used with submatrix expressions on the left hand
+side. See the section on submatrices [3.9].
+
+To set the elements of a matrix to a scalar use operator '='
+
+    Real r; int m,n;
+    ......
+    Matrix A(m,n); A = r;
+
+
+
+
+
+        3.4  Entering values
+        ===  ======== ======
+
+You can load the elements of a matrix from an array:
+
+    Matrix A(3,2);
+    Real a[] = { 11,12,21,22,31,33 };
+    A << a;
+
+This construction does not check that the numbers of elements match correctly.
+This version of '<<' can be used with submatrices on the left hand side. It is
+not defined for band matrices.
+
+Alternatively you can enter short lists using a sequence of numbers separated
+by '<<' .
+
+    Matrix A(3,2);
+    A << 11 << 12
+      << 21 << 22
+      << 31 << 32;
+
+This does check for the correct total number of entries, although the message
+for there being insufficient numbers in the list may be delayed until the end
+of the block or the next use of this construction. This does not work for band
+matrices or submatrices, or for long lists. Also try to restrict its use to
+numbers. You can include expressions, but these must not call a function which
+includes the same construction.
+
+Remember that matrices are stored by rows and that symmetric matrices are
+stored as lower triangular matrices when using these methods to enter data. 
+
+
+
+
+        3.5  Unary operators
+        ===  ===== =========
+
+The package supports unary operations
+
+    X = -A;           // change sign of elements
+    X = A.t();        // transpose
+    X = A.i();        // inverse (of square matrix A)
+    X = A.Reverse();  // reverse order of elements of vector
+                      // or matrix (not band matrix)
+
+
+
+
+        3.6  Binary operators
+        ===  ====== =========
+
+The package supports binary operations
+
+    X = A + B;       // matrix addition
+    X = A - B;       // matrix subtraction
+    X = A * B;       // matrix multiplication
+    X = A.i() * B;   // equation solve (square matrix A)
+    X = A | B;       // concatenate horizontally (concatenate the rows)
+    X = A & B;       // concatenate vertically (concatenate the columns)
+    X = SP(A, B);    // elementwise product of A and B (Schur product)
+    bool b = A == B; // test whether A and B are equal
+    bool b = A != B; // ! (A == B)
+    A += B;          // A = A + B;
+    A -= B;          // A = A - B;
+    A *= B;          // A = A * B;
+    A |= B;          // A = A | B;
+    A &= B;          // A = A & B;
+    <, >, <=, >=     // included for compatibility with STL - see notes
+
+
+Notes:
+
+*  If you are doing repeated multiplication. For example 'A*B*C', use brackets
+to force the order of evaluation to minimise the number of operations. If 'C'
+is a column vector and 'A' is not a vector, then it will usually reduce the
+number of operations to use 'A*(B*C)'.
+
+*  In the equation solve example case the inverse is not explicitly
+calculated. An LU decomposition of 'A' is performed and this is applied to
+'B'. This is more efficient than calculating the inverse and then multiplying.
+See also multiple matrix solving [3.12].
+
+*  The package does not (yet?) recognise 'B*A.i()' as an equation solve and
+the inverse of 'A' would be calculated. It is probably better to use
+'(A.t().i()*B.t()).t()'.
+
+*  Horizontal or vertical concatenation returns a result of type Matrix,
+RowVector or ColumnVector.
+
+*  If 'A' is m x p, 'B' is m x q, then 'A | B' is m x (p+q) with the k-th row
+being the elements of the k-th row of 'A' followed by the elements of the k-th
+row of 'B'.
+
+*  If 'A' is p x n, 'B' is q x n, then 'A & B' is (p+q) x n with the k-th
+column being the elements of the k-th column of 'A' followed by the elements
+of the k-th column of 'B'.
+
+*  For complicated concatenations of matrices, consider instead using
+submatrices [3.9].
+
+*  See the section on submatrices [3.9] on using a submatrix on the RHS of an
+expression.
+
+*  Two matrices are equal if their difference is zero. They may be of
+different types. For the CroutMatrix or BandLUMatrix they must be of the same
+type and have all their elements equal. This is not a very useful operator and
+is included for compatibility with some container templates.
+
+*  The inequality operators are included for compatibility with the standard
+template library [3.28]. If actually called, they will throw an exception. So
+don't try to sort a "list" of matrices.
+
+
+
+
+
+        3.7  Matrix and scalar
+        ===  ====== === ======
+
+The following expressions multiply the elements of a matrix 'A' by a scalar f:
+'A * f' or 'f * A' . Likewise one can divide the elements of a matrix 'A' by a
+scalar f: 'A / f'
+
+The expressions  'A + f' and 'A - f' add or subtract a rectangular matrix of
+the same dimension as 'A' with elements equal to 'f' to or from the matrix
+'A'.
+
+The expression 'f + A' is an alternative to 'A + f'. The expression 'f - A'
+subtracts matrix 'A' from a rectangular matrix of the same dimension as 'A'
+and with elements equal to 'f'
+
+The expression 'A += f' replaces 'A' by 'A + f'. Operators '-=', '*=', '/='
+are similarly defined.
+
+
+
+        3.8  Scalar functions of a matrix
+        ===  ====== ========= == = ======
+
+
+    int i, j;
+    int m = A.Nrows();                     // number of rows
+    int n = A.Ncols();                     // number of columns
+    Real r = A.AsScalar();                 // value of 1x1 matrix
+    Real ssq = A.SumSquare();              // sum of squares of elements
+    Real sav = A.SumAbsoluteValue();       // sum of absolute values
+    Real s = A.Sum();                      // sum of values
+    Real mv = A.MaximumAbsoluteValue();    // maximum of absolute values
+    Real mv = A.MinimumAbsoluteValue();    // minimum of absolute values
+    Real mv = A.Maximum();                 // maximum value
+    Real mv = A.Minimum();                 // minimum value
+    Real mv = A.MaximumAbsoluteValue1(i);  // maximum of absolute values
+    Real mv = A.MinimumAbsoluteValue1(i);  // minimum of absolute values
+    Real mv = A.Maximum1(i);               // maximum value
+    Real mv = A.Minimum1(i);               // minimum value
+    Real mv = A.MaximumAbsoluteValue2(i,j);// maximum of absolute values
+    Real mv = A.MinimumAbsoluteValue2(i,j);// minimum of absolute values
+    Real mv = A.Maximum2(i,j);             // maximum value
+    Real mv = A.Minimum2(i,j);             // minimum value
+    Real norm = A.Norm1();                 // maximum of sum of absolute
+                                              values of elements of a column
+    Real norm = A.NormInfinity();          // maximum of sum of absolute
+                                              values of elements of a row
+    Real t = A.Trace();                    // trace
+    Real d = A.Determinant();              // determinant
+    LogAndSign ld = A.LogDeterminant();    // log of determinant
+    bool z = A.IsZero();                   // test all elements zero
+    MatrixType mt = A.Type();              // type of matrix
+    Real* s = Store();                     // pointer to array of elements
+    int l = Storage();                     // length of array of elements
+    bool s = A.IsSingular();               // A is a CroutMatrix or
+                                              BandLUMatrix
+    MatrixBandWidth mbw = A.BandWidth();   // upper and lower bandwidths
+
+
+The functions 'A.MaximumAbsoluteValue()', 'A.MinimumAbsoluteValue()',
+'A.Maximum()' and 'A.Minimum()' throw an exception if 'A' has no rows or no
+columns. The versions 'A.MaximumAbsoluteValue1(i)', etc return the location of
+the extreme element in a RowVector, ColumnVector or DiagonalMatrix. The
+versions 'A.MaximumAbsoluteValue2(i,j)', etc return the row and column numbers
+of the extreme element. These versions also throw an exception if 'A' has no
+rows or no columns. If the extreme value occurs more than once the location of
+the last one is given. 
+
+'A.LogDeterminant()' returns a value of type LogAndSign. If ld is of type
+LogAndSign  use
+
+    ld.Value()    to get the value of the determinant
+    ld.Sign()     to get the sign of the determinant (values 1, 0, -1)
+    ld.LogValue() to get the log of the absolute value.
+
+Note that the direct use of the function 'Determinant()' will often cause a
+floating point overflow exception.
+
+'A.IsZero()' returns Boolean value 'true' if the matrix 'A' has all elements
+equal to 0.0.
+
+'IsSingular' is defined only for CroutMatrix and BandLUMatrix. It returns
+'true' if one of the diagonal elements of the LU decomposition is exactly
+zero.  
+
+'MatrixType mt = A.Type()' returns the type of a matrix. Use '(char*)mt' to
+get a string  (UT, LT, Rect, Sym, Diag, Band, UB, LB, Crout, BndLU) showing
+the type (Vector types are returned as Rect).
+
+'MatrixBandWidth' has member functions 'Upper()' and 'Lower()' for finding the
+upper and lower bandwidths (number of diagonals above and below the diagonal,
+both zero for a diagonal matrix). For non-band matrices -1 is returned for
+both these values.
+
+The versions Sum(A), SumSquare(A), SumAbsoluteValue(A),
+MaximumAbsoluteValue(A), MinimumAbsoluteValue(A), Maximum(A), Minimum(A),
+Trace(A), LogDeterminant(A), Determinant(A), Norm1(A), NormInfinity(A) can be
+used in place of A.Sum(), A.SumSquare(), A.SumAbsoluteValue(),
+A.MaximumAbsoluteValue(), A.MinimumAbsoluteValue(), A.Maximum(), A.Minimum(),
+A.Trace(), A.LogDeterminant(), A.Norm1(), A.NormInfinity().
+
+
+
+
+        3.9  Submatrices
+        ===  ===========
+
+
+    A.SubMatrix(fr,lr,fc,lc)
+
+This selects a submatrix from 'A'. The arguments  fr,lr,fc,lc are the first
+row, last row, first column, last column of the submatrix with the numbering
+beginning at 1. This may be used in any matrix expression or on the left hand
+side of '=', '<<' or Inject. Inject does not check no information loss. You
+can also use the construction
+
+    Real c; .... A.SubMatrix(fr,lr,fc,lc) = c;
+
+to set a submatrix equal to a constant.
+
+The following are variants of SubMatrix:
+
+    A.SymSubMatrix(f,l)             //   This assumes fr=fc and lr=lc.
+    A.Rows(f,l)                     //   select rows
+    A.Row(f)                        //   select single row
+    A.Columns(f,l)                  //   select columns
+    A.Column(f)                     //   select single column
+
+In each case f and l mean the first and last row or column to be selected
+(starting at 1).
+
+I allow lr = fr-1, lc = fc-1 or l = f-1 to indicate that a matrix of zero rows
+or columns is to be returned.
+
+If SubMatrix or its variant occurs on the right hand side of an '=' or '<<' or
+within an expression its type is as follows
+
+    A.SubMatrix(fr,lr,fc,lc):           If A is RowVector or
+                                        ColumnVector then same type
+                                        otherwise type Matrix
+    A.SymSubMatrix(f,l):                Same type as A
+    A.Rows(f,l):                        Type Matrix
+    A.Row(f):                           Type RowVector
+    A.Columns(f,l):                     Type Matrix
+    A.Column(f):                        Type ColumnVector
+
+If SubMatrix or its variant appears on the left hand side of  '=' or '<<' ,
+think of its type being Matrix. Thus 'L.Row(1)' where 'L' is
+LowerTriangularMatrix expects 'L.Ncols()' elements even though it will use
+only one of them. If you are using '=' the program will check for no loss of
+data.
+
+A SubMatrix can appear on the left-hand side of '+=' or '-=' with a matrix
+expression on the right-hand side. It can also appear on the left-hand side of
+'+=', '-=', '*=' or '/=' with a Real on the right-hand side. In each case
+there must be no loss of information.
+
+Do not use the '+=' and '-=' operations with a submatrix of a SymmetricMatrix
+or BandSymmetricMatrix on the LHS and a Real on the RHS. 
+
+If you are are using the submatrix facility to build a matrix from a small
+number of components, consider instead using the concatenation operators
+[3.6].
+
+
+
+
+        3.10  Change dimensions
+        ====  ====== ==========
+
+The following operations change the dimensions of a matrix. The values of the
+elements are lost.
+
+    A.ReSize(nrows,ncols);        // for type Matrix or nricMatrix
+    A.ReSize(n);                  // for all other types, except Band
+    A.ReSize(n,lower,upper);      // for BandMatrix
+    A.ReSize(n,lower);            // for LowerBandMatrix
+    A.ReSize(n,upper);            // for UpperBandMatrix
+    A.ReSize(n,lower);            // for SymmetricBandMatrix
+    A.ReSize(B);                  // set dims to those of B 
+
+Use 'A.CleanUp()' to set the dimensions of 'A' to zero and release all the
+heap memory.
+
+'A.ReSize(B)' sets the dimensions of 'A' to those of a matrix 'B'. This
+includes the band-width in the case of a band matrix. It is an error for 'A'
+to be a band matrix and 'B' not a band matrix (or diagonal matrix).
+
+Remember that 'ReSize' destroys values. If you want to 'ReSize', but keep the
+values in the bit that is left use something like
+
+   ColumnVector V(100);
+   ...                            // load values
+   V = V.Rows(1,50);              // to get first 50 values.
+
+If you want to extend a matrix or vector use something like
+
+   ColumnVector V(50);
+   ...                            // load values
+   { V.Release(); ColumnVector X=V; V.ReSize(100); V.Rows(1,50)=X; }
+                                  // V now length 100
+
+
+
+
+
+        3.11  Change type
+        ====  ====== ====
+
+The following functions interpret the elements of a matrix (stored row by row)
+to be a vector or matrix of a different type. Actual copying is usually
+avoided where these occur as part of a more complicated expression.
+
+    A.AsRow()
+    A.AsColumn()
+    A.AsDiagonal()
+    A.AsMatrix(nrows,ncols)
+    A.AsScalar()
+
+The expression 'A.AsScalar()' is used to convert a 1 x 1 matrix to a scalar.
+
+
+
+
+        3.12  Multiple matrix solve
+        ====  ======== ====== =====
+
+To solve the matrix equation 'Ay = b' where 'A' is a square matrix of equation
+coefficients, 'y' is a column vector of values to be solved for, and 'b' is a
+column vector, use the code
+
+    int n = something
+    Matrix A(n,n); ColumnVector b(n);
+    ... put values in A and b
+    ColumnVector y = A.i() * b;       // solves matrix equation
+
+The following notes are for the case where you want to solve more than one
+matrix equation with different values of 'b' but the same 'A'. Or where you
+want to solve a matrix equation and also find the determinant of 'A'. In these
+cases you probably want to avoid repeating the LU decomposition of 'A' for
+each solve or determinant calculation.
+
+
+
+If 'A' is a square or symmetric matrix use
+
+    CroutMatrix X = A;                // carries out LU decomposition
+    Matrix AP = X.i()*P; Matrix AQ = X.i()*Q;
+    LogAndSign ld = X.LogDeterminant();
+
+rather than
+
+    Matrix AP = A.i()*P; Matrix AQ = A.i()*Q;
+    LogAndSign ld = A.LogDeterminant();
+
+since each operation will repeat the LU decomposition.
+
+If 'A' is a BandMatrix or a SymmetricBandMatrix begin with
+
+    BandLUMatrix X = A;               // carries out LU decomposition
+
+A CroutMatrix or a BandLUMatrix can't be manipulated or copied. Use references
+as an alternative to copying.
+
+Alternatively use
+
+    LinearEquationSolver X = A;
+
+This will choose the most appropriate decomposition of 'A'. That is, the band
+form if 'A' is banded; the Crout decomposition if 'A' is square or symmetric
+and no decomposition if 'A' is triangular or diagonal. If you want to use the
+LinearEquationSolver '#include newmatap.h'.
+
+
+
+
+        3.13  Memory management
+        ====  ====== ==========
+
+The package does not support delayed copy. Several strategies are required to
+prevent unnecessary matrix copies.
+
+Where a matrix is called as a function argument use a constant reference. For
+example
+
+    YourFunction(const Matrix& A)
+
+rather than
+
+    YourFunction(Matrix A)
+
+
+Skip the rest of this section on your first reading.
+ -----------------------------------------------------------------------------
+Gnu g++ (< 2.6) users please read on; if you are returning matrix values from
+a function, then you must use the ReturnMatrix construct.     
+ -----------------------------------------------------------------------------
+
+A second place where it is desirable to avoid unnecessary copies is when a
+function is returning a matrix. Matrices can be returned from a function with
+the return command as you would expect. However these may incur one and
+possibly two copyings of the matrix. To avoid this use the following
+instructions.
+
+Make your function of type  ReturnMatrix . Then precede the return statement
+with a Release statement (or a ReleaseAndDelete statement if the matrix was
+created with new). For example
+
+
+    ReturnMatrix MakeAMatrix()
+    {
+       Matrix A;                // or any other matrix type
+       ......
+       A.Release(); return A;
+    }
+
+or
+
+    ReturnMatrix MakeAMatrix()
+    {
+       Matrix* m = new Matrix;
+       ......
+       m->ReleaseAndDelete(); return *m;
+    }
+
+If your compiler objects to this code, replace the return statements with
+
+    return A.ForReturn();
+
+or
+
+    return m->ForReturn();
+
+
+If you are using AT&T C++ you may wish to replace  'return A;' by return
+'(ReturnMatrix)A;'  to avoid a warning message; but this will give a runtime
+error with Gnu. (You can't please everyone.)
+ -----------------------------------------------------------------------------
+Do not forget to make the function of type ReturnMatrix; otherwise you may get
+incomprehensible run-time errors.                       
+ -----------------------------------------------------------------------------
+You can also use '.Release()' or '->ReleaseAndDelete()' to allow a matrix
+expression to recycle space. Suppose you call
+
+    A.Release();
+
+just before 'A' is used just once in an expression. Then the memory used by
+'A' is either returned to the system or reused in the expression. In either
+case, 'A''s memory is destroyed. This procedure can be used to improve
+efficiency and reduce the use of memory.
+
+Use '->ReleaseAndDelete' for matrices created by new if you want to completely
+delete the matrix after it is accessed.
+
+
+
+
+        3.14  Efficiency
+        ====  ==========
+
+The package tends to be not very efficient for dealing with matrices with
+short rows. This is because some administration is required for accessing rows
+for a variety of types of matrices. To reduce the administration a special
+multiply routine is used for rectangular matrices in place of the generic one.
+Where operations can be done without reference to the individual rows (such as
+adding matrices of the same type) appropriate routines are used.
+
+When you are using small matrices (say smaller than 10 x 10) you may find it
+faster to use rectangular matrices rather than the triangular or symmetric
+ones.
+
+
+
+        3.15  Output
+        ====  ======
+
+To print a matrix use an expression like
+
+    Matrix A;
+    ......
+    cout << setw(10) << setprecision(5) << A;
+
+This will work only with systems that support the standard input/output
+routines including manipulators. You need to #include the file newmatio.h.
+
+The present version of this routine is useful only for matrices small enough
+to fit within a page or screen width.
+
+To print several vectors or matrices in columns use a concatenation operator
+[3.6]:
+
+   ColumnVector A, B;
+   .....
+   cout << setw(10) << setprecision(5) << (A | B);
+
+
+
+
+        3.16  Unspecified type
+        ====  =========== ====
+
+Skip this section on your first reading.
+
+If you want to work with a matrix of unknown type, say in a function. You can
+construct a matrix of type 'GenericMatrix'. Eg
+
+   Matrix A;
+   .....                                  // put some values in A
+   GenericMatrix GM = A;
+
+A GenericMatrix matrix can be used anywhere where a matrix expression can be
+used and also on the left hand side of an '='. You can pass any type of matrix
+(excluding the Crout and BandLUMatrix types) to a 'const GenericMatrix&'
+argument in a function. However most scalar functions including Nrows(),
+Ncols(), Type() and element access do not work with it. Nor does the
+ReturnMatrix construct. See also the paragraph on LinearEquationSolver [3.12].
+
+An alternative and less flexible approach is to use BaseMatrix or
+GeneralMatrix.
+
+Suppose you wish to write a function which accesses a matrix of unknown type
+including expressions (eg 'A*B'). Then use a layout similar to the following:
+
+   void YourFunction(BaseMatrix& X)
+   {
+      GeneralMatrix* gm = X.Evaluate();   // evaluate an expression
+                                          // if necessary
+      ........                            // operations on *gm
+      gm->tDelete();                      // delete *gm if a temporary
+   }
+
+See, as an example, the definitions of 'operator<<' in newmat9.cpp.
+
+Under certain circumstances; particularly where 'X' is to be used just once in
+an expression you can leave out the 'Evaluate()' statement and the
+corresponding 'tDelete()'. Just use 'X' in the expression.
+
+If you know YourFunction will never have to handle a formula as its argument
+you could also use
+
+   void YourFunction(const GeneralMatrix& X)
+   {
+      ........                            // operations on X
+   }
+
+Do not try to construct a GeneralMatrix or BaseMatrix.
+
+
+
+
+        3.17  Cholesky decomposition
+        ====  ======== =============
+
+Suppose 'S' is symmetric and positive definite. Then there exists a unique
+lower triangular matrix 'L' such that 'L * L.t() = S'. To calculate this use
+
+    SymmetricMatrix S;
+    ......
+    LowerTriangularMatrix L = Cholesky(S);
+
+If 'S' is a symmetric band matrix then 'L' is a band matrix and an alternative
+procedure is provided for carrying out the decomposition:
+
+    SymmetricBandMatrix S;
+    ......
+    LowerBandMatrix L = Cholesky(S);
+
+
+
+
+        3.18  QR decomposition
+        ====  == =============
+
+This is a variant on the usual QR transformation.
+
+Start with matrix
+
+       / 0    0 \      s
+       \ X    Y /      n
+
+         s    t
+
+Our version of the QR decomposition multiplies this matrix by an orthogonal
+matrix Q to get
+
+       / U    M \      s
+       \ 0    Z /      n
+
+         s    t
+
+where 'U' is upper triangular (the R of the QR transform).
+
+This is good for solving least squares problems: choose b (matrix or row
+vector) to minimise the sum of the squares of the elements of
+
+         Y - X*b
+
+Then choose 'b = U.i()*M;' The residuals 'Y - X*b' are in 'Z'.
+
+This is the usual QR transformation applied to the matrix 'X' with the square
+zero matrix attached concatenated on top of it. It gives the same triangular
+matrix as the QR transform applied directly to 'X' and generally seems to work
+in the same way as the usual QR transform. However it fits into the matrix
+package better and also gives us the residuals directly. It turns out to be
+essentially a modified Gram-Schmidt decomposition.
+
+Two routines are provided:
+
+    QRZ(X, U);
+
+replaces 'X' by orthogonal columns and forms 'U'.
+
+    QRZ(X, Y, M);
+
+uses 'X' from the first routine, replaces 'Y' by 'Z' and forms 'M'.
+
+The are also two routines 'QRZT(X, L)' and 'QRZT(X, Y, M)' which do the same
+decomposition on the transposes of all these matrices. QRZT replaces the
+routines HHDecompose in earlier versions of newmat. HHDecompose is still
+defined but just calls QRZT.
+
+
+
+
+        3.19  Singular value decomposition
+        ====  ======== ===== =============
+
+The singular value decomposition of an m x n 'Matrix' 'A' (where m >= n) is a
+decomposition
+
+    A  = U * D * V.t()
+
+where 'U' is m x n with  'U.t() * U'  equalling the identity, 'D' is an n x n
+'DiagonalMatrix' and 'V' is an n x n orthogonal matrix (type 'Matrix' in
+"Newmat").
+
+Singular value decompositions are useful for understanding the structure of
+ill-conditioned matrices, solving least squares problems, and for finding the
+eigenvalues of 'A.t() * A'.
+
+To calculate the singular value decomposition of 'A' (with m >= n) use one of
+
+    SVD(A, D, U, V);                  // U = A is OK
+    SVD(A, D);
+    SVD(A, D, U);                     // U = A is OK
+    SVD(A, D, U, false);              // U (can = A) for workspace only
+    SVD(A, D, U, V, false);           // U (can = A) for workspace only
+
+where 'A', 'U' and 'V' are of type 'Matrix' and 'D' is a 'DiagonalMatrix'. 
+The values of 'A' are not changed unless 'A' is also inserted as the third
+argument.
+
+
+
+
+        3.20  Eigenvalue decomposition
+        ====  ========== =============
+
+An eigenvalue decomposition of a SymmetricMatrix 'A' is a decomposition
+
+    A  = V * D * V.t()
+
+where 'V' is an orthogonal matrix (type 'Matrix' in "Newmat") and 'D' is a
+DiagonalMatrix.
+
+Eigenvalue analyses are used in a wide variety of engineering, statistical and
+other mathematical analyses.
+
+The package includes two algorithms: Jacobi and Householder. The first is
+extremely reliable but much slower than the second.
+
+The code is adapted from routines in "Handbook for Automatic Computation, Vol
+II, Linear Algebra" by Wilkinson and Reinsch, published by Springer Verlag. 
+
+
+    Jacobi(A,D,S,V);                  // A, S symmetric; S is workspace,
+                                      //    S = A is OK; V is a matrix
+    Jacobi(A,D);                      // A symmetric
+    Jacobi(A,D,S);                    // A, S symmetric; S is workspace,
+                                      //    S = A is OK
+    Jacobi(A,D,V);                    // A symmetric; V is a matrix
+
+    EigenValues(A,D);                 // A symmetric
+    EigenValues(A,D,S);               // A, S symmetric; S is for back
+                                      //    transforming, S = A is OK
+    EigenValues(A,D,V);               // A symmetric; V is a matrix
+
+where 'A', 'S' are of type 'SymmetricMatrix', 'D' is of type 'DiagonalMatrix'
+and 'V' is of type 'Matrix'. The values of 'A' are not changed unless 'A' is
+also inserted as the third argument. If you need eigenvectors use one of the
+forms with matrix 'V'. The eigenvectors are returned as the columns of 'V'.
+
+
+
+
+        3.21  Sorting
+        ====  =======
+
+To sort the values in a matrix or vector, 'A', (in general this operation
+makes sense only for vectors and diagonal matrices) use
+
+    SortAscending(A);
+
+or
+
+    SortDescending(A);
+
+I use the quicksort algorithm. The algorithm is similar to that in Sedgewick's
+algorithms in C++. If the sort seems to be failing (as quicksort can do) an
+exception is thrown.
+
+You will get incorrect results if you try to sort a band matrix - but why
+would you want to sort a band matrix?
+
+
+
+        3.22  Fast Fourier transform
+        ====  ==== ======= =========
+
+
+   FFT(X, Y, F, G);                         // F=X and G=Y are OK
+
+where 'X', 'Y', 'F', 'G' are column vectors. 'X' and 'Y' are the real and
+imaginary input vectors; 'F' and 'G' are the real and imaginary output
+vectors. The lengths of 'X' and 'Y' must be equal and should be the product of
+numbers less than about 10 for fast execution.
+
+The formula is
+
+          n-1
+   h[k] = SUM  z[j] exp (-2 pi i jk/n)
+          j=0
+
+where 'z[j]' is stored complex and stored in 'X(j+1)' and 'Y(j+1)'. Likewise
+'h[k]' is complex and stored in 'F(k+1)' and 'G(k+1)'. The fast Fourier
+algorithm takes order n log(n) operations (for "good" values of n) rather than
+n**2 that straight evaluation (see the file 'tmtf.cpp') takes. 
+
+I use one of two methods:
+
+*  A program originally written by Sande and Gentleman. This requires that "n"
+can be expressed as a product of small numbers.</LI>  *  A method of Carl de
+Boor (1980), "Siam J Sci Stat Comput", pp 173-8. The sines and cosines are
+calculated explicitly. This gives better accuracy, at an expense of being a
+little slower than is otherwise possible. This is slower than the
+Sande-Gentleman program but will work for all "n" --- although it will be very
+slow for "bad" values of "n".</LI>
+
+
+Related functions
+
+   FFTI(F, G, X, Y);                        // X=F and Y=G are OK
+   RealFFT(X, F, G);
+   RealFFTI(F, G, X);
+
+'FFTI' is the inverse transform for 'FFT'. 'RealFFT' is for the case when the
+input vector is real, that is 'Y = 0'. I assume the length of 'X', denoted by
+n, is even. The program sets the lengths of 'F' and 'G' to n/2 + 1. 'RealFFTI'
+is the inverse of 'RealFFT'.
+
+See also the section on fast trigonometric transforms [3.23].
+
+
+
+
+        3.23  Fast trigonometric transforms
+        ====  ==== ============= ==========
+
+These are the sin and cosine transforms as defined by Charles Van Loan (1992)
+in "Computational frameworks for the fast Fourier transform" published by
+SIAM. See page 229. Some other authors use slightly different conventions. All
+the functions call the fast Fourier transforms [3.22] and require an even
+transform length, denoted by "m" in these notes. As with the FFT "m" should be
+the product of numbers less than about 10 for fast execution. 
+
+The functions I define are 
+
+   DCT(U,V);                // U, V are ColumnVectors, length "m+1"
+   DCT_inverse(U,V);        // inverse of DCT
+   DST(U,V);                // U, V are ColumnVectors, length "m+1"
+   DST_inverse(U,V);        // inverse of DST
+   DCT_II(U,V);             // U, V are ColumnVectors, length "m"
+   DCT_II_inverse(U,V);     // inverse of DCT_II
+   DST_II(U,V);             // U, V are ColumnVectors, length "m"
+   DST_II_inverse(U,V);     // inverse of DST_II
+
+where 'U' is the input and 'V' is the output. 'V = U' is OK. The length of 'V'
+is set by the functions.
+
+Here are the formulae:
+
+DCT
+
+                   m-1                             k
+   v[k] = u[0]/2 + SUM { u[j] cos (pi jk/m) } + (-) u[m]/2
+                   j=1
+
+for 'k = 0...m', where 'u[j]' and 'v[k]' are stored in 'U(j+1)' and 'V(k+1)'.
+
+DST
+
+          m-1
+   v[k] = SUM { u[j] sin (pi jk/m) }
+          j=1
+
+for 'k = 1...(m-1)', where 'u[j]' and 'v[k]' are stored in 'U(j+1)' and
+'V(k+1)'. 'u[0]' and 'u[m]' are ignored and 'v[0]' and 'v[m]' are set to zero.
+
+DCT_II
+
+          m-1
+   v[k] = SUM { u[j] cos (pi (j+1/2)k/m) }
+          j=0
+
+for 'k = 0...(m-1)', where 'u[j]' and 'v[k]' are stored in 'U(j+1)' and
+'V(k+1)'.
+
+DST_II
+
+           m
+   v[k] = SUM { u[j] sin (pi (j-1/2)k/m) }
+          j=1
+
+for 'k = 1...m', where 'u[j]' and 'v[k]' are stored in 'U(j)' and 'V(k)'.
+
+Note that the relationship between the subscripts in the formulae and those
+used in "newmat" is different for DST_II (and DST_II_inverse).
+
+
+
+
+        3.24  Interface to Numerical Recipes in C
+        ====  ========= == ========= ======= == =
+
+This package can be used with the vectors and matrices defined in "Numerical
+Recipes in C". You need to edit the routines in Numerical Recipes so that the
+elements are of the same type as used in this package. Eg replace float by
+double, vector by dvector and matrix by dmatrix, etc. You may need to edit the
+function definitions to use the version acceptable to your compiler (if you
+are using the first edition of NRIC). You may need to enclose the code from
+Numerical Recipes in 'extern "C" { ... }'. You will also need to include the
+matrix and vector utility routines.
+
+Then any vector in Numerical Recipes with subscripts starting from 1 in a
+function call can be accessed by a RowVector, ColumnVector or DiagonalMatrix
+in the present package. Similarly any matrix with subscripts starting from 1
+can be accessed by an  nricMatrix  in the present package. The class
+nricMatrix is derived from Matrix and can be used in place of Matrix. In each
+case, if you wish to refer to a RowVector, ColumnVector, DiagonalMatrix or
+nricMatrix X in an function from Numerical Recipes, use 'X.nric()' in the
+function call.
+
+Numerical Recipes cannot change the dimensions of a matrix or vector. So
+matrices or vectors must be correctly dimensioned before a Numerical Recipes
+routine is called.
+
+For example
+
+   SymmetricMatrix B(44);
+   .....                             // load values into B
+   nricMatrix BX = B;                // copy values to an nricMatrix
+   DiagonalMatrix D(44);             // Matrices for output
+   nricMatrix V(44,44);              //    correctly dimensioned
+   int nrot;
+   jacobi(BX.nric(),44,D.nric(),V.nric(),&nrot);
+                                     // jacobi from NRIC
+   cout << D;                        // print eigenvalues
+
+
+
+
+
+        3.25  Exceptions
+        ====  ==========
+
+Here is the class structure for exceptions:
+
+Exception
+  Logic_error
+    ProgramException                 miscellaneous matrix error
+    IndexException                   index out of bounds
+    VectorException                  unable to convert matrix to vector
+    NotSquareException               matrix is not square (invert, solve)
+    SubMatrixDimensionException      out of bounds index of submatrix
+    IncompatibleDimensionsException  (multiply, add etc)
+    NotDefinedException              operation not defined (eg <)
+    CannotBuildException             copying a matrix where copy is undefined
+    InternalException                probably an error in newmat
+  Runtime_error
+    NPDException                     matrix not positive definite (Cholesky)
+    ConvergenceException             no convergence (e-values, non-linear,
+sort)
+    SingularException                matrix is singular (invert, solve)
+    SolutionException                no convergence in solution routine
+    OverflowException                floating point overflow
+  Bad_alloc                          out of space (new fails)
+
+
+I have attempted to mimic the exception class structure in the C++ standard
+library, by defining the Logic_error and Runtime_error classes.
+
+If there is no catch statement or exceptions are disabled then my
+'Terminate()' function in 'myexcept.h' is called. This prints out an error
+message, the dimensions and types of the matrices involved, the name of the
+routine detecting the exception, and any other information set by the Tracer
+[4] class. Also see the section on error messages [4] for additional notes on
+the messages generated by the exceptions.
+
+You can also print this information by printing 'Exception::what()'.
+
+See the file 'test_exc.cpp' as an example of catching an exception and
+printing the error message.
+
+The 08 version of newmat defined a member function 'void SetAction(int)' to
+help customise the action when an exception is called. This has been deleted
+in the 09 version. Now include an instruction such as 'cout <<
+Exception::what() << endl;' in the 'Catch' or 'CatchAll' block to determine
+the action.
+
+The library includes the alternatives of using the inbuilt exceptions provided
+by a compiler, simulating exceptions, or disabling exceptions. See customising
+[2.3] for selecting the correct exception option. 
+
+The rest of this section describes my partial simulation of exceptions for
+compilers which do not support C++ exceptions. I use Carlos Vidal's article in
+the September 1992 "C Users Journal" as a starting point.
+
+Newmat does a partial clean up of memory following throwing an exception - see
+the next section. However, the present version will leave a little heap memory
+unrecovered under some circumstances. I would not expect this to be a major
+problem, but it is something that needs to be sorted out.
+
+The functions/macros I define are Try, Throw, Catch, CatchAll and
+CatchAndThrow. Try, Throw, Catch and CatchAll correspond to try, throw, catch
+and catch(...) in the C++ standard. A list of Catch clauses must be terminated
+by either CatchAll or CatchAndThrow but not both. Throw takes an Exception as
+an argument or takes no argument (for passing on an exception). I do not have
+a version of Throw for specifying which exceptions a function might throw.
+Catch takes an exception class name as an argument; CatchAll and CatchAndThrow
+don't have any arguments. Try, Catch and CatchAll must be followed by blocks
+enclosed in curly brackets.
+
+I have added another macro ReThrow to mean a rethrow, Throw(). This was
+necessary to enable the package to be compatible with both my exception
+package and C++ exceptions.
+
+If you want to throw an exception, use a statement like
+
+   Throw(Exception("Error message\n"));
+
+It is important to have the exception declaration in the Throw statement,
+rather than as a separate statement.
+
+All exception classes must be derived from the class, Exception, defined in
+newmat and can contain only static variables. See the examples in newmat if
+you want to define additional exceptions.
+
+
+
+
+        3.26  Cleanup after an exception
+        ====  ======= ===== == =========
+
+This section is about the simulated exceptions used in newmat. It is
+irrelevant if you are using the exceptions built into a compiler or have set
+the disable-exceptions option.
+
+The simulated exception mechanisms in newmat are based on the C functions
+setjmp and longjmp. These functions do not call destructors so can lead to
+garbage being left on the heap. (I refer to memory allocated by "new" as heap
+memory). For example, when you call
+
+   Matrix A(20,30);
+
+a small amount of space is used on the stack containing the row and column
+dimensions of the matrix and 600 doubles are allocated on the heap for the
+actual values of the matrix. At the end of the block in which A is declared,
+the destructor for A is called and the 600 doubles are freed. The locations on
+the stack are freed as part of the normal operations of the stack. If you
+leave the block using a longjmp command those 600 doubles will not be freed
+and will occupy space until the program terminates.
+
+To overcome this problem newmat keeps a list of all the currently declared
+matrices and its exception mechanism will return heap memory when you do a
+Throw and Catch.
+
+However it will not return heap memory from objects from other packages.
+
+If you want the mechanism to work with another class you will have to do four
+things:
+
+1:  derive your class from class Janitor defined in except.h;
+
+2:  define a function 'void CleanUp()' in that class to return all heap
+memory;
+
+3:  include the following lines in the class definition
+
+      public:
+         void* operator new(size_t size)
+         { do_not_link=true; void* t = ::operator new(size); return t; }
+         void operator delete(void* t) { ::operator delete(t); }
+
+4:  be sure to include a copy constructor in you class definition, that is,
+something like
+
+      X(const X&);
+
+
+Note that the function 'CleanUp()' does somewhat the same duties as the
+destructor. However 'CleanUp()' has to do the "cleaning" for the class you are
+working with and also the classes it is derived from. So it will often be
+wrong to use exactly the same code for both 'CleanUp()' and the destructor or
+to define your destructor as a call to 'CleanUp()'.
+
+
+
+
+        3.27  Non-linear applications
+        ====  ========== ============
+
+Files solution.h, solution.cpp contain a class for solving for x in y = f(x)
+where x is a one-dimensional continuous monotonic function. This is not a
+matrix thing at all but is included because it is a useful thing and because
+it is a simpler version of the technique used in the non-linear least squares.
+
+Files newmatnl.h, newmatnl.cpp contain a series of classes for non-linear
+least squares and maximum likelihood.
+
+Documentation for both of these is in the definition files. Simple examples
+are in sl_ex.cpp, nl_ex.cpp and garch.cpp.
+
+
+
+
+        3.28  Standard template library
+        ====  ======== ======== =======
+
+The standard template library (STL) is the set of "container templates"
+(vector, deque, list etc) defined by the C++ standards committee. Newmat is
+intended to be compatible with the STL in the sense that you can store
+matrices in the standard containers. I have defined '==' and inequality  [3.6]
+operators to help make this possible. Probably there will have to be some
+other changes. My experiments with the Rogue Wave STL that comes with Borland
+C++ 5.0 showed that some things worked and some things unexpectedly didn't
+work. In particular, I couldn't get the list container to work. I don't know
+whose fault this is.
+
+If you want to use the container classes with Newmat please note
+
+*   Don't use simulated exceptions.
+
+*   Make sure the option DO_FREE_CHECK [2.3] is *not* turned on.
+
+*   You can store only one type of matrix in a container. If you want to use a
+variety of types use the GenericMatrix type or store pointers to the matrices.
+
+*   The vector and deque container templates like to copy their elements. For
+the vector container this happens when you insert an element anywhere except
+at the end or when you append an element and the current vector storage
+overflows. Since Newmat does not have "copy-on-write" this could get very
+inefficient. (Later versions may have "copy-on-write" for the GenericMatrix
+type).
+
+*   You won't be able to sort the container or do anything that would call an
+inequality operator.
+
+
+I doubt whether the STL container will be used often for matrices. So I don't
+think these limitations are very critical. If you think otherwise, please tell
+me.
+
+
+
+
+
+        3.29  Namespace
+        ====  =========
+
+"Namespace" is a new facility in C++. Its purpose is to avoid name clashes
+between different libraries. I have included the namespace capability.
+Activate the line '#define use_namespace' in 'include.h'. Then include either
+the statement
+
+   using namespace NEWMAT;
+
+at the beginning of any file that needs to access the newmat library or 
+
+   using namespace RBD_LIBRARIES;
+
+at the beginning of any file that needs to access all my libraries. 
+
+This works correctly with Borland [2.4.2] C++ version 5.
+
+Microsoft [2.4.5] Visual C++ version 5 works in my example and test files, but
+fails with apparently insignificant changes (it may be more reliable if you
+have applied service pack 3). If you #include "newmatap.h", but no other
+newmat include file, then also #include "newmatio.h".
+
+My use of namespace does not work with Gnu g++ [2.4.3] version 2.7.2.
+
+I have defined the following namespaces:
+
+*   RBD_COMMON for functions and classes used by most of my libraries *  
+NEWMAT for the newmat library *   RBD_LIBRARIES for all my libraries
+
+
+
+
+
+        4  Error messages
+        =  ===== ========
+
+Most error messages are self-explanatory. The message gives the size of the
+matrices involved. Matrix types are referred to by the following codes:
+
+   Matrix or vector                   Rect
+   Symmetric matrix                   Sym
+   Band matrix                        Band
+   Symmetric band matrix              SmBnd
+   Lower triangular matrix            LT
+   Lower triangular band matrix       LwBnd
+   Upper triangular matrix            UT
+   Upper triangular band matrix       UpBnd
+   Diagonal matrix                    Diag
+   Crout matrix (LU matrix)           Crout
+   Band LU matrix                     BndLU
+
+Other codes should not occur.
+
+See the section on exceptions [3.25] for more details on the structure of the
+exception classes.
+
+I have defined a class Tracer that is intended to help locate the place where
+an error has occurred. At the beginning of a function I suggest you include a
+statement like
+
+   Tracer tr("name");
+
+where name is the name of the function. This name will be printed as part of
+the error message, if an exception occurs in that function, or in a function
+called from that function. You can change the name as you proceed through a
+function with the ReName function
+
+   tr.ReName("new name");
+
+if, for example, you want to track progress through the function.
+
+
+
+
+        5  Bugs
+        =  ====
+
+
+*  Small memory leaks may occur when an exception is thrown and caught.
+
+*  My exception scheme may not be not properly linked in with the standard
+library exceptions. In particular, my scheme may fail to catch out-of-memory
+exceptions.
+
+
+
+
+
+
+        6  List of files
+        =  ==== == =====
+
+Documentation
+
+ README          readme file
+ NEWMAT   TXT    documentation file
+
+
+Definition files
+
+ BOOLEAN  H      boolean class definition
+ CONTROLW H      control word definition file
+ INCLUDE  H      details of include files and options
+ MYEXCEPT H      general exception handler definitions
+ NEWMAT   H      main matrix class definition file
+ NEWMATAP H      applications definition file
+ NEWMATIO H      input/output definition file
+ NEWMATNL H      non-linear optimisation definition file
+ NEWMATRC H      row/column functions definition files
+ NEWMATRM H      rectangular matrix access definition files
+ PRECISIO H      numerical precision constants
+ SOLUTION H      one dimensional solve definition file
+
+
+Program files
+
+ BANDMAT  CPP    band matrix routines
+ CHOLESKY CPP    Cholesky decomposition
+ EVALUE   CPP    eigenvalues and eigenvector calculation
+ FFT      CPP    fast Fourier, trig. transforms
+ HHOLDER  CPP    QR routines
+ JACOBI   CPP    eigenvalues by the Jacobi method
+ MYEXCEPT CPP    general error and exception handler
+ NEWFFT   CPP    new fast Fourier transform
+ NEWMAT1  CPP    type manipulation routines
+ NEWMAT2  CPP    row and column manipulation functions
+ NEWMAT3  CPP    row and column access functions
+ NEWMAT4  CPP    constructors, resize, utilities
+ NEWMAT5  CPP    transpose, evaluate, matrix functions
+ NEWMAT6  CPP    operators, element access
+ NEWMAT7  CPP    invert, solve, binary operations
+ NEWMAT8  CPP    LU decomposition, scalar functions
+ NEWMAT9  CPP    output routines
+ NEWMATEX CPP    matrix exception handler
+ NEWMATNL CPP    non-linear optimisation
+ NEWMATRM CPP    rectangular matrix access functions
+ SORT     CPP    sorting functions
+ SOLUTION CPP    one dimensional solve
+ SUBMAT   CPP    submatrix functions
+ SVD      CPP    singular value decomposition
+
+
+Example files
+
+ EXAMPLE  CPP    example of use of package
+ EXAMPLE  TXT    output from example
+ SL_EX    CPP    example of OneDimSolve routine
+ SL_EX    TXT    output from example
+ NL_EX    CPP    example of non-linear least squares
+ NL_EX    TXT    output from example
+ GARCH    CPP    example of maximum-likelihood fit
+ GARCH    DAT    data file for garch.cpp
+ GARCH    TXT    output from example
+ TEST_EXC CPP    demonstration exceptions
+ TEST_EXC TXT    output from TEST_EXC.CPP
+
+
+Test files
+
+ TMT*     CPP    test files
+ TMT      TXT    output from the test files
+
+See the section on testing [2.7] for details of the test files.
+
+Make files
+
+ GNU      MAK    make file for Gnu G++
+ CC       MAK    make file for AT&T, Sun and HPUX
+ MS_NT    MAK    make file for Microsoft Visual C++ 2 (windows NT)
+ MS       MAK    make file for Microsoft Visual C++ 1.51 (DOS)
+ BC       MAK    make file for Borland C++ 4.5,5 (large model)
+ BC32     MAK    make file for Borland C++ 4.5,5 (32 bit console model)
+ WATCOM   MAK    make file for Watcom 10
+ WATCO_NT MAK    make file for Watcom 10 (windows NT)
+
+
+
+
+
+        7  Problem report form
+        =  ======= ====== ====
+
+Copy and paste this to your editor; fill it out and email to
+    robertd@netlink.co.nz (don't forget the "d" in robertd).
+
+But first look in my web page http://webnz.com/robert/ to see if the bug has
+already been reported.
+
+ Version: ............... newmat10 beta (26 December 1999)
+ Your email address: ....
+ Today's date: ..........
+ Your machine: ..........
+ Operating system: ......
+ Compiler & version: ....
+ Compiler options
+   (eg GUI or console)...
+ Describe the problem - attach examples if possible:
+
+
+
+
+
+
+
+
+
+
+
+
+        8  Notes on the design of the library
+        =  ===== == === ====== == === =======
+
+        Safety, usability, efficiency                8.1
+        Matrix vs array library                      8.2
+        Design questions                             8.3
+        Data storage                                 8.4
+        Memory management                            8.5
+        Evaluation of expressions                    8.6
+        Explosion in the number of operations        8.7
+        Destruction of temporaries                   8.8
+        A calculus of matrix types                   8.9
+        Error handling                               8.10
+        Sparse matrices                              8.11
+        Complex matrices                             8.12
+
+
+I describe some of the ideas behind this package, some of the decisions that I
+needed to make and give some details about the way it works. You don't need to
+read this part of the documentation in order to use the package.
+
+It isn't obvious what is the best way of going about structuring a matrix
+package. I don't think you can figure this out with "thought" experiments.
+Different people have to try out different approaches. And someone else may
+have to figure out which is best. Or, more likely, the ultimate packages will
+lift some ideas from each of a variety of trial packages. So, I don't claim my
+package is an "ultimate" package, but simply a trial of a number of ideas. The
+following pages give some background on these ideas.
+
+
+        8.1  Safety, usability, efficiency
+        ===  ======= ========== ==========
+
+Some general comments
+
+A library like "newmat" needs to balance "safety", "usability" and
+"efficiency".
+
+By safety, I mean getting the right answer, and not causing crashes or damage
+to the computer system.
+
+By usability, I mean being easy to learn and use, including not being too
+complicated, being intuitive, saving the users' time, being nice to use.
+
+Efficiency means minimising the use of computer memory and time.
+
+In the early days of computers the emphasis was on efficiency. But computer
+power gets cheaper and cheaper, halving in price every 18 months. On the other
+hand the unaided human brain is probably not a lot better than it was 100,000
+years ago! So we should expect the balance to shift to put more emphasis on
+safety and usability and a little less on efficiency. So I don't mind if my
+programs are a little less efficient than programs written in pure C (or
+Fortran) if I gain substantially in safety and usability. But I would mind if
+they were a lot less efficient.
+
+Type of use
+
+Second reason for putting extra emphasis on safety and usability is the way I
+and, I suspect, most other users actually use "newmat". Most completed
+programs are used only a few times. Some result is required for a client,
+paper or thesis. The program is developed and tested, the result is obtained,
+and the program archived. Of course bits of the program will be recycled for
+the next project. But it may be less usual for the same program to be run over
+and over again. So the cost, computer time + people time, is in the
+development time and often, much less in the actual time to run the final
+program. So good use of people time, especially during development is really
+important. This means you need highly usable libraries.
+
+So if you are dealing with matrices, you want the good interface that I have
+tried to provide in "newmat", and, of course, reliable methods underneath it.
+
+Of course, efficiency is still important. We often want to run the biggest
+problem our computer will handle and often a little bigger. The C++ language
+almost lets us have both worlds. We can define a reasonably good interface,
+and get good efficiency in the use of the computer.
+
+Levels of access
+
+We can imagine the "black box" model of a "newmat". Suppose the inside is
+hidden but can be accessed by the methods described in the reference [3]
+section. Then the interface is reasonably consistent and intuitive. Matrices
+can be accessed and manipulated in much the same way as doubles or ints in
+regular C. All accesses are checked. It is most unlikely that an incorrect
+index will crash the system. In general, users do not need to use pointers, so
+one shouldn't get pointers pointing into space. And, hopefully, you will get
+simpler code and so less errors.
+
+There are some exceptions to this. In particular, the C-like subscripts [3.2]
+are not checked for validity. They give faster access but with a lower level
+of safety.
+
+Then there is the Store() [3.8] function which takes you to the data array
+within a matrix. This takes you right inside the "black box". But this is what
+you have to use if you are writing, for example, a new matrix factorisation,
+and require fast access to the data array. I have tried to write code to
+simplify access to the interior of a rectangular matrix, see file
+newmatrm.cpp, but I don't regard this as very successful, as yet, and have not
+included it in the documentation. Ideally we should have improved versions of
+this code for each of the major types of matrix. But, in reality, most of my
+matrix factorisations are written in what is basically the C language with
+very little C++.
+
+So our "box" is not very "black". You have a choice of how far you penetrate.
+On the outside you have a good level of safety, but in some cases efficiency
+is compromised a little. If you penetrate inside the "box" safety is reduced
+but you can get better efficiency.
+
+Some performance data
+
+This section looks at the performance on "newmat" for simple sums, comparing
+it with pure C code and with a somewhat unintelligent array program.
+
+The following table lists the time (in seconds) for carrying out the
+operations 'X=A+B;', 'X=A+B+C;', 'X=A+B+C+D;', where 'X,A,B,C,D' are of type
+ColumnVector, with a variety of programs. I am using Borland C++, version 5 in
+32 bit console mode under windows NT 4.0 on a PC with a 150 mhz pentium and
+128 mbytes of memory.
+
+        length	iters.	newmat	subs.	C	C-resz	array
+
+    X=A+B
+        2000000	2	1.2	3.7	1.2	1.4	3.3
+        200000	20	1.2	3.7	1.2	1.5	3.1
+        20000	200	1.0	3.6	1.0	1.2	2.9
+        2000	2000	1.0	3.6	0.9	0.9	2.2
+        200	20000	0.8	3.0	0.4	0.5	1.9
+        20	200000	5.5	2.9	0.4	0.9	2.8
+        2	2000000	43.9	3.2	1.0	4.2	12.3
+
+    X=A+B+C						
+        2000000	2	2.5	4.6	1.6	2.1	32.5
+        200000	20	2.1	4.6	1.6	1.8	6.2
+        20000	200	1.8	4.5	1.5	1.8	5.6
+        2000	2000	1.8	4.4	1.3	1.3	3.9
+        200	20000	2.2	4.3	1.0	0.9	2.3
+        20	200000	8.5	4.3	1.0	1.2	3.0
+        2	2000000	62.5	3.9	1.0	4.4	17.7
+
+    X=A+B+C+D						
+        2000000	2	3.7	6.7	2.4	2.8	260.7
+        200000	20	3.7	6.7	2.4	2.5	9.2
+        20000	200	3.4	6.6	2.3	2.9	8.2
+        2000	2000	2.9	6.4	2.0	2.0	5.9
+        200	20000	2.5	5.5	1.0	1.3	4.3
+        20	200000	9.9	5.5	1.0	1.6	4.5
+        2	2000000	76.5	5.8	1.7	5.0	24.9
+
+The first column gives the lengths of the arrays, the second the number of
+iterations and the remaining columns the total time required in seconds. If
+the only thing that consumed time was the double precision addition then the
+numbers within each block of the table would be the same.
+
+The column labelled "newmat" is using the standard "newmat" add. In the next
+column the calculation is using the usual C style "for" loop and accessing the
+elements using "newmat" subscripts such as 'A(i)'. The column labelled "C"
+uses the usual C method: 'while (j--) *x++ = *a++ + *b++;' . The following
+column also includes an 'X.ReSize()' in the outer loop to correspond to the
+reassignment of memory that "newmat" would do. The final column is the time
+taken by a simple array package that makes no attempt to eliminate unnecessary
+copying or to recycle temporary memory but does have array definitions of the
+basic operators. It does, however, do its sums in blocks of 4 and copies in
+blocks of 8 in the same way that "newmat" does. 
+
+Here are my conclusions.
+
+
+*  "Newmat" does very badly for length 2 and doesn't do very well for length
+20. There is some particularly tortuous code in "newmat" for determining which
+sum algorithm to use and I am sure this could be improved. However the "array"
+program is also having difficulty with length 2 so it is unlikely that the
+problem could be completely eliminated. 
+
+*  The "array" program is running into problems for length 2,000,000. This is
+because RAM memory is being exhausted.
+
+*  For arrays of length 2000 or longer "newmat" is doing about as well as C
+and slightly better than C with resize in the 'X=A+B' table. For the other two
+tables it is slower, but not dramatically so.
+
+*  Addition using the "newmat" subscripts, while considerably slower than the
+others, is still surprisingly good.
+
+*  The "array" program is more than 2 times slower than "newmat" for lengths
+2000 or higher.
+
+In summary: for the situation considered here, "newmat" is doing very well for
+large ColumnVectors, even for sums with several terms, but not so well for
+shorter ColumnVectors.
+
+
+        8.2  Matrix vs array library
+        ===  ====== == ===== =======
+
+The "newmat" library is for the manipulation of matrices, including the
+standard operations such as multiplication as understood by numerical
+analysts, engineers and mathematicians.
+
+A matrix is a two dimensional array of numbers. However, very special
+operations such as matrix multiplication are defined specifically for
+matrices. This means that a "matrix" library, as I understand the term, is
+different from a general "array" library.
+
+I see a matrix package as providing the following
+
+ 1. Evaluation of matrix expressions in a form familiar to scientists and
+engineers. For example 'A = B * (C + D.t());'. In particular '*' means matrix
+multiply.
+
+ 2. Access to the elements of a matrix;
+
+ 3. Access to submatrices;
+
+ 4. Common elementary matrix functions such as determinant and trace;
+
+ 5. A platform for developing advanced matrix functions such as eigen-value
+analysis;
+
+ 6. Good efficiency and storage management;
+
+ 7. Graceful exit from errors.
+
+ It may also provide
+
+ 8. A variety of types of elements (eg real and complex);
+
+ 9. A variety of types of matrices (eg rectangular and symmetric).
+
+In contrast an array package should provide
+
+ 1'. Arrays can be copied with a single instruction; may have some arithmetic
+operations for elementwise combination of arrays, say '+', '-', '*', '/', it
+may provide matrix multiplication as a function;
+
+ 2'. High speed access to elements directly and perhaps with iterators;
+
+ 3'. Access to subarrays and rows (and columns?);
+
+ 6'. Good efficiency and storage management;
+
+ 7'. Graceful exit from errors;
+
+ 8'. A wide variety of types of elements (eg int, float, double, string etc);
+
+ 9'. One, two and three dimensional arrays, at least, with starting points of
+the indices set by user.
+
+It may be possible to amalgamate these two sets of requirements to some
+extent. However "newmat" is definitely oriented towards the first set.
+
+
+        8.3  Design questions
+        ===  ====== =========
+
+Even within the bounds set by the requirements of a matrix library there is a
+substantial opportunity for variation between what different matrix packages
+might provide. It is not possible to build a matrix package that will meet
+everyone's requirements. In many cases if you put in one facility, you impose
+overheads on everyone using the package. This both in storage required for the
+program and in efficiency. Likewise a package that is optimised towards
+handling large matrices is likely to become less efficient for very small
+matrices where the administration time for the matrix may become significant
+compared with the time to carry out the operations. It is better to provide a
+variety of packages (hopefully compatible) so that most users can find one
+that meets their requirements. This package is intended to be one of these
+packages; but not all of them.
+
+Since my background is in statistical methods, this package is oriented
+towards the kinds things you need for statistical analyses.
+
+Now looking at some specific questions.
+
+What size of matrices?
+
+A matrix library may target small matrices (say 3 x 3), or medium sized
+matrices, or very large matrices.
+
+A library targeting very small matrices will seek to minimise administration.
+A library for medium sized or very large matrices can spend more time on
+administration in order to conserve space or optimise the evaluation of
+expressions. A library for very large matrices will need to pay special
+attention to storage and numerical properties. This library is designed for
+medium sized matrices. This means it is worth introducing some optimisations,
+but I don't have to worry about setting up some form of virtual memory.
+
+Which matrix types?
+
+As well as the usual rectangular matrices, matrices occuring repeatedly in
+numerical calculations are upper and lower triangular matrices, symmetric
+matrices and diagonal matrices. This is particularly the case in calculations
+involving least squares and eigenvalue calculations. So as a first stage these
+were the types I decided to include.
+
+It is also necessary to have types row vector and column vector. In a "matrix"
+package, in contrast to an "array" package, it is necessary to have both these
+types since they behave differently in matrix expressions. The vector types
+can be derived for the rectangular matrix type, so having them does not
+greatly increase the complexity of the package.
+
+The problem with having several matrix types is the number of versions of the
+binary operators one needs. If one has 5 distinct matrix types then a simple
+library will need 25 versions of each of the binary operators. In fact, we can
+evade this problem, but at the cost of some complexity. 
+
+What element types?
+
+Ideally we would allow element types double, float, complex and int, at least.
+It might be reasonably easy, using templates or equivalent, to provide a
+library which could handle a variety of element types. However, as soon as one
+starts implementing the binary operators between matrices with different
+element types, again one gets an explosion in the number of operations one
+needs to consider. At the present time the compilers I deal with are not up to
+handling this problem with templates. (Of course, when I started writing
+"newmat" there were no templates). But even when the compilers do meet the
+specifications of the draft standard, writing a matrix package that allows for
+a variety of element types using the template mechanism is going to be very
+difficult. I am inclined to use templates in an "array" library but not in a
+"matrix" library.
+
+Hence I decided to implement only one element type. But the user can decide
+whether this is float or double. The package assumes elements are of type
+Real. The user typedefs Real to float or double.
+
+It might also be worth including symmetric and triangular matrices with extra
+precision elements (double or long double) to be used for storage only and
+with a minimum of operations defined. These would be used for accumulating the
+results of sums of squares and product matrices or multistage QR
+triangularisations. 
+
+Allow matrix expressions
+
+I want to be able to write matrix expressions the way I would on paper. So if
+I want to multiply two matrices and then add the transpose of a third one I
+can write something like 'X = A * B + C.t();'. I want this expression to be
+evaluated with close to the same efficiency as a hand-coded version. This is
+not so much of a problem with expressions including a multiply since the
+multiply will dominate the time. However, it is not so easy to achieve with
+expressions with just '+' and '-'.
+
+A second requirement is that temporary matrices generated during the
+evaluation of an expression are destroyed as quickly as possible.
+
+A desirable feature is that a certain amount of "intelligence" be displayed in
+the evaluation of an expression. For example, in the expression 'X = A.i() *
+B;' where 'i()' denotes inverse, it would be desirable if the inverse wasn't
+explicitly calculated.
+
+Naming convention
+
+How are classes and public member functions to be named? As a general rule I
+have spelt identifiers out in full with individual words being capitalised.
+For example "UpperTriangularMatrix". If you don't like this you can #define or
+typedef shorter names. This convention means you can select an abbreviation
+scheme that makes sense to you.
+
+Exceptions to the general rule are the functions for transpose and inverse. To
+make matrix expressions more like the corresponding mathematical formulae, I
+have used the single letter abbreviations, 't()' and 'i()'. 
+
+Row and column index ranges
+
+In mathematical work matrix subscripts usually start at one. In C, array
+subscripts start at zero. In Fortran, they start at one. Possibilities for
+this package were to make them start at 0 or 1 or be arbitrary.
+
+Alternatively one could specify an "index set" for indexing the rows and
+columns of a matrix. One would be able to add or multiply matrices only if the
+appropriate row and column index sets were identical.
+
+In fact, I adopted the simpler convention of making the rows and columns of a
+matrix be indexed by an integer starting at one, following the traditional
+convention. In an earlier version of the package I had them starting at zero,
+but even I was getting mixed up when trying to use this earlier package. So I
+reverted to the more usual notation and started at 1. 
+
+Element access - method and checking
+
+We want to be able to use the notation 'A(i,j)' to specify the '(i,j)'-th
+element of a matrix. This is the way mathematicians expect to address the
+elements of matrices. I consider the notation 'A[i][j]' totally alien. However
+I include this as an option to help people converting from C.
+
+There are two ways of working out the address of 'A(i,j)'. One is using a
+"dope" vector which contains the first address of each row. Alternatively you
+can calculate the address using the formula appropriate for the structure of
+'A'. I use this second approach. It is probably slower, but saves worrying
+about an extra bit of storage.
+
+The other question is whether to check for 'i' and 'j' being in range. I do
+carry out this check following years of experience with both systems that do
+and systems that don't do this check. I would hope that the routines I supply
+with this package will reduce your need to access elements of matrices so
+speed of access is not a high priority. 
+
+Use iterators
+
+Iterators are an alternative way of providing fast access to the elements of
+an array or matrix when they are to be accessed sequentially. They need to be
+customised for each type of matrix. I have not implemented iterators in this
+package, although some iterator like functions are used internally for some
+row and column functions.
+
+
+        8.4  Data storage
+        ===  ==== =======
+
+Structure
+
+Each matrix object contains the basic information such as the number of rows
+and columns and a status variable plus a pointer to the data array which is on
+the heap.
+
+One block or several
+
+The elements of the matrix are stored as a single array. Alternatives would
+have been to store each row as a separate array or a set of adjacent rows as a
+separate array. The present solution simplifies the program but limits the
+size of matrices in 16 bit PCs that have a 64k byte limit on the size of
+arrays (I don't use the 'huge' keyword). The large arrays may also cause
+problems for memory management in smaller machines.
+
+By row or by column or other
+
+In Fortran two dimensional arrays are stored by column. In most other systems
+they are stored by row. I have followed this later convention. This makes it
+easier to interface with other packages written in C but harder to interface
+with those written in Fortran. This may have been a wrong decision. Most work
+on the efficient manipulation of large matrices is being done in Fortran. It
+would have been easier to use this work if I had adopted the Fortran
+convention.
+
+An alternative would be to store the elements by mid-sized rectangular blocks.
+This might impose less strain on memory management when one needs to access
+both rows and columns.
+
+Storage of symmetric matrices
+
+Symmetric matrices are stored as lower triangular matrices. The decision was
+pretty arbitrary, but it does slightly simplify the Cholesky decomposition
+program.
+
+
+
+        8.5  Memory management - reference counting or status variable?
+        ===  ====== ========== = ========= ======== == ====== =========
+
+Consider the instruction
+
+   X = A + B + C;
+
+To evaluate this a simple program will add 'A' to 'B' putting the total in a
+temporary 'T1'. Then it will add 'T1' to 'C' creating another temporary 'T2'
+which will be copied into 'X'. 'T1' and 'T2' will sit around till the end of
+the execution of the statement and perhaps of the block. It would be faster if
+the program recognised that 'T1' was temporary and stored the sum of 'T1' and
+'C' back into 'T1' instead of creating 'T2' and then avoided the final copy by
+just assigning the contents of 'T1' to 'X' rather than copying. In this case
+there will be no temporaries requiring deletion. (More precisely there will be
+a header to be deleted but no contents).
+
+For an instruction like
+
+   X = (A * B) + (C * D);
+
+we can't easily avoid one temporary being left over, so we would like this
+temporary deleted as quickly as possible.
+
+I provide the functionality for doing all this by attaching a status variable
+to each matrix. This indicates if the matrix is temporary so that its memory
+is available for recycling or deleting. Any matrix operation checks the status
+variables of the matrices it is working with and recycles or deletes any
+temporary memory.
+
+An alternative or additional approach would be to use "reference counting and
+delayed copying" - also known as "copy on write". If a program requests a
+matrix to be copied, the copy is delayed until an instruction is executed
+which modifies the memory of either the original matrix or the copy. If the
+original matrix is deleted before either matrix is modified, in effect, the
+values of the original matrix are transfered to the copy without any actual
+copying taking place. This solves the difficult problem of returning an object
+from a function without copying and saves the unnecessary copying in the
+previous examples. 
+
+There are downsides to the delayed copying approach. Typically, for delayed
+copying one uses a structure like the following:
+
+
+   Matrix
+     |
+     +------> Array Object
+     |          |
+     |          +------> Data array
+     |          |
+     |          +------- Counter
+     |
+     +------ Dimension information
+
+
+where the arrows denote a pointer to a data structure. If one wants to access
+the "Data array" one will need to track through two pointers. If one is going
+to write, one will have to check whether one needs to copy first. This is not
+important when one is going to access the whole array, say, for a add
+operation. But if one wants to access just a single element, then it imposes a
+significant additional overhead on that operation. Any subscript operation
+would need to check whether an update was required - even read since it is
+hard for the compiler to tell whether a subscript access is a read or write.
+
+Some matrix libraries don't bother to do this. So if you write 'A = B;' and
+then modify an element of one of 'A' or 'B', then the same element of the
+other is also modified. I don't think this is acceptable behaviour.
+
+Delayed copy does not provide the additional functionality of my approach but
+I suppose it would be possible to have both delayed copy and tagging
+temporaries.
+
+My approach does not automatically avoid all copying. In particular, you need
+use a special technique to return a matrix from a function without copying.
+
+
+
+        8.6  Evaluation of expressions - lazy evaluation
+        ===  ========== == =========== = ==== ==========
+
+Consider the instruction
+
+   X = B - X;
+
+A simple program will subtract 'X' from 'B', store the result in a temporary
+'T1' and copy 'T1' into 'X'. It would be faster if the program recognised that
+the result could be stored directly into 'X'. This would happen automatically
+if the program could look at the instruction first and mark 'X' as temporary.
+
+C programmers would expect to avoid the same problem with
+
+   X = X - B;
+
+by using an operator '-=' 
+
+   X -= B;
+
+However this is an unnatural notation for non C users and it may be nicer to
+write 'X = X - B'; and know that the program will carry out the
+simplification.
+
+Another example where this intelligent analysis of an instruction is helpful
+is in
+
+   X = A.i() * B;
+
+where 'i()' denotes inverse. Numerical analysts know it is inefficient to
+evaluate this expression by carrying out the inverse operation and then the
+multiply. Yet it is a convenient way of writing the instruction. It would be
+helpful if the program recognised this expression and carried out the more
+appropriate approach.
+
+I regard this interpretation of 'A.i() * B' as just providing a convenient
+notation. The objective is not to correct the errors of people who are unaware
+of the inefficiency of 'A.i() * B' if interpreted literally.
+
+There is a third reason for the two-stage evaluation of expressions and this
+is probably the most important one. In C++ it is quite hard to return an
+expression from a function such as ('*', '+' etc) without a copy. This is
+particularly the case when an assignment ('=') is involved. The mechanism
+described here provides one way for avoiding this in matrix expressions.
+
+To carry out this "intelligent" analysis of an instruction matrix expressions
+are evaluated in two stages. In the the first stage a tree representation of
+the expression is formed. For example '(A+B)*C' is represented by a tree
+
+'
+       *
+      / \
+     +   C
+    / \
+   A   B '
+
+Rather than adding 'A' and 'B' the '+' operator yields an object of a class
+"AddedMatrix" which is just a pair of pointers to 'A' and 'B'. Then the '*'
+operator yields a "MultipliedMatrix" which is a pair of pointers to the
+"AddedMatrix" and 'C'. The tree is examined for any simplifications and then
+evaluated recursively.
+
+Further possibilities not yet included are to recognise 'A.t()*A' and
+'A.t()+A' as symmetric or to improve the efficiency of evaluation of
+expressions like 'A+B+C', 'A*B*C', 'A*B.t()' ('t()' denotes transpose).
+
+One of the disadvantages of the two-stage approach is that the types of matrix
+expressions are determined at run-time. So the compiler will not detect errors
+of the type
+
+
+   Matrix M;
+   DiagonalMatrix D;
+   ....;
+   D = M;
+
+
+We don't allow conversions using '=' when information would be lost. Such
+errors will be detected when the statement is executed. 
+
+
+
+        8.7  How to overcome an explosion in number of operations
+        ===  === == ======== == ========= == ====== == ==========
+
+The package attempts to solve the problem of the large number of versions of
+the binary operations required when one has a variety of types.
+
+With "n" types of matrices the binary operations will each require "n"-squared
+separate algorithms. Some reduction in the number may be possible by carrying
+out conversions. However, the situation rapidly becomes impossible with more
+than 4 or 5 types. Doug Lea told me that it was possible to avoid this
+problem. I don't know what his solution is. Here's mine.
+
+Each matrix type includes routines for extracting individual rows or columns.
+I assume a row or column consists of a sequence of zeros, a sequence of stored
+values and then another sequence of zeros. Only a single algorithm is then
+required for each binary operation. The rows can be located very quickly since
+most of the matrices are stored row by row. Columns must be copied and so the
+access is somewhat slower. As far as possible my algorithms access the
+matrices by row.
+
+There is another approach. Each of the matrix types defined in this package
+can be set up so both rows and columns have their elements at equal intervals
+provided we are prepared to store the rows and columns in up to three chunks.
+With such an approach one could write a single "generic" algorithm for each of
+multiply and add. This would be a reasonable alternative to my approach.
+
+I provide several algorithms for operations like + . If one is adding two
+matrices of the same type then there is no need to access the individual rows
+or columns and a faster general algorithm is appropriate.
+
+Generally the method works well. However symmetric matrices are not always
+handled very efficiently (yet) since complete rows are not stored explicitly.
+
+The original version of the package did not use this access by row or column
+method and provided the multitude of algorithms for the combination of
+different matrix types. The code file length turned out to be just a little
+longer than the present one when providing the same facilities with 5 distinct
+types of matrices. It would have been very difficult to increase the number of
+matrix types in the original version. Apparently 4 to 5 types is about the
+break even point for switching to the approach adopted in the present package.
+
+However it must also be admitted that there is a substantial overhead in the
+approach adopted in the present package for small matrices. The test program
+developed for the original version of the package takes 30 to 50% longer to
+run with the current version (though there may be some other reasons for
+this). This is for matrices in the range 6x6 to 10x10.
+
+To try to improve the situation a little I do provide an ordinary matrix
+multiplication routine for the case when all the matrices involved are
+rectangular.
+
+
+        8.8  Destruction of temporaries
+        ===  =========== == ===========
+
+Versions before version 5 of newmat did not work correctly with Gnu C++
+(version 5 or earlier). This was because the tree structure used to represent
+a matrix expression was set up on the stack. This was fine for AT&T, Borland
+and Zortech C++.
+
+However early version Gnu C++ destroys temporary structures as soon as the
+function that accesses them finishes. The other compilers wait until the end
+of the current expression or current block. To overcome this problem, there is
+now an option to store the temporaries forming the tree structure on the heap
+(created with new) and to delete them explicitly. Activate the definition of
+TEMPS_DESTROYED_QUICKLY to set this option.
+
+In fact, I suggest this be the default option as, with it, the package uses
+less storage and runs faster. There still exist situations Gnu C++ will go
+wrong. These include statements like
+
+   A = X * Matrix(P * Q);
+
+   Real r = (A*B)(3,4);
+
+Neither of these kinds of statements will occur often in practice.
+
+Now that the C++ standards committee has said that temporary structures should
+not be destroyed before a statement finishes, my policy needs to be
+re-evaluated. Probably, I'll return to using the stack, because of the
+difficulty of managing exceptions with the heap version. 
+
+
+
+        8.9  A calculus of matrix types
+        ===  = ======== == ====== =====
+
+The program needs to be able to work out the class of the result of a matrix
+expression. This is to check that a conversion is legal or to determine the
+class of an intermediate result. To assist with this, a class MatrixType is
+defined. Operators '+', '-', '*', '>=' are defined to calculate the types of
+the results of expressions or to check that conversions are legal.
+
+Early versions of "newmat" stored the types of the results of operations in a
+table. So, for example, if you multiplied an UpperTriangularMatrix by a
+LowerTriangularMatrix, "newmat" would look up the table and see that the
+result was of type Matrix. With this approach the exploding [8.7] number of
+operations problem recurred although not as seriously as when code had to be
+written for each pair of types. But there was always the suspicion that
+somewhere, there was an error in one of those 9x9 tables, that would be very
+hard to find. And the problem would get worse as additional matrix types or
+operators were included.
+
+The present version of "newmat" solves the problem by assigning "attributes"
+such as "diagonal" or "band" or "upper triangular" to each matrix type. Which
+attributes a matrix type has, is stored as bits in an integer. As an example,
+the DiagonalMatrix type has the bits corresponding to "diagonal", "symmetric"
+and "band" equal to 1. By looking at the attributes of each of the operands of
+a binary operator, the program can work out the attributes of the result of
+the operation with simple bitwise operations. Hence it can deduce an
+appropriate type. The "symmetric" attribute is a minor problem because
+"symmetric" * "symmetric" does not yield "symmetric" unless both operands are
+"diagonal". But otherwise very simple code can be used to deduce the
+attributes of the result of a binary operation.
+
+Tables of the types resulting from the binary operators are output at the
+beginning of the test [2.7] program. 
+
+
+
+
+        8.10  Error handling
+        ====  ===== ========
+
+The library now does have a moderately graceful exit from errors. One can use
+either the simulated exceptions or the compiler supported exceptions. When
+newmat08 was released (in 1995), compiler exception handling in the compilers
+I had access to was unreliable. I recommended you used my simulated
+exceptions. Now (in 1997) compiler supported exceptions do seem to work on a
+variety of compilers - but not all compilers.
+
+The approach in the present library, attempting to simulate C++ exceptions, is
+not completely satisfactory, but seems a good interim solution for those who
+cannot use compiler supported exceptions. People who don't want exceptions in
+any shape or form, can set the option to exit the program if an exception is
+thrown.
+
+The exception mechanism cannot clean-up objects explicitly created by new.
+This must be explicitly carried out by the package writer or the package user.
+I have not yet done this completely with the present package so occasionally a
+little garbage may be left behind after an exception. I don't think this is a
+big problem, but it is one that needs fixing.
+
+
+
+        8.11  Sparse matrices
+        ====  ====== ========
+
+The library does not support sparse matrices.
+
+For sparse matrices there is going to be some kind of structure vector. It is
+going to have to be calculated for the results of expressions in much the same
+way that types are calculated. In addition, a whole new set of row and column
+operations would have to be written.
+
+Sparse matrices are important for people solving large sets of differential
+equations as well as being important for statistical and operational research
+applications.
+
+But there are packages being developed specifically for sparse matrices and
+these might present the best approach, at least where sparse matrices are the
+main interest.
+
+
+
+
+        8.12  Complex matrices
+        ====  ======= ========
+
+The package does not yet support matrices with complex elements. There are at
+least two approaches to including these. One is to have matrices with complex
+elements.
+
+This probably means making new versions of the basic row and column operations
+for Real*Complex, Complex*Complex, Complex*Real and similarly for + and -.
+This would be OK, except that if I also want to do this for sparse matrices,
+then when you put these together, the whole thing will get out of hand.
+
+The alternative is to represent a Complex matrix by a pair of Real matrices.
+One probably needs another level of decoding expressions but I think it might
+still be simpler than the first approach. But there is going to be a problem
+with accessing elements and it does not seem possible to solve this in an
+entirely satisfactory way.
+
+Complex matrices are used extensively by electrical engineers and physicists
+and really should be fully supported in a comprehensive package.
+
+You can simulate most complex operations by representing 'Z = X + iY' by
+
+    /  X   Y \
+    \ -Y   X / 
+
+Most matrix operations will simulate the corresponding complex operation, when
+applied to this matrix. But, of course, this matrix is twice as big as you
+would need with a genuine complex matrix library.
+
+
+
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat1.cpp b/Utilities/OSSIM/ossim_core/matrix/newmat1.cpp
new file mode 100644
index 0000000000..c1f81e3130
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat1.cpp
@@ -0,0 +1,199 @@
+//$$ newmat1.cpp   Matrix type functions
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+//#define WANT_STREAM
+
+#include "newmat.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,1); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+/************************* MatrixType functions *****************************/
+
+
+// Skew needs more work <<<<<<<<<
+
+// all operations to return MatrixTypes which correspond to valid types
+// of matrices.
+// Eg: if it has the Diagonal attribute, then it must also have
+// Upper, Lower, Band, Square and Symmetric.
+
+
+MatrixType MatrixType::operator*(const MatrixType& mt) const
+{
+   REPORT
+   int a = attribute & mt.attribute & ~(Symmetric | Skew);
+   a |= (a & Diagonal) * 63;                   // recognise diagonal
+   return MatrixType(a);
+}
+
+MatrixType MatrixType::SP(const MatrixType& mt) const
+// elementwise product
+// Lower, Upper, Diag, Band if only one is
+// Symmetric, Ones, Valid (and Real) if both are
+// Need to include Lower & Upper => Diagonal
+// Will need to include both Skew => Symmetric
+{
+   REPORT
+   int a = ((attribute | mt.attribute) & ~(Symmetric + Skew + Valid + Ones))
+      | (attribute & mt.attribute);
+   if ((a & Lower) != 0  &&  (a & Upper) != 0) a |= Diagonal;
+   if ((attribute & Skew) != 0)
+   {
+      if ((mt.attribute & Symmetric) != 0) a |= Skew;  
+      if ((mt.attribute & Skew) != 0) { a &= ~Skew; a |= Symmetric; }
+   }
+   else if ((mt.attribute & Skew) != 0 && (attribute & Symmetric) != 0)
+      a |= Skew;  
+   a |= (a & Diagonal) * 63;                   // recognise diagonal
+   return MatrixType(a);
+}
+
+MatrixType MatrixType::KP(const MatrixType& mt) const
+// Kronecker product
+// Lower, Upper, Diag, Symmetric, Band, Valid if both are
+// Band if LHS is band & other is square 
+// Ones is complicated so leave this out
+{
+   REPORT
+   int a = (attribute & mt.attribute)  & ~Ones;
+   if ((attribute & Band) != 0 && (mt.attribute & Square) != 0)
+      a |= Band;
+   //int a = ((attribute & mt.attribute) | (attribute & Band)) & ~Ones;
+
+   return MatrixType(a);
+}
+
+MatrixType MatrixType::i() const               // type of inverse
+{
+   REPORT
+   int a = attribute & ~(Band+LUDeco);
+   a |= (a & Diagonal) * 63;                   // recognise diagonal
+   return MatrixType(a);
+}
+
+MatrixType MatrixType::t() const
+// swap lower and upper attributes
+// assume Upper is in bit above Lower
+{
+   REPORT
+   int a = attribute;
+   a ^= (((a >> 1) ^ a) & Lower) * 3;
+   return MatrixType(a);
+}
+
+MatrixType MatrixType::MultRHS() const
+{
+   REPORT
+   // remove symmetric attribute unless diagonal
+   return (attribute >= Dg) ? attribute : (attribute & ~Symmetric);
+}
+
+// this is used for deciding type of multiplication
+bool Rectangular(MatrixType a, MatrixType b, MatrixType c)
+{
+   REPORT
+   return
+      ((a.attribute | b.attribute | c.attribute)
+      & ~(MatrixType::Valid | MatrixType::Square)) == 0;
+}
+
+const char* MatrixType::Value() const
+{
+// make a string with the name of matrix with the given attributes
+   switch (attribute)
+   {
+   case Valid:                              REPORT return "Rect ";
+   case Valid+Square:                       REPORT return "Squ  ";
+   case Valid+Symmetric+Square:             REPORT return "Sym  ";
+   case Valid+Skew+Square:                  REPORT return "Skew ";
+   case Valid+Band+Square:                  REPORT return "Band ";
+   case Valid+Symmetric+Band+Square:        REPORT return "SmBnd";
+   case Valid+Upper+Square:                 REPORT return "UT   ";
+   case Valid+Diagonal+Symmetric+Band+Upper+Lower+Square:
+                                            REPORT return "Diag ";
+   case Valid+Diagonal+Symmetric+Band+Upper+Lower+Ones+Square:
+                                            REPORT return "Ident";
+   case Valid+Band+Upper+Square:            REPORT return "UpBnd";
+   case Valid+Lower+Square:                 REPORT return "LT   ";
+   case Valid+Band+Lower+Square:            REPORT return "LwBnd";
+   default:
+      REPORT
+      if (!(attribute & Valid))             return "UnSp ";
+      if (attribute & LUDeco)
+         return (attribute & Band) ?     "BndLU" : "Crout";
+                                            return "?????";
+   }
+}
+
+
+GeneralMatrix* MatrixType::New(int nr, int nc, BaseMatrix* bm) const
+{
+// make a new matrix with the given attributes
+
+   Tracer tr("New"); GeneralMatrix* gm=0;   // initialised to keep gnu happy
+   switch (attribute)
+   {
+   case Valid:
+      REPORT
+      if (nc==1) { gm = new ColumnVector(nr); break; }
+      if (nr==1) { gm = new RowVector(nc); break; }
+      gm = new Matrix(nr, nc); break;
+
+   case Valid+Square:
+      REPORT
+      if (nc!=nr) { Throw(NotSquareException()); }
+      gm = new SquareMatrix(nr); break;
+
+   case Valid+Symmetric+Square:
+      REPORT gm = new SymmetricMatrix(nr); break;
+
+   case Valid+Band+Square:
+      {
+         REPORT
+         MatrixBandWidth bw = bm->BandWidth();
+         gm = new BandMatrix(nr,bw.lower,bw.upper); break;
+      }
+
+   case Valid+Symmetric+Band+Square:
+      REPORT gm = new SymmetricBandMatrix(nr,bm->BandWidth().lower); break;
+
+   case Valid+Upper+Square:
+      REPORT gm = new UpperTriangularMatrix(nr); break;
+
+   case Valid+Diagonal+Symmetric+Band+Upper+Lower+Square:
+      REPORT gm = new DiagonalMatrix(nr); break;
+
+   case Valid+Band+Upper+Square:
+      REPORT gm = new UpperBandMatrix(nr,bm->BandWidth().upper); break;
+
+   case Valid+Lower+Square:
+      REPORT gm = new LowerTriangularMatrix(nr); break;
+
+   case Valid+Band+Lower+Square:
+      REPORT gm = new LowerBandMatrix(nr,bm->BandWidth().lower); break;
+
+   case Valid+Diagonal+Symmetric+Band+Upper+Lower+Ones+Square:
+      REPORT gm = new IdentityMatrix(nr); break;
+
+   default:
+      Throw(ProgramException("Invalid matrix type"));
+   }
+   
+   MatrixErrorNoSpace(gm); gm->Protect(); return gm;
+}
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat2.cpp b/Utilities/OSSIM/ossim_core/matrix/newmat2.cpp
new file mode 100644
index 0000000000..ced949741f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat2.cpp
@@ -0,0 +1,641 @@
+//$$ newmat2.cpp      Matrix row and column operations
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#define WANT_MATH
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrc.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,2); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+//#define MONITOR(what,storage,store) { cout << what << " " << storage << " at " << (long)store << "\n"; }
+
+#define MONITOR(what,store,storage) {}
+
+/************************** Matrix Row/Col functions ************************/
+
+void MatrixRowCol::Add(const MatrixRowCol& mrc)
+{
+   // THIS += mrc
+   REPORT
+   int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
+   if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
+   if (l<=0) return;
+   Real* elx=data+(f-skip); Real* el=mrc.data+(f-mrc.skip);
+   while (l--) *elx++ += *el++;
+}
+
+void MatrixRowCol::AddScaled(const MatrixRowCol& mrc, Real x)
+{
+   REPORT
+   // THIS += (mrc * x)
+   int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
+   if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
+   if (l<=0) return;
+   Real* elx=data+(f-skip); Real* el=mrc.data+(f-mrc.skip);
+   while (l--) *elx++ += *el++ * x;
+}
+
+void MatrixRowCol::Sub(const MatrixRowCol& mrc)
+{
+   REPORT
+   // THIS -= mrc
+   int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
+   if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
+   if (l<=0) return;
+   Real* elx=data+(f-skip); Real* el=mrc.data+(f-mrc.skip);
+   while (l--) *elx++ -= *el++;
+}
+
+void MatrixRowCol::Inject(const MatrixRowCol& mrc)
+// copy stored elements only
+{
+   REPORT
+   int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
+   if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
+   if (l<=0) return;
+   Real* elx=data+(f-skip); Real* ely=mrc.data+(f-mrc.skip);
+   while (l--) *elx++ = *ely++;
+}
+
+Real DotProd(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
+{
+   REPORT                                         // not accessed
+   int f = mrc1.skip; int f2 = mrc2.skip;
+   int l = f + mrc1.storage; int l2 = f2 + mrc2.storage;
+   if (f < f2) f = f2; if (l > l2) l = l2; l -= f;
+   if (l<=0) return 0.0;
+
+   Real* el1=mrc1.data+(f-mrc1.skip); Real* el2=mrc2.data+(f-mrc2.skip);
+   Real sum = 0.0;
+   while (l--) sum += *el1++ * *el2++;
+   return sum;
+}
+
+void MatrixRowCol::Add(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
+{
+   // THIS = mrc1 + mrc2
+   int f = skip; int l = skip + storage;
+   int f1 = mrc1.skip; int l1 = f1 + mrc1.storage;
+   if (f1<f) f1=f; if (l1>l) l1=l;
+   int f2 = mrc2.skip; int l2 = f2 + mrc2.storage;
+   if (f2<f) f2=f; if (l2>l) l2=l;
+   Real* el = data + (f-skip);
+   Real* el1 = mrc1.data+(f1-mrc1.skip); Real* el2 = mrc2.data+(f2-mrc2.skip);
+   if (f1<f2)
+   {
+      int i = f1-f; while (i--) *el++ = 0.0;
+      if (l1<=f2)                              // disjoint
+      {
+         REPORT                                // not accessed
+         i = l1-f1;     while (i--) *el++ = *el1++;
+         i = f2-l1;     while (i--) *el++ = 0.0;
+         i = l2-f2;     while (i--) *el++ = *el2++;
+         i = l-l2;      while (i--) *el++ = 0.0;
+      }
+      else
+      {
+         i = f2-f1;    while (i--) *el++ = *el1++;
+         if (l1<=l2)
+         {
+            REPORT
+            i = l1-f2; while (i--) *el++ = *el1++ + *el2++;
+            i = l2-l1; while (i--) *el++ = *el2++;
+            i = l-l2;  while (i--) *el++ = 0.0;
+         }
+         else
+         {
+            REPORT
+            i = l2-f2; while (i--) *el++ = *el1++ + *el2++;
+            i = l1-l2; while (i--) *el++ = *el1++;
+            i = l-l1;  while (i--) *el++ = 0.0;
+         }
+      }
+   }
+   else
+   {
+      int i = f2-f; while (i--) *el++ = 0.0;
+      if (l2<=f1)                              // disjoint
+      {
+         REPORT                                // not accessed
+         i = l2-f2;     while (i--) *el++ = *el2++;
+         i = f1-l2;     while (i--) *el++ = 0.0;
+         i = l1-f1;     while (i--) *el++ = *el1++;
+         i = l-l1;      while (i--) *el++ = 0.0;
+      }
+      else
+      {
+         i = f1-f2;    while (i--) *el++ = *el2++;
+         if (l2<=l1)
+         {
+            REPORT
+            i = l2-f1; while (i--) *el++ = *el1++ + *el2++;
+            i = l1-l2; while (i--) *el++ = *el1++;
+            i = l-l1;  while (i--) *el++ = 0.0;
+         }
+         else
+         {
+            REPORT
+            i = l1-f1; while (i--) *el++ = *el1++ + *el2++;
+            i = l2-l1; while (i--) *el++ = *el2++;
+            i = l-l2;  while (i--) *el++ = 0.0;
+         }
+      }
+   }
+}
+
+void MatrixRowCol::Sub(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
+{
+   // THIS = mrc1 - mrc2
+   int f = skip; int l = skip + storage;
+   int f1 = mrc1.skip; int l1 = f1 + mrc1.storage;
+   if (f1<f) f1=f; if (l1>l) l1=l;
+   int f2 = mrc2.skip; int l2 = f2 + mrc2.storage;
+   if (f2<f) f2=f; if (l2>l) l2=l;
+   Real* el = data + (f-skip);
+   Real* el1 = mrc1.data+(f1-mrc1.skip); Real* el2 = mrc2.data+(f2-mrc2.skip);
+   if (f1<f2)
+   {
+      int i = f1-f; while (i--) *el++ = 0.0;
+      if (l1<=f2)                              // disjoint
+      {
+         REPORT                                // not accessed
+         i = l1-f1;     while (i--) *el++ = *el1++;
+         i = f2-l1;     while (i--) *el++ = 0.0;
+         i = l2-f2;     while (i--) *el++ = - *el2++;
+         i = l-l2;      while (i--) *el++ = 0.0;
+      }
+      else
+      {
+         i = f2-f1;    while (i--) *el++ = *el1++;
+         if (l1<=l2)
+         {
+            REPORT
+            i = l1-f2; while (i--) *el++ = *el1++ - *el2++;
+            i = l2-l1; while (i--) *el++ = - *el2++;
+            i = l-l2;  while (i--) *el++ = 0.0;
+         }
+         else
+         {
+            REPORT
+            i = l2-f2; while (i--) *el++ = *el1++ - *el2++;
+            i = l1-l2; while (i--) *el++ = *el1++;
+            i = l-l1;  while (i--) *el++ = 0.0;
+         }
+      }
+   }
+   else
+   {
+      int i = f2-f; while (i--) *el++ = 0.0;
+      if (l2<=f1)                              // disjoint
+      {
+         REPORT                                // not accessed
+         i = l2-f2;     while (i--) *el++ = - *el2++;
+         i = f1-l2;     while (i--) *el++ = 0.0;
+         i = l1-f1;     while (i--) *el++ = *el1++;
+         i = l-l1;      while (i--) *el++ = 0.0;
+      }
+      else
+      {
+         i = f1-f2;    while (i--) *el++ = - *el2++;
+         if (l2<=l1)
+         {
+            REPORT
+            i = l2-f1; while (i--) *el++ = *el1++ - *el2++;
+            i = l1-l2; while (i--) *el++ = *el1++;
+            i = l-l1;  while (i--) *el++ = 0.0;
+         }
+         else
+         {
+            REPORT
+            i = l1-f1; while (i--) *el++ = *el1++ - *el2++;
+            i = l2-l1; while (i--) *el++ = - *el2++;
+            i = l-l2;  while (i--) *el++ = 0.0;
+         }
+      }
+   }
+}
+
+
+void MatrixRowCol::Add(const MatrixRowCol& mrc1, Real x)
+{
+   // THIS = mrc1 + x
+   REPORT
+   if (!storage) return;
+   int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
+   if (f < skip) { f = skip; if (l < f) l = f; }
+   if (l > lx) { l = lx; if (f > lx) f = lx; }
+
+   Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
+
+   int l1 = f-skip;  while (l1--) *elx++ = x;
+       l1 = l-f;     while (l1--) *elx++ = *ely++ + x;
+       lx -= l;      while (lx--) *elx++ = x;
+}
+
+void MatrixRowCol::NegAdd(const MatrixRowCol& mrc1, Real x)
+{
+   // THIS = x - mrc1
+   REPORT
+   if (!storage) return;
+   int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
+   if (f < skip) { f = skip; if (l < f) l = f; }
+   if (l > lx) { l = lx; if (f > lx) f = lx; }
+
+   Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
+
+   int l1 = f-skip;  while (l1--) *elx++ = x;
+       l1 = l-f;     while (l1--) *elx++ = x - *ely++;
+       lx -= l;      while (lx--) *elx++ = x;
+}
+
+void MatrixRowCol::RevSub(const MatrixRowCol& mrc1)
+{
+   // THIS = mrc - THIS
+   REPORT
+   if (!storage) return;
+   int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
+   if (f < skip) { f = skip; if (l < f) l = f; }
+   if (l > lx) { l = lx; if (f > lx) f = lx; }
+
+   Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
+
+   int l1 = f-skip;  while (l1--) { *elx = - *elx; elx++; }
+       l1 = l-f;     while (l1--) { *elx = *ely++ - *elx; elx++; }
+       lx -= l;      while (lx--) { *elx = - *elx; elx++; }
+}
+
+void MatrixRowCol::ConCat(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
+{
+   // THIS = mrc1 | mrc2
+   REPORT
+   int f1 = mrc1.skip; int l1 = f1 + mrc1.storage; int lx = skip + storage;
+   if (f1 < skip) { f1 = skip; if (l1 < f1) l1 = f1; }
+   if (l1 > lx) { l1 = lx; if (f1 > lx) f1 = lx; }
+
+   Real* elx = data;
+
+   int i = f1-skip;  while (i--) *elx++ =0.0;
+   i = l1-f1;
+   if (i)                       // in case f1 would take ely out of range
+      { Real* ely = mrc1.data+(f1-mrc1.skip);  while (i--) *elx++ = *ely++; }
+
+   int f2 = mrc2.skip; int l2 = f2 + mrc2.storage; i = mrc1.length;
+   int skipx = l1 - i; lx -= i; // addresses rel to second seg, maybe -ve
+   if (f2 < skipx) { f2 = skipx; if (l2 < f2) l2 = f2; }
+   if (l2 > lx) { l2 = lx; if (f2 > lx) f2 = lx; }
+
+   i = f2-skipx; while (i--) *elx++ = 0.0;
+   i = l2-f2;
+   if (i)                       // in case f2 would take ely out of range
+      { Real* ely = mrc2.data+(f2-mrc2.skip); while (i--) *elx++ = *ely++; }
+   lx -= l2;     while (lx--) *elx++ = 0.0;
+}
+
+void MatrixRowCol::Multiply(const MatrixRowCol& mrc1)
+// element by element multiply into
+{
+   REPORT
+   if (!storage) return;
+   int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
+   if (f < skip) { f = skip; if (l < f) l = f; }
+   if (l > lx) { l = lx; if (f > lx) f = lx; }
+
+   Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
+
+   int l1 = f-skip;  while (l1--) *elx++ = 0;
+       l1 = l-f;     while (l1--) *elx++ *= *ely++;
+       lx -= l;      while (lx--) *elx++ = 0;
+}
+
+void MatrixRowCol::Multiply(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
+// element by element multiply
+{
+   int f = skip; int l = skip + storage;
+   int f1 = mrc1.skip; int l1 = f1 + mrc1.storage;
+   if (f1<f) f1=f; if (l1>l) l1=l;
+   int f2 = mrc2.skip; int l2 = f2 + mrc2.storage;
+   if (f2<f) f2=f; if (l2>l) l2=l;
+   Real* el = data + (f-skip); int i;
+   if (f1<f2) f1 = f2; if (l1>l2) l1 = l2;
+   if (l1<=f1) { REPORT i = l-f; while (i--) *el++ = 0.0; }  // disjoint
+   else
+   {
+      REPORT
+      Real* el1 = mrc1.data+(f1-mrc1.skip);
+      Real* el2 = mrc2.data+(f1-mrc2.skip);
+      i = f1-f ;    while (i--) *el++ = 0.0;
+      i = l1-f1;    while (i--) *el++ = *el1++ * *el2++;
+      i = l-l1;     while (i--) *el++ = 0.0;
+   }
+}
+
+void MatrixRowCol::KP(const MatrixRowCol& mrc1, const MatrixRowCol& mrc2)
+// row for Kronecker product
+{
+   int f = skip; int s = storage; Real* el = data; int i;
+
+   i = mrc1.skip * mrc2.length;
+   if (i > f)
+   {
+      i -= f; f = 0; if (i > s) { i = s; s = 0; }  else s -= i;
+      while (i--) *el++ = 0.0;
+      if (s == 0) return;
+   }
+   else f -= i;
+
+   i = mrc1.storage; Real* el1 = mrc1.data;
+   int mrc2_skip = mrc2.skip; int mrc2_storage = mrc2.storage;
+   int mrc2_length = mrc2.length;
+   int mrc2_remain = mrc2_length - mrc2_skip - mrc2_storage;
+   while (i--)
+   {
+      int j; Real* el2 = mrc2.data; Real vel1 = *el1;
+      if (f == 0 && mrc2_length <= s)
+      {
+         j = mrc2_skip; s -= j;    while (j--) *el++ = 0.0;
+         j = mrc2_storage; s -= j; while (j--) *el++ = vel1 * *el2++;
+         j = mrc2_remain; s -= j;  while (j--) *el++ = 0.0;
+      }
+      else if (f >= mrc2_length) f -= mrc2_length;
+      else
+      {
+         j = mrc2_skip;
+         if (j > f)
+         {
+            j -= f; f = 0; if (j > s) { j = s; s = 0; } else s -= j;
+            while (j--) *el++ = 0.0;
+         }
+         else f -= j;
+
+         j = mrc2_storage;
+         if (j > f)
+         {
+            j -= f; el2 += f; f = 0; if (j > s) { j = s; s = 0; } else s -= j;
+            while (j--) *el++ = vel1 * *el2++;
+         }
+         else f -= j;
+
+         j = mrc2_remain;
+         if (j > f)
+         {
+            j -= f; f = 0; if (j > s) { j = s; s = 0; } else s -= j;
+            while (j--) *el++ = 0.0;
+         }
+         else f -= j;
+      }
+      if (s == 0) return;
+      ++el1;
+   }
+
+   i = (mrc1.length - mrc1.skip - mrc1.storage) * mrc2.length;
+   if (i > f)
+   {
+      i -= f; if (i > s) i = s;
+      while (i--) *el++ = 0.0;
+   }
+}
+
+
+void MatrixRowCol::Copy(const MatrixRowCol& mrc1)
+{
+   // THIS = mrc1
+   REPORT
+   if (!storage) return;
+   int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
+   if (f < skip) { f = skip; if (l < f) l = f; }
+   if (l > lx) { l = lx; if (f > lx) f = lx; }
+
+   Real* elx = data; Real* ely = 0;
+
+   if (l-f) ely = mrc1.data+(f-mrc1.skip);
+
+   int l1 = f-skip;  while (l1--) *elx++ = 0.0;
+       l1 = l-f;     while (l1--) *elx++ = *ely++;
+       lx -= l;      while (lx--) *elx++ = 0.0;
+}
+
+void MatrixRowCol::CopyCheck(const MatrixRowCol& mrc1)
+// Throw an exception if this would lead to a loss of data
+{
+   REPORT
+   if (!storage) return;
+   int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
+   if (f < skip || l > lx) Throw(ProgramException("Illegal Conversion"));
+
+   Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
+
+   int l1 = f-skip;  while (l1--) *elx++ = 0.0;
+       l1 = l-f;     while (l1--) *elx++ = *ely++;
+       lx -= l;      while (lx--) *elx++ = 0.0;
+}
+
+void MatrixRowCol::Check(const MatrixRowCol& mrc1)
+// Throw an exception if +=, -=, copy etc would lead to a loss of data
+{
+   REPORT
+   int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
+   if (f < skip || l > lx) Throw(ProgramException("Illegal Conversion"));
+}
+
+void MatrixRowCol::Check()
+// Throw an exception if +=, -= of constant would lead to a loss of data
+// that is: check full row is present
+// may not be appropriate for symmetric matrices
+{
+   REPORT
+   if (skip!=0 || storage!=length)
+      Throw(ProgramException("Illegal Conversion"));
+}
+
+void MatrixRowCol::Negate(const MatrixRowCol& mrc1)
+{
+   // THIS = -mrc1
+   REPORT
+   if (!storage) return;
+   int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
+   if (f < skip) { f = skip; if (l < f) l = f; }
+   if (l > lx) { l = lx; if (f > lx) f = lx; }
+
+   Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
+
+   int l1 = f-skip;  while (l1--) *elx++ = 0.0;
+       l1 = l-f;     while (l1--) *elx++ = - *ely++;
+       lx -= l;      while (lx--) *elx++ = 0.0;
+}
+
+void MatrixRowCol::Multiply(const MatrixRowCol& mrc1, Real s)
+{
+   // THIS = mrc1 * s
+   REPORT
+   if (!storage) return;
+   int f = mrc1.skip; int l = f + mrc1.storage; int lx = skip + storage;
+   if (f < skip) { f = skip; if (l < f) l = f; }
+   if (l > lx) { l = lx; if (f > lx) f = lx; }
+
+   Real* elx = data; Real* ely = mrc1.data+(f-mrc1.skip);
+
+   int l1 = f-skip;  while (l1--) *elx++ = 0.0;
+       l1 = l-f;     while (l1--) *elx++ = *ely++ * s;
+       lx -= l;      while (lx--) *elx++ = 0.0;
+}
+
+void DiagonalMatrix::Solver(MatrixColX& mrc, const MatrixColX& mrc1)
+{
+   // mrc = mrc / mrc1   (elementwise)
+   REPORT
+   int f = mrc1.skip; int f0 = mrc.skip;
+   int l = f + mrc1.storage; int lx = f0 + mrc.storage;
+   if (f < f0) { f = f0; if (l < f) l = f; }
+   if (l > lx) { l = lx; if (f > lx) f = lx; }
+
+   Real* elx = mrc.data; Real* eld = store+f;
+
+   int l1 = f-f0;    while (l1--) *elx++ = 0.0;
+       l1 = l-f;     while (l1--) *elx++ /= *eld++;
+       lx -= l;      while (lx--) *elx++ = 0.0;
+   // Solver makes sure input and output point to same memory
+}
+
+void IdentityMatrix::Solver(MatrixColX& mrc, const MatrixColX& mrc1)
+{
+   // mrc = mrc / mrc1   (elementwise)
+   REPORT
+   int f = mrc1.skip; int f0 = mrc.skip;
+   int l = f + mrc1.storage; int lx = f0 + mrc.storage;
+   if (f < f0) { f = f0; if (l < f) l = f; }
+   if (l > lx) { l = lx; if (f > lx) f = lx; }
+
+   Real* elx = mrc.data; Real eldv = *store;
+
+   int l1 = f-f0;    while (l1--) *elx++ = 0.0;
+       l1 = l-f;     while (l1--) *elx++ /= eldv;
+       lx -= l;      while (lx--) *elx++ = 0.0;
+   // Solver makes sure input and output point to same memory
+}
+
+void MatrixRowCol::Copy(const Real*& r)
+{
+   // THIS = *r
+   REPORT
+   Real* elx = data; const Real* ely = r+skip; r += length;
+   int l = storage; while (l--) *elx++ = *ely++;
+}
+
+void MatrixRowCol::Copy(const int*& r)
+{
+   // THIS = *r
+   REPORT
+   Real* elx = data; const int* ely = r+skip; r += length;
+   int l = storage; while (l--) *elx++ = *ely++;
+}
+
+void MatrixRowCol::Copy(Real r)
+{
+   // THIS = r
+   REPORT  Real* elx = data; int l = storage; while (l--) *elx++ = r;
+}
+
+void MatrixRowCol::Zero()
+{
+   // THIS = 0
+   REPORT  Real* elx = data; int l = storage; while (l--) *elx++ = 0;
+}
+
+void MatrixRowCol::Multiply(Real r)
+{
+   // THIS *= r
+   REPORT  Real* elx = data; int l = storage; while (l--) *elx++ *= r;
+}
+
+void MatrixRowCol::Add(Real r)
+{
+   // THIS += r
+   REPORT
+   Real* elx = data; int l = storage; while (l--) *elx++ += r;
+}
+
+Real MatrixRowCol::SumAbsoluteValue()
+{
+   REPORT
+   Real sum = 0.0; Real* elx = data; int l = storage;
+   while (l--) sum += fabs(*elx++);
+   return sum;
+}
+
+// max absolute value of r and elements of row/col
+// we use <= or >= in all of these so we are sure of getting
+// r reset at least once.
+Real MatrixRowCol::MaximumAbsoluteValue1(Real r, int& i)
+{
+   REPORT
+   Real* elx = data; int l = storage; int li = -1;
+   while (l--) { Real f = fabs(*elx++); if (r <= f) { r = f; li = l; } }
+   i = (li >= 0) ? storage - li + skip : 0;
+   return r;
+}
+
+// min absolute value of r and elements of row/col
+Real MatrixRowCol::MinimumAbsoluteValue1(Real r, int& i)
+{
+   REPORT
+   Real* elx = data; int l = storage; int li = -1;
+   while (l--) { Real f = fabs(*elx++); if (r >= f) { r = f; li = l; } }
+   i = (li >= 0) ? storage - li + skip : 0;
+   return r;
+}
+
+// max value of r and elements of row/col
+Real MatrixRowCol::Maximum1(Real r, int& i)
+{
+   REPORT
+   Real* elx = data; int l = storage; int li = -1;
+   while (l--) { Real f = *elx++; if (r <= f) { r = f; li = l; } }
+   i = (li >= 0) ? storage - li + skip : 0;
+   return r;
+}
+
+// min value of r and elements of row/col
+Real MatrixRowCol::Minimum1(Real r, int& i)
+{
+   REPORT
+   Real* elx = data; int l = storage; int li = -1;
+   while (l--) { Real f = *elx++; if (r >= f) { r = f; li = l; } }
+   i = (li >= 0) ? storage - li + skip : 0;
+   return r;
+}
+
+Real MatrixRowCol::Sum()
+{
+   REPORT
+   Real sum = 0.0; Real* elx = data; int l = storage;
+   while (l--) sum += *elx++;
+   return sum;
+}
+
+void MatrixRowCol::SubRowCol(MatrixRowCol& mrc, int skip1, int l1) const
+{
+   mrc.length = l1;  int d = skip - skip1;
+   if (d<0) { mrc.skip = 0; mrc.data = data - d; }
+   else  { mrc.skip = d; mrc.data = data; }
+   d = skip + storage - skip1;
+   d = ((l1 < d) ? l1 : d) - mrc.skip;  mrc.storage = (d < 0) ? 0 : d;
+   mrc.cw = 0;
+}
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat3.cpp b/Utilities/OSSIM/ossim_core/matrix/newmat3.cpp
new file mode 100644
index 0000000000..7bc2d4f8a0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat3.cpp
@@ -0,0 +1,842 @@
+//$$ newmat3.cpp        Matrix get and restore rows and columns
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+//#define WANT_STREAM
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrc.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,3); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+//#define MONITOR(what,storage,store)
+//   { cout << what << " " << storage << " at " << (long)store << "\n"; }
+
+#define MONITOR(what,store,storage) {}
+
+
+// Control bits codes for GetRow, GetCol, RestoreRow, RestoreCol
+//
+// LoadOnEntry:
+//    Load data into MatrixRow or Col dummy array under GetRow or GetCol
+// StoreOnExit:
+//    Restore data to original matrix under RestoreRow or RestoreCol
+// DirectPart:
+//    Load or restore only part directly stored; must be set with StoreOnExit
+//    Still have decide how to handle this with symmetric
+// StoreHere:
+//    used in columns only - store data at supplied storage address;
+//    used for GetCol, NextCol & RestoreCol. No need to fill out zeros
+// HaveStore:
+//    dummy array has been assigned (internal use only).
+
+// For symmetric matrices, treat columns as rows unless StoreHere is set;
+// then stick to columns as this will give better performance for doing
+// inverses
+
+// How components are used:
+
+// Use rows wherever possible in preference to columns
+
+// Columns without StoreHere are used in in-exact transpose, sum column,
+// multiply a column vector, and maybe in future access to column,
+// additional multiply functions, add transpose
+
+// Columns with StoreHere are used in exact transpose (not symmetric matrices
+// or vectors, load only)
+
+// Columns with MatrixColX (Store to full column) are used in inverse and solve
+
+// Functions required for each matrix class
+
+// GetRow(MatrixRowCol& mrc)
+// GetCol(MatrixRowCol& mrc)
+// GetCol(MatrixColX& mrc)
+// RestoreRow(MatrixRowCol& mrc)
+// RestoreCol(MatrixRowCol& mrc)
+// RestoreCol(MatrixColX& mrc)
+// NextRow(MatrixRowCol& mrc)
+// NextCol(MatrixRowCol& mrc)
+// NextCol(MatrixColX& mrc)
+
+// The Restore routines assume StoreOnExit has already been checked
+// Defaults for the Next routines are given below
+// Assume cannot have both !DirectPart && StoreHere for MatrixRowCol routines
+
+
+// Default NextRow and NextCol:
+// will work as a default but need to override NextRow for efficiency
+
+void GeneralMatrix::NextRow(MatrixRowCol& mrc)
+{
+   REPORT
+   if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreRow(mrc); }
+   mrc.rowcol++;
+   if (mrc.rowcol<nrows) { REPORT this->GetRow(mrc); }
+   else { REPORT mrc.cw -= StoreOnExit; }
+}
+
+void GeneralMatrix::NextCol(MatrixRowCol& mrc)
+{
+   REPORT                                                // 423
+   if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); }
+   mrc.rowcol++;
+   if (mrc.rowcol<ncols) { REPORT this->GetCol(mrc); }
+   else { REPORT mrc.cw -= StoreOnExit; }
+}
+
+void GeneralMatrix::NextCol(MatrixColX& mrc)
+{
+   REPORT                                                // 423
+   if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); }
+   mrc.rowcol++;
+   if (mrc.rowcol<ncols) { REPORT this->GetCol(mrc); }
+   else { REPORT mrc.cw -= StoreOnExit; }
+}
+
+
+// routines for matrix
+
+void Matrix::GetRow(MatrixRowCol& mrc)
+{
+   REPORT
+   mrc.skip=0; mrc.storage=mrc.length=ncols; mrc.data=store+mrc.rowcol*ncols;
+}
+
+
+void Matrix::GetCol(MatrixRowCol& mrc)
+{
+   REPORT
+   mrc.skip=0; mrc.storage=mrc.length=nrows;
+   if ( ncols==1 && !(mrc.cw*StoreHere) )      // ColumnVector
+      { REPORT mrc.data=store; }
+   else
+   {
+      Real* ColCopy;
+      if ( !(mrc.cw*(HaveStore+StoreHere)) )
+      {
+         REPORT
+         ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy);
+         MONITOR_REAL_NEW("Make (MatGetCol)",nrows,ColCopy)
+         mrc.data = ColCopy; mrc.cw += HaveStore;
+      }
+      else { REPORT ColCopy = mrc.data; }
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT
+         Real* Mstore = store+mrc.rowcol; int i=nrows;
+         //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
+         if (i) for (;;)
+            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
+      }
+   }
+}
+
+void Matrix::GetCol(MatrixColX& mrc)
+{
+   REPORT
+   mrc.skip=0; mrc.storage=nrows; mrc.length=nrows;
+   if (+(mrc.cw*LoadOnEntry))
+   {
+      REPORT  Real* ColCopy = mrc.data;
+      Real* Mstore = store+mrc.rowcol; int i=nrows;
+      //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
+      if (i) for (;;)
+          { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
+   }
+}
+
+void Matrix::RestoreCol(MatrixRowCol& mrc)
+{
+   // always check StoreOnExit before calling RestoreCol
+   REPORT                                   // 429
+   if (+(mrc.cw*HaveStore))
+   {
+      REPORT                                // 426
+      Real* Mstore = store+mrc.rowcol; int i=nrows;
+      Real* Cstore = mrc.data;
+      // while (i--) { *Mstore = *Cstore++; Mstore+=ncols; }
+      if (i) for (;;)
+          { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols; }
+   }
+}
+
+void Matrix::RestoreCol(MatrixColX& mrc)
+{
+   REPORT
+   Real* Mstore = store+mrc.rowcol; int i=nrows; Real* Cstore = mrc.data;
+   // while (i--) { *Mstore = *Cstore++; Mstore+=ncols; }
+   if (i) for (;;)
+      { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols; }
+}
+
+void Matrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrMat(); }  // 1808
+
+void Matrix::NextCol(MatrixRowCol& mrc)
+{
+   REPORT                                        // 632
+   if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); }
+   mrc.rowcol++;
+   if (mrc.rowcol<ncols)
+   {
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT
+         Real* ColCopy = mrc.data;
+         Real* Mstore = store+mrc.rowcol; int i=nrows;
+         //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
+         if (i) for (;;)
+            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
+      }
+   }
+   else { REPORT mrc.cw -= StoreOnExit; }
+}
+
+void Matrix::NextCol(MatrixColX& mrc)
+{
+   REPORT
+   if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); }
+   mrc.rowcol++;
+   if (mrc.rowcol<ncols)
+   {
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT
+         Real* ColCopy = mrc.data;
+         Real* Mstore = store+mrc.rowcol; int i=nrows;
+         // while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
+         if (i) for (;;)
+            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
+      }
+   }
+   else { REPORT mrc.cw -= StoreOnExit; }
+}
+
+// routines for diagonal matrix
+
+void DiagonalMatrix::GetRow(MatrixRowCol& mrc)
+{
+   REPORT
+   mrc.skip=mrc.rowcol; mrc.storage=1;
+   mrc.data=store+mrc.skip; mrc.length=ncols;
+}
+
+void DiagonalMatrix::GetCol(MatrixRowCol& mrc)
+{
+   REPORT
+   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
+   if (+(mrc.cw*StoreHere))              // should not happen
+      Throw(InternalException("DiagonalMatrix::GetCol(MatrixRowCol&)"));
+   else  { REPORT mrc.data=store+mrc.skip; }
+                                                      // not accessed
+}
+
+void DiagonalMatrix::GetCol(MatrixColX& mrc)
+{
+   REPORT
+   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
+   mrc.data = mrc.store+mrc.skip;
+   *(mrc.data)=*(store+mrc.skip);
+}
+
+void DiagonalMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); }
+						      // 800
+
+void DiagonalMatrix::NextCol(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); }
+                        // not accessed
+
+void DiagonalMatrix::NextCol(MatrixColX& mrc)
+{
+   REPORT
+   if (+(mrc.cw*StoreOnExit))
+      { REPORT *(store+mrc.rowcol)=*(mrc.data); }
+   mrc.IncrDiag();
+   int t1 = +(mrc.cw*LoadOnEntry);
+   if (t1 && mrc.rowcol < ncols)
+      { REPORT *(mrc.data)=*(store+mrc.rowcol); }
+}
+
+// routines for upper triangular matrix
+
+void UpperTriangularMatrix::GetRow(MatrixRowCol& mrc)
+{
+   REPORT
+   int row = mrc.rowcol; mrc.skip=row; mrc.length=ncols;
+   mrc.storage=ncols-row; mrc.data=store+(row*(2*ncols-row+1))/2;
+}
+
+
+void UpperTriangularMatrix::GetCol(MatrixRowCol& mrc)
+{
+   REPORT
+   mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i;
+   mrc.length=nrows; Real* ColCopy;
+   if ( !(mrc.cw*(StoreHere+HaveStore)) )
+   {
+      REPORT                                              // not accessed
+      ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy);
+      MONITOR_REAL_NEW("Make (UT GetCol)",nrows,ColCopy)
+      mrc.data = ColCopy; mrc.cw += HaveStore;
+   }
+   else { REPORT ColCopy = mrc.data; }
+   if (+(mrc.cw*LoadOnEntry))
+   {
+      REPORT
+      Real* Mstore = store+mrc.rowcol; int j = ncols;
+      // while (i--) { *ColCopy++ = *Mstore; Mstore += --j; }
+      if (i) for (;;)
+         { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; }
+   }
+}
+
+void UpperTriangularMatrix::GetCol(MatrixColX& mrc)
+{
+   REPORT
+   mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i;
+   mrc.length=nrows;
+   if (+(mrc.cw*LoadOnEntry))
+   {
+      REPORT
+      Real* ColCopy = mrc.data;
+      Real* Mstore = store+mrc.rowcol; int j = ncols;
+      // while (i--) { *ColCopy++ = *Mstore; Mstore += --j; }
+      if (i) for (;;)
+         { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; }
+   }
+}
+
+void UpperTriangularMatrix::RestoreCol(MatrixRowCol& mrc)
+{
+  REPORT
+  Real* Mstore = store+mrc.rowcol; int i=mrc.rowcol+1; int j = ncols;
+  Real* Cstore = mrc.data;
+  // while (i--) { *Mstore = *Cstore++; Mstore += --j; }
+  if (i) for (;;)
+     { *Mstore = *Cstore++; if (!(--i)) break; Mstore += --j; }
+}
+
+void UpperTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrUT(); }
+						      // 722
+
+// routines for lower triangular matrix
+
+void LowerTriangularMatrix::GetRow(MatrixRowCol& mrc)
+{
+   REPORT
+   int row=mrc.rowcol; mrc.skip=0; mrc.storage=row+1; mrc.length=ncols;
+   mrc.data=store+(row*(row+1))/2;
+}
+
+void LowerTriangularMatrix::GetCol(MatrixRowCol& mrc)
+{
+   REPORT
+   int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows;
+   int i=nrows-col; mrc.storage=i; Real* ColCopy;
+   if ( +(mrc.cw*(StoreHere+HaveStore)) )
+      { REPORT  ColCopy = mrc.data; }
+   else
+   {
+      REPORT                                            // not accessed
+      ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy);
+      MONITOR_REAL_NEW("Make (LT GetCol)",nrows,ColCopy)
+      mrc.cw += HaveStore; mrc.data = ColCopy;
+   }
+
+   if (+(mrc.cw*LoadOnEntry))
+   {
+      REPORT
+      Real* Mstore = store+(col*(col+3))/2;
+      // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
+      if (i) for (;;)
+         { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
+   }
+}
+
+void LowerTriangularMatrix::GetCol(MatrixColX& mrc)
+{
+   REPORT
+   int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows;
+   int i=nrows-col; mrc.storage=i; mrc.data = mrc.store + col;
+
+   if (+(mrc.cw*LoadOnEntry))
+   {
+      REPORT  Real* ColCopy = mrc.data;
+      Real* Mstore = store+(col*(col+3))/2;
+      // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
+      if (i) for (;;)
+         { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
+   }
+}
+
+void LowerTriangularMatrix::RestoreCol(MatrixRowCol& mrc)
+{
+   REPORT
+   int col=mrc.rowcol; Real* Cstore = mrc.data;
+   Real* Mstore = store+(col*(col+3))/2; int i=nrows-col;
+   //while (i--) { *Mstore = *Cstore++; Mstore += ++col; }
+   if (i) for (;;)
+      { *Mstore = *Cstore++; if (!(--i)) break; Mstore += ++col; }
+}
+
+void LowerTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrLT(); }
+					                 //712
+
+// routines for symmetric matrix
+
+void SymmetricMatrix::GetRow(MatrixRowCol& mrc)
+{
+   REPORT                                                //571
+   mrc.skip=0; int row=mrc.rowcol; mrc.length=ncols;
+   if (+(mrc.cw*DirectPart))
+      { REPORT mrc.storage=row+1; mrc.data=store+(row*(row+1))/2; }
+   else
+   {
+      // do not allow StoreOnExit and !DirectPart
+      if (+(mrc.cw*StoreOnExit))
+         Throw(InternalException("SymmetricMatrix::GetRow(MatrixRowCol&)"));
+      mrc.storage=ncols; Real* RowCopy;
+      if (!(mrc.cw*HaveStore))
+      {
+         REPORT
+         RowCopy = new Real [ncols]; MatrixErrorNoSpace(RowCopy);
+         MONITOR_REAL_NEW("Make (SymGetRow)",ncols,RowCopy)
+         mrc.cw += HaveStore; mrc.data = RowCopy;
+      }
+      else { REPORT RowCopy = mrc.data; }
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT                                         // 544
+         Real* Mstore = store+(row*(row+1))/2; int i = row;
+         while (i--) *RowCopy++ = *Mstore++;
+         i = ncols-row;
+         // while (i--) { *RowCopy++ = *Mstore; Mstore += ++row; }
+         if (i) for (;;)
+            { *RowCopy++ = *Mstore; if (!(--i)) break; Mstore += ++row; }
+      }
+   }
+}
+
+void SymmetricMatrix::GetCol(MatrixRowCol& mrc)
+{
+   // do not allow StoreHere
+   if (+(mrc.cw*StoreHere))
+      Throw(InternalException("SymmetricMatrix::GetCol(MatrixRowCol&)"));
+
+   int col=mrc.rowcol; mrc.length=nrows;
+   REPORT
+   mrc.skip=0;
+   if (+(mrc.cw*DirectPart))    // actually get row ??
+      { REPORT mrc.storage=col+1; mrc.data=store+(col*(col+1))/2; }
+   else
+   {
+      // do not allow StoreOnExit and !DirectPart
+      if (+(mrc.cw*StoreOnExit))
+         Throw(InternalException("SymmetricMatrix::GetCol(MatrixRowCol&)"));
+
+      mrc.storage=ncols; Real* ColCopy;
+      if ( +(mrc.cw*HaveStore)) { REPORT ColCopy = mrc.data; }
+      else
+      {
+         REPORT                                      // not accessed
+         ColCopy = new Real [ncols]; MatrixErrorNoSpace(ColCopy);
+         MONITOR_REAL_NEW("Make (SymGetCol)",ncols,ColCopy)
+         mrc.cw += HaveStore; mrc.data = ColCopy;
+      }
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT
+         Real* Mstore = store+(col*(col+1))/2; int i = col;
+         while (i--) *ColCopy++ = *Mstore++;
+         i = ncols-col;
+         // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
+         if (i) for (;;)
+            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
+      }
+   }
+}
+
+void SymmetricMatrix::GetCol(MatrixColX& mrc)
+{
+   int col=mrc.rowcol; mrc.length=nrows;
+   if (+(mrc.cw*DirectPart))
+   {
+      REPORT
+      mrc.skip=col; int i=nrows-col; mrc.storage=i;
+      mrc.data = mrc.store+col;
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT                           // not accessed
+         Real* ColCopy = mrc.data;
+         Real* Mstore = store+(col*(col+3))/2;
+         // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
+         if (i) for (;;)
+            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
+      }
+   }
+   else
+   {
+      REPORT
+      // do not allow StoreOnExit and !DirectPart
+      if (+(mrc.cw*StoreOnExit))
+         Throw(InternalException("SymmetricMatrix::GetCol(MatrixColX&)"));
+
+      mrc.skip=0; mrc.storage=ncols;
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT
+         Real* ColCopy = mrc.data;
+         Real* Mstore = store+(col*(col+1))/2; int i = col;
+         while (i--) *ColCopy++ = *Mstore++;
+         i = ncols-col;
+         // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
+         if (i) for (;;)
+            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
+      }
+   }
+}
+
+// Do not need RestoreRow because we do not allow !DirectPart && StoreOnExit
+
+void SymmetricMatrix::RestoreCol(MatrixColX& mrc)
+{
+   REPORT
+   // Really do restore column
+   int col=mrc.rowcol; Real* Cstore = mrc.data;
+   Real* Mstore = store+(col*(col+3))/2; int i = nrows-col;
+   // while (i--) { *Mstore = *Cstore++; Mstore+= ++col; }
+   if (i) for (;;)
+      { *Mstore = *Cstore++; if (!(--i)) break; Mstore+= ++col; }
+
+}
+
+// routines for row vector
+
+void RowVector::GetCol(MatrixRowCol& mrc)
+{
+   REPORT
+   // do not allow StoreHere
+   if (+(mrc.cw*StoreHere))
+      Throw(InternalException("RowVector::GetCol(MatrixRowCol&)"));
+
+   mrc.skip=0; mrc.storage=1; mrc.length=nrows; mrc.data = store+mrc.rowcol;
+
+}
+
+void RowVector::GetCol(MatrixColX& mrc)
+{
+   REPORT
+   mrc.skip=0; mrc.storage=1; mrc.length=nrows;
+   if (mrc.cw >= LoadOnEntry)
+      { REPORT *(mrc.data) = *(store+mrc.rowcol); }
+
+}
+
+void RowVector::NextCol(MatrixRowCol& mrc)
+{ REPORT mrc.rowcol++; mrc.data++; }
+
+void RowVector::NextCol(MatrixColX& mrc)
+{
+   if (+(mrc.cw*StoreOnExit)) { REPORT *(store+mrc.rowcol)=*(mrc.data); }
+
+   mrc.rowcol++;
+   if (mrc.rowcol < ncols)
+   {
+      if (+(mrc.cw*LoadOnEntry)) { REPORT *(mrc.data)=*(store+mrc.rowcol); }
+   }
+   else { REPORT mrc.cw -= StoreOnExit; }
+}
+
+void RowVector::RestoreCol(MatrixColX& mrc)
+   { REPORT *(store+mrc.rowcol)=*(mrc.data); }           // not accessed
+
+
+// routines for band matrices
+
+void BandMatrix::GetRow(MatrixRowCol& mrc)
+{
+   REPORT
+   int r = mrc.rowcol; int w = lower+1+upper; mrc.length=ncols;
+   int s = r-lower;
+   if (s<0) { mrc.data = store+(r*w-s); w += s; s = 0; }
+   else mrc.data = store+r*w;
+   mrc.skip = s; s += w-ncols; if (s>0) w -= s; mrc.storage = w;
+}
+
+// should make special versions of this for upper and lower band matrices
+
+void BandMatrix::NextRow(MatrixRowCol& mrc)
+{
+   REPORT
+   int r = ++mrc.rowcol;
+   if (r<=lower) { mrc.storage++; mrc.data += lower+upper; }
+   else  { mrc.skip++; mrc.data += lower+upper+1; }
+   if (r>=ncols-upper) mrc.storage--;
+}
+
+void BandMatrix::GetCol(MatrixRowCol& mrc)
+{
+   REPORT
+   int c = mrc.rowcol; int n = lower+upper; int w = n+1;
+   mrc.length=nrows; Real* ColCopy;
+   int b; int s = c-upper;
+   if (s<=0) { w += s; s = 0; b = c+lower; } else b = s*w+n;
+   mrc.skip = s; s += w-nrows; if (s>0) w -= s; mrc.storage = w;
+   if ( +(mrc.cw*(StoreHere+HaveStore)) )
+      { REPORT ColCopy = mrc.data; }
+   else
+   {
+      REPORT
+      ColCopy = new Real [n+1]; MatrixErrorNoSpace(ColCopy);
+      MONITOR_REAL_NEW("Make (BMGetCol)",n+1,ColCopy)
+      mrc.cw += HaveStore; mrc.data = ColCopy;
+   }
+
+   if (+(mrc.cw*LoadOnEntry))
+   {
+      REPORT
+      Real* Mstore = store+b;
+      // while (w--) { *ColCopy++ = *Mstore; Mstore+=n; }
+      if (w) for (;;)
+         { *ColCopy++ = *Mstore; if (!(--w)) break; Mstore+=n; }
+   }
+}
+
+void BandMatrix::GetCol(MatrixColX& mrc)
+{
+   REPORT
+   int c = mrc.rowcol; int n = lower+upper; int w = n+1;
+   mrc.length=nrows; int b; int s = c-upper;
+   if (s<=0) { w += s; s = 0; b = c+lower; } else b = s*w+n;
+   mrc.skip = s; s += w-nrows; if (s>0) w -= s; mrc.storage = w;
+   mrc.data = mrc.store+mrc.skip;
+
+   if (+(mrc.cw*LoadOnEntry))
+   {
+      REPORT
+      Real* ColCopy = mrc.data; Real* Mstore = store+b;
+      // while (w--) { *ColCopy++ = *Mstore; Mstore+=n; }
+      if (w) for (;;)
+         { *ColCopy++ = *Mstore; if (!(--w)) break; Mstore+=n; }
+   }
+}
+
+void BandMatrix::RestoreCol(MatrixRowCol& mrc)
+{
+   REPORT
+   int c = mrc.rowcol; int n = lower+upper; int s = c-upper;
+   Real* Mstore = store + ((s<=0) ? c+lower : s*n+s+n);
+   Real* Cstore = mrc.data;
+   int w = mrc.storage;
+   // while (w--) { *Mstore = *Cstore++; Mstore += n; }
+   if (w) for (;;)
+      { *Mstore = *Cstore++; if (!(--w)) break; Mstore += n; }
+}
+
+// routines for symmetric band matrix
+
+void SymmetricBandMatrix::GetRow(MatrixRowCol& mrc)
+{
+   REPORT
+   int r=mrc.rowcol; int s = r-lower; int w1 = lower+1; int o = r*w1;
+   mrc.length = ncols;
+   if (s<0) { w1 += s; o -= s; s = 0; }
+   mrc.skip = s;
+
+   if (+(mrc.cw*DirectPart))
+      { REPORT  mrc.data = store+o; mrc.storage = w1; }
+   else
+   {
+      // do not allow StoreOnExit and !DirectPart
+      if (+(mrc.cw*StoreOnExit))
+         Throw(InternalException("SymmetricBandMatrix::GetRow(MatrixRowCol&)"));
+      int w = w1+lower; s += w-ncols; Real* RowCopy;
+      if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
+      if (!(mrc.cw*HaveStore))
+      {
+         REPORT
+         RowCopy = new Real [2*lower+1]; MatrixErrorNoSpace(RowCopy);
+         MONITOR_REAL_NEW("Make (SmBGetRow)",2*lower+1,RowCopy)
+         mrc.cw += HaveStore; mrc.data = RowCopy;
+      }
+      else { REPORT  RowCopy = mrc.data; }
+
+      if (+(mrc.cw*LoadOnEntry))
+      {
+	      REPORT
+         Real* Mstore = store+o;
+         while (w1--) *RowCopy++ = *Mstore++;
+         Mstore--;
+         while (w2--) { Mstore += lower; *RowCopy++ = *Mstore; }
+      }
+   }
+}
+
+void SymmetricBandMatrix::GetCol(MatrixRowCol& mrc)
+{
+   // do not allow StoreHere
+   if (+(mrc.cw*StoreHere))
+      Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixRowCol&)"));
+
+   int c=mrc.rowcol; int w1 = lower+1; mrc.length=nrows;
+   REPORT
+   int s = c-lower; int o = c*w1;
+   if (s<0) { w1 += s; o -= s; s = 0; }
+   mrc.skip = s;
+
+   if (+(mrc.cw*DirectPart))
+   { REPORT  mrc.data = store+o; mrc.storage = w1; }
+   else
+   {
+      // do not allow StoreOnExit and !DirectPart
+      if (+(mrc.cw*StoreOnExit))
+         Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixRowCol&)"));
+      int w = w1+lower; s += w-ncols; Real* ColCopy;
+      if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
+
+      if ( +(mrc.cw*HaveStore) ) { REPORT ColCopy = mrc.data; }
+      else
+      {
+         REPORT ColCopy = new Real [2*lower+1]; MatrixErrorNoSpace(ColCopy);
+         MONITOR_REAL_NEW("Make (SmBGetCol)",2*lower+1,ColCopy)
+         mrc.cw += HaveStore; mrc.data = ColCopy;
+      }
+
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT
+         Real* Mstore = store+o;
+         while (w1--) *ColCopy++ = *Mstore++;
+         Mstore--;
+         while (w2--) { Mstore += lower; *ColCopy++ = *Mstore; }
+      }
+   }
+}
+
+void SymmetricBandMatrix::GetCol(MatrixColX& mrc)
+{
+   int c=mrc.rowcol; int w1 = lower+1; mrc.length=nrows;
+   if (+(mrc.cw*DirectPart))
+   {
+      REPORT
+      int b = c*w1+lower;
+      mrc.skip = c; c += w1-nrows; w1 -= c; mrc.storage = w1;
+      Real* ColCopy = mrc.data = mrc.store+mrc.skip;
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT
+         Real* Mstore = store+b;
+         // while (w1--) { *ColCopy++ = *Mstore; Mstore += lower; }
+         if (w1) for (;;)
+            { *ColCopy++ = *Mstore; if (!(--w1)) break; Mstore += lower; }
+      }
+   }
+   else
+   {
+      REPORT
+      // do not allow StoreOnExit and !DirectPart
+      if (+(mrc.cw*StoreOnExit))
+         Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixColX&)"));
+      int s = c-lower; int o = c*w1;
+      if (s<0) { w1 += s; o -= s; s = 0; }
+      mrc.skip = s;
+
+      int w = w1+lower; s += w-ncols;
+      if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
+
+      Real* ColCopy = mrc.data = mrc.store+mrc.skip;
+
+      if (+(mrc.cw*LoadOnEntry))
+      {
+         REPORT
+         Real* Mstore = store+o;
+         while (w1--) *ColCopy++ = *Mstore++;
+         Mstore--;
+         while (w2--) { Mstore += lower; *ColCopy++ = *Mstore; }
+      }
+
+   }
+}
+
+void SymmetricBandMatrix::RestoreCol(MatrixColX& mrc)
+{
+   REPORT
+   int c = mrc.rowcol;
+   Real* Mstore = store + c*lower+c+lower;
+   Real* Cstore = mrc.data; int w = mrc.storage;
+   // while (w--) { *Mstore = *Cstore++; Mstore += lower; }
+   if (w) for (;;)
+      { *Mstore = *Cstore++; if (!(--w)) break; Mstore += lower; }
+}
+
+// routines for identity matrix
+
+void IdentityMatrix::GetRow(MatrixRowCol& mrc)
+{
+   REPORT
+   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.data=store; mrc.length=ncols;
+}
+
+void IdentityMatrix::GetCol(MatrixRowCol& mrc)
+{
+   REPORT
+   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
+   if (+(mrc.cw*StoreHere))              // should not happen
+      Throw(InternalException("IdentityMatrix::GetCol(MatrixRowCol&)"));
+   else  { REPORT mrc.data=store; }
+}
+
+void IdentityMatrix::GetCol(MatrixColX& mrc)
+{
+   REPORT
+   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
+   mrc.data = mrc.store+mrc.skip; *(mrc.data)=*store;
+}
+
+void IdentityMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrId(); }
+
+void IdentityMatrix::NextCol(MatrixRowCol& mrc) { REPORT mrc.IncrId(); }
+
+void IdentityMatrix::NextCol(MatrixColX& mrc)
+{
+   REPORT
+   if (+(mrc.cw*StoreOnExit)) { REPORT *store=*(mrc.data); }
+   mrc.IncrDiag();            // must increase mrc.data so need IncrDiag
+   int t1 = +(mrc.cw*LoadOnEntry);
+   if (t1 && mrc.rowcol < ncols) { REPORT *(mrc.data)=*store; }
+}
+
+
+
+
+// *************************** destructors *******************************
+
+MatrixRowCol::~MatrixRowCol()
+{
+   if (+(cw*HaveStore))
+   {
+      MONITOR_REAL_DELETE("Free    (RowCol)",-1,data)  // do not know length
+      delete [] data;
+   }
+}
+
+MatrixRow::~MatrixRow() { if (+(cw*StoreOnExit)) gm->RestoreRow(*this); }
+
+MatrixCol::~MatrixCol() { if (+(cw*StoreOnExit)) gm->RestoreCol(*this); }
+
+MatrixColX::~MatrixColX() { if (+(cw*StoreOnExit)) gm->RestoreCol(*this); }
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat4.cpp b/Utilities/OSSIM/ossim_core/matrix/newmat4.cpp
new file mode 100644
index 0000000000..bcde93a50d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat4.cpp
@@ -0,0 +1,1027 @@
+//$$ newmat4.cpp       Constructors, ReSize, basic utilities
+
+// Copyright (C) 1991,2,3,4,8,9: R B Davies
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrc.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,4); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+#define DO_SEARCH                   // search for LHS of = in RHS
+
+// ************************* general utilities *************************/
+
+static int tristore(int n)                    // elements in triangular matrix
+{ return (n*(n+1))/2; }
+
+
+// **************************** constructors ***************************/
+
+GeneralMatrix::GeneralMatrix()
+{ store=0; storage=0; nrows=0; ncols=0; tag=-1; }
+
+GeneralMatrix::GeneralMatrix(ArrayLengthSpecifier s)
+{
+   REPORT
+   storage=s.Value(); tag=-1;
+   if (storage)
+   {
+      store = new Real [storage]; MatrixErrorNoSpace(store);
+      MONITOR_REAL_NEW("Make (GenMatrix)",storage,store)
+   }
+   else store = 0;
+}
+
+Matrix::Matrix(int m, int n) : GeneralMatrix(m*n)
+{ REPORT nrows=m; ncols=n; }
+
+SquareMatrix::SquareMatrix(ArrayLengthSpecifier n)
+   : Matrix(n.Value(),n.Value())
+{ REPORT }
+
+SymmetricMatrix::SymmetricMatrix(ArrayLengthSpecifier n)
+   : GeneralMatrix(tristore(n.Value()))
+{ REPORT nrows=n.Value(); ncols=n.Value(); }
+
+UpperTriangularMatrix::UpperTriangularMatrix(ArrayLengthSpecifier n)
+   : GeneralMatrix(tristore(n.Value()))
+{ REPORT nrows=n.Value(); ncols=n.Value(); }
+
+LowerTriangularMatrix::LowerTriangularMatrix(ArrayLengthSpecifier n)
+   : GeneralMatrix(tristore(n.Value()))
+{ REPORT nrows=n.Value(); ncols=n.Value(); }
+
+DiagonalMatrix::DiagonalMatrix(ArrayLengthSpecifier m) : GeneralMatrix(m)
+{ REPORT nrows=m.Value(); ncols=m.Value(); }
+
+Matrix::Matrix(const BaseMatrix& M)
+{
+   REPORT // CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Rt);
+   GetMatrix(gmx);
+}
+
+SquareMatrix::SquareMatrix(const BaseMatrix& M) : Matrix(M)
+{
+   REPORT
+   if (ncols != nrows)
+   {
+      Tracer tr("SquareMatrix");
+      Throw(NotSquareException(*this));
+   }
+}
+
+
+SquareMatrix::SquareMatrix(const Matrix& gm)
+{
+   REPORT
+   if (gm.ncols != gm.nrows)
+   {
+      Tracer tr("SquareMatrix(Matrix)");
+      Throw(NotSquareException(gm));
+   }
+   GetMatrix(&gm);
+}
+
+
+RowVector::RowVector(const BaseMatrix& M) : Matrix(M)
+{
+   REPORT
+   if (nrows!=1)
+   {
+      Tracer tr("RowVector");
+      Throw(VectorException(*this));
+   }
+}
+
+ColumnVector::ColumnVector(const BaseMatrix& M) : Matrix(M)
+{
+   REPORT
+   if (ncols!=1)
+   {
+      Tracer tr("ColumnVector");
+      Throw(VectorException(*this));
+   }
+}
+
+SymmetricMatrix::SymmetricMatrix(const BaseMatrix& M)
+{
+   REPORT  // CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Sm);
+   GetMatrix(gmx);
+}
+
+UpperTriangularMatrix::UpperTriangularMatrix(const BaseMatrix& M)
+{
+   REPORT // CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UT);
+   GetMatrix(gmx);
+}
+
+LowerTriangularMatrix::LowerTriangularMatrix(const BaseMatrix& M)
+{
+   REPORT // CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LT);
+   GetMatrix(gmx);
+}
+
+DiagonalMatrix::DiagonalMatrix(const BaseMatrix& M)
+{
+   REPORT //CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Dg);
+   GetMatrix(gmx);
+}
+
+IdentityMatrix::IdentityMatrix(const BaseMatrix& M)
+{
+   REPORT //CheckConversion(M);
+   // MatrixConversionCheck mcc;
+   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Id);
+   GetMatrix(gmx);
+}
+
+GeneralMatrix::~GeneralMatrix()
+{
+   if (store)
+   {
+      MONITOR_REAL_DELETE("Free (GenMatrix)",storage,store)
+      delete [] store;
+   }
+}
+
+CroutMatrix::CroutMatrix(const BaseMatrix& m)
+{
+   REPORT
+   Tracer tr("CroutMatrix");
+   indx = 0;                     // in case of exception at next line
+   GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate(MatrixType::Rt);
+   GetMatrix(gm);
+   if (nrows!=ncols) { CleanUp(); Throw(NotSquareException(*gm)); }
+   d=true; sing=false;
+   indx=new int [nrows]; MatrixErrorNoSpace(indx);
+   MONITOR_INT_NEW("Index (CroutMat)",nrows,indx)
+   ludcmp();
+}
+
+CroutMatrix::~CroutMatrix()
+{
+   MONITOR_INT_DELETE("Index (CroutMat)",nrows,indx)
+   delete [] indx;
+}
+
+//ReturnMatrix::ReturnMatrix(GeneralMatrix& gmx)
+//{
+//   REPORT
+//   gm = gmx.Image(); gm->ReleaseAndDelete();
+//}
+
+
+GeneralMatrix::operator ReturnMatrix() const
+{
+   REPORT
+   GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
+   return ReturnMatrix(gm);
+}
+
+
+
+ReturnMatrix GeneralMatrix::ForReturn() const
+{
+   REPORT
+   GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
+   return ReturnMatrix(gm);
+}
+
+
+// ************************** ReSize matrices ***************************/
+
+void GeneralMatrix::ReSize(int nr, int nc, int s)
+{
+   REPORT
+   if (store)
+   {
+      MONITOR_REAL_DELETE("Free (ReDimensi)",storage,store)
+      delete [] store;
+   }
+   storage=s; nrows=nr; ncols=nc; tag=-1;
+   if (s)
+   {
+      store = new Real [storage]; MatrixErrorNoSpace(store);
+      MONITOR_REAL_NEW("Make (ReDimensi)",storage,store)
+   }
+   else store = 0;
+}
+
+void Matrix::ReSize(int nr, int nc)
+{ REPORT GeneralMatrix::ReSize(nr,nc,nr*nc); }
+
+void SquareMatrix::ReSize(int n)
+{ REPORT GeneralMatrix::ReSize(n,n,n*n); }
+
+void SquareMatrix::ReSize(int nr, int nc)
+{
+   REPORT
+   Tracer tr("SquareMatrix::ReSize");
+   if (nc != nr) Throw(NotSquareException(*this));
+   GeneralMatrix::ReSize(nr,nc,nr*nc);
+}
+
+void SymmetricMatrix::ReSize(int nr)
+{ REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); }
+
+void UpperTriangularMatrix::ReSize(int nr)
+{ REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); }
+
+void LowerTriangularMatrix::ReSize(int nr)
+{ REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); }
+
+void DiagonalMatrix::ReSize(int nr)
+{ REPORT GeneralMatrix::ReSize(nr,nr,nr); }
+
+void RowVector::ReSize(int nc)
+{ REPORT GeneralMatrix::ReSize(1,nc,nc); }
+
+void ColumnVector::ReSize(int nr)
+{ REPORT GeneralMatrix::ReSize(nr,1,nr); }
+
+void RowVector::ReSize(int nr, int nc)
+{
+   Tracer tr("RowVector::ReSize");
+   if (nr != 1) Throw(VectorException(*this));
+   REPORT GeneralMatrix::ReSize(1,nc,nc);
+}
+
+void ColumnVector::ReSize(int nr, int nc)
+{
+   Tracer tr("ColumnVector::ReSize");
+   if (nc != 1) Throw(VectorException(*this));
+   REPORT GeneralMatrix::ReSize(nr,1,nr);
+}
+
+void IdentityMatrix::ReSize(int nr)
+{ REPORT GeneralMatrix::ReSize(nr,nr,1); *store = 1; }
+
+
+void Matrix::ReSize(const GeneralMatrix& A)
+{ REPORT  ReSize(A.Nrows(), A.Ncols()); }
+
+void SquareMatrix::ReSize(const GeneralMatrix& A)
+{
+   REPORT
+   int n = A.Nrows();
+   if (n != A.Ncols())
+   {
+      Tracer tr("SquareMatrix::ReSize(GM)");
+      Throw(NotSquareException(*this));
+   }
+   ReSize(n);
+}
+
+void nricMatrix::ReSize(const GeneralMatrix& A)
+{ REPORT  ReSize(A.Nrows(), A.Ncols()); }
+
+void ColumnVector::ReSize(const GeneralMatrix& A)
+{ REPORT  ReSize(A.Nrows(), A.Ncols()); }
+
+void RowVector::ReSize(const GeneralMatrix& A)
+{ REPORT  ReSize(A.Nrows(), A.Ncols()); }
+
+void SymmetricMatrix::ReSize(const GeneralMatrix& A)
+{
+   REPORT
+   int n = A.Nrows();
+   if (n != A.Ncols())
+   {
+      Tracer tr("SymmetricMatrix::ReSize(GM)");
+      Throw(NotSquareException(*this));
+   }
+   ReSize(n);
+}
+
+void DiagonalMatrix::ReSize(const GeneralMatrix& A)
+{
+   REPORT
+   int n = A.Nrows();
+   if (n != A.Ncols())
+   {
+      Tracer tr("DiagonalMatrix::ReSize(GM)");
+      Throw(NotSquareException(*this));
+   }
+   ReSize(n);
+}
+
+void UpperTriangularMatrix::ReSize(const GeneralMatrix& A)
+{
+   REPORT
+   int n = A.Nrows();
+   if (n != A.Ncols())
+   {
+      Tracer tr("UpperTriangularMatrix::ReSize(GM)");
+      Throw(NotSquareException(*this));
+   }
+   ReSize(n);
+}
+
+void LowerTriangularMatrix::ReSize(const GeneralMatrix& A)
+{
+   REPORT
+   int n = A.Nrows();
+   if (n != A.Ncols())
+   {
+      Tracer tr("LowerTriangularMatrix::ReSize(GM)");
+      Throw(NotSquareException(*this));
+   }
+   ReSize(n);
+}
+
+void IdentityMatrix::ReSize(const GeneralMatrix& A)
+{
+   REPORT
+   int n = A.Nrows();
+   if (n != A.Ncols())
+   {
+      Tracer tr("IdentityMatrix::ReSize(GM)");
+      Throw(NotSquareException(*this));
+   }
+   ReSize(n);
+}
+
+void GeneralMatrix::ReSize(const GeneralMatrix&)
+{
+   REPORT
+   Tracer tr("GeneralMatrix::ReSize(GM)");
+   Throw(NotDefinedException("ReSize", "this type of matrix"));
+}
+
+void GeneralMatrix::ReSizeForAdd(const GeneralMatrix& A, const GeneralMatrix&)
+{ REPORT ReSize(A); }
+
+void GeneralMatrix::ReSizeForSP(const GeneralMatrix& A, const GeneralMatrix&)
+{ REPORT ReSize(A); }
+
+
+// ************************* SameStorageType ******************************/
+
+// SameStorageType checks A and B have same storage type including bandwidth
+// It does not check same dimensions since we assume this is already done
+
+bool GeneralMatrix::SameStorageType(const GeneralMatrix& A) const
+{
+   REPORT
+   return Type() == A.Type();
+}
+
+
+// ******************* manipulate types, storage **************************/
+
+int GeneralMatrix::search(const BaseMatrix* s) const
+{ REPORT return (s==this) ? 1 : 0; }
+
+int GenericMatrix::search(const BaseMatrix* s) const
+{ REPORT return gm->search(s); }
+
+int MultipliedMatrix::search(const BaseMatrix* s) const
+{ REPORT return bm1->search(s) + bm2->search(s); }
+
+int ShiftedMatrix::search(const BaseMatrix* s) const
+{ REPORT return bm->search(s); }
+
+int NegatedMatrix::search(const BaseMatrix* s) const
+{ REPORT return bm->search(s); }
+
+int ReturnMatrix::search(const BaseMatrix* s) const
+{ REPORT return (s==gm) ? 1 : 0; }
+
+MatrixType Matrix::Type() const { return MatrixType::Rt; }
+MatrixType SquareMatrix::Type() const { return MatrixType::Sq; }
+MatrixType SymmetricMatrix::Type() const { return MatrixType::Sm; }
+MatrixType UpperTriangularMatrix::Type() const { return MatrixType::UT; }
+MatrixType LowerTriangularMatrix::Type() const { return MatrixType::LT; }
+MatrixType DiagonalMatrix::Type() const { return MatrixType::Dg; }
+MatrixType RowVector::Type() const { return MatrixType::RV; }
+MatrixType ColumnVector::Type() const { return MatrixType::CV; }
+MatrixType CroutMatrix::Type() const { return MatrixType::Ct; }
+MatrixType BandMatrix::Type() const { return MatrixType::BM; }
+MatrixType UpperBandMatrix::Type() const { return MatrixType::UB; }
+MatrixType LowerBandMatrix::Type() const { return MatrixType::LB; }
+MatrixType SymmetricBandMatrix::Type() const { return MatrixType::SB; }
+
+MatrixType IdentityMatrix::Type() const { return MatrixType::Id; }
+
+
+
+MatrixBandWidth BaseMatrix::BandWidth() const { REPORT return -1; }
+MatrixBandWidth DiagonalMatrix::BandWidth() const { REPORT return 0; }
+MatrixBandWidth IdentityMatrix::BandWidth() const { REPORT return 0; }
+
+MatrixBandWidth UpperTriangularMatrix::BandWidth() const
+   { REPORT return MatrixBandWidth(0,-1); }
+
+MatrixBandWidth LowerTriangularMatrix::BandWidth() const
+   { REPORT return MatrixBandWidth(-1,0); }
+
+MatrixBandWidth BandMatrix::BandWidth() const
+   { REPORT return MatrixBandWidth(lower,upper); }
+
+MatrixBandWidth GenericMatrix::BandWidth()const
+   { REPORT return gm->BandWidth(); }
+
+MatrixBandWidth AddedMatrix::BandWidth() const
+   { REPORT return gm1->BandWidth() + gm2->BandWidth(); }
+
+MatrixBandWidth SPMatrix::BandWidth() const
+   { REPORT return gm1->BandWidth().minimum(gm2->BandWidth()); }
+
+MatrixBandWidth KPMatrix::BandWidth() const
+{
+   int lower, upper;
+   MatrixBandWidth bw1 = gm1->BandWidth(), bw2 = gm2->BandWidth();
+   if (bw1.Lower() < 0)
+   {
+      if (bw2.Lower() < 0) { REPORT lower = -1; }
+      else { REPORT lower = bw2.Lower() + (gm1->Nrows() - 1) * gm2->Nrows(); }
+   }
+   else
+   {
+      if (bw2.Lower() < 0)
+         { REPORT lower = (1 + bw1.Lower()) * gm2->Nrows() - 1; }
+      else { REPORT lower = bw2.Lower() + bw1.Lower() * gm2->Nrows(); }
+   }
+   if (bw1.Upper() < 0)
+   {
+      if (bw2.Upper() < 0) { REPORT upper = -1; }
+      else { REPORT upper = bw2.Upper() + (gm1->Nrows() - 1) * gm2->Nrows(); }
+   }
+   else
+   {
+      if (bw2.Upper() < 0)
+         { REPORT upper = (1 + bw1.Upper()) * gm2->Nrows() - 1; }
+      else { REPORT upper = bw2.Upper() + bw1.Upper() * gm2->Nrows(); }
+   }
+   return MatrixBandWidth(lower, upper);
+}
+
+MatrixBandWidth MultipliedMatrix::BandWidth() const
+{ REPORT return gm1->BandWidth() * gm2->BandWidth(); }
+
+MatrixBandWidth ConcatenatedMatrix::BandWidth() const { REPORT return -1; }
+
+MatrixBandWidth SolvedMatrix::BandWidth() const
+{
+   if (+gm1->Type() & MatrixType::Diagonal)
+      { REPORT return gm2->BandWidth(); }
+   else { REPORT return -1; }
+}
+
+MatrixBandWidth ScaledMatrix::BandWidth() const
+   { REPORT return gm->BandWidth(); }
+
+MatrixBandWidth NegatedMatrix::BandWidth() const
+   { REPORT return gm->BandWidth(); }
+
+MatrixBandWidth TransposedMatrix::BandWidth() const
+   { REPORT return gm->BandWidth().t(); }
+
+MatrixBandWidth InvertedMatrix::BandWidth() const
+{
+   if (+gm->Type() & MatrixType::Diagonal)
+      { REPORT return MatrixBandWidth(0,0); }
+   else { REPORT return -1; }
+}
+
+MatrixBandWidth RowedMatrix::BandWidth() const { REPORT return -1; }
+MatrixBandWidth ColedMatrix::BandWidth() const { REPORT return -1; }
+MatrixBandWidth DiagedMatrix::BandWidth() const { REPORT return 0; }
+MatrixBandWidth MatedMatrix::BandWidth() const { REPORT return -1; }
+MatrixBandWidth ReturnMatrix::BandWidth() const
+   { REPORT return gm->BandWidth(); }
+
+MatrixBandWidth GetSubMatrix::BandWidth() const
+{
+
+   if (row_skip==col_skip && row_number==col_number)
+      { REPORT return gm->BandWidth(); }
+   else { REPORT return MatrixBandWidth(-1); }
+}
+
+// ********************** the memory managment tools **********************/
+
+//  Rules regarding tDelete, reuse, GetStore, BorrowStore
+//    All matrices processed during expression evaluation must be subject
+//    to exactly one of reuse(), tDelete(), GetStore() or BorrowStore().
+//    If reuse returns true the matrix must be reused.
+//    GetMatrix(gm) always calls gm->GetStore()
+//    gm->Evaluate obeys rules
+//    bm->Evaluate obeys rules for matrices in bm structure
+
+void GeneralMatrix::tDelete()
+{
+   if (tag<0)
+   {
+      if (tag<-1) { REPORT store = 0; delete this; return; }  // borrowed
+      else { REPORT return; }   // not a temporary matrix - leave alone
+   }
+   if (tag==1)
+   {
+      if (store)
+      {
+         REPORT  MONITOR_REAL_DELETE("Free   (tDelete)",storage,store)
+         delete [] store;
+      }
+      MiniCleanUp(); return;                           // CleanUp
+   }
+   if (tag==0) { REPORT delete this; return; }
+
+   REPORT tag--; return;
+}
+
+static void BlockCopy(int n, Real* from, Real* to)
+{
+   REPORT
+   int i = (n >> 3);
+   while (i--)
+   {
+      *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
+      *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
+   }
+   i = n & 7; while (i--) *to++ = *from++;
+}
+
+bool GeneralMatrix::reuse()
+{
+   if (tag < -1)                 // borrowed storage
+   {
+      if (storage)
+      {
+         REPORT
+         Real* s = new Real [storage]; MatrixErrorNoSpace(s);
+         MONITOR_REAL_NEW("Make     (reuse)",storage,s)
+         BlockCopy(storage, store, s); store = s;
+      }
+      else { REPORT MiniCleanUp(); }                // CleanUp
+      tag = 0; return true;
+   }
+   if (tag < 0 ) { REPORT return false; }
+   if (tag <= 1 )  { REPORT return true; }
+   REPORT tag--; return false;
+}
+
+Real* GeneralMatrix::GetStore()
+{
+   if (tag<0 || tag>1)
+   {
+      Real* s;
+      if (storage)
+      {
+         s = new Real [storage]; MatrixErrorNoSpace(s);
+         MONITOR_REAL_NEW("Make  (GetStore)",storage,s)
+         BlockCopy(storage, store, s);
+      }
+      else s = 0;
+      if (tag > 1) { REPORT tag--; }
+      else if (tag < -1) { REPORT store = 0; delete this; } // borrowed store
+      else { REPORT }
+      return s;
+   }
+   Real* s = store;                             // CleanUp - done later
+   if (tag==0) { REPORT store = 0; delete this; }
+   else { REPORT  MiniCleanUp(); }
+   return s;
+}
+
+void GeneralMatrix::GetMatrix(const GeneralMatrix* gmx)
+{
+   REPORT  tag=-1; nrows=gmx->Nrows(); ncols=gmx->Ncols();
+   storage=gmx->storage; SetParameters(gmx);
+   store=((GeneralMatrix*)gmx)->GetStore();
+}
+
+GeneralMatrix* GeneralMatrix::BorrowStore(GeneralMatrix* gmx, MatrixType mt)
+// Copy storage of *this to storage of *gmx. Then convert to type mt.
+// If mt == 0 just let *gmx point to storage of *this if tag==-1.
+{
+   if (!mt)
+   {
+      if (tag == -1) { REPORT gmx->tag = -2; gmx->store = store; }
+      else { REPORT gmx->tag = 0; gmx->store = GetStore(); }
+   }
+   else if (Compare(gmx->Type(),mt))
+   { REPORT  gmx->tag = 0; gmx->store = GetStore(); }
+   else
+   {
+      REPORT gmx->tag = -2; gmx->store = store;
+      gmx = gmx->Evaluate(mt); gmx->tag = 0; tDelete();
+   }
+
+   return gmx;
+}
+
+void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt)
+// Count number of references to this in X.
+// If zero delete storage in this;
+// otherwise tag this to show when storage can be deleted
+// evaluate X and copy to this
+{
+#ifdef DO_SEARCH
+   int counter=X.search(this);
+   if (counter==0)
+   {
+      REPORT
+      if (store)
+      {
+         MONITOR_REAL_DELETE("Free (operator=)",storage,store)
+         REPORT delete [] store; storage = 0; store = 0;
+      }
+   }
+   else { REPORT Release(counter); }
+   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
+   if (gmx!=this) { REPORT GetMatrix(gmx); }
+   else { REPORT }
+   Protect();
+#else
+   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
+   if (gmx!=this)
+   {
+      REPORT
+      if (store)
+      {
+         MONITOR_REAL_DELETE("Free (operator=)",storage,store)
+         REPORT delete [] store; storage = 0; store = 0;
+      }
+      GetMatrix(gmx);
+   }
+   else { REPORT }
+   Protect();
+#endif
+}
+
+// version with no conversion
+void GeneralMatrix::Eq(const GeneralMatrix& X)
+{
+   GeneralMatrix* gmx = (GeneralMatrix*)&X;
+   if (gmx!=this)
+   {
+      REPORT
+      if (store)
+      {
+         MONITOR_REAL_DELETE("Free (operator=)",storage,store)
+         REPORT delete [] store; storage = 0; store = 0;
+      }
+      GetMatrix(gmx);
+   }
+   else { REPORT }
+   Protect();
+}
+
+// version to work with operator<<
+void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt, bool ldok)
+{
+   REPORT
+   if (ldok) mt.SetDataLossOK();
+   Eq(X, mt);
+}
+
+void GeneralMatrix::Eq2(const BaseMatrix& X, MatrixType mt)
+// a cut down version of Eq for use with += etc.
+// we know BaseMatrix points to two GeneralMatrix objects,
+// the first being this (may be the same).
+// we know tag has been set correctly in each.
+{
+   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
+   if (gmx!=this) { REPORT GetMatrix(gmx); }  // simplify GetMatrix ?
+   else { REPORT }
+   Protect();
+}
+
+void GeneralMatrix::Inject(const GeneralMatrix& X)
+// copy stored values of X; otherwise leave els of *this unchanged
+{
+   REPORT
+   Tracer tr("Inject");
+   if (nrows != X.nrows || ncols != X.ncols)
+      Throw(IncompatibleDimensionsException());
+   MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry);
+   MatrixRow mrx(this, LoadOnEntry+StoreOnExit+DirectPart);
+   int i=nrows;
+   while (i--) { mrx.Inject(mr); mrx.Next(); mr.Next(); }
+}
+
+// ************* checking for data loss during conversion *******************/
+
+bool Compare(const MatrixType& source, MatrixType& destination)
+{
+   if (!destination) { destination=source; return true; }
+   if (destination==source) return true;
+   if (!destination.DataLossOK && !(destination>=source))
+      Throw(ProgramException("Illegal Conversion", source, destination));
+   return false;
+}
+
+// ************* Make a copy of a matrix on the heap *********************/
+
+GeneralMatrix* Matrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new Matrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* SquareMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new SquareMatrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* SymmetricMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new SymmetricMatrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* UpperTriangularMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new UpperTriangularMatrix(*this);
+   MatrixErrorNoSpace(gm); return gm;
+}
+
+GeneralMatrix* LowerTriangularMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new LowerTriangularMatrix(*this);
+   MatrixErrorNoSpace(gm); return gm;
+}
+
+GeneralMatrix* DiagonalMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new DiagonalMatrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* RowVector::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new RowVector(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* ColumnVector::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new ColumnVector(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* BandMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new BandMatrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* UpperBandMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new UpperBandMatrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* LowerBandMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new LowerBandMatrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* SymmetricBandMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new SymmetricBandMatrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* nricMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new nricMatrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* IdentityMatrix::Image() const
+{
+   REPORT
+   GeneralMatrix* gm = new IdentityMatrix(*this); MatrixErrorNoSpace(gm);
+   return gm;
+}
+
+GeneralMatrix* GeneralMatrix::Image() const
+{
+   bool dummy = true;
+   if (dummy)                                   // get rid of warning message
+      Throw(InternalException("Cannot apply Image to this matrix type"));
+   return 0;
+}
+
+
+// *********************** nricMatrix routines *****************************/
+
+void nricMatrix::MakeRowPointer()
+{
+   REPORT
+   if (nrows > 0)
+   {
+      row_pointer = new Real* [nrows]; MatrixErrorNoSpace(row_pointer);
+      Real* s = Store() - 1; int i = nrows; Real** rp = row_pointer;
+      if (i) for (;;) { *rp++ = s; if (!(--i)) break; s+=ncols; }
+   }
+   else row_pointer = 0;
+}
+
+void nricMatrix::DeleteRowPointer()
+   { REPORT if (nrows) delete [] row_pointer; }
+
+void GeneralMatrix::CheckStore() const
+{
+   REPORT
+   if (!store)
+      Throw(ProgramException("NRIC accessing matrix with unset dimensions"));
+}
+
+
+// *************************** CleanUp routines *****************************/
+
+void GeneralMatrix::CleanUp()
+{
+   // set matrix dimensions to zero, delete storage
+   REPORT
+   if (store && storage)
+   {
+      MONITOR_REAL_DELETE("Free (CleanUp)    ",storage,store)
+      REPORT delete [] store;
+   }
+   store=0; storage=0; nrows=0; ncols=0; tag = -1;
+}
+
+void nricMatrix::CleanUp()
+   { REPORT DeleteRowPointer(); GeneralMatrix::CleanUp(); }
+
+void nricMatrix::MiniCleanUp()
+   { REPORT DeleteRowPointer(); GeneralMatrix::MiniCleanUp(); }
+
+void RowVector::CleanUp()
+   { REPORT GeneralMatrix::CleanUp(); nrows=1; }
+
+void ColumnVector::CleanUp()
+   { REPORT GeneralMatrix::CleanUp(); ncols=1; }
+
+void CroutMatrix::CleanUp()
+{
+   REPORT
+   if (nrows) delete [] indx;
+   GeneralMatrix::CleanUp();
+}
+
+void CroutMatrix::MiniCleanUp()
+{
+   REPORT
+   if (nrows) delete [] indx;
+   GeneralMatrix::MiniCleanUp();
+}
+
+void BandLUMatrix::CleanUp()
+{
+   REPORT
+   if (nrows) delete [] indx;
+   if (storage2) delete [] store2;
+   GeneralMatrix::CleanUp();
+}
+
+void BandLUMatrix::MiniCleanUp()
+{
+   REPORT
+   if (nrows) delete [] indx;
+   if (storage2) delete [] store2;
+   GeneralMatrix::MiniCleanUp();
+}
+
+// ************************ simple integer array class ***********************
+
+// construct a new array of length xn. Check that xn is non-negative and
+// that space is available
+
+SimpleIntArray::SimpleIntArray(int xn) : n(xn)
+{
+   if (n < 0) Throw(Logic_error("invalid array length"));
+   else if (n == 0) { REPORT  a = 0; }
+   else { REPORT  a = new int [n]; if (!a) Throw(Bad_alloc()); }
+}
+
+// destroy an array - return its space to memory
+
+SimpleIntArray::~SimpleIntArray() { REPORT  if (a) delete [] a; }
+
+// access an element of an array; return a "reference" so elements
+// can be modified.
+// check index is within range
+// in this array class the index runs from 0 to n-1
+
+int& SimpleIntArray::operator[](int i)
+{
+   REPORT
+   if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
+   return a[i];
+}
+
+// same thing again but for arrays declared constant so we can't
+// modify its elements
+
+int SimpleIntArray::operator[](int i) const
+{
+   REPORT
+   if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
+   return a[i];
+}
+
+// set all the elements equal to a given value
+
+void SimpleIntArray::operator=(int ai)
+   { REPORT  for (int i = 0; i < n; i++) a[i] = ai; }
+
+// set the elements equal to those of another array.
+// check the arrays are of the same length
+
+void SimpleIntArray::operator=(const SimpleIntArray& b)
+{
+   REPORT
+   if (b.n != n) Throw(Logic_error("array lengths differ in copy"));
+   for (int i = 0; i < n; i++) a[i] = b.a[i];
+}
+
+// construct a new array equal to an existing array
+// check that space is available
+
+SimpleIntArray::SimpleIntArray(const SimpleIntArray& b) : n(b.n)
+{
+   if (n == 0) { REPORT  a = 0; }
+   else
+   {
+      REPORT
+      a = new int [n]; if (!a) Throw(Bad_alloc());
+      for (int i = 0; i < n; i++) a[i] = b.a[i];
+   }
+}
+
+// change the size of an array; optionally copy data from old array to
+// new array
+
+void SimpleIntArray::ReSize(int n1, bool keep)
+{
+   if (n1 == n) { REPORT  return; }
+   else if (n1 == 0) { REPORT  n = 0; delete [] a; a = 0; }
+   else if (n == 0)
+      { REPORT  a = new int [n1]; if (!a) Throw(Bad_alloc()); n = n1; }
+   else
+   {
+      int* a1 = a;
+      if (keep)
+      {
+         REPORT
+         a = new int [n1]; if (!a) Throw(Bad_alloc());
+         if (n > n1) n = n1;
+         for (int i = 0; i < n; i++) a[i] = a1[i];
+         n = n1; delete [] a1;
+      }
+      else
+      {
+         REPORT  n = n1; delete [] a1;
+         a = new int [n]; if (!a) Throw(Bad_alloc());
+      }
+   }
+}
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat5.cpp b/Utilities/OSSIM/ossim_core/matrix/newmat5.cpp
new file mode 100644
index 0000000000..665da82e66
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat5.cpp
@@ -0,0 +1,485 @@
+//$$ newmat5.cpp         Transpose, evaluate etc
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+//#define WANT_STREAM
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrc.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,5); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+/************************ carry out operations ******************************/
+
+
+GeneralMatrix* GeneralMatrix::Transpose(TransposedMatrix* tm, MatrixType mt)
+{
+   GeneralMatrix* gm1;
+
+   if (Compare(Type().t(),mt))
+   {
+      REPORT
+      gm1 = mt.New(ncols,nrows,tm);
+      for (int i=0; i<ncols; i++)
+      {
+         MatrixRow mr(gm1, StoreOnExit+DirectPart, i);
+         MatrixCol mc(this, mr.Data(), LoadOnEntry, i);
+      }
+   }
+   else
+   {
+      REPORT
+      gm1 = mt.New(ncols,nrows,tm);
+      MatrixRow mr(this, LoadOnEntry);
+      MatrixCol mc(gm1, StoreOnExit+DirectPart);
+      int i = nrows;
+      while (i--) { mc.Copy(mr); mr.Next(); mc.Next(); }
+   }
+   tDelete(); gm1->ReleaseAndDelete(); return gm1;
+}
+
+GeneralMatrix* SymmetricMatrix::Transpose(TransposedMatrix*, MatrixType mt)
+{ REPORT  return Evaluate(mt); }
+
+
+GeneralMatrix* DiagonalMatrix::Transpose(TransposedMatrix*, MatrixType mt)
+{ REPORT return Evaluate(mt); }
+
+GeneralMatrix* ColumnVector::Transpose(TransposedMatrix*, MatrixType mt)
+{
+   REPORT
+   GeneralMatrix* gmx = new RowVector; MatrixErrorNoSpace(gmx);
+   gmx->nrows = 1; gmx->ncols = gmx->storage = storage;
+   return BorrowStore(gmx,mt);
+}
+
+GeneralMatrix* RowVector::Transpose(TransposedMatrix*, MatrixType mt)
+{
+   REPORT
+   GeneralMatrix* gmx = new ColumnVector; MatrixErrorNoSpace(gmx);
+   gmx->ncols = 1; gmx->nrows = gmx->storage = storage;
+   return BorrowStore(gmx,mt);
+}
+
+GeneralMatrix* IdentityMatrix::Transpose(TransposedMatrix*, MatrixType mt)
+{ REPORT return Evaluate(mt); }
+
+GeneralMatrix* GeneralMatrix::Evaluate(MatrixType mt)
+{
+   if (Compare(this->Type(),mt)) { REPORT return this; }
+   REPORT
+   GeneralMatrix* gmx = mt.New(nrows,ncols,this);
+   MatrixRow mr(this, LoadOnEntry);
+   MatrixRow mrx(gmx, StoreOnExit+DirectPart);
+   int i=nrows;
+   while (i--) { mrx.Copy(mr); mrx.Next(); mr.Next(); }
+   tDelete(); gmx->ReleaseAndDelete(); return gmx;
+}
+
+GeneralMatrix* GenericMatrix::Evaluate(MatrixType mt)
+   { REPORT  return gm->Evaluate(mt); }
+
+GeneralMatrix* ShiftedMatrix::Evaluate(MatrixType mt)
+{
+   gm=((BaseMatrix*&)bm)->Evaluate();
+   int nr=gm->Nrows(); int nc=gm->Ncols();
+   Compare(gm->Type().AddEqualEl(),mt);
+   if (!(mt==gm->Type()))
+   {
+      REPORT
+      GeneralMatrix* gmx = mt.New(nr,nc,this);
+      MatrixRow mr(gm, LoadOnEntry);
+      MatrixRow mrx(gmx, StoreOnExit+DirectPart);
+      while (nr--) { mrx.Add(mr,f); mrx.Next(); mr.Next(); }
+      gmx->ReleaseAndDelete(); gm->tDelete();
+      return gmx;
+   }
+   else if (gm->reuse())
+   {
+      REPORT gm->Add(f);
+      return gm;
+   }
+   else
+   {
+      REPORT GeneralMatrix* gmy = gm->Type().New(nr,nc,this);
+      gmy->ReleaseAndDelete(); gmy->Add(gm,f);
+      return gmy;
+   }
+}
+
+GeneralMatrix* NegShiftedMatrix::Evaluate(MatrixType mt)
+{
+   gm=((BaseMatrix*&)bm)->Evaluate();
+   int nr=gm->Nrows(); int nc=gm->Ncols();
+   Compare(gm->Type().AddEqualEl(),mt);
+   if (!(mt==gm->Type()))
+   {
+      REPORT
+      GeneralMatrix* gmx = mt.New(nr,nc,this);
+      MatrixRow mr(gm, LoadOnEntry);
+      MatrixRow mrx(gmx, StoreOnExit+DirectPart);
+      while (nr--) { mrx.NegAdd(mr,f); mrx.Next(); mr.Next(); }
+      gmx->ReleaseAndDelete(); gm->tDelete();
+      return gmx;
+   }
+   else if (gm->reuse())
+   {
+      REPORT gm->NegAdd(f);
+      return gm;
+   }
+   else
+   {
+      REPORT GeneralMatrix* gmy = gm->Type().New(nr,nc,this);
+      gmy->ReleaseAndDelete(); gmy->NegAdd(gm,f);
+      return gmy;
+   }
+}
+
+GeneralMatrix* ScaledMatrix::Evaluate(MatrixType mt)
+{
+   gm=((BaseMatrix*&)bm)->Evaluate();
+   int nr=gm->Nrows(); int nc=gm->Ncols();
+   if (Compare(gm->Type(),mt))
+   {
+      if (gm->reuse())
+      {
+         REPORT gm->Multiply(f);
+         return gm;
+      }
+      else
+      {
+         REPORT GeneralMatrix* gmx = gm->Type().New(nr,nc,this);
+         gmx->ReleaseAndDelete(); gmx->Multiply(gm,f);
+         return gmx;
+      }
+   }
+   else
+   {
+      REPORT
+      GeneralMatrix* gmx = mt.New(nr,nc,this);
+      MatrixRow mr(gm, LoadOnEntry);
+      MatrixRow mrx(gmx, StoreOnExit+DirectPart);
+      while (nr--) { mrx.Multiply(mr,f); mrx.Next(); mr.Next(); }
+      gmx->ReleaseAndDelete(); gm->tDelete();
+      return gmx;
+   }
+}
+
+GeneralMatrix* NegatedMatrix::Evaluate(MatrixType mt)
+{
+   gm=((BaseMatrix*&)bm)->Evaluate();
+   int nr=gm->Nrows(); int nc=gm->Ncols();
+   if (Compare(gm->Type(),mt))
+   {
+      if (gm->reuse())
+      {
+         REPORT gm->Negate();
+         return gm;
+      }
+      else
+      {
+         REPORT
+         GeneralMatrix* gmx = gm->Type().New(nr,nc,this);
+         gmx->ReleaseAndDelete(); gmx->Negate(gm);
+         return gmx;
+      }
+   }
+   else
+   {
+      REPORT
+      GeneralMatrix* gmx = mt.New(nr,nc,this);
+      MatrixRow mr(gm, LoadOnEntry);
+      MatrixRow mrx(gmx, StoreOnExit+DirectPart);
+      while (nr--) { mrx.Negate(mr); mrx.Next(); mr.Next(); }
+      gmx->ReleaseAndDelete(); gm->tDelete();
+      return gmx;
+   }
+}
+
+GeneralMatrix* ReversedMatrix::Evaluate(MatrixType mt)
+{
+   gm=((BaseMatrix*&)bm)->Evaluate(); GeneralMatrix* gmx;
+
+   if ((gm->Type()).IsBand() && ! (gm->Type()).IsDiagonal())
+   {
+      gm->tDelete();
+      Throw(NotDefinedException("Reverse", "band matrices"));
+   }
+
+   if (gm->reuse()) { REPORT gm->ReverseElements(); gmx = gm; }
+   else
+   {
+      REPORT
+      gmx = gm->Type().New(gm->Nrows(), gm->Ncols(), this);
+      gmx->ReverseElements(gm); gmx->ReleaseAndDelete();
+   }
+   return gmx->Evaluate(mt); // target matrix is different type?
+
+}
+
+GeneralMatrix* TransposedMatrix::Evaluate(MatrixType mt)
+{
+   REPORT
+   gm=((BaseMatrix*&)bm)->Evaluate();
+   Compare(gm->Type().t(),mt);
+   GeneralMatrix* gmx=gm->Transpose(this, mt);
+   return gmx;
+}
+
+GeneralMatrix* RowedMatrix::Evaluate(MatrixType mt)
+{
+   gm = ((BaseMatrix*&)bm)->Evaluate();
+   GeneralMatrix* gmx = new RowVector; MatrixErrorNoSpace(gmx);
+   gmx->nrows = 1; gmx->ncols = gmx->storage = gm->storage;
+   return gm->BorrowStore(gmx,mt);
+}
+
+GeneralMatrix* ColedMatrix::Evaluate(MatrixType mt)
+{
+   gm = ((BaseMatrix*&)bm)->Evaluate();
+   GeneralMatrix* gmx = new ColumnVector; MatrixErrorNoSpace(gmx);
+   gmx->ncols = 1; gmx->nrows = gmx->storage = gm->storage;
+   return gm->BorrowStore(gmx,mt);
+}
+
+GeneralMatrix* DiagedMatrix::Evaluate(MatrixType mt)
+{
+   gm = ((BaseMatrix*&)bm)->Evaluate();
+   GeneralMatrix* gmx = new DiagonalMatrix; MatrixErrorNoSpace(gmx);
+   gmx->nrows = gmx->ncols = gmx->storage = gm->storage;
+   return gm->BorrowStore(gmx,mt);
+}
+
+GeneralMatrix* MatedMatrix::Evaluate(MatrixType mt)
+{
+   Tracer tr("MatedMatrix::Evaluate");
+   gm = ((BaseMatrix*&)bm)->Evaluate();
+   GeneralMatrix* gmx = new Matrix; MatrixErrorNoSpace(gmx);
+   gmx->nrows = nr; gmx->ncols = nc; gmx->storage = gm->storage;
+   if (nr*nc != gmx->storage)
+      Throw(IncompatibleDimensionsException());
+   return gm->BorrowStore(gmx,mt);
+}
+
+GeneralMatrix* GetSubMatrix::Evaluate(MatrixType mt)
+{
+   REPORT
+   Tracer tr("SubMatrix(evaluate)");
+   gm = ((BaseMatrix*&)bm)->Evaluate();
+   if (row_number < 0) row_number = gm->Nrows();
+   if (col_number < 0) col_number = gm->Ncols();
+   if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
+   {
+      gm->tDelete();
+      Throw(SubMatrixDimensionException());
+   }
+   if (IsSym) Compare(gm->Type().ssub(), mt);
+   else Compare(gm->Type().sub(), mt);
+   GeneralMatrix* gmx = mt.New(row_number, col_number, this);
+   int i = row_number;
+   MatrixRow mr(gm, LoadOnEntry, row_skip); 
+   MatrixRow mrx(gmx, StoreOnExit+DirectPart);
+   MatrixRowCol sub;
+   while (i--)
+   {
+      mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+      mrx.Copy(sub); mrx.Next(); mr.Next();
+   }
+   gmx->ReleaseAndDelete(); gm->tDelete();
+   return gmx;
+}
+
+
+GeneralMatrix* ReturnMatrix::Evaluate(MatrixType mt)
+{
+   return gm->Evaluate(mt);
+}
+
+
+void GeneralMatrix::Add(GeneralMatrix* gm1, Real f)
+{
+   REPORT
+   Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
+   while (i--)
+   { *s++ = *s1++ + f; *s++ = *s1++ + f; *s++ = *s1++ + f; *s++ = *s1++ + f; }
+   i = storage & 3; while (i--) *s++ = *s1++ + f;
+}
+   
+void GeneralMatrix::Add(Real f)
+{
+   REPORT
+   Real* s=store; int i=(storage >> 2);
+   while (i--) { *s++ += f; *s++ += f; *s++ += f; *s++ += f; }
+   i = storage & 3; while (i--) *s++ += f;
+}
+   
+void GeneralMatrix::NegAdd(GeneralMatrix* gm1, Real f)
+{
+   REPORT
+   Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
+   while (i--)
+   { *s++ = f - *s1++; *s++ = f - *s1++; *s++ = f - *s1++; *s++ = f - *s1++; }
+   i = storage & 3; while (i--) *s++ = f - *s1++;
+}
+   
+void GeneralMatrix::NegAdd(Real f)
+{
+   REPORT
+   Real* s=store; int i=(storage >> 2);
+   while (i--)
+   {
+      *s = f - *s; s++; *s = f - *s; s++;
+      *s = f - *s; s++; *s = f - *s; s++;
+   }
+   i = storage & 3; while (i--)  { *s = f - *s; s++; }
+}
+   
+void GeneralMatrix::Negate(GeneralMatrix* gm1)
+{
+   // change sign of elements
+   REPORT
+   Real* s1=gm1->store; Real* s=store; int i=(storage >> 2);
+   while (i--)
+   { *s++ = -(*s1++); *s++ = -(*s1++); *s++ = -(*s1++); *s++ = -(*s1++); }
+   i = storage & 3; while(i--) *s++ = -(*s1++);
+}
+   
+void GeneralMatrix::Negate()
+{
+   REPORT
+   Real* s=store; int i=(storage >> 2);
+   while (i--)
+   { *s = -(*s); s++; *s = -(*s); s++; *s = -(*s); s++; *s = -(*s); s++; }
+   i = storage & 3; while(i--) { *s = -(*s); s++; }
+}
+   
+void GeneralMatrix::Multiply(GeneralMatrix* gm1, Real f)
+{
+   REPORT
+   Real* s1=gm1->store; Real* s=store;  int i=(storage >> 2);
+   while (i--)
+   { *s++ = *s1++ * f; *s++ = *s1++ * f; *s++ = *s1++ * f; *s++ = *s1++ * f; }
+   i = storage & 3; while (i--) *s++ = *s1++ * f;
+}
+   
+void GeneralMatrix::Multiply(Real f)
+{
+   REPORT
+   Real* s=store; int i=(storage >> 2);
+   while (i--) { *s++ *= f; *s++ *= f; *s++ *= f; *s++ *= f; }
+   i = storage & 3; while (i--) *s++ *= f;
+}
+   
+
+/************************ MatrixInput routines ****************************/
+
+// int MatrixInput::n;          // number values still to be read
+// Real* MatrixInput::r;        // pointer to next location to be read to
+
+MatrixInput MatrixInput::operator<<(Real f)
+{
+   REPORT
+   Tracer et("MatrixInput");
+   if (n<=0) Throw(ProgramException("List of values too long"));
+   *r = f; int n1 = n-1; n=0;   // n=0 so we won't trigger exception
+   return MatrixInput(n1, r+1);
+}
+
+
+MatrixInput GeneralMatrix::operator<<(Real f)
+{
+   REPORT
+   Tracer et("MatrixInput");
+   int n = Storage();
+   if (n<=0) Throw(ProgramException("Loading data to zero length matrix"));
+   Real* r; r = Store(); *r = f; n--;
+   return MatrixInput(n, r+1);
+}
+
+MatrixInput GetSubMatrix::operator<<(Real f)
+{
+   REPORT
+   Tracer et("MatrixInput (GetSubMatrix)");
+   SetUpLHS();
+   if (row_number != 1 || col_skip != 0 || col_number != gm->Ncols())
+   {
+      Throw(ProgramException("MatrixInput requires complete rows"));
+   }
+   MatrixRow mr(gm, DirectPart, row_skip);  // to pick up location and length
+   int n = mr.Storage();
+   if (n<=0)
+   {
+      Throw(ProgramException("Loading data to zero length row"));
+   }
+   Real* r; r = mr.Data(); *r = f; n--;
+   if (+(mr.cw*HaveStore))
+   {
+      Throw(ProgramException("Fails with this matrix type"));
+   }
+   return MatrixInput(n, r+1);
+}
+
+MatrixInput::~MatrixInput()
+{
+   REPORT
+   Tracer et("MatrixInput");
+   if (n!=0) Throw(ProgramException("A list of values was too short"));
+}
+
+MatrixInput BandMatrix::operator<<(Real)
+{
+   Tracer et("MatrixInput");
+   bool dummy = true;
+   if (dummy)                                   // get rid of warning message
+      Throw(ProgramException("Cannot use list read with a BandMatrix"));
+   return MatrixInput(0, 0);
+}
+
+void BandMatrix::operator<<(const Real*)
+{ Throw(ProgramException("Cannot use array read with a BandMatrix")); }
+
+void BandMatrix::operator<<(const int*)
+{ Throw(ProgramException("Cannot use array read with a BandMatrix")); }
+
+void SymmetricBandMatrix::operator<<(const Real*)
+{ Throw(ProgramException("Cannot use array read with a BandMatrix")); }
+
+void SymmetricBandMatrix::operator<<(const int*)
+{ Throw(ProgramException("Cannot use array read with a BandMatrix")); }
+
+// ************************* Reverse order of elements ***********************
+
+void GeneralMatrix::ReverseElements(GeneralMatrix* gm)
+{
+   // reversing into a new matrix
+   REPORT
+   int n = Storage(); Real* rx = Store() + n; Real* x = gm->Store();
+   while (n--) *(--rx) = *(x++);
+}
+
+void GeneralMatrix::ReverseElements()
+{
+   // reversing in place
+   REPORT
+   int n = Storage(); Real* x = Store(); Real* rx = x + n;
+   n /= 2;
+   while (n--) { Real t = *(--rx); *rx = *x; *(x++) = t; }
+}
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat6.cpp b/Utilities/OSSIM/ossim_core/matrix/newmat6.cpp
new file mode 100644
index 0000000000..08b3b907d5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat6.cpp
@@ -0,0 +1,884 @@
+//$$ newmat6.cpp            Operators, element access, submatrices
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrc.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,6); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+/*************************** general utilities *************************/
+
+static int tristore(int n)                      // els in triangular matrix
+{ return (n*(n+1))/2; }
+
+
+/****************************** operators *******************************/
+
+Real& Matrix::operator()(int m, int n)
+{
+   REPORT
+   if (m<=0 || m>nrows || n<=0 || n>ncols)
+      Throw(IndexException(m,n,*this));
+   return store[(m-1)*ncols+n-1];
+}
+
+Real& SymmetricMatrix::operator()(int m, int n)
+{
+   REPORT
+   if (m<=0 || n<=0 || m>nrows || n>ncols)
+      Throw(IndexException(m,n,*this));
+   if (m>=n) return store[tristore(m-1)+n-1];
+   else return store[tristore(n-1)+m-1];
+}
+
+Real& UpperTriangularMatrix::operator()(int m, int n)
+{
+   REPORT
+   if (m<=0 || n<m || n>ncols)
+      Throw(IndexException(m,n,*this));
+   return store[(m-1)*ncols+n-1-tristore(m-1)];
+}
+
+Real& LowerTriangularMatrix::operator()(int m, int n)
+{
+   REPORT
+   if (n<=0 || m<n || m>nrows)
+      Throw(IndexException(m,n,*this));
+   return store[tristore(m-1)+n-1];
+}
+
+Real& DiagonalMatrix::operator()(int m, int n)
+{
+   REPORT
+   if (n<=0 || m!=n || m>nrows || n>ncols)
+      Throw(IndexException(m,n,*this));
+   return store[n-1];
+}
+
+Real& DiagonalMatrix::operator()(int m)
+{
+   REPORT
+   if (m<=0 || m>nrows) Throw(IndexException(m,*this));
+   return store[m-1];
+}
+
+Real& ColumnVector::operator()(int m)
+{
+   REPORT
+   if (m<=0 || m> nrows) Throw(IndexException(m,*this));
+   return store[m-1];
+}
+
+Real& RowVector::operator()(int n)
+{
+   REPORT
+   if (n<=0 || n> ncols) Throw(IndexException(n,*this));
+   return store[n-1];
+}
+
+Real& BandMatrix::operator()(int m, int n)
+{
+   REPORT
+   int w = upper+lower+1; int i = lower+n-m;
+   if (m<=0 || m>nrows || n<=0 || n>ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this));
+   return store[w*(m-1)+i];
+}
+
+Real& UpperBandMatrix::operator()(int m, int n)
+{
+   REPORT
+   int w = upper+1; int i = n-m;
+   if (m<=0 || m>nrows || n<=0 || n>ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this));
+   return store[w*(m-1)+i];
+}
+
+Real& LowerBandMatrix::operator()(int m, int n)
+{
+   REPORT
+   int w = lower+1; int i = lower+n-m;
+   if (m<=0 || m>nrows || n<=0 || n>ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this));
+   return store[w*(m-1)+i];
+}
+
+Real& SymmetricBandMatrix::operator()(int m, int n)
+{
+   REPORT
+   int w = lower+1;
+   if (m>=n)
+   {
+      REPORT
+      int i = lower+n-m;
+      if ( m>nrows || n<=0 || i<0 )
+         Throw(IndexException(m,n,*this));
+      return store[w*(m-1)+i];
+   }
+   else
+   {
+      REPORT
+      int i = lower+m-n;
+      if ( n>nrows || m<=0 || i<0 )
+         Throw(IndexException(m,n,*this));
+      return store[w*(n-1)+i];
+   }
+}
+
+
+Real Matrix::operator()(int m, int n) const
+{
+   REPORT
+   if (m<=0 || m>nrows || n<=0 || n>ncols)
+      Throw(IndexException(m,n,*this));
+   return store[(m-1)*ncols+n-1];
+}
+
+Real SymmetricMatrix::operator()(int m, int n) const
+{
+   REPORT
+   if (m<=0 || n<=0 || m>nrows || n>ncols)
+      Throw(IndexException(m,n,*this));
+   if (m>=n) return store[tristore(m-1)+n-1];
+   else return store[tristore(n-1)+m-1];
+}
+
+Real UpperTriangularMatrix::operator()(int m, int n) const
+{
+   REPORT
+   if (m<=0 || n<m || n>ncols)
+      Throw(IndexException(m,n,*this));
+   return store[(m-1)*ncols+n-1-tristore(m-1)];
+}
+
+Real LowerTriangularMatrix::operator()(int m, int n) const
+{
+   REPORT
+   if (n<=0 || m<n || m>nrows)
+      Throw(IndexException(m,n,*this));
+   return store[tristore(m-1)+n-1];
+}
+
+Real DiagonalMatrix::operator()(int m, int n) const
+{
+   REPORT
+   if (n<=0 || m!=n || m>nrows || n>ncols)
+      Throw(IndexException(m,n,*this));
+   return store[n-1];
+}
+
+Real DiagonalMatrix::operator()(int m) const
+{
+   REPORT
+   if (m<=0 || m>nrows) Throw(IndexException(m,*this));
+   return store[m-1];
+}
+
+Real ColumnVector::operator()(int m) const
+{
+   REPORT
+   if (m<=0 || m> nrows) Throw(IndexException(m,*this));
+   return store[m-1];
+}
+
+Real RowVector::operator()(int n) const
+{
+   REPORT
+   if (n<=0 || n> ncols) Throw(IndexException(n,*this));
+   return store[n-1];
+}
+
+Real BandMatrix::operator()(int m, int n) const
+{
+   REPORT
+   int w = upper+lower+1; int i = lower+n-m;
+   if (m<=0 || m>nrows || n<=0 || n>ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this));
+   return store[w*(m-1)+i];
+}
+
+Real UpperBandMatrix::operator()(int m, int n) const
+{
+   REPORT
+   int w = upper+1; int i = n-m;
+   if (m<=0 || m>nrows || n<=0 || n>ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this));
+   return store[w*(m-1)+i];
+}
+
+Real LowerBandMatrix::operator()(int m, int n) const
+{
+   REPORT
+   int w = lower+1; int i = lower+n-m;
+   if (m<=0 || m>nrows || n<=0 || n>ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this));
+   return store[w*(m-1)+i];
+}
+
+Real SymmetricBandMatrix::operator()(int m, int n) const
+{
+   REPORT
+   int w = lower+1;
+   if (m>=n)
+   {
+      REPORT
+      int i = lower+n-m;
+      if ( m>nrows || n<=0 || i<0 )
+         Throw(IndexException(m,n,*this));
+      return store[w*(m-1)+i];
+   }
+   else
+   {
+      REPORT
+      int i = lower+m-n;
+      if ( n>nrows || m<=0 || i<0 )
+         Throw(IndexException(m,n,*this));
+      return store[w*(n-1)+i];
+   }
+}
+
+
+Real BaseMatrix::AsScalar() const
+{
+   REPORT
+   GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+
+   if (gm->nrows!=1 || gm->ncols!=1)
+   {
+      Tracer tr("AsScalar");
+      Try
+         { Throw(ProgramException("Cannot convert to scalar", *gm)); }
+      CatchAll { gm->tDelete(); ReThrow; }
+   }
+
+   Real x = *(gm->store); gm->tDelete(); return x;
+}
+
+
+AddedMatrix BaseMatrix::operator+(const BaseMatrix& bm) const
+{ REPORT return AddedMatrix(this, &bm); }
+
+SPMatrix SP(const BaseMatrix& bm1,const BaseMatrix& bm2)
+{ REPORT return SPMatrix(&bm1, &bm2); }
+
+KPMatrix KP(const BaseMatrix& bm1,const BaseMatrix& bm2)
+{ REPORT return KPMatrix(&bm1, &bm2); }
+
+MultipliedMatrix BaseMatrix::operator*(const BaseMatrix& bm) const
+{ REPORT return MultipliedMatrix(this, &bm); }
+
+ConcatenatedMatrix BaseMatrix::operator|(const BaseMatrix& bm) const
+{ REPORT return ConcatenatedMatrix(this, &bm); }
+
+StackedMatrix BaseMatrix::operator&(const BaseMatrix& bm) const
+{ REPORT return StackedMatrix(this, &bm); }
+
+SolvedMatrix InvertedMatrix::operator*(const BaseMatrix& bmx) const
+{ REPORT return SolvedMatrix(bm, &bmx); }
+
+SubtractedMatrix BaseMatrix::operator-(const BaseMatrix& bm) const
+{ REPORT return SubtractedMatrix(this, &bm); }
+
+ShiftedMatrix BaseMatrix::operator+(Real f) const
+{ REPORT return ShiftedMatrix(this, f); }
+
+ShiftedMatrix operator+(Real f, const BaseMatrix& BM)
+{ REPORT return ShiftedMatrix(&BM, f); }
+
+NegShiftedMatrix operator-(Real f, const BaseMatrix& bm)
+{ REPORT return NegShiftedMatrix(f, &bm); }
+
+ScaledMatrix BaseMatrix::operator*(Real f) const
+{ REPORT return ScaledMatrix(this, f); }
+
+ScaledMatrix BaseMatrix::operator/(Real f) const
+{ REPORT return ScaledMatrix(this, 1.0/f); }
+
+ScaledMatrix operator*(Real f, const BaseMatrix& BM)
+{ REPORT return ScaledMatrix(&BM, f); }
+
+ShiftedMatrix BaseMatrix::operator-(Real f) const
+{ REPORT return ShiftedMatrix(this, -f); }
+
+TransposedMatrix BaseMatrix::t() const
+{ REPORT return TransposedMatrix(this); }
+
+NegatedMatrix BaseMatrix::operator-() const
+{ REPORT return NegatedMatrix(this); }
+
+ReversedMatrix BaseMatrix::Reverse() const
+{ REPORT return ReversedMatrix(this); }
+
+InvertedMatrix BaseMatrix::i() const
+{ REPORT return InvertedMatrix(this); }
+
+
+RowedMatrix BaseMatrix::AsRow() const
+{ REPORT return RowedMatrix(this); }
+
+ColedMatrix BaseMatrix::AsColumn() const
+{ REPORT return ColedMatrix(this); }
+
+DiagedMatrix BaseMatrix::AsDiagonal() const
+{ REPORT return DiagedMatrix(this); }
+
+MatedMatrix BaseMatrix::AsMatrix(int nrx, int ncx) const
+{ REPORT return MatedMatrix(this,nrx,ncx); }
+
+
+void GeneralMatrix::operator=(Real f)
+{ REPORT int i=storage; Real* s=store; while (i--) { *s++ = f; } }
+
+void Matrix::operator=(const BaseMatrix& X)
+{
+   REPORT //CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::Rt);
+} 
+
+void SquareMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT //CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::Rt);
+   if (nrows != ncols)
+      { Tracer tr("SquareMatrix(=)"); Throw(NotSquareException(*this)); }
+}
+
+void SquareMatrix::operator=(const Matrix& m)
+{
+   REPORT
+   if (m.nrows != m.ncols)
+      { Tracer tr("SquareMatrix(=Matrix)"); Throw(NotSquareException(*this)); }
+   Eq(m);
+}
+
+void RowVector::operator=(const BaseMatrix& X)
+{
+   REPORT  // CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::RV);
+   if (nrows!=1)
+      { Tracer tr("RowVector(=)"); Throw(VectorException(*this)); }
+}
+
+void ColumnVector::operator=(const BaseMatrix& X)
+{
+   REPORT //CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::CV);
+   if (ncols!=1)
+      { Tracer tr("ColumnVector(=)"); Throw(VectorException(*this)); }
+}
+
+void SymmetricMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT // CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::Sm);
+}
+
+void UpperTriangularMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT //CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::UT);
+}
+
+void LowerTriangularMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT //CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::LT);
+}
+
+void DiagonalMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT // CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::Dg);
+}
+
+void IdentityMatrix::operator=(const BaseMatrix& X)
+{
+   REPORT // CheckConversion(X);
+   // MatrixConversionCheck mcc;
+   Eq(X,MatrixType::Id);
+}
+
+void GeneralMatrix::operator<<(const Real* r)
+{
+   REPORT
+   int i = storage; Real* s=store;
+   while(i--) *s++ = *r++;
+}
+
+
+void GeneralMatrix::operator<<(const int* r)
+{
+   REPORT
+   int i = storage; Real* s=store;
+   while(i--) *s++ = *r++;
+}
+
+
+void GenericMatrix::operator=(const GenericMatrix& bmx)
+{
+   if (&bmx != this) { REPORT if (gm) delete gm; gm = bmx.gm->Image();}
+   else { REPORT }
+   gm->Protect();
+}
+
+void GenericMatrix::operator=(const BaseMatrix& bmx)
+{
+   if (gm)
+   {
+      int counter=bmx.search(gm);
+      if (counter==0) { REPORT delete gm; gm=0; }
+      else { REPORT gm->Release(counter); }
+   }
+   else { REPORT }
+   GeneralMatrix* gmx = ((BaseMatrix&)bmx).Evaluate();
+   if (gmx != gm) { REPORT if (gm) delete gm; gm = gmx->Image(); }
+   else { REPORT }
+   gm->Protect();
+}
+
+
+/*************************** += etc ***************************************/
+
+// will also need versions for SubMatrix
+
+
+
+// GeneralMatrix operators
+
+void GeneralMatrix::operator+=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GeneralMatrix::operator+=");
+   // MatrixConversionCheck mcc;
+   Protect();                                   // so it cannot get deleted
+						// during Evaluate
+   GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
+   AddedMatrix am(this,gm);
+   if (gm==this) Release(2); else Release();
+   Eq2(am,Type());
+}
+
+void GeneralMatrix::operator-=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GeneralMatrix::operator-=");
+   // MatrixConversionCheck mcc;
+   Protect();                                   // so it cannot get deleted
+						// during Evaluate
+   GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
+   SubtractedMatrix am(this,gm);
+   if (gm==this) Release(2); else Release();
+   Eq2(am,Type());
+}
+
+void GeneralMatrix::operator*=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GeneralMatrix::operator*=");
+   // MatrixConversionCheck mcc;
+   Protect();                                   // so it cannot get deleted
+						// during Evaluate
+   GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
+   MultipliedMatrix am(this,gm);
+   if (gm==this) Release(2); else Release();
+   Eq2(am,Type());
+}
+
+void GeneralMatrix::operator|=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GeneralMatrix::operator|=");
+   // MatrixConversionCheck mcc;
+   Protect();                                   // so it cannot get deleted
+						// during Evaluate
+   GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
+   ConcatenatedMatrix am(this,gm);
+   if (gm==this) Release(2); else Release();
+   Eq2(am,Type());
+}
+
+void GeneralMatrix::operator&=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GeneralMatrix::operator&=");
+   // MatrixConversionCheck mcc;
+   Protect();                                   // so it cannot get deleted
+						// during Evaluate
+   GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate();
+   StackedMatrix am(this,gm);
+   if (gm==this) Release(2); else Release();
+   Eq2(am,Type());
+}
+
+void GeneralMatrix::operator+=(Real r)
+{
+   REPORT
+   Tracer tr("GeneralMatrix::operator+=(Real)");
+   // MatrixConversionCheck mcc;
+   ShiftedMatrix am(this,r);
+   Release(); Eq2(am,Type());
+}
+
+void GeneralMatrix::operator*=(Real r)
+{
+   REPORT
+   Tracer tr("GeneralMatrix::operator*=(Real)");
+   // MatrixConversionCheck mcc;
+   ScaledMatrix am(this,r);
+   Release(); Eq2(am,Type());
+}
+
+
+// Generic matrix operators
+
+void GenericMatrix::operator+=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GenericMatrix::operator+=");
+   if (!gm) Throw(ProgramException("GenericMatrix is null"));
+   gm->Protect();            // so it cannot get deleted during Evaluate
+   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
+   AddedMatrix am(gm,gmx);
+   if (gmx==gm) gm->Release(2); else gm->Release();
+   GeneralMatrix* gmy = am.Evaluate();
+   if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
+   else { REPORT }
+   gm->Protect();
+}
+
+void GenericMatrix::operator-=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GenericMatrix::operator-=");
+   if (!gm) Throw(ProgramException("GenericMatrix is null"));
+   gm->Protect();            // so it cannot get deleted during Evaluate
+   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
+   SubtractedMatrix am(gm,gmx);
+   if (gmx==gm) gm->Release(2); else gm->Release();
+   GeneralMatrix* gmy = am.Evaluate();
+   if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
+   else { REPORT }
+   gm->Protect();
+}
+
+void GenericMatrix::operator*=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GenericMatrix::operator*=");
+   if (!gm) Throw(ProgramException("GenericMatrix is null"));
+   gm->Protect();            // so it cannot get deleted during Evaluate
+   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
+   MultipliedMatrix am(gm,gmx);
+   if (gmx==gm) gm->Release(2); else gm->Release();
+   GeneralMatrix* gmy = am.Evaluate();
+   if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
+   else { REPORT }
+   gm->Protect();
+}
+
+void GenericMatrix::operator|=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GenericMatrix::operator|=");
+   if (!gm) Throw(ProgramException("GenericMatrix is null"));
+   gm->Protect();            // so it cannot get deleted during Evaluate
+   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
+   ConcatenatedMatrix am(gm,gmx);
+   if (gmx==gm) gm->Release(2); else gm->Release();
+   GeneralMatrix* gmy = am.Evaluate();
+   if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
+   else { REPORT }
+   gm->Protect();
+}
+
+void GenericMatrix::operator&=(const BaseMatrix& X)
+{
+   REPORT
+   Tracer tr("GenericMatrix::operator&=");
+   if (!gm) Throw(ProgramException("GenericMatrix is null"));
+   gm->Protect();            // so it cannot get deleted during Evaluate
+   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate();
+   StackedMatrix am(gm,gmx);
+   if (gmx==gm) gm->Release(2); else gm->Release();
+   GeneralMatrix* gmy = am.Evaluate();
+   if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
+   else { REPORT }
+   gm->Protect();
+}
+
+void GenericMatrix::operator+=(Real r)
+{
+   REPORT
+   Tracer tr("GenericMatrix::operator+= (Real)");
+   if (!gm) Throw(ProgramException("GenericMatrix is null"));
+   ShiftedMatrix am(gm,r);
+   gm->Release();
+   GeneralMatrix* gmy = am.Evaluate();
+   if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
+   else { REPORT }
+   gm->Protect();
+}
+
+void GenericMatrix::operator*=(Real r)
+{
+   REPORT
+   Tracer tr("GenericMatrix::operator*= (Real)");
+   if (!gm) Throw(ProgramException("GenericMatrix is null"));
+   ScaledMatrix am(gm,r);
+   gm->Release();
+   GeneralMatrix* gmy = am.Evaluate();
+   if (gmy != gm) { REPORT delete gm; gm = gmy->Image(); }
+   else { REPORT }
+   gm->Protect();
+}
+
+
+/************************* element access *********************************/
+
+Real& Matrix::element(int m, int n)
+{
+   REPORT
+   if (m<0 || m>= nrows || n<0 || n>= ncols)
+      Throw(IndexException(m,n,*this,true));
+   return store[m*ncols+n];
+}
+
+Real Matrix::element(int m, int n) const
+{
+   REPORT
+   if (m<0 || m>= nrows || n<0 || n>= ncols)
+      Throw(IndexException(m,n,*this,true));
+   return store[m*ncols+n];
+}
+
+Real& SymmetricMatrix::element(int m, int n)
+{
+   REPORT
+   if (m<0 || n<0 || m >= nrows || n>=ncols)
+      Throw(IndexException(m,n,*this,true));
+   if (m>=n) return store[tristore(m)+n];
+   else return store[tristore(n)+m];
+}
+
+Real SymmetricMatrix::element(int m, int n) const
+{
+   REPORT
+   if (m<0 || n<0 || m >= nrows || n>=ncols)
+      Throw(IndexException(m,n,*this,true));
+   if (m>=n) return store[tristore(m)+n];
+   else return store[tristore(n)+m];
+}
+
+Real& UpperTriangularMatrix::element(int m, int n)
+{
+   REPORT
+   if (m<0 || n<m || n>=ncols)
+      Throw(IndexException(m,n,*this,true));
+   return store[m*ncols+n-tristore(m)];
+}
+
+Real UpperTriangularMatrix::element(int m, int n) const
+{
+   REPORT
+   if (m<0 || n<m || n>=ncols)
+      Throw(IndexException(m,n,*this,true));
+   return store[m*ncols+n-tristore(m)];
+}
+
+Real& LowerTriangularMatrix::element(int m, int n)
+{
+   REPORT
+   if (n<0 || m<n || m>=nrows)
+      Throw(IndexException(m,n,*this,true));
+   return store[tristore(m)+n];
+}
+
+Real LowerTriangularMatrix::element(int m, int n) const
+{
+   REPORT
+   if (n<0 || m<n || m>=nrows)
+      Throw(IndexException(m,n,*this,true));
+   return store[tristore(m)+n];
+}
+
+Real& DiagonalMatrix::element(int m, int n)
+{
+   REPORT
+   if (n<0 || m!=n || m>=nrows || n>=ncols)
+      Throw(IndexException(m,n,*this,true));
+   return store[n];
+}
+
+Real DiagonalMatrix::element(int m, int n) const
+{
+   REPORT
+   if (n<0 || m!=n || m>=nrows || n>=ncols)
+      Throw(IndexException(m,n,*this,true));
+   return store[n];
+}
+
+Real& DiagonalMatrix::element(int m)
+{
+   REPORT
+   if (m<0 || m>=nrows) Throw(IndexException(m,*this,true));
+   return store[m];
+}
+
+Real DiagonalMatrix::element(int m) const
+{
+   REPORT
+   if (m<0 || m>=nrows) Throw(IndexException(m,*this,true));
+   return store[m];
+}
+
+Real& ColumnVector::element(int m)
+{
+   REPORT
+   if (m<0 || m>= nrows) Throw(IndexException(m,*this,true));
+   return store[m];
+}
+
+Real ColumnVector::element(int m) const
+{
+   REPORT
+   if (m<0 || m>= nrows) Throw(IndexException(m,*this,true));
+   return store[m];
+}
+
+Real& RowVector::element(int n)
+{
+   REPORT
+   if (n<0 || n>= ncols)  Throw(IndexException(n,*this,true));
+   return store[n];
+}
+
+Real RowVector::element(int n) const
+{
+   REPORT
+   if (n<0 || n>= ncols)  Throw(IndexException(n,*this,true));
+   return store[n];
+}
+
+Real& BandMatrix::element(int m, int n)
+{
+   REPORT
+   int w = upper+lower+1; int i = lower+n-m;
+   if (m<0 || m>= nrows || n<0 || n>= ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this,true));
+   return store[w*m+i];
+}
+
+Real BandMatrix::element(int m, int n) const
+{
+   REPORT
+   int w = upper+lower+1; int i = lower+n-m;
+   if (m<0 || m>= nrows || n<0 || n>= ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this,true));
+   return store[w*m+i];
+}
+
+Real& UpperBandMatrix::element(int m, int n)
+{
+   REPORT
+   int w = upper+1; int i = n-m;
+   if (m<0 || m>= nrows || n<0 || n>= ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this,true));
+   return store[w*m+i];
+}
+
+Real UpperBandMatrix::element(int m, int n) const
+{
+   REPORT
+   int w = upper+1; int i = n-m;
+   if (m<0 || m>= nrows || n<0 || n>= ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this,true));
+   return store[w*m+i];
+}
+
+Real& LowerBandMatrix::element(int m, int n)
+{
+   REPORT
+   int w = lower+1; int i = lower+n-m;
+   if (m<0 || m>= nrows || n<0 || n>= ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this,true));
+   return store[w*m+i];
+}
+
+Real LowerBandMatrix::element(int m, int n) const
+{
+   REPORT
+   int w = lower+1; int i = lower+n-m;
+   if (m<0 || m>= nrows || n<0 || n>= ncols || i<0 || i>=w)
+      Throw(IndexException(m,n,*this,true));
+   return store[w*m+i];
+}
+
+Real& SymmetricBandMatrix::element(int m, int n)
+{
+   REPORT
+   int w = lower+1;
+   if (m>=n)
+   {
+      REPORT
+      int i = lower+n-m;
+      if ( m>=nrows || n<0 || i<0 )
+         Throw(IndexException(m,n,*this,true));
+      return store[w*m+i];
+   }
+   else
+   {
+      REPORT
+      int i = lower+m-n;
+      if ( n>=nrows || m<0 || i<0 )
+         Throw(IndexException(m,n,*this,true));
+      return store[w*n+i];
+   }
+}
+
+Real SymmetricBandMatrix::element(int m, int n) const
+{
+   REPORT
+   int w = lower+1;
+   if (m>=n)
+   {
+      REPORT
+      int i = lower+n-m;
+      if ( m>=nrows || n<0 || i<0 )
+         Throw(IndexException(m,n,*this,true));
+      return store[w*m+i];
+   }
+   else
+   {
+      REPORT
+      int i = lower+m-n;
+      if ( n>=nrows || m<0 || i<0 )
+         Throw(IndexException(m,n,*this,true));
+      return store[w*n+i];
+   }
+}
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat7.cpp b/Utilities/OSSIM/ossim_core/matrix/newmat7.cpp
new file mode 100644
index 0000000000..c82e1a853e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat7.cpp
@@ -0,0 +1,1037 @@
+//$$ newmat7.cpp     Invert, solve, binary operations
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrc.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,7); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+//***************************** solve routines ******************************/
+
+GeneralMatrix* GeneralMatrix::MakeSolver()
+{
+   REPORT
+   GeneralMatrix* gm = new CroutMatrix(*this);
+   MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
+}
+
+GeneralMatrix* Matrix::MakeSolver()
+{
+   REPORT
+   GeneralMatrix* gm = new CroutMatrix(*this);
+   MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;
+}
+
+void CroutMatrix::Solver(MatrixColX& mcout, const MatrixColX& mcin)
+{
+   REPORT
+   int i = mcin.skip; Real* el = mcin.data-i; Real* el1 = el;
+   while (i--) *el++ = 0.0;
+   el += mcin.storage; i = nrows - mcin.skip - mcin.storage;
+   while (i--) *el++ = 0.0;
+   lubksb(el1, mcout.skip);
+}
+
+
+// Do we need check for entirely zero output?
+
+void UpperTriangularMatrix::Solver(MatrixColX& mcout,
+   const MatrixColX& mcin)
+{
+   REPORT
+   int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
+   while (i-- > 0) *elx++ = 0.0;
+   int nr = mcin.skip+mcin.storage;
+   elx = mcin.data+mcin.storage; Real* el = elx;
+   int j = mcout.skip+mcout.storage-nr; int nc = ncols-nr; i = nr-mcout.skip;
+   while (j-- > 0) *elx++ = 0.0;
+   Real* Ael = store + (nr*(2*ncols-nr+1))/2; j = 0;
+   while (i-- > 0)
+   {
+      elx = el; Real sum = 0.0; int jx = j++; Ael -= nc;
+      while (jx--) sum += *(--Ael) * *(--elx);
+      elx--; *elx = (*elx - sum) / *(--Ael);
+   }
+}
+
+void LowerTriangularMatrix::Solver(MatrixColX& mcout,
+   const MatrixColX& mcin)
+{
+   REPORT
+   int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i;
+   while (i-- > 0) *elx++ = 0.0;
+   int nc = mcin.skip; i = nc+mcin.storage; elx = mcin.data+mcin.storage;
+   int nr = mcout.skip+mcout.storage; int j = nr-i; i = nr-nc;
+   while (j-- > 0) *elx++ = 0.0;
+   Real* el = mcin.data; Real* Ael = store + (nc*(nc+1))/2; j = 0;
+   while (i-- > 0)
+   {
+      elx = el; Real sum = 0.0; int jx = j++; Ael += nc;
+      while (jx--) sum += *Ael++ * *elx++;
+      *elx = (*elx - sum) / *Ael++;
+   }
+}
+
+//******************* carry out binary operations *************************/
+
+static GeneralMatrix*
+   GeneralMult(GeneralMatrix*,GeneralMatrix*,MultipliedMatrix*,MatrixType);
+static GeneralMatrix*
+   GeneralSolv(GeneralMatrix*,GeneralMatrix*,BaseMatrix*,MatrixType);
+static GeneralMatrix*
+   GeneralSolvI(GeneralMatrix*,BaseMatrix*,MatrixType);
+static GeneralMatrix*
+   GeneralKP(GeneralMatrix*,GeneralMatrix*,KPMatrix*,MatrixType);
+
+GeneralMatrix* MultipliedMatrix::Evaluate(MatrixType mt)
+{
+   REPORT
+   gm2 = ((BaseMatrix*&)bm2)->Evaluate();
+   gm2 = gm2->Evaluate(gm2->Type().MultRHS());     // no symmetric on RHS
+   gm1=((BaseMatrix*&)bm1)->Evaluate();
+   return GeneralMult(gm1, gm2, this, mt);
+}
+
+GeneralMatrix* SolvedMatrix::Evaluate(MatrixType mt)
+{
+   REPORT
+   gm1=((BaseMatrix*&)bm1)->Evaluate();
+   gm2=((BaseMatrix*&)bm2)->Evaluate();
+   return GeneralSolv(gm1,gm2,this,mt);
+}
+
+GeneralMatrix* KPMatrix::Evaluate(MatrixType mt)
+{
+   REPORT
+   gm1=((BaseMatrix*&)bm1)->Evaluate();
+   gm2=((BaseMatrix*&)bm2)->Evaluate();
+   return GeneralKP(gm1,gm2,this,mt);
+}
+
+// routines for adding or subtracting matrices of identical storage structure
+
+static void Add(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
+{
+   REPORT
+   Real* s1=gm1->Store(); Real* s2=gm2->Store();
+   Real* s=gm->Store(); int i=gm->Storage() >> 2;
+   while (i--)
+   {
+       *s++ = *s1++ + *s2++; *s++ = *s1++ + *s2++;
+       *s++ = *s1++ + *s2++; *s++ = *s1++ + *s2++;
+   }
+   i=gm->Storage() & 3; while (i--) *s++ = *s1++ + *s2++;
+}
+
+static void AddTo(GeneralMatrix* gm, const GeneralMatrix* gm2)
+{
+   REPORT
+   const Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2;
+   while (i--)
+   { *s++ += *s2++; *s++ += *s2++; *s++ += *s2++; *s++ += *s2++; }
+   i=gm->Storage() & 3; while (i--) *s++ += *s2++;
+}
+
+void GeneralMatrix::PlusEqual(const GeneralMatrix& gm)
+{
+   REPORT
+   if (nrows != gm.nrows || ncols != gm.ncols)
+      Throw(IncompatibleDimensionsException(*this, gm));
+   AddTo(this, &gm);
+}
+
+static void Subtract(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
+{
+   REPORT
+   Real* s1=gm1->Store(); Real* s2=gm2->Store();
+   Real* s=gm->Store(); int i=gm->Storage() >> 2;
+   while (i--)
+   {
+       *s++ = *s1++ - *s2++; *s++ = *s1++ - *s2++;
+       *s++ = *s1++ - *s2++; *s++ = *s1++ - *s2++;
+   }
+   i=gm->Storage() & 3; while (i--) *s++ = *s1++ - *s2++;
+}
+
+static void SubtractFrom(GeneralMatrix* gm, const GeneralMatrix* gm2)
+{
+   REPORT
+   const Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2;
+   while (i--)
+   { *s++ -= *s2++; *s++ -= *s2++; *s++ -= *s2++; *s++ -= *s2++; }
+   i=gm->Storage() & 3; while (i--) *s++ -= *s2++;
+}
+
+void GeneralMatrix::MinusEqual(const GeneralMatrix& gm)
+{
+   REPORT
+   if (nrows != gm.nrows || ncols != gm.ncols)
+      Throw(IncompatibleDimensionsException(*this, gm));
+   SubtractFrom(this, &gm);
+}
+
+static void ReverseSubtract(GeneralMatrix* gm, const GeneralMatrix* gm2)
+{
+   REPORT
+   const Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2;
+   while (i--)
+   {
+      *s = *s2++ - *s; s++; *s = *s2++ - *s; s++;
+      *s = *s2++ - *s; s++; *s = *s2++ - *s; s++;
+   }
+   i=gm->Storage() & 3; while (i--) { *s = *s2++ - *s; s++; }
+}
+
+static void SP(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
+{
+   REPORT
+   Real* s1=gm1->Store(); Real* s2=gm2->Store();
+   Real* s=gm->Store(); int i=gm->Storage() >> 2;
+   while (i--)
+   {
+       *s++ = *s1++ * *s2++; *s++ = *s1++ * *s2++;
+       *s++ = *s1++ * *s2++; *s++ = *s1++ * *s2++;
+   }
+   i=gm->Storage() & 3; while (i--) *s++ = *s1++ * *s2++;
+}
+
+static void SP(GeneralMatrix* gm, GeneralMatrix* gm2)
+{
+   REPORT
+   Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2;
+   while (i--)
+   { *s++ *= *s2++; *s++ *= *s2++; *s++ *= *s2++; *s++ *= *s2++; }
+   i=gm->Storage() & 3; while (i--) *s++ *= *s2++;
+}
+
+// routines for adding or subtracting matrices of different storage structure
+
+static void AddDS(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
+{
+   REPORT
+   int nr = gm->Nrows();
+   MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
+   MatrixRow mr(gm, StoreOnExit+DirectPart);
+   while (nr--) { mr.Add(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }
+}
+
+static void AddDS(GeneralMatrix* gm, GeneralMatrix* gm2)
+// Add into first argument
+{
+   REPORT
+   int nr = gm->Nrows();
+   MatrixRow mr(gm, StoreOnExit+LoadOnEntry+DirectPart);
+   MatrixRow mr2(gm2, LoadOnEntry);
+   while (nr--) { mr.Add(mr2); mr.Next(); mr2.Next(); }
+}
+
+static void SubtractDS
+   (GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
+{
+   REPORT
+   int nr = gm->Nrows();
+   MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
+   MatrixRow mr(gm, StoreOnExit+DirectPart);
+   while (nr--) { mr.Sub(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }
+}
+
+static void SubtractDS(GeneralMatrix* gm, GeneralMatrix* gm2)
+{
+   REPORT
+   int nr = gm->Nrows();
+   MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart);
+   MatrixRow mr2(gm2, LoadOnEntry);
+   while (nr--) { mr.Sub(mr2); mr.Next(); mr2.Next(); }
+}
+
+static void ReverseSubtractDS(GeneralMatrix* gm, GeneralMatrix* gm2)
+{
+   REPORT
+   int nr = gm->Nrows();
+   MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart);
+   MatrixRow mr2(gm2, LoadOnEntry);
+   while (nr--) { mr.RevSub(mr2); mr2.Next(); mr.Next(); }
+}
+
+static void SPDS(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2)
+{
+   REPORT
+   int nr = gm->Nrows();
+   MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
+   MatrixRow mr(gm, StoreOnExit+DirectPart);
+   while (nr--) { mr.Multiply(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }
+}
+
+static void SPDS(GeneralMatrix* gm, GeneralMatrix* gm2)
+// SP into first argument
+{
+   REPORT
+   int nr = gm->Nrows();
+   MatrixRow mr(gm, StoreOnExit+LoadOnEntry+DirectPart);
+   MatrixRow mr2(gm2, LoadOnEntry);
+   while (nr--) { mr.Multiply(mr2); mr.Next(); mr2.Next(); }
+}
+
+static GeneralMatrix* GeneralMult1(GeneralMatrix* gm1, GeneralMatrix* gm2,
+   MultipliedMatrix* mm, MatrixType mtx)
+{
+   REPORT
+   Tracer tr("GeneralMult1");
+   int nr=gm1->Nrows(); int nc=gm2->Ncols();
+   if (gm1->Ncols() !=gm2->Nrows())
+      Throw(IncompatibleDimensionsException(*gm1, *gm2));
+   GeneralMatrix* gmx = mtx.New(nr,nc,mm);
+
+   MatrixCol mcx(gmx, StoreOnExit+DirectPart);
+   MatrixCol mc2(gm2, LoadOnEntry);
+   while (nc--)
+   {
+      MatrixRow mr1(gm1, LoadOnEntry, mcx.Skip());
+      Real* el = mcx.Data();                         // pointer to an element
+      int n = mcx.Storage();
+      while (n--) { *(el++) = DotProd(mr1,mc2); mr1.Next(); }
+      mc2.Next(); mcx.Next();
+   }
+   gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
+}
+
+static GeneralMatrix* GeneralMult2(GeneralMatrix* gm1, GeneralMatrix* gm2,
+   MultipliedMatrix* mm, MatrixType mtx)
+{
+   // version that accesses by row only - not good for thin matrices
+   // or column vectors in right hand term.
+   REPORT
+   Tracer tr("GeneralMult2");
+   int nr=gm1->Nrows(); int nc=gm2->Ncols();
+   if (gm1->Ncols() !=gm2->Nrows())
+      Throw(IncompatibleDimensionsException(*gm1, *gm2));
+   GeneralMatrix* gmx = mtx.New(nr,nc,mm);
+
+   MatrixRow mrx(gmx, LoadOnEntry+StoreOnExit+DirectPart);
+   MatrixRow mr1(gm1, LoadOnEntry);
+   while (nr--)
+   {
+      MatrixRow mr2(gm2, LoadOnEntry, mr1.Skip());
+      Real* el = mr1.Data();                         // pointer to an element
+      int n = mr1.Storage();
+      mrx.Zero();
+      while (n--) { mrx.AddScaled(mr2, *el++); mr2.Next(); }
+      mr1.Next(); mrx.Next();
+   }
+   gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
+}
+
+static GeneralMatrix* mmMult(GeneralMatrix* gm1, GeneralMatrix* gm2)
+{
+   // matrix multiplication for type Matrix only
+   REPORT
+   Tracer tr("MatrixMult");
+
+   int nr=gm1->Nrows(); int ncr=gm1->Ncols(); int nc=gm2->Ncols();
+   if (ncr != gm2->Nrows()) Throw(IncompatibleDimensionsException(*gm1,*gm2));
+
+   Matrix* gm = new Matrix(nr,nc); MatrixErrorNoSpace(gm);
+
+   Real* s1=gm1->Store(); Real* s2=gm2->Store(); Real* s=gm->Store();
+
+   if (ncr)
+   {
+      while (nr--)
+      {
+         Real* s2x = s2; int j = ncr;
+         Real* sx = s; Real f = *s1++; int k = nc;
+         while (k--) *sx++ = f * *s2x++;
+         while (--j)
+            { sx = s; f = *s1++; k = nc; while (k--) *sx++ += f * *s2x++; }
+         s = sx;
+      }
+   }
+   else *gm = 0.0;
+
+   gm->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gm;
+}
+
+static GeneralMatrix* GeneralMult(GeneralMatrix* gm1, GeneralMatrix* gm2,
+   MultipliedMatrix* mm, MatrixType mtx)
+{
+   if ( Rectangular(gm1->Type(), gm2->Type(), mtx))
+   {
+      REPORT
+      return mmMult(gm1, gm2);
+   }
+   else
+   {
+      REPORT
+      Compare(gm1->Type() * gm2->Type(),mtx);
+      int nr = gm2->Nrows(); int nc = gm2->Ncols();
+      if (nc <= 5 && nr > nc)
+      {
+         REPORT
+         return GeneralMult1(gm1, gm2, mm, mtx);
+      }
+      else
+      {
+         REPORT
+         return GeneralMult2(gm1, gm2, mm, mtx);
+      }
+   }
+   return NULL;
+}
+
+static GeneralMatrix* GeneralKP(GeneralMatrix* gm1, GeneralMatrix* gm2,
+   KPMatrix* kp, MatrixType mtx)
+{
+   REPORT
+   Tracer tr("GeneralKP");
+   int nr1 = gm1->Nrows(); int nc1 = gm1->Ncols();
+   int nr2 = gm2->Nrows(); int nc2 = gm2->Ncols();
+   Compare((gm1->Type()).KP(gm2->Type()),mtx);
+   GeneralMatrix* gmx = mtx.New(nr1*nr2, nc1*nc2, kp);
+   MatrixRow mrx(gmx, LoadOnEntry+StoreOnExit+DirectPart);
+   MatrixRow mr1(gm1, LoadOnEntry);
+   for (int i = 1; i <= nr1; ++i)
+   {
+      MatrixRow mr2(gm2, LoadOnEntry);
+      for (int j = 1; j <= nr2; ++j)
+         { mrx.KP(mr1,mr2); mr2.Next(); mrx.Next(); }
+      mr1.Next();
+   }
+   gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
+}
+
+static GeneralMatrix* GeneralSolv(GeneralMatrix* gm1, GeneralMatrix* gm2,
+   BaseMatrix* sm, MatrixType mtx)
+{
+   REPORT
+   Tracer tr("GeneralSolv");
+   Compare(gm1->Type().i() * gm2->Type(),mtx);
+   int nr = gm1->Nrows();
+   if (nr != gm1->Ncols()) Throw(NotSquareException(*gm1));
+   int nc = gm2->Ncols();
+   if (gm1->Ncols() != gm2->Nrows())
+      Throw(IncompatibleDimensionsException(*gm1, *gm2));
+   GeneralMatrix* gmx = mtx.New(nr,nc,sm); MatrixErrorNoSpace(gmx);
+   Real* r = new Real [nr]; MatrixErrorNoSpace(r);
+   MONITOR_REAL_NEW("Make   (GenSolv)",nr,r)
+   GeneralMatrix* gms = gm1->MakeSolver();
+   Try
+   {
+
+      MatrixColX mcx(gmx, r, StoreOnExit+DirectPart);   // copy to and from r
+         // this must be inside Try so mcx is destroyed before gmx
+      MatrixColX mc2(gm2, r, LoadOnEntry);
+      while (nc--) { gms->Solver(mcx, mc2); mcx.Next(); mc2.Next(); }
+   }
+   CatchAll
+   {
+      if (gms) gms->tDelete();
+      delete gmx;                   // <--------------------
+      gm2->tDelete();
+      MONITOR_REAL_DELETE("Delete (GenSolv)",nr,r)
+                          // AT&T version 2.1 gives an internal error
+      delete [] r;
+      ReThrow;
+   }
+   gms->tDelete(); gmx->ReleaseAndDelete(); gm2->tDelete();
+   MONITOR_REAL_DELETE("Delete (GenSolv)",nr,r)
+                          // AT&T version 2.1 gives an internal error
+   delete [] r;
+   return gmx;
+}
+
+// version for inverses - gm2 is identity
+static GeneralMatrix* GeneralSolvI(GeneralMatrix* gm1, BaseMatrix* sm,
+   MatrixType mtx)
+{
+   REPORT
+   Tracer tr("GeneralSolvI");
+   Compare(gm1->Type().i(),mtx);
+   int nr = gm1->Nrows();
+   if (nr != gm1->Ncols()) Throw(NotSquareException(*gm1));
+   int nc = nr;
+   // DiagonalMatrix I(nr); I = 1;
+   IdentityMatrix I(nr);
+   GeneralMatrix* gmx = mtx.New(nr,nc,sm); MatrixErrorNoSpace(gmx);
+   Real* r = new Real [nr]; MatrixErrorNoSpace(r);
+   MONITOR_REAL_NEW("Make   (GenSolvI)",nr,r)
+   GeneralMatrix* gms = gm1->MakeSolver();
+   Try
+   {
+
+      MatrixColX mcx(gmx, r, StoreOnExit+DirectPart);   // copy to and from r
+         // this must be inside Try so mcx is destroyed before gmx
+      MatrixColX mc2(&I, r, LoadOnEntry);
+      while (nc--) { gms->Solver(mcx, mc2); mcx.Next(); mc2.Next(); }
+   }
+   CatchAll
+   {
+      if (gms) gms->tDelete();
+      delete gmx;
+      MONITOR_REAL_DELETE("Delete (GenSolvI)",nr,r)
+                          // AT&T version 2.1 gives an internal error
+      delete [] r;
+      ReThrow;
+   }
+   gms->tDelete(); gmx->ReleaseAndDelete();
+   MONITOR_REAL_DELETE("Delete (GenSolvI)",nr,r)
+                          // AT&T version 2.1 gives an internal error
+   delete [] r;
+   return gmx;
+}
+
+GeneralMatrix* InvertedMatrix::Evaluate(MatrixType mtx)
+{
+   // Matrix Inversion - use solve routines
+   Tracer tr("InvertedMatrix::Evaluate");
+   REPORT
+   gm=((BaseMatrix*&)bm)->Evaluate();
+   return GeneralSolvI(gm,this,mtx);
+}
+
+//*************************** New versions ************************
+
+GeneralMatrix* AddedMatrix::Evaluate(MatrixType mtd)
+{
+   REPORT
+   Tracer tr("AddedMatrix::Evaluate");
+   gm1=((BaseMatrix*&)bm1)->Evaluate(); gm2=((BaseMatrix*&)bm2)->Evaluate();
+   int nr=gm1->Nrows(); int nc=gm1->Ncols();
+   if (nr!=gm2->Nrows() || nc!=gm2->Ncols())
+   {
+      Try { Throw(IncompatibleDimensionsException(*gm1, *gm2)); }
+      CatchAll
+      {
+         gm1->tDelete(); gm2->tDelete();
+         ReThrow;
+      }
+   }
+   MatrixType mt1 = gm1->Type(), mt2 = gm2->Type(); MatrixType mts = mt1 + mt2;
+   if (!mtd) { REPORT mtd = mts; }
+   else if (!(mtd.DataLossOK || mtd >= mts))
+   {
+      REPORT
+      gm1->tDelete(); gm2->tDelete();
+      Throw(ProgramException("Illegal Conversion", mts, mtd));
+   }
+   GeneralMatrix* gmx;
+   bool c1 = (mtd == mt1), c2 = (mtd == mt2);
+   if ( c1 && c2 && (gm1->SimpleAddOK(gm2) == 0) )
+   {
+      if (gm1->reuse()) { REPORT AddTo(gm1,gm2); gm2->tDelete(); gmx = gm1; }
+      else if (gm2->reuse()) { REPORT AddTo(gm2,gm1); gmx = gm2; }
+      else
+      {
+         REPORT
+         // what if new throws an exception
+         Try { gmx = mt1.New(nr,nc,this); }
+         CatchAll
+         {
+            ReThrow;
+         }
+         gmx->ReleaseAndDelete(); Add(gmx,gm1,gm2);
+      }
+   }
+   else
+   {
+      if (c1 && c2)
+      {
+         short SAO = gm1->SimpleAddOK(gm2);
+         if (SAO & 1) { REPORT c1 = false; }
+         if (SAO & 2) { REPORT c2 = false; }
+      }
+      if (c1 && gm1->reuse() )               // must have type test first
+         { REPORT AddDS(gm1,gm2); gm2->tDelete(); gmx = gm1; }
+      else if (c2 && gm2->reuse() )
+         { REPORT AddDS(gm2,gm1); if (!c1) gm1->tDelete(); gmx = gm2; }
+      else
+      {
+         REPORT
+         Try { gmx = mtd.New(nr,nc,this); }
+         CatchAll
+         {
+            if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
+            ReThrow;
+         }
+         AddDS(gmx,gm1,gm2);
+         if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
+         gmx->ReleaseAndDelete();
+      }
+   }
+   return gmx;
+}
+
+GeneralMatrix* SubtractedMatrix::Evaluate(MatrixType mtd)
+{
+   REPORT
+   Tracer tr("SubtractedMatrix::Evaluate");
+   gm1=((BaseMatrix*&)bm1)->Evaluate(); gm2=((BaseMatrix*&)bm2)->Evaluate();
+   int nr=gm1->Nrows(); int nc=gm1->Ncols();
+   if (nr!=gm2->Nrows() || nc!=gm2->Ncols())
+   {
+      Try { Throw(IncompatibleDimensionsException(*gm1, *gm2)); }
+      CatchAll
+      {
+         gm1->tDelete(); gm2->tDelete();
+         ReThrow;
+      }
+   }
+   MatrixType mt1 = gm1->Type(), mt2 = gm2->Type(); MatrixType mts = mt1 + mt2;
+   if (!mtd) { REPORT mtd = mts; }
+   else if (!(mtd.DataLossOK || mtd >= mts))
+   {
+      gm1->tDelete(); gm2->tDelete();
+      Throw(ProgramException("Illegal Conversion", mts, mtd));
+   }
+   GeneralMatrix* gmx;
+   bool c1 = (mtd == mt1), c2 = (mtd == mt2);
+   if ( c1 && c2 && (gm1->SimpleAddOK(gm2) == 0) )
+   {
+      if (gm1->reuse())
+         { REPORT SubtractFrom(gm1,gm2); gm2->tDelete(); gmx = gm1; }
+      else if (gm2->reuse()) { REPORT ReverseSubtract(gm2,gm1); gmx = gm2; }
+      else
+      {
+         REPORT
+         Try { gmx = mt1.New(nr,nc,this); }
+         CatchAll
+         {
+            ReThrow;
+         }
+         gmx->ReleaseAndDelete(); Subtract(gmx,gm1,gm2);
+      }
+   }
+   else
+   {
+      if (c1 && c2)
+      {
+         short SAO = gm1->SimpleAddOK(gm2);
+         if (SAO & 1) { REPORT c1 = false; }
+         if (SAO & 2) { REPORT c2 = false; }
+      }
+      if (c1 && gm1->reuse() )               // must have type test first
+         { REPORT SubtractDS(gm1,gm2); gm2->tDelete(); gmx = gm1; }
+      else if (c2 && gm2->reuse() )
+      {
+         REPORT ReverseSubtractDS(gm2,gm1);
+         if (!c1) gm1->tDelete(); gmx = gm2;
+      }
+      else
+      {
+         REPORT
+         // what if New throws and exception
+         Try { gmx = mtd.New(nr,nc,this); }
+         CatchAll
+         {
+            if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
+            ReThrow;
+         }
+         SubtractDS(gmx,gm1,gm2);
+         if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
+         gmx->ReleaseAndDelete();
+      }
+   }
+   return gmx;
+}
+
+GeneralMatrix* SPMatrix::Evaluate(MatrixType mtd)
+{
+   REPORT
+   Tracer tr("SPMatrix::Evaluate");
+   gm1=((BaseMatrix*&)bm1)->Evaluate(); gm2=((BaseMatrix*&)bm2)->Evaluate();
+   int nr=gm1->Nrows(); int nc=gm1->Ncols();
+   if (nr!=gm2->Nrows() || nc!=gm2->Ncols())
+   {
+      Try { Throw(IncompatibleDimensionsException(*gm1, *gm2)); }
+      CatchAll
+      {
+         gm1->tDelete(); gm2->tDelete();
+         ReThrow;
+      }
+   }
+   MatrixType mt1 = gm1->Type(), mt2 = gm2->Type();
+   MatrixType mts = mt1.SP(mt2);
+   if (!mtd) { REPORT mtd = mts; }
+   else if (!(mtd.DataLossOK || mtd >= mts))
+   {
+      gm1->tDelete(); gm2->tDelete();
+      Throw(ProgramException("Illegal Conversion", mts, mtd));
+   }
+   GeneralMatrix* gmx;
+   bool c1 = (mtd == mt1), c2 = (mtd == mt2);
+   if ( c1 && c2 && (gm1->SimpleAddOK(gm2) == 0) )
+   {
+      if (gm1->reuse()) { REPORT SP(gm1,gm2); gm2->tDelete(); gmx = gm1; }
+      else if (gm2->reuse()) { REPORT SP(gm2,gm1); gmx = gm2; }
+      else
+      {
+         REPORT
+         Try { gmx = mt1.New(nr,nc,this); }
+         CatchAll
+         {
+            ReThrow;
+         }
+         gmx->ReleaseAndDelete(); SP(gmx,gm1,gm2);
+      }
+   }
+   else
+   {
+      if (c1 && c2)
+      {
+         short SAO = gm1->SimpleAddOK(gm2);
+         if (SAO & 1) { REPORT c2 = false; }    // c1 and c2 swapped
+         if (SAO & 2) { REPORT c1 = false; }
+      }
+      if (c1 && gm1->reuse() )               // must have type test first
+         { REPORT SPDS(gm1,gm2); gm2->tDelete(); gmx = gm1; }
+      else if (c2 && gm2->reuse() )
+         { REPORT SPDS(gm2,gm1); if (!c1) gm1->tDelete(); gmx = gm2; }
+      else
+      {
+         REPORT
+         // what if New throws and exception
+         Try { gmx = mtd.New(nr,nc,this); }
+         CatchAll
+         {
+            if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
+            ReThrow;
+         }
+         SPDS(gmx,gm1,gm2);
+         if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
+         gmx->ReleaseAndDelete();
+      }
+   }
+   return gmx;
+}
+
+
+
+//*************************** norm functions ****************************/
+
+Real BaseMatrix::Norm1() const
+{
+   // maximum of sum of absolute values of a column
+   REPORT
+   GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   int nc = gm->Ncols(); Real value = 0.0;
+   MatrixCol mc(gm, LoadOnEntry);
+   while (nc--)
+      { Real v = mc.SumAbsoluteValue(); if (value < v) value = v; mc.Next(); }
+   gm->tDelete(); return value;
+}
+
+Real BaseMatrix::NormInfinity() const
+{
+   // maximum of sum of absolute values of a row
+   REPORT
+   GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   int nr = gm->Nrows(); Real value = 0.0;
+   MatrixRow mr(gm, LoadOnEntry);
+   while (nr--)
+      { Real v = mr.SumAbsoluteValue(); if (value < v) value = v; mr.Next(); }
+   gm->tDelete(); return value;
+}
+
+//********************** Concatenation and stacking *************************/
+
+GeneralMatrix* ConcatenatedMatrix::Evaluate(MatrixType mtx)
+{
+   REPORT
+   Tracer tr("Concatenate");
+      gm2 = ((BaseMatrix*&)bm2)->Evaluate();
+      gm1 = ((BaseMatrix*&)bm1)->Evaluate();
+      Compare(gm1->Type() | gm2->Type(),mtx);
+      int nr=gm1->Nrows(); int nc = gm1->Ncols() + gm2->Ncols();
+      if (nr != gm2->Nrows())
+         Throw(IncompatibleDimensionsException(*gm1, *gm2));
+      GeneralMatrix* gmx = mtx.New(nr,nc,this);
+      MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
+      MatrixRow mr(gmx, StoreOnExit+DirectPart);
+      while (nr--) { mr.ConCat(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }
+      gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
+}
+
+GeneralMatrix* StackedMatrix::Evaluate(MatrixType mtx)
+{
+   REPORT
+   Tracer tr("Stack");
+      gm2 = ((BaseMatrix*&)bm2)->Evaluate();
+      gm1 = ((BaseMatrix*&)bm1)->Evaluate();
+      Compare(gm1->Type() & gm2->Type(),mtx);
+      int nc=gm1->Ncols();
+      int nr1 = gm1->Nrows(); int nr2 = gm2->Nrows();
+      if (nc != gm2->Ncols())
+         Throw(IncompatibleDimensionsException(*gm1, *gm2));
+      GeneralMatrix* gmx = mtx.New(nr1+nr2,nc,this);
+      MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry);
+      MatrixRow mr(gmx, StoreOnExit+DirectPart);
+      while (nr1--) { mr.Copy(mr1); mr1.Next(); mr.Next(); }
+      while (nr2--) { mr.Copy(mr2); mr2.Next(); mr.Next(); }
+      gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;
+}
+
+// ************************* equality of matrices ******************** //
+
+static bool RealEqual(Real* s1, Real* s2, int n)
+{
+   int i = n >> 2;
+   while (i--)
+   {
+      if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
+      if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
+   }
+   i = n & 3; while (i--) if (*s1++ != *s2++) return false;
+   return true;
+}
+
+static bool intEqual(int* s1, int* s2, int n)
+{
+   int i = n >> 2;
+   while (i--)
+   {
+      if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
+      if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
+   }
+   i = n & 3; while (i--) if (*s1++ != *s2++) return false;
+   return true;
+}
+
+
+bool operator==(const BaseMatrix& A, const BaseMatrix& B)
+{
+   Tracer tr("BaseMatrix ==");
+   REPORT
+   GeneralMatrix* gmA = ((BaseMatrix&)A).Evaluate();
+   GeneralMatrix* gmB = ((BaseMatrix&)B).Evaluate();
+
+   if (gmA == gmB)                            // same matrix
+      { REPORT gmA->tDelete(); return true; }
+
+   if ( gmA->Nrows() != gmB->Nrows() || gmA->Ncols() != gmB->Ncols() )
+                                              // different dimensions
+      { REPORT gmA->tDelete(); gmB->tDelete(); return false; }
+
+   // check for CroutMatrix or BandLUMatrix
+   MatrixType AType = gmA->Type(); MatrixType BType = gmB->Type();
+   if (AType.CannotConvert() || BType.CannotConvert() )
+   {
+      REPORT
+      bool bx = gmA->IsEqual(*gmB);
+      gmA->tDelete(); gmB->tDelete();
+      return bx;
+   }
+
+   // is matrix storage the same
+   // will need to modify if further matrix structures are introduced
+   if (AType == BType && gmA->BandWidth() == gmB->BandWidth())
+   {                                          // compare store
+      REPORT
+      bool bx = RealEqual(gmA->Store(),gmB->Store(),gmA->Storage());
+      gmA->tDelete(); gmB->tDelete();
+      return bx;
+   }
+
+   // matrix storage different - just subtract
+   REPORT  return IsZero(*gmA-*gmB);
+}
+
+bool operator==(const GeneralMatrix& A, const GeneralMatrix& B)
+{
+   Tracer tr("GeneralMatrix ==");
+   // May or may not call tDeletes
+   REPORT
+
+   if (&A == &B)                              // same matrix
+      { REPORT return true; }
+
+   if ( A.Nrows() != B.Nrows() || A.Ncols() != B.Ncols() )
+      { REPORT return false; }                // different dimensions
+
+   // check for CroutMatrix or BandLUMatrix
+   MatrixType AType = A.Type(); MatrixType BType = B.Type();
+   if (AType.CannotConvert() || BType.CannotConvert() )
+      { REPORT  return A.IsEqual(B); }
+
+   // is matrix storage the same
+   // will need to modify if further matrix structures are introduced
+   if (AType == BType && A.BandWidth() == B.BandWidth())
+      { REPORT return RealEqual(A.Store(),B.Store(),A.Storage()); }
+
+   // matrix storage different - just subtract
+   REPORT  return IsZero(A-B);
+}
+
+bool GeneralMatrix::IsZero() const
+{
+   REPORT
+   Real* s=store; int i = storage >> 2;
+   while (i--)
+   {
+      if (*s++) return false; if (*s++) return false;
+      if (*s++) return false; if (*s++) return false;
+   }
+   i = storage & 3; while (i--) if (*s++) return false;
+   return true;
+}
+
+bool IsZero(const BaseMatrix& A)
+{
+   Tracer tr("BaseMatrix::IsZero");
+   REPORT
+   GeneralMatrix* gm1 = 0; bool bx;
+   Try { gm1=((BaseMatrix&)A).Evaluate(); bx = gm1->IsZero(); }
+   CatchAll { if (gm1) gm1->tDelete(); ReThrow; }
+   gm1->tDelete();
+   return bx;
+}
+
+// IsEqual functions - insist matrices are of same type
+// as well as equal values to be equal
+
+bool GeneralMatrix::IsEqual(const GeneralMatrix& A) const
+{
+   Tracer tr("GeneralMatrix IsEqual");
+   if (A.Type() != Type())                       // not same types
+      { REPORT return false; }
+   if (&A == this)                               // same matrix
+      { REPORT  return true; }
+   if (A.nrows != nrows || A.ncols != ncols)
+                                                 // different dimensions
+   { REPORT return false; }
+   // is matrix storage the same - compare store
+   REPORT
+   return RealEqual(A.store,store,storage);
+}
+
+bool CroutMatrix::IsEqual(const GeneralMatrix& A) const
+{
+   Tracer tr("CroutMatrix IsEqual");
+   if (A.Type() != Type())                       // not same types
+      { REPORT return false; }
+   if (&A == this)                               // same matrix
+      { REPORT  return true; }
+   if (A.nrows != nrows || A.ncols != ncols)
+                                                 // different dimensions
+   { REPORT return false; }
+   // is matrix storage the same - compare store
+   REPORT
+   return RealEqual(A.store,store,storage)
+      && intEqual(((CroutMatrix&)A).indx, indx, nrows);
+}
+
+
+bool BandLUMatrix::IsEqual(const GeneralMatrix& A) const
+{
+   Tracer tr("BandLUMatrix IsEqual");
+   if (A.Type() != Type())                       // not same types
+      { REPORT  return false; }
+   if (&A == this)                               // same matrix
+      { REPORT  return true; }
+   if ( A.Nrows() != nrows || A.Ncols() != ncols
+      || ((BandLUMatrix&)A).m1 != m1 || ((BandLUMatrix&)A).m2 != m2 )
+                                                 // different dimensions
+   { REPORT  return false; }
+
+   // matrix storage the same - compare store
+   REPORT
+   return RealEqual(A.Store(),store,storage)
+      && RealEqual(((BandLUMatrix&)A).store2,store2,storage2)
+      && intEqual(((BandLUMatrix&)A).indx, indx, nrows);
+}
+
+
+// ************************* cross products ******************** //
+
+inline void CrossProductBody(Real* a, Real* b, Real* c)
+{
+   c[0] = a[1] * b[2] - a[2] * b[1];
+   c[1] = a[2] * b[0] - a[0] * b[2];
+   c[2] = a[0] * b[1] - a[1] * b[0];
+}
+
+Matrix CrossProduct(const Matrix& A, const Matrix& B)
+{
+   REPORT
+   int ac = A.Ncols(); int ar = A.Nrows();
+   int bc = B.Ncols(); int br = B.Nrows();
+   Real* a = A.Store(); Real* b = B.Store();
+   if (ac == 3)
+   {
+      if (bc != 3 || ar != 1 || br != 1)
+         { Tracer et("CrossProduct"); IncompatibleDimensionsException(A, B); }
+      REPORT
+      RowVector C(3);  Real* c = C.Store(); CrossProductBody(a, b, c);
+      return C;
+   }
+   else
+   {
+      if (ac != 1 || bc != 1 || ar != 3 || br != 3)
+         { Tracer et("CrossProduct"); IncompatibleDimensionsException(A, B); }
+      REPORT
+      ColumnVector C(3);  Real* c = C.Store(); CrossProductBody(a, b, c);
+      return C;
+   }
+}
+
+ReturnMatrix CrossProductRows(const Matrix& A, const Matrix& B)
+{
+   REPORT
+   int n = A.Nrows();
+   if (A.Ncols() != 3 || B.Ncols() != 3 || n != B.Nrows())
+      { Tracer et("CrossProductRows"); IncompatibleDimensionsException(A, B); }
+   Matrix C(n, 3);
+   Real* a = A.Store(); Real* b = B.Store(); Real* c = C.Store();
+   if (n--)
+   {
+      for (;;)
+      {
+         CrossProductBody(a, b, c);
+         if (!(n--)) break;
+         a += 3; b += 3; c += 3;
+      }
+   }
+
+   return C.ForReturn();
+}
+
+ReturnMatrix CrossProductColumns(const Matrix& A, const Matrix& B)
+{
+   REPORT
+   int n = A.Ncols();
+   if (A.Nrows() != 3 || B.Nrows() != 3 || n != B.Ncols())
+      { Tracer et("CrossProductColumns"); IncompatibleDimensionsException(A, B); }
+   Matrix C(3, n);
+   Real* a = A.Store(); Real* b = B.Store(); Real* c = C.Store();
+   Real* an = a+n; Real* an2 = an+n;
+   Real* bn = b+n; Real* bn2 = bn+n;
+   Real* cn = c+n; Real* cn2 = cn+n;
+
+   int i = n; 
+   while (i--)
+   {
+      *c++   = *an    * *bn2   - *an2   * *bn;
+      *cn++  = *an2++ * *b     - *a     * *bn2++;
+      *cn2++ = *a++   * *bn++  - *an++  * *b++;
+   }
+
+   return C.ForReturn();
+}
+
+
+#ifdef use_namespace
+}
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat8.cpp b/Utilities/OSSIM/ossim_core/matrix/newmat8.cpp
new file mode 100644
index 0000000000..ca9842afb6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat8.cpp
@@ -0,0 +1,734 @@
+//$$ newmat8.cpp         Advanced LU transform, scalar functions
+
+// Copyright (C) 1991,2,3,4,8: R B Davies
+
+#define WANT_MATH
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrc.h"
+#include "precisio.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,8); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+/************************** LU transformation ****************************/
+
+void CroutMatrix::ludcmp()
+// LU decomposition from Golub & Van Loan, algorithm 3.4.1, (the "outer
+// product" version).
+// This replaces the code derived from Numerical Recipes in C in previous
+// versions of newmat and being row oriented runs much faster with large
+// matrices.
+{
+   REPORT
+   Tracer trace( "Crout(ludcmp)" ); sing = false;
+   Real* akk = store;                    // runs down diagonal
+
+   Real big = fabs(*akk); int mu = 0; Real* ai = akk; int k;
+
+   for (k = 1; k < nrows; k++)
+   {
+      ai += nrows; const Real trybig = fabs(*ai);
+      if (big < trybig) { big = trybig; mu = k; }
+   }
+
+
+   if (nrows) for (k = 0;;)
+   {
+      /*
+      int mu1;
+      {
+         Real big = fabs(*akk); mu1 = k; Real* ai = akk; int i;
+
+         for (i = k+1; i < nrows; i++)
+         {
+            ai += nrows; const Real trybig = fabs(*ai);
+            if (big < trybig) { big = trybig; mu1 = i; }
+         }
+      }
+      if (mu1 != mu) cout << k << " " << mu << " " << mu1 << endl;
+      */
+
+      indx[k] = mu;
+
+      if (mu != k)                       //row swap
+      {
+         Real* a1 = store + nrows * k; Real* a2 = store + nrows * mu; d = !d;
+         int j = nrows;
+         while (j--) { const Real temp = *a1; *a1++ = *a2; *a2++ = temp; }
+      }
+
+      Real diag = *akk; big = 0; mu = k + 1;
+      if (diag != 0)
+      {
+         ai = akk; int i = nrows - k - 1;
+         while (i--)
+         {
+            ai += nrows; Real* al = ai; Real mult = *al / diag; *al = mult;
+            int l = nrows - k - 1; Real* aj = akk;
+            // work out the next pivot as part of this loop
+            // this saves a column operation
+            if (l-- != 0)
+            {
+               *(++al) -= (mult * *(++aj));
+               const Real trybig = fabs(*al);
+               if (big < trybig) { big = trybig; mu = nrows - i - 1; }
+               while (l--) *(++al) -= (mult * *(++aj));
+            }
+         }
+      }
+      else sing = true;
+      if (++k == nrows) break;          // so next line won't overflow
+      akk += nrows + 1;
+   }
+}
+
+void CroutMatrix::lubksb(Real* B, int mini)
+{
+   REPORT
+   // this has been adapted from Numerical Recipes in C. The code has been
+   // substantially streamlined, so I do not think much of the original
+   // copyright remains. However there is not much opportunity for
+   // variation in the code, so it is still similar to the NR code.
+   // I follow the NR code in skipping over initial zeros in the B vector.
+
+   Tracer trace("Crout(lubksb)");
+   if (sing) Throw(SingularException(*this));
+   int i, j, ii = nrows;            // ii initialised : B might be all zeros
+
+
+   // scan for first non-zero in B
+   for (i = 0; i < nrows; i++)
+   {
+      int ip = indx[i]; Real temp = B[ip]; B[ip] = B[i]; B[i] = temp;
+      if (temp != 0.0) { ii = i; break; }
+   }
+
+   Real* bi; Real* ai;
+   i = ii + 1;
+
+   if (i < nrows)
+   {
+      bi = B + ii; ai = store + ii + i * nrows;
+      for (;;)
+      {
+         int ip = indx[i]; Real sum = B[ip]; B[ip] = B[i];
+         Real* aij = ai; Real* bj = bi; j = i - ii;
+         while (j--) sum -= *aij++ * *bj++;
+         B[i] = sum;
+         if (++i == nrows) break;
+         ai += nrows;
+      }
+   }
+
+   ai = store + nrows * nrows;
+
+   for (i = nrows - 1; i >= mini; i--)
+   {
+      Real* bj = B+i; ai -= nrows; Real* ajx = ai+i;
+      Real sum = *bj; Real diag = *ajx;
+      j = nrows - i; while(--j) sum -= *(++ajx) * *(++bj);
+      B[i] = sum / diag;
+   }
+}
+
+/****************************** scalar functions ****************************/
+
+inline Real square(Real x) { return x*x; }
+
+Real GeneralMatrix::SumSquare() const
+{
+   REPORT
+   Real sum = 0.0; int i = storage; Real* s = store;
+   while (i--) sum += square(*s++);
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+Real GeneralMatrix::SumAbsoluteValue() const
+{
+   REPORT
+   Real sum = 0.0; int i = storage; Real* s = store;
+   while (i--) sum += fabs(*s++);
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+Real GeneralMatrix::Sum() const
+{
+   REPORT
+   Real sum = 0.0; int i = storage; Real* s = store;
+   while (i--) sum += *s++;
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+// maxima and minima
+
+// There are three sets of routines
+// MaximumAbsoluteValue, MinimumAbsoluteValue, Maximum, Minimum
+// ... these find just the maxima and minima
+// MaximumAbsoluteValue1, MinimumAbsoluteValue1, Maximum1, Minimum1
+// ... these find the maxima and minima and their locations in a
+//     one dimensional object
+// MaximumAbsoluteValue2, MinimumAbsoluteValue2, Maximum2, Minimum2
+// ... these find the maxima and minima and their locations in a
+//     two dimensional object
+
+// If the matrix has no values throw an exception
+
+// If we do not want the location find the maximum or minimum on the
+// array stored by GeneralMatrix
+// This won't work for BandMatrices. We call ClearCorner for
+// MaximumAbsoluteValue but for the others use the AbsoluteMinimumValue2
+// version and discard the location.
+
+// For one dimensional objects, when we want the location of the
+// maximum or minimum, work with the array stored by GeneralMatrix
+
+// For two dimensional objects where we want the location of the maximum or
+// minimum proceed as follows:
+
+// For rectangular matrices use the array stored by GeneralMatrix and
+// deduce the location from the location in the GeneralMatrix
+
+// For other two dimensional matrices use the Matrix Row routine to find the
+// maximum or minimum for each row.
+
+static void NullMatrixError(const GeneralMatrix* gm)
+{
+   ((GeneralMatrix&)*gm).tDelete();
+   Throw(ProgramException("Maximum or minimum of null matrix"));
+}
+
+Real GeneralMatrix::MaximumAbsoluteValue() const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   Real maxval = 0.0; int l = storage; Real* s = store;
+   while (l--) { Real a = fabs(*s++); if (maxval < a) maxval = a; }
+   ((GeneralMatrix&)*this).tDelete(); return maxval;
+}
+
+Real GeneralMatrix::MaximumAbsoluteValue1(int& i) const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   Real maxval = 0.0; int l = storage; Real* s = store; int li = storage;
+   while (l--)
+      { Real a = fabs(*s++); if (maxval <= a) { maxval = a; li = l; }  }
+   i = storage - li;
+   ((GeneralMatrix&)*this).tDelete(); return maxval;
+}
+
+Real GeneralMatrix::MinimumAbsoluteValue() const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   int l = storage - 1; Real* s = store; Real minval = fabs(*s++);
+   while (l--) { Real a = fabs(*s++); if (minval > a) minval = a; }
+   ((GeneralMatrix&)*this).tDelete(); return minval;
+}
+
+Real GeneralMatrix::MinimumAbsoluteValue1(int& i) const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   int l = storage - 1; Real* s = store; Real minval = fabs(*s++); int li = l;
+   while (l--)
+      { Real a = fabs(*s++); if (minval >= a) { minval = a; li = l; }  }
+   i = storage - li;
+   ((GeneralMatrix&)*this).tDelete(); return minval;
+}
+
+Real GeneralMatrix::Maximum() const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   int l = storage - 1; Real* s = store; Real maxval = *s++;
+   while (l--) { Real a = *s++; if (maxval < a) maxval = a; }
+   ((GeneralMatrix&)*this).tDelete(); return maxval;
+}
+
+Real GeneralMatrix::Maximum1(int& i) const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   int l = storage - 1; Real* s = store; Real maxval = *s++; int li = l;
+   while (l--) { Real a = *s++; if (maxval <= a) { maxval = a; li = l; } }
+   i = storage - li;
+   ((GeneralMatrix&)*this).tDelete(); return maxval;
+}
+
+Real GeneralMatrix::Minimum() const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   int l = storage - 1; Real* s = store; Real minval = *s++;
+   while (l--) { Real a = *s++; if (minval > a) minval = a; }
+   ((GeneralMatrix&)*this).tDelete(); return minval;
+}
+
+Real GeneralMatrix::Minimum1(int& i) const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   int l = storage - 1; Real* s = store; Real minval = *s++; int li = l;
+   while (l--) { Real a = *s++; if (minval >= a) { minval = a; li = l; } }
+   i = storage - li;
+   ((GeneralMatrix&)*this).tDelete(); return minval;
+}
+
+Real GeneralMatrix::MaximumAbsoluteValue2(int& i, int& j) const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   Real maxval = 0.0; int nr = Nrows();
+   MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
+   for (int r = 1; r <= nr; r++)
+   {
+      int c; maxval = mr.MaximumAbsoluteValue1(maxval, c);
+      if (c > 0) { i = r; j = c; }
+      mr.Next();
+   }
+   ((GeneralMatrix&)*this).tDelete(); return maxval;
+}
+
+Real GeneralMatrix::MinimumAbsoluteValue2(int& i, int& j) const
+{
+   REPORT
+   if (storage == 0)  NullMatrixError(this);
+   Real minval = FloatingPointPrecision::Maximum(); int nr = Nrows();
+   MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
+   for (int r = 1; r <= nr; r++)
+   {
+      int c; minval = mr.MinimumAbsoluteValue1(minval, c);
+      if (c > 0) { i = r; j = c; }
+      mr.Next();
+   }
+   ((GeneralMatrix&)*this).tDelete(); return minval;
+}
+
+Real GeneralMatrix::Maximum2(int& i, int& j) const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   Real maxval = -FloatingPointPrecision::Maximum(); int nr = Nrows();
+   MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
+   for (int r = 1; r <= nr; r++)
+   {
+      int c; maxval = mr.Maximum1(maxval, c);
+      if (c > 0) { i = r; j = c; }
+      mr.Next();
+   }
+   ((GeneralMatrix&)*this).tDelete(); return maxval;
+}
+
+Real GeneralMatrix::Minimum2(int& i, int& j) const
+{
+   REPORT
+   if (storage == 0) NullMatrixError(this);
+   Real minval = FloatingPointPrecision::Maximum(); int nr = Nrows();
+   MatrixRow mr((GeneralMatrix*)this, LoadOnEntry+DirectPart);
+   for (int r = 1; r <= nr; r++)
+   {
+      int c; minval = mr.Minimum1(minval, c);
+      if (c > 0) { i = r; j = c; }
+      mr.Next();
+   }
+   ((GeneralMatrix&)*this).tDelete(); return minval;
+}
+
+Real Matrix::MaximumAbsoluteValue2(int& i, int& j) const
+{
+   REPORT
+   int k; Real m = GeneralMatrix::MaximumAbsoluteValue1(k); k--;
+   i = k / Ncols(); j = k - i * Ncols(); i++; j++;
+   return m;
+}
+
+Real Matrix::MinimumAbsoluteValue2(int& i, int& j) const
+{
+   REPORT
+   int k; Real m = GeneralMatrix::MinimumAbsoluteValue1(k); k--;
+   i = k / Ncols(); j = k - i * Ncols(); i++; j++;
+   return m;
+}
+
+Real Matrix::Maximum2(int& i, int& j) const
+{
+   REPORT
+   int k; Real m = GeneralMatrix::Maximum1(k); k--;
+   i = k / Ncols(); j = k - i * Ncols(); i++; j++;
+   return m;
+}
+
+Real Matrix::Minimum2(int& i, int& j) const
+{
+   REPORT
+   int k; Real m = GeneralMatrix::Minimum1(k); k--;
+   i = k / Ncols(); j = k - i * Ncols(); i++; j++;
+   return m;
+}
+
+Real SymmetricMatrix::SumSquare() const
+{
+   REPORT
+   Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows;
+   for (int i = 0; i<nr; i++)
+   {
+      int j = i;
+      while (j--) sum2 += square(*s++);
+      sum1 += square(*s++);
+   }
+   ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
+}
+
+Real SymmetricMatrix::SumAbsoluteValue() const
+{
+   REPORT
+   Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows;
+   for (int i = 0; i<nr; i++)
+   {
+      int j = i;
+      while (j--) sum2 += fabs(*s++);
+      sum1 += fabs(*s++);
+   }
+   ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
+}
+
+Real IdentityMatrix::SumAbsoluteValue() const
+   { REPORT  return fabs(Trace()); }    // no need to do tDelete?
+
+Real SymmetricMatrix::Sum() const
+{
+   REPORT
+   Real sum1 = 0.0; Real sum2 = 0.0; Real* s = store; int nr = nrows;
+   for (int i = 0; i<nr; i++)
+   {
+      int j = i;
+      while (j--) sum2 += *s++;
+      sum1 += *s++;
+   }
+   ((GeneralMatrix&)*this).tDelete(); return sum1 + 2.0 * sum2;
+}
+
+Real IdentityMatrix::SumSquare() const
+{
+   Real sum = *store * *store * nrows;
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+
+Real BaseMatrix::SumSquare() const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->SumSquare(); return s;
+}
+
+Real BaseMatrix::NormFrobenius() const
+   { REPORT  return sqrt(SumSquare()); }
+
+Real BaseMatrix::SumAbsoluteValue() const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->SumAbsoluteValue(); return s;
+}
+
+Real BaseMatrix::Sum() const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->Sum(); return s;
+}
+
+Real BaseMatrix::MaximumAbsoluteValue() const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->MaximumAbsoluteValue(); return s;
+}
+
+Real BaseMatrix::MaximumAbsoluteValue1(int& i) const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->MaximumAbsoluteValue1(i); return s;
+}
+
+Real BaseMatrix::MaximumAbsoluteValue2(int& i, int& j) const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->MaximumAbsoluteValue2(i, j); return s;
+}
+
+Real BaseMatrix::MinimumAbsoluteValue() const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->MinimumAbsoluteValue(); return s;
+}
+
+Real BaseMatrix::MinimumAbsoluteValue1(int& i) const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->MinimumAbsoluteValue1(i); return s;
+}
+
+Real BaseMatrix::MinimumAbsoluteValue2(int& i, int& j) const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->MinimumAbsoluteValue2(i, j); return s;
+}
+
+Real BaseMatrix::Maximum() const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->Maximum(); return s;
+}
+
+Real BaseMatrix::Maximum1(int& i) const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->Maximum1(i); return s;
+}
+
+Real BaseMatrix::Maximum2(int& i, int& j) const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->Maximum2(i, j); return s;
+}
+
+Real BaseMatrix::Minimum() const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->Minimum(); return s;
+}
+
+Real BaseMatrix::Minimum1(int& i) const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->Minimum1(i); return s;
+}
+
+Real BaseMatrix::Minimum2(int& i, int& j) const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   Real s = gm->Minimum2(i, j); return s;
+}
+
+Real DotProduct(const Matrix& A, const Matrix& B)
+{
+   REPORT
+   int n = A.storage;
+   if (n != B.storage) Throw(IncompatibleDimensionsException(A,B));
+   Real sum = 0.0; Real* a = A.store; Real* b = B.store;
+   while (n--) sum += *a++ * *b++;
+   return sum;
+}
+
+Real Matrix::Trace() const
+{
+   REPORT
+   Tracer trace("Trace");
+   int i = nrows; int d = i+1;
+   if (i != ncols) Throw(NotSquareException(*this));
+   Real sum = 0.0; Real* s = store;
+//   while (i--) { sum += *s; s += d; }
+   if (i) for (;;) { sum += *s; if (!(--i)) break; s += d; }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+Real DiagonalMatrix::Trace() const
+{
+   REPORT
+   int i = nrows; Real sum = 0.0; Real* s = store;
+   while (i--) sum += *s++;
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+Real SymmetricMatrix::Trace() const
+{
+   REPORT
+   int i = nrows; Real sum = 0.0; Real* s = store; int j = 2;
+   // while (i--) { sum += *s; s += j++; }
+   if (i) for (;;) { sum += *s; if (!(--i)) break; s += j++; }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+Real LowerTriangularMatrix::Trace() const
+{
+   REPORT
+   int i = nrows; Real sum = 0.0; Real* s = store; int j = 2;
+   // while (i--) { sum += *s; s += j++; }
+   if (i) for (;;) { sum += *s; if (!(--i)) break; s += j++; }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+Real UpperTriangularMatrix::Trace() const
+{
+   REPORT
+   int i = nrows; Real sum = 0.0; Real* s = store;
+   while (i) { sum += *s; s += i--; }             // won t cause a problem
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+Real BandMatrix::Trace() const
+{
+   REPORT
+   int i = nrows; int w = lower+upper+1;
+   Real sum = 0.0; Real* s = store+lower;
+   // while (i--) { sum += *s; s += w; }
+   if (i) for (;;) { sum += *s; if (!(--i)) break; s += w; }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+Real SymmetricBandMatrix::Trace() const
+{
+   REPORT
+   int i = nrows; int w = lower+1;
+   Real sum = 0.0; Real* s = store+lower;
+   // while (i--) { sum += *s; s += w; }
+   if (i) for (;;) { sum += *s; if (!(--i)) break; s += w; }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+Real IdentityMatrix::Trace() const
+{
+   Real sum = *store * nrows;
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+
+Real BaseMatrix::Trace() const
+{
+   REPORT
+   MatrixType Diag = MatrixType::Dg; Diag.SetDataLossOK();
+   GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate(Diag);
+   Real sum = gm->Trace(); return sum;
+}
+
+void LogAndSign::operator*=(Real x)
+{
+   if (x > 0.0) { log_value += log(x); }
+   else if (x < 0.0) { log_value += log(-x); sign = -sign; }
+   else sign = 0;
+}
+
+void LogAndSign::PowEq(int k)
+{
+   if (sign)
+   {
+      log_value *= k;
+      if ( (k & 1) == 0 ) sign = 1;
+   }
+}
+
+Real LogAndSign::Value() const
+{
+   Tracer et("LogAndSign::Value");
+   if (log_value >= FloatingPointPrecision::LnMaximum())
+      Throw(OverflowException("Overflow in exponential"));
+   return sign * exp(log_value);
+}
+
+LogAndSign::LogAndSign(Real f)
+{
+   if (f == 0.0) { log_value = 0.0; sign = 0; return; }
+   else if (f < 0.0) { sign = -1; f = -f; }
+   else sign = 1;
+   log_value = log(f);
+}
+
+LogAndSign DiagonalMatrix::LogDeterminant() const
+{
+   REPORT
+   int i = nrows; LogAndSign sum; Real* s = store;
+   while (i--) sum *= *s++;
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+LogAndSign LowerTriangularMatrix::LogDeterminant() const
+{
+   REPORT
+   int i = nrows; LogAndSign sum; Real* s = store; int j = 2;
+   // while (i--) { sum *= *s; s += j++; }
+   if (i) for(;;) { sum *= *s; if (!(--i)) break; s += j++; }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+LogAndSign UpperTriangularMatrix::LogDeterminant() const
+{
+   REPORT
+   int i = nrows; LogAndSign sum; Real* s = store;
+   while (i) { sum *= *s; s += i--; }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+LogAndSign IdentityMatrix::LogDeterminant() const
+{
+   REPORT
+   int i = nrows; LogAndSign sum;
+   if (i > 0) { sum = *store; sum.PowEq(i); }
+   ((GeneralMatrix&)*this).tDelete(); return sum;
+}
+
+LogAndSign BaseMatrix::LogDeterminant() const
+{
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   LogAndSign sum = gm->LogDeterminant(); return sum;
+}
+
+LogAndSign GeneralMatrix::LogDeterminant() const
+{
+   REPORT
+   Tracer tr("LogDeterminant");
+   if (nrows != ncols) Throw(NotSquareException(*this));
+   CroutMatrix C(*this); return C.LogDeterminant();
+}
+
+LogAndSign CroutMatrix::LogDeterminant() const
+{
+   REPORT
+   if (sing) return 0.0;
+   int i = nrows; int dd = i+1; LogAndSign sum; Real* s = store;
+   if (i) for(;;)
+   {
+      sum *= *s;
+      if (!(--i)) break;
+      s += dd;
+   }
+   if (!d) sum.ChangeSign(); return sum;
+
+}
+
+Real BaseMatrix::Determinant() const
+{
+   REPORT
+   Tracer tr("Determinant");
+   REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate();
+   LogAndSign ld = gm->LogDeterminant();
+   return ld.Value();
+}
+
+
+
+
+
+LinearEquationSolver::LinearEquationSolver(const BaseMatrix& bm)
+{
+   gm = ((BaseMatrix&) bm ).Evaluate()->MakeSolver();
+   if (gm==&bm) { REPORT  gm = gm->Image(); }
+   // want a copy if  *gm is actually bm
+   else { REPORT  gm->Protect(); }
+}
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmat9.cpp b/Utilities/OSSIM/ossim_core/matrix/newmat9.cpp
new file mode 100644
index 0000000000..80500e6d6d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmat9.cpp
@@ -0,0 +1,76 @@
+//$$ newmat9.cpp         Input and output
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+
+#define WANT_STREAM
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatio.h"
+#include "newmatrc.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+using namespace std;
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,9); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+// for G++ 3.01
+#ifndef ios_format_flags
+#define ios_format_flags long
+#endif
+
+ostream& operator<<(ostream& s, const BaseMatrix& X)
+{
+   GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate(); operator<<(s, *gm);
+   gm->tDelete(); return s;
+}
+
+
+ostream& operator<<(ostream& s, const GeneralMatrix& X)
+{
+   MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry);
+   int w = s.width();  int nr = X.Nrows();  ios_format_flags f = s.flags();
+   s.setf(ios::fixed, ios::floatfield);
+   for (int i=1; i<=nr; i++)
+   {
+      int skip = mr.skip;  int storage = mr.storage;
+      Real* store = mr.data;  skip *= w+1;
+      while (skip--) s << " ";
+      while (storage--) { s.width(w); s << *store++ << " "; }
+//      while (storage--) s << setw(w) << *store++ << " ";
+      mr.Next();  s << "\n";
+   }
+   s << flush;  s.flags(f); return s;
+}
+
+// include this stuff if you are using an old version of G++
+// with an incomplete io library
+
+/*
+
+ostream& operator<<(ostream& os, Omanip_precision i)
+   { os.precision(i.x); return os; }
+
+Omanip_precision setprecision(int i) { return Omanip_precision(i); }
+
+ostream& operator<<(ostream& os, Omanip_width i)
+   { os.width(i.x); return os; }
+
+Omanip_width setw(int i) { return Omanip_width(i); }
+
+*/
+
+#ifdef use_namespace
+}
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmatap.h b/Utilities/OSSIM/ossim_core/matrix/newmatap.h
new file mode 100644
index 0000000000..f25e6234f4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmatap.h
@@ -0,0 +1,201 @@
+//$$ newmatap.h           definition file for matrix package applications
+
+// Copyright (C) 1991,2,3,4,8: R B Davies
+
+#ifndef NEWMATAP_LIB
+#define NEWMATAP_LIB 0
+
+#include "newmat.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+// ************************** applications *****************************/
+
+
+void QRZT(Matrix&, LowerTriangularMatrix&);
+
+void QRZT(const Matrix&, Matrix&, Matrix&);
+
+void QRZ(Matrix&, UpperTriangularMatrix&);
+
+void QRZ(const Matrix&, Matrix&, Matrix&);
+
+inline void HHDecompose(Matrix& X, LowerTriangularMatrix& L)
+{ QRZT(X,L); }
+
+inline void HHDecompose(const Matrix& X, Matrix& Y, Matrix& M)
+{ QRZT(X, Y, M); }
+
+void UpdateQRZT(Matrix& X, LowerTriangularMatrix& L);
+
+void UpdateQRZ(Matrix& X, UpperTriangularMatrix& U);
+
+
+ReturnMatrix Cholesky(const SymmetricMatrix&);
+
+ReturnMatrix Cholesky(const SymmetricBandMatrix&);
+
+
+// produces the Cholesky decomposition of A + x.t() * x where A = chol.t() * chol
+// and x is a RowVector
+void UpdateCholesky(UpperTriangularMatrix &chol, RowVector r1Modification);
+
+// produces the Cholesky decomposition of A - x.t() * x where A = chol.t() * chol
+// and x is a RowVector
+void DowndateCholesky(UpperTriangularMatrix &chol, RowVector x);
+
+// a RIGHT circular shift of the rows and columns from
+// 1,...,k-1,k,k+1,...l,l+1,...,p to
+// 1,...,k-1,l,k,k+1,...l-1,l+1,...p
+void RightCircularUpdateCholesky(UpperTriangularMatrix &chol, int k, int l);
+
+// a LEFT circular shift of the rows and columns from
+// 1,...,k-1,k,k+1,...l,l+1,...,p to
+// 1,...,k-1,k+1,...l,k,l+1,...,p to
+void LeftCircularUpdateCholesky(UpperTriangularMatrix &chol, int k, int l); 
+
+
+void SVD(const Matrix&, DiagonalMatrix&, Matrix&, Matrix&,
+    bool=true, bool=true);
+
+void SVD(const Matrix&, DiagonalMatrix&);
+
+inline void SVD(const Matrix& A, DiagonalMatrix& D, Matrix& U,
+   bool withU = true) { SVD(A, D, U, U, withU, false); }
+
+void SortSV(DiagonalMatrix& D, Matrix& U, bool ascending = false);
+
+void SortSV(DiagonalMatrix& D, Matrix& U, Matrix& V, bool ascending = false);
+
+void Jacobi(const SymmetricMatrix&, DiagonalMatrix&);
+
+void Jacobi(const SymmetricMatrix&, DiagonalMatrix&, SymmetricMatrix&);
+
+void Jacobi(const SymmetricMatrix&, DiagonalMatrix&, Matrix&);
+
+void Jacobi(const SymmetricMatrix&, DiagonalMatrix&, SymmetricMatrix&,
+   Matrix&, bool=true);
+
+void EigenValues(const SymmetricMatrix&, DiagonalMatrix&);
+
+void EigenValues(const SymmetricMatrix&, DiagonalMatrix&, SymmetricMatrix&);
+
+void EigenValues(const SymmetricMatrix&, DiagonalMatrix&, Matrix&);
+
+class SymmetricEigenAnalysis
+// not implemented yet
+{
+public:
+   SymmetricEigenAnalysis(const SymmetricMatrix&);
+private:
+   DiagonalMatrix diag;
+   DiagonalMatrix offdiag;
+   SymmetricMatrix backtransform;
+   FREE_CHECK(SymmetricEigenAnalysis)
+};
+
+void SortAscending(GeneralMatrix&);
+
+void SortDescending(GeneralMatrix&);
+
+
+// class for deciding which fft to use and containing new fft function
+class FFT_Controller
+{
+public:
+   static bool OnlyOldFFT;
+   static bool ar_1d_ft (int PTS, Real* X, Real *Y);
+   static bool CanFactor(int PTS);
+};
+
+void FFT(const ColumnVector&, const ColumnVector&,
+   ColumnVector&, ColumnVector&);
+
+void FFTI(const ColumnVector&, const ColumnVector&,
+   ColumnVector&, ColumnVector&);
+
+void RealFFT(const ColumnVector&, ColumnVector&, ColumnVector&);
+
+void RealFFTI(const ColumnVector&, const ColumnVector&, ColumnVector&);
+
+void DCT_II(const ColumnVector&, ColumnVector&);
+
+void DCT_II_inverse(const ColumnVector&, ColumnVector&);
+
+void DST_II(const ColumnVector&, ColumnVector&);
+
+void DST_II_inverse(const ColumnVector&, ColumnVector&);
+
+void DCT(const ColumnVector&, ColumnVector&);
+
+void DCT_inverse(const ColumnVector&, ColumnVector&);
+
+void DST(const ColumnVector&, ColumnVector&);
+
+void DST_inverse(const ColumnVector&, ColumnVector&);
+
+void FFT2(const Matrix& U, const Matrix& V, Matrix& X, Matrix& Y);
+
+void FFT2I(const Matrix& U, const Matrix& V, Matrix& X, Matrix& Y);
+
+
+// This class is used by the new FFT program
+
+// Suppose an integer is expressed as a sequence of digits with each
+// digit having a different radix.
+// This class supposes we are counting with this multi-radix number
+// but also keeps track of the number with the digits (and radices)
+// reversed.
+// The integer starts at zero
+// operator++() increases it by 1
+// Counter gives the number of increments
+// Reverse() gives the value with the digits in reverse order
+// Swap is true if reverse is less than counter
+// Finish is true when we have done a complete cycle and are back at zero
+
+class MultiRadixCounter
+{
+   const SimpleIntArray& Radix;
+                              // radix of each digit
+                              // n-1 highest order, 0 lowest order
+   SimpleIntArray& Value;     // value of each digit
+   const int n;               // number of digits
+   int reverse;               // value when order of digits is reversed
+   int product;               // product of radices
+   int counter;               // counter
+   bool finish;               // true when we have gone over whole range
+public:
+   MultiRadixCounter(int nx, const SimpleIntArray& rx,
+      SimpleIntArray& vx);
+   void operator++();         // increment the multi-radix counter
+   bool Swap() const { return reverse < counter; }
+   bool Finish() const { return finish; }
+   int Reverse() const { return reverse; }
+   int Counter() const { return counter; }
+};
+
+
+#ifdef use_namespace
+}
+#endif
+
+
+
+#endif
+
+// body file: cholesky.cpp
+// body file: evalue.cpp
+// body file: fft.cpp
+// body file: hholder.cpp
+// body file: jacobi.cpp
+// body file: newfft.cpp
+// body file: sort.cpp
+// body file: svd.cpp
+
+
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmatex.cpp b/Utilities/OSSIM/ossim_core/matrix/newmatex.cpp
new file mode 100644
index 0000000000..55e393bf91
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmatex.cpp
@@ -0,0 +1,313 @@
+//$$ newmatex.cpp                    Exception handler
+
+// Copyright (C) 1992,3,4,7: R B Davies
+
+#define WANT_STREAM                  // include.h will get stream fns
+
+#include "include.h"                 // include standard files
+#include "newmat.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+unsigned long OverflowException::Select;
+unsigned long SingularException::Select;
+unsigned long NPDException::Select;
+unsigned long ConvergenceException::Select;
+unsigned long ProgramException::Select;
+unsigned long IndexException::Select;
+unsigned long VectorException::Select;
+unsigned long NotSquareException::Select;
+unsigned long SubMatrixDimensionException::Select;
+unsigned long IncompatibleDimensionsException::Select;
+unsigned long NotDefinedException::Select;
+unsigned long CannotBuildException::Select;
+unsigned long InternalException::Select;
+
+
+
+static void MatrixDetails(const GeneralMatrix& A)
+// write matrix details to Exception buffer
+{
+   MatrixBandWidth bw = A.BandWidth(); int ubw = bw.upper; int lbw = bw.lower;
+   BaseException::AddMessage("MatrixType = ");
+   BaseException::AddMessage(A.Type().Value());
+   BaseException::AddMessage("  # Rows = "); BaseException::AddInt(A.Nrows());
+   BaseException::AddMessage("; # Cols = "); BaseException::AddInt(A.Ncols());
+   if (lbw >=0)
+   {
+      BaseException::AddMessage("; lower BW = ");
+      BaseException::AddInt(lbw);
+   }
+   if (ubw >=0)
+   {
+      BaseException::AddMessage("; upper BW = ");
+      BaseException::AddInt(ubw);
+   }
+   BaseException::AddMessage("\n");
+}
+
+NPDException::NPDException(const GeneralMatrix& A)
+   : Runtime_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: matrix not positive definite\n\n");
+   MatrixDetails(A);
+   Tracer::AddTrace();
+}
+
+SingularException::SingularException(const GeneralMatrix& A)
+   : Runtime_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: matrix is singular\n\n");
+   MatrixDetails(A);
+   Tracer::AddTrace();
+}
+
+ConvergenceException::ConvergenceException(const GeneralMatrix& A)
+   : Runtime_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: process fails to converge\n\n");
+   MatrixDetails(A);
+   Tracer::AddTrace();
+}
+
+ConvergenceException::ConvergenceException(const char* c) : Runtime_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: ");
+   AddMessage(c); AddMessage("\n\n");
+   if (c) Tracer::AddTrace();
+}
+
+OverflowException::OverflowException(const char* c) : Runtime_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: ");
+   AddMessage(c); AddMessage("\n\n");
+   if (c) Tracer::AddTrace();
+}
+
+ProgramException::ProgramException(const char* c) : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: ");
+   AddMessage(c); AddMessage("\n\n");
+   if (c) Tracer::AddTrace();
+}
+
+ProgramException::ProgramException(const char* c, const GeneralMatrix& A)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: ");
+   AddMessage(c); AddMessage("\n\n");
+   MatrixDetails(A);
+   if (c) Tracer::AddTrace();
+}
+
+ProgramException::ProgramException(const char* c, const GeneralMatrix& A,
+   const GeneralMatrix& B) : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: ");
+   AddMessage(c); AddMessage("\n\n");
+   MatrixDetails(A); MatrixDetails(B);
+   if (c) Tracer::AddTrace();
+}
+
+ProgramException::ProgramException(const char* c, MatrixType a, MatrixType b)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: ");
+   AddMessage(c); AddMessage("\nMatrixTypes = ");
+   AddMessage(a.Value()); AddMessage("; ");
+   AddMessage(b.Value()); AddMessage("\n\n");
+   if (c) Tracer::AddTrace();
+}
+
+VectorException::VectorException() : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: cannot convert matrix to vector\n\n");
+   Tracer::AddTrace();
+}
+
+VectorException::VectorException(const GeneralMatrix& A)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: cannot convert matrix to vector\n\n");
+   MatrixDetails(A);
+   Tracer::AddTrace();
+}
+
+NotSquareException::NotSquareException(const GeneralMatrix& A)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: matrix is not square\n\n");
+   MatrixDetails(A);
+   Tracer::AddTrace();
+}
+
+NotSquareException::NotSquareException()
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: matrix is not square\n\n");
+   Tracer::AddTrace();
+}
+
+SubMatrixDimensionException::SubMatrixDimensionException()
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: incompatible submatrix dimension\n\n");
+   Tracer::AddTrace();
+}
+
+IncompatibleDimensionsException::IncompatibleDimensionsException()
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: incompatible dimensions\n\n");
+   Tracer::AddTrace();
+}
+
+IncompatibleDimensionsException::IncompatibleDimensionsException
+   (const GeneralMatrix& A, const GeneralMatrix& B)
+      : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: incompatible dimensions\n\n");
+   MatrixDetails(A); MatrixDetails(B);
+   Tracer::AddTrace();
+}
+
+NotDefinedException::NotDefinedException(const char* op, const char* matrix)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: ");
+   AddMessage(op);
+   AddMessage(" not defined for ");
+   AddMessage(matrix);
+   AddMessage("\n\n");
+   Tracer::AddTrace();
+}
+
+CannotBuildException::CannotBuildException(const char* matrix)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: cannot build matrix type ");
+   AddMessage(matrix); AddMessage("\n\n");
+   Tracer::AddTrace();
+}
+
+IndexException::IndexException(int i, const GeneralMatrix& A)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: index error: requested index = ");
+   AddInt(i); AddMessage("\n\n");
+   MatrixDetails(A);
+   Tracer::AddTrace();
+}
+
+IndexException::IndexException(int i, int j, const GeneralMatrix& A)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: index error: requested indices = ");
+   AddInt(i); AddMessage(", "); AddInt(j);
+   AddMessage("\n\n");
+   MatrixDetails(A);
+   Tracer::AddTrace();
+}
+
+
+IndexException::IndexException(int i, const GeneralMatrix& A, bool)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("detected by Newmat: element error: requested index (wrt 0) = ");
+   AddInt(i);
+   AddMessage("\n\n");
+   MatrixDetails(A);
+   Tracer::AddTrace();
+}
+
+IndexException::IndexException(int i, int j, const GeneralMatrix& A, bool)
+   : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage(
+      "detected by Newmat: element error: requested indices (wrt 0) = ");
+   AddInt(i); AddMessage(", "); AddInt(j);
+   AddMessage("\n\n");
+   MatrixDetails(A);
+   Tracer::AddTrace();
+}
+
+InternalException::InternalException(const char* c) : Logic_error()
+{
+   Select = BaseException::Select;
+   AddMessage("internal error detected by Newmat: please inform author\n");
+   AddMessage(c); AddMessage("\n\n");
+   Tracer::AddTrace();
+}
+
+
+
+
+/************************* ExeCounter functions *****************************/
+
+#ifdef DO_REPORT
+
+int ExeCounter::nreports;                      // will be set to zero
+
+ExeCounter::ExeCounter(int xl, int xf) : line(xl), fileid(xf), nexe(0) {}
+
+ExeCounter::~ExeCounter()
+{
+   nreports++;
+   cout << "REPORT  " << setw(6) << nreports << "  "
+      << setw(6) << fileid << "  " << setw(6) << line
+      << "  " << setw(6) << nexe << "\n";
+}
+
+#endif
+
+/**************************** error handler *******************************/
+
+void MatrixErrorNoSpace(const void* v) { if (!v) Throw(Bad_alloc()); }
+// throw exception if v is null
+
+
+
+
+/************************* miscellanous errors ***************************/
+
+
+void CroutMatrix::GetRow(MatrixRowCol&)
+   { Throw(NotDefinedException("GetRow","Crout")); }
+void CroutMatrix::GetCol(MatrixRowCol&)
+   { Throw(NotDefinedException("GetCol","Crout")); }
+void BandLUMatrix::GetRow(MatrixRowCol&)
+   { Throw(NotDefinedException("GetRow","BandLUMatrix")); }
+void BandLUMatrix::GetCol(MatrixRowCol&)
+   { Throw(NotDefinedException("GetCol","BandLUMatrix")); }
+void BaseMatrix::IEQND() const
+   { Throw(NotDefinedException("inequalities", "matrices")); }
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmatio.h b/Utilities/OSSIM/ossim_core/matrix/newmatio.h
new file mode 100644
index 0000000000..af8231d9c1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmatio.h
@@ -0,0 +1,61 @@
+//$$ newmatio.h           definition file for matrix package input/output
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#ifndef NEWMATIO_LIB
+#define NEWMATIO_LIB 0
+
+#ifndef WANT_STREAM
+#define WANT_STREAM
+#endif
+
+#include "newmat.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+
+/**************************** input/output *****************************/
+
+	OSSIM_DLL std::ostream& operator<<(std::ostream&, const BaseMatrix&);
+
+	OSSIM_DLL std::ostream& operator<<(std::ostream&, const GeneralMatrix&);
+
+
+/*  Use in some old versions of G++ without complete iomanipulators
+
+class Omanip_precision
+{
+   int x;
+public:
+   Omanip_precision(int i) : x(i) {}
+   friend ostream& operator<<(ostream& os, Omanip_precision i);
+};
+
+
+Omanip_precision setprecision(int i);
+
+class Omanip_width
+{
+   int x;
+public:
+   Omanip_width(int i) : x(i) {}
+   friend ostream& operator<<(ostream& os, Omanip_width i);
+};
+
+Omanip_width setw(int i);
+
+*/
+
+#ifdef use_namespace
+}
+#endif
+
+
+
+#endif
+
+// body file: newmat9.cpp
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmatnl.cpp b/Utilities/OSSIM/ossim_core/matrix/newmatnl.cpp
new file mode 100644
index 0000000000..ba0140c99f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmatnl.cpp
@@ -0,0 +1,260 @@
+//$$ newmatnl.cpp         Non-linear optimisation
+
+// Copyright (C) 1993,4,5,6: R B Davies
+
+
+#define WANT_MATH
+#define WANT_STREAM
+
+#include "newmatap.h"
+#include "newmatnl.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+using namespace std;
+
+void FindMaximum2::Fit(ColumnVector& Theta, int n_it)
+{
+   Tracer tr("FindMaximum2::Fit");
+   enum State {Start, Restart, Continue, Interpolate, Extrapolate,
+      Fail, Convergence};
+   State TheState = Start;
+   Real z,w,x,x2,g,l1,l2,l3,d1,d2=0,d3;
+   ColumnVector Theta1, Theta2, Theta3;
+   int np = Theta.Nrows();
+   ColumnVector H1(np), H3, HP(np), K, K1(np);
+   bool oorg, conv;
+   int counter = 0;
+   Theta1 = Theta; HP = 0.0; g = 0.0;
+
+   // This is really a set of gotos and labels, but they do not work
+   // correctly in AT&T C++ and Sun 4.01 C++.
+
+   for(;;)
+   {
+      switch (TheState)
+      {
+      case Start:
+	 tr.ReName("FindMaximum2::Fit/Start");
+	 Value(Theta1, true, l1, oorg);
+	 if (oorg) Throw(ProgramException("invalid starting value\n"));
+
+      case Restart:
+	 tr.ReName("FindMaximum2::Fit/ReStart");
+	 conv = NextPoint(H1, d1);
+	 if (conv) { TheState = Convergence; break; }
+	 if (counter++ > n_it) { TheState = Fail; break; }
+
+	 z = 1.0 / sqrt(d1);
+	 H3 = H1 * z; K = (H3 - HP) * g; HP = H3;
+	 g = 0.0;                     // de-activate to use curved projection
+	 if (g==0.0) K1 = 0.0; else K1 = K * 0.2 + K1 * 0.6;
+	 // (K - K1) * alpha + K1 * (1 - alpha)
+	 //     = K * alpha + K1 * (1 - 2 * alpha)
+	 K = K1 * d1; g = z;
+
+      case Continue:
+	 tr.ReName("FindMaximum2::Fit/Continue");
+	 Theta2 = Theta1 + H1 + K;
+	 Value(Theta2, false, l2, oorg);
+	 if (counter++ > n_it) { TheState = Fail; break; }
+	 if (oorg)
+	 {
+	    H1 *= 0.5; K *= 0.25; d1 *= 0.5; g *= 2.0;
+	    TheState =  Continue; break;
+	 }
+	 d2 = LastDerivative(H1 + K * 2.0);
+
+      case Interpolate:
+	 tr.ReName("FindMaximum2::Fit/Interpolate");
+	 z = d1 + d2 - 3.0 * (l2 - l1);
+	 w = z * z - d1 * d2;
+	 if (w < 0.0) { TheState = Extrapolate; break; }
+	 w = z + sqrt(w);
+	 if (1.5 * w + d1 < 0.0)
+	    { TheState = Extrapolate; break; }
+	 if (d2 > 0.0 && l2 > l1 && w > 0.0)
+	    { TheState = Extrapolate; break; }
+	 x = d1 / (w + d1); x2 = x * x; g /= x;
+	 Theta3 = Theta1 + H1 * x + K * x2;
+	 Value(Theta3, true, l3, oorg);
+	 if (counter++ > n_it) { TheState = Fail; break; }
+	 if (oorg)
+	 {
+	    if (x <= 1.0)
+	       { x *= 0.5; x2 = x*x; g *= 2.0; d1 *= x; H1 *= x; K *= x2; }
+	    else
+	    {
+	       x = 0.5 * (x-1.0); x2 = x*x; Theta1 = Theta2;
+	       H1 = (H1 + K * 2.0) * x;
+	       K *= x2; g = 0.0; d1 = x * d2; l1 = l2;
+	    }
+	    TheState = Continue; break;
+	 }
+
+	 if (l3 >= l1 && l3 >= l2)
+	    { Theta1 = Theta3; l1 = l3; TheState =  Restart; break; }
+
+	 d3 = LastDerivative(H1 + K * 2.0);
+	 if (l1 > l2)
+	    { H1 *= x; K *= x2; Theta2 = Theta3; d1 *= x; d2 = d3*x; }
+	 else
+	 {
+	    Theta1 = Theta2; Theta2 = Theta3;
+	    x -= 1.0; x2 = x*x; g = 0.0; H1 = (H1 + K * 2.0) * x;
+	    K *= x2; l1 = l2; l2 = l3; d1 = x*d2; d2 = x*d3;
+	    if (d1 <= 0.0) { TheState = Start; break; }
+	 }
+	 TheState =  Interpolate; break;
+
+      case Extrapolate:
+	 tr.ReName("FindMaximum2::Fit/Extrapolate");
+	 Theta1 = Theta2; g = 0.0; K *= 4.0; H1 = (H1 * 2.0 + K);
+	 d1 = 2.0 * d2; l1 = l2;
+	 TheState = Continue; break;
+
+      case Fail:
+	 Throw(ConvergenceException(Theta));
+
+      case Convergence:
+	 Theta = Theta1; return;
+      }
+   }
+}
+
+
+
+void NonLinearLeastSquares::Value
+   (const ColumnVector& Parameters, bool, Real& v, bool& oorg)
+{
+   Tracer tr("NonLinearLeastSquares::Value");
+   Y.ReSize(n_obs); X.ReSize(n_obs,n_param);
+   // put the fitted values in Y, the derivatives in X.
+   Pred.Set(Parameters);
+   if (!Pred.IsValid()) { oorg=true; return; }
+   for (int i=1; i<=n_obs; i++)
+   {
+      Y(i) = Pred(i);
+      X.Row(i) = Pred.Derivatives();
+   }
+   if (!Pred.IsValid()) { oorg=true; return; }  // check afterwards as well
+   Y = *DataPointer - Y; Real ssq = Y.SumSquare();
+   errorvar =  ssq / (n_obs - n_param);
+   cout << endl;
+   cout << setw(15) << setprecision(10) << " " << errorvar;
+   Derivs = Y.t() * X;          // get the derivative and stash it
+   oorg = false; v = -0.5 * ssq;
+}
+
+bool NonLinearLeastSquares::NextPoint(ColumnVector& Adj, Real& test)
+{
+   Tracer tr("NonLinearLeastSquares::NextPoint");
+   QRZ(X, U); QRZ(X, Y, M);     // do the QR decomposition
+   test = M.SumSquare();
+   cout << " " << setw(15) << setprecision(10)
+      << test << " " << Y.SumSquare() / (n_obs - n_param);
+   Adj = U.i() * M;
+   if (test < errorvar * criterion) return true;
+   else return false;
+}
+
+Real NonLinearLeastSquares::LastDerivative(const ColumnVector& H)
+{ return (Derivs * H).AsScalar(); }
+
+void NonLinearLeastSquares::Fit(const ColumnVector& Data,
+   ColumnVector& Parameters)
+{
+   Tracer tr("NonLinearLeastSquares::Fit");
+   n_param = Parameters.Nrows(); n_obs = Data.Nrows();
+   DataPointer = &Data;
+   FindMaximum2::Fit(Parameters, Lim);
+   cout << "\nConverged" << endl;
+}
+
+void NonLinearLeastSquares::MakeCovariance()
+{
+   if (Covariance.Nrows()==0)
+   {
+      UpperTriangularMatrix UI = U.i();
+      Covariance << UI * UI.t() * errorvar;
+      SE << Covariance;                 // get diagonals
+      for (int i = 1; i<=n_param; i++) SE(i) = sqrt(SE(i));
+   }
+}
+
+void NonLinearLeastSquares::GetStandardErrors(ColumnVector& SEX)
+   { MakeCovariance(); SEX = SE.AsColumn(); }
+
+void NonLinearLeastSquares::GetCorrelations(SymmetricMatrix& Corr)
+   { MakeCovariance(); Corr << SE.i() * Covariance * SE.i(); }
+
+void NonLinearLeastSquares::GetHatDiagonal(DiagonalMatrix& Hat) const
+{
+   Hat.ReSize(n_obs);
+   for (int i = 1; i<=n_obs; i++) Hat(i) = X.Row(i).SumSquare();
+}
+
+
+// the MLE_D_FI routines
+
+void MLE_D_FI::Value
+   (const ColumnVector& Parameters, bool wg, Real& v, bool& oorg)
+{
+   Tracer tr("MLE_D_FI::Value");
+   if (!LL.IsValid(Parameters,wg)) { oorg=true; return; }
+   v = LL.LogLikelihood();
+   if (!LL.IsValid()) { oorg=true; return; }     // check validity again
+   cout << endl;
+   cout << setw(20) << setprecision(10) << v;
+   oorg = false;
+   Derivs = LL.Derivatives();                    // Get derivatives
+}
+
+bool MLE_D_FI::NextPoint(ColumnVector& Adj, Real& test)
+{
+   Tracer tr("MLE_D_FI::NextPoint");
+   SymmetricMatrix FI = LL.FI();
+   LT = Cholesky(FI);
+   ColumnVector Adj1 = LT.i() * Derivs;
+   Adj = LT.t().i() * Adj1;
+   test = SumSquare(Adj1);
+   cout << "   " << setw(20) << setprecision(10) << test;
+   return (test < Criterion);
+}
+
+Real MLE_D_FI::LastDerivative(const ColumnVector& H)
+{ return (Derivs.t() * H).AsScalar(); }
+
+void MLE_D_FI::Fit(ColumnVector& Parameters)
+{
+   Tracer tr("MLE_D_FI::Fit");
+   FindMaximum2::Fit(Parameters,Lim);
+   cout << "\nConverged" << endl;
+}
+  
+void MLE_D_FI::MakeCovariance()
+{
+   if (Covariance.Nrows()==0)
+   {
+      LowerTriangularMatrix LTI = LT.i();
+      Covariance << LTI.t() * LTI;
+      SE << Covariance;                // get diagonal
+      int n = Covariance.Nrows();
+      for (int i=1; i <= n; i++) SE(i) = sqrt(SE(i));
+   }
+}
+
+void MLE_D_FI::GetStandardErrors(ColumnVector& SEX)
+{ MakeCovariance(); SEX = SE.AsColumn(); }
+   
+void MLE_D_FI::GetCorrelations(SymmetricMatrix& Corr)
+{ MakeCovariance(); Corr << SE.i() * Covariance * SE.i(); }
+
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmatnl.h b/Utilities/OSSIM/ossim_core/matrix/newmatnl.h
new file mode 100644
index 0000000000..9f49adc040
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmatnl.h
@@ -0,0 +1,322 @@
+//$$ newmatnl.h           definition file for non-linear optimisation
+
+// Copyright (C) 1993,4,5: R B Davies
+
+#ifndef NEWMATNL_LIB
+#define NEWMATNL_LIB 0
+
+#include "newmat.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+
+
+/*
+
+This is a beginning of a series of classes for non-linear optimisation.
+
+At present there are two classes. FindMaximum2 is the basic optimisation
+strategy when one is doing an optimisation where one has first
+derivatives and estimates of the second derivatives. Class
+NonLinearLeastSquares is derived from FindMaximum2. This provides the
+functions that calculate function values and derivatives.
+
+A third class is now added. This is for doing maximum-likelihood when
+you have first derviatives and something like the Fisher Information
+matrix (eg the variance covariance matrix of the first derivatives or
+minus the second derivatives - this matrix is assumed to be positive
+definite).
+
+
+
+   class FindMaximum2
+
+Suppose T is the ColumnVector of parameters, F(T) the function we want
+to maximise, D(T) the ColumnVector of derivatives of F with respect to
+T, and S(T) the matrix of second derivatives.
+
+Then the basic iteration is given a value of T, update it to
+
+           T - S.i() * D
+
+where .i() denotes inverse.
+
+If F was quadratic this would give exactly the right answer (except it
+might get a minimum rather than a maximum). Since F is not usually
+quadratic, the simple procedure would be to recalculate S and D with the
+new value of T and keep iterating until the process converges. This is
+known as the method of conjugate gradients.
+
+In practice, this method may not converge. FindMaximum2 considers an
+iteration of the form
+
+           T - x * S.i() * D
+
+where x is a number. It tries x = 1 and uses the values of F and its
+slope with respect to x at x = 0 and x = 1 to fit a cubic in x. It then
+choses x to maximise the resulting function. This gives our new value of
+T. The program checks that the value of F is getting better and carries
+out a variety of strategies if it is not.
+
+The program also has a second strategy. If the successive values of T
+seem to be lying along a curve - eg we are following along a curved
+ridge, the program will try to fit this ridge and project along it. This
+does not work at present and is commented out.
+
+FindMaximum2 has three virtual functions which need to be over-ridden by
+a derived class.
+
+   void Value(const ColumnVector& T, bool wg, Real& f, bool& oorg);
+
+T is the column vector of parameters. The function returns the value of
+the function to f, but may instead set oorg to true if the parameter
+values are not valid. If wg is true it may also calculate and store the
+second derivative information.
+
+   bool NextPoint(ColumnVector& H, Real& d);
+
+Using the value of T provided in the previous call of Value, find the
+conjugate gradients adjustment to T, that is - S.i() * D. Also return
+
+           d = D.t() * S.i() * D.
+
+NextPoint should return true if it considers that the process has
+converged (d very small) and false otherwise. The previous call of Value
+will have set wg to true, so that S will be available.
+
+   Real LastDerivative(const ColumnVector& H);
+
+Return the scalar product of H and the vector of derivatives at the last
+value of T.
+
+The function Fit is the function that calls the iteration.
+
+   void Fit(ColumnVector&, int);
+
+The arguments are the trial parameter values as a ColumnVector and the
+maximum number of iterations. The program calls a DataException if the
+initial parameters are not valid and a ConvergenceException if the
+process fails to converge.
+
+
+   class NonLinearLeastSquares
+
+This class is derived from FindMaximum2 and carries out a non-linear
+least squares fit. It uses a QR decomposition to carry out the
+operations required by FindMaximum2.
+
+A prototype class R1_Col_I_D is provided. The user needs to derive a
+class from this which includes functions the predicted value of each
+observation its derivatives. An object from this class has to be
+provided to class NonLinearLeastSquares.
+
+Suppose we observe n normal random variables with the same unknown
+variance and such the i-th one has expected value given by f(i,P)
+where P is a column vector of unknown parameters and f is a known
+function. We wish to estimate P.
+
+First derive a class from R1_Col_I_D and override Real operator()(int i)
+to give the value of the function f in terms of i and the ColumnVector
+para defined in class R1_CoL_I_D. Also override ReturnMatrix
+Derivatives() to give the derivates of f at para and the value of i
+used in the preceeding call to operator(). Return the result as a
+RowVector. Construct an object from this class. Suppose in what follows
+it is called pred.
+
+Now constuct a NonLinearLeastSquaresObject accessing pred and optionally
+an iteration limit and an accuracy critierion.
+
+   NonLinearLeastSquares NLLS(pred, 1000, 0.0001);
+
+The accuracy critierion should be somewhat less than one and 0.0001 is
+about the smallest sensible value.
+
+Define a ColumnVector P containing a guess at the value of the unknown
+parameter, and a ColumnVector Y containing the unknown data. Call
+
+   NLLS.Fit(Y,P);
+
+If the process converges, P will contain the estimates of the unknown
+parameters. If it does not converge an exception will be generated.
+
+The following member functions can be called after you have done a fit.
+
+Real ResidualVariance() const;
+
+The estimate of the variance of the observations.
+
+void GetResiduals(ColumnVector& Z) const;
+
+The residuals of the individual observations.
+
+void GetStandardErrors(ColumnVector&);
+
+The standard errors of the observations.
+
+void GetCorrelations(SymmetricMatrix&);
+
+The correlations of the observations.
+
+void GetHatDiagonal(DiagonalMatrix&) const;
+
+Forms a diagonal matrix of values between 0 and 1. If the i-th value is
+larger than, say 0.2, then the i-th data value could have an undue
+influence on your estimates.
+
+
+*/
+
+class FindMaximum2
+{
+   virtual void Value(const ColumnVector&, bool, Real&, bool&) = 0;
+   virtual bool NextPoint(ColumnVector&, Real&) = 0;
+   virtual Real LastDerivative(const ColumnVector&) = 0;
+public:
+   void Fit(ColumnVector&, int);
+   virtual ~FindMaximum2() {}            // to keep gnu happy
+};
+
+class R1_Col_I_D
+{
+   // The prototype for a Real function of a ColumnVector and an
+   // integer.
+   // You need to derive your function from this one and put in your
+   // function for operator() and Derivatives() at least.
+   // You may also want to set up a constructor to enter in additional
+   // parameter values (that will not vary during the solve).
+
+protected:
+   ColumnVector para;                 // Current x value
+
+public:
+   virtual bool IsValid() { return true; }
+                                       // is the current x value OK
+   virtual Real operator()(int i) = 0; // i-th function value at current para
+   virtual void Set(const ColumnVector& X) { para = X; }
+                                       // set current para
+   bool IsValid(const ColumnVector& X)
+      { Set(X); return IsValid(); }
+                                       // set para, check OK
+   Real operator()(int i, const ColumnVector& X)
+      { Set(X); return operator()(i); }
+                                       // set para, return value
+   virtual ReturnMatrix Derivatives() = 0;
+                                       // return derivatives as RowVector
+   virtual ~R1_Col_I_D() {}            // to keep gnu happy
+};
+
+
+class NonLinearLeastSquares : public FindMaximum2
+{
+   // these replace the corresponding functions in FindMaximum2
+   void Value(const ColumnVector&, bool, Real&, bool&);
+   bool NextPoint(ColumnVector&, Real&);
+   Real LastDerivative(const ColumnVector&);
+
+   Matrix X;                         // the things we need to do the
+   ColumnVector Y;                   // QR triangularisation
+   UpperTriangularMatrix U;          // see the write-up in newmata.txt
+   ColumnVector M;
+   Real errorvar, criterion;
+   int n_obs, n_param;
+   const ColumnVector* DataPointer;
+   RowVector Derivs;
+   SymmetricMatrix Covariance;
+   DiagonalMatrix SE;
+   R1_Col_I_D& Pred;                 // Reference to predictor object
+   int Lim;                          // maximum number of iterations
+
+public:
+   NonLinearLeastSquares(R1_Col_I_D& pred, int lim=1000, Real crit=0.0001)
+      : criterion(crit), Pred(pred), Lim(lim) {}
+   void Fit(const ColumnVector&, ColumnVector&);
+   Real ResidualVariance() const { return errorvar; }
+   void GetResiduals(ColumnVector& Z) const { Z = Y; }
+   void GetStandardErrors(ColumnVector&);
+   void GetCorrelations(SymmetricMatrix&);
+   void GetHatDiagonal(DiagonalMatrix&) const;
+
+private:
+   void MakeCovariance();
+};
+
+
+// The next class is the prototype class for calculating the
+// log-likelihood.
+// I assume first derivatives are available and something like the 
+// Fisher Information or variance/covariance matrix of the first
+// derivatives or minus the matrix of second derivatives is
+// available. This matrix must be positive definite.
+
+class LL_D_FI
+{
+protected:
+   ColumnVector para;                  // current parameter values
+   bool wg;                         // true if FI matrix wanted
+
+public:
+   virtual void Set(const ColumnVector& X) { para = X; }
+                                       // set parameter values
+   virtual void WG(bool wgx) { wg = wgx; }
+                                       // set wg
+
+   virtual bool IsValid() { return true; }
+                                       // return true is para is OK
+   bool IsValid(const ColumnVector& X, bool wgx=true)
+      { Set(X); WG(wgx); return IsValid(); }
+
+   virtual Real LogLikelihood() = 0;   // return the loglikelihhod
+   Real LogLikelihood(const ColumnVector& X, bool wgx=true)
+      { Set(X); WG(wgx); return LogLikelihood(); }
+
+   virtual ReturnMatrix Derivatives() = 0;
+                                       // column vector of derivatives
+   virtual ReturnMatrix FI() = 0;      // Fisher Information matrix
+   virtual ~LL_D_FI() {}               // to keep gnu happy
+};
+
+// This is the class for doing the maximum likelihood estimation
+
+class MLE_D_FI : public FindMaximum2
+{
+   // these replace the corresponding functions in FindMaximum2
+   void Value(const ColumnVector&, bool, Real&, bool&);
+   bool NextPoint(ColumnVector&, Real&);
+   Real LastDerivative(const ColumnVector&);
+
+   // the things we need for the analysis
+   LL_D_FI& LL;                        // reference to log-likelihood
+   int Lim;                            // maximum number of iterations
+   Real Criterion;                     // convergence criterion
+   ColumnVector Derivs;                // for the derivatives
+   LowerTriangularMatrix LT;           // Cholesky decomposition of FI
+   SymmetricMatrix Covariance;
+   DiagonalMatrix SE;
+
+public:
+   MLE_D_FI(LL_D_FI& ll, int lim=1000, Real criterion=0.0001)
+      : LL(ll), Lim(lim), Criterion(criterion) {}
+   void Fit(ColumnVector& Parameters);
+   void GetStandardErrors(ColumnVector&);
+   void GetCorrelations(SymmetricMatrix&);
+
+private:
+   void MakeCovariance();
+};
+
+
+#ifdef use_namespace
+}
+#endif
+
+
+
+#endif
+
+// body file: newmatnl.cpp
+
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmatrc.h b/Utilities/OSSIM/ossim_core/matrix/newmatrc.h
new file mode 100644
index 0000000000..ac62825745
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmatrc.h
@@ -0,0 +1,171 @@
+//$$ newmatrc.h              definition file for row/column classes
+
+// Copyright (C) 1991,2,3,4,7: R B Davies
+
+#ifndef NEWMATRC_LIB
+#define NEWMATRC_LIB 0
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#include "controlw.h"
+
+
+/************** classes MatrixRowCol, MatrixRow, MatrixCol *****************/
+
+// Used for accessing the rows and columns of matrices
+// All matrix classes must provide routines for calculating matrix rows and
+// columns. Assume rows can be found very efficiently.
+
+enum LSF { LoadOnEntry=1,StoreOnExit=2,DirectPart=4,StoreHere=8,HaveStore=16 };
+
+
+class LoadAndStoreFlag : public ControlWord
+{
+public:
+   LoadAndStoreFlag() {}
+   LoadAndStoreFlag(int i) : ControlWord(i) {}
+   LoadAndStoreFlag(LSF lsf) : ControlWord(lsf) {}
+   LoadAndStoreFlag(const ControlWord& cwx) : ControlWord(cwx) {}
+};
+
+class MatrixRowCol
+// the row or column of a matrix
+{
+public:                                        // these are public to avoid
+                                               // numerous friend statements
+   int length;                                 // row or column length
+   int skip;                                   // initial number of zeros
+   int storage;                                // number of stored elements
+   int rowcol;                                 // row or column number
+   GeneralMatrix* gm;                          // pointer to parent matrix
+   Real* data;                                 // pointer to local storage
+   LoadAndStoreFlag cw;                        // Load? Store? Is a Copy?
+   void IncrMat() { rowcol++; data += storage; }   // used by NextRow
+   void IncrDiag() { rowcol++; skip++; data++; }
+   void IncrId() { rowcol++; skip++; }
+   void IncrUT() { rowcol++; data += storage; storage--; skip++; }
+   void IncrLT() { rowcol++; data += storage; storage++; }
+
+public:
+   void Zero();                                // set elements to zero
+   void Add(const MatrixRowCol&);              // add a row/col
+   void AddScaled(const MatrixRowCol&, Real);  // add a multiple of a row/col
+   void Add(const MatrixRowCol&, const MatrixRowCol&);
+                                               // add two rows/cols
+   void Add(const MatrixRowCol&, Real);        // add a row/col
+   void NegAdd(const MatrixRowCol&, Real);     // Real - a row/col
+   void Sub(const MatrixRowCol&);              // subtract a row/col
+   void Sub(const MatrixRowCol&, const MatrixRowCol&);
+					       // sub a row/col from another
+   void RevSub(const MatrixRowCol&);           // subtract from a row/col
+   void ConCat(const MatrixRowCol&, const MatrixRowCol&);
+                                               // concatenate two row/cols
+   void Multiply(const MatrixRowCol&);         // multiply a row/col
+   void Multiply(const MatrixRowCol&, const MatrixRowCol&);
+                                               // multiply two row/cols
+   void KP(const MatrixRowCol&, const MatrixRowCol&);
+                                               // Kronecker Product two row/cols
+   void Copy(const MatrixRowCol&);             // copy a row/col
+   void CopyCheck(const MatrixRowCol&);        // ... check for data loss
+   void Check(const MatrixRowCol&);            // just check for data loss
+   void Check();                               // check full row/col present
+   void Copy(const Real*&);                    // copy from an array
+   void Copy(const int*&);                     // copy from an array
+   void Copy(Real);                            // copy from constant
+   void Add(Real);                             // add a constant
+   void Multiply(Real);                        // multiply by constant
+   Real SumAbsoluteValue();                    // sum of absolute values
+   Real MaximumAbsoluteValue1(Real r, int& i); // maximum of absolute values
+   Real MinimumAbsoluteValue1(Real r, int& i); // minimum of absolute values
+   Real Maximum1(Real r, int& i);              // maximum
+   Real Minimum1(Real r, int& i);              // minimum
+   Real Sum();                                 // sum of values
+   void Inject(const MatrixRowCol&);           // copy stored els of a row/col
+   void Negate(const MatrixRowCol&);           // change sign of a row/col
+   void Multiply(const MatrixRowCol&, Real);   // scale a row/col
+   friend Real DotProd(const MatrixRowCol&, const MatrixRowCol&);
+                                               // sum of pairwise product
+   Real* Data() { return data; }
+   int Skip() { return skip; }                 // number of elements skipped
+   int Storage() { return storage; }           // number of elements stored
+   int Length() { return length; }             // length of row or column
+   void Skip(int i) { skip=i; }
+   void Storage(int i) { storage=i; }
+   void Length(int i) { length=i; }
+   void SubRowCol(MatrixRowCol&, int, int) const;
+					       // get part of a row or column
+   MatrixRowCol() {}                           // to stop warning messages
+   ~MatrixRowCol();
+   FREE_CHECK(MatrixRowCol)
+};
+
+class MatrixRow : public MatrixRowCol
+{
+public:
+   // bodies for these are inline at the end of this .h file
+   MatrixRow(GeneralMatrix*, LoadAndStoreFlag, int=0);
+                                               // extract a row
+   ~MatrixRow();
+   void Next();                                // get next row
+   FREE_CHECK(MatrixRow)
+};
+
+class MatrixCol : public MatrixRowCol
+{
+public:
+   // bodies for these are inline at the end of this .h file
+   MatrixCol(GeneralMatrix*, LoadAndStoreFlag, int=0);
+                                               // extract a col
+   MatrixCol(GeneralMatrix*, Real*, LoadAndStoreFlag, int=0);
+                                               // store/retrieve a col
+   ~MatrixCol();
+   void Next();                                // get next row
+   FREE_CHECK(MatrixCol)
+};
+
+// MatrixColX is an alternative to MatrixCol where the complete
+// column is stored externally
+
+class MatrixColX : public MatrixRowCol
+{
+public:
+   // bodies for these are inline at the end of this .h file
+   MatrixColX(GeneralMatrix*, Real*, LoadAndStoreFlag, int=0);
+                                               // store/retrieve a col
+   ~MatrixColX();
+   void Next();                                // get next row
+   Real* store;                                // pointer to local storage
+                                               //    less skip
+   FREE_CHECK(MatrixColX)
+};
+
+/**************************** inline bodies ****************************/
+
+inline MatrixRow::MatrixRow(GeneralMatrix* gmx, LoadAndStoreFlag cwx, int row)
+{ gm=gmx; cw=cwx; rowcol=row; gm->GetRow(*this); }
+
+inline void MatrixRow::Next() { gm->NextRow(*this); }
+
+inline MatrixCol::MatrixCol(GeneralMatrix* gmx, LoadAndStoreFlag cwx, int col)
+{ gm=gmx; cw=cwx; rowcol=col; gm->GetCol(*this); }
+
+inline MatrixCol::MatrixCol(GeneralMatrix* gmx, Real* r,
+   LoadAndStoreFlag cwx, int col)
+{ gm=gmx; data=r; cw=cwx+StoreHere; rowcol=col; gm->GetCol(*this); }
+
+inline MatrixColX::MatrixColX(GeneralMatrix* gmx, Real* r,
+   LoadAndStoreFlag cwx, int col)
+{ gm=gmx; store=data=r; cw=cwx+StoreHere; rowcol=col; gm->GetCol(*this); }
+
+
+inline void MatrixCol::Next() { gm->NextCol(*this); }
+
+inline void MatrixColX::Next() { gm->NextCol(*this); }
+
+#ifdef use_namespace
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmatrm.cpp b/Utilities/OSSIM/ossim_core/matrix/newmatrm.cpp
new file mode 100644
index 0000000000..2aa5068a1b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmatrm.cpp
@@ -0,0 +1,216 @@
+//$$newmatrm.cpp                         rectangular matrix operations
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#define WANT_MATH
+
+#include "newmat.h"
+#include "newmatrm.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,12); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+// operations on rectangular matrices
+
+
+void RectMatrixRow::Reset (const Matrix& M, int row, int skip, int length)
+{
+   REPORT
+   RectMatrixRowCol::Reset
+      ( M.Store()+row*M.Ncols()+skip, length, 1, M.Ncols() );
+}
+
+void RectMatrixRow::Reset (const Matrix& M, int row)
+{
+   REPORT
+   RectMatrixRowCol::Reset( M.Store()+row*M.Ncols(), M.Ncols(), 1, M.Ncols() );
+}
+
+void RectMatrixCol::Reset (const Matrix& M, int skip, int col, int length)
+{
+   REPORT
+   RectMatrixRowCol::Reset
+      ( M.Store()+col+skip*M.Ncols(), length, M.Ncols(), 1 );
+}
+
+void RectMatrixCol::Reset (const Matrix& M, int col)
+{
+   REPORT
+   RectMatrixRowCol::Reset( M.Store()+col, M.Nrows(), M.Ncols(), 1 );
+}
+
+
+Real RectMatrixRowCol::SumSquare() const
+{
+   REPORT
+   long_Real sum = 0.0; int i = n; Real* s = store; int d = spacing;
+   // while (i--) { sum += (long_Real)*s * *s; s += d; }
+   if (i) for(;;)
+      { sum += (long_Real)*s * *s; if (!(--i)) break; s += d; }
+   return (Real)sum;
+}
+
+Real RectMatrixRowCol::operator*(const RectMatrixRowCol& rmrc) const
+{
+   REPORT
+   long_Real sum = 0.0; int i = n;
+   Real* s = store; int d = spacing;
+   Real* s1 = rmrc.store; int d1 = rmrc.spacing;
+   if (i!=rmrc.n)
+   {
+      Tracer tr("newmatrm");
+      Throw(InternalException("Dimensions differ in *"));
+   }
+   // while (i--) { sum += (long_Real)*s * *s1; s += d; s1 += d1; }
+   if (i) for(;;)
+      { sum += (long_Real)*s * *s1; if (!(--i)) break; s += d; s1 += d1; }
+   return (Real)sum;
+}
+
+void RectMatrixRowCol::AddScaled(const RectMatrixRowCol& rmrc, Real r)
+{
+   REPORT
+   int i = n; Real* s = store; int d = spacing;
+   Real* s1 = rmrc.store; int d1 = rmrc.spacing;
+   if (i!=rmrc.n)
+   {
+      Tracer tr("newmatrm");
+      Throw(InternalException("Dimensions differ in AddScaled"));
+   }
+   // while (i--) { *s += *s1 * r; s += d; s1 += d1; }
+   if (i) for (;;)
+      { *s += *s1 * r; if (!(--i)) break; s += d; s1 += d1; }
+}
+
+void RectMatrixRowCol::Divide(const RectMatrixRowCol& rmrc, Real r)
+{
+   REPORT
+   int i = n; Real* s = store; int d = spacing;
+   Real* s1 = rmrc.store; int d1 = rmrc.spacing;
+   if (i!=rmrc.n)
+   {
+      Tracer tr("newmatrm");
+      Throw(InternalException("Dimensions differ in Divide"));
+   }
+   // while (i--) { *s = *s1 / r; s += d; s1 += d1; }
+   if (i) for (;;) { *s = *s1 / r; if (!(--i)) break; s += d; s1 += d1; }
+}
+
+void RectMatrixRowCol::Divide(Real r)
+{
+   REPORT
+   int i = n; Real* s = store; int d = spacing;
+   // while (i--) { *s /= r; s += d; }
+   if (i) for (;;) { *s /= r; if (!(--i)) break; s += d; }
+}
+
+void RectMatrixRowCol::Negate()
+{
+   REPORT
+   int i = n; Real* s = store; int d = spacing;
+   // while (i--) { *s = - *s; s += d; }
+   if (i) for (;;) { *s = - *s; if (!(--i)) break; s += d; }
+}
+
+void RectMatrixRowCol::Zero()
+{
+   REPORT
+   int i = n; Real* s = store; int d = spacing;
+   // while (i--) { *s = 0.0; s += d; }
+   if (i) for (;;) { *s = 0.0; if (!(--i)) break; s += d; }
+}
+
+void ComplexScale(RectMatrixCol& U, RectMatrixCol& V, Real x, Real y)
+{
+   REPORT
+   int n = U.n;
+   if (n != V.n)
+   {
+      Tracer tr("newmatrm");
+      Throw(InternalException("Dimensions differ in ComplexScale"));
+   }
+   Real* u = U.store; Real* v = V.store; 
+   int su = U.spacing; int sv = V.spacing;
+   //while (n--)
+   //{
+   //   Real z = *u * x - *v * y;  *v =  *u * y + *v * x;  *u = z;
+   //   u += su;  v += sv;
+   //}
+   if (n) for (;;)
+   {
+      Real z = *u * x - *v * y;  *v =  *u * y + *v * x;  *u = z;
+      if (!(--n)) break;
+      u += su;  v += sv;
+   }
+}
+
+void Rotate(RectMatrixCol& U, RectMatrixCol& V, Real tau, Real s)
+{
+   REPORT
+   //  (U, V) = (U, V) * (c, s)  where  tau = s/(1+c), c^2 + s^2 = 1
+   int n = U.n;
+   if (n != V.n)
+   {
+      Tracer tr("newmatrm");
+      Throw(InternalException("Dimensions differ in Rotate"));
+   }
+   Real* u = U.store; Real* v = V.store;
+   int su = U.spacing; int sv = V.spacing;
+   //while (n--)
+   //{
+   //   Real zu = *u; Real zv = *v;
+   //   *u -= s * (zv + zu * tau); *v += s * (zu - zv * tau);
+   //   u += su;  v += sv;
+   //}
+   if (n) for(;;)
+   {
+      Real zu = *u; Real zv = *v;
+      *u -= s * (zv + zu * tau); *v += s * (zu - zv * tau);
+      if (!(--n)) break;
+      u += su;  v += sv;
+   }
+}
+
+
+// misc procedures for numerical things
+
+Real pythag(Real f, Real g, Real& c, Real& s)
+// return z=sqrt(f*f+g*g), c=f/z, s=g/z
+// set c=1,s=0 if z==0
+// avoid floating point overflow or divide by zero
+{
+   if (f==0 && g==0) { c=1.0; s=0.0; return 0.0; }
+   Real af = f>=0 ? f : -f;
+   Real ag = g>=0 ? g : -g;
+   if (ag<af)
+   {
+      REPORT
+      Real h = g/f; Real sq = sqrt(1.0+h*h);
+      if (f<0) sq = -sq;           // make return value non-negative
+      c = 1.0/sq; s = h/sq; return sq*f;
+   }
+   else
+   {
+      REPORT
+      Real h = f/g; Real sq = sqrt(1.0+h*h);
+      if (g<0) sq = -sq;
+      s = 1.0/sq; c = h/sq; return sq*g;
+   }
+}
+
+
+
+
+#ifdef use_namespace
+}
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/newmatrm.h b/Utilities/OSSIM/ossim_core/matrix/newmatrm.h
new file mode 100644
index 0000000000..fab132a7f9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/newmatrm.h
@@ -0,0 +1,145 @@
+//$$newmatrm.h                            rectangular matrix operations
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#ifndef NEWMATRM_LIB
+#define NEWMATRM_LIB 0
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+// operations on rectangular matrices
+
+class RectMatrixCol;
+
+class RectMatrixRowCol
+// a class for accessing rows and columns of rectangular matrices
+{
+protected:
+#ifdef use_namespace              // to make namespace work
+public:
+#endif
+   Real* store;                   // pointer to storage
+   int n;                         // number of elements
+   int spacing;                   // space between elements
+   int shift;                     // space between cols or rows
+   RectMatrixRowCol(Real* st, int nx, int sp, int sh)
+      : store(st), n(nx), spacing(sp), shift(sh) {}
+   void Reset(Real* st, int nx, int sp, int sh)
+      { store=st; n=nx; spacing=sp; shift=sh; }
+public:
+   Real operator*(const RectMatrixRowCol&) const;         // dot product
+   void AddScaled(const RectMatrixRowCol&, Real);         // add scaled
+   void Divide(const RectMatrixRowCol&, Real);            // scaling
+   void Divide(Real);                                     // scaling
+   void Negate();                                         // change sign
+   void Zero();                                           // zero row col
+   Real& operator[](int i) { return *(store+i*spacing); } // element
+   Real SumSquare() const;                                // sum of squares
+   Real& First() { return *store; }                       // get first element
+   void DownDiag() { store += (shift+spacing); n--; }
+   void UpDiag() { store -= (shift+spacing); n++; }
+   friend void ComplexScale(RectMatrixCol&, RectMatrixCol&, Real, Real);
+   friend void Rotate(RectMatrixCol&, RectMatrixCol&, Real, Real);
+   FREE_CHECK(RectMatrixRowCol)
+};
+
+class RectMatrixRow : public RectMatrixRowCol
+{
+public:
+   RectMatrixRow(const Matrix&, int, int, int);
+   RectMatrixRow(const Matrix&, int);
+   void Reset(const Matrix&, int, int, int);
+   void Reset(const Matrix&, int);
+   Real& operator[](int i) { return *(store+i); }
+   void Down() { store += shift; }
+   void Right() { store++; n--; }
+   void Up() { store -= shift; }
+   void Left() { store--; n++; }
+   FREE_CHECK(RectMatrixRow)
+};
+
+class RectMatrixCol : public RectMatrixRowCol
+{
+public:
+   RectMatrixCol(const Matrix&, int, int, int);
+   RectMatrixCol(const Matrix&, int);
+   void Reset(const Matrix&, int, int, int);
+   void Reset(const Matrix&, int);
+   void Down() { store += spacing; n--; }
+   void Right() { store++; }
+   void Up() { store -= spacing; n++; }
+   void Left() { store--; }
+   friend void ComplexScale(RectMatrixCol&, RectMatrixCol&, Real, Real);
+   friend void Rotate(RectMatrixCol&, RectMatrixCol&, Real, Real);
+   FREE_CHECK(RectMatrixCol)
+};
+
+class RectMatrixDiag : public RectMatrixRowCol
+{
+public:
+   RectMatrixDiag(const DiagonalMatrix& D)
+      : RectMatrixRowCol(D.Store(), D.Nrows(), 1, 1) {}
+   Real& operator[](int i) { return *(store+i); }
+   void DownDiag() { store++; n--; }
+   void UpDiag() { store--; n++; }
+   FREE_CHECK(RectMatrixDiag)
+};
+
+
+
+
+inline RectMatrixRow::RectMatrixRow
+   (const Matrix& M, int row, int skip, int length)
+   : RectMatrixRowCol( M.Store()+row*M.Ncols()+skip, length, 1, M.Ncols() ) {}
+
+inline RectMatrixRow::RectMatrixRow (const Matrix& M, int row)
+   : RectMatrixRowCol( M.Store()+row*M.Ncols(), M.Ncols(), 1, M.Ncols() ) {}
+
+inline RectMatrixCol::RectMatrixCol
+   (const Matrix& M, int skip, int col, int length)
+   : RectMatrixRowCol( M.Store()+col+skip*M.Ncols(), length, M.Ncols(), 1 ) {}
+
+inline RectMatrixCol::RectMatrixCol (const Matrix& M, int col)
+   : RectMatrixRowCol( M.Store()+col, M.Nrows(), M.Ncols(), 1 ) {}
+
+inline Real square(Real x) { return x*x; }
+inline Real sign(Real x, Real y)
+   { return (y>=0) ? x : -x; }                    // assume x >=0
+
+
+// Misc numerical things
+
+Real pythag(Real f, Real g, Real& c, Real& s);
+
+inline void GivensRotation(Real cGivens, Real sGivens, Real& x, Real& y)
+{
+   // allow for possibility &x = &y
+   Real tmp0 = cGivens * x + sGivens * y;
+   Real tmp1 = -sGivens * x + cGivens * y;
+   x = tmp0; y = tmp1;
+}
+   
+inline void GivensRotationR(Real cGivens, Real sGivens, Real& x, Real& y)
+{
+   // also change sign of y
+   // allow for possibility &x = &y
+   Real tmp0 = cGivens * x + sGivens * y;
+   Real tmp1 = sGivens * x - cGivens * y;
+   x = tmp0; y = tmp1;
+}   
+
+
+
+
+
+#ifdef use_namespace
+}
+#endif
+
+#endif
+
+// body file: newmatrm.cpp
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/nl_ex.txt b/Utilities/OSSIM/ossim_core/matrix/nl_ex.txt
new file mode 100644
index 0000000000..78bfef7523
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/nl_ex.txt
@@ -0,0 +1,42 @@
+Fitting parameters
+
+               70.02918529     209.6252324 0.1541078372
+               94.78295699
+               49.23360397     147.1803571 0.1734849298
+               1.848950128
+               0.7422941575      1.70673579 0.1733822274
+               0.2113527145
+               0.1955923541   0.06041118379 0.1754552928
+               0.1754553498
+               0.1754553471 2.341694142e-08 0.1754553393
+Converged
+
+
+Estimates and standard errors
+     19.77       0.73 
+    -23.63       0.82 
+      0.35       0.04 
+
+
+Residual s.d. =       0.42
+
+CorrelationMatrix
+      1.00      -0.05      -0.91 
+     -0.05       1.00      -0.31 
+     -0.91      -0.31       1.00 
+
+
+X, Y, Residual, Hat
+      1.00       3.20       0.10       0.89 
+      2.00       7.90      -0.11       0.33 
+      3.00      11.10      -0.38       0.39 
+      4.00      14.50       0.58       0.35 
+      6.00      16.70      -0.16       0.32 
+      8.00      18.30      -0.02       0.73 
+
+
+Var/cov
+        0.5295        -0.0324        -0.0250 
+       -0.0324         0.6668        -0.0096 
+       -0.0250        -0.0096         0.0014 
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/precisio.h b/Utilities/OSSIM/ossim_core/matrix/precisio.h
new file mode 100644
index 0000000000..f5ef68cbb7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/precisio.h
@@ -0,0 +1,241 @@
+//$$ precisio.h                          floating point constants
+
+#ifndef PRECISION_LIB
+#define PRECISION_LIB 0
+
+#ifdef _STANDARD_                 // standard library available
+#include <limits>
+#endif
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef _STANDARD_                 // standard library available
+
+using namespace std;
+	
+class FloatingPointPrecision
+{
+public:
+   static int Dig()              // number of decimal digits or precision
+      { return numeric_limits<Real>::digits10 ; }
+
+   static Real Epsilon()         // smallest number such that 1+Eps!=Eps
+      { return numeric_limits<Real>::epsilon(); }
+
+   static int Mantissa()         // bits in mantisa
+      { return numeric_limits<Real>::digits; }
+
+   static Real Maximum()         // maximum value
+      { return numeric_limits<Real>::max(); }
+
+   static int MaximumDecimalExponent()  // maximum decimal exponent
+      { return numeric_limits<Real>::max_exponent10; }
+
+   static int MaximumExponent()  // maximum binary exponent
+      { return numeric_limits<Real>::max_exponent; }
+
+   static Real LnMaximum()       // natural log of maximum
+      { return (Real)log(Maximum()); }
+
+   static Real Minimum()         // minimum positive value
+      { return numeric_limits<Real>::min(); } 
+
+   static int MinimumDecimalExponent() // minimum decimal exponent
+      { return numeric_limits<Real>::min_exponent10; }
+
+   static int MinimumExponent()  // minimum binary exponent
+      { return numeric_limits<Real>::min_exponent; }
+
+   static Real LnMinimum()       // natural log of minimum
+      { return (Real)log(Minimum()); }
+
+   static int Radix()            // exponent radix
+      { return numeric_limits<Real>::radix; }
+
+   static int Rounds()           // addition rounding (1 = does round)
+   {
+	  return numeric_limits<Real>::round_style ==
+		 round_to_nearest ? 1 : 0;
+   }
+
+};
+
+
+#else                              // _STANDARD_ not defined
+
+#ifndef SystemV                    // if there is float.h
+
+
+#ifdef USING_FLOAT
+
+
+class FloatingPointPrecision
+{
+public:
+   static int Dig()
+      { return FLT_DIG; }        // number of decimal digits or precision
+
+   static Real Epsilon()
+      { return FLT_EPSILON; }    // smallest number such that 1+Eps!=Eps
+
+   static int Mantissa()
+      { return FLT_MANT_DIG; }   // bits in mantisa
+
+   static Real Maximum()
+      { return FLT_MAX; }        // maximum value
+
+   static int MaximumDecimalExponent()
+      { return FLT_MAX_10_EXP; } // maximum decimal exponent
+
+   static int MaximumExponent()
+      { return FLT_MAX_EXP; }    // maximum binary exponent
+
+   static Real LnMaximum()
+      { return (Real)log(Maximum()); } // natural log of maximum
+
+   static Real Minimum()
+      { return FLT_MIN; }        // minimum positive value
+
+   static int MinimumDecimalExponent()
+      { return FLT_MIN_10_EXP; } // minimum decimal exponent
+
+   static int MinimumExponent()
+      { return FLT_MIN_EXP; }    // minimum binary exponent
+
+   static Real LnMinimum()
+      { return (Real)log(Minimum()); } // natural log of minimum
+
+   static int Radix()
+      { return FLT_RADIX; }      // exponent radix
+
+   static int Rounds()
+      { return FLT_ROUNDS; }     // addition rounding (1 = does round)
+
+};
+
+#endif                           // USING_FLOAT
+
+
+#ifdef USING_DOUBLE
+
+class FloatingPointPrecision
+{
+public:
+
+   static int Dig()
+      { return DBL_DIG; }        // number of decimal digits or precision
+
+   static Real Epsilon()
+      { return DBL_EPSILON; }    // smallest number such that 1+Eps!=Eps
+
+   static int Mantissa()
+      { return DBL_MANT_DIG; }   // bits in mantisa
+
+   static Real Maximum()
+      { return DBL_MAX; }        // maximum value
+
+   static int MaximumDecimalExponent()
+      { return DBL_MAX_10_EXP; } // maximum decimal exponent
+
+   static int MaximumExponent()
+      { return DBL_MAX_EXP; }    // maximum binary exponent
+
+   static Real LnMaximum()
+      { return (Real)log(Maximum()); } // natural log of maximum
+
+   static Real Minimum()
+   {
+//#ifdef __BCPLUSPLUS__
+//       return 2.225074e-308;     // minimum positive value
+//#else
+       return DBL_MIN;
+//#endif
+   }
+
+   static int MinimumDecimalExponent()
+      { return DBL_MIN_10_EXP; } // minimum decimal exponent
+
+   static int MinimumExponent()
+      { return DBL_MIN_EXP; }    // minimum binary exponent
+
+   static Real LnMinimum()
+      { return (Real)log(Minimum()); } // natural log of minimum
+
+
+   static int Radix()
+      { return FLT_RADIX; }      // exponent radix
+
+   static int Rounds()
+      { return FLT_ROUNDS; }     // addition rounding (1 = does round)
+
+};
+
+#endif                             // USING_DOUBLE
+
+#else                              // if there is no float.h
+
+#ifdef USING_FLOAT
+
+class FloatingPointPrecision
+{
+public:
+
+   static Real Epsilon()
+      { return pow(2.0,(int)(1-FSIGNIF)); }
+                                   // smallest number such that 1+Eps!=Eps
+
+   static Real Maximum()
+      { return MAXFLOAT; }            // maximum value
+
+   static Real LnMaximum()
+      { return (Real)log(Maximum()); }  // natural log of maximum
+
+   static Real Minimum()
+      { return MINFLOAT; }             // minimum positive value
+
+   static Real LnMinimum()
+      { return (Real)log(Minimum()); }  // natural log of minimum
+
+};
+
+#endif                                  // USING_FLOAT
+
+
+#ifdef USING_DOUBLE
+
+class FloatingPointPrecision
+{
+public:
+
+   static Real Epsilon()
+      { return pow(2.0,(int)(1-DSIGNIF)); }
+                                      // smallest number such that 1+Eps!=Eps
+
+   static Real Maximum()
+      { return MAXDOUBLE; }           // maximum value
+
+   static Real LnMaximum()
+      { return LN_MAXDOUBLE; }        // natural log of maximum
+
+   static Real Minimum()
+      { return MINDOUBLE; }
+
+   static Real LnMinimum()
+      { return LN_MINDOUBLE; }        // natural log of minimum
+};
+
+#endif                                // USING_DOUBLE
+
+#endif                                // SystemV
+
+#endif                                // _STANDARD_
+
+#ifdef use_namespace
+}
+#endif                                // use_namespace
+
+
+
+#endif                                // PRECISION_LIB
diff --git a/Utilities/OSSIM/ossim_core/matrix/sl_ex.txt b/Utilities/OSSIM/ossim_core/matrix/sl_ex.txt
new file mode 100644
index 0000000000..b578f10a72
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/sl_ex.txt
@@ -0,0 +1,21 @@
+-10   -2.15443
+-9   -2.08008
+-8   -2
+-7   -1.91293
+-6   -1.81712
+-5   -1.70998
+-4   -1.5874
+-3   -1.44225
+-2   -1.25992
+-1   -1.00001
+0   0
+1   1.00001
+2   1.25992
+3   1.44225
+4   1.58741
+5   1.70998
+6   1.81712
+7   1.91293
+8   2
+9   2.08008
+10   2.15443
diff --git a/Utilities/OSSIM/ossim_core/matrix/solution.cpp b/Utilities/OSSIM/ossim_core/matrix/solution.cpp
new file mode 100644
index 0000000000..128bf5b20a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/solution.cpp
@@ -0,0 +1,203 @@
+//$$ solution.cpp                    // solve routines
+
+// Copyright (C) 1994: R B Davies
+
+
+#define WANT_STREAM                  // include.h will get stream fns
+#define WANT_MATH                    // include.h will get math fns
+
+#include "include.h"
+#include "boolean.h"
+#include "myexcept.h"
+
+#include "solution.h"
+
+#ifdef use_namespace
+namespace RBD_COMMON {
+#endif
+
+R1_R1::~R1_R1()
+{
+}
+
+void R1_R1::Set(Real X)
+{
+   if ((!minXinf && X <= minX) || (!maxXinf && X >= maxX))
+       Throw(SolutionException("X value out of range"));
+   x = X; xSet = true;
+}
+
+R1_R1::operator Real()
+{
+   if (!xSet) Throw(SolutionException("Value of X not set"));
+   Real y = operator()();
+   return y;
+}
+
+unsigned long SolutionException::Select;
+
+SolutionException::SolutionException(const char* a_what) : Exception()
+{
+   Select = Exception::Select;
+   AddMessage("Error detected by solution package\n");
+   AddMessage(a_what); AddMessage("\n");
+   if (a_what) Tracer::AddTrace();
+};
+
+inline Real square(Real x) { return x*x; }
+
+void OneDimSolve::LookAt(int V)
+{
+   lim--;
+   if (!lim) Throw(SolutionException("Does not converge"));
+   Last = V;
+   Real yy = function(x[V]) - YY;
+   Finish = (fabs(yy) <= accY) || (Captured && fabs(x[L]-x[U]) <= accX );
+   y[V] = vpol*yy;
+}
+
+void OneDimSolve::HFlip() { hpol=-hpol; State(U,C,L); }
+
+void OneDimSolve::VFlip()
+   { vpol = -vpol; y[0] = -y[0]; y[1] = -y[1]; y[2] = -y[2]; }
+
+void OneDimSolve::Flip()
+{
+   hpol=-hpol; vpol=-vpol; State(U,C,L);
+   y[0] = -y[0]; y[1] = -y[1]; y[2] = -y[2];
+}
+
+void OneDimSolve::State(int I, int J, int K) { L=I; C=J; U=K; }
+
+void OneDimSolve::Linear(int I, int J, int K)
+{
+   x[J] = (x[I]*y[K] - x[K]*y[I])/(y[K] - y[I]);
+   // cout << "Linear\n";
+}
+
+void OneDimSolve::Quadratic(int I, int J, int K)
+{
+   // result to overwrite I
+   Real YJK, YIK, YIJ, XKI, XKJ;
+   YJK = y[J] - y[K]; YIK = y[I] - y[K]; YIJ = y[I] - y[J];
+   XKI = (x[K] - x[I]);
+   XKJ = (x[K]*y[J] - x[J]*y[K])/YJK;
+   if ( square(YJK/YIK)>(x[K] - x[J])/XKI ||
+      square(YIJ/YIK)>(x[J] - x[I])/XKI )
+   {
+      x[I] = XKJ;
+      // cout << "Quadratic - exceptional\n";
+   }
+   else
+   {
+      XKI = (x[K]*y[I] - x[I]*y[K])/YIK;
+      x[I] = (XKJ*y[I] - XKI*y[J])/YIJ;
+      // cout << "Quadratic - normal\n";
+   }
+}
+
+Real OneDimSolve::Solve(Real Y, Real X, Real Dev, int Lim)
+{
+   enum Loop { start, captured1, captured2, binary, finish };
+   Tracer et("OneDimSolve::Solve");
+   lim=Lim; Captured = false;
+   if (Dev==0.0) Throw(SolutionException("Dev is zero"));
+   L=0; C=1; U=2; vpol=1; hpol=1; y[C]=0.0; y[U]=0.0;
+   if (Dev<0.0) { hpol=-1; Dev = -Dev; }
+   YY=Y;                                // target value
+   x[L] = X;                            // initial trial value
+   if (!function.IsValid(X))
+      Throw(SolutionException("Starting value is invalid"));
+   Loop TheLoop = start;
+   for (;;)
+   {
+      switch (TheLoop)
+      {
+      case start:
+         LookAt(L); if (Finish) { TheLoop = finish; break; }
+         if (y[L]>0.0) VFlip();               // so Y[L] < 0
+
+         x[U] = X + Dev * hpol;
+         if (!function.maxXinf && x[U] > function.maxX)
+            x[U] = (function.maxX + X) / 2.0;
+         if (!function.minXinf && x[U] < function.minX)
+            x[U] = (function.minX + X) / 2.0;
+
+         LookAt(U); if (Finish) { TheLoop = finish; break; }
+         if (y[U] > 0.0) { TheLoop = captured1; Captured = true; break; }
+         if (y[U] == y[L])
+            Throw(SolutionException("Function is flat"));
+         if (y[U] < y[L]) HFlip();             // Change direction
+         State(L,U,C);
+         for (i=0; i<20; i++)
+         {
+            // cout << "Searching for crossing point\n";
+            // Have L C then crossing point, Y[L]<Y[C]<0
+            x[U] = x[C] + Dev * hpol;
+            if (!function.maxXinf && x[U] > function.maxX)
+            x[U] = (function.maxX + x[C]) / 2.0;
+            if (!function.minXinf && x[U] < function.minX)
+            x[U] = (function.minX + x[C]) / 2.0;
+
+            LookAt(U); if (Finish) { TheLoop = finish; break; }
+            if (y[U] > 0) { TheLoop = captured2; Captured = true; break; }
+            if (y[U] < y[C])
+                Throw(SolutionException("Function is not monotone"));
+            Dev *= 2.0;
+            State(C,U,L);
+         }
+         if (TheLoop != start ) break;
+         Throw(SolutionException("Cannot locate a crossing point"));
+
+      case captured1:
+         // cout << "Captured - 1\n";
+         // We have 2 points L and U with crossing between them
+         Linear(L,C,U);                   // linear interpolation
+                                          // - result to C
+         LookAt(C); if (Finish) { TheLoop = finish; break; }
+         if (y[C] > 0.0) Flip();            // Want y[C] < 0
+         if (y[C] < 0.5*y[L]) { State(C,L,U); TheLoop = binary; break; }
+
+      case captured2:
+         // cout << "Captured - 2\n";
+         // We have L,C before crossing, U after crossing
+         Quadratic(L,C,U);                // quad interpolation
+                                          // - result to L
+         State(C,L,U);
+         if ((x[C] - x[L])*hpol <= 0.0 || (x[C] - x[U])*hpol >= 0.0)
+            { TheLoop = captured1; break; }
+         LookAt(C); if (Finish) { TheLoop = finish; break; }
+         // cout << "Through first stage\n";
+         if (y[C] > 0.0) Flip();
+         if (y[C] > 0.5*y[L]) { TheLoop = captured2; break; }
+         else { State(C,L,U); TheLoop = captured1; break; }
+
+      case binary:
+         // We have L, U around crossing - do binary search
+         // cout << "Binary\n";
+         for (i=3; i; i--)
+         {
+            x[C] = 0.5*(x[L]+x[U]);
+            LookAt(C); if (Finish) { TheLoop = finish; break; }
+            if (y[C]>0.0) State(L,U,C); else State(C,L,U);
+         }
+         if (TheLoop != binary) break;
+         TheLoop = captured1; break;
+
+      case finish:
+	 return x[Last];
+
+      }
+   }
+}
+
+bool R1_R1::IsValid(Real X)
+{
+   Set(X);
+   return (minXinf || x > minX) && (maxXinf || x < maxX);
+}
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/solution.h b/Utilities/OSSIM/ossim_core/matrix/solution.h
new file mode 100644
index 0000000000..d44ed3ba6b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/solution.h
@@ -0,0 +1,96 @@
+//$$ solution.h                      // solve routines
+
+#include "boolean.h"
+#include "myexcept.h"
+
+#ifdef use_namespace
+namespace RBD_COMMON {
+#endif
+
+
+// Solve the equation f(x)=y for x where f is a monotone continuous
+// function of x
+// Essentially Brent s method
+
+// You need to derive a class from R1_R1 and override "operator()"
+// with the function you want to solve.
+// Use an object from this class in OneDimSolve
+
+class R1_R1
+{
+   // the prototype for a Real function of a Real variable
+   // you need to derive your function from this one and put in your
+   // function for operator() at least. You probably also want to set up a
+   // constructor to put in additional parameter values (e.g. that will not
+   // vary during a solve)
+
+protected:
+   Real x;                             // Current x value
+   bool xSet;                          // true if a value assigned to x
+
+public:
+   virtual ~R1_R1();
+   
+   Real minX, maxX;                    // range of value x
+   bool minXinf, maxXinf;              // true if these are infinite
+   R1_R1() : xSet(false), minXinf(true), maxXinf(true) {}
+   virtual Real operator()() = 0;      // function value at current x
+                                       // set current x
+   virtual void Set(Real X);           // set x, check OK
+   Real operator()(Real X) { Set(X); return operator()(); }
+                                       // set x, return value
+   virtual bool IsValid(Real X);
+   operator Real();                    // implicit conversion
+};
+
+class SolutionException : public Exception
+{
+public:
+   static unsigned long Select;
+   SolutionException(const char* a_what = 0);
+};
+
+class OneDimSolve
+{
+   R1_R1& function;                     // reference to the function
+   Real accX;                           // accuracy in X direction
+   Real accY;                           // accuracy in Y direction
+   int lim;                             // maximum number of iterations
+
+public:
+   OneDimSolve(R1_R1& f, Real AccY = 0.0001, Real AccX = 0.0)
+      : function(f), accX(AccX), accY(AccY) {}
+                       // f is an R1_R1 function
+   Real Solve(Real Y, Real X, Real Dev, int Lim=100);
+                       // Solve for x in Y=f(x)
+                       // X is the initial trial value of x
+                       // X+Dev is the second trial value
+                       // program returns a value of x such that
+                       // |Y-f(x)| <= accY or |f.inv(Y)-x| <= accX
+
+private:
+   Real x[3], y[3];                         // Trial values of X and Y
+   int L,C,U,Last;                          // Locations of trial values
+   int vpol, hpol;                          // polarities
+   Real YY;                                 // target value
+   int i;
+   void LookAt(int);                        // get new value of function
+   bool Finish;                             // true if LookAt finds conv.
+   bool Captured;                           // true when target surrounded
+   void VFlip();
+   void HFlip();
+   void Flip();
+   void State(int I, int J, int K);
+   void Linear(int, int, int);
+   void Quadratic(int, int, int);
+};
+
+
+#ifdef use_namespace
+}
+#endif
+
+// body file: solution.cpp
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/sort.cpp b/Utilities/OSSIM/ossim_core/matrix/sort.cpp
new file mode 100644
index 0000000000..a30081135c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/sort.cpp
@@ -0,0 +1,272 @@
+//$$ sort.cpp                            Sorting
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#define WANT_MATH
+
+#include "include.h"
+
+#include "newmatap.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,13); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+/******************************** Quick sort ********************************/
+
+// Quicksort.
+// Essentially the method described in Sedgewick s algorithms in C++
+// My version is still partially recursive, unlike Segewick s, but the
+// smallest segment of each split is used in the recursion, so it should
+// not overlead the stack.
+
+// If the process does not seems to be converging an exception is thrown.
+
+
+#define DoSimpleSort 17            // when to switch to insert sort
+#define MaxDepth 50                // maximum recursion depth
+
+static void MyQuickSortDescending(Real* first, Real* last, int depth);
+static void InsertionSortDescending(Real* first, const int length,
+   int guard);
+static Real SortThreeDescending(Real* a, Real* b, Real* c);
+
+static void MyQuickSortAscending(Real* first, Real* last, int depth);
+static void InsertionSortAscending(Real* first, const int length,
+   int guard);
+
+
+void SortDescending(GeneralMatrix& GM)
+{
+   REPORT
+   Tracer et("QuickSortDescending");
+
+   Real* data = GM.Store(); int max = GM.Storage();
+
+   if (max > DoSimpleSort) MyQuickSortDescending(data, data + max - 1, 0);
+   InsertionSortDescending(data, max, DoSimpleSort);
+
+}
+
+static Real SortThreeDescending(Real* a, Real* b, Real* c)
+{
+   // sort *a, *b, *c; return *b; optimise for already sorted
+   if (*a >= *b)
+   {
+      if (*b >= *c) { REPORT return *b; }
+      else if (*a >= *c) { REPORT Real x = *c; *c = *b; *b = x; return x; }
+      else { REPORT Real x = *a; *a = *c; *c = *b; *b = x; return x; }
+   }
+   else if (*c >= *b) { REPORT Real x = *c; *c = *a; *a = x; return *b; }
+   else if (*a >= *c) { REPORT Real x = *a; *a = *b; *b = x; return x; }
+   else { REPORT Real x = *c; *c = *a; *a = *b; *b = x; return x; }
+}
+
+static void InsertionSortDescending(Real* first, const int length,
+   int guard)
+// guard gives the length of the sequence to scan to find first
+// element (eg = length)
+{
+   REPORT
+   if (length <= 1) return;
+
+   // scan for first element
+   Real* f = first; Real v = *f; Real* h = f;
+   if (guard > length) { REPORT guard = length; }
+   int i = guard - 1;
+   while (i--) if (v < *(++f)) { v = *f; h = f; }
+   *h = *first; *first = v;
+
+   // do the sort
+   i = length - 1; f = first;
+   while (i--)
+   {
+      Real* g = f++; h = f; v = *h;
+      while (*g < v) *h-- = *g--;
+      *h = v;
+   }
+}
+
+static void MyQuickSortDescending(Real* first, Real* last, int depth)
+{
+   REPORT
+   for (;;)
+   {
+      const int length = last - first + 1;
+      if (length < DoSimpleSort) { REPORT return; }
+      if (depth++ > MaxDepth)
+         Throw(ConvergenceException("QuickSortDescending fails: "));
+      Real* centre = first + length/2;
+      const Real test = SortThreeDescending(first, centre, last);
+      Real* f = first; Real* l = last;
+      for (;;)
+      {
+         while (*(++f) > test) {}
+         while (*(--l) < test) {}
+         if (l <= f) break;
+         const Real temp = *f; *f = *l; *l = temp;
+      }
+      if (f > centre)
+         { REPORT MyQuickSortDescending(l+1, last, depth); last = f-1; }
+      else { REPORT MyQuickSortDescending(first, f-1, depth); first = l+1; }
+   }
+}
+
+void SortAscending(GeneralMatrix& GM)
+{
+   REPORT
+   Tracer et("QuickSortAscending");
+
+   Real* data = GM.Store(); int max = GM.Storage();
+
+   if (max > DoSimpleSort) MyQuickSortAscending(data, data + max - 1, 0);
+   InsertionSortAscending(data, max, DoSimpleSort);
+
+}
+
+static void InsertionSortAscending(Real* first, const int length,
+   int guard)
+// guard gives the length of the sequence to scan to find first
+// element (eg guard = length)
+{
+   REPORT
+   if (length <= 1) return;
+
+   // scan for first element
+   Real* f = first; Real v = *f; Real* h = f;
+   if (guard > length) { REPORT guard = length; }
+   int i = guard - 1;
+   while (i--) if (v > *(++f)) { v = *f; h = f; }
+   *h = *first; *first = v;
+
+   // do the sort
+   i = length - 1; f = first;
+   while (i--)
+   {
+      Real* g = f++; h = f; v = *h;
+      while (*g > v) *h-- = *g--;
+      *h = v;
+   }
+}
+static void MyQuickSortAscending(Real* first, Real* last, int depth)
+{
+   REPORT
+   for (;;)
+   {
+      const int length = last - first + 1;
+      if (length < DoSimpleSort) { REPORT return; }
+      if (depth++ > MaxDepth)
+         Throw(ConvergenceException("QuickSortAscending fails: "));
+      Real* centre = first + length/2;
+      const Real test = SortThreeDescending(last, centre, first);
+      Real* f = first; Real* l = last;
+      for (;;)
+      {
+         while (*(++f) < test) {}
+         while (*(--l) > test) {}
+         if (l <= f) break;
+         const Real temp = *f; *f = *l; *l = temp;
+      }
+      if (f > centre)
+         { REPORT MyQuickSortAscending(l+1, last, depth); last = f-1; }
+      else { REPORT MyQuickSortAscending(first, f-1, depth); first = l+1; }
+   }
+}
+
+//********* sort diagonal matrix & rearrange matrix columns ****************
+
+// used by SVD
+
+// these are for sorting singular values - should be updated with faster
+// sorts that handle exchange of columns better
+// however time is probably not significant compared with SVD time
+
+void SortSV(DiagonalMatrix& D, Matrix& U, bool ascending)
+{
+   REPORT
+   Tracer trace("SortSV_DU");
+   int m = U.Nrows(); int n = U.Ncols();
+   if (n != D.Nrows()) Throw(IncompatibleDimensionsException(D,U));
+   Real* u = U.Store();
+   for (int i=0; i<n; i++)
+   {
+      int k = i; Real p = D.element(i);
+      if (ascending)
+      {
+         for (int j=i+1; j<n; j++)
+            { if (D.element(j) < p) { k = j; p = D.element(j); } }
+      }
+      else
+      {
+         for (int j=i+1; j<n; j++)
+         { if (D.element(j) > p) { k = j; p = D.element(j); } }
+      }
+      if (k != i)
+      {
+         D.element(k) = D.element(i); D.element(i) = p; int j = m;
+         Real* uji = u + i; Real* ujk = u + k;
+         if (j) for(;;)
+         {
+            p = *uji; *uji = *ujk; *ujk = p;
+            if (!(--j)) break;
+            uji += n; ujk += n;
+         }
+      }
+   }
+}
+
+void SortSV(DiagonalMatrix& D, Matrix& U, Matrix& V, bool ascending)
+{
+   REPORT
+   Tracer trace("SortSV_DUV");
+   int mu = U.Nrows(); int mv = V.Nrows(); int n = D.Nrows();
+   if (n != U.Ncols()) Throw(IncompatibleDimensionsException(D,U));
+   if (n != V.Ncols()) Throw(IncompatibleDimensionsException(D,V));
+   Real* u = U.Store(); Real* v = V.Store();
+   for (int i=0; i<n; i++)
+   {
+      int k = i; Real p = D.element(i);
+      if (ascending)
+      {
+         for (int j=i+1; j<n; j++)
+            { if (D.element(j) < p) { k = j; p = D.element(j); } }
+      }
+      else
+      {
+         for (int j=i+1; j<n; j++)
+         { if (D.element(j) > p) { k = j; p = D.element(j); } }
+      }
+      if (k != i)
+      {
+         D.element(k) = D.element(i); D.element(i) = p;
+         Real* uji = u + i; Real* ujk = u + k;
+         Real* vji = v + i; Real* vjk = v + k;
+         int j = mu;
+         if (j) for(;;)
+         {
+            p = *uji; *uji = *ujk; *ujk = p; if (!(--j)) break;
+            uji += n; ujk += n;
+         }
+         j = mv;
+         if (j) for(;;)
+         {
+            p = *vji; *vji = *vjk; *vjk = p; if (!(--j)) break;
+            vji += n; vjk += n;
+         }
+      }
+   }
+}
+
+
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/submat.cpp b/Utilities/OSSIM/ossim_core/matrix/submat.cpp
new file mode 100644
index 0000000000..79f57147be
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/submat.cpp
@@ -0,0 +1,340 @@
+//$$ submat.cpp                         submatrices
+
+// Copyright (C) 1991,2,3,4: R B Davies
+
+#include "include.h"
+
+#include "newmat.h"
+#include "newmatrc.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,11); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+/****************************** submatrices *********************************/
+
+GetSubMatrix BaseMatrix::SubMatrix(int first_row, int last_row, int first_col,
+   int last_col) const
+{
+   REPORT
+   Tracer tr("SubMatrix");
+   int a = first_row - 1; int b = last_row - first_row + 1;
+   int c = first_col - 1; int d = last_col - first_col + 1;
+   if (a<0 || b<0 || c<0 || d<0) Throw(SubMatrixDimensionException());
+                             // allow zero rows or columns
+   return GetSubMatrix(this, a, b, c, d, false);
+}
+
+GetSubMatrix BaseMatrix::SymSubMatrix(int first_row, int last_row) const
+{
+   REPORT
+   Tracer tr("SubMatrix(symmetric)");
+   int a = first_row - 1; int b = last_row - first_row + 1;
+   if (a<0 || b<0) Throw(SubMatrixDimensionException());
+                             // allow zero rows or columns
+   return GetSubMatrix( this, a, b, a, b, true);
+}
+
+GetSubMatrix BaseMatrix::Row(int first_row) const
+{
+   REPORT
+   Tracer tr("SubMatrix(row)");
+   int a = first_row - 1;
+   if (a<0) Throw(SubMatrixDimensionException());
+   return GetSubMatrix(this, a, 1, 0, -1, false);
+}
+
+GetSubMatrix BaseMatrix::Rows(int first_row, int last_row) const
+{
+   REPORT
+   Tracer tr("SubMatrix(rows)");
+   int a = first_row - 1; int b = last_row - first_row + 1;
+   if (a<0 || b<0) Throw(SubMatrixDimensionException());
+                             // allow zero rows or columns
+   return GetSubMatrix(this, a, b, 0, -1, false);
+}
+
+GetSubMatrix BaseMatrix::Column(int first_col) const
+{
+   REPORT
+   Tracer tr("SubMatrix(column)");
+   int c = first_col - 1;
+   if (c<0) Throw(SubMatrixDimensionException());
+   return GetSubMatrix(this, 0, -1, c, 1, false);
+}
+
+GetSubMatrix BaseMatrix::Columns(int first_col, int last_col) const
+{
+   REPORT
+   Tracer tr("SubMatrix(columns)");
+   int c = first_col - 1; int d = last_col - first_col + 1;
+   if (c<0 || d<0) Throw(SubMatrixDimensionException());
+                             // allow zero rows or columns
+   return GetSubMatrix(this, 0, -1, c, d, false);
+}
+
+void GetSubMatrix::SetUpLHS()
+{
+   REPORT
+   Tracer tr("SubMatrix(LHS)");
+   const BaseMatrix* bm1 = bm;
+   GeneralMatrix* gm1 = ((BaseMatrix*&)bm)->Evaluate();
+   if ((BaseMatrix*)gm1!=bm1)
+      Throw(ProgramException("Invalid LHS"));
+   if (row_number < 0) row_number = gm1->Nrows();
+   if (col_number < 0) col_number = gm1->Ncols();
+   if (row_skip+row_number > gm1->Nrows()
+      || col_skip+col_number > gm1->Ncols())
+         Throw(SubMatrixDimensionException());
+}
+
+void GetSubMatrix::operator<<(const BaseMatrix& bmx)
+{
+   REPORT
+   Tracer tr("SubMatrix(<<)"); GeneralMatrix* gmx = 0;
+   Try
+   {
+      SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate();
+      if (row_number != gmx->Nrows() || col_number != gmx->Ncols())
+         Throw(IncompatibleDimensionsException());
+      MatrixRow mrx(gmx, LoadOnEntry);
+      MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                     // do need LoadOnEntry
+      MatrixRowCol sub; int i = row_number;
+      while (i--)
+      {
+         mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+         sub.Copy(mrx); mr.Next(); mrx.Next();
+      }
+      gmx->tDelete();
+   }
+
+   CatchAll
+   {
+      if (gmx) gmx->tDelete();
+      ReThrow;
+   }
+}
+
+void GetSubMatrix::operator=(const BaseMatrix& bmx)
+{
+   REPORT
+   Tracer tr("SubMatrix(=)"); GeneralMatrix* gmx = 0;
+   // MatrixConversionCheck mcc;         // Check for loss of info
+   Try
+   {
+      SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate();
+      if (row_number != gmx->Nrows() || col_number != gmx->Ncols())
+         Throw(IncompatibleDimensionsException());
+      LoadAndStoreFlag lasf =
+         (  row_skip == col_skip
+            && gm->Type().IsSymmetric()
+            && gmx->Type().IsSymmetric() )
+        ? LoadOnEntry+DirectPart
+        : LoadOnEntry;
+      MatrixRow mrx(gmx, lasf);
+      MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                     // do need LoadOnEntry
+      MatrixRowCol sub; int i = row_number;
+      while (i--)
+      {
+         mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+         sub.CopyCheck(mrx); mr.Next(); mrx.Next();
+      }
+      gmx->tDelete();
+   }
+
+   CatchAll
+   {
+      if (gmx) gmx->tDelete();
+      ReThrow;
+   }
+}
+
+void GetSubMatrix::operator<<(const Real* r)
+{
+   REPORT
+   Tracer tr("SubMatrix(<<Real*)");
+   SetUpLHS();
+   if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
+      Throw(SubMatrixDimensionException());
+   MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                  // do need LoadOnEntry
+   MatrixRowCol sub; int i = row_number;
+   while (i--)
+   {
+      mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+      sub.Copy(r); mr.Next();
+   }
+}
+
+void GetSubMatrix::operator<<(const int* r)
+{
+   REPORT
+   Tracer tr("SubMatrix(<<int*)");
+   SetUpLHS();
+   if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
+      Throw(SubMatrixDimensionException());
+   MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                  // do need LoadOnEntry
+   MatrixRowCol sub; int i = row_number;
+   while (i--)
+   {
+      mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+      sub.Copy(r); mr.Next();
+   }
+}
+
+void GetSubMatrix::operator=(Real r)
+{
+   REPORT
+   Tracer tr("SubMatrix(=Real)");
+   SetUpLHS();
+   MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                  // do need LoadOnEntry
+   MatrixRowCol sub; int i = row_number;
+   while (i--)
+   {
+      mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+      sub.Copy(r); mr.Next();
+   }
+}
+
+void GetSubMatrix::Inject(const GeneralMatrix& gmx)
+{
+   REPORT
+   Tracer tr("SubMatrix(inject)");
+   SetUpLHS();
+   if (row_number != gmx.Nrows() || col_number != gmx.Ncols())
+      Throw(IncompatibleDimensionsException());
+   MatrixRow mrx((GeneralMatrix*)(&gmx), LoadOnEntry);
+   MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                  // do need LoadOnEntry
+   MatrixRowCol sub; int i = row_number;
+   while (i--)
+   {
+      mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+      sub.Inject(mrx); mr.Next(); mrx.Next();
+   }
+}
+
+void GetSubMatrix::operator+=(const BaseMatrix& bmx)
+{
+   REPORT
+   Tracer tr("SubMatrix(+=)"); GeneralMatrix* gmx = 0;
+   // MatrixConversionCheck mcc;         // Check for loss of info
+   Try
+   {
+      SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate();
+      if (row_number != gmx->Nrows() || col_number != gmx->Ncols())
+         Throw(IncompatibleDimensionsException());
+      MatrixRow mrx(gmx, LoadOnEntry);
+      MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                     // do need LoadOnEntry
+      MatrixRowCol sub; int i = row_number;
+      while (i--)
+      {
+         mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+         sub.Check(mrx);                            // check for loss of info
+         sub.Add(mrx); mr.Next(); mrx.Next();
+      }
+      gmx->tDelete();
+   }
+
+   CatchAll
+   {
+      if (gmx) gmx->tDelete();
+      ReThrow;
+   }
+}
+
+void GetSubMatrix::operator-=(const BaseMatrix& bmx)
+{
+   REPORT
+   Tracer tr("SubMatrix(-=)"); GeneralMatrix* gmx = 0;
+   // MatrixConversionCheck mcc;         // Check for loss of info
+   Try
+   {
+      SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate();
+      if (row_number != gmx->Nrows() || col_number != gmx->Ncols())
+         Throw(IncompatibleDimensionsException());
+      MatrixRow mrx(gmx, LoadOnEntry);
+      MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                     // do need LoadOnEntry
+      MatrixRowCol sub; int i = row_number;
+      while (i--)
+      {
+         mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+         sub.Check(mrx);                            // check for loss of info
+         sub.Sub(mrx); mr.Next(); mrx.Next();
+      }
+      gmx->tDelete();
+   }
+
+   CatchAll
+   {
+      if (gmx) gmx->tDelete();
+      ReThrow;
+   }
+}
+
+void GetSubMatrix::operator+=(Real r)
+{
+   REPORT
+   Tracer tr("SubMatrix(+= or -= Real)");
+   // MatrixConversionCheck mcc;         // Check for loss of info
+   Try
+   {
+      SetUpLHS();
+      MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                     // do need LoadOnEntry
+      MatrixRowCol sub; int i = row_number;
+      while (i--)
+      {
+         mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+         sub.Check();                               // check for loss of info
+         sub.Add(r); mr.Next();
+      }
+   }
+
+   CatchAll
+   {
+      ReThrow;
+   }
+}
+
+void GetSubMatrix::operator*=(Real r)
+{
+   REPORT
+   Tracer tr("SubMatrix(*= or /= Real)");
+   // MatrixConversionCheck mcc;         // Check for loss of info
+   Try
+   {
+      SetUpLHS();
+      MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
+                                     // do need LoadOnEntry
+      MatrixRowCol sub; int i = row_number;
+      while (i--)
+      {
+         mr.SubRowCol(sub, col_skip, col_number);   // put values in sub
+         sub.Multiply(r); mr.Next();
+      }
+   }
+
+   CatchAll
+   {
+      ReThrow;
+   }
+}
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/svd.cpp b/Utilities/OSSIM/ossim_core/matrix/svd.cpp
new file mode 100644
index 0000000000..fd499fa183
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/svd.cpp
@@ -0,0 +1,204 @@
+//$$svd.cpp                           singular value decomposition
+
+// Copyright (C) 1991,2,3,4,5: R B Davies
+// Updated 17 July, 1995
+
+#define WANT_MATH
+
+#include "include.h"
+#include "newmatap.h"
+#include "newmatrm.h"
+#include "precisio.h"
+
+#ifdef use_namespace
+namespace NEWMAT {
+#endif
+
+#ifdef DO_REPORT
+#define REPORT { static ExeCounter ExeCount(__LINE__,15); ++ExeCount; }
+#else
+#define REPORT {}
+#endif
+
+
+
+
+void SVD(const Matrix& A, DiagonalMatrix& Q, Matrix& U, Matrix& V,
+   bool withU, bool withV)
+// from Wilkinson and Reinsch: "Handbook of Automatic Computation"
+{
+   REPORT
+   Tracer trace("SVD");
+   Real eps = FloatingPointPrecision::Epsilon();
+   Real tol = FloatingPointPrecision::Minimum()/eps;
+
+   int m = A.Nrows(); int n = A.Ncols();
+   if (m<n)
+      Throw(ProgramException("Want no. Rows >= no. Cols", A));
+   if (withV && &U == &V)
+      Throw(ProgramException("Need different matrices for U and V", U, V));
+   U = A; Real g = 0.0; Real f,h; Real x = 0.0; int i;
+   RowVector E(n); RectMatrixRow EI(E,0); Q.ReSize(n);
+   RectMatrixCol UCI(U,0); RectMatrixRow URI(U,0,1,n-1);
+
+   if (n) for (i=0;;)
+   {
+      EI.First() = g; Real ei = g; EI.Right(); Real s = UCI.SumSquare();
+      if (s<tol) { REPORT Q.element(i) = 0.0; }
+      else
+      {
+         REPORT
+         f = UCI.First(); g = -sign(sqrt(s), f); h = f*g-s; UCI.First() = f-g;
+         Q.element(i) = g; RectMatrixCol UCJ = UCI; int j=n-i;
+         while (--j) { UCJ.Right(); UCJ.AddScaled(UCI, (UCI*UCJ)/h); }
+      }
+
+      s = URI.SumSquare();
+      if (s<tol) { REPORT g = 0.0; }
+      else
+      {
+         REPORT
+         f = URI.First(); g = -sign(sqrt(s), f); URI.First() = f-g;
+         EI.Divide(URI,f*g-s); RectMatrixRow URJ = URI; int j=m-i;
+         while (--j) { URJ.Down(); URJ.AddScaled(EI, URI*URJ); }
+      }
+
+      Real y = fabs(Q.element(i)) + fabs(ei); if (x<y) { REPORT x = y; }
+      if (++i == n) { REPORT break; }
+      UCI.DownDiag(); URI.DownDiag();
+   }
+
+   if (withV)
+   {
+      REPORT
+      V.ReSize(n,n); V = 0.0; RectMatrixCol VCI(V,n-1,n-1,1);
+      if (n) { VCI.First() = 1.0; g=E.element(n-1); if (n!=1) URI.UpDiag(); }
+      for (i=n-2; i>=0; i--)
+      {
+         VCI.Left();
+         if (g!=0.0)
+         {
+            VCI.Divide(URI, URI.First()*g); int j = n-i;
+            RectMatrixCol VCJ = VCI;
+            while (--j) { VCJ.Right(); VCJ.AddScaled( VCI, (URI*VCJ) ); }
+         }
+         VCI.Zero(); VCI.Up(); VCI.First() = 1.0; g=E.element(i);
+         if (i==0) break;
+         URI.UpDiag();
+      }
+   }
+
+   if (withU)
+   {
+      REPORT
+      for (i=n-1; i>=0; i--)
+      {
+         g = Q.element(i); URI.Reset(U,i,i+1,n-i-1); URI.Zero();
+         if (g!=0.0)
+         {
+            h=UCI.First()*g; int j=n-i; RectMatrixCol UCJ = UCI;
+            while (--j)
+            {
+               UCJ.Right(); UCI.Down(); UCJ.Down(); Real s = UCI*UCJ;
+               UCI.Up(); UCJ.Up(); UCJ.AddScaled(UCI,s/h);
+            }
+            UCI.Divide(g);
+         }
+         else UCI.Zero();
+         UCI.First() += 1.0;
+         if (i==0) break;
+         UCI.UpDiag();
+      }
+   }
+
+   eps *= x;
+   for (int k=n-1; k>=0; k--)
+   {
+      Real z = -FloatingPointPrecision::Maximum(); // to keep Gnu happy
+      Real y; int limit = 50; int l = 0;
+      while (limit--)
+      {
+         Real c, s; int i; int l1=k; bool tfc=false;
+         for (l=k; l>=0; l--)
+         {
+//          if (fabs(E.element(l))<=eps) goto test_f_convergence;
+            if (fabs(E.element(l))<=eps) { REPORT tfc=true; break; }
+            if (fabs(Q.element(l-1))<=eps) { REPORT l1=l; break; }
+            REPORT
+         }
+         if (!tfc)
+         {
+            REPORT
+            l=l1; l1=l-1; s = -1.0; c = 0.0;
+            for (i=l; i<=k; i++)
+            {
+               f = - s * E.element(i); E.element(i) *= c;
+//             if (fabs(f)<=eps) goto test_f_convergence;
+               if (fabs(f)<=eps) { REPORT break; }
+               g = Q.element(i); h = pythag(g,f,c,s); Q.element(i) = h;
+               if (withU)
+               {
+                  REPORT
+                  RectMatrixCol UCI(U,i); RectMatrixCol UCJ(U,l1);
+                  ComplexScale(UCJ, UCI, c, s);
+               }
+            }
+         }
+//       test_f_convergence: z = Q.element(k); if (l==k) goto convergence;
+         z = Q.element(k);  if (l==k) { REPORT break; }
+
+         x = Q.element(l); y = Q.element(k-1);
+         g = E.element(k-1); h = E.element(k);
+         f = ((y-z)*(y+z) + (g-h)*(g+h)) / (2*h*y);
+         if (f>1)         { REPORT g = f * sqrt(1 + square(1/f)); }
+         else if (f<-1)   { REPORT g = -f * sqrt(1 + square(1/f)); }
+         else             { REPORT g = sqrt(f*f + 1); }
+            { REPORT f = ((x-z)*(x+z) + h*(y / ((f<0.0) ? f-g : f+g)-h)) / x; }
+
+         c = 1.0; s = 1.0;
+         for (i=l+1; i<=k; i++)
+         {
+            g = E.element(i); y = Q.element(i); h = s*g; g *= c;
+            z = pythag(f,h,c,s); E.element(i-1) = z;
+            f = x*c + g*s; g = -x*s + g*c; h = y*s; y *= c;
+            if (withV)
+            {
+               REPORT
+               RectMatrixCol VCI(V,i); RectMatrixCol VCJ(V,i-1);
+               ComplexScale(VCI, VCJ, c, s);
+            }
+            z = pythag(f,h,c,s); Q.element(i-1) = z;
+            f = c*g + s*y; x = -s*g + c*y;
+            if (withU)
+            {
+               REPORT
+               RectMatrixCol UCI(U,i); RectMatrixCol UCJ(U,i-1);
+               ComplexScale(UCI, UCJ, c, s);
+            }
+         }
+         E.element(l) = 0.0; E.element(k) = f; Q.element(k) = x;
+      }
+      if (l!=k) { Throw(ConvergenceException(A)); }
+// convergence:
+      if (z < 0.0)
+      {
+         REPORT
+         Q.element(k) = -z;
+         if (withV) { RectMatrixCol VCI(V,k); VCI.Negate(); }
+      }
+   }
+   if (withU & withV) SortSV(Q, U, V);
+   else if (withU) SortSV(Q, U);
+   else if (withV) SortSV(Q, V);
+   else SortDescending(Q);
+}
+
+void SVD(const Matrix& A, DiagonalMatrix& D)
+{ REPORT Matrix U; SVD(A, D, U, U, false, false); }
+
+
+
+#ifdef use_namespace
+}
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/test_exc.txt b/Utilities/OSSIM/ossim_core/matrix/test_exc.txt
new file mode 100644
index 0000000000..f22356b04d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/test_exc.txt
@@ -0,0 +1,189 @@
+
+This tests the exception system, so you will get
+a long list of error messages
+
+
+Print a real number (may help lost memory test): 3.14159
+-----------------------------------------
+
+Incompatible dimensions
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: incompatible dimensions
+
+MatrixType = Rect   # Rows = 2; # Cols = 3
+MatrixType = Rect   # Rows = 4; # Cols = 5
+Trace: AddedMatrix::Evaluate; Block A; Test.
+
+-----------------------------------------
+
+Bad index
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: index error: requested indices = 3, 3
+
+MatrixType = Rect   # Rows = 2; # Cols = 3
+Trace: Block B; Test.
+
+-----------------------------------------
+
+Illegal conversion
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: Illegal Conversion
+MatrixTypes = Rect ; UT   
+
+Trace: Block C; Test.
+
+-----------------------------------------
+
+Invert non-square matrix - 1
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: matrix is not square
+
+MatrixType = Rect   # Rows = 2; # Cols = 3
+Trace: CroutMatrix; Block D; Test.
+
+-----------------------------------------
+
+Invert non-square matrix - 2
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: matrix is not square
+
+MatrixType = Rect   # Rows = 2; # Cols = 3
+Trace: GeneralSolvI; InvertedMatrix::Evaluate; Block E; Test.
+
+-----------------------------------------
+
+Non 1x1 matrix to scalar
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: Cannot convert to scalar
+
+MatrixType = Rect   # Rows = 2; # Cols = 3
+Trace: AsScalar; Block F; Test.
+
+-----------------------------------------
+
+Matrix to vector
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: cannot convert matrix to vector
+
+MatrixType = Rect   # Rows = 2; # Cols = 3
+Trace: ColumnVector; Block G; Test.
+
+-----------------------------------------
+
+Invert singular matrix
+
+
+An exception has been thrown
+Runtime error:- detected by Newmat: matrix is singular
+
+MatrixType = Crout  # Rows = 2; # Cols = 2
+Trace: Crout(lubksb); GeneralSolvI; InvertedMatrix::Evaluate; Block H; Test.
+
+-----------------------------------------
+
+SubMatrix error
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: incompatible submatrix dimension
+
+Trace: SubMatrix(evaluate); Block I; Test.
+
+-----------------------------------------
+
+SubMatrix error
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: incompatible submatrix dimension
+
+Trace: SubMatrix(row); Block J; Test.
+
+-----------------------------------------
+
+Cholesky error
+
+
+An exception has been thrown
+Runtime error:- detected by Newmat: matrix not positive definite
+
+MatrixType = Sym    # Rows = 50; # Cols = 50
+Trace: Cholesky; Block K; Test.
+
+-----------------------------------------
+
+Inequality error
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: inequalities not defined for matrices
+
+Trace: Block L; Test.
+
+-----------------------------------------
+
+Maximum of empty matrix
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: Maximum or minimum of null matrix
+
+Trace: Block M; Test.
+
+-----------------------------------------
+
+Incorrectly ReSizing band matrix
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: UpperBandMatrix with non-zero lower band
+
+Trace: UpperBandMatrix::ReSize; Block N; Test.
+
+-----------------------------------------
+
+Incorrectly ReSizing symmetric band matrix
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: Upper and lower band-widths not equal
+
+Trace: SymmetricBandMatrix::ReSize(GM); Block M; Test.
+
+-----------------------------------------
+
+ReSize CroutMatrix
+
+
+An exception has been thrown
+Logic error:- detected by Newmat: ReSize not defined for this type of matrix
+
+Trace: GeneralMatrix::ReSize(GM); Block O; Test.
+
+-----------------------------------------
+
+
+End test
+
+(The following memory checks are probably not valid with all
+compilers - see documentation)
+
+Checking for lost memory: 8141636 8141636  - ok
+
+
+Checking for lost memory: 8141636 8141636  - ok
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/watco_nt.mak b/Utilities/OSSIM/ossim_core/matrix/watco_nt.mak
new file mode 100644
index 0000000000..7939bd8d06
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/watco_nt.mak
@@ -0,0 +1,205 @@
+everything:   tmt.exe example.exe nl_ex.exe sl_ex.exe garch.exe test_exc.exe
+
+.cpp.obj:
+	      wpp386/bt=nt  $*.cpp
+
+OBJ_LIB = bandmat.obj cholesky.obj evalue.obj fft.obj hholder.obj     &
+  jacobi.obj myexcept.obj newmat1.obj newmat2.obj newmat3.obj         &
+  newmat4.obj newmat5.obj newmat6.obj newmat7.obj newmat8.obj         &
+  newmat9.obj newmatex.obj newmatnl.obj newmatrm.obj solution.obj     &
+  sort.obj submat.obj svd.obj newfft.obj
+
+OBJ_T = tmt.obj tmt1.obj tmt2.obj tmt3.obj tmt4.obj tmt5.obj tmt6.obj      &
+  tmt7.obj tmt8.obj tmt9.obj tmta.obj tmtb.obj tmtc.obj tmtd.obj tmte.obj  &
+  tmtf.obj tmtg.obj tmth.obj tmti.obj tmtj.obj tmtk.obj tmtl.obj
+
+tmt.exe:    	$(OBJ_T) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file tmt.obj,tmt1.obj,tmt2.obj,tmt3.obj     >> link.lnk
+	        echo file tmt4.obj,tmt5.obj,tmt6.obj,tmt7.obj    >> link.lnk
+	        echo file tmt8.obj,tmt9.obj,tmta.obj,tmti.obj    >> link.lnk
+	        echo file tmtb.obj,tmtc.obj,tmtd.obj,tmte.obj    >> link.lnk
+	        echo file tmtf.obj,tmtg.obj,tmth.obj,tmtj.obj    >> link.lnk
+	        echo file tmtk.obj,tmtl.obj                      >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,newfft.obj   >> link.lnk
+	        echo name tmt.exe                                >> link.lnk
+		echo SYSTEM nt                                   >> link.lnk
+	        wlink @link.lnk
+
+OBJ_E = example.obj
+
+example.exe:    $(OBJ_E) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,example.obj  >> link.lnk
+	        echo file newmat9.obj,newfft.obj                 >> link.lnk
+	        echo name example.exe                            >> link.lnk
+		echo SYSTEM nt                                   >> link.lnk
+	        wlink @link.lnk
+
+OBJ_N = nl_ex.obj
+
+nl_ex.exe:    	$(OBJ_N) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file nl_ex.obj,newmatnl.obj,newmat9.obj     >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,newfft.obj   >> link.lnk
+	        echo name nl_ex.exe                              >> link.lnk
+		echo SYSTEM nt                                   >> link.lnk
+	        wlink @link.lnk
+
+OBJ_S = sl_ex.obj
+
+sl_ex.exe:    	$(OBJ_S) $(OBJ_LIB)
+	        echo file sl_ex.obj,myexcept.obj,solution.obj     > link.lnk
+	        echo name sl_ex.exe                              >> link.lnk
+		echo SYSTEM nt                                   >> link.lnk
+	        wlink @link.lnk
+
+OBJ_G = garch.obj
+
+garch.exe:      $(OBJ_G) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file garch.obj,newmatnl.obj,newmat9.obj     >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,newfft.obj   >> link.lnk
+	        echo name garch.exe                              >> link.lnk
+		echo SYSTEM nt                                   >> link.lnk
+	        wlink @link.lnk
+
+OBJ_X = test_exc.obj
+
+test_exc.exe:   $(OBJ_X) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file test_exc.obj,newmatnl.obj,newmat9.obj  >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,newfft.obj   >> link.lnk
+	        echo name test_exc.exe                           >> link.lnk
+		echo SYSTEM nt                                   >> link.lnk
+	        wlink @link.lnk
+
+newmatxx = include.h newmat.h boolean.h myexcept.h
+
+myexcept.obj:   include.h boolean.h myexcept.h myexcept.cpp
+
+newmatex.obj:   $(newmatxx) newmatex.cpp
+
+newmatnl.obj:   $(newmatxx) newmatnl.h newmatap.h
+
+example.obj:    $(newmatxx) newmatap.h example.cpp
+
+cholesky.obj:   $(newmatxx) cholesky.cpp
+
+evalue.obj:     $(newmatxx) newmatrm.h precisio.h evalue.cpp
+
+fft.obj:        $(newmatxx) newmatap.h fft.cpp
+
+newfft.obj:     $(newmatxx) newmatap.h newfft.cpp
+
+hholder.obj:    $(newmatxx) newmatap.h hholder.cpp
+
+jacobi.obj:     $(newmatxx) precisio.h newmatrm.h jacobi.cpp
+
+bandmat.obj:    $(newmatxx) newmatrc.h controlw.h bandmat.cpp
+
+newmat1.obj:    $(newmatxx) newmat1.cpp
+
+newmat2.obj:    $(newmatxx) newmatrc.h controlw.h newmat2.cpp
+
+newmat3.obj:    $(newmatxx) newmatrc.h controlw.h newmat3.cpp
+
+newmat4.obj:    $(newmatxx) newmatrc.h controlw.h newmat4.cpp
+
+newmat5.obj:    $(newmatxx) newmatrc.h controlw.h newmat5.cpp
+
+newmat6.obj:    $(newmatxx) newmatrc.h controlw.h newmat6.cpp
+
+newmat7.obj:    $(newmatxx) newmatrc.h controlw.h newmat7.cpp
+
+newmat8.obj:    $(newmatxx) newmatap.h newmat8.cpp
+
+newmat9.obj:    $(newmatxx) newmatrc.h controlw.h newmatio.h newmat9.cpp
+
+newmatrm.obj:   $(newmatxx) newmatrm.h newmatrm.cpp
+
+sort.obj:       $(newmatxx) newmatap.h sort.cpp
+
+submat.obj:     $(newmatxx) newmatrc.h controlw.h submat.cpp
+
+svd.obj:        $(newmatxx) newmatrm.h precisio.h svd.cpp
+
+tmt.obj:        $(newmatxx) newmatap.h tmt.cpp 
+
+tmt1.obj:       $(newmatxx) newmatap.h tmt1.cpp 
+
+tmt2.obj:       $(newmatxx) newmatap.h tmt2.cpp 
+
+tmt3.obj:       $(newmatxx) newmatap.h tmt3.cpp 
+
+tmt4.obj:       $(newmatxx) newmatap.h tmt4.cpp 
+
+tmt5.obj:       $(newmatxx) newmatap.h tmt5.cpp 
+
+tmt6.obj:       $(newmatxx) newmatap.h tmt6.cpp 
+
+tmt7.obj:       $(newmatxx) newmatap.h tmt7.cpp 
+
+tmt8.obj:       $(newmatxx) newmatap.h tmt8.cpp 
+
+tmt9.obj:       $(newmatxx) newmatap.h tmt9.cpp 
+
+tmta.obj:       $(newmatxx) newmatap.h tmta.cpp 
+
+tmtb.obj:       $(newmatxx) newmatap.h tmtb.cpp 
+
+tmtc.obj:       $(newmatxx) newmatap.h tmtc.cpp 
+
+tmtd.obj:       $(newmatxx) newmatap.h tmtd.cpp 
+
+tmte.obj:       $(newmatxx) newmatap.h tmte.cpp 
+
+tmtf.obj:       $(newmatxx) newmatap.h tmtf.cpp 
+
+tmtg.obj:       $(newmatxx) newmatap.h tmtg.cpp 
+
+tmth.obj:       $(newmatxx) newmatap.h tmth.cpp
+
+tmti.obj:       $(newmatxx) newmatap.h tmti.cpp
+
+tmtj.obj:       $(newmatxx) newmatap.h tmtj.cpp
+
+tmtk.obj:       $(newmatxx) newmatap.h tmtk.cpp
+
+tmtl.obj:       $(newmatxx) newmatap.h tmtl.cpp
+
+nl_ex.obj:      $(newmatxx) newmatap.h newmatnl.h nl_ex.cpp
+
+sl_ex.obj:      include.h boolean.h myexcept.h sl_ex.cpp
+
+solution.obj:   include.h boolean.h myexcept.h solution.cpp
+
+garch.obj:      $(newmatxx) newmatap.h newmatnl.h garch.cpp
+
+test_exc.obj:   $(newmatxx) test_exc.cpp
+
diff --git a/Utilities/OSSIM/ossim_core/matrix/watcom.mak b/Utilities/OSSIM/ossim_core/matrix/watcom.mak
new file mode 100644
index 0000000000..c6fdc4d0bd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/matrix/watcom.mak
@@ -0,0 +1,200 @@
+everything:   tmt.exe example.exe nl_ex.exe sl_ex.exe garch.exe test_exc.exe
+
+
+.cpp.obj:
+	      wpp386  $*.cpp
+
+OBJ_LIB = bandmat.obj cholesky.obj evalue.obj fft.obj hholder.obj     &
+  jacobi.obj myexcept.obj newmat1.obj newmat2.obj newmat3.obj         &
+  newmat4.obj newmat5.obj newmat6.obj newmat7.obj newmat8.obj         &
+  newmat9.obj newmatex.obj newmatnl.obj newmatrm.obj solution.obj     &
+  sort.obj submat.obj svd.obj newfft.obj
+
+OBJ_T = tmt.obj tmt1.obj tmt2.obj tmt3.obj tmt4.obj tmt5.obj tmt6.obj      &
+  tmt7.obj tmt8.obj tmt9.obj tmta.obj tmtb.obj tmtc.obj tmtd.obj tmte.obj  &
+  tmtf.obj tmtg.obj tmth.obj tmti.obj tmtj.obj tmtk.obj tmtl.obj
+
+tmt.exe:    	$(OBJ_T) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file tmt.obj,tmt1.obj,tmt2.obj,tmt3.obj     >> link.lnk
+	        echo file tmt4.obj,tmt5.obj,tmt6.obj,tmt7.obj    >> link.lnk
+	        echo file tmt8.obj,tmt9.obj,tmta.obj,tmti.obj    >> link.lnk
+	        echo file tmtb.obj,tmtc.obj,tmtd.obj,tmte.obj    >> link.lnk
+	        echo file tmtf.obj,tmtg.obj,tmth.obj,tmtj.obj    >> link.lnk
+	        echo file tmtk.obj,tmtl.obj                      >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,newfft.obj   >> link.lnk
+	        echo name tmt.exe                                >> link.lnk
+	        echo option stack=8192                           >> link.lnk
+	        wlink @link.lnk
+
+OBJ_E = example.obj
+
+example.exe:    $(OBJ_E) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,example.obj  >> link.lnk
+	        echo file newmat9.obj,newfft.obj                 >> link.lnk
+	        echo name example.exe                            >> link.lnk
+	        wlink @link.lnk
+
+OBJ_N = nl_ex.obj
+
+nl_ex.exe:    	$(OBJ_N) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file nl_ex.obj,newmatnl.obj,newmat9.obj     >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,newfft.obj   >> link.lnk
+	        echo name nl_ex.exe                              >> link.lnk
+	        wlink @link.lnk
+
+OBJ_S = sl_ex.obj
+
+sl_ex.exe:    	$(OBJ_S) $(OBJ_LIB)
+	        echo file sl_ex.obj,myexcept.obj,solution.obj     > link.lnk
+	        echo name sl_ex.exe                              >> link.lnk
+	        wlink @link.lnk
+
+OBJ_G = garch.obj
+
+garch.exe:      $(OBJ_G) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file garch.obj,newmatnl.obj,newmat9.obj     >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,newfft.obj   >> link.lnk
+	        echo name garch.exe                              >> link.lnk
+	        wlink @link.lnk
+
+OBJ_X = test_exc.obj
+
+test_exc.exe:   $(OBJ_X) $(OBJ_LIB)
+	        echo file newmat1.obj,newmat2.obj,newmat3.obj     > link.lnk
+	        echo file newmat4.obj,svd.obj,newmat5.obj        >> link.lnk
+	        echo file newmat6.obj,newmat7.obj,newmat8.obj    >> link.lnk
+	        echo file test_exc.obj,newmatnl.obj,newmat9.obj  >> link.lnk
+	        echo file cholesky.obj,hholder.obj,sort.obj      >> link.lnk
+	        echo file submat.obj,jacobi.obj,newmatrm.obj     >> link.lnk
+	        echo file fft.obj,evalue.obj,bandmat.obj         >> link.lnk
+	        echo file newmatex.obj,myexcept.obj,newfft.obj   >> link.lnk
+	        echo name test_exc.exe                           >> link.lnk
+	        wlink @link.lnk
+
+newmatxx = include.h newmat.h boolean.h myexcept.h
+
+myexcept.obj:   include.h boolean.h myexcept.h myexcept.cpp
+
+newmatex.obj:   $(newmatxx) newmatex.cpp
+
+newmatnl.obj:   $(newmatxx) newmatnl.h newmatap.h
+
+example.obj:    $(newmatxx) newmatap.h example.cpp
+
+cholesky.obj:   $(newmatxx) cholesky.cpp
+
+evalue.obj:     $(newmatxx) newmatrm.h precisio.h evalue.cpp
+
+fft.obj:        $(newmatxx) newmatap.h fft.cpp
+
+newfft.obj:     $(newmatxx) newmatap.h newfft.cpp
+
+hholder.obj:    $(newmatxx) newmatap.h hholder.cpp
+
+jacobi.obj:     $(newmatxx) precisio.h newmatrm.h jacobi.cpp
+
+bandmat.obj:    $(newmatxx) newmatrc.h controlw.h bandmat.cpp
+
+newmat1.obj:    $(newmatxx) newmat1.cpp
+
+newmat2.obj:    $(newmatxx) newmatrc.h controlw.h newmat2.cpp
+
+newmat3.obj:    $(newmatxx) newmatrc.h controlw.h newmat3.cpp
+
+newmat4.obj:    $(newmatxx) newmatrc.h controlw.h newmat4.cpp
+
+newmat5.obj:    $(newmatxx) newmatrc.h controlw.h newmat5.cpp
+
+newmat6.obj:    $(newmatxx) newmatrc.h controlw.h newmat6.cpp
+
+newmat7.obj:    $(newmatxx) newmatrc.h controlw.h newmat7.cpp
+
+newmat8.obj:    $(newmatxx) newmatap.h newmat8.cpp
+
+newmat9.obj:    $(newmatxx) newmatrc.h controlw.h newmatio.h newmat9.cpp
+
+newmatrm.obj:   $(newmatxx) newmatrm.h newmatrm.cpp
+
+sort.obj:       $(newmatxx) newmatap.h sort.cpp
+
+submat.obj:     $(newmatxx) newmatrc.h controlw.h submat.cpp
+
+svd.obj:        $(newmatxx) newmatrm.h precisio.h svd.cpp
+
+tmt.obj:        $(newmatxx) newmatap.h tmt.cpp 
+
+tmt1.obj:       $(newmatxx) newmatap.h tmt1.cpp 
+
+tmt2.obj:       $(newmatxx) newmatap.h tmt2.cpp 
+
+tmt3.obj:       $(newmatxx) newmatap.h tmt3.cpp 
+
+tmt4.obj:       $(newmatxx) newmatap.h tmt4.cpp 
+
+tmt5.obj:       $(newmatxx) newmatap.h tmt5.cpp 
+
+tmt6.obj:       $(newmatxx) newmatap.h tmt6.cpp 
+
+tmt7.obj:       $(newmatxx) newmatap.h tmt7.cpp 
+
+tmt8.obj:       $(newmatxx) newmatap.h tmt8.cpp 
+
+tmt9.obj:       $(newmatxx) newmatap.h tmt9.cpp 
+
+tmta.obj:       $(newmatxx) newmatap.h tmta.cpp 
+
+tmtb.obj:       $(newmatxx) newmatap.h tmtb.cpp 
+
+tmtc.obj:       $(newmatxx) newmatap.h tmtc.cpp 
+
+tmtd.obj:       $(newmatxx) newmatap.h tmtd.cpp 
+
+tmte.obj:       $(newmatxx) newmatap.h tmte.cpp 
+
+tmtf.obj:       $(newmatxx) newmatap.h tmtf.cpp 
+
+tmtg.obj:       $(newmatxx) newmatap.h tmtg.cpp 
+
+tmth.obj:       $(newmatxx) newmatap.h tmth.cpp
+
+tmti.obj:       $(newmatxx) newmatap.h tmti.cpp
+
+tmtj.obj:       $(newmatxx) newmatap.h tmtj.cpp
+
+tmtk.obj:       $(newmatxx) newmatap.h tmtk.cpp
+
+tmtl.obj:       $(newmatxx) newmatap.h tmtl.cpp
+
+nl_ex.obj:      $(newmatxx) newmatap.h newmatnl.h nl_ex.cpp
+
+sl_ex.obj:      include.h boolean.h myexcept.h sl_ex.cpp
+
+solution.obj:   include.h boolean.h myexcept.h solution.cpp
+
+garch.obj:      $(newmatxx) newmatap.h newmatnl.h garch.cpp
+
+test_exc.obj:   $(newmatxx) newmatap.h newmatnl.h test_exc.cpp
diff --git a/Utilities/OSSIM/ossim_core/parallel/.cvsignore b/Utilities/OSSIM/ossim_core/parallel/.cvsignore
new file mode 100644
index 0000000000..c7420bf174
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/.cvsignore
@@ -0,0 +1,4 @@
+*.d
+Makefile
+.shared_obj
+
diff --git a/Utilities/OSSIM/ossim_core/parallel/CMakeLists.txt b/Utilities/OSSIM/ossim_core/parallel/CMakeLists.txt
new file mode 100644
index 0000000000..22cae85d29
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_parallel_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_parallel_HDRS "*.h")
+ADD_LIBRARY(ossim_parallel ${ossim_parallel_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_parallel)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_parallel_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimIgen.cpp b/Utilities/OSSIM/ossim_core/parallel/ossimIgen.cpp
new file mode 100644
index 0000000000..4fd5a108fb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimIgen.cpp
@@ -0,0 +1,805 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: implementation for image generator
+//
+//*************************************************************************
+// $Id: ossimIgen.cpp,v 1.18 2005/12/25 17:33:14 dburken Exp $
+
+#include <iterator>
+#include <sstream>
+#include <exception>
+
+#include <ossimConfig.h> /* To pick up define OSSIM_HAS_MPI. */
+
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+#    include <mpi.h>
+#  endif
+#endif
+
+#include <parallel/ossimIgen.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimStdOutProgress.h>
+
+#include <init/ossimInit.h>
+#include <projections/ossimProjection.h>
+// #include "projections/map_projections/ossimUtmProjection.h>
+
+#include <projections/map_projections/ossimMapProjection.h>
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/factory/ossimMapProjectionFactory.h>
+#include <imaging/ossimImageChain.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/ossimImageChain.h>
+#include <imaging/tile_sources/ossimImageRenderer.h>
+#include <imaging/tile_sources/ossimRectangleCutFilter.h>
+#include <imaging/formats/tiff/ossimTiffWriter.h>
+#include <imaging/factory/ossimImageWriterFactoryRegistry.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <projections/ossimImageViewProjectionTransform.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <imaging/annotation/ossimGeoAnnotationSource.h>
+#include <base/common/ossimPreferences.h>
+#include <base/common/ossimKeywordNames.h>
+#include <parallel/ossimMpi.h>
+#include <base/common/ossimArgumentParser.h>
+#include <base/common/ossimApplicationUsage.h>
+
+// include the Master implementation for the writer
+// sequence.
+//
+#include <parallel/ossimImageMpiMWriterSequenceConnection.h>
+#include <parallel/ossimImageMpiSWriterSequenceConnection.h>
+
+// #include <parallel/ossimImageMpiSequenceConnection.h>
+
+static ossimTrace traceDebug(ossimString("ossimIgen:debug"));
+
+ossimIgen::ossimIgen()
+   :
+    theProductProjection(NULL),
+    theOutputRect(),
+    theBuildThumbnailFlag(false),
+    theThumbnailResolution(0, 0),
+    theNumberOfTilesToBuffer(2),
+    theKwl(),
+    theTilingEnabled(false),
+    theTiling(),
+    theProgressFlag(true)
+{
+   theOutputRect.makeNan();
+}
+
+ossimIgen::~ossimIgen()
+{
+   deleteAttributes();
+   
+}
+
+void ossimIgen::initializeAttributes()
+{
+   theBuildThumbnailFlag  = false;
+   theThumbnailResolution = ossimIpt(0,0);
+   theTilingEnabled = false;
+
+   if(ossimMpi::instance()->getRank() != 0)
+   {
+      ossimPreferences::instance()->addPreferences(theKwl,
+                                                   "preferences.",
+                                                   true);
+   }
+
+   const char* lookup = theKwl.find("igen.output_progress");
+   if (lookup)
+   {
+      ossimString os = lookup;
+      theProgressFlag = os.toBool();
+   }
+   
+   const char* thumbnailStr = theKwl.find("igen.thumbnail");
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "Thumbnail string = " << ossimString(thumbnailStr) << std::endl;
+   }
+   if(thumbnailStr)
+   {
+      theBuildThumbnailFlag= ossimString(thumbnailStr).toBool();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Generate thumbnail attribute is set to "
+            << theBuildThumbnailFlag << std::endl;
+      }
+      if(theBuildThumbnailFlag)
+      {
+         const char* resStr = theKwl.find("igen.thumbnail_res");
+         if(resStr)
+         {
+            theThumbnailResolution = ossimIpt(0,0);
+            std::istringstream in(resStr);
+            in >> theThumbnailResolution.x >> theThumbnailResolution.y;
+
+            if(theThumbnailResolution.x < 1)
+            {
+               theThumbnailResolution.x = 128;
+            }
+            if(theThumbnailResolution.y < 1)
+            {
+               theThumbnailResolution.y = theThumbnailResolution.x;
+            }
+//            theThumbnailResolution = ossimString(resStr).toInt32();
+            
+         }
+         else
+         {
+            theThumbnailResolution = ossimIpt(128, 128);
+         }
+      }
+   }
+   const char* numberOfSlaveTileBuffersStr = theKwl.find("igen.slave_tile_buffers");
+   if(numberOfSlaveTileBuffersStr)
+   {
+      theNumberOfTilesToBuffer = ossimString(numberOfSlaveTileBuffersStr).toLong();
+   }
+
+   const char* tilingKw = theKwl.find("igen.tiling.type");
+   if(tilingKw)
+   {
+      theTilingEnabled = true;
+      if(!theTiling.loadState(theKwl, "igen.tiling."))
+      {
+         theTilingEnabled = false;
+      }
+   }
+}
+
+void ossimIgen::slaveSetup()
+{
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+   int stringSize;
+   MPI_Status status;
+   int numberOfTimes = 0;
+
+   // we first need to receive the size of the keyword list to load
+   MPI_Recv(&stringSize,
+            1,
+            MPI_INT,
+            0,    // source
+            0,    // tag
+            MPI_COMM_WORLD,
+            &status);
+
+   if(status.MPI_ERROR != MPI_SUCCESS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "SLAVE = "
+         << ossimMpi::instance()->getRank()
+         << "Had errors receiving!!!!" << std::endl;
+      return;
+   }
+   
+   char* buf = new char[stringSize+1];
+
+   numberOfTimes = 0;
+
+   // now lets get the keywordlist as a string so we can load it up
+   MPI_Recv(buf,
+            stringSize,
+            MPI_CHAR,
+            0, // source
+            0, // tag
+            MPI_COMM_WORLD,
+            &status);
+   
+   if(status.MPI_ERROR != MPI_SUCCESS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "SLAVE = " << ossimMpi::instance()->getRank()
+         << "Had errors receiving in ossimIgen::slaveCreate(!!!!"
+         << std::endl;
+      return;
+   }
+   buf[stringSize] = '\0';
+
+   if(status.MPI_ERROR != MPI_SUCCESS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "SLAVE = " << ossimMpi::instance()->getRank()
+         << "Had errors receiving!!!!" << std::endl;
+      return;
+   }
+
+   // now lets convert the received keywordlist into an actual
+   // ossimKeywordlist by using the parsStream method.
+   std::ostringstream kwlStream;
+
+   kwlStream << buf << ends;
+   
+   istringstream kwlInStream(kwlStream.str());
+   theKwl.clear();
+   theKwl.parseStream(kwlInStream);
+   initializeAttributes();
+   delete buf;
+   buf = NULL;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "****************** KWL ************************" << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << theKwl << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "**************** END KWL ************************" << std::endl;
+      
+   }
+   loadProduct();
+#  endif
+#endif
+}
+
+void ossimIgen::initialize(const ossimKeywordlist& kwl)
+{
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+   if(ossimMpi::instance()->getNumberOfProcessors() > 0)
+   {
+      if(ossimMpi::instance()->getRank() != 0)
+      {
+         slaveSetup();
+         return;
+      }
+   }
+#  endif
+#endif
+   theKwl = kwl;
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "The igen kewyord list  ==== \n" << theKwl << std::endl;
+   }
+   ossimKeywordlist kwlPrefs = ossimPreferences::instance()->preferencesKWL();
+   
+   kwlPrefs.addPrefixToAll("preferences.");
+   theKwl.add(kwlPrefs);
+
+   initializeAttributes();
+   
+   // now stream it to all slave processors
+   //
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+
+   if(ossimMpi::instance()->getNumberOfProcessors() > 0)
+   {
+      std::ostringstream outputKeywordlist;
+      
+      theKwl.writeToStream(outputKeywordlist);
+      ossimString kwlString = outputKeywordlist.str();
+      ossim_uint32 size = kwlString.size();
+      
+      for(long processor = 1;
+          processor < ossimMpi::instance()->getNumberOfProcessors();
+          ++processor)
+      {
+      // let's send the keywordlist argument.
+      // This is two steps.  We send a message to
+      // indicate the size and then we send the
+      // string.
+      //
+         MPI_Send(&size,
+                  1,
+                  MPI_INT,
+                  processor,
+                  0,
+                  MPI_COMM_WORLD);
+         
+         MPI_Send((void*)kwlString.c_str(),
+                  size,
+                  MPI_CHAR,
+                  processor,
+                  0,
+                  MPI_COMM_WORLD);
+      }
+   }
+#  endif
+#endif
+   loadProduct();
+   
+}
+
+bool ossimIgen::loadProduct()//ossimKeywordlist& kwl,
+                            //bool thumbnail,
+                            //long resolution)
+{
+   const char* MODULE = "ossimIgen::loadProduct";
+
+   if(traceDebug())
+   {
+      CLOG << "entered..." << std::endl;
+   }
+
+   if(traceDebug())
+   {
+      CLOG << " Creating object1..." << std::endl;
+   }
+
+   theContainer.deleteAllChildren();
+
+   theContainer.loadState(theKwl);
+
+   theProductProjection = buildProductProjection(theKwl);
+
+   if(theProductProjection)
+   {
+      vector<ossimImageViewTransform*> transforms;
+      setView(&theContainer, theProductProjection);
+      // if it's a thumbnail then adjust the GSD and
+      // reset the view proj to the chain.
+      if(theBuildThumbnailFlag)
+      {
+         buildThumbnail();
+         delete theProductProjection;
+         
+         theProductProjection = buildProductProjection(theKwl);
+         
+         setView(&theContainer, theProductProjection);
+      }
+      
+   }
+   
+   ossimKeywordlist proj;
+   
+   ossimDrect rect;
+   ossimImageChain* chain = getChain();
+   if(!getOutputRect(theKwl, rect)&&chain)
+   {
+      rect = chain->getBoundingRect();
+   }
+   else
+   {
+      rect.makeNan();
+   }
+   
+   // Stretch the rectangle out to integer boundaries.
+   if(!rect.hasNans())
+   {
+      rect.stretchOut();
+   }
+   theOutputRect = rect;
+   
+   if(theProductProjection)
+   {
+      theProductProjection->saveState(proj, "projection.");
+         
+   }
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "bounding rect = " << theOutputRect << std::endl;
+      CLOG << "leaving..." << std::endl;
+   }
+   
+   return true;
+}
+
+void ossimIgen::outputProduct()
+{
+   ossimImageChain* chain = getChain();
+   if(chain)
+   {
+      chain->initialize();
+   }
+   ossimImageSourceSequencer* sequencer = NULL;
+   
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+   // only allocate the slave connection if
+   // the number of processors is larger than
+   // 1
+   //
+   if(ossimMpi::instance()->getNumberOfProcessors() > 1)
+   {
+      if(ossimMpi::instance()->getRank()!=0)
+      {
+         sequencer = new ossimImageMpiSWriterSequenceConnection(NULL,
+                                                                 theNumberOfTilesToBuffer);
+      }
+      else
+      {
+         sequencer = new ossimImageMpiMWriterSequenceConnection();
+      }
+   }
+   else
+   {
+      sequencer = new ossimImageSourceSequencer();
+   }
+#  else
+
+   // we will just load a serial connection if MPI is not supported.
+   //
+   sequencer = new ossimImageSourceSequencer(NULL);
+   
+#  endif
+#else
+
+   // we will just load a serial connection if MPI is not supported.
+   sequencer = new ossimImageSourceSequencer(NULL);
+   
+#endif
+   
+   std::vector<ossimConnectableObject*> imageWriters = theContainer.findAllObjectsOfType(STATIC_TYPE_INFO(ossimImageFileWriter),
+                                                                                         false);
+   if(imageWriters.size() > 0)
+   {
+      ossimImageFileWriter* writer = PTR_CAST(ossimImageFileWriter, imageWriters[0]);
+
+      
+      writer->changeSequencer(sequencer);
+      writer->connectMyInputTo(chain);
+      writer->initialize();
+   }
+   else
+   {
+      delete sequencer;
+      sequencer = NULL;
+   }
+   
+   std::vector<ossimConnectableObject*> processObjects = theContainer.findAllObjectsOfType(STATIC_TYPE_INFO(ossimProcessInterface),
+                                                                                           false);
+   ossim_uint32 i = 0;
+   ossimImageFileWriter* writer  = 0;
+   for(i = 0; ((i < processObjects.size())&&(!writer)); ++i)
+   {
+      writer = PTR_CAST(ossimImageFileWriter,
+                        processObjects[i]);
+   }
+
+   if(writer)
+   {
+      ossimRefPtr<ossimProjection> proj = buildProductProjection(theKwl);
+      ossimMapProjection *mapProj = PTR_CAST(ossimMapProjection,proj.get());
+      
+      if(theTilingEnabled&&mapProj)
+      {
+         ossimRefPtr<ossimMapProjection> view;
+         ossimIrect clipRect;
+         theTiling.initialize(*mapProj,
+                               chain->getBoundingRect());
+         ossimRectangleCutFilter* cut = new ossimRectangleCutFilter;
+         
+         chain->addFirst(cut);
+         ossim_uint32 idx = 0;
+         ossimFilename tempFile = writer->getFilename();
+
+         if(!tempFile.isDir())
+         {
+            tempFile = tempFile.path();
+         }
+         ossimString tileName;
+         
+         while(theTiling.next(view,
+                              clipRect,
+                              tileName))
+         {
+            ossimStdOutProgress* prog = NULL;
+            if ( (ossimMpi::instance()->getRank() == 0) && theProgressFlag)
+            {
+               // Add a listener to master.
+               prog = new ossimStdOutProgress(0, true);
+               writer->addListener(prog);
+            }
+            
+            setView(chain, view.get());
+            chain->initialize();
+            cut->setRectangle(clipRect);
+            chain->initialize();
+            writer->disconnect();
+            writer->connectMyInputTo(chain);
+            writer->setFilename(tempFile.dirCat(tileName));
+            writer->initialize();
+
+            try
+            {
+               writer->execute();
+            }
+            catch(std::exception& e)
+            {
+               ossimNotify(ossimNotifyLevel_FATAL)
+                  << "ossimIgen::outputProduct ERROR:\n"
+                  << "Caught exception!\n"
+                  << e.what()
+                  << std::endl;
+            }
+            catch(...)
+            {
+               ossimNotify(ossimNotifyLevel_FATAL)
+                  << "ossimIgen::outputProduct ERROR:\n"
+                  << "Unknown exception caught!\n"
+                  << std::endl;
+            }
+
+            ++idx;
+
+            if (prog)
+            {
+               writer->removeListener(prog);
+               delete prog;
+               prog = NULL;
+            }
+            
+         }
+      }
+      else
+      {
+         ossimStdOutProgress* prog = NULL;
+         if ( (ossimMpi::instance()->getRank() == 0) && theProgressFlag)
+         {
+            // Add a listener to master.
+            prog = new ossimStdOutProgress(0, true);
+            writer->addListener(prog);
+         }
+
+         try
+         {
+            writer->execute();
+         }
+         catch(std::exception& e)
+         {
+            ossimNotify(ossimNotifyLevel_FATAL)
+               << "ossimIgen::outputProduct ERROR:\n"
+               << "Caught exception!\n"
+                  << e.what()
+               << std::endl;
+         }
+         catch(...)
+         {
+            ossimNotify(ossimNotifyLevel_FATAL)
+               << "ossimIgen::outputProduct ERROR:\n"
+               << "Unknown exception caught!\n"
+               << std::endl;
+         }
+
+         if (prog)
+         {
+            writer->removeListener(prog);
+            delete prog;
+            prog = NULL;
+         }
+      }
+   }
+
+   if(ossimMpi::instance()->getRank() == 0)
+   {
+      for(ossim_uint32 i = 0; i < processObjects.size(); ++i)
+      {
+         if(!PTR_CAST(ossimImageFileWriter,
+                      processObjects[i]))
+         {
+            ossimProcessInterface* process = PTR_CAST(ossimProcessInterface,
+                                                      processObjects[i]);
+            if(process)
+            {
+               processObjects[i]->connectMyInputTo(chain);
+               process->execute();
+            }
+         }
+      }
+   }
+}
+
+void ossimIgen::deleteAttributes()
+{
+   if(theProductProjection)
+   {
+      delete theProductProjection;
+      theProductProjection = NULL;
+   }
+   theContainer.deleteAllChildren();
+}
+
+ossimProjection* ossimIgen::createImageProjection(const ossimKeywordlist& kwl)
+{
+   // here we need to modify the factory to produce the correct
+   // projector so we can seemlessly use sensors as well.  For
+   // now we hardcode the Map projector
+   ossimProjection* imageProjection = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+   
+   if(!imageProjection)
+   {
+      
+//       cerr << "Unable to create Image projection: "
+//            << ossimString(kwl.find("projection.type"))
+//            << " in ossimIgen::createImageProjection" << endl;
+      // ERROR
+   }
+
+   return imageProjection;   
+}
+
+ossimProjection* ossimIgen::buildProductProjection(const ossimKeywordlist& kwl,
+                                                   const char* prefix)
+{
+   ossimKeywordlist kwlProj;
+
+   ossimString projPrefix = ossimString(prefix) + "projection.";
+   const char* ul_lat = kwl.find(prefix, ossimKeywordNames::UL_LAT_KW);
+   const char* ul_lon = kwl.find(prefix, ossimKeywordNames::UL_LON_KW);
+   const char* lr_lat = kwl.find(prefix, ossimKeywordNames::LR_LAT_KW);
+   const char* lr_lon = kwl.find(prefix, ossimKeywordNames::LR_LON_KW);
+   const char* origin_latitude    = kwl.find(projPrefix.c_str(),
+                                             ossimKeywordNames::ORIGIN_LATITUDE_KW);
+   const char* central_meridian   = kwl.find(projPrefix.c_str(),
+                                             ossimKeywordNames::CENTRAL_MERIDIAN_KW);
+   double      originLat = 0.0;
+   double      originLon = 0.0;
+   
+   ossimProjection* projection = NULL;
+   projection = ossimProjectionFactoryRegistry::instance()->createProjection(kwl, "product.projection.");
+   
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, projection);
+   
+
+   if(mapProj)
+   {
+      ossimKeywordlist projKwl;
+      mapProj->saveState(projKwl);
+
+      // allow one to override
+      if(origin_latitude&&central_meridian)
+      {
+         originLat = ossimString(origin_latitude).toDouble();
+         originLon = ossimString(central_meridian).toDouble();
+      }
+      // default
+      else if(ul_lat&&ul_lon&&lr_lat&&lr_lon)
+      {
+         double ulLat = ossimString(ul_lat).toDouble();
+         double ulLon = ossimString(ul_lon).toDouble();
+         double lrLat = ossimString(lr_lat).toDouble();
+         double lrLon = ossimString(lr_lon).toDouble();
+
+         originLat = (ulLat + lrLat)*.5;
+         originLon = (ulLon + lrLon)*.5;
+               
+         if (origin_latitude)
+         {
+            originLat = ossimString(origin_latitude).toDouble();
+         }
+         if (central_meridian)
+         {
+            originLon = ossimString(central_meridian).toDouble();
+         }
+      }
+
+      if(origin_latitude)
+      {
+         projKwl.add(ossimKeywordNames::ORIGIN_LATITUDE_KW,
+                     originLat,
+                     true);
+      }
+
+      if(central_meridian)
+      {
+         projKwl.add(ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+                     originLon,
+                     true);
+      }
+      delete mapProj;
+      
+      projection = ossimProjectionFactoryRegistry::instance()->createProjection(projKwl);
+
+   }
+   else
+   {
+      
+//       cout << "ERROR: not all product information was supplied. \n"
+//            << "     need:  ul_lat, ul_lon, lr_lat lr_lon (area of coverage)\n"
+//            << "            projection datum and projection type";
+   }
+
+   
+   return projection;
+}
+
+void ossimIgen::setView(ossimConnectableObject* obj,
+                        ossimObject* viewObj)
+{
+   if(!viewObj||!obj)
+   {
+      return;
+   }
+   vector<ossimConnectableObject*> result;
+   obj->findAllInputsOfType(result, STATIC_TYPE_INFO(ossimViewInterface), true, true);
+
+   for(ossim_uint32 i = 0; i < result.size();++i)
+   {
+      ossimViewInterface* viewInterface = PTR_CAST(ossimViewInterface,
+                                                   result[i]);
+      if(viewInterface)
+      {
+         ossimObject* obj = viewObj->dup();
+         viewInterface->setView(obj, true);
+      }
+   }
+}
+
+
+bool ossimIgen::getOutputRect(const ossimKeywordlist& kwl,
+                              ossimDrect& rect)
+{
+   ossimProjection* viewProj = buildProductProjection(kwl);
+   ossimImageChain* chain = getChain();
+   
+   
+   
+   if(chain)
+   {
+      setView(chain, viewProj);
+      chain->initialize();
+      rect = chain->getBoundingRect();
+      
+      return true;
+   }
+   if(viewProj)
+   {
+      delete viewProj;
+   }
+
+   return false;
+}
+
+void ossimIgen::buildThumbnail()
+{
+   double resolution = ossimMax(theThumbnailResolution.x, theThumbnailResolution.y);
+   ossimProjection* viewProj   = buildProductProjection(theKwl);
+   ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, viewProj);
+   
+   
+   ossimDrect rect;
+
+   if(mapProj && getOutputRect(theKwl, rect))
+   {
+      double xScale = rect.width()  / (double)resolution;
+      double yScale = rect.height() / (double)resolution;
+
+      //---
+      // Maintain aspect ratio - adjust based on largest Scale.
+      // 
+      // Note the second argument to applyScale is to
+      // "not recenter the tie point".  This was added to fix a resampler
+      // runaway split problem. (drb 20051225)
+      //---
+      if (xScale > yScale)
+      {
+         mapProj->applyScale(ossimDpt(xScale, xScale), false);
+      }
+      else
+      {
+         mapProj->applyScale(ossimDpt(yScale, yScale), false);
+      }
+      mapProj->saveState(theKwl, "product.projection.");
+   }
+   
+   delete viewProj;
+}
+
+ossimImageChain* ossimIgen::getChain()
+{
+   ossimConnectableObject* obj = theContainer.findFirstObjectOfType(STATIC_TYPE_NAME(ossimImageChain),
+                                                                    false);
+
+   return PTR_CAST(ossimImageChain, obj);
+}
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimIgen.h b/Utilities/OSSIM/ossim_core/parallel/ossimIgen.h
new file mode 100644
index 0000000000..d1023b9355
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimIgen.h
@@ -0,0 +1,94 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: Class declaration for image generator.
+//
+//*************************************************************************
+// $Id: ossimIgen.h,v 1.6 2005/10/11 22:19:58 dburken Exp $
+#ifndef ossimIgen_HEADER
+#define ossimIgen_HEADER
+
+#include <iostream>
+#include <list>
+#include <fstream>
+
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimConnectableContainer.h>
+#include <imaging/ossimTiling.h>
+
+class ossimImageChain;
+class ossimImageFileWriter;
+class ossimProjection;
+class ossimImageViewTransform;
+class ossimImageSource;
+class ossimImageMpiMWriterSequenceConnection;
+class ossimImageMpiSWriterSequenceConnection;
+class ossimObject;
+class ossimArgumentParser;
+
+class OSSIM_DLL ossimIgen
+{
+public:
+   ossimIgen();
+   virtual ~ossimIgen();
+
+   virtual void initialize(const ossimKeywordlist& kwl);
+   virtual void outputProduct();
+   
+protected:
+   ossimConnectableContainer theContainer;
+
+   ossimProjection*  theProductProjection;
+   ossimDrect        theOutputRect;
+   bool              theBuildThumbnailFlag;
+   ossimIpt          theThumbnailResolution;
+   long              theNumberOfTilesToBuffer;
+   ossimKeywordlist  theKwl;
+   bool              theTilingEnabled;
+   ossimTiling       theTiling;
+   bool              theProgressFlag;
+   
+   /**
+    * Initializes attributes of class.
+    *
+    * Keywords searched for by method:
+    * 
+    * igen.output_progress: true (bool)
+    *
+    * igen.thumbnail: true (bool)
+    *
+    * igen.thumbnail_res: 128 128 (x_res, y_res)
+    *
+    * (number of buffers for slave nodes to process before waiting)
+    * igen.slave_tile_buffers: 2
+    *
+    * igen.tiling.type: ?
+    *
+    * igen.tiling: ?
+    */
+   void initializeAttributes();
+   void slaveSetup();
+
+   bool loadProduct();
+   
+   void deleteAttributes();
+   void setView(ossimConnectableObject* obj, ossimObject* viewObj);
+   ossimProjection* createImageProjection(const ossimKeywordlist& kwl);
+   virtual ossimProjection* buildProductProjection(const ossimKeywordlist& kwl,
+                                                   const char* prefix="product.");
+   bool getOutputRect(const ossimKeywordlist& kwl,
+                      ossimDrect& rect);
+   void buildThumbnail();
+   void outputImageGeometry(const char* filename);
+   ossimImageChain* getChain();
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiMWriterSequenceConnection.cpp b/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiMWriterSequenceConnection.cpp
new file mode 100644
index 0000000000..7cc5a56600
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiMWriterSequenceConnection.cpp
@@ -0,0 +1,290 @@
+//*******************************************************************
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// This class is specific to the Master connection and is optimized
+// for the writer sequence and batch processing chain.  For the Slave
+// implementation look for the ossimImageMpiSWriterSequenceConnection.cc and .h
+// files.  The Master connection is currently implemented to allways do
+// a recieve and does no processing itself.  The slave connection does
+// all the actual work and processing.
+//
+//*******************************************************************
+//  $Id: ossimImageMpiMWriterSequenceConnection.cpp,v 1.20 2005/11/07 22:03:24 dburken Exp $
+
+
+#include <ossimConfig.h> /* To pick up OSSIM_HAS_MPI. */
+
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+#    include <mpi.h>
+#  endif
+#endif
+
+#include <parallel/ossimImageMpiMWriterSequenceConnection.h>
+#include <parallel/ossimMpi.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimTrace.h>
+#include <base/misc/ossimEndian.h>
+
+static ossimTrace traceDebug = ossimTrace("ossimImageMpiMWriterSequenceConnection:debug");
+
+RTTI_DEF1(ossimImageMpiMWriterSequenceConnection, "ossimImageMpiMWriterSequenceConnection", ossimImageSourceSequencer)
+
+
+ossimImageMpiMWriterSequenceConnection::ossimImageMpiMWriterSequenceConnection(
+   ossimImageSource* inputSource,
+   ossimObject* owner)
+   :ossimImageSourceSequencer(inputSource, owner),
+    theOutputTile(NULL)
+{
+   theRank = 0;
+   theNumberOfProcessors = 1;
+
+#ifdef OSSIM_HAS_MPI   
+#  if OSSIM_HAS_MPI
+   MPI_Comm_rank(MPI_COMM_WORLD, &theRank);
+   MPI_Comm_size(MPI_COMM_WORLD, &theNumberOfProcessors);
+#  endif
+#endif   
+
+   if(theRank!=0)
+   {
+      theCurrentTileNumber = theRank -1;
+   }
+   else
+   {
+      theCurrentTileNumber = 0;
+   }
+   theNeedToSendRequest = true;
+}
+
+ossimImageMpiMWriterSequenceConnection::ossimImageMpiMWriterSequenceConnection(ossimObject* owner)
+   :ossimImageSourceSequencer(NULL, owner),
+    theOutputTile(NULL)
+{
+   theRank = 0;
+   theNumberOfProcessors = 1;
+   
+#ifdef OSSIM_HAS_MPI     
+#  if OSSIM_HAS_MPI
+   MPI_Comm_rank(MPI_COMM_WORLD, &theRank);
+   MPI_Comm_size(MPI_COMM_WORLD, &theNumberOfProcessors);
+#  endif
+#endif
+   
+   if(theRank!=0)
+   {
+      theCurrentTileNumber = theRank -1;
+   }
+   else
+   {
+      theCurrentTileNumber = 0;
+   }
+   theNeedToSendRequest = true;
+}
+
+ossimImageMpiMWriterSequenceConnection::~ossimImageMpiMWriterSequenceConnection()
+{
+}
+
+void ossimImageMpiMWriterSequenceConnection::initialize()
+{
+  ossimImageSourceSequencer::initialize();
+
+  theCurrentTileNumber = theRank;//-1;
+  theOutputTile = NULL;
+  
+  if(theInputConnection)
+  {
+     theOutputTile = ossimImageDataFactory::instance()->create(this, this);
+     theOutputTile->initialize();
+  }
+}
+
+void ossimImageMpiMWriterSequenceConnection::setToStartOfSequence()
+{
+   ossimImageSourceSequencer::setToStartOfSequence();
+   if(theRank != 0)
+   {
+      // we will subtract one since the masters job is just
+      // writting and not issue getTiles.
+      theCurrentTileNumber = theRank-1;
+
+   }
+   else
+   {
+      // the master will start at 0
+      theCurrentTileNumber = 0;
+   }
+}
+
+/*!
+ * Will allow you to get the next tile in the sequence.
+ */
+ossimRefPtr<ossimImageData> ossimImageMpiMWriterSequenceConnection::getNextTile(ossim_uint32 resLevel)
+{
+#if OSSIM_HAS_MPI
+   ossimEndian endian;
+   MPI_Status status;
+   if(!theOutputTile)
+   {
+      initialize();
+      if (!theOutputTile)
+      {
+         return theOutputTile;
+      }
+   }
+   
+   void* buf = theOutputTile->getBuf();
+
+   ossim_uint32 numberOfTiles = getNumberOfTiles();
+   int errorValue = 0;
+   
+   if(theCurrentTileNumber >= numberOfTiles)
+   {
+      return NULL;
+   }
+   errorValue = MPI_Recv(buf,
+                         theOutputTile->getSizeInBytes(),
+                         MPI_UNSIGNED_CHAR,
+                         theCurrentTileNumber%(theNumberOfProcessors-1)+1,
+                         0,
+                         MPI_COMM_WORLD,
+                         &status);
+   if((endian.getSystemEndianType()!=OSSIM_BIG_ENDIAN)&&
+      (theOutputTile->getScalarType()!=OSSIM_UINT8))
+   {
+      endian.swap(theOutputTile->getScalarType(),
+                  buf,
+                  theOutputTile->getSize());
+   }
+   
+#if 0
+   // Since MPI can run on different platforms
+   // I am not sure if MPI has built in byte
+   // swap.  If so I will name each datatype
+   // so it can handle byte swap.  Does anyone
+   // know if MPI does byte swapping.
+   switch(theOutputTile->getScalarType())
+   {
+      case OSSIM_UINT8:
+      {
+         // we add 1 to the rank so we don't wait on a message
+         // to ourself (rank = 0).
+         errorValue = MPI_Recv(buf,
+                               theOutputTile->getSize(),
+                               MPI_UNSIGNED_CHAR,
+                               theCurrentTileNumber%(theNumberOfProcessors-1)+1,
+                               0,
+                               MPI_COMM_WORLD,
+                               &status);
+         break;
+      }
+      case OSSIM_SINT8:
+      {
+         // we add 1 to the rank so we don't wait on a message
+         // to ourself (rank = 0).
+         errorValue = MPI_Recv(buf,
+                               theOutputTile->getSize(),
+                               MPI_CHAR,
+                               theCurrentTileNumber%(theNumberOfProcessors-1)+1,
+                               0,
+                               MPI_COMM_WORLD,
+                               &status);
+         break;
+      }
+      case OSSIM_UINT16:
+      case OSSIM_USHORT11:
+      {
+         errorValue = MPI_Recv(buf,
+                               theOutputTile->getSize(),
+                               MPI_UNSIGNED_SHORT,
+                               theCurrentTileNumber%(theNumberOfProcessors-1)+1,
+                               0,
+                               MPI_COMM_WORLD,
+                               &status);
+         break;
+      }
+      case OSSIM_SINT16:
+      {
+         errorValue = MPI_Recv(buf,
+                               theOutputTile->getSize(),
+                               MPI_SHORT,
+                               theCurrentTileNumber%(theNumberOfProcessors-1)+1,
+                               0,
+                               MPI_COMM_WORLD,
+                               &status);
+         break;
+      }
+      case OSSIM_SINT32:
+      {
+         errorValue = MPI_Recv(buf,
+                               theOutputTile->getSize(),
+                               MPI_LONG,
+                               theCurrentTileNumber%(theNumberOfProcessors-1)+1,
+                               0,
+                               MPI_COMM_WORLD,
+                               &status);
+         break;
+      }
+      case OSSIM_UINT32:
+      {
+         errorValue = MPI_Recv(buf,
+                               theOutputTile->getSize(),
+                               MPI_UNSIGNED_LONG,
+                               theCurrentTileNumber%(theNumberOfProcessors-1)+1,
+                               0,
+                               MPI_COMM_WORLD,
+                               &status);
+         break;
+      }
+      case OSSIM_FLOAT32:
+      case OSSIM_NORMALIZED_FLOAT:
+      {
+         errorValue = MPI_Recv(buf,
+                               theOutputTile->getSize(),
+                               MPI_FLOAT,
+                               theCurrentTileNumber%(theNumberOfProcessors-1)+1,
+                               0,
+                               MPI_COMM_WORLD,
+                               &status);
+         break;
+      }
+      case OSSIM_FLOAT64:
+      case OSSIM_NORMALIZED_DOUBLE:
+      {
+         errorValue = MPI_Recv(buf,
+                               theOutputTile->getSize(),
+                               MPI_DOUBLE,
+                               theCurrentTileNumber%(theNumberOfProcessors-1)+1,
+                               0,
+                               MPI_COMM_WORLD,
+                               &status);
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+#endif
+   ossimIpt origin;
+   getTileOrigin(theCurrentTileNumber,
+                 origin);
+   theOutputTile->setOrigin(origin);
+   theOutputTile->validate();
+   ++theCurrentTileNumber;
+   return theOutputTile;
+#else
+   return ossimImageSourceSequencer::getNextTile(resLevel);
+#endif
+   
+}
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiMWriterSequenceConnection.h b/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiMWriterSequenceConnection.h
new file mode 100644
index 0000000000..e0b9e3e3cb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiMWriterSequenceConnection.h
@@ -0,0 +1,60 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// This class is specific to the Master connection and is optimized
+// for the writer sequence and batch processing chain.  For the Slave
+// implementation look for the ossimImageMpiSWriterSequenceConnection.cc and .h
+// files.  The Master connection is currently implemented to allways do
+// a recieve and does no processing itself.  The slave connection does
+// all the actual work and processing.
+//
+//*******************************************************************
+//  $Id: ossimImageMpiMWriterSequenceConnection.h,v 1.6 2005/02/11 15:07:35 dburken Exp $
+#ifndef ossimImageMpiMWriterSequenceConnection_HEADER
+#define ossimImageMpiMWriterSequenceConnection_HEADER
+#include <imaging/ossimImageSourceSequencer.h>
+class ossimImageData;
+class ossimImageMpiMWriterSequenceConnection : public ossimImageSourceSequencer
+{
+public:
+   ossimImageMpiMWriterSequenceConnection(ossimObject* owner=NULL);
+   ossimImageMpiMWriterSequenceConnection(ossimImageSource* inputSource,
+                                          ossimObject* owner=NULL);
+  virtual ~ossimImageMpiMWriterSequenceConnection();
+
+   /*!
+    * This is a virtual method that can be overriden
+    * by derived classes (MPI, or PVM or other
+    * parallel connections.  This method is to indicate
+    * whether or not this connection is the master/
+    * controlling connection.
+    */
+   virtual void initialize();
+   virtual void setToStartOfSequence();
+
+   virtual bool isMaster()const
+      {
+         return true;
+      }
+   /*!
+    * Will allow you to get the next tile in the sequence.
+    */
+   virtual ossimRefPtr<ossimImageData> getNextTile(ossim_uint32 resLevel=0);
+protected:
+   int theNumberOfProcessors;
+   int theRank;
+   bool theNeedToSendRequest;
+   ossimRefPtr<ossimImageData> theOutputTile;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiSWriterSequenceConnection.cpp b/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiSWriterSequenceConnection.cpp
new file mode 100644
index 0000000000..5ddf3dacb6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiSWriterSequenceConnection.cpp
@@ -0,0 +1,355 @@
+//----------------------------------------------------------------------------
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// $Id: ossimImageMpiSWriterSequenceConnection.cpp,v 1.26 2005/11/07 22:03:24 dburken Exp $
+//----------------------------------------------------------------------------
+
+#include <ossimConfig.h> /* To pick up OSSIM_HAS_MPI. */
+
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+#    include <mpi.h>
+#  endif
+#endif
+
+#include <parallel/ossimImageMpiSWriterSequenceConnection.h>
+#include <parallel/ossimMpi.h>
+#include <imaging/ossimImageData.h>
+#include <imaging/factory/ossimImageDataFactory.h>
+#include <base/common/ossimTrace.h>
+#include <base/misc/ossimEndian.h>
+#include <base/context/ossimNotifyContext.h>
+
+static ossimTrace traceDebug = ossimTrace("ossimImageMpiSWriterSequenceConnection:debug");
+
+RTTI_DEF1(ossimImageMpiSWriterSequenceConnection, "ossimImageMpiSWriterSequenceConnection", ossimImageSourceSequencer)
+
+ossimImageMpiSWriterSequenceConnection::ossimImageMpiSWriterSequenceConnection(ossimObject* owner,
+                                                                               long numberOfTilesToBuffer)
+   :ossimImageSourceSequencer(NULL,
+                              owner),
+    theNumberOfTilesToBuffer(numberOfTilesToBuffer),
+    theOutputTile(NULL)
+{
+   theRank = 0;
+   theNumberOfProcessors = 1;
+   theNumberOfTilesToBuffer = ((theNumberOfTilesToBuffer>0)?theNumberOfTilesToBuffer:2);
+
+#ifdef OSSIM_HAS_MPI   
+#  if OSSIM_HAS_MPI
+   MPI_Comm_rank(MPI_COMM_WORLD, &theRank);
+   MPI_Comm_size(MPI_COMM_WORLD, &theNumberOfProcessors);
+#  endif
+#endif
+   
+   if(theRank!=0)
+   {
+      theCurrentTileNumber = theRank -1;
+   }
+   else
+   {
+      theCurrentTileNumber = 0;
+   }
+}
+
+ossimImageMpiSWriterSequenceConnection::ossimImageMpiSWriterSequenceConnection(ossimImageSource* inputSource,
+                                                                               ossimObject* owner,
+                                                                               long numberOfTilesToBuffer)
+   :ossimImageSourceSequencer(inputSource,
+                                 owner),
+    theNumberOfTilesToBuffer(numberOfTilesToBuffer),
+    theOutputTile(NULL)
+{
+   theRank = 0;
+   theNumberOfProcessors = 1;
+   theNumberOfTilesToBuffer = ((theNumberOfTilesToBuffer>0)?theNumberOfTilesToBuffer:2);
+#if OSSIM_HAS_MPI
+   MPI_Comm_rank(MPI_COMM_WORLD, &theRank);
+   MPI_Comm_size(MPI_COMM_WORLD, &theNumberOfProcessors);
+#endif
+   if(theRank!=0)
+   {
+      theCurrentTileNumber = theRank -1;
+   }
+   else
+   {
+      theCurrentTileNumber = 0;
+   }   
+}
+
+ossimImageMpiSWriterSequenceConnection::~ossimImageMpiSWriterSequenceConnection()
+{   
+   deleteOutputTiles();
+}
+
+void ossimImageMpiSWriterSequenceConnection::deleteOutputTiles()
+{
+   if(theOutputTile)
+   {
+      delete [] theOutputTile;
+      theOutputTile = NULL;
+   }
+}
+
+void ossimImageMpiSWriterSequenceConnection::initialize()
+{
+  ossimImageSourceSequencer::initialize();
+
+  theCurrentTileNumber = theRank-1;
+  if(theOutputTile)
+  {
+     deleteOutputTiles();
+  }
+  
+  if(theInputConnection)
+  {
+     theOutputTile = new ossimRefPtr<ossimImageData>[theNumberOfTilesToBuffer];
+     
+     for(long index = 0; index < theNumberOfTilesToBuffer; ++index)
+     {
+        theOutputTile[index] = ossimImageDataFactory::instance()->create(this,
+                                                                         this);
+        theOutputTile[index]->initialize();
+     }
+  }
+}
+
+void ossimImageMpiSWriterSequenceConnection::setToStartOfSequence()
+{
+   ossimImageSourceSequencer::setToStartOfSequence();
+   if(theRank != 0)
+   {
+      // we will subtract one since the masters job is just
+      // writting and not issue getTiles.
+      theCurrentTileNumber = theRank-1;
+
+   }
+   else
+   {
+      // the master will start at 0
+      theCurrentTileNumber = 0;
+   }
+}
+
+void ossimImageMpiSWriterSequenceConnection::slaveProcessTiles()
+{
+#ifdef OSSIM_HAS_MPI 
+#  if OSSIM_HAS_MPI
+   ossimEndian endian;
+   ossim_uint32 numberOfTiles    = getNumberOfTiles();
+   long currentSendRequest = 0;
+   long numberOfTilesSent  = 0;
+   int errorValue= 0;
+   MPI_Status status;
+   MPI_Status *statusArray = new MPI_Status[theNumberOfTilesToBuffer];
+   MPI_Request *requests   = new MPI_Request[theNumberOfTilesToBuffer];
+
+   memset(statusArray, '\0', sizeof(MPI_Status)*theNumberOfTilesToBuffer);
+   memset(requests, '\0', sizeof(MPI_Request)*theNumberOfTilesToBuffer);
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimImageMpiSWriterSequenceConnection::slaveProcessTiles(): entering slave and will look at " << numberOfTiles << " tiles" << std::endl;
+   }
+   while(theCurrentTileNumber < numberOfTiles)
+   {
+      ossimRefPtr<ossimImageData> data = ossimImageSourceSequencer::getTile(theCurrentTileNumber);
+
+      // if the current send requests have looped around
+      // make sure we wait to see if it was sent
+      //
+      errorValue = MPI_Wait(&requests[currentSendRequest],
+                            &status);
+      requests[currentSendRequest] = 0;
+      if(data.valid() &&
+         (data->getDataObjectStatus()!=OSSIM_NULL)&&
+         (data->getDataObjectStatus()!=OSSIM_EMPTY))
+      {
+         theOutputTile[currentSendRequest]->setImageRectangle(data->getImageRectangle());
+         theOutputTile[currentSendRequest]->initialize();
+         
+         theOutputTile[currentSendRequest]->loadTile(data.get());
+         theOutputTile[currentSendRequest]->setDataObjectStatus(data->getDataObjectStatus());
+
+         if(traceDebug())
+         {
+            if(data->getDataObjectStatus() == OSSIM_EMPTY)
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "DEBUG ossimImageMpiSWriterSequenceConnection::slaveProcessTiles(): In salve = "
+                  << theRank << " tile is empty" << std::endl;
+            }
+         }
+      }
+      else
+      {
+         if(traceDebug())
+         {
+            if(!data)
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "DEBUG ossimImageMpiSWriterSequenceConnection::slaveProcessTiles(): In slave = "
+                  << theRank << " ptr is null " << std::endl;
+            }
+            else
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "DEBUG ossimImageMpiSWriterSequenceConnection::slaveProcessTiles(): In slave = " << theRank << " tile is empty" << std::endl;
+            }
+         }
+         theOutputTile[currentSendRequest]->makeBlank();
+      }
+
+      void* buf = theOutputTile[currentSendRequest]->getBuf();
+      if((endian.getSystemEndianType()!=OSSIM_BIG_ENDIAN)&&
+         (theOutputTile[currentSendRequest]->getScalarType()!=OSSIM_UINT8))
+      {
+         endian.swap(theOutputTile[currentSendRequest]->getScalarType(),
+                     buf,
+                     theOutputTile[currentSendRequest]->getSize());
+      }
+      errorValue = MPI_Isend(buf,
+                             theOutputTile[currentSendRequest]->getSizeInBytes(),
+                             MPI_UNSIGNED_CHAR,
+                             0,
+                             0,
+                             MPI_COMM_WORLD,
+                             &requests[currentSendRequest]);
+#if 0      
+      switch(theOutputTile[currentSendRequest]->getScalarType())
+      {
+         case OSSIM_UINT8:
+         {
+            errorValue = MPI_Isend(buf,
+                                    theOutputTile[currentSendRequest]->getSize(),
+                                    MPI_UNSIGNED_CHAR,
+                                    0,
+                                    0,
+                                    MPI_COMM_WORLD,
+                                    &requests[currentSendRequest]);
+            break;
+         }
+         case OSSIM_SINT8:
+         {
+            errorValue = MPI_Isend(buf,
+                                    theOutputTile[currentSendRequest]->getSize(),
+                                    MPI_CHAR,
+                                    0,
+                                    0,
+                                    MPI_COMM_WORLD,
+                                    &requests[currentSendRequest]);
+            break;
+         }
+         case OSSIM_UINT16:
+         {
+            errorValue = MPI_Isend(buf,
+                                    theOutputTile[currentSendRequest]->getSize(),
+                                    MPI_UNSIGNED_SHORT,
+                                    0,
+                                    0,
+                                    MPI_COMM_WORLD,
+                                    &requests[currentSendRequest]);
+            break;
+         }
+         case OSSIM_SINT16:
+         {
+            errorValue = MPI_Isend(buf,
+                                    theOutputTile[currentSendRequest]->getSize(),
+                                    MPI_SHORT,
+                                    0,
+                                    0,
+                                    MPI_COMM_WORLD,
+                                    &requests[currentSendRequest]);
+            break;
+         }
+         case OSSIM_UINT32:
+         {
+            errorValue = MPI_Isend(buf,
+                                    theOutputTile[currentSendRequest]->getSize(),
+                                    MPI_UNSIGNED_LONG,
+                                    0,
+                                    0,
+                                    MPI_COMM_WORLD,
+                                    &requests[currentSendRequest]);
+            break;
+         }
+         case OSSIM_SINT32:
+         {
+            errorValue = MPI_Isend(buf,
+                                    theOutputTile[currentSendRequest]->getSize(),
+                                    MPI_LONG,
+                                    0,
+                                    0,
+                                    MPI_COMM_WORLD,
+                                    &requests[currentSendRequest]);
+            break;
+         }
+         case OSSIM_FLOAT32:
+         case OSSIM_NORMALIZED_FLOAT:
+         {
+            errorValue = MPI_Isend(buf,
+                                    theOutputTile[currentSendRequest]->getSize(),
+                                    MPI_FLOAT,
+                                    0,
+                                    0,
+                                    MPI_COMM_WORLD,
+                                    &requests[currentSendRequest]);
+            break;
+         }
+         case OSSIM_FLOAT64:
+         case OSSIM_NORMALIZED_DOUBLE:
+         {
+            errorValue = MPI_Isend(buf,
+                                    theOutputTile[currentSendRequest]->getSize(),
+                                    MPI_DOUBLE,
+                                    0,
+                                    0,
+                                    MPI_COMM_WORLD,
+                                    &requests[currentSendRequest]);
+            break;
+         }
+         default:
+            break;
+      }
+#endif
+      theCurrentTileNumber += (theNumberOfProcessors-1);
+      numberOfTilesSent++;
+      currentSendRequest++;
+      currentSendRequest %= theNumberOfTilesToBuffer;
+   }
+   ossim_int32 tempCount = 0;
+   // must wait in the correct order
+   //
+   while(tempCount < theNumberOfTilesToBuffer)
+   {
+      currentSendRequest++;
+      currentSendRequest %= theNumberOfTilesToBuffer;
+      
+      errorValue = MPI_Wait(&requests[currentSendRequest],
+                            &status);
+      ++tempCount;
+   }
+   
+//   MPI_Waitall(theNumberOfTilesToBuffer,
+//               requests,
+//               statusArray);
+   
+   delete [] statusArray;
+   delete [] requests;
+#  endif
+#endif
+}
+
+
+ossimRefPtr<ossimImageData> ossimImageMpiSWriterSequenceConnection::getNextTile(ossim_uint32 resLevel)
+{
+   ossimNotify(ossimNotifyLevel_FATAL)
+      << "FATAL ossimImageMpiSWriterSequenceConnection::getNextTile(): "
+      << "should not be called" << std::endl;
+   return ossimRefPtr<ossimImageData>();
+}
+
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiSWriterSequenceConnection.h b/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiSWriterSequenceConnection.h
new file mode 100644
index 0000000000..cc138cce53
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimImageMpiSWriterSequenceConnection.h
@@ -0,0 +1,53 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimImageMpiSWriterSequenceConnection.h,v 1.9 2005/02/11 15:07:35 dburken Exp $
+#ifndef ossimImageMpiSWriterSequenceConnection_HEADER
+#define ossimImageMpiSWriterSequenceConnection_HEADER
+#include <imaging/ossimImageSourceSequencer.h>
+class ossimImageData;
+class ossimImageMpiSWriterSequenceConnection : public ossimImageSourceSequencer
+{
+public:
+   ossimImageMpiSWriterSequenceConnection(ossimObject* owner=NULL,
+                                          long numberOfTilesToBuffer = 2);
+   
+   ossimImageMpiSWriterSequenceConnection(ossimImageSource* inputSource,
+                                          ossimObject* owner=NULL,
+                                          long numberOfTilesToBuffer = 2);
+   
+  virtual ~ossimImageMpiSWriterSequenceConnection();
+   virtual bool isMaster()const
+      {
+         return false;
+      }
+
+   virtual void initialize();
+   virtual void setToStartOfSequence();
+   /*!
+    * Will allow you to get the next tile in the sequence.
+    */
+   virtual ossimRefPtr<ossimImageData> getNextTile(ossim_uint32 resLevel=0);
+
+   virtual void slaveProcessTiles();
+   
+protected:
+   int theNumberOfProcessors;
+   int theRank;
+   int theNumberOfTilesToBuffer;
+   
+   ossimRefPtr<ossimImageData>* theOutputTile;
+
+   void deleteOutputTiles();
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimMpi.cpp b/Utilities/OSSIM/ossim_core/parallel/ossimMpi.cpp
new file mode 100644
index 0000000000..683cd203a0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimMpi.cpp
@@ -0,0 +1,175 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimMpi.cpp,v 1.20 2005/11/07 22:03:24 dburken Exp $
+
+#include <parallel/ossimMpi.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <time.h>
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimMpi.cpp,v 1.20 2005/11/07 22:03:24 dburken Exp $";
+#endif
+
+static ossimTrace traceDebug = ossimTrace("ossimMpi:debug");
+
+ossimMpi* ossimMpi::theInstance=0;
+
+ossimMpi* ossimMpi::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimMpi;
+      theInstance->setEnabledFlag(true);
+   }
+   
+   return theInstance;
+}
+
+bool ossimMpi::isEnabled()const
+{
+   return theEnabledFlag;
+}
+
+ossim_float64 ossimMpi::getTime()const
+{
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+   if(theEnabledFlag)
+   {
+      return MPI_Wtime();
+   }
+   else
+   {
+      return time(0);
+   }
+#  else
+   return time(0);
+#  endif
+#else
+   return time(0);
+#endif
+}
+
+void ossimMpi::initialize(int* argc, char*** argv)
+{
+   if(theEnabledFlag)
+   {
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+      int success=0;
+      success = MPI_Init(argc, argv);
+      if(traceDebug())
+      {
+#    ifdef OSSIM_ID_ENABLED
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimMpi::initialize: OSSIM_ID = "
+            << OSSIM_ID << std::endl;
+#    endif
+         if(success == MPI_SUCCESS)
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimMpi::initialize\n"
+               << "MPI is initialized and running with "
+               << getNumberOfProcessors()
+               << " processors..."
+               << std::endl;
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimMpi::initialize:  MPI is not initialized."
+               << std::endl;
+         }
+      }
+#  else
+      if(traceDebug())
+      {
+#    ifdef OSSIM_ID_ENABLED
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimMpi::initialize: OSSIM_ID = "
+            << OSSIM_ID << std::endl;
+#    endif
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimMpi::initialize: Not compiled with mpi!"
+            << std::endl;
+      }
+#  endif
+#else
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimMpi::initialize: Not compiled with mpi!"
+         << std::endl;   
+#endif
+   }
+}
+void ossimMpi::setEnabledFlag(bool flag)
+{
+   theEnabledFlag = flag;
+}
+
+void ossimMpi::finalize()
+{
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+   if(theEnabledFlag)
+   {
+      int success;
+      success = MPI_Finalize();
+      if(traceDebug())
+      {
+         if(success == MPI_SUCCESS)
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimMpi::finalize(): mpi is finalized" << std::endl;
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimMpi::finalize(): "
+               << "mpi is not finalized successfully" << std::endl;
+         }
+      }
+   }
+#  endif
+#endif
+}
+
+int ossimMpi::getRank()const
+{
+   int result = 0;
+
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+   if(theEnabledFlag)
+   {
+      MPI_Comm_rank(MPI_COMM_WORLD, &result);
+   }
+#  endif
+#endif
+   
+   return result;
+}
+
+int ossimMpi::getNumberOfProcessors()const
+{
+   int result = 1;
+
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+   if(theEnabledFlag)
+   {
+      MPI_Comm_size(MPI_COMM_WORLD, &result);
+   }
+#  endif
+#endif
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimMpi.h b/Utilities/OSSIM/ossim_core/parallel/ossimMpi.h
new file mode 100644
index 0000000000..71dd0e9246
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimMpi.h
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimMpi.h,v 1.10 2005/11/07 22:03:24 dburken Exp $
+#ifndef ossimMpi_HEADER
+#define ossimMpi_HEADER
+
+#include <ossimConfig.h>
+#include <base/common/ossimConstants.h>
+
+#ifdef OSSIM_HAS_MPI
+#  if OSSIM_HAS_MPI
+#    include <mpi.h>
+#  endif
+#endif
+
+class OSSIM_DLL ossimMpi
+{
+public:
+   static ossimMpi* instance();
+
+   ossim_float64 getTime()const;
+   /*!
+    * Typically called only one time
+    */
+   void initialize(int* argc, char*** argv);
+
+   /*!
+    * Called only once when we would like to
+    * shutdown mpi
+    */
+   void finalize();
+   int getRank()const;
+   int getNumberOfProcessors()const;
+   void setEnabledFlag(bool flag);
+   bool isEnabled()const;
+protected:
+   ossimMpi(){} // hide 
+   ossimMpi(const ossimMpi&){} // hide
+   void operator =(const ossimMpi&){} // hide
+
+   /*!
+    * We will have only a single instance of
+    * this class.
+    */
+   static ossimMpi* theInstance;
+   bool theEnabledFlag;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimOrthoIgen.cpp b/Utilities/OSSIM/ossim_core/parallel/ossimOrthoIgen.cpp
new file mode 100644
index 0000000000..995a0d2aa9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimOrthoIgen.cpp
@@ -0,0 +1,1051 @@
+#include <sstream>
+#include <parallel/ossimOrthoIgen.h>
+#include <parallel/ossimIgen.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <imaging/annotation/ossimGeoAnnotationSource.h>
+#include <imaging/ossimImageChain.h>
+#include <imaging/formats/ossimImageHandler.h>
+#include <imaging/tile_sources/ossimImageRenderer.h>
+#include <imaging/tile_sources/ossimHistogramRemapper.h>
+#include <imaging/tile_sources/ossimImageCombiner.h>
+#include <imaging/resample/ossimFilterResampler.h>
+#include <imaging/factory/ossimImageHandlerRegistry.h>
+#include <imaging/factory/ossimImageWriterFactoryRegistry.h>
+#include <base/common/ossimKeywordNames.h>
+#include <imaging/formats/tiff/ossimTiffWriter.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+#include <imaging/tile_sources/ossimGeoPolyCutter.h>
+#include <imaging/tile_sources/ossimEastingNorthingCutter.h>
+#include <base/misc/ossimUnitConversionTool.h>
+#include "ossimMpi.h"
+
+static ossimTrace traceDebug("ossimOrthoIgen:debug");
+static ossimTrace traceLog("ossimOrthoIgen:log");
+
+ossimOrthoIgen::ossimOrthoIgenFilename::ossimOrthoIgenFilename(const ossimFilename& file, bool decodeEntry)
+{
+   if(decodeEntry)
+   {
+      setFilenameWithDecoding(file);
+   }
+   else
+   {
+      setFilenameAndEntry(file, -1);
+   }
+}
+
+void ossimOrthoIgen::ossimOrthoIgenFilename::setFilenameWithDecoding(const ossimFilename& file)
+{
+   ossimFilename::size_type idx = file.rfind("|", file.length());
+   ossimString actualFile = file;
+   ossimString entry("-1");       
+   if(idx != ossimFilename::npos)
+   {
+      actualFile = ossimString(file.begin(), file.begin()+idx);
+      entry      = ossimString(file.begin()+idx+1,
+                               file.end());
+      entry = entry.trim();
+      actualFile = actualFile.trim();
+   }
+
+   theFilename = ossimFilename(actualFile);
+   theEntry    = entry.toInt32();
+}
+
+ossimOrthoIgen::ossimOrthoIgen()
+   :
+   theThumbnailRes(""),
+   theThumbnailFlag(false),
+   theMetersPerPixelOverride(OSSIM_DBL_NAN, OSSIM_DBL_NAN),
+   theProjectionType(OSSIM_UNKNOWN_PROJECTION),
+   theProjectionName(""),
+   theGeographicOriginOfLatitude(0.0),
+   theCombinerType("ossimImageMosaic"),
+   theResamplerType("nearest neighbor"),
+   theTemplateView(""),
+   theTilingTemplate(""),
+   theTilingFilename(""),
+   theChainTemplate(""),
+   theCombinerTemplate(""),
+   theAnnotationTemplate(""),
+   theWriterTemplate(""),
+   theSlaveBuffers("2"),
+   theCutCenter(OSSIM_DBL_NAN, OSSIM_DBL_NAN),
+   theCutDxDy(OSSIM_DBL_NAN, OSSIM_DBL_NAN),
+   theCutCenterUnit(OSSIM_UNIT_UNKNOWN),
+   theCutDxDyUnit(OSSIM_UNIT_UNKNOWN),
+   theLowPercentClip(OSSIM_DBL_NAN),
+   theHighPercentClip(OSSIM_DBL_NAN),
+   theFilenames()
+{
+   // setDefaultValues();
+}
+
+void ossimOrthoIgen::addArguments(ossimArgumentParser& argumentParser)
+{
+   argumentParser.getApplicationUsage()->addCommandLineOption("--annotate", "annotation keyword list");
+
+   argumentParser.getApplicationUsage()->addCommandLineOption("-t or --thumbnail", "thumbnail resolution");
+   
+   argumentParser.getApplicationUsage()->addCommandLineOption("--meters","Specifies an override for the meters per pixel");
+   argumentParser.getApplicationUsage()->addCommandLineOption("--slave-buffers","number of slave tile buffers for mpi processing (default = 2)");
+   argumentParser.getApplicationUsage()->addCommandLineOption("--view-template","Specify an external file that contains view information");
+   argumentParser.getApplicationUsage()->addCommandLineOption("--chain-template","Specify an external file that contains chain information");
+   argumentParser.getApplicationUsage()->addCommandLineOption("--combiner-template","Specify an external file that contains combiner information");
+   argumentParser.getApplicationUsage()->addCommandLineOption("--tiling-template","Specify an external file that contains tiling information");
+   argumentParser.getApplicationUsage()->addCommandLineOption("--writer-template","Specify an external file that contains tiling information");
+   
+   argumentParser.getApplicationUsage()->addCommandLineOption("--utm","Defaults to a utm image chain with GSD = to the input");
+
+   argumentParser.getApplicationUsage()->addCommandLineOption("--geo","Defaults to a geographic image chain with GSD = to the input.  Origin of latitude is on the equator.");
+   argumentParser.getApplicationUsage()->addCommandLineOption("--input-proj","Makes the view equal to the input.  If more than one file then the first is taken");
+   
+   argumentParser.getApplicationUsage()->addCommandLineOption("--geo-scaled","Takes a latitude as an argument for purpose of scaling.  Specifies that no spec file was defined.  Defaults to a scaled geographic image chain with GSD = to the input.");
+   
+   argumentParser.getApplicationUsage()->addCommandLineOption("--combiner-type","Specify what mosaic to use, ossimImageMosiac or ossimFeatherMosaic or osimBlendMosaic ... etc");
+   
+   argumentParser.getApplicationUsage()->addCommandLineOption("--resample-type","Specify what resampler to use, nearest neighbor, bilinear, bicubic");
+   
+   argumentParser.getApplicationUsage()->addCommandLineOption("--cut-center-ll","Specify the center cut in lat lon space.  Takes two argument <lat> <lon>");
+   argumentParser.getApplicationUsage()->addCommandLineOption("--cut-radius-meters","Specify the cut distance in meters.  A bounding box for the cut will be produced");
+
+   argumentParser.getApplicationUsage()->addCommandLineOption("--hist-stretch","Specify in normalized percent the low clip and then the high clip value");
+}
+
+void ossimOrthoIgen::initialize(ossimArgumentParser& argumentParser)
+{
+   double tempDouble;
+   double tempDouble2;
+   ossimString tempString;
+   ossimArgumentParser::ossimParameter stringParam(tempString);
+   ossimArgumentParser::ossimParameter doubleParam(tempDouble);
+   ossimArgumentParser::ossimParameter doubleParam2(tempDouble2);
+   theCutCenter.makeNan();
+   theCutDxDy.makeNan();
+   theCutCenterUnit   = OSSIM_UNIT_UNKNOWN;
+   theCutDxDyUnit     = OSSIM_UNIT_UNKNOWN;
+   theLowPercentClip  = OSSIM_DBL_NAN;
+   theHighPercentClip = OSSIM_DBL_NAN;
+   
+   theMetersPerPixelOverride.makeNan();
+   if(argumentParser.read("--annotate", stringParam))
+   {
+      theAnnotationTemplate = ossimFilename(tempString);
+   }
+   if(argumentParser.read("-t", stringParam)   ||
+      argumentParser.read("--thumbnail", stringParam))
+   {
+      theThumbnailRes  = tempString;
+      theThumbnailFlag = true;
+   }
+   if(argumentParser.read("--slave-buffers", stringParam))
+   {
+      theSlaveBuffers = tempString;
+   }
+   if(argumentParser.read("--cut-center-ll", doubleParam, doubleParam2))
+   {
+      theCutCenter.lat = tempDouble;
+      theCutCenter.lon = tempDouble2;
+      theCutCenterUnit = OSSIM_DEGREES;
+   }
+   if(argumentParser.read("--cut-radius-meters", doubleParam))
+   {
+      theCutDxDy.x = tempDouble;
+      theCutDxDy.y = tempDouble;
+      theCutDxDyUnit = OSSIM_METERS;
+   }
+   if(argumentParser.read("--hist-stretch", doubleParam, doubleParam2))
+   {
+      theLowPercentClip = tempDouble;
+      theHighPercentClip = tempDouble2;
+   }
+   if(argumentParser.read("--meters", doubleParam))
+   {
+      theMetersPerPixelOverride.x = tempDouble;
+      theMetersPerPixelOverride.y = tempDouble;
+   }
+   if(argumentParser.read("--writer-template",
+                          stringParam))
+   {
+      theWriterTemplate = tempString;
+   }
+   if(argumentParser.read("--tiling-template",
+                          stringParam))
+   {
+      theTilingTemplate = ossimFilename(tempString);
+   }
+   if(argumentParser.read("--chain-template", stringParam))
+   {
+      theChainTemplate = ossimFilename(tempString);
+   }
+   if(argumentParser.read("--combiner-template", stringParam))
+   {
+      theCombinerTemplate = ossimFilename(tempString);
+   }
+   if (argumentParser.read("--utm"))
+   {
+      theProjectionType = OSSIM_UTM_PROJECTION;
+      theProjectionName = "ossimUtmProjection";
+   }
+   else if(argumentParser.read("--geo"))
+   {
+      theProjectionType = OSSIM_GEO_PROJECTION;
+      theProjectionName = "ossimEquDistCylProjection";
+   }
+   else if(argumentParser.read("--input-proj"))
+   {
+      theProjectionType = OSSIM_INPUT_PROJECTION;
+   }
+   else
+   {
+      theProjectionType = OSSIM_UNKNOWN_PROJECTION;
+   }
+   if(argumentParser.read("--view-template", stringParam))
+   {
+      theTemplateView = ossimFilename(tempString);
+      theProjectionType = OSSIM_EXTERNAL_PROJECTION;
+   }
+   if(argumentParser.read("--geo-scaled", doubleParam))
+   {
+      theProjectionType = OSSIM_GEO_PROJECTION;
+      theProjectionName = "ossimEquDistCylProjection";
+      if ( (tempDouble < 90.0) && (tempDouble > -90.0) )
+      {
+         theGeographicOriginOfLatitude = tempDouble;
+      }
+      else
+      {
+         theGeographicOriginOfLatitude = 0.0;
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimOrthoIgen::initialize WARNING:"
+            << "\nLatitude out  of range!  Must be between -90 and 90."
+            << "\nRemains at zero."
+            << std::endl;
+      }
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimOrthoIgen::initialize DEBUG:"
+            << "\ngeographicOriginOfLatitude:  " << theGeographicOriginOfLatitude
+            << std::endl;
+      }
+   }
+   if(argumentParser.read("--combiner-type", stringParam))
+   {
+      theCombinerType = tempString;
+   }
+   else
+   {
+      theCombinerType = "ossimImageMosaic";
+   }
+   if(argumentParser.read("--resample-type", stringParam))
+   {
+      theResamplerType = tempString;
+   }
+
+   
+}
+
+void ossimOrthoIgen::addFiles(ossimArgumentParser& argumentParser,
+                              bool withDecoding,
+                              ossim_uint32 startIdx)
+{
+   ossim_uint32 idx = startIdx;
+   while(argumentParser.argv()[idx])
+   {
+      addFile(ossimFilename(argumentParser.argv()[idx]), withDecoding);
+//      theFilenames.push_back(ossimFilename(argumentParser.argv()[idx]));
+      ++idx;
+   }
+}
+
+bool ossimOrthoIgen::execute()
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimOrthoIgen::execute DEBUG: Entered ..."
+         << std::endl;
+   }
+//   double start=0, stop=0;
+
+   if(theFilenames.size() < 1)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimOrthoIgen::execute WARNING: No filenames to process"
+         << std::endl;
+      return false;
+   }
+
+//    if(ossimMpi::instance()->getRank() == 0)
+//    {
+//       start = ossimMpi::instance()->getTime();
+//    }
+   ossimKeywordlist igenKwl;
+   ossimKeywordlist inputGeom;
+   if(ossimMpi::instance()->getRank() == 0)
+   {
+      if(!setupIgenKwl(igenKwl))
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "ossimOrthoIgen::execute DEBUG: setupIgenKwl returned false..."
+               << std::endl;
+         }
+         return false;
+      }
+
+      if (traceLog())
+      {
+         const char* lookup = igenKwl.find("object2.filename");
+         if (lookup)
+         {
+            ossimFilename logFile = lookup;
+            logFile.setExtension("log");
+            igenKwl.write(logFile.c_str());
+         }
+      }
+   }
+   
+   ossimIgen *igen = new ossimIgen;
+   igen->initialize(igenKwl);
+   igen->outputProduct();
+   
+//    if(ossimMpi::instance()->getRank() == 0)
+//    {
+//       stop = ossimMpi::instance()->getTime();
+//       ossimNotify(ossimNotifyLevel_NOTICE)
+//          << "Time elapsed: " << (stop-start)
+//          << std::endl;
+//    }
+   delete igen;
+   igen = NULL;
+
+   return true;
+}
+
+void ossimOrthoIgen::clearFilenameList()
+{
+   theFilenames.clear();
+}
+
+void ossimOrthoIgen::addFile(const ossimFilename& file,
+                             bool withEncodedEntry)
+{
+   ossimOrthoIgenFilename filename;
+   if(withEncodedEntry)
+   {
+      filename.setFilenameWithDecoding(file);
+   }
+   else
+   {
+      filename.setFilenameAndEntry(file, -1);
+   }
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimOrthoIgen::addFile DEBUG:"
+         << "\nAdded file: " << filename.theFilename
+         << std::endl;
+   }   
+
+   theFilenames.push_back(filename);
+}
+
+void ossimOrthoIgen::setDefaultValues()
+{
+   theThumbnailRes = "";
+   theThumbnailFlag = false;
+   theMetersPerPixelOverride.makeNan();
+   theTemplateView = "";
+   theProjectionType = OSSIM_UNKNOWN_PROJECTION;
+   theGeographicOriginOfLatitude = 0.0;
+   theCombinerType = "ossimImageMosaic";
+   theResamplerType = "nearest neighbor";
+   theTilingTemplate = "";
+   theTilingFilename = "";
+   theSlaveBuffers = "2";
+   clearFilenameList();
+   theLowPercentClip = OSSIM_DBL_NAN;
+   theHighPercentClip = OSSIM_DBL_NAN;
+   theCutCenter.makeNan();
+   theCutDxDy.makeNan();
+   theCutCenterUnit   = OSSIM_UNIT_UNKNOWN;
+   theCutDxDyUnit     = OSSIM_UNIT_UNKNOWN;
+}
+
+void ossimOrthoIgen::setCombinerType(const ossimString& combinerType)
+{
+   theCombinerType = combinerType;
+}
+
+void ossimOrthoIgen::setProjectionName(const ossimString& projName)
+{
+   // for now we will only support utm or geographic for this.
+   theProjectionName = projName;
+
+   if(projName == "ossimUtmProjection")
+   {
+      theProjectionType = OSSIM_UTM_PROJECTION;
+   }
+   else if(projName == "ossimEquDistCylProjection")
+   {
+      theProjectionType = OSSIM_GEO_PROJECTION;
+   }
+}
+
+void ossimOrthoIgen::setResamplerType(const ossimString& resamplerType)
+{
+   theResamplerType = resamplerType;
+}
+
+void ossimOrthoIgen::setCutCenter(const ossimDpt& dpt,
+                                  ossimUnitType unit)
+{
+   theCutCenter     = dpt;
+   theCutCenterUnit = unit;
+}
+
+void ossimOrthoIgen::setCutDxDy(const ossimDpt& dpt,
+                                ossimUnitType unit)
+{
+   theCutDxDy     = dpt;
+   theCutDxDyUnit = unit;
+}
+
+bool ossimOrthoIgen::setupIgenKwl(ossimKeywordlist& kwl)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimOrthoIgen::setupIgenKwl DEBUG: Entered ..."
+         << std::endl;
+   }
+   setupTiling(kwl);
+   kwl.add("igen.thumbnail",
+           theThumbnailFlag,
+           true);
+   if((theThumbnailRes != "")&&
+      theThumbnailFlag)
+   {
+      kwl.add("igen.thumbnail_res",
+              theThumbnailRes.c_str(),
+              true);
+   }
+   if(theSlaveBuffers == "")
+   {
+      kwl.add("igen.slave_tile_buffers",
+              2,
+              true);
+   }
+   else
+   {
+      kwl.add("igen.slave_tile_buffers",
+              theSlaveBuffers.c_str(),
+              true);
+   }
+   ossim_uint32 inputFileIdx = 0;
+   if(!setupView(kwl))
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimOrthoIgen::execute DEBUG: setupView returned false..."
+            << std::endl;
+      }
+       return false;
+   }
+
+   if(theFilenames.size() > 1)
+   {
+      ossimKeywordlist tempKwl;
+      ossimRefPtr<ossimObject> obj;
+      
+
+      if(theChainTemplate.exists())
+      {
+         tempKwl.addFile(theChainTemplate);
+         obj = ossimObjectFactoryRegistry::instance()->createObject(tempKwl);
+      }
+      ossimRefPtr<ossimImageChain> chain = PTR_CAST(ossimImageChain, obj.get());
+      
+      if(!chain)  // then create a default rendering chain
+      {
+         ossimImageChain*    tempChain = new ossimImageChain;
+         if(theProjectionType != OSSIM_UNKNOWN_PROJECTION)
+         {
+            ossimImageRenderer* tempObject   = new ossimImageRenderer;
+            if(tempObject->getResampler())
+            {
+               tempObject->getResampler()->setFilterType(theResamplerType);
+            }
+            if(tempObject)
+            {
+               tempChain->addChild(tempObject);
+            }
+         }
+         obj   = tempChain;
+         chain = tempChain;
+      }
+      
+      ossimRefPtr<ossimConnectableObject> mosaicObject;
+      if(theCombinerTemplate.exists())
+      {
+         tempKwl.clear();
+         tempKwl.addFile(theCombinerTemplate);
+      }
+      mosaicObject = (ossimConnectableObject*)ossimObjectFactoryRegistry::instance()->createObject(tempKwl);
+      if(!PTR_CAST(ossimImageCombiner,
+                  mosaicObject.get()))
+      {
+         mosaicObject = 0;
+      }
+      if(!mosaicObject.valid())
+      {
+         mosaicObject = (ossimConnectableObject*)ossimObjectFactoryRegistry::instance()->createObject(theCombinerType);
+      }
+      if(!mosaicObject)
+      {
+         mosaicObject = (ossimConnectableObject*)ossimObjectFactoryRegistry::instance()->createObject(ossimString("ossimImageMosaic"));
+      }
+      
+      if(!mosaicObject)
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "Unable to create a mosaic object" << std::endl;
+         return false;
+      }
+      
+      ossim_uint32 fileSize = theFilenames.size()-1;
+      ossim_uint32 idx;
+      ossim_uint32 chainIdx = 1;
+      ossimRefPtr<ossimImageChain> rootChain = new ossimImageChain;
+      chain->saveState(kwl, "object1.object1.");
+      for(idx = inputFileIdx;idx < fileSize; ++idx)
+      {
+         // first lets add an input to the chain
+         //
+         ossimFilename input  = theFilenames[idx].theFilename;
+         ossimRefPtr<ossimImageHandler> handler = ossimImageHandlerRegistry::instance()->open(input);
+         ossimHistogramRemapper* histRemapper = 0;
+         if(handler.valid())
+         {
+            std::vector<ossim_uint32> entryList;
+            if(theFilenames[idx].theEntry >-1)
+            {
+               entryList.push_back(theFilenames[idx].theEntry);
+            }
+            else
+            {
+               handler->getEntryList(entryList);
+            }
+
+            ossim_uint32 entryIdx = 0;
+            for(entryIdx = 0; entryIdx < entryList.size(); ++entryIdx)
+            {
+               ossimImageHandler* h = (ossimImageHandler*)handler->dup();
+               h->setCurrentEntry(entryList[entryIdx]);
+               ossimImageChain* tempChain = (ossimImageChain*)chain->dup();
+               tempChain->addLast(h);
+               
+               if((theHighPercentClip!=OSSIM_DBL_NAN)&&
+                  (theLowPercentClip!=OSSIM_DBL_NAN))
+               {
+                  ossimFilename inputHisto = handler->createHistogramFilename();
+                  if(inputHisto.exists())
+                  {
+                     tempChain->addLast(histRemapper);
+                     histRemapper = new ossimHistogramRemapper;
+                     tempChain->insertRight(histRemapper, h);
+                     histRemapper->openHistogram(inputHisto);
+                     histRemapper->setHighNormalizedClipPoint(1.0-theHighPercentClip);
+                     histRemapper->setLowNormalizedClipPoint(theLowPercentClip);
+                  }
+                  else
+                  {
+                     ossimNotify(ossimNotifyLevel_WARN)
+                        <<"Histogram file " << inputHisto
+                        << " not found!"
+                        << std::endl;
+                  }
+               }
+               tempChain->makeUniqueIds();
+               tempChain->saveState(kwl, (ossimString("object1.object")+ossimString::toString(chainIdx)+".").c_str());
+               rootChain->add(tempChain);
+               ++chainIdx;
+               mosaicObject->connectMyInputTo(tempChain);
+            }
+         }
+         else if(input == "NULL_FILE")
+         {
+            ossimImageChain* tempChain = (ossimImageChain*)chain->dup();
+            tempChain->makeUniqueIds();
+            tempChain->saveState(kwl, (ossimString("object1.object")+ossimString::toString(chainIdx)+".").c_str());
+            rootChain->add(tempChain);
+            ++chainIdx;
+            mosaicObject->connectMyInputTo(tempChain);
+         }
+      }
+      mosaicObject->saveState(kwl, (ossimString("object1.object")+
+                                    ossimString::toString(chainIdx)+".").c_str());
+
+      ++chainIdx;
+
+      ossimRefPtr<ossimConnectableObject> input = mosaicObject;
+
+      // Annotation setup...
+      ossimRefPtr<ossimConnectableObject> annotator =
+         setupAnnotation(kwl, input.get());
+      if (annotator.valid())
+      {
+         annotator->saveState(
+            kwl,
+            (ossimString("object1.object")+
+             ossimString::toString(chainIdx)+".").c_str());
+         input = annotator;
+         ++chainIdx;
+      }
+      else
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "ossimOrthoIgen::setupIgenKwl DEBUG:\n"
+               << "setupAnnotation failed..."
+               << std::endl;
+         }
+         // return false; Not sure if we want this to be an error???
+      }
+      
+      ossimRefPtr<ossimConnectableObject> cutter = setupCutter(kwl,
+                                                               input.get());
+      
+      if(cutter.valid())
+      {
+         cutter->saveState(kwl, (ossimString("object1.object")+
+                                 ossimString::toString(chainIdx)+".").c_str());
+         input = cutter;
+      }
+                  
+      rootChain = 0;
+      kwl.add("object1.type",
+              "ossimImageChain",
+              true);
+
+      if(!setupWriter(kwl, input.get()))
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "ossimOrthoIgen::execute DEBUG: setupWriter returned false..."
+               << std::endl;
+         }
+         return false;
+      }
+      
+   }
+
+   return true;
+}
+
+ossimRefPtr<ossimConnectableObject> ossimOrthoIgen::setupCutter(
+   ossimKeywordlist& kwl, ossimConnectableObject* input)
+{
+   ossimRefPtr<ossimConnectableObject> result;
+   if(theCutDxDy.hasNans())
+   {
+      return result;
+   }
+   ossimRefPtr<ossimProjection> viewProj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl, "product.projection.");
+   
+   if(viewProj.valid())
+   {
+      ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, viewProj.get());
+      if(mapProj)
+      {
+         ossimGpt centerLatLon(theCutCenter.lat,
+                               theCutCenter.lon,
+                               0.0,
+                               mapProj->getDatum());
+//         if(theCutDxDyUnit == OSSIM_METERS)
+         {
+            if(!mapProj->isGeographic())
+            {
+               ossimDpt dxdy(ossimUnitConversionTool(theCutDxDy.x, theCutDxDyUnit).getValue(OSSIM_METERS),
+                             ossimUnitConversionTool(theCutDxDy.y, theCutDxDyUnit).getValue(OSSIM_METERS));
+               
+               ossimEastingNorthingCutter* cutter = new ossimEastingNorthingCutter;
+               ossimDpt pt, centerEn;
+               mapProj->worldToLineSample(centerLatLon,
+                                          pt);
+               pt = ossimIpt(pt);
+               mapProj->lineSampleToEastingNorthing(pt, centerEn);
+               
+               ossimDpt ul = centerEn + ossimDpt(-dxdy.x,
+                                                 dxdy.y);
+               ossimDpt lr = centerEn + ossimDpt(dxdy.x,
+                                                 -dxdy.y);
+               
+               
+               cutter->setEastingNorthingRectangle(ul, lr);
+               
+               result = cutter;
+            }
+            else
+            {
+               ossimDpt dxdy(ossimUnitConversionTool(theCutDxDy.x, theCutDxDyUnit).getValue(OSSIM_DEGREES),
+                             ossimUnitConversionTool(theCutDxDy.y, theCutDxDyUnit).getValue(OSSIM_DEGREES));
+               ossimGeoPolyCutter* cutter = new ossimGeoPolyCutter;
+               ossimDpt metersPerDegree = centerLatLon.metersPerDegree();
+               ossimDpt degreePerMeter;
+               std::vector<ossimGpt> polygon;
+               degreePerMeter.x = ((metersPerDegree.x > FLT_EPSILON)?1.0/metersPerDegree.x:0.0);
+               degreePerMeter.y = ((metersPerDegree.y > FLT_EPSILON)?1.0/metersPerDegree.y:0.0);
+               
+               ossimGpt ul(centerLatLon.latd() + dxdy.y,
+                           centerLatLon.lond() - dxdy.x);
+               ossimGpt ur(centerLatLon.latd() + dxdy.y,
+                           centerLatLon.lond() + dxdy.x);
+               ossimGpt lr(centerLatLon.latd() - dxdy.y,
+                           centerLatLon.lond() + dxdy.x);
+               ossimGpt ll(centerLatLon.latd() - dxdy.y,
+                           centerLatLon.lond() - dxdy.x);
+
+               polygon.push_back(ul);
+               polygon.push_back(ur);
+               polygon.push_back(lr);
+               polygon.push_back(ll);
+               cutter->setNumberOfPolygons(1);
+               cutter->setPolygon(polygon);
+
+               result = cutter;
+
+            }
+         }
+      }
+   }
+   if(result.valid())
+   {
+      result->connectMyInputTo(input);
+   }
+   
+   return result;
+}
+
+bool ossimOrthoIgen::setupWriter(ossimKeywordlist& kwl, ossimConnectableObject* input)
+{
+   ossimFilename outputFilename = theFilenames[theFilenames.size()-1].theFilename;
+   ossimImageFileWriter* writer = 0;
+   if(theTilingFilename!="")
+   {
+      if(!outputFilename.isDir())
+      {
+         outputFilename = outputFilename.path();
+      }
+      outputFilename = outputFilename.dirCat(theTilingFilename);
+   }
+
+   if((theWriterTemplate == "")||
+      (!theWriterTemplate.exists()))
+   {
+      ossimRefPtr<ossimImageFileWriter> outputObj = 0;
+      if(theTilingFilename == "%SRTM%")
+      {
+         ossimKeywordlist kwlWriter;
+         
+         kwlWriter.add("type",
+                       "ossimGeneralRasterWriter",
+                       true);
+         kwlWriter.add("byte_order",
+                       "big_endian");
+         outputObj = ossimImageWriterFactoryRegistry::instance()->createWriter(kwlWriter);
+         outputFilename = outputFilename.path();
+      }
+      else if(outputFilename.ext() != "")
+      {
+         ossimFilename ext = outputFilename.ext();
+         outputObj = ossimImageWriterFactoryRegistry::instance()->createWriterFromExtension(ext);
+         if(!outputObj.valid())
+         {
+            outputObj = new ossimTiffWriter;
+            writer = (ossimImageFileWriter*)outputObj.get();
+            outputFilename.setExtension("tif");
+         }
+      }
+      else
+      {
+         // just do a default just so we can set the keywords for now
+         //
+         outputObj = new ossimTiffWriter;
+      }
+      if(outputObj.valid())
+      {
+         writer = (ossimImageFileWriter*)outputObj.get();
+         writer->setFilename(outputFilename);
+         
+         writer->connectMyInputTo(0, input);
+         writer->saveState(kwl, "object2.");
+      }
+      kwl.add("object2.",
+              ossimKeywordNames::FILENAME_KW,
+              outputFilename.c_str(),
+              true);
+      
+      if(!kwl.find("object2.type"))
+      {
+         kwl.add("object2.",
+                 "type",
+                 "ossimImageFileWriter",
+                 true);
+      }
+   }
+
+   return true;
+}
+
+bool ossimOrthoIgen::setupView(ossimKeywordlist& kwl)
+{
+   ossimKeywordlist tempKwl;
+   if(theTemplateView != "")
+   {
+      tempKwl.addFile(theTemplateView);
+   }
+   ossimRefPtr<ossimObject> productObj = ossimObjectFactoryRegistry::instance()->createObject(tempKwl, "product.projection.");
+   if(!productObj.valid())
+   {
+      productObj = ossimObjectFactoryRegistry::instance()->createObject(tempKwl);
+      if(!PTR_CAST(ossimProjection, productObj.get()))
+      {
+         productObj = 0;
+      }
+      else
+      {
+         if(!theMetersPerPixelOverride.hasNans())
+         {
+            ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, productObj.get());
+
+            if(mapProj&&!theMetersPerPixelOverride.hasNans())
+            {
+               mapProj->setMetersPerPixel(theMetersPerPixelOverride);
+            }
+         }
+      }
+   }
+   if(!productObj.valid() && (theTemplateView!=""))
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimOrthoIgen::setupView WARNING: File template "
+         << theTemplateView << " did not have a valid view" << std::endl;
+   }
+   if(productObj.valid())
+   {
+      productObj->saveState(kwl, "product.projection.");
+   }
+   else
+   {
+      ossimKeywordlist inputGeom;
+      // Open up the image.
+      ossimFilename input  = theFilenames[0].theFilename;
+      ossimRefPtr<ossimImageHandler> handler =
+         ossimImageHandlerRegistry::instance()->open(input);
+      if(!handler)
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "ossimOrthoIgen::setupView DEBUG:"
+               << "\nCould not open: " << input.c_str()
+               << std::endl;
+         }
+ 
+         return false;
+      }
+      handler->getImageGeometry(inputGeom);
+      
+      // Get the input projection.
+      ossimRefPtr<ossimProjection> inputProj =
+         ossimProjectionFactoryRegistry::instance()->createProjection(
+            inputGeom);
+      if(inputProj.valid()&&
+         (theProjectionType !=OSSIM_UNKNOWN_PROJECTION))
+      {
+         // Get the input resolution.
+         ossimDpt metersPerPixel = inputProj->getMetersPerPixel();
+         
+         ossim_float64 gsd = (metersPerPixel.x+metersPerPixel.y)/2.0;
+         if(!theMetersPerPixelOverride.hasNans())
+         {
+            gsd = theMetersPerPixelOverride.x;
+         }
+         
+         // Get the bounding rect.
+         ossimIrect rect = handler->getBoundingRect();
+         
+         // Create an output projection.
+         ossimRefPtr<ossimMapProjection> outputProjection;
+         if (theProjectionType == OSSIM_GEO_PROJECTION)
+         {
+            // Assuming WGS 84 for now.
+            outputProjection = new ossimEquDistCylProjection();
+            ossimGpt gpt(theGeographicOriginOfLatitude, 0.0);
+            
+            // Set the origin.
+            outputProjection->setOrigin(gpt);
+            // Set the resolution.
+            outputProjection->setMetersPerPixel(ossimDpt(gsd, gsd));
+            
+            // Save the state to keyword list.
+            outputProjection->saveState(kwl, "product.projection.");
+         }
+         else if((theProjectionType == OSSIM_UTM_PROJECTION)||
+                 ((theProjectionType == OSSIM_INPUT_PROJECTION) &&
+                  !PTR_CAST(ossimMapProjection, inputProj.get())))
+            
+         {
+            // Default to UTM.
+            ossimUtmProjection* utm = new ossimUtmProjection;
+            ossimGpt midGpt;
+            
+            
+            inputProj->lineSampleToWorld(ossimDpt(rect.midPoint()),
+                                         midGpt);
+            
+            utm->setZone(midGpt);
+            
+            ossimDpt eastingNorthing;
+            
+            utm->setMetersPerPixel(ossimDpt(gsd, gsd));
+            
+            eastingNorthing = utm->forward(utm->origin());
+            
+            utm->setUlEastingNorthing(eastingNorthing);
+            outputProjection = utm;
+            // Set the resolution.
+            outputProjection->setMetersPerPixel(ossimDpt(gsd, gsd));
+            // Save the state to keyword list.
+            outputProjection->saveState(kwl, "product.projection.");
+         }
+         else // input is a map projection so just use that if we are type INPUT
+         {
+            inputProj->saveState(kwl, "product.projection.");
+         }
+      }
+   }
+   return true;
+}
+
+ossimRefPtr<ossimConnectableObject> ossimOrthoIgen::setupAnnotation(
+   ossimKeywordlist& kwl, ossimConnectableObject* input) const
+{
+   ossimRefPtr<ossimConnectableObject> result = NULL;
+   
+   if(theAnnotationTemplate.exists() == false)
+   {
+      return result;
+   }
+   
+   ossimKeywordlist tempKwl;
+   if (tempKwl.addFile(theAnnotationTemplate) == false)
+   {
+      return result;
+   }
+   
+   ossimRefPtr<ossimObject> obj = ossimObjectFactoryRegistry::instance()->
+      createObject(tempKwl, "object1.");
+   if (obj.valid())
+   {
+      ossimGeoAnnotationSource* oga = PTR_CAST(ossimGeoAnnotationSource,
+                                               obj.get());
+      if (oga)
+      {
+         // Connect to input.
+         oga->connectMyInputTo(input);
+         
+         // Set the view.
+         ossimRefPtr<ossimProjection> viewProj =
+            ossimProjectionFactoryRegistry::instance()->createProjection(
+               kwl, "product.projection.");
+         if (viewProj.valid())
+         {
+            oga->setProjection(viewProj.get(),
+                               false); // False for doesn't own projection.
+         }
+
+         result = oga;
+      }
+   }
+   
+   return result;
+}
+
+bool ossimOrthoIgen::setupTiling(ossimKeywordlist& kwl)
+{
+   ossimKeywordlist tempKwl;
+   ossimFilename outputFilename = theFilenames[theFilenames.size()-1].theFilename;
+
+   if((theTilingTemplate == "")||
+      (!tempKwl.addFile(theTilingTemplate)))
+   {
+      return false;
+   }
+
+   if(outputFilename.isDir())
+   {
+      if(tempKwl.find("igen.tiling.type"))
+      {
+         kwl.add(tempKwl);
+         theTilingFilename = tempKwl.find("igen.tiling.tile_name_mask");
+      }
+      else if(tempKwl.find("type"))
+      {
+         kwl.add("igen.tiling.", tempKwl);
+         theTilingFilename = tempKwl.find("tile_name_mask");
+      }
+   }
+   else
+   {
+      theTilingFilename = outputFilename.file();
+      if(tempKwl.find("igen.tiling.type"))
+      {
+         tempKwl.add("igen.tiling.tile_name_mask",
+                     theTilingFilename.c_str(),
+                     true);
+         kwl.add(tempKwl);
+      }
+      else if(tempKwl.find("type"))
+      {
+         tempKwl.add("tile_name_mask",
+                     theTilingFilename.c_str(),
+                     true);
+         kwl.add("igen.tiling.", tempKwl);
+      }
+   }
+   
+   return true;
+}
+
+void ossimOrthoIgen::setMetersPerPixel(const ossimDpt& mpp)
+{
+   theMetersPerPixelOverride = mpp;
+}
+
+void ossimOrthoIgen::setThumbnailResolution(const ossimIpt& res)
+{
+   std::ostringstream out;
+
+   out << res.x << " " << res.y;
+
+   theThumbnailRes = out.str().c_str();
+}
+
+void ossimOrthoIgen::setThumbnailFlag(bool thumbnailFlag)
+{
+   theThumbnailFlag = thumbnailFlag;
+}
diff --git a/Utilities/OSSIM/ossim_core/parallel/ossimOrthoIgen.h b/Utilities/OSSIM/ossim_core/parallel/ossimOrthoIgen.h
new file mode 100644
index 0000000000..0e91f28cf6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/parallel/ossimOrthoIgen.h
@@ -0,0 +1,144 @@
+#ifndef ossimOrthoIgen_HEADER
+#define ossimOrthoIgen_HEADER
+#include <base/common/ossimObject.h>
+#include <base/common/ossimArgumentParser.h>
+#include <base/common/ossimApplicationUsage.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimFilename.h>
+class ossimConnectableObject;
+class OSSIM_DLL ossimOrthoIgen : public ossimReferenced
+{
+public:
+   enum ossimOrthoIgenProjectionType
+   {
+      OSSIM_UNKNOWN_PROJECTION = 0,
+      OSSIM_UTM_PROJECTION,
+      OSSIM_GEO_PROJECTION,
+      OSSIM_INPUT_PROJECTION,
+      OSSIM_EXTERNAL_PROJECTION
+   };
+   class ossimOrthoIgenFilename
+   {
+   public:
+      ossimOrthoIgenFilename()
+         :theFilename(""),
+         theEntry(-1)
+         {}
+      ossimOrthoIgenFilename(const ossimFilename& file, bool decodeEntry);
+      ossimOrthoIgenFilename(const ossimFilename& file, ossim_int32 entryNumber)
+         :theFilename(file),
+         theEntry(entryNumber)
+      {
+      }
+      void setFilenameWithDecoding(const ossimFilename& file);
+      void setFilenameAndEntry(const ossimFilename& file,
+                               ossim_int32 entry)
+      {
+         theFilename = file;
+         theEntry    = entry;
+      }
+      ossimFilename theFilename;
+      ossim_int32  theEntry;
+   };
+   ossimOrthoIgen();
+
+   /**
+    * Will add command line arguments to initialize this object from a command line application
+    *
+    * <pre>
+    * Command Line Arguments:
+    *
+    * -t or --thumbnail  Takes an integer argument that is used to set both width
+    *                    and height.
+    *                    example: -t 1024 will produce an image that is 1024x1024
+    * --meters           Takes a double precision argument that is used for meters per pixel
+    *                    override.
+    *                    example: --meters 5 will create a 5 meter product.
+    * --slave-buffers    Takes an integer as an argument that specifies the number of slave tile buffers per
+    *                    slave node.  The slave nodes are suppose to be asynch send.  It will
+    *                    not wait for the send to finish.  It will got to the next buffer and check to
+    *                    see if it's been sent and if not it will then wait for the buffer to be free.
+    *                    example: --slave-buffers 10  will create 10 buffers per slave node.
+    * --chain-template   Takes a file name that is a kewyord list that is used as a template for every
+    *                    input file.
+    *                    example:
+    * 
+    * @param argumentParser Argument parser object to add command line options to
+    *
+    */ 
+   void addArguments(ossimArgumentParser& argumentParser);
+   void initialize(ossimArgumentParser& argumentParser);
+   void addFiles(ossimArgumentParser& argumentParser,
+                 bool withDecoding,
+                 ossim_uint32 startIdx = 1);
+   void clearFilenameList();
+   void addFile(const ossimFilename& file, bool withDecoding=false);
+   bool execute();
+   void setDefaultValues();
+
+   void setCombinerType(const ossimString& combinerName);
+   
+   void setProjectionName(const ossimString& proj);
+   void setResamplerType(const ossimString& resamplerType);
+
+   
+   void setCutCenter(const ossimDpt& dpt,
+                     ossimUnitType unit = OSSIM_DEGREES);
+   void setCutDxDy(const ossimDpt& dpt,
+                   ossimUnitType unit = OSSIM_METERS);
+   void setMetersPerPixel(const ossimDpt& mpp);
+   void setThumbnailResolution(const ossimIpt& res);
+   void setThumbnailFlag(bool flag);
+
+   bool setupIgenKwl(ossimKeywordlist& kwl);
+   
+protected:
+   ossimString theThumbnailRes;
+   bool        theThumbnailFlag;
+   ossimDpt    theMetersPerPixelOverride;
+   ossimOrthoIgenProjectionType theProjectionType;
+   ossimString                  theProjectionName;
+   ossim_float64 theGeographicOriginOfLatitude;
+   ossimString   theCombinerType;
+   ossimString   theResamplerType;
+   ossimFilename theTemplateView;
+   ossimFilename theTilingTemplate;
+   ossimFilename theTilingFilename;
+   ossimFilename theChainTemplate;
+   ossimFilename theCombinerTemplate;
+   ossimFilename theAnnotationTemplate;
+   ossimFilename theWriterTemplate;
+   ossimString   theSlaveBuffers;
+   ossimDpt      theCutCenter;
+   ossimDpt      theCutDxDy;
+   ossimUnitType theCutCenterUnit;
+   ossimUnitType theCutDxDyUnit;
+   ossim_float64 theLowPercentClip;
+   ossim_float64 theHighPercentClip;
+   
+   std::vector<ossimOrthoIgenFilename> theFilenames;
+
+   bool setupTiling(ossimKeywordlist& kwl);
+   
+   ossimRefPtr<ossimConnectableObject> setupCutter(ossimKeywordlist& kwl,
+                                                   ossimConnectableObject* input);
+   bool setupWriter(ossimKeywordlist& kwl,
+                    ossimConnectableObject* input);
+   bool setupView(ossimKeywordlist& kwl);
+
+   /**
+    * Sets up any annotation from --annotate option.
+    *
+    * @param kwl Main keyword list to save to.
+    *
+    * @param input Input connection of the annotation filter.
+    *
+    * @note This must be called after "setupView" as it needs a projection.
+    */
+   ossimRefPtr<ossimConnectableObject> setupAnnotation(
+      ossimKeywordlist& kwl,
+      ossimConnectableObject* input) const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/plugin/.cvsignore b/Utilities/OSSIM/ossim_core/plugin/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/plugin/CMakeLists.txt b/Utilities/OSSIM/ossim_core/plugin/CMakeLists.txt
new file mode 100644
index 0000000000..e4ce402dd8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_plugin_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_plugin_HDRS "*.h")
+ADD_LIBRARY(ossim_plugin ${ossim_plugin_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_plugin)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_plugin_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/plugin/ossimDynamicLibrary.cpp b/Utilities/OSSIM/ossim_core/plugin/ossimDynamicLibrary.cpp
new file mode 100644
index 0000000000..6383f20d4c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/ossimDynamicLibrary.cpp
@@ -0,0 +1,118 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// LICENSE: LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*********************************************************************
+// $Id: ossimDynamicLibrary.cpp,v 1.13 2005/10/17 18:42:27 gpotts Exp $
+#include <plugin/ossimDynamicLibrary.h>
+#include <plugin/ossimSharedObjectBridge.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+
+RTTI_DEF(ossimDynamicLibrary, "ossimDynamicLibrary");
+
+// Static trace for debugging.
+static ossimTrace traceDebug(ossimString("ossimDynamicLibrary:debug"));
+
+ossimDynamicLibrary::ossimDynamicLibrary()
+   :theLibrary(0)
+{
+}
+
+ossimDynamicLibrary::ossimDynamicLibrary(const ossimString& name)
+{
+   load(name);
+}
+
+ossimDynamicLibrary::~ossimDynamicLibrary()
+{
+}
+
+bool ossimDynamicLibrary::load()
+{
+   return load(theLibraryName);
+}
+
+
+bool ossimDynamicLibrary::load(const ossimString& name)
+{
+   ossimFilename libraryName = name;
+#if OSSIM_DYNAMIC_ENABLED
+#  if defined(__WIN32__) || defined(_WIN32)
+   libraryName.convertForwardToBackSlashes();
+   theLibrary = LoadLibrary(libraryName.c_str());
+#  elif HAVE_DLFCN_H
+   libraryName.convertBackToForwardSlashes();
+   theLibrary = dlopen(libraryName.c_str(), RTLD_LAZY);
+#  endif
+#endif
+
+   if (isLoaded())
+   {
+      theLibraryName = libraryName;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimDynamicLibrary::load DEBUG:" << std::endl;
+      
+      if (isLoaded())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Loaded library:  " << name << std::endl;
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimDynamicLibrary::load DEBUG:"
+            << "\nFailed to load library:  " << name
+            << std::endl;
+#if OSSIM_DYNAMIC_ENABLED
+#  if HAVE_DLFCN_H
+         ossimNotify(ossimNotifyLevel_DEBUG) << dlerror() << std::endl;
+#  endif
+#endif
+      }
+      
+   }
+   
+   return isLoaded();
+}
+
+void ossimDynamicLibrary::unload()
+{
+   if(isLoaded())
+   {
+#if OSSIM_DYNAMIC_ENABLED
+#  if defined(__WIN32__) || defined(_WIN32)
+      FreeLibrary(theLibrary);
+#  elif HAVE_DLFCN_H
+      dlclose(theLibrary);
+#  endif
+#endif
+      theLibrary = NULL;
+   }
+}
+
+void *ossimDynamicLibrary::getSymbol(const ossimString& name) const
+{
+   if(isLoaded())
+   {
+#if OSSIM_DYNAMIC_ENABLED
+#  if defined(__WIN32__) || defined(_WIN32)
+      return (void*)GetProcAddress( (HINSTANCE)theLibrary, name.c_str());
+#  elif HAVE_DLFCN_H
+      return dlsym(theLibrary, name.c_str());
+#  endif
+#endif
+   }
+
+   return (void*)NULL;
+}
diff --git a/Utilities/OSSIM/ossim_core/plugin/ossimDynamicLibrary.h b/Utilities/OSSIM/ossim_core/plugin/ossimDynamicLibrary.h
new file mode 100644
index 0000000000..2908188e14
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/ossimDynamicLibrary.h
@@ -0,0 +1,69 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// LICENSE: LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimDynamicLibrary.h,v 1.9 2004/11/10 17:44:32 dburken Exp $
+#ifndef ossimDynamicLibrary_HEADER
+#define ossimDynamicLibrary_HEADER
+
+#include <base/data_types/ossimString.h>
+#include <base/common/ossimRtti.h>
+#include <base/common/ossimReferenced.h>
+
+#include <ossimConfig.h>
+
+#if defined(_WIN32) || defined(__WIN32__)
+#include <windows.h>
+#elif HAVE_DLFCN_H
+#include <dlfcn.h>
+#else
+#define OSSIM_DYNAMIC_DISABLED
+// #error "dynamic loading interface is unsupported on this platform"
+#endif
+
+class ossimDynamicLibrary : public ossimReferenced
+{
+public:
+   ossimDynamicLibrary();
+   ossimDynamicLibrary(const ossimString& name);
+   virtual ~ossimDynamicLibrary();
+   // return TRUE if the library was loaded successfully
+   bool isLoaded() const { return theLibrary != 0; }
+
+   // load the library with the given name (full or not), return TRUE on
+   // success
+   bool load(const ossimString& name);
+
+   bool load();
+   // unload the library, also done automatically in dtor
+   void unload();
+
+   // load a symbol from the library, return NULL if an error occured or
+   // symbol wasn't found
+   void *getSymbol(const ossimString& name) const;
+
+   const ossimString& getName()const
+      {
+         return theLibraryName;
+      }
+
+protected:
+    // the handle to DLL or NULL
+#if defined(_WIN32)
+	HINSTANCE theLibrary;
+#else
+	void* theLibrary;
+#endif
+   ossimString theLibraryName;
+
+TYPE_DATA
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/plugin/ossimPluginLibrary.cpp b/Utilities/OSSIM/ossim_core/plugin/ossimPluginLibrary.cpp
new file mode 100644
index 0000000000..ee4f480dca
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/ossimPluginLibrary.cpp
@@ -0,0 +1,95 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimPluginLibrary.cpp,v 1.4 2005/05/20 16:28:31 gpotts Exp $
+#include "ossimPluginLibrary.h"
+
+RTTI_DEF1(ossimPluginLibrary, "ossimPluginLibrary", ossimDynamicLibrary);
+
+ossimPluginLibrary::ossimPluginLibrary()
+   :ossimDynamicLibrary(),
+    theInfo(0)
+{
+}
+
+ossimPluginLibrary::ossimPluginLibrary(const ossimString& name)
+   :ossimDynamicLibrary(name),
+    theInfo(0)
+{
+   initialize();
+}
+
+ossimPluginLibrary::~ossimPluginLibrary()
+{
+}
+
+void ossimPluginLibrary::initialize()
+{
+   if(!isLoaded())
+   {
+      load();
+   }
+
+   ossimSharedLibraryInitializePtr init = (ossimSharedLibraryInitializePtr)getSymbol("ossimSharedLibraryInitialize");
+   
+   if(init)
+   {         
+      init(&theInfo);
+   }
+}
+
+void ossimPluginLibrary::finalize()
+{
+   ossimSharedLibraryInitializePtr finalizeLib = (ossimSharedLibraryInitializePtr)getSymbol("ossimSharedLibraryFinalize");
+   if(finalizeLib)
+   {         
+      finalizeLib(&theInfo);
+   }
+   
+   unload();
+}
+
+ossimString ossimPluginLibrary::getDescription()const
+{
+   ossimString result;
+
+   if(theInfo&&isLoaded()&&theInfo->getDescription)
+   {
+      result = theInfo->getDescription();
+   }
+
+   return result;
+}
+
+void ossimPluginLibrary::getClassNames(std::vector<ossimString>& classNames)const
+{
+   if(theInfo&&theInfo->getNumberOfClassNames&&theInfo->getClassName)
+   {
+      ossim_int32 idx        = 0;
+      ossim_int32 numObjects = 0;
+
+      numObjects = theInfo->getNumberOfClassNames();
+      for(idx = 0; idx < numObjects; ++idx)
+      {
+         classNames.push_back(theInfo->getClassName(idx));
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/plugin/ossimPluginLibrary.h b/Utilities/OSSIM/ossim_core/plugin/ossimPluginLibrary.h
new file mode 100644
index 0000000000..b0dd643fc1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/ossimPluginLibrary.h
@@ -0,0 +1,45 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimPluginLibrary.h,v 1.3 2004/05/19 18:37:37 dburken Exp $
+#ifndef ossimPluginLibrary_HEADER
+#define ossimPluginLibrary_HEADER
+#include "plugin/ossimSharedObjectBridge.h"
+#include "ossimDynamicLibrary.h"
+
+class OSSIMDLLEXPORT ossimPluginLibrary : public ossimDynamicLibrary
+{
+public:
+   ossimPluginLibrary();
+   ossimPluginLibrary(const ossimString& name);
+   virtual ~ossimPluginLibrary();
+   void initialize();
+   void finalize();
+   ossimString getDescription()const;
+   void getClassNames(std::vector<ossimString>& classNames)const;
+   
+protected:
+   ossimSharedObjectInfo* theInfo;
+
+TYPE_DATA
+};
+
+#endif 
diff --git a/Utilities/OSSIM/ossim_core/plugin/ossimSharedObjectBridge.cpp b/Utilities/OSSIM/ossim_core/plugin/ossimSharedObjectBridge.cpp
new file mode 100644
index 0000000000..afb8ec014c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/ossimSharedObjectBridge.cpp
@@ -0,0 +1,27 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimSharedObjectBridge.cpp,v 1.3 2004/08/30 17:16:54 gpotts Exp $
+#include "ossimSharedObjectBridge.h"
+
+extern "C"
+{
+}
diff --git a/Utilities/OSSIM/ossim_core/plugin/ossimSharedObjectBridge.h b/Utilities/OSSIM/ossim_core/plugin/ossimSharedObjectBridge.h
new file mode 100644
index 0000000000..d1ca048487
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/ossimSharedObjectBridge.h
@@ -0,0 +1,54 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimSharedObjectBridge.h,v 1.17 2005/05/20 20:28:27 dburken Exp $
+#ifndef ossimSharedObjectBridge_HEADER
+#define ossimSharedObjectBridge_HEADER
+#include <vector>
+#include "base/common/ossimObject.h"
+#include "base/common/ossimConstants.h"
+
+extern "C"
+{
+   typedef const char* (*ossimSharedLibraryGetDescriptionPtr)();
+   typedef int (*ossimSharedLibraryGetNumberOfClassNamesPtr)();
+   typedef const char* (*ossimSharedLibraryGetClassNamesPtr)(int idx);
+   
+   struct OSSIMDLLEXPORT ossimSharedObjectInfo
+   {
+      ossimSharedLibraryGetDescriptionPtr getDescription;
+      ossimSharedLibraryGetNumberOfClassNamesPtr getNumberOfClassNames;
+      ossimSharedLibraryGetClassNamesPtr getClassName;
+   };
+   
+   
+   typedef void (*ossimSharedLibraryInitializePtr)(ossimSharedObjectInfo** info);
+   typedef void (*ossimSharedLibraryFinalizePtr)();
+
+   /*
+    * these need to define these in your plugin.  They are only here for clairity
+    * 
+    * extern void ossimSharedLibraryInitialize(ossimSharedObjectInfo** info);
+    * extern void ossimSharedLibraryFinalize();
+    */
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/plugin/ossimSharedPluginRegistry.cpp b/Utilities/OSSIM/ossim_core/plugin/ossimSharedPluginRegistry.cpp
new file mode 100644
index 0000000000..e0b2f1b9f0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/ossimSharedPluginRegistry.cpp
@@ -0,0 +1,181 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimSharedPluginRegistry.cpp,v 1.25 2005/05/20 20:28:27 dburken Exp $
+#include <algorithm>
+#include <plugin/ossimSharedPluginRegistry.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <plugin/ossimSharedObjectBridge.h>
+
+ossimSharedPluginRegistry* ossimSharedPluginRegistry::theInstance = NULL;
+//ossimPluginBridgeStructure ossimSharedPluginRegistry::thePluginBridgeFactoryPointers;
+
+static ossimTrace traceDebug("ossimSharedPluginRegistry:debug");
+
+ossimSharedPluginRegistry::~ossimSharedPluginRegistry()
+{
+   theLibraryList.clear();
+
+   theInstance = NULL;
+}
+
+ossimSharedPluginRegistry* ossimSharedPluginRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimSharedPluginRegistry;
+   }
+
+   return theInstance;
+}
+
+bool ossimSharedPluginRegistry::registerPlugin(const ossimFilename& filename)
+{
+   bool result = false;
+   if(!getPlugin(filename))
+   {
+      ossimPluginLibrary *lib =new ossimPluginLibrary;
+      if(lib->load(filename))
+      {
+         if(lib->getSymbol("ossimSharedLibraryInitialize"))
+         {
+            lib->initialize();
+            theLibraryList.push_back(lib);
+            result = true;
+         }
+         else
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "ossimSharedPluginRegistry DEBUG:"
+                                                   << "ossimSharedLibraryInitialize symbol not found\n"
+                                                   << endl;
+            }
+            
+         }
+      }
+      else
+      {
+         delete lib;
+         lib = 0;
+      }
+   }
+   return result;
+}
+
+bool ossimSharedPluginRegistry::unregisterPlugin(int idx)
+{
+   ossimPluginLibrary* lib = getPlugin(idx);
+   bool result = false;
+   if(lib)
+   {
+      std::vector<ossimRefPtr<ossimPluginLibrary> >::iterator iter = std::find(theLibraryList.begin(),
+                                                                   theLibraryList.end(),
+                                                                   lib);
+
+      if(iter != theLibraryList.end())
+      {
+         (*iter)->finalize();
+         theLibraryList.erase(iter);
+         result  = true;
+      }
+   }
+   
+   return result;
+}
+
+const ossimPluginLibrary* ossimSharedPluginRegistry::getPlugin(const ossimFilename& filename)const
+{
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theLibraryList.size();++idx)
+   {
+      if(filename == theLibraryList[idx]->getName())
+      {
+         return theLibraryList[idx].get();
+      }
+   }
+   
+   return 0;
+}
+
+ossimPluginLibrary* ossimSharedPluginRegistry::getPlugin(const ossimFilename& filename)
+{
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theLibraryList.size();++idx)
+   {
+      if(filename == theLibraryList[idx]->getName())
+      {
+         return theLibraryList[idx].get();
+      }
+   }
+   
+   return 0;
+}
+
+ossim_uint32 ossimSharedPluginRegistry::getIndex(const ossimPluginLibrary* lib)const
+{
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theLibraryList.size(); ++idx)
+   {
+      if(theLibraryList[idx] == lib)
+      {
+         return idx;
+      }
+   }
+
+   return idx;
+}
+
+ossimPluginLibrary* ossimSharedPluginRegistry::getPlugin(ossim_uint32 idx)
+{
+   ossimPluginLibrary* result = 0;
+   
+   if((idx>=0)&&(idx < theLibraryList.size()))
+   {
+      result = theLibraryList[idx].get();
+   }
+
+   return result;
+}
+
+const ossimPluginLibrary* ossimSharedPluginRegistry::getPlugin(ossim_uint32 idx)const
+{
+   const ossimPluginLibrary* result = 0;
+   
+   if((idx>=0)&&(idx < theLibraryList.size()))
+   {
+      result = theLibraryList[idx].get();
+   }
+
+   return result;
+}
+
+ossim_uint32 ossimSharedPluginRegistry::getNumberOfPlugins()const
+{
+   return theLibraryList.size();
+}
diff --git a/Utilities/OSSIM/ossim_core/plugin/ossimSharedPluginRegistry.h b/Utilities/OSSIM/ossim_core/plugin/ossimSharedPluginRegistry.h
new file mode 100644
index 0000000000..5edbb9eaae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/plugin/ossimSharedPluginRegistry.h
@@ -0,0 +1,36 @@
+#ifndef ossimSharedPluginRegistry_HEADER
+#define ossimSharedPluginRegistry_HEADER
+#include <vector>
+#include <plugin/ossimSharedObjectBridge.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/common/ossimRefPtr.h>
+#include <plugin/ossimPluginLibrary.h>
+
+class OSSIMDLLEXPORT ossimSharedPluginRegistry
+{
+public:
+   virtual ~ossimSharedPluginRegistry();
+   
+   static ossimSharedPluginRegistry* instance();
+
+   bool registerPlugin(const ossimFilename& filename);
+   bool unregisterPlugin(int idx);
+   const ossimPluginLibrary* getPlugin(const ossimFilename& filename)const;
+   ossimPluginLibrary* getPlugin(const ossimFilename& filename);
+
+   ossim_uint32 getIndex(const ossimPluginLibrary* lib)const;
+   ossimPluginLibrary* getPlugin(ossim_uint32 idx);
+   const ossimPluginLibrary* getPlugin(ossim_uint32 idx)const;
+   ossim_uint32 getNumberOfPlugins()const;
+   
+protected:
+   ossimSharedPluginRegistry(){}
+   ossimSharedPluginRegistry(const ossimSharedPluginRegistry&){}
+   void operator = (const ossimSharedPluginRegistry&){}
+
+   static ossimSharedPluginRegistry* theInstance;
+  
+   std::vector<ossimRefPtr<ossimPluginLibrary> > theLibraryList;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/.cvsignore b/Utilities/OSSIM/ossim_core/projections/.cvsignore
new file mode 100644
index 0000000000..5e618e9f5c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+.shared_obj
+Makefile
diff --git a/Utilities/OSSIM/ossim_core/projections/CMakeLists.txt b/Utilities/OSSIM/ossim_core/projections/CMakeLists.txt
new file mode 100644
index 0000000000..1a192de6a0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_projections_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_projections_HDRS "*.h")
+ADD_LIBRARY(ossim_projections ${ossim_projections_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_projections)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_projections_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/.cvsignore b/Utilities/OSSIM/ossim_core/projections/factory/.cvsignore
new file mode 100644
index 0000000000..7df3918588
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+Makefile
+
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimImageViewTransformFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimImageViewTransformFactory.cpp
new file mode 100644
index 0000000000..3f5858d547
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimImageViewTransformFactory.cpp
@@ -0,0 +1,69 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimImageViewTransformFactory.cpp,v 1.3 2002/08/27 17:30:11 gpotts Exp $
+#include "ossimImageViewTransformFactory.h"
+#include "projections/ossimImageViewProjectionTransform.h"
+#include "projections/ossimImageViewAffineTransform.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+RTTI_DEF1(ossimImageViewTransformFactory, "ossimImageViewTransformFactory", ossimObject)
+
+ossimImageViewTransformFactory* ossimImageViewTransformFactory::theInstance = 0;
+
+ossimImageViewTransformFactory* ossimImageViewTransformFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimImageViewTransformFactory;
+   }
+
+   return theInstance;
+}
+
+ossimImageViewTransform* ossimImageViewTransformFactory::createTransform(const ossimKeywordlist& kwl,
+                                                                         const char* prefix)
+{
+   ossimImageViewTransform* result=NULL;
+   
+   const char *lookup = kwl.find(prefix, "type");
+
+   if(lookup)
+   {
+      if(ossimString(lookup) == STATIC_TYPE_NAME(ossimImageViewProjectionTransform))
+      {
+         result = new ossimImageViewProjectionTransform;
+      }
+      if(ossimString(lookup) == STATIC_TYPE_NAME(ossimImageViewAffineTransform))
+      {
+         result = new ossimImageViewAffineTransform;
+      }
+   }
+   if(result)
+   {
+      result->loadState(kwl, prefix);
+   }
+   
+   return result;
+}
+   
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimImageViewTransformFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimImageViewTransformFactory.h
new file mode 100644
index 0000000000..0ef7269f50
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimImageViewTransformFactory.h
@@ -0,0 +1,49 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimImageViewTransformFactory.h,v 1.1 2001/10/26 13:49:04 gpotts Exp $
+#ifndef ossimImageViewTransformFactory_HEADER
+#define ossimImageViewTransformFactory_HEADER
+#include "base/common/ossimObject.h"
+
+class ossimImageViewTransform;
+class ossimKeywordlist;
+
+class ossimImageViewTransformFactory : public ossimObject
+{
+public:
+   static ossimImageViewTransformFactory* instance();
+   virtual ossimImageViewTransform* createTransform(const ossimKeywordlist& kwl,
+                                                    const char* prefix = 0);
+   
+protected:
+   ossimImageViewTransformFactory(){}//hide
+   ossimImageViewTransformFactory(const ossimImageViewTransformFactory&){}
+   void operator =(const ossimImageViewTransformFactory&){}
+
+   static ossimImageViewTransformFactory* theInstance;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimMapProjectionFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimMapProjectionFactory.cpp
new file mode 100644
index 0000000000..de275890b1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimMapProjectionFactory.cpp
@@ -0,0 +1,326 @@
+//*****************************************************************************
+// FILE: ossimMapProjectionFactory.cc
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimMapProjectionFactory
+//
+// SOFTWARE HISTORY:
+//>
+//   15Jun2001  Garrett Potts
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimMapProjectionFactory.cpp,v 1.42 2004/09/24 17:19:40 dburken Exp $
+
+#include <projections/factory/ossimMapProjectionFactory.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimFilename.h>
+
+//***
+// Note to programmer: To add a new projection, search this file for
+// "ADD_PROJECTION" to locate places requiring editing. Functional example
+// below...
+//
+// ADD_PROJECTION: Include all map projection headers here:
+//***
+
+#include "projections/map_projections/ossimAlbersProjection.h"
+#include "projections/map_projections/ossimAzimEquDistProjection.h"
+#include "projections/map_projections/ossimBonneProjection.h"
+#include "projections/map_projections/ossimBngProjection.h"
+#include "projections/map_projections/ossimCassiniProjection.h"
+#include "projections/map_projections/ossimCylEquAreaProjection.h"
+#include "projections/map_projections/ossimEquDistCylProjection.h"
+#include "projections/map_projections/ossimEckert4Projection.h"
+#include "projections/map_projections/ossimEckert6Projection.h"
+#include "projections/map_projections/ossimGnomonicProjection.h"
+#include "projections/map_projections/ossimLambertConformalConicProjection.h"
+#include "projections/map_projections/ossimLlxyProjection.h"
+#include "projections/map_projections/ossimMercatorProjection.h"
+#include "projections/map_projections/ossimMillerProjection.h"
+#include "projections/map_projections/ossimMollweidProjection.h"
+#include "projections/map_projections/ossimNewZealandMapGridProjection.h"
+#include "projections/map_projections/ossimObliqueMercatorProjection.h"
+#include "projections/map_projections/ossimOrthoGraphicProjection.h"
+#include "projections/map_projections/ossimPolarStereoProjection.h"
+#include "projections/map_projections/ossimPolyconicProjection.h"
+#include "projections/map_projections/ossimSinusoidalProjection.h"
+#include "projections/map_projections/ossimStereographicProjection.h"
+#include "projections/map_projections/ossimTransCylEquAreaProjection.h"
+#include "projections/map_projections/ossimTransMercatorProjection.h"
+#include "projections/map_projections/ossimUpsProjection.h"
+#include "projections/map_projections/ossimUtmProjection.h"
+#include "projections/map_projections/ossimVanDerGrintenProjection.h"
+#include "projections/map_projections/ossimSpaceObliqueMercatorProjection.h"
+#include <support_data/ikonos/ossimSpaceImagingGeom.h>
+//***
+// ADD_PROJECTION: List names of all map projections produced by this factory:
+//***
+
+ossimMapProjectionFactory* ossimMapProjectionFactory::theInstance = 0;
+
+//*****************************************************************************
+//  STATIC METHOD: ossimMapProjectionFactory::instance()
+//  
+//*****************************************************************************
+ossimMapProjectionFactory* ossimMapProjectionFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimMapProjectionFactory;
+   }
+
+   return (ossimMapProjectionFactory*) theInstance;
+}
+
+ossimProjection*
+ossimMapProjectionFactory::createProjection(const ossimFilename& filename,
+                                            ossim_uint32 entryIdx)const
+{
+   if(!filename.exists())
+   {
+      return NULL;
+   }
+
+   // Check for external geometry file.
+   ossimProjection* proj = createProjectionFromGeometryFile(filename,
+                                                            entryIdx);
+   if (proj)
+   {
+      return proj;
+   }
+
+   ossimFilename geomFile = filename;
+   geomFile = geomFile.setExtension("geom");
+   if(!geomFile.exists())
+   {
+      return NULL;
+   }
+   ossimKeywordlist kwl;
+   if(kwl.addFile(geomFile))
+   {
+      return createProjection(kwl);
+   }
+
+   return NULL;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSensorModelFactory::create(kwl, prefix)
+//  
+//*****************************************************************************
+ossimProjection* ossimMapProjectionFactory::createProjection(const ossimKeywordlist &keywordList,
+															 const char *prefix) const
+{
+   ossimProjection *result=NULL;
+	
+   const char *lookup = keywordList.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char *lookupSpaceImaging = keywordList.find(prefix, ossimSpaceImagingGeom::SIG_PRODUCER_KW);
+   if(lookup)
+   {
+      result = createProjection(ossimString(lookup).trim());
+      if(result)
+      {
+         result->loadState(keywordList, prefix);
+      }
+   }
+   else
+   {
+      if(lookupSpaceImaging)
+      {
+		  ossimKeywordlist kwl;
+		  ossimKeywordlist kwl2;
+		  kwl.add(keywordList,
+				  prefix,
+				  true);
+         
+         ossimSpaceImagingGeom spaceImaging;
+         
+         spaceImaging.setGeometry(kwl);
+
+         spaceImaging.exportToOssim(kwl2);
+
+         result = ossimProjectionFactoryRegistry::instance()->createProjection(kwl2);
+         if(result)
+         {
+            return result;
+         }
+      }
+      // look for the geom_file keyword.
+      //
+      lookup = keywordList.find(prefix, ossimKeywordNames::GEOM_FILE_KW);
+      if(lookup)
+      {
+         ossimKeywordlist kwl;
+
+         kwl.addFile(lookup);
+
+         result = createProjection(kwl);
+         
+         if(!result)
+         {
+         // maybe they prepend projection. in the geom
+         // file.
+            result = createProjection(kwl, "projection.");
+         }
+
+      }      
+   }
+   return result;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSensorModelFactory::create(projection_name)
+//  
+//*****************************************************************************
+ossimProjection* ossimMapProjectionFactory::createProjection(const ossimString &name) const
+{
+   //***
+   // ADD_PROJECTION: Test for each map projection here:
+   //***
+   if(name ==  STATIC_TYPE_NAME(ossimAlbersProjection))
+      return new ossimAlbersProjection;
+   if(name ==  STATIC_TYPE_NAME(ossimAzimEquDistProjection))
+      return new ossimAzimEquDistProjection;
+   if( name == STATIC_TYPE_NAME(ossimBonneProjection))
+      return new ossimBonneProjection;
+   if( name == STATIC_TYPE_NAME(ossimBngProjection))
+      return new ossimBngProjection;
+   if(name ==  STATIC_TYPE_NAME(ossimCassiniProjection))
+      return new ossimCassiniProjection;
+   if(name ==  STATIC_TYPE_NAME(ossimCylEquAreaProjection))
+      return new ossimCylEquAreaProjection;
+   if(name ==  STATIC_TYPE_NAME(ossimEquDistCylProjection))
+      return new ossimEquDistCylProjection;
+   if(name ==  STATIC_TYPE_NAME(ossimEckert4Projection))
+      return new ossimEckert4Projection;
+   if(name ==  STATIC_TYPE_NAME(ossimEckert6Projection))
+      return new ossimEckert6Projection;
+   if(name == STATIC_TYPE_NAME(ossimGnomonicProjection))
+      return new ossimGnomonicProjection;
+   if(name ==  STATIC_TYPE_NAME(ossimLambertConformalConicProjection))
+      return new ossimLambertConformalConicProjection;
+   if(name ==  STATIC_TYPE_NAME(ossimLlxyProjection))
+      return new ossimLlxyProjection;
+   if(name == STATIC_TYPE_NAME(ossimMercatorProjection))
+      return new ossimMercatorProjection;
+   if(name == STATIC_TYPE_NAME(ossimMillerProjection))
+      return new ossimMillerProjection;
+   if(name == STATIC_TYPE_NAME(ossimMollweidProjection))
+      return new ossimMollweidProjection;
+   if(name == STATIC_TYPE_NAME(ossimNewZealandMapGridProjection))
+      return new ossimNewZealandMapGridProjection;
+   if(name == STATIC_TYPE_NAME(ossimObliqueMercatorProjection))
+      return new ossimObliqueMercatorProjection;
+   if(name == STATIC_TYPE_NAME(ossimOrthoGraphicProjection))
+      return new ossimOrthoGraphicProjection;
+   if(name == STATIC_TYPE_NAME(ossimPolarStereoProjection))
+      return new ossimPolarStereoProjection;
+   if(name == STATIC_TYPE_NAME(ossimPolyconicProjection))
+      return new ossimPolyconicProjection;
+   if(name == STATIC_TYPE_NAME(ossimSinusoidalProjection))
+      return new ossimSinusoidalProjection;
+   if(name == STATIC_TYPE_NAME(ossimStereographicProjection))
+      return new ossimStereographicProjection;
+   if(name == STATIC_TYPE_NAME(ossimTransCylEquAreaProjection))
+      return new ossimTransCylEquAreaProjection;
+   if(name == STATIC_TYPE_NAME(ossimTransMercatorProjection))
+      return new ossimTransMercatorProjection;
+   if(name == STATIC_TYPE_NAME(ossimUpsProjection))
+      return new ossimUpsProjection;
+   if(name == STATIC_TYPE_NAME(ossimUtmProjection))
+      return new ossimUtmProjection;
+   if(name == STATIC_TYPE_NAME(ossimVanDerGrintenProjection))
+      return new ossimVanDerGrintenProjection;
+   if(name == STATIC_TYPE_NAME(ossimSpaceObliqueMercatorProjection))
+   {
+      return new ossimSpaceObliqueMercatorProjection;
+   }
+   return NULL;
+}
+
+ossimObject* ossimMapProjectionFactory::createObject(const ossimString& typeName)const
+{
+   return createProjection(typeName);
+}
+
+ossimObject* ossimMapProjectionFactory::createObject(const ossimKeywordlist& kwl,
+                                                     const char* prefix)const
+{
+   return createProjection(kwl, prefix);
+}
+
+void ossimMapProjectionFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimAlbersProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimAzimEquDistProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimBonneProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimBngProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimCassiniProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimCylEquAreaProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimEquDistCylProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimEckert4Projection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimEckert6Projection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimGnomonicProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimLambertConformalConicProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimLlxyProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimMercatorProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimMillerProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimMollweidProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimNewZealandMapGridProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimObliqueMercatorProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimOrthoGraphicProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimPolarStereoProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimPolyconicProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimSinusoidalProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimStereographicProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimTransCylEquAreaProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimTransMercatorProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimUpsProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimUtmProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimVanDerGrintenProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimSpaceObliqueMercatorProjection)));
+}
+
+list<ossimString> ossimMapProjectionFactory::getList()const
+{
+   list<ossimString> result;
+
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimAlbersProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimAzimEquDistProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimBonneProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimBngProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimCassiniProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimCylEquAreaProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimEquDistCylProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimEckert4Projection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimEckert6Projection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimGnomonicProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimLambertConformalConicProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimLlxyProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimMercatorProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimMillerProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimMollweidProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimNewZealandMapGridProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimObliqueMercatorProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimOrthoGraphicProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimPolarStereoProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimPolyconicProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimSinusoidalProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimStereographicProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimTransCylEquAreaProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimTransMercatorProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimUpsProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimUtmProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimVanDerGrintenProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimSpaceObliqueMercatorProjection)));
+   
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimMapProjectionFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimMapProjectionFactory.h
new file mode 100644
index 0000000000..1584e0691f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimMapProjectionFactory.h
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  Garrett Potts
+//
+// Description:
+//
+// class ossimProjectionFactory maintains a static list of projection
+// makers.  If a user wants to create a projection they can pass in
+// a projection name and a datum if desired.  Currently the default
+// datum will be WGS84.
+//*******************************************************************
+//  $Id: ossimMapProjectionFactory.h,v 1.7 2004/09/24 17:19:40 dburken Exp $
+
+#ifndef ossimMapProjectionFactory_HEADER
+#define ossimMapProjectionFactory_HEADER
+
+#include "ossimProjectionFactoryBase.h"
+
+class ossimProjection;
+class ossimString;
+
+class OSSIMDLLEXPORT ossimMapProjectionFactory : public ossimProjectionFactoryBase
+{
+public:
+   /*!
+    * METHOD: instance()
+    * Instantiates singleton instance of this class:
+    */
+   static ossimMapProjectionFactory* instance();
+
+   virtual ossimProjection* createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const;
+   /*!
+    * METHOD: create()
+    * Attempts to create an instance of the projection specified by name.
+    * Returns successfully constructed projection or NULL.
+    */
+   virtual ossimProjection* createProjection(const ossimString& name)const;
+   virtual ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                             const char* prefix = 0)const;
+
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /*!
+    * METHOD: getList()
+    * Returns list of all projections represented by this factory:
+    */
+   virtual list<ossimString> getList()const;
+
+protected:
+   ossimMapProjectionFactory() {}
+   static ossimMapProjectionFactory*  theInstance;
+ 
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimMiscProjectionFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimMiscProjectionFactory.cpp
new file mode 100644
index 0000000000..5926e8280b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimMiscProjectionFactory.cpp
@@ -0,0 +1,190 @@
+//*****************************************************************************
+// FILE: ossimMiscProjectionFactory.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimMiscProjectionFactory
+//
+// SOFTWARE HISTORY:
+//>
+//   15Jun2001  Garrett Potts
+//              Initial coding.
+//<
+//*****************************************************************************
+//  $Id: ossimMiscProjectionFactory.cpp,v 1.8 2004/10/04 18:57:11 gpotts Exp $
+
+#include <projections/factory/ossimMiscProjectionFactory.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/common/ossimKeywordNames.h>
+
+//***
+// Note to programmer: To add a new projection, search this file for
+// "ADD_PROJECTION" to locate places requiring editing. Functional example
+// below...
+//
+// ADD_PROJECTION: Include all map projection headers here:
+//***
+
+#include <projections/ossimAffineProjection.h>
+#include <projections/ossimBilinearProjection.h>
+#include <projections/ossimQuadProjection.h>
+#include <projections/ossimWarpProjection.h>
+#include <projections/ossimRpcProjection.h>
+
+//***
+// ADD_PROJECTION: List names of all map projections produced by this factory:
+//***
+
+ossimMiscProjectionFactory* ossimMiscProjectionFactory::theInstance = 0;
+
+//*****************************************************************************
+//  STATIC METHOD: ossimMiscProjectionFactory::instance()
+//  
+//*****************************************************************************
+ossimMiscProjectionFactory* ossimMiscProjectionFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimMiscProjectionFactory;
+   }
+
+   return (ossimMiscProjectionFactory*) theInstance;
+}
+
+ossimProjection*
+ossimMiscProjectionFactory::createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx) const
+{
+   // Check for external geometry file.
+   return createProjectionFromGeometryFile(filename, entryIdx);
+}
+
+//*****************************************************************************
+//  METHOD: ossimMiscProjectionFactory::createProjection(kwl, prefix)
+//  
+//*****************************************************************************
+ossimProjection*
+ossimMiscProjectionFactory::createProjection(const ossimKeywordlist &kwl,
+                                             const char *prefix) const
+{
+   ossimProjection *result=NULL;
+   
+   const char *lookup = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+
+   if(lookup)
+   {
+      result = createProjection(ossimString(lookup).trim());
+      if(result)
+      {
+         result->loadState(kwl, prefix);
+      }
+   }
+   else
+   {
+      // look for the geom_file keyword.
+      //
+      lookup = kwl.find(prefix, "geom_file");
+      if(lookup)
+      {
+         ossimKeywordlist kwl2;
+
+         kwl2.addFile(lookup);
+
+         result = createProjection(kwl2, "projection.");
+         // maybe they did not prepend projection. in the pro
+         // file.
+         if(!result)
+         {
+            result = createProjection(kwl2);
+         }
+
+      }      
+   }
+   return result;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMiscProjectionFactory::createProjection(projection_name)
+//  
+//*****************************************************************************
+ossimProjection*
+ossimMiscProjectionFactory::createProjection(const ossimString &name) const
+{
+   //***
+   // ADD_PROJECTION: Test for each map projection here:
+   //***
+   if(name == STATIC_TYPE_NAME(ossimAffineProjection))
+   {
+      return new ossimAffineProjection;
+   }
+   if(name == STATIC_TYPE_NAME(ossimBilinearProjection))
+   {
+      return new ossimBilinearProjection;
+   }
+   if(name == STATIC_TYPE_NAME(ossimQuadProjection))
+   {
+      return new ossimQuadProjection;
+   }
+   if(name == STATIC_TYPE_NAME(ossimRpcProjection))
+   {
+      return new ossimRpcProjection;
+   }
+   if(name == STATIC_TYPE_NAME(ossimWarpProjection))
+   {
+      return new ossimWarpProjection;
+   }
+   return NULL;
+}
+
+//*****************************************************************************
+//  METHOD 
+//*****************************************************************************
+ossimObject*
+ossimMiscProjectionFactory::createObject(const ossimString& typeName)const
+{
+   return createProjection(typeName);
+}
+
+//*****************************************************************************
+//  METHOD 
+//*****************************************************************************
+ossimObject*
+ossimMiscProjectionFactory::createObject(const ossimKeywordlist& kwl,
+                                                     const char* prefix)const
+{
+   return createProjection(kwl, prefix);
+}
+
+//*****************************************************************************
+//  METHOD 
+//*****************************************************************************
+void ossimMiscProjectionFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimAffineProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimBilinearProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimRpcProjection)));
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimQuadProjection)));   
+   typeList.push_back(ossimString(STATIC_TYPE_NAME(ossimWarpProjection)));
+}
+
+//*****************************************************************************
+//  METHOD 
+//*****************************************************************************
+list<ossimString> ossimMiscProjectionFactory::getList()const
+{
+   list<ossimString> result;
+
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimAffineProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimBilinearProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimRpcProjection)));
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimQuadProjection)));   
+   result.push_back(ossimString(STATIC_TYPE_NAME(ossimWarpProjection)));
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimMiscProjectionFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimMiscProjectionFactory.h
new file mode 100644
index 0000000000..7529ef7339
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimMiscProjectionFactory.h
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// class ossimProjectionFactory maintains a static list of projection
+// makers.  If a user wants to create a projection they can pass in
+// a projection name and a datum if desired.  Currently the default
+// datum will be WGS84.
+//*******************************************************************
+//  $Id: ossimMiscProjectionFactory.h,v 1.4 2004/09/24 17:19:40 dburken Exp $
+
+#ifndef ossimMiscProjectionFactory_HEADER
+#define ossimMiscProjectionFactory_HEADER
+
+#include "ossimProjectionFactoryBase.h"
+
+class ossimProjection;
+class ossimString;
+
+class ossimMiscProjectionFactory : public ossimProjectionFactoryBase
+{
+public:
+   /*!
+    * METHOD: instance()
+    * Instantiates singleton instance of this class:
+    */
+   static ossimMiscProjectionFactory* instance();
+
+   /*!
+    * METHOD: create()
+    * Attempts to create an instance of the projection specified by name.
+    * Returns successfully constructed projection or NULL.
+    */
+   virtual ossimProjection* createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const;
+   virtual ossimProjection* createProjection(const ossimString& name)const;
+   virtual ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                             const char* prefix = 0)const;
+
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /*!
+    * METHOD: getList()
+    * Returns list of all projections represented by this factory:
+    */
+   virtual list<ossimString> getList()const;
+
+protected:
+   ossimMiscProjectionFactory() {}
+   static ossimMiscProjectionFactory*  theInstance;
+ 
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimNitfProjectionFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimNitfProjectionFactory.cpp
new file mode 100644
index 0000000000..d058e1f87f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimNitfProjectionFactory.cpp
@@ -0,0 +1,874 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2004 Intelligence Data Systems, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Matt Revelle
+//          David Burken
+//
+// Description:
+//
+// Contains class definition for ossimNitfProjectionFactory.
+//
+// $Id: ossimNitfProjectionFactory.cpp,v 1.18 2005/10/16 22:59:03 dburken Exp $
+//----------------------------------------------------------------------------
+
+#include <fstream>
+#include <cmath>
+
+#include <projections/factory/ossimNitfProjectionFactory.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <projections/map_projections/ossimLlxyProjection.h>
+#include <projections/ossimBilinearProjection.h>
+#include <support_data/nitf/ossimNitfFile.h>
+#include <support_data/nitf/ossimNitfFileHeader.h>
+#include <support_data/nitf/ossimNitfImageHeader.h>
+#include <support_data/nitf/ossimNitfBlockaTag.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimDms.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <projections/ossimProjection.h>
+#include <projections/sensor_modeling/rpc/ossimIkonosRpcModel.h>
+#include <projections/sensor_modeling/rpc/ossimNitfRpcModel.h>
+#include <projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.h>
+#include <support_data/nitf/ossimNitfFile.h>
+#include <support_data/nitf/ossimNitfImageHeader.h>
+
+
+//---
+// Define Trace flags for use within this file:
+//---
+#include <base/common/ossimTrace.h>
+static ossimTrace traceDebug = ossimTrace("ossimNitfProjectionFactory:debug");
+
+ossimNitfProjectionFactory* ossimNitfProjectionFactory::theInstance = NULL;
+
+ossimNitfProjectionFactory::ossimNitfProjectionFactory()
+{
+}
+
+ossimNitfProjectionFactory::~ossimNitfProjectionFactory()
+{
+}
+
+ossimNitfProjectionFactory* ossimNitfProjectionFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimNitfProjectionFactory();
+   }
+
+   return theInstance;
+}
+
+ossimProjection*
+ossimNitfProjectionFactory::createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const
+{
+   static const char MODULE[]="ossimNitfProjectionFactory::createProjection";
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " DEBUG:"
+         << "\nfilename:  " << filename
+         << "\nentryIdx:  " << entryIdx
+         << std::endl;
+   }
+
+   // See if there is an external geomtry.
+   ossimProjection* result = createProjectionFromGeometryFile(filename,
+                                                              entryIdx);
+   if (result)
+   {
+      return result;
+   }
+
+   if(!isNitf(filename))
+   {
+      return result; // result is NULL
+   }
+
+   ossimNitfFile* nitf = new ossimNitfFile();
+   if (!nitf->parseFile(filename))
+   {
+      delete nitf;
+      nitf = NULL;
+      return result; // result is NULL
+   }
+
+   long imageIndex = static_cast<long>(entryIdx);
+   if ( imageIndex > (nitf->getHeader()->getNumberOfImages()-1) )
+   {
+      return result;
+   }
+
+   ossimNitfImageHeader* imageHeader = nitf->getNewImageHeader(imageIndex);
+   {
+      if (!imageHeader)
+      {
+         return result;
+      }
+   }
+
+   ossimString coordinateSystem   = imageHeader->getCoordinateSystem();
+   
+   if (coordinateSystem == "G" || coordinateSystem == "D")
+   {
+      result = makeGeographic(imageHeader, coordinateSystem, filename);
+   }
+   else if(coordinateSystem == "N" || coordinateSystem == "S")
+   {
+      result = makeUtm(imageHeader, coordinateSystem, filename);
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " DEBUG:"
+         << "\ncoordinateSysetm:       " << coordinateSystem
+         << std::endl;
+   }
+
+   return result;
+}
+
+
+ossimProjection*
+ossimNitfProjectionFactory::createProjection(const ossimKeywordlist& kwl,
+                                             const char *prefix) const
+{
+   return NULL;
+}
+
+ossimProjection*
+ossimNitfProjectionFactory::createProjection(const ossimString &name) const
+{
+   return NULL;
+}
+
+ossimObject*
+ossimNitfProjectionFactory::createObject(const ossimString& typeName)const
+{
+   return (ossimObject*)createProjection(typeName);
+}
+
+ossimObject*
+ossimNitfProjectionFactory::createObject(const ossimKeywordlist& kwl,
+                                         const char* prefix)const
+{
+   return createProjection(kwl, prefix);
+}
+
+void ossimNitfProjectionFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   
+}
+
+list<ossimString> ossimNitfProjectionFactory::getList()const
+{
+   list<ossimString> result;
+   return result;
+}
+
+bool ossimNitfProjectionFactory::isNitf(const ossimFilename& filename)const
+{
+   std::ifstream in(filename.c_str(), ios::in|ios::binary);
+   
+   if(in)
+   {
+      char nitfFile[4];
+      in.read((char*)nitfFile, 4);
+      ossimString s(nitfFile, nitfFile+4);
+      if ( (s == "NITF") || (s == "NSIF") )
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+ossimProjection* ossimNitfProjectionFactory::makeGeographic(
+   const ossimNitfImageHeader* hdr,
+   const ossimString& coordinateSysetm,
+   const ossimFilename& filename) const
+{
+   ossimProjection* proj = NULL;
+   if (!hdr)
+   {
+      return proj;
+   }
+
+   // To hold corner points.
+   std::vector<ossimGpt> gpts;
+
+   //---
+   // Get the corner points.
+   // 
+   // Look for points from the BLOCKA tag.  This may or may not be present.
+   // If present since it has six digit precision use it for the points.
+   //---
+   if ( getBlockaPoints(hdr, gpts, filename) == false )
+   {
+      ossimString geographicLocation = hdr->getGeographicLocation();
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfProjectionFactory::makeGeographic DEBUG:"
+            << "\ngeographicLocation: " << geographicLocation
+            << std::endl;
+      }
+      
+      if (coordinateSysetm == "G")
+      {
+         //---
+         // If coord system is G then format is:
+         // Lat = ddmmssX
+         //       where d is degrees and m is minutes
+         //       and s is seconds and X is either N (North) or S (South).
+         // Lon = dddmmssX
+         //       where d is degrees and m is minutes
+         //       and s is seconds and X is either N (North) or S (South).
+         //---
+         parseGeographicString(geographicLocation, gpts);
+      }
+      else if (coordinateSysetm == "D")
+      {
+         //---
+         // If coor system is D then format is:
+         // +-dd.ddd +-dd.ddd four times where + is northern hemispher and
+         // - is souther hemisphere for lat and longitude
+         // + is easting and - is westing.
+         //---
+         parseDecimalDegreesString(geographicLocation, gpts);
+      }
+   }
+
+   if (gpts.size() != 4)
+   {
+      return 0;
+   }
+   
+   if (!isSkewed(gpts))
+   {
+      proj = makeEuiDistant(hdr, gpts);
+   }
+   else
+   {
+      // Image is rotated.  Make a Bilinear.
+      proj = makeBilinear(hdr, gpts);
+   }
+
+   if (traceDebug() && proj)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfProjectionFactory::makeGeographic DEBUG:"
+         << "\nUpper left corner:   " << gpts[0]
+         << "\nUpper right corner:  " << gpts[1]
+         << "\nLower right corner:  " << gpts[2]
+         << "\nLower left corner:   " << gpts[3] << endl
+         << proj->print(ossimNotify(ossimNotifyLevel_DEBUG))
+         << std::endl;
+   }
+
+   return proj;
+}
+
+ossimProjection* ossimNitfProjectionFactory::makeUtm(
+   const ossimNitfImageHeader* hdr,
+   const ossimString& coordinateSystem,
+   const ossimFilename& filename) const
+{
+   ossimUtmProjection* proj = NULL;
+   if (!hdr)
+   {
+      return proj;
+   }
+
+   ossimString geographicLocation = hdr->getGeographicLocation();
+
+   std::vector<ossimDpt> utmPoints;
+   ossim_uint32 zone;
+   ossimDpt scale;
+   parseUtmString(geographicLocation,
+                  zone,
+                  utmPoints);
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfProjectionFactory::makeUtm DEBUG"
+         << "\ngeo string: " << geographicLocation
+         << std::endl;
+      for (ossim_uint32 i=0; i<utmPoints.size(); ++i)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "utmPoints[" << utmPoints[i] << std::endl;
+      }
+   }
+   
+   proj = new ossimUtmProjection;
+   if(coordinateSystem == "S")
+   {
+      proj->setHemisphere('S');
+   }
+   else
+   {
+      proj->setHemisphere('N');
+   }
+   proj->setZone(zone);
+
+   if(isSkewed(utmPoints))
+   {
+      std::vector<ossimGpt> gpts;
+
+      // Try blocka points first as they are more accurate.
+      if ( getBlockaPoints(hdr, gpts, filename) == false )
+      {
+         ossimGpt ul = proj->inverse(utmPoints[0]);
+         ossimGpt ur = proj->inverse(utmPoints[1]);
+         ossimGpt lr = proj->inverse(utmPoints[2]);
+         ossimGpt ll = proj->inverse(utmPoints[3]);
+         gpts.push_back(ul);
+         gpts.push_back(ur);
+         gpts.push_back(lr);
+         gpts.push_back(ll);
+      }
+      
+      delete proj;
+      proj = 0;
+      return makeBilinear(hdr, gpts);
+   }
+   else
+   {
+      computeScaleInMeters(hdr, utmPoints, scale);
+   }
+
+   ossimProjection* result = 0;
+   if(!scale.hasNans())
+   {
+      //---
+      // Get the tie point.
+      // 
+      // Look for the the BLOCKA tag which may or may not be present.
+      // This has six digit precision in decimal degrees which equates to
+      // about 0.11 meters (at equator) as compared to 1.0 accuaracy of the
+      // IGEOLO field.
+      //---
+      ossimDpt tie;
+      std::vector<ossimGpt> gpts;
+      if ( getBlockaPoints(hdr, gpts, filename) )
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "ossimNitfProjectionFactory::makeUtm DEBUG:"
+               << "\nTie point from blocka: " << gpts[0]
+               << endl;
+         }
+
+         tie = proj->forward(gpts[0]);
+         tie.x += scale.x/2.0;
+         tie.y -= scale.y/2.0;
+      }
+      else
+      {
+         tie.x = utmPoints[0].x + scale.x/2.0;
+         tie.y = utmPoints[0].y - scale.y/2.0;
+      }
+      
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfProjectionFactory::makeUtm DEBUG:"
+            << "\nTie point: " << tie
+            << "\nScale:     " << scale
+            << endl;
+      }
+      
+      proj->setUlEastingNorthing(tie);
+      proj->setMetersPerPixel(scale);
+      result = proj;
+   }
+   else
+   {
+      delete proj;
+      proj = 0;
+   }
+   return result;
+}
+
+ossimProjection* ossimNitfProjectionFactory::makeEuiDistant(
+   const ossimNitfImageHeader* hdr,
+   const std::vector<ossimGpt>& gpts) const
+{
+   ossimEquDistCylProjection* proj = NULL;
+
+   // Get the scale.
+   ossimDpt scale;
+   computeScaleInDecimalDegrees(hdr, gpts, scale);
+
+   if (scale.hasNans())
+   {
+      return proj;
+   }
+   
+   // Make the projection.
+   proj = new ossimEquDistCylProjection();
+
+   // Shift the tie to the center of the pixel.
+   ossimGpt tiePoint;
+   tiePoint.latd(gpts[0].latd() - (scale.y/2.0));
+   tiePoint.lond(gpts[0].lond() + (scale.x/2.0));
+
+   // Set the tie point...
+//    proj->setOrigin(tiePoint);
+   proj->setUlGpt(tiePoint);
+
+   // Set the scale
+   proj->setLatSpacing(scale.y);
+   proj->setLonSpacing(scale.x);
+
+   return proj;
+}
+
+ossimProjection* ossimNitfProjectionFactory::makeBilinear(
+   const ossimNitfImageHeader* hdr,
+   const std::vector<ossimGpt>& gpts) const
+{
+   double rows = hdr->getNumberOfRows();
+   double cols = hdr->getNumberOfCols();
+   
+   ossimDpt ul(0.0, 0.0);
+   ossimDpt ur(cols-1.0, 0.0);   
+   ossimDpt lr(cols-1.0, rows-1.0);
+   ossimDpt ll(0.0, rows-1.0);
+
+   return new ossimBilinearProjection(ul,
+                                      ur,
+                                      lr,
+                                      ll,
+                                      gpts[0],
+                                      gpts[1],
+                                      gpts[2],
+                                      gpts[3]);
+}
+
+bool ossimNitfProjectionFactory::isSkewed(
+   const std::vector<ossimGpt>& gpts) const
+{
+
+   return !( (gpts[0].latd() == gpts[1].latd()) &&
+             (gpts[2].latd() == gpts[3].latd()) &&
+             (gpts[0].lond() == gpts[3].lond()) &&
+             (gpts[1].lond() == gpts[2].lond()) );
+   
+}
+
+bool ossimNitfProjectionFactory::isSkewed(
+   const std::vector<ossimDpt>& dpts) const
+{
+   return !( (dpts[0].y == dpts[1].y) &&
+             (dpts[2].y == dpts[3].y) &&
+             (dpts[0].x == dpts[3].x) &&
+             (dpts[1].x == dpts[2].x) );
+   
+}
+
+bool ossimNitfProjectionFactory::getBlockaPoints(
+   const ossimNitfImageHeader* hdr,
+   std::vector<ossimGpt>& gpts,
+   const ossimFilename& filename) const
+{
+   if (!hdr)
+   {
+      return false;
+   }
+
+   ossimNitfTagInformation tagInfo;
+   ossimRefPtr<ossimNitfRegisteredTag> blockaTag;
+   
+   if (hdr->getTag(tagInfo, ossimString("BLOCKA")) == true)
+   {
+      blockaTag = tagInfo.getTagData();
+
+      if (!blockaTag) // Tag is there but it was not parsed.
+      {
+         blockaTag = new ossimNitfBlockaTag();
+         std::ifstream in(filename.c_str(), ios::in|ios::binary);
+         if(in)
+         {
+            // Seek to the start of tag data.
+            in.seekg(tagInfo.getTagDataOffset());
+            blockaTag->parseStream(in);
+            in.close();
+         }
+      }
+   }
+
+   if (!blockaTag)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfProjectionFactory::getBlockaPoints DEBUG:"
+            << "\nBLOCKA tag not found."
+            << std::endl;
+      }
+      return false;
+   }
+
+   if (gpts.size())
+   {
+      gpts.clear();
+   }
+
+   ossimNitfBlockaTag* tag = PTR_CAST(ossimNitfBlockaTag, blockaTag.get());
+   if (!tag)
+   {
+      return false;
+   }
+
+   ossimDpt dpt;
+   ossimGpt gpt;
+
+   // Get the upper left or first row first column.
+   tag->getFrfcLoc(dpt);
+   gpt.latd(dpt.y);
+   gpt.lond(dpt.x);
+   gpts.push_back(gpt);
+
+   // Get the upper right or first row last column.
+   tag->getFrlcLoc(dpt);
+   gpt.latd(dpt.y);
+   gpt.lond(dpt.x);
+   gpts.push_back(gpt);
+
+   // Get the lower right or last row last column.
+   tag->getLrlcLoc(dpt);
+   gpt.latd(dpt.y);
+   gpt.lond(dpt.x);
+   gpts.push_back(gpt);
+
+   // Get the lower left or last row first column.
+   tag->getLrfcLoc(dpt);
+   gpt.latd(dpt.y);
+   gpt.lond(dpt.x);
+   gpts.push_back(gpt);
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfProjectionFactory::getBlockaPoints DEBUG:"
+         << std::endl;
+      for (int i=0; i<4; ++i)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "gpt[" << i << "] " << gpts[i] << std::endl;
+      }
+   }
+   
+   return true;
+}
+
+void ossimNitfProjectionFactory::computeScaleInDecimalDegrees(
+   const ossimNitfImageHeader* hdr,
+   const std::vector<ossimGpt>& gpts,
+   ossimDpt& scale) const
+{
+   if ( !hdr || isSkewed(gpts))
+   {
+      scale.makeNan();
+      return;
+   }
+   ossimIrect imageRect = hdr->getImageRect();
+
+   //---
+   // Calculate the scale.  This assumes that the corner points are for the
+   // edge of the corner pixels, not the center of the corner pixels.
+   //---
+   double longitudeSize  = 0.0;
+   double latitudeSize = 0.0;
+   if ( (gpts[1].lond() < 0.0) && (gpts[0].lond() >= 0) )
+   {
+      //---
+      // Upper right negative(Western), upper left positive (Eastern).
+      // Crossing date line maybe???
+      //---
+      longitudeSize = (gpts[1].lond() + 360.0) - gpts[0].lond();
+   }
+   else
+   {
+      longitudeSize = gpts[1].lond() - gpts[0].lond();
+   }
+
+   latitudeSize = gpts[0].latd() - gpts[2].latd();
+
+   double rows = imageRect.height();
+   double cols = imageRect.width();
+//   double rows = hdr->getNumberOfRows();
+//   double cols = hdr->getNumberOfCols();
+       
+   if (!rows || !cols)
+   {
+      scale.makeNan();
+      return;
+   }
+   scale.y = latitudeSize  / rows;
+   scale.x = longitudeSize / cols;
+}
+
+void ossimNitfProjectionFactory::computeScaleInMeters(
+   const ossimNitfImageHeader* hdr,
+   const std::vector<ossimDpt>& dpts,
+   ossimDpt& scale) const
+{
+   if ( !hdr || isSkewed(dpts))
+   {
+      scale.makeNan();
+      return;
+   }
+   ossimIrect imageRect = hdr->getImageRect();
+
+   //---
+   // Calculate the scale.  This assumes that the corner points are for the
+   // edge of the corner pixels, not the center of the corner pixels.
+   //---
+   double eastingSize  = 0.0;
+   double northingSize = 0.0;
+   
+   eastingSize  = fabs(dpts[1].x - dpts[0].x);
+   northingSize = fabs(dpts[0].y - dpts[3].y);
+
+   double rows = imageRect.height();//hdr->getNumberOfRows();
+   double cols = imageRect.width();//hdr->getNumberOfCols();
+
+   if (!rows || !cols)
+   {
+      scale.makeNan();
+      return;
+   }
+   scale.y = northingSize / rows;
+   scale.x = eastingSize  / cols;
+}
+
+void ossimNitfProjectionFactory::parseUtmString(const ossimString& utmLocation,
+                                                ossim_uint32& zone,
+                                                std::vector<ossimDpt>& utmPoints)const
+{
+   ossim_uint32 idx = 0;
+   ossimString z;
+   ossimString east;
+   ossimString north;
+
+   
+   z    = ossimString(utmLocation.begin() + idx,
+                   utmLocation.begin() + idx + 2);
+   idx += 2;
+   east = ossimString(utmLocation.begin() + idx,
+                      utmLocation.begin() + idx + 6);
+   idx += 6;
+   north = ossimString(utmLocation.begin() + idx,
+                       utmLocation.begin() + idx + 7);
+   idx += 7;
+
+   utmPoints.push_back(ossimDpt(east.toDouble(),
+                                north.toDouble()));
+   
+   z    = ossimString(utmLocation.begin() + idx,
+                   utmLocation.begin() + idx + 2);
+   idx += 2;
+   east = ossimString(utmLocation.begin() + idx,
+                      utmLocation.begin() + idx + 6);
+   idx += 6;
+   north = ossimString(utmLocation.begin() + idx,
+                       utmLocation.begin() + idx + 7);
+   idx += 7;
+   utmPoints.push_back(ossimDpt(east.toDouble(),
+                                north.toDouble()));
+
+   z    = ossimString(utmLocation.begin() + idx,
+                   utmLocation.begin() + idx + 2);
+   idx += 2;
+   east = ossimString(utmLocation.begin() + idx,
+                      utmLocation.begin() + idx + 6);
+   idx += 6;
+   north = ossimString(utmLocation.begin() + idx,
+                       utmLocation.begin() + idx + 7);
+   idx += 7;
+   utmPoints.push_back(ossimDpt(east.toDouble(),
+                                north.toDouble()));
+
+   z    = ossimString(utmLocation.begin() + idx,
+                   utmLocation.begin() + idx + 2);
+   idx += 2;
+   east = ossimString(utmLocation.begin() + idx,
+                      utmLocation.begin() + idx + 6);
+   idx += 6;
+   north = ossimString(utmLocation.begin() + idx,
+                       utmLocation.begin() + idx + 7);
+   idx += 7;
+   utmPoints.push_back(ossimDpt(east.toDouble(),
+                                north.toDouble()));
+
+   zone = z.toUInt32();
+}
+
+
+void ossimNitfProjectionFactory::parseGeographicString(
+   const ossimString& geographicLocation, std::vector<ossimGpt>& gpts) const
+{
+   gpts.clear();
+   
+   if (geographicLocation.size() != 60)
+   {
+      return;
+   }
+
+   int geo_index = 0;
+   for (int i=0; i<4; ++i)
+   {
+      //---
+      // We have to split up the geographicLocation string for the dms class.
+      // 
+      // geographicLocation = ddmmssXdddmmssX (four times).
+      // "dd mm ss X" has a string length of 10
+      // "ddd mm ss X" has a string length of 11
+      //---
+      int lat_index = 0;
+      int lon_index = 0;
+      const char SPACE = ' ';
+      ossimString latString(10, SPACE);
+      ossimString lonString(11, SPACE);
+
+      // degrees latitude
+      latString[lat_index++] = geographicLocation[geo_index++];
+      latString[lat_index++] = geographicLocation[geo_index++];
+      ++lat_index;
+
+      // minutes latitude
+      latString[lat_index++] = geographicLocation[geo_index++];
+      latString[lat_index++] = geographicLocation[geo_index++];
+      ++lat_index;
+      
+      // seconds latitude
+      latString[lat_index++] = geographicLocation[geo_index++];
+      latString[lat_index++] = geographicLocation[geo_index++];
+      ++lat_index;
+
+      // hemisphere
+      latString[lat_index++] = geographicLocation[geo_index++];
+ 
+      // degrees longitude
+      lonString[lon_index++] = geographicLocation[geo_index++];
+      lonString[lon_index++] = geographicLocation[geo_index++];
+      lonString[lon_index++] = geographicLocation[geo_index++];
+      ++lon_index;
+
+      // minutes longitude
+      lonString[lon_index++] = geographicLocation[geo_index++];
+      lonString[lon_index++] = geographicLocation[geo_index++];
+      ++lon_index;
+
+      // seconds longitude
+      lonString[lon_index++] = geographicLocation[geo_index++];
+      lonString[lon_index++] = geographicLocation[geo_index++];
+      ++lon_index;
+
+      // hemisphere
+      lonString[lon_index++] = geographicLocation[geo_index++];
+
+      // Convert to decimal degrees using the dms class.
+      ossimGpt gpt;
+      ossimDms dms(0.0);
+      dms.setLatFlag(true);
+      if ( ! dms.setDegrees(latString.c_str()) )
+      {
+         gpts.clear();
+         return;
+      }
+      gpt.latd(dms.getDegrees());
+
+      dms.setLatFlag(false);
+      if ( ! dms.setDegrees(lonString.c_str()) )
+      {
+         gpts.clear();
+         return;
+      }
+      gpt.lond(dms.getDegrees());
+
+      gpts.push_back(gpt);
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfProjectionFactory::parseGeographicString DEBUG:"
+            << "\nground point[" << i << "]:  " << gpt
+            << std::endl;
+      }
+   }
+}
+
+void ossimNitfProjectionFactory::parseDecimalDegreesString(const ossimString& geographicLocation,
+                                                           std::vector<ossimGpt>& gpts) const
+{
+   const char* bufPtr = geographicLocation.c_str();
+
+   
+   ossimString ulLat(bufPtr,
+                     bufPtr + 7);
+   bufPtr+=7;
+   ossimString ulLon(bufPtr,
+                     bufPtr+8);
+   bufPtr+=8;
+   ossimString urLat(bufPtr,
+                     bufPtr + 7);
+   bufPtr+=7;
+   ossimString urLon(bufPtr,
+                     bufPtr+8);
+   bufPtr+=8;
+   ossimString lrLat(bufPtr,
+                     bufPtr + 7);
+   bufPtr+=7;
+   ossimString lrLon(bufPtr,
+                     bufPtr+8);
+   bufPtr+=8;
+   ossimString llLat(bufPtr,
+                     bufPtr + 7);
+   bufPtr+=7;
+   ossimString llLon(bufPtr,
+                     bufPtr+8);
+
+   gpts.push_back(ossimGpt(ulLat.toDouble(), ulLon.toDouble()));
+   gpts.push_back(ossimGpt(urLat.toDouble(), urLon.toDouble()));
+   gpts.push_back(ossimGpt(lrLat.toDouble(), lrLon.toDouble()));
+   gpts.push_back(ossimGpt(llLat.toDouble(), llLon.toDouble()));
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfProjectionFactory::parseDecimalDegreesString DEBUG:"
+         << "\nground point[" << 0 << "]:  " << gpts[0]
+         << "\nground point[" << 1 << "]:  " << gpts[1]
+         << "\nground point[" << 2 << "]:  " << gpts[2]
+         << "\nground point[" << 3 << "]:  " << gpts[3]
+         << std::endl;
+   }
+}
+
+ossimNitfProjectionFactory::ossimNitfProjectionFactory(const ossimNitfProjectionFactory&)
+{
+}
+
+ossimNitfProjectionFactory& ossimNitfProjectionFactory::operator=(const ossimNitfProjectionFactory&)
+{
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimNitfProjectionFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimNitfProjectionFactory.h
new file mode 100644
index 0000000000..10361cf2ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimNitfProjectionFactory.h
@@ -0,0 +1,253 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2004 Intelligence Data Systems, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Matt Revelle
+//          David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimNitfProjectionFactory.
+//
+// $Id: ossimNitfProjectionFactory.h,v 1.8 2005/10/16 22:02:09 dburken Exp $
+//----------------------------------------------------------------------------
+#ifndef ossimNitfProjectionFactory_HEADER
+#define ossimNitfProjectionFactory_HEADER
+
+#include <vector>
+#include <projections/factory/ossimProjectionFactoryBase.h>
+
+class ossimProjection;
+class ossimString;
+class ossimGpt;
+class ossimNitfImageHeader;
+class ossimDpt;
+
+class OSSIMDLLEXPORT ossimNitfProjectionFactory : public ossimProjectionFactoryBase
+{
+public:
+
+   /**
+    * METHOD: instance()
+    *
+    * @return  Singleton instance of this class.
+    */
+   static ossimNitfProjectionFactory* instance();
+
+   /**
+    * destructor
+    */
+   virtual ~ossimNitfProjectionFactory();
+
+   /**
+    * @param filename This filename can be an image file or
+    * it can also be a ossim .geom file.  It could be other
+    * forms of geom files as well.  The factories job will be to
+    * determine what parser to use and return a projection if
+    * successful.
+    *
+    * @return ossimProjection* on success or NULL if not handled.
+    */
+   virtual ossimProjection* createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const;
+   
+   /**
+    * @param name This would be a projection name.
+    *
+    * @return ossimProjection* on success or NULL if not handled.
+    */
+   virtual ossimProjection* createProjection(const ossimString& name)const;
+
+   
+   /**
+    * @param kwl  Keyword list to instantiate projection from.
+    *
+    * @return ossimProjection* on success or NULL if not handled.
+    */
+   virtual ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                             const char* prefix = 0)const;
+   /**
+    * Creates an object given a type name.
+    *
+    * @return ossimObject on success or NULL if not handled.
+    */
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /**
+    * Creates and object given a keyword list.
+    *
+    * @return ossimObject on success or NULL if not handled.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /**
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    *
+    * @param typeList List to append names to.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /**
+    * @note  Being depricated with getTypeNameList found in ossimObjectFactory
+    */
+   virtual list<ossimString> getList()const;
+
+private:
+   /**
+    * @param hdr The nitf image header.
+    *
+    * @param coordianteSystem The coordinate system as a string.
+    *
+    * @param geographicLocation This should contain the four corner strings.
+    *
+    * @param filename The nitf file name.
+    * 
+    * @return Either an  ossimEquDistCylProjection or ossimBilinearProjection
+    * depending upon if the corner points line up evenly.
+    */
+   ossimProjection* makeGeographic(const ossimNitfImageHeader* hdr,
+                                   const ossimString& coordinateSysetm,
+                                   const ossimFilename& filename) const;
+
+   /**
+    * @param hdr The nitf image header.
+    *
+    * @param coordianteSystem The coordinate system as a string.
+    *
+    * @param geographicLocation This should contain the four corner strings.
+    *
+    * @param filename The nitf file name.
+    * 
+    * @return ossimUtmProjection
+    */
+   ossimProjection* makeUtm(const ossimNitfImageHeader* hdr,
+                            const ossimString& coordinateSysetm,
+                            const ossimFilename& filename) const;
+   
+   /**
+    * @param hdr The nitf image header.
+    *
+    * @param gpts Four geographic corner points.
+    * 
+    * @return ossimEquDistCylProjection* or null if a problem is found.
+    */
+   ossimProjection* makeEuiDistant(const ossimNitfImageHeader* hdr,
+                                   const std::vector<ossimGpt>& gpts) const;
+   
+   /**
+    * @return ossimBilinearProjection* or null if a problem is found.
+    */
+   ossimProjection* makeBilinear(const ossimNitfImageHeader* hdr,
+                                 const std::vector<ossimGpt>& gpts) const;
+
+   /**
+    * Parses geographic stream.  This will initialize the vector of ossimGpt's
+    * with the four corners.  If the string geographicLocation is not the
+    * correct size the vector will be cleared.
+    *
+    * @param geographicLocation String containing corners.
+    *
+    * @param gpts Vector to initialize.
+    */
+   void parseGeographicString(const ossimString& geographicLocation,
+                              std::vector<ossimGpt>& gpts) const;
+
+   /**
+    * Parses Decimal degree stream.  This will initialize the vector of ossimGpt's
+    * with the four corners.  If the string geographicLocation is not the
+    * correct size the vector will be cleared.
+    *
+    * @param geographicLocation String containing corners.
+    *
+    * @param gpts Vector to initialize.
+    */
+   void parseDecimalDegreesString(const ossimString& geographicLocation,
+                                  std::vector<ossimGpt>& gpts) const;
+
+   void parseUtmString(const ossimString& utmLocation,
+                       ossim_uint32& zone,
+                       std::vector<ossimDpt>& utmPoints)const;
+   /**
+    * Computes the scale in decimal degrees with scale.x being longitude,
+    * y being latitude.
+    *
+    * @param hdr The nitf image header from the currently opened nitf file.
+    *
+    * @param gpts Four geographic corner points.
+    *
+    * @param scale Scale to initialize.
+    *
+    * @note scale will be set to nan's on failure.
+    */
+   void computeScaleInDecimalDegrees(const ossimNitfImageHeader* hdr,
+                                     const std::vector<ossimGpt>& gpts,
+                                     ossimDpt& scale) const;
+
+   /**
+    * Computes the scale in meters with scale.x being easting,
+    * y being northing.
+    *
+    * @param hdr The nitf image header from the currently opened nitf file.
+    *
+    * @param dpts Four utm corner points.
+    *
+    * @param scale Scale to initialize.
+    *
+    * @note scale will be set to nan's on failure.
+    */
+   void ossimNitfProjectionFactory::computeScaleInMeters(
+      const ossimNitfImageHeader* hdr,
+      const std::vector<ossimDpt>& dpts,
+      ossimDpt& scale) const;
+      
+   /**
+    * @return true if corner points are parallel to each other, else false.
+    */
+   bool isSkewed(const std::vector<ossimGpt>& gpts) const;
+
+   /**
+    * @return true if corner points are parallel to each other, else false.
+    */
+   bool isSkewed(const std::vector<ossimDpt>& gpts) const;
+
+   /**
+    * @param hdr The nitf image header from the currently opened nitf file.
+    * 
+    * @param gpts Ground points to initialize from BLOCKA tag.  This should
+    * be an empty vector.
+    *
+    * @param filename The nitf file name.
+    * 
+    * @return true if BLOCKA tag was parsed.
+    */
+   bool getBlockaPoints(const ossimNitfImageHeader* hdr,
+                        std::vector<ossimGpt>& gpts,
+                        const ossimFilename& filename) const;
+   
+   /**
+    * Private constructor, users must go through instance() method.
+    */
+   ossimNitfProjectionFactory();
+
+   /**
+    * Private copy constructor to hide from use.
+    */
+   ossimNitfProjectionFactory(const ossimNitfProjectionFactory& obj);
+
+   /**
+    * Private operator = to hide from use.
+    */
+   ossimNitfProjectionFactory& operator=(const ossimNitfProjectionFactory& rhs);
+   
+   static ossimNitfProjectionFactory*  theInstance;
+
+   bool isNitf(const ossimFilename& filename)const;
+};
+
+#endif /* End of "#ifndef ossimNitfProjectionFactory_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimPcsCodeProjectionFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimPcsCodeProjectionFactory.cpp
new file mode 100644
index 0000000000..6b352caafb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimPcsCodeProjectionFactory.cpp
@@ -0,0 +1,327 @@
+//----------------------------------------------------------------------------
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  David Burken
+//
+// Description:
+//
+// Class definition of projection factory to return projection from
+// a Projection Coordinate System (PCS) code.
+//
+// For current documentation on pcs codes see:
+// 
+// http://www.remotesensing.org/geotiff/spec/geotiff6.html#6.3.3.1
+// 
+//----------------------------------------------------------------------------
+//  $Id: ossimPcsCodeProjectionFactory.cpp,v 1.1 2005/11/25 20:30:48 dburken Exp $
+
+#include <projections/factory/ossimPcsCodeProjectionFactory.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+
+
+static const ossimTrace
+traceDebug(ossimString("ossimPcsCodeProjectionFactory:debug"));
+
+#if OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimPcsCodeProjectionFactory.cpp,v 1.1 2005/11/25 20:30:48 dburken Exp $";
+#endif
+
+ossimPcsCodeProjectionFactory* ossimPcsCodeProjectionFactory::theInstance = 0;
+
+ossimPcsCodeProjectionFactory::ossimPcsCodeProjectionFactory()
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimPcsCodeProjectionFactory::ossimPcsCodeProjectionFactory"
+         << " entered..." << std::endl;
+#if OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "OSSIM_ID:  " << OSSIM_ID << std::endl;
+#endif
+   }
+}
+
+ossimPcsCodeProjectionFactory* ossimPcsCodeProjectionFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimPcsCodeProjectionFactory;
+   }
+
+   return (ossimPcsCodeProjectionFactory*) theInstance;
+}
+
+ossimProjection*
+ossimPcsCodeProjectionFactory::createProjection(const ossimFilename& filename,
+                                                ossim_uint32 entryIdx)const
+{
+   if(!filename.exists())
+   {
+      return NULL;
+   }
+
+   // Check for external geometry file.
+   ossimProjection* proj = createProjectionFromGeometryFile(filename,
+                                                            entryIdx);
+   if (proj)
+   {
+      return proj;
+   }
+
+   ossimFilename geomFile = filename;
+   geomFile = geomFile.setExtension("geom");
+   if(!geomFile.exists())
+   {
+      return NULL;
+   }
+   
+   ossimKeywordlist kwl;
+   if(kwl.addFile(geomFile))
+   {
+      return createProjection(kwl);
+   }
+
+   return NULL;
+}
+
+ossimProjection* ossimPcsCodeProjectionFactory::createProjection(
+   const ossimKeywordlist &keywordList, const char *prefix) const
+{
+   ossimProjection *result=NULL;
+	
+   const char *lookup = keywordList.find(prefix,
+                                         ossimKeywordNames::PCS_CODE_KW);
+   if(lookup)
+   {
+      result = createProjection(ossimString(lookup).trim());
+      if(result)
+      {
+         result->loadState(keywordList, prefix);
+      }
+   }
+   return result;
+}
+
+ossimProjection* ossimPcsCodeProjectionFactory::createProjection(
+   const ossimString &name) const
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimPcsCodeProjectionFactory::createProjection entered..."
+         << "\nname:  " << name << endl;
+   }
+   
+   ossimProjection* result = NULL;
+   
+   ossim_int32 code = name.toInt32();
+
+   //---
+   // Divide the code by 100. Then check for a known type.  If it is a
+   // utm projection the last two digits represent the zone.
+   //---
+   int type = code/100;
+   int zone = code%100;
+
+   switch (type)
+   {
+      case 322:
+      {
+         //---
+         // utm, WGS72 (WGD), northern hemisphere
+         // All 60 zones handled.
+         //---
+         if ( (zone > 0) && (zone < 61) )
+         {
+            ossimUtmProjection* proj =
+               new ossimUtmProjection(*(ossimDatumFactory::instance()->
+                                        wgs72()->ellipsoid()));
+            proj->setDatum(ossimDatumFactory::instance()->
+                           wgs72());
+            proj->setZone(zone);
+            proj->setHemisphere('N');
+            result = proj;
+            return result;
+         }
+         break;
+      }
+         
+      case 323:
+      {
+         //---
+         // utm, WGS72 (WGD), southern hemisphere
+         // All 60 zones handled.
+         //---
+         if ( (zone > 0) && (zone < 61) )
+         {
+            ossimUtmProjection* proj =
+               new ossimUtmProjection(*(ossimDatumFactory::instance()->
+                                        wgs72()->ellipsoid()));
+            proj->setDatum(ossimDatumFactory::instance()->
+                           wgs72());
+            proj->setZone(zone);
+            proj->setHemisphere('S');
+            result = proj;
+            return result;
+         }
+         break;
+      }
+      
+      case 326:
+      {
+         //---
+         // utm, WGS84 (WGE), northern hemisphere
+         // All 60 zones hadled.
+         //---
+         if ( (zone > 0) && (zone < 61) )
+         {
+            ossimUtmProjection* proj =
+               new ossimUtmProjection(*(ossimDatumFactory::instance()->
+                                        wgs84()->ellipsoid()));
+            proj->setDatum(ossimDatumFactory::instance()->
+                           wgs84());
+            proj->setZone(zone);
+            proj->setHemisphere('N');
+            result = proj;
+            return result;
+         }
+         break;
+      }
+      
+      case 327:
+      {
+         //---
+         // utm, WGS84 (WGE), southern hemisphere
+         // All 60 zones handled.
+         //---
+         if ( (zone > 0) && (zone < 61) )
+         {
+            ossimUtmProjection* proj =
+               new ossimUtmProjection(*(ossimDatumFactory::instance()->
+                                        wgs84()->ellipsoid()));
+            proj->setDatum(ossimDatumFactory::instance()->
+                           wgs84());
+            proj->setZone(zone);
+            proj->setHemisphere('S');
+            result = proj;
+            return result;
+         }
+         break;
+      }
+      
+      case 267:
+      {
+         //---
+         // utm, "NAS-C", northern hemisphere
+         // Only UTM NAD27 North zones 3 to 22 are in the 267xx range...
+         // 26729 through 26803 handled by state plane factory.
+         //---
+         if ( (code > 26702) && (code < 26723) )
+         {
+            ossimUtmProjection* proj =
+               new ossimUtmProjection(*(ossimDatumFactory::instance()->
+                                        create(ossimString("NAS-C"))->
+                                        ellipsoid()));
+            proj->setDatum(ossimDatumFactory::instance()->
+                           create(ossimString("NAS-C")));
+            proj->setZone(zone);
+            proj->setHemisphere('N');
+            result = proj;
+            return result;
+         }
+         break;
+      }
+         
+      case 269:
+      {
+         //---
+         // utm, "NAR-C", northern hemisphere
+         // Only UTM NAD83 North zones 3 to 23 are in the 269xx
+         // range...
+         // 26929 through 26998 handled by state plane factory.
+         //---
+         if ( (code > 26902) && (code < 26924) )
+         {
+            ossimUtmProjection* proj =
+               new ossimUtmProjection(*(ossimDatumFactory::instance()->
+                                        create(ossimString("NAR-C"))->
+                                        ellipsoid()));
+            proj->setDatum(ossimDatumFactory::instance()->
+                           create(ossimString("NAR-C")));
+            proj->setZone(zone);
+            proj->setHemisphere('N');
+            result = proj;
+            return result;
+         }
+         break;
+      }
+      
+      case 248:
+      {
+         //---
+         // Provisional S. American 1956
+         // 24818 through 24880
+         //---
+         if ( (code > 24817) && (code < 24881) )
+         {
+            ossimUtmProjection* proj =
+               new ossimUtmProjection(*(ossimDatumFactory::instance()->
+                                        create(ossimString("PRB-M"))->
+                                        ellipsoid()));
+            
+            proj->setDatum(ossimDatumFactory::instance()->
+                           create(ossimString("PRB-M")));
+            if (zone > 60)
+            {
+               proj->setZone(zone - 60);
+               proj->setHemisphere('S');
+            }
+            else
+            {
+               proj->setZone(zone);
+               proj->setHemisphere('N');
+            }
+            result = proj;
+            return result;
+         }
+         break;
+      }
+      
+   } // End of switch on code.
+
+   return result;
+}
+
+ossimObject* ossimPcsCodeProjectionFactory::createObject(
+   const ossimString& typeName)const
+{
+   return createProjection(typeName);
+}
+
+ossimObject* ossimPcsCodeProjectionFactory::createObject(
+   const ossimKeywordlist& kwl,
+   const char* prefix)const
+{
+   return createProjection(kwl, prefix);
+}
+
+void ossimPcsCodeProjectionFactory::getTypeNameList(
+   std::vector<ossimString>& /* typeList */)const
+{
+}
+
+list<ossimString> ossimPcsCodeProjectionFactory::getList()const
+{
+   list<ossimString> result;
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimPcsCodeProjectionFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimPcsCodeProjectionFactory.h
new file mode 100644
index 0000000000..46796e5d6d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimPcsCodeProjectionFactory.h
@@ -0,0 +1,84 @@
+//----------------------------------------------------------------------------
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  David Burken
+//
+// Description:
+//
+// Class declaration of projection factory to return projection from
+// a Projection Coordinate System (PCS) code.
+//
+// For current documentation on pcs codes see:
+// 
+// http://www.remotesensing.org/geotiff/spec/geotiff6.html#6.3.3.1
+// 
+//----------------------------------------------------------------------------
+//  $Id: ossimPcsCodeProjectionFactory.h,v 1.1 2005/11/25 20:30:48 dburken Exp $
+
+#ifndef ossimPcsCodeProjectionFactory_HEADER
+#define ossimPcsCodeProjectionFactory_HEADER
+
+#include <projections/factory/ossimProjectionFactoryBase.h>
+
+class ossimProjection;
+class ossimString;
+
+class OSSIMDLLEXPORT ossimPcsCodeProjectionFactory : public ossimProjectionFactoryBase
+{
+public:
+   /*!
+    * METHOD: instance()
+    * Instantiates singleton instance of this class:
+    */
+   static ossimPcsCodeProjectionFactory* instance();
+
+   virtual ossimProjection* createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const;
+   /*!
+    * METHOD: create()
+    * Attempts to create an instance of the projection specified by name.
+    * Returns successfully constructed projection or NULL.
+    */
+
+   /**
+    * Creates projection from a pcs code string.
+    *
+    * @return ossimProjection* or null if code is not handled.
+    */
+   virtual ossimProjection* createProjection(const ossimString& name)const;
+   
+   virtual ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                             const char* prefix = 0)const;
+
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /*!
+    * METHOD: getList()
+    * Returns list of all projections represented by this factory:
+    */
+   virtual list<ossimString> getList()const;
+
+protected:
+   ossimPcsCodeProjectionFactory();
+   
+   static ossimPcsCodeProjectionFactory*  theInstance;
+ 
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryBase.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryBase.cpp
new file mode 100644
index 0000000000..c3822258d6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryBase.cpp
@@ -0,0 +1,90 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//*******************************************************************
+//  $Id: ossimProjectionFactoryBase.cpp,v 1.3 2004/09/24 17:19:40 dburken Exp $
+
+#include <projections/factory/ossimProjectionFactoryBase.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/data_types/ossimFilename.h>
+
+//---
+// Define Trace flags for use within this file:
+//---
+#include <base/common/ossimTrace.h>
+static ossimTrace traceDebug = ossimTrace("ossimProjectionFactoryBase:debug");
+
+RTTI_DEF1(ossimProjectionFactoryBase, "ossimProjectionFactoryBase", ossimObjectFactory);
+
+ossimProjection* ossimProjectionFactoryBase::createProjectionFromGeometryFile(const ossimFilename& imageFile, ossim_uint32 entryIdx)const
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimProjectionFactoryBase::createProjectionFromGeometryFile "
+         << "DEBUG:"
+         << "\nimageFile:  " << imageFile
+         << "\nentryIdx:   " << entryIdx
+         << endl;
+   }
+
+   // Try to find a geometry file for imageFile.
+   
+   ossimFilename geomFile = imageFile;
+   if (entryIdx == 0)
+   {
+      geomFile.setExtension("geom");
+      if(geomFile.exists())
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "Found geometry file:  " << geomFile
+               << endl;
+         }
+
+         ossimKeywordlist kwl;
+         if(kwl.addFile(geomFile))
+         {
+            return ossimProjectionFactoryRegistry::instance()->
+               createProjection(kwl);
+         }
+      }
+   }
+
+   // Look for an indexed geometry file.
+   geomFile = imageFile.fileNoExtension();
+   geomFile += "_e";
+   geomFile += ossimString::toString(entryIdx);
+   geomFile.setExtension("geom");
+   if(geomFile.exists())
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Found geometry file:  " << geomFile
+            << endl;
+      }
+      
+      ossimKeywordlist kwl;
+      if(kwl.addFile(geomFile))
+      {
+         return ossimProjectionFactoryRegistry::instance()->
+            createProjection(kwl);
+      }
+   }   
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG:  No geometry file found.  Returning NULL..."
+         << endl;
+   }
+
+   return NULL;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryBase.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryBase.h
new file mode 100644
index 0000000000..07f9062939
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryBase.h
@@ -0,0 +1,78 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//*******************************************************************
+//  $Id: ossimProjectionFactoryBase.h,v 1.9 2005/10/28 14:01:03 gpotts Exp $
+#ifndef ossimProjectionFactoryBase_HEADER
+#define ossimProjectionFactoryBase_HEADER
+
+#include <list>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/factory/ossimObjectFactory.h>
+
+class ossimProjection;
+
+class OSSIM_DLL ossimProjectionFactoryBase : public ossimObjectFactory
+{
+public:
+   
+   /**
+    * takes a filename. This filename can be an image file or
+    * it can also be a ossim .geom file.  It could be other
+    * forms of geom files as well.  The factories job will be to
+    * determine what parser to use and return a projection if
+    * successful.
+    */
+   virtual ossimProjection* createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const=0;
+
+   /**
+    * Take a projection type name.
+    */
+   virtual ossimProjection* createProjection(const ossimString& name)const=0;
+
+   /**
+    * Take a keywordlist.
+    */
+   virtual ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                             const char* prefix)const=0;
+
+   /**
+    * Being depricated with getTypeNameList found in ossimObjectFactory
+    */
+   virtual std::list<ossimString> getList()const=0;
+
+protected:
+
+   /**
+    * This method takes the filename and tries to find an external ".geom"
+    * file.
+    *
+    * If the "entryIndx" is 0 and the "imageFile" is foo.ntf this will
+    * look for "foo.geom".  If that fails it will look for foo_e0.geom.
+    *
+    * If the "entryIndx" is 5 and the "imageFile" is foo.ntf this will
+    * look for foo_e5.geom.
+    *
+    * @param imageFile Image file that needs a projection.
+    *
+    * @param entryIdx For image files that support multiple images this is
+    * the zero base index to that image.  Images that don't support multiple
+    * indexes should just pass 0.
+    *
+    * @return An ossimProjection* on success or NULL on failure.
+    */
+   ossimProjection*
+   createProjectionFromGeometryFile(const ossimFilename& imageFile,
+                                    ossim_uint32 entryIdx)const;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryRegistry.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryRegistry.cpp
new file mode 100644
index 0000000000..3f368f0ca5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryRegistry.cpp
@@ -0,0 +1,199 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimProjectionFactoryRegistry.cpp,v 1.23 2005/11/25 20:31:35 dburken Exp $
+#include <algorithm>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/factory/ossimProjectionFactoryBase.h>
+#include <projections/factory/ossimSrsProjectionFactory.h>
+#include <projections/factory/ossimMapProjectionFactory.h>
+#include <projections/factory/ossimTiffProjectionFactory.h>
+#include <projections/factory/ossimNitfProjectionFactory.h>
+#include <projections/factory/ossimPcsCodeProjectionFactory.h>
+#include <projections/factory/ossimStatePlaneProjectionFactory.h>
+#include <projections/factory/ossimSensorModelFactory.h>
+#include <projections/factory/ossimMiscProjectionFactory.h>
+#include <projections/ossimProjection.h>
+#include <base/factory/ossimObjectFactoryRegistry.h>
+
+ossimProjectionFactoryRegistry* ossimProjectionFactoryRegistry::theInstance=NULL;
+
+ossimProjectionFactoryRegistry* ossimProjectionFactoryRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimProjectionFactoryRegistry;
+      theInstance->initializeDefaults();
+      ossimObjectFactoryRegistry::instance()->registerFactory(theInstance);
+   }
+
+   return theInstance;
+}
+
+ossimProjection*
+ossimProjectionFactoryRegistry::createProjection(const ossimFilename& name,
+                                                 ossim_uint32 entryIdx)const
+{
+   ossimProjection* result = NULL;
+   vector<ossimProjectionFactoryBase*>::const_iterator factory = theFactoryList.begin();
+
+   while( (factory != theFactoryList.end()) && !result )
+   {
+      if(*factory)
+      {
+         result = (*factory)->createProjection(name, entryIdx);
+      }
+      
+      ++factory;
+   }
+   
+   return result;
+}
+
+ossimProjection* ossimProjectionFactoryRegistry::createProjection(const ossimString& name)const
+{
+   ossimProjection* result = NULL;
+   vector<ossimProjectionFactoryBase*>::const_iterator factory = theFactoryList.begin();
+
+   while((factory != theFactoryList.end()&&!
+          result))
+   {
+      if(*factory)
+      {
+         result = (*factory)->createProjection(name);
+      }
+      
+      ++factory;
+   }
+   
+   return result;
+}
+
+ossimProjection* ossimProjectionFactoryRegistry::createProjection(
+   const ossimKeywordlist& kwl, const char* prefix)const
+{
+   ossimProjection* result = NULL;
+   vector<ossimProjectionFactoryBase*>::const_iterator factory = theFactoryList.begin();
+
+   while( (factory != theFactoryList.end()) && !result )
+   {
+      if(*factory)
+      {
+         result = (*factory)->createProjection(kwl, prefix);
+      }
+      
+      ++factory;
+   }
+   
+   return result;
+}
+
+bool ossimProjectionFactoryRegistry::registerFactory(ossimProjectionFactoryBase* factory)
+{
+   if(factory&&!findFactory(factory))
+   {
+      theFactoryList.push_back(factory);
+      return true;
+   }
+
+   return false;
+}
+
+void ossimProjectionFactoryRegistry::unregisterFactory(ossimProjectionFactoryBase* factory)
+{
+   std::vector<ossimProjectionFactoryBase*>::iterator iter =  std::find(theFactoryList.begin(),
+                                                                        theFactoryList.end(),
+                                                                        factory);
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+}
+
+bool ossimProjectionFactoryRegistry::findFactory(ossimProjectionFactoryBase* factory)const
+{
+   return (std::find(theFactoryList.begin(),
+                     theFactoryList.end(),
+                     factory)!=theFactoryList.end());
+}
+
+std::list<ossimString> ossimProjectionFactoryRegistry::getList()const
+{
+   list<ossimString> result;
+   vector<ossimProjectionFactoryBase*>::const_iterator factory = theFactoryList.begin();
+
+   while(factory != theFactoryList.end())
+   {
+      if(*factory)
+      {
+         list<ossimString> temp = (*factory)->getList();
+         result.insert(result.end(),
+                       temp.begin(),
+                       temp.end());
+      }
+      
+      ++factory;
+   }
+   
+   return result;
+   
+}
+
+ossimObject* ossimProjectionFactoryRegistry::createObject(const ossimString& typeName)const
+{
+   return createProjection(typeName);
+}
+
+ossimObject* ossimProjectionFactoryRegistry::createObject(const ossimKeywordlist& kwl,
+                                                          const char* prefix)const
+{
+   return createProjection(kwl, prefix);
+}
+
+void ossimProjectionFactoryRegistry::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   vector<ossimString> result;
+   vector<ossimProjectionFactoryBase*>::const_iterator factory = theFactoryList.begin();
+
+   while(factory != theFactoryList.end())
+   {
+      if(*factory)
+      {
+         result.clear();
+         (*factory)->getTypeNameList(result);
+         typeList.insert(typeList.end(),
+                         result.begin(),
+                         result.end());
+      }
+      
+      ++factory;
+   }   
+}
+
+void ossimProjectionFactoryRegistry::initializeDefaults()
+{
+   theInstance->registerFactory(ossimSensorModelFactory::instance());
+   theInstance->registerFactory(ossimMapProjectionFactory::instance());
+   theInstance->registerFactory(ossimSrsProjectionFactory::instance());
+   theInstance->registerFactory(ossimTiffProjectionFactory::instance());
+   theInstance->registerFactory(ossimPcsCodeProjectionFactory::instance());   
+   theInstance->registerFactory(ossimStatePlaneProjectionFactory::instance());
+   theInstance->registerFactory(ossimNitfProjectionFactory::instance());   
+   theInstance->registerFactory(ossimMiscProjectionFactory::instance());
+}
+
+extern "C"
+{
+  void* ossimProjectionFactoryRegistryGetInstance()
+  {
+    return ossimProjectionFactoryRegistry::instance();
+  }
+
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryRegistry.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryRegistry.h
new file mode 100644
index 0000000000..0337b133bd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionFactoryRegistry.h
@@ -0,0 +1,71 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id: ossimProjectionFactoryRegistry.h,v 1.13 2005/09/08 17:30:52 gpotts Exp $
+#ifndef ossimProjectionFactoryRegistry_HEADER
+#define ossimProjectionFactoryRegistry_HEADER
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/factory/ossimObjectFactory.h>
+
+#include <vector>
+#include <list>
+class ossimProjectionFactoryBase;
+class ossimProjection;
+
+class OSSIMDLLEXPORT ossimProjectionFactoryRegistry : public ossimObjectFactory
+{
+public:
+   static ossimProjectionFactoryRegistry* instance();
+
+   ossimProjection* createProjection(const ossimFilename& filename,
+                                     ossim_uint32 entryIdx)const;
+   ossimProjection* createProjection(const ossimString& name)const;
+   ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                     const char* prefix=NULL)const;
+
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /**
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /**
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   bool registerFactory(ossimProjectionFactoryBase* factory);
+   void unregisterFactory(ossimProjectionFactoryBase* factory);
+   bool findFactory(ossimProjectionFactoryBase* factory)const;
+   
+   std::list<ossimString> getList()const;
+   
+protected:
+   ossimProjectionFactoryRegistry(){}
+   ossimProjectionFactoryRegistry(const ossimProjectionFactoryRegistry& rhs):ossimObjectFactory(rhs){}
+   void operator = (const ossimProjectionFactoryRegistry&){}
+
+   static ossimProjectionFactoryRegistry*   theInstance;
+   std::vector<ossimProjectionFactoryBase*> theFactoryList;
+
+   void initializeDefaults();
+};
+
+extern "C"
+{
+  OSSIMDLLEXPORT void* ossimProjectionFactoryRegistryGetInstance();
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionViewControllerFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionViewControllerFactory.cpp
new file mode 100644
index 0000000000..f5fdbbb3af
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionViewControllerFactory.cpp
@@ -0,0 +1,90 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimProjectionViewControllerFactory.cpp,v 1.5 2005/09/14 19:23:14 gpotts Exp $
+
+#include "ossimProjectionViewControllerFactory.h"
+#include "base/factory/ossimObjectFactoryRegistry.h"
+#include "projections/ossimMapViewController.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+RTTI_DEF1(ossimProjectionViewControllerFactory, "ossimProjectionViewControllerFactory", ossimObjectFactory);
+
+ossimProjectionViewControllerFactory* ossimProjectionViewControllerFactory::theInstance = NULL;
+
+ossimProjectionViewControllerFactory* ossimProjectionViewControllerFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimProjectionViewControllerFactory;
+   }
+
+   return theInstance;
+}
+
+ossimViewController* ossimProjectionViewControllerFactory::createViewController(const ossimString& name)const
+{
+   if(name == STATIC_TYPE_NAME(ossimMapViewController))
+   {
+      return new ossimMapViewController;
+   }
+
+   return (ossimViewController*)NULL;
+}
+
+ossimViewController* ossimProjectionViewControllerFactory::createViewController(const ossimKeywordlist& kwl,
+                                                                                const char* prefix)const
+{
+   const char* type = kwl.find(prefix,  ossimKeywordNames::TYPE_KW);
+   ossimViewController* result = NULL;
+   if(type)
+   {
+      result = createViewController(ossimString(type));
+      if(result)
+      {
+         if(!result->loadState(kwl, prefix))
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }
+   
+   return result;
+}
+
+ossimObject* ossimProjectionViewControllerFactory::createObject(const ossimString& typeName)const
+{
+   return createViewController(typeName);
+}
+
+ossimObject* ossimProjectionViewControllerFactory::createObject(const ossimKeywordlist& kwl,
+                                                                const char* prefix)const
+{
+   return createViewController(kwl, prefix);
+}
+
+void ossimProjectionViewControllerFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   typeList.push_back("ossimMapViewController");
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionViewControllerFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionViewControllerFactory.h
new file mode 100644
index 0000000000..8f0114e12c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimProjectionViewControllerFactory.h
@@ -0,0 +1,54 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimProjectionViewControllerFactory.h,v 1.2 2005/09/14 19:23:30 gpotts Exp $
+#ifndef ossimProjectionViewControllerFactory_HEADER
+#define ossimProjectionViewControllerFactory_HEADER
+#include "base/factory/ossimBaseObjectFactory.h"
+#include "base/data_types/ossimString.h"
+
+class ossimViewController;
+
+class ossimProjectionViewControllerFactory : public ossimObjectFactory
+{
+public:
+   static ossimProjectionViewControllerFactory* instance();
+
+   virtual ossimViewController* createViewController(const ossimString& name)const;
+   virtual ossimViewController* createViewController(const ossimKeywordlist& kwl,
+                                                     const char* prefix)const;
+
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix)const;
+
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+protected:
+   ossimProjectionViewControllerFactory(){}
+   ossimProjectionViewControllerFactory(const ossimProjectionViewControllerFactory& rhs ){}
+
+   static ossimProjectionViewControllerFactory* theInstance;
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimSensorModelFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimSensorModelFactory.cpp
new file mode 100644
index 0000000000..9be8a6e67f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimSensorModelFactory.cpp
@@ -0,0 +1,548 @@
+//*****************************************************************************
+// FILE: ossimSensorModelFactory.cc
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// AUTHOR:  Oscar Kramer
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimSensorModelFactory
+//
+//*****************************************************************************
+//  $Id: ossimSensorModelFactory.cpp,v 1.43 2005/11/29 18:36:58 dburken Exp $
+#include <fstream>
+#include <algorithm>
+#include <projections/factory/ossimSensorModelFactory.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimDirectory.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  = ossimTrace("ossimSensorModelFactory:exec");
+static ossimTrace traceDebug = ossimTrace("ossimSensorModelFactory:debug");
+
+//***
+// Note to programmer: To add a new model, search this file for "ADD_MODEL"
+// to locate places requiring editing. Functional example below...
+//
+// ADD_MODEL: Include all sensor model headers here:
+//***
+#include <projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.h>
+#include <projections/sensor_modeling/rpc/ossimRpcModel.h>
+#include <projections/sensor_modeling/rpc/ossimIkonosRpcModel.h>
+#include <projections/sensor_modeling/rpc/ossimNitfRpcModel.h>
+#include <projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.h>
+#include <projections/sensor_modeling/landsat/ossimLandSatModel.h>
+#include <projections/sensor_modeling/spot/ossimSpot5Model.h>
+#include <support_data/spot/ossimSpotDimapSupportData.h>
+#include <projections/sensor_modeling/ossimNitfMapModel.h>
+#include <projections/sensor_modeling/fcsi/ossimFcsiModel.h>
+#include <projections/sensor_modeling/fcsi/ossimApplanixUtmModel.h>
+#include <projections/sensor_modeling/fcsi/ossimApplanixEcefModel.h>
+#include <support_data/ff_l7/ossimFfL7.h>
+#include <support_data/ff_l7/ossimFfL5.h>
+
+//***
+// ADD_MODEL: List names of all sensor models produced by this factory:
+//***
+//const char* MY_NEW_MODEL = "myNewModel";
+// const char* OCG_MODEL        = "ossimCoarseGridModel";
+// const char* RPC_MODEL        = "ossimRpcModel";
+// const char* IKONOS_RPC_MODEL = "ossimIkonosRpcModel";
+// const char* NITF_RPC_MODEL   = "ossimNitfRpcModel";
+// const char* LANDSAT_MODEL    = "ossimLandSatModel";
+// const char* NITF_MAP_MODEL   = "ossimNitfMapModel";
+// const char* FCSI_MODEL       = "ossimFcsiModel";
+// const char* EMERGE_FCSI_MODEL= "ossimEmergeFcsiModel";
+
+ossimSensorModelFactory* ossimSensorModelFactory::theInstance = 0;
+
+//*****************************************************************************
+//  STATIC METHOD: ossimSensorModelFactory::instance()
+//  
+//*****************************************************************************
+ossimSensorModelFactory*  ossimSensorModelFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimSensorModelFactory;
+   }
+
+   return (ossimSensorModelFactory*) theInstance;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSensorModelFactory::create(kwl, prefix)
+//*****************************************************************************
+ossimProjection* ossimSensorModelFactory::createProjection(const ossimKeywordlist &keywordList,
+                                                           const char *prefix) const
+{
+   ossimProjection *result=NULL;
+
+   //
+   // Permit specification of geometry file name in lieu of type:
+   //
+   const char*  value = keywordList.find(prefix, ossimKeywordNames::GEOM_FILE_KW);
+   if (value)
+   {
+      result = createProjection(ossimFilename(value), 0);
+   }
+   //
+   // Search for occurence of "type" keyword:
+   //
+   else
+   {
+      value = keywordList.find(prefix, ossimKeywordNames::TYPE_KW);
+      if(value)
+      {
+         result = createProjection(ossimString(value));
+         if(result)
+         {
+            if(!result->loadState(keywordList, prefix))
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+      }
+   }
+                  
+   return result;
+}
+
+//*****************************************************************************
+//  METHOD: 
+//  
+//*****************************************************************************
+ossimProjection*
+ossimSensorModelFactory::createProjection(const ossimString &name) const
+{
+   //***
+   // Name should represent the model type:
+   //***
+   if(name == STATIC_TYPE_NAME(ossimCoarseGridModel))
+   {
+      return new ossimCoarseGridModel;
+   }
+
+   if (name ==  STATIC_TYPE_NAME(ossimRpcModel))
+   {
+      return new ossimRpcModel;
+   }
+
+   if(name == STATIC_TYPE_NAME(ossimLandSatModel))
+   {
+      return new ossimLandSatModel;
+   }
+
+   if(name == STATIC_TYPE_NAME(ossimNitfMapModel))
+   {
+      return new ossimNitfMapModel;
+   }
+
+   if(name == STATIC_TYPE_NAME(ossimQuickbirdRpcModel))
+   {
+      return new ossimQuickbirdRpcModel;
+   }
+
+   if(name == STATIC_TYPE_NAME(ossimNitfRpcModel))
+   {
+       return new ossimNitfRpcModel;
+   }
+   if(name == STATIC_TYPE_NAME(ossimFcsiModel))
+   {
+      return new ossimFcsiModel;
+   }
+   if(name == STATIC_TYPE_NAME(ossimApplanixUtmModel))
+   {
+      return new ossimApplanixUtmModel;
+   }
+   if(name == STATIC_TYPE_NAME(ossimApplanixEcefModel))
+   {
+      return new ossimApplanixEcefModel;
+   }
+
+   if(name == STATIC_TYPE_NAME(ossimSpot5Model))
+   {
+      return new ossimSpot5Model;
+   }
+
+   //***
+   // ADD_MODEL: (Please leave this comment for the next programmer)
+   //***
+//   if(name == MY_NEW_MODEL)
+//      return new myNewModel;
+
+   return NULL;
+}
+
+
+//*****************************************************************************
+//  METHOD:  ossimSensorModelFactory::getList()
+//  
+//*****************************************************************************
+list<ossimString> ossimSensorModelFactory::getList() const
+{
+   list<ossimString> result;
+
+   //***
+   // Place the name of each model produced in the list:
+   //***
+   result.push_back(STATIC_TYPE_NAME(ossimCoarseGridModel));
+   result.push_back(STATIC_TYPE_NAME(ossimRpcModel));
+   result.push_back(STATIC_TYPE_NAME(ossimIkonosRpcModel));
+   result.push_back(STATIC_TYPE_NAME(ossimNitfRpcModel));
+   result.push_back(STATIC_TYPE_NAME(ossimQuickbirdRpcModel));
+   result.push_back(STATIC_TYPE_NAME(ossimLandSatModel));
+   result.push_back(STATIC_TYPE_NAME(ossimNitfMapModel));
+   result.push_back(STATIC_TYPE_NAME(ossimFcsiModel));
+   result.push_back(STATIC_TYPE_NAME(ossimApplanixUtmModel));
+   result.push_back(STATIC_TYPE_NAME(ossimApplanixEcefModel));
+   result.push_back(STATIC_TYPE_NAME(ossimSpot5Model));
+
+   //***
+   // ADD_MODEL: Please leave this comment for the next programmer. Add above.
+   //***
+   //result.push_back(ossimString(MY_NEW_MODEL));
+   
+   return result;
+}
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+ossimObject*
+ossimSensorModelFactory::createObject(const ossimString& typeName)const
+{
+   return createProjection(typeName);
+}
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+ossimObject*
+ossimSensorModelFactory::createObject(const ossimKeywordlist& kwl,
+                                      const char* prefix)const
+{
+   return createProjection(kwl, prefix);
+}
+   
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+void
+ossimSensorModelFactory::getTypeNameList(std::vector<ossimString>& typeList)
+   const
+{
+   typeList.push_back(STATIC_TYPE_NAME(ossimApplanixEcefModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimApplanixUtmModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimCoarseGridModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimRpcModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimIkonosRpcModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimQuickbirdRpcModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimNitfRpcModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimLandSatModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimNitfMapModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimFcsiModel));
+   typeList.push_back(STATIC_TYPE_NAME(ossimSpot5Model));
+
+   //***
+   // ADD_MODEL: Please leave this comment for the next programmer. Add above.
+   //***
+   //typeList.push_back(ossimString(MY_NEW_MODEL));
+   
+}
+
+ossimProjection* ossimSensorModelFactory::createProjection(const ossimFilename& filename,
+                                                           ossim_uint32  entryIdx) const
+{
+   ossimKeywordlist kwl;
+   ossimProjection* model = 0;
+
+   ossimFilename geomFile = filename;
+   geomFile = geomFile.setExtension("geom");
+   
+   if(geomFile.exists()&&
+      kwl.addFile(filename.c_str()))
+   {
+      ossimFilename coarseGrid;
+      
+      const char* type = kwl.find(ossimKeywordNames::TYPE_KW);
+      if(type)
+      {
+         if(ossimString(type) == ossimString(STATIC_TYPE_NAME(ossimCoarseGridModel)))
+         {
+            findCoarseGrid(coarseGrid,
+                           filename);
+            
+            if(coarseGrid.exists() &&(coarseGrid != ""))
+            {
+               kwl.add("grid_file_name",
+                       coarseGrid.c_str(),
+                       true);
+               model = new ossimCoarseGridModel(kwl);
+               if(!model->getErrorStatus())
+               {
+                  return model;
+               }
+            }
+         }
+      }
+      kwl.clear();
+   }
+
+   // See if there is an external geomtry.
+   ossimProjection* proj = createProjectionFromGeometryFile(filename,
+                                                            entryIdx);
+   if (proj)
+   {
+      return proj;
+   }
+
+   if(model)
+   {
+      delete model;
+      model = 0;
+   }
+   // first check for override
+   //
+   if(geomFile.exists()&&kwl.addFile(geomFile.c_str()))
+   {
+      model =  createProjection(kwl);
+   }
+   if(model)
+   {
+      return model;
+   }
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModelFactory::createProjection: Testing ossimCoarsGridModel" << std::endl;
+   }
+   
+   ifstream input(geomFile.c_str());
+   char ecgTest[4];
+   input.read((char*)ecgTest, 3);
+   ecgTest[3] = '\0';
+   input.close();
+   if(ossimString(ecgTest) == "eCG")
+   {
+      ossimKeywordlist kwlTemp;
+      kwlTemp.add("type",
+                  "ossimCoarseGridModel",
+                  true);
+      kwlTemp.add("geom_file",
+                  geomFile.c_str(),
+                  true);
+      return createProjection(kwlTemp);
+   }
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModelFactory::createProjection: testing ossimRpcModel" << std::endl;
+   }
+
+   //---
+   // Test for quick bird rpc.  Could be either a tiff or nitf so not wrapped
+   // around "isNitf()" anymore.
+   //---
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimSensorModelFactory::createProjection: "
+         << "testing ossimQuickbirdRpcModel"
+         << std::endl;
+   }
+   
+   ossimQuickbirdRpcModel* qbModel = new ossimQuickbirdRpcModel;
+   if(qbModel->parseFile(filename))
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimSensorModelFactory::createProjection: "
+            << "returning ossimQuickbirdRpcModel" << std::endl;
+      }
+      model = qbModel;
+      return model;
+   }
+   else
+   {
+      delete qbModel;
+      qbModel = NULL;
+   }
+
+   if(isNitf(filename))
+   {
+     if(traceDebug())
+     {
+        ossimNotify(ossimNotifyLevel_DEBUG)
+           << "DEBUG ossimSensorModelFactory::createProjection: "
+           << " testing ossimNitfRpcModel" << std::endl;
+     }
+
+     model = new ossimNitfRpcModel(filename);  // filename = NITF_file
+     if(!model->getErrorStatus())
+     {
+        return model;
+     }
+     delete model;
+     model = 0;
+     
+     if(traceDebug())
+     {
+        ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModelFactory::createProjection: testing ossimIkinosRpcModel" << std::endl;
+     }
+     
+     model = new ossimIkonosRpcModel(filename);
+     if(!model->getErrorStatus())
+     {
+        return model;
+     }
+     delete model;
+     model = 0;
+     if(traceDebug())
+     {
+        ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModelFactory::createProjection: testing ossimNitfMapModel" << std::endl;
+     }
+     
+     model = new ossimNitfMapModel(filename); // filename = NITF_file
+     if(!model->getErrorStatus())
+     {
+        return model;
+     }
+     delete model;
+     model = 0;
+   }
+   else if(isLandsat(filename))
+   {
+      model = new ossimLandSatModel(filename);
+      if(!model->getErrorStatus())
+         return model;
+      delete model;
+      model = 0;
+   }
+
+   ossimFilename spot5Test = geomFile;
+   
+
+   if(!spot5Test.exists())
+   {
+      spot5Test = geomFile.path();
+      spot5Test = spot5Test.dirCat(ossimFilename("metadata.dim"));
+   }
+   if(spot5Test.exists())
+   {
+      ossimSpotDimapSupportData *meta = new ossimSpotDimapSupportData;
+      if(meta->loadXmlFile(spot5Test))
+      {
+         model = new ossimSpot5Model(meta);
+         if(!model->getErrorStatus())
+         {
+            return model;
+         }
+         delete model;
+         model = 0;
+      }
+      else
+      {
+         delete meta;
+         meta = 0;
+      }
+   }
+   
+   model = new ossimCoarseGridModel(geomFile);
+   if(model)
+   {
+      if(!model->getErrorStatus())
+         return model;
+      delete model;
+      model = 0;
+   }
+   return model;
+}
+   
+bool ossimSensorModelFactory::isNitf(const ossimFilename& filename)const
+{
+   std::ifstream in(filename.c_str(), ios::in|ios::binary);
+   
+   if(in)
+   {
+      char nitfFile[4];
+      in.read((char*)nitfFile, 4);
+
+      return (ossimString(nitfFile,
+                          nitfFile+4) == "NITF");
+   }
+
+   return false;
+}
+
+bool ossimSensorModelFactory::isLandsat(const ossimFilename& filename)const
+{
+   ossimFilename temp(filename);
+   temp.downcase();
+   ossimFfL7* ff_headerp = 0;
+   if (temp.contains("header.dat"))
+   {
+       ff_headerp = new ossimFfL5(filename);
+   } else {
+       ff_headerp = new ossimFfL7(filename);
+   }
+   bool r = !(ff_headerp->getErrorStatus());
+
+   delete ff_headerp;
+   return r;
+}
+
+void ossimSensorModelFactory::findCoarseGrid(ossimFilename& result,
+                                             const ossimFilename& geomFile)const
+{
+   result = geomFile;
+   result.setFile(result.fileNoExtension()+"_ocg");
+   result.setExtension("dat");
+   
+   if(!result.exists())
+   {
+      result = geomFile;
+      result.setExtension("dat");
+   }
+   
+   // let's find a .dat file in the current directory
+   //
+   if(!result.exists())
+   {
+      result = "";
+      ossimDirectory directoryList(geomFile.path());
+      ossimFilename file;
+      if(directoryList.getFirst(file,
+                                ossimDirectory::OSSIM_DIR_FILES))
+      {
+         ossimString testString = "OSSIM_DBL_GRID";
+         char tempBuf[14];
+         do
+         {
+            if(file.ext().downcase() == "dat")
+            {
+               ifstream in(file);
+               if(in)
+               {
+                  in.read((char*)tempBuf, 14);
+                  in.close();
+                  if(ossimString(tempBuf, tempBuf+14) == testString)
+                  {
+                     result = file;
+                  }
+               }
+               
+            }
+         }while((directoryList.getNext(file))&&(result == ""));
+      }
+      // try to find it
+   }
+}
+
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimSensorModelFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimSensorModelFactory.h
new file mode 100644
index 0000000000..404a2b1881
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimSensorModelFactory.h
@@ -0,0 +1,73 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Oscar Kramer
+//
+// Description: Factory for all ossim sensor models.
+// 
+//*******************************************************************
+//  $Id: ossimSensorModelFactory.h,v 1.7 2004/09/24 17:19:40 dburken Exp $
+#ifndef ossimSensorModelFactory_HEADER
+#define ossimSensorModelFactory_HEADER
+#include "ossimProjectionFactoryBase.h"
+
+class ossimProjection;
+class ossimString;
+class ossimFilename;
+
+class ossimSensorModelFactory : public ossimProjectionFactoryBase
+{
+public:
+   /*!
+    * METHOD: instance()
+    * For accessing static instance of concrete factory.
+    */
+   static ossimSensorModelFactory* instance();
+   
+   virtual ossimProjection* createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const;
+   /*!
+    * METHOD: create()
+    * Attempts to create an instance of the Product given a Specifier or
+    * keywordlist. Returns successfully constructed product or NULL.
+    */
+   virtual ossimProjection* createProjection(const ossimString& spec)     const;
+   virtual ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                             const char* prefix = 0)      const;
+
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+   /*!
+    * METHOD: getList()
+    * Returns name list of all products represented by this factory.
+    */
+   virtual std::list<ossimString> getList() const;
+
+protected:
+   ossimSensorModelFactory() {}
+   
+   static ossimSensorModelFactory*  theInstance;
+   bool isNitf(const ossimFilename& filename)const;
+   bool isLandsat(const ossimFilename& filename)const;
+   void findCoarseGrid(ossimFilename& result,
+                       const ossimFilename& geomFile)const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimSrsProjectionFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimSrsProjectionFactory.cpp
new file mode 100644
index 0000000000..f30de560e7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimSrsProjectionFactory.cpp
@@ -0,0 +1,159 @@
+//*****************************************************************************
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimMapProjectionFactory
+//
+//*****************************************************************************
+//  $Id: ossimSrsProjectionFactory.cpp,v 1.2 2005/09/08 17:36:22 gpotts Exp $
+#include <sstream>
+#include "ossimSrsProjectionFactory.h"
+#include <base/common/ossimKeywordNames.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <projections/map_projections/ossimTransMercatorProjection.h>
+#include <projections/map_projections/ossimOrthoGraphicProjection.h>
+
+ossimSrsProjectionFactory* ossimSrsProjectionFactory::theInstance = 0;
+
+ossimSrsProjectionFactory* ossimSrsProjectionFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimSrsProjectionFactory;
+   }
+
+   return (ossimSrsProjectionFactory*) theInstance;
+}
+
+ossimProjection* ossimSrsProjectionFactory::createProjection(const ossimFilename& filename,
+                                                             ossim_uint32 entryIdx)const
+{
+   return 0;
+}
+
+ossimProjection* ossimSrsProjectionFactory::createProjection(const ossimKeywordlist &keywordList,
+                                                             const char *prefix) const
+{
+   const char *lookup = keywordList.find(prefix, ossimKeywordNames::TYPE_KW);
+
+   if(lookup)
+   {
+      ossimProjection* proj = createProjection(ossimString(lookup));
+      if(proj)
+      {
+         proj->loadState(keywordList, prefix);
+         return proj;
+      }
+   }
+
+   return 0;
+}
+
+ossimProjection* ossimSrsProjectionFactory::createProjection(const ossimString &name) const
+{
+   ossimString tempName = name;
+   tempName = tempName.trim();
+   tempName = tempName.upcase();
+   if(tempName.contains("AUTO"))
+   {
+      ossimString projId;
+      ossimString projUnits;
+      ossimString projOriginLon;
+      ossimString projOriginLat;
+      tempName = tempName.substitute("AUTO:",
+                                     "");
+      tempName = tempName.substitute(",",
+                                     " ",
+                                     true);
+      std::istringstream in(tempName);
+      in >> projId >> projUnits >> projOriginLon >> projOriginLat;
+
+      ossimGpt origin(projOriginLat.toDouble(),
+                      projOriginLon.toDouble());
+
+      switch(projId.toUInt32())
+      {
+         case 42001:
+         {
+            ossimUtmProjection* utm = new ossimUtmProjection;
+            utm->setZone(origin);
+            utm->setOrigin(origin);
+            utm->update();
+            return utm;
+         }
+         case 42002:
+         {
+            ossimTransMercatorProjection* transMerc = new ossimTransMercatorProjection;
+
+            transMerc->setFalseNorthing(origin.latd()>=0.0?0.0:10000000.0);
+            transMerc->setOrigin(ossimGpt(0.0, origin.lond()));
+            transMerc->setScaleFactor(.9996);
+            transMerc->update();
+            return transMerc;
+         }
+         case 42003:
+         {
+            ossimOrthoGraphicProjection* ortho = new ossimOrthoGraphicProjection;
+            ortho->setOrigin(origin);
+            ortho->update();
+            return ortho;
+         }
+         case 42004:
+         {
+            ossimEquDistCylProjection* geographic = new ossimEquDistCylProjection;
+            geographic->setOrigin(origin);
+            geographic->update();
+            return geographic;
+         }
+         default:
+         {
+            return 0;
+         }
+      }
+   }
+   else if(tempName.contains("EPSG"))
+   {
+      tempName = tempName.substitute("EPSG:", "");
+      switch(tempName.toUInt32())
+      {
+         case 4326:
+         {
+            return new ossimEquDistCylProjection;
+         }
+         default:
+         {
+            return 0;
+         }
+      }
+   }
+
+   return 0;
+}
+
+ossimObject* ossimSrsProjectionFactory::createObject(const ossimString& typeName)const
+{
+   return createProjection(typeName);
+}
+
+ossimObject* ossimSrsProjectionFactory::createObject(const ossimKeywordlist& kwl,
+                                                     const char* prefix)const
+{
+   return createProjection(kwl, prefix);
+}
+
+void ossimSrsProjectionFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   
+}
+
+list<ossimString> ossimSrsProjectionFactory::getList()const
+{
+   list<ossimString> result;
+
+   
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimSrsProjectionFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimSrsProjectionFactory.h
new file mode 100644
index 0000000000..480287c7c1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimSrsProjectionFactory.h
@@ -0,0 +1,68 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimSrsProjectionFactory.h,v 1.1 2005/09/08 16:49:27 gpotts Exp $
+
+#ifndef ossimSrsProjectionFactory_HEADER
+#define ossimSrsProjectionFactory_HEADER
+
+#include "ossimProjectionFactoryBase.h"
+
+class ossimProjection;
+class ossimString;
+
+class OSSIMDLLEXPORT ossimSrsProjectionFactory : public ossimProjectionFactoryBase
+{
+public:
+   /*!
+    * METHOD: instance()
+    * Instantiates singleton instance of this class:
+    */
+   static ossimSrsProjectionFactory* instance();
+
+   virtual ossimProjection* createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const;
+   /*!
+    * METHOD: create()
+    * Attempts to create an instance of the projection specified by name.
+    * Returns successfully constructed projection or NULL.
+    */
+   virtual ossimProjection* createProjection(const ossimString& name)const;
+   virtual ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                             const char* prefix = 0)const;
+
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /*!
+    * METHOD: getList()
+    * Returns list of all projections represented by this factory:
+    */
+   virtual list<ossimString> getList()const;
+
+protected:
+   ossimSrsProjectionFactory() {}
+   static ossimSrsProjectionFactory*  theInstance;
+ 
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimStatePlaneProjectionFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimStatePlaneProjectionFactory.cpp
new file mode 100644
index 0000000000..417bf92fb6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimStatePlaneProjectionFactory.cpp
@@ -0,0 +1,854 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//*******************************************************************
+//  $Id: ossimStatePlaneProjectionFactory.cpp,v 1.15 2005/03/30 17:12:24 dburken Exp $
+#include "ossimStatePlaneProjectionFactory.h"
+#include "projections/ossimStatePlaneProjectionInfo.h"
+#include "projections/factory/ossimMapProjectionFactory.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/data_types/ossimFilename.h"
+#include "projections/ossimProjection.h"
+using namespace std;
+
+ossimStatePlaneProjectionFactory* ossimStatePlaneProjectionFactory::theInstance = NULL;
+
+ossimStatePlaneProjectionFactory::~ossimStatePlaneProjectionFactory()
+{
+   theInstance = NULL;
+}
+
+ossimStatePlaneProjectionFactory* ossimStatePlaneProjectionFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimStatePlaneProjectionFactory;
+
+      theInstance->initializeMap();
+   }
+
+   return theInstance;
+}
+
+ossimProjection* ossimStatePlaneProjectionFactory::createProjection(
+   const ossimFilename& filename, ossim_uint32 entryIdx)const
+{
+   // See if there is an external geomtry.
+   return createProjectionFromGeometryFile(filename, entryIdx);
+}
+
+ossimProjection* ossimStatePlaneProjectionFactory::createProjection(
+   const ossimString& name)const
+{
+   ossimProjection* result = NULL;
+
+   std::map<ossim_int32, ossimStatePlaneProjectionInfo*>::const_iterator current;
+   ossim_int32 c = name.toLong();
+   current = theStatePlaneInfoMap.find(c);
+
+   if(current != theStatePlaneInfoMap.end())
+   {
+      ossimKeywordlist kwl2;
+      
+      (*current).second->populateProjectionKeywords(kwl2);
+
+      result = ossimMapProjectionFactory::instance()->createProjection(kwl2);
+   }
+
+   if(!result)
+   {
+      std::map<ossimString, ossimStatePlaneProjectionInfo*>::const_iterator currentName;
+      currentName = theStatePlaneInfoNameMap.find(c);
+      if(currentName != theStatePlaneInfoNameMap.end())
+      {
+         ossimKeywordlist kwl2;
+         
+         (*currentName).second->populateProjectionKeywords(kwl2);
+         
+         result = ossimMapProjectionFactory::instance()->createProjection(kwl2);
+      }
+   }
+   
+   return result;
+}
+
+ossimProjection* ossimStatePlaneProjectionFactory::createProjection(const ossimKeywordlist& kwl,
+                                                                    const char* prefix)const
+{
+   ossimProjection* result = NULL;
+   const char* pcs_code = kwl.find(prefix,
+                                   ossimKeywordNames::PCS_CODE_KW);
+   const char* type_kw  = kwl.find(prefix,
+                                   ossimKeywordNames::TYPE_KW);
+   if(pcs_code)
+   {
+      std::map<ossim_int32, ossimStatePlaneProjectionInfo*>::const_iterator current;
+      ossim_int32 code = ossimString(pcs_code).toLong();
+      current = theStatePlaneInfoMap.find(code);
+
+      if(current != theStatePlaneInfoMap.end())
+      {
+         ossimKeywordlist kwl2 = kwl;
+
+         (*current).second->populateProjectionKeywords(kwl2, prefix);
+
+         result = ossimMapProjectionFactory::instance()->createProjection(kwl2, prefix);
+	 
+      }
+   }
+   else if(type_kw)
+   {
+      std::map<ossimString, ossimStatePlaneProjectionInfo*>::const_iterator current;
+      current = theStatePlaneInfoNameMap.find(ossimString(type_kw));
+      if(current != theStatePlaneInfoNameMap.end())
+      {
+         ossimKeywordlist kwl2 = kwl;
+
+         (*current).second->populateProjectionKeywords(kwl2, prefix);
+
+         result = ossimMapProjectionFactory::instance()->createProjection(kwl2, prefix);
+      }
+   }
+   
+   return result;
+}
+
+const ossimStatePlaneProjectionInfo* ossimStatePlaneProjectionFactory::getInfo(ossim_int32 pcsCode)const
+{
+   std::map<ossim_int32, ossimStatePlaneProjectionInfo*>::const_iterator current;
+   current = theStatePlaneInfoMap.find(pcsCode);
+   
+   if(current != theStatePlaneInfoMap.end())
+   {
+      return (*current).second;
+   }
+
+   return (const ossimStatePlaneProjectionInfo*)NULL;
+}
+
+const ossimStatePlaneProjectionInfo* ossimStatePlaneProjectionFactory::getInfo(const ossimString& name)const
+{
+   std::map<ossimString, ossimStatePlaneProjectionInfo*>::const_iterator current;
+   current = theStatePlaneInfoNameMap.find(name);
+   
+   if(current != theStatePlaneInfoNameMap.end())
+   {
+      return (*current).second;
+   }
+
+   return (const ossimStatePlaneProjectionInfo*)NULL;
+}
+
+
+
+std::list<ossimString> ossimStatePlaneProjectionFactory::getList()const
+{
+   list<ossimString> result;
+
+   std::map<ossim_int32, ossimStatePlaneProjectionInfo*>::const_iterator current = theStatePlaneInfoMap.begin();
+
+   while(current != theStatePlaneInfoMap.end())
+   {
+      result.push_back((*current).second->name());
+      
+      ++current;
+   }
+   
+   return result;
+}
+
+ossimObject* ossimStatePlaneProjectionFactory::createObject(const ossimString& typeName)const
+{
+   return createProjection(typeName);
+}
+
+ossimObject* ossimStatePlaneProjectionFactory::createObject(const ossimKeywordlist& kwl,
+                                                            const char* prefix)const
+{
+   return createProjection(kwl, prefix);
+}
+   
+void ossimStatePlaneProjectionFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   std::map<ossim_int32, ossimStatePlaneProjectionInfo*>::const_iterator current = theStatePlaneInfoMap.begin();
+
+   while(current != theStatePlaneInfoMap.end())
+   {
+      typeList.push_back((*current).second->name());
+      
+      ++current;
+   }
+//   typeList.push_back("ossimStatePlaneProjection");
+}
+
+bool ossimStatePlaneProjectionFactory::addStatePlaneInfo(ossimStatePlaneProjectionInfo* info)
+{
+   if(info)
+   {
+      theStatePlaneInfoMap.insert(make_pair((ossim_int32)info->code(), 
+                                            info));
+      theStatePlaneInfoNameMap.insert(make_pair(info->name(), 
+                                                info));
+
+      return true;
+   }
+   
+   return false;
+   
+}
+
+void ossimStatePlaneProjectionFactory::initializeMap()
+{
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alabama_East", 26729, "ossimTransMercatorProjection", "30 30 n", "85 50 w",
+                                                       25000, 0, 500000, 0.0, "ft"));
+   
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alabama_West", 26730, "ossimTransMercatorProjection", "30 n", "87 30 w",
+                  15000, 0, 500000, 0.0, "ft"));
+   
+   // addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_1", 26731 UNSUPPORTED! (Hotine Mercator)
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_2", 26732, "ossimTransMercatorProjection", "54 n", "142 w", 10000, 0,
+                  500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_3", 26733, "ossimTransMercatorProjection", "54 n", "146 w", 10000, 0,
+                  500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_4", 26734, "ossimTransMercatorProjection", "54 n", "150 w", 10000, 0,
+                  500000, 0.0, "ft")); 
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_5", 26735, "ossimTransMercatorProjection", "54 n", "154 w", 10000, 0,
+                  500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_6", 26736, "ossimTransMercatorProjection", "54 n", "158 w", 10000, 0,
+                  500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_7", 26737, "ossimTransMercatorProjection", "54 n", "162 w", 10000, 0,
+                  700000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_8", 26738, "ossimTransMercatorProjection", "54 n", "166 w", 10000, 0,
+                  500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_9", 26739, "ossimTransMercatorProjection", "54 n", "170 w", 10000, 0,
+                  600000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Alaska_zone_10",  26740, "ossimLambertConformalConicProjection", "51 n", "176 w",
+                  "51 50 n", "53 50 n", 3000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_California_I",    26741, "ossimLambertConformalConicProjection", "39 20", "122 w",
+                  "40 n", "41 40 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_California_II",   26742, "ossimLambertConformalConicProjection", "37 40", "122 w",
+                  "38 20", "39 50", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_California_III",  26743, "ossimLambertConformalConicProjection", "36 30 n", "120 30 w",
+                  "37 04 n", "38 26 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_California_IV",   26744, "ossimLambertConformalConicProjection", "35 20 n", "119 w",
+                  "36 n", "37 15 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_California_V",    26745, "ossimLambertConformalConicProjection", "33 30 n", "118 w",
+                  "34 02 n", "35 28 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_California_VI",   26746, "ossimLambertConformalConicProjection", "32 10", "116 15 w",
+                  "32 47 n", "33 53 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_California_VII",  26747, "ossimLambertConformalConicProjection", "34 08 n", "118 20 w",
+                  "33 52 n", "34 25 n", 4186692.58, 4160926.74, "ft"));
+                              
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Arizona_East",    26748, "ossimTransMercatorProjection", "31 n", "110 10 w",
+                  10000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Arizona_Central", 26749, "ossimTransMercatorProjection", "31 n", "111 55 w",
+                  10000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Arizona_West", 26750, "ossimTransMercatorProjection", "31 n", "113 45 w",
+                  15000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Arkansas_North",  26751, "ossimLambertConformalConicProjection", "34 20 n", "92 w",
+                  "34 56 n", "36 14 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Arkansas_South",  26752, "ossimLambertConformalConicProjection", "32 40 n", "92 w",
+                  "33 18 n", "34 46 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Colorado_North",  26753, "ossimLambertConformalConicProjection", "39 20 n", "105 30 w",
+                  "39 43 n", "40 47 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Colorado_Central",26754, "ossimLambertConformalConicProjection", "37 50 n", "105 30 w",
+                  "38 27 n", "39 45 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Colorado_South",  26755, "ossimLambertConformalConicProjection", "36 40 n", "105 30 w",
+                  "37 14 n", "38 26 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Connecticut",   26756, "ossimLambertConformalConicProjection", "40 50 n", "72 45 w",
+                  "41 12 n", "41 52 n", 600000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Delaware",      26757, "ossimTransMercatorProjection", "38 n", "75 25 w",
+                  200000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Florida_East",  26758, "ossimTransMercatorProjection", "24 20 n", "81 w",
+                  17000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Florida_West",  26759, "ossimTransMercatorProjection", "24 20 n", "82 w",
+                  17000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Florida_North", 26760, "ossimLambertConformalConicProjection", "29 n", "84 30 w",
+                  "29 35 n", "30 45 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Hawaii_zone_1", 26761, "ossimTransMercatorProjection", "18 50 n", "155 30 w",
+                  30000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Hawaii_zone_2", 26762, "ossimTransMercatorProjection", "20 20 n","156 40 w",
+                  30000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Hawaii_zone_3", 26763, "ossimTransMercatorProjection", "21 10 n", "158 w",
+                  100000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Hawaii_zone_4", 26764, "ossimTransMercatorProjection", "21 50 n", "159 30 w",
+                  100000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Hawaii_zone_5", 26765, "ossimTransMercatorProjection", "21 40 n", "160 10 w",
+                  0.0, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Georgia_East",  26766, "ossimTransMercatorProjection", "30 n", "82 10 w",
+                  10000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Georgia_West",  26767, "ossimTransMercatorProjection", "30 n", "84 10 w",
+                  10000, 0, 500000, 0.0, "ft")); 
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Idaho_East",    26768, "ossimTransMercatorProjection", "41 40 n", "112 10 w",
+                  19000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Idaho_Central", 26769, "ossimTransMercatorProjection", "41 40 n", "114 w",
+                  19000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Idaho_West",    26770, "ossimTransMercatorProjection", "41 40 n", "115 45 w",
+                  15000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Illinois_East", 26771, "ossimTransMercatorProjection", "36 40 n", "88 20 w",
+                  40000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Illinois_West", 26772, "ossimTransMercatorProjection", "36 40 n", "90 10 w",
+                  17000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Indiana_East",  26773, "ossimTransMercatorProjection", "37 30 n", "85 40 w",
+                  30000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Indiana_West",  26774, "ossimTransMercatorProjection", "37 30 n", "87 05 w",
+                  30000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Iowa_North",    26775, "ossimLambertConformalConicProjection", "41 30 n", "93 30 w",
+                  "42 04 n", "43 16 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Iowa_South",    26776, "ossimLambertConformalConicProjection", "40 n", "93 30 w",
+                  "40 37 n", "41 47 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Kansas_North",  26777, "ossimLambertConformalConicProjection", "38 20 n", "98 00 w",
+                  "38 43 n", "39 47 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Kansas_South",  26778, "ossimLambertConformalConicProjection", "36 40 n", "98 30 w",
+                  "37 16 n", "38 34 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Kentucky_North",  26779, "ossimLambertConformalConicProjection", "37 30 n", "84 15 w",
+                  "37 58 n", "38 58 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Kentucky_South",  26780, "ossimLambertConformalConicProjection", "36 20 n", "85 45 w",
+                  "36 44 n", "37 56 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Louisiana_North", 26781, "ossimLambertConformalConicProjection", "30 40 n", "92 30 w",
+                  "31 10 n", "32 40 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Louisiana_South", 26782, "ossimLambertConformalConicProjection", "28 40 n", "91 20 w",
+                  "29 18 n", "30 42 n", 2000000, 0.0, "ft"));
+
+//   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Louisiana_Offshore", 0, "ossimLambertConformalConicProjection", "25 40 n", "91 20 w",
+//                                                       "26 10 n", "27 50 n", 2000000, 0.0, "ft"));
+
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Maine_East", 26783, "ossimTransMercatorProjection", "43 50 n", "68 30 w",
+                  10000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Maine_West", 26784, "ossimTransMercatorProjection", "42 50 n", "70 10 w",
+                  30000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Maryland",   26785, "ossimLambertConformalConicProjection", "37 50 n", "77 00 w",
+                  "38 18 n", "39 27 n", 800000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Massachusetts",   26786, "ossimLambertConformalConicProjection", "41 00 n", "71 30 w",
+                  "41 43 n", "42 41 n", 600000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Massachusetts_Is",26787, "ossimLambertConformalConicProjection", "41 00 n", "70 30 w",
+                  "41 17 n", "41 29 n", 200000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Michigan_North",  26788, "ossimLambertConformalConicProjection", "44 47 n", "87 w",
+                  "45 29 n", "47 05 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Michigan_Central",26789, "ossimLambertConformalConicProjection", "43 19 n", "84 20 w",
+                  "44 11 n", "45 42 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Michigan_South",  26790, "ossimLambertConformalConicProjection", "41 30 n", "84 20 w",
+                  "42 06 n", "43 40 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Minnesota_North", 26791, "ossimLambertConformalConicProjection", "46 30 n", "93 06 w",
+                  "47 02 n", "48 38 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Minnesota_Cent",  26792, "ossimLambertConformalConicProjection", "45 00 n", "94 15 w",
+                  "45 37 n", "47 03 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Minnesota_South", 26793, "ossimLambertConformalConicProjection", "43 00 n", "94 00 w",
+                  "43 47 n", "45 13 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Mississippi_East",26794, "ossimTransMercatorProjection", "29 40 n", "88 50 w",
+                  25000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Mississippi_West",26795, "ossimTransMercatorProjection", "30 30 n", "90 20 w",
+                  17000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Missouri_East",   26796, "ossimTransMercatorProjection", "35 50 n", "90 30 w",
+                  15000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Missouri_Central",26797, "ossimTransMercatorProjection", "35 50 n", "92 30 w",
+                  15000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Missouri_West",   26798, "ossimTransMercatorProjection", "36 10 n", "94 30 w",
+                  17000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD_Michigan_Old_East", 26801, "ossimTransMercatorProjection", "41 30 n", "83 40 w",
+                  17500, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD_Michigan_Old_Centr",26802, "ossimTransMercatorProjection", "41 30 n", "85 45 w",
+                  11000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD_Michigan_Old_West", 26803, "ossimTransMercatorProjection", "41 30 n", "88 45 w",
+                  11000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Montana_North",   32001, "ossimLambertConformalConicProjection", "47 00 n", "109 30 w",
+                  "47 51 n", "48 43 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Montana_Central", 32002, "ossimLambertConformalConicProjection", "45 50 n", "109 30 w",
+                  "46 27 n", "47 53 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Montana_South",   32003, "ossimLambertConformalConicProjection", "44 00 n", "109 30 w",
+                  "44 52 n", "46 24 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Nebraska_North",  32005, "ossimLambertConformalConicProjection", "41 20 n", "100 00 w",
+                  "41 51 n", "42 49 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Nebraska_South",  32006, "ossimLambertConformalConicProjection", "39 40 n", "99 30 w",
+                  "40 17 n", "41 43 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Nevada_East",     32007, "ossimTransMercatorProjection", "34 45 n", "115 35 w",
+                  10000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Nevada_Central",  32008, "ossimTransMercatorProjection", "34 45 n", "116 40 w",
+                  10000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Nevada_West",     32009, "ossimTransMercatorProjection", "34 45 n", "118 35 w",
+                  10000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_New_Hampshire",   32010, "ossimTransMercatorProjection", "42 30 n", "71 40 w",
+                  30000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_New_Jersey",      32011, "ossimTransMercatorProjection", "38 50 n", "74 40 w",
+                  40000, 0, 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_New_Mexico_East", 32012, "ossimTransMercatorProjection", "31 00 n", "104 20 w",
+                  11000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_New_Mexico_Cent", 32013, "ossimTransMercatorProjection", "31 00 n", "106 15 w",
+                  10000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_New_Mexico_West", 32014, "ossimTransMercatorProjection", "31 00 n", "107 50 w",
+                  12000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_New_York_East",   32015, "ossimTransMercatorProjection", "40 00 n", "74 20 w",
+                  30000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_New_York_Central",32016, "ossimTransMercatorProjection", "40 00 n", "76 35 w",
+                  16000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_New_York_West",   32017, "ossimTransMercatorProjection", "40 00 n", "78 35 w",
+                  16000, 0, 500000, 0.0, "ft"));
+   
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_New_York_Long_Is",32018, "ossimLambertConformalConicProjection", "40 30 n", "74 w",
+                  "40 40 n", "41 02 n", 2000000, 100000, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_North_Carolina",  32019, "ossimLambertConformalConicProjection", "33 45 n", "79 00 w",
+                  "34 20 n", "36 10 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_North_Dakota_N",  32020, "ossimLambertConformalConicProjection", "47 00 n", "100 30 w",
+                  "47 26 n", "48 44 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_North_Dakota_S",  32021, "ossimLambertConformalConicProjection", "45 40 n", "100 30 w",
+                  "46 11 n", "47 29 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Ohio_North",      32022, "ossimLambertConformalConicProjection", "39 40 n", "82 30 w",
+                  "40 26 n", "41 42 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Ohio_South",      32023, "ossimLambertConformalConicProjection", "38 00 n", "82 30 w",
+                  "38 44 n", "40 02 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Oklahoma_North",  32024, "ossimLambertConformalConicProjection", "35 00 n", "98 00 w",
+                  "35 34 n", "36 46 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Oklahoma_South",  32025, "ossimLambertConformalConicProjection", "33 20 n", "98 00 w",
+                  "33 56 n", "35 14 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Oregon_North",    32026, "ossimLambertConformalConicProjection", "43 40 n", "120 30 w",
+                  "44 20 n", "46 00 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Oregon_South",    32027, "ossimLambertConformalConicProjection", "41 40 n", "120 30 w",
+                  "42 20 n", "44 00 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Pennsylvania_N",  32028, "ossimLambertConformalConicProjection", "40 10 n", "77 45 w",
+                  "40 53 n", "41 57 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Pennsylvania_S",  32029, "ossimLambertConformalConicProjection", "39 20 n", "77 45 w",
+                  "39 56 n", "40 58 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Rhode_Island",    32030, "ossimTransMercatorProjection", "41 05 n", "71 30 w",
+                  160000, 0, 500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_South_Carolina_N",32031, "ossimLambertConformalConicProjection", "33 00 n", "81 00 w",
+                  "33 46 n", "34 58 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_South_Carolina_S",32033, "ossimLambertConformalConicProjection", "31 50 n", "81 00 w",
+                  "32 20 n", "33 40 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_South_Dakota_N",  32034, "ossimLambertConformalConicProjection", "43 50 n", "100 00 w",
+                  "44 25 n", "45 41 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_South_Dakota_S",  32035, "ossimLambertConformalConicProjection", "42 20 n", "100 20 w",
+                  "42 50 n", "44 24 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Tennessee",       32036, "ossimLambertConformalConicProjection", "34 40 n", "86 00 w",
+                  "35 15 n", "36 25 n", 2000000, 100000, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Texas_North",     32037, "ossimLambertConformalConicProjection", "34 00 n", "101 30 w",
+                  "34 39 n", "36 11 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Texas_North_Cen", 32038, "ossimLambertConformalConicProjection", "31 40 n", "97 30 w",
+                  "32 08 n", "33 58 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Texas_Central",   32039, "ossimLambertConformalConicProjection", "29 40 n", "100 20 w",
+                  "30 07 n", "31 53 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Texas_South_Cen", 32040, "ossimLambertConformalConicProjection", "27 50 n", "99 00 w",
+                  "28 23 n", "30 17 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Texas_South",     32041, "ossimLambertConformalConicProjection", "25 40 n", "98 30 w",
+                  "26 10 n", "27 50 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Utah_North",      32042, "ossimLambertConformalConicProjection", "40 20 n", "111 30 w",
+                  "40 43 n", "41 47 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Utah_Central",    32043, "ossimLambertConformalConicProjection", "38 20 n", "111 30 w",
+                  "39 01 n", "40 39 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Utah_South",      32044, "ossimLambertConformalConicProjection", "36 40 n", "111 30 w",
+                  "37 13 n", "38 21 n", 2000000, 0.0, "ft"));
+
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Vermont",  32045, "ossimTransMercatorProjection", "42 30 n", "72 30 w", 28000, 0,
+                  500000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Virginia_North",  32046, "ossimLambertConformalConicProjection", "37 40 n", "78 30 w",
+                  "38 02 n", "39 12 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Virginia_South",  32047, "ossimLambertConformalConicProjection", "36 20 n", "78 30 w",
+                  "36 46 n", "37 58 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Washington_North",32048, "ossimLambertConformalConicProjection", "47 00 n", "120 50 w",
+                  "47 30 n", "48 44 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Washington_South",32049, "ossimLambertConformalConicProjection", "45 20 n", "120 30 w",
+                  "45 50 n", "47 20 n", 2000000, 0.0, "ft"));
+   
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_West_Virginia_N", 32050, "ossimLambertConformalConicProjection", "38 30 n", "79 30 w",
+                  "39 00 n", "40 15 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_West_Virginia_S", 32051, "ossimLambertConformalConicProjection", "37 00 n", "81 00 w",
+                  "37 29 n", "38 53 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Wisconsin_North", 32052, "ossimLambertConformalConicProjection", "45 10 n", "90 00 w",
+                  "45 34 n", "46 46 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Wisconsin_Cen",   32053, "ossimLambertConformalConicProjection", "43 50 n", "90 00 w",
+                  "44 15 n", "45 30 n", 2000000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Wisconsin_South", 32054, "ossimLambertConformalConicProjection", "42 00 n", "90 00 w",
+                  "42 44 n", "44 04 n", 2000000, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Wyoming_East", 32055, "ossimTransMercatorProjection", "40 40 n", "105 10 w",
+                  17000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Wyoming_E_Cen", 32056, "ossimTransMercatorProjection", "40 40 n", "107 20 w",
+                  17000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Wyoming_W_Cen", 32057, "ossimTransMercatorProjection", "40 40 n", "108 45 w",
+                  17000, 0, 500000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Wyoming_West",  32058, "ossimTransMercatorProjection", "40 40 n", "110 05 w",
+                  17000, 0, 500000, 0.0, "ft"));
+   
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_Puerto_Rico",  32059, "ossimLambertConformalConicProjection", "17 50 n", "66 26 w",
+                  "18 02 n", "18 26 n", 500000, 0.0, "ft"));
+   
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD27_St_Croix",     32060, "ossimLambertConformalConicProjection", "17 50 n", "66 26 w",
+                  "18 02 n", "18 26 n", 500000, 100000, "ft"));
+
+
+   //***            
+   // NAD83 Datum based State Plane Projections
+   //***
+               
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alabama_East",  26929, "ossimTransMercatorProjection", "30 30 n", "85 50 w",
+                  25000, 0, 200000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alabama_West",  26930, "ossimTransMercatorProjection", "30 n", "87 30 w",
+                  15000, 0, 600000, 0.0, "m"));
+
+   // addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_1", 26931  UNSUPPORTED!
+   // (Hotine Mercator)
+   
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_2", 26932, "ossimTransMercatorProjection", "54 n", "142 w", 10000, 0,
+                  500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_3", 26933, "ossimTransMercatorProjection", "54 n", "146 w", 10000, 0,
+                  500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_4", 26934, "ossimTransMercatorProjection", "54 n", "150 w", 10000, 0,
+                  500000, 0.0, "m")); 
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_5", 26935, "ossimTransMercatorProjection", "54 n", "154 w", 10000, 0,
+                  500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_6", 26936, "ossimTransMercatorProjection", "54 n", "158 w", 10000, 0,
+                  500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_7", 26937, "ossimTransMercatorProjection", "54 n", "162 w", 10000, 0,
+                  500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_8", 26938, "ossimTransMercatorProjection", "54 n", "166 w", 10000, 0,
+                  500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_9", 26939, "ossimTransMercatorProjection", "54 n", "170 w", 10000, 0,
+                  500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Alaska_zone_10",26940, "ossimLambertConformalConicProjection", "51 n", "176 w",
+                  "51 50 n", "53 50 n", 1000000, 0.0, "m"));
+                              
+// California
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_California_1",  26941, "ossimLambertConformalConicProjection", "39 20 n", "122 w",
+                  "40 n", "41 40 n", 2000000, 500000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_California_2",  26942, "ossimLambertConformalConicProjection", "37 40 n", "122 w",
+                  "38 20 n", "39 50 n", 2000000, 500000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_California_3",  26943, "ossimLambertConformalConicProjection", "36 30 n", "120 30 w",
+                  "37 04 n", "38 26 n", 2000000, 500000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_California_4",  26944, "ossimLambertConformalConicProjection", "35 20 n", "119 w",
+                  "36 n", "37 15 n", 2000000, 500000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_California_5",  26945, "ossimLambertConformalConicProjection", "33 30 n", "118 w",
+                  "34 02 n", "35 28 n", 2000000, 500000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_California_6",  26946, "ossimLambertConformalConicProjection", "32 10", "116 15 w",
+                  "32 47 n", "33 53 n", 2000000, 500000, "m"));
+
+// Arizona
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Arizona_East",  26948, "ossimTransMercatorProjection", "31 n", "110 10 w",
+                  10000, 0, 213360, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Arizona_Centr", 26949, "ossimTransMercatorProjection", "31 n", "111 55 w",
+                  10000, 0, 213360, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Arizona_West", 26950, "ossimTransMercatorProjection", "31 n", "113 45 w",
+                  15000, 0, 213360, 0.0, "ft"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Arkansas_North", 26951, "ossimLambertConformalConicProjection", "34 20 n", "92 w",
+                  "34 56 n", "36 14 n", 400000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Arkansas_South", 26952, "ossimLambertConformalConicProjection", "32 40 n", "92 w",
+                  "33 18 n", "34 46 n", 400000, 400000, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Colorado_North",  26953, "ossimLambertConformalConicProjection", "39 20 n", "105 30 w",
+                  "39 43 n", "40 47 n", 914401.8289, 304800.6096, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Colorado_Centr",  26954, "ossimLambertConformalConicProjection", "37 50 n", "105 30 w",
+                  "38 27 n", "39 45 n", 914401.8289, 304800.6096, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Colorado_South",  26955, "ossimLambertConformalConicProjection", "36 40 n", "105 30 w",
+                  "37 14 n", "38 26 n", 914401.8289, 304800.6096, "m"));
+
+               
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Connecticut",   26956, "ossimLambertConformalConicProjection",  "40 50 n", "72 45 w",
+                  "41 12 n", "41 52 n", 304800.6096, 152400.3048, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Delaware",  26957, "ossimTransMercatorProjection", "38 n", "75 25 w", 200000, 0,
+                  200000, 0.0, "m"));
+
+// Florida
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Florida_East",  26958, "ossimTransMercatorProjection", "24 20 n", "81 w",
+                  17000, 0, 200000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Florida_West",  26959, "ossimTransMercatorProjection", "24 20 n", "82 w",
+                  17000, 0, 200000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Florida_North", 26960, "ossimLambertConformalConicProjection", "29 n", "84 30 w",
+                  "29 35 n", "30 45 n", 600000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Hawaii_zone_1", 26961, "ossimTransMercatorProjection", "18 50 n", "155 30 w",
+                  30000, 0, 500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Hawaii_zone_2", 26962, "ossimTransMercatorProjection", "20 20 n","156 40 w",
+                  30000, 0, 500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Hawaii_zone_3", 26963, "ossimTransMercatorProjection", "21 10 n", "158 w",
+                  100000, 0, 500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Hawaii_zone_4", 26964, "ossimTransMercatorProjection", "21 50 n", "159 30 w",
+                  100000, 0, 500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Hawaii_zone_5", 26965, "ossimTransMercatorProjection", "21 40 n", "160 10 w",
+                  0.0, 0, 500000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Georgia_East",  26966, "ossimTransMercatorProjection", "30 n", "82 10 w",
+                  10000, 0, 200000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Georgia_West",  26967, "ossimTransMercatorProjection", "30 n", "84 10 w",
+                  10000, 0, 700000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Idaho_East",    26968, "ossimTransMercatorProjection", "41 40 n", "112 10 w",
+                  19000, 0, 200000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Idaho_Central", 26969, "ossimTransMercatorProjection", "41 40 n", "114 w",
+                  19000, 0, 500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Idaho_West",    26970, "ossimTransMercatorProjection", "41 40 n", "115 45 w",
+                  15000, 0, 800000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Illinois_East", 26971, "ossimTransMercatorProjection", "36 40 n", "88 20 w",
+                  40000, 0, 300000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Illinois_West", 26972, "ossimTransMercatorProjection", "36 40 n", "90 10 w",
+                  17000, 0, 700000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Indiana_East",  26973, "ossimTransMercatorProjection", "37 30 n", "85 40 w",
+                  30000, 0, 100000, 250000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Indiana_West",  26974, "ossimTransMercatorProjection", "37 30 n", "87 05 w",
+                  30000, 0, 900000, 250000, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Iowa_North",  26975, "ossimLambertConformalConicProjection", "41 30 n", "93 30 w",
+                  "42 04 n", "43 16 n", 1500000, 1000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Iowa_South",  26976, "ossimLambertConformalConicProjection", "40 n", "93 30 w",
+                  "40 37 n", "41 47 n", 500000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Kansas_North",  26977, "ossimLambertConformalConicProjection", "38 20 n", "98 00 w",
+                  "38 43 n", "39 47 n", 400000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Kansas_South",  26978, "ossimLambertConformalConicProjection", "36 40 n", "98 30 w",
+                  "37 16 n", "38 34 n", 400000, 400000, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Kentucky_North",  26979, "ossimLambertConformalConicProjection", "37 30 n", "84 15 w",
+                  "37 58 n", "38 58 n", 500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Kentucky_South",  26980, "ossimLambertConformalConicProjection", "36 20 n", "85 45 w",
+                  "36 44 n", "37 56 n", 500000, 500000, "m"));
+
+   // Louisiana
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Louisiana_North", 26981, "ossimLambertConformalConicProjection", "30 30 n", "92 30 w",
+                  "31 10 n", "32 40 n", 1000000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Louisiana_South", 26982, "ossimLambertConformalConicProjection", "28 30 n", "91 20 w",
+                  "29 18 n", "30 42 n", 1000000, 0.0, "m"));
+
+//   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Louisiana_Offshore", 0, "ossimLambertConformalConicProjection", "25 30 n", "91 20 w",
+//                  "26 10 n", "27 50 n", 1000000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Maine_East", 26983, "ossimTransMercatorProjection", "43 40 n", "68 30 w",
+                  10000, 0, 300000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Maine_West", 26984, "ossimTransMercatorProjection", "42 50 n", "70 10 w",
+                  30000, 0, 900000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Maryland", 26985, "ossimLambertConformalConicProjection","37 40 n", "77 00 w",
+                  "38 18 n", "39 27 n", 400000, 0.0, "m"));
+                              
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Massachusetts",   26986, "ossimLambertConformalConicProjection",  "41 00 n", "71 30 w",
+                  "41 43 n", "42 41 n", 200000, 750000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Massachusetts_Is", 26987, "ossimLambertConformalConicProjection", "41 00 n", "70 30 w",
+                  "41 17 n", "41 29 n", 500000, 0.0, "m"));
+                              
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Michigan_North",  26988, "ossimLambertConformalConicProjection", "44 47 n", "87 w",
+                  "45 29 n", "47 05 n", 8000000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Michigan_Central",26989, "ossimLambertConformalConicProjection", "43 19 n", "84 22 w",
+                  "44 11 n", "45 42 n", 6000000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Michigan_South",  26990, "ossimLambertConformalConicProjection", "41 30 n", "84 22 w",
+                  "42 06 n", "43 40 n", 4000000, 0.0, "m")); 
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Minnesota_North", 26991, "ossimLambertConformalConicProjection", "46 30 n", "93 06 w",
+                  "47 02 n", "48 38 n", 800000, 100000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Minnesota_Cent",  26992, "ossimLambertConformalConicProjection", "45 00 n", "94 15 w",
+                  "45 37 n", "47 03 n", 800000, 100000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Minnesota_South", 26993, "ossimLambertConformalConicProjection", "43 00 n", "94 00 w",
+                  "43 47 n", "45 13 n", 800000, 100000, "m"));
+   
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Mississippi_East",26994, "ossimTransMercatorProjection", "29 30 n", "88 50 w",
+                  20000, 0, 300000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Mississippi_West",26995, "ossimTransMercatorProjection", "29 30 n", "90 20 w",
+                  20000, 0, 700000, 0.0, "m"));
+                              
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Missouri_East",   26996, "ossimTransMercatorProjection", "35 50 n", "90 30 w",
+                  15000, 0, 250000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Missouri_Central",26997, "ossimTransMercatorProjection", "35 50 n", "92 30 w",
+                  15000, 0, 500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Missouri_West",   26998, "ossimTransMercatorProjection", "36 10 n", "94 30 w",
+                  17000, 0, 850000, 0.0, "m"));
+                              
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Montana",  32100, "ossimLambertConformalConicProjection", "44 15 n", "109 30 w",
+                  "45 00 n", "49 00 n", 600000, 0.0, "m"));
+                              
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Nebraska", 32104, "ossimLambertConformalConicProjection", "39 50 n", "100 00 w",
+                  "40 00 n", "43 00 n", 500000, 0.0, "m"));
+                                                            
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Nevada_East",     32107, "ossimTransMercatorProjection",  "34 45 n", "115 35 w",
+                  10000, 0, 200000, 8000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Nevada_Central",  32108, "ossimTransMercatorProjection", "34 45 n", "116 40 w",
+                  10000, 0, 500000, 6000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Nevada_West",     32109, "ossimTransMercatorProjection", "34 45 n", "118 35 w",
+                  10000, 0, 800000, 4000000, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_New_Hampshire",   32110, "ossimTransMercatorProjection", "42 30 n", "71 40 w",
+                  30000, 0, 300000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_New_Jersey",      32111, "ossimTransMercatorProjection", "38 50 n", "74 30 w",
+                  10000, 0, 150000, 0.0, "m"));
+
+   // AddStatePlaneMapInfo(New Mexico
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_New_Mexico_East", 32112, "ossimTransMercatorProjection", "31 00 n", "104 20 w",
+                  11000, 0, 165000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_New_Mexico_Cent", 32113, "ossimTransMercatorProjection", "31 00 n", "106 15 w",
+                  10000, 0, 500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_New_Mexico_West", 32114, "ossimTransMercatorProjection", "31 00 n", "107 50 w",
+                  12000, 0, 830000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_New_York_East",   32115, "ossimTransMercatorProjection", "38 50 n", "74 30 w",
+                  10000, 0, 150000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_New_York_Central",32116, "ossimTransMercatorProjection", "40 00 n", "76 35 w",
+                  16000, 0, 250000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_New_York_West",   32117, "ossimTransMercatorProjection", "40 00 n", "78 35 w",
+                  16000, 0, 350000, 0.0, "ft"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_New_York_Long_Is",32118, "ossimLambertConformalConicProjection", "40 10 n", "74 w",
+                  "40 40 n", "41 02 n", 300000, 0.0, "m"));
+   
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_North_Carolina",  32119, "ossimLambertConformalConicProjection", "33 45 n", "79 00 w",
+                  "34 20 n", "36 10 n", 609601.22, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_North_Dakota_N",  32120, "ossimLambertConformalConicProjection", "47 00 n", "100 30 w",
+                  "47 26 n", "48 44 n", 600000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_North_Dakota_S",  32121, "ossimLambertConformalConicProjection", "45 40 n", "100 30 w",
+                  "46 11 n", "47 29 n", 600000, 0.0, "m"));
+
+   // Ohio
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Ohio_North",      32122, "ossimLambertConformalConicProjection",  "39 40 n", "82 30 w",
+                  "40 26 n", "41 42 n", 600000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Ohio_South",      32123, "ossimLambertConformalConicProjection", "38 00 n", "82 30 w",
+                  "38 44 n", "40 02 n", 600000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Oklahoma_North",  32124, "ossimLambertConformalConicProjection",  "35 00 n", "98 00 w",
+                  "35 34 n", "36 46 n", 600000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Oklahoma_South",  32125, "ossimLambertConformalConicProjection", "33 20 n", "98 00 w",
+                  "33 56 n", "35 14 n", 600000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Oregon_North",    32126, "ossimLambertConformalConicProjection",  "43 40 n",
+                  "120 30 w", "44 20 n", "46 00 n", 2500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Oregon_South",    32127, "ossimLambertConformalConicProjection", "41 40 n", "120 30 w",
+                  "42 20 n", "44 00 n", 1500000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Pennsylvania_N",  32128, "ossimLambertConformalConicProjection", "40 10 n", "77 45 w",
+                  "40 53 n", "41 57 n", 600000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Pennsylvania_S",  32129, "ossimLambertConformalConicProjection", "39 20 n", "77 45 w",
+                  "39 56 n", "40 58 n", 600000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Rhode_Island", 32130, "ossimTransMercatorProjection", "41 05 n", "71 30 w",
+                  160000, 0, 100000, 0.0, "m")); 
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_South_Carolina",  32133, "ossimLambertConformalConicProjection",  "31 50 n", "81 00 w",
+                  "32 30 n", "34 50 n", 609600, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_South_Dakota_N",  32134, "ossimLambertConformalConicProjection", "43 50 n", "100 00 w",
+                  "44 25 n", "45 41 n", 600000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_South_Dakota_S",  32135, "ossimLambertConformalConicProjection", "42 20 n", "100 20 w",
+                  "42 50 n", "44 24 n", 600000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Tennessee",       32136, "ossimLambertConformalConicProjection", "34 20 n", "86 00 w",
+                  "35 15 n", "36 25 n", 600000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Texas_North",     32137, "ossimLambertConformalConicProjection", "34 00 n", "101 30 w",
+                  "34 39 n", "36 11 n", 200000, 1000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Texas_North_Cen", 32138, "ossimLambertConformalConicProjection", "31 40 n", "98 30 w",
+                  "32 08 n", "33 58 n", 600000, 2000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Texas_Central",   32139, "ossimLambertConformalConicProjection", "29 40 n", "100 20 w",
+                  "30 07 n", "31 53 n", 700000, 3000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Texas_South_Cen", 32140, "ossimLambertConformalConicProjection", "27 50 n", "99 00 w",
+                  "28 23 n", "30 17 n", 600000, 4000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Texas_South",     32141, "ossimLambertConformalConicProjection", "25 40 n", "98 30 w",
+                  "26 10 n", "27 50 n", 300000, 5000000, "m"));
+   
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Utah_North",      32142, "ossimLambertConformalConicProjection", "40 20 n", "111 30 w",
+                  "40 43 n", "41 47 n", 500000, 1000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Utah_Central",    32143, "ossimLambertConformalConicProjection", "38 20 n", "111 30 w",
+                  "39 01 n", "40 39 n", 500000, 2000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Utah_South",      32144, "ossimLambertConformalConicProjection", "36 40 n", "111 30 w",
+                  "37 13 n", "38 21 n", 500000, 3000000, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Vermont",  32145, "ossimTransMercatorProjection", "42 30 n", "72 30 w", 28000, 0,
+                  500000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Virginia_North",  32146, "ossimLambertConformalConicProjection", "37 40 n", "78 30 w",
+                  "38 02 n", "39 12 n", 3500000, 2000000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Virginia_South",  32147, "ossimLambertConformalConicProjection", "36 20 n", "78 30 w",
+                  "36 46 n", "37 58 n", 3500000, 1000000, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Washington_North",32148, "ossimLambertConformalConicProjection", "47 00 n", "120 50 w",
+                  "47 30 n", "48 44 n", 500000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Washington_South",32149, "ossimLambertConformalConicProjection", "45 20 n", "120 30 w",
+                  "45 50 n", "47 20 n", 500000, 0.0, "m"));
+
+   // West Virginia
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_West_Virginia_N", 32150, "ossimLambertConformalConicProjection", "38 30 n", "79 30 w",
+                  "39 00 n", "40 15 n", 600000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_West_Virginia_S", 32151, "ossimLambertConformalConicProjection", "37 00 n", "81 00 w",
+                  "37 29 n", "38 53 n", 600000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Wisconsin_North", 32152, "ossimLambertConformalConicProjection", "45 10 n", "90 00 w",
+                  "45 34 n", "46 46 n", 600000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Wisconsin_Cen",   32153, "ossimLambertConformalConicProjection", "43 50 n", "90 00 w",
+                  "44 15 n", "45 30 n", 600000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Wisconsin_South", 32154, "ossimLambertConformalConicProjection", "42 00 n", "90 00 w",
+                  "42 44 n", "44 04 n", 600000, 0.0, "m"));
+
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Wyoming_East",  32155, "ossimTransMercatorProjection", "40 30 n", "105 10 w",
+                  16000, 0, 200000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Wyoming_E_Cen", 32156, "ossimTransMercatorProjection", "40 30 n", "107 20 w",
+                  16000, 0, 400000, 100000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Wyoming_W_Cen", 32157, "ossimTransMercatorProjection", "40 30 n", "108 45 w",
+                  16000, 0, 600000, 0.0, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo("NAD83_Wyoming_West",  32158, "ossimTransMercatorProjection", "40 30 n", "110 05 w",
+                  16000, 0, 800000, 100000, "m"));
+   addStatePlaneInfo(new ossimStatePlaneProjectionInfo ("NAD83_Puerto_Rico", 32161, "ossimLambertConformalConicProjection", "17 50 n", "66 26 w",
+                  "18 02 n", "18 26 n", 200000, 200000, "m"));
+}
+
+//---
+// Hidden from use stuff.
+//---
+ossimStatePlaneProjectionFactory::ossimStatePlaneProjectionFactory()
+   : ossimProjectionFactoryBase()
+{}
+
+ossimStatePlaneProjectionFactory::ossimStatePlaneProjectionFactory(const ossimStatePlaneProjectionFactory&)
+   : ossimProjectionFactoryBase()
+{}
+
+void ossimStatePlaneProjectionFactory::operator=(const ossimStatePlaneProjectionFactory& /* rhs */)
+{}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimStatePlaneProjectionFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimStatePlaneProjectionFactory.h
new file mode 100644
index 0000000000..03cfa66c1b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimStatePlaneProjectionFactory.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//*******************************************************************
+//  $Id: ossimStatePlaneProjectionFactory.h,v 1.9 2004/09/24 17:19:40 dburken Exp $
+#ifndef ossimStatePlaneProjectionFactory_HEADER
+#define ossimStatePlaneProjectionFactory_HEADER
+#include "ossimProjectionFactoryBase.h"
+class ossimStatePlaneProjectionInfo;
+
+class OSSIMDLLEXPORT ossimStatePlaneProjectionFactory : public ossimProjectionFactoryBase
+{
+public:
+   static ossimStatePlaneProjectionFactory* instance();
+   virtual ~ossimStatePlaneProjectionFactory();
+   virtual ossimProjection* createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const;
+   virtual ossimProjection* createProjection(const ossimString& name)const;
+   virtual ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                             const char* prefix=0)const;
+   const ossimStatePlaneProjectionInfo* getInfo(ossim_int32 pcsCode)const;
+   const ossimStatePlaneProjectionInfo* getInfo(const ossimString& name)const;
+   virtual std::list<ossimString> getList()const;
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+   
+   bool  addStatePlaneInfo(ossimStatePlaneProjectionInfo* info);
+protected:
+   ossimStatePlaneProjectionFactory();
+   ossimStatePlaneProjectionFactory(const ossimStatePlaneProjectionFactory&);
+   void operator =(const ossimStatePlaneProjectionFactory& rhs);
+   
+   static ossimStatePlaneProjectionFactory* theInstance;
+
+   std::map<ossim_int32, ossimStatePlaneProjectionInfo*> theStatePlaneInfoMap;
+   std::map<ossimString, ossimStatePlaneProjectionInfo*> theStatePlaneInfoNameMap;
+
+   void initializeMap();
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimTiffProjectionFactory.cpp b/Utilities/OSSIM/ossim_core/projections/factory/ossimTiffProjectionFactory.cpp
new file mode 100644
index 0000000000..bbcfeb5cdc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimTiffProjectionFactory.cpp
@@ -0,0 +1,133 @@
+//*****************************************************************************
+// FILE: ossimTiffProjectionFactory.cc
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimTiffProjectionFactory
+//
+//*****************************************************************************
+//  $Id: ossimTiffProjectionFactory.cpp,v 1.3 2004/09/24 17:19:40 dburken Exp $
+
+#include "ossimTiffProjectionFactory.h"
+#include "support_data/tiff/ossimGeoTiff.h"
+#include "ossimProjectionFactoryRegistry.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/data_types/ossimFilename.h"
+#include "projections/ossimProjection.h"
+#include <fstream>
+
+ossimTiffProjectionFactory* ossimTiffProjectionFactory::theInstance = 0;
+
+//*****************************************************************************
+//  STATIC METHOD: ossimTiffProjectionFactory::instance()
+//  
+//*****************************************************************************
+ossimTiffProjectionFactory* ossimTiffProjectionFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimTiffProjectionFactory;
+   }
+
+   return (ossimTiffProjectionFactory*) theInstance;
+}
+
+ossimProjection*
+ossimTiffProjectionFactory::createProjection(const ossimFilename& filename,
+                                              ossim_uint32 entryIdx)const
+{
+   if(!filename.exists())
+   {
+      return NULL;
+   }
+
+   // See if there is an external geomtry.
+   ossimProjection* result = createProjectionFromGeometryFile(filename,
+                                                              entryIdx);
+   if (result)
+   {
+      return result;
+   }
+
+   if(isTiff(filename))
+   {
+      ossimGeoTiff geotiff(filename);
+      ossimKeywordlist kwl;
+      
+      if(geotiff.addImageGeometry(kwl))
+      {
+         return ossimProjectionFactoryRegistry::instance()->
+            createProjection(kwl);
+      }
+   }
+   
+   return NULL;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSensorModelFactory::create(kwl, prefix)
+//  
+//*****************************************************************************
+ossimProjection*
+ossimTiffProjectionFactory::createProjection(const ossimKeywordlist &keywordList,
+                                            const char *prefix) const
+{
+   return NULL;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSensorModelFactory::create(projection_name)
+//  
+//*****************************************************************************
+ossimProjection* ossimTiffProjectionFactory::createProjection(const ossimString &name) const
+{
+   return NULL;
+}
+
+ossimObject* ossimTiffProjectionFactory::createObject(const ossimString& typeName)const
+{
+   return (ossimObject*)createProjection(typeName);
+}
+
+ossimObject* ossimTiffProjectionFactory::createObject(const ossimKeywordlist& kwl,
+                                                     const char* prefix)const
+{
+   return createProjection(kwl, prefix);
+}
+
+void ossimTiffProjectionFactory::getTypeNameList(std::vector<ossimString>& typeList)const
+{
+   
+}
+
+list<ossimString> ossimTiffProjectionFactory::getList()const
+{
+   list<ossimString> result;
+
+   
+   return result;
+}
+
+bool ossimTiffProjectionFactory::isTiff(const ossimFilename& filename)const
+{
+   std::ifstream in;
+   unsigned char header[2];
+
+   in.open( filename.c_str(), ios::in|ios::binary);
+   if( !in)
+       return false;
+
+   in.read( (char*)header, 2);
+
+   if( (header[0] != 'M' || header[1] != 'M')
+       && (header[0] != 'I' || header[1] != 'I') )
+   {
+      return false;
+   }
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/factory/ossimTiffProjectionFactory.h b/Utilities/OSSIM/ossim_core/projections/factory/ossimTiffProjectionFactory.h
new file mode 100644
index 0000000000..7e966b5aff
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/factory/ossimTiffProjectionFactory.h
@@ -0,0 +1,75 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// class ossimProjectionFactory maintains a static list of projection
+// makers.  If a user wants to create a projection they can pass in
+// a projection name and a datum if desired.  Currently the default
+// datum will be WGS84.
+//*******************************************************************
+//  $Id: ossimTiffProjectionFactory.h,v 1.3 2004/09/24 17:19:40 dburken Exp $
+
+#ifndef ossimTiffProjectionFactory_HEADER
+#define ossimTiffProjectionFactory_HEADER
+
+#include "ossimProjectionFactoryBase.h"
+
+class ossimProjection;
+class ossimString;
+
+class ossimTiffProjectionFactory : public ossimProjectionFactoryBase
+{
+public:
+   /*!
+    * METHOD: instance()
+    * Instantiates singleton instance of this class:
+    */
+   static ossimTiffProjectionFactory* instance();
+
+   virtual ossimProjection* createProjection(const ossimFilename& filename,
+                                             ossim_uint32 entryIdx)const;
+   /*!
+    * METHOD: create()
+    * Attempts to create an instance of the projection specified by name.
+    * Returns successfully constructed projection or NULL.
+    */
+   virtual ossimProjection* createProjection(const ossimString& name)const;
+   virtual ossimProjection* createProjection(const ossimKeywordlist& kwl,
+                                             const char* prefix = 0)const;
+
+   virtual ossimObject* createObject(const ossimString& typeName)const;
+
+   /*!
+    * Creates and object given a keyword list.
+    */
+   virtual ossimObject* createObject(const ossimKeywordlist& kwl,
+                                     const char* prefix=0)const;
+   
+   /*!
+    * This should return the type name of all objects in all factories.
+    * This is the name used to construct the objects dynamially and this
+    * name must be unique.
+    */
+   virtual void getTypeNameList(std::vector<ossimString>& typeList)const;
+
+   /*!
+    * METHOD: getList()
+    * Returns list of all projections represented by this factory:
+    */
+   virtual list<ossimString> getList()const;
+
+protected:
+   ossimTiffProjectionFactory() {}
+   static ossimTiffProjectionFactory*  theInstance;
+
+   bool isTiff(const ossimFilename& filename)const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/.cvsignore b/Utilities/OSSIM/ossim_core/projections/map_projections/.cvsignore
new file mode 100644
index 0000000000..7df3918588
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+Makefile
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAlbersProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAlbersProjection.cpp
new file mode 100644
index 0000000000..3d4ab0264b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAlbersProjection.cpp
@@ -0,0 +1,660 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Albers projection code.  
+//*******************************************************************
+//  $Id: ossimAlbersProjection.cpp,v 1.17 2005/09/09 19:23:58 gpotts Exp $
+
+#include "ossimAlbersProjection.h"
+
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimAlbersProjection, "ossimAlbersProjection", ossimMapProjection)
+
+#ifdef PI_OVER_2
+#  undef PI_OVER_2
+#endif   
+
+#define ALBERS_NO_ERROR           0x0000
+#define ALBERS_LAT_ERROR          0x0001
+#define ALBERS_LON_ERROR          0x0002
+#define ALBERS_EASTING_ERROR      0x0004
+#define ALBERS_NORTHING_ERROR     0x0008
+#define ALBERS_ORIGIN_LAT_ERROR   0x0010
+#define ALBERS_CENT_MER_ERROR     0x0020
+#define ALBERS_A_ERROR            0x0040
+#define ALBERS_INV_F_ERROR        0x0080
+#define ALBERS_FIRST_STDP_ERROR   0x0100
+#define ALBERS_SECOND_STDP_ERROR  0x0200
+#define ALBERS_FIRST_SECOND_ERROR 0x0400
+#define ALBERS_HEMISPHERE_ERROR   0x0800
+
+#define PI_OVER_2  ( M_PI / 2.0)                 
+#define ES_SIN(sinlat)          (es * sinlat)
+#define ONE_MINUS_SQR(x)        (1.0 - x * x)
+#define ALBERS_M(clat,oneminussqressin)   (clat / sqrt(oneminussqressin))
+#define ALBERS_Q(slat,oneminussqressin,essin) (one_MINUS_es2)*(slat / (oneminussqressin)-    \
+											  (1 / (two_es)) *log((1 - essin) / (1 + essin)))
+
+
+ossimAlbersProjection::ossimAlbersProjection(const ossimEllipsoid& ellipsoid,
+                                             const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Albers_Delta_Northing = 40000000.0;
+   Albers_Delta_Easting  = 40000000.0;
+   setDefaults();
+   update();
+}
+    
+ossimAlbersProjection::ossimAlbersProjection(const ossimEllipsoid& ellipsoid,
+                                             const ossimGpt& origin,
+                                             double stdParallel1,
+                                             double stdParallel2,
+                                             double falseEasting,
+                                             double falseNorthing)
+  :ossimMapProjection(ellipsoid, origin)
+{
+   Albers_Std_Parallel_1 = stdParallel1*RAD_PER_DEG;
+   Albers_Std_Parallel_2 = stdParallel2*RAD_PER_DEG;
+   Albers_Delta_Northing = 40000000.0;
+   Albers_Delta_Easting  = 40000000.0;
+   Albers_False_Easting  = falseEasting;
+   Albers_False_Northing = falseNorthing;
+   
+   update();
+   
+}
+
+ossimObject* ossimAlbersProjection::dup() const
+{
+   return new ossimAlbersProjection(*this);
+}
+
+ossimAlbersProjection::~ossimAlbersProjection()
+{
+}
+
+void ossimAlbersProjection::update()
+{
+   Set_Albers_Parameters(theEllipsoid.getA(),
+                         theEllipsoid.getFlattening(),
+                         theOrigin.latr(),
+                         theOrigin.lonr(),
+                         Albers_Std_Parallel_1,
+                         Albers_Std_Parallel_2,
+                         Albers_False_Easting,
+                         Albers_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+
+ossimGpt ossimAlbersProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat, lon;
+   
+   
+   Convert_Albers_To_Geodetic(eastingNorthing.x,
+                              eastingNorthing.y,
+                              &lat,
+                              &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0, theDatum);
+}
+
+ossimDpt ossimAlbersProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+
+   Convert_Geodetic_To_Albers(gpt.latr(),
+                              gpt.lonr(),
+                              &easting,
+                              &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+void ossimAlbersProjection::setStandardParallel1(double degree)
+{
+   Albers_Std_Parallel_1 = degree*RAD_PER_DEG;
+   update();
+}
+
+void ossimAlbersProjection::setStandardParallel2(double degree)
+{
+   Albers_Std_Parallel_2 = degree*RAD_PER_DEG;
+   update();
+}
+
+void ossimAlbersProjection::setStandardParallels(double parallel1Degree,
+                                                 double parallel2Degree)
+{
+   Albers_Std_Parallel_1 = parallel1Degree*RAD_PER_DEG;
+   Albers_Std_Parallel_2 = parallel2Degree*RAD_PER_DEG;
+   update();
+   
+}
+
+void ossimAlbersProjection::setFalseEasting(double falseEasting)
+{
+   Albers_False_Easting = falseEasting;
+   update();
+}
+
+void ossimAlbersProjection::setFalseNorthing(double falseNorthing)
+{
+   Albers_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimAlbersProjection::setFalseEastingNorthing(double falseEasting,
+                                                    double falseNorthing)
+{
+   Albers_False_Easting = falseEasting;
+   Albers_False_Northing = falseNorthing;  
+   update();
+}
+
+void ossimAlbersProjection::setParameters(double parallel1,
+                                          double parallel2,
+                                          double falseEasting,
+                                          double falseNorthing)
+{
+   Albers_False_Easting = falseEasting;
+   Albers_False_Northing = falseNorthing;  
+   Albers_Std_Parallel_1 = parallel1*RAD_PER_DEG;
+   Albers_Std_Parallel_2 = parallel2*RAD_PER_DEG;
+   update(); 
+}
+
+double ossimAlbersProjection::getStandardParallel1()const
+{
+   return  Albers_Std_Parallel_1;
+}
+
+double ossimAlbersProjection::getStandardParallel2()const
+{
+   return  Albers_Std_Parallel_2;
+}
+
+double ossimAlbersProjection::getFalseEasting()const
+{
+   return Albers_False_Easting;
+}
+
+double ossimAlbersProjection::getFalseNorthing()const
+{
+   return Albers_False_Northing;
+}
+
+void ossimAlbersProjection::setDefaults()
+{
+
+   // initialize to some default
+   //
+   Albers_Std_Parallel_1 = 29.5*RAD_PER_DEG;
+   Albers_Std_Parallel_2 = 45.5*RAD_PER_DEG;
+   Albers_False_Easting  = 0.0;
+   Albers_False_Northing = 0.0;  
+}
+
+bool ossimAlbersProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::STD_PARALLEL_1_KW,
+           Albers_Std_Parallel_1*DEG_PER_RAD,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::STD_PARALLEL_2_KW,
+           Albers_Std_Parallel_2*DEG_PER_RAD,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Albers_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Albers_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimAlbersProjection::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   const char* stdParallel1  = kwl.find(prefix, ossimKeywordNames::STD_PARALLEL_1_KW);
+   const char* stdParallel2  = kwl.find(prefix, ossimKeywordNames::STD_PARALLEL_2_KW);
+
+   
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimAlbersProjection))
+   {
+      if(falseEasting)
+      {
+         Albers_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Albers_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+      if(stdParallel1)
+      {
+         Albers_Std_Parallel_1 = ossimString(stdParallel1).toDouble()*RAD_PER_DEG;
+      }
+      else
+      {
+         Albers_Std_Parallel_1 = 29.5*RAD_PER_DEG;         
+      }
+      if(stdParallel2)
+      {
+         Albers_Std_Parallel_2 = ossimString(stdParallel2).toDouble()*RAD_PER_DEG;
+      }
+      else
+      {
+         Albers_Std_Parallel_2 = 45.5*RAD_PER_DEG;
+      }
+   }
+
+   update();
+   
+   return flag;
+}
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS
+ */
+long ossimAlbersProjection::Set_Albers_Parameters(double a,
+                                                  double f,
+                                                  double Origin_Latitude,
+                                                  double Central_Meridian,
+                                                  double Std_Parallel_1,
+                                                  double Std_Parallel_2,
+                                                  double False_Easting,
+                                                  double False_Northing)
+
+{
+/*
+ * The function Set_Albers_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise ALBERS_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    Std_Parallel_1    : First standard parallel                   (input)
+ *    Std_Parallel_2    : Second standard parallel                  (input)
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double sin_lat, sin_lat_1, cos_lat;
+  double m1, m2, SQRm1;
+  double q0, q1, q2;
+  double es_sin, one_MINUS_SQRes_sin;
+  double nq0;
+  double inv_f = 1 / f;
+  long Error_Code = ALBERS_NO_ERROR;
+
+  if (a <= 0.0)
+  { /* Semi-major axis must be greater than zero */
+    Error_Code |= ALBERS_A_ERROR;
+  }
+  if ((inv_f < 250) || (inv_f > 350))
+  { /* Inverse flattening must be between 250 and 350 */
+    Error_Code |= ALBERS_INV_F_ERROR;
+  }
+  if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+  { /* origin latitude out of range */
+    Error_Code |= ALBERS_ORIGIN_LAT_ERROR;
+  }
+  if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
+  { /* origin longitude out of range */
+    Error_Code |= ALBERS_CENT_MER_ERROR;
+  }
+  if ((Std_Parallel_1 < -PI_OVER_2) || (Std_Parallel_1 > PI_OVER_2))
+  { /* First Standard Parallel out of range */
+    Error_Code |= ALBERS_FIRST_STDP_ERROR;
+  }
+  if ((Std_Parallel_2 < -PI_OVER_2) || (Std_Parallel_2 > PI_OVER_2))
+  { /* Second Standard Parallel out of range */
+    Error_Code |= ALBERS_SECOND_STDP_ERROR;
+  }
+  if ((Std_Parallel_1 == 0.0) && (Std_Parallel_2 == 0.0))
+  { /* First & Second Standard Parallels equal 0 */
+    Error_Code |= ALBERS_FIRST_SECOND_ERROR;
+  }
+  if (Std_Parallel_1 == -Std_Parallel_2)
+  { /* Parallels are opposite latitudes */
+    Error_Code |= ALBERS_HEMISPHERE_ERROR;
+  }
+
+  if (!Error_Code)
+  { /* no errors */
+    Albers_a = a;
+    Albers_f = f;
+    Albers_Origin_Lat = Origin_Latitude;
+    Albers_Std_Parallel_1 = Std_Parallel_1;
+    Albers_Std_Parallel_2 = Std_Parallel_2;
+    if (Central_Meridian > M_PI)
+      Central_Meridian -= TWO_PI;
+    Albers_Origin_Long = Central_Meridian;
+    Albers_False_Easting = False_Easting;
+    Albers_False_Northing = False_Northing;
+
+    es2 = 2 * Albers_f - Albers_f * Albers_f;
+    es = sqrt(es2);
+    one_MINUS_es2 = 1 - es2;
+    two_es = 2 * es;
+
+    sin_lat = sin(Albers_Origin_Lat);
+    es_sin = ES_SIN(sin_lat);
+    one_MINUS_SQRes_sin = ONE_MINUS_SQR(es_sin);
+    q0 = ALBERS_Q(sin_lat, one_MINUS_SQRes_sin, es_sin);
+
+    sin_lat_1 = sin(Albers_Std_Parallel_1);
+    cos_lat = cos(Albers_Std_Parallel_1);
+    es_sin = ES_SIN(sin_lat_1);
+    one_MINUS_SQRes_sin = ONE_MINUS_SQR(es_sin);
+    m1 = ALBERS_M(cos_lat, one_MINUS_SQRes_sin);
+    q1 = ALBERS_Q(sin_lat_1, one_MINUS_SQRes_sin, es_sin);
+
+    SQRm1 = m1 * m1;
+    if (fabs(Albers_Std_Parallel_1 - Albers_Std_Parallel_2) > 1.0e-10)
+    {
+      sin_lat = sin(Albers_Std_Parallel_2);
+      cos_lat = cos(Albers_Std_Parallel_2);
+      es_sin = ES_SIN(sin_lat);
+      one_MINUS_SQRes_sin = ONE_MINUS_SQR(es_sin);
+      m2 = ALBERS_M(cos_lat, one_MINUS_SQRes_sin);
+      q2 = ALBERS_Q(sin_lat, one_MINUS_SQRes_sin, es_sin);
+      n = (SQRm1 - m2 * m2) / (q2 - q1);
+    }
+    else
+      n = sin_lat_1;
+
+    C = SQRm1 + n * q1;
+    Albers_a_OVER_n = Albers_a / n;
+    nq0 = n * q0;
+    if (C < nq0)
+      rho0 = 0;
+    else
+      rho0 = Albers_a_OVER_n * sqrt(C - nq0);
+
+
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+} /* END OF Set_Albers_Parameters */
+
+
+void ossimAlbersProjection::Get_Albers_Parameters(double *a,
+                                                  double *f,
+                                                  double *Origin_Latitude,
+                                                  double *Central_Meridian,
+                                                  double *Std_Parallel_1,
+                                                  double *Std_Parallel_2,
+                                                  double *False_Easting,
+                                                  double *False_Northing)const
+
+{ /* BEGIN Get_Albers_Parameters */
+/*
+ * The function Get_Albers_Parameters returns the current ellipsoid
+ * parameters, and Albers projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid										(output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Origin_Longitude  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    Std_Parallel_1    : First standard parallel                   (output)
+ *    Std_Parallel_2    : Second standard parallel                  (output)
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Albers_a;
+  *f = Albers_f;
+  *Origin_Latitude = Albers_Origin_Lat;
+  *Std_Parallel_1 = Albers_Std_Parallel_1;
+  *Std_Parallel_2 = Albers_Std_Parallel_2;
+  *Central_Meridian = Albers_Origin_Long;
+  *False_Easting = Albers_False_Easting;
+  *False_Northing = Albers_False_Northing;
+  return;
+} /* END OF Get_Albers_Parameters */
+
+
+long ossimAlbersProjection::Convert_Geodetic_To_Albers (double Latitude,
+                                                        double Longitude,
+                                                        double *Easting,
+                                                        double *Northing)const
+
+{ /* BEGIN Convert_Geodetic_To_Albers */
+/*
+ * The function Convert_Geodetic_To_Albers converts geodetic (latitude and
+ * longitude) coordinates to Albers projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Albers projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ALBERS_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double dlam;                      /* Longitude - Central Meridan */
+  double sin_lat, cos_lat;
+  double es_sin, one_MINUS_SQRes_sin;
+  double q;
+  double rho;
+  double theta;
+  double nq;
+  long Error_Code = ALBERS_NO_ERROR;
+
+  if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+  {  /* Latitude out of range */
+    Error_Code |= ALBERS_LAT_ERROR;
+  }
+  if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+  {  /* Longitude out of range */
+    Error_Code|= ALBERS_LON_ERROR;
+  }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    dlam = Longitude - Albers_Origin_Long;
+    if (dlam > M_PI)
+    {
+      dlam -= TWO_PI;
+    }
+    if (dlam < -M_PI)
+    {
+      dlam += TWO_PI;
+    }
+    sin_lat = sin(Latitude);
+    cos_lat = cos(Latitude);
+    es_sin = ES_SIN(sin_lat);
+    one_MINUS_SQRes_sin = ONE_MINUS_SQR(es_sin);
+    q = ALBERS_Q(sin_lat, one_MINUS_SQRes_sin, es_sin);
+    nq = n * q;
+    if (C < nq)
+      rho = 0;
+    else
+      rho = Albers_a_OVER_n * sqrt(C - nq);
+
+
+    theta = n * dlam;
+    *Easting = rho * sin(theta) + Albers_False_Easting;
+    *Northing = rho0 - rho * cos(theta) + Albers_False_Northing;
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Albers */
+
+
+long ossimAlbersProjection::Convert_Albers_To_Geodetic(double Easting,
+                                                       double Northing,
+                                                       double *Latitude,
+                                                       double *Longitude)const
+{ /* BEGIN Convert_Albers_To_Geodetic */
+/*
+ * The function Convert_Albers_To_Geodetic converts Albers projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Albers projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ALBERS_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dy, dx;
+  double rho0_MINUS_dy;
+  double q, qconst, q_OVER_2;
+  double rho, rho_n;
+  double PHI, Delta_PHI = 1.0;
+  double sin_phi;
+  double es_sin, one_MINUS_SQRes_sin;
+  double theta = 0.0;
+  double tolerance = 4.85e-10;        /* approximately 1/1000th of
+                              an arc second or 1/10th meter */
+  long Error_Code = ALBERS_NO_ERROR; 
+
+  if ((Easting < (Albers_False_Easting - Albers_Delta_Easting)) 
+      || (Easting > Albers_False_Easting + Albers_Delta_Easting))
+  { /* Easting out of range  */
+    Error_Code |= ALBERS_EASTING_ERROR;
+  }
+  if ((Northing < (Albers_False_Northing - Albers_Delta_Northing)) 
+      || (Northing > Albers_False_Northing + Albers_Delta_Northing))
+  { /* Northing out of range */
+    Error_Code |= ALBERS_NORTHING_ERROR;
+  }
+
+  if (!Error_Code)
+  {
+    dy = Northing - Albers_False_Northing;
+    dx = Easting - Albers_False_Easting;
+    rho0_MINUS_dy = rho0 - dy;
+    rho = sqrt(dx * dx + rho0_MINUS_dy * rho0_MINUS_dy);
+
+    if (n < 0)
+    {
+      rho *= -1.0;
+      dy *= -1.0;
+      dx *= -1.0;
+      rho0_MINUS_dy *= -1.0;
+    }
+
+    if (rho != 0.0)
+      theta = atan2(dx, rho0_MINUS_dy);
+    rho_n = rho * n;
+    q = (C - (rho_n * rho_n) / (Albers_a * Albers_a)) / n;
+    qconst = 1 - ((one_MINUS_es2) / (two_es)) * log((1.0 - es) / (1.0 + es));
+    if (fabs(fabs(qconst) - fabs(q)) > 1.0e-6)
+    {
+      q_OVER_2 = q / 2.0;
+      if (q_OVER_2 > 1.0)
+        *Latitude = PI_OVER_2;
+      else if (q_OVER_2 < -1.0)
+        *Latitude = -PI_OVER_2;
+      else
+      {
+        PHI = asin(q_OVER_2);
+        if (es < 1.0e-10)
+          *Latitude = PHI;
+        else
+        {
+          while (fabs(Delta_PHI) > tolerance)
+          {
+            sin_phi = sin(PHI);
+            es_sin = ES_SIN(sin_phi);
+            one_MINUS_SQRes_sin = ONE_MINUS_SQR(es_sin);
+            Delta_PHI = (one_MINUS_SQRes_sin * one_MINUS_SQRes_sin) / (2.0 * cos(PHI)) *
+                        (q / (one_MINUS_es2) - sin_phi / one_MINUS_SQRes_sin +
+                         (log((1.0 - es_sin) / (1.0 + es_sin)) / (two_es)));
+            PHI += Delta_PHI;
+          }
+          *Latitude = PHI;
+        }
+
+        if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+          *Latitude = PI_OVER_2;
+        else if (*Latitude < -PI_OVER_2)
+          *Latitude = -PI_OVER_2;
+
+      }
+    }
+    else
+    {
+      if (q >= 0.0)
+        *Latitude = PI_OVER_2;
+      else
+        *Latitude = -PI_OVER_2;
+    }
+    *Longitude = Albers_Origin_Long + theta / n;
+
+    if (*Longitude > M_PI)
+      *Longitude -= TWO_PI;
+    if (*Longitude < -M_PI)
+      *Longitude += TWO_PI;
+
+    if (*Longitude > M_PI) /* force distorted values to 180, -180 degrees */
+      *Longitude = M_PI;
+    else if (*Longitude < -M_PI)
+      *Longitude = -M_PI;
+
+  }
+  return (Error_Code);
+} /* END OF Convert_Albers_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAlbersProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAlbersProjection.h
new file mode 100644
index 0000000000..18382b0572
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAlbersProjection.h
@@ -0,0 +1,252 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Albers projection code.  
+//*******************************************************************
+//  $Id: ossimAlbersProjection.h,v 1.9 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimAlbersProjection_HEADER
+#define ossimAlbersProjection_HEADER
+#include "ossimMapProjection.h"
+
+//! Albers Equal Area Conic Projection
+/*!
+ *  A basic conic projection developed by H.C. Albers.  Classified as a 
+ *  conic and equal area.  A graphic can be found at:  
+ *  http://everest.hunter.cuny.edu/mp/pbander/albers.gif
+ */
+
+class ossimAlbersProjection : public ossimMapProjection
+{
+public:
+   ossimAlbersProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                         const ossimGpt& origin = ossimGpt());
+   ossimAlbersProjection(const ossimEllipsoid& ellipsoid,
+                         const ossimGpt& origin,
+                         double stdParallel1,
+                         double stdParallel2,
+                         double falseEasting,
+                         double falseNorthing);
+   
+   virtual ~ossimAlbersProjection();
+
+   ossimObject *dup()const;
+   
+   virtual ossimDpt forward(const ossimGpt &worldPoint)    const;
+   virtual ossimGpt inverse(const ossimDpt &projectedPoint)const;
+   virtual void update();
+
+   /*!
+    * The passed in Argument is in degrees and will convert it to radians
+    * for Geotrans. Update is then called so we can pre-compute paramters.
+    */
+   void setStandardParallel1(double degree);
+
+   /*!
+    * The passed in Argument is in degrees and will convert it to radians
+    * for Geotrans. Update is then called so we can pre-compute paramters
+    */
+   void setStandardParallel2(double degree);
+
+   /*!
+    * Will allow you to set both parallels. both are passed in degrees.
+    */
+   void setStandardParallels(double parallel1Degree,
+                             double prallel2Degree);
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   /*!
+    * Allows one to set all parameters for this projections.  parallels are in
+    * degrees and easting northings are in meters.
+    * Update is then called so we can pre-compute paramters.
+    */
+   void setParameters(double parallel1,
+                      double parallel2,
+                      double falseEasting,
+                      double falseNorthing);
+   
+   virtual double getStandardParallel1() const;
+   virtual double getStandardParallel2() const;
+   virtual double getFalseEasting()      const;
+   virtual double getFalseNorthing()     const;
+   
+   void setDefaults();
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+private:
+
+
+   //________________________GEOTRANS__________________________
+   //
+   mutable double Albers_a;                   /* Semi-major axis of ellipsoid in meters */
+   mutable double Albers_f;           /* Flattening of ellipsoid */
+   mutable double es;            /* Eccentricity of ellipsoid */
+   mutable double es2;            /* Eccentricity squared         */
+   mutable double C;                     /* constant c   */
+   mutable double rho0;                 /* height above ellipsoid		*/
+   mutable double n;                    /* ratio between meridians		*/
+   mutable double Albers_a_OVER_n;      /* Albers_a / n */
+   mutable double one_MINUS_es2;        /* 1 - es2 */
+   mutable double two_es;               /* 2 * es */
+   
+/* Albers Projection Parameters */
+   mutable double Albers_Origin_Lat;    /* Latitude of origin in radians     */
+   mutable double Albers_Origin_Long;               /* Longitude of origin in radians    */
+   mutable double Albers_Std_Parallel_1;
+   mutable double Albers_Std_Parallel_2;
+   mutable double Albers_False_Easting;
+   mutable double Albers_False_Northing;
+   
+   mutable double Albers_Delta_Northing;
+   mutable double Albers_Delta_Easting;
+   
+/*!
+ * The function Set_Albers_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise ALBERS_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection (central meridian)
+ *    Std_Parallel_1    : First standard parallel                   (input)
+ *    Std_Parallel_2    : Second standard parallel                  (input)
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+   long Set_Albers_Parameters(double a,
+                             double f,
+                             double Origin_Latitude,
+                             double Central_Meridian,
+                             double Std_Parallel_1,
+                             double Std_Parallel_2,
+                             double False_Easting,
+                             double False_Northing);
+
+
+/*!
+ * The function Get_Albers_Parameters returns the current ellipsoid
+ * parameters, and Albers projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    Std_Parallel_1    : First standard parallel                   (output)
+ *    Std_Parallel_2    : Second standard parallel                  (output)
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Albers_Parameters(double *a,
+                             double *f,
+                             double *Origin_Latitude,
+                             double *Central_Meridian,
+                             double *Std_Parallel_1,
+                             double *Std_Parallel_2,
+                             double *False_Easting,
+                             double *False_Northing)const;
+
+
+
+/*!
+ * The function Convert_Geodetic_To_Albers converts geodetic (latitude and
+ * longitude) coordinates to Albers projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Albers projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ALBERS_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Albers (double Latitude,
+                                   double Longitude,
+                                   double *Easting,
+                                   double *Northing)const;
+
+
+
+/*!
+ * The function Convert_Albers_To_Geodetic converts Albers projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Albers projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ALBERS_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Albers_To_Geodetic(double Easting,
+                                  double Northing,
+                                  double *Latitude,
+                                  double *Longitude)const;
+
+
+   
+/*
+ * RTTI information defined in data_types/rtti.h
+ */
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAzimEquDistProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAzimEquDistProjection.cpp
new file mode 100644
index 0000000000..63cd95f8a8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAzimEquDistProjection.cpp
@@ -0,0 +1,491 @@
+#include "ossimAzimEquDistProjection.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/common/ossimTrace.h"
+
+
+#define PI_OVER_2  ( M_PI / 2.0)                 
+#define ONE        (1.0 * M_PI / 180.0)       /* 1 degree in radians           */
+
+#define AZEQ_NO_ERROR           0x0000
+#define AZEQ_LAT_ERROR          0x0001
+#define AZEQ_LON_ERROR          0x0002
+#define AZEQ_EASTING_ERROR      0x0004
+#define AZEQ_NORTHING_ERROR     0x0008
+#define AZEQ_ORIGIN_LAT_ERROR   0x0010
+#define AZEQ_CENT_MER_ERROR     0x0020
+#define AZEQ_A_ERROR            0x0040
+#define AZEQ_INV_F_ERROR        0x0080
+#define AZEQ_PROJECTION_ERROR   0x0100
+
+RTTI_DEF1(ossimAzimEquDistProjection,"ossimAzimEquDistProjection", ossimMapProjection)
+   
+ossimAzimEquDistProjection::ossimAzimEquDistProjection(const ossimEllipsoid& ellipsoid,
+                                                       const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid,
+                       origin)
+{
+   setDefaults();
+}
+
+ossimAzimEquDistProjection::ossimAzimEquDistProjection(const ossimEllipsoid& ellipsoid,
+                                                       const ossimGpt& origin,
+                                                       double falseEasting,
+                                                       double falseNorthing)
+   :ossimMapProjection(ellipsoid,
+                       origin)
+{
+   setFalseEastingNorthing(falseEasting, falseNorthing);
+}
+
+void ossimAzimEquDistProjection::update()
+{
+   ossimMapProjection::update();
+   Set_Azimuthal_Equidistant_Parameters(theEllipsoid.getA(),
+                                        theEllipsoid.getFlattening(),
+                                        theOrigin.latr(),
+                                        theOrigin.lonr(),
+                                        Azeq_False_Easting,
+                                        Azeq_False_Northing);
+                                        
+}
+
+ossimGpt ossimAzimEquDistProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat, lon;
+
+   Convert_Azimuthal_Equidistant_To_Geodetic(eastingNorthing.x,
+                                             eastingNorthing.y,
+                                             &lat,
+                                             &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimAzimEquDistProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Azimuthal_Equidistant(gpt.latr(),
+                                             gpt.lonr(),
+                                             &easting,
+                                             &northing);
+   return ossimDpt(easting, northing);
+}
+
+void ossimAzimEquDistProjection::setFalseEasting(double falseEasting)
+{
+   Azeq_False_Easting = falseEasting;
+
+   update();
+}
+
+void ossimAzimEquDistProjection::setFalseNorthing(double falseNorthing)
+{
+   Azeq_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimAzimEquDistProjection::setFalseEastingNorthing(double falseEasting,
+                                                         double falseNorthing)
+{
+   Azeq_False_Easting = falseEasting;
+   Azeq_False_Northing = falseNorthing;
+   
+   update();   
+}
+
+void ossimAzimEquDistProjection::setDefaults()
+{
+   Azeq_False_Easting  = 0.0;
+   Azeq_False_Northing = 0.0;
+   update();
+}
+
+bool ossimAzimEquDistProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   ossimMapProjection::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Azeq_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Azeq_False_Northing,
+           true);
+           
+   return true;
+}
+
+bool ossimAzimEquDistProjection::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+
+   update();
+   
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimAzimEquDistProjection))
+   {
+      if(falseEasting)
+      {
+         Azeq_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Azeq_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+
+   update();
+   
+   return flag;
+}
+
+long ossimAzimEquDistProjection::Set_Azimuthal_Equidistant_Parameters(double a,
+                                                                      double f,
+                                                                      double Origin_Latitude,
+                                                                      double Central_Meridian,
+                                                                      double False_Easting,
+                                                                      double False_Northing)
+{
+/* BEGIN Set_Azimuthal_Equidistant_Parameters */
+/*
+ * The function Set_Azimuthal_Equidistant_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise AZEQ_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double es2, es4, es6;
+//  double inv_f = 1 / f;
+  double temp_Northing = 0.0;
+  long Error_Code = AZEQ_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= AZEQ_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= AZEQ_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+//   { /* origin latitude out of range */
+//     Error_Code |= AZEQ_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= AZEQ_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Azeq_a = a;
+    Azeq_f = f;
+    es2 = 2 * Azeq_f - Azeq_f * Azeq_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    /* spherical radius */
+    Ra = Azeq_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 / 3024.0);
+    Azeq_Origin_Lat = Origin_Latitude;
+    Sin_Azeq_Origin_Lat = sin(Azeq_Origin_Lat);
+    Cos_Azeq_Origin_Lat = cos(Azeq_Origin_Lat);
+    abs_Azeq_Origin_Lat = fabs(Azeq_Origin_Lat);
+//     if (Central_Meridian > M_PI)
+//       Central_Meridian -= TWO_PI;
+    Azeq_Origin_Long = Central_Meridian;
+    Azeq_False_Northing = False_Northing;
+    Azeq_False_Easting = False_Easting;
+
+    if (fabs(abs_Azeq_Origin_Lat - PI_OVER_2) < 1.0e-10)
+    {
+      Azeq_Delta_Northing = 20015110.0;
+      Azeq_Delta_Easting = 20015110.0;
+    }
+    else if (abs_Azeq_Origin_Lat >= 1.0e-10)
+    {
+      if (Azeq_Origin_Long > 0.0)
+      {
+        Convert_Geodetic_To_Azimuthal_Equidistant(-Azeq_Origin_Lat, 
+                                                  (Azeq_Origin_Long - M_PI - ONE), &Azeq_Delta_Easting, &temp_Northing);
+      }
+      else
+      {
+        Convert_Geodetic_To_Azimuthal_Equidistant(-Azeq_Origin_Lat, 
+                                                  (Azeq_Origin_Long + M_PI - ONE), &Azeq_Delta_Easting, &temp_Northing);
+      }
+      Azeq_Delta_Northing = 19903915.0;
+    }
+    else
+    {
+      Azeq_Delta_Northing = 19903915.0;
+      Azeq_Delta_Easting = 19903915.0;
+    }
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Azimuthal_Equidistant_Parameters */
+
+
+void ossimAzimEquDistProjection::Get_Azimuthal_Equidistant_Parameters(double *a,
+                                                                      double *f,
+                                                                      double *Origin_Latitude,
+                                                                      double *Central_Meridian,
+                                                                      double *False_Easting,
+                                                                      double *False_Northing)const
+{
+/* Begin Get_Azimuthal_Equidistant_Parameters */
+/*
+ * The function Get_Azimuthal_Equidistant_Parameters returns the current ellipsoid
+ * parameters and Azimuthal Equidistant projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid                   (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Azeq_a;
+  *f = Azeq_f;
+  *Origin_Latitude = Azeq_Origin_Lat;
+  *Central_Meridian = Azeq_Origin_Long;
+  *False_Easting = Azeq_False_Easting;
+  *False_Northing = Azeq_False_Northing;
+  return;
+} /* End Get_Azimuthal_Equidistant_Parameters */
+
+
+long ossimAzimEquDistProjection::Convert_Geodetic_To_Azimuthal_Equidistant (double Latitude,
+                                                                            double Longitude,
+                                                                            double *Easting,
+                                                                            double *Northing)const
+{
+/* Begin Convert_Geodetic_To_Azimuthal_Equidistant */
+/*
+ * The function Convert_Geodetic_To_Azimuthal_Equidistant converts geodetic (latitude and
+ * longitude) coordinates to Azimuthal Equidistant projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Azimuthal Equidistant projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise AZEQ_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double dlam;       /* Longitude - Central Meridan */
+  double k_prime;    /* scale factor */
+  double c;          /* angular distance from center */
+  double slat = sin(Latitude);
+  double clat = cos(Latitude);
+  double cos_c;
+  double sin_dlam, cos_dlam;
+  double Ra_kprime;
+  double Ra_PI_OVER_2_Lat;
+  long Error_Code = AZEQ_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   { /* Latitude out of range */
+//     Error_Code |= AZEQ_LAT_ERROR;
+//   }
+//   if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+//   { /* Longitude out of range */
+//     Error_Code |= AZEQ_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Azeq_Origin_Long;
+    if (dlam > M_PI)
+    {
+      dlam -= TWO_PI;
+    }
+    if (dlam < -M_PI)
+    {
+      dlam += TWO_PI;
+    }
+
+    sin_dlam = sin(dlam);
+    cos_dlam = cos(dlam);
+    if (fabs(abs_Azeq_Origin_Lat - PI_OVER_2) < 1.0e-10)
+    {
+      if (Azeq_Origin_Lat >= 0.0)
+      {
+        Ra_PI_OVER_2_Lat = Ra * (PI_OVER_2 - Latitude);
+        *Easting = Ra_PI_OVER_2_Lat * sin_dlam + Azeq_False_Easting;
+        *Northing = -1.0 * (Ra_PI_OVER_2_Lat * cos_dlam) + Azeq_False_Northing;
+      }
+      else
+      {
+        Ra_PI_OVER_2_Lat = Ra * (PI_OVER_2 + Latitude);
+        *Easting = Ra_PI_OVER_2_Lat * sin_dlam + Azeq_False_Easting;
+        *Northing = Ra_PI_OVER_2_Lat * cos_dlam + Azeq_False_Northing;
+      }
+    }
+    else if (abs_Azeq_Origin_Lat <= 1.0e-10)
+    {
+      cos_c = clat * cos_dlam;
+      if (fabs(fabs(cos_c) - 1.0) < 1.0e-14)
+      {
+        if (cos_c >= 0.0)
+        {
+          *Easting = Azeq_False_Easting;
+          *Northing = Azeq_False_Northing;
+        }
+        else
+        {
+          /* if cos_c == -1 */
+          Error_Code |= AZEQ_PROJECTION_ERROR;
+        }
+      }
+      else
+      {
+        c = acos(cos_c);
+        k_prime = c / sin(c);
+        Ra_kprime = Ra * k_prime;
+        *Easting = Ra_kprime * clat * sin_dlam + Azeq_False_Easting;
+        *Northing = Ra_kprime * slat + Azeq_False_Northing;
+      }
+    }
+    else
+    {
+      cos_c = (Sin_Azeq_Origin_Lat * slat) + (Cos_Azeq_Origin_Lat * clat * cos_dlam);
+      if (fabs(fabs(cos_c) - 1.0) < 1.0e-14)
+      {
+        if (cos_c >= 0.0)
+        {
+          *Easting = Azeq_False_Easting;
+          *Northing = Azeq_False_Northing;
+        }
+        else
+        {
+          /* if cos_c == -1 */
+          Error_Code |= AZEQ_PROJECTION_ERROR;
+        }
+      }
+      else
+      {
+        c = acos(cos_c);
+        k_prime = c / sin(c);
+        Ra_kprime = Ra * k_prime;
+        *Easting = Ra_kprime * clat * sin_dlam + Azeq_False_Easting;
+        *Northing = Ra_kprime * (Cos_Azeq_Origin_Lat * slat - Sin_Azeq_Origin_Lat * clat * cos_dlam) + Azeq_False_Northing;
+      }
+    }
+  }
+  return (Error_Code);
+} /* End Convert_Geodetic_To_Azimuthal_Equidistant */
+
+
+long ossimAzimEquDistProjection::Convert_Azimuthal_Equidistant_To_Geodetic(double Easting,
+                                                                           double Northing,
+                                                                           double *Latitude,
+                                                                           double *Longitude)const
+{ /* Begin Convert_Azimuthal_Equidistant_To_Geodetic */
+/*
+ * The function Convert_Azimuthal_Equidistant_To_Geodetic converts Azimuthal_Equidistant projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Azimuthal_Equidistant projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise AZEQ_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx, dy;
+  double rho;        /* height above ellipsoid */
+  double c;          /* angular distance from center */
+  double sin_c, cos_c, dy_sinc;
+  long Error_Code = AZEQ_NO_ERROR; 
+
+//   if ((Easting < (Azeq_False_Easting - Azeq_Delta_Easting)) 
+//       || (Easting > (Azeq_False_Easting + Azeq_Delta_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= AZEQ_EASTING_ERROR;
+//   }
+//   if ((Northing < (Azeq_False_Northing - Azeq_Delta_Northing)) 
+//       || (Northing > (Azeq_False_Northing + Azeq_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= AZEQ_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  {
+    dy = Northing - Azeq_False_Northing;
+    dx = Easting - Azeq_False_Easting;
+    rho = sqrt(dx * dx + dy * dy);
+    if (fabs(rho) <= 1.0e-10)
+    {
+      *Latitude = Azeq_Origin_Lat;
+      *Longitude = Azeq_Origin_Long;
+    }
+    else
+    {
+      c = rho / Ra;
+      sin_c = sin(c);
+      cos_c = cos(c);
+      dy_sinc = dy * sin_c;
+      *Latitude = asin((cos_c * Sin_Azeq_Origin_Lat) + ((dy_sinc * Cos_Azeq_Origin_Lat) / rho));
+      if (fabs(abs_Azeq_Origin_Lat - PI_OVER_2) < 1.0e-10)
+      {
+        if (Azeq_Origin_Lat >= 0.0)
+          *Longitude = Azeq_Origin_Long + atan2(dx, -dy);
+        else
+          *Longitude = Azeq_Origin_Long + atan2(dx, dy);
+      }
+      else
+        *Longitude = Azeq_Origin_Long + atan2((dx * sin_c), ((rho * Cos_Azeq_Origin_Lat * cos_c) - (dy_sinc * Sin_Azeq_Origin_Lat)));
+    }
+
+    if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+      *Latitude = PI_OVER_2;
+    else if (*Latitude < -PI_OVER_2)
+      *Latitude = -PI_OVER_2;
+
+//     if (*Longitude > M_PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -M_PI)
+//       *Longitude += TWO_PI;
+
+    if (*Longitude > M_PI)  /* force distorted values to 180, -180 degrees */
+      *Longitude = M_PI;
+    else if (*Longitude < -M_PI)
+      *Longitude = -M_PI;
+
+  }
+  return (Error_Code);
+} /* End Convert_Azimuthal_Equidistant_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAzimEquDistProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAzimEquDistProjection.h
new file mode 100644
index 0000000000..3747d63248
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimAzimEquDistProjection.h
@@ -0,0 +1,197 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Equidistant Cylinder projection code.  
+//*******************************************************************
+//  $Id: ossimAzimEquDistProjection.h,v 1.4 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimAzimEquDistProjection_HEADER
+#define ossimAzimEquDistProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimAzimEquDistProjection : public ossimMapProjection
+{
+public:
+   ossimAzimEquDistProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                              const ossimGpt& origin = ossimGpt());
+   
+   ossimAzimEquDistProjection(const ossimEllipsoid& ellipsoid,
+                              const ossimGpt& origin,
+                              double falseEasting,
+                              double falseNorthing);
+   
+   ossimAzimEquDistProjection(const ossimAzimEquDistProjection& rhs)
+      {
+         *this = rhs;
+      }
+   virtual ~ossimAzimEquDistProjection(){}
+   virtual ossimObject *dup()const
+   {
+      return new ossimAzimEquDistProjection(*this);
+   }
+   
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+
+   double getFalseEasting()const{return Azeq_False_Easting;}
+   double getFalseNorthing()const{return Azeq_False_Northing;}
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   /*!
+    * Will initialize all parameters to a default values and then call
+    * update for pre-computations.
+    */
+   void setDefaults();
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+protected:   
+   mutable double abs_Azeq_Origin_Lat;
+   mutable double Azeq_a;                  /* Semi-major axis of ellipsoid in meters */
+   mutable double Azeq_f;          /* Flattening of ellipsoid */
+   mutable double Ra;                /* Spherical Radius */
+   mutable double Sin_Azeq_Origin_Lat;
+   mutable double Cos_Azeq_Origin_Lat;
+   mutable double Azeq_Origin_Lat;               /* Latitude of origin in radians */
+   mutable double Azeq_Origin_Long;              /* Longitude of origin in radians */
+   mutable double Azeq_False_Northing;           /* False northing in meters */
+   mutable double Azeq_False_Easting;            /* False easting in meters */
+
+   mutable double Azeq_Delta_Northing;
+   mutable double Azeq_Delta_Easting;
+/*!
+ * The function Set_Azimuthal_Equidistant_Parameters receives the ellipsoid 
+ * parameters and projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise AZEQ_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Azimuthal_Equidistant_Parameters(double a,
+                                            double f,
+                                            double Origin_Latitude,
+                                            double Central_Meridian,
+                                            double False_Easting,
+                                            double False_Northing);
+
+/*!
+ * The function Get_Azimuthal_Equidistant_Parameters returns the current ellipsoid
+ * parameters and Azimuthal Equidistant projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Azimuthal_Equidistant_Parameters(double *a,
+                                            double *f,
+                                            double *Origin_Latitude,
+                                            double *Central_Meridian,
+                                            double *False_Easting,
+                                            double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Azimuthal_Equidistant converts geodetic (latitude and
+ * longitude) coordinates to Azimuthal Equidistant projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Azimuthal Equidistant projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise AZEQ_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Azimuthal_Equidistant (double Latitude,
+                                                  double Longitude,
+                                                  double *Easting,
+                                                  double *Northing)const;
+
+/*!
+ * The function Convert_Azimuthal_Equidistant_To_Geodetic converts Azimuthal Equidistant 
+ * projection (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Azimuthal Equidistant projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise AZEQ_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Azimuthal_Equidistant_To_Geodetic(double Easting,
+                                                 double Northing,
+                                                 double *Latitude,
+                                                 double *Longitude)const;
+
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBngProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBngProjection.cpp
new file mode 100644
index 0000000000..91b27cfadf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBngProjection.cpp
@@ -0,0 +1,761 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+//  $Id: ossimBngProjection.cpp,v 1.16 2004/06/23 20:12:57 dburken Exp $
+#include <projections/map_projections/ossimBngProjection.h>
+#include <projections/map_projections/ossimTranmerc.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/factory/ossimEllipsoidFactory.h>
+#include <base/common/ossimKeywordNames.h>
+#include <elevation/ossimElevManager.h>
+
+#include <string.h>
+#include <stdio.h>
+
+#define BNG_NO_ERROR           0x0000
+#define BNG_LAT_ERROR          0x0001
+#define BNG_LON_ERROR          0x0002
+#define BNG_EASTING_ERROR      0x0004
+#define BNG_NORTHING_ERROR     0x0008
+#define BNG_INVALID_AREA_ERROR 0x0010
+#define BNG_STRING_ERROR       0x0020
+#define BNG_ELLIPSOID_ERROR    0x0040
+
+#define PI_OVER_2       (M_PI / 2.0e0)            /* PI over 2 */
+#define MAX_LAT         (61.5 * M_PI / 180.0)     /* 61.5 degrees */
+#define MIN_LAT         (49.5 * M_PI / 180.0)     /* 49.5 degrees */
+#define MAX_LON         (3.5 * M_PI / 180.0)      /* 3.5 degrees */
+#define MIN_LON         (-10.0 * M_PI / 180.0)    /* -10 degrees */
+#define BNG500GRID      "STNOHJ"                /* 500,000 unit square identifications */
+#define BNG100GRID      "VWXYZQRSTULMNOPFGHJKABCDE" /* 100,000 unit square identifications */
+static double BNG_Max_Easting = 759961.0;
+static double BNG_Max_Northing = 1257875.0;
+static double BNG_Min_Easting = -133134.0;
+static double BNG_Min_Northing = -14829.0;
+
+static char BNG_Letters[3] = "SV";
+static double BNG_Easting = 0.0;
+static double BNG_Northing = 0.0;
+static const char* Airy = "AA";
+static char BNG_Ellipsoid_Code[3] = "AA";
+
+RTTI_DEF1(ossimBngProjection, "ossimBngProjection", ossimMapProjection);
+
+ossimBngProjection::ossimBngProjection()
+   :ossimMapProjection(*ossimEllipsoidFactory::instance()->create("AA"),
+                       ossimGpt(49.0, -2.0, OSSIM_DBL_NAN, ossimDatumFactory::instance()->create("OGB-M")))
+{
+   string_Broken = 0;
+   theDatum = ossimDatumFactory::instance()->create("OGB-M");
+   update();
+}
+
+
+ossimGpt ossimBngProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   char s[100];
+   double lat;
+   double lon;
+
+   string_Broken = 0;
+   Set_Transverse_Mercator_Parameters(BNG_a, BNG_f, BNG_Origin_Lat,
+                                      BNG_Origin_Long, BNG_False_Easting, 
+                                      BNG_False_Northing, BNG_Scale_Factor);
+   
+   Convert_Transverse_Mercator_To_BNG(eastingNorthing.x,
+                                      eastingNorthing.y,
+                                      5,
+                                      s);
+   Convert_BNG_To_Geodetic(s,
+                           &lat,
+                           &lon);
+   ossimGpt result(49, -2, OSSIM_DBL_NAN,theDatum);
+   result.latr(lat);
+   result.lonr(lon);
+
+   return result;
+}
+
+ossimDpt ossimBngProjection::forward(const ossimGpt &latLon)const
+{
+   char BNG[100];
+
+   string_Broken = 0;
+   Set_Transverse_Mercator_Parameters(BNG_a, BNG_f, BNG_Origin_Lat,
+                                      BNG_Origin_Long, BNG_False_Easting, 
+                                      BNG_False_Northing, BNG_Scale_Factor);
+   
+   Convert_Geodetic_To_BNG (latLon.latr(),
+                            latLon.lonr(),
+                            5,
+                            BNG);
+
+   ossimDpt en;
+   
+   Convert_BNG_To_Transverse_Mercator(BNG,
+				      &en.x,
+				      &en.y);
+   
+   return en;
+}
+
+void ossimBngProjection::update()
+{
+   BNG_Origin_Lat     = (49.0 * M_PI / 180.0);
+   BNG_Origin_Long    = (-2.0 * M_PI / 180.0);
+   BNG_False_Northing = -100000.0;
+   BNG_False_Easting  = 400000.0;
+   BNG_Scale_Factor   = .9996012717;
+   BNG_a              = 6377563.396;
+   BNG_f              = 1 / 299.324964600;
+
+   //      ossimString code = theDatum->code();
+      //   if(code.upcase().contains("OGB"))
+   //     {
+       theOrigin = ossimGpt(49.0, -2.0, OSSIM_DBL_NAN, theDatum);
+       //     }
+   //   else
+//      {
+//        theOrigin = ossimGpt(49.0, -2.0, OSSIM_DBL_NAN, ossimDatumFactory::instance()->create("OGB-7"));      
+//      }
+   
+   ossimMapProjection::update();
+}
+
+/*!
+ * Method to save the state of an object to a keyword list.
+ * Return true if ok or false on error.
+ */
+bool ossimBngProjection::saveState(ossimKeywordlist& kwl,
+                                   const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           getClassName(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+	   BNG_False_Easting,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+	   BNG_False_Northing,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_FACTOR_KW,
+	   BNG_Scale_Factor,
+           true);
+
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+/*!
+ * Method to the load (recreate) the state of an object from a keyword
+ * list.  Return true if ok or false on error.
+ */
+bool ossimBngProjection::loadState(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+{
+   
+   ossimMapProjection::loadState(kwl,
+                                 prefix);
+
+   update();
+
+   return true;
+}
+
+
+long ossimBngProjection::Find_Index (char letter, 
+                                     const char* letter_Array, 
+                                     long *index)const
+{
+/*
+ * The function Find_Index searches for a given letter in an array. 
+ * It returns the index of the letter in the array if the letter is found.
+ * If the letter is not found, an error code is returned, otherwise
+ * BNG_NO_ERROR is returned. 
+ *
+ *    letter              : Letter being searched for         
+ *    letter_Array        : Array being searched         
+ *    index               : Index of letter in array        
+ */
+  long i = 0;
+  long not_Found = 1;
+  long length = strlen(letter_Array);
+  long Error_Code = BNG_NO_ERROR;
+
+  while ((i < length) && (not_Found))
+  {
+    if (letter == letter_Array[i])
+    {
+      *index = i;
+      not_Found = 0;
+    }
+    i++;
+  }
+  if (not_Found)
+    Error_Code = BNG_STRING_ERROR;
+
+  return Error_Code;
+}
+
+long ossimBngProjection::Round_BNG (double value)const
+/* Round value to nearest integer, using standard engineering rule */
+{ /* Round_BNG */
+   double ivalue;
+   long ival;
+   double fraction = modf (value, &ivalue);
+   ival = (long)(ivalue);
+   if ((fraction > 0.5) || ((fraction == 0.5) && (ival%2 == 1)))
+      ival++;
+   
+   return (ival);
+}
+
+long ossimBngProjection::Make_BNG_String (char ltrnum[4],
+                                          long Easting, 
+                                          long Northing,
+                                          char* BNG,
+                                          long Precision)const
+                        
+{ /* Make_BNG_String */
+/* Construct a BNG string from its component parts */
+  double divisor;
+  long east;
+  long north;
+  long i;
+  long j;
+  double unitInterval;
+  long error_code = BNG_NO_ERROR;
+
+  i = 0;
+  for (j = 0; j < 3; j++)
+  {
+     BNG[i++] = ltrnum[j];
+  }
+  
+  divisor = pow ((double)10.0,(double) (5 - Precision));
+  unitInterval = pow ((double)10.0, (double)Precision);
+  east = Round_BNG (Easting/divisor);
+  if (east == unitInterval)
+    east -= 1;
+  if ((Precision == 0) && (east == 1))
+     east = 0;
+  i += sprintf (BNG + i, "%*.*ld",(int) Precision,(int) Precision, east);
+
+  north = Round_BNG (Northing/divisor);
+  if (north == unitInterval)
+    north -= 1;
+  if ((Precision == 0) && (north == 1))
+    north = 0;
+  i += sprintf (BNG + i, "%*.*ld",(int)  Precision,(int) Precision, north);
+
+  return (error_code);
+} /* Make_BNG_String */
+
+long ossimBngProjection::Break_BNG_String (char* BNG,
+                                           char Letters[3],
+                                           double* Easting,
+                                           double* Northing,
+                                           long* Precision)const
+/* Break down a BNG string into its component parts */
+{ /* Break_BNG_String */
+  long i = 0;
+  long j;
+  long num_digits = 0;
+  long num_letters;
+  long temp_error = 0;
+  long length = strlen(BNG);
+  long error_code = BNG_NO_ERROR;
+
+  string_Broken = 1;
+  while (BNG[i] == ' ')
+     i++;  /* skip any leading blanks */
+  j = i;
+  while (isalpha(BNG[i]))
+    i++;
+  num_letters = i - j;
+  if (num_letters == 2)
+  {
+    /* get letters */
+    Letters[0] = (char)toupper(BNG[j]);
+    Letters[1] = (char)toupper(BNG[j+1]);
+    Letters[2] = 0;
+  }
+  else
+    error_code |= BNG_STRING_ERROR;
+  if (!error_code)
+  {
+    error_code |= Check_Out_Of_Area(Letters[0], Letters[1]);
+    while (BNG[i] == ' ')
+      i++;
+    j = i;
+    if (BNG[length-1] == ' ')
+      length --;
+    while ((i < length) && (!temp_error))
+    {
+      if (isdigit(BNG[i]))
+        i++;
+      else
+      {
+         temp_error = BNG_STRING_ERROR;
+      }
+    }
+    if (temp_error)
+      error_code |= temp_error;
+    if (!error_code)
+    {
+       num_digits = i - j;
+      if ((num_digits <= 10) && (num_digits%2 == 0))
+      {
+        long n;
+        char east_string[6];
+        char north_string[6];
+        long east;
+        long north;
+        double multiplier;
+
+        /* get easting & northing */
+        n = num_digits / 2;
+        *Precision = n;
+        if (n > 0)
+        {
+          strncpy (east_string, BNG+j, n);
+          east_string[n] = 0;
+          sscanf (east_string, "%ld", &east);
+          strncpy (north_string, BNG+j+n, n);
+          north_string[n] = 0;
+          sscanf (north_string, "%ld", &north);
+          multiplier = pow ((double)10.0,(double)( 5 - n));
+          *Easting = east * multiplier;
+          *Northing = north * multiplier;
+        }
+        else
+        {
+          *Easting = 0.0;
+          *Northing = 0.0;
+        }
+      }
+      else
+        error_code |= BNG_STRING_ERROR;
+    }
+  }
+  return (error_code);
+} /* Break_BNG_String */
+
+long ossimBngProjection::Check_Out_Of_Area(char BNG500,
+                                           char BNG100)const
+
+{ /* BEGIN Check_Out_Of_Area */
+/*
+ * The function Check_Out_Of_Area checks if the 500,000 and 
+ * 100,000 unit square identifications are within the valid area. If
+ * they are not, an error code is returned, otherwise BNG_NO_ERROR 
+ * is returned.
+ *
+ *    BNG500        : 500,000 square unit identification         
+ *    BNG100        : 100,000 square unit identification         
+ */
+
+  long Error_Code = BNG_NO_ERROR;
+
+  switch (BNG500)
+  {
+    case 'S':
+      switch (BNG100)
+      {
+        case 'A':
+        case 'F':
+        case 'L':
+          Error_Code |= BNG_INVALID_AREA_ERROR;
+          break;
+        default:
+          break;
+      }
+      break;
+    case 'N':
+      switch (BNG100)
+      {
+        case 'V':
+          Error_Code |= BNG_INVALID_AREA_ERROR;
+          break;
+        default:
+          break;
+      }
+      break;
+
+    case 'H':
+      if (BNG100 < 'L')
+        Error_Code |= BNG_INVALID_AREA_ERROR;
+      break;
+    case 'T':
+      switch (BNG100)
+      {
+        case 'D':
+        case 'E':
+        case 'J':
+        case 'K':
+        case 'O':
+        case 'P':
+        case 'T':
+        case 'U':
+        case 'X':
+        case 'Y':
+        case 'Z':
+          Error_Code |= BNG_INVALID_AREA_ERROR;
+          break;
+        default:
+          break;
+      }
+      break;
+    case 'O':
+      switch (BNG100)
+      {
+        case 'C':
+        case 'D':
+        case 'E':
+        case 'J':
+        case 'K':
+        case 'O':
+        case 'P':
+        case 'T':
+        case 'U':
+        case 'Y':
+        case 'Z':
+          Error_Code |= BNG_INVALID_AREA_ERROR;
+          break;
+        default:
+          break;
+      }
+      break;
+    case 'J':
+      switch (BNG100)
+      {
+        case 'L':
+        case 'M':
+        case 'Q':
+        case 'R':
+        case 'V':
+        case 'W':
+          Error_Code = BNG_NO_ERROR;
+          break;
+        default:
+          Error_Code |= BNG_INVALID_AREA_ERROR;
+          break;
+      }
+      break;
+    default:
+      Error_Code |= BNG_INVALID_AREA_ERROR;
+      break;
+  }
+  return Error_Code;
+} /* END OF Check_Out_Of_Area */
+
+long ossimBngProjection::Set_BNG_Parameters(char *Ellipsoid_Code)
+
+{ /* BEGIN Set_BNG_Parameters */
+/*
+ * The function Set_BNG_Parameters receives the ellipsoid code and sets
+ * the corresponding state variables. If any errors occur, the error code(s)
+ * are returned by the function, otherwise BNG_NO_ERROR is returned.
+ *
+ *   Ellipsoid_Code : 2-letter code for ellipsoid           (input)
+ */
+
+  long Error_Code = BNG_NO_ERROR;
+
+  if (strcmp(Ellipsoid_Code, Airy) != 0)
+  { /* Ellipsoid must be Airy */
+    Error_Code |= BNG_ELLIPSOID_ERROR;
+  }
+    
+  if (!Error_Code)
+  { /* no errors */
+    strcpy(BNG_Ellipsoid_Code, Ellipsoid_Code);
+    string_Broken = 0;
+
+    Set_Transverse_Mercator_Parameters(BNG_a, BNG_f, BNG_Origin_Lat,
+                                       BNG_Origin_Long, BNG_False_Easting, 
+                                       BNG_False_Northing, BNG_Scale_Factor);
+  }
+  return (Error_Code);
+}  /* END of Set_BNG_Parameters  */
+
+void ossimBngProjection::Get_BNG_Parameters(char *Ellipsoid_Code)
+                        
+{ /* BEGIN Get_BNG_Parameters */
+/*                         
+ * The function Get_BNG_Parameters returns the current ellipsoid
+ * code.
+ *
+ *   Ellipsoid_Code : 2-letter code for ellipsoid          (output)
+ */
+
+  strcpy(Ellipsoid_Code, BNG_Ellipsoid_Code);
+
+  return;
+} /* END OF Get_BNG_Parameters */
+
+long ossimBngProjection::Convert_Geodetic_To_BNG (double Latitude,
+                                                  double Longitude,
+                                                  long Precision,
+                                                  char* BNG)const
+
+{ /* BEGIN Convert_Geodetic_To_BNG */
+/*
+ * The function Convert_Geodetic_To_BNG converts geodetic (latitude and
+ * longitude) coordinates to a BNG coordinate string, according to the 
+ * current ellipsoid parameters.  If any errors occur, the error code(s)  
+ * are returned by the function, otherwise BNG_NO_ERROR is returned.
+ * 
+ *    Latitude   : Latitude, in radians                    (input)
+ *    Longitude  : Longitude, in radians                   (input)
+ *    Precision  : Precision level of BNG string           (input)
+ *    BNG        : British National Grid coordinate string (output)
+ *  
+ */
+  double TMEasting, TMNorthing;
+  long Error_Code = BNG_NO_ERROR;
+
+  if ((Latitude < MIN_LAT) || (Latitude > MAX_LAT))
+  {  /* Latitude out of range */
+    Error_Code|= BNG_LAT_ERROR;
+  }
+  if ((Longitude < MIN_LON) || (Longitude > MAX_LON))
+  {  /* Longitude out of range */
+    Error_Code|= BNG_LON_ERROR;
+  }
+
+  if (!Error_Code)
+  { /* no errors */
+
+     Error_Code |= Convert_Geodetic_To_Transverse_Mercator(Latitude, Longitude, &TMEasting, &TMNorthing);
+     
+    if ((TMEasting < 0.0) && (TMEasting > -2.0))
+      TMEasting = 0.0;
+    if ((TMNorthing < 0.0) && (TMNorthing > -2.0))
+      TMNorthing = 0.0;
+
+    if ((TMEasting < BNG_Min_Easting) || (TMEasting > BNG_Max_Easting))
+      Error_Code |= BNG_INVALID_AREA_ERROR;
+    if ((TMNorthing < BNG_Min_Northing) || (TMNorthing > BNG_Max_Northing))
+      Error_Code |= BNG_INVALID_AREA_ERROR;
+    
+    if (!Error_Code)
+      Error_Code |= Convert_Transverse_Mercator_To_BNG(TMEasting, TMNorthing, Precision, BNG);
+  }
+  return Error_Code;
+} /* END OF Convert_Geodetic_To_BNG */
+
+long ossimBngProjection::Convert_BNG_To_Geodetic (char *BNG, 
+                                                  double *Latitude, 
+                                                  double *Longitude)const
+
+{ /* Convert_BNG_To_Geodetic */
+/*
+ * The function Convert_BNG_To_Geodetic converts a BNG coordinate string 
+ * to geodetic (latitude and longitude) coordinates, according to the current
+ * ellipsoid parameters. If any errors occur, the error code(s) are returned 
+ * by the function, otherwise BNG_NO_ERROR is returned. 
+ * 
+ *    BNG        : British National Grid coordinate string (input)
+ *    Latitude   : Latitude, in radians                    (output)
+ *    Longitude  : Longitude, in radians                   (output)
+ *  
+ */
+
+  double TMEasting, TMNorthing;
+  long in_Precision;
+  long temp_Error = 0;
+  long Error_Code = BNG_NO_ERROR;
+  
+  Error_Code |= Break_BNG_String(BNG, BNG_Letters, &BNG_Easting, &BNG_Northing, &in_Precision);
+  
+  if(!Error_Code)
+  {
+    Error_Code |= Convert_BNG_To_Transverse_Mercator(BNG, &TMEasting, &TMNorthing);
+
+    if ((TMEasting < BNG_Min_Easting) || (TMEasting > BNG_Max_Easting))
+      Error_Code |= BNG_INVALID_AREA_ERROR;
+    if ((TMNorthing < BNG_Min_Northing) || (TMNorthing > BNG_Max_Northing))
+      Error_Code |= BNG_INVALID_AREA_ERROR;
+
+    if(!Error_Code)
+    {
+      temp_Error |= Convert_Transverse_Mercator_To_Geodetic(TMEasting, TMNorthing, Latitude, Longitude);
+      
+      if (temp_Error & TRANMERC_EASTING_ERROR)
+        Error_Code |= BNG_EASTING_ERROR;
+      if (temp_Error & TRANMERC_NORTHING_ERROR)
+        Error_Code |= BNG_NORTHING_ERROR;
+
+      if ((*Latitude < MIN_LAT) || (*Latitude > MAX_LAT))
+        Error_Code|= BNG_INVALID_AREA_ERROR;
+      if ((*Longitude < MIN_LON) || (*Longitude > MAX_LON))
+        Error_Code|= BNG_INVALID_AREA_ERROR;
+    }
+  }
+  return Error_Code;
+} /* END OF Convert_BNG_To_Geodetic */
+
+
+long ossimBngProjection::Convert_Transverse_Mercator_To_BNG(double Easting,
+                                                            double Northing,
+                                                            long Precision,
+                                                            char *BNG)const
+
+{/* BEGIN Convert_Transverse_Mercator_To_BNG */
+/*
+ * The function Convert_Transverse_Mercator_To_BNG converts Transverse Mercator
+ * (easting and northing) coordinates to a BNG coordinate string, according
+ * to the current ellipsoid parameters.  If any errors occur, the error code(s)
+ * are returned by the function, otherwise BNG_NO_ERROR is returned.
+ *
+ *    Easting    : Easting (X), in meters                  (input)
+ *    Northing   : Northing (Y), in meters                 (input)
+ *    Precision  : Precision level of BNG string           (input)
+ *    BNG        : British National Grid coordinate string (output)
+ */
+
+  char letters[4];
+  long x, y;
+  long index;
+  long temp_Easting, temp_Northing;
+  long Error_Code = BNG_NO_ERROR;
+
+  if ((Easting < BNG_Min_Easting) || (Easting > BNG_Max_Easting))
+  { /* Easting out of range  */
+    Error_Code |= BNG_EASTING_ERROR;
+  }
+  if ((Northing < BNG_Min_Northing) || (Northing > BNG_Max_Northing))
+  { /* Northing out of range */
+    Error_Code |= BNG_NORTHING_ERROR;
+  }
+
+  if (!Error_Code)
+  { /* no errors */
+    temp_Easting = Round_BNG(Easting);
+    temp_Northing = Round_BNG(Northing);
+
+    temp_Easting += 1000000; 
+    temp_Northing += 500000;
+
+    x = temp_Easting / 500000;
+    y = temp_Northing / 500000;
+    
+    index = y * 5 + x;
+    if ((index >= 0) && (index < 25))
+    {
+      letters[0] = BNG100GRID[index];
+      temp_Easting %= 500000;
+      temp_Northing %= 500000;
+      x = temp_Easting / 100000;
+      y = temp_Northing / 100000;
+      index = y * 5 + x;
+      if ((index >= 0) && (index < 25))
+      {
+        letters[1] = BNG100GRID[index];
+        Error_Code |= Check_Out_Of_Area(letters[0], letters[1]);
+        if (!Error_Code)
+        {
+          letters[2] = ' ';
+          letters[3] = 0;
+          temp_Easting %= 100000;
+          temp_Northing %= 100000;
+          Make_BNG_String(letters, temp_Easting, temp_Northing, BNG, Precision);
+        }
+      }
+      else
+      {
+        long five_y = 5 * y;
+        if ((x >= (25 - five_y)) || (x < -five_y))
+          Error_Code |= BNG_EASTING_ERROR;
+        if ((five_y >= (25 - x)) || (five_y < -x))
+          Error_Code |= BNG_NORTHING_ERROR;
+      }
+    }
+    else
+    {
+      long five_y = 5 * y;
+      if ((x >= (25 - five_y)) || (x < -five_y))
+        Error_Code |= BNG_EASTING_ERROR;
+      if ((five_y >= (25 - x)) || (five_y < -x))
+        Error_Code |= BNG_NORTHING_ERROR;
+    }
+  }
+  return Error_Code;
+} /* END OF Convert_Transverse_Mercator_To_BNG */
+
+
+long ossimBngProjection::Convert_BNG_To_Transverse_Mercator(char *BNG,
+                                                            double *Easting,
+                                                            double *Northing)const
+   
+{ /* Convert_BNG_To_Transverse_Mercator */
+/*
+ * The function Convert_BNG_To_Transverse_Mercator converts a BNG coordinate string
+ * to Transverse Mercator projection (easting and northing) coordinates 
+ * according to the current ellipsoid parameters.  If any errors occur, 
+ * the error code(s) are returned by the function, otherwise BNG_NO_ERROR 
+ * is returned.
+ *
+ *    BNG        : British National Grid coordinate string (input)
+ *    Easting    : Easting (X), in meters                  (output)
+ *    Northing   : Northing (Y), in meters                 (output)
+ */
+  long northing_Offset, easting_Offset;
+  long i = 0;
+  long j = 0;
+  long in_Precision;
+  long Error_Code = BNG_NO_ERROR;
+  
+  if (!string_Broken)
+  {
+     Error_Code |= Break_BNG_String(BNG, BNG_Letters, &BNG_Easting, &BNG_Northing, &in_Precision);
+  }
+  if (!Error_Code)
+  {
+    Error_Code |= Find_Index(BNG_Letters[0], BNG500GRID, &i);
+    if (!Error_Code)
+    {
+      northing_Offset = 500000 * (i / 2);
+      easting_Offset = 500000 * (i % 2);
+
+      Error_Code |= Find_Index(BNG_Letters[1], BNG100GRID, &j);
+      if (!Error_Code)
+      {
+        northing_Offset += 100000 * (j / 5);
+        easting_Offset += 100000 * (j % 5);
+        
+        *Easting = BNG_Easting + easting_Offset;
+        *Northing = BNG_Northing + northing_Offset;
+      }
+    }
+  }
+  return Error_Code;
+} /* END OF Convert_BNG_To_Transverse_Mercator */
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBngProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBngProjection.h
new file mode 100644
index 0000000000..084711d163
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBngProjection.h
@@ -0,0 +1,159 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+//*******************************************************************
+//  $Id: ossimBngProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+#include <projections/map_projections/ossimMapProjection.h>
+
+class OSSIMDLLEXPORT ossimBngProjection : public ossimMapProjection
+{
+public:
+   ossimBngProjection();
+      
+   virtual ossimObject* dup()const
+      {
+         return new ossimBngProjection(*this);
+      }
+
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+protected:
+   
+/* Ellipsoid Parameters, must be Airy  */
+   double BNG_a;               /* Semi-major axis of ellipsoid, in meters */
+   double BNG_f;         /* Flattening of ellipsoid */
+
+/* BNG projection Parameters */
+   double BNG_Origin_Lat;  /* Latitude of origin, in radians */
+   double BNG_Origin_Long; /* Longitude of origin, in radians */
+   double BNG_False_Northing;        /* False northing, in meters */
+   double BNG_False_Easting;          /* False easting, in meters */
+   double BNG_Scale_Factor;        /* Scale factor                      */
+   mutable long string_Broken;
+
+   long Find_Index (char letter, 
+                    const char* letter_Array, 
+                    long *index)const;
+   
+   long Round_BNG (double value)const;
+
+   long Make_BNG_String (char ltrnum[4],
+                         long Easting, 
+                         long Northing,
+                         char* BNG,
+                         long Precision)const;
+   
+   long Break_BNG_String (char* BNG,
+                          char Letters[3],
+                          double* Easting,
+                          double* Northing,
+                          long* Precision)const;
+   
+   long Check_Out_Of_Area(char BNG500,
+                          char BNG100)const;
+   
+   long Set_BNG_Parameters(char *Ellipsoid_Code);
+   void Get_BNG_Parameters(char *Ellipsoid_Code);
+  
+/*!
+ * The function Convert_Geodetic_To_BNG converts geodetic (latitude and
+ * longitude) coordinates to a BNG coordinate string, according to the 
+ * current ellipsoid parameters.  If any errors occur, the error code(s)  
+ * are returned by the function, otherwise BNG_NO_ERROR is returned.
+ * 
+ *    Latitude   : Latitude, in radians                    (input)
+ *    Longitude  : Longitude, in radians                   (input)
+ *    Precision  : Precision level of BNG string           (input)
+ *    BNG        : British National Grid coordinate string (output)
+ *  
+ */
+   long Convert_Geodetic_To_BNG (double Latitude,
+                                 double Longitude,
+                                 long Precision,
+                                 char* BNG)const;
+   
+
+
+/*!
+ * The function Convert_BNG_To_Geodetic converts a BNG coordinate string 
+ * to geodetic (latitude and longitude) coordinates, according to the current
+ * ellipsoid parameters. If any errors occur, the error code(s) are returned 
+ * by the function, otherwise BNG_NO_ERROR is returned. 
+ * 
+ *    BNG        : British National Grid coordinate string (input)
+ *    Latitude   : Latitude, in radians                    (output)
+ *    Longitude  : Longitude, in radians                   (output)
+ *  
+ */
+   long Convert_BNG_To_Geodetic (char *BNG, 
+                                 double *Latitude, 
+                                 double *Longitude)const;
+
+
+/*!
+ * The function Convert_Transverse_Mercator_To_BNG converts Transverse Mercator
+ * (easting and northing) coordinates to a BNG coordinate string, according
+ * to the current ellipsoid parameters.  If any errors occur, the error code(s)
+ * are returned by the function, otherwise BNG_NO_ERROR is returned.
+ *
+ *    Easting    : Easting (X), in meters                  (input)
+ *    Northing   : Northing (Y), in meters                 (input)
+ *    Precision  : Precision level of BNG string           (input)
+ *    BNG        : British National Grid coordinate string (output)
+ */
+   long Convert_Transverse_Mercator_To_BNG(double Easting,
+                                           double Northing,            
+                                           long Precision,
+                                           char *BNG)const;
+
+
+
+/*!
+ * The function Convert_BNG_To_Transverse_Mercator converts a BNG coordinate string
+ * to Transverse Mercator projection (easting and northing) coordinates 
+ * according to the current ellipsoid parameters.  If any errors occur, 
+ * the error code(s) are returned by the function, otherwise BNG_NO_ERROR 
+ * is returned.
+ *
+ *    BNG        : British National Grid coordinate string (input)
+ *    Easting    : Easting (X), in meters                  (output)
+ *    Northing   : Northing (Y), in meters                 (output)
+ */
+   long Convert_BNG_To_Transverse_Mercator(char *BNG,
+                                           double *Easting,
+                                           double *Northing)const;
+
+TYPE_DATA
+};
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBonneProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBonneProjection.cpp
new file mode 100644
index 0000000000..d03c08590e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBonneProjection.cpp
@@ -0,0 +1,541 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Bonne projection code.  
+//*******************************************************************
+//  $Id: ossimBonneProjection.cpp,v 1.12 2004/01/08 21:49:21 jlargent Exp $
+#include "ossimBonneProjection.h"
+#include "ossimSinusoid.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimBonneProjection, "ossimBonneProjection", ossimMapProjection)
+
+
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+#define BONN_NO_ERROR           0x0000
+#define BONN_LAT_ERROR          0x0001
+#define BONN_LON_ERROR          0x0002
+#define BONN_EASTING_ERROR      0x0004
+#define BONN_NORTHING_ERROR     0x0008
+#define BONN_ORIGIN_LAT_ERROR   0x0010
+#define BONN_CENT_MER_ERROR     0x0020
+#define BONN_A_ERROR            0x0040
+#define BONN_B_ERROR            0x0080
+#define BONN_A_LESS_B_ERROR     0x0100
+
+#define PI_OVER_2  (M_PI / 2.0)                 
+#define BONN_m(coslat,sinlat)                   (coslat/sqrt(1.0 - es2*sinlat*sinlat))
+#define BONN_M(c0lat,c1s2lat,c2s4lat,c3s6lat)   (Bonn_a*(c0lat-c1s2lat+c2s4lat-c3s6lat))
+#define COEFF_TIMES_BONN_SIN(coeff,x,latit)	    (coeff*(sin(x * latit)))
+#define FLOAT_EQ(x,v,epsilon)   (((v - epsilon) < x) && (x < (v + epsilon)))
+
+ossimBonneProjection::ossimBonneProjection(const ossimEllipsoid& ellipsoid,
+                                           const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();   
+   update();
+}
+
+ossimBonneProjection::ossimBonneProjection(const ossimEllipsoid& ellipsoid,
+                                           const ossimGpt& origin,
+                                           const double falseEasting,
+                                           const double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Bonn_False_Easting  = falseEasting;
+   Bonn_False_Northing = falseNorthing;
+   Bonn_Delta_Northing = 25000000.0;
+
+   update();
+}
+
+void ossimBonneProjection::update()
+{
+   Set_Bonne_Parameters(theEllipsoid.getA(),
+                        theEllipsoid.getFlattening(),
+                        theOrigin.latr(),
+                        theOrigin.lonr(),
+                        Bonn_False_Easting,
+                        Bonn_False_Northing);
+   
+   ossimMapProjection::update();
+}
+
+void ossimBonneProjection::setFalseEasting(double falseEasting)
+{
+   Bonn_False_Easting = falseEasting;
+   update();
+}
+
+void ossimBonneProjection::setFalseNorthing(double falseNorthing)
+{
+   Bonn_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimBonneProjection::setFalseEastingNorthing(double falseEasting,
+                                                   double falseNorthing)
+{
+   Bonn_False_Easting = falseEasting;
+   Bonn_False_Northing = falseNorthing;  
+   update();
+}
+
+void ossimBonneProjection::setDefaults()
+{
+
+   Bonn_False_Easting  = 0.0;
+   Bonn_False_Northing = 0.0;  
+   Bonn_Delta_Northing = 25000000.0;
+   if(theOrigin.latd() == 0.0)
+   {
+      // we can't have the origin of lat 0 for Bonne
+      // so bump it up an arc second.
+      //
+      theOrigin.latd(1.0/3600.0);
+   }
+}
+
+ossimGpt ossimBonneProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat, lon;
+
+   Convert_Bonne_To_Geodetic(eastingNorthing.x,
+                             eastingNorthing.y,
+                             &lat,
+                             &lon);
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0, theDatum);  
+}
+
+ossimDpt ossimBonneProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Bonne(gpt.latr(),
+                             gpt.lonr(),
+                             &easting,
+                             &northing);
+   return ossimDpt(easting, northing);
+}
+
+bool ossimBonneProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Bonn_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Bonn_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimBonneProjection::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimBonneProjection))
+   {
+      if(falseEasting)
+      {
+         Bonn_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Bonn_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+   return flag;
+}
+
+
+/*
+ * These state variables are for optimization purposes.  The only function
+ * that should modify them is Set_Bonne_Parameters.
+ */
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+long ossimBonneProjection::Set_Bonne_Parameters(double a,
+                                                double f,
+                                                double Origin_Latitude,
+                                                double Central_Meridian,
+                                                double False_Easting,
+                                                double False_Northing)
+{ /* Begin Set_Bonne_Parameters */
+/*
+ * The function Set_Bonne_Parameters receives the ellipsoid parameters and
+ * Bonne projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise BONN_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double j, three_es4;
+  double x,e1,e2,e3,e4;
+  double clat; 
+  double sin2lat, sin4lat, sin6lat, lat;
+//  double inv_f = 1 / f;
+  long Error_Code = BONN_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= BONN_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+// 	 Error_Code |= BONN_INV_F_ERROR;
+//   } 
+//   if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+//   { /* origin latitude out of range */
+//     Error_Code |= BONN_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= BONN_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Bonn_a = a;
+    Bonn_f = f;
+    Bonn_Origin_Lat = Origin_Latitude;
+//     if (Central_Meridian > PI)
+//       Central_Meridian -= TWO_PI;
+    Bonn_Origin_Long = Central_Meridian;
+    Bonn_False_Northing = False_Northing;
+    Bonn_False_Easting = False_Easting;
+    if (Bonn_Origin_Lat == 0.0)
+    {
+       if (Bonn_Origin_Long > 0)
+       {
+          Bonn_Max_Easting = 19926189.0;
+          Bonn_Min_Easting = -20037509.0;
+       }
+       else if (Bonn_Origin_Long < 0)
+       {
+          Bonn_Max_Easting = 20037509.0;
+          Bonn_Min_Easting = -19926189.0;
+       }
+       else
+       {
+          Bonn_Max_Easting = 20037509.0;
+          Bonn_Min_Easting = -20037509.0;
+       }
+       Bonn_Delta_Northing = 10001966.0;
+       Set_Sinusoidal_Parameters(Bonn_a, Bonn_f, Bonn_Origin_Long, Bonn_False_Easting, Bonn_False_Northing);
+    }
+    else
+    {
+       Sin_Bonn_Origin_Lat = sin(Bonn_Origin_Lat);
+       
+       es2 = 2 * Bonn_f - Bonn_f * Bonn_f;
+       es4 = es2 * es2;
+       es6 = es4 * es2;
+       j = 45.0 * es6 / 1024.0;
+       three_es4 = 3.0 * es4;
+       c0 = 1 - es2 / 4.0 - three_es4 / 64.0 - 5.0 * es6 / 256.0;
+       c1 = 3.0 * es2 / 8.0 + three_es4 / 32.0 + j;
+       c2 = 15.0 * es4 / 256.0 + j;
+       c3 = 35.0 * es6 / 3072.0;
+       
+       clat = cos(Bonn_Origin_Lat);
+       m1 = BONN_m(clat, Sin_Bonn_Origin_Lat);
+       
+       lat = c0 * Bonn_Origin_Lat;
+       sin2lat = COEFF_TIMES_BONN_SIN(c1, 2.0, Bonn_Origin_Lat);
+       sin4lat = COEFF_TIMES_BONN_SIN(c2, 4.0, Bonn_Origin_Lat);
+       sin6lat = COEFF_TIMES_BONN_SIN(c3, 6.0, Bonn_Origin_Lat);
+       M1 = BONN_M(lat, sin2lat, sin4lat, sin6lat);
+       
+       x = sqrt (1.0 - es2);
+       e1 = (1.0 - x) / (1.0 + x);
+       e2 = e1 * e1;
+       e3 = e2 * e1;
+       e4 = e3 * e1;
+       a0 = 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0;
+       a1 = 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0;
+       a2 = 151.0 * e3 / 96.0;
+       a3 = 1097.0 * e4 / 512.0;
+       if (Sin_Bonn_Origin_Lat == 0.0)
+          Bonn_am1sin = 0.0;
+       else
+          Bonn_am1sin = Bonn_a * m1 / Sin_Bonn_Origin_Lat;
+       
+       Bonn_Max_Easting = 20027474.0;
+       Bonn_Min_Easting = -20027474.0;
+       Bonn_Delta_Northing = 20003932.0;
+       
+    }
+    
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Bonne_Parameters */
+
+
+void ossimBonneProjection::Get_Bonne_Parameters(double *a,
+                                                double *f,
+                                                double *Origin_Latitude,
+                                                double *Central_Meridian,
+                                                double *False_Easting,
+                                                double *False_Northing)const
+{ /* Begin Get_Bonne_Parameters */
+/*
+ * The function Get_Bonne_Parameters returns the current ellipsoid
+ * parameters and Bonne projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid                   (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Bonn_a;
+  *f = Bonn_f;
+  *Origin_Latitude = Bonn_Origin_Lat;
+  *Central_Meridian = Bonn_Origin_Long;
+  *False_Easting = Bonn_False_Easting;
+  *False_Northing = Bonn_False_Northing;
+  return;
+} /* End Get_Bonne_Parameters */
+
+
+long ossimBonneProjection::Convert_Geodetic_To_Bonne (double Latitude,
+                                                      double Longitude,
+                                                      double *Easting,
+                                                      double *Northing)const
+{ /* Begin Convert_Geodetic_To_Bonne */
+/*
+ * The function Convert_Geodetic_To_Bonne converts geodetic (latitude and
+ * longitude) coordinates to Bonne projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Bonne projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise BONN_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double dlam; /* Longitude - Central Meridan */
+  double mm;
+  double MM;
+  double rho;
+  double EE;
+  double clat = cos(Latitude);
+  double slat = sin(Latitude);
+  double lat, sin2lat, sin4lat, sin6lat;
+  long Error_Code = BONN_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   { /* Latitude out of range */
+//     Error_Code |= BONN_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   { /* Longitude out of range */
+//     Error_Code |= BONN_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+     if (Bonn_Origin_Lat == 0.0)
+        Convert_Geodetic_To_Sinusoidal(Latitude, Longitude, Easting, Northing);
+     else
+     {
+        dlam = Longitude - Bonn_Origin_Long;
+        if (dlam > M_PI)
+        {
+           dlam -= TWO_PI;
+        }
+        if (dlam < -M_PI)
+        {
+           dlam += TWO_PI;
+        }
+        if ((Latitude - Bonn_Origin_Lat) == 0.0 && FLOAT_EQ(fabs(Latitude),PI_OVER_2,.00001))
+        {
+           *Easting = 0.0;
+           *Northing = 0.0;
+        }
+        else
+        {
+           mm = BONN_m(clat, slat);
+           
+           lat = c0 * Latitude;
+           sin2lat = COEFF_TIMES_BONN_SIN(c1, 2.0, Latitude);
+           sin4lat = COEFF_TIMES_BONN_SIN(c2, 4.0, Latitude);
+           sin6lat = COEFF_TIMES_BONN_SIN(c3, 6.0, Latitude);
+           MM = BONN_M(lat, sin2lat, sin4lat, sin6lat);         
+           
+           rho = Bonn_am1sin + M1 - MM;
+           if (rho == 0)
+              EE = 0;
+           else
+              EE = Bonn_a * mm * dlam / rho;
+           *Easting = rho * sin(EE) + Bonn_False_Easting;
+           *Northing = Bonn_am1sin - rho * cos(EE) + Bonn_False_Northing;
+        }
+     }
+  }
+  return (Error_Code);
+} /* End Convert_Geodetic_To_Bonne */
+
+
+long ossimBonneProjection::Convert_Bonne_To_Geodetic(double Easting,
+                                                     double Northing,
+                                                     double *Latitude,
+                                                     double *Longitude)const
+{ /* Begin Convert_Bonne_To_Geodetic */
+/*
+ * The function Convert_Bonne_To_Geodetic converts Bonne projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Bonne projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise BONN_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx;     /* Delta easting - Difference in easting (easting-FE)      */
+  double dy;     /* Delta northing - Difference in northing (northing-FN)   */
+  double mu;
+  double MM;
+  double mm;
+  double am1sin_dy;
+  double rho;
+  double sin2mu, sin4mu, sin6mu, sin8mu;
+  double clat, slat;
+  long Error_Code = BONN_NO_ERROR;
+
+//   if ((Easting < (Bonn_False_Easting + Bonn_Min_Easting))
+//       || (Easting > (Bonn_False_Easting + Bonn_Max_Easting)))
+//   { /* Easting out of range */
+//     Error_Code |= BONN_EASTING_ERROR;
+//   }
+//   if ((Northing < (Bonn_False_Northing - Bonn_Delta_Northing))
+//       || (Northing > (Bonn_False_Northing + Bonn_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= BONN_NORTHING_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+     if (Bonn_Origin_Lat == 0.0)
+        Convert_Sinusoidal_To_Geodetic(Easting, Northing, Latitude, Longitude);
+     else
+     {
+        dy = Northing - Bonn_False_Northing;
+        dx = Easting - Bonn_False_Easting;
+        am1sin_dy = Bonn_am1sin - dy;
+        rho = sqrt(dx * dx + am1sin_dy * am1sin_dy);
+        if (Bonn_Origin_Lat < 0.0)
+           rho = -rho;
+        MM = Bonn_am1sin + M1 - rho;
+        
+        mu = MM / (Bonn_a * c0); 
+        sin2mu = COEFF_TIMES_BONN_SIN(a0, 2.0, mu);
+        sin4mu = COEFF_TIMES_BONN_SIN(a1, 4.0, mu);
+        sin6mu = COEFF_TIMES_BONN_SIN(a2, 6.0, mu);
+        sin8mu = COEFF_TIMES_BONN_SIN(a3, 8.0, mu);
+        *Latitude = mu + sin2mu + sin4mu + sin6mu + sin8mu;
+        
+        if (FLOAT_EQ(fabs(*Latitude),PI_OVER_2,.00001))
+        {
+           *Longitude = Bonn_Origin_Long;
+        }
+        else
+        {
+           clat = cos(*Latitude);
+           slat = sin(*Latitude);
+           mm = BONN_m(clat, slat);
+           
+           if (Bonn_Origin_Lat < 0.0)
+           {
+              dx = -dx;
+              am1sin_dy = -am1sin_dy;
+           }
+           *Longitude = Bonn_Origin_Long + rho * (atan2(dx, am1sin_dy)) /
+                        (Bonn_a * mm);
+        }
+        
+        if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+           *Latitude = PI_OVER_2;
+        else if (*Latitude < -PI_OVER_2)
+           *Latitude = -PI_OVER_2;
+        
+//         if (*Longitude > PI)
+//            *Longitude -= TWO_PI;
+//         if (*Longitude < -PI)
+//            *Longitude += TWO_PI;
+        
+        if (*Longitude > M_PI)/* force distorted values to 180, -180 degrees */
+           *Longitude = M_PI;
+        else if (*Longitude < -M_PI)
+           *Longitude = -M_PI;
+     }
+  }
+  return (Error_Code);
+} /* End Convert_Bonne_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBonneProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBonneProjection.h
new file mode 100644
index 0000000000..71065d95f0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimBonneProjection.h
@@ -0,0 +1,215 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Bonne projection code.  
+//*******************************************************************
+//  $Id: ossimBonneProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimBonneProjection_HEADER
+#define ossimBonneProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimBonneProjection : public ossimMapProjection
+{
+public:
+   
+   ossimBonneProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                        const ossimGpt& origin = ossimGpt());
+   ossimBonneProjection(const ossimEllipsoid& ellipsoid,
+                        const ossimGpt& origin,
+                        const double falseEasting,
+                        const double falseNorthing);
+   ~ossimBonneProjection(){}
+   virtual ossimObject *dup()const{return new ossimBonneProjection(*this);}
+
+   virtual ossimDpt forward(const ossimGpt &worldPoint)    const;
+   virtual ossimGpt inverse(const ossimDpt &projectedPoint)const;
+   virtual void update();
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   double getFalseEasting()const{return Bonn_False_Easting;}
+   double getFalseNorthing()const{return Bonn_False_Northing;}
+
+   /*!
+    * Initialize all pramters to default and calls update for
+    * pre-computations.
+    */
+   void setDefaults();
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+
+   
+private:
+
+   
+   mutable double Bonn_a;                 /* Semi-major axis of ellipsoid in meters */
+   mutable double Bonn_f;         /* Flattening of ellipsoid */
+   mutable double es2;        /* Eccentricity (0.08181919084262188000) squared  */
+   mutable double es4;         /* es2 * es2 */
+   mutable double es6;         /* es4 * es2 */
+   mutable double M1;               /* Bonn_M(Bonna,c0lat,c1s2lat,c2s4lat,c3s6lat) */
+   mutable double m1;               /* Bonn_m(coslat,sinlat,es2) */
+   mutable double c0;               /* 1 - es2 / 4.0 - 3.0 * es4 / 64.0 - 5.0 * es6 / 256.0 */
+   mutable double c1;             /* 3.0 * es2 / 8.0 + 3.0 * es4 / 32.0 + 45.0 * es6 / 1024.0 */
+   mutable double c2;          /* 15.0 * es4 / 256.0 + 45.0 * es6 / 1024.0 */
+   mutable double c3;          /* 35.0 * es6 / 3072.0 */
+   mutable double a0;             /* 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0 */
+   mutable double a1;          /* 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0 */
+   mutable double a2;          /* 151.0 * e3 / 96.0 */
+   mutable double a3;          /* 1097.0 * e4 / 512.0 */
+   
+   
+/* Bonne projection Parameters */
+   mutable double  Bonn_Origin_Lat;           /* Latitude of origin in radians     */
+   mutable double  Bonn_Origin_Long;                          /* Longitude of origin in radians    */
+   mutable double  Bonn_False_Northing;                       /* False northing in meters          */
+   mutable double  Bonn_False_Easting;                        /* False easting in meters           */
+   mutable double  Sin_Bonn_Origin_Lat;           /* sin(Bonn_Origin_Lat)              */
+   mutable double  Bonn_am1sin;                   /* Bonn_a * m1 / Sin_Bonn_Origin_Lat */
+   
+/* Maximum variance for easting and northing values for WGS 84.
+ */
+   mutable double  Bonn_Max_Easting;
+   mutable double  Bonn_Min_Easting;
+   mutable double  Bonn_Delta_Northing;
+   
+/*!
+ * The function Set_Bonne_Parameters receives the ellipsoid parameters and
+ * Bonne projcetion parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise BONN_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Bonne_Parameters(double a,
+                            double f,
+                            double Origin_Latitude,
+                            double Central_Meridian,
+                            double False_Easting,
+                            double False_Northing);
+
+
+/*!
+ * The function Get_Bonne_Parameters returns the current ellipsoid
+ * parameters and Bonne projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid                   (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Bonne_Parameters(double *a,
+                            double *f,
+                            double *Origin_Latitude,
+                            double *Central_Meridian,
+                            double *False_Easting,
+                            double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Bonne converts geodetic (latitude and
+ * longitude) coordinates to Bonne projection easting, and northing
+ * coordinates, according to the current ellipsoid and Bonne projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise BONN_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Bonne (double Latitude,
+                                  double Longitude,
+                                  double *Easting,
+                                  double *Northing)const; 
+
+
+/*!
+ * The function Convert_Bonne_To_Geodetic converts Bonne projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Bonne projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise BONN_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Bonne_To_Geodetic(double Easting,
+                                 double Northing,
+                                 double *Latitude,
+                                 double *Longitude)const;
+
+/*!
+ * RTTI found in data_types/rtti.h
+ */
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCadrgProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCadrgProjection.cpp
new file mode 100644
index 0000000000..583698fae3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCadrgProjection.cpp
@@ -0,0 +1,417 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimCadrgProjection.cpp,v 1.12 2005/09/09 19:23:58 gpotts Exp $
+#include "ossimCadrgProjection.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/common/ossimTrace.h"
+#include "elevation/ossimElevManager.h"
+#include "base/data_types/datum/ossimDatum.h"
+
+RTTI_DEF1(ossimCadrgProjection, "ossimCadrgProjection", ossimMapProjection)
+
+double ossimCadrgProjection::theOldZoneExtents[] = {0.0, 32.0, 48.0, 56.0, 64.0,
+                                                    68.0, 72.0, 76.0, 80.0, 90.0};
+double ossimCadrgProjection::theCadrgArcA[] = { 369664, 302592, 245760, 199168,
+					       163328, 137216, 110080, 82432 };
+
+double ossimCadrgProjection::theNorthLimit = 90.0*M_PI/180.0;
+double ossimCadrgProjection::theSouthLimit = -90.0*M_PI/180.0;
+
+ossimCadrgProjection::ossimCadrgProjection()
+   :ossimMapProjection(ossimEllipsoid(), ossimGpt()),
+    theCadrgZone(1),
+    theMapScale(5000000),
+    theWidth(0.0),
+    theHeight(0.0)
+{
+   computeParameters();
+}
+
+ossimCadrgProjection::~ossimCadrgProjection()
+{
+   
+}
+
+ossimObject *ossimCadrgProjection::dup()const
+{
+   return new ossimCadrgProjection(*this);
+}
+
+
+ossimDpt ossimCadrgProjection::worldToLineSample(const ossimGpt &worldPoint)    const
+{
+   ossimDpt lineSample;
+
+   worldToLineSample(worldPoint, lineSample);
+
+   return lineSample;
+}
+
+ossimGpt ossimCadrgProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat=0.0;
+   double lon=0.0;
+
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimCadrgProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+   
+   return ossimDpt(easting, northing);
+}
+
+ossimGpt ossimCadrgProjection::lineSampleToWorld(const ossimDpt &projectedPoint)const
+{
+   ossimGpt worldPoint;
+
+   lineSampleToWorld(projectedPoint, worldPoint);
+
+   return worldPoint;
+}
+
+void ossimCadrgProjection::worldToLineSample(const ossimGpt &worldPoint,
+                                            ossimDpt&       lineSample)const
+{
+   double lat = worldPoint.latd();
+   double lon = worldPoint.lond();
+   double centerLat = theOrigin.latd();
+   double centerLon = theOrigin.lond()*DEG_PER_RAD;
+   
+   lineSample.y = (centerLat - lat)/90.0*thePixelConstant.y;
+   lineSample.x = (lon - centerLon)/360.0*thePixelConstant.x;
+
+   lineSample = lineSample - theUlLineSample;
+}
+
+void ossimCadrgProjection::lineSampleToWorld(const ossimDpt &projectedPoint,
+                                            ossimGpt& gpt)const
+{
+   gpt = theOrigin;
+
+
+   ossimDpt adjustedPixel(projectedPoint.x + theUlLineSample.x,
+                          projectedPoint.y + theUlLineSample.y);
+
+//   double lat = gpt.latd() - (90/thePixelConstant.y)*adjustedPixel.y;
+//   double lon = gpt.lond() + (360/thePixelConstant.x)*adjustedPixel.x;
+   double lat = gpt.latd() - (90/thePixelConstant.y)*adjustedPixel.y;
+   double lon = gpt.lond() + (360/thePixelConstant.x)*adjustedPixel.x;
+   
+   gpt.latd(lat);
+   gpt.lond(lon);
+
+   gpt.clampLat(-90, 90);
+   gpt.clampLon(-180, 180);
+}
+
+double ossimCadrgProjection::computeXPixConstant(double scale,
+                                                 long zone)const
+{
+   double adrgscale = 1000000/scale;
+   
+   // E-W pixel constant
+   double x_pix = (double) adrgscale*theCadrgArcA[zone-1] / 512.0;
+   
+   // Increase, if necessary, to the next highest integer value
+   x_pix = ceil(x_pix);
+   x_pix = x_pix * 1.33333;//(512*100)/(150*256);
+   
+   // Round the final result.
+   x_pix = irint(x_pix);
+   
+   return x_pix*256.0;
+   
+}
+
+double ossimCadrgProjection::computeYPixConstant(double scale)const
+{
+   double adrgscale = 1000000/scale;
+   const long CADRG_ARC_B = 400384;
+   
+   double y_pix = (double) adrgscale * CADRG_ARC_B / 512.0;
+   
+   // Increase, if necessary, to the next highest integer value
+   y_pix = ceil(y_pix);
+
+   y_pix = y_pix * 0.33333;//(512*100)/(4*150*256);
+   
+   // Round the final result.
+   y_pix = irint(y_pix);
+   
+   return y_pix*256.0;
+}
+
+void ossimCadrgProjection::computeParameters()
+{
+   theUlLineSample = ossimDpt(0,0);
+
+   thePixelConstant.y = computeYPixConstant(theMapScale);
+   thePixelConstant.x = computeXPixConstant(theMapScale,
+                                            theCadrgZone);
+   double height = theHeight;
+   double width  = theWidth;
+   
+   if(width > thePixelConstant.x)
+   {
+      width  = thePixelConstant.x;
+   }
+   
+   if(height > thePixelConstant.y)
+   {
+      height = thePixelConstant.y;
+   }
+
+
+   theUlLineSample.x = -width/2.0;
+   theUlLineSample.y = -height/2.0;
+}
+
+bool ossimCadrgProjection::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix)const
+{
+   bool result = ossimProjection::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           ossimKeywordNames::ZONE_KW,
+           theCadrgZone,
+           true);
+   
+   kwl.add(prefix,
+           "map_scale",
+           theMapScale,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_LINES_KW,
+           theHeight,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_SAMPLES_KW,
+           theWidth,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::UL_LAT_KW,
+           theUlGpt.latd(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::UL_LON_KW,
+           theUlGpt.lond(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::LL_LAT_KW,
+           theLlGpt.latd(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::LL_LON_KW,
+           theLlGpt.lond(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::LR_LAT_KW,
+           theLrGpt.latd(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::LR_LON_KW,
+           theLrGpt.lond(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::UR_LAT_KW,
+           theUrGpt.latd(),
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::UR_LON_KW,
+           theUrGpt.lond(),
+           true);
+
+  
+   
+   if(theDatum)
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::DATUM_KW,
+              theDatum->code(),
+              true);
+   }
+
+   return result;
+}
+
+
+bool ossimCadrgProjection::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   ossimProjection::loadState(kwl, prefix);
+
+   
+   const char* lookup = kwl.find(prefix, ossimKeywordNames::UL_LAT_KW);
+   if(lookup)
+   {
+      theUlGpt.latd(ossimString(lookup).toDouble());
+   }
+   else
+    {
+       theUlGpt.latd(90.0);
+    }
+
+    lookup = kwl.find(prefix, ossimKeywordNames::UL_LON_KW);
+    if(lookup)
+    {
+       theUlGpt.lond(ossimString(lookup).toDouble());
+    }
+    else
+    {
+       theUlGpt.lond(-180.0);
+    }
+
+    lookup = kwl.find(prefix, ossimKeywordNames::LL_LAT_KW);
+    if(lookup)
+    {
+       theLlGpt.latd(ossimString(lookup).toDouble());
+    }
+    else
+    {
+       theLlGpt.latd(0.0);
+    }
+
+    lookup = kwl.find(prefix, ossimKeywordNames::LL_LON_KW);
+    if(lookup)
+    {
+       theLlGpt.lond(ossimString(lookup).toDouble());
+    }
+   else
+   {
+      theLlGpt.lond(-180.0);
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::LR_LAT_KW);
+   if(lookup)
+   {
+      theLrGpt.latd(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      theLrGpt.latd(0.0);
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::LR_LON_KW);
+   if(lookup)
+   {
+      theLrGpt.lond(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      theLrGpt.lond(180.0);
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::LR_LAT_KW);
+   if(lookup)
+   {
+      theLrGpt.latd(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      theLrGpt.latd(0.0);
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::LR_LON_KW);
+   if(lookup)
+   {
+      theLrGpt.lond(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      theLrGpt.lond(180.0);
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::UR_LAT_KW);
+   if(lookup)
+   {
+      theUrGpt.latd(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      theUrGpt.latd(90.0);
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::UR_LON_KW);
+   if(lookup)
+   {
+      theUrGpt.lond(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      theUrGpt.lond(180.0);
+   }
+
+   const char* zone = kwl.find(prefix,
+                               ossimKeywordNames::ZONE_KW);
+   if(zone)
+   {
+      theCadrgZone = ossimString(zone).toLong();
+   }
+   const char* mapScale = kwl.find(prefix,
+                                   "map_scale");
+   if(mapScale)
+   {
+      theMapScale = ossimString(mapScale).toDouble();
+   }
+   const char *height = kwl.find(prefix,
+                                 ossimKeywordNames::NUMBER_LINES_KW);
+   const char *width  = kwl.find(prefix,
+                                 ossimKeywordNames::NUMBER_SAMPLES_KW);
+   if(height)
+   {
+      theHeight = ossimString(height).toDouble();
+   }
+   
+   if(width)
+   {
+      theWidth  = ossimString(width).toDouble();
+   }
+
+   computeParameters();
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCadrgProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCadrgProjection.h
new file mode 100644
index 0000000000..e764c74ded
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCadrgProjection.h
@@ -0,0 +1,101 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description: 
+//
+//*******************************************************************
+//  $Id: ossimCadrgProjection.h,v 1.9 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimCadrgProjection_HEADER
+#define ossimCadrgProjection_HEADER
+#include "ossimMapProjection.h"
+
+class ossimCadrgProjection : public ossimMapProjection
+{
+public:
+   ossimCadrgProjection();
+
+                       
+   virtual ~ossimCadrgProjection();
+   virtual ossimObject *dup()const;
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   
+   virtual ossimDpt worldToLineSample(const ossimGpt &worldPoint)    const;
+   virtual ossimGpt lineSampleToWorld(const ossimDpt &projectedPoint)const;
+   virtual void worldToLineSample(const ossimGpt &worldPoint,
+                                  ossimDpt&       lineSample)const;
+   virtual void lineSampleToWorld(const ossimDpt &projectedPoint,
+                                  ossimGpt& gpt)const;
+
+   double computeXPixConstant(double scale, long zone)const;
+   double computeYPixConstant(double scale)const;
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   
+   ossimString getProjectionName()const
+      {
+         return getClassName();
+      }
+      
+protected:
+   /*
+    * Are from the ADRG Mil spec for 1:1,000,000 and
+    * are scales for each zone.
+    */
+   static double theCadrgArcA[8];
+   
+
+   static double theOldZoneExtents[10];
+
+   static double theNorthLimit;
+   static double theSouthLimit;
+
+   long theCadrgZone;
+
+   ossimDpt thePixelConstant;
+   double theMapScale;
+
+   double theWidth;
+   double theHeight;
+
+   ossimDpt theUlLineSample;
+
+   ossimGpt theUlGpt;
+   ossimGpt theLlGpt;
+   ossimGpt theLrGpt;
+   ossimGpt theUrGpt;
+   
+   void computeParameters();
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCassiniProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCassiniProjection.cpp
new file mode 100644
index 0000000000..05b76cc526
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCassiniProjection.cpp
@@ -0,0 +1,546 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Cassini projection code.  
+//*******************************************************************
+//  $Id: ossimCassiniProjection.cpp,v 1.11 2004/01/08 21:49:21 jlargent Exp $
+
+#include <math.h>
+#include "ossimCassiniProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimCassiniProjection, "ossimCassiniProjection", ossimMapProjection)
+
+
+
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+
+#ifdef PI_OVER_2
+#  undef PI_OVER_2
+#endif
+
+#define CASS_NO_ERROR           0x0000
+#define CASS_LAT_ERROR          0x0001
+#define CASS_LON_ERROR          0x0002
+#define CASS_EASTING_ERROR      0x0004
+#define CASS_NORTHING_ERROR     0x0008
+#define CASS_ORIGIN_LAT_ERROR   0x0010
+#define CASS_CENT_MER_ERROR     0x0020
+#define CASS_A_ERROR            0x0040
+#define CASS_B_ERROR            0x0080
+#define CASS_A_LESS_B_ERROR     0x0100
+#define CASS_LON_WARNING        0x0200
+
+#define PI_OVER_2  ( M_PI / 2.0)                    
+#define CASS_M(c0lat, c1s2lat, c2s4lat, c3s6lat)  (Cass_a*(c0lat-c1s2lat+c2s4lat-c3s6lat))
+#define CASS_RD(sinlat)                           (sqrt(1.0 - es2 * (sinlat * sinlat)))
+#define CASS_COEFF_TIMES_SIN(coeff, x, latit)	  (coeff * (sin (x * latit)))
+#define FLOAT_EQ(x,v,epsilon)   (((v - epsilon) < x) && (x < (v + epsilon)))
+#define THIRTY_ONE  (31.0 * M_PI / 180.0)	  /* 31 degrees in radians */
+
+
+
+ossimCassiniProjection::ossimCassiniProjection(const ossimEllipsoid& ellipsoid,
+                                               const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimCassiniProjection::ossimCassiniProjection(const ossimEllipsoid& ellipsoid,
+                                               const ossimGpt& origin,
+                                               const double falseEasting,
+                                               const double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Cass_False_Easting  = falseEasting;
+   Cass_False_Northing = falseNorthing;
+   Cass_Min_Easting    = -20037508.4;
+   Cass_Max_Easting    = 20037508.4;
+   Cass_Min_Northing   = -56575846.0;
+   Cass_Max_Northing   = 56575846.0;
+   
+   update();
+}
+
+void ossimCassiniProjection::update()
+{      
+   Set_Cassini_Parameters(theEllipsoid.getA(),
+                          theEllipsoid.getFlattening(),
+                          theOrigin.latr(),
+                          theOrigin.lonr(),
+                          Cass_False_Easting,
+                          Cass_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimCassiniProjection::setFalseEasting(double falseEasting)
+{
+   Cass_False_Easting = falseEasting;
+   update();
+}
+
+void ossimCassiniProjection::setFalseNorthing(double falseNorthing)
+{
+   Cass_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimCassiniProjection::setFalseEastingNorthing(double falseEasting,
+                                                   double falseNorthing)
+{
+   Cass_False_Easting  = falseEasting;
+   Cass_False_Northing = falseNorthing;  
+   update();
+}
+
+void ossimCassiniProjection::setDefaults()
+{
+
+   Cass_Min_Easting    = -20037508.4;
+   Cass_Max_Easting    = 20037508.4;
+   Cass_Min_Northing   = -56575846.0;
+   Cass_Max_Northing   = 56575846.0;
+   Cass_False_Easting  = 0.0;
+   Cass_False_Northing = 0.0;
+}
+
+ossimGpt ossimCassiniProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Cassini_To_Geodetic(eastingNorthing.x,
+                               eastingNorthing.y,
+                               &lat,
+                               &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0, theDatum);  
+}
+
+ossimDpt ossimCassiniProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Cassini(gpt.latr(),
+                               gpt.lonr(),
+                               &easting,
+                               &northing);
+   return ossimDpt(easting, northing);
+
+}
+
+bool ossimCassiniProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Cass_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Cass_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimCassiniProjection::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimCassiniProjection))
+   {
+      if(falseEasting)
+      {
+         Cass_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Cass_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+   
+   return flag;
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+long ossimCassiniProjection::Set_Cassini_Parameters(double a,
+                                                    double f,
+                                                    double Origin_Latitude,
+                                                    double Central_Meridian,
+                                                    double False_Easting,
+                                                    double False_Northing)
+{ /* Begin Set_Cassini_Parameters */
+/*
+ * The function Set_Cassini_Parameters receives the ellipsoid parameters and
+ * Cassini projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise CASS_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double j,three_es4;
+  double x, e1, e2, e3, e4;
+  double lat, sin2lat, sin4lat, sin6lat;
+  double temp;
+//  double inv_f = 1 / f;
+  long Error_Code = CASS_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= CASS_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= CASS_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+//   { /* origin latitude out of range */
+//     Error_Code |= CASS_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= CASS_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Cass_a = a;
+    Cass_f = f;
+    Cass_Origin_Lat = Origin_Latitude;
+//     if (Central_Meridian > PI)
+//       Central_Meridian -= TWO_PI;
+    Cass_Origin_Long = Central_Meridian;
+    Cass_False_Northing = False_Northing;
+    Cass_False_Easting = False_Easting;
+    es2 = 2 * Cass_f - Cass_f * Cass_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    j = 45.0 * es6 / 1024.0;
+    three_es4 = 3.0 * es4;
+    c0 = 1 - es2 / 4.0 - three_es4 / 64.0 - 5.0 * es6 / 256.0; 
+    c1 = 3.0 * es2 /8.0 + three_es4 / 32.0 + j;
+    c2 = 15.0 * es4 / 256.0 + j;
+    c3 = 35.0 * es6 / 3072.0;
+    lat = c0 * Cass_Origin_Lat;
+    sin2lat = CASS_COEFF_TIMES_SIN(c1, 2.0, Cass_Origin_Lat);
+    sin4lat = CASS_COEFF_TIMES_SIN(c2, 4.0, Cass_Origin_Lat);
+    sin6lat = CASS_COEFF_TIMES_SIN(c3, 6.0, Cass_Origin_Lat);
+    M0 = CASS_M(lat, sin2lat, sin4lat, sin6lat);
+
+    One_Minus_es2 = 1.0 - es2;
+    x = sqrt (One_Minus_es2);
+    e1 = (1 - x) / (1 + x);
+    e2 = e1 * e1;
+    e3 = e2 * e1;
+    e4 = e3 * e1;
+    a0 = 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0;
+    a1 = 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0;
+    a2 = 151.0 * e3 / 96.0;
+    a3 = 1097.0 * e4 /512.0;
+
+    if (Cass_Origin_Long > 0)
+    {
+      Convert_Geodetic_To_Cassini(THIRTY_ONE, Cass_Origin_Long - M_PI, &temp, &Cass_Max_Northing);
+      Convert_Geodetic_To_Cassini(-THIRTY_ONE, Cass_Origin_Long - M_PI, &temp, &Cass_Min_Northing); 
+      Cass_Max_Easting = 19926188.9;
+      Cass_Min_Easting = -20037508.4;
+    }
+    else if (Cass_Origin_Long < 0)
+    {
+      Convert_Geodetic_To_Cassini(THIRTY_ONE, M_PI + Cass_Origin_Long, &temp, &Cass_Max_Northing); 
+      Convert_Geodetic_To_Cassini(-THIRTY_ONE, M_PI + Cass_Origin_Long, &temp, &Cass_Min_Northing);
+      Cass_Max_Easting = 20037508.4;
+      Cass_Min_Easting = -19926188.9;
+    }
+    else
+    {
+      Convert_Geodetic_To_Cassini(THIRTY_ONE, M_PI, &temp, &Cass_Max_Northing); 
+      Convert_Geodetic_To_Cassini(-THIRTY_ONE, M_PI , &temp, &Cass_Min_Northing);
+      Cass_Max_Easting = 20037508.4;
+      Cass_Min_Easting = -20037508.4;
+    }
+
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Cassini_Parameters */
+
+
+void ossimCassiniProjection::Get_Cassini_Parameters(double *a,
+                                                    double *f,
+                                                    double *Origin_Latitude,
+                                                    double *Central_Meridian,
+                                                    double *False_Easting,
+                                                    double *False_Northing)const
+{ /* Begin Get_Cassini_Parameters */
+/*
+ * The function Get_Cassini_Parameters returns the current ellipsoid
+ * parameters, Cassini projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid                   (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Cass_a;
+  *f = Cass_f;
+  *Origin_Latitude = Cass_Origin_Lat;
+  *Central_Meridian = Cass_Origin_Long;
+  *False_Easting = Cass_False_Easting;
+  *False_Northing = Cass_False_Northing;
+  
+  return;
+} /* End Get_Cassini_Parameters */
+
+
+long ossimCassiniProjection::Convert_Geodetic_To_Cassini (double Latitude,
+                                                          double Longitude,
+                                                          double *Easting,
+                                                          double *Northing)const
+{ /* Begin Convert_Geodetic_To_Cassini */
+/*
+ * The function Convert_Geodetic_To_Cassini converts geodetic (latitude and
+ * longitude) coordinates to Cassini projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Cassini projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise CASS_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double lat, sin2lat, sin4lat, sin6lat;
+  double RD;
+  double tlat = tan(Latitude);
+  double clat = cos(Latitude);
+  double slat = sin(Latitude);
+  double dlam;                      /* Longitude - Central Meridan */
+  double NN;
+  double TT;
+  double AA, A2, A3, A4, A5;
+  double CC;
+  double MM;
+  long Error_Code = CASS_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   { /* Latitude out of range */
+//     Error_Code |= CASS_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   { /* Longitude out of range */
+//     Error_Code |= CASS_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Cass_Origin_Long;
+
+    if (fabs(dlam) > (4.0 * M_PI / 180.0))
+    { /* Distortion will result if Longitude is more than 4 degrees from the Central Meridian */
+      Error_Code |= CASS_LON_WARNING;
+    }
+
+    if (dlam > M_PI)
+    {
+      dlam -= TWO_PI;
+    }
+    if (dlam < -M_PI)
+    {
+      dlam += TWO_PI;
+    }
+    RD = CASS_RD(slat);
+    NN = Cass_a / RD;
+    TT = tlat * tlat;
+    AA = dlam * clat;
+    A2 = AA * AA;
+    A3 = AA * A2;
+    A4 = AA * A3;
+    A5 = AA * A4;
+    CC = es2 * clat * clat / One_Minus_es2;
+    lat = c0 * Latitude;
+    sin2lat = CASS_COEFF_TIMES_SIN(c1, 2.0, Latitude);
+    sin4lat = CASS_COEFF_TIMES_SIN(c2, 4.0, Latitude);
+    sin6lat = CASS_COEFF_TIMES_SIN(c3, 6.0, Latitude);
+    MM = CASS_M(lat, sin2lat, sin4lat, sin6lat);
+
+    *Easting = NN * (AA - (TT * A3 / 6.0) - (8.0 - TT + 8.0 * CC) *
+                     (TT * A5 / 120.0)) + Cass_False_Easting;
+    *Northing = MM - M0 + NN * tlat * ((A2 / 2.0) + (5.0 - TT +
+                                                     6.0 * CC) * A4 / 24.0) + Cass_False_Northing;
+  }
+  return (Error_Code);
+} /* End Convert_Geodetic_To_Cassini */
+
+
+long ossimCassiniProjection::Convert_Cassini_To_Geodetic(double Easting,
+                                                         double Northing,
+                                                         double *Latitude,
+                                                         double *Longitude)const
+{ /* Begin Convert_Cassini_To_Geodetic */
+/*
+ * The function Convert_Cassini_To_Geodetic converts Cassini projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Cassini projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise CASS_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx;     /* Delta easting - Difference in easting (easting-FE)      */
+  double dy;     /* Delta northing - Difference in northing (northing-FN)   */
+  double mu1;
+  double sin2mu, sin4mu, sin6mu, sin8mu;
+  double M1;
+  double phi1;
+  double tanphi1, sinphi1, cosphi1;
+  double T1, T;
+  double N1;
+  double RD, R1;
+  double DD, D2, D3, D4, D5;
+//  const double epsilon = 1.0e-1;
+  long Error_Code = CASS_NO_ERROR;
+
+//   if ((Easting < (Cass_False_Easting + Cass_Min_Easting))
+//       || (Easting > (Cass_False_Easting + Cass_Max_Easting)))
+//   { /* Easting out of range */
+//     Error_Code |= CASS_EASTING_ERROR;
+//   }
+//   if ((Northing < (Cass_False_Northing + Cass_Min_Northing - epsilon))
+//       || (Northing > (Cass_False_Northing + Cass_Max_Northing + epsilon)))
+//   { /* Northing out of range */
+//     Error_Code |= CASS_NORTHING_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dy = Northing - Cass_False_Northing;
+    dx = Easting - Cass_False_Easting;
+    M1 = M0 + dy;
+    mu1 = M1 / (Cass_a * c0); 
+
+    sin2mu = CASS_COEFF_TIMES_SIN(a0, 2.0, mu1);
+    sin4mu = CASS_COEFF_TIMES_SIN(a1, 4.0, mu1);
+    sin6mu = CASS_COEFF_TIMES_SIN(a2, 6.0, mu1);
+    sin8mu = CASS_COEFF_TIMES_SIN(a3, 8.0, mu1);
+    phi1 = mu1 + sin2mu + sin4mu + sin6mu + sin8mu;
+
+    if (FLOAT_EQ(phi1,PI_OVER_2,.00001))
+    {
+      *Latitude =  PI_OVER_2;
+      *Longitude = Cass_Origin_Long;
+    }
+    else if (FLOAT_EQ(phi1,-PI_OVER_2,.00001))
+    {
+      *Latitude = -PI_OVER_2;
+      *Longitude = Cass_Origin_Long;
+    }
+    else
+    {
+      tanphi1 = tan(phi1);
+      sinphi1 = sin(phi1);
+      cosphi1 = cos(phi1);
+      T1 = tanphi1 * tanphi1;
+      RD = CASS_RD(sinphi1);
+      N1 = Cass_a / RD;
+      R1 = N1 * One_Minus_es2 / (RD * RD);
+      DD = dx / N1;
+      D2 = DD * DD;
+      D3 = D2 * DD;
+      D4 = D3 * DD;
+      D5 = D4 * DD;
+      T = (1.0 + 3.0 * T1);
+      *Latitude = phi1 - (N1 * tanphi1 / R1) * (D2 / 2.0 - T * D4 / 24.0);
+
+      *Longitude = Cass_Origin_Long + (DD - T1 * D3 / 3.0 + T * T1 * D5 / 15.0) / cosphi1;
+
+      if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+        *Latitude = PI_OVER_2;
+      else if (*Latitude < -PI_OVER_2)
+        *Latitude = -PI_OVER_2;
+
+//       if (*Longitude > PI)
+//         *Longitude -= TWO_PI;
+//       if (*Longitude < -PI)
+//         *Longitude += TWO_PI;
+
+      if (*Longitude > M_PI)  /* force distorted values to 180, -180 degrees */
+        *Longitude = M_PI;
+      else if (*Longitude < -M_PI)
+        *Longitude = -M_PI;
+    }
+    if (fabs(*Longitude - Cass_Origin_Long) > (4.0 * M_PI / 180.0))
+    { /* Distortion will result if Longitude is more than 4 degrees from the Central Meridian */
+      Error_Code |= CASS_LON_WARNING;
+    }
+  }
+  return (Error_Code);
+} /* End Convert_Cassini_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCassiniProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCassiniProjection.h
new file mode 100644
index 0000000000..23c2b9cb7f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCassiniProjection.h
@@ -0,0 +1,208 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Cassini projection code.  
+//*******************************************************************
+//  $Id: ossimCassiniProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimCassiniProjection_HEADER
+#define ossimCassiniProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimCassiniProjection : public ossimMapProjection
+{
+public:
+   ossimCassiniProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                          const ossimGpt& origin = ossimGpt());
+   ossimCassiniProjection(const ossimEllipsoid& ellipsoid,
+                          const ossimGpt& origin,
+                          const double falseEasting,
+                          const double falseNorthing);
+   ~ossimCassiniProjection(){}
+   virtual ossimObject *dup()const{return new ossimCassiniProjection(*this);}
+   
+   virtual ossimDpt forward(const ossimGpt &worldPoint)    const;
+   virtual ossimGpt inverse(const ossimDpt &projectedPoint)const;
+   virtual void update();
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   double getFalseEasting()const{return Cass_False_Easting;}
+   double getFalseNorthing()const{return Cass_False_Northing;}
+
+   /*!
+    * Initialize all pramters to default and calls update for
+    * pre-computations.
+    */
+   void setDefaults();
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+   
+   //_____________________GETRANS STUFF_____________________
+   
+   mutable double Cass_a;                      /* Semi-major axis of ellipsoid in meters */
+   mutable double Cass_f;              /* Flattening of ellipsoid */
+   mutable double es2;             /* Eccentricity (0.08181919084262188000) squared  */
+   mutable double es4;               /* es2 * es2 */
+   mutable double es6;              /* es4 * es2 */
+   mutable double M0;
+   mutable double c0;                    /* 1 - es2 / 4.0 - 3.0 * es4 / 64.0 - 5.0 * es6 / 256.0 */
+   mutable double c1;                  /* 3.0 * es2 / 8.0 + 3.0 * es4 / 32.0 + 45.0 * es6 / 1024.0 */
+   mutable double c2;               /* 15.0 * es4 / 256.0 + 45.0 * es6 / 1024.0 */
+   mutable double c3;               /* 35.0 * es6 / 3072.0 */
+   mutable double One_Minus_es2;         /* 1.0 - es2 */
+   mutable double a0;                  /* 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0 */
+   mutable double a1;               /* 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0 */
+   mutable double a2;               /* 151.0 * e3 / 96.0 */
+   mutable double a3;               /* 1097.0 * e4 /512.0 */
+   
+/* Cassini projection Parameters */
+   mutable double Cass_Origin_Lat;                   /* Latitude of origin in radians     */
+   mutable double Cass_Origin_Long;                  /* Longitude of origin in radians    */
+   mutable double Cass_False_Northing;               /* False northing in meters          */
+   mutable double Cass_False_Easting;                /* False easting in meters           */
+   
+ /* Maximum variance for easting and northing values for WGS 84.
+  */
+   mutable double Cass_Min_Easting;
+   mutable double Cass_Max_Easting;
+   mutable double Cass_Min_Northing;
+   mutable double Cass_Max_Northing;
+
+/*!
+ * The function Set_Cassini_Parameters receives the ellipsoid parameters and
+ * Cassini projcetion parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise CASS_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Cassini_Parameters(double a,
+                              double f,
+                              double Origin_Latitude,
+                              double Central_Meridian,
+                              double False_Easting,
+                              double False_Northing);
+
+
+/*!
+ * The function Get_Cassini_Parameters returns the current ellipsoid
+ * parameters, and Cassini projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Cassini_Parameters(double *a,
+                              double *f,
+                              double *Origin_Latitude,
+                              double *Central_Meridian,
+                              double *False_Easting,
+                              double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Cassini converts geodetic (latitude and
+ * longitude) coordinates to Cassini projection easting, and northing
+ * coordinates, according to the current ellipsoid and Cassini projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise CASS_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Cassini (double Latitude,
+                                    double Longitude,
+                                    double *Easting,
+                                    double *Northing)const; 
+
+
+/*!
+ * The function Convert_Cassini_To_Geodetic converts Cassini projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Cassini projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise CASS_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Cassini_To_Geodetic(double Easting,
+                                   double Northing,
+                                   double *Latitude,
+                                   double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCylEquAreaProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCylEquAreaProjection.cpp
new file mode 100644
index 0000000000..08fbe53752
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCylEquAreaProjection.cpp
@@ -0,0 +1,467 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Cylinder Equal Area  projection code.  
+//*******************************************************************
+//  $Id: ossimCylEquAreaProjection.cpp,v 1.11 2004/01/08 21:49:21 jlargent Exp $
+#include "ossimCylEquAreaProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimCylEquAreaProjection, "ossimCylEquAreaProjection", ossimMapProjection)
+   
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+#define CYEQ_NO_ERROR           0x0000
+#define CYEQ_LAT_ERROR          0x0001
+#define CYEQ_LON_ERROR          0x0002
+#define CYEQ_EASTING_ERROR      0x0004
+#define CYEQ_NORTHING_ERROR     0x0008
+#define CYEQ_ORIGIN_LAT_ERROR   0x0010
+#define CYEQ_CENT_MER_ERROR     0x0020
+#define CYEQ_A_ERROR            0x0040
+#define CYEQ_B_ERROR            0x0080
+#define CYEQ_A_LESS_B_ERROR     0x0100
+
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define CYLEQAR_Q(slat, x)                (1.0-es2)*(slat/(1.0-x*x)-(1.0/(2.0*es))*      \
+									          log((1.0-x)/(1.0+x))) 
+#define CYEQ_COEFF_TIMES_SIN(coeff, c, Beta)      (coeff * sin(c * Beta))
+#define ONE        (1.0 * M_PI / 180.0)  /* 1 degree in radians           */
+
+
+ossimCylEquAreaProjection::ossimCylEquAreaProjection(const ossimEllipsoid& ellipsoid,
+                                               const ossimGpt& origin)
+  :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimCylEquAreaProjection::ossimCylEquAreaProjection(const ossimEllipsoid& ellipsoid,
+                                                     const ossimGpt& origin,
+                                                     double falseEasting,
+                                                     double falseNorthing)
+  :ossimMapProjection(ellipsoid, origin)
+{
+   Cyeq_False_Easting  = falseEasting;
+   Cyeq_False_Northing = falseNorthing;
+   Cyeq_Max_Easting    = 20037509.0;
+   Cyeq_Min_Easting    = -20037509.0;
+   Cyeq_Delta_Northing = 6363886.0;
+
+   update();
+}
+
+void ossimCylEquAreaProjection::setFalseEasting(double falseEasting)
+{
+   Cyeq_False_Easting = falseEasting;
+   update();
+}
+
+void ossimCylEquAreaProjection::setFalseNorthing(double falseNorthing)
+{
+   Cyeq_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimCylEquAreaProjection::setFalseEastingNorthing(double falseEasting,
+                                                        double falseNorthing)
+{
+   Cyeq_False_Easting = falseEasting;
+   Cyeq_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimCylEquAreaProjection::setDefaults()
+{
+   Cyeq_False_Easting  = 0.0;
+   Cyeq_False_Northing = 0.0;
+   Cyeq_Max_Easting    = 20037509.0;
+   Cyeq_Min_Easting    = -20037509.0;
+   Cyeq_Delta_Northing = 6363886.0;
+}
+
+void ossimCylEquAreaProjection::update()
+{   
+   Cyeq_Max_Easting    = 20037509.0;
+   Cyeq_Min_Easting    = -20037509.0;
+   Cyeq_Delta_Northing = 6363886.0;
+
+   Set_Cyl_Eq_Area_Parameters(theEllipsoid.getA(),
+                              theEllipsoid.getFlattening(),
+                              theOrigin.latr(),
+                              theOrigin.lonr(),
+                              Cyeq_False_Easting,
+                              Cyeq_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+
+ossimGpt ossimCylEquAreaProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Cyl_Eq_Area_To_Geodetic(eastingNorthing.x,
+                                   eastingNorthing.y,
+                                   &lat,
+                                   &lon);
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0, theDatum);  
+}
+
+ossimDpt ossimCylEquAreaProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Cyl_Eq_Area(gpt.latr(),
+                                   gpt.lonr(),
+                                   &easting,
+                                   &northing);
+
+   return ossimDpt(easting, northing);
+
+}
+
+bool ossimCylEquAreaProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Cyeq_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Cyeq_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimCylEquAreaProjection::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimCylEquAreaProjection))
+   {
+      if(falseEasting)
+      {
+         Cyeq_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Cyeq_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+   
+   return flag;
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+long ossimCylEquAreaProjection::Set_Cyl_Eq_Area_Parameters(double a,
+                                                           double f,
+                                                           double Origin_Latitude,
+                                                           double Central_Meridian,
+                                                           double False_Easting,
+                                                           double False_Northing)
+{ /* Begin Set_Cyl_Eq_Area_Parameters */
+/*
+ * The function Set_Cyl_Eq_Area_Parameters receives the ellipsoid parameters and
+ * Cylindrical Equal Area projcetion parameters as inputs, and sets the corresponding 
+ * state variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise CYEQ_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double Sin_Cyeq_Origin_Lat;
+  double temp;
+//  double inv_f = 1 / f;
+  long Error_Code = CYEQ_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= CYEQ_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= CYEQ_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+//   { /* origin latitude out of range */
+//     Error_Code |= CYEQ_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= CYEQ_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Cyeq_a = a;
+    Cyeq_f = f;
+    Cyeq_Origin_Lat = Origin_Latitude;
+    if (Central_Meridian > M_PI)
+      Central_Meridian -= TWO_PI;
+    Cyeq_Origin_Long = Central_Meridian;
+    Cyeq_False_Northing = False_Northing;
+    Cyeq_False_Easting = False_Easting;
+    es2 = 2 * Cyeq_f - Cyeq_f * Cyeq_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    es = sqrt(es2);
+    c0 = es2 / 3.0 + 31.0 * es4 / 180.0 + 517.0 * es6 / 5040.0; 
+    c1 = 23.0 * es4 / 360.0 + 251.0 * es6 / 3780.0;
+    c2 = 761.0 * es6 / 45360.0; 
+    Sin_Cyeq_Origin_Lat = sin(Cyeq_Origin_Lat);
+    k0 = cos(Cyeq_Origin_Lat) / sqrt(1.0 - es2 * Sin_Cyeq_Origin_Lat * Sin_Cyeq_Origin_Lat);
+    Cyeq_a_k0 = Cyeq_a * k0;
+    two_k0 = 2.0 * k0;
+
+    if (Cyeq_Origin_Long > 0)
+    {
+      Convert_Geodetic_To_Cyl_Eq_Area(PI_OVER_2, Cyeq_Origin_Long - M_PI - ONE, &Cyeq_Max_Easting, &temp);
+      Convert_Geodetic_To_Cyl_Eq_Area(PI_OVER_2, Cyeq_Origin_Long - M_PI, &Cyeq_Min_Easting, &temp);
+      Convert_Geodetic_To_Cyl_Eq_Area(PI_OVER_2, M_PI, &temp, &Cyeq_Delta_Northing);
+    }
+    else if (Cyeq_Origin_Long < 0)
+    {
+      Convert_Geodetic_To_Cyl_Eq_Area(PI_OVER_2, Cyeq_Origin_Long + M_PI, &Cyeq_Max_Easting, &temp);
+      Convert_Geodetic_To_Cyl_Eq_Area(PI_OVER_2, Cyeq_Origin_Long + M_PI + ONE, &Cyeq_Min_Easting, &temp);
+      Convert_Geodetic_To_Cyl_Eq_Area(PI_OVER_2, M_PI, &temp, &Cyeq_Delta_Northing);  
+    }
+    else
+    {
+      Convert_Geodetic_To_Cyl_Eq_Area(PI_OVER_2, M_PI, &Cyeq_Max_Easting, &Cyeq_Delta_Northing);  
+      Cyeq_Min_Easting = -Cyeq_Max_Easting;
+    }
+
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Cyl_Eq_Area_Parameters */
+
+
+void ossimCylEquAreaProjection::Get_Cyl_Eq_Area_Parameters(double *a,
+                                                           double *f,
+                                                           double *Origin_Latitude,
+                                                           double *Central_Meridian,
+                                                           double *False_Easting,
+                                                           double *False_Northing)const
+{ /* Begin Get_Cyl_Eq_Area_Parameters */
+/*
+ * The function Get_Cyl_Eq_Area_Parameters returns the current ellipsoid
+ * parameters, and Cylindrical Equal Area projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Cyeq_a;
+  *f = Cyeq_f;
+  *Origin_Latitude = Cyeq_Origin_Lat;
+  *Central_Meridian = Cyeq_Origin_Long;
+  *False_Easting = Cyeq_False_Easting;
+  *False_Northing = Cyeq_False_Northing;
+  return;
+} /* End Get_Cyl_Eq_Area_Parameters */
+
+
+long ossimCylEquAreaProjection::Convert_Geodetic_To_Cyl_Eq_Area (double Latitude,
+                                                                 double Longitude,
+                                                                 double *Easting,
+                                                                 double *Northing)const
+{ /* Begin Convert_Geodetic_To_Cyl_Eq_Area */
+/*
+ * The function Convert_Geodetic_To_Cyl_Eq_Area converts geodetic (latitude and
+ * longitude) coordinates to Cylindrical Equal Area projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Cylindrical Equal Area projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise CYEQ_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double dlam;                      /* Longitude - Central Meridan */
+  double qq;
+  double x;
+  double sin_lat = sin(Latitude);
+  long Error_Code = CYEQ_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   { /* Latitude out of range */
+//     Error_Code |= CYEQ_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   { /* Longitude out of range */
+//     Error_Code |= CYEQ_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Cyeq_Origin_Long;
+//     if (dlam > PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+    x = es * sin_lat;
+    qq = CYLEQAR_Q(sin_lat,x);
+    *Easting = Cyeq_a_k0 * dlam + Cyeq_False_Easting;
+    *Northing = Cyeq_a * qq / two_k0 + Cyeq_False_Northing;
+  }
+  return (Error_Code);
+} /* End Convert_Geodetic_To_Cyl_Eq_Area */
+
+
+long ossimCylEquAreaProjection::Convert_Cyl_Eq_Area_To_Geodetic(double Easting,
+                                                                double Northing,
+                                                                double *Latitude,
+                                                                double *Longitude)const
+{ /* Begin Convert_Cyl_Eq_Area_To_Geodetic */
+/*
+ * The function Convert_Cyl_Eq_Area_To_Geodetic converts
+ * Cylindrical Equal Area projection (easting and northing) coordinates
+ * to geodetic (latitude and longitude) coordinates, according to the
+ * current ellipsoid and Cylindrical Equal Area projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise CYEQ_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double sin2beta, sin4beta, sin6beta;
+  double dx;     /* Delta easting - Difference in easting (easting-FE)      */
+  double dy;     /* Delta northing - Difference in northing (northing-FN)   */
+  double qp;
+  double beta;
+  double sin_lat = sin(PI_OVER_2);
+  double i;
+  double x;
+  long Error_Code = CYEQ_NO_ERROR;
+
+//   if ((Easting < (Cyeq_False_Easting + Cyeq_Min_Easting))
+//       || (Easting > (Cyeq_False_Easting + Cyeq_Max_Easting)))
+//   { /* Easting out of range */
+//     Error_Code |= CYEQ_EASTING_ERROR;
+//   }
+//   if ((Northing < (Cyeq_False_Northing - fabs(Cyeq_Delta_Northing)))
+//       || (Northing > (Cyeq_False_Northing + fabs(Cyeq_Delta_Northing))))
+//   { /* Northing out of range */
+//     Error_Code |= CYEQ_NORTHING_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dy = Northing - Cyeq_False_Northing;
+    dx = Easting - Cyeq_False_Easting;
+    x = es * sin_lat;
+    qp = CYLEQAR_Q(sin_lat,x);
+    i = two_k0 * dy / (Cyeq_a * qp);
+    if (i > 1.0)
+      i = 1.0;
+    else if (i < -1.0)
+      i = -1.0;
+    beta = asin(i);
+    sin2beta = CYEQ_COEFF_TIMES_SIN(c0, 2.0, beta);
+    sin4beta = CYEQ_COEFF_TIMES_SIN(c1, 4.0, beta);
+    sin6beta = CYEQ_COEFF_TIMES_SIN(c2, 6.0, beta);
+    *Latitude = beta + sin2beta + sin4beta + sin6beta;
+    *Longitude = Cyeq_Origin_Long + dx / Cyeq_a_k0;
+
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+
+//     if (*Longitude > PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -PI)
+//       *Longitude += TWO_PI;
+
+//     if (*Longitude > PI) /* force distorted values to 180, -180 degrees */
+//       *Longitude = PI;
+//     else if (*Longitude < -PI)
+//       *Longitude = -PI;
+
+
+  }
+  return (Error_Code);
+} /* End Convert_Cyl_Eq_Area_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCylEquAreaProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCylEquAreaProjection.h
new file mode 100644
index 0000000000..5db0607841
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimCylEquAreaProjection.h
@@ -0,0 +1,211 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Cylinder Equal Area  projection code.  
+//*******************************************************************
+//  $Id: ossimCylEquAreaProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimCylEquAreaProjection_HEADER
+#define ossimCylEquAreaProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimCylEquAreaProjection : public ossimMapProjection
+{
+public: 
+   ossimCylEquAreaProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                             const ossimGpt& origin = ossimGpt());
+   ossimCylEquAreaProjection(const ossimEllipsoid& ellipsoid,
+                             const ossimGpt& origin,
+                             double falseEasting,
+                             double falseNorthing);
+   ~ossimCylEquAreaProjection(){}
+   virtual ossimObject *dup()const
+      {
+         return new ossimCylEquAreaProjection(*this);
+      }
+
+   virtual ossimDpt forward(const ossimGpt &worldPoint)    const;
+   virtual ossimGpt inverse(const ossimDpt &projectedPoint)const;
+   virtual void update();
+   
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   double getFalseEasting()const{return  Cyeq_False_Easting;}
+   double getFalseNorthing()const{return Cyeq_False_Northing;}
+
+   /*!
+    * Initialize all pramters to default and calls update for
+    * pre-computations.
+    */
+   void setDefaults();
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+
+
+/* Ellipsoid Parameters, default to WGS 84 */
+   mutable double Cyeq_a;                     /* Semi-major axis of ellipsoid in meters */
+   mutable double Cyeq_f;             /* Flattening of ellipsoid */
+   mutable double es2;            /* Eccentricity (0.08181919084262188000) squared  */
+   mutable double es;                  /* Sqrt(es2) */
+   mutable double es4;             /* es2 * es2 */
+   mutable double es6;             /* es4 * es2 */
+   mutable double k0;
+   mutable double Cyeq_a_k0;                  /* Cyeq_a * k0 */
+   mutable double two_k0;                           /* 2.0 * k0 */
+   mutable double c0;                 /* es2 / 3.0 + 31.0 * es4 / 180.0 + 517.0 * es6 / 5040.0 */
+   mutable double c1;              /* 23.0 es4 / 360.0 + 251.0 * es6 / 3780.0 */
+   mutable double c2;              /* 761.0 * es6 / 45360.0 */
+   
+/* Cylindrical Equal Area projection Parameters */
+   mutable double Cyeq_Origin_Lat;                  /* Latitude of origin in radians     */
+   mutable double Cyeq_Origin_Long;                 /* Longitude of origin in radians    */
+   mutable double Cyeq_False_Northing;              /* False northing in meters          */
+   mutable double Cyeq_False_Easting;               /* False easting in meters           */
+   
+/* Maximum variance for easting and northing values for WGS 84.
+ */
+   mutable double Cyeq_Max_Easting;
+   mutable double Cyeq_Min_Easting;
+   mutable double Cyeq_Delta_Northing;
+
+/*!
+ * The function Set_Cyl_Eq_Area_Parameters receives the ellipsoid parameters and
+ * Cylindrical Equal Area projcetion parameters as inputs, and sets the corresponding 
+ * state variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise CYEQ_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Cyl_Eq_Area_Parameters(double a,
+                                  double f,
+                                  double Origin_Latitude,
+                                  double Central_Meridian,
+                                  double False_Easting,
+                                  double False_Northing);
+
+
+/*!
+ * The function Get_Cyl_Eq_Area_Parameters returns the current ellipsoid
+ * parameters and Cylindrical Equal Area projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */  void Get_Cyl_Eq_Area_Parameters(double *a,
+                                  double *f,
+                                  double *Origin_Latitude,
+                                  double *Central_Meridian,
+                                  double *False_Easting,
+                                  double *False_Northing)const;
+
+
+
+/*!
+ * The function Convert_Geodetic_To_Cyl_Eq_Area converts geodetic (latitude and
+ * longitude) coordinates to Cylindrical Equal Area projection easting, and northing
+ * coordinates, according to the current ellipsoid and Cylindrical Equal Area projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise CYEQ_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Cyl_Eq_Area (double Latitude,
+                                        double Longitude,
+                                        double *Easting,
+                                        double *Northing)const; 
+
+
+/*!
+ * The function Convert_Cyl_Eq_Area_To_Geodetic converts Cylindrical Equal Area projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Cylindrical Equal Area projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise CYEQ_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Cyl_Eq_Area_To_Geodetic(double Easting,
+                                       double Northing,
+                                       double *Latitude,
+                                       double *Longitude)const;
+
+/*!
+ * RTTI information found in data_types/rtti.h
+ */
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert4Projection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert4Projection.cpp
new file mode 100644
index 0000000000..681dbf40f5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert4Projection.cpp
@@ -0,0 +1,462 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Eckert4 projection code.  
+//*******************************************************************
+//  $Id: ossimEckert4Projection.cpp,v 1.11 2004/01/08 21:49:21 jlargent Exp $
+#include "ossimEckert4Projection.h"
+
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimEckert4Projection, "ossimEckert4Projection", ossimMapProjection)
+
+
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define NUM(Theta, SinTheta, CosTheta)   (Theta + SinTheta * CosTheta + 2.0 * SinTheta)
+
+
+#define ECK4_NO_ERROR           0x0000
+#define ECK4_LAT_ERROR          0x0001
+#define ECK4_LON_ERROR          0x0002
+#define ECK4_EASTING_ERROR      0x0004
+#define ECK4_NORTHING_ERROR     0x0008
+#define ECK4_CENT_MER_ERROR     0x0020
+#define ECK4_A_ERROR            0x0040
+#define ECK4_B_ERROR            0x0080
+#define ECK4_A_LESS_B_ERROR     0x0100
+
+/***************************************************************************/
+/*
+ *                               GLOBALS
+ */
+
+const double two_PLUS_PI_OVER_2 = (2.0 + M_PI / 2.0);
+
+ossimEckert4Projection::ossimEckert4Projection(const ossimEllipsoid& ellipsoid,
+                                               const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimEckert4Projection::ossimEckert4Projection(const ossimEllipsoid& ellipsoid,
+                                               const ossimGpt& origin,
+                                               double falseEasting,
+                                               double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   
+   Eck4_False_Easting  = falseEasting;
+   Eck4_False_Northing = falseNorthing;
+   Eck4_Delta_Northing = 8451144.0;
+   Eck4_Max_Easting    = 16902288.0;
+   Eck4_Min_Easting    = -16902288.0;
+
+   update();
+}
+
+
+void ossimEckert4Projection::update()
+{   
+   
+   Set_Eckert4_Parameters(theEllipsoid.getA(),
+                          theEllipsoid.getFlattening(),
+                          theOrigin.lonr(),
+                          Eck4_False_Easting,
+                          Eck4_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+ossimGpt ossimEckert4Projection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat  = 0.0;
+   double lon = 0.0;
+   
+   Convert_Eckert4_To_Geodetic(eastingNorthing.x,
+                               eastingNorthing.y,
+                               &lat,
+                               &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimEckert4Projection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Eckert4(gpt.latr(),
+                               gpt.lonr(),
+                               &easting,
+                               &northing);
+
+   return ossimDpt(easting, northing);
+}
+
+void ossimEckert4Projection::setFalseEasting(double falseEasting)
+{
+   Eck4_False_Easting = falseEasting;
+   update();
+}
+
+void ossimEckert4Projection::setFalseNorthing(double falseNorthing)
+{
+   Eck4_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimEckert4Projection::setFalseEastingNorthing(double falseEasting,
+                                                        double falseNorthing)
+{
+   Eck4_False_Easting = falseEasting;
+   Eck4_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimEckert4Projection::setDefaults()
+{
+   Eck4_Delta_Northing  = 8451144.0;
+   Eck4_Max_Easting     = 16902288.0;
+   Eck4_Min_Easting     = -16902288.0;
+   Eck4_False_Easting   = 0.0;
+   Eck4_False_Northing  = 0.0;
+}
+
+bool ossimEckert4Projection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Eck4_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Eck4_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimEckert4Projection::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimEckert4Projection))
+   {
+      if(falseEasting)
+      {
+         Eck4_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Eck4_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+   
+   return flag;
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS
+ */
+
+
+long ossimEckert4Projection::Set_Eckert4_Parameters(double a,
+                                                    double f,                
+                                                    double Central_Meridian,
+                                                    double False_Easting,
+                                                    double False_Northing)
+
+{ /* Begin Set_Eckert4_Parameters */
+/*
+ * The function Set_Eckert4_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise ECK4_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double Ra;              /* Spherical radius */
+//  double inv_f = 1 / f;
+  long Error_Code = ECK4_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= ECK4_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= ECK4_INV_F_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= ECK4_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Eck4_a = a;
+    Eck4_f = f;
+    es2 = 2 * Eck4_f - Eck4_f * Eck4_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    /* spherical radius */
+    Ra = Eck4_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 / 3024.0);
+    Ra0 = 0.4222382 * Ra;
+    Ra1 = 1.3265004 * Ra;
+//     if (Central_Meridian > PI)
+//       Central_Meridian -= TWO_PI;
+    Eck4_Origin_Long = Central_Meridian;
+    Eck4_False_Easting = False_Easting;
+    Eck4_False_Northing = False_Northing;
+    if (Eck4_Origin_Long > 0)
+    {
+      Eck4_Max_Easting = 16808386.0;
+      Eck4_Min_Easting = -16902288.0;
+    }
+    else if (Eck4_Origin_Long < 0)
+    {
+      Eck4_Max_Easting = 16902288.0;
+      Eck4_Min_Easting = -16808386.0;
+    }
+    else
+    {
+      Eck4_Max_Easting = 16902288.0;
+      Eck4_Min_Easting = -16902288.0;
+    }
+
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Eckert4_Parameters */
+
+
+void ossimEckert4Projection::Get_Eckert4_Parameters(double *a,
+                                                    double *f,
+                                                    double *Central_Meridian,
+                                                    double *False_Easting,
+                                                    double *False_Northing)const
+{ /* Begin Get_Eckert4_Parameters */
+/*
+ * The function Get_Eckert4_Parameters returns the current ellipsoid
+ * parameters and Eckert IV projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid		    (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Eck4_a;
+  *f = Eck4_f;
+  *Central_Meridian = Eck4_Origin_Long;
+  *False_Easting = Eck4_False_Easting;
+  *False_Northing = Eck4_False_Northing;
+  return;
+} /* End Get_Eckert4_Parameters */
+
+
+long ossimEckert4Projection::Convert_Geodetic_To_Eckert4 (double Latitude,
+                                                          double Longitude,
+                                                          double *Easting,
+                                                          double *Northing)const
+
+{ /* Begin Convert_Geodetic_To_Eckert4 */
+/*
+ * The function Convert_Geodetic_To_Eckert4 converts geodetic (latitude and
+ * longitude) coordinates to Eckert IV projection (easting and northing)
+ * coordinates, according to the current ellipsoid, spherical radius and
+ * Eckert IV projection parameters.
+ * If any errors occur, the error code(s) are returned by the
+ * function, otherwise ECK4_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double slat = sin(Latitude);
+  double sin_theta, cos_theta;
+  double num;
+  double dlam;     /* Longitude - Central Meridan */
+  double theta = Latitude / 2.0;
+  double delta_theta = 1.0;
+  double dt_tolerance = 4.85e-10;        /* approximately 1/1000th of
+                                            an arc second or 1/10th meter */
+  long Error_Code = ECK4_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   {  /* Latitude out of range */
+//     Error_Code |= ECK4_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   {  /* Longitude out of range */
+//     Error_Code|= ECK4_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    dlam = Longitude - Eck4_Origin_Long;
+//     if (dlam > PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+    while (fabs(delta_theta) > dt_tolerance)
+    {
+       sin_theta = sin(theta);
+       cos_theta = cos(theta);
+       num = NUM(theta, sin_theta, cos_theta);
+       delta_theta = -(num - two_PLUS_PI_OVER_2 * slat) /
+                     (2.0 * cos_theta * (1.0 + cos_theta));
+       theta += delta_theta;
+    }
+    *Easting = Ra0 * dlam * (1.0 + cos(theta)) + Eck4_False_Easting;
+    *Northing = Ra1 * sin(theta) + Eck4_False_Northing; 
+  }
+  
+  return (Error_Code);
+
+} /* End Convert_Geodetic_To_Eckert4 */
+
+
+long ossimEckert4Projection::Convert_Eckert4_To_Geodetic(double Easting,
+                                                         double Northing,
+                                                         double *Latitude,
+                                                         double *Longitude)const
+{ /* Begin Convert_Eckert4_To_Geodetic */
+/*
+ * The function Convert_Eckert4_To_Geodetic converts Eckert IV projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid, spherical radius and
+ * Eckert IV projection coordinates.
+ * If any errors occur, the error code(s) are returned by the
+ * function, otherwise ECK4_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double theta;
+  double sin_theta, cos_theta;
+  double num;
+  double dx, dy;
+  double i;
+
+  long Error_Code = ECK4_NO_ERROR;
+
+//   if ((Easting < (Eck4_False_Easting + Eck4_Min_Easting))
+//       || (Easting > (Eck4_False_Easting + Eck4_Max_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= ECK4_EASTING_ERROR;
+//   }
+//   if ((Northing < (Eck4_False_Northing - Eck4_Delta_Northing)) 
+//       || (Northing > (Eck4_False_Northing + Eck4_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= ECK4_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  {
+    dy = Northing - Eck4_False_Northing;
+    dx = Easting - Eck4_False_Easting;
+    i = dy / Ra1;
+    if (i > 1.0)
+      i = 1.0;
+    else if (i < -1.0)
+      i = -1.0;
+
+    theta = asin(i);
+    sin_theta = sin(theta);
+    cos_theta = cos(theta);
+    num = NUM(theta, sin_theta, cos_theta);
+
+    *Latitude = asin(num / two_PLUS_PI_OVER_2);
+    *Longitude = Eck4_Origin_Long + dx / (Ra0 * (1 + cos_theta));
+
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+
+//     if (*Longitude > PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -PI)
+//       *Longitude += TWO_PI;
+
+//     if (*Longitude > PI)  /* force distorted values to 180, -180 degrees */
+//       *Longitude = PI;
+//     else if (*Longitude < -PI)
+//       *Longitude = -PI;
+
+  }
+  return (Error_Code);
+
+} /* End Convert_Eckert4_To_Geodetic */
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert4Projection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert4Projection.h
new file mode 100644
index 0000000000..f3e314b723
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert4Projection.h
@@ -0,0 +1,193 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Eckert4 projection code.  
+//*******************************************************************
+//  $Id: ossimEckert4Projection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimEcker4Projection_HEADER
+#define ossimEcker4Projection_HEADER
+#include "ossimMapProjection.h"
+
+class ossimEckert4Projection : public ossimMapProjection
+{
+public:
+    
+   ossimEckert4Projection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                          const ossimGpt& origin = ossimGpt());
+   ossimEckert4Projection(const ossimEllipsoid& ellipsoid,
+                          const ossimGpt& origin,
+                          double falseEasting,
+                          double falseNorthing);
+   ~ossimEckert4Projection(){}
+   virtual ossimObject *dup()const
+      {
+         return new ossimEckert4Projection(*this);
+      }
+   
+   virtual ossimDpt forward(const ossimGpt &worldPoint)     const;
+   virtual ossimGpt inverse(const ossimDpt &projectedPoint) const;
+   virtual void update();
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   double getFalseEasting()const{return  Eck4_False_Easting;}
+   double getFalseNorthing()const{return Eck4_False_Northing;}
+
+   /*!
+    * Initialize all pramters to default and calls update for
+    * pre-computations.
+    */
+   void setDefaults();
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+/* Ellipsoid Parameters, default to WGS 84 */
+   mutable double Eck4_a;                      /* Semi-major axis of ellipsoid in meters */
+   mutable double Eck4_f;              /* Flattening of ellipsoid */
+   mutable double es2;             /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;              /* es2 * es2  */
+   mutable double es6;              /* es4 * es2  */
+   
+   mutable double Ra0;                   /* 0.4222382 * Sperical Radius (6371007.1810824) */
+   mutable double Ra1;                   /* 1.3265004 * Sperical Radius (6371007.1810824) */
+   
+/* Eckert4 projection Parameters */
+   mutable double Eck4_Origin_Long;                  /* Longitude of origin in radians    */
+   mutable double Eck4_False_Easting;
+   mutable double Eck4_False_Northing;
+   mutable double Eck4_Delta_Northing;
+   mutable double Eck4_Max_Easting;
+   mutable double Eck4_Min_Easting;
+   
+/*!
+ * The function Set_Eckert4_Parameters receives the ellipsoid parameters and
+ * Eckert IV projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise ECK4_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Eckert4_Parameters(double a,
+                              double f,                           
+                              double Central_Meridian,
+                              double False_Easting,
+                              double False_Northing);
+
+
+/*!
+ * The function Get_Eckert4_Parameters returns the current ellipsoid
+ * parameters and EckertIV projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Eckert4_Parameters(double *a,
+                              double *f,                            
+                              double *Central_Meridian,
+                              double *False_Easting,
+                              double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Eckert4 converts geodetic (latitude and
+ * longitude) coordinates to Eckert IV projection easting, and northing
+ * coordinates, according to the current ellipsoid and Eckert IV projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ECK4_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Eckert4 (double Latitude,
+                                    double Longitude,
+                                    double *Easting,
+                                    double *Northing)const;
+
+
+/*!
+ * The function Convert_Eckert4_To_Geodetic converts Eckert IV projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Eckert IV projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ECK4_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Eckert4_To_Geodetic(double Easting,
+                                   double Northing,
+                                   double *Latitude,
+                                   double *Longitude)const;
+
+/*!
+ * RTTI information
+ */
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert6Projection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert6Projection.cpp
new file mode 100644
index 0000000000..1c1cb65a78
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert6Projection.cpp
@@ -0,0 +1,445 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Eckert6 projection code.  
+//*******************************************************************
+//  $Id: ossimEckert6Projection.cpp,v 1.10 2004/01/08 21:49:21 jlargent Exp $
+
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+#include "ossimEckert6Projection.h"
+
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimEckert6Projection, "ossimEckert6Projection", ossimMapProjection)
+
+#define ECK6_NO_ERROR           0x0000
+#define ECK6_LAT_ERROR          0x0001
+#define ECK6_LON_ERROR          0x0002
+#define ECK6_EASTING_ERROR      0x0004
+#define ECK6_NORTHING_ERROR     0x0008
+#define ECK6_CENT_MER_ERROR     0x0020
+#define ECK6_A_ERROR            0x0040
+#define ECK6_B_ERROR            0x0080
+#define ECK6_A_LESS_B_ERROR     0x0100
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+
+#define MAX_LAT    ( (M_PI * 90.0) / 180.0 )  /* 90 degrees in radians    */
+
+/***************************************************************************/
+/*
+ *                               GLOBALS
+ */
+
+const double one_PLUS_PI_OVER_2 = (1.0 + M_PI / 2.0);
+
+ossimEckert6Projection::ossimEckert6Projection(const ossimEllipsoid& ellipsoid,
+                                               const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+}
+
+ossimEckert6Projection::ossimEckert6Projection(const ossimEllipsoid& ellipsoid,
+                                               const ossimGpt& origin,
+                                               double falseEasting,
+                                               double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Eck6_False_Easting  = falseEasting;
+   Eck6_False_Northing = falseNorthing;
+   Eck6_Delta_Northing  = 8451144.0;
+   Eck6_Max_Easting     = 16902288.0;
+   Eck6_Min_Easting     = -16902288.0;
+   
+   update();
+}
+
+void ossimEckert6Projection::update()
+{
+   Set_Eckert6_Parameters(theEllipsoid.getA(),
+                          theEllipsoid.getFlattening(),
+                          theOrigin.lonr(),
+                          Eck6_False_Easting,
+                          Eck6_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+ossimGpt ossimEckert6Projection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Eckert6_To_Geodetic(eastingNorthing.x,
+                               eastingNorthing.y,
+                               &lat,
+                               &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimEckert6Projection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Eckert6(gpt.latr(),
+                               gpt.lonr(),
+                               &easting,
+                               &northing);
+   
+   return ossimDpt(easting, northing);
+}
+void ossimEckert6Projection::setFalseEasting(double falseEasting)
+{
+   Eck6_False_Easting = falseEasting;
+   update();
+}
+
+void ossimEckert6Projection::setFalseNorthing(double falseNorthing)
+{
+   Eck6_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimEckert6Projection::setFalseEastingNorthing(double falseEasting,
+                                                        double falseNorthing)
+{
+   Eck6_False_Easting = falseEasting;
+   Eck6_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimEckert6Projection::setDefaults()
+{
+   Eck6_Delta_Northing  = 8451144.0;
+   Eck6_Max_Easting     = 16902288.0;
+   Eck6_Min_Easting     = -16902288.0;
+   Eck6_False_Easting   = 0.0;
+   Eck6_False_Northing  = 0.0;
+   
+   update();
+}
+
+bool ossimEckert6Projection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Eck6_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Eck6_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimEckert6Projection::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimEckert6Projection))
+   {
+      if(falseEasting)
+      {
+         Eck6_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Eck6_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+   
+   return flag;
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS
+ */
+
+
+long ossimEckert6Projection::Set_Eckert6_Parameters(double a,
+                                                    double f,
+                                                    double Central_Meridian,
+                                                    double False_Easting,
+                                                    double False_Northing)
+{ /* Begin Set_Eckert6_Parameters */
+/*
+ * The function Set_Eckert6_Parameters receives the ellipsoid parameters and
+ * Eckert VI projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise ECK6_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double Ra;                      /* Spherical radius */
+//  double inv_f = 1 / f;
+  long Error_Code = ECK6_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= ECK6_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= ECK6_INV_F_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= ECK6_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Eck6_a = a;
+    Eck6_f = f;
+    es2 = 2 * Eck6_f - Eck6_f * Eck6_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    /* spherical radius */
+    Ra = Eck6_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 /3024.0);
+    Ra_Over_Sqrt_Two_Plus_PI = Ra / (sqrt(2.0 + M_PI));
+    Inv_Ra_Over_Sqrt_Two_Plus_PI = 1 / Ra_Over_Sqrt_Two_Plus_PI;
+//     if (Central_Meridian > PI)
+//       Central_Meridian -= TWO_PI;
+    Eck6_Origin_Long = Central_Meridian;
+    Eck6_False_Easting = False_Easting;
+    Eck6_False_Northing = False_Northing;
+    if (Eck6_Origin_Long > 0)
+    {
+      Eck6_Max_Easting = 17555761.0;
+      Eck6_Min_Easting = -17653839.0;
+    }
+    else if (Eck6_Origin_Long < 0)
+    {
+      Eck6_Max_Easting = 17653838.0;
+      Eck6_Min_Easting = -17555761.0;
+    }
+    else
+    {
+      Eck6_Max_Easting = 17653838.0;
+      Eck6_Min_Easting = -17653838.0;
+    }
+
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Eckert6_Parameters */
+
+
+void ossimEckert6Projection::Get_Eckert6_Parameters(double *a,
+                                                    double *f,
+                                                    double *Central_Meridian,
+                                                    double *False_Easting,
+                                                    double *False_Northing)const
+{ /* Begin Get_Eckert6_Parameters */
+/*
+ * The function Get_Eckert6_Parameters returns the current ellipsoid
+ * parameters and Eckert VI projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Eck6_a;
+  *f = Eck6_f;
+  *Central_Meridian = Eck6_Origin_Long;
+  *False_Easting = Eck6_False_Easting;
+  *False_Northing = Eck6_False_Northing;
+  
+  return;
+} /* End Get_Eckert6_Parameters */
+
+
+long ossimEckert6Projection::Convert_Geodetic_To_Eckert6 (double Latitude,
+                                                          double Longitude,
+                                                          double *Easting,
+                                                          double *Northing)const
+
+{ /* Begin Convert_Geodetic_To_Eckert6 */
+/*
+ * The function Convert_Geodetic_To_Eckert6 converts geodetic (latitude and
+ * longitude) coordinates to Eckert VI projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Eckert VI projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ECK6_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double slat = sin(Latitude);
+  double dlam;     /* Longitude - Central Meridan */
+  double theta = Latitude;
+  double delta_theta = 1.0;
+  double dt_tolerance = 4.85e-10;        /* approximately 1/1000th of
+                                             an arc second or 1/10th meter */
+  long Error_Code = ECK6_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   {  /* Latitude out of range */
+//     Error_Code |= ECK6_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   {  /* Longitude out of range */
+//     Error_Code|= ECK6_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    dlam = Longitude - Eck6_Origin_Long;
+//     if (dlam > PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+    while (fabs(delta_theta) > dt_tolerance)
+    {
+      delta_theta = -(theta + sin(theta) - one_PLUS_PI_OVER_2 *
+                      slat) / (1.0 + cos(theta));
+      theta += delta_theta;
+    }
+    *Easting = Ra_Over_Sqrt_Two_Plus_PI * dlam * (1.0 + cos(theta)) +
+               Eck6_False_Easting;
+    *Northing = 2.0 * Ra_Over_Sqrt_Two_Plus_PI  * theta + Eck6_False_Northing;
+
+  }
+  return (Error_Code);
+
+} /* End Convert_Geodetic_To_Eckert6 */
+
+
+long ossimEckert6Projection::Convert_Eckert6_To_Geodetic(double Easting,
+                                                         double Northing,
+                                                         double *Latitude,
+                                                         double *Longitude)const
+{ /* Begin Convert_Eckert6_To_Geodetic */
+/*
+ * The function Convert_Eckert6_To_Geodetic converts Eckert VI projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Eckert VI projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ECK6_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx, dy;
+  double theta;
+  double i;
+
+  long Error_Code = ECK6_NO_ERROR;
+
+//   if ((Easting < (Eck6_False_Easting + Eck6_Min_Easting))
+//       || (Easting > (Eck6_False_Easting + Eck6_Max_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= ECK6_EASTING_ERROR;
+//   }
+//   if ((Northing < (Eck6_False_Northing - Eck6_Delta_Northing))
+//       || (Northing > (Eck6_False_Northing + Eck6_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= ECK6_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  {
+    dy = Northing - Eck6_False_Northing;
+    dx = Easting - Eck6_False_Easting;
+    theta = Inv_Ra_Over_Sqrt_Two_Plus_PI * dy / 2.0;
+    i = (theta + sin(theta)) / one_PLUS_PI_OVER_2;
+    if (i > 1.0)
+      *Latitude = MAX_LAT;
+    else if (i < -1.0)
+      *Latitude = -MAX_LAT;
+    else
+      *Latitude = asin(i);
+    *Longitude = Eck6_Origin_Long + Inv_Ra_Over_Sqrt_Two_Plus_PI * dx / (1 + cos(theta));
+
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+
+//     if (*Longitude > PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -PI)
+//       *Longitude += TWO_PI;
+
+//     if (*Longitude > PI)  /* force distorted values to 180, -180 degrees */
+//       *Longitude = PI;
+//     else if (*Longitude < -PI)
+//       *Longitude = -PI;
+
+  }
+  return (Error_Code);
+
+} /* End Convert_Eckert6_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert6Projection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert6Projection.h
new file mode 100644
index 0000000000..74db055c2f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEckert6Projection.h
@@ -0,0 +1,193 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Eckert6 projection code.  
+//*******************************************************************
+//  $Id: ossimEckert6Projection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimEckert6Projection_HEADER
+#define ossimEckert6Projection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimEckert6Projection : public ossimMapProjection
+{
+public:   
+   ossimEckert6Projection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                          const ossimGpt& origin = ossimGpt());
+   ossimEckert6Projection(const ossimEllipsoid& ellipsoid,
+                          const ossimGpt& origin,
+                          double falseEasting,
+                          double falseNorthing);
+   ~ossimEckert6Projection(){}
+   virtual ossimObject *dup()const{return new ossimEckert6Projection(*this);}
+
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+   
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   double getFalseEasting()const{return  Eck6_False_Easting;}
+   double getFalseNorthing()const{return Eck6_False_Northing;}
+
+   /*!
+    * Initialize all pramters to default and calls update for
+    * pre-computations.
+    */
+   void setDefaults();
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+
+   //__________________GEOTRANS STUFF____________________
+   
+   mutable double Eck6_a;                      /* Semi-major axis of ellipsoid in meters */
+   mutable double Eck6_f;              /* Flattening of ellipsoid */
+   mutable double es2;             /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;              /* es2 * es2	*/
+   mutable double es6;              /* es4 * es2  */
+   mutable double Ra_Over_Sqrt_Two_Plus_PI;      /* Ra(6371007.1810824)/Sqrt(2.0 + PI) */
+   mutable double Inv_Ra_Over_Sqrt_Two_Plus_PI; /* Sqrt(2.0 + PI)/Ra(6371007.1810824) */
+   
+   
+/* Eckert6 projection Parameters */
+   mutable double Eck6_Origin_Long;                         /* Longitude of origin in radians    */
+   mutable double Eck6_False_Easting;
+   mutable double Eck6_False_Northing;
+   mutable double Eck6_Delta_Northing;
+   mutable double Eck6_Max_Easting;
+   mutable double Eck6_Min_Easting;
+
+   
+/*!
+ * The function Set_Eckert6_Parameters receives the ellipsoid parameters and
+ * Eckert VI projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise ECK6_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Eckert6_Parameters(double a,
+                              double f,
+                              double Central_Meridian,
+                              double False_Easting,
+                              double False_Northing);
+
+
+/*!
+ * The function Get_Eckert6_Parameters returns the current ellipsoid
+ * parameters and Eckert VI projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Eckert6_Parameters(double *a,
+                              double *f,
+                              double *Central_Meridian,
+                              double *False_Easting,
+                              double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Eckert6 converts geodetic (latitude and
+ * longitude) coordinates to Eckert VI projection easting, and northing
+ * coordinates, according to the current ellipsoid and Eckert VI projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ECK6_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Eckert6 (double Latitude,
+                                    double Longitude,
+                                    double *Easting,
+                                    double *Northing)const;
+
+
+/*!
+ * The function Convert_Eckert6_To_Geodetic converts Eckert VI projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Eckert VI projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ECK6_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Eckert6_To_Geodetic(double Easting,
+                                   double Northing,
+                                   double *Latitude,
+                                   double *Longitude)const;
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEquDistCylProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEquDistCylProjection.cpp
new file mode 100644
index 0000000000..ce9e2a9fe8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEquDistCylProjection.cpp
@@ -0,0 +1,466 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Equidistant Cylinder projection code.  
+//*******************************************************************
+//  $Id: ossimEquDistCylProjection.cpp,v 1.24 2005/02/10 12:15:59 gpotts Exp $
+
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/context/ossimNotifyContext.h>
+
+static ossimTrace traceDebug("ossimEquDistCylProjection:debug");
+
+RTTI_DEF1(ossimEquDistCylProjection,
+          "ossimEquDistCylProjection",
+          ossimLlxyProjection)
+   
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define ONE	   (1.0 * M_PI / 180.0)       /* 1 degree in radians*/
+
+#define EQCY_NO_ERROR           0x0000
+#define EQCY_LAT_ERROR          0x0001
+#define EQCY_LON_ERROR          0x0002
+#define EQCY_EASTING_ERROR      0x0004
+#define EQCY_NORTHING_ERROR     0x0008
+#define EQCY_ORIGIN_LAT_ERROR   0x0010
+#define EQCY_CENT_MER_ERROR     0x0020
+#define EQCY_A_ERROR            0x0040
+#define EQCY_B_ERROR            0x0080
+#define EQCY_A_LESS_B_ERROR     0x0100
+
+
+ossimEquDistCylProjection::ossimEquDistCylProjection(const ossimEllipsoid& ellipsoid,
+                                                     const ossimGpt& origin)
+  :ossimLlxyProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimEquDistCylProjection::ossimEquDistCylProjection(const ossimEllipsoid& ellipsoid,
+                                                     const ossimGpt& origin,
+                                                     double falseEasting,
+                                                     double falseNorthing)
+  :ossimLlxyProjection(ellipsoid, origin)
+{
+   Eqcy_False_Easting  = falseEasting;
+   Eqcy_False_Northing = falseNorthing;
+
+   Eqcy_Delta_Northing = 10007555.0;
+   Eqcy_Max_Easting    = 20015110.0;
+   Eqcy_Min_Easting    = -20015110.0;
+   
+   update();
+}
+
+void ossimEquDistCylProjection::update()
+{
+
+   Set_Equidistant_Cyl_Parameters(theEllipsoid.getA(),
+                                  theEllipsoid.getFlattening(),
+                                  theOrigin.latr(),
+                                  theOrigin.lonr(),
+                                  Eqcy_False_Easting,
+                                  Eqcy_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimEquDistCylProjection::setFalseEasting(double falseEasting)
+{
+   Eqcy_False_Easting = falseEasting;
+   update();
+}
+
+void ossimEquDistCylProjection::setFalseNorthing(double falseNorthing)
+{
+   Eqcy_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimEquDistCylProjection::setFalseEastingNorthing(double falseEasting,
+                                                        double falseNorthing)
+{
+   Eqcy_False_Easting  = falseEasting;
+   Eqcy_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimEquDistCylProjection::setDefaults()
+{
+   Eqcy_False_Easting  = 0.0;
+   Eqcy_False_Northing = 0.0;
+   Eqcy_Delta_Northing = 10007555.0;
+   Eqcy_Max_Easting    = 20015110.0;
+   Eqcy_Min_Easting    = -20015110.0;
+}
+
+ossimGpt ossimEquDistCylProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+
+   Convert_Equidistant_Cyl_To_Geodetic(eastingNorthing.x,
+                                       eastingNorthing.y,
+                                       &lat,
+                                       &lon);
+
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);
+}
+
+ossimDpt ossimEquDistCylProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Equidistant_Cyl(gpt.latr(),
+                                       gpt.lonr(),
+                                       &easting,
+                                       &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+
+
+bool ossimEquDistCylProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   ossimMapProjection::saveState(kwl, prefix);
+   
+   
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Eqcy_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Eqcy_False_Northing,
+           true);
+   
+   return true;
+}
+
+bool ossimEquDistCylProjection::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimEquDistCylProjection::loadState: Input keyword list is \n" << kwl << endl;
+   }
+
+   ossimLlxyProjection::loadState(kwl, prefix);
+
+   const char* falseEasting  = kwl.find(prefix,
+                                        ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix,
+                                        ossimKeywordNames::FALSE_NORTHING_KW);
+
+   const char* type          = kwl.find(prefix,
+                                        ossimKeywordNames::TYPE_KW);
+
+   setDefaults();
+   // make sure we are of the same type.  If we are then the easting
+   // northing values will make since
+   //
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimEquDistCylProjection))
+   {
+      if(falseEasting)
+      {
+         Eqcy_False_Easting  = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Eqcy_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   else
+   {
+      theUlEastingNorthing.makeNan();
+   }
+   // finalize the initialization.
+   update();
+            
+   return true;
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS
+ */
+
+
+long ossimEquDistCylProjection::Set_Equidistant_Cyl_Parameters(double a,
+                                                               double f,
+                                                               double Std_Parallel,
+                                                               double Central_Meridian,
+                                                               double False_Easting,
+                                                               double False_Northing)
+{ /* Begin Set_Equidistant_Cyl_Parameters */
+/*
+ * The function Set_Equidistant_Cyl_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  It also calculates the spherical radius of the sphere having 
+ * the same area as the ellipsoid.  If any errors occur, the error code(s) 
+ * are returned by the function, otherwise EQCY_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Std_Parallel      : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          standard parallel of the projection     (input)
+ */
+
+  double temp;
+//  double inv_f = 1 / f;
+  long Error_Code = EQCY_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= EQCY_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= EQCY_INV_F_ERROR;
+//   }
+//   if ((Std_Parallel < -PI_OVER_2) || (Std_Parallel > PI_OVER_2))
+//   { /* standard parallel out of range */
+//     Error_Code |= EQCY_STDP_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= EQCY_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Eqcy_a = a;
+    Eqcy_f = f;
+    es2 = 2 * Eqcy_f - Eqcy_f * Eqcy_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    /* spherical radius */
+    Ra = Eqcy_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 /3024.0);
+    Eqcy_Std_Parallel = Std_Parallel;
+    Cos_Eqcy_Std_Parallel = cos(Eqcy_Std_Parallel);
+    Ra_Cos_Eqcy_Std_Parallel = Ra * Cos_Eqcy_Std_Parallel;
+//    if (Central_Meridian > M_PI)
+//      Central_Meridian -= TWO_PI;
+    Eqcy_Origin_Long = Central_Meridian;
+    Eqcy_False_Easting = False_Easting;
+    Eqcy_False_Northing = False_Northing;
+    if (Eqcy_Origin_Long > 0)
+    {
+      Convert_Geodetic_To_Equidistant_Cyl(PI_OVER_2, Eqcy_Origin_Long - M_PI - ONE, &Eqcy_Max_Easting, &temp);
+      Convert_Geodetic_To_Equidistant_Cyl(PI_OVER_2, Eqcy_Origin_Long - M_PI, &Eqcy_Min_Easting, &temp);
+    }
+    else if (Eqcy_Origin_Long < 0)
+    {
+      Convert_Geodetic_To_Equidistant_Cyl(PI_OVER_2, Eqcy_Origin_Long + M_PI, &Eqcy_Max_Easting, &temp);
+      Convert_Geodetic_To_Equidistant_Cyl(PI_OVER_2, Eqcy_Origin_Long + M_PI + ONE, &Eqcy_Min_Easting, &temp);
+    }
+    else
+    {
+      Convert_Geodetic_To_Equidistant_Cyl(PI_OVER_2, M_PI, &Eqcy_Max_Easting, &temp);
+      Eqcy_Min_Easting = -Eqcy_Max_Easting;
+    }
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Equidistant_Cyl_Parameters */
+
+
+void ossimEquDistCylProjection::Get_Equidistant_Cyl_Parameters(double *a,
+                                                               double *f,
+                                                               double *Std_Parallel,
+                                                               double *Central_Meridian,
+                                                               double *False_Easting,
+                                                               double *False_Northing)const
+{ /* Begin Get_Equidistant_Cyl_Parameters */
+/*
+ * The function Get_Equidistant_Cyl_Parameters returns the current ellipsoid
+ * parameters and Equidistant Cylindrical projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Std_Parallel      : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          standard parallel of the projection     (output)
+ */
+
+  *a = Eqcy_a;
+  *f = Eqcy_f;
+  *Std_Parallel = Eqcy_Std_Parallel;
+  *Central_Meridian = Eqcy_Origin_Long;
+  *False_Easting = Eqcy_False_Easting;
+  *False_Northing = Eqcy_False_Northing;
+  return;
+} /* End Get_Equidistant_Cyl_Parameters */
+
+
+long ossimEquDistCylProjection::Convert_Geodetic_To_Equidistant_Cyl (double Latitude,
+                                                                     double Longitude,
+                                                                     double *Easting,
+                                                                     double *Northing)const
+   
+{ /* Begin Convert_Geodetic_To_Equidistant_Cyl */
+/*
+ * The function Convert_Geodetic_To_Equidistant_Cyl converts geodetic (latitude and
+ * longitude) coordinates to Equidistant Cylindrical projection (easting and northing)
+ * coordinates, according to the current ellipsoid, spherical radiius
+ * and Equidistant Cylindrical projection parameters.
+ * If any errors occur, the error code(s) are returned by the
+ * function, otherwise EQCY_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double dlam;     /* Longitude - Central Meridan */
+  long Error_Code = EQCY_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   {  /* Latitude out of range */
+//     Error_Code |= EQCY_LAT_ERROR;
+//   }
+//   if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+//   {  /* Longitude out of range */
+//     Error_Code|= EQCY_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Eqcy_Origin_Long;
+    if (dlam > M_PI)
+    {
+      dlam -= TWO_PI;
+    }
+    if (dlam < -M_PI)
+    {
+      dlam += TWO_PI;
+    }
+
+    *Easting = Ra_Cos_Eqcy_Std_Parallel * dlam + Eqcy_False_Easting;
+    *Northing = Ra * Latitude + Eqcy_False_Northing;
+
+  }
+  return (Error_Code);
+
+} /* End Convert_Geodetic_To_Equidistant_Cyl */
+
+
+long ossimEquDistCylProjection::Convert_Equidistant_Cyl_To_Geodetic(double Easting,
+                                                                    double Northing,
+                                                                    double *Latitude,
+                                                                    double *Longitude)const
+{ /* Begin Convert_Equidistant_Cyl_To_Geodetic */
+/*
+ * The function Convert_Equidistant_Cyl_To_Geodetic converts Equidistant Cylindrical projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid, spherical radius
+ * and Equidistant Cylindrical projection coordinates.
+ * If any errors occur, the error code(s) are returned by the
+ * function, otherwise EQCY_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx, dy;
+  long Error_Code = EQCY_NO_ERROR;
+
+//   if ((Easting < (Eqcy_False_Easting + Eqcy_Min_Easting))
+//       || (Easting > (Eqcy_False_Easting + Eqcy_Max_Easting)))
+//   { /* Easting out of range */
+//     Error_Code |= EQCY_EASTING_ERROR;
+//   }
+//   if ((Northing < (Eqcy_False_Northing - Eqcy_Delta_Northing))
+//       || (Northing > (Eqcy_False_Northing + Eqcy_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= EQCY_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  {
+    dy = Northing - Eqcy_False_Northing;
+    dx = Easting - Eqcy_False_Easting;
+    *Latitude = dy / Ra;
+
+    if (Ra_Cos_Eqcy_Std_Parallel == 0)
+      *Longitude = 0;
+    else
+      *Longitude = Eqcy_Origin_Long + dx / Ra_Cos_Eqcy_Std_Parallel;
+
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+
+//    if (*Longitude > PI)
+//      *Longitude -= TWO_PI;
+//    if (*Longitude < -PI)
+//      *Longitude += TWO_PI;
+
+//    if (*Longitude > PI)  /* force distorted values to 180, -180 degrees */
+//      *Longitude = PI;
+//    else if (*Longitude < -PI)
+//      *Longitude = -PI;
+
+  }
+  return (Error_Code);
+
+} /* End Convert_Equidistant_Cyl_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEquDistCylProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEquDistCylProjection.h
new file mode 100644
index 0000000000..a6ac5b76ce
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimEquDistCylProjection.h
@@ -0,0 +1,209 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Equidistant Cylinder projection code.  
+//*******************************************************************
+//  $Id: ossimEquDistCylProjection.h,v 1.18 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimEquDistCylProjection_HEADER
+#define ossimEquDistCylProjection_HEADER
+
+#include <projections/map_projections/ossimLlxyProjection.h>
+
+class OSSIMDLLEXPORT ossimEquDistCylProjection : public ossimLlxyProjection
+{
+public:
+   ossimEquDistCylProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                             const ossimGpt& origin = ossimGpt());
+   ossimEquDistCylProjection(const ossimEllipsoid& ellipsoid,
+                             const ossimGpt& origin,
+                             double falseEasting,
+                             double falseNorthing);
+   
+   ossimEquDistCylProjection(const ossimEquDistCylProjection& rhs)
+      :ossimLlxyProjection(rhs)
+      {
+         *this = rhs;
+      }
+   
+   ~ossimEquDistCylProjection(){}
+   virtual ossimObject *dup()const
+      {
+         return new ossimEquDistCylProjection(*this);
+      }
+   
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   double getFalseEasting()const{return Eqcy_False_Easting;}
+   double getFalseNorthing()const{return Eqcy_False_Northing;}
+   
+    virtual bool isGeographic()const
+       {
+          return true;
+       }
+   void setDefaults();
+//   virtual void setMetersPerPixel(const ossimDpt& pt);
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   
+private:   
+   //---------------------GEOTRANS-------------------------------
+   mutable double Eqcy_a;                  /* Semi-major axis of ellipsoid in meters */
+   mutable double Eqcy_f;          /* Flattening of ellipsoid */
+   mutable double es2;         /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;          /* es2 * es2	 */
+   mutable double es6;          /* es4 * es2  */
+   mutable double Ra;                /* Spherical Radius  */
+   
+/* Equidistant Cylindrical projection Parameters */
+   mutable double Eqcy_Std_Parallel;             /* Latitude of standard parallel in radians     */
+   mutable double Cos_Eqcy_Std_Parallel;         /* cos(Eqcy_Std_Parallel)  */
+   mutable double Eqcy_Origin_Long;              /* Longitude of origin in radians    */
+   mutable double Eqcy_False_Easting;
+   mutable double Eqcy_False_Northing;
+   mutable double Eqcy_Delta_Northing;
+   mutable double Eqcy_Max_Easting;
+   mutable double Eqcy_Min_Easting;
+   mutable double Ra_Cos_Eqcy_Std_Parallel; /* Ra * Cos_Eqcy_Std_Parallel */
+
+/*!
+ * The function Set_Equidistant_Cyl_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  It also calculates the spherical radius of the sphere having 
+ * the same area as the ellipsoid.  If any errors occur, the error code(s) 
+ * are returned by the function, otherwise EQCY_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Std_Parallel      : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          standard parallel of the projection     (input)
+ */
+  long Set_Equidistant_Cyl_Parameters(double a,
+                                      double f,
+                                      double Std_Parallel,
+                                      double Central_Meridian,
+                                      double False_Easting,
+                                      double False_Northing);
+
+
+/*!
+ * The function Get_Equidistant_Cyl_Parameters returns the current ellipsoid
+ * parameters and Equidistant Cylindrical projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Std_Parallel      : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          standard parallel of the projection     (output)
+ */
+  void Get_Equidistant_Cyl_Parameters(double *a,
+                                      double *f,
+                                      double *Std_Parallel,
+                                      double *Central_Meridian,
+                                      double *False_Easting,
+                                      double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Equidistant_Cyl converts geodetic (latitude and
+ * longitude) coordinates to Equidistant Cylindrical projection easting, and northing
+ * coordinates, according to the current ellipsoid and Equidistant Cylindrical projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise EQCY_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Equidistant_Cyl (double Latitude,
+                                            double Longitude,
+                                            double *Easting,
+                                            double *Northing)const;
+
+
+/*!
+ * The function Convert_Equidistant_Cyl_To_Geodetic converts Equidistant Cylindrical projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Equidistant Cylindrical projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise EQCY_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Equidistant_Cyl_To_Geodetic(double Easting,
+                                           double Northing,
+                                           double *Latitude,
+                                           double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimGnomonicProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimGnomonicProjection.cpp
new file mode 100644
index 0000000000..0ca8208579
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimGnomonicProjection.cpp
@@ -0,0 +1,459 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimGnomonicProjection.cpp,v 1.5 2004/01/08 21:49:21 jlargent Exp $
+#include "ossimGnomonicProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimGnomonicProjection, "ossimGnomonicProjection", ossimMapProjection)
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+
+#define GNOM_NO_ERROR           0x0000
+#define GNOM_LAT_ERROR          0x0001
+#define GNOM_LON_ERROR          0x0002
+#define GNOM_EASTING_ERROR      0x0004
+#define GNOM_NORTHING_ERROR     0x0008
+#define GNOM_ORIGIN_LAT_ERROR   0x0010
+#define GNOM_CENT_MER_ERROR     0x0020
+#define GNOM_A_ERROR            0x0040
+#define GNOM_INV_F_ERROR        0x0080
+
+ossimGnomonicProjection::ossimGnomonicProjection(const ossimEllipsoid& ellipsoid,
+                                                 const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimGnomonicProjection::ossimGnomonicProjection(const ossimEllipsoid& ellipsoid,
+                                                 const ossimGpt& origin,
+                                                 double falseEasting,
+                                                 double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Gnom_False_Easting  = falseEasting;
+   Gnom_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimGnomonicProjection::update()
+{   
+   Set_Gnomonic_Parameters(theEllipsoid.getA(),
+                           theEllipsoid.getFlattening(),
+                           theOrigin.latr(),
+                           theOrigin.lonr(),
+                           Gnom_False_Easting,
+                           Gnom_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimGnomonicProjection::setFalseEasting(double falseEasting)
+{
+   Gnom_False_Easting = falseEasting;
+   
+   update();
+}
+
+void ossimGnomonicProjection::setFalseNorthing(double falseNorthing)
+{
+   Gnom_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimGnomonicProjection::setDefaults()
+{
+   Gnom_False_Easting  = 0.0;
+   Gnom_False_Northing = 0.0;
+   Gnom_Delta_Northing = 40000000;
+   Gnom_Delta_Easting  =  40000000;
+}
+
+void ossimGnomonicProjection::setFalseEastingNorthing(double falseEasting,
+                                                           double falseNorthing)
+{
+   Gnom_False_Easting  = falseEasting;
+   Gnom_False_Northing = falseNorthing;
+   
+   update();
+}
+
+ossimGpt ossimGnomonicProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Gnomonic_To_Geodetic(eastingNorthing.x,
+                                eastingNorthing.y,
+                                &lat,
+                                &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimGnomonicProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Gnomonic(gpt.latr(),
+                                gpt.lonr(),
+                                &easting,
+                                &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+bool ossimGnomonicProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Gnom_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Gnom_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);   
+}
+
+bool ossimGnomonicProjection::loadState(const ossimKeywordlist& kwl,
+                                             const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimGnomonicProjection))
+   {
+      if(falseEasting)
+      {
+         Gnom_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Gnom_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+
+   return flag;
+
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+long ossimGnomonicProjection::Set_Gnomonic_Parameters(double a,
+                                                      double f,
+                                                      double Origin_Latitude,
+                                                      double Central_Meridian,
+                                                      double False_Easting,
+                                                      double False_Northing)
+{ /* BEGIN Set_Gnomonic_Parameters */
+/*
+ * The function Set_Gnomonic_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise GNOM_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double es2, es4, es6;
+//  double inv_f = 1 / f;
+  long Error_Code = GNOM_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= GNOM_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= GNOM_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+//   { /* origin latitude out of range */
+//     Error_Code |= GNOM_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= GNOM_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Gnom_a = a;
+    Gnom_f = f;
+    es2 = 2 * Gnom_f - Gnom_f * Gnom_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    /* spherical radius */
+    Ra = Gnom_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 / 3024.0);
+    Gnom_Origin_Lat = Origin_Latitude;
+    Sin_Gnom_Origin_Lat = sin(Gnom_Origin_Lat);
+    Cos_Gnom_Origin_Lat = cos(Gnom_Origin_Lat);
+    abs_Gnom_Origin_Lat = fabs(Gnom_Origin_Lat);
+//     if (Central_Meridian > PI)
+//       Central_Meridian -= TWO_PI;
+    Gnom_Origin_Long = Central_Meridian;
+    Gnom_False_Northing = False_Northing;
+    Gnom_False_Easting = False_Easting;
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Gnomonic_Parameters */
+
+
+void ossimGnomonicProjection::Get_Gnomonic_Parameters(double *a,
+                                                      double *f,
+                                                      double *Origin_Latitude,
+                                                      double *Central_Meridian,
+                                                      double *False_Easting,
+                                                      double *False_Northing)const
+{ /* Begin Get_Gnomonic_Parameters */
+/*
+ * The function Get_Gnomonic_Parameters returns the current ellipsoid
+ * parameters and Gnomonic projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Gnom_a;
+  *f = Gnom_f;
+  *Origin_Latitude = Gnom_Origin_Lat;
+  *Central_Meridian = Gnom_Origin_Long;
+  *False_Easting = Gnom_False_Easting;
+  *False_Northing = Gnom_False_Northing;
+  
+  return;
+} /* End Get_Gnomonic_Parameters */
+
+
+long ossimGnomonicProjection::Convert_Geodetic_To_Gnomonic (double Latitude,
+                                                            double Longitude,
+                                                            double *Easting,
+                                                            double *Northing)const
+{ /* Begin Convert_Geodetic_To_Gnomonic */
+/*
+ * The function Convert_Geodetic_To_Gnomonic converts geodetic (latitude and
+ * longitude) coordinates to Gnomonic projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Gnomonic projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise GNOM_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double dlam;       /* Longitude - Central Meridan */
+  double cos_c;      
+  double k_prime;    /* scale factor */
+  double Ra_kprime;
+  double slat = sin(Latitude);
+  double clat = cos(Latitude);
+  double Ra_cotlat;
+  double sin_dlam, cos_dlam;
+  double temp_Easting, temp_Northing;
+  long Error_Code = GNOM_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   { /* Latitude out of range */
+//     Error_Code |= GNOM_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   { /* Longitude out of range */
+//     Error_Code |= GNOM_LON_ERROR;
+//   }
+  dlam = Longitude - Gnom_Origin_Long;
+  sin_dlam = sin(dlam);
+  cos_dlam = cos(dlam);
+  cos_c = Sin_Gnom_Origin_Lat * slat + Cos_Gnom_Origin_Lat * clat * cos_dlam;
+  if (cos_c <= 1.0e-10)
+  {  /* Point is out of view.  Will return longitude out of range message
+    since no point out of view is implemented.  */
+    Error_Code |= GNOM_LON_ERROR;
+  }
+  if (!Error_Code)
+  { /* no errors */
+//     if (dlam > PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+    if (fabs(abs_Gnom_Origin_Lat - PI_OVER_2) < 1.0e-10)
+    {
+      Ra_cotlat = Ra * (clat / slat);
+      temp_Easting = Ra_cotlat * sin_dlam;
+      temp_Northing = Ra_cotlat * cos_dlam;
+      if (Gnom_Origin_Lat >= 0.0)
+      {
+        *Easting = temp_Easting + Gnom_False_Easting;
+        *Northing = -1.0 * temp_Northing + Gnom_False_Northing;
+      }
+      else
+      {
+        *Easting = -1.0 * temp_Easting + Gnom_False_Easting;
+        *Northing = temp_Northing + Gnom_False_Northing;
+      }
+    }
+    else if (abs_Gnom_Origin_Lat <= 1.0e-10)
+    {
+      *Easting = Ra * tan(dlam) + Gnom_False_Easting;
+      *Northing = Ra * tan(Latitude) / cos_dlam + Gnom_False_Northing;
+    }
+    else
+    {
+      k_prime = 1 / cos_c;
+      Ra_kprime = Ra * k_prime;
+      *Easting = Ra_kprime * clat * sin_dlam + Gnom_False_Easting;
+      *Northing = Ra_kprime * (Cos_Gnom_Origin_Lat * slat - Sin_Gnom_Origin_Lat * clat * cos_dlam) + Gnom_False_Northing;
+    }
+  }
+  return (Error_Code);
+} /* End Convert_Geodetic_To_Gnomonic */
+
+
+long ossimGnomonicProjection::Convert_Gnomonic_To_Geodetic(double Easting,
+                                                           double Northing,
+                                                           double *Latitude,
+                                                           double *Longitude)const
+{ /* Begin Convert_Gnomonic_To_Geodetic */
+/*
+ * The function Convert_Gnomonic_To_Geodetic converts Gnomonic projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Gnomonic projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise GNOM_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx, dy;
+  double rho;
+  double c;
+  double sin_c, cos_c;
+  double dy_sinc;
+  long Error_Code = GNOM_NO_ERROR; 
+
+//   if ((Easting < (Gnom_False_Easting - Gnom_Delta_Easting)) 
+//       || (Easting > (Gnom_False_Easting + Gnom_Delta_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= GNOM_EASTING_ERROR;
+//   }
+//   if ((Northing < (Gnom_False_Northing - Gnom_Delta_Northing)) 
+//       || (Northing > (Gnom_False_Northing + Gnom_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= GNOM_NORTHING_ERROR;
+//   }
+  if (!Error_Code)
+  {
+    dy = Northing - Gnom_False_Northing;
+    dx = Easting - Gnom_False_Easting;
+    rho = sqrt(dx * dx + dy * dy);
+    if (fabs(rho) <= 1.0e-10)
+    {
+      *Latitude = Gnom_Origin_Lat;
+      *Longitude = Gnom_Origin_Long;
+    }
+    else
+    {
+      c = atan(rho / Ra);
+      sin_c = sin(c);
+      cos_c = cos(c);
+      dy_sinc = dy * sin_c;
+      *Latitude = asin((cos_c * Sin_Gnom_Origin_Lat) + ((dy_sinc * Cos_Gnom_Origin_Lat) / rho));
+      if (fabs(abs_Gnom_Origin_Lat - PI_OVER_2) < 1.0e-10)
+      {
+        if (Gnom_Origin_Lat >= 0.0)
+          *Longitude = Gnom_Origin_Long + atan2(dx, -dy);
+        else
+          *Longitude = Gnom_Origin_Long + atan2(dx, dy);
+      }
+      else
+        *Longitude = Gnom_Origin_Long + atan2((dx * sin_c), (rho * Cos_Gnom_Origin_Lat * cos_c - dy_sinc * Sin_Gnom_Origin_Lat));
+    }
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+//     if (*Longitude > PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -PI)
+//       *Longitude += TWO_PI;
+//     if (*Longitude > PI)  /* force distorted values to 180, -180 degrees */
+//       *Longitude = PI;
+//     else if (*Longitude < -PI)
+//       *Longitude = -PI;
+  }
+  return (Error_Code);
+} /* End Convert_Gnomonic_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimGnomonicProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimGnomonicProjection.h
new file mode 100644
index 0000000000..40c4188e92
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimGnomonicProjection.h
@@ -0,0 +1,193 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimGnomonicProjection.h,v 1.2 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimGnomonicProjection_HEADER
+#define ossimGnomonicProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimGnomonicProjection : public ossimMapProjection
+{
+public:
+   ossimGnomonicProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                                const ossimGpt& origin = ossimGpt());
+   ossimGnomonicProjection(const ossimEllipsoid& ellipsoid,
+                                const ossimGpt& origin,
+                                const double falseEasting,
+                                const double falseNorthing);
+   ~ossimGnomonicProjection(){}
+   virtual ossimObject *dup()const
+      {
+         return new ossimGnomonicProjection(*this);
+      }
+   
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();   
+   
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return  Gnom_False_Easting;}
+   double getFalseNorthing()const{return Gnom_False_Northing;}
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+protected:
+
+   //__________________________GEOTRANS________________________
+   mutable double Gnom_a;               /* Semi-major axis of ellipsoid in meters */
+   mutable double Gnom_f;               /* Flattening of ellipsoid */
+   mutable double Ra;                   /* Spherical Radius */
+   mutable double Sin_Gnom_Origin_Lat;
+   mutable double Cos_Gnom_Origin_Lat;
+   
+/* Gnomonic projection Parameters */
+   mutable double Gnom_Origin_Lat;               /* Latitude of origin in radians */
+   mutable double Gnom_Origin_Long;              /* Longitude of origin in radians */
+   mutable double Gnom_False_Northing;           /* False northing in meters */
+   mutable double Gnom_False_Easting;            /* False easting in meters */
+   mutable double abs_Gnom_Origin_Lat;
+   
+   mutable double Gnom_Delta_Northing;
+   mutable double Gnom_Delta_Easting;
+   
+/*
+ * The function Set_Gnomonic_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise GNOM_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Gnomonic_Parameters(double a,
+                               double f,
+                               double Origin_Latitude,
+                               double Central_Meridian,
+                               double False_Easting,
+                               double False_Northing);
+
+/*!
+ * The function Get_Gnomonic_Parameters returns the current ellipsoid
+ * parameters and Gnomonic projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Gnomonic_Parameters(double *a,
+                               double *f,
+                               double *Origin_Latitude,
+                               double *Central_Meridian,
+                               double *False_Easting,
+                               double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Gnomonic converts geodetic (latitude and
+ * longitude) coordinates to Gnomonic projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Gnomonic projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise GNOM_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Gnomonic (double Latitude,
+                                     double Longitude,
+                                     double *Easting,
+                                     double *Northing)const;
+
+
+/*!
+ * The function Convert_Gnomonic_To_Geodetic converts Gnomonic projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Gnomonic projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise GNOM_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Gnomonic_To_Geodetic(double Easting,
+                                    double Northing,
+                                    double *Latitude,
+                                    double *Longitude)const;
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLambertConformalConicProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLambertConformalConicProjection.cpp
new file mode 100644
index 0000000000..d3a29e0e30
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLambertConformalConicProjection.cpp
@@ -0,0 +1,647 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Lamberts Conformal Conic projection code.  
+//*******************************************************************
+//  $Id: ossimLambertConformalConicProjection.cpp,v 1.14 2005/09/09 19:23:58 gpotts Exp $
+
+#include "ossimLambertConformalConicProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimLambertConformalConicProjection, "ossimLambertConformalConicProjection", ossimMapProjection)
+
+/***************************************************************************/
+/*                               DEFINES
+ *
+ */
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define MAX_LAT    (( M_PI *  89.99972222222222) / 180.0)  /* 89 59 59.0 degrees in radians */
+#define LAMBERT_m(clat,essin)                  (clat / sqrt(1.0 - essin * essin))
+#define LAMBERT_t(lat,essin)                   tan(PI_OVER_4 - lat / 2) /				\
+										            pow((1.0 - essin) / (1.0 + essin), es_OVER_2)
+#define ES_SIN(sinlat)                         (es * sinlat)
+/**************************************************************************/
+/*                               GLOBAL DECLARATIONS
+ *
+ */
+
+const double PI_OVER_4 = (M_PI / 4.0);
+
+#define LAMBERT_NO_ERROR           0x0000
+#define LAMBERT_LAT_ERROR          0x0001
+#define LAMBERT_LON_ERROR          0x0002
+#define LAMBERT_EASTING_ERROR      0x0004
+#define LAMBERT_NORTHING_ERROR     0x0008
+#define LAMBERT_FIRST_STDP_ERROR   0x0010
+#define LAMBERT_SECOND_STDP_ERROR  0x0020
+#define LAMBERT_ORIGIN_LAT_ERROR   0x0040
+#define LAMBERT_CENT_MER_ERROR     0x0080
+#define LAMBERT_A_ERROR            0x0100
+#define LAMBERT_B_ERROR            0x0200
+#define LAMBERT_A_LESS_B_ERROR     0x0400
+#define LAMBERT_HEMISPHERE_ERROR   0x0800
+#define LAMBERT_FIRST_SECOND_ERROR 0x1000
+
+ossimLambertConformalConicProjection::ossimLambertConformalConicProjection(const ossimEllipsoid& ellipsoid,
+                                                                           const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+    
+ossimLambertConformalConicProjection::ossimLambertConformalConicProjection(const ossimEllipsoid& ellipsoid,
+                                                                           const ossimGpt& origin,
+                                                                           double stdParallel1,
+                                                                           double stdParallel2,
+                                                                           double falseEasting,
+                                                                           double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Lambert_Std_Parallel_1 = stdParallel1;
+   Lambert_Std_Parallel_2 = stdParallel2;
+   Lambert_False_Easting  = falseEasting;
+   Lambert_False_Northing = falseNorthing;
+   
+   update();
+}
+
+ossimLambertConformalConicProjection::~ossimLambertConformalConicProjection()
+{
+}
+
+ossimObject* ossimLambertConformalConicProjection::dup()const
+{
+   return new ossimLambertConformalConicProjection(*this);
+}
+
+void ossimLambertConformalConicProjection::update()
+{   
+   Set_Lambert_Parameters(theEllipsoid.getA(),
+                          theEllipsoid.getFlattening(),
+                          theOrigin.latr(),
+                          theOrigin.lonr(),
+                          Lambert_Std_Parallel_1,
+                          Lambert_Std_Parallel_2,
+                          Lambert_False_Easting,
+                          Lambert_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimLambertConformalConicProjection::setStandardParallel1(double degree)
+{
+   Lambert_Std_Parallel_1 = degree*RAD_PER_DEG;
+   update();
+}
+
+void ossimLambertConformalConicProjection::setStandardParallel2(double degree)
+{
+   Lambert_Std_Parallel_2 = degree*RAD_PER_DEG;
+   update();
+}
+
+void ossimLambertConformalConicProjection::setStandardParallels(double parallel1Degree,
+                                                                double parallel2Degree)
+{
+   Lambert_Std_Parallel_1 = parallel1Degree*RAD_PER_DEG;
+   Lambert_Std_Parallel_2 = parallel2Degree*RAD_PER_DEG;
+   update();
+   
+}
+
+void ossimLambertConformalConicProjection::setFalseEasting(double falseEasting)
+{
+   Lambert_False_Easting = falseEasting;
+   update();
+}
+
+void ossimLambertConformalConicProjection::setFalseNorthing(double falseNorthing)
+{
+   Lambert_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimLambertConformalConicProjection::setFalseEastingNorthing(double falseEasting,
+                                                                   double falseNorthing)
+{
+   Lambert_False_Easting = falseEasting;
+   Lambert_False_Northing = falseNorthing;  
+   update();
+}
+
+void ossimLambertConformalConicProjection::setParameters(double parallel1,
+                                                         double parallel2,
+                                                         double falseEasting,
+                                                         double falseNorthing)
+{
+   Lambert_False_Easting = falseEasting;
+   Lambert_False_Northing = falseNorthing;  
+   Lambert_Std_Parallel_1 = parallel1*RAD_PER_DEG;
+   Lambert_Std_Parallel_2 = parallel2*RAD_PER_DEG;
+   update(); 
+}
+
+
+void ossimLambertConformalConicProjection::setDefaults()
+{
+   Lambert_Std_Parallel_1 = 40*RAD_PER_DEG;
+   Lambert_Std_Parallel_2 = 50*RAD_PER_DEG;
+   Lambert_False_Northing = 0.0;
+   Lambert_False_Easting  = 0.0;
+}
+
+ossimGpt ossimLambertConformalConicProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+  
+   Convert_Lambert_To_Geodetic(eastingNorthing.x,
+                               eastingNorthing.y,
+                               &lat,
+                               &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);
+}
+
+ossimDpt ossimLambertConformalConicProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Lambert(gpt.latr(),
+                               gpt.lonr(),
+                               &easting,
+                               &northing);
+
+   return ossimDpt(easting, northing);
+}
+
+bool ossimLambertConformalConicProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::STD_PARALLEL_1_KW,
+           Lambert_Std_Parallel_1*DEG_PER_RAD,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::STD_PARALLEL_2_KW,
+           Lambert_Std_Parallel_2*DEG_PER_RAD,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Lambert_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Lambert_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimLambertConformalConicProjection::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   const char* stdParallel1  = kwl.find(prefix, ossimKeywordNames::STD_PARALLEL_1_KW);
+   const char* stdParallel2  = kwl.find(prefix, ossimKeywordNames::STD_PARALLEL_2_KW);
+
+   setDefaults();
+   
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimLambertConformalConicProjection))
+   {
+      if(falseEasting)
+      {
+         Lambert_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Lambert_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+      if(stdParallel1)
+      {
+         Lambert_Std_Parallel_1 = ossimString(stdParallel1).toDouble()*RAD_PER_DEG;
+      }
+      if(stdParallel2)
+      {
+         Lambert_Std_Parallel_2 = ossimString(stdParallel2).toDouble()*RAD_PER_DEG;
+      }
+   }
+   update();
+   return flag;
+}
+
+/************************************************************************/
+/*                              FUNCTIONS
+ *
+ */
+
+long ossimLambertConformalConicProjection::Set_Lambert_Parameters(double a,
+                                                                  double f,
+                                                                  double Origin_Latitude,
+                                                                  double Central_Meridian,
+                                                                  double Std_Parallel_1,
+                                                                  double Std_Parallel_2,
+                                                                  double False_Easting,
+                                                                  double False_Northing)
+
+{ /* BEGIN Set_Lambert_Parameters */
+/*
+ * The function Set_Lambert_Parameters receives the ellipsoid parameters and
+ * Lambert Conformal Conic projection parameters as inputs, and sets the
+ * corresponding state variables.  If any errors occur, the error code(s)
+ * are returned by the function, otherwise LAMBERT_NO_ERROR is returned.
+ *
+ *   a                   : Semi-major axis of ellipsoid, in meters   (input)
+ *   f                   : Flattening of ellipsoid						       (input)
+ *   Origin_Latitude     : Latitude of origin, in radians            (input)
+ *   Central_Meridian    : Longitude of origin, in radians           (input)
+ *   Std_Parallel_1      : First standard parallel, in radians       (input)
+ *   Std_Parallel_2      : Second standard parallel, in radians      (input)
+ *   False_Easting       : False easting, in meters                  (input)
+ *   False_Northing      : False northing, in meters                 (input)
+ */
+
+  double slat, slat1, clat;
+  double es_sin;
+  double t0, t1, t2;
+  double m1, m2;
+//  double inv_f = 1 / f;
+  long Error_Code = LAMBERT_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= LAMBERT_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= LAMBERT_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -MAX_LAT) || (Origin_Latitude > MAX_LAT))
+//   { /* Origin Latitude out of range */
+//     Error_Code |= LAMBERT_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Std_Parallel_1 < -MAX_LAT) || (Std_Parallel_1 > MAX_LAT))
+//   { /* First Standard Parallel out of range */
+//     Error_Code |= LAMBERT_FIRST_STDP_ERROR;
+//   }
+//   if ((Std_Parallel_2 < -MAX_LAT) || (Std_Parallel_2 > MAX_LAT))
+//   { /* Second Standard Parallel out of range */
+//     Error_Code |= LAMBERT_SECOND_STDP_ERROR;
+//   }
+//   if ((Std_Parallel_1 == 0) && (Std_Parallel_2 == 0))
+//   { /* First & Second Standard Parallels are both 0 */
+//     Error_Code |= LAMBERT_FIRST_SECOND_ERROR;
+//   }
+//   if (Std_Parallel_1 == -Std_Parallel_2)
+//   { /* Parallels are the negation of each other */
+//     Error_Code |= LAMBERT_HEMISPHERE_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* Origin Longitude out of range */
+//     Error_Code |= LAMBERT_CENT_MER_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    Lambert_a = a;
+    Lambert_f = f;
+    Lambert_Origin_Lat = Origin_Latitude;
+    Lambert_Std_Parallel_1 = Std_Parallel_1;
+    Lambert_Std_Parallel_2 = Std_Parallel_2;
+//     if (Central_Meridian > PI)
+//       Central_Meridian -= TWO_PI;
+    Lambert_Origin_Long = Central_Meridian;
+    Lambert_False_Easting = False_Easting;
+    Lambert_False_Northing = False_Northing;
+
+    es2 = 2 * Lambert_f - Lambert_f * Lambert_f;
+    es = sqrt(es2);
+    es_OVER_2 = es / 2.0;
+
+    slat = sin(Lambert_Origin_Lat);
+    es_sin = ES_SIN(slat);
+    t0 = LAMBERT_t(Lambert_Origin_Lat, es_sin);
+
+    slat1 = sin(Lambert_Std_Parallel_1);
+    clat = cos(Lambert_Std_Parallel_1);
+    es_sin = ES_SIN(slat1);
+    m1 = LAMBERT_m(clat, es_sin);
+    t1 = LAMBERT_t(Lambert_Std_Parallel_1, es_sin);
+
+
+    if (fabs(Lambert_Std_Parallel_1 - Lambert_Std_Parallel_2) > 1.0e-10)
+    {
+      slat = sin(Lambert_Std_Parallel_2);
+      clat = cos(Lambert_Std_Parallel_2);
+      es_sin = ES_SIN(slat);
+      m2 = LAMBERT_m(clat, es_sin);
+      t2 = LAMBERT_t(Lambert_Std_Parallel_2, es_sin);
+      n = log(m1 / m2) / log(t1 / t2);
+    }
+    else
+      n = slat1;
+    F = m1 / (n * pow(t1, n));
+    Lambert_aF = Lambert_a * F;
+    if ((t0 == 0) && (n < 0))
+      rho0 = 0.0;
+    else
+      rho0 = Lambert_aF * pow(t0, n);
+
+  }
+  return (Error_Code);
+} /* END OF Set_Lambert_Parameters */
+
+
+void ossimLambertConformalConicProjection::Get_Lambert_Parameters(double *a,
+                                                                  double *f,
+                                                                  double *Origin_Latitude,
+                                                                  double *Central_Meridian,
+                                                                  double *Std_Parallel_1,
+                                                                  double *Std_Parallel_2,
+                                                                  double *False_Easting,
+                                                                  double *False_Northing)const
+
+{ /* BEGIN Get_Lambert_Parameters */
+/*                         
+ * The function Get_Lambert_Parameters returns the current ellipsoid
+ * parameters and Lambert Conformal Conic projection parameters.
+ *
+ *   a                   : Semi-major axis of ellipsoid, in meters   (output)
+ *   f                   : Flattening of ellipsoid					         (output)
+ *   Origin_Latitude     : Latitude of origin, in radians            (output)
+ *   Central_Meridian    : Longitude of origin, in radians           (output)
+ *   Std_Parallel_1      : First standard parallel, in radians       (output)
+ *   Std_Parallel_2      : Second standard parallel, in radians      (output)
+ *   False_Easting       : False easting, in meters                  (output)
+ *   False_Northing      : False northing, in meters                 (output)
+ */
+
+
+  *a = Lambert_a;
+  *f = Lambert_f;
+  *Std_Parallel_1 = Lambert_Std_Parallel_1;
+  *Std_Parallel_2 = Lambert_Std_Parallel_2;
+  *Origin_Latitude = Lambert_Origin_Lat;
+  *Central_Meridian = Lambert_Origin_Long;
+  *False_Easting = Lambert_False_Easting;
+  *False_Northing = Lambert_False_Northing;
+  
+  return;
+} /* END OF Get_Lambert_Parameters */
+
+
+long ossimLambertConformalConicProjection::Convert_Geodetic_To_Lambert (double Latitude,
+                                                                        double Longitude,
+                                                                        double *Easting,
+                                                                        double *Northing)const
+   
+{ /* BEGIN Convert_Geodetic_To_Lambert */
+/*
+ * The function Convert_Geodetic_To_Lambert converts Geodetic (latitude and
+ * longitude) coordinates to Lambert Conformal Conic projection (easting
+ * and northing) coordinates, according to the current ellipsoid and
+ * Lambert Conformal Conic projection parameters.  If any errors occur, the
+ * error code(s) are returned by the function, otherwise LAMBERT_NO_ERROR is
+ * returned.
+ *
+ *    Latitude         : Latitude, in radians                         (input)
+ *    Longitude        : Longitude, in radians                        (input)
+ *    Easting          : Easting (X), in meters                       (output)
+ *    Northing         : Northing (Y), in meters                      (output)
+ */
+
+  double slat;
+  double es_sin;
+  double t;
+  double rho;
+  double dlam;
+  double theta;
+  long  Error_Code = LAMBERT_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   {  /* Latitude out of range */
+//     Error_Code|= LAMBERT_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   {  /* Longitude out of range */
+//     Error_Code|= LAMBERT_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    if (fabs(fabs(Latitude) - PI_OVER_2) > 1.0e-10)
+    {
+      slat = sin(Latitude);
+      es_sin = ES_SIN(slat);
+      t = LAMBERT_t(Latitude, es_sin);
+      rho = Lambert_aF * pow(t, n);
+    }
+    else
+    {
+      if ((Latitude * n) <= 0)
+      { /* Point can not be projected */
+        Error_Code |= LAMBERT_LAT_ERROR;
+        return (Error_Code);
+      }
+      rho = 0.0;
+    }
+
+    dlam = Longitude - Lambert_Origin_Long;
+
+//     if (dlam > PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+
+    theta = n * dlam;
+
+    *Easting = rho * sin(theta) + Lambert_False_Easting;
+    *Northing = rho0 - rho * cos(theta) + Lambert_False_Northing;
+
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Lambert */
+
+
+
+long ossimLambertConformalConicProjection::Convert_Lambert_To_Geodetic (double Easting,
+                                                                        double Northing,
+                                                                        double *Latitude,
+                                                                        double *Longitude)const
+
+{ /* BEGIN Convert_Lambert_To_Geodetic */
+/*
+ * The function Convert_Lambert_To_Geodetic converts Lambert Conformal
+ * Conic projection (easting and northing) coordinates to Geodetic
+ * (latitude and longitude) coordinates, according to the current ellipsoid
+ * and Lambert Conformal Conic projection parameters.  If any errors occur,
+ * the error code(s) are returned by the function, otherwise LAMBERT_NO_ERROR
+ * is returned.
+ *
+ *    Easting          : Easting (X), in meters                       (input)
+ *    Northing         : Northing (Y), in meters                      (input)
+ *    Latitude         : Latitude, in radians                         (output)
+ *    Longitude        : Longitude, in radians                        (output)
+ */
+
+
+  double dy, dx;
+  double rho, rho0_MINUS_dy;
+  double t;
+  double PHI;
+  double tempPHI = 0.0;
+  double sin_PHI;
+  double es_sin;
+  double theta = 0.0;
+  double tolerance = 4.85e-10;
+  long Error_Code = LAMBERT_NO_ERROR;
+
+//   if ((Easting < (Lambert_False_Easting - Lambert_Delta_Easting))
+//       ||(Easting > (Lambert_False_Easting + Lambert_Delta_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= LAMBERT_EASTING_ERROR;
+//   }
+//   if ((Northing < (Lambert_False_Northing - Lambert_Delta_Northing))
+//       || (Northing > (Lambert_False_Northing + Lambert_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= LAMBERT_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    dy = Northing - Lambert_False_Northing;
+    dx = Easting - Lambert_False_Easting;
+    rho0_MINUS_dy = rho0 - dy;
+    rho = sqrt(dx * dx + (rho0_MINUS_dy) * (rho0_MINUS_dy));
+
+    if (n < 0.0)
+    {
+      rho *= -1.0;
+      dy *= -1.0;
+      dx *= -1.0;
+      rho0_MINUS_dy *= -1.0;
+    }
+
+    if (rho != 0.0)
+    {
+      theta = atan2(dx, rho0_MINUS_dy);
+      t = pow(rho / (Lambert_aF) , 1.0 / n);
+      PHI = PI_OVER_2 - 2.0 * atan(t);
+      while (fabs(PHI - tempPHI) > tolerance)
+      {
+        tempPHI = PHI;
+        sin_PHI = sin(PHI);
+        es_sin = ES_SIN(sin_PHI);
+        PHI = PI_OVER_2 - 2.0 * atan(t * pow((1.0 - es_sin) / (1.0 + es_sin), es_OVER_2));
+      }
+      *Latitude = PHI;
+      *Longitude = theta / n + Lambert_Origin_Long;
+
+      if (fabs(*Latitude) < 2.0e-7)  /* force lat to 0 to avoid -0 degrees */
+        *Latitude = 0.0;
+      if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+        *Latitude = PI_OVER_2;
+      else if (*Latitude < -PI_OVER_2)
+        *Latitude = -PI_OVER_2;
+
+      if (*Longitude > M_PI)
+      {
+        if (*Longitude - M_PI < 3.5e-6) 
+          *Longitude = M_PI;
+//         else
+//           *Longitude -= TWO_PI;
+      }
+      if (*Longitude < -M_PI)
+      {
+        if (fabs(*Longitude + M_PI) < 3.5e-6)
+          *Longitude = -M_PI;
+//         else
+//           *Longitude += TWO_PI;
+      }
+
+      if (fabs(*Longitude) < 2.0e-7)  /* force lon to 0 to avoid -0 degrees */
+        *Longitude = 0.0;
+      if (*Longitude > M_PI)  /* force distorted values to 180, -180 degrees */
+        *Longitude = M_PI;
+      else if (*Longitude < -M_PI)
+        *Longitude = -M_PI;
+    }
+    else
+    {
+      if (n > 0.0)
+        *Latitude = PI_OVER_2;
+      else
+        *Latitude = -PI_OVER_2;
+      *Longitude = Lambert_Origin_Long;
+    }
+  }
+  return (Error_Code);
+} /* END OF Convert_Lambert_To_Geodetic */
+
+double ossimLambertConformalConicProjection::getStandardParallel1()const
+{
+   return  Lambert_Std_Parallel_1;
+}
+
+double ossimLambertConformalConicProjection::getStandardParallel2()const
+{
+   return  Lambert_Std_Parallel_2;
+}
+
+double ossimLambertConformalConicProjection::getFalseEasting()const
+{
+   return Lambert_False_Easting;
+}
+
+double ossimLambertConformalConicProjection::getFalseNorthing()const
+{
+   return Lambert_False_Northing;
+}
+ 
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLambertConformalConicProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLambertConformalConicProjection.h
new file mode 100644
index 0000000000..89d864def8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLambertConformalConicProjection.h
@@ -0,0 +1,230 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Lamberts Conformal Conic projection code.  
+//*******************************************************************
+//  $Id: ossimLambertConformalConicProjection.h,v 1.6 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimLambertConformalConicProjection_HEADER
+#define ossimLambertConformalConicProjection_HEADER
+#include "ossimMapProjection.h"
+
+class ossimLambertConformalConicProjection : public ossimMapProjection
+{
+public:
+   ossimLambertConformalConicProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                                        const ossimGpt& origin = ossimGpt());
+   
+   ossimLambertConformalConicProjection(const ossimEllipsoid& ellipsoid,
+                                        const ossimGpt& origin,
+                                        double stdParallel1,
+                                        double stdParallel2,
+                                        double falseEasting,
+                                        double falseNorthing);
+   
+   virtual ~ossimLambertConformalConicProjection();
+   
+   virtual ossimObject *dup()const;
+   
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+   
+   /*!
+    * The passed in Argument is in degrees and will convert it to radians
+    * for Geotrans. Update is then called so we can pre-compute paramters.
+    */
+   void setStandardParallel1(double degree);
+
+   /*!
+    * The passed in Argument is in degrees and will convert it to radians
+    * for Geotrans. Update is then called so we can pre-compute paramters
+    */
+   void setStandardParallel2(double degree);
+
+   /*!
+    * Will allow you to set both parallels. both are passed in degrees.
+    */
+   void setStandardParallels(double parallel1Degree,
+                             double prallel2Degree);
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   /*!
+    * Allows one to set all parameters for this projections.  parallels are in
+    * degrees and easting northings are in meters.
+    * Update is then called so we can pre-compute paramters.
+    */
+   void setParameters(double parallel1,
+                      double parallel2,
+                      double falseEasting,
+                      double falseNorthing);
+   
+   virtual double getStandardParallel1() const;
+   virtual double getStandardParallel2() const;
+   virtual double getFalseEasting()      const;
+   virtual double getFalseNorthing()     const;
+   
+   void setDefaults();
+
+   /*!
+   * Method to save the state of an object to a keyword list.
+   * Return true if ok or false on error.
+   */
+  virtual bool saveState(ossimKeywordlist& kwl,
+			 const char* prefix=0)const;
+  
+  /*!
+   * Method to the load (recreate) the state of an object from a keyword
+   * list.  Return true if ok or false on error.
+   */
+  virtual bool loadState(const ossimKeywordlist& kwl,
+			 const char* prefix=0);
+
+private:
+
+   //_______________GEOTRANS____________________
+   mutable double Lambert_a;               /* Semi-major axis of ellipsoid, in meters */
+   mutable double Lambert_f;       /* Flattening of ellipsoid */
+   mutable double es;         /* Eccentricity of ellipsoid */
+   mutable double es2;         /* Eccentricity squared */
+   mutable double es_OVER_2;        /* Eccentricity / 2.0 */
+   mutable double n;                 /* Ratio of angle between meridians */
+   mutable double F;                 /* Flattening of ellipsoid */
+   mutable double rho0;              /* Height above ellipsoid */
+   mutable double Lambert_aF;        /* Lambert_a * F */
+   
+/* Lambert_Conformal_Conic projection Parameters */
+   mutable double Lambert_Std_Parallel_1; /* Lower std. parallel, in radians */
+   mutable double Lambert_Std_Parallel_2; /* Upper std. parallel, in radians */
+   mutable double Lambert_Origin_Lat;     /* Latitude of origin, in radians */
+   mutable double Lambert_Origin_Long;                /* Longitude of origin, in radians */
+   mutable double Lambert_False_Northing;             /* False northing, in meters */
+   mutable double Lambert_False_Easting;              /* False easting, in meters */
+
+/*!
+ * The function Set_Lambert_Parameters receives the ellipsoid parameters and
+ * Lambert Conformal Conic projection parameters as inputs, and sets the
+ * corresponding state variables.  If any errors occur, the error code(s)
+ * are returned by the function, otherwise LAMBERT_NO_ERROR is returned.
+ *
+ *   a                   : Semi-major axis of ellipsoid, in meters   (input)
+ *   f                   : Flattening of ellipsoid				  	       (input)
+ *   Origin_Latitude     : Latitude of origin in radians             (input)
+ *   Central_Meridian    : Longitude of origin in radians            (input)
+ *   Std_Parallel_1      : First standard parallel                   (input)
+ *   Std_Parallel_2      : Second standard parallel                  (input)
+ *   False_Easting       : False easting in meters                   (input)
+ *   False_Northing      : False northing in meters                  (input)
+ */
+  long Set_Lambert_Parameters(double a,
+                              double f,
+                              double Origin_Latitude,
+                              double Central_Meridian,
+                              double Std_Parallel_1,
+                              double Std_Parallel_2,
+                              double False_Easting,
+                              double False_Northing);
+
+
+
+
+/*!
+ * The function Get_Lambert_Parameters returns the current ellipsoid
+ * parameters and Lambert Conformal Conic projection parameters.
+ *
+ *   a                   : Semi-major axis of ellipsoid, in meters   (output)
+ *   f                   : Flattening of ellipsoid					         (output)
+ *   Origin_Latitude     : Latitude of origin, in radians            (output)
+ *   Central_Meridian    : Longitude of origin, in radians           (output)
+ *   Std_Parallel_1      : First standard parallel                   (output)
+ *   Std_Parallel_2      : Second standard parallel                  (output)
+ *   False_Easting       : False easting, in meters                  (output)
+ *   False_Northing      : False northing, in meters                 (output) 
+ */
+  void Get_Lambert_Parameters(double *a,
+                              double *f,
+                              double *Origin_Latitude,
+                              double *Central_Meridian,
+                              double *Std_Parallel_1,
+                              double *Std_Parallel_2,
+                              double *False_Easting,
+                              double *False_Northing)const;
+
+/*!
+ * The function Convert_Geodetic_To_Lambert converts Geodetic (latitude and
+ * longitude) coordinates to Lambert Conformal Conic projection (easting
+ * and northing) coordinates, according to the current ellipsoid and
+ * Lambert Conformal Conic projection parameters.  If any errors occur, the
+ * error code(s) are returned by the function, otherwise LAMBERT_NO_ERROR is
+ * returned.
+ *
+ *    Latitude         : Latitude in radians                         (input)
+ *    Longitude        : Longitude in radians                        (input)
+ *    Easting          : Easting (X) in meters                       (output)
+ *    Northing         : Northing (Y) in meters                      (output)
+ */
+  long Convert_Geodetic_To_Lambert (double Latitude,
+                                    double Longitude,
+                                    double *Easting,
+                                    double *Northing)const;
+
+/*!
+ * The function Convert_Lambert_To_Geodetic converts Lambert Conformal
+ * Conic projection (easting and northing) coordinates to Geodetic
+ * (latitude and longitude) coordinates, according to the current ellipsoid
+ * and Lambert Conformal Conic projection parameters.  If any errors occur,
+ * the error code(s) are returned by the function, otherwise LAMBERT_NO_ERROR
+ * is returned.
+ *
+ *    Easting          : Easting (X) in meters                       (input)
+ *    Northing         : Northing (Y) in meters                      (input)
+ *    Latitude         : Latitude in radians                         (output)
+ *    Longitude        : Longitude in radians                        (output)
+ */
+  long Convert_Lambert_To_Geodetic (double Easting,
+                                    double Northing,
+                                    double *Latitude,
+                                    double *Longitude)const;
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLlxyProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLlxyProjection.cpp
new file mode 100644
index 0000000000..ae60abf0af
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLlxyProjection.cpp
@@ -0,0 +1,323 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for ossimLlxy.  This is a simple "latitude /
+// longitude to x / y" projection.
+// 
+//*******************************************************************
+//  $Id: ossimLlxyProjection.cpp,v 1.24 2005/09/09 19:23:58 gpotts Exp $
+
+#include <projections/map_projections/ossimLlxyProjection.h>
+#include <elevation/ossimElevManager.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/datum/ossimDatum.h>
+
+// RTTI information for the ossimMapProjection
+RTTI_DEF1(ossimLlxyProjection, "ossimLlxyProjection" , ossimMapProjection);
+
+ossimLlxyProjection::ossimLlxyProjection()
+{
+   theDeltaLatPerPixel = 1.0;
+   theDeltaLonPerPixel = 1.0;
+   theUlEastingNorthing.y = OSSIM_DBL_NAN;
+   theUlEastingNorthing.x = OSSIM_DBL_NAN;
+   computeMetersPerPixel(theOrigin, 
+			 theDeltaLatPerPixel,
+			 theDeltaLonPerPixel,
+			 theMetersPerPixel);
+}
+
+ossimLlxyProjection::ossimLlxyProjection(const ossimLlxyProjection& rhs)
+   :
+      ossimMapProjection(rhs)
+{
+   theOrigin              = rhs.theOrigin;
+   theUlGpt               = rhs.theUlGpt;
+   theUlEastingNorthing.y = OSSIM_DBL_NAN;
+   theUlEastingNorthing.x = OSSIM_DBL_NAN;
+   theDatum               = theOrigin.datum();
+   theEllipsoid           = *(theDatum->ellipsoid());
+   theDeltaLatPerPixel    = rhs.theDeltaLatPerPixel;
+   theDeltaLonPerPixel    = rhs.theDeltaLonPerPixel;
+   computeMetersPerPixel(theOrigin, 
+			 theDeltaLatPerPixel,
+			 theDeltaLonPerPixel,
+			 theMetersPerPixel);
+}
+
+ossimLlxyProjection::ossimLlxyProjection(const ossimGpt& origin,
+                                         double latSpacing,
+                                         double lonSpacing)
+   :
+      ossimMapProjection()
+{
+   theOrigin              = origin;
+   theUlGpt               = origin;
+   theUlEastingNorthing.y = 0.0;
+   theUlEastingNorthing.x = 0.0;
+   theDatum               = theOrigin.datum();
+   theEllipsoid           = *(theDatum->ellipsoid());
+   theDeltaLatPerPixel    = latSpacing;
+   theDeltaLonPerPixel    = lonSpacing;
+   computeMetersPerPixel(theOrigin, 
+			 theDeltaLatPerPixel,
+			 theDeltaLonPerPixel,
+			 theMetersPerPixel);
+}
+
+ossimLlxyProjection::ossimLlxyProjection(const ossimEllipsoid& ellipsoid,
+					 const ossimGpt& origin)
+  :ossimMapProjection(ellipsoid, origin)
+{
+   theDeltaLatPerPixel = 1.0;
+   theDeltaLonPerPixel = 1.0;
+   theUlEastingNorthing.y = OSSIM_DBL_NAN;
+   theUlEastingNorthing.x = OSSIM_DBL_NAN;
+   computeMetersPerPixel(theOrigin, 
+			 theDeltaLatPerPixel,
+			 theDeltaLonPerPixel,
+			 theMetersPerPixel);
+}
+
+ossimLlxyProjection::~ossimLlxyProjection()
+{
+}
+
+ossimObject* ossimLlxyProjection::dup()const
+{
+   return new ossimLlxyProjection(*this);
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::computeDegreesPerPixel
+//  
+//*****************************************************************************
+void ossimLlxyProjection::computeDegreesPerPixel(const ossimGpt& ground,
+                                                const ossimDpt& metersPerPixel,
+                                                double &deltaLat,
+                                                double &deltaLon)
+{
+   ossimDpt mpd = ground.metersPerDegree();
+   ossimDpt dpm(1.0/mpd.x,
+                1.0/mpd.y);
+   deltaLat = metersPerPixel.y*dpm.y;
+   deltaLon = metersPerPixel.x*dpm.x;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::computeMetersPerPixel
+//  
+//*****************************************************************************
+void ossimLlxyProjection::computeMetersPerPixel(const ossimGpt& center,
+						  double deltaDegreesPerPixelLat,
+						  double deltaDegreesPerPixelLon,
+						  ossimDpt &metersPerPixel)
+{
+  metersPerPixel = center.metersPerDegree();
+  metersPerPixel.x *= deltaDegreesPerPixelLon;
+  metersPerPixel.y *= deltaDegreesPerPixelLat;
+}
+
+void ossimLlxyProjection::worldToLineSample(const ossimGpt& worldPoint,
+                                            ossimDpt&       lineSampPt) const
+{
+   ossimGpt gpt = worldPoint;
+   
+   if (theOrigin.datum() != gpt.datum())
+   {
+      // Apply datum shift if it's not the same.
+      gpt.changeDatum(theOrigin.datum());
+   }
+
+   lineSampPt.line = (theUlGpt.latd() - gpt.latd()) / theDeltaLatPerPixel;
+   lineSampPt.samp = (gpt.lond() - theUlGpt.lond()) / theDeltaLonPerPixel;
+}
+
+void ossimLlxyProjection::lineSampleToWorld(const ossimDpt& lineSampPt,
+                                            ossimGpt&       worldPt) const
+{
+   // Start with the origin.  This will keep the origin's datum.
+   worldPt = theUlGpt;
+   
+   double lat = theUlGpt.latd() - (lineSampPt.line * theDeltaLatPerPixel);
+   double lon = theUlGpt.lond() + (lineSampPt.samp * theDeltaLonPerPixel);
+
+   //---
+   // Assuming the origin had a lon between -180 and 180 and lat between -90
+   // and 90.
+   //---
+//    if (lon > 180.0)
+//    {
+//       lon -= 360.0;
+//    }
+//    else if (lon < -180.0)
+//    {
+//       lon += 360.0;
+//    }
+//    if (lat > 90.0)
+//    {
+//       lat -= 90.0;
+//    }
+//    else if (lat < -90.0)
+//    {
+//       lat = -180.0 - lat;
+//    }
+
+   worldPt.latd(lat);
+   worldPt.lond(lon);
+   worldPt.hgt = ossimElevManager::instance()->getHeightAboveEllipsoid(worldPt);
+}
+
+std::ostream& ossimLlxyProjection::print(std::ostream& out) const
+{
+   out << setiosflags(ios::fixed) << setprecision(15)
+       << "ossimLlxyProjection dump:"
+       << "\norigin:  " << theOrigin
+       << "\nlatitude spacing in decimal degrees:   " << theDeltaLatPerPixel
+       << "\nlongitude spacing in decimal degrees:  " << theDeltaLonPerPixel
+       << "\n\nossimMapProjection dump:\n" << endl;
+
+   return ossimMapProjection::print(out);
+}
+
+void ossimLlxyProjection::setMetersPerPixel(const ossimDpt& pt)
+{
+  ossimMapProjection::setMetersPerPixel(pt);
+  computeDegreesPerPixel(theOrigin,
+			 theMetersPerPixel,
+			 theDeltaLatPerPixel,
+			 theDeltaLonPerPixel);
+}
+
+bool ossimLlxyProjection::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix) const
+{
+   // Base class...
+   ossimMapProjection::saveState(kwl, prefix);
+
+   return true;
+}
+
+bool ossimLlxyProjection::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   // Base class...
+   ossimMapProjection::loadState(kwl, prefix);
+
+    const char* deltaLat = kwl.find(prefix, ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT);
+    const char* deltaLon = kwl.find(prefix, ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON);
+    const char* deltaX   = kwl.find(prefix, ossimKeywordNames::METERS_PER_PIXEL_X_KW);
+    const char* deltaY   = kwl.find(prefix, ossimKeywordNames::METERS_PER_PIXEL_Y_KW);
+    
+    if (deltaLat&&deltaLon)
+    {
+       theDeltaLatPerPixel = ossimString(deltaLat).toDouble();
+       theDeltaLonPerPixel = ossimString(deltaLon).toDouble();
+       computeMetersPerPixel(theOrigin, 
+                             theDeltaLatPerPixel,
+                             theDeltaLonPerPixel,
+                             theMetersPerPixel);
+    }
+    else if(deltaX&&deltaY)
+    {
+       theMetersPerPixel.x = ossimString(deltaX).toDouble();
+       theMetersPerPixel.y = ossimString(deltaY).toDouble();
+       
+       computeDegreesPerPixel(theOrigin, 
+                              theMetersPerPixel,
+                              theDeltaLatPerPixel,
+                              theDeltaLonPerPixel);
+    }
+    if(!deltaLat&&!deltaLon&&!deltaX&&!deltaY)
+    {
+       theDeltaLatPerPixel = 1.0;
+       theDeltaLonPerPixel = 1.0;
+       computeMetersPerPixel(theOrigin,
+                             theDeltaLatPerPixel,
+                             theDeltaLonPerPixel,
+                             theMetersPerPixel);
+    }
+    
+    return true;
+}
+
+bool ossimLlxyProjection::operator==(const ossimProjection& projection) const
+{
+   const ossimLlxyProjection* proj
+      = PTR_CAST(ossimLlxyProjection, &projection);
+
+   if(!proj)
+   {
+      return false;
+   }
+
+   return ( // (theOrigin     == proj->theOrigin)     &&  // tmp... fix gpt!
+            (theDeltaLatPerPixel == proj->theDeltaLatPerPixel) &&
+            (theDeltaLonPerPixel == proj->theDeltaLonPerPixel) );
+}
+
+
+ossimDpt ossimLlxyProjection::forward(const ossimGpt &worldPoint) const
+{
+   ossimDpt result;
+
+   worldToLineSample(worldPoint, result);
+
+   return result;
+}
+
+ossimGpt ossimLlxyProjection::inverse(const ossimDpt &projectedPoint) const
+{
+   ossimGpt result;
+   
+   lineSampleToWorld(projectedPoint, result);
+   
+   return result;
+}
+
+void ossimLlxyProjection::setLatSpacing(double spacing)
+{
+   theDeltaLatPerPixel = spacing;
+
+   // Update the meters per pixel.
+   ossimDpt pt = ossimGpt(0.0, 0.0).metersPerDegree();
+   theMetersPerPixel.y = pt.y * theDeltaLatPerPixel;
+}
+
+void ossimLlxyProjection::setLonSpacing(double spacing)
+{
+   theDeltaLonPerPixel = spacing;
+
+   // Update the meters per pixel.
+   ossimDpt pt = ossimGpt(0.0, 0.0).metersPerDegree();
+   theMetersPerPixel.x = pt.x * theDeltaLonPerPixel;
+}
+
+bool ossimLlxyProjection::isGeographic() const
+{
+   return true;
+}
+
+void ossimLlxyProjection::setOrigin(const ossimGpt& origin)
+{
+   theOrigin = origin;
+}
+
+double ossimLlxyProjection::getLatSpacing() const
+{
+   return theDeltaLatPerPixel;
+}
+
+double ossimLlxyProjection::getLonSpacing() const
+{
+   return theDeltaLonPerPixel;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLlxyProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLlxyProjection.h
new file mode 100644
index 0000000000..6c121addfa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimLlxyProjection.h
@@ -0,0 +1,146 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class declaration for ossimLlxy.  This is a simple "latitude /
+// longitude to x / y" projection.  Note that "origin" and "tie_point" are
+// synonymous in this projection.
+// 
+//*******************************************************************
+//  $Id: ossimLlxyProjection.h,v 1.13 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimLlxyProjection_HEADER
+#define ossimLlxyProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class OSSIMDLLEXPORT ossimLlxyProjection : public ossimMapProjection
+{
+public:
+   ossimLlxyProjection();
+   ossimLlxyProjection(const ossimLlxyProjection& rhs);
+   ossimLlxyProjection(const ossimEllipsoid& ellipsoid,
+                       const ossimGpt& origin);
+   ossimLlxyProjection(const ossimGpt& origin,
+                       double latSpacing,  // decimal degrees
+                       double lonSpacing);
+   
+   virtual ~ossimLlxyProjection();
+   
+   virtual ossimObject *dup()const;
+   
+   virtual bool isGeographic()const;
+   
+   virtual ossimDpt forward(const ossimGpt &worldPoint) const;
+   virtual ossimGpt inverse(const ossimDpt &projectedPoint) const;
+   
+   /*!
+    * METHOD:  setOrigin(const ossimGpt& origin)
+    * Set the origin of the projection.
+    */
+   virtual void setOrigin(const ossimGpt& origin);
+
+   /*!
+    *  METHOD:  getLatSpacing() 
+    *  Returns the latitude spacing as a double representing decimal degrees.
+    */
+   virtual double getLatSpacing() const;
+
+   /*!
+    *  METHOD:  getLonSpacing() 
+    *  Returns the longitude spacing as a double representing decimal degrees.
+    */
+   virtual double getLonSpacing() const;
+
+   /*!
+    *  METHOD:  setLatSpacing(double spacing)
+    *  Set the latitude spacing as a double representing decimal degrees.
+    */
+   virtual void   setLatSpacing(double spacing);
+
+    /*!
+    *  METHOD:  setLonSpacing(double spacing)
+    *  Set the latitude spacing as a double representing decimal degrees.
+    */
+   virtual void   setLonSpacing(double spacing);
+
+   /*!
+    *  METHOD: worldToLineSample()
+    * Performs the forward projection from ground point to line, sample.
+    */
+   virtual void worldToLineSample(const ossimGpt& worldPoint,
+                                  ossimDpt&       lineSampPt) const;
+
+   /*!
+    *  METHOD: lineSampleToWorld()
+    * Performs the inverse projection from line, sample to ground (world):
+    */
+   virtual void lineSampleToWorld(const ossimDpt& lineSampPt,
+                                  ossimGpt&       worldPt) const;
+
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual std::ostream& print(std::ostream& out) const;
+
+   virtual bool operator==(const ossimProjection& projection) const;
+
+  //   virtual ossimDpt getMetersPerPixel() const;
+   virtual void setMetersPerPixel(const ossimDpt& pt);
+   /*!
+    * This will go from the ground point and give
+    * you an approximate lat and lon per pixel. the Delta Lat
+    * and delta lon will be in degrees.
+    */
+   virtual void computeDegreesPerPixel(const ossimGpt& ground,
+                                       const ossimDpt& metersPerPixel,
+                                       double &deltaLat,
+                                       double &deltaLon);
+
+   
+   /*!
+    * This will go from the ground point and give
+    * you an approximate meters per pixel. the Delta Lat
+    * and delta lon will be in degrees.
+    */
+   virtual void computeMetersPerPixel(const ossimGpt& center,
+                                      double deltaDegreesPerPixelLat,
+                                      double deltaDegreesPerPixelLon,
+                                      ossimDpt &metersPerPixel);
+   
+private:
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjection.cpp
new file mode 100644
index 0000000000..d8ebaa55e6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjection.cpp
@@ -0,0 +1,1054 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Base class for all map projections.
+// 
+//*******************************************************************
+//  $Id: ossimMapProjection.cpp,v 1.108 2005/12/25 17:11:52 dburken Exp $
+
+#include <iostream>
+#include <iomanip>
+
+#include <projections/map_projections/ossimMapProjection.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/ossimString.h>
+#include <elevation/ossimElevManager.h>
+#include <base/data_types/ossimMatrix3x3.h>
+#include <base/misc/ossimUnitConversionTool.h>
+
+// RTTI information for the ossimMapProjection
+RTTI_DEF1(ossimMapProjection, "ossimMapProjection" , ossimProjection);
+
+
+ossimMapProjection::ossimMapProjection(const ossimEllipsoid& ellipsoid,
+                                       const ossimGpt& origin)
+   :theEllipsoid(ellipsoid),
+    theOrigin(origin),
+    theDatum(origin.datum()), // force no shifting
+    theMetersPerPixel(1, 1),
+    theUlGpt(0, 0),
+    theUlEastingNorthing(0, 0),
+    theDeltaLatPerPixel(OSSIM_DBL_NAN),
+    theDeltaLonPerPixel(OSSIM_DBL_NAN)
+{
+   theUlGpt = theOrigin;
+   theUlEastingNorthing.makeNan();
+
+   thePcsCode = 0;
+}
+
+ossimMapProjection::ossimMapProjection(const ossimMapProjection& src)
+      : ossimProjection(src),
+        theEllipsoid(src.theEllipsoid),
+        theOrigin(src.theOrigin),
+        theDatum(src.theDatum),
+        theMetersPerPixel(src.theMetersPerPixel),
+        theUlGpt(src.theUlGpt),
+        theUlEastingNorthing(src.theUlEastingNorthing),
+        theDeltaLatPerPixel(src.theDeltaLatPerPixel),
+        theDeltaLonPerPixel(src.theDeltaLonPerPixel),
+        thePcsCode(src.thePcsCode)
+{
+}
+
+
+ossimMapProjection::~ossimMapProjection()
+{
+}
+
+ossimGpt ossimMapProjection::origin()const
+{
+   return theOrigin;
+}
+
+void ossimMapProjection::setPcsCode(ossim_uint16 pcsCode)
+{
+  thePcsCode = pcsCode;
+}
+
+ossim_uint16 ossimMapProjection::getPcsCode()const
+{
+  return thePcsCode;
+}
+
+ossimString ossimMapProjection::getProjectionName() const
+{
+   return getClassName();
+}
+
+double ossimMapProjection::getA() const
+{
+   return theEllipsoid.getA();
+}
+
+double ossimMapProjection::getB() const
+{
+   return theEllipsoid.getB();
+}
+
+double ossimMapProjection::getF() const
+{
+   return theEllipsoid.getFlattening();
+}
+
+ossimDpt ossimMapProjection::getMetersPerPixel() const
+{
+   return theMetersPerPixel;
+}
+
+ossimDpt ossimMapProjection::getDecimalDegreesPerPixel() const
+{
+   return ossimDpt(theDeltaLonPerPixel, theDeltaLatPerPixel);
+}
+
+const ossimDpt& ossimMapProjection::getUlEastingNorthing() const
+{
+   return theUlEastingNorthing;
+}
+
+const ossimGpt&   ossimMapProjection::getUlGpt() const
+{
+   return theUlGpt;
+}
+
+const ossimDatum* ossimMapProjection::getDatum() const
+{
+   return theDatum;
+}
+
+bool ossimMapProjection::isGeographic()const
+{
+   return false;
+}
+
+void ossimMapProjection::setEllipsoid(const ossimEllipsoid& ellipsoid)
+{
+   theEllipsoid = ellipsoid; update();
+}
+
+void ossimMapProjection::setAB(double a, double b)
+{
+   theEllipsoid.setA(a); theEllipsoid.setB(b); update();
+}
+
+void ossimMapProjection::setDatum(const ossimDatum* datum)
+{
+   if(datum)
+   {
+      theDatum = datum; setEllipsoid( *(datum->ellipsoid()));
+   }
+}
+
+void ossimMapProjection::setOrigin(const ossimGpt& origin)
+{
+   theOrigin = origin; update();
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::assign
+//
+//*****************************************************************************
+void ossimMapProjection::assign(const ossimProjection &aProjection)
+{
+   if(&aProjection!=this)
+   {
+      ossimKeywordlist kwl;
+
+      aProjection.saveState(kwl);
+      loadState(kwl);
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::update
+//
+//*****************************************************************************
+void ossimMapProjection::update()
+{
+   // if the delta lat and lon per pixel is set then
+   // check to see if the meters were set.
+   //
+   if((theDeltaLatPerPixel != OSSIM_DBL_NAN)&&
+      (theDeltaLonPerPixel != OSSIM_DBL_NAN))
+   {
+      if(theMetersPerPixel.hasNans())
+      {
+         computeMetersPerPixel(theDeltaLatPerPixel,
+                               theDeltaLonPerPixel,
+                               theMetersPerPixel);
+      }
+   }
+   else if(!theMetersPerPixel.hasNans())
+   {
+      computeDegreesPerPixel(theOrigin,
+                             theMetersPerPixel,
+                             theDeltaLatPerPixel,
+                             theDeltaLonPerPixel);
+   }
+
+   // compute the tie points if not already computed
+   //
+   if((theUlGpt.latd()==OSSIM_DBL_NAN)||
+      (theUlGpt.lond()==OSSIM_DBL_NAN))
+   {
+      theUlGpt = theOrigin;
+   }
+    if(theUlEastingNorthing.hasNans())
+    {
+//       theUlEastingNorthing.x = 0.0;
+//       theUlEastingNorthing.y = 0.0;
+      if((theUlGpt.latd()!=OSSIM_DBL_NAN)&&
+ 	(theUlGpt.lond()!=OSSIM_DBL_NAN))
+      {
+         theUlEastingNorthing = forward(theUlGpt);
+      }
+    }
+}
+
+void ossimMapProjection::applyScale(const ossimDpt& scale,
+                                    bool recenterTiePoint)
+{
+   if (!recenterTiePoint)
+   {
+      theDeltaLonPerPixel *= scale.x;
+      theDeltaLatPerPixel *= scale.y;
+      theMetersPerPixel.x *= scale.x;
+      theMetersPerPixel.y *= scale.y;
+   }
+   else
+   {
+      if (isGeographic())
+      {
+         // Get the current tie.
+         ossimGpt tie = getUlGpt();
+         
+         // Shift it to the upper left edge of the pixel.
+         tie.lond( tie.lond() - theDeltaLonPerPixel/2.0);
+         tie.latd( tie.latd() + theDeltaLatPerPixel/2.0);
+         
+         // Apply the scale.
+         theDeltaLonPerPixel *= scale.x;
+         theDeltaLatPerPixel *= scale.y;
+         theMetersPerPixel.x *= scale.x;
+         theMetersPerPixel.y *= scale.y;
+         
+         // Now shift it back to center of the new tie.
+         tie.lond( tie.lond() + theDeltaLonPerPixel/2.0);
+         tie.latd( tie.latd() - theDeltaLatPerPixel/2.0);
+         
+         // Set the tie to new point.
+         setUlGpt(tie);
+      }
+      else
+      {
+         // Get the current tie point.
+         ossimDpt tie = getUlEastingNorthing();
+         
+         // Shift it to the upper left edge of the pixel.
+         tie.x -= theMetersPerPixel.x/2.0;
+         tie.y += theMetersPerPixel.y/2.0;
+         
+         // Apply the scale.
+         theMetersPerPixel.x *= scale.x;
+         theMetersPerPixel.y *= scale.y;
+         theDeltaLonPerPixel *= scale.x;
+         theDeltaLatPerPixel *= scale.y;
+         
+         // Now shift it back to center of the new tie.
+         tie.x += theMetersPerPixel.x/2.0;
+         tie.y -= theMetersPerPixel.y/2.0;
+         
+         // Set the tie to new point.
+         setUlEastingNorthing(tie);
+      }
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::worldToLineSample
+//
+//*****************************************************************************
+ossimDpt ossimMapProjection::worldToLineSample(const ossimGpt &worldPoint)const
+{
+   ossimDpt result;
+
+   worldToLineSample(worldPoint, result);
+
+   return result;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::lineSampleToWorld
+//
+//*****************************************************************************
+ossimGpt ossimMapProjection::lineSampleToWorld(const ossimDpt &lineSample)const
+{
+   ossimGpt result;
+
+   lineSampleToWorld(lineSample, result);
+
+   return result;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::worldToLineSample
+//
+//*****************************************************************************
+void ossimMapProjection::worldToLineSample(const ossimGpt &worldPoint,
+                                           ossimDpt&       lineSample)const
+{
+   // make sure our tie point is good and world point
+   // is good.
+   //
+   if(theUlEastingNorthing.isNan()||
+      worldPoint.isLatNan() || worldPoint.isLonNan())
+   {
+      lineSample.makeNan();
+      return;
+   }
+   // initialize line sample
+   //   lineSample = ossimDpt(0,0);
+
+   // I am commenting this code out because I am going to
+   // move it to the ossimImageViewProjectionTransform.
+   //
+   // see if we have a datum set and if so
+   // shift the world to our datum.  If not then
+   // find the easting northing value for the world
+   // point.
+    if(theDatum)
+    {
+       ossimGpt gpt = worldPoint;
+
+       gpt.changeDatum(theDatum);
+
+       // lineSample is currently in easting northing
+       // and will need to be converted to line sample.
+       lineSample = forward(gpt);
+    }
+    else
+    {
+       // lineSample is currently in easting northing
+       // and will need to be converted to line sample.
+       lineSample = forward(worldPoint);
+    }
+
+   // check the final result to make sure there were no
+   // problems.
+   //
+   if(!lineSample.isNan())
+   {
+//       if(!isIdentityMatrix())
+//       {
+//          ossimDpt temp = lineSample;
+
+//          lineSample.x = theInverseTrans[0][0]*temp.x+
+//                         theInverseTrans[0][1]*temp.y+
+//                         theInverseTrans[0][2];
+
+//          lineSample.y = theInverseTrans[1][0]*temp.x+
+//                         theInverseTrans[1][1]*temp.y+
+//                         theInverseTrans[1][2];
+//       }
+//       else
+      {
+         lineSample.x = ((lineSample.x  - theUlEastingNorthing.x)/theMetersPerPixel.x);
+
+         // We must remember that the Northing is negative since the positive
+         // axis for an image is assumed to go down since it's image space.
+         lineSample.y = (-(lineSample.y - theUlEastingNorthing.y)/theMetersPerPixel.y);
+      }
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::lineSampleHeightToWorld
+//
+//*****************************************************************************
+void ossimMapProjection::lineSampleHeightToWorld(const ossimDpt &lineSample,
+                                                 const double&  hgtEllipsoid,
+                                                 ossimGpt&      gpt)const
+{
+   //
+   // make sure that the passed in lineSample is good and
+   // check to make sure our easting northing is good so
+   // we can compute the line sample.
+   //
+   //
+   if(lineSample.hasNans()||theUlEastingNorthing.hasNans())
+   {
+      gpt.makeNan();
+      return;
+   }
+   ossimDpt eastingNorthing;
+
+   eastingNorthing = (theUlEastingNorthing);
+   
+   eastingNorthing.x += (lineSample.x*theMetersPerPixel.x);
+
+   //
+   // Note:  the Northing is positive up.  In image space
+   // the positive axis is down so we must multiply by
+   // -1
+   //
+   eastingNorthing.y += (-lineSample.y*theMetersPerPixel.y);
+
+
+   //
+   // now invert the meters into a ground point.
+   //
+   gpt = inverse(eastingNorthing);
+   gpt.datum(theDatum);
+
+   if(gpt.isLatNan() && gpt.isLonNan())
+   {
+      gpt.makeNan();
+   }
+   else
+   {
+      gpt.clampLat(-90, 90);
+      gpt.clampLon(-180, 180);
+
+      // Finally assign the specified height:
+      gpt.hgt = hgtEllipsoid;
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::lineSampleToWorld
+//
+//  Implements the base class pure virtual. Simply calls lineSampleToWorld()
+//  and assigns argument height to the resultant groundpoint.
+//
+//*****************************************************************************
+void ossimMapProjection::lineSampleToWorld (const ossimDpt& lineSampPt,
+                                            ossimGpt&       worldPt) const
+{
+   double null_elev = OSSIM_DBL_NAN;
+
+   lineSampleHeightToWorld(lineSampPt, null_elev, worldPt);
+
+   worldPt.hgt =  ossimElevManager::instance()->getHeightAboveEllipsoid(worldPt);
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::lineSampleToEastingNorthing
+//
+//*****************************************************************************
+void ossimMapProjection::lineSampleToEastingNorthing(const ossimDpt& lineSample,
+                                                     ossimDpt&       eastingNorthing)const
+{
+   // make sure that the passed in lineSample is good and
+   // check to make sure our easting northing is good so
+   // we can compute the line sample.
+   //
+   if(lineSample.hasNans()||theUlEastingNorthing.hasNans())
+   {
+      eastingNorthing.makeNan();
+      return;
+   }
+   ossimDpt deltaPoint = lineSample;
+
+   eastingNorthing.x = theUlEastingNorthing.x + deltaPoint.x*theMetersPerPixel.x;
+   eastingNorthing.y = theUlEastingNorthing.y + (-deltaPoint.y)*theMetersPerPixel.y ;
+
+   //   eastingNorthing.x += (lineSample.x*theMetersPerPixel.x);
+
+   // Note:  the Northing is positive up.  In image space
+   // the positive axis is down so we must multiply by
+   // -1
+   //   eastingNorthing.y += (-lineSample.y*theMetersPerPixel.y);
+}
+
+void ossimMapProjection::setMetersPerPixel(const ossimDpt& gsd)
+{
+   theMetersPerPixel=gsd;
+   computeDegreesPerPixel(theOrigin,
+                          theMetersPerPixel,
+                          theDeltaLatPerPixel,
+                          theDeltaLonPerPixel);
+}
+
+void ossimMapProjection::setDecimalDegreesPerPixel(const ossimDpt& gsd)
+{
+   theDeltaLatPerPixel = gsd.lat;
+   theDeltaLonPerPixel = gsd.lon;
+
+   computeMetersPerPixel(theOrigin,
+                         gsd.lat,
+                         gsd.lon,
+                         theMetersPerPixel);
+}
+
+void ossimMapProjection::eastingNorthingToWorld(const ossimDpt& eastingNorthing,
+                                                ossimGpt&       worldPt)const
+{
+   ossimDpt lineSample;
+   eastingNorthingToLineSample(eastingNorthing, lineSample);
+   lineSampleToWorld(lineSample, worldPt);
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::eastingNorthingToLineSample
+//
+//*****************************************************************************
+void ossimMapProjection::eastingNorthingToLineSample(const ossimDpt& eastingNorthing,
+                                                     ossimDpt&       lineSample)const
+{
+   if(eastingNorthing.hasNans())
+   {
+      lineSample.makeNan();
+      return;
+   }
+   // check the final result to make sure there were no
+   // problems.
+   //
+   if(!eastingNorthing.isNan())
+   {
+     lineSample.x = (eastingNorthing.x - theUlEastingNorthing.x)/theMetersPerPixel.x;
+
+     // We must remember that the Northing is negative since the positive
+     // axis for an image is assumed to go down since it's image space.
+     lineSample.y = (-(eastingNorthing.y-theUlEastingNorthing.y))/theMetersPerPixel.y;
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::setUlEastingNorthing
+//
+//*****************************************************************************
+void ossimMapProjection::setUlEastingNorthing(const ossimDpt& ulEastingNorthing)
+{
+   theUlEastingNorthing = ulEastingNorthing;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::setUlGpt
+//
+//*****************************************************************************
+void ossimMapProjection::setUlGpt(const ossimGpt& ulGpt)
+{
+   theUlGpt = ulGpt;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::saveState
+//
+//*****************************************************************************
+bool ossimMapProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   ossimProjection::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           ossimKeywordNames::ORIGIN_LATITUDE_KW,
+           theOrigin.latd(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+           theOrigin.lond(),
+           true);
+
+   if(isGeographic())
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LAT_KW,
+              theUlGpt.latd(),
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LON_KW,
+              theUlGpt.lond(),
+              true);
+   }
+
+   theEllipsoid.saveState(kwl, prefix);
+
+   if(!ossimIsNan(theDeltaLatPerPixel)&&isGeographic())
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+              theDeltaLatPerPixel,
+              true);
+   }
+
+   if(!ossimIsNan(theDeltaLonPerPixel)&&isGeographic())
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+              theDeltaLonPerPixel,
+              true);
+   }
+
+   if(theDatum)
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::DATUM_KW,
+              theDatum->code(),
+              true);
+   }
+
+   if(!theMetersPerPixel.isNan()&&!isGeographic())
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+              theMetersPerPixel.x,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+              theMetersPerPixel.y,
+              true);
+   }
+
+   if(!theUlEastingNorthing.isNan()&&!isGeographic())
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_EASTING_KW,
+              theUlEastingNorthing.x,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_NORTHING_KW,
+              theUlEastingNorthing.y,
+              true);
+   }
+
+   if(thePcsCode != 0)
+     {
+       kwl.add(prefix,
+	       ossimKeywordNames::PCS_CODE_KW,
+	       thePcsCode,
+	       true);
+     }
+
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::loadState
+//
+//*****************************************************************************
+bool ossimMapProjection::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   ossimProjection::loadState(kwl, prefix);
+
+   const char* scale_x  = kwl.find(prefix, ossimKeywordNames::SCALE_X_KW);
+   const char* scale_y  = kwl.find(prefix, ossimKeywordNames::SCALE_Y_KW);
+   const char* trans_x  = kwl.find(prefix, ossimKeywordNames::TRANSLATION_X_KW);
+   const char* trans_y  = kwl.find(prefix, ossimKeywordNames::TRANSLATION_Y_KW);
+   const char* rotation = kwl.find(prefix, ossimKeywordNames::ROTATION_KW);
+   const char* pcs_code = kwl.find(prefix, ossimKeywordNames::PCS_CODE_KW);
+   ossimDpt scale(1.0, 1.0);
+   ossimDpt trans(0.0, 0.0);
+   double   rot = 0.0;
+
+   if(scale_x)
+      scale.x = ossimString(scale_x).toDouble();
+
+   if(scale_y)
+      scale.y = ossimString(scale_y).toDouble();
+
+   if(trans_x)
+      trans.x = ossimString(trans_x).toDouble();
+
+   if(trans_y)
+      trans.y = ossimString(trans_y).toDouble();
+
+   if(rotation)
+      rot = ossimString(rotation).toDouble();
+
+   if(pcs_code)
+     {
+       thePcsCode = (ossim_uint16)ossimString(pcs_code).toULong();
+     }
+   else
+     {
+       thePcsCode = 0;
+     }
+
+   const char *lookup;
+
+   // Get the latitude of the origin.
+   lookup = kwl.find(prefix, ossimKeywordNames::ORIGIN_LATITUDE_KW);
+   if (lookup)
+   {
+      theOrigin.latd(ossimString(lookup).toDouble());
+   }
+
+   // Get the central meridian.
+   lookup = kwl.find(prefix, ossimKeywordNames::CENTRAL_MERIDIAN_KW);
+   if (lookup)
+   {
+      theOrigin.lond(ossimString(lookup).toDouble());
+   }
+
+   theEllipsoid.loadState(kwl, prefix);
+
+   //***
+   // Call the virtual method "updateState" to allow derived classes to
+   // verify/update their state.
+   //***
+   lookup = kwl.find(prefix, ossimKeywordNames::DATUM_KW);
+   if(lookup)
+   {
+      theDatum = ossimDatumFactory::instance()->create(lookup);
+      if(theDatum)
+      {
+         const ossimEllipsoid* ellipse = theDatum->ellipsoid();
+         if(ellipse)
+         {
+            theEllipsoid = *ellipse;
+         }
+      }
+   }
+   else
+   {
+      theDatum = ossimDatumFactory::instance()->wgs84();
+   }
+
+   if(theDatum)
+   {
+      theOrigin.datum(theDatum);
+      theUlGpt.datum(theDatum);
+   }
+
+   lookup =  kwl.find(prefix, ossimKeywordNames::METERS_PER_PIXEL_X_KW);
+   if(lookup)
+   {
+      theMetersPerPixel.x = fabs(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      theMetersPerPixel.x = OSSIM_DBL_NAN;
+   }
+
+   lookup =  kwl.find(prefix, ossimKeywordNames::METERS_PER_PIXEL_Y_KW);
+   if(lookup)
+   {
+      theMetersPerPixel.y = fabs(ossimString(lookup).toDouble());
+   }
+   else
+   {
+      theMetersPerPixel.y = OSSIM_DBL_NAN;
+   }
+
+   theUlEastingNorthing.makeNan();
+   theUlGpt.makeNan();
+
+   const char* easting =  kwl.find(prefix, ossimKeywordNames::TIE_POINT_EASTING_KW);
+   if(easting)
+   {
+      theUlEastingNorthing.x = (ossimString(easting).toDouble());
+   }
+
+   const char* northing =  kwl.find(prefix, ossimKeywordNames::TIE_POINT_NORTHING_KW);
+   if(northing)
+   {
+      theUlEastingNorthing.y = (ossimString(northing).toDouble());
+   }
+   const char* tie_lat     = NULL;
+   const char* tie_lon     = NULL;
+
+
+   tie_lat      = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LAT_KW);
+   tie_lon      = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LON_KW);
+
+   if(tie_lat && tie_lon )
+   {
+      theUlGpt.latd(ossimString(tie_lat).toDouble());
+      theUlGpt.lond(ossimString(tie_lon).toDouble());
+   }
+   else
+   {
+      theUlGpt.makeNan();
+   }
+
+   const char* deg_per_lat = kwl.find(prefix, ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT);
+   const char* deg_per_lon = kwl.find(prefix, ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON);
+
+   if(deg_per_lat)
+   {
+      theDeltaLatPerPixel = fabs(ossimString(deg_per_lat).toDouble());
+   }
+   else
+   {
+      theDeltaLatPerPixel = OSSIM_DBL_NAN;
+   }
+   if(deg_per_lon)
+   {
+      theDeltaLonPerPixel = fabs(ossimString(deg_per_lon).toDouble());
+   }
+   else
+   {
+      theDeltaLonPerPixel = OSSIM_DBL_NAN;
+   }
+
+   if((theDeltaLonPerPixel!=OSSIM_DBL_NAN)&&
+      (theDeltaLatPerPixel!=OSSIM_DBL_NAN)&&
+      theMetersPerPixel.hasNans())
+   {
+      theMetersPerPixel    = theOrigin.metersPerDegree();
+      theMetersPerPixel.x *= theDeltaLonPerPixel;
+      theMetersPerPixel.y *= theDeltaLatPerPixel;
+   }
+   
+   ossimString pixelType = kwl.find(prefix, ossimKeywordNames::PIXEL_TYPE_KW);
+   pixelType=pixelType.trim();
+   if(pixelType!="")
+   {
+      pixelType.downcase();
+      if(pixelType.contains("area"))
+      {
+         if((theMetersPerPixel.x != OSSIM_DBL_NAN)&&
+            (theMetersPerPixel.y != OSSIM_DBL_NAN))
+         {
+            if(!theUlEastingNorthing.hasNans())
+            {
+               theUlEastingNorthing.x += theMetersPerPixel.x;
+               theUlEastingNorthing.y -= theMetersPerPixel.y;
+            }
+         }
+         if((theDeltaLatPerPixel != OSSIM_DBL_NAN)&&
+            (theDeltaLonPerPixel != OSSIM_DBL_NAN))
+         {
+            theUlGpt.latd( theUlGpt.latd() - theDeltaLatPerPixel);
+            theUlGpt.lond( theUlGpt.lond() + theDeltaLonPerPixel);
+         }
+      }
+   }
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::print
+//*****************************************************************************
+std::ostream& ossimMapProjection::print(std::ostream& out) const
+{
+   const char MODULE[] = "ossimMapProjection::print";
+
+   out << setiosflags(ios::fixed) << setprecision(15)
+       << "\n// " << MODULE
+       << "\n" << ossimKeywordNames::TYPE_KW               << ":  "
+       << getClassName()
+       << "\n" << ossimKeywordNames::MAJOR_AXIS_KW         << ":  "
+       << theEllipsoid.getA()
+       << "\n" << ossimKeywordNames::MINOR_AXIS_KW         << ":  "
+       << theEllipsoid.getB()
+       << "\n" << ossimKeywordNames::ORIGIN_LATITUDE_KW    << ":  "
+       << theOrigin.latd()
+       << "\n" << ossimKeywordNames::CENTRAL_MERIDIAN_KW   << ":  "
+       << theOrigin.lond()
+       << "\n" << ossimKeywordNames::DATUM_KW              << ":  "
+       << (theDatum?theDatum->code().c_str():"unknown")
+       << "\n" << ossimKeywordNames::METERS_PER_PIXEL_X_KW << ":  "
+       << (ossimIsNan(theMetersPerPixel.x)?ossimString("nan"):ossimString::toString(theMetersPerPixel.x, 15))
+       << "\n" << ossimKeywordNames::METERS_PER_PIXEL_Y_KW << ":  "
+       << (ossimIsNan(theMetersPerPixel.y)?ossimString("nan"):ossimString::toString(theMetersPerPixel.y, 15))
+       << std::endl;
+   return ossimProjection::print(out);
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::computeDegreesPerPixel
+//
+//*****************************************************************************
+void ossimMapProjection::computeDegreesPerPixel(const ossimGpt& ground,
+                                                const ossimDpt& metersPerPixel,
+                                                double &deltaLat,
+                                                double &deltaLon)
+{
+//    ossimDpt mpd = ground.metersPerDegree();
+//    ossimDpt dpm(1.0/mpd.x,
+//                 1.0/mpd.y);
+//    deltaLat = metersPerPixel.y*dpm.y;
+//    deltaLon = metersPerPixel.x*dpm.x;
+   ossimDpt eastNorthGround = forward(ground);
+   ossimDpt rightEastNorth  =  eastNorthGround;
+   ossimDpt downEastNorth   =  eastNorthGround;
+   rightEastNorth.x += metersPerPixel.x;
+   downEastNorth.y  -= metersPerPixel.y;
+
+   ossimGpt rightGpt = inverse(rightEastNorth);
+   ossimGpt downGpt  = inverse(downEastNorth);
+
+   // use euclidean distance to get length along the horizontal (lon)
+   // and vertical (lat) directions
+   //
+   double tempDeltaLat = rightGpt.latd() - ground.latd();
+   double tempDeltaLon = rightGpt.lond() - ground.lond();
+   deltaLon = sqrt(tempDeltaLat*tempDeltaLat + tempDeltaLon*tempDeltaLon);
+
+   tempDeltaLat = downGpt.latd() - ground.latd();
+   tempDeltaLon = downGpt.lond() - ground.lond();
+   deltaLat = sqrt(tempDeltaLat*tempDeltaLat + tempDeltaLon*tempDeltaLon);
+
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::computeMetersPerPixel
+//
+//*****************************************************************************
+void ossimMapProjection::computeMetersPerPixel(const ossimGpt& center,
+                                               double deltaDegreesPerPixelLat,
+                                               double deltaDegreesPerPixelLon,
+                                               ossimDpt &metersPerPixel)
+{
+//     metersPerPixel = center.metersPerDegree();
+//     metersPerPixel.x *= deltaDegreesPerPixelLon;
+//     metersPerPixel.y *= deltaDegreesPerPixelLat;
+
+   ossimGpt right=center;
+   ossimGpt down=center;
+
+   down.latd(center.latd()  + deltaDegreesPerPixelLat);
+   right.lond(center.lond() + deltaDegreesPerPixelLon);
+
+   ossimDpt centerMeters = forward(center);
+   ossimDpt rightMeters = forward(right);
+   ossimDpt downMeters  = forward(down);
+
+
+   metersPerPixel.x = (rightMeters - centerMeters).length();
+   metersPerPixel.y = (downMeters  - centerMeters).length();
+
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::computeMetersPerPixel
+//
+//*****************************************************************************
+void ossimMapProjection::computeMetersPerPixel(double deltaDegreesPerPixelLat,
+                                               double deltaDegreesPerPixelLon,
+                                               ossimDpt &metersPerPixel)
+{
+   computeMetersPerPixel(theOrigin,
+                         deltaDegreesPerPixelLat,
+                         deltaDegreesPerPixelLon,
+                         metersPerPixel);
+}
+
+//*****************************************************************************
+//  METHOD: ossimMapProjection::operator==
+//
+//*****************************************************************************
+bool ossimMapProjection::operator==(const ossimProjection& projection) const
+{
+   const ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, &projection);
+
+   if(!mapProj)
+   {
+      return false;
+   }
+
+   if( (theDatum        == mapProj->theDatum) &&
+       (getClassName()  == mapProj->getClassName())&&
+       (theOrigin       == mapProj->theOrigin))
+   {
+      if(isGeographic())
+      {
+         return ( (theDeltaLatPerPixel == mapProj->theDeltaLatPerPixel) &&
+                  (theDeltaLonPerPixel == mapProj->theDeltaLonPerPixel) &&
+                  (theUlGpt            == mapProj->theUlGpt));
+      }
+      else
+      {
+         return ( (theMetersPerPixel    == mapProj->theMetersPerPixel) &&
+                  (theUlEastingNorthing == mapProj->theUlEastingNorthing));
+      }
+   }
+
+   return false;
+}
+
+double ossimMapProjection::getFalseEasting() const
+{
+   return 0.0;
+}
+
+double ossimMapProjection::getFalseNorthing() const
+{
+   return 0.0;
+}
+
+double ossimMapProjection::getStandardParallel1() const
+{
+   return 0.0;
+}
+
+double ossimMapProjection::getStandardParallel2() const
+{
+   return 0.0;
+}
+
+void ossimMapProjection::snaptTiePointTo(ossim_float64 multiple,
+                                         ossimUnitType unitType)
+{
+   ossim_float64 convertedMultiple = multiple;
+   
+   if (isGeographic() && (unitType != OSSIM_DEGREES) )
+   {
+      // Convert to degrees.
+      ossimUnitConversionTool convertor;
+      convertor.setOrigin(theOrigin);
+      convertor.setValue(multiple, unitType);
+      convertedMultiple = convertor.getDegrees();
+   }
+   else if ( !isGeographic() && (unitType != OSSIM_METERS) )
+   {
+      // Convert to meters.
+      ossimUnitConversionTool convertor;
+      convertor.setOrigin(theOrigin);
+      convertor.setValue(multiple, unitType);
+      convertedMultiple = convertor.getMeters();
+   }
+
+   // cout << "multiple: " << convertedMultiple << endl;
+   
+   // Convert the tie point.
+   if (isGeographic())
+   {
+      // Snap the latitude.
+      ossim_float64 d = theUlGpt.latd();
+      d = irint(d / convertedMultiple) * convertedMultiple;
+      theUlGpt.latd(d);
+
+      // Snap the longitude.
+      d = theUlGpt.lond();
+      d = irint(d / convertedMultiple) * convertedMultiple;
+      theUlGpt.lond(d);
+
+      // Adjust the stored easting / northing.
+      theUlEastingNorthing = forward(theUlGpt);
+   }
+   else
+   {
+      // Snap the easting.
+      ossim_float64 d = theUlEastingNorthing.x;
+      d = irint(d / convertedMultiple) * convertedMultiple;
+      theUlEastingNorthing.x = d;
+
+      // Snap the northing.
+      d = theUlEastingNorthing.y;
+      d = irint(d / convertedMultiple) * convertedMultiple;
+      theUlEastingNorthing.y = d;
+
+      // Adjust the stored upper left ground point.
+      theUlGpt = inverse(theUlEastingNorthing);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjection.h
new file mode 100644
index 0000000000..e70bc2e349
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjection.h
@@ -0,0 +1,295 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Base class for all map projections.
+// 
+//*******************************************************************
+//  $Id: ossimMapProjection.h,v 1.51 2005/12/25 17:11:52 dburken Exp $
+
+#ifndef ossimMapProjection_HEADER
+#define ossimMapProjection_HEADER
+
+#include <projections/ossimProjection.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimKeyword.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/data_types/ossimDrect.h>
+#include <iostream>
+using namespace std;
+
+#include <matrix/newmat.h>
+#include <matrix/newmatio.h>
+
+class ossimKeywordlist;
+
+class OSSIMDLLEXPORT ossimMapProjection : public ossimProjection
+{
+public:
+   ossimMapProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                      const ossimGpt& origin=ossimGpt());
+
+   ossimMapProjection(const ossimMapProjection& src);
+   virtual ~ossimMapProjection();
+
+   virtual ossimGpt origin()const;
+
+   /**
+    * All map projections will convert the world coordinate to an easting
+    * northing (Meters).
+    */
+   virtual ossimDpt forward(const ossimGpt &worldPoint) const = 0;
+
+   /**
+    * Will take a point in meters and convert it to ground.
+    */
+   virtual ossimGpt inverse(const ossimDpt &projectedPoint)const = 0;
+
+   virtual ossimDpt worldToLineSample(const ossimGpt &worldPoint)const;
+   virtual void     worldToLineSample(const ossimGpt &worldPoint,
+                                      ossimDpt&       lineSample)const;
+   
+   virtual ossimGpt lineSampleToWorld(const ossimDpt &projectedPoint)const;
+   virtual void     lineSampleToWorld(const ossimDpt &projectedPoint,
+                                      ossimGpt& gpt)const;
+   /**
+    * This is the pure virtual that projects the image point to the given
+    * elevation above ellipsoid, thereby bypassing reference to a DEM. Useful
+    * for projections that are sensitive to elevation.
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                        const double&   heightAboveEllipsoid,
+                                        ossimGpt&       worldPt) const;
+
+   virtual void lineSampleToEastingNorthing(const ossimDpt& liineSample,
+                                            ossimDpt& eastingNorthing)const;
+
+   virtual void eastingNorthingToLineSample(const ossimDpt& eastingNorthing,
+                                            ossimDpt&       lineSample)const;
+
+   virtual void eastingNorthingToWorld(const ossimDpt& eastingNorthing,
+                                       ossimGpt&       worldPt)const;
+
+   
+   /**
+    * Derived classes should implement as needed.
+    * This implementation returns 0.0.
+    * 
+    * @return The false easting.
+    *
+    * @note At some point we should make theFalseEasting a data member and
+    * change derived classes to use it.
+    */
+   virtual double getFalseEasting() const;
+
+   /**
+    * Derived classes should implement as needed.
+    * This implementation returns 0.0.
+    * 
+    * @return The false northing.
+    * 
+    * @note At some point we should make theFalseEasting a data member and
+    * change derived classes to use it.
+    */
+   virtual double getFalseNorthing() const;
+   
+   /**
+    * Derived classes should implement as needed.
+    * This implementation returns 0.0.
+    * 
+    * @return The first standard parallel.
+    */
+   virtual double getStandardParallel1() const;
+
+   /**
+    * Derived classes should implement as needed.
+    * This implementation returns 0.0.
+    * 
+    * @return The second standard parallel.
+    */
+   virtual double getStandardParallel2() const;
+   
+   virtual void update();
+
+   virtual void setPcsCode(ossim_uint16 pcsCode);
+   virtual ossim_uint16 getPcsCode()const;
+   
+   /**
+    *  Returns the projection name.
+    */
+   virtual ossimString getProjectionName() const;
+   
+   /**
+    * ACCESS METHODS: 
+    */
+   virtual double getA() const;
+   virtual double getB() const;
+   virtual double getF() const;
+   
+   virtual ossimDpt getMetersPerPixel() const;
+
+   /**
+    * Returns decimal degrees per pixel as an ossimDpt with
+    * "x" representing longitude and "y" representing latitude.
+    */
+   virtual ossimDpt getDecimalDegreesPerPixel() const;
+   
+   virtual const ossimDpt&   getUlEastingNorthing() const;
+   virtual const ossimGpt&   getUlGpt() const;
+   virtual const ossimDatum* getDatum() const;
+
+   virtual bool isGeographic()const;
+
+   /**
+    * Applies scale to theDeltaLonPerPixel, theDeltaLatPerPixel and
+    * theMetersPerPixel data members (eg: theDeltaLonPerPixel *= scale.x).
+    *
+    * @param scale Multiplier to be applied to theDeltaLonPerPixel,
+    * theDeltaLatPerPixel and theMetersPerPixel
+    *
+    * @param recenterTiePoint If true the will adjust the tie point by
+    * shifting the original tie to the upper left corner, applying scale,
+    * then shifting back by half of either the new
+    * theDeltaLat/lon or theMetersPerPixel depending on if projection
+    * isGeographic.
+    */
+   virtual void applyScale(const ossimDpt& scale, bool recenterTiePoint);
+   
+   /**
+    * SET METHODS: 
+    */
+   virtual void setEllipsoid(const ossimEllipsoid& ellipsoid);
+   virtual void setAB(double a, double b);
+   virtual void setDatum(const ossimDatum* datum);
+   virtual void setOrigin(const ossimGpt& origin);
+   virtual void setMetersPerPixel(const ossimDpt& gsd);
+   virtual void setDecimalDegreesPerPixel(const ossimDpt& gsd);
+   virtual void setUlEastingNorthing(const  ossimDpt& ulEastingNorthing);
+   virtual void setUlGpt(const  ossimGpt& ulGpt);
+   virtual void assign( const  ossimProjection &aProjection);
+   
+    /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * Prints data members to stream.  Returns stream&.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+   virtual bool operator==(const ossimProjection& projection) const;
+
+   /**
+    * This will go from the ground point and give
+    * you an approximate lat and lon per pixel. the Delta Lat
+    * and delta lon will be in degrees.
+    */
+   virtual void computeDegreesPerPixel(const ossimGpt& ground,
+                                       const ossimDpt& metersPerPixel,
+                                       double &deltaLat,
+                                       double &deltaLon);
+
+   
+   /**
+    * This will go from the ground point and give
+    * you an approximate meters per pixel. the Delta Lat
+    * and delta lon will be in degrees.
+    */
+   virtual void computeMetersPerPixel(const ossimGpt& center,
+                                      double deltaDegreesPerPixelLat,
+                                      double deltaDegreesPerPixelLon,
+                                      ossimDpt &metersPerPixel);
+
+   /**
+    * This will go from its internal origin of latitude and longitude and give
+    * you an approximate meters per pixel. the Delta Lat
+    * and delta lon will be in degrees.
+    */
+   virtual void computeMetersPerPixel(double deltaDegreesPerPixelLat,
+                                      double deltaDegreesPerPixelLon,
+                                      ossimDpt &metersPerPixel);
+
+   void setMatrix(double rotation,
+                  const ossimDpt& scale,
+                  const ossimDpt& translation);
+   
+   void setMatrixScale(const ossimDpt& scale);
+   
+   void setMatrixRotation(double rotation);
+
+   void setMatrixTranslation(const ossimDpt& translation);
+
+   /**
+    * Utility method to snap the tie point to some multiple.
+    *
+    * This is used to overcome inaccuracies in formats like NITF's rpc tag
+    * witch has a four digit decimal degree precision for the lat/lon offset.
+    *
+    * @param multiple Value to snap tie point to like 1.0.
+    *
+    * @param unitType OSSIM_METERS or OSSIM_DEGREES.
+    *
+    * EXAMPLE1:
+    * projection:    ossimUtmProjection
+    * tie point is:  551634.88, 4492036.16
+    * multiple:      1.0
+    * unitType:      OSSIM_METERS
+    * new tie point: 551635.00, 4492036.00
+    *
+    * EXAMPLE2:
+    * projection:    ossimEquDistCylProjection
+    * tie point is:  -90.3246343      42.0297589
+    * multiple:      0.0001
+    * unitType:      OSSIM_DEGREES
+    * new tie point: -90.3246 42.0298
+    */
+   void snaptTiePointTo(ossim_float64 multiple, ossimUnitType unitType);
+                      
+
+protected:
+   ossimEllipsoid   theEllipsoid;
+   ossimGpt         theOrigin;
+
+   /**
+    * This is only set if we want to have built in datum shifting
+    */
+   const ossimDatum* theDatum;
+   
+   /**
+    * Holds the number of meters per sample.
+    */
+   ossimDpt          theMetersPerPixel;
+   
+   ossimGpt          theUlGpt;
+   ossimDpt          theUlEastingNorthing;
+
+   double            theDeltaLatPerPixel;
+   double            theDeltaLonPerPixel;
+   
+   ossim_uint16      thePcsCode;
+   
+TYPE_DATA
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjectionInfo.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjectionInfo.cpp
new file mode 100644
index 0000000000..0c67a1d1c3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjectionInfo.cpp
@@ -0,0 +1,548 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// Class for encapsulate projection info given a projection, datum, and
+// output rectangle.
+//
+// NOTE:
+// - Output rectangle should be relative to the center of pixels.
+//   Shifts will be made for "pixel is area" internally.
+//
+//*******************************************************************
+//  $Id: ossimMapProjectionInfo.cpp,v 1.30 2005/10/13 15:04:06 dburken Exp $
+
+#include <fstream>
+#include <time.h>
+
+using namespace std;
+
+#include <projections/map_projections/ossimMapProjectionInfo.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+
+//***
+// Static trace for debugging.
+//***
+static ossimTrace traceDebug("ossimMapProjectionInfo::debug");
+
+//***
+// Keywords for getStateFrom/saveStateTo.
+//***
+const char* ossimMapProjectionInfo::OUTPUT_US_FT_INFO_KW =
+"viewinfo.output_readme_in_us_ft_flag";
+
+const char* ossimMapProjectionInfo::PIXEL_TYPE_KW = "viewinfo.pixel_type";
+
+const char* ossimMapProjectionInfo::README_IMAGE_STRING_KW =
+"viewinfo.readme_image_string";
+
+ossimMapProjectionInfo::ossimMapProjectionInfo(const ossimMapProjection* proj,
+                                               const ossimDrect& output_rect)
+   :
+      theProjection               (proj),
+      theErrorStatus              (false),
+      theLinesPerImage            (0),
+      thePixelsPerLine            (0),
+      theCornerGroundPt           (),
+      theCornerEastingNorthingPt  (),
+      theCenterGroundPt           (),
+      theCenterEastingNorthingPt  (0.0, 0.0),
+      thePixelType                (OSSIM_PIXEL_IS_POINT),
+      theOutputInfoInFeetFlag     (false),
+      theImageInfoString          ()
+{
+   if (!theProjection)
+   {
+      theErrorStatus = true;
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimMapProjectionInfo::ossimMapProjectionInfo: "
+         << "Null projection pointer passed to constructor!"
+         << "\nError status has been set.  Returning..."
+         << std::endl;
+      return;
+   }
+   
+   initializeMembers(output_rect);
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimMapProjectionInfo::ossimMapProjectionInfo:\n"
+         << "output_rect:  " << output_rect << "\n"
+         << *this << std::endl;
+   }
+}
+
+ossimMapProjectionInfo::~ossimMapProjectionInfo()
+{
+}
+
+bool ossimMapProjectionInfo::errorStatus() const
+{
+   return theErrorStatus;
+}
+
+void ossimMapProjectionInfo::initializeMembers(const ossimDrect& rect)
+{
+   theBoundingRect = rect;
+   theLinesPerImage  = irint(rect.height());
+   thePixelsPerLine  = irint(rect.width());
+
+   theProjection->lineSampleToWorld(rect.ul(),
+                                    theCornerGroundPt[0]);
+   
+   theProjection->lineSampleToWorld(rect.ur(),
+                                    theCornerGroundPt[1]);
+   
+   theProjection->lineSampleToWorld(rect.lr(), 
+                                    theCornerGroundPt[2]);
+   
+   
+   theProjection->lineSampleToWorld(rect.ll(), 
+                                    theCornerGroundPt[3]);
+
+   theProjection->lineSampleToEastingNorthing(rect.ul(),
+                                              theCornerEastingNorthingPt[0]);
+
+   theProjection->lineSampleToEastingNorthing(rect.ur(), 
+                                              theCornerEastingNorthingPt[1]);
+   
+   theProjection->lineSampleToEastingNorthing(rect.lr(),
+                                              theCornerEastingNorthingPt[2]);
+   
+   theProjection->lineSampleToEastingNorthing(rect.ll(), 
+                                              theCornerEastingNorthingPt[3]);
+   
+   theCenterEastingNorthingPt.x = (theCornerEastingNorthingPt[0].x +
+                                   theCornerEastingNorthingPt[1].x +
+                                   theCornerEastingNorthingPt[2].x +
+                                   theCornerEastingNorthingPt[3].x) / 4.0;
+   
+   theCenterEastingNorthingPt.y = (theCornerEastingNorthingPt[0].y +
+                                   theCornerEastingNorthingPt[1].y +
+                                   theCornerEastingNorthingPt[2].y +
+                                   theCornerEastingNorthingPt[3].y) / 4.0;
+   
+   theCenterGroundPt = theProjection->inverse(theCenterEastingNorthingPt);
+}
+
+
+void ossimMapProjectionInfo::getGeom(ossimKeywordlist& kwl,
+                                     const char* prefix)const
+{
+   ossimDpt dpt = ulEastingNorthingPt();
+   ossimGpt gpt = ulGroundPt();
+
+   theProjection->saveState(kwl, prefix);
+
+   if(!theProjection->isGeographic())
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_EASTING_KW,
+              dpt.x,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_NORTHING_KW,
+              dpt.y,
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LAT_KW,
+              gpt.latd(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LON_KW,
+              gpt.lond(),
+              true);
+   }
+}
+
+std::ostream& ossimMapProjectionInfo::print(std::ostream& os) const
+{
+   if (!os)
+   {
+      return os;
+   }
+
+   os << setiosflags(ios::left)
+      << setiosflags(ios::fixed)
+      << "ossimMapProjectionInfo Data Members:\n"
+      << "Projection name:  " << theProjection->getProjectionName()
+      << setw(30) << "\nOutput pixel type:"
+      << ((getPixelType() == OSSIM_PIXEL_IS_POINT) ? "pixel is point" :
+          "pixel is area")
+      << setw(30) << "\nMeters per pixel:"
+      << getMetersPerPixel()
+      << setw(30) << "\nUS survey feet per pixel:"
+      << getUsSurveyFeetPerPixel()
+      << setw(30) << "\nDecimal degrees per pixel:"
+      << getDecimalDegreesPerPixel()
+      << setw(30) << "\nNumber of lines:"
+      << theLinesPerImage
+      << setw(30) << "\nNumber of pixels:"
+      << thePixelsPerLine
+      << setw(30) << "\nUpper left ground point:"
+      << theCornerGroundPt[0]
+      << setw(30) << "\nUpper right ground point:"
+      << theCornerGroundPt[1]
+      << setw(30) << "\nLower right ground point:"
+      << theCornerGroundPt[2]
+      << setw(30) << "\nLower left ground point:"
+      << theCornerGroundPt[3]
+      << setw(30) << "\nUpper left easting_northing:"
+      << theCornerEastingNorthingPt[0]
+      << setw(30) << "\nUpper right easting_northing:"
+      << theCornerEastingNorthingPt[1]
+      << setw(30) << "\nLower right easting_northing:"
+      << theCornerEastingNorthingPt[2]
+      << setw(30) << "\nLower left easting_northing:"
+      << theCornerEastingNorthingPt[3]
+      << setw(30) << "\nCenter ground point:"
+      << theCenterGroundPt
+      << setw(30) << "\nCenter easting_northing:"
+      << theCenterEastingNorthingPt
+      << "\nMap Projection dump:";
+   theProjection->print(os);
+
+   return os;
+}
+
+void ossimMapProjectionInfo::setPixelType (ossimPixelType type)
+{
+   thePixelType = type;
+}
+
+ossimPixelType ossimMapProjectionInfo::getPixelType () const
+{
+   return thePixelType;
+}
+
+void ossimMapProjectionInfo::setOutputFeetFlag (bool flag)
+{
+   theOutputInfoInFeetFlag = flag;
+}
+
+bool ossimMapProjectionInfo::unitsInFeet() const
+{
+   return theOutputInfoInFeetFlag;
+}
+
+ossimString ossimMapProjectionInfo::getImageInfoString () const
+{
+   return theImageInfoString;
+}
+
+void ossimMapProjectionInfo::setImageInfoString (const ossimString& string)
+{
+   theImageInfoString = string;
+}
+
+const ossimMapProjection* ossimMapProjectionInfo::getProjection() const
+{
+   return theProjection;
+}
+
+ossimDpt ossimMapProjectionInfo::ulEastingNorthingPt( ) const
+{
+   if (getPixelType() == OSSIM_PIXEL_IS_AREA)
+   {
+      ossimDpt mpp = getMetersPerPixel();
+      ossimDpt pt;
+      pt.x = theCornerEastingNorthingPt[0].x - (mpp.x / 2.0);
+      pt.y = theCornerEastingNorthingPt[0].y + (mpp.y / 2.0);
+      return pt;
+   }
+   else
+   {
+      return theCornerEastingNorthingPt[0];
+   }
+}
+
+ossimDpt ossimMapProjectionInfo::urEastingNorthingPt( ) const
+{
+   if (getPixelType() == OSSIM_PIXEL_IS_AREA)
+   {
+      ossimDpt mpp = getMetersPerPixel();
+      ossimDpt pt;
+      pt.x = theCornerEastingNorthingPt[1].x + (mpp.x / 2.0);
+      pt.y = theCornerEastingNorthingPt[1].y + (mpp.y / 2.0);
+      return pt;      
+   }
+   else
+   {
+      return theCornerEastingNorthingPt[1];
+   }
+}
+
+ossimDpt ossimMapProjectionInfo::lrEastingNorthingPt( ) const
+{
+   if (getPixelType() == OSSIM_PIXEL_IS_AREA)
+   {
+      ossimDpt mpp = getMetersPerPixel();
+      ossimDpt pt;
+      pt.x = theCornerEastingNorthingPt[2].x + (mpp.x / 2.0);
+      pt.y = theCornerEastingNorthingPt[2].y - (mpp.y / 2.0);
+      return pt;      
+   }
+   else
+   {
+      return theCornerEastingNorthingPt[2];
+   }
+}
+
+ossimDpt ossimMapProjectionInfo::llEastingNorthingPt( ) const
+{
+   if (getPixelType() == OSSIM_PIXEL_IS_AREA)
+   {
+      ossimDpt mpp = getMetersPerPixel();
+      ossimDpt pt;
+      pt.x = theCornerEastingNorthingPt[3].x - (mpp.x / 2.0);
+      pt.y = theCornerEastingNorthingPt[3].y - (mpp.y / 2.0);
+      return pt;      
+   }
+   else
+   {
+      return theCornerEastingNorthingPt[3];
+   }
+}
+
+ossimGpt ossimMapProjectionInfo::ulGroundPt( ) const
+{
+   if (getPixelType() == OSSIM_PIXEL_IS_AREA)
+   {
+      ossimDpt ddpp = getDecimalDegreesPerPixel();
+      ossimGpt gpt;
+      gpt.latd(theCornerGroundPt[0].latd() + (ddpp.y / 2.0));
+      gpt.lond(theCornerGroundPt[0].lond() - (ddpp.x / 2.0));
+      return gpt;
+   }
+   else
+   {
+      return theCornerGroundPt[0];
+   } 
+}
+
+ossimGpt ossimMapProjectionInfo::urGroundPt( ) const
+{
+   if (getPixelType() == OSSIM_PIXEL_IS_AREA)
+   {
+      ossimDpt ddpp = getDecimalDegreesPerPixel();
+      ossimGpt gpt;
+      gpt.latd(theCornerGroundPt[1].latd() + (ddpp.y / 2.0));
+      gpt.lond(theCornerGroundPt[1].lond() + (ddpp.x / 2.0));
+      return gpt;
+   }
+   else
+   {
+      return theCornerGroundPt[1];
+   }
+}
+
+ossimGpt ossimMapProjectionInfo::lrGroundPt( ) const
+{
+   if (getPixelType() == OSSIM_PIXEL_IS_AREA)
+   {
+      ossimDpt ddpp = getDecimalDegreesPerPixel();
+      ossimGpt gpt;
+      gpt.latd(theCornerGroundPt[2].latd() - (ddpp.y / 2.0));
+      gpt.lond(theCornerGroundPt[2].lond() + (ddpp.x / 2.0));
+      return gpt;
+   }
+   else
+   {
+      return theCornerGroundPt[2];
+   }
+}
+
+ossimGpt ossimMapProjectionInfo::llGroundPt( ) const
+{
+   if (getPixelType() == OSSIM_PIXEL_IS_AREA)
+   {
+      ossimDpt ddpp = getDecimalDegreesPerPixel();
+      ossimGpt gpt;
+      gpt.latd(theCornerGroundPt[3].latd() - (ddpp.y / 2.0));
+      gpt.lond(theCornerGroundPt[3].lond() - (ddpp.x / 2.0));
+      return gpt;
+   }
+   else
+   {
+      return theCornerGroundPt[3];
+   }   
+}
+
+ossimGpt ossimMapProjectionInfo::centerGroundPt( ) const
+{
+   // Center is simply center, no shift for pixel is area...
+   return theCenterGroundPt;
+}
+
+ossimDpt ossimMapProjectionInfo::centerEastingNorthingPt() const
+{
+   return theCenterEastingNorthingPt;
+}
+
+ossim_int32 ossimMapProjectionInfo::linesPerImage() const
+{
+   return theLinesPerImage;
+}
+
+ossim_int32 ossimMapProjectionInfo::pixelsPerLine() const
+{
+   return thePixelsPerLine;
+}
+
+bool ossimMapProjectionInfo::loadState(const ossimKeywordlist& kwl,
+                                       const char* )
+{
+   const char* lookupReturn = kwl.find(README_IMAGE_STRING_KW);
+
+   //***
+   // "theImageInfoString" goes in the README file "Image:" field and can
+   // be used to identify the image.
+   //***
+   if (lookupReturn) theImageInfoString = lookupReturn;
+   
+   lookupReturn = kwl.find(ossimKeywordNames::PIXEL_TYPE_KW);
+
+   if (lookupReturn)
+   {
+      ossimString tmp = lookupReturn;
+
+      tmp.downcase();
+
+      if (tmp.contains("area"))
+      {
+         thePixelType = OSSIM_PIXEL_IS_AREA;
+      }
+      else
+      {
+         thePixelType = OSSIM_PIXEL_IS_POINT;
+      }
+   }
+
+   lookupReturn = kwl.find(OUTPUT_US_FT_INFO_KW);
+
+   if (lookupReturn)
+   {
+      int tmp = atoi(lookupReturn);
+
+      if (tmp)
+      {
+         theOutputInfoInFeetFlag = true;
+      }
+      else
+      {
+         theOutputInfoInFeetFlag = false;
+      }
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimMapProjectionInfo::loadState:"
+         << "\ntheImageInfoString:       " << theImageInfoString
+         << "\nthePixelType:             " << int(thePixelType)
+         << "\ntheOutputInfoInFeetFlag:  " << theOutputInfoInFeetFlag
+         << endl;
+   }
+
+   return true;
+}
+
+bool ossimMapProjectionInfo::saveState(ossimKeywordlist& kwl,
+                                       const char* ) const 
+{
+   kwl.add(README_IMAGE_STRING_KW,
+           theImageInfoString.chars());
+   
+   ossimString tmp;
+   
+   if (thePixelType == OSSIM_PIXEL_IS_POINT)
+   {
+      tmp = "point";
+   }
+   else
+   {
+      tmp = "area";
+   }
+   
+   kwl.add(PIXEL_TYPE_KW,
+           tmp.chars());
+
+   kwl.add(OUTPUT_US_FT_INFO_KW,
+           int(theOutputInfoInFeetFlag));
+   
+   return true;
+}
+
+ossimDpt ossimMapProjectionInfo::ulEastingNorthingPtInFt() const
+{
+   ossimDpt pt = ulEastingNorthingPt();
+   
+   pt.x = mtrs2usft(pt.x);
+   
+   pt.y = mtrs2usft(pt.y);
+   
+   return pt;
+}
+
+ossimDpt ossimMapProjectionInfo::urEastingNorthingPtInFt() const
+{
+   ossimDpt pt = urEastingNorthingPt();
+   pt.x = mtrs2usft(pt.x);
+   pt.y = mtrs2usft(pt.y);
+   return pt;
+}
+
+ossimDpt ossimMapProjectionInfo::lrEastingNorthingPtInFt() const
+{
+   ossimDpt pt = lrEastingNorthingPt();
+   pt.x = mtrs2usft(pt.x);
+   pt.y = mtrs2usft(pt.y);
+   return pt;
+}
+
+ossimDpt ossimMapProjectionInfo::llEastingNorthingPtInFt() const
+{
+   ossimDpt pt = llEastingNorthingPt();
+   pt.x = mtrs2usft(pt.x);
+   pt.y = mtrs2usft(pt.y);
+   return pt;
+}
+
+ossimDpt ossimMapProjectionInfo::getMetersPerPixel() const
+{
+   return theProjection->getMetersPerPixel();
+}
+
+ossimDpt ossimMapProjectionInfo::getUsSurveyFeetPerPixel() const
+{
+   ossimDpt pt = getMetersPerPixel();
+   
+   pt.x = mtrs2usft(pt.x);
+   pt.y = mtrs2usft(pt.y);
+
+   return pt;
+}
+
+ossimDpt ossimMapProjectionInfo::getDecimalDegreesPerPixel() const
+{
+   return theProjection->getDecimalDegreesPerPixel();
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjectionInfo.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjectionInfo.h
new file mode 100644
index 0000000000..719257b3a1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMapProjectionInfo.h
@@ -0,0 +1,277 @@
+//*******************************************************************
+// Copyright (C) 2001 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// Class for encapsulate projection info given a projection, datum, and
+// output rectangle.
+//
+// NOTE:
+// - Output rectangle should be relative to the center of pixels.
+//   Shifts will be made for "pixel is area" internally.
+//
+//*******************************************************************
+//  $Id: ossimMapProjectionInfo.h,v 1.13 2005/10/13 15:04:06 dburken Exp $
+
+#ifndef ossimMapProjectionInfo_HEADER
+#define ossimMapProjectionInfo_HEADER
+
+#include <base/common/ossimObject.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDrect.h>
+
+class ossimMapProjection;
+class ossimFilename;
+class ossimDrect;
+class ossimImageChain;
+
+class OSSIMDLLEXPORT ossimMapProjectionInfo : public ossimObject
+{
+public:
+
+   ossimMapProjectionInfo(const ossimMapProjection* proj,
+                          const ossimDrect& output_rect);
+
+   virtual ~ossimMapProjectionInfo();
+
+   /**
+    *  Returns true on error false if ok.
+    */
+   bool errorStatus() const;
+
+   /**
+    * Adds tie point to keyword list.  This will be latitude, longitude if
+    * projection is geographic; else, easting, northing.
+    */
+   void getGeom(ossimKeywordlist& kwl, const char* prefix=NULL)const;
+
+   /**
+    *  Returns the pixel size in meters.
+    *  x = sample direction
+    *  y = line direction
+    */
+   ossimDpt getMetersPerPixel() const;
+   
+   /**
+    *  Returns the pixel size in U.S. Survey feet.
+    *  x = sample direction
+    *  y = line direction
+    *
+    *  NOTE:
+    *  The US survey feet per meter converion (0.3048006096 feet per meter)
+    *  is NOT the same as the standard feet per meter conversion
+    *  (0.3048 feet per meter).
+    */
+   ossimDpt getUsSurveyFeetPerPixel() const;
+
+   /**
+    *  Returns the decimal degrees per pixel.
+    *  x = sample direction
+    *  y = line direction
+    */
+   ossimDpt getDecimalDegreesPerPixel() const;
+   
+   /**
+    *  Returns the upper left easting and northing as a ossimDpt.
+    *  The easting is "u" and the northing is "v". Units are in meters.
+    */
+   ossimDpt ulEastingNorthingPt() const;
+
+   /**
+    *  Returns the upper right easting and northing as a ossimDpt.
+    *  The easting is "u" and the northing is "v". Units are in meters.
+    */
+   ossimDpt urEastingNorthingPt() const;
+
+   /**
+    *  Returns the lower right easting and northing as a ossimDpt.
+    *  The easting is "u" and the northing is "v". Units are in meters.
+    */
+   ossimDpt lrEastingNorthingPt() const;
+
+   /**
+    *  Returns the lower left easting and northing as a ossimDpt.
+    *  The easting is "u" and the northing is "v". Units are in meters.
+    */
+   ossimDpt llEastingNorthingPt() const;
+   
+   /**
+    *  Returns the upper left easting and northing as a ossimDpt.
+    *  The easting is "u" and the northing is "v".
+    *  Units are in U.S. Survey feet.
+    */
+   ossimDpt ulEastingNorthingPtInFt() const;
+
+   /**
+    *  Returns the upper right easting and northing as a ossimDpt.
+    *  The easting is "u" and the northing is "v".
+    *  Units are in U.S. Survey feet.
+    */
+   ossimDpt urEastingNorthingPtInFt() const;
+
+   /**
+    *  Returns the lower right easting and northing as a ossimDpt.
+    *  The easting is "u" and the northing is "v".
+    *  Units are in U.S. Survey feet.
+    */
+   ossimDpt lrEastingNorthingPtInFt() const;
+
+   /**
+    *  Returns the lower left easting and northing as a ossimDpt.
+    *  The easting is "u" and the northing is "v". 
+    *  Units are in U.S. Survey feet.
+    */
+   ossimDpt llEastingNorthingPtInFt() const;
+   
+   /**
+    * Returns the upper left ground point.
+    */
+   ossimGpt ulGroundPt() const;
+
+   /**
+    * Returns the upper right ground point.
+    */
+   ossimGpt urGroundPt() const;
+
+   /**
+    * Returns the lower right ground point.
+    */
+   ossimGpt lrGroundPt() const;
+ 
+   /**
+    * Returns the lower left ground point.
+    */
+   ossimGpt llGroundPt() const;
+
+   /**
+    * Returns the center ground point.
+    */
+   ossimGpt centerGroundPt() const;
+
+   /** @return The center ground point. */
+   ossimDpt centerEastingNorthingPt() const;
+
+   /** @return The lines per image. */
+   ossim_int32 linesPerImage() const;
+
+   /** @return The pixels per line (samples). */
+   ossim_int32 pixelsPerLine() const;
+
+   /**
+    * Formatted print of data members.  Used by operator <<.
+    */
+   std::ostream& print(std::ostream& os) const;
+
+   /**
+    *  Sets the data member "thePixelType".
+    *  NOTE:
+    *  PIXEL_IS_POINT (ennumerated to a "0"):
+    *  Corner coordinates are relative to the center of pixel.
+    *  PIXEL_IS_AREA (ennumerated to a "1"):
+    *  Corner coordinates are relative to the outer edge of the pixel.
+    */
+   void setPixelType (ossimPixelType type);
+
+   /**
+    *  Returns data member "thePixelType".
+    *  NOTE:
+    *  OSSIM_PIXEL_IS_POINT (ennumerated to a "0"):
+    *  Corner coordinates are relative to the center of pixel.
+    *  OSSIM_PIXEL_IS_AREA (ennumerated to a "1"):
+    *  Corner coordinates are relative to the outer of the pixel.
+    */
+   ossimPixelType  getPixelType () const;
+
+   /**
+    * Sets the data member "theOutputInfoInFeetFlag".
+    */
+   void setOutputFeetFlag (bool flag);
+
+   /**
+    *  Returns the data member "theOutputInfoInFeetFlag".
+    *  True = feet, false = meters.
+    */
+   bool unitsInFeet() const;
+
+   /**
+    * Returns theImageInfoString.
+    */
+   ossimString getImageInfoString () const;
+
+   /**
+    *  Used to set data member "theImageInfoString".  This will be output
+    *  in the "Image: " field of the README file.
+    */
+   void setImageInfoString (const ossimString& string);
+
+   /**
+    * Returns reference to "theProjection".
+    */
+   const ossimMapProjection* getProjection() const;
+
+   //****
+   // Keywords for getStateFrom/saveStateTo.
+   //***
+   static const char* README_IMAGE_STRING_KW;
+   static const char* PIXEL_TYPE_KW;
+   static const char* OUTPUT_US_FT_INFO_KW;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = 0);
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = 0) const;
+   
+private:
+
+   // Do not permit construction with void args.
+   ossimMapProjectionInfo();
+   ossimMapProjectionInfo& operator=(const ossimMapProjectionInfo&);
+   
+   void initializeMembers(const ossimDrect& output_rect);
+   
+   const ossimMapProjection* theProjection;
+   mutable bool              theErrorStatus;
+   int                       theLinesPerImage;
+   int                       thePixelsPerLine;
+   ossimGpt                  theCornerGroundPt[4];
+   ossimDpt                  theCornerEastingNorthingPt[4];
+   ossimGpt                  theCenterGroundPt;
+   ossimDpt                  theCenterEastingNorthingPt;
+   ossimDrect                theBoundingRect;
+   
+   /**
+    *   "thePixelType" defines whether the tie point coordinates are
+    *   relative to the center of the pixel(which is PIXEL_IS_POINT) or
+    *   the upper left corner of the pixel(PIXEL_IS_AREA).  The default
+    *   pixle type is PIXEL_IS_POINT.
+    */
+   ossimPixelType                 thePixelType;
+
+   /**
+    *   If "theOutputInfoInFeetFlag" is true the readme file tie point
+    *   info will be output in both meters and U.S. feet.
+    *   NOTE:
+    *   U.S. feet conversion is "meters/0.3048006096" not the standard
+    *   "meters/0.3048".
+    *   Reference for U.S. feet value:
+    *   U.S.G.S. "Map Projections - A Working Manual" USGS Professional
+    *   paper 1395 page 51.
+    */
+   bool                      theOutputInfoInFeetFlag;
+
+   /**
+    *   "theImageInfoString" goes in the README file "Image:" field
+    *   to identify the image.
+    */
+   ossimString               theImageInfoString;
+};
+
+#endif /* End of #ifndef ossimMapProjectionInfo_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMercatorProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMercatorProjection.cpp
new file mode 100644
index 0000000000..8d4c09a8d2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMercatorProjection.cpp
@@ -0,0 +1,462 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Mercator projection code.  
+//*******************************************************************
+//  $Id: ossimMercatorProjection.cpp,v 1.10 2004/01/08 21:49:21 jlargent Exp $
+
+#include <math.h>
+#include "ossimMercatorProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimMercatorProjection, "ossimMercatorProjection", ossimMapProjection)
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+
+#define PI         3.14159265358979323e0  /* PI                            */
+#define PI_OVER_2  ( PI / 2.0e0)  
+#define MAX_LAT    ( (PI * 89.5) / 180.0 )  /* 89.5 degrees in radians         */
+
+#define MERC_NO_ERROR           0x0000
+#define MERC_LAT_ERROR          0x0001
+#define MERC_LON_ERROR          0x0002
+#define MERC_EASTING_ERROR      0x0004
+#define MERC_NORTHING_ERROR     0x0008
+#define MERC_ORIGIN_LAT_ERROR   0x0010
+#define MERC_CENT_MER_ERROR     0x0020
+#define MERC_A_ERROR            0x0040
+#define MERC_B_ERROR            0x0080
+#define MERC_A_LESS_B_ERROR     0x0100
+
+ossimMercatorProjection::ossimMercatorProjection(const ossimEllipsoid& ellipsoid,
+                                                 const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimMercatorProjection::ossimMercatorProjection(const ossimEllipsoid& ellipsoid,
+                                                 const ossimGpt& origin,
+                                                 double falseEasting,
+                                                 double falseNorthing,
+                                                 double scaleFactor)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Merc_False_Easting  = falseEasting;
+   Merc_False_Northing = falseNorthing;
+   Merc_Scale_Factor   = scaleFactor;
+   Merc_Delta_Easting  = 20237883.0;
+   Merc_Delta_Northing = 23421740.0;
+
+   update();
+}
+
+void ossimMercatorProjection::update()
+{
+   
+   Set_Mercator_Parameters(theEllipsoid.getA(),
+                           theEllipsoid.getFlattening(),
+                           theOrigin.latr(),
+                           theOrigin.lonr(),
+                           Merc_False_Easting,
+                           Merc_False_Northing,
+                           &Merc_Scale_Factor);
+
+   ossimMapProjection::update();
+}
+
+void ossimMercatorProjection::setFalseEasting(double falseEasting)
+{
+   Merc_False_Easting = falseEasting;
+   update();
+}
+
+void ossimMercatorProjection::setFalseNorthing(double falseNorthing)
+{
+   Merc_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimMercatorProjection::setScaleFactor(double scaleFactor)
+{
+   Merc_Scale_Factor = scaleFactor;
+   update();
+}
+
+void ossimMercatorProjection::setFalseEastingNorthing(double falseEasting,
+                                                      double falseNorthing)
+{
+   Merc_False_Easting = falseEasting;
+   Merc_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimMercatorProjection::setParameters(double falseEasting,
+                                            double falseNorthing,
+                                            double scaleFactor)
+{
+   Merc_False_Easting  = falseEasting;
+   Merc_False_Northing = falseNorthing;
+   Merc_Scale_Factor   = scaleFactor;
+   
+   update(); 
+}
+
+void ossimMercatorProjection::setDefaults()
+{
+   Merc_Delta_Easting  = 20237883.0;
+   Merc_Delta_Northing = 23421740.0;
+   Merc_Scale_Factor   = 1.0;
+}
+
+ossimGpt ossimMercatorProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Mercator_To_Geodetic(eastingNorthing.x,
+                                eastingNorthing.y,
+                                &lat,
+                                &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimMercatorProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+   
+   Convert_Geodetic_To_Mercator(gpt.latr(),
+                                gpt.lonr(),
+                                &easting,
+                                &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+
+bool ossimMercatorProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Merc_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Merc_False_Northing,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_FACTOR_KW,
+           Merc_Scale_Factor,
+           true);
+
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimMercatorProjection::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   const char* scaleFactor   = kwl.find(prefix, ossimKeywordNames::SCALE_FACTOR_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimMercatorProjection))
+   {
+      if(falseEasting)
+      {
+         Merc_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Merc_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+      if(scaleFactor)
+      {
+         Merc_Scale_Factor = ossimString(scaleFactor).toDouble();
+      }
+   }
+   update();
+   
+   return flag;
+}
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+long ossimMercatorProjection::Set_Mercator_Parameters(double a,      
+                                                      double f,
+                                                      double Origin_Latitude,
+                                                      double Central_Meridian,
+                                                      double False_Easting,
+                                                      double False_Northing,
+                                                      double *Scale_Factor)
+{ /* BEGIN Set_Mercator_Parameters */
+/*
+ * The function Set_Mercator_Parameters receives the ellipsoid parameters and
+ * Mercator projection parameters as inputs, and sets the corresponding state 
+ * variables.  It calculates and returns the scale factor.  If any errors
+ * occur, the error code(s) are returned by the function, otherwise Merc_NO_ERROR
+ * is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ *    Scale_Factor      : Multiplier which reduces distances in the 
+ *                          projection to the actual distance on the
+ *                          ellipsoid                               (output)
+ */
+
+  double es2;   /* Eccentricity squared of ellipsoid to the second power    */
+  double es3;   /* Eccentricity squared of ellipsoid to the third power     */
+  double es4;   /* Eccentricity squared of ellipsoid to the fourth power    */
+  double sin_olat; /* sin(Origin_Latitude), temp variable */
+//  double inv_f = 1 / f;
+  long Error_Code = MERC_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= MERC_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= MERC_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -MAX_LAT) || (Origin_Latitude > MAX_LAT))
+//   { /* origin latitude out of range */
+//     Error_Code |= MERC_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > (2*PI)))
+//   { /* origin longitude out of range */
+//     Error_Code |= MERC_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Merc_a = a;
+    Merc_f = f;
+    Merc_Origin_Lat = Origin_Latitude;
+//     if (Central_Meridian > PI)
+//       Central_Meridian -= (2*PI);
+    Merc_Origin_Long = Central_Meridian;
+    Merc_False_Northing = False_Northing;
+    Merc_False_Easting = False_Easting;
+    Merc_es = 2 * Merc_f - Merc_f * Merc_f;
+    Merc_e = sqrt(Merc_es);
+    sin_olat = sin(Origin_Latitude);
+    Merc_Scale_Factor = 1.0 / ( sqrt(1.e0 - Merc_es * sin_olat * sin_olat) 
+                                / cos(Origin_Latitude) );
+    es2 = Merc_es * Merc_es;
+    es3 = es2 * Merc_es;
+    es4 = es3 * Merc_es;
+    Merc_ab = Merc_es / 2.e0 + 5.e0 * es2 / 24.e0 + es3 / 12.e0
+              + 13.e0 * es4 / 360.e0;
+    Merc_bb = 7.e0 * es2 / 48.e0 + 29.e0 * es3 / 240.e0 
+              + 811.e0 * es4 / 11520.e0;
+    Merc_cb = 7.e0 * es3 / 120.e0 + 81.e0 * es4 / 1120.e0;
+    Merc_db = 4279.e0 * es4 / 161280.e0;
+    *Scale_Factor = Merc_Scale_Factor;
+    Convert_Geodetic_To_Mercator( MAX_LAT, (Merc_Origin_Long + PI),                                           
+                                  &Merc_Delta_Easting, &Merc_Delta_Northing);
+    if (Merc_Delta_Easting < 0)
+      Merc_Delta_Easting = -Merc_Delta_Easting;
+    Merc_Delta_Easting *= 1.01;
+    Merc_Delta_Easting -= Merc_False_Easting;
+    Merc_Delta_Northing *= 1.01;
+    Merc_Delta_Northing -= Merc_False_Northing;
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+} /* END OF Set_Mercator_Parameters */
+
+
+void ossimMercatorProjection::Get_Mercator_Parameters(double *a,
+                                                      double *f,
+                                                      double *Origin_Latitude,
+                                                      double *Central_Meridian,
+                                                      double *False_Easting,
+                                                      double *False_Northing,
+                                                      double *Scale_Factor)const
+{ /* BEGIN Get_Mercator_Parameters */
+/*
+ * The function Get_Mercator_Parameters returns the current ellipsoid
+ * parameters, Mercator projection parameters, and scale factor.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ *    Scale_Factor      : Multiplier which reduces distances in the 
+ *                          projection to the actual distance on the
+ *                          ellipsoid                               (output)
+ */
+
+  *a = Merc_a;
+  *f = Merc_f;
+  *Origin_Latitude = Merc_Origin_Lat;
+  *Central_Meridian = Merc_Origin_Long;
+  *False_Easting = Merc_False_Easting;
+  *False_Northing = Merc_False_Northing;
+  *Scale_Factor = Merc_Scale_Factor;
+  
+  return;
+} /* END OF Get_Mercator_Parameters */
+
+
+long ossimMercatorProjection::Convert_Geodetic_To_Mercator (double Latitude,
+                                                            double Longitude,
+                                                            double *Easting,
+                                                            double *Northing)const
+{ /* BEGIN Convert_Geodetic_To_Mercator */
+/*
+ * The function Convert_Geodetic_To_Mercator converts geodetic (latitude and
+ * longitude) coordinates to Mercator projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Mercator projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MERC_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double ctanz2;        /* Cotangent of z/2 - z - Isometric colatitude     */
+  double e_x_sinlat;    /* e * sin(Latitude)                               */
+  double Delta_Long;    /* Difference in origin longitude and longitude    */
+  double tan_temp;
+  double pow_temp;
+
+  long Error_Code = MERC_NO_ERROR;
+
+//   if ((Latitude < -MAX_LAT) || (Latitude > MAX_LAT))
+//   { /* Latitude out of range */
+//     Error_Code |= MERC_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > (2*PI)))
+//   { /* Longitude out of range */
+//     Error_Code |= MERC_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    if (Longitude > PI)
+      Longitude -= (2*PI);
+    e_x_sinlat = Merc_e * sin(Latitude);
+    tan_temp = tan(PI / 4.e0 + Latitude / 2.e0);
+    pow_temp = pow( ((1.e0 - e_x_sinlat) / (1.e0 + e_x_sinlat)),
+                    (Merc_e / 2.e0) );
+    ctanz2 = tan_temp * pow_temp;
+    *Northing = Merc_Scale_Factor * Merc_a * log(ctanz2) + Merc_False_Northing;
+    Delta_Long = Longitude - Merc_Origin_Long;
+//     if (Delta_Long > PI)
+//       Delta_Long -= (2 * PI);
+//     if (Delta_Long < -PI)
+//       Delta_Long += (2 * PI);
+    *Easting = Merc_Scale_Factor * Merc_a * Delta_Long
+               + Merc_False_Easting;
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Mercator */
+
+
+long ossimMercatorProjection::Convert_Mercator_To_Geodetic(double Easting,
+                                                           double Northing,
+                                                           double *Latitude,
+                                                           double *Longitude)const
+{ /* BEGIN Convert_Mercator_To_Geodetic */
+/*
+ * The function Convert_Mercator_To_Geodetic converts Mercator projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Mercator projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MERC_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx;     /* Delta easting - Difference in easting (easting-FE)      */
+  double dy;     /* Delta northing - Difference in northing (northing-FN)   */
+  double xphi;   /* Isometric latitude                                      */
+  long Error_Code = MERC_NO_ERROR;
+
+//   if ((Easting < (Merc_False_Easting - Merc_Delta_Easting))
+//       || (Easting > (Merc_False_Easting + Merc_Delta_Easting)))
+//   { /* Easting out of range */
+//     Error_Code |= MERC_EASTING_ERROR;
+//   }
+//   if ((Northing < (Merc_False_Northing - Merc_Delta_Northing))
+//       || (Northing > (Merc_False_Northing + Merc_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= MERC_NORTHING_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dy = Northing - Merc_False_Northing;
+    dx = Easting - Merc_False_Easting;
+    *Longitude = Merc_Origin_Long + dx / (Merc_Scale_Factor * Merc_a);
+    xphi = PI / 2.e0 
+           - 2.e0 * atan(1.e0 / exp(dy / (Merc_Scale_Factor * Merc_a)));
+    *Latitude = xphi + Merc_ab * sin(2.e0 * xphi) + Merc_bb * sin(4.e0 * xphi)
+                + Merc_cb * sin(6.e0 * xphi) + Merc_db * sin(8.e0 * xphi);
+//     if (*Longitude > PI)
+//       *Longitude -= (2 * PI);
+//     if (*Longitude < -PI)
+//       *Longitude += (2 * PI);
+  }
+  return (Error_Code);
+} /* END OF Convert_Mercator_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMercatorProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMercatorProjection.h
new file mode 100644
index 0000000000..b702ff257c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMercatorProjection.h
@@ -0,0 +1,224 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Mercator projection code.  
+//*******************************************************************
+//  $Id: ossimMercatorProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimMercatorProjection_HEADER
+#define ossimMercatorProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimMercatorProjection : public ossimMapProjection
+{
+public:
+   
+   ossimMercatorProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                           const ossimGpt& origin = ossimGpt());
+   
+   ossimMercatorProjection(const ossimEllipsoid& ellipsoid,
+                           const ossimGpt& origin,
+                           double falseEasting,
+                           double falseNorthing,
+                           double scaleFactor);
+   ~ossimMercatorProjection(){}
+   virtual ossimObject *dup()const{return new ossimMercatorProjection(*this);}
+
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();   
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   /*!
+    * sets the scale.
+    */
+   void setScaleFactor(double scaleFactor);
+
+   /*!
+    * Allows one to set all parameters for this projections.  parallels are in
+    * degrees and easting northings are in meters.
+    * Update is then called so we can pre-compute paramters.
+    */
+   void setParameters(double falseEasting,
+                      double falseNorthing,
+                      double scaleFactor);  
+   void setDefaults();
+   
+   double getFalseEasting()const{return Merc_False_Easting;}
+   double getFalseNorthing()const{return Merc_False_Northing;}
+   double getScaleFactor()const{return Merc_Scale_Factor;}
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+   //_________________GEOTRANS STUFF____________________________
+
+   mutable double Merc_a;    /* Semi-major axis of ellipsoid in meters */
+   mutable double Merc_f;      /* Flattening of ellipsoid */
+   mutable double Merc_e; /* Eccentricity of ellipsoid    */
+   mutable double Merc_es; /* Eccentricity squared         */
+   
+/* Mercator projection Parameters */
+   mutable double Merc_Origin_Lat;      /* Latitude of origin in radians     */
+   mutable double Merc_Origin_Long;     /* Longitude of origin in radians    */
+   mutable double Merc_False_Northing;  /* False northing in meters          */
+   mutable double Merc_False_Easting;   /* False easting in meters           */
+   mutable double Merc_Scale_Factor;    /* Scale factor                      */
+   
+/* Isometric to geodetic latitude parameters, default to WGS 84 */
+   mutable double Merc_ab;
+   mutable double Merc_bb;
+   mutable double Merc_cb;
+   mutable double Merc_db;
+   
+/* Maximum variance for easting and northing values for WGS 84.
+ */
+   mutable double Merc_Delta_Easting;
+   mutable double Merc_Delta_Northing;
+   
+
+/*!
+ * The function Set_Mercator_Parameters receives the ellipsoid parameters and
+ * Mercator projcetion parameters as inputs, and sets the corresponding state 
+ * variables.  It calculates and returns the scale factor.  If any errors
+ * occur, the error code(s) are returned by the function, otherwise 
+ * MERC_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ *    Scale_Factor      : Multiplier which reduces distances in the 
+ *                          projection to the actual distance on the
+ *                          ellipsoid                               (output)
+ */
+  long Set_Mercator_Parameters(double a,      
+                               double f,
+                               double Origin_Latitude,
+                               double Central_Meridian,
+                               double False_Easting,
+                               double False_Northing,
+                               double *Scale_Factor);
+
+
+/*!
+ * The function Get_Mercator_Parameters returns the current ellipsoid
+ * parameters, Mercator projection parameters, and scale factor.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ *    Scale_Factor      : Multiplier which reduces distances in the 
+ *                          projection to the actual distance on the
+ *                          ellipsoid                               (output)
+ */
+  void Get_Mercator_Parameters(double *a,
+                               double *f,
+                               double *Origin_Latitude,
+                               double *Central_Meridian,
+                               double *False_Easting,
+                               double *False_Northing,
+                               double *Scale_Factor)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Mercator converts geodetic (latitude and
+ * longitude) coordinates to Mercator projection easting, and northing
+ * coordinates, according to the current ellipsoid and Mercator projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MERC_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Mercator (double Latitude,
+                                     double Longitude,
+                                     double *Easting,
+                                     double *Northing)const;
+
+
+/*!
+ * The function Convert_Mercator_To_Geodetic converts Mercator projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Mercator projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MERC_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Mercator_To_Geodetic(double Easting,
+                                    double Northing,
+                                    double *Latitude,
+                                    double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMgrs.c b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMgrs.c
new file mode 100644
index 0000000000..6516908346
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMgrs.c
@@ -0,0 +1,1325 @@
+/***************************************************************************/
+/* RSC IDENTIFIER:  MGRS
+ *
+ * ABSTRACT
+ *
+ *    This component converts between geodetic coordinates (latitude and 
+ *    longitude) and Military Grid Reference System (MGRS) coordinates. 
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *          MGRS_NO_ERROR          : No errors occurred in function
+ *          MGRS_LAT_ERROR         : Latitude outside of valid range 
+ *                                    (-90 to 90 degrees)
+ *          MGRS_LON_ERROR         : Longitude outside of valid range
+ *                                    (-180 to 360 degrees)
+ *          MGRS_STR_ERROR         : An MGRS string error: string too long,
+ *                                    too short, or badly formed
+ *          MGRS_PRECISION_ERROR   : The precision must be between 0 and 5 
+ *                                    inclusive.
+ *          MGRS_A_ERROR           : Semi-major axis less than or equal to zero
+ *          MGRS_INV_F_ERROR       : Inverse flattening outside of valid range
+ *									                  (250 to 350)
+ *          MGRS_EASTING_ERROR     : Easting outside of valid range
+ *                                    (100,000 to 900,000 meters for UTM)
+ *                                    (0 to 4,000,000 meters for UPS)
+ *          MGRS_NORTHING_ERROR    : Northing outside of valid range
+ *                                    (0 to 10,000,000 meters for UTM)
+ *                                    (0 to 4,000,000 meters for UPS)
+ *          MGRS_ZONE_ERROR        : Zone outside of valid range (1 to 60)
+ *          MGRS_HEMISPHERE_ERROR  : Invalid hemisphere ('N' or 'S')
+ *
+ * REUSE NOTES
+ *
+ *    MGRS is intended for reuse by any application that does conversions
+ *    between geodetic coordinates and MGRS coordinates.
+ *
+ * REFERENCES
+ *
+ *    Further information on MGRS can be found in the Reuse Manual.
+ *
+ *    MGRS originated from : U.S. Army Topographic Engineering Center
+ *                           Geospatial Information Division
+ *                           7701 Telegraph Road
+ *                           Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *
+ * ENVIRONMENT
+ *
+ *    MGRS was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC version 2.8.1
+ *    2. Windows 95 with MS Visual C++ version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    16-11-94          Original Code
+ *    15-09-99          Reengineered upper layers
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                               INCLUDES
+ */
+#include <ctype.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include "ossimUps.h"
+#include "ossimUtm.h"
+#include "ossimMgrs.h"
+
+/*
+ *      ctype.h     - Standard C character handling library
+ *      math.h      - Standard C math library
+ *      stdio.h     - Standard C input/output library
+ *      string.h    - Standard C string handling library
+ *      ups.h       - Universal Polar Stereographic (UPS) projection
+ *      utm.h       - Universal Transverse Mercator (UTM) projection
+ *      mgrs.h      - function prototype error checking
+ */
+
+
+/***************************************************************************/
+/*
+ *                              GLOBAL DECLARATIONS
+ */
+#define DEGRAD       0.017453292519943295 /* PI/180                          */
+#define R3           0.052359877559829890 /* RADIANS FOR  3 DEGREES          */ 
+#define R8           0.139626340159546400 /* RADIANS FOR  8 DEGREES          */
+#define R9           0.157079632679489700 /* RADIANS FOR  9 DEGREES          */
+#define R21          0.366519142918809200 /* RADIANS FOR  21 DEGREES         */
+#define R33          0.575958653158128800 /* RADIANS FOR  33 DEGREES         */
+#define R56          0.977384381116824600 /* RADIANS FOR  56 DEGREES         */
+#define R64          1.117010721276371000 /* RADIANS FOR  64 DEGREES         */
+#define R72          1.256637061435917000 /* RADIANS FOR  72 DEGREES         */
+#define R80          1.396263401595464000 /* RADIANS FOR  80 DEGREES         */
+#define UPS_SOUTH              3    /* UPS COORDINATE IN SOUTHERN HEMISPHERE */
+#define UPS_NORTH              2    /* UPS COORDINATE IN NORTHERN HEMISPHERE */ 
+#define UTM                    1    /* UTM COORDINATE                        */ 
+#define ALBET                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* ALPHABET       */
+#define LETTER_A               0   /* ARRAY INDEX FOR LETTER A               */
+#define LETTER_B               1   /* ARRAY INDEX FOR LETTER B               */
+#define LETTER_C               2   /* ARRAY INDEX FOR LETTER C               */
+#define LETTER_D               3   /* ARRAY INDEX FOR LETTER D               */
+#define LETTER_E               4   /* ARRAY INDEX FOR LETTER E               */
+#define LETTER_H               7   /* ARRAY INDEX FOR LETTER H               */
+#define LETTER_I               8   /* ARRAY INDEX FOR LETTER I               */
+#define LETTER_J               9   /* ARRAY INDEX FOR LETTER J               */
+#define LETTER_L              11   /* ARRAY INDEX FOR LETTER L               */
+#define LETTER_M              12   /* ARRAY INDEX FOR LETTER M               */
+#define LETTER_N              13   /* ARRAY INDEX FOR LETTER N               */
+#define LETTER_O              14   /* ARRAY INDEX FOR LETTER O               */
+#define LETTER_P              15   /* ARRAY INDEX FOR LETTER P               */
+#define LETTER_Q              16   /* ARRAY INDEX FOR LETTER Q               */
+#define LETTER_R              17   /* ARRAY INDEX FOR LETTER R               */
+#define LETTER_S              18   /* ARRAY INDEX FOR LETTER S               */
+#define LETTER_U              20   /* ARRAY INDEX FOR LETTER U               */
+#define LETTER_V              21   /* ARRAY INDEX FOR LETTER V               */
+#define LETTER_W              22   /* ARRAY INDEX FOR LETTER W               */
+#define LETTER_X              23   /* ARRAY INDEX FOR LETTER X               */
+#define LETTER_Y              24   /* ARRAY INDEX FOR LETTER Y               */
+#define LETTER_Z              25   /* ARRAY INDEX FOR LETTER Z               */
+#define RND1                  0.1e0  /* ROUND TO NEAREST .1            */
+#define RND5                  0.5e0  /* ROUND TO NEAREST .5            */
+#define EOLN                   '\0'  /* END OF STRING CHARACTER        */
+#define BLANK                   ' '  /* BLANK CHARACTER                */
+#define OSSIM_MGRS_LETTERS            3  /* NUMBER OF LETTERS IN MGRS              */
+#define NUM_OFFSET             48  /* USED TO CONVERT NUMBERS TO LETTERS     */
+#define ONEHT          100000.e0    /* ONE HUNDRED THOUSAND                  */
+#define TWOMIL        2000000.e0    /* TWO MILLION                           */
+#define EIGHT          800000.e0    /* EIGHT HUNDRED THOUSAND                */
+#define ONE3HT        1300000.e0    /* ONE MILLION THREE HUNDRED THOUSAND    */
+#define ZERO                   0.e0  /* ZERO                           */
+#define TEN                10.e0    /* TEN                                   */
+#define TRUE                      1  /* CONSTANT VALUE FOR TRUE VALUE  */
+#define FALSE                     0  /* CONSTANT VALUE FOR FALSE VALUE */
+#define PI    3.14159265358979323e0  /* PI                             */
+#define PI_OVER_2  (PI / 2.0e0)
+#define NUM                   "01234567890"                /* NUMBERS        */
+#define MAXALBET              25   /* LAST INDEX IN ALPHABET ARRAY(0-25)     */
+#define MAXNUMBER             10   /* LAST INDEX IN NUMBER ARRAY(0-9)        */
+#define OSSIM_MGRS_ZONE_AND_LETTERS   5  /* NUM. OF CHARS. IN ZONE AND LETTERS     */
+#define OSSIM_MGRS_MINIMUM            9  /* MINIMUM NUMBER OF CHARS FOR MGRS       */
+#define OSSIM_MGRS_MAXIMUM           15  /* MAXIMUM NUMBER OF CHARS FOR MGRS       */
+
+#define MIN_EASTING  100000
+#define MAX_EASTING  900000
+#define MIN_NORTHING 0
+#define MAX_NORTHING 10000000
+#define MAX_PRECISION           5   /* Maximum precision of easting & northing */
+#define MIN_UTM_LAT      ( (-80 * PI) / 180.0 ) /* -80 degrees in radians    */
+#define MAX_UTM_LAT      ( (84 * PI) / 180.0 )  /* 84 degrees in radians     */
+
+#define MIN_EAST_NORTH 0
+#define MAX_EAST_NORTH 4000000
+
+/* Ellipsoid parameters, default to WGS 84 */
+double OSSIM_MGRS_a = 6378137.0;    /* Semi-major axis of ellipsoid in meters */
+double OSSIM_MGRS_f = 1 / 298.257223563; /* Flattening of ellipsoid           */
+double OSSIM_MGRS_recpf = 298.257223563;
+char   OSSIM_MGRS_Ellipsoid_Code[3] = {'W','E',0};
+
+const char* OSSIM_CLARKE_1866 = "CC";
+const char* OSSIM_CLARKE_1880 = "CD";
+const char* OSSIM_BESSEL_1841 = "BR";
+/* 
+ *    OSSIM_CLARKE_1866 : Ellipsoid code for OSSIM_CLARKE_1866
+ *    OSSIM_CLARKE_1880 : Ellipsoid code for OSSIM_CLARKE_1880
+ *    OSSIM_BESSEL_1841 : Ellipsoid code for OSSIM_BESSEL_1841
+ */
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+void UTMSET (long izone, 
+             long* ltrlow, 
+             long* ltrhi, 
+             double *fnltr)
+{ /* BEGIN UTMSET */
+  /*
+   *    izone  : Zone number
+   *    ltrlow : 2nd letter low number
+   *    ltrhi  : 2nd letter high number
+   *    fnltr  : False northing
+   */
+  long iset;      /* Set number (1-6) based on UTM zone number           */
+  long igroup;    /* Group number (1-2) based on ellipsoid code and zone */
+  iset = 1;
+  while (((izone-iset) / 6) * 6 + iset != izone)
+  {
+    iset = iset +1;
+    if (iset > 6)
+    {
+      return;
+    }
+  } 
+  igroup = 1;
+  if (!strcmp(OSSIM_MGRS_Ellipsoid_Code,OSSIM_CLARKE_1866) || !strcmp(OSSIM_MGRS_Ellipsoid_Code, OSSIM_CLARKE_1880) || !strcmp(OSSIM_MGRS_Ellipsoid_Code,OSSIM_BESSEL_1841))
+  {
+    igroup = 2;
+  }
+  else if (!strcmp(OSSIM_MGRS_Ellipsoid_Code, OSSIM_CLARKE_1866) && (izone >= 47) && (izone <= 55 ))
+  {
+    igroup = 1;
+  }
+  if ((iset == 1) || (iset == 4))
+  {
+    *ltrlow = LETTER_A;
+    *ltrhi = LETTER_H;
+  }
+  else if ((iset == 2) || (iset == 5))
+  {
+    *ltrlow = LETTER_J;
+    *ltrhi = LETTER_R;
+  }
+  else if ((iset == 3) || (iset == 6))
+  {
+    *ltrlow = LETTER_S;
+    *ltrhi = LETTER_Z;
+  }
+  if (igroup == 1)
+  {
+    *fnltr = ZERO;
+    if ((iset % 2) ==  0)
+    {
+      *fnltr = 1500000.e0;
+    }
+  }
+  else if (igroup == 2)
+  {
+    *fnltr = 1000000.0e0;
+    if ((iset % 2) == 0)
+    {
+      *fnltr =  500000.e0;
+    }
+  }
+  return;
+} /* END OF UTMSET */
+
+
+void UTMLIM (long* n, 
+             double sphi, 
+             long izone, 
+             double *spsou, 
+             double *spnor,
+             double *sleast, 
+             double *slwest)
+{                          /* BEGIN UTMLIM */
+  /*
+   *    n      : 1st letter number for MGRS
+   *    sphi   : Latitude in radians
+   *    izone  : Zone number 
+   *    spsou  : South latitude limit
+   *    spnor  : North latitude limit
+   *    sleast : East longitude limit 
+   *    slwest : West longitude limit 
+   */
+  double slcm;     /* Central meridian - Longitude of origin              */
+  double temp;     /* Temporary variable                                  */
+  long icm;        /* Central meridian                                    */
+  long isphi;      /* South latitude limit                                */
+  if (*n <= LETTER_A)
+  {
+    temp = ((sphi + R80) / (R8)) + 2;
+    temp = temp + .00000001;
+    *n = (long)temp;
+    if (*n > LETTER_H)
+    {
+      *n = *n + 1;
+    }
+    if (*n > LETTER_N)
+    {
+      *n = *n + 1;
+    }
+    if (*n >= LETTER_Y)
+    {
+      *n = LETTER_X;
+    }
+    if ((*n  ==  LETTER_M) && (sphi  ==  ZERO ))
+    {
+      *n = LETTER_N;
+    }
+    isphi = (*n - 3) * 8 - 80;
+  }
+  else
+  {
+    isphi = (*n - 3) * 8 - 80;
+    *n = *n - 1;    
+  }
+  if (*n > LETTER_H)
+  {
+    isphi = isphi - 8;
+  }
+  if (*n > LETTER_N)
+  {
+    isphi = isphi - 8;
+  }
+  *spsou = (double)(isphi) * DEGRAD;
+  *spnor = *spsou + R8;
+  if (*n == LETTER_X)
+  {
+    *spnor = *spsou + 12.e0 * DEGRAD;
+  }
+  icm = izone * 6 - 183;
+  slcm = (double) icm * DEGRAD;
+  *sleast = slcm + R3;
+  *slwest = slcm - R3;
+  if ((izone < 31) || (izone > 37))
+  {
+    return;
+  }
+  if (*n < LETTER_V)
+  {
+    return;
+  }
+  if ((*n == LETTER_V) && (izone == 31))
+  {
+    *sleast = R3;
+  }
+  if ((*n == LETTER_V) && (izone == 32))
+  {
+    *slwest = R3;
+  }
+  if (*n < LETTER_X)
+  {
+    return;
+  }
+  if (izone == 31)
+  {
+    *sleast = R9;
+  }
+  if (izone == 33)
+  {
+    *slwest = R9;
+    *sleast = R21;
+  }
+  if (izone == 35)
+  {
+    *slwest = R21;
+    *sleast = R33;
+  }
+  if (izone == 37)
+  {
+    *slwest = R33;
+  }
+  return;
+} /* END OF UTMLIM */
+
+
+void UTMOSSIM_MGRS (long izone,
+              long* ltrnum,
+              double sphi,
+              double x,
+              double y)
+{ /* BEGIN UTMMGRS */
+  /*
+   *    izone      : Zone number.
+   *    ltrnum     : Values of letters in the MGRS coordinate.
+   *    sphi       : Latitude in radians.
+   *    x          : Easting.
+   *    y          : Northing.
+   *
+   *    UTMMGRS CALLS THE FOLLOWING ROUTINES:
+   *
+   *    GPTUTM
+   *    UTMLIM
+   *    UTMSET
+   */
+  double fnltr;       /* False northing for 3rd letter                     */
+  double slcm;        /* Central meridian - longitude of origin            */
+  double sleast;      /* Longitude east limit - UTM                        */
+  double slwest;      /* Longitude west limit -UTM                         */
+  double spnor;       /* MGRS north latitude limits based on 1st letter    */
+  double spsou;       /* MGRS south latitude limits based on 1st letter    */
+  double xltr;        /* Easting used to derive 2nd letter of MGRS         */
+  double yltr;        /* Northing used to derive 3rd letter of MGRS        */
+  long ltrlow;        /* 2nd letter range - low number                     */
+  long ltrhi;         /* 2nd letter range - high number                    */
+  char hemisphere;
+
+  UTMSET(izone, &ltrlow, &ltrhi, &fnltr);
+  ltrnum[0] = LETTER_A;
+  UTMLIM(&ltrnum[0], sphi, izone, &spsou, &spnor, &sleast, &slwest);
+  slcm = (double)(izone * 6 - 183) * DEGRAD;
+  /*
+    GPTUTM(a, recf, spsou, slcm, &izone, &yltr, &xltr, (long)1);
+  */
+  Set_UTM_Parameters(OSSIM_MGRS_a,OSSIM_MGRS_f,izone);
+  Convert_Geodetic_To_UTM(spsou,slcm,&izone,&hemisphere,&xltr,&yltr);
+
+  yltr = (double)((long)(y + RND5));
+  if (((double)((long)(yltr + RND5))) == ((double)((long)(1.e7 + RND5))))
+  {
+    yltr = (double)((long)(yltr - 1.e0 + RND5)); 
+  }
+  while (yltr >= TWOMIL)
+  {
+    yltr = yltr - TWOMIL; 
+  }
+  yltr = yltr - fnltr;
+  if (yltr < ZERO)
+  {
+    yltr = yltr + TWOMIL;
+  }
+  ltrnum[2] = (long)((yltr + RND1) / ONEHT); 
+  if (ltrnum[2] > LETTER_H)
+  {
+    ltrnum[2] = ltrnum[2] + 1;
+  }
+  if (ltrnum[2] > LETTER_N)
+  {
+    ltrnum[2] = ltrnum[2] + 1;
+  }
+  xltr = (double)((long)(x));
+  if (((ltrnum[0] == LETTER_V) && (izone == 31)) && 
+      (((double)((long)(xltr + RND5))) == ((double)((long)(5.e5 + RND5)))))
+  {
+    xltr = (double)((long)(xltr - 1.e0 + RND5)); /* SUBTRACT 1 METER */
+  }
+  ltrnum[1] = ltrlow + ((long)((xltr + RND1) / ONEHT) -1); 
+  if ((ltrlow == LETTER_J) && (ltrnum[1] > LETTER_N))
+  {
+    ltrnum[1] = ltrnum[1] + 1;
+  }
+  return;
+} /* END UTMMGRS */
+
+
+void UPSSET (long n, 
+             long* ltrlow, 
+             long* ltrhi, 
+             double *feltr,
+             double *fnltr, 
+             long* ltrhy)
+{ /* BEGIN UPSSET */
+  /*
+   *   n      : Value of 1st letter in MGRS coordinate.
+   *   ltrlow : Low number for 2nd letter.
+   *   ltrhi  : High number for 2nd letter.
+   *   feltr  : False easting.
+   *   fnltr  : False northing.
+   *   ltrhy  : High number for 3rd letter.
+   */
+  if (n == LETTER_Z) /* EASTERN HEMISPHERE-NORTH ZONE */
+  {
+    *ltrlow = LETTER_A;
+    *ltrhi  = LETTER_J;
+    *feltr = TWOMIL;
+    *fnltr = ONE3HT;
+    *ltrhy = LETTER_P;
+  }
+  else if (n == LETTER_Y) /* WESTERN HEMISPHERE-NORTH ZONE */
+  {
+    *ltrlow = LETTER_J;
+    *ltrhi  = LETTER_Z;
+    *feltr = EIGHT;
+    *fnltr = ONE3HT;
+    *ltrhy = LETTER_P;
+  }
+  else if (n == LETTER_B) /* ** EASTERN HEMISPHERE - SOUTH ZONE */
+  {
+    *ltrlow = LETTER_A;
+    *ltrhi  = LETTER_R;
+    *feltr = TWOMIL;
+    *fnltr = EIGHT;
+    *ltrhy = LETTER_Z;
+  }
+  else if (n == LETTER_A) /* ** WESTERN HEMISPHERE - SOUTH ZONE */
+  {
+    *ltrlow = LETTER_J;
+    *ltrhi  = LETTER_Z;
+    *feltr = EIGHT;
+    *fnltr = EIGHT;
+    *ltrhy = LETTER_Z;
+  }
+  return;
+} /* END OF UPSSET */
+
+
+void UPS (char* mgrs,
+          long* ltrnum,
+          double x,
+          double y,
+          long iarea)
+{ /* BEGIN UPS */
+  /*
+   *    mgrs   : MGRS coordinate.
+   *    ltrnum : Values of the letters in the MGRS coordinate.
+   *    x      : Easting.
+   *    y      : Northing.
+   *    iarea  : Set to UPS_NORTH or UPS_SOUTH.
+   *
+   *    UPS CALLS THE FOLLOWING ROUTINES:
+   *
+   *    UPSSET
+   */
+  double feltr;       /* False easting for 2nd letter                      */
+  double fnltr;       /* False northing for 3rd letter                     */
+  double xltr;        /* Easting used to derive 2nd letter of MGRS         */
+  double yltr;        /* Northing used to derive 3rd letter of MGRS        */
+  long ltrlow;        /* 2nd letter range - low number                     */
+  long ltrhi;         /* 2nd letter range - high number                    */
+  long ltrhy;         /* 3rd letter range - high number (UPS)              */
+  if (iarea == UPS_NORTH)
+  {
+    ltrnum[0] = LETTER_Y;
+    if (((double)((long)(x + RND5))) >= TWOMIL)
+    {
+      ltrnum[0] = LETTER_Z; 
+    }
+  }
+  else if (iarea == UPS_SOUTH)
+  {
+    ltrnum[0] = LETTER_A;
+    if (((double)((long)(x + RND5))) >= TWOMIL)
+    {
+      ltrnum[0] = LETTER_B;
+    }
+  }
+  UPSSET(ltrnum[0], &ltrlow, &ltrhi, &feltr, &fnltr, &ltrhy);
+  mgrs[0] = BLANK;
+  mgrs[1] = BLANK;
+  yltr = (double)((long)(y + RND5));
+  yltr = yltr - fnltr;
+  ltrnum[2] = (long)((yltr + RND1) / ONEHT);
+  if (ltrnum[2] > LETTER_H)
+  {
+    ltrnum[2] = ltrnum[2] + 1;
+  }
+  if (ltrnum[2] > LETTER_N)
+  {
+    ltrnum[2] = ltrnum[2] + 1;
+  }
+  xltr = (double)((long)(x + RND5));
+  xltr = xltr - feltr;
+  ltrnum[1] = ltrlow + ((long)((xltr + RND1) / ONEHT)); 
+  if (x < TWOMIL)
+  {
+    if (ltrnum[1] > LETTER_L)
+    {
+      ltrnum[1] = ltrnum[1] + 3; 
+    }
+    if (ltrnum[1] > LETTER_U)
+    {
+      ltrnum[1] = ltrnum[1] + 2; 
+    }
+  }
+  if (x >= TWOMIL)
+  {
+    if (ltrnum[1] > LETTER_C)
+    {
+      ltrnum[1] = ltrnum[1] + 2; 
+    }
+    if (ltrnum[1] > LETTER_H)
+    {
+      ltrnum[1] = ltrnum[1] + 1; 
+    }
+    if (ltrnum[1] > LETTER_L)
+    {
+      ltrnum[1] = ltrnum[1] + 3; 
+    }
+  }
+  return;
+} /* END OF UPS */
+
+
+void LTR2UPS (long* ltrnum, 
+              long ltrlow, 
+              long ltrhi, 
+              long ltrhy, 
+              long* ierr, 
+              double *xltr, 
+              double *yltr, 
+              double fnltr, 
+              double feltr, 
+              double *x, 
+              double *y, 
+              double sign)
+{ /* BEGIN LTR2UPS */
+  /*    
+   *    ltrnum : Values of the letters in the MGRS coordinate
+   *    ltrlow : Low number
+   *    ltrhi  : High number-2nd letter
+   *    ltrhy  : High number-3rd letter
+   *    ierr   : Error code
+   *    xltr   : Easting for 100,000 meter grid square
+   *    yltr   : Northing for 100,000 meter grid square
+   *    fnltr  : False northing for 3rd letter
+   *    feltr  : False easting for 2nd letter
+   *    x      : Easting
+   *    y      : Northing
+   *    sign   : Set to either positive or negative
+   */
+  if (ltrnum[1] < ltrlow)
+  {
+    *ierr = TRUE;
+    return;
+  }
+  if (ltrnum[1] > ltrhi)
+  {
+    *ierr = TRUE;
+    return;
+  }
+  if (ltrnum[2] > ltrhy)
+  {
+    *ierr = TRUE;
+    return;
+  }
+  if ((ltrnum[1] == LETTER_D) || (ltrnum[1] == LETTER_E) ||
+      (ltrnum[1] == LETTER_M) || (ltrnum[1] == LETTER_N) ||
+      (ltrnum[1] == LETTER_V) || (ltrnum[1] == LETTER_W))
+  {
+    *ierr = TRUE;
+    return;
+  }
+  *yltr = (double)ltrnum[2] * ONEHT + fnltr; 
+  if (ltrnum[2] > LETTER_I)
+  {
+    *yltr = *yltr - ONEHT;
+  }
+  if (ltrnum[2] > LETTER_O)
+  {
+    *yltr = *yltr - ONEHT;
+  }
+  *xltr = (double)((ltrnum[1]) - ltrlow) * ONEHT + feltr; 
+  if (ltrlow != LETTER_A)
+  {
+    if (ltrnum[1] > LETTER_L)
+    {
+      *xltr = *xltr - 3.e0 * ONEHT;
+    }
+    if (ltrnum[1] > LETTER_U)
+    {
+      *xltr = *xltr - 2.e0 * ONEHT;
+    }
+  }
+  else if (ltrlow == LETTER_A)
+  {
+    if (ltrnum[1] > LETTER_C)
+    {
+      *xltr = *xltr - 2.e0 * ONEHT;
+    }
+    if (ltrnum[1] > LETTER_I)
+    {
+      *xltr = *xltr - ONEHT;
+    }
+    if (ltrnum[1] > LETTER_L)
+    {
+      *xltr = *xltr - 3.e0 * ONEHT ;
+    }
+  }
+  *x = *xltr;
+  *y = *yltr * sign;
+  return;
+} /* END OF LTR2UPS */
+
+
+void GRID_UPS (long   *Letters,
+               char   *Hemisphere,
+               double *Easting,
+               double *Northing,
+               long   *Error)
+{ /* BEGIN GRID_UPS */
+  double feltr;               /* False easting for 2nd letter               */
+  double fnltr;               /* False northing for 3rd letter              */
+  double sleast;              /* Longitude east limit - UTM                 */
+  double slwest;              /* Longitude west limit -UTM                  */
+  double spnor;               /* North latitude limits based on 1st letter  */
+  double spsou;               /* South latitude limits based on 1st letter  */
+  double x;                   /* easting                                    */
+  double xltr;                /* easting for 100,000 meter grid square      */
+  double xnum;                /* easting part of MGRS                       */
+  double y;                   /* northing                                   */
+  double yltr;                /* northing for 100,000 meter grid square     */
+  double ynum;                /* northing part of MGRS                      */
+  long izone;                 /* Zone number                                */
+  long ltrhi;                 /* 2nd letter range - high number             */
+  long ltrhy;                 /* 3rd letter range - high number (UPS)       */
+  long ltrlow;                /* 2nd letter range - low number              */
+  long sign;
+  double sphi;
+  double slam;
+  if ((Letters[0] == LETTER_Y) || (Letters[0] == LETTER_Z))
+  {
+    spsou = MAX_UTM_LAT;
+    sign = 1;
+  }
+  else
+  {
+    spsou = MIN_UTM_LAT;
+    sign = -1;
+  }
+  slam = PI / 2.e0;
+  if ((Letters[0] == LETTER_Y) || (Letters[0] == LETTER_A))
+  {
+    slam = -slam;
+  }
+  izone = 0;
+  sphi = spsou;
+  Set_UPS_Parameters(OSSIM_MGRS_a,OSSIM_MGRS_f);
+  Convert_Geodetic_To_UPS(sphi,slam,Hemisphere,&x,&y);
+  spnor = sphi;
+  sleast = slam;
+  slwest = slam;
+  UPSSET(Letters[0], &ltrlow, &ltrhi, &feltr, &fnltr, &ltrhy);
+  LTR2UPS(Letters, ltrlow, ltrhi, ltrhy, Error, &xltr, &yltr, fnltr, feltr, 
+          &x, &y, sign);
+  xnum = *Easting;
+  ynum = *Northing;
+  y = (yltr + ynum);
+  x = xltr + xnum;
+  *Easting = x;
+  *Northing = y;
+  return;
+} /* END OF GRID_UPS */
+
+
+void LTR2UTM (long* ltrnum, 
+              long ltrlow, 
+              long ltrhi, 
+              long* ierr, 
+              double *xltr, 
+              double *yltr, 
+              double fnltr, 
+              double yslow, 
+              double ylow) 
+{ /* BEGIN LTR2UTM */
+  /*    
+   *    xltr   : Easting for 100,000 meter grid square.
+   *    yltr   : Northing for 100,000 meter grid square.
+   *    ierr   : Error code.
+   *    ltrnum : Values of the letters in the OSSIM_MGRS coordinate.
+   *    ltrlow : Low number.
+   *    ltrhi  : High number.
+   *    fnltr  : False northing for 3rd letter.
+   *    yslow  : Northing scaled down to less than 2 million.
+   *    ylow   : Lowest northing of area to nearest 100,000.
+   */
+  if (ltrnum[1] < ltrlow)
+  {
+    *ierr = TRUE;
+    return;
+  }
+  if (ltrnum[1] > ltrhi)
+  {
+    *ierr = TRUE;
+    return;
+  }
+  if (ltrnum[2] > LETTER_V)
+  {
+    *ierr = TRUE;
+    return;
+  }
+  *yltr = (double)(ltrnum[2]) * ONEHT + fnltr;
+  *xltr = (double)((ltrnum[1]) - ltrlow + 1) * ONEHT;
+  if ((ltrlow == LETTER_J) && (ltrnum[1] > LETTER_O))
+  {
+    *xltr = *xltr - ONEHT;
+  }
+  if (ltrnum[2] > LETTER_O)
+  {
+    *yltr = *yltr - ONEHT;
+  }
+  if (ltrnum[2] > LETTER_I)
+  {
+    *yltr = *yltr - ONEHT; 
+  }
+  if (((double)((long)(*yltr + RND5))) >= ((double)((long)(TWOMIL + RND5))))
+  {
+    *yltr = *yltr - TWOMIL;
+  }
+  *yltr = ((double)((long)(*yltr + RND5)));
+  *yltr = *yltr - yslow;
+  if (*yltr < ZERO)
+  {
+    *yltr = *yltr + TWOMIL;
+  }
+  *yltr = ((double)((long)(ylow + *yltr + RND5)));
+  return;
+} /* END OF LTR2UTM */
+
+
+void GRID_UTM (long   *Zone,
+               long   *Letters,
+               char   *Hemisphere,
+               double *Easting,
+               double *Northing,
+               long   In_Precision,
+               long   *Error)
+{ /* BEGIN GRID_UTM */
+  double fnltr;               /* False northing for 3rd letter              */
+  long ltrhi;                 /* 2nd letter range - High number             */
+  long ltrlow;                /* 2nd letter range - Low number              */
+  long number;                /* Value of ltrnum[0] + 1                     */
+/*  double slam;*/
+  double slcm;                /* Central meridian                           */
+  double sleast;              /* Longitude east limit - UTM                 */
+  double slwest;              /* Longitude west limit -UTM                  */
+  double sphi;                /* Latitude (needed by UTMLIM)                */
+  double spnor;               /* North latitude limits based on 1st letter  */
+  double spsou;               /* South latitude limits based on 1st letter  */
+  double xltr;                /* Easting for 100,000 meter grid square      */
+  double ylow;                /* Lowest northing of area to nearest 100,000 */
+  double yltr;                /* Northing for 100,000 meter grid square     */
+  double yslow;               /* Northing scaled down to less than 2 million*/
+  double Latitude = 0.0;
+  double Longitude = 0.0;
+  double divisor = 1.0;
+  if ((*Zone == 32) && (Letters[0] == LETTER_X))
+  {
+    *Error = TRUE;
+    return;
+  }
+  if ((*Zone == 34) && (Letters[0] == LETTER_X))
+  {
+    *Error = TRUE;
+    return;
+  }
+  if ((*Zone == 36) && (Letters[0] == LETTER_X))
+  {
+    *Error = TRUE;
+    return;
+  }
+  number = Letters[0] + 1;
+  sphi = 0.0;
+  UTMLIM(&number,sphi,*Zone,&spsou,&spnor,&sleast,&slwest);
+  Set_UTM_Parameters(OSSIM_MGRS_a,OSSIM_MGRS_f,*Zone);
+  slcm = (double)(*Zone * 6 - 183) * DEGRAD; 
+  Convert_Geodetic_To_UTM(spsou,slcm,Zone,Hemisphere,&xltr,&yltr);
+  ylow = ((double)((long)((double)((long)(yltr / ONEHT)) * ONEHT)));
+  yslow = ylow;
+  while (yslow >= TWOMIL)
+  {
+    yslow = yslow - TWOMIL;
+  }
+  yslow = ((double)((long)(yslow)));
+  UTMSET(*Zone, &ltrlow, &ltrhi, &fnltr);
+  LTR2UTM(Letters, ltrlow, ltrhi, Error, &xltr, &yltr, fnltr, yslow, ylow);
+  *Easting = xltr + *Easting;
+  *Northing = yltr + *Northing;
+  /* check that point is within Zone Letter bounds */
+  Convert_UTM_To_Geodetic(*Zone,*Hemisphere,*Easting,*Northing,&Latitude,&Longitude);
+  divisor = pow (10.0, In_Precision);
+  if (((spsou - DEGRAD/divisor) <= Latitude) && (Latitude <= (spnor + DEGRAD/divisor)))
+    return;
+  else
+    *Error = TRUE;
+  return;
+}/* END OF GRID_UTM */
+
+
+long Round_OSSIM_MGRS (double value)
+/* Round value to nearest integer, using standard engineering rule */
+{ /* Round_OSSIM_MGRS */
+  double ivalue;
+  long ival;
+  double fraction = modf (value, &ivalue);
+  ival = (long)(ivalue);
+  if ((fraction > 0.5) || ((fraction == 0.5) && (ival%2 == 1)))
+    ival++;
+  return (ival);
+} /* Round_OSSIM_MGRS */
+
+
+long Make_OSSIM_MGRS_String (char* OSSIM_MGRS, 
+                       long Zone, 
+                       long ltrnum[OSSIM_MGRS_LETTERS], 
+                       double Easting, 
+                       double Northing,
+                       long Precision)
+/* Construct an OSSIM_MGRS string from its component parts */
+{ /* Make_OSSIM_MGRS_String */
+  int i;
+  int j;
+  int error_code = OSSIM_MGRS_NO_ERROR;
+  double divisor;
+  long int east;  /* double data type? (drb) */
+  long int north; /* double data type? (drb) */
+  i = 0;
+  if (Zone)
+    i = sprintf (OSSIM_MGRS+i,"%2.2ld",Zone);
+  for (j=0;j<3;j++)
+    OSSIM_MGRS[i++] = ALBET[ltrnum[j]];
+  divisor = pow (10.0, (5 - Precision));
+  Easting = fmod (Easting, 100000.0);
+  if (Easting >= 99999.5)
+    Easting = 99999.0;
+  east = (long int)(Easting/divisor);
+  i += sprintf (OSSIM_MGRS+i, "%*.*ld", (int)Precision, (int)Precision, east);
+  Northing = fmod (Northing, 100000.0);
+  if (Northing >= 99999.5)
+    Northing = 99999.0;
+  north = (long int)(Northing/divisor);
+  i += sprintf (OSSIM_MGRS+i, "%*.*ld", (int)Precision, (int)Precision, north);
+  return (error_code);
+} /* Make_OSSIM_MGRS_String */
+
+
+long Break_OSSIM_MGRS_String (char* OSSIM_MGRS,
+                        long* Zone,
+                        long Letters[OSSIM_MGRS_LETTERS],
+                        double* Easting,
+                        double* Northing,
+                        long* Precision)
+/* Break down an OSSIM_MGRS string into its component parts */
+{ /* Break_OSSIM_MGRS_String */
+  long error_code = OSSIM_MGRS_NO_ERROR;
+  long i = 0;
+  long j;
+  long num_digits;
+  long num_letters;
+  while (OSSIM_MGRS[i] == ' ')
+    i++;  /* skip any leading blanks */
+  j = i;
+  while (isdigit(OSSIM_MGRS[i]))
+    i++;
+  num_digits = i - j;
+  if (num_digits <= 2)
+    if (num_digits > 0)
+    {
+      char zone_string[3];
+      /* get zone */
+      strncpy (zone_string, OSSIM_MGRS+j, 2);
+      zone_string[2] = 0;
+      sscanf (zone_string, "%ld", Zone);  
+      if ((*Zone < 1) || (*Zone > 60))
+        error_code |= OSSIM_MGRS_STRING_ERROR;
+    }
+    else
+      *Zone = 0;
+  else
+    error_code |= OSSIM_MGRS_STRING_ERROR;
+  j = i;
+  while (isalpha(OSSIM_MGRS[i]))
+    i++;
+  num_letters = i - j;
+  if (num_letters == 3)
+  {
+    /* get letters */
+    Letters[0] = (toupper(OSSIM_MGRS[j]) - (long)'A');
+    if ((Letters[0] == LETTER_I) || (Letters[0] == LETTER_O))
+      error_code |= OSSIM_MGRS_STRING_ERROR;
+    Letters[1] = (toupper(OSSIM_MGRS[j+1]) - (long)'A');
+    if ((Letters[1] == LETTER_I) || (Letters[1] == LETTER_O))
+      error_code |= OSSIM_MGRS_STRING_ERROR;
+    Letters[2] = (toupper(OSSIM_MGRS[j+2]) - (long)'A');
+    if ((Letters[2] == LETTER_I) || (Letters[2] == LETTER_O))
+      error_code |= OSSIM_MGRS_STRING_ERROR;
+  }
+  else
+    error_code |= OSSIM_MGRS_STRING_ERROR;
+  j = i;
+  while (isdigit(OSSIM_MGRS[i]))
+    i++;
+  num_digits = i - j;
+  if ((num_digits <= 10) && (num_digits%2 == 0))
+  {
+    long n;
+    char east_string[6];
+    char north_string[6];
+    long east;
+    long north;
+    double multiplier;
+    /* get easting & northing */
+    n = num_digits/2;
+    *Precision = n;
+    if (n > 0)
+    {
+      strncpy (east_string, OSSIM_MGRS+j, n);
+      east_string[n] = 0;
+      sscanf (east_string, "%ld", &east);
+      strncpy (north_string, OSSIM_MGRS+j+n, n);
+      north_string[n] = 0;
+      sscanf (north_string, "%ld", &north);
+      multiplier = pow (10.0, 5 - n);
+      *Easting = east * multiplier;
+      *Northing = north * multiplier;
+    }
+    else
+    {
+      *Easting = 0.0;
+      *Northing = 0.0;
+    }
+  }
+  else
+    error_code |= OSSIM_MGRS_STRING_ERROR;
+  return (error_code);
+} /* Break_OSSIM_MGRS_String */
+
+
+long Set_OSSIM_MGRS_Parameters (double a,
+                          double f,
+                          char   *Ellipsoid_Code)
+/*
+ * The function SET_OSSIM_MGRS_PARAMETERS receives the ellipsoid parameters and sets
+ * the corresponding state variables. If any errors occur, the error code(s)
+ * are returned by the function, otherwise OSSIM_MGRS_NO_ERROR is returned.
+ *
+ *   a                : Semi-major axis of ellipsoid in meters  (input)
+ *   f                : Flattening of ellipsoid					        (input)
+ *   Ellipsoid_Code   : 2-letter code for ellipsoid             (input)
+ */
+{ /* Set_OSSIM_MGRS_Parameters  */
+
+  double inv_f = 1 / f;
+  long Error_Code = OSSIM_MGRS_NO_ERROR;
+
+  if (a <= 0.0)
+  { /* Semi-major axis must be greater than zero */
+    Error_Code |= OSSIM_MGRS_A_ERROR;
+  }
+  if ((inv_f < 250) || (inv_f > 350))
+  { /* Inverse flattening must be between 250 and 350 */
+    Error_Code |= OSSIM_MGRS_INV_F_ERROR;
+  }
+  if (!Error_Code)
+  { /* no errors */
+    OSSIM_MGRS_a = a;
+    OSSIM_MGRS_f = f;
+    OSSIM_MGRS_recpf = inv_f;
+    strcpy (OSSIM_MGRS_Ellipsoid_Code, Ellipsoid_Code);
+  }
+  return (Error_Code);
+}  /* Set_OSSIM_MGRS_Parameters  */
+
+
+
+void Get_OSSIM_MGRS_Parameters (double *a,
+                          double *f,
+                          char* Ellipsoid_Code)
+/*
+ * The function Get_OSSIM_MGRS_Parameters returns the current ellipsoid
+ * parameters.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters (output)
+ *  f                : Flattening of ellipsoid					       (output)
+ *  Ellipsoid_Code   : 2-letter code for ellipsoid             (output)
+ */
+{ /* Get_OSSIM_MGRS_Parameters */
+  *a = OSSIM_MGRS_a;
+  *f = OSSIM_MGRS_f;
+  strcpy (Ellipsoid_Code, OSSIM_MGRS_Ellipsoid_Code);
+  return;
+} /* Get_OSSIM_MGRS_Parameters */
+
+
+long Convert_Geodetic_To_OSSIM_MGRS (double Latitude,
+                               double Longitude,
+                               long Precision,
+                               char* OSSIM_MGRS)
+/*
+ *    Latitude   : Latitude in radians              (input)
+ *    Longitude  : Longitude in radians             (input)
+ *    OSSIM_MGRS       : OSSIM_MGRS coordinate string           (output)
+ *  
+ */
+{ /* Convert_Geodetic_To_OSSIM_MGRS */
+  long error_code = OSSIM_MGRS_NO_ERROR;
+  long zone;
+  char hemisphere;
+  double easting;
+  double northing;
+  if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+  { /* Latitude out of range */
+    error_code |= OSSIM_MGRS_LAT_ERROR;
+  }
+  if ((Longitude < -PI) || (Longitude > (2*PI)))
+  { /* Longitude out of range */
+    error_code |= OSSIM_MGRS_LON_ERROR;
+  }
+  if ((Precision < 0) || (Precision > MAX_PRECISION))
+    error_code |= OSSIM_MGRS_PRECISION_ERROR;
+  if (!error_code)
+  {
+    if ((Latitude < MIN_UTM_LAT) || (Latitude > MAX_UTM_LAT))
+    {
+      Set_UPS_Parameters (OSSIM_MGRS_a, OSSIM_MGRS_f);
+      error_code |= Convert_Geodetic_To_UPS (Latitude, Longitude, &hemisphere, &easting, &northing);
+      error_code |= Convert_UPS_To_OSSIM_MGRS (hemisphere, easting, northing, Precision, OSSIM_MGRS);
+    }
+    else
+    {
+      Set_UTM_Parameters (OSSIM_MGRS_a, OSSIM_MGRS_f, 0);
+      error_code |= Convert_Geodetic_To_UTM (Latitude, Longitude, &zone, &hemisphere, &easting, &northing);
+      error_code |= Convert_UTM_To_OSSIM_MGRS (zone, hemisphere, easting, northing, Precision, OSSIM_MGRS);
+    }
+  }
+  return (error_code);
+} /* Convert_Geodetic_To_OSSIM_MGRS */
+
+
+long Convert_OSSIM_MGRS_To_Geodetic (char* OSSIM_MGRS, 
+                               double *Latitude, 
+                               double *Longitude)
+/*
+ *    OSSIM_MGRS       : OSSIM_MGRS coordinate string           (output)
+ *    Latitude   : Latitude in radians              (input)
+ *    Longitude  : Longitude in radians             (input)
+ *  
+ */
+{ /* Convert_OSSIM_MGRS_To_Geodetic */
+  long error_code = OSSIM_MGRS_NO_ERROR;
+  long Zone;
+  long Letters[OSSIM_MGRS_LETTERS];
+  char Hemisphere;
+  double Easting;
+  double Northing;
+  long In_Precision;
+  error_code = Break_OSSIM_MGRS_String (OSSIM_MGRS, &Zone, Letters, &Easting, &Northing, &In_Precision);
+  if (!error_code)
+  {
+     if (Zone)
+     {
+        error_code |= Convert_OSSIM_MGRS_To_UTM (OSSIM_MGRS, &Zone, &Hemisphere, &Easting, &Northing);
+        Set_UTM_Parameters (OSSIM_MGRS_a, OSSIM_MGRS_f, 0);
+        error_code |= Convert_UTM_To_Geodetic (Zone, Hemisphere, Easting, Northing, Latitude, Longitude);
+     }
+     else
+     {
+        error_code |= Convert_OSSIM_MGRS_To_UPS (OSSIM_MGRS, &Hemisphere, &Easting, &Northing);
+        Set_UPS_Parameters (OSSIM_MGRS_a, OSSIM_MGRS_f);
+        error_code |= Convert_UPS_To_Geodetic (Hemisphere, Easting, Northing, Latitude, Longitude);
+     }
+  }
+  return (error_code);
+} /* END OF Convert_OSSIM_MGRS_To_Geodetic */
+
+
+
+long Convert_UTM_To_OSSIM_MGRS (long Zone,
+                          char Hemisphere,
+                          double Easting,
+                          double Northing,
+                          long Precision,
+                          char* OSSIM_MGRS)
+/*
+ * The function Convert_UTM_To_OSSIM_MGRS converts UTM (zone, easting, and
+ * northing) coordinates to an OSSIM_MGRS coordinate string, according to the 
+ * current ellipsoid parameters.  If any errors occur, the error code(s) 
+ * are returned by the  function, otherwise OSSIM_MGRS_NO_ERROR is returned.
+ *
+ *    Zone       : UTM zone                         (input)
+ *    Hemisphere : North or South hemisphere        (input)
+ *    Easting    : Easting (X) in meters            (input)
+ *    Northing   : Northing (Y) in meters           (input)
+ *    Precision  : Precision level of OSSIM_MGRS string   (input)
+ *    OSSIM_MGRS       : OSSIM_MGRS coordinate string           (output)
+ */
+{ /* Convert_UTM_To_OSSIM_MGRS */
+  long error_code = OSSIM_MGRS_NO_ERROR;
+  long temp_error = OSSIM_MGRS_NO_ERROR;
+  long Letters[OSSIM_MGRS_LETTERS]; /* Number location of 3 letters in alphabet   */
+  double Latitude;           /* Latitude of UTM point */
+  double Longitude;          /* Longitude of UTM point */
+  double divisor;
+  if ((Zone < 1) || (Zone > 60))
+    error_code |= OSSIM_MGRS_ZONE_ERROR;
+  if ((Hemisphere != 'S') && (Hemisphere != 'N'))
+    error_code |= OSSIM_MGRS_HEMISPHERE_ERROR;
+  if ((Easting < MIN_EASTING) || (Easting > MAX_EASTING))
+    error_code |= OSSIM_MGRS_EASTING_ERROR;
+  if ((Northing < MIN_NORTHING) || (Northing > MAX_NORTHING))
+    error_code |= OSSIM_MGRS_NORTHING_ERROR;
+  if ((Precision < 0) || (Precision > MAX_PRECISION))
+    error_code |= OSSIM_MGRS_PRECISION_ERROR;
+  if (!error_code)
+  {
+    Set_UTM_Parameters (OSSIM_MGRS_a, OSSIM_MGRS_f,0);
+    temp_error = Convert_UTM_To_Geodetic (Zone, Hemisphere, Easting, Northing, &Latitude, &Longitude);
+	if (temp_error & UTM_NORTHING_ERROR)
+		error_code |= OSSIM_MGRS_NORTHING_ERROR;
+	else
+	{
+	  /* Round easting and northing values */
+	  divisor = pow (10.0, (5 - Precision));
+	  Easting = Round_OSSIM_MGRS (Easting/divisor) * divisor;
+	  Northing = Round_OSSIM_MGRS (Northing/divisor) * divisor;
+	  UTMOSSIM_MGRS (Zone, Letters, Latitude, Easting, Northing);
+	  /* UTM checks - these should be done in UTMOSSIM_MGRS */
+	  if ((Zone == 31) && (Letters[0] == LETTER_V))
+	    if (Easting > 500000)
+		  Easting = 500000;
+	  if (Northing > 10000000)
+	    Northing = 10000000;
+	  Make_OSSIM_MGRS_String (OSSIM_MGRS, Zone, Letters, Easting, Northing, Precision);
+	}
+  }
+  return (error_code);
+} /* Convert_UTM_To_OSSIM_MGRS */
+
+
+long Convert_OSSIM_MGRS_To_UTM (char   *OSSIM_MGRS,
+                          long   *Zone,
+                          char   *Hemisphere,
+                          double *Easting,
+                          double *Northing)
+/*
+ * The function Convert_OSSIM_MGRS_To_UTM converts an OSSIM_MGRS coordinate string
+ * to UTM projection (zone, hemisphere, easting and northing) coordinates 
+ * according to the current ellipsoid parameters.  If any errors occur, 
+ * the error code(s) are returned by the function, otherwise UTM_NO_ERROR 
+ * is returned.
+ *
+ *    OSSIM_MGRS       : OSSIM_MGRS coordinate string           (input)
+ *    Zone       : UTM zone                         (output)
+ *    Hemisphere : North or South hemisphere        (output)
+ *    Easting    : Easting (X) in meters            (output)
+ *    Northing   : Northing (Y) in meters           (output)
+ */
+{ /* Convert_OSSIM_MGRS_To_UTM */
+  long error_code = OSSIM_MGRS_NO_ERROR;
+  long Letters[OSSIM_MGRS_LETTERS];
+  long In_Precision;
+  long Error = 0;
+  error_code = Break_OSSIM_MGRS_String (OSSIM_MGRS, Zone, Letters, Easting, Northing, &In_Precision);
+  if (!*Zone)
+    error_code |= OSSIM_MGRS_STRING_ERROR;
+  if (!error_code)
+  {
+    GRID_UTM (Zone, Letters, Hemisphere, Easting, Northing, In_Precision, &Error);
+    if (Error)
+      error_code = OSSIM_MGRS_STRING_ERROR;
+  }
+  return (error_code);
+} /* Convert_OSSIM_MGRS_To_UTM */
+
+
+long Convert_UPS_To_OSSIM_MGRS (char   Hemisphere,
+                          double Easting,
+                          double Northing,
+                          long   Precision,
+                          char*  OSSIM_MGRS)
+/*
+ *  The function Convert_UPS_To_OSSIM_MGRS converts UPS (hemisphere, easting, 
+ *  and northing) coordinates to an OSSIM_MGRS coordinate string according to 
+ *  the current ellipsoid parameters.  If any errors occur, the error
+ *  code(s) are returned by the function, otherwise UPS_NO_ERROR is 
+ *  returned.
+ *
+ *    Hemisphere    : Hemisphere either 'N' or 'S'     (input)
+ *    Easting       : Easting/X in meters              (input)
+ *    Northing      : Northing/Y in meters             (input)
+ *    Precision     : Precision level of OSSIM_MGRS string   (input)
+ *    OSSIM_MGRS          : OSSIM_MGRS coordinate string           (output)
+ */
+{ /* Convert_UPS_To_OSSIM_MGRS */
+  double divisor;
+  long error_code = OSSIM_MGRS_NO_ERROR;
+  long ltrnum[OSSIM_MGRS_LETTERS]; /* Number location of 3 letters in alphabet   */
+  if ((Hemisphere != 'N') && (Hemisphere != 'S'))
+    error_code |= OSSIM_MGRS_HEMISPHERE_ERROR;
+  if ((Easting < MIN_EAST_NORTH) || (Easting > MAX_EAST_NORTH))
+    error_code |= OSSIM_MGRS_EASTING_ERROR;
+  if ((Northing < MIN_EAST_NORTH) || (Northing > MAX_EAST_NORTH))
+    error_code |= OSSIM_MGRS_NORTHING_ERROR;
+  if ((Precision < 0) || (Precision > MAX_PRECISION))
+    error_code |= OSSIM_MGRS_PRECISION_ERROR;
+  if (!error_code)
+  {
+    divisor = pow (10.0, (5 - Precision));
+    Easting = Round_OSSIM_MGRS (Easting/divisor) * divisor;
+    Northing = Round_OSSIM_MGRS (Northing/divisor) * divisor;
+    if (Hemisphere == 'S')
+      UPS (OSSIM_MGRS, ltrnum, Easting, Northing, UPS_SOUTH);
+    else
+      UPS (OSSIM_MGRS, ltrnum, Easting, Northing, UPS_NORTH);
+    Make_OSSIM_MGRS_String (OSSIM_MGRS, 0, ltrnum, Easting, Northing, Precision);
+  }
+  return (error_code);
+} /* Convert_UPS_To_OSSIM_MGRS */
+
+
+long Convert_OSSIM_MGRS_To_UPS ( char   *OSSIM_MGRS,
+                           char   *Hemisphere,
+                           double *Easting,
+                           double *Northing)
+/*
+ *  The function Convert_OSSIM_MGRS_To_UPS converts an OSSIM_MGRS coordinate string
+ *  to UPS (hemisphere, easting, and northing) coordinates, according 
+ *  to the current ellipsoid parameters. If any errors occur, the error 
+ *  code(s) are returned by the function, otherwide UPS_NO_ERROR is returned.
+ *
+ *    OSSIM_MGRS          : OSSIM_MGRS coordinate string           (input)
+ *    Hemisphere    : Hemisphere either 'N' or 'S'     (output)
+ *    Easting       : Easting/X in meters              (output)
+ *    Northing      : Northing/Y in meters             (output)
+ */
+{ /* Convert_OSSIM_MGRS_To_UPS */
+  long error_code = OSSIM_MGRS_NO_ERROR;
+  long Error = 0;
+  long Zone;
+  long Letters[OSSIM_MGRS_LETTERS];
+  long In_Precision;
+  error_code = Break_OSSIM_MGRS_String (OSSIM_MGRS, &Zone, Letters, Easting, Northing, &In_Precision);
+  if (Zone)
+    error_code |= OSSIM_MGRS_STRING_ERROR;
+  if (!error_code)
+  {
+    GRID_UPS (Letters, Hemisphere, Easting, Northing, &Error);
+    if (Error)
+      error_code = OSSIM_MGRS_STRING_ERROR;
+  }
+  return (error_code);
+} /* Convert_OSSIM_MGRS_To_UPS */
+
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMgrs.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMgrs.h
new file mode 100644
index 0000000000..582ce57772
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMgrs.h
@@ -0,0 +1,252 @@
+#ifndef MGRS_H
+  #define MGRS_H
+
+/***************************************************************************/
+/* RSC IDENTIFIER:  MGRS
+ *
+ * ABSTRACT
+ *
+ *    This component converts between geodetic coordinates (latitude and 
+ *    longitude) and Military Grid Reference System (MGRS) coordinates. 
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *          MGRS_NO_ERROR          : No errors occurred in function
+ *          MGRS_LAT_ERROR         : Latitude outside of valid range 
+ *                                    (-90 to 90 degrees)
+ *          MGRS_LON_ERROR         : Longitude outside of valid range
+ *                                    (-180 to 360 degrees)
+ *          MGRS_STR_ERROR         : An MGRS string error: string too long,
+ *                                    too short, or badly formed
+ *          MGRS_PRECISION_ERROR   : The precision must be between 0 and 5 
+ *                                    inclusive.
+ *          MGRS_A_ERROR           : Semi-major axis less than or equal to zero
+ *          MGRS_INV_F_ERROR       : Inverse flattening outside of valid range
+ *									                  (250 to 350)
+ *          MGRS_EASTING_ERROR     : Easting outside of valid range
+ *                                    (100,000 to 900,000 meters for UTM)
+ *                                    (0 to 4,000,000 meters for UPS)
+ *          MGRS_NORTHING_ERROR    : Northing outside of valid range
+ *                                    (0 to 10,000,000 meters for UTM)
+ *                                    (0 to 4,000,000 meters for UPS)
+ *          MGRS_ZONE_ERROR        : Zone outside of valid range (1 to 60)
+ *          MGRS_HEMISPHERE_ERROR  : Invalid hemisphere ('N' or 'S')
+ *
+ * REUSE NOTES
+ *
+ *    MGRS is intended for reuse by any application that does conversions
+ *    between geodetic coordinates and MGRS coordinates.
+ *
+ * REFERENCES
+ *
+ *    Further information on MGRS can be found in the Reuse Manual.
+ *
+ *    MGRS originated from : U.S. Army Topographic Engineering Center
+ *                           Geospatial Information Division
+ *                           7701 Telegraph Road
+ *                           Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *
+ * ENVIRONMENT
+ *
+ *    MGRS was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC version 2.8.1
+ *    2. Windows 95 with MS Visual C++ version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    16-11-94          Original Code
+ *    15-09-99          Reengineered upper layers
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+#define OSSIM_MGRS_NO_ERROR                0x0000
+#define OSSIM_MGRS_LAT_ERROR               0x0001
+#define OSSIM_MGRS_LON_ERROR               0x0002
+#define OSSIM_MGRS_STRING_ERROR            0x0004
+#define OSSIM_MGRS_PRECISION_ERROR         0x0008
+#define OSSIM_MGRS_A_ERROR                 0x0010
+#define OSSIM_MGRS_INV_F_ERROR             0x0020
+#define OSSIM_MGRS_EASTING_ERROR           0x0040
+#define OSSIM_MGRS_NORTHING_ERROR          0x0080
+#define OSSIM_MGRS_ZONE_ERROR              0x0100
+#define OSSIM_MGRS_HEMISPHERE_ERROR        0x0200
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTION PROTOTYPES
+ */
+
+/* ensure proper linkage to c++ programs */
+  #ifdef __cplusplus
+extern "C" {
+  #endif
+
+
+  long Set_OSSIM_MGRS_Parameters(double a,
+                           double f,
+                           char   *Ellipsoid_Code);
+/*
+ * The function Set_MGRS_Parameters receives the ellipsoid parameters and sets
+ * the corresponding state variables. If any errors occur, the error code(s)
+ * are returned by the function, otherwise MGRS_NO_ERROR is returned.
+ *
+ *   a                : Semi-major axis of ellipsoid in meters (input)
+ *   f                : Flattening of ellipsoid					       (input)
+ *   Ellipsoid_Code   : 2-letter code for ellipsoid            (input)
+ */
+
+
+  void Get_OSSIM_MGRS_Parameters(double *a,
+                           double *f,
+                           char   *Ellipsoid_Code);
+/*
+ * The function Get_MGRS_Parameters returns the current ellipsoid
+ * parameters.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters (output)
+ *  f                : Flattening of ellipsoid					       (output)
+ *  Ellipsoid_Code   : 2-letter code for ellipsoid             (output)
+ */
+
+
+  long Convert_Geodetic_To_OSSIM_MGRS (double Latitude,
+                                 double Longitude,
+                                 long   Precision,
+                                 char *MGRS);
+/*
+ * The function Convert_Geodetic_To_MGRS converts geodetic (latitude and
+ * longitude) coordinates to an MGRS coordinate string, according to the 
+ * current ellipsoid parameters.  If any errors occur, the error code(s) 
+ * are returned by the  function, otherwise MGRS_NO_ERROR is returned.
+ *
+ *    Latitude   : Latitude in radians              (input)
+ *    Longitude  : Longitude in radians             (input)
+ *    Precision  : Precision level of MGRS string   (input)
+ *    MGRS       : MGRS coordinate string           (output)
+ *  
+ */
+
+
+  long Convert_OSSIM_MGRS_To_Geodetic (char *MGRS,
+                                 double *Latitude,
+                                 double *Longitude);
+/*
+ * This function converts an MGRS coordinate string to Geodetic (latitude
+ * and longitude in radians) coordinates.  If any errors occur, the error 
+ * code(s) are returned by the  function, otherwise MGRS_NO_ERROR is returned.  
+ *
+ *    MGRS       : MGRS coordinate string           (input)
+ *    Latitude   : Latitude in radians              (output)
+ *    Longitude  : Longitude in radians             (output)
+ *  
+ */
+
+
+  long Convert_UTM_To_OSSIM_MGRS (long Zone,
+                            char Hemisphere,
+                            double Easting,
+                            double Northing,
+                            long Precision,
+                            char *MGRS);
+/*
+ * The function Convert_UTM_To_MGRS converts UTM (zone, easting, and
+ * northing) coordinates to an MGRS coordinate string, according to the 
+ * current ellipsoid parameters.  If any errors occur, the error code(s) 
+ * are returned by the  function, otherwise MGRS_NO_ERROR is returned.
+ *
+ *    Zone       : UTM zone                         (input)
+ *    Hemisphere : North or South hemisphere        (input)
+ *    Easting    : Easting (X) in meters            (input)
+ *    Northing   : Northing (Y) in meters           (input)
+ *    Precision  : Precision level of MGRS string   (input)
+ *    MGRS       : MGRS coordinate string           (output)
+ */
+
+
+  long Convert_OSSIM_MGRS_To_UTM (char   *MGRS,
+                            long   *Zone,
+                            char   *Hemisphere,
+                            double *Easting,
+                            double *Northing); 
+/*
+ * The function Convert_MGRS_To_UTM converts an MGRS coordinate string
+ * to UTM projection (zone, hemisphere, easting and northing) coordinates 
+ * according to the current ellipsoid parameters.  If any errors occur, 
+ * the error code(s) are returned by the function, otherwise UTM_NO_ERROR 
+ * is returned.
+ *
+ *    MGRS       : MGRS coordinate string           (input)
+ *    Zone       : UTM zone                         (output)
+ *    Hemisphere : North or South hemisphere        (output)
+ *    Easting    : Easting (X) in meters            (output)
+ *    Northing   : Northing (Y) in meters           (output)
+ */
+
+
+
+  long Convert_UPS_To_OSSIM_MGRS ( char   Hemisphere,
+                             double Easting,
+                             double Northing,
+                             long Precision,
+                             char *MGRS);
+
+/*
+ *  The function Convert_UPS_To_MGRS converts UPS (hemisphere, easting, 
+ *  and northing) coordinates to an MGRS coordinate string according to 
+ *  the current ellipsoid parameters.  If any errors occur, the error
+ *  code(s) are returned by the function, otherwise UPS_NO_ERROR is 
+ *  returned.
+ *
+ *    Hemisphere    : Hemisphere either 'N' or 'S'     (input)
+ *    Easting       : Easting/X in meters              (input)
+ *    Northing      : Northing/Y in meters             (input)
+ *    Precision     : Precision level of MGRS string   (input)
+ *    MGRS          : MGRS coordinate string           (output)
+ */
+
+
+  long Convert_OSSIM_MGRS_To_UPS ( char   *MGRS,
+                             char   *Hemisphere,
+                             double *Easting,
+                             double *Northing);
+/*
+ *  The function Convert_MGRS_To_UPS converts an MGRS coordinate string
+ *  to UPS (hemisphere, easting, and northing) coordinates, according 
+ *  to the current ellipsoid parameters. If any errors occur, the error 
+ *  code(s) are returned by the function, otherwide UPS_NO_ERROR is returned.
+ *
+ *    MGRS          : MGRS coordinate string           (input)
+ *    Hemisphere    : Hemisphere either 'N' or 'S'     (output)
+ *    Easting       : Easting/X in meters              (output)
+ *    Northing      : Northing/Y in meters             (output)
+ */
+
+
+
+  #ifdef __cplusplus
+}
+  #endif
+
+#endif /* MGRS_H */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMillerProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMillerProjection.cpp
new file mode 100644
index 0000000000..5a884bd695
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMillerProjection.cpp
@@ -0,0 +1,411 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Miller projection code.  
+//*******************************************************************
+//  $Id: ossimMillerProjection.cpp,v 1.12 2004/01/08 21:49:22 jlargent Exp $
+
+#include <math.h>
+#include "ossimMillerProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimMillerProjection, "ossimMillerProjection", ossimMapProjection)
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+
+#define MILL_NO_ERROR           0x0000
+#define MILL_LAT_ERROR          0x0001
+#define MILL_LON_ERROR          0x0002
+#define MILL_EASTING_ERROR      0x0004
+#define MILL_NORTHING_ERROR     0x0008
+#define MILL_CENT_MER_ERROR     0x0020
+#define MILL_A_ERROR            0x0040
+#define MILL_B_ERROR            0x0080
+#define MILL_A_LESS_B_ERROR     0x0100
+
+ossimMillerProjection::ossimMillerProjection(const ossimEllipsoid& ellipsoid,
+                                             const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+//    Mill_Delta_Northing = 14675058.0;
+//    Mill_Max_Easting    = 20015110.0;
+//    Mill_Min_Easting    = -20015110.0;
+}
+
+ossimMillerProjection::ossimMillerProjection(const ossimEllipsoid& ellipsoid,
+                                             const ossimGpt& origin,
+                                             double falseEasting,
+                                             double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+
+   Mill_False_Easting  = falseEasting;
+   Mill_False_Northing = falseNorthing;
+   Mill_Delta_Northing = 14675058.0;
+   Mill_Max_Easting    = 20015110.0;
+   Mill_Min_Easting    = -20015110.0;
+
+   update();
+}
+
+void ossimMillerProjection::update()
+{
+   Set_Miller_Parameters(theEllipsoid.getA(),
+                         theEllipsoid.getFlattening(),
+                         theOrigin.lonr(),
+                         Mill_False_Easting,
+                         Mill_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimMillerProjection::setFalseEasting(double falseEasting)
+{
+   Mill_False_Easting = falseEasting;
+   update();
+}
+
+void ossimMillerProjection::setFalseNorthing(double falseNorthing)
+{
+   Mill_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimMillerProjection::setDefaults()
+{
+   Mill_False_Easting  = 0.0;
+   Mill_False_Northing = 0.0;
+   Mill_Delta_Northing = 14675058.0;
+   Mill_Max_Easting    = 20015110.0;
+   Mill_Min_Easting    = -20015110.0;
+}
+
+void ossimMillerProjection::setFalseEastingNorthing(double falseEasting,
+                                                    double falseNorthing)
+{
+   Mill_False_Easting  = falseEasting;
+   Mill_False_Northing = falseNorthing;
+   
+   update();
+}
+
+ossimGpt ossimMillerProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+
+   Convert_Miller_To_Geodetic(eastingNorthing.x,
+                              eastingNorthing.y,
+                              &lat,
+                              &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);
+}
+
+ossimDpt ossimMillerProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Miller(gpt.latr(),
+                              gpt.lonr(),
+                              &easting,
+                              &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+bool ossimMillerProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Mill_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Mill_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimMillerProjection::loadState(const ossimKeywordlist& kwl,
+                                      const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimMillerProjection))
+   {
+      if(falseEasting)
+      {
+         Mill_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Mill_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   update();
+
+   return flag;
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS
+ */
+
+long ossimMillerProjection::Set_Miller_Parameters(double a,
+                                                  double f,
+                                                  double Central_Meridian ,
+                                                  double False_Easting,
+                                                  double False_Northing)
+{ /* Begin Set_Miller_Parameters */
+/*
+ * The function Set_Miller_Parameters receives the ellipsoid parameters and
+ * Miller Cylindrical projcetion parameters as inputs, and sets the corresponding
+ * state variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise MILL_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+//  double inv_f = 1 / f;
+  long Error_Code = MILL_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= MILL_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= MILL_INV_F_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= MILL_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Mill_a = a;
+    Mill_f = f;
+    es2 = 2 * Mill_f - Mill_f * Mill_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    /* spherical radius */
+    Ra = Mill_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 /3024.0);
+//     if (Central_Meridian > PI)
+//       Central_Meridian -= TWO_PI;
+    Mill_Origin_Long = Central_Meridian;
+    Mill_False_Easting = False_Easting;
+    Mill_False_Northing = False_Northing;
+    if (Mill_Origin_Long > 0)
+    {
+      Mill_Max_Easting = 19903915.0;
+      Mill_Min_Easting = -20015110.0;
+    }
+    else if (Mill_Origin_Long < 0)
+    {
+      Mill_Max_Easting = 20015110.0;
+      Mill_Min_Easting = -19903915.0;
+    }
+    else
+    {
+      Mill_Max_Easting = 20015110.0;
+      Mill_Min_Easting = -20015110.0;
+    }
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Miller_Parameters */
+
+
+void ossimMillerProjection::Get_Miller_Parameters(double *a,
+                                                  double *f,
+                                                  double *Central_Meridian,
+                                                  double *False_Easting,
+                                                  double *False_Northing)const
+{ /* Begin Get_Miller_Parameters */
+/*
+ * The function Get_Miller_Parameters returns the current ellipsoid
+ * parameters and Miller Cylindrical projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Mill_a;
+  *f = Mill_f;
+  *Central_Meridian = Mill_Origin_Long;
+  *False_Easting = Mill_False_Easting;
+  *False_Northing = Mill_False_Northing;
+  
+  return;
+} /* End Get_Miller_Parameters */
+
+
+long ossimMillerProjection::Convert_Geodetic_To_Miller (double Latitude,
+                                                        double Longitude,
+                                                        double *Easting,
+                                                        double *Northing)const
+
+{ /* Begin Convert_Geodetic_To_Miller */
+/*
+ * The function Convert_Geodetic_To_Miller converts geodetic (latitude and
+ * longitude) coordinates to Miller Cylindrical projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Miller Cylindrical projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MILL_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double slat = sin(0.8 * Latitude);
+  double dlam;     /* Longitude - Central Meridan */
+
+  long   Error_Code = MILL_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   {  /* Latitude out of range */
+//     Error_Code |= MILL_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   {  /* Longitude out of range */
+//     Error_Code|= MILL_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Mill_Origin_Long;
+//     if (dlam > PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+    *Easting = Ra * dlam + Mill_False_Easting;
+    *Northing = (Ra / 1.6) * log((1.0 + slat) /
+                                 (1.0 - slat)) + Mill_False_Northing;
+  }
+  return (Error_Code);
+} /* End Convert_Geodetic_To_Miller */
+
+
+long ossimMillerProjection::Convert_Miller_To_Geodetic(double Easting,
+                                                       double Northing,
+                                                       double *Latitude,
+                                                       double *Longitude)const
+{ /* Begin Convert_Miller_To_Geodetic */
+/*
+ * The function Convert_Miller_To_Geodetic converts Miller Cylindrical projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Miller Cylindrical projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MILL_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx, dy;
+  long Error_Code = MILL_NO_ERROR;
+
+//   if ((Easting < (Mill_False_Easting + Mill_Min_Easting))
+//       || (Easting > (Mill_False_Easting + Mill_Max_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= MILL_EASTING_ERROR;
+//   }
+//   if ((Northing < (Mill_False_Northing - Mill_Delta_Northing)) || 
+//       (Northing > (Mill_False_Northing + Mill_Delta_Northing) ))
+//   { /* Northing out of range */
+//     Error_Code |= MILL_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  {
+    dy = Northing - Mill_False_Northing;
+    dx = Easting - Mill_False_Easting;
+    *Latitude = atan(sinh(0.8 * dy / Ra)) / 0.8;
+    *Longitude = Mill_Origin_Long + dx / Ra;
+
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+
+//     if (*Longitude > PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -PI)
+//       *Longitude += TWO_PI;
+
+//     if (*Longitude > PI)  /* force distorted values to 180, -180 degrees */
+//       *Longitude = PI;
+//     else if (*Longitude < -PI)
+//       *Longitude = -PI;
+
+  }
+  return (Error_Code);
+} /* End Convert_Miller_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMillerProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMillerProjection.h
new file mode 100644
index 0000000000..01e97cd045
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMillerProjection.h
@@ -0,0 +1,186 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Miller projection code.  
+//*******************************************************************
+//  $Id: ossimMillerProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimMillerProjection_HEADER
+#define ossimMillerProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimMillerProjection : public ossimMapProjection
+{
+public:
+   ossimMillerProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                         const ossimGpt& origin = ossimGpt());
+   ossimMillerProjection(const ossimEllipsoid& ellipsoid,
+                         const ossimGpt& origin,
+                         const double falseEasting,
+                         const double falseNorthing);
+   
+   ~ossimMillerProjection(){}
+   
+   virtual ossimObject *dup()const{return new ossimMillerProjection(*this);}
+
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return Mill_False_Easting;}
+   double getFalseNorthing()const{return Mill_False_Northing;}
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+
+   //________________GEOTRANS STUFF___________________
+
+   mutable double Mill_a;   /* Semi-major axis of ellipsoid in meters */
+   mutable double Mill_f;   /* Flattening of ellipsoid */
+   mutable double es2;      /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;      /* es2 * es2	*/
+   mutable double es6;      /* es4 * es2   */
+   mutable double Ra;       /* Spherical Radius */
+   
+/* Miller projection Parameters */
+   mutable double Mill_Origin_Long;                  /* Longitude of origin in radians    */
+   mutable double Mill_False_Easting;
+   mutable double Mill_False_Northing;
+   mutable double Mill_Delta_Northing;
+   mutable double Mill_Max_Easting;
+   mutable double Mill_Min_Easting;
+   
+/*!
+ * The function Set_Miller_Parameters receives the ellipsoid parameters and
+ * Miller Cylindrical projcetion parameters as inputs, and sets the corresponding
+ * state variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise MILL_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Miller_Parameters(double a,
+                             double f,
+                             double Central_Meridian,
+                             double False_Easting,
+                             double False_Northing);
+
+
+/*!
+ * The function Get_Miller_Parameters returns the current ellipsoid
+ * parameters and Miller Cylindrical projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Miller_Parameters(double *a,
+                             double *f,
+                             double *Central_Meridian,
+                             double *False_Easting,
+                             double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Miller converts geodetic (latitude and
+ * longitude) coordinates to Miller Cylindrical projection easting, and northing
+ * coordinates, according to the current ellipsoid and Miller Cylindrical projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MILL_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Miller (double Latitude,
+                                   double Longitude,
+                                   double *Easting,
+                                   double *Northing)const;
+
+
+/*!
+ * The function Convert_Miller_To_Geodetic converts Miller Cylindrical projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Miller Cylindrical projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MILL_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Miller_To_Geodetic(double Easting,
+                                  double Northing,
+                                  double *Latitude,
+                                  double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMollweidProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMollweidProjection.cpp
new file mode 100644
index 0000000000..4be11722eb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMollweidProjection.cpp
@@ -0,0 +1,453 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Mollweid projection code.  
+//*******************************************************************
+//  $Id: ossimMollweidProjection.cpp,v 1.11 2004/01/08 21:49:22 jlargent Exp $
+#include <math.h>
+#include "ossimMollweidProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimMollweidProjection, "ossimMollweidProjection", ossimMapProjection)
+
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define MAX_LAT    ( (M_PI * 90.0) / 180.0 ) /* 90 degrees in radians    */
+
+#define MOLL_NO_ERROR           0x0000
+#define MOLL_LAT_ERROR          0x0001
+#define MOLL_LON_ERROR          0x0002
+#define MOLL_EASTING_ERROR      0x0004
+#define MOLL_NORTHING_ERROR     0x0008
+#define MOLL_CENT_MER_ERROR     0x0020
+#define MOLL_A_ERROR            0x0040
+#define MOLL_B_ERROR            0x0080
+#define MOLL_A_LESS_B_ERROR     0x0100
+
+ossimMollweidProjection::ossimMollweidProjection(const ossimEllipsoid& ellipsoid,
+                                                 const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimMollweidProjection::ossimMollweidProjection(const ossimEllipsoid& ellipsoid,
+                                                 const ossimGpt& origin,
+                                                 double falseEasting,
+                                                 double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+
+   Moll_False_Easting  = falseEasting;
+   Moll_False_Northing = falseNorthing;
+   Moll_Delta_Northing = 9009965.0;
+   Moll_Max_Easting    = 18019930.0;
+   Moll_Min_Easting    = -18019930.0;
+
+   update();
+}
+
+void ossimMollweidProjection::update()
+{   
+
+   Set_Mollweide_Parameters(theEllipsoid.getA(),
+                            theEllipsoid.getFlattening(),
+                            theOrigin.lonr(),
+                            Moll_False_Easting,
+                            Moll_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimMollweidProjection::setFalseEasting(double falseEasting)
+{
+   Moll_False_Easting = falseEasting;
+   update();
+}
+
+void ossimMollweidProjection::setFalseNorthing(double falseNorthing)
+{
+   Moll_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimMollweidProjection::setDefaults()
+{
+   Moll_False_Easting  = 0.0;
+   Moll_False_Northing = 0.0;
+   Moll_Delta_Northing = 9009965.0;
+   Moll_Max_Easting    = 18019930.0;
+   Moll_Min_Easting    = -18019930.0;
+}
+
+void ossimMollweidProjection::setFalseEastingNorthing(double falseEasting,
+                                                      double falseNorthing)
+{
+   Moll_False_Easting  = falseEasting;
+   Moll_False_Northing = falseNorthing;
+   
+   update();
+}
+
+ossimGpt ossimMollweidProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Mollweide_To_Geodetic(eastingNorthing.x,
+                                 eastingNorthing.y,
+                                 &lat,
+                                 &lon);
+
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimMollweidProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Mollweide(gpt.latr(),
+                                 gpt.lonr(),
+                                 &easting,
+                                 &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+bool ossimMollweidProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Moll_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Moll_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+   
+}
+
+bool ossimMollweidProjection::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimMollweidProjection))
+   {
+      if(falseEasting)
+      {
+         Moll_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Moll_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   update();
+
+   return flag;   
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS
+ */
+
+
+long ossimMollweidProjection::Set_Mollweide_Parameters(double a,
+                                                       double f,
+                                                       double Central_Meridian,
+                                                       double False_Easting,
+                                                       double False_Northing)
+{ /* Begin Set_Mollweide_Parameters */
+/*
+ * The function Set_Mollweide_Parameters receives the ellipsoid parameters and
+ * Mollweide projcetion parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise MOLL_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double Ra;                       /* Spherical Radius */
+//  double inv_f = 1 / f;
+  long Error_Code = MOLL_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= MOLL_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= MOLL_INV_F_ERROR;
+//   }
+//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= MOLL_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Moll_a = a;
+    Moll_f = f;
+    es2 = 2 * Moll_f - Moll_f * Moll_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    /* spherical radius */
+    Ra = Moll_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 / 3024.0);
+    Sqrt2_Ra = sqrt(2.0) * Ra;
+    Sqrt8_Ra = sqrt(8.0) * Ra;
+//     if (Central_Meridian > PI)
+//       Central_Meridian -= TWO_PI;
+    Moll_Origin_Long = Central_Meridian;
+    Moll_False_Easting = False_Easting;
+    Moll_False_Northing = False_Northing;
+
+    if (Moll_Origin_Long > 0)
+    {
+      Moll_Max_Easting = 17919819.0;
+      Moll_Min_Easting = -18019930.0;
+    }
+    else if (Moll_Origin_Long < 0)
+    {
+      Moll_Max_Easting = 18019930.0;
+      Moll_Min_Easting = -17919819.0;
+    }
+    else
+    {
+      Moll_Max_Easting = 18019930.0;
+      Moll_Min_Easting = -18019930.0;
+    }
+
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Mollweide_Parameters */
+
+
+void ossimMollweidProjection::Get_Mollweide_Parameters(double *a,
+                                                       double *f,
+                                                       double *Central_Meridian,
+                                                       double *False_Easting,
+                                                       double *False_Northing)const
+{ /* Begin Get_Mollweide_Parameters */
+/*
+ * The function Get_Mollweide_Parameters returns the current ellipsoid
+ * parameters and Mollweide projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Moll_a;
+  *f = Moll_f;
+  *Central_Meridian = Moll_Origin_Long;
+  *False_Easting = Moll_False_Easting;
+  *False_Northing = Moll_False_Northing;
+  
+  return;
+} /* End Get_Mollweide_Parameters */
+
+
+long ossimMollweidProjection::Convert_Geodetic_To_Mollweide (double Latitude,
+                                                             double Longitude,
+                                                             double *Easting,
+                                                             double *Northing)const
+
+{ /* Begin Convert_Geodetic_To_Mollweide */
+/*
+ * The function Convert_Geodetic_To_Mollweide converts geodetic (latitude and
+ * longitude) coordinates to Mollweide projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Mollweide projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MOLL_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double PI_Sin_Latitude = M_PI * sin(Latitude);
+  double dlam;                                  /* Longitude - Central Meridan */
+  double theta;
+  double theta_primed = Latitude;
+  double delta_theta_primed = 0.1745329;        /* arbitrarily initialized to 10 deg */
+  double dtp_tolerance = 4.85e-10;              /* approximately 1/1000th of
+                                                 an arc second or 1/10th meter */
+  long   Error_Code = MOLL_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   {  /* Latitude out of range */
+//     Error_Code |= MOLL_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   {  /* Longitude out of range */
+//     Error_Code|= MOLL_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Moll_Origin_Long;
+//     if (dlam > PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+    while (fabs(delta_theta_primed) > dtp_tolerance)
+    {
+      delta_theta_primed = -(theta_primed + sin(theta_primed) -
+                             PI_Sin_Latitude) / (1.0 + cos(theta_primed));
+      theta_primed += delta_theta_primed;
+    }
+    theta = theta_primed / 2.0;
+    *Easting = (Sqrt8_Ra / M_PI ) * dlam * cos(theta) +
+               Moll_False_Easting;
+    *Northing = Sqrt2_Ra * sin(theta) + Moll_False_Northing;
+
+  }
+  return (Error_Code);
+
+} /* End Convert_Geodetic_To_Mollweide */
+
+
+long ossimMollweidProjection::Convert_Mollweide_To_Geodetic(double Easting,
+                                                            double Northing,
+                                                            double *Latitude,
+                                                            double *Longitude)const
+{ /* Begin Convert_Mollweide_To_Geodetic */
+/*
+ * The function Convert_Mollweide_To_Geodetic converts Mollweide projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Mollweide projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MOLL_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx, dy;
+  double theta = 0.0;
+  double two_theta;
+  double i;
+
+  long Error_Code = MOLL_NO_ERROR;
+
+//   if ((Easting < (Moll_False_Easting + Moll_Min_Easting))
+//       || (Easting > (Moll_False_Easting + Moll_Max_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= MOLL_EASTING_ERROR;
+//   }
+//   if ((Northing < (Moll_False_Northing - Moll_Delta_Northing)) || 
+//       (Northing >(Moll_False_Northing + Moll_Delta_Northing) ))
+//   { /* Northing out of range */
+//     Error_Code |= MOLL_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  {
+    dy = Northing - Moll_False_Northing;
+    dx = Easting - Moll_False_Easting;
+    i = dy / Sqrt2_Ra;
+    if (fabs(i) > 1.0)
+    {
+      *Latitude = MAX_LAT;
+      if (Northing < 0.0)
+        *Latitude *= -1.0;
+    }
+
+    else
+    {
+      theta = asin(i);
+      two_theta = 2.0 * theta;
+      *Latitude = asin((two_theta + sin(two_theta)) / M_PI);
+
+      if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+        *Latitude = PI_OVER_2;
+      else if (*Latitude < -PI_OVER_2)
+        *Latitude = -PI_OVER_2;
+
+    }
+    if (fabs(fabs(*Latitude) - MAX_LAT) < 1.0e-10)
+      *Longitude = Moll_Origin_Long;
+    else
+      *Longitude = Moll_Origin_Long + M_PI * dx /
+                   (Sqrt8_Ra * cos(theta));
+
+//     if (*Longitude > PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -PI)
+//       *Longitude += TWO_PI;
+
+//     if (*Longitude > PI)  /* force distorted values to 180, -180 degrees */
+//       *Longitude = PI;
+//     else if (*Longitude < -PI)
+//       *Longitude = -PI;
+
+
+  }
+  return (Error_Code);
+
+} /* End Convert_Mollweide_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMollweidProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMollweidProjection.h
new file mode 100644
index 0000000000..07a9a18a60
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimMollweidProjection.h
@@ -0,0 +1,188 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Mollweid projection code.  
+//*******************************************************************
+//  $Id: ossimMollweidProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimMollweidProojection_HEADER
+#define ossimMollweidProojection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimMollweidProjection : public ossimMapProjection
+{
+public:   
+   ossimMollweidProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                           const ossimGpt& origin = ossimGpt());
+   ossimMollweidProjection(const ossimEllipsoid& ellipsoid,
+                           const ossimGpt& origin,
+                           const double falseEasting,
+                           const double falseNorthing);
+   
+   ~ossimMollweidProjection(){}
+   
+   virtual ossimObject *dup()const{return new ossimMollweidProjection(*this);}
+
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();   
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return Moll_False_Easting;}
+   double getFalseNorthing()const{return Moll_False_Northing;}
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+
+   //__________________GEOTRANS______________________
+   mutable double Moll_a;                /* Semi-major axis of ellipsoid in meters */
+   mutable double Moll_f;        /* Flattening of ellipsoid */
+   mutable double es2;       /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;        /* es2 * es2	*/
+   mutable double es6;        /* es4 * es2  */
+   mutable double Sqrt2_Ra;        /* sqrt(2.0) * Spherical Radius(6371007.1810824) */
+   mutable double Sqrt8_Ra;        /* sqrt(8.0) * Spherical Radius(6371007.1810824) */
+   
+/* Mollweide projection Parameters */
+   mutable double Moll_Origin_Long;            /* Longitude of origin in radians    */
+   mutable double Moll_False_Easting;
+   mutable double Moll_False_Northing;
+   mutable double Moll_Delta_Northing;
+   mutable double Moll_Max_Easting;
+   mutable double Moll_Min_Easting;
+
+/*!
+ * The function Set_Mollweide_Parameters receives the ellipsoid parameters and
+ * Mollweide projcetion parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise MOLL_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Mollweide_Parameters(double a,
+                                double f,
+                                double Central_Meridian,
+                                double False_Easting,
+                                double False_Northing);
+
+
+/*!
+ * The function Get_Mollweide_Parameters returns the current ellipsoid
+ * parameters and Mollweide projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Mollweide_Parameters(double *a,
+                                double *f,
+                                double *Central_Meridian,
+                                double *False_Easting,
+                                double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Mollweide converts geodetic (latitude and
+ * longitude) coordinates to Mollweide projection easting, and northing
+ * coordinates, according to the current ellipsoid and Mollweide projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MOLL_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Mollweide (double Latitude,
+                                      double Longitude,
+                                      double *Easting,
+                                      double *Northing)const;
+
+
+/*!
+ * The function Convert_Mollweide_To_Geodetic converts Mollweide projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Mollweide projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise MOLL_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Mollweide_To_Geodetic(double Easting,
+                                     double Northing,
+                                     double *Latitude,
+                                     double *Longitude)const;
+   
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimNewZealandMapGridProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimNewZealandMapGridProjection.cpp
new file mode 100644
index 0000000000..2556f1b17e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimNewZealandMapGridProjection.cpp
@@ -0,0 +1,434 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimNewZealandMapGridProjection.cpp,v 1.7 2004/04/07 19:44:55 gpotts Exp $
+#include <projections/map_projections/ossimNewZealandMapGridProjection.h>
+#include <base/factory/ossimEllipsoidFactory.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimNewZealandMapGridProjection, "ossimNewZealandMapGridProjection", ossimMapProjection)
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+
+#define MAX_LAT         (-33.5 * M_PI / 180.0)    /* -33.5 degrees */
+#define MIN_LAT         (-48.5 * M_PI / 180.0)    /* -48.5 degrees */
+#define MAX_LON         (180.0 * M_PI / 180.0)    /* 180 degrees */
+#define MIN_LON         (165.5 * M_PI / 180.0)    /* 165.5 degrees */
+
+#define NZMG_NO_ERROR           0x0000
+#define NZMG_LAT_ERROR          0x0001
+#define NZMG_LON_ERROR          0x0002
+#define NZMG_EASTING_ERROR      0x0004
+#define NZMG_NORTHING_ERROR     0x0008
+#define NZMG_ELLIPSOID_ERROR    0x0010
+
+typedef struct ComplexNumber
+{
+  double real;
+  double imag;
+} Complex;
+
+static double A[] = { 0.6399175073, -0.1358797613, 0.063294409,
+                      -0.02526853, 0.0117879, -0.0055161,
+                      0.0026906, -0.001333, 0.00067, -0.00034 };
+
+static Complex B[] = { { 0.7557853228, 0.0 },
+                       { 0.249204646, 0.003371507 },
+                       { -0.001541739, 0.041058560 },
+                       { -0.10162907, 0.01727609 },
+                       { -0.26623489, -0.36249218 },
+                       { -0.6870983, -1.1651967 } };
+
+static Complex C[] = { { 1.3231270439, 0.0 },
+                       { -0.577245789, -0.007809598 },
+                       { 0.508307513, -0.112208952 },
+                       { -0.15094762, 0.18200602 },
+                       { 1.01418179, 1.64497696 },
+                       { 1.9660549, 2.5127645 } };
+
+static double D[] = { 1.5627014243, 0.5185406398, -0.03333098,
+                      -0.1052906, -0.0368594, 0.007317,
+                      0.01220, 0.00394, -0.0013 };   
+                    
+/* These state variables are for optimization purposes. The only function
+ * that should modify them is Set_NZMG_Parameters.         */
+
+/************************************************************************/
+/*                              FUNCTIONS
+ *
+ */
+
+/* Add two complex numbers */
+static Complex Add(Complex z1, Complex z2)
+{
+  Complex z;
+
+  z.real = z1.real + z2.real;
+  z.imag = z1.imag + z2.imag;
+
+  return z;
+}
+
+
+/* Multiply two complex numbers */
+static Complex Multiply(Complex z1, Complex z2)
+{
+  Complex z;
+
+  z.real = z1.real * z2.real - z1.imag * z2.imag;
+  z.imag = z1.imag * z2.real + z1.real * z2.imag;
+
+  return z;
+}
+
+
+/* Divide two complex numbers */
+static Complex Divide(Complex z1, Complex z2)
+{
+  Complex z;
+  double denom;
+
+  denom = z2.real * z2.real + z2.imag * z2.imag;
+  z.real = (z1.real * z2.real + z1.imag * z2.imag) / denom;
+  z.imag = (z1.imag * z2.real - z1.real * z2.imag) / denom;
+
+  return z;
+}
+
+ossimNewZealandMapGridProjection::ossimNewZealandMapGridProjection()
+   :ossimMapProjection(*ossimEllipsoidFactory::instance()->create("IN"),
+                       ossimGpt(-41, 173.0))
+{
+   setDefaults();
+   update();
+}
+
+ossimNewZealandMapGridProjection::~ossimNewZealandMapGridProjection()
+{
+}
+
+void ossimNewZealandMapGridProjection::setFalseEasting(double falseEasting)
+{
+   NZMG_False_Easting  = falseEasting;
+   update();
+}
+
+void ossimNewZealandMapGridProjection::setFalseNorthing(double falseNorthing)
+{
+   NZMG_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimNewZealandMapGridProjection::setFalseEastingNorthing(double falseEasting, double falseNorthing)
+{
+   NZMG_False_Easting  = falseEasting;
+   NZMG_False_Northing = falseNorthing;
+   
+   update();   
+}
+
+void ossimNewZealandMapGridProjection::setDefaults()
+{
+   theOrigin.latd(-41.0);
+   theOrigin.lond(173.0);
+
+   // origin of lat needs to be in degrees
+   NZMG_Origin_Lat     = theOrigin.latd();
+
+   // origin of lon is in radians
+   NZMG_Origin_Long    = theOrigin.lonr();
+   NZMG_Max_Easting    = 3170000.0;
+   NZMG_Max_Northing   = 6900000.0;
+   NZMG_Min_Easting    = 1810000.0;
+   NZMG_Min_Northing   = 5160000.0;
+
+   NZMG_False_Easting  = 2510000.0;
+   NZMG_False_Northing = 6023150.0;
+}
+
+void ossimNewZealandMapGridProjection::update()
+{
+   theOrigin = ossimGpt(-41, 173);
+
+   // create the new zealand datum.
+   theDatum     = ossimDatumFactory::instance()->create("GEO");
+
+   if(theDatum)
+   {
+      theEllipsoid = *(theDatum->ellipsoid());
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimNewZealandMapGridProjection::update(): Was unable to locate the newzealand datum!" << std::endl;
+   }
+   
+   NZMG_Origin_Lat   = theOrigin.latd();
+   NZMG_Origin_Long  = theOrigin.lonr();
+   NZMG_a            = theEllipsoid.getA();
+   
+   ossimMapProjection::update();
+}
+
+ossimGpt ossimNewZealandMapGridProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+
+   Convert_NZMG_To_Geodetic(eastingNorthing.x,
+                            eastingNorthing.y,
+                            &lat,
+                            &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);
+}
+
+ossimDpt ossimNewZealandMapGridProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_NZMG(gpt.latr(),
+                            gpt.lonr(),
+                            &easting,
+                            &northing);
+   
+   return ossimDpt(easting, northing); 
+}
+
+bool ossimNewZealandMapGridProjection::saveState(ossimKeywordlist& kwl,
+                                                 const char* prefix)const
+{
+   ossimMapProjection::saveState(kwl, prefix);
+
+   return true;
+}
+
+bool ossimNewZealandMapGridProjection::loadState(const ossimKeywordlist& kwl,
+                                                 const char* prefix)
+{
+   ossimKeywordlist newKwl = kwl;
+
+   // force a New Zealand Datum and the origin of lat and lon
+   // to the New Zealand.
+   newKwl.add(prefix,
+              ossimKeywordNames::DATUM_KW,
+              "GEO",
+              true);
+   
+   newKwl.add(prefix,
+              ossimKeywordNames::ORIGIN_LATITUDE_KW,
+              -41,
+              true);
+   
+   newKwl.add(prefix,
+              ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+              173.0,
+              true);
+   
+   setDefaults();
+   
+   ossimMapProjection::loadState(newKwl, prefix);
+   update();
+
+   return true;
+}
+
+long ossimNewZealandMapGridProjection::Convert_Geodetic_To_NZMG (double Latitude,
+                                                                 double Longitude,
+                                                                 double *Easting,
+                                                                 double *Northing)const
+
+{ /* BEGIN Convert_Geodetic_To_NZMG */
+/*
+ * The function Convert_Geodetic_To_NZMG converts geodetic (latitude and
+ * longitude) coordinates to New Zealand Map Grid projection (easting and northing)
+ * coordinates, according to the current ellipsoid and New Zealand Map Grid 
+ * projection parameters.  If any errors occur, the error code(s) are returned 
+ * by the function, otherwise NZMG_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi), in radians           (input)
+ *    Longitude         : Longitude (lambda), in radians       (input)
+ *    Easting           : Easting (X), in meters               (output)
+ *    Northing          : Northing (Y), in meters              (output)
+ */
+
+  Complex Zeta, z;
+  int n;
+  double dphi;
+  double du, dlam;
+  long Error_Code = NZMG_NO_ERROR;
+
+//   if ((Latitude < MIN_LAT) || (Latitude > MAX_LAT))
+//   {  /* Latitude out of range */
+//     Error_Code|= NZMG_LAT_ERROR;
+//   }
+//   if ((Longitude < MIN_LON) || (Longitude > MAX_LON))
+//   {  /* Longitude out of range */
+//     Error_Code|= NZMG_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+    dphi = (Latitude * (180.0 / M_PI) - NZMG_Origin_Lat) * 3600.0 * 1.0e-5;
+    du = A[9];
+    for (n = 8; n >= 0; n--)
+      du = du * dphi + A[n];
+    du *= dphi;
+
+    dlam = Longitude - NZMG_Origin_Long;
+
+    Zeta.real = du;
+    Zeta.imag = dlam;
+
+    z.real = B[5].real;
+    z.imag = B[5].imag;
+    for (n = 4; n >= 0; n--)
+    {
+      z = Multiply(z, Zeta);
+      z = Add(B[n], z);
+    }
+    z = Multiply(z, Zeta);
+
+    *Easting = (z.imag * NZMG_a) + NZMG_False_Easting;
+    *Northing = (z.real * NZMG_a) + NZMG_False_Northing;
+
+//     if ((*Easting < NZMG_Min_Easting) || (*Easting > NZMG_Max_Easting)) 
+//       Error_Code |= NZMG_EASTING_ERROR;
+//     if ((*Northing < NZMG_Min_Northing) || (*Northing > NZMG_Max_Northing))
+//       Error_Code |= NZMG_NORTHING_ERROR;
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_NZMG */
+
+
+long ossimNewZealandMapGridProjection::Convert_NZMG_To_Geodetic(double Easting,
+                                                                double Northing,
+                                                                double *Latitude,
+                                                                double *Longitude)const
+
+{ /* Begin Convert_NZMG_To_Geodetic */
+/*
+ * The function Convert_NZMG_To_Geodetic converts New Zealand Map Grid projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and New Zealand Map Grid projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise NZMG_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X), in meters                  (input)
+ *    Northing          : Northing (Y), in meters                 (input)
+ *    Latitude          : Latitude (phi), in radians              (output)
+ *    Longitude         : Longitude (lambda), in radians          (output)
+ */
+
+  int i, n;
+  Complex coeff;
+  Complex z, Zeta, Zeta_Numer, Zeta_Denom, Zeta_sqr;
+  double dphi;
+  long Error_Code = NZMG_NO_ERROR; 
+
+//   if ((Easting < NZMG_Min_Easting) || (Easting > NZMG_Max_Easting)) 
+//   { /* Easting out of range  */
+//     Error_Code |= NZMG_EASTING_ERROR;
+//   }
+//   if ((Northing < NZMG_Min_Northing) || (Northing > NZMG_Max_Northing))
+//   { /* Northing out of range */
+//     Error_Code |= NZMG_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+    z.real = (Northing - NZMG_False_Northing) / NZMG_a;
+    z.imag = (Easting - NZMG_False_Easting) / NZMG_a;
+
+    Zeta.real = C[5].real;
+    Zeta.imag = C[5].imag;
+    for (n = 4; n >= 0; n--)
+    {
+      Zeta = Multiply(Zeta, z);
+      Zeta = Add(C[n], Zeta);
+    }
+    Zeta = Multiply(Zeta, z);
+
+    for (i = 0; i < 2; i++)
+    {
+      Zeta_Numer.real = 5.0 * B[5].real;
+      Zeta_Numer.imag = 5.0 * B[5].imag;
+      Zeta_Denom.real = 6.0 * B[5].real;
+      Zeta_Denom.imag = 6.0 * B[5].imag;
+      for (n = 4; n >= 1; n--)
+      {
+        Zeta_Numer = Multiply(Zeta_Numer, Zeta);
+        coeff.real = n * B[n].real;
+        coeff.imag = n * B[n].imag;
+        Zeta_Numer = Add(coeff, Zeta_Numer); 
+
+        Zeta_Denom = Multiply(Zeta_Denom, Zeta);
+        coeff.real = (n+1) * B[n].real;
+        coeff.imag = (n+1) * B[n].imag;
+        Zeta_Denom = Add(coeff, Zeta_Denom);
+      }
+      Zeta_sqr = Multiply(Zeta, Zeta);
+
+      Zeta_Numer = Multiply(Zeta_Numer, Zeta_sqr);
+      Zeta_Numer = Add(z, Zeta_Numer);
+
+      Zeta_Denom = Multiply(Zeta_Denom, Zeta);
+      Zeta_Denom = Add(B[0], Zeta_Denom);
+
+      Zeta = Divide(Zeta_Numer, Zeta_Denom);  
+    }
+    dphi = D[8];
+    for (n = 7; n >= 0; n--)
+      dphi = dphi * Zeta.real + D[n];
+    dphi *= Zeta.real;
+      
+    *Latitude = NZMG_Origin_Lat + (dphi * 1.0e5 / 3600.0);
+    *Latitude *= M_PI / 180.0;
+    *Longitude = NZMG_Origin_Long + Zeta.imag;
+
+//     if ((*Longitude > M_PI) && (*Longitude - M_PI < 1.0e-6))
+//       *Longitude = M_PI;
+
+//     if ((*Latitude < MIN_LAT) || (*Latitude > MAX_LAT))
+//       Error_Code|= NZMG_LAT_ERROR;
+//     if ((*Longitude < MIN_LON) || (*Longitude > MAX_LON))
+//       Error_Code|= NZMG_LON_ERROR;
+  }
+  return (Error_Code);
+} /* END OF Convert_NZMG_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimNewZealandMapGridProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimNewZealandMapGridProjection.h
new file mode 100644
index 0000000000..c5b68dd44d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimNewZealandMapGridProjection.h
@@ -0,0 +1,135 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimNewZealandMapGridProjection.h,v 1.3 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimNewZealandMapGridProjection_HEADER
+#define ossimNewZealandMapGridProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+
+class ossimNewZealandMapGridProjection : public ossimMapProjection
+{
+public:
+   ossimNewZealandMapGridProjection();
+   ~ossimNewZealandMapGridProjection();
+   virtual ossimObject* dup()const
+      {
+         return new ossimNewZealandMapGridProjection(*this);
+      }
+   virtual void update();   
+
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+  
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return  NZMG_False_Easting;}
+   double getFalseNorthing()const{return NZMG_False_Northing;}
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+protected:
+
+   // these should be set to constant values that never change.  The origin
+   // will be fixed and the false easting northings will also be fixed.
+   //
+   mutable double NZMG_Origin_Lat;             /* Latitude of origin, in radians */
+   mutable double NZMG_Origin_Long;            /* Longitude of origin, in radians */
+   mutable double NZMG_False_Northing;         /* False northing, in meters */
+   mutable double NZMG_False_Easting;          /* False easting, in meters */
+   mutable double NZMG_a;
+/* Maximum variance for easting and northing values for International. */
+   mutable double NZMG_Max_Easting;
+   mutable double NZMG_Max_Northing;
+   mutable double NZMG_Min_Easting;
+   mutable double NZMG_Min_Northing;
+
+/*!
+ * The function Convert_Geodetic_To_NZMG converts geodetic (latitude and
+ * longitude) coordinates to New Zealand Map Grid projection (easting and northing)
+ * coordinates, according to the current ellipsoid and New Zealand Map Grid 
+ * projection parameters.  If any errors occur, the error code(s) are returned 
+ * by the function, otherwise NZMG_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi), in radians           (input)
+ *    Longitude         : Longitude (lambda), in radians       (input)
+ *    Easting           : Easting (X), in meters               (output)
+ *    Northing          : Northing (Y), in meters              (output)
+ */
+   long Convert_Geodetic_To_NZMG (double Latitude,
+                                  double Longitude,
+                                  double *Easting,
+                                  double *Northing)const;
+
+
+
+/*!
+ * The function Convert_NZMG_To_Geodetic converts New Zealand Map Grid projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and New Zealand Map Grid projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise NZMG_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X), in meters                  (input)
+ *    Northing          : Northing (Y), in meters                 (input)
+ *    Latitude          : Latitude (phi), in radians              (output)
+ *    Longitude         : Longitude (lambda), in radians          (output)
+ */
+   long Convert_NZMG_To_Geodetic(double Easting,
+                                 double Northing,
+                                 double *Latitude,
+                                 double *Longitude)const;
+   
+TYPE_DATA   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimObliqueMercatorProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimObliqueMercatorProjection.cpp
new file mode 100644
index 0000000000..5d1f2dd691
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimObliqueMercatorProjection.cpp
@@ -0,0 +1,734 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimObliqueMercatorProjection.cpp,v 1.5 2004/01/08 21:49:22 jlargent Exp $
+#include "ossimObliqueMercatorProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+#define OMERC_NO_ERROR                0x0000
+#define OMERC_LAT_ERROR               0x0001
+#define OMERC_LON_ERROR               0x0002
+#define OMERC_ORIGIN_LAT_ERROR        0x0004
+#define OMERC_LAT1_ERROR              0x0008
+#define OMERC_LAT2_ERROR              0x0010
+#define OMERC_LON1_ERROR              0x0020
+#define OMERC_LON2_ERROR              0x0040
+#define OMERC_LAT1_LAT2_ERROR         0x0080
+#define OMERC_DIFF_HEMISPHERE_ERROR   0x0100
+#define OMERC_EASTING_ERROR           0x0200
+#define OMERC_NORTHING_ERROR          0x0400
+#define OMERC_A_ERROR                 0x0800
+#define OMERC_INV_F_ERROR             0x1000
+#define OMERC_SCALE_FACTOR_ERROR      0x2000
+#define OMERC_LON_WARNING             0x4000
+
+RTTI_DEF1(ossimObliqueMercatorProjection, "ossimObliqueMercatorProjection", ossimMapProjection)
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef PI_OVER_4
+#  define PI_OVER_4  ( M_PI / 4.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define MIN_SCALE_FACTOR  0.3
+#define MAX_SCALE_FACTOR  3.0
+   
+#define OMERC_t(lat, e_sinlat, e_over_2)  (tan(PI_OVER_4 - lat / 2.0)) /         \
+                      (pow((1 - e_sinlat) / (1 + e_sinlat), e_over_2))
+
+
+ossimObliqueMercatorProjection::ossimObliqueMercatorProjection(const ossimEllipsoid& ellipsoid,
+                                                               const ossimGpt& origin)
+   : ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimObliqueMercatorProjection::ossimObliqueMercatorProjection(const ossimEllipsoid& ellipsoid,
+                                                               const ossimGpt& origin,
+                                                               const ossimGpt& point1,
+                                                               const ossimGpt& point2,
+                                                               double falseEasting,
+                                                               double falseNorthing,
+                                                               double scaleFactor)
+   : ossimMapProjection(ellipsoid, origin)
+{
+   setParameters(point1, point2, falseEasting, falseNorthing, scaleFactor);
+}
+
+void ossimObliqueMercatorProjection::update()
+{
+   Set_Oblique_Mercator_Parameters(theEllipsoid.getA(),
+                                   theEllipsoid.getFlattening(),
+                                   theOrigin.latr(),
+                                   theCentralPoint1.latr(),
+                                   theCentralPoint1.lonr(),
+                                   theCentralPoint2.latr(),
+                                   theCentralPoint2.lonr(),
+                                   OMerc_False_Easting,
+                                   OMerc_False_Northing,
+                                   OMerc_Scale_Factor);
+
+   ossimMapProjection::update();
+}
+
+void ossimObliqueMercatorProjection::setFalseEasting(double falseEasting)
+{
+   OMerc_False_Easting = falseEasting;
+   update();
+}
+
+void ossimObliqueMercatorProjection::setFalseNorthing(double falseNorthing)
+{
+   OMerc_False_Northing = falseNorthing;
+   update();  
+}
+
+void ossimObliqueMercatorProjection::setFalseEastingNorthing(double falseEasting, double falseNorthing)
+{
+   OMerc_False_Easting = falseEasting;
+   OMerc_False_Northing = falseNorthing;
+   update();  
+   
+}
+
+void ossimObliqueMercatorProjection::setCentralPoint1(const ossimGpt& point)
+{
+   theCentralPoint1 = point;
+
+   update();
+}
+
+void ossimObliqueMercatorProjection::setCentralPoint2(const ossimGpt& point)
+{
+   theCentralPoint2 = point;
+   update();
+}
+
+void ossimObliqueMercatorProjection::setScaleFactor(double scaleFactor)
+{
+   OMerc_Scale_Factor = scaleFactor;
+   update();
+}
+
+void ossimObliqueMercatorProjection::setParameters(const ossimGpt& point1,
+                                                   const ossimGpt& point2,
+                                                   double falseEasting,
+                                                   double falseNorthing,
+                                                   double scaleFactor)
+{
+   theCentralPoint1 = point1;
+   theCentralPoint2 = point2;
+   OMerc_False_Easting = falseEasting;
+   OMerc_False_Northing = falseNorthing;
+   OMerc_Scale_Factor = scaleFactor;
+
+   update();
+}
+
+void ossimObliqueMercatorProjection::setDefaults()
+{
+   // initialize the central points to be 5 degrees about the origin.
+   OMerc_Delta_Northing = 40000000.0;
+   OMerc_Delta_Easting  = 40000000.0;
+
+   theCentralPoint1.latd(theOrigin.latd() - 5.0);
+   theCentralPoint1.lond(theOrigin.lond() - 5.0);
+   theCentralPoint2.latd(theOrigin.latd() + 5.0);
+   theCentralPoint2.lond(theOrigin.lond() + 5.0);
+   
+   theCentralPoint1.clampLat(-90.0, 90.0);
+   theCentralPoint1.clampLon(-180.0, 180.0);
+   theCentralPoint2.clampLat(-90.0, 90.0);
+   theCentralPoint2.clampLon(-180.0, 180.0);
+   
+   OMerc_False_Easting  = 0.0;
+   OMerc_False_Northing = 0.0;
+
+   OMerc_Scale_Factor   = 1.0;
+}
+
+
+ossimGpt ossimObliqueMercatorProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Oblique_Mercator_To_Geodetic(eastingNorthing.x,
+                                        eastingNorthing.y,
+                                        &lat,
+                                        &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimObliqueMercatorProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Oblique_Mercator(gpt.latr(),
+                                        gpt.lonr(),
+                                        &easting,
+                                        &northing);
+   return ossimDpt(easting, northing);
+}
+
+bool ossimObliqueMercatorProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           OMerc_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           OMerc_False_Northing,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_FACTOR_KW,
+           OMerc_Scale_Factor,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CENTRAL_POINT1_LAT_KW,
+           theCentralPoint1.latd(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CENTRAL_POINT1_LON_KW,
+           theCentralPoint1.lond(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CENTRAL_POINT2_LAT_KW,
+           theCentralPoint2.latd(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::CENTRAL_POINT2_LON_KW,
+           theCentralPoint2.lond(),
+           true);
+           
+   
+   return ossimMapProjection::saveState(kwl, prefix);   
+}
+
+bool ossimObliqueMercatorProjection::loadState(const ossimKeywordlist& kwl,
+                                             const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   const char* point1Lat     = kwl.find(prefix, ossimKeywordNames::CENTRAL_POINT1_LAT_KW);
+   const char* point1Lon     = kwl.find(prefix, ossimKeywordNames::CENTRAL_POINT1_LON_KW);
+   const char* point2Lat     = kwl.find(prefix, ossimKeywordNames::CENTRAL_POINT2_LAT_KW);
+   const char* point2Lon     = kwl.find(prefix, ossimKeywordNames::CENTRAL_POINT2_LON_KW);
+   const char* scale         = kwl.find(prefix, ossimKeywordNames::SCALE_FACTOR_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimObliqueMercatorProjection))
+   {
+      if(falseEasting)
+      {
+         OMerc_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         OMerc_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+      if(point1Lat&&point1Lon&&point2Lat&&point2Lon)
+      {
+         theCentralPoint1.latd(ossimString(point1Lat).toDouble());
+         theCentralPoint1.lond(ossimString(point1Lon).toDouble());
+         theCentralPoint2.latd(ossimString(point2Lat).toDouble());
+         theCentralPoint2.lond(ossimString(point2Lon).toDouble());
+      }
+      if(scale)
+      {
+         OMerc_Scale_Factor = ossimString(scale).toDouble();
+      }
+   }
+   
+   update();
+
+   return flag;
+
+}
+
+/*
+ *                              FUNCTIONS     
+ */
+
+long ossimObliqueMercatorProjection::Set_Oblique_Mercator_Parameters(double a,
+                                                                     double f,
+                                                                     double Origin_Latitude,
+                                                                     double Latitude_1,
+                                                                     double Longitude_1,
+                                                                     double Latitude_2,
+                                                                     double Longitude_2,
+                                                                     double False_Easting,
+                                                                     double False_Northing,
+                                                                     double Scale_Factor)
+{ /* BEGIN Set_Oblique_Mercator_Parameters */
+/*
+ * The function Set_Oblique_Mercator_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise OMERC_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters  (input)
+ *    f                 : Flattening of ellipsoid                  (input)
+ *    Origin_Latitude   : Latitude, in radians, at which the       (input)
+ *                          point scale factor is 1.0
+ *    Latitude_1        : Latitude, in radians, of first point lying on
+ *                          central line                           (input)
+ *    Longitude_1       : Longitude, in radians, of first point lying on
+ *                          central line                           (input)
+ *    Latitude_2        : Latitude, in radians, of second point lying on
+ *                          central line                           (input)
+ *    Longitude_2       : Longitude, in radians, of second point lying on
+ *                          central line                           (input)
+ *    False_Easting     : A coordinate value, in meters, assigned to the
+ *                          central meridian of the projection     (input)
+ *    False_Northing    : A coordinate value, in meters, assigned to the
+ *                          origin latitude of the projection      (input)
+ *    Scale_Factor      : Multiplier which reduces distances in the
+ *                          projection to the actual distance on the
+ *                          ellipsoid                              (input)
+ */
+
+//  double inv_f = 1 / f;
+  double es2, one_MINUS_es2;
+  double cos_olat, cos_olat2;
+  double sin_olat, sin_olat2, es2_sin_olat2;
+  double t0, t1, t2;
+  double D, D2, D2_MINUS_1, sqrt_D2_MINUS_1;
+  double H, L, LH;
+  double E2;
+  double F, G, J, P;
+  double dlon;
+  long Error_Code = OMERC_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= OMERC_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= OMERC_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude <= -PI_OVER_2) || (Origin_Latitude >= PI_OVER_2))
+//   { /* origin latitude out of range -  can not be at a pole */
+//     Error_Code |= OMERC_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Latitude_1 <= -PI_OVER_2) || (Latitude_1 >= PI_OVER_2))
+//   { /* first latitude out of range -  can not be at a pole */
+//     Error_Code |= OMERC_LAT1_ERROR;
+//   }
+//   if ((Latitude_2 <= -PI_OVER_2) || (Latitude_2 >= PI_OVER_2))
+//   { /* second latitude out of range -  can not be at a pole */
+//     Error_Code |= OMERC_LAT2_ERROR;
+//   }
+//   if (Latitude_1 == 0.0)
+//   { /* first latitude can not be at the equator */
+//     Error_Code |= OMERC_LAT1_ERROR;
+//   }
+//   if (Latitude_1 == Latitude_2)
+//   { /* first and second latitudes can not be equal */
+//     Error_Code |= OMERC_LAT1_LAT2_ERROR;
+//   }
+//   if (((Latitude_1 < 0.0) && (Latitude_2 > 0.0)) ||
+//       ((Latitude_1 > 0.0) && (Latitude_2 < 0.0)))
+//   { /*first and second points can not be in different hemispheres */
+//     Error_Code |= OMERC_DIFF_HEMISPHERE_ERROR;
+//   }
+//   if ((Longitude_1 < -PI) || (Longitude_1 > TWO_PI))
+//   { /* first longitude out of range */
+//     Error_Code |= OMERC_LON1_ERROR;
+//   }
+//   if ((Longitude_2 < -PI) || (Longitude_2 > TWO_PI))
+//   { /* first longitude out of range */
+//     Error_Code |= OMERC_LON2_ERROR;
+//   }
+//   if ((Scale_Factor < MIN_SCALE_FACTOR) || (Scale_Factor > MAX_SCALE_FACTOR))
+//   { /* scale factor out of range */
+//     Error_Code |= OMERC_SCALE_FACTOR_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+
+    OMerc_a = a;
+    OMerc_f = f;
+    OMerc_Origin_Lat = Origin_Latitude;
+    OMerc_Lat_1 = Latitude_1;
+    OMerc_Lat_2 = Latitude_2;
+    OMerc_Lon_1 = Longitude_1;
+    OMerc_Lon_2 = Longitude_2;
+    OMerc_Scale_Factor = Scale_Factor;
+    OMerc_False_Northing = False_Northing;
+    OMerc_False_Easting = False_Easting;
+
+    es2 = 2 * OMerc_f - OMerc_f * OMerc_f;
+    es = sqrt(es2);
+    one_MINUS_es2 = 1 - es2;
+    es_OVER_2 = es / 2.0;
+
+    cos_olat = cos(OMerc_Origin_Lat);
+    cos_olat2 = cos_olat * cos_olat;
+    sin_olat = sin(OMerc_Origin_Lat);
+    sin_olat2 = sin_olat * sin_olat;
+    es2_sin_olat2 = es2 * sin_olat2;
+
+    OMerc_B = sqrt(1 + (es2 * cos_olat2 * cos_olat2) / one_MINUS_es2);
+    OMerc_A = (OMerc_a * OMerc_B * OMerc_Scale_Factor * sqrt(one_MINUS_es2)) / (1.0 - es2_sin_olat2);  
+    A_over_B = OMerc_A / OMerc_B;
+    B_over_A = OMerc_B / OMerc_A;
+
+    t0 = OMERC_t(OMerc_Origin_Lat, es * sin_olat, es_OVER_2);
+    t1 = OMERC_t(OMerc_Lat_1, es * sin(OMerc_Lat_1), es_OVER_2);  
+    t2 = OMERC_t(OMerc_Lat_2, es * sin(OMerc_Lat_2), es_OVER_2);  
+
+    D = (OMerc_B * sqrt(one_MINUS_es2)) / (cos_olat * sqrt(1.0 - es2_sin_olat2)); 
+    D2 = D * D;
+    if (D2 < 1.0)
+      D2 = 1.0;
+    D2_MINUS_1 = D2 - 1.0;
+    sqrt_D2_MINUS_1 = sqrt(D2_MINUS_1);
+    if (D2_MINUS_1 > 1.0e-10)
+    {
+      if (OMerc_Origin_Lat >= 0.0)
+        OMerc_E = (D + sqrt_D2_MINUS_1) * pow(t0, OMerc_B);
+      else
+        OMerc_E = (D - sqrt_D2_MINUS_1) * pow(t0, OMerc_B);
+    }
+    else
+      OMerc_E = D * pow(t0, OMerc_B);
+    H = pow(t1, OMerc_B);
+    L = pow(t2, OMerc_B);
+    F = OMerc_E / H;
+    G = (F - 1.0 / F) / 2.0;
+    E2 = OMerc_E * OMerc_E;
+    LH = L * H;
+    J = (E2 - LH) / (E2 + LH);
+    P = (L - H) / (L + H);
+
+    dlon = OMerc_Lon_1 - OMerc_Lon_2;
+    if (dlon < -M_PI )
+      OMerc_Lon_2 -= TWO_PI;
+    if (dlon > M_PI)
+      OMerc_Lon_2 += TWO_PI;
+    dlon = OMerc_Lon_1 - OMerc_Lon_2;
+    OMerc_Origin_Long = (OMerc_Lon_1 + OMerc_Lon_2) / 2.0 - (atan(J * tan(OMerc_B * dlon / 2.0) / P)) / OMerc_B;
+
+    dlon = OMerc_Lon_1 - OMerc_Origin_Long;
+//     if (dlon < -M_PI )
+//       OMerc_Origin_Long -= TWO_PI;
+//     if (dlon > M_PI)
+//       OMerc_Origin_Long += TWO_PI;
+   
+    dlon = OMerc_Lon_1 - OMerc_Origin_Long;
+    OMerc_gamma = atan(sin(OMerc_B * dlon) / G);
+    cos_gamma = cos(OMerc_gamma);
+    sin_gamma = sin(OMerc_gamma);
+  
+    OMerc_azimuth = asin(D * sin_gamma);
+    cos_azimuth = cos(OMerc_azimuth);
+    sin_azimuth = sin(OMerc_azimuth);
+
+   if (OMerc_Origin_Lat >= 0)
+      OMerc_u =  A_over_B * atan(sqrt_D2_MINUS_1/cos_azimuth);
+   else
+      OMerc_u = -A_over_B * atan(sqrt_D2_MINUS_1/cos_azimuth);
+
+  } /* End if(!Error_Code) */
+  return (Error_Code);
+} /* End Set_Oblique_Mercator_Parameters */
+
+void ossimObliqueMercatorProjection::Get_Oblique_Mercator_Parameters(double *a,
+                                                                     double *f,
+                                                                     double *Origin_Latitude,
+                                                                     double *Latitude_1,
+                                                                     double *Longitude_1,
+                                                                     double *Latitude_2,
+                                                                     double *Longitude_2,
+                                                                     double *False_Easting,
+                                                                     double *False_Northing,
+                                                                     double *Scale_Factor)const
+{ /* Begin Get_Oblique_Mercator_Parameters */
+/*
+ * The function Get_Oblique_Mercator_Parameters returns the current ellipsoid
+ * parameters and Oblique Mercator projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters  (output)
+ *    f                 : Flattening of ellipsoid                  (output)
+ *    Origin_Latitude   : Latitude, in radians, at which the       (output)
+ *                          point scale factor is 1.0
+ *    Latitude_1        : Latitude, in radians, of first point lying on
+ *                          central line                           (output)
+ *    Longitude_1       : Longitude, in radians, of first point lying on
+ *                          central line                           (output)
+ *    Latitude_2        : Latitude, in radians, of second point lying on
+ *                          central line                           (output)
+ *    Longitude_2       : Longitude, in radians, of second point lying on
+ *                          central line                           (output)
+ *    False_Easting     : A coordinate value, in meters, assigned to the
+ *                          central meridian of the projection     (output)
+ *    False_Northing    : A coordinate value, in meters, assigned to the
+ *                          origin latitude of the projection      (output)
+ *    Scale_Factor      : Multiplier which reduces distances in the
+ *                          projection to the actual distance on the
+ *                          ellipsoid                              (output)
+ */
+
+  *a = OMerc_a;
+  *f = OMerc_f;
+  *Origin_Latitude = OMerc_Origin_Lat;
+  *Latitude_1 = OMerc_Lat_1;
+  *Longitude_1 = OMerc_Lon_1;
+  *Latitude_2 = OMerc_Lat_2;
+  *Longitude_2 = OMerc_Lon_2;
+  *Scale_Factor = OMerc_Scale_Factor;
+  *False_Easting = OMerc_False_Easting;
+  *False_Northing = OMerc_False_Northing;
+  
+  return;
+} /* End Get_Azimuthal_Equidistant_Parameters */
+
+long ossimObliqueMercatorProjection::Convert_Geodetic_To_Oblique_Mercator(double Latitude,
+                                                                          double Longitude,
+                                                                          double *Easting,
+                                                                          double *Northing)const
+{ /* BEGIN Convert_Geodetic_To_Oblique_Mercator */
+/*
+ * The function Convert_Geodetic_To_Oblique_Mercator converts geodetic (latitude and
+ * longitude) coordinates to Oblique Mercator projection (easting and
+ * northing) coordinates, according to the current ellipsoid and Oblique Mercator 
+ * projection parameters.  If any errors occur, the error code(s) are returned 
+ * by the function, otherwise OMERC_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi), in radians           (input)
+ *    Longitude         : Longitude (lambda), in radians       (input)
+ *    Easting           : Easting (X), in meters               (output)
+ *    Northing          : Northing (Y), in meters              (output)
+ */
+
+  double dlam, B_dlam, cos_B_dlam;
+  double t, S, T, V, U;
+  double Q, Q_inv;
+  /* Coordinate axes defined with respect to the azimuth of the center line */
+  /* Natural origin*/
+  double v = 0;
+  double u = 0;
+  long Error_Code = OMERC_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   { /* Latitude out of range */
+//     Error_Code |= OMERC_LAT_ERROR;
+//   }
+//   if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+//   { /* Longitude out of range */
+//     Error_Code |= OMERC_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - OMerc_Origin_Long;
+
+//     if (fabs(dlam) >= PI_OVER_2)
+//     { /* Distortion will result if Longitude is 90 degrees or more from the Central Meridian */
+//       Error_Code |= OMERC_LON_WARNING;
+//     }
+
+//     if (dlam > M_PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -M_PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+
+    if (fabs(fabs(Latitude) - PI_OVER_2) > 1.0e-10)
+    {
+      t = OMERC_t(Latitude, es * sin(Latitude), es_OVER_2);  
+      Q = OMerc_E / pow(t, OMerc_B);
+      Q_inv = 1.0 / Q;
+      S = (Q - Q_inv) / 2.0;
+      T = (Q + Q_inv) / 2.0;
+      B_dlam = OMerc_B * dlam;
+      V = sin(B_dlam);
+      U = ((-1.0 * V * cos_gamma) + (S * sin_gamma)) / T;
+      if (fabs(fabs(U) - 1.0) < 1.0e-10)
+      { /* Point projects into infinity */
+        Error_Code |= OMERC_LON_ERROR;
+      }
+      else
+      {
+        v = A_over_B * log((1.0 - U) / (1.0 + U)) / 2.0;
+        cos_B_dlam = cos(B_dlam);
+        if (fabs(cos_B_dlam) < 1.0e-10)
+          u = OMerc_A * B_dlam;
+        else
+          u = A_over_B * atan(((S * cos_gamma) + (V * sin_gamma)) / cos_B_dlam);
+      }
+    }
+    else
+    {
+      if (Latitude > 0.0)
+        v = A_over_B * log(tan(PI_OVER_4 - (OMerc_gamma / 2.0)));
+      else
+        v = A_over_B * log(tan(PI_OVER_4 + (OMerc_gamma / 2.0)));
+      u = A_over_B * Latitude;
+    }
+
+
+    u = u - OMerc_u;
+
+    *Easting  = OMerc_False_Easting + v * cos_azimuth + u * sin_azimuth;
+    *Northing = OMerc_False_Northing + u * cos_azimuth - v * sin_azimuth;
+
+  }
+  return (Error_Code);
+} /* End Convert_Geodetic_To_Oblique_Mercator */
+
+
+long ossimObliqueMercatorProjection::Convert_Oblique_Mercator_To_Geodetic(double Easting,
+                                                                          double Northing,
+                                                                          double *Latitude,
+                                                                          double *Longitude)const
+{ /* Begin Convert_Oblique_Mercator_To_Geodetic */
+/*
+ * The function Convert_Oblique_Mercator_To_Geodetic converts Oblique Mercator projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Oblique Mercator projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise OMERC_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X), in meters                  (input)
+ *    Northing          : Northing (Y), in meters                 (input)
+ *    Latitude          : Latitude (phi), in radians              (output)
+ *    Longitude         : Longitude (lambda), in radians          (output)
+ */
+
+  double dx, dy;
+  /* Coordinate axes defined with respect to the azimuth of the center line */
+  /* Natural origin*/
+  double u, v;
+  double Q_prime, Q_prime_inv;
+  double S_prime, T_prime, V_prime, U_prime;
+  double t;
+  double es_sin;
+  double u_B_over_A;
+  double phi;
+  double temp_phi = 0.0;
+  long Error_Code = OMERC_NO_ERROR; 
+
+//   if ((Easting < (OMerc_False_Easting - OMerc_Delta_Easting)) 
+//       || (Easting > (OMerc_False_Easting + OMerc_Delta_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= OMERC_EASTING_ERROR;
+//   }
+//   if ((Northing < (OMerc_False_Northing - OMerc_Delta_Northing)) 
+//       || (Northing > (OMerc_False_Northing + OMerc_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= OMERC_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  {
+    dy = Northing - OMerc_False_Northing;
+    dx = Easting - OMerc_False_Easting;
+    v = dx * cos_azimuth - dy * sin_azimuth;
+    u = dy * cos_azimuth + dx * sin_azimuth;
+    u = u + OMerc_u;
+    Q_prime = exp(-1.0 * (v * B_over_A ));
+    Q_prime_inv = 1.0 / Q_prime;
+    S_prime = (Q_prime - Q_prime_inv) / 2.0;
+    T_prime = (Q_prime + Q_prime_inv) / 2.0;
+    u_B_over_A = u * B_over_A;
+    V_prime = sin(u_B_over_A);
+    U_prime = (V_prime * cos_gamma + S_prime * sin_gamma) / T_prime;
+    if (fabs(fabs(U_prime) - 1.0) < 1.0e-10)
+    {
+      if (U_prime > 0)
+        *Latitude = PI_OVER_2;
+      else
+        *Latitude = -PI_OVER_2;
+      *Longitude = OMerc_Origin_Long;
+    }
+    else
+    {
+      t = pow(OMerc_E / sqrt((1.0 + U_prime) / (1.0 - U_prime)), 1.0 / OMerc_B);
+      phi = PI_OVER_2 - 2.0 * atan(t);
+      while (fabs(phi - temp_phi) > 1.0e-10)
+      {
+        temp_phi = phi;
+        es_sin = es * sin(phi);
+        phi = PI_OVER_2 - 2.0 * atan(t * pow((1.0 - es_sin) / (1.0 + es_sin), es_OVER_2));
+      }
+      *Latitude = phi;
+      *Longitude = OMerc_Origin_Long - atan2((S_prime * cos_gamma - V_prime * sin_gamma), cos(u_B_over_A)) / OMerc_B;
+    }
+
+//     if (fabs(*Latitude) < 2.0e-7)  /* force lat to 0 to avoid -0 degrees */
+//       *Latitude = 0.0;
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+
+//     if (*Longitude > PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -PI)
+//       *Longitude += TWO_PI;
+
+//     if (fabs(*Longitude) < 2.0e-7)  /* force lon to 0 to avoid -0 degrees */
+//       *Longitude = 0.0;
+//     if (*Longitude > PI)  /* force distorted values to 180, -180 degrees */
+//       *Longitude = PI;
+//     else if (*Longitude < -PI)
+//       *Longitude = -PI;
+
+//     if (fabs(*Longitude - OMerc_Origin_Long) >= PI_OVER_2)
+//     { /* Distortion will result if Longitude is 90 degrees or more from the Central Meridian */
+//       Error_Code |= OMERC_LON_WARNING;
+//     }
+
+  }
+  return (Error_Code);
+} /* End Convert_Oblique_Mercator_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimObliqueMercatorProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimObliqueMercatorProjection.h
new file mode 100644
index 0000000000..c8dd252d79
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimObliqueMercatorProjection.h
@@ -0,0 +1,256 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimObliqueMercatorProjection.h,v 1.2 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimObliqueMercatorProjection_HEADER
+#define ossimObliqueMercatorProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimObliqueMercatorProjection : public ossimMapProjection
+{
+public:   
+   ossimObliqueMercatorProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                                  const ossimGpt& origin = ossimGpt());
+
+   /*!
+    * Points 1 and 2 lie along the central line.
+    */
+   ossimObliqueMercatorProjection(const ossimEllipsoid& ellipsoid,
+                                  const ossimGpt& origin,
+                                  const ossimGpt& point1,
+                                  const ossimGpt& point2,
+                                  double falseEasting,
+                                  double falseNorthing,
+                                  double scaleFactor);
+   
+   ~ossimObliqueMercatorProjection(){}
+   virtual ossimObject *dup()const
+      {
+         return new ossimObliqueMercatorProjection(*this);
+      }
+   
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+   
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+   
+   void setCentralPoint1(const ossimGpt& point);
+   void setCentralPoint2(const ossimGpt& point);
+   void setScaleFactor(double scaleFactor);
+   
+   void setParameters(const ossimGpt& point1,
+                      const ossimGpt& point2,
+                      double falseEasting,
+                      double falseNorthing,
+                      double scaleFactor);
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+   
+   void setDefaults();
+   
+   double getFalseEasting()const{return  OMerc_False_Easting;}
+   double getFalseNorthing()const{return OMerc_False_Northing;}
+   const ossimGpt& getCentralPoint1()const{return theCentralPoint1;}
+   const ossimGpt& getCentralPoint2()const{return theCentralPoint2;}
+   double getScaleFactor()const{return OMerc_Scale_Factor;}
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+protected:
+
+   ossimGpt theCentralPoint1;
+   ossimGpt theCentralPoint2;
+
+//________________________GEOTRANS STUFF_____________________________________
+   
+   mutable double OMerc_a;                   /* Semi-major axis of ellipsoid, in meters */
+   mutable double OMerc_f;           /* Flattening of ellipsoid */
+   mutable double es;
+   mutable double es_OVER_2;
+   mutable double OMerc_A;
+   mutable double OMerc_B;
+   mutable double OMerc_E;
+   mutable double OMerc_gamma;
+   mutable double OMerc_azimuth;       /* Azimuth of central line as it crosses origin lat */
+   mutable double OMerc_Origin_Long;  /* Longitude at center of projection */
+   mutable double cos_gamma;
+   mutable double sin_gamma;
+   mutable double sin_azimuth;  
+   mutable double cos_azimuth;
+   mutable double A_over_B;
+   mutable double B_over_A;
+   mutable double OMerc_u;             /* Coordinates for center point (uc , vc), vc = 0 */
+                                                 /* at center lat and lon */
+/* Oblique Mercator projection Parameters */
+   mutable double OMerc_Origin_Lat;/* Latitude of projection center, in radians */
+   mutable double OMerc_Lat_1;     /* Latitude of first point lying on central line */
+   mutable double OMerc_Lon_1;     /* Longitude of first point lying on central line */
+   mutable double OMerc_Lat_2;     /* Latitude of second point lying on central line */
+   mutable double OMerc_Lon_2;      /* Longitude of second point lying on central line */
+   mutable double OMerc_Scale_Factor;                /* Scale factor at projection center */
+   mutable double OMerc_False_Northing;              /* False northing, in meters, at projection center */
+   mutable double OMerc_False_Easting;               /* False easting, in meters, at projection center */
+   
+   mutable double OMerc_Delta_Northing;
+   mutable double OMerc_Delta_Easting;
+   
+/*!
+ * The function Set_Oblique_Mercator_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise OMERC_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Origin_Latitude   : Latitude, in radians, at which the        (input)
+ *                          point scale factor is 1.0
+ *    Latitude_1        : Latitude, in radians, of first point lying on
+ *                           central line                           (input)
+ *    Longitude_1       : Longitude, in radians, of first point lying on
+ *                           central line                           (input)
+ *    Latitude_2        : Latitude, in radians, of second point lying on
+ *                           central line                           (input)
+ *    Longitude_2       : Longitude, in radians, of second point lying on
+ *                           central line                           (input)
+ *    False_Easting     : A coordinate value, in meters, assigned to the
+ *                          central meridian of the projection      (input)
+ *    False_Northing    : A coordinate value, in meters, assigned to the
+ *                          origin latitude of the projection       (input)
+ *    Scale_Factor      : Multiplier which reduces distances in the
+ *                          projection to the actual distance on the
+ *                          ellipsoid                               (input)
+ */
+  long Set_Oblique_Mercator_Parameters(double a,
+                                       double f,
+                                       double Origin_Latitude,
+                                       double Latitude_1,
+                                       double Longitude_1,
+                                       double Latitude_2,
+                                       double Longitude_2,
+                                       double False_Easting,
+                                       double False_Northing,
+                                       double Scale_Factor);
+
+
+/*!
+ * The function Get_Oblique_Mercator_Parameters returns the current ellipsoid
+ * parameters and Oblique Mercator projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters  (output)
+ *    f                 : Flattening of ellipsoid                  (output)
+ *    Origin_Latitude   : Latitude, in radians, at which the       (output)
+ *                          point scale factor is 1.0
+ *    Latitude_1        : Latitude, in radians, of first point lying on
+ *                          central line                           (output)
+ *    Longitude_1       : Longitude, in radians, of first point lying on
+ *                          central line                           (output)
+ *    Latitude_2        : Latitude, in radians, of second point lying on
+ *                          central line                           (output)
+ *    Longitude_2       : Longitude, in radians, of second point lying on
+ *                          central line                           (output)
+ *    False_Easting     : A coordinate value, in meters, assigned to the
+ *                          central meridian of the projection     (output)
+ *    False_Northing    : A coordinate value, in meters, assigned to the
+ *                          origin latitude of the projection      (output)
+ *    Scale_Factor      : Multiplier which reduces distances in the
+ *                          projection to the actual distance on the
+ *                          ellipsoid                              (output)
+ */
+  void Get_Oblique_Mercator_Parameters(double *a,
+                                       double *f,
+                                       double *Origin_Latitude,
+                                       double *Latitude_1,
+                                       double *Longitude_1,
+                                       double *Latitude_2,
+                                       double *Longitude_2,
+                                       double *False_Easting,
+                                       double *False_Northing,
+                                       double *Scale_Factor)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Oblique_Mercator converts geodetic (latitude and
+ * longitude) coordinates to Oblique Mercator projection (easting and
+ * northing) coordinates, according to the current ellipsoid and Oblique Mercator 
+ * projection parameters.  If any errors occur, the error code(s) are returned 
+ * by the function, otherwise OMERC_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi), in radians           (input)
+ *    Longitude         : Longitude (lambda), in radians       (input)
+ *    Easting           : Easting (X), in meters               (output)
+ *    Northing          : Northing (Y), in meters              (output)
+ */
+  long Convert_Geodetic_To_Oblique_Mercator(double Latitude,
+                                            double Longitude,
+                                            double *Easting,
+                                            double *Northing)const;
+
+
+/*!
+ * The function Convert_Oblique_Mercator_To_Geodetic converts Oblique Mercator projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Oblique Mercator projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise OMERC_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X), in meters                  (input)
+ *    Northing          : Northing (Y), in meters                 (input)
+ *    Latitude          : Latitude (phi), in radians              (output)
+ *    Longitude         : Longitude (lambda), in radians          (output)
+ */
+  long Convert_Oblique_Mercator_To_Geodetic(double Easting,
+                                            double Northing,
+                                            double *Latitude,
+                                            double *Longitude)const;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimOrthoGraphicProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimOrthoGraphicProjection.cpp
new file mode 100644
index 0000000000..9e34b03eab
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimOrthoGraphicProjection.cpp
@@ -0,0 +1,501 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans OrthoGraphic projection code.  
+//*******************************************************************
+//  $Id: ossimOrthoGraphicProjection.cpp,v 1.12 2005/09/28 19:23:17 gpotts Exp $
+
+#include <math.h>
+#include "ossimOrthoGraphicProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimOrthoGraphicProjection, "ossimOrthoGraphicProjection", ossimMapProjection)
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define MAX_LAT    ( (M_PI * 90) / 180.0 )  /* 90 degrees in radians   */
+
+
+#define ORTH_NO_ERROR           0x0000
+#define ORTH_LAT_ERROR          0x0001
+#define ORTH_LON_ERROR          0x0002
+#define ORTH_EASTING_ERROR      0x0004
+#define ORTH_NORTHING_ERROR     0x0008
+#define ORTH_ORIGIN_LAT_ERROR   0x0010
+#define ORTH_CENT_MER_ERROR     0x0020
+#define ORTH_A_ERROR            0x0040
+#define ORTH_B_ERROR            0x0080
+#define ORTH_A_LESS_B_ERROR     0x0100
+#define ORTH_RADIUS_ERROR	     0x0200
+
+
+ossimOrthoGraphicProjection::ossimOrthoGraphicProjection(const ossimEllipsoid& ellipsoid,
+                                                         const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimOrthoGraphicProjection::ossimOrthoGraphicProjection(const ossimEllipsoid& ellipsoid,
+                                                 const ossimGpt& origin,
+                                                 double falseEasting,
+                                                 double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{   
+   Orth_False_Easting  = falseEasting;
+   Orth_False_Northing = falseNorthing;
+
+   update();
+}
+
+void ossimOrthoGraphicProjection::update()
+{
+   Set_Orthographic_Parameters(theEllipsoid.getA(),
+                               theEllipsoid.getFlattening(),
+                               theOrigin.latr(),
+                               theOrigin.lonr(),
+                               Orth_False_Easting,
+                               Orth_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimOrthoGraphicProjection::setFalseEasting(double falseEasting)
+{
+   Orth_False_Easting = falseEasting;
+   update();
+}
+
+void ossimOrthoGraphicProjection::setFalseNorthing(double falseNorthing)
+{
+   Orth_False_Northing = falseNorthing;
+   update();
+}
+
+void ossimOrthoGraphicProjection::setDefaults()
+{
+   Orth_False_Easting  = 0.0;
+   Orth_False_Northing = 0.0;
+}
+
+void ossimOrthoGraphicProjection::setFalseEastingNorthing(double falseEasting,
+                                                      double falseNorthing)
+{
+   Orth_False_Easting  = falseEasting;
+   Orth_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimOrthoGraphicProjection::getGroundClipPoints(ossimGeoPolygon& gpts)const
+{
+   
+   gpts.addPoint(ossimGpt(theOrigin.latd(),
+                          theOrigin.lond()-90.0,
+                          0.0,
+                          theDatum));
+   gpts.addPoint(ossimGpt(theOrigin.latd()+90.0,
+                          theOrigin.lond(),
+                          0.0,
+                          theDatum));
+   gpts.addPoint(ossimGpt(theOrigin.latd(),
+                          theOrigin.lond()+90.0,
+                          0.0,
+                          theDatum));
+   gpts.addPoint(ossimGpt(theOrigin.latd()-90.0,
+                          theOrigin.lond(),
+                          0.0,
+                          theDatum));
+
+   
+}
+
+ossimGpt ossimOrthoGraphicProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   ossimGpt result;
+   if(Convert_Orthographic_To_Geodetic(eastingNorthing.x,
+                                       eastingNorthing.y,
+                                       &lat,
+                                       &lon)==ORTH_NO_ERROR)
+   {
+      result.datum(theDatum);
+      result.latr(lat);
+      result.lonr(lon);
+   }
+   else
+   {
+      result.makeNan();
+   }
+
+   return result;
+}
+
+ossimDpt ossimOrthoGraphicProjection::forward(const ossimGpt &latLon)const
+{
+
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   ossimDpt result;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   if(Convert_Geodetic_To_Orthographic(gpt.latr(),
+                                       gpt.lonr(),
+                                       &easting,
+                                       &northing) == ORTH_NO_ERROR)
+   {
+      result = ossimDpt(easting, northing);
+   }
+   else
+   {
+      result.makeNan();
+   }
+   
+   return result;
+}
+
+bool ossimOrthoGraphicProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Orth_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Orth_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimOrthoGraphicProjection::loadState(const ossimKeywordlist& kwl,
+                                            const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimOrthoGraphicProjection))
+   {
+      if(falseEasting)
+      {
+         Orth_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Orth_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   update();
+
+   return flag;
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS
+ */
+
+
+long ossimOrthoGraphicProjection::Set_Orthographic_Parameters(double a,
+                                                              double f,
+                                                              double Origin_Latitude,
+                                                              double Central_Meridian,
+                                                              double False_Easting,
+                                                              double False_Northing)
+{ /* BEGIN Set_Orthographic_Parameters */
+/*
+ * The function Set_Orthographic_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise ORTH_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)                          
+ */
+
+//  double inv_f = 1 / f;
+  long Error_Code = ORTH_NO_ERROR;
+
+  if (a <= 0.0)
+  { /* Semi-major axis must be greater than zero */
+    Error_Code |= ORTH_A_ERROR;
+  }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= ORTH_INV_F_ERROR;
+//   }
+  if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+  { /* origin latitude out of range */
+    Error_Code |= ORTH_ORIGIN_LAT_ERROR;
+  }
+  if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
+  { /* origin longitude out of range */
+    Error_Code |= ORTH_CENT_MER_ERROR;
+  }
+  if (!Error_Code)
+  { /* no errors */
+    Orth_a = a;
+    Orth_f = f;
+    es2 = 2 * Orth_f - Orth_f * Orth_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    Ra = Orth_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 /3024.0);
+    Orth_Origin_Lat = Origin_Latitude;
+    Sin_Orth_Origin_Lat = sin(Orth_Origin_Lat);
+    Cos_Orth_Origin_Lat = cos(Orth_Origin_Lat);
+//     if (Central_Meridian > M_PI)
+//       Central_Meridian -= TWO_PI;
+    Orth_Origin_Long = Central_Meridian;
+    Orth_False_Easting = False_Easting;
+    Orth_False_Northing = False_Northing;
+
+  } /* END OF if(!Error_Code) */
+  
+  return (Error_Code);
+} /* END OF Set_Orthographic_Parameters */
+
+
+void ossimOrthoGraphicProjection::Get_Orthographic_Parameters(double *a,
+                                                              double *f,
+                                                              double *Origin_Latitude,
+                                                              double *Central_Meridian,
+                                                              double *False_Easting,
+                                                              double *False_Northing)const
+{ /* BEGIN Get_Orthographic_Parameters */
+/*
+ * The function Get_Orthographic_Parameters returns the current ellipsoid
+ * parameters and Orthographic projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output) 
+ */
+
+  *a = Orth_a;
+  *f = Orth_f;
+  *Origin_Latitude = Orth_Origin_Lat;
+  *Central_Meridian = Orth_Origin_Long;
+  *False_Easting = Orth_False_Easting;
+  *False_Northing = Orth_False_Northing;
+  
+  return;
+} /* END OF Get_Orthographic_Parameters */
+
+
+long ossimOrthoGraphicProjection::Convert_Geodetic_To_Orthographic (double Latitude,
+                                                                    double Longitude,
+                                                                    double *Easting,
+                                                                    double *Northing)const
+
+{ /* BEGIN Convert_Geodetic_To_Orthographic */
+/*
+ * The function Convert_Geodetic_To_Orthographic converts geodetic (latitude and
+ * longitude) coordinates to Orthographic projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Orthographic projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ORTH_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double slat = sin(Latitude);
+  double clat = cos(Latitude);
+  double dlam;                        /* Longitude - Central Meridan */
+  double clat_cdlam;
+  double cos_c;                       /* Value used to determine whether the point is beyond
+                                   viewing.  If zero or positive, the point is within view.  */
+  long   Error_Code = ORTH_NO_ERROR;
+
+  if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+  {  /* Latitude out of range */
+     Error_Code |= ORTH_LAT_ERROR;
+  }
+  if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+  {  /* Longitude out of range */
+     Error_Code|= ORTH_LON_ERROR;
+  }
+  dlam = Longitude - Orth_Origin_Long;
+  clat_cdlam = clat * cos(dlam);
+  cos_c = Sin_Orth_Origin_Lat * slat + Cos_Orth_Origin_Lat * clat_cdlam;
+  if (cos_c < 0.0)
+  {  /* Point is out of view.  Will return longitude out of range message
+        since no point out of view is implemented.  */
+     Error_Code |= ORTH_LON_ERROR;
+  }
+
+  if (!Error_Code)
+  { /* no errors */
+     if (dlam > M_PI)
+     {
+        dlam -= TWO_PI;
+     }
+     if (dlam < -M_PI)
+     {
+        dlam += TWO_PI;
+     }
+     *Easting = Ra * clat * sin(dlam) + Orth_False_Easting;
+     *Northing = Ra * (Cos_Orth_Origin_Lat * slat - Sin_Orth_Origin_Lat * clat_cdlam) +
+        Orth_False_Northing;
+  }
+  return (Error_Code);
+
+} /* END OF Convert_Geodetic_To_Orthographic */
+
+
+long ossimOrthoGraphicProjection::Convert_Orthographic_To_Geodetic(double Easting,
+                                                                   double Northing,
+                                                                   double *Latitude,
+                                                                   double *Longitude)const
+{ /* BEGIN Convert_Orthographic_To_Geodetic */
+/*
+ * The function Convert_Orthographic_To_Geodetic converts Orthographic projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Orthographic projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ORTH_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double cc;
+  double cos_cc, sin_cc;
+  double rho;
+  double dx, dy;
+  double atan_dx_over_dy;
+//  double temp;
+  double rho_OVER_Ra;
+  long Error_Code = ORTH_NO_ERROR;
+
+  if ((Easting > (Orth_False_Easting + Ra)) ||
+      (Easting < (Orth_False_Easting - Ra)))
+  { /* Easting out of range */
+    Error_Code |= ORTH_EASTING_ERROR;
+  }
+  if ((Northing > (Orth_False_Northing + Ra)) ||
+      (Northing < (Orth_False_Northing - Ra)))
+  { /* Northing out of range */
+    Error_Code |= ORTH_NORTHING_ERROR;
+  }
+  if (!Error_Code)
+  {
+    double temp = sqrt(Easting * Easting + Northing * Northing);     
+
+    if ((temp > (Orth_False_Easting + Ra)) || (temp > (Orth_False_Northing + Ra)) ||
+        (temp < (Orth_False_Easting - Ra)) || (temp < (Orth_False_Northing - Ra)))
+    { /* Point is outside of projection area */
+      Error_Code |= ORTH_RADIUS_ERROR;
+    }
+  }
+
+  if (!Error_Code)
+  {
+    dx = Easting - Orth_False_Easting;
+    dy = Northing - Orth_False_Northing;
+    atan_dx_over_dy = atan(dx / dy);
+    rho = sqrt(dx * dx + dy * dy);
+    if (rho == 0.0)
+    {
+      *Latitude = Orth_Origin_Lat;
+      *Longitude = Orth_Origin_Long;
+    }
+    else
+    {
+      rho_OVER_Ra = rho / Ra;
+
+      if (rho_OVER_Ra > 1.0)
+        rho_OVER_Ra = 1.0;
+      else if (rho_OVER_Ra < -1.0)
+        rho_OVER_Ra = -1.0;
+
+      cc = asin(rho_OVER_Ra);
+      cos_cc = cos(cc);
+      sin_cc = sin(cc);
+      *Latitude = asin(cos_cc * Sin_Orth_Origin_Lat + (dy * sin_cc * Cos_Orth_Origin_Lat / rho));
+
+      if (Orth_Origin_Lat == MAX_LAT)
+        *Longitude = Orth_Origin_Long - atan_dx_over_dy;
+      else if (Orth_Origin_Lat == -MAX_LAT)
+        *Longitude = Orth_Origin_Long + atan_dx_over_dy;
+      else
+        *Longitude = Orth_Origin_Long + atan(dx * sin_cc / (rho *
+                                                            Cos_Orth_Origin_Lat * cos_cc - dy * Sin_Orth_Origin_Lat * sin_cc));
+
+//       if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//         *Latitude = PI_OVER_2;
+//       else if (*Latitude < -PI_OVER_2)
+//         *Latitude = -PI_OVER_2;
+
+//       if (*Longitude > M_PI)
+//         *Longitude -= TWO_PI;
+//       if (*Longitude < -M_PI)
+//         *Longitude += TWO_PI;
+
+//       if (*Longitude > M_PI)  /* force distorted values to 180, -180 degrees */
+//         *Longitude = M_PI;
+//       else if (*Longitude < -M_PI)
+//         *Longitude = -M_PI;
+    } 
+  }
+  return (Error_Code);
+} /* END OF Convert_Orthographic_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimOrthoGraphicProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimOrthoGraphicProjection.h
new file mode 100644
index 0000000000..74fe9ac9a0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimOrthoGraphicProjection.h
@@ -0,0 +1,196 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans OrthoGraphic  projection code.  
+//*******************************************************************
+//  $Id: ossimOrthoGraphicProjection.h,v 1.6 2005/09/28 19:23:17 gpotts Exp $
+
+#ifndef ossimOrthoGraphicProjection_HEADER
+#define ossimOrthoGraphicProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimOrthoGraphicProjection : public ossimMapProjection
+{
+public:
+   
+   ossimOrthoGraphicProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                               const ossimGpt& origin = ossimGpt());
+   ossimOrthoGraphicProjection(const ossimEllipsoid& ellipsoid,
+                               const ossimGpt& origin,
+                               const double falseEasting,
+                               const double falseNorthing);
+   ~ossimOrthoGraphicProjection(){}
+   
+   virtual ossimObject *dup()const
+      {
+         return new ossimOrthoGraphicProjection(*this);
+      }
+   virtual void getGroundClipPoints(ossimGeoPolygon& gpts)const;
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return  Orth_False_Easting;}
+   double getFalseNorthing()const{return Orth_False_Northing;}
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+   
+   //___________________GEOTRANS_______________________
+   mutable double Orth_a;                      /* Semi-major axis of ellipsoid in meters */
+   mutable double Orth_f;              /* Flattening of ellipsoid */
+   mutable double es2;             /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;              /* es2 * es2 */
+   mutable double es6;              /* es4 * es2 */
+   mutable double Ra;                    /* Spherical Radius */
+   
+/* Orthographic projection Parameters */
+   mutable double Orth_Origin_Lat;                   /* Latitude of origin in radians     */
+   mutable double Orth_Origin_Long;                  /* Longitude of origin in radians    */
+   mutable double Orth_False_Easting;
+   mutable double Orth_False_Northing;
+   mutable double Sin_Orth_Origin_Lat;               /* sin(Orth_Origin_Lat) */
+   mutable double Cos_Orth_Origin_Lat;               /* cos(Orth_Origin_Lat) */
+   
+/*!
+ * The function Set_Orthographic_Parameters receives the ellipsoid parameters and
+ * Orthographic projcetion parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise ORTH_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)                          
+ */
+  long Set_Orthographic_Parameters(double a,
+                                   double f,
+                                   double Origin_Latitude,
+                                   double Central_Meridian,
+                                   double False_Easting,
+                                   double False_Northing);
+
+
+
+/*!
+ * The function Get_Orthographic_Parameters returns the current ellipsoid
+ * parameters and Orthographic projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid                   (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Origin_Longitude  : Longitude in radians at the center of     (output)
+ *                          the projection (central meridian)
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output) 
+ */
+  void Get_Orthographic_Parameters(double *a,
+                                   double *f,
+                                   double *Origin_Latitude,
+                                   double *Origin_Longitude,
+                                   double *False_Easting,
+                                   double *False_Northing)const;
+
+
+
+/*!
+ * The function Convert_Geodetic_To_Orthographic converts geodetic (latitude and
+ * longitude) coordinates to Orthographic projection easting, and northing
+ * coordinates, according to the current ellipsoid and Orthographic projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ORTH_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Orthographic (double Latitude,
+                                         double Longitude,
+                                         double *Easting,
+                                         double *Northing)const;
+
+
+/*!
+ * The function Convert_Orthographic_To_Geodetic converts Orthographic projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Orthographic projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise ORTH_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Orthographic_To_Geodetic(double Easting,
+                                        double Northing,
+                                        double *Latitude,
+                                        double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarStereoProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarStereoProjection.cpp
new file mode 100644
index 0000000000..ea9dede9af
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarStereoProjection.cpp
@@ -0,0 +1,562 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Polar Stereographic  projection code.  
+//*******************************************************************
+//  $Id: ossimPolarStereoProjection.cpp,v 1.11 2004/01/08 21:49:22 jlargent Exp $
+
+#include <math.h>
+#include "ossimPolarStereoProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimPolarStereoProjection, "ossimPolarStereoProjection", ossimMapProjection)
+/************************************************************************/
+/*                               DEFINES
+ *
+ */
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define POLAR_POW(EsSin)     pow((1.0 - EsSin) / (1.0 + EsSin), es_OVER_2)
+
+#define POLAR_NO_ERROR                0x0000
+#define POLAR_LAT_ERROR               0x0001
+#define POLAR_LON_ERROR               0x0002
+#define POLAR_ORIGIN_LAT_ERROR        0x0004
+#define POLAR_ORIGIN_LON_ERROR        0x0008
+#define POLAR_EASTING_ERROR	      0x0010
+#define POLAR_NORTHING_ERROR	      0x0020
+#define POLAR_A_ERROR                 0x0040
+#define POLAR_B_ERROR                 0x0080
+#define POLAR_A_LESS_B_ERROR          0x0100
+#define POLAR_RADIUS_ERROR            0x0200
+
+/************************************************************************/
+/*                           GLOBAL DECLARATIONS
+ *
+ */
+
+const double PI_Over_4 = (M_PI / 4.0);
+
+ossimPolarStereoProjection::ossimPolarStereoProjection(const ossimEllipsoid& ellipsoid,
+                                                       const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+//    Polar_Delta_Easting  = 12713601.0;
+//    Polar_Delta_Northing = 12713601.0;
+}
+
+ossimPolarStereoProjection::ossimPolarStereoProjection(const ossimEllipsoid& ellipsoid,
+                                                       const ossimGpt& origin,
+                                                       double falseEasting,
+                                                       double falseNorthing)
+{
+   Polar_False_Easting  = falseEasting;
+   Polar_False_Northing = falseNorthing;
+   Polar_Delta_Easting  = 12713601.0;
+   Polar_Delta_Northing = 12713601.0;
+
+   update();
+}
+
+void ossimPolarStereoProjection::update()
+{   
+   Set_Polar_Stereographic_Parameters(theEllipsoid.getA(),
+                                      theEllipsoid.getFlattening(),
+                                      theOrigin.latr(),
+                                      theOrigin.lonr(),
+                                      Polar_False_Easting,
+                                      Polar_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimPolarStereoProjection::setFalseEasting(double falseEasting)
+{
+   Polar_False_Easting = falseEasting;
+   
+   update();
+}
+
+void ossimPolarStereoProjection::setFalseNorthing(double falseNorthing)
+{
+   Polar_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimPolarStereoProjection::setDefaults()
+{
+   Polar_False_Easting  = 0.0;
+   Polar_False_Northing = 0.0;
+}
+
+void ossimPolarStereoProjection::setFalseEastingNorthing(double falseEasting,
+                                                      double falseNorthing)
+{
+   Polar_False_Easting  = falseEasting;
+   Polar_False_Northing = falseNorthing;
+   
+   update();
+}
+
+ossimGpt ossimPolarStereoProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Polar_Stereographic_To_Geodetic(eastingNorthing.x,
+                                           eastingNorthing.y,
+                                           &lat,
+                                           &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);
+}
+
+ossimDpt ossimPolarStereoProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Polar_Stereographic(gpt.latr(),
+                                           gpt.lonr(),
+                                           &easting,
+                                           &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+bool ossimPolarStereoProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Polar_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Polar_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimPolarStereoProjection::loadState(const ossimKeywordlist& kwl,
+                                           const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimPolarStereoProjection))
+   {
+      if(falseEasting)
+      {
+         Polar_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Polar_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+
+   return flag;
+}
+
+
+/************************************************************************/
+/*                              FUNCTIONS
+ *
+ */
+
+
+long ossimPolarStereoProjection::Set_Polar_Stereographic_Parameters (double a,
+                                                                     double f,
+                                                                     double Latitude_of_True_Scale,
+                                                                     double Longitude_Down_from_Pole,
+                                                                     double False_Easting,
+                                                                     double False_Northing)
+
+{  /* BEGIN Set_Polar_Stereographic_Parameters   */
+/*  
+ *  The function Set_Polar_Stereographic_Parameters receives the ellipsoid
+ *  parameters and Polar Stereograpic projection parameters as inputs, and
+ *  sets the corresponding state variables.  If any errors occur, error
+ *  code(s) are returned by the function, otherwise POLAR_NO_ERROR is returned.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (input)
+ *  f                : Flattening of ellipsoid					               (input)
+ *  Latitude_of_True_Scale  : Latitude of true scale, in radians       (input)
+ *  Longitude_Down_from_Pole : Longitude down from pole, in radians    (input)
+ *  False_Easting    : Easting (X) at center of projection, in meters  (input)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (input)
+ */
+
+  double es2;
+  double slat, clat;
+  double essin;
+  double one_PLUS_es, one_MINUS_es;
+  double pow_es;
+  double temp;
+//  double inv_f = 1 / f;
+  const double  epsilon = 1.0e-2;
+  long Error_Code = POLAR_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= POLAR_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= POLAR_INV_F_ERROR;
+//   }
+//   if ((Latitude_of_True_Scale < -PI_OVER_2) || (Latitude_of_True_Scale > PI_OVER_2))
+//   { /* Origin Latitude out of range */
+//     Error_Code |= POLAR_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Longitude_Down_from_Pole < -PI) || (Longitude_Down_from_Pole > TWO_PI))
+//   { /* Origin Longitude out of range */
+//     Error_Code |= POLAR_ORIGIN_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    Polar_a = a;
+    two_Polar_a = 2.0 * Polar_a;
+    Polar_f = f;
+
+    if (Longitude_Down_from_Pole > M_PI)
+      Longitude_Down_from_Pole -= TWO_PI;
+    if (Latitude_of_True_Scale < 0)
+    {
+      Southern_Hemisphere = 1;
+      Polar_Origin_Lat = -Latitude_of_True_Scale;
+      Polar_Origin_Long = -Longitude_Down_from_Pole;
+    }
+    else
+    {
+      Southern_Hemisphere = 0;
+      Polar_Origin_Lat = Latitude_of_True_Scale;
+      Polar_Origin_Long = Longitude_Down_from_Pole;
+    }
+    Polar_False_Easting = False_Easting;
+    Polar_False_Northing = False_Northing;
+
+    es2 = 2 * Polar_f - Polar_f * Polar_f;
+    es = sqrt(es2);
+    es_OVER_2 = es / 2.0;
+
+    if (fabs(fabs(Polar_Origin_Lat) - PI_OVER_2) > 1.0e-10)
+    {
+      slat = sin(Polar_Origin_Lat);
+      essin = es * slat;
+      pow_es = POLAR_POW(essin);
+      clat = cos(Polar_Origin_Lat);
+      mc = clat / sqrt(1.0 - essin * essin);
+      Polar_a_mc = Polar_a * mc;
+      tc = tan(PI_Over_4 - Polar_Origin_Lat / 2.0) / pow_es;
+    }
+    else
+    {
+      one_PLUS_es = 1.0 + es;
+      one_MINUS_es = 1.0 - es;
+      e4 = sqrt(pow(one_PLUS_es, one_PLUS_es) * pow(one_MINUS_es, one_MINUS_es));
+    }
+  }
+  /* Calculate Radius */
+  Convert_Geodetic_To_Polar_Stereographic(0, Polar_Origin_Long, 
+                                          &temp, &Polar_Delta_Northing);
+  Polar_Delta_Northing = fabs(Polar_Delta_Northing) + epsilon;
+  Polar_Delta_Easting = Polar_Delta_Northing;
+
+
+  return (Error_Code);
+} /* END OF Set_Polar_Stereographic_Parameters */
+
+
+
+void ossimPolarStereoProjection::Get_Polar_Stereographic_Parameters (double *a,
+                                                                     double *f,
+                                                                     double *Latitude_of_True_Scale,
+                                                                     double *Longitude_Down_from_Pole,
+                                                                     double *False_Easting,
+                                                                     double *False_Northing)const
+
+{ /* BEGIN Get_Polar_Stereographic_Parameters  */
+/*
+ * The function Get_Polar_Stereographic_Parameters returns the current
+ * ellipsoid parameters and Polar projection parameters.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (output)
+ *  f                : Flattening of ellipsoid					               (output)
+ *  Latitude_of_True_Scale  : Latitude of true scale, in radians       (output)
+ *  Longitude_Down_from_Pole : Longitude down from pole, in radians    (output)
+ *  False_Easting    : Easting (X) at center of projection, in meters  (output)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (output)
+ */
+
+  *a = Polar_a;
+  *f = Polar_f;
+  *Latitude_of_True_Scale = Polar_Origin_Lat;
+  *Longitude_Down_from_Pole = Polar_Origin_Long;
+  *False_Easting = Polar_False_Easting;
+  *False_Northing = Polar_False_Northing;
+  
+  return;
+} /* END OF Get_Polar_Stereographic_Parameters */
+
+
+long ossimPolarStereoProjection::Convert_Geodetic_To_Polar_Stereographic (double Latitude,
+                                                                          double Longitude,
+                                                                          double *Easting,
+                                                                          double *Northing)const
+
+{  /* BEGIN Convert_Geodetic_To_Polar_Stereographic */
+
+/*
+ * The function Convert_Geodetic_To_Polar_Stereographic converts geodetic
+ * coordinates (latitude and longitude) to Polar Stereographic coordinates
+ * (easting and northing), according to the current ellipsoid
+ * and Polar Stereographic projection parameters. If any errors occur, error
+ * code(s) are returned by the function, otherwise POLAR_NO_ERROR is returned.
+ *
+ *    Latitude   :  Latitude, in radians                      (input)
+ *    Longitude  :  Longitude, in radians                     (input)
+ *    Easting    :  Easting (X), in meters                    (output)
+ *    Northing   :  Northing (Y), in meters                   (output)
+ */
+
+  double dlam;
+  double slat;
+  double essin;
+  double t;
+  double rho;
+  double pow_es;
+  long Error_Code = POLAR_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   {   /* Latitude out of range */
+//     Error_Code |= POLAR_LAT_ERROR;
+//   }
+//   if ((Latitude < 0) && (Southern_Hemisphere == 0))
+//   {   /* Latitude and Origin Latitude in different hemispheres */
+//     Error_Code |= POLAR_LAT_ERROR;
+//   }
+//   if ((Latitude > 0) && (Southern_Hemisphere == 1))
+//   {   /* Latitude and Origin Latitude in different hemispheres */
+//     Error_Code |= POLAR_LAT_ERROR;
+//   }
+//   if ((Longitude < -PI) || (Longitude > TWO_PI))
+//   {  /* Longitude out of range */
+//     Error_Code |= POLAR_LON_ERROR;
+//   }
+
+
+  if (!Error_Code)
+  {  /* no errors */
+
+    if (fabs(fabs(Latitude) - PI_OVER_2) < 1.0e-10)
+    {
+      *Easting = 0.0;
+      *Northing = 0.0;
+    }
+    else
+    {
+      if (Southern_Hemisphere != 0)
+      {
+        Longitude *= -1.0;
+        Latitude *= -1.0;
+      }
+      dlam = Longitude - Polar_Origin_Long;
+//       if (dlam > M_PI)
+//       {
+//         dlam -= TWO_PI;
+//       }
+//       if (dlam < -M_PI)
+//       {
+//         dlam += TWO_PI;
+//       }
+      slat = sin(Latitude);
+      essin = es * slat;
+      pow_es = POLAR_POW(essin);
+      t = tan(PI_Over_4 - Latitude / 2.0) / pow_es;
+
+      if (fabs(fabs(Polar_Origin_Lat) - PI_OVER_2) > 1.0e-10)
+        rho = Polar_a_mc * t / tc;
+      else
+        rho = two_Polar_a * t / e4;
+
+      *Easting = rho * sin(dlam) + Polar_False_Easting;
+
+      if (Southern_Hemisphere != 0)
+      {
+        *Easting *= -1.0;
+        *Northing = rho * cos(dlam) + Polar_False_Northing;
+      }
+      else
+        *Northing = -rho * cos(dlam) + Polar_False_Northing;
+
+    }
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Polar_Stereographic */
+
+
+long ossimPolarStereoProjection::Convert_Polar_Stereographic_To_Geodetic (double Easting,
+                                                                          double Northing,
+                                                                          double *Latitude,
+                                                                          double *Longitude)const
+
+{ /*  BEGIN Convert_Polar_Stereographic_To_Geodetic  */
+/*
+ *  The function Convert_Polar_Stereographic_To_Geodetic converts Polar
+ *  Stereographic coordinates (easting and northing) to geodetic
+ *  coordinates (latitude and longitude) according to the current ellipsoid
+ *  and Polar Stereographic projection Parameters. If any errors occur, the
+ *  code(s) are returned by the function, otherwise POLAR_NO_ERROR
+ *  is returned.
+ *
+ *  Easting          : Easting (X), in meters                   (input)
+ *  Northing         : Northing (Y), in meters                  (input)
+ *  Latitude         : Latitude, in radians                     (output)
+ *  Longitude        : Longitude, in radians                    (output)
+ *
+ */
+
+  double dy, dx;
+  double rho;
+  double t;
+  double PHI, sin_PHI;
+  double tempPHI = 0.0;
+  double essin;
+  double pow_es;
+//  double temp;
+  long Error_Code = POLAR_NO_ERROR;
+
+//   if ((Easting > (Polar_False_Easting + Polar_Delta_Easting)) ||
+//       (Easting < (Polar_False_Easting - Polar_Delta_Easting)))
+//   { /* Easting out of range */
+//     Error_Code |= POLAR_EASTING_ERROR;
+//   }
+//   if ((Northing > (Polar_False_Northing + Polar_Delta_Northing)) ||
+//       (Northing < (Polar_False_Northing - Polar_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= POLAR_NORTHING_ERROR;
+//   }
+//   if (!Error_Code)
+//   {
+//     temp = sqrt(Easting * Easting + Northing * Northing);     
+
+//     if ((temp > (Polar_False_Easting + Polar_Delta_Easting)) || 
+//         (temp > (Polar_False_Northing + Polar_Delta_Northing)) ||
+//         (temp < (Polar_False_Easting - Polar_Delta_Easting)) || 
+//         (temp < (Polar_False_Northing - Polar_Delta_Northing)))
+//     { /* Point is outside of projection area */
+//       Error_Code |= POLAR_RADIUS_ERROR;
+//     }
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    dy = Northing - Polar_False_Northing;
+    dx = Easting - Polar_False_Easting;
+    if ((dy == 0.0) && (dx == 0.0))
+    {
+      *Latitude = PI_OVER_2;
+      *Longitude = Polar_Origin_Long;
+
+    }
+    else
+    {
+      if (Southern_Hemisphere != 0)
+      {
+        dy *= -1.0;
+        dx *= -1.0;
+      }
+
+      rho = sqrt(dx * dx + dy * dy);
+      if (fabs(fabs(Polar_Origin_Lat) - PI_OVER_2) > 1.0e-10)
+        t = rho * tc / (Polar_a_mc);
+      else
+        t = rho * e4 / (two_Polar_a);
+      PHI = PI_OVER_2 - 2.0 * atan(t);
+      while (fabs(PHI - tempPHI) > 1.0e-10)
+      {
+        tempPHI = PHI;
+        sin_PHI = sin(PHI);
+        essin =  es * sin_PHI;
+        pow_es = POLAR_POW(essin);
+        PHI = PI_OVER_2 - 2.0 * atan(t * pow_es);
+      }
+      *Latitude = PHI;
+      *Longitude = Polar_Origin_Long + atan2(dx, -dy);
+
+//       if (*Longitude > M_PI)
+//         *Longitude -= TWO_PI;
+//       else if (*Longitude < -M_PI)
+//         *Longitude += TWO_PI;
+
+
+//       if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//         *Latitude = PI_OVER_2;
+//       else if (*Latitude < -PI_OVER_2)
+//         *Latitude = -PI_OVER_2;
+
+//       if (*Longitude > M_PI)  /* force distorted values to 180, -180 degrees */
+//         *Longitude = M_PI;
+//       else if (*Longitude < -M_PI)
+//         *Longitude = -M_PI;
+
+    }
+    if (Southern_Hemisphere != 0)
+    {
+      *Latitude *= -1.0;
+      *Longitude *= -1.0;
+    }
+
+  }
+  return (Error_Code);
+} /* END OF Convert_Polar_Stereographic_To_Geodetic */
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarStereoProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarStereoProjection.h
new file mode 100644
index 0000000000..eceb760510
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarStereoProjection.h
@@ -0,0 +1,192 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Polar Stereographic  projection code.  
+//*******************************************************************
+//  $Id: ossimPolarStereoProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimPolarStereoProjection_HEADER
+#define ossimPolarStereoProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimPolarStereoProjection : public ossimMapProjection
+{
+public:
+   ossimPolarStereoProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                              const ossimGpt& origin = ossimGpt());
+   ossimPolarStereoProjection(const ossimEllipsoid& ellipsoid,
+                              const ossimGpt& origin,
+                              const double falseEasting,
+                              const double falseNorthing);
+   ~ossimPolarStereoProjection(){}
+   
+   virtual ossimObject *dup()const{return new ossimPolarStereoProjection(*this);}
+   
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+   
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return  Polar_False_Easting;}
+   double getFalseNorthing()const{return Polar_False_Northing;}
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+
+   mutable double Polar_a;                    /* Semi-major axis of ellipsoid in meters  */
+   mutable double Polar_f;            /* Flattening of ellipsoid  */
+   mutable double es;            /* Eccentricity of ellipsoid    */
+   mutable double es_OVER_2;           /* es / 2.0 */
+   mutable double Southern_Hemisphere;                /* Flag variable */
+   mutable double mc;                    
+   mutable double tc;
+   mutable double e4;
+   mutable double Polar_a_mc;                 /* Polar_a * mc */
+   mutable double two_Polar_a;               /* 2.0 * Polar_a */
+   
+/* Polar Stereographic projection Parameters */
+   mutable double Polar_Origin_Lat;   /* Latitude of origin in radians */
+   mutable double Polar_Origin_Long;                /* Longitude of origin in radians */
+   mutable double Polar_False_Easting;              /* False easting in meters */
+   mutable double Polar_False_Northing;             /* False northing in meters */
+   
+/* Maximum variance for easting and northing values for WGS 84. */
+   mutable double Polar_Delta_Easting;
+   mutable double Polar_Delta_Northing;
+   
+/*!
+ *  The function Set_Polar_Stereographic_Parameters receives the ellipsoid
+ *  parameters and Polar Stereograpic projection parameters as inputs, and
+ *  sets the corresponding state variables.  If any errors occur, error
+ *  code(s) are returned by the function, otherwise POLAR_NO_ERROR is returned.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (input)
+ *  f                : Flattening of ellipsoid                         (input)
+ *  Latitude_of_True_Scale  : Latitude of true scale, in radians       (input)
+ *  Longitude_Down_from_Pole : Longitude down from pole, in radians    (input)
+ *  False_Easting    : Easting (X) at center of projection, in meters  (input)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (input)
+ */
+  long Set_Polar_Stereographic_Parameters (double a,
+                                           double f,
+                                           double Latitude_of_True_Scale,
+                                           double Longitude_Down_from_Pole,
+                                           double False_Easting,
+                                           double False_Northing);
+
+
+/*!
+ * The function Get_Polar_Stereographic_Parameters returns the current
+ * ellipsoid parameters and Polar projection parameters.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (output)
+ *  f                : Flattening of ellipsoid                         (output)
+ *  Latitude_of_True_Scale  : Latitude of true scale, in radians       (output)
+ *  Longitude_Down_from_Pole : Longitude down from pole, in radians    (output)
+ *  False_Easting    : Easting (X) at center of projection, in meters  (output)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (output)
+ */
+  void Get_Polar_Stereographic_Parameters (double *a,
+                                           double *f,
+                                           double *Latitude_of_True_Scale,
+                                           double *Longitude_Down_from_Pole,
+                                           double *False_Easting,
+                                           double *False_Northing)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Polar_Stereographic converts geodetic
+ * coordinates (latitude and longitude) to Polar Stereographic coordinates
+ * (easting and northing), according to the current ellipsoid
+ * and Polar Stereographic projection parameters. If any errors occur, error
+ * code(s) are returned by the function, otherwise POLAR_NO_ERROR is returned.
+ *
+ *    Latitude   :  Latitude, in radians                      (input)
+ *    Longitude  :  Longitude, in radians                     (input)
+ *    Easting    :  Easting (X), in meters                    (output)
+ *    Northing   :  Northing (Y), in meters                   (output)
+ */
+  long Convert_Geodetic_To_Polar_Stereographic (double Latitude,
+                                                double Longitude,
+                                                double *Easting,
+                                                double *Northing)const;
+
+
+
+/*!
+ *  The function Convert_Polar_Stereographic_To_Geodetic converts Polar
+ *  Stereographic coordinates (easting and northing) to geodetic
+ *  coordinates (latitude and longitude) according to the current ellipsoid
+ *  and Polar Stereographic projection Parameters. If any errors occur, the
+ *  code(s) are returned by the function, otherwise POLAR_NO_ERROR
+ *  is returned.
+ *
+ *  Easting          : Easting (X), in meters                   (input)
+ *  Northing         : Northing (Y), in meters                  (input)
+ *  Latitude         : Latitude, in radians                     (output)
+ *  Longitude        : Longitude, in radians                    (output)
+ *
+ */
+  long Convert_Polar_Stereographic_To_Geodetic (double Easting,
+                                                double Northing,
+                                                double *Latitude,
+                                                double *Longitude)const;
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarst.c b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarst.c
new file mode 100644
index 0000000000..04c9ce96e4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarst.c
@@ -0,0 +1,505 @@
+/***************************************************************************/
+/* RSC IDENTIFIER: POLAR STEREOGRAPHIC 
+ *
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between geodetic (latitude and
+ *    longitude) coordinates and Polar Stereographic (easting and northing) 
+ *    coordinates.
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid 
+ *    value is found the error code is combined with the current error code 
+ *    using the bitwise or.  This combining allows multiple error codes to 
+ *    be returned. The possible error codes are:
+ *
+ *          POLAR_NO_ERROR           : No errors occurred in function
+ *          POLAR_LAT_ERROR          : Latitude outside of valid range
+ *                                      (-90 to 90 degrees)
+ *          POLAR_LON_ERROR          : Longitude outside of valid range
+ *                                      (-180 to 360 degrees) 
+ *          POLAR_ORIGIN_LAT_ERROR   : Latitude of true scale outside of valid
+ *                                      range (-90 to 90 degrees)
+ *          POLAR_ORIGIN_LON_ERROR   : Longitude down from pole outside of valid
+ *                                      range (-180 to 360 degrees)
+ *          POLAR_EASTING_ERROR      : Easting outside of valid range,
+ *                                      depending on ellipsoid and
+ *                                      projection parameters
+ *          POLAR_NORTHING_ERROR     : Northing outside of valid range,
+ *                                      depending on ellipsoid and
+ *                                      projection parameters
+ *          POLAR_RADIUS_ERROR       : Coordinates too far from pole,
+ *                                      depending on ellipsoid and
+ *                                      projection parameters
+ *          POLAR_A_ERROR            : Semi-major axis less than or equal to zero
+ *          POLAR_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	                  (250 to 350)
+ *
+ *
+ * REUSE NOTES
+ *
+ *    POLAR STEREOGRAPHIC is intended for reuse by any application that  
+ *    performs a Polar Stereographic projection.
+ *
+ *
+ * REFERENCES
+ *
+ *    Further information on POLAR STEREOGRAPHIC can be found in the
+ *    Reuse Manual.
+ *
+ *
+ *    POLAR STEREOGRAPHIC originated from :
+ *                                U.S. Army Topographic Engineering Center
+ *                                Geospatial Information Division
+ *                                7701 Telegraph Road
+ *                                Alexandria, VA  22310-3864
+ *
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ *
+ * RESTRICTIONS
+ *
+ *    POLAR STEREOGRAPHIC has no restrictions.
+ *
+ *
+ * ENVIRONMENT
+ *
+ *    POLAR STEREOGRAPHIC was tested and certified in the following
+ *    environments:
+ *
+ *    1. Solaris 2.5 with GCC, version 2.8.1
+ *    2. Window 95 with MS Visual C++, version 6
+ *
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    06-11-95          Original Code
+ *    03-01-97          Original Code
+ *
+ *
+ */
+
+
+/************************************************************************/
+/*
+ *                               INCLUDES
+ */
+
+#include <math.h>
+#include "ossimPolarst.h"
+
+/*
+ *    math.h     - Standard C math library
+ *    polarst.h  - Is for prototype error checking
+ */
+
+
+/************************************************************************/
+/*                               DEFINES
+ *
+ */
+
+
+#define PI           3.14159265358979323e0       /* PI     */
+#define PI_OVER_2    (PI / 2.0)           
+#define TWO_PI       (2.0 * PI)
+#define POLAR_POW(EsSin)     pow((1.0 - EsSin) / (1.0 + EsSin), es_OVER_2)
+
+/************************************************************************/
+/*                           GLOBAL DECLARATIONS
+ *
+ */
+
+const double PI_Over_4 = (PI / 4.0);
+
+/* Ellipsoid Parameters, default to WGS 84  */
+static double Polar_a = 6378137.0;                    /* Semi-major axis of ellipsoid in meters  */
+static double Polar_f = 1 / 298.257223563;            /* Flattening of ellipsoid  */
+static double es = 0.08181919084262188000;            /* Eccentricity of ellipsoid    */
+static double es_OVER_2 = .040909595421311;           /* es / 2.0 */
+static double Southern_Hemisphere = 0;                /* Flag variable */
+static double mc = 1.0;                    
+static double tc = 1.0;
+static double e4 = 1.0033565552493;
+static double Polar_a_mc = 6378137.0;                 /* Polar_a * mc */
+static double two_Polar_a = 12756274.0;               /* 2.0 * Polar_a */
+
+/* Polar Stereographic projection Parameters */
+static double Polar_Origin_Lat = ((PI * 90) / 180);   /* Latitude of origin in radians */
+static double Polar_Origin_Long = 0.0;                /* Longitude of origin in radians */
+static double Polar_False_Easting = 0.0;              /* False easting in meters */
+static double Polar_False_Northing = 0.0;             /* False northing in meters */
+
+/* Maximum variance for easting and northing values for WGS 84. */
+static double Polar_Delta_Easting = 12713601.0;
+static double Polar_Delta_Northing = 12713601.0;
+
+/* These state variables are for optimization purposes. The only function
+ * that should modify them is Set_Polar_Stereographic_Parameters.         
+ */
+
+
+/************************************************************************/
+/*                              FUNCTIONS
+ *
+ */
+
+
+long Set_Polar_Stereographic_Parameters (double a,
+                                         double f,
+                                         double Latitude_of_True_Scale,
+                                         double Longitude_Down_from_Pole,
+                                         double False_Easting,
+                                         double False_Northing)
+
+{  /* BEGIN Set_Polar_Stereographic_Parameters   */
+/*  
+ *  The function Set_Polar_Stereographic_Parameters receives the ellipsoid
+ *  parameters and Polar Stereograpic projection parameters as inputs, and
+ *  sets the corresponding state variables.  If any errors occur, error
+ *  code(s) are returned by the function, otherwise POLAR_NO_ERROR is returned.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (input)
+ *  f                : Flattening of ellipsoid					               (input)
+ *  Latitude_of_True_Scale  : Latitude of true scale, in radians       (input)
+ *  Longitude_Down_from_Pole : Longitude down from pole, in radians    (input)
+ *  False_Easting    : Easting (X) at center of projection, in meters  (input)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (input)
+ */
+
+  double es2;
+  double slat, clat;
+  double essin;
+  double one_PLUS_es, one_MINUS_es;
+  double pow_es;
+  double temp;
+  double inv_f = 1 / f;
+  const double  epsilon = 1.0e-2;
+  long Error_Code = POLAR_NO_ERROR;
+
+  if (a <= 0.0)
+  { /* Semi-major axis must be greater than zero */
+    Error_Code |= POLAR_A_ERROR;
+  }
+  if ((inv_f < 250) || (inv_f > 350))
+  { /* Inverse flattening must be between 250 and 350 */
+    Error_Code |= POLAR_INV_F_ERROR;
+  }
+  if ((Latitude_of_True_Scale < -PI_OVER_2) || (Latitude_of_True_Scale > PI_OVER_2))
+  { /* Origin Latitude out of range */
+    Error_Code |= POLAR_ORIGIN_LAT_ERROR;
+  }
+  if ((Longitude_Down_from_Pole < -PI) || (Longitude_Down_from_Pole > TWO_PI))
+  { /* Origin Longitude out of range */
+    Error_Code |= POLAR_ORIGIN_LON_ERROR;
+  }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    Polar_a = a;
+    two_Polar_a = 2.0 * Polar_a;
+    Polar_f = f;
+
+    if (Longitude_Down_from_Pole > PI)
+      Longitude_Down_from_Pole -= TWO_PI;
+    if (Latitude_of_True_Scale < 0)
+    {
+      Southern_Hemisphere = 1;
+      Polar_Origin_Lat = -Latitude_of_True_Scale;
+      Polar_Origin_Long = -Longitude_Down_from_Pole;
+    }
+    else
+    {
+      Southern_Hemisphere = 0;
+      Polar_Origin_Lat = Latitude_of_True_Scale;
+      Polar_Origin_Long = Longitude_Down_from_Pole;
+    }
+    Polar_False_Easting = False_Easting;
+    Polar_False_Northing = False_Northing;
+
+    es2 = 2 * Polar_f - Polar_f * Polar_f;
+    es = sqrt(es2);
+    es_OVER_2 = es / 2.0;
+
+    if (fabs(fabs(Polar_Origin_Lat) - PI_OVER_2) > 1.0e-10)
+    {
+      slat = sin(Polar_Origin_Lat);
+      essin = es * slat;
+      pow_es = POLAR_POW(essin);
+      clat = cos(Polar_Origin_Lat);
+      mc = clat / sqrt(1.0 - essin * essin);
+      Polar_a_mc = Polar_a * mc;
+      tc = tan(PI_Over_4 - Polar_Origin_Lat / 2.0) / pow_es;
+    }
+    else
+    {
+      one_PLUS_es = 1.0 + es;
+      one_MINUS_es = 1.0 - es;
+      e4 = sqrt(pow(one_PLUS_es, one_PLUS_es) * pow(one_MINUS_es, one_MINUS_es));
+    }
+  }
+  /* Calculate Radius */
+  Convert_Geodetic_To_Polar_Stereographic(0, Polar_Origin_Long, 
+                                          &temp, &Polar_Delta_Northing);
+  Polar_Delta_Northing = fabs(Polar_Delta_Northing) + epsilon;
+  Polar_Delta_Easting = Polar_Delta_Northing;
+
+
+  return (Error_Code);
+} /* END OF Set_Polar_Stereographic_Parameters */
+
+
+
+void Get_Polar_Stereographic_Parameters (double *a,
+                                         double *f,
+                                         double *Latitude_of_True_Scale,
+                                         double *Longitude_Down_from_Pole,
+                                         double *False_Easting,
+                                         double *False_Northing)
+
+{ /* BEGIN Get_Polar_Stereographic_Parameters  */
+/*
+ * The function Get_Polar_Stereographic_Parameters returns the current
+ * ellipsoid parameters and Polar projection parameters.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (output)
+ *  f                : Flattening of ellipsoid					               (output)
+ *  Latitude_of_True_Scale  : Latitude of true scale, in radians       (output)
+ *  Longitude_Down_from_Pole : Longitude down from pole, in radians    (output)
+ *  False_Easting    : Easting (X) at center of projection, in meters  (output)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (output)
+ */
+
+  *a = Polar_a;
+  *f = Polar_f;
+  *Latitude_of_True_Scale = Polar_Origin_Lat;
+  *Longitude_Down_from_Pole = Polar_Origin_Long;
+  *False_Easting = Polar_False_Easting;
+  *False_Northing = Polar_False_Northing;
+  return;
+} /* END OF Get_Polar_Stereographic_Parameters */
+
+
+long Convert_Geodetic_To_Polar_Stereographic (double Latitude,
+                                              double Longitude,
+                                              double *Easting,
+                                              double *Northing)
+
+{  /* BEGIN Convert_Geodetic_To_Polar_Stereographic */
+
+/*
+ * The function Convert_Geodetic_To_Polar_Stereographic converts geodetic
+ * coordinates (latitude and longitude) to Polar Stereographic coordinates
+ * (easting and northing), according to the current ellipsoid
+ * and Polar Stereographic projection parameters. If any errors occur, error
+ * code(s) are returned by the function, otherwise POLAR_NO_ERROR is returned.
+ *
+ *    Latitude   :  Latitude, in radians                      (input)
+ *    Longitude  :  Longitude, in radians                     (input)
+ *    Easting    :  Easting (X), in meters                    (output)
+ *    Northing   :  Northing (Y), in meters                   (output)
+ */
+
+  double dlam;
+  double slat;
+  double essin;
+  double t;
+  double rho;
+  double pow_es;
+  long Error_Code = POLAR_NO_ERROR;
+
+  if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+  {   /* Latitude out of range */
+    Error_Code |= POLAR_LAT_ERROR;
+  }
+  if ((Latitude < 0) && (Southern_Hemisphere == 0))
+  {   /* Latitude and Origin Latitude in different hemispheres */
+    Error_Code |= POLAR_LAT_ERROR;
+  }
+  if ((Latitude > 0) && (Southern_Hemisphere == 1))
+  {   /* Latitude and Origin Latitude in different hemispheres */
+    Error_Code |= POLAR_LAT_ERROR;
+  }
+  if ((Longitude < -PI) || (Longitude > TWO_PI))
+  {  /* Longitude out of range */
+    Error_Code |= POLAR_LON_ERROR;
+  }
+
+
+  if (!Error_Code)
+  {  /* no errors */
+
+    if (fabs(fabs(Latitude) - PI_OVER_2) < 1.0e-10)
+    {
+      *Easting = 0.0;
+      *Northing = 0.0;
+    }
+    else
+    {
+      if (Southern_Hemisphere != 0)
+      {
+        Longitude *= -1.0;
+        Latitude *= -1.0;
+      }
+      dlam = Longitude - Polar_Origin_Long;
+      if (dlam > PI)
+      {
+        dlam -= TWO_PI;
+      }
+      if (dlam < -PI)
+      {
+        dlam += TWO_PI;
+      }
+      slat = sin(Latitude);
+      essin = es * slat;
+      pow_es = POLAR_POW(essin);
+      t = tan(PI_Over_4 - Latitude / 2.0) / pow_es;
+
+      if (fabs(fabs(Polar_Origin_Lat) - PI_OVER_2) > 1.0e-10)
+        rho = Polar_a_mc * t / tc;
+      else
+        rho = two_Polar_a * t / e4;
+
+      *Easting = rho * sin(dlam) + Polar_False_Easting;
+
+      if (Southern_Hemisphere != 0)
+      {
+        *Easting *= -1.0;
+        *Northing = rho * cos(dlam) + Polar_False_Northing;
+      }
+      else
+        *Northing = -rho * cos(dlam) + Polar_False_Northing;
+
+    }
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Polar_Stereographic */
+
+
+long Convert_Polar_Stereographic_To_Geodetic (double Easting,
+                                              double Northing,
+                                              double *Latitude,
+                                              double *Longitude)
+
+{ /*  BEGIN Convert_Polar_Stereographic_To_Geodetic  */
+/*
+ *  The function Convert_Polar_Stereographic_To_Geodetic converts Polar
+ *  Stereographic coordinates (easting and northing) to geodetic
+ *  coordinates (latitude and longitude) according to the current ellipsoid
+ *  and Polar Stereographic projection Parameters. If any errors occur, the
+ *  code(s) are returned by the function, otherwise POLAR_NO_ERROR
+ *  is returned.
+ *
+ *  Easting          : Easting (X), in meters                   (input)
+ *  Northing         : Northing (Y), in meters                  (input)
+ *  Latitude         : Latitude, in radians                     (output)
+ *  Longitude        : Longitude, in radians                    (output)
+ *
+ */
+
+  double dy, dx;
+  double rho;
+  double t;
+  double PHI, sin_PHI;
+  double tempPHI = 0.0;
+  double essin;
+  double pow_es;
+  double temp;
+  long Error_Code = POLAR_NO_ERROR;
+
+  if ((Easting > (Polar_False_Easting + Polar_Delta_Easting)) ||
+      (Easting < (Polar_False_Easting - Polar_Delta_Easting)))
+  { /* Easting out of range */
+    Error_Code |= POLAR_EASTING_ERROR;
+  }
+  if ((Northing > (Polar_False_Northing + Polar_Delta_Northing)) ||
+      (Northing < (Polar_False_Northing - Polar_Delta_Northing)))
+  { /* Northing out of range */
+    Error_Code |= POLAR_NORTHING_ERROR;
+  }
+  if (!Error_Code)
+  {
+    temp = sqrt(Easting * Easting + Northing * Northing);     
+
+    if ((temp > (Polar_False_Easting + Polar_Delta_Easting)) || 
+        (temp > (Polar_False_Northing + Polar_Delta_Northing)) ||
+        (temp < (Polar_False_Easting - Polar_Delta_Easting)) || 
+        (temp < (Polar_False_Northing - Polar_Delta_Northing)))
+    { /* Point is outside of projection area */
+      Error_Code |= POLAR_RADIUS_ERROR;
+    }
+  }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    dy = Northing - Polar_False_Northing;
+    dx = Easting - Polar_False_Easting;
+    if ((dy == 0.0) && (dx == 0.0))
+    {
+      *Latitude = PI_OVER_2;
+      *Longitude = Polar_Origin_Long;
+
+    }
+    else
+    {
+      if (Southern_Hemisphere != 0)
+      {
+        dy *= -1.0;
+        dx *= -1.0;
+      }
+
+      rho = sqrt(dx * dx + dy * dy);
+      if (fabs(fabs(Polar_Origin_Lat) - PI_OVER_2) > 1.0e-10)
+        t = rho * tc / (Polar_a_mc);
+      else
+        t = rho * e4 / (two_Polar_a);
+      PHI = PI_OVER_2 - 2.0 * atan(t);
+      while (fabs(PHI - tempPHI) > 1.0e-10)
+      {
+        tempPHI = PHI;
+        sin_PHI = sin(PHI);
+        essin =  es * sin_PHI;
+        pow_es = POLAR_POW(essin);
+        PHI = PI_OVER_2 - 2.0 * atan(t * pow_es);
+      }
+      *Latitude = PHI;
+      *Longitude = Polar_Origin_Long + atan2(dx, -dy);
+
+      if (*Longitude > PI)
+        *Longitude -= TWO_PI;
+      else if (*Longitude < -PI)
+        *Longitude += TWO_PI;
+
+
+      if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+        *Latitude = PI_OVER_2;
+      else if (*Latitude < -PI_OVER_2)
+        *Latitude = -PI_OVER_2;
+
+      if (*Longitude > PI)  /* force distorted values to 180, -180 degrees */
+        *Longitude = PI;
+      else if (*Longitude < -PI)
+        *Longitude = -PI;
+
+    }
+    if (Southern_Hemisphere != 0)
+    {
+      *Latitude *= -1.0;
+      *Longitude *= -1.0;
+    }
+
+  }
+  return (Error_Code);
+} /* END OF Convert_Polar_Stereographic_To_Geodetic */
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarst.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarst.h
new file mode 100644
index 0000000000..60b8aa00c9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolarst.h
@@ -0,0 +1,202 @@
+#ifndef POLARST_H
+  #define POLARST_H
+/***************************************************************************/
+/* RSC IDENTIFIER: POLAR STEREOGRAPHIC 
+ *
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between geodetic (latitude and
+ *    longitude) coordinates and Polar Stereographic (easting and northing) 
+ *    coordinates.
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid 
+ *    value is found the error code is combined with the current error code 
+ *    using the bitwise or.  This combining allows multiple error codes to 
+ *    be returned. The possible error codes are:
+ *
+ *          POLAR_NO_ERROR           : No errors occurred in function
+ *          POLAR_LAT_ERROR          : Latitude outside of valid range
+ *                                      (-90 to 90 degrees)
+ *          POLAR_LON_ERROR          : Longitude outside of valid range
+ *                                      (-180 to 360 degrees) 
+ *          POLAR_ORIGIN_LAT_ERROR   : Latitude of true scale outside of valid
+ *                                      range (-90 to 90 degrees)
+ *          POLAR_ORIGIN_LON_ERROR   : Longitude down from pole outside of valid
+ *                                      range (-180 to 360 degrees)
+ *          POLAR_EASTING_ERROR      : Easting outside of valid range,
+ *                                      depending on ellipsoid and
+ *                                      projection parameters
+ *          POLAR_NORTHING_ERROR     : Northing outside of valid range,
+ *                                      depending on ellipsoid and
+ *                                      projection parameters
+ *          POLAR_RADIUS_ERROR       : Coordinates too far from pole,
+ *                                      depending on ellipsoid and
+ *                                      projection parameters
+ *          POLAR_A_ERROR            : Semi-major axis less than or equal to zero
+ *          POLAR_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	                  (250 to 350)
+ *
+ *
+ * REUSE NOTES
+ *
+ *    POLAR STEREOGRAPHIC is intended for reuse by any application that  
+ *    performs a Polar Stereographic projection.
+ *
+ *
+ * REFERENCES
+ *
+ *    Further information on POLAR STEREOGRAPHIC can be found in the
+ *    Reuse Manual.
+ *
+ *
+ *    POLAR STEREOGRAPHIC originated from :
+ *                                U.S. Army Topographic Engineering Center
+ *                                Geospatial Information Division
+ *                                7701 Telegraph Road
+ *                                Alexandria, VA  22310-3864
+ *
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ *
+ * RESTRICTIONS
+ *
+ *    POLAR STEREOGRAPHIC has no restrictions.
+ *
+ *
+ * ENVIRONMENT
+ *
+ *    POLAR STEREOGRAPHIC was tested and certified in the following
+ *    environments:
+ *
+ *    1. Solaris 2.5 with GCC, version 2.8.1
+ *    2. Window 95 with MS Visual C++, version 6
+ *
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    06-11-95          Original Code
+ *    03-01-97          Original Code
+ *
+ *
+ */
+
+
+/**********************************************************************/
+/*
+ *                        DEFINES
+ */
+
+  #define POLAR_NO_ERROR                0x0000
+  #define POLAR_LAT_ERROR               0x0001
+  #define POLAR_LON_ERROR               0x0002
+  #define POLAR_ORIGIN_LAT_ERROR        0x0004
+  #define POLAR_ORIGIN_LON_ERROR        0x0008
+  #define POLAR_EASTING_ERROR			  0x0010
+  #define POLAR_NORTHING_ERROR		  0x0020
+  #define POLAR_A_ERROR                 0x0040
+  #define POLAR_INV_F_ERROR             0x0080
+  #define POLAR_RADIUS_ERROR            0x0100
+
+/**********************************************************************/
+/*
+ *                        FUNCTION PROTOTYPES
+ */
+
+/* ensure proper linkage to c++ programs */
+  #ifdef __cplusplus
+extern "C" {
+  #endif
+
+  long Set_Polar_Stereographic_Parameters (double a,
+                                           double f,
+                                           double Latitude_of_True_Scale,
+                                           double Longitude_Down_from_Pole,
+                                           double False_Easting,
+                                           double False_Northing);
+/*  
+ *  The function Set_Polar_Stereographic_Parameters receives the ellipsoid
+ *  parameters and Polar Stereograpic projection parameters as inputs, and
+ *  sets the corresponding state variables.  If any errors occur, error
+ *  code(s) are returned by the function, otherwise POLAR_NO_ERROR is returned.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (input)
+ *  f                : Flattening of ellipsoid                         (input)
+ *  Latitude_of_True_Scale  : Latitude of true scale, in radians       (input)
+ *  Longitude_Down_from_Pole : Longitude down from pole, in radians    (input)
+ *  False_Easting    : Easting (X) at center of projection, in meters  (input)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (input)
+ */
+
+
+  void Get_Polar_Stereographic_Parameters (double *a,
+                                           double *f,
+                                           double *Latitude_of_True_Scale,
+                                           double *Longitude_Down_from_Pole,
+                                           double *False_Easting,
+                                           double *False_Northing);
+/*
+ * The function Get_Polar_Stereographic_Parameters returns the current
+ * ellipsoid parameters and Polar projection parameters.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (output)
+ *  f                : Flattening of ellipsoid                         (output)
+ *  Latitude_of_True_Scale  : Latitude of true scale, in radians       (output)
+ *  Longitude_Down_from_Pole : Longitude down from pole, in radians    (output)
+ *  False_Easting    : Easting (X) at center of projection, in meters  (output)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (output)
+ */
+
+
+  long Convert_Geodetic_To_Polar_Stereographic (double Latitude,
+                                                double Longitude,
+                                                double *Easting,
+                                                double *Northing);
+/*
+ * The function Convert_Geodetic_To_Polar_Stereographic converts geodetic
+ * coordinates (latitude and longitude) to Polar Stereographic coordinates
+ * (easting and northing), according to the current ellipsoid
+ * and Polar Stereographic projection parameters. If any errors occur, error
+ * code(s) are returned by the function, otherwise POLAR_NO_ERROR is returned.
+ *
+ *    Latitude   :  Latitude, in radians                      (input)
+ *    Longitude  :  Longitude, in radians                     (input)
+ *    Easting    :  Easting (X), in meters                    (output)
+ *    Northing   :  Northing (Y), in meters                   (output)
+ */
+
+
+
+  long Convert_Polar_Stereographic_To_Geodetic (double Easting,
+                                                double Northing,
+                                                double *Latitude,
+                                                double *Longitude);
+
+/*
+ *  The function Convert_Polar_Stereographic_To_Geodetic converts Polar
+ *  Stereographic coordinates (easting and northing) to geodetic
+ *  coordinates (latitude and longitude) according to the current ellipsoid
+ *  and Polar Stereographic projection Parameters. If any errors occur, the
+ *  code(s) are returned by the function, otherwise POLAR_NO_ERROR
+ *  is returned.
+ *
+ *  Easting          : Easting (X), in meters                   (input)
+ *  Northing         : Northing (Y), in meters                  (input)
+ *  Latitude         : Latitude, in radians                     (output)
+ *  Longitude        : Longitude, in radians                    (output)
+ *
+ */
+
+  #ifdef __cplusplus
+}
+  #endif
+
+#endif  /* POLARST_H  */
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolyconicProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolyconicProjection.cpp
new file mode 100644
index 0000000000..c3af40d504
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolyconicProjection.cpp
@@ -0,0 +1,529 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Polyconic  projection code.  
+//*******************************************************************
+//  $Id: ossimPolyconicProjection.cpp,v 1.12 2004/01/08 21:49:22 jlargent Exp $
+
+#include <math.h>
+#include "ossimPolyconicProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimPolyconicProjection, "ossimPolyconicProjection", ossimMapProjection)
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define POLY_COEFF_TIMES_SIN(coeff, x, latit)         (coeff * (sin (x * latit)))
+#define POLY_M(c0lat,c1s2lat,c2s4lat,c3s6lat)   (Poly_a*(c0lat - c1s2lat + c2s4lat - c3s6lat)) 
+#define FLOAT_EQ(x,v,epsilon)   (((v - epsilon) < x) && (x < (v + epsilon)))
+#define FOURTY_ONE (41.0 * M_PI / 180.0)  /* 41 degrees in radians */
+
+#define POLY_NO_ERROR           0x0000
+#define POLY_LAT_ERROR          0x0001
+#define POLY_LON_ERROR          0x0002
+#define POLY_EASTING_ERROR      0x0004
+#define POLY_NORTHING_ERROR     0x0008
+#define POLY_ORIGIN_LAT_ERROR   0x0010
+#define POLY_CENT_MER_ERROR     0x0020
+#define POLY_A_ERROR            0x0040
+#define POLY_B_ERROR            0x0080
+#define POLY_A_LESS_B_ERROR     0x0100
+#define POLY_LON_WARNING        0x0200
+
+ossimPolyconicProjection::ossimPolyconicProjection(const ossimEllipsoid& ellipsoid,
+                                                       const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimPolyconicProjection::ossimPolyconicProjection(const ossimEllipsoid& ellipsoid,
+                                                   const ossimGpt& origin,
+                                                   double falseEasting,
+                                                   double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Poly_False_Easting  = falseEasting;
+   Poly_False_Northing = falseNorthing;
+   Poly_Max_Easting    = 20037509.0;
+   Poly_Max_Northing   = 15348215.0;
+   Poly_Min_Easting    = -20037509.0;
+   Poly_Min_Northing   = -15348215.0;
+
+   update();
+}
+
+void ossimPolyconicProjection::update()
+{   
+   Set_Polyconic_Parameters(theEllipsoid.getA(),
+                            theEllipsoid.getFlattening(),
+                            theOrigin.latr(),
+                            theOrigin.lonr(),
+                            Poly_False_Easting,
+                            Poly_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimPolyconicProjection::setFalseEasting(double falseEasting)
+{
+   Poly_False_Easting = falseEasting;
+   
+   update();
+}
+
+void ossimPolyconicProjection::setFalseNorthing(double falseNorthing)
+{
+   Poly_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimPolyconicProjection::setDefaults()
+{
+   Poly_False_Easting  = 0.0;
+   Poly_False_Northing = 0.0;
+   Poly_Max_Easting    = 20037509.0;
+   Poly_Max_Northing   = 15348215.0;
+   Poly_Min_Easting    = -20037509.0;
+   Poly_Min_Northing   = -15348215.0;
+}
+
+void ossimPolyconicProjection::setFalseEastingNorthing(double falseEasting,
+                                                      double falseNorthing)
+{
+   Poly_False_Easting  = falseEasting;
+   Poly_False_Northing = falseNorthing;
+   
+   update();
+}
+
+ossimGpt ossimPolyconicProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+
+   Convert_Polyconic_To_Geodetic(eastingNorthing.x,
+                                 eastingNorthing.y,
+                                 &lat,
+                                 &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimPolyconicProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Polyconic(gpt.latr(),
+                                 gpt.lonr(),
+                                 &easting,
+                                 &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+bool ossimPolyconicProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Poly_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Poly_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimPolyconicProjection::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimPolyconicProjection))
+   {
+      if(falseEasting)
+      {
+         Poly_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Poly_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+
+   return flag;
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+long ossimPolyconicProjection::Set_Polyconic_Parameters(double a,
+                                                        double f,
+                                                        double Origin_Latitude,
+                                                        double Central_Meridian,
+                                                        double False_Easting,
+                                                        double False_Northing)
+
+{ /* BEGIN Set_Polyconic_Parameters */
+/*
+ * The function Set_Polyconic_Parameters receives the ellipsoid parameters and
+ * Polyconic projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise POLY_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double j, three_es4;
+  double lat, sin2lat, sin4lat, sin6lat;
+  double temp;
+//  double inv_f = 1 / f;
+  long Error_Code = POLY_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= POLY_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= POLY_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+//   { /* origin latitude out of range */
+//     Error_Code |= POLY_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= POLY_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Poly_a = a;
+    Poly_f = f;
+    Poly_Origin_Lat = Origin_Latitude;
+//     if (Central_Meridian > M_PI)
+//       Central_Meridian -= TWO_PI;
+    Poly_Origin_Long = Central_Meridian;
+    Poly_False_Northing = False_Northing;
+    Poly_False_Easting = False_Easting;
+    es2 = 2 * Poly_f - Poly_f * Poly_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+
+    j = 45.0 * es6 / 1024.0;
+    three_es4 = 3.0 * es4;
+    c0 = 1.0 - es2 / 4.0 - three_es4 / 64.0 - 5.0 * es6 / 256.0;
+    c1 = 3.0 * es2 / 8.0 + three_es4 / 32.0 + j;
+    c2 = 15.0 * es4 / 256.0 + j;
+    c3 = 35.0 * es6 / 3072.0;
+
+    lat = c0 * Poly_Origin_Lat;
+    sin2lat = POLY_COEFF_TIMES_SIN(c1, 2.0, Poly_Origin_Lat);
+    sin4lat = POLY_COEFF_TIMES_SIN(c2, 4.0, Poly_Origin_Lat);
+    sin6lat = POLY_COEFF_TIMES_SIN(c3, 6.0, Poly_Origin_Lat);
+    M0 = POLY_M(lat, sin2lat, sin4lat, sin6lat);
+
+    if (Poly_Origin_Long > 0)
+    {
+      Convert_Geodetic_To_Polyconic(FOURTY_ONE, Poly_Origin_Long - M_PI, &temp, &Poly_Max_Northing);
+      Convert_Geodetic_To_Polyconic(-FOURTY_ONE, Poly_Origin_Long - M_PI, &temp, &Poly_Min_Northing);
+      Poly_Max_Easting = 19926189.0;
+      Poly_Min_Easting = -20037509.0;
+    }
+    else if (Poly_Origin_Long < 0)
+    {
+      Convert_Geodetic_To_Polyconic(FOURTY_ONE, Poly_Origin_Long + M_PI, &temp, &Poly_Max_Northing);
+      Convert_Geodetic_To_Polyconic(-FOURTY_ONE, Poly_Origin_Long + M_PI, &temp, &Poly_Min_Northing);
+      Poly_Max_Easting = 20037509.0;
+      Poly_Min_Easting = -19926189.0;
+    }
+    else
+    {
+      Convert_Geodetic_To_Polyconic(FOURTY_ONE, M_PI, &temp, &Poly_Max_Northing);
+      Convert_Geodetic_To_Polyconic(-FOURTY_ONE, M_PI, &temp, &Poly_Min_Northing);
+      Poly_Max_Easting = 20037509.0;
+      Poly_Min_Easting = -20037509.0;
+    }
+
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+} /* END OF Set_Polyconic_Parameters */
+
+void ossimPolyconicProjection::Get_Polyconic_Parameters(double *a,
+                                                        double *f,
+                                                        double *Origin_Latitude,
+                                                        double *Central_Meridian,
+                                                        double *False_Easting,
+                                                        double *False_Northing)const
+
+{ /* BEGIN Get_Polyconic_Parameters */
+/*
+ * The function Get_Polyconic_Parameters returns the current ellipsoid
+ * parameters, and Polyconic projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Poly_a;
+  *f = Poly_f;
+  *Origin_Latitude = Poly_Origin_Lat;
+  *Central_Meridian = Poly_Origin_Long;
+  *False_Easting = Poly_False_Easting;
+  *False_Northing = Poly_False_Northing;
+  
+  return;
+} /* END OF Get_Polyconic_Parameters */
+
+
+long ossimPolyconicProjection::Convert_Geodetic_To_Polyconic (double Latitude,
+                                                              double Longitude,
+                                                              double *Easting,
+                                                              double *Northing)const
+{ /* BEGIN Convert_Geodetic_To_Polyconic */
+/*
+ * The function Convert_Geodetic_To_Polyconic converts geodetic (latitude and
+ * longitude) coordinates to Polyconic projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Polyconic projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise POLY_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double slat = sin(Latitude);
+  double lat, sin2lat, sin4lat, sin6lat;
+  double dlam;                      /* Longitude - Central Meridan */
+  double NN;
+  double NN_OVER_tlat;
+  double MM;
+  double EE;
+  long Error_Code = POLY_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   { /* Latitude out of range */
+//     Error_Code |= POLY_LAT_ERROR;
+//   }
+//   if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+//   { /* Longitude out of range */
+//     Error_Code |= POLY_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Poly_Origin_Long;
+    if (fabs(dlam) > (M_PI / 2.0))
+    { /* Distortion will result if Longitude is more than 90 degrees from the Central Meridian */
+      Error_Code |= POLY_LON_WARNING;
+    }
+//     if (dlam > M_PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -M_PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+    if (Latitude == 0.0)
+    {
+      *Easting = Poly_a * dlam + Poly_False_Easting;
+      *Northing = -M0 + Poly_False_Northing;
+    }
+    else
+    {
+      NN = Poly_a / sqrt(1.0 - es2 * (slat * slat));
+      NN_OVER_tlat = NN  / tan(Latitude);
+      lat = c0 * Latitude;
+      sin2lat = POLY_COEFF_TIMES_SIN(c1, 2.0, Latitude);
+      sin4lat = POLY_COEFF_TIMES_SIN(c2, 4.0, Latitude);
+      sin6lat = POLY_COEFF_TIMES_SIN(c3, 6.0, Latitude);
+      MM = POLY_M(lat, sin2lat, sin4lat, sin6lat);
+      EE = dlam * slat;
+      *Easting = NN_OVER_tlat * sin(EE) + Poly_False_Easting;
+      *Northing = MM - M0 + NN_OVER_tlat * (1.0 - cos(EE)) +
+                  Poly_False_Northing;
+    }
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Polyconic */
+
+
+long ossimPolyconicProjection::Convert_Polyconic_To_Geodetic(double Easting,
+                                                             double Northing,
+                                                             double *Latitude,
+                                                             double *Longitude)const
+{ /* BEGIN Convert_Polyconic_To_Geodetic */
+/*
+ * The function Convert_Polyconic_To_Geodetic converts Polyconic projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Polyconic projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise POLY_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx;     /* Delta easting - Difference in easting (easting-FE)      */
+  double dy;     /* Delta northing - Difference in northing (northing-FN)   */
+  double dx_OVER_Poly_a;
+  double AA;
+  double BB;
+  double CC = 0.0;
+  double PHIn, Delta_PHI = 1.0;
+  double sin_PHIn;
+  double PHI, sin2PHI,sin4PHI, sin6PHI;
+  double Mn, Mn_prime, Ma;
+  double AA_Ma;
+  double Ma2_PLUS_BB;
+  double AA_MINUS_Ma;
+  double tolerance = 1.0e-12;        /* approximately 1/1000th of
+                               an arc second or 1/10th meter */
+  long Error_Code = POLY_NO_ERROR;
+
+//   if ((Easting < (Poly_False_Easting + Poly_Min_Easting))
+//       || (Easting > (Poly_False_Easting + Poly_Max_Easting)))
+//   { /* Easting out of range */
+//     Error_Code |= POLY_EASTING_ERROR;
+//   }
+//   if ((Northing < (Poly_False_Northing + Poly_Min_Northing))
+//       || (Northing > (Poly_False_Northing + Poly_Max_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= POLY_NORTHING_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dy = Northing - Poly_False_Northing;
+    dx = Easting - Poly_False_Easting;
+    dx_OVER_Poly_a = dx / Poly_a;
+    if (FLOAT_EQ(dy,-M0,1))
+    {
+      *Latitude = 0.0;
+      *Longitude = dx_OVER_Poly_a + Poly_Origin_Long;
+    }
+    else
+    {
+      AA = (M0 + dy) / Poly_a;
+      BB = dx_OVER_Poly_a * dx_OVER_Poly_a + (AA * AA);
+      PHIn = AA;
+
+      while (fabs(Delta_PHI) > tolerance)
+      {
+        sin_PHIn = sin(PHIn);
+        CC = sqrt(1.0 - es2 * sin_PHIn * sin_PHIn) * tan(PHIn);
+        PHI = c0 * PHIn;
+        sin2PHI = POLY_COEFF_TIMES_SIN(c1, 2.0, PHIn);
+        sin4PHI = POLY_COEFF_TIMES_SIN(c2, 4.0, PHIn);
+        sin6PHI = POLY_COEFF_TIMES_SIN(c3, 6.0, PHIn);
+        Mn = POLY_M(PHI, sin2PHI, sin4PHI, sin6PHI);
+        Mn_prime = c0 - 2.0 * c1 * cos(2.0 * PHIn) + 4.0 * c2 * cos(4.0 * PHIn) - 
+                   6.0 * c3 * cos(6.0 * PHIn);  
+        Ma = Mn / Poly_a;
+        AA_Ma = AA * Ma;
+        Ma2_PLUS_BB = Ma * Ma + BB;
+        AA_MINUS_Ma = AA - Ma;
+        Delta_PHI = (AA_Ma * CC + AA_MINUS_Ma - 0.5 * (Ma2_PLUS_BB) * CC) /
+                    (es2 * sin2PHI * (Ma2_PLUS_BB - 2.0 * AA_Ma) /
+                     4.0 * CC + (AA_MINUS_Ma) * (CC * Mn_prime - 2.0 / sin2PHI) - Mn_prime);
+        PHIn -= Delta_PHI;
+      }
+      *Latitude = PHIn;
+
+//       if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//         *Latitude = PI_OVER_2;
+//       else if (*Latitude < -PI_OVER_2)
+//         *Latitude = -PI_OVER_2;
+
+      if (FLOAT_EQ(fabs(*Latitude),PI_OVER_2,.00001) || (*Latitude == 0))
+        *Longitude = Poly_Origin_Long;
+
+      else
+      {
+        *Longitude = (asin(dx_OVER_Poly_a * CC)) / sin(*Latitude) +
+                     Poly_Origin_Long;
+      }
+    }
+//     if (*Longitude > M_PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -M_PI)
+//       *Longitude += TWO_PI;
+
+//     if (*Longitude > M_PI)  /* force distorted values to 180, -180 degrees */
+//       *Longitude = M_PI;
+//     else if (*Longitude < -M_PI)
+//       *Longitude = -M_PI;
+
+  }
+  return (Error_Code);
+} /* END OF Convert_Polyconic_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolyconicProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolyconicProjection.h
new file mode 100644
index 0000000000..d45236a668
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimPolyconicProjection.h
@@ -0,0 +1,203 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Polyconic  projection code.  
+//*******************************************************************
+//  $Id: ossimPolyconicProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimPolyconicProjection_HEADER
+#define ossimPolyconicProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimPolyconicProjection : public ossimMapProjection
+{
+public:   
+   ossimPolyconicProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                            const ossimGpt& origin = ossimGpt());
+   ossimPolyconicProjection(const ossimEllipsoid& ellipsoid,
+                            const ossimGpt& origin,
+                            const double falseEasting,
+                            const double falseNorthing);
+   ~ossimPolyconicProjection(){}
+   virtual ossimObject *dup()const
+      {
+         return new ossimPolyconicProjection(*this);
+      }
+   
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return  Poly_False_Easting;}
+   double getFalseNorthing()const{return Poly_False_Northing;}
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+private:
+   
+   mutable double Poly_a;                      /* Semi-major axis of ellipsoid in meters */
+   mutable double Poly_f;              /* Flattening of ellipsoid */
+   mutable double es2;             /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;              /* es2 * es2 */
+   mutable double es6;              /* es4 * es2 */
+   mutable double M0;
+   mutable double c0;      /* 1 - es2 / 4.0 - 3.0 * es4 / 64.0 - 5.0 * es6 / 256.0 */
+   mutable double c1; /* 3.0 * es2 / 8.0 + 3.0 * es4 / 32.0 + 45.0 * es6 / 1024.0 */
+   mutable double c2;             /* 15.0 * es4 / 256.0 + 45.0 * es6 / 1024.0 */
+   mutable double c3;               /* 35.0 * es6 / 3072.0 */
+   
+/* Polyconic projection Parameters */
+   mutable double Poly_Origin_Lat;                   /* Latitude of origin in radians     */
+   mutable double Poly_Origin_Long;                  /* Longitude of origin in radians    */
+   mutable double Poly_False_Northing;               /* False northing in meters          */
+   mutable double Poly_False_Easting;                /* False easting in meters           */
+   
+/* Maximum variance for easting and northing values for WGS 84.
+ */
+   mutable double Poly_Max_Easting;
+   mutable double Poly_Max_Northing;
+   mutable double Poly_Min_Easting;
+   mutable double Poly_Min_Northing;
+
+/*!
+ * The function Set_Polyconic_Parameters receives the ellipsoid parameters and
+ * Polyconic projcetion parameters as inputs, and sets the corresponding state
+ * variables.If any errors
+ * occur, the error code(s) are returned by the function, otherwise 
+ * POLY_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Polyconic_Parameters(double a,
+                                double f,
+                                double Origin_Latitude,
+                                double Central_Meridian,
+                                double False_Easting,
+                                double False_Northing);
+
+
+
+/*!
+ * The function Get_Polyconic_Parameters returns the current ellipsoid
+ * parameters, and Polyconic projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid                   (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Polyconic_Parameters(double *a,
+                                double *f,
+                                double *Origin_Latitude,
+                                double *Central_Meridian,
+                                double *False_Easting,
+                                double *False_Northing)const;
+
+
+
+/*!
+ * The function Convert_Geodetic_To_Polyconic converts geodetic (latitude and
+ * longitude) coordinates to Polyconic projection easting, and northing
+ * coordinates, according to the current ellipsoid and Polyconic projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise POLY_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Polyconic (double Latitude,
+                                      double Longitude,
+                                      double *Easting,
+                                      double *Northing)const; 
+
+
+/*!
+ * The function Convert_Polyconic_To_Geodetic converts Polyconic projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Polyconic projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise POLY_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Polyconic_To_Geodetic(double Easting,
+                                     double Northing,
+                                     double *Latitude,
+                                     double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoid.c b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoid.c
new file mode 100644
index 0000000000..f50d76a4d8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoid.c
@@ -0,0 +1,388 @@
+/***************************************************************************/
+/* RSC IDENTIFIER: SINUSOIDAL
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between Geodetic coordinates 
+ *    (latitude and longitude in radians) and Sinusoid projection coordinates
+ *    (easting and northing in meters).
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *          SINU_NO_ERROR           : No errors occurred in function
+ *          SINU_LAT_ERROR          : Latitude outside of valid range
+ *                                      (-90 to 90 degrees)
+ *          SINU_LON_ERROR          : Longitude outside of valid range
+ *                                      (-180 to 360 degrees)
+ *          SINU_EASTING_ERROR      : Easting outside of valid range
+ *                                      (False_Easting +/- ~20,000,000 m,
+ *                                       depending on ellipsoid parameters)
+ *          SINU_NORTHING_ERROR     : Northing outside of valid range
+ *                                      (False_Northing +/- ~10,000,000 m,
+ *                                       depending on ellipsoid parameters)
+ *          SINU_CENT_MER_ERROR     : Origin longitude outside of valid range
+ *                                      (-180 to 360 degrees)
+ *          SINU_A_ERROR            : Semi-major axis less than or equal to zero
+ *          SINU_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	                  (250 to 350)
+ *
+ * REUSE NOTES
+ *
+ *    SINUSOIDAL is intended for reuse by any application that performs a
+ *    Sinusoid projection or its inverse.
+ *    
+ * REFERENCES
+ *
+ *    Further information on SINUSOIDAL can be found in the Reuse Manual.
+ *
+ *    SINUSOIDAL originated from :  U.S. Army Topographic Engineering Center
+ *                                  Geospatial Information Division
+ *                                  7701 Telegraph Road
+ *                                  Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    SINUSOIDAL has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    SINUSOIDAL was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC, version 2.8.1
+ *    2. Windows 95 with MS Visual C++, version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    7-15-99          Original Code
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                               INCLUDES
+ */
+
+#include <math.h>
+#include "ossimSinusoid.h"
+
+/*
+ *    math.h     - Standard C math library
+ *    sinusoid.h - Is for prototype error checking
+ */
+
+
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+
+#define PI         3.14159265358979323e0  /* PI                            */
+#define PI_OVER_2  (PI / 2.0)                 
+#define TWO_PI     (2.0 * PI)                  
+#define SINU_COEFF_TIMES_SIN(coeff, x, latit)      (coeff * sin(x * latit))
+#define FLOAT_EQ(x,v,epsilon)   (((v - epsilon) < x) && (x < (v + epsilon)))
+
+
+/***************************************************************************/
+/*
+ *                               GLOBALS
+ */
+
+/* Ellipsoid Parameters, default to WGS 84 */
+static double Sinu_a = 6378137.0;                      /* Semi-major axis of ellipsoid in meters */
+static double Sinu_f = 1 / 298.257223563;              /* Flattening of ellipsoid */
+static double es2 = 0.0066943799901413800;             /* Eccentricity (0.08181919084262188000) squared         */
+static double es4 = 4.4814723452405e-005;              /* es2 * es2 */
+static double es6 = 3.0000678794350e-007;              /* es4 * es2 */
+static double c0 = .99832429845280;           /* 1 - es2 / 4.0 - 3.0 * es4 / 64.0 - 5.0 * es6 / 256.0 */
+static double c1 = .0025146070605187;     /* 3.0 * es2 / 8.0 + 3.0 * es4 / 32.0 + 45.0 * es6 / 1024.0 */
+static double c2 = 2.6390465943377e-006;             /* 15.0 * es4 / 256.0 + 45.0 * es6 / 1024.0 */
+static double c3 = 3.4180460865959e-009;               /* 35.0 * es6 / 3072.0 */
+static double a0 = .0025188265843907;                  /* 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0 */
+static double a1 = 3.7009490356205e-006;               /* 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0 */
+static double a2 = 7.4478137675038e-009;               /* 151.0 * e3 / 96.0 */
+static double a3 = 1.7035993238596e-011;               /* 1097.0 * e4 / 512.0 */
+
+/* Sinusoid projection Parameters */
+static double Sinu_Origin_Long = 0.0;                  /* Longitude of origin in radians    */
+static double Sinu_False_Northing = 0.0;               /* False northing in meters          */
+static double Sinu_False_Easting = 0.0;                /* False easting in meters           */
+
+/* Maximum variance for easting and northing values for WGS 84.
+ */
+static double Sinu_Max_Easting = 20037509.0;
+static double Sinu_Min_Easting = -20037509.0;
+static double Sinu_Delta_Northing = 10001966.0;
+/*
+ * These state variables are for optimization purposes.  The only function
+ * that should modify them is Set_Sinusoidal_Parameters.
+ */
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+long Set_Sinusoidal_Parameters(double a,
+                               double f,
+                               double Central_Meridian,
+                               double False_Easting,
+                               double False_Northing)
+{ /* BEGIN Set_Sinusoidal_Parameters */
+/*
+ * The function Set_Sinusoidal_Parameters receives the ellipsoid parameters and
+ * Sinusoidal projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise SINU_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double j;
+  double One_MINUS_es2, Sqrt_One_MINUS_es2, e1, e2, e3, e4;
+  double inv_f = 1 / f;
+  long Error_Code = SINU_NO_ERROR;
+
+  if (a <= 0.0)
+  { /* Semi-major axis must be greater than zero */
+    Error_Code |= SINU_A_ERROR;
+  }
+  if ((inv_f < 250) || (inv_f > 350))
+  { /* Inverse flattening must be between 250 and 350 */
+    Error_Code |= SINU_INV_F_ERROR;
+  }
+  if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
+  { /* origin longitude out of range */
+    Error_Code |= SINU_CENT_MER_ERROR;
+  }
+  if (!Error_Code)
+  { /* no errors */
+    Sinu_a = a;
+    Sinu_f = f;
+    es2 = 2 * Sinu_f - Sinu_f * Sinu_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    j = 45.0 * es6 / 1024.0;
+    c0 = 1.0 - es2 / 4.0 - 3.0 * es4 / 64.0 - 5.0 * es6 / 256.0;
+    c1 = 3.0 * es2 / 8.0 + 3.0 * es4 / 32.0 + j;
+    c2 = 15.0 * es4 / 256.0 + j;
+    c3 = 35.0 * es6 / 3072.0;
+    One_MINUS_es2 = 1.0 - es2;
+    Sqrt_One_MINUS_es2 = sqrt(One_MINUS_es2);
+    e1 = (1.0 - Sqrt_One_MINUS_es2) / (1.0 + Sqrt_One_MINUS_es2);
+    e2 = e1 * e1;
+    e3 = e2 * e1;
+    e4 = e3 * e1;
+    a0 = 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0 ;
+    a1 = 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0;
+    a2 = 151.0 * e3 / 96.0;
+    a3 = 1097.0 * e4 / 512.0;
+    if (Central_Meridian > PI)
+      Central_Meridian -= TWO_PI;
+    Sinu_Origin_Long = Central_Meridian;
+    Sinu_False_Northing = False_Northing;
+    Sinu_False_Easting = False_Easting;
+
+    if (Sinu_Origin_Long > 0)
+    {
+      Sinu_Max_Easting = 19926189.0;
+      Sinu_Min_Easting = -20037509.0;
+    }
+    else if (Sinu_Origin_Long < 0)
+    {
+      Sinu_Max_Easting = 20037509.0;
+      Sinu_Min_Easting = -19926189.0;
+    }
+    else
+    {
+      Sinu_Max_Easting = 20037509.0;
+      Sinu_Min_Easting = -20037509.0;
+    }
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+} /* END OF Set_Sinusoidal_Parameters */
+
+void Get_Sinusoidal_Parameters(double *a,
+                               double *f,
+                               double *Central_Meridian,
+                               double *False_Easting,
+                               double *False_Northing)
+{ /* BEGIN Get_Sinusoidal_Parameters */
+/*
+ * The function Get_Sinusoidal_Parameters returns the current ellipsoid
+ * parameters, and Sinusoidal projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Sinu_a;
+  *f = Sinu_f;
+  *Central_Meridian = Sinu_Origin_Long;
+  *False_Easting = Sinu_False_Easting;
+  *False_Northing = Sinu_False_Northing;
+  return;
+} /* END OF Get_Sinusoidal_Parameters */
+
+
+long Convert_Geodetic_To_Sinusoidal (double Latitude,
+                                     double Longitude,
+                                     double *Easting,
+                                     double *Northing)
+{ /* BEGIN Convert_Geodetic_To_Sinusoidal */
+/*
+ * The function Convert_Geodetic_To_Sinusoidal converts geodetic (latitude and
+ * longitude) coordinates to Sinusoidal projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Sinusoidal projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise SINU_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double slat = sin(Latitude);
+  double sin2lat, sin4lat, sin6lat;
+  double dlam;                      /* Longitude - Central Meridan */
+  double mm;
+  double MM;
+  long Error_Code = SINU_NO_ERROR;
+
+  if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+  { /* Latitude out of range */
+    Error_Code |= SINU_LAT_ERROR;
+  }
+  if ((Longitude < -PI) || (Longitude > TWO_PI))
+  { /* Longitude out of range */
+    Error_Code |= SINU_LON_ERROR;
+  }
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Sinu_Origin_Long;
+    if (dlam > PI)
+    {
+      dlam -= TWO_PI;
+    }
+    if (dlam < -PI)
+    {
+      dlam += TWO_PI;
+    }
+    mm = sqrt(1.0 - es2 * slat * slat);
+
+    sin2lat = SINU_COEFF_TIMES_SIN(c1, 2.0, Latitude);
+    sin4lat = SINU_COEFF_TIMES_SIN(c2, 4.0, Latitude);
+    sin6lat = SINU_COEFF_TIMES_SIN(c3, 6.0, Latitude);
+    MM = Sinu_a * (c0 * Latitude - sin2lat + sin4lat - sin6lat);
+
+    *Easting = Sinu_a * dlam * cos(Latitude) / mm + Sinu_False_Easting;
+    *Northing = MM + Sinu_False_Northing;
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Sinusoidal */
+
+
+long Convert_Sinusoidal_To_Geodetic(double Easting,
+                                    double Northing,
+                                    double *Latitude,
+                                    double *Longitude)
+{ /* BEGIN Convert_Sinusoidal_To_Geodetic */
+/*
+ * The function Convert_Sinusoidal_To_Geodetic converts Sinusoidal projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Sinusoidal projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise SINU_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx;     /* Delta easting - Difference in easting (easting-FE)      */
+  double dy;     /* Delta northing - Difference in northing (northing-FN)   */
+  double mu;
+  double sin2mu, sin4mu, sin6mu, sin8mu;
+  double sin_lat;
+  long Error_Code = SINU_NO_ERROR;
+
+  if ((Easting < (Sinu_False_Easting + Sinu_Min_Easting))
+      || (Easting > (Sinu_False_Easting + Sinu_Max_Easting)))
+  { /* Easting out of range */
+    Error_Code |= SINU_EASTING_ERROR;
+  }
+  if ((Northing < (Sinu_False_Northing - Sinu_Delta_Northing))
+      || (Northing > (Sinu_False_Northing + Sinu_Delta_Northing)))
+  { /* Northing out of range */
+    Error_Code |= SINU_NORTHING_ERROR;
+  }
+  if (!Error_Code)
+  { /* no errors */
+    dy = Northing - Sinu_False_Northing;
+    dx = Easting - Sinu_False_Easting;
+
+    mu = dy / (Sinu_a * c0);
+    sin2mu = SINU_COEFF_TIMES_SIN(a0, 2.0, mu);
+    sin4mu = SINU_COEFF_TIMES_SIN(a1, 4.0, mu);
+    sin6mu = SINU_COEFF_TIMES_SIN(a2, 6.0, mu);
+    sin8mu = SINU_COEFF_TIMES_SIN(a3, 8.0, mu);
+    *Latitude = mu + sin2mu + sin4mu + sin6mu + sin8mu;
+
+    if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+      *Latitude = PI_OVER_2;
+    else if (*Latitude < -PI_OVER_2)
+      *Latitude = -PI_OVER_2;
+
+    if (FLOAT_EQ(fabs(*Latitude),PI_OVER_2,1.0e-8))
+      *Longitude = Sinu_Origin_Long;
+    else
+    {
+      sin_lat = sin(*Latitude);
+      *Longitude = Sinu_Origin_Long + dx * sqrt(1.0 - es2 *
+                                                sin_lat * sin_lat) / (Sinu_a * cos(*Latitude));
+
+
+      if (*Longitude > PI)
+        *Longitude -= TWO_PI;
+      if (*Longitude < -PI)
+        *Longitude += TWO_PI;
+
+      if (*Longitude > PI)  /* force distorted values to 180, -180 degrees */
+        *Longitude = PI;
+      else if (*Longitude < -PI)
+        *Longitude = -PI;
+
+
+    }
+  }
+  return (Error_Code);
+} /* END OF Convert_Sinusoidal_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoid.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoid.h
new file mode 100644
index 0000000000..76d5e83c3e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoid.h
@@ -0,0 +1,185 @@
+#ifndef SINUSOID_H
+  #define SINUSOID_H
+
+/***************************************************************************/
+/* RSC IDENTIFIER: SINUSOIDAL
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between Geodetic coordinates 
+ *    (latitude and longitude in radians) and Sinusoid projection coordinates
+ *    (easting and northing in meters).
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *          SINU_NO_ERROR           : No errors occurred in function
+ *          SINU_LAT_ERROR          : Latitude outside of valid range
+ *                                      (-90 to 90 degrees)
+ *          SINU_LON_ERROR          : Longitude outside of valid range
+ *                                      (-180 to 360 degrees)
+ *          SINU_EASTING_ERROR      : Easting outside of valid range
+ *                                      (False_Easting +/- ~20,000,000 m,
+ *                                       depending on ellipsoid parameters)
+ *          SINU_NORTHING_ERROR     : Northing outside of valid range
+ *                                      (False_Northing +/- ~10,000,000 m,
+ *                                       depending on ellipsoid parameters)
+ *          SINU_CENT_MER_ERROR     : Origin longitude outside of valid range
+ *                                      (-180 to 360 degrees)
+ *          SINU_A_ERROR            : Semi-major axis less than or equal to zero
+ *          SINU_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	                  (250 to 350)
+ *
+ * REUSE NOTES
+ *
+ *    SINUSOIDAL is intended for reuse by any application that performs a
+ *    Sinusoid projection or its inverse.
+ *    
+ * REFERENCES
+ *
+ *    Further information on SINUSOIDAL can be found in the Reuse Manual.
+ *
+ *    SINUSOIDAL originated from :  U.S. Army Topographic Engineering Center
+ *                                  Geospatial Information Division
+ *                                  7701 Telegraph Road
+ *                                  Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    SINUSOIDAL has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    SINUSOIDAL was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC, version 2.8.1
+ *    2. Windows 95 with MS Visual C++, version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    7-15-99          Original Code
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+  #define SINU_NO_ERROR           0x0000
+  #define SINU_LAT_ERROR          0x0001
+  #define SINU_LON_ERROR          0x0002
+  #define SINU_EASTING_ERROR      0x0004
+  #define SINU_NORTHING_ERROR     0x0008
+  #define SINU_CENT_MER_ERROR     0x0020
+  #define SINU_A_ERROR            0x0040
+  #define SINU_INV_F_ERROR        0x0080
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTION PROTOTYPES
+ *                                for SINUSOID.C
+ */
+
+/* ensure proper linkage to c++ programs */
+  #ifdef __cplusplus
+extern "C" {
+  #endif
+
+  long Set_Sinusoidal_Parameters(double a,
+                                 double f,
+                                 double Central_Meridian,
+                                 double False_Easting,
+                                 double False_Northing);
+
+/*
+ * The function Set_Sinusoidal_Parameters receives the ellipsoid parameters and
+ * Sinusoidal projcetion parameters as inputs, and sets the corresponding state
+ * variables. If any errors occur, the error code(s) are returned by the function, 
+ * otherwise SINU_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+
+  void Get_Sinusoidal_Parameters(double *a,
+                                 double *f,
+                                 double *Central_Meridian,
+                                 double *False_Easting,
+                                 double *False_Northing);
+
+/*
+ * The function Get_Sinusoidal_Parameters returns the current ellipsoid
+ * parameters and Sinusoidal projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid                   (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+
+  long Convert_Geodetic_To_Sinusoidal (double Latitude,
+                                       double Longitude,
+                                       double *Easting,
+                                       double *Northing); 
+/*
+ * The function Convert_Geodetic_To_Sinusoidal converts geodetic (latitude and
+ * longitude) coordinates to Sinusoidal projection easting, and northing
+ * coordinates, according to the current ellipsoid and Sinusoidal projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise SINU_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+
+  long Convert_Sinusoidal_To_Geodetic(double Easting,
+                                      double Northing,
+                                      double *Latitude,
+                                      double *Longitude);
+/*
+ * The function Convert_Sinusoidal_To_Geodetic converts Sinusoidal projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Sinusoida projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise SINU_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  #ifdef __cplusplus
+}
+  #endif
+
+#endif /* SINUSOID_H */
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoidalProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoidalProjection.cpp
new file mode 100644
index 0000000000..bd51ee74fd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoidalProjection.cpp
@@ -0,0 +1,455 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Sinusoidal projection code.  
+//*******************************************************************
+//  $Id: ossimSinusoidalProjection.cpp,v 1.11 2004/01/08 21:49:22 jlargent Exp $
+
+#include <math.h>
+#include "ossimSinusoidalProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimSinusoidalProjection, "ossimSinusoidalProjection", ossimMapProjection)
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+#define SINU_NO_ERROR           0x0000
+#define SINU_LAT_ERROR          0x0001
+#define SINU_LON_ERROR          0x0002
+#define SINU_EASTING_ERROR      0x0004
+#define SINU_NORTHING_ERROR     0x0008
+#define SINU_CENT_MER_ERROR     0x0020
+#define SINU_A_ERROR            0x0040
+#define SINU_B_ERROR            0x0080
+#define SINU_A_LESS_B_ERROR     0x0100
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+
+#define SINU_COEFF_TIMES_SIN(coeff, x, latit)      (coeff * sin(x * latit))
+#define FLOAT_EQ(x,v,epsilon)   (((v - epsilon) < x) && (x < (v + epsilon)))
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+ossimSinusoidalProjection::ossimSinusoidalProjection(const ossimEllipsoid& ellipsoid,
+                                                     const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimSinusoidalProjection::ossimSinusoidalProjection(const ossimEllipsoid& ellipsoid,
+                                                     const ossimGpt& origin,
+                                                     double falseEasting,
+                                                     double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Sinu_False_Easting  = falseEasting;
+   Sinu_False_Northing = falseNorthing;
+   Sinu_Max_Easting    = 20037509.0;
+   Sinu_Min_Easting    = -20037509.0;
+   Sinu_Delta_Northing = 10001966.0;
+
+   update();
+}
+
+void ossimSinusoidalProjection::update()
+{   
+   Set_Sinusoidal_Parameters(theEllipsoid.getA(),
+                             theEllipsoid.getFlattening(),
+                             theOrigin.lonr(),
+                             Sinu_False_Easting,
+                             Sinu_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimSinusoidalProjection::setFalseEasting(double falseEasting)
+{
+   Sinu_False_Easting = falseEasting;
+   
+   update();
+}
+
+void ossimSinusoidalProjection::setFalseNorthing(double falseNorthing)
+{
+   Sinu_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimSinusoidalProjection::setDefaults()
+{
+   Sinu_Max_Easting    = 20037509.0;
+   Sinu_Min_Easting    = -20037509.0;
+   Sinu_Delta_Northing = 10001966.0;
+   Sinu_False_Easting  = 0.0;
+   Sinu_False_Northing = 0.0;
+}
+
+void ossimSinusoidalProjection::setFalseEastingNorthing(double falseEasting,
+                                                        double falseNorthing)
+{
+   Sinu_False_Easting  = falseEasting;
+   Sinu_False_Northing = falseNorthing;
+   
+   update();
+}
+
+ossimGpt ossimSinusoidalProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Sinusoidal_To_Geodetic(eastingNorthing.x,
+                                  eastingNorthing.y,
+                                  &lat,
+                                  &lon);   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimSinusoidalProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Sinusoidal(gpt.latr(),
+                                  gpt.lonr(),
+                                  &easting,
+                                  &northing);   
+   return ossimDpt(easting, northing);
+}
+
+bool ossimSinusoidalProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Sinu_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Sinu_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimSinusoidalProjection::loadState(const ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimSinusoidalProjection))
+   {
+      if(falseEasting)
+      {
+         Sinu_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Sinu_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+
+   return flag;
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS     
+ */
+
+
+long ossimSinusoidalProjection::Set_Sinusoidal_Parameters(double a,
+                                                          double f,
+                                                          double Central_Meridian,
+                                                          double False_Easting,
+                                                          double False_Northing)
+{ /* BEGIN Set_Sinusoidal_Parameters */
+/*
+ * The function Set_Sinusoidal_Parameters receives the ellipsoid parameters and
+ * Sinusoidal projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise SINU_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+  double j;
+  double One_MINUS_es2, Sqrt_One_MINUS_es2, e1, e2, e3, e4;
+//  double inv_f = 1 / f;
+  long Error_Code = SINU_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= SINU_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= SINU_INV_F_ERROR;
+//   }
+//   if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= SINU_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Sinu_a = a;
+    Sinu_f = f;
+    es2 = 2 * Sinu_f - Sinu_f * Sinu_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    j = 45.0 * es6 / 1024.0;
+    c0 = 1.0 - es2 / 4.0 - 3.0 * es4 / 64.0 - 5.0 * es6 / 256.0;
+    c1 = 3.0 * es2 / 8.0 + 3.0 * es4 / 32.0 + j;
+    c2 = 15.0 * es4 / 256.0 + j;
+    c3 = 35.0 * es6 / 3072.0;
+    One_MINUS_es2 = 1.0 - es2;
+    Sqrt_One_MINUS_es2 = sqrt(One_MINUS_es2);
+    e1 = (1.0 - Sqrt_One_MINUS_es2) / (1.0 + Sqrt_One_MINUS_es2);
+    e2 = e1 * e1;
+    e3 = e2 * e1;
+    e4 = e3 * e1;
+    a0 = 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0 ;
+    a1 = 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0;
+    a2 = 151.0 * e3 / 96.0;
+    a3 = 1097.0 * e4 / 512.0;
+//     if (Central_Meridian > M_PI)
+//       Central_Meridian -= TWO_PI;
+    Sinu_Origin_Long = Central_Meridian;
+    Sinu_False_Northing = False_Northing;
+    Sinu_False_Easting = False_Easting;
+
+    if (Sinu_Origin_Long > 0)
+    {
+      Sinu_Max_Easting = 19926189.0;
+      Sinu_Min_Easting = -20037509.0;
+    }
+    else if (Sinu_Origin_Long < 0)
+    {
+      Sinu_Max_Easting = 20037509.0;
+      Sinu_Min_Easting = -19926189.0;
+    }
+    else
+    {
+      Sinu_Max_Easting = 20037509.0;
+      Sinu_Min_Easting = -20037509.0;
+    }
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+} /* END OF Set_Sinusoidal_Parameters */
+
+void ossimSinusoidalProjection::Get_Sinusoidal_Parameters(double *a,
+                                                          double *f,
+                                                          double *Central_Meridian,
+                                                          double *False_Easting,
+                                                          double *False_Northing)const
+{ /* BEGIN Get_Sinusoidal_Parameters */
+/*
+ * The function Get_Sinusoidal_Parameters returns the current ellipsoid
+ * parameters, and Sinusoidal projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Sinu_a;
+  *f = Sinu_f;
+  *Central_Meridian = Sinu_Origin_Long;
+  *False_Easting = Sinu_False_Easting;
+  *False_Northing = Sinu_False_Northing;
+  
+  return;
+} /* END OF Get_Sinusoidal_Parameters */
+
+
+long ossimSinusoidalProjection::Convert_Geodetic_To_Sinusoidal (double Latitude,
+                                                                double Longitude,
+                                                                double *Easting,
+                                                                double *Northing)const
+{ /* BEGIN Convert_Geodetic_To_Sinusoidal */
+/*
+ * The function Convert_Geodetic_To_Sinusoidal converts geodetic (latitude and
+ * longitude) coordinates to Sinusoidal projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Sinusoidal projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise SINU_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double slat = sin(Latitude);
+  double sin2lat, sin4lat, sin6lat;
+  double dlam;                      /* Longitude - Central Meridan */
+  double mm;
+  double MM;
+  long Error_Code = SINU_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   { /* Latitude out of range */
+//     Error_Code |= SINU_LAT_ERROR;
+//   }
+//   if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+//   { /* Longitude out of range */
+//     Error_Code |= SINU_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Sinu_Origin_Long;
+//     if (dlam > M_PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -M_PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+    mm = sqrt(1.0 - es2 * slat * slat);
+
+    sin2lat = SINU_COEFF_TIMES_SIN(c1, 2.0, Latitude);
+    sin4lat = SINU_COEFF_TIMES_SIN(c2, 4.0, Latitude);
+    sin6lat = SINU_COEFF_TIMES_SIN(c3, 6.0, Latitude);
+    MM = Sinu_a * (c0 * Latitude - sin2lat + sin4lat - sin6lat);
+
+    *Easting = Sinu_a * dlam * cos(Latitude) / mm + Sinu_False_Easting;
+    *Northing = MM + Sinu_False_Northing;
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Sinusoidal */
+
+
+long ossimSinusoidalProjection::Convert_Sinusoidal_To_Geodetic(double Easting,
+                                                               double Northing,
+                                                               double *Latitude,
+                                                               double *Longitude)const
+{ /* BEGIN Convert_Sinusoidal_To_Geodetic */
+/*
+ * The function Convert_Sinusoidal_To_Geodetic converts Sinusoidal projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Sinusoidal projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise SINU_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx;     /* Delta easting - Difference in easting (easting-FE)      */
+  double dy;     /* Delta northing - Difference in northing (northing-FN)   */
+  double mu;
+  double sin2mu, sin4mu, sin6mu, sin8mu;
+  double sin_lat;
+  long Error_Code = SINU_NO_ERROR;
+
+//   if ((Easting < (Sinu_False_Easting + Sinu_Min_Easting))
+//       || (Easting > (Sinu_False_Easting + Sinu_Max_Easting)))
+//   { /* Easting out of range */
+//     Error_Code |= SINU_EASTING_ERROR;
+//   }
+//   if ((Northing < (Sinu_False_Northing - Sinu_Delta_Northing))
+//       || (Northing > (Sinu_False_Northing + Sinu_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= SINU_NORTHING_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dy = Northing - Sinu_False_Northing;
+    dx = Easting - Sinu_False_Easting;
+
+    mu = dy / (Sinu_a * c0);
+    sin2mu = SINU_COEFF_TIMES_SIN(a0, 2.0, mu);
+    sin4mu = SINU_COEFF_TIMES_SIN(a1, 4.0, mu);
+    sin6mu = SINU_COEFF_TIMES_SIN(a2, 6.0, mu);
+    sin8mu = SINU_COEFF_TIMES_SIN(a3, 8.0, mu);
+    *Latitude = mu + sin2mu + sin4mu + sin6mu + sin8mu;
+
+    if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+      *Latitude = PI_OVER_2;
+    else if (*Latitude < -PI_OVER_2)
+      *Latitude = -PI_OVER_2;
+
+    if (FLOAT_EQ(fabs(*Latitude),PI_OVER_2,1.0e-8))
+      *Longitude = Sinu_Origin_Long;
+    else
+    {
+      sin_lat = sin(*Latitude);
+      *Longitude = Sinu_Origin_Long + dx * sqrt(1.0 - es2 *
+                                                sin_lat * sin_lat) / (Sinu_a * cos(*Latitude));
+
+
+//       if (*Longitude > M_PI)
+//         *Longitude -= TWO_PI;
+//       if (*Longitude < -M_PI)
+//         *Longitude += TWO_PI;
+
+//       if (*Longitude > M_PI)  /* force distorted values to 180, -180 degrees */
+//         *Longitude = M_PI;
+//       else if (*Longitude < -M_PI)
+//         *Longitude = -M_PI;
+    }
+  }
+  return (Error_Code);
+} /* END OF Convert_Sinusoidal_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoidalProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoidalProjection.h
new file mode 100644
index 0000000000..6ab2f4462d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSinusoidalProjection.h
@@ -0,0 +1,201 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Sinusoidal projection code.  
+//*******************************************************************
+//  $Id: ossimSinusoidalProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimSinusoidalProjection_HEADER
+#define ossimSinusoidalProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimSinusoidalProjection : public ossimMapProjection
+{
+public:
+   ossimSinusoidalProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                             const ossimGpt& origin = ossimGpt());
+   
+   ossimSinusoidalProjection(const ossimEllipsoid& ellipsoid,
+                             const ossimGpt& origin,
+                             const double falseEasting,
+                             const double falseNorthing);
+   
+   ~ossimSinusoidalProjection(){}
+
+   virtual ossimObject *dup()const{return new ossimSinusoidalProjection(*this);}
+
+   
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return  Sinu_False_Easting;}
+   double getFalseNorthing()const{return Sinu_False_Northing;}
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+
+   //_______________________GEOTRANS________________________
+   mutable double Sinu_a;                      /* Semi-major axis of ellipsoid in meters */
+   mutable double Sinu_f;              /* Flattening of ellipsoid */
+   mutable double es2;             /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;              /* es2 * es2 */
+   mutable double es6;              /* es4 * es2 */
+   mutable double c0;           /* 1 - es2 / 4.0 - 3.0 * es4 / 64.0 - 5.0 * es6 / 256.0 */
+   mutable double c1;     /* 3.0 * es2 / 8.0 + 3.0 * es4 / 32.0 + 45.0 * es6 / 1024.0 */
+   mutable double c2;             /* 15.0 * es4 / 256.0 + 45.0 * es6 / 1024.0 */
+   mutable double c3;               /* 35.0 * es6 / 3072.0 */
+   mutable double a0;                  /* 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0 */
+   mutable double a1;               /* 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0 */
+   mutable double a2;               /* 151.0 * e3 / 96.0 */
+   mutable double a3;               /* 1097.0 * e4 / 512.0 */
+   
+/* Sinusoid projection Parameters */
+   mutable double Sinu_Origin_Long;      /* Longitude of origin in radians    */
+   mutable double Sinu_False_Northing;   /* False northing in meters          */
+   mutable double Sinu_False_Easting;    /* False easting in meters           */
+   
+/* Maximum variance for easting and northing values for WGS 84.
+ */
+   mutable double Sinu_Max_Easting;
+   mutable double Sinu_Min_Easting;
+   mutable double Sinu_Delta_Northing;   
+
+
+/*!
+ * The function Set_Sinusoidal_Parameters receives the ellipsoid parameters and
+ * Sinusoidal projcetion parameters as inputs, and sets the corresponding state
+ * variables. If any errors occur, the error code(s) are returned by the function, 
+ * otherwise SINU_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Sinusoidal_Parameters(double a,
+                                 double f,
+                                 double Central_Meridian,
+                                 double False_Easting,
+                                 double False_Northing);
+
+
+
+/*!
+ * The function Get_Sinusoidal_Parameters returns the current ellipsoid
+ * parameters and Sinusoidal projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid                   (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+  void Get_Sinusoidal_Parameters(double *a,
+                                 double *f,
+                                 double *Central_Meridian,
+                                 double *False_Easting,
+                                 double *False_Northing)const;
+
+
+
+/*!
+ * The function Convert_Geodetic_To_Sinusoidal converts geodetic (latitude and
+ * longitude) coordinates to Sinusoidal projection easting, and northing
+ * coordinates, according to the current ellipsoid and Sinusoidal projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise SINU_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Sinusoidal (double Latitude,
+                                       double Longitude,
+                                       double *Easting,
+                                       double *Northing)const; 
+
+
+/*!
+ * The function Convert_Sinusoidal_To_Geodetic converts Sinusoidal projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Sinusoida projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise SINU_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Sinusoidal_To_Geodetic(double Easting,
+                                      double Northing,
+                                      double *Latitude,
+                                      double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSpaceObliqueMercatorProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSpaceObliqueMercatorProjection.cpp
new file mode 100644
index 0000000000..c69615ddaa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSpaceObliqueMercatorProjection.cpp
@@ -0,0 +1,408 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimSpaceObliqueMercatorProjection.cpp,v 1.14 2004/01/08 21:59:33 jlargent Exp $
+#include "ossimSpaceObliqueMercatorProjection.h"
+#include <math.h>
+#include "base/common/ossimConstants.h"
+
+#define PI_OVER_2 (M_PI/2)
+#define PI (M_PI)
+#define TWOPI (2*M_PI)
+#define HALFPI (M_PI/2.0)
+#define TOL 1e-7
+#define PI_HALFPI 4.71238898038468985766
+#define TWOPI_HALFPI 7.85398163397448309610
+#define ONE_TOL	 1.00000000000001
+#define ATOL 1e-50
+#define FORTPI		0.78539816339744833
+
+double aasin(double v)
+{
+   double av;
+
+   if ((av = fabs(v)) >= 1.)
+   {
+      return (v < 0. ? -HALFPI : HALFPI);
+   }
+   return asin(v);
+}
+double aacos(double v)
+{
+	double av;
+
+	if ((av = fabs(v)) >= 1.)
+        {
+           return (v < 0. ? PI : 0.);
+	}
+	return acos(v);
+}
+double asqrt(double v)
+{
+   return ((v <= 0) ? 0. : sqrt(v));
+}
+double aatan2(double n, double d)
+{
+   return ((fabs(n) < ATOL && fabs(d) < ATOL) ? 0. : atan2(n,d));
+}
+
+static const char* PATH_KW                     = "path";
+static const char* SATELLITE_TYPE_KW           = "satellite_type";
+
+#if 0
+static const char* ANGLE_OF_INCLINATION_KW     = "angle_of_inclination";
+static const char* REVOLUTION_TIME_KW          = "earth_rev_time";
+static const char* EARTH_ROTATION_LENGTH_KW    = "earth_rot_length";
+static const char* LONGITUDE_ASCENDING_NODE_KW = "lon_ascending_node";
+static const char* J_COEFFICIENT_KW  = "j_coeff";
+static const char* W_COEFFICIENT_KW  = "w_coeff";
+static const char* Q_COEFFICIENT_KW  = "q_coeff";
+static const char* T_COEFFICIENT_KW  = "t_coeff";
+static const char* A2_COEFFICIENT_KW = "a2_coeff";
+static const char* A4_COEFFICIENT_KW = "a4_coeff";
+static const char* B_COEFFICIENT_KW  = "b_coeff";
+static const char* C1_COEFFICIENT_KW = "c1_coeff";
+static const char* C3_COEFFICIENT_KW = "c3_coeff";
+static const char* ECCENTRICITY_KW   = "eccentricity";
+#endif
+
+RTTI_DEF1(ossimSpaceObliqueMercatorProjection, "ossimSpaceObliqueMercatorProjection", ossimMapProjection);
+
+
+//*****************************************************************************
+//  CONSTRUCTOR
+//*****************************************************************************
+ossimSpaceObliqueMercatorProjection::ossimSpaceObliqueMercatorProjection
+   (ossimSatelliteType type,
+    double pathNumber,
+    const ossimEllipsoid& ellipsoid)
+      :
+      ossimMapProjection(ellipsoid)
+{
+   setParameters(type, pathNumber);
+}
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+void ossimSpaceObliqueMercatorProjection::setParameters(ossimSatelliteType type,
+                                                        double path)
+{
+   thePath = path;
+   theSatelliteType = type;
+   double lam = 0.0;
+   double alf = 0.0;
+   double esc = 0.0;
+   double ess = 0.0;
+   
+   e  = theEllipsoid.eccentricity();
+   es = e*e;
+   one_es = 1- es;
+   rone_es = 1.0/one_es;
+   a   = theEllipsoid.a();
+   
+   switch(theSatelliteType)
+   {
+   case SOM_TYPE_LANDSAT_1:
+   case SOM_TYPE_LANDSAT_2:
+   case SOM_TYPE_LANDSAT_3:
+   {
+      lam0 = RAD_PER_DEG*(128.87 - (360.0/251.0)*path);
+      p22 = 103.2669323;
+      alf = RAD_PER_DEG * 99.092;
+      break;
+   }
+   case SOM_TYPE_LANDSAT_4:
+   case SOM_TYPE_LANDSAT_5:
+   case SOM_TYPE_LANDSAT_7:
+   {
+      
+      lam0 = RAD_PER_DEG*(129.305582487 - (360.0/233.0)*path);
+      p22 = 98.8841202;
+      alf = RAD_PER_DEG * 98.2;
+      break;
+   }
+   }
+   p22 /= 1440.;
+   sa = sin(alf);
+   ca = cos(alf);
+   if (fabs(ca) < 1e-9)
+      ca = 1e-9;
+   esc = es * ca * ca;
+   ess = es * sa * sa;
+   w = (1. - esc) * rone_es;
+   w = w * w - 1.;
+   q = ess * rone_es;
+   t = ess * (2. - es) * rone_es * rone_es;
+   u = esc * rone_es;
+   xj = one_es * one_es * one_es;
+   rlm = PI * (1. / 248. + .5161290322580645);
+   rlm2 = rlm + TWOPI;
+   a2 = a4 = b = c1 = c3 = 0.;
+   seraz0(0.0, 1.0);
+   for (lam = 9.; lam <= 81.0001; lam += 18.)
+      seraz0(lam, 4.0);
+   for (lam = 18; lam <= 72.0001; lam += 18.)
+      seraz0(lam, 2.0);
+   seraz0(90.0, 1.0);
+   a2 /= 30.0;
+   a4 /= 60.0;
+   b /= 30.0;
+   c1 /= 15.0;
+   c3 /= 45.0;
+
+   update();
+}
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+void ossimSpaceObliqueMercatorProjection::seraz0(double lam,
+                                                 double mult)
+{
+    double sdsq, h, s, fc, sd, sq, d__1;
+
+    lam *= RAD_PER_DEG;
+    sd = sin(lam);
+    sdsq = sd * sd;
+    s = p22 * sa * cos(lam) * sqrt((1. + t * sdsq) / ((
+	    1. + w * sdsq) * (1. + q * sdsq)));
+    d__1 = 1. + q * sdsq;
+    h = sqrt((1. + q * sdsq) / (1. + w * sdsq)) * ((1. + 
+	    w * sdsq) / (d__1 * d__1) - p22 * ca);
+    sq = sqrt(xj * xj + s * s);
+    b += fc = mult * (h * xj - s * s) / sq;
+    a2 += fc * cos(lam + lam);
+    a4 += fc * cos(lam * 4.);
+    fc = mult * s * (h + xj) / sq;
+    c1 += fc * cos(lam);
+    c3 += fc * cos(lam * 3.);
+   
+}
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+ossimDpt
+ossimSpaceObliqueMercatorProjection::forward(const ossimGpt &worldPoint) const
+{
+   ossimGpt gpt = worldPoint;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != worldPoint.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   ossimDpt xy;
+   
+   int l, nn;
+   double lamt, xlam, sdsq, c, d, s, lamdp, phidp, lampp, tanph,
+      lamtp, cl, sd, sp, fac, sav, tanphi;
+   double phi = gpt.latr();
+   double lam = gpt.lonr() - lam0;
+   
+   if (phi > HALFPI)
+      phi = HALFPI;
+   else if (phi < -HALFPI)
+      phi = -HALFPI;
+   lampp = phi >= 0. ? HALFPI : PI_HALFPI;
+   tanphi = tan(phi);
+   for (nn = 0;;)
+   {
+      sav = lampp;
+      lamtp = lam + p22 * lampp;
+      cl = cos(lamtp);
+      if (fabs(cl) < TOL)
+         lamtp -= TOL;
+      fac = lampp - sin(lampp) * (cl < 0. ? -HALFPI : HALFPI);
+      for (l = 50; l; --l) {
+         lamt = lam + p22 * sav;
+         if (fabs(c = cos(lamt)) < TOL)
+            lamt -= TOL;
+         xlam = (one_es * tanphi * sa + sin(lamt) * ca) / c;
+         lamdp = atan(xlam) + fac;
+         if (fabs(fabs(sav) - fabs(lamdp)) < TOL)
+            break;
+         sav = lamdp;
+      }
+      if (!l || ++nn >= 3 || (lamdp > rlm && lamdp < rlm2))
+         break;
+      if (lamdp <= rlm)
+         lampp = TWOPI_HALFPI;
+      else if (lamdp >= rlm2)
+         lampp = HALFPI;
+   }
+   if (l) {
+      sp = sin(phi);
+      phidp = aasin((one_es * ca * sp - sa * cos(phi) * 
+                     sin(lamt)) / sqrt(1. - es * sp * sp));
+      tanph = log(tan(FORTPI + .5 * phidp));
+      sd = sin(lamdp);
+      sdsq = sd * sd;
+      s = p22 * sa * cos(lamdp) * sqrt((1. + t * sdsq)
+                                       / ((1. + w * sdsq) * (1. + q * sdsq)));
+      d = sqrt(xj * xj + s * s);
+      xy.x = b * lamdp + a2 * sin(2. * lamdp) + a4 *
+             sin(lamdp * 4.) - tanph * s / d;
+      xy.y = c1 * sd + c3 * sin(lamdp * 3.) + tanph * xj / d;
+   }
+   else
+   {
+      xy.x = xy.y = OSSIM_INFINITY;
+   }
+
+   xy.x*=a;
+   xy.y*=a;
+   return xy;
+}
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+ossimGpt
+ossimSpaceObliqueMercatorProjection::inverse(const ossimDpt &projectedPoint)
+   const
+{
+   int nn;
+   double lamt, sdsq, s, lamdp, phidp, sppsq, dd, sd, sl, fac, scl, sav, spp;
+   double lam, phi;
+   
+   ossimDpt xy = projectedPoint;
+   xy.x/=a;
+   xy.y/=a;
+   
+   lamdp = xy.x / b;
+   nn = 50;
+   do {
+      sav = lamdp;
+      sd = sin(lamdp);
+      sdsq = sd * sd;
+      s = p22 * sa * cos(lamdp) * sqrt((1. + t * sdsq)
+                                       / ((1. + w * sdsq) * (1. + q * sdsq)));
+      lamdp = xy.x + xy.y * s / xj - a2 * sin(
+         2. * lamdp) - a4 * sin(lamdp * 4.) - s / xj * (
+            c1 * sin(lamdp) + c3 * sin(lamdp * 3.));
+      lamdp /= b;
+   } while (fabs(lamdp - sav) >= TOL && --nn);
+   sl = sin(lamdp);
+   fac = exp(sqrt(1. + s * s / xj / xj) * (xy.y - 
+                                           c1 * sl - c3 * sin(lamdp * 3.)));
+   phidp = 2. * (atan(fac) - FORTPI);
+   dd = sl * sl;
+   if (fabs(cos(lamdp)) < TOL)
+      lamdp -= TOL;
+   spp = sin(phidp);
+   sppsq = spp * spp;
+   lamt = atan(((1. - sppsq * rone_es) * tan(lamdp) * ca -
+                spp * sa * sqrt((1. + q * dd) * (1. - sppsq) - sppsq * u) /
+                cos(lamdp)) / (1. - sppsq * (1. + u)));
+   sl = lamt >= 0. ? 1. : -1.;
+   scl = cos(lamdp) >= 0. ? 1. : -1;
+   lamt -= HALFPI * (1. - scl) * sl;
+   
+   lam = lamt - p22 * lamdp;
+   if (fabs(sa) < TOL)
+      phi = aasin(spp / sqrt(one_es * one_es + es * sppsq));
+   else
+      phi = atan((tan(lamdp) * cos(lamt) - ca * sin(lamt)) /
+                    (one_es * sa));
+   return ossimGpt(phi*DEG_PER_RAD,
+                   (lam+lam0)*DEG_PER_RAD, 0.0, theDatum);
+   
+}                        
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+void ossimSpaceObliqueMercatorProjection::update()
+{
+//   theMetersPerPixel.x    = 1.0;
+//   theMetersPerPixel.y    = 1.0;
+   
+//   theUlEastingNorthing.x = 0.0;
+//   theUlEastingNorthing.y = 0.0;
+}
+
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+bool ossimSpaceObliqueMercatorProjection::saveState(ossimKeywordlist& kwl,
+                                                    const char* prefix) const
+{
+   kwl.add(prefix,
+           PATH_KW,
+           thePath,
+           true);
+   
+   kwl.add(prefix,
+           SATELLITE_TYPE_KW,
+           (int)theSatelliteType,
+           true);
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+bool ossimSpaceObliqueMercatorProjection::loadState(const ossimKeywordlist& kwl,
+                                                    const char* prefix)
+{
+   bool result = true;
+
+   const char* path = kwl.find(prefix, PATH_KW);
+   const char* type = kwl.find(prefix,  SATELLITE_TYPE_KW);
+
+   if(path)
+   {
+      thePath = ossimString(path).toDouble();
+   }
+   else
+   {
+      result = false;
+   }
+   if(type)
+   {
+      theSatelliteType = (ossimSatelliteType)ossimString(type).toInt();
+   }
+   else
+   {
+      result = false;
+   }
+
+   setParameters(theSatelliteType, thePath);
+
+   if(result)
+   {
+      result = ossimMapProjection::loadState(kwl, prefix);
+   }
+   else
+   {
+      ossimMapProjection::loadState(kwl, prefix);
+   }
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSpaceObliqueMercatorProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSpaceObliqueMercatorProjection.h
new file mode 100644
index 0000000000..e1d50a84b5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimSpaceObliqueMercatorProjection.h
@@ -0,0 +1,105 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimSpaceObliqueMercatorProjection.h,v 1.6 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimSpaceObliqueMercatorProjection_HEADER
+#define ossimSpaceObliqueMercatorProjection_HEADER
+#include "ossimMapProjection.h"
+
+/*!
+ * This class implments the formulas for the ellipsoid and
+ * circular orbit.  All formulas were directly taken from
+ * proj 4.  Proj 4 implementation is from the following
+ * manual reference:
+ *
+ * Map Projections - A Working Manual
+ * by John Snyder
+ * Space Oblique Mercator p. 221.
+ *
+ * 
+ */
+class ossimSpaceObliqueMercatorProjection : public ossimMapProjection
+{
+public:
+   enum ossimSatelliteType
+   {
+      SOM_TYPE_LANDSAT_1 = 0,
+      SOM_TYPE_LANDSAT_2 = 1,
+      SOM_TYPE_LANDSAT_3 = 2,
+      SOM_TYPE_LANDSAT_4 = 3, 
+      SOM_TYPE_LANDSAT_5 = 4,
+      SOM_TYPE_LANDSAT_7 = 5
+   };
+   
+   ossimSpaceObliqueMercatorProjection(ossimSatelliteType type=SOM_TYPE_LANDSAT_7,
+                                       double pathNumber=34,
+                                       const ossimEllipsoid& ellipsoid = ossimEllipsoid());
+
+   virtual ossimObject* dup()const{return new ossimSpaceObliqueMercatorProjection(*this);}
+   virtual ossimDpt forward(const ossimGpt &worldPoint)    const;
+   virtual ossimGpt inverse(const ossimDpt &projectedPoint)const;
+
+     /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+  virtual void setParameters(ossimSatelliteType type,
+                              double path);
+   
+   virtual void update();
+protected:
+
+   // proj 4 parameters that I bridge to.
+   //
+   double a2, a4, b, c1, c3; 
+   double q, t, u, w, p22, sa, ca, xj, rlm, rlm2;
+
+   // proj4 stuff 
+   double lam0;
+   double es;
+   double e;
+   double one_es;
+   double rone_es;
+   double a;
+   
+   void seraz0(double lam, double mult);
+   
+   /*!
+    * Is the p variable in Map Projections a Working Manual.
+    */
+   double thePath;
+   ossimSatelliteType theSatelliteType;
+   
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimStereographicProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimStereographicProjection.cpp
new file mode 100644
index 0000000000..f5fbcc3b6b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimStereographicProjection.cpp
@@ -0,0 +1,511 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimStereographicProjection.cpp,v 1.4 2004/01/08 21:49:22 jlargent Exp $
+
+#include "ossimStereographicProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimStereographicProjection, "ossimStereographicProjection", ossimMapProjection)
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef PI_OVER_4
+#  define PI_OVER_4  ( M_PI / 4.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+#define ONE	   (1.0 * M_PI / 180.0)       /* 1 degree in radians*/
+
+#define STEREO_NO_ERROR                0x0000
+#define STEREO_LAT_ERROR               0x0001
+#define STEREO_LON_ERROR               0x0002
+#define STEREO_ORIGIN_LAT_ERROR        0x0004
+#define STEREO_CENT_MER_ERROR          0x0008
+#define STEREO_EASTING_ERROR			     0x0010
+#define STEREO_NORTHING_ERROR		       0x0020
+#define STEREO_A_ERROR                 0x0040
+#define STEREO_INV_F_ERROR             0x0080
+
+ossimStereographicProjection::ossimStereographicProjection(const ossimEllipsoid& ellipsoid,
+                                                       const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimStereographicProjection::ossimStereographicProjection(const ossimEllipsoid& ellipsoid,
+                                                   const ossimGpt& origin,
+                                                   double falseEasting,
+                                                   double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Stereo_False_Easting  = falseEasting;
+   Stereo_False_Northing = falseNorthing;
+   Stereo_Delta_Easting  = 1460090226.0;
+   Stereo_Delta_Northing = 1460090226.0;
+   
+   update();
+}
+
+void ossimStereographicProjection::update()
+{   
+   Set_Stereographic_Parameters(theEllipsoid.getA(),
+                            theEllipsoid.getFlattening(),
+                            theOrigin.latr(),
+                            theOrigin.lonr(),
+                            Stereo_False_Easting,
+                            Stereo_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimStereographicProjection::setFalseEasting(double falseEasting)
+{
+   Stereo_False_Easting = falseEasting;
+   
+   update();
+}
+
+void ossimStereographicProjection::setFalseNorthing(double falseNorthing)
+{
+   Stereo_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimStereographicProjection::setDefaults()
+{
+   Stereo_False_Easting  = 0.0;
+   Stereo_False_Northing = 0.0;
+   Stereo_Delta_Easting  = 1460090226.0;
+   Stereo_Delta_Northing = 1460090226.0;
+}
+
+void ossimStereographicProjection::setFalseEastingNorthing(double falseEasting,
+                                                           double falseNorthing)
+{
+   Stereo_False_Easting  = falseEasting;
+   Stereo_False_Northing = falseNorthing;
+   
+   update();
+}
+
+ossimGpt ossimStereographicProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+
+   Convert_Stereographic_To_Geodetic(eastingNorthing.x,
+                                 eastingNorthing.y,
+                                 &lat,
+                                 &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimStereographicProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Stereographic(gpt.latr(),
+                                     gpt.lonr(),
+                                     &easting,
+                                     &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+bool ossimStereographicProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Stereo_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Stereo_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimStereographicProjection::loadState(const ossimKeywordlist& kwl,
+                                         const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimStereographicProjection))
+   {
+      if(falseEasting)
+      {
+         Stereo_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Stereo_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+
+   return flag;
+}
+/************************************************************************/
+/*                              FUNCTIONS
+ *
+ */
+
+long ossimStereographicProjection::Set_Stereographic_Parameters (double a,
+                                                                 double f,
+                                                                 double Origin_Latitude,
+                                                                 double Central_Meridian,
+                                                                 double False_Easting,
+                                                                 double False_Northing)
+
+{  /* BEGIN Set_Stereographic_Parameters   */
+/*  
+ *  The function Set_Stereographic_Parameters receives the ellipsoid
+ *  parameters and Stereograpic projection parameters as inputs, and
+ *  sets the corresponding state variables.  If any errors occur, error
+ *  code(s) are returned by the function, otherwise STEREO_NO_ERROR is returned.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (input)
+ *  f                : Flattening of ellipsoid					               (input)
+ *  Origin_Latitude  : Latitude, in radians, at the center of          (input)
+ *                       the projection
+ *  Central_Meridian : Longitude, in radians, at the center of         (input)
+ *                       the projection
+ *  False_Easting    : Easting (X) at center of projection, in meters  (input)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (input)
+ */
+
+  double es2, es4, es6;
+  double temp = 0;
+//  double inv_f = 1 / f;
+  long Error_Code = STEREO_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= STEREO_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= STEREO_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+//   { /* origin latitude out of range */
+//     Error_Code |= STEREO_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= STEREO_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Stereo_a = a;
+    Stereo_f = f;
+    es2 = 2 * Stereo_f - Stereo_f * Stereo_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    Stereo_Ra = Stereo_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 /3024.0);
+    Two_Stereo_Ra = 2.0 * Stereo_Ra;
+    Stereo_Origin_Lat = Origin_Latitude;
+    Sin_Stereo_Origin_Lat = sin(Stereo_Origin_Lat);
+    Cos_Stereo_Origin_Lat = cos(Stereo_Origin_Lat);
+//     if (Central_Meridian > M_PI)
+//       Central_Meridian -= TWO_PI;
+    Stereo_Origin_Long = Central_Meridian;
+    Stereo_False_Easting = False_Easting;
+    Stereo_False_Northing = False_Northing;
+    if(fabs(fabs(Stereo_Origin_Lat) - PI_OVER_2) < 1.0e-10)
+      Stereo_At_Pole = 1;
+    else
+      Stereo_At_Pole = 0;
+
+    if ((Stereo_At_Pole) || (fabs(Stereo_Origin_Lat) < 1.0e-10))
+    {
+      Stereo_Delta_Easting = 1460090226.0;
+    }
+    else
+    {
+      if (Stereo_Origin_Long <= 0)
+        Convert_Geodetic_To_Stereographic(-Stereo_Origin_Lat, M_PI + Stereo_Origin_Long - ONE, &Stereo_Delta_Easting, &temp);
+      else
+        Convert_Geodetic_To_Stereographic(-Stereo_Origin_Lat, Stereo_Origin_Long - M_PI - ONE, &Stereo_Delta_Easting, &temp);
+    }
+
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+} /* END OF Set_Stereographic_Parameters */
+
+void ossimStereographicProjection::Get_Stereographic_Parameters(double *a,
+                                                                double *f,
+                                                                double *Origin_Latitude,
+                                                                double *Central_Meridian,
+                                                                double *False_Easting,
+                                                                double *False_Northing)const
+
+{ /* BEGIN Get_Stereographic_Parameters */
+/*
+ * The function Get_Stereographic_Parameters returns the current ellipsoid
+ * parameters and Stereographic projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude, in radians, at the center of    (output)
+ *                          the projection
+ *    Central_Meridian  : Longitude, in radians, at the center of   (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value, in meters, assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value, in meters, assigned to the
+ *                          origin latitude of the projection       (output) 
+ */
+
+  *a = Stereo_a;
+  *f = Stereo_f;
+  *Origin_Latitude = Stereo_Origin_Lat;
+  *Central_Meridian = Stereo_Origin_Long;
+  *False_Easting = Stereo_False_Easting;
+  *False_Northing = Stereo_False_Northing;
+  
+  return;
+} /* END OF Get_Stereographic_Parameters */
+
+long ossimStereographicProjection::Convert_Geodetic_To_Stereographic (double Latitude,
+                                                                      double Longitude,
+                                                                      double *Easting,
+                                                                      double *Northing)const
+
+{  /* BEGIN Convert_Geodetic_To_Stereographic */
+
+/*
+ * The function Convert_Geodetic_To_Stereographic converts geodetic
+ * coordinates (latitude and longitude) to Stereographic coordinates
+ * (easting and northing), according to the current ellipsoid
+ * and Stereographic projection parameters. If any errors occur, error
+ * code(s) are returned by the function, otherwise STEREO_NO_ERROR is returned.
+ *
+ *    Latitude   :  Latitude, in radians                      (input)
+ *    Longitude  :  Longitude, in radians                     (input)
+ *    Easting    :  Easting (X), in meters                    (output)
+ *    Northing   :  Northing (Y), in meters                   (output)
+ */
+
+  double g, k;
+  double num = 0;
+  double Ra_k = 0;
+  double slat = sin(Latitude);
+  double clat = cos(Latitude);
+  double dlam;                        /* Longitude - Central Meridan */
+  double cos_dlam;
+  long   Error_Code = STEREO_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   {  /* Latitude out of range */
+//     Error_Code |= STEREO_LAT_ERROR;
+//   }
+//   if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+//   {  /* Longitude out of range */
+//     Error_Code|= STEREO_LON_ERROR;
+//   }
+  if (!Error_Code)
+  {  /* no errors */
+
+
+    dlam = Longitude - Stereo_Origin_Long;
+//     if (dlam > M_PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -M_PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+
+    cos_dlam = cos(dlam);
+    g = 1.0 + Sin_Stereo_Origin_Lat * slat + Cos_Stereo_Origin_Lat * clat * cos_dlam;
+    if (fabs(g) <= 1.0e-10)
+    {  /* Point is out of view.  Will return longitude out of range message
+          since no point out of view is implemented.  */
+      Error_Code |= STEREO_LON_ERROR;
+    }
+    else
+    {
+      if (Stereo_At_Pole)
+      {
+        if (fabs(fabs(Latitude) - PI_OVER_2) < 1.0e-10)
+        {
+          *Easting = Stereo_False_Easting;
+          *Northing = Stereo_False_Northing;
+        }
+        else
+        {
+          if (Stereo_Origin_Lat > 0)
+          {
+            num = Two_Stereo_Ra * tan(PI_OVER_4 - Latitude / 2.0);
+            *Easting = Stereo_False_Easting + num * sin(dlam);
+            *Northing = Stereo_False_Northing + (-num * cos_dlam);
+          }
+          else
+          {
+            num = Two_Stereo_Ra * tan(PI_OVER_4 + Latitude / 2.0);
+            *Easting = Stereo_False_Easting + num * sin(dlam);
+            *Northing = Stereo_False_Northing + num * cos_dlam;
+          }
+        }
+      }
+      else
+      {
+        if (fabs(Stereo_Origin_Lat) <= 1.0e-10)
+        {
+          k = 2.0 / (1.0 + clat * cos_dlam);
+          Ra_k = Stereo_Ra * k;
+          *Northing = Stereo_False_Northing + Ra_k * slat;
+        }
+        else
+        {
+          k = 2.0 / g;
+          Ra_k = Stereo_Ra * k;
+          *Northing = Stereo_False_Northing + Ra_k * (Cos_Stereo_Origin_Lat * slat - Sin_Stereo_Origin_Lat * clat * cos_dlam);
+        }
+        *Easting = Stereo_False_Easting + Ra_k * clat * sin(dlam);
+      }
+    }
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Stereographic */
+  
+long ossimStereographicProjection::Convert_Stereographic_To_Geodetic(double Easting,
+                                                                     double Northing,
+                                                                     double *Latitude,
+                                                                     double *Longitude)const
+{ /* BEGIN Convert_Stereographic_To_Geodetic */
+/*
+ * The function Convert_Stereographic_To_Geodetic converts Stereographic projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Stereographic projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise STEREO_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X), in meters              (input)
+ *    Northing          : Northing (Y), in meters             (input)
+ *    Latitude          : Latitude (phi), in radians          (output)
+ *    Longitude         : Longitude (lambda), in radians      (output)
+ */
+
+  double dx, dy;
+  double rho, c;
+  double sin_c, cos_c;
+  double dy_sin_c;
+  long Error_Code = STEREO_NO_ERROR;
+
+//   if ((Easting < (Stereo_False_Easting - Stereo_Delta_Easting))
+//       ||(Easting > (Stereo_False_Easting + Stereo_Delta_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= STEREO_EASTING_ERROR;
+//   }
+//   if ((Northing < (Stereo_False_Northing - Stereo_Delta_Northing))
+//       || (Northing > (Stereo_False_Northing + Stereo_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= STEREO_NORTHING_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+
+    dy = Northing - Stereo_False_Northing;
+    dx = Easting - Stereo_False_Easting;
+    rho = sqrt(dx * dx + dy * dy);
+    if (fabs(rho) <= 1.0e-10)
+    {
+      *Latitude = Stereo_Origin_Lat;
+      *Longitude = Stereo_Origin_Long;
+    }
+    else
+    {
+      c = 2.0 * atan(rho / (Two_Stereo_Ra));
+      sin_c = sin(c);
+      cos_c = cos(c);
+      dy_sin_c = dy * sin_c;
+      if (Stereo_At_Pole)
+      {
+        if (Stereo_Origin_Lat > 0)
+          *Longitude = Stereo_Origin_Long + atan2(dx, -dy);
+        else
+          *Longitude = Stereo_Origin_Long + atan2(dx, dy);
+      }
+      else
+        *Longitude = Stereo_Origin_Long + atan2(dx * sin_c, (rho * Cos_Stereo_Origin_Lat * cos_c - dy_sin_c * Sin_Stereo_Origin_Lat));
+      *Latitude = asin(cos_c * Sin_Stereo_Origin_Lat + ((dy_sin_c * Cos_Stereo_Origin_Lat) / rho));
+    }
+
+//     if (fabs(*Latitude) < 2.2e-8)  /* force lat to 0 to avoid -0 degrees */
+//       *Latitude = 0.0;
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+
+//     if (*Longitude > M_PI)
+//     {
+//       if (*Longitude - M_PI < 3.5e-6) 
+//         *Longitude = M_PI;
+//       else
+//         *Longitude -= TWO_PI;
+//     }
+//     if (*Longitude < -M_PI)
+//     {
+//       if (fabs(*Longitude + M_PI) < 3.5e-6)
+//         *Longitude = -M_PI;
+//       else
+//         *Longitude += TWO_PI;
+//     }
+//
+//     if (fabs(*Longitude) < 2.0e-7)  /* force lon to 0 to avoid -0 degrees */
+//       *Longitude = 0.0;
+//     if (*Longitude > M_PI)  /* force distorted values to 180, -180 degrees */
+//       *Longitude = M_PI;
+//     else if (*Longitude < -M_PI)
+//       *Longitude = -M_PI;
+  }
+  return (Error_Code);
+} /* END OF Convert_Stereographic_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimStereographicProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimStereographicProjection.h
new file mode 100644
index 0000000000..cff7bcce8c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimStereographicProjection.h
@@ -0,0 +1,193 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimStereographicProjection.h,v 1.2 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimStereographicProjection_HEADER
+#define ossimStereographicProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimStereographicProjection : public ossimMapProjection
+{
+public:   
+   ossimStereographicProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                            const ossimGpt& origin = ossimGpt());
+   ossimStereographicProjection(const ossimEllipsoid& ellipsoid,
+                            const ossimGpt& origin,
+                            const double falseEasting,
+                            const double falseNorthing);
+   ~ossimStereographicProjection(){}
+   virtual ossimObject *dup()const
+      {
+         return new ossimStereographicProjection(*this);
+      }
+   
+   virtual void update();
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return  Stereo_False_Easting;}
+   double getFalseNorthing()const{return Stereo_False_Northing;}
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+private:
+
+/************************************************************************/
+/*                           GLOBAL DECLARATIONS
+ *
+ */
+/* Ellipsoid Parameters, default to WGS 84  */
+mutable double Stereo_a;                    /* Semi-major axis of ellipsoid, in meters  */
+mutable double Stereo_f;            /* Flattening of ellipsoid  */
+mutable double Stereo_Ra;             /* Spherical Radius */
+mutable double Two_Stereo_Ra;        /* 2 * Spherical Radius */
+mutable long   Stereo_At_Pole;                        /* Flag variable */
+
+/* Stereographic projection Parameters */
+mutable double Stereo_Origin_Lat;                 /* Latitude of origin, in radians */
+mutable double Stereo_Origin_Long;                /* Longitude of origin, in radians */
+mutable double Stereo_False_Easting;              /* False easting, in meters */
+mutable double Stereo_False_Northing;             /* False northing, in meters */
+mutable double Sin_Stereo_Origin_Lat;             /* sin(Stereo_Origin_Lat) */
+mutable double Cos_Stereo_Origin_Lat;             /* cos(Stereo_Origin_Lat) */
+
+/* Maximum variance for easting and northing values for WGS 84. */
+mutable double Stereo_Delta_Easting;
+mutable double Stereo_Delta_Northing;
+
+/*!
+ *  The function Set_Stereographic_Parameters receives the ellipsoid
+ *  parameters and Stereograpic projection parameters as inputs, and
+ *  sets the corresponding state variables.  If any errors occur, error
+ *  code(s) are returned by the function, otherwise STEREO_NO_ERROR is returned.
+ *
+ *  a                : Semi-major axis of ellipsoid, in meters         (input)
+ *  f                : Flattening of ellipsoid					               (input)
+ *  Origin_Latitude  : Latitude, in radians, at the center of          (input)
+ *                       the projection
+ *  Central_Meridian : Longitude, in radians, at the center of         (input)
+ *                       the projection
+ *  False_Easting    : Easting (X) at center of projection, in meters  (input)
+ *  False_Northing   : Northing (Y) at center of projection, in meters (input)
+ */
+long Set_Stereographic_Parameters (double a,
+                                   double f,
+                                   double Origin_Latitude,
+                                   double Central_Meridian,
+                                   double False_Easting,
+                                   double False_Northing);
+
+/*!
+ * The function Get_Stereographic_Parameters returns the current ellipsoid
+ * parameters and Stereographic projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude, in radians, at the center of    (output)
+ *                          the projection
+ *    Central_Meridian  : Longitude, in radians, at the center of   (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value, in meters, assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value, in meters, assigned to the
+ *                          origin latitude of the projection       (output) 
+ */
+void Get_Stereographic_Parameters(double *a,
+                                  double *f,
+                                  double *Origin_Latitude,
+                                  double *Central_Meridian,
+                                  double *False_Easting,
+                                  double *False_Northing)const;
+
+/*!
+ * The function Convert_Geodetic_To_Stereographic converts geodetic
+ * coordinates (latitude and longitude) to Stereographic coordinates
+ * (easting and northing), according to the current ellipsoid
+ * and Stereographic projection parameters. If any errors occur, error
+ * code(s) are returned by the function, otherwise STEREO_NO_ERROR is returned.
+ *
+ *    Latitude   :  Latitude, in radians                      (input)
+ *    Longitude  :  Longitude, in radians                     (input)
+ *    Easting    :  Easting (X), in meters                    (output)
+ *    Northing   :  Northing (Y), in meters                   (output)
+ */
+long Convert_Geodetic_To_Stereographic (double Latitude,
+                                        double Longitude,
+                                        double *Easting,
+                                        double *Northing)const;
+
+/*!
+ * The function Convert_Stereographic_To_Geodetic converts Stereographic projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Stereographic projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise STEREO_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X), in meters              (input)
+ *    Northing          : Northing (Y), in meters             (input)
+ *    Latitude          : Latitude (phi), in radians          (output)
+ *    Longitude         : Longitude (lambda), in radians      (output)
+ */
+long Convert_Stereographic_To_Geodetic(double Easting,
+                                       double Northing,
+                                       double *Latitude,
+                                       double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTranmerc.c b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTranmerc.c
new file mode 100644
index 0000000000..cc9e0cecd0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTranmerc.c
@@ -0,0 +1,625 @@
+/***************************************************************************/
+/* RSC IDENTIFIER: TRANSVERSE MERCATOR
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between Geodetic coordinates 
+ *    (latitude and longitude) and Transverse Mercator projection coordinates
+ *    (easting and northing).
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *       TRANMERC_NO_ERROR           : No errors occurred in function
+ *       TRANMERC_LAT_ERROR          : Latitude outside of valid range
+ *                                      (-90 to 90 degrees)
+ *       TRANMERC_LON_ERROR          : Longitude outside of valid range
+ *                                      (-180 to 360 degrees, and within
+ *                                        +/-90 of Central Meridian)
+ *       TRANMERC_EASTING_ERROR      : Easting outside of valid range
+ *                                      (depending on ellipsoid and
+ *                                       projection parameters)
+ *       TRANMERC_NORTHING_ERROR     : Northing outside of valid range
+ *                                      (depending on ellipsoid and
+ *                                       projection parameters)
+ *       TRANMERC_ORIGIN_LAT_ERROR   : Origin latitude outside of valid range
+ *                                      (-90 to 90 degrees)
+ *       TRANMERC_CENT_MER_ERROR     : Central meridian outside of valid range
+ *                                      (-180 to 360 degrees)
+ *       TRANMERC_A_ERROR            : Semi-major axis less than or equal to zero
+ *       TRANMERC_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	                  (250 to 350)
+ *       TRANMERC_SCALE_FACTOR_ERROR : Scale factor outside of valid
+ *                                     range (0.3 to 3.0)
+ *		 TM_LON_WARNING              : Distortion will result if longitude is more
+ *                                       than 9 degrees from the Central Meridian
+ *
+ * REUSE NOTES
+ *
+ *    TRANSVERSE MERCATOR is intended for reuse by any application that 
+ *    performs a Transverse Mercator projection or its inverse.
+ *    
+ * REFERENCES
+ *
+ *    Further information on TRANSVERSE MERCATOR can be found in the 
+ *    Reuse Manual.
+ *
+ *    TRANSVERSE MERCATOR originated from :  
+ *                      U.S. Army Topographic Engineering Center
+ *                      Geospatial Information Division
+ *                      7701 Telegraph Road
+ *                      Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    TRANSVERSE MERCATOR has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    TRANSVERSE MERCATOR was tested and certified in the following 
+ *    environments:
+ *
+ *    1. Solaris 2.5 with GCC, version 2.8.1
+ *    2. Windows 95 with MS Visual C++, version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    10-02-97          Original Code
+ *    03-02-97          Re-engineered Code
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                               INCLUDES
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include "ossimTranmerc.h"
+#include "base/common/ossimConstants.h"
+
+/*
+ *    math.h      - Standard C math library
+ *    tranmerc.h  - Is for prototype error checking
+ */
+
+
+/****************************** DEFINES ************************************/
+
+#define MAX_LAT         ((M_PI * 90.0)/180.0)    /* 90 degrees in radians */
+#define MAX_DELTA_LONG  ((M_PI * 90.0)/180.0)    /* 90 degrees in radians */
+#define MIN_SCALE_FACTOR  0.3
+#define MAX_SCALE_FACTOR  3.0
+
+#define SPHTMD(Latitude) ((double) (TranMerc_ap * Latitude \
+      - TranMerc_bp * sin(2.e0 * Latitude) + TranMerc_cp * sin(4.e0 * Latitude) \
+      - TranMerc_dp * sin(6.e0 * Latitude) + TranMerc_ep * sin(8.e0 * Latitude) ) )
+
+#define SPHSN(Latitude) ((double) (TranMerc_a / sqrt( 1.e0 - TranMerc_es * \
+      pow(sin(Latitude), 2))))
+
+#define SPHSR(Latitude) ((double) (TranMerc_a * (1.e0 - TranMerc_es) / \
+    pow(DENOM(Latitude), 3)))
+
+#define DENOM(Latitude) ((double) (sqrt(1.e0 - TranMerc_es * pow(sin(Latitude),2))))
+
+
+/**************************************************************************/
+/*                               GLOBAL DECLARATIONS
+ *
+ */
+
+/* Ellipsoid Parameters, default to WGS 84  */
+static double TranMerc_a = 6378137.0;              /* Semi-major axis of ellipsoid i meters */
+static double TranMerc_f = 1 / 298.257223563;      /* Flattening of ellipsoid  */
+static double TranMerc_es = 0.0066943799901413800; /* Eccentricity (0.08181919084262188000) squared */
+static double TranMerc_ebs = 0.0067394967565869;   /* Second Eccentricity squared */
+
+/* Transverse_Mercator projection Parameters */
+static double TranMerc_Origin_Lat = 0.0;           /* Latitude of origin in radians */
+static double TranMerc_Origin_Long = 0.0;          /* Longitude of origin in radians */
+static double TranMerc_False_Northing = 0.0;       /* False northing in meters */
+static double TranMerc_False_Easting = 0.0;        /* False easting in meters */
+static double TranMerc_Scale_Factor = 1.0;         /* Scale factor  */
+
+/* Isometeric to geodetic latitude parameters, default to WGS 84 */
+static double TranMerc_ap = 6367449.1458008;
+static double TranMerc_bp = 16038.508696861;
+static double TranMerc_cp = 16.832613334334;
+static double TranMerc_dp = 0.021984404273757;
+static double TranMerc_ep = 3.1148371319283e-005;
+
+/* Maximum variance for easting and northing values for WGS 84. */
+static double TranMerc_Delta_Easting = 40000000.0;
+static double TranMerc_Delta_Northing = 40000000.0;
+
+/* These state variables are for optimization purposes. The only function
+ * that should modify them is Set_Tranverse_Mercator_Parameters.         */
+
+
+/************************************************************************/
+/*                              FUNCTIONS     
+ *
+ */
+
+
+long Set_Transverse_Mercator_Parameters(double a,
+                                        double f,
+                                        double Origin_Latitude,
+                                        double Central_Meridian,
+                                        double False_Easting,
+                                        double False_Northing,
+                                        double Scale_Factor)
+
+{ /* BEGIN Set_Tranverse_Mercator_Parameters */
+  /*
+   * The function Set_Tranverse_Mercator_Parameters receives the ellipsoid
+   * parameters and Tranverse Mercator projection parameters as inputs, and
+   * sets the corresponding state variables. If any errors occur, the error
+   * code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+   * returned.
+   *
+   *    a                 : Semi-major axis of ellipsoid, in meters    (input)
+   *    f                 : Flattening of ellipsoid						         (input)
+   *    Origin_Latitude   : Latitude in radians at the origin of the   (input)
+   *                         projection
+   *    Central_Meridian  : Longitude in radians at the center of the  (input)
+   *                         projection
+   *    False_Easting     : Easting/X at the center of the projection  (input)
+   *    False_Northing    : Northing/Y at the center of the projection (input)
+   *    Scale_Factor      : Projection scale factor                    (input) 
+   */
+
+  double tn;        /* True Meridianal distance constant  */
+  double tn2;
+  double tn3;
+  double tn4;
+  double tn5;
+  double dummy_northing;
+  double TranMerc_b; /* Semi-minor axis of ellipsoid, in meters */
+/*  double inv_f = 1 / f; */
+  long Error_Code = TRANMERC_NO_ERROR;
+
+#if 0
+  if (a <= 0.0)
+  { /* Semi-major axis must be greater than zero */
+    Error_Code |= TRANMERC_A_ERROR;
+  }
+  if ((inv_f < 250) || (inv_f > 350))
+  { /* Inverse flattening must be between 250 and 350 */
+    Error_Code |= TRANMERC_INV_F_ERROR;
+  }
+  if ((Origin_Latitude < -MAX_LAT) || (Origin_Latitude > MAX_LAT))
+  { /* origin latitude out of range */
+    Error_Code |= TRANMERC_ORIGIN_LAT_ERROR;
+  }
+  if ((Central_Meridian < -M_PI) || (Central_Meridian > (TWO_PI)))
+  { /* origin longitude out of range */
+    Error_Code |= TRANMERC_CENT_MER_ERROR;
+  }
+  if ((Scale_Factor < MIN_SCALE_FACTOR) || (Scale_Factor > MAX_SCALE_FACTOR))
+  {
+    Error_Code |= TRANMERC_SCALE_FACTOR_ERROR;
+  }
+#endif
+  if (!Error_Code)
+  { /* no errors */
+    TranMerc_a = a;
+    TranMerc_f = f;
+    TranMerc_Origin_Lat = 0;
+    TranMerc_Origin_Long = 0;
+    TranMerc_False_Northing = 0;
+    TranMerc_False_Easting = 0; 
+    TranMerc_Scale_Factor = 1;
+
+    /* Eccentricity Squared */
+    TranMerc_es = 2 * TranMerc_f - TranMerc_f * TranMerc_f;
+    /* Second Eccentricity Squared */
+    TranMerc_ebs = (1 / (1 - TranMerc_es)) - 1;
+
+    TranMerc_b = TranMerc_a * (1 - TranMerc_f);    
+    /*True meridianal constants  */
+    tn = (TranMerc_a - TranMerc_b) / (TranMerc_a + TranMerc_b);
+    tn2 = tn * tn;
+    tn3 = tn2 * tn;
+    tn4 = tn3 * tn;
+    tn5 = tn4 * tn;
+
+    TranMerc_ap = TranMerc_a * (1.e0 - tn + 5.e0 * (tn2 - tn3)/4.e0
+                                + 81.e0 * (tn4 - tn5)/64.e0 );
+    TranMerc_bp = 3.e0 * TranMerc_a * (tn - tn2 + 7.e0 * (tn3 - tn4)
+                                       /8.e0 + 55.e0 * tn5/64.e0 )/2.e0;
+    TranMerc_cp = 15.e0 * TranMerc_a * (tn2 - tn3 + 3.e0 * (tn4 - tn5 )/4.e0) /16.0;
+    TranMerc_dp = 35.e0 * TranMerc_a * (tn3 - tn4 + 11.e0 * tn5 / 16.e0) / 48.e0;
+    TranMerc_ep = 315.e0 * TranMerc_a * (tn4 - tn5) / 512.e0;
+    Convert_Geodetic_To_Transverse_Mercator(MAX_LAT,
+                                            MAX_DELTA_LONG,
+                                            &TranMerc_Delta_Easting,
+                                            &TranMerc_Delta_Northing);
+    Convert_Geodetic_To_Transverse_Mercator(0,
+                                            MAX_DELTA_LONG,
+                                            &TranMerc_Delta_Easting,
+                                            &dummy_northing);
+    TranMerc_Origin_Lat = Origin_Latitude;
+    if (Central_Meridian > M_PI)
+      Central_Meridian -= (TWO_PI);
+    TranMerc_Origin_Long = Central_Meridian;
+    TranMerc_False_Northing = False_Northing;
+    TranMerc_False_Easting = False_Easting; 
+    TranMerc_Scale_Factor = Scale_Factor;
+  } /* END OF if(!Error_Code) */
+  
+  return (Error_Code);
+}  /* END of Set_Transverse_Mercator_Parameters  */
+
+
+void Get_Transverse_Mercator_Parameters(double *a,
+                                        double *f,
+                                        double *Origin_Latitude,
+                                        double *Central_Meridian,
+                                        double *False_Easting,
+                                        double *False_Northing,
+                                        double *Scale_Factor)
+
+{ /* BEGIN Get_Tranverse_Mercator_Parameters  */
+  /*
+   * The function Get_Transverse_Mercator_Parameters returns the current
+   * ellipsoid and Transverse Mercator projection parameters.
+   *
+   *    a                 : Semi-major axis of ellipsoid, in meters    (output)
+   *    f                 : Flattening of ellipsoid						         (output)
+   *    Origin_Latitude   : Latitude in radians at the origin of the   (output)
+   *                         projection
+   *    Central_Meridian  : Longitude in radians at the center of the  (output)
+   *                         projection
+   *    False_Easting     : Easting/X at the center of the projection  (output)
+   *    False_Northing    : Northing/Y at the center of the projection (output)
+   *    Scale_Factor      : Projection scale factor                    (output) 
+   */
+
+  *a = TranMerc_a;
+  *f = TranMerc_f;
+  *Origin_Latitude = TranMerc_Origin_Lat;
+  *Central_Meridian = TranMerc_Origin_Long;
+  *False_Easting = TranMerc_False_Easting;
+  *False_Northing = TranMerc_False_Northing;
+  *Scale_Factor = TranMerc_Scale_Factor;
+  return;
+} /* END OF Get_Tranverse_Mercator_Parameters */
+
+
+
+long Convert_Geodetic_To_Transverse_Mercator (double Latitude,
+                                              double Longitude,
+                                              double *Easting,
+                                              double *Northing)
+
+{      /* BEGIN Convert_Geodetic_To_Transverse_Mercator */
+
+  /*
+   * The function Convert_Geodetic_To_Transverse_Mercator converts geodetic
+   * (latitude and longitude) coordinates to Transverse Mercator projection
+   * (easting and northing) coordinates, according to the current ellipsoid
+   * and Transverse Mercator projection coordinates.  If any errors occur, the
+   * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+   * returned.
+   *
+   *    Latitude      : Latitude in radians                         (input)
+   *    Longitude     : Longitude in radians                        (input)
+   *    Easting       : Easting/X in meters                         (output)
+   *    Northing      : Northing/Y in meters                        (output)
+   */
+
+  double c;       /* Cosine of latitude                          */
+  double c2;
+  double c3;
+  double c5;
+  double c7;
+  double dlam;    /* Delta longitude - Difference in Longitude       */
+  double eta;     /* constant - TranMerc_ebs *c *c                   */
+  double eta2;
+  double eta3;
+  double eta4;
+  double s;       /* Sine of latitude                        */
+  double sn;      /* Radius of curvature in the prime vertical       */
+  double t;       /* Tangent of latitude                             */
+  double tan2;
+  double tan3;
+  double tan4;
+  double tan5;
+  double tan6;
+  double t1;      /* Term in coordinate conversion formula - GP to Y */
+  double t2;      /* Term in coordinate conversion formula - GP to Y */
+  double t3;      /* Term in coordinate conversion formula - GP to Y */
+  double t4;      /* Term in coordinate conversion formula - GP to Y */
+  double t5;      /* Term in coordinate conversion formula - GP to Y */
+  double t6;      /* Term in coordinate conversion formula - GP to Y */
+  double t7;      /* Term in coordinate conversion formula - GP to Y */
+  double t8;      /* Term in coordinate conversion formula - GP to Y */
+  double t9;      /* Term in coordinate conversion formula - GP to Y */
+  double tmd;     /* True Meridional distance                        */
+  double tmdo;    /* True Meridional distance for latitude of origin */
+  long    Error_Code = TRANMERC_NO_ERROR;
+/*  double temp_Origin; */
+/*  double temp_Long; */
+#if 0
+  if ((Latitude < -MAX_LAT) || (Latitude > MAX_LAT))
+  {  /* Latitude out of range */
+    Error_Code|= TRANMERC_LAT_ERROR;
+  }
+  if (Longitude > M_PI)
+    Longitude -= (TWO_PI);
+  if ((Longitude < (TranMerc_Origin_Long - MAX_DELTA_LONG))
+      || (Longitude > (TranMerc_Origin_Long + MAX_DELTA_LONG)))
+  {
+    if (Longitude < 0)
+      temp_Long = Longitude + TWO_PI;
+    else
+      temp_Long = Longitude;
+    if (TranMerc_Origin_Long < 0)
+      temp_Origin = TranMerc_Origin_Long + TWO_PI;
+    else
+      temp_Origin = TranMerc_Origin_Long;
+    if ((temp_Long < (temp_Origin - MAX_DELTA_LONG))
+        || (temp_Long > (temp_Origin + MAX_DELTA_LONG)))
+      Error_Code|= TRANMERC_LON_ERROR;
+  }
+#endif
+
+  if (!Error_Code)
+  { /* no errors */
+
+    /* 
+     *  Delta Longitude
+     */
+    dlam = Longitude - TranMerc_Origin_Long;
+
+    if (fabs(dlam) > (9.0 * RAD_PER_DEG))
+    { /* Distortion will result if Longitude is more than 9 degrees from the Central Meridian */
+      Error_Code |= TRANMERC_LON_WARNING;
+    }
+
+    if (dlam > M_PI)
+      dlam -= (TWO_PI);
+    if (dlam < -M_PI)
+      dlam += (TWO_PI);
+    if (fabs(dlam) < 2.e-10)
+      dlam = 0.0;
+
+    s = sin(Latitude);
+    c = cos(Latitude);
+    c2 = c * c;
+    c3 = c2 * c;
+    c5 = c3 * c2;
+    c7 = c5 * c2;
+    t = tan (Latitude);
+    tan2 = t * t;
+    tan3 = tan2 * t;
+    tan4 = tan3 * t;
+    tan5 = tan4 * t;
+    tan6 = tan5 * t;
+    eta = TranMerc_ebs * c2;
+    eta2 = eta * eta;
+    eta3 = eta2 * eta;
+    eta4 = eta3 * eta;
+
+    /* radius of curvature in prime vertical */
+    sn = SPHSN(Latitude);
+
+    /* True Meridianal Distances */
+    tmd = SPHTMD(Latitude);
+
+    /*  Origin  */
+    tmdo = SPHTMD (TranMerc_Origin_Lat);
+
+    /* northing */
+    t1 = (tmd - tmdo) * TranMerc_Scale_Factor;
+    t2 = sn * s * c * TranMerc_Scale_Factor/ 2.e0;
+    t3 = sn * s * c3 * TranMerc_Scale_Factor * (5.e0 - tan2 + 9.e0 * eta 
+                                                + 4.e0 * eta2) /24.e0; 
+
+    t4 = sn * s * c5 * TranMerc_Scale_Factor * (61.e0 - 58.e0 * tan2
+                                                + tan4 + 270.e0 * eta - 330.e0 * tan2 * eta + 445.e0 * eta2
+                                                + 324.e0 * eta3 -680.e0 * tan2 * eta2 + 88.e0 * eta4 
+                                                -600.e0 * tan2 * eta3 - 192.e0 * tan2 * eta4) / 720.e0;
+
+    t5 = sn * s * c7 * TranMerc_Scale_Factor * (1385.e0 - 3111.e0 * 
+                                                tan2 + 543.e0 * tan4 - tan6) / 40320.e0;
+
+    *Northing = TranMerc_False_Northing + t1 + pow(dlam,2.e0) * t2
+                + pow(dlam,4.e0) * t3 + pow(dlam,6.e0) * t4
+                + pow(dlam,8.e0) * t5; 
+
+    /* Easting */
+    t6 = sn * c * TranMerc_Scale_Factor;
+    t7 = sn * c3 * TranMerc_Scale_Factor * (1.e0 - tan2 + eta ) /6.e0;
+    t8 = sn * c5 * TranMerc_Scale_Factor * (5.e0 - 18.e0 * tan2 + tan4
+                                            + 14.e0 * eta - 58.e0 * tan2 * eta + 13.e0 * eta2 + 4.e0 * eta3 
+                                            - 64.e0 * tan2 * eta2 - 24.e0 * tan2 * eta3 )/ 120.e0;
+    t9 = sn * c7 * TranMerc_Scale_Factor * ( 61.e0 - 479.e0 * tan2
+                                             + 179.e0 * tan4 - tan6 ) /5040.e0;
+
+    *Easting = TranMerc_False_Easting + dlam * t6 + pow(dlam,3.e0) * t7 
+               + pow(dlam,5.e0) * t8 + pow(dlam,7.e0) * t9;
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Transverse_Mercator */
+
+
+long Convert_Transverse_Mercator_To_Geodetic (
+                                             double Easting,
+                                             double Northing,
+                                             double *Latitude,
+                                             double *Longitude)
+{      /* BEGIN Convert_Transverse_Mercator_To_Geodetic */
+
+  /*
+   * The function Convert_Transverse_Mercator_To_Geodetic converts Transverse
+   * Mercator projection (easting and northing) coordinates to geodetic
+   * (latitude and longitude) coordinates, according to the current ellipsoid
+   * and Transverse Mercator projection parameters.  If any errors occur, the
+   * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+   * returned.
+   *
+   *    Easting       : Easting/X in meters                         (input)
+   *    Northing      : Northing/Y in meters                        (input)
+   *    Latitude      : Latitude in radians                         (output)
+   *    Longitude     : Longitude in radians                        (output)
+   */
+
+  double c;       /* Cosine of latitude                          */
+  double de;      /* Delta easting - Difference in Easting (Easting-Fe)    */
+  double dlam;    /* Delta longitude - Difference in Longitude       */
+  double eta;     /* constant - TranMerc_ebs *c *c                   */
+  double eta2;
+  double eta3;
+  double eta4;
+  double ftphi;   /* Footpoint latitude                              */
+  int    i;       /* Loop iterator                   */
+  double s;       /* Sine of latitude                        */
+  double sn;      /* Radius of curvature in the prime vertical       */
+  double sr;      /* Radius of curvature in the meridian             */
+  double t;       /* Tangent of latitude                             */
+  double tan2;
+  double tan4;
+  double t10;     /* Term in coordinate conversion formula - GP to Y */
+  double t11;     /* Term in coordinate conversion formula - GP to Y */
+  double t12;     /* Term in coordinate conversion formula - GP to Y */
+  double t13;     /* Term in coordinate conversion formula - GP to Y */
+  double t14;     /* Term in coordinate conversion formula - GP to Y */
+  double t15;     /* Term in coordinate conversion formula - GP to Y */
+  double t16;     /* Term in coordinate conversion formula - GP to Y */
+  double t17;     /* Term in coordinate conversion formula - GP to Y */
+  double tmd;     /* True Meridional distance                        */
+  double tmdo;    /* True Meridional distance for latitude of origin */
+  long Error_Code = TRANMERC_NO_ERROR;
+
+#if 0
+  if ((Easting < (TranMerc_False_Easting - TranMerc_Delta_Easting))
+      ||(Easting > (TranMerc_False_Easting + TranMerc_Delta_Easting)))
+  { /* Easting out of range  */
+    Error_Code |= TRANMERC_EASTING_ERROR;
+  }
+  if ((Northing < (TranMerc_False_Northing - TranMerc_Delta_Northing))
+      || (Northing > (TranMerc_False_Northing + TranMerc_Delta_Northing)))
+  { /* Northing out of range */
+    Error_Code |= TRANMERC_NORTHING_ERROR;
+  }
+#endif
+
+  if (!Error_Code)
+  {
+    /* True Meridional Distances for latitude of origin */
+    tmdo = SPHTMD(TranMerc_Origin_Lat);
+
+    /*  Origin  */
+    tmd = tmdo +  (Northing - TranMerc_False_Northing) / TranMerc_Scale_Factor; 
+
+    /* First Estimate */
+    sr = SPHSR(0.e0);
+    ftphi = tmd/sr;
+
+    for (i = 0; i < 5 ; i++)
+    {
+      t10 = SPHTMD (ftphi);
+      sr = SPHSR(ftphi);
+      ftphi = ftphi + (tmd - t10) / sr;
+    }
+
+    /* Radius of Curvature in the meridian */
+    sr = SPHSR(ftphi);
+
+    /* Radius of Curvature in the meridian */
+    sn = SPHSN(ftphi);
+
+    /* Sine Cosine terms */
+    s = sin(ftphi);
+    c = cos(ftphi);
+
+    /* Tangent Value  */
+    t = tan(ftphi);
+    tan2 = t * t;
+    tan4 = tan2 * tan2;
+    eta = TranMerc_ebs * pow(c,2);
+    eta2 = eta * eta;
+    eta3 = eta2 * eta;
+    eta4 = eta3 * eta;
+    de = Easting - TranMerc_False_Easting;
+    if (fabs(de) < 0.0001)
+      de = 0.0;
+
+    /* Latitude */
+    t10 = t / (2.e0 * sr * sn * pow(TranMerc_Scale_Factor, 2));
+    t11 = t * (5.e0  + 3.e0 * tan2 + eta - 4.e0 * pow(eta,2)
+               - 9.e0 * tan2 * eta) / (24.e0 * sr * pow(sn,3) 
+                                       * pow(TranMerc_Scale_Factor,4));
+    t12 = t * (61.e0 + 90.e0 * tan2 + 46.e0 * eta + 45.E0 * tan4
+               - 252.e0 * tan2 * eta  - 3.e0 * eta2 + 100.e0 
+               * eta3 - 66.e0 * tan2 * eta2 - 90.e0 * tan4
+               * eta + 88.e0 * eta4 + 225.e0 * tan4 * eta2
+               + 84.e0 * tan2* eta3 - 192.e0 * tan2 * eta4)
+          / ( 720.e0 * sr * pow(sn,5) * pow(TranMerc_Scale_Factor, 6) );
+    t13 = t * ( 1385.e0 + 3633.e0 * tan2 + 4095.e0 * tan4 + 1575.e0 
+                * pow(t,6))/ (40320.e0 * sr * pow(sn,7) * pow(TranMerc_Scale_Factor,8));
+    *Latitude = ftphi - pow(de,2) * t10 + pow(de,4) * t11 - pow(de,6) * t12 
+                + pow(de,8) * t13;
+
+    t14 = 1.e0 / (sn * c * TranMerc_Scale_Factor);
+
+    t15 = (1.e0 + 2.e0 * tan2 + eta) / (6.e0 * pow(sn,3) * c * 
+                                        pow(TranMerc_Scale_Factor,3));
+
+    t16 = (5.e0 + 6.e0 * eta + 28.e0 * tan2 - 3.e0 * eta2
+           + 8.e0 * tan2 * eta + 24.e0 * tan4 - 4.e0 
+           * eta3 + 4.e0 * tan2 * eta2 + 24.e0 
+           * tan2 * eta3) / (120.e0 * pow(sn,5) * c  
+                             * pow(TranMerc_Scale_Factor,5));
+
+    t17 = (61.e0 +  662.e0 * tan2 + 1320.e0 * tan4 + 720.e0 
+           * pow(t,6)) / (5040.e0 * pow(sn,7) * c 
+                          * pow(TranMerc_Scale_Factor,7));
+
+    /* Difference in Longitude */
+    dlam = de * t14 - pow(de,3) * t15 + pow(de,5) * t16 - pow(de,7) * t17;
+
+    /* Longitude */
+    (*Longitude) = TranMerc_Origin_Long + dlam;
+    while (*Latitude > (90.0 * RAD_PER_DEG))
+    {
+      *Latitude = M_PI - *Latitude;
+      *Longitude += M_PI;
+      if (*Longitude > M_PI)
+        *Longitude -= (TWO_PI);
+    }
+
+    while (*Latitude < (-90.0 * RAD_PER_DEG))
+    {
+      *Latitude = - (*Latitude + M_PI);
+      *Longitude += M_PI;
+      if (*Longitude > M_PI)
+        *Longitude -= (TWO_PI);
+    }
+    if (*Longitude > (TWO_PI))
+      *Longitude -= (TWO_PI);
+    if (*Longitude < -M_PI)
+      *Longitude += (TWO_PI);
+
+    if (fabs(dlam) > (9.0 * RAD_PER_DEG))
+    { /* Distortion will result if Longitude is more than 9 degrees from the Central Meridian */
+      Error_Code |= TRANMERC_LON_WARNING;
+    }
+  }
+  return (Error_Code);
+} /* END OF Convert_Transverse_Mercator_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTranmerc.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTranmerc.h
new file mode 100644
index 0000000000..93e9a35e22
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTranmerc.h
@@ -0,0 +1,209 @@
+#ifndef TRANMERC_H
+#define TRANMERC_H
+
+/***************************************************************************/
+/* RSC IDENTIFIER: TRANSVERSE MERCATOR
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between Geodetic coordinates 
+ *    (latitude and longitude) and Transverse Mercator projection coordinates
+ *    (easting and northing).
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *       TRANMERC_NO_ERROR           : No errors occurred in function
+ *       TRANMERC_LAT_ERROR          : Latitude outside of valid range
+ *                                      (-90 to 90 degrees)
+ *       TRANMERC_LON_ERROR          : Longitude outside of valid range
+ *                                      (-180 to 360 degrees, and within
+ *                                        +/-90 of Central Meridian)
+ *       TRANMERC_EASTING_ERROR      : Easting outside of valid range
+ *                                      (depending on ellipsoid and
+ *                                       projection parameters)
+ *       TRANMERC_NORTHING_ERROR     : Northing outside of valid range
+ *                                      (depending on ellipsoid and
+ *                                       projection parameters)
+ *       TRANMERC_ORIGIN_LAT_ERROR   : Origin latitude outside of valid range
+ *                                      (-90 to 90 degrees)
+ *       TRANMERC_CENT_MER_ERROR     : Central meridian outside of valid range
+ *                                      (-180 to 360 degrees)
+ *       TRANMERC_A_ERROR            : Semi-major axis less than or equal to zero
+ *       TRANMERC_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	                  (250 to 350)
+ *       TRANMERC_SCALE_FACTOR_ERROR : Scale factor outside of valid
+ *                                     range (0.3 to 3.0)
+ *		 TM_LON_WARNING              : Distortion will result if longitude is more
+ *                                      than 9 degrees from the Central Meridian
+ *
+ * REUSE NOTES
+ *
+ *    TRANSVERSE MERCATOR is intended for reuse by any application that 
+ *    performs a Transverse Mercator projection or its inverse.
+ *    
+ * REFERENCES
+ *
+ *    Further information on TRANSVERSE MERCATOR can be found in the 
+ *    Reuse Manual.
+ *
+ *    TRANSVERSE MERCATOR originated from :  
+ *                      U.S. Army Topographic Engineering Center
+ *                      Geospatial Information Division
+ *                      7701 Telegraph Road
+ *                      Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    TRANSVERSE MERCATOR has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    TRANSVERSE MERCATOR was tested and certified in the following 
+ *    environments:
+ *
+ *    1. Solaris 2.5 with GCC, version 2.8.1
+ *    2. Windows 95 with MS Visual C++, version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    10-02-97          Original Code
+ *    03-02-97          Re-engineered Code
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+#define TRANMERC_NO_ERROR           0x0000
+#define TRANMERC_LAT_ERROR          0x0001
+#define TRANMERC_LON_ERROR          0x0002
+#define TRANMERC_EASTING_ERROR      0x0004
+#define TRANMERC_NORTHING_ERROR     0x0008
+#define TRANMERC_ORIGIN_LAT_ERROR   0x0010
+#define TRANMERC_CENT_MER_ERROR     0x0020
+#define TRANMERC_A_ERROR            0x0040
+#define TRANMERC_INV_F_ERROR        0x0080
+#define TRANMERC_SCALE_FACTOR_ERROR 0x0100
+#define TRANMERC_LON_WARNING        0x0200
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTION PROTOTYPES
+ *                                for TRANMERC.C
+ */
+
+/* ensure proper linkage to c++ programs */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+  long Set_Transverse_Mercator_Parameters(double a,      
+                                          double f,
+                                          double Origin_Latitude,
+                                          double Central_Meridian,
+                                          double False_Easting,
+                                          double False_Northing,
+                                          double Scale_Factor);
+/*
+ * The function Set_Tranverse_Mercator_Parameters receives the ellipsoid
+ * parameters and Tranverse Mercator projection parameters as inputs, and
+ * sets the corresponding state variables. If any errors occur, the error
+ * code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+ * returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters    (input)
+ *    f                 : Flattening of ellipsoid                    (input)
+ *    Origin_Latitude   : Latitude in radians at the origin of the   (input)
+ *                         projection
+ *    Central_Meridian  : Longitude in radians at the center of the  (input)
+ *                         projection
+ *    False_Easting     : Easting/X at the center of the projection  (input)
+ *    False_Northing    : Northing/Y at the center of the projection (input)
+ *    Scale_Factor      : Projection scale factor                    (input) 
+ */
+
+
+  void Get_Transverse_Mercator_Parameters(double *a,
+                                          double *f,
+                                          double *Origin_Latitude,
+                                          double *Central_Meridian,
+                                          double *False_Easting,
+                                          double *False_Northing,
+                                          double *Scale_Factor);
+/*
+ * The function Get_Transverse_Mercator_Parameters returns the current
+ * ellipsoid and Transverse Mercator projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters    (output)
+ *    f                 : Flattening of ellipsoid                    (output)
+ *    Origin_Latitude   : Latitude in radians at the origin of the   (output)
+ *                         projection
+ *    Central_Meridian  : Longitude in radians at the center of the  (output)
+ *                         projection
+ *    False_Easting     : Easting/X at the center of the projection  (output)
+ *    False_Northing    : Northing/Y at the center of the projection (output)
+ *    Scale_Factor      : Projection scale factor                    (output) 
+ */
+
+
+  long Convert_Geodetic_To_Transverse_Mercator (double Latitude,
+                                                double Longitude,
+                                                double *Easting,
+                                                double *Northing);
+
+/*
+ * The function Convert_Geodetic_To_Transverse_Mercator converts geodetic
+ * (latitude and longitude) coordinates to Transverse Mercator projection
+ * (easting and northing) coordinates, according to the current ellipsoid
+ * and Transverse Mercator projection coordinates.  If any errors occur, the
+ * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+ * returned.
+ *
+ *    Latitude      : Latitude in radians                         (input)
+ *    Longitude     : Longitude in radians                        (input)
+ *    Easting       : Easting/X in meters                         (output)
+ *    Northing      : Northing/Y in meters                        (output)
+ */
+
+
+  long Convert_Transverse_Mercator_To_Geodetic (double Easting,
+                                                double Northing,
+                                                double *Latitude,
+                                                double *Longitude);
+
+/*
+ * The function Convert_Transverse_Mercator_To_Geodetic converts Transverse
+ * Mercator projection (easting and northing) coordinates to geodetic
+ * (latitude and longitude) coordinates, according to the current ellipsoid
+ * and Transverse Mercator projection parameters.  If any errors occur, the
+ * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+ * returned.
+ *
+ *    Easting       : Easting/X in meters                         (input)
+ *    Northing      : Northing/Y in meters                        (input)
+ *    Latitude      : Latitude in radians                         (output)
+ *    Longitude     : Longitude in radians                        (output)
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRANMERC_H */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransCylEquAreaProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransCylEquAreaProjection.cpp
new file mode 100644
index 0000000000..90673bb2db
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransCylEquAreaProjection.cpp
@@ -0,0 +1,606 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Transverse Cylindrical Equal Area
+// projection code.  
+//*******************************************************************
+//  $Id: ossimTransCylEquAreaProjection.cpp,v 1.11 2004/01/08 21:49:22 jlargent Exp $
+
+#include <math.h>
+#include "ossimTransCylEquAreaProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimTransCylEquAreaProjection, "ossimTransCylEquAreaProjection", ossimMapProjection)
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+
+#define TCEA_Q(sinlat,x)                (One_MINUS_es2*(sinlat/(1.0-es2*sinlat*sinlat)-One_OVER_2es*log((1-x)/(1+x))))
+#define TCEA_COEFF_TIMES_SIN(coeff,x,latit)         (coeff * sin(x*latit))
+#define TCEA_M(c0lat,c1lat,c2lat,c3lat)             (Tcea_a * (c0lat - c1lat + c2lat - c3lat))
+#define TCEA_L(Beta,c0lat,c1lat,c2lat)              (Beta + c0lat + c1lat + c2lat)
+#define MIN_SCALE_FACTOR  0.3
+#define MAX_SCALE_FACTOR  3.0
+
+#define TCEA_NO_ERROR           0x0000
+#define TCEA_LAT_ERROR          0x0001
+#define TCEA_LON_ERROR          0x0002
+#define TCEA_EASTING_ERROR      0x0004
+#define TCEA_NORTHING_ERROR     0x0008
+#define TCEA_ORIGIN_LAT_ERROR   0x0010
+#define TCEA_CENT_MER_ERROR     0x0020
+#define TCEA_A_ERROR            0x0040
+#define TCEA_INV_F_ERROR        0x0080
+#define TCEA_SCALE_FACTOR_ERROR 0x0100
+#define TCEA_LON_WARNING        0x0200
+
+ossimTransCylEquAreaProjection::ossimTransCylEquAreaProjection(const ossimEllipsoid& ellipsoid,
+                                                               const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimTransCylEquAreaProjection::ossimTransCylEquAreaProjection(const ossimEllipsoid& ellipsoid,
+                                                               const ossimGpt& origin,
+                                                               double falseEasting,
+                                                               double falseNorthing,
+                                                               double scaleFactor)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Tcea_False_Easting  = falseEasting;
+   Tcea_False_Northing = falseNorthing;
+   Tcea_Scale_Factor   = scaleFactor;
+   Tcea_Min_Easting  = -6398628.0;
+   Tcea_Max_Easting  = 6398628.0;
+   Tcea_Min_Northing = -20003931.0;
+   Tcea_Max_Northing = 20003931.0;
+
+   update();
+}
+
+void ossimTransCylEquAreaProjection::setFalseEasting(double falseEasting)
+{
+   Tcea_False_Easting = falseEasting;
+   
+   update();
+}
+
+
+void ossimTransCylEquAreaProjection::setFalseNorthing(double falseNorthing)
+{
+   Tcea_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimTransCylEquAreaProjection::setFalseEastingNorthing(double falseEasting,
+                                                      double falseNorthing)
+{
+   Tcea_False_Easting  = falseEasting;
+   Tcea_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimTransCylEquAreaProjection::setScaleFactor(double scaleFactor)
+{
+   Tcea_Scale_Factor = scaleFactor;
+   
+   update();
+}
+
+void ossimTransCylEquAreaProjection::setParameters(double falseEasting,
+                                                   double falseNorthing,
+                                                   double scaleFactor)
+{
+   Tcea_False_Easting  = falseEasting;
+   Tcea_False_Northing = falseNorthing;
+   Tcea_Scale_Factor = scaleFactor;
+   
+   update();
+}
+
+void ossimTransCylEquAreaProjection::setDefaults()
+{
+   Tcea_Scale_Factor   = 1.0;
+   Tcea_False_Easting  = 0.0;
+   Tcea_False_Northing = 0.0;
+   Tcea_Min_Easting    = -6398628.0;
+   Tcea_Max_Easting    = 6398628.0;
+   Tcea_Min_Northing   = -20003931.0;
+   Tcea_Max_Northing   = 20003931.0;
+}
+
+void ossimTransCylEquAreaProjection::update()
+{  
+   Set_Trans_Cyl_Eq_Area_Parameters(theEllipsoid.getA(),
+                                    theEllipsoid.getFlattening(),
+                                    theOrigin.latr(),
+                                    theOrigin.lonr(),
+                                    Tcea_False_Easting,
+                                    Tcea_False_Northing,
+                                    Tcea_Scale_Factor);
+   ossimMapProjection::update();
+}
+   
+
+ossimGpt ossimTransCylEquAreaProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Trans_Cyl_Eq_Area_To_Geodetic(eastingNorthing.x,
+                                         eastingNorthing.y,
+                                         &lat,
+                                         &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimTransCylEquAreaProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Trans_Cyl_Eq_Area(gpt.latr(),
+                                         gpt.lonr(),
+                                         &easting,
+                                         &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+bool ossimTransCylEquAreaProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Tcea_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Tcea_False_Northing,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_FACTOR_KW,
+           Tcea_Scale_Factor,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimTransCylEquAreaProjection::loadState(const ossimKeywordlist& kwl,
+                                               const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   const char* scaleFactor   = kwl.find(prefix, ossimKeywordNames::SCALE_FACTOR_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimTransCylEquAreaProjection))
+   {
+      if(falseEasting)
+      {
+         Tcea_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Tcea_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+      if(scaleFactor)
+      {
+         Tcea_Scale_Factor = ossimString(scaleFactor).toDouble();
+      }
+   }
+   
+   update();
+
+   return flag;
+}
+
+long ossimTransCylEquAreaProjection::Set_Trans_Cyl_Eq_Area_Parameters(double a,
+                                                                      double f,
+                                                                      double Origin_Latitude,
+                                                                      double Central_Meridian,
+                                                                      double False_Easting,
+                                                                      double False_Northing,
+                                                                      double Scale_Factor)
+{ /* BEGIN Set_Trans_Cyl_Eq_Area_Parameters */
+/*
+ * The function Set_Trans_Cyl_Eq_Area_Parameters receives the ellipsoid parameters and
+ * Transverse Cylindrical Equal Area projection parameters as inputs, and sets the 
+ * corresponding state variables.  If any errors occur, the error code(s) are returned 
+ * by the function, otherwise TCEA_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ *    Scale_Factor      : Multiplier which reduces distances in the
+ *                          projection to the actual distance on the
+ *                          ellipsoid                               (input)
+ */
+
+  double sin_lat_90 = sin(PI_OVER_2);
+  double x, j, three_es4;
+  double Sqrt_One_MINUS_es2;
+  double e1, e2, e3, e4;
+  double lat, sin2lat, sin4lat, sin6lat;
+  double temp, temp_northing;
+//  double inv_f = 1 / f;
+  long Error_Code = TCEA_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= TCEA_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= TCEA_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
+//   { /* origin latitude out of range */
+//     Error_Code |= TCEA_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= TCEA_CENT_MER_ERROR;
+//   }
+//   if ((Scale_Factor < MIN_SCALE_FACTOR) || (Scale_Factor > MAX_SCALE_FACTOR))
+//   {
+//     Error_Code |= TCEA_SCALE_FACTOR_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+    Tcea_a = a;
+    Tcea_f = f;
+    Tcea_Origin_Lat = Origin_Latitude;
+    if (Central_Meridian > M_PI)
+      Central_Meridian -= TWO_PI;
+    Tcea_Origin_Long = Central_Meridian;
+    Tcea_False_Northing = False_Northing;
+    Tcea_False_Easting = False_Easting;
+    Tcea_Scale_Factor = Scale_Factor;
+
+    es2 = 2 * Tcea_f - Tcea_f * Tcea_f;
+    es = sqrt(es2);
+    One_MINUS_es2 = 1.0 - es2;
+    Sqrt_One_MINUS_es2 = sqrt(One_MINUS_es2);
+    One_OVER_2es = 1.0 / (2.0 * es);
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    x = es * sin_lat_90;
+    qp = TCEA_Q(sin_lat_90,x);
+
+    a0 = es2 / 3.0 + 31.0 * es4 / 180.0 + 517.0 * es6 / 5040.0;
+    a1 = 23.0 * es4 / 360.0 + 251.0 * es6 / 3780.0;
+    a2 = 761.0 * es6 / 45360.0;
+
+    e1 = (1.0 - Sqrt_One_MINUS_es2) / (1.0 + Sqrt_One_MINUS_es2);
+    e2 = e1 * e1;
+    e3 = e2 * e1;
+    e4 = e3 * e1;
+    b0 = 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0;
+    b1 = 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0;
+    b2 = 151.0 * e3 / 96.0;
+    b3 = 1097.0 * e4 / 512.0;
+
+    j = 45.0 * es6 / 1024.0;
+    three_es4 = 3.0 * es4;
+    c0 = 1.0 - es2 / 4.0 - three_es4 / 64.0 - 5.0 * es6 / 256.0;
+    c1 = 3.0 * es2 / 8.0 + three_es4 / 32.0 + j;
+    c2 = 15.0 * es4 / 256.0 + j;
+    c3 = 35.0 * es6 / 3072.0;
+    lat = c0 * Tcea_Origin_Lat;
+    sin2lat = TCEA_COEFF_TIMES_SIN(c1, 2.0, Tcea_Origin_Lat);
+    sin4lat = TCEA_COEFF_TIMES_SIN(c2, 4.0, Tcea_Origin_Lat);
+    sin6lat = TCEA_COEFF_TIMES_SIN(c3, 6.0, Tcea_Origin_Lat);
+    M0 = TCEA_M(lat, sin2lat, sin4lat, sin6lat);
+    Convert_Geodetic_To_Trans_Cyl_Eq_Area(PI_OVER_2, M_PI, &temp, &temp_northing);
+    if (temp_northing > 0)
+    {
+      Tcea_Min_Northing = temp_northing - 20003931.458986;
+      Tcea_Max_Northing = temp_northing;
+    }
+    else if (temp_northing < 0)
+    {
+      Tcea_Max_Northing = temp_northing + 20003931.458986;
+      Tcea_Min_Northing = temp_northing;
+    }
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+} /* END OF Set_Trans_Cyl_Eq_Area_Parameters */
+
+void ossimTransCylEquAreaProjection::Get_Trans_Cyl_Eq_Area_Parameters(double *a,
+                                                                      double *f,
+                                                                      double *Origin_Latitude,
+                                                                      double *Central_Meridian,
+                                                                      double *False_Easting,
+                                                                      double *False_Northing,
+                                                                      double *Scale_Factor)const
+{ /* BEGIN Get_Trans_Cyl_Eq_Area_Parameters */
+/*
+ * The function Get_Trans_Cyl_Eq_Area_Parameters returns the current ellipsoid
+ * parameters, Transverse Cylindrical Equal Area projection parameters, and scale factor.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ *    Scale_Factor      : Multiplier which reduces distances in the
+ *                          projection to the actual distance on the
+ *                          ellipsoid                               (output)
+ */
+
+  *a = Tcea_a;
+  *f = Tcea_f;
+  *Origin_Latitude = Tcea_Origin_Lat;
+  *Central_Meridian = Tcea_Origin_Long;
+  *False_Easting = Tcea_False_Easting;
+  *False_Northing = Tcea_False_Northing;
+  *Scale_Factor = Tcea_Scale_Factor;
+  
+  return;
+} /* END OF Get_Trans_Cyl_Eq_Area_Parameters */
+
+
+long ossimTransCylEquAreaProjection::Convert_Geodetic_To_Trans_Cyl_Eq_Area (double Latitude,
+                                                                            double Longitude,
+                                                                            double *Easting,
+                                                                            double *Northing)const
+{ /* BEGIN Convert_Geodetic_To_Trans_Cyl_Eq_Area */
+/*
+ * The function Convert_Geodetic_To_Trans_Cyl_Eq_Area converts geodetic (latitude and
+ * longitude) coordinates to Transverse Cylindrical Equal Area projection (easting and
+ * northing) coordinates, according to the current ellipsoid and Transverse Cylindrical 
+ * Equal Area projection parameters.  If any errors occur, the error code(s) are returned 
+ * by the function, otherwise TCEA_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double x;
+  double dlam;                      /* Longitude - Central Meridan */
+  double sin_lat = sin(Latitude);
+  double qq, qq_OVER_qp;
+  double beta, betac;
+  double sin2betac, sin4betac, sin6betac;
+  double PHIc;
+  double phi, sin2phi, sin4phi, sin6phi;
+  double sinPHIc;
+  double Mc;
+  long Error_Code = TCEA_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   { /* Latitude out of range */
+//     Error_Code |= TCEA_LAT_ERROR;
+//   }
+//   if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+//   { /* Longitude out of range */
+//     Error_Code |= TCEA_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dlam = Longitude - Tcea_Origin_Long;
+    if (fabs(dlam) >= (M_PI / 2.0))
+    { /* Distortion will result if Longitude is more than 90 degrees from the Central Meridian */
+      Error_Code |= TCEA_LON_WARNING;
+    }
+
+    if (dlam > M_PI)
+    {
+      dlam -= TWO_PI;
+    }
+    if (dlam < -M_PI)
+    {
+      dlam += TWO_PI;
+    }
+    if (Latitude == PI_OVER_2)
+    {
+      qq = qp;
+      qq_OVER_qp = 1.0;
+    }
+    else
+    {
+      x = es * sin_lat;
+      qq = TCEA_Q(sin_lat, x);
+      qq_OVER_qp = qq / qp;
+    }
+
+
+    if (qq_OVER_qp > 1.0)
+      qq_OVER_qp = 1.0;
+    else if (qq_OVER_qp < -1.0)
+      qq_OVER_qp = -1.0;
+
+    beta = asin(qq_OVER_qp);
+    betac = atan(tan(beta) / cos(dlam));
+
+    if ((fabs(betac) - PI_OVER_2) > 1.0e-8)
+      PHIc = betac;
+    else
+    {
+      sin2betac = TCEA_COEFF_TIMES_SIN(a0, 2.0, betac);
+      sin4betac = TCEA_COEFF_TIMES_SIN(a1, 4.0, betac);
+      sin6betac = TCEA_COEFF_TIMES_SIN(a2, 6.0, betac);
+      PHIc = TCEA_L(betac, sin2betac, sin4betac, sin6betac);
+    }
+
+    sinPHIc = sin(PHIc);
+    *Easting = Tcea_a * cos(beta) * cos(PHIc) * sin(dlam) /
+               (Tcea_Scale_Factor * cos(betac) * sqrt(1.0 - es2 *
+                                                      sinPHIc * sinPHIc)) + Tcea_False_Easting;
+
+    phi = c0 * PHIc;
+    sin2phi = TCEA_COEFF_TIMES_SIN(c1, 2.0, PHIc);
+    sin4phi = TCEA_COEFF_TIMES_SIN(c2, 4.0, PHIc);
+    sin6phi = TCEA_COEFF_TIMES_SIN(c3, 6.0, PHIc);
+    Mc = TCEA_M(phi, sin2phi, sin4phi, sin6phi);
+
+    *Northing = Tcea_Scale_Factor * (Mc - M0) + Tcea_False_Northing;
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Trans_Cyl_Eq_Area */
+
+
+long ossimTransCylEquAreaProjection::Convert_Trans_Cyl_Eq_Area_To_Geodetic(double Easting,
+                                                                           double Northing,
+                                                                           double *Latitude,
+                                                                           double *Longitude)const
+{ /* BEGIN Convert_Trans_Cyl_Eq_Area_To_Geodetic */
+/*
+ * The function Convert_Trans_Cyl_Eq_Area_To_Geodetic converts Transverse
+ * Cylindrical Equal Area projection (easting and northing) coordinates
+ * to geodetic (latitude and longitude) coordinates, according to the
+ * current ellipsoid and Transverse Cylindrical Equal Area projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise TCEA_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double x;
+  double dx;     /* Delta easting - Difference in easting (easting-FE)      */
+  double dy;     /* Delta northing - Difference in northing (northing-FN)   */
+  double Mc;
+  double MUc;
+  double sin2mu, sin4mu, sin6mu, sin8mu;
+  double PHIc;
+  double Qc;
+  double sin_lat;
+  double beta, betac, beta_prime;
+  double sin2beta, sin4beta, sin6beta;
+  double cosbetac;
+  double Qc_OVER_qp;
+  double temp;
+
+  long Error_Code = TCEA_NO_ERROR;
+
+//   if ((Easting < (Tcea_False_Easting + Tcea_Min_Easting))
+//       || (Easting > (Tcea_False_Easting + Tcea_Max_Easting)))
+//   { /* Easting out of range */
+//     Error_Code |= TCEA_EASTING_ERROR;
+//   }
+//   if ((Northing < (Tcea_False_Northing + Tcea_Min_Northing))
+//       || (Northing > (Tcea_False_Northing + Tcea_Max_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= TCEA_NORTHING_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    dy = Northing - Tcea_False_Northing;
+    dx = Easting - Tcea_False_Easting;
+    Mc = M0 + dy / Tcea_Scale_Factor;
+    MUc = Mc / (Tcea_a * c0);
+
+    sin2mu = TCEA_COEFF_TIMES_SIN(b0, 2.0, MUc);
+    sin4mu = TCEA_COEFF_TIMES_SIN(b1, 4.0, MUc);
+    sin6mu = TCEA_COEFF_TIMES_SIN(b2, 6.0, MUc);
+    sin8mu = TCEA_COEFF_TIMES_SIN(b3, 8.0, MUc);
+    PHIc = MUc + sin2mu + sin4mu + sin6mu + sin8mu;
+
+    sin_lat = sin(PHIc);
+    x = es * sin_lat;
+    Qc = TCEA_Q(sin_lat, x);
+    Qc_OVER_qp = Qc / qp;
+
+    if (Qc_OVER_qp < -1.0)
+      Qc_OVER_qp = -1.0;
+    else if (Qc_OVER_qp > 1.0)
+      Qc_OVER_qp = 1.0;
+
+    betac = asin(Qc_OVER_qp);
+    cosbetac = cos(betac);
+    temp = Tcea_Scale_Factor * dx * cosbetac * sqrt(1.0 -
+                                                    es2 * sin_lat * sin_lat) / (Tcea_a * cos(PHIc));
+    if (temp > 1.0)
+      temp = 1.0;
+    else if (temp < -1.0)
+      temp = -1.0;
+    beta_prime = -asin(temp);
+    beta = asin(cos(beta_prime) * sin(betac));
+
+    sin2beta = TCEA_COEFF_TIMES_SIN(a0, 2.0, beta);
+    sin4beta = TCEA_COEFF_TIMES_SIN(a1, 4.0, beta);
+    sin6beta = TCEA_COEFF_TIMES_SIN(a2, 6.0, beta);
+    *Latitude = TCEA_L(beta, sin2beta, sin4beta, sin6beta);
+
+    *Longitude = Tcea_Origin_Long - atan(tan(beta_prime) / cosbetac);
+
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+
+//     if (*Longitude > M_PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -M_PI)
+//       *Longitude += TWO_PI;
+
+//     if (*Longitude > M_PI) /* force distorted values to 180, -180 degrees */
+//       *Longitude = M_PI;
+//     else if (*Longitude < -M_PI)
+//       *Longitude = -M_PI;
+  }
+  return (Error_Code);
+} /* END OF Convert_Trans_Cyl_Eq_Area_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransCylEquAreaProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransCylEquAreaProjection.h
new file mode 100644
index 0000000000..3468a74ca2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransCylEquAreaProjection.h
@@ -0,0 +1,230 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Transverse Cylindrical Equal Area
+// projection code.  
+//*******************************************************************
+//  $Id: ossimTransCylEquAreaProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimTransCylEquAreaProjection_HEADER
+#define ossimTransCylEquAreaProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimTransCylEquAreaProjection : public ossimMapProjection
+{
+public:   
+   ossimTransCylEquAreaProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(6378137, 6356752.3142),
+                                  const ossimGpt& origin = ossimGpt());
+   ossimTransCylEquAreaProjection(const ossimEllipsoid& ellipsoid,
+                                  const ossimGpt& origin,
+                                  double falseEasting,
+                                  double falseNorthing,
+                                  double scaleFactor);
+   
+   ~ossimTransCylEquAreaProjection(){}
+
+   virtual ossimObject *dup()const{return new ossimTransCylEquAreaProjection(*this);}
+
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+   
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*
+    * Set's scale and then update.
+    */
+   void setScaleFactor(double scaleFactor);
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setParameters(double falseEasting,
+                      double falseNorthing,
+                      double scaleFactor);
+   
+   void setDefaults();
+
+   double getFalseEasting()const{return  Tcea_False_Easting;}
+   double getFalseNorthing()const{return Tcea_False_Northing;}
+   double getScaleFactor()const{return Tcea_Scale_Factor;}
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+private:
+   
+   mutable double Tcea_a;                /* Semi-major axis of ellipsoid in meters */
+   mutable double Tcea_f;        /* Flattening of ellipsoid */
+   mutable double es2;       /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;        /* es2 * es2 */
+   mutable double es6;        /* es4 * es2 */
+   mutable double es;             /* sqrt(es2) */
+   mutable double M0; 
+   mutable double qp;
+   mutable double One_MINUS_es2;   /* 1.0 - es2 */
+   mutable double One_OVER_2es;    /* 1.0 / (2.0 * es) */
+   mutable double a0;     /* es2 / 3.0 + 31.0 * es4 / 180.0 + 517.0 * es6 / 5040.0 */
+   mutable double a1;         /*  23.0 * es4 / 360.0 + 251.0 * es6 / 3780.0 */
+   mutable double a2;         /* 761.0 * es6 / 45360.0 */
+   mutable double b0;            /* 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0 */
+   mutable double b1;         /* 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0 */
+   mutable double b2;         /* 151.0 * e3 / 96.0 */
+   mutable double b3;         /* 1097.0 * e4 / 512.0 */
+   mutable double c0;/* 1.0 - es2 / 4.0 - 3.0 * es4 / 64.0 - 5.0 * es6 / 256.0 */
+   mutable double c1;/* 3.0 * es2 / 8.0 + 3.0 * es4 / 32.0 + 45.0 * es6 / 1024.0 */
+   mutable double c2;         /* 15.0 * es4 / 256.0 + 45.0 * es6 / 1024.0 */
+   mutable double c3;         /* 35.0 * es6 / 3072.0 */
+   
+/* Transverse Cylindrical Equal Area projection Parameters */
+   mutable double Tcea_Origin_Lat;             /* Latitude of origin in radians     */
+   mutable double Tcea_Origin_Long;            /* Longitude of origin in radians    */
+   mutable double Tcea_False_Northing;         /* False northing in meters          */
+   mutable double Tcea_False_Easting;          /* False easting in meters           */
+   mutable double Tcea_Scale_Factor;           /* Scale factor                      */
+   
+/* Maximum variance for easting and northing values for WGS 84.
+ */
+   mutable double Tcea_Min_Easting;
+   mutable double Tcea_Max_Easting;
+   mutable double Tcea_Min_Northing;
+   mutable double Tcea_Max_Northing;
+   
+/*
+ * The function Set_Trans_Cyl_Eq_Area_Parameters receives the ellipsoid parameters and
+ * Transverse Cylindrical Equal Area projcetion parameters as inputs, and sets the corresponding
+ * state variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise TCEA_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid                   (input)
+ *    Origin_Latitude   : Latitude in radians at which the          (input)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ *    Scale_Factor      : Multiplier which reduces distances in the 
+ *                          projection to the actual distance on the
+ *                          ellipsoid                               (input)
+ */
+  long Set_Trans_Cyl_Eq_Area_Parameters(double a,
+                                        double f,
+                                        double Origin_Latitude,
+                                        double Central_Meridian,
+                                        double False_Easting,
+                                        double False_Northing,
+                                        double Scale_Factor);
+
+
+/*!
+ * The function Get_Trans_Cyl_Eq_Area_Parameters returns the current ellipsoid
+ * parameters, Transverse Cylindrical Equal Area projection parameters, and scale factor.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid                   (output)
+ *    Origin_Latitude   : Latitude in radians at which the          (output)
+ *                          point scale factor is 1.0
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ *    Scale_Factor      : Multiplier which reduces distances in the
+ *                          projection to the actual distance on the
+ *                          ellipsoid                               (output)
+ */
+  void Get_Trans_Cyl_Eq_Area_Parameters(double *a,
+                                        double *f,
+                                        double *Origin_Latitude,
+                                        double *Central_Meridian,
+                                        double *False_Easting,
+                                        double *False_Northing,
+                                        double *Scale_Factor)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Trans_Cyl_Eq_Area converts geodetic (latitude and
+ * longitude) coordinates to Transverse Cylindrical Equal Area projection easting, and northing
+ * coordinates, according to the current ellipsoid and Transverse Cylindrical Equal Area projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise TCEA_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Trans_Cyl_Eq_Area (double Latitude,
+                                              double Longitude,
+                                              double *Easting,
+                                              double *Northing)const; 
+
+
+/*!
+ * The function Convert_Trans_Cyl_Eq_Area_To_Geodetic converts Transverse Cylindrical Equal Area 
+ * projection easting and northing coordinates to geodetic (latitude and longitude) coordinates.
+ * coordinates, according to the current ellipsoid and Transverse Cylindrical Equal Area projection
+ * If any errors occur, the error code(s) are returned by the function, otherwise TCEA_NO_ERROR 
+ * is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Trans_Cyl_Eq_Area_To_Geodetic(double Easting,
+                                             double Northing,
+                                             double *Latitude,
+                                             double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransMercatorProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransMercatorProjection.cpp
new file mode 100644
index 0000000000..f1b7348afe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransMercatorProjection.cpp
@@ -0,0 +1,743 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Transverse Mercator  projection code.  
+//*******************************************************************
+//  $Id: ossimTransMercatorProjection.cpp,v 1.16 2004/06/14 17:33:59 dburken Exp $
+#include <cmath>
+using namespace std;
+
+#include "ossimTransMercatorProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimTransMercatorProjection, "ossimTransMercatorProjection", ossimMapProjection)
+
+/******************************* DEFINES *********************************/
+
+#define TRANMERC_NO_ERROR           0x0000
+#define TRANMERC_LAT_ERROR          0x0001
+#define TRANMERC_LON_ERROR          0x0002
+#define TRANMERC_EASTING_ERROR      0x0004
+#define TRANMERC_NORTHING_ERROR     0x0008
+#define TRANMERC_ORIGIN_LAT_ERROR   0x0010
+#define TRANMERC_CENT_MER_ERROR     0x0020
+#define TRANMERC_A_ERROR            0x0040
+#define TRANMERC_B_ERROR            0x0080
+#define TRANMERC_A_LESS_B_ERROR     0x0100
+#define TRANMERC_SCALE_FACTOR_ERROR 0x0200
+#define TRANMERC_LON_WARNING        0x0400
+
+#define MAX_LAT         ((M_PI * 90.0)/180.0)    /* 90 degrees in radians */
+#define MAX_DELTA_LONG  ((M_PI * 90.0)/180.0)    /* 90 degrees in radians */
+#define MIN_SCALE_FACTOR  0.3
+#define MAX_SCALE_FACTOR  3.0
+
+#define SPHTMD(Latitude) ((double) (TranMerc_ap * Latitude \
+      - TranMerc_bp * sin(2.e0 * Latitude) + TranMerc_cp * sin(4.e0 * Latitude) \
+      - TranMerc_dp * sin(6.e0 * Latitude) + TranMerc_ep * sin(8.e0 * Latitude) ) )
+
+#define SPHSN(Latitude) ((double) (getA() / sqrt( 1.e0 - TranMerc_es * \
+      pow(sin(Latitude), 2))))
+
+#define SPHSR(Latitude) ((double) (getA() * (1.e0 - TranMerc_es) / \
+    pow(DENOM(Latitude), 3)))
+
+#define DENOM(Latitude) ((double) (sqrt(1.e0 - TranMerc_es * pow(sin(Latitude),2))))
+
+ossimTransMercatorProjection::ossimTransMercatorProjection(const ossimEllipsoid& ellipsoid,
+                                                           const ossimGpt& origin)
+   :
+      ossimMapProjection(ellipsoid, origin),
+      TranMerc_a(6378137.0),
+      TranMerc_f(1.0/298.257223563),
+      TranMerc_es(0.0066943799901413800),
+      TranMerc_ebs(0.0067394967565869),
+      TranMerc_Origin_Lat(origin.latr()),
+      TranMerc_Origin_Long(origin.lonr()),
+      TranMerc_False_Northing(0.0),
+      TranMerc_False_Easting(0.0),
+      TranMerc_Scale_Factor(1.0),
+      TranMerc_ap(6367449.1458008),
+      TranMerc_bp(16038.508696861),
+      TranMerc_cp(16.832613334334),
+      TranMerc_dp(0.021984404273757),
+      TranMerc_Delta_Easting(40000000.0),
+      TranMerc_Delta_Northing(40000000.0)
+{
+   update();
+}
+
+ossimTransMercatorProjection::ossimTransMercatorProjection(const ossimEllipsoid& ellipsoid,
+                                                           const ossimGpt& origin,
+                                                           double falseEasting,
+                                                           double falseNorthing,
+                                                           double scaleFactor)
+   :
+      ossimMapProjection(ellipsoid, origin),
+      TranMerc_a(6378137.0),
+      TranMerc_f(1.0/298.257223563),
+      TranMerc_es(0.0066943799901413800),
+      TranMerc_ebs(0.0067394967565869),
+      TranMerc_Origin_Lat(origin.latr()),
+      TranMerc_Origin_Long(origin.lonr()),
+      TranMerc_False_Northing(falseNorthing),
+      TranMerc_False_Easting(falseEasting),
+      TranMerc_Scale_Factor(scaleFactor),
+      TranMerc_ap(6367449.1458008),
+      TranMerc_bp(16038.508696861),
+      TranMerc_cp(16.832613334334),
+      TranMerc_dp(0.021984404273757),
+      TranMerc_Delta_Easting(40000000.0),
+      TranMerc_Delta_Northing(40000000.0)
+{
+   update();
+}
+
+void ossimTransMercatorProjection::update()
+{
+   Set_Transverse_Mercator_Parameters(theEllipsoid.getA(),
+                                      theEllipsoid.getFlattening(),
+                                      theOrigin.latr(),
+                                      theOrigin.lonr(),
+                                      TranMerc_False_Easting,
+                                      TranMerc_False_Northing,
+                                      TranMerc_Scale_Factor);
+
+   ossimMapProjection::update();
+}
+
+void ossimTransMercatorProjection::setFalseEasting(double falseEasting)
+{
+   TranMerc_False_Easting  = falseEasting;
+   
+   update();
+}
+
+
+void ossimTransMercatorProjection::setFalseNorthing(double falseNorthing)
+{
+   TranMerc_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimTransMercatorProjection::setFalseEastingNorthing(double falseEasting,
+                                                      double falseNorthing)
+{
+   TranMerc_False_Easting  = falseEasting;
+   TranMerc_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimTransMercatorProjection::setScaleFactor(double scaleFactor)
+{
+   TranMerc_Scale_Factor = scaleFactor;
+   
+   update();
+}
+
+void ossimTransMercatorProjection::setParameters(double falseEasting,
+                                                   double falseNorthing,
+                                                   double scaleFactor)
+{
+   TranMerc_False_Easting  = falseEasting;
+   TranMerc_False_Northing = falseNorthing;
+   TranMerc_Scale_Factor   = scaleFactor;
+   
+   update();
+}
+
+void ossimTransMercatorProjection::setDefaults()
+{
+   TranMerc_False_Easting  = 0.0;
+   TranMerc_False_Northing = 0.0;
+   TranMerc_Scale_Factor   = 1.0;
+   TranMerc_Delta_Easting  = 40000000.0;
+   TranMerc_Delta_Northing = 40000000.0;
+}
+
+ossimGpt ossimTransMercatorProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Transverse_Mercator_To_Geodetic(eastingNorthing.x,
+                                           eastingNorthing.y,
+                                           &lat,
+                                           &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);
+}
+
+ossimDpt ossimTransMercatorProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Transverse_Mercator(gpt.latr(),
+                                           gpt.lonr(),
+                                           &easting,
+                                           &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+bool ossimTransMercatorProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           TranMerc_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           TranMerc_False_Northing,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::SCALE_FACTOR_KW,
+           TranMerc_Scale_Factor,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+bool ossimTransMercatorProjection::loadState(const ossimKeywordlist& kwl,
+                                             const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   const char* scaleFactor   = kwl.find(prefix, ossimKeywordNames::SCALE_FACTOR_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimTransMercatorProjection))
+   {
+      if(falseEasting)
+      {
+         TranMerc_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         TranMerc_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+      if(scaleFactor)
+      {
+         double d = ossimString(scaleFactor).toDouble();
+         if (d > 0.0) // Check to avoid divide by zero.
+         {
+            TranMerc_Scale_Factor = d;
+         }
+      }
+   }
+   update();
+
+   return flag;
+}
+
+/************************************************************************/
+/*                              FUNCTIONS     
+ *
+ */
+
+
+long ossimTransMercatorProjection::Set_Transverse_Mercator_Parameters(double a,
+                                                                      double f,
+                                                                      double Origin_Latitude,
+                                                                      double Central_Meridian,
+                                                                      double False_Easting,
+                                                                      double False_Northing,
+                                                                      double Scale_Factor)
+
+{ /* BEGIN Set_Tranverse_Mercator_Parameters */
+  /*
+   * The function Set_Tranverse_Mercator_Parameters receives the ellipsoid
+   * parameters and Tranverse Mercator projection parameters as inputs, and
+   * sets the corresponding state variables. If any errors occur, the error
+   * code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+   * returned.
+   *
+   *    a                 : Semi-major axis of ellipsoid, in meters    (input)
+   *    f                 : Flattening of ellipsoid						         (input)
+   *    Origin_Latitude   : Latitude in radians at the origin of the   (input)
+   *                         projection
+   *    Central_Meridian  : Longitude in radians at the center of the  (input)
+   *                         projection
+   *    False_Easting     : Easting/X at the center of the projection  (input)
+   *    False_Northing    : Northing/Y at the center of the projection (input)
+   *    Scale_Factor      : Projection scale factor                    (input) 
+   */
+
+  double tn;        /* True Meridianal distance constant  */
+  double tn2;
+  double tn3;
+  double tn4;
+  double tn5;
+  double dummy_northing;
+  double TranMerc_b; /* Semi-minor axis of ellipsoid, in meters */
+//  double inv_f = 1 / f;
+  long Error_Code = TRANMERC_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= TRANMERC_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= TRANMERC_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -MAX_LAT) || (Origin_Latitude > MAX_LAT))
+//   { /* origin latitude out of range */
+//     Error_Code |= TRANMERC_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= TRANMERC_CENT_MER_ERROR;
+//   }
+//   if ((Scale_Factor < MIN_SCALE_FACTOR) || (Scale_Factor > MAX_SCALE_FACTOR))
+//   {
+//     Error_Code |= TRANMERC_SCALE_FACTOR_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    TranMerc_a = a;
+    TranMerc_f = f;
+    TranMerc_Origin_Lat = 0;
+    TranMerc_Origin_Long = 0;
+    TranMerc_False_Northing = 0;
+    TranMerc_False_Easting = 0; 
+    TranMerc_Scale_Factor = 1;
+
+    /* Eccentricity Squared */
+    TranMerc_es = 2 * TranMerc_f - TranMerc_f * TranMerc_f;
+    /* Second Eccentricity Squared */
+    TranMerc_ebs = (1 / (1 - TranMerc_es)) - 1;
+
+    TranMerc_b = TranMerc_a * (1 - TranMerc_f);    
+    /*True meridianal constants  */
+    tn = (TranMerc_a - TranMerc_b) / (TranMerc_a + TranMerc_b);
+    tn2 = tn * tn;
+    tn3 = tn2 * tn;
+    tn4 = tn3 * tn;
+    tn5 = tn4 * tn;
+
+    TranMerc_ap = TranMerc_a * (1.e0 - tn + 5.e0 * (tn2 - tn3)/4.e0
+                                + 81.e0 * (tn4 - tn5)/64.e0 );
+    TranMerc_bp = 3.e0 * TranMerc_a * (tn - tn2 + 7.e0 * (tn3 - tn4)
+                                       /8.e0 + 55.e0 * tn5/64.e0 )/2.e0;
+    TranMerc_cp = 15.e0 * TranMerc_a * (tn2 - tn3 + 3.e0 * (tn4 - tn5 )/4.e0) /16.0;
+    TranMerc_dp = 35.e0 * TranMerc_a * (tn3 - tn4 + 11.e0 * tn5 / 16.e0) / 48.e0;
+    TranMerc_ep = 315.e0 * TranMerc_a * (tn4 - tn5) / 512.e0;
+    Convert_Geodetic_To_Transverse_Mercator(MAX_LAT,
+                                            MAX_DELTA_LONG,
+                                            &TranMerc_Delta_Easting,
+                                            &TranMerc_Delta_Northing);
+    Convert_Geodetic_To_Transverse_Mercator(0,
+                                            MAX_DELTA_LONG,
+                                            &TranMerc_Delta_Easting,
+                                            &dummy_northing);
+    TranMerc_Origin_Lat = Origin_Latitude;
+    if (Central_Meridian > M_PI)
+      Central_Meridian -= TWO_PI;
+    TranMerc_Origin_Long = Central_Meridian;
+    TranMerc_False_Northing = False_Northing;
+    TranMerc_False_Easting = False_Easting; 
+    TranMerc_Scale_Factor = Scale_Factor;
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+}  /* END of Set_Transverse_Mercator_Parameters  */
+
+
+void ossimTransMercatorProjection::Get_Transverse_Mercator_Parameters(double *a,
+                                                                      double *f,
+                                                                      double *Origin_Latitude,
+                                                                      double *Central_Meridian,
+                                                                      double *False_Easting,
+                                                                      double *False_Northing,
+                                                                      double *Scale_Factor)const
+
+{ /* BEGIN Get_Tranverse_Mercator_Parameters  */
+  /*
+   * The function Get_Transverse_Mercator_Parameters returns the current
+   * ellipsoid and Transverse Mercator projection parameters.
+   *
+   *    a                 : Semi-major axis of ellipsoid, in meters    (output)
+   *    f                 : Flattening of ellipsoid						         (output)
+   *    Origin_Latitude   : Latitude in radians at the origin of the   (output)
+   *                         projection
+   *    Central_Meridian  : Longitude in radians at the center of the  (output)
+   *                         projection
+   *    False_Easting     : Easting/X at the center of the projection  (output)
+   *    False_Northing    : Northing/Y at the center of the projection (output)
+   *    Scale_Factor      : Projection scale factor                    (output) 
+   */
+
+  *a = TranMerc_a;
+  *f = TranMerc_f;
+  *Origin_Latitude = TranMerc_Origin_Lat;
+  *Central_Meridian = TranMerc_Origin_Long;
+  *False_Easting = TranMerc_False_Easting;
+  *False_Northing = TranMerc_False_Northing;
+  *Scale_Factor = TranMerc_Scale_Factor;
+  
+  return;
+} /* END OF Get_Tranverse_Mercator_Parameters */
+
+
+
+long ossimTransMercatorProjection::Convert_Geodetic_To_Transverse_Mercator (double Latitude,
+                                                                            double Longitude,
+                                                                            double *Easting,
+                                                                            double *Northing)const
+   
+{      /* BEGIN Convert_Geodetic_To_Transverse_Mercator */
+
+  /*
+   * The function Convert_Geodetic_To_Transverse_Mercator converts geodetic
+   * (latitude and longitude) coordinates to Transverse Mercator projection
+   * (easting and northing) coordinates, according to the current ellipsoid
+   * and Transverse Mercator projection coordinates.  If any errors occur, the
+   * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+   * returned.
+   *
+   *    Latitude      : Latitude in radians                         (input)
+   *    Longitude     : Longitude in radians                        (input)
+   *    Easting       : Easting/X in meters                         (output)
+   *    Northing      : Northing/Y in meters                        (output)
+   */
+
+  double c;       /* Cosine of latitude                          */
+  double c2;
+  double c3;
+  double c5;
+  double c7;
+  double dlam;    /* Delta longitude - Difference in Longitude       */
+  double eta;     /* constant - TranMerc_ebs *c *c                   */
+  double eta2;
+  double eta3;
+  double eta4;
+  double s;       /* Sine of latitude                        */
+  double sn;      /* Radius of curvature in the prime vertical       */
+  double t;       /* Tangent of latitude                             */
+  double tan2;
+  double tan3;
+  double tan4;
+  double tan5;
+  double tan6;
+  double t1;      /* Term in coordinate conversion formula - GP to Y */
+  double t2;      /* Term in coordinate conversion formula - GP to Y */
+  double t3;      /* Term in coordinate conversion formula - GP to Y */
+  double t4;      /* Term in coordinate conversion formula - GP to Y */
+  double t5;      /* Term in coordinate conversion formula - GP to Y */
+  double t6;      /* Term in coordinate conversion formula - GP to Y */
+  double t7;      /* Term in coordinate conversion formula - GP to Y */
+  double t8;      /* Term in coordinate conversion formula - GP to Y */
+  double t9;      /* Term in coordinate conversion formula - GP to Y */
+  double tmd;     /* True Meridional distance                        */
+  double tmdo;    /* True Meridional distance for latitude of origin */
+  long    Error_Code = TRANMERC_NO_ERROR;
+//  double temp_Origin;
+//  double temp_Long;
+
+//   if ((Latitude < -MAX_LAT) || (Latitude > MAX_LAT))
+//   {  /* Latitude out of range */
+//     Error_Code|= TRANMERC_LAT_ERROR;
+//   }
+   if (Longitude > M_PI)
+     Longitude -= TWO_PI;
+//   if ((Longitude < (TranMerc_Origin_Long - MAX_DELTA_LONG))
+//       || (Longitude > (TranMerc_Origin_Long + MAX_DELTA_LONG)))
+//   {
+//     if (Longitude < 0)
+//       temp_Long = Longitude + TWO_PI;
+//     else
+//       temp_Long = Longitude;
+//     if (TranMerc_Origin_Long < 0)
+//       temp_Origin = TranMerc_Origin_Long + TWO_PI;
+//     else
+//       temp_Origin = TranMerc_Origin_Long;
+//     if ((temp_Long < (temp_Origin - MAX_DELTA_LONG))
+//         || (temp_Long > (temp_Origin + MAX_DELTA_LONG)))
+//       Error_Code|= TRANMERC_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+
+    /* 
+     *  Delta Longitude
+     */
+    dlam = Longitude - TranMerc_Origin_Long;
+
+//     if (fabs(dlam) > (9.0 * M_PI / 180))
+//     { /* Distortion will result if Longitude is more than 9 degrees from the Central Meridian */
+//       Error_Code |= TRANMERC_LON_WARNING;
+//     }
+
+     if (dlam > M_PI)
+       dlam -= TWO_PI;
+     if (dlam < -M_PI)
+       dlam += TWO_PI;
+     if (fabs(dlam) < 2.e-10)
+       dlam = 0.0;
+
+    s = sin(Latitude);
+    c = cos(Latitude);
+    c2 = c * c;
+    c3 = c2 * c;
+    c5 = c3 * c2;
+    c7 = c5 * c2;
+    t = tan (Latitude);
+    tan2 = t * t;
+    tan3 = tan2 * t;
+    tan4 = tan3 * t;
+    tan5 = tan4 * t;
+    tan6 = tan5 * t;
+    eta = TranMerc_ebs * c2;
+    eta2 = eta * eta;
+    eta3 = eta2 * eta;
+    eta4 = eta3 * eta;
+
+    /* radius of curvature in prime vertical */
+    sn = SPHSN(Latitude);
+
+    /* True Meridianal Distances */
+    tmd = SPHTMD(Latitude);
+
+    /*  Origin  */
+    tmdo = SPHTMD (TranMerc_Origin_Lat);
+
+    /* northing */
+    t1 = (tmd - tmdo) * TranMerc_Scale_Factor;
+    t2 = sn * s * c * TranMerc_Scale_Factor/ 2.e0;
+    t3 = sn * s * c3 * TranMerc_Scale_Factor * (5.e0 - tan2 + 9.e0 * eta 
+                                                + 4.e0 * eta2) /24.e0; 
+
+    t4 = sn * s * c5 * TranMerc_Scale_Factor * (61.e0 - 58.e0 * tan2
+                                                + tan4 + 270.e0 * eta - 330.e0 * tan2 * eta + 445.e0 * eta2
+                                                + 324.e0 * eta3 -680.e0 * tan2 * eta2 + 88.e0 * eta4 
+                                                -600.e0 * tan2 * eta3 - 192.e0 * tan2 * eta4) / 720.e0;
+
+    t5 = sn * s * c7 * TranMerc_Scale_Factor * (1385.e0 - 3111.e0 * 
+                                                tan2 + 543.e0 * tan4 - tan6) / 40320.e0;
+
+    *Northing = TranMerc_False_Northing + t1 + pow(dlam,2.e0) * t2
+                + pow(dlam,4.e0) * t3 + pow(dlam,6.e0) * t4
+                + pow(dlam,8.e0) * t5; 
+
+    /* Easting */
+    t6 = sn * c * TranMerc_Scale_Factor;
+    t7 = sn * c3 * TranMerc_Scale_Factor * (1.e0 - tan2 + eta ) /6.e0;
+    t8 = sn * c5 * TranMerc_Scale_Factor * (5.e0 - 18.e0 * tan2 + tan4
+                                            + 14.e0 * eta - 58.e0 * tan2 * eta + 13.e0 * eta2 + 4.e0 * eta3 
+                                            - 64.e0 * tan2 * eta2 - 24.e0 * tan2 * eta3 )/ 120.e0;
+    t9 = sn * c7 * TranMerc_Scale_Factor * ( 61.e0 - 479.e0 * tan2
+                                             + 179.e0 * tan4 - tan6 ) /5040.e0;
+
+    *Easting = TranMerc_False_Easting + dlam * t6 + pow(dlam,3.e0) * t7 
+               + pow(dlam,5.e0) * t8 + pow(dlam,7.e0) * t9;
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Transverse_Mercator */
+
+
+long ossimTransMercatorProjection::Convert_Transverse_Mercator_To_Geodetic (double Easting,
+                                                                            double Northing,
+                                                                            double *Latitude,
+                                                                            double *Longitude)const
+{      /* BEGIN Convert_Transverse_Mercator_To_Geodetic */
+
+  /*
+   * The function Convert_Transverse_Mercator_To_Geodetic converts Transverse
+   * Mercator projection (easting and northing) coordinates to geodetic
+   * (latitude and longitude) coordinates, according to the current ellipsoid
+   * and Transverse Mercator projection parameters.  If any errors occur, the
+   * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+   * returned.
+   *
+   *    Easting       : Easting/X in meters                         (input)
+   *    Northing      : Northing/Y in meters                        (input)
+   *    Latitude      : Latitude in radians                         (output)
+   *    Longitude     : Longitude in radians                        (output)
+   */
+
+  double c;       /* Cosine of latitude                          */
+  double de;      /* Delta easting - Difference in Easting (Easting-Fe)    */
+  double dlam;    /* Delta longitude - Difference in Longitude       */
+  double eta;     /* constant - TranMerc_ebs *c *c                   */
+  double eta2;
+  double eta3;
+  double eta4;
+  double ftphi;   /* Footpoint latitude                              */
+  int    i;       /* Loop iterator                   */
+  double s;       /* Sine of latitude                        */
+  double sn;      /* Radius of curvature in the prime vertical       */
+  double sr;      /* Radius of curvature in the meridian             */
+  double t;       /* Tangent of latitude                             */
+  double tan2;
+  double tan4;
+  double t10;     /* Term in coordinate conversion formula - GP to Y */
+  double t11;     /* Term in coordinate conversion formula - GP to Y */
+  double t12;     /* Term in coordinate conversion formula - GP to Y */
+  double t13;     /* Term in coordinate conversion formula - GP to Y */
+  double t14;     /* Term in coordinate conversion formula - GP to Y */
+  double t15;     /* Term in coordinate conversion formula - GP to Y */
+  double t16;     /* Term in coordinate conversion formula - GP to Y */
+  double t17;     /* Term in coordinate conversion formula - GP to Y */
+  double tmd;     /* True Meridional distance                        */
+  double tmdo;    /* True Meridional distance for latitude of origin */
+  long Error_Code = TRANMERC_NO_ERROR;
+
+//   if ((Easting < (TranMerc_False_Easting - TranMerc_Delta_Easting))
+//       ||(Easting > (TranMerc_False_Easting + TranMerc_Delta_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= TRANMERC_EASTING_ERROR;
+//   }
+//   if ((Northing < (TranMerc_False_Northing - TranMerc_Delta_Northing))
+//       || (Northing > (TranMerc_False_Northing + TranMerc_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= TRANMERC_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  {
+    /* True Meridional Distances for latitude of origin */
+    tmdo = SPHTMD(TranMerc_Origin_Lat);
+
+    /*  Origin  */
+    tmd = tmdo +  (Northing - TranMerc_False_Northing) / TranMerc_Scale_Factor; 
+
+    /* First Estimate */
+    sr = SPHSR(0.e0);
+    ftphi = tmd/sr;
+
+    for (i = 0; i < 5 ; i++)
+    {
+      t10 = SPHTMD (ftphi);
+      sr = SPHSR(ftphi);
+      ftphi = ftphi + (tmd - t10) / sr;
+    }
+
+    /* Radius of Curvature in the meridian */
+    sr = SPHSR(ftphi);
+
+    /* Radius of Curvature in the meridian */
+    sn = SPHSN(ftphi);
+
+    /* Sine Cosine terms */
+    s = sin(ftphi);
+    c = cos(ftphi);
+
+    /* Tangent Value  */
+    t = tan(ftphi);
+    tan2 = t * t;
+    tan4 = tan2 * tan2;
+    eta = TranMerc_ebs * pow(c,2);
+    eta2 = eta * eta;
+    eta3 = eta2 * eta;
+    eta4 = eta3 * eta;
+    de = Easting - TranMerc_False_Easting;
+    if (fabs(de) < 0.0001)
+      de = 0.0;
+
+    /* Latitude */
+    t10 = t / (2.e0 * sr * sn * pow(TranMerc_Scale_Factor, 2));
+    t11 = t * (5.e0  + 3.e0 * tan2 + eta - 4.e0 * pow(eta,2)
+               - 9.e0 * tan2 * eta) / (24.e0 * sr * pow(sn,3) 
+                                       * pow(TranMerc_Scale_Factor,4));
+    t12 = t * (61.e0 + 90.e0 * tan2 + 46.e0 * eta + 45.E0 * tan4
+               - 252.e0 * tan2 * eta  - 3.e0 * eta2 + 100.e0 
+               * eta3 - 66.e0 * tan2 * eta2 - 90.e0 * tan4
+               * eta + 88.e0 * eta4 + 225.e0 * tan4 * eta2
+               + 84.e0 * tan2* eta3 - 192.e0 * tan2 * eta4)
+          / ( 720.e0 * sr * pow(sn,5) * pow(TranMerc_Scale_Factor, 6) );
+    t13 = t * ( 1385.e0 + 3633.e0 * tan2 + 4095.e0 * tan4 + 1575.e0 
+                * pow(t,6))/ (40320.e0 * sr * pow(sn,7) * pow(TranMerc_Scale_Factor,8));
+    *Latitude = ftphi - pow(de,2) * t10 + pow(de,4) * t11 - pow(de,6) * t12 
+                + pow(de,8) * t13;
+
+    t14 = 1.e0 / (sn * c * TranMerc_Scale_Factor);
+
+    t15 = (1.e0 + 2.e0 * tan2 + eta) / (6.e0 * pow(sn,3) * c * 
+                                        pow(TranMerc_Scale_Factor,3));
+
+    t16 = (5.e0 + 6.e0 * eta + 28.e0 * tan2 - 3.e0 * eta2
+           + 8.e0 * tan2 * eta + 24.e0 * tan4 - 4.e0 
+           * eta3 + 4.e0 * tan2 * eta2 + 24.e0 
+           * tan2 * eta3) / (120.e0 * pow(sn,5) * c  
+                             * pow(TranMerc_Scale_Factor,5));
+
+    t17 = (61.e0 +  662.e0 * tan2 + 1320.e0 * tan4 + 720.e0 
+           * pow(t,6)) / (5040.e0 * pow(sn,7) * c 
+                          * pow(TranMerc_Scale_Factor,7));
+
+    /* Difference in Longitude */
+    dlam = de * t14 - pow(de,3) * t15 + pow(de,5) * t16 - pow(de,7) * t17;
+
+    /* Longitude */
+    (*Longitude) = TranMerc_Origin_Long + dlam;
+    while (*Latitude > (90.0 * RAD_PER_DEG))
+    {
+      *Latitude = M_PI - *Latitude;
+      *Longitude += M_PI;
+      if (*Longitude > M_PI)
+        *Longitude -= TWO_PI;
+    }
+
+     while (*Latitude < (-90.0 * RAD_PER_DEG))
+     {
+       *Latitude = - (*Latitude + M_PI);
+       *Longitude += M_PI;
+       if (*Longitude > M_PI)
+         *Longitude -= TWO_PI;
+     }
+     if (*Longitude > TWO_PI)
+       *Longitude -= TWO_PI;
+     if (*Longitude < -M_PI)
+       *Longitude += TWO_PI;
+
+//     if (fabs(dlam) > (9.0 * M_PI / 180))
+//     { /* Distortion will result if Longitude is more than 9 degrees from the Central Meridian */
+//       Error_Code |= TRANMERC_LON_WARNING;
+//     }
+  }
+  return (Error_Code);
+} /* END OF Convert_Transverse_Mercator_To_Geodetic */
+
+std::ostream& ossimTransMercatorProjection::print(std::ostream& out) const
+{
+   out << setiosflags(ios::fixed) << setprecision(15)
+       << "// ossimTransMercatorProjection::print\n"
+       << ossimKeywordNames::SCALE_FACTOR_KW << ":  " << TranMerc_Scale_Factor
+       << endl;
+   return ossimMapProjection::print(out);
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransMercatorProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransMercatorProjection.h
new file mode 100644
index 0000000000..d48a60ad80
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimTransMercatorProjection.h
@@ -0,0 +1,220 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Geotrans Transverse Mercator  projection code.  
+//*******************************************************************
+//  $Id: ossimTransMercatorProjection.h,v 1.8 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimTransMercatorProjection_HEADER
+#define ossimTransMercatorProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimTransMercatorProjection : public ossimMapProjection
+{
+public:
+   ossimTransMercatorProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(6378137, 6356752.3142),
+                                const ossimGpt& origin = ossimGpt());
+   ossimTransMercatorProjection(const ossimEllipsoid& ellipsoid,
+                                const ossimGpt& origin,
+                                double falseEasting,
+                                double falseNorthing,
+                                double scaleFactor);
+   ~ossimTransMercatorProjection(){}
+
+   virtual ossimObject *dup()const{return new ossimTransMercatorProjection(*this);}
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+   
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*
+    * Set's scale and then update.
+    */
+   void setScaleFactor(double scaleFactor);
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setParameters(double falseEasting,
+                      double falseNorthing,
+                      double scaleFactor);
+   
+   void setDefaults();
+
+   double getFalseEasting()const{return  TranMerc_False_Easting;}
+   double getFalseNorthing()const{return TranMerc_False_Northing;}
+   double getScaleFactor()const{return TranMerc_Scale_Factor;}
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /*!
+    * Prints data members to stream.  Returns stream&.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+   
+protected:
+
+   //_____________GEOTRANS_______________
+   
+   double TranMerc_a;              /* Semi-major axis of ellipsoid i meters */
+   double TranMerc_f;      /* Flattening of ellipsoid  */
+   double TranMerc_es; /* Eccentricity (0.08181919084262188000) squared */
+   double TranMerc_ebs;   /* Second Eccentricity squared */
+   
+/* Transverse_Mercator projection Parameters */
+   double TranMerc_Origin_Lat;           /* Latitude of origin in radians */
+   double TranMerc_Origin_Long;          /* Longitude of origin in radians */
+   double TranMerc_False_Northing;       /* False northing in meters */
+   double TranMerc_False_Easting;        /* False easting in meters */
+   double TranMerc_Scale_Factor;         /* Scale factor  */
+   
+/* Isometeric to geodetic latitude parameters, default to WGS 84 */
+   double TranMerc_ap;
+   double TranMerc_bp;
+   double TranMerc_cp;
+   double TranMerc_dp;
+   double TranMerc_ep;
+   
+/* Maximum variance for easting and northing values for WGS 84. */
+   double TranMerc_Delta_Easting;
+   double TranMerc_Delta_Northing;
+   
+/*!
+ * The function Set_Tranverse_Mercator_Parameters receives the ellipsoid
+ * parameters and Tranverse Mercator projection parameters as inputs, and
+ * sets the corresponding state variables. If any errors occur, the error
+ * code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+ * returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters    (input)
+ *    f                 : Flattening of ellipsoid                    (input)
+ *    Origin_Latitude   : Latitude in radians at the origin of the   (input)
+ *                         projection
+ *    Central_Meridian  : Longitude in radians at the center of the  (input)
+ *                         projection
+ *    False_Easting     : Easting/X at the center of the projection  (input)
+ *    False_Northing    : Northing/Y at the center of the projection (input)
+ *    Scale_Factor      : Projection scale factor                    (input) 
+ */
+  long Set_Transverse_Mercator_Parameters(double a,      
+                                          double f,
+                                          double Origin_Latitude,
+                                          double Central_Meridian,
+                                          double False_Easting,
+                                          double False_Northing,
+                                          double Scale_Factor);
+
+
+/*!
+ * The function Get_Transverse_Mercator_Parameters returns the current
+ * ellipsoid and Transverse Mercator projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters    (output)
+ *    f                 : Flattening of ellipsoid                    (output)
+ *    Origin_Latitude   : Latitude in radians at the origin of the   (output)
+ *                         projection
+ *    Central_Meridian  : Longitude in radians at the center of the  (output)
+ *                         projection
+ *    False_Easting     : Easting/X at the center of the projection  (output)
+ *    False_Northing    : Northing/Y at the center of the projection (output)
+ *    Scale_Factor      : Projection scale factor                    (output) 
+ */
+  void Get_Transverse_Mercator_Parameters(double *a,
+                                          double *f,
+                                          double *Origin_Latitude,
+                                          double *Central_Meridian,
+                                          double *False_Easting,
+                                          double *False_Northing,
+                                          double *Scale_Factor)const;
+
+
+/*!
+ * The function Convert_Geodetic_To_Transverse_Mercator converts geodetic
+ * (latitude and longitude) coordinates to Transverse Mercator projection
+ * (easting and northing) coordinates, according to the current ellipsoid
+ * and Transverse Mercator projection coordinates.  If any errors occur, the
+ * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+ * returned.
+ *
+ *    Latitude      : Latitude in radians                         (input)
+ *    Longitude     : Longitude in radians                        (input)
+ *    Easting       : Easting/X in meters                         (output)
+ *    Northing      : Northing/Y in meters                        (output)
+ */
+  long Convert_Geodetic_To_Transverse_Mercator (double Latitude,
+                                                double Longitude,
+                                                double *Easting,
+                                                double *Northing)const;
+
+
+
+/*!
+ * The function Convert_Transverse_Mercator_To_Geodetic converts Transverse
+ * Mercator projection (easting and northing) coordinates to geodetic
+ * (latitude and longitude) coordinates, according to the current ellipsoid
+ * and Transverse Mercator projection parameters.  If any errors occur, the
+ * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+ * returned.
+ *
+ *    Easting       : Easting/X in meters                         (input)
+ *    Northing      : Northing/Y in meters                        (input)
+ *    Latitude      : Latitude in radians                         (output)
+ *    Longitude     : Longitude in radians                        (output)
+ */
+  long Convert_Transverse_Mercator_To_Geodetic (double Easting,
+                                                double Northing,
+                                                double *Latitude,
+                                                double *Longitude)const;
+
+
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUps.c b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUps.c
new file mode 100644
index 0000000000..717801fb6d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUps.c
@@ -0,0 +1,310 @@
+/********************************************************************/
+/* RSC IDENTIFIER: UPS
+ *
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between geodetic (latitude
+ *    and longitude) coordinates and Universal Polar Stereographic (UPS)
+ *    projection (hemisphere, easting, and northing) coordinates.
+ *
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an 
+ *    invalid value is found the error code is combined with the 
+ *    current error code using the bitwise or.  This combining allows  
+ *    multiple error codes to be returned. The possible error codes 
+ *    are:
+ *
+ *         UPS_NO_ERROR           : No errors occurred in function
+ *         UPS_LAT_ERROR          : Latitude outside of valid range
+ *                                   (North Pole: 83.5 to 90,
+ *                                    South Pole: -79.5 to -90)
+ *         UPS_LON_ERROR          : Longitude outside of valid range
+ *                                   (-180 to 360 degrees)
+ *         UPS_HEMISPHERE_ERROR   : Invalid hemisphere ('N' or 'S')
+ *         UPS_EASTING_ERROR      : Easting outside of valid range,
+ *                                   (0 to 4,000,000m)
+ *         UPS_NORTHING_ERROR     : Northing outside of valid range,
+ *                                   (0 to 4,000,000m)
+ *         UPS_A_ERROR            : Semi-major axis less than or equal to zero
+ *         UPS_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	               (250 to 350)
+ *
+ *
+ * REUSE NOTES
+ *
+ *    UPS is intended for reuse by any application that performs a Universal
+ *    Polar Stereographic (UPS) projection.
+ *
+ *
+ * REFERENCES
+ *
+ *    Further information on UPS can be found in the Reuse Manual.
+ *
+ *    UPS originated from :  U.S. Army Topographic Engineering Center
+ *                           Geospatial Information Division
+ *                           7701 Telegraph Road
+ *                           Alexandria, VA  22310-3864
+ *
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ *
+ * RESTRICTIONS
+ *
+ *    UPS has no restrictions.
+ *
+ *
+ * ENVIRONMENT
+ *
+ *    UPS was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC version 2.8.1
+ *    2. Windows 95 with MS Visual C++ version 6
+ *
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    06-11-95          Original Code
+ *    03-01-97          Original Code
+ *
+ *
+ */
+
+
+/************************************************************************/
+/*
+ *                               INCLUDES
+ */
+
+#include <math.h>
+#include "ossimPolarst.h"
+#include "ossimUps.h"
+/*
+ *    math.h     - Is needed to call the math functions.
+ *    polar.h    - Is used to convert polar stereographic coordinates
+ *    ups.h      - Defines the function prototypes for the ups module.
+ */
+
+
+/************************************************************************/
+/*                               GLOBAL DECLARATIONS
+ *
+ */
+
+#define PI       3.14159265358979323e0  /* PI     */
+#define PI_OVER    (PI/2.0e0)           /* PI over 2 */
+#define MAX_LAT    ((PI * 90)/180.0)    /* 90 degrees in radians */
+#define MAX_ORIGIN_LAT ((81.114528 * PI) / 180.0)
+#define MIN_NORTH_LAT (83.5*PI/180.0)
+#define MIN_SOUTH_LAT (-79.5*PI/180.0)
+#define MIN_EAST_NORTH 0
+#define MAX_EAST_NORTH 4000000
+
+/* Ellipsoid Parameters, default to WGS 84  */
+static double UPS_a = 6378137.0;          /* Semi-major axis of ellipsoid in meters   */
+static double UPS_f = 1 / 298.257223563;  /* Flattening of ellipsoid  */
+const double UPS_False_Easting = 2000000;
+const double UPS_False_Northing = 2000000;
+static double UPS_Origin_Latitude = MAX_ORIGIN_LAT;  /*set default = North Hemisphere */
+static double UPS_Origin_Longitude = 0.0;
+static double false_easting = 0.0;
+static double false_northing = 0.0;
+static double UPS_Easting = 0.0;
+static double UPS_Northing = 0.0;
+
+
+/************************************************************************/
+/*                              FUNCTIONS
+ *
+ */
+
+
+long Set_UPS_Parameters( double a,
+                         double f)
+{
+/*
+ * The function SET_UPS_PARAMETERS receives the ellipsoid parameters and sets
+ * the corresponding state variables. If any errors occur, the error code(s)
+ * are returned by the function, otherwise UPS_NO_ERROR is returned.
+ *
+ *   a     : Semi-major axis of ellipsoid in meters (input)
+ *   f     : Flattening of ellipsoid					      (input)
+ */
+
+  double inv_f = 1 / f;
+  long Error_Code = UPS_NO_ERROR;
+
+  if (a <= 0.0)
+  { /* Semi-major axis must be greater than zero */
+    Error_Code |= UPS_A_ERROR;
+  }
+  if ((inv_f < 250) || (inv_f > 350))
+  { /* Inverse flattening must be between 250 and 350 */
+    Error_Code |= UPS_INV_F_ERROR;
+  }
+
+  if (!Error_Code)
+  { /* no errors */
+    UPS_a = a;
+    UPS_f = f;
+  }
+  return (Error_Code);
+}  /* END of Set_UPS_Parameters  */
+
+
+void Get_UPS_Parameters( double *a,
+                         double *f)
+{
+/*
+ * The function Get_UPS_Parameters returns the current ellipsoid parameters.
+ *
+ *  a      : Semi-major axis of ellipsoid, in meters (output)
+ *  f      : Flattening of ellipsoid					       (output)
+ */
+
+  *a = UPS_a;
+  *f = UPS_f;
+  return;
+} /* END OF Get_UPS_Parameters */
+
+
+long Convert_Geodetic_To_UPS ( double Latitude,
+                               double Longitude,
+                               char   *Hemisphere,
+                               double *Easting,
+                               double *Northing)
+{
+/*
+ *  The function Convert_Geodetic_To_UPS converts geodetic (latitude and
+ *  longitude) coordinates to UPS (hemisphere, easting, and northing)
+ *  coordinates, according to the current ellipsoid parameters. If any 
+ *  errors occur, the error code(s) are returned by the function, 
+ *  otherwide UPS_NO_ERROR is returned.
+ *
+ *    Latitude      : Latitude in radians                       (input)
+ *    Longitude     : Longitude in radians                      (input)
+ *    Hemisphere    : Hemisphere either 'N' or 'S'              (output)
+ *    Easting       : Easting/X in meters                       (output)
+ *    Northing      : Northing/Y in meters                      (output)
+ */
+
+  double tempEasting, tempNorthing;
+  long Error_Code = UPS_NO_ERROR;
+
+  if ((Latitude < -MAX_LAT) || (Latitude > MAX_LAT))
+  {   /* latitude out of range */
+    Error_Code |= UPS_LAT_ERROR;
+  }
+  if ((Latitude < 0) && (Latitude > MIN_SOUTH_LAT))
+    Error_Code |= UPS_LAT_ERROR;
+  if ((Latitude >= 0) && (Latitude < MIN_NORTH_LAT))
+    Error_Code |= UPS_LAT_ERROR;
+  if ((Longitude < -PI) || (Longitude > (2 * PI)))
+  {  /* slam out of range */
+    Error_Code |= UPS_LON_ERROR;
+  }
+
+  if (!Error_Code)
+  {  /* no errors */
+    if (Latitude < 0)
+    {
+      UPS_Origin_Latitude = -MAX_ORIGIN_LAT; 
+      *Hemisphere = 'S';
+    }
+    else
+    {
+      UPS_Origin_Latitude = MAX_ORIGIN_LAT; 
+      *Hemisphere = 'N';
+    }
+
+
+    Set_Polar_Stereographic_Parameters( UPS_a,
+                                        UPS_f,
+                                        UPS_Origin_Latitude,
+                                        UPS_Origin_Longitude,
+                                        false_easting,
+                                        false_northing);
+
+    Convert_Geodetic_To_Polar_Stereographic(Latitude,
+                                            Longitude,
+                                            &tempEasting,
+                                            &tempNorthing);
+
+    UPS_Easting = UPS_False_Easting + tempEasting;
+    UPS_Northing = UPS_False_Northing + tempNorthing;
+
+
+    *Easting = UPS_Easting;
+    *Northing = UPS_Northing;
+  }  /*  END of if(!Error_Code)   */
+
+  return (Error_Code);
+}  /* END OF Convert_Geodetic_To_UPS  */
+
+
+long Convert_UPS_To_Geodetic(char   Hemisphere,
+                             double Easting,
+                             double Northing,
+                             double *Latitude,
+                             double *Longitude)
+{
+/*
+ *  The function Convert_UPS_To_Geodetic converts UPS (hemisphere, easting, 
+ *  and northing) coordinates to geodetic (latitude and longitude) coordinates
+ *  according to the current ellipsoid parameters.  If any errors occur, the 
+ *  error code(s) are returned by the function, otherwise UPS_NO_ERROR is 
+ *  returned.
+ *
+ *    Hemisphere    : Hemisphere either 'N' or 'S'              (input)
+ *    Easting       : Easting/X in meters                       (input)
+ *    Northing      : Northing/Y in meters                      (input)
+ *    Latitude      : Latitude in radians                       (output)
+ *    Longitude     : Longitude in radians                      (output)
+ */
+
+  long Error_Code = UPS_NO_ERROR;
+
+  if ((Hemisphere != 'N') && (Hemisphere != 'S'))
+    Error_Code |= UPS_HEMISPHERE_ERROR;
+  if ((Easting < MIN_EAST_NORTH) || (Easting > MAX_EAST_NORTH))
+    Error_Code |= UPS_EASTING_ERROR;
+  if ((Northing < MIN_EAST_NORTH) || (Northing > MAX_EAST_NORTH))
+    Error_Code |= UPS_NORTHING_ERROR;
+
+  if (Hemisphere =='N')
+  {UPS_Origin_Latitude = MAX_ORIGIN_LAT;}
+  if (Hemisphere =='S')
+  {UPS_Origin_Latitude = -MAX_ORIGIN_LAT;}
+
+  if (!Error_Code)
+  {   /*  no errors   */
+    Set_Polar_Stereographic_Parameters( UPS_a,
+                                        UPS_f,
+                                        UPS_Origin_Latitude,
+                                        UPS_Origin_Longitude,
+                                        UPS_False_Easting,
+                                        UPS_False_Northing);
+
+
+
+    Convert_Polar_Stereographic_To_Geodetic( Easting,
+                                             Northing,
+                                             Latitude,
+                                             Longitude); 
+
+
+    if ((*Latitude < 0) && (*Latitude > MIN_SOUTH_LAT))
+      Error_Code |= UPS_LAT_ERROR;
+    if ((*Latitude >= 0) && (*Latitude < MIN_NORTH_LAT))
+      Error_Code |= UPS_LAT_ERROR;
+  }  /*  END OF if(!Error_Code) */
+  return (Error_Code);
+}  /*  END OF Convert_UPS_To_Geodetic  */ 
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUps.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUps.h
new file mode 100644
index 0000000000..9f6c81722f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUps.h
@@ -0,0 +1,175 @@
+#ifndef UPS_H
+  #define UPS_H
+/********************************************************************/
+/* RSC IDENTIFIER: UPS
+ *
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between geodetic (latitude
+ *    and longitude) coordinates and Universal Polar Stereographic (UPS)
+ *    projection (hemisphere, easting, and northing) coordinates.
+ *
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an 
+ *    invalid value is found the error code is combined with the 
+ *    current error code using the bitwise or.  This combining allows  
+ *    multiple error codes to be returned. The possible error codes 
+ *    are:
+ *
+ *         UPS_NO_ERROR           : No errors occurred in function
+ *         UPS_LAT_ERROR          : Latitude outside of valid range
+ *                                   (North Pole: 83.5 to 90,
+ *                                    South Pole: -79.5 to -90)
+ *         UPS_LON_ERROR          : Longitude outside of valid range
+ *                                   (-180 to 360 degrees)
+ *         UPS_HEMISPHERE_ERROR   : Invalid hemisphere ('N' or 'S')
+ *         UPS_EASTING_ERROR      : Easting outside of valid range,
+ *                                   (0 to 4,000,000m)
+ *         UPS_NORTHING_ERROR     : Northing outside of valid range,
+ *                                   (0 to 4,000,000m)
+ *         UPS_A_ERROR            : Semi-major axis less than or equal to zero
+ *         UPS_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	               (250 to 350)
+ *
+ *
+ * REUSE NOTES
+ *
+ *    UPS is intended for reuse by any application that performs a Universal
+ *    Polar Stereographic (UPS) projection.
+ *
+ *
+ * REFERENCES
+ *
+ *    Further information on UPS can be found in the Reuse Manual.
+ *
+ *    UPS originated from :  U.S. Army Topographic Engineering Center
+ *                           Geospatial Information Division
+ *                           7701 Telegraph Road
+ *                           Alexandria, VA  22310-3864
+ *
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ *
+ * RESTRICTIONS
+ *
+ *    UPS has no restrictions.
+ *
+ *
+ * ENVIRONMENT
+ *
+ *    UPS was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC version 2.8.1
+ *    2. Windows 95 with MS Visual C++ version 6
+ *
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    06-11-95          Original Code
+ *    03-01-97          Original Code
+ *
+ *
+ */
+
+
+/**********************************************************************/
+/*
+ *                        DEFINES
+ */
+
+  #define UPS_NO_ERROR                0x0000
+  #define UPS_LAT_ERROR               0x0001
+  #define UPS_LON_ERROR               0x0002
+  #define UPS_HEMISPHERE_ERROR        0x0004
+  #define UPS_EASTING_ERROR           0x0008
+  #define UPS_NORTHING_ERROR          0x0010
+  #define UPS_A_ERROR                 0x0020
+  #define UPS_INV_F_ERROR             0x0040
+
+
+/**********************************************************************/
+/*
+ *                        FUNCTION PROTOTYPES
+ *                          for UPS.C
+ */
+
+/* ensure proper linkage to c++ programs */
+  #ifdef __cplusplus
+extern "C" {
+  #endif
+
+  long Set_UPS_Parameters( double a,
+                           double f);
+/*
+ * The function SET_UPS_PARAMETERS receives the ellipsoid parameters and sets
+ * the corresponding state variables. If any errors occur, the error code(s)
+ * are returned by the function, otherwise UPS_NO_ERROR is returned.
+ *
+ *   a     : Semi-major axis of ellipsoid in meters (input)
+ *   f     : Flattening of ellipsoid                (input)
+ */
+
+
+  void Get_UPS_Parameters( double *a,
+                           double *f);
+/*
+ * The function Get_UPS_Parameters returns the current ellipsoid parameters.
+ *
+ *  a      : Semi-major axis of ellipsoid, in meters (output)
+ *  f      : Flattening of ellipsoid                 (output)
+ */
+
+
+  long Convert_Geodetic_To_UPS ( double Latitude,
+                                 double Longitude,
+                                 char   *Hemisphere,
+                                 double *Easting,
+                                 double *Northing);
+/*
+ *  The function Convert_Geodetic_To_UPS converts geodetic (latitude and
+ *  longitude) coordinates to UPS (hemisphere, easting, and northing)
+ *  coordinates, according to the current ellipsoid parameters. If any 
+ *  errors occur, the error code(s) are returned by the function, 
+ *  otherwide UPS_NO_ERROR is returned.
+ *
+ *    Latitude      : Latitude in radians                       (input)
+ *    Longitude     : Longitude in radians                      (input)
+ *    Hemisphere    : Hemisphere either 'N' or 'S'              (output)
+ *    Easting       : Easting/X in meters                       (output)
+ *    Northing      : Northing/Y in meters                      (output)
+ */
+
+
+  long Convert_UPS_To_Geodetic(char   Hemisphere,
+                               double Easting,
+                               double Northing,
+                               double *Latitude,
+                               double *Longitude);
+
+/*
+ *  The function Convert_UPS_To_Geodetic converts UPS (hemisphere, easting, 
+ *  and northing) coordinates to geodetic (latitude and longitude) coordinates
+ *  according to the current ellipsoid parameters.  If any errors occur, the 
+ *  error code(s) are returned by the function, otherwise UPS_NO_ERROR is 
+ *  returned.
+ *
+ *    Hemisphere    : Hemisphere either 'N' or 'S'              (input)
+ *    Easting       : Easting/X in meters                       (input)
+ *    Northing      : Northing/Y in meters                      (input)
+ *    Latitude      : Latitude in radians                       (output)
+ *    Longitude     : Longitude in radians                      (output)
+ */
+
+  #ifdef __cplusplus
+}
+  #endif
+
+#endif  /* UPS_H  */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpsProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpsProjection.cpp
new file mode 100644
index 0000000000..dea1cab8fa
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpsProjection.cpp
@@ -0,0 +1,335 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimUpsProjection.cpp,v 1.4 2004/01/08 21:49:22 jlargent Exp $
+#include "ossimUpsProjection.h"
+#include "ossimPolarst.h"
+
+#define PI       3.14159265358979323e0  /* PI     */
+#define PI_OVER    (PI/2.0e0)           /* PI over 2 */
+#define MAX_LAT    ((PI * 90)/180.0)    /* 90 degrees in radians */
+#define MAX_ORIGIN_LAT ((81.114528 * PI) / 180.0)
+#define MIN_NORTH_LAT (83.5*PI/180.0)
+#define MIN_SOUTH_LAT (-79.5*PI/180.0)
+#define MIN_EAST_NORTH 0
+#define MAX_EAST_NORTH 4000000
+
+#define UPS_NO_ERROR                0x0000
+#define UPS_LAT_ERROR               0x0001
+#define UPS_LON_ERROR               0x0002
+#define UPS_HEMISPHERE_ERROR        0x0004
+#define UPS_EASTING_ERROR           0x0008
+#define UPS_NORTHING_ERROR          0x0010
+#define UPS_A_ERROR                 0x0020
+#define UPS_INV_F_ERROR             0x0040
+
+RTTI_DEF1(ossimUpsProjection, "ossimUpsProjection", ossimMapProjection);
+
+ossimUpsProjection::ossimUpsProjection(const ossimEllipsoid& ellipsoid,
+                                       const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+    
+
+void ossimUpsProjection::setDefaults()
+{
+   if(theOrigin.latd() >= -FLT_EPSILON)
+   {
+      UPS_Origin_Latitude  =  MAX_ORIGIN_LAT;
+      theHemisphere        = 'N';
+   }
+   else
+   {
+      UPS_Origin_Latitude  =  -MAX_ORIGIN_LAT;
+      theHemisphere = 'S';
+   }
+   UPS_False_Easting    = 2000000;
+   UPS_False_Northing   = 2000000;
+   false_easting        = 0.0;
+   false_northing       = 0.0;
+   UPS_Easting          = 0.0;
+   UPS_Northing         = 0.0;
+   UPS_Origin_Longitude = 0.0;
+   theOrigin            = ossimGpt(UPS_Origin_Latitude*DEG_PER_RAD,
+                                   0.0,0.0);
+}
+
+ossimGpt ossimUpsProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_UPS_To_Geodetic(theHemisphere,
+                           eastingNorthing.x,
+                           eastingNorthing.y,
+                           &lat,
+                           &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);
+}
+
+ossimDpt ossimUpsProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+   
+   Convert_Geodetic_To_UPS(gpt.latr(),
+                           gpt.lonr(),
+                           &theHemisphere,
+                           &easting,
+                           &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+void ossimUpsProjection::update()
+{
+   Set_UPS_Parameters(theEllipsoid.getA(),
+                      theEllipsoid.getFlattening());
+
+   ossimMapProjection::update();
+}
+
+/*!
+ * Method to save the state of an object to a keyword list.
+ * Return true if ok or false on error.
+ */
+bool ossimUpsProjection::saveState(ossimKeywordlist& kwl,
+                                   const char* prefix)const
+{
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+
+/*!
+ * Method to the load (recreate) the state of an object from a keyword
+ * list.  Return true if ok or false on error.
+ */
+bool ossimUpsProjection::loadState(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+{
+   setDefaults();
+
+   return ossimMapProjection::loadState(kwl, prefix);
+}
+
+/************************************************************************/
+/*                              FUNCTIONS
+ *
+ */
+
+
+long ossimUpsProjection::Set_UPS_Parameters( double a,
+                                             double f)
+{
+/*
+ * The function SET_UPS_PARAMETERS receives the ellipsoid parameters and sets
+ * the corresponding state variables. If any errors occur, the error code(s)
+ * are returned by the function, otherwise UPS_NO_ERROR is returned.
+ *
+ *   a     : Semi-major axis of ellipsoid in meters (input)
+ *   f     : Flattening of ellipsoid					      (input)
+ */
+
+//  double inv_f = 1 / f;
+  long Error_Code = UPS_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= UPS_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= UPS_INV_F_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+    UPS_a = a;
+    UPS_f = f;
+  }
+  return (Error_Code);
+}  /* END of Set_UPS_Parameters  */
+
+
+void ossimUpsProjection::Get_UPS_Parameters( double *a,
+                                             double *f)const
+{
+/*
+ * The function Get_UPS_Parameters returns the current ellipsoid parameters.
+ *
+ *  a      : Semi-major axis of ellipsoid, in meters (output)
+ *  f      : Flattening of ellipsoid					       (output)
+ */
+
+  *a = UPS_a;
+  *f = UPS_f;
+  
+  return;
+} /* END OF Get_UPS_Parameters */
+
+
+long ossimUpsProjection::Convert_Geodetic_To_UPS ( double Latitude,
+                                                   double Longitude,
+                                                   char   *Hemisphere,
+                                                   double *Easting,
+                                                   double *Northing)const
+{
+/*
+ *  The function Convert_Geodetic_To_UPS converts geodetic (latitude and
+ *  longitude) coordinates to UPS (hemisphere, easting, and northing)
+ *  coordinates, according to the current ellipsoid parameters. If any 
+ *  errors occur, the error code(s) are returned by the function, 
+ *  otherwide UPS_NO_ERROR is returned.
+ *
+ *    Latitude      : Latitude in radians                       (input)
+ *    Longitude     : Longitude in radians                      (input)
+ *    Hemisphere    : Hemisphere either 'N' or 'S'              (output)
+ *    Easting       : Easting/X in meters                       (output)
+ *    Northing      : Northing/Y in meters                      (output)
+ */
+
+  double tempEasting, tempNorthing;
+  long Error_Code = UPS_NO_ERROR;
+
+//   if ((Latitude < -MAX_LAT) || (Latitude > MAX_LAT))
+//   {   /* latitude out of range */
+//     Error_Code |= UPS_LAT_ERROR;
+//   }
+//   if ((Latitude < 0) && (Latitude > MIN_SOUTH_LAT))
+//     Error_Code |= UPS_LAT_ERROR;
+//   if ((Latitude >= 0) && (Latitude < MIN_NORTH_LAT))
+//     Error_Code |= UPS_LAT_ERROR;
+//   if ((Longitude < -PI) || (Longitude > (2 * PI)))
+//   {  /* slam out of range */
+//     Error_Code |= UPS_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  {  /* no errors */
+//     if (Latitude < 0)
+//     {
+//       UPS_Origin_Latitude = -MAX_ORIGIN_LAT; 
+//       *Hemisphere = 'S';
+//     }
+//     else
+//     {
+//       UPS_Origin_Latitude = MAX_ORIGIN_LAT; 
+//       *Hemisphere = 'N';
+//     }
+
+
+    Set_Polar_Stereographic_Parameters( UPS_a,
+                                        UPS_f,
+                                        UPS_Origin_Latitude,
+                                        UPS_Origin_Longitude,
+                                        false_easting,
+                                        false_northing);
+
+    Convert_Geodetic_To_Polar_Stereographic(Latitude,
+                                            Longitude,
+                                            &tempEasting,
+                                            &tempNorthing);
+
+    UPS_Easting = UPS_False_Easting + tempEasting;
+    UPS_Northing = UPS_False_Northing + tempNorthing;
+
+
+    *Easting = UPS_Easting;
+    *Northing = UPS_Northing;
+  }  /*  END of if(!Error_Code)   */
+
+  return (Error_Code);
+}  /* END OF Convert_Geodetic_To_UPS  */
+
+
+long ossimUpsProjection::Convert_UPS_To_Geodetic(char   Hemisphere,
+                                                 double Easting,
+                                                 double Northing,
+                                                 double *Latitude,
+                                                 double *Longitude)const
+{
+/*
+ *  The function Convert_UPS_To_Geodetic converts UPS (hemisphere, easting, 
+ *  and northing) coordinates to geodetic (latitude and longitude) coordinates
+ *  according to the current ellipsoid parameters.  If any errors occur, the 
+ *  error code(s) are returned by the function, otherwise UPS_NO_ERROR is 
+ *  returned.
+ *
+ *    Hemisphere    : Hemisphere either 'N' or 'S'              (input)
+ *    Easting       : Easting/X in meters                       (input)
+ *    Northing      : Northing/Y in meters                      (input)
+ *    Latitude      : Latitude in radians                       (output)
+ *    Longitude     : Longitude in radians                      (output)
+ */
+
+  long Error_Code = UPS_NO_ERROR;
+
+//   if ((Hemisphere != 'N') && (Hemisphere != 'S'))
+//     Error_Code |= UPS_HEMISPHERE_ERROR;
+//   if ((Easting < MIN_EAST_NORTH) || (Easting > MAX_EAST_NORTH))
+//     Error_Code |= UPS_EASTING_ERROR;
+//   if ((Northing < MIN_EAST_NORTH) || (Northing > MAX_EAST_NORTH))
+//     Error_Code |= UPS_NORTHING_ERROR;
+
+  if (Hemisphere =='N')
+  {UPS_Origin_Latitude = MAX_ORIGIN_LAT;}
+  if (Hemisphere =='S')
+  {UPS_Origin_Latitude = -MAX_ORIGIN_LAT;}
+
+  if (!Error_Code)
+  {   /*  no errors   */
+    Set_Polar_Stereographic_Parameters( UPS_a,
+                                        UPS_f,
+                                        UPS_Origin_Latitude,
+                                        UPS_Origin_Longitude,
+                                        UPS_False_Easting,
+                                        UPS_False_Northing);
+
+
+
+    Convert_Polar_Stereographic_To_Geodetic( Easting,
+                                             Northing,
+                                             Latitude,
+                                             Longitude); 
+
+
+//     if ((*Latitude < 0) && (*Latitude > MIN_SOUTH_LAT))
+//       Error_Code |= UPS_LAT_ERROR;
+//     if ((*Latitude >= 0) && (*Latitude < MIN_NORTH_LAT))
+//       Error_Code |= UPS_LAT_ERROR;
+  }  /*  END OF if(!Error_Code) */
+  return (Error_Code);
+}  /*  END OF Convert_UPS_To_Geodetic  */ 
+
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpsProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpsProjection.h
new file mode 100644
index 0000000000..e1f3de04a9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpsProjection.h
@@ -0,0 +1,140 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimUpsProjection.h,v 1.2 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimUpsProjection_HEADER
+#define ossimUpsProjection_HEADER
+#include "ossimMapProjection.h"
+
+class ossimUpsProjection : public ossimMapProjection
+{
+public:
+   ossimUpsProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                      const ossimGpt& origin = ossimGpt());
+
+   virtual ossimObject *dup()const{return new ossimUpsProjection(*this);}
+   
+   void setDefaults();
+
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   double getFalseEasting()const{return UPS_False_Easting;}
+   double getFalseNorthing()const{return UPS_False_Northing;}
+   
+protected:
+   mutable char theHemisphere;
+
+   //___________________GEOTRANS__________________
+   //
+   mutable double UPS_a;          /* Semi-major axis of ellipsoid in meters   */
+   mutable double UPS_f;  /* Flattening of ellipsoid  */
+   mutable double UPS_Origin_Latitude;  /*set default = North Hemisphere */
+   mutable double UPS_Origin_Longitude;
+   mutable double false_easting;
+   mutable double false_northing;
+   mutable double UPS_Easting;
+   mutable double UPS_Northing;
+   double UPS_False_Easting;
+   double UPS_False_Northing;
+
+/*!
+ * The function SET_UPS_PARAMETERS receives the ellipsoid parameters and sets
+ * the corresponding state variables. If any errors occur, the error code(s)
+ * are returned by the function, otherwise UPS_NO_ERROR is returned.
+ *
+ *   a     : Semi-major axis of ellipsoid in meters (input)
+ *   f     : Flattening of ellipsoid                (input)
+ */
+   long Set_UPS_Parameters( double a,
+                           double f);
+
+
+/*!
+ * The function Get_UPS_Parameters returns the current ellipsoid parameters.
+ *
+ *  a      : Semi-major axis of ellipsoid, in meters (output)
+ *  f      : Flattening of ellipsoid                 (output)
+ */
+  void Get_UPS_Parameters( double *a,
+                           double *f)const;
+
+
+/*!
+ *  The function Convert_Geodetic_To_UPS converts geodetic (latitude and
+ *  longitude) coordinates to UPS (hemisphere, easting, and northing)
+ *  coordinates, according to the current ellipsoid parameters. If any 
+ *  errors occur, the error code(s) are returned by the function, 
+ *  otherwide UPS_NO_ERROR is returned.
+ *
+ *    Latitude      : Latitude in radians                       (input)
+ *    Longitude     : Longitude in radians                      (input)
+ *    Hemisphere    : Hemisphere either 'N' or 'S'              (output)
+ *    Easting       : Easting/X in meters                       (output)
+ *    Northing      : Northing/Y in meters                      (output)
+ */
+  long Convert_Geodetic_To_UPS ( double Latitude,
+                                 double Longitude,
+                                 char   *Hemisphere,
+                                 double *Easting,
+                                 double *Northing)const;
+
+
+/*!
+ *  The function Convert_UPS_To_Geodetic converts UPS (hemisphere, easting, 
+ *  and northing) coordinates to geodetic (latitude and longitude) coordinates
+ *  according to the current ellipsoid parameters.  If any errors occur, the 
+ *  error code(s) are returned by the function, otherwise UPS_NO_ERROR is 
+ *  returned.
+ *
+ *    Hemisphere    : Hemisphere either 'N' or 'S'              (input)
+ *    Easting       : Easting/X in meters                       (input)
+ *    Northing      : Northing/Y in meters                      (input)
+ *    Latitude      : Latitude in radians                       (output)
+ *    Longitude     : Longitude in radians                      (output)
+ */
+  long Convert_UPS_To_Geodetic(char   Hemisphere,
+                               double Easting,
+                               double Northing,
+                               double *Latitude,
+                               double *Longitude)const;
+
+TYPE_DATA  
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpspt.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpspt.cpp
new file mode 100644
index 0000000000..3f1a3c086a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpspt.cpp
@@ -0,0 +1,67 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// This is the Universal Polar Stereographic (UPS) point.  Allows
+// easy onversion between different coordinates.
+//*******************************************************************
+//  $Id: ossimUpspt.cpp,v 1.2 2001/08/15 03:05:49 okramer Exp $
+#include "ossimUpspt.h"
+#include "ossimUtmpt.h"
+#include "ossimUps.h"
+
+#include "base/data_types/ossimGpt.h"
+#include "base/data_types/ossimEcefPoint.h"
+#include "base/data_types/ellipse/ossimEllipsoid.h"
+#include "base/data_types/datum/ossimDatum.h"
+
+ossimUpspt::ossimUpspt(const ossimGpt &aPt)
+{
+   convertFromGeodetic(aPt);
+}
+
+ossimUpspt::ossimUpspt(const ossimEcefPoint &aPt)
+{
+   convertFromGeodetic(ossimGpt(aPt));
+}
+
+
+void ossimUpspt::convertFromGeodetic(const ossimGpt &aPt)
+{
+   const ossimDatum *aDatum = aPt.datum();
+
+   if(aDatum)
+   {
+      Set_UPS_Parameters(aDatum->ellipsoid()->a(),
+                         aDatum->ellipsoid()->b());
+      
+      Convert_Geodetic_To_UPS(aPt.latr(),
+                              aPt.lonr(),
+                              &theHemisphere,
+                              &theEasting,
+                              &theNorthing);
+      theDatum = const_cast<ossimDatum*>(aDatum);
+   }
+   else
+   {
+      //ERROR: should never happen
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpspt.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpspt.h
new file mode 100644
index 0000000000..1b76b2066a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUpspt.h
@@ -0,0 +1,56 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts(gpotts@imagelinks.com)
+//
+// Description:
+//
+// This is the Universal Polar Stereographic (UPS) point.  Allows
+// easy onversion between different coordinates.
+//*******************************************************************
+//  $Id: ossimUpspt.h,v 1.2 2001/08/15 03:05:49 okramer Exp $
+
+#ifndef ossimUpspt_HEADER
+#define ossimUpspt_HEADER
+
+class ossimUtmpt;
+class ossimGpt;
+class ossimEcefPoint;
+class ossimDatum;
+
+class ossimUpspt
+{
+public:
+   ossimUpspt(const ossimGpt &aPt);
+   ossimUpspt(const ossimEcefPoint &aPt);
+
+   char hemisphere()const{return theHemisphere;}
+   double easting()const {return theEasting;}
+   double northing()const{return theNorthing;}
+   const ossimDatum* datum()const{return theDatum;}
+   
+private:
+   char    theHemisphere;
+   double  theEasting;
+   double  theNorthing;
+   ossimDatum  *theDatum;
+
+   void convertFromGeodetic(const ossimGpt &aPt);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtm.c b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtm.c
new file mode 100644
index 0000000000..28867fdfb1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtm.c
@@ -0,0 +1,337 @@
+/***************************************************************************/
+/* RSC IDENTIFIER: UTM
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between geodetic coordinates 
+ *    (latitude and longitudes) and Universal Transverse Mercator (UTM)
+ *    projection (zone, hemisphere, easting, and northing) coordinates.
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *          UTM_NO_ERROR           : No errors occurred in function
+ *          UTM_LAT_ERROR          : Latitude outside of valid range
+ *                                    (-80.5 to 84.5 degrees)
+ *          UTM_LON_ERROR          : Longitude outside of valid range
+ *                                    (-180 to 360 degrees)
+ *          UTM_EASTING_ERROR      : Easting outside of valid range
+ *                                    (100,000 to 900,000 meters)
+ *          UTM_NORTHING_ERROR     : Northing outside of valid range
+ *                                    (0 to 10,000,000 meters)
+ *          UTM_ZONE_ERROR         : Zone outside of valid range (1 to 60)
+ *          UTM_HEMISPHERE_ERROR   : Invalid hemisphere ('N' or 'S')
+ *          UTM_ZONE_OVERRIDE_ERROR: Zone outside of valid range
+ *                                    (1 to 60) and within 1 of 'natural' zone
+ *          UTM_A_ERROR            : Semi-major axis less than or equal to zero
+ *          UTM_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	                (250 to 350)
+ *
+ * REUSE NOTES
+ *
+ *    UTM is intended for reuse by any application that performs a Universal
+ *    Transverse Mercator (UTM) projection or its inverse.
+ *    
+ * REFERENCES
+ *
+ *    Further information on UTM can be found in the Reuse Manual.
+ *
+ *    UTM originated from :  U.S. Army Topographic Engineering Center
+ *                           Geospatial Information Division
+ *                           7701 Telegraph Road
+ *                           Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    UTM has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    UTM was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC, version 2.8.1
+ *    2. MSDOS with MS Visual C++, version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    10-02-97          Original Code
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                              INCLUDES
+ */
+#include "ossimTranmerc.h"
+#include "ossimUtm.h"
+/*
+ *    tranmerc.h    - Is used to convert transverse mercator coordinates
+ *    utm.h         - Defines the function prototypes for the utm module.
+ */
+
+
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+#define PI           3.14159265358979323e0    /* PI                        */
+#define MIN_LAT      ( (-80.5 * PI) / 180.0 ) /* -80.5 degrees in radians    */
+#define MAX_LAT      ( (84.5 * PI) / 180.0 )  /* 84.5 degrees in radians     */
+#define MIN_EASTING  100000
+#define MAX_EASTING  900000
+#define MIN_NORTHING 0
+#define MAX_NORTHING 10000000
+
+/***************************************************************************/
+/*
+ *                              GLOBAL DECLARATIONS
+ */
+
+static double UTM_a = 6378137.0;         /* Semi-major axis of ellipsoid in meters  */
+static double UTM_f = 1 / 298.257223563; /* Flattening of ellipsoid                 */
+static long   UTM_Override = 0;          /* Zone override flag                      */
+
+
+/***************************************************************************/
+/*
+ *                                FUNCTIONS
+ *
+ */
+
+long Set_UTM_Parameters(double a,      
+                        double f,
+                        long   override)
+{
+/*
+ * The function Set_UTM_Parameters receives the ellipsoid parameters and
+ * UTM zone override parameter as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise UTM_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters       (input)
+ *    f                 : Flattening of ellipsoid						            (input)
+ *    override          : UTM override zone, zero indicates no override (input)
+ */
+
+  double inv_f = 1 / f;
+  long Error_Code = UTM_NO_ERROR;
+
+  if (a <= 0.0)
+  { /* Semi-major axis must be greater than zero */
+    Error_Code |= UTM_A_ERROR;
+  }
+  if ((inv_f < 250) || (inv_f > 350))
+  { /* Inverse flattening must be between 250 and 350 */
+    Error_Code |= UTM_INV_F_ERROR;
+  }
+  if ((override < 0) || (override > 60))
+  {
+    Error_Code |= UTM_ZONE_OVERRIDE_ERROR;
+  }
+  if (!Error_Code)
+  { /* no errors */
+    UTM_a = a;
+    UTM_f = f;
+    UTM_Override = override;
+  }
+  return (Error_Code);
+} /* END OF Set_UTM_Parameters */
+
+
+void Get_UTM_Parameters(double *a,
+                        double *f,
+                        long   *override)
+{
+/*
+ * The function Get_UTM_Parameters returns the current ellipsoid
+ * parameters and UTM zone override parameter.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters       (output)
+ *    f                 : Flattening of ellipsoid						            (output)
+ *    override          : UTM override zone, zero indicates no override (output)
+ */
+
+  *a = UTM_a;
+  *f = UTM_f;
+  *override = UTM_Override;
+} /* END OF Get_UTM_Parameters */
+
+
+long Convert_Geodetic_To_UTM (double Latitude,
+                              double Longitude,
+                              long   *Zone,
+                              char   *Hemisphere,
+                              double *Easting,
+                              double *Northing)
+{ 
+/*
+ * The function Convert_Geodetic_To_UTM converts geodetic (latitude and
+ * longitude) coordinates to UTM projection (zone, hemisphere, easting and
+ * northing) coordinates according to the current ellipsoid and UTM zone
+ * override parameters.  If any errors occur, the error code(s) are returned
+ * by the function, otherwise UTM_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude in radians                 (input)
+ *    Longitude         : Longitude in radians                (input)
+ *    Zone              : UTM zone                            (output)
+ *    Hemisphere        : North or South hemisphere           (output)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  long Lat_Degrees;
+  long Long_Degrees;
+  long temp_zone;
+  long Error_Code = UTM_NO_ERROR;
+  double Origin_Latitude = 0;
+  double Central_Meridian = 0;
+  double False_Easting = 500000;
+  double False_Northing = 0;
+  double Scale = 0.9996;
+
+  if ((Latitude < MIN_LAT) || (Latitude > MAX_LAT))
+  { /* Latitude out of range */
+    Error_Code |= UTM_LAT_ERROR;
+  }
+  if ((Longitude < -PI) || (Longitude > (2*PI)))
+  { /* Longitude out of range */
+    Error_Code |= UTM_LON_ERROR;
+  }
+  if (!Error_Code)
+  { /* no errors */
+    if (Longitude < 0)
+      Longitude += (2*PI);
+    Lat_Degrees = (long)(Latitude * 180.0 / PI);
+    Long_Degrees = (long)(Longitude * 180.0 / PI);
+
+    if (Longitude < PI)
+      temp_zone = (long)(31 + ((Longitude * 180.0 / PI) / 6.0));
+    else
+      temp_zone = (long)(((Longitude * 180.0 / PI) / 6.0) - 29);
+    if (temp_zone > 60)
+      temp_zone = 1;
+    /* UTM special cases */
+    if ((Lat_Degrees > 55) && (Lat_Degrees < 64) && (Long_Degrees > -1)
+        && (Long_Degrees < 3))
+      temp_zone = 31;
+    if ((Lat_Degrees > 55) && (Lat_Degrees < 64) && (Long_Degrees > 2)
+        && (Long_Degrees < 12))
+      temp_zone = 32;
+    if ((Lat_Degrees > 71) && (Long_Degrees > -1) && (Long_Degrees < 9))
+      temp_zone = 31;
+    if ((Lat_Degrees > 71) && (Long_Degrees > 8) && (Long_Degrees < 21))
+      temp_zone = 33;
+    if ((Lat_Degrees > 71) && (Long_Degrees > 20) && (Long_Degrees < 33))
+      temp_zone = 35;
+    if ((Lat_Degrees > 71) && (Long_Degrees > 32) && (Long_Degrees < 42))
+      temp_zone = 37;
+
+    if (UTM_Override)
+    {
+      if ((temp_zone == 1) && (UTM_Override == 60))
+        temp_zone = UTM_Override;
+      else if ((temp_zone == 60) && (UTM_Override == 1))
+        temp_zone = UTM_Override;
+      else if (((temp_zone-1) <= UTM_Override) && (UTM_Override <= (temp_zone+1)))
+        temp_zone = UTM_Override;
+      else
+        Error_Code = UTM_ZONE_OVERRIDE_ERROR;
+    }
+    if (!Error_Code)
+    {
+      if (temp_zone >= 31)
+        Central_Meridian = (6 * temp_zone - 183) * PI / 180.0;
+      else
+        Central_Meridian = (6 * temp_zone + 177) * PI / 180.0;
+      *Zone = temp_zone;
+      if (Latitude < 0)
+      {
+        False_Northing = 10000000;
+        *Hemisphere = 'S';
+      }
+      else
+        *Hemisphere = 'N';
+      Set_Transverse_Mercator_Parameters(UTM_a, UTM_f, Origin_Latitude,
+                                         Central_Meridian, False_Easting, False_Northing, Scale);
+      Convert_Geodetic_To_Transverse_Mercator(Latitude, Longitude, Easting,
+                                              Northing);
+      if ((*Easting < MIN_EASTING) || (*Easting > MAX_EASTING))
+        Error_Code = UTM_EASTING_ERROR;
+      if ((*Northing < MIN_NORTHING) || (*Northing > MAX_NORTHING))
+        Error_Code |= UTM_NORTHING_ERROR;
+    }
+  } /* END OF if (!Error_Code) */
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_UTM */
+
+
+long Convert_UTM_To_Geodetic(long   Zone,
+                             char   Hemisphere,
+                             double Easting,
+                             double Northing,
+                             double *Latitude,
+                             double *Longitude)
+{
+/*
+ * The function Convert_UTM_To_Geodetic converts UTM projection (zone, 
+ * hemisphere, easting and northing) coordinates to geodetic(latitude
+ * and  longitude) coordinates, according to the current ellipsoid
+ * parameters.  If any errors occur, the error code(s) are returned
+ * by the function, otherwise UTM_NO_ERROR is returned.
+ *
+ *    Zone              : UTM zone                               (input)
+ *    Hemisphere        : North or South hemisphere              (input)
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude in radians                    (output)
+ *    Longitude         : Longitude in radians                   (output)
+ */
+  long Error_Code = UTM_NO_ERROR;
+  double Origin_Latitude = 0;
+  double Central_Meridian = 0;
+  double False_Easting = 500000;
+  double False_Northing = 0;
+  double Scale = 0.9996;
+
+  if ((Zone < 1) || (Zone > 60))
+    Error_Code |= UTM_ZONE_ERROR;
+  if ((Hemisphere != 'S') && (Hemisphere != 'N'))
+    Error_Code |= UTM_HEMISPHERE_ERROR;
+  if ((Easting < MIN_EASTING) || (Easting > MAX_EASTING))
+    Error_Code |= UTM_EASTING_ERROR;
+  if ((Northing < MIN_NORTHING) || (Northing > MAX_NORTHING))
+    Error_Code |= UTM_NORTHING_ERROR;
+  if (!Error_Code)
+  { /* no errors */
+    if (Zone >= 31)
+      Central_Meridian = ((6 * Zone - 183) * PI / 180.0 + 0.00000005);
+    else
+      Central_Meridian = ((6 * Zone + 177) * PI / 180.0 + 0.00000005);
+    if (Hemisphere == 'S')
+      False_Northing = 10000000;
+    Set_Transverse_Mercator_Parameters(UTM_a, UTM_f, Origin_Latitude,
+                                       Central_Meridian, False_Easting, False_Northing, Scale);
+    if (Convert_Transverse_Mercator_To_Geodetic(Easting,
+                                                Northing,
+                                                Latitude, 
+                                                Longitude))
+      Error_Code |= UTM_NORTHING_ERROR;
+    if ((*Latitude < MIN_LAT) || (*Latitude > MAX_LAT))
+    { /* Latitude out of range */
+      Error_Code |= UTM_NORTHING_ERROR;
+    }
+  }
+  return (Error_Code);
+} /* END OF Convert_UTM_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtm.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtm.h
new file mode 100644
index 0000000000..0b32051b86
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtm.h
@@ -0,0 +1,178 @@
+#ifndef UTM_H
+  #define UTM_H
+
+/***************************************************************************/
+/* RSC IDENTIFIER: UTM
+ *
+ * ABSTRACT
+ *
+ *    This component provides conversions between geodetic coordinates 
+ *    (latitude and longitudes) and Universal Transverse Mercator (UTM)
+ *    projection (zone, hemisphere, easting, and northing) coordinates.
+ *
+ * ERROR HANDLING
+ *
+ *    This component checks parameters for valid values.  If an invalid value
+ *    is found, the error code is combined with the current error code using 
+ *    the bitwise or.  This combining allows multiple error codes to be
+ *    returned. The possible error codes are:
+ *
+ *          UTM_NO_ERROR           : No errors occurred in function
+ *          UTM_LAT_ERROR          : Latitude outside of valid range
+ *                                    (-80.5 to 84.5 degrees)
+ *          UTM_LON_ERROR          : Longitude outside of valid range
+ *                                    (-180 to 360 degrees)
+ *          UTM_EASTING_ERROR      : Easting outside of valid range
+ *                                    (100,000 to 900,000 meters)
+ *          UTM_NORTHING_ERROR     : Northing outside of valid range
+ *                                    (0 to 10,000,000 meters)
+ *          UTM_ZONE_ERROR         : Zone outside of valid range (1 to 60)
+ *          UTM_HEMISPHERE_ERROR   : Invalid hemisphere ('N' or 'S')
+ *          UTM_ZONE_OVERRIDE_ERROR: Zone outside of valid range
+ *                                    (1 to 60) and within 1 of 'natural' zone
+ *          UTM_A_ERROR            : Semi-major axis less than or equal to zero
+ *          UTM_INV_F_ERROR        : Inverse flattening outside of valid range
+ *								  	                (250 to 350)
+ *
+ * REUSE NOTES
+ *
+ *    UTM is intended for reuse by any application that performs a Universal
+ *    Transverse Mercator (UTM) projection or its inverse.
+ *    
+ * REFERENCES
+ *
+ *    Further information on UTM can be found in the Reuse Manual.
+ *
+ *    UTM originated from :  U.S. Army Topographic Engineering Center
+ *                           Geospatial Information Division
+ *                           7701 Telegraph Road
+ *                           Alexandria, VA  22310-3864
+ *
+ * LICENSES
+ *
+ *    None apply to this component.
+ *
+ * RESTRICTIONS
+ *
+ *    UTM has no restrictions.
+ *
+ * ENVIRONMENT
+ *
+ *    UTM was tested and certified in the following environments:
+ *
+ *    1. Solaris 2.5 with GCC, version 2.8.1
+ *    2. MSDOS with MS Visual C++, version 6
+ *
+ * MODIFICATIONS
+ *
+ *    Date              Description
+ *    ----              -----------
+ *    10-02-97          Original Code
+ *
+ */
+
+
+/***************************************************************************/
+/*
+ *                              DEFINES
+ */
+
+  #define UTM_NO_ERROR            0x0000
+  #define UTM_LAT_ERROR           0x0001
+  #define UTM_LON_ERROR           0x0002
+  #define UTM_EASTING_ERROR       0x0004
+  #define UTM_NORTHING_ERROR      0x0008
+  #define UTM_ZONE_ERROR          0x0010
+  #define UTM_HEMISPHERE_ERROR    0x0020
+  #define UTM_ZONE_OVERRIDE_ERROR 0x0040
+  #define UTM_A_ERROR             0x0080
+  #define UTM_INV_F_ERROR         0x0100
+
+
+/***************************************************************************/
+/*
+ *                              FUNCTION PROTOTYPES
+ *                                for UTM.C
+ */
+
+/* ensure proper linkage to c++ programs */
+  #ifdef __cplusplus
+extern "C" {
+  #endif
+
+  long Set_UTM_Parameters(double a,      
+                          double f,
+                          long   override);
+/*
+ * The function Set_UTM_Parameters receives the ellipsoid parameters and
+ * UTM zone override parameter as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the 
+ * function, otherwise UTM_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters       (input)
+ *    f                 : Flattening of ellipsoid                       (input)
+ *    override          : UTM override zone, zero indicates no override (input)
+ */
+
+
+  void Get_UTM_Parameters(double *a,
+                          double *f,
+                          long   *override);
+/*
+ * The function Get_UTM_Parameters returns the current ellipsoid
+ * parameters and UTM zone override parameter.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters       (output)
+ *    f                 : Flattening of ellipsoid                       (output)
+ *    override          : UTM override zone, zero indicates no override (output)
+ */
+
+
+  long Convert_Geodetic_To_UTM (double Latitude,
+                                double Longitude,
+                                long   *Zone,
+                                char   *Hemisphere,
+                                double *Easting,
+                                double *Northing); 
+/*
+ * The function Convert_Geodetic_To_UTM converts geodetic (latitude and
+ * longitude) coordinates to UTM projection (zone, hemisphere, easting and
+ * northing) coordinates according to the current ellipsoid and UTM zone
+ * override parameters.  If any errors occur, the error code(s) are returned
+ * by the function, otherwise UTM_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude in radians                 (input)
+ *    Longitude         : Longitude in radians                (input)
+ *    Zone              : UTM zone                            (output)
+ *    Hemisphere        : North or South hemisphere           (output)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+
+  long Convert_UTM_To_Geodetic(long   Zone,
+                               char   Hemisphere,
+                               double Easting,
+                               double Northing,
+                               double *Latitude,
+                               double *Longitude);
+/*
+ * The function Convert_UTM_To_Geodetic converts UTM projection (zone, 
+ * hemisphere, easting and northing) coordinates to geodetic(latitude
+ * and  longitude) coordinates, according to the current ellipsoid
+ * parameters.  If any errors occur, the error code(s) are returned
+ * by the function, otherwise UTM_NO_ERROR is returned.
+ *
+ *    Zone              : UTM zone                               (input)
+ *    Hemisphere        : North or South hemisphere              (input)
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude in radians                    (output)
+ *    Longitude         : Longitude in radians                   (output)
+ */
+
+  #ifdef __cplusplus
+}
+  #endif
+
+#endif /* UTM_H */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmProjection.cpp
new file mode 100644
index 0000000000..4b6f66f70d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmProjection.cpp
@@ -0,0 +1,892 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Calls Geotrans Utm projection code.  
+//*******************************************************************
+//  $Id: ossimUtmProjection.cpp,v 1.40 2005/09/09 19:23:58 gpotts Exp $
+#include <cmath>
+using namespace std;
+
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+RTTI_DEF1(ossimUtmProjection, "ossimUtmProjection", ossimMapProjection)
+
+/******************************* DEFINES *********************************/
+   
+#define UTM_NO_ERROR            0x0000
+#define UTM_LAT_ERROR           0x0001
+#define UTM_LON_ERROR           0x0002
+#define UTM_EASTING_ERROR       0x0004
+#define UTM_NORTHING_ERROR      0x0008
+#define UTM_ZONE_ERROR          0x0010
+#define UTM_HEMISPHERE_ERROR    0x0020
+#define UTM_ZONE_OVERRIDE_ERROR 0x0040
+#define UTM_A_ERROR             0x0080
+#define UTM_B_ERROR             0x0100
+#define UTM_A_LESS_B_ERROR      0x0200
+
+#define MIN_LAT      ( (-80.5 * M_PI) / 180.0 ) /* -80.5 degrees in radians */
+#define MAX_LAT      ( (84.5 * M_PI) / 180.0 )  /* 84.5 degrees in radians  */
+#define MAX_DELTA_LONG  ((M_PI * 90.0)/180.0)    /* 90 degrees in radians */
+#define MIN_EASTING  100000
+#define MAX_EASTING  900000
+#define MIN_NORTHING 0
+#define MAX_NORTHING 10000000
+#define MIN_SCALE_FACTOR  0.3
+#define MAX_SCALE_FACTOR  3.0
+
+#define SPHTMD(Latitude) ((double) (theTranMerc_ap * Latitude \
+      - theTranMerc_bp * sin(2.e0 * Latitude) + theTranMerc_cp * sin(4.e0 * Latitude) \
+      - theTranMerc_dp * sin(6.e0 * Latitude) + theTranMerc_ep * sin(8.e0 * Latitude) ) )
+
+#define SPHSN(Latitude) ((double) (getA() / sqrt( 1.e0 - theTranMerc_es * \
+      pow(sin(Latitude), 2))))
+
+#define SPHSR(Latitude) ((double) (getA() * (1.e0 - theTranMerc_es) / \
+    pow(DENOM(Latitude), 3)))
+
+#define DENOM(Latitude) ((double) (sqrt(1.e0 - theTranMerc_es * pow(sin(Latitude),2))))
+
+
+ossimUtmProjection::ossimUtmProjection(const ossimEllipsoid& ellipsoid,
+                                       const ossimGpt& origin)
+   :
+      ossimMapProjection(ellipsoid, origin),
+      theTranMerc_a(6378137.0),
+      theTranMerc_f(1.0/298.257223563),
+      theTranMerc_es(0.0066943799901413800),
+      theTranMerc_ebs(0.0067394967565869),
+      theTranMerc_Origin_Lat(0.0),
+      theTranMerc_Origin_Long(0.0),
+      theTranMerc_False_Northing(0.0),
+      theTranMerc_False_Easting(500000.0),
+      theTranMerc_Scale_Factor(0.9996),
+      theTranMerc_ap(6367449.1458008),
+      theTranMerc_bp(16038.508696861),
+      theTranMerc_cp(16.832613334334),
+      theTranMerc_dp(0.021984404273757),
+      theTranMerc_Delta_Easting(40000000.0),
+      theTranMerc_Delta_Northing(40000000.0),
+      theZone(1),
+      theHemisphere('N')
+      
+{
+   setZone(origin);
+   update();
+}
+
+ossimUtmProjection::ossimUtmProjection(const ossimEllipsoid& ellipsoid,
+                                       const ossimGpt& origin,
+                                       long zone,
+                                       char hemisphere)
+   :
+      ossimMapProjection(ellipsoid, origin),
+      theTranMerc_a(6378137.0),
+      theTranMerc_f(1.0/298.257223563),
+      theTranMerc_es(0.0066943799901413800),
+      theTranMerc_ebs(0.0067394967565869),
+      theTranMerc_Origin_Lat(0.0),
+      theTranMerc_Origin_Long(0.0),
+      theTranMerc_False_Northing(0.0),
+      theTranMerc_False_Easting(500000.0),
+      theTranMerc_Scale_Factor(0.9996),
+      theTranMerc_ap(6367449.1458008),
+      theTranMerc_bp(16038.508696861),
+      theTranMerc_cp(16.832613334334),
+      theTranMerc_dp(0.021984404273757),
+      theTranMerc_Delta_Easting(40000000.0),
+      theTranMerc_Delta_Northing(40000000.0),
+      theZone(zone),
+      theHemisphere('N')      
+{
+   setZone(zone);
+   setHemisphere(hemisphere);
+   update();
+}
+
+ossimUtmProjection::ossimUtmProjection(long zone)
+   :
+      ossimMapProjection(),
+      theTranMerc_a(6378137.0),
+      theTranMerc_f(1.0/298.257223563),
+      theTranMerc_es(0.0066943799901413800),
+      theTranMerc_ebs(0.0067394967565869),
+      theTranMerc_Origin_Lat(0.0),
+      theTranMerc_Origin_Long(0.0),
+      theTranMerc_False_Northing(0.0),
+      theTranMerc_False_Easting(500000.0),
+      theTranMerc_Scale_Factor(0.9996),
+      theTranMerc_ap(6367449.1458008),
+      theTranMerc_bp(16038.508696861),
+      theTranMerc_cp(16.832613334334),
+      theTranMerc_dp(0.021984404273757),
+      theTranMerc_Delta_Easting(40000000.0),
+      theTranMerc_Delta_Northing(40000000.0),
+      theZone(zone),
+      theHemisphere('N')      
+{
+   setZone(zone);
+   theOrigin.lond(computeZoneMeridian(theZone));
+   update();
+}
+
+ossimUtmProjection::ossimUtmProjection(const ossimUtmProjection& src)
+      :ossimMapProjection(src),
+      theTranMerc_a(src.theTranMerc_a),
+      theTranMerc_f(src.theTranMerc_f),
+      theTranMerc_es(src.theTranMerc_es),
+      theTranMerc_ebs(src.theTranMerc_ebs),
+      theTranMerc_Origin_Lat(src.theTranMerc_Origin_Lat),
+      theTranMerc_Origin_Long(src.theTranMerc_Origin_Long),
+      theTranMerc_False_Northing(src.theTranMerc_False_Northing),
+      theTranMerc_False_Easting(src.theTranMerc_False_Easting),
+      theTranMerc_Scale_Factor(src.theTranMerc_Scale_Factor),
+      theTranMerc_ap(src.theTranMerc_ap),
+      theTranMerc_bp(src.theTranMerc_bp),
+      theTranMerc_cp(src.theTranMerc_cp),
+      theTranMerc_dp(src.theTranMerc_dp),
+      theTranMerc_Delta_Easting(src.theTranMerc_Delta_Easting),
+      theTranMerc_Delta_Northing(src.theTranMerc_Delta_Northing),
+      theZone(src.theZone),
+      theHemisphere(src.theHemisphere)      
+{
+}
+
+void ossimUtmProjection::update()
+{
+   Set_Transverse_Mercator_Parameters(theEllipsoid.getA(),
+                                      theEllipsoid.getFlattening(),
+                                      theOrigin.latr(),
+                                      theOrigin.lonr(),
+                                      theTranMerc_False_Easting,
+                                      theTranMerc_False_Northing,
+                                      theTranMerc_Scale_Factor);
+
+   ossimMapProjection::update();
+}
+
+ossimGpt ossimUtmProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Transverse_Mercator_To_Geodetic(eastingNorthing.x,
+                                           eastingNorthing.y,
+                                           &lat,
+                                           &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);
+}
+
+ossimDpt ossimUtmProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Transverse_Mercator(gpt.latr(),
+                                           gpt.lonr(),
+                                           &easting,
+                                           &northing);
+   
+   return ossimDpt(easting, northing);
+}
+
+ossimObject* ossimUtmProjection::dup()const
+{
+   ossimUtmProjection* proj = new ossimUtmProjection(*this);
+
+   //---
+   // TEMP:
+   // Set the projection up correctly.
+   // Note: The setZone sets the origin, but does not set all parameter
+   // needed; hence, the setZone, setOrigin.
+   //---
+   proj->setZone(theZone);
+   proj->setOrigin(proj->origin());
+   proj->setUlGpt(proj->origin());
+   return proj;
+}
+
+long ossimUtmProjection::getZone() const
+{
+   return theZone;
+}
+
+char ossimUtmProjection::getHemisphere() const
+{
+   return theHemisphere;
+}
+
+void ossimUtmProjection::setZone(const ossimGpt& ground)
+{
+   theZone = computeZone(ground);
+   theOrigin.lond(computeZoneMeridian(theZone));
+   theOrigin.latd(0.0);
+   theTranMerc_Origin_Long = theOrigin.lonr();
+   char hemisphere = theOrigin.latd() < 0.0?'S':'N';
+   setHemisphere(hemisphere);
+}
+
+void ossimUtmProjection::setZone(long zone)
+{
+   if(ossimIsNan(zone))
+   {
+      theZone = computeZone(theOrigin);
+   }
+   else
+   {
+      theZone = zone;
+   }
+   theOrigin.lond(computeZoneMeridian(theZone));
+   theOrigin.latd(0);
+   theTranMerc_Origin_Long = theOrigin.lonr();
+}
+
+void ossimUtmProjection::setHemisphere(char hemisphere)
+{
+   hemisphere = toupper(hemisphere);
+   if((hemisphere != 'N') &&
+      (hemisphere != 'S'))
+   {
+      theHemisphere = theOrigin.latd() < 0?'S':'N';
+   }
+   else
+   {
+      theHemisphere = hemisphere;
+   }
+
+   if (theHemisphere == 'N')
+   {
+      theTranMerc_False_Northing = 0.0;
+   }
+   else
+   {
+      theTranMerc_False_Northing  = 10000000.0;
+   }
+}
+
+long ossimUtmProjection::computeZone(const ossimGpt& ground)
+{
+   long result = 0;
+
+   double longitude = ground.lonr();
+   double lat_Degrees  = (long)( (ground.latd()) + 0.00000005);
+   double long_Degrees = (long)( (ground.lond()) + 0.00000005);
+   
+   if (longitude < M_PI)
+      result = (long)( (31 + ((180 * longitude) / (6 * M_PI)) ) + 0.00000005);
+   else
+      result = (long)( (((180 * longitude) / (6 * M_PI)) - 29) + 0.00000005);
+   if (result > 60)
+      result = 1;
+    /* UTM special cases */
+   if ((lat_Degrees > 55) && (lat_Degrees < 64) && (long_Degrees > -1)
+       && (long_Degrees < 3))
+      result = 31;
+   if ((lat_Degrees > 55) && (lat_Degrees < 64) && (long_Degrees > 2)
+       && (long_Degrees < 12))
+      result = 32;
+   if ((lat_Degrees > 71) && (long_Degrees > -1) && (long_Degrees < 9))
+      result = 31;
+   if ((lat_Degrees > 71) && (long_Degrees > 8) && (long_Degrees < 21))
+      result = 33;
+   if ((lat_Degrees > 71) && (long_Degrees > 20) && (long_Degrees < 33))
+      result = 35;
+   if ((lat_Degrees > 71) && (long_Degrees > 32) && (long_Degrees < 42))
+      result = 37;
+
+   return result;
+}
+
+double ossimUtmProjection::computeZoneMeridian(long zone)
+{
+   return (6.0 * zone - 183.0);;
+}
+
+bool ossimUtmProjection::operator==(const ossimProjection& projection) const
+{
+   if(ossimMapProjection::operator==(projection))
+   {
+      ossimUtmProjection* utm = PTR_CAST(ossimUtmProjection, &projection);
+      if(utm)
+      {
+         return ((theZone == utm->theZone)&&
+                 (theHemisphere == utm->theHemisphere));
+      }
+   }
+
+   return false;
+}
+
+bool ossimUtmProjection::loadState(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+{
+   const char* zone       = kwl.find(prefix, ossimKeywordNames::ZONE_KW);
+   const char* hemisphere = kwl.find(prefix, ossimKeywordNames::HEMISPHERE_KW);
+   
+   ossimMapProjection::loadState(kwl, prefix);
+
+   // initialize zone to a dummy value.
+   //
+   theZone = OSSIM_LONG_NAN;
+//   if(ossimString(type) == STATIC_TYPE_NAME(ossimUtmProjection))
+   {
+      if(!zone)
+      {
+         theZone = computeZone(theOrigin);
+      }
+      else if (zone) 
+      {
+         theZone = atoi(zone);
+
+         if(theZone  < 1)
+         {
+            theZone = computeZone(theOrigin);
+         }
+         else
+         {
+//            if(!kwl.find(prefix, ossimKeywordNames::CENTRAL_MERIDIAN_KW))
+//            {
+               theOrigin.lond(computeZoneMeridian(theZone));
+//            }
+//            if(!kwl.find(prefix, ossimKeywordNames::ORIGIN_LATITUDE_KW))
+//            {
+               theOrigin.latd(0);
+//            }
+         }
+      }
+      if (hemisphere)
+      {
+         ossimString s = hemisphere;
+         s = s.trim();
+         s = s.upcase();
+         
+         setHemisphere(*s.c_str());
+      }
+      else
+      {
+         char hemisphere = theOrigin.latd()<0?'S':'N';
+         setHemisphere(hemisphere);
+      }
+   }
+
+   update();
+   
+   return true;
+}
+
+bool ossimUtmProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::ZONE_KW,
+           theZone,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::HEMISPHERE_KW,
+           theHemisphere,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);
+}
+   
+long ossimUtmProjection::Set_Transverse_Mercator_Parameters(double a,
+                                                                      double f,
+                                                                      double Origin_Latitude,
+                                                                      double Central_Meridian,
+                                                                      double False_Easting,
+                                                                      double False_Northing,
+                                                                      double Scale_Factor)
+
+{ /* BEGIN Set_Tranverse_Mercator_Parameters */
+  /*
+   * The function Set_Tranverse_Mercator_Parameters receives the ellipsoid
+   * parameters and Tranverse Mercator projection parameters as inputs, and
+   * sets the corresponding state variables. If any errors occur, the error
+   * code(s) are returned by the function, otherwise UTM_NO_ERROR is
+   * returned.
+   *
+   *    a                 : Semi-major axis of ellipsoid, in meters    (input)
+   *    f                 : Flattening of ellipsoid						         (input)
+   *    Origin_Latitude   : Latitude in radians at the origin of the   (input)
+   *                         projection
+   *    Central_Meridian  : Longitude in radians at the center of the  (input)
+   *                         projection
+   *    False_Easting     : Easting/X at the center of the projection  (input)
+   *    False_Northing    : Northing/Y at the center of the projection (input)
+   *    Scale_Factor      : Projection scale factor                    (input) 
+   */
+
+  double tn;        /* True Meridianal distance constant  */
+  double tn2;
+  double tn3;
+  double tn4;
+  double tn5;
+  double dummy_northing;
+  double TranMerc_b; /* Semi-minor axis of ellipsoid, in meters */
+//  double inv_f = 1 / f;
+  long Error_Code = UTM_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= UTM_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= UTM_INV_F_ERROR;
+//   }
+//   if ((Origin_Latitude < -MAX_LAT) || (Origin_Latitude > MAX_LAT))
+//   { /* origin latitude out of range */
+//     Error_Code |= UTM_ORIGIN_LAT_ERROR;
+//   }
+//   if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= UTM_CENT_MER_ERROR;
+//   }
+//   if ((Scale_Factor < MIN_SCALE_FACTOR) || (Scale_Factor > MAX_SCALE_FACTOR))
+//   {
+//     Error_Code |= UTM_SCALE_FACTOR_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    theTranMerc_a = a;
+    theTranMerc_f = f;
+    theTranMerc_Origin_Lat = 0;
+    theTranMerc_Origin_Long = 0;
+    theTranMerc_False_Northing = 0;
+    theTranMerc_False_Easting = 0; 
+    // theTranMerc_Scale_Factor = 1;
+
+    /* Eccentricity Squared */
+    theTranMerc_es = 2 * theTranMerc_f - theTranMerc_f * theTranMerc_f;
+    /* Second Eccentricity Squared */
+    theTranMerc_ebs = (1 / (1 - theTranMerc_es)) - 1;
+
+    TranMerc_b = theTranMerc_a * (1 - theTranMerc_f);    
+    /*True meridianal constants  */
+    tn = (theTranMerc_a - TranMerc_b) / (theTranMerc_a + TranMerc_b);
+    tn2 = tn * tn;
+    tn3 = tn2 * tn;
+    tn4 = tn3 * tn;
+    tn5 = tn4 * tn;
+
+    theTranMerc_ap = theTranMerc_a * (1.e0 - tn + 5.e0 * (tn2 - tn3)/4.e0
+                                + 81.e0 * (tn4 - tn5)/64.e0 );
+    theTranMerc_bp = 3.e0 * theTranMerc_a * (tn - tn2 + 7.e0 * (tn3 - tn4)
+                                       /8.e0 + 55.e0 * tn5/64.e0 )/2.e0;
+    theTranMerc_cp = 15.e0 * theTranMerc_a * (tn2 - tn3 + 3.e0 * (tn4 - tn5 )/4.e0) /16.0;
+    theTranMerc_dp = 35.e0 * theTranMerc_a * (tn3 - tn4 + 11.e0 * tn5 / 16.e0) / 48.e0;
+    theTranMerc_ep = 315.e0 * theTranMerc_a * (tn4 - tn5) / 512.e0;
+    Convert_Geodetic_To_Transverse_Mercator(MAX_LAT,
+                                            MAX_DELTA_LONG,
+                                            &theTranMerc_Delta_Easting,
+                                            &theTranMerc_Delta_Northing);
+    Convert_Geodetic_To_Transverse_Mercator(0,
+                                            MAX_DELTA_LONG,
+                                            &theTranMerc_Delta_Easting,
+                                            &dummy_northing);
+    theTranMerc_Origin_Lat = Origin_Latitude;
+    if (Central_Meridian > M_PI)
+      Central_Meridian -= TWO_PI;
+    theTranMerc_Origin_Long = Central_Meridian;
+    theTranMerc_False_Northing = False_Northing;
+    theTranMerc_False_Easting = False_Easting; 
+    // theTranMerc_Scale_Factor = Scale_Factor;
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+}  /* END of Set_Transverse_Mercator_Parameters  */
+
+
+void ossimUtmProjection::Get_Transverse_Mercator_Parameters(double *a,
+                                                                      double *f,
+                                                                      double *Origin_Latitude,
+                                                                      double *Central_Meridian,
+                                                                      double *False_Easting,
+                                                                      double *False_Northing,
+                                                                      double *Scale_Factor)const
+
+{ /* BEGIN Get_Tranverse_Mercator_Parameters  */
+  /*
+   * The function Get_Transverse_Mercator_Parameters returns the current
+   * ellipsoid and Transverse Mercator projection parameters.
+   *
+   *    a                 : Semi-major axis of ellipsoid, in meters    (output)
+   *    f                 : Flattening of ellipsoid						         (output)
+   *    Origin_Latitude   : Latitude in radians at the origin of the   (output)
+   *                         projection
+   *    Central_Meridian  : Longitude in radians at the center of the  (output)
+   *                         projection
+   *    False_Easting     : Easting/X at the center of the projection  (output)
+   *    False_Northing    : Northing/Y at the center of the projection (output)
+   *    Scale_Factor      : Projection scale factor                    (output) 
+   */
+
+  *a = theTranMerc_a;
+  *f = theTranMerc_f;
+  *Origin_Latitude = theTranMerc_Origin_Lat;
+  *Central_Meridian = theTranMerc_Origin_Long;
+  *False_Easting = theTranMerc_False_Easting;
+  *False_Northing = theTranMerc_False_Northing;
+  *Scale_Factor = theTranMerc_Scale_Factor;
+  
+  return;
+} /* END OF Get_Tranverse_Mercator_Parameters */
+
+
+
+long ossimUtmProjection::Convert_Geodetic_To_Transverse_Mercator (double Latitude,
+                                                                            double Longitude,
+                                                                            double *Easting,
+                                                                            double *Northing)const
+   
+{      /* BEGIN Convert_Geodetic_To_Transverse_Mercator */
+
+  /*
+   * The function Convert_Geodetic_To_Transverse_Mercator converts geodetic
+   * (latitude and longitude) coordinates to Transverse Mercator projection
+   * (easting and northing) coordinates, according to the current ellipsoid
+   * and Transverse Mercator projection coordinates.  If any errors occur, the
+   * error code(s) are returned by the function, otherwise UTM_NO_ERROR is
+   * returned.
+   *
+   *    Latitude      : Latitude in radians                         (input)
+   *    Longitude     : Longitude in radians                        (input)
+   *    Easting       : Easting/X in meters                         (output)
+   *    Northing      : Northing/Y in meters                        (output)
+   */
+
+  double c;       /* Cosine of latitude                          */
+  double c2;
+  double c3;
+  double c5;
+  double c7;
+  double dlam;    /* Delta longitude - Difference in Longitude       */
+  double eta;     /* constant - theTranMerc_ebs *c *c                   */
+  double eta2;
+  double eta3;
+  double eta4;
+  double s;       /* Sine of latitude                        */
+  double sn;      /* Radius of curvature in the prime vertical       */
+  double t;       /* Tangent of latitude                             */
+  double tan2;
+  double tan3;
+  double tan4;
+  double tan5;
+  double tan6;
+  double t1;      /* Term in coordinate conversion formula - GP to Y */
+  double t2;      /* Term in coordinate conversion formula - GP to Y */
+  double t3;      /* Term in coordinate conversion formula - GP to Y */
+  double t4;      /* Term in coordinate conversion formula - GP to Y */
+  double t5;      /* Term in coordinate conversion formula - GP to Y */
+  double t6;      /* Term in coordinate conversion formula - GP to Y */
+  double t7;      /* Term in coordinate conversion formula - GP to Y */
+  double t8;      /* Term in coordinate conversion formula - GP to Y */
+  double t9;      /* Term in coordinate conversion formula - GP to Y */
+  double tmd;     /* True Meridional distance                        */
+  double tmdo;    /* True Meridional distance for latitude of origin */
+  long    Error_Code = UTM_NO_ERROR;
+//  double temp_Origin;
+//  double temp_Long;
+
+//   if ((Latitude < -MAX_LAT) || (Latitude > MAX_LAT))
+//   {  /* Latitude out of range */
+//     Error_Code|= UTM_LAT_ERROR;
+//   }
+   if (Longitude > M_PI)
+     Longitude -= TWO_PI;
+//   if ((Longitude < (theTranMerc_Origin_Long - MAX_DELTA_LONG))
+//       || (Longitude > (theTranMerc_Origin_Long + MAX_DELTA_LONG)))
+//   {
+//     if (Longitude < 0)
+//       temp_Long = Longitude + TWO_PI;
+//     else
+//       temp_Long = Longitude;
+//     if (theTranMerc_Origin_Long < 0)
+//       temp_Origin = theTranMerc_Origin_Long + TWO_PI;
+//     else
+//       temp_Origin = theTranMerc_Origin_Long;
+//     if ((temp_Long < (temp_Origin - MAX_DELTA_LONG))
+//         || (temp_Long > (temp_Origin + MAX_DELTA_LONG)))
+//       Error_Code|= UTM_LON_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+
+    /* 
+     *  Delta Longitude
+     */
+    dlam = Longitude - theTranMerc_Origin_Long;
+
+//     if (fabs(dlam) > (9.0 * M_PI / 180))
+//     { /* Distortion will result if Longitude is more than 9 degrees from the Central Meridian */
+//       Error_Code |= UTM_LON_WARNING;
+//     }
+
+     if (dlam > M_PI)
+       dlam -= TWO_PI;
+     if (dlam < -M_PI)
+       dlam += TWO_PI;
+     if (fabs(dlam) < 2.e-10)
+       dlam = 0.0;
+
+    s = sin(Latitude);
+    c = cos(Latitude);
+    c2 = c * c;
+    c3 = c2 * c;
+    c5 = c3 * c2;
+    c7 = c5 * c2;
+    t = tan (Latitude);
+    tan2 = t * t;
+    tan3 = tan2 * t;
+    tan4 = tan3 * t;
+    tan5 = tan4 * t;
+    tan6 = tan5 * t;
+    eta = theTranMerc_ebs * c2;
+    eta2 = eta * eta;
+    eta3 = eta2 * eta;
+    eta4 = eta3 * eta;
+
+    /* radius of curvature in prime vertical */
+    sn = SPHSN(Latitude);
+
+    /* True Meridianal Distances */
+    tmd = SPHTMD(Latitude);
+
+    /*  Origin  */
+    tmdo = SPHTMD (theTranMerc_Origin_Lat);
+
+    /* northing */
+    t1 = (tmd - tmdo) * theTranMerc_Scale_Factor;
+    t2 = sn * s * c * theTranMerc_Scale_Factor/ 2.e0;
+    t3 = sn * s * c3 * theTranMerc_Scale_Factor * (5.e0 - tan2 + 9.e0 * eta 
+                                                + 4.e0 * eta2) /24.e0; 
+
+    t4 = sn * s * c5 * theTranMerc_Scale_Factor * (61.e0 - 58.e0 * tan2
+                                                + tan4 + 270.e0 * eta - 330.e0 * tan2 * eta + 445.e0 * eta2
+                                                + 324.e0 * eta3 -680.e0 * tan2 * eta2 + 88.e0 * eta4 
+                                                -600.e0 * tan2 * eta3 - 192.e0 * tan2 * eta4) / 720.e0;
+
+    t5 = sn * s * c7 * theTranMerc_Scale_Factor * (1385.e0 - 3111.e0 * 
+                                                tan2 + 543.e0 * tan4 - tan6) / 40320.e0;
+
+    *Northing = theTranMerc_False_Northing + t1 + pow(dlam,2.e0) * t2
+                + pow(dlam,4.e0) * t3 + pow(dlam,6.e0) * t4
+                + pow(dlam,8.e0) * t5; 
+
+    /* Easting */
+    t6 = sn * c * theTranMerc_Scale_Factor;
+    t7 = sn * c3 * theTranMerc_Scale_Factor * (1.e0 - tan2 + eta ) /6.e0;
+    t8 = sn * c5 * theTranMerc_Scale_Factor * (5.e0 - 18.e0 * tan2 + tan4
+                                            + 14.e0 * eta - 58.e0 * tan2 * eta + 13.e0 * eta2 + 4.e0 * eta3 
+                                            - 64.e0 * tan2 * eta2 - 24.e0 * tan2 * eta3 )/ 120.e0;
+    t9 = sn * c7 * theTranMerc_Scale_Factor * ( 61.e0 - 479.e0 * tan2
+                                             + 179.e0 * tan4 - tan6 ) /5040.e0;
+
+    *Easting = theTranMerc_False_Easting + dlam * t6 + pow(dlam,3.e0) * t7 
+               + pow(dlam,5.e0) * t8 + pow(dlam,7.e0) * t9;
+  }
+  return (Error_Code);
+} /* END OF Convert_Geodetic_To_Transverse_Mercator */
+
+
+long ossimUtmProjection::Convert_Transverse_Mercator_To_Geodetic (double Easting,
+                                                                            double Northing,
+                                                                            double *Latitude,
+                                                                            double *Longitude)const
+{      /* BEGIN Convert_Transverse_Mercator_To_Geodetic */
+
+  /*
+   * The function Convert_Transverse_Mercator_To_Geodetic converts Transverse
+   * Mercator projection (easting and northing) coordinates to geodetic
+   * (latitude and longitude) coordinates, according to the current ellipsoid
+   * and Transverse Mercator projection parameters.  If any errors occur, the
+   * error code(s) are returned by the function, otherwise UTM_NO_ERROR is
+   * returned.
+   *
+   *    Easting       : Easting/X in meters                         (input)
+   *    Northing      : Northing/Y in meters                        (input)
+   *    Latitude      : Latitude in radians                         (output)
+   *    Longitude     : Longitude in radians                        (output)
+   */
+
+  double c;       /* Cosine of latitude                          */
+  double de;      /* Delta easting - Difference in Easting (Easting-Fe)    */
+  double dlam;    /* Delta longitude - Difference in Longitude       */
+  double eta;     /* constant - theTranMerc_ebs *c *c                   */
+  double eta2;
+  double eta3;
+  double eta4;
+  double ftphi;   /* Footpoint latitude                              */
+  int    i;       /* Loop iterator                   */
+  double s;       /* Sine of latitude                        */
+  double sn;      /* Radius of curvature in the prime vertical       */
+  double sr;      /* Radius of curvature in the meridian             */
+  double t;       /* Tangent of latitude                             */
+  double tan2;
+  double tan4;
+  double t10;     /* Term in coordinate conversion formula - GP to Y */
+  double t11;     /* Term in coordinate conversion formula - GP to Y */
+  double t12;     /* Term in coordinate conversion formula - GP to Y */
+  double t13;     /* Term in coordinate conversion formula - GP to Y */
+  double t14;     /* Term in coordinate conversion formula - GP to Y */
+  double t15;     /* Term in coordinate conversion formula - GP to Y */
+  double t16;     /* Term in coordinate conversion formula - GP to Y */
+  double t17;     /* Term in coordinate conversion formula - GP to Y */
+  double tmd;     /* True Meridional distance                        */
+  double tmdo;    /* True Meridional distance for latitude of origin */
+  long Error_Code = UTM_NO_ERROR;
+
+//   if ((Easting < (theTranMerc_False_Easting - theTranMerc_Delta_Easting))
+//       ||(Easting > (theTranMerc_False_Easting + theTranMerc_Delta_Easting)))
+//   { /* Easting out of range  */
+//     Error_Code |= UTM_EASTING_ERROR;
+//   }
+//   if ((Northing < (theTranMerc_False_Northing - theTranMerc_Delta_Northing))
+//       || (Northing > (theTranMerc_False_Northing + theTranMerc_Delta_Northing)))
+//   { /* Northing out of range */
+//     Error_Code |= UTM_NORTHING_ERROR;
+//   }
+
+  if (!Error_Code)
+  {
+    /* True Meridional Distances for latitude of origin */
+    tmdo = SPHTMD(theTranMerc_Origin_Lat);
+
+    /*  Origin  */
+    tmd = tmdo +  (Northing - theTranMerc_False_Northing) / theTranMerc_Scale_Factor; 
+
+    /* First Estimate */
+    sr = SPHSR(0.e0);
+    ftphi = tmd/sr;
+
+    for (i = 0; i < 5 ; i++)
+    {
+      t10 = SPHTMD (ftphi);
+      sr = SPHSR(ftphi);
+      ftphi = ftphi + (tmd - t10) / sr;
+    }
+
+    /* Radius of Curvature in the meridian */
+    sr = SPHSR(ftphi);
+
+    /* Radius of Curvature in the meridian */
+    sn = SPHSN(ftphi);
+
+    /* Sine Cosine terms */
+    s = sin(ftphi);
+    c = cos(ftphi);
+
+    /* Tangent Value  */
+    t = tan(ftphi);
+    tan2 = t * t;
+    tan4 = tan2 * tan2;
+    eta = theTranMerc_ebs * pow(c,2);
+    eta2 = eta * eta;
+    eta3 = eta2 * eta;
+    eta4 = eta3 * eta;
+    de = Easting - theTranMerc_False_Easting;
+    if (fabs(de) < 0.0001)
+      de = 0.0;
+
+    /* Latitude */
+    t10 = t / (2.e0 * sr * sn * pow(theTranMerc_Scale_Factor, 2));
+    t11 = t * (5.e0  + 3.e0 * tan2 + eta - 4.e0 * pow(eta,2)
+               - 9.e0 * tan2 * eta) / (24.e0 * sr * pow(sn,3) 
+                                       * pow(theTranMerc_Scale_Factor,4));
+    t12 = t * (61.e0 + 90.e0 * tan2 + 46.e0 * eta + 45.E0 * tan4
+               - 252.e0 * tan2 * eta  - 3.e0 * eta2 + 100.e0 
+               * eta3 - 66.e0 * tan2 * eta2 - 90.e0 * tan4
+               * eta + 88.e0 * eta4 + 225.e0 * tan4 * eta2
+               + 84.e0 * tan2* eta3 - 192.e0 * tan2 * eta4)
+          / ( 720.e0 * sr * pow(sn,5) * pow(theTranMerc_Scale_Factor, 6) );
+    t13 = t * ( 1385.e0 + 3633.e0 * tan2 + 4095.e0 * tan4 + 1575.e0 
+                * pow(t,6))/ (40320.e0 * sr * pow(sn,7) * pow(theTranMerc_Scale_Factor,8));
+    *Latitude = ftphi - pow(de,2) * t10 + pow(de,4) * t11 - pow(de,6) * t12 
+                + pow(de,8) * t13;
+
+    t14 = 1.e0 / (sn * c * theTranMerc_Scale_Factor);
+
+    t15 = (1.e0 + 2.e0 * tan2 + eta) / (6.e0 * pow(sn,3) * c * 
+                                        pow(theTranMerc_Scale_Factor,3));
+
+    t16 = (5.e0 + 6.e0 * eta + 28.e0 * tan2 - 3.e0 * eta2
+           + 8.e0 * tan2 * eta + 24.e0 * tan4 - 4.e0 
+           * eta3 + 4.e0 * tan2 * eta2 + 24.e0 
+           * tan2 * eta3) / (120.e0 * pow(sn,5) * c  
+                             * pow(theTranMerc_Scale_Factor,5));
+
+    t17 = (61.e0 +  662.e0 * tan2 + 1320.e0 * tan4 + 720.e0 
+           * pow(t,6)) / (5040.e0 * pow(sn,7) * c 
+                          * pow(theTranMerc_Scale_Factor,7));
+
+    /* Difference in Longitude */
+    dlam = de * t14 - pow(de,3) * t15 + pow(de,5) * t16 - pow(de,7) * t17;
+
+    /* Longitude */
+    (*Longitude) = theTranMerc_Origin_Long + dlam;
+    while (*Latitude > (90.0 * RAD_PER_DEG))
+    {
+      *Latitude = M_PI - *Latitude;
+      *Longitude += M_PI;
+      if (*Longitude > M_PI)
+        *Longitude -= TWO_PI;
+    }
+
+     while (*Latitude < (-90.0 * RAD_PER_DEG))
+     {
+       *Latitude = - (*Latitude + M_PI);
+       *Longitude += M_PI;
+       if (*Longitude > M_PI)
+         *Longitude -= TWO_PI;
+     }
+     if (*Longitude > TWO_PI)
+       *Longitude -= TWO_PI;
+     if (*Longitude < -M_PI)
+       *Longitude += TWO_PI;
+
+//     if (fabs(dlam) > (9.0 * M_PI / 180))
+//     { /* Distortion will result if Longitude is more than 9 degrees from the Central Meridian */
+//       Error_Code |= UTM_LON_WARNING;
+//     }
+  }
+  return (Error_Code);
+} /* END OF Convert_Transverse_Mercator_To_Geodetic */
+
+std::ostream& ossimUtmProjection::print(std::ostream& out) const
+{
+   out << setiosflags(ios::fixed) << setprecision(15)
+       << "// ossimUtmProjection::print"
+       << "\ntheZone:  " << theZone
+       << "\ntheHemisphere:  " << theHemisphere
+       << endl;
+   return ossimMapProjection::print(out);
+}
+
+double ossimUtmProjection::getFalseEasting() const
+{
+   return theTranMerc_False_Easting;
+}
+
+double ossimUtmProjection::getFalseNorthing() const
+{
+   return theTranMerc_False_Northing;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmProjection.h
new file mode 100644
index 0000000000..42ca953528
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmProjection.h
@@ -0,0 +1,209 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Calls Geotrans Utm projection code.  
+//*******************************************************************
+//  $Id: ossimUtmProjection.h,v 1.18 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimUtmProjection_HEADER
+#define ossimUtmProjection_HEADER
+#include <projections/map_projections/ossimMapProjection.h>
+
+class OSSIMDLLEXPORT ossimUtmProjection : public ossimMapProjection
+{
+public:
+   ossimUtmProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                      const ossimGpt& origin = ossimGpt());
+   
+   ossimUtmProjection(const ossimEllipsoid& ellipsoid,
+                      const ossimGpt& origin,
+                      long zone,
+                      char hemisphere);
+   ossimUtmProjection(long zone);
+   ossimUtmProjection(const ossimUtmProjection& src);
+   
+   virtual ossimObject* dup()const;
+
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();
+   void setZone(const ossimGpt& ground);
+   void setZone(long zone);
+   void setHemisphere(char hemisphere);
+   static long computeZone(const ossimGpt& gpt);
+
+   /**
+    * Return in decimal degrees the zone meridian.
+    */
+   static double computeZoneMeridian(long zone);
+
+   long getZone()const;
+
+   char getHemisphere()const;
+   
+   virtual bool operator==(const ossimProjection& projection) const;
+
+   /**
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+   
+   /**
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /**
+    * Prints data members to stream.  Returns stream&.
+    */
+   virtual std::ostream& print(std::ostream& out) const;   
+
+   /**
+    * @return The false easting.
+    */
+   virtual double getFalseEasting() const;
+
+   /**
+    * @return The false northing.
+    */
+   virtual double getFalseNorthing() const;
+
+private:
+   /*_____________GEOTRANS_______________*/
+   
+   /**
+    * The function Set_Tranverse_Mercator_Parameters receives the ellipsoid
+    * parameters and Tranverse Mercator projection parameters as inputs, and
+    * sets the corresponding state variables. If any errors occur, the error
+    * code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+    * returned.
+    *
+    * a                 : Semi-major axis of ellipsoid, in meters    (input)
+    * f                 : Flattening of ellipsoid                    (input)
+    * Origin_Latitude   : Latitude in radians at the origin of the   (input)
+    *                      projection
+    * Central_Meridian  : Longitude in radians at the center of the  (input)
+    *                      projection
+    * False_Easting     : Easting/X at the center of the projection  (input)
+    * False_Northing    : Northing/Y at the center of the projection (input)
+    * Scale_Factor      : Projection scale factor                    (input) 
+    */
+   long Set_Transverse_Mercator_Parameters(double a,      
+                                           double f,
+                                           double Origin_Latitude,
+                                           double Central_Meridian,
+                                           double False_Easting,
+                                           double False_Northing,
+                                           double Scale_Factor);
+   /**
+    * The function Get_Transverse_Mercator_Parameters returns the current
+    * ellipsoid and Transverse Mercator projection parameters.
+    *
+    * a                 : Semi-major axis of ellipsoid, in meters    (output)
+    * f                 : Flattening of ellipsoid                    (output)
+    * Origin_Latitude   : Latitude in radians at the origin of the   (output)
+    *                      projection
+    * Central_Meridian  : Longitude in radians at the center of the  (output)
+    *                      projection
+    * False_Easting     : Easting/X at the center of the projection  (output)
+    * False_Northing    : Northing/Y at the center of the projection (output)
+    * Scale_Factor      : Projection scale factor                    (output) 
+    */
+   void Get_Transverse_Mercator_Parameters(double *a,
+                                           double *f,
+                                           double *Origin_Latitude,
+                                           double *Central_Meridian,
+                                           double *False_Easting,
+                                           double *False_Northing,
+                                           double *Scale_Factor)const;
+   
+   
+   /**
+    * The function Convert_Geodetic_To_Transverse_Mercator converts geodetic
+    * (latitude and longitude) coordinates to Transverse Mercator projection
+    * (easting and northing) coordinates, according to the current ellipsoid
+    * and Transverse Mercator projection coordinates.  If any errors occur, the
+    * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+    * returned.
+    *
+    * Latitude      : Latitude in radians                         (input)
+    * Longitude     : Longitude in radians                        (input)
+    * Easting       : Easting/X in meters                         (output)
+    * Northing      : Northing/Y in meters                        (output)
+    */
+   long Convert_Geodetic_To_Transverse_Mercator (double Latitude,
+                                                 double Longitude,
+                                                 double *Easting,
+                                                 double *Northing)const;
+   
+   
+   /**
+    * The function Convert_Transverse_Mercator_To_Geodetic converts Transverse
+    * Mercator projection (easting and northing) coordinates to geodetic
+    * (latitude and longitude) coordinates, according to the current ellipsoid
+    * and Transverse Mercator projection parameters.  If any errors occur, the
+    * error code(s) are returned by the function, otherwise TRANMERC_NO_ERROR is
+    * returned.
+    *
+    *    Easting       : Easting/X in meters                         (input)
+    *    Northing      : Northing/Y in meters                        (input)
+    *    Latitude      : Latitude in radians                         (output)
+    *    Longitude     : Longitude in radians                        (output)
+    */
+   long Convert_Transverse_Mercator_To_Geodetic (double Easting,
+                                                 double Northing,
+                                                 double *Latitude,
+                                                 double *Longitude)const;
+   
+   double theTranMerc_a;  /* Semi-major axis of ellipsoid i meters */
+   double theTranMerc_f;  /* Flattening of ellipsoid  */
+   
+   /* Eccentricity (0.08181919084262188000) squared */
+   double theTranMerc_es;
+   
+   double theTranMerc_ebs;   /* Second Eccentricity squared */
+   
+   /* Transverse_Mercator projection Parameters */
+   
+   double theTranMerc_Origin_Lat;     /* Latitude of origin in radians */
+   double theTranMerc_Origin_Long;    /* Longitude of origin in radians */
+   double theTranMerc_False_Northing; /* False northing in meters */
+   double theTranMerc_False_Easting;  /* False easting in meters */
+   double theTranMerc_Scale_Factor;   /* Scale factor  */
+   
+   /* Isometeric to geodetic latitude parameters, default to WGS 84 */
+   double theTranMerc_ap;
+   double theTranMerc_bp;
+   double theTranMerc_cp;
+   double theTranMerc_dp;
+   double theTranMerc_ep;
+   
+   /* Maximum variance for easting and northing values for WGS 84. */
+   double theTranMerc_Delta_Easting;
+   double theTranMerc_Delta_Northing;  
+   
+   /** 
+    * zone can be from 1 through 59
+    */
+   long   theZone;
+   
+   /**
+    * can be N or S.
+    */
+   char   theHemisphere;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmpt.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmpt.cpp
new file mode 100644
index 0000000000..0ab60fed04
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmpt.cpp
@@ -0,0 +1,88 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// This is the Universal Transverse Mercator (UTM) point.  Allows
+// easy onversion between different coordinates.
+//*******************************************************************
+//  $Id: ossimUtmpt.cpp,v 1.5 2005/10/18 12:26:46 gpotts Exp $
+
+#include "ossimUtmpt.h"
+#include "base/data_types/ossimGpt.h"
+#include "base/data_types/ossimEcefPoint.h"
+#include "base/data_types/datum/ossimDatum.h"
+#include "base/data_types/ellipse/ossimEllipsoid.h"
+#include "projections/map_projections/ossimUtm.h"
+
+ossimUtmpt::ossimUtmpt(const ossimGpt &aPt)
+{
+   convertFromGround(aPt);
+}
+
+ossimUtmpt::ossimUtmpt(const ossimEcefPoint &aPt)
+{
+   convertFromGround(ossimGpt(aPt));
+}
+
+ossimUtmpt::ossimUtmpt(long         zone,
+                       char         hemisphere,  // N or S
+                       double       easting,
+                       double       northing,
+                       const ossimDatum* datum)
+   :
+      theZone       (zone),
+      theHemisphere (hemisphere),
+      theEasting    (easting),
+      theNorthing   (northing),
+      theDatum      (datum)
+{}
+
+void ossimUtmpt::convertFromGround(const ossimGpt &aPt)
+{
+   const ossimDatum *aDatum = aPt.datum();
+
+   if(aDatum)
+   {
+      //call Geotrans init code
+      Set_UTM_Parameters(aDatum->ellipsoid()->a(), aDatum->ellipsoid()->flattening(), 0);
+      Convert_Geodetic_To_UTM(aPt.latr(),
+                              aPt.lonr(),
+                              &theZone,
+                              &theHemisphere,
+                              &theEasting,
+                              &theNorthing);
+      theDatum = aDatum;
+   }
+   else
+   {
+      //ERROR: Should never happen
+   }
+}
+
+void ossimUtmpt::convertToGround(ossimGpt &aPt)
+{
+   Set_UTM_Parameters( theDatum->ellipsoid()->a(),
+                       theDatum->ellipsoid()->flattening(),
+                       0 );
+   
+   double latitude  = 0.0;
+   double longitude = 0.0;
+
+   Convert_UTM_To_Geodetic( zone(),
+                            hemisphere(),
+                            easting(),
+                            northing(),
+                            &latitude,
+                            &longitude );
+
+   aPt.latr(latitude);
+   aPt.lonr(longitude);
+   aPt.datum(theDatum);
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmpt.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmpt.h
new file mode 100644
index 0000000000..23894f1a9a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimUtmpt.h
@@ -0,0 +1,89 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// This is the Universal Transverse Mercator (UTM) point.  Allows
+// easy onversion between different coordinates.
+//*******************************************************************
+//  $Id: ossimUtmpt.h,v 1.5 2004/08/26 21:02:33 dburken Exp $
+#ifndef ossimUtmpt_HEADER
+#define ossimUtmpt_HEADER
+
+#include <base/common/ossimConstants.h>
+
+class ossimGpt;
+class ossimEcefPoint;
+class ossimUpspt;
+class ossimDatum;
+
+class OSSIMDLLEXPORT ossimUtmpt
+{
+public:
+   ossimUtmpt(const ossimGpt &aPt);
+   ossimUtmpt(const ossimEcefPoint &aPt);
+   ossimUtmpt(long         zone,
+              char         hemisphere,  // N or S
+              double       easting,
+              double       northing,
+              const ossimDatum* datum);
+   
+   // ossimUtmpt(const ossimUpspt &aPt);
+
+   /**
+    * Return the zone for this utm point.
+    */
+   long zone() const { return theZone; }
+
+   /**
+    * Return the hemisphere ( Northern or Southern).
+    * We store this as a char value N or S.  We store it
+    * like this because we are interfacing to geotrans
+    * and geotrans stores their values in this manner.
+    */
+   char hemisphere() const { return theHemisphere; }
+
+   /**
+    * return the easting value in meters.
+    */
+   double easting() const { return theEasting; }
+
+   /**
+    * return the northing value in meters.
+    */
+   double northing() const { return theNorthing; }
+
+   /**
+    * return the reference datum for this point.
+    */
+   const ossimDatum* datum() const { return theDatum; }
+
+   /**
+    * Initializes this point to utm coordinates for the ground point.
+    *
+    * @param aPt Ground point to initialize from.
+    */
+   void convertFromGround(const ossimGpt &aPt);
+
+   /**
+    * Initializes the ground point from the utm coordinates of this point.
+    *
+    * @param aPt Ground point to initialize.
+    */
+   void convertToGround(ossimGpt &aPt);
+   
+private:
+   long               theZone;
+   char               theHemisphere;
+   double             theEasting;
+   double             theNorthing;
+   const ossimDatum*  theDatum;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimVanDerGrintenProjection.cpp b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimVanDerGrintenProjection.cpp
new file mode 100644
index 0000000000..1dfe423fc9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimVanDerGrintenProjection.cpp
@@ -0,0 +1,529 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Grinten projection code.  
+//*******************************************************************
+//  $Id: ossimVanDerGrintenProjection.cpp,v 1.11 2004/01/08 21:49:22 jlargent Exp $
+#include "ossimVanDerGrintenProjection.h"
+#include "base/common/ossimKeywordNames.h"
+
+RTTI_DEF1(ossimVanDerGrintenProjection, "ossimVanDerGrintenProjection", ossimMapProjection)
+   
+/***************************************************************************/
+/*
+ *                               DEFINES
+ */
+
+#ifndef PI_OVER_2
+#  define PI_OVER_2  ( M_PI / 2.0)
+#endif
+#ifndef TWO_PI
+#  define TWO_PI     (2.0 * M_PI)
+#endif
+
+#define MAX_LAT     ( 90.0 * (M_PI / 180.0) )  /* 90 degrees in radians   */
+#define FLOAT_EQ(x,v,epsilon)   (((v - epsilon) < x) && (x < (v + epsilon)))
+
+#define GRIN_NO_ERROR           0x0000
+#define GRIN_LAT_ERROR          0x0001
+#define GRIN_LON_ERROR          0x0002
+#define GRIN_EASTING_ERROR      0x0004
+#define GRIN_NORTHING_ERROR     0x0008
+#define GRIN_CENT_MER_ERROR     0x0020
+#define GRIN_A_ERROR            0x0040
+#define GRIN_B_ERROR            0x0080
+#define GRIN_A_LESS_B_ERROR     0x0100
+#define GRIN_RADIUS_ERROR		  0x0200
+
+/***************************************************************************/
+/*
+ *                               GLOBALS
+ */
+
+const double TWO_OVER_PI = (2.0 / M_PI);
+const double PI_OVER_3 = (M_PI / 3.0);
+const double ONE_THIRD  = (1.0 / 3.0);
+
+
+ossimVanDerGrintenProjection::ossimVanDerGrintenProjection(const ossimEllipsoid& ellipsoid,
+                                                           const ossimGpt& origin)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   setDefaults();
+   update();
+}
+
+ossimVanDerGrintenProjection::ossimVanDerGrintenProjection(const ossimEllipsoid& ellipsoid,
+                                                   const ossimGpt& origin,
+                                                   double falseEasting,
+                                                   double falseNorthing)
+   :ossimMapProjection(ellipsoid, origin)
+{
+   Grin_False_Easting  = falseEasting;
+   Grin_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimVanDerGrintenProjection::update()
+{   
+   Set_Van_der_Grinten_Parameters(theEllipsoid.getA(),
+                                  theEllipsoid.getFlattening(),
+                                  theOrigin.lonr(),
+                                  Grin_False_Easting,
+                                  Grin_False_Northing);
+
+   ossimMapProjection::update();
+}
+
+void ossimVanDerGrintenProjection::setFalseEasting(double falseEasting)
+{
+   Grin_False_Easting = falseEasting;
+   
+   update();
+}
+
+void ossimVanDerGrintenProjection::setFalseNorthing(double falseNorthing)
+{
+   Grin_False_Northing = falseNorthing;
+   
+   update();
+}
+
+void ossimVanDerGrintenProjection::setDefaults()
+{
+   Grin_False_Easting  = 0.0;
+   Grin_False_Northing = 0.0;
+}
+
+void ossimVanDerGrintenProjection::setFalseEastingNorthing(double falseEasting,
+                                                           double falseNorthing)
+{
+   Grin_False_Easting  = falseEasting;
+   Grin_False_Northing = falseNorthing;
+   
+   update();
+}
+
+ossimGpt ossimVanDerGrintenProjection::inverse(const ossimDpt &eastingNorthing)const
+{
+   double lat = 0.0;
+   double lon = 0.0;
+   
+   Convert_Van_der_Grinten_To_Geodetic(eastingNorthing.x,
+                                       eastingNorthing.y,
+                                       &lat,
+                                       &lon);
+   
+   return ossimGpt(lat*DEG_PER_RAD, lon*DEG_PER_RAD, 0.0, theDatum);  
+}
+
+ossimDpt ossimVanDerGrintenProjection::forward(const ossimGpt &latLon)const
+{
+   double easting  = 0.0;
+   double northing = 0.0;
+   ossimGpt gpt = latLon;
+   
+   if (theDatum)
+   {
+      if (theDatum->code() != latLon.datum()->code())
+      {
+         gpt.changeDatum(theDatum); // Shift to our datum.
+      }
+   }
+
+   Convert_Geodetic_To_Van_der_Grinten(gpt.latr(),
+                                       gpt.lonr(),
+                                       &easting,
+                                       &northing);
+   return ossimDpt(easting, northing);
+}
+
+bool ossimVanDerGrintenProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           Grin_False_Easting,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           Grin_False_Northing,
+           true);
+   
+   return ossimMapProjection::saveState(kwl, prefix);   
+}
+
+bool ossimVanDerGrintenProjection::loadState(const ossimKeywordlist& kwl,
+                                             const char* prefix)
+{
+   bool flag = ossimMapProjection::loadState(kwl, prefix);
+   const char* type          = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   const char* falseEasting  = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
+   const char* falseNorthing = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
+   
+   setDefaults();
+   if(ossimString(type) == STATIC_TYPE_NAME(ossimVanDerGrintenProjection))
+   {
+      if(falseEasting)
+      {
+         Grin_False_Easting = ossimString(falseEasting).toDouble();
+      }
+      if(falseNorthing)
+      {
+         Grin_False_Northing = ossimString(falseNorthing).toDouble();
+      }
+   }
+   
+   update();
+
+   return flag;
+
+}
+
+/***************************************************************************/
+/*
+ *                              FUNCTIONS
+ */
+
+
+long ossimVanDerGrintenProjection::Set_Van_der_Grinten_Parameters(double a,
+                                                                  double f,
+                                                                  double Central_Meridian,
+                                                                  double False_Easting,
+                                                                  double False_Northing)
+
+{ /* BEGIN Set_Van_der_Grinten_Parameters */
+/*
+ * The function Set_Van_der_Grinten_Parameters receives the ellipsoid parameters and
+ * projection parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, 
+ * otherwise Grin_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid							      (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+
+//  double inv_f = 1 / f;
+  long Error_Code = GRIN_NO_ERROR;
+
+//   if (a <= 0.0)
+//   { /* Semi-major axis must be greater than zero */
+//     Error_Code |= GRIN_A_ERROR;
+//   }
+//   if ((inv_f < 250) || (inv_f > 350))
+//   { /* Inverse flattening must be between 250 and 350 */
+//     Error_Code |= GRIN_INV_F_ERROR;
+//   }
+//   if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
+//   { /* origin longitude out of range */
+//     Error_Code |= GRIN_CENT_MER_ERROR;
+//   }
+  if (!Error_Code)
+  { /* no errors */
+    Grin_a = a;
+    Grin_f = f;
+    es2 = 2 * Grin_f - Grin_f * Grin_f;
+    es4 = es2 * es2;
+    es6 = es4 * es2;
+    /* spherical radius */
+    Ra = Grin_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 /3024.0);
+    PI_Ra = M_PI * Ra;
+//     if (Central_Meridian > M_PI)
+//       Central_Meridian -= TWO_PI;
+    Grin_Origin_Long    = Central_Meridian;
+    Grin_False_Easting  = False_Easting;
+    Grin_False_Northing = False_Northing;
+
+  } /* END OF if(!Error_Code) */
+  return (Error_Code);
+} /* END OF Set_Van_der_Grinten_Parameters */
+
+
+void ossimVanDerGrintenProjection::Get_Van_der_Grinten_Parameters(double *a,
+                                                                  double *f,
+                                                                  double *Central_Meridian,
+                                                                  double *False_Easting,
+                                                                  double *False_Northing)const
+
+{ /* BEGIN Get_Van_der_Grinten_Parameters */
+/*
+ * The function Get_Van_der_Grinten_Parameters returns the current ellipsoid
+ * parameters, and Van Der Grinten projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output)
+ */
+
+  *a = Grin_a;
+  *f = Grin_f;
+  *Central_Meridian = Grin_Origin_Long;
+  *False_Easting = Grin_False_Easting;
+  *False_Northing = Grin_False_Northing;
+  
+  return;
+} /* END OF Get_Van_der_Grinten_Parameters */
+
+
+long ossimVanDerGrintenProjection::Convert_Geodetic_To_Van_der_Grinten (double Latitude,
+                                                                        double Longitude,
+                                                                        double *Easting,
+                                                                        double *Northing)const
+
+{ /* BEGIN Convert_Geodetic_To_Van_der_Grinten */
+/*
+ * The function Convert_Geodetic_To_Van_der_Grinten converts geodetic (latitude and
+ * longitude) coordinates to Van Der Grinten projection (easting and northing)
+ * coordinates, according to the current ellipsoid and Van Der Grinten projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise GRIN_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+
+  double dlam;                      /* Longitude - Central Meridan */
+  double aa, aasqr;
+  double gg;
+  double pp, ppsqr;
+  double gg_MINUS_ppsqr, ppsqr_PLUS_aasqr;
+  double in_theta;
+  double theta;
+  double sin_theta, cos_theta;
+  double qq;
+  long   Error_Code = GRIN_NO_ERROR;
+
+//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
+//   {  /* Latitude out of range */
+//     Error_Code |= GRIN_LAT_ERROR;
+//   }
+//   if ((Longitude < -M_PI) || (Longitude > TWO_PI))
+//   {  /* Longitude out of range */
+//     Error_Code|= GRIN_LON_ERROR;
+//   }
+
+  if (!Error_Code)
+  { /* no errors */
+
+    dlam = Longitude - Grin_Origin_Long;
+//     if (dlam > M_PI)
+//     {
+//       dlam -= TWO_PI;
+//     }
+//     if (dlam < -M_PI)
+//     {
+//       dlam += TWO_PI;
+//     }
+
+    if (Latitude == 0.0)
+    {
+      *Easting = Ra * dlam + Grin_False_Easting;
+      *Northing = 0.0;
+    }
+    else if (dlam == 0.0 || FLOAT_EQ(Latitude,MAX_LAT,.00001)  || FLOAT_EQ(Latitude,-MAX_LAT,.00001))
+    {
+      in_theta = fabs(TWO_OVER_PI * Latitude);
+
+      if (in_theta > 1.0)
+        in_theta = 1.0;
+      else if (in_theta < -1.0)
+        in_theta = -1.0;
+
+      theta = asin(in_theta);
+      *Easting = 0.0;
+      *Northing = PI_Ra * tan(theta / 2) + Grin_False_Northing;
+      if (Latitude < 0.0)
+        *Northing *= -1.0;
+    }
+    else
+    {
+      aa = 0.5 * fabs(M_PI / dlam - dlam / M_PI);
+      in_theta = fabs(TWO_OVER_PI * Latitude);
+
+      if (in_theta > 1.0)
+        in_theta = 1.0;
+      else if (in_theta < -1.0)
+        in_theta = -1.0;
+
+      theta = asin(in_theta);
+      sin_theta = sin(theta);
+      cos_theta = cos(theta);
+      gg = cos_theta / (sin_theta + cos_theta - 1);
+      pp = gg * (2 / sin_theta - 1);
+      aasqr = aa * aa;
+      ppsqr = pp * pp;
+      gg_MINUS_ppsqr = gg - ppsqr;
+      ppsqr_PLUS_aasqr = ppsqr + aasqr;
+      qq = aasqr + gg;
+      *Easting = PI_Ra * (aa * (gg_MINUS_ppsqr) +
+                          sqrt(aasqr * (gg_MINUS_ppsqr) * (gg_MINUS_ppsqr) -
+                               (ppsqr_PLUS_aasqr) * (gg * gg - ppsqr))) / 
+                 (ppsqr_PLUS_aasqr) + Grin_False_Easting;
+      if (dlam < 0.0)
+        *Easting *= -1.0;
+      *Northing = PI_Ra * (pp * qq - aa * sqrt ((aasqr + 1) * (ppsqr_PLUS_aasqr) - qq * qq)) /
+                  (ppsqr_PLUS_aasqr) + Grin_False_Northing;
+      if (Latitude < 0.0)
+        *Northing *= -1.0;
+    }
+  }
+  return (Error_Code);
+
+} /* END OF Convert_Geodetic_To_Van_der_Grinten */
+
+
+long ossimVanDerGrintenProjection::Convert_Van_der_Grinten_To_Geodetic(double Easting,
+                                                                       double Northing,
+                                                                       double *Latitude,
+                                                                       double *Longitude)const
+{ /* BEGIN Convert_Van_der_Grinten_To_Geodetic */
+/*
+ * The function Convert_Van_der_Grinten_To_Geodetic converts Grinten projection
+ * (easting and northing) coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Grinten projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise GRIN_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+
+  double dx, dy;
+  double xx, xxsqr;
+  double yy, yysqr, two_yysqr;
+  double xxsqr_PLUS_yysqr;
+  double c1;
+  double c2;
+  double c3, c3sqr;
+  double c2_OVER_3c3;
+  double dd;
+  double a1;
+  double m1;
+  double i;
+  double theta1;
+//  double temp;
+//  const double epsilon = 1.0e-2;
+
+  long Error_Code = GRIN_NO_ERROR;
+
+//   if ((Easting > (Grin_False_Easting + PI_Ra + epsilon)) ||
+//       (Easting < (Grin_False_Easting - PI_Ra - epsilon)))
+//   { /* Easting out of range */
+//     Error_Code |= GRIN_EASTING_ERROR;
+//   }
+//   if ((Northing > (Grin_False_Northing + PI_Ra + epsilon)) ||
+//       (Northing < (Grin_False_Northing - PI_Ra - epsilon)))
+//   { /* Northing out of range */
+//     Error_Code |= GRIN_NORTHING_ERROR;
+//   }
+//   if (!Error_Code)
+//   {
+//     temp = sqrt(Easting * Easting + Northing * Northing);     
+
+//     if ((temp > (Grin_False_Easting + PI_Ra + epsilon)) || 
+//         (temp > (Grin_False_Northing + PI_Ra + epsilon)) ||
+//         (temp < (Grin_False_Easting - PI_Ra - epsilon)) || 
+//         (temp < (Grin_False_Northing - PI_Ra - epsilon)))
+//     { /* Point is outside of projection area */
+//       Error_Code |= GRIN_RADIUS_ERROR;
+//     }
+//   }
+
+  if (!Error_Code)
+  {
+    dy = Northing - Grin_False_Northing;
+    dx = Easting - Grin_False_Easting;
+    xx = dx / PI_Ra;
+    yy = dy / PI_Ra;
+    xxsqr = xx * xx;
+    yysqr = yy * yy;
+    xxsqr_PLUS_yysqr = xxsqr + yysqr;
+    two_yysqr = 2 * yysqr;
+
+    if (Northing == 0.0)
+      *Latitude = 0.0;
+
+    else
+    {
+      c1 = - fabs(yy) * (1 + xxsqr_PLUS_yysqr);
+      c2 = c1 - two_yysqr + xxsqr;
+      c3 = - 2 * c1 + 1 + two_yysqr + (xxsqr_PLUS_yysqr) * (xxsqr_PLUS_yysqr);
+      c2_OVER_3c3 = c2 / (3.0 * c3);
+      c3sqr = c3 * c3;
+      dd = yysqr / c3 + ((2 * c2 * c2 * c2) / (c3sqr * c3) - (9 * c1 * c2) / (c3sqr)) / 27;
+      a1 = (c1 - c2 * c2_OVER_3c3) /c3;
+      m1 = 2 * sqrt(-ONE_THIRD * a1);
+      i = 3 * dd/ (a1 * m1);
+      if ((i > 1.0)||(i < -1.0))
+        *Latitude = MAX_LAT;
+      else
+      {
+        theta1 = ONE_THIRD * acos(3 * dd / (a1 * m1));
+        *Latitude = M_PI * (-m1 * cos(theta1 + PI_OVER_3) - c2_OVER_3c3);
+      }
+    }
+    if (Northing < 0.0)
+      *Latitude *= -1.0;
+
+    if (xx == 0.0)
+      *Longitude = Grin_Origin_Long;
+    else
+    {
+      *Longitude = M_PI * (xxsqr_PLUS_yysqr - 1 + 
+                         sqrt(1 + (2 * xxsqr - two_yysqr) + (xxsqr_PLUS_yysqr) * (xxsqr_PLUS_yysqr))) / 
+                   (2 * xx) + Grin_Origin_Long;
+    }
+//     if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
+//       *Latitude = PI_OVER_2;
+//     else if (*Latitude < -PI_OVER_2)
+//       *Latitude = -PI_OVER_2;
+
+//     if (*Longitude > M_PI)
+//       *Longitude -= TWO_PI;
+//     if (*Longitude < -M_PI)
+//       *Longitude += TWO_PI;
+
+//     if (*Longitude > M_PI) /* force distorted values to 180, -180 degrees */
+//       *Longitude = M_PI;
+//     else if (*Longitude < -M_PI)
+//       *Longitude = -M_PI;
+
+  }
+  return (Error_Code);
+
+} /* END OF Convert_Van_der_Grinten_To_Geodetic */
diff --git a/Utilities/OSSIM/ossim_core/projections/map_projections/ossimVanDerGrintenProjection.h b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimVanDerGrintenProjection.h
new file mode 100644
index 0000000000..df6e0b3064
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/map_projections/ossimVanDerGrintenProjection.h
@@ -0,0 +1,189 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// Calls Grinten projection code.  
+//*******************************************************************
+//  $Id: ossimVanDerGrintenProjection.h,v 1.5 2005/09/09 19:23:58 gpotts Exp $
+#ifndef ossimVanDerGrintenProjection_HEADER
+#define ossimVanDerGrintenProjection_HEADER
+
+#include "ossimMapProjection.h"
+
+class ossimVanDerGrintenProjection : public ossimMapProjection
+{
+public:
+   ossimVanDerGrintenProjection(const ossimEllipsoid& ellipsoid = ossimEllipsoid(),
+                                const ossimGpt& origin = ossimGpt());
+   ossimVanDerGrintenProjection(const ossimEllipsoid& ellipsoid,
+                                const ossimGpt& origin,
+                                const double falseEasting,
+                                const double falseNorthing);
+   ~ossimVanDerGrintenProjection(){}
+   virtual ossimObject *dup()const
+      {
+         return new ossimVanDerGrintenProjection(*this);
+      }
+   
+   virtual ossimGpt inverse(const ossimDpt &eastingNorthing)const;
+   virtual ossimDpt forward(const ossimGpt &latLon)const;
+   virtual void update();   
+   
+
+   /*!
+    * SetFalseEasting.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEasting(double falseEasting);
+
+   /*!
+    * SetFalseNorthing.  The value is in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseNorthing(double falseNorthing);
+
+   /*!
+    * Sets both false easting and northing values.  The values are
+    * expected to be in meters.
+    * Update is then called so we can pre-compute paramters
+    */
+   void setFalseEastingNorthing(double falseEasting, double falseNorthing);
+
+   void setDefaults();
+
+   double getFalseEasting()const{return  Grin_False_Easting;}
+   double getFalseNorthing()const{return Grin_False_Northing;}
+   
+   /*!
+    * Method to save the state of an object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   /*!
+    * Method to the load (recreate) the state of an object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+protected:
+
+   //________________GEOTRANS_____________
+   
+   
+   mutable double Grin_a;                      /* Semi-major axis of ellipsoid in meters */
+   mutable double Grin_f;              /* Flattening of ellipsoid */
+   mutable double es2;             /* Eccentricity (0.08181919084262188000) squared         */
+   mutable double es4;              /* es2 * es2 */
+   mutable double es6;              /* es4 * es2 */
+   mutable double Ra;                    /* Spherical Radius */
+   mutable double PI_Ra;                  
+   
+   mutable double Grin_Origin_Long;                  /* Longitude of origin in radians    */
+   mutable double Grin_False_Easting;
+   mutable double Grin_False_Northing;
+/* Van Der Grinten projection Parameters */
+   
+/*!
+ * The function Set_Van_der_Grinten_Parameters receives the ellipsoid parameters and
+ * Van Der Grinten projcetion parameters as inputs, and sets the corresponding state
+ * variables.  If any errors occur, the error code(s) are returned by the function, otherwise
+ * GRIN_NO_ERROR is returned.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (input)
+ *    f                 : Flattening of ellipsoid						        (input)
+ *    Central_Meridian  : Longitude in radians at the center of     (input)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (input)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (input)
+ */
+  long Set_Van_der_Grinten_Parameters(double a,
+                                      double f,
+                                      double Central_Meridian,
+                                      double False_Easting,
+                                      double False_Northing);
+
+
+
+/*!
+ * The function Get_Van_der_Grinten_Parameters returns the current ellipsoid
+ * parameters, and Van Der Grinten projection parameters.
+ *
+ *    a                 : Semi-major axis of ellipsoid, in meters   (output)
+ *    f                 : Flattening of ellipsoid						        (output)
+ *    Central_Meridian  : Longitude in radians at the center of     (output)
+ *                          the projection
+ *    False_Easting     : A coordinate value in meters assigned to the
+ *                          central meridian of the projection.     (output)
+ *    False_Northing    : A coordinate value in meters assigned to the
+ *                          origin latitude of the projection       (output) 
+ */
+  void Get_Van_der_Grinten_Parameters(double *a,
+                                      double *f,
+                                      double *Central_Meridian,
+                                      double *False_Easting,
+                                      double *False_Northing)const;
+
+
+
+/*!
+ * The function Convert_Geodetic_To_Van_der_Grinten converts geodetic (latitude and
+ * longitude) coordinates to Van Der Grinten projection easting, and northing
+ * coordinates, according to the current ellipsoid and Van Der Grinten projection
+ * parameters.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise GRIN_NO_ERROR is returned.
+ *
+ *    Latitude          : Latitude (phi) in radians           (input)
+ *    Longitude         : Longitude (lambda) in radians       (input)
+ *    Easting           : Easting (X) in meters               (output)
+ *    Northing          : Northing (Y) in meters              (output)
+ */
+  long Convert_Geodetic_To_Van_der_Grinten (double Latitude,
+                                            double Longitude,
+                                            double *Easting,
+                                            double *Northing)const;
+
+
+/*!
+ * The function Convert_Van_der_Grinten_To_Geodetic converts Van Der Grinten projection
+ * easting and northing coordinates to geodetic (latitude and longitude)
+ * coordinates, according to the current ellipsoid and Van Der Grinten projection
+ * coordinates.  If any errors occur, the error code(s) are returned by the
+ * function, otherwise GRIN_NO_ERROR is returned.
+ *
+ *    Easting           : Easting (X) in meters                  (input)
+ *    Northing          : Northing (Y) in meters                 (input)
+ *    Latitude          : Latitude (phi) in radians              (output)
+ *    Longitude         : Longitude (lambda) in radians          (output)
+ */
+  long Convert_Van_der_Grinten_To_Geodetic(double Easting,
+                                           double Northing,
+                                           double *Latitude,
+                                           double *Longitude)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimAffineProjection.cpp b/Utilities/OSSIM/ossim_core/projections/ossimAffineProjection.cpp
new file mode 100644
index 0000000000..87ce079052
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimAffineProjection.cpp
@@ -0,0 +1,287 @@
+//*****************************************************************************
+// FILE: ossimAffineProjection.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimAffineModel. This is an
+//   implementation of a warping interpolation model.
+//
+//*****************************************************************************
+//  $Id: ossimAffineProjection.cpp,v 1.6 2005/09/09 19:23:58 gpotts Exp $
+
+#include <projections/ossimAffineProjection.h>
+RTTI_DEF1(ossimAffineProjection, "ossimAffineProjection", ossimProjection);
+
+#include <base/misc/ossimAffineTransform.h>
+#include <base/context/ossimNotifyContext.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimAffineProjection:exec");
+static ossimTrace traceDebug ("ossimAffineProjection:debug");
+
+//*****************************************************************************
+//  CONSTRUCTOR: Default
+//  
+//*****************************************************************************
+ossimAffineProjection::ossimAffineProjection()
+   :
+      ossimProjection(),
+      theClientProjection (NULL),
+      theAffineTransform (NULL)
+{
+}
+
+
+//*****************************************************************************
+//  CONSTRUCTOR: Primary constructor accepting pointer to the underlying
+//               client projection
+//  
+//*****************************************************************************
+ossimAffineProjection::ossimAffineProjection(ossimProjection* client)
+   :
+      ossimProjection(),
+      theClientProjection (client),
+      theAffineTransform (NULL)
+{
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: Accepts geom keywordlist
+//*****************************************************************************
+ossimAffineProjection::ossimAffineProjection(const ossimKeywordlist& geom_kwl,
+                                         const char* prefix)
+   :
+      ossimProjection(),
+      theClientProjection (NULL),
+      theAffineTransform (NULL)
+{
+   theClientProjection = ossimProjectionFactoryRegistry::instance()->
+                         createProjection(geom_kwl, prefix);
+
+   theAffineTransform = new ossimAffineTransform();
+   bool rtn_stat = theAffineTransform->loadState(geom_kwl, prefix);
+
+   if (!theClientProjection ||
+       theClientProjection->getErrorStatus() || !rtn_stat)
+      setErrorStatus(ossimErrorCodes::OSSIM_ERROR);
+}
+   
+//*****************************************************************************
+//  DESTRUCTOR
+//*****************************************************************************
+ossimAffineProjection::~ossimAffineProjection()
+{
+   delete theClientProjection;
+   delete theAffineTransform;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAffineProjection::worldToLineSample()
+//*****************************************************************************
+void
+ossimAffineProjection::worldToLineSample (const ossimGpt& worldPoint,
+                                          ossimDpt&       lineSampPt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimAffineProjection::worldToLineSample: Entering..." << std::endl;
+
+   if (theClientProjection && theAffineTransform)
+   {
+      theClientProjection->worldToLineSample(worldPoint, lineSampPt);
+      theAffineTransform->inverse(lineSampPt);
+   }
+   else
+      lineSampPt.makeNan();
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimAffineProjection::worldToLineSample: Returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAffineProjection::lineSampleToWorld()
+//*****************************************************************************
+void
+ossimAffineProjection::lineSampleToWorld(const ossimDpt& lineSampPt,
+                                       ossimGpt&       worldPt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimAffineProjection::lineSampleToWorld: Entering..." << std::endl;
+
+   if (theClientProjection && theAffineTransform)
+   {
+      ossimDpt adjustedPt;
+      theAffineTransform->forward(lineSampPt, adjustedPt);
+      theClientProjection->lineSampleToWorld(adjustedPt, worldPt);
+   }
+   else
+   {
+      worldPt.makeNan();
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimAffineProjection::lineSampleToWorld: Returning..." << std::endl;
+}
+   
+//*****************************************************************************
+//  METHOD: ossimAffineProjection::lineSampleToWorld()
+//*****************************************************************************
+void
+ossimAffineProjection::lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                               const double&   hgt,
+                                               ossimGpt&       worldPt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimAffineProjection::lineSampleHeightToWorld: Entering..." << std::endl;
+
+   if (theClientProjection && theAffineTransform)
+   {
+      ossimDpt adjustedPt;
+      theAffineTransform->forward(lineSampPt, adjustedPt);
+      theClientProjection->lineSampleHeightToWorld(adjustedPt, hgt, worldPt);
+   }
+   else
+   {
+      worldPt.makeNan();
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "dEBUG ossimAffineProjection::lineSampleHeightToWorld: Returning..." << std::endl;
+}
+   
+//*****************************************************************************
+//  METHOD: ossimAffineProjection::print()
+//*****************************************************************************
+std::ostream& ossimAffineProjection::print(std::ostream& out) const
+{
+   
+   if (theClientProjection && theAffineTransform)
+   {
+      out <<
+         "ossimAffineProjection:\n"
+         "  Member theClientProjection: ";
+      theClientProjection->print(out);
+      out << "\n Member theAffineTransform: "
+          << *theAffineTransform << endl;
+   }
+   else
+   {
+      out << "ossimAffineProjection -- Not initialized." << endl;
+   }
+   return out;
+}
+
+std::ostream& operator<<(std::ostream& os, const ossimAffineProjection& m)
+{
+   return m.print(os);
+}
+
+//*****************************************************************************
+//  METHOD: ossimAffineProjection::()
+//*****************************************************************************
+bool ossimAffineProjection::saveState(ossimKeywordlist& kwl,
+                                      const char* prefix) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimAffineProjection::saveState: entering..." << std::endl;
+
+   if (theClientProjection && theAffineTransform)
+   {
+      theClientProjection->saveState(kwl, prefix);
+      theAffineTransform->saveState(kwl, prefix);
+   }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimAffineProjection::saveState: returning..." << std::endl;
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimAffineProjection::()
+//*****************************************************************************
+bool ossimAffineProjection::loadState(const ossimKeywordlist& kwl,
+                                            const char* prefix)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimAffineProjection::loadState: entering..." << std::endl;
+
+   bool good_load;
+   int  err_stat;
+   
+   if (!theClientProjection)
+   {
+      theClientProjection = ossimProjectionFactoryRegistry::instance()->
+                            createProjection(kwl, prefix);
+      err_stat = theClientProjection->getErrorStatus();
+      if (err_stat != ossimErrorCodes::OSSIM_OK)
+      {
+         return false;
+      }
+   }
+   else
+   {
+      good_load = theClientProjection->loadState(kwl, prefix);
+      if (!good_load)
+      {
+         return false;
+      }
+   }
+
+   if (!theAffineTransform)
+   {
+      theAffineTransform = new ossimAffineTransform();
+   }
+   good_load = theAffineTransform->loadState(kwl, prefix);
+   if (!good_load)
+   {
+      return false;
+   }
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimAffineProjection::loadState: returning..." << std::endl;
+
+   return true;
+
+}
+
+//*****************************************************************************
+//  METHOD: ossimAffineProjection::()
+//*****************************************************************************
+ossimObject* ossimAffineProjection::dup() const
+{
+   ossimKeywordlist kwl;
+   saveState(kwl);
+   ossimProjection* duped = new ossimAffineProjection(kwl);
+   return duped;
+}
+   
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+ossimGpt ossimAffineProjection::origin() const
+{
+   if (theClientProjection)
+      return theClientProjection->origin();
+   return ossimGpt(0.0, 0.0, 0.0);
+}
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+ossimDpt  ossimAffineProjection::getMetersPerPixel() const
+{
+   if (theClientProjection)
+      return theClientProjection->getMetersPerPixel();
+   return ossimDpt(OSSIM_NAN, OSSIM_NAN);
+}
+      
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimAffineProjection.h b/Utilities/OSSIM/ossim_core/projections/ossimAffineProjection.h
new file mode 100644
index 0000000000..a7e162ef7f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimAffineProjection.h
@@ -0,0 +1,130 @@
+//*****************************************************************************
+// FILE: ossimAffineProjection.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimAffineProjection. This is an
+//   implementation of a warping interpolation model.
+//
+//*****************************************************************************
+//  $Id: ossimAffineProjection.h,v 1.3 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimAffineProjection_HEADER
+#define ossimAffineProjection_HEADER
+
+#include "projections/ossimProjection.h"
+#include "base/data_types/ossimIpt.h"
+
+class ossim2dTo2dTransform;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimAffineProjection
+ *
+ *****************************************************************************/
+class ossimAffineProjection : public ossimProjection
+{
+public:
+   /*!
+    * Default Contructor:
+    */
+   ossimAffineProjection();
+
+   /*!
+    * Primary constructor accepting pointer to the underlying client projection.
+    */
+   ossimAffineProjection(ossimProjection* client);
+
+   /*!
+    * Constructor accepts OSSIM keywordlist geometry file.
+    */
+   ossimAffineProjection(const ossimKeywordlist& geom_kwl,
+                       const char* prefix=NULL);
+   
+   ~ossimAffineProjection();
+   
+   /*!
+    * METHOD: worldToLineSample()
+    * Performs the forward projection from ground point to line, sample.
+    */
+   virtual void worldToLineSample(const ossimGpt& worldPoint,
+                                  ossimDpt&       lineSampPt) const;
+
+   /*!
+    * METHOD: lineSampleToWorld()
+    * Performs the inverse projection from line, sample to ground (world):
+    */
+   virtual void lineSampleToWorld(const ossimDpt& lineSampPt,
+                                      ossimGpt&       worldPt) const;
+   
+   /*!
+    * Performs the inverse projection from line, sample to ground, bypassing
+    * reference to elevation surface:
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                        const double&   hgtEllipsoid,
+                                        ossimGpt&       worldPt) const;
+   
+   /*!
+    * Extends base-class implementation. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+   friend std::ostream& operator<<(std::ostream& os,
+                                   const ossimAffineProjection& m);
+   
+   /*!
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files. Returns true if successful.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0) const;
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+
+   /*!
+    * Returns pointer to a new instance, copy of this.
+    */
+   virtual ossimObject* dup() const;
+   
+   /*!
+    * Returns projection's ground point origin. That is the GP corresponding
+    * to line=0, sample=0.
+    */
+   virtual ossimGpt origin() const;
+
+   /*!
+    * Compares this instance with arg projection. NOT IMPLEMENTED.
+    */
+   virtual bool operator==(const ossimProjection& projection) const
+      { return false; }
+
+   virtual ossimDpt getMetersPerPixel() const;
+      
+protected:
+   
+   /*!
+    * Data Members:
+    */
+   ossimProjection*      theClientProjection;
+   ossim2dTo2dTransform* theAffineTransform;
+   
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimBilinearProjection.cpp b/Utilities/OSSIM/ossim_core/projections/ossimBilinearProjection.cpp
new file mode 100644
index 0000000000..27e4840646
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimBilinearProjection.cpp
@@ -0,0 +1,433 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems, Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimBilinearProjection.cpp,v 1.6 2004/09/30 20:20:41 dburken Exp $
+
+#include <sstream>
+using namespace std;
+
+#include <projections/ossimBilinearProjection.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <elevation/ossimElevManager.h>
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimBilinearProjection.cpp,v 1.6 2004/09/30 20:20:41 dburken Exp $";
+#endif
+
+// static const ossim_uint32 MINIMUM_NMBER_OF_POINTS = 4;
+
+static ossimTrace traceDebug("ossimBilinearProjection:debug");
+
+RTTI_DEF1(ossimBilinearProjection, "ossimBilinearProjection", ossimProjection);
+
+ossimBilinearProjection::ossimBilinearProjection()
+   :
+      ossimProjection(),
+      theLineSamplePt(0),
+      theGeographicPt(0),
+      theLatFit(),
+      theLonFit()
+{
+#ifdef OSSIM_ID_ENABLED
+   if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG) << OSSIM_ID << endl;
+#endif    
+}
+
+ossimBilinearProjection::ossimBilinearProjection(const ossimBilinearProjection& rhs)
+   :
+      ossimProjection(rhs),
+      theLineSamplePt(rhs.theLineSamplePt),
+      theGeographicPt(rhs.theGeographicPt),
+      theLonFit(rhs.theLonFit)
+{
+}
+
+ossimBilinearProjection::ossimBilinearProjection(const ossimDpt& ul,
+                                         const ossimDpt& ur,
+                                         const ossimDpt& lr,
+                                         const ossimDpt& ll,
+                                         const ossimGpt& ulg,
+                                         const ossimGpt& urg,
+                                         const ossimGpt& lrg,
+                                         const ossimGpt& llg)
+   :
+      ossimProjection(),
+      theLineSamplePt(4),
+      theGeographicPt(4),
+      theLatFit(),
+      theLonFit()
+{
+   theLineSamplePt[0] = ul;
+   theLineSamplePt[1] = ur;
+   theLineSamplePt[2] = lr;
+   theLineSamplePt[3] = ll;
+
+   theGeographicPt[0] = ulg;
+   theGeographicPt[1] = urg;
+   theGeographicPt[2] = lrg;
+   theGeographicPt[3] = llg;
+   
+   initializeBilinear();
+}
+                       
+ossimBilinearProjection::~ossimBilinearProjection()
+{
+}
+
+ossimObject *ossimBilinearProjection::dup()const
+{
+   return new ossimBilinearProjection(*this);
+}
+
+ossimGpt ossimBilinearProjection::origin()const
+{
+   ossimGpt result;
+   result.makeNan();
+   if ( (theGeographicPt.size() == 0) || gPtsHaveNan() )
+   {
+      return result;
+   }
+
+   double lat        = 0.0;
+   double lon        = 0.0;
+   const double SIZE = theGeographicPt.size();
+   
+   vector<ossimGpt>::const_iterator i = theGeographicPt.begin();
+   while (i != theGeographicPt.end())
+   {
+      lat += (*i).latd();
+      lon += (*i).lond();
+      ++i;
+   }
+
+   result.latd(lat/SIZE);
+   result.lond(lon/SIZE);
+   result.height(0.0);
+   result.datum(theGeographicPt[0].datum());
+   
+   return result;
+}
+
+void ossimBilinearProjection::worldToLineSample(const ossimGpt& worldPoint,
+                                            ossimDpt&       lineSampPt) const
+{
+   ossimProjection::worldToLineSample(worldPoint, lineSampPt);
+}
+
+void ossimBilinearProjection::lineSampleToWorld(const ossimDpt& lineSampPt,
+                                                ossimGpt&       worldPt) const
+{
+   lineSampleHeightToWorld(lineSampPt,
+                           OSSIM_DBL_NAN,
+                           worldPt);
+   
+}
+
+void ossimBilinearProjection::lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                                  const double&   heightAboveEllipsoid,
+                                                  ossimGpt&       worldPt) const
+{
+   worldPt.makeNan();
+
+   if (dPtsHaveNan() || gPtsHaveNan())
+   {
+      return;
+   }
+
+   
+   worldPt.lat = theLatFit.lsFitValue(lineSampPt.x, lineSampPt.y);
+   worldPt.lon = theLonFit.lsFitValue(lineSampPt.x, lineSampPt.y);
+   if (heightAboveEllipsoid != OSSIM_DBL_NAN)
+   {
+      worldPt.hgt = heightAboveEllipsoid;
+   }
+   else
+   {
+      worldPt.hgt =
+         ossimElevManager::instance()->getHeightAboveEllipsoid(worldPt);
+   }
+   if (theGeographicPt.size())
+   {
+      worldPt.datum(theGeographicPt[0].datum());
+   }
+}   
+
+bool ossimBilinearProjection::saveState(ossimKeywordlist& kwl,
+                                        const char* prefix)const
+{
+   if (theLineSamplePt.size() != theGeographicPt.size())
+   {
+      // Should never happen.
+      return false;
+   }
+
+   ossimProjection::saveState(kwl, prefix);
+
+   const ossim_uint32 SIZE = theLineSamplePt.size();
+
+   for (ossim_uint32 i = 0; i < SIZE; ++i)
+   {
+      ossimString index_string = ossimString::toString(i);
+
+      // Add the geographic point.
+      ossimString kw = "gpt";
+      kw += index_string;
+      ostringstream os1;
+      os1 << theGeographicPt[i];
+      kwl.add(prefix, kw, os1.str().c_str());
+
+      // Add the sample line..
+      kw = "dpt";
+      kw += index_string;
+      ostringstream os2;
+      os2 << theLineSamplePt[i];
+      kwl.add(prefix, kw, os2.str().c_str());
+   }
+
+   return true;
+}
+
+bool ossimBilinearProjection::loadState(const ossimKeywordlist& kwl,
+                                        const char* prefix)
+{
+   // Load the base class.
+   ossimProjection::loadState(kwl, prefix);
+
+   // Start with clear lists.
+   theLineSamplePt.clear();
+   theGeographicPt.clear();
+
+   //---
+   // Get the number of points.
+   // If 0 or gpt size not equal to dpt size get out.
+   //---
+   const ossim_uint32 SIZE = kwl.numberOf(prefix, "gpt");
+   if ( (SIZE == 0) || (SIZE != kwl.numberOf(prefix, "dpt")) )
+   {
+      return false;
+   }
+
+   for (ossim_uint32 i = 0; i < SIZE; ++i)
+   {
+      const char* lookup;
+      ossimString index_string = ossimString::toString(i);
+
+      // Get the geographic point.
+      ossimString kw = "gpt";
+      kw += index_string;
+      lookup = kwl.find(prefix, kw);
+      if (lookup)
+      {
+         ossimGpt gp;
+         istringstream is(lookup);
+         is >> gp;
+
+         //---
+         // Allow for "nan" height values by substituting with 0.0 so the
+         // hasNans() will work.  "nan"s will get placed in the point if the
+         // user doesn't have the elevation manager preferences set up
+         // correctly.
+         //---
+         if (gp.isHgtNan())
+         {
+            gp.height(0.0);
+         }
+         theGeographicPt.push_back(gp);
+      }
+
+      // Get the line sample point.
+      kw = "dpt";
+      kw += index_string;
+      lookup = kwl.find(prefix, kw);
+      if (lookup)
+      {
+         ossimDpt dp;
+         istringstream is(lookup);
+         is >> dp;
+         theLineSamplePt.push_back(dp);
+      }
+   }
+
+   if (traceDebug())
+   {
+      print(ossimNotify(ossimNotifyLevel_DEBUG));
+   }
+   
+   initializeBilinear();
+
+   return true;
+}
+
+bool ossimBilinearProjection::operator==(const ossimProjection& projection) const
+{
+   return false;
+}
+
+ossimDpt ossimBilinearProjection::getMetersPerPixel() const
+{
+   ossimGpt centerG;
+   ossimGpt rightG;
+   ossimGpt topG;
+
+   ossimDpt midPoint = midLineSamplePt();
+                     
+   lineSampleToWorld(midPoint, centerG);
+   lineSampleToWorld(midPoint+ossimDpt(1,0), rightG);
+   lineSampleToWorld(midPoint+ossimDpt(0,-1), topG);
+   
+   ossimEcefPoint centerP = centerG;
+   ossimEcefPoint rightP  = rightG;
+   ossimEcefPoint topP    = topG;
+
+   ossimEcefVector horizontal = rightP-centerP;
+   ossimEcefVector vertical   = topP-centerP;
+
+   ossimDpt result(horizontal.magnitude(),
+                   vertical.magnitude());
+
+   result.x = (result.x + result.y)/2.0;
+   result.y = result.x;
+   
+   return result;
+}
+
+void ossimBilinearProjection::initializeBilinear()
+{
+   theLatFit.clear();
+   theLonFit.clear();
+
+   const ossim_uint32 SIZE = theLineSamplePt.size();
+   if (SIZE != theGeographicPt.size())
+   {
+      return;
+   }
+
+   for (ossim_uint32 i = 0; i < SIZE; ++i)
+   {
+      theLatFit.addSample(theLineSamplePt[i].x,
+                          theLineSamplePt[i].y,
+                          theGeographicPt[i].latd());
+      
+      theLonFit.addSample(theLineSamplePt[i].x,
+                          theLineSamplePt[i].y,
+                          theGeographicPt[i].lond());
+   }
+
+   theLatFit.solveLS();
+   theLonFit.solveLS();
+}
+
+bool ossimBilinearProjection::dPtsHaveNan() const
+{
+   if (theLineSamplePt.size() == 0)
+   {
+      return false;
+   }
+
+   vector<ossimDpt>::const_iterator i = theLineSamplePt.begin();
+   while (i != theLineSamplePt.end())
+   {
+      if ( (*i).hasNans() )
+      {
+         return true;
+      }
+      ++i;
+   }
+   return false;
+}
+
+bool ossimBilinearProjection::gPtsHaveNan() const
+{
+   //---
+   // NOTE:  This method ignores nans in the height field.
+   //---
+   
+   if (theGeographicPt.size() == 0)
+   {
+      return false;
+   }
+
+   vector<ossimGpt>::const_iterator i = theGeographicPt.begin();
+   while (i != theGeographicPt.end())
+   {
+      if ( (*i).isLatNan() || (*i).isLonNan() )
+      {
+         return true;
+      }
+      ++i;
+   }
+   return false;
+}
+
+ossimDpt ossimBilinearProjection::midLineSamplePt() const
+{
+   ossimDpt result;
+   
+   if ( (theLineSamplePt.size() == 0) || dPtsHaveNan())
+   {
+      result.makeNan();
+      return result;
+   }
+
+   double x = 0.0;
+   double y = 0.0;
+   vector<ossimDpt>::const_iterator i = theLineSamplePt.begin();
+   while (i != theLineSamplePt.end())
+   {
+      x += (*i).x;
+      y += (*i).y;
+      ++i;
+   }
+   const double SIZE = theLineSamplePt.size();
+   result.x = x / SIZE;
+   result.y = y / SIZE;
+
+   return result;
+}
+
+std::ostream& ossimBilinearProjection::print(std::ostream& out) const
+{
+   ossimNotify(ossimNotifyLevel_INFO)
+      << "ossimBilinearProjection::print\n";
+
+   ossim_uint32 index = 0;
+   vector<ossimDpt>::const_iterator di = theLineSamplePt.begin();
+   while (di != theLineSamplePt.end())
+   {
+      ossimNotify(ossimNotifyLevel_INFO)
+         << "theLineSamplePt[" << index << "]:  "
+         << (*di) << endl;
+      ++di;
+      ++index;
+   }
+
+   index = 0;
+   vector<ossimGpt>::const_iterator gi = theGeographicPt.begin();
+   while (gi != theGeographicPt.end())
+   {
+      ossimNotify(ossimNotifyLevel_INFO)
+         << "theGeographicPt[" << index << "]:  "
+         << (*gi) << endl;
+      ++gi;
+      ++index;
+   }
+
+   return ossimProjection::print(out);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimBilinearProjection.h b/Utilities/OSSIM/ossim_core/projections/ossimBilinearProjection.h
new file mode 100644
index 0000000000..1af3e320e8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimBilinearProjection.h
@@ -0,0 +1,108 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems, Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimBilinearProjection.h,v 1.2 2004/07/01 21:02:30 dburken Exp $
+#ifndef ossimBilinearProjection_HEADER
+#define ossimBilinearProjection_HEADER
+
+#include <vector>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimGpt.h>
+#include <projections/ossimProjection.h>
+#include <base/common/ossimLeastSquaresBilin.h>
+
+class ossimBilinearProjection : public ossimProjection
+{
+public:
+   ossimBilinearProjection();
+   ossimBilinearProjection(const ossimBilinearProjection& rhs);
+   ossimBilinearProjection(const ossimDpt& ul,
+                           const ossimDpt& ur,
+                           const ossimDpt& lr,
+                           const ossimDpt& ll,
+                           const ossimGpt& ulg,
+                           const ossimGpt& urg,
+                           const ossimGpt& lrg,
+                           const ossimGpt& llg);
+   virtual ~ossimBilinearProjection();
+   virtual ossimObject *dup()const;
+   virtual ossimGpt origin()const;
+   
+   virtual void worldToLineSample(const ossimGpt& worldPoint,
+                                  ossimDpt&       lineSampPt) const;
+   /*!
+    * METHOD: lineSampleToWorld()
+    * Performs the inverse projection from line, sample to ground (world):
+    */
+   virtual void lineSampleToWorld(const ossimDpt& lineSampPt,
+                                  ossimGpt&       worldPt) const;
+   
+   /*!
+    * METHOD: lineSampleHeightToWorld
+    * This is the pure virtual that projects the image point to the given
+    * elevation above ellipsoid, thereby bypassing reference to a DEM. Useful
+    * for projections that are sensitive to elevation (such as sensor models).
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                        const double&   heightAboveEllipsoid,
+                                        ossimGpt&       worldPt) const;
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual bool operator==(const ossimProjection& projection) const;
+   virtual ossimDpt getMetersPerPixel() const;
+
+   virtual std::ostream& print(std::ostream& out) const;
+
+protected:
+   void initializeBilinear();
+
+   /**
+    * Checks theLineSamplePt for nans.
+    * @return true if any point has a nan.
+    * @note If theLineSamplePt size is 0 this returns false.
+    */
+   bool dPtsHaveNan() const;
+   
+   /**
+    * Checks theGeographicPt for nans.
+    * @return true if any point has a nan.
+    * @note If theLineSamplePt size is 0 this returns false.
+    */
+   bool gPtsHaveNan() const;
+
+   /**
+    * @return The mid point of theLineSamplePts.
+    */
+   ossimDpt midLineSamplePt() const;
+   
+   std::vector<ossimDpt>  theLineSamplePt;
+   std::vector<ossimGpt>  theGeographicPt;
+   ossimLeastSquaresBilin theLatFit;
+   ossimLeastSquaresBilin theLonFit;
+
+TYPE_DATA   
+};
+
+#endif /* #ifndef ossimBilinearProjection_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimImageViewAffineTransform.cpp b/Utilities/OSSIM/ossim_core/projections/ossimImageViewAffineTransform.cpp
new file mode 100644
index 0000000000..f91807f280
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimImageViewAffineTransform.cpp
@@ -0,0 +1,352 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimImageViewAffineTransform.cpp,v 1.9 2006/01/05 12:03:52 gpotts Exp $
+#include "ossimImageViewAffineTransform.h"
+#include "base/data_types/ossimKeywordlist.h"
+#include "base/data_types/ossimMatrix3x3.h"
+
+RTTI_DEF1(ossimImageViewAffineTransform, "ossimImageViewAffineTransform", ossimImageViewTransform)
+
+ossimImageViewAffineTransform::ossimImageViewAffineTransform(double rotateDegrees,
+                                                             double scaleXValue,
+                                                             double scaleYValue,
+                                                             double translateXValue,
+                                                             double translateYValue,
+                                                             double translateOriginXValue,
+                                                             double translateOriginYValue)
+   :theTransform(3,3),
+    theInverseTransform(3,3),
+    theRotation(rotateDegrees),
+    theScale(scaleXValue, scaleYValue),
+    theTranslate(translateXValue, translateYValue),
+    theTranslateOrigin(translateOriginXValue, translateOriginYValue)
+{
+   theTransform << 1 << 0 << 0
+                << 0 << 1 << 0
+                << 0 << 0 << 1;
+   
+   theInverseTransform << 1 << 0 << 0
+                       << 0 << 1 << 0
+                       << 0 << 0 << 1;
+
+   
+   rotate(rotateDegrees);
+   scale(scaleXValue, scaleYValue);
+   translate(translateXValue, translateYValue);
+   translateOrigin(translateOriginXValue, translateOriginYValue);
+}
+
+ossimImageViewAffineTransform::~ossimImageViewAffineTransform()
+{
+}
+
+void ossimImageViewAffineTransform::imageToView(const ossimDpt& imagePoint,
+                                                ossimDpt&       viewPoint)const
+{
+   
+//    viewPoint.x = theTransform[0][0]*(imagePoint.x - translateRotationOriginPoint.x) + theTransform[0][1]*(imagePoint.y - translateRotationOriginPoint.y) + theTransform[0][2];
+//    viewPoint.y = theTransform[1][0]*(imagePoint.x - translateRotationOriginPoint.x) + theTransform[1][1]*(imagePoint.y - translateRotationOriginPoint.y) + theTransform[1][2];
+    viewPoint.x = theTransform[0][0]*imagePoint.x + theTransform[0][1]*imagePoint.y + theTransform[0][2];
+    viewPoint.y = theTransform[1][0]*imagePoint.x + theTransform[1][1]*imagePoint.y + theTransform[1][2];
+}
+
+void ossimImageViewAffineTransform::viewToImage(const ossimDpt& viewPoint,
+                                                ossimDpt&       imagePoint)const
+{
+   
+//    imagePoint.x = theInverseTransform[0][0]*viewPoint.x + theInverseTransform[0][1]*viewPoint.y + theInverseTransform[0][2] + translateRotationOriginPoint.x;
+//    imagePoint.y = theInverseTransform[1][0]*viewPoint.x + theInverseTransform[1][1]*viewPoint.y + theInverseTransform[1][2] + translateRotationOriginPoint.y;
+   imagePoint.x = theInverseTransform[0][0]*viewPoint.x + theInverseTransform[0][1]*viewPoint.y + theInverseTransform[0][2];
+   imagePoint.y = theInverseTransform[1][0]*viewPoint.x + theInverseTransform[1][1]*viewPoint.y + theInverseTransform[1][2];
+   
+}
+
+void ossimImageViewAffineTransform::setMatrix(NEWMAT::Matrix& matrix)
+{
+   theTransform        = matrix;
+   theInverseTransform = theTransform.i();
+}
+
+const NEWMAT::Matrix& ossimImageViewAffineTransform::getMatrix()const
+{
+   return theTransform;
+}
+
+
+
+void ossimImageViewAffineTransform::scale(double x, double y)
+{
+//    NEWMAT::Matrix m(3, 3);
+
+//    m << x << 0 << 0
+//      << 0 << y << 0
+//      << 0 << 0 << 1;
+
+   
+//   theTransform = (m*theTransform);
+
+//   theInverseTransform = theTransform.i();
+
+   theScale = ossimDpt(x,y);
+   buildCompositeTransform();
+}
+
+void ossimImageViewAffineTransform::translate(double deltaX,
+                                              double deltaY)
+{
+   theTranslate = ossimDpt(deltaX, deltaY);
+   buildCompositeTransform();
+//    NEWMAT::Matrix m(3,3);
+
+//    m << 1 << 0 << deltaX
+//      << 0 << 1 << deltaY
+//      << 0 << 0 << 1;
+   
+   
+//    theTransform = m*theTransform;
+//    theInverseTransform = theTransform.i();
+}
+
+void ossimImageViewAffineTransform::translateX(double deltaX)
+{
+   translate(deltaX, theTranslate.y);
+}
+
+void ossimImageViewAffineTransform::translateY(double deltaY)
+{
+   translate(theTranslate.x, deltaY);
+}
+
+void ossimImageViewAffineTransform::scaleX(double x)
+{
+   scale(x, theScale.y);
+}
+
+void ossimImageViewAffineTransform::scaleY(double y)
+{
+   scale(theScale.x, y);
+}
+
+void ossimImageViewAffineTransform::translateOrigin(double originX, double originY)
+{
+   theTranslateOrigin.x = originX;
+   theTranslateOrigin.y = originY;
+   buildCompositeTransform();
+}
+
+void ossimImageViewAffineTransform::translateOriginX(double originX)
+{
+   translateOrigin(originX,theTranslateOrigin.y);
+}
+
+void ossimImageViewAffineTransform::translateOriginY(double originY)
+{
+   translateOrigin(theTranslateOrigin.x, originY);
+}
+
+void ossimImageViewAffineTransform::rotate(double degrees)
+{
+   theRotation = degrees;
+   buildCompositeTransform();
+//   theTransform = (theTransform * ossimMatrix3x3::createRotationZMatrix(degrees));
+//    theTransform = ossimMatrix3x3::createRotationZMatrix(degrees) * theTransform;
+
+//    theInverseTransform = theTransform.i();
+}
+
+void ossimImageViewAffineTransform::buildCompositeTransform()
+{
+   NEWMAT::Matrix scaleM(3, 3);
+   NEWMAT::Matrix rotzM = ossimMatrix3x3::createRotationZMatrix(theRotation);
+   NEWMAT::Matrix transM(3,3);
+   NEWMAT::Matrix transOriginM(3,3);
+   NEWMAT::Matrix transOriginNegatedM(3,3);
+   
+   transM << 1 << 0 << theTranslate.x
+          << 0 << 1 << theTranslate.y
+          << 0 << 0 << 1;
+   
+   transOriginM << 1 << 0 << theTranslateOrigin.x
+                << 0 << 1 << theTranslateOrigin.y
+                << 0 << 0 << 1;
+   
+   transOriginNegatedM << 1 << 0 << -theTranslateOrigin.x
+                       << 0 << 1 << -theTranslateOrigin.y
+                       << 0 << 0 << 1;
+   
+   scaleM << theScale.x << 0 << 0
+          << 0 << theScale.y << 0
+          << 0 << 0 << 1;
+
+   theTransform        = transOriginM*transM*scaleM*rotzM*transOriginNegatedM;
+   theInverseTransform = theTransform.i();
+   
+}
+
+
+bool ossimImageViewAffineTransform::loadState(const ossimKeywordlist& kwl,
+                                              const char* prefix)
+{
+   ossimString newPrefix = ossimString(prefix) + "transform.";
+   
+   const char* lookup = kwl.find(newPrefix.c_str(),
+                                 "m11");
+   if(lookup)
+   {
+      theTransform[0][0] = ossimString(lookup).toDouble();
+   }
+
+   lookup = kwl.find(newPrefix.c_str(),
+                     "m12");
+   if(lookup)
+   {
+      theTransform[0][1] = ossimString(lookup).toDouble();
+   }
+
+   lookup = kwl.find(newPrefix.c_str(),
+                     "m13");
+   if(lookup)
+   {
+      theTransform[0][2] = ossimString(lookup).toDouble();
+   }
+
+   lookup = kwl.find(newPrefix.c_str(),
+                     "m21");
+   if(lookup)
+   {
+      theTransform[1][0] = ossimString(lookup).toDouble();
+   }
+
+   lookup = kwl.find(newPrefix.c_str(),
+                     "m22");
+   if(lookup)
+   {
+      theTransform[1][1] = ossimString(lookup).toDouble();
+   }
+
+   lookup = kwl.find(newPrefix.c_str(),
+                     "m23");
+   if(lookup)
+   {
+      theTransform[1][2] = ossimString(lookup).toDouble();
+   }
+
+   lookup = kwl.find(newPrefix.c_str(),
+                     "m31");
+   if(lookup)
+   {
+      theTransform[2][0] = ossimString(lookup).toDouble();
+   }
+
+   lookup = kwl.find(newPrefix.c_str(),
+                     "m32");
+   if(lookup)
+   {
+      theTransform[2][1] = ossimString(lookup).toDouble();
+   }
+
+   lookup = kwl.find(newPrefix.c_str(),
+                     "m33");
+   if(lookup)
+   {
+      theTransform[2][2] = ossimString(lookup).toDouble();
+   }
+
+   lookup = kwl.find(newPrefix.c_str(),
+                     "rotate");
+   if(lookup)
+   {
+      double degrees = ossimString(lookup).toDouble();
+      theTransform *=  ossimMatrix3x3::createRotationZMatrix(degrees);
+   }
+   theInverseTransform = theTransform.i();
+
+   return true;
+}
+
+bool ossimImageViewAffineTransform::saveState(ossimKeywordlist& kwl,
+                                              const char* prefix)const
+{
+   
+   kwl.add(prefix,
+           "transform.m11",
+           theTransform[0][0],
+           true);
+   kwl.add(prefix,
+           "transform.m12",
+           theTransform[0][1],
+           true);
+   kwl.add(prefix,
+           "transform.m13",
+           theTransform[0][2],
+           true);
+   kwl.add(prefix,
+           "transform.m21",
+           theTransform[1][0],
+           true);
+   kwl.add(prefix,
+           "transform.m22",
+           theTransform[1][1],
+           true);
+   kwl.add(prefix,
+           "transform.m23",
+           theTransform[1][2],
+           true);
+   kwl.add(prefix,
+           "transform.m31",
+           theTransform[2][0],
+           true);
+   kwl.add(prefix,
+           "transform.m32",
+           theTransform[2][1],
+           true);
+   kwl.add(prefix,
+           "transform.m33",
+           theTransform[2][2],
+           true);
+   
+   return true;
+}
+
+bool ossimImageViewAffineTransform::isValid()const
+{
+   return true;
+}
+
+bool ossimImageViewAffineTransform::setView(ossimObject* /* obj */,
+                                            bool /* ownsProjection*/ )
+{
+   return false;
+}
+
+ossimObject* ossimImageViewAffineTransform::getView()
+{
+   return NULL;
+}
+
+const ossimObject* ossimImageViewAffineTransform::getView()const
+{
+   return NULL;
+}
+
+ossimDpt ossimImageViewAffineTransform::getInputMetersPerPixel()const
+{
+   return ossimDpt(1,1);
+}
+
+ossimDpt ossimImageViewAffineTransform::getOutputMetersPerPixel()const
+{
+   ossimDpt result;
+   
+   result.makeNan();
+   
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimImageViewAffineTransform.h b/Utilities/OSSIM/ossim_core/projections/ossimImageViewAffineTransform.h
new file mode 100644
index 0000000000..d724dfbbff
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimImageViewAffineTransform.h
@@ -0,0 +1,139 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimImageViewAffineTransform.h,v 1.9 2005/08/30 11:50:05 gpotts Exp $
+#ifndef ossimImageViewAffineTransform_HEADER
+#define ossimImageViewAffineTransform_HEADER
+#include "ossimImageViewTransform.h"
+#include "matrix/newmat.h"
+
+class OSSIMDLLEXPORT ossimImageViewAffineTransform: public ossimImageViewTransform
+{
+public:
+   ossimImageViewAffineTransform(double rotateDegrees = 0,
+                                 double scaleXValue = 1,
+                                 double scaleYValue = 1,
+                                 double translateXValue = 0,
+                                 double translateYValue = 0,
+                                 double translateOriginXValue = 0,
+                                 double translateOriginYValue = 0);
+   virtual ~ossimImageViewAffineTransform();
+   
+   virtual void imageToView(const ossimDpt& imagePoint,
+                            ossimDpt&       viewPoint)const;
+   virtual void viewToImage(const ossimDpt& viewPoint,
+                            ossimDpt&       imagePoint)const;
+   void setMatrix(NEWMAT::Matrix& matrix);
+   const NEWMAT::Matrix& getMatrix()const;
+   
+   virtual bool isIdentity()const
+   {
+      return ((theTransform[0][0] == 1.0)&&
+              (theTransform[0][1] == 0.0)&&
+              (theTransform[0][2] == 0.0)&&
+              (theTransform[1][0] == 0.0)&&
+              (theTransform[1][1] == 1.0)&&
+              (theTransform[1][2] == 0.0)&&
+              (theTransform[2][0] == 0.0)&&
+              (theTransform[2][1] == 0.0)&&
+              (theTransform[2][2] == 1.0));
+   }
+
+   virtual bool isValid()const;
+   virtual bool setView(ossimObject* obj, bool ownsProjection=false);
+   virtual ossimObject* getView();
+   virtual const ossimObject* getView()const;
+   
+   /** @return (1, 1) ???????(drb) */
+   virtual ossimDpt getInputMetersPerPixel()const;
+
+   /** @return (nan, nan) ????????? (drb) */
+   virtual ossimDpt getOutputMetersPerPixel()const;
+   
+   /*!
+    * Translate in the x and y direction.
+    */ 
+   virtual void translate(double deltaX, double deltaY);
+   
+   /*!
+    * Translate in the x direction.
+    */
+   virtual void translateX(double deltaX);
+   
+   /*!
+    * Translate in the Y direction.
+    */
+   virtual void translateY(double deltaY);
+   
+   /*!
+    * Translate the origin for rotation in the x and y direction.
+    */
+   virtual void translateOrigin(double originX, double originY);
+   
+   /*!
+    * Translate the origin for rotation in the x direction.
+    */
+   virtual void translateOriginX(double originX);
+   
+   /*!
+    * Translate the origin for rotation in the y direction.
+    */
+   virtual void translateOriginY(double originY);
+   
+   /*!
+    * will allow you to specify a scale
+    * for both the x and y direction.
+    */
+   virtual void scale(double x, double y);
+   
+   /*!
+    * will alow you to specify a scale
+    * along the X direction.
+    */
+   virtual void scaleX(double x);
+   
+   /*!
+    * Will allow you to scale along the Y
+    * direction.
+    */
+   virtual void scaleY(double y);
+   
+   /*!
+    * Will apply a rotation
+    */
+   virtual void rotate(double degrees);
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix =0);
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix =0)const;
+   
+protected:
+   void buildCompositeTransform();
+   
+   /*!
+    * This is the transformation from image to
+    * viewing coordinates.  If this matrix is
+    * changed it will perform an inverse to solve
+    * the inverse transform.
+    */
+   NEWMAT::Matrix theTransform;
+   NEWMAT::Matrix theInverseTransform;
+   ossim_float64 theRotation;
+   ossimDpt      theScale;
+   ossimDpt      theTranslate;
+   ossimDpt      theTranslateOrigin;
+//   ossimDpt theTranslateRotationOriginPoint;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimImageViewProjectionTransform.cpp b/Utilities/OSSIM/ossim_core/projections/ossimImageViewProjectionTransform.cpp
new file mode 100644
index 0000000000..d3fae95774
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimImageViewProjectionTransform.cpp
@@ -0,0 +1,476 @@
+//*****************************************************************************
+// FILE: ossimImageViewProjectionTransform.cc
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Garrett Potts
+//
+// DESCRIPTION: Contains declaration of ossimImageViewProjectionTransform.
+//    This class provides an image to view transform that utilizes two
+//    independent 2D-to-3D projections. Intended for transforming view to
+//    geographic "world" space to input image space.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimImageViewProjectionTransform.cpp,v 1.32 2005/09/28 19:23:17 gpotts Exp $
+//
+#include <projections/ossimImageViewProjectionTransform.h>
+#include <projections/ossimProjection.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <base/data_types/ossimGeoPolygon.h>
+#include <base/data_types/ossimPolyArea2d.h>
+
+RTTI_DEF1(ossimImageViewProjectionTransform,
+          "ossimImageViewProjectionTransform",
+          ossimImageViewTransform);
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimImageViewProjectionTransform:exec");
+static ossimTrace traceDebug ("ossimImageViewProjectionTransform:debug");
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimImageViewProjectionTransform
+//  
+//*****************************************************************************
+ossimImageViewProjectionTransform::ossimImageViewProjectionTransform
+(  ossimProjection* imageProjection,
+   ossimProjection* viewProjection,
+   bool ownsImageProjectionFlag,
+   bool ownsViewProjectionFlag)
+   :
+      ossimImageViewTransform(),
+      theImageProjection(imageProjection),
+      theViewProjection(viewProjection),
+      theOwnsImageProjFlag(ownsImageProjectionFlag),
+      theOwnsViewProjFlag(ownsViewProjectionFlag),
+      theSameProjection(false),
+      theInputMapProjectionFlag(false),
+      theOutputMapProjectionFlag(false)
+{
+   if(!theViewProjection)
+   {
+//      theViewProjection    = new ossimEquDistCylProjection;
+      theOwnsViewProjFlag  = true;
+   }
+ 
+   if(!theImageProjection)
+   {
+      theImageProjection   = new ossimEquDistCylProjection;
+      theOwnsImageProjFlag = true;
+   }
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimImageViewProjectionTransform
+//  
+//*****************************************************************************
+ossimImageViewProjectionTransform::~ossimImageViewProjectionTransform()
+{
+   if(theImageProjection && theOwnsImageProjFlag)
+   {
+      delete theImageProjection;
+      theImageProjection = NULL;
+   }
+   if(theViewProjection && theOwnsViewProjFlag)
+   {
+      delete theViewProjection;
+      theViewProjection = NULL;
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::imageToView
+//  
+//*****************************************************************************
+void ossimImageViewProjectionTransform::imageToView
+(   const ossimDpt& imagePoint,
+    ossimDpt&       viewPoint) const
+{
+   if(theImageProjection&&theViewProjection)
+   {
+      ossimGpt gpt;
+
+//       if(theInputMapProjectionFlag)
+// 	{
+// 	  ((ossimMapProjection*)theImageProjection)->lineSampleToWorldIterate(imagePoint,
+// 									      gpt);
+// 	}
+//       else
+// 	{
+      theImageProjection->lineSampleToWorld(imagePoint, gpt);
+//	}
+      
+      if(gpt.isLatNan()||gpt.isLonNan())
+      {
+         viewPoint.makeNan();
+         return;
+      }
+      theViewProjection->worldToLineSample(gpt, viewPoint);
+#if 0
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimImageViewProjectionTransform::imageToView:"
+            <<"\n    viewPoint:  "<<viewPoint
+            <<"\n    gpt:        "<<gpt
+            <<"\n    imagePoint: "<<imagePoint<<std::endl;
+         
+      }
+#endif
+   }
+}
+   
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::viewToImage
+//  
+//*****************************************************************************
+void ossimImageViewProjectionTransform::viewToImage
+(   const ossimDpt& viewPoint,
+    ossimDpt&       imagePoint) const
+{
+   bool transformed = false;
+   if(theSameProjection)
+   {
+      ossimDpt en;
+      ossimMapProjection* mapIProj = (ossimMapProjection*)theImageProjection;
+      ossimMapProjection* mapVProj = (ossimMapProjection*)theViewProjection;
+
+      if(mapIProj&&mapVProj)
+      {
+         mapVProj->lineSampleToEastingNorthing(viewPoint, en);
+         mapIProj->eastingNorthingToLineSample(en, imagePoint);
+         return;
+      }
+   }
+   
+   if(!transformed&&theImageProjection&&theViewProjection)
+   {
+      ossimGpt gpt;
+      theViewProjection->lineSampleToWorld(viewPoint, gpt);
+      if(gpt.isLatNan()||gpt.isLonNan())
+	{
+	  imagePoint.makeNan();
+	  return;
+	}
+      theImageProjection->worldToLineSample(gpt, imagePoint);
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimImageViewProjectionTransform::viewToImage:"
+                                             <<"\n    viewPoint:  "<<viewPoint
+                                             <<"\n    gpt:        "<<gpt
+                                             <<"\n    imagePoint: "<<imagePoint<<std::endl;
+      }
+//       if(removeError&&!imagePoint.hasNans()&&!viewPoint.hasNans())
+//       {
+//          ossimDpt err;
+         
+// 	 getRoundTripErrorImage(err, ossimIpt(imagePoint));
+//          imagePoint+=err;
+//          if( fabs(imagePoint.x - (int)imagePoint.x) <= FLT_EPSILON)
+//          {
+//             imagePoint.x = (int)imagePoint.x;
+//          }
+//          if( fabs(imagePoint.y - (int)imagePoint.y) <= FLT_EPSILON)
+//          {
+//             imagePoint.y = (int)imagePoint.y;
+//          }
+//       }
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::setViewProjection
+//  
+//*****************************************************************************
+void ossimImageViewProjectionTransform::setViewProjection(ossimProjection* viewProjection, bool ownsViewProjection) 
+{
+   if(theViewProjection &&
+      (theViewProjection!=viewProjection) &&
+      theOwnsViewProjFlag)
+   {
+      delete theViewProjection;
+      theViewProjection = (ossimProjection*)NULL;
+   }
+   theOwnsViewProjFlag = ownsViewProjection;
+   theViewProjection   = viewProjection;
+   if(PTR_CAST(ossimMapProjection,
+               theViewProjection))
+   {
+      theOutputMapProjectionFlag = true;
+   }
+   else
+   {
+      theOutputMapProjectionFlag = false;
+   }
+   checkSameProjection();
+}
+
+bool ossimImageViewProjectionTransform::setView(ossimObject* baseObject,
+                                                bool ownsTheView)
+{
+   bool result = true;
+   if(baseObject)
+   {
+      // if not null then we will set it if it is of
+      // our type
+      ossimProjection* proj = PTR_CAST(ossimProjection, baseObject);
+      
+      if(proj)
+      {
+         setViewProjection(proj, ownsTheView);
+      }
+      else
+      {
+         result = false;
+      }
+   }
+   else
+   {
+      // if it's null we will just clear the view out
+      setViewProjection((ossimProjection*)NULL, true);
+   }
+
+   checkSameProjection();
+   return result;
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::setImageProjection
+//  
+//*****************************************************************************
+void ossimImageViewProjectionTransform::setImageProjection(ossimProjection* imageProjection, bool ownsImageProjection)
+{
+   if(theImageProjection &&
+      (theImageProjection!=imageProjection) &&
+      theOwnsImageProjFlag)
+   {
+      delete theImageProjection;
+      theImageProjection = (ossimProjection*)NULL;
+   }
+   theOwnsImageProjFlag = ownsImageProjection;
+   theImageProjection = imageProjection;
+   if(PTR_CAST(ossimMapProjection,
+               theImageProjection))
+   {
+      theInputMapProjectionFlag = true;
+   }
+   else
+   {
+      theInputMapProjectionFlag = false;
+   }
+   
+   checkSameProjection();
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::setViewProjection
+//  
+//*****************************************************************************
+void ossimImageViewProjectionTransform::setViewProjection(const ossimProjection& viewProjection)                                                          
+{
+   if(theViewProjection && theOwnsViewProjFlag)
+   {
+      delete theViewProjection;
+      theViewProjection = (ossimProjection*)NULL;
+   }
+   theViewProjection   = (ossimProjection*)viewProjection.dup();
+   theOwnsViewProjFlag = true;
+   if(PTR_CAST(ossimMapProjection,
+               theViewProjection))
+   {
+      theOutputMapProjectionFlag = true;
+   }
+   else
+   {
+      theOutputMapProjectionFlag = false;
+   }
+   checkSameProjection();
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::setImageProjection
+//  
+//*****************************************************************************
+void ossimImageViewProjectionTransform::setImageProjection(const ossimProjection& imageProjection)
+{
+   if(theImageProjection && theOwnsImageProjFlag)
+   {
+      delete theImageProjection;
+   }
+
+   theImageProjection = (ossimProjection*)imageProjection.dup();
+   if(PTR_CAST(ossimMapProjection,
+               theImageProjection))
+   {
+      theInputMapProjectionFlag = true;
+   }
+   theOwnsImageProjFlag = true;
+   checkSameProjection();
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::print
+//*****************************************************************************
+std::ostream& ossimImageViewProjectionTransform::print(std::ostream& out)const
+{
+   if(theImageProjection)
+   {
+      out << "image projection: " << endl;
+      theImageProjection->print(out);
+   }
+   if(theViewProjection)
+   {
+      out << "view projection: " << endl;
+      theViewProjection->print(out);
+   }
+   return out;
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::getImageProjection
+//*****************************************************************************
+ossimProjection* ossimImageViewProjectionTransform::getImageProjection()
+{
+   return theImageProjection;
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::getViewProjection
+//  
+//*****************************************************************************
+ossimProjection* ossimImageViewProjectionTransform::getViewProjection()
+{
+   return theViewProjection;
+}
+
+ossimDrect ossimImageViewProjectionTransform::getImageToViewBounds(const ossimDrect& imageRect)const
+{
+   ossimDrect result = ossimImageViewTransform::getImageToViewBounds(imageRect);
+
+   if(result.hasNans()&&theImageProjection&&theViewProjection)
+   {
+      ossimGeoPolygon viewClip;
+      theViewProjection->getGroundClipPoints(viewClip);
+      if(viewClip.size())
+      {
+         std::vector<ossimPolygon> visiblePolygons;
+         
+         std::vector<ossimGpt> imageGpts(4);
+         const ossimDatum* viewDatum = theViewProjection->origin().datum();
+         theImageProjection->lineSampleToWorld(imageRect.ul(), imageGpts[0]);
+         theImageProjection->lineSampleToWorld(imageRect.ur(), imageGpts[1]);
+         theImageProjection->lineSampleToWorld(imageRect.lr(), imageGpts[2]);
+         theImageProjection->lineSampleToWorld(imageRect.ll(), imageGpts[3]);
+
+         imageGpts[0].changeDatum(viewDatum);
+         imageGpts[1].changeDatum(viewDatum);
+         imageGpts[2].changeDatum(viewDatum);
+         imageGpts[3].changeDatum(viewDatum);
+         
+         ossimPolyArea2d viewPolyArea(viewClip.getVertexList());
+         ossimPolyArea2d imagePolyArea(imageGpts);
+         viewPolyArea &= imagePolyArea;
+         viewPolyArea.getAllVisiblePolygons(visiblePolygons);
+         if(visiblePolygons.size())
+         {
+            
+            std::vector<ossimDpt> vpts;
+            ossim_uint32 idx = 0;
+            for(idx=0; idx<visiblePolygons[0].getNumberOfVertices();++idx)
+            {
+               ossimDpt tempPt;
+               ossimGpt gpt(visiblePolygons[0][idx].lat,
+                            visiblePolygons[0][idx].lon,
+                            0.0,
+                            viewDatum);
+               theViewProjection->worldToLineSample(gpt,
+                                                    tempPt);
+               vpts.push_back(tempPt);
+            }
+            result = ossimDrect(vpts);
+         }
+      }
+      
+   }
+
+   return result;
+}
+
+//*****************************************************************************
+//  METHOD: ossimImageViewProjectionTransform::loadState
+//  
+//*****************************************************************************
+bool ossimImageViewProjectionTransform::loadState(const ossimKeywordlist& kwl,
+                                                  const char* prefix)
+{
+   ossimString newPrefix = prefix;
+
+   if(theImageProjection)
+   {
+      delete theImageProjection;
+      theImageProjection = NULL;
+   }
+   if(theViewProjection)
+   {
+      delete theViewProjection;
+      theViewProjection = NULL;
+   }
+
+   newPrefix = ossimString(prefix) + "view_proj.";
+   theViewProjection
+      = ossimProjectionFactoryRegistry::instance()->createProjection(kwl, newPrefix.c_str());
+   
+   theOwnsImageProjFlag = true;   
+   theOwnsViewProjFlag = true;
+   if(PTR_CAST(ossimMapProjection,
+               theImageProjection))
+   {
+      theInputMapProjectionFlag = true;
+   }
+   else
+   {
+      theInputMapProjectionFlag = false;
+   }
+   if(PTR_CAST(ossimMapProjection,
+               theViewProjection))
+   {
+      theOutputMapProjectionFlag = true;
+   }
+   else
+   {
+      theOutputMapProjectionFlag = false;
+   }
+
+   return ossimImageViewTransform::loadState(kwl, prefix);
+}
+
+bool ossimImageViewProjectionTransform::saveState(ossimKeywordlist& kwl,
+                                                  const char* prefix)const
+{
+   if(theViewProjection)
+   {
+      theViewProjection->saveState(kwl,
+                                   (ossimString(prefix) + "view_proj.").c_str());
+   }
+   kwl.add(prefix,
+           "type",
+           STATIC_TYPE_NAME(ossimImageViewProjectionTransform),
+           true);
+   
+   return ossimImageViewTransform::saveState(kwl, prefix);
+}
+
+void ossimImageViewProjectionTransform::checkSameProjection()
+{
+   theSameProjection = false;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimImageViewProjectionTransform.h b/Utilities/OSSIM/ossim_core/projections/ossimImageViewProjectionTransform.h
new file mode 100644
index 0000000000..86e9c9058d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimImageViewProjectionTransform.h
@@ -0,0 +1,169 @@
+//*****************************************************************************
+// FILE: ossimImageViewProjectionTransform.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Garrett Potts (gpotts@imagelinks.com)
+//
+// DESCRIPTION: Contains declaration of ossimImageViewProjectionTransform.
+//    This class provides an image to view transform that utilizes two
+//    independent 2D-to-3D projections. Intended for transforming view to
+//    geographic "world" space to input image space.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimImageViewProjectionTransform.h,v 1.14 2005/09/28 19:23:17 gpotts Exp $
+
+#ifndef ossimImageViewProjectionTransform_HEADER
+#define ossimImageViewProjectionTransform_HEADER
+
+#include <projections/ossimImageViewTransform.h>
+#include <projections/ossimProjection.h>
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+class ossimProjection;
+class ossimMapProjection;
+
+class OSSIMDLLEXPORT ossimImageViewProjectionTransform : public ossimImageViewTransform
+{
+public:
+   ossimImageViewProjectionTransform(ossimProjection* imageProjection=NULL,
+                                     ossimProjection* viewProjection=NULL,
+                                     bool ownsImageProjectionFlag=true,
+                                     bool ownsViewProjectionFlag=true);
+   
+   virtual ~ossimImageViewProjectionTransform();
+
+   virtual bool isValid()const
+      {
+         return (theImageProjection&&theViewProjection);
+      }
+  virtual bool isIdentity()const
+  {
+    if(theImageProjection&&theViewProjection)
+      {
+	return (*theImageProjection)==(*theViewProjection);
+      }
+    
+    return true;
+  }
+   virtual void imageToView(const ossimDpt& imagePoint,
+                            ossimDpt&       viewPoint)const;
+   virtual void viewToImage(const ossimDpt& viewPoint,
+                            ossimDpt&       imagePoint)const;
+
+//   virtual void getRoundTripErrorView(ossimDpt& result,
+// 				     const ossimDpt& viewPt)const;
+
+//   virtual void getRoundTripErrorImage(ossimDpt& result,
+// 				      const ossimDpt& imagePt)const;
+   /*!
+    * Will not allocate a new projection.  It will just copy
+    * the pointer and delete the one it owns if they addresses
+    * are different.  It will own the passes in projection.
+    */
+   void setViewProjection(ossimProjection* viewProjection,
+                          bool ownsViewProjection=false);   
+
+   /*!
+    * Will allocate a new projection and copy it.
+    */
+   void setViewProjection(const ossimProjection& viewProjection);
+
+   /*!
+    * Will not allocate a new projection.  It will just copy
+    * the pointer and delete the one it owns if they addresses
+    * are different. Flag indicates whether this becomes owner.
+    */
+   void setImageProjection(ossimProjection* imageProjection,
+                           bool ownsImageProjection=false);
+
+   /*!
+    * Will allocate a new projection and copy it.
+    */
+   void setImageProjection(const ossimProjection& imageProjection);
+
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   ossimProjection* getImageProjection();
+   ossimProjection* getViewProjection();
+
+   virtual bool setView(ossimObject* baseObject,
+                        bool ownsTheView = false);
+   virtual ossimObject* getView()
+      {
+         return theViewProjection;
+      }
+   virtual const ossimObject* getView()const
+      {
+         return theViewProjection;
+      }
+
+   virtual ossimDpt getInputMetersPerPixel()const
+      {
+         ossimDpt result;
+
+         result.makeNan();
+
+         if(theImageProjection)
+         {
+            result = theImageProjection->getMetersPerPixel();
+         }
+
+         return result;
+      }
+   virtual ossimDpt getOutputMetersPerPixel()const
+      {
+         ossimDpt result;
+
+         result.makeNan();
+
+         if(theViewProjection)
+         {
+            result = theViewProjection->getMetersPerPixel();
+         }
+
+         return result;
+      }
+   virtual ossimDrect getImageToViewBounds(const ossimDrect& imageRect)const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix =0);
+   
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = 0)const;
+protected:
+   ossimProjection* theImageProjection;
+   ossimProjection* theViewProjection;
+   bool             theOwnsImageProjFlag;
+   bool             theOwnsViewProjFlag;
+   mutable bool     theSameProjection;
+   mutable bool     theInputMapProjectionFlag;
+   mutable bool     theOutputMapProjectionFlag;
+   void checkSameProjection();
+//    void findWorldPoint(const ossimDpt& imagePoint,
+//                        ossimGpt& worldPt,
+//                        ossimMapProjection* proj)const;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimImageViewTransform.cpp b/Utilities/OSSIM/ossim_core/projections/ossimImageViewTransform.cpp
new file mode 100644
index 0000000000..9d9ef3ebbe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimImageViewTransform.cpp
@@ -0,0 +1,272 @@
+#include <math.h>
+#include "base/common/ossimCommon.h" // this is going to be used for the ossimGetSign
+#include "ossimImageViewTransform.h"
+#include "base/data_types/ossimDrect.h" 
+#include "base/data_types/ossimIrect.h" 
+
+RTTI_DEF2(ossimImageViewTransform, "ossimImageViewTransform", ossim2dTo2dTransform, ossimViewInterface)
+
+ossimImageViewTransform::ossimImageViewTransform()
+    :
+       ossim2dTo2dTransform(),
+       ossimViewInterface(NULL)
+{
+   ossimViewInterface::theObject = this;
+}
+
+void ossimImageViewTransform::forward(const ossimDpt& input,
+                                      ossimDpt& output) const
+{
+   imageToView(input, output);
+}
+
+void ossimImageViewTransform::imageToView(const ossimDpt& imagePoint,
+                                          ossimDpt&       viewPoint)const
+{
+   viewPoint = imagePoint;
+}
+
+void ossimImageViewTransform::viewToImage(const ossimDpt& viewPoint,
+                                          ossimDpt&       imagePoint)const
+{
+   imagePoint = viewPoint;
+}
+
+ossimDpt ossimImageViewTransform::imageToView(const ossimDpt& imagePoint)const
+{
+   ossimDpt tempPt;
+   
+   imageToView(imagePoint, tempPt);
+   
+   return tempPt;
+}
+
+ossimDpt ossimImageViewTransform::viewToImage(const ossimDpt& viewPoint)const
+{
+   ossimDpt tempPt;
+   
+   viewToImage(viewPoint, tempPt);
+   
+   return tempPt;
+}
+
+void ossimImageViewTransform::getRoundTripErrorView(ossimDpt& result,
+                                                    const ossimDpt& /* viewPt */)const
+{
+   result = ossimDpt(0,0);
+}
+
+ossimDpt ossimImageViewTransform::getRoundTripErrorView(const ossimDpt& viewPt)const
+{
+   ossimDpt result;
+   getRoundTripErrorView(result, viewPt);
+   return result;
+}
+
+void ossimImageViewTransform::getRoundTripErrorImage(ossimDpt& result,
+                                                     const ossimDpt& /* imagePt */)const
+{
+   result = ossimDpt(0,0);
+}
+
+ossimDpt ossimImageViewTransform::getRoundTripErrorImage(const ossimDpt& imagePt)const
+{
+   ossimDpt result;
+   getRoundTripErrorView(result, imagePt);
+   return result;
+}
+  
+bool ossimImageViewTransform::loadState(const ossimKeywordlist& /* kwl */,
+                                        const char* /* prefix */)
+{
+   return true;
+}
+
+bool ossimImageViewTransform::saveState(ossimKeywordlist& /* kwl */,
+                                        const char* /* prefix */)const
+{
+   return true;
+}
+
+void ossimImageViewTransform::getScaleChangeImageToView(ossimDpt& result,
+                                                        const ossimDrect& imageRect)
+{
+   result.makeNan();
+   if(!imageRect.hasNans())
+   {
+      ossimDpt vul;
+      ossimDpt vur;
+      ossimDpt vlr;
+      ossimDpt vll;
+
+      imageToView(imageRect.ul(),
+                  vul);
+      imageToView(imageRect.ur(),
+                  vur);
+      imageToView(imageRect.lr(),
+                  vlr);
+      imageToView(imageRect.ll(),
+                  vll);
+
+      if(!vul.hasNans()&&
+         !vur.hasNans()&&
+         !vlr.hasNans()&&
+         !vll.hasNans())
+      {
+         
+         double deltaTop    = (vul - vur).length();
+         double deltaBottom = (vll - vlr).length();
+         double deltaRight  = (vur - vlr).length();
+         
+         double w = imageRect.width();
+         double h = imageRect.height();
+         result.x = (deltaTop/w + deltaBottom/w)*.5;
+         result.y = (deltaRight/h + deltaRight/h)*.5;
+      }
+   }
+}
+
+void ossimImageViewTransform::getScaleChangeViewToImage(ossimDpt& result,
+                                                        const ossimDrect& viewRect)
+{
+   result.makeNan();
+   if(!viewRect.hasNans())
+   {
+      ossimDpt iul;
+      ossimDpt iur;
+      ossimDpt ilr;
+      ossimDpt ill;
+
+      imageToView(viewRect.ul(),
+                  iul);
+      imageToView(viewRect.ur(),
+                  iur);
+      imageToView(viewRect.lr(),
+                  ilr);
+      imageToView(viewRect.ll(),
+                  ill);
+
+      if(!iul.hasNans()&&
+         !iur.hasNans()&&
+         !ilr.hasNans()&&
+         !ill.hasNans())
+      {
+         
+         double deltaTop    = (iul - iur).length();
+         double deltaBottom = (ill - ilr).length();
+         double deltaRight  = (iur - ilr).length();
+         
+         double w = viewRect.width();
+         double h = viewRect.height();
+         result.x = (deltaTop/w + deltaBottom/w)*.5;
+         result.y = (deltaRight/h + deltaRight/h)*.5;
+      }
+   }
+}
+
+void ossimImageViewTransform::getImageToViewScale(ossimDpt& resultScale,
+						  const ossimDpt& imagePoint,
+						  const ossimDpt& deltaImagePointXY)const
+{
+  ossimDpt p1 = imagePoint;
+  ossimDpt p2(imagePoint.x + deltaImagePointXY.x,
+	      imagePoint.y);
+  ossimDpt p3(imagePoint.x,
+	      imagePoint.y + deltaImagePointXY.y);
+  
+  ossimDpt transformedP1;
+  ossimDpt transformedP2;
+  ossimDpt transformedP3;
+
+  imageToView(p1, transformedP1);
+  imageToView(p2, transformedP2);
+  imageToView(p3, transformedP3);
+
+  ossimDpt deltaP1P2 = transformedP1 - transformedP2;
+  ossimDpt deltaP1P3 = transformedP1 - transformedP3;
+ 
+  // now compute the distances.
+  double sumSquaredSqrtP1P2 = sqrt((deltaP1P2.x*deltaP1P2.x) +
+			       (deltaP1P2.y*deltaP1P2.y));
+  double sumSquaredSqrtP1P3 = sqrt((deltaP1P3.x*deltaP1P3.x) +
+			       (deltaP1P3.y*deltaP1P3.y));
+
+  resultScale.x = 0;
+  resultScale.y = 0;
+
+  if(sumSquaredSqrtP1P2 > FLT_EPSILON)
+    {
+      resultScale.x = sumSquaredSqrtP1P2/deltaImagePointXY.x;
+    }
+  if(sumSquaredSqrtP1P3 > FLT_EPSILON)
+    {
+      resultScale.y = sumSquaredSqrtP1P3/deltaImagePointXY.y;
+    }
+}
+
+void ossimImageViewTransform::getViewToImageScale(ossimDpt& resultScale,
+						  const ossimDpt& viewPoint,
+						  const ossimDpt& deltaViewPointXY)const
+{
+  ossimDpt p1 = viewPoint;
+  ossimDpt p2(viewPoint.x + deltaViewPointXY.x,
+	      viewPoint.y);
+  ossimDpt p3(viewPoint.x,
+	      viewPoint.y + deltaViewPointXY.y);
+
+  ossimDpt transformedP1;
+  ossimDpt transformedP2;
+  ossimDpt transformedP3;
+
+  viewToImage(p1, transformedP1);
+  viewToImage(p2, transformedP2);
+  viewToImage(p3, transformedP3);
+
+  ossimDpt deltaP1P2 = transformedP1 - transformedP2;
+  ossimDpt deltaP1P3 = transformedP1 - transformedP3;
+
+  // now compute the distances.
+  double sumSquaredSqrtP1P2 = sqrt((deltaP1P2.x*deltaP1P2.x) +
+                                   (deltaP1P2.y*deltaP1P2.y));
+  double sumSquaredSqrtP1P3 = sqrt((deltaP1P3.x*deltaP1P3.x) +
+                                   (deltaP1P3.y*deltaP1P3.y));
+
+  resultScale.x = 0;
+  resultScale.y = 0;
+
+  if(sumSquaredSqrtP1P2 > FLT_EPSILON)
+    {
+      resultScale.x = sumSquaredSqrtP1P2/deltaViewPointXY.x;
+    }
+  if(sumSquaredSqrtP1P3 > FLT_EPSILON)
+    {
+      resultScale.y = sumSquaredSqrtP1P3/deltaViewPointXY.y;
+    }
+}
+
+ossimDrect ossimImageViewTransform::getImageToViewBounds(const ossimDrect& imageRect)const
+{
+   ossimDpt p1;
+   ossimDpt p2;
+   ossimDpt p3;
+   ossimDpt p4;
+
+   imageToView(imageRect.ul(), p1);
+   imageToView(imageRect.ur(), p2);
+   imageToView(imageRect.lr(), p3);
+   imageToView(imageRect.ll(), p4);
+
+   return ossimDrect(p1, p2, p3, p4);
+}
+
+std::ostream& ossimImageViewTransform::print(std::ostream& out) const
+{
+   return out;
+}
+
+std::ostream& operator<<(std::ostream& out,
+                         const ossimImageViewTransform& data)
+{
+   return data.print(out);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimImageViewTransform.h b/Utilities/OSSIM/ossim_core/projections/ossimImageViewTransform.h
new file mode 100644
index 0000000000..0445a45a80
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimImageViewTransform.h
@@ -0,0 +1,134 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:  This class hides the image view transformation process.
+//               We should be able to open up ay image within the system
+//               and be able to map it to the view space.  Classes need to
+//               derive and override the methods within this class.  This will
+//               mainly be used in the resampling process.
+//
+//*******************************************************************
+//  $Id: ossimImageViewTransform.h,v 1.16 2005/09/28 19:23:17 gpotts Exp $
+#ifndef ossimImageViewTransform_HEADER
+#define ossimImageViewTransform_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimViewInterface.h"
+#include "base/common/ossimObject.h"
+#include "base/data_types/ossimDpt.h"
+#include "base/data_types/ossimDrect.h"
+#include "base/misc/ossim2dTo2dTransform.h"
+
+class OSSIMDLLEXPORT ossimImageViewTransform : public ossim2dTo2dTransform,
+					       public ossimViewInterface
+{
+public:
+   friend OSSIMDLLEXPORT ostream& operator<<(ostream& out,
+					     const ossimImageViewTransform& data);
+   
+   ossimImageViewTransform();
+
+   virtual void forward(const ossimDpt& input, ossimDpt& output) const;
+  
+  /*!
+   * derived classes will specify if the imageViewTransform is an
+   * identity.  
+   */
+   virtual bool isIdentity()const=0;
+
+
+   virtual bool isValid()const=0;
+   virtual ossimDpt getInputMetersPerPixel()const=0;
+   virtual ossimDpt getOutputMetersPerPixel()const=0;
+   /*!
+   * If it needs to it will use the information passed in to get the
+   * scae factor by transforming the line point.x to point.x+deltaXY and 
+   * point.y to point.y + deltaXY.y.  It will comput new delta's and 
+   * set the ratio of deltaXY/newDeltaXY to the result scale.  
+   *
+   * Derived classes can overide this default implementation.  Note:
+   * if the scale changes are only subpixel then it will return a scale
+   * of one.  We have to see how this works before we actually keep this
+   * implementation.
+   */
+  virtual void getImageToViewScale(ossimDpt& resultScale,
+				   const ossimDpt& imagePoint,
+				   const ossimDpt& deltaImagePointXY)const;
+
+  /*!
+   * If it needs to it will use the information passed in to get the
+   * scae factor by transforming the line point.x to point.x+deltaXY and 
+   * point.y to point.y + deltaXY.y.  It will comput new delta's and 
+   * set the ratio of deltaXY/newDeltaXY to the result scale.  
+   *
+   * Derived classes can overide this default implementation.  Note:
+   * if the scale changes are only subpixel then it will return a scale
+   * of one.  We have to see how this works before we actually keep this
+   * implementation.
+   */
+  virtual void getViewToImageScale(ossimDpt& resultScale,
+				   const ossimDpt& imagePoint,
+				   const ossimDpt& deltaImagePointXY)const;
+  
+  virtual void imageToView(const ossimDpt& imagePoint,
+                           ossimDpt&       viewPoint)const;
+  
+  virtual void viewToImage(const ossimDpt& viewPoint,
+                           ossimDpt&       imagePoint)const;
+  
+  virtual std::ostream& print(std::ostream& out) const;
+  
+  ossimDpt imageToView(const ossimDpt& imagePoint)const;
+  
+  ossimDpt viewToImage(const ossimDpt& viewPoint)const;
+  
+  /*!
+   * This should compute output/input.
+   */
+  virtual void getScaleChangeImageToView(ossimDpt& result,
+                                         const ossimDrect& imageRect);
+  /*!
+   * This should compute output/input.
+   */
+  virtual void getScaleChangeViewToImage(ossimDpt& result,
+                                         const ossimDrect& viewRect);
+  
+  virtual void getRoundTripErrorView(ossimDpt& result,
+				     const ossimDpt& viewPt)const;
+  
+  virtual ossimDpt getRoundTripErrorView(const ossimDpt& viewPt)const;
+  
+  virtual void getRoundTripErrorImage(ossimDpt& result,
+                                      const ossimDpt& imagePt)const;
+  
+  virtual ossimDpt getRoundTripErrorImage(const ossimDpt& imagePt)const;
+
+  virtual ossimDrect getImageToViewBounds(const ossimDrect& imageRect)const;
+  
+  virtual bool loadState(const ossimKeywordlist& kwl,
+                         const char* prefix =0);
+  
+  virtual bool saveState(ossimKeywordlist& kwl,
+                         const char* prefix = 0)const;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimMapViewController.cpp b/Utilities/OSSIM/ossim_core/projections/ossimMapViewController.cpp
new file mode 100644
index 0000000000..34cc364c9d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimMapViewController.cpp
@@ -0,0 +1,215 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimMapViewController.cpp,v 1.21 2004/12/20 15:07:25 gpotts Exp $
+#include <projections/ossimMapViewController.h>
+#include <projections/map_projections/ossimEquDistCylProjection.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+RTTI_DEF1(ossimMapViewController, "ossimMapViewController", ossimViewController);
+
+ossimMapViewController::ossimMapViewController()
+   :ossimViewController()
+{
+}
+
+ossimMapViewController::ossimMapViewController(ossimObject* owner,
+                                               ossim_uint32 inputListSize,
+                                               ossim_uint32 outputListSize,
+                                               bool inputListFixedFlag,
+                                               bool outputListFixedFlag)
+   :ossimViewController(owner,
+                        inputListSize,
+                        outputListSize,
+                        inputListFixedFlag,
+                        outputListFixedFlag)
+{
+   if(theOwner)
+   {
+      const ossimObject* obj = findFirstViewOfType(STATIC_TYPE_INFO(ossimMapProjection));
+      ossimMapProjection* proj = PTR_CAST(ossimMapProjection, obj);
+      
+      if(proj)
+      {
+         // we are initialized to the first view.
+         theView = proj->dup();
+      }
+      else
+      {
+         // initialize the controller to true geographic
+         theView = new ossimEquDistCylProjection;
+      }
+   }
+   else
+   {
+      // initialize the controller to true geographic
+      theView = new ossimEquDistCylProjection;
+   }
+}
+
+ossimMapViewController::~ossimMapViewController()
+{
+}
+
+bool ossimMapViewController::setView(ossimObject* object)
+{
+   if(PTR_CAST(ossimMapProjection, object))
+   {
+      return ossimViewController::setView(object);
+   }
+   
+   return false;
+}
+
+void ossimMapViewController::changeOwner(ossimObject* owner)
+{
+   ossimConnectableObject::changeOwner(owner);
+   
+   if(!theView)
+   {
+      // initialize the controller to geographic
+      const ossimObject* obj   = findFirstViewOfType(STATIC_TYPE_INFO(ossimMapProjection));
+      ossimMapProjection* proj = PTR_CAST(ossimMapProjection, obj);
+      
+      if(proj)
+      {
+         // we are initialized to the first view.
+         setView(proj->dup());
+         propagateView();
+      }
+      else
+      {
+         // initialize the controller to true geographic
+         setView(new ossimEquDistCylProjection);
+         propagateView();
+      }
+   }
+   else
+   {
+      propagateView();
+   }   
+}
+
+void ossimMapViewController::setFilename(const ossimFilename& file)
+{
+   if(file.exists())
+   {
+      ossimKeywordlist kwl;
+      kwl.addFile(file.c_str());
+      
+      ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+      if(PTR_CAST(ossimMapProjection, proj))
+      {
+         setView(proj);
+      }
+      else
+      {
+         if(proj)
+         {
+            delete proj;
+         }
+      }
+   }
+
+   theGeometryFile = file;
+}
+
+
+bool ossimMapViewController::saveState(ossimKeywordlist& kwl,
+                                       const char* prefix)const
+{
+   ossimSource::saveState(kwl, prefix);
+   ossimMapProjection* proj = PTR_CAST(ossimMapProjection, getView());
+
+   ossimString newPrefix = prefix;
+   newPrefix += "projection.";
+   
+   if(proj)
+   {
+      if(theGeometryFile == "")
+      {
+         proj->saveState(kwl, newPrefix.c_str());
+      }
+      else
+      {
+         ofstream output(theGeometryFile.c_str());
+         if(output)
+         {
+            kwl.add(prefix,
+                    ossimKeywordNames::FILENAME_KW,
+                    theGeometryFile);
+            ossimKeywordlist kwl2;
+            proj->saveState(kwl2);
+            kwl2.writeToStream(output);
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimMapViewController::saveState can't open filename " << theGeometryFile
+                                               << "\nsaving inline to passed in keywordlist" << std::endl;
+            proj->saveState(kwl, newPrefix);
+         }
+      }
+   }
+   
+   return true;
+}
+
+bool ossimMapViewController::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   ossimSource::loadState(kwl, prefix);
+
+   theGeometryFile = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   ossimProjection* proj=(ossimProjection*)NULL;
+   
+   if(theGeometryFile == "")
+   {
+      ossimString newPrefix = prefix;
+      newPrefix += "projection.";
+      proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl, newPrefix.c_str());
+   }
+   else
+   {
+      ossimKeywordlist kwl2;
+      kwl2.addFile(theGeometryFile);
+
+      proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl2);
+   }
+   
+   if(PTR_CAST(ossimMapProjection, proj))
+   {
+      setView(proj);
+   }
+   else
+   {
+      if(proj)
+      {
+         delete proj;
+      }      
+   }
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimMapViewController.h b/Utilities/OSSIM/ossim_core/projections/ossimMapViewController.h
new file mode 100644
index 0000000000..57531ade15
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimMapViewController.h
@@ -0,0 +1,72 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+//
+//*************************************************************************
+// $Id: ossimMapViewController.h,v 1.7 2003/05/13 11:31:10 dburken Exp $
+#ifndef ossimMapViewController_HEADER
+#define ossimMapViewController_HEADER
+#include "base/common/ossimViewController.h"
+#include "base/data_types/ossimFilename.h"
+
+class ossimMapViewController : public ossimViewController
+{
+public:
+   ossimMapViewController();
+   ossimMapViewController(ossimObject* owner,
+                          ossim_uint32 inputListSize,
+                          ossim_uint32 outputListSize,
+                          bool         inputListFixedFlag=true,
+                          bool         outputListFixedFlag=false);
+
+   virtual ~ossimMapViewController();
+   virtual bool setView(ossimObject* object);
+   virtual void changeOwner(ossimObject* owner);
+   virtual void setFilename(const ossimFilename& file);
+   virtual const ossimFilename& getFilename()const
+      {
+         return theGeometryFile;
+      }
+   
+   virtual ossimString getShortName()const
+      {
+         return ossimString("Map View");
+      }
+   
+   virtual ossimString getLongName()const
+      {
+         return ossimString("Map View controller");
+      }
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+protected:
+
+   /*!
+    * If the file is not "" (empty) then it will
+    * use this filename to load and save the geometry
+    * projection.
+    */
+   ossimFilename theGeometryFile;
+   
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimProjection.cpp b/Utilities/OSSIM/ossim_core/projections/ossimProjection.cpp
new file mode 100644
index 0000000000..7557c38807
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimProjection.cpp
@@ -0,0 +1,203 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Base class for all projections.  
+//*******************************************************************
+//  $Id: ossimProjection.cpp,v 1.15 2005/09/28 19:23:17 gpotts Exp $
+
+#include <iostream>
+#include <iomanip>
+
+#include <projections/ossimProjection.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/common/ossimKeywordNames.h>
+#include <elevation/ossimElevManager.h>
+#include <base/context/ossimNotifyContext.h>
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimProjection:exec");
+static ossimTrace traceDebug ("ossimProjection:debug");
+
+using namespace std;
+
+RTTI_DEF1(ossimProjection, "ossimProjection", ossimObject);
+
+//*******************************************************************
+// Public constructor:
+//*******************************************************************
+ossimProjection::ossimProjection()
+{
+}
+
+//*****************************************************************************
+//  METHOD: ossimProjection::saveState()
+//*****************************************************************************
+bool ossimProjection::saveState(ossimKeywordlist& kwl,
+                           const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           TYPE_NAME(this),
+           true);
+
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimProjection::loadState()
+//*****************************************************************************
+bool ossimProjection::loadState(const ossimKeywordlist& kwl,
+                                const char*             prefix)
+{
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimProjection::worldToLineSample()
+//  
+//  Performs forward projection of ground point to image space via iterative
+//  calls to lineSampleHeightToWorld
+//  
+//*****************************************************************************
+void ossimProjection::worldToLineSample(const ossimGpt& worldPoint,
+                                         ossimDpt&       ip) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimProjection::worldToLineSample: entering..." << std::endl;
+   static const double PIXEL_THRESHOLD    = 0.1; // acceptable pixel error
+   static const int    MAX_NUM_ITERATIONS = 20;
+
+   //***
+   // First check if the world point is inside bounding rectangle:
+   //***
+   int iters = 0;
+   double height = worldPoint.hgt;
+   if ((height == ossimElevSource::DEFAULT_NULL_HEIGHT)||
+       (height == OSSIM_DBL_NAN))
+      height = 0.0;
+
+   //***
+   // Utilize iterative scheme for arriving at image point. Begin with guess
+   // at image center:
+   //***
+   ip.u = 0;
+   ip.v = 0;
+   
+   ossimDpt ip_du;
+   ossimDpt ip_dv;
+
+   ossimGpt gp, gp_du, gp_dv;
+   double dlat_du, dlat_dv, dlon_du, dlon_dv;
+   double delta_lat, delta_lon, delta_u, delta_v;
+   double inverse_norm;
+   
+   //***
+   // Begin iterations:
+   //***
+   do
+   {
+      //***
+      // establish perturbed image points about the guessed point:
+      //***
+      ip_du.u = ip.u + 1.0;
+      ip_du.v = ip.v;
+      ip_dv.u = ip.u;
+      ip_dv.v = ip.v + 1.0;
+      
+      //***
+      // Compute numerical partials at current guessed point:
+      //***
+      lineSampleHeightToWorld(ip,    height, gp);
+      lineSampleHeightToWorld(ip_du, height, gp_du);
+      lineSampleHeightToWorld(ip_dv, height, gp_dv);
+
+      dlat_du = gp_du.lat - gp.lat; //e
+      dlon_du = gp_du.lon - gp.lon; //g
+      dlat_dv = gp_dv.lat - gp.lat; //f
+      dlon_dv = gp_dv.lon - gp.lon; //h
+
+      //***
+      // Test for convergence:
+      //***
+      delta_lat = worldPoint.lat - gp.lat;
+      delta_lon = worldPoint.lon - gp.lon;
+      
+      //***
+      // Compute linearized estimate of image point given gp delta:
+      //***
+      inverse_norm = dlat_dv*dlon_du - dlat_du*dlon_dv; // fg-eh
+      if (inverse_norm != 0)
+      {
+          delta_u = (-dlon_dv*delta_lat + dlat_dv*delta_lon)/inverse_norm;
+          delta_v = ( dlon_du*delta_lat - dlat_du*delta_lon)/inverse_norm;
+          ip.u += delta_u;
+          ip.v += delta_v;
+      }
+      else
+      {
+         delta_u = 0;
+         delta_v = 0;
+      }
+
+      iters++;
+      
+   } while (((fabs(delta_u) > PIXEL_THRESHOLD) ||
+             (fabs(delta_v) > PIXEL_THRESHOLD)) &&
+            (iters < MAX_NUM_ITERATIONS));
+
+   //***
+   // Note that this error mesage appears only if max count was reached while
+   // iterating. A linear (no iteration) solution would finish with iters =
+   // MAX_NUM_ITERATIONS + 1:
+   //***
+   if (iters == MAX_NUM_ITERATIONS)
+   {
+//       ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimProjection::worldToLineSample: Exceeded max number of iterations computing image \n"
+//            << "point for ground point: " << worldPoint
+//            << "\nCheck the geometry file for valid quantities." << endl;
+   }
+   
+}
+
+void ossimProjection::getRoundTripError(const ossimDpt& imagePoint,
+                                        ossimDpt& errorResult)const
+{
+   ossimGpt world;
+   ossimDpt testPt;
+   
+   lineSampleToWorld(imagePoint, world);
+   worldToLineSample(world, testPt);
+
+   errorResult = imagePoint - testPt;
+}
+
+void ossimProjection::getRoundTripError(const ossimGpt& groundPoint,
+                                        ossimDpt& errorResult)const
+{
+   ossimDpt tempPt;
+   ossimGpt tempGround;
+
+   worldToLineSample(groundPoint, tempPt);
+   lineSampleToWorld(tempPt, tempGround);
+   
+   errorResult = ossimDpt(groundPoint) - ossimDpt(tempGround);
+}
+
+void ossimProjection::getGroundClipPoints(ossimGeoPolygon& gpts)const
+{
+}
+
+std::ostream& ossimProjection::print(std::ostream& out) const
+{
+   return ossimErrorStatusInterface::print(out);
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimProjection.h b/Utilities/OSSIM/ossim_core/projections/ossimProjection.h
new file mode 100644
index 0000000000..b1c405ad54
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimProjection.h
@@ -0,0 +1,148 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description: Base class for all projections (2D-to-3D transform)
+//
+//*******************************************************************
+//  $Id: ossimProjection.h,v 1.20 2005/09/28 19:23:17 gpotts Exp $
+#ifndef ossimProjection_HEADER
+#define ossimProjection_HEADER
+#include <iostream>
+
+#include <base/common/ossimObject.h>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimKeyword.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimGeoPolygon.h>
+#include <elevation/ossimElevManager.h>
+
+class OSSIMDLLEXPORT ossimProjection : public ossimObject,
+   public ossimErrorStatusInterface
+{
+public:
+   /*!
+    * Constructors, Destructor:
+    */
+   ossimProjection();
+   virtual ~ossimProjection() {}
+
+   virtual ossimObject *dup()const=0;
+
+   /*!
+    * METHOD: origin()
+    * Returns projection's ground point origin. That is the GP corresponding
+    * to line=0, sample=0.
+    */
+   virtual ossimGpt origin()const=0;
+
+   /*!
+    * METHODS: forward(), reverse() 
+    * OBSOLETE -- provided for existing GUI code only. Bogus return value.
+    */
+   virtual ossimDpt forward(const ossimGpt &wp) const;  //inline below
+   virtual ossimGpt inverse(const ossimDpt &pp) const;  //inline below
+
+   /*!
+    * METHOD: worldToLineSample()
+    * Performs the forward projection from ground point to line, sample.
+    */
+   virtual void worldToLineSample(const ossimGpt& worldPoint,
+                                  ossimDpt&       lineSampPt) const = 0;
+
+   /*!
+    * METHOD: lineSampleToWorld()
+    * Performs the inverse projection from line, sample to ground (world):
+    */
+   virtual void lineSampleToWorld(const ossimDpt& lineSampPt,
+                                  ossimGpt&       worldPt) const = 0;
+   
+   /*!
+    * METHOD: lineSampleHeightToWorld
+    * This is the pure virtual that projects the image point to the given
+    * elevation above ellipsoid, thereby bypassing reference to a DEM. Useful
+    * for projections that are sensitive to elevation (such as sensor models).
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                        const double&   heightAboveEllipsoid,
+                                        ossimGpt&       worldPt) const = 0;
+
+   virtual void getRoundTripError(const ossimDpt& imagePoint,
+                                  ossimDpt& errorResult)const;
+
+   virtual void getRoundTripError(const ossimGpt& groundPoint,
+                                  ossimDpt& errorResult)const;
+   
+   virtual std::ostream& print(std::ostream& out) const;
+
+   virtual void getGroundClipPoints(ossimGeoPolygon& gpts)const;
+   /*!
+    * METHODS:  saveState, loadState
+    * Fulfills ossimObject base-class pure virtuals.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /*!
+    * OPERATOR: ==
+    * Compares this instance with arg projection. NOT IMPLEMENTED.
+    */
+   virtual bool operator==(const ossimProjection& projection) const=0;
+
+   /*!
+    * ACCESS METHODS: 
+    */
+   virtual ossimDpt getMetersPerPixel() const=0;
+   
+protected:
+   
+
+   TYPE_DATA
+};
+
+//====================== BEGIN INLINE DEFINITIONS ===========================
+
+//*****************************************************************************
+//  INLINE METHOD: ossimProjection::forward()
+//  Projects ground point to 2D plane.
+//*****************************************************************************
+inline ossimDpt ossimProjection::forward(const ossimGpt &wp) const
+{
+   ossimDpt p;
+   worldToLineSample(wp, p);
+   return p;
+}
+
+//*****************************************************************************
+//  INLINE METHOD: ossimProjection::inverse()
+//  Inverse projection from 2D plane to ground point.
+//*****************************************************************************
+inline ossimGpt ossimProjection::inverse(const ossimDpt &pp) const
+{
+   ossimGpt g;
+   lineSampleToWorld(pp, g);
+   return g;
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimQuadProjection.cpp b/Utilities/OSSIM/ossim_core/projections/ossimQuadProjection.cpp
new file mode 100644
index 0000000000..7d837f08fb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimQuadProjection.cpp
@@ -0,0 +1,543 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems, Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimQuadProjection.cpp,v 1.3 2004/06/17 14:13:36 dburken Exp $
+
+#include <projections/ossimQuadProjection.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimEcefVector.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/common/ossimKeywordNames.h>
+#include <elevation/ossimElevManager.h>
+
+RTTI_DEF1(ossimQuadProjection, "ossimQuadProjection", ossimProjection);
+
+ossimQuadProjection::ossimQuadProjection()
+      :ossimProjection()
+{
+   theInputRect.makeNan();
+   theUlg.makeNan();
+   theUrg.makeNan();
+   theLrg.makeNan();
+   theLlg.makeNan();
+}
+
+ossimQuadProjection::ossimQuadProjection(const ossimQuadProjection& rhs)
+   :ossimProjection(rhs),
+    theInputRect(rhs.theInputRect),
+    theUlg(rhs.theUlg),
+    theUrg(rhs.theUrg),
+    theLrg(rhs.theLrg),
+    theLlg(rhs.theLlg),
+    theLatGrid(rhs.theLatGrid),
+    theLonGrid(rhs.theLonGrid)
+{
+}
+
+ossimQuadProjection::ossimQuadProjection(const ossimIrect& rect,
+                                         const ossimGpt& ulg,
+                                         const ossimGpt& urg,
+                                         const ossimGpt& lrg,
+                                         const ossimGpt& llg)
+      :theInputRect(rect),
+       theUlg(ulg),
+       theUrg(urg),
+       theLrg(lrg),
+       theLlg(llg)
+{
+   initializeGrids();
+}
+                       
+ossimQuadProjection::~ossimQuadProjection()
+{
+}
+
+ossimObject *ossimQuadProjection::dup()const
+{
+   return new ossimQuadProjection(*this);
+}
+
+ossimGpt ossimQuadProjection::origin()const
+{
+   ossimGpt result;
+   result.makeNan();
+   if(theUlg.isLatNan()||
+      theUlg.isLonNan()||
+      theUrg.isLatNan()||
+      theUrg.isLonNan()||
+      theLrg.isLatNan()||
+      theLrg.isLonNan()||
+      theLlg.isLatNan()||
+      theLlg.isLonNan())
+   {
+      return result;
+   }
+
+   result.latd( (theUlg.latd() + theUrg.latd() + theLrg.latd() + theLlg.latd())*.25);
+   result.lond( (theUlg.lond() + theUrg.lond() + theLrg.lond() + theLlg.lond())*.25);
+
+   result.datum(theUlg.datum());
+   
+   return result;
+}
+
+void ossimQuadProjection::worldToLineSample(const ossimGpt& worldPoint,
+                                            ossimDpt&       lineSampPt) const
+{
+   ossimProjection::worldToLineSample(worldPoint, lineSampPt);
+}
+
+void ossimQuadProjection::lineSampleToWorld(const ossimDpt& lineSampPt,
+                                            ossimGpt&       worldPt) const
+{
+   lineSampleHeightToWorld(lineSampPt,
+                           OSSIM_DBL_NAN,
+                           worldPt);
+   
+}
+
+void ossimQuadProjection::lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                                  const double&   heightAboveEllipsoid,
+                                                  ossimGpt&       worldPt) const
+{
+   worldPt.makeNan();
+   worldPt.datum(theUlg.datum());
+   
+   if(theUlg.isLatNan()||
+      theUlg.isLonNan()||
+      theUrg.isLatNan()||
+      theUrg.isLonNan()||
+      theLrg.isLatNan()||
+      theLrg.isLonNan()||
+      theLlg.isLatNan()||
+      theLlg.isLonNan()||
+      theInputRect.hasNans())
+   {
+      return;
+   }
+
+   if(!theInputRect.pointWithin(lineSampPt))
+   {
+      worldPt = extrapolate(lineSampPt,
+                            heightAboveEllipsoid);
+      worldPt.hgt = ossimElevManager::instance()->getHeightAboveEllipsoid(worldPt);
+      return;
+   }
+   
+   worldPt.lat = theLatGrid(lineSampPt);
+   worldPt.lon = theLonGrid(lineSampPt);
+   worldPt.hgt = heightAboveEllipsoid;
+   worldPt.hgt = ossimElevManager::instance()->getHeightAboveEllipsoid(worldPt);
+}   
+
+bool ossimQuadProjection::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix)const
+{
+   ossimProjection::saveState(kwl, prefix);
+   kwl.add(prefix,
+           ossimKeywordNames::DATUM_KW,
+           theUlg.datum()->code(),
+           true);
+   
+   if(theInputRect.hasNans())
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::UL_X_KW,
+              "nan",
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::UL_Y_KW,
+              "nan",
+              true);
+      kwl.add(prefix,
+              "width",
+              0,
+              true);
+      kwl.add(prefix,
+              "height",
+              0,
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::UL_X_KW,
+              theInputRect.ul().x,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::UL_Y_KW,
+              theInputRect.ul().y,
+              true);
+      kwl.add(prefix,
+              "width",
+              theInputRect.width(),
+              true);
+      kwl.add(prefix,
+              "height",
+              theInputRect.height(),
+              true);
+   }
+   
+   if(theUlg.isLatNan()||
+      theUlg.isLonNan()||
+      theUrg.isLatNan()||
+      theUrg.isLonNan()||
+      theLrg.isLatNan()||
+      theLrg.isLonNan()||
+      theLlg.isLatNan()||
+      theLlg.isLonNan())
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::UL_LAT_KW,
+              "nan",
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::UL_LON_KW,
+              "nan",
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::UR_LAT_KW,
+              "nan",
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::UR_LON_KW,
+              "nan",
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LR_LAT_KW,
+              "nan",
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LR_LON_KW,
+              "nan",
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LL_LAT_KW,
+              "nan",
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LL_LON_KW,
+              "nan",
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::UL_LAT_KW,
+              theUlg.latd(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::UL_LON_KW,
+              theUlg.lond(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::UR_LAT_KW,
+              theUrg.latd(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::UR_LON_KW,
+              theUrg.lond(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LR_LAT_KW,
+              theLrg.latd(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LR_LON_KW,
+              theLrg.lond(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LL_LAT_KW,
+              theLlg.latd(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LL_LON_KW,
+              theLlg.lond(),
+              true);
+   }
+   return true;
+}
+
+bool ossimQuadProjection::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   ossimProjection::loadState(kwl, prefix);
+   theUlg.makeNan();
+   theUrg.makeNan();
+   theLrg.makeNan();
+   theLlg.makeNan();
+   theInputRect.makeNan();
+
+   ossimString ulLat = kwl.find(prefix, ossimKeywordNames::UL_LAT_KW);
+   ossimString ulLon = kwl.find(prefix, ossimKeywordNames::UL_LON_KW);
+   ossimString urLat = kwl.find(prefix, ossimKeywordNames::UR_LAT_KW);
+   ossimString urLon = kwl.find(prefix, ossimKeywordNames::UR_LON_KW);
+   ossimString lrLat = kwl.find(prefix, ossimKeywordNames::LR_LAT_KW);
+   ossimString lrLon = kwl.find(prefix, ossimKeywordNames::LR_LON_KW);
+   ossimString llLat = kwl.find(prefix, ossimKeywordNames::LL_LAT_KW);
+   ossimString llLon = kwl.find(prefix, ossimKeywordNames::LL_LON_KW);
+   ossimString datum = kwl.find(prefix, ossimKeywordNames::DATUM_KW);
+   ossimString ulX    = kwl.find(prefix, ossimKeywordNames::UL_X_KW);
+   ossimString ulY    = kwl.find(prefix, ossimKeywordNames::UL_Y_KW);
+   ossimString width  = kwl.find(prefix, "width");
+   ossimString height = kwl.find(prefix, "height");
+
+   if(ulLat == "nan")
+   {
+      theUlg.latd(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      theUlg.latd(ulLat.toDouble());
+   }
+   if(ulLon == "nan")
+   {
+      theUlg.lond(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      theUlg.lond(ulLon.toDouble());
+   }
+   
+   if(urLat == "nan")
+   {
+      theUrg.latd(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      theUrg.latd(urLat.toDouble());
+   }
+   if(urLon == "nan")
+   {
+      theUrg.lond(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      theUrg.lond(urLon.toDouble());
+   }
+   
+   if(lrLat == "nan")
+   {
+      theLrg.latd(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      theLrg.latd(lrLat.toDouble());
+   }
+   if(lrLon == "nan")
+   {
+      theLrg.lond(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      theLrg.lond(lrLon.toDouble());
+   }
+   
+   if(llLat == "nan")
+   {
+      theLlg.latd(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      theLlg.latd(llLat.toDouble());
+   }
+   if(llLon == "nan")
+   {
+      theLlg.lond(OSSIM_DBL_NAN);
+   }
+   else
+   {
+      theLlg.lond(llLon.toDouble());
+   }
+
+   ossimIpt ul;
+   
+   ul.makeNan();
+   
+   if((ulX != "nan") &&
+      (ulY != "nan"))
+   {
+      ul.x = ulX.toInt32();
+      ul.y = ulY.toInt32();
+   }
+   ossim_uint32 w = width.toUInt32();
+   ossim_uint32 h = height.toUInt32();
+   if(datum == "")
+   {
+      datum = "WGE";
+   }
+   const ossimDatum* datumPtr = ossimDatumFactory::instance()->create(datum);
+   theUlg.datum(datumPtr);
+   theUrg.datum(datumPtr);
+   theLrg.datum(datumPtr);
+   theLlg.datum(datumPtr);
+   
+   if(w&&h)
+   {
+      theInputRect = ossimIrect(ul.x,
+                                ul.y,
+                                ul.x + w - 1,
+                                ul.y + h - 1);
+   }
+   else
+   {
+      theInputRect.makeNan();
+   }
+
+   initializeGrids();
+
+   return true;
+}
+
+bool ossimQuadProjection::operator==(const ossimProjection& projection) const
+{
+   return false;
+}
+
+ossimDpt ossimQuadProjection::getMetersPerPixel() const
+{
+   ossimGpt centerG;
+   ossimGpt rightG;
+   ossimGpt topG;
+
+   lineSampleToWorld(theInputRect.midPoint(), centerG);
+   lineSampleToWorld(theInputRect.midPoint()+ossimDpt(1,0), rightG);
+   lineSampleToWorld(theInputRect.midPoint()+ossimDpt(0,-1), topG);
+   
+   ossimEcefPoint centerP = centerG;
+   ossimEcefPoint rightP  = rightG;
+   ossimEcefPoint topP    = topG;
+
+   ossimEcefVector horizontal = rightP-centerP;
+   ossimEcefVector vertical   = topP-centerP;
+
+   ossimDpt result(horizontal.magnitude(),
+                   vertical.magnitude());
+
+   result.x = (result.x + result.y)/2.0;
+   result.y = result.x;
+
+   
+   return result;
+}
+
+void ossimQuadProjection::initializeGrids()
+{
+   ossimIpt gridSize(2,2);
+   
+   ossimDpt spacing = ossimDpt((double)(theInputRect.width()-1)/(gridSize.x-1),
+                               (double)(theInputRect.height()-1)/(gridSize.y-1));
+   
+   theLatGrid.setNullValue(OSSIM_DBL_NAN);
+   theLonGrid.setNullValue(OSSIM_DBL_NAN);
+   theLatGrid.initialize(gridSize, theInputRect.ul(), spacing);
+   theLonGrid.initialize(gridSize, theInputRect.ul(), spacing);
+
+   theLatGrid.setNode(0,0, theUlg.latd());
+   theLatGrid.setNode(1,0, theUrg.latd());
+   theLatGrid.setNode(1,1, theLrg.latd());
+   theLatGrid.setNode(0,1, theLlg.latd());
+
+   theLonGrid.setNode(0,0, theUlg.lond());
+   theLonGrid.setNode(1,0, theUrg.lond());
+   theLonGrid.setNode(1,1, theLrg.lond());
+   theLonGrid.setNode(0,1, theLlg.lond());
+}
+
+ossimGpt ossimQuadProjection::extrapolate(const ossimDpt& imagePoint,
+                                          const double&   height) const
+{
+   //***
+   // If image point supplied has NaN components, return now with a NaN point.
+   // This prevents an infinite recursion between model worldToLineSample
+   // and this method:
+   //***
+   if ((imagePoint.line == OSSIM_DBL_NAN) || (imagePoint.samp == OSSIM_DBL_NAN))
+   {
+      return ossimGpt(OSSIM_DBL_NAN, OSSIM_DBL_NAN, OSSIM_DBL_NAN);
+   }
+
+   //***
+   // Determine which edge is intersected by the radial, and establish
+   // intersection:
+   //***
+   ossimGpt gpt;
+   ossimDpt edgePt (imagePoint);
+   ossimDpt image_center (theInputRect.midPoint());
+   ossimDrect clipRect = theInputRect;
+   clipRect.clip(image_center, edgePt);
+
+   //***
+   // Need edgePt relative to image center. Compute an epsilon perturbation in
+   // the direction of edgePt for later computing directional derivative,
+   // and back out the offset to origin:
+   //***
+   ossimDpt deltaPt (edgePt - image_center);
+   ossimDpt epsilon (deltaPt/deltaPt.length());
+   edgePt -= epsilon;  // insure that we are inside the image
+   ossimDpt edgePt_prime (edgePt - epsilon); // epsilon=1pixel
+       
+   //***
+   // Establish ground point corresponding to edge point and edgePt+epsilon:
+   //***
+   ossimGpt edgeGP;
+   ossimGpt edgeGP_prime;
+
+   if (height == OSSIM_DBL_NAN)
+   {
+      lineSampleToWorld(edgePt, edgeGP);
+      lineSampleToWorld(edgePt_prime, edgeGP_prime);
+   }
+   else
+   {
+      lineSampleHeightToWorld(edgePt, height, edgeGP);
+      lineSampleHeightToWorld(edgePt_prime, height, edgeGP_prime);
+   }
+   
+   //***
+   // Compute approximate directional derivatives of lat and lon along radial
+   // at the edge:
+   //***
+   double dpixel    = (edgePt-edgePt_prime).length();
+   double dlat_drad = (edgeGP.lat - edgeGP_prime.lat)/dpixel;
+   double dlon_drad = (edgeGP.lon - edgeGP_prime.lon)/dpixel;
+
+   //***
+   // Now extrapolate to image point of interest:
+   //***
+   double delta_pixel = (imagePoint - edgePt).length();
+
+   gpt.lat = edgeGP.lat + dlat_drad*delta_pixel;
+   gpt.lon = edgeGP.lon + dlon_drad*delta_pixel;
+//    if (height == OSSIM_DBL_NAN)
+//    {
+//       gpt.hgt = theElevation->getHeightAboveMSL(gpt);
+//    }
+//    else
+      gpt.hgt = height;
+   
+   return gpt;
+   
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimQuadProjection.h b/Utilities/OSSIM/ossim_core/projections/ossimQuadProjection.h
new file mode 100644
index 0000000000..d99c49f252
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimQuadProjection.h
@@ -0,0 +1,88 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems, Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts
+// 
+//********************************************************************
+// $Id: ossimQuadProjection.h,v 1.3 2004/06/17 14:13:36 dburken Exp $
+#ifndef ossimQuadProjection_HEADER
+#define ossimQuadProjection_HEADER
+
+#include <projections/ossimProjection.h>
+#include <base/data_types/ossimIrect.h>
+#include <base/data_types/ossimDblGrid.h>
+
+class ossimQuadProjection : public ossimProjection
+{
+ public:
+   ossimQuadProjection();
+   ossimQuadProjection(const ossimQuadProjection& rhs);
+   ossimQuadProjection(const ossimIrect& rect,
+                       const ossimGpt& ulg,
+                       const ossimGpt& urg,
+                       const ossimGpt& lrg,
+                       const ossimGpt& llg);
+                       
+   virtual ~ossimQuadProjection();
+   virtual ossimObject *dup()const;
+   virtual ossimGpt origin()const;
+   
+   virtual void worldToLineSample(const ossimGpt& worldPoint,
+                                  ossimDpt&       lineSampPt) const;
+   /*!
+    * METHOD: lineSampleToWorld()
+    * Performs the inverse projection from line, sample to ground (world):
+    */
+   virtual void lineSampleToWorld(const ossimDpt& lineSampPt,
+                                  ossimGpt&       worldPt) const;
+   
+   /*!
+    * METHOD: lineSampleHeightToWorld
+    * This is the pure virtual that projects the image point to the given
+    * elevation above ellipsoid, thereby bypassing reference to a DEM. Useful
+    * for projections that are sensitive to elevation (such as sensor models).
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                        const double&   heightAboveEllipsoid,
+                                        ossimGpt&       worldPt) const;
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0)const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   virtual bool operator==(const ossimProjection& projection) const;
+   virtual ossimDpt getMetersPerPixel() const;
+
+ protected:
+   ossimIrect theInputRect;
+   ossimGpt theUlg;
+   ossimGpt theUrg;
+   ossimGpt theLrg;
+   ossimGpt theLlg;
+
+   ossimDblGrid theLatGrid;   
+   ossimDblGrid theLonGrid;
+
+   void initializeGrids();
+   ossimGpt extrapolate(const ossimDpt& imagePoint,
+                        const double&   height) const;
+TYPE_DATA   
+};
+
+#endif /* #ifndef ossimQuadProjection_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimRpcProjection.cpp b/Utilities/OSSIM/ossim_core/projections/ossimRpcProjection.cpp
new file mode 100644
index 0000000000..b2d07f3c23
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimRpcProjection.cpp
@@ -0,0 +1,788 @@
+//*****************************************************************************
+// FILE: ossimRpcModel.cc
+//
+// Copyright (C) 2004 Intelligence Data Systems.
+//
+// LGPL
+// 
+// AUTHOR: Garrett Potts
+//
+//*****************************************************************************
+//$Id: ossimRpcProjection.cpp,v 1.4 2005/09/22 11:58:12 gpotts Exp $
+
+#include <projections/ossimRpcProjection.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimEcefVector.h>
+
+RTTI_DEF1(ossimRpcProjection, "ossimRpcProjection", ossimProjection);
+
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <cstdio>
+#include <fstream>
+#include <iostream>
+#include <algorithm>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimRpcProjection:exec");
+static ossimTrace traceDebug ("ossimRpcProjection:debug");
+
+static const int    MODEL_VERSION_NUMBER  = 1;
+static const int    NUM_COEFFS        = 20;
+static const char*  MODEL_TYPE        = "ossimRpcModel";
+static const char*  POLY_TYPE_KW      = "polynomial_format";
+static const char*  LINE_SCALE_KW     = "line_scale";
+static const char*  SAMP_SCALE_KW     = "samp_scale";
+static const char*  LAT_SCALE_KW      = "lat_scale";
+static const char*  LON_SCALE_KW      = "long_scale";
+static const char*  HGT_SCALE_KW      = "height_scale";
+static const char*  LINE_OFFSET_KW    = "line_off";
+static const char*  SAMP_OFFSET_KW    = "samp_off";
+static const char*  LAT_OFFSET_KW     = "lat_off";
+static const char*  LON_OFFSET_KW     = "long_off";
+static const char*  HGT_OFFSET_KW     = "height_off";
+static const char*  LINE_NUM_COEF_KW  = "line_num_coeff_";
+static const char*  LINE_DEN_COEF_KW  = "line_den_coeff_";
+static const char*  SAMP_NUM_COEF_KW  = "samp_num_coeff_";
+static const char*  SAMP_DEN_COEF_KW  = "samp_den_coeff_";
+
+//*****************************************************************************
+//  DEFAULT CONSTRUCTOR: ossimRpcModel()
+//  
+//*****************************************************************************
+ossimRpcProjection::ossimRpcProjection()
+   : ossimProjection()
+ {
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection Default Constructor: entering..." << std::endl;
+
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection Default Constructor: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: ossimRpcProjection(ossimRpcProjection)
+//  
+//*****************************************************************************
+ossimRpcProjection::ossimRpcProjection(const ossimRpcProjection& model)
+   :
+      ossimProjection(model),
+      thePolyType     (model.thePolyType),
+      theLineScale    (model.theLineScale),
+      theSampScale    (model.theSampScale),
+      theLatScale     (model.theLatScale),
+      theLonScale     (model.theLonScale),
+      theHgtScale     (model.theHgtScale),
+      theLineOffset   (model.theLineOffset),
+      theSampOffset   (model.theSampOffset),
+      theLatOffset    (model.theLatOffset),
+      theLonOffset    (model.theLonOffset),
+      theHgtOffset    (model.theHgtOffset)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection Copy Constructor: entering..." << std::endl;
+
+   for (int i=0; i<20; i++)
+   {
+      theLineNumCoef[i] = model.theLineNumCoef[i];
+      theLineDenCoef[i] = model.theLineDenCoef[i];
+      theSampNumCoef[i] = model.theSampNumCoef[i];
+      theSampDenCoef[i] = model.theSampDenCoef[i];
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection Copy Constructor: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimRpcProjection()
+//  
+//*****************************************************************************
+ossimRpcProjection::~ossimRpcProjection()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ~ossimRpcProjection() Destructor: entering..." << std::endl;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNotify(ossimNotifyLevel_DEBUG): returning..." << std::endl;
+}
+
+void ossimRpcProjection::setAttributes(ossim_float64 sampleOffset,
+                                       ossim_float64 lineOffset,
+                                       ossim_float64 sampleScale,
+                                       ossim_float64 lineScale,
+                                       ossim_float64 latOffset,
+                                       ossim_float64 lonOffset,
+                                       ossim_float64 heightOffset,
+                                       ossim_float64 latScale,
+                                       ossim_float64 lonScale,
+                                       ossim_float64 heightScale,
+                                       const std::vector<double>& xNumeratorCoeffs,
+                                       const std::vector<double>& xDenominatorCoeffs,
+                                       const std::vector<double>& yNumeratorCoeffs,
+                                       const std::vector<double>& yDenominatorCoeffs,
+                                       PolynomialType polyType)
+{
+   thePolyType = polyType;
+   
+   theLineScale  = lineScale;
+   theSampScale  = sampleScale;
+   theLatScale   = latScale;
+   theLonScale   = lonScale;
+   theHgtScale   = heightScale;
+   theLineOffset = lineOffset;
+   theSampOffset = sampleOffset;
+   theLatOffset  = latOffset;
+   theLonOffset  = lonOffset;
+   theHgtOffset  = heightOffset;
+
+   if(xNumeratorCoeffs.size() == 20)
+   {
+      std::copy(xNumeratorCoeffs.begin(),
+                xNumeratorCoeffs.end(),
+                theSampNumCoef);
+   }
+   if(xDenominatorCoeffs.size() == 20)
+   {
+      std::copy(xDenominatorCoeffs.begin(),
+                xDenominatorCoeffs.end(),
+                theSampDenCoef);
+   }
+   if(yNumeratorCoeffs.size() == 20)
+   {
+      std::copy(yNumeratorCoeffs.begin(),
+                yNumeratorCoeffs.end(),
+                theLineNumCoef);
+   }
+   if(yDenominatorCoeffs.size() == 20)
+   {
+      std::copy(yDenominatorCoeffs.begin(),
+                yDenominatorCoeffs.end(),
+                theLineDenCoef);
+   }
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimRpcProjection::worldToLineSample()
+//  
+//  Overrides base class implementation. Directly computes line-sample from
+//  the polynomials.
+//*****************************************************************************
+void ossimRpcProjection::worldToLineSample(const ossimGpt& ground_point,
+                                      ossimDpt&       imgPt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::worldToLineSample(): entering..." << std::endl;
+
+   if(ground_point.isLatNan() ||
+      ground_point.isLonNan() )
+     {
+       imgPt.makeNan();
+       return;
+     }
+   //***
+   // Normalize the lat, lon, hgt:
+   //***
+   double nlat = (ground_point.lat - theLatOffset) / theLatScale;
+   double nlon = (ground_point.lon - theLonOffset) / theLonScale;
+   double nhgt;
+
+   if(ground_point.hgt == OSSIM_DBL_NAN)
+   {
+      nhgt = (theHgtScale - theHgtOffset) / theHgtScale;
+   }
+   else
+   {
+      nhgt = (ground_point.hgt - theHgtOffset) / theHgtScale;
+   }
+   //
+   // Compute the adjusted, normalized line (U) and sample (V):
+   //
+   imgPt.x = (polynomial(nlat, nlon, nhgt, theSampNumCoef)/
+              polynomial(nlat, nlon, nhgt, theSampDenCoef))*theSampScale + theSampOffset;
+   
+   imgPt.y = (polynomial(nlat, nlon, nhgt, theLineNumCoef)/
+              polynomial(nlat, nlon, nhgt, theLineDenCoef))*theLineScale + theLineOffset ;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::worldToLineSample(): returning..." << std::endl;
+
+   return;
+}
+
+void  ossimRpcProjection::lineSampleToWorld(const ossimDpt& imagePoint,
+                                            ossimGpt&       worldPoint) const
+{
+   if(!imagePoint.hasNans())
+   {
+      lineSampleHeightToWorld(imagePoint,
+                              worldPoint.height(),
+                              worldPoint);
+   }
+   else
+   {
+      worldPoint.makeNan();
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimRpcProjection::lineSampleHeightToWorld()
+//  
+//  Performs reverse projection of image line/sample to ground point.
+//  The imaging ray is intersected with a level plane at height = elev.
+//
+//  NOTE: U = line, V = sample -- this differs from the convention.
+//
+//*****************************************************************************
+void ossimRpcProjection::lineSampleHeightToWorld(const ossimDpt& image_point,
+                                            const double&   ellHeight,
+                                            ossimGpt&       gpt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::lineSampleHeightToWorld: entering..." << std::endl;
+
+   //
+   // Constants for convergence tests:
+   //
+   static const int    MAX_NUM_ITERATIONS  = 10;
+   static const double CONVERGENCE_EPSILON = 0.1;  // pixels
+   
+   //
+   // The image point must be adjusted by the adjustable parameters as well
+   // as the scale and offsets given as part of the RPC param normalization.
+   //
+   //      NOTE: U = line, V = sample
+   //
+   double U    = (image_point.y-theLineOffset)/(theLineScale);
+   double V    = (image_point.x-theSampOffset)/(theSampScale);
+
+
+   // now apply adjust intrack and cross track
+   //***
+   // Initialize quantities to be used in the iteration for ground point:
+   //***
+   double nlat      = 0.0;  // normalized latitude
+   double nlon      = 0.0;  // normalized longitude
+   
+   double nhgt;
+
+   if(ellHeight == OSSIM_DBL_NAN)
+   {
+     nhgt = (theHgtScale - theHgtOffset) / theHgtScale;  // norm height
+   }
+   else
+   {
+      nhgt = (ellHeight - theHgtOffset) / theHgtScale;  // norm height
+   }
+   
+   double epsilonU = CONVERGENCE_EPSILON/(theLineScale);
+   double epsilonV = CONVERGENCE_EPSILON/(theSampScale);
+   int    iteration = 0;
+
+   //***
+   // Declare variables only once outside the loop. These include:
+   // * polynomials (numerators Pu, Pv, and denominators Qu, Qv),
+   // * partial derivatives of polynomials wrt X, Y,
+   // * computed normalized image point: Uc, Vc,
+   // * residuals of normalized image point: deltaU, deltaV,
+   // * partial derivatives of Uc and Vc wrt X, Y,
+   // * corrections to normalized lat, lon: deltaLat, deltaLon.
+   //***
+   double Pu, Qu, Pv, Qv;
+   double dPu_dLat, dQu_dLat, dPv_dLat, dQv_dLat;
+   double dPu_dLon, dQu_dLon, dPv_dLon, dQv_dLon;
+   double Uc, Vc;
+   double deltaU, deltaV;
+   double dU_dLat, dU_dLon, dV_dLat, dV_dLon, W;
+   double deltaLat, deltaLon;
+   
+   //***
+   // Now iterate until the computed Uc, Vc is within epsilon of the desired
+   // image point U, V:
+   //***
+   do
+   {
+      //***
+      // Calculate the normalized line and sample Uc, Vc as ratio of
+      // polynomials Pu, Qu and Pv, Qv:
+      //***
+      Pu = polynomial(nlat, nlon, nhgt, theLineNumCoef);
+      Qu = polynomial(nlat, nlon, nhgt, theLineDenCoef);
+      Pv = polynomial(nlat, nlon, nhgt, theSampNumCoef);
+      Qv = polynomial(nlat, nlon, nhgt, theSampDenCoef);
+      Uc = Pu/Qu;
+      Vc = Pv/Qv;
+      
+      //***
+      // Compute residuals between desired and computed line, sample:
+      //***
+      deltaU = U - Uc;
+      deltaV = V - Vc;
+      
+      //***
+      // Check for convergence and skip re-linearization if converged:
+      //***
+      if ((fabs(deltaU) > epsilonU) || (fabs(deltaV) > epsilonV))
+      {
+         //***
+         // Analytically compute the partials of each polynomial wrt lat, lon:
+         //***
+         dPu_dLat = dPoly_dLat(nlat, nlon, nhgt, theLineNumCoef);
+         dQu_dLat = dPoly_dLat(nlat, nlon, nhgt, theLineDenCoef);
+         dPv_dLat = dPoly_dLat(nlat, nlon, nhgt, theSampNumCoef);
+         dQv_dLat = dPoly_dLat(nlat, nlon, nhgt, theSampDenCoef);
+         dPu_dLon = dPoly_dLon(nlat, nlon, nhgt, theLineNumCoef);
+         dQu_dLon = dPoly_dLon(nlat, nlon, nhgt, theLineDenCoef);
+         dPv_dLon = dPoly_dLon(nlat, nlon, nhgt, theSampNumCoef);
+         dQv_dLon = dPoly_dLon(nlat, nlon, nhgt, theSampDenCoef);
+         
+         //***
+         // Analytically compute partials of quotients U and V wrt lat, lon: 
+         //***
+         dU_dLat = (Qu*dPu_dLat - Pu*dQu_dLat)/(Qu*Qu);
+         dU_dLon = (Qu*dPu_dLon - Pu*dQu_dLon)/(Qu*Qu);
+         dV_dLat = (Qv*dPv_dLat - Pv*dQv_dLat)/(Qv*Qv);
+         dV_dLon = (Qv*dPv_dLon - Pv*dQv_dLon)/(Qv*Qv);
+         
+         W = dU_dLon*dV_dLat - dU_dLat*dV_dLon;
+         
+         //***
+         // Now compute the corrections to normalized lat, lon:
+         //***
+         deltaLat = (dU_dLon*deltaV - dV_dLon*deltaU) / W;
+         deltaLon = (dV_dLat*deltaU - dU_dLat*deltaV) / W;
+         nlat += deltaLat;
+         nlon += deltaLon;
+      }
+      
+      iteration++;
+      
+   } while (((fabs(deltaU)>epsilonU) || (fabs(deltaV)>epsilonV))
+            && (iteration < MAX_NUM_ITERATIONS));
+      
+   //***
+   // Test for exceeding allowed number of iterations. Flag error if so:
+   //***
+   if (iteration == MAX_NUM_ITERATIONS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimRpcProjection::lineSampleHeightToWorld: \nMax number of iterations reached in ground point "
+                                         << "solution. Results are inaccurate." << endl;
+   }
+
+   //***
+   // Now un-normalize the ground point lat, lon and establish return quantity:
+   //***
+   gpt.lat = nlat*theLatScale + theLatOffset;
+   gpt.lon = nlon*theLonScale + theLonOffset;
+   gpt.hgt = ellHeight;
+   
+}
+
+ossimGpt ossimRpcProjection::origin()const
+{
+   return ossimGpt(theLatOffset,
+                   theLonOffset,
+                   theHgtOffset);
+}
+
+
+ossimDpt ossimRpcProjection::getMetersPerPixel() const
+{
+   ossimDpt left  = ossimDpt(theSampOffset-1,
+                             theLineOffset);
+   ossimDpt right = ossimDpt(theSampOffset+1,
+                             theLineOffset);
+   ossimDpt top  = ossimDpt(theSampOffset,
+                            theLineOffset-1);
+   ossimDpt bottom = ossimDpt(theSampOffset,
+                              theLineOffset+1);
+   ossimGpt leftG;
+   ossimGpt rightG;
+   ossimGpt topG;
+   ossimGpt bottomG;
+   
+   lineSampleToWorld(left, leftG);
+   lineSampleToWorld(right, rightG);
+   lineSampleToWorld(top, topG);
+   lineSampleToWorld(bottom, bottomG);
+
+   ossimDpt result;
+   
+   result.x = (ossimEcefPoint(leftG) - ossimEcefPoint(rightG)).magnitude()/2.0;
+   result.y = (ossimEcefPoint(topG) - ossimEcefPoint(bottomG)).magnitude()/2.0;
+
+   return result;
+}
+
+bool ossimRpcProjection::operator==(const ossimProjection& projection) const
+{
+   if(&projection == this) return true;
+
+   // not implemented yet
+   //
+   return false;
+}
+
+//*****************************************************************************
+// PRIVATE METHOD: ossimRpcProjection::polynomial
+//  
+//  Computes polynomial.
+//  
+//*****************************************************************************
+double ossimRpcProjection::polynomial(const double& P, const double& L,
+                                      const double& H, const double* c) const
+{
+   double r;
+
+   if (thePolyType == A)
+   {
+      r = c[ 0]       + c[ 1]*L     + c[ 2]*P     + c[ 3]*H     +
+          c[ 4]*L*P   + c[ 5]*L*H   + c[ 6]*P*H   + c[ 7]*L*P*H +
+          c[ 8]*L*L   + c[ 9]*P*P   + c[10]*H*H   + c[11]*L*L*L +
+          c[12]*L*L*P + c[13]*L*L*H + c[14]*L*P*P + c[15]*P*P*P +
+          c[16]*P*P*H + c[17]*L*H*H + c[18]*P*H*H + c[19]*H*H*H;
+   }
+   else
+   {
+      r = c[ 0]       + c[ 1]*L     + c[ 2]*P     + c[ 3]*H     +
+          c[ 4]*L*P   + c[ 5]*L*H   + c[ 6]*P*H   + c[ 7]*L*L   +
+          c[ 8]*P*P   + c[ 9]*H*H   + c[10]*L*P*H + c[11]*L*L*L +
+          c[12]*L*P*P + c[13]*L*H*H + c[14]*L*L*P + c[15]*P*P*P +
+          c[16]*P*H*H + c[17]*L*L*H + c[18]*P*P*H + c[19]*H*H*H;
+   }
+   
+   return r;
+}
+
+//*****************************************************************************
+// PRIVATE METHOD: ossimRpcProjection::dPoly_dLat
+//  
+//  Computes derivative of polynomial wrt normalized Latitude P.
+//  
+//*****************************************************************************
+double ossimRpcProjection::dPoly_dLat(const double& P, const double& L,
+                                 const double& H, const double* c) const
+{
+   double dr;
+
+   if (thePolyType == A)
+   {
+      dr = c[2] + c[4]*L + c[6]*H + c[7]*L*H + 2*c[9]*P + c[12]*L*L +
+           2*c[14]*L*P + 3*c[15]*P*P +2*c[16]*P*H + c[18]*H*H;
+   }
+   else
+   {
+      dr = c[2] + c[4]*L + c[6]*H + 2*c[8]*P + c[10]*L*H + 2*c[12]*L*P +
+           c[14]*L*L + 3*c[15]*P*P + c[16]*H*H + 2*c[18]*P*H;
+   }
+   
+   return dr;
+}
+
+//*****************************************************************************
+// PRIVATE METHOD: ossimRpcProjection::dPoly_dLon
+//  
+//  Computes derivative of polynomial wrt normalized Longitude L.
+//  
+//*****************************************************************************
+double ossimRpcProjection::dPoly_dLon(const double& P, const double& L,
+                                 const double& H, const double* c) const
+{
+   double dr;
+
+   if (thePolyType == A)
+   {
+      dr = c[1] + c[4]*P + c[5]*H + c[7]*P*H + 2*c[8]*L + 3*c[11]*L*L +
+           2*c[12]*L*P + 2*c[13]*L*H + c[14]*P*P + c[17]*H*H;
+   }
+   else
+   {
+      dr = c[1] + c[4]*P + c[5]*H + 2*c[7]*L + c[10]*P*H + 3*c[11]*L*L +
+           c[12]*P*P + c[13]*H*H + 2*c[14]*P*L + 2*c[17]*L*H;
+   }
+   return dr;
+}
+
+//*****************************************************************************
+//  METHOD: ossimRpcProjection::print()
+//  
+//  Formatted dump of data members.
+//  
+//*****************************************************************************
+std::ostream& ossimRpcProjection::print(std::ostream& out) const
+{
+   out << "\nDump of ossimRpcProjection object at " << hex << this << ":\n"
+       << POLY_TYPE_KW   << ": " << thePolyType   << "\n"
+       << LINE_SCALE_KW  << ": " << theLineScale  << "\n"
+       << SAMP_SCALE_KW  << ": " << theSampScale  << "\n"
+       << LAT_SCALE_KW   << ": " << theLatScale   << "\n"
+       << LON_SCALE_KW   << ": " << theLonScale   << "\n"
+       << HGT_SCALE_KW   << ": " << theHgtScale   << "\n"
+       << LINE_OFFSET_KW << ": " << theLineOffset << "\n"
+       << SAMP_OFFSET_KW << ": " << theSampOffset << "\n"
+       << LAT_OFFSET_KW  << ": " << theLatOffset  << "\n"
+       << LON_OFFSET_KW  << ": " << theLonOffset  << "\n"
+       << HGT_OFFSET_KW  << ": " << theHgtOffset  << endl;
+
+   for (int i=0; i<NUM_COEFFS; i++)
+      out<<"  "<<LINE_NUM_COEF_KW<<"["<<i<<"]: "<<theLineNumCoef[i]<<endl;
+
+   out << endl;
+   for (int i=0; i<NUM_COEFFS; i++)
+      out<<"  "<<LINE_DEN_COEF_KW<<"["<<i<<"]: "<<theLineDenCoef[i]<<endl;
+
+   out << endl;
+   for (int i=0; i<NUM_COEFFS; i++)
+      out<<"  "<<SAMP_NUM_COEF_KW<<"["<<i<<"]: "<<theSampNumCoef[i]<<endl;
+
+   out << endl;
+   for (int i=0; i<NUM_COEFFS; i++)
+      out<<"  "<<SAMP_DEN_COEF_KW<<"["<<i<<"]: "<<theSampDenCoef[i]<<endl;
+      
+   out << endl;
+
+   return ossimProjection::print(out);
+}
+
+//*****************************************************************************
+//  METHOD: ossimRpcProjection::saveState()
+//  
+//  Saves the model state to the KWL. This KWL also serves as a geometry file.
+//  
+//*****************************************************************************
+bool ossimRpcProjection::saveState(ossimKeywordlist& kwl,
+                              const char* prefix) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::saveState(): entering..." << std::endl;
+
+   kwl.add(prefix, ossimKeywordNames::TYPE_KW, MODEL_TYPE);
+
+   //***
+   // Hand off to base class for common stuff:
+   //***
+   ossimProjection::saveState(kwl, prefix);
+
+   kwl.add(prefix,
+           POLY_TYPE_KW,
+           (char)thePolyType,
+           true);
+   
+   kwl.add(prefix, LINE_SCALE_KW, theLineScale);
+   kwl.add(prefix, SAMP_SCALE_KW, theSampScale);
+   kwl.add(prefix, LAT_SCALE_KW, theLatScale);
+   kwl.add(prefix, LON_SCALE_KW, theLonScale);
+   kwl.add(prefix, HGT_SCALE_KW, theHgtScale);
+   kwl.add(prefix, LINE_OFFSET_KW, theLineOffset);
+   kwl.add(prefix, SAMP_OFFSET_KW, theSampOffset);
+   kwl.add(prefix, LAT_OFFSET_KW, theLatOffset);
+   kwl.add(prefix, LON_OFFSET_KW, theLonOffset);
+   
+   kwl.add(prefix, HGT_OFFSET_KW, theHgtOffset);
+
+   for (int i=0; i<NUM_COEFFS; i++)
+   {
+      kwl.add(prefix, (LINE_NUM_COEF_KW + ossimString::toString(i)).c_str(), theLineNumCoef[i]);
+      kwl.add(prefix, (LINE_DEN_COEF_KW + ossimString::toString(i)).c_str(), theLineDenCoef[i]);
+      kwl.add(prefix, (SAMP_NUM_COEF_KW + ossimString::toString(i)).c_str(), theSampNumCoef[i]);
+      kwl.add(prefix, (SAMP_DEN_COEF_KW + ossimString::toString(i)).c_str(), theSampDenCoef[i]);
+   }
+      
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::saveState(): returning..." << std::endl;
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimRpcProjection::loadState()
+//  
+//  Restores the model's state from the KWL. This KWL also serves as a
+//  geometry file.
+//  
+//*****************************************************************************
+bool ossimRpcProjection::loadState(const ossimKeywordlist& kwl,
+                              const char* prefix) 
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::loadState(): entering..." << std::endl;
+
+   const char* value;
+   const char* keyword;
+
+   //***
+   // Pass on to the base-class for parsing first:
+   //***
+   bool success = ossimProjection::loadState(kwl, prefix);
+   if (!success)
+   {
+      theErrorStatus++;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::loadState(): returning with error..." << std::endl;
+      return false;
+   }
+      
+   //***
+   // Continue parsing for local members:
+   //***
+   keyword = POLY_TYPE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   thePolyType = (PolynomialType) value[0];
+      
+   keyword = LINE_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLineScale = ossimString(value).toDouble();
+   
+   keyword = SAMP_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theSampScale = ossimString(value).toDouble();
+   
+   keyword = LAT_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLatScale = ossimString(value).toDouble();
+   
+   keyword = LON_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLonScale = ossimString(value).toDouble();
+   
+   keyword = HGT_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theHgtScale = ossimString(value).toDouble();
+   
+   keyword = LINE_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLineOffset = ossimString(value).toDouble();
+   
+   keyword = SAMP_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theSampOffset = ossimString(value).toDouble();
+   
+   keyword = LAT_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLatOffset = ossimString(value).toDouble();
+   
+   keyword = LON_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLonOffset = ossimString(value).toDouble();
+   
+   keyword = HGT_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theHgtOffset = ossimString(value).toDouble();
+
+   for (int i=0; i<NUM_COEFFS; i++)
+   {
+      value = kwl.find(prefix, (LINE_NUM_COEF_KW+ossimString::toString(i)).c_str());
+      if (!value)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                             << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                             << std::endl;
+         return false;
+      }
+      theLineNumCoef[i] = ossimString(value).toDouble();
+   
+      value = kwl.find(prefix, (LINE_DEN_COEF_KW+ossimString::toString(i)).c_str());
+      if (!value)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                             << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                             << std::endl;
+         return false;
+      }
+      theLineDenCoef[i] = ossimString(value).toDouble();
+   
+      value = kwl.find(prefix, (SAMP_NUM_COEF_KW+ossimString::toString(i)).c_str());
+      if (!value)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                             << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                             << std::endl;
+         return false;
+      }
+      theSampNumCoef[i] = ossimString(value).toDouble();
+      
+      value = kwl.find(prefix, (SAMP_DEN_COEF_KW+ossimString::toString(i)).c_str());
+      if (!value)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::loadState(): Error encountered parsing the following required keyword: "
+                                             << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                             << std::endl;
+         return false;
+      }
+      theSampDenCoef[i] = ossimString(value).toDouble();
+   }
+      
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcProjection::loadState(): returning..." << std::endl;
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimRpcProjection.h b/Utilities/OSSIM/ossim_core/projections/ossimRpcProjection.h
new file mode 100644
index 0000000000..589555b4c9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimRpcProjection.h
@@ -0,0 +1,151 @@
+//*****************************************************************************
+// FILE: ossimRpcProjection.h
+//
+// Copyright (C) 2004 Intelligence Data Syatems
+//
+// LGPL
+//
+// DESCRIPTION: Contains declaration of class ossimRpcProjection.
+//   This is a replacement model utilizing the Rational Polynomial Coefficients
+//   (RPC), a.k.a. Rapid Positioning Capability, and Universal Sensor Model
+//   (USM).
+//
+//*****************************************************************************
+//  $Id: ossimRpcProjection.h,v 1.2 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimRpcProjection_HEADER
+#define ossimRpcProjection_HEADER
+
+#include <projections/ossimProjection.h>
+#include <base/data_types/ossimIpt.h>
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimRpcProjection
+ *
+ *****************************************************************************/
+class OSSIM_DLL ossimRpcProjection : public ossimProjection
+{
+public:
+   //***
+   // Enumeration of supported RPC polynomial formats:
+   //***
+   enum PolynomialType
+   {
+      A='A',  // corresponds to "RPC00A"
+      B='B'   // corresponds to "RPC00B"
+   };
+   
+   /*!
+    * CONSTRUCTORS:
+    */
+   ossimRpcProjection();
+   ossimRpcProjection(const ossimRpcProjection& copy_this);
+   ~ossimRpcProjection();
+
+   void setAttributes(ossim_float64 theSampleOffset,
+                      ossim_float64 theLineOffset,
+                      ossim_float64 theSampleScale,
+                      ossim_float64 theLineScale,
+                      ossim_float64 theLatOffset,
+                      ossim_float64 theLonOffset,
+                      ossim_float64 theHeightOffset,
+                      ossim_float64 theLatScale,
+                      ossim_float64 theLonScale,
+                      ossim_float64 theHeightScale,
+                      const std::vector<double>& xNumeratorCoeffs,
+                      const std::vector<double>& xDenominatorCoeffs,
+                      const std::vector<double>& yNumeratorCoeffs,
+                      const std::vector<double>& yDenominatorCoeffs,
+                      PolynomialType polyType = B);
+                      
+   /*!
+    * METHOD: worldToLineSample()
+    * Overrides base class implementation. Directly computes line-sample from
+    * the polynomials.
+    */
+   virtual void  worldToLineSample(const ossimGpt& world_point,
+                                   ossimDpt&       image_point) const;
+   /*!
+    * METHOD: print()
+    * Extends base-class implementation. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+   /*!
+    * METHODS:  saveState, loadState
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files. Returns true if successful.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual void  lineSampleToWorld(const ossimDpt& image_point,
+                                   ossimGpt&       world_point) const;
+   //***
+   // METHOD: lineSampleHeightToWorld()
+   // Overrides base class pure virtual. Height understood to be relative to
+   // standard ellipsoid.
+   //***
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const double&   heightEllipsoid,
+                                        ossimGpt&       worldPoint) const;
+
+   /*!
+    * METHOD: dup()
+    * Returns pointer to a new instance, copy of this.
+    */
+   virtual ossimObject* dup() const { return new ossimRpcProjection(*this); }
+
+   virtual ossimGpt origin()const;
+   virtual ossimDpt getMetersPerPixel() const;
+   virtual bool operator==(const ossimProjection& projection) const;
+   
+protected:
+   //***
+   // Methods for computing RPC polynomial and its derivatives:
+   //***
+   double polynomial(const double& nlat,
+                     const double& nlon,
+                     const double& nhgt,
+                     const double* coeffs) const;
+   double dPoly_dLat(const double& nlat,
+                     const double& nlon,
+                     const double& nhgt,
+                     const double* coeffs) const;
+   double dPoly_dLon(const double& nlat,
+                     const double& nlon,
+                     const double& nhgt,
+                     const double* coeffs) const;
+   
+   PolynomialType thePolyType;
+   //***
+   // Quantities for zero-biasing and normalizing the image point and
+   // ground point coordinates referenced in the polynomials:
+   //***
+   double theLineScale;
+   double theSampScale;
+   double theLatScale;
+   double theLonScale;
+   double theHgtScale;
+   double theLineOffset;
+   double theSampOffset;
+   double theLatOffset;
+   double theLonOffset;
+   double theHgtOffset;
+
+   //***
+   // Coefficients:
+   //***
+   double theLineNumCoef[20];
+   double theLineDenCoef[20];
+   double theSampNumCoef[20];
+   double theSampDenCoef[20];
+   
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimRpcSolver.cpp b/Utilities/OSSIM/ossim_core/projections/ossimRpcSolver.cpp
new file mode 100644
index 0000000000..05544db4f6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimRpcSolver.cpp
@@ -0,0 +1,792 @@
+//*****************************************************************************
+// FILE: ossimRpcModel.h
+//
+// Copyright (C) 2004 Intelligence Data Systems, Inc.
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+//
+// AUTHOR: Garrett Potts
+//
+//*****************************************************************************
+//  $Id: ossimRpcSolver.cpp,v 1.15 2005/10/12 10:48:44 dburken Exp $
+#include <projections/ossimRpcSolver.h>
+#include <projections/sensor_modeling/rpc/ossimRpcModel.h>
+#include <projections/ossimProjection.h>
+#include <matrix/newmatap.h>
+#include <matrix/newmatio.h>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <time.h>
+#include <matrix/newmatnl.h>
+#include <matrix/newmatio.h>
+#include <elevation/ossimElevManager.h>
+#include <support_data/nitf/ossimNitfRpcBTag.h>
+
+ossimRpcSolver::ossimRpcSolver(bool useElevation,
+                               bool heightAboveMSLFlag)
+{
+   theUseElevationFlag = useElevation;
+   theHeightAboveMSLFlag = heightAboveMSLFlag;
+   theXNumCoeffs.resize(20);
+   theXDenCoeffs.resize(20);
+   theYNumCoeffs.resize(20);
+   theYDenCoeffs.resize(20);
+
+   std::fill(theXNumCoeffs.begin(),
+             theXNumCoeffs.end(), 0.0);
+   std::fill(theXDenCoeffs.begin(),
+             theXDenCoeffs.end(), 0.0);
+   std::fill(theYNumCoeffs.begin(),
+             theYNumCoeffs.end(), 0.0);
+   std::fill(theYDenCoeffs.begin(),
+             theYDenCoeffs.end(), 0.0);
+   theXNumCoeffs[0] = 1.0;
+   theXDenCoeffs[0] = 1.0;
+   theYNumCoeffs[0] = 1.0;
+   theYDenCoeffs[0] = 1.0;
+}
+
+void ossimRpcSolver::solveCoefficients(const ossimDrect& imageBounds,
+                                       const ossimProjection& proj,
+                                       ossim_uint32 xSamples,
+                                       ossim_uint32 ySamples,
+                                       bool shiftTo0Flag)
+{
+   std::vector<ossimGpt> theGroundPoints;
+   std::vector<ossimDpt> theImagePoints;
+   ossim_uint32 x,y;
+   ossim_float64 w = imageBounds.width();
+   ossim_float64 h = imageBounds.height();
+   ossimGpt gpt;
+   ossimGpt defaultGround;
+   if(ySamples < 1) ySamples = 12;
+   if(xSamples < 1) xSamples = 12;
+   srand(time(0));
+   double xnorm;
+   double ynorm;
+   ossimDpt ul = imageBounds.ul();
+   ossimDpt shiftTo0(-ul.x,
+                     -ul.y);
+   for(y = 0; y < ySamples; ++y)
+   {
+      for(x = 0; x < xSamples; ++x)
+      {
+         if(ySamples > 1)
+         {
+            ynorm = (double)y/(double)(ySamples-1.0);
+         }
+         else
+         {
+            ynorm = 0.0;
+         }
+         if(xSamples > 1)
+         {
+            xnorm = (double)x/(double)(xSamples-1.0);
+         }
+         else
+         {
+            xnorm = 0.0;
+         }
+         
+         ossimDpt dpt((.25 + .5*xnorm)*w + ul.x,
+                      (.25 + .5*ynorm)*h + ul.y);
+         
+         proj.lineSampleToWorld(dpt,
+                                gpt);
+         gpt.changeDatum(defaultGround.datum());
+
+         if(shiftTo0Flag)
+         {
+            theImagePoints.push_back(dpt+shiftTo0);
+         }
+         else
+         {
+            theImagePoints.push_back(dpt);
+         }
+         if(theHeightAboveMSLFlag)
+         {
+            double h = ossimElevManager::instance()->getHeightAboveMSL(gpt);
+            gpt.height(h);
+         }
+         theGroundPoints.push_back(gpt);
+      }
+   }
+   solveCoefficients(theImagePoints,
+                     theGroundPoints);
+}
+
+void ossimRpcSolver::solveCoefficients(const std::vector<ossimDpt>& imagePoints,
+                                       const std::vector<ossimGpt>& groundControlPoints,
+                                       const ossimDpt& imageShift)
+{
+   if((imagePoints.size() != groundControlPoints.size()))
+   {
+      return;
+   }
+
+   // we will first create f which holds the result of f(x,y,z).
+   // This basically holds the cooresponding image point for each
+   // ground control point.  One for x and a second array for y
+   //
+   std::vector<double> f[2];
+
+   //  Holds the x, y, z vectors
+   //
+   std::vector<double> x;
+   std::vector<double> y;
+   std::vector<double> z;
+   ossim_uint32 c = 0;
+   f[0].resize(imagePoints.size());
+   f[1].resize(imagePoints.size());
+   x.resize(imagePoints.size());
+   y.resize(imagePoints.size());
+   z.resize(imagePoints.size());
+
+   // compute the image bounds for the given image points
+   //
+   ossimDrect rect(imagePoints);
+
+   // get the widtha dn height that will be used
+   // in data normalization
+   //
+   ossim_float64 w = rect.width();
+   ossim_float64 h = rect.width();
+
+   // setup scales for normalization
+//   ossim_float64 xScale = w/2.0;
+//   ossim_float64 yScale = h/2.0;
+
+   // get the shift for the cneter of the data
+   ossimDpt centerImagePoint  = rect.midPoint();
+   
+   double latSum=0.0;
+   double lonSum=0.0;
+   double heightSum=0.0;
+
+   // find the center ground  Use elevation only if its enabled
+   //
+   for(c = 0; c < groundControlPoints.size();++c)
+   {
+      if(groundControlPoints[c].latd() != OSSIM_DBL_NAN)
+      {
+         latSum += groundControlPoints[c].latd();
+      }
+      if(groundControlPoints[c].lond() != OSSIM_DBL_NAN)
+      {
+         lonSum += groundControlPoints[c].lond();
+      }
+      if(!groundControlPoints[c].isHgtNan())
+      {
+         if(theUseElevationFlag)
+         {
+            heightSum += groundControlPoints[c].height();
+         }
+      }
+   }
+
+   // set the center ground for the offset
+   //
+   ossimGpt centerGround(latSum/groundControlPoints.size(),
+                         lonSum/groundControlPoints.size(),
+                         heightSum/groundControlPoints.size());
+
+   // set up ground scales and deltas for normalization
+   //
+//   ossim_float64 latScale       = 0.0;
+//   ossim_float64 lonScale       = 0.0;
+//   ossim_float64 heightScale    = 0.0;
+   ossim_float64 deltaLat       = 0.0;
+   ossim_float64 deltaLon       = 0.0;
+   ossim_float64 deltaHeight    = 0.0;
+   ossim_float64 maxDeltaLat    = 0.0;
+   ossim_float64 maxDeltaLon    = 0.0;
+   ossim_float64 maxDeltaHeight = 0.0;
+   for(c = 0; c < groundControlPoints.size(); ++c)
+   {
+      deltaLat = (groundControlPoints[c].latd()-centerGround.latd());
+      deltaLon = (groundControlPoints[c].lond()-centerGround.lond());
+      if(!groundControlPoints[c].isHgtNan())
+      {
+         if(theUseElevationFlag)
+         {
+            deltaHeight = groundControlPoints[c].height() - centerGround.height();
+         }
+         else
+         {
+            deltaHeight = 0.0;
+         }
+      }
+      else
+      {
+         deltaHeight = 0.0;
+      }
+      f[0][c] = (imagePoints[c].x - centerImagePoint.x)/(w/2.0);
+      f[1][c] = (imagePoints[c].y - centerImagePoint.y)/(h/2.0);
+      
+      x[c] = deltaLon;
+      y[c] = deltaLat;
+      z[c] = deltaHeight;
+
+      if(fabs(deltaLat) > maxDeltaLat) maxDeltaLat          = fabs(deltaLat);
+      if(fabs(deltaLon) > maxDeltaLon) maxDeltaLon          = fabs(deltaLon);
+      if(fabs(deltaHeight) > maxDeltaHeight) maxDeltaHeight = fabs(deltaHeight);
+   }
+
+   // if the delta is already between -1 to 1 I guess its safe not to normalize
+   // so force the divisor to 1.0
+   //
+   if(maxDeltaLat < 1)    maxDeltaLat = 1.0;
+   if(maxDeltaLon < 1)    maxDeltaLon = 1.0;
+   if(maxDeltaHeight < 1) maxDeltaHeight = 1.0;
+
+   // normalize the ground points
+   for(c = 0; c < groundControlPoints.size(); ++c)
+   {
+      x[c] /= maxDeltaLon;
+      y[c] /= maxDeltaLat;
+      z[c] /= maxDeltaHeight;
+   }
+
+   theLatScale    = maxDeltaLat;
+   theLonScale    = maxDeltaLon;
+   theHeightScale = maxDeltaHeight;
+
+   
+   theImageOffset = centerImagePoint;
+   theImageScale  = ossimDpt(w/2.0,
+                             h/2.0);
+   theGroundOffset = centerGround;
+
+   if(theGroundOffset.height() == OSSIM_DBL_NAN)
+   {
+      theGroundOffset.height(0.0);
+   }
+
+   // now lets solve the coefficients
+   //
+   std::vector<double> coeffx;
+   std::vector<double> coeffy;
+
+   NEWMAT::ColumnVector coeffxVec;
+   NEWMAT::ColumnVector coeffyVec;
+   // perform a least squares fit for sample values found in f
+   // given the world values with variables x, y, z
+   //
+   solveCoefficients(coeffxVec,
+                     f[0],
+                     x,
+                     y,
+                     z);
+
+   
+   // perform a least squares fit for line values found in f
+   // given the world values with variables x, y, z
+   //
+   solveCoefficients(coeffyVec,
+                     f[1],
+                     x,
+                     y,
+                     z);
+
+   coeffx.resize(coeffxVec.Nrows());
+   coeffy.resize(coeffyVec.Nrows());
+   
+   for(c = 0; c < coeffx.size();++c)
+   {
+      coeffx[c] = coeffxVec[c];
+      coeffy[c] = coeffyVec[c];
+   }
+   // there are 20 numerator coefficients
+   // and 19 denominator coefficients
+   // I believe that the very first one for the
+   // denominator coefficients is fixed at 1.0
+   //
+   std::copy(coeffx.begin(),
+             coeffx.begin()+20,
+             theXNumCoeffs.begin());
+   std::copy(coeffx.begin()+20,
+             coeffx.begin()+39,
+             theXDenCoeffs.begin()+1);
+   std::copy(coeffy.begin(),
+             coeffy.begin()+20,
+             theYNumCoeffs.begin());
+   std::copy(coeffy.begin()+20,
+             coeffy.begin()+39,
+             theYDenCoeffs.begin()+1);
+   theXDenCoeffs[0] = 1.0;
+   theYDenCoeffs[0] = 1.0;
+
+
+   // now lets compute the RMSE for the given control points by feeding it
+   // back through the modeled RPC
+   //
+   ossim_float64  sumSquareError = 0.0;
+   ossim_uint32 idx = 0;
+
+//    std::cout << "ground offset height = " << theGroundOffset.height()
+//              << "Height scale         = " << theHeightScale << std::endl;
+   for (idx = 0; idx<imagePoints.size(); idx++)
+   {
+       ossim_float64 x = (groundControlPoints[idx].lond() - theGroundOffset.lond())/theLonScale;
+       ossim_float64 y = (groundControlPoints[idx].latd() - theGroundOffset.latd())/theLatScale;
+       ossim_float64 z = (groundControlPoints[idx].height() - theGroundOffset.height())/theHeightScale;
+
+      if(z == OSSIM_DBL_NAN)
+      {
+         z = 0.0;
+      }
+      else
+      {
+         z = (z - theGroundOffset.height())/theHeightScale;
+      }
+
+       ossim_float64 imageX = ((eval(theXNumCoeffs, x, y, z)/
+                                eval(theXDenCoeffs, x, y, z))*theImageScale.x) + theImageOffset.x;
+      
+       ossim_float64 imageY = ((eval(theYNumCoeffs, x, y, z)/
+                                eval(theYDenCoeffs, x, y, z))*theImageScale.y) + theImageOffset.y;
+      
+      ossimDpt evalPt(imageX, imageY);
+      ossim_float64 len = (evalPt - imagePoints[idx]).length();
+      
+      sumSquareError += (len*len);
+   }
+
+   // set the error
+   //
+   theError = sqrt(sumSquareError/imagePoints.size());
+}
+
+ossimRefPtr<ossimRpcModel> ossimRpcSolver::createRpcModel()const
+{
+   ossimRpcModel* model = new ossimRpcModel;
+   
+   model->setAttributes(theImageOffset.x,
+                        theImageOffset.y,
+                        theImageScale.x,
+                        theImageScale.y,
+                        theGroundOffset.latd(),
+                        theGroundOffset.lond(),
+                        theGroundOffset.height(),
+                        theLatScale,
+                        theLonScale,
+                        theHeightScale,
+                        theXNumCoeffs,
+                        theXDenCoeffs,
+                        theYNumCoeffs,
+                        theYDenCoeffs);
+   return model;
+}
+
+ossimRefPtr<ossimRpcProjection> ossimRpcSolver::createRpcProjection()const
+{
+   ossimRpcProjection* proj = new ossimRpcProjection;
+   
+   proj->setAttributes(theImageOffset.x,
+                       theImageOffset.y,
+                       theImageScale.x,
+                       theImageScale.y,
+                       theGroundOffset.latd(),
+                       theGroundOffset.lond(),
+                       theGroundOffset.height(),
+                       theLatScale,
+                       theLonScale,
+                       theHeightScale,
+                       theXNumCoeffs,
+                       theXDenCoeffs,
+                       theYNumCoeffs,
+                       theYDenCoeffs);
+   return proj;
+}
+
+const std::vector<double>& ossimRpcSolver::getImageXNumCoefficients()const
+{
+   return theXNumCoeffs;
+}
+
+const std::vector<double>& ossimRpcSolver::getImageXDenCoefficients()const
+{
+   return theXDenCoeffs;
+}
+
+const std::vector<double>& ossimRpcSolver::getImageYNumCoefficients()const
+{
+   return theYNumCoeffs;
+}
+
+const std::vector<double>& ossimRpcSolver::getImageYDenCoefficients()const
+{
+   return theYDenCoeffs;
+}
+
+double ossimRpcSolver::getImageXOffset()const
+{
+   return theImageOffset.x;
+}
+
+double ossimRpcSolver::getImageYOffset()const
+{
+   return theImageOffset.y;
+}
+
+double ossimRpcSolver::getLatOffset()const
+{
+   return theGroundOffset.latd();
+}
+
+double ossimRpcSolver::getLonOffset()const
+{
+   return theGroundOffset.lond();
+}
+
+double ossimRpcSolver::getHeightOffset()const
+{
+   return theGroundOffset.height();
+}
+
+double ossimRpcSolver::getImageXScale()const
+{
+   return theImageScale.x;
+}
+
+double ossimRpcSolver::getImageYScale()const
+{
+   return theImageScale.y;
+}
+
+double ossimRpcSolver::getLatScale()const
+{
+   return theLatScale;
+}
+
+double ossimRpcSolver::getLonScale()const
+{
+   return theLonScale;
+}
+
+double ossimRpcSolver::getHeightScale()const
+{
+   return theHeightScale;
+}
+
+double ossimRpcSolver::getRmsError()const
+{
+   return theError;
+}
+
+void ossimRpcSolver::solveInitialCoefficients(NEWMAT::ColumnVector& coeff,
+                                              const std::vector<double>& f,
+                                              const std::vector<double>& x,
+                                              const std::vector<double>& y,
+                                              const std::vector<double>& z)const
+{
+   ossim_uint32 idx = 0;
+   NEWMAT::Matrix m;
+   NEWMAT::ColumnVector r(f.size());
+   for(idx = 0; idx < f.size(); ++idx)
+   {
+      r[idx] = f[idx];
+   }
+   setupSystemOfEquations(m,
+                          r,
+                          x,
+                          y,
+                          z);
+   
+   coeff = invert(m.t()*m)*m.t()*r;
+}
+
+void ossimRpcSolver::solveCoefficients(NEWMAT::ColumnVector& coeff,
+                                       const std::vector<double>& f,
+                                       const std::vector<double>& x,
+                                       const std::vector<double>& y,
+                                       const std::vector<double>& z)const
+{
+   // this is an iterative  linear least square fit.  We really pobably need
+   // a nonlinear fit instead
+   //
+   ossim_uint32 idx = 0;
+   NEWMAT::Matrix m;
+
+   NEWMAT::ColumnVector r(f.size());
+
+   for(idx = 0; idx < f.size(); ++idx)
+   {
+      r[idx] = f[idx];
+   }
+
+   NEWMAT::ColumnVector tempCoeff;
+   NEWMAT::DiagonalMatrix weights(f.size());
+   NEWMAT::ColumnVector denominator(20);
+
+   // initialize the weight matrix to the identity
+   //
+   for(idx = 0; idx < f.size(); ++idx)
+   {
+      weights[idx] = 1.0;
+   }
+
+   double residualValue = 1.0/FLT_EPSILON;
+   ossim_uint32 iterations = 0;
+   NEWMAT::Matrix w2;
+   do
+   {
+      w2 = weights*weights;
+
+      // sets up the matrix to hold the system of
+      // equations
+      setupSystemOfEquations(m,
+                             r,
+                             x,
+                             y,
+                             z);
+
+      // solve the least sqaures solution.  Note: the invert is used
+      // to do a Singular Value Decomposition for the inverse since the
+      // matrix is more than likely singular.  Slower but more robust
+      //
+      tempCoeff = invert(m.t()*w2*m)*m.t()*w2*r;
+
+      // set up the weight matrix by using the denominator
+      //
+      for(idx = 0; idx < 19; ++idx)
+      {
+         denominator[idx+1] = tempCoeff[20+idx];
+      }
+      denominator[0] = 1.0;
+      
+      setupWeightMatrix(weights,
+                        denominator,
+                        r,
+                        x,
+                        y,
+                        z);
+
+      // compute the residual
+      //
+      NEWMAT::ColumnVector residual = (m.t()*w2*m*tempCoeff-m.t()*w2*r);
+
+      // now get the innerproduct
+      //
+      NEWMAT::Matrix tempRes = (residual.t()*residual);
+      residualValue = tempRes[0][0];
+
+      ++iterations;
+      
+   }while((residualValue >FLT_EPSILON)&&
+          (iterations < 10));
+   coeff = tempCoeff;
+
+}
+
+NEWMAT::Matrix ossimRpcSolver::invert(const NEWMAT::Matrix& m)const
+{
+   ossim_uint32 idx = 0;
+   NEWMAT::DiagonalMatrix d;
+   NEWMAT::Matrix u;
+   NEWMAT::Matrix v;
+
+   // decompose m.t*m which is stored in Temp into the singular values and vectors.
+   //
+   NEWMAT::SVD(m, d, u, v, true, true);
+   
+   // invert the diagonal
+   // this is just doing the reciprical fo all diagonal components and store back int
+   // d.  ths compute d inverse.
+   //
+   for(idx=0; idx < (ossim_uint32)d.Ncols(); ++idx)
+   {
+      if(d[idx] > FLT_EPSILON)
+      {
+         d[idx] = 1.0/d[idx];
+      }
+      else
+      {
+         d[idx] = 0.0;
+      }
+   }
+
+   //compute inverse of decomposed m;
+   return v*d*u.t();
+}
+
+
+void ossimRpcSolver::setupSystemOfEquations(NEWMAT::Matrix& equations,
+                                            const NEWMAT::ColumnVector& f,
+                                            const std::vector<double>& x,
+                                            const std::vector<double>& y,
+                                            const std::vector<double>& z)const
+{
+   ossim_uint32 idx;
+   equations.ReSize(f.Nrows(),
+                    39);
+   
+   for(idx = 0; idx < (ossim_uint32)f.Nrows();++idx)
+   {
+      equations[idx][0]  = 1;
+      equations[idx][1]  = x[idx];
+      equations[idx][2]  = y[idx];
+      equations[idx][3]  = z[idx];
+      equations[idx][4]  = x[idx]*y[idx];
+      equations[idx][5]  = x[idx]*z[idx];
+      equations[idx][6]  = y[idx]*z[idx];
+      equations[idx][7]  = x[idx]*x[idx];
+      equations[idx][8]  = y[idx]*y[idx];
+      equations[idx][9]  = z[idx]*z[idx];
+      equations[idx][10] = x[idx]*y[idx]*z[idx];
+      equations[idx][11] = x[idx]*x[idx]*x[idx];
+      equations[idx][12] = x[idx]*y[idx]*y[idx];
+      equations[idx][13] = x[idx]*z[idx]*z[idx];
+      equations[idx][14] = x[idx]*x[idx]*y[idx];
+      equations[idx][15] = y[idx]*y[idx]*y[idx];
+      equations[idx][16] = y[idx]*z[idx]*z[idx];
+      equations[idx][17] = z[idx]*x[idx]*z[idx];
+      equations[idx][18] = y[idx]*y[idx]*z[idx];
+      equations[idx][19] = z[idx]*z[idx]*z[idx];
+      equations[idx][20] = -f[idx]*x[idx];
+      equations[idx][21] = -f[idx]*y[idx];
+      equations[idx][22] = -f[idx]*z[idx];
+      equations[idx][23] = -f[idx]*x[idx]*y[idx];
+      equations[idx][24] = -f[idx]*x[idx]*z[idx];
+      equations[idx][25] = -f[idx]*y[idx]*z[idx];
+      equations[idx][26] = -f[idx]*x[idx]*x[idx];
+      equations[idx][27] = -f[idx]*y[idx]*y[idx];
+      equations[idx][28] = -f[idx]*z[idx]*z[idx];
+      equations[idx][29] = -f[idx]*x[idx]*y[idx]*z[idx];
+      equations[idx][30] = -f[idx]*x[idx]*x[idx]*x[idx];
+      equations[idx][31] = -f[idx]*x[idx]*y[idx]*y[idx];
+      equations[idx][32] = -f[idx]*x[idx]*z[idx]*z[idx];
+      equations[idx][33] = -f[idx]*x[idx]*x[idx]*y[idx];
+      equations[idx][34] = -f[idx]*y[idx]*y[idx]*y[idx];
+      equations[idx][35] = -f[idx]*y[idx]*z[idx]*z[idx];
+      equations[idx][36] = -f[idx]*z[idx]*x[idx]*z[idx];
+      equations[idx][37] = -f[idx]*y[idx]*y[idx]*z[idx];
+      equations[idx][38] = -f[idx]*z[idx]*z[idx]*z[idx];
+   }
+}
+
+void ossimRpcSolver::setupWeightMatrix(NEWMAT::DiagonalMatrix& result, // holds the resulting weights
+                                       const NEWMAT::ColumnVector& coefficients,
+                                       const NEWMAT::ColumnVector& f,
+                                       const std::vector<double>& x,
+                                       const std::vector<double>& y,
+                                       const std::vector<double>& z)const
+{
+   result.ReSize(f.Nrows());
+   ossim_uint32 idx = 0;
+   ossim_uint32 idx2 = 0;
+   NEWMAT::RowVector row(coefficients.Nrows());
+   
+    for(idx = 0; idx < (ossim_uint32)f.Nrows(); ++idx)
+    {
+       row[0]  = 1;
+       row[1]  = x[idx];
+       row[2]  = y[idx];
+       row[3]  = z[idx];
+       row[4]  = x[idx]*y[idx];
+       row[5]  = x[idx]*z[idx];
+       row[6]  = y[idx]*z[idx];
+       row[7]  = x[idx]*x[idx];
+       row[8]  = y[idx]*y[idx];
+       row[9]  = z[idx]*z[idx];
+       row[10] = x[idx]*y[idx]*z[idx];
+       row[11] = x[idx]*x[idx]*x[idx];
+       row[12] = x[idx]*y[idx]*y[idx];
+       row[13] = x[idx]*z[idx]*z[idx];
+       row[14] = x[idx]*x[idx]*y[idx];
+       row[15] = y[idx]*y[idx]*y[idx];
+       row[16] = y[idx]*z[idx]*z[idx];
+       row[17] = z[idx]*x[idx]*z[idx];
+       row[18] = y[idx]*y[idx]*z[idx];
+       row[19] = z[idx]*z[idx]*z[idx];
+
+      result[idx] = 0.0;
+      for(idx2 = 0; idx2 < (ossim_uint32)row.Ncols(); ++idx2)
+      {
+         result[idx] += row[idx2]*coefficients[idx2];
+      }
+
+      if(result[idx] > FLT_EPSILON)
+      {
+         result[idx] = 1.0/result[idx];
+      }
+    }
+}
+
+double ossimRpcSolver::eval(const std::vector<double>& coeff,
+                            double x,
+                            double y,
+                            double z)const
+{
+   return coeff[ 0]       + coeff[ 1]*x     + coeff[ 2]*y     + coeff[ 3]*z     +
+          coeff[ 4]*x*y   + coeff[ 5]*x*z   + coeff[ 6]*y*z   + coeff[ 7]*x*x   +
+          coeff[ 8]*y*y   + coeff[ 9]*z*z   + coeff[10]*x*y*z + coeff[11]*x*x*x +
+          coeff[12]*x*y*y + coeff[13]*x*z*z + coeff[14]*x*x*y + coeff[15]*y*y*y +
+          coeff[16]*y*z*z + coeff[17]*x*x*z + coeff[18]*y*y*z + coeff[19]*z*z*z;
+}
+
+
+ossimRefPtr<ossimNitfRegisteredTag> ossimRpcSolver::getNitfRpcBTag() const
+{
+   ossimNitfRpcBTag* rpcbTag = new ossimNitfRpcBTag();
+
+   // success always true
+   rpcbTag->setSuccess(true);
+
+   // temp "0"...
+   rpcbTag->setErrorBias(0.0);
+
+   // temp "0"...
+   rpcbTag->setErrorRand(0.0);
+
+   // line offset
+   rpcbTag->setLineOffset(static_cast<ossim_uint32>(getImageYOffset()));
+
+   // sample offset
+   rpcbTag->setSampleOffset(static_cast<ossim_uint32>(getImageXOffset()));
+
+   // latitude offset
+   rpcbTag->setGeodeticLatOffset(getLatOffset());
+
+   // longitude offset
+   rpcbTag->setGeodeticLonOffset(getLonOffset());
+
+   // height offset
+   rpcbTag->setGeodeticHeightOffset(
+      static_cast<ossim_int32>(getHeightOffset()));
+
+   // line scale
+   rpcbTag->setLineScale(static_cast<ossim_uint32>(getImageYScale()));
+
+   // sample scale
+   rpcbTag->setSampleScale(static_cast<ossim_uint32>(getImageXScale()));
+
+   // latitude scale
+   rpcbTag->setGeodeticLatScale(getLatScale());
+
+   // longitude scale
+   rpcbTag->setGeodeticLonScale(getLonScale());
+
+   // height scale
+   rpcbTag->setGeodeticHeightScale(static_cast<ossim_int32>(getHeightScale()));
+
+   // line numerator coefficients
+   rpcbTag->setLineNumeratorCoeff(getImageYNumCoefficients());
+   
+   // line denominator coefficients
+   rpcbTag->setLineDenominatorCoeff(getImageYDenCoefficients());
+
+   // sample numerator coefficients
+   rpcbTag->setSampleNumeratorCoeff(getImageXNumCoefficients());
+
+   // sample denominator coefficients
+   rpcbTag->setSampleDenominatorCoeff(getImageXDenCoefficients());
+
+   // Return it as an ossimRefPtr<ossimNitfRegisteredTag>...
+   ossimRefPtr<ossimNitfRegisteredTag> tag = rpcbTag;
+   
+   return tag;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimRpcSolver.h b/Utilities/OSSIM/ossim_core/projections/ossimRpcSolver.h
new file mode 100644
index 0000000000..2a8235320a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimRpcSolver.h
@@ -0,0 +1,233 @@
+//*****************************************************************************
+// FILE: ossimRpcModel.h
+//
+// Copyright (C) 2004 Intelligence Data Systems, Inc.
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+//
+// AUTHOR: Garrett Potts
+//
+//*****************************************************************************
+//  $Id: ossimRpcSolver.h,v 1.11 2005/10/06 16:02:45 gpotts Exp $
+#ifndef ossimRpcSolver_HEADER
+#define ossimRpcSolver_HEADER
+
+#include <vector>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDrect.h>
+#include <matrix/newmat.h>
+#include <projections/sensor_modeling/rpc/ossimRpcModel.h>
+#include <projections/ossimRpcProjection.h>
+
+class ossimProjection;
+class ossimNitfRegisteredTag;
+
+
+/**
+ * This currently only support Rational poilynomial B format.  This can be found in
+ * the NITF registered commercial tag document.
+ * 
+ * <pre>
+ * Format is:
+ *          coeff[ 0]       + coeff[ 1]*x     + coeff[ 2]*y     + coeff[ 3]*z     +
+ *          coeff[ 4]*x*y   + coeff[ 5]*x*z   + coeff[ 6]*y*z   + coeff[ 7]*x*x   +
+ *          coeff[ 8]*y*y   + coeff[ 9]*z*z   + coeff[10]*x*y*z + coeff[11]*x*x*x +
+ *          coeff[12]*x*y*y + coeff[13]*x*z*z + coeff[14]*x*x*y + coeff[15]*y*y*y +
+ *          coeff[16]*y*z*z + coeff[17]*x*x*z + coeff[18]*y*y*z + coeff[19]*z*z*z;
+ *
+ *       where coeff is one of XNum, XDen, YNum, and YDen.  So there are 80
+ *       coefficients all together.
+ *
+ *       
+ * Currently we use a linear least squares fit to solve the coefficients.  This is the simplest
+ * to implement.  We probably relly need a nonlinear minimizer to fit the coefficients but I don't have
+ * time to experiment.  Levenberg Marquardt might be a solution to look into.
+ *
+ *
+ * 
+ * HOW TO USE:
+ * 
+ *        ossimRpcSolver solver;
+ *        solver.solveCoefficients(rect,
+ *                                 *proj.get());
+ *                                 
+ * We can also call solve coefficients with a list of ground control points.
+ * First is the list of image points followed by the ground points.
+ * NOTE: Thes must be equal in size.
+ * 
+ *        solver.solveCoefficients(imagePoints,
+ *                                 groundPoints);
+ *                                 
+ *                                 
+ * Once you call solveCoefficients you can create the projector:
+ *                                 
+ *        ossimRefPtr<ossimRpcProjection> rpc = solver.createRpcProjection();
+ *
+ * </pre>
+ * 
+ */ 
+class OSSIM_DLL ossimRpcSolver
+{
+public:
+   /**
+    * The use elvation flag will deterimne if we force the height t be 0.  If the elevation
+    * is enabled then we use the height field of the control points to determine the
+    * coefficients of the RPC00 polynomial.  If its false then we will ignore the height
+    * by setting the height field to 0.0.
+    *
+    * Note:  even if the elevation is enabled all NAN heights are set to 0.0.
+    */
+   ossimRpcSolver(bool useElevation=false,
+                  bool heightAboveMSLFlag=true);
+
+	virtual ~ossimRpcSolver(){}
+   /**
+    * This will convert any projector to an RPC model
+    */
+   void solveCoefficients(const ossimDrect& imageBouunds,
+                          const ossimProjection& imageProj,
+                          ossim_uint32 xSamples=8,
+                          ossim_uint32 ySamples=8,
+                          bool shiftTo0Flag=true);
+
+   /**
+    * takes associated image points and ground points
+    * and solves the coefficents for the rational polynomial for
+    * line and sample calculations from world points.
+    *
+    * Note: All data will be normalized between -1 and 1 for
+    *       numerical robustness.
+    */ 
+   void solveCoefficients(const std::vector<ossimDpt>& imagePoints,
+                          const std::vector<ossimGpt>& groundControlPoints,
+                          const ossimDpt& imageShift = ossimDpt(0.0,0.0));
+
+   /**
+    * Creates and Rpc model from the coefficients
+    */
+   ossimRefPtr<ossimRpcModel> createRpcModel()const;
+
+   /**
+    * Create a simple rpc projection which is a dumbed down
+    * rpc model.
+    */
+   ossimRefPtr<ossimRpcProjection> createRpcProjection()const;
+
+
+   /**
+    * Gives access to the solved coefficients.  For the image
+    * X numerator
+    */
+   const std::vector<double>& getImageXNumCoefficients()const;
+
+   /**
+    * Gives access to the solved coefficients.  For the image
+    * X denominator
+    */
+   const std::vector<double>& getImageXDenCoefficients()const;
+
+   /**
+    * Gives access to the solved coefficients.  For the image
+    * Y numerator
+    */
+   const std::vector<double>& getImageYNumCoefficients()const;
+
+   /**
+    * Gives access to the solved coefficients. For the image
+    * Y denominator
+    */
+   const std::vector<double>& getImageYDenCoefficients()const;
+
+   
+   double getImageXOffset()const;
+   double getImageYOffset()const;
+   double getLatOffset()const;
+   double getLonOffset()const;
+   double getHeightOffset()const;
+   double getImageXScale()const;
+   double getImageYScale()const;
+   double getLatScale()const;
+   double getLonScale()const;
+   double getHeightScale()const;
+
+   double getRmsError()const;
+
+   /**
+    * @return ossimRefPtr<ossimNitfRegisteredTag>
+    *
+    * @note one of the solve methods should have been called prior to this.
+    */
+   ossimRefPtr<ossimNitfRegisteredTag> getNitfRpcBTag() const;
+   
+protected:
+   virtual void solveInitialCoefficients(NEWMAT::ColumnVector& coeff,
+                                         const std::vector<double>& f,
+                                         const std::vector<double>& x,
+                                         const std::vector<double>& y,
+                                         const std::vector<double>& z)const;
+                                         
+   virtual void solveCoefficients(NEWMAT::ColumnVector& coeff,
+                                  const std::vector<double>& f,
+                                  const std::vector<double>& x,
+                                  const std::vector<double>& y,
+                                  const std::vector<double>& z)const;
+   
+   double eval(const std::vector<double>& coeff,
+               double x,
+               double y,
+               double z)const;
+
+   /**
+    * Inverts using the SVD method
+    */
+   NEWMAT::Matrix invert(const NEWMAT::Matrix& m)const;
+   
+   void setupSystemOfEquations(NEWMAT::Matrix& equations,
+                               const NEWMAT::ColumnVector& f,
+                               const std::vector<double>& x,
+                               const std::vector<double>& y,
+                               const std::vector<double>& z)const;
+
+   void setupWeightMatrix(NEWMAT::DiagonalMatrix& result, // holds the resulting weights
+                          const NEWMAT::ColumnVector& coefficients,
+                          const NEWMAT::ColumnVector& f,
+                          const std::vector<double>& x,
+                          const std::vector<double>& y,
+                          const std::vector<double>& z)const;
+
+   bool theUseElevationFlag;
+   bool theHeightAboveMSLFlag;
+   ossimDpt      theImageOffset;
+   ossimGpt      theGroundOffset;
+   ossimDpt      theImageScale;
+   ossim_float64 theLatScale;
+   ossim_float64 theLonScale;
+   ossim_float64 theHeightScale;
+   ossim_float64 theError;
+   /**
+    * there are 20 coefficients in the cubic RPC model
+    */ 
+   std::vector<ossim_float64> theXNumCoeffs;
+
+   /**
+    * there are 20 coefficients in the cubic RPC model
+    */ 
+   std::vector<ossim_float64> theXDenCoeffs;
+
+   /**
+    * there are 20 coefficients in the cubic RPC model
+    */ 
+   std::vector<ossim_float64> theYNumCoeffs;
+
+   /**
+    * there are 20 coefficients in the cubic RPC model
+    */ 
+   std::vector<ossim_float64> theYDenCoeffs;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimStatePlaneProjectionInfo.cpp b/Utilities/OSSIM/ossim_core/projections/ossimStatePlaneProjectionInfo.cpp
new file mode 100644
index 0000000000..acc182a827
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimStatePlaneProjectionInfo.cpp
@@ -0,0 +1,306 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//*******************************************************************
+//  $Id: ossimStatePlaneProjectionInfo.cpp,v 1.9 2004/06/09 15:36:16 dburken Exp $
+#include "ossimStatePlaneProjectionInfo.h"
+#include "map_projections/ossimTransMercatorProjection.h"
+#include "map_projections/ossimLambertConformalConicProjection.h"
+#include "base/common/ossimKeywordNames.h"
+#include "base/factory/ossimDatumFactory.h"
+#include "base/common/ossimConstants.h"
+
+ossimStatePlaneProjectionInfo::ossimStatePlaneProjectionInfo(char*  name,
+                                                             int    pcsCode,
+                                                             char*  projName,
+                                                             char*  param1,
+                                                             char*  param2,
+                                                             char*  param3,
+                                                             char*  param4,
+                                                             double falseEast,
+                                                             double falseNorth,
+                                                             char*  units)
+   :
+      thePcsCode        (pcsCode),
+      theName           (name),
+      theProjectionName (projName),
+      theDatum          (0),
+      theOriginLat      (param1),
+      theOriginLon      (param2),
+      theOrigin         (),
+      theParameter3     (0.0),
+      theParameter4     (0.0),
+      theFalseEasting   (falseEast),
+      theFalseNorthing  (falseNorth),
+      theScaleFactor    (0.0),
+      theUnits          (units)
+      
+{
+   // Set the parameters 
+   theParameter3 = ossimDms(param3).getDegrees();
+   theParameter4 = ossimDms(param4).getDegrees();
+
+   if(theName.contains("NAD27"))
+   {
+      theDatum = ossimDatumFactory::instance()->create("NAS-C"); // NAD 1927
+   }
+   else
+   {
+      theDatum = ossimDatumFactory::instance()->create("NAR-C");  // NAD 1983
+   }
+
+   theOrigin = ossimGpt(theOriginLat.getDegrees(),
+                        theOriginLon.getDegrees(),
+                        0,
+                        theDatum);   
+}
+
+ossimStatePlaneProjectionInfo::ossimStatePlaneProjectionInfo(char*  name,
+                                                             int    pcsCode,
+                                                             char*  projName,
+                                                             char*  param1,
+                                                             char*  param2,
+                                                             double param3,
+                                                             double param4,
+                                                             double falseEast,
+                                                             double falseNorth,
+                                                             char*  units)
+   :
+      thePcsCode        (pcsCode),
+      theName           (name),
+      theProjectionName (projName),
+      theDatum          (0),
+      theOriginLat      (param1),
+      theOriginLon      (param2),
+      theOrigin         (),
+      theParameter3     (param3),
+      theParameter4     (param4),
+      theFalseEasting   (falseEast),
+      theFalseNorthing  (falseNorth),
+      theScaleFactor    (0.0),
+      theUnits          (units)
+{
+   if(theName.contains("NAD27"))
+   {
+      theDatum = ossimDatumFactory::instance()->create("NAS-C"); // NAD 1927
+   }
+   else
+   {
+      theDatum = ossimDatumFactory::instance()->create("NAR-C");  // NAD 1983
+   }
+
+   theOrigin = ossimGpt(theOriginLat.getDegrees(),
+                        theOriginLon.getDegrees(),
+                        0,
+                        theDatum);   
+   if(fabs(theParameter3) > FLT_EPSILON)
+   {
+      theScaleFactor = 1.0 - (1.0 / theParameter3);
+   }
+   else
+   {
+      theScaleFactor = 1.0;
+   }
+   
+}
+
+int ossimStatePlaneProjectionInfo::code() const
+{
+   return thePcsCode;
+}
+
+const ossimString& ossimStatePlaneProjectionInfo::name() const
+{
+   return theName;
+}
+
+const ossimString& ossimStatePlaneProjectionInfo::projName() const
+{
+   return theProjectionName;
+}
+
+double ossimStatePlaneProjectionInfo::originLat() const
+{
+   return theOriginLat.getDegrees();
+}
+
+double ossimStatePlaneProjectionInfo::originLon() const
+{
+   return theOriginLon.getDegrees();
+}
+
+const ossimDatum* ossimStatePlaneProjectionInfo::datum() const
+{
+   return theDatum;
+}
+
+ossimGpt ossimStatePlaneProjectionInfo::origin() const
+{
+   return theOrigin;
+}
+
+double ossimStatePlaneProjectionInfo::parallel1() const
+{
+   return theParameter3;
+}
+
+double ossimStatePlaneProjectionInfo::parallel2() const
+{
+   return theParameter4;
+}
+
+double ossimStatePlaneProjectionInfo::falseEasting() const
+{
+   return theFalseEasting;
+}
+
+double ossimStatePlaneProjectionInfo::falseNorthing() const
+{
+   return theFalseNorthing;
+}
+
+double ossimStatePlaneProjectionInfo::scaleFactor() const
+{
+   return theScaleFactor;
+}
+
+const ossimString&  ossimStatePlaneProjectionInfo::units() const
+{
+   return theUnits;
+}
+
+bool ossimStatePlaneProjectionInfo::isSameCode(int pcsCode) const
+{
+   if(pcsCode == thePcsCode)
+   {
+      return true;
+   }
+
+   return false;
+}
+
+double ossimStatePlaneProjectionInfo::falseEastingInMeters() const
+{
+   if (units()=="m")
+   {
+      return theFalseEasting;
+   }
+   return theFalseEasting * US_METERS_PER_FT;
+}
+
+double ossimStatePlaneProjectionInfo::falseNorthingInMeters() const
+{
+   if (units()=="m")
+   {
+      return theFalseNorthing;
+   }
+
+   return theFalseNorthing * US_METERS_PER_FT;
+}
+
+void ossimStatePlaneProjectionInfo::populateProjectionKeywords(ossimKeywordlist& kwl,
+                                                               const char* prefix)const
+{
+  kwl.add(prefix,
+	  ossimKeywordNames::PCS_CODE_KW,
+	  thePcsCode,
+	  true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_EASTING_KW,
+           falseEastingInMeters(),
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::FALSE_NORTHING_KW,
+           falseNorthingInMeters(),
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::ORIGIN_LATITUDE_KW,
+           origin().latd(),
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+           origin().lond(),
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           projName(),
+           true);
+   if(theDatum)
+   {
+      
+      kwl.add(prefix,
+              ossimKeywordNames::DATUM_KW,
+              theDatum->code(),
+              true);
+   }
+
+   if (projName()== STATIC_TYPE_NAME(ossimLambertConformalConicProjection))
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TYPE_KW,
+              STATIC_TYPE_NAME(ossimLambertConformalConicProjection),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::STD_PARALLEL_1_KW,
+              parallel1(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::STD_PARALLEL_2_KW,
+              parallel2(),
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::SCALE_FACTOR_KW,
+              theScaleFactor,
+              true);
+   }
+}
+
+ostream& operator<<(ostream& os, const ossimStatePlaneProjectionInfo& thePlane)
+{
+   if (thePlane.projName()== STATIC_TYPE_NAME(ossimTransMercatorProjection))
+   {
+      return  os << "ossimStatePlaneProjection: "
+                 << "\nName:    " << thePlane.name()
+                 << "\nPcsCode: " << thePlane.code()
+                 << "\norigin:  " << thePlane.origin()
+                 << "\nscale factor:  " << setprecision(12)
+                 << thePlane.scaleFactor()
+                 << "\nfalseEasting:   " << thePlane.falseEasting()
+                 << "\nfalseNorthing:  " << thePlane.falseNorthing()
+                 << endl;
+   }
+   else  // Lambert
+   {
+      return  os << "ossimStatePlaneProjection: "
+                 << "\nName:    " << thePlane.name()
+                 << "\nPcsCode: " << thePlane.code()
+                 << "\norigin:  " << thePlane.origin()
+                 << "\nphi1:    "
+                 << setprecision(12) << thePlane.parallel1()
+                 << "\nphi2:    "
+                 << setprecision(12) << thePlane.parallel2()
+                 << "\nfalseEasting:   " << thePlane.falseEasting()
+                 << "\nfalseNorthing:  " << thePlane.falseNorthing()
+                 << endl;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimStatePlaneProjectionInfo.h b/Utilities/OSSIM/ossim_core/projections/ossimStatePlaneProjectionInfo.h
new file mode 100644
index 0000000000..a99f06fa54
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimStatePlaneProjectionInfo.h
@@ -0,0 +1,108 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//*******************************************************************
+//  $Id: ossimStatePlaneProjectionInfo.h,v 1.5 2004/06/09 15:35:33 dburken Exp $
+#ifndef ossimStatePlaneProjectionInfo_HEADER
+#define ossimStatePlaneProjectionInfo_HEADER
+
+#include "base/data_types/ossimDms.h"
+#include "base/data_types/ossimGpt.h"
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+class  ossimDatum;
+
+class OSSIMDLLEXPORT ossimStatePlaneProjectionInfo
+{
+
+   friend ostream& operator<<(ostream&, const ossimStatePlaneProjectionInfo&);
+
+public:
+
+   ossimStatePlaneProjectionInfo(char*  name,
+                                 int    pcsCode,
+                                 char*  projCode,
+                                 char*  param1,
+                                 char*  param2,
+                                 char*  param3,
+                                 char*  param4,
+                                 double falseEast,
+                                 double falseNorth,
+                                 char*   units);
+  
+   ossimStatePlaneProjectionInfo(char*  name,
+                                 int    pcsCode,
+                                 char*  projCode,
+                                 char*  param1,
+                                 char*  param2,
+                                 double param3,
+                                 double param4,
+                                 double falseEast,
+                                 double falseNorth,
+                                 char*  units);
+   
+   int                code()                  const;
+   const ossimString& name()                  const;
+   const ossimString& projName()              const;
+   double             originLat()             const;
+   double             originLon()             const;
+   const ossimDatum*  datum()                 const;
+   ossimGpt           origin()                const;
+   double             parallel1()             const;
+   double             parallel2()             const;
+   double             falseEasting()          const;
+   double             falseNorthing()         const;
+   double             falseEastingInMeters()  const;
+   double             falseNorthingInMeters() const;
+   double             scaleFactor()           const;
+   const ossimString& units()                 const;
+   bool               isSameCode( int Code )  const;
+
+   void populateProjectionKeywords(ossimKeywordlist& kwl,
+                                   const char* prefix=NULL)const;
+private:
+   
+   int                  thePcsCode;       // The Geotiff code 
+   ossimString          theName;          // Descriptive PCS name
+   
+   /*!
+    * ossimLambertConformalConicProjection or
+    * ossimTransMercatorProjection
+    */
+   ossimString          theProjectionName;
+   
+   const ossimDatum*    theDatum; // Either NAD83 or NAD27  based on name
+   
+   ossimDms             theOriginLat;
+   ossimDms             theOriginLon;
+   ossimGpt             theOrigin;
+   
+   double               theParameter3;      // parallel 1   or   Scale factor
+   double               theParameter4;      // parallel 2   or      0
+   
+   double               theFalseEasting;
+   double               theFalseNorthing;
+   
+   double               theScaleFactor;
+   
+   ossimString          theUnits;        // "ft" or "m"
+};
+
+#endif /* #ifndef ossimStatePlaneProjectionInfo_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimWarpProjection.cpp b/Utilities/OSSIM/ossim_core/projections/ossimWarpProjection.cpp
new file mode 100644
index 0000000000..fb965b2cf3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimWarpProjection.cpp
@@ -0,0 +1,343 @@
+//*****************************************************************************
+// FILE: ossimWarpProjection.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimWarpModel. This is an
+//   implementation of a warping interpolation model.
+//
+//*****************************************************************************
+//  $Id: ossimWarpProjection.cpp,v 1.11 2005/09/09 19:23:58 gpotts Exp $
+
+#include <projections/ossimWarpProjection.h>
+RTTI_DEF1(ossimWarpProjection, "ossimWarpProjection", ossimProjection);
+
+#include <base/misc/ossimQuadTreeWarp.h>
+#include <base/misc/ossimAffineTransform.h>
+#include <projections/factory/ossimProjectionFactoryRegistry.h>
+#include <base/context/ossimNotifyContext.h>
+
+static const char* AFFINE_PREFIX     = "affine.";
+static const char* QUADWARP_PREFIX   = "quadwarp.";
+static const char* PROJECTION_PREFIX = "projection.";
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimWarpProjection:exec");
+static ossimTrace traceDebug ("ossimWarpProjection:debug");
+
+//*****************************************************************************
+//  CONSTRUCTOR: Default
+//  
+//*****************************************************************************
+ossimWarpProjection::ossimWarpProjection()
+   :
+      ossimProjection(),
+      theClientProjection (NULL),
+      theWarpTransform (NULL),
+      theAffineTransform (NULL)
+{
+   theWarpTransform   = new ossimQuadTreeWarp;
+   theAffineTransform = new ossimAffineTransform;   
+}
+
+
+//*****************************************************************************
+//  CONSTRUCTOR: Primary constructor accepting pointer to the underlying
+//               client projection
+//  
+//*****************************************************************************
+ossimWarpProjection::ossimWarpProjection(ossimProjection* client)
+   :
+      ossimProjection(),
+      theClientProjection (client),
+      theWarpTransform (NULL),
+      theAffineTransform (NULL)
+{
+   theWarpTransform   = new ossimQuadTreeWarp;
+   theAffineTransform = new ossimAffineTransform;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: Accepts geom keywordlist
+//*****************************************************************************
+ossimWarpProjection::ossimWarpProjection(const ossimKeywordlist& geom_kwl,
+                                         const char* prefix)
+   :
+      ossimProjection(),
+      theClientProjection (NULL),
+      theWarpTransform (NULL),
+      theAffineTransform (NULL)
+{
+   theClientProjection = ossimProjectionFactoryRegistry::instance()->
+                         createProjection(geom_kwl, prefix);
+
+   theWarpTransform = new ossimQuadTreeWarp();
+   bool rtn_stat = theWarpTransform->loadState(geom_kwl, prefix);
+
+   theAffineTransform = new ossimAffineTransform();
+   rtn_stat &= theAffineTransform->loadState(geom_kwl, prefix);
+
+   if ((!theClientProjection) ||
+       (theClientProjection->getErrorStatus()) ||
+       (!rtn_stat))
+      setErrorStatus(ossimErrorCodes::OSSIM_ERROR);
+}
+   
+//*****************************************************************************
+//  DESTRUCTOR
+//*****************************************************************************
+ossimWarpProjection::~ossimWarpProjection()
+{
+   if(theClientProjection)
+   {
+      delete theClientProjection;
+      theClientProjection = NULL;
+   }
+   if(theWarpTransform)
+   {
+      delete theWarpTransform;
+      theWarpTransform = NULL;
+   }
+   if(theAffineTransform)
+   {
+      delete theAffineTransform;
+      theAffineTransform = NULL;
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimWarpProjection::worldToLineSample()
+//*****************************************************************************
+void ossimWarpProjection::worldToLineSample (const ossimGpt& worldPoint,
+                                        ossimDpt&       lineSampPt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimWarpProjection::worldToLineSample: Entering..." << std::endl;
+
+   if (theClientProjection && theWarpTransform && theAffineTransform)
+   {
+      theClientProjection->worldToLineSample(worldPoint, lineSampPt);
+      theAffineTransform->inverse(lineSampPt);
+      theWarpTransform->inverse(lineSampPt);
+   }
+   else
+   {
+      lineSampPt.makeNan();
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimWarpProjection::worldToLineSample: Returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimWarpProjection::lineSampleToWorld()
+//*****************************************************************************
+void ossimWarpProjection::lineSampleToWorld(const ossimDpt& lineSampPt,
+                                            ossimGpt&       worldPt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimWarpProjection::lineSampleToWorld: Entering..." << std::endl;
+
+   if (theClientProjection && theWarpTransform && theAffineTransform)
+   {
+      ossimDpt adjustedPt;
+      theWarpTransform->forward(adjustedPt);
+      theAffineTransform->forward(lineSampPt, adjustedPt);
+      theClientProjection->lineSampleToWorld(adjustedPt, worldPt);
+   }
+   else
+   {
+      worldPt.makeNan();
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimWarpProjection::lineSampleToWorld: Returning..." << std::endl;
+}
+   
+//*****************************************************************************
+//  METHOD: ossimWarpProjection::lineSampleToWorld()
+//*****************************************************************************
+void ossimWarpProjection::lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                             const double&   hgt,
+                                             ossimGpt&       worldPt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimWarpProjection::lineSampleHeightToWorld: Entering..." << std::endl;
+
+   if (theClientProjection && theWarpTransform && theAffineTransform)
+   {
+      ossimDpt adjustedPt;
+      theAffineTransform->forward(lineSampPt, adjustedPt);
+      theWarpTransform->forward(adjustedPt);
+      theClientProjection->lineSampleHeightToWorld(adjustedPt, hgt, worldPt);
+   }
+   else
+   {
+      worldPt.makeNan();
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimWarpProjection::lineSampleHeightToWorld: Returning..." << std::endl;
+}
+   
+//*****************************************************************************
+//  METHOD: ossimWarpProjection::print()
+//*****************************************************************************
+std::ostream& ossimWarpProjection::print(std::ostream& out) const
+{
+   if (theClientProjection && theWarpTransform && theAffineTransform)
+   {
+      out <<
+         "ossimWarpProjection:\n"
+	  << "  Member theClientProjection: ";
+      theClientProjection->print(out);
+      
+      out << "  Member theAffineTransform: "  << *theAffineTransform <<  "\n"
+	  << "  Member theWarpTransform: "    << *theWarpTransform << endl;
+   }
+   else
+   {
+      out << "ossimWarpProjection -- Not inititialized." << endl;
+   }
+   return out;
+}
+
+std::ostream& operator<<(std::ostream& os, const ossimWarpProjection& m)
+{
+   return m.print(os);
+}
+
+//*****************************************************************************
+//  METHOD: ossimWarpProjection::saveState()
+//*****************************************************************************
+bool ossimWarpProjection::saveState(ossimKeywordlist& kwl,
+                                            const char* prefix) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimWarpProjection::saveState: entering..." << std::endl;
+
+   ossimString projPrefix     = ossimString(prefix) + PROJECTION_PREFIX;
+   ossimString affinePrefix   = ossimString(prefix) + AFFINE_PREFIX;
+   ossimString quadwarpPrefix = ossimString(prefix) + QUADWARP_PREFIX;
+
+   if (theClientProjection && theWarpTransform && theAffineTransform)
+   {
+      theClientProjection->saveState(kwl, projPrefix.c_str());
+      theAffineTransform->saveState(kwl, affinePrefix.c_str());
+      theWarpTransform->saveState(kwl, quadwarpPrefix.c_str());
+   }
+      
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimWarpProjection::saveState: returning..." << std::endl;
+   return ossimProjection::saveState(kwl, prefix);
+}
+
+//*****************************************************************************
+//  METHOD: ossimWarpProjection::loadState()
+//*****************************************************************************
+bool ossimWarpProjection::loadState(const ossimKeywordlist& kwl,
+                                            const char* prefix)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimWarpProjection::loadState: entering..." << std::endl;
+
+//   bool good_load;
+//   int  err_stat;
+   bool result = true;
+   
+   ossimString projPrefix = ossimString(prefix) + PROJECTION_PREFIX;
+   ossimString affinePrefix = ossimString(prefix) + AFFINE_PREFIX;
+   ossimString quadwarpPrefix = ossimString(prefix) + QUADWARP_PREFIX;
+
+   if(theClientProjection) delete theClientProjection;
+   theClientProjection = (ossimProjection*)NULL;
+
+   if (!theWarpTransform)
+      theWarpTransform = new ossimQuadTreeWarp();
+
+   if (!theAffineTransform)
+      theAffineTransform = new ossimAffineTransform();
+
+   theClientProjection = ossimProjectionFactoryRegistry::instance()->createProjection(kwl, projPrefix.c_str());
+
+   if(!theClientProjection)
+     {
+       result = false;
+     }
+   else
+     {
+       theWarpTransform->loadState(kwl,   quadwarpPrefix.c_str());
+       theAffineTransform->loadState(kwl, affinePrefix.c_str());
+     }
+
+   return ossimProjection::loadState(kwl, prefix);
+}
+
+//*****************************************************************************
+//  METHOD: ossimWarpProjection::dup()
+//*****************************************************************************
+ossimObject* ossimWarpProjection::dup() const
+{
+   ossimKeywordlist kwl;
+   saveState(kwl);
+   return new ossimWarpProjection(kwl);
+}
+   
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+ossimGpt ossimWarpProjection::origin() const
+{
+   if (theClientProjection)
+      return theClientProjection->origin();
+   return ossimGpt(0.0, 0.0, 0.0);
+}
+
+//*****************************************************************************
+//  METHOD: 
+//*****************************************************************************
+ossimDpt  ossimWarpProjection::getMetersPerPixel() const
+{
+   if (theClientProjection)
+      return theClientProjection->getMetersPerPixel();
+   return ossimDpt(OSSIM_NAN, OSSIM_NAN);
+}
+      
+
+void ossimWarpProjection::setNewWarpTransform(ossim2dTo2dTransform* warp)
+{
+   if(warp)
+   {
+      if(theWarpTransform)
+      {
+         delete theWarpTransform;
+         theWarpTransform = NULL;
+      }
+      theWarpTransform = warp;
+   }
+}
+
+void ossimWarpProjection::setNewAffineTransform(ossim2dTo2dTransform* affine)
+{
+   if(affine)
+   {
+      if(theAffineTransform)
+      {
+         delete theAffineTransform;
+         theAffineTransform = NULL;
+      }
+      theAffineTransform = affine;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/ossimWarpProjection.h b/Utilities/OSSIM/ossim_core/projections/ossimWarpProjection.h
new file mode 100644
index 0000000000..703ffd64c9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/ossimWarpProjection.h
@@ -0,0 +1,146 @@
+//*****************************************************************************
+// FILE: ossimWarpProjection.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimWarpProjection. This is an
+//   implementation of a warping interpolation model.
+//
+//*****************************************************************************
+//  $Id: ossimWarpProjection.h,v 1.6 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimWarpProjection_HEADER
+#define ossimWarpProjection_HEADER
+
+#include "projections/ossimProjection.h"
+#include "base/data_types/ossimIpt.h"
+
+class ossim2dTo2dTransform;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimWarpProjection
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimWarpProjection : public ossimProjection
+{
+public:
+   /*!
+    * Default Contructor:
+    */
+   ossimWarpProjection();
+
+   /*!
+    * Primary constructor accepting pointer to the underlying client projection.
+    */
+   ossimWarpProjection(ossimProjection* client);
+
+   /*!
+    * Constructor accepts OSSIM keywordlist geometry file.
+    */
+   ossimWarpProjection(const ossimKeywordlist& geom_kwl,
+                       const char* prefix=NULL);
+   
+   ~ossimWarpProjection();
+   
+   /*!
+    * METHOD: worldToLineSample()
+    * Performs the forward projection from ground point to line, sample.
+    */
+   virtual void worldToLineSample(const ossimGpt& worldPoint,
+                                  ossimDpt&       lineSampPt) const;
+
+   /*!
+    * METHOD: lineSampleToWorld()
+    * Performs the inverse projection from line, sample to ground (world):
+    */
+   virtual void lineSampleToWorld(const ossimDpt& lineSampPt,
+                                      ossimGpt&       worldPt) const;
+   
+   /*!
+    * Performs the inverse projection from line, sample to ground, bypassing
+    * reference to elevation surface:
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                        const double&   hgtEllipsoid,
+                                        ossimGpt&       worldPt) const;
+   
+   /*!
+    * Extends base-class implementation. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+   friend std::ostream& operator<<(std::ostream& os,
+                                   const ossimWarpProjection& m);
+   
+   /*!
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files. Returns true if successful.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0) const;
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+
+   /*!
+    * Returns pointer to a new instance, copy of this.
+    */
+   virtual ossimObject* dup() const;
+   
+   /*!
+    * Returns projection's ground point origin. That is the GP corresponding
+    * to line=0, sample=0.
+    */
+   virtual ossimGpt origin() const;
+
+   /*!
+    * Compares this instance with arg projection. NOT IMPLEMENTED.
+    */
+   virtual bool operator==(const ossimProjection& projection) const
+      { return false; }
+
+   virtual ossimDpt getMetersPerPixel() const;
+
+   virtual ossim2dTo2dTransform* getWarpTransform()
+      {
+         return theWarpTransform;
+      }
+   virtual ossim2dTo2dTransform* getAffineTransform()
+      {
+         return theAffineTransform;
+      }
+   virtual ossimProjection* getClientProjection()
+      {
+         return theClientProjection;
+      }
+   virtual void setNewWarpTransform(ossim2dTo2dTransform* warp);
+   virtual void setNewAffineTransform(ossim2dTo2dTransform* affine);
+   
+protected:
+   
+   /*!
+    * Data Members:
+    */
+   ossimProjection*      theClientProjection;
+   ossim2dTo2dTransform* theWarpTransform;
+   ossim2dTo2dTransform* theAffineTransform;
+   
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/.cvsignore b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/.cvsignore
new file mode 100644
index 0000000000..2dc074247b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/.cvsignore
@@ -0,0 +1,2 @@
+*.d
+Makefile
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/.cvsignore b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.cpp
new file mode 100644
index 0000000000..3e5569a5f3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.cpp
@@ -0,0 +1,1348 @@
+//*****************************************************************************
+// FILE: ossimCoarseGridModel.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  See LICENSE.txt file in the top level directory.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimCoarseGridModel. This is an
+//   implementation of an interpolation sensor model. 
+//
+//   IMPORTANT: The lat/lon grid is for ground points on the ellipsoid.
+//   The dLat/dHgt and dLon/dHgt partials therefore are used against
+//   elevations relative to the ellipsoid.
+//
+//*****************************************************************************
+//  $Id: ossimCoarseGridModel.cpp,v 1.55 2005/11/29 18:35:46 dburken Exp $
+
+#include <projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.h>
+
+RTTI_DEF1(ossimCoarseGridModel, "ossimCoarseGridModel", ossimSensorModel);
+
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/context/ossimNotifyContext.h>
+#include <elevation/ossimElevManager.h>
+
+#include <cstdio>
+#include <fstream>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceExec  ("ossimCoarseGridModel:exec");
+static ossimTrace traceDebug ("ossimCoarseGridModel:debug");
+
+static const char* MODEL_TYPE = "ossimCoarseGridModel";
+static const char* GRID_FILE_NAME_KW = "grid_file_name";
+static const ossimFilename DEFAULT_GEOM_FILE_EXT ("_ocg.geom");
+static const ossimFilename DEFAULT_GRID_FILE_EXT ("_ocg.dat");
+static const ossimFilename DEFAULT_MET_GRID_NAME ("ecg.grid");
+static const ossimString   MET_ECG_MAGIC_NUMBER  ("eCG");
+
+double ossimCoarseGridModel::theInterpolationError = .1;
+ossim_int32 ossimCoarseGridModel::theMinGridSpacing     = 100;
+
+//*****************************************************************************
+//  DEFAULT CONSTRUCTOR: ossimCoarseGridModel()
+//  
+//*****************************************************************************
+ossimCoarseGridModel::ossimCoarseGridModel()
+   :
+      ossimSensorModel(),
+      theDlatDparamGrid (0),
+      theDlonDparamGrid (0),
+      theHeightEnabledFlag(true)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel: entering..."
+      << std::endl;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel: returning..."
+      << std::endl;
+}
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: ossimCoarseGridModel(ossimCoarseGridModel)
+//  
+//*****************************************************************************
+ossimCoarseGridModel::ossimCoarseGridModel(const ossimCoarseGridModel& model)
+   :
+      ossimSensorModel  (model),
+      theGridFilename   (model.theGridFilename),
+      theLatGrid        (model.theLatGrid),
+      theLonGrid        (model.theLonGrid),
+      theDlatDhGrid     (model.theDlatDhGrid),
+      theDlonDhGrid     (model.theDlonDhGrid),
+      theHeightEnabledFlag(true)
+{
+   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel(model): entering..."
+      << std::endl;
+
+   int numberOfParams = getNumberOfAdjustableParameters();
+   if(numberOfParams)
+   {
+      //***
+      // Allocate adjustable parameter partials grids then assign:
+      //***
+      theDlatDparamGrid = new ossimDblGrid [numberOfParams];
+      theDlonDparamGrid = new ossimDblGrid [numberOfParams];
+      
+      for (int i=0; i<numberOfParams; i++)
+      {
+         theDlatDparamGrid[i] = model.theDlatDparamGrid[i];
+         theDlonDparamGrid[i] = model.theDlonDparamGrid[i];
+      }
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel: returning..."
+      << std::endl;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimCoarseGridModel(filename)
+//  
+//  Constructs model from geometry file
+//  
+//*****************************************************************************
+ossimCoarseGridModel::ossimCoarseGridModel(const ossimFilename& geom_file)
+   :
+      ossimSensorModel(),
+      theDlatDparamGrid (0),
+      theDlonDparamGrid (0),
+      theHeightEnabledFlag(true)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel(geom_file): entering..." << std::endl;
+
+   loadGeomFile(geom_file);
+
+   if (traceExec())   ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel(geom_file): returning..." << std::endl;
+   return;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimCoarseGridModel(kwl)
+//  
+//  Constructs model from keywordlist geometry file
+//  
+//*****************************************************************************
+ossimCoarseGridModel::ossimCoarseGridModel(const ossimKeywordlist& geom_kwl)
+   :
+      ossimSensorModel(),
+      theDlatDparamGrid (0),
+      theDlonDparamGrid (0),
+      theHeightEnabledFlag(true)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel(geom_kwl): entering..." << std::endl;
+
+   //***
+   // Parse keywordlist for geometry:
+   //***
+   loadState(geom_kwl);
+}
+
+//*************************************************************************************************
+//! Assigns the grid data given a projection (typically a rigorous sensor model)
+//*************************************************************************************************
+void ossimCoarseGridModel::buildGrid(const ossimDrect& imageBounds,
+                                     ossimProjection* proj,
+                                     double heightDelta,
+                                     bool enableHeightFlag,
+                                     bool makeAdjustableFlag)
+{
+   theHeightEnabledFlag =  enableHeightFlag;
+   
+   if(proj&&(!imageBounds.hasNans()))
+   {
+     // don't let it get any smaller than 100, 100 pixels
+     // on the input projector
+     //
+     // may want this to be adjusted by outside
+     //
+     const ossimDatum* targetDatum = ossimDatumFactory::instance()->wgs84();
+     ossimIpt gridSize(2,2);
+     ossimDpt gridOrigin(0,0);
+     ossimGpt gpt;
+     ossimGpt gpt2;
+     ossimGpt bilinearGpt;
+     resizeAdjustableParameterArray(0);
+     double normSplit = 1.0;
+     ossimDpt imageSize(imageBounds.width(),
+                        imageBounds.height());
+     double error = 0.0;
+
+     // int y=0;
+     // int x=0;
+     // double ht=0, vt=0;
+     // double w = imageBounds.width();
+     // double h = imageBounds.height();
+     ossimIpt imageOrigin = imageBounds.ul();
+     // ossimDpt metersPerPixel = proj->getMetersPerPixel();
+     ossimDpt spacing ((double)(imageBounds.width()-1)/(gridSize.x-1),
+                       (double)(imageBounds.height()-1)/(gridSize.y-1));
+
+     if(theDlatDparamGrid)
+     {
+        delete [] theDlatDparamGrid;
+        theDlatDparamGrid = NULL;
+     }
+     if(theDlonDparamGrid)
+     {
+        delete [] theDlonDparamGrid;
+        theDlonDparamGrid = NULL;
+     }
+     
+     proj->lineSampleToWorld(imageBounds.midPoint(), gpt);
+
+     do
+     {
+        if(traceDebug())
+        {
+           ossimNotify(ossimNotifyLevel_DEBUG) << "Checking grid size " << gridSize << std::endl;
+        }
+        
+        spacing = ossimDpt((double)(imageBounds.width()-1)/(gridSize.x-1),
+                           (double)(imageBounds.height()-1)/(gridSize.y-1));
+
+        theLatGrid.setNullValue(OSSIM_DBL_NAN);
+        theLonGrid.setNullValue(OSSIM_DBL_NAN);
+        theDlatDhGrid.setNullValue(0.0);
+        theDlonDhGrid.setNullValue(0.0);
+        theLatGrid.initialize(gridSize, gridOrigin, spacing);
+        theLonGrid.initialize(gridSize, gridOrigin, spacing);
+        theDlatDhGrid.initialize(gridSize, gridOrigin, spacing);
+        theDlonDhGrid.initialize(gridSize, gridOrigin, spacing);
+        ossim_int32 x, y;
+        
+        for(y = 0; y < gridSize.y; ++y)
+        {
+           for(x = 0; x < gridSize.x; ++x)
+           {
+              ossimDpt norm((double)x/(double)(gridSize.x-1),
+                            (double)y/(double)(gridSize.y-1));
+              
+              ossimDpt pt(imageOrigin.x + norm.x*(imageSize.x-1),
+                          imageOrigin.y + norm.y*(imageSize.y-1));
+              
+              proj->lineSampleToWorld(pt, gpt);
+              double h = gpt.height();
+              if(h == OSSIM_DBL_NAN)
+              {
+                 h += heightDelta;
+              }
+              proj->lineSampleHeightToWorld(pt, h, gpt2);
+              gpt.changeDatum(targetDatum);
+              gpt2.changeDatum(targetDatum);
+              
+              theLatGrid.setNode(x, y, gpt.latd());
+              theLonGrid.setNode(x, y, gpt.lond());
+
+              theDlatDhGrid.setNode(x, y, (gpt2.latd() - gpt.latd())/heightDelta);
+              theDlonDhGrid.setNode(x, y, (gpt2.lond() - gpt.lond())/heightDelta);
+           }
+        }
+        ossim_int32 upperY = 2*gridSize.y;
+        ossim_int32 upperX = 2*gridSize.x;
+        error = 0.0;
+
+        ossimDpt v[4];
+        v[0].lat = theLatGrid.getNode(0,0);
+        v[0].lon = theLonGrid.getNode(0,0);
+        v[1].lat = theLatGrid.getNode(gridSize.x-1, 0);
+        v[1].lon = theLonGrid.getNode(gridSize.x-1, 0);
+        v[2].lat = theLatGrid.getNode(gridSize.x-1, gridSize.y-1);
+        v[2].lon = theLonGrid.getNode(gridSize.x-1, gridSize.y-1);
+        v[3].lat = theLatGrid.getNode(0, gridSize.y-1);
+        v[3].lon = theLonGrid.getNode(0, gridSize.y-1);
+        theBoundGndPolygon = ossimPolygon(4, v);
+        
+        
+        theImageSize  = ossimDpt(imageBounds.width(), imageBounds.height());
+        theRefImgPt   = imageBounds.midPoint();
+        theRefGndPt   = ossimGpt(theLatGrid(theRefImgPt),
+                                 theLonGrid(theRefImgPt));
+        ossimDpt ref_ip_dx(theRefImgPt.x+1.0, theRefImgPt.y);
+        ossimDpt ref_ip_dy(theRefImgPt.x, theRefImgPt.y+1.0);
+        ossimGpt ref_gp_dx(theLatGrid(ref_ip_dx), theLonGrid(ref_ip_dx));
+        ossimGpt ref_gp_dy(theLatGrid(ref_ip_dy), theLonGrid(ref_ip_dy));
+
+        theGSD.x   = theRefGndPt.distanceTo(ref_gp_dx);
+        theGSD.y   = theRefGndPt.distanceTo(ref_gp_dy);
+
+        theMeanGSD = (theGSD.line + theGSD.samp)/2.0;
+        theImageClipRect  = imageBounds;
+        theSubImageOffset = ossimIpt(0,0);
+
+        for(y = 0; ((y < upperY)&&(error < theInterpolationError)); ++y)
+        {
+           for(x = 0; ((x < upperX)&&(error<theInterpolationError)); ++x)
+           {
+              ossimDpt norm((double)x/(double)(upperX-1),
+                            (double)y/(double)(upperY-1));
+              
+              ossimDpt imagePoint(imageOrigin.x + norm.x*(imageSize.x-1),
+                                  imageOrigin.y + norm.y*(imageSize.y-1));
+              ossimDpt testIpt;
+
+               proj->lineSampleToWorld(imagePoint, gpt);
+               worldToLineSample(gpt, testIpt);
+//               lineSampleToWorld(imagePoint, bilinearGpt);
+//               gpt.changeDatum(targetDatum);
+//               double dist = gpt.distanceTo(bilinearGpt);
+
+//               error = ossimMax(ossimMax(dist/theMeanGSD, dist/theMeanGSD), error);
+               error = (testIpt-imagePoint).length();
+           }
+        }
+
+        gridSize.x *= 2;
+        gridSize.y *= 2;
+        normSplit *= .5;
+     }while((error > theInterpolationError)&&
+            ((imageSize.x*normSplit) > theMinGridSpacing)&&
+            ((imageSize.y*normSplit) > theMinGridSpacing));
+
+
+     gridSize = theLatGrid.size();
+
+     ossimAdjustableParameterInterface* adjustableParameters = PTR_CAST(ossimAdjustableParameterInterface,
+                                                                        proj);
+     removeAllAdjustments();
+     if(adjustableParameters&&makeAdjustableFlag)
+     {
+        if(adjustableParameters->getNumberOfAdjustableParameters() > 0)
+        {
+           newAdjustment(adjustableParameters->getNumberOfAdjustableParameters());
+
+           int numberOfParams = getNumberOfAdjustableParameters();
+           if(numberOfParams)
+           {
+              //***
+              // Allocate adjustable parameter partials grids then assign:
+              //***
+              theDlatDparamGrid = new ossimDblGrid [numberOfParams];
+              theDlonDparamGrid = new ossimDblGrid [numberOfParams];
+              ossim_uint32 paramIdx = 0;
+              for(paramIdx = 0; paramIdx < getNumberOfAdjustableParameters(); ++ paramIdx)
+              {
+                 theDlonDparamGrid[paramIdx].setNullValue(0.0);
+                 theDlatDparamGrid[paramIdx].setNullValue(0.0);
+                 theDlatDparamGrid[paramIdx].initialize(gridSize, gridOrigin, spacing);
+                 theDlonDparamGrid[paramIdx].initialize(gridSize, gridOrigin, spacing);
+                 setAdjustableParameter(paramIdx,
+                                        0.0);
+                 setParameterSigma(paramIdx,
+                                   adjustableParameters->getParameterSigma(paramIdx));
+                 setParameterUnit(paramIdx,
+                                  adjustableParameters->getParameterUnit(paramIdx));
+                 setParameterCenter(paramIdx,
+                                    0.0);
+                 setParameterDescription(paramIdx,
+                                         adjustableParameters->getParameterDescription(paramIdx));
+
+                 double oldParameter = adjustableParameters->getAdjustableParameter(paramIdx);
+                 adjustableParameters->setAdjustableParameter(paramIdx, 1.0, true);
+                 double adjust = adjustableParameters->computeParameterOffset(paramIdx);
+                 double deltaLat = 0;
+                 double deltaLon = 0;
+                 if(adjust != 0.0)
+                 {
+                    for(int y = 0; y < gridSize.y; ++y)
+                    {
+                       for(int x = 0; x < gridSize.x; ++x)
+                       {
+                          ossimDpt norm((double)x/(double)(gridSize.x-1),
+                                        (double)y/(double)(gridSize.y-1));
+                          
+                          ossimDpt pt(imageOrigin.x + norm.x*(imageSize.x-1),
+                                      imageOrigin.y + norm.y*(imageSize.y-1));
+                          
+                          proj->lineSampleHeightToWorld(pt, 0.0, gpt);
+
+                          gpt.changeDatum(targetDatum);
+                          gpt2.latd(theLatGrid(pt));
+                          gpt2.lond(theLonGrid(pt));
+                          deltaLat = gpt.latd()-gpt2.latd();
+                          deltaLon = gpt.lond()-gpt2.lond();
+
+                          theDlatDparamGrid[paramIdx].setNode(x, y,
+                                                              deltaLat/adjust);
+                          theDlonDparamGrid[paramIdx].setNode(x, y,
+                                                              deltaLon/adjust);
+                       }
+                    }
+                 }
+                 adjustableParameters->setAdjustableParameter(paramIdx, oldParameter, true);
+              }
+           }
+        }
+     }
+     getAdjustment(theInitialAdjustment);
+  }
+}
+
+void ossimCoarseGridModel::setInterpolationError(double error)
+{
+   theInterpolationError = error;
+}
+
+void ossimCoarseGridModel::setMinGridSpacing(ossim_int32 minSpacing)
+{
+   theMinGridSpacing = minSpacing;
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimCoarseGridModel()
+//  
+//*****************************************************************************
+ossimCoarseGridModel::~ossimCoarseGridModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimCoarseGridModel::~ossimCoarseGridModel: entering..."
+      << std::endl;
+
+   if(theDlatDparamGrid&&theDlonDparamGrid)
+   {
+      //***
+      // Deallocate memory:
+      //***
+      delete [] theDlatDparamGrid;
+      delete [] theDlonDparamGrid;
+      theDlatDparamGrid = NULL;
+      theDlonDparamGrid = NULL;
+   }
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimCoarseGridModel::~ossimCoarseGridModel: returning..."
+      << std::endl;
+}
+
+void ossimCoarseGridModel::lineSampleToWorld(const ossimDpt& image_point,
+                                             ossimGpt&       gpt) const
+{
+   if(!theHeightEnabledFlag)
+   {
+      //
+      // Extrapolate if image point is outside image:
+      //
+      if (!insideImage(image_point))
+      {
+         gpt = extrapolate(image_point);
+         return;
+      }
+      
+      lineSampleHeightToWorld(image_point, 0.0, gpt);
+   }
+   else
+   {
+      ossimSensorModel::lineSampleToWorld(image_point, gpt);
+   }
+}
+//*****************************************************************************
+//  METHOD: ossimCoarseGridModel::lineSampleHeightToWorld()
+//  
+//  Establishes the ground point corresponding to the input image_point and
+//  specified elevation above MSL
+//
+//*****************************************************************************
+void
+ossimCoarseGridModel::lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                              const double&   arg_hgt_above_ellipsoid,
+                                              ossimGpt&       worldPt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::lineSampleHeightToWorld: entering..." << std::endl;
+   
+   if(theLatGrid.size().x < 1 ||
+      theLatGrid.size().y < 1)
+   {
+      worldPt.makeNan();
+      return;
+   }
+
+   double height = (arg_hgt_above_ellipsoid == OSSIM_DBL_NAN) ? 0.0 : arg_hgt_above_ellipsoid;
+
+   // Extrapolate if point is outside image:
+   if (!insideImage(lineSampPt))
+   {
+      worldPt = extrapolate(lineSampPt, height);
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::lineSampleHeightToWorld: returning..." << std::endl;
+      return;
+   }
+
+   // The image point may correspond to an offset sub-image. Need to convert
+   // to full image space before anything:
+   ossimDpt ip = lineSampPt + theSubImageOffset;
+   
+   // Establish the interpolated values from the grids:
+   worldPt.lat = theLatGrid(ip);
+   worldPt.lon = theLonGrid(ip);
+   worldPt.hgt = height;
+
+   if(theHeightEnabledFlag)
+   {
+      // Adjust horizontally due to elevation:
+      worldPt.lat += theDlatDhGrid(ip)*height;
+      worldPt.lon += theDlonDhGrid(ip)*height;
+   }
+   int numberOfParams = getNumberOfAdjustableParameters();
+ 
+   // Now add increments due to adjustable parameter deltas:
+   for (int p=0; p<numberOfParams; p++)
+   {
+       worldPt.lat += (theDlatDparamGrid[p](ip) * computeParameterOffset(p));
+       worldPt.lon += (theDlonDparamGrid[p](ip) * computeParameterOffset(p));
+   }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::lineSampleHeightToWorld: returning..." << std::endl;
+}
+
+void ossimCoarseGridModel::initAdjustableParameters()
+{
+   if(getNumberOfAdjustableParameters() < 1)
+   {
+      addAdjustment(theInitialAdjustment, true);
+   }
+   else
+   {
+      setAdjustment(theInitialAdjustment, true);
+   }
+}
+
+void ossimCoarseGridModel::imagingRay(const ossimDpt& image_point,
+                                      ossimEcefRay&   image_ray) const
+{
+   ossimSensorModel::imagingRay(image_point, image_ray);
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimCoarseGridModel::print()
+//  
+//  Formatted dump of data members.
+//  
+//*****************************************************************************
+std::ostream& ossimCoarseGridModel::print(std::ostream& out) const 
+{
+   out << "\nDump of ossimCoarseGridModel object at: " << this << "\n"
+       << "\n           Grid File Name: " << theGridFilename 
+       << "\n                 Image ID: " << theImageID 
+       << "\n                   Sensor: " << theSensorID
+       << "\n  Image Size (rows, cols): " << theImageSize
+       << "\n      Ref Pt (samp, line): " << theRefImgPt 
+       << "\n   Ref Pt (lat, lon, hgt): " << theRefGndPt 
+       << "\n           GSD (row, col): " << theGSD 
+       << "\n  Bounding Ground Polygon: " << theBoundGndPolygon << endl;
+//      << "\n         Number of Params: " << theNumParams << "\n"<<endl;
+   
+   char buf[256];
+   ossimIpt size (theLatGrid.size());
+   ossimDpt spacing (theLatGrid.spacing());
+   int line, samp;
+   ossimIpt node;
+   
+   out << "[ line,  samp]        lat        lon         dLat/dH      dLon/dH\n"
+       << "-------------------------------------------------------------------"
+       <<endl;
+
+   for (node.y=0; node.y<size.y; node.y++)
+   {
+      line = (int) (node.y*spacing.y);
+      
+      for (node.x=0; node.x<size.x; node.x++)
+      {
+         samp = (int) (node.x*spacing.x);
+         
+         sprintf(buf, "[%5d, %5d]    %+9.5f  %+10.5f    %+11.4e  %+11.4e",
+                  line, samp,
+                  theLatGrid.getNode(node),
+                  theLonGrid.getNode(node),
+                  theDlatDhGrid.getNode(node),
+                  theDlonDhGrid.getNode(node));
+         out << buf << endl;
+      }
+      out <<"-----------------------------------------------------------------"
+          <<endl;
+   }
+
+   out << "\n\nDump of lat/lon Partials w.r.t. Adjustable Parameters:"<<endl;
+   out << "\nEnd Dump of ossimCoarseGridModel.\n" <<  endl;
+   return out;
+}
+
+//*****************************************************************************
+//  METHOD: ossimCoarseGridModel::loadGeomFile
+//  
+//  When a geometry file is specified, this function determines the proper
+//  method to invoke for reading contents.
+//
+//  Returns true if successful.
+//  
+//*****************************************************************************
+bool ossimCoarseGridModel::loadGeomFile(const ossimFilename& geom_file)
+{
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimCoarseGridModel::loadGeomFile: entering..."
+         << "\ngeom_file:  " << geom_file << std::endl;
+
+   }
+   
+   bool rtn_status;
+   ossimFilename geomFile = geom_file;
+   //***
+   // Open the file and test for format:
+   //***
+   ifstream ifs (geom_file);
+      
+   if (!ifs)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG : "
+            << "Failed attempt trying to open ossimCoarseGridModel geom "
+            << "file at: " << geom_file << ". Aborting construction..."
+            << std::endl;
+      }
+
+      theErrorStatus++;
+      if (traceExec())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimCoarseGridModel::loadGeomFile: returning..."
+            << std::endl;
+      }
+      
+      return false;
+   }
+   
+   //***
+   // Test for MET ECG magic number, and hand off to met ECG loader if present:
+   //***
+   // can't use ifs >> magic_number since on binary files this could go for a while.
+   // must use explicit byte count for test.
+   //
+      
+      char ecgMagic[4];
+      ifs.read((char*)ecgMagic, 3);
+      ecgMagic[3] = '\0';
+
+   if(ossimString(ecgMagic)== MET_ECG_MAGIC_NUMBER)
+   {
+      ossimFilename grid_file = geom_file;
+      grid_file.setExtension("");
+      grid_file.setFile(DEFAULT_MET_GRID_NAME);
+      rtn_status = loadMetEcgGeom(geom_file, grid_file);
+
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadGeomFile: returning..." << std::endl;
+      return rtn_status;
+   }
+   ifs.close();
+
+   //***
+   // Otherwise, assume the geom file is an OCG keywordlist:
+   //***
+   ossimKeywordlist kwl (geom_file);
+
+   rtn_status = loadState(kwl);
+   if(kwl.getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+      rtn_status = false;
+   }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadGeomFile: returning..." << std::endl;
+   return rtn_status;
+}
+
+//*****************************************************************************
+//  METHOD: ossimCoarseGridModel::saveState()
+//  
+//  Saves the model state to the KWL. This KWL also serves as a geometry file.
+//
+//  Returns true if successful.
+//  
+//*****************************************************************************
+bool ossimCoarseGridModel::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveState: entering..." << std::endl;
+
+   kwl.add(prefix, ossimKeywordNames::TYPE_KW, "ossimCoarseGridModel");
+   kwl.add(prefix, GRID_FILE_NAME_KW, theGridFilename);
+   kwl.add(prefix, "height_enabled_flag", theHeightEnabledFlag, true);
+   ossimSensorModel::saveState(kwl, prefix);
+   ossimString initAdjPrefix = ossimString(prefix) + "init_adjustment.";
+   theInitialAdjustment.saveState(kwl, initAdjPrefix);
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveState: returning..." << std::endl;
+
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimCoarseGridModel::loadState()
+//  
+//  Restores the model's state from the KWL. This KWL also serves as a
+//  geometry file.
+//
+//  Returns true if successful.
+//  
+//*****************************************************************************
+bool ossimCoarseGridModel::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix) 
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: entering..." << std::endl;
+
+   const char* value;
+   bool success;
+   
+   //***
+   // Assure this keywordlist contains correct type info:
+   //***
+   value = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   if (!value || (strcmp(value, "ossimCoarseGridModel")))
+   {
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState:  returning..." << std::endl;
+      theErrorStatus++;
+      return false;
+   }
+   value = kwl.find(prefix, "height_enabled_flag");
+   if(value)
+   {
+      theHeightEnabledFlag = ossimString(value).toBool();
+   }
+
+   //***
+   // Look for specification of separate geometry file:
+   //***
+   value = kwl.find(prefix, ossimKeywordNames::GEOM_FILE_KW);
+   if (value)
+   {
+      success = loadGeomFile(ossimFilename(value));
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: returning..." << std::endl;
+      return success;
+   }
+   
+   //***
+   // Pass on to the base-class for parsing first:
+   //***
+   success = ossimSensorModel::loadState(kwl, prefix);
+   if (!success)
+   {
+      theErrorStatus++;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: returning with error..." << std::endl;
+      return false;
+   }
+
+   value = kwl.find(prefix, GRID_FILE_NAME_KW);
+   if (value)
+      theGridFilename = value;
+   else
+   {
+      theErrorStatus++;
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: Error encountered parsing the following required keyword: "
+//                                           << "<" <<GRID_FILE_NAME_KW
+//                                           << ">. Check the keywordlist for proper syntax." << std::endl;
+//       if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: returning with error..." << std::endl;
+      return false;
+   }
+
+   if((theGridFilename != "") &&
+      (theGridFilename.exists()))
+   {
+      //***
+      // Load the coarse grid file specified in KWL. This method resets the
+      // theErrorStatus to OSSIM_OK if successful:
+      //***
+      loadCoarseGrid(theGridFilename);
+   }
+
+   ossimString initAdjPrefix = ossimString(prefix) + "init_adjustment.";
+
+   theInitialAdjustment.loadState(kwl, initAdjPrefix.c_str());
+
+   if((theRefGndPt.hgt == OSSIM_DBL_NAN) ||
+      (theRefGndPt.hgt == 0))
+   {
+      theRefGndPt.hgt = ossimElevManager::instance()->getHeightAboveEllipsoid(theRefGndPt);
+      if(theRefGndPt.hgt < 0)
+      {
+         theRefGndPt.hgt = fabs(theRefGndPt.hgt);
+      }
+   }
+      
+   if(theInitialAdjustment.getNumberOfAdjustableParameters() < 1)
+   {
+      getAdjustment(theInitialAdjustment);
+   }
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: returning..." << std::endl;
+   if (theErrorStatus)
+      return false;
+   
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimCoarseGridModel::saveCoarseGrid(cgFileName)
+//  
+//  Saves the coarse grid to disk file.
+//
+//  Returns true if successful.
+//  
+//*****************************************************************************
+bool ossimCoarseGridModel::saveCoarseGrid(const ossimFilename& cgFileName)const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveCoarseGrid: entering..." << std::endl;
+
+   //***
+   // Create and open grid file as stream:
+   //***
+   ofstream outstream (cgFileName.chars());
+   if (!outstream.is_open())
+   {
+      theErrorStatus++;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveCoarseGrid: Error encountered creating coarse grid file <" << cgFileName
+                                          << ">. Check that directory exists and is writable." << std::endl;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveCoarseGrid: returning with error..." << std::endl;
+      return false;
+   }
+
+   //***
+   // Let each grid object write itself to the output file:
+   //***
+   theLatGrid.save(outstream, "Latitude Grid");
+   theLonGrid.save(outstream, "Longitude Grid");
+   theDlatDhGrid.save(outstream, "dLat/dH Grid");
+   theDlonDhGrid.save(outstream, "dLon_dH Grid");
+
+   ossimString descr;
+   int numberOfParams = getNumberOfAdjustableParameters();
+   for (int p=0; p<numberOfParams; p++)
+   {
+      descr = getParameterDescription(p) + " dLat_dParam Grid";
+      theDlatDparamGrid[p].save(outstream, descr.chars());
+      descr = getParameterDescription(p) + " dLon_dParam Grid";
+      theDlonDparamGrid[p].save(outstream, descr.chars());
+   }
+   theGridFilename = cgFileName;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveCoarseGrid: returning..." << std::endl;
+   return true;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimCoarseGridModel::loadCoarseGrid(cgFileName)
+//  
+//  Loads the coarse grid from disk file.
+//
+//  Returns true if successful.
+//  
+//*****************************************************************************
+bool ossimCoarseGridModel::loadCoarseGrid(const ossimFilename& cgFileName)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadCoarseGrid: entering..." << std::endl;
+
+   ossimDpt v[4];
+   ossimIpt grid_size;
+
+   //***
+   // Open existing grid file:
+   //***
+   ifstream instream (cgFileName.chars());
+   if (!instream.is_open())
+   {
+      theErrorStatus++;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimCoarseGridModel::loadCoarseGrid: Error encountered opening coarse grid file <" << cgFileName
+                                          << ">. Check that the file exists and is readable." << std::endl;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "CEBUG ossimCoarseGridModel::loadCoarseGrid: returning with error..." << std::endl;
+      return false;
+   }
+   theGridFilename = cgFileName;
+   if(theDlatDparamGrid)
+     {
+       delete [] theDlatDparamGrid;
+       theDlatDparamGrid = NULL;
+     }
+   if(theDlonDparamGrid)
+     {
+       delete [] theDlonDparamGrid;
+       theDlonDparamGrid = NULL;
+     }
+   //
+   // Reallocate memory:
+   //
+   int numberOfParams = getNumberOfAdjustableParameters();
+   if(numberOfParams)
+   {
+      theDlatDparamGrid = new ossimDblGrid [numberOfParams];
+      theDlonDparamGrid = new ossimDblGrid [numberOfParams];
+   }
+   //***
+   // Let each grid object read itself from the input file:
+   //***
+   if (!theLatGrid.load(instream))
+   {
+      ++theErrorStatus;
+      return false;
+   }
+   if (!theLonGrid.load(instream))
+   {
+      ++theErrorStatus;
+      return false;
+   }
+   if (!theDlatDhGrid.load(instream))
+   {
+      ++theErrorStatus;
+      return false;
+   }
+   if (!theDlonDhGrid.load(instream))
+   {
+      ++theErrorStatus;
+      return false;
+   }
+
+   for (int p=0; p<numberOfParams; p++)
+   {
+      if (!theDlatDparamGrid[p].load(instream))
+      {
+         ++theErrorStatus;
+         return false;
+      }
+      if (!theDlonDparamGrid[p].load(instream))
+      {
+         ++theErrorStatus;
+         return false;
+      }
+   }
+
+   //***
+   // Initialize the bounging ground rectangle:
+   //***
+   grid_size = theLatGrid.size();
+
+
+   v[0].lat = theLatGrid(0,0);
+   v[0].lon = theLonGrid(0,0);
+   v[1].lat = theLatGrid(theImageSize.x-1, 0);
+   v[1].lon = theLonGrid(theImageSize.x-1, 0);
+   v[2].lat = theLatGrid(theImageSize.x-1, theImageSize.y-1);
+   v[2].lon = theLonGrid(theImageSize.x-1, theImageSize.y-1);
+   v[3].lat = theLatGrid(0, theImageSize.y-1);
+   v[3].lon = theLonGrid(0, theImageSize.y-1);
+
+
+//     ossimGpt gpt;
+//     lineSampleHeightToWorld(ossimDpt(0,0), 0, gpt);
+//     v[0].lat = gpt.latd();
+//     v[0].lon = gpt.lond();
+//     lineSampleHeightToWorld(ossimDpt(grid_size.x-1,0), 0.0, gpt);
+//     v[1].lat = gpt.latd();
+//     v[1].lon = gpt.lond();
+//     lineSampleHeightToWorld(ossimDpt(grid_size.x-1, grid_size.y-1), 0.0, gpt);
+//     v[2].lat = gpt.latd();
+//     v[2].lon = gpt.lond();
+//     lineSampleHeightToWorld(ossimDpt(0,grid_size.y-1), 0.0,gpt);
+//     v[3].lat = gpt.latd();
+//     v[3].lon = gpt.lond();
+   
+   theBoundGndPolygon = ossimPolygon(4, v);
+
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadCoarseGrid: returning..." << std::endl;
+   return true;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG rossimCoarseGridModel::loadCoarseGrid: eturning with error..." << std::endl;
+   return false;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimCoarseGridModel::reallocateGrid()
+//  
+//  Deletes existing grid arrays and allocates new ones.
+//  
+//*****************************************************************************
+void ossimCoarseGridModel::reallocateGrid(const ossimIpt& grid_size)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::reallocateGrid:entering..." << endl;
+
+
+   //***
+   // Deallocate memory:
+   //***
+   if(theDlatDparamGrid)
+     {
+       delete [] theDlatDparamGrid;
+       theDlatDparamGrid = NULL;
+     }
+   if(theDlonDparamGrid)
+     {
+       delete [] theDlonDparamGrid;
+       theDlonDparamGrid = NULL;
+     }
+   //***
+   // determine grid spacing given new info:
+   //***
+   ossimDpt spacing ((double)(theImageSize.x-1)/(double)(grid_size.x-1),
+                     (double)(theImageSize.y-1)/(double)(grid_size.y-1));
+
+   //***
+   // Allocate all:
+   //***
+   ossimDpt grid_origin(0.0, 0.0);
+   theLatGrid.setNullValue(OSSIM_DBL_NAN);
+   theLonGrid.setNullValue(OSSIM_DBL_NAN);
+   theDlatDhGrid.setNullValue(0.0);
+   theDlonDhGrid.setNullValue(0.0);
+   theLatGrid.initialize(grid_size, grid_origin, spacing);
+   theLonGrid.initialize(grid_size, grid_origin, spacing);
+   theDlatDhGrid.initialize(grid_size, grid_origin, spacing);
+   theDlonDhGrid.initialize(grid_size, grid_origin, spacing);
+
+   
+   int numberOfParams = getNumberOfAdjustableParameters();
+   if(numberOfParams)
+   {
+      
+      theDlatDparamGrid = new ossimDblGrid [numberOfParams];
+      theDlonDparamGrid = new ossimDblGrid [numberOfParams];
+   }
+   for (int p=0; p<numberOfParams; p++)
+   {
+      theDlonDparamGrid[p].setNullValue(0.0);
+      theDlatDparamGrid[p].setNullValue(0.0);
+      theDlatDparamGrid[p].initialize(grid_size, grid_origin, spacing);
+      theDlonDparamGrid[p].initialize(grid_size, grid_origin, spacing);
+   }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::reallocateGrid: returning..." << std::endl;
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimCoarseGridModel::loadMetEcgGeom(ecgGeomFile, ecgGridFile)
+//  
+//  Loads a met ECG geometry and grid, and outputs it to an
+//  ossimCoarseGridModel format KWL and grid file with the same base name.
+//  
+//*****************************************************************************
+bool ossimCoarseGridModel::loadMetEcgGeom(const ossimFilename& ecgGeomName,
+                                          const ossimFilename& ecgGridName) 
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadMetEcgGeom: entering..." << std::endl;
+
+   ossimNotify(ossimNotifyLevel_INFO) << "INFO ossimCoarseGridModel::loadMetEcgGeom: Converting MET ECG geometry file... "<< std::endl;
+   
+   //***
+   // Open existing MET ECG geom file:
+   //***
+   FILE* geomFile = fopen(ecgGeomName.chars(), "r");
+   if (!geomFile)
+   {
+      theErrorStatus++;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimCoarseGridModel::loadMetEcgGeom: Error encountered opening ECG geometry file <" << ecgGeomName
+                                          << ">. Check that the file exists and is readable." << std::endl;
+      
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadMetEcgGeom: returning with error..." << std::endl;
+      return false;
+   }
+
+   //***
+   // Open existing MET ECG grid file:
+   //***
+   FILE* gridFile = fopen(ecgGridName.chars(), "r");
+   if (!gridFile)
+   {
+      theErrorStatus++;
+      ossimNotify(ossimNotifyLevel_FATAL) << "fATAL ossimCoarseGridModel::loadMetEcgGeom: Error encountered opening ECG grid file <" << ecgGridName
+                                          << ">. Check that the file exists and is readable." << std::endl;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadMetEcgGeom: returning with error..." << std::endl;
+      return false;
+   }
+
+   //***
+   // Read from ECG geometry file:
+   //***
+   char    strbuf[128], desc[128];
+   int     version;
+   fscanf(geomFile,"%s %d %s", strbuf, &version, desc);
+   theImageID = strbuf;
+   
+   if (version > 1)
+   {
+      fscanf(geomFile,"%s %s", strbuf, desc);
+      theSensorID = strbuf;
+   }
+   else
+      theSensorID = "UNKNOWN";
+
+   ossimIpt grid_size;
+   int numParams;
+   fscanf(geomFile,"%d %s", (int*) &grid_size.line, desc);
+   fscanf(geomFile,"%d %s", (int*) &grid_size.samp, desc);
+   fscanf(geomFile,"%d %s", &numParams,     desc);
+
+   removeAllAdjustments();
+   newAdjustment(numParams);
+   //***
+   // Let base class allocate memory for parameter-associated arrays:
+   //***
+//   allocateAdjParams();
+   
+   if (version >3)
+   {
+      //***
+      // values for image offsets are doubles
+      //***
+      fscanf(geomFile,"%lf %s", &theSubImageOffset.line, desc);
+      fscanf(geomFile,"%lf %s", &theSubImageOffset.samp, desc);
+   }
+   else
+   {
+      if (version==3)
+      {
+         //***
+         // values for patch offsets are integers
+         //***
+         int intOffsetLine;
+         int intOffsetSample;
+         fscanf(geomFile,"%d %s", &intOffsetLine, desc);
+         fscanf(geomFile,"%d %s", &intOffsetSample, desc);
+         theSubImageOffset.line = intOffsetLine;
+         theSubImageOffset.samp = intOffsetSample;
+      }
+      else
+      {
+         //***
+         // patch offsets not supported:
+         //***
+         theSubImageOffset.line = 0.0;
+         theSubImageOffset.samp = 0.0;
+      }
+   }
+   fscanf(geomFile, "%d %s",  (int*) &theImageSize.line, desc);
+   fscanf(geomFile, "%d %s",  (int*) &theImageSize.samp, desc);
+
+   //***
+   // Initialize other data members given theImageSize:
+   //***
+   theImageClipRect = ossimDrect(0, 0, theImageSize.x-1, theImageSize.y-1);
+   theRefImgPt = ossimDpt((double)(theImageSize.x-1)/2.0,
+                          (double)(theImageSize.y-1)/2.0);
+
+   double pos_error, illumAz, illumElev;
+   int    illumDataFlag;
+   
+   fscanf(geomFile, "%lf %s", &theRefGndPt.hgt, desc);
+   fscanf(geomFile, "%lf %s", &pos_error, desc);
+   fscanf(geomFile, "%d %s",  &illumDataFlag,desc);
+   fscanf(geomFile, "%lf %s", &illumAz,desc);
+   fscanf(geomFile, "%lf %s", &illumElev,desc);
+
+   //***
+   // Read adjustable parameters from ECG geom file:
+   //***
+   int i;
+   double param=0.0;
+   for(i=0; i<numParams; i++)
+   {
+      fscanf(geomFile, "%lf %s", &param, desc);
+      setParameterCenter(i, param, false);
+      setAdjustableParameter(i, 0.0, false);
+      setParameterDescription(i, desc);
+      setParameterUnit(i, OSSIM_UNIT_UNKNOWN);
+   }
+
+   //***
+   // store the sigma values of the adjustable parameters in the input
+   // geometry file in Model_type. 
+   //***
+      for(i=0; i<numParams; i++)
+      {
+         double sigma = 0.0;
+         fscanf(geomFile,"%lf %s", &sigma, desc);
+         setParameterSigma(i, sigma, false);
+      }
+
+   //***
+   // store the values of the adjustable parameters as well as the description 
+   // of the parameters in the input geometry file in Model_type.
+   // NOTE: Version 5 format implies the adjustable parameters are zero.
+   //***
+   if (version < 5)
+   {
+      for(i=0; i<numParams; i++)
+      {
+	fscanf(geomFile,"%lf %s", &param, desc);
+	setParameterCenter(i, getParameterCenter(i) + param, false);
+      }
+   }
+   
+   //***
+   // Allocate memory for all arrays:
+   //***
+   reallocateGrid(grid_size);
+      
+   //***
+   // Read the enhanced coarse grid data --
+   // First read the phi, lambda, dphi_dh, dlambda_dh coarse grid entries from 
+   // the enhanced coarse grid file.
+   //***
+   fscanf(gridFile,"%s %s %s %s %s %s %s %s", desc, desc, desc, desc, 
+          desc, desc, desc, desc);
+   int intBuf;
+   double lat, lon, dlat_dh, dlon_dh, dlat_dp, dlon_dp;
+   for(int y=0; y<grid_size.y; y++)
+   {
+      for(int x=0; x<grid_size.x; x++)
+      {
+         fscanf(gridFile,"%d %d %lf %lf %lf %lf",
+                &intBuf, &intBuf, &lat, &lon, &dlat_dh, &dlon_dh);
+         theLatGrid.setNode(x, y, lat);
+         theLonGrid.setNode(x, y, lon);
+         theDlatDhGrid.setNode(x, y, dlat_dh);
+         theDlonDhGrid.setNode(x, y, dlon_dh);
+      }
+   }
+
+   //***
+   // read dphi_dp and dlambda_dp together
+   //***
+   fscanf(gridFile,"%s %s %s %s %s %s %s\n", desc, desc, desc, desc, 
+          desc, desc, desc);
+   for(int p=0; p<numParams; p++)
+   {
+      for(int y=0; y<grid_size.y; y++)
+      {
+         for(int x=0; x<grid_size.x; x++)
+         {
+            //***
+            // x=0, y=0 treated special:
+            //***
+            if ((x == 0) && (y == 0))
+            {
+               fscanf(gridFile,"%s %d %d %lf %lf",
+                      desc, &intBuf, &intBuf, &dlat_dp, &dlon_dp);
+            }
+            else
+            {
+               fscanf(gridFile,"%d %d %lf %lf",
+                      &intBuf, &intBuf, &dlat_dp, &dlon_dp);
+            }
+
+            theDlatDparamGrid[p].setNode(x, y, dlat_dp);
+            theDlonDparamGrid[p].setNode(x, y, dlon_dp);
+         }
+      }
+   }
+
+   fclose (geomFile);
+   fclose (gridFile);
+
+   //***
+   // Establish reference ground point as center of image:
+   //***
+   theRefGndPt.lat = theLatGrid(theRefImgPt);
+   theRefGndPt.lon = theLonGrid(theRefImgPt);
+   //***
+   // Establish the GSD at image center:
+   //***
+   ossimDpt ref_ip_dx(theRefImgPt.x+1.0, theRefImgPt.y);
+   ossimDpt ref_ip_dy(theRefImgPt.x, theRefImgPt.y+1.0);
+   ossimGpt ref_gp_dx(theLatGrid(ref_ip_dx), theLonGrid(ref_ip_dx));
+   ossimGpt ref_gp_dy(theLatGrid(ref_ip_dy), theLonGrid(ref_ip_dy));
+   theGSD.x = theRefGndPt.distanceTo(ref_gp_dx);
+   theGSD.y = theRefGndPt.distanceTo(ref_gp_dy);
+   theMeanGSD = (theGSD.line + theGSD.samp)/2.0;
+   
+   theGSD.x = theMeanGSD;
+   theGSD.y = theMeanGSD;
+
+   //***
+   // Initialize the bounging ground rectangle:
+   //***
+   ossimDpt v[4];
+   v[0].lat = theLatGrid.getNode(0,0);
+   v[0].lon = theLonGrid.getNode(0,0);
+   v[1].lat = theLatGrid.getNode(grid_size.x-1,0);
+   v[1].lon = theLonGrid.getNode(grid_size.x-1,0);
+   v[2].lat = theLatGrid.getNode(grid_size.x-1,grid_size.y-1);
+   v[2].lon = theLonGrid.getNode(grid_size.x-1,grid_size.y-1);
+   v[3].lat = theLatGrid.getNode(0,grid_size.y-1);
+   v[3].lon = theLonGrid.getNode(0,grid_size.y-1);
+   theBoundGndPolygon = ossimPolygon(4, v);
+   
+   //***
+   // Now save state and grid. First extract base name:
+   //***
+   ossimFilename path (ecgGeomName.path());
+   ossimFilename base (ecgGeomName.fileNoExtension());
+   ossimFilename ocgGeomName (path.dirCat(base) + DEFAULT_GEOM_FILE_EXT);
+   theGridFilename = ossimFilename(path.dirCat(base) + DEFAULT_GRID_FILE_EXT);
+
+   ossimString drivePart;
+   ossimString pathPart;
+   ossimString filePart;
+   ossimString extPart;
+   ecgGeomName.split(drivePart,
+                     pathPart,
+                     filePart,
+                     extPart);
+   
+   ossimFilename ocgGeoName;
+   ocgGeomName.merge(drivePart,
+                    pathPart,
+                    filePart+DEFAULT_GEOM_FILE_EXT,
+                    "");
+   theGridFilename.merge(drivePart,
+                    pathPart,
+                    filePart+DEFAULT_GRID_FILE_EXT,
+                    "");
+
+   getAdjustment(theInitialAdjustment);
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadMetEcgGeom: returning..." << std::endl;
+   return true;
+}
+
+//*****************************************************************************
+// STATIC METHOD: ossimCoarseGridModel::writeGeomTemplate
+//  
+//  Writes a sample geometry KWL to the output stream.
+//  
+//*****************************************************************************
+void ossimCoarseGridModel::writeGeomTemplate(ostream& os)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::writeGeomTemplate: entering..." << std::endl;
+
+   os <<
+      "//**************************************************************\n"
+      "// Template for OCG model kewordlist\n"
+      "//**************************************************************\n"
+      << ossimKeywordNames::TYPE_KW << ": " << MODEL_TYPE << endl;
+
+   ossimSensorModel::writeGeomTemplate(os);
+   
+   os << "//\n"
+      << "// Derived-class ossimCoarseGridModel Keywords:\n"
+      << "//\n"
+      << GRID_FILE_NAME_KW << ": <string>\n" << endl;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::writeGeomTemplate: returning..." << std::endl;
+   return;
+}
+   
+
+      
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.h
new file mode 100644
index 0000000000..24aa4c204e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/coarse_grid/ossimCoarseGridModel.h
@@ -0,0 +1,173 @@
+//*****************************************************************************
+// FILE: ossimCoarseGridModel.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimCoarseGridModel. This is an
+//   implementation of an interpolation sensor model.
+//
+//*****************************************************************************
+//  $Id: ossimCoarseGridModel.h,v 1.22 2005/09/22 11:58:12 gpotts Exp $
+
+#ifndef ossimCoarseGridModel_HEADER
+#define ossimCoarseGridModel_HEADER
+
+#include "projections/sensor_modeling/ossimSensorModel.h"
+#include "base/data_types/ossimIpt.h"
+#include "base/data_types/ossimDblGrid.h"
+#include "base/data_types/ossimFilename.h"
+
+/******************************************************************************
+ *
+ * CLASS:  ossimCoarseGridModel
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimCoarseGridModel : public ossimSensorModel
+{
+public:
+   /**
+    * CONSTRUCTORS:
+    */
+   ossimCoarseGridModel();
+   ossimCoarseGridModel(const ossimCoarseGridModel& copy_this);
+
+   /**
+    * CONSTRUCTOR (filename)
+    * Accepts name of geometry file. This can be either MET ECG geom file, or
+    * OSSIM keywordlist geometry file.
+    */
+   ossimCoarseGridModel(const ossimFilename& geom_file);
+
+   /**
+    * CONSTRUCTOR (keywordlist)
+    * Accepts OSSIM keywordlist geometry file.
+    */
+   ossimCoarseGridModel(const ossimKeywordlist& geom_kwl);
+   
+   ~ossimCoarseGridModel();
+
+   /**
+    * This method will build a grid from any projector.
+    * The first argument must be the image space bounds for
+    * the projection.  The second argument is the projector
+    * that will be used to approximate a bilinear grid over.
+    *
+    * The accuracy of the grid can be controlled by the static method
+    * setInterpolationError.
+    */
+  virtual void buildGrid(const ossimDrect& imageBounds,
+			 ossimProjection* proj,
+                         double heightDelta=500.0,
+                         bool enableHeightFlag=false,
+                         bool makeAdjustableFlag=true);
+
+   /**
+    *  This is used when building a grid from a projector.
+    *  You can set the interpolation error.  The default is
+    *  subpixel accuracy (within .1 of a pixel).
+    */
+   static void setInterpolationError(double error=.1);
+   static void setMinGridSpacing(ossim_int32 minSpacing = 100);
+   /**
+    * METHOD: print()
+    * Extends base-class implementation. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   /**
+    * METHODS:  saveState, loadState
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files. Returns true if successful.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0) const;
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+
+   /**
+    * STATIC METHOD: writeGeomTemplate(ostream)
+    * Writes a template of geometry keywords processed by loadState and
+    * saveState to output stream.
+    */
+   static void writeGeomTemplate(ostream& os);
+
+   /**
+    * METHOD: dup()
+    * Returns pointer to a new instance, copy of this.
+    */
+   virtual ossimObject* dup() const
+      { return new ossimCoarseGridModel(*this); }
+   
+   /**
+    * METHOD: loadGeomFile()
+    * Since there are tweo geometry file formats supported (native KWL and MET
+    * ECG), this method determines which parser method to invoke.
+    */
+   bool loadGeomFile(const ossimFilename& geom_file);
+   
+   /**
+    * METHOD: saveCoarseGrid(), loadCoarseGrid()
+    * Saves/loads the coarse grid to/from the specified file. Returns true if
+    * successful.
+    */
+   bool saveCoarseGrid(const ossimFilename& cgFileName) const;
+   bool loadCoarseGrid(const ossimFilename& cgFileName);
+
+   /**
+    * METHOD: loadMetEcgGeom()
+    * Service to initialize this object from a MET ECG geom and grid files. 
+    */
+   bool loadMetEcgGeom(const ossimFilename& ecgGeomFile,
+                       const ossimFilename& ecgGridFile);
+
+   virtual void imagingRay(const ossimDpt& image_point,
+                           ossimEcefRay&   image_ray) const;
+
+   
+   virtual void lineSampleToWorld(const ossimDpt& image_point,
+                                  ossimGpt&       gpt) const;
+   /**
+    * METHOD: lineSampleHeightToWorld(image_point, height, &ground_point)
+    * This is the virtual that performs the actual work of projecting
+    * the image point to the earth at some specified elevation.
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const double&   heightEllipsoid,
+                                        ossimGpt&       world_pt) const;
+
+
+   virtual void initAdjustableParameters();
+   
+private:
+   /**
+    * METHOD: reallocateGrid()
+    * Deletes existing allocated memory and reallocates
+    * new space. This may happen if a new grid is loaded over an existing one.
+    */
+   void reallocateGrid(const ossimIpt& size);
+   
+   /**
+    * Data Members:
+    */
+   mutable ossimFilename theGridFilename;
+   ossimDblGrid  theLatGrid;         // degrees
+   ossimDblGrid  theLonGrid;         // degrees
+   ossimDblGrid  theDlatDhGrid;      // degrees/meter
+   ossimDblGrid  theDlonDhGrid;      // degrees/meter
+   ossimDblGrid* theDlatDparamGrid;  // degrees/(units-of-param)
+   ossimDblGrid* theDlonDparamGrid;  // degrees/(units-of-param)
+
+   static double       theInterpolationError;
+   static ossim_int32  theMinGridSpacing;
+   ossimAdjustmentInfo theInitialAdjustment;
+   bool                theHeightEnabledFlag;
+   
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/.cvsignore b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixEcefModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixEcefModel.cpp
new file mode 100644
index 0000000000..c8ba0cb32a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixEcefModel.cpp
@@ -0,0 +1,625 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LGPL
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimApplanixEcefModel.cpp,v 1.15 2005/09/06 16:21:11 gpotts Exp $
+#include <sstream>
+#include "ossimApplanixEcefModel.h"
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/misc/ossimUnitConversionTool.h>
+#include <base/misc/lookup_tables/ossimUnitTypeLut.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/data_types/ossimLsrSpace.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/geoid/ossimGeoidManager.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <support_data/fcsi/ossimApplanixEOFile.h>
+#include <base/data_types/ossimMatrix4x4.h>
+static ossimTrace traceDebug("ossimApplanixEcefModel:debug");
+
+RTTI_DEF1(ossimApplanixEcefModel, "ossimApplanixEcefModel", ossimSensorModel);
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimApplanixEcefModel.cpp,v 1.15 2005/09/06 16:21:11 gpotts Exp $";
+#endif
+
+ossimApplanixEcefModel::ossimApplanixEcefModel()
+{
+   theCompositeMatrix          = ossimMatrix4x4::createIdentity();
+   theCompositeMatrixInverse   = ossimMatrix4x4::createIdentity();
+   theRoll                     = 0.0;
+   thePitch                    = 0.0;
+   theHeading                  = 0.0;
+   theFocalLength              = 55.0;
+   thePixelSize = ossimDpt(.009, .009);
+   theEcefPlatformPosition = ossimGpt(0.0,0.0, 1000.0);
+   theAdjEcefPlatformPosition = ossimGpt(0.0,0.0, 1000.0);
+   theGSD.x = 0.1524;
+   theGSD.y = 0.1524;
+   theMeanGSD = 0.1524;
+   theLensDistortion = new ossimMeanRadialLensDistortion;
+   initAdjustableParameters();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimApplanixEcefModel::ossimApplanixEcefModel DEBUG:" << endl;
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)<< "OSSIM_ID:  " << OSSIM_ID << endl;
+#endif
+   }
+}
+
+ossimApplanixEcefModel::ossimApplanixEcefModel(const ossimApplanixEcefModel& src)
+   :ossimSensorModel(src)
+{
+   if(src.theLensDistortion.valid())
+   {
+      theLensDistortion = new ossimMeanRadialLensDistortion(*(src.theLensDistortion.get()));
+   }
+   else
+   {
+      theLensDistortion = new ossimMeanRadialLensDistortion();
+   }
+}
+
+ossimObject* ossimApplanixEcefModel::dup()const
+{
+   return new ossimApplanixEcefModel(*this);
+}
+
+void ossimApplanixEcefModel::imagingRay(const ossimDpt& image_point,
+                                    ossimEcefRay&   image_ray) const
+{
+//    if(traceDebug())
+//    {
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "ossimApplanixEcefModel::imagingRay: ..... entered" << std::endl;
+//    }
+    ossimDpt f1 ((image_point) - theRefImgPt);
+   f1.x *= thePixelSize.x;
+   f1.y *= -thePixelSize.y;
+   ossimDpt film (f1 - thePrincipalPoint);
+//    if(traceDebug())
+//    {
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "pixel size   = " << thePixelSize << std::endl;
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "principal pt = " << thePrincipalPoint << std::endl;
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "film pt      = " << film << std::endl;
+//    }
+   if (theLensDistortion.valid())
+   {
+      ossimDpt filmOut;
+      theLensDistortion->undistort(film, filmOut);
+      film = filmOut;
+   }
+   
+   ossimColumnVector3d cam_ray_dir (film.x,
+                                    film.y,
+                                    -theFocalLength);
+   ossimEcefVector     ecf_ray_dir (theCompositeMatrix*cam_ray_dir);
+   ecf_ray_dir = ecf_ray_dir*(1.0/ecf_ray_dir.magnitude());
+   
+   image_ray.setOrigin(theAdjEcefPlatformPosition);
+   image_ray.setDirection(ecf_ray_dir);
+   
+//    if(traceDebug())
+//    {
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "ossimApplanixEcefModel::imagingRay: ..... leaving" << std::endl;
+//    }
+}
+
+void ossimApplanixEcefModel::lineSampleHeightToWorld(const ossimDpt& image_point,
+                                                 const double&   heightEllipsoid,
+                                                 ossimGpt&       worldPoint) const
+{
+   if (!insideImage(image_point))
+   {
+      worldPoint = extrapolate(image_point, heightEllipsoid);
+   }
+   else
+   {
+      //***
+      // First establish imaging ray from image point:
+      //***
+      ossimEcefRay ray;
+      imagingRay(image_point, ray);
+      ossimEcefPoint Pecf (ray.intersectAboveEarthEllipsoid(heightEllipsoid));
+      worldPoint = ossimGpt(Pecf);
+   }
+}
+
+void ossimApplanixEcefModel::worldToLineSample(const ossimGpt& world_point,
+                                           ossimDpt&       image_point) const
+{
+   if((theBoundGndPolygon.getNumberOfVertices() > 0)&&
+      (!theBoundGndPolygon.hasNans()))
+   {
+      if (!(theBoundGndPolygon.pointWithin(world_point)))
+      {
+         image_point = extrapolate(world_point);
+         return;
+      }         
+   }
+   ossimEcefPoint g_ecf(world_point);
+   ossimEcefVector ecfRayDir(g_ecf - theAdjEcefPlatformPosition);
+   ossimColumnVector3d camRayDir (theCompositeMatrixInverse*ecfRayDir.data());
+   
+      
+   double scale = -theFocalLength/camRayDir[2];
+   ossimDpt film (scale*camRayDir[0], scale*camRayDir[1]);
+      
+   if (theLensDistortion.valid())
+   {
+      ossimDpt filmOut;
+      theLensDistortion->distort(film, filmOut);
+      film = filmOut;
+    }
+   
+     ossimDpt f1(film + thePrincipalPoint);
+    ossimDpt p1(f1.x/thePixelSize.x,
+                -f1.y/thePixelSize.y);
+
+    ossimDpt p0 (p1.x + theRefImgPt.x,
+                 p1.y + theRefImgPt.y);
+    
+    image_point = p0;
+}
+
+void ossimApplanixEcefModel::updateModel()
+{
+   ossimGpt gpt;
+   
+   ossimGpt wgs84Pt;
+   double metersPerDegree = wgs84Pt.metersPerDegree().x;
+   double degreePerMeter = 1.0/metersPerDegree;
+   double latShift = -computeParameterOffset(1)*theMeanGSD*degreePerMeter;
+   double lonShift = computeParameterOffset(0)*theMeanGSD*degreePerMeter;
+
+   gpt = theEcefPlatformPosition;
+   double height = gpt.height();
+   gpt.height(height + computeParameterOffset(5));
+   gpt.latd(gpt.latd() + latShift);
+   gpt.lond(gpt.lond() + lonShift);
+   theAdjEcefPlatformPosition = gpt;
+   
+   ossimLsrSpace lsrSpace(theAdjEcefPlatformPosition, theHeading+computeParameterOffset(4));
+
+   // make a left handed roational matrix;
+   ossimMatrix4x4 lsrMatrix(lsrSpace.lsrToEcefRotMatrix());
+   NEWMAT::Matrix orientation = (ossimMatrix4x4::createRotationXMatrix(thePitch+computeParameterOffset(3), OSSIM_LEFT_HANDED)*
+                                 ossimMatrix4x4::createRotationYMatrix(theRoll+computeParameterOffset(2), OSSIM_LEFT_HANDED));
+   theCompositeMatrix        = (lsrMatrix.getData()*orientation);
+   theCompositeMatrixInverse = theCompositeMatrix.i();
+
+   theBoundGndPolygon.resize(4);
+   ossim_float64 w = theImageClipRect.width()*.1;
+   ossim_float64 h = theImageClipRect.height()*.1;
+   
+   lineSampleToWorld(theImageClipRect.ul()+ossimDpt(-w, -h), gpt);
+   theBoundGndPolygon[0] = gpt;
+   lineSampleToWorld(theImageClipRect.ur()+ossimDpt(w, -h), gpt);
+   theBoundGndPolygon[1] = gpt;
+   lineSampleToWorld(theImageClipRect.lr()+ossimDpt(w, h), gpt);
+   theBoundGndPolygon[2] = gpt;
+   lineSampleToWorld(theImageClipRect.ll()+ossimDpt(-w, h), gpt);
+   theBoundGndPolygon[3] = gpt;
+}
+
+void ossimApplanixEcefModel::initAdjustableParameters()
+{
+
+   resizeAdjustableParameterArray(6);
+   
+   setAdjustableParameter(0, 0.0);
+   setParameterDescription(0, "x_offset");
+   setParameterUnit(0, "pixels");
+
+   setAdjustableParameter(1, 0.0);
+   setParameterDescription(1, "y_offset");
+   setParameterUnit(1, "pixels");
+
+   setAdjustableParameter(2, 0.0);
+   setParameterDescription(2, "roll");
+   setParameterUnit(2, "degrees");
+
+   setAdjustableParameter(3, 0.0);
+   setParameterDescription(3, "pitch");
+   setParameterUnit(3, "degrees");
+
+   setAdjustableParameter(4, 0.0);
+   setParameterDescription(4, "heading");
+   setParameterUnit(4, "degrees");
+
+   setAdjustableParameter(5, 0.0);
+   setParameterDescription(5, "altitude");
+   setParameterUnit(5, "meters");
+   
+   
+   setParameterSigma(0, 100.0);
+   setParameterSigma(1, 100.0);
+   setParameterSigma(2, 1);
+   setParameterSigma(3, 1);
+   setParameterSigma(4, 4);
+   setParameterSigma(5, 50);
+}
+
+void ossimApplanixEcefModel::setPrincipalPoint(ossimDpt principalPoint)
+{
+   thePrincipalPoint = principalPoint;
+}
+
+void ossimApplanixEcefModel::setRollPitchHeading(double roll,
+                                                 double pitch,
+                                                 double heading)
+{
+   theRoll    = roll;
+   thePitch   = pitch;
+   theHeading = heading;
+   
+   updateModel();
+}
+
+void ossimApplanixEcefModel::setPixelSize(const ossimDpt& pixelSize)
+{
+   thePixelSize = pixelSize;
+}
+
+void ossimApplanixEcefModel::setImageRect(const ossimDrect& rect)
+{
+   theImageClipRect = rect;
+   theRefImgPt = rect.midPoint();
+}
+
+void ossimApplanixEcefModel::setFocalLength(double focalLength)
+{
+   theFocalLength = focalLength;
+}
+
+void ossimApplanixEcefModel::setPlatformPosition(const ossimGpt& gpt)
+{
+   theRefGndPt            = gpt;
+   theEcefPlatformPosition = gpt;
+   updateModel();
+   
+}
+
+bool ossimApplanixEcefModel::saveState(ossimKeywordlist& kwl,
+                                   const char* prefix) const
+{
+   ossimSensorModel::saveState(kwl, prefix);
+   
+   kwl.add(prefix, "type", "ossimApplanixEcefModel", true);
+
+   kwl.add(prefix, "roll", theRoll, true);
+   kwl.add(prefix, "pitch", thePitch, true);
+   kwl.add(prefix, "heading", theHeading, true);
+   kwl.add(prefix, "principal_point", ossimString::toString(thePrincipalPoint.x) + " " + ossimString::toString(thePrincipalPoint.y));
+   kwl.add(prefix, "pixel_size",      ossimString::toString(thePixelSize.x) + " " + ossimString::toString(thePixelSize.y));
+   kwl.add(prefix, "focal_length", theFocalLength);
+   kwl.add(prefix, "ecef_platform_position",
+           ossimString::toString(theEcefPlatformPosition.x()) + " " +
+           ossimString::toString(theEcefPlatformPosition.y()) + " " +
+           ossimString::toString(theEcefPlatformPosition.z()));
+
+   if(theLensDistortion.valid())
+   {
+      ossimString lensPrefix = ossimString(prefix)+"distortion.";
+      theLensDistortion->saveState(kwl,
+                                   lensPrefix.c_str());
+   }
+   
+   return true;
+}
+
+bool ossimApplanixEcefModel::loadState(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+{
+   if(traceDebug())
+   {
+      std::cout << "ossimApplanixEcefModel::loadState: ......... entered" << std::endl;
+   }
+   theImageClipRect = ossimDrect(0,0,4076,4091);
+   theRefImgPt      = ossimDpt(2046.0, 2038.5);
+
+   ossimSensorModel::loadState(kwl, prefix);
+   
+   theEcefPlatformPosition    = ossimGpt(0.0,0.0,1000.0);
+   theAdjEcefPlatformPosition = ossimGpt(0.0,0.0,1000.0);
+   theRoll    = 0.0;
+   thePitch   = 0.0;
+   theHeading = 0.0;
+   bool computeGsdFlag = false;
+   const char* roll              = kwl.find(prefix, "roll");
+   const char* pitch             = kwl.find(prefix, "pitch");
+   const char* heading           = kwl.find(prefix, "heading");
+   const char* principal_point   = kwl.find(prefix, "principal_point");
+   const char* pixel_size        = kwl.find(prefix, "pixel_size");
+   const char* focal_length      = kwl.find(prefix, "focal_length");
+   const char* ecef_platform_position = kwl.find(prefix, "ecef_platform_position");
+   const char* latlonh_platform_position = kwl.find(prefix, "latlonh_platform_position");
+   const char* compute_gsd_flag  = kwl.find(prefix, "compute_gsd_flag");
+   const char* eo_file           = kwl.find(prefix, "eo_file");
+   const char* camera_file       = kwl.find(prefix, "camera_file");
+   const char* eo_id             = kwl.find(prefix, "eo_id");
+   bool result = true;
+   if(eo_id)
+   {
+      theImageID = eo_id;
+   }
+   if(eo_file)
+   {
+      ossimApplanixEOFile eoFile;
+      if(eoFile.parseFile(ossimFilename(eo_file)))
+      {
+         ossimRefPtr<ossimApplanixEORecord> record = eoFile.getRecordGivenId(theImageID);
+         if(record.valid())
+         {
+            ossim_int32 rollIdx    = eoFile.getFieldIdx("ROLL");
+            ossim_int32 pitchIdx   = eoFile.getFieldIdx("PITCH");
+            ossim_int32 headingIdx = eoFile.getFieldIdx("HEADING");
+            ossim_int32 xIdx       = eoFile.getFieldIdx("X");
+            ossim_int32 yIdx       = eoFile.getFieldIdx("Y");
+            ossim_int32 zIdx       = eoFile.getFieldIdx("Z");
+
+            if((rollIdx >= 0)&&
+               (pitchIdx >= 0)&&
+               (headingIdx >= 0)&&
+               (xIdx >= 0)&&
+               (yIdx >= 0)&&
+               (zIdx >= 0))
+            {
+               theRoll    = (*record)[rollIdx].toDouble();
+               thePitch   = (*record)[pitchIdx].toDouble();
+               theHeading = (*record)[headingIdx].toDouble();
+               theEcefPlatformPosition = ossimEcefPoint((*record)[xIdx].toDouble(),
+                                                        (*record)[yIdx].toDouble(),
+                                                        (*record)[zIdx].toDouble());
+               theAdjEcefPlatformPosition = theEcefPlatformPosition;
+            }
+            else
+            {
+               return false;
+            }
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_WARN) << "ossimApplanixEcefModel::loadState()  Image id " << theImageID << " not found in eo file " << eo_file << std::endl;
+            
+            return false;
+         }
+      }
+      else
+      {
+         return false;
+      }
+      computeGsdFlag = true;
+   }
+   else
+   {
+      if(roll)
+      {
+         theRoll = ossimString(roll).toDouble();
+      }
+      if(pitch)
+      {
+         thePitch = ossimString(pitch).toDouble();
+      }
+      if(heading)
+      {
+         theHeading = ossimString(heading).toDouble();
+      }
+      if(ecef_platform_position)
+      {
+         std::istringstream in(ecef_platform_position);
+         double x,y,z;
+         in >> x
+            >> y
+            >> z;
+         
+         theEcefPlatformPosition = ossimEcefPoint(x,y,z);
+      }
+      else if(latlonh_platform_position)
+      {
+         std::istringstream in(latlonh_platform_position);
+         double lat,lon,hgt;
+         in >> lat
+            >> lon
+            >> hgt;
+         
+         theEcefPlatformPosition = ossimGpt(lat,lon,hgt);
+      }
+   }
+
+   if(camera_file)
+   {
+      ossimKeywordlist cameraKwl;
+      ossimKeywordlist lensKwl;
+      cameraKwl.add(camera_file);
+      const char* sensor = cameraKwl.find("sensor");
+      const char* image_size      = cameraKwl.find(prefix, "image_size");
+      principal_point = cameraKwl.find("principal_point");
+      focal_length    = cameraKwl.find("focal_length");
+      pixel_size      = cameraKwl.find(prefix, "pixel_size");
+      focal_length    = cameraKwl.find(prefix, "focal_length");
+      const char* distortion_units = cameraKwl.find(prefix, "distortion_units");
+      ossimUnitConversionTool tool;
+      ossimUnitType unitType = OSSIM_MILLIMETERS;
+
+      if(distortion_units)
+      {
+         unitType = (ossimUnitType)ossimUnitTypeLut().getEntryNumber(distortion_units);
+
+         if(unitType == OSSIM_UNIT_UNKNOWN)
+         {
+            unitType = OSSIM_MILLIMETERS;
+         }
+      }
+      if(image_size)
+      {
+         std::istringstream in(image_size);
+         double w, h;
+         in>>w >> h;
+         theImageClipRect = ossimDrect(0,0,w-1,h-1);
+         theRefImgPt      = ossimDpt(w/2.0, h/2.0);
+      }
+      if(sensor)
+      {
+         theSensorID = sensor;
+      }
+      if(principal_point)
+      {
+         std::istringstream in(principal_point);
+         in >>thePrincipalPoint.x >> thePrincipalPoint.y;
+      }
+      if(pixel_size)
+      {
+         std::istringstream in(pixel_size);
+         in >> thePixelSize.x;
+         thePixelSize.y = thePixelSize.x;
+      }
+      if(focal_length)
+      {
+         theFocalLength = ossimString(focal_length).toDouble();
+      }
+
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < 26; ++idx)
+      {
+         const char* value = cameraKwl.find(ossimString("d")+ossimString::toString(idx));
+
+         if(value)
+         {
+            std::istringstream in(value);
+            double distance, distortion;
+
+            in >> distance >> distortion;
+            tool.setValue(distortion, unitType);
+            lensKwl.add(ossimString("distance") + ossimString::toString(idx),
+                        distance,
+                        true);
+            lensKwl.add(ossimString("distortion") + ossimString::toString(idx),
+                        tool.getMillimeters(),
+                        true);
+         }
+         lensKwl.add("convergence_threshold",
+                     .00001,
+                     true);
+         if(pixel_size)
+         {
+            lensKwl.add("dxdy",
+                        ossimString(pixel_size) + " " + ossimString(pixel_size),
+                        true);
+         }
+         else
+         {
+            lensKwl.add("dxdy",
+                        ".009 .009",
+                        true);
+         }
+      }
+      if(theLensDistortion.valid())
+      {
+         theLensDistortion->loadState(lensKwl,"");
+      }
+   }
+   else
+   {
+      
+      if(principal_point)
+      {
+         std::istringstream in(principal_point);
+         in >>thePrincipalPoint.x >> thePrincipalPoint.y;
+      }
+      else
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "No principal_point found" << std::endl;
+            result = false;
+         }
+      }
+      if(pixel_size)
+      {
+         std::istringstream in(pixel_size);
+         in >> thePixelSize.x >> thePixelSize.y;
+      }
+      else
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "No pixel size found" << std::endl;
+            result = false;
+         }
+      }
+      if(focal_length)
+      {
+         theFocalLength = ossimString(focal_length).toDouble();
+      }
+      else
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "No focal length found" << std::endl;
+            result = false;
+         }
+      }
+      
+      if(theLensDistortion.valid())
+      {
+         ossimString lensPrefix = ossimString(prefix)+"distortion.";
+         if(!theLensDistortion->loadState(kwl,
+                                          lensPrefix.c_str()))
+         {
+            result = false;
+         }
+      }
+   }
+   theRefGndPt = theEcefPlatformPosition;
+   theRefGndPt.height(0.0);
+   if(compute_gsd_flag||computeGsdFlag)
+   {
+      theMeanGSD = OSSIM_DBL_NAN;
+      
+   }
+
+
+   updateModel();
+
+   ossimGpt centerGpt;
+   lineSampleToWorld(theRefImgPt, centerGpt);
+   if(compute_gsd_flag)
+   {
+      if(ossimString(compute_gsd_flag).toBool())
+      {
+         ossimGpt right;
+         ossimGpt top;
+         lineSampleToWorld(theRefImgPt + ossimDpt(1.0, 0.0),
+                           right);
+         lineSampleToWorld(theRefImgPt + ossimDpt(0.0, -1.0),
+                           top);
+         
+         ossimEcefVector horizontal = ossimEcefPoint(centerGpt)-ossimEcefPoint(right);
+         ossimEcefVector vertical   = ossimEcefPoint(centerGpt)-ossimEcefPoint(top);
+
+         theGSD.x = horizontal.length();
+         theGSD.y = vertical.length();
+         theMeanGSD = (theGSD.x+theGSD.y)*.5;
+      }
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << std::setprecision(15) << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "roll:     " << theRoll << std::endl
+                                          << "pitch:    " << thePitch << std::endl
+                                          << "heading:  " << theHeading << std::endl
+                                          << "platform: " << theEcefPlatformPosition << std::endl
+                                          << "focal len: " << theFocalLength << std::endl
+                                          << "principal: " << thePrincipalPoint << std::endl
+                                          << "Ground:    " << ossimGpt(theEcefPlatformPosition) << std::endl;
+   }
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixEcefModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixEcefModel.h
new file mode 100644
index 0000000000..0968389728
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixEcefModel.h
@@ -0,0 +1,71 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LGPL
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimApplanixEcefModel.h,v 1.5 2005/06/29 12:00:15 gpotts Exp $
+#ifndef ossimApplanixEcefModel_HEADER
+#define ossimApplanixEcefModel_HEADER
+#include "ossimFcsiModel.h"
+#include <projections/sensor_modeling/ossimMeanRadialLensDistortion.h>
+#include <base/data_types/ossimDpt3d.h>
+
+class OSSIM_DLL ossimApplanixEcefModel : public ossimSensorModel
+{
+public:
+   ossimApplanixEcefModel();
+   ossimApplanixEcefModel(const ossimApplanixEcefModel& src);
+   virtual ossimObject* dup()const;
+   
+   virtual void imagingRay(const ossimDpt& image_point,
+                           ossimEcefRay&   image_ray) const;
+
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const double&   heightEllipsoid,
+                                        ossimGpt&       worldPoint) const;
+   virtual void worldToLineSample(const ossimGpt& world_point,
+                                  ossimDpt&       image_point) const;
+   
+   virtual void updateModel();
+
+   void setPrincipalPoint(ossimDpt principalPoint);
+
+
+   void setRollPitchHeading(double roll,
+                            double pitch,
+                            double heading);
+   
+   void setPixelSize(const ossimDpt& pixelSize);
+   void setImageRect(const ossimDrect& rect);
+   void setFocalLength(double focalLength);
+   void setPlatformPosition(const ossimGpt& gpt);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   virtual void initAdjustableParameters();
+   
+protected:
+   NEWMAT::Matrix theCompositeMatrix;
+   NEWMAT::Matrix theCompositeMatrixInverse;
+   double         theRoll;
+   double         thePitch;
+   double         theHeading;
+   ossimDpt       thePrincipalPoint;
+   ossimDpt       thePixelSize;
+   double         theFocalLength;
+   ossimEcefPoint theEcefPlatformPosition;
+   ossimRefPtr<ossimMeanRadialLensDistortion> theLensDistortion;
+
+
+   ossimEcefPoint theAdjEcefPlatformPosition;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixUtmModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixUtmModel.cpp
new file mode 100644
index 0000000000..5e72f3b339
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixUtmModel.cpp
@@ -0,0 +1,802 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LGPL
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimApplanixUtmModel.cpp,v 1.3 2005/09/20 13:16:13 gpotts Exp $
+#include <sstream>
+#include "ossimApplanixUtmModel.h"
+#include <base/data_types/ellipse/ossimEllipsoid.h>
+#include <base/misc/ossimUnitConversionTool.h>
+#include <base/misc/lookup_tables/ossimUnitTypeLut.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/data_types/ossimLsrSpace.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/geoid/ossimGeoidManager.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <support_data/fcsi/ossimApplanixEOFile.h>
+#include <base/data_types/ossimMatrix4x4.h>
+static ossimTrace traceDebug("ossimApplanixUtmModel:debug");
+
+RTTI_DEF1(ossimApplanixUtmModel, "ossimApplanixUtmModel", ossimSensorModel);
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimApplanixUtmModel.cpp,v 1.3 2005/09/20 13:16:13 gpotts Exp $";
+#endif
+
+ossimApplanixUtmModel::ossimApplanixUtmModel()
+   :theOmega(0.0),
+    thePhi(0.0),
+    theKappa(0.0),
+    theBoreSightTx(0.0),
+    theBoreSightTy(0.0),
+    theBoreSightTz(0.0)
+{
+   theCompositeMatrix          = ossimMatrix4x4::createIdentity();
+   theCompositeMatrixInverse   = ossimMatrix4x4::createIdentity();
+   theFocalLength              = 55.0;
+   thePixelSize = ossimDpt(.009, .009);
+   theEcefPlatformPosition = ossimGpt(0.0,0.0, 1000.0);
+   theGSD.x = 0.1524;
+   theGSD.y = 0.1524;
+   theMeanGSD = 0.1524;
+   theLensDistortion = new ossimMeanRadialLensDistortion;
+   initAdjustableParameters();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimApplanixUtmModel::ossimApplanixUtmModel DEBUG:" << endl;
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)<< "OSSIM_ID:  " << OSSIM_ID << endl;
+#endif
+   }
+}
+
+ossimApplanixUtmModel::ossimApplanixUtmModel(const ossimApplanixUtmModel& src)
+   :ossimSensorModel(src),
+    theCompositeMatrix(src.theCompositeMatrix),
+    theCompositeMatrixInverse(src.theCompositeMatrixInverse),
+    theOmega(src.theOmega),
+    thePhi(src.thePhi),
+    theKappa(src.theKappa),
+    theBoreSightTx(src.theBoreSightTx),
+    theBoreSightTy(src.theBoreSightTy),
+    theBoreSightTz(src.theBoreSightTz),
+    thePrincipalPoint(src.thePrincipalPoint),
+    thePixelSize(src.thePixelSize),
+    theFocalLength(src.theFocalLength),
+    theEcefPlatformPosition(src.theEcefPlatformPosition),
+    thePlatformPosition(src.thePlatformPosition),
+    theUtmZone(src.theUtmZone),
+    theUtmHemisphere(src.theUtmHemisphere),
+    theUtmPlatformPosition(src.theUtmPlatformPosition)
+{
+   if(src.theLensDistortion.valid())
+   {
+      theLensDistortion = new ossimMeanRadialLensDistortion(*(src.theLensDistortion.get()));
+   }
+   else
+   {
+      theLensDistortion = new ossimMeanRadialLensDistortion();
+   }
+}
+
+ossimObject* ossimApplanixUtmModel::dup()const
+{
+   return new ossimApplanixUtmModel(*this);
+}
+
+void ossimApplanixUtmModel::imagingRay(const ossimDpt& image_point,
+                                    ossimEcefRay&   image_ray) const
+{
+//    if(traceDebug())
+//    {
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "ossimApplanixUtmModel::imagingRay: ..... entered" << std::endl;
+//    }
+    ossimDpt f1 ((image_point) - theRefImgPt);
+   f1.x *= thePixelSize.x;
+   f1.y *= -thePixelSize.y;
+   ossimDpt film (f1 - thePrincipalPoint);
+//    if(traceDebug())
+//    {
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "pixel size   = " << thePixelSize << std::endl;
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "principal pt = " << thePrincipalPoint << std::endl;
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "film pt      = " << film << std::endl;
+//    }
+   if (theLensDistortion.valid())
+   {
+      ossimDpt filmOut;
+      theLensDistortion->undistort(film, filmOut);
+      film = filmOut;
+   }
+   
+   ossimColumnVector3d cam_ray_dir (film.x,
+                                    film.y,
+                                    -theFocalLength);
+   ossimEcefVector     ecf_ray_dir (theCompositeMatrix*cam_ray_dir);
+   ecf_ray_dir = ecf_ray_dir*(1.0/ecf_ray_dir.magnitude());
+   
+   image_ray.setOrigin(theAdjEcefPlatformPosition);
+   image_ray.setDirection(ecf_ray_dir);
+   
+//    if(traceDebug())
+//    {
+//       ossimNotify(ossimNotifyLevel_DEBUG) << "ossimApplanixUtmModel::imagingRay: ..... leaving" << std::endl;
+//    }
+}
+
+void ossimApplanixUtmModel::lineSampleHeightToWorld(const ossimDpt& image_point,
+                                                 const double&   heightEllipsoid,
+                                                 ossimGpt&       worldPoint) const
+{
+   if (!insideImage(image_point))
+   {
+      worldPoint = extrapolate(image_point, heightEllipsoid);
+   }
+   else
+   {
+      //***
+      // First establish imaging ray from image point:
+      //***
+      ossimEcefRay ray;
+      imagingRay(image_point, ray);
+      ossimEcefPoint Pecf (ray.intersectAboveEarthEllipsoid(heightEllipsoid));
+      worldPoint = ossimGpt(Pecf);
+   }
+}
+
+void ossimApplanixUtmModel::worldToLineSample(const ossimGpt& world_point,
+                                           ossimDpt&       image_point) const
+{
+   if((theBoundGndPolygon.getNumberOfVertices() > 0)&&
+      (!theBoundGndPolygon.hasNans()))
+   {
+      if (!(theBoundGndPolygon.pointWithin(world_point)))
+      {
+         image_point = extrapolate(world_point);
+         return;
+      }         
+   }
+   ossimEcefPoint g_ecf(world_point);
+   ossimEcefVector ecfRayDir(g_ecf - theAdjEcefPlatformPosition);
+   ossimColumnVector3d camRayDir (theCompositeMatrixInverse*ecfRayDir.data());
+   
+      
+   double scale = -theFocalLength/camRayDir[2];
+   ossimDpt film (scale*camRayDir[0], scale*camRayDir[1]);
+      
+   if (theLensDistortion.valid())
+   {
+      ossimDpt filmOut;
+      theLensDistortion->distort(film, filmOut);
+      film = filmOut;
+    }
+   
+     ossimDpt f1(film + thePrincipalPoint);
+    ossimDpt p1(f1.x/thePixelSize.x,
+                -f1.y/thePixelSize.y);
+
+    ossimDpt p0 (p1.x + theRefImgPt.x,
+                 p1.y + theRefImgPt.y);
+    
+    image_point = p0;
+}
+
+void ossimApplanixUtmModel::updateModel()
+{
+
+   ossimGpt wgs84Pt;
+   double metersPerDegree = wgs84Pt.metersPerDegree().x;
+   double degreePerMeter = 1.0/metersPerDegree;
+   double latShift = -computeParameterOffset(1)*theMeanGSD*degreePerMeter;
+   double lonShift = computeParameterOffset(0)*theMeanGSD*degreePerMeter;
+
+   ossimGpt gpt = thePlatformPosition;
+//   gpt.height(0.0);
+   double height = gpt.height();
+   gpt.height(height + computeParameterOffset(5));
+   gpt.latd(gpt.latd() + latShift);
+   gpt.lond(gpt.lond() + lonShift);
+   
+   theAdjEcefPlatformPosition = gpt;
+   ossimLsrSpace lsrSpace(theAdjEcefPlatformPosition);
+   // ORIENT TO A UTM AXIS
+   //
+    NEWMAT::ColumnVector v(3);
+   
+    v[0] = 0.0;
+    v[1] = 0.0;
+    v[2] = 1.0;
+    NEWMAT::ColumnVector v2 = lsrSpace.lsrToEcefRotMatrix()*v;
+    ossimEcefVector zVector(v2[0], v2[1], v2[2]);
+    zVector.normalize();
+   
+   // now lets create a UTM axis by creating a derivative at the center
+   // by shift over a few pixels and subtracting
+   //
+   ossimUtmProjection utmProj;
+   
+   utmProj.setZone(theUtmZone);
+   utmProj.setMetersPerPixel(ossimDpt(1.0,1.0));
+   ossimDpt midPt  = utmProj.forward(theAdjEcefPlatformPosition);
+   ossimDpt rPt    = midPt + ossimDpt(10, 0.0);
+   ossimDpt uPt    = midPt + ossimDpt(0.0, 10.0);
+   ossimGpt wMidPt = utmProj.inverse(midPt);
+   ossimGpt wRPt   = utmProj.inverse(rPt);
+   ossimGpt wUPt   = utmProj.inverse(uPt);
+   
+   ossimEcefPoint ecefMidPt = wMidPt;
+   ossimEcefPoint ecefRPt   = wRPt;
+   ossimEcefPoint ecefUPt   = wUPt;
+   
+   ossimEcefVector east  = ecefRPt-ecefMidPt;
+   ossimEcefVector north = ecefUPt-ecefMidPt;
+   east.normalize();
+   north.normalize();
+   
+   // now use the lsr space constructors to construct an orthogonal set of axes
+   //
+   lsrSpace = ossimLsrSpace(thePlatformPosition,
+                            0,
+                            north,
+                            east.cross(north));
+//   lsrSpace = ossimLsrSpace(thePlatformPosition);
+   // DONE ORIENT TO UTM AXIS
+   
+   NEWMAT::Matrix platformLsrMatrix = lsrSpace.lsrToEcefRotMatrix();
+   NEWMAT::Matrix orientationMatrix = (ossimMatrix3x3::createRotationXMatrix(theOmega+computeParameterOffset(2), OSSIM_LEFT_HANDED)*
+                                       ossimMatrix3x3::createRotationYMatrix(thePhi+computeParameterOffset(3), OSSIM_LEFT_HANDED)*
+                                       ossimMatrix3x3::createRotationZMatrix(theKappa+computeParameterOffset(4), OSSIM_LEFT_HANDED));
+   
+   theCompositeMatrix         = platformLsrMatrix*orientationMatrix;
+   theCompositeMatrixInverse  = theCompositeMatrix.i();
+
+//   theAdjEcefPlatformPosition = theEcefPlatformPosition; 
+
+   theBoundGndPolygon.resize(4);
+   ossim_float64 w = theImageClipRect.width()*.1;
+   ossim_float64 h = theImageClipRect.height()*.1;
+   
+   lineSampleToWorld(theImageClipRect.ul()+ossimDpt(-w, -h), gpt);
+   theBoundGndPolygon[0] = gpt;
+   lineSampleToWorld(theImageClipRect.ur()+ossimDpt(w, -h), gpt);
+   theBoundGndPolygon[1] = gpt;
+   lineSampleToWorld(theImageClipRect.lr()+ossimDpt(w, h), gpt);
+   theBoundGndPolygon[2] = gpt;
+   lineSampleToWorld(theImageClipRect.ll()+ossimDpt(-w, h), gpt);
+   theBoundGndPolygon[3] = gpt;
+}
+
+void ossimApplanixUtmModel::initAdjustableParameters()
+{
+   resizeAdjustableParameterArray(6);
+   
+   setAdjustableParameter(0, 0.0);
+   setParameterDescription(0, "x_offset");
+   setParameterUnit(0, "pixels");
+
+   setAdjustableParameter(1, 0.0);
+   setParameterDescription(1, "y_offset");
+   setParameterUnit(1, "pixels");
+
+   setAdjustableParameter(2, 0.0);
+   setParameterDescription(2, "orientation x");
+   setParameterUnit(2, "degrees");
+
+   setAdjustableParameter(3, 0.0);
+   setParameterDescription(3, "orientation y");
+   setParameterUnit(3, "degrees");
+
+   setAdjustableParameter(4, 0.0);
+   setParameterDescription(4, "orientation z");
+   setParameterUnit(4, "degrees");
+
+   setAdjustableParameter(5, 0.0);
+   setParameterDescription(5, "Altitude delta");
+   setParameterUnit(5, "meters");
+
+   
+   
+   setParameterSigma(0, 100.0);
+   setParameterSigma(1, 100.0);
+   setParameterSigma(2, 1);
+   setParameterSigma(3, 1);
+   setParameterSigma(4, 1);
+   setParameterSigma(5, 50);
+}
+
+void ossimApplanixUtmModel::setPrincipalPoint(ossimDpt principalPoint)
+{
+   thePrincipalPoint = principalPoint;
+}
+
+void ossimApplanixUtmModel::setPixelSize(const ossimDpt& pixelSize)
+{
+   thePixelSize = pixelSize;
+}
+
+void ossimApplanixUtmModel::setImageRect(const ossimDrect& rect)
+{
+   theImageClipRect = rect;
+   theRefImgPt = rect.midPoint();
+}
+
+void ossimApplanixUtmModel::setFocalLength(double focalLength)
+{
+   theFocalLength = focalLength;
+}
+
+void ossimApplanixUtmModel::setPlatformPosition(const ossimGpt& gpt)
+{
+   theRefGndPt             = gpt;
+   theEcefPlatformPosition = gpt;
+   updateModel();
+   
+}
+
+bool ossimApplanixUtmModel::saveState(ossimKeywordlist& kwl,
+                                   const char* prefix) const
+{
+   ossimSensorModel::saveState(kwl, prefix);
+   
+   kwl.add(prefix, "type", "ossimApplanixUtmModel", true);
+
+   kwl.add(prefix, "omega", theOmega, true);
+   kwl.add(prefix, "phi", thePhi, true);
+   kwl.add(prefix, "kappa", theKappa, true);
+   kwl.add(prefix, "bore_sight_tx", theBoreSightTx*60, true);
+   kwl.add(prefix, "bore_sight_ty", theBoreSightTy*60, true);
+   kwl.add(prefix, "bore_sight_tz", theBoreSightTz*60, true);
+   kwl.add(prefix, "principal_point", ossimString::toString(thePrincipalPoint.x) + " " + ossimString::toString(thePrincipalPoint.y));
+   kwl.add(prefix, "pixel_size",      ossimString::toString(thePixelSize.x) + " " + ossimString::toString(thePixelSize.y));
+   kwl.add(prefix, "focal_length", theFocalLength);
+   kwl.add(prefix, "ecef_platform_position",
+           ossimString::toString(theEcefPlatformPosition.x()) + " " +
+           ossimString::toString(theEcefPlatformPosition.y()) + " " +
+           ossimString::toString(theEcefPlatformPosition.z()));
+   kwl.add(prefix, "latlonh_platform_position",
+           ossimString::toString(thePlatformPosition.latd()) + " " +
+           ossimString::toString(thePlatformPosition.lond()) + " " +
+           ossimString::toString(thePlatformPosition.height()) + " " +
+           thePlatformPosition.datum()->code());
+   kwl.add(prefix,
+           "utm_platform_position",
+           ossimString::toString(theUtmPlatformPosition.x) + " " +
+           ossimString::toString(theUtmPlatformPosition.y) + " " +
+           ossimString::toString(theUtmPlatformPosition.z) + " " +
+           thePlatformPosition.datum()->code(),
+           true);
+   kwl.add(prefix,
+           "utm_zone",
+           theUtmZone,
+           true);
+   kwl.add(prefix,
+           "utm_hemisphere",
+           theUtmHemisphere,
+           true);
+   kwl.add(prefix,
+           "shift_values",
+           ossimString::toString(theShiftValues.x()) + " " + 
+           ossimString::toString(theShiftValues.y()) + " " +
+           ossimString::toString(theShiftValues.z()),
+           true);
+   if(theLensDistortion.valid())
+   {
+      ossimString lensPrefix = ossimString(prefix)+"distortion.";
+      theLensDistortion->saveState(kwl,
+                                   lensPrefix.c_str());
+   }
+   
+   return true;
+}
+
+bool ossimApplanixUtmModel::loadState(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+{
+   if(traceDebug())
+   {
+      std::cout << "ossimApplanixUtmModel::loadState: ......... entered" << std::endl;
+   }
+   theImageClipRect = ossimDrect(0,0,4076,4091);
+   theRefImgPt      = ossimDpt(2046.0, 2038.5);
+   
+   ossimSensorModel::loadState(kwl, prefix);
+
+   const char* eo_file           = kwl.find(prefix, "eo_file");
+   const char* eo_id             = kwl.find(prefix, "eo_id");
+   const char* omega             = kwl.find(prefix, "omega");
+   const char* phi               = kwl.find(prefix, "phi");
+   const char* kappa             = kwl.find(prefix, "kappa");
+   const char* bore_sight_tx     = kwl.find(prefix, "bore_sight_tx");
+   const char* bore_sight_ty     = kwl.find(prefix, "bore_sight_ty");
+   const char* bore_sight_tz     = kwl.find(prefix, "bore_sight_tz");
+   
+   const char* principal_point   = kwl.find(prefix, "principal_point");
+   const char* pixel_size        = kwl.find(prefix, "pixel_size");
+   const char* focal_length      = kwl.find(prefix, "focal_length");
+   const char* latlonh_platform_position = kwl.find(prefix, "latlonh_platform_position");
+   const char* utm_platform_position = kwl.find(prefix, "utm_platform_position");
+   const char* compute_gsd_flag  = kwl.find(prefix, "compute_gsd_flag");
+   const char* utm_zone          = kwl.find(prefix, "utm_zone");
+   const char* utm_hemisphere    = kwl.find(prefix, "utm_hemisphere");
+   const char* camera_file       = kwl.find(prefix, "camera_file");
+   const char* shift_values      = kwl.find(prefix, "shift_values");
+   
+   theCompositeMatrix          = ossimMatrix3x3::createIdentity();
+   theCompositeMatrixInverse   = ossimMatrix3x3::createIdentity();
+   theOmega                    = 0.0;
+   thePhi                      = 0.0;
+   theKappa                    = 0.0;
+   theBoreSightTx              = 0.0;
+   theBoreSightTy              = 0.0;
+   theBoreSightTz              = 0.0;
+   theFocalLength              = 55.0;
+   thePixelSize = ossimDpt(.009, .009);
+   theEcefPlatformPosition = ossimGpt(0.0,0.0, 1000.0);
+
+   bool loadedFromEoFile = false;
+
+   if(eo_id)
+   {
+      theImageID = eo_id;
+   }
+   // loading from standard eo file with given record id
+   //
+   if(eo_file)
+   {
+      ossimApplanixEOFile eoFile;
+      
+      if(eoFile.parseFile(ossimFilename(eo_file)))
+      {
+         ossimRefPtr<ossimApplanixEORecord> record = eoFile.getRecordGivenId(theImageID);
+
+         if(record.valid())
+         {
+            loadedFromEoFile = true;
+            theBoreSightTx = eoFile.getBoreSightTx()/60.0;
+            theBoreSightTy = eoFile.getBoreSightTy()/60.0;
+            theBoreSightTz = eoFile.getBoreSightTz()/60.0;
+            theShiftValues = ossimEcefVector(eoFile.getShiftValuesX(),
+                                             eoFile.getShiftValuesY(),
+                                             eoFile.getShiftValuesZ());
+            ossim_int32 easting  = eoFile.getFieldIdxLike("EASTING");
+            ossim_int32 northing = eoFile.getFieldIdxLike("NORTHING");
+            ossim_int32 height   = eoFile.getFieldIdxLike("HEIGHT");
+            ossim_int32 omega    = eoFile.getFieldIdxLike("OMEGA");
+            ossim_int32 phi      = eoFile.getFieldIdxLike("PHI");
+            ossim_int32 kappa    = eoFile.getFieldIdxLike("KAPPA");
+
+            if((omega>=0)&&
+               (phi>=0)&&
+               (kappa>=0)&&
+               (height>=0)&&
+               (easting>=0)&&
+               (northing>=0))
+            {
+               theOmega = (*record)[omega].toDouble();
+               thePhi   = (*record)[phi].toDouble();
+               theKappa = (*record)[kappa].toDouble();
+               double h = (*record)[height].toDouble();
+               ossimString heightType = kwl.find(prefix, "height_type");
+               if(eoFile.isUtmFrame())
+               {
+                  theUtmZone = eoFile.getUtmZone();
+                  theUtmHemisphere = eoFile.getUtmHemisphere()=="North"?'N':'S';
+                  ossimUtmProjection utmProj;
+                  utmProj.setZone(theUtmZone);
+                  utmProj.setHemisphere((char)theUtmHemisphere);
+                  theUtmPlatformPosition.x = (*record)[easting].toDouble();
+                  theUtmPlatformPosition.y = (*record)[northing].toDouble();
+                  theUtmPlatformPosition.z = h;
+                  thePlatformPosition = utmProj.inverse(ossimDpt(theUtmPlatformPosition.x,
+                                                                 theUtmPlatformPosition.y));
+                  thePlatformPosition.height(h);
+
+                  double offset = ossimGeoidManager::instance()->offsetFromEllipsoid(thePlatformPosition);
+                  if(offset != OSSIM_DBL_NAN)
+                  {
+                     thePlatformPosition.height(h + offset);
+                     theUtmPlatformPosition.z = h + offset;
+                  }
+               }
+               else
+               {
+                  return false;
+               }
+            }
+            theEcefPlatformPosition = thePlatformPosition;
+         }
+         else
+         {
+            return false;
+         }
+      }
+   }
+   if(!loadedFromEoFile)
+   {
+      if(shift_values)
+      {
+         std::istringstream in(shift_values);
+         double x, y, z;
+
+         in >> x >> y >> z;
+
+         theShiftValues = ossimEcefVector(x,y,z);
+         
+      }
+      if(omega&&phi&&kappa)
+      {
+         theOmega = ossimString(omega).toDouble();
+         thePhi   = ossimString(phi).toDouble();
+         theKappa = ossimString(kappa).toDouble();
+      }
+      if(bore_sight_tx&&bore_sight_ty&&bore_sight_tz)
+      {
+         theBoreSightTx = ossimString(bore_sight_tx).toDouble()/60.0;
+         theBoreSightTy = ossimString(bore_sight_ty).toDouble()/60.0;
+         theBoreSightTz = ossimString(bore_sight_tz).toDouble()/60.0;
+      }
+      double lat, lon, h;
+      if(utm_zone)
+      {
+         theUtmZone = ossimString(utm_zone).toInt32();
+      }
+      if(utm_hemisphere)
+      {
+         ossimString hem = utm_hemisphere;
+         hem = hem.trim();
+         hem = hem.upcase();
+         theUtmHemisphere = *(hem.begin());
+      }
+      if(utm_platform_position)
+      {
+         ossimUtmProjection utmProj;
+         istringstream in(utm_platform_position);
+         ossimString datumString;
+         utmProj.setZone(theUtmZone);
+         utmProj.setHemisphere((char)theUtmHemisphere);
+         in >> theUtmPlatformPosition.x >> theUtmPlatformPosition.y >> theUtmPlatformPosition.z >> datumString;
+         const ossimDatum* datum = ossimDatumFactory::instance()->create(datumString);
+         if(datum)
+         {
+            utmProj.setDatum(datum);
+         }
+         
+         thePlatformPosition = utmProj.inverse(ossimDpt(theUtmPlatformPosition.x,
+                                                        theUtmPlatformPosition.y));
+         thePlatformPosition.height(theUtmPlatformPosition.z);
+         
+         ossimString heightType = kwl.find(prefix, "height_type");
+         if(heightType == "msl")
+         {
+            double offset = ossimGeoidManager::instance()->offsetFromEllipsoid(thePlatformPosition);
+            if(offset != OSSIM_DBL_NAN)
+            {
+               thePlatformPosition.height(thePlatformPosition.height() + offset);
+               theUtmPlatformPosition.z = thePlatformPosition.height();
+            }
+         }
+         theEcefPlatformPosition = thePlatformPosition;
+      }
+      else if(latlonh_platform_position)
+      {
+         std::istringstream in(latlonh_platform_position);
+         std::string datumCode;
+         in >> lat >> lon >> h >> datumCode;
+         thePlatformPosition.latd(lat);
+         thePlatformPosition.lond(lon);
+         thePlatformPosition.height(h);
+         const ossimDatum* datum = ossimDatumFactory::instance()->create(datumCode);
+         if(datum)
+         {
+            thePlatformPosition.datum(datum);
+         }
+         ossimString heightType = kwl.find(prefix, "height_type");
+         if(heightType == "msl")
+         {
+            double offset = ossimGeoidManager::instance()->offsetFromEllipsoid(thePlatformPosition);
+            if(offset != OSSIM_DBL_NAN)
+            {
+               thePlatformPosition.height(thePlatformPosition.height() + offset);
+            }
+         }
+         theEcefPlatformPosition = thePlatformPosition;
+      }
+   }
+   if(principal_point)
+   {
+      std::istringstream in(principal_point);
+      in >>thePrincipalPoint.x >> thePrincipalPoint.y;
+   }
+   if(pixel_size)
+   {
+      std::istringstream in(pixel_size);
+      in >> thePixelSize.x >> thePixelSize.y;
+   }
+   if(focal_length)
+   {
+      theFocalLength = ossimString(focal_length).toDouble();
+   }
+
+   if(camera_file)
+   {
+      ossimKeywordlist cameraKwl;
+      ossimKeywordlist lensKwl;
+      cameraKwl.add(camera_file);
+      const char* sensor = cameraKwl.find("sensor");
+      const char* image_size      = cameraKwl.find(prefix, "image_size");
+      principal_point = cameraKwl.find("principal_point");
+      focal_length    = cameraKwl.find("focal_length");
+      pixel_size      = cameraKwl.find(prefix, "pixel_size");
+      focal_length    = cameraKwl.find(prefix, "focal_length");
+      const char* distortion_units = cameraKwl.find(prefix, "distortion_units");
+      ossimUnitConversionTool tool;
+      ossimUnitType unitType = OSSIM_MILLIMETERS;
+
+      if(distortion_units)
+      {
+         unitType = (ossimUnitType)ossimUnitTypeLut().getEntryNumber(distortion_units);
+
+         if(unitType == OSSIM_UNIT_UNKNOWN)
+         {
+            unitType = OSSIM_MILLIMETERS;
+         }
+      }
+      if(image_size)
+      {
+         std::istringstream in(image_size);
+         double w, h;
+         in>>w >> h;
+         theImageClipRect = ossimDrect(0,0,w-1,h-1);
+         theRefImgPt      = ossimDpt(w/2.0, h/2.0);
+      }
+      if(sensor)
+      {
+         theSensorID = sensor;
+      }
+      if(principal_point)
+      {
+         std::istringstream in(principal_point);
+         in >>thePrincipalPoint.x >> thePrincipalPoint.y;
+      }
+      if(pixel_size)
+      {
+         std::istringstream in(pixel_size);
+         in >> thePixelSize.x;
+         thePixelSize.y = thePixelSize.x;
+      }
+      if(focal_length)
+      {
+         theFocalLength = ossimString(focal_length).toDouble();
+      }
+
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < 26; ++idx)
+      {
+         const char* value = cameraKwl.find(ossimString("d")+ossimString::toString(idx));
+
+         if(value)
+         {
+            std::istringstream in(value);
+            double distance, distortion;
+
+            in >> distance >> distortion;
+            tool.setValue(distortion, unitType);
+            lensKwl.add(ossimString("distance") + ossimString::toString(idx),
+                        distance,
+                        true);
+            lensKwl.add(ossimString("distortion") + ossimString::toString(idx),
+                        tool.getMillimeters(),
+                        true);
+         }
+         lensKwl.add("convergence_threshold",
+                     .00001,
+                     true);
+         if(pixel_size)
+         {
+            lensKwl.add("dxdy",
+                        ossimString(pixel_size) + " " + ossimString(pixel_size),
+                        true);
+         }
+         else
+         {
+            lensKwl.add("dxdy",
+                        ".009 .009",
+                        true);
+         }
+      }
+      if(theLensDistortion.valid())
+      {
+         theLensDistortion->loadState(lensKwl,"");
+      }
+   }
+   else
+   {
+      
+      if(principal_point)
+      {
+         std::istringstream in(principal_point);
+         in >>thePrincipalPoint.x >> thePrincipalPoint.y;
+      }
+      else
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "No principal_point found" << std::endl;
+            return false;
+         }
+      }
+      if(pixel_size)
+      {
+         std::istringstream in(pixel_size);
+         in >> thePixelSize.x >> thePixelSize.y;
+      }
+      else
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "No pixel size found" << std::endl;
+            return false;
+         }
+      }
+      if(focal_length)
+      {
+         theFocalLength = ossimString(focal_length).toDouble();
+      }
+      else
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "No focal length found" << std::endl;
+            return false;
+         }
+      }
+      
+      if(theLensDistortion.valid())
+      {
+         ossimString lensPrefix = ossimString(prefix)+"distortion.";
+         theLensDistortion->loadState(kwl,
+                                      lensPrefix.c_str());
+      }
+   }
+   theRefGndPt = thePlatformPosition;
+   
+   updateModel();
+
+   lineSampleToWorld(theRefImgPt, theRefGndPt);
+   if(compute_gsd_flag)
+   {
+      if(ossimString(compute_gsd_flag).toBool())
+      {
+         ossimGpt right;
+         ossimGpt top;
+         lineSampleToWorld(theRefImgPt + ossimDpt(1.0, 0.0),
+                           right);
+         lineSampleToWorld(theRefImgPt + ossimDpt(1.0, 0.0),
+                           top);
+
+         ossimEcefVector horizontal = ossimEcefPoint(theRefGndPt)-ossimEcefPoint(right);
+         ossimEcefVector vertical   = ossimEcefPoint(theRefGndPt)-ossimEcefPoint(top);
+
+         theGSD.x = horizontal.length();
+         theGSD.y = vertical.length();
+         theMeanGSD = (theGSD.x+theGSD.y)*.5;
+      }
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theOmega:              " << theOmega << std::endl
+                                          << "thePhi:                " << thePhi   << std::endl
+                                          << "theKappa:              " << theKappa << std::endl;
+      std::cout << "platform position:     " << thePlatformPosition << std::endl;
+      std::cout << "platform position ECF: " << theEcefPlatformPosition << std::endl;
+      std::cout << "ossimApplanixModel::loadState: ......... leaving" << std::endl;
+   }
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixUtmModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixUtmModel.h
new file mode 100644
index 0000000000..a772c5472d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimApplanixUtmModel.h
@@ -0,0 +1,73 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LGPL
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimApplanixUtmModel.h,v 1.1 2005/09/06 16:20:04 gpotts Exp $
+#ifndef ossimApplanixUtmModel_HEADER
+#define ossimApplanixUtmModel_HEADER
+#include "ossimFcsiModel.h"
+#include <projections/sensor_modeling/ossimMeanRadialLensDistortion.h>
+#include <base/data_types/ossimDpt3d.h>
+
+class OSSIM_DLL ossimApplanixUtmModel : public ossimSensorModel
+{
+public:
+   ossimApplanixUtmModel();
+   ossimApplanixUtmModel(const ossimApplanixUtmModel& src);
+   virtual ossimObject* dup()const;
+   
+   virtual void imagingRay(const ossimDpt& image_point,
+                           ossimEcefRay&   image_ray) const;
+
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const double&   heightEllipsoid,
+                                        ossimGpt&       worldPoint) const;
+   virtual void worldToLineSample(const ossimGpt& world_point,
+                                  ossimDpt&       image_point) const;
+   
+   virtual void updateModel();
+
+   void setPrincipalPoint(ossimDpt principalPoint);
+
+   void setPixelSize(const ossimDpt& pixelSize);
+   void setImageRect(const ossimDrect& rect);
+   void setFocalLength(double focalLength);
+   void setPlatformPosition(const ossimGpt& gpt);
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   virtual void initAdjustableParameters();
+   
+protected:
+   NEWMAT::Matrix theCompositeMatrix;
+   NEWMAT::Matrix theCompositeMatrixInverse;
+   double         theOmega;
+   double         thePhi;
+   double         theKappa;
+   double         theBoreSightTx;
+   double         theBoreSightTy;
+   double         theBoreSightTz;
+   ossimDpt       thePrincipalPoint;
+   ossimDpt       thePixelSize;
+   double         theFocalLength;
+   ossimEcefPoint theEcefPlatformPosition;
+   ossimGpt       thePlatformPosition;
+   ossim_int32    theUtmZone;
+   ossim_int8     theUtmHemisphere;
+   ossimDpt3d     theUtmPlatformPosition;
+   ossimEcefVector theShiftValues;
+   
+   ossimRefPtr<ossimMeanRadialLensDistortion> theLensDistortion;
+   ossimEcefPoint theAdjEcefPlatformPosition;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimFcsiModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimFcsiModel.cpp
new file mode 100644
index 0000000000..0636ae1686
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimFcsiModel.cpp
@@ -0,0 +1,1064 @@
+//*****************************************************************************
+// FILE: ossimFcsiModel.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// LGPL
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains sensor model implementation for "Frame Camera Scanned
+//   Image" (FCSI, pronounced "foxy"). 
+//   
+//   This model represents image data that was scanned from film exposed by a
+//   conventional aerial frame camera. The data members defined in this class
+//   represent the fundamental quantities needed for the transformation.
+//   Typically, a different set of parameters will be provided in the metadata.
+//   An interface (support data) class will need to be implemented to convert
+//   a particular system's format to the quantities needed by this model.
+// 
+//   Coordinate systems in use are described here:
+//
+//   Pixel    -- line/sample in the digital image. The origin of this system is
+//               the upper left corner of the image, and represents a LEFT-
+//               HANDED coordinate system with Y (line) positive down and X
+//               (sample) positive to the right.
+//
+//   Film     -- x, y related to pixel space by affine transform (which includes
+//               mirror reflection due to left-handed system above) represented
+//               by thePrincipalPoint and the theScanXformMatrix. The latter
+//               contains scale, skew, and rotation/reflection. The film
+//               coordinates are adjusted for radial and decentering distortion.
+//
+//   Camera/  -- 3D system containing film plane and optical (Z) axis. Given the
+//   Platform    focal length (Z) and the film point (X,Y), a 3D ray direction
+//               is established in this space. This space is also termed "LSR"
+//               in the code. If there is a rotation between the film/optical
+//               axes and the platform (interior orientation), then that
+//               transformation must be included as part of the LSR-to-ECF
+//               rotation by the metadata reader object.
+//
+//   ECF      -- Universal earth frame of reference. The imaging ray direction
+//               is transformed from Camera space to ECF by theAdjLsrToEcfRot.
+//
+//   There are two rotations to go from Camera to ECF. First is the initial
+//   camera orientation as derived from the metadata, combining the interior
+//   orientation (relation between camera and platform) and the exterior
+//   orientation dependent on the platform attitude w.r.t. the ECF system.
+//   The second rotation is a differential rotation due to the attitude
+//   adjustable params. These are arbitrarily taken as rotations about the ECF
+//   XYZ axes, not the platform attitude axes of roll/pitch/yaw. The
+//   combined rotation is stored in theAdjLsrToEcfRot, which is precomputed
+//   in updateModel() once with each adjustment.
+//
+//   When the time comes to incorporate least-squares parameter adjustment, care
+//   must be taken to propagate the a priori sigmas for position and attitude
+//   (including both internal and external orientation angles) into the ECF
+//   coordinates. This also applies to the affine transform parameters used in
+//   transforming pixels to film coordinates. The propagated uncertainties can
+//   then be used to assign the adjustable parameter sigmas array (and
+//   covariance when we get to that...)
+//
+// SOFTWARE HISTORY:
+//   16JAN2003  Oscar Kramer, ImageLinks
+//              Initial coding
+//
+//*****************************************************************************
+// $Id: ossimFcsiModel.cpp,v 1.15 2005/05/12 14:52:52 gpotts Exp $
+
+#include <projections/sensor_modeling/fcsi/ossimFcsiModel.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimFcsiModel, "ossimFcsiModel", ossimSensorModel);
+
+#include <fstream>
+#include <sstream>
+
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimEcefRay.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimFcsiModel:exec");
+static ossimTrace traceDebug ("ossimFcsiModel:debug");
+
+//***
+// File-scope constants:
+//***
+static const int MODEL_VERSION_NUMBER  = 1;
+static const ossimString PARAM_NAMES[] ={"x_pos_offset",
+                                         "y_pos_offset",
+                                         "z_pos_offset",
+                                         "x_rot_corr",
+                                         "y_rot_corr",
+                                         "z_rot_corr",
+                                         "foc_len_offset",
+                                         "scan_skew_corr"};
+static const ossimString PARAM_UNITS[] ={"meters",
+                                         "meters",
+                                         "meters",
+                                         "degrees",
+                                         "degress",
+                                         "degress",
+                                         "millimeters",
+                                         "degrees"};
+
+//***
+// Public FCSI Keywords:
+//***
+const char* ossimFcsiModel::PRINCIPAL_POINT_X_KW   = "principal_point_x";
+const char* ossimFcsiModel::PRINCIPAL_POINT_Y_KW   = "principal_point_y";
+const char* ossimFcsiModel::SCAN_SCALE_MATRIX_00_KW = "scan_scale_matrix_00";
+const char* ossimFcsiModel::SCAN_SCALE_MATRIX_01_KW = "scan_scale_matrix_01";
+const char* ossimFcsiModel::SCAN_SCALE_MATRIX_10_KW = "scan_scale_matrix_10";
+const char* ossimFcsiModel::SCAN_SCALE_MATRIX_11_KW = "scan_scale_matrix_11";
+const char* ossimFcsiModel::SCAN_ROTATION_ANGLE_KW = "scan_rotation_angle";
+const char* ossimFcsiModel::SCAN_SKEW_ANGLE_KW     = "scan_skew_angle";
+const char* ossimFcsiModel::FOCAL_LENGTH_KW        = "focal_length";
+const char* ossimFcsiModel::PLATFORM_POSITION_X_KW = "platform_position_x";
+const char* ossimFcsiModel::PLATFORM_POSITION_Y_KW = "platform_position_y";
+const char* ossimFcsiModel::PLATFORM_POSITION_Z_KW = "platform_position_z";
+const char* ossimFcsiModel::CAMERA_ORIENTATION_MATRIX_ELEM_KW
+                               = "camera_orientation_matrix_elem_";
+
+//*****************************************************************************
+//  DEFAULT CONSTRUCTOR: ossimFcsiModel()
+//
+//  Note: Using this constructor results in an uninitialized model. It is
+//  expected that either a loadState with valid keywordlist is called, or that
+//  the individual set-methods (including the base-class' set methods are
+//  called. When set-methods are used, a final call to completeInitialization()
+//  (declared in ossimSensorModel) is required to give the model a chance to
+//  "digest" the values previously set.
+//  
+//*****************************************************************************
+ossimFcsiModel::ossimFcsiModel()
+   :
+   ossimSensorModel       (),
+   thePrincipalPoint      (0, 0),
+   theScanSkew            (0.0),  
+   theScanRotation        (0.0),
+   theOpticalDistortion   (0),
+   theLsrToEcfRot         (3, 3),
+   theEcfOffset           (0, 0, 0),
+   theXrotCorr            (0.0),
+   theYrotCorr            (0.0),
+   theZrotCorr            (0.0),
+   theFocalOffset         (0.0),
+   theScanSkewCorr        (0.0),
+   theAdjLsrToEcfRot      (3, 3),
+   theAdjEcfToLsrRot      (3, 3)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: entering..." << std::endl;
+   theScanScaleMatrix[0] = 1.0;
+   theScanScaleMatrix[1] = 0.0;
+   theScanScaleMatrix[2] = 0.0;
+   theScanScaleMatrix[3] = 1.0;
+   theScanXformMatrix[0] = 1.0;
+   theScanXformMatrix[1] = 0.0;
+   theScanXformMatrix[2] = 0.0;
+   theScanXformMatrix[3] = 1.0;
+   initAdjustableParameters();
+   setErrorStatus(); // indicate uninitialized
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimFcsiModel(filename)
+//  
+//  Constructs model from a keywordlist filename
+//  
+//*****************************************************************************
+ossimFcsiModel::ossimFcsiModel(const ossimFilename& init_file)
+   :
+   ossimSensorModel       (),
+   thePrincipalPoint      (0, 0),
+   theScanSkew            (0.0),  
+   theScanRotation        (0.0),
+   theOpticalDistortion   (0),
+   theLsrToEcfRot         (3, 3),
+   theEcfOffset           (0, 0, 0),
+   theXrotCorr            (0.0),
+   theYrotCorr            (0.0),
+   theZrotCorr            (0.0),
+   theFocalOffset         (0.0),
+   theScanSkewCorr        (0.0),
+   theAdjLsrToEcfRot      (3, 3),
+   theAdjEcfToLsrRot      (3, 3)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: entering..." << std::endl;
+
+   initAdjustableParameters();
+   ossimKeywordlist kwl (init_file);
+   loadState(kwl);
+
+   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: Exited..." << std::endl;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimFcsiModel(kwl)
+//  
+//  Constructs model from keywordlist geometry file
+//  
+//*****************************************************************************
+ossimFcsiModel::ossimFcsiModel(const ossimKeywordlist& geom_kwl)
+   :
+   ossimSensorModel       (),
+   thePrincipalPoint      (0, 0),
+   theScanSkew            (0.0),  
+   theScanRotation        (0.0),
+   theOpticalDistortion   (0),
+   theLsrToEcfRot         (3, 3),
+   theEcfOffset           (0, 0, 0),
+   theXrotCorr            (0.0),
+   theYrotCorr            (0.0),
+   theZrotCorr            (0.0),
+   theFocalOffset         (0.0),
+   theScanSkewCorr        (0.0),
+   theAdjLsrToEcfRot      (3, 3),
+   theAdjEcfToLsrRot      (3, 3)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: entering..." << std::endl;
+
+   initAdjustableParameters();
+   loadState(geom_kwl);
+
+   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: Exited..." << std::endl;
+}
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: 
+//*****************************************************************************
+ossimFcsiModel::ossimFcsiModel(const ossimFcsiModel& foxy)
+   :
+   ossimSensorModel     (foxy),
+   thePrincipalPoint    (foxy.thePrincipalPoint),
+   theScanSkew          (foxy.theScanSkew),  
+   theScanRotation      (foxy.theScanRotation),
+   theFocalLen          (foxy.theFocalLen),
+   thePlatformPos       (foxy.thePlatformPos),
+   theLsrToEcfRot       (foxy.theLsrToEcfRot),
+   theEcfOffset         (foxy.theEcfOffset),
+   theXrotCorr          (foxy.theXrotCorr),
+   theYrotCorr          (foxy.theYrotCorr),
+   theZrotCorr          (foxy.theZrotCorr),
+   theFocalOffset       (foxy.theFocalOffset),
+   theScanSkewCorr      (foxy.theScanSkewCorr)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: entering..." << std::endl;
+
+   if(foxy.theOpticalDistortion)
+   {
+      //
+      // Finish the copy:
+      //
+      theOpticalDistortion =
+         new ossimRadialDecentLensDistortion (*(foxy.theOpticalDistortion));
+   }
+
+   for (int i=0; i<4; i++)
+      theScanScaleMatrix[i] = foxy.theScanScaleMatrix[i];
+
+   //***
+   // Compute quantities derived from adjustables:
+   //***
+   updateModel();
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimFcsiModel::lineSampleHeightToWorld()
+//  
+//  Performs the line/sample to groundpoint projection given an elevation.
+//
+//  1. Compute ECF Imaging ray (see imagingRay() method below)
+//  5. Intersect imaging ray with elevation surface.
+//
+//*****************************************************************************
+void ossimFcsiModel::lineSampleHeightToWorld(const ossimDpt& image_point,
+                                             const double&   height,
+                                             ossimGpt&       gpt) const
+{
+   bool debug = false;  // setable via interactive debugger
+   if (traceExec() || debug)  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: entering..." << std::endl;
+   
+   //***
+   // Extrapolate if point is outside image:
+   //***
+   if (!insideImage(image_point))
+   {
+      gpt = extrapolate(image_point, height);
+   }
+
+   else
+   {
+      //***
+      // First establish imaging ray from image point:
+      //***
+      ossimEcefRay imaging_ray;
+      imagingRay(image_point, imaging_ray);
+      ossimEcefPoint Pecf (imaging_ray.intersectAboveEarthEllipsoid(height));
+      gpt = ossimGpt(Pecf);
+
+      if (traceDebug() || debug)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "Pecf = " << Pecf << std::endl;
+         ossimNotify(ossimNotifyLevel_DEBUG) << "gpt = " << gpt << std::endl;
+      }
+   }
+
+   if (traceExec() || debug)  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::ossimFcsiModel: returning..." << std::endl;
+}
+   
+   
+//*****************************************************************************
+//  METHOD: ossimFcsiModel::imagingRay()
+//
+//  Establishes an origin (at the platform position) and direction of the
+//  imaging ray as follows:
+//
+//  1. Remove any pixel offset into the image (in the case where the digital
+//     image is a sub-image of a larger scan).
+//  2. Transform pixel coordinates to film point (with inherent lens distortion)
+//  3. Remove radial and decentering lens distortion to arrive at ideal film
+//     coordinates.
+//  4. Establish an internal imaging ray direction vector given the focal length
+//  5. Transform ray direction vector to ECF coordinates and assign origin.
+//
+//*****************************************************************************
+void ossimFcsiModel::imagingRay(const ossimDpt& image_point,
+                                ossimEcefRay&   image_ray) const
+{
+   bool debug = false;  // setable via interactive debugger: "set debug = true"
+   if (traceExec() || debug)  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::imagingRay: entering..." << std::endl;
+   
+   //***
+   // In case this is a sub-image of a full image scan, need to add the
+   // sub-image offset maintained in the base-class:
+   //***
+   ossimDpt p0 (image_point + theSubImageOffset);
+
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "image_point = " << image_point << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theSubImageOffset = " << theSubImageOffset << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "p0 = " << p0 << std::endl;
+   }
+   
+   //***
+   // Apply pixel to film coordinates affine transform:
+   //***
+   ossimDpt p1 (p0 - theRefImgPt);
+   ossimDpt f1 (theScanXformMatrix[0]*p1.x + theScanXformMatrix[1]*p1.y,
+                theScanXformMatrix[2]*p1.x + theScanXformMatrix[3]*p1.y);
+   ossimDpt film (f1 - thePrincipalPoint);
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theRefImgPt = " << theRefImgPt << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "p1 = " << p1 << std::endl;
+      for (int i=0; i<4; i++)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "theScanXformMatrix["<<i<<"] = "<<theScanXformMatrix[i] << std::endl;
+      }
+      ossimNotify(ossimNotifyLevel_DEBUG) << "f1 = " << f1 << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "thePrincipalPoint = " << thePrincipalPoint << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "film (distorted) = " << film << std::endl;
+   }
+
+   //***
+   // Correct film point for optical (radial, decentering) distortion:
+   //***
+   if (theOpticalDistortion)
+      theOpticalDistortion->inverse(film);
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "film (undistorted) = " << film << std::endl;
+      if(theOpticalDistortion)
+      {
+         theOpticalDistortion->print(ossimNotify(ossimNotifyLevel_DEBUG));
+      }
+   }
+   
+   //***
+   // Establish image ray in  camera-space (LSR) coordinates, then rotate to the
+   // ECF. This rotation contains interior orientation, exterior orientation,
+   // and attitude correction:
+   //***
+   ossimColumnVector3d cam_ray_dir (film.x, film.y, -theAdjFocalLen);
+   ossimEcefVector ecf_ray_dir (theAdjLsrToEcfRot*cam_ray_dir);
+   ecf_ray_dir = ecf_ray_dir*(1.0/ecf_ray_dir.magnitude());
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theAdjFocalLen = " << theAdjFocalLen << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "cam_ray_dir = " << cam_ray_dir << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theAdjLsrToEcfRot = \n" << theAdjLsrToEcfRot << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ecf_ray_dir = " << ecf_ray_dir << std::endl;
+   }
+   
+   //***
+   // Establish ECF Ray object to represent imaging ray:
+   //***
+   image_ray.setOrigin(theAdjPlatformPos);
+   image_ray.setDirection(ecf_ray_dir);
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theAdjPlatformPos = " << theAdjPlatformPos << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theAdjPlatformPos (ossimGpt): " << ossimGpt(theAdjPlatformPos)
+                                          << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "image_ray = " << image_ray << std::endl;
+   }
+
+   if (traceExec() || debug)  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::imagingRay: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  METHOD ossimFcsiModel::worldToLineSample()
+//
+//  Rigorous inverse transform overrides base-class iterative solution. It
+//  implements the exact reverse transform as imagingRay() above.
+//  
+//*****************************************************************************
+void ossimFcsiModel::worldToLineSample(const ossimGpt& world_point,
+                                       ossimDpt&       image_point) const
+{
+   bool debug = false;  // setable via interactive debugger: "set debug = true"
+   if (traceExec() || debug)  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::imagingRay: entering..." << std::endl;
+
+   //***
+   // Establish ECF ray from platform to ground point and rotate to platform LSR
+   //***
+   ossimEcefPoint g_ecf (world_point);
+   ossimEcefVector ecf_ray_dir (g_ecf - theAdjPlatformPos);
+   ossimColumnVector3d cam_ray_dir (theAdjEcfToLsrRot*ecf_ray_dir.data());
+
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)<<"world_point = " << world_point << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG)<<"g_ecf = " << g_ecf << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG)<<"theAdjPlatformPos = " << theAdjPlatformPos << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG)<<"theAdjPlatformPos (ossimGpt): "<<ossimGpt(theAdjPlatformPos)<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG)<<"ecf_ray_dir = " << ecf_ray_dir.unitVector() << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG)<<"theAdjEcfToLsrRot = \n" << theAdjEcfToLsrRot << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG)<<"cam_ray_dir = " << cam_ray_dir << endl;
+   }
+      
+   //***
+   // Scale the direction vector by the focal length to arrive at  film
+   // coordinates:
+   //***
+   double scale = -theAdjFocalLen/cam_ray_dir[2];
+   ossimDpt film (scale*cam_ray_dir[0], scale*cam_ray_dir[1]);
+
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theAdjFocalLen = " << theAdjFocalLen << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "scale = " << scale << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "film (undistorted) = " << film << endl;
+   }
+      
+   //***
+   // Add distortion:
+   //***
+   if (theOpticalDistortion)
+      theOpticalDistortion->forward(film);
+   
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "film (distorted) = " << film << endl;
+   }
+      
+   //***
+   // Apply film to pixel coordinates affine transform:
+   //***
+   ossimDpt f1(film + thePrincipalPoint);
+   ossimDpt p1(theInvScanXformMatrix[0]*f1.x+theInvScanXformMatrix[1]*f1.y,
+               theInvScanXformMatrix[2]*f1.x+theInvScanXformMatrix[3]*f1.y);
+   ossimDpt p0 (p1 + theRefImgPt);
+
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "thePrincipalPoint = " << thePrincipalPoint << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "f1 = " << f1 << endl;
+      for (int i=0; i<4; i++)
+         ossimNotify(ossimNotifyLevel_DEBUG)<<"theInvScanXformMatrix["<<i<<"] = "<<theInvScanXformMatrix[i]
+             <<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "p1 = " << p1 << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theRefImgPt = " << theRefImgPt << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "p0 = " << p0 << endl;
+   }
+      
+   //***
+   // Finally, apply the sub-image offset to get to digital image coordinates:
+   //***
+   image_point = p0 - theSubImageOffset;
+   
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "theImageOffset = " << theSubImageOffset << endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "image_point = " << image_point << endl;
+   }
+   
+   if (traceExec() || debug)  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::imagingRay: returning..." << std::endl;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimFcsiModel::print()
+//  
+//  Formatted dump of data members.
+//  
+//*****************************************************************************
+std::ostream& ossimFcsiModel::print(std::ostream& out) const
+{
+   out << "\nDump of ossimFcsiModel object at " << hex << this << ":\n"
+       << "\nossimFcsiModel data members: "
+       << "\n        thePrincipalPoint: " << thePrincipalPoint
+       << "\n        theScanScaleMatrix: " << theScanScaleMatrix[0] << "  "
+       << theScanScaleMatrix[1]
+       << "\n                            " << theScanScaleMatrix[2] << "  "
+       << theScanScaleMatrix[3]
+       << "\n          theScanSkew: " << theScanSkew
+       << "\n      theScanRotation: " << theScanRotation;
+
+   for (int i=0; i<4; ++i)
+   {
+      out << "\ntheScanXformMatrix["<<i<<"]: " << theScanXformMatrix[i];
+   }
+
+   out << "\n          theFocalLen: " << theFocalLen
+       << "\n       thePlatformPos: " << thePlatformPos
+       << "\n       theLsrToEcfRot: \n"  << theLsrToEcfRot
+       << "\n    theAdjLsrToEcfRot: \n" << theAdjLsrToEcfRot
+       << "\n         theEcfOffset: " << theEcfOffset
+       << "\n          theXrotCorr: " << theXrotCorr
+       << "\n          theYrotCorr: " << theYrotCorr
+       << "\n          theZrotCorr: " << theZrotCorr
+       << "\n       theFocalOffset: " << theFocalOffset
+       << "\n      theScanSkewCorr: " << theScanSkewCorr
+       << endl;
+   
+   if (theOpticalDistortion)
+   {
+      out << *theOpticalDistortion << endl;
+   }
+
+   return ossimSensorModel::print(out);
+}
+
+//*****************************************************************************
+//  METHOD: ossimFcsiModel::saveState()
+//  
+//  Saves the model state to the KWL. This KWL also serves as a geometry file.
+//  
+//*****************************************************************************
+bool ossimFcsiModel::saveState(ossimKeywordlist& kwl,
+                              const char* prefix) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::saveState: entering..." << std::endl;
+
+   kwl.add(prefix, ossimKeywordNames::TYPE_KW, "ossimFcsiModel");
+
+   //***
+   // Hand off to base class for common stuff:
+   //***
+   ossimSensorModel::saveState(kwl, prefix);
+
+   //***
+   // Save off data members:
+   //***
+   kwl.add(prefix, PRINCIPAL_POINT_X_KW,    thePrincipalPoint.x);
+   kwl.add(prefix, PRINCIPAL_POINT_Y_KW,    thePrincipalPoint.y);
+   kwl.add(prefix, SCAN_SCALE_MATRIX_00_KW, theScanScaleMatrix[0]);
+   kwl.add(prefix, SCAN_SCALE_MATRIX_01_KW, theScanScaleMatrix[1]);
+   kwl.add(prefix, SCAN_SCALE_MATRIX_10_KW, theScanScaleMatrix[2]);
+   kwl.add(prefix, SCAN_SCALE_MATRIX_11_KW, theScanScaleMatrix[3]);
+   kwl.add(prefix, SCAN_SKEW_ANGLE_KW,      theScanSkew);
+   kwl.add(prefix, SCAN_ROTATION_ANGLE_KW,  theScanRotation);
+   kwl.add(prefix, FOCAL_LENGTH_KW,         theFocalLen);
+   kwl.add(prefix, PLATFORM_POSITION_X_KW,
+           thePlatformPos.x());
+   kwl.add(prefix, PLATFORM_POSITION_Y_KW,
+           thePlatformPos.y());
+   kwl.add(prefix, PLATFORM_POSITION_Z_KW,
+           thePlatformPos.z());
+
+   //***
+   // Camera orientation matrix:
+   // i is row and j is column
+   //***
+   for (int i=0; i<3; i++)
+   {
+      for (int j=0; j<3; j++)
+      {
+         ostringstream ostr;
+         ostr << CAMERA_ORIENTATION_MATRIX_ELEM_KW
+              << i << "_" << j << ends;
+         kwl.add(prefix, ostr.str().c_str(), theLsrToEcfRot[i][j]);
+      }
+   }
+   
+   //***
+   // Optical distortion coefficients:
+   //***
+   if (theOpticalDistortion)
+   {
+      ostringstream ostr;
+      ostr << prefix << "distortion." << ends;
+      theOpticalDistortion->saveState(kwl, ostr.str().c_str());
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::saveState: returning..." << std::endl;
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimFcsiModel::loadState()
+//  
+//  Restores the model's state from the KWL. This KWL also serves as a
+//  geometry file.
+//  
+//*****************************************************************************
+bool ossimFcsiModel::loadState(const ossimKeywordlist& kwl,
+                               const char* prefix) 
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::loadState: entering..." << std::endl;
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG:"
+                                          << "\nInput kwl:  " << kwl
+                                          << std::endl;
+   }
+
+   const char* value;
+   const char* keyword;
+   bool success;
+
+   //***
+   // Assure this keywordlist contains correct type info:
+   //***
+   keyword = ossimKeywordNames::TYPE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "Type name not found");
+      return false;
+      
+   }
+   if (strcmp(value, TYPE_NAME(this)))
+   {
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::saveState: returning..." << std::endl;
+      return false;
+   }
+      
+   //***
+   // Clear out any existing adjustable params:
+   //***
+   
+   //***
+   // Pass on to the base-class for parsing first:
+   //***
+   success = ossimSensorModel::loadState(kwl, prefix);
+   if (!success)
+   {
+      return false;
+   }
+   if(!getNumberOfAdjustableParameters())
+   {
+      initAdjustableParameters();
+   }
+
+   //***
+   // Now begin loading data members:
+   //***
+   keyword = PRINCIPAL_POINT_X_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "principle point x not given");
+      return false;
+   }
+   thePrincipalPoint.x = atof(value);
+ 
+   keyword = PRINCIPAL_POINT_Y_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "principle point y not given");
+      return false;
+   }
+      
+   thePrincipalPoint.y = atof(value);
+ 
+   keyword = SCAN_SCALE_MATRIX_00_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "scale matrix 0,0 not given");
+      return false;
+   }
+   theScanScaleMatrix[0] = atof(value);
+ 
+   keyword = SCAN_SCALE_MATRIX_01_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "scale matrix 0,1 not given");
+      return false;
+   }
+   theScanScaleMatrix[1] = atof(value);
+ 
+   keyword = SCAN_SCALE_MATRIX_10_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "scale matrix 1,0 not given");
+      return false;
+   }
+   theScanScaleMatrix[2] = atof(value);
+ 
+   keyword = SCAN_SCALE_MATRIX_11_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "scale matrix 1,1 not given");
+      return false;
+   }
+   theScanScaleMatrix[3] = atof(value);
+ 
+   keyword = SCAN_SKEW_ANGLE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+      theScanSkew = 0.0;
+   else
+      theScanSkew = atof(value);
+
+   keyword = SCAN_ROTATION_ANGLE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+      theScanRotation = 0.0;
+   else
+      theScanRotation = atof(value);
+ 
+   keyword = FOCAL_LENGTH_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "Focal length not given");
+      return false;
+   }
+   theFocalLen = atof(value);
+ 
+   keyword = PLATFORM_POSITION_X_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "Platform position X not given");
+      return false;
+   }
+   thePlatformPos.x() = atof(value);
+ 
+   keyword = PLATFORM_POSITION_Y_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "Platform position Y not given");
+   }
+   thePlatformPos.y() = atof(value);
+ 
+   keyword = PLATFORM_POSITION_Z_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimSetError(getClassName(),
+                    ossimErrorCodes::OSSIM_ERROR,
+                    "Platform position Z not given");
+   }
+   thePlatformPos.z() = atof(value);
+   
+   //***
+   // Platform orientation matrix:
+   //***
+   for (int i=0; i<3; i++)
+   {
+      for (int j=0; j<3; j++)
+      {
+         ostringstream ostr;
+         ostr << CAMERA_ORIENTATION_MATRIX_ELEM_KW
+              << i << "_" << j << ends;
+         ossimString s = ostr.str();
+         keyword = s.c_str();
+         value = kwl.find(prefix, keyword);
+         if (!value)
+         {
+            ossimSetError(getClassName(),
+                          ossimErrorCodes::OSSIM_ERROR,
+                          "Camera orientation matrix not given");
+         }
+         theLsrToEcfRot[i][j] = ossimString(value).toDouble();
+      }
+   }
+   
+   //***
+   // Reading of optical distortion coefficients is left to the service object:
+   //***
+   if (theOpticalDistortion)
+      delete theOpticalDistortion;
+   theOpticalDistortion = new ossimRadialDecentLensDistortion(kwl, prefix);
+
+   //***
+   // Initialize given parameters read:
+   //***
+   clearErrorStatus();
+   updateModel();
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::loadState: returning..." << std::endl;
+   return true;
+}
+
+//*****************************************************************************
+// PROTECTED METHOD: ossimFcsiModel::updateModel()
+//
+// Following a parameter adjustment, this method is called to recompute all
+// dependent quantities that are used by the projection methods.
+// 
+//*****************************************************************************
+void  ossimFcsiModel::updateModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::updateModel: entering..." << std::endl;
+   
+   //***
+   // Update the geometry...
+   // Adjusted = Initial + adj_parm[i]*adj_sigma[i]
+   // Some parameters have a zero initial value and that term is not included.
+   //***
+   theEcfOffset.x() = getAdjustableParameter(X_POS) *
+                      getParameterSigma(X_POS);
+   theEcfOffset.y() = getAdjustableParameter(Y_POS) *
+                      getParameterSigma(Y_POS);
+   theEcfOffset.z() = getAdjustableParameter(Z_POS) *
+                      getParameterSigma(Z_POS);
+   theXrotCorr      = getAdjustableParameter(X_ROT) *
+                      getParameterSigma(X_ROT);
+   theYrotCorr      = getAdjustableParameter(Y_ROT) *
+                      getParameterSigma(Y_ROT);
+   theZrotCorr      = getAdjustableParameter(Z_ROT) *
+                      getParameterSigma(Z_ROT);
+   theFocalOffset   = getAdjustableParameter(FOCAL_LEN) *
+                      getParameterSigma(FOCAL_LEN);
+   theScanSkewCorr  = getAdjustableParameter(SCAN_SKEW) *
+                      getParameterSigma(SCAN_SKEW);
+
+   //***
+   // Compute adjusted quatities used in projection code:
+   //***
+   theAdjFocalLen    = theFocalLen    + theFocalOffset;
+   theAdjPlatformPos = thePlatformPos + theEcfOffset;
+   
+   //***
+   // Establish the Scanner to film transform matrix.
+   //
+   // NOTE FOR IMPLEMENTING PARAMETER ADJUSTMENT: while the scan skew
+   // angle is an adjustable parameter, the pixel scaling is not since this
+   // error can be absorbed by the focal length adjustment, though the sigma
+   // for the focal length must be inflated to account for the additional error
+   // source. A similar situation occurrs with the scan rotation which manifests
+   // as an attitude adjustment.
+   //***
+   double cos_rot  = cosd(theScanRotation);
+   double sin_rot  = sind(theScanRotation);
+   double tan_skew = tand(theScanSkew + theScanSkewCorr);
+
+   double a =  theScanScaleMatrix[0]*(sin_rot*tan_skew + cos_rot) +
+               theScanScaleMatrix[1]*(cos_rot*tan_skew - sin_rot);
+   double b =  theScanScaleMatrix[0]*sin_rot + theScanScaleMatrix[1]*cos_rot;
+   double c =  theScanScaleMatrix[2]*(sin_rot*tan_skew + cos_rot) +
+               theScanScaleMatrix[3]*(cos_rot*tan_skew - sin_rot);
+   double d =  theScanScaleMatrix[2]*sin_rot + theScanScaleMatrix[3]*cos_rot;
+
+   theScanXformMatrix[0] = a;
+   theScanXformMatrix[1] = b;
+   theScanXformMatrix[2] = c;
+   theScanXformMatrix[3] = d;
+
+   //***
+   // The inverse of the scanner-to-film transform must be computed since it is
+   // not an orthogonal matrix (inverse != transpose):
+   //***
+   theInvScanXformMatrix[0] =  d/(d*a - b*c);
+   theInvScanXformMatrix[1] = -b/(d*a - b*c);
+   theInvScanXformMatrix[2] =  c/(b*c - a*d);
+   theInvScanXformMatrix[3] = -a/(b*c - a*d);
+
+   //***
+   // Establish the differential rotation matrix due to attitude correction:
+   //***
+   double cw = cosd(theXrotCorr);
+   double sw = sind(theXrotCorr);
+   double cp = cosd(theYrotCorr);
+   double sp = sind(theYrotCorr);
+   double ck = cosd(theZrotCorr);
+   double sk = sind(theZrotCorr);
+
+   NEWMAT::Matrix attitudeCorrection(3, 3);
+   attitudeCorrection(1,1) =  ck*cw - sk*sp*sw;
+   attitudeCorrection(1,2) =  sk*cp;
+   attitudeCorrection(1,3) =  ck*sw + sk*sp*cw;
+   attitudeCorrection(2,1) = -sk*cw - ck*sp*sw;
+   attitudeCorrection(2,2) =  cp*ck;
+   attitudeCorrection(2,3) = -sk*sw + ck*sp*cw;
+   attitudeCorrection(3,1) = -cp*sw;
+   attitudeCorrection(3,2) = -sp;
+   attitudeCorrection(3,3) =  cp*cw;
+
+   //***
+   // Now compute the final LSR to ECF rotation:
+   //***
+   theAdjLsrToEcfRot = attitudeCorrection * theLsrToEcfRot;
+   theAdjEcfToLsrRot = theAdjLsrToEcfRot.t();
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::updateModel: returning..." << std::endl;
+}
+
+
+//*****************************************************************************
+// PRIVATE METHOD: ossimFcsiModel::initAdjustableParameters()
+//  
+//  This method initializes the base class adjustable parameter and associated
+//  sigmas arrays with quantities specific to this model. These are default
+//  values only. A functional implementation would assign the sigmas via a
+//  keywordlist or camera specific derived class.
+//  
+//*****************************************************************************
+void ossimFcsiModel::initAdjustableParameters()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::initAdjustableParameters: entering..." << std::endl;
+
+   int numParams = NUM_ADJUSTABLE_PARAMS;
+   resizeAdjustableParameterArray(NUM_ADJUSTABLE_PARAMS);
+   
+//   if(!getNumberOfAdjustableParameters())
+///   {
+   //***
+   // Allocate storage for adjustables and assign their names and units strings
+   //***
+//      newAdjustment(NUM_ADJUSTABLE_PARAMS);
+//   }
+   //***
+   // Initialize base-class adjustable parameter array:
+   //***
+   for (int i=0; i<numParams; i++)
+   {
+      setAdjustableParameter(i, 0.0);
+      setParameterDescription(i, PARAM_NAMES[i]);
+      setParameterUnit(i, PARAM_UNITS[i]);
+   }
+   
+   //***
+   // Initialize base-class parameter sigma array:
+   //***
+   setParameterSigma(X_POS, 50.0);
+   setParameterSigma(Y_POS, 50.0);
+   setParameterSigma(Z_POS, 50.0);  
+   setParameterSigma(X_ROT, 0.01);
+   setParameterSigma(Y_ROT, 0.01);
+   setParameterSigma(Z_ROT, 0.01);
+   setParameterSigma(FOCAL_LEN,0.005);  
+   setParameterSigma(SCAN_SKEW, 0.001);
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::initAdjustableParameters: returning..." << std::endl;
+}
+
+//*****************************************************************************
+// STATIC METHOD: ossimFcsiModel::writeGeomTemplate
+//  
+//  Writes a sample kwl to output stream. Please update this method with any
+//  format and/or keyword changes. It will make life a lot easier for everyone.
+//  
+//*****************************************************************************
+void ossimFcsiModel::writeGeomTemplate(ostream& os)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::writeGeomTemplate: entering..." << std::endl;
+
+   os <<
+      "//*****************************************************************\n"
+      "// Template for Frame Camera Scanned Image (FCSI) model keywordlist\n"
+      "//*****************************************************************\n"
+      << ossimKeywordNames::TYPE_KW << ": " << "ossimFcsiModel" << endl;
+
+   ossimSensorModel::writeGeomTemplate(os);
+   
+   os << "//***\n"
+      << "// Derived-class FCSI Keywords:\n"
+      << "//***\n"
+      << PRINCIPAL_POINT_X_KW << ": <pixels>\n"
+      << PRINCIPAL_POINT_Y_KW << ": <pixels>\n"
+      << SCAN_SCALE_MATRIX_00_KW << ": <mm/pixel>\n"
+      << SCAN_SCALE_MATRIX_01_KW << ": <mm/pixel>\n"
+      << SCAN_SCALE_MATRIX_10_KW << ": <mm/pixel>\n"
+      << SCAN_SCALE_MATRIX_11_KW << ": <mm/pixel>\n"
+      << SCAN_SKEW_ANGLE_KW << ": <degrees> [OPTIONAL]\n"
+      << SCAN_ROTATION_ANGLE_KW << ": <degrees> [OPTIONAL]\n"
+      << FOCAL_LENGTH_KW << ": <millimeters>\n"
+      << PLATFORM_POSITION_X_KW << ": <meters (ECF)>\n"
+      << PLATFORM_POSITION_Y_KW << ": <meters (ECF)>\n"
+      << PLATFORM_POSITION_Z_KW << ": <meters (ECF)>\n"
+      << "\n"
+      << "//***\n"
+      << "// Camera (LSR) to ECF orientation matrix:\n"
+      << "//***\n";
+   
+   for (int i=0; i<3; i++)
+   {
+      for (int j=0; j<3; j++)
+      {
+         ostringstream ostr;
+         ostr << CAMERA_ORIENTATION_MATRIX_ELEM_KW
+              << i << "_" << j << ends;
+         os << ostr.str() << ": <Euler rot matrix element>\n";
+      }
+   }
+
+   os << "\n"
+      << "//***\n"
+      << "// Optical distortion coefficients [OPTIONAL]:\n"
+      << "//***\n"
+      << "distortion."
+      << ossimRadialDecentLensDistortion::RADIAL_DISTORTION_COEFF_KW
+      << "N: <coeff N> (for N <= 5)\n"
+      << "distortion."
+      << ossimRadialDecentLensDistortion::DECENT_DISTORTION_COEFF_KW
+      << "N: <coeff N> (for N <= 4)\n"
+      << endl;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimFcsiModel::writeGeomTemplate: returning..." << std::endl;
+   
+   return;
+}
+
+
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimFcsiModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimFcsiModel.h
new file mode 100644
index 0000000000..9bb808a189
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/fcsi/ossimFcsiModel.h
@@ -0,0 +1,249 @@
+//*****************************************************************************
+// FILE: ossimFcsiModel.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION: Contains sensor model class declaration for "Frame Camera
+//   Scanned Image" (FCSI, pronounced "foxy"). 
+//   
+//   This model represents image data that was scanned from film exposed by a
+//   conventional aerial frame camera. The data members defined in this class
+//   represent the fundamental quantities needed for the transformation.
+//   Typically, a different set of parameters will be provided in the metadata.
+//   An interface (support data) class will need to be implemented to convert
+//   a particular system's format to the quantities needed by this model.
+// 
+//   Coordinate systems in use are described here:
+//
+//   Pixel    -- line/sample in the digital image. The origin of this system is
+//               the upper left corner of the image, and represents a LEFT-
+//               HANDED coordinate system with Y (line) positive down and X
+//               (sample) positive to the right.
+//
+//   Film     -- x, y related to pixel space by affine transform (which includes
+//               mirror reflection due to left-handed system above) represented
+//               by thePrincipalPoint and the theScanXformMatrix. The latter
+//               contains scale, skew, and rotation/reflection. The film
+//               coordinates are adjusted for radial and decentering distortion.
+//
+//   Camera/  -- 3D system containing film plane and optical (Z) axis. Given the
+//   Platform    focal length (Z) and the film point (X,Y), a 3D ray direction
+//               is established in this space. This space is also termed "LSR"
+//               in the code. If there is a rotation between the film/optical
+//               axes and the platform (interior orientation), then that
+//               transformation must be included as part of the LSR-to-ECF
+//               rotation by the metadata reader object.
+//
+//   ECF      -- Universal earth frame of reference. The imaging ray direction
+//               is transformed from Camera space to ECF by theAdjLsrToEcfRot.
+//
+//   There are two rotations to go from Camera to ECF. First is the initial
+//   camera orientation as derived from the metadata, combining the interior
+//   orientation (relation between camera and platform) and the exterior
+//   orientation dependent on the platform attitude w.r.t. the ECF system.
+//   The second rotation is a differential rotation due to the attitude
+//   adjustable params. These are arbitrarily taken as rotations about the ECF
+//   XYZ axes, not the platform attitude axes of roll/pitch/yaw. The
+//   combined rotation is stored in theAdjLsrToEcfRot, which is precomputed
+//   in updateModel() once with each adjustment.
+//
+//   When the time comes to incorporate least-squares parameter adjustment, care
+//   must be taken to propagate the a priori sigmas for position and attitude
+//   (including both internal and external orientation angles) into the ECF
+//   coordinates. This also applies to the affine transform parameters used in
+//   transforming pixels to film coordinates. The propagated uncertainties can
+//   then be used to assign the adjustable parameter sigmas array (and
+//   covariance when we get to that...)
+//
+// SOFTWARE HISTORY:
+//   16JAN2003  Oscar Kramer, ImageLinks
+//              Initial coding
+//
+//*****************************************************************************
+//  $Id: ossimFcsiModel.h,v 1.10 2005/05/12 19:55:13 gpotts Exp $
+
+#ifndef ossimFcsiModel_HEADER
+#define ossimFcsiModel_HEADER
+
+#include <iostream>
+using namespace std;
+
+#include "projections/sensor_modeling/ossimSensorModel.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimDpt.h"
+#include "base/data_types/ossimEcefPoint.h"
+#include "base/data_types/ossimMatrix3x3.h"
+#include "projections/sensor_modeling/ossimRadialDecentLensDistortion.h"
+
+//******************************************************************************
+//
+// CLASS:  ossimFcsiModel
+//
+//******************************************************************************
+class OSSIM_DLL ossimFcsiModel : public ossimSensorModel
+{
+public:
+   /*!
+    * CONSTRUCTORS:
+    */
+   ossimFcsiModel();
+   ossimFcsiModel(const ossimFilename& init_file);
+   ossimFcsiModel(const ossimKeywordlist& geom_kwl);
+   ossimFcsiModel(const ossimFcsiModel& rhs);
+   
+   virtual ~ossimFcsiModel() { delete theOpticalDistortion; }
+
+   enum AdjustParamIndex
+   {
+      X_POS = 0,
+      Y_POS,
+      Z_POS,
+      X_ROT,
+      Y_ROT,
+      Z_ROT,
+      FOCAL_LEN,
+      SCAN_SKEW,
+      NUM_ADJUSTABLE_PARAMS // not an index
+   };
+
+   /*!
+    * Returns pointer to a new instance, copy of this.
+    */
+   virtual ossimObject* dup() const { return new ossimFcsiModel(*this); }
+   
+   /*!
+    * Extends base-class implementation. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   /*!
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files. Returns true if successful.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /*!
+    * Writes a template of geom keywords processed by loadState and saveState
+    * to output stream.
+    */
+   static void writeGeomTemplate(ostream& os);
+   
+   /*!
+    * Overrides base class pure virtual.
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const double&   heightEllipsoid,
+                                        ossimGpt&       worldPoint) const;
+   
+   /*!
+    * Given an image point, returns a ray originating at some arbitrarily high
+    * point (ideally at the sensor position) and pointing towards the target.
+    */
+   virtual void imagingRay(const ossimDpt& image_point,
+                           ossimEcefRay&   image_ray) const;
+
+   /*!
+    * Rigorous inverse transform implented, overrides base-class' iterative
+    * solution.
+    */
+   virtual void worldToLineSample(const ossimGpt& world_point,
+                                  ossimDpt&       image_point) const;
+      
+   /*!
+    * Following a change to the adjustable parameter set, this virtual
+    * is called to permit instances to compute derived quantities after
+    * parameter change.
+    */
+   virtual void updateModel();
+
+   /*!
+    * Global keywords for use by this model:
+    */
+   static const char* PRINCIPAL_POINT_X_KW;
+   static const char* PRINCIPAL_POINT_Y_KW;
+   static const char* SCAN_SCALE_MATRIX_00_KW;
+   static const char* SCAN_SCALE_MATRIX_01_KW;
+   static const char* SCAN_SCALE_MATRIX_10_KW;
+   static const char* SCAN_SCALE_MATRIX_11_KW;
+   static const char* SCAN_SKEW_ANGLE_KW;
+   static const char* SCAN_ROTATION_ANGLE_KW;
+   static const char* FOCAL_LENGTH_KW;
+   static const char* PLATFORM_POSITION_X_KW;
+   static const char* PLATFORM_POSITION_Y_KW;
+   static const char* PLATFORM_POSITION_Z_KW;
+   static const char* CAMERA_ORIENTATION_MATRIX_ELEM_KW;
+
+protected:
+
+   /*!
+    * Assigns initial default values to adjustable parameters and related
+    * members.
+    */
+   void initAdjustableParameters();
+
+   //***
+   // Affine transform variables for scanned image to film coordinate
+   // transformation, in order of application:
+   //***
+   ossimDpt       thePrincipalPoint; // principal point location in pixels
+   double         theScanScaleMatrix[4];// converts pixel to film X, Y mm
+   double         theScanSkew;       // degrees
+   double         theScanRotation;   // degrees left rotation of scanned image
+
+   //***
+   // Transform variables for film coordinates to platform LSR (interior
+   // orientation):
+   //***
+   double         theFocalLen;     // millimeters
+   ossimRadialDecentLensDistortion* theOpticalDistortion;
+   
+   //***
+   // Transform variables for platform LSR to ECF coordinates (interior/exterior
+   // orientation and offset):
+   //***
+   ossimEcefPoint thePlatformPos;
+   NEWMAT::Matrix theLsrToEcfRot;
+   
+   //***
+   // Un-normalized adjustable parameters:
+   //***
+   ossimEcefVector theEcfOffset;      // meters
+   double          theXrotCorr;       // degrees
+   double          theYrotCorr;       // degrees
+   double          theZrotCorr;       // degrees
+   double          theFocalOffset;    // millimeters
+   double          theScanSkewCorr;   // degrees
+
+   //***
+   // Quantities derived from adjustables and assigned in updateModel():
+   //***
+   ossimEcefPoint theAdjPlatformPos;
+   double         theAdjFocalLen;
+   NEWMAT::Matrix theAdjLsrToEcfRot;
+   NEWMAT::Matrix theAdjEcfToLsrRot;
+   double         theScanXformMatrix[4]; 
+   double         theInvScanXformMatrix[4];
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/.cvsignore b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/ossimLandSatModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/ossimLandSatModel.cpp
new file mode 100644
index 0000000000..4c0b1bc69c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/ossimLandSatModel.cpp
@@ -0,0 +1,1154 @@
+//*****************************************************************************
+// FILE: ossimLandSatModel.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: 
+//
+// SOFTWARE HISTORY:
+//   01AUG2002  O. Kramer, ImageLinks
+//              Initial coding.
+//   21NOV2002  O. Kramer, ImageLinks
+//              Fixed use of map projection to use forward/inverse instead of
+//              worldTLinesample/lineSampleToWorld methods.
+//
+//*****************************************************************************
+
+#include <projections/sensor_modeling/landsat/ossimLandSatModel.h>
+
+RTTI_DEF1(ossimLandSatModel, "ossimLandSatModel", ossimSensorModel);
+
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <support_data/ff_l7/ossimFfL7.h>
+#include <support_data/ff_l7/ossimFfL5.h>
+#include <projections/map_projections/ossimSpaceObliqueMercatorProjection.h>
+#include <projections/map_projections/ossimUtmProjection.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <base/data_types/ossimLsrPoint.h>
+#include <base/data_types/ossimLsrRay.h>
+#include <base/data_types/ossimLsrSpace.h>
+#include <stdio.h>
+#include <fstream>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimLandSatModel:exec");
+static ossimTrace traceDebug ("ossimLandSatModel:debug");
+
+static const int    MODEL_VERSION_NUMBER   = 2;
+static const char*  PROJECTION_TYPE_KW     = "theProjectionType";
+static const char*  MAP_ZONE_KW            = "theMapZone";
+static const char*  MAP_OFFSET_X_KW        = "theMapOffset.x";
+static const char*  MAP_OFFSET_Y_KW        = "theMapOffset.y";
+static const char*  WRS_PATH_NUMBER_KW     = "theWrsPathNumber";
+static const char*  ROW_NUMBER_KW          = "theWrsRowNumber";
+static const char*  ILLUM_AZIMUTH_KW       = "theIllumAzimuth";
+static const char*  ILLUM_ELEVATION_KW     = "theIllumElevation";
+static const char*  MERIDIANAL_ANGLE_KW    = "theMeridianalAngle";
+static const char*  ORBIT_ALTITUDE_KW      = "theOrbitAltitude";
+static const char*  ORBIT_INCLINATION_KW   = "theOrbitInclination";
+static const char*  MAP_AZIM_ANGLE_KW      = "theMapAzimAngle";
+static const char*  MAP_2Ic_ROT_ANGLE_KW   = "theMap2IcRotAngle";
+static const char*  INTRACK_OFFSET_KW      = "theIntrackOffset";
+static const char*  CRTRACK_OFFSET_KW      = "theCrtrackOffset";
+static const char*  LINE_GSD_CORR_KW       = "theLineGsdCorr";
+static const char*  SAMP_GSD_CORR_KW       = "theSampGsdCorr";
+static const char*  ROLL_OFFSET_KW         = "theRollOffset";
+static const char*  YAW_OFFSET_KW          = "theYawOffset";
+static const char*  YAW_RATE_KW            = "theYawRate";
+static const char*  MAP_ROTATION_KW        = "theMapRotation";
+
+
+static const double   GEODETIC_2_GEOCENTRIC_FACTOR  = 1.00674;
+static const double   L7_ORBIT_ALTITUDE  = 705300.0;
+static const double   L7_ORBIT_INCLINATION  = 98.22;
+static const double   L7_NOMINAL_POS_ERROR  = 200.0;
+
+static const double   L5_ORBIT_ALTITUDE  = 705300.0;
+static const double   L5_ORBIT_INCLINATION  = 98.22;
+static const double   L5_NOMINAL_POS_ERROR  = 1200.0; //arbitrary : to be fixed
+
+
+static const char* PARAM_NAMES[] ={"intrack_offset",
+                                         "crtrack_offset",
+                                         "line_gsd_corr",
+                                         "samp_gsd_corr",
+                                         "roll_offset",
+                                         "yaw_offset",
+                                         "yaw_rate",
+                                         "map_rotation"};
+
+static const char* PARAM_UNITS[] ={"meters",
+                                         "meters",
+                                         "meters",
+                                         "meters",
+                                         "degrees",
+                                         "degrees",
+                                         "seconds",
+                                         "degrees"};
+
+static const char* PROJ_TYPE[] = { "UNKNOWN_PROJECTION",
+                                         "UTM_MAP",
+                                         "UTM_ORBIT",
+                                         "SOM_MAP",
+                                         "SOM_ORBIT" };
+
+//*****************************************************************************
+//  DEFAULT CONSTRUCTOR: ossimLandSatModel()
+//  
+//*****************************************************************************
+ossimLandSatModel::ossimLandSatModel()
+   :
+   ossimSensorModel(),
+   theMapProjection(NULL),
+   theIntrackOffset     (0.0),
+   theCrtrackOffset     (0.0),
+   theLineGsdCorr       (0.0),   
+   theSampGsdCorr       (0.0),
+   theRollOffset        (0.0),
+   theYawOffset         (0.0),
+   theYawRate           (0.0),
+   theMapRotation       (0.0)
+
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel: entering..." << std::endl;
+
+   initAdjustableParameters();
+   
+   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: ossimLandSatModel(ossimLandSatModel)
+//  
+//*****************************************************************************
+ossimLandSatModel::ossimLandSatModel(const ossimFfL7& head)
+   :
+   ossimSensorModel(),
+   theMapProjection(NULL),
+   theIntrackOffset     (0.0),
+   theCrtrackOffset     (0.0),
+   theLineGsdCorr       (0.0),   
+   theSampGsdCorr       (0.0),
+   theRollOffset        (0.0),
+   theYawOffset         (0.0),
+   theYawRate           (0.0),
+   theMapRotation       (0.0)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel(head): entering..." << std::endl;   
+
+   initFromHeader(head);
+
+   if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel(head): Exited..." << std::endl;
+}
+
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLandSatModel(filename)
+//  
+//  Constructs model from a filename. The file can be either a FF header file
+//  or a KWL file.
+//  
+//*****************************************************************************
+ossimLandSatModel::ossimLandSatModel(const ossimFilename& init_file)
+   :
+   ossimSensorModel     (),
+   theMapProjection     (NULL),
+   theIntrackOffset     (0.0),
+   theCrtrackOffset     (0.0),
+   theLineGsdCorr       (0.0),   
+   theSampGsdCorr       (0.0),
+   theRollOffset        (0.0),
+   theYawOffset         (0.0),
+   theYawRate           (0.0),
+   theMapRotation       (0.0)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel(init_file): entering..." << std::endl;
+
+   ossimFfL7* ff_headerp=0;
+   if (ossimString::downcase(init_file).contains("header.dat"))
+   {
+      ff_headerp=new ossimFfL5(init_file);
+   } else {
+      ff_headerp=new ossimFfL7(init_file);
+   }
+   if (!ff_headerp->getErrorStatus())
+   {
+      initFromHeader(*ff_headerp);
+   }
+   
+   //***
+   // If not header, then check for possible KWL file. The loadState sets the
+   // error status:
+   //***
+   else
+   {
+      ossimKeywordlist kwl (init_file);
+      loadState(kwl);
+   }
+   delete ff_headerp;
+
+   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel(init_file): Exited..." << std::endl;
+}
+
+
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimLandSatModel(kwl)
+//  
+//  Constructs model from keywordlist geometry file
+//  
+//*****************************************************************************
+ossimLandSatModel::ossimLandSatModel(const ossimKeywordlist& geom_kwl)
+   :
+   ossimSensorModel(),
+   theMapProjection(NULL),
+   theIntrackOffset     (0.0),
+   theCrtrackOffset     (0.0),
+   theLineGsdCorr       (0.0),   
+   theSampGsdCorr       (0.0),
+   theRollOffset        (0.0),
+   theYawOffset         (0.0),
+   theYawRate           (0.0),
+   theMapRotation       (0.0)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel(geom_kwl): entering..." << std::endl;
+
+   initAdjustableParameters();
+
+   //***
+   // Parse keywordlist for geometry:
+   //***
+   loadState(geom_kwl);
+
+   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel(geom_kwl): Exited..." << std::endl;
+}
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: 
+//*****************************************************************************
+ossimLandSatModel::ossimLandSatModel(const ossimLandSatModel& rhs)
+   :
+   ossimSensorModel   (rhs),
+   theIllumAzimuth    (rhs.theIllumAzimuth),
+   theIllumElevation  (rhs.theIllumElevation),
+   theOrbitAltitude   (rhs.theOrbitAltitude),
+   theOrbitInclination(rhs.theOrbitInclination),
+   theMapZone         (rhs.theMapZone),
+   theMapOffset       (rhs.theMapOffset),
+   theWrsPathNumber   (rhs.theWrsPathNumber),
+   theWrsRowNumber    (rhs.theWrsRowNumber),
+   theMeridianalAngle (rhs.theMeridianalAngle),
+   thePositionError   (rhs.thePositionError),
+   theProjectionType  (rhs.theProjectionType),
+   theMapProjection   (rhs.theMapProjection?
+                       (ossimMapProjection*)rhs.theMapProjection->dup():
+                       (ossimMapProjection*)NULL),
+   theMapAzimAngle    (rhs.theMapAzimAngle),
+   theMapAzimCos      (rhs.theMapAzimCos),
+   theMapAzimSin      (rhs.theMapAzimSin),
+   theMap2IcRotAngle  (rhs.theMap2IcRotAngle),
+   theMap2IcRotCos    (rhs.theMap2IcRotCos),
+   theMap2IcRotSin    (rhs.theMap2IcRotSin),
+   theIntrackOffset   (rhs.theIntrackOffset),
+   theCrtrackOffset   (rhs.theCrtrackOffset),
+   theLineGsdCorr     (rhs.theLineGsdCorr),
+   theSampGsdCorr     (rhs.theSampGsdCorr),
+   theRollOffset      (rhs.theRollOffset),
+   theYawOffset       (rhs.theYawOffset),
+   theYawRate         (rhs.theYawRate),
+   theMapRotation     (rhs.theMapRotation),
+   theRollRotMat      (rhs.theRollRotMat)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel(rhs): entering..." << std::endl;
+   
+   initAdjustableParameters();
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::ossimLandSatModel(rhs): returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimLandSatModel()
+//  
+//*****************************************************************************
+ossimLandSatModel::~ossimLandSatModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::~ossimLandSatModel: entering..." << std::endl;
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::~ossimLandSatModel: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimLandSatModel::initFromHeader()
+//  
+//*****************************************************************************
+void ossimLandSatModel::initFromHeader(const ossimFfL7& head)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::initFromHeader: entering..." << std::endl;
+   
+   //***
+   // Initialize base-class data members:
+   //***
+   theRefGndPt         = head.theCenterGP;
+   theRefImgPt         = head.theCenterImagePoint;
+   theImageSize.x      = head.thePixelsPerLine;
+   theImageSize.y      = head.theLinesPerBand;
+   theImageID          = head.theRequestNumber;
+   theImageClipRect    = ossimDrect(0, 0, theImageSize.x-1, theImageSize.y-1);
+   theGSD.samp         = head.theGsd;
+   theGSD.line         = head.theGsd;
+   theIllumAzimuth     = head.theSunAzimuth;
+   theIllumElevation   = head.theSunElevation;
+   theMapZone          = head.theUsgsMapZone;
+   theWrsPathNumber    = head.thePathNumber;
+   theWrsRowNumber     = head.theRowNumber;
+   theRollOffset       = head.theOffNadirAngle;
+   theMeanGSD          = head.theGsd;
+   
+   //satellite orbit and accuracy
+   ossimString satname(head.theSatName);
+   if (satname.contains("7"))
+   {
+      theOrbitAltitude    = L7_ORBIT_ALTITUDE;
+      theOrbitInclination = L7_ORBIT_INCLINATION;
+      theNominalPosError  = L7_NOMINAL_POS_ERROR;
+   } else if (satname.contains("5"))
+   {
+      theOrbitAltitude    = L5_ORBIT_ALTITUDE;
+      theOrbitInclination = L5_ORBIT_INCLINATION;
+      theNominalPosError  = L5_NOMINAL_POS_ERROR;
+   } else {
+      theErrorStatus = 1; //MODEL_ERROR
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimLandSatModel::initFromHeader: " << "Unknown satellite name : " << satname << std::endl;
+      }
+   }   
+   
+   
+   //***
+   // Assign the meridianal angle. The Meridianal angle is
+   // the angle between true north and the vehicles ground track. The
+   // orientation angle is the rotation of the raster image from north (this
+   // will be 0 for map-oriented imagery).
+   //
+   // Compute meridianal angle between the along-track direction
+   // and the meridian going through the scene center excluding earth rotation
+   // effects. The spherical triangle equation is Napier's rule for right-angle
+   // spherical triangles.  This angle is a negative number from -8.2 to -90
+   // depending on scene latitude:
+   //***
+   double phi_c = atand(tand(theRefGndPt.lat)/
+                        GEODETIC_2_GEOCENTRIC_FACTOR);
+   double cos_phi_c   = cosd(phi_c);
+   theMeridianalAngle = -asind(cosd(theOrbitInclination) / cos_phi_c);
+   theMapAzimAngle = head.theOrientationAngle;
+
+   //***
+   // Fetch the corner points from the header:
+   //***
+   ossimDpt v[4]; // temporarily holds vertices for ground polygon
+   v[0] = head.theUL_Corner;
+   v[1] = head.theUR_Corner;
+   v[2] = head.theLR_Corner;
+   v[3] = head.theLL_Corner;
+   theBoundGndPolygon = ossimPolygon(4, v);
+
+   //***
+   // Initialize map projection parameters:
+   // Determine the projection/orientation type:
+   //***
+   ossimString orient_type = head.theProductType;
+   ossimString proj_type   = head.theMapProjectionName;
+   if (proj_type.contains("SOM"))
+   {
+      //***
+      // Inverse the line direction GSD for SOM, since projection "intrack"
+      // axis (x) is descending:
+      //***
+      if (orient_type.contains("ORBIT"))
+         theProjectionType  = SOM_ORBIT;
+      else
+         theProjectionType = SOM_MAP;
+
+      // this is a hack.  After testing two it is consistently off
+      // by 90 degrees.
+      //
+      theMapAzimAngle -= 90.0;
+   }
+   else if (proj_type.contains("UTM"))
+   {
+      if (orient_type.contains("ORBIT"))
+         theProjectionType  = UTM_ORBIT;
+      else
+         theProjectionType = UTM_MAP;
+   }
+   else
+   {
+      theErrorStatus = 1; //MODEL_ERROR
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimLandSatModel::initFromHeader: "
+                                             << "Unknown projection/orientation type." << std::endl;
+      }
+      return;
+   }
+
+   //***
+   // Establish the map projection:
+   //***
+   initMapProjection();
+
+      
+   theMapOffset = theMapProjection->forward(head.theUL_Corner);
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimLandSatModel::initFromHeader:"
+         << "\ntheMapProjection:\n";
+
+      theMapProjection->print(ossimNotify(ossimNotifyLevel_DEBUG));
+
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "\nHeader upper left ground point:  " << head.theUL_Corner
+         << std::endl;
+   }
+
+   //*** 
+   // initialize remaining data members:
+   //***
+   initAdjustableParameters();
+   updateModel();
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::initFromHeader: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimLandSatModel::lineSampleHeightToWorld()
+//  
+//  Performs the line/sample to groundpoint projection given an elevation.
+//  
+//  5. Intersect imaging ray with elevation surface.
+//
+//*****************************************************************************
+void ossimLandSatModel::lineSampleHeightToWorld(const ossimDpt& image_point,
+                                                const double&   height,
+                                                ossimGpt&       gpt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::lineSampleHeightToWorld: entering..." << std::endl;
+
+   //***
+   // Extrapolate if point is outside image:
+   //***
+   if (!insideImage(image_point))
+   {
+      gpt = extrapolate(image_point, height);
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::lineSampleHeightToWorld: returning..." << std::endl;
+      return;
+   }
+
+   //***
+   // First establish imaging ray from image point:
+   //***
+   ossimEcefRay imaging_ray;
+   imagingRay(image_point, imaging_ray);
+   ossimEcefPoint Pecf (imaging_ray.intersectAboveEarthEllipsoid(height));
+   gpt = ossimGpt(Pecf);
+}
+   
+   
+//*****************************************************************************
+//  METHOD: ossimLandSatModel::imagingRay()
+//  
+//  This model implements an affine transform with scaling to arrive at an
+//  ECF ray given an image point. This ray is intersected with a constant
+//  elevation surface to arrive at a ground point. The transform to arrive at a
+//  point on the ground [p,l,0] is implemented briefly as follows:
+//
+//  0. Establish the lat/lon map point given input point.
+//
+//  1. Determine intrack/crosstrack coordinates of image map point by rotating
+//     the input coordinates by meridianal angle.
+//
+//  2. Given intrack line number, compute vehicle position at time of imaging.
+//
+//  3. Establish imaging ray given input point ground coordinates and vehicle
+//     position.
+//
+//  4. Perturb imaging ray by adjustable parameters for platform attitude and
+//     position error.
+//
+//*****************************************************************************
+void ossimLandSatModel::imagingRay(const ossimDpt& inImgPt,
+                                   ossimEcefRay&   image_ray) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "ossimLandSatModel::imagingRay: entering..." << std::endl;
+
+   bool debug_flag = false; // setable by interactive debugger
+   if (traceDebug() || debug_flag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "inImgPt = " << inImgPt << std::endl;
+   }
+
+   //***
+   // Get ground point for given map image point:
+   //***
+   ossimDpt rot_img_pt(-inImgPt.line*theMapAzimSin+inImgPt.samp*theMapAzimCos,
+                        inImgPt.line*theMapAzimCos+inImgPt.samp*theMapAzimSin);
+   ossimDpt map_point 
+      (theMapOffset.x + rot_img_pt.samp*(theGSD.samp+theSampGsdCorr), 
+       theMapOffset.y - rot_img_pt.line*(theGSD.line+theLineGsdCorr));
+
+   ossimGpt inGndPt (theMapProjection->inverse(map_point));
+   if (traceDebug() || debug_flag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t theMapOffset="<<theMapOffset<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t rot_img_pt="<<rot_img_pt<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t image point map_point="<<map_point<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t inGndPt="<<inGndPt<<endl;
+   }
+
+
+   //***
+   // Rotate the image map coordinates by the map-to-IC rotation
+   // to arrive at intrack/crosstrack coordinate:
+   //***
+   ossimDpt offInMapPt (inImgPt - theRefImgPt);
+   ossimDpt icInPt
+      (offInMapPt.line*theMap2IcRotSin + offInMapPt.samp*theMap2IcRotCos,
+       offInMapPt.line*theMap2IcRotCos - offInMapPt.samp*theMap2IcRotSin);
+   if (traceDebug() || debug_flag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t offInMapPt="<<offInMapPt<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t icInPt="<<icInPt<<endl;
+   }
+
+   //***
+   // Establish an image map point at vehicle NADIR corresponding to imaging
+   // line:
+   //***
+   ossimDpt icNdrPt (0.0, icInPt.line);
+   ossimDpt offNdrMapPt
+      (-icNdrPt.line*theMap2IcRotSin + icNdrPt.samp*theMap2IcRotCos,
+        icNdrPt.line*theMap2IcRotCos + icNdrPt.samp*theMap2IcRotSin);
+   ossimDpt ndrMapPt(offNdrMapPt + theRefImgPt);
+   ossimDpt rotNdrMapPt
+      (-ndrMapPt.line*theMapAzimSin + ndrMapPt.samp*theMapAzimCos,
+       ndrMapPt.line*theMapAzimCos + ndrMapPt.samp*theMapAzimSin);
+   if (traceDebug() || debug_flag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t icNdrPt="<<icNdrPt<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t offNdrMapPt="<<offNdrMapPt<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t ndrMapPt="<<ndrMapPt<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t rotNdrMapPt="<<rotNdrMapPt<<endl;
+   }
+
+   //***
+   // Establish the vehicle position at time of line imaging:
+   //***
+   map_point.y =theMapOffset.y+rotNdrMapPt.x*(theGSD.x+theSampGsdCorr);
+   if ((theProjectionType == SOM_ORBIT) || (theProjectionType == SOM_MAP))
+      map_point.x = theMapOffset.x+rotNdrMapPt.y*(theGSD.y+theLineGsdCorr);
+   else
+      map_point.x = theMapOffset.x-rotNdrMapPt.y*(theGSD.y+theLineGsdCorr);
+      
+   ossimGpt vehiclePlhPos(theMapProjection->inverse(map_point));
+   vehiclePlhPos.hgt = theOrbitAltitude;
+   if (traceDebug() || debug_flag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t map_point="<<map_point<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t vehiclePlhPos="<<vehiclePlhPos<<endl;
+   }
+   
+   //***
+   // Establish an LSR space at the vehicle with X along the intrack direction:
+   //***
+   ossimLsrSpace icrSpace (vehiclePlhPos, theMeridianalAngle-90.0);
+   if (traceDebug() || debug_flag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t icrSpace="<<icrSpace<<endl;
+   }
+
+   //***
+   // Now establish a ray pointing to the imaged ground point from the vehicle
+   // in ICR space:
+   //***
+   ossimLsrPoint lsrInPt (inGndPt, icrSpace);
+   ossimLsrPoint vehicleLsrPos (0.0, 0.0, 0.0, icrSpace);
+   ossimLsrRay   initLsrImgRay (vehicleLsrPos, lsrInPt);
+   if (traceDebug() || debug_flag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t initLsrImgRay="<<initLsrImgRay<<endl;
+   } 
+
+   //***
+   // Establish the attitude rotation matrix considering the attitude biases
+   // and rates:
+   //***
+   double cos, sin;
+   double norm_line = inImgPt.line/theImageSize.line;
+   double yaw = theYawOffset + theYawRate*norm_line;
+   cos = cosd(yaw);
+   sin = sind(yaw);
+   NEWMAT::Matrix T_yaw = ossimMatrix3x3::create( cos,-sin, 0.0,
+                                                  sin, cos, 0.0,
+                                                  0.0, 0.0, 1.0);
+   NEWMAT::Matrix attRotMat = T_yaw * theRollRotMat;
+
+   //***
+   // Now apply the perturbation to the ray due to the adjustable parameters,
+   // and arrive at the ECF adjusted imaging ray:
+   //***
+   ossimLsrVector adjLsrImgRayDir (attRotMat*initLsrImgRay.direction().data(),
+                                   icrSpace);
+   ossimLsrPoint  adjLsrImgRayOrg (theIntrackOffset,
+                                   theCrtrackOffset,
+                                   0.0,  // no radial adjustment of position
+                                   icrSpace);
+   ossimLsrRay adjLsrImgRay (adjLsrImgRayOrg, adjLsrImgRayDir);
+   image_ray = ossimEcefRay(adjLsrImgRay);
+   if (traceDebug() || debug_flag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t adjLsrImgRay="<<adjLsrImgRay<<endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "\t image_ray="<<image_ray<<endl;
+   }
+
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::imagingRay: Returning..." << std::endl;
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimLandSatModel::print()
+//  
+//  Formatted dump of data members.
+//  
+//*****************************************************************************
+std::ostream& ossimLandSatModel::print(std::ostream& os) const
+{
+   os << "\nDump of ossimLandSatModel object at "
+      << hex << this << ":\n"
+      << "\nLandSatModel -- Dump of all data members: "
+      << "\n         theImageID: " << theImageID.chars()
+      << "\n       theImageSize: " << theImageSize
+      << "\n        theRefImgPt: " << theRefImgPt
+      << "\n        theRefGndPt: " << theRefGndPt
+      << "\n        theGSD.line: " << theGSD.line
+      << "\n        theGSD.samp: " << theGSD.samp
+      << "\n  theProjectionType: " << PROJ_TYPE[theProjectionType]
+      << "\n         theMapZone: " << theMapZone
+      << "\n       theMapOffset: " << theMapOffset
+      << "\n   theWrsPathNumber: " << theWrsPathNumber
+      << "\n    theWrsRowNumber: " << theWrsRowNumber
+      << "\n    theIllumAzimuth: " << theIllumAzimuth
+      << "\n  theIllumElevation: " << theIllumElevation
+      << "\n   thePositionError: " << thePositionError
+      << "\n theMeridianalAngle: " << theMeridianalAngle
+      << "\n   theOrbitAltitude: " << theOrbitAltitude
+      << "\ntheOrbitInclination: " << theOrbitInclination
+      << "\n    theMapAzimAngle: " << theMapAzimAngle
+      << "\n  theMap2IcRotAngle: " << theMap2IcRotAngle
+      << "\n   theIntrackOffset: " << theIntrackOffset
+      << "\n   theCrtrackOffset: " << theCrtrackOffset
+      << "\n     theLineGsdCorr: " << theLineGsdCorr
+      << "\n     theSampGsdCorr: " << theSampGsdCorr
+      << "\n      theRollOffset: " << theRollOffset
+      << "\n       theYawOffset: " << theYawOffset
+      << "\n         theYawRate: " << theYawRate
+      << "\n     theMapRotation: " << theMapRotation
+      << endl;
+
+   return ossimSensorModel::print(os);
+}
+
+//*****************************************************************************
+//  METHOD: ossimLandSatModel::saveState()
+//  
+//  Saves the model state to the KWL. This KWL also serves as a geometry file.
+//  
+//*****************************************************************************
+bool ossimLandSatModel::saveState(ossimKeywordlist& kwl,
+                              const char* prefix) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::saveState: entering..." << std::endl;
+
+   kwl.add(prefix, ossimKeywordNames::TYPE_KW, TYPE_NAME(this));
+
+   //***
+   // Hand off to base class for common stuff:
+   //***
+   ossimSensorModel::saveState(kwl, prefix);
+
+   //***
+   // Save off data members:
+   //***
+   kwl.add(prefix, PROJECTION_TYPE_KW,   theProjectionType, true);
+   kwl.add(prefix, MAP_ZONE_KW,          theMapZone, true);
+   kwl.add(prefix, MAP_OFFSET_X_KW,      theMapOffset.x, true);
+   kwl.add(prefix, MAP_OFFSET_Y_KW,      theMapOffset.y, true);
+   kwl.add(prefix, WRS_PATH_NUMBER_KW,   theWrsPathNumber, true);
+   kwl.add(prefix, ROW_NUMBER_KW,        theWrsRowNumber, true);
+   kwl.add(prefix, ILLUM_AZIMUTH_KW,     theIllumAzimuth, true);
+   kwl.add(prefix, ILLUM_ELEVATION_KW,   theIllumElevation, true);
+   kwl.add(prefix, MERIDIANAL_ANGLE_KW,  theMeridianalAngle, true);
+   kwl.add(prefix, ORBIT_ALTITUDE_KW,    theOrbitAltitude, true);
+   kwl.add(prefix, ORBIT_INCLINATION_KW, theOrbitInclination, true);
+   kwl.add(prefix, MAP_AZIM_ANGLE_KW,    theMapAzimAngle, true);
+   kwl.add(prefix, MAP_2Ic_ROT_ANGLE_KW, theMap2IcRotAngle, true);
+
+//    kwl.add(prefix, INTRACK_OFFSET_KW ,   theIntrackOffset, true);
+//    kwl.add(prefix, CRTRACK_OFFSET_KW,    theCrtrackOffset, true);
+//    kwl.add(prefix, LINE_GSD_CORR_KW,     theLineGsdCorr, true);
+//    kwl.add(prefix, SAMP_GSD_CORR_KW,     theSampGsdCorr, true);
+//    kwl.add(prefix, ROLL_OFFSET_KW,       theRollOffset, true);
+//    kwl.add(prefix, YAW_OFFSET_KW,        theYawOffset, true);
+//    kwl.add(prefix, YAW_RATE_KW,          theYawRate, true);
+//    kwl.add(prefix, MAP_ROTATION_KW,      theMapRotation, true);
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::saveState: returning..." << std::endl;
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimLandSatModel::loadState()
+//  
+//  Restores the model's state from the KWL. This KWL also serves as a
+//  geometry file.
+//  
+//*****************************************************************************
+bool ossimLandSatModel::loadState(const ossimKeywordlist& kwl,
+                                  const char* prefix) 
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::loadState: entering..." << std::endl;
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::loadState:"
+                                          << "\nInput kwl:  " << kwl
+                                          << std::endl;
+   }
+
+   const char* value = NULL;
+   const char* keyword =NULL;
+   bool success;
+
+   //***
+   // Assure this keywordlist contains correct type info:
+   //***
+   value = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   if (!value || (strcmp(value, TYPE_NAME(this)))) 
+     {
+       theErrorStatus = 1;
+       return false;
+     }
+
+   //
+   // Clear out any existing adjustable params:
+   //
+   if(getNumberOfAdjustableParameters() != NUM_ADJUSTABLE_PARAMS)
+     {
+       initAdjustableParameters();
+     }
+   
+   //***
+   // Pass on to the base-class for parsing first:
+   //***
+   success = ossimSensorModel::loadState(kwl, prefix);
+   if (!success) 
+     {
+       theErrorStatus++;
+       return false;
+     }
+ 
+   keyword = PROJECTION_TYPE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+
+   theProjectionType = (ProjectionType) atoi(value);
+ 
+   keyword = MAP_ZONE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theMapZone = atoi(value);
+ 
+   keyword = MAP_OFFSET_X_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theMapOffset.x = atof(value);
+ 
+   keyword = MAP_OFFSET_Y_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theMapOffset.y = atof(value);
+ 
+   keyword = WRS_PATH_NUMBER_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theWrsPathNumber = atoi(value);
+
+   keyword = ROW_NUMBER_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theWrsRowNumber = atoi(value);
+ 
+   keyword = ILLUM_AZIMUTH_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theIllumAzimuth = atof(value);
+ 
+   keyword = ILLUM_ELEVATION_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theIllumElevation = atof(value);
+ 
+   keyword = MERIDIANAL_ANGLE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theMeridianalAngle = atof(value);
+ 
+   keyword = ORBIT_ALTITUDE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theOrbitAltitude = atof(value);
+   
+   keyword = ORBIT_INCLINATION_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theOrbitInclination = atof(value);
+   
+   keyword = MAP_AZIM_ANGLE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theMapAzimAngle = atof(value);
+ 
+   keyword = MAP_2Ic_ROT_ANGLE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+     {
+       theErrorStatus++;
+       return false;
+     }
+   theMap2IcRotAngle = atof(value);
+
+   theIntrackOffset = 0.0;
+   theCrtrackOffset = 0.0;
+   theLineGsdCorr   = 0.0;
+   theSampGsdCorr   = 0.0;
+   theRollOffset    = 0.0;
+   theYawOffset     = 0.0;
+   theYawRate       = 0.0;
+   theMapRotation   = 0.0;
+
+   //***
+   // Adjustable parameters are optional keywords:
+   //***
+//    keyword = INTRACK_OFFSET_KW;
+//    value = kwl.find(prefix, keyword);
+//    if(value)
+//       theIntrackOffset = ossimString(value).toDouble();
+//    else
+//     theIntrackOffset = 0.0;
+   
+//    keyword = CRTRACK_OFFSET_KW;
+//    value = kwl.find(prefix, keyword);
+//    if(value)
+//       theCrtrackOffset = ossimString(value).toDouble();
+//    else
+//      theCrtrackOffset = 0.0;
+
+//    keyword = LINE_GSD_CORR_KW;
+//    value = kwl.find(prefix, keyword);
+//    if(value)
+//       theLineGsdCorr = ossimString(value).toDouble();
+//    else
+//       theLineGsdCorr = 0.0;
+
+//    keyword = SAMP_GSD_CORR_KW;
+//    value = kwl.find(prefix, keyword);
+//    if(value)
+//       theSampGsdCorr = ossimString(value).toDouble();
+//    else
+//       theSampGsdCorr = 0.0;
+   
+//    keyword = ROLL_OFFSET_KW;
+//    value = kwl.find(prefix, keyword);
+//    if(value)
+//       theRollOffset = ossimString(value).toDouble();
+//    else
+//       theRollOffset = 0.0;
+   
+//    keyword = YAW_OFFSET_KW;
+//    value = kwl.find(prefix, keyword);
+//    if(value)
+//       theYawOffset = ossimString(value).toDouble();
+//    else
+//      theYawOffset = 0.0;
+   
+//    keyword = YAW_RATE_KW;
+//    value = kwl.find(prefix, keyword);
+//    if(value)
+//       theYawRate = ossimString(value).toDouble();
+//    else
+//       theYawRate = 0.0;
+
+//    keyword = MAP_ROTATION_KW;
+//    value = kwl.find(prefix,  keyword);
+//    if(value)
+//       theMapRotation = ossimString(value).toDouble();
+//    else
+//       theMapRotation = 0.0;
+
+   //***
+   // Initialize given parameters read:
+   //***
+   initMapProjection();
+   updateModel();
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::loadState: returning..." << std::endl;
+   return true;
+}
+
+//*****************************************************************************
+// STATIC METHOD: ossimLandSatModel::writeGeomTemplate
+//  
+//  Writes a sample kwl to output stream.
+//  
+//*****************************************************************************
+void ossimLandSatModel::writeGeomTemplate(ostream& os)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::writeGeomTemplate: entering..." << std::endl;
+
+   os <<
+      "//**************************************************************\n"
+      "// Template for LandSat model keywordlist\n"
+      "//**************************************************************\n"
+      << ossimKeywordNames::TYPE_KW << ": " << "ossimLandSatModel" << endl;
+
+   ossimSensorModel::writeGeomTemplate(os);
+   
+   os << "//\n"
+      << "// Derived-class ossimLandSatModel Keywords:\n"
+      << "//\n"
+      << PROJECTION_TYPE_KW     << ": <float>\n"
+      << MAP_ZONE_KW            << ": <float>\n"
+      << MAP_OFFSET_X_KW        << ": <float>\n"
+      << MAP_OFFSET_Y_KW        << ": <float>\n"
+      << WRS_PATH_NUMBER_KW     << ": <float>\n"
+      << ROW_NUMBER_KW          << ": <float>\n"
+      << ILLUM_AZIMUTH_KW       << ": <float>\n"
+      << ILLUM_ELEVATION_KW     << ": <float>\n"
+      << MERIDIANAL_ANGLE_KW    << ": <float>\n"
+      << ORBIT_ALTITUDE_KW      << ": <float>\n"
+      << ORBIT_INCLINATION_KW   << ": <float>\n"
+      << MAP_AZIM_ANGLE_KW      << ": <float>\n"
+      << MAP_2Ic_ROT_ANGLE_KW   << ": <float>\n"
+      << INTRACK_OFFSET_KW      << ": <float> [optional]\n"
+      << CRTRACK_OFFSET_KW      << ": <float> [optional]\n"
+      << LINE_GSD_CORR_KW       << ": <float> [optional]\n"
+      << SAMP_GSD_CORR_KW       << ": <float> [optional]\n"
+      << ROLL_OFFSET_KW         << ": <float> [optional]\n"
+      << YAW_OFFSET_KW          << ": <float> [optional]\n"
+      << YAW_RATE_KW            << ": <float> [optional]\n"
+      << MAP_ROTATION_KW        << ": <float> [optional]\n"
+      << endl;
+   os << "\n" <<endl;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::writeGeomTemplate: returning..." << std::endl;
+   return;
+}
+
+
+//*****************************************************************************
+// PROTECTED METHOD: ossimLandSatModel::initMapProjection()
+//  
+//*****************************************************************************
+void ossimLandSatModel::initMapProjection()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) <<  "DEBUG ossimLandSatModel::writeGeomTemplate: entering... " << std::endl;
+
+   if(theMapProjection)
+   {
+      delete theMapProjection;
+      theMapProjection = NULL;
+   }
+   
+   //*** 
+   // Instantiate the proper map projection:
+   //***
+   if ((theProjectionType == SOM_ORBIT) || (theProjectionType == SOM_MAP))
+   {
+      theMapProjection = new ossimSpaceObliqueMercatorProjection(
+         ossimSpaceObliqueMercatorProjection::SOM_TYPE_LANDSAT_7,
+         (double)theWrsPathNumber);
+   }
+   else 
+   {
+      theMapProjection = new ossimUtmProjection(theMapZone);
+   }
+
+   //***
+   // Initialize angle sines/cosines used in phiLambda projection:
+   //***
+   theMap2IcRotAngle = theMeridianalAngle + theMapAzimAngle;
+   theMap2IcRotCos   = cosd(theMap2IcRotAngle);
+   theMap2IcRotSin   = sind(theMap2IcRotAngle);
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) <<  "DEBUG ossimLandSatModel::writeGeomTemplate: returning... " << std::endl;
+   return;
+}
+
+//*****************************************************************************
+// PROTECTED METHOD:
+//*****************************************************************************
+void  ossimLandSatModel::updateModel()
+{
+   //***
+   // Update the geometry...
+   // Adjusted = Initial + adj_parm[i]*adj_sigma[i]
+   // Some parameters have a zero initial value and that term is not included.
+   //***
+  theIntrackOffset = computeParameterOffset(INTRACK_OFFSET);
+  theCrtrackOffset = computeParameterOffset(CRTRACK_OFFSET);
+  theLineGsdCorr   = computeParameterOffset(LINE_GSD_CORR);
+  theSampGsdCorr   = computeParameterOffset(SAMP_GSD_CORR);
+  theRollOffset    = computeParameterOffset(ROLL_OFFSET);
+  theYawOffset     = computeParameterOffset(YAW_OFFSET);
+  theYawRate       = computeParameterOffset(YAW_RATE);
+  theMapRotation   = computeParameterOffset(MAP_ROTATION);
+
+//   int numParams = getNumberOfAdjustableParameters();
+   //***
+   // Now the initial values have been updated, zero out the adjustment:
+   //***
+//    for (int i=0; i<numParams; i++)
+//       setAdjustableParameter(i, 0.0);
+
+   //***
+   // Compute image-common values dependent on adjustable parameters:
+   //***
+   if (theProjectionType == UTM_ORBIT)
+   {
+      theMapAzimCos = cosd(-theMapAzimAngle + theMapRotation);
+      theMapAzimSin = sind(-theMapAzimAngle + theMapRotation);
+   }
+   else
+   {
+      theMapAzimCos = cosd(theMapAzimAngle + theMapRotation);
+      theMapAzimSin = sind(theMapAzimAngle + theMapRotation);
+   }
+
+   double cos = cosd(theRollOffset);
+   double sin = sind(theRollOffset);
+   theRollRotMat = ossimMatrix3x3::create( 1.0, 0.0, 0.0,
+                                           0.0, cos,-sin,
+                                           0.0, sin, cos);
+   
+   
+}
+//*****************************************************************************
+// PRIVATE METHOD: ossimLandSatModel::initAdjustableParameters()
+//  
+//  This method initializes the base class adjustable parameter and associated
+//  sigmas arrays with quantities specific to this model.
+//
+//  
+//*****************************************************************************
+void ossimLandSatModel::initAdjustableParameters()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::initAdjustableParameters: entering..." << std::endl;
+
+   //
+   // Allocate storage for adjustables and assign their names and units strings
+   //
+   resizeAdjustableParameterArray(NUM_ADJUSTABLE_PARAMS);
+   int numParams = getNumberOfAdjustableParameters();
+   //***
+   // Initialize base-class adjustable parameter array:
+   //***
+   for (int i=0; i<numParams; i++)
+   {
+      setAdjustableParameter(i, 0.0);
+      setParameterDescription(i, PARAM_NAMES[i]);
+      setParameterUnit(i,PARAM_UNITS[i]);
+   }
+   //***
+   // Initialize base-class parameter sigma array:
+   //***
+   setParameterSigma(INTRACK_OFFSET, 500.0);
+   setParameterSigma(CRTRACK_OFFSET, 500.0);
+   setParameterSigma(LINE_GSD_CORR, 0.005);  
+   setParameterSigma(SAMP_GSD_CORR, 0.005);  
+   setParameterSigma(ROLL_OFFSET, 0.01);  
+   setParameterSigma(YAW_OFFSET, 0.01);  
+   setParameterSigma(YAW_RATE, 0.05);  
+   setParameterSigma(MAP_ROTATION, 0.1);
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimLandSatModel::initAdjustableParameters: returning..." << std::endl;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/ossimLandSatModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/ossimLandSatModel.h
new file mode 100644
index 0000000000..c67776a031
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/landsat/ossimLandSatModel.h
@@ -0,0 +1,191 @@
+//*****************************************************************************
+// FILE: ossimLandSatModel.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// DESCRIPTION: Contains declaration of LandSat sensor model class.
+//
+// SOFTWARE HISTORY:
+//   01AUG2002  Oscar Kramer, ImageLinks
+//              Initial coding.
+//   21NOV2002  Oscar Kramer, ImageLinks
+//              Modified selection of adjustable parameters..
+//
+//*****************************************************************************
+//  $Id: ossimLandSatModel.h,v 1.19 2005/05/12 19:55:13 gpotts Exp $
+
+#ifndef ossimLandSatModel_HEADER
+#define ossimLandSatModel_HEADER
+
+#include <projections/sensor_modeling/ossimSensorModel.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimEcefRay.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimMatrix3x3.h>
+#include <iostream>
+
+class ossimFfL7;
+class ossimString;
+class ossimMapProjection;
+
+//******************************************************************************
+//*
+//* CLASS:  ossimLandSatModel
+//*
+//*******************************************************************************
+class OSSIMDLLEXPORT ossimLandSatModel : public ossimSensorModel
+{
+public:
+   /*!
+    * CONSTRUCTORS:
+    */
+   ossimLandSatModel();
+   ossimLandSatModel(const ossimFfL7& head);
+   ossimLandSatModel(const ossimFilename& init_file);
+   ossimLandSatModel(const ossimKeywordlist& geom_kwl);
+   ossimLandSatModel(const ossimLandSatModel& rhs);
+   
+   virtual ~ossimLandSatModel();
+
+   enum ProjectionType
+   {
+      UNKNOWN_PROJECTION = 0,
+      UTM_MAP,
+      UTM_ORBIT,
+      SOM_MAP,
+      SOM_ORBIT
+   };
+   
+   enum AdjustParamIndex
+   {
+      INTRACK_OFFSET = 0,
+      CRTRACK_OFFSET,
+      LINE_GSD_CORR,
+      SAMP_GSD_CORR,
+      ROLL_OFFSET,
+      YAW_OFFSET,
+      YAW_RATE,
+      MAP_ROTATION,
+      NUM_ADJUSTABLE_PARAMS // not an index
+   };
+   
+   /*!
+    * Returns pointer to a new instance, copy of this.
+    */
+   virtual ossimObject* dup() const { return 0; } // TBR
+   
+   /*!
+    * Extends base-class implementation. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   /*!
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files. Returns true if successful.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /*!
+    * Writes a template of geom keywords processed by loadState and saveState
+    * to output stream.
+    */
+   static void writeGeomTemplate(ostream& os);
+   
+   //***
+   // Overrides base class pure virtual.
+   //***
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const double&   heightEllipsoid,
+                                        ossimGpt&       worldPoint) const;
+   
+   /*!
+    * Given an image point, returns a ray originating at some arbitrarily high
+    * point (ideally at the sensor position) and pointing towards the target.
+    */
+   virtual void imagingRay(const ossimDpt& image_point,
+                           ossimEcefRay&   image_ray) const;
+
+   /*!
+    * Following a change to the adjustable parameter set, this virtual
+    * is called to permit instances to compute derived quantities after
+    * parameter change.
+    */
+   virtual void updateModel();
+
+protected:
+
+   /*!
+    * Initializes the model given a fast format header.
+    */
+   void initFromHeader(const ossimFfL7& head);
+   
+   virtual void initAdjustableParameters();
+   void initMapProjection();
+
+   //***
+   // Image constant parameters:
+   //***
+   double           theIllumAzimuth;  
+   double           theIllumElevation;
+   double           theOrbitAltitude;
+   double           theOrbitInclination;
+   int              theMapZone;
+   ossimDpt         theMapOffset;
+   int              theWrsPathNumber;
+   int              theWrsRowNumber;    
+   double           theMeridianalAngle;   
+   double           thePositionError;
+
+   ProjectionType       theProjectionType;
+   ossimMapProjection*  theMapProjection;
+
+   double           theMapAzimAngle; 
+   double           theMapAzimCos;    
+   double           theMapAzimSin;
+   double           theMap2IcRotAngle;
+   double           theMap2IcRotCos;
+   double           theMap2IcRotSin;
+   
+   //***
+   // Adjustable parameters:
+   //***
+   double           theIntrackOffset;
+   double           theCrtrackOffset;
+   double           theLineGsdCorr;   
+   double           theSampGsdCorr;   
+   double           theRollOffset;
+   double           theYawOffset; 
+   double           theYawRate; 
+   double           theMapRotation; 
+
+   //***
+   // Quantities derived from the adjustable parameters:
+   //***
+   NEWMAT::Matrix   theRollRotMat;
+   
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimAdjMapModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimAdjMapModel.cpp
new file mode 100644
index 0000000000..5f4b9ddc16
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimAdjMapModel.cpp
@@ -0,0 +1,416 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, Oscar Kramer, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Oscar Kramer
+//
+// Description:
+// 
+// Special "sensor model" that provides a conventional map projection but
+// with additional capability for adjusting the map x,y coordinates with
+// offset, scale, and rotation transform.  Funtions to control notifications,
+// information and error output.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimAdjMapModel.cpp,v 1.2 2005/05/12 19:55:13 gpotts Exp $
+
+#include <projections/sensor_modeling/ossimAdjMapModel.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <base/common/ossimKeywordNames.h>
+#include <projections/factory/ossimMapProjectionFactory.h>
+#include <elevation/ossimElevManager.h>
+
+// Geometry File Keywords:
+static const char* PARAMETER_KEYWORDS[] = {"map_offset_x",
+                                           "map_offset_y",
+                                           "map_rotation",
+                                           "map_scale_x",
+                                           "map_scale_y"};
+static const char* MAP_PROJ_FILE_KW    = "map_proj_filename";
+
+RTTI_DEF1(ossimAdjMapModel, "ossimAdjMapModel", ossimSensorModel);
+
+//----------------------------------------------------------------------------
+//! Constructs to uninitialized state (needed by factory).
+//----------------------------------------------------------------------------
+
+ossimAdjMapModel::ossimAdjMapModel()
+   :
+   ossimSensorModel(),
+   theAdjParams(NUM_ADJ_PARAMS),
+   theMapProjection(),
+   theCosTheta(0.0),
+   theSinTheta(0.0)
+{
+   theImageSize = ossimIpt(0,0);
+   initAdjustableParameters();
+   theErrorStatus++;
+}
+
+//----------------------------------------------------------------------------
+//! Constructs with map projection and image rectangle size.
+//----------------------------------------------------------------------------
+
+ossimAdjMapModel::ossimAdjMapModel(ossimMapProjection* map_proj,
+                                   const ossimIpt& image_size)
+   :
+   ossimSensorModel(),
+   theAdjParams(NUM_ADJ_PARAMS),
+   theMapProjection(map_proj),
+   theCosTheta(0.0),
+   theSinTheta(0.0)
+{
+   initializeFromMap();
+   theImageSize = image_size;
+   initAdjustableParameters();
+}
+
+//----------------------------------------------------------------------------
+//! Copy constructor
+//----------------------------------------------------------------------------
+
+ossimAdjMapModel::ossimAdjMapModel(const ossimAdjMapModel& copy_this)
+   :
+   ossimSensorModel(copy_this),
+   theAdjParams(NUM_ADJ_PARAMS),
+   theMapProjection(copy_this.theMapProjection),
+   theCosTheta(0.0),
+   theSinTheta(0.0)
+{
+   theAdjParams = copy_this.theAdjParams;
+}
+
+//----------------------------------------------------------------------------
+//! Constructs from Geom KWL
+//----------------------------------------------------------------------------
+ossimAdjMapModel::ossimAdjMapModel(const ossimKeywordlist& kwl,
+                                   const char* prefix)
+   :
+   ossimSensorModel(kwl),
+   theAdjParams(NUM_ADJ_PARAMS),
+   theMapProjection(),
+   theCosTheta(0.0),
+   theSinTheta(0.0)      
+                
+{
+   initAdjustableParameters();
+   loadState(kwl, prefix);
+}
+
+//----------------------------------------------------------------------------
+//! Constructs from Geom KWL
+//----------------------------------------------------------------------------
+
+ossimAdjMapModel::ossimAdjMapModel(const ossimFilename& kwl_filename)
+   :
+   ossimSensorModel(),
+   theAdjParams(NUM_ADJ_PARAMS),
+   theMapProjection(),
+   theCosTheta(0.0),
+   theSinTheta(0.0)      
+{
+   initAdjustableParameters();
+   ossimKeywordlist kwl (kwl_filename);
+   loadState(kwl);
+}
+
+//----------------------------------------------------------------------------
+//! Initializes base class data members after map model established. Returns TRUE if all's well.
+//----------------------------------------------------------------------------
+bool ossimAdjMapModel::initializeFromMap()
+{
+   if (!theMapProjection)
+   {
+      theErrorStatus++;
+      return false;
+   }
+   theSensorID = "AdjMapModel";
+   theGSD = theMapProjection->getMetersPerPixel();
+   theMeanGSD = 0.5*(theGSD.x + theGSD.y);
+   theRefGndPt = theMapProjection->origin();
+
+   return true;
+}
+
+//----------------------------------------------------------------------------
+//! Destructor
+//----------------------------------------------------------------------------
+ossimAdjMapModel::~ossimAdjMapModel()
+{
+   theAdjParams.CleanUp();
+}
+
+//----------------------------------------------------------------------------
+//! Initializes adjustable parameters to their default values.
+//! Overrides ossimAdjustableParameterInterface virtual method.
+//----------------------------------------------------------------------------
+void ossimAdjMapModel::initAdjustableParameters()
+{
+   // Initialize this adjustment as the initial geometry "adjustment":
+   removeAllAdjustments();
+   newAdjustment(NUM_ADJ_PARAMS);
+   setAdjustmentDescription("Initial Geometry");
+
+   // Initialize each adjustable parameter for this initial:
+   setAdjustableParameter (OFFSET_X, 0.0, 1.0);
+   setParameterDescription(OFFSET_X, "map_offset_x");
+   setParameterCenter     (OFFSET_X, 0.0);
+
+   setAdjustableParameter (OFFSET_Y, 0.0, 1.0);
+   setParameterDescription(OFFSET_Y, "map_offset_y");
+   setParameterCenter     (OFFSET_Y, 0.0);
+
+   setAdjustableParameter (ROTATION, 0.0, 1.0);
+   setParameterDescription(ROTATION, "map_rotation");
+   setParameterCenter     (ROTATION, 0.0);
+
+   setAdjustableParameter (SCALE_X, 0.0, 1.0);
+   setParameterDescription(SCALE_X, "map_scale_x");
+   setParameterCenter     (SCALE_X, 1.0);
+
+   setAdjustableParameter (SCALE_Y, 0.0, 1.0);
+   setParameterDescription(SCALE_Y, "map_scale_y");
+   setParameterCenter     (SCALE_Y, 1.0);
+
+   updateModel();
+}
+
+//----------------------------------------------------------------------------
+//! Following a change to the adjustable parameter set, this virtual is called
+//! to permit instances to compute derived quantities after parameter change.
+//----------------------------------------------------------------------------
+void ossimAdjMapModel::updateModel()
+{
+   for (int i=0; i<NUM_ADJ_PARAMS; i++)
+      theAdjParams[i] = computeParameterOffset(i);
+
+   theCosTheta = cosd(theAdjParams[ROTATION]);
+   theSinTheta = sind(theAdjParams[ROTATION]);
+}
+
+//----------------------------------------------------------------------------
+//! Overrides base class pure virtual.
+//----------------------------------------------------------------------------
+void ossimAdjMapModel::lineSampleHeightToWorld(const ossimDpt& image_point,
+                                     const double&   heightEllipsoid,
+                                     ossimGpt&       worldPoint) const
+{
+   // Just call other transform method 
+   // Check for bad map projection pointer:
+   if (!theMapProjection)
+   {
+      worldPoint = ossimGpt(OSSIM_NAN, OSSIM_NAN, OSSIM_NAN);
+      return;
+   }
+
+   // Adjust image point by transform:
+   double x = theAdjParams[SCALE_X]*(image_point.x - theAdjParams[OFFSET_X]);
+   double y = theAdjParams[SCALE_Y]*(image_point.y - theAdjParams[OFFSET_Y]);
+   ossimDpt adjusted_point(x*theCosTheta + y*theSinTheta, 
+                           y*theCosTheta - x*theSinTheta);
+
+   // Obtain ground point given adjusted image point:
+   theMapProjection->lineSampleHeightToWorld(adjusted_point,
+                                             heightEllipsoid,
+                                             worldPoint);
+   worldPoint.height(heightEllipsoid);
+}
+
+//----------------------------------------------------------------------------
+//! Overrides base class virtual.
+//----------------------------------------------------------------------------
+void ossimAdjMapModel::lineSampleToWorld(const ossimDpt& image_point,
+                                         ossimGpt&       worldPoint) const
+{
+   lineSampleHeightToWorld(image_point, 0.0, worldPoint);
+   if (!worldPoint.hasNans())
+   {
+//      worldPoint.height(theElevation->getHeightAboveEllipsoid(worldPoint));
+   }
+}
+
+//----------------------------------------------------------------------------
+//! Rigorous inverse transform implented, overrides base-class' iterative
+//! solution.
+//----------------------------------------------------------------------------
+void ossimAdjMapModel::worldToLineSample(const ossimGpt& world_point,
+                                         ossimDpt&       image_point) const
+{
+   // Check for bad map projection pointer:
+   if (!theMapProjection)
+   {
+      image_point = ossimDpt(OSSIM_NAN, OSSIM_NAN);
+      return;
+   }
+
+   // Obtain non-adjusted image point given ground point:
+   ossimDpt p1;
+   theMapProjection->worldToLineSample(world_point, p1);
+
+   // Adjust image point by transform:
+   ossimDpt p2 (p1.x*theCosTheta - p1.y*theSinTheta, 
+                p1.y*theCosTheta + p1.x*theSinTheta);
+   image_point.x = p2.x/theAdjParams[SCALE_X] + theAdjParams[OFFSET_X];
+   image_point.y = p2.y/theAdjParams[SCALE_Y] + theAdjParams[OFFSET_Y];
+}
+
+//----------------------------------------------------------------------------
+//! Fulfills ossimObject base-class pure virtuals. Saves geometry
+//! KWL files. Returns true if successful.
+//----------------------------------------------------------------------------
+bool ossimAdjMapModel::saveState(ossimKeywordlist& kwl, const char* prefix) const
+{
+   kwl.add(prefix, ossimKeywordNames::TYPE_KW, "ossimAdjMapModel");
+
+   // Hand off to base class for common stuff:
+   ossimSensorModel::saveState(kwl, prefix);
+
+   // Save off data members:
+   for (int i=0; i<NUM_ADJ_PARAMS; i++)
+      kwl.add(prefix, PARAMETER_KEYWORDS[i], theAdjParams[i]);
+
+   // Save off map projection info:
+   if (theMapProjection.valid())
+   {
+      theMapProjection->saveState(kwl, prefix);
+   }
+
+   return true;
+}
+
+//----------------------------------------------------------------------------
+//! Fulfills ossimObject base-class pure virtuals. Loads geometry
+//! KWL files. Returns true if successful.
+//----------------------------------------------------------------------------
+bool ossimAdjMapModel::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+   static const ossimString MODULE ("ossimAdjMapModel::loadState() -- ");
+   bool success = true;
+   const char* value_str;
+   double value;
+   ossimString error_msg (MODULE+"Error encountered reading keyword: ");
+
+   try
+   {
+      // Verify correct model type:
+      value_str = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+      if ((!value_str) || (strcmp(value_str, TYPE_NAME(this))))
+      {
+         throw (error_msg + ossimKeywordNames::TYPE_KW);
+      }
+
+      //---
+      // Instantiate the map projection via the factory if one has not been
+      // initialized yet:
+      //---
+      if (!theMapProjection)
+      {
+         // should find the map projection filename in the KWL:
+         value_str = kwl.find(prefix, MAP_PROJ_FILE_KW);
+         if (!value_str)
+         {
+            throw (error_msg + MAP_PROJ_FILE_KW);
+         }
+         theMapProjection = PTR_CAST(ossimMapProjection,
+            ossimMapProjectionFactory::instance()->createProjection(ossimKeywordlist(value_str)));
+         if (!theMapProjection)
+         {
+            throw "Error encountered instantiating map ";
+         }
+      }
+
+      // Everything OK so far, just load in the adjustable parameters. This involves modifying the
+      // center value of the bsae class adjustable parameter:
+      for (int i=0; i<NUM_ADJ_PARAMS; i++)
+      {
+         value_str = kwl.find(prefix, PARAMETER_KEYWORDS[i]);
+         if (!value_str)
+         {
+            throw (error_msg + PARAMETER_KEYWORDS[i]).chars();
+         }
+         value = atof(value_str);
+         setParameterCenter(i, value);
+      }
+   }
+   catch (const char* message)
+   {
+      theErrorStatus++;
+      success = false;
+   }
+
+   //---
+   // updateModel() reads the base class adjustable parameters and initializes
+   // theAdjParams
+   // with the unnormalized, biased (to the "center" set above) quantities
+   // used in the projection:
+   //---
+   if (success)
+   {
+      initializeFromMap();
+      updateModel();
+   }
+
+   return success;
+}  
+
+//----------------------------------------------------------------------------
+//! Writes a template of geom keywords processed by loadState and saveState to
+//! output stream.
+//----------------------------------------------------------------------------
+void ossimAdjMapModel::writeGeomTemplate(ostream& os)
+{
+   os <<
+      "//*****************************************************************\n"
+      "// Template for Adjustable Map Model keywordlist\n"
+      "//*****************************************************************\n"
+      << ossimKeywordNames::TYPE_KW << ": " << "ossimFcsiModel" << endl;
+
+   ossimSensorModel::writeGeomTemplate(os);
+
+   os << "//***\n"
+      << "// Derived-class AdjMapModel Keywords:\n"
+      << "//***\n"
+      << PARAMETER_KEYWORDS[OFFSET_X] << ": <east offset meters>\n"
+      << PARAMETER_KEYWORDS[OFFSET_Y] << ": <north offset meters>\n"
+      << PARAMETER_KEYWORDS[ROTATION] << ": <degrees CW>\n"
+      << PARAMETER_KEYWORDS[SCALE_X]  << ": <ratio>\n"
+      << PARAMETER_KEYWORDS[SCALE_Y]  << ": <ratio>\n"
+      << endl;
+
+   return;
+}
+
+//----------------------------------------------------------------------------
+//! Extends base-class implementation. Dumps contents of object to ostream.
+//----------------------------------------------------------------------------
+std::ostream& ossimAdjMapModel::print(std::ostream& out) const
+{      
+   ossimSensorModel::print(out);
+   for (int i=0; i<NUM_ADJ_PARAMS; i++)
+      out << PARAMETER_KEYWORDS[i]  << ": " << theAdjParams[i] << endl;
+   out << endl;
+
+   return out;
+}
+
+//----------------------------------------------------------------------------
+//! Fetches the GSD from the internal map projection.
+//----------------------------------------------------------------------------
+ossimDpt ossimAdjMapModel::getMetersPerPixel () const
+{
+   if (theMapProjection.valid())
+   {
+      return theMapProjection->getMetersPerPixel();
+   }
+   
+   return ossimDpt(0,0);
+}
+
+ossimObject* ossimAdjMapModel::dup() const
+{
+   return new ossimAdjMapModel(*this);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimAdjMapModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimAdjMapModel.h
new file mode 100644
index 0000000000..68a6a81ed9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimAdjMapModel.h
@@ -0,0 +1,132 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, Oscar Kramer, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Oscar Kramer
+//
+// Description:
+// 
+// Special "sensor model" that provides a conventional map projection but
+// with additional capability for adjusting the map x,y coordinates with
+// offset, scale, and rotation transform.  Funtions to control notifications,
+// information and error output.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimAdjMapModel.h,v 1.2 2005/05/12 19:55:13 gpotts Exp $
+#ifndef ossimAdjMapModel_HEADER
+#define ossimAdjMapModel_HEADER
+
+#include <matrix/newmat.h>
+#include <projections/sensor_modeling/ossimSensorModel.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/common/ossimRefPtr.h>
+
+using namespace NEWMAT;
+
+class ossimMapProjection;
+
+//----------------------------------------------------------------------------
+//  CLASS DESCRIPTION: ossimAdjMapModel
+//! Special "sensor model" that provides a conventional map projection but with
+//  additional
+//! capability for adjusting the map x,y coordinates with offset, scale, and
+//  rotation transform.
+//----------------------------------------------------------------------------
+class OSSIMDLLEXPORT ossimAdjMapModel : public ossimSensorModel
+{
+public:
+   //! Constructs to uninitialized state (needed by factory).
+   ossimAdjMapModel();
+
+   //! Constructs with map projection and image rectangle size.
+   ossimAdjMapModel(ossimMapProjection* map_proj, const ossimIpt& image_size);
+
+   //! Copy constructor
+   ossimAdjMapModel(const ossimAdjMapModel& copy_this);
+
+   //! Constructs given geom KWL.
+   ossimAdjMapModel(const ossimKeywordlist& kwl, const char* prefix);
+
+   //! Constructs given geom filename.
+   ossimAdjMapModel(const ossimFilename& geom_filename);
+
+   //! Destructor only deletes the map projection.
+   virtual ~ossimAdjMapModel();
+
+   //! Initializes base class data members after map model established.
+   //  Returns TRUE if all's well.
+   bool initializeFromMap();
+
+   //! Returns pointer to a new instance, copy of this.
+   virtual ossimObject* dup() const;
+   
+   //! Extends base-class implementation. Dumps contents of object to ostream.
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   //! Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+   //! KWL files. Returns true if successful.
+   virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0) const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+   
+   //! Writes a template of geom keywords processed by loadState and saveState
+   //  to output stream.
+   static void writeGeomTemplate(ostream& os);
+   
+   //! Overrides base class pure virtual.
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const double&   heightEllipsoid,
+                                        ossimGpt&       worldPoint) const;
+   
+   //! Overrides base class virtual.
+   virtual void lineSampleToWorld(const ossimDpt& image_point,
+                                  ossimGpt&       worldPoint) const;
+   
+   //! Rigorous inverse transform implented, overrides base-class' iterative
+   //  solution.
+   virtual void worldToLineSample(const ossimGpt& world_point,
+                                  ossimDpt&       image_point) const;
+      
+   //! Following a change to the adjustable parameter set, this virtual is
+   //  called to permit 
+   //! instances to compute derived quantities after parameter change.
+   virtual void updateModel();
+
+   //! Initializes adjustable parameters to their default values.
+   //! Overrides ossimAdjustableParameterInterface virtual method.
+   virtual void initAdjustableParameters();
+
+   //! Fetches the GSD from the internal map projection.
+   virtual ossimDpt 	getMetersPerPixel () const;
+
+   //! Enumeration for adjustable parameter positions in theAdjParams vector
+   enum AdjParamIndex
+   {
+      OFFSET_X = 0,         // meters
+      OFFSET_Y,             // meters
+      ROTATION,             // degrees CCW
+      SCALE_X,              // ratio
+      SCALE_Y,              // ratio
+      NUM_ADJ_PARAMS // not an index
+   };
+
+private:
+   //! This is the vector of UNNORMALIZED, BIASED parameters as used in the
+   //! model. The collection of normalized, 0-biased, parameters used in
+   //! registration are found in the
+   //! ossimAdjustableParameterInterface and related classes.
+   //!  The quantities here are computed given the base class quantities.
+   ColumnVector                    theAdjParams;
+
+   ossimRefPtr<ossimMapProjection> theMapProjection;
+   double                          theCosTheta;
+   double                          theSinTheta;
+
+TYPE_DATA
+};
+
+#endif /* End of "#ifndef ossimAdjMapModel_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimLensDistortion.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimLensDistortion.cpp
new file mode 100644
index 0000000000..6c041c322e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimLensDistortion.cpp
@@ -0,0 +1,48 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LGPL
+// 
+// Author:  Garrett Potts
+//
+// Description:
+//
+// ossimLensDistortion
+//*******************************************************************
+//  $Id: ossimLensDistortion.cpp,v 1.4 2005/06/24 17:52:08 gpotts Exp $
+#include <sstream>
+#include "ossimLensDistortion.h"
+#include <base/data_types/ossimKeywordlist.h>
+
+RTTI_DEF1(ossimLensDistortion, "ossimLensDistortion", ossim2dTo2dTransform);
+
+bool ossimLensDistortion::saveState(ossimKeywordlist& kwl,
+                                    const char* prefix)const
+{
+   ossim2dTo2dTransform::saveState(kwl, prefix);
+   
+   kwl.add(prefix,
+           "center",
+           ossimString::toString(theCenter.x) + " " + ossimString::toString(theCenter.y),
+           true);
+
+   return true;
+}
+
+bool ossimLensDistortion::loadState(const ossimKeywordlist& kwl,
+                                    const char* prefix)
+{
+   const char* center = kwl.find(prefix, "center");
+   theCenter.x = 0.0;
+   theCenter.y = 0.0;
+   
+   if(center)
+   {
+      istringstream in(center);
+      
+      in >> theCenter.x >> theCenter.y;
+   }
+
+   return ossim2dTo2dTransform::loadState(kwl, prefix);
+
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimLensDistortion.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimLensDistortion.h
new file mode 100644
index 0000000000..77bc605f03
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimLensDistortion.h
@@ -0,0 +1,52 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// LGPL
+// 
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// ossimLensDistortion
+//*******************************************************************
+//  $Id: ossimLensDistortion.h,v 1.3 2005/06/24 17:52:08 gpotts Exp $
+
+#ifndef ossimLensDistortion_HEADER
+#define ossimLensDistortion_HEADER
+#include <base/misc/ossim2dTo2dTransform.h>
+class OSSIM_DLL ossimLensDistortion : public ossim2dTo2dTransform
+{
+public:
+   ossimLensDistortion(const ossimDpt& callibrartedCenter=ossimDpt(0,0))
+      :theCenter(callibrartedCenter)
+   {
+   }
+   void setCenter(const ossimDpt& center)
+   {
+      theCenter = center;
+   }
+   virtual void forward(const ossimDpt& input,
+                        ossimDpt& output) const
+   {
+      distort(input, output);
+   }
+   virtual void inverse(const ossimDpt& input,
+                        ossimDpt& output)
+   {
+      undistort(input, output);
+   }
+   virtual void distort(const ossimDpt& input, ossimDpt& output)const=0;
+   virtual void undistort(const ossimDpt& input, ossimDpt& output)const=0;
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = 0)const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = 0);
+   
+protected:
+   ossimDpt theCenter;
+
+TYPE_DATA   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimMeanRadialLensDistortion.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimMeanRadialLensDistortion.cpp
new file mode 100644
index 0000000000..ffaa9bfefd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimMeanRadialLensDistortion.cpp
@@ -0,0 +1,267 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// MeanRadialLens distortion.
+//*******************************************************************
+//  $Id: ossimMeanRadialLensDistortion.cpp,v 1.9 2005/06/24 17:52:08 gpotts Exp $
+#include "ossimMeanRadialLensDistortion.h"
+
+#include <base/common/ossimCommon.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+RTTI_DEF1(ossimMeanRadialLensDistortion, "ossimMeanRadialLensDistortion", ossimLensDistortion);
+
+void ossimMeanRadialLensDistortion::solveCoefficients(const std::vector<double>& radialDistance,
+                                                      const std::vector<double>& radialDistortion)
+{
+   NEWMAT::ColumnVector distanceVec(radialDistance.size());
+   NEWMAT::ColumnVector distortionVec(radialDistortion.size());
+   ossim_uint32 idx = 0;
+
+   theCoefficients[0] = 0;
+   theCoefficients[1] = 0;
+   theCoefficients[2] = 0;
+   theCoefficients[3] = 0;
+   if(radialDistance.size() == radialDistortion.size())
+   {
+      for(idx = 0; idx < radialDistance.size();++idx)
+      {
+         distanceVec[idx]   = radialDistance[idx];
+         distortionVec[idx] = radialDistortion[idx];
+      }
+      solveCoefficients(distanceVec,
+                        distortionVec);
+   }
+}
+
+void ossimMeanRadialLensDistortion::solveCoefficients(const NEWMAT::ColumnVector &radialDistance,
+                                                      const NEWMAT::ColumnVector &radialDistortion)
+{
+   NEWMAT::ColumnVector coefficients(4);
+   theCoefficients.resize(4);
+   theCoefficients[0] = 0;
+   theCoefficients[1] = 0;
+   theCoefficients[2] = 0;
+   theCoefficients[3] = 0;
+   if((radialDistance.Nrows() == 0) ||
+      (radialDistortion.Nrows() == 0))
+   {
+      return;
+   }
+   if(radialDistance.Nrows() == radialDistortion.Nrows())
+   {
+      NEWMAT::Matrix M(radialDistance.Nrows(), 4);
+      
+      // set up the matrix
+      for(long row = 0; row < M.Nrows(); row++)
+      {
+         M[row][0] = radialDistance[row];
+         M[row][1] = M[row][0]*radialDistance[row]*radialDistance[row];
+         M[row][2] = M[row][1]*radialDistance[row]*radialDistance[row];
+         M[row][3] = M[row][2]*radialDistance[row]*radialDistance[row];
+      }
+      
+      NEWMAT::Matrix mTranspose = M.t();
+      coefficients = ((mTranspose*M).i())*(mTranspose*radialDistortion);
+
+      theCoefficients[0] = coefficients[0];
+      theCoefficients[1] = coefficients[1];
+      theCoefficients[2] = coefficients[2];
+      theCoefficients[3] = coefficients[3];
+   }
+   else
+   {
+   }
+}
+
+double ossimMeanRadialLensDistortion::deltaR(double radius)const
+{
+  double r3 = radius*radius*radius;
+  double r5 = r3*radius*radius;
+  double r7 = r5*radius*radius;
+
+  return (radius*theCoefficients[0] +r3*theCoefficients[1] + r5*theCoefficients[2] + r7*theCoefficients[3]);
+}
+
+void ossimMeanRadialLensDistortion::distort(const ossimDpt& input, ossimDpt& output)const
+{
+   int iters = 0;
+
+   //***
+   // Begin with guess. Forward transform is defined as trasforming left to
+   // right. We are therefore solving for left:
+   //***
+   ossimDpt left (input);
+   ossimDpt left_dx;
+   ossimDpt left_dy;
+   ossimDpt right;
+   ossimDpt right_dx;
+   ossimDpt right_dy;
+   ossimDpt dr_dx;
+   ossimDpt dr_dy;
+   ossimDpt r_diff;
+   ossimDpt l_diff;
+   double inverse_norm;
+   
+   //***
+   // Begin iterations:
+   //***
+   do
+   {
+      //***
+      // establish perturbed image points about the guessed point:
+      //***
+      left_dx.x = left.x + 1.0;
+      left_dx.y = left.y;
+      left_dy.x = left.x;
+      left_dy.y = left.y + 1.0;
+      
+      //***
+      // Compute numerical partials at current guessed point:
+      //***
+      undistort(left,    right);
+      undistort(left_dx, right_dx);
+      undistort(left_dy, right_dy);
+
+      dr_dx.x = (right_dx.x - right.x); //e
+      dr_dx.y = (right_dx.y - right.y); //g
+      dr_dy.x = (right_dy.x - right.x); //f
+      dr_dy.y = (right_dy.y - right.y); //h
+
+      //***
+      // Test for convergence:
+      //***
+      r_diff = input - right;
+      
+      //***
+      // Compute linearized estimate of image point given gp delta:
+      //***
+      inverse_norm = dr_dy.u*dr_dx.v - dr_dx.u*dr_dy.v; // fg-eh
+      if (inverse_norm != 0)
+      {
+          l_diff.u = (-dr_dy.v*r_diff.u + dr_dy.u*r_diff.v)/inverse_norm;
+          l_diff.v = ( dr_dx.v*r_diff.u - dr_dx.u*r_diff.v)/inverse_norm;
+          left += l_diff;
+      }
+      else
+      {
+         l_diff.u = 0;
+         l_diff.v = 0;
+      }
+
+      iters++;
+      
+   } while (((fabs(l_diff.u) > theConvergenceThreshold) ||
+             (fabs(l_diff.v) > theConvergenceThreshold)) &&
+            (iters < theMaxIterations));
+
+
+   output = left;
+}
+
+void ossimMeanRadialLensDistortion::undistort(const ossimDpt& input, ossimDpt& output)const
+{
+   ossimDpt deltaPosition(input.x - theCenter.x,
+                          input.y - theCenter.y);
+   double r = sqrt(deltaPosition.x*deltaPosition.x + 
+                   deltaPosition.y*deltaPosition.y);
+   double deltaRadius = deltaR(r);
+   
+   if((fabs(r) <= FLT_EPSILON)||
+      (fabs(deltaRadius) <= FLT_EPSILON))
+   {
+      output = input;
+      return;
+   }
+   
+   double deltaX      = (deltaPosition.x*(deltaRadius/r)); 
+   double deltaY      = (deltaPosition.y*(deltaRadius/r)); 
+   
+   output.x = deltaPosition.x-deltaX;
+   output.y = deltaPosition.y-deltaY;
+}
+
+bool ossimMeanRadialLensDistortion::saveState(ossimKeywordlist& kwl,
+                                              const char* prefix)const
+{
+   kwl.add(prefix,
+           "k0",
+           theCoefficients[0],
+           true);
+   
+   kwl.add(prefix,
+           "k1",
+           theCoefficients[1],
+           true);
+   kwl.add(prefix,
+           "k2",
+           theCoefficients[2],
+           true);
+   
+   kwl.add(prefix,
+           "k3",
+           theCoefficients[3],
+           true);
+
+   return ossimLensDistortion::saveState(kwl, prefix);
+}
+
+bool ossimMeanRadialLensDistortion::loadState(const ossimKeywordlist& kwl,
+                                              const char* prefix)
+{
+   const char* k0 = kwl.find(prefix, "k0");
+   const char* k1 = kwl.find(prefix, "k1");
+   const char* k2 = kwl.find(prefix, "k2");
+   const char* k3 = kwl.find(prefix, "k3");
+
+   if(k1&&k2&&k3&&k3)
+   {
+      theCoefficients[0] = ossimString(k0).toDouble();
+      theCoefficients[1] = ossimString(k1).toDouble();
+      theCoefficients[2] = ossimString(k2).toDouble();
+      theCoefficients[3] = ossimString(k3).toDouble();
+   }
+   else
+   {
+      std::vector<double> distances;
+      std::vector<double> distortions;
+      ossim_uint32 idx = 0;
+      const char* distance   = kwl.find(prefix, "distance0");
+      const char* distortion = kwl.find(prefix, "distortion0");
+
+      while(distance&&distortion)
+      {
+         distances.push_back(ossimString(distance).toDouble());
+         distortions.push_back(ossimString(distortion).toDouble());
+         ++idx;
+         distance   = kwl.find(prefix,
+                               ossimString("distance")+ossimString::toString(idx));
+         distortion = kwl.find(prefix,
+                               ossimString("distortion")+ossimString::toString(idx));
+      }
+
+      solveCoefficients(distances, distortions);
+   }
+
+   return ossimLensDistortion::loadState(kwl, prefix);
+   
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimMeanRadialLensDistortion.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimMeanRadialLensDistortion.h
new file mode 100644
index 0000000000..c17f46ad1f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimMeanRadialLensDistortion.h
@@ -0,0 +1,120 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// LGPL
+// 
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+// MeanRadialLensDistortion
+//*******************************************************************
+//  $Id: ossimMeanRadialLensDistortion.h,v 1.4 2005/06/24 17:52:08 gpotts Exp $
+#ifndef ossimMeanRadialLensDistortion_HEADER
+#define ossimMeanRadialLensDistortion_HEADER
+#include <vector>
+#include "matrix/newmat.h"
+#include "base/data_types/ossimDpt.h"
+#include "ossimLensDistortion.h"
+class ossimMeanRadialLensDistortion : public ossimLensDistortion
+{
+public:
+   ossimMeanRadialLensDistortion()
+   {
+      theCoefficients.resize(4);
+      theCoefficients[0] = 0.0;
+      theCoefficients[1] = 0.0;
+      theCoefficients[2] = 0.0;
+      theCoefficients[3] = 0.0;
+   }
+
+  /*!
+   * Instantiate a ossimMeanRadialLens with the calibrated data.
+   * The data consists of the Principal point,
+   * focal distance, radialDistance measures for the distortion
+   * deltas, the radial distortion values.
+   * 
+   * example of construction:
+   *
+   * lets say we have the following:
+   *
+   * principal point = (.008 , -.001) mm
+   *
+   * and
+   *
+   * field angle       radial distance       deltaR (distortion)
+   *_____________________________________________________________
+   *  7.5 deg.             .004 mm             .0202 mm
+   *  15 deg.              .007 mm             .0411 mm
+   *  22.5 deg.            .007 mm             .0635 mm
+   *  :
+   *  :
+   *  :
+   *
+   * then construct the ossimMeanRadialLensDistortion class to construct the
+   * given focal length and principal point and the middle column as
+   * the radial distance column vector and the third column as the
+   * distortion values.
+   */
+/*    ossimMeanRadialLensDistortion(ossimDpt    calibratedPrincipalPoint, */
+/*                                  const NEWMAT::ColumnVector &radialDistance, */
+/*                                  const NEWMAT::ColumnVector &radialDistortion) */
+   ossimMeanRadialLensDistortion(ossimDpt    calibratedPrincipalPoint,
+                                 const NEWMAT::ColumnVector &radialDistance,
+                                 const NEWMAT::ColumnVector &radialDistortion)
+      :ossimLensDistortion(calibratedPrincipalPoint)
+  {
+     theCoefficients.resize(4);
+     solveCoefficients(radialDistance, radialDistortion);
+  }
+      
+  /*!
+   * Returns the coefficients (k1, k2, k3, k4) for the deltaR polynomial:
+   *
+   *    deltaR = k1*r + k2*r^3 + k3*r^5 + k4*r^7
+   */
+  const std::vector<double>& getCoefficients()const{return theCoefficients;}
+  std::vector<double>& getCoefficients(){return theCoefficients;}
+
+
+//  ossimDpt adjustPoint(const ossimDpt &position)const;
+  virtual std::ostream& print(std::ostream& out) const
+  {return out;}
+
+  /*!
+   * dletaR computes how much we should adjust r.  The
+   * return value is the adjustment amount.  This method is used
+   * by adjustPoint.
+   */
+  double deltaR(double r)const;
+
+  virtual void distort(const ossimDpt& input, ossimDpt& output)const;
+  virtual void undistort(const ossimDpt& input, ossimDpt& output)const;
+  
+  /*!
+   * solves the coefficients given the radial distances and distortion
+   * for each distance.
+   */
+  void solveCoefficients(const NEWMAT::ColumnVector &radialDistance,
+			 const NEWMAT::ColumnVector &radialDistortion);
+  /*!
+   * solves the coefficients given the radial distances and distortion
+   * for each distance.
+   */
+  void solveCoefficients(const std::vector<double>& radialDistance,
+			 const std::vector<double>& radialDistortion);
+  
+  virtual bool saveState(ossimKeywordlist& kwl,
+                         const char* prefix = 0)const;
+  
+  virtual bool loadState(const ossimKeywordlist& kwl,
+                         const char* prefix = 0);
+  
+protected:
+  std::vector<double> theCoefficients;
+  
+TYPE_DATA  
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimNitfMapModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimNitfMapModel.cpp
new file mode 100644
index 0000000000..29a818a98b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimNitfMapModel.cpp
@@ -0,0 +1,680 @@
+//*****************************************************************************
+// FILE: ossimNitfMapModel.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Doug Shibla (dshibla@imagelinks.com)
+//
+// DESCRIPTION: 
+//
+// LIMITATIONS: 
+//
+//*****************************************************************************
+
+#include <projections/sensor_modeling/ossimNitfMapModel.h>
+
+RTTI_DEF1(ossimNitfMapModel, "ossimNitfMapModel", ossimSensorModel);
+
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <stdio.h>
+#include <fstream>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimNitfMapModel:exec");
+static ossimTrace traceDebug ("ossimNitfMapModel:debug");
+
+static const char* PIAIMC_TAG  = "PIAIMC";
+static const char* USE26A_TAG  = "USE26A";
+static const char* USE00A_TAG  = "USE00A";
+static const char* IMAGE_ID_KW = "image_id";
+
+//*****************************************************************************
+//  DEFAULT CONSTRUCTOR: ossimNitfMapModel()
+//  
+//*****************************************************************************
+ossimNitfMapModel::ossimNitfMapModel()
+   : ossimSensorModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::ossimNitfMapModel: entering..." << std::endl;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::ossimNitfMapModel: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimNitfMapModel(filename)
+//  
+//  Constructs model from a filename. The file can be either a FF header file
+//  or a KWL file.
+//  
+//*****************************************************************************
+ossimNitfMapModel::ossimNitfMapModel(const ossimFilename& init_file)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::ossimNitfMapModel(init_file): entering..." << std::endl;
+
+   //***
+   // Open the NITF file:
+   //***
+   FILE* fptr = fopen (init_file.chars(), "r");
+   if (!fptr)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimNitfMapModel::ossimNitfMapModel(init_file): Could not open NITF file at: <" << init_file << ">."
+                                             << " Aborting with error..." << std::endl;
+      }
+      theErrorStatus = 1;
+      return;
+   }
+
+   //***
+   // Read a sufficient number of bytes to include USE tag:
+   //***
+   char* header = new char [6000];
+   fread(header, 6000, 1, fptr);
+   fclose(fptr);
+   fptr = 0;
+   //***
+   // Validate correct NITF version:
+   //***
+   if (strncmp(header, "NITF02.00", 9))
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::ossimNitfMapModel(init_file):"
+                                             << "\n\tFailed attempt to open <" << init_file
+                                             << "> as NITF2.00."<<endl;
+      }
+      theErrorStatus = 1;
+      return;
+   }
+
+   //***
+   // Fetch Image ID:
+   //***
+   char charbuf[80];
+   strncpy(charbuf, &header[447], 28);
+   charbuf[28] = '\0';
+   theImageID = charbuf;
+
+   //***
+   // Fetch Image Size:
+   //***
+   strncpy(charbuf, &header[737], 8);
+   charbuf[8] = '\0';
+   theImageSize.line = atoi(charbuf);
+   strncpy(charbuf, &header[745], 8);
+   charbuf[8] = '\0';
+   theImageSize.samp = atoi(charbuf);
+
+   
+   // Fetch Image Size:
+   ossimString coord;
+   strncpy(charbuf, &header[775], 1);
+   charbuf[1] = '\0';
+   coord = charbuf;
+   if (coord == "G")
+   {
+      double degreeLat;
+      double degreeLon;
+      double minute;
+      double second;
+      ossimString hemis;
+      
+      strncpy(charbuf, &header[780], 2);
+      charbuf[2] = '\0';
+      second = atof(charbuf);
+      second = second / 60;
+      strncpy(charbuf, &header[778], 2);
+      charbuf[2] = '\0';
+      minute = atof(charbuf);
+      minute = (minute + second) / 60;
+      strncpy(charbuf, &header[776], 2);
+      charbuf[2] = '\0';
+      degreeLat = atof(charbuf);
+      degreeLat = degreeLat + minute;
+      strncpy(charbuf, &header[782], 1);
+      charbuf[1] = '\0';
+      hemis = charbuf;
+      if (hemis == "S")
+         degreeLat = 0 - degreeLat;
+      strncpy(charbuf, &header[788], 2);
+      charbuf[2] = '\0';
+      second = atof(charbuf);
+      second = second / 60;
+      strncpy(charbuf, &header[786], 2);
+      charbuf[2] = '\0';
+      minute = atof(charbuf);
+      minute = (minute + second) / 60;
+      strncpy(charbuf, &header[783], 3);
+      charbuf[3] = '\0';
+      degreeLon = atof(charbuf);
+      degreeLon = degreeLon + minute;
+      strncpy(charbuf, &header[790], 1);
+      charbuf[1] = '\0';
+      hemis = charbuf;
+      if (hemis == "W")
+         degreeLon = 0 - degreeLon;
+      ossimDpt ip0 (degreeLon, degreeLat);
+      strncpy(charbuf, &header[795], 2);
+      charbuf[2] = '\0';
+      second = atof(charbuf);
+      second = second / 60;
+      strncpy(charbuf, &header[793], 2);
+      charbuf[2] = '\0';
+      minute = atof(charbuf);
+      minute = (minute + second) / 60;
+      strncpy(charbuf, &header[791], 2);
+      charbuf[2] = '\0';
+      degreeLat = atof(charbuf);
+      degreeLat = degreeLat + minute;
+      strncpy(charbuf, &header[797], 1);
+      charbuf[1] = '\0';
+      hemis = charbuf;
+      if (hemis == "S")
+         degreeLat = 0 - degreeLat;
+      strncpy(charbuf, &header[803], 2);
+      charbuf[2] = '\0';
+      second = atof(charbuf);
+      second = second / 60;
+      strncpy(charbuf, &header[801], 2);
+      charbuf[2] = '\0';
+      minute = atof(charbuf);
+      minute = (minute + second) / 60;
+      strncpy(charbuf, &header[798], 3);
+      charbuf[3] = '\0';
+      degreeLon = atof(charbuf);
+      degreeLon = degreeLon + minute;
+      strncpy(charbuf, &header[805], 1);
+      charbuf[1] = '\0';
+      hemis = charbuf;
+      if (hemis == "W")
+         degreeLon = 0 - degreeLon;
+      ossimDpt ip1 (degreeLon, degreeLat);
+      strncpy(charbuf, &header[810], 2);
+      charbuf[2] = '\0';
+      second = atof(charbuf);
+      second = second / 60;
+      strncpy(charbuf, &header[808], 2);
+      charbuf[2] = '\0';
+      minute = atof(charbuf);
+      minute = (minute + second) / 60;
+      strncpy(charbuf, &header[806], 2);
+      charbuf[2] = '\0';
+      degreeLat = atof(charbuf);
+      degreeLat = degreeLat + minute;
+      strncpy(charbuf, &header[812], 1);
+      charbuf[1] = '\0';
+      hemis = charbuf;
+      if (hemis == "S")
+         degreeLat = 0 - degreeLat;
+      strncpy(charbuf, &header[818], 2);
+      charbuf[2] = '\0';
+      second = atof(charbuf);
+      second = second / 60;
+      strncpy(charbuf, &header[816], 2);
+      charbuf[2] = '\0';
+      minute = atof(charbuf);
+      minute = (minute + second) / 60;
+      strncpy(charbuf, &header[813], 3);
+      charbuf[3] = '\0';
+      degreeLon = atof(charbuf);
+      degreeLon = degreeLon + minute;
+      strncpy(charbuf, &header[820], 1);
+      charbuf[1] = '\0';
+      hemis = charbuf;
+      if (hemis == "W")
+         degreeLon = 0 - degreeLon;
+      ossimDpt ip2 (degreeLon, degreeLat);
+      strncpy(charbuf, &header[825], 2);
+      charbuf[2] = '\0';
+      second = atof(charbuf);
+      second = second / 60;
+      strncpy(charbuf, &header[823], 2);
+      charbuf[2] = '\0';
+      minute = atof(charbuf);
+      minute = (minute + second) / 60;
+      strncpy(charbuf, &header[821], 2);
+      charbuf[2] = '\0';
+      degreeLat = atof(charbuf);
+      degreeLat = degreeLat + minute;
+      strncpy(charbuf, &header[827], 1);
+      charbuf[1] = '\0';
+      hemis = charbuf;
+      if (hemis == "S")
+         degreeLat = 0 - degreeLat;
+      strncpy(charbuf, &header[833], 2);
+      charbuf[2] = '\0';
+      second = atof(charbuf);
+      second = second / 60;
+      strncpy(charbuf, &header[831], 2);
+      charbuf[2] = '\0';
+      minute = atof(charbuf);
+      minute = (minute + second) / 60;
+      strncpy(charbuf, &header[828], 3);
+      charbuf[3] = '\0';
+      degreeLon = atof(charbuf);
+      degreeLon = degreeLon + minute;
+      strncpy(charbuf, &header[835], 1);
+      charbuf[1] = '\0';
+      hemis = charbuf;
+      if (hemis == "W")
+         degreeLon = 0 - degreeLon;
+      ossimDpt ip3 (degreeLon, degreeLat);
+      
+      theBoundGndPolygon
+         = ossimPolygon (ip0, ip1, ip2, ip3);
+   }
+   else
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimNitfMapModel::ossimNitfMapModel(init_file): Could not find the corner coordinates!! "
+                                            << " Aborting with error..." << std::endl;
+      }
+      theErrorStatus = 1;
+      return;
+   }
+   
+   
+   // Search for the PIAIMC Tag to fetch GSD:
+   const char* tag_ptr = strstr(header, PIAIMC_TAG);
+   if (tag_ptr)
+   {
+      //***
+      // Parse the tag for GSD (in inches):
+      //***
+      strncpy(charbuf, &tag_ptr[348], 7);
+      charbuf[7] = '\0';
+      theGSD.line = atof(charbuf)/12.0 * MTRS_PER_FT;
+      theGSD.samp = theGSD.line;
+   }
+   else
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimNitfMapModel::ossimNitfMapModel(init_file): Could not find the <" << PIAIMC_TAG
+                                            << "> tag in the NITF file at: <" << init_file << "> to extract GSD."
+                                            << " Searching for alternate <" << USE26A_TAG << ">... "<< std::endl;
+      }
+      
+
+      //***
+      // Search USE26A tag:
+      //***
+      const char* tag_ptr = strstr(header, USE26A_TAG);
+      if (tag_ptr)
+      {
+         //***
+         // Parse the tag for GSD (in inches):
+         //***
+         strncpy(charbuf, &tag_ptr[15], 5);
+         charbuf[6] = '\0';
+         theGSD.line = atof(charbuf)/12.0 * MTRS_PER_FT;
+         theGSD.samp = theGSD.line;
+      }
+      else
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimNitfMapModel::ossimNitfMapModel(init_file): Could not find the <" << USE26A_TAG
+                                               << "> tag in the NITF file at: <" << init_file << "> to extract GSD."
+                                               << " Searching for alternate <" << USE00A_TAG << ">... "<< std::endl;
+         }
+
+         //***
+         // Search USE00A tag:
+         //***
+         const char* tag_ptr = strstr(header, USE00A_TAG);
+         if (!tag_ptr)
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "WARNING ossimNitfMapModel::ossimNitfMapModel(init_file): Could not find the <" << USE00A_TAG
+                                                   << "> tag in the NITF file at: <"
+                                                   << init_file << ">." << " Aborting with error..." << std::endl;
+            }
+            theErrorStatus = 1;
+            return;
+         }
+
+         //***
+         // Parse the tag for GSD (in inches):
+         //***
+         strncpy(charbuf, &tag_ptr[15], 5);
+         charbuf[6] = '\0';
+         theGSD.line = atof(charbuf)/12.0 * MTRS_PER_FT;
+         theGSD.samp = theGSD.line;
+      }
+   }
+
+   ossimString drivePart;
+   ossimString pathPart;
+   ossimString filePart;
+   ossimString extPart;
+   init_file.split(drivePart,
+                  pathPart,
+                  filePart,
+                  extPart);
+   //***
+   // Save current state:
+   //***
+   ossimFilename geom_filename;
+   geom_filename.merge(drivePart,
+                       pathPart,
+                       filePart,
+                       "geom");
+   ossimKeywordlist geom_kwl;
+   saveState(geom_kwl);
+   geom_kwl.write(geom_filename.chars());
+
+
+   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::ossimNitfMapModel: Exited..." << std::endl;
+}
+
+
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimNitfMapModel(kwl)
+//  
+//  Constructs model from keywordlist geometry file
+//  
+//*****************************************************************************
+ossimNitfMapModel::ossimNitfMapModel(const ossimKeywordlist& geom_kwl)
+   : ossimSensorModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::ossimNitfMapModel(geom_file): entering..." << std::endl;
+
+   //***
+   // Parse keywordlist for geometry:
+   //***
+   loadState(geom_kwl);
+
+   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::ossimNitfMapModel(geom_file): Exited..." << std::endl;
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimNitfMapModel()
+//  
+//*****************************************************************************
+ossimNitfMapModel::~ossimNitfMapModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::~ossimNitfMapModel: entering..." << std::endl;
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::~ossimNitfMapModel: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimNitfMapModel::lineSampleHeightToWorld()
+//  
+//  Performs reverse projection of image line/sample to ground point.
+//  The imaging ray is intersected with a level plane at height above ellipsoid.
+//
+//*****************************************************************************
+void ossimNitfMapModel::lineSampleHeightToWorld(const ossimDpt& image_point,
+                                                const double&   height,
+                                                ossimGpt&       gpt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::lineSampleHeightToWorld: entering..." << std::endl;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::lineSampleHeightToWorld: exiting..." << std::endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimNitfMapModel::print()
+//  
+//  Formatted dump of data members.
+//  
+//*****************************************************************************
+std::ostream& ossimNitfMapModel::print(std::ostream& out) const
+{
+   out << "\nDump of ossimNitfMapModel object at " << hex << this << ":"
+       << endl;
+
+   return ossimSensorModel::print(out);
+}
+
+//*****************************************************************************
+//  METHOD: ossimNitfMapModel::saveState()
+//  
+//  Saves the model state to the KWL. This KWL also serves as a geometry file.
+//  
+//*****************************************************************************
+bool ossimNitfMapModel::saveState(ossimKeywordlist& kwl,
+                              const char* prefix) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::saveState: entering..." << std::endl;
+
+
+   // Hand off to base class for common stuff:
+   ossimSensorModel::saveState(kwl, prefix);
+
+      kwl.add(prefix, 
+              IMAGE_ID_KW,
+              theImageID.chars());
+
+      kwl.add(prefix,
+              ossimKeywordNames::NUMBER_LINES_KW,
+              theImageSize.line,
+              true);
+      
+      kwl.add(prefix,
+              ossimKeywordNames::NUMBER_SAMPLES_KW,
+              theImageSize.samp,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+              theGSD.line,
+              true);
+      
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+              theGSD.samp,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::UL_Y_KW,
+              0,
+              true);
+      
+      kwl.add(prefix,
+              ossimKeywordNames::UL_X_KW,
+              0,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::LR_Y_KW,
+              theImageSize.line - 1,
+              true);
+      
+      kwl.add(prefix,
+              ossimKeywordNames::LR_X_KW,
+              theImageSize.samp - 1,
+              true);
+
+      ossimDpt ulcorner;
+      if(!theBoundGndPolygon.vertex(0, ulcorner))
+      {
+         ulcorner = ossimDpt(0,0);
+      }
+      
+      kwl.add(prefix,
+              ossimKeywordNames::UL_LAT_KW,
+              ulcorner.lat,
+              true);
+      
+      kwl.add(prefix,
+              ossimKeywordNames::UL_LON_KW,
+              ulcorner.lon,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LAT_KW,
+              ulcorner.lat,
+              true);
+      
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LON_KW,
+              ulcorner.lon,
+              true);
+
+      ossimDpt corner;
+      if(!theBoundGndPolygon.nextVertex(corner))
+      {
+         corner = ossimDpt(0,0);
+      }
+      kwl.add(prefix,
+              ossimKeywordNames::UR_LAT_KW,
+              corner.lat,
+              true);
+      
+      kwl.add(prefix,
+              ossimKeywordNames::UR_LON_KW,
+              corner.lon,
+              true);
+
+      ossimDpt lrcorner;
+      if(!theBoundGndPolygon.nextVertex(lrcorner))
+      {
+         lrcorner = ossimDpt(0,0);
+      }
+      kwl.add(prefix,
+              ossimKeywordNames::LR_LAT_KW,
+              lrcorner.lat,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LR_LON_KW,
+              lrcorner.lon,
+              true);
+      
+
+      if(!theBoundGndPolygon.nextVertex(corner))
+      {
+         corner = ossimDpt(0,0);
+      }
+      kwl.add(prefix,
+              ossimKeywordNames::LL_LAT_KW,
+              corner.lat,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::LL_LON_KW,
+              corner.lon,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::ORIGIN_LATITUDE_KW,
+              (ulcorner.lat + lrcorner.lat)/2,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+              (lrcorner.lon + ulcorner.lon)/2,
+              true);
+
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+              fabs((ulcorner.lat - lrcorner.lat))/(theImageSize.line - 1),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+              fabs((lrcorner.lon - ulcorner.lon))/(theImageSize.samp - 1),
+              true);
+
+      kwl.add(prefix, ossimKeywordNames::TYPE_KW, "ossimEquDistCylProjection");
+//   kwl.add(prefix, ossimKeywordNames::TYPE_KW, TYPE_NAME(this));
+
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::saveState: returning..." << std::endl;
+      return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimNitfMapModel::loadState()
+//  
+//  Restores the model's state from the KWL. This KWL also serves as a
+//  geometry file.
+//  
+//*****************************************************************************
+bool ossimNitfMapModel::loadState(const ossimKeywordlist& kwl,
+                                  const char* prefix) 
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::loadState: entering..." << std::endl;
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::loadState:"
+                                          << "\nInput kwl:  " << kwl
+                                          << std::endl;
+   }
+
+   const char* value = 0;
+   const char* keyword = 0;
+   bool success = false;
+
+   //***
+   // Assure this keywordlist contains correct type info:
+   //***
+   value = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   if (!value || (strcmp(value, TYPE_NAME(this))))
+      goto loadStateError;
+       
+   //***
+   // Pass on to the base-class for parsing first:
+   //***
+   success = ossimSensorModel::loadState(kwl, prefix);
+   if (!success) goto loadStateError;
+ 
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::loadState: returning..." << std::endl;
+   return true;
+ 
+   //***
+   // Local error handling:
+   //***
+ loadStateError:
+   theErrorStatus++;
+   ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimNitfMapModel::loadState: encountered parsing the following required keyword: "
+                                       << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                       << std::endl;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::loadState: returning with error..." << std::endl;
+   return false;   
+}
+
+//*****************************************************************************
+// STATIC METHOD: ossimNitfMapModel::writeGeomTemplate
+//  
+//  Writes a sample kwl to output stream.
+//  
+//*****************************************************************************
+void ossimNitfMapModel::writeGeomTemplate(ostream& os)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::writeGeomTemplate: entering..." << std::endl;
+
+   os <<
+      "//**************************************************************\n"
+      "// Template for LandSat model keywordlist\n"
+      "//**************************************************************\n"
+      << ossimKeywordNames::TYPE_KW << ": " << "ossimNitfMapModel" << endl;
+
+   ossimSensorModel::writeGeomTemplate(os);
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfMapModel::writeGeomTemplate: returning..." << std::endl;
+   return;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimNitfMapModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimNitfMapModel.h
new file mode 100644
index 0000000000..bc7f8289d1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimNitfMapModel.h
@@ -0,0 +1,90 @@
+//*****************************************************************************
+// FILE: ossimNitfMapModel.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Doug Shibla (dshibla@imagelinks.com)
+//
+// DESCRIPTION:
+//
+//*****************************************************************************
+//  $Id: ossimNitfMapModel.h,v 1.4 2005/05/12 19:55:13 gpotts Exp $
+
+#ifndef ossimNitfMapModel_HEADER
+#define ossimNitfMapModel_HEADER
+
+#include <projections/sensor_modeling/ossimSensorModel.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <iostream>
+
+class ossimString;
+class ossimMapProjection;
+
+class OSSIMDLLEXPORT ossimNitfMapModel : public ossimSensorModel
+{
+public:
+   /*!
+    * CONSTRUCTORS:
+    */
+   ossimNitfMapModel();
+   ossimNitfMapModel(const ossimFilename& init_file);
+   ossimNitfMapModel(const ossimKeywordlist& geom_kwl);
+   
+   virtual ~ossimNitfMapModel();
+
+   /*!
+    * Returns pointer to a new instance, copy of this.
+    */
+   virtual ossimObject* dup() const { return 0; } // TBR
+   
+   /*!
+    * Extends base-class implementation. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   /*!
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files. Returns true if successful.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /*!
+    * Writes a template of geom keywords processed by loadState and saveState
+    * to output stream.
+    */
+   static void writeGeomTemplate(ostream& os);
+   
+   //***
+   // Overrides base class pure virtual.
+   //***
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const double&   heightEllipsoid,
+                                        ossimGpt&       worldPoint) const;
+   
+protected:
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimRadialDecentLensDistortion.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimRadialDecentLensDistortion.cpp
new file mode 100644
index 0000000000..c96d46da77
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimRadialDecentLensDistortion.cpp
@@ -0,0 +1,207 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts 
+//
+// Description:
+//
+// MeanRadialLens distortion.
+//
+//*******************************************************************
+//  $Id: ossimRadialDecentLensDistortion.cpp,v 1.8 2005/06/22 10:12:36 dburken Exp $
+
+#include <projections/sensor_modeling/ossimRadialDecentLensDistortion.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimCommon.h>
+
+RTTI_DEF1(ossimRadialDecentLensDistortion, "ossimRadialDecentLensDistortion",
+          ossim2dTo2dTransform);
+
+const char* ossimRadialDecentLensDistortion::PRINCIPAL_POINT_X_KW
+                               = "principal_point_x";
+const char* ossimRadialDecentLensDistortion::PRINCIPAL_POINT_Y_KW
+                               = "principal_point_y";
+const char* ossimRadialDecentLensDistortion::RADIAL_DISTORTION_COEFF_KW
+                               = "radial_distortion_coeff_K";
+const char* ossimRadialDecentLensDistortion::DECENT_DISTORTION_COEFF_KW
+                               = "decent_distortion_coeff_P";
+
+ossimRadialDecentLensDistortion::ossimRadialDecentLensDistortion
+(const ossimKeywordlist& kwl, const char* prefix)
+   :
+   theCalibratedPrincipalPoint (0, 0),
+   theRadialDistortionParameters(5),
+   theDecentDistortionParameters(5)
+{
+   loadState(kwl, prefix);
+}
+
+bool ossimRadialDecentLensDistortion::loadState(const ossimKeywordlist& kwl,
+                                                const char* prefix)
+{
+   const char* value;
+
+   theCalibratedPrincipalPoint = ossimDpt(0, 0);
+
+   value = kwl.find(prefix, PRINCIPAL_POINT_X_KW);
+   if (value)
+   {
+      theCalibratedPrincipalPoint.x = atof(value);
+   }
+
+   value = kwl.find(prefix, PRINCIPAL_POINT_Y_KW);
+   if (value)
+   {
+      theCalibratedPrincipalPoint.y = atof(value);
+   }
+   
+   for (int i=0; i<5; ++i)
+   {
+      ossimString key = RADIAL_DISTORTION_COEFF_KW;
+      key += ossimString::toString(i);
+      value = kwl.find(prefix, key.c_str());
+      if (!value)
+      {
+         theRadialDistortionParameters[i] = 0.0;
+      }
+      else
+      {
+         theRadialDistortionParameters[i] = ossimString::toDouble(value);
+      }
+
+      key = DECENT_DISTORTION_COEFF_KW;
+      key += ossimString::toString(i);
+      value = kwl.find(prefix, key.c_str());
+      if (!value)
+      {
+         theDecentDistortionParameters[i] = 0.0;
+      }
+      else
+      {
+         theDecentDistortionParameters[i] = ossimString::toDouble(value);
+      }
+   }
+
+   //***
+   // Pass on to base class:
+   //***
+   bool rtn_val = ossim2dTo2dTransform::loadState(kwl, prefix);
+
+   return rtn_val;
+}
+
+bool ossimRadialDecentLensDistortion::saveState(ossimKeywordlist& kwl,
+                                                const char* prefix) const
+{
+   //***
+   // Principal Point:
+   //***
+   kwl.add(prefix, PRINCIPAL_POINT_X_KW, theCalibratedPrincipalPoint.x);
+   kwl.add(prefix, PRINCIPAL_POINT_Y_KW, theCalibratedPrincipalPoint.y);
+   
+   for(int i=0; i<5; ++i)
+   {
+      //---
+      // Radial distortion coefficients:
+      //---
+      ossimString key = RADIAL_DISTORTION_COEFF_KW;
+      key += ossimString::toString(i);
+      kwl.add(prefix,
+              key.c_str(),
+              theRadialDistortionParameters[i],
+              true,  // overwrite
+              15,    // precision
+              false, // trim zeroes
+              true); // scientific
+
+      //---
+      // Decentering distortion coefficients:
+      //---
+      key = DECENT_DISTORTION_COEFF_KW;
+      key += ossimString::toString(i);
+      kwl.add(prefix,
+              key.c_str(),
+              theDecentDistortionParameters[i],
+              true,  // overwrite
+              15,    // precision
+              false, // trim zeroes
+              true); // scientific
+   }
+
+   //***
+   // Pass on to base class:
+   //***
+   bool rtn_val = ossim2dTo2dTransform::saveState(kwl, prefix);
+
+   return rtn_val;
+}
+   
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+double ossimRadialDecentLensDistortion::deltaR(double radius)const
+{
+  double rSquare = radius*radius;
+
+  return theRadialDistortionParameters[0] +
+     rSquare*(theRadialDistortionParameters[1] +
+              rSquare*(theRadialDistortionParameters[2] +
+                       rSquare*(theRadialDistortionParameters[3] +
+                                rSquare*theRadialDistortionParameters[4])));
+}
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+void ossimRadialDecentLensDistortion::forward(const ossimDpt& input_pt,
+                                              ossimDpt&       output_pt)
+   const
+{
+   ossimDpt deltaPosition(input_pt.x - theCalibratedPrincipalPoint.x,
+                          input_pt.y - theCalibratedPrincipalPoint.y);
+   double r = sqrt(square(deltaPosition.x) + 
+                   square(deltaPosition.y));
+   double dr = deltaR(r);
+   double deltaX1 = deltaPosition.x*dr;
+   double deltaY1 = deltaPosition.y*dr;
+
+   double rSquare = r*r;
+   double deltaX2 =  (1 + theDecentDistortionParameters[3]*rSquare +
+                      theDecentDistortionParameters[4]*rSquare*rSquare)*
+                     (theDecentDistortionParameters[1]*(rSquare + 2*deltaPosition.x*deltaPosition.x) +
+                      2*theDecentDistortionParameters[2]*deltaPosition.x*deltaPosition.y);
+   
+   double deltaY2 =  (1 + theDecentDistortionParameters[3]*rSquare +  theDecentDistortionParameters[4]*rSquare*rSquare)*
+                     (theDecentDistortionParameters[2]*(rSquare + 2*deltaPosition.y*deltaPosition.y) +
+                      2*theDecentDistortionParameters[1]*deltaPosition.x*deltaPosition.y);
+
+   output_pt.x = deltaPosition.x + deltaX1 + deltaX2;
+   output_pt.y = deltaPosition.y + deltaY1 + deltaY2;
+}
+
+//*****************************************************************************
+//  METHOD: ossimRadialDecentLensDistortion::print()
+//  
+//*****************************************************************************
+std::ostream& ossimRadialDecentLensDistortion::print(std::ostream& os) const
+{
+   os << "\nDump of ossimRadialDecentLensDistortion object" << endl;
+   
+   os << "  theCalibratedPrincipalPoint: " << theCalibratedPrincipalPoint;
+   
+   for (unsigned int i=0; i<5; i++)
+      os << "\n  K["<<i<<"]: " << theRadialDistortionParameters[i];  
+   
+   for (unsigned int i=0; i<5; i++)
+      os << "\n  P["<<i<<"]: " << theDecentDistortionParameters[i];  
+   
+   os << endl;
+
+   // call base class print???
+   
+   return os;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimRadialDecentLensDistortion.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimRadialDecentLensDistortion.h
new file mode 100644
index 0000000000..0fffc098af
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimRadialDecentLensDistortion.h
@@ -0,0 +1,174 @@
+//*******************************************************************
+// FILE: RadialDecentLensDistortion.h
+//
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description: Modeling for lens radial and decentering distortion.
+//
+//   The default implementation is:
+//  
+//   Let X and Y be coordinates relative to the center. Let
+//   Xc and Yc be the adjusted point so that:
+//  
+//   Xc = X + delta1X + delta2X
+//   Yc = Y + delta1Y + delta2Y
+//  
+//   
+//   delta1X = X*(k0 + k1*r^2 + k2*r^4 + k3*r^6 + k4*r^8)
+//   delta1Y = Y*(k0 + k1*r^2 + k2*r^4 + k3*r^6 + k4*r^8)
+//   
+//   delta2X = (1 + p3*r^2 + p4*r^4)[p1*(r^2 + 2*X^2) + 2*p2*X*Y]
+//   delta2Y = (1 + p3*r^2 + p4*r^4)[2*p1*X*Y  + p2*(r^2 + 2*Y^2) ]
+//  
+//  
+//   Note the point that is passed in we will compute:
+//        <X, Y> =  position - calibratedPrincipalPoint.
+//  
+//        so if you compute the delta then make sure that
+//        this class is constructed with principal point
+//        at 0,0
+//  
+//   Reference book: Elements of Photogrammetry Paul Wolf
+//   
+//*******************************************************************
+//  $Id: ossimRadialDecentLensDistortion.h,v 1.4 2003/12/22 18:48:32 dburken Exp $
+#ifndef ossimRadialDecentLensDistortion_HEADER
+#define ossimRadialDecentLensDistortion_HEADER
+#include <iostream>
+using namespace std;
+
+#include "matrix/newmat.h"
+#include "base/data_types/ossimDpt.h"
+#include "base/misc/ossim2dTo2dTransform.h"
+
+//*****************************************************************************
+//  CLASS
+//*****************************************************************************
+class OSSIMDLLEXPORT ossimRadialDecentLensDistortion
+   : public ossim2dTo2dTransform
+{
+public:
+   ossimRadialDecentLensDistortion() {}
+   ossimRadialDecentLensDistortion
+      (ossimDpt    calibratedPrincipalPoint,
+       const NEWMAT::ColumnVector &radialDistortionParameters,
+       const NEWMAT::ColumnVector &decentDistortionParameters)
+      : theRadialDistortionParameters(radialDistortionParameters),
+        theDecentDistortionParameters(decentDistortionParameters)
+      {  }
+
+   ossimRadialDecentLensDistortion(const ossimRadialDecentLensDistortion& copy)
+      : theCalibratedPrincipalPoint (copy.theCalibratedPrincipalPoint),
+        theRadialDistortionParameters (copy.theRadialDistortionParameters),
+        theDecentDistortionParameters (copy.theDecentDistortionParameters) { }
+
+   ossimRadialDecentLensDistortion(const ossimKeywordlist& kwl,
+                                   const char* prefix);
+
+   virtual ~ossimRadialDecentLensDistortion(){}
+   
+   /*!
+    * Implementation of base class 2D-to-2D transformation. The "forward"
+    * transformation is defined here as going from an undistorted ideal point to
+    * a distorted real point, i.e., adding distortion.
+    * 
+    * Also available (implemented in the base class) are:
+    *   inverse(distorted_point_in, undistorted_pt_out)
+    *   inverse(undistort_this_pt)
+    */
+   virtual void forward(const ossimDpt& undistorted_point_in,
+                        ossimDpt&       distorted_point_out) const;
+
+   virtual void forward(ossimDpt&  modify_this) const 
+      {
+         ossimDpt output;
+         forward(modify_this, output);
+         modify_this = output;
+      }
+      
+   
+   /*!
+    * Method to save the state of the object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   /*!
+    * Method to the load (recreate) the state of the object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /*!
+    * Set methods provide alternative initialization scheme to loadState:
+    */
+   void setPrincipalPoint(const ossimDpt pp);
+   void setRadialDistortionParams(const NEWMAT::ColumnVector& params);
+   void setDecentDistortionParams(const NEWMAT::ColumnVector& params);
+   /*!
+    * Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   static const char* PRINCIPAL_POINT_X_KW;
+   static const char* PRINCIPAL_POINT_Y_KW;
+   static const char* RADIAL_DISTORTION_COEFF_KW;
+   static const char* DECENT_DISTORTION_COEFF_KW;
+   
+private:
+   /*!
+    * default implementation Will solve the polynomial:
+    *
+    * k0 + k1*r^2 + k2*r^4 + k3*r^6 + k4*r^8
+    */
+   virtual double deltaR(double radius)const;
+   
+   ossimDpt     theCalibratedPrincipalPoint;
+   NEWMAT::ColumnVector theRadialDistortionParameters;
+   NEWMAT::ColumnVector theDecentDistortionParameters;  
+
+   TYPE_DATA
+};
+
+//*****************************************************************************
+//  INLINE METHODS
+//*****************************************************************************
+inline void
+ossimRadialDecentLensDistortion::setPrincipalPoint(const ossimDpt pp)
+{
+   theCalibratedPrincipalPoint = pp;
+}
+
+inline void ossimRadialDecentLensDistortion::setRadialDistortionParams
+   (const NEWMAT::ColumnVector& params)
+{
+   theRadialDistortionParameters = params;
+}
+
+inline void ossimRadialDecentLensDistortion::setDecentDistortionParams
+   (const NEWMAT::ColumnVector& params)
+{
+   theDecentDistortionParameters = params;
+}
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimSensorModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimSensorModel.cpp
new file mode 100644
index 0000000000..93fc0b0d27
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimSensorModel.cpp
@@ -0,0 +1,962 @@
+//*****************************************************************************
+// FILE: ossimSensorModel.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION:
+//   Contains implementation of class ossimSensorModel. This is the base
+//   class to all sensor model-related projections including replacement
+//   models such as coarse grids and polynomial models. This base class
+//   supports adjustable parameters for registration adjustment.
+//
+//   Important note to sensor model implementors: In order to avoid a separate
+//   set of "initial adjustable parameters," this design assumes ALL initial
+//   values are 0. When designing the derived-class model, insure that the
+//   adjustable parameters are 0-based. This applies to the adjustable param
+//   array declared in this base class only. The derived classes can declare
+//   their own adjstable params that are more descriptive and that can be
+//   assigned an initial value thet is non-zero, but that are linearly related
+//   to the adjustable params of this class. In that case, the updateModel()
+//   method will compute the derived-class's parameters based on
+//   theAdjustableParams array, after an adjustment is made.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimSensorModel.cpp,v 1.71 2005/09/22 11:58:12 gpotts Exp $
+#include <iostream>
+#include <sstream>
+using namespace std;
+
+#include <stdio.h>
+
+#include <projections/sensor_modeling/ossimSensorModel.h>
+
+RTTI_DEF2(ossimSensorModel, "ossimSensorModel", ossimProjection, ossimAdjustableParameterInterface);
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/factory/ossimDatumFactory.h>
+
+#include <elevation/ossimElevManager.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimSensorModel:exec");
+static ossimTrace traceDebug ("ossimSensorModel:debug");
+
+static const char*       REF_GPT_LAT_KW      = "ref_point_lat";
+static const char*       REF_GPT_LON_KW      = "ref_point_lon";
+static const char*       REF_GPT_HGT_KW      = "ref_point_hgt";
+static const char*       REF_IPT_LINE_KW     = "ref_point_line";
+static const char*       REF_IPT_SAMP_KW     = "ref_point_samp";
+static const char*       IMAGE_ID_KW         = "image_id";
+static const char*       SENSOR_ID_KW        = "sensor";
+static const ossimString NULL_STRING         = "NULL";
+static const double      RAY_ORIGIN_HEIGHT   = 10000.0; //meters
+
+//*****************************************************************************
+//  DEFAULT CONSTRUCTOR: ossimSensorModel()
+//*****************************************************************************
+ossimSensorModel::ossimSensorModel()
+   :
+   ossimProjection     (),
+   ossimAdjustableParameterInterface(),
+   theImageSize        (0, 0),
+   theSubImageOffset   (0.0, 0.0),
+   theImageID          (),
+   theSensorID         (),
+   theGSD              (0.0, 0.0),
+   theMeanGSD          (0.0),
+   theRefGndPt         (0.0, 0.0, 0.0),
+   theRefImgPt         (0.0, 0.0),
+   theBoundGndPolygon  (),
+   theImageClipRect    (),
+   theNominalPosError  (0)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::ossimSensorModel(geom_kwl): entering..." << endl;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::ossimSensorModel(geom_kwl): returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: ossimSensorModel(ossimSensorModel)
+//*****************************************************************************
+ossimSensorModel::ossimSensorModel(const ossimSensorModel& model)
+   :
+   ossimProjection(model),
+   ossimAdjustableParameterInterface(model),
+   theImageSize       (model.theImageSize),
+   theSubImageOffset  (model.theSubImageOffset),
+   theImageID         (model.theImageID),
+   theSensorID        (model.theSensorID),
+   theGSD             (model.theGSD),
+   theMeanGSD         (model.theMeanGSD),
+   theRefGndPt        (model.theRefGndPt),
+   theRefImgPt        (model.theRefImgPt),
+   theBoundGndPolygon (model.theBoundGndPolygon),
+   theImageClipRect   (model.theImageClipRect),
+   theNominalPosError (model.theNominalPosError)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::ossimSensorModel(model): entering..." << std::endl;
+
+   theErrorStatus = model.theErrorStatus;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::ossimSensorModel(model): returning..." << std::endl;
+   return;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimSensorModel(geom_kwl)
+//  
+//  Constructs from a geometry keywordlist.
+//  
+//*****************************************************************************
+ossimSensorModel::ossimSensorModel(const ossimKeywordlist& geom_kwl)
+   :
+   ossimProjection     (),
+   ossimAdjustableParameterInterface(),
+   theImageSize        (0, 0),
+   theSubImageOffset   (0.0, 0.0),
+   theImageID          (),
+   theSensorID         (),
+   theGSD              (0.0, 0.0),
+   theMeanGSD          (0.0),
+   theRefGndPt         (0.0, 0.0, 0.0),
+   theRefImgPt         (0.0, 0.0),
+   theBoundGndPolygon  (),
+   theImageClipRect    (),
+   theNominalPosError  (0)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::ossimSensorModel(geom_kwl): entering..." << std::endl;
+
+//   ossimElevManager::instance()->loadState(geom_kwl);
+   loadState(geom_kwl);
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::ossimSensorModel(geom_kwl): returning..." << std::endl;
+   return;
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimSensorModel
+//  
+//*****************************************************************************
+ossimSensorModel::~ossimSensorModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::~ossimSensorModel: entering..." << std::endl;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::~ossimSensorModel: returning..." << std::endl;
+}
+
+ossimObject* ossimSensorModel::getBaseObject()
+{
+   return this;
+}
+
+const ossimObject* ossimSensorModel::getBaseObject()const
+{
+   return this;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimSensorModel::lineSampleToWorld(image_pt, &gpt)
+//  
+//  Intersects the ray associated with image_pt with the available elevation
+//  model. Returns ground point
+//  
+//*****************************************************************************
+void ossimSensorModel::lineSampleToWorld(const ossimDpt& image_point,
+                                         ossimGpt&       gpt) const
+{
+   bool debug = false;  // setable via interactive debugger
+   if (traceExec() || debug)  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::lineSampleToWorld:entering..." << std::endl;
+   
+   if(image_point.hasNans())
+   {
+      gpt.makeNan();
+      return;
+   }
+   //***
+   // Extrapolate if image point is outside image:
+   //***
+   if (!insideImage(image_point))
+   {
+      gpt = extrapolate(image_point);
+      return;
+   }
+
+   //***
+   // Determine imaging ray and invoke elevation source object's services to
+   // intersect ray with terrain model:
+   //***
+   ossimEcefRay ray;
+   imagingRay(image_point, ray);
+   ossimElevManager::instance()->intersectRay(ray, gpt);
+
+   if (traceDebug() || debug)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "image_point = " << image_point << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ray = " << ray << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "gpt = " << gpt << std::endl;
+   }
+
+   if (traceExec() || debug)  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::lineSampleToWorld: returning..." << std::endl;
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSensorModel::worldToLineSample()
+//  
+//  Performs forward projection of ground point to image space.
+//  
+//*****************************************************************************
+void ossimSensorModel::worldToLineSample(const ossimGpt& worldPoint,
+                                         ossimDpt&       ip) const
+{
+   //   static bool recursionFlag = false;
+
+   static const double PIXEL_THRESHOLD    = 0.1; // acceptable pixel error
+   static const int    MAX_NUM_ITERATIONS = 20;
+
+
+   if(worldPoint.isLatNan()||
+      worldPoint.isLonNan())
+     {
+       ip.makeNan();
+       return;
+     }
+      
+   //***
+   // First check if the world point is inside bounding rectangle:
+   //***
+   int iters = 0;
+   ossimDpt wdp (worldPoint);
+   //   if ((!recursionFlag)&&!(theBoundGndPolygon.pointWithin(wdp)))
+
+   if((theBoundGndPolygon.getNumberOfVertices() > 0)&&
+      (!theBoundGndPolygon.hasNans()))
+   {
+      if (!(theBoundGndPolygon.pointWithin(wdp)))
+      {
+         //      recursionFlag = true;
+         ip = extrapolate(worldPoint);
+         //      recursionFlag = false;
+         return;
+      }         
+   }
+   //***
+   // Substitute zero for null elevation if present:
+   //***
+   double height = worldPoint.hgt;
+   if ((height == ossimElevSource::DEFAULT_NULL_HEIGHT)||
+       (height == OSSIM_DBL_NAN))
+      height = 0.0;
+
+   //***
+   // Utilize iterative scheme for arriving at image point. Begin with guess
+   // at image center:
+   //***
+   ip.u = theRefImgPt.u;
+   ip.v = theRefImgPt.v;
+   
+   ossimDpt ip_du;
+   ossimDpt ip_dv;
+
+   ossimGpt gp, gp_du, gp_dv;
+   double dlat_du, dlat_dv, dlon_du, dlon_dv;
+   double delta_lat, delta_lon, delta_u, delta_v;
+   double inverse_norm;
+   
+   //***
+   // Begin iterations:
+   //***
+   do
+   {
+      //***
+      // establish perturbed image points about the guessed point:
+      //***
+      ip_du.u = ip.u + 1.0;
+      ip_du.v = ip.v;
+      ip_dv.u = ip.u;
+      ip_dv.v = ip.v + 1.0;
+      
+      //***
+      // Compute numerical partials at current guessed point:
+      //***
+      lineSampleHeightToWorld(ip,    height, gp);
+      lineSampleHeightToWorld(ip_du, height, gp_du);
+      lineSampleHeightToWorld(ip_dv, height, gp_dv);
+
+      dlat_du = gp_du.lat - gp.lat; //e
+      dlon_du = gp_du.lon - gp.lon; //g
+      dlat_dv = gp_dv.lat - gp.lat; //f
+      dlon_dv = gp_dv.lon - gp.lon; //h
+
+      //***
+      // Test for convergence:
+      //***
+      delta_lat = worldPoint.lat - gp.lat;
+      delta_lon = worldPoint.lon - gp.lon;
+      
+      //***
+      // Compute linearized estimate of image point given gp delta:
+      //***
+      inverse_norm = dlat_dv*dlon_du - dlat_du*dlon_dv; // fg-eh
+      if (inverse_norm != 0)
+      {
+          delta_u = (-dlon_dv*delta_lat + dlat_dv*delta_lon)/inverse_norm;
+          delta_v = ( dlon_du*delta_lat - dlat_du*delta_lon)/inverse_norm;
+          ip.u += delta_u;
+          ip.v += delta_v;
+      }
+      else
+      {
+         delta_u = 0;
+         delta_v = 0;
+      }
+
+      iters++;
+    } while (((fabs(delta_u) > PIXEL_THRESHOLD) ||
+              (fabs(delta_v) > PIXEL_THRESHOLD)) &&
+             (iters < MAX_NUM_ITERATIONS));
+//    } while (((fabs(delta_u) > PIXEL_THRESHOLD) ||
+//              (fabs(delta_v) > PIXEL_THRESHOLD)) &&
+//             (iters < MAX_NUM_ITERATIONS));
+
+   //***
+   // Note that this error mesage appears only if max count was reached while
+   // iterating. A linear (no iteration) solution would finish with iters =
+   // MAX_NUM_ITERATIONS + 1:
+   //***
+   if (iters == MAX_NUM_ITERATIONS)
+   {
+   }
+
+   //***
+   // The image point computed this way corresponds to full image space.
+   // Apply image offset in the case this is a sub-image rectangle:
+   //***
+      ip -= theSubImageOffset;
+
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSensorModel::print(ostream)
+//  
+//  Dumps contents of object to ostream.
+//  
+//*****************************************************************************
+std::ostream& ossimSensorModel::print(std::ostream& out) const
+{
+   out << setprecision(15) << setiosflags(ios::fixed)
+       << "\n ossimSensorModel base-class data members:\n"
+       << "\n         theImageID: " << theImageID
+       << "\n        theSensorID: " << theSensorID
+       << "\n       theImageSize: " << theImageSize
+       << "\n  theSubImageOffset: " << theSubImageOffset
+       << "\n             theGSD: " << theGSD
+       << "\n         theMeanGSD: " << theMeanGSD
+       << "\n        theRefGndPt: " << theRefGndPt
+       << "\n        theRefImgPt: " << theRefImgPt
+       << "\n theBoundGndPolygon: \n" << theBoundGndPolygon
+       << "\n theBoundGndPolygon: " << theBoundGndPolygon
+       << "\n   theImageClipRect: " << theImageClipRect
+       << "\n theNominalPosError: " << theNominalPosError
+       << endl;
+
+   //---
+   // Note:
+   // need ossimAdjustableParameterInterface::print(os);
+   //---
+
+   return ossimProjection::print(out);
+}
+
+void ossimSensorModel::setImageRect(const ossimDrect& imageRect)
+{
+   theImageClipRect = imageRect;
+   theRefImgPt = imageRect.midPoint();
+}
+void ossimSensorModel::setGroundRect(const ossimGpt& ul,
+                                     const ossimGpt& ur,
+                                     const ossimGpt& lr,
+                                     const ossimGpt& ll)
+{
+   theBoundGndPolygon.clear();
+   theBoundGndPolygon.addPoint(ul);
+   theBoundGndPolygon.addPoint(ur);
+   theBoundGndPolygon.addPoint(lr);
+   theBoundGndPolygon.addPoint(ll);
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimSensorModel::saveState()
+//  
+//  Saves the state of this object to KWL.
+//  
+//*****************************************************************************
+bool ossimSensorModel::saveState(ossimKeywordlist& kwl,
+                                 const char*       prefix) const 
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::saveState: entering..." << std::endl;
+
+   kwl.add(prefix, IMAGE_ID_KW, theImageID.chars());
+   kwl.add(prefix, SENSOR_ID_KW, theSensorID.chars());
+   
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_LINES_KW,
+           theImageSize.line,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_SAMPLES_KW,
+           theImageSize.samp,
+           true);
+   
+   kwl.add(prefix,
+           REF_GPT_LAT_KW,
+           theRefGndPt.lat,
+           true);
+   
+   kwl.add(prefix,
+           REF_GPT_LON_KW,
+           theRefGndPt.lon,
+           true);
+   
+   kwl.add(prefix,
+           REF_GPT_HGT_KW,
+           theRefGndPt.hgt,
+           true);
+   
+   kwl.add(prefix,
+           REF_IPT_LINE_KW,
+           theRefImgPt.line,
+           true);
+      
+   kwl.add(prefix,
+           REF_IPT_SAMP_KW,
+           theRefImgPt.samp,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+           theGSD.line,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+           theGSD.samp,
+           true);
+   
+   ossimDpt corner;
+   if(!theBoundGndPolygon.vertex(0, corner))
+   {
+      corner = ossimDpt(0,0);
+   }
+   
+   kwl.add(prefix,
+           ossimKeywordNames::UL_LAT_KW,
+           corner.lat,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::UL_LON_KW,
+           corner.lon,
+           true);
+   
+   if(!theBoundGndPolygon.nextVertex(corner))
+   {
+      corner = ossimDpt(0,0);
+   }
+   kwl.add(prefix,
+           ossimKeywordNames::UR_LAT_KW,
+           corner.lat,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::UR_LON_KW,
+           corner.lon,
+           true);
+   
+   if(!theBoundGndPolygon.nextVertex(corner))
+   {
+      corner = ossimDpt(0,0);
+   }
+   kwl.add(prefix,
+           ossimKeywordNames::LR_LAT_KW,
+           corner.lat,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::LR_LON_KW,
+           corner.lon,
+           true);
+   
+   
+   if(!theBoundGndPolygon.nextVertex(corner))
+   {
+      corner = ossimDpt(0,0);
+   }
+   kwl.add(prefix,
+           ossimKeywordNames::LL_LAT_KW,
+           corner.lat,
+           true);
+   kwl.add(prefix,
+           ossimKeywordNames::LL_LON_KW,
+           corner.lon,
+           true);
+
+
+   kwl.add(prefix,
+           "rect",
+           ossimString::toString(theImageClipRect.ul().x)
+           + " " + ossimString::toString(theImageClipRect.ul().y) + " " +
+           ossimString::toString(theImageClipRect.lr().x) + " " +
+           ossimString::toString(theImageClipRect.lr().y),
+           true);
+
+   saveAdjustments(kwl, prefix);
+   //
+   // Also save the state of the elevation object:
+   //
+//   ossimElevManager::instance()->saveState(kwl, prefix);
+   
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::saveState:returning..." << std::endl;
+   return ossimProjection::saveState(kwl, prefix);;
+}
+
+//*****************************************************************************
+//  METHOD: ossimSensorModel::loadState()
+//  
+//  Loads the state of this object from KWL.
+//  
+//*****************************************************************************
+bool ossimSensorModel::loadState(const ossimKeywordlist& kwl,
+                                 const char*       prefix)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::loadState: entering..." << std::endl;
+
+   const char* keyword;
+   const char* value;
+//   int nconv;
+   ossimDpt v[4]; // temporarily holds vertices for ground polygon
+
+   //***
+   // Read each keyword, breaking out if error occurs:
+   //***
+   keyword = IMAGE_ID_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+      theImageID = value;
+   else
+      theImageID = NULL_STRING;
+   
+   keyword = SENSOR_ID_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+      theSensorID = value;
+   else
+      theSensorID = NULL_STRING;
+      
+   keyword = ossimKeywordNames::NUMBER_LINES_KW;//IMAGE_SIZE_LINES_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      theImageSize.line = ossimString(value).toLong();
+   }
+
+   keyword = ossimKeywordNames::NUMBER_SAMPLES_KW;// IMAGE_SIZE_SAMPS_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      theImageSize.samp = ossimString(value).toLong();
+   }
+
+   keyword = REF_IPT_LINE_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      theRefImgPt.line = ossimString(value).toDouble();
+   }
+
+   keyword = REF_IPT_SAMP_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      theRefImgPt.samp = ossimString(value).toDouble();
+   }
+
+   keyword = REF_GPT_LAT_KW;
+   value = kwl.find(prefix, keyword);
+   if(value)
+   {
+      theRefGndPt.latd(ossimString(value).toDouble());
+   }
+   
+
+   keyword = REF_GPT_LON_KW;
+   value = kwl.find(prefix, keyword);
+   if(value)
+   {
+      theRefGndPt.lond(ossimString(value).toDouble());
+   }
+   
+
+   keyword = REF_GPT_HGT_KW;
+   value = kwl.find(prefix, keyword);
+   if(value)
+   {
+      theRefGndPt.hgt = ossimString(value).toDouble();
+   }
+   
+
+   keyword = ossimKeywordNames::METERS_PER_PIXEL_Y_KW;// GSD_LINE_DIR_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      theGSD.line = ossimString(value).toDouble();
+   }
+
+   keyword = ossimKeywordNames::METERS_PER_PIXEL_X_KW;//GSD_SAMP_DIR_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      theGSD.samp = ossimString(value).toDouble();
+   }
+
+   theMeanGSD = (fabs(theGSD.line) + fabs(theGSD.samp))/2.0;
+
+   keyword = ossimKeywordNames::UL_LAT_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      v[0].lat = ossimString(value).toDouble();
+   }
+
+   keyword = ossimKeywordNames::UL_LON_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      v[0].lon = ossimString(value).toDouble();
+   }
+
+   keyword = ossimKeywordNames::UR_LAT_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      v[1].lat = ossimString(value).toDouble();
+   }
+
+   keyword = ossimKeywordNames::UR_LON_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      v[1].lon = ossimString(value).toDouble();
+   }
+
+   keyword = ossimKeywordNames::LR_LAT_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      v[2].lat = ossimString(value).toDouble();
+   }
+
+   keyword = ossimKeywordNames::LR_LON_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      v[2].lon = ossimString(value).toDouble();
+   }
+
+   keyword = ossimKeywordNames::LL_LAT_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      v[3].lat = ossimString(value).toDouble();
+   }
+
+   keyword = ossimKeywordNames::LL_LON_KW;
+   value = kwl.find(prefix, keyword);
+   if (value)
+   {
+      v[3].lon = ossimString(value).toDouble();
+   }
+
+   //***
+   // Initialize other data members given quantities read in KWL:
+   //***
+   theBoundGndPolygon = ossimPolygon(4, v);
+
+   const char* rect = kwl.find(prefix, "rect");
+   if(rect)
+   {
+      std::istringstream in(rect);
+      double ulx, uly, lrx, lry;
+      in >> ulx >> uly >> lrx >> lry;
+      theImageClipRect = ossimDrect(ulx, uly, lrx, lry);
+   }
+   else
+   {
+      theImageClipRect = ossimDrect(0.0, 0.0,
+                                    theImageSize.samp-1, theImageSize.line-1);
+   }
+   loadAdjustments(kwl, prefix);
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::loadState: returning..." << std::endl;
+   return ossimProjection::loadState(kwl, prefix);;
+}
+
+//*****************************************************************************
+// PROTECTED METHOD: Model_type::extrapolate(image_point)
+//
+//  This method computes extrapolated values of latitude and longitude for
+//  points which are outside the actual image boundaries.
+//*****************************************************************************
+ossimGpt ossimSensorModel::extrapolate (const ossimDpt& imagePoint,
+                                        const double&   height) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) <<  "DEBUG ossimSensorModel::extrapolate: entering... " << std::endl;
+
+   //***
+   // If image point supplied has NaN components, return now with a NaN point.
+   // This prevents an infinite recursion between model worldToLineSample
+   // and this method:
+   //***
+   if ((imagePoint.line == OSSIM_DBL_NAN) || (imagePoint.samp == OSSIM_DBL_NAN))
+   {
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::extrapolate: returning..." << std::endl;
+      return ossimGpt(OSSIM_DBL_NAN, OSSIM_DBL_NAN, OSSIM_DBL_NAN);
+   }
+
+   //***
+   // Determine which edge is intersected by the radial, and establish
+   // intersection:
+   //***
+   ossimGpt gpt;
+   ossimDpt edgePt (imagePoint);
+   ossimDpt image_center (theRefImgPt);
+   theImageClipRect.clip(image_center, edgePt);
+
+   //***
+   // Need edgePt relative to image center. Compute an epsilon perturbation in
+   // the direction of edgePt for later computing directional derivative,
+   // and back out the offset to origin:
+   //***
+   ossimDpt deltaPt (edgePt - image_center);
+   ossimDpt epsilon (deltaPt/deltaPt.length());
+   edgePt -= epsilon;  // insure that we are inside the image
+   ossimDpt edgePt_prime (edgePt - epsilon); // epsilon=1pixel
+       
+   //***
+   // Establish ground point corresponding to edge point and edgePt+epsilon:
+   //***
+   ossimGpt edgeGP;
+   ossimGpt edgeGP_prime;
+
+   if (height == OSSIM_DBL_NAN)
+   {
+      lineSampleToWorld(edgePt, edgeGP);
+      lineSampleToWorld(edgePt_prime, edgeGP_prime);
+   }
+   else
+   {
+      lineSampleHeightToWorld(edgePt, height, edgeGP);
+      lineSampleHeightToWorld(edgePt_prime, height, edgeGP_prime);
+   }
+   
+   //***
+   // Compute approximate directional derivatives of lat and lon along radial
+   // at the edge:
+   //***
+   double dpixel    = (edgePt-edgePt_prime).length();
+   double dlat_drad = (edgeGP.lat - edgeGP_prime.lat)/dpixel;
+   double dlon_drad = (edgeGP.lon - edgeGP_prime.lon)/dpixel;
+
+   //***
+   // Now extrapolate to image point of interest:
+   //***
+   double delta_pixel = (imagePoint - edgePt).length();
+
+   gpt.lat = edgeGP.lat + dlat_drad*delta_pixel;
+   gpt.lon = edgeGP.lon + dlon_drad*delta_pixel;
+   if (height == ossimElevSource::DEFAULT_NULL_HEIGHT)
+   {
+      gpt.hgt = ossimElevManager::instance()->getHeightAboveEllipsoid(gpt);
+   }
+   else
+      gpt.hgt = height;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::extrapolate: returning..." << std::endl;
+   return gpt;
+}
+
+
+//*****************************************************************************
+// PROTECTED METHOD: Model_type::extrapolate(ground_point)
+//
+//  This method computes extrapolated values of line and sample for
+//  points which are outside the actual image boundaries.
+//*****************************************************************************
+ossimDpt ossimSensorModel::extrapolate (const ossimGpt& gpt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) <<  "DEBUG ossimSensorModel::extrapolate: entering... " << std::endl;
+
+   double height = 0.0;
+   //***
+   // If ground point supplied has NaN components, return now with a NaN point.
+   //***
+   if ((gpt.lat==OSSIM_DBL_NAN) ||
+       (gpt.lon==OSSIM_DBL_NAN)) //||
+//       (gpt.hgt==OSSIM_DBL_NAN))
+   {
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::extrapolate: returning..." << std::endl;
+      return ossimDpt(OSSIM_DBL_NAN, OSSIM_DBL_NAN);
+   }
+   if(gpt.hgt != OSSIM_DBL_NAN)
+   {
+      height = gpt.hgt;
+   }
+   //***
+   // Determine which edge is intersected by the radial, and establish
+   // intersection:
+   //***
+   ossimDpt edgePt (gpt);
+   ossimDpt image_center (theRefGndPt);
+   theBoundGndPolygon.clipLineSegment(image_center, edgePt);
+
+   //---
+   // Compute an epsilon perturbation in the direction away from edgePt for
+   // later computing directional derivative:
+   //---
+   const double  DEG_PER_MTR =  8.983152841e-06; // Equator WGS-84...
+   double epsilon = theMeanGSD*DEG_PER_MTR; //degrees (latitude) per pixel
+   ossimDpt deltaPt (edgePt-image_center);
+   ossimDpt epsilonPt (deltaPt*epsilon/deltaPt.length());
+   edgePt -= epsilonPt;
+   ossimDpt edgePt_prime (edgePt - epsilonPt);
+       
+   //***
+   // Establish image point corresponding to edge point and edgePt+epsilon:
+   //***
+      ossimGpt edgeGP       (edgePt.lat,       edgePt.lon,       height);//gpt.hgt);
+      ossimGpt edgeGP_prime (edgePt_prime.lat, edgePt_prime.lon, height);//gpt.hgt);
+
+   worldToLineSample(edgeGP, edgePt);
+   worldToLineSample(edgeGP_prime, edgePt_prime);
+
+   //***
+   // Compute approximate directional derivatives of line and sample along
+   // radial at the edge:
+   //***
+   double dsamp_drad = (edgePt.samp - edgePt_prime.samp)/epsilon;
+   double dline_drad = (edgePt.line - edgePt_prime.line)/epsilon;
+
+   //***
+   // Now extrapolate to point of interest:
+   //***
+   double delta = (ossimDpt(gpt) - ossimDpt(edgeGP)).length();
+
+   
+   ossimDpt extrapolated_ip (edgePt.samp + delta*dsamp_drad,
+                             edgePt.line + delta*dline_drad);
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::extrapolate: returning..." << std::endl;
+
+   return extrapolated_ip;
+}
+
+
+//*****************************************************************************
+//  METHOD: ossimSensorModel::imagingRay()
+//  
+//  Default implementation for computing imaging ray from image point.
+//  
+//*****************************************************************************
+void ossimSensorModel::imagingRay(const ossimDpt& image_point,
+                                  ossimEcefRay&   image_ray) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::imagingRay: entering..." << std::endl;
+
+   ossimGpt start;
+   ossimGpt end;
+
+   lineSampleHeightToWorld(image_point, RAY_ORIGIN_HEIGHT, start);
+   lineSampleHeightToWorld(image_point, 0.0, end);
+
+   image_ray = ossimEcefRay(start, end);
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::imagingRay: returning..." << std::endl;
+   return;
+}
+
+//*****************************************************************************
+//  STATIC METHOD: ossimSensorModel::writeGeomTemplate
+//  
+//  Outputs a sample geometry KWL to stream provided.
+//  
+//*****************************************************************************
+void ossimSensorModel::writeGeomTemplate(ostream& os)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::writeGeomTemplate:entering..." << std::endl;
+   
+   os << "//***\n"
+      << "// Base-class ossimSensorModel Keywords:\n"
+      << "//***\n"
+      << ossimKeywordNames::ID_KW << ":  <string>\n"
+      << SENSOR_ID_KW << ": <string>\n"
+      << ossimKeywordNames::NUMBER_LINES_KW << ": <int>\n"
+      << ossimKeywordNames::NUMBER_SAMPLES_KW << ": <int>\n"
+      << REF_GPT_LAT_KW << ": <decimal degrees>\n"
+      << REF_GPT_LON_KW << ": <decimal degrees>\n"
+      << REF_GPT_HGT_KW << ": <float meters>\n"
+      << REF_IPT_LINE_KW << ": <float>\n"
+      << REF_IPT_SAMP_KW << ": <float>\n"
+      << ossimKeywordNames::METERS_PER_PIXEL_Y_KW << ": <float meters>\n"
+      << ossimKeywordNames::METERS_PER_PIXEL_X_KW << ": <float meters>\n"
+      << ossimKeywordNames::UL_LAT_KW << ": <decimal degrees>\n"
+      << ossimKeywordNames::UL_LON_KW << ": <decimal degrees>\n"
+      << ossimKeywordNames::UR_LAT_KW << ": <decimal degrees>\n"
+      << ossimKeywordNames::UR_LON_KW << ": <decimal degrees>\n"
+      << ossimKeywordNames::LR_LAT_KW << ": <decimal degrees>\n"
+      << ossimKeywordNames::LR_LON_KW << ": <decimal degrees>\n"
+      << ossimKeywordNames::LL_LAT_KW << ": <decimal degrees>\n"
+      << ossimKeywordNames::LL_LON_KW << ": <decimal degrees>\n"
+      << "\n"
+      << "//***\n"
+      << "// Repeat following four entries for each adjustable parameter:\n"
+      << "//***\n"
+//       << PARAM_PREFIX << "N." << PARAM_NAME_KW << ": <string>\n" 
+//       << PARAM_PREFIX << "N." << PARAM_UNITS_KW << ": <string>\n" 
+//       << PARAM_PREFIX << "N." << PARAM_VALUE_KW << ": <float>\n" 
+//       << PARAM_PREFIX << "N." << PARAM_SIGMA_KW << ": <float>\n"
+      << std::endl;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSensorModel::writeGeomTemplate: returning..." << std::endl;
+   return;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimSensorModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimSensorModel.h
new file mode 100644
index 0000000000..2829290d67
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/ossimSensorModel.h
@@ -0,0 +1,234 @@
+//*****************************************************************************
+// FILE: ossimSensorModel.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION:
+//   Contains declaration of class ossimSensorModel. This is the base class to
+//   all sensor model-related projections including replacement models such as
+//   coarse grids and polynomial models. This base class supports adjustable
+//   parameters for registration adjustment.
+//
+//   Important note to sensor model implementors: In order to avoid a separate
+//   set of "initial adjustable parameters," this design assumes ALL initial
+//   values are 0. When designing the derived-class model, insure that the
+//   adjustable parameters are 0-based. This applies to theAdjustableParams
+//   array declared in this base class only. The derived classes can declare
+//   their own adjstable params that are more descriptive and that can be
+//   assigned an initial value that is non-zero, but that are linearly related
+//   to the adjustable params of this class. In that case, the updateModel()
+//   method will compute the derived-class's parameters based on
+//   theAdjustableParams array, after an adjustment is made.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimSensorModel.h,v 1.28 2005/05/12 19:55:13 gpotts Exp $
+
+#ifndef ossimSensorModel_HEADER
+#define ossimSensorModel_HEADER
+
+#include <projections/ossimProjection.h>
+#include <base/data_types/ossimEcefRay.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimPolygon.h>
+#include <base/data_types/ossimDrect.h>
+#include <elevation/ossimElevSource.h>
+#include <base/misc/ossimAdjustableParameterInterface.h>
+
+class ossimKeywordlist;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimSensorModel
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimSensorModel : public ossimProjection,
+   public ossimAdjustableParameterInterface
+{
+public:
+   /*!
+    * CONSTRUCTORS:
+    */
+   ossimSensorModel();
+   ossimSensorModel(const ossimSensorModel& copy_this);
+   ossimSensorModel(const ossimKeywordlist& geom_kwl);
+
+   virtual ~ossimSensorModel();
+
+   virtual ossimObject* getBaseObject();
+   virtual const ossimObject* getBaseObject()const;
+   
+   /*!
+    * ACCESS METHODS:
+    */
+   virtual ossimGpt origin()            const {return theRefGndPt; }
+   virtual ossimDpt getMetersPerPixel() const {return ossimDpt(fabs(theGSD.x),
+                                                               fabs(theGSD.y));}
+   
+   /*!
+    * Implementation of base-class pure virtual projection methods. These
+    * methods may be overriden by derived classes if those have more efficient
+    * schemes. The implementations here are iterative (relatively slow). Both
+    * depend on calls to the pure virtual lineSampleHeightToWorld() method.
+    */
+   virtual void  lineSampleToWorld(const ossimDpt& image_point,
+                                   ossimGpt&       world_point) const;
+   virtual void  worldToLineSample(const ossimGpt& world_point,
+                                   ossimDpt&       image_point) const;
+
+   /*!
+    * METHOD: lineSampleHeightToWorld
+    * This is the pure virtual that performs the actual work of projecting
+    * the image point to the given elevation above MSL. 
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& lineSampPt,
+                                        const double&   heightAboveMSL,
+                                        ossimGpt&       worldPt) const = 0;
+   /*!
+    * METHOD: imagingRay(image_point, &ossimEcefRay)
+    * Given an image point, returns a ray originating at some arbitrarily high
+    * point (ideally at the sensor position) and pointing towards the target.
+    * Implemented here but should be overriden for more efficient solution.
+    */
+   virtual void imagingRay(const ossimDpt& image_point,
+                           ossimEcefRay&   image_ray) const;
+
+   /*!
+    * METHOD: print()
+    * Fulfills base-class pure virtual. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+   void setImageRect(const ossimDrect& imageRect);
+   void setGroundRect(const ossimGpt& ul,
+                      const ossimGpt& ur,
+                      const ossimGpt& lr,
+                      const ossimGpt& ll);
+   /*!
+    * METHOD: imageSize()
+    * Returns the maximum line/sample rigorously defined by this model.
+    */
+   ossimDpt imageSize() const { return theImageSize; }
+
+   /*!
+    * This is from the adjustable parameter interface.  It is
+    * called when a paraemter adjustment is made.
+    */
+   virtual void adjustableParametersChanged()
+      {
+         updateModel();
+      }
+   /*!
+    * VIRTUAL METHOD: updateModel()
+    * Following a change to the adjustable parameter set, this virtual
+    * is called to permit instances to compute derived quantities after
+    * parameter change.
+    */
+   virtual void updateModel() {}
+
+   /*!
+    * METHODS:  saveState, loadState
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   /*!
+    * METHOD: insideImage(image_point)
+    * Returns true if the image_point lies inside the image rectangle.
+    */
+   virtual bool insideImage(const ossimDpt& p) const
+      {
+/*          return( (p.u>=(0.0-FLT_EPSILON)) && */
+/*                  (p.u<=(double)(theImageSize.u-(1-FLT_EPSILON))) && */
+/*                  (p.v>=(0.0-FLT_EPSILON)) && */
+/*                  (p.v<=(double)(theImageSize.v-(1-FLT_EPSILON))) ); */
+         return theImageClipRect.pointWithin(p);
+      }
+
+   /*!
+    * STATIC METHOD: writeGeomTemplate(ostream)
+    * Writes a template of keywords processed by loadState and saveState to
+    * output stream.
+    */
+   static void writeGeomTemplate(ostream& os);
+
+   /*!
+    * OPERATORS: 
+    */
+   virtual bool operator==(const ossimProjection& proj) const; //inline below
+
+protected:
+   /*!
+    * METHOD: extrapolate()
+    * Extrapolates solutions for points outside of the image. The second
+    * version accepts a height value -- if left at the default, the elevation
+    * will be looked up via theElevation object.
+    */
+   virtual ossimDpt extrapolate (const ossimGpt& gp) const;
+   virtual ossimGpt extrapolate (const ossimDpt& ip,
+				 const double& height
+				 =ossimElevSource::DEFAULT_NULL_HEIGHT) const;
+
+   ossimIpt       theImageSize;       // pixels
+
+   /*!
+    * Support sub-image of larger full image by maintaining offset to UL corner
+    */
+   ossimDpt       theSubImageOffset;  // pixels
+   
+   ossimString    theImageID;
+   ossimString    theSensorID;
+   ossimDpt       theGSD;             // meters
+   ossim_float64  theMeanGSD;         // meters
+   ossimGpt       theRefGndPt;        // should be image center
+   ossimDpt       theRefImgPt;        // should be image center
+   ossimPolygon   theBoundGndPolygon;
+   ossimDrect     theImageClipRect;
+   ossim_float64  theNominalPosError; // meters
+  
+TYPE_DATA
+};
+
+//================= BEGIN INLINE DEFINITIONS =================================
+
+//*****************************************************************************
+//  OPERATOR == 
+//*****************************************************************************
+inline bool ossimSensorModel::operator==(const ossimProjection& proj) const
+{
+   const  ossimSensorModel* model
+      = PTR_CAST(ossimSensorModel, (const ossimProjection*) &proj);
+    
+   if ( (!model) ||
+	(theSensorID != model->theSensorID) ||
+	(theImageID != model->theImageID) ||
+	(theSubImageOffset != model->theSubImageOffset) )
+      return false;
+
+   return true;
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/.cvsignore b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimIkonosRpcModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimIkonosRpcModel.cpp
new file mode 100644
index 0000000000..d711acb5cd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimIkonosRpcModel.cpp
@@ -0,0 +1,601 @@
+//*****************************************************************************
+// FILE: ossimIkonosRpcModel.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains implementation of class ossimIkonosRpcModel. This 
+//    derived class implements the capability of reading Ikonos RPC support
+//    data.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimIkonosRpcModel.cpp,v 1.10 2004/04/08 13:27:34 gpotts Exp $
+#include <projections/sensor_modeling/rpc/ossimIkonosRpcModel.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimIkonosRpcModel, "ossimIkonosRpcModel", ossimRpcModel);
+
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimIkonosRpcModel:exec");
+static ossimTrace traceDebug ("ossimIkonosRpcModel:debug");
+
+static const char* MODEL_TYPE        = "ossimIkonosRpcModel";
+static const char* META_DATA_FILE    = "meta_data_file";
+static const char* RPC_DATA_FILE     = "rpc_data_file";
+static const char* LINE_OFF_KW       = "LINE_OFF";
+static const char* SAMP_OFF_KW       = "SAMP_OFF";
+static const char* LAT_OFF_KW        = "LAT_OFF";
+static const char* LONG_OFF_KW       = "LONG_OFF";
+static const char* HEIGHT_OFF_KW     = "HEIGHT_OFF";
+static const char* LINE_SCALE_KW     = "LINE_SCALE";
+static const char* SAMP_SCALE_KW     = "SAMP_SCALE";
+static const char* LAT_SCALE_KW      = "LAT_SCALE";
+static const char* LONG_SCALE_KW     = "LONG_SCALE";
+static const char* HEIGHT_SCALE_KW   = "HEIGHT_SCALE";
+static const char* LINE_NUM_COEFF_KW = "LINE_NUM_COEFF_";
+static const char* LINE_DEN_COEFF_KW = "LINE_DEN_COEFF_";
+static const char* SAMP_NUM_COEFF_KW = "SAMP_NUM_COEFF_";
+static const char* SAMP_DEN_COEFF_KW = "SAMP_DEN_COEFF_";
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimIkonosRpcModel
+//  
+//  Constructs given a geometry file that specifies the filenames for the
+//  metadata and RPC data files.
+//  
+//*****************************************************************************
+ossimIkonosRpcModel::ossimIkonosRpcModel(const ossimFilename& geom_file)
+   :  ossimRpcModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel Constructor #1: entering..." << std::endl;
+
+   ossimKeywordlist kwl(geom_file);
+   const char* value;
+   
+   //***
+   // Assure this keywordlist contains correct type info:
+   //***
+   value = kwl.find(ossimKeywordNames::TYPE_KW);
+   if (!value || (strcmp(value, "ossimIkonosRpcModel")))
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG  ossimIkonosRpcModel Constructor #1:"
+                                             << "\nFailed attempt to construct. sensor type \""<<value
+                                             << "\" does not match \"ossimIkonosRpcModel\"." << std::endl;
+      }
+
+      theErrorStatus++;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG  ossimIkonosRpcModel Constructor #1: returning..." << std::endl;
+      return;
+   }
+
+   //***
+   // Read meta data filename from geom file:
+   //***
+   value = kwl.find(META_DATA_FILE);
+   if (!value)
+   {
+      theErrorStatus++;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel Constructor #1: returning..." << std::endl;
+      return;
+   }
+
+   ossimFilename metadata (value);
+
+   //***
+   // Read RPC data filename from geom file:
+   //***
+   value = kwl.find(RPC_DATA_FILE);
+   if (!value)
+   {
+      theErrorStatus++;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG  ossimIkonosRpcModel Constructor #1: returning..." << std::endl;
+      return;
+   }
+   ossimFilename rpcdata (value);
+
+   parseMetaData(metadata);
+   parseRpcData (rpcdata);
+   finishConstruction();
+
+   ossimString drivePart;
+   ossimString pathPart;
+   ossimString filePart;
+   ossimString extPart;
+   geom_file.split(drivePart,
+                   pathPart,
+                   filePart,
+                   extPart);
+
+   
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG returning..." << std::endl;
+   
+   return;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimIkonosRpcModel
+//  
+//  Constructs given filenames for metadata and RPC data.
+//  
+//*****************************************************************************
+ossimIkonosRpcModel::ossimIkonosRpcModel(const ossimFilename& metadata,
+                                         const ossimFilename& rpcdata)
+   :
+      ossimRpcModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel Constructor #2: entering..." << std::endl;
+
+   parseMetaData(metadata);
+   parseRpcData (rpcdata);
+   finishConstruction();
+
+   //***
+   // Save current state in RPC model format:
+   //***
+   ossimString drivePart;
+   ossimString pathPart;
+   ossimString filePart;
+   ossimString extPart;
+   metadata.split(drivePart,
+                  pathPart,
+                  filePart,
+                  extPart);
+   
+   ossimFilename init_rpc_geom;
+   init_rpc_geom.merge(drivePart,
+                       pathPart,
+                       ossimRpcModel::INIT_RPC_GEOM_FILENAME,
+                       "");
+//      (metadata.path().dirCat(ossimRpcModel::INIT_RPC_GEOM_FILENAME));
+   ossimKeywordlist kwl (init_rpc_geom);
+   saveState(kwl);
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel Constructor #2: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  METHOD: ossimIkonosRpcModel::finishConstruction()
+//  
+//*****************************************************************************
+void ossimIkonosRpcModel::finishConstruction()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel finishConstruction(): entering..." << std::endl;
+
+   //***
+   // Assign other data members:
+   //***
+   thePolyType      = B; // This may not be true for early RPC imagery
+   theRefImgPt.line = theLineOffset;
+   theRefImgPt.samp = theSampOffset;
+   theRefGndPt.lat  = theLatOffset;
+   theRefGndPt.lon  = theLonOffset;
+   theRefGndPt.hgt  = theHgtOffset;
+   theMeanGSD       = (theGSD.x + theGSD.y)/2.0;
+
+   //***
+   // Assign the bounding image space rectangle:
+   //***
+   theImageClipRect = ossimDrect(0.0, 0.0,
+                                 theImageSize.samp-1, theImageSize.line-1);
+
+   //***
+   // Assign the bounding ground polygon:
+   //***
+   ossimGpt v0, v1, v2, v3;
+   ossimDpt ip0 (0.0, 0.0);
+   lineSampleHeightToWorld(ip0, 0.0, v0);
+   ossimDpt ip1 (theImageSize.samp-1.0, 0.0);
+   lineSampleHeightToWorld(ip1, 0.0, v1);
+   ossimDpt ip2 (theImageSize.samp-1.0, theImageSize.line-1.0);
+   lineSampleHeightToWorld(ip2, 0.0, v2);
+   ossimDpt ip3 (0.0, theImageSize.line-1.0);
+   lineSampleHeightToWorld(ip3, 0.0, v3);
+   theBoundGndPolygon
+      = ossimPolygon (ossimDpt(v0), ossimDpt(v1), ossimDpt(v2), ossimDpt(v3));
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel finishConstruction(): returning..." << std::endl;
+   return;
+}
+
+//*****************************************************************************
+// PROTECTED METHOD: ossimIkonosRpcModel::parseMetaData()
+//  
+//  Parses the Ikonos metadata file.
+//  
+//*****************************************************************************
+void ossimIkonosRpcModel::parseMetaData(const ossimFilename& data_file)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel::parseMetaData(data_file): entering..." << std::endl;
+
+   FILE* fptr = fopen (data_file, "r");
+   if (!fptr)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseMetaData(data_file): Could not open Meta data file <" << data_file << ">. "
+                                          << "Aborting..." << std::endl;
+      theErrorStatus++;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel::parseMetaData(data_file): returning with error..." << std::endl;
+      return;
+   }
+
+   char* strptr;
+   char linebuf[80];
+   char dummy[80], name[80];
+
+   //***
+   // Read the file into a buffer:
+   //***
+   char filebuf[5000];
+   fread(filebuf, 1, 5000, fptr);
+   
+   //***
+   // Image ID:
+   //***
+   strptr = strstr(filebuf, "\nSource Image ID:");
+   if (!strptr)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseMetaData(data_file): "
+                                          << "\n\tAborting construction. Error encountered parsing "
+                                          << "presumed meta-data file." << endl;
+      
+      return;
+   }
+      
+   sscanf(strptr, "%17c %s", dummy, name);
+   theImageID = name;
+
+   //***
+   // Sensor Type:
+   //***
+   strptr = strstr(strptr, "\nSensor:");
+   if (!strptr)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseMetaData(data_file): "
+                                             << "\n\tAborting construction. Error encountered parsing "
+                                             << "presumed meta-data file." << endl;
+         
+         return;
+      }
+   }
+   sscanf(strptr, "%8c %s", dummy, name);
+   theSensorID = name;
+
+   //***
+   // GSD:
+   //***
+   strptr = strstr(strptr, "\nPixel Size X:");
+   if (!strptr)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseMetaData(data_file): "
+                                             << "\n\tAborting construction. Error encountered parsing "
+                                             << "presumed meta-data file." << endl;
+         
+         return;
+      }
+   }
+   sscanf(strptr, "%14c %lf", dummy, &theGSD.samp);
+   strptr = strstr(strptr, "\nPixel Size Y:");
+   if (!strptr)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseMetaData(data_file): "
+                                             << "\n\tAborting construction. Error encountered parsing "
+                                             << "presumed meta-data file." << endl;
+         
+         return;
+      }
+   }
+   sscanf(linebuf, "%14c %lf", dummy, &theGSD.line);
+
+   //***
+   // Image size:
+   //***
+   strptr = strstr(strptr, "\nColumns:");
+   if (!strptr)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseMetaData(data_file): "
+                                             << "\n\tAborting construction. Error encountered parsing "
+                                             << "presumed meta-data file." << endl;
+         
+         return;
+      }
+   }
+   sscanf(strptr, "%s %d", dummy, &theImageSize.samp);
+   strptr = strstr(strptr, "\nRows:");
+   if (!strptr)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseMetaData(data_file): "
+                                             << "\n\tAborting construction. Error encountered parsing "
+                                             << "presumed meta-data file." << endl;
+         
+         return;
+      }
+   }
+   sscanf(strptr, "%s %d", dummy, &theImageSize.line);
+           
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel::parseMetaData(data_file): returning..." << std::endl;
+   return;
+}
+
+
+//*****************************************************************************
+// PROTECTED METHOD: ossimIkonosRpcModel::parseRpcData()
+//  
+//  Parses the Ikonos RPC data file.
+//  
+//*****************************************************************************
+void ossimIkonosRpcModel::parseRpcData(const ossimFilename& data_file)
+{
+   if (traceExec())   ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel::parseRpcData(data_file): entering..." << std::endl;
+
+   //***
+   // The Ikonos RPC data file is conveniently formatted as KWL file:
+   //***
+   ossimKeywordlist kwl (data_file);
+   if (kwl.getErrorStatus())
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "ERROR ossimIkonosRpcModel::parseRpcData(data_file): Could not open RPC data file <" << data_file << ">. "
+                                          << "Aborting..." << std::endl;
+      theErrorStatus++;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "returning with error..." << std::endl;
+      return;
+   }
+
+   const char* buf;
+   const char* keyword;
+   
+   //***
+   // Parse data from KWL:
+   //***
+   keyword = LINE_OFF_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+   theLineOffset = atof(buf);
+      
+   keyword = SAMP_OFF_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+   theSampOffset = atof(buf);
+
+   keyword = LAT_OFF_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+      
+   theLatOffset = atof(buf);
+   
+   keyword = LONG_OFF_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+   theLonOffset = atof(buf);
+
+   keyword = HEIGHT_OFF_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+      
+   theHgtOffset = atof(buf);
+
+   keyword = LINE_SCALE_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+   theLineScale = atof(buf);
+   
+   keyword = SAMP_SCALE_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+   theSampScale = atof(buf);
+   
+   keyword = LAT_SCALE_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+
+   theLatScale = atof(buf);
+   
+   keyword = LONG_SCALE_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+   theLonScale = atof(buf);
+   
+   keyword = HEIGHT_SCALE_KW;
+   buf = kwl.find(keyword);
+   if (!buf)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                          << "\nAborting construction. Error looking up keyword: "
+                                          << keyword << std::endl;
+      return;
+   }
+      
+   theHgtScale = atof(buf);
+   
+   char kwbuf[32];
+   keyword = kwbuf;
+   for(int i=1; i<=20; i++)
+   {
+      sprintf(kwbuf, "%s%d", LINE_NUM_COEFF_KW, i);
+      buf = kwl.find(keyword);
+      if (!buf)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                             << "\nAborting construction. Error looking up keyword: "
+                                             << keyword << std::endl;
+         return;
+      }
+      
+      theLineNumCoef[i-1] = atof(buf);
+      
+      sprintf(kwbuf, "%s%d", LINE_DEN_COEFF_KW, i);
+      buf = kwl.find(keyword);
+      if (!buf)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                             << "\nAborting construction. Error looking up keyword: "
+                                             << keyword << std::endl;
+         return;
+      }
+      theLineDenCoef[i-1] = atof(buf);
+      
+      sprintf(kwbuf, "%s%d", SAMP_NUM_COEFF_KW, i);
+      buf = kwl.find(keyword);
+      if (!buf)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                             << "\nAborting construction. Error looking up keyword: "
+                                             << keyword << std::endl;
+         return;
+      }
+      theSampNumCoef[i-1] = atof(buf);
+      
+      sprintf(kwbuf, "%s%d", SAMP_DEN_COEFF_KW, i);
+      buf = kwl.find(keyword);
+      if (!buf)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimIkonosRpcModel::parseRpcData(data_file):"
+                                             << "\nAborting construction. Error looking up keyword: "
+                                             << keyword << std::endl;
+         return;
+      }
+      theSampDenCoef[i-1] = atof(buf);
+   }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel::parseRpcData(data_file): returning..." << std::endl;
+   return;
+
+   theErrorStatus++;
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimIkonosRpcModel::parseRpcData(data_file): returning with error..." << std::endl;
+   
+   return;
+}
+
+//*****************************************************************************
+//  METHOD: ossimIkonosRpcModel::writeGeomTemplate()
+//  
+//   Writes a template of an ossimIkonosRpcModel geometry file.
+//  
+//*****************************************************************************
+void ossimIkonosRpcModel::writeGeomTemplate(ostream& os)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::writeGeomTemplate(os): entering..." << std::endl;
+
+   os <<
+      "//**************************************************************\n"
+      "// Template for Ikonos RPC geometry keywordlist\n"
+      "//\n"
+      "// NOTE: It is preferable to select the full RPC geometry KWL \n"
+      "//       that should have been created with the first use of the\n"
+      "//       derived model type ossimIkonosRpcModel. Using this KWL \n"
+      "//       implies that an initial geometry is being constructed \n"
+      "//       with all adjustable parameters initialized to 0. \n"
+      "//**************************************************************\n"
+      << ossimKeywordNames::TYPE_KW << ": " << MODEL_TYPE << endl;
+   os << META_DATA_FILE << ": <string>\n"
+      << RPC_DATA_FILE  << ": <string>\n" << endl;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::writeGeomTemplate(os): returning..." << std::endl;
+   return;
+}
+
+bool ossimIkonosRpcModel::saveState(ossimKeywordlist& kwl,
+				    const char* prefix)const
+{
+  ossimRpcModel::saveState(kwl, prefix);
+
+  // this model just sets the base class values so
+  // we do not need to re-construct this model so 
+  // specify the type as the base class type
+  //
+  kwl.add(prefix,
+	  ossimKeywordNames::TYPE_KW,
+	  STATIC_TYPE_NAME(ossimRpcModel),
+	  true);
+
+  return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimIkonosRpcModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimIkonosRpcModel.h
new file mode 100644
index 0000000000..c8970503a1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimIkonosRpcModel.h
@@ -0,0 +1,68 @@
+//*****************************************************************************
+// FILE: ossimIkonosRpcModel.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// AUTHOR: Oscar Kramer (okramer@imagelinks.com)
+//
+// DESCRIPTION: Contains declaration of class ossimIkonosRpcModel. This 
+//    derived class implements the capability of reading Ikonos RPC support
+//    data.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimIkonosRpcModel.h,v 1.2 2003/12/31 13:25:07 gpotts Exp $
+
+#ifndef ossimIkonosRpcModel_HEADER
+#define ossimIkonosRpcModel_HEADER
+
+#include "ossimRpcModel.h"
+
+class ossimFilename;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimIkonosRpcModel
+ *
+ *****************************************************************************/
+class ossimIkonosRpcModel : public ossimRpcModel
+{
+public:
+   ossimIkonosRpcModel(const ossimFilename& geom_file);
+
+   ossimIkonosRpcModel(const ossimFilename& metadata,
+                       const ossimFilename& rpcdata);
+
+  virtual bool saveState(ossimKeywordlist& kwl,
+			 const char* prefix=0)const;
+   /*!
+    * STATIC METHOD: writeGeomTemplate(ostream)
+    * Writes a template of an ossimIkonosRpcModel geometry file.
+    */
+   static void writeGeomTemplate(ostream& os);
+   
+protected:
+   void finishConstruction();
+   void parseMetaData(const ossimFilename& metadata);
+   void parseRpcData (const ossimFilename& rpcdata);
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimNitfRpcModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimNitfRpcModel.cpp
new file mode 100644
index 0000000000..5f0e9fd96a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimNitfRpcModel.cpp
@@ -0,0 +1,466 @@
+//*****************************************************************************
+// FILE: ossimNitfRpcModel.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class ossimNitfRpcModel. This 
+//    derived class implements the capability of reading Nitf RPC support
+//    data.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimNitfRpcModel.cpp,v 1.19 2004/12/21 16:49:22 gpotts Exp $
+
+#include <projections/sensor_modeling/rpc/ossimNitfRpcModel.h>
+
+RTTI_DEF1(ossimNitfRpcModel, "ossimNitfRpcModel", ossimRpcModel);
+
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/context/ossimNotifyContext.h>
+#include <support_data/nitf/ossimNitfFile.h>
+#include <support_data/nitf/ossimNitfFileHeader.h>
+#include <support_data/nitf/ossimNitfImageHeader.h>
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimNitfRpcModel:exec");
+static ossimTrace traceDebug ("ossimNitfRpcModel:debug");
+
+static const char* RPC00A_TAG = "RPC00A";
+static const char* RPC00B_TAG = "RPC00B";
+static const char* PIAIMC_TAG = "PIAIMC";
+static const char* STDIDC_TAG = "STDIDC";
+static const char* USE26A_TAG = "USE26A";
+static const char* USE00A_TAG = "USE00A";
+
+ossimNitfRpcModel::ossimNitfRpcModel()
+  :ossimRpcModel(),
+   theBiasError(0.0),
+   theRandError(0.0)
+{
+}
+
+ossimNitfRpcModel::ossimNitfRpcModel(const ossimNitfRpcModel& rhs)
+  :ossimRpcModel(rhs),
+   theBiasError(0.0),
+   theRandError(0.0)
+{
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimNitfRpcModel
+//  
+//  Constructs given filename for NITF file
+//  
+//*****************************************************************************
+ossimNitfRpcModel::ossimNitfRpcModel(const ossimFilename& nitfFile)
+   :
+      ossimRpcModel()
+{
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimNitfRpcModel::ossimNitfRpcModel(nitfFile): entering..."
+         << std::endl;
+   }
+
+   ossimNitfFile* file = new ossimNitfFile;
+
+   if(!file->parseFile(nitfFile))
+   {
+      delete file;
+      return;
+   }
+   const ossimNitfFileHeader* header = file->getHeader();
+
+   if(!header)
+   {
+      delete file;
+      return;
+   }
+   ossimNitfImageHeader* ih = file->getNewImageHeader(0);
+
+   if(!ih)
+   {
+      delete file;
+      return;
+   }
+
+   std::ifstream in(nitfFile.c_str());
+
+   char charbuf[128];
+   //***
+   // Open the NITF file:
+   //***
+   if (!in)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfRpcModel::ossimNitfRpcModel DEBUG:"
+            << "\nCould not open NITF file at: <"
+            << nitfFile << ">."
+            << "\nAborting with error..."
+            << std::endl;
+      }
+
+      theErrorStatus++;
+      delete ih;
+      delete file;
+      return;
+   }
+
+   //***
+   // Fetch Image ID:
+   //***
+   theImageID = ih->getImageId();
+
+
+   ossimIrect imageRect = ih->getImageRect();
+   
+   //***
+   // Fetch Image Size:
+   //***
+   theImageSize.line = imageRect.height();
+   theImageSize.samp = imageRect.width();
+      
+   ossimNitfTagInformation tag;
+   if(ih->getTag(tag, PIAIMC_TAG))
+   {
+//      in.seekg(tag.getTagDataOffset()+348);
+      in.seekg(tag.getTagDataOffset()+337);
+      
+      //***
+      // Parse the tag for GSD (in inches):
+      //***
+      in.read(charbuf, 7);
+      charbuf[7] = '\0';
+      theGSD.line = atof(charbuf)/12.0 * MTRS_PER_FT;
+      theGSD.samp = theGSD.line;
+   }
+   else if(ih->getTag(tag, USE26A_TAG))
+   {
+	   //***
+	   // Parse the tag for GSD (in inches):
+	   //***
+	   //         in.seekg(tag.getTagDataOffset()+15);
+	   in.seekg(tag.getTagDataOffset()+4);
+	   in.read(charbuf, 5);
+	   charbuf[6] = '\0';
+	   theGSD.line = atof(charbuf)/12.0 * MTRS_PER_FT;
+	   theGSD.samp = theGSD.line;
+   }
+   else if(ih->getTag(tag, USE00A_TAG))
+   {
+	   in.seekg(tag.getTagDataOffset()+4);
+	   in.read(charbuf, 5);
+	   charbuf[6] = '\0';
+	   theGSD.line = atof(charbuf)/12.0 * MTRS_PER_FT;
+	   theGSD.samp = theGSD.line;
+   }
+   else
+   {
+      theGSD.line = OSSIM_DBL_NAN;
+      theGSD.samp = OSSIM_DBL_NAN;
+   }
+      
+   //***
+   // Search for the STDID Tag to fetch mission (satellite) name:
+   //***
+   if(ih->getTag(tag, STDIDC_TAG))
+   {
+	   in.seekg(tag.getTagDataOffset()+14);
+	   in.read(charbuf, 14);
+	   charbuf[14] = '\0';
+	   theSensorID = charbuf;
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfRpcModel::ossimNitfRpcModel DEBUG:"
+            << "\nCould not find the STDIDC tag <" << STDIDC_TAG
+            << ">\n in the NITF file at: <"
+            << nitfFile << ">." << " Setting platform ID to \"UNKNOWN\"..."
+            << std::endl;
+      }
+
+      theSensorID = "UNKNOWN";
+   }
+   
+   //---
+   // Search the header for the start of the RPC tag:
+   //---
+   if(ih->getTag(tag, RPC00A_TAG))
+   {
+      thePolyType = A;
+   }
+   else
+   {
+      if(ih->getTag(tag, RPC00B_TAG))
+      {
+         thePolyType = B;
+      }
+      else
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "ossimNitfRpcModel::ossimNitfRpcModel DEBUG:"
+               << "\nCould not find neither RPC tags <" << RPC00A_TAG
+               << "> nor <" << RPC00B_TAG << "> in the NITF file at: <"
+               << nitfFile << ">." << " Aborting with error..."
+               << std::endl;
+         }
+
+         theErrorStatus++;
+         delete ih;
+         delete file;
+         return;
+      }
+   }
+
+   char* tag_ptr = new char[tag.getTagLength()];
+   in.seekg(tag.getTagDataOffset());
+   in.read(tag_ptr, tag.getTagLength());
+
+   //***
+   // Now parse the tag block for pertinent data:
+   //***
+   int line_off, samp_off, hgt_off, line_scl, samp_scl, hgt_scl;
+   
+   char* tempBufPtr = tag_ptr;
+   
+   theBiasError = ossimString(tempBufPtr+1,
+                              tempBufPtr+8).toDouble();
+   tempBufPtr+=8;
+   theRandError = ossimString(tempBufPtr,
+                              tempBufPtr+7).toDouble();
+   tempBufPtr+=7;
+   line_off = ossimString(tempBufPtr,
+                          tempBufPtr+6).toInt();
+   tempBufPtr+=6;
+   samp_off = ossimString(tempBufPtr,
+                          tempBufPtr+5).toInt();
+   tempBufPtr+=5;
+   
+   theLatOffset = ossimString(tempBufPtr,
+                              tempBufPtr+8).toDouble();
+   tempBufPtr+=8;
+
+   theLonOffset = ossimString(tempBufPtr,
+                              tempBufPtr+9).toDouble();
+   tempBufPtr+=9;
+
+   hgt_off = ossimString(tempBufPtr,
+                         tempBufPtr+5).toInt();
+   tempBufPtr+=5;
+   line_scl = ossimString(tempBufPtr,
+                         tempBufPtr+6).toInt();
+   tempBufPtr+=6;
+   samp_scl = ossimString(tempBufPtr,
+                         tempBufPtr+5).toInt();
+   tempBufPtr+=5;
+   theLatScale = ossimString(tempBufPtr,
+                              tempBufPtr+8).toDouble();
+   tempBufPtr+=8;
+
+   theLonScale = ossimString(tempBufPtr,
+                              tempBufPtr+9).toDouble();
+   tempBufPtr+=9;
+   hgt_scl = ossimString(tempBufPtr,
+                         tempBufPtr+5).toInt();
+   tempBufPtr+=5;
+   
+//    sscanf(tag_ptr,
+//           "%7lf %7lf %6d %5d %8lf %9lf %5d %6d %5d %8lf %9lf %5d",
+//           &theBiasError,
+//           &theRandError,
+//           &line_off,
+//           &samp_off,
+//           &theLatOffset,
+//           &theLonOffset,
+//           &hgt_off,
+//           &line_scl,
+//           &samp_scl,
+//           &theLatScale,
+//           &theLonScale,
+//           &hgt_scl);
+
+//    cout << "******************bias error he got is " << theBiasError << endl;
+   theLineOffset = (double) line_off;
+   theSampOffset = (double) samp_off;
+   theHgtOffset  = (double) hgt_off;
+   theLineScale  = (double) line_scl;
+   theSampScale  = (double) samp_scl;
+   theHgtScale   = (double) hgt_scl;
+
+//    theRefImgPt.line = theLineOffset;
+//    theRefImgPt.samp = theSampOffset;
+//    theRefGndPt.lat  = theLatOffset;
+//    theRefGndPt.lon  = theLonOffset;
+//    theRefGndPt.hgt = theHgtOffset;
+
+   //***
+   // Parse coefficients:
+   //***
+   tempBufPtr = tag_ptr + 81;
+//   tag_ptr += 92;
+//   tag_ptr += 92;
+   for (int i=0; i<20; i++)
+   {
+      sscanf(tempBufPtr, "%12lf", &theLineNumCoef[i]);
+      tempBufPtr += 12;
+   }
+   for (int i=0; i<20; i++)
+   {
+      sscanf(tempBufPtr, "%12lf", &theLineDenCoef[i]);
+      tempBufPtr += 12;
+   }
+   for (int i=0; i<20; i++)
+   {
+      sscanf(tempBufPtr, "%12lf", &theSampNumCoef[i]);
+      tempBufPtr += 12;
+   }
+   for (int i=0; i<20; i++)
+   {
+      sscanf(tempBufPtr, "%12lf", &theSampDenCoef[i]);
+      tempBufPtr += 12;
+   }
+
+   delete [] tag_ptr;
+   //***
+   // Assign other data members to default values:
+   //***
+   theNominalPosError = sqrt(theBiasError*theBiasError +
+                             theRandError*theRandError); // meters
+
+   delete ih;
+   delete file;
+   
+   //***
+   // Assign other data members:
+   //***
+   thePolyType = B; // This may not be true for early RPC imagery
+   theRefImgPt.line = theImageSize.line/2.0;
+   theRefImgPt.samp = theImageSize.samp/2.0;
+   theRefGndPt.lat  = theLatOffset;
+   theRefGndPt.lon  = theLonOffset;
+   theRefGndPt.hgt  = theHgtOffset;
+   
+   
+   
+
+   //***
+   // Assign the bounding image space rectangle:
+   //***
+   theImageClipRect = ossimDrect(0.0, 0.0,
+                                 theImageSize.samp-1, theImageSize.line-1);
+
+   //***
+   // Assign the bounding ground polygon:
+   //***
+   ossimGpt v0, v1, v2, v3;
+   ossimDpt ip0 (0.0, 0.0);
+   lineSampleHeightToWorld(ip0, theHgtOffset, v0);
+   ossimDpt ip1 (theImageSize.samp-1.0, 0.0);
+   lineSampleHeightToWorld(ip1, theHgtOffset, v1);
+   ossimDpt ip2 (theImageSize.samp-1.0, theImageSize.line-1.0);
+   lineSampleHeightToWorld(ip2, theHgtOffset, v2);
+   ossimDpt ip3 (0.0, theImageSize.line-1.0);
+   lineSampleHeightToWorld(ip3, theHgtOffset, v3);
+
+   theBoundGndPolygon
+      = ossimPolygon (ossimDpt(v0), ossimDpt(v1), ossimDpt(v2), ossimDpt(v3));
+
+   
+   lineSampleHeightToWorld(theRefImgPt, theHgtOffset, theRefGndPt);
+
+   if( (theGSD.line == OSSIM_DBL_NAN) || (theGSD.samp == OSSIM_DBL_NAN) )
+   {
+	   ossimGpt rightGpt;
+	   ossimGpt topGpt;
+	   
+	   lineSampleHeightToWorld(theRefImgPt + ossimDpt(1, 0),
+							   theHgtOffset,
+							   rightGpt);
+	   lineSampleHeightToWorld(theRefImgPt + ossimDpt(0, -1),
+							   theHgtOffset,
+							   topGpt);
+	   ossimEcefPoint rightPt = rightGpt;
+	   ossimEcefPoint topPt   = topGpt;
+	   ossimEcefPoint origin  = theRefGndPt;
+	   
+	   ossim_float64 gsdx = (rightPt-origin).magnitude();
+	   ossim_float64 gsdy = (topPt-origin).magnitude();
+	   theGSD.x = (gsdx + gsdy)/2.0;
+	   theGSD.y = theGSD.x;
+   }
+   theMeanGSD = (theGSD.x + theGSD.y)/2.0;
+   if (ossimString::toString(theRefGndPt.lat).trim().upcase() == "NAN" 
+       || ossimString::toString(theRefGndPt.lon).trim().upcase() == "NAN")
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfRpcModel::ossimNitfRpcModel DEBUG:"
+            << "\nGround Reference Point not valid." 
+            << " Aborting with error..."
+            << std::endl;
+      }
+
+      theErrorStatus++;
+      delete ih;
+      return;
+   }
+
+   ossimString drivePart;
+   ossimString pathPart;
+   ossimString filePart;
+   ossimString extPart;
+   nitfFile.split(drivePart,
+                  pathPart,
+                  filePart,
+                  extPart);
+   
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimNitfRpcModel::ossimNitfRpcModel: returning..."
+         << std::endl;
+   }
+   return;
+}
+
+bool ossimNitfRpcModel::saveState(ossimKeywordlist& kwl,
+				           const char* prefix) const
+{
+  kwl.add(prefix, 
+	  "bias_error",
+	  theBiasError,
+	  true);
+  kwl.add(prefix,
+	  "rand_error",
+	  theRandError,
+	  true);
+  
+  return ossimRpcModel::saveState(kwl, prefix);
+}
+
+bool ossimNitfRpcModel::loadState(const ossimKeywordlist& kwl,
+				  const char* prefix)
+{
+  theBiasError = ossimString(kwl.find(prefix, "bias_error")).toDouble();
+  theRandError = ossimString(kwl.find(prefix, "rand_error")).toDouble();
+
+  return ossimRpcModel::loadState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimNitfRpcModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimNitfRpcModel.h
new file mode 100644
index 0000000000..95a6b80978
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimNitfRpcModel.h
@@ -0,0 +1,53 @@
+//*****************************************************************************
+// FILE: ossimNitfRpcModel.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains declaration of class ossimNitfRpcModel. This 
+//    derived class implements the capability of reading Nitf RPC support
+//    data.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimNitfRpcModel.h,v 1.4 2005/09/09 19:23:58 gpotts Exp $
+
+#ifndef ossimNitfRpcModel_HEADER
+#define ossimNitfRpcModel_HEADER
+
+#include "ossimRpcModel.h"
+
+class ossimFilename;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimNitfRpcModel
+ *
+ *****************************************************************************/
+class ossimNitfRpcModel : public ossimRpcModel
+{
+public:
+   ossimNitfRpcModel();
+   ossimNitfRpcModel(const ossimNitfRpcModel& rhs);
+   ossimNitfRpcModel(const ossimFilename& nitfFile);
+   virtual ossimObject* dup() const { return new ossimNitfRpcModel(*this); }
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+private:
+   double theBiasError;
+   double theRandError;
+
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.cpp
new file mode 100644
index 0000000000..6b3ebd4145
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.cpp
@@ -0,0 +1,534 @@
+//*****************************************************************************
+// FILE: ossimQuickbirdRpcModel.cpp
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION: Contains declaration of class ossimQuickbirdRpcModel. This 
+//    derived class implements the capability of reading Quickbird RPC support
+//    data.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimQuickbirdRpcModel.cpp,v 1.6 2005/11/08 20:04:13 dburken Exp $
+
+#include <projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.h>
+#include <support_data/qb/ossimQuickbirdRpcHeader.h>
+#include <support_data/qb/ossimQuickbirdTile.h>
+#include <support_data/nitf/ossimNitfFile.h>
+#include <support_data/nitf/ossimNitfFileHeader.h>
+#include <support_data/nitf/ossimNitfImageHeader.h>
+#include <imaging/formats/tiff/ossimTiffTileSource.h>
+
+static const char* RPC00A_TAG = "RPC00A";
+static const char* RPC00B_TAG = "RPC00B";
+static const char* PIAIMC_TAG = "PIAIMC";
+// static const char* STDIDC_TAG = "STDIDC";
+static const char* USE26A_TAG = "USE26A";
+static const char* USE00A_TAG = "USE00A";
+
+
+RTTI_DEF1(ossimQuickbirdRpcModel, "ossimQuickbirdRpcModel", ossimRpcModel);
+
+
+ossimQuickbirdRpcModel::ossimQuickbirdRpcModel()
+      :ossimRpcModel()
+{
+}
+
+ossimQuickbirdRpcModel::ossimQuickbirdRpcModel(const ossimQuickbirdRpcModel& rhs)
+      : ossimRpcModel(rhs)
+{
+}
+
+ossimObject* ossimQuickbirdRpcModel::dup() const
+{
+   return new ossimQuickbirdRpcModel(*this);
+}
+
+bool ossimQuickbirdRpcModel::parseFile(const ossimFilename& file)
+{
+   if (!parseNitfFile(file))
+   {
+      return parseTiffFile(file);
+   }
+   return true;
+}
+
+bool ossimQuickbirdRpcModel::parseNitfFile(const ossimFilename& file)
+{
+   ossimFilename nitfFile = file;
+   
+   ossimRefPtr<ossimNitfFile> nitfFilePtr = new ossimNitfFile;
+   
+   if(!nitfFilePtr->parseFile(nitfFile))
+   {
+      nitfFile = nitfFile.setExtension("NTF");
+      if(!nitfFilePtr->parseFile(nitfFile))
+      {
+         nitfFile = nitfFile.setExtension("ntf");
+         if(!nitfFilePtr->parseFile(nitfFile))
+         {
+            return false;
+         }
+      }
+   }
+
+   ossimQuickbirdRpcHeader hdr;
+   ossimQuickbirdTile tileHdr;
+   ossimFilename tileFile = file;
+   ossimFilename rpcFile = file;
+
+   tileFile = tileFile.replaceAllThatMatch("_R[0-9]+C[0-9]+");
+   rpcFile  = rpcFile.replaceAllThatMatch("_R[0-9]+C[0-9]+");
+   bool useInternalRpcTags = false;
+   
+   if(!hdr.open(rpcFile))
+   {
+      rpcFile = rpcFile.setExtension("RPB");
+      if(!hdr.open(rpcFile))
+      {
+         rpcFile = rpcFile.setExtension("rpb");
+         if(!hdr.open(rpcFile))
+         {
+            useInternalRpcTags = true;
+         }
+      }
+   }
+   
+   tileFile = tileFile.setExtension("TIL");
+   if(!tileHdr.open(tileFile))
+   {
+      tileFile = tileFile.setExtension("til");
+      if(!tileHdr.open(tileFile))
+      {
+         return false;
+      }
+   }
+
+   const ossimNitfFileHeader* header = nitfFilePtr->getHeader();
+
+   if(!header)
+   {
+      return false;
+   }
+   
+   ossimQuickbirdTileInfo info;
+   
+   if(!tileHdr.getInfo(info, nitfFile.file()))
+   {
+      return false;
+   }
+
+   ossimRefPtr<ossimNitfImageHeader> ih =
+      nitfFilePtr->getNewImageHeader(0);
+   
+   ossimIrect imageRect = ih->getImageRect();
+   ossim_uint32 w = imageRect.width();
+   ossim_uint32 h = imageRect.height();
+   
+   if(w < 1) w = 1;
+   if(h < 1) h = 1;
+   
+   if((info.theUlXOffset != OSSIM_INT_NAN) &&
+      (info.theUlYOffset != OSSIM_INT_NAN) &&
+      (info.theLrXOffset != OSSIM_INT_NAN) &&
+      (info.theLrYOffset != OSSIM_INT_NAN) &&
+      (info.theLlXOffset != OSSIM_INT_NAN) &&
+      (info.theLlYOffset != OSSIM_INT_NAN) &&
+      (info.theUrXOffset != OSSIM_INT_NAN) &&
+      (info.theUrYOffset != OSSIM_INT_NAN))
+   {
+      imageRect = ossimIrect(ossimIpt(info.theUlXOffset,
+                                      info.theUlYOffset),
+                             ossimIpt(info.theUrXOffset,
+                                      info.theUrYOffset),
+                             ossimIpt(info.theLrXOffset,
+                                      info.theLrYOffset),
+                             ossimIpt(info.theLlXOffset,
+                                      info.theLlYOffset));
+   }
+   else if((info.theUlXOffset != OSSIM_INT_NAN)&&
+           (info.theUlYOffset != OSSIM_INT_NAN))
+   {
+      imageRect = ossimIrect(info.theUlXOffset,
+                             info.theUlYOffset,
+                             info.theUlXOffset + (w-1),
+                             info.theUlYOffset + (h-1));
+   }
+
+   char charbuf[128];
+   std::ifstream in(nitfFile.c_str());
+
+   ossimNitfTagInformation tag;
+   if(ih->getTag(tag, PIAIMC_TAG))
+   {
+      in.seekg(tag.getTagDataOffset()+337);
+      
+      in.read(charbuf, 7);
+      charbuf[7] = '\0';
+      theGSD.line = atof(charbuf)/12.0 * MTRS_PER_FT;
+      theGSD.samp = theGSD.line;
+   }
+   else if(ih->getTag(tag, USE26A_TAG))
+   {
+      in.seekg(tag.getTagDataOffset()+4);
+      in.read(charbuf, 5);
+      charbuf[6] = '\0';
+      theGSD.line = atof(charbuf)/12.0 * MTRS_PER_FT;
+      theGSD.samp = theGSD.line;
+   }
+   else if(ih->getTag(tag, USE00A_TAG))
+   {
+      in.seekg(tag.getTagDataOffset()+4);
+      in.read(charbuf, 5);
+      charbuf[6] = '\0';
+      theGSD.line = atof(charbuf)/12.0 * MTRS_PER_FT;
+      theGSD.samp = theGSD.line;
+   }
+   else
+   {
+      theGSD.line = OSSIM_DBL_NAN;
+      theGSD.samp = OSSIM_DBL_NAN;
+   }
+
+   if(useInternalRpcTags)
+   {
+      //***
+      // Search the header for the start of the RPC tag:
+      //***
+      if(ih->getTag(tag, RPC00A_TAG))
+      {
+         thePolyType = A;
+      }
+      else
+      {
+         if(ih->getTag(tag, RPC00B_TAG))
+         {
+            thePolyType = B;
+         }
+         else
+         {
+            ossimNotify(ossimNotifyLevel_FATAL)
+               << "FATAL ossimNitfRpcModel::ossimNitfRpcModel: ERROR"
+               << "\nCould not find neither RPC tags <" << RPC00A_TAG
+               << "> nor <" << RPC00B_TAG
+               << "> in the NITF file at: <"
+               << nitfFile << ">." << " Aborting with error..." << std::endl;
+            theErrorStatus++;
+            return false;
+         }
+      }
+      char* tag_ptr = new char[tag.getTagLength()];
+      in.seekg(tag.getTagDataOffset());
+      in.read(tag_ptr, tag.getTagLength());
+
+      char* tempBufPtr = tag_ptr + 81;
+      for (int i=0; i<20; i++)
+      {
+         sscanf(tempBufPtr, "%12lf", &theLineNumCoef[i]);
+         tempBufPtr += 12;
+      }
+      for (int i=0; i<20; i++)
+      {
+         sscanf(tempBufPtr, "%12lf", &theLineDenCoef[i]);
+         tempBufPtr += 12;
+      }
+      for (int i=0; i<20; i++)
+      {
+         sscanf(tempBufPtr, "%12lf", &theSampNumCoef[i]);
+         tempBufPtr += 12;
+      }
+      for (int i=0; i<20; i++)
+      {
+         sscanf(tempBufPtr, "%12lf", &theSampDenCoef[i]);
+         tempBufPtr += 12;
+      }
+      
+      delete [] tag_ptr;
+   }
+   else
+   {
+      if(hdr.isAPolynomial())
+      {
+         thePolyType = A;
+      }
+      else
+      {
+         thePolyType = B;
+      }
+      
+      std::copy(hdr.theLineNumCoeff.begin(),
+                hdr.theLineNumCoeff.end(),
+                theLineNumCoef);
+      std::copy(hdr.theLineDenCoeff.begin(),
+                hdr.theLineDenCoeff.end(),
+                theLineDenCoef);
+      std::copy(hdr.theSampNumCoeff.begin(),
+                hdr.theSampNumCoeff.end(),
+                theSampNumCoef);
+      std::copy(hdr.theSampDenCoeff.begin(),
+                hdr.theSampDenCoeff.end(),
+                theSampDenCoef);
+   }
+
+   
+   theLineScale = hdr.theLineScale;
+   theSampScale = hdr.theSampScale;
+   theLatScale  = hdr.theLatScale;
+   theLonScale  = hdr.theLonScale;
+   theHgtScale  = hdr.theHeightScale;
+   theLineOffset = hdr.theLineOffset;
+   theSampOffset = hdr.theSampOffset;
+   theLatOffset  = hdr.theLatOffset;
+   theLonOffset  = hdr.theLonOffset;
+   theHgtOffset = hdr.theHeightOffset;
+   theImageSize.line = imageRect.height();
+   theImageSize.samp = imageRect.width();
+   theRefImgPt.line = imageRect.midPoint().y;
+   theRefImgPt.samp = imageRect.midPoint().x;
+   theRefGndPt.lat = theLatOffset;
+   theRefGndPt.lon = theLonOffset;
+   theRefGndPt.hgt = theHgtOffset;
+//    theImageClipRect = ossimIrect(0,
+//                                  0,
+//                                  theImageSize.samp-1,
+//                                  theImageSize.line-1);
+   theImageClipRect = imageRect;
+   theImageID = hdr.theSatId;
+
+   ossimGpt v0, v1, v2, v3;
+   lineSampleHeightToWorld(imageRect.ul(), theHgtOffset, v0);
+   lineSampleHeightToWorld(imageRect.ur(), theHgtOffset, v1);
+   lineSampleHeightToWorld(imageRect.lr(), theHgtOffset, v2);
+   lineSampleHeightToWorld(imageRect.ll(), theHgtOffset, v3);
+   
+   theBoundGndPolygon
+      = ossimPolygon (ossimDpt(v0), ossimDpt(v1), ossimDpt(v2), ossimDpt(v3));
+
+   lineSampleHeightToWorld(theRefImgPt, theHgtOffset, theRefGndPt);
+   ossimGpt rightGpt;
+   ossimGpt topGpt;
+   
+   lineSampleHeightToWorld(theRefImgPt + ossimDpt(1, 0),
+                           theHgtOffset,
+                           rightGpt);
+   lineSampleHeightToWorld(theRefImgPt + ossimDpt(0, -1),
+                           theHgtOffset,
+                           topGpt);
+   
+   if( (theGSD.line == OSSIM_DBL_NAN) || (theGSD.samp == OSSIM_DBL_NAN) )
+   {
+      ossimGpt rightGpt;
+      ossimGpt topGpt;
+      
+      lineSampleHeightToWorld(theRefImgPt + ossimDpt(1, 0),
+                              theHgtOffset,
+                              rightGpt);
+      lineSampleHeightToWorld(theRefImgPt + ossimDpt(0, -1),
+                              theHgtOffset,
+                              topGpt);
+      ossimEcefPoint rightPt = rightGpt;
+      ossimEcefPoint topPt   = topGpt;
+      ossimEcefPoint origin  = theRefGndPt;
+      
+      ossim_float64 gsdx = (rightPt-origin).magnitude();
+      ossim_float64 gsdy = (topPt-origin).magnitude();
+      theGSD.x = (gsdx + gsdy)/2.0;
+      theGSD.y = theGSD.x;
+   }
+   
+   theMeanGSD = (theGSD.x + theGSD.y)/2.0;
+
+   return true;
+}
+
+bool ossimQuickbirdRpcModel::parseTiffFile(const ossimFilename& file)
+{
+   // Make the gsd nan so it gets computed.
+   theGSD.makeNan();
+   
+   ossimFilename tiffFile = file;
+
+   ossimRefPtr<ossimTiffTileSource> tiff = new ossimTiffTileSource();
+
+   if (!tiff->open(file))
+   {
+      return false;
+   }
+
+   ossimIrect imageRect = tiff->getImageRectangle();
+   
+   ossimQuickbirdRpcHeader hdr;
+   ossimQuickbirdTile tileHdr;
+   ossimFilename tileFile = file;
+   ossimFilename rpcFile = file;
+
+   tileFile = tileFile.replaceAllThatMatch("_R[0-9]+C[0-9]+");
+   rpcFile  = rpcFile.replaceAllThatMatch("_R[0-9]+C[0-9]+");
+   
+   if(!hdr.open(rpcFile))
+   {
+      rpcFile = rpcFile.setExtension("RPB");
+      if(!hdr.open(rpcFile))
+      {
+         rpcFile = rpcFile.setExtension("rpb");
+         if(!hdr.open(rpcFile))
+         {
+            return false;
+         }
+      }
+   }
+   
+   tileFile = tileFile.setExtension("TIL");
+   if(!tileHdr.open(tileFile))
+   {
+      tileFile = tileFile.setExtension("til");
+      if(!tileHdr.open(tileFile))
+      {
+         return false;
+      }
+   }
+
+   ossimQuickbirdTileInfo info;
+   
+   if(!tileHdr.getInfo(info, file.file()))
+   {
+      return false;
+   }
+
+   ossim_uint32 w = imageRect.width();
+   ossim_uint32 h = imageRect.height();
+   
+   if(w < 1) w = 1;
+   if(h < 1) h = 1;
+   
+   if((info.theUlXOffset != OSSIM_INT_NAN) &&
+      (info.theUlYOffset != OSSIM_INT_NAN) &&
+      (info.theLrXOffset != OSSIM_INT_NAN) &&
+      (info.theLrYOffset != OSSIM_INT_NAN) &&
+      (info.theLlXOffset != OSSIM_INT_NAN) &&
+      (info.theLlYOffset != OSSIM_INT_NAN) &&
+      (info.theUrXOffset != OSSIM_INT_NAN) &&
+      (info.theUrYOffset != OSSIM_INT_NAN))
+   {
+      imageRect = ossimIrect(ossimIpt(info.theUlXOffset,
+                                      info.theUlYOffset),
+                             ossimIpt(info.theUrXOffset,
+                                      info.theUrYOffset),
+                             ossimIpt(info.theLrXOffset,
+                                      info.theLrYOffset),
+                             ossimIpt(info.theLlXOffset,
+                                      info.theLlYOffset));
+   }
+   else if((info.theUlXOffset != OSSIM_INT_NAN)&&
+           (info.theUlYOffset != OSSIM_INT_NAN))
+   {
+      imageRect = ossimIrect(info.theUlXOffset,
+                             info.theUlYOffset,
+                             info.theUlXOffset + (w-1),
+                             info.theUlYOffset + (h-1));
+   }
+
+   if(hdr.isAPolynomial())
+   {
+      thePolyType = A;
+   }
+   else
+   {
+      thePolyType = B;
+   }
+   
+   std::copy(hdr.theLineNumCoeff.begin(),
+             hdr.theLineNumCoeff.end(),
+             theLineNumCoef);
+   std::copy(hdr.theLineDenCoeff.begin(),
+             hdr.theLineDenCoeff.end(),
+             theLineDenCoef);
+   std::copy(hdr.theSampNumCoeff.begin(),
+             hdr.theSampNumCoeff.end(),
+             theSampNumCoef);
+   std::copy(hdr.theSampDenCoeff.begin(),
+             hdr.theSampDenCoeff.end(),
+             theSampDenCoef);
+
+   
+   theLineScale = hdr.theLineScale;
+   theSampScale = hdr.theSampScale;
+   theLatScale  = hdr.theLatScale;
+   theLonScale  = hdr.theLonScale;
+   theHgtScale  = hdr.theHeightScale;
+   theLineOffset = hdr.theLineOffset;
+   theSampOffset = hdr.theSampOffset;
+   theLatOffset  = hdr.theLatOffset;
+   theLonOffset  = hdr.theLonOffset;
+   theHgtOffset = hdr.theHeightOffset;
+   theImageSize.line = imageRect.height();
+   theImageSize.samp = imageRect.width();
+   theRefImgPt.line = imageRect.midPoint().y;
+   theRefImgPt.samp = imageRect.midPoint().x;
+   theRefGndPt.lat = theLatOffset;
+   theRefGndPt.lon = theLonOffset;
+   theRefGndPt.hgt = theHgtOffset;
+   theImageClipRect = imageRect;
+   theImageID = hdr.theSatId;
+
+   ossimGpt v0, v1, v2, v3;
+   lineSampleHeightToWorld(imageRect.ul(), theHgtOffset, v0);
+   lineSampleHeightToWorld(imageRect.ur(), theHgtOffset, v1);
+   lineSampleHeightToWorld(imageRect.lr(), theHgtOffset, v2);
+   lineSampleHeightToWorld(imageRect.ll(), theHgtOffset, v3);
+   
+   theBoundGndPolygon
+      = ossimPolygon (ossimDpt(v0), ossimDpt(v1), ossimDpt(v2), ossimDpt(v3));
+
+   lineSampleHeightToWorld(theRefImgPt, theHgtOffset, theRefGndPt);
+   ossimGpt rightGpt;
+   ossimGpt topGpt;
+   
+   lineSampleHeightToWorld(theRefImgPt + ossimDpt(1, 0),
+                           theHgtOffset,
+                           rightGpt);
+   lineSampleHeightToWorld(theRefImgPt + ossimDpt(0, -1),
+                           theHgtOffset,
+                           topGpt);
+   
+   if( (theGSD.line == OSSIM_DBL_NAN) || (theGSD.samp == OSSIM_DBL_NAN) )
+   {
+      ossimGpt rightGpt;
+      ossimGpt topGpt;
+      
+      lineSampleHeightToWorld(theRefImgPt + ossimDpt(1, 0),
+                              theHgtOffset,
+                              rightGpt);
+      lineSampleHeightToWorld(theRefImgPt + ossimDpt(0, -1),
+                              theHgtOffset,
+                              topGpt);
+      ossimEcefPoint rightPt = rightGpt;
+      ossimEcefPoint topPt   = topGpt;
+      ossimEcefPoint origin  = theRefGndPt;
+      
+      ossim_float64 gsdx = (rightPt-origin).magnitude();
+      ossim_float64 gsdy = (topPt-origin).magnitude();
+      theGSD.x = (gsdx + gsdy)/2.0;
+      theGSD.y = theGSD.x;
+   }
+   
+   theMeanGSD = (theGSD.x + theGSD.y)/2.0;
+   
+   return true;
+}
+
+bool ossimQuickbirdRpcModel::saveState(ossimKeywordlist& kwl,
+                                       const char* prefix) const
+{
+   return ossimRpcModel::saveState(kwl, prefix);
+}
+
+bool ossimQuickbirdRpcModel::loadState(const ossimKeywordlist& kwl,
+                                       const char* prefix)
+{
+   return ossimRpcModel::loadState(kwl, prefix);
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.h
new file mode 100644
index 0000000000..0e378a7b77
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimQuickbirdRpcModel.h
@@ -0,0 +1,55 @@
+//*****************************************************************************
+// FILE: ossimQuickbirdRpcModel.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// DESCRIPTION: Contains declaration of class ossimQuickbirdRpcModel. This 
+//    derived class implements the capability of reading Quickbird RPC support
+//    data.
+//
+// LIMITATIONS: None.
+//
+//*****************************************************************************
+//  $Id: ossimQuickbirdRpcModel.h,v 1.3 2005/11/08 18:12:17 dburken Exp $
+#ifndef ossimQuickbirdRpcModel_HEADER
+#define ossimQuickbirdRpcModel_HEADER
+
+#include <projections/sensor_modeling/rpc/ossimRpcModel.h>
+
+class ossimFilename;
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimQuickbirdRpcModel
+ *
+ *****************************************************************************/
+class ossimQuickbirdRpcModel : public ossimRpcModel
+{
+public:
+   ossimQuickbirdRpcModel();
+   ossimQuickbirdRpcModel(const ossimQuickbirdRpcModel& rhs);
+   
+   virtual ossimObject* dup() const;
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   bool parseFile(const ossimFilename& file);
+   
+   
+protected:
+
+   bool parseNitfFile(const ossimFilename& file);
+   bool parseTiffFile(const ossimFilename& file);
+   
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimRpcModel.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimRpcModel.cpp
new file mode 100644
index 0000000000..e913df483b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimRpcModel.cpp
@@ -0,0 +1,1040 @@
+//*****************************************************************************
+// FILE: ossimRpcModel.cc
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains implementation of class ossimRpcModel.
+//   This is a replacement model utilizing the Rational Polynomial Coefficients
+//   (RPC), a.k.a. Rapid Positioning Capability, and Universal Sensor Model
+//   (USM).
+//
+// LIMITATIONS: Does not support parameter adjustment (YET)
+//
+//*****************************************************************************
+//  $Id: ossimRpcModel.cpp,v 1.31 2005/05/06 17:30:15 gpotts Exp $
+
+#include <projections/sensor_modeling/rpc/ossimRpcModel.h>
+
+RTTI_DEF1(ossimRpcModel, "ossimRpcModel", ossimSensorModel);
+
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimKeywordNames.h>
+#include <cstdio>
+#include <fstream>
+#include <iostream>
+#include <algorithm>
+
+//***
+// Define Trace flags for use within this file:
+//***
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimRpcModel:exec");
+static ossimTrace traceDebug ("ossimRpcModel:debug");
+
+const ossimFilename ossimRpcModel::INIT_RPC_GEOM_FILENAME ("rpc_init.geom");
+static const int    MODEL_VERSION_NUMBER  = 1;
+static const int    NUM_COEFFS        = 20;
+static const char*  MODEL_TYPE        = "ossimRpcModel";
+static const char*  POLY_TYPE_KW      = "polynomial_format";
+static const char*  LINE_SCALE_KW     = "line_scale";
+static const char*  SAMP_SCALE_KW     = "samp_scale";
+static const char*  LAT_SCALE_KW      = "lat_scale";
+static const char*  LON_SCALE_KW      = "long_scale";
+static const char*  HGT_SCALE_KW      = "height_scale";
+static const char*  LINE_OFFSET_KW    = "line_off";
+static const char*  SAMP_OFFSET_KW    = "samp_off";
+static const char*  LAT_OFFSET_KW     = "lat_off";
+static const char*  LON_OFFSET_KW     = "long_off";
+static const char*  HGT_OFFSET_KW     = "height_off";
+static const char*  LINE_NUM_COEF_KW  = "line_num_coeff_";
+static const char*  LINE_DEN_COEF_KW  = "line_den_coeff_";
+static const char*  SAMP_NUM_COEF_KW  = "samp_num_coeff_";
+static const char*  SAMP_DEN_COEF_KW  = "samp_den_coeff_";
+
+static const ossimString PARAM_NAMES[] ={"intrack_offset",
+                                        "crtrack_offset",
+                                        "intrack_scale",
+                                        "crtrack_scale",
+                                        "map_rotation",
+                                        "yaw_offset"};
+static const ossimString PARAM_UNITS[] ={"pixel",
+                                        "pixel",
+                                        "scale",
+                                        "scale",
+                                        "degrees",
+                                        "degrees"};
+      
+//*****************************************************************************
+//  DEFAULT CONSTRUCTOR: ossimRpcModel()
+//  
+//*****************************************************************************
+ossimRpcModel::ossimRpcModel()
+   : ossimSensorModel(),
+     theIntrackOffset(0),
+     theCrtrackOffset(0),
+     theIntrackScale(0.0),
+     theCrtrackScale(0.0),
+     theYawSkew   (0.0),
+     theCosMapRot (1.0),
+     theSinMapRot (0.0)
+   
+ {
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel Default Constructor: entering..." << std::endl;
+
+   initAdjustableParameters();
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel Default Constructor: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  COPY CONSTRUCTOR: ossimRpcModel(ossimRpcModel)
+//  
+//*****************************************************************************
+ossimRpcModel::ossimRpcModel(const ossimRpcModel& model)
+   :
+      ossimSensorModel(model),
+      thePolyType     (model.thePolyType),
+      theLineScale    (model.theLineScale),
+      theSampScale    (model.theSampScale),
+      theLatScale     (model.theLatScale),
+      theLonScale     (model.theLonScale),
+      theHgtScale     (model.theHgtScale),
+      theLineOffset   (model.theLineOffset),
+      theSampOffset   (model.theSampOffset),
+      theLatOffset    (model.theLatOffset),
+      theLonOffset    (model.theLonOffset),
+      theHgtOffset    (model.theHgtOffset),
+      theIntrackOffset(model.theIntrackOffset),
+      theCrtrackOffset(model.theCrtrackOffset),
+      theIntrackScale(model.theIntrackScale),
+      theCrtrackScale(model.theCrtrackScale),
+      theYawSkew      (model.theYawSkew),
+      theCosMapRot    (model.theCosMapRot),
+      theSinMapRot    (model.theSinMapRot)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel Copy Constructor: entering..." << std::endl;
+
+   for (int i=0; i<20; i++)
+   {
+      theLineNumCoef[i] = model.theLineNumCoef[i];
+      theLineDenCoef[i] = model.theLineDenCoef[i];
+      theSampNumCoef[i] = model.theSampNumCoef[i];
+      theSampDenCoef[i] = model.theSampDenCoef[i];
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel Copy Constructor: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  CONSTRUCTOR: ossimRpcModel(kwl)
+//  
+//  Constructs model from keywordlist geometry file
+//  
+//*****************************************************************************
+ossimRpcModel::ossimRpcModel(const ossimKeywordlist& geom_kwl)
+   : ossimSensorModel(),
+     theIntrackOffset(0),
+     theCrtrackOffset(0),
+     theIntrackScale(0.0),
+     theCrtrackScale(0.0),
+     theYawSkew   (0.0),
+     theCosMapRot (1.0),
+     theSinMapRot (0.0)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel(kwl) Constructor: entering..." << std::endl;
+
+   if(geom_kwl.getErrorStatus() == ossimErrorCodes::OSSIM_OK)
+   {
+      //***
+      // Parse keywordlist for geometry:
+      //***
+      loadState(geom_kwl);
+   }
+   else
+   {
+      theErrorStatus++;
+   }
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimRpcModel()
+//  
+//*****************************************************************************
+ossimRpcModel::~ossimRpcModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ~ossimRpcModel() Destructor: entering..." << std::endl;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNotify(ossimNotifyLevel_DEBUG): returning..." << std::endl;
+}
+
+void ossimRpcModel::setAttributes(ossim_float64 sampleOffset,
+                                  ossim_float64 lineOffset,
+                                  ossim_float64 sampleScale,
+                                  ossim_float64 lineScale,
+                                  ossim_float64 latOffset,
+                                  ossim_float64 lonOffset,
+                                  ossim_float64 heightOffset,
+                                  ossim_float64 latScale,
+                                  ossim_float64 lonScale,
+                                  ossim_float64 heightScale,
+                                  const std::vector<double>& xNumeratorCoeffs,
+                                  const std::vector<double>& xDenominatorCoeffs,
+                                  const std::vector<double>& yNumeratorCoeffs,
+                                  const std::vector<double>& yDenominatorCoeffs,
+                                  PolynomialType polyType,
+                                  bool computeGsd)
+{
+   thePolyType = polyType;
+   
+   theLineScale  = lineScale;
+   theSampScale  = sampleScale;
+   theLatScale   = latScale;
+   theLonScale   = lonScale;
+   theHgtScale   = heightScale;
+   theLineOffset = lineOffset;
+   theSampOffset = sampleOffset;
+   theLatOffset  = latOffset;
+   theLonOffset  = lonOffset;
+   theHgtOffset  = heightOffset;
+
+   if(xNumeratorCoeffs.size() == 20)
+   {
+      std::copy(xNumeratorCoeffs.begin(),
+                xNumeratorCoeffs.end(),
+                theSampNumCoef);
+   }
+   if(xDenominatorCoeffs.size() == 20)
+   {
+      std::copy(xDenominatorCoeffs.begin(),
+                xDenominatorCoeffs.end(),
+                theSampDenCoef);
+   }
+   if(yNumeratorCoeffs.size() == 20)
+   {
+      std::copy(yNumeratorCoeffs.begin(),
+                yNumeratorCoeffs.end(),
+                theLineNumCoef);
+   }
+   if(yDenominatorCoeffs.size() == 20)
+   {
+      std::copy(yDenominatorCoeffs.begin(),
+                yDenominatorCoeffs.end(),
+                theLineDenCoef);
+   }
+
+   if(computeGsd)
+   {
+      ossimGpt centerGround;
+      ossimGpt rightGround;
+      ossimGpt topGround;
+      lineSampleToWorld(ossimDpt(sampleOffset,
+                                 lineOffset),
+                        centerGround);
+      lineSampleToWorld(ossimDpt(sampleOffset+1,
+                                 lineOffset),
+                        rightGround);
+      lineSampleToWorld(ossimDpt(sampleOffset,
+                                 lineOffset+1),
+                        topGround);
+      
+      ossimEcefPoint p1 = centerGround;
+      ossimEcefPoint p2 = rightGround;
+      ossimEcefPoint p3 = topGround;
+      
+      theGSD.x = (p2-p1).magnitude();
+      theGSD.y = (p3-p1).magnitude();
+      theMeanGSD = (theGSD.x+theGSD.y)*.5;
+   }
+}
+
+void ossimRpcModel::setMetersPerPixel(const ossimDpt& metersPerPixel)
+{
+   theGSD = metersPerPixel;
+   theMeanGSD = (theGSD.x+theGSD.y)*.5;
+}
+
+//*****************************************************************************
+//  METHOD: ossimRpcModel::worldToLineSample()
+//  
+//  Overrides base class implementation. Directly computes line-sample from
+//  the polynomials.
+//*****************************************************************************
+void ossimRpcModel::worldToLineSample(const ossimGpt& ground_point,
+                                      ossimDpt&       img_pt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::worldToLineSample(): entering..." << std::endl;
+
+   if(ground_point.isLatNan() ||
+      ground_point.isLonNan() )
+     {
+       img_pt.makeNan();
+       return;
+     }
+   //***
+   // First check if the world point is inside bounding rectangle:
+   //***
+//   ossimDpt wdp (ground_point);
+//    if (!(theBoundGndPolygon.pointWithin(wdp)))
+//    {
+//      img_pt = extrapolate(ground_point);
+//       if (traceExec())  CLOG << "returning..." << endl;
+//       return;
+//    }
+         
+   //***
+   // Normalize the lat, lon, hgt:
+   //***
+   double nlat = (ground_point.lat - theLatOffset) / theLatScale;
+   double nlon = (ground_point.lon - theLonOffset) / theLonScale;
+   double nhgt;
+
+   if(ground_point.hgt == OSSIM_DBL_NAN)
+   {
+      nhgt = (theHgtScale - theHgtOffset) / theHgtScale;
+   }
+   else
+   {
+      nhgt = (ground_point.hgt - theHgtOffset) / theHgtScale;
+   }
+   //***
+   // Compute the adjusted, normalized line (U) and sample (V):
+   //***
+   double Pu = polynomial(nlat, nlon, nhgt, theLineNumCoef);
+   double Qu = polynomial(nlat, nlon, nhgt, theLineDenCoef);
+   double Pv = polynomial(nlat, nlon, nhgt, theSampNumCoef);
+   double Qv = polynomial(nlat, nlon, nhgt, theSampDenCoef);
+   double U_rot  = Pu / Qu;
+   double V_rot  = Pv / Qv;
+
+   //***
+   // U, V are normalized quantities. Need now to establish the image file
+   // line and sample. First, back out the adjustable parameter effects
+   // starting with rotation:
+   //***
+   double U = U_rot*theCosMapRot + V_rot*theSinMapRot;
+   double V = V_rot*theCosMapRot - U_rot*theSinMapRot;
+
+   //***
+   // Now back out skew, scale, and offset adjustments:
+   //***
+   img_pt.line = U*(theLineScale+theIntrackScale) + theLineOffset + theIntrackOffset;
+//   img_pt.samp = V*(theSampScale+theCrtrackScale) + theSampOffset + theIntrackOffset - theYawSkew*img_pt.u;
+   img_pt.samp = V*(theSampScale+theCrtrackScale) + theSampOffset + theCrtrackOffset - theYawSkew*img_pt.u;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::worldToLineSample(): returning..." << std::endl;
+   return;
+}
+
+void  ossimRpcModel::lineSampleToWorld(const ossimDpt& imagePoint,
+                                       ossimGpt&       worldPoint) const
+{
+   if(!imagePoint.hasNans())
+   {
+      lineSampleHeightToWorld(imagePoint,
+                              worldPoint.height(),
+                              worldPoint);
+   }
+   else
+   {
+      worldPoint.makeNan();
+   }
+}
+
+//*****************************************************************************
+//  METHOD: ossimRpcModel::lineSampleHeightToWorld()
+//  
+//  Performs reverse projection of image line/sample to ground point.
+//  The imaging ray is intersected with a level plane at height = elev.
+//
+//  NOTE: U = line, V = sample -- this differs from the convention.
+//
+//*****************************************************************************
+void ossimRpcModel::lineSampleHeightToWorld(const ossimDpt& image_point,
+                                            const double&   ellHeight,
+                                            ossimGpt&       gpt) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::lineSampleHeightToWorld: entering..." << std::endl;
+
+   //***
+   // Extrapolate if point is outside image:
+   //***
+//    if (!insideImage(image_point))
+//    {
+//       gpt = extrapolate(image_point, ellHeight);
+//       if (traceExec())  CLOG << "returning..." << endl;
+//       return;
+//    }
+
+   //***
+   // Constants for convergence tests:
+   //***
+   static const int    MAX_NUM_ITERATIONS  = 10;
+   static const double CONVERGENCE_EPSILON = 0.1;  // pixels
+   
+   //***
+   // The image point must be adjusted by the adjustable parameters as well
+   // as the scale and offsets given as part of the RPC param normalization.
+   //
+   //      NOTE: U = line, V = sample
+   //***
+   double skew = (image_point.x-theSampOffset - theCrtrackOffset)*theYawSkew;
+   double U    = (image_point.y-theLineOffset - theIntrackOffset+skew) / (theLineScale+theIntrackScale);
+   double V    = (image_point.x-theSampOffset - theCrtrackOffset) / (theSampScale+theCrtrackScale);
+
+   //***
+   // Rotate the normalized U, V by the map rotation error (adjustable param):
+   //***
+   double U_rot = theCosMapRot*U - theSinMapRot*V;
+   double V_rot = theSinMapRot*U + theCosMapRot*V;
+   U = U_rot; V = V_rot;
+
+
+   // now apply adjust intrack and cross track
+   //***
+   // Initialize quantities to be used in the iteration for ground point:
+   //***
+   double nlat      = 0.0;  // normalized latitude
+   double nlon      = 0.0;  // normalized longitude
+   
+   double nhgt;
+
+   if(ellHeight == OSSIM_DBL_NAN)
+   {
+     nhgt = (theHgtScale - theHgtOffset) / theHgtScale;  // norm height
+   }
+   else
+   {
+      nhgt = (ellHeight - theHgtOffset) / theHgtScale;  // norm height
+   }
+   
+   double epsilonU = CONVERGENCE_EPSILON/(theLineScale+theIntrackScale);
+   double epsilonV = CONVERGENCE_EPSILON/(theSampScale+theCrtrackScale);
+   int    iteration = 0;
+
+   //***
+   // Declare variables only once outside the loop. These include:
+   // * polynomials (numerators Pu, Pv, and denominators Qu, Qv),
+   // * partial derivatives of polynomials wrt X, Y,
+   // * computed normalized image point: Uc, Vc,
+   // * residuals of normalized image point: deltaU, deltaV,
+   // * partial derivatives of Uc and Vc wrt X, Y,
+   // * corrections to normalized lat, lon: deltaLat, deltaLon.
+   //***
+   double Pu, Qu, Pv, Qv;
+   double dPu_dLat, dQu_dLat, dPv_dLat, dQv_dLat;
+   double dPu_dLon, dQu_dLon, dPv_dLon, dQv_dLon;
+   double Uc, Vc;
+   double deltaU, deltaV;
+   double dU_dLat, dU_dLon, dV_dLat, dV_dLon, W;
+   double deltaLat, deltaLon;
+   
+   //***
+   // Now iterate until the computed Uc, Vc is within epsilon of the desired
+   // image point U, V:
+   //***
+   do
+   {
+      //***
+      // Calculate the normalized line and sample Uc, Vc as ratio of
+      // polynomials Pu, Qu and Pv, Qv:
+      //***
+      Pu = polynomial(nlat, nlon, nhgt, theLineNumCoef);
+      Qu = polynomial(nlat, nlon, nhgt, theLineDenCoef);
+      Pv = polynomial(nlat, nlon, nhgt, theSampNumCoef);
+      Qv = polynomial(nlat, nlon, nhgt, theSampDenCoef);
+      Uc = Pu/Qu;
+      Vc = Pv/Qv;
+      
+      //***
+      // Compute residuals between desired and computed line, sample:
+      //***
+      deltaU = U - Uc;
+      deltaV = V - Vc;
+      
+      //***
+      // Check for convergence and skip re-linearization if converged:
+      //***
+      if ((fabs(deltaU) > epsilonU) || (fabs(deltaV) > epsilonV))
+      {
+         //***
+         // Analytically compute the partials of each polynomial wrt lat, lon:
+         //***
+         dPu_dLat = dPoly_dLat(nlat, nlon, nhgt, theLineNumCoef);
+         dQu_dLat = dPoly_dLat(nlat, nlon, nhgt, theLineDenCoef);
+         dPv_dLat = dPoly_dLat(nlat, nlon, nhgt, theSampNumCoef);
+         dQv_dLat = dPoly_dLat(nlat, nlon, nhgt, theSampDenCoef);
+         dPu_dLon = dPoly_dLon(nlat, nlon, nhgt, theLineNumCoef);
+         dQu_dLon = dPoly_dLon(nlat, nlon, nhgt, theLineDenCoef);
+         dPv_dLon = dPoly_dLon(nlat, nlon, nhgt, theSampNumCoef);
+         dQv_dLon = dPoly_dLon(nlat, nlon, nhgt, theSampDenCoef);
+         
+         //***
+         // Analytically compute partials of quotients U and V wrt lat, lon: 
+         //***
+         dU_dLat = (Qu*dPu_dLat - Pu*dQu_dLat)/(Qu*Qu);
+         dU_dLon = (Qu*dPu_dLon - Pu*dQu_dLon)/(Qu*Qu);
+         dV_dLat = (Qv*dPv_dLat - Pv*dQv_dLat)/(Qv*Qv);
+         dV_dLon = (Qv*dPv_dLon - Pv*dQv_dLon)/(Qv*Qv);
+         
+         W = dU_dLon*dV_dLat - dU_dLat*dV_dLon;
+         
+         //***
+         // Now compute the corrections to normalized lat, lon:
+         //***
+         deltaLat = (dU_dLon*deltaV - dV_dLon*deltaU) / W;
+         deltaLon = (dV_dLat*deltaU - dU_dLat*deltaV) / W;
+         nlat += deltaLat;
+         nlon += deltaLon;
+      }
+      
+      iteration++;
+      
+   } while (((fabs(deltaU)>epsilonU) || (fabs(deltaV)>epsilonV))
+            && (iteration < MAX_NUM_ITERATIONS));
+      
+   //***
+   // Test for exceeding allowed number of iterations. Flag error if so:
+   //***
+   if (iteration == MAX_NUM_ITERATIONS)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimRpcModel::lineSampleHeightToWorld: \nMax number of iterations reached in ground point "
+                                         << "solution. Results are inaccurate." << endl;
+   }
+
+   //***
+   // Now un-normalize the ground point lat, lon and establish return quantity:
+   //***
+   gpt.lat = nlat*theLatScale + theLatOffset;
+   gpt.lon = nlon*theLonScale + theLonOffset;
+   gpt.hgt = ellHeight;
+   
+}
+
+//*****************************************************************************
+// PRIVATE METHOD: ossimRpcModel::polynomial
+//  
+//  Computes polynomial.
+//  
+//*****************************************************************************
+double ossimRpcModel::polynomial(const double& P, const double& L,
+                                 const double& H, const double* c) const
+{
+   double r;
+
+   if (thePolyType == A)
+   {
+      r = c[ 0]       + c[ 1]*L     + c[ 2]*P     + c[ 3]*H     +
+          c[ 4]*L*P   + c[ 5]*L*H   + c[ 6]*P*H   + c[ 7]*L*P*H +
+          c[ 8]*L*L   + c[ 9]*P*P   + c[10]*H*H   + c[11]*L*L*L +
+          c[12]*L*L*P + c[13]*L*L*H + c[14]*L*P*P + c[15]*P*P*P +
+          c[16]*P*P*H + c[17]*L*H*H + c[18]*P*H*H + c[19]*H*H*H;
+   }
+   else
+   {
+      r = c[ 0]       + c[ 1]*L     + c[ 2]*P     + c[ 3]*H     +
+          c[ 4]*L*P   + c[ 5]*L*H   + c[ 6]*P*H   + c[ 7]*L*L   +
+          c[ 8]*P*P   + c[ 9]*H*H   + c[10]*L*P*H + c[11]*L*L*L +
+          c[12]*L*P*P + c[13]*L*H*H + c[14]*L*L*P + c[15]*P*P*P +
+          c[16]*P*H*H + c[17]*L*L*H + c[18]*P*P*H + c[19]*H*H*H;
+   }
+   
+   return r;
+}
+
+//*****************************************************************************
+// PRIVATE METHOD: ossimRpcModel::dPoly_dLat
+//  
+//  Computes derivative of polynomial wrt normalized Latitude P.
+//  
+//*****************************************************************************
+double ossimRpcModel::dPoly_dLat(const double& P, const double& L,
+                                 const double& H, const double* c) const
+{
+   double dr;
+
+   if (thePolyType == A)
+   {
+      dr = c[2] + c[4]*L + c[6]*H + c[7]*L*H + 2*c[9]*P + c[12]*L*L +
+           2*c[14]*L*P + 3*c[15]*P*P +2*c[16]*P*H + c[18]*H*H;
+   }
+   else
+   {
+      dr = c[2] + c[4]*L + c[6]*H + 2*c[8]*P + c[10]*L*H + 2*c[12]*L*P +
+           c[14]*L*L + 3*c[15]*P*P + c[16]*H*H + 2*c[18]*P*H;
+   }
+   
+   return dr;
+}
+
+//*****************************************************************************
+// PRIVATE METHOD: ossimRpcModel::dPoly_dLon
+//  
+//  Computes derivative of polynomial wrt normalized Longitude L.
+//  
+//*****************************************************************************
+double ossimRpcModel::dPoly_dLon(const double& P, const double& L,
+                                 const double& H, const double* c) const
+{
+   double dr;
+
+   if (thePolyType == A)
+   {
+      dr = c[1] + c[4]*P + c[5]*H + c[7]*P*H + 2*c[8]*L + 3*c[11]*L*L +
+           2*c[12]*L*P + 2*c[13]*L*H + c[14]*P*P + c[17]*H*H;
+   }
+   else
+   {
+      dr = c[1] + c[4]*P + c[5]*H + 2*c[7]*L + c[10]*P*H + 3*c[11]*L*L +
+           c[12]*P*P + c[13]*H*H + 2*c[14]*P*L + 2*c[17]*L*H;
+   }
+   return dr;
+}
+
+
+void ossimRpcModel::updateModel()
+{
+   theIntrackOffset    = computeParameterOffset(INTRACK_OFFSET);
+   theCrtrackOffset    = computeParameterOffset(CRTRACK_OFFSET);
+   theIntrackScale     = computeParameterOffset(INTRACK_SCALE);
+   theCrtrackScale     = computeParameterOffset(CRTRACK_SCALE);
+//   theYawSkew          = sind(computeParameterOffset(YAW_OFFSET));
+   double mapRotation  = computeParameterOffset(MAP_ROTATION);
+   theCosMapRot        = cosd(mapRotation);
+   theSinMapRot        = sind(mapRotation);
+}
+
+void ossimRpcModel::initAdjustableParameters()
+{
+   resizeAdjustableParameterArray(NUM_ADJUSTABLE_PARAMS);
+   int numParams = getNumberOfAdjustableParameters();
+   for (int i=0; i<numParams; i++)
+   {
+      setAdjustableParameter(i, 0.0);
+      setParameterDescription(i, PARAM_NAMES[i]);
+      setParameterUnit(i,PARAM_UNITS[i]);
+   }
+   setParameterSigma(INTRACK_OFFSET, 50.0);
+   setParameterSigma(CRTRACK_OFFSET, 50.0);
+   setParameterSigma(INTRACK_SCALE, 50.0);  
+   setParameterSigma(CRTRACK_SCALE, 50.0);  
+   setParameterSigma(MAP_ROTATION, 0.1);
+//   setParameterSigma(YAW_OFFSET, 0.001);
+}
+
+
+ossimDpt ossimRpcModel::extrapolate (const ossimGpt& gp) const
+{
+  return ossimSensorModel::extrapolate(gp);
+//   ossimDpt temp;
+  
+//   temp.makeNan();
+  
+//   return temp;
+  
+}
+
+ossimGpt ossimRpcModel::extrapolate (const ossimDpt& ip,
+				       const double& height) const
+{
+  return ossimSensorModel::extrapolate(ip, height);
+//  return ossimGpt(OSSIM_DBL_NAN, OSSIM_DBL_NAN, OSSIM_DBL_NAN, 0);
+}
+
+//*****************************************************************************
+//  METHOD: ossimRpcModel::print()
+//  
+//  Formatted dump of data members.
+//  
+//*****************************************************************************
+std::ostream& ossimRpcModel::print(std::ostream& out) const
+{
+   out << "\nDump of ossimRpcModel object at " << hex << this << ":\n"
+       << POLY_TYPE_KW   << ": " << thePolyType   << "\n"
+       << LINE_SCALE_KW  << ": " << theLineScale  << "\n"
+       << SAMP_SCALE_KW  << ": " << theSampScale  << "\n"
+       << LAT_SCALE_KW   << ": " << theLatScale   << "\n"
+       << LON_SCALE_KW   << ": " << theLonScale   << "\n"
+       << HGT_SCALE_KW   << ": " << theHgtScale   << "\n"
+       << LINE_OFFSET_KW << ": " << theLineOffset << "\n"
+       << SAMP_OFFSET_KW << ": " << theSampOffset << "\n"
+       << LAT_OFFSET_KW  << ": " << theLatOffset  << "\n"
+       << LON_OFFSET_KW  << ": " << theLonOffset  << "\n"
+       << HGT_OFFSET_KW  << ": " << theHgtOffset  << endl;
+
+   for (int i=0; i<NUM_COEFFS; i++)
+      out<<"  "<<LINE_NUM_COEF_KW<<"["<<i<<"]: "<<theLineNumCoef[i]<<endl;
+
+   out << endl;
+   for (int i=0; i<NUM_COEFFS; i++)
+      out<<"  "<<LINE_DEN_COEF_KW<<"["<<i<<"]: "<<theLineDenCoef[i]<<endl;
+
+   out << endl;
+   for (int i=0; i<NUM_COEFFS; i++)
+      out<<"  "<<SAMP_NUM_COEF_KW<<"["<<i<<"]: "<<theSampNumCoef[i]<<endl;
+
+   out << endl;
+   for (int i=0; i<NUM_COEFFS; i++)
+      out<<"  "<<SAMP_DEN_COEF_KW<<"["<<i<<"]: "<<theSampDenCoef[i]<<endl;
+      
+   out << endl;
+
+   return ossimSensorModel::print(out);
+}
+
+//*****************************************************************************
+//  METHOD: ossimRpcModel::saveState()
+//  
+//  Saves the model state to the KWL. This KWL also serves as a geometry file.
+//  
+//*****************************************************************************
+bool ossimRpcModel::saveState(ossimKeywordlist& kwl,
+                              const char* prefix) const
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::saveState(): entering..." << std::endl;
+
+   char value[128];
+
+   kwl.add(prefix, ossimKeywordNames::TYPE_KW, MODEL_TYPE);
+
+   //***
+   // Hand off to base class for common stuff:
+   //***
+   ossimSensorModel::saveState(kwl, prefix);
+
+   //***
+   // Save off offsets and scales:
+   //***
+   sprintf(value, "%c", (char) thePolyType);
+   kwl.add(prefix, POLY_TYPE_KW, value);
+   
+   sprintf(value, "%22.15e", theLineScale);
+   kwl.add(prefix, LINE_SCALE_KW, value);
+   
+   sprintf(value, "%22.15e", theSampScale);
+   kwl.add(prefix, SAMP_SCALE_KW, value);
+   
+   sprintf(value, "%22.15e", theLatScale);
+   kwl.add(prefix, LAT_SCALE_KW, value);
+   
+   sprintf(value, "%22.15e", theLonScale);
+   kwl.add(prefix, LON_SCALE_KW, value);
+   
+   sprintf(value, "%22.15e", theHgtScale);
+   kwl.add(prefix, HGT_SCALE_KW, value);
+   
+   sprintf(value, "%22.15e", theLineOffset);
+   kwl.add(prefix, LINE_OFFSET_KW, value);
+   
+   sprintf(value, "%22.15e", theSampOffset);
+   kwl.add(prefix, SAMP_OFFSET_KW, value);
+   
+   sprintf(value, "%22.15e", theLatOffset);
+   kwl.add(prefix, LAT_OFFSET_KW, value);
+   
+   sprintf(value, "%22.15e", theLonOffset);
+   kwl.add(prefix, LON_OFFSET_KW, value);
+   
+   sprintf(value, "%22.15e", theHgtOffset);
+   kwl.add(prefix, HGT_OFFSET_KW, value);
+
+   char key[128];
+   for (int i=0; i<NUM_COEFFS; i++)
+   {
+      sprintf(key,   "%s%02d", LINE_NUM_COEF_KW, i);
+      sprintf(value, "%22.15e",    theLineNumCoef[i]);
+      kwl.add(prefix, key, value);
+      
+      sprintf(key,   "%s%02d", LINE_DEN_COEF_KW, i);
+      sprintf(value, "%22.15e",    theLineDenCoef[i]);
+      kwl.add(prefix, key, value);
+      
+      sprintf(key,   "%s%02d", SAMP_NUM_COEF_KW, i);
+      sprintf(value, "%22.15e",    theSampNumCoef[i]);
+      kwl.add(prefix, key, value);
+      
+      sprintf(key,   "%s%02d", SAMP_DEN_COEF_KW, i);
+      sprintf(value, "%22.15e",    theSampDenCoef[i]);
+      kwl.add(prefix, key, value);
+   }
+      
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::saveState(): returning..." << std::endl;
+   return true;
+}
+
+//*****************************************************************************
+//  METHOD: ossimRpcModel::loadState()
+//  
+//  Restores the model's state from the KWL. This KWL also serves as a
+//  geometry file.
+//  
+//*****************************************************************************
+bool ossimRpcModel::loadState(const ossimKeywordlist& kwl,
+                              const char* prefix) 
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::loadState(): entering..." << std::endl;
+
+   const char* value;
+   const char* keyword;
+
+   //***
+   // Pass on to the base-class for parsing first:
+   //***
+   bool success = ossimSensorModel::loadState(kwl, prefix);
+   if (!success)
+   {
+      theErrorStatus++;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::loadState(): returning with error..." << std::endl;
+      return false;
+   }
+      
+   //***
+   // Continue parsing for local members:
+   //***
+   keyword = POLY_TYPE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   thePolyType = (PolynomialType) value[0];
+      
+   keyword = LINE_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLineScale = atof(value);
+   
+   keyword = SAMP_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theSampScale = atof(value);
+   
+   keyword = LAT_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLatScale = atof(value);
+   
+   keyword = LON_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLonScale = atof(value);
+   
+   keyword = HGT_SCALE_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theHgtScale = atof(value);
+   
+   keyword = LINE_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLineOffset = atof(value);
+   
+   keyword = SAMP_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theSampOffset = atof(value);
+   
+   keyword = LAT_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLatOffset = atof(value);
+   
+   keyword = LON_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theLonOffset = atof(value);
+   
+   keyword = HGT_OFFSET_KW;
+   value = kwl.find(prefix, keyword);
+   if (!value)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                          << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                          << std::endl;
+      return false;
+   }
+   theHgtOffset = atof(value);
+
+   char key[128];
+   keyword = key;
+   for (int i=0; i<NUM_COEFFS; i++)
+   {
+      sprintf(key,   "%s%02d", LINE_NUM_COEF_KW, i);
+      value = kwl.find(prefix, keyword);
+      if (!value)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                             << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                             << std::endl;
+         return false;
+      }
+      theLineNumCoef[i] = atof(value);
+   
+      sprintf(key,   "%s%02d", LINE_DEN_COEF_KW, i);
+      value = kwl.find(prefix, keyword);
+      if (!value)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                             << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                             << std::endl;
+         return false;
+      }
+      theLineDenCoef[i] = atof(value);
+   
+      sprintf(key,   "%s%02d", SAMP_NUM_COEF_KW, i);
+      value = kwl.find(prefix, keyword);
+      if (!value)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                             << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                             << std::endl;
+         return false;
+      }
+      theSampNumCoef[i] = atof(value);
+      
+      sprintf(key,   "%s%02d", SAMP_DEN_COEF_KW, i);
+      value = kwl.find(prefix, keyword);
+      if (!value)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcModel::loadState(): Error encountered parsing the following required keyword: "
+                                             << "<" << keyword << ">. Check the keywordlist for proper syntax."
+                                             << std::endl;
+         return false;
+      }
+      theSampDenCoef[i] = atof(value);
+   }
+      
+   //***
+   // Initialize other data members given quantities read in KWL:
+   //***
+   theYawSkew   = 0.0;
+   theCosMapRot = 1.0;
+   theSinMapRot = 0.0;
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::loadState(): returning..." << std::endl;
+   return true;
+}
+
+//*****************************************************************************
+// STATIC METHOD: ossimRpcModel::writeGeomTemplate
+//  
+//  Writes a sample kwl to output stream.
+//  
+//*****************************************************************************
+void ossimRpcModel::writeGeomTemplate(ostream& os)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::writeGeomTemplate(): entering..." << std::endl;
+
+   os <<
+      "//**************************************************************\n"
+      "// Template for RPC model keywordlist\n"
+      "//**************************************************************\n"
+      << ossimKeywordNames::TYPE_KW << ": " << MODEL_TYPE << endl;
+
+   ossimSensorModel::writeGeomTemplate(os);
+   
+   os << "//\n"
+      << "// Derived-class ossimRpcModel Keywords:\n"
+      << "//\n"
+      << POLY_TYPE_KW << ": A|B\n"
+      << "\n"
+      << "// RPC data consists of coefficients and normalization \n"
+      << "// parameters. The RPC keywords used here are compatible with \n"
+      << "// keywords found in Ikonos \"rpc.txt\" files.\n"
+      << "// First are the normalization parameters:\n"
+      << LINE_OFFSET_KW << ": <float>\n"
+      << SAMP_OFFSET_KW << ": <float>\n"
+      << LAT_OFFSET_KW << ": <float>\n"
+      << LON_OFFSET_KW << ": <float>\n"
+      << HGT_OFFSET_KW << ": <float>\n"
+      << LINE_SCALE_KW << ": <float>\n"
+      << SAMP_SCALE_KW << ": <float>\n"
+      << LAT_SCALE_KW << ": <float>\n"
+      << LON_SCALE_KW << ": <float>\n"
+      << HGT_SCALE_KW << ": <float>\n"
+      << "\n"
+      << "// RPC Coefficients are specified with indexes. Coefficients \n "
+      << "// are specified for the four polynomials: line numerator, line \n"
+      << "// denominator, sample numerator, and sample denominator:" << endl;
+
+   for (int i=1; i<=20; i++)
+      os << LINE_NUM_COEF_KW << i << ": <float>" << endl; 
+   os << endl;
+   for (int i=1; i<=20; i++)
+      os << LINE_DEN_COEF_KW << i << ": <float>" << endl; 
+   os << endl;
+   for (int i=1; i<=20; i++)
+      os << SAMP_NUM_COEF_KW << i << ": <float>" << endl; 
+   os << endl;
+   for (int i=1; i<=20; i++)
+      os << SAMP_DEN_COEF_KW << i << ": <float>" << endl; 
+   os << "\n" <<endl;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimRpcModel::writeGeomTemplate(): returning..." << std::endl;
+   return;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimRpcModel.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimRpcModel.h
new file mode 100644
index 0000000000..d55f2c13ae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/rpc/ossimRpcModel.h
@@ -0,0 +1,193 @@
+//*****************************************************************************
+// FILE: ossimRpcModel.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// AUTHOR: Oscar Kramer
+//
+// DESCRIPTION: Contains declaration of class ossimRpcModel.
+//   This is a replacement model utilizing the Rational Polynomial Coefficients
+//   (RPC), a.k.a. Rapid Positioning Capability, and Universal Sensor Model
+//   (USM).
+//
+//*****************************************************************************
+//  $Id: ossimRpcModel.h,v 1.12 2005/05/12 19:55:13 gpotts Exp $
+
+#ifndef ossimRpcModel_HEADER
+#define ossimRpcModel_HEADER
+
+#include <projections/sensor_modeling/ossimSensorModel.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimDblGrid.h>
+#include <base/data_types/ossimFilename.h>
+
+/*!****************************************************************************
+ *
+ * CLASS:  ossimRpcModel
+ *
+ *****************************************************************************/
+class OSSIMDLLEXPORT ossimRpcModel : public ossimSensorModel
+{
+public:
+   //***
+   // Enumeration of supported RPC polynomial formats:
+   //***
+   enum PolynomialType
+   {
+      A='A',  // corresponds to "RPC00A"
+      B='B'   // corresponds to "RPC00B"
+   };
+   
+   /*!
+    * CONSTRUCTORS:
+    */
+   ossimRpcModel();
+   ossimRpcModel(const ossimRpcModel& copy_this);
+   ossimRpcModel(const ossimKeywordlist& geom_kwl);
+   ~ossimRpcModel();
+
+   void setAttributes(ossim_float64 theSampleOffset,
+                      ossim_float64 theLineOffset,
+                      ossim_float64 theSampleScale,
+                      ossim_float64 theLineScale,
+                      ossim_float64 theLatOffset,
+                      ossim_float64 theLonOffset,
+                      ossim_float64 theHeightOffset,
+                      ossim_float64 theLatScale,
+                      ossim_float64 theLonScale,
+                      ossim_float64 theHeightScale,
+                      const std::vector<double>& xNumeratorCoeffs,
+                      const std::vector<double>& xDenominatorCoeffs,
+                      const std::vector<double>& yNumeratorCoeffs,
+                      const std::vector<double>& yDenominatorCoeffs,
+                      PolynomialType polyType = B,
+                      bool computeGsd=true);
+
+   void setMetersPerPixel(const ossimDpt& metersPerPixel);
+   /*!
+    * METHOD: worldToLineSample()
+    * Overrides base class implementation. Directly computes line-sample from
+    * the polynomials.
+    */
+   virtual void  worldToLineSample(const ossimGpt& world_point,
+                                   ossimDpt&       image_point) const;
+   /*!
+    * METHOD: print()
+    * Extends base-class implementation. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+   /*!
+    * METHODS:  saveState, loadState
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files. Returns true if successful.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+
+   virtual void  lineSampleToWorld(const ossimDpt& image_point,
+                                   ossimGpt&       world_point) const;
+   //***
+   // METHOD: lineSampleHeightToWorld()
+   // Overrides base class pure virtual. Height understood to be relative to
+   // standard ellipsoid.
+   //***
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const double&   heightEllipsoid,
+                                        ossimGpt&       worldPoint) const;
+
+   /*!
+    * STATIC METHOD: writeGeomTemplate(ostream)
+    * Writes a template of geom keywords processed by loadState and saveState
+    * to output stream.
+    */
+   static void writeGeomTemplate(ostream& os);
+
+   virtual void updateModel();
+   virtual void initAdjustableParameters();
+
+   /*!
+    * METHOD: dup()
+    * Returns pointer to a new instance, copy of this.
+    */
+   virtual ossimObject* dup() const { return new ossimRpcModel(*this); }
+   
+  static const ossimFilename INIT_RPC_GEOM_FILENAME;
+
+protected:
+   enum AdjustParamIndex
+   {
+      INTRACK_OFFSET = 0,
+      CRTRACK_OFFSET,
+      INTRACK_SCALE,
+      CRTRACK_SCALE,
+      MAP_ROTATION,
+//      YAW_OFFSET,
+      NUM_ADJUSTABLE_PARAMS // not an index
+   };
+
+   //***
+   // Methods for computing RPC polynomial and its derivatives:
+   //***
+   double polynomial(const double& nlat,
+                     const double& nlon,
+                     const double& nhgt,
+                     const double* coeffs) const;
+   double dPoly_dLat(const double& nlat,
+                     const double& nlon,
+                     const double& nhgt,
+                     const double* coeffs) const;
+   double dPoly_dLon(const double& nlat,
+                     const double& nlon,
+                     const double& nhgt,
+                     const double* coeffs) const;
+   
+   virtual ossimDpt extrapolate (const ossimGpt& gp) const;
+   virtual ossimGpt extrapolate (const ossimDpt& ip,
+				 const double& height
+				 =ossimElevSource::DEFAULT_NULL_HEIGHT) const;
+   PolynomialType thePolyType;
+   //***
+   // Quantities for zero-biasing and normalizing the image point and
+   // ground point coordinates referenced in the polynomials:
+   //***
+   double theLineScale;
+   double theSampScale;
+   double theLatScale;
+   double theLonScale;
+   double theHgtScale;
+   double theLineOffset;
+   double theSampOffset;
+   double theLatOffset;
+   double theLonOffset;
+   double theHgtOffset;
+
+   //***
+   // Coefficients:
+   //***
+   double theLineNumCoef[20];
+   double theLineDenCoef[20];
+   double theSampNumCoef[20];
+   double theSampDenCoef[20];
+   
+   //***
+   // Quantities derived from the adjustable parameters:
+   //***
+   double theIntrackOffset;
+   double theCrtrackOffset;
+   double theIntrackScale;
+   double theCrtrackScale;
+   double theYawSkew;  // = sin(theYawOffset)
+   double theCosMapRot;
+   double theSinMapRot;
+   TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/.cvsignore b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/ossimSpot5Model.cpp b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/ossimSpot5Model.cpp
new file mode 100644
index 0000000000..c8402b8cb5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/ossimSpot5Model.cpp
@@ -0,0 +1,593 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Oscar Kramer (ossim port by D. Burken)
+//
+// Description:  
+//
+// Contains definition of class ossimSpot5Model.
+// 
+//*****************************************************************************
+// $Id: ossimSpot5Model.cpp,v 1.14 2006/01/06 14:43:13 gpotts Exp $
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+using namespace std;
+
+#include <projections/sensor_modeling/spot/ossimSpot5Model.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <support_data/spot/ossimSpotDimapSupportData.h>
+#include <projections/map_projections/ossimMapProjection.h>
+#include <base/data_types/ossimLsrPoint.h>
+#include <base/data_types/ossimEcefRay.h>
+#include <base/data_types/ossimLsrRay.h>
+#include <base/data_types/ossimLsrSpace.h>
+#include <base/data_types/ossimDpt3d.h>
+#include <base/data_types/ossimColumnVector3d.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimSpot5Model, "ossimSpot5Model", ossimSensorModel);
+
+
+//---
+// Define Trace flags for use within this file:
+//---
+#include <base/common/ossimTrace.h>
+static ossimTrace traceExec  ("ossimSpot5Model:exec");
+static ossimTrace traceDebug ("ossimSpot5Model:debug");
+
+static const ossim_int32 MODEL_VERSION_NUMBER = 1;
+
+static const char* PARAM_NAMES[] = { "roll_offset",
+                                     "pitch_offset",
+                                     "yaw_offset",
+                                     "roll_rate",
+                                     "pitch_rate",
+                                     "yaw_rate",
+                                     "focal_length_offset" };
+
+static const char* PARAM_UNITS[] = { "degrees",   // degrees
+                                     "degrees",   // degrees
+                                     "degrees",   // degrees
+                                     "degrees",   // degrees/sec
+                                     "degrees",   // degrees/sec
+                                     "degrees",   // degrees/sec
+                                     "unknown" }; // percent deviation from nominal
+
+static const ossim_float64 SIGMA[] = { 0.0001,   // degrees
+                                       0.0001,   // degrees
+                                       0.0003,   // degrees
+                                       0.00002,  // delta degrees
+                                       0.00002,  // delta degrees
+                                       0.00005,  // delta degrees
+                                       0.0001 }; // percent
+
+ossimSpot5Model::ossimSpot5Model()
+   :
+   ossimSensorModel      (),
+   theSupportData        (NULL),
+   theMetaDataFile       ("NOT ASSIGNED"),
+   theIllumAzimuth       (0.0),
+   theIllumElevation     (0.0),
+   thePositionError      (0.0),
+   theRefImagingTime     (0.0),
+   theLineSamplingPeriod (0.0),
+   theSatToOrbRotation   (3, 3),
+   theOrbToEcfRotation   (3, 3),
+   theRollOffset         (0.0),
+   thePitchOffset        (0.0),
+   theYawOffset          (0.0),
+   theRollRate           (0.0),
+   thePitchRate          (0.0),
+   theYawRate            (0.0),
+   theFocalLenOffset     (0.0)
+{
+   initAdjustableParameters();
+}
+
+ossimSpot5Model::ossimSpot5Model(ossimSpotDimapSupportData* sd)
+   :
+   ossimSensorModel      (),
+   theSupportData        (sd),
+   theMetaDataFile       ("NOT ASSIGNED"),
+   theIllumAzimuth       (0.0),
+   theIllumElevation     (0.0),
+   thePositionError      (0.0),
+   theRefImagingTime     (0.0),
+   theLineSamplingPeriod (0.0),
+   theSatToOrbRotation   (3, 3),
+   theOrbToEcfRotation   (3, 3),
+   theRollOffset         (0.0),
+   thePitchOffset        (0.0),
+   theYawOffset          (0.0),
+   theRollRate           (0.0),
+   thePitchRate          (0.0),
+   theYawRate            (0.0),
+   theFocalLenOffset     (0.0)
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model(dimap_file) Constructor: entering..." << std::endl;
+
+   //---
+   // Instantiate the support data classes after establishing the filenames:
+   //---
+   loadSupportData();
+   if (getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model(dimap_file) Constructor: returning with error..." << std::endl;
+      return;
+   }
+
+   //---
+   // initialize remaining data members:
+   //---
+   initAdjustableParameters();
+   updateModel();
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model(dimap_file) Constructor: returning..." << std::endl;
+}
+
+//*****************************************************************************
+//  DESTRUCTOR: ~ossimSpot5Model()
+//  
+//*****************************************************************************
+ossimSpot5Model::~ossimSpot5Model()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG DESTRUCTOR: ~ossimSpot5Model(): entering..." << std::endl;
+
+   if (theSupportData)
+   {
+      delete theSupportData;
+      theSupportData = NULL;
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG DESTRUCTOR: ~ossimSpot5Model(): returning..." << std::endl;
+}
+
+ossimSpot5Model::ossimSpot5Model(const ossimSpot5Model& rhs)
+   :ossimSensorModel(rhs)
+{
+   if(theSupportData)
+   {
+      
+      delete theSupportData;
+      theSupportData = 0;
+   }
+   if(rhs.theSupportData)
+   {
+      theSupportData = (ossimSpotDimapSupportData*)rhs.theSupportData->dup();
+   }
+   loadSupportData();
+   updateModel();
+}
+
+//*****************************************************************************
+//  METHOD
+//*****************************************************************************
+void ossimSpot5Model::computeSatToOrbRotation(ossim_float64 t)const
+{
+   if (traceExec())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimSpot5Model::computeSatToOrbRotation(): entering..."
+         << std::endl;
+   }
+
+   //---
+   // Linearly interpolate attitudes angles:
+   //---
+   ossimDpt3d att;
+   theSupportData->getAttitude(t, att);
+
+   //---
+   // Apply the attitude adjustable parameters:
+   //---
+   double dt = theRefImagingTime - t;
+   att.x     += thePitchOffset + dt*thePitchRate;
+   att.y     += theRollOffset  + dt*theRollRate;
+   att.z     += theYawOffset   + dt*theYawRate;
+   
+   //---
+   // Compute trig functions to populate rotation matrices: ANGLES IN RADIANS
+   //---
+    double cp = cos(att.x);
+    double sp = sin(att.x);
+    double cr = cos(att.y);
+    double sr = sin(att.y);
+    double cy = cos(att.z);
+    double sy = sin(att.z);
+
+   //---
+   // Populate rotation matrix:
+   //---
+    theSatToOrbRotation = NEWMAT::Matrix(3,3);
+    theSatToOrbRotation << (cr*cy) << (-cr*sy) << (-sr)
+                        << (cp*sy+sp*sr*cy) << (cp*cy-sp*sr*sy) << (sp*cr)
+                        << (-sp*sy+cp*sr*cy) << (-sp*cy-cp*sr*sy) <<  cp*cr;
+    
+   
+    if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model::computeSatToOrbRotation(): returning..." << std::endl;
+}
+
+//*****************************************************************************
+// PUBLIC METHOD: ossimSpot5Model::updateModel()
+//  
+//  Updates the model parameters given the normalized adjustable parameter
+//  array.
+//  
+//*****************************************************************************
+void ossimSpot5Model::updateModel()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model::updateModel(): entering..." << std::endl;
+
+   if(getNumberOfAdjustableParameters() < 1)
+   {
+      theRollOffset     = 0;
+      thePitchOffset    = 0;
+      theYawOffset      = 0;
+      theRollRate       = 0;
+      thePitchRate      = 0;
+      theYawRate        = 0;
+      theFocalLenOffset = 0;
+   }
+   else
+   {
+      theRollOffset     = computeParameterOffset(0);
+      thePitchOffset    = computeParameterOffset(1);
+      theYawOffset      = computeParameterOffset(2);
+      theRollRate       = computeParameterOffset(3);
+      thePitchRate      = computeParameterOffset(4);
+      theYawRate        = computeParameterOffset(5);
+      theFocalLenOffset = computeParameterOffset(6);
+   }
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model::updateModel(): returning..." << std::endl;   
+}
+
+void ossimSpot5Model::initAdjustableParameters()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model::initAdjustableParameters(): entering..." << std::endl;
+
+   //---
+   // Allocate storage for adjustables and assign their names and units
+   // strings.
+   //---
+   resizeAdjustableParameterArray(7);
+   ossim_uint32 numParams = getNumberOfAdjustableParameters();
+   
+   //---
+   // Initialize base-class adjustable parameter array:
+   //---
+   for (ossim_uint32 i=0; i<numParams; ++i)
+   {
+      setAdjustableParameter(i, 0.0);
+      setParameterDescription(i, PARAM_NAMES[i]);
+      setParameterUnit(i,PARAM_UNITS[i]);
+      setParameterSigma(i, SIGMA[i]);
+   }
+   
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model::initAdjustableParameters(): returning..." << std::endl;
+}
+
+void ossimSpot5Model::loadSupportData()
+{
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "ossimSpot5Model::loadSupportData(): entering..." << std::endl;
+
+   //---
+   // Check for good support data:
+   //---
+   if (!theSupportData)
+   {
+      setErrorStatus();
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimSpot5Model::loadSupportData(): Null SpotDimapSupportData pointer passed to"
+                                          << " constructor! Aborting..." << std::endl;
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model::loadSupportData(): returning..." << std::endl;
+      return;
+   }
+      
+   if (theSupportData->getErrorStatus() != ossimErrorCodes::OSSIM_OK)
+   {
+      setErrorStatus();
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimSpot5Model::loadSupportData(): Bad SpotDimapSupportData detected. Aborting..."
+                                          << std::endl;
+      if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model::loadSupportData(): returning..." << std::endl;
+      return;
+   }
+
+   //---
+   // Initialize some member variables from the support data:
+   //---
+   theSensorID     = "Spot 5";
+   theImageID      = theSupportData->getImageID();
+   theMetaDataFile = theSupportData->getMetadataFile();
+   theSupportData->getRefGroundPoint(theRefGndPt);
+   theSupportData->getRefImagePoint(theRefImgPt);
+   theSupportData->getSunAzimuth(theIllumAzimuth);
+   theSupportData->getSunElevation(theIllumElevation);
+   ossimDpt sz;
+   theSupportData->getImageSize(sz);
+   theImageSize = sz;
+   theSupportData->getRefLineTime(theRefImagingTime);
+   theSupportData->getLineSamplingPeriod(theLineSamplingPeriod);
+   theSupportData->getSubImageOffset(theSubImageOffset);
+   theImageClipRect    = ossimDrect(0,0, theImageSize.x -1, theImageSize.y-1);
+   ossimGpt p1;
+   ossimGpt p2;
+   ossimGpt p3;
+   ossimGpt p4;
+
+
+   // I need to find the nominal scale of the spot 5 dataset
+   
+   //---
+   // Position error is a function of whether star tracker information was
+   // available:
+   //---
+   if (theSupportData->isStarTrackerUsed())
+   {
+      thePositionError = 50.0;
+   }
+   else
+   {
+      thePositionError = 200.0; // meters
+   }
+   updateModel();
+
+   lineSampleToWorld(theImageClipRect.ul(), p1);
+   lineSampleToWorld(theImageClipRect.ur(), p2);
+   lineSampleToWorld(theImageClipRect.lr(), p3);
+   lineSampleToWorld(theImageClipRect.ll(), p4);
+
+//    theSupportData->getUlCorner(p1);
+//    theSupportData->getUrCorner(p2);
+//    theSupportData->getLrCorner(p3);
+//    theSupportData->getLlCorner(p4);
+
+   ossimDpt v[4]; // temporarily holds vertices for ground polygon
+   v[0] = p1;
+   v[1] = p2;
+   v[2] = p3;
+   v[3] = p4;
+   theBoundGndPolygon = ossimPolygon(4, v);
+
+
+   ossimGpt cgpt, hgpt, vgpt;
+   // ossimEcefPoint hVector, vVector;
+   ossimDpt midpt = theImageClipRect.midPoint();
+
+   lineSampleToWorld(midpt, cgpt);
+   lineSampleToWorld(midpt + ossimDpt(1,0), hgpt);
+   lineSampleToWorld(midpt + ossimDpt(0,1), vgpt);
+
+   theGSD     = ossimDpt((ossimEcefPoint(cgpt) - ossimEcefPoint(hgpt)).magnitude(),
+			 (ossimEcefPoint(cgpt) - ossimEcefPoint(vgpt)).magnitude());
+   
+   theMeanGSD = (theGSD.x+theGSD.y)/2.0;
+
+   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model::loadSupportData(): returning..." << std::endl;
+}
+
+ossimObject* ossimSpot5Model::dup() const
+{
+   return new ossimSpot5Model(*this);
+}
+
+std::ostream& ossimSpot5Model::print(std::ostream& out) const
+{
+   out << "\nDump of ossimSpot5Model at address " << (hex) << this
+       << "\n------------------------------------------------"
+       << "\n  theImageID            = " << theImageID
+       << "\n  theMetadataFile       = " << theMetaDataFile
+       << "\n  theIllumAzimuth       = " << theIllumAzimuth
+       << "\n  theIllumElevation     = " << theIllumElevation
+       << "\n  thePositionError      = " << thePositionError
+       << "\n  theImageSize          = " << theImageSize
+       << "\n  theRefGndPt           = " << theRefGndPt
+       << "\n  theRefImgPt           = " << theRefImgPt
+       << "\n  theRefImagingTime     = " << theRefImagingTime
+       << "\n  theLineSamplingPeriod = " << theLineSamplingPeriod
+       << "\n  theRollOffset         = " << theRollOffset
+       << "\n  thePitchOffset        = " << thePitchOffset
+       << "\n  theYawOffset          = " << theYawOffset
+       << "\n  theRollRate           = " << theRollRate
+       << "\n  thePitchRate          = " << thePitchRate
+       << "\n  theYawRate            = " << theYawRate
+       << "\n  theFocalLenOffset     = " << theFocalLenOffset
+       << "\n------------------------------------------------"
+       << "\n  " << endl;
+
+   return ossimSensorModel::print(out);
+}
+
+bool ossimSpot5Model::saveState(ossimKeywordlist& kwl,
+                          const char* prefix) const
+{
+   ossimString supportPrefix = ossimString(prefix) + "support_data.";
+   theSupportData->saveState(kwl, supportPrefix);
+   
+   
+   return ossimSensorModel::saveState(kwl, prefix);
+}
+
+bool ossimSpot5Model::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   ossimString supportPrefix = ossimString(prefix) + "support_data.";
+   
+   if(!theSupportData)
+   {
+      theSupportData = new ossimSpotDimapSupportData;
+   }
+   
+   if(theSupportData->loadState(kwl, supportPrefix))
+   {
+      ossimSensorModel::loadState(kwl, prefix);
+   }
+   
+   loadSupportData();
+   updateModel();
+   
+   return true;
+}
+
+void ossimSpot5Model::imagingRay(const ossimDpt& image_point,
+                                 ossimEcefRay&   image_ray) const
+{
+   bool runtime_dbflag = 0;
+
+   ossimDpt iPt = image_point;
+   iPt.samp += theSubImageOffset.samp;
+   iPt.line += theSubImageOffset.line;
+
+
+   //
+   // 1. Establish time of line imaging:
+   //
+   double t_line = theRefImagingTime +
+                   theLineSamplingPeriod*(iPt.line - theRefImgPt.line);
+   if (traceDebug() || runtime_dbflag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG Spot5Model::imagingRay():------------ BEGIN DEBUG PASS ---------------" << std::endl;
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG Spot5Model::imagingRay(): t_line = " << t_line << std::endl;
+   }
+
+   //
+   // 2. Interpolate ephemeris position and velocity (in ECF):
+   //
+   ossimEcefPoint  tempEcefPoint;
+   ossimEcefPoint  P_ecf;
+   theSupportData->getPositionEcf(t_line, P_ecf);
+   theSupportData->getVelocityEcf(t_line, tempEcefPoint);
+   ossimEcefVector V_ecf(tempEcefPoint.x(),
+                         tempEcefPoint.y(),
+                         tempEcefPoint.z());
+   if (traceDebug() || runtime_dbflag)
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG:\n\tP_ecf = " << P_ecf
+                                          << "\n\t V_ecf = " << V_ecf << std::endl;
+   }
+                   
+   //
+   // 3. Establish the look direction in Vehicle LSR space (S_sat).
+   //    ANGLES IN RADIANS
+   //
+    ossim_float64 Psi_x;
+    theSupportData->getPixelLookAngleX(iPt.samp, Psi_x);
+    ossim_float64 Psi_y;
+    theSupportData->getPixelLookAngleY(iPt.samp, Psi_y);
+    if (traceDebug() || runtime_dbflag)
+    {
+       ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG:\n\t Psi_x = " << Psi_x
+                                           << "\n\t Psi_y = " << Psi_y << endl;
+    }
+
+    ossimColumnVector3d u_sat (-tan(Psi_y), tan(Psi_x), -(1.0 + theFocalLenOffset));
+    if (traceDebug() || runtime_dbflag)
+    {
+       ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG \n\t u_sat = " << u_sat << endl;
+    }
+
+   //
+   // 4. Transform vehicle LSR space look direction vector to orbital LSR space
+   //    (S_orb):
+   //
+    computeSatToOrbRotation(t_line);
+    
+    ossimColumnVector3d u_orb = (theSatToOrbRotation*u_sat).unit();
+    if (traceDebug() || runtime_dbflag)
+    {
+       ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG:\n\t theSatToOrbRotation = " << theSatToOrbRotation
+                                           << "\n\t u_orb = " << u_orb << endl;
+    }
+
+   //
+   // 5. Transform orbital LSR space look direction vector to ECF.
+   //
+   //   a. S_orb space Z-axis (Z_orb) is || to the ECF radial vector (P_ecf),
+   //   b. X_orb axis is computed as cross-product between velocity and radial,
+   //   c. Y_orb completes the orthogonal S_orb coordinate system.
+   //
+    ossimColumnVector3d Z_orb (P_ecf.x(),
+                               P_ecf.y(),
+                               P_ecf.z());
+    Z_orb = Z_orb.unit();
+
+    ossimColumnVector3d X_orb = ossimColumnVector3d(V_ecf.x(),
+                                                    V_ecf.y(),
+                                                    V_ecf.z()).cross(Z_orb).unit();
+    ossimColumnVector3d Y_orb = Z_orb.cross(X_orb);
+
+    theOrbToEcfRotation = NEWMAT::Matrix(3, 3);
+    theOrbToEcfRotation << X_orb[0] << Y_orb[0] << Z_orb[0]
+                        << X_orb[1] << Y_orb[1] << Z_orb[1]
+                        << X_orb[2] << Y_orb[2] << Z_orb[2];
+    
+
+   ossimColumnVector3d u_ecf  = (theOrbToEcfRotation*u_orb);
+    if (traceDebug() || runtime_dbflag)
+    {
+       ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG:\n\t theOrbToEcfRotation = " << theOrbToEcfRotation
+            << "\n\t u_ecf = " << u_ecf << endl;
+    }
+   
+   //
+   // Establish the imaging ray given direction and origin:
+   //
+    image_ray = ossimEcefRay(P_ecf, ossimEcefVector(u_ecf[0], u_ecf[1], u_ecf[2]));
+    
+    if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG Spot5Model::imagingRay(): returning..." << std::endl;
+}
+
+void ossimSpot5Model::lineSampleHeightToWorld(const ossimDpt& image_point,
+                                              const ossim_float64& heightEllipsoid,
+                                              ossimGpt& worldPoint) const
+{
+   if (!insideImage(image_point))
+   {
+      worldPoint = extrapolate(image_point, heightEllipsoid);
+      if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimSpot5Model::lineSampleHeightToWorld(): returning..." << std::endl;
+      return;
+   }
+   
+   //***
+   // First establish imaging ray from image point:
+   //***
+   ossimEcefRay imaging_ray;
+   imagingRay(image_point, imaging_ray);
+   ossimEcefPoint Pecf (imaging_ray.intersectAboveEarthEllipsoid(heightEllipsoid));
+   worldPoint = ossimGpt(Pecf);
+}
+
+ossimDpt ossimSpot5Model::extrapolate (const ossimGpt& gp) const
+{
+    ossimDpt temp;
+
+    temp.makeNan();
+
+    return temp;
+
+//   ossimDpt tempGpt = gp;
+//   ossimDpt dest;
+//   theGroundToImageMap.map(tempGpt, dest);
+  
+//  return dest;
+
+}
+
+ossimGpt ossimSpot5Model::extrapolate (const ossimDpt& ip,
+				       const double& height) const
+{
+  return ossimGpt(OSSIM_DBL_NAN, OSSIM_DBL_NAN, OSSIM_DBL_NAN, 0);
+
+//    ossimDpt dest;
+
+//    theImageToGroundMap.map(ip, dest);
+  
+
+//    return ossimGpt(dest.lat, dest.lon, OSSIM_DBL_NAN, origin().datum());
+}
diff --git a/Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/ossimSpot5Model.h b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/ossimSpot5Model.h
new file mode 100644
index 0000000000..9d82da155c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/projections/sensor_modeling/spot/ossimSpot5Model.h
@@ -0,0 +1,163 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc.  All rights reserved.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Oscar Kramer <okramer@imagelinks.com>
+//          ossim port by David Burken <dburken@imagelinks.com>
+//
+// Description:  
+//
+// Contains declaration of class ossimSpot5Model.
+// 
+//*****************************************************************************
+// $Id: ossimSpot5Model.h,v 1.7 2006/01/06 14:43:13 gpotts Exp $
+#ifndef ossimSpot5Model_HEADER
+#define ossimSpot5Model_HEADER
+
+#include <iostream>
+using namespace std;
+
+#include <projections/sensor_modeling/ossimSensorModel.h>
+#include <base/data_types/ossimIpt.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimEcefRay.h>
+#include <base/data_types/ossimEcefPoint.h>
+#include <base/data_types/ossimMatrix3x3.h>
+
+class ossimSpotDimapSupportData;
+
+class OSSIMDLLEXPORT ossimSpot5Model : public ossimSensorModel
+{
+public:
+   /*!
+    * CONSTRUCTORS:
+    */
+   ossimSpot5Model();
+   ossimSpot5Model(ossimSpotDimapSupportData* sd);
+   ossimSpot5Model(const ossimFilename& init_file);
+   ossimSpot5Model(const ossimKeywordlist& geom_kwl);
+   ossimSpot5Model(const ossimSpot5Model& rhs);
+
+   virtual ~ossimSpot5Model();
+
+   enum AdjustParamIndex
+   {
+      ROLL_OFFSET = 0,
+      PITCH_OFFSET,
+      YAW_OFFSET,
+      ROLL_RATE,
+      PITCH_RATE,
+      YAW_RATE,
+      FOCAL_LEN_OFFSET,
+      NUM_ADJUSTABLE_PARAMS // not an index
+   };   
+
+   /*!
+    * Returns pointer to a new instance, copy of this.
+    * Not implemented yet!  Returns NULL...
+    */
+   virtual ossimObject* dup() const;
+
+   /*!
+    * Extends base-class implementation. Dumps contents of object to ostream.
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+   /*!
+    * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
+    * KWL files. Returns true if successful.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=NULL) const;
+   
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=NULL);
+
+   /*!
+    * Writes a template of geom keywords processed by loadState and saveState
+    * to output stream.
+    */
+   static void writeGeomTemplate(ostream& os);
+
+   /*!
+    * Given an image point and height, initializes worldPoint.
+    */
+   virtual void lineSampleHeightToWorld(const ossimDpt& image_point,
+                                        const ossim_float64& heightEllipsoid,
+                                        ossimGpt& worldPoint) const;
+   
+   /*!
+    * Given an image point, returns a ray originating at some arbitrarily high
+    * point (ideally at the sensor position) and pointing towards the target.
+    */
+   virtual void imagingRay(const ossimDpt& image_point,
+                           ossimEcefRay&   image_ray) const;
+
+   /*!
+    * Following a change to the adjustable parameter set, this virtual
+    * is called to permit instances to compute derived quantities after
+    * parameter change.
+    */
+   virtual void updateModel();
+
+protected:
+
+   /*!
+    * Sets adjustables to default values.
+    */
+   void initAdjustableParameters();
+   
+   void loadGeometry(FILE*);
+   void loadSupportData();
+   void computeSatToOrbRotation(ossim_float64 t)const;
+
+   virtual ossimDpt extrapolate (const ossimGpt& gp) const;
+   virtual ossimGpt extrapolate (const ossimDpt& ip,
+				 const double& height
+				 =ossimElevSource::DEFAULT_NULL_HEIGHT) const;
+
+   ossimSpotDimapSupportData* theSupportData;
+
+   //---
+   // Image constant parameters:
+   //---
+   ossimFilename  theMetaDataFile;
+   ossim_float64  theIllumAzimuth;  
+   ossim_float64  theIllumElevation;
+   ossim_float64  thePositionError;
+   ossim_float64  theRefImagingTime;
+   ossim_float64  theLineSamplingPeriod;
+   mutable NEWMAT::Matrix theSatToOrbRotation;
+   mutable NEWMAT::Matrix theOrbToEcfRotation;
+
+   //---
+   // Adjustable parameters:
+   //---
+   ossim_float64  theRollOffset;      // degrees
+   ossim_float64  thePitchOffset;     // degrees
+   ossim_float64  theYawOffset;       // degrees
+   ossim_float64  theRollRate;        // degrees/sec
+   ossim_float64  thePitchRate;       // degrees/sec
+   ossim_float64  theYawRate;         // degrees/sec
+   ossim_float64  theFocalLenOffset;  // percent deviation from nominal
+
+TYPE_DATA
+};
+
+#endif /* #ifndef ossimSpot5Model_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/support_data/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/.cvsignore
new file mode 100644
index 0000000000..744ff800ee
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/.cvsignore
@@ -0,0 +1,4 @@
+*.d
+.shared_obj
+Makefile
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/CMakeLists.txt b/Utilities/OSSIM/ossim_core/support_data/CMakeLists.txt
new file mode 100644
index 0000000000..237be8a918
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_support_data_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_support_data_HDRS "*.h")
+ADD_LIBRARY(ossim_support_data ${ossim_support_data_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_support_data)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_support_data_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/support_data/doqq/ossimDoqq.cpp b/Utilities/OSSIM/ossim_core/support_data/doqq/ossimDoqq.cpp
new file mode 100644
index 0000000000..e7f2d96d2f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/doqq/ossimDoqq.cpp
@@ -0,0 +1,393 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description: This class parses a Digital Ortho Quarter Quad (DOQQ)
+//              header.
+//
+//********************************************************************
+// $Id: ossimDoqq.cpp,v 1.6 2005/11/08 20:24:26 gpotts Exp $
+
+#include <fstream>
+#include <iostream>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ossimDoqq.h"
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+static ossimTrace traceDebug("ossimDoqq:debug");
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDoqq::ossimDoqq(ossimFilename file)
+   :
+      theErrorStatus(OSSIM_OK)
+{
+   static const char MODULE[] = "ossimDoqq Constructor";
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "Entering " << MODULE << std::endl;
+   }
+      
+   // Check first line of header to determine which version to parse.
+   std::ifstream inFile(file.c_str(), std::ios::in);
+   char header[23];
+   inFile.seekg(0, std::ios::beg);
+   inFile.get(header, 22);
+   header[22] = '\0';
+   if(strcmp((const char*)header, "BEGIN_USGS_DOQ_HEADER") == 0)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimDoqq::ossimDoqq Loading DOQ version 2 header..."
+            << std::endl;
+      }
+
+      ldstr_v2(inFile);
+   }
+   else
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimDoqq::ossimDoqq  Loading DOQ version 1 header..."
+            << std::endl;
+      }
+
+      ldstr_v1(inFile);
+   }
+
+   inFile.close();
+
+   // Check for error.
+   if(theErrorStatus)
+   {
+      return;
+   }
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << *this << std::endl;
+   }
+}
+
+ossimDoqq::~ossimDoqq()
+{
+}
+
+void ossimDoqq::ldstr_v2(std::istream& in)
+{
+   static const char MODULE[] = "ossimDoqq::ldstr_v2(istream& in)";
+
+   if (!in)
+   {
+      theErrorStatus = OSSIM_ERROR;
+      return;
+   }
+
+   char line[100];
+   while(!strncmp(line, "END_USGS_HEADER", 15) == 0)
+   {
+      // Read in one line of header at a time.
+      in.getline(line, 100);
+      
+      if(strncmp(line, "SAMPLES_AND_LINES", 17) == 0)
+      {
+         char dum1[30];
+         char dum2[30];
+         char dum3[30];
+         sscanf(line, "%s %s %s", dum1, dum2, dum3);
+         theLine = atoi(dum3);
+         theSample = atoi(dum2);
+      }
+
+      if(strncmp(line, "HORIZONTAL_COORDINATE_SYSTEM", 28) == 0)
+      {
+         char dum1[30];
+         char dum2[30];
+         sscanf(line, "%s %s", dum1, dum2);
+         theProjection = dum2;
+      }
+      
+      if(strncmp(line, "NW_QUAD_CORNER_XY", 17) == 0)
+      {         
+         char dum1[30];
+         char dum2[30];
+         char dum3[30];         
+         sscanf(line, "%s %s %s", dum1, dum2, dum3);
+         
+         theUE = atof(dum2);
+         theUN = atof(dum3);
+      }
+      
+      if(strncmp(line, "NE_QUAD_CORNER_XY", 17) == 0)
+      {
+         char dum1[30];
+         char dum2[30];
+         char dum3[30];
+         sscanf(line, "%s %s %s", dum1, dum2, dum3);
+         theLE = atof(dum2);
+         theLN = atof(dum3);
+      }
+
+      if(strncmp(line, "COORDINATE_ZONE", 15) == 0)
+      {
+         char dum1[30];
+         char dum2[30];
+         sscanf(line, "%s %s", dum1, dum2);
+         theUtmZone = atoi(dum2);
+      }
+
+      if(strncmp(line, "SOURCE_IMAGE_DATE", 17) == 0)
+      {
+         char dum1[30];
+         char dum2[30];
+	 char dum3[30];
+	 char dum4[30];
+         sscanf(line, "%s %s %s %s", dum1, dum2, dum3, dum4);
+         theAcqYear  = ossimString(dum2);
+	 theAcqMonth = ossimString(dum3);
+	 theAcqDay   = ossimString(dum4);
+      }
+
+      if((strncmp(line, "XY_ORIGIN", 9) == 0))
+      {
+         char dum1[30];
+         char dum2[30];
+         char dum3[30];
+         sscanf(line, "%s %s %s", dum1, dum2, dum3);
+         theEasting = atof(dum2);
+         theNorthing = atof(dum3);        
+      }
+
+      if((strncmp(line, "HORIZONTAL_DATUM", 16) == 0) && theDatum.empty())
+      {
+         char dum1[30];
+         char dum2[30];
+         ossimString datum;         
+         sscanf(line, "%s %s", dum1, dum2);
+         datum = dum2; 
+         
+         if(datum.contains("NAD27"))
+	   theDatum = "NAD";
+         else
+	   theDatum = "NAR";
+      }
+
+      if(strncmp(line, "BYTE_COUNT", 10) == 0)
+      {
+         char dum1[30];
+         char dum2[30];
+         ossimString header;         
+         sscanf(line, "%s %s", dum1, dum2);
+         header = dum2;
+         
+         theHeaderSize = atoi(header.chars());
+      }
+
+      if(strncmp(line, "BAND_CONTENT", 12) == 0)
+      {
+         char dum1[30];
+         char dum2[30];
+         ossimString rgbType;        
+         sscanf(line, "%s %s", dum1, dum2);
+         rgbType = dum2;
+
+         if(rgbType.contains("BLACK&WHITE"))
+            theRgb = 1;
+         else
+            theRgb = 3;
+      }
+
+      if(strncmp(line, "HORIZONTAL_RESOLUTION", 21) == 0)
+      {
+         char dum1[30];
+         char dum2[30];
+         ossimString gsd;
+         sscanf(line, "%s %s", dum1, dum2);
+         gsd = dum2;
+
+         theGsd.x = gsd.toDouble();
+         theGsd.y = gsd.toDouble();
+//         theGsd = atof(gsd.chars());
+//          theGsd.x = ossimAbs(ossimString(dum1).toDouble());
+//          theGsd.y = ossimAbs(ossimString(dum2).toDouble());
+      }
+   }
+
+   // Check for valid lines and samples and header size.
+   if(theLine <= 0 || theSample <= 0 || theHeaderSize <= 0)
+   {
+      theErrorStatus = OSSIM_ERROR;
+
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " ERROR:\n"
+            << "\tInvalid lines or samples or header size."
+            << std::endl;
+      }
+      
+      return;
+   }
+}
+
+void ossimDoqq::ldstr_v1(std::istream& in)
+{
+   static const char MODULE[] = "ossimDoqq::ldstr_v1(istream& in)";
+
+   if (!in)
+   {
+      theErrorStatus = OSSIM_ERROR;
+      return;
+   }
+
+   char tmp1[DATA_ORDER_SIZE];
+   in.seekg(DATA_ORDER_OFFSET, std::ios::beg);
+   in.get(tmp1, DATA_ORDER_SIZE);
+   theDataOrder = tmp1;
+
+   //***
+   // Perform a sanity check on the data order just in case this isn't a
+   // ossimDoqq file.
+   //***  
+   tmp1[DATA_ORDER_SIZE-1] = '\0';
+   int data_order = atoi(tmp1);
+   if ( (data_order != 1) && (data_order != 2) )
+   {
+      theErrorStatus = OSSIM_ERROR;
+
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " NOTICE:\n"
+            << "Invalid data ordering.  Not a doq?" << std::endl;
+      }
+   }
+   
+   char tmp2[LINE_SIZE];
+   in.seekg(LINE_OFFSET, std::ios::beg);
+   in.get(tmp2, LINE_SIZE);
+   theLine = atoi(tmp2);
+
+   char tmp3[SAMPLE_SIZE];
+   in.seekg(SAMPLE_OFFSET,std::ios::beg);
+   in.get(tmp3, SAMPLE_SIZE); 
+   theSample = atoi(tmp3);
+
+   // Check for valid lines and samples.
+   if (theLine <= 0 || theSample <= 0)
+   {
+      theErrorStatus = OSSIM_ERROR;
+
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << MODULE << " ERROR:\n"
+            << "\tInvalid lines or samples."
+            << std::endl;
+      }
+      
+      return;
+   }
+   
+   char tmp4[PROJECTION_SIZE];
+   in.seekg(PROJECTION_OFFSET, std::ios::beg);
+   in.get(tmp4, PROJECTION_SIZE);
+   theProjection = tmp4;
+
+   char tmp5[UTM_ZONE_SIZE];
+   in.seekg(UTM_ZONE_OFFSET, std::ios::beg);
+   in.get(tmp5, UTM_ZONE_SIZE);
+   theUtmZone = atoi(tmp5);
+
+   char tmp8[DATUM_SIZE];
+   in.seekg(DATUM_OFFSET, std::ios::beg);
+   in.get(tmp8, DATUM_SIZE);
+   theDatum = tmp8;
+
+   char rgbType[RGB_SIZE];
+   in.seekg(RGB_OFFSET, std::ios::beg);
+   in.get(rgbType, RGB_SIZE);
+
+
+   if(atoi(rgbType) == 5)
+   {
+      theRgb = 3;
+   }
+   else
+   {
+      theRgb = 1;
+   }
+   
+   theHeaderSize = (theSample * theRgb * 4);
+
+   // Calculate the size of each record.
+   theRecordSize = (theSample * theRgb);
+
+   char tmp6[UL_EASTING_SIZE];
+   in.seekg( (theRecordSize * 2) + UL_EASTING_OFFSET, std::ios::beg);
+   in.get(tmp6, UL_EASTING_SIZE);
+
+   char tmp7[UL_NORTHING_SIZE];
+   in.seekg( (theRecordSize * 2) + UL_NORTHING_OFFSET, std::ios::beg);
+   in.get(tmp7, UL_NORTHING_SIZE);
+
+   // Get Easting and Northing.
+   theEasting = convertStr(tmp6);
+   theNorthing = convertStr(tmp7);
+
+   char tmp10[GSD_SIZE];
+   in.seekg( (theRecordSize*3) + GSD_X_OFFSET, std::ios::beg);
+   in.get(tmp10, GSD_SIZE, std::ios::beg);
+   theGsd.x = ossimAbs(ossimString(tmp10, tmp10+GSD_SIZE).toDouble());
+   in.seekg( (theRecordSize*3) + GSD_Y_OFFSET, std::ios::beg);
+   in.get(tmp10, GSD_SIZE, std::ios::beg);
+   theGsd.y = ossimAbs(ossimString(tmp10, tmp10+GSD_SIZE).toDouble());
+   
+}
+
+ossim_float64 ossimDoqq::convertStr(const char str[]) const
+{
+   //***
+   // The USGS Projection Parameters in a OssimDoqq header have a "D" to
+   // denote the exponent.  This simply substitutes the "D" with an
+   // "E" so that atof works properly.
+   //***
+   ossimString tmp = str;
+   tmp.gsub("D", "E");
+   return atof(tmp.chars());
+}
+
+std::ostream& operator<<(std::ostream& out, const ossimDoqq& doq)
+{
+   out << "\nContents of DOQQ Update:\n"
+       << "\nLine:           " << doq.theLine
+       << "\nSample:         " << doq.theSample
+       << "\nProjection:     " << doq.theProjection
+       << "\nDatum:          " << doq.theDatum
+       << "\nEasting:        " << doq.theEasting
+       << "\nNorthing:       " << doq.theNorthing
+       << "\nUN:             " << doq.theUN
+       << "\nUE:             " << doq.theUE
+       << "\nLN:             " << doq.theLN
+       << "\nLE:             " << doq.theLE
+       << "\nGSD:            " << doq.theGsd
+       << "\nBand:           " << doq.theRgb
+       << "\nUtm Zone:       " << doq.theUtmZone << std::endl;
+   
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/doqq/ossimDoqq.h b/Utilities/OSSIM/ossim_core/support_data/doqq/ossimDoqq.h
new file mode 100644
index 0000000000..73b2dbbe20
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/doqq/ossimDoqq.h
@@ -0,0 +1,122 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//
+// Description: This class parses a Digital Ortho Quarter Quad (DOQQ)
+//              header.
+//
+//********************************************************************
+// $Id: ossimDoqq.h,v 1.3 2005/11/08 18:26:57 gpotts Exp $
+
+#ifndef ossimDoqq_HEADER
+#define ossimDoqq_HEADER
+
+#include <iostream>
+
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/common/ossimReferenced.h>
+
+class OSSIM_DLL ossimDoqq : public ossimReferenced
+{
+public:
+   ossimDoqq(ossimFilename file);
+   ~ossimDoqq();
+   
+   enum ossimErrorStatus
+   {
+      OSSIM_OK    = 0,
+      OSSIM_ERROR = 1
+   };
+
+   enum
+   {
+      NUMBER_OF_RECORDS       = 4,
+      QUADRANGLE_NAME_OFFSET  = 0,
+      QUADRANT_OFFSET         = 38,
+      NATION_OFFSET           = 40,
+      STATE_OFFSET            = 44,
+      GSD_X_OFFSET            = 59,
+      GSD_Y_OFFSET            = 59,
+      DATA_ORDER_OFFSET       = 142,      
+      LINE_OFFSET             = 145,
+      SAMPLE_OFFSET           = 151,
+      PROJECTION_OFFSET       = 196,
+      RGB_OFFSET              = 157,
+      UL_EASTING_OFFSET       = 288,
+      UL_NORTHING_OFFSET      = 312,
+      UTM_ZONE_OFFSET         = 199,
+      DATUM_OFFSET            = 168,
+
+      QUADRANGLE_NAME_SIZE    = 37,
+      QUADRANT_SIZE           = 2,
+      NATION_SIZE             = 4,
+      STATE_SIZE              = 2,
+      DATA_ORDER_SIZE         = 3,
+      LINE_SIZE               = 8,
+      SAMPLE_SIZE             = 8,  
+      PROJECTION_SIZE         = 3,
+      RGB_SIZE                = 3,
+      MARKING_U_SIZE          = 5,
+      MARKING_V_SIZE          = 5,
+      UL_EASTING_SIZE         = 24,
+      UL_NORTHING_SIZE        = 24,
+      UTM_ZONE_SIZE           = 6,
+      DATUM_SIZE              = 2,
+      RADIOMETRY_SIZE         = 3,
+      GSD_SIZE              = 12
+      
+   };
+
+   ossimString theProjection;
+   ossimString theDatum;
+   ossimString theQuadName;
+   ossimString theQuad;
+   ossimString theNation;
+   ossimString theState;
+   ossimString theDataOrder;
+   ossimString theMarkU;
+   ossimString theMarkV;
+   
+   ossim_int32 theUtmZone;
+   ossim_int32 theLine;
+   ossim_int32 theSample;
+   ossim_int32 theRgb;
+
+   ossimString theAcqYear;
+   ossimString theAcqMonth;
+   ossimString theAcqDay;
+   
+   ossim_float64   theEasting;
+   ossim_float64   theNorthing;
+   ossim_float64   theUN;
+   ossim_float64   theUE;
+   ossim_float64   theLN;
+   ossim_float64   theLE;
+   ossimDpt        theGsd;
+   ossim_int32     theHeaderSize;
+   ossim_int32     theRecordSize;
+
+   friend std::ostream& operator<<(std::ostream& os, const ossimDoqq& doq);
+   ossim_int32 errorStatus() const { return theErrorStatus; }
+   
+private:
+   // prevent use
+   ossimDoqq();
+
+   ossimErrorStatus        theErrorStatus;
+   
+   ossim_float64 convertStr(const char str[]) const;
+
+   void ldstr_v1(std::istream& in);
+   void ldstr_v2(std::istream& in);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/dted/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedAcc.cpp b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedAcc.cpp
new file mode 100644
index 0000000000..a0f51b6493
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedAcc.cpp
@@ -0,0 +1,248 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the Accuracy Description
+//               (ACC) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedAcc.cpp,v 1.11 2005/01/11 18:08:57 dburken Exp $
+
+#include <fstream>
+using namespace std;
+
+#include <support_data/dted/ossimDtedAcc.h>
+#include <base/context/ossimNotifyContext.h>
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedAcc::ossimDtedAcc(const ossimFilename& dted_file,
+                           ossim_int32 offset)
+   :
+      theRecSen(),
+      theAbsoluteCE(),
+      theAbsoluteLE(),
+      theRelativeCE(),
+      theRelativeLE(),
+      theField6(),
+      theField7(),
+      theField8(),
+      theField9(),
+      theField10(),
+      theField11(),
+      theField12(),
+      theField13(),
+      theField14(),
+      theField15(),
+      theField16(),
+      theField17(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   // Check to see that dted file exists.
+   if(!dted_file.exists())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimDtedAcc::ossimDtedAcc: The DTED file does not exist: " << dted_file << std::endl;
+      return;
+   }
+
+   // Check to see that the dted file is readable.
+   if(!dted_file.isReadable())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimDtedAcc::ossimDtedAcc: The DTED file is not readable: " << dted_file << std::endl;
+      return;
+   }
+   
+   // Open the dted file for reading.
+   ifstream in(dted_file.c_str());
+   if(!in)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimDtedAcc::ossimDtedAcc: Can't open the DTED file: " << dted_file << endl;
+      return;
+   }
+   
+   parse(in);
+}
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedAcc::ossimDtedAcc(istream& in,
+                           ossim_int32 offset)
+   :
+      theRecSen(),
+      theAbsoluteCE(),
+      theAbsoluteLE(),
+      theRelativeCE(),
+      theRelativeLE(),
+      theField6(),
+      theField7(),
+      theField8(),
+      theField9(),
+      theField10(),
+      theField11(),
+      theField12(),
+      theField13(),
+      theField14(),
+      theField15(),
+      theField16(),
+      theField17(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   parse(in);
+}
+
+//**************************************************************************
+// ossimDtedAcc::parse()
+//**************************************************************************
+void ossimDtedAcc::parse(istream& in)
+{
+   // Seek to the start of the record.
+   in.seekg(theStartOffset, ios::beg);
+   
+   // Parse theRecSen
+   in.read(theRecSen, FIELD1_SIZE);
+   theRecSen[FIELD1_SIZE] = '\0';
+
+   if(!(strncmp(theRecSen, "ACC", 3) == 0))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      return;
+   }
+   
+   // Parse theAbsoluteCE
+   in.read(theAbsoluteCE, FIELD2_SIZE);
+   theAbsoluteCE[FIELD2_SIZE] = '\0';
+   
+   // Parse theAbsoluteLE
+   in.read(theAbsoluteLE, FIELD3_SIZE);
+   theAbsoluteLE[FIELD3_SIZE] = '\0';
+   
+   // Parse theRelativeCE
+   in.read(theRelativeCE, FIELD4_SIZE);
+   theRelativeCE[FIELD4_SIZE] = '\0';
+   
+   // Parse theRelativeLE
+   in.read(theRelativeLE, FIELD5_SIZE);
+   theRelativeLE[FIELD5_SIZE] = '\0';
+   
+   // Parse Field 6
+   in.read(theField6, FIELD6_SIZE);
+   theField6[FIELD6_SIZE] = '\0';
+   
+   // Parse Field 7
+   in.read(theField7, FIELD7_SIZE);
+   theField7[FIELD7_SIZE] = '\0';
+   
+   // Parse Field 8
+   in.read(theField8, FIELD8_SIZE);
+   theField8[FIELD8_SIZE] = '\0';
+   
+   // Parse Field 9
+   in.read(theField9, FIELD9_SIZE);
+   theField9[FIELD9_SIZE] = '\0';
+   
+   // Parse Field 10
+   in.read(theField10, FIELD10_SIZE);
+   theField10[FIELD10_SIZE] = '\0';
+   
+   // Parse Field 11
+   in.read(theField11, FIELD11_SIZE);
+   theField11[FIELD11_SIZE] = '\0';
+   
+   // Parse Field 12
+   in.read(theField12, FIELD12_SIZE);
+   theField12[FIELD12_SIZE] = '\0';
+   
+   // Parse Field 13
+   in.read(theField13, FIELD13_SIZE);
+   theField13[FIELD13_SIZE] = '\0';
+   
+   // Parse Field 14
+   in.read(theField14, FIELD14_SIZE);
+   theField14[FIELD14_SIZE] = '\0';
+   
+   // Parse Field 15
+   in.read(theField15, FIELD15_SIZE);
+   theField15[FIELD15_SIZE] = '\0';
+   
+   // Parse Field 16
+   in.read(theField16, FIELD16_SIZE);
+   theField16[FIELD16_SIZE] = '\0';
+   
+   // Parse Field 17
+   in.read(theField17, FIELD17_SIZE);
+   theField17[FIELD17_SIZE] = '\0';
+
+   // Set the stop offset.
+   theStopOffset = theStartOffset + ACC_LENGTH;
+}
+
+ossim_int32 ossimDtedAcc::absCE() const
+{
+   return (theAbsoluteCE ? atoi(theAbsoluteCE) : 0);
+}
+
+ossim_int32 ossimDtedAcc::absLE() const
+{
+   return (theAbsoluteLE ? atoi(theAbsoluteLE) : 0);
+}
+
+ossim_int32 ossimDtedAcc::relCE() const
+{
+   return (theRelativeCE ? atoi(theRelativeCE) : 0);
+}
+
+ossim_int32 ossimDtedAcc::relLE() const
+{
+   return (theRelativeLE ? atoi(theRelativeLE) : 0);
+}
+   
+ossim_int32 ossimDtedAcc::startOffset() const
+{
+   return theStartOffset;
+}
+
+ossim_int32 ossimDtedAcc::stopOffset()  const
+{
+   return theStopOffset;
+}
+
+
+
+//**************************************************************************
+// operator <<
+//**************************************************************************
+ostream& operator<<( ostream& os, const ossimDtedAcc& acc)
+{
+   os << "\nDTED Header (ACC):"
+      << "\n-------------------------------"
+      << "\nRecoginition Sentinel: " << acc.theRecSen
+      << "\nAbsolute CE:           " << acc.theAbsoluteCE
+      << "\nAbsolute LE:           " << acc.theAbsoluteLE
+      << "\nRelative CE:           " << acc.theRelativeCE
+      << "\nRelative LE:           " << acc.theRelativeLE
+      << "\nStart Offset:          " << acc.theStartOffset
+      << "\nStop Offset:           " << acc.theStopOffset
+      << endl;
+
+   return os;
+}
+
+ossimDtedAcc::ossimDtedAcc(const ossimDtedAcc& source)
+{}
+
+const ossimDtedAcc& ossimDtedAcc::operator=(const ossimDtedAcc& rhs)
+{
+   return rhs;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedAcc.h b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedAcc.h
new file mode 100644
index 0000000000..e8d2fb41e6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedAcc.h
@@ -0,0 +1,102 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the Accuracy Description
+//               (ACC) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedAcc.h,v 1.9 2005/10/17 19:24:25 gpotts Exp $
+
+#ifndef ossimDtedAcc_H
+#define ossimDtedAcc_H
+#include <iostream>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/data_types/ossimFilename.h>
+
+
+class ossimDtedAcc : public ossimErrorStatusInterface
+{
+public:
+   ossimDtedAcc(const ossimFilename& dted_file, ossim_int32 offset);
+   ossimDtedAcc(std::istream& in, ossim_int32 offset);
+
+   enum
+   {
+      ACC_LENGTH = 2700,
+      ACC_ABSOLUTE_CE = 4,
+      ACC_ABSOLUTE_LE = 8,
+      ACC_RELATIVE_CE = 12,
+      ACC_RELATIVE_LE = 16,
+      ACC_RESERVED_1 = 20,
+      ACC_RESERVED_2 = 24,
+      ACC_RESERVED_3 = 25,
+      ACC_MULTIPLE_FLAG = 56,
+      ACC_RESERVED = 58,
+      FIELD1_SIZE           = 3,
+      FIELD2_SIZE           = 4,
+      FIELD3_SIZE           = 4,
+      FIELD4_SIZE           = 4,
+      FIELD5_SIZE           = 4,
+      FIELD6_SIZE           = 4,
+      FIELD7_SIZE           = 1,
+      FIELD8_SIZE           = 31,
+      FIELD9_SIZE           = 2,
+      FIELD10_SIZE          = 4,
+      FIELD11_SIZE          = 4,
+      FIELD12_SIZE          = 4,
+      FIELD13_SIZE          = 4,
+      FIELD14_SIZE          = 2,
+      FIELD15_SIZE          = 9,
+      FIELD16_SIZE          = 10,
+      FIELD17_SIZE          = 18,
+      FIELD18_SIZE          = 69
+   };
+
+   // The Recoginition Sentinel signifies if the ACC record exists.
+
+   ossim_int32 absCE() const;
+   ossim_int32 absLE() const;
+   ossim_int32 relCE() const;
+   ossim_int32 relLE() const;
+   
+   ossim_int32 startOffset() const;
+   ossim_int32 stopOffset()  const;
+   
+   friend std::ostream& operator<<( std::ostream& os, const ossimDtedAcc& acc);
+   void parse(std::istream& in);
+
+private:
+   // Do not allow...
+   ossimDtedAcc(const ossimDtedAcc& source);
+   const ossimDtedAcc& operator=(const ossimDtedAcc& rhs);
+
+   
+   char theRecSen[FIELD1_SIZE+1];
+   char theAbsoluteCE[FIELD2_SIZE+1];
+   char theAbsoluteLE[FIELD3_SIZE+1];
+   char theRelativeCE[FIELD4_SIZE+1];
+   char theRelativeLE[FIELD5_SIZE+1];
+   char theField6[FIELD6_SIZE+1];
+   char theField7[FIELD7_SIZE+1];
+   char theField8[FIELD8_SIZE+1];
+   char theField9[FIELD9_SIZE+1];
+   char theField10[FIELD10_SIZE+1];
+   char theField11[FIELD11_SIZE+1];
+   char theField12[FIELD12_SIZE+1];
+   char theField13[FIELD13_SIZE+1];
+   char theField14[FIELD14_SIZE+1];
+   char theField15[FIELD15_SIZE+1];
+   char theField16[FIELD16_SIZE+1];
+   char theField17[FIELD17_SIZE+1];
+   
+   ossim_int32 theStartOffset;
+   ossim_int32 theStopOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedDsi.cpp b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedDsi.cpp
new file mode 100644
index 0000000000..93f3e63ddb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedDsi.cpp
@@ -0,0 +1,553 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the Data Set Identification
+//               (DSI) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedDsi.cpp,v 1.11 2005/01/11 18:08:57 dburken Exp $
+
+#include <fstream>
+using namespace std;
+
+#include <support_data/dted/ossimDtedDsi.h>
+#include <base/context/ossimNotifyContext.h>
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedDsi::ossimDtedDsi(const ossimFilename& dted_file, ossim_int32 offset)
+   :
+      theRecSen(),
+      theSecurityCode(),
+      theField3(),
+      theField4(),
+      theProductLevel(),
+      theField7(),
+      theField8(),
+      theEdition(),
+      theMatchMergeVersion(),
+      theMaintenanceDate(),
+      theMatchMergeDate(),
+      theMaintenanceCode(),
+      theProducerCode(),
+      theField15(),
+      theProductStockSpecNumber(),
+      theProductSpecNumber(),
+      theProductSpecDate(),
+      theVerticalDatum(),
+      theHorizontalDatum(),
+      theField21(),
+      theCompilationDate(),
+      theField23(),
+      theLatOrigin(),
+      theLonOrigin(),
+      theLatSW(),
+      theLonSW(),
+      theLatNW(),
+      theLonNW(),
+      theLatNE(),
+      theLonNE(),
+      theLatSE(),
+      theLonSE(),
+      theOrientation(),
+      theLatInterval(),
+      theLonInterval(),
+      theNumLatPoints(),
+      theNumLonLines(),
+      theCellIndicator(),
+      theField40(),
+      theField41(),
+      theField42(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   // Check to see that dted file exists.
+   if(!dted_file.exists())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedDsi::ossimDtedDsi: \nThe DTED file does not exist: " << dted_file << std::endl;
+      return;
+   }
+
+   // Check to see that the dted file is readable.
+   if(!dted_file.isReadable())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedDsi::ossimDtedDsi: The DTED file is not readable: " << dted_file << std::endl;
+      return;
+   }
+   
+   // Open the dted file for reading.
+   ifstream in(dted_file.c_str());
+   if(!in)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedDsi::ossimDtedDsi: Unable to open the DTED file: " << dted_file << std::endl;
+      return;
+   }
+
+   parse(in);
+
+   in.close();
+}
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedDsi::ossimDtedDsi(istream&  in, ossim_int32 offset)
+   :
+      theRecSen(),
+      theSecurityCode(),
+      theField3(),
+      theField4(),
+      theProductLevel(),
+      theField7(),
+      theField8(),
+      theEdition(),
+      theMatchMergeVersion(),
+      theMaintenanceDate(),
+      theMatchMergeDate(),
+      theMaintenanceCode(),
+      theProducerCode(),
+      theField15(),
+      theProductStockSpecNumber(),
+      theProductSpecNumber(),
+      theProductSpecDate(),
+      theVerticalDatum(),
+      theHorizontalDatum(),
+      theField21(),
+      theCompilationDate(),
+      theField23(),
+      theLatOrigin(),
+      theLonOrigin(),
+      theLatSW(),
+      theLonSW(),
+      theLatNW(),
+      theLonNW(),
+      theLatNE(),
+      theLonNE(),
+      theLatSE(),
+      theLonSE(),
+      theOrientation(),
+      theLatInterval(),
+      theLonInterval(),
+      theNumLatPoints(),
+      theNumLonLines(),
+      theCellIndicator(),
+      theField40(),
+      theField41(),
+      theField42(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   parse(in);
+}
+
+void ossimDtedDsi::parse(istream& in)
+{
+
+   char tmp_chars[26]; // For blank field reads.
+   
+   // Seek to the start of the record.
+   in.seekg(theStartOffset, ios::beg);
+   
+   // Parse theRecSen
+   in.read(theRecSen, FIELD1_SIZE);
+   theRecSen[FIELD1_SIZE] = '\0';
+   
+   if(!(strncmp(theRecSen, "DSI", 3) == 0))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      return;
+   }
+
+   // Parse theSecurityCode
+   in.read(theSecurityCode, FIELD2_SIZE);
+   theSecurityCode[FIELD2_SIZE] = '\0';
+   
+   // Parse Field 3
+   in.read(theField3, FIELD3_SIZE);
+   theField3[FIELD3_SIZE] = '\0';
+   
+   // Parse Field 4
+   in.read(theField4, FIELD4_SIZE);
+   theField4[FIELD4_SIZE] = '\0';
+   
+   // Parse Field 5 (currently blank)
+   in.read(tmp_chars, FIELD5_SIZE);
+   
+   // Parse theProductLevel
+   in.read(theProductLevel, FIELD6_SIZE);
+   theProductLevel[FIELD6_SIZE] = '\0';
+   
+   // Parse Field 7
+   in.read(theField7, FIELD7_SIZE);
+   theField7[FIELD7_SIZE] = '\0';
+   
+   // Parse Field 8
+   in.read(theField8, FIELD8_SIZE);
+   theField8[FIELD8_SIZE] = '\0';
+   
+   // Parse theEdition
+   in.read(theEdition, FIELD9_SIZE);
+   theEdition[FIELD9_SIZE] = '\0';
+   
+   // Parse theMatchMergeVersion
+   in.read(theMatchMergeVersion, FIELD10_SIZE);
+   theMatchMergeVersion[FIELD10_SIZE] = '\0';
+   
+   // Parse theMaintenanceDate
+   in.read(theMaintenanceDate, FIELD11_SIZE);
+   theMaintenanceDate[FIELD11_SIZE] = '\0';
+   
+   // Parse theMatchMergeDate
+   in.read(theMatchMergeDate, FIELD12_SIZE);
+   theMatchMergeDate[FIELD12_SIZE] = '\0';
+   
+   // Parse theMaintenanceCode
+   in.read(theMaintenanceCode, FIELD13_SIZE);
+   theMaintenanceCode[FIELD13_SIZE] = '\0';
+   
+   // Parse theProducerCode
+   in.read(theProducerCode, FIELD14_SIZE);
+   theProducerCode[FIELD14_SIZE] = '\0';
+   
+   // Parse Field 15
+   in.read(theField15, FIELD15_SIZE);
+   theField15[FIELD15_SIZE] = '\0';
+   
+   // Parse theProductStockSpecNumber
+   in.read(theProductStockSpecNumber, FIELD16_SIZE);
+   theProductStockSpecNumber[FIELD16_SIZE] = '\0';
+   
+   // Parse theProductSpecNumber
+   in.read(theProductSpecNumber, FIELD17_SIZE);
+   theProductSpecNumber[FIELD17_SIZE] = '\0';
+   
+   // Parse theProductSpecDate
+   in.read(theProductSpecDate, FIELD18_SIZE);
+   theProductSpecDate[FIELD18_SIZE] = '\0';
+   
+   // Parse theVerticalDatum
+   in.read(theVerticalDatum, FIELD19_SIZE);
+   theVerticalDatum[FIELD19_SIZE] = '\0';
+   
+   // Parse theHorizontalDatum
+   in.read(theHorizontalDatum, FIELD20_SIZE);
+   theHorizontalDatum[FIELD20_SIZE] = '\0';
+   
+   // Parse Field 21
+   in.read(theField21, FIELD21_SIZE);
+   theField21[FIELD21_SIZE] = '\0';
+   
+   // Parse theCompilationDate
+   in.read(theCompilationDate, FIELD22_SIZE);
+   theCompilationDate[FIELD22_SIZE] = '\0';
+   
+   // Parse Field 23
+   in.read(theField23, FIELD23_SIZE);
+   theField23[FIELD23_SIZE] = '\0';
+   
+   // Parse theLatOrigin
+   in.read(theLatOrigin, FIELD24_SIZE);
+   theLatOrigin[FIELD24_SIZE] = '\0';
+   
+   // Parse theLonOrigin
+   in.read(theLonOrigin, FIELD25_SIZE);
+   theLonOrigin[FIELD25_SIZE] = '\0';
+   
+   // Parse theLatSW
+   in.read(theLatSW, FIELD26_SIZE);
+   theLatSW[FIELD26_SIZE] = '\0';
+   
+   // Parse theLonSW
+   in.read(theLonSW, FIELD27_SIZE);
+   theLonSW[FIELD27_SIZE] = '\0';
+   
+   // Parse theLatNW
+   in.read(theLatNW, FIELD28_SIZE);
+   theLatNW[FIELD28_SIZE] = '\0';
+   
+   // Parse theLonNW
+   in.read(theLonNW, FIELD29_SIZE);
+   theLonNW[FIELD29_SIZE] = '\0';
+   
+   // Parse theLatNE
+   in.read(theLatNE, FIELD30_SIZE);
+   theLatNE[FIELD30_SIZE] = '\0';
+   
+   // Parse theLonNE
+   in.read(theLonNE, FIELD31_SIZE);
+   theLonNE[FIELD31_SIZE] = '\0';
+   
+   // Parse theLatSE
+   in.read(theLatSE, FIELD32_SIZE);
+   theLatSE[FIELD32_SIZE] = '\0';
+   
+   // Parse theLonSE
+   in.read(theLonSE, FIELD33_SIZE);
+   theLonSE[FIELD33_SIZE] = '\0';
+   
+   // Parse theOrientation
+   in.read(theOrientation, FIELD34_SIZE);
+   theOrientation[FIELD34_SIZE] = '\0';
+   
+   // Parse theLatInterval
+   in.read(theLatInterval, FIELD35_SIZE);
+   theLatInterval[FIELD35_SIZE] = '\0';
+   
+   // Parse theLonInterval
+   in.read(theLonInterval, FIELD36_SIZE);
+   theLonInterval[FIELD36_SIZE] = '\0';
+   
+   // Parse theNumLatPoints
+   in.read(theNumLatPoints, FIELD37_SIZE);
+   theNumLatPoints[FIELD37_SIZE] = '\0';
+   
+   // Parse theNumLonLines
+   in.read(theNumLonLines, FIELD38_SIZE);
+   theNumLonLines[FIELD38_SIZE] = '\0';
+   
+   // Parse theCellIndicator
+   in.read(theCellIndicator, FIELD39_SIZE);
+   theCellIndicator[FIELD39_SIZE] = '\0';
+   
+   // Parse Field 40
+   in.read(theField40, FIELD40_SIZE);
+   theField40[FIELD40_SIZE] = '\0';
+   
+   // Parse Field 41
+   in.read(theField41, FIELD41_SIZE);
+   theField41[FIELD41_SIZE] = '\0';
+   
+   // Parse Field 42
+   in.read(theField42, FIELD42_SIZE);
+   theField42[FIELD42_SIZE] = '\0';
+
+   // Set the stop offset.
+   theStopOffset = theStartOffset + DSI_LENGTH;
+}
+
+ossimString ossimDtedDsi::recoginitionSentinel() const
+{
+   return theRecSen;
+}
+
+ossimString ossimDtedDsi::securityCode() const
+{
+   return ossimString(theSecurityCode);
+}
+
+ossimString ossimDtedDsi::productLevel() const
+{
+   return ossimString(theProductLevel);
+}
+
+ossimString ossimDtedDsi::edition() const
+{
+   return ossimString(theEdition);
+}
+
+ossimString ossimDtedDsi::matchMergeVersion() const
+{
+   return ossimString(theMatchMergeVersion);
+}
+
+ossimString ossimDtedDsi::maintanenceDate() const
+{
+   return ossimString(theMaintenanceDate);
+}
+
+ossimString ossimDtedDsi::matchMergeDate() const
+{
+   return ossimString(theMatchMergeDate);
+}
+
+ossimString ossimDtedDsi::maintenanceCode() const
+{
+   return ossimString(theMaintenanceCode);
+}
+
+ossimString ossimDtedDsi::producerCode() const
+{
+   return ossimString(theProducerCode);
+}
+
+ossimString ossimDtedDsi::productStockSpecNumber() const
+{
+   return ossimString(theProductStockSpecNumber);
+}
+
+ossimString ossimDtedDsi::productSpecNumber() const
+{
+   return ossimString(theProductSpecNumber);
+}
+
+ossimString ossimDtedDsi::productSpecDate() const
+{
+   return ossimString(theProductSpecDate);
+}
+
+ossimString ossimDtedDsi::verticalDatum() const
+{
+   return ossimString(theVerticalDatum);
+}
+
+ossimString ossimDtedDsi::horizontalDatum() const
+{
+   return ossimString(theHorizontalDatum);
+}
+
+ossimString ossimDtedDsi::compilationDate() const
+{
+   return ossimString(theCompilationDate);
+}
+
+ossimString ossimDtedDsi::latOrigin() const
+{
+   return ossimString(theLatOrigin);
+}
+
+ossimString ossimDtedDsi::lonOrigin() const
+{
+   return ossimString(theLonOrigin);
+}
+
+ossimString ossimDtedDsi::latSW() const
+{
+   return ossimString(theLatSW);
+}
+
+ossimString ossimDtedDsi::lonSW() const
+{
+   return ossimString(theLonSW);
+}
+
+ossimString ossimDtedDsi::latNW() const
+{
+   return ossimString(theLatNW);
+}
+
+ossimString ossimDtedDsi::lonNW() const
+{
+   return ossimString(theLonNW);
+}
+
+ossimString ossimDtedDsi::latNE() const
+{
+   return ossimString(theLatNE);
+}
+
+ossimString ossimDtedDsi::lonNE() const
+{
+   return ossimString(theLonNE);
+}
+
+ossimString ossimDtedDsi::latSE() const
+{
+   return ossimString(theLatSE);
+}
+
+ossimString ossimDtedDsi::lonSE() const
+{
+   return ossimString(theLonSE);
+}
+
+ossimString ossimDtedDsi::orientation() const
+{
+   return ossimString(theOrientation);
+}
+
+ossimString ossimDtedDsi::latInterval() const
+{
+   return ossimString(theLatInterval);
+}
+
+ossimString ossimDtedDsi::lonInterval() const
+{
+   return ossimString(theLonInterval);
+}
+
+ossim_int32  ossimDtedDsi::numLatPoints() const
+{
+   return (theNumLatPoints ? atoi(theNumLatPoints) : 0);
+}
+
+ossim_int32  ossimDtedDsi::numLonLines() const
+{
+   return (theNumLonLines ? atoi(theNumLonLines) : 0);
+}
+
+ossim_int32  ossimDtedDsi::cellIndicator() const
+{
+   return (theCellIndicator ? atoi(theCellIndicator) : 0);
+}
+
+ossim_int32 ossimDtedDsi::startOffset() const
+{
+   return theStartOffset;
+}
+ossim_int32 ossimDtedDsi::stopOffset() const
+{
+   return theStopOffset;
+}
+
+
+//**************************************************************************
+// operator <<
+//**************************************************************************
+ostream& operator<<( ostream& os, const ossimDtedDsi& dsi)
+{
+   os << "\nDTED Header (DSI):"
+      << "\n-------------------------------"
+      << "\nRecoginition Sentinel:     " << dsi.theRecSen
+      << "\nSecurity Code:             " << dsi.theSecurityCode
+      << "\nProduct Level:             " << dsi.theProductLevel
+      << "\nEdition:                   " << dsi.theEdition
+      << "\nMatch/Merge Version:       " << dsi.theMatchMergeVersion
+      << "\nMaintenance Date:          " << dsi.theMaintenanceDate
+      << "\nMatch/Merge Date:          " << dsi.theMatchMergeDate
+      << "\nMaintenance Code:          " << dsi.theMaintenanceCode
+      << "\nProducer Code:             " << dsi.theProducerCode
+      << "\nProduct Stock Spec Number: " << dsi.theProductStockSpecNumber
+      << "\nProduct Spec Number:       " << dsi.theProductSpecNumber
+      << "\nVertical Datum:            " << dsi.theVerticalDatum
+      << "\nHorizontal Datum:          " << dsi.theHorizontalDatum
+      << "\nCompilation Date:          " << dsi.theCompilationDate
+      << "\nLat Origin:                " << dsi.theLatOrigin
+      << "\nLon Origin:                " << dsi.theLonOrigin
+      << "\nLat SW:                    " << dsi.theLatSW
+      << "\nLon SW:                    " << dsi.theLonSW
+      << "\nLat NW:                    " << dsi.theLatNW
+      << "\nLon NW:                    " << dsi.theLonNW
+      << "\nLat NE:                    " << dsi.theLatNE
+      << "\nLon NE:                    " << dsi.theLonNE
+      << "\nLat SE:                    " << dsi.theLatSE
+      << "\nLon SE:                    " << dsi.theLonSE
+      << "\nOrientation:               " << dsi.theOrientation
+      << "\nLat Interval:              " << dsi.theLatInterval
+      << "\nLon Interval:              " << dsi.theLonInterval
+      << "\nNumber of Lat Points:      " << dsi.theNumLatPoints
+      << "\nNumber of Lon Lines:       " << dsi.theNumLonLines
+      << "\nCell Indicator:            " << dsi.theCellIndicator
+      << "\nStart Offset:              " << dsi.theStartOffset
+      << "\nStop Offset:               " << dsi.theStopOffset
+      << endl;
+
+   return os;
+}
+
+ossimDtedDsi::ossimDtedDsi(const ossimDtedDsi& source)
+{}
+
+const ossimDtedDsi& ossimDtedDsi::operator=(const ossimDtedDsi& rhs)
+{
+   return rhs;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedDsi.h b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedDsi.h
new file mode 100644
index 0000000000..0c3394eba4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedDsi.h
@@ -0,0 +1,207 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the Data Set Identification
+//               (DSI) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedDsi.h,v 1.10 2005/10/17 19:24:25 gpotts Exp $
+
+#ifndef ossimDtedDsi_H
+#define ossimDtedDsi_H
+#include <iostream>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/data_types/ossimFilename.h>
+
+class ossimDtedDsi : public ossimErrorStatusInterface
+{
+public:
+   ossimDtedDsi(const ossimFilename& dted_file, ossim_int32 offset);
+   ossimDtedDsi(std::istream& in, ossim_int32 offset);
+
+   enum
+   {
+      DSI_LENGTH = 648,
+      DSI_SECURITY_CODE = 4,
+      DSI_SECURITY_CONTROL = 5,
+      DSI_SECURITY_HANDLING = 7,
+      DSI_RESERVED_1 = 34,
+      DSI_DMA_SERIES = 60,
+      DSI_RESERVED_2 = 65,
+      DSI_RESERVED_3 = 80,
+      DSI_DATA_EDITION = 88,
+      DSI_MATCH_MERGE_VERSION = 90,
+      DSI_MAINTENANCE_DATE = 91,
+      DSI_MATCH_MERGE_DATE = 95,
+      DSI_MAINTENANCE_CODE = 99,
+      DSI_PRODUCER_CODE = 103,
+      DSI_RESERVED_4 = 111,
+      DSI_PRODUCT_SPEC_STOCK_NUMBER = 127, 
+      DSI_PRODUCT_SPEC_NUMBER = 136,
+      DSI_PRODUCT_SPEC_DATE = 138,
+      DSI_VERTICAL_DATUM = 142,
+      DSI_HORIZ_DATUM = 145,
+      DSI_DIGITIZING_SYSTEM = 150,
+      DSI_COMPILATION_DATE = 160,
+      DSI_RESERVED_5 = 164,
+      DSI_LAT_ORIGIN = 186,
+      DSI_LON_ORIGIN = 195,
+      DSI_LAT_SW = 205,
+      DSI_LON_SW = 212,
+      DSI_LAT_NW = 220,
+      DSI_LON_NW = 227,
+      DSI_LAT_NE = 235,
+      DSI_LON_NE = 242,
+      DSI_LAT_SE = 250,
+      DSI_LON_SE = 257,
+      DSI_ORIENTATION = 265,
+      DSI_LAT_INTERVAL = 274,
+      DSI_LON_INTERVAL = 278,
+      DSI_NUM_LAT_LINES = 282,
+      DSI_NUM_LON_LINES = 286,
+      DSI_PARTIAL_CELL_INDICATOR = 290,
+      DSI_RESERVED = 292,
+      FIELD1_SIZE           = 3,
+      FIELD2_SIZE           = 1,
+      FIELD3_SIZE           = 2,
+      FIELD4_SIZE           = 27,
+      FIELD5_SIZE           = 26,
+      FIELD6_SIZE           = 5,
+      FIELD7_SIZE           = 15,
+      FIELD8_SIZE           = 8,
+      FIELD9_SIZE           = 2,
+      FIELD10_SIZE          = 1,
+      FIELD11_SIZE          = 4,
+      FIELD12_SIZE          = 4,
+      FIELD13_SIZE          = 4,
+      FIELD14_SIZE          = 8,
+      FIELD15_SIZE          = 16,
+      FIELD16_SIZE          = 9,
+      FIELD17_SIZE          = 2,
+      FIELD18_SIZE          = 4,
+      FIELD19_SIZE          = 3,
+      FIELD20_SIZE          = 5,
+      FIELD21_SIZE          = 10,
+      FIELD22_SIZE          = 4,
+      FIELD23_SIZE          = 22,
+      FIELD24_SIZE          = 9,
+      FIELD25_SIZE          = 10,
+      FIELD26_SIZE          = 7,
+      FIELD27_SIZE          = 8,
+      FIELD28_SIZE          = 7,
+      FIELD29_SIZE          = 8,
+      FIELD30_SIZE          = 7,
+      FIELD31_SIZE          = 8,
+      FIELD32_SIZE          = 7,
+      FIELD33_SIZE          = 8,
+      FIELD34_SIZE          = 9,
+      FIELD35_SIZE          = 4,
+      FIELD36_SIZE          = 4,
+      FIELD37_SIZE          = 4,
+      FIELD38_SIZE          = 4,
+      FIELD39_SIZE          = 2,
+      FIELD40_SIZE          = 101,
+      FIELD41_SIZE          = 100,
+      FIELD42_SIZE          = 156
+   };
+
+   // The Recoginition Sentinel signifies if the DSI record exists.
+   ossimString recoginitionSentinel() const;
+
+   ossimString securityCode()           const;
+   ossimString productLevel()           const;
+   ossimString edition()                const;
+   ossimString matchMergeVersion()      const;
+   ossimString maintanenceDate()        const;
+   ossimString matchMergeDate()         const;
+   ossimString maintenanceCode()        const;
+   ossimString producerCode()           const;
+   ossimString productStockSpecNumber() const;
+   ossimString productSpecNumber()      const;
+   ossimString productSpecDate()        const;
+   ossimString verticalDatum()          const;
+   ossimString horizontalDatum()        const;
+   ossimString compilationDate()        const;
+   ossimString latOrigin()              const;
+   ossimString lonOrigin()              const;
+   ossimString latSW()                  const;
+   ossimString lonSW()                  const;
+   ossimString latNW()                  const;
+   ossimString lonNW()                  const;
+   ossimString latNE()                  const;
+   ossimString lonNE()                  const;
+   ossimString latSE()                  const;
+   ossimString lonSE()                  const;
+
+   ossimString orientation()    const;
+   ossimString latInterval()    const;
+   ossimString lonInterval()    const;
+   ossim_int32 numLatPoints()   const;
+   ossim_int32 numLonLines()    const;
+   ossim_int32 cellIndicator()  const;
+   ossim_int32 startOffset()    const;
+   ossim_int32 stopOffset()     const;
+   
+   friend std::ostream& operator<<( std::ostream& os, const ossimDtedDsi& dsi);
+   
+   void parse(std::istream& in);
+
+private:
+   // Do not allow...
+   ossimDtedDsi(const ossimDtedDsi& source);
+   const ossimDtedDsi& operator=(const ossimDtedDsi& rhs);
+
+   
+   char theRecSen[FIELD1_SIZE+1];
+   char theSecurityCode[FIELD2_SIZE+1];
+   char theField3[FIELD3_SIZE+1];
+   char theField4[FIELD4_SIZE+1];
+   char theProductLevel[FIELD6_SIZE+1];
+   char theField7[FIELD7_SIZE+1];
+   char theField8[FIELD8_SIZE+1];
+   char theEdition[FIELD9_SIZE+1];
+   char theMatchMergeVersion[FIELD10_SIZE+1];
+   char theMaintenanceDate[FIELD11_SIZE+1];
+   char theMatchMergeDate[FIELD12_SIZE+1];
+   char theMaintenanceCode[FIELD13_SIZE+1];
+   char theProducerCode[FIELD14_SIZE+1];
+   char theField15[FIELD15_SIZE+1];
+   char theProductStockSpecNumber[FIELD16_SIZE+1];
+   char theProductSpecNumber[FIELD17_SIZE+1];
+   char theProductSpecDate[FIELD18_SIZE+1];
+   char theVerticalDatum[FIELD19_SIZE+1];
+   char theHorizontalDatum[FIELD20_SIZE+1];
+   char theField21[FIELD21_SIZE+1];
+   char theCompilationDate[FIELD22_SIZE+1];
+   char theField23[FIELD23_SIZE+1];
+   char theLatOrigin[FIELD24_SIZE+1];
+   char theLonOrigin[FIELD25_SIZE+1];
+   char theLatSW[FIELD26_SIZE+1];
+   char theLonSW[FIELD27_SIZE+1];
+   char theLatNW[FIELD28_SIZE+1];
+   char theLonNW[FIELD29_SIZE+1];
+   char theLatNE[FIELD30_SIZE+1];
+   char theLonNE[FIELD31_SIZE+1];
+   char theLatSE[FIELD32_SIZE+1];
+   char theLonSE[FIELD33_SIZE+1];
+   char theOrientation[FIELD34_SIZE+1];
+   char theLatInterval[FIELD35_SIZE+1];
+   char theLonInterval[FIELD36_SIZE+1];
+   char theNumLatPoints[FIELD37_SIZE+1];
+   char theNumLonLines[FIELD38_SIZE+1];
+   char theCellIndicator[FIELD39_SIZE+1];
+   char theField40[FIELD40_SIZE+1];
+   char theField41[FIELD41_SIZE+1];
+   char theField42[FIELD42_SIZE+1];
+   
+   ossim_int32       theStartOffset;
+   ossim_int32       theStopOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedHdr.cpp b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedHdr.cpp
new file mode 100644
index 0000000000..dcde1ef0c7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedHdr.cpp
@@ -0,0 +1,234 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the File Header Label
+//               (HDR) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedHdr.cpp,v 1.11 2005/01/11 18:08:57 dburken Exp $
+
+#include <fstream>
+using namespace std;
+
+#include <support_data/dted/ossimDtedHdr.h>
+#include <base/context/ossimNotifyContext.h>
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedHdr::ossimDtedHdr(const ossimFilename& dted_file, ossim_int32 offset)
+   :
+      theRecSen(),
+      theField2(),
+      theFilename(),
+      theField4(),
+      theField5(),
+      theField6(),
+      theVersion(),
+      theCreationDate(),
+      theField9(),
+      theField10(),
+      theField11(),
+      theField12(),
+      theField13(),
+      theField14(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   // Check to see that dted file exists.
+   if(!dted_file.exists())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedHdr::ossimDtedHdr: The DTED file does not exist: " << dted_file << std::endl;
+      return;
+   }
+
+   // Check to see that the dted file is readable.
+   if(!dted_file.isReadable())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedHdr::ossimDtedHdr: The DTED file is not readable: " << dted_file << std::endl;
+      return;
+   }
+
+   ifstream in(dted_file.c_str());
+   // Open the dted file for reading.
+   if(!in)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedHdr::ossimDtedHdr: Error opening the DTED file: " << dted_file << std::endl;
+      return;
+   }
+
+   // Continue parsing all the record fields.
+   parse(in);
+
+   in.close();
+}
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedHdr::ossimDtedHdr(istream& in, ossim_int32 offset)
+   :
+      theRecSen(),
+      theField2(),
+      theFilename(),
+      theField4(),
+      theField5(),
+      theField6(),
+      theVersion(),
+      theCreationDate(),
+      theField9(),
+      theField10(),
+      theField11(),
+      theField12(),
+      theField13(),
+      theField14(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   parse(in);
+}
+
+//**************************************************************************
+// ossimDtedHdr::parse()
+//**************************************************************************
+void ossimDtedHdr::parse(istream& in)
+{
+   // Seek to the start of the record.
+   in.seekg(theStartOffset, ios::beg);
+   
+   // Parse theRecSen
+   in.read(theRecSen, FIELD1_SIZE);
+   theRecSen[FIELD1_SIZE] = '\0';
+
+   if(!(strncmp(theRecSen, "HDR", 3) == 0))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      return;
+   }
+   
+   // Parse Field 2
+   in.read(theField2, FIELD2_SIZE);
+   theField2[FIELD2_SIZE] = '\0';
+   
+   // Parse theFilename
+   in.read(theFilename, FIELD3_SIZE);
+   theFilename[FIELD3_SIZE] = '\0';
+   
+   // Parse Field 4
+   in.read(theField4, FIELD4_SIZE);
+   theField4[FIELD4_SIZE] = '\0';
+   
+   // Parse Field 5
+   in.read(theField5, FIELD5_SIZE);
+   theField5[FIELD5_SIZE] = '\0';
+   
+   // Parse Field 6
+   in.read(theField6, FIELD6_SIZE);
+   theField6[FIELD6_SIZE] = '\0';
+   
+   // Parse Field 7
+   in.read(theVersion, FIELD7_SIZE);
+   theVersion[FIELD7_SIZE] = '\0';
+   
+   // Parse theCreationDate
+   in.read(theCreationDate, FIELD8_SIZE);
+   theCreationDate[FIELD8_SIZE] = '\0';
+   
+   // Parse Field 9
+   in.read(theField9, FIELD9_SIZE);
+   theField9[FIELD9_SIZE] = '\0';   
+   
+   // Parse Field 10
+   in.read(theField10, FIELD10_SIZE);
+   theField10[FIELD10_SIZE] = '\0';   
+   
+   // Parse Field 11
+   in.read(theField11, FIELD11_SIZE);
+   theField11[FIELD11_SIZE] = '\0';   
+   
+   // Parse Field 12
+   in.read(theField12, FIELD12_SIZE);
+   theField12[FIELD12_SIZE] = '\0';   
+   
+   // Parse Field 13
+   in.read(theField13, FIELD13_SIZE);
+   theField13[FIELD13_SIZE] = '\0';   
+   
+   // Parse Field 14
+   in.read(theField14, FIELD14_SIZE);
+   theField14[FIELD14_SIZE] = '\0';
+
+   // Set the stop offset.
+   theStopOffset = theStartOffset + HDR_LENGTH;
+}
+
+//**************************************************************************
+// operator <<
+//**************************************************************************
+ostream& operator<<( ostream& os, const ossimDtedHdr& hdr)
+{
+   os << "\nDTED Header (VOL):"
+      << "\n-------------------------------"
+      << "\ntheRecSen:             " << hdr.theRecSen
+      << "\nField 2:               " << hdr.theField2
+      << "\ntheFilename:           " << hdr.theFilename
+      << "\nField 4:               " << hdr.theField4
+      << "\nField 5:               " << hdr.theField5
+      << "\nField 6:               " << hdr.theField6
+      << "\nVersion:               " << hdr.theVersion
+      << "\ntheCreationDate:       " << hdr.theCreationDate
+      << "\nField 9:               " << hdr.theField9
+      << "\nField 10:              " << hdr.theField10
+      << "\nField 11:              " << hdr.theField11
+      << "\nField 12:              " << hdr.theField12
+      << "\nField 13:              " << hdr.theField13
+      << "\nField 14:              " << hdr.theField14
+      << endl;
+   
+   return os;
+}
+
+ossimString ossimDtedHdr::recoginitionSentinel() const
+{
+   return theRecSen;
+}
+
+ossimString ossimDtedHdr::fileName() const
+{
+   return theFilename;
+}
+ossimString ossimDtedHdr::version() const
+{ return theVersion;
+}
+
+ossimString ossimDtedHdr::creationDate() const
+{
+   return theCreationDate;
+}
+
+ossim_int32 ossimDtedHdr::startOffset() const
+{
+   return theStartOffset;
+}
+
+ossim_int32 ossimDtedHdr::stopOffset() const
+{
+   return theStopOffset;
+}
+
+ossimDtedHdr::ossimDtedHdr(const ossimDtedHdr& source)
+{}
+
+const ossimDtedHdr& ossimDtedHdr::operator=(const ossimDtedHdr& rhs)
+{
+   return rhs;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedHdr.h b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedHdr.h
new file mode 100644
index 0000000000..84cdb757db
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedHdr.h
@@ -0,0 +1,97 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the File Header Label
+//               (HDR) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedHdr.h,v 1.9 2005/10/17 19:24:25 gpotts Exp $
+
+#ifndef DtedHdr_H
+#define DtedHdr_H
+#include <iostream>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/data_types/ossimFilename.h>
+
+class ossimDtedHdr : public ossimErrorStatusInterface
+{
+public:
+   ossimDtedHdr(const ossimFilename& dted_file, ossim_int32 offset);
+   ossimDtedHdr(std::istream& in, ossim_int32 offset);
+
+   enum
+   {
+      HDR_LENGTH            = 80,
+      HDR_ONE_LABEL_1       =  4,
+      HDR_FILENAME          =  5,
+      HDR_UNIVAC            = 22,
+      HDR_REEL              = 28,
+      HDR_FILE_NUM          = 32,
+      HDR_GENERATION_NUM    = 36,
+      HDR_VERSION_NUM       = 40,
+      HDR_CREATION_DATE     = 42,
+      HDR_EXPIRATION_DATE   = 48,
+      HDR_ACCESS            = 54,
+      HDR_BLOCK_COUNT       = 55,
+      HDR_QUALIFIER         = 61,
+      HDR_BLANKS            = 74,
+      FIELD1_SIZE           = 3,
+      FIELD2_SIZE           = 1,
+      FIELD3_SIZE           = 17,
+      FIELD4_SIZE           = 6,
+      FIELD5_SIZE           = 4,
+      FIELD6_SIZE           = 4,
+      FIELD7_SIZE           = 4,
+      FIELD8_SIZE           = 2,
+      FIELD9_SIZE           = 6,
+      FIELD10_SIZE          = 6,
+      FIELD11_SIZE          = 1,
+      FIELD12_SIZE          = 6,
+      FIELD13_SIZE          = 13,
+      FIELD14_SIZE          = 7
+   };
+
+   // The Recoginition Sentinel signifies if the HDR record exists.
+   ossimString recoginitionSentinel() const;
+
+   ossimString fileName()     const;
+   ossimString version()      const;
+   ossimString creationDate() const;
+   ossim_int32 startOffset()  const;
+   ossim_int32 stopOffset()   const;
+
+   friend std::ostream& operator<<( std::ostream& os, const ossimDtedHdr& hdr);
+
+   void parse(std::istream& in);
+
+private:
+   // Do not allow...
+   ossimDtedHdr(const ossimDtedHdr& source);
+   const ossimDtedHdr& operator=(const ossimDtedHdr& rhs);
+   
+   char theRecSen[FIELD1_SIZE+1];
+   char theField2[FIELD2_SIZE+1];
+   char theFilename[FIELD3_SIZE+1];
+   char theField4[FIELD4_SIZE+1];
+   char theField5[FIELD5_SIZE+1];
+   char theField6[FIELD6_SIZE+1];
+   char theVersion[FIELD7_SIZE+1];
+   char theCreationDate[FIELD8_SIZE+1];
+   char theField9[FIELD9_SIZE+1];
+   char theField10[FIELD10_SIZE+1];
+   char theField11[FIELD11_SIZE+1];
+   char theField12[FIELD12_SIZE+1];
+   char theField13[FIELD13_SIZE+1];
+   char theField14[FIELD14_SIZE+1];
+   
+   ossim_int32 theStartOffset;
+   ossim_int32 theStopOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedRecord.cpp b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedRecord.cpp
new file mode 100644
index 0000000000..f34bb26ea0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedRecord.cpp
@@ -0,0 +1,323 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the Data Record Description
+//               of a DTED Level 1 file.
+//
+// Notes:  Each elevation is a true value referenced to meas sea level
+//         (MSL) datum recorded to the nearest meter.  The horizontal
+//         position is referenced to precise longitude-latitiude
+//         locations in terms of the current World Geodetic System
+//         (WGS84) determined for each file by reference to the origin
+//         at the southwest corner.  The elevations are evenly spaced
+//         in latitude and longitude at the interval designated in the
+//         User Header Label (UHL) in South to North profile sequence.
+//
+//********************************************************************
+// $Id: ossimDtedRecord.cpp,v 1.16 2005/01/11 18:08:57 dburken Exp $
+
+#include <iostream>
+using namespace std;
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <support_data/dted/ossimDtedRecord.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/misc/ossimEndian.h>
+#include <base/context/ossimNotifyContext.h>
+
+static const ossim_uint16 DATA_NULL_VALUE = 0xffff; // -32767
+static const ossim_uint16 DATA_MIN_VALUE  = 0xfffe; // -32766
+static const ossim_uint16 DATA_MAX_VALUE  = 0x7fff; // +32767
+static const ossim_uint16 DATA_VALUE_MASK = 0x7fff; // 0111 1111 1111 1111
+static const ossim_uint16 DATA_SIGN_MASK  = 0x8000; // 1000 0000 0000 0000
+static const ossim_uint16 DATA_RECOGNITION_SENTINEL = 0xAA;  // 170
+
+//***
+// Offsets from start of data record (one record per longitude line):
+//***
+static const int BLOCK_COUNT_OFFSET = 2;
+static const int LON_INDEX_OFFSET   = 4;
+static const int LAT_INDEX_OFFSET   = 6;
+static const int ELEV_DATA_OFFSET   = 8;
+static const int RECORD_HDR_LENGTH  = 12;
+static const int BYTES_PER_POINT    = 2;
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedRecord::ossimDtedRecord(istream& in,
+                                 ossim_int32 offset,
+                                 ossim_int32 num_points)
+   :
+      theRecSen("170"),
+      theDataBlockCount(0),
+      theLonCount(0),
+      theLatCount(0),
+      theCheckSum(0),
+      thePoints(new ossim_int32[num_points]),
+      thePointsData(new ossim_uint16[num_points]),
+      theComputedCheckSum(0),
+      theNumPoints(num_points),
+      theStartOffset(offset),
+      theStopOffset(offset + RECORD_HDR_LENGTH + (num_points*BYTES_PER_POINT))
+{
+   // Verify we are at a cell record by checking the Recognition Sentinel.
+   ossim_uint8 buf[1];
+   in.seekg(theStartOffset, ios::beg);
+   in.read((char*)buf, 1);
+ 
+#if 0
+   printf("\nBuf: %02X", (int)buf[0]);  // Display in HEX
+#endif
+   
+   if(!(buf[0] = DATA_RECOGNITION_SENTINEL))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedRecord::ossimDtedRecord: reading DTED's data record at: " << theStartOffset
+                                          << std::endl;
+      return;
+   }
+
+   // Valid data record, so let's process on.
+   parse(in);
+
+
+   //***
+   // Note:  The validateCheckSum method works; however, our in-house
+   //        dted has bad stored check sums even though the post are good.
+   //        So this in temporarily shut off.
+   //***
+   // Verify Check Sum for uncorrupted elevation data.
+   if(validateCheckSum(in))
+   {
+      //***
+      // Note:  The validateCheckSum method works; however, our in-house
+      //        dted has bad stored check sums even though the posts are good.
+      //        So this in temporarily shut off.
+      //***
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimDtedRecord::ossimDtedRecord:"
+         << "\nInvalid checksum in data record at: "
+         << theStartOffset
+         << "\nParsed Check Sum = " << theCheckSum
+         << "\nComputed Check Sum = " << theComputedCheckSum
+         << "\nDTED Level 1 Elevation File is considered corrupted."
+         << std::endl;
+      return;
+   }
+}
+
+ossimDtedRecord::~ossimDtedRecord()
+{
+   if (thePoints)
+   {
+      delete [] thePoints;
+      thePoints = NULL;
+   }
+   if (thePointsData)
+   {
+      delete [] thePointsData;
+      thePointsData = NULL;
+   }
+}
+
+//**************************************************************************
+// parse()
+//**************************************************************************
+void ossimDtedRecord::parse(istream& in)
+{
+   // DTED is stored in big endian byte order so swap the bytes if needed.
+   bool swap_bytes = ossimGetByteOrder() == OSSIM_LITTLE_ENDIAN ? true : false;
+   
+   ossim_sint16 s;
+   
+   // parse data block count
+   in.seekg(theStartOffset + BLOCK_COUNT_OFFSET, ios::beg);
+   in.read((char*)&s, 2);
+   theDataBlockCount = (swap_bytes ? ( (s << 8) | (s >> 8) ) : s);
+   
+   // parse lon count
+   in.seekg(theStartOffset + LON_INDEX_OFFSET, ios::beg);
+   in.read((char*)&s, 2);
+   theLonCount = (swap_bytes ? ( (s << 8) | (s >> 8) ) : s);
+   
+   // parse lat count
+   in.seekg(theStartOffset + LAT_INDEX_OFFSET, ios::beg);
+   in.read((char*)&s, 2);
+   theLatCount = (swap_bytes ? ( (s << 8) | (s >> 8) ) : s);
+   
+   // Parse all elevation points.
+   in.seekg(theStartOffset + ELEV_DATA_OFFSET, ios::beg);
+   int i = 0;
+   for(i = 0; i < theNumPoints; i++)
+   {
+      in.read((char*)&s, 2);
+      s = (swap_bytes ? ( (s << 8) | (s >> 8) ) : s);
+      if (s & DATA_SIGN_MASK) s = (s & DATA_VALUE_MASK) * -1;
+      ossim_int32 value = convert(s);
+
+      // Check to make sure value is within valid limits for a value.
+      if(value == OSSIM_NAN)
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimDtedRecord::parse: Null Value found at point index: " << i
+                                            << ", continuing..." << std::endl;
+      }
+
+      thePoints[i] = value;
+      thePointsData[i] = s;
+   }
+}
+
+//**************************************************************************
+// validateCheckSum()
+//**************************************************************************
+ossim_int32 ossimDtedRecord::validateCheckSum(istream& in)
+{
+   // DTED is stored in big endian byte order so swap the bytes if needed.
+   bool swap_bytes = ossimGetByteOrder() == OSSIM_LITTLE_ENDIAN ? true : false;
+   
+   // Compute the check sum.
+   in.seekg(theStartOffset, ios::beg);
+   theComputedCheckSum = 0;
+   ossim_int32 bytesToRead = (theNumPoints * 2) + ELEV_DATA_OFFSET;
+   int i = 0;
+   
+   for(i = 0; i < bytesToRead; i++)
+   {
+      ossim_uint8 c;
+      in.read((char*)&c, 1);
+      theComputedCheckSum += static_cast<ossim_uint32>(c);
+   }   
+
+   // Read the stored check sum and swap the byte if needed.
+   in.read((char*)&theCheckSum, 4); 
+   if (swap_bytes)
+   {
+      ossimEndian swapper;
+      swapper.swap(theCheckSum);
+   }
+   
+   // Compare computed and parsed checksums.
+   if(theCheckSum != theComputedCheckSum)
+      return TRUE;
+   else
+      return FALSE;
+}
+
+//**************************************************************************
+// convert(ossim_uint16 val)
+//**************************************************************************
+ossim_int32 ossimDtedRecord::convert(ossim_sint16 val)
+{
+   if(val == -32767) // Null value.
+         return static_cast<ossim_int32>(OSSIM_INT_NAN);
+   else
+       return static_cast<ossim_int32>(val);
+}
+
+ossimString ossimDtedRecord::recoginitionSentinel() const
+{
+   return theRecSen;
+}
+
+ossim_int32 ossimDtedRecord::dataBlockCount() const
+{
+   return theDataBlockCount;
+}
+
+ossim_int32 ossimDtedRecord::lonCount() const
+{
+   return theLonCount;
+}
+
+ossim_int32 ossimDtedRecord::latCount() const
+{
+   return theLatCount;
+}
+
+ossim_uint32 ossimDtedRecord::checkSum() const
+{
+   return theCheckSum;
+}
+
+ossim_uint32 ossimDtedRecord::computedCheckSum() const
+{
+   return theComputedCheckSum;
+}
+
+ossim_int32 ossimDtedRecord::numPoints() const
+{
+   return theNumPoints;
+}
+
+ossim_int32 ossimDtedRecord::getPoint(ossim_int32 i) const
+{
+   return thePoints[i];
+}
+
+ossim_uint16 ossimDtedRecord::getPointData(ossim_int32 i) const
+{
+   return thePointsData[i];
+}
+
+ossim_int32*  ossimDtedRecord::points() const
+{
+   return thePoints;
+}
+
+ossim_uint16* ossimDtedRecord::pointsData() const
+{
+   return thePointsData;
+}
+
+ossim_int32 ossimDtedRecord::startOffset() const
+{
+   return theStartOffset;
+}
+
+ossim_int32 ossimDtedRecord::stopOffset() const
+{
+   return theStopOffset;
+}
+
+//**************************************************************************
+// operator <<
+//**************************************************************************
+ostream& operator<<( ostream& os, const ossimDtedRecord& rec)
+{
+   os << "\nDTED Record:"
+      << "\n-------------------------------"
+      << "\nRecoginition Sentinel: " << rec.theRecSen
+      << "\nData Block Count:      " << rec.theDataBlockCount
+      << "\nLon Count:             " << rec.theLonCount
+      << "\nLat Count:             " << rec.theLatCount
+      << "\nNum Points:            " << rec.theNumPoints
+      << "\nParsed Check Sum:      " << rec.theCheckSum
+      << "\nComputed Check Sum     " << rec.theComputedCheckSum
+      << "\nStart Offset:          " << rec.theStartOffset
+      << "\nStop Offset:           " << rec.theStopOffset
+      << endl;
+   int i = 0;
+
+   for(i = 0; i < rec.theNumPoints; i++)
+   {
+      os << "\nPoint[" << i << "]: " << rec.thePoints[i];
+   }
+
+   os << endl;
+
+   return os;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedRecord.h b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedRecord.h
new file mode 100644
index 0000000000..2ff841d4d1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedRecord.h
@@ -0,0 +1,174 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the Data Record Description
+//               of a DTED Level 1 file.
+//
+// Notes:  Each elevation is a true value referenced to meas sea level
+//         (MSL) datum recorded to the nearest meter.  The horizontal
+//         position is referenced to precise longitude-latitiude
+//         locations in terms of the current World Geodetic System
+//         (WGS84) determined for each file by reference to the origin
+//         at the southwest corner.  The elevations are evenly spaced
+//         in latitude and longitude at the interval designated in the
+//         User Header Label (UHL) in South to North profile sequence.
+//
+//********************************************************************
+// $Id: ossimDtedRecord.h,v 1.10 2005/01/11 18:08:57 dburken Exp $
+#ifndef ossimDtedRecord_H
+#define ossimDtedRecord_H
+#include <iostream>
+
+#include "base/common/ossimConstants.h"
+#include "base/data_types/ossimString.h"
+#include "base/common/ossimErrorStatusInterface.h"
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+class ossimDtedRecord : public ossimErrorStatusInterface
+{
+public:
+   ossimDtedRecord(std::istream& in,
+                   ossim_int32 offest,
+                   ossim_int32 num_points);
+   // NOTE:  When using this class be sure that as you cycle through
+   //        all the points within a record, that you verify they are
+   //        sequential.  According to the DTED Specification
+   //        (MIL-PRF-89020A) issued in 19 April 1996, page 22 all
+   //        records must be sequential.  If not, file may be corrupt.
+   //
+   //        To verify this, you can do the following:
+   //
+   //        int count = 0;
+   //        for(int i = 0; i < num_lon_lines; i++)
+   //          rec[i] = new ossimDtedRecord(theFileDesc, offset,
+   //                       num_lat_points);
+   //          if(count != (rec[i]->dataBlockCount() + 1))
+   //             ERROR -- Records are not sequential
+   //          count = rec[i]->dataBlockCount();
+
+   ~ossimDtedRecord();
+   
+   enum
+   {
+      DATA_LENGTH = 12,
+      DATA_BLOCK_COUNT = 2,
+      DATA_LON_COUNT = 4,
+      DATA_LAT_COUNT = 6,
+      DATA_ELEV_START = 8,
+      DATA_BYTES_PER_POINT = 2,
+   };
+
+   // The Recoginition Sentinel signifies if the Data Record exists.
+   ossimString recoginitionSentinel() const;
+
+   ossim_int32  dataBlockCount()   const;
+   ossim_int32  lonCount()         const;
+   ossim_int32  latCount()         const;
+   ossim_uint32 checkSum()         const;
+   ossim_uint32 computedCheckSum() const;
+   ossim_int32  numPoints()        const;
+
+   // Access methods for the elevation data
+   ossim_int32   getPoint(ossim_int32 i)     const;
+   ossim_uint16  getPointData(ossim_int32 i) const;
+   ossim_int32*  points()                    const;
+   ossim_uint16* pointsData()                const;
+   
+   ossim_int32 startOffset() const;
+   ossim_int32 stopOffset()  const;
+
+   friend ostream& operator<<( ostream& os, const ossimDtedRecord& rec);
+   void parse(std::istream& in);
+
+private:
+   // prevent use
+   ossimDtedRecord(const ossimDtedRecord& source);
+
+   ossim_int32  theFile;
+
+   /*!
+    * 252 (8 bit)
+    */
+   ossimString theRecSen;
+
+   /*!
+    *  Sequential count of the block within the file.
+    */
+   ossim_int32  theDataBlockCount;
+
+   /*!
+    *  Count of the meridian.
+    *  True longitude = longitude count x data interval + origin
+    *  (Offset from the SW corner longitude)
+    */
+   ossim_int32  theLonCount;
+
+   /*!
+    *  Count of the parallel.
+    *  True latitude = latitude count x data interval + origin
+    *  (Offset from the SW corner latitude)
+    */
+   ossim_int32  theLatCount;
+
+   /*!
+    *  Algebraic addition of contents of block.
+    *  The checksum is computed algebraically using integer arithmetic by
+    *  summing all header and elevation bytes contained int the record as
+    *  8-bit values.  Each byte is considered an unsigned, 8-bit value for
+    *  checksum calculation.
+    */
+   ossim_uint32  theCheckSum;
+
+   /*!
+    *  All the elevation points in a Data Record as ints.
+    *  (ie. all the latitudal points in a longitudinal line)
+    */
+   ossim_int32* thePoints;
+
+   /*!
+    *  All the elevation points in a Data Record as unsigned shorts.
+    *  (ie. all the latitudal points in a longitudinal line)
+    */
+   ossim_uint16* thePointsData;
+
+   /*!
+    *  Our computed check sum.  This should match the checksum
+    *  at the end of the Data Record.
+    */
+   ossim_uint32  theComputedCheckSum;
+
+   /*!
+    *  The number of points in a longitudinal line.
+    */
+   ossim_int32  theNumPoints;
+
+   ossim_int32       theStartOffset;
+   ossim_int32       theStopOffset;
+
+   /*!
+    *  Converts signed short to an interger.  Returns OSSIM_NAN if val is
+    *  a null value (-32767).
+    */
+   ossim_int32 convert(ossim_sint16 val);
+
+   /*!
+    *  Compute the check sum for the Data Record and compare against
+    *  the parsed check sum from the data record. This must be correct
+    *  to be a valid data record. If not, there is a chance of a
+    *  corrupted elevation cell.
+    */
+   ossim_int32 validateCheckSum(std::istream& in);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedUhl.cpp b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedUhl.cpp
new file mode 100644
index 0000000000..0c573efbc8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedUhl.cpp
@@ -0,0 +1,298 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the User Header Label
+//               (UHL) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedUhl.cpp,v 1.11 2005/01/11 18:08:57 dburken Exp $
+
+#include <fstream>
+using namespace std;
+
+#include <support_data/dted/ossimDtedUhl.h>
+#include <base/context/ossimNotifyContext.h>
+
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedUhl::ossimDtedUhl(const ossimFilename& dted_file, ossim_int32 offset)
+   :
+      theRecSen(),
+      theField2(),
+      theLonOrigin(),
+      theLatOrigin(),
+      theLonInterval(),
+      theLatInterval(),
+      theAbsoluteLE(),
+      theSecurityCode(),
+      theNumLonLines(),
+      theNumLatPoints(),
+      theMultipleAccuracy(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   // Check to see that dted file exists.
+   if(!dted_file.exists())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedUhl::ossimDtedUhl: The DTED file does not exist: " << dted_file << std::endl;
+      return;
+   }
+
+   // Check to see that the dted file is readable.
+   if(!dted_file.isReadable())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedUhl::ossimDtedUhl: The DTED file is not readable --> " << dted_file << std::endl;
+      return;
+   }
+
+   ifstream in(dted_file.c_str());
+   if(!in)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedUhl::ossimDtedUhl: Error opening the DTED file: " << dted_file << std::endl;
+      
+      return;
+   }
+
+   parse(in);
+
+   in.close();
+}
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedUhl::ossimDtedUhl(istream& in, ossim_int32 offset)
+   :
+      theRecSen(),
+      theLonOrigin(),
+      theLatOrigin(),
+      theLonInterval(),
+      theLatInterval(),
+      theAbsoluteLE(),
+      theSecurityCode(),
+      theNumLonLines(),
+      theNumLatPoints(),
+      theMultipleAccuracy(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   parse(in);
+}
+
+//**************************************************************************
+// ossimDtedUhl::parse()
+//**************************************************************************
+void ossimDtedUhl::parse(istream& in)
+{
+   // Seek to the start of the record.
+   in.seekg(theStartOffset, ios::beg);
+   
+   // Parse theRecSen
+   in.read(theRecSen, FIELD1_SIZE);
+   theRecSen[FIELD1_SIZE] = '\0';
+
+   if(!(strncmp(theRecSen, "UHL", 3) == 0))
+   {
+      // Not a user header label.
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;  
+      return;
+   }  
+   
+   // Parse Field 2
+   in.read(theField2, FIELD2_SIZE);
+   theField2[FIELD2_SIZE] = '\0';
+   
+   // Parse theLonOrigin
+   in.read(theLonOrigin, FIELD3_SIZE);
+   theLonOrigin[FIELD3_SIZE] = '\0';
+   
+   // Parse theLatOrigin
+   in.read(theLatOrigin, FIELD4_SIZE);
+   theLatOrigin[FIELD4_SIZE] = '\0';
+   
+   // Parse theLonInterval
+   in.read(theLonInterval, FIELD5_SIZE);
+   theLonInterval[FIELD5_SIZE] = '\0';
+   
+   // Parse theLatInterval
+   in.read(theLatInterval, FIELD6_SIZE);
+   theLatInterval[FIELD6_SIZE] = '\0';
+   
+   // Parse theAbsoluteLE
+   in.read(theAbsoluteLE, FIELD7_SIZE);
+   theAbsoluteLE[FIELD7_SIZE] = '\0';
+   
+   // Parse theSecurityCode
+   in.read(theSecurityCode, FIELD8_SIZE);
+   theSecurityCode[FIELD8_SIZE] = '\0';
+   
+   // Parse Field 9
+   in.read(theField9, FIELD9_SIZE);
+   theField9[FIELD9_SIZE] = '\0';
+   
+   // Parse theNumLonLines
+   in.read(theNumLonLines, FIELD10_SIZE);
+   theNumLonLines[FIELD10_SIZE] = '\0';
+   
+   // Parse theNumLatPoints
+   in.read(theNumLatPoints, FIELD11_SIZE);
+   theNumLatPoints[FIELD11_SIZE] = '\0';
+   
+   // Parse theMultipleAccuracy
+   in.read(theMultipleAccuracy, FIELD12_SIZE);
+   theMultipleAccuracy[FIELD12_SIZE] = '\0';
+
+   // Field 13 not parsed as it's unused.
+
+   // Set the stop offset.
+   theStopOffset = theStartOffset + UHL_LENGTH;
+}
+
+ossimString ossimDtedUhl::recoginitionSentinel() const
+{
+   return theRecSen;
+}
+
+double ossimDtedUhl::lonOrigin() const
+{
+   return degreesFromString(theLonOrigin);
+}
+
+double ossimDtedUhl::latOrigin() const
+{
+   return degreesFromString(theLatOrigin);
+}
+
+double ossimDtedUhl::lonInterval()      const
+{
+   return spacingFromString(theLonInterval);
+}
+
+double ossimDtedUhl::latInterval()      const
+{
+   return spacingFromString(theLatInterval);
+}
+  
+double ossimDtedUhl::degreesFromString(const char* str) const
+{
+   // Parse the string:  DDDMMMSSH
+   if (!str)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedUhl::degreesFromString: "
+                                          << "Null pointer passed to method!" << std::endl;
+      return 0.0;
+   }
+   
+   if (strlen(str) < 8)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDtedUhl::decimalDegreesFromString:"
+                                          << "String not big enough!" << std::endl;
+      return 0.0;
+   }
+
+   double d = ((str[0]-'0')*100 + (str[1]-'0')*10 + (str[2]-'0') +
+               (str[3]-'0')/6.0 + (str[4]-'0')/60.0 +
+               (str[5]-'0')/360.0 + (str[6]-'0')/3600.0);
+   
+   if ( (str[7] == 'S') || (str[7] == 's') ||
+        (str[7] == 'W') || (str[7] == 'w') )
+   {
+      d *= -1.0;
+   }
+   
+   return d;
+}
+ 
+double ossimDtedUhl::spacingFromString(const char* str) const
+{
+   // Parse the string: SSSS (tenths of a second)
+   if (!str)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimDtedUhl::decimalDegreesFromString: "
+         << "Null pointer passed to method!" << std::endl;
+      return 0.0;
+   }
+
+   return atof(str) / 36000.0;  // return 10ths of second as decimal degrees.
+}
+
+double ossimDtedUhl::absoluteLE() const
+{
+   return (theAbsoluteLE ? atoi(theAbsoluteLE) : 0);
+}
+
+ossimString ossimDtedUhl::securityCode() const
+{
+   return theSecurityCode;
+}
+
+ossim_int32 ossimDtedUhl::numLonLines() const
+{
+   return (theNumLonLines ? atoi(theNumLonLines) : 0);
+}
+
+ossim_int32 ossimDtedUhl::numLatPoints() const
+{
+   return (theNumLatPoints ? atoi(theNumLatPoints) : 0);
+}
+
+ossim_int32 ossimDtedUhl::mulitpleAccuracy() const
+{
+   return (theMultipleAccuracy ? atoi(theMultipleAccuracy) : 0);
+}
+
+ossim_int32 ossimDtedUhl::startOffset() const
+{
+   return theStartOffset;
+}
+
+ossim_int32 ossimDtedUhl::stopOffset() const
+{
+   return theStopOffset;
+}
+
+//**************************************************************************
+// operator <<
+//**************************************************************************
+ostream& operator<<( ostream& os, const ossimDtedUhl& uhl)
+{
+   os << "\nDTED Header (UHL):"
+      << "\n-------------------------------"
+      << "\nRecoginition Sentinel: " << uhl.theRecSen
+      << "\nLon Origin:            " << uhl.theLonOrigin
+      << "\nLat Origin:            " << uhl.theLatOrigin
+      << "\nLon Interval:          " << uhl.theLonInterval
+      << "\nLat Interval:          " << uhl.theLatInterval
+      << "\nAbsolute LE:           " << uhl.theAbsoluteLE
+      << "\nSecurity Code:         " << uhl.theSecurityCode
+      << "\nNumber of Lon Lines:   " << uhl.theNumLonLines
+      << "\nNumber of Lat Lines:   " << uhl.theNumLatPoints
+      << "\nMultiple Accuracy:     " << uhl.theMultipleAccuracy
+      << "\nStart Offset:          " << uhl.theStartOffset
+      << "\nStop Offset:           " << uhl.theStopOffset
+      << endl;
+   
+   return os;
+}
+
+ossimDtedUhl::ossimDtedUhl(const ossimDtedUhl& source)
+{
+}
+
+const ossimDtedUhl& ossimDtedUhl::operator=(const ossimDtedUhl& rhs)
+{
+   return rhs;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedUhl.h b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedUhl.h
new file mode 100644
index 0000000000..8085af5cbd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedUhl.h
@@ -0,0 +1,100 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+// 
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the User Header Label
+//               (UHL) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedUhl.h,v 1.10 2005/10/17 19:24:25 gpotts Exp $
+#ifndef ossimDtedUhl_H
+#define ossimDtedUhl_H
+#include <iostream>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/data_types/ossimFilename.h>
+
+class ossimDtedUhl : public ossimErrorStatusInterface
+{
+public:
+   ossimDtedUhl(const ossimFilename& dted_file, ossim_int32 offset);
+   ossimDtedUhl(std::istream& in, ossim_int32 offset);
+
+   enum
+   {
+      UHL_LENGTH        = 80,
+      UHL_LON_ORIGIN    =  5,
+      UHL_LAT_ORIGIN    = 13,
+      UHL_LON_INTERVAL  = 21,
+      UHL_LAT_INTERVAL  = 25,
+      UHL_ABSOLUTE_LE   = 29,
+      UHL_SECURITY_CODE = 33,
+      UHL_REFERENCE_NUM = 33,
+      UHL_NUM_LON_LINES = 48,
+      UHL_NUM_LAT_LINES = 52,
+      UHL_MULTIPLE_ACC  = 56,
+      UHL_RESERVED      = 57,
+      FIELD1_SIZE       = 3,
+      FIELD2_SIZE       = 1,
+      FIELD3_SIZE       = 8,
+      FIELD4_SIZE       = 8,
+      FIELD5_SIZE       = 4,
+      FIELD6_SIZE       = 4,
+      FIELD7_SIZE       = 4,
+      FIELD8_SIZE       = 3,
+      FIELD9_SIZE       = 12,
+      FIELD10_SIZE      = 4,
+      FIELD11_SIZE      = 4,
+      FIELD12_SIZE      = 1,
+      FIELD13_SIZE      = 24
+   };
+   
+   // The Recoginition Sentinel signifies if the UHL record exists.
+   ossimString recoginitionSentinel() const;
+
+   double      lonOrigin()        const;
+   double      latOrigin()        const;
+   double      lonInterval()      const;
+   double      latInterval()      const;
+   double      absoluteLE()       const;
+   ossimString securityCode()     const;
+   ossim_int32 numLonLines()      const;
+   ossim_int32 numLatPoints()     const;
+   ossim_int32 mulitpleAccuracy() const;
+   ossim_int32 startOffset()      const;
+   ossim_int32 stopOffset()       const;
+   
+   friend std::ostream& operator<<( std::ostream& os, const ossimDtedUhl& uhl);
+
+   void parse(std::istream& in);
+
+private:
+   // Do not allow...
+   ossimDtedUhl(const ossimDtedUhl& source);
+   const ossimDtedUhl& operator=(const ossimDtedUhl& rhs);
+
+   double degreesFromString(const char* str) const;
+   double spacingFromString(const char* str) const;
+   
+   char theRecSen[FIELD1_SIZE+1];
+   char theField2[FIELD2_SIZE+1];
+   char theLonOrigin[FIELD3_SIZE+1];
+   char theLatOrigin[FIELD4_SIZE+1];
+   char theLonInterval[FIELD5_SIZE+1];
+   char theLatInterval[FIELD6_SIZE+1];
+   char theAbsoluteLE[FIELD7_SIZE+1];
+   char theSecurityCode[FIELD8_SIZE+1];
+   char theField9[FIELD9_SIZE+1];
+   char theNumLonLines[FIELD10_SIZE+1];
+   char theNumLatPoints[FIELD11_SIZE+1];
+   char theMultipleAccuracy[FIELD12_SIZE+1];
+   
+   ossim_int32 theStartOffset;
+   ossim_int32 theStopOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedVol.cpp b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedVol.cpp
new file mode 100644
index 0000000000..4a0b552180
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedVol.cpp
@@ -0,0 +1,191 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the Volume Header Label
+//               (VOL) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedVol.cpp,v 1.11 2005/01/11 18:08:57 dburken Exp $
+
+#include <fstream>
+using namespace std;
+
+#include <support_data/dted/ossimDtedVol.h>
+#include <base/context/ossimNotifyContext.h>
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedVol::ossimDtedVol(const ossimFilename& dted_file,
+                           ossim_int32 offset)
+   :
+      theRecSen(),
+      theField2(),
+      theReelNumber(),
+      theField4(),
+      theField5(),
+      theAccountNumber(),
+      theField7(),
+      theField8(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   // Check to see that dted file exists.
+   if(!dted_file.exists())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimDtedVol::ossimDtedVol"
+         << "\nThe DTED file does not exist: " << dted_file << std::endl;
+      return;
+   }
+
+   // Check to see that the dted file is readable.
+   if(!dted_file.isReadable())
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimDtedVol::ossimDtedVol"
+         << "\nThe DTED file is not readable: " << dted_file << std::endl;
+      return;
+   }
+   
+   // Open the dted file for reading.
+   ifstream in(dted_file.c_str());
+   if(!in)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimDtedVol::ossimDtedVol"
+         << "\nUnable to open the DTED file: " << dted_file << std::endl;
+      return;
+   }
+
+   parse(in);
+
+   in.close();
+}
+
+//**************************************************************************
+// CONSTRUCTOR
+//**************************************************************************
+ossimDtedVol::ossimDtedVol(istream& in,
+                           ossim_int32 offset)
+   :
+      theRecSen(),
+      theReelNumber(),
+      theAccountNumber(),
+      theStartOffset(offset),
+      theStopOffset(0)
+{
+   parse(in);
+}
+
+void ossimDtedVol::parse(istream& in)
+{
+   // Seek to the start of the record.
+   in.seekg(theStartOffset, ios::beg);
+   
+   // Parse theRecSen
+   in.read(theRecSen, FIELD1_SIZE);
+   theRecSen[FIELD1_SIZE] = '\0';
+
+   if(!(strncmp(theRecSen, "VOL", 3) == 0))
+   {
+      // Not a volume header label.
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      return;
+   }   
+
+   // Parse Field 2
+   in.read(theField2, FIELD2_SIZE);
+   theField2[FIELD2_SIZE] = '\0';
+   
+   // Parse theReelNumber
+   in.read(theReelNumber, FIELD3_SIZE);
+   theReelNumber[FIELD3_SIZE] = '\0';
+   
+   // Parse Field 4
+   in.read(theField4, FIELD4_SIZE);
+   theField4[FIELD4_SIZE] = '\0';
+   
+   // Parse Field 5
+   in.read(theField5, FIELD5_SIZE);
+   theField5[FIELD5_SIZE] = '\0';
+   
+   // Parse theAccountNumber
+   in.read(theAccountNumber, FIELD6_SIZE);
+   theAccountNumber[FIELD6_SIZE] = '\0';
+   
+   // Parse Field 7
+   in.read(theField7, FIELD7_SIZE);
+   theField7[FIELD7_SIZE] = '\0';
+
+   // Parse Field 8
+   in.read(theField8, FIELD8_SIZE);
+   theField8[FIELD8_SIZE] = '\0';
+
+   // Set the stop offset.
+   theStopOffset = theStartOffset + VOL_LENGTH;
+}
+
+ossimString ossimDtedVol::getRecoginitionSentinel() const
+{
+   return ossimString(theRecSen);
+}
+
+ossimString ossimDtedVol::getReelNumber() const
+{
+   return ossimString(theReelNumber);
+}
+
+ossimString ossimDtedVol::getAccountNumber() const
+{
+   return ossimString(theAccountNumber);
+}
+
+ossim_int32 ossimDtedVol::startOffset() const
+{
+   return theStartOffset;
+}
+
+ossim_int32 ossimDtedVol::stopOffset() const
+{
+   return theStopOffset;
+}
+
+//**************************************************************************
+// operator <<
+//**************************************************************************
+ostream& operator<<( ostream& os, const ossimDtedVol& vol)
+{
+   os << "\nDTED Header (VOL):"
+      << "\n-------------------------------"
+      << "\nRecoginition Sentinel: " << vol.theRecSen
+      << "\nField 2:               " << vol.theField2
+      << "\ntheReelNumber:         " << vol.theReelNumber
+      << "\nField 4:               " << vol.theField4
+      << "\nField 5:               " << vol.theField5
+      << "\ntheAccountNumber:      " << vol.theAccountNumber
+      << "\nField 7:               " << vol.theField7
+      << "\nField 8:               " << vol.theField8
+      << endl;
+   
+   return os;
+}
+
+ossimDtedVol::ossimDtedVol(const ossimDtedVol& source)
+{
+}
+
+const ossimDtedVol& ossimDtedVol::operator=(const ossimDtedVol& rhs)
+{
+   return rhs;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedVol.h b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedVol.h
new file mode 100644
index 0000000000..48c6416874
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/dted/ossimDtedVol.h
@@ -0,0 +1,78 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description:  This class gives access to the Volume Header Label
+//               (VOL) of a DTED Level 1 file.
+//
+//********************************************************************
+// $Id: ossimDtedVol.h,v 1.9 2005/10/17 19:24:25 gpotts Exp $
+
+#ifndef ossimDtedVol_H
+#define ossimDtedVol_H
+#include <iostream>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/data_types/ossimFilename.h>
+
+class ossimDtedVol : public ossimErrorStatusInterface
+{
+public:
+   ossimDtedVol(const ossimFilename& dted_file,
+                ossim_int32 offset);
+   ossimDtedVol(std::istream& in,
+                ossim_int32 offset);
+
+   enum
+   {
+      VOL_LENGTH            = 80,
+      VOL_ONE_LABEL_1       =  4,
+      VOL_REEL_NUMBER       =  5,
+      VOL_REEL_ACCESS       = 11,
+      VOL_SPACE             = 12,
+      VOL_ACCOUNT_NUMBER    = 38,
+      VOL_BLANKS            = 52,
+      VOL_ONE_LABEL_2       = 80,
+      FIELD1_SIZE           = 3,
+      FIELD2_SIZE           = 1,
+      FIELD3_SIZE           = 6,
+      FIELD4_SIZE           = 1,
+      FIELD5_SIZE           = 26,
+      FIELD6_SIZE           = 14,
+      FIELD7_SIZE           = 28,
+      FIELD8_SIZE           = 1
+   };
+   
+   // The Recoginition Sentinel signifies if the VOL record exists.
+   ossimString getRecoginitionSentinel() const;
+   ossimString getReelNumber()           const;
+   ossimString getAccountNumber()        const;
+   ossim_int32 startOffset()             const;
+   ossim_int32 stopOffset()              const;
+   friend std::ostream& operator<<( std::ostream& os, const ossimDtedVol& vol);
+   
+   void parse(std::istream& in);
+
+private:
+   // Do not allow...
+   ossimDtedVol(const ossimDtedVol& source);
+   const ossimDtedVol& operator=(const ossimDtedVol& rhs);
+
+   char theRecSen[FIELD1_SIZE+1];
+   char theField2[FIELD2_SIZE+1];
+   char theReelNumber[FIELD3_SIZE+1];
+   char theField4[FIELD4_SIZE+1];
+   char theField5[FIELD5_SIZE+1];
+   char theAccountNumber[FIELD6_SIZE+1];
+   char theField7[FIELD7_SIZE+1];
+   char theField8[FIELD8_SIZE+1];
+  
+   ossim_int32 theStartOffset;
+   ossim_int32 theStopOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/envi/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/envi/.cvsignore
new file mode 100644
index 0000000000..3ccb77a586
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/envi/.cvsignore
@@ -0,0 +1,4 @@
+*.d
+*.o
+*.~*
+Makefile
diff --git a/Utilities/OSSIM/ossim_core/support_data/envi/ossimEnviHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/envi/ossimEnviHeader.cpp
new file mode 100644
index 0000000000..590b81a5f6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/envi/ossimEnviHeader.cpp
@@ -0,0 +1,974 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Class for reading and writing an ENVI (The Environment for Visualizing
+// Images) header file.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimEnviHeader.cpp,v 1.4 2005/06/21 19:05:04 dburken Exp $
+
+#include <fstream>
+#include <string>
+using namespace std;
+
+#include <support_data/envi/ossimEnviHeader.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+// Define keywords not already found in ossimKeywordNames.
+static const char HEADER_OFFSET_KW[]    = "header_offset";
+static const char FILE_TYPE_KW[]        = "file_type";
+static const char DATA_TYPE_KW[]        = "data_type";
+static const char SENSOR_TYPE_KW[]      = "sensor_type";
+static const char X_START_KW[]          = "x_start";
+static const char MAP_INFO_KW[]         = "map_info";
+static const char WAVELENGTH_UNITS_KW[] = "wavelength_units";
+static const char BAND_NAME_KW[]        = "band_name";
+static const char WAVELENGTH_KW[]       = "wavelength";
+
+static ossimTrace traceDebug(ossimString("ossimEnviHeader:debug"));
+
+ossimEnviHeader::ossimEnviHeader()
+   :
+   ossimErrorStatusInterface(),
+   theDescription(),
+   theSamples(0),
+   theLines(0),
+   theBands(0),
+   theHeaderOffset(0),
+   theFileType("ENVI Standard"),
+   theDataType(0),
+   theInterleave("Unknown"),
+   theSensorType(),
+   theByteOrder(OSSIM_LITTLE_ENDIAN),
+   theXStart(0),
+   theMapInfo(),
+   theWavelengthUnits("Unknown"),
+   theBandName(),
+   theWavelength()   
+{
+   // Start the byte order of with the machine byte order.
+   theByteOrder = ossimGetByteOrder();
+}
+
+ossimEnviHeader::~ossimEnviHeader()
+{
+}
+
+bool ossimEnviHeader::open(const ossimFilename& file)
+{
+   ifstream is(file.c_str(), ios_base::in);
+   if (!is)
+   {
+      setErrorStatus();
+      return false;
+   }
+
+   string s;
+   is >> s;
+
+   if (s != "ENVI")
+   {
+      setErrorStatus();
+      return false;
+   }
+
+   // Parse the file.
+   while (is)
+   {
+      // read something.
+      is >> s;
+      
+      if (s == "description")
+      {
+         parseDescription(is);
+      }
+      else if (s == "samples")
+      {
+         is >> s; // eat the =
+         is >> theSamples;
+      }
+      else if (s == "lines")
+      {
+         is >> s; // eat the =
+         is >> theLines;
+      }
+      else if (s == "bands")
+      {
+         is >> s; // eat the =
+         is >> theBands;
+      }
+      else if (s == "header")
+      {
+         is >> s;
+         if (s == "offset")
+         {
+            is >> s; // eat the =
+            is >> theHeaderOffset;
+         }
+      }
+      else if (s == "file")
+      {
+         is >> s;
+         if (s == "type")
+         {
+            is >> s; // eat the =
+            getline(is, s);
+            theFileType = s;
+         }
+      }
+      else if (s == "data")
+      {
+         is >> s;
+         if (s == "type")
+         {
+            is >> s; // eat the =
+            is >> theDataType;
+         }
+      }
+      else if (s == "interleave")
+      {
+         is >> s; // eat the =
+         is >> theInterleave;
+      }
+      else if (s == "sensor")
+      {
+         is >> s;
+         if (s == "type")
+         {
+            is >> s; // eat the =
+            is >> theSensorType;
+         }
+      }
+      else if (s == "byte")
+      {
+         is >> s;
+         if (s == "order")
+         {
+            is >> s; // eat the =
+            int i;
+            is >> i;
+            theByteOrder = (i == 1 ? OSSIM_BIG_ENDIAN : OSSIM_LITTLE_ENDIAN);
+         }
+      }
+      else if (s == "x")
+      {
+         is >> s;
+         if (s == "start")
+         {
+            is >> s; // eat the =
+            is >> theXStart;
+         }
+      }
+      else if (s == "map")
+      {
+         is >> s;
+         if (s == "info")
+         {
+            is >> s; // eat the =
+            getline(is, theMapInfo); // one big string
+         }
+      }
+      else if (s == "wavelength")
+      {
+         is >> s;
+         if (s == "units")
+         {
+            is >> s; // eat the =
+            is >> theWavelengthUnits;
+         }
+         else if (s == "=")
+         {
+            parseWavelength(is);
+         }
+      }
+      else if (s == "band")
+      {
+         is >> s;
+         if (s == "names")
+         {
+            parseBandNames(is);
+         }
+      }
+   }
+
+   // Must have these; else, error.
+   if (!theSamples || !theLines || !theBands)
+   {
+      return false;
+   }
+   
+   return true;
+}
+
+bool ossimEnviHeader::writeFile(const ossimFilename& file)
+{
+   if (theDescription.empty())
+   {
+      theDescription = file;
+   }
+   
+   ofstream out(file.c_str(), ios_base::out);
+
+   if (!out)
+   {
+      return false;
+   }
+   
+   print(out);
+   out.close();
+   return true;
+}
+
+std::ostream& ossimEnviHeader::print(std::ostream& out) const
+{
+   out << "ENVI"
+       << "\ndescription = {\n" << theDescription << "}"
+       << "\nsamples = " << theSamples
+       << "\nlines   = " << theLines
+       << "\nbands   = " << theBands
+       << "\nheader offset = " << theHeaderOffset
+       << "\nfile type = " << theFileType
+       << "\ndata type = " << theDataType
+       << "\ninterleave = " << theInterleave;
+   if (theSensorType.size())
+   {
+      out << "\nsensor type = " << theSensorType;
+   }
+
+   out << "\nbyte order = " << theByteOrder;
+
+   if (theXStart)
+   {
+      out << "\nx start = " << theXStart;
+   }
+
+   if (theMapInfo.size())
+   {
+      out << "\nmap info = " << theMapInfo;
+   }
+
+   if (theWavelength.size())
+   {
+      out << "\nwavelength units = " << theWavelengthUnits;
+   }
+
+   if (theBandName.size())
+   {
+      out << "\nband names = {";
+      ossim_uint32 i;
+      ossim_uint32 size = theBandName.size();
+      for (i = 0; i < size; ++i)
+      {
+         out << "\n " << theBandName[i];
+         if (i < size-1)
+         {
+            out << ",";
+         }
+         else
+         {
+            out << "}";
+         }
+      }
+   }
+   else
+   {
+      out << "\nband names = {";
+      ossim_uint32 i;
+      for (i = 0; i < theBands; ++i)
+      {
+         out << "\nBand " << (i+1);
+         if (i < theBands-1)
+         {
+            out << ",";
+         }
+         else
+         {
+            out << "}";
+         }
+      }
+   }
+   
+   if (theWavelength.size())
+   {
+      out << "\nwavelength = {\n";
+      ossim_uint32 i;
+      ossim_uint32 size = theWavelength.size();
+      for (i = 0; i < size; ++i)
+      {
+         out << theWavelength[i];
+         if (i < size-1)
+         {
+            out << ", ";
+         }
+         else
+         {
+            out << "}";
+         }
+      }
+   }
+
+   out << endl;
+   
+   return out;
+}
+
+ossimString ossimEnviHeader::getDescription() const
+{
+   return theDescription;
+}
+
+void ossimEnviHeader::setDescription(const ossimString& description)
+{
+   theDescription = description;
+}
+
+ossim_uint32 ossimEnviHeader::getSamples() const
+{
+   return theSamples;
+}
+
+void ossimEnviHeader::setSamples(ossim_uint32 samples)
+{
+   theSamples = samples;
+}
+
+ossim_uint32 ossimEnviHeader::getLines() const
+{
+   return theLines;
+}
+
+void ossimEnviHeader::setLines(ossim_uint32 lines)
+{
+   theLines = lines;
+}
+
+ossim_uint32 ossimEnviHeader::getBands() const
+{
+   return theBands;
+}
+
+void ossimEnviHeader::setBands(ossim_uint32 bands)
+{
+   theBands = bands;
+}
+
+ossim_uint32 ossimEnviHeader::getHeaderOffset() const
+{
+   return theHeaderOffset;
+}
+
+void ossimEnviHeader::setHeaderOffset(ossim_uint32 headerOffset)
+{
+   theHeaderOffset = headerOffset;
+}
+
+ossimString ossimEnviHeader::getFileType() const
+{
+   return theFileType;
+}
+
+void ossimEnviHeader::setFileType(const ossimString& fileType)
+{
+   theFileType = fileType;
+}
+
+ossim_uint32 ossimEnviHeader::getDataType() const
+{
+   return theDataType;
+}
+
+ossimScalarType ossimEnviHeader::getOssimScalarType() const
+{
+   switch( theDataType )
+   {
+      case 1:
+         return OSSIM_UINT8;
+
+      case 2:
+         return OSSIM_SINT16;
+
+      case 3:
+         return OSSIM_SINT32;
+
+      case 4:
+         return OSSIM_FLOAT32;
+
+      case 5:
+         return OSSIM_FLOAT64;
+
+      case 6:
+         return OSSIM_CFLOAT32;
+
+      case 9:
+         return OSSIM_CFLOAT64;
+
+      case 12:
+         return OSSIM_UINT16;
+
+      case 13:
+         return OSSIM_UINT32;
+
+      default:
+         return OSSIM_SCALAR_UNKNOWN;
+   }
+
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+void ossimEnviHeader::setDataType(ossimScalarType scalar)
+{
+   switch( scalar )
+   {
+      case OSSIM_UINT8:
+         theDataType = 1;
+         break;
+
+      case OSSIM_SINT16:
+         theDataType = 2;
+         break;
+
+      case OSSIM_SINT32:
+         theDataType = 3;
+         break;
+
+      case OSSIM_FLOAT32:
+         theDataType = 4;
+         break;
+
+      case OSSIM_FLOAT64:
+         theDataType = 5;
+         break;
+
+      case OSSIM_CFLOAT32:
+         theDataType = 6;
+         break;
+
+      case OSSIM_CFLOAT64:
+         theDataType = 9;
+         break;
+
+      case OSSIM_UINT16:
+         theDataType = 12;
+         break;
+
+      case OSSIM_UINT32:
+         theDataType = 13;
+         break;
+
+      default:
+         break;
+   }
+}
+ossimString ossimEnviHeader::getInterleaveType() const
+{
+   return theInterleave;
+}
+ossimInterleaveType ossimEnviHeader::getOssimInterleaveType() const
+{
+   if (theInterleave == "bsq")
+   {
+      return OSSIM_BSQ;
+   }
+   else if  (theInterleave == "bil")
+   {
+      return OSSIM_BIL;
+   }
+   else if  (theInterleave == "bip")
+   {
+      return OSSIM_BIP;
+   }
+   else
+   {
+      return OSSIM_INTERLEAVE_UNKNOWN;
+   }
+}
+
+void ossimEnviHeader::setInterleaveType(ossimInterleaveType interleave)
+{
+   switch (interleave)
+   {
+      case OSSIM_BIL:
+         theInterleave = "bil";
+         break;
+         
+      case OSSIM_BSQ:
+         theInterleave = "bsq";
+         break;
+         
+      case OSSIM_BIP:
+         theInterleave = "bip";
+         break;
+      default:
+         theInterleave = "Unknown";
+         break;
+   }
+}
+
+ossimString ossimEnviHeader::getSensorType() const
+{
+   return theSensorType;
+}
+
+void ossimEnviHeader::setSensorType(const ossimString& sensorType)
+{
+   theSensorType = sensorType;
+}
+
+ossimByteOrder ossimEnviHeader::getByteOrder() const
+{
+   // 0 = little
+   // 1 = big
+   return theByteOrder;
+}
+
+void ossimEnviHeader::setByteorder(ossimByteOrder byteOrder)
+{
+   theByteOrder = byteOrder;
+}
+
+ossim_int32 ossimEnviHeader::getXStart() const
+{
+   return theXStart;
+}
+
+void ossimEnviHeader::setXStart(ossim_int32 xstart)
+{
+   theXStart = xstart;
+}
+
+ossimString ossimEnviHeader::getMapInfo() const
+{
+   return theMapInfo;
+}
+
+void ossimEnviHeader::setMapInfo(const ossimString& mapInfo)
+{
+   theMapInfo = mapInfo;
+}
+
+void ossimEnviHeader::setMapInfo(const ossimKeywordlist& kwl,
+                                 const char* prefix)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimEnviHeader::setMapInfo DEBUG:"
+         << "\nkwl:\n"
+         << kwl
+         << endl;
+   }
+
+   const char* lookup;
+   
+   // Get the projection type.
+   ossimString projection;
+   lookup = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+   if (lookup)
+   {
+      projection = lookup;
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimEnviHeader::setMapInfo WARNING:"
+         << "\nNo projection type found!\nReturning..."
+         << endl;
+         
+      return; // Have to have the projection type!
+   }
+
+   // Get the datum.
+   ossimString datum = "WGS-84";
+   lookup = kwl.find(prefix, ossimKeywordNames::DATUM_KW);
+   if (lookup)
+   {
+      ossimString os = lookup;
+      if (os = "WGE")
+      {
+         datum = "WGS-84";
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimEnviHeader::setMapInfo WARNING:"
+            << "\nUnhandled ossim -> envi datum:  " << datum
+            << "\nAssuming WGS-84!"
+            << endl;
+      }
+   }
+
+   if ( (projection == "ossimEquDistCylProjection") ||
+        (projection == "ossimLlxyProjection") )
+   {
+      const char* tieLat = NULL;
+      const char* tieLon = NULL;
+      const char* degLat = NULL;
+      const char* degLon = NULL;
+      tieLat = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LAT_KW);
+      tieLon = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LON_KW);
+      degLat = kwl.find(prefix,
+                        ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT);
+      degLon = kwl.find(prefix,
+                       ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON);
+      
+      if (!tieLat || !tieLon || !degLat || !degLon)
+      {
+         return;
+      }
+                 
+      theMapInfo = "{Geographic Lat/Lon, 1.0000, 1.0000, ";
+      theMapInfo += tieLon;
+      theMapInfo += ", ";
+      theMapInfo += tieLat;
+      theMapInfo += ", ";
+      theMapInfo += degLon;
+      theMapInfo += ", ";
+      theMapInfo += degLat;
+      theMapInfo += ", ";
+      theMapInfo += datum;
+      theMapInfo += ", units=degrees}";
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimEnviHeader::setMapInfo DEBUG:"
+         << "\ntheMapInfo:  " << theMapInfo
+         << endl;
+   }
+}
+
+ossimString ossimEnviHeader::getWavelengthUnits() const
+{
+   return theWavelengthUnits;
+}
+
+void ossimEnviHeader::setWavelengthUnits(const ossimString& waveLengthUnits)
+{
+   theWavelengthUnits = waveLengthUnits;
+}
+
+void ossimEnviHeader::getBandNames(vector<ossimString>& bandNames) const
+{
+   bandNames = theBandName;
+}
+
+void ossimEnviHeader::setBandNames(const vector<ossimString>& bandNames)
+{
+   theBandName = bandNames;
+}
+
+void ossimEnviHeader::getWavelengths(vector<ossimString>& waveLengths) const
+{
+   waveLengths = theWavelength;
+}
+
+void ossimEnviHeader::setWavelengths(const vector<ossimString>& wavelengths)
+{
+   theWavelength = wavelengths;
+}
+
+void ossimEnviHeader::parseDescription(std::ifstream& is)
+{
+   bool record = false;
+   theDescription.clear();
+   char c = '\0';
+
+   while (c != '}')
+   {
+      is.get(c);
+      if (c == '{') // start record.
+      {
+         record = true;
+         continue;
+      }
+      else if (c == '}') // finished recording
+      {
+         break;
+      }
+      else if (!is) // something bad happened.
+      {
+         setErrorStatus();
+         return;
+      }
+
+      if (record)
+      {
+         theDescription.push_back(c);
+      }
+   }
+}
+
+void ossimEnviHeader::parseWavelength(std::ifstream& is)
+{
+   bool record = false;
+   theWavelength.clear();
+   char c = '\0';
+
+   string bandWavelength;
+   
+   while (c != '}')
+   {
+      is.get(c);
+      if (c == '{') // start record.
+      {
+         record = true;
+         continue;
+      }
+      else if (c == '\n')
+      {
+         continue; // skip newlines
+      }
+      else if (c == '}') // finished recording
+      {
+         theWavelength.push_back(bandWavelength);
+         break;
+      }
+      else if (c == ',')
+      {
+         theWavelength.push_back(bandWavelength);
+         bandWavelength.clear();
+         continue;
+      }
+
+      if (!is) // something bad happened.
+      {
+         setErrorStatus();
+         return;
+      }
+
+      if (record)
+      {
+         bandWavelength.push_back(c);
+      }
+   }
+}
+
+void ossimEnviHeader::parseBandNames(std::ifstream& is)
+{
+   bool record = false;
+   theBandName.clear();
+   char c = '\0';
+
+   string bandName;
+   
+   while (c != '}')
+   {
+      is.get(c);
+      if (c == '{') // start record.
+      {
+         record = true;
+         continue;
+      }
+      else if (c == '\n')
+      {
+         continue; // skip newlines
+      }
+      else if (c == '}') // finished recording
+      {
+         ossimString os = bandName;
+         os.trim();
+         theBandName.push_back(os);
+         break;
+      }
+      else if (c == ',')
+      {
+         ossimString os = bandName;
+         os.trim();
+         theBandName.push_back(os);
+         bandName.clear();
+         continue;
+      }
+
+      if (!is) // something bad happened.
+      {
+         setErrorStatus();
+         return;
+      }
+
+      if (record)
+      {
+         bandName.push_back(c);
+      }
+   }
+}
+
+bool ossimEnviHeader::loadState(const ossimKeywordlist& kwl,
+                                const char* prefix)
+{
+   const char* lookup;
+   ossimString s;
+
+   lookup = kwl.find(prefix, ossimKeywordNames::DESCRIPTION_KW);
+   if (lookup)
+   {
+      theDescription = lookup;
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_SAMPLES_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theSamples = s.toUInt32();
+   }
+   
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_LINES_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theLines = s.toUInt32();
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_BANDS_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theBands = s.toUInt32();
+   }
+
+   lookup = kwl.find(prefix, HEADER_OFFSET_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theHeaderOffset = s.toUInt32();
+   }
+
+   lookup = kwl.find(prefix, FILE_TYPE_KW);
+   if (lookup)
+   {
+      theFileType = lookup;
+   }
+
+   lookup = kwl.find(prefix, DATA_TYPE_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theDataType = s.toUInt32();
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::INTERLEAVE_TYPE_KW);
+   if (lookup)
+   {
+      theInterleave = lookup;
+   }
+
+   lookup = kwl.find(prefix, SENSOR_TYPE_KW);
+   if (lookup)
+   {
+      theSensorType = lookup;
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::BYTE_ORDER_KW);
+   if (lookup)
+   {
+      s = lookup;
+      s.downcase();
+      if (s == "little_endian")
+      {
+         theByteOrder = OSSIM_LITTLE_ENDIAN;
+      }
+      else if (s == "big_endian")
+      {
+         theByteOrder= OSSIM_BIG_ENDIAN;
+      }
+      else
+      {
+         ossim_uint32 i = s.toUInt32();
+         if (i == 0)
+         {
+            theByteOrder = OSSIM_LITTLE_ENDIAN;
+         }
+         else if (i == 1)
+         {
+            theByteOrder= OSSIM_BIG_ENDIAN;
+         }
+      }
+   }
+   
+   lookup = kwl.find(prefix, X_START_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theXStart = (ossimByteOrder)s.toInt32();
+   }
+
+   lookup = kwl.find(prefix, MAP_INFO_KW);
+   if (lookup)
+   {
+      theMapInfo = lookup;
+   }
+
+   lookup = kwl.find(prefix, WAVELENGTH_UNITS_KW);
+   if (lookup)
+   {
+      theWavelengthUnits = lookup;
+   }
+
+   ossim_uint32 n;
+   ossim_uint32 count;
+   const ossim_uint32 MAX_TRIES = 1024; // Avoid infinate loop.
+   
+   // Get the band names.
+   n = kwl.numberOf(prefix, BAND_NAME_KW);
+   if (n)
+   {
+      theBandName.clear();
+      count = 0;
+      while ( (count < n) || (count > MAX_TRIES) )
+      {
+         s = BAND_NAME_KW;
+         s += ossimString::toString(count);
+         lookup = kwl.find(prefix, s);
+         if (lookup)
+         {
+            theBandName.push_back(ossimString(lookup));
+         }
+         ++count;
+      }
+   }
+            
+   // Get the band names.
+   n = kwl.numberOf(prefix, WAVELENGTH_KW);
+   if (n)
+   {
+      theWavelength.clear();
+      count = 0;
+      while ( (count < n) || (count > MAX_TRIES) )
+      {
+         s = WAVELENGTH_KW;
+         s += ossimString::toString(count);
+         lookup = kwl.find(prefix, s);
+         if (lookup)
+         {
+            theWavelength.push_back(ossimString(lookup));
+         }
+         ++count;
+      }
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimEnviHeader::loadState DEUG\n"
+         << *this
+         << endl;
+   }
+   
+
+   
+   
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/envi/ossimEnviHeader.h b/Utilities/OSSIM/ossim_core/support_data/envi/ossimEnviHeader.h
new file mode 100644
index 0000000000..fa34e2fdc4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/envi/ossimEnviHeader.h
@@ -0,0 +1,339 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Class for reading and writing an ENVI (The Environment for Visualizing
+// Images) header file.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimEnviHeader.h,v 1.3 2005/06/21 19:05:04 dburken Exp $
+#ifndef ossimEnviHeader_HEADER
+#define ossimEnviHeader_HEADER
+
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimString.h>
+
+
+class ossimFilename;
+class ossimKeywordlist;
+
+/**
+ * Class for reading and writing an ENVI (The Environment for Visualizing
+ * Images) header file.
+ */
+class OSSIM_DLL ossimEnviHeader : public ossimErrorStatusInterface
+{
+public:
+
+   /** default construtor */
+   ossimEnviHeader();
+
+   /** virtual destructor */
+   virtual ~ossimEnviHeader();
+
+   /**
+    * Opens an envi header.
+    * 
+    * @return true on success, false on error.
+    */
+   bool open(const ossimFilename& file);
+
+   /**
+    * Writes header to file in a standard envi format.
+    *
+    * @param file File to write to.
+    *
+    * @return true on success, false on error.
+    */
+   bool writeFile(const ossimFilename& file);
+   
+   /**
+    * Prints header to out in a standard envi format.
+    *
+    * @param out Stream to write to.
+    *
+    * @return Reference to the stream passed.
+    */
+   std::ostream& print(std::ostream& out) const;
+
+   /**
+    * @return The description of the file.
+    */
+   ossimString getDescription() const;
+
+   /**
+    * @param description The description of the file.
+    */
+   void setDescription(const ossimString& description);
+
+   /**
+    * @return The number of samples.
+    */
+   ossim_uint32 getSamples() const;
+
+   /**
+    * Sets the number of samples.
+    * 
+    * @param samples The number of samples.
+    */
+   void setSamples(ossim_uint32 samples);
+
+   /**
+    * @return The number of lines.
+    */
+   ossim_uint32 getLines() const;
+
+   /**
+    * Sets the number of lines.
+    * 
+    * @param lines The number of lines.
+    */
+   void setLines(ossim_uint32 lines);
+
+   /**
+    * @return The number of bands.
+    */
+   ossim_uint32 getBands() const;
+
+   /**
+    * Sets the number of bands.
+    * 
+    * @param bands The number of bands.
+    */
+   void setBands(ossim_uint32 bands);
+
+   /**
+    * @return The number of header offset in bytes.
+    */
+   ossim_uint32 getHeaderOffset() const;
+
+   /**
+    * Sets the header offset in bytes.
+    * 
+    * @param headerOffset The number of header offset in bytes.
+    */
+   void setHeaderOffset(ossim_uint32 headerOffset);
+
+   /**
+    * @return The file type
+    */
+   ossimString getFileType() const;
+
+   /**
+    * Sets the file type.
+    * 
+    * @param fileType The sensor type as a string.
+    */
+   void setFileType(const ossimString& fileType);
+
+   /**
+    * @return The envi data type..
+    */
+   ossim_uint32 getDataType() const;
+
+   /**
+    * @return The ossimScalarType from the envi data type..
+    */
+   ossimScalarType getOssimScalarType() const;
+
+   /**
+    * Sets the envi data type based on the ossimScalarType.
+    * 
+    * @param scalar The ossimScalarType of the image.
+    */
+   void setDataType(ossimScalarType scalar);
+
+   /**
+    * @return The envi interleave type.
+    */
+   ossimString getInterleaveType() const;
+
+   /**
+    * @return The ossimInterleaveType from the envi interleave..
+    */
+   ossimInterleaveType getOssimInterleaveType() const;
+
+   /**
+    * Sets the envi interleave type string based on the ossimInterleaveType.
+    * 
+    * @param interleave The ossimInterleaveType of the image.
+    */
+   void setInterleaveType(ossimInterleaveType interleave);
+
+   /**
+    * @return The sensor type..
+    */
+   ossimString getSensorType() const;
+
+   /**
+    * Sets the envi sensor type string.
+    * 
+    * @param sensorType The sensor type as a string.
+    */
+   void setSensorType(const ossimString& sensorType);
+
+   /**
+    * @return The envi byte order.
+    *
+    * @note (Same as the ossimByteOrder enumeration):
+    * 0 = LITTLE_ENDIAN,
+    * 1 = BIG_ENDIAN
+    * 
+    */
+   ossimByteOrder getByteOrder() const;
+   
+   /**
+    * Sets the envi byte order from the ossimByteOrder.
+    * 
+    * @param byteorder The ossimByteOrder of the image.
+    */
+   void setByteorder(ossimByteOrder byteOrder);
+   
+   /**
+    * @return The x start.
+    */
+   ossim_int32 getXStart() const;
+
+   /**
+    * Sets the x start.
+    * 
+    * @param xStart
+    */
+   void setXStart(ossim_int32 xstart);
+
+   /**
+    * @return The envi map info string.
+    */
+   ossimString getMapInfo() const;
+
+   /**
+    * Sets the envi map info string.
+    * 
+    * @param mapInfo envi map info string.
+    */
+   void setMapInfo(const ossimString& mapInfo);
+
+   /**
+    * Sets the envi map info string from a keyword list containing geometry
+    * information.
+    * 
+    * @param kwl Keyword list containing geometry information.
+    */
+   void setMapInfo(const ossimKeywordlist& kwl,  const char* prefix=0);
+
+   /**
+    * @return The env wavelength units..
+    */
+   ossimString getWavelengthUnits() const;
+
+   /**
+    * Sets the envi wavelength units string.
+    * 
+    * @param wavelengthUnits envi wavelength units string.
+    */
+   void setWavelengthUnits(const ossimString& wavelenghtUnits);
+
+   /**
+    * @param bandNames Vector of strings to initialize with band names.
+    */
+   void getBandNames(vector<ossimString>& bandNames) const;
+
+   /**
+    * Sets the band name string vector.
+    * 
+    * @param bandNames Vector of band name strings.
+    */
+   void setBandNames(const vector<ossimString>& bandNames);
+
+   /**
+    * @param wavelengths Vector of strings to initialize with wave lengths.
+    */
+   void getWavelengths(vector<ossimString>& wavelengths) const;
+
+   /**
+    * Sets the envi band name string.
+    * 
+    * @param wavelengths Vector of band name strings.
+    */
+   void setWavelengths(const vector<ossimString>& wavelengths);
+
+   /**
+    * Method to the load (recreate) the state of the object from a keyword
+    * list.
+    *
+    * @param kwl Keyword list to initialize from.
+    *
+    * @param prefix Usually something like: "object1."
+    *
+    * @return This method will alway return true as it is intended to be
+    * used in conjuction with the set methods.
+    *
+    * Keywords picked up by loadState:
+    * 
+    * description: My_file
+    *
+    * number_samples: 1024
+    *
+    * number_lines: 512
+    *
+    * number_bands: 3
+    *
+    * header_offset: 0
+    *
+    * file_type: ENVI Standard
+    *
+    * data_type: 1
+    *
+    * interleave_type: bil
+    *
+    * sensor_type:  Unknown
+    *
+    * (little_endian or big_endian)
+    * byte_order: little_endian
+    * 
+    * map_info: Unkown
+    *
+    * wavelength_units: 
+    *
+    * band_name0: Red band
+    * band_name1: Green band
+    * band_name2: Blue band
+    *
+    * wavelength0:  620.25
+    * wavelength1:  514.5
+    * wavelength2:  470.0
+    */
+   bool loadState(const ossimKeywordlist& kwl, const char* prefix=0);
+
+private:
+
+   void parseDescription(std::ifstream& is);
+   void parseWavelength(std::ifstream& is);
+   void parseBandNames(std::ifstream& is);
+
+   ossimString         theDescription;
+   ossim_uint32        theSamples;
+   ossim_uint32        theLines;
+   ossim_uint32        theBands;
+   ossim_uint32        theHeaderOffset;
+   ossimString         theFileType;
+   ossim_uint32        theDataType;
+   ossimString         theInterleave;
+   ossimString         theSensorType;
+   ossimByteOrder      theByteOrder;
+   ossim_int32         theXStart;
+   ossimString         theMapInfo;
+   ossimString         theWavelengthUnits;
+   vector<ossimString> theBandName;
+   vector<ossimString> theWavelength;
+};
+#endif /* #ifndef ossimEnviHeader_HEADER */
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/ers/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/ers/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ers/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/support_data/ers/ossimERS.cpp b/Utilities/OSSIM/ossim_core/support_data/ers/ossimERS.cpp
new file mode 100644
index 0000000000..52348346ac
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ers/ossimERS.cpp
@@ -0,0 +1,603 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Chong-Ket Chuah
+// 
+// Description:
+// Implementation of ossimERS class for parsing a ER Mapper raster
+// file format header.
+//
+//********************************************************************
+// $Id: ossimERS.cpp,v 1.19 2004/10/01 15:42:10 dburken Exp $
+
+#include <fstream>
+#include <iostream>
+using namespace std;
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimTrace.h>
+#include <support_data/ers/ossimERS.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+
+static ossimTrace traceDebug("ossimERS:degug");
+
+
+ossimERS::ossimERS()
+   :
+      ossimErrorStatusInterface()
+{
+   clearFields();
+}
+
+ossimERS::ossimERS(const char* headerFile)
+   :
+      ossimErrorStatusInterface()
+{
+   clearFields();
+
+   // open the header file:
+   std::ifstream in;
+   in.open(headerFile, ios::in | ios::binary);
+
+   if (!in)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   // Begin parsing records:
+   if (!theErrorStatus)
+   {
+      parseHeader(in);
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimERS DEBUG:"
+         << *this
+         << endl;
+   }
+}
+
+void ossimERS::parseError(char *msg)
+{
+   theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+}
+
+void ossimERS::parseRasterInfo(std::istream& in)
+{
+   vector<ossimString> tokens;
+
+   bool done = false;
+   while (!done)
+   {
+      tokens = parseLine(in);
+      if (tokens.empty())
+      {
+         parseError("premature end of header file.");
+         return;
+      }
+      if (tokens[0] == "CellType")
+      {
+         if (tokens[1] == "Unsigned8BitInteger")
+         {
+            theCelltype = OSSIM_UCHAR;
+         }
+         else if (tokens[1] == "Unsigned16BitInteger")
+         {
+            theCelltype = OSSIM_USHORT16;
+         }
+         else if (tokens[1] == "Signed16BitInteger")
+         {
+            theCelltype = OSSIM_SSHORT16;
+         }
+         else if (tokens[1] == "IEEE4ByteReal")
+         {
+            theCelltype = OSSIM_FLOAT;
+         }
+         else if (tokens[1] == "IEEE8ByteReal")
+         {
+            theCelltype = OSSIM_DOUBLE;
+         }
+         else
+         {
+            parseError("Unsupported CellType.");
+         }
+      }
+      else if (tokens[0] == "NullCellValue")
+      {
+         theHasNullCells = true;
+         theNullCell = tokens[1].toInt();	 // float nullcell value?
+      }
+      else if (tokens[0] == "Xdimension")
+      {	// ignore "CellInfo"
+         theCellSizeX = tokens[1].toDouble();
+      }
+      else if (tokens[0] == "Ydimension")
+      {	// ignore "CellInfo"
+         theCellSizeY = tokens[1].toDouble();
+      }
+      else if (tokens[0] == "NrOfLines")
+      {
+         theLine = tokens[1].toInt();
+      }
+      else if (tokens[0] == "NrOfCellsPerLine")
+      {
+         theSample = tokens[1].toInt();
+      }
+      else if (tokens[0] == "Eastings")
+      {	// ignore "RegistrationCoord"
+         theTieUnitType = OSSIM_METERS;
+         theOriginX = tokens[1].toDouble();
+      }
+      else if (tokens[0] == "Northings")
+      {	// ignore "RegistrationCoord"
+         theTieUnitType = OSSIM_METERS;
+         theOriginY = tokens[1].toDouble();
+      }
+      else if (tokens[0] == "Longitude")
+      {	// ignore "RegistrationCoord"
+                                                // need to check coordinatestype ("Cannot use Latitude with UTM projection")
+         double deg, min, sec;
+         sscanf (tokens[1].chars(), "%lg:%lg:%lg", &deg, &min, &sec);
+         theOriginX = ossimAbs(deg) + min/60.0 + sec/3600.0;
+         if (deg < 0.0)
+         {
+            theOriginX = -theOriginX;
+         }
+         theTieUnitType = OSSIM_DEGREES;
+      }
+      else if (tokens[0] == "Latitude")
+      {	// ignore "RegistrationCoord"
+         double deg, min, sec;
+         sscanf (tokens[1].chars(), "%lg:%lg:%lg", &deg, &min, &sec);
+         theOriginY = ossimAbs(deg) + min/60.0 + sec/3600.0;
+         if (deg < 0.0)
+         {
+            theOriginY = -theOriginY;
+         }
+         theTieUnitType = OSSIM_DEGREES;
+      }
+      else if (tokens[0] == "NrOfBands")
+      {
+         theBands = tokens[1].toInt();
+      }
+      else if (tokens[0] == "Value")
+      {	// ignore "BandID"
+        // keep adding to the bandID vector
+        // delete Value key then join the rest of tokens
+         tokens.erase(tokens.begin());
+         ossimString id;
+         id.join(tokens, " ");
+         theBandID.push_back(id);
+      }
+      else if (tokens[0] == "RasterInfo")
+      {
+         done = true;
+      }
+   }
+}
+
+
+void ossimERS::parseCoordinateSpace(std::istream& in)
+{
+   vector<ossimString> tokens;
+
+   bool done = false;
+   while (!done)
+   {
+      tokens = parseLine(in);
+      if (tokens.empty())
+      {
+         parseError("premature end of header file.");
+         return;
+      }
+      if (tokens[0] == "Datum")
+      {
+         theDatum = tokens[1];
+         if (theDatum != "WGS84" && theDatum != "RAW")
+         {
+            parseError("Datum must be WGS84 or RAW");
+         }
+      }
+      else if (tokens[0] == "Projection")
+      {
+         theProjection = tokens[1];
+         // need to parse projection string
+         /*(EqualStrings (tok(1,3), "UTM")) {
+           coordinateSystem = 'U';
+           if (tok(0) == 'N')
+           northernHemisphere = 1;
+           else
+           northernHemisphere = 0;
+           spString zoneStr = tok(4,2);
+           sscanf (zoneStr.chars(), "%d", &zone);
+         */
+      }
+      else if (tokens[0] == "CoordinateType")
+      {
+         // ignore it
+      }
+      else if (tokens[0] == "Units")
+      {
+         // ignore it for now
+      }
+      else if (tokens[0] == "Rotation")
+      {
+         double deg, min, sec;
+         sscanf (tokens[1].chars(), "%lg:%lg:%lg", &deg, &min, &sec);
+         theRotation = deg + min/60.0 + sec/3600.0;
+      }
+      else if (tokens[0] == "CoordinateSpace")
+      {
+         done = true;
+      }
+   }
+
+   // requires more error checking on unit and rotation here
+   return;
+}
+
+void ossimERS::parseHeader(std::istream& in)
+{
+   theErrorStatus = ossimErrorCodes::OSSIM_OK;
+   char magicNumberTest[14];
+   in.read(magicNumberTest, 13);
+   if(ossimString(magicNumberTest,
+                  magicNumberTest+13) != "DatasetHeader")
+   {
+      parseError("First line must be DatasetHeader");
+      return;
+   }
+   in.seekg(0);
+   vector<ossimString> tokens = parseLine(in);
+   if(!tokens.size())
+   {
+      parseError("First line must be DatasetHeader");
+      return;
+   }
+   if (tokens[0] != "DatasetHeader")
+   {
+      parseError("First line must be DatasetHeader");
+      return;
+   }
+
+   bool done = false;
+   while (!done)
+   {
+      tokens = parseLine(in);
+      if (tokens.empty())
+      {
+         parseError("premature end of header file.");
+         return;
+      }
+      if (tokens[0] == "Version")
+      {
+         theVersion = tokens[1].toDouble();
+         if (theVersion < 4.0)
+         {
+            parseError("Version must be 4.0 or greater");
+         }
+      }
+      else if (tokens[0] == "DataSetType")
+      {
+         theDatasetType = tokens[1];
+         if (theDatasetType != "ERStorage")
+         {
+            parseError("DataSetType must be ERStorage");
+         }
+      }
+      else if (tokens[0] == "DataType")
+      {
+         theDatatype = tokens[1];
+         if (theDatatype != "Raster")
+         {
+            parseError("DataType must be Raster");
+         }
+      }
+      else if (tokens[0] == "ByteOrder")
+      {
+         theByteorder = tokens[1];
+         if (theByteorder != "MSBFirst" && theByteorder != "LSBFirst")
+         {
+            parseError("ByteOrder must either be MSBFirst or LSBFirst");
+         }
+      }
+      else if (tokens[0] == "CoordinateSpace")
+      {
+         if (tokens[1] == "Begin")
+         {
+            parseCoordinateSpace(in);
+         }
+      }
+      else if (tokens[0] == "RasterInfo")
+      {
+         if (tokens[1] == "Begin")
+         {
+            parseRasterInfo(in);
+         }
+      }
+      else if (tokens[0] == "SenseDate")
+      {
+         // ignore for now
+      }
+      else if (tokens[0] == "Comments")
+      {
+         // ignore for now
+      }
+      else if (tokens[0] == "DatasetHeader")
+      {
+         done = true;
+      }
+   }
+
+   if(theProjection.contains("GEODETIC"))
+   {
+      theTieUnitType = OSSIM_DEGREES;
+   }
+
+   return;
+}
+
+
+// read a line from the file, split it using "= \t\n" delimiters.
+// if the first token is empty, if the line begins with a tab, delete
+// the token.  The second token, the value for the key, may be quoted.
+// trim the quotes.
+vector<ossimString> ossimERS::parseLine(std::istream& in)
+{
+/*   const int bufSize = 500; */
+   ossimString line;
+   vector<ossimString> tokens;
+   bool invalidCharHit = false;
+   const int MAX_LENGTH = 10000;
+   int tempCount = 0;
+   // read a line, skipping empty line
+   while (tokens.empty()&&(in)&&(tempCount < MAX_LENGTH))
+   {
+     tempCount = 1;
+      char c = in.get();
+      while( (c != '\n')&&
+             (!in.eof())&&
+             (!invalidCharHit))
+      {
+         if(c > 0x7e)
+         {
+            invalidCharHit = true;
+         }
+         else
+         {
+            line += (char)c;
+            c = in.get();
+	    ++tempCount;
+         }
+      }
+
+      if(!invalidCharHit)
+      {
+         line.trim('\t');
+         line.trim('\n');
+         line.trim('\r');
+         line.trim(' ');
+
+         if(line != "")
+         {
+            tokens = line.split("= \t");
+            if (tokens.size() > 1)
+            {
+               tokens[1].trim('\"');
+               tokens.back().trim('\"');
+            }
+         }
+      }
+      else
+      {
+         tokens.clear();
+         return tokens;
+      }
+   }
+   if(in.bad()||(tempCount>=MAX_LENGTH))
+     {
+       tokens.clear();
+     }
+
+   return tokens;
+}
+
+
+std::ostream& ossimERS::print(std::ostream& out) const
+{
+   out << setw(30) << "\ndatasetType:      " << theDatasetType
+       << setw(30) << "\ndatatype:	  " << theDatatype
+       << setw(30) << "\nbyteorder:        " << theByteorder
+       << setw(30) << "\ncomments:         " << theComments;
+   
+   //  CoordSpace
+   out << setw(30) << "\ndatum:            " << theDatum
+       << setw(30) << "\nprojection:       " << theProjection
+       << setw(30) << "\ncoordsystype:     " << theCoordSysType
+       << setw(30) << "\nunits:            " << theUnits
+       << setw(30) << "\nrotation:         " << theRotation;
+   
+   
+   // RasterInfo
+   out << setw(30) << "\ncelltype:          " << theCelltype
+       << setw(30) << "\nhasNullcells:      " << theHasNullCells
+       << setw(30) << "\nnullcell:          " << theNullCell
+       << setw(30) << "\ncellsizeX:         " << theCellSizeX
+       << setw(30) << "\ncellsizeY:         " << theCellSizeY
+       << setw(30) << "\ntheLine:           " << theLine
+       << setw(30) << "\ntheSample:         " << theSample
+       << setw(30) << "\ntheBands:          " << theBands
+       << setw(30) << "\noriginX:           " << theOriginX
+       << setw(30) << "\noriginY:           " << theOriginY;
+   
+   for (int i=0; i<(int)theBandID.size(); i++)
+   {
+      out << "\nBandID["<<i<<"]:             " << theBandID[i];
+   }
+   
+   out << endl;
+   
+   return out;
+}
+
+bool ossimERS::toOssimProjectionGeom(ossimKeywordlist& kwl,
+                                     const char* prefix)const
+{
+   ossimString proj  = toOssimProjection();
+   ossimString datum = toOssimDatum();
+
+   if(proj == "")
+   {
+      return false;
+   }
+
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           proj.c_str(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::DATUM_KW,
+           datum.c_str(),
+           true);
+
+   // if it's UTM we have to extract out zone and hemisphere
+   // from the projection name stored by ERMapper.
+   //
+   if(proj == "ossimUtmProjection")
+   {
+      ossimString zone(theProjection.begin()+4,
+                       theProjection.end());
+      ossimString hemisphere(theProjection.begin(),
+                             theProjection.begin()+1);
+      kwl.add(prefix,
+              ossimKeywordNames::ZONE_KW,
+              zone.c_str(),
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::HEMISPHERE_KW,
+              hemisphere.c_str(),
+              true);
+   }
+
+   if(theTieUnitType == OSSIM_METERS)
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_EASTING_KW,
+              theOriginX + theCellSizeX/2,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_NORTHING_KW,
+              theOriginY - theCellSizeY/2,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+              theCellSizeX,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+              theCellSizeY,
+              true);
+
+   }
+   else if(theTieUnitType == OSSIM_DEGREES)
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LAT_KW,
+              theOriginY - theCellSizeY/2,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LON_KW,
+              theOriginX + theCellSizeX/2,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+              theCellSizeX,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+              theCellSizeY,
+              true);
+   }
+
+   return true;
+}
+
+ossimString ossimERS::toOssimProjection()const
+{
+   ossimString result = "";
+
+   if(theProjection.contains("UTM"))
+   {
+      result = "ossimUtmProjection";
+   }
+   else if(theProjection.contains("GEODETIC"))
+   {
+      result = "ossimEquDistCylProjection";
+   }
+
+   return result;
+}
+
+ossimString ossimERS::toOssimDatum()const
+{
+   ossimString result = "WGE"; // wgs 84 default datum code
+
+   if(theDatum != "WGS84")
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING Datum ossimERS::toOssimDatum: " << theDatum << " is not handled in ossimERS::toOssimDatum()\n"
+                                            << "Please notify us with the datum name so we can add it\n";
+   }
+
+   return result;
+}
+
+//***************************************************************************
+// PRIVATE METHOD: ossimERS::initialize()
+// Initializes all fields to blanks (or 0's) and null terminates strings.
+//***************************************************************************
+void ossimERS::clearFields()
+{
+//   static const char source[] = "";
+
+   theErrorStatus = ossimErrorCodes::OSSIM_OK;
+   theVersion       = 0;
+   theFilename      = "";
+   theDescription   = "";
+   theSensorname    = "";
+   theHeaderOffset = 0;
+   theDatasetType   = "";
+   theDatatype      = "";
+   theByteorder     = "";
+   theComments      = "";
+   theDatum         = "";
+   theProjection    = "";
+   theCoordSysType  = "";
+   theUnits         = "";
+   theRotation      = 0.0;
+   theCelltype      = OSSIM_SCALAR_UNKNOWN;
+   theCellsizeof    = 0;
+   theHasNullCells  = false;
+   theNullCell      = 0;
+   theCellSizeX     = 0;
+   theCellSizeY     = 0;
+   theLine       = 0;
+   theSample     = 0;
+   theOriginX       = 0;
+   theOriginY       = 0;
+   theBands      = 0;
+   theTieUnitType= OSSIM_UNIT_UNKNOWN;
+   theBandID.clear();
+
+   return;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/ers/ossimERS.h b/Utilities/OSSIM/ossim_core/support_data/ers/ossimERS.h
new file mode 100644
index 0000000000..b3653ab689
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ers/ossimERS.h
@@ -0,0 +1,89 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Chong-Ket Chuah
+//
+// Description: 
+// This class parses a ER Mapper raster file format header.
+//
+//********************************************************************
+// $Id: ossimERS.h,v 1.7 2004/10/01 15:42:10 dburken Exp $
+
+#ifndef ossimERS_HEADER
+#define ossimERS_HEADER
+#include <iostream>
+using namespace std;
+
+#include <cstdio>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+class ossimERS : public ossimErrorStatusInterface
+{
+public:
+   ossimERS(const char* file);
+   ~ossimERS() {};
+
+   void clearFields();
+   // DatasetHeader 
+   double      theVersion;
+   ossimString theFilename;
+   ossimString theDescription;
+   
+//   tm lastupdated;
+   ossimString theSensorname;
+//   tm sensedate;
+   ossim_int32       theHeaderOffset;				// for non-ermapper file
+   ossimString theDatasetType;		// ERStorage
+   ossimString theDatatype;			// Raster
+   ossimString theByteorder;			//MSBFirst or LSBFirst
+   ossimString theComments;				// arbitrary comment field
+   
+   //  CoordSpace 
+   ossimString theDatum;				/* geodetic datum */
+   ossimString theProjection;
+   ossimString theCoordSysType;
+   ossimString theUnits;
+   double      theRotation;
+
+   ossimUnitType theTieUnitType;
+   // RasterInfo 
+   ossimScalarType theCelltype;
+   ossim_int32 theCellsizeof;
+   bool theHasNullCells;
+   double theNullCell;
+   double theCellSizeX;
+   double theCellSizeY;
+   ossim_int32 theLine;
+   ossim_int32 theSample;
+   double theOriginX;
+   double theOriginY;
+   ossim_int32 theBands;
+   vector<ossimString> theBandID;
+   
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   bool toOssimProjectionGeom(ossimKeywordlist& kwl,
+                              const char* prefix=NULL)const;
+   ossimString toOssimProjection()const;
+   ossimString toOssimDatum()const;
+   ossim_int32 errorStatus() const { return theErrorStatus; }
+   
+private:
+   // prevent use
+   ossimERS();
+   void parseError(char *msg);
+   vector<ossimString> parseLine(std::istream& in);
+   void parseHeader(std::istream& fptr);
+   void parseRasterInfo(std::istream& fptr);
+   void parseCoordinateSpace(std::istream& fptr);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/esri/.cvsignore
new file mode 100644
index 0000000000..9bd48b65d7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+*.d
+*.o
+*.*~
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigBounds.cpp b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigBounds.cpp
new file mode 100644
index 0000000000..045eb7fb99
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigBounds.cpp
@@ -0,0 +1,58 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigBounds.cpp,v 1.2 2002/08/12 16:12:59 gpotts Exp $
+#include "support_data/esri/ossimAigBounds.h"
+#include "base/misc/ossimEndian.h"
+
+bool ossimAigBounds::writeStream(ostream& out)
+{
+   ossimEndian endian;
+   double tempDouble;
+   
+   if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+   {
+      tempDouble = ll_x;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+
+      tempDouble = ll_y;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+      
+      tempDouble = ur_x;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+      
+      tempDouble = ur_y;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+   }
+   else
+   {
+      out.write((char*)(&ll_x), 8);
+      out.write((char*)(&ll_y), 8);
+      out.write((char*)(&ur_x), 8);
+      out.write((char*)(&ur_y), 8);
+   }
+
+   return out.good();
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigBounds.h b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigBounds.h
new file mode 100644
index 0000000000..7e502927e5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigBounds.h
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigBounds.h,v 1.4 2002/08/27 18:25:36 gpotts Exp $
+#ifndef ossimAigBounds_HEADER
+#define ossimAigBounds_HEADER
+#include <iostream>
+
+class ossimAigBounds
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimAigBounds& data)
+      {
+         out << "ll_x:  " << data.ll_x << std::endl
+             << "ll_y:  " << data.ll_y << std::endl
+             << "ur_x:  " << data.ur_x << std::endl
+             << "ur_y:  " << data.ur_y;
+         
+         return out;
+      }
+   ossimAigBounds()
+      {
+         reset();
+      }
+
+   void reset()
+      {
+         ll_x = 0.0;
+         ll_y = 0.0;
+         ur_x = 0.0;
+         ur_y = 0.0;
+      }
+   bool writeStream(std::ostream& out);
+   double ll_x;
+   double ll_y;
+   double ur_x;
+   double ur_y;
+};
+
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigDataFileHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigDataFileHeader.cpp
new file mode 100644
index 0000000000..90532d600a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigDataFileHeader.cpp
@@ -0,0 +1,49 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigDataFileHeader.cpp,v 1.2 2003/05/13 11:31:10 dburken Exp $
+#include "support_data/esri/ossimAigDataFileHeader.h"
+#include "base/misc/ossimEndian.h"
+
+bool ossimAigDataFileHeader::writeStream(std::ostream& out)const
+{
+   ossimEndian endian;
+   ossim_uint32 tempInt;
+   
+   if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+   {
+      out.write((char*)theMagicNumber, 8);
+      out.write((char*)theZeroFill1, 16);
+      tempInt = theFileSize;
+      endian.swap(tempInt);
+      out.write((char*)(&tempInt), 4);
+      out.write((char*)theZeroFill2, 72);
+   }
+   else
+   {
+      out.write((char*)theMagicNumber, 8);
+      out.write((char*)theZeroFill1, 16);
+      out.write((char*)(&theFileSize), 8);
+      out.write((char*)theZeroFill2, 72);
+   }
+   
+   return out.good();
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigDataFileHeader.h b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigDataFileHeader.h
new file mode 100644
index 0000000000..67a9033ec5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigDataFileHeader.h
@@ -0,0 +1,179 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigDataFileHeader.h,v 1.2 2003/05/13 11:31:10 dburken Exp $
+#ifndef ossimAigDataFileHeader_HEADER
+#define ossimAigDataFileHeader_HEADER
+#include <iostream>
+#include "base/common/ossimConstants.h"
+#include <string.h>
+
+class ossimAigDataFileHeader
+{
+public:
+   ossimAigDataFileHeader()
+      {
+         reset();
+      }
+
+   void reset()
+      {
+         theMagicNumber[0] = 0x00;
+         theMagicNumber[1] = 0x00;
+         theMagicNumber[2] = 0x27;
+         theMagicNumber[3] = 0x0A;
+         theMagicNumber[4] = 0xFF;
+         theMagicNumber[5] = 0xFF;
+         theMagicNumber[6] = 0xFC;
+         theMagicNumber[7] = 0x14;
+         memset((char*)theZeroFill1,
+                0x00,
+                16);
+         memset((char*)theZeroFill2,
+                0x00,
+                72);
+         theFileSize = 50;
+      }
+   bool writeStream(std::ostream& out)const;
+   
+   ossim_uint8 theMagicNumber[8];
+   ossim_uint8 theZeroFill1[16];
+   /*!
+    *  The size of this file in number of shorts.
+    */
+   ossim_int32 theFileSize;
+   ossim_uint8 theZeroFill2[72];
+
+
+   // ________________ These fields are replicated for every tile__________
+   
+   /*!
+    * Size of this tiles data measured in
+    * shorts. This matches the size in
+    * the index file, and does not
+    * include the tile size itself. The
+    * next tile starts 2*n+2 bytes after
+    * the start of this tile, where n is the
+    * value of this field.
+    */
+      
+   ossim_int16 theTileSize;
+
+   //____________________These are from Frank's docs on the grid format
+   /*!
+    * Tile type code indicating the
+    * organization of the following data
+    * (integer coverages only).
+    *
+    * theTileType = 0x00 (constant block)
+    *               All pixels take the value of the RMin. Data is ignored.
+    *               It appears there is sometimes a bit of
+    *               meaningless data (up to four bytes) in the block.
+    *
+    * theTileType = 0x01 (raw 1bit data)
+    *
+    * theTileType = 0x04 (raw 4bit data)
+    *               One full tiles worth of data pixel values follows the
+    *               RMin field, with 4 bits per pixel. The high
+    *               order four bits of a byte comes before the
+    *               low order four bits.
+    * theTileType = 0x08 (raw byte data)
+    *               One full tiles worth of data pixel values
+    *               (one byte per pixel) follows the RMin field.
+    * theTileType = 0x10 (raw 16bit data)
+    *               One full tiles worth of data pixel values
+    *               follows the RMin field, with 16 bits per pixel (MSB).
+    * theTileType = 0xCF (16 bit literal runs/nodata runs)
+    *               The data is organized in a series of runs.
+    *               Each run starts with a marker which should be
+    *               interpreted as:
+    *                 Marker < 128: The marker is followed by Marker
+    *                                pixels of literal data with two MSB bytes
+    *                                per pixel. 
+    *                 Marker > 127: The marker indicates that 256-Marker pixels
+    *                               of no data pixels should be put into the
+    *                               output stream. No data
+    *                               (other than the next marker) follows
+    *                               this marker. 
+    * theTileType = 0xD7 (literal runs/nodata runs)
+    *               The data is organized in a series of runs.
+    *               Each run starts with a marker which should be
+    *               interpreted as:
+    *                 Marker < 128: The marker is followed by Marker pixels of
+    *                               literal data with one byte per pixel. 
+    *                 Marker > 127: The marker indicates that 256-Marker pixels
+    *                               of no data pixels should be put into the
+    *                               output stream. No data (other than the next
+    *                               marker) follows this marker.
+    * theTileType = 0xDF (RMin runs/nodata runs)
+    *               The data is organized in a series of runs.
+    *               Each run starts with a marker which should be
+    *               interpreted as: 
+    *                 Marker < 128: The marker is followed by Marker pixels of
+    *                               literal data with one byte per pixel. 
+    *                 Marker > 127: The marker indicates that 256-Marker pixels
+    *                               of no data pixels should be put into the
+    *                               output stream. No data
+    *                               (other than the next marker) follows this
+    *                               marker.
+    *                 This is similar to 0xD7, except that the data size is zero bytes instead of 1,
+    *                 so only RMin values are inserted into the output stream.
+    * theTileType = 0xE0 (run length encoded 32bit)
+    *               The data is organized in a series of runs.
+    *               Each run starts with a marker which should be
+    *               interpreted as a count. The four bytes following the count
+    *               should be interpreted as an MSB
+    *               Int32 value. They indicate that count pixels of value
+    *               should be inserted into the output stream.
+    * theTileType = 0xF0 (run length encoded 16bit)
+    *               The data is organized in a series of runs. Each run
+    *               starts with a marker which should be interpreted as a count.
+    *               The two bytes following the count should be interpreted as an MSB
+    *               Int16 value. They indicate that count pixels of value should be
+    *               inserted into the output stream.
+    * theTileType = 0xFC/0xF8 (run length encoded 8bit)
+    *               The data is organized in a series of runs.
+    *               Each run starts with a marker which should be
+    *               interpreted as a count. The following byte is the value.
+    *               They indicate that count pixels of value should be inserted
+    *               into the output stream.  The intepretation is the same for
+    *               0xFC, and 0xF8. I believe that 0xFC has a lower dynamic (2bit) range than 0xF8 (4 or 8 bit).
+    * theTileType = 0xFF (unknown)
+    *               I have yet to deduce how this is organized, though it seems to be used for data with one bit of
+    *               dynamic range. and presumably uses some sort of run length encoding. But it's operation is not
+    *               obvious despite many hours, productions of hundreds of test files, and attempts to develop a
+    *               dictionary of binary strings for different run values.
+   */
+   
+   ossim_uint8 theTileType;
+
+   /*!
+    * Number of bytes following to
+    * form the minimum value for the
+    * tile (integer coverages only). This describes
+    * the size of the next field
+    */
+   ossim_uint8 theMinSize;
+
+   ossim_int32 theMin;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigHeader.cpp
new file mode 100644
index 0000000000..986958fcd5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigHeader.cpp
@@ -0,0 +1,91 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigHeader.cpp,v 1.3 2003/05/13 11:31:10 dburken Exp $
+#include "support_data/esri/ossimAigHeader.h"
+#include "base/misc/ossimEndian.h"
+
+bool ossimAigHeader::writeStream(std::ostream& out)
+{
+   ossimEndian endian;
+   double          tempDouble;
+   ossim_uint32    tempInt;
+   
+   if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+   {
+      out.write((char*)theMagic, 8);
+      out.write((char*)theUnknownData, 8);
+      tempInt = theCellType;
+      endian.swap(tempInt);
+      out.write((char*)&tempInt, 4);
+      
+      out.write((char*)theUnknownAssortedData, 236);
+      tempDouble = thePixelSizeX;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+      tempDouble = thePixelSizeY;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+      tempDouble = 0.0;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+      out.write((char*)(&tempDouble), 8);
+
+      tempInt = theNumberOfTilesPerRow;
+      endian.swap(tempInt);
+      out.write((char*)&tempInt, 4);
+      
+      tempInt = theNumberOfTilesPerColumn;
+      endian.swap(tempInt);
+      out.write((char*)&tempInt, 4);
+
+      tempInt = theWidthOfTileInPixels;
+      endian.swap(tempInt);
+      out.write((char*)&tempInt, 4);
+
+      tempInt = theUnknownValue;
+      endian.swap(tempInt);
+      out.write((char*)&tempInt, 4);
+
+      tempInt = theHeightOfTileInPixels;
+      endian.swap(tempInt);
+      out.write((char*)&tempInt, 4);
+   }
+   else
+   {
+      out.write((char*)theMagic, 8);
+      out.write((char*)theUnknownData, 8);
+      out.write((char*)&theCellType, 4);
+      out.write((char*)theUnknownAssortedData, 236);
+      out.write((char*)(&thePixelSizeX), 8);
+      out.write((char*)(&thePixelSizeY), 8);
+      tempDouble = 0.0;
+      out.write((char*)(&tempDouble), 8);
+      out.write((char*)(&tempDouble), 8);
+      out.write((char*)&theNumberOfTilesPerRow, 4);
+      out.write((char*)&theNumberOfTilesPerColumn, 4);
+      out.write((char*)&theWidthOfTileInPixels, 4);
+      out.write((char*)&theUnknownValue, 4);
+      out.write((char*)&theHeightOfTileInPixels, 4);
+   }
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigHeader.h b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigHeader.h
new file mode 100644
index 0000000000..f8945f9211
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigHeader.h
@@ -0,0 +1,128 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigHeader.h,v 1.5 2003/05/13 11:31:10 dburken Exp $
+
+#ifndef ossimAigHeader_HEADER
+#define ossimAigHeader_HEADER
+#include <iostream>
+#include "base/common/ossimConstants.h"
+#include "string.h"
+
+class ossimAigHeader
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimAigHeader& header)
+      {
+         out << "Magic number:  " << header.theMagic << std::endl
+             << "Coverage:      " << (header.theCellType==1?"Integer":"float") << std::endl
+             << "Pixel size x:  " << header.thePixelSizeX << std::endl
+             << "Pixel size y:  " << header.thePixelSizeY << std::endl
+             << "Tiles per row: " << header.theNumberOfTilesPerRow << std::endl
+             << "Tiles per col: " << header.theNumberOfTilesPerColumn << std::endl
+             << "Tile width:    " << header.theWidthOfTileInPixels << std::endl
+             << "Tile height:   " << header.theHeightOfTileInPixels;
+         
+         return out;
+      }
+   ossimAigHeader()
+      {
+         reset();
+      }
+
+   void reset()
+      {
+         memset(theMagic, '\0', 8);
+         strcpy(theMagic, "GRID1.2");
+         memset(theUnknownData, '\0', 8);
+         setIntCoverage();
+         memset(theUnknownAssortedData, '\0', 236);
+         thePixelSizeX = 1.0;
+         thePixelSizeY = 1.0;
+         theUnknownGeoReferencingValues[0] = 0.0;
+         theUnknownGeoReferencingValues[1] = 0.0;
+         theNumberOfTilesPerRow = 0;
+         theNumberOfTilesPerColumn = 0;
+         theWidthOfTileInPixels = 0;
+         theUnknownValue = 1;
+         theHeightOfTileInPixels = 0;
+      }
+
+   bool writeStream(std::ostream& out);
+
+   void setFloatCoverage()
+      {
+         theCellType = 2;
+      }
+   void setIntCoverage()
+      {
+         theCellType = 1;
+      }
+   char theMagic[8];
+   char theUnknownData[8];
+   
+   /*!
+    * 1 means int cover and 2 means float cover
+    */
+   ossim_int32   theCellType;
+   
+   char    theUnknownAssortedData[236];
+
+   /*!
+    * Holds the width of the pixel in geo referenced
+    * coordinate.  It's 1 otherwise
+    */
+   double  thePixelSizeX;
+
+   /*!
+    * Holds the height of the pixel in geo referenced
+    * coordinate.  It's 1 otherwise
+    */
+   double  thePixelSizeY;
+
+   double  theUnknownGeoReferencingValues[2];
+
+   /*!
+    * This is the width of the file in tiles..
+    */
+   int     theNumberOfTilesPerRow;
+
+   /*!
+    * This is the height of the file in tiles..
+    */
+   int     theNumberOfTilesPerColumn;
+
+   /*!
+    * Numer of pixels wide the tile is.  Usually the value is
+    * 256
+    */
+   int     theWidthOfTileInPixels;
+   
+   int     theUnknownValue;
+
+   /*!
+    * Numer of pixels high the tile is.  Usually the value is
+    * 4
+    */
+   int     theHeightOfTileInPixels;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigIndexFileHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigIndexFileHeader.cpp
new file mode 100644
index 0000000000..48c9ebe628
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigIndexFileHeader.cpp
@@ -0,0 +1,46 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigIndexFileHeader.cpp,v 1.3 2003/05/13 11:31:10 dburken Exp $
+#include "support_data/esri/ossimAigIndexFileHeader.h"
+#include "base/misc/ossimEndian.h"
+
+bool ossimAigIndexFileHeader::writeStream(std::ostream& out)
+{
+   ossimEndian endian;
+   ossim_uint32 tempInt;
+   
+   if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+   {
+      out.write((char*)theMagicNumber, 8);
+      out.write((char*)theZeroFill1, 16);
+      tempInt = theFileSize;
+      endian.swap(tempInt);
+      out.write((char*)(&tempInt), 4);
+      out.write((char*)theZeroFill2, 72);
+   }
+   else
+   {
+      out.write((char*)(&theFileSize), 8);
+   }
+   
+   return out.good();
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigIndexFileHeader.h b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigIndexFileHeader.h
new file mode 100644
index 0000000000..92084823cc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigIndexFileHeader.h
@@ -0,0 +1,90 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigIndexFileHeader.h,v 1.4 2003/05/13 11:31:10 dburken Exp $
+#ifndef ossimAigIndexFileHeader_HEADER
+#define ossimAigIndexFileHeader_HEADER
+#include <iostream>
+#include "base/common/ossimConstants.h"
+#include <string.h>
+
+class ossimAigIndexFileHeader
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimAigIndexFileHeader& data)
+      {
+         out << "theFileSize: " << data.theFileSize;
+         
+         return out;
+      }
+   ossimAigIndexFileHeader()
+      {
+         reset();
+      }
+   void reset()
+      {
+         theMagicNumber[0] = 0x00;
+         theMagicNumber[1] = 0x00;
+         theMagicNumber[2] = 0x27;
+         theMagicNumber[3] = 0x0A;
+         theMagicNumber[4] = 0xFF;
+         theMagicNumber[5] = 0xFF;
+         theMagicNumber[6] = 0xFC;
+         theMagicNumber[7] = 0x14;
+         memset((char*)theZeroFill1,
+                0x00,
+                16);
+         memset((char*)theZeroFill2,
+                0x00,
+                72);
+         theFileSize = 50;
+      }
+   bool writeStream(std::ostream& out);
+
+   ossim_uint8 theMagicNumber[8];
+
+   ossim_uint8 theZeroFill1[16];
+   /*!
+    *  The size of this file in number of shorts.
+    */
+   ossim_int32 theFileSize;
+
+   ossim_uint8 theZeroFill2[72];
+
+
+   /*!
+    *  The next two fields that follow are replicated the number
+    * of tiles in the file.  These two fields holds the offset of the tile
+    * in the data file and the size of the tile in the data file( both are in
+    * shorts and not bytes);
+    */
+// 100 + t*8 
+//           4 
+//                     MSB Int32 
+//                              Offset to tile t in w001001.adf measured in two byte
+//                              shorts. 
+// 104 + t*8 
+//           4 
+//                     MSB Int32 
+//                              Size of tile t in 2 byte shorts.   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigStatistics.cpp b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigStatistics.cpp
new file mode 100644
index 0000000000..dae14176af
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigStatistics.cpp
@@ -0,0 +1,58 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigStatistics.cpp,v 1.1 2002/08/12 15:26:04 gpotts Exp $
+#include "base/misc/ossimEndian.h"
+#include "support_data/esri/ossimAigStatistics.h"
+
+bool ossimAigStatistics::writeStream(ostream& out)
+{
+   ossimEndian endian;
+   double tempDouble;
+   
+   if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+   {
+      tempDouble = theMin;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+
+      tempDouble = theMax;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+      
+      tempDouble = theMean;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+      
+      tempDouble = theStandardDev;
+      endian.swap(tempDouble);
+      out.write((char*)(&tempDouble), 8);
+   }
+   else
+   {
+      out.write((char*)(&theMin), 8);
+      out.write((char*)(&theMax), 8);
+      out.write((char*)(&theMean), 8);
+      out.write((char*)(&theStandardDev), 8);
+   }
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigStatistics.h b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigStatistics.h
new file mode 100644
index 0000000000..56f5f32fa8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/esri/ossimAigStatistics.h
@@ -0,0 +1,51 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts  (gpotts@imagelinks.com)
+//
+//*******************************************************************
+// $Id: ossimAigStatistics.h,v 1.1 2002/08/12 15:26:04 gpotts Exp $
+#ifndef ossimAigStatistics_HEADER
+#define ossimAigStatistics_HEADER
+#include <iostream>
+
+class ossimAigStatistics
+{
+public:
+   ossimAigStatistics()
+      {
+         reset();
+      }
+
+   void reset()
+      {
+         theMin         = 0.0;
+         theMax         = 0.0;
+         theMean        = 0.0;
+         theStandardDev = 0.0;
+      }
+
+   bool writeStream(ostream& out);
+
+   double theMin;
+   double theMax;
+   double theMean;
+   double theStandardDev;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/fcsi/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/fcsi/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/fcsi/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/support_data/fcsi/ossimApplanixEOFile.cpp b/Utilities/OSSIM/ossim_core/support_data/fcsi/ossimApplanixEOFile.cpp
new file mode 100644
index 0000000000..667fcc5f99
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/fcsi/ossimApplanixEOFile.cpp
@@ -0,0 +1,690 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LGPL
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimApplanixEOFile.cpp,v 1.9 2005/10/03 16:57:55 gpotts Exp $
+#include "ossimApplanixEOFile.h"
+#include <iterator>
+#include <fstream>
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimRegExp.h>
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug("ossimApplanixEOFile:debug");
+
+static std::istream& applanix_skipws(std::istream& in)
+{
+   int c = in.peek();
+   while(((c == ' ') ||
+          (c == '\r') ||
+          (c == '\t') ||
+          (c == '\n'))&&
+         (in.good()))
+   {
+      in.ignore(1);
+      c = in.peek();
+   }
+   
+   return in;
+}
+
+std::ostream& operator <<(std::ostream& out, const ossimApplanixEORecord& src)
+{
+   if(src.theField.size())
+   {
+      std::copy(src.theField.begin(),
+                src.theField.end(),
+                std::ostream_iterator<ossimString>(out, " "));
+   }
+
+   return out;
+}
+
+std::ostream& operator <<(std::ostream& out, const ossimApplanixEOFile& src)
+{
+   ossim_uint32 idx = 0;
+   out << src.theHeader << std::endl << std::endl;
+
+   if(src.theRecordFormat.size())
+   {
+      std::copy(src.theRecordFormat.begin(),
+                --src.theRecordFormat.end(),
+                std::ostream_iterator<ossimString>(out, ", "));
+      out << *(--src.theRecordFormat.end());
+      out << std::endl;
+   }
+
+   out << "Kappa Cardinal Rotation = " << src.theKappaCardinal << std::endl;
+   out << "Bore Sight tx = " << src.theBoreSightTx << std::endl
+       << "Bore Sight ty = " << src.theBoreSightTy << std::endl
+       << "Bore Sight tz = " << src.theBoreSightTz << std::endl;
+   
+   out << "Lever arm lx = " << src.theLeverArmLx << std::endl
+       << "Lever arm ly = " << src.theLeverArmLy << std::endl
+       << "Lever arm lz = " << src.theLeverArmLz << std::endl;
+   
+   out << "Shift Value X = " << src.theShiftValuesX << std::endl
+       << "Shift Value Y = " << src.theShiftValuesY << std::endl
+       << "Shift Value Z = " << src.theShiftValuesZ << std::endl;
+   
+   out << "Mapping Frame Datum      = " << src.theMappingFrameDatum      << std::endl
+       << "Mapping Frame Projection = " << src.theMappingFrameProjection << std::endl
+       << "Central Meridian         = " << src.theCentralMeridian << std::endl
+       << "Origin of Latitude       = " << src.theOriginLatitude  << std::endl
+       << "Grid Scale Factor        = " << src.theGridScaleFactor << std::endl
+       << "False easting            = " << src.theFalseEasting    << std::endl
+       << "False northing           = " << src.theFalseNorthing   << std::endl;
+
+   out << "theUtmZone               = " << src.theUtmZone << std::endl;
+   out << "theUtmHemisphere         = " << src.theUtmHemisphere << std::endl;
+   
+   if(src.theApplanixRecordList.size())
+   {
+      out << std::endl;
+      for(idx = 0; idx < src.theApplanixRecordList.size()-1; ++idx)
+      {
+         out << *(src.theApplanixRecordList[idx]) << std::endl;
+      }
+      out << *(src.theApplanixRecordList[idx]);
+      
+   }
+
+   return out;
+}
+
+ossimApplanixEOFile::ossimApplanixEOFile()
+{
+   theMinLat = OSSIM_DBL_NAN;
+   theMinLon = OSSIM_DBL_NAN;
+   theMaxLat = OSSIM_DBL_NAN;
+   theMaxLon = OSSIM_DBL_NAN;
+}
+
+bool ossimApplanixEOFile::parseFile(const ossimFilename& file)
+{
+   ifstream in(file.c_str());
+
+   return parseStream(in);
+}
+
+bool ossimApplanixEOFile::isEOFile(const ossimFilename& file)const
+{
+   ifstream in(file.c_str());
+
+   return isEOFile(in);
+}
+
+bool ossimApplanixEOFile::isEOFile(std::istream& in)const
+{
+   ossimString header;
+
+   return parseHeader(in, header);
+}
+
+
+bool ossimApplanixEOFile::parseStream(std::istream& in)
+{
+   theRecordIdMap.clear();
+   ossimString line;
+   int c = '\0';
+   if(!parseHeader(in, theHeader))
+   {
+      return false;
+   }
+
+   // now parse parameters
+   in>>applanix_skipws;
+   line = "";
+   while(in.good()&&
+         !line.contains("RECORD FORMAT"))
+   {
+      std::getline(in, line);
+      line = line.upcase();
+      line = line.substitute("\r","\n", true);
+      if(line.contains("KAPPA CARDINAL"))
+      {
+         theKappaCardinal = line;
+         theKappaCardinal = theKappaCardinal.substitute("KAPPA CARDINAL ROTATION","");
+         theKappaCardinal = theKappaCardinal.substitute(":","");
+         theKappaCardinal = theKappaCardinal.substitute("\n","");
+      }
+      else if(line.contains("LEVER ARM"))
+      {
+         ossimKeywordlist kwl('=');
+         line = line.substitute("LEVER ARM VALUES:",
+                                "");
+         line = line.substitute(",",
+                                "\n",
+                                true);
+         istringstream in(line);
+
+         kwl.parseStream(in);
+
+         theLeverArmLx = kwl.find("LX");
+         theLeverArmLy = kwl.find("LY");
+         theLeverArmLz = kwl.find("LZ");
+      }
+      else if(line.contains("BORESIGHT VALUES"))
+      {
+         ossimKeywordlist kwl('=');
+         line = line.substitute("BORESIGHT VALUES:",
+                                "");
+         line = line.substitute(",",
+                                "\n",
+                                true);
+
+         istringstream in(line);
+
+         kwl.parseStream(in);
+
+         
+         theBoreSightTx = kwl.find("TX");
+         theBoreSightTy = kwl.find("TY");
+         theBoreSightTz = kwl.find("TZ");
+      }
+      else if(line.contains("SHIFT VALUES:"))
+      {
+         ossimKeywordlist kwl('=');
+         line = line.substitute("SHIFT VALUES:","");
+         line = line.substitute(",",
+                                "\n",
+                                true);
+
+         istringstream in(line);
+         kwl.parseStream(in);
+
+         
+         theShiftValuesX = kwl.find("X");
+         theShiftValuesY = kwl.find("Y");
+         theShiftValuesZ = kwl.find("Z");
+         
+      }
+      else if(line.contains("GRID:"))
+      { 
+         ossimKeywordlist kwl(':');
+         line = line.substitute(";",
+                                "\n",
+                                true);
+         istringstream in(line);
+         kwl.parseStream(in);
+         theUtmZone = kwl.find("ZONE");
+
+         if(theUtmZone.contains("NORTH"))
+         {
+            theUtmHemisphere = "North";
+         }
+         else
+         {
+            theUtmHemisphere = "South";
+         }
+          theUtmZone = theUtmZone.replaceAllThatMatch("UTM|\\(.*\\)|NORTH|SOUTH","");
+          theUtmZone = theUtmZone.trim();
+      }
+      else if(line.contains("FRAME DATUM"))
+      {
+         ossimKeywordlist kwl(':');
+         line = line.substitute(";",
+                                "\n",
+                                true);
+         istringstream in(line);
+         kwl.parseStream(in);
+
+         theMappingFrameDatum = kwl.find("MAPPING FRAME DATUM");
+         theMappingFrameProjection = kwl.find("MAPPING FRAME PROJECTION");
+         theMappingFrameDatum = theMappingFrameDatum.trim();
+         theMappingFrameProjection = theMappingFrameProjection.trim();
+      }
+      else if(line.contains("POSPROC SBET"))
+      {
+         theSbetField = line.after(":");
+         theSbetField = theSbetField.trim();
+      }
+      else if(line.contains("CENTRAL MERIDIAN"))
+      {
+         theCentralMeridian = line;
+         theCentralMeridian = theCentralMeridian.substitute("CENTRAL MERIDIAN","");
+         theCentralMeridian = theCentralMeridian.substitute("=","");
+         theCentralMeridian = theCentralMeridian.substitute("DEG","");
+         theCentralMeridian = theCentralMeridian.substitute(";","");
+      }
+      else if(line.contains("LATITUDE OF THE GRID ORIGIN"))
+      {
+         ossimKeywordlist kwl('=');
+         line = line.substitute(";",
+                                "\n",
+                                true);
+         istringstream in(line);
+         kwl.parseStream(in);
+
+         theOriginLatitude  = kwl.find("LATITUDE OF THE GRID ORIGIN");
+         theGridScaleFactor = kwl.find("GRID SCALE FACTOR");
+      }
+      else if(line.contains("FALSE EASTING"))
+      {
+         ossimKeywordlist kwl('=');
+         line = line.substitute(";",
+                                "\n",
+                                true);
+         istringstream in(line);
+         kwl.parseStream(in);
+
+         theFalseEasting  = kwl.find("FALSE EASTING");
+         theFalseNorthing = kwl.find("FALSE NORTHING");
+      }
+   }
+
+   in>>applanix_skipws;
+
+   c = in.get();
+
+   std::vector<ossimString> fieldArray;
+   ossimString field;
+
+   while(in.good()&&
+         (c!='\n')&&
+         (c!='\r'))
+   {
+      field = "";
+      while((c != ',')&&
+            (c != '\n')&&
+            (c != '\r'))
+      {
+         field += (char)c;
+         c = in.get();
+      }
+      if((c!='\n')&&
+         (c!='\r'))
+      {
+         c = in.get();
+      }
+      field = field.trim();
+      if(field != "")
+      {
+         theRecordFormat.push_back(field);
+      }
+   }
+   in>>applanix_skipws;
+
+   if(in.peek() == '(')
+   {
+      std::getline(in, line);
+   }
+   in>>applanix_skipws;
+   ossimRefPtr<ossimApplanixEORecord> record = new ossimApplanixEORecord(theRecordFormat.size());
+   ossim_int32 latIdx = getFieldIdx("LAT");
+   ossim_int32 lonIdx = getFieldIdx("LONG");;
+   bool hasLatLon = (latIdx >=0)&&(lonIdx >= 0);
+
+   
+   if(hasLatLon)
+   {
+      theMinLat = 90.0;
+      theMaxLat = -90.0;
+      theMinLon = 180.0;
+      theMaxLon = -180.0;
+   }
+   else
+   {
+      theMinLat = OSSIM_DBL_NAN;
+      theMaxLat = OSSIM_DBL_NAN;
+      theMinLon = OSSIM_DBL_NAN;
+      theMaxLon = OSSIM_DBL_NAN;
+   }
+   
+   while(in.good()&&theRecordFormat.size())
+   {
+      std::getline(in, line);
+      line = line.trim();
+      if(line != "")
+      {
+         std::istringstream inStr(line);
+         ossim_uint32 idx;
+         ossimString value;
+
+         for(idx = 0; idx < theRecordFormat.size(); ++idx)
+         {
+            inStr >> (*record)[idx];
+         }
+         if(hasLatLon)
+         {
+            double lat = (*record)[latIdx].toDouble();
+            double lon = (*record)[lonIdx].toDouble();
+
+            if(lat<theMinLat) theMinLat = lat;
+            if(lat>theMaxLat) theMaxLat = lat;
+            if(lon<theMinLon) theMinLon = lon;
+            if(lon>theMaxLon) theMaxLon = lon;
+            
+         }
+         theApplanixRecordList.push_back(new ossimApplanixEORecord(*record));
+      }
+   }
+   indexRecordIds();
+
+   if(traceDebug())
+   {
+      if(hasLatLon)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "min lat: " << theMinLat << std::endl
+                                             << "min lon: " << theMinLon << std::endl
+                                             << "max lat: " << theMaxLat << std::endl
+                                             << "max lon: " << theMaxLon << std::endl;
+      }
+   }
+   return true;
+}
+
+bool ossimApplanixEOFile::parseHeader(const ossimFilename& file,
+                                      ossimString& header)const
+{
+   ifstream in(file.c_str());
+
+   return parseHeader(in, header);
+}
+
+bool ossimApplanixEOFile::parseHeader(std::istream& in,
+                                      ossimString& header)const
+{
+   header = "";
+   in >> applanix_skipws;
+
+   int c = in.peek();
+   
+   if((c!='*')||
+      (!in.good()))
+   {
+      return false;
+   }
+   ossimString line;
+
+   std::getline(in, line);
+   line = line .substitute("\r",
+                           "\n");
+   if(!line.contains("************"))
+   {
+      return false;
+   }
+
+   header = line;
+   header += "\n";
+
+   in>>applanix_skipws;
+   std::getline(in, line);
+   line = line .substitute("\r",
+                           "\n");
+   
+   while((in.good())&&
+         (!line.contains("***********")))
+   {
+      header += line;
+      header += "\n";
+      std::getline(in, line);
+      line = line .substitute("\r",
+                              "\n");
+   }
+   header += line;
+   header += "\n";
+
+   if(!header.contains("Applanix"))
+   {
+      return false;
+   }
+   
+   return true;
+}
+
+void ossimApplanixEOFile::indexRecordIds()
+{
+   ossimString id;
+   ossim_uint32 idx;
+   ossim_int32 idIdx = getFieldIdxLike("ID");
+   ossim_uint32 size = theApplanixRecordList.size();
+   theRecordIdMap.clear();
+
+   if(idIdx < 0) return;
+
+   for(idx = 0; idx < size; ++idx)
+   {
+      id = (*theApplanixRecordList[idx])[idIdx];
+      theRecordIdMap.insert(std::make_pair(id, theApplanixRecordList[idx]));
+   }
+}
+
+ossim_int32 ossimApplanixEOFile::getFieldIdxLike(const ossimString& searchKey)const
+{
+   ossimString key = searchKey;
+   ossim_uint32 idx = 0;
+   key = key.upcase();
+
+   for(idx = 0; idx < theRecordFormat.size(); ++idx)
+   {
+      if(ossimString::upcase(theRecordFormat[idx]).contains(key))
+      {
+         return (int)idx;
+      }
+   }
+
+   return -1;
+}
+
+ossim_int32 ossimApplanixEOFile::getFieldIdx(const ossimString& searchKey)const
+{
+   ossimString key = searchKey;
+   ossim_uint32 idx = 0;
+   
+   key = key.upcase();
+
+   for(idx = 0; idx < theRecordFormat.size(); ++idx)
+   {
+      if(ossimString::upcase(theRecordFormat[idx]) == key)
+      {
+         return (int)idx;
+      }
+   }
+   
+   return -1;
+}
+
+
+const ossimRefPtr<ossimApplanixEORecord> ossimApplanixEOFile::getRecordGivenId(const ossimString& id)const
+{
+
+   if(theRecordIdMap.size())
+   {
+      std::map<ossimString, ossimRefPtr<ossimApplanixEORecord> >::const_iterator iter = theRecordIdMap.find(id);
+      
+      if(iter!=theRecordIdMap.end())
+      {
+         return iter->second;
+      }
+   }
+   else
+   {
+      ossim_uint32 idx;
+      ossim_int32 idxId = getFieldIdx("ID");
+      
+      if(idxId >= 0)
+      {
+         for(idx = 0; idx < theApplanixRecordList.size(); ++idx)
+         {
+            if((*theApplanixRecordList[idx])[idxId] == id)
+            {
+               return theApplanixRecordList[idx];
+            }
+         }
+      }
+   }
+   
+   return 0;
+}
+
+ossim_uint32 ossimApplanixEOFile::getNumberOfRecords()const
+{
+   return theApplanixRecordList.size();
+}
+
+const ossimRefPtr<ossimApplanixEORecord> ossimApplanixEOFile::getRecord(ossim_uint32 idx)const
+{
+   if(idx < theApplanixRecordList.size())
+   {
+      return theApplanixRecordList[idx];
+   }
+   
+   return 0;
+}
+
+bool ossimApplanixEOFile::isHeightAboveMSL()const
+{
+   return (getFieldIdx("ORTHOMETRIC HEIGHT") >= 0);
+}
+
+bool ossimApplanixEOFile::isEcefModel()const
+{
+   ossim_int32 xIdx = getFieldIdx("X");
+   ossim_int32 yIdx = getFieldIdx("Y");
+   ossim_int32 zIdx = getFieldIdx("Z");
+   ossim_int32 rollIdx = getFieldIdx("ROLL");
+   ossim_int32 pitchIdx = getFieldIdx("PITCH");
+   ossim_int32 headingIdx = getFieldIdx("HEADING");
+
+   return ((xIdx >=0)&&
+           (yIdx >=0)&&
+           (zIdx >=0)&&
+           (rollIdx>=0)&&
+           (pitchIdx>=0)&&
+           (headingIdx>=0));
+}
+
+
+bool ossimApplanixEOFile::isUtmFrame()const
+{
+   return ((getFieldIdxLike("EASTING")>=0)&&
+            (getFieldIdxLike("NORTHING") >=0)&&
+            (getFieldIdxLike("HEIGHT") >= 0)&&
+            (getFieldIdxLike("OMEGA") >=0)&&
+            (getFieldIdxLike("PHI") >=0)&&
+            (getFieldIdxLike("KAPPA") >=0));
+            
+   return (getUtmZone() >= 0.0);
+}
+
+ossim_int32 ossimApplanixEOFile::getUtmZone()const
+{
+   return theUtmZone.toInt32();
+}
+
+ossimString ossimApplanixEOFile::getUtmHemisphere()const
+{
+   return theUtmHemisphere;
+}
+
+ossimString ossimApplanixEOFile::getSbetField()const
+{
+   return theSbetField;
+}
+
+double ossimApplanixEOFile::getBoreSightTx()const
+{
+   return theBoreSightTx.toDouble();
+}
+
+double ossimApplanixEOFile::getBoreSightTy()const
+{
+   return theBoreSightTy.toDouble();
+}
+
+double ossimApplanixEOFile::getBoreSightTz()const
+{
+   return theBoreSightTz.toDouble();
+}
+
+double ossimApplanixEOFile::getLeverArmLx()const
+{
+   return theLeverArmLx.toDouble();
+}
+
+double ossimApplanixEOFile::getLeverArmLy()const
+{
+   return theLeverArmLy.toDouble();
+}
+
+double ossimApplanixEOFile::getLeverArmLz()const
+{
+   return theLeverArmLz.toDouble();
+}
+
+double ossimApplanixEOFile::getKardinalKappa()const
+{
+   return theKappaCardinal.toDouble();
+}
+
+double ossimApplanixEOFile::getShiftValuesX()const
+{
+   return theShiftValuesX.toDouble();
+}
+
+double ossimApplanixEOFile::getShiftValuesY()const
+{
+   return theShiftValuesY.toDouble();
+}
+
+double ossimApplanixEOFile::getShiftValuesZ()const
+{
+   return theShiftValuesZ.toDouble();
+}
+
+ossimString ossimApplanixEOFile::getMappingFrameDatum()const
+{
+   return theMappingFrameDatum;
+}
+
+ossimString ossimApplanixEOFile::getMappingFrameProjection()const
+{
+   return theMappingFrameProjection;
+}
+
+double ossimApplanixEOFile::getMappingFrameCentralMeridian()const
+{
+   return theCentralMeridian.toDouble();
+}
+
+double ossimApplanixEOFile::getMappingFrameOriginLatitude()const
+{
+   return theOriginLatitude.toDouble();
+}
+
+double ossimApplanixEOFile::getMappingFrameGridScaleFactor()const
+{
+   return theGridScaleFactor.toDouble();
+}
+
+double ossimApplanixEOFile::getMappingFrameFalseEasting()const
+{
+   return theFalseEasting.toDouble();
+}
+
+double ossimApplanixEOFile::getMappingFrameFalseNorthing()const
+{
+   return theFalseNorthing.toDouble();
+}
+
+ossimString ossimApplanixEOFile::convertToOssimDatumCode(const ossimString& datum)const
+{
+   ossimString result = "WGE";
+   ossimString temp = datum;
+   temp = temp.upcase();
+
+   if(temp == "NAD83")
+   {
+      result = "NAR-C";
+   }
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/fcsi/ossimApplanixEOFile.h b/Utilities/OSSIM/ossim_core/support_data/fcsi/ossimApplanixEOFile.h
new file mode 100644
index 0000000000..66228658cf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/fcsi/ossimApplanixEOFile.h
@@ -0,0 +1,208 @@
+//*******************************************************************
+// Copyright (C) 2005 Garrett Potts
+//
+// LGPL
+// 
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimApplanixEOFile.h,v 1.9 2005/10/03 16:57:55 gpotts Exp $
+#ifndef ossimApplanixEOFile_HEADER
+#define ossimApplanixEOFile_HEADER
+#include <iostream>
+#include <map>
+#include <vector>
+#include <base/common/ossimReferenced.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/data_types/ossimFilename.h>
+
+class OSSIM_DLL ossimApplanixEORecord : public ossimReferenced
+{
+public:
+   OSSIM_DLL friend std::ostream& operator <<(std::ostream& out, const ossimApplanixEORecord& src);
+   ossimApplanixEORecord(const ossimApplanixEORecord& src)
+      :theField(src.theField)
+   {
+   }
+   ossimApplanixEORecord(ossim_uint32 size=0)
+   {
+      setSize(size);
+   }
+
+   void setSize(ossim_uint32 size)
+   {
+      theField.resize(size);
+   }
+   const ossimString& operator [](ossim_uint32 idx)const
+   {
+      return theField[idx];
+   }
+   ossimString& operator [](ossim_uint32 idx)
+   {
+      return theField[idx];
+   }
+
+   std::vector<ossimString> theField;
+};
+
+class OSSIM_DLL ossimApplanixEOFile : public ossimReferenced
+{
+public:
+   OSSIM_DLL friend std::ostream& operator <<(std::ostream& out, const ossimApplanixEOFile& src);
+   ossimApplanixEOFile();
+
+   /**
+    * Will parse the entire Exterior orientation file and then index any record
+    * ID's found.  This calls the parseStream method.
+    *
+    * @param file  The exterior orientation file
+    */ 
+   bool parseFile(const ossimFilename& file);
+
+   /**
+    * Will parse the stream and set internal queriable parameters.
+    * @param inThe input stream containing the Applanix format exterior orientation file
+    * 
+    */
+   bool parseStream(std::istream& in);
+   
+
+   /**
+    * Utility method that just checks for an APPlanix exterior orientation header.
+    * Will call the isEOFile(istream) method.
+    *
+    * @param file theExterior orientation file.
+    */ 
+   bool isEOFile(const ossimFilename& file)const;
+
+   /**
+    * Utility method that just checks for an APPlanix exterior orientation header.
+    */ 
+   bool isEOFile(std::istream& in)const;
+
+   /**
+    * Parses the header of the exterior orientation file.
+    * Calls the parseHeader(istream, header) method.
+    *
+    * @param file The filename that is an Applanix Exterior orientation file.
+    * @param header The resulting header that was parsed out.
+    */
+   bool parseHeader(const ossimFilename& file,
+                    ossimString& header)const;
+
+   /**
+    * Parses the header of the exterior orientation file.
+    * Calls the parseHeader(istream, header) method.
+    *
+    * @param in The input stream That contains an exterior orientation 
+    * @param header The resulting header that was parsed out.
+    */
+   bool parseHeader(std::istream& in,
+                    ossimString& header)const;
+
+   /**
+    * Is a case insensitive parse of the column names for the orientation
+    * record.  Note this will check to see if the search key is contained
+    * within any column heading.  So if a Heading has something like
+    * "ID MORE TEXT"  then you can call this with just "ID" and get a match
+    *
+    * @param searchKey  the substring to search for
+    * @return The id of the column or -1 if can't find the column
+    */
+   ossim_int32 getFieldIdxLike(const ossimString& searchKey)const;
+   
+   
+   /**
+    * Is a case insensitive parse of the column names for the orientation
+    * record.  Note this will check to see if the search key exactly matches
+    * a column heading.  So if a Heading has something like
+    * "ID MORE TEXT"  then you can call this with just "ID MORE TEXT" to have a match
+    *
+    * @param searchKey  the substring to search for
+    *
+    * @return The id of the column or -1 if can't find the column
+    */
+   ossim_int32 getFieldIdx(const ossimString& searchKey)const;
+   
+   /** 
+    * Will index all records based on the "ID #" field for fast searching.
+    */ 
+   void indexRecordIds();
+
+   /**
+    *  Given an ID it will search and find an EO record that matches the ID.
+    *
+    *  If the records are not indexed it will do a linear search on the record array.
+    *
+    *  @param id  The id of the record to find.
+    *  
+    *  @return The exterior orientation for that record.
+    */
+   const ossimRefPtr<ossimApplanixEORecord> getRecordGivenId(const ossimString& id)const;
+
+   ossim_uint32 getNumberOfRecords()const;
+   const ossimRefPtr<ossimApplanixEORecord> getRecord(ossim_uint32 idx)const;
+      
+   bool isHeightAboveMSL()const;
+   bool isEcefModel()const;
+   bool isUtmFrame()const;
+   ossim_int32 getUtmZone()const;
+   ossimString getUtmHemisphere()const;
+
+   ossimString getSbetField()const;
+   double getBoreSightTx()const;
+   double getBoreSightTy()const;
+   double getBoreSightTz()const;
+   double getLeverArmLx()const;
+   double getLeverArmLy()const;
+   double getLeverArmLz()const;
+   double getKardinalKappa()const;
+   double getShiftValuesX()const;
+   double getShiftValuesY()const;
+   double getShiftValuesZ()const;
+
+   ossimString getMappingFrameDatum()const;
+   ossimString getMappingFrameProjection()const;
+   double getMappingFrameCentralMeridian()const;
+   double getMappingFrameOriginLatitude()const;
+   double getMappingFrameGridScaleFactor()const;
+   double getMappingFrameFalseEasting()const;
+   double getMappingFrameFalseNorthing()const;
+
+   ossimString convertToOssimDatumCode(const ossimString& datum)const;
+   
+protected:
+   ossimString theHeader;
+   ossimString theVersion;
+   ossimString theBoreSightTx;
+   ossimString theBoreSightTy;
+   ossimString theBoreSightTz;
+   ossimString theKappaCardinal;
+   ossimString theLeverArmLx;
+   ossimString theLeverArmLy;
+   ossimString theLeverArmLz;
+   ossimString theShiftValuesX;
+   ossimString theShiftValuesY;
+   ossimString theShiftValuesZ;
+   ossimString theSbetField;
+
+   ossimString theMappingFrameDatum;
+   ossimString theMappingFrameProjection;
+   ossimString theCentralMeridian;
+   ossimString theOriginLatitude;
+   ossimString theGridScaleFactor;
+   ossimString theFalseEasting;
+   ossimString theFalseNorthing;
+   ossimString theUtmZone;
+   ossimString theUtmHemisphere;
+
+   ossim_float64 theMinLat;
+   ossim_float64 theMinLon;
+   ossim_float64 theMaxLat;
+   ossim_float64 theMaxLon;
+   std::vector<ossimString> theRecordFormat;
+   std::vector< ossimRefPtr<ossimApplanixEORecord> > theApplanixRecordList;
+   std::map<ossimString, ossimRefPtr<ossimApplanixEORecord> > theRecordIdMap;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_l7/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/ff_l7/.cvsignore
new file mode 100644
index 0000000000..7df3918588
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_l7/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+Makefile
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL5.cpp b/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL5.cpp
new file mode 100644
index 0000000000..6a057821a5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL5.cpp
@@ -0,0 +1,183 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Oscar Kramer (SoBe Software)
+// Description: Container class for LandSat7 Fast Format header files.
+//
+// ********************************************************************
+// $Id: ossimFfL5.cpp,v 1.1 2005/11/10 15:03:51 gpotts Exp $
+//
+#include <cstdlib>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <iomanip>
+using namespace std;
+#include <time.h>
+
+#include <base/data_types/ossimString.h>
+#include <base/common/ossimDate.h>
+#include <support_data/ff_l7/ossimFfL5.h>
+#include <base/context/ossimNotifyContext.h>
+#include <support_data/ff_revb/ossimFfRevb.h>
+
+ossimFfL5::ossimFfL5()
+   : ossimFfL7()
+{
+}
+
+ossimFfL5::ossimFfL5(const char* headerFile)
+   : ossimFfL7()    
+{   
+   // open the header file:
+   readHeaderRevB(headerFile);  
+}
+
+ossimFfL5::~ossimFfL5()
+{
+}
+
+
+void ossimFfL5::readHeaderRevB(const ossimString& header_name)
+{
+   theErrorStatus = ossimErrorCodes::OSSIM_ERROR; // assume error, prove not at end;
+   
+   ossimFfRevb h(header_name);
+   if (h.errorStatus() != ossimFfRevb::OSSIM_OK) return;
+   
+   strcpy(theRequestNumber,   h.theProductOrderNumber);
+   strcpy(theLocationCode,    h.thePathRowNumber);
+   strcpy(theAcquisitionDate, h.theAcquisitionDate);
+   strcpy(theSatName,         h.theSatNumber);
+   strcpy(theSensorName,      h.theInstrumentType);
+   strcpy(theSensorMode,      "");
+   theOffNadirAngle =         h.theOrientationAngle;
+   strcpy(theProductType,     h.theProductType);
+   strcpy(theProductSize,     h.theProductSize);
+   strcpy(theProcessingType,  h.theProcessingType);
+   strcpy(theResampAlgorithm, h.theResampAlgorithm);
+   thePixelsPerLine         = h.thePixelsPerLine;
+   theLinesPerBand          = h.theLinesPerImage;
+   theRecordSize            = h.theRecordSize;
+   theGsd                   = h.theGsd;
+   theOutputBitsPerPixel    = 8;
+   theAcquiredBitsPerPixel  = 8;
+   strcpy(theBandsPresentString, h.theBandsPresentString);
+   
+   //generate band names   
+   int i=0;
+   while((theBandsPresentString[i]>='0') && (theBandsPresentString[i]<='9'))
+   {
+      sprintf(theBandFileNames[i],"band%c.dat",theBandsPresentString[i]);
+      ++i;
+   }
+   int nbb=i;
+
+   std::vector<ossimString> arrayPathRow = ossimString(theLocationCode).split("/");
+   if(arrayPathRow.size() == 2)
+   {
+      thePathNumber = arrayPathRow[0].toInt();
+      theRowNumber = arrayPathRow[1].beforePos(3).toInt();
+   }
+   
+   //extract gains/biases from max/min radiance
+   double min,max;
+   theBias.clear();
+   theGain.clear();
+   for(i=0;i<nbb;++i)
+   {
+      if (sscanf( h.theBandRadiance[i]," %lf/%lf",&max,&min) != 2) return;
+      theBias.push_back(min);
+      theGain.push_back(max/254.0-min/255.0);
+   }
+   
+   strcpy(theMapProjectionName      ,h.theMapProjName);
+   strcpy(theEllipsoid              ,h.theEllipsoid); 
+   strcpy(theDatum, "WGS-84");
+
+   // added to read in all 15 parameters instead of the first two.
+   
+   for(long parameter=0;parameter < 15; ++parameter)
+   {
+      ossimString temp(h.theUsgsProjParam[parameter]);
+      theProjectionParams[parameter] = temp.gsub('D','E').toDouble();
+   }
+   
+   theUsgsMapZone            = h.theUsgsMapZone;
+   
+   char temps[256];
+   sprintf(temps,"%s %s",h.theUlLon, h.theUlLat);
+   if (convertGeoPoint(temps, theUL_Corner) != ossimErrorCodes::OSSIM_OK) return;
+   
+   sprintf(temps,"%s %s",h.theUrLon, h.theUrLat);
+   if (convertGeoPoint(temps, theUR_Corner) != ossimErrorCodes::OSSIM_OK) return;
+   
+   sprintf(temps,"%s %s",h.theLrLon, h.theLrLat);
+   if (convertGeoPoint(temps, theLR_Corner) != ossimErrorCodes::OSSIM_OK) return;
+   
+   sprintf(temps,"%s %s",h.theLlLon, h.theLlLat);
+   if (convertGeoPoint(temps, theLL_Corner) != ossimErrorCodes::OSSIM_OK) return;        
+   
+   sprintf(temps,"%s %s",h.theCenterLon, h.theCenterLat);
+   if (convertGeoPoint(temps, theCenterGP) != ossimErrorCodes::OSSIM_OK) return;        
+      
+   theCenterImagePoint.x     = h.theCenterSample;
+   theCenterImagePoint.y     = h.theCenterLine;
+      
+   theHorizontalOffset       = h.theOffset;
+   theOrientationAngle       = h.theOrientationAngle;
+   theSunElevation           = h.theSunElevation;
+   theSunAzimuth             = h.theSunAzimuth;
+
+   // The header was successfully extracted:
+   theErrorStatus = ossimErrorCodes::OSSIM_OK;   
+   return;
+}
+ 
+int ossimFfL5::convertGeoPoint(const char* sptr, ossimGpt& geo_point)
+{
+   int    londeg;
+   int    lonmin;
+   double lonsec;
+   char   lonhem;
+   int    latdeg;
+   int    latmin;
+   double latsec;
+   char   lathem;
+   
+   int converted = sscanf(sptr, "%03d%02d%7lf%c %02d%02d%7lf%c",
+                          &londeg, &lonmin, &lonsec, &lonhem,
+                          &latdeg, &latmin, &latsec, &lathem);
+
+   if (converted != 8)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   geo_point.lat = (double)latdeg + (double)latmin/60.0 + latsec/3600.0;
+   if (lathem == 'S')
+      geo_point.lat *= -1.0;
+   
+   geo_point.lon= (double)londeg + (double)lonmin/60.0 + lonsec/3600.0;
+   if (lonhem == 'W')
+      geo_point.lon *= -1.0;
+
+   return ossimErrorCodes::OSSIM_OK;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL5.h b/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL5.h
new file mode 100644
index 0000000000..48976de071
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL5.h
@@ -0,0 +1,54 @@
+// *******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Oscar Kramer (SoBe Software)
+// Description: Container class for LandSat5 Fast Format header files (RevB & C)
+//
+// ********************************************************************
+// $Id: ossimFfL5.h,v 1.1 2005/11/10 15:03:51 gpotts Exp $
+
+#ifndef ossimFfL5_HEADER
+#define ossimFfL5_HEADER
+
+
+#include <support_data/ff_l7/ossimFfL7.h>
+
+using namespace std;
+
+// Forward class declarations.
+
+// ***************************************************************************
+// CLASS: ossimFfL5
+// ***************************************************************************
+
+class OSSIMDLLEXPORT ossimFfL5 : public ossimFfL7
+{
+   friend ostream& operator<<(ostream& os, const ossimFfL5& head);
+
+public:
+   ossimFfL5();
+   ossimFfL5(const char* headerFile);
+   virtual ~ossimFfL5();
+   
+private:
+   void    readHeaderRevB(const ossimString& header_name);
+   int     convertGeoPoint(const char* sptr, ossimGpt& geo_point);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL7.cpp b/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL7.cpp
new file mode 100644
index 0000000000..f8330dbd8e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL7.cpp
@@ -0,0 +1,564 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Oscar Kramer (SoBe Software)
+// Description: Container class for LandSat7 Fast Format header files.
+//
+//********************************************************************
+// $Id: ossimFfL7.cpp,v 1.22 2005/11/10 15:01:41 gpotts Exp $
+
+#include <cstdlib>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <iomanip>
+using namespace std;
+#include <time.h>
+
+#include <base/data_types/ossimString.h>
+#include <base/common/ossimDate.h>
+#include <support_data/ff_l7/ossimFfL7.h>
+#include <base/context/ossimNotifyContext.h>
+
+ossimFfL7::ossimFfL7()
+   :
+      ossimErrorStatusInterface()
+{
+   initialize();
+}
+
+ossimFfL7::ossimFfL7(const char* headerFile)
+   :
+      ossimErrorStatusInterface()
+{
+   initialize();
+   
+   // open the header file:
+   FILE* fptr = fopen(headerFile, "r");
+   if (!fptr)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   // Begin reading records:
+   if (!theErrorStatus)
+      readAdminRecord(fptr);
+   if (!theErrorStatus)
+      readRadiomRecord(fptr);
+   if (!theErrorStatus)
+      readGeomRecord(fptr);
+   if(fptr)
+   {
+      fclose(fptr);
+   }
+}
+ossimFfL7::~ossimFfL7()
+{}
+ 
+ossimString ossimFfL7::pathRow() const
+{
+   ossimString tmp = "p";
+   tmp += theLocationCode;
+   tmp.gsub("/", "r");
+   tmp.gsub(" ", "");
+
+   return tmp;
+}
+
+void ossimFfL7::dump(ostream& os) const
+{
+   os << setiosflags(ios::left | ios::fixed)
+      << "\nAdministrative Record:"
+      << setw(30) << "\ntheRequestNumber: " 
+      << theRequestNumber;
+
+   os << setw(30) << "\nLocationCode:     " << theLocationCode
+      << setw(30) << "\nAcquisitionDate:  " << theAcquisitionDate
+      << setw(30) << "\nSatelliteName:    " << theSatName
+      << setw(30) << "\nSensorName:       " << theSensorName
+      << setw(30) << "\nSensorMode:       " << theSensorMode
+      << setw(30) << "\nOffNadirAngle:    "
+      << setprecision(2) << theOffNadirAngle;
+
+   os << setw(30) << "\nProductType: " 
+      << theProductType
+      << setw(30) << "\nProductSize: " 
+      << theProductSize
+      << setw(30) << "\nProcessingType: " 
+      << theProcessingType 
+      << setw(30) << "\nResampAlgorithm: " 
+      << theResampAlgorithm
+      << setw(30) << "\nPixelsPerLine: " 
+      << thePixelsPerLine
+      << setw(30) << "\nLinesPerImage: " 
+      << theLinesPerBand
+      << setw(30) << "\nRecordSize: " 
+      << theRecordSize
+      << setw(30) << "\nGsd: " 
+      << setprecision(2) << theGsd
+      << setw(30) << "\nOutputBitsPerPixel: " 
+      << theOutputBitsPerPixel
+      << setw(30) << "\nAcquiredBitsPerPixel: " 
+      << theAcquiredBitsPerPixel
+      << setw(30) << "\nBandsPresentString: " 
+      << theBandsPresentString;
+   
+   for (int i=0; i<6; i++)
+      os << "\nBandFileNames["<<i<<"]:             " <<theBandFileNames[i];
+   os << endl;
+
+   os << setprecision(15) << setw(30) << "\nRadiometric record:" << endl;
+   ossim_uint32 band = 0;
+   vector<ossim_float64>::const_iterator bi = theBias.begin();
+   while (bi != theBias.end())
+   {
+      os << "band[" << band << "] bias:  " << (*bi) << endl;
+      ++bi;
+      ++band;
+   }
+
+   band = 0;
+   bi = theGain.begin();
+   while (bi != theGain.end())
+   {
+      os << "band[" << band << "] gain:  " << (*bi) << endl;
+      ++bi;
+      ++band;
+   }
+   
+   os << endl
+      << "Geometric Record:"
+      << setw(30) << "\nMapProjectionName:" 
+      << theMapProjectionName
+      << setw(30) << "\nEllipsoid:" 
+      << theEllipsoid
+      << setw(30) << "\nDatum:" 
+      << theDatum;
+
+   for (int i = 0; i < 15; i++)
+   {
+      os << "\nProjectionParams[" << setw(2) << i << setw(10) << "]:  "
+         << theProjectionParams[i];
+   }
+
+   os << setprecision(3) 
+      << setw(30) << "\nUL Corner:" << theUL_Corner
+      << setw(30) << "\nUR Corner:" << theUR_Corner
+      << setw(30) << "\nLR Corner:" << theLR_Corner
+      << setw(30) << "\nLL Corner:" << theLL_Corner
+      << setw(30) << "\nCenter Point (Ground):" << theCenterGP
+      << setw(30) << "\nCenter Point (Image):" << theCenterImagePoint
+      << setw(30) << "\nHorizontalOffset:" 
+      << theHorizontalOffset
+      << setprecision(2) << setw(30) << "\nOrientationAngle:" 
+      << theOrientationAngle
+      << setw(30) << "\nSunElevationAngle:" 
+      << setprecision(1) << theSunElevation
+      << setw(30) << "\nSunAzimuth:" <<  theSunAzimuth
+      << resetiosflags(ios::left)
+      << endl << endl;
+}
+
+void ossimFfL7::writeHeader(ostream& os) const
+{
+   ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimFfL7::writeHeader: This method is not yet implemented. Ignoring request..."
+                                      << std::endl;
+   os << "WARNING ossimFfL7::writeHeader: This method is not yet implemented. Ignoring request..."
+      << std::endl;
+}
+
+void ossimFfL7::readAdminRecord(FILE* fptr)
+{
+   static const int OFFSET = -1;
+   int converted;
+   theErrorStatus = ossimErrorCodes::OSSIM_ERROR; // assume error, prove not at end;
+
+   fseek(fptr, OFFSET + 9, SEEK_SET);
+   converted = fscanf(fptr, "%20c", theRequestNumber);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 35, SEEK_SET);
+   converted = fscanf(fptr, "%17c", theLocationCode);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 71, SEEK_SET);
+   converted = fscanf(fptr, "%8c", theAcquisitionDate);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 92, SEEK_SET);
+   converted = fscanf(fptr, "%10c", theSatName);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 111, SEEK_SET);
+   converted = fscanf(fptr, "%10c", theSensorName);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 135, SEEK_SET);
+   converted = fscanf(fptr, "%6c", theSensorMode);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 154, SEEK_SET);
+   converted = fscanf(fptr, "%6lf", &theOffNadirAngle);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 655, SEEK_SET);
+   converted = fscanf(fptr, "%18c", theProductType);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 688, SEEK_SET);
+   converted = fscanf(fptr, "%10c", theProductSize);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 741, SEEK_SET);
+   converted = fscanf(fptr, "%11c", theProcessingType);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 765, SEEK_SET);
+   converted = fscanf(fptr, "%2c", theResampAlgorithm);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 843, SEEK_SET);
+   converted = fscanf(fptr, "%5d", &thePixelsPerLine);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 865, SEEK_SET);
+   converted = fscanf(fptr, "%5d", &theLinesPerBand);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 932, SEEK_SET);
+   converted = fscanf(fptr, "%9d", &theRecordSize);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 954, SEEK_SET);
+   converted = fscanf(fptr, "%6lf", &theGsd);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 984, SEEK_SET);
+   converted = fscanf(fptr, "%2d", &theOutputBitsPerPixel);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 1012, SEEK_SET);
+   converted = fscanf(fptr, "%2d", &theAcquiredBitsPerPixel);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 1056, SEEK_SET);
+   converted = fscanf(fptr, "%32c", theBandsPresentString);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 1131, SEEK_SET);
+   converted = fscanf(fptr, "%29c", theBandFileNames[0]);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 1170, SEEK_SET);
+   converted = fscanf(fptr, "%29c", theBandFileNames[1]);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 1211, SEEK_SET);
+   converted = fscanf(fptr, "%29c", theBandFileNames[2]);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 1250, SEEK_SET);
+   converted = fscanf(fptr, "%29c", theBandFileNames[3]);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 1291, SEEK_SET);
+   converted = fscanf(fptr, "%29c", theBandFileNames[4]);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 1330, SEEK_SET);
+   converted = fscanf(fptr, "%29c", theBandFileNames[5]);
+   if (converted != 1) return;
+
+   std::vector<ossimString> arrayPathRow = ossimString(theLocationCode).split("/");
+   if(arrayPathRow.size() == 2)
+   {
+      thePathNumber = arrayPathRow[0].toInt();
+      theRowNumber = arrayPathRow[1].beforePos(3).toInt();
+   }
+   
+   // The Admin record was successfully extracted:
+   theErrorStatus = ossimErrorCodes::OSSIM_OK;   
+   return;
+}
+
+
+//***************************************************************************
+// PRIVATE METHOD: ossimFfL7::readRadiomRecord()
+//  
+//***************************************************************************
+void ossimFfL7::readRadiomRecord(FILE* fptr)
+{
+   int converted;
+   char radiom_record[1537];
+   
+   if (!theErrorStatus)
+   {
+      fseek(fptr, 1536, SEEK_SET);
+      converted = fscanf(fptr, "%1536c", radiom_record);
+      if (converted != 1) theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   // Get the gains and biases.
+   theBias.clear();
+   theGain.clear();
+
+   const ossim_uint32 MAX = 128;
+   char temp_chars[MAX];
+   istringstream is(radiom_record);
+
+   // Eat the first line. "GAINS AND BIASES IN ASCENDING BAND NUMBER ORDER"
+   is.getline(temp_chars, MAX);
+   
+   const char SPACE     = 0x20;
+   const char LINE_FEED = 0x0a;
+   
+   // LS7 header has room for eight bands per spec.   
+   for (ossim_uint32 band = 0; band < 8; ++band)
+   {
+      is.getline(temp_chars, MAX);
+      bool blank_line = true;
+      for (ossim_uint32 i = 0; i < MAX; ++i)
+      {
+         if (temp_chars[i] == LINE_FEED) break;  // end of line...
+
+         if (temp_chars[i] != SPACE)
+         {
+            blank_line = false; // has bias and gain...
+            break;
+         }
+      }
+
+      if (blank_line == true) continue; // go to next line...
+      
+      double d = 0.0;
+      istringstream is2(temp_chars);
+      is2 >> d;
+      theBias.push_back(d);
+      is2 >> d;
+      theGain.push_back(d);
+   }
+}
+
+//***************************************************************************
+// PRIVATE METHOD: ossimFfL7::readGeomRecord()
+//  
+//***************************************************************************
+void ossimFfL7::readGeomRecord(FILE* fptr)
+{
+   static const int OFFSET = 3071;
+   int converted;
+   theErrorStatus = ossimErrorCodes::OSSIM_ERROR; // assume error, prove not at end;
+
+   fseek(fptr, OFFSET + 32, SEEK_SET);
+   converted = fscanf(fptr, "%4c", theMapProjectionName);
+   if (converted != 1) return;
+
+   fseek(fptr, OFFSET + 48, SEEK_SET);
+   converted = fscanf(fptr, "%18c", theEllipsoid);
+   if (converted != 1) return;
+      
+   strcpy(theDatum, "WGS-84");
+
+   // added to read in all 15 parameters instead of the first two.
+   long currentOffset = OFFSET + 110;
+   for(long parameter=0;parameter < 15; ++parameter)
+   {
+      fseek(fptr, currentOffset, SEEK_SET);
+      converted = fscanf(fptr, "%24lf", &theProjectionParams[parameter]);
+      if (converted != 1) return;
+
+      currentOffset +=25;
+   }
+      
+   
+   fseek(fptr, OFFSET + 521, SEEK_SET);
+   converted = fscanf(fptr, "%6d", &theUsgsMapZone);
+   if (converted != 1) return;
+      
+   fseek(fptr, OFFSET + 566, SEEK_SET);
+   if(convertGeoPoint(fptr, theUL_Corner)) return;
+      
+   fseek(fptr, OFFSET + 646, SEEK_SET);
+   if(convertGeoPoint(fptr, theUR_Corner)) return;
+      
+   fseek(fptr, OFFSET + 726, SEEK_SET);
+   if(convertGeoPoint(fptr, theLR_Corner)) return;
+      
+   fseek(fptr, OFFSET + 806, SEEK_SET);
+   if(convertGeoPoint(fptr, theLL_Corner)) return;
+      
+   fseek(fptr, OFFSET + 890, SEEK_SET);
+   if(convertGeoPoint(fptr, theCenterGP)) return;
+      
+   fseek(fptr, OFFSET + 945, SEEK_SET);
+
+   int x;
+   int y;
+   
+   converted = fscanf(fptr, "%5d %5d", &x, &y);
+   if (converted != 2) return;
+   
+   theCenterImagePoint.x = x;
+   theCenterImagePoint.y = y;
+      
+   fseek(fptr, OFFSET + 969, SEEK_SET);
+   converted = fscanf(fptr, "%6d", &theHorizontalOffset);
+   if (converted != 1) return;
+      
+   fseek(fptr, OFFSET + 995, SEEK_SET);
+   converted = fscanf(fptr, "%6lf", &theOrientationAngle);
+   if (converted != 1) return;
+      
+   fseek(fptr, OFFSET + 1062, SEEK_SET);
+   converted = fscanf(fptr, "%4lf", &theSunElevation);
+   if (converted != 1) return;
+      
+   fseek(fptr, OFFSET + 1086, SEEK_SET);
+   converted = fscanf(fptr, "%5lf", &theSunAzimuth);
+   if (converted != 1) return;
+
+   // successfully reached the end of Geom record:
+   theErrorStatus = ossimErrorCodes::OSSIM_OK;
+
+   return;
+}
+
+
+//***************************************************************************
+// PRIVATE METHOD: ossimFfL7::convertGeoPoint(char* buffer);
+//  
+//***************************************************************************
+int ossimFfL7::convertGeoPoint(FILE* fptr, ossimGpt& geo_point)
+{
+   int    londeg;
+   int    lonmin;
+   double lonsec;
+   char   lonhem;
+   int    latdeg;
+   int    latmin;
+   double latsec;
+   char   lathem;
+   
+   int converted = fscanf(fptr, "%03d%02d%7lf%c %02d%02d%7lf%c",
+                          &londeg, &lonmin, &lonsec, &lonhem,
+                          &latdeg, &latmin, &latsec, &lathem);
+
+   if (converted != 8)
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   geo_point.lat = (double)latdeg + (double)latmin/60.0 + latsec/3600.0;
+   if (lathem == 'S')
+      geo_point.lat *= -1.0;
+   
+   geo_point.lon= (double)londeg + (double)lonmin/60.0 + lonsec/3600.0;
+   if (lonhem == 'W')
+      geo_point.lon *= -1.0;
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+   
+//***************************************************************************
+// PRIVATE METHOD: ossimFfL7::initialize()
+// Initializes all fields to blanks (or 0's) and null terminates strings.
+//***************************************************************************
+void ossimFfL7::initialize()
+{
+   static const char source[] = "";
+
+   // The Admin Record:
+   strncpy(theRequestNumber, source, 21);
+   strncpy(theLocationCode, source, 18);
+   thePathNumber = 0;
+   theRowNumber = 0;
+   strncpy(theAcquisitionDate, source, 20);
+   strncpy(theSatName, source, 11);
+   strncpy(theSensorName, source, 11);
+   strncpy(theSensorMode, source, 7);
+   theOffNadirAngle = 0.0;      
+   strncpy(theProductType, source, 19);
+   strncpy(theProductSize, source, 11);
+   strncpy(theProcessingType, source, 12);
+   strncpy(theResampAlgorithm, source, 3);
+   thePixelsPerLine = 0;
+   theLinesPerBand = 0;
+   theRecordSize = 0;
+   theGsd = 0.0;
+   theOutputBitsPerPixel = 0;
+   theAcquiredBitsPerPixel = 0;
+   strncpy(theBandsPresentString, source, 33);
+   strncpy(theBandFileNames[0], source, 30);
+   strncpy(theBandFileNames[1], source, 30);
+   strncpy(theBandFileNames[2], source, 30);
+   strncpy(theBandFileNames[3], source, 30);
+   strncpy(theBandFileNames[4], source, 30);
+   strncpy(theBandFileNames[5], source, 30);
+
+   // The Radiometry Record:
+   theBias.clear();
+   theGain.clear();
+
+   // The Geometry Record:
+   strncpy(theMapProjectionName, source, 5);
+   strncpy(theEllipsoid, source, 19);
+   strncpy(theDatum, source, 7);
+   for (int i=0; i<15; i++)
+      theProjectionParams[i] = 0.0;
+   theUsgsMapZone = 0;
+
+   theHorizontalOffset  = 0;   
+   theOrientationAngle  = 0.0; 
+   theSunElevation      = 0.0; 
+   theSunAzimuth        = 0.0; 
+
+   return;
+}
+
+void ossimFfL7::getBias(vector<double>& bias) const
+{
+   bias = theBias;
+}
+
+void ossimFfL7::getGain(vector<double>& gain) const
+{
+   gain = theGain;
+}
+
+
+long ossimFfL7::getJulianDay()const
+{
+   ossimDate date(ossimString(theAcquisitionDate+4,
+                              theAcquisitionDate+6).toLong(),
+                  ossimString(theAcquisitionDate+6,
+                              theAcquisitionDate+8).toLong(),
+                  ossimString(theAcquisitionDate,
+                              theAcquisitionDate+4).toLong());
+   
+   return static_cast<long>(date.getJulian());
+}
+
+unsigned int ossimFfL7::getBandCount()const
+{
+   ossimString tmp(theBandsPresentString);
+   tmp.trim(); //remove spaces
+   return tmp.length();
+//   return strlen(tmp.chars()); //beurk! should implement length in ossimString
+}
+ 
+//***************************************************************************
+// Function:
+// ostream& operator<<(ostream& os, const ossimFfL7& head)
+//***************************************************************************
+ostream& operator<<(ostream& os, const ossimFfL7& head)
+{
+   head.dump(os);
+   return os;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL7.h b/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL7.h
new file mode 100644
index 0000000000..d7b609db54
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_l7/ossimFfL7.h
@@ -0,0 +1,152 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+// 
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Oscar Kramer (SoBe Software)
+//
+// Description: Container class for LandSat7 Fast Format header files.
+//
+//********************************************************************
+// $Id: ossimFfL7.h,v 1.11 2005/11/10 15:02:02 gpotts Exp $
+
+#ifndef ossimFfL7_HEADER
+#define ossimFfL7_HEADER
+#include <iostream>
+using namespace std;
+
+#include <cstdio>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimIpt.h>
+
+// Forward class declarations.
+
+// ***************************************************************************
+// CLASS: ossimFfL7
+// ***************************************************************************
+
+class OSSIMDLLEXPORT ossimFfL7 : public ossimErrorStatusInterface
+{
+   friend ostream& operator<<(ostream& os, const ossimFfL7& head);
+
+public:
+   ossimFfL7  ();
+   ossimFfL7  (const char* headerFile);
+   virtual ~ossimFfL7();
+   
+   void   dump(ostream& os) const;
+      //> Provides a readable dump of this object.
+      //<
+   void   writeHeader(ostream& os) const;
+      //> Writes the full header to the output stream in proper L7A format.
+      //  NOT YET IMPLEMENTED
+      //<
+   int    path() const { return thePathNumber; }
+      //> Returns the path as an int.
+      //  Currently uses the1stPathRowNumber string.
+      //<
+   int    row() const { return theRowNumber; }
+      //> Returns the row as an int from the pathRowString.
+      //  Currently uses the1stPathRowNumber string.
+      //<
+   ossimString pathRow() const;
+      //> Returns a string represnting the path and row as a name.
+      //  i.e.: PPP/RRFFSS will be returned as pPPPrRRFFSS
+      //  This method will remove any spaces.
+      //<
+
+   /*!
+    * Initializes "bias" with "theBias" from the radiometry record.
+    * Contains eight bands; although, only bands present will be initialized.
+    */
+   void getBias(vector<double>& bias) const;
+   double getBias(long bandIdx)const
+      {
+         return theBias[bandIdx];
+      }
+
+   /*!
+    * Initializes "bias" with "theBias" from the radiometry record.
+    * Contains eight bands; although, only bands present will be initialized.
+    */
+   void getGain(vector<double>& gain) const;
+   double getGain(long bandIdx)const
+      {
+         return theGain[bandIdx];
+      }
+
+   double getParam(ossim_uint32 i)const
+      {
+         if(i < 16)
+         {
+            return theProjectionParams[i];
+         }
+         return 0.0;
+      }
+
+   virtual unsigned int getBandCount()const;
+   
+   long getJulianDay()const;
+   // The Admin Record:
+   char   theRequestNumber[21];     // NNNYYMMDDSSSSUUUU
+   char   theLocationCode[18];      // ppp/rrrffss
+   int    thePathNumber;
+   int    theRowNumber;
+   char   theAcquisitionDate[20];   // yyyymmdd
+   char   theSatName[11];           // "LANDSAT7"
+   char   theSensorName[11];        // "ETM+"
+   char   theSensorMode[7];         // "NORMAL"
+   double theOffNadirAngle;         // degrees
+   char   theProductType[19];       // "MAPbORIENTED"|"ORBITbORIENTED"
+   char   theProductSize[11];       // ("FULLb"|"SUB"|"MULTI")+"SCENE"
+   char   theProcessingType[12];    // "SYSTEMATIC"
+   char   theResampAlgorithm[3];    // "CC"|"NN"|"MF"
+   int    thePixelsPerLine;
+   int    theLinesPerBand;
+   int    theRecordSize;
+   double theGsd;
+   int    theOutputBitsPerPixel;
+   int    theAcquiredBitsPerPixel;
+   char   theBandsPresentString[33];
+   char   theBandFileNames[8][30];
+
+   // The Radiometry Record:
+   vector<double> theBias;
+   vector<double> theGain;
+
+   // The Geometry Record:
+   char    theMapProjectionName[5];  
+   char    theEllipsoid[19];        // "WGS84"
+   char    theDatum[7];             // "WGS84"
+   double  theProjectionParams[15];
+   int     theUsgsMapZone;
+
+   ossimGpt theUL_Corner;
+   ossimGpt theUR_Corner;
+   ossimGpt theLR_Corner;
+   ossimGpt theLL_Corner;
+   ossimGpt theCenterGP;
+
+   ossimIpt theCenterImagePoint;
+
+   int     theHorizontalOffset;   // pixels
+   double  theOrientationAngle;   // degrees
+   double  theSunElevation;       // degrees
+   double  theSunAzimuth;         // degrees
+
+private:
+   void        initialize();
+   void        readAdminRecord(FILE* fptr);
+   void        readRadiomRecord(FILE* fptr);
+   void        readGeomRecord(FILE* fptr);
+   int         convertGeoPoint(FILE*, ossimGpt&);
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_revb/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/ff_revb/.cvsignore
new file mode 100644
index 0000000000..7df3918588
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_revb/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+Makefile
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_revb/ossimFfRevb.cpp b/Utilities/OSSIM/ossim_core/support_data/ff_revb/ossimFfRevb.cpp
new file mode 100644
index 0000000000..66be9ecaa8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_revb/ossimFfRevb.cpp
@@ -0,0 +1,1373 @@
+ //*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Dave Burken (dburken@imagelinks.com)
+// Description: This class parses an EOSAT Fast Format rev b header.
+//
+//********************************************************************
+// $Id: ossimFfRevb.cpp,v 1.3 2004/04/07 16:39:34 gpotts Exp $
+
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <sstream>
+#include <iomanip>
+
+#include <support_data/ff_revb/ossimFfRevb.h>
+#include <base/data_types/ossimString.h>
+#include <base/context/ossimNotifyContext.h>
+
+// File scope constants for seek positions.
+const int RADIANCE_OFFSET [7] = { 300,
+                                  317,
+                                  334,
+                                  351,
+                                  368,
+                                  385,
+                                  402  };
+
+static const int PROJ_PARAM_OFFSET [15]  = { 594,
+                                      618,
+                                      642,
+                                      666,
+                                      690,
+                                      714,
+                                      738,
+                                      762,
+                                      786,
+                                      810,
+                                      834,
+                                      858,
+                                      882,
+                                      906,
+                                      930 };
+
+
+//***************************************************************************
+// CONSTRUCTOR
+//***************************************************************************
+ossimFfRevb::ossimFfRevb()
+   :
+      the1stLineInVolume(1),
+      theLinesPerVolume(0),
+      theOrientationAngle(0.0),
+      theUsgsProjNumber(0),
+      theUsgsMapZone(0),
+      theSemiMajorAxis(0.0),
+      theSemiMinorAxis(0.0),
+      theGsd(0.0),
+      thePixelsPerLine(0),
+      theLinesPerImage(0),
+      theUlEasting(0.0),
+      theUlNorthing(0.0),
+      theUrEasting(0.0),
+      theUrNorthing(0.0),
+      theLrEasting(0.0),
+      theLrNorthing(0.0),
+      theLlEasting(0.0),
+      theLlNorthing(0.0),
+      theBlockingFactor(0),
+      theRecordSize(0),
+      theSunElevation(0),
+      theSunAzimuth(0),
+      theCenterEasting(0.0),
+      theCenterNorthing(0.0),
+      theCenterSample(0),
+      theCenterLine(0),
+      theOffset(0),
+      theErrorStatus(OSSIM_OK)
+{
+   const char tmpBuff[] = "";
+
+   strcpy(theProductOrderNumber, tmpBuff);
+   strcpy(thePathRowNumber, tmpBuff);
+   strcpy(theAcquisitionDate, tmpBuff);
+   strcpy(theSatNumber, tmpBuff);
+   strcpy(theInstrumentType, tmpBuff);
+   strcpy(theProductType, "MAP ORIENTED");
+   strcpy(theProductSize, tmpBuff);
+   strcpy(theMapSheetName, tmpBuff);
+   strcpy(theProcessingType, "TERRAIN");
+   strcpy(theResampAlgorithm, "NN");
+
+   int i;
+   for (i=0; i<NUMBER_OF_BANDS; i++)
+   {
+      strcpy(theBandRadiance[i], tmpBuff);
+   }
+
+   strcpy(theVolumeNumber, tmpBuff);
+   strcpy(theMapProjName, tmpBuff);
+
+   for (i=0; i<NUMBER_OF_PROJECTION_PARAMETERS; i++)
+   {
+      strcpy(theUsgsProjParam[i], tmpBuff);
+   }
+
+   strcpy(theEllipsoid, tmpBuff);
+   strcpy(theUlLon, tmpBuff);
+   strcpy(theUlLat, tmpBuff);
+   strcpy(theUrLon, tmpBuff);
+   strcpy(theUrLat, tmpBuff);
+   strcpy(theLrLon, tmpBuff);
+   strcpy(theLrLat, tmpBuff);
+   strcpy(theLlLon, tmpBuff);
+   strcpy(theLlLat, tmpBuff);
+   strcpy(theBandsPresentString, "P");
+   strcpy(theCenterLon, tmpBuff);
+   strcpy(theCenterLat, tmpBuff);
+   strcpy(theFormatVersion, "B");
+   
+}
+
+//***************************************************************************
+// CONSTRUCTOR:
+// ossimFfRevb::ossimFfRevb(const char* headerFile)
+//
+// Takes a filename representing an IRS-1C Fast Format rev C header.
+//***************************************************************************
+ossimFfRevb::ossimFfRevb(const char* headerFile)
+   :
+   theErrorStatus(OSSIM_OK)
+{
+   ifstream is;
+
+   is.open(headerFile);
+
+   if (!is)
+   {
+      theErrorStatus = OSSIM_ERROR;
+
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::ossimFfRevb(header):"
+                                          << "Cannot open header = " << headerFile << "\n"
+                                          << "Returning from constructor." << std::endl;
+
+      return;
+   }
+
+   loadFromStream(is);
+
+   is.close();
+
+}
+
+
+//***************************************************************************
+// PUBLIC METHOD:
+// int ossimFfRevb::path(int sceneNbr) const
+//
+// Convenience method to parse the path from the path/row string.  Returns
+// zero if stream is not opened.  Current loacation field is:
+// path/row/fraction/subscene in ppp/rrrff format.
+//***************************************************************************
+int ossimFfRevb::path() const
+{
+   char tmpBuff[4];
+   int path = 0;
+
+   istringstream is(thePathRowNumber);
+
+   if (is)
+   {
+      is.get(tmpBuff, 4);
+      tmpBuff[3] = '\0';
+
+      if (tmpBuff)
+      {
+         path = atoi(tmpBuff);
+      }
+   }
+
+   return path;
+}
+
+
+//***************************************************************************
+// PUBLIC METHOD:
+// int ossimFfRevb::row(int sceneNbr) const
+//
+// Convenience method to parse the row from the path/row string.  Returns
+// zero if stream is not opened.  Current loacation field is:
+// path/row/fraction/subscene in ppp/rrrff format.
+//***************************************************************************
+int ossimFfRevb::row() const
+{
+   char tmpBuff[4];
+   int row = 0;
+
+   istringstream is(thePathRowNumber);
+
+   if (is)
+   {
+      is.seekg(4, ios::beg);
+      is.get(tmpBuff, 4);
+      tmpBuff[3] = '\0';
+
+      if (tmpBuff)
+      {
+         row = atoi(tmpBuff);
+      }
+   }
+
+   return row;
+}
+
+
+//***************************************************************************
+// PUBLIC METHOD:
+// int ossimFfRevb::fraction(int sceneNbr) const
+//
+// Convenience method to parse the fraction from the path/row string.  Returns
+// zero if stream is not opened.  Current loacation field is:
+// path/row/fraction/subscene in ppp/rrrff format.
+//***************************************************************************
+int ossimFfRevb::fraction() const
+{
+   char tmpBuff[3];
+   int fraction = 0;
+
+   istringstream is(thePathRowNumber);
+
+   if (is)
+   {
+      is.seekg(7, ios::beg);
+      is.get(tmpBuff, 3);
+      tmpBuff[2] = '\0';
+
+      if (tmpBuff)
+      {
+         fraction = atoi(tmpBuff);
+      }
+   }
+
+   return fraction;
+}
+
+//***************************************************************************
+// PUBLIC METHOD:
+// double ossimFfRevb::projParam(int paramNumber) const
+//
+// Returns the projection parameter as a double from the string taken from
+// the header.  There are fifteen parameters so the possible range for
+// paramNumber is 0 to 14.
+//***************************************************************************
+double ossimFfRevb::projParam(int paramNumber) const
+{
+   if (paramNumber >= NUMBER_OF_PROJECTION_PARAMETERS)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::projParam: "
+                                          << "Parameter out of range:  " << paramNumber
+                                          << "\nValid range:  0 - 14" << std::endl;
+      return 0.0;
+   }
+
+   //***
+   // The USGS Projection Parameters in a rev b header have a "D" to
+   // denote the exponent.  This simply substitutes the "D" with an
+   // "E" so that atof works properly.
+   //***
+   ossimString tmp = theUsgsProjParam[paramNumber];
+   tmp.gsub("D", "E");
+
+   return atof(tmp.chars());
+}
+
+//***************************************************************************
+// PUBLIC METHOD:
+// void ossimFfRevb::print(ostream& os) const
+//
+// Prints data members.
+//***************************************************************************
+void ossimFfRevb::print(ostream& os) const
+{
+   os << setiosflags(ios::left | ios::fixed)
+      << setw(30) << "\nimage_id:" 
+      << theProductOrderNumber
+      << setw(30) << "\npath_row_number:"
+      << thePathRowNumber
+      << setw(30) << "\nacquisition_date:"
+      << theAcquisitionDate
+      << setw(30) << "\nsatellite_name:"
+      << theSatNumber
+      << setw(30) << "\nsensor_name:"
+      << theInstrumentType
+      << setw(30) << "\nproduct_type:" 
+      << theProductType
+      << setw(30) << "\nproduct_size:" 
+      << theProductSize
+      << setw(30) << "\nprocessing_type:" 
+      << theProcessingType 
+      << setw(30) << "\nresamp_algorithm:" 
+      << theResampAlgorithm;
+
+   int i;
+   for (i=0; i<NUMBER_OF_BANDS; i++)
+   {
+      os << "\nband" << i+1 << setw(25) << "_radiance:"
+         << theBandRadiance[i];
+   }
+
+   os << setw(30) << "\ntape_volume_number:" 
+      << theVolumeNumber
+      << setw(30) << "\nfirst_line_in_volume:" 
+      << the1stLineInVolume
+      << setw(30) << "\nlines_per_volume:" 
+      << theLinesPerVolume
+      << setw(30) << "\norientation_angle:" 
+      << setprecision(2) << theOrientationAngle
+      << setw(30) << "\nprojection_type:" 
+      << theMapProjName
+      << setw(30) << "\nusgs_projection_number:" 
+      << theUsgsProjNumber
+      << setw(30) << "\nmap_zone:" 
+      << theUsgsMapZone;
+
+//    os << setprecision(15);
+   os << setiosflags(ios::right);
+   for (i=0; i<NUMBER_OF_PROJECTION_PARAMETERS; i++)
+   {
+      os << "\nprojection_parameter_" << i+1 << setw(10) << ":"
+         << setw(24) << theUsgsProjParam[i];
+   }
+   os << resetiosflags(ios::right);
+   
+
+   os << setw(30) << "\nellipsoid:" 
+      << theEllipsoid
+      << setw(30) << "\nsemi_major_axis:"
+      << setprecision(3) << setw(11) << theSemiMajorAxis
+      << setw(30) << "\nsemi_minor_axis:"
+      << setw(11) << theSemiMinorAxis
+      << setw(30) << "\ngsd:" 
+      << setprecision(2) << setw(5) << theGsd      
+      << setw(30) << "\nnumber_samples:"
+      << thePixelsPerLine
+      << setw(30) << "\nnumber_lines:" 
+      << theLinesPerImage
+      << setprecision(3)
+      << setw(30) << "\nul_longitude:" 
+      << theUlLon
+      << setw(30) << "\nul_latitude:" 
+      << theUlLat
+      << setw(30) << "\nul_easting:" 
+      << setw(13) << theUlEasting
+      << setw(30) << "\nul_northing:" 
+      << setw(13) << theUlNorthing   
+      << setw(30) << "\nur_longitude:" 
+      << theUrLon
+      << setw(30) << "\nur_latitude:" 
+      << theUrLat
+      << setw(30) << "\nur_easting:" 
+      << setw(13) << theUrEasting
+      << setw(30) << "\nur_northing:" 
+      << setw(13) << theUrNorthing
+      << setw(30) << "\nlr_longitude:" 
+      << theLrLon
+      << setw(30) << "\nlr_latitude:" 
+      << theLrLat
+      << setw(30) << "\nlr_easting:" 
+      << setw(13) << theLrEasting
+      << setw(30) << "\nlr_northing:" 
+      << setw(13) << theLrNorthing
+      << setw(30) << "\nll_longitude:" 
+      << theLlLon
+      << setw(30) << "\nll_latitude:" 
+      << theLlLat
+      << setw(30) << "\nll_easting:" 
+      << setw(13) << theLlEasting
+      << setw(30) << "\nll_northing:" 
+      << setw(13) << theLlNorthing      
+      << setw(30) << "\nbands_present_string:" 
+      << theBandsPresentString
+      << setw(30) << "\ntape_blocking_factor:" 
+      << theBlockingFactor
+      << setw(30) << "\nrecord_size:" 
+      << theRecordSize
+      << setw(30) << "\nillum_elevation:" 
+      << theSunElevation
+      << setw(30) << "\nillum_azimuth:"
+      << theSunAzimuth
+      << setw(30) << "\ncenter_longitude:" 
+      << theCenterLon
+      << setw(30) << "\ncenter_latitude:" 
+      << theCenterLat
+      << setw(30) << "\ncenter_easting:" 
+      << setw(13) << theCenterEasting
+      << setw(30) << "\ncenter_northing:" 
+      << setw(13) << theCenterNorthing
+      << setw(30) << "\ncenter_sample:" 
+      << theCenterSample
+      << setw(30) << "\ncenter_line:" 
+      << theCenterLine
+      << setw(30) << "\nhorizontal_offset:" 
+      << theOffset
+      << setw(30) << "\nformat_version:" 
+      << theFormatVersion
+      << std::endl;
+
+}
+
+//***************************************************************************
+// PUBLIC METHOD:
+// void ossimFfRevb::write(ostream& os) const
+//
+// Writes an EOSAT Fast Format Rev B formatted header.
+//***************************************************************************
+void ossimFfRevb::write(ostream& os) const
+{
+   const char PRODUCT_ID_DESC [PRODUCT_ORDER_NUMBER_DESC_SIZE + 1]
+      = "PRODUCT =";
+
+   const char WRS_DESC [WRS_DESC_SIZE + 1]
+      = " WRS =";
+
+   const char DATE_DESC [DATE_DESC_SIZE + 1]
+      = " ACQUISITION DATE =";
+   
+   const char SATELLITE_NUMBER_DESC [SAT_NUMBER_DESC_SIZE + 1]
+      = " SATELLITE =";
+   
+   const char INSTRUMENT_TYPE_DESC [INSTRUMENT_TYPE_DESC_SIZE + 1]
+      = " INSTRUMENT =";
+   
+   const char PRODUCT_TYPE_DESC [PRODUCT_TYPE_DESC_SIZE + 1]
+      = " PRODUCT TYPE =";
+   
+   const char PRODUCT_SIZE_DESC [PRODUCT_SIZE_DESC_SIZE + 1]
+      = " PRODUCT SIZE =";
+   
+   const char PROCESSING_TYPE_DESC [PROCESSING_TYPE_DESC_SIZE + 1]
+      = " TYPE OF GEODETIC PROCESSING =";
+   
+   const char RESAMPLING_ALGO_DESC [RESAMPLING_ALGO_DESC_SIZE + 1]
+      = " RESAMPLING =";
+   
+   const char RADIANCE_DESC [RADIANCE_DESC_SIZE + 1]
+      = " RAD GAINS/BIASES = ";
+
+   const char VOLUME_NUMBER_DESC [VOLUME_NUMBER_DESC_SIZE + 1]
+      = " TAPE SPANNING FLAG=";
+   
+   const char  FIRST_LINE_DESC [FIRST_LINE_DESC_SIZE + 1]
+      = " START LINE #=";
+
+   const char LINES_PER_VOLUME_DESC [LINES_PER_VOLUME_DESC_SIZE + 1]
+      = " LINES PER VOL=";
+
+   const char ORIENTATION_ANGLE_DESC [ORIENTATION_ANGLE_DESC_SIZE + 1]
+      = " ORIENTATION =";
+
+   const char MAP_PROJ_NAME_DESC [MAP_PROJ_NAME_DESC_SIZE + 1]
+      = " PROJECTION =";
+ 
+   const char USGS_PROJ_NUMBER_DESC [USGS_PROJ_NUMBER_DESC_SIZE + 1]
+      = " USGS PROJECTION # =";
+ 
+   const char USGS_MAP_ZONE_DESC [USGS_MAP_ZONE_DESC_SIZE + 1]
+      = " USGS MAP ZONE =";
+ 
+   const char PROJECTION_PARAMETER_DESC [USGS_PROJ_PARAMS_DESC_SIZE + 1]
+      = " USGS PROJECTION PARAMETERS =";
+
+   const char ELLIPSOID_DESC [ELLIPSOID_DESC_SIZE + 1]
+      = " EARTH ELLIPSOID =";
+      
+   const char MAJOR_AXIS_DESC [MAJOR_AXIS_DESC_SIZE+ 1]
+      = " SEMI-MAJOR AXIS =";
+      
+   const char MINOR_AXIS_DESC [MINOR_AXIS_DESC_SIZE+ 1]
+      = " SEMI-MINOR AXIS =";
+      
+   const char PIXEL_GSD_DESC [PIXEL_GSD_DESC_SIZE + 1]
+      = " PIXEL SIZE =";
+   
+   const char PIXELS_PER_LINE_DESC [PIXELS_PER_LINE_DESC_SIZE + 1]
+      = " PIXELS PER LINE=";
+   
+   const char LINES_PER_IMAGE_DESC [LINES_PER_IMAGE_DESC_SIZE + 1]
+      = " LINES PER IMAGE=";
+
+   const char UL_DESC [CORNER_DESC_SIZE + 1]
+      = " UL ";
+
+   const char UR_DESC [CORNER_DESC_SIZE + 1]
+      = " UR ";
+   
+   const char LR_DESC [CORNER_DESC_SIZE + 1]
+      = " LR ";
+   
+   const char LL_DESC [CORNER_DESC_SIZE + 1]
+      = " LL ";
+   
+   const char BANDS_PRESENT_DESC [BANDS_PRESENT_DESC_SIZE + 1]
+      = " BANDS PRESENT =";
+   
+   const char BLOCKING_FACTOR_DESC [BLOCKING_FACTOR_DESC_SIZE + 1]
+      = " BLOCKING FACTOR =";
+   
+   const char RECORD_LENGTH_DESC [RECORD_LENGTH_DESC_SIZE + 1]
+      = " RECORD LENGTH =";
+   
+   const char SUN_ELEVATION_DESC [SUN_ELEVATION_DESC_SIZE + 1]
+      = " SUN ELEVATION =";
+   
+   const char SUN_AZIMUTH_DESC [SUN_AZIMUTH_DESC_SIZE + 1]
+      = " SUN AZIMUTH =";
+
+   const char CENTER_DESC [CENTER_DESC_SIZE + 1]
+      = " CENTER ";
+   
+   const char OFFSET_DESC [OFFSET_DESC_SIZE + 1]
+      = " OFFSET=";
+   
+   const char REV_DESC [REV_DESC_SIZE + 1]
+      = " REV";
+      
+   const char SPACE[] = " ";
+
+   //***
+   // Start at beginning of the stream.
+   //***
+   os.seekp(0, ios::beg);
+   os << setiosflags(ios::fixed)  // Disable scientific mode.
+      << setiosflags(ios::left)
+       
+      << PRODUCT_ID_DESC
+      << setw(PRODUCT_ORDER_NUMBER_SIZE)
+      << theProductOrderNumber
+
+      << WRS_DESC         
+      << setw(PATH_ROW_NUMBER_SIZE) 
+      << thePathRowNumber
+
+      << DATE_DESC
+      << setw(DATE_SIZE) 
+      << theAcquisitionDate
+
+      << SATELLITE_NUMBER_DESC
+      << setw(SAT_NUMBER_SIZE) 
+      << theSatNumber 
+
+      << INSTRUMENT_TYPE_DESC
+      << setw(INSTRUMENT_TYPE_SIZE) 
+      << theInstrumentType
+
+      << PRODUCT_TYPE_DESC
+      << setw(PRODUCT_TYPE_SIZE) 
+      << theProductType
+
+      << PRODUCT_SIZE_DESC
+      << setw(PRODUCT_SIZE_SIZE) 
+      << theProductSize
+
+      << setw(MAP_SHEET_SIZE)
+      << theMapSheetName
+
+      << PROCESSING_TYPE_DESC
+      << setw(PROCESSING_TYPE_SIZE) 
+      << theProcessingType
+
+      << RESAMPLING_ALGO_DESC
+      << setw(RESAMPLING_ALGO_SIZE) 
+      << theResampAlgorithm
+
+      << RADIANCE_DESC;
+
+   int i;
+   for (i=0; i<NUMBER_OF_BANDS-1; i++) // Ouput six of the seven bands.
+   {
+      os << setw(RADIANCE_SIZE) << theBandRadiance[i] << SPACE;
+   }
+
+   os << setw(RADIANCE_SIZE) << theBandRadiance[6] // Last one no space.
+
+      << VOLUME_NUMBER_DESC
+      << setw(VOLUME_NUMBER_SIZE) 
+      << theVolumeNumber
+
+      << resetiosflags(ios::left)
+      << setiosflags(ios::right)
+
+      << FIRST_LINE_DESC
+      << setw(FIRST_LINE_IN_VOLUME_SIZE) 
+      << the1stLineInVolume
+
+      << LINES_PER_VOLUME_DESC 
+      << setw(LINES_PER_VOLUME_SIZE) 
+      << theLinesPerVolume 
+
+      << ORIENTATION_ANGLE_DESC 
+      << setprecision(2) << setw(ORIENTATION_ANGLE_SIZE) 
+      << theOrientationAngle  
+
+      << MAP_PROJ_NAME_DESC
+      << setw(MAP_PROJ_NAME_SIZE) 
+      << theMapProjName
+
+      << USGS_PROJ_NUMBER_DESC 
+      << setw(USGS_PROJ_NUMBER_SIZE) 
+      << theUsgsProjNumber 
+
+      << USGS_MAP_ZONE_DESC 
+      << setw(USGS_MAP_ZONE_SIZE) 
+      << theUsgsMapZone 
+
+      << PROJECTION_PARAMETER_DESC;
+
+   for (i=0; i<NUMBER_OF_PROJECTION_PARAMETERS; i++)
+   {
+      os << setw(USGS_PROJ_PARAMS_SIZE)
+         << theUsgsProjParam[i];
+   }
+
+   
+   os << setiosflags(ios::left)
+
+      << ELLIPSOID_DESC
+      << setw(ELLIPSOID_SIZE)
+      << theEllipsoid
+      << resetiosflags(ios::left)
+      << setprecision(3)
+
+      << setiosflags(ios::right)
+
+      << MAJOR_AXIS_DESC
+      << setw(MAJOR_AXIS_SIZE) 
+      << theSemiMajorAxis 
+
+      << MINOR_AXIS_DESC
+      << setw(MINOR_AXIS_SIZE) 
+      << theSemiMinorAxis
+
+      << setprecision(2)
+
+      << PIXEL_GSD_DESC
+      << setw(PIXEL_GSD_SIZE) 
+      << theGsd
+      
+      << PIXELS_PER_LINE_DESC
+      << setw(PIXELS_PER_LINE_SIZE) 
+      << thePixelsPerLine
+ 
+      << LINES_PER_IMAGE_DESC
+      << setw(LINES_PER_IMAGE_SIZE) 
+      << theLinesPerImage
+
+      << setprecision(3)
+
+      << UL_DESC
+      << setw(LON_SIZE)
+      << theUlLon
+      << SPACE
+      << setw(LAT_SIZE)
+      << theUlLat
+      << SPACE
+      << setw(EASTING_SIZE)
+      << theUlEasting
+      << SPACE
+      << setw(NORTHING_SIZE) 
+      << theUlNorthing
+
+      << UR_DESC
+      << setw(LON_SIZE)
+      << theUrLon
+      << SPACE
+      << setw(LAT_SIZE)
+      << theUrLat
+      << SPACE
+      << setw(EASTING_SIZE)
+      << theUrEasting
+      << SPACE
+      << setw(NORTHING_SIZE) 
+      << theUrNorthing
+
+      << LR_DESC
+      << setw(LON_SIZE)
+      << theLrLon
+      << SPACE
+      << setw(LAT_SIZE)
+      << theLrLat
+      << SPACE
+      << setw(EASTING_SIZE)
+      << theLrEasting
+      << SPACE
+      << setw(NORTHING_SIZE) 
+      << theLrNorthing
+
+      << LL_DESC
+      << setw(LON_SIZE)
+      << theLlLon
+      << SPACE
+      << setw(LAT_SIZE)
+      << theLlLat
+      << SPACE
+      << setw(EASTING_SIZE)
+      << theLlEasting
+      << SPACE
+      << setw(NORTHING_SIZE) 
+      << theLlNorthing
+
+      << resetiosflags(ios::right);
+
+   os << BANDS_PRESENT_DESC
+      << setw(BANDS_PRESENT_SIZE) 
+      << theBandsPresentString
+
+      << BLOCKING_FACTOR_DESC
+      << setw(BLOCKING_FACTOR_SIZE) 
+      << theBlockingFactor
+
+      << RECORD_LENGTH_DESC
+      << setw(RECORD_LENGTH_SIZE) 
+      << theRecordSize
+         
+      << SUN_ELEVATION_DESC
+      << setw(SUN_ELEVATION_SIZE) 
+      << theSunElevation
+         
+      << SUN_AZIMUTH_DESC
+      << setw(SUN_AZIMUTH_SIZE) 
+      << theSunAzimuth
+         
+      << CENTER_DESC 
+      << setw(LON_SIZE) 
+      << theCenterLon 
+      << SPACE
+      << setw(LAT_SIZE)
+      << theCenterLat
+      << SPACE
+      << setiosflags(ios::right)
+      << setw(EASTING_SIZE)
+      << theCenterEasting
+      << SPACE
+      << setw(NORTHING_SIZE)
+      << theCenterNorthing
+      << setw(CENTER_SAMPLE_SIZE)
+      << theCenterSample
+      << setw(CENTER_LINE_SIZE)
+      << theCenterLine
+
+      << OFFSET_DESC
+      << setw(OFFSET_SIZE)
+      << theOffset
+
+      << REV_DESC
+      << setw(FORMAT_VERSION_SIZE)
+      << theFormatVersion << flush;  // Byte count of file should be 1536.
+
+}
+
+
+//***************************************************************************
+// PRIVATE METHOD:
+// ossimFfRevb::loadFromStream(istream& is)
+// Initializes data members from an EOSAT Fast Format Rev B header.
+//***************************************************************************
+void ossimFfRevb::loadFromStream(istream& is)
+{
+   if (!is)
+   {
+      theErrorStatus = OSSIM_ERROR;
+
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream:\n"
+                                          << "Null stream passed in.  Returning from method."
+                                          << std::endl;
+      return;
+   }
+
+   //***
+   // See .h for enumerations for field sizes and offsets. 
+   //***
+
+   //***
+   // NOTE:  Because of header inconsistencies all seeks will be relative to
+   //        the beginning of the stream.
+   //***
+
+   //***
+   // Temporary buffer for fields that need to be converted to integers or
+   // floats.
+   //***
+   char tmpBuff[25];
+
+   int i; // For iterations.
+
+   is.seekg(PRODUCT_ORDER_NUMBER_OFFSET, ios::beg);
+   is.get(theProductOrderNumber, 
+          PRODUCT_ORDER_NUMBER_SIZE + 1,
+          ' ');
+   if (checkStream(is)) return;
+ 
+   is.seekg(PATH_ROW_NUMBER_OFFSET, ios::beg);
+   is.get(thePathRowNumber, PATH_ROW_NUMBER_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(DATE_OFFSET, ios::beg);
+   is.get(theAcquisitionDate, DATE_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(SAT_NUMBER_OFFSET, ios::beg);
+   is.get(theSatNumber, SAT_NUMBER_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(INSTRUMENT_TYPE_OFFSET, ios::beg);
+   is.get(theInstrumentType, INSTRUMENT_TYPE_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(PRODUCT_TYPE_OFFSET, ios::beg);
+   is.get(theProductType, PRODUCT_TYPE_SIZE+ 1);
+   if (checkStream(is)) return;
+
+   is.seekg(PRODUCT_SIZE_OFFSET, ios::beg);
+   is.get(theProductSize, PRODUCT_SIZE_SIZE+ 1);
+   if (checkStream(is)) return;
+
+   is.seekg(MAP_SHEET_NAME_OFFSET, ios::beg);
+   is.get(theMapSheetName, MAP_SHEET_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(PROCESSING_TYPE_OFFSET, ios::beg);
+   is.get(theProcessingType, PROCESSING_TYPE_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(RESAMPLING_ALGO_OFFSET, ios::beg);
+   is.get(theResampAlgorithm, RESAMPLING_ALGO_SIZE + 1);
+   if (checkStream(is)) return;
+
+   for (i=0; i<NUMBER_OF_BANDS; i++)
+   {      
+      is.seekg(RADIANCE_OFFSET[i], ios::beg);
+      is.get(theBandRadiance[i], RADIANCE_SIZE + 1);
+      if (checkStream(is)) return;
+   }
+
+   is.seekg(VOLUME_NUMBER_OFFSET, ios::beg);
+   is.get(theVolumeNumber, VOLUME_NUMBER_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(FIRST_LINE_IN_VOLUME_OFFSET, ios::beg);
+   is.get(tmpBuff, FIRST_LINE_IN_VOLUME_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      the1stLineInVolume = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading 1st line in volume." << std::endl;
+   }
+
+   is.seekg(LINES_PER_VOLUME_OFFSET, ios::beg);
+   is.get(tmpBuff, LINES_PER_VOLUME_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theLinesPerVolume = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "\tDetected an error reading the lines per volume." << std::endl;
+   }
+   
+   is.seekg(ORIENTATION_ANGLE_OFFSET, ios::beg);
+   is.get(tmpBuff, ORIENTATION_ANGLE_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theOrientationAngle = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading orientation angle." << std::endl;
+   }
+
+   is.seekg(MAP_PROJ_NAME_OFFSET, ios::beg);
+   is.get(theMapProjName, MAP_PROJ_NAME_SIZE + 1);
+   if (checkStream(is)) return;
+   
+   is.seekg(USGS_PROJ_NUMBER_OFFSET, ios::beg);
+   is.get(tmpBuff, USGS_PROJ_NUMBER_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theUsgsProjNumber = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading USGS Projection Number." << std::endl;
+   }
+
+   is.seekg(USGS_MAP_ZONE_OFFSET, ios::beg);
+   is.get(tmpBuff, USGS_MAP_ZONE_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theUsgsMapZone = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading USGS Projection Number." << std::endl;
+   }
+
+   //***
+   // Get the fifteen projection parameters.
+   //***
+   for (i=0; i < NUMBER_OF_PROJECTION_PARAMETERS; i++)
+   {
+      is.seekg(PROJ_PARAM_OFFSET[i], ios::beg);
+      is.get(theUsgsProjParam[i], USGS_PROJ_PARAMS_SIZE + 1);
+      if (checkStream(is)) return;
+   }
+   
+   is.seekg(ELLIPSOID_OFFSET, ios::beg);
+   is.get(theEllipsoid, ELLIPSOID_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(MAJOR_AXIS_OFFSET, ios::beg);
+   is.get(tmpBuff,  MAJOR_AXIS_SIZE+ 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theSemiMajorAxis = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading semi major axis." << std::endl;
+   }
+   
+   is.seekg(MINOR_AXIS_OFFSET, ios::beg);
+   is.get(tmpBuff,  MINOR_AXIS_SIZE+ 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theSemiMinorAxis = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading semi minor axis." << std::endl;
+   }
+
+   is.seekg(PIXEL_GSD_OFFSET, ios::beg);
+   is.get(tmpBuff, PIXEL_GSD_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theGsd = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading pixel size." << std::endl;
+   }
+   
+   is.seekg(PIXELS_PER_LINE_OFFSET, ios::beg);
+   is.get(tmpBuff, PIXELS_PER_LINE_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      thePixelsPerLine = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading pixels per line." << std::endl;
+   }
+
+   is.seekg(LINES_PER_IMAGE_OFFSET, ios::beg);
+   is.get(tmpBuff, LINES_PER_IMAGE_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theLinesPerImage = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream:"
+                                          << "Detected an error reading lines per image." << std::endl;
+   }
+
+   //***
+   // Start of upper left data:  longitude, latitude, easting, and northing. 
+   //***
+   is.seekg(UL_LON_OFFSET, ios::beg);
+   is.get(theUlLon, LON_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(UL_LAT_OFFSET, ios::beg);
+   is.get(theUlLat, LAT_SIZE + 1);
+   if (checkStream(is)) return;
+   
+   is.seekg(UL_EASTING_OFFSET, ios::beg);
+   is.get(tmpBuff, EASTING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theUlEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream:"
+                                          << "Detected an error reading UL easting." << std::endl;
+   }
+
+   is.seekg(UL_NORTHING_OFFSET, ios::beg);
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theUlNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream:: "
+                                          << "Detected an error reading UL northing." << std::endl;
+   }
+   //***
+   // End of upper left data.
+   //***
+
+   //***
+   // Start of upper right data: longitude, latitude, easting, and northing. 
+   //***
+   is.seekg(UR_LON_OFFSET, ios::beg);
+   is.get(theUrLon, LON_SIZE + 1);
+   if (checkStream(is)) return;
+   
+   is.seekg(UR_LAT_OFFSET, ios::beg);
+   is.get(theUrLat, LAT_SIZE + 1);
+   if (checkStream(is)) return;
+   
+   is.seekg(UR_EASTING_OFFSET, ios::beg);
+   is.get(tmpBuff, EASTING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theUrEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading UR easting." << std::endl;
+   }
+
+   is.seekg(UR_NORTHING_OFFSET, ios::beg);
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theUrNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading UR northing." << std::endl;
+   }
+   //***
+   // End of upper right data.
+   //***
+
+   //***
+   // Start of lower right data: longitude, latitude, easting, and northing. 
+   //***
+   is.seekg(LR_LON_OFFSET, ios::beg);
+   is.get(theLrLon, LON_SIZE + 1);
+   if (checkStream(is)) return;
+   
+   is.seekg(LR_LAT_OFFSET, ios::beg);
+   is.get(theLrLat, LAT_SIZE + 1);
+   if (checkStream(is)) return;
+   
+   is.seekg(LR_EASTING_OFFSET, ios::beg);
+   is.get(tmpBuff, EASTING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theLrEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading LR easting." << std::endl;
+   }
+
+   is.seekg(LR_NORTHING_OFFSET, ios::beg);
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theLrNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading LR northing." << std::endl;
+   }
+   //***
+   // End of lower right data.
+   //***
+
+   //***
+   // Start of lower left data:  longitude, latitude, easting, and northing. 
+   //***
+   is.seekg(LL_LON_OFFSET, ios::beg);
+   is.get(theLlLon, LON_SIZE + 1);
+   if (checkStream(is)) return;
+   
+   is.seekg(LL_LAT_OFFSET, ios::beg);
+   is.get(theLlLat, LAT_SIZE + 1);
+   if (checkStream(is)) return;
+   
+   is.seekg(LL_EASTING_OFFSET, ios::beg);
+   is.get(tmpBuff, EASTING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theLlEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading LL easting." << std::endl;
+   }
+
+   is.seekg(LL_NORTHING_OFFSET, ios::beg);
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theLlNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading LL northing." << std::endl;
+   }
+   //***
+   // End of lower left data.
+   //***
+
+   is.seekg(BANDS_PRESENT_OFFSET, ios::beg);
+   is.get(theBandsPresentString, BANDS_PRESENT_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(BLOCKING_FACTOR_OFFSET, ios::beg);
+   is.get(tmpBuff, BLOCKING_FACTOR_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theBlockingFactor = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading the blocking factor." << std::endl;
+   }
+
+   is.seekg(RECORD_LENGTH_OFFSET, ios::beg);
+   is.get(tmpBuff, RECORD_LENGTH_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theRecordSize = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading record size." << std::endl;
+   }
+
+   is.seekg(SUN_ELEVATION_OFFSET, ios::beg);
+   is.get(tmpBuff, SUN_ELEVATION_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theSunElevation = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading sun elevation angle." << std::endl;
+   }
+
+   is.seekg(SUN_AZIMUTH_OFFSET, ios::beg);
+   is.get(tmpBuff, SUN_AZIMUTH_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theSunAzimuth = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL  ossimFfRevb::loadFromStream:"
+                                          << "\tDetected an error reading sun azimuth." << std::endl;
+   }
+
+   //***
+   // Start of scene center data:  longitude, latitude, easting, northing,
+   // sample, line. 
+   //***
+   is.seekg(CENTER_LON_OFFSET, ios::beg);
+   is.get(theCenterLon, LON_SIZE + 1);
+   if (checkStream(is)) return;
+
+   is.seekg(CENTER_LAT_OFFSET, ios::beg);
+   is.get(theCenterLat, LAT_SIZE + 1);
+   if (checkStream(is)) return;
+   
+   is.seekg(CENTER_EASTING_OFFSET, ios::beg);
+   is.get(tmpBuff, EASTING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theCenterEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading center easting." << std::endl;
+   }
+
+   is.seekg(CENTER_NORTHING_OFFSET, ios::beg);
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theCenterNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading center northing." << std::endl;
+   }
+
+   is.seekg(CENTER_SAMPLE_OFFSET, ios::beg);
+   is.get(tmpBuff, CENTER_SAMPLE_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theCenterSample = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading center sample." << std::endl;
+   }
+
+   is.seekg(CENTER_LINE_OFFSET, ios::beg);
+   is.get(tmpBuff, CENTER_LINE_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theCenterLine = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading center line." << std::endl;
+   }
+   //***
+   // End of scene center data.
+   //***
+
+   is.seekg(OFFSET_OFFSET, ios::beg);
+   is.get(tmpBuff, OFFSET_SIZE + 1);
+   if (checkStream(is)) return;
+   if (tmpBuff)
+   {
+      theOffset = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL  ossimFfRevb::loadFromStream: "
+                                          << "Detected an error reading horizontal offset." << std::endl;
+   }
+
+   is.seekg(FORMAT_VERSION_OFFSET, ios::beg);
+   is.get(theFormatVersion, FORMAT_VERSION_SIZE + 1);
+   if (checkStream(is)) return;
+
+}
+
+//***************************************************************************
+// PRIVATE METHOD:
+// ossimFfRevb::checkStream(istream& is)
+//
+// Checks the stream.  If an error has occurred it sets theErrorStatus.
+// Returns: theErrorStatus    ( 0 = OK,  1 = ERROR )
+//***************************************************************************
+int ossimFfRevb::checkStream(istream& is)
+{
+   //***
+   // istreams set fault bits and the operator! is overloaded to return
+   // true if an error has occurred.
+   //***
+   if (!is)
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "ossimFfRevb::checkStream ERROR: "
+                                          << "Stream corrupted.   Returning from method."
+                                          << std::endl;
+   } 
+   return theErrorStatus;
+}
+   
+//***************************************************************************
+// Function:
+// ostream& operator<<(ostream& os, const ossimFfRevb& head)
+//***************************************************************************
+ostream& operator<<(ostream& os, const ossimFfRevb& head)
+{
+   head.print(os);
+
+   return os;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_revb/ossimFfRevb.h b/Utilities/OSSIM/ossim_core/support_data/ff_revb/ossimFfRevb.h
new file mode 100644
index 0000000000..8fd2537af9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_revb/ossimFfRevb.h
@@ -0,0 +1,303 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Dave Burken (dburken@imagelinks.com)
+// Description: This class parses an EOSAT Fast Format rev b header.
+//
+//********************************************************************
+// $Id: ossimFfRevb.h,v 1.1.1.1 2001/02/05 20:13:28 dburken Exp $
+
+#ifndef ossimFfRevb_HEADER
+#define ossimFfRevb_HEADER
+#include <iostream>
+using namespace std;
+
+//***************************************************************************
+// CLASS: ossimFfRevb.h
+//***************************************************************************
+class ossimFfRevb
+{
+public:
+   ossimFfRevb  ();
+   ossimFfRevb  (const char* headerFile);
+   ~ossimFfRevb (){};
+
+   enum ErrorStatus
+   {
+      OSSIM_OK    = 0,
+      OSSIM_ERROR = 1
+   };
+
+   //***
+   // Enumerations for parsing header.  Contains size in bytes
+   // for all fields.
+   // 
+   // NOTE:  Sizes are the actual number of bytes for that field so add
+   //        one for trailing '\0' to get the string length for the
+   //        data member that are character arrays.
+   //***
+   enum
+   {
+      NUMBER_OF_PROJECTION_PARAMETERS = 15,
+      NUMBER_OF_BANDS                 = 7
+   };
+   
+   enum
+   {
+      PRODUCT_ORDER_NUMBER_DESC_SIZE      = 9,
+      PRODUCT_ORDER_NUMBER_SIZE           = 11,
+      WRS_DESC_SIZE                       = 6,
+      PATH_ROW_NUMBER_SIZE                = 9,
+      DATE_DESC_SIZE                      = 19,
+      DATE_SIZE                           = 8,
+      SAT_NUMBER_DESC_SIZE                = 12,
+      SAT_NUMBER_SIZE                     = 2,
+      INSTRUMENT_TYPE_DESC_SIZE           = 13,
+      INSTRUMENT_TYPE_SIZE                = 4,
+      PRODUCT_TYPE_DESC_SIZE              = 15,
+      PRODUCT_TYPE_SIZE                   = 14,
+      PRODUCT_SIZE_DESC_SIZE              = 15,
+      PRODUCT_SIZE_SIZE                   = 10,
+      MAP_SHEET_SIZE                      = 78,
+      PROCESSING_TYPE_DESC_SIZE           = 30,
+      PROCESSING_TYPE_SIZE                = 10,
+      RESAMPLING_ALGO_DESC_SIZE           = 13,
+      RESAMPLING_ALGO_SIZE                = 2,
+      RADIANCE_DESC_SIZE                  = 20,
+      RADIANCE_SIZE                       = 16,
+      VOLUME_NUMBER_DESC_SIZE             = 20,
+      VOLUME_NUMBER_SIZE                  = 3,
+      FIRST_LINE_DESC_SIZE                = 14,
+      FIRST_LINE_IN_VOLUME_SIZE           = 5,
+      LINES_PER_VOLUME_DESC_SIZE          = 15,
+      LINES_PER_VOLUME_SIZE               = 5,
+      ORIENTATION_ANGLE_DESC_SIZE         = 14,
+      ORIENTATION_ANGLE_SIZE              = 6,
+      MAP_PROJ_NAME_DESC_SIZE             = 13,
+      MAP_PROJ_NAME_SIZE                  = 4,
+      USGS_PROJ_NUMBER_DESC_SIZE          = 20,
+      USGS_PROJ_NUMBER_SIZE               = 6,
+      USGS_MAP_ZONE_DESC_SIZE             = 16,
+      USGS_MAP_ZONE_SIZE                  = 6,
+      USGS_PROJ_PARAMS_DESC_SIZE          = 29,
+      USGS_PROJ_PARAMS_SIZE               = 24,
+      ELLIPSOID_DESC_SIZE                 = 18,
+      ELLIPSOID_SIZE                      = 20,
+      MAJOR_AXIS_DESC_SIZE                = 18,
+      MAJOR_AXIS_SIZE                     = 11,
+      MINOR_AXIS_DESC_SIZE                = 18,
+      MINOR_AXIS_SIZE                     = 11,
+      PIXEL_GSD_DESC_SIZE                 = 13,
+      PIXEL_GSD_SIZE                      = 5,
+      PIXELS_PER_LINE_DESC_SIZE           = 17,
+      PIXELS_PER_LINE_SIZE                = 5,
+      LINES_PER_IMAGE_DESC_SIZE           = 17,
+      LINES_PER_IMAGE_SIZE                = 5,
+      CORNER_DESC_SIZE                    = 4,
+      LON_SIZE                            = 13,
+      LAT_SIZE                            = 12,
+      EASTING_SIZE                        = 13,
+      NORTHING_SIZE                       = 13,
+      BANDS_PRESENT_DESC_SIZE             = 16,
+      BANDS_PRESENT_SIZE                  = 7,
+      BLOCKING_FACTOR_DESC_SIZE           = 18,
+      BLOCKING_FACTOR_SIZE                = 4,
+      RECORD_LENGTH_DESC_SIZE             = 16,
+      RECORD_LENGTH_SIZE                  = 5,
+      SUN_ELEVATION_DESC_SIZE             = 16,
+      SUN_ELEVATION_SIZE                  = 2,
+      SUN_AZIMUTH_DESC_SIZE               = 14,
+      SUN_AZIMUTH_SIZE                    = 3,
+      CENTER_DESC_SIZE                    = 8,
+      CENTER_SAMPLE_SIZE                  = 6,
+      CENTER_LINE_SIZE                    = 6,
+      OFFSET_DESC_SIZE                    = 8,
+      OFFSET_SIZE                         = 4,
+      REV_DESC_SIZE                       = 4,
+      FORMAT_VERSION_SIZE                 = 1
+   };
+      
+   //***
+   // Enumerations for byte offsets in header.  All offsets are relative to
+   // the first byte of the first record which is byte 0.
+   //***
+   enum
+   {
+      // One record:  bytes 0 - 1535
+      PRODUCT_ORDER_NUMBER_OFFSET           = 9,
+      PATH_ROW_NUMBER_OFFSET                = 26,
+      DATE_OFFSET                           = 54,
+      SAT_NUMBER_OFFSET                     = 74,
+      INSTRUMENT_TYPE_OFFSET                 = 89,
+      PRODUCT_TYPE_OFFSET                   = 108,
+      PRODUCT_SIZE_OFFSET                   = 137,
+      MAP_SHEET_NAME_OFFSET                 = 147,
+      PROCESSING_TYPE_OFFSET                = 255,
+      RESAMPLING_ALGO_OFFSET                = 278,
+      VOLUME_NUMBER_OFFSET                  = 438,
+      FIRST_LINE_IN_VOLUME_OFFSET           = 455,
+      LINES_PER_VOLUME_OFFSET               = 475,
+      ORIENTATION_ANGLE_OFFSET              = 494,
+      MAP_PROJ_NAME_OFFSET                  = 513,
+      USGS_PROJ_NUMBER_OFFSET               = 537,
+      USGS_MAP_ZONE_OFFSET                  = 559,
+      ELLIPSOID_OFFSET                      = 972,
+      MAJOR_AXIS_OFFSET                     = 1010,
+      MINOR_AXIS_OFFSET                     = 1039,
+      PIXEL_GSD_OFFSET                      = 1063,
+      PIXELS_PER_LINE_OFFSET                = 1085,
+      LINES_PER_IMAGE_OFFSET                = 1107, 
+      UL_LON_OFFSET                         = 1116,
+      UL_LAT_OFFSET                         = 1130,
+      UL_EASTING_OFFSET                     = 1143,
+      UL_NORTHING_OFFSET                    = 1157,
+      UR_LON_OFFSET                         = 1174,
+      UR_LAT_OFFSET                         = 1188,
+      UR_EASTING_OFFSET                     = 1201,
+      UR_NORTHING_OFFSET                    = 1215,
+      LR_LON_OFFSET                         = 1232,
+      LR_LAT_OFFSET                         = 1246,
+      LR_EASTING_OFFSET                     = 1259,
+      LR_NORTHING_OFFSET                    = 1273,
+      LL_LON_OFFSET                         = 1290,
+      LL_LAT_OFFSET                         = 1304,
+      LL_EASTING_OFFSET                     = 1317,
+      LL_NORTHING_OFFSET                    = 1331,
+      BANDS_PRESENT_OFFSET                  = 1360,
+      BLOCKING_FACTOR_OFFSET                = 1385,
+      RECORD_LENGTH_OFFSET                  = 1405,
+      SUN_ELEVATION_OFFSET                  = 1426, 
+      SUN_AZIMUTH_OFFSET                    = 1442,
+      CENTER_LON_OFFSET                     = 1453,
+      CENTER_LAT_OFFSET                     = 1467,
+      CENTER_EASTING_OFFSET                 = 1480,
+      CENTER_NORTHING_OFFSET                = 1494,
+      CENTER_SAMPLE_OFFSET                  = 1507,
+      CENTER_LINE_OFFSET                    = 1513,
+      OFFSET_OFFSET                         = 1527,
+      FORMAT_VERSION_OFFSET                 = 1535 };
+
+   int errorStatus() const { return theErrorStatus; }
+
+   void print(ostream& os) const;
+
+   void write(ostream& os) const;
+
+   int    path() const;
+      //> Returns the path as an int.
+      //<
+   int    row() const;
+      //> Returns the row as an int from the pathRowString.
+      //<
+   int    fraction() const;
+      //> Returns the fraction as an int from the pathRowString.
+      //<
+   double projParam(int paramNumber) const;
+      //>  Converts the USGS Projection Parameter string, which has a
+      //   "D" to denote the exponent, to a double.
+      //<
+
+   friend ostream& operator<<(ostream& os, const ossimFfRevb& head);
+     
+   char   theProductOrderNumber[PRODUCT_ORDER_NUMBER_SIZE + 1];
+   char   thePathRowNumber[PATH_ROW_NUMBER_SIZE + 1];   
+   char   theAcquisitionDate[DATE_SIZE + 1];
+      //> yyyyddmm
+      //<
+   char   theSatNumber[SAT_NUMBER_SIZE + 1];
+      //> L4, L5, 1B, 1C
+      //<
+   char   theInstrumentType[INSTRUMENT_TYPE_SIZE + 1];
+      //> TM, LISS1 LISS2, LISS3, PAN, WIFS
+      //<
+   char   theProductType[PRODUCT_TYPE_SIZE + 1]; // MAP or ORBIT oriented
+   char   theProductSize[PRODUCT_SIZE_SIZE + 1]; // FULL, SUB, MAP
+      //> SYSTEMATIC, PRECISION, TERRAIN RADIOMETRIC
+      //<
+   char   theMapSheetName[MAP_SHEET_SIZE + 1];
+   char   theProcessingType[PROCESSING_TYPE_SIZE + 1];
+      //> SYSTEMATIC, PRECISION, TERRAIN RADIOMETRIC
+      //<
+   char   theResampAlgorithm[RESAMPLING_ALGO_SIZE + 1]; // CC, NN or BL
+   char   theBandRadiance[NUMBER_OF_BANDS][RADIANCE_SIZE + 1];
+   char   theVolumeNumber[VOLUME_NUMBER_SIZE + 1];
+   int    the1stLineInVolume;
+   int    theLinesPerVolume;
+   double theOrientationAngle;   // degrees
+   char   theMapProjName[MAP_PROJ_NAME_SIZE + 1];
+   int    theUsgsProjNumber;
+   int    theUsgsMapZone;
+   char   theUsgsProjParam[NUMBER_OF_PROJECTION_PARAMETERS]
+                          [USGS_PROJ_PARAMS_SIZE + 1];
+      //>  USGS Projection Parameters.  These are actually a string
+      //   representing doubles; however, EOSAT uses a "D" for the
+      //   exponent notation, so they are read in as a char*.
+      //   To convert to double use the method "projParam".
+      //<
+   char   theEllipsoid[ELLIPSOID_SIZE + 1];
+   double theSemiMajorAxis;
+   double theSemiMinorAxis;
+   double theGsd;             // pixel size in meters
+   int    thePixelsPerLine;   // samples
+   int    theLinesPerImage;   // lines
+
+   char    theUlLon[LON_SIZE + 1]; // deg, min, sec
+   char    theUlLat[LAT_SIZE + 1]; // deg, min, sec
+   double  theUlEasting;           // meters
+   double  theUlNorthing;          // meters
+   
+   char    theUrLon[LON_SIZE + 1]; // deg, min, sec
+   char    theUrLat[LAT_SIZE + 1]; // deg, min, sec
+   double  theUrEasting;           // meters
+   double  theUrNorthing;          // meters
+   
+   char    theLrLon[LON_SIZE + 1]; // deg, min, sec
+   char    theLrLat[LAT_SIZE + 1]; // deg, min, sec
+   double  theLrEasting;           // meters
+   double  theLrNorthing;          // meters
+   
+   char    theLlLon[LON_SIZE + 1]; // deg, min, sec
+   char    theLlLat[LAT_SIZE + 1]; // deg, min, sec
+   double  theLlEasting;           // meters
+   double  theLlNorthing;          // meters
+
+   char    theBandsPresentString[BANDS_PRESENT_SIZE + 1];
+   int     theBlockingFactor;
+   int     theRecordSize;
+   int     theSunElevation;        // degrees
+   int     theSunAzimuth;          // degrees
+
+   char    theCenterLon[LON_SIZE + 1]; // deg, min, sec
+   char    theCenterLat[LAT_SIZE + 1]; // deg, min, sec
+   double  theCenterEasting;           // meters
+   double  theCenterNorthing;          // meters
+   int     theCenterSample;       // Nearest whole pixel.
+   int     theCenterLine;         // Nearest whole pixel.
+   int     theOffset;   // pixels
+   char    theFormatVersion[FORMAT_VERSION_SIZE + 1];
+
+private:
+   void loadFromStream(istream& is);
+
+   int checkStream(istream& is);
+
+   ErrorStatus theErrorStatus;
+};
+   
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_revc/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/ff_revc/.cvsignore
new file mode 100644
index 0000000000..7df3918588
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_revc/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+Makefile
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_revc/ossimFfRevc.cpp b/Utilities/OSSIM/ossim_core/support_data/ff_revc/ossimFfRevc.cpp
new file mode 100644
index 0000000000..ecdfd0fa3b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_revc/ossimFfRevc.cpp
@@ -0,0 +1,1956 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Dave Burken (dburken@imagelinks.com)
+// Description: This class parses an EOSAT Fast Format rev c header.
+//
+//********************************************************************
+// $Id: ossimFfRevc.cpp,v 1.3 2004/04/07 16:39:34 gpotts Exp $
+
+#include <fstream>
+#include <sstream>
+#include <iomanip>
+using namespace std;
+
+#include <cstdlib>
+#include <cstring>
+
+#include <support_data/ff_revc/ossimFfRevc.h>
+#include <base/data_types/ossimString.h>
+#include <base/context/ossimNotifyContext.h>
+
+const int LOCATION_OFFSET [4] = { 23,
+                                  183,
+                                  343,
+                                  503 };
+
+const int PATH_ROW_NUMBER_OFFSET [4] = { 34,
+                                         194,
+                                         354,
+                                         514 };
+
+const int DATE_OFFSET [4] = { 70,
+                              230,
+                              390,
+                              550 };
+
+const int SAT_NAME_OFFSET [4] = { 91,
+                                  251,
+                                  411,
+                                  571 };
+
+const int SENSOR_NAME_OFFSET [4] = { 110,
+                                     270,
+                                     430,
+                                     590 };
+
+const int SENSOR_MODE_OFFSET [4] = { 134,
+                                     294,
+                                     454,
+                                     614 };
+
+const int OFF_NADIR_ANGLE_OFFSET [4] = { 153, 
+                                         313,
+                                         473,
+                                         633 };
+
+
+const int BIAS_OFFSET [8] = { 1616,
+                              1696,
+                              1776,
+                              1856,
+                              1936,
+                              2016,
+                              2096,
+                              2176  };
+
+const int GAIN_OFFSET [8] = { 1641,
+                              1721,
+                              1801,
+                              1881,
+                              1961,
+                              2041,
+                              2121,
+                              2201  };
+
+static const int PROJ_PARAM_OFFSET [15]  = { 3181,
+                                      3206,
+                                      3232,
+                                      3257,
+                                      3282,
+                                      3312,
+                                      3337,
+                                      3362,
+                                      3392,
+                                      3417,
+                                      3442,
+                                      3472,
+                                      3497,
+                                      3522,
+                                      3552  };
+
+static const char BLANK_STRING[] = " ";
+
+//***************************************************************************
+// CONSTRUCTOR
+//***************************************************************************
+ossimFfRevc::ossimFfRevc()
+   :
+      theAdminRecord(),
+      theRadiomRecord(),
+      theGeoRecord(),
+      theErrorStatus(OSSIM_OK)
+{ }
+
+//***************************************************************************
+// CONSTRUCTOR:
+// ossimFfRevc::ossimFfRevc(const char* headerFile)
+//
+// Takes a filename representing an IRS-1C Fast Format rev C header.
+//***************************************************************************
+ossimFfRevc::ossimFfRevc(const char* headerFile)
+   :
+   theErrorStatus(OSSIM_OK)
+{
+   ifstream is;
+
+   is.open(headerFile);
+
+   if (!is)
+   {
+      theErrorStatus = OSSIM_ERROR;
+
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::ossimFfRevc(header): "
+                                          << "Cannot open:  " << headerFile << "\n"
+                                          << "Returning from constructor." << std::endl;
+
+      return;
+   }
+
+   loadFromStream(is);
+
+   is.close();
+
+}
+
+
+//***************************************************************************
+// PUBLIC METHOD:
+// int ossimFfRevc::path(int sceneNbr) const
+//
+// Convenience method to parse the path from the path/row string.  Returns
+// zero if stream is not opened.  Current loacation field is:
+// path/row/fraction/subscene in ppp/rrrffss format.
+//***************************************************************************
+int ossimFfRevc::path(int sceneNbr) const
+{
+   char tmpBuff[4];
+   int path = 0;
+
+   istringstream is(theAdminRecord.thePathRowNumber[sceneNbr]);
+
+   if (is)
+   {
+      is.get(tmpBuff, 4);
+
+      if (tmpBuff)
+      {
+         path = atoi(tmpBuff);
+      }
+   }
+
+   return path;
+}
+
+
+//***************************************************************************
+// PUBLIC METHOD:
+// int ossimFfRevc::row(int sceneNbr) const
+//
+// Convenience method to parse the row from the path/row string.  Returns
+// zero if stream is not opened.  Current loacation field is:
+// path/row/fraction/subscene in ppp/rrrffss format.
+//***************************************************************************
+int ossimFfRevc::row(int sceneNbr) const
+{
+   char tmpBuff[4];
+   int row = 0;
+
+   istringstream is(theAdminRecord.thePathRowNumber[sceneNbr]);
+
+   if (is)
+   {
+      is.seekg(4, ios::beg);
+      is.get(tmpBuff, 4);
+
+      if (tmpBuff)
+      {
+         row = atoi(tmpBuff);
+      }
+   }
+
+   return row;
+}
+
+
+//***************************************************************************
+// PUBLIC METHOD:
+// int ossimFfRevc::fraction(int sceneNbr) const
+//
+// Convenience method to parse the fraction from the path/row string.  Returns
+// zero if stream is not opened.  Current loacation field is:
+// path/row/fraction/subscene in ppp/rrrffss format.
+//***************************************************************************
+int ossimFfRevc::fraction(int sceneNbr) const
+{
+   char tmpBuff[3];
+   int fraction = 0;
+
+   istringstream is(theAdminRecord.thePathRowNumber[sceneNbr]);
+
+   if (is)
+   {
+      is.seekg(7, ios::beg);
+      is.get(tmpBuff, 3);
+
+      if (tmpBuff)
+      {
+         fraction = atoi(tmpBuff);
+      }
+   }
+
+   return fraction;
+}
+
+
+//***************************************************************************
+// PUBLIC METHOD:
+// int ossimFfRevc::subScene(int sceneNbr) const
+//
+// Convenience method to parse the subScene from the path/row string.  Returns
+// zero if stream is not opened.  Current loacation field is:
+// path/row/fraction/subscene in ppp/rrrffss format.
+//***************************************************************************
+ossimString ossimFfRevc::subScene(int sceneNbr) const
+{
+   char   tmpBuff[3];
+   ossimString subScene;
+
+   istringstream is(theAdminRecord.thePathRowNumber[sceneNbr]);
+
+   if (is)
+   {
+      is.seekg(9, ios::beg);
+      is.get(tmpBuff, 3);
+
+      if (tmpBuff)
+      {
+         subScene = tmpBuff;
+      }
+   }
+
+   return subScene;
+}
+
+//***************************************************************************
+// ossimFfRevc::pathRow(int sceneNbr)
+//***************************************************************************
+ossimString ossimFfRevc::pathRow(int sceneNbr) const
+{
+   ossimString tmp = "p";
+
+   tmp += theAdminRecord.thePathRowNumber[sceneNbr];
+
+   tmp.gsub("/", "r");
+
+   tmp.gsub(" ", "");
+
+   return tmp;
+}
+
+//***************************************************************************
+// PUBLIC METHOD:
+// void ossimFfRevc::print(ostream& os) const
+//
+// Prints data members.
+//***************************************************************************
+void ossimFfRevc::print(ostream& os) const
+{
+   os << setiosflags(ios::left | ios::fixed)
+      << "Administrative Record:"
+      << setw(30) << "\ntheProductOrderNumber:" 
+      << theAdminRecord.theProductOrderNumber;
+
+   int i;
+   for (i = 0; i < NUMBER_OF_SCENES; i++)
+   {
+      os << "\nScene" << (i + 1) << setw(23) << " PathRowNumber:"
+         << theAdminRecord.thePathRowNumber[i]
+         << "\nScene" << (i + 1) << setw(23) << " AcquisitionDate:  "
+         << theAdminRecord.theAcquisitionDate[i]
+         << "\nScene" << (i + 1) << setw(23) << " SatelliteName:    "
+         << theAdminRecord.theSatName[i]
+         << "\nScene" << (i + 1) << setw(23) << " SensorName:       "
+         << theAdminRecord.theSensorName[i]
+         << "\nScene" << (i + 1) << setw(23) << " SensorMode:       "
+         << theAdminRecord.theSensorMode[i]
+         << "\nScene" << (i + 1) << setw(23) << " OffNadirAngle:    "
+         << setprecision(2) << theAdminRecord.theOffNadirAngle[i];
+   }
+
+   os << setw(30) << "\nProductType:" 
+      << theAdminRecord.theProductType
+      << setw(30) << "\nProductSize:" 
+      << theAdminRecord.theProductSize
+      << setw(30) << "\nProcessingType:" 
+      << theAdminRecord.theProcessingType 
+      << setw(30) << "\nResampAlgorithm:" 
+      << theAdminRecord.theResampAlgorithm
+      << setw(30) << "\nTapeVolumeNumber:" 
+      << theAdminRecord.theTapeVolumeNumber
+      << setw(30) << "\nNumberVolumesPerTape:" 
+      << theAdminRecord.theNumberVolumesPerTape
+      << setw(30) << "\nPixelsPerLine:" 
+      << theAdminRecord.thePixelsPerLine
+      << setw(30) << "\nLinesPerImage:" 
+      << theAdminRecord.theLinesPerImage
+      << setw(30) << "\n1stLineInVolume:" 
+      << theAdminRecord.the1stLineInVolume
+      << setw(30) << "\nTapeBlockingFactor:" 
+      << theAdminRecord.theTapeBlockingFactor
+      << setw(30) << "\nRecordSize:" 
+      << theAdminRecord.theRecordSize
+      << setw(30) << "\nGsd:" 
+      << setprecision(2) << theAdminRecord.theGsd
+      << setw(30) << "\nOutputBitsPerPixel:" 
+      << theAdminRecord.theOutputBitsPerPixel
+      << setw(30) << "\nAcquiredBitsPerPixel:" 
+      << theAdminRecord.theAcquiredBitsPerPixel
+      << setw(30) << "\nBandsPresentString:" 
+      << theAdminRecord.theBandsPresentString
+      << setw(30) << "\nFormatVersion:" 
+      << theAdminRecord.theFormatVersion
+      << endl 
+      << setw(30) << "Radiometric record:";
+
+   os << setprecision(15);
+
+   for (i = 0; i < NUMBER_OF_BANDS; i++)
+   {
+      os << "\nBand" << (i + 1) << setw(24) << " bias:" 
+         << theRadiomRecord.theBias[i]
+         << "\nBand" << (i + 1) << setw(24) << " gain:" 
+         << theRadiomRecord.theGain[i];
+   }
+
+   os << endl
+      << "Geometric Record:"
+      << setw(30) << "\nMapProjectionName:" 
+      << theGeoRecord.theMapProjectionName
+      << setw(30) << "\nEllipsoid:" 
+      << theGeoRecord.theEllipsoid
+      << setw(30) << "\nDatum:" 
+      << theGeoRecord.theDatum;
+
+   for (i = 0; i < 15; i++)
+   {
+      os << "\nProjectionParams[" << setw(2) << i << setw(10) << "]:  "
+         << theGeoRecord.theProjectionParams[i];
+   }
+
+   os << setprecision(3) 
+      << setw(30) << "\nUlLon:" 
+      << theGeoRecord.theUlLon
+      << setw(30) << "\nUlLat:" 
+      << theGeoRecord.theUlLat
+      << setw(30) << "\nUlEasting:" 
+      << theGeoRecord.theUlEasting
+      << setw(30) << "\nUlNorthing:" 
+      << theGeoRecord.theUlNorthing   
+      << setw(30) << "\nUrLon:" 
+      << theGeoRecord.theUrLon
+      << setw(30) << "\nUrLat:" 
+      << theGeoRecord.theUrLat
+      << setw(30) << "\nUrEasting:" 
+      << theGeoRecord.theUrEasting
+      << setw(30) << "\nUrNorthing:" 
+      << theGeoRecord.theUrNorthing
+      << setw(30) << "\nLrLon:" 
+      << theGeoRecord.theLrLon
+      << setw(30) << "\nLrLat:" 
+      << theGeoRecord.theLrLat
+      << setw(30) << "\nLrEasting:" 
+      << theGeoRecord.theLrEasting
+      << setw(30) << "\nLrNorthing:" 
+      << theGeoRecord.theLrNorthing
+      << setw(30) << "\nLlLon:" 
+      << theGeoRecord.theLlLon
+      << setw(30) << "\nLlLat:" 
+      << theGeoRecord.theLlLat
+      << setw(30) << "\nLlEasting:" 
+      << theGeoRecord.theLlEasting
+      << setw(30) << "\nLlNorthing:" 
+      << theGeoRecord.theLlNorthing
+      << setw(30) << "\nCenterLon:" 
+      << theGeoRecord.theCenterLon
+      << setw(30) << "\nCenterLat:" 
+      << theGeoRecord.theCenterLat
+      << setw(30) << "\nCenterEasting:" 
+      << theGeoRecord.theCenterEasting
+      << setw(30) << "\nCenterNorthing:" 
+      << theGeoRecord.theCenterNorthing
+      << setw(30) << "\nCenterSample:" 
+      << theGeoRecord.theCenterSample
+      << setw(30) << "\nCenterLine:" 
+      << theGeoRecord.theCenterLine
+      << setw(30) << "\nHorizontalOffset:" 
+      << theGeoRecord.theHorizontalOffset
+      << setprecision(2) << setw(30) << "\nOrientationAngle:" 
+      << theGeoRecord.theOrientationAngle
+      << setw(30) << "\nSunElevationAngle:" 
+      << setprecision(1) << theGeoRecord.theSunElevationAngle
+      << setw(30) << "\nSunAzimuth:" <<  theGeoRecord.theSunAzimuth
+      << resetiosflags(ios::left)
+      << endl << endl;
+
+}
+
+//***************************************************************************
+// PUBLIC METHOD:
+// void ossimFfRevc::write(ostream& os) const
+//
+// Writes data members in EOSAT Fast Format Rev C format.
+//***************************************************************************
+void ossimFfRevc::write(ostream& os) const
+{
+   const char PRODUCT_ID_DESC [PRODUCT_ORDER_NUMBER_DESC_SIZE + 1]
+      = "PRODUCT ID =";
+
+   const char LOCATION_DESC [LOCATION_DESC_SIZE + 1]
+      = " LOCATION =";
+
+   const char DATE_DESC [DATE_DESC_SIZE + 1]
+      = " ACQUISITION DATE =";
+   
+   const char SATELLITE_NAME_DESC [SAT_NAME_DESC_SIZE + 1]
+      = "SATELLITE =";
+   
+   const char SENSOR_NAME_DESC [SENSOR_NAME_DESC_SIZE + 1]
+      = " SENSOR =";
+   
+   const char SENSOR_MODE_DESC [SENSOR_MODE_DESC_SIZE + 1]
+      = " SENSOR MODE =";
+      
+   const char LOOK_ANGLE_DESC [LOOK_ANGLE_DESC_SIZE + 1]
+      = " LOOK ANGLE =";
+   
+   const char PRODUCT_TYPE_DESC [PRODUCT_TYPE_DESC_SIZE + 1]
+      = "PRODUCT TYPE =";
+   
+   const char PRODUCT_SIZE_DESC [PRODUCT_SIZE_DESC_SIZE + 1]
+      = " PRODUCT SIZE =";
+   
+   const char PROCESSING_TYPE_DESC [PROCESSING_TYPE_DESC_SIZE + 1]
+      = "TYPE OF PROCESSING =";
+   
+   const char RESAMPLING_ALGO_DESC [RESAMPLING_ALGO_DESC_SIZE + 1]
+      = " RESAMPLING =";
+   
+   const char TAPE_VOLUME_NUMBER_DESC [TAPE_VOLUME_NUMBER_DESC_SIZE + 1]
+      = "VOLUME #/# IN SET =";
+   
+   const char PIXELS_PER_LINE_DESC [PIXELS_PER_LINE_DESC_SIZE + 1]
+      = " PIXELS PER LINE =";
+   
+   const char LINES_PER_IMAGE_DESC [LINES_PER_IMAGE_DESC_SIZE + 1]
+      = " LINES PER BAND =";
+
+   const char  FIRST_LINE_DESC [FIRST_LINE_DESC_SIZE + 1]
+      = "START LINE # =";
+   
+   const char BLOCKING_FACTOR_DESC [BLOCKING_FACTOR_DESC_SIZE + 1]
+      = " BLOCKING FACTOR =";
+   
+   const char RECORD_LENGTH_DESC [RECORD_LENGTH_DESC_SIZE + 1]
+      = " RECORD LENGTH =";
+   
+   const char PIXEL_GSD_DESC [PIXEL_GSD_DESC_SIZE + 1]
+      = " PIXEL SIZE =";
+   
+   const char BITS_PER_PIXEL_DESC [BITS_PER_PIXEL_DESC_SIZE + 1]
+      = "OUTPUT BITS PER PIXEL =";
+   
+   const char AQUIRED_BITS_PER_PIXEL_DESC
+      [AQUIRED_BITS_PER_PIXEL_DESC_SIZE + 1] = " ACQUIRED BITS PER PIXEL =";
+   
+   const char BANDS_PRESENT_DESC [BANDS_PRESENT_DESC_SIZE + 1]
+      = "BANDS PRESENT =";
+   
+   const char REV_DESC [REV_DESC_SIZE + 1]
+      = "REV            ";
+   
+   const char BIAS_GAIN_DESC [BIAS_GAIN_DESC_SIZE + 1]
+      = "BIASES AND GAINS IN THE BAND ORDER AS ON THIS TAPE";
+   
+   const char GEO_DESC [GEO_DESC_SIZE + 1]
+      = "GEOMETRIC DATA";
+   
+   const char MAP_PROJECTION_NAME_DESC [MAP_PROJECTION_NAME_DESC_SIZE + 1]
+      = " MAP PROJECTION =";
+   
+   const char ELLIPSOID_DESC [ELLIPSOID_DESC_SIZE + 1]
+      = " ELLIPSOID =";
+      
+   const char DATUM_DESC [DATUM_DESC_SIZE + 1]
+      = " DATUM =";
+   
+   const char PROJECTION_PARAMETER_DESC [PROJECTION_PARAMETER_DESC_SIZE + 1]
+      = "USGS PROJECTION PARAMETERS =";
+   
+   const char UL_DESC [CORNER_DESC_SIZE + 1]
+      = "UL =";
+
+   const char UR_DESC [CORNER_DESC_SIZE + 1]
+      = "UR =";
+   
+   const char LR_DESC [CORNER_DESC_SIZE + 1]
+      = "LR =";
+   
+   const char LL_DESC [CORNER_DESC_SIZE + 1]
+      = "LL =";
+   
+   const char CENTER_DESC [CENTER_DESC_SIZE + 1]
+      = "CENTER =";
+   
+   const char HORIZONTAL_OFFSET_DESC [HORIZONTAL_OFFSET_DESC_SIZE + 1]
+      = "OFFSET =";
+   
+   const char ORIENTATION_ANGLE_DESC [ORIENTATION_ANGLE_DESC_SIZE + 1]
+      = " ORIENTATION ANGLE =";
+   
+   const char SUN_ELEVATION_DESC [SUN_ELEVATION_DESC_SIZE + 1]
+      = "SUN ELEVATION ANGLE =";
+   
+   const char SUN_AZIMUTH_DESC [SUN_AZIMUTH_DESC_SIZE + 1]
+      = " SUN AZIMUTH ANGLE =";
+
+   const char SPACE[] = " ";
+
+   //>
+   // NOTE:  "seekp's" will be perormed as needed for safety.
+   //<
+
+   //>
+   // Start at beginning of the stream.
+   //<
+   os.seekp(0, ios::beg);
+
+   //>
+   // Start of administrative record.
+   //<
+
+   os << setiosflags(ios::fixed)  // Disable scientific mode.
+
+      << PRODUCT_ID_DESC
+
+      << setw(PRODUCT_ORDER_NUMBER_SIZE)
+      << theAdminRecord.theProductOrderNumber;
+
+   //>
+   // The admin record can contain info for up to four scenes.
+   //<
+
+   int i;
+   for (i = 0; i < 4; i++)
+   {
+      os.seekp(LOCATION_OFFSET[i], ios::beg);
+
+      os << LOCATION_DESC         
+      
+         << setw(PATH_ROW_NUMBER_SIZE) 
+         << theAdminRecord.thePathRowNumber[i] 
+
+         << DATE_DESC
+
+         << setw(DATE_SIZE) 
+         << theAdminRecord.theAcquisitionDate[i] 
+
+         << setw(1) << SPACE << endl // End of line.
+
+         << SATELLITE_NAME_DESC // Start of line.
+
+         << setw(SAT_NAME_SIZE) 
+         << theAdminRecord.theSatName[i] 
+
+         << SENSOR_NAME_DESC
+      
+         << setw(SENSOR_NAME_SIZE) 
+         << theAdminRecord.theSensorName[i]
+
+         << SENSOR_MODE_DESC
+
+         << setw(SENSOR_MODE_SIZE) 
+         << theAdminRecord.theSensorMode[i]
+
+         << LOOK_ANGLE_DESC
+
+         << setw(OFF_NADIR_ANGLE_SIZE)
+         << setiosflags(ios::right)
+         << setprecision(2) 
+         << theAdminRecord.theOffNadirAngle[i] // End of scene.
+         << resetiosflags(ios::right)
+         << endl 
+         << setw(23) << SPACE; // End of line.
+   } // End of scene loop.
+
+   os.seekp(640, ios::beg); // Start of line.
+
+   os << PRODUCT_TYPE_DESC
+
+      << setiosflags(ios::left)
+      
+      << setw(PRODUCT_TYPE_SIZE)
+      << theAdminRecord.theProductType
+
+      << PRODUCT_SIZE_DESC
+
+      << setw(PRODUCT_SIZE_SIZE)
+      << theAdminRecord.theProductSize
+
+      << setw(22) << SPACE << endl; // End of line.
+
+   os.seekp(720, ios::beg);
+
+   os << PROCESSING_TYPE_DESC
+
+      << setw(PROCESSING_TYPE_SIZE)
+      << theAdminRecord.theProcessingType
+
+      << RESAMPLING_ALGO_DESC
+
+      << setw(RESAMPLING_ALGO_SIZE)
+      << theAdminRecord.theResampAlgorithm
+
+      << resetiosflags(ios::left)
+
+      << setw(33) << SPACE << endl; // End of line.
+
+   os.seekp(800, ios::beg);  // Start of line.
+   
+   os << TAPE_VOLUME_NUMBER_DESC
+
+      << setiosflags(ios::right)
+
+      << setw(TAPE_VOLUME_NUMBER_SIZE) 
+      << theAdminRecord.theTapeVolumeNumber
+      << "/" << setw(VOLUMES_PER_TAPE_SIZE)
+      << theAdminRecord.theNumberVolumesPerTape
+
+      << PIXELS_PER_LINE_DESC
+
+      << setw(PIXELS_PER_LINE_SIZE)
+      << theAdminRecord.thePixelsPerLine 
+
+      << LINES_PER_IMAGE_DESC
+
+      << setw(LINES_PER_IMAGE_SIZE)
+      << theAdminRecord.theLinesPerImage
+
+      << "/"
+
+      << setw(LINES_PER_IMAGE_SIZE)
+      << theAdminRecord.theLinesPerImage
+
+      << setw(4) << SPACE << endl;  // End of line.
+  
+   os.seekp(880, ios::beg);  // Start of line.
+
+   os << setiosflags(ios::right)
+
+      << FIRST_LINE_DESC
+
+      << setw(LINES_PER_IMAGE_SIZE)
+      << theAdminRecord.the1stLineInVolume
+
+      << BLOCKING_FACTOR_DESC
+
+      << setw(BLOCKING_FACTOR_SIZE)
+      << theAdminRecord.theTapeBlockingFactor
+ 
+      << RECORD_LENGTH_DESC
+
+      << setw(RECORD_LENGTH_SIZE)
+      << theAdminRecord.theRecordSize
+
+      << PIXEL_GSD_DESC
+
+      
+      << setw(PIXEL_GSD_SIZE)
+      << setprecision(2)
+      << theAdminRecord.theGsd
+
+      << endl;  // End of line.
+
+   os.seekp(960, ios::beg);  // Start of line.
+
+   os << BITS_PER_PIXEL_DESC
+
+      << setw(BITS_PER_PIXEL_SIZE)
+      << theAdminRecord.theOutputBitsPerPixel
+
+      << AQUIRED_BITS_PER_PIXEL_DESC
+
+      << setw(BITS_PER_PIXEL_SIZE)
+      << theAdminRecord.theAcquiredBitsPerPixel
+
+      << resetiosflags(ios::right)
+
+      << setw(26) << SPACE << endl;  // End of line.
+
+   os.seekp(1040, ios::beg);  // Start of line.
+
+   os << BANDS_PRESENT_DESC
+
+      << setw(BANDS_PRESENT_SIZE)
+      << theAdminRecord.theBandsPresentString
+
+      << setw(31) << SPACE << endl // End of line.
+      << setw(79) << SPACE << endl
+      << setw(79) << SPACE << endl
+      << setw(79) << SPACE << endl
+      << setw(79) << SPACE << endl
+      << setw(79) << SPACE << endl;
+
+   os.seekp(1520, ios::beg);
+   
+   os << REV_DESC
+
+      << setw(FORMAT_VERSION_SIZE)
+      << theAdminRecord.theFormatVersion;
+
+   //***
+   // End of administrative record(bytes 0 to 1535).
+   //***
+
+   //***
+   // Beginning of radiometric record.
+   //***
+
+   os.seekp(1536, ios::beg);  
+
+   os << BIAS_GAIN_DESC
+
+      << setw(29) << SPACE << endl; 
+
+   //***
+   // Loop through the bands and get write out the bias and gain for each
+   // band.
+   //***
+   
+   os << resetiosflags(ios::left) << setiosflags(ios::right);
+
+   for (i = 0; i < 8; i++)
+   {
+      os.seekp(BIAS_OFFSET[i], ios::beg);
+
+      os << setprecision(15)
+         
+         << setw(BIAS_SIZE)
+         << theRadiomRecord.theBias[i]
+
+         << SPACE 
+
+         << setw(GAIN_SIZE) 
+         << theRadiomRecord.theGain[i]
+
+         << setw(30) << SPACE << endl;
+   } // End of loop through the bands.
+
+   os << resetiosflags(ios::right);
+
+   os.seekp(2256, ios::beg);
+
+   os << setw(79) << SPACE << endl;
+   os << setw(79) << SPACE << endl;
+   os << setw(79) << SPACE << endl;
+   os << setw(79) << SPACE << endl;
+   os << setw(79) << SPACE << endl;
+   os << setw(79) << SPACE << endl;
+   os << setw(79) << SPACE << endl;
+   os << setw(79) << SPACE << endl;
+   os << setw(79) << SPACE << endl;
+   os << setw(79) << SPACE << endl;
+   os << setw(15) << SPACE << endl;
+
+   //***
+   // End of radiometric record(bytes 1536 to 3071).
+   //***
+
+   //**
+   // Start of geometric record(bytes 3072 to 4607).
+   //***
+
+   os.seekp(3072, ios::beg);  // Start of record.
+
+   os << GEO_DESC
+
+      << MAP_PROJECTION_NAME_DESC
+
+      << setiosflags(ios::left) // Alpha fields left justified.
+
+      << setw(MAP_PROJECTION_NAME_SIZE)
+      << theGeoRecord.theMapProjectionName
+
+      << ELLIPSOID_DESC // Looks like this has changed.
+
+      << setw(ELLIPSOID_SIZE)
+      << theGeoRecord.theEllipsoid
+
+      << DATUM_DESC
+
+      << setw(DATUM_SIZE)
+      << theGeoRecord.theDatum
+
+      << resetiosflags(ios::left)
+      
+      << endl // End of line
+
+      << PROJECTION_PARAMETER_DESC
+      << SPACE;
+
+   os.seekp(PROJ_PARAM_OFFSET[0], ios::beg);
+   os << setprecision(15)
+      << setiosflags(ios::right)
+      
+      << setw(PROJECTION_PARAMETER_SIZE) 
+      << theGeoRecord.theProjectionParams[0]
+      << SPACE;
+
+   os.seekp(PROJ_PARAM_OFFSET[1], ios::beg);
+   os << setw(PROJECTION_PARAMETER_SIZE) 
+      << theGeoRecord.theProjectionParams[1]
+      << setw(1) << SPACE << endl;
+
+   //***
+   // Code is duplicated every three projection parameter four times; 
+   // hence, the double loop.
+   //***
+   for (i = 0; i < 4; i++)
+   {
+      for (int j = i * 3 + 2; j < (i * 3) + 5; j++)
+      {
+         os.seekp(PROJ_PARAM_OFFSET[j], ios::beg);
+
+         os << setw(PROJECTION_PARAMETER_SIZE) 
+            << theGeoRecord.theProjectionParams[j]
+            << setw(1) << SPACE;
+
+         os.seekp(PROJ_PARAM_OFFSET[j], ios::beg);
+         os << setw(PROJECTION_PARAMETER_SIZE) 
+            << theGeoRecord.theProjectionParams[j]
+            << setw(1) << SPACE;
+
+         os.seekp(PROJ_PARAM_OFFSET[j], ios::beg);
+         os << setw(PROJECTION_PARAMETER_SIZE) 
+            << theGeoRecord.theProjectionParams[j]
+            << setw(5) << SPACE << endl;
+      }
+   }
+
+   os.seekp(PROJ_PARAM_OFFSET[14], ios::beg);
+   os << setw(PROJECTION_PARAMETER_SIZE) 
+      << theGeoRecord.theProjectionParams[14]
+      << setw(55) << SPACE << endl << resetiosflags(ios::right);
+
+
+   os.seekp(3632, ios::beg);
+   os << UL_DESC
+ 
+      << SPACE
+      
+      << setw(LON_SIZE) << theGeoRecord.theUlLon
+
+      << SPACE
+
+      << setw(LAT_SIZE) << theGeoRecord.theUlLat
+
+      << SPACE
+
+      << setprecision(3)
+      
+      << setw(EASTING_SIZE) << setiosflags(ios::right) 
+      << theGeoRecord.theUlEasting
+
+      << SPACE
+
+      << setw(NORTHING_SIZE) 
+      << theGeoRecord.theUlNorthing
+
+      << setw(20) << SPACE << endl << resetiosflags(ios::right);
+
+      
+   os.seekp(3712, ios::beg);
+   os << UR_DESC
+ 
+      << SPACE
+      
+      << setw(LON_SIZE) << theGeoRecord.theUrLon
+
+      << SPACE
+
+      << setw(LAT_SIZE) << theGeoRecord.theUrLat
+
+      << SPACE
+
+      << setw(EASTING_SIZE) << setiosflags(ios::right) 
+      << theGeoRecord.theUrEasting
+
+      << SPACE
+
+      << setw(NORTHING_SIZE) 
+      << theGeoRecord.theUrNorthing
+
+      << setw(20) << SPACE << endl << resetiosflags(ios::right);
+
+      
+   os.seekp(3792, ios::beg);
+   os << LR_DESC
+ 
+      << SPACE
+      
+      << setw(LON_SIZE) << theGeoRecord.theLrLon
+
+      << SPACE
+
+      << setw(LAT_SIZE) << theGeoRecord.theLrLat
+
+      << SPACE
+
+      << setw(EASTING_SIZE) << setiosflags(ios::right) 
+      << theGeoRecord.theLrEasting
+
+      << SPACE
+
+      << setw(NORTHING_SIZE) 
+      << theGeoRecord.theLrNorthing
+
+      << setw(20) << SPACE << endl << resetiosflags(ios::right);
+
+      
+   os.seekp(3872, ios::beg);
+   os << LL_DESC
+ 
+      << SPACE
+      
+      << setw(LON_SIZE) << theGeoRecord.theLlLon
+
+      << SPACE
+
+      << setw(LAT_SIZE) << theGeoRecord.theLlLat
+
+      << SPACE
+
+      << setw(EASTING_SIZE) << setiosflags(ios::right) 
+      << theGeoRecord.theLlEasting
+
+      << SPACE
+
+      << setw(NORTHING_SIZE) 
+      << theGeoRecord.theLlNorthing
+
+      << setw(20) << SPACE << endl << resetiosflags(ios::right);
+
+   os.seekp(3952, ios::beg);
+   os << CENTER_DESC
+
+      << SPACE
+
+      << setw(LON_SIZE) 
+      << theGeoRecord.theCenterLon
+      
+      << SPACE
+
+      << setw(LAT_SIZE) 
+      << theGeoRecord.theCenterLat
+
+      << SPACE
+
+      << setw(EASTING_SIZE) << setiosflags(ios::right) 
+      << theGeoRecord.theCenterEasting
+
+      << SPACE
+
+      << setw(NORTHING_SIZE) 
+      << theGeoRecord.theCenterNorthing
+
+      << SPACE 
+
+      << setw(CENTER_SAMPLE_SIZE) 
+      << theGeoRecord.theCenterSample
+
+      << SPACE 
+
+      << setw(CENTER_LINE_SIZE) 
+      << theGeoRecord.theCenterLine
+
+      << setw(4) << SPACE << endl;
+
+   os.seekp(4032, ios::beg);
+   os << HORIZONTAL_OFFSET_DESC
+
+      << setw(HORIZONTAL_OFFSET_SIZE) 
+      << theGeoRecord.theHorizontalOffset
+
+      << ORIENTATION_ANGLE_DESC
+
+      << setw(ORIENTATION_ANGLE_SIZE) 
+      << setprecision(2)
+      << theGeoRecord.theOrientationAngle
+
+      << setw(39) << SPACE << endl; // 41 in spec
+
+   os.seekp(4112, ios::beg);
+   os << SUN_ELEVATION_DESC
+
+      << setw(SUN_ELEVATION_SIZE) 
+      << setprecision(1) 
+      << theGeoRecord.theSunElevationAngle
+
+      << SUN_AZIMUTH_DESC
+
+      << setw(SUN_AZIMUTH_SIZE) 
+      << setprecision(1) 
+      << theGeoRecord.theSunAzimuth  // End of data.
+
+      << setw(29) << SPACE << endl 
+      << setw(79) << SPACE << endl 
+      << setw(79) << SPACE << endl 
+      << setw(79) << SPACE << endl 
+      << setw(79) << SPACE << endl
+      << setw(79) << SPACE << endl
+      << setw(15) << SPACE << endl << flush; // ? size
+
+   //***
+   // End of geometric record(bytes 3072 to 4607).
+   //***
+   
+}
+
+
+//***************************************************************************
+// PRIVATE METHOD:
+// ossimFfRevc::loadFromStream(istream& is)
+//***************************************************************************
+void ossimFfRevc::loadFromStream(istream& is)
+{
+   //***
+   // See .h for enumerations for field sizes and offsets. 
+   //***
+
+   //***
+   // NOTE:  Because of header inconsistencies all seeks will be relative to
+   //        the beginning of the stream.
+   //***
+
+   //***
+   // Temporary buffer for fields that need to be converted to integers or
+   // floats.
+   //***
+   
+   char tmpBuff[25];
+
+   //***
+   // Start of administrative record.
+   //***
+
+   is.seekg(PRODUCT_ORDER_NUMBER_OFFSET, ios::beg);
+
+   is.get(theAdminRecord.theProductOrderNumber, 
+          PRODUCT_ORDER_NUMBER_SIZE + 1,
+          ' ');
+
+   if (checkStream(is)) return;
+
+   //***
+   // Loop through the four scenes and get the data.
+   //***
+
+   int i;
+   for (i = 0; i < NUMBER_OF_SCENES; i++)
+   {
+ 
+      is.seekg(PATH_ROW_NUMBER_OFFSET[i], ios::beg);
+
+      is.get(theAdminRecord.thePathRowNumber[i], PATH_ROW_NUMBER_SIZE + 1);
+   
+      if (checkStream(is)) return;
+
+      is.seekg(DATE_OFFSET[i], ios::beg);
+
+      is.get(theAdminRecord.theAcquisitionDate[i], DATE_SIZE + 1);
+   
+      if (checkStream(is)) return;
+
+      is.seekg(SAT_NAME_OFFSET[i], ios::beg);
+
+      is.get(theAdminRecord.theSatName[i], SAT_NAME_SIZE + 1);
+   
+      if (checkStream(is)) return;
+
+      is.seekg(SENSOR_NAME_OFFSET[i], ios::beg);
+
+      is.get(theAdminRecord.theSensorName[i], SENSOR_NAME_SIZE + 1);
+   
+      if (checkStream(is)) return;
+
+      is.seekg(SENSOR_MODE_OFFSET[i], ios::beg);
+
+      is.get(theAdminRecord.theSensorMode[i], SENSOR_MODE_SIZE + 1);
+  
+      if (checkStream(is)) return;
+
+      is.seekg(OFF_NADIR_ANGLE_OFFSET[i], ios::beg);
+
+      is.get(tmpBuff, OFF_NADIR_ANGLE_SIZE + 1);
+
+      if (checkStream(is)) return;
+
+      if (tmpBuff)
+      {
+         theAdminRecord.theOffNadirAngle[i] = atof(tmpBuff);
+      }
+      else
+      {
+         theErrorStatus = OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                             << "Detected an error reading the1stOffNadirAngle." << std::endl;
+      }
+   } // End of scene loop.
+   
+   is.seekg(PRODUCT_TYPE_OFFSET, ios::beg);
+
+   is.get(theAdminRecord.theProductType, PRODUCT_TYPE_SIZE + 1);
+
+   if (checkStream(is)) return;
+ 
+   is.seekg(PRODUCT_SIZE_OFFSET, ios::beg);
+
+   is.get(theAdminRecord.theProductSize, PRODUCT_SIZE_SIZE + 1);
+
+   if (checkStream(is)) return;
+   
+   is.seekg(PROCESSING_TYPE_OFFSET, ios::beg);
+
+   is.get(theAdminRecord.theProcessingType, PROCESSING_TYPE_SIZE + 1);
+
+   if (checkStream(is)) return;
+   
+   is.seekg(RESAMPLING_ALGO_OFFSET, ios::beg);
+
+   is.get(theAdminRecord.theResampAlgorithm, RESAMPLING_ALGO_SIZE + 1);
+
+   if (checkStream(is)) return;
+   
+   is.seekg(TAPE_VOLUME_NUMBER_OFFSET, ios::beg);
+
+   is.get(tmpBuff, TAPE_VOLUME_NUMBER_SIZE + 1, '/');
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.theTapeVolumeNumber = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading theTapeVolumeNumber." << std::endl;
+   }
+
+   is.seekg(VOLUMES_PER_TAPE_OFFSET, ios::beg);
+
+   is.get(tmpBuff, VOLUMES_PER_TAPE_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.theNumberVolumesPerTape = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading theNumberVolumesPerTape." << std::endl;
+   }
+    
+   is.seekg(PIXELS_PER_LINE_OFFSET, ios::beg);
+
+   is.get(tmpBuff, PIXELS_PER_LINE_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.thePixelsPerLine = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading thePixelsPerLine." << std::endl;
+   }
+   
+   is.seekg(LINES_PER_IMAGE_OFFSET, ios::beg);
+
+   is.get(tmpBuff, LINES_PER_IMAGE_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.theLinesPerImage = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading theLinesPerImage." << std::endl;
+   }
+
+   is.seekg(FIRST_LINE_IN_VOLUME_OFFSET, ios::beg);
+
+   is.get(tmpBuff, FIRST_LINE_IN_VOLUME_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.the1stLineInVolume = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading the1stLineInVolume." << std::endl;
+   }
+
+   is.seekg(BLOCKING_FACTOR_OFFSET, ios::beg);
+
+   is.get(tmpBuff, BLOCKING_FACTOR_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.theTapeBlockingFactor = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading theTapeBlockingFactor." << std::endl;
+   }
+   
+   is.seekg(RECORD_LENGTH_OFFSET, ios::beg);
+
+   is.get(tmpBuff, RECORD_LENGTH_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.theRecordSize = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading theRecordSize." << std::endl;
+   }
+   
+   is.seekg(PIXEL_GSD_OFFSET, ios::beg);
+
+   is.get(tmpBuff, PIXEL_GSD_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.theGsd = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading theGsd." << std::endl;
+   }
+   
+   is.seekg(BITS_PER_PIXEL_OFFSET, ios::beg);
+
+   is.get(tmpBuff, BITS_PER_PIXEL_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.theOutputBitsPerPixel = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading theOutputBitsPerPixel." << std::endl;
+   }
+   
+   is.seekg(ACQUIRED_BITS_PER_PIXEL_OFFSET, ios::beg);
+
+   is.get(tmpBuff, BITS_PER_PIXEL_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theAdminRecord.theAcquiredBitsPerPixel = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream:"
+                                          << "Detected an error reading theAcquiredBitsPerPixel." << std::endl;
+   }
+   
+   is.seekg(BANDS_PRESENT_OFFSET, ios::beg);
+
+   is.get(theAdminRecord.theBandsPresentString, BANDS_PRESENT_SIZE + 1);
+
+   if (checkStream(is)) return;
+   
+   is.seekg(FORMAT_VERSION_OFFSET, ios::beg);
+
+   is.get(theAdminRecord.theFormatVersion, FORMAT_VERSION_SIZE + 1);
+
+   if (checkStream(is)) return;
+   //***
+   // End of administrative record.
+   //***
+
+   //***
+   // Start of radiometric record.
+   //***
+
+   for (i = 0; i < NUMBER_OF_BANDS; i++)
+   {
+      is.seekg(BIAS_OFFSET[i], ios::beg);
+
+      is.get(tmpBuff, BIAS_SIZE + 1);
+
+      if (checkStream(is)) return;
+   
+      if (tmpBuff)
+      {
+         theRadiomRecord.theBias[i] = atof(tmpBuff);
+      }
+      else
+      {
+         theErrorStatus = OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                             << "Detected an error reading bias for band:  "
+                                             << (i + 1) << endl;
+      }
+
+      is.seekg(GAIN_OFFSET[i], ios::beg);
+
+      is.get(tmpBuff, GAIN_SIZE + 1);
+
+      if (checkStream(is)) return;
+   
+      if (tmpBuff)
+      {
+         theRadiomRecord.theGain[i] = atof(tmpBuff);
+      }
+      else
+      {
+         theErrorStatus = OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream:"
+                                             << "Detected an error reading gain for band:  "
+                                             << i << std::endl;
+      }
+   }
+   //***
+   // End of radiometric record.
+   //***
+
+   //***
+   // Start of geometric record.
+   //***
+
+   is.seekg(MAP_PROJECTION_NAME_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theMapProjectionName, MAP_PROJECTION_NAME_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   is.seekg(ELLIPSOID_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theEllipsoid, ELLIPSOID_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   is.seekg(DATUM_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theDatum, DATUM_SIZE + 1, ' ');
+   
+   if (checkStream(is)) return;
+
+   //***
+   // Get the fifteen projection parameters.
+   //***
+   
+   for(i = 0; i < 15; i++)
+   {
+      is.seekg(PROJ_PARAM_OFFSET[i], ios::beg);
+   
+      is.get(tmpBuff, PROJECTION_PARAMETER_SIZE + 1);
+
+      if (checkStream(is)) return;
+
+      if (tmpBuff)
+      {
+         theGeoRecord.theProjectionParams[i] = atof(tmpBuff);
+      }
+      else
+      {
+         theErrorStatus = OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL) << "FATALossimFfRevc::loadFromStream: "
+                                             << "Detected an error reading ProjectionParams." << std::endl;
+      }
+   }
+
+   //***
+   // Start of upper left data:  longitude, latitude, easting, and northing. 
+   //***
+   is.seekg(UL_LON_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theUlLon, LON_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(UL_LAT_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theUlLat, LAT_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(UL_EASTING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, EASTING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theUlEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading UL easting." << std::endl;
+   }
+
+   is.seekg(UL_NORTHING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theUlNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading UL northing." << std::endl;
+   }
+   //***
+   // End of upper left data.
+   //***
+
+   //***
+   // Start of upper right data:  longitude, latitude, easting, and northing. 
+   //***
+   is.seekg(UR_LON_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theUrLon, LON_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(UR_LAT_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theUrLat, LAT_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(UR_EASTING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, EASTING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theUrEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading UR easting." << std::endl;
+   }
+
+   is.seekg(UR_NORTHING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theUrNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream:"
+                                          << "Detected an error reading UR northing." << std::endl;
+   }
+   //***
+   // End of upper right data.
+   //***
+
+   //***
+   // Start of lower right data:  longitude, latitude, easting, and northing. 
+   //***
+   is.seekg(LR_LON_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theLrLon, LON_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(LR_LAT_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theLrLat, LAT_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(LR_EASTING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, EASTING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theLrEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading LR easting." << std::endl;
+   }
+
+   is.seekg(LR_NORTHING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theLrNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading LR northing." << std::endl;
+   }
+   //***
+   // End of lower right data.
+   //***
+
+   //***
+   // Start of lower left data:  longitude, latitude, easting, and northing. 
+   //***
+   is.seekg(LL_LON_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theLlLon, LON_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(LL_LAT_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theLlLat, LAT_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(LL_EASTING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, EASTING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theLlEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading LL easting." << std::endl;
+   }
+
+   is.seekg(LL_NORTHING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theLlNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading LL northing." << std::endl;
+   }
+   //***
+   // End of lower left data.
+   //***
+
+   //***
+   // Start of scene center data:  longitude, latitude, easting, northing,
+   // sample, line. 
+   //***
+   is.seekg(CENTER_LON_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theCenterLon, LON_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(CENTER_LAT_OFFSET, ios::beg);
+
+   is.get(theGeoRecord.theCenterLat, LAT_SIZE + 1);
+   
+   if (checkStream(is)) return;
+   
+   is.seekg(CENTER_EASTING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, EASTING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theCenterEasting = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading center easting." << std::endl;
+   }
+
+   is.seekg(CENTER_NORTHING_OFFSET, ios::beg);
+
+   is.get(tmpBuff, NORTHING_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theCenterNorthing = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading center northing." << std::endl;
+   }
+
+   is.seekg(CENTER_SAMPLE_OFFSET, ios::beg);
+
+   is.get(tmpBuff, CENTER_SAMPLE_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theCenterSample = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading center sample." << std::endl;
+   }
+
+   is.seekg(CENTER_LINE_OFFSET, ios::beg);
+
+   is.get(tmpBuff, CENTER_LINE_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theCenterLine = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading center line." << std::endl;
+   }
+   //***
+   // End of scene center data.
+   //***
+   
+   is.seekg(HORIZONTAL_OFFSET_OFFSET, ios::beg);
+
+   is.get(tmpBuff, HORIZONTAL_OFFSET_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theHorizontalOffset = atoi(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading horizontal offset." << std::endl;
+   }
+   
+   is.seekg(ORIENTATION_ANGLE_OFFSET, ios::beg);
+
+   is.get(tmpBuff, ORIENTATION_ANGLE_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theOrientationAngle = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading orientation angle." << std::endl;
+   }
+   
+   is.seekg(SUN_ELEVATION_OFFSET, ios::beg);
+
+   is.get(tmpBuff, SUN_ELEVATION_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theSunElevationAngle = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading sun elevation angle." << std::endl;
+   }
+   
+   is.seekg(SUN_AZIMUTH_OFFSET, ios::beg);
+
+   is.get(tmpBuff, SUN_AZIMUTH_SIZE + 1);
+
+   if (checkStream(is)) return;
+
+   if (tmpBuff)
+   {
+      theGeoRecord.theSunAzimuth = atof(tmpBuff);
+   }
+   else
+   {
+      theErrorStatus = OSSIM_ERROR;
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::loadFromStream: "
+                                          << "Detected an error reading sun azimuth." << std::endl;
+   }
+   //***
+   // End of geometric record.
+   //***
+   
+}
+
+//***************************************************************************
+// PRIVATE METHOD:
+// ossimFfRevc::checkStream(istream& is)
+//
+// Checks the stream.  If an error has occurred it sets theErrorStatus.
+// Returns: theErrorStatus    ( 0 = OK,  1 = ERROR )
+//***************************************************************************
+int ossimFfRevc::checkStream(istream& is)
+{
+   //***
+   // istreams set fault bits and the operator! is overloaded to return
+   // true if an error has occurred.
+   //***
+   
+   if (!is)
+   {
+      theErrorStatus = OSSIM_ERROR;
+
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimFfRevc::checkStream: "
+                                          << "Stream corrupted.   Returning from method."
+                                          << std::endl;
+   } 
+
+   return theErrorStatus;
+}
+   
+//***************************************************************************
+// Function:
+// ostream& operator<<(ostream& os, const ossimFfRevc& head)
+//***************************************************************************
+ostream& operator<<(ostream& os, const ossimFfRevc& head)
+{
+   head.print(os);
+
+   return os;
+}
+
+//***************************************************************************
+// CONSTRUCTOR:
+// ossimFfRevc::AdminRecord::AdminRecord()
+//
+// Default constructor for AdminRecord nested class:
+//***************************************************************************
+ossimFfRevc::AdminRecord::AdminRecord()
+   :
+      theTapeVolumeNumber(1),
+      theNumberVolumesPerTape(1),
+      thePixelsPerLine(0),
+      theLinesPerImage(0),
+      the1stLineInVolume(1),
+      theTapeBlockingFactor(1),
+      theRecordSize(0),
+      theGsd(0.0),
+      theOutputBitsPerPixel(8),
+      theAcquiredBitsPerPixel(6)
+{
+   const char tmpBuff[] = "";
+
+   strcpy(theProductOrderNumber, tmpBuff);
+
+   //>
+   // There can be four scenes.
+   //<
+   
+   for (int i = 0; i < 4; i++)
+   {
+      strcpy(thePathRowNumber[i], tmpBuff);
+      strcpy(theAcquisitionDate[i], tmpBuff);
+      strcpy(theSatName[i], tmpBuff);
+      strcpy(theSensorName[i], tmpBuff);
+      strcpy(theSensorMode[i], tmpBuff);
+      theOffNadirAngle[i] = 0.0;
+   }
+   strcpy(theProductType, "MAP ORIENTED");
+   strcpy(theProductSize, tmpBuff);
+   strcpy(theProcessingType, "SYSTEMATIC");
+   strcpy(theResampAlgorithm, "CC");
+   strcpy(theBandsPresentString, "P");
+   strcpy(theFormatVersion, "C");
+}
+
+//***************************************************************************
+// CONSTRUCTOR:
+// ossimFfRevc::RadiomRecord::RadiomRecord()
+//
+// Default constructor for RadiomRecord nested class:
+//***************************************************************************
+ossimFfRevc::RadiomRecord::RadiomRecord()
+{
+   for (int i = 0; i < 8; i++)
+   {
+      theBias[i] = 0.0;
+      theGain[i] = 0.0;
+   }
+}
+         
+//***************************************************************************
+// CONSTRUCTOR:
+// ossimFfRevc::GeoRecord::GeomRecord()
+//
+// Default constructor for GeoRecord nested class:
+//***************************************************************************
+ossimFfRevc::GeoRecord::GeoRecord()
+   :
+      theUlEasting(0.0),
+      theUlNorthing(0.0),
+      theUrEasting(0.0),
+      theUrNorthing(0.0),
+      theLrEasting(0.0),
+      theLrNorthing(0.0),
+      theLlEasting(0.0),
+      theLlNorthing(0.0),
+      theCenterEasting(0.0),
+      theCenterNorthing(0.0),
+      theCenterSample(0),
+      theCenterLine(0),
+      theHorizontalOffset(0),
+      theOrientationAngle(0.0),
+      theSunElevationAngle(0.0),
+      theSunAzimuth(0.0)
+{
+   for (int i = 0; i < 15; i++)
+   {
+      theProjectionParams[i] = 0.0;
+   }
+
+   const char tmpBuff[] = "";
+
+   strcpy(theMapProjectionName, "UTM");
+   strcpy(theEllipsoid, tmpBuff);
+   strcpy(theDatum, tmpBuff);
+   strcpy(theUlLon, tmpBuff);
+   strcpy(theUlLat, tmpBuff);
+   strcpy(theUrLon, tmpBuff);
+   strcpy(theUrLat, tmpBuff);
+   strcpy(theLrLon, tmpBuff);
+   strcpy(theLrLat, tmpBuff);
+   strcpy(theLlLon, tmpBuff);
+   strcpy(theLlLat, tmpBuff);
+   strcpy(theCenterLon, tmpBuff);
+   strcpy(theCenterLat, tmpBuff);
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/ff_revc/ossimFfRevc.h b/Utilities/OSSIM/ossim_core/support_data/ff_revc/ossimFfRevc.h
new file mode 100644
index 0000000000..775423a726
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ff_revc/ossimFfRevc.h
@@ -0,0 +1,361 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Dave Burken (dburken@imagelinks.com)
+// Description: This class parses an EOSAT Fast Format rev c header.
+//
+//********************************************************************
+// $Id: ossimFfRevc.h,v 1.1.1.1 2001/02/05 20:13:28 dburken Exp $
+
+#ifndef ossimFfRevc_HEADER
+#define ossimFfRevc_HEADER
+#include <iostream>
+using namespace std;
+
+// Forward class declarations.
+class ossimString;
+      
+//***************************************************************************
+// CLASS: ossimFfRevc.h
+//***************************************************************************
+
+class ossimFfRevc
+{
+public:
+   ossimFfRevc  ();
+   ossimFfRevc  (const char* headerFile);
+   ~ossimFfRevc (){};
+
+   enum ErrorStatus
+   {
+      OSSIM_OK    = 0,
+      OSSIM_ERROR = 1
+   };
+
+   //>
+   // Enumerations for parsing header.  Contains size in bytes
+   // for all fields.
+   // 
+   // NOTE:  Sizes are the actual number of bytes for that field so add
+   //        one for trailing '\0' to get the string length for the
+   //        data member that are character arrays.
+   //<
+
+   enum
+   {
+      NUMBER_OF_BANDS                 = 8,
+      NUMBER_OF_SCENES                = 4,
+      NUMBER_OF_PROJECTION_PARAMETERS = 15
+   };
+   
+   enum
+   {
+      // Adminstrative record:
+      PRODUCT_ORDER_NUMBER_DESC_SIZE      = 12,
+      PRODUCT_ORDER_NUMBER_SIZE           = 11,
+      LOCATION_DESC_SIZE                  = 11,
+      PATH_ROW_NUMBER_SIZE                = 17,
+      DATE_DESC_SIZE                      = 19,
+      DATE_SIZE                           = 8,
+      SAT_NAME_DESC_SIZE                  = 11,
+      SAT_NAME_SIZE                       = 10,
+      SENSOR_NAME_DESC_SIZE               = 9,
+      SENSOR_NAME_SIZE                    = 10,
+      SENSOR_MODE_DESC_SIZE               = 14,
+      SENSOR_MODE_SIZE                    = 6,
+      LOOK_ANGLE_DESC_SIZE                = 13,
+      OFF_NADIR_ANGLE_SIZE                = 6,
+      PRODUCT_TYPE_DESC_SIZE              = 14,
+      PRODUCT_TYPE_SIZE                   = 18,
+      PRODUCT_SIZE_DESC_SIZE              = 15,
+      PRODUCT_SIZE_SIZE                   = 10,
+      PROCESSING_TYPE_DESC_SIZE           = 20,
+      PROCESSING_TYPE_SIZE                = 11,
+      RESAMPLING_ALGO_DESC_SIZE           = 13,
+      RESAMPLING_ALGO_SIZE                = 2,
+      TAPE_VOLUME_NUMBER_DESC_SIZE        = 19,
+      TAPE_VOLUME_NUMBER_SIZE             = 2,
+      VOLUMES_PER_TAPE_SIZE               = 2,
+      PIXELS_PER_LINE_DESC_SIZE           = 18,
+      PIXELS_PER_LINE_SIZE                = 5,
+      LINES_PER_IMAGE_DESC_SIZE           = 17,
+      LINES_PER_IMAGE_SIZE                = 5,
+      FIRST_LINE_DESC_SIZE                = 14,
+      FIRST_LINE_IN_VOLUME_SIZE           = 5,
+      BLOCKING_FACTOR_DESC_SIZE           = 18,
+      BLOCKING_FACTOR_SIZE                = 2,
+      RECORD_LENGTH_DESC_SIZE             = 16,
+      RECORD_LENGTH_SIZE                  = 5,
+      PIXEL_GSD_DESC_SIZE                 = 13,
+      PIXEL_GSD_SIZE                      = 6,
+      BITS_PER_PIXEL_DESC_SIZE            = 23,
+      BITS_PER_PIXEL_SIZE                 = 2,  // Output and Acquired
+      AQUIRED_BITS_PER_PIXEL_DESC_SIZE    = 26,
+      BANDS_PRESENT_DESC_SIZE             = 15,
+      BANDS_PRESENT_SIZE                  = 33,
+      REV_DESC_SIZE                       = 15,
+      FORMAT_VERSION_SIZE                 = 1,
+      // Radiometric record:
+      BIAS_GAIN_DESC_SIZE                 = 50, 
+      BIAS_SIZE                           = 24,
+      GAIN_SIZE                           = 24,
+      // Geometric record:
+      GEO_DESC_SIZE                       = 14,
+      MAP_PROJECTION_NAME_DESC_SIZE       = 17,
+      MAP_PROJECTION_NAME_SIZE            = 4,
+      ELLIPSOID_DESC_SIZE                 = 12,
+      ELLIPSOID_SIZE                      = 18,
+      DATUM_DESC_SIZE                     = 8,
+      DATUM_SIZE                          = 6,
+      PROJECTION_PARAMETER_DESC_SIZE      = 28,
+      PROJECTION_PARAMETER_SIZE           = 24,
+      CORNER_DESC_SIZE                    = 4,
+      CENTER_DESC_SIZE                    = 8,
+      LON_SIZE                            = 13,
+      LAT_SIZE                            = 12,
+      EASTING_SIZE                        = 13,
+      NORTHING_SIZE                       = 13,
+      CENTER_SAMPLE_SIZE                  = 5,
+      CENTER_LINE_SIZE                    = 5,
+      HORIZONTAL_OFFSET_DESC_SIZE         = 8,
+      HORIZONTAL_OFFSET_SIZE              = 6,
+      ORIENTATION_ANGLE_DESC_SIZE         = 20,
+      ORIENTATION_ANGLE_SIZE              = 6,
+      SUN_ELEVATION_DESC_SIZE             = 21,
+      SUN_ELEVATION_SIZE                  = 4,
+      SUN_AZIMUTH_DESC_SIZE               = 20,
+      SUN_AZIMUTH_SIZE                    = 5
+   };
+
+   //---
+   //>
+   // Enumerations for byte offsets in header.  All offsets are relative to
+   // the first byte of the first record which is byte 0.
+   //<
+   
+   enum
+   {
+      // Administrative record:  bytes 0 - 1535
+      PRODUCT_ORDER_NUMBER_OFFSET           = 12,
+      PRODUCT_TYPE_OFFSET                   = 654,
+      PRODUCT_SIZE_OFFSET                   = 687,
+      PROCESSING_TYPE_OFFSET                = 740,
+      RESAMPLING_ALGO_OFFSET                = 764,
+      TAPE_VOLUME_NUMBER_OFFSET             = 819,
+      VOLUMES_PER_TAPE_OFFSET               = 822,
+      PIXELS_PER_LINE_OFFSET                = 842,
+      LINES_PER_IMAGE_OFFSET                = 864,
+      FIRST_LINE_IN_VOLUME_OFFSET           = 894,
+      BLOCKING_FACTOR_OFFSET                = 917,
+      RECORD_LENGTH_OFFSET                  = 935,
+      PIXEL_GSD_OFFSET                      = 954,
+      BITS_PER_PIXEL_OFFSET                 = 983,
+      ACQUIRED_BITS_PER_PIXEL_OFFSET        = 1011,
+      BANDS_PRESENT_OFFSET                  = 1055,
+      FORMAT_VERSION_OFFSET                 = 1535,
+      // Radiometric record:  bytes 1536 - 3071
+      // See file scope constants for bias and gain OFFSET positions.
+      // Geometric record:  bytes 3072 - 4607
+      MAP_PROJECTION_NAME_OFFSET    = 3103,
+      ELLIPSOID_OFFSET              = 3119,  
+      DATUM_OFFSET                  = 3145,
+      UL_LON_OFFSET                 = 3637,
+      UL_LAT_OFFSET                 = 3651,
+      UL_EASTING_OFFSET             = 3664,
+      UL_NORTHING_OFFSET            = 3678,
+      UR_LON_OFFSET                 = 3717,
+      UR_LAT_OFFSET                 = 3731,
+      UR_EASTING_OFFSET             = 3744,
+      UR_NORTHING_OFFSET            = 3758,
+      LR_LON_OFFSET                 = 3797,
+      LR_LAT_OFFSET                 = 3811,
+      LR_EASTING_OFFSET             = 3824,
+      LR_NORTHING_OFFSET            = 3838,
+      LL_LON_OFFSET                 = 3877,
+      LL_LAT_OFFSET                 = 3891,
+      LL_EASTING_OFFSET             = 3904,
+      LL_NORTHING_OFFSET            = 3918,
+      CENTER_LON_OFFSET             = 3961,
+      CENTER_LAT_OFFSET             = 3975,
+      CENTER_EASTING_OFFSET         = 3988,
+      CENTER_NORTHING_OFFSET        = 4002,
+      CENTER_SAMPLE_OFFSET          = 4016,
+      CENTER_LINE_OFFSET            = 4022,
+      HORIZONTAL_OFFSET_OFFSET      = 4040,
+      ORIENTATION_ANGLE_OFFSET      = 4066, 
+      SUN_ELEVATION_OFFSET          = 4133, 
+      SUN_AZIMUTH_OFFSET            = 4157
+   };
+
+   //---
+   //>
+   // An EOSAT Fast Format Rev C header consists of three
+   // records:  administrative, radiometric and geometric
+   // each record has a class defined for it to hold the pertinent
+   // data.
+   //<
+   
+   class AdminRecord
+   {
+   public:
+      AdminRecord();
+      ~AdminRecord(){}
+
+      //  Data Members for record.
+      
+      char   theProductOrderNumber[PRODUCT_ORDER_NUMBER_SIZE + 1];
+
+      char   thePathRowNumber[NUMBER_OF_SCENES][PATH_ROW_NUMBER_SIZE + 1];   
+      char   theAcquisitionDate[NUMBER_OF_SCENES][DATE_SIZE + 1];
+         //> yyyyddmm
+         //<
+      char   theSatName[NUMBER_OF_SCENES][SAT_NAME_SIZE + 1];
+         //> L4, L5, 1B, 1C
+         //<
+      char   theSensorName[NUMBER_OF_SCENES][SENSOR_NAME_SIZE + 1];
+         //> TM, LISS1 LISS2, LISS3, PAN, WIFS
+         //<
+      char   theSensorMode[NUMBER_OF_SCENES][SENSOR_MODE_SIZE + 1];
+      double theOffNadirAngle[NUMBER_OF_SCENES];  // degrees
+
+      char   theProductType[PRODUCT_TYPE_SIZE + 1]; // MAP or ORBIT oriented
+      char   theProductSize[PRODUCT_SIZE_SIZE + 1]; // FULL, SUB, MAP
+         //> SYSTEMATIC, PRECISION, TERRAIN RADIOMETRIC
+         //<
+      char   theProcessingType[PROCESSING_TYPE_SIZE + 1];
+      char   theResampAlgorithm[RESAMPLING_ALGO_SIZE + 1]; // CC or NN
+      int    theTapeVolumeNumber;
+      int    theNumberVolumesPerTape;
+      int    thePixelsPerLine;
+      int    theLinesPerImage;
+      int    the1stLineInVolume;
+      int    theTapeBlockingFactor;
+      int    theRecordSize;
+      double theGsd; // pixel size in meters
+      int    theOutputBitsPerPixel;
+      int    theAcquiredBitsPerPixel;
+      char   theBandsPresentString[BANDS_PRESENT_SIZE + 1];
+      char   theFormatVersion[FORMAT_VERSION_SIZE + 1];
+   };
+
+   class RadiomRecord
+   {
+   public:
+      RadiomRecord();
+      ~RadiomRecord(){}
+      
+
+      double theBias[8];
+      double theGain[8];
+   };
+
+   class GeoRecord
+   {
+   public:
+      GeoRecord();
+      ~GeoRecord(){}
+      
+      char    theMapProjectionName[MAP_PROJECTION_NAME_SIZE + 1];
+      char    theEllipsoid[ELLIPSOID_SIZE + 1];
+      char    theDatum[DATUM_SIZE + 1];
+      double  theProjectionParams[15];
+   
+      char    theUlLon[LON_SIZE + 1]; // deg, min, sec
+      char    theUlLat[LAT_SIZE + 1]; // deg, min, sec
+      double  theUlEasting;
+      double  theUlNorthing;
+   
+      char    theUrLon[LON_SIZE + 1]; // deg, min, sec
+      char    theUrLat[LAT_SIZE + 1]; // deg, min, sec
+      double  theUrEasting;
+      double  theUrNorthing;
+   
+      char    theLrLon[LON_SIZE + 1]; // deg, min, sec
+      char    theLrLat[LAT_SIZE + 1]; // deg, min, sec
+      double  theLrEasting;
+      double  theLrNorthing;
+   
+      char    theLlLon[LON_SIZE + 1]; // deg, min, sec
+      char    theLlLat[LAT_SIZE + 1]; // deg, min, sec
+      double  theLlEasting;
+      double  theLlNorthing;
+
+      char    theCenterLon[LON_SIZE + 1]; // deg, min, sec
+      char    theCenterLat[LAT_SIZE + 1]; // deg, min, sec
+      double  theCenterEasting;
+      double  theCenterNorthing;
+      int     theCenterSample;       // Nearest whole pixel.
+      int     theCenterLine;         // Nearest whole pixel.
+
+      int     theHorizontalOffset;   // pixels
+      double  theOrientationAngle;   // degrees
+      double  theSunElevationAngle;  // degrees
+      double  theSunAzimuth;         // degrees
+   };
+
+   AdminRecord  theAdminRecord;
+   RadiomRecord theRadiomRecord;
+   GeoRecord    theGeoRecord;
+   
+   int errorStatus() const { return theErrorStatus; }
+
+   void print(ostream& os) const;
+
+   void write(ostream& os) const;
+
+   friend ostream& operator<<(ostream& os, const ossimFfRevc& head);
+
+
+   //>
+   // Convenience methods.
+   //<
+   
+   int    path(int sceneNbr=0) const;
+      //> Returns the path as an int.
+      //  Currently uses the1stPathRowNumber string.
+      //<
+   int    row(int sceneNbr=0) const;
+      //> Returns the row as an int from the pathRowString.
+      //  Currently uses the1stPathRowNumber string.
+      //<
+   int    fraction(int sceneNbr=0) const;
+      //> Returns the fraction as an int from the pathRowString.
+      //  Currently uses the1stPathRowNumber string.
+      //<
+   ossimString subScene(int sceneNbr=0) const;
+      //> Returns the sub scene as an string from the pathRowString.
+      //  Currently uses the1stPathRowNumber string.
+      //<
+
+   ossimString pathRow(int sceneNbr=0) const;
+      //> Returns a string represnting the path and row as a name.
+      //  i.e.: 287/05100D0 will be returned as p287r05100D0
+      //  This method will remove any spaces.
+      //<
+
+private:
+   void loadFromStream(istream& is);
+
+   int checkStream(istream& is);
+
+   ErrorStatus theErrorStatus;
+};
+
+   
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/ikonos/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/ikonos/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ikonos/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimIkonosMetaData.cpp b/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimIkonosMetaData.cpp
new file mode 100644
index 0000000000..29275b663c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimIkonosMetaData.cpp
@@ -0,0 +1,46 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken <dburken@imagelinks.com>
+// 
+// Description:
+// 
+// Class definition for ossimIkonosMetaData.
+// 
+// This class parses a Space Imaging Ikonos meta data file.
+//
+//********************************************************************
+// $Id: ossimIkonosMetaData.cpp,v 1.1 2003/05/29 21:17:10 dburken Exp $
+
+#include "ossimIkonosMetaData.h"
+
+RTTI_DEF2(ossimIkonosMetaData, "ossimIkonosMetaData", ossimObject, ossimErrorStatusInterface);
+
+ossimIkonosMetaData::ossimIkonosMetaData()
+{
+}
+
+ossimIkonosMetaData::ossimIkonosMetaData(const char* metaDataFile)
+{
+}
+
+ossimIkonosMetaData::~ossimIkonosMetaData()
+{
+}
+
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimIkonosMetaData.h b/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimIkonosMetaData.h
new file mode 100644
index 0000000000..906f7e072d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimIkonosMetaData.h
@@ -0,0 +1,49 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken <dburken@imagelinks.com>
+// 
+// Description:
+//
+// Class declaration for ossimIkonosMetaData.
+// 
+// This class parses a Space Imaging Ikonos meta data file.
+//
+//********************************************************************
+// $Id: ossimIkonosMetaData.h,v 1.1 2003/05/29 21:17:10 dburken Exp $
+
+#ifndef ossimIkonosMetaData_HEADER
+#define ossimIkonosMetaData_HEADER
+
+#include "base/common/ossimObject.h"
+#include "base/common/ossimErrorStatusInterface.h"
+
+class OSSIMDLLEXPORT ossimIkonosMetaData : public ossimObject,
+                                           public ossimErrorStatusInterface
+{
+public:
+   ossimIkonosMetaData();
+   ossimIkonosMetaData(const char* metaDataFile);
+   virtual ~ossimIkonosMetaData();
+
+ private:
+   
+TYPE_DATA   
+};
+
+#endif /* #ifndef ossimIkonosMetaData_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimSpaceImagingGeom.cpp b/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimSpaceImagingGeom.cpp
new file mode 100644
index 0000000000..13129a1388
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimSpaceImagingGeom.cpp
@@ -0,0 +1,286 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:  Converts SpaceImaging geometry file to
+//               OSSIM Geometry file.
+//
+//*******************************************************************
+//  $Id: ossimSpaceImagingGeom.cpp,v 1.2 2004/05/24 19:44:31 gpotts Exp $
+#include <support_data/ikonos/ossimSpaceImagingGeom.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+#include <sstream>
+#include <iostream>
+using namespace std;
+
+const char* ossimSpaceImagingGeom::SIG_PRODUCER_KW = "Producer";
+const char* ossimSpaceImagingGeom::SIG_PROJECT_NAME_KW = "Project Name";
+const char* ossimSpaceImagingGeom::SIG_FILENAME_KW = "Filename";
+const char* ossimSpaceImagingGeom::SIG_BAND_KW = "Band";
+const char* ossimSpaceImagingGeom::SIG_BITS_PER_PIXEL_KW = "Bits/Pixel";
+const char* ossimSpaceImagingGeom::SIG_NUMBER_OF_BANDS_KW = "Number of Bands";
+const char* ossimSpaceImagingGeom::SIG_DATUM_KW = "Datum";
+const char* ossimSpaceImagingGeom::SIG_PROJECTION_KW = "Projection";
+const char* ossimSpaceImagingGeom::SIG_SELECTED_PROJECTION_KW = "Selected Projection";
+const char* ossimSpaceImagingGeom::SIG_ZONE_KW = "Zone";
+const char* ossimSpaceImagingGeom::SIG_UL_EASTING_KW = "UL Map X (Easting)";
+const char* ossimSpaceImagingGeom::SIG_UL_NORTHING_KW = "UL Map Y (Northing)";
+const char* ossimSpaceImagingGeom::SIG_PIXEL_SIZE_X_KW = "Pixel Size X";
+const char* ossimSpaceImagingGeom::SIG_PIXEL_SIZE_Y_KW = "Pixel Size Y";
+const char* ossimSpaceImagingGeom::SIG_COLUMNS_KW = "Columns";
+const char* ossimSpaceImagingGeom::SIG_ROWS_KW = "Rows";
+
+ossimSpaceImagingGeom::ossimSpaceImagingGeom()
+{
+}
+
+ossimSpaceImagingGeom::ossimSpaceImagingGeom(const ossimFilename& file,
+                                             const char* prefix)
+{
+   setGeometry(file);
+   thePrefix = prefix;
+}
+
+void ossimSpaceImagingGeom::setGeometry(const ossimFilename& file)
+{
+   theSpaceImagingGeometry.clear();
+
+   theSpaceImagingGeometry.addFile(file.c_str());
+}
+
+void ossimSpaceImagingGeom::setGeometry(const ossimKeywordlist& kwl)
+{
+   theSpaceImagingGeometry.clear();
+
+   theSpaceImagingGeometry = kwl;
+}
+
+void ossimSpaceImagingGeom::exportToOssim(ossimKeywordlist& kwl,
+                                          const char* prefix)const
+{
+   const ossimKeywordlist::KeywordMap& geomMap = theSpaceImagingGeometry.getMap();
+   ossimKeywordlist::KeywordMap::const_iterator node = geomMap.begin();
+   
+   while(node != geomMap.end())
+   {
+      ossimString keyword = spaceImagingToOssimKeyword((*node).first);
+      ossimString value   = spaceImagingToOssimValue((*node).first,
+                                                     (*node).second);
+      if(keyword != "")
+      {
+         kwl.add(prefix,
+                 keyword.c_str(),
+                 value.c_str(),
+                 true);
+      }
+      ++node;
+   }
+}
+
+ossimString ossimSpaceImagingGeom::spaceImagingToOssimKeyword(const ossimString& spaceImagingKeyword)const
+{
+   if(spaceImagingKeyword == SIG_NUMBER_OF_BANDS_KW)
+   {
+      return ossimString (ossimKeywordNames::NUMBER_BANDS_KW);
+   }
+   else if(spaceImagingKeyword == SIG_DATUM_KW)
+   {
+      return ossimString(ossimKeywordNames::DATUM_KW);
+   }
+   else if((spaceImagingKeyword == SIG_PROJECTION_KW)||
+		   (spaceImagingKeyword == SIG_SELECTED_PROJECTION_KW))
+   {
+      return ossimString(ossimKeywordNames::TYPE_KW);
+   }
+   else if(spaceImagingKeyword == SIG_ZONE_KW)
+   {
+      return ossimString(ossimKeywordNames::ZONE_KW);
+   }
+   else if(spaceImagingKeyword == SIG_UL_EASTING_KW)
+   {
+      return ossimString(ossimKeywordNames::TIE_POINT_EASTING_KW);
+   }
+   else if(spaceImagingKeyword == SIG_UL_NORTHING_KW)
+   {
+      return ossimString(ossimKeywordNames::TIE_POINT_NORTHING_KW);
+   }
+   else if(spaceImagingKeyword == SIG_PIXEL_SIZE_X_KW)
+   {
+      return ossimString(ossimKeywordNames::METERS_PER_PIXEL_X_KW);
+   }
+   else if(spaceImagingKeyword == SIG_PIXEL_SIZE_Y_KW)
+   {
+      return ossimString(ossimKeywordNames::METERS_PER_PIXEL_Y_KW);
+   }
+   else if(spaceImagingKeyword == SIG_COLUMNS_KW)
+   {
+      return ossimString(ossimKeywordNames::NUMBER_SAMPLES_KW);
+   }
+   else if(spaceImagingKeyword == SIG_ROWS_KW)
+   {
+      return ossimString(ossimKeywordNames::NUMBER_LINES_KW);
+   }
+   
+   return ossimString("");
+}
+
+ossimString ossimSpaceImagingGeom::spaceImagingToOssimValue(const ossimString& spaceImagingKeyword,
+                                                            const ossimString& spaceImagingValue)const
+{
+   const char* value = theSpaceImagingGeometry.find(thePrefix.c_str(),
+                                                    spaceImagingKeyword.c_str());
+
+   if(!value) return ossimString("");
+   
+   if(spaceImagingKeyword == SIG_DATUM_KW)
+   {
+      // better to have a lut for this.  For now I'll put it
+      // here.  As the list gets larger let's move it to a
+      // lut then.
+      ossimString datum = value;
+      datum = datum.trim().upcase();
+      
+      if( datum == "WGS84")
+      {
+         return ossimString("WGE");
+      }
+   }
+   else if((spaceImagingKeyword == SIG_PROJECTION_KW)||
+		   (spaceImagingKeyword == SIG_SELECTED_PROJECTION_KW))
+   {
+      ossimString proj = value;
+      proj = proj.trim().upcase();
+      
+      if(proj == "UNIVERSAL TRANSVERSE MERCATOR")
+      {
+         return ossimString("ossimUtmProjection");
+      }
+      else
+      {
+		  ossimNotify(ossimNotifyLevel_WARN)  << "WARNING ossimSpaceImagingGeom::spaceImagingToOssimValue: Projection " << value << " doesn't have a converter yet!" << endl
+		  << "Please add it" << endl;
+      }
+   }
+   else if(spaceImagingKeyword == SIG_UL_EASTING_KW)
+   {
+      ossimString easting = value;
+      easting = easting.trim();
+
+      ostringstream os;
+      os << easting;
+
+      ossimString eastingValue;
+      ossimString eastingUnits;
+
+      istringstream is(os.str());
+      is >> eastingValue >> eastingUnits;
+
+      eastingUnits = eastingUnits.trim().upcase();
+      if(eastingUnits!= "METERS")
+      {
+		  ossimNotify(ossimNotifyLevel_WARN)  << "WARNING ossimSpaceImagingGeom::spaceImagingToOssimValue: units " << eastingUnits << " not supported yet!" << endl;
+      }
+
+      return eastingValue;
+   }
+   else if(spaceImagingKeyword == SIG_UL_NORTHING_KW)
+   {
+      ossimString northing = value;
+      northing = northing.trim();
+
+      ostringstream os;
+      os << northing;
+
+      ossimString northingValue;
+      ossimString northingUnits;
+
+      istringstream is(os.str());
+      is >> northingValue >> northingUnits;
+
+      northingUnits = northingUnits.trim().upcase();
+      if(northingUnits!= "METERS")
+      {
+		  ossimNotify(ossimNotifyLevel_WARN)  << "WARNING ossimSpaceImagingGeom::spaceImagingToOssimValue: units " << northingUnits << " not supported yet!" << endl;
+      }
+      
+      return northingValue;
+   }
+   else if(spaceImagingKeyword == SIG_PIXEL_SIZE_X_KW)
+   {
+      ossimString gsd = value;
+      gsd = gsd.trim();
+
+      ostringstream os;
+      os << gsd;
+
+      ossimString gsdValue;
+      ossimString gsdUnits;
+
+      istringstream is(os.str());
+      is >> gsdValue >> gsdUnits;
+
+      gsdUnits = gsdUnits.trim().upcase();
+      if(gsdUnits!= "METERS")
+      {
+		  ossimNotify(ossimNotifyLevel_WARN)  << "WARNING ossimSpaceImagingGeom::spaceImagingToOssimValue: units " << gsdUnits << " not supported yet!" << endl;
+      }
+      
+      return gsdValue;
+   }
+   else if(spaceImagingKeyword == SIG_PIXEL_SIZE_Y_KW)
+   {
+      ossimString gsd = value;
+      gsd = gsd.trim();
+
+      ostringstream os;
+      os << gsd;
+
+      ossimString gsdValue;
+      ossimString gsdUnits;
+
+      istringstream is(os.str());
+      is >> gsdValue >> gsdUnits;
+
+      gsdUnits = gsdUnits.trim().upcase();
+      if(gsdUnits!= "METERS")
+      {
+		  ossimNotify(ossimNotifyLevel_WARN)  << "WARNING ossimSpaceImagingGeom::spaceImagingToOssimValue: units " << gsdUnits << " not supported yet!" << endl;
+      }
+      
+      return gsdValue;
+   }
+   
+   return ossimString(value);
+}
+
+ossimString ossimSpaceImagingGeom::getBandName()const
+{
+   return theSpaceImagingGeometry.find(SIG_BAND_KW);
+}
+
+ossimFilename ossimSpaceImagingGeom::getFilename()const
+{
+   return theSpaceImagingGeometry.find(SIG_FILENAME_KW);
+}
+
+ossimString ossimSpaceImagingGeom::getProducer()const
+{
+   return theSpaceImagingGeometry.find(SIG_PRODUCER_KW);
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimSpaceImagingGeom.h b/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimSpaceImagingGeom.h
new file mode 100644
index 0000000000..9aca0d6b71
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/ikonos/ossimSpaceImagingGeom.h
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:  Converts SpaceImaging geometry file to
+//               OSSIM Geometry file.
+//
+//*******************************************************************
+//  $Id: ossimSpaceImagingGeom.h,v 1.2 2004/05/24 19:44:31 gpotts Exp $
+#ifndef ossimSpaceImagingGeom_HEADER
+#define ossimSpaceImagingGeom_HEADER
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimKeywordlist.h"
+
+class ossimSpaceImagingGeom
+{
+public:
+   ossimSpaceImagingGeom(const ossimFilename& file,
+                         const char* prefix = 0);
+   ossimSpaceImagingGeom();
+
+   void setGeometry(const ossimFilename& file);
+   void setGeometry(const ossimKeywordlist& kwl);
+
+   void exportToOssim(ossimKeywordlist& kwl,
+                      const char* prefix=0)const;
+
+   ossimString spaceImagingToOssimKeyword(const ossimString& spaceImagingKeyword)const;
+   ossimString spaceImagingToOssimValue(const ossimString& spaceImagingKeyword,
+                                        const ossimString& spaceImagingValue)const;
+
+   ossimString getBandName()const;
+   ossimFilename getFilename()const;
+   ossimString getProducer()const;
+   
+   static const char* SIG_PRODUCER_KW;
+   static const char* SIG_PROJECT_NAME_KW;
+   static const char* SIG_FILENAME_KW;
+   static const char* SIG_BAND_KW;
+   static const char* SIG_BITS_PER_PIXEL_KW;
+   static const char* SIG_NUMBER_OF_BANDS_KW;
+   static const char* SIG_DATUM_KW;
+   static const char* SIG_PROJECTION_KW;
+   static const char* SIG_SELECTED_PROJECTION_KW;
+   static const char* SIG_ZONE_KW;
+   static const char* SIG_UL_EASTING_KW;
+   static const char* SIG_UL_NORTHING_KW;
+   static const char* SIG_PIXEL_SIZE_X_KW;
+   static const char* SIG_PIXEL_SIZE_Y_KW;
+   static const char* SIG_COLUMNS_KW;
+   static const char* SIG_ROWS_KW;
+   
+protected:
+   ossimKeywordlist theSpaceImagingGeometry;
+   ossimString      thePrefix;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/nitf/.cvsignore
new file mode 100644
index 0000000000..e152773943
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/.cvsignore
@@ -0,0 +1,5 @@
+*.d
+*.o
+*~
+Makefile
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfBlockaTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfBlockaTag.cpp
new file mode 100644
index 0000000000..3be3b1cb0c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfBlockaTag.cpp
@@ -0,0 +1,319 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2004, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description: BLOCKA tag class declaration.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimNitfBlockaTag.cpp,v 1.4 2005/10/13 21:25:38 dburken Exp $
+
+#include <cstring> /* for memcpy */
+
+#include <support_data/nitf/ossimNitfBlockaTag.h>
+#include <support_data/nitf/ossimNitfCommon.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimDms.h>
+#include <base/data_types/ossimDpt.h>
+
+static const ossimTrace traceDebug(ossimString("ossimNitfBlockaTag:debug"));
+
+RTTI_DEF1(ossimNitfBlockaTag, "ossimNitfBlockaTag", ossimNitfRegisteredTag);
+
+#ifndef MIN
+#  define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+ossimNitfBlockaTag::ossimNitfBlockaTag()
+{
+   clearFields();
+}
+
+ossimString ossimNitfBlockaTag::getRegisterTagName() const
+{
+   return ossimString("BLOCKA");
+}
+
+void ossimNitfBlockaTag::parseStream(std::istream& in)
+{
+   clearFields();
+   
+   in.read(theBlockInstance, BLOCK_INSTANCE_SIZE);
+   in.read(theNGray,         N_GRAY_SIZE);
+   in.read(theLLines,        L_LINES_SIZE);
+   in.read(theLayoverAngle,  LAYOVER_ANGLE_SIZE);
+   in.read(theShadowAngle,   SHADOW_ANGLE_SIZE);
+   in.read(theField6,        FIELD_6_SIZE);
+   in.read(theFrlcLoc,       FRLC_LOC_SIZE);
+   in.read(theLrlcLoc,       LRLC_LOC_SIZE);
+   in.read(theLrfcLoc,       LRFC_LOC_SIZE);
+   in.read(theFrfcLoc,       FRFC_LOC_SIZE);
+   in.read(theField11,       FIELD_11_SIZE);
+   
+}
+
+void ossimNitfBlockaTag::writeStream(std::ostream& out)
+{
+   out.write(theBlockInstance, BLOCK_INSTANCE_SIZE);
+   out.write(theNGray,         N_GRAY_SIZE);
+   out.write(theLLines,        L_LINES_SIZE);
+   out.write(theLayoverAngle,  LAYOVER_ANGLE_SIZE);
+   out.write(theShadowAngle,   SHADOW_ANGLE_SIZE);
+   out.write(theField6,        FIELD_6_SIZE);
+   out.write(theFrlcLoc,       FRLC_LOC_SIZE);
+   out.write(theLrlcLoc,       LRLC_LOC_SIZE);
+   out.write(theLrfcLoc,       LRFC_LOC_SIZE);
+   out.write(theFrfcLoc,       FRFC_LOC_SIZE);
+   out.write(theField11,       FIELD_11_SIZE);
+}
+
+ossim_uint32 ossimNitfBlockaTag::getSizeInBytes()const
+{
+   return 123;
+}
+
+void ossimNitfBlockaTag::clearFields()
+{
+   memcpy(theBlockInstance, "01",    BLOCK_INSTANCE_SIZE);
+   memset(theNGray,         '0',     N_GRAY_SIZE);
+   memset(theLLines,        '0',     L_LINES_SIZE);
+   memset(theLayoverAngle,  ' ',     LAYOVER_ANGLE_SIZE);
+   memset(theShadowAngle,   ' ',     SHADOW_ANGLE_SIZE);
+   memset(theField6,        ' ',     FIELD_6_SIZE);
+   memset(theFrlcLoc,       ' ',     FRLC_LOC_SIZE);
+   memset(theLrlcLoc,       ' ',     LRLC_LOC_SIZE);
+   memset(theLrfcLoc,       ' ',     LRFC_LOC_SIZE);
+   memset(theFrfcLoc,       ' ',     FRFC_LOC_SIZE);
+   memcpy(theField11,       "010.0", FIELD_11_SIZE);
+   
+   theBlockInstance[BLOCK_INSTANCE_SIZE] = '\0';
+   theNGray[N_GRAY_SIZE]                 = '\0';
+   theLLines[L_LINES_SIZE]               = '\0';
+   theLayoverAngle[LAYOVER_ANGLE_SIZE]   = '\0';
+   theShadowAngle[SHADOW_ANGLE_SIZE]     = '\0';
+   theField6[FIELD_6_SIZE]               = '\0';
+   theFrlcLoc[FRLC_LOC_SIZE]             = '\0';
+   theLrlcLoc[LRLC_LOC_SIZE]             = '\0';
+   theLrfcLoc[LRFC_LOC_SIZE]             = '\0';
+   theFrfcLoc[FRFC_LOC_SIZE]             = '\0';
+   theField11[FIELD_11_SIZE]              = '\0';
+}
+
+std::ostream& ossimNitfBlockaTag::print(std::ostream& out) const
+{
+   // Grab the corners parsed into points.
+   ossimDpt ulPt;
+   ossimDpt urPt;
+   ossimDpt lrPt;
+   ossimDpt llPt;
+   getFrfcLoc(ulPt);
+   getFrlcLoc(urPt);
+   getLrlcLoc(lrPt);
+   getLrfcLoc(llPt);
+   
+   out << "ossimNitfBlockaTag::print"
+       << "\ntheBlockInstance:  " << theBlockInstance
+       << "\ntheNGray:          " << theNGray
+       << "\ntheLLines:         " << theLLines
+       << "\ntheLayoverAngle:   " << theLayoverAngle
+       << "\ntheShadowAngle:    " << theShadowAngle
+       << "\ntheField6:         " << theField6
+       << "\ntheFrlcLoc:        " << theFrlcLoc
+       << "\ntheLrlcLoc:        " << theLrlcLoc
+       << "\ntheLrfcLoc:        " << theLrfcLoc
+       << "\ntheFrfcLoc:        " << theFrfcLoc
+       << "\ntheField11:        " << theField11
+       << "\nupper left:        " << ulPt
+       << "\nupper right:       " << urPt
+       << "\nlower right:       " << lrPt
+       << "\nlower left:        " << llPt
+       << std::endl;
+
+   return out;
+}
+
+void ossimNitfBlockaTag::setBlockInstance(ossim_uint32 block)
+{
+   if ( (block > 0) && (block < 100) )
+   {
+      ossimString os =
+         ossimNitfCommon::convertToIntString(block,
+                                             BLOCK_INSTANCE_SIZE);
+      memcpy(theBlockInstance, os.c_str(), BLOCK_INSTANCE_SIZE);
+   }
+}
+
+ossimString ossimNitfBlockaTag::getBlockInstance() const
+{
+   return ossimString(theBlockInstance);
+}
+
+void ossimNitfBlockaTag::setNGray(ossim_uint32 grayCount)
+{
+   if (grayCount < 100000)
+   {
+      ossimString os =
+         ossimNitfCommon::convertToUIntString(grayCount,
+                                              N_GRAY_SIZE);
+      memcpy(theNGray, os.c_str(), N_GRAY_SIZE);
+   }
+}
+
+ossimString ossimNitfBlockaTag::getNGray() const
+{
+   return ossimString(theNGray);
+}
+
+void ossimNitfBlockaTag::setLLines(ossim_uint32 lines)
+{
+   if (lines < 100000)
+   {
+      ossimString os =
+         ossimNitfCommon::convertToUIntString(lines, L_LINES_SIZE);
+      memcpy(theLLines, os.c_str(), L_LINES_SIZE);
+   }
+}
+
+ossimString ossimNitfBlockaTag::getLLines() const
+{
+   return ossimString(theLLines);
+}
+
+void ossimNitfBlockaTag::setLayoverAngle(ossim_uint32 angle)
+{
+   if (angle < 360)
+   {
+      ossimString os =
+         ossimNitfCommon::convertToUIntString(angle, LAYOVER_ANGLE_SIZE);
+      memcpy(theLayoverAngle, os.c_str(), LAYOVER_ANGLE_SIZE);
+   }
+}
+
+ossimString ossimNitfBlockaTag::getLayoverAngle() const
+{
+   return ossimString(theLayoverAngle);
+}
+
+void ossimNitfBlockaTag::setShadowAngle(ossim_uint32 angle)
+{
+   if (angle < 360)
+   {
+      ossimString os =
+         ossimNitfCommon::convertToUIntString(angle, SHADOW_ANGLE_SIZE);
+      memcpy(theShadowAngle, os.c_str(), SHADOW_ANGLE_SIZE);
+   }
+}
+
+ossimString ossimNitfBlockaTag::getShadowAngle() const
+{
+   return ossimString(theShadowAngle);
+}
+
+void ossimNitfBlockaTag::setFrlcLoc(const ossimDpt& pt)
+{
+   ossimString os = ossimNitfCommon::convertToDdLatLonLocString(pt, 6);
+   memcpy(theFrlcLoc, os.c_str(), FRLC_LOC_SIZE);
+}
+
+ossimString ossimNitfBlockaTag::getFrlcLoc() const
+{
+   return ossimString(theFrlcLoc);
+}
+
+void ossimNitfBlockaTag::getFrlcLoc(ossimDpt& pt) const
+{
+   ossimString os = theFrlcLoc;
+   converLocStringToPt(os, pt);
+}
+
+void ossimNitfBlockaTag::setLrlcLoc(const ossimDpt& pt)
+{
+   ossimString os = ossimNitfCommon::convertToDdLatLonLocString(pt, 6);
+   memcpy(theLrlcLoc, os.c_str(), LRLC_LOC_SIZE);
+}
+   
+ossimString ossimNitfBlockaTag::getLrlcLoc() const
+{
+   return ossimString(theLrlcLoc);
+}
+
+void ossimNitfBlockaTag::getLrlcLoc(ossimDpt& pt) const
+{
+   ossimString os = theLrlcLoc;
+   converLocStringToPt(os, pt);
+}
+
+void ossimNitfBlockaTag::setLrfcLoc(const ossimDpt& pt)
+{
+   ossimString os = ossimNitfCommon::convertToDdLatLonLocString(pt, 6);
+   memcpy(theLrfcLoc, os.c_str(), LRFC_LOC_SIZE);
+}
+
+ossimString ossimNitfBlockaTag::getLrfcLoc() const
+{
+   return ossimString(theLrfcLoc);
+}
+
+void ossimNitfBlockaTag::getLrfcLoc(ossimDpt& pt) const
+{
+   ossimString os = theLrfcLoc;
+   converLocStringToPt(os, pt); 
+}
+
+void ossimNitfBlockaTag::setFrfcLoc(const ossimDpt& pt)
+{
+   ossimString os = ossimNitfCommon::convertToDdLatLonLocString(pt, 6);
+   memcpy(theFrfcLoc, os.c_str(), FRFC_LOC_SIZE);
+}
+
+ossimString ossimNitfBlockaTag::getFrfcLoc() const
+{
+   return ossimString(theFrfcLoc);
+}
+
+void ossimNitfBlockaTag::getFrfcLoc(ossimDpt& pt) const
+{
+   ossimString os = theFrfcLoc;
+   converLocStringToPt(os, pt);
+}
+
+void ossimNitfBlockaTag::converLocStringToPt(const ossimString& locationString,
+                                             ossimDpt& pt) const
+{
+   if (locationString.size() != 21) return;
+
+   std::string s = locationString;
+   
+   std::string lat(s, 0, 10);
+   std::string lon(s, 10, 11);
+
+   if ( (lat[0] == 'N') || (lat[0] == 'S') )
+   {
+      // Use the dms class to parse.
+      ossimDms dms(0.0, true);
+      dms.setDegrees(lat.c_str());
+      pt.y = dms.getDegrees();
+   }
+   else
+   {
+      ossimString os = lat;
+      pt.y = os.toDouble();
+   }
+   if ( (lon[0] == 'E') || (lon[0] == 'W') )
+   {
+      // Use the dms class to parse.
+      ossimDms dms(0.0, false);
+      dms.setDegrees(lon.c_str());
+      pt.x = dms.getDegrees();
+   }
+   else
+   {
+      ossimString os = lon;
+      pt.x = os.toDouble();
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfBlockaTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfBlockaTag.h
new file mode 100644
index 0000000000..40f87edf20
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfBlockaTag.h
@@ -0,0 +1,341 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2004, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description: BLOCKA tag class declaration.
+//
+// See document STDI-0002 Table 8-9 for more info.
+// 
+// http://164.214.2.51/ntb/baseline/docs/stdi0002/final.pdf
+//
+//----------------------------------------------------------------------------
+// $Id: ossimNitfBlockaTag.h,v 1.5 2005/10/13 21:24:47 dburken Exp $
+#ifndef ossimNitfBlockaTag_HEADER
+#define ossimNitfBlockaTag_HEADER
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class ossimDpt;
+
+class OSSIM_DLL ossimNitfBlockaTag : public ossimNitfRegisteredTag
+{
+public:
+   enum 
+   {
+      BLOCK_INSTANCE_SIZE = 2,
+      N_GRAY_SIZE         = 5,
+      L_LINES_SIZE        = 5,
+      LAYOVER_ANGLE_SIZE  = 3,
+      SHADOW_ANGLE_SIZE   = 3,
+      FIELD_6_SIZE        = 16, // reserved
+      FRLC_LOC_SIZE       = 21,
+      LRLC_LOC_SIZE       = 21,
+      LRFC_LOC_SIZE       = 21,
+      FRFC_LOC_SIZE       = 21,
+      FIELD_11_SIZE       = 5,  // reserved
+      //                -----
+      //                  123
+   };
+   
+   /** default constructor */
+   ossimNitfBlockaTag();
+
+   /** @return "BLOCKA" as an ossimString. */
+   virtual ossimString getRegisterTagName() const;
+  
+   /**
+    * Parse method.
+    *
+    * @param in Stream to parse.
+    */
+   virtual void parseStream(std::istream& in);
+   
+   /**
+    * Write method.
+    *
+    * @param out Stream to write to.
+    */
+   virtual void writeStream(std::ostream& out);
+   
+   /** @return The size of this record in bytes (123) within a nitf file. */
+   virtual ossim_uint32 getSizeInBytes()const;
+   
+   /**
+    * Clears all string fields within the record to some default nothingness.
+    */
+   virtual void clearFields();
+   
+   /**
+    * Print method.
+    *
+    * @param out Stream to print to.
+    * 
+    * @return std::ostream&
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+   /** @param block number to set block instance to.  Valid range 01 to 99. */
+   void setBlockInstance(ossim_uint32 block);
+
+   
+   /** @return theBlockInstance as a string. */
+   ossimString getBlockInstance() const;
+   
+   /**
+    * @param grayCount Count of gray fill.
+    *
+    * Valid range:  0 to 99999
+    */
+   void setNGray(ossim_uint32 grayCount);
+   
+   /** @return theNGray as a string. */
+   ossimString getNGray() const;
+   
+   /**
+    * @param lines Number of rows.
+    *
+    * Valid range:  0 to 99999
+    */
+   void setLLines(ossim_uint32 lines);
+   
+   /** @return theLLines as a string. */
+   ossimString getLLines() const;
+   
+   /**
+    * @param angle Value to set theLayoverAngle to.
+    *
+    * Valid range: 000 to 359 or spaces
+    */
+   void setLayoverAngle(ossim_uint32 angle);
+   
+   /** @return theLayoverAngle as a string. */
+   ossimString getLayoverAngle() const;
+   
+   /**
+    * @param angle Value to set theLayoverAngle to.
+    *
+    * Valid range: 000 to 359 or spaces
+    */
+   void setShadowAngle(ossim_uint32 angle);
+   
+   /** @return theLayoverAngle as a string. */
+   ossimString getShadowAngle() const;
+   
+   /**
+    * Convert latitude and logitude to theFrlcLoc string.
+    * 
+    * @param pt Ground point of first row, last column.
+    *
+    * @param longitude Longitude portion in decimal degrees.
+    */
+   void setFrlcLoc(const ossimDpt& pt);
+   
+   /** @return theFrlcLoc as a string. */
+   ossimString getFrlcLoc() const;
+   
+   /** @param pt Ground point to initialize with location. */
+   void getFrlcLoc(ossimDpt& pt) const;
+
+   /**
+    * Convert latitude and logitude to theLrlcLoc string.
+    * 
+    * @param pt Ground point of last row, last column.
+    *
+    * @param longitude Longitude portion in decimal degrees.
+    */
+   void setLrlcLoc(const ossimDpt& pt);
+   
+   /** @return theLrlcLoc as a string. */
+   ossimString getLrlcLoc() const;
+   
+   /** @param pt Ground point to initialize with location. */
+   void getLrlcLoc(ossimDpt& pt) const;
+
+      /**
+    * Convert latitude and logitude to theLrfcLoc string.
+    * 
+    * @param pt Ground point of last row, first column.
+    *
+    * @param longitude Longitude portion in decimal degrees.
+    */
+   void setLrfcLoc(const ossimDpt& pt);
+   
+   /** @return theLrfcLoc as a string. */
+   ossimString getLrfcLoc() const;
+   
+   /** @param pt Ground point to initialize with location. */
+   void getLrfcLoc(ossimDpt& pt) const;
+
+      /**
+    * Convert latitude and logitude to theFrfcLoc string.
+    * 
+    * @param pt Ground point of first row, first column.
+    *
+    * @param longitude Longitude portion in decimal degrees.
+    */
+   void setFrfcLoc(const ossimDpt& pt);
+   
+   /** @return theFrfcLoc as a string. */
+   ossimString getFrfcLoc() const;
+   
+   /** @param pt Ground point to initialize with location. */
+   void getFrfcLoc(ossimDpt& pt) const;
+   
+protected:
+
+   /**
+    * Parses location string and initializes pt with result.
+    *
+    * @param locationString String to parse.
+    *
+    * @param pt Point to initialize.
+    */
+   void converLocStringToPt(const ossimString& locationString,
+                            ossimDpt& pt) const;
+                            
+   
+   /**
+    * FIELD: BLOCK_INSTANCE
+    *
+    * required 2 byte field
+    *
+    * 01 to 99
+    * 
+    * Block number of the image.
+    */
+   char theBlockInstance[BLOCK_INSTANCE_SIZE+1];
+   
+   /**
+    * FIELD: N_GRAY
+    *
+    * required 5 byte field
+    *
+    * 00000 to 99999
+    *
+    * SAR The number of gray fill pixels.
+    *
+    * EO-IR: 00000
+    */
+   char theNGray[N_GRAY_SIZE+1];
+   
+   /**
+    * FIELD: L_LINES
+    *
+    * required 5 byte field
+    *
+    * 00000 to 99999
+    *
+    * Row count.
+    */
+   char theLLines[L_LINES_SIZE+1];
+   
+   /**
+    * FIELD: LAYOVER_ANGLE
+    *
+    * required 3 byte field
+    *
+    * 000 to 359 or spaces
+    * 
+    * SAR: Angle between the first row of pixels and the layover direction in
+    * the image, measured in a clockwise direction.
+    *
+    * EO-IR: spaces
+    */
+   char theLayoverAngle[LAYOVER_ANGLE_SIZE+1];
+   
+   /**
+    * FIELD: SHADOW_ANGLE
+    *
+    * required 3 byte field
+    *
+    * 000 to 359 or spaces
+    *
+    * SAR: Angle between the first row of pixels and the radar shadow in
+    * the image, measured in a clockwase direction.
+    *
+    * EO-IR: spaces
+    */
+   char theShadowAngle[SHADOW_ANGLE_SIZE+1];
+   
+   /**
+    * FIELD: FIELD_6
+    *
+    * Reserved field of 16 spaces.
+    */
+   char theField6[FIELD_6_SIZE+1];
+   
+   /**
+    * FIELD: FRLC_LOC
+    *
+    * required 21 byte field
+    *
+    * XDDMMSS.SSYDDDMMSS.SS
+    * OR
+    * +-dd.dddddd+-ddd.dddddd
+    * OR
+    * 21 spaces
+    *
+    * Location of the first row, last column of the image block.
+    */
+   char theFrlcLoc[FRLC_LOC_SIZE+1];
+   
+   /**
+    * FIELD: LRLC_LOC
+    *
+    * required 21 byte field
+    *
+    * XDDMMSS.SSYDDDMMSS.SS
+    * OR
+    * +-dd.dddddd+-ddd.dddddd
+    * OR
+    * 21 spaces
+    *
+    * Location of the last row, last column of the image block.
+    */
+   char theLrlcLoc[LRLC_LOC_SIZE+1];
+   
+   /**
+    * FIELD: LRFC_LOC
+    *
+    * required 21 byte field
+    *
+    * XDDMMSS.SSYDDDMMSS.SS
+    * OR
+    * +-dd.dddddd+-ddd.dddddd
+    * OR
+    * 21 spaces
+    *
+    * Location of the last row, first column of the image block.
+    */
+   char theLrfcLoc[LRFC_LOC_SIZE+1];
+   
+   /**
+    * FIELD: FRFC_LOC
+    *
+    * required 21 byte field
+    *
+    * XDDMMSS.SSYDDDMMSS.SS
+    * OR
+    * +-dd.dddddd+-ddd.dddddd
+    * OR
+    * 21 spaces
+    *
+    * Location of the first row, first column of the image block.
+    */
+   char theFrfcLoc[FRFC_LOC_SIZE+1];
+   
+   /**
+    * FIELD: FIELD_11
+    *
+    * Reserved field of 5 bytes containing: 010.0 
+    */
+   char theField11[FIELD_11_SIZE+1];
+   
+TYPE_DATA   
+};
+
+#endif /* End of "#ifndef ossimNitfBlockaTag_HEADER" */
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCommon.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCommon.cpp
new file mode 100644
index 0000000000..6a4c10105e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCommon.cpp
@@ -0,0 +1,213 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description: Utility class for global nitf methods.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimNitfCommon.cpp,v 1.4 2005/10/17 19:21:55 gpotts Exp $
+
+#include <sstream>
+#include <iomanip>
+
+#include <support_data/nitf/ossimNitfCommon.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimDpt.h>
+
+static const ossimTrace traceDebug(ossimString("ossimNitfCommon:debug"));
+
+                                   
+ossimNitfCommon::ossimNitfCommon(){}
+
+ossimNitfCommon::~ossimNitfCommon(){}
+
+ossimString ossimNitfCommon::convertToScientificString(
+   const ossim_float64& aValue,
+   ossim_uint32 size)
+{
+   // Precision cannot hit 0 for this to work...
+   if ( ((aValue < 0.0) && (size < 8)) ||
+        ((aValue >= 0.0) && (size < 7)) )
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfCommon::convertToScientificString DEBUG:"
+            << "\nsize range error!"
+            << std::endl;
+      }
+      return ossimString();
+   }
+
+   //--
+   // Set the precision to account for size with 1.xxxxxE+01
+   //---
+   ossim_uint32 precision = size - 6;
+   
+   if (aValue < 0.0)
+   {
+      --precision;
+   }
+   
+   std::ostringstream s1;
+   s1 << std::setiosflags(std::ios_base::scientific|std::ios_base::internal)
+      << std::setfill('0')
+      // << setw(size)
+      << std::setprecision(precision)
+      << aValue;
+   
+   ossimString result = s1.str();
+
+   // Upcase the "e".
+   result.upcase();
+   
+   if (traceDebug())
+   {
+      if (result.size() != size)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfCommon::convertToScientificString DEBUG:"
+            << "\nIncorrect output size!"
+            << "\nValue:  " << aValue
+            << "\nString: " << result
+            << std::endl;
+      }
+   }
+   return result;
+}
+
+ossimString ossimNitfCommon::convertToDoubleString(
+   const ossim_float64& aValue,
+   ossim_uint32 precision,
+   ossim_uint32 size)
+{
+   ossim_uint32 width = size;
+   
+   std::ostringstream s1;
+   s1 << std::setiosflags(std::ios_base::fixed|
+                     std::ios_base::internal)
+      << std::setprecision(precision)
+      << std::setfill('0')
+      << std::setw(width)
+      << aValue;
+   
+   ossimString result = s1.str();
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfCommon::convertToDoubleString DEBUG:"
+         << "\nresult: " << result << std::endl;
+      
+      if (result.size() != size)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfCommon::convertToDoubleString DEBUG:"
+            << "\nIncorrect output size!"
+            << std::endl;
+      }
+   }
+   return result;
+}
+
+ossimString ossimNitfCommon::convertToUIntString(ossim_uint32 aValue,
+                                                ossim_uint32 size)
+{
+   ossim_uint32 width = size;
+   
+   std::ostringstream s1;
+   s1 << std::setiosflags(std::ios_base::fixed|
+                     std::ios_base::internal)
+      << std::setfill('0')
+      << std::setw(width)
+      << aValue;
+   
+   ossimString result = s1.str();
+
+   if (traceDebug())
+   {
+      if (result.size() != size)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfCommon::convertToUIntString DEBUG:"
+            << "\nIncorrect output size!"
+            << "\nValue:  " << aValue
+            << "\nString: " << result
+            << std::endl;
+      }
+   }
+   return result;   
+}
+
+ossimString ossimNitfCommon::convertToIntString(ossim_int32 aValue,
+                                                ossim_uint32 size)
+{
+   ossim_uint32 width = size;
+   
+   std::ostringstream s1;
+   s1 << std::setiosflags(std::ios_base::fixed|
+                     std::ios_base::internal)
+      << std::setfill('0')
+      << std::setw(width)
+      << aValue;
+   
+   ossimString result = s1.str();
+
+   if (traceDebug())
+   {
+      if (result.size() != size)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfCommon::convertToIntString DEBUG:"
+            << "\nIncorrect output size!"
+            << "\nValue:  " << aValue
+            << "\nString: " << result
+            << std::endl;
+      }
+   }
+   return result;   
+}
+
+ossimString ossimNitfCommon::convertToDdLatLonLocString(const ossimDpt& pt,
+                                                        ossim_uint32 precision)
+{
+   ossimString lat;
+   ossimString lon;
+   ossim_uint32 latSize = precision+4; // size = precision + "-33."
+   ossim_uint32 lonSize = precision+5; // size = precision + "-122."
+   
+   if (pt.y >= 0.0)
+   {
+      lat = "+";
+      --latSize;
+   }
+   if (pt.x >= 0.0)
+   {
+      lon = "+";
+      --lonSize;
+   }
+   lat += convertToDoubleString(pt.y,
+                                precision,
+                                latSize);
+   lon += convertToDoubleString(pt.x,
+                                precision,
+                                lonSize);
+   ossimString result = lat+lon;
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimNitfCommon::convertToDdLatLonLocString DEBUG:"
+         << "\nresult: " << result
+         << std::endl;
+   }
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCommon.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCommon.h
new file mode 100644
index 0000000000..97db882fab
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCommon.h
@@ -0,0 +1,106 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description: Utility class for global nitf methods.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimNitfCommon.h,v 1.2 2005/10/12 15:35:07 dburken Exp $
+#ifndef ossimNitfCommon_HEADER
+#define ossimNitfCommon_HEADER
+
+#include <base/common/ossimConstants.h>
+
+class ossimString;
+class ossimDpt;
+
+/** class ossimNitfCommon for global utility methods */   
+class OSSIM_DLL ossimNitfCommon
+{
+public:
+   ossimNitfCommon();
+   ~ossimNitfCommon();
+
+   /**
+    * This method takes a value and a size(or width) and converts it to a
+    * scientific notation sting in the format: ±0.999999E±9
+    *
+    * @note If the value is positive, currently there is no + added to the
+    * front.
+    *
+    * @param aValue Value to convert to string.
+    *
+    * @param size total size of the string.  This must be at least 7 if
+    * aValue is positive and at least 8 if aValue is negative; else,
+    * no action is taken and an empty string is returned.
+    */
+   static ossimString convertToScientificString(const ossim_float64& aValue,
+                                                ossim_uint32 size);
+
+   /**
+    * This method takes a value and converts to a string of size with
+    * requested precision with a '0' fill.
+    *
+    * Format example: 00925.00
+    * 
+    * @param aValue Value to convert to string.
+    *
+    * @param precision The floating point precision.
+    *
+    * @param size total size of the string.
+    */
+   static ossimString convertToDoubleString(const ossim_float64& aValue,
+                                            ossim_uint32 precision,
+                                            ossim_uint32 size);
+
+   /**
+    * This method takes a value and converts to a string of size with
+    * with a '0' fill.
+    *
+    * Format example: 00925
+
+    * @param aValue Value to convert to string.
+    *
+    * @param size total size of the string.
+    */
+   static ossimString convertToUIntString(ossim_uint32 aValue,
+                                          ossim_uint32 size);
+   
+   /**
+    * Just like convertToUIntString only takes a signed value.
+    * 
+    * This method takes a value and converts to a string of size with
+    * with a '0' fill.
+    *
+    * Format example: 00925
+
+    * @param aValue Value to convert to string.
+    *
+    * @param size total size of the string.
+    */
+   static ossimString convertToIntString(ossim_int32 aValue,
+                                         ossim_uint32 size);
+
+   /**
+    * Converts pt to a decimal degrees latitude longitude location string.
+    *
+    * Format example: +-dd.dddddd+-ddd.dddddd
+    *
+    * @param pt Point to convert where pt.x = longitude and pt.y = latitude.
+    *
+    * @param  precision The floating point precision. This will determine the
+    * size of the string.
+    */
+   static ossimString convertToDdLatLonLocString(const ossimDpt& pt,
+                                                 ossim_uint32 precision);
+
+   
+
+}; // End of class ossimNitfCommon.
+   
+#endif /* #ifndef ossimNitfCommon_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCompressionHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCompressionHeader.cpp
new file mode 100644
index 0000000000..5db9612d8d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCompressionHeader.cpp
@@ -0,0 +1,13 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts
+//
+// LICENSE: LGPL see top level LICENSE.txt for more details
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfCompressionHeader.cpp,v 1.1 2004/11/09 19:11:41 gpotts Exp $
+#include "ossimNitfCompressionHeader.h"
+
+RTTI_DEF1(ossimNitfCompressionHeader, "ossimNitfCompressionHeader", ossimObject);
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCompressionHeader.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCompressionHeader.h
new file mode 100644
index 0000000000..16c890c3f6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfCompressionHeader.h
@@ -0,0 +1,24 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts
+//
+// LICENSE: LGPL see top level LICENSE.txt for more details
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfCompressionHeader.h,v 1.1 2004/11/09 19:11:41 gpotts Exp $
+#ifndef ossimNitfCompressionHeader_HEADER
+#define ossimNitfCompressionHeader_HEADER
+#include <base/common/ossimObject.h>
+#include <iostream>
+
+class OSSIM_DLL ossimNitfCompressionHeader : public ossimObject
+{
+public:
+   virtual void parseStream(std::istream& in) = 0;
+protected:
+
+TYPE_DATA;   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegment.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegment.cpp
new file mode 100644
index 0000000000..73aec4e60b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegment.cpp
@@ -0,0 +1,34 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfDataExtensionSegment.cpp,v 1.1 2003/04/02 20:27:35 gpotts Exp $
+#include "ossimNitfDataExtensionSegment.h"
+RTTI_DEF1(ossimNitfDataExtensionSegment, "ossimNitfDataExtensionSegment", ossimObject)
+
+ostream& operator <<(ostream &out,
+                     const ossimNitfDataExtensionSegment &data)
+{
+   data.print(out);
+   
+   return out;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegment.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegment.h
new file mode 100644
index 0000000000..5fdac62a94
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegment.h
@@ -0,0 +1,44 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfDataExtensionSegment.h,v 1.2 2004/05/23 18:42:33 dburken Exp $
+#ifndef ossimNitfDataExtensionSegment_HEADER
+#define ossimNitfDataExtensionSegment_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimObject.h"
+class ossimNitfTagInformation;
+
+class OSSIMDLLEXPORT ossimNitfDataExtensionSegment : public ossimObject
+{
+public:
+   friend ostream& operator <<(ostream &out,
+                               const ossimNitfDataExtensionSegment &data);
+   ossimNitfDataExtensionSegment(){}
+   virtual ~ossimNitfDataExtensionSegment(){}
+   virtual void parseStream(istream &in)=0;
+   virtual const ossimNitfTagInformation&  getTagInformation()const=0;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegmentV2_0.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegmentV2_0.cpp
new file mode 100644
index 0000000000..85e3e67686
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegmentV2_0.cpp
@@ -0,0 +1,142 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfDataExtensionSegmentV2_0.cpp,v 1.2 2004/05/23 18:42:33 dburken Exp $
+#include "ossimNitfDataExtensionSegmentV2_0.h"
+
+RTTI_DEF1(ossimNitfDataExtensionSegmentV2_0, "ossimNitfDataExtensionSegmentV2_0",ossimNitfDataExtensionSegment)
+
+std::ostream& operator <<(std::ostream& out,
+                          const ossimNitfDataExtIdentSecurityChunkV2_0& data)
+{
+   out << "theFilePartType:                " << data.theFilePartType        << endl
+       << "theUniqueDataExtTypeId:         " << data.theUniqueDataExtTypeId << endl
+       << "theVersionDataFieldDef:         " << data.theVersionDataFieldDef << endl
+       << "theDataExtSecurityClass:        " << data.theDataExtSecurityClass << endl
+       << "theDataExtCodewords:            " << data.theDataExtCodewords     << endl
+       << "theDataExtControlAndHand:       " << data.theDataExtControlAndHand << endl
+       << "theDataExtReleasingInst:        " << data.theDataExtReleasingInst << endl
+       << "theDataExtClassAuthority:       " << data.theDataExtClassAuthority << endl
+       << "theDataExtSecurityConNum:       " << data.theDataExtSecurityConNum << endl
+       << "theDataExtSecuityDowngrade:     " << data.theDataExtSecuityDowngrade << endl
+       << "theDataExtDowngradingEvent:     " << data.theDataExtDowngradingEvent;
+   
+   return out;
+}
+   
+ossimNitfDataExtensionSegmentV2_0::ossimNitfDataExtensionSegmentV2_0()
+{
+   clearFields();
+}
+
+ossimNitfDataExtensionSegmentV2_0::~ossimNitfDataExtensionSegmentV2_0()
+{
+}
+
+void ossimNitfDataExtensionSegmentV2_0::parseStream(istream &in)
+{
+   if(in)
+   {
+      clearFields();
+
+      in.read(theIdentSecurityChunk.theFilePartType, 2); // 2 byte alpha
+      in.read(theIdentSecurityChunk.theUniqueDataExtTypeId, 25); // 25 byte alpha numeric
+      in.read(theIdentSecurityChunk.theVersionDataFieldDef, 2); // 2 byte numeric
+      in.read(theIdentSecurityChunk.theDataExtSecurityClass, 1); // 1 byte alpha
+      in.read(theIdentSecurityChunk.theDataExtCodewords, 40);    // 40 byte alpha numeric
+      in.read(theIdentSecurityChunk.theDataExtControlAndHand, 40); // 40 byte alpha numeric
+      in.read(theIdentSecurityChunk.theDataExtReleasingInst, 40); // 40 byte alpha numeric
+      in.read(theIdentSecurityChunk.theDataExtClassAuthority, 20); // 20 byte alph num
+      in.read(theIdentSecurityChunk.theDataExtSecurityConNum, 20); // 20 byte alpha num
+      in.read(theIdentSecurityChunk.theDataExtSecuityDowngrade, 6); // 6 byte alpha num      
+      if(ossimString(theIdentSecurityChunk.theDataExtSecuityDowngrade) == "999998")
+      {
+         in.read(theIdentSecurityChunk.theDataExtDowngradingEvent, 40); // 40 byte alpha num
+      }
+      in.read(theOverflowedHeaderType, 6);
+      in.read(theDataItemOverflowed, 3);
+      in.read(theLengthOfUserDefinedSubheaderFields, 4);
+      // look to see if there is any data and if so read the tag
+      // to see what it is
+      long length = ossimString(theLengthOfUserDefinedSubheaderFields).toLong();
+      
+      if(length > 0)
+      {
+         in.ignore(length);
+      }
+      // currently I think we are looking for registered extensions keyword in
+      // the theUniqueDataExtTypeId field
+      if(ossimString(theIdentSecurityChunk.theUniqueDataExtTypeId).trim().upcase() == "REGISTERED EXTENSIONS")
+      {
+         theTag.clearFields();
+         theTag.parseStream(in);
+      }
+   }
+}
+
+void ossimNitfDataExtensionSegmentV2_0::clearFields()
+{
+   memset(theIdentSecurityChunk.theFilePartType, ' ', 2); // 2 byte alpha
+   memset(theIdentSecurityChunk.theUniqueDataExtTypeId, ' ', 25); // 25 byte alpha numeric
+   memset(theIdentSecurityChunk.theVersionDataFieldDef, ' ', 2); // 2 byte numeric
+   memset(theIdentSecurityChunk.theDataExtSecurityClass, ' ', 1); // 1 byte alpha
+   memset(theIdentSecurityChunk.theDataExtCodewords, ' ', 40);    // 40 byte alpha numeric
+   memset(theIdentSecurityChunk.theDataExtControlAndHand, ' ', 40); // 40 byte alpha numeric
+   memset(theIdentSecurityChunk.theDataExtReleasingInst, ' ', 40); // 40 byte alpha numeric
+   memset(theIdentSecurityChunk.theDataExtClassAuthority, ' ', 20); // 20 byte alph num
+   memset(theIdentSecurityChunk.theDataExtSecurityConNum, ' ', 20); // 20 byte alpha num
+   memset(theIdentSecurityChunk.theDataExtSecuityDowngrade, ' ', 6); // 6 byte alpha num
+   memset(theIdentSecurityChunk.theDataExtDowngradingEvent, ' ', 40); // 40 byte alpha num
+   memset(theOverflowedHeaderType, ' ', 6);
+   memset(theDataItemOverflowed, ' ', 3);
+   memset(theLengthOfUserDefinedSubheaderFields, ' ', 4);
+   
+   theIdentSecurityChunk.theFilePartType[2] = '\0'; // 2 byte alpha
+   theIdentSecurityChunk.theUniqueDataExtTypeId[25] = '\0'; // 25 byte alpha numeric
+   theIdentSecurityChunk.theVersionDataFieldDef[2] = '\0'; // 2 byte numeric
+   theIdentSecurityChunk.theDataExtSecurityClass[1] = '\0'; // 1 byte alpha
+   theIdentSecurityChunk.theDataExtCodewords[40] = '\0';    // 40 byte alpha numeric
+   theIdentSecurityChunk.theDataExtControlAndHand[40] = '\0'; // 40 byte alpha numeric
+   theIdentSecurityChunk.theDataExtReleasingInst[40] = '\0'; // 40 byte alpha numeric
+   theIdentSecurityChunk.theDataExtClassAuthority[20] = '\0'; // 20 byte alph num
+   theIdentSecurityChunk.theDataExtSecurityConNum[20] = '\0'; // 20 byte alpha num
+   theIdentSecurityChunk.theDataExtSecuityDowngrade[6] = '\0'; // 6 byte alpha num
+   theIdentSecurityChunk.theDataExtDowngradingEvent[40] = '\0'; // 40 byte alpha num
+   theOverflowedHeaderType[6] = '\0';
+   theDataItemOverflowed[3]   = '\0';
+   theLengthOfUserDefinedSubheaderFields[5] = '\0';
+   
+}
+
+  
+std::ostream& ossimNitfDataExtensionSegmentV2_0::print(std::ostream& out)const
+{
+   out << theIdentSecurityChunk << endl
+       << "theOverflowedHeaderType:               "
+       << theOverflowedHeaderType << endl
+       << "theDataItemOverflowed:                 "
+       << theDataItemOverflowed << endl
+       << "theLengthOfUserDefinedSubheaderFields: "
+       << theLengthOfUserDefinedSubheaderFields << endl
+       << theTag;
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegmentV2_0.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegmentV2_0.h
new file mode 100644
index 0000000000..29e578d878
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfDataExtensionSegmentV2_0.h
@@ -0,0 +1,83 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfDataExtensionSegmentV2_0.h,v 1.2 2004/05/23 18:42:33 dburken Exp $
+#ifndef ossimNitfDataExtensionSegmentV2_0_HEADER
+#define ossimNitfDataExtensionSegmentV2_0_HEADER
+#include "ossimNitfDataExtensionSegment.h"
+#include "ossimNitfTagInformation.h"
+
+struct ossimNitfDataExtIdentSecurityChunkV2_0
+{
+   friend std::ostream& operator <<(std::ostream& out,
+                                    const ossimNitfDataExtIdentSecurityChunkV2_0& data);
+   char theFilePartType[3]; // 2 byte alpha
+   char theUniqueDataExtTypeId[26]; // 25 byte alpha numeric
+   char theVersionDataFieldDef[3]; // 2 byte numeric
+   char theDataExtSecurityClass[2]; // 1 byte alpha
+   char theDataExtCodewords[41];    // 40 byte alpha numeric
+   char theDataExtControlAndHand[41]; // 40 byte alpha numeric
+   char theDataExtReleasingInst[41]; // 40 byte alpha numeric
+   char theDataExtClassAuthority[21]; // 20 byte alph num
+   char theDataExtSecurityConNum[21]; // 20 byte alpha num
+   char theDataExtSecuityDowngrade[7]; // 6 byte alpha num
+   char theDataExtDowngradingEvent[41]; // 40 byte alpha num
+};
+
+class OSSIMDLLEXPORT ossimNitfDataExtensionSegmentV2_0 : public ossimNitfDataExtensionSegment
+{
+public:
+   ossimNitfDataExtensionSegmentV2_0();
+   virtual ~ossimNitfDataExtensionSegmentV2_0();
+   virtual void parseStream(istream &in);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual const ossimNitfTagInformation&  getTagInformation()const
+      {
+         return theTag;
+      }
+
+private:
+   void clearFields();
+   
+   ossimNitfDataExtIdentSecurityChunkV2_0 theIdentSecurityChunk;
+   
+   /*!
+    * This is a 6 byte field
+    */
+   char theOverflowedHeaderType[7];
+
+   /*!
+    * This is a 3 byte field
+    */
+   char theDataItemOverflowed[4];
+
+   /*!
+    * This is a 4 byte field.
+    */
+   char theLengthOfUserDefinedSubheaderFields[5];
+   
+   ossimNitfTagInformation                theTag;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfDes.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfDes.cpp
new file mode 100644
index 0000000000..953a1f7022
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfDes.cpp
@@ -0,0 +1,49 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfEmbeddedRpfDes.cpp,v 1.3 2004/09/24 14:38:46 gpotts Exp $
+#include "ossimNitfEmbeddedRpfDes.h"
+#include "ossimNitfEmbeddedRpfHeader.h"
+
+
+RTTI_DEF1(ossimNitfEmbeddedRpfDes, "ossimNitfEmbeddedRpfDes", ossimNitfRegisteredTag)
+
+
+ossimNitfEmbeddedRpfDes::ossimNitfEmbeddedRpfDes()
+{
+}
+
+ossimNitfEmbeddedRpfDes::~ossimNitfEmbeddedRpfDes()
+{
+}
+
+void ossimNitfEmbeddedRpfDes::parseStream(istream &in)
+{
+   if(in)
+   {
+   }
+}
+
+std::ostream& ossimNitfEmbeddedRpfDes::print(std::ostream& out)const
+{
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfDes.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfDes.h
new file mode 100644
index 0000000000..1d80f18408
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfDes.h
@@ -0,0 +1,48 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfEmbeddedRpfDes.h,v 1.3 2004/09/24 14:38:46 gpotts Exp $
+#ifndef ossimNitfEmbeddedRpfDes_HEADER
+#define ossimNitfEmbeddedRpfDes_HEADER
+#include "ossimNitfRegisteredTag.h"
+class ossimNitfFileHeader;
+
+class OSSIMDLLEXPORT ossimNitfEmbeddedRpfDes : public ossimNitfRegisteredTag
+{
+public:
+   ossimNitfEmbeddedRpfDes();
+   virtual ~ossimNitfEmbeddedRpfDes();
+   /*!
+    * This will return the name of the registered tag for this
+    * user defined header.
+    */
+   virtual ossimString getRegisterTagName()const{return "RPFDES";}
+
+   virtual void parseStream(std::istream &in);
+   virtual std::ostream& print(std::ostream& out)const;
+
+TYPE_DATA
+private:
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfHeader.cpp
new file mode 100644
index 0000000000..33d47679be
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfHeader.cpp
@@ -0,0 +1,78 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfEmbeddedRpfHeader.cpp,v 1.7 2004/09/28 15:35:30 gpotts Exp $
+#include "ossimNitfEmbeddedRpfHeader.h"
+#include "support_data/rpf/ossimRpfHeader.h"
+
+RTTI_DEF1(ossimNitfEmbeddedRpfHeader, "ossimNitfEmbeddedRpfHeader", ossimNitfRegisteredTag)
+   
+ossimNitfEmbeddedRpfHeader::ossimNitfEmbeddedRpfHeader()
+   : theRpfHeader(NULL)
+{
+   theRpfHeader = new ossimRpfHeader;
+}
+
+ossimNitfEmbeddedRpfHeader::~ossimNitfEmbeddedRpfHeader()
+{
+   if(theRpfHeader)
+   {
+      delete theRpfHeader;
+      theRpfHeader = NULL;
+   }
+}
+
+ossimString ossimNitfEmbeddedRpfHeader::getRegisterTagName()const
+{
+   return ossimString("RPFHDR");
+}
+
+const ossimRpfHeader* ossimNitfEmbeddedRpfHeader::getRpfHeader()const
+{
+   return theRpfHeader;
+}
+
+void ossimNitfEmbeddedRpfHeader::parseStream(std::istream& in)
+{
+   if(in&&theRpfHeader)
+   {
+      theRpfHeader->parseStream(in);
+   }
+}
+
+void ossimNitfEmbeddedRpfHeader::writeStream(std::ostream& out)
+{
+}
+
+std::ostream& ossimNitfEmbeddedRpfHeader::print(std::ostream& out)const
+{
+   if(theRpfHeader)
+   {
+      theRpfHeader->print(out);
+   }
+   return out;
+}
+
+ossim_uint32 ossimNitfEmbeddedRpfHeader::getSizeInBytes()const
+{
+   return 48;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfHeader.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfHeader.h
new file mode 100644
index 0000000000..fe7b560c35
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfEmbeddedRpfHeader.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfEmbeddedRpfHeader.h,v 1.6 2004/09/28 15:35:30 gpotts Exp $
+#ifndef ossimNitfEmbeddedRpfHeader_HEADER
+#define ossimNitfEmbeddedRpfHeader_HEADER
+#include "ossimNitfRegisteredTag.h"
+class ossimRpfHeader;
+
+class OSSIMDLLEXPORT ossimNitfEmbeddedRpfHeader : public ossimNitfRegisteredTag
+{
+public:
+   ossimNitfEmbeddedRpfHeader();
+   virtual ~ossimNitfEmbeddedRpfHeader();
+   /*!
+    * This will return the name of the registered tag for this
+    * user defined header.
+    */
+   virtual ossimString getRegisterTagName()const;
+
+   /*!
+    * This class will ignore the headerTag since it is the header
+    * tag.
+    */
+   virtual void parseStream(std::istream &in);
+   virtual void writeStream(std::ostream& out);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual ossim_uint32 getSizeInBytes()const;
+   
+   virtual const ossimRpfHeader* getRpfHeader()const;
+   
+
+TYPE_DATA
+private:
+   ossimRpfHeader *theRpfHeader;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFile.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFile.cpp
new file mode 100644
index 0000000000..55fcb6e946
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFile.cpp
@@ -0,0 +1,264 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfFile.cpp,v 1.7 2005/08/19 18:59:45 gpotts Exp $
+#include <support_data/nitf/ossimNitfFile.h>
+#include <support_data/nitf/ossimNitfFileHeader.h>
+#include <support_data/nitf/ossimNitfImageHeader.h>
+#include <support_data/nitf/ossimNitfFileHeaderV2_0.h>
+#include <support_data/nitf/ossimNitfFileHeaderV2_1.h>
+#include <support_data/nitf/ossimNitfImageHeaderV2_0.h>
+#include <support_data/nitf/ossimNitfImageHeaderV2_1.h>
+#include <support_data/nitf/ossimNitfTagFactoryRegistry.h>
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/context/ossimNotifyContext.h>
+
+#include <fstream>
+using namespace std;
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+//***
+// Static trace for debugging
+//***
+static ossimTrace traceDebug("ossimNitfFile:debug");
+
+std::ostream& operator <<(std::ostream& out, const ossimNitfFile& data)
+{
+   return data.print(out);
+}
+
+std::ostream& ossimNitfFile::print(std::ostream& out) const
+{
+   if(theNitfFileHeader)
+   {
+      out << *(theNitfFileHeader)<<endl;
+
+      int n = 0;
+      n = theNitfFileHeader->getNumberOfImages();
+      int idx = 0;
+
+      for(idx = 0; idx < n;++idx)
+      {
+         ossimNitfImageHeader* ih = getNewImageHeader(idx);
+         out << "IMAGE -----> " << idx << std::endl;
+         if(ih)
+         {
+            out << *ih << std::endl;
+            delete ih;
+            ih = 0;
+         }
+      }
+   }
+
+   return out;
+}
+
+ossimNitfFile::ossimNitfFile()
+   : theFilename(""),
+     theNitfFileHeader(NULL)
+{
+}
+
+ossimNitfFile::~ossimNitfFile()
+{
+   if(theNitfFileHeader)
+   {
+      delete theNitfFileHeader;
+      theNitfFileHeader = NULL;
+   }
+}
+
+bool ossimNitfFile::parseFile(const ossimFilename& file)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimNitfFile::parseFile: "
+         << "endtered......"
+         << std::endl;
+   }
+   ifstream in(file.c_str(), ios::in|ios::binary);
+   if (in.fail())
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimNitfFile::parseFile: "
+                                             << "Could not open file:  " << file.c_str()
+                                             << "\nReturning..." << std::endl;
+      }
+      return false;
+   }
+      
+   if(theNitfFileHeader)
+   {
+      delete theNitfFileHeader;
+      theNitfFileHeader = NULL;
+   }
+
+   char temp[10];
+   in.read(temp, 9);
+   in.seekg(0, ios::beg);
+   temp[9] ='\0';
+   
+   theFilename = file;
+
+   ossimString s(temp);
+   if(s == "NITF02.00")
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG: NITF Version 2.0"
+            << std::endl;
+      }
+      theNitfFileHeader = new ossimNitfFileHeaderV2_0;
+   }
+   else if ( (s == "NITF02.10") || (s == "NSIF01.00") )
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG: NITF Version 2.1"
+            << std::endl;
+      }
+      theNitfFileHeader = new ossimNitfFileHeaderV2_1;
+   }
+   else
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimNitfFile::parseFile: "
+            << "Not an NITF file!"
+            << std::endl;
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimNitfFile::parseFile: returning...........false"
+            << "endtered......"
+            << std::endl;
+      }
+      return false;
+   }
+
+   if(theNitfFileHeader)
+   {
+      theNitfFileHeader->parseStream(in);
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimNitfFile::parseFile: returning...........true"
+         << std::endl;
+   }
+   return true;
+}
+
+const ossimNitfFileHeader* ossimNitfFile::getHeader()const
+{
+   return theNitfFileHeader;
+}
+
+ossimIrect ossimNitfFile::getImageRect()const
+{
+   if(theNitfFileHeader)
+   {
+      return theNitfFileHeader->getImageRect();
+   }
+
+   return ossimIrect(ossimIpt(0,0), ossimIpt(0,0));
+}
+
+ossimNitfImageHeader* ossimNitfFile::getNewImageHeader(long imageNumber)const
+{
+   if(theNitfFileHeader)
+   {
+      ifstream in(theFilename.c_str(), ios::in|ios::binary);
+
+      return theNitfFileHeader->getNewImageHeader(imageNumber,
+                                                  in);
+      in.close();
+   }
+   
+   return NULL;
+}
+
+ossimNitfSymbolHeader* ossimNitfFile::getNewSymbolHeader(long symbolNumber)const
+{
+   if(theNitfFileHeader)
+   {
+      ifstream in(theFilename.c_str(), ios::in|ios::binary);
+
+      return theNitfFileHeader->getNewSymbolHeader(symbolNumber,
+                                                   in);
+      in.close();
+   }
+   
+   return NULL;
+}
+
+ossimNitfLabelHeader* ossimNitfFile::getNewLabelHeader(long labelNumber)const
+{
+   if(theNitfFileHeader)
+   {
+      ifstream in(theFilename.c_str(), ios::in|ios::binary);
+
+      return theNitfFileHeader->getNewLabelHeader(labelNumber,
+                                                  in);
+      in.close();
+   }
+   
+   return NULL;
+}
+
+ossimNitfTextHeader* ossimNitfFile::getNewTextHeader(long textNumber)const
+{
+   if(theNitfFileHeader)
+   {
+      ifstream in(theFilename.c_str(), ios::in|ios::binary);
+
+      return theNitfFileHeader->getNewTextHeader(textNumber,
+                                                 in);
+      in.close();
+   }
+   
+   return NULL;
+}
+
+ossimNitfDataExtensionSegment* ossimNitfFile::getNewDataExtensionSegment(long dataExtNumber)const
+{
+   if(theNitfFileHeader)
+   {
+      ifstream in(theFilename.c_str(), ios::in|ios::binary);
+
+      return theNitfFileHeader->getNewDataExtensionSegment(dataExtNumber,
+                                                           in);
+      in.close();
+   }
+   
+   return NULL;
+}
+
+ossimString ossimNitfFile::getVersion()const
+{
+   if(theNitfFileHeader)
+   {
+      return ossimString(theNitfFileHeader->getVersion());
+   }
+   
+   return ossimString("");
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFile.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFile.h
new file mode 100644
index 0000000000..c786cba0e4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFile.h
@@ -0,0 +1,72 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfFile.h,v 1.4 2005/11/08 17:40:53 dburken Exp $
+#ifndef ossimNitfFile_HEADER
+#define ossimNitfFile_HEADER
+
+#include <iostream>
+#include <vector>
+
+#include <base/common/ossimReferenced.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimIrect.h>
+
+class ossimNitfFileHeader;
+class ossimNitfImageHeader;
+class ossimNitfSymbolHeader;
+class ossimNitfLabelHeader;
+class ossimNitfTextHeader;
+class ossimNitfDataExtensionSegment;
+class ossimFilename;
+class ossimNitfRegisteredTag;
+class ossimNitfTagInformation;
+
+class OSSIMDLLEXPORT ossimNitfFile : public ossimReferenced
+{
+public:
+   friend OSSIMDLLEXPORT std::ostream& operator <<(std::ostream& out,
+                                                   const ossimNitfFile &data);
+   virtual std::ostream& print(std::ostream& out) const;
+   
+   ossimNitfFile();
+   virtual ~ossimNitfFile();
+
+   /*!
+    *  Opens the nitf file and attempts to parse.
+    *  Returns true on success, false on error.
+    */
+   bool parseFile(const ossimFilename &file);
+
+   /*!
+    * Will return the header.
+    */
+   const ossimNitfFileHeader* getHeader()const;
+   ossimIrect getImageRect()const;
+   
+   ossimNitfImageHeader*  getNewImageHeader(long imageNumber)const;
+   ossimNitfSymbolHeader* getNewSymbolHeader(long symbolNumber)const;
+   ossimNitfLabelHeader*  getNewLabelHeader(long labelNumber)const;
+   ossimNitfTextHeader*   getNewTextHeader(long textNumber)const;
+   ossimNitfDataExtensionSegment* getNewDataExtensionSegment(long dataExtNumber)const;
+   
+   ossimString getVersion()const;
+
+protected:
+   ossimNitfImageHeader* allocateImageHeader()const;
+   
+   ossimFilename         theFilename;
+   ossimNitfFileHeader*  theNitfFileHeader;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeader.cpp
new file mode 100644
index 0000000000..d5cb1dff7f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeader.cpp
@@ -0,0 +1,140 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfFileHeader.cpp,v 1.8 2004/09/29 13:47:00 gpotts Exp $
+#include "ossimNitfFileHeader.h"
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+RTTI_DEF2(ossimNitfFileHeader, "ossimNitfFileHeader", ossimObject, ossimPropertyInterface);
+
+std::ostream& ossimNitfImageOffsetInformation::print(std::ostream& out) const
+{
+   return out << "theImageHeaderOffset:          "
+              << theImageHeaderOffset << endl
+              << "theImageDataOffset:            "
+              << theImageDataOffset;
+}
+
+ossimNitfFileHeader::ossimNitfFileHeader()
+{
+}
+
+ossimNitfFileHeader::~ossimNitfFileHeader()
+{
+}
+
+
+bool ossimNitfFileHeader::getTag(ossimNitfTagInformation& tagInfo,
+                                 const ossimString& tagName)const
+{
+   if(theTagList.size())
+   {
+      for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
+      {
+         if(theTagList[i].getTagName() == tagName)
+         {
+            tagInfo = theTagList[i];
+            return true;
+         }
+      }
+   }
+
+   return false;
+}
+
+bool  ossimNitfFileHeader::hasImages()const
+{
+   return (getNumberOfImages() > 0);
+}
+
+bool  ossimNitfFileHeader::hasSymbols()const
+{
+   return (getNumberOfSymbols() > 0);
+}
+
+bool  ossimNitfFileHeader::hasGraphics()const
+{
+   return (getNumberOfGraphics() > 0);
+}
+
+bool  ossimNitfFileHeader::hasText()const
+{
+   return (getNumberOfTextSegments() > 0);
+}
+
+bool  ossimNitfFileHeader::hasLabels()const
+{
+   return (getNumberOfLabels() > 0);
+}
+bool ossimNitfFileHeader::hasDataExtSegments()const
+{
+   return (getNumberOfDataExtSegments() > 0);
+}
+
+bool ossimNitfFileHeader::getTagInformation(ossimNitfTagInformation& tag,
+                                            int idx) const
+{
+   bool result = false;
+   
+   if(static_cast<ossim_uint32>(idx) < theTagList.size())
+   {
+      tag = theTagList[idx];
+      result = true;
+   }
+   
+   return result;
+}
+
+int ossimNitfFileHeader::getNumberOfTags()const
+{
+   return theTagList.size();
+}
+
+ossim_uint32 ossimNitfFileHeader::getTotalTagLength()const
+{
+   ossim_uint32 tagLength = 0;
+   
+   for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
+   {
+      tagLength += theTagList[i].getTotalTagLength();
+   }
+   
+   return tagLength;
+}
+
+
+void ossimNitfFileHeader::setProperty(ossimRefPtr<ossimProperty> property)
+{
+}
+
+ossimRefPtr<ossimProperty> ossimNitfFileHeader::getProperty(const ossimString& name)const
+{
+   return NULL;
+}
+
+void ossimNitfFileHeader::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeader.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeader.h
new file mode 100644
index 0000000000..a87358ea01
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeader.h
@@ -0,0 +1,179 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfFileHeader.h,v 1.11 2005/08/19 18:59:45 gpotts Exp $
+#ifndef ossimNitfFileHeader_HEADER
+#define ossimNitfFileHeader_HEADER
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <iterator>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/common/ossimObject.h>
+#include <base/common/ossimPropertyInterface.h>
+#include <base/property/ossimProperty.h>
+#include "ossimNitfTagInformation.h"
+
+class ossimNitfImageHeader;
+class ossimNitfSymbolHeader;
+class ossimNitfTextHeader;
+class ossimNitfLabelHeader;
+class ossimNitfRegisteredTag;
+class ossimNitfDataExtensionSegment;
+class ossimNitfRegisteredTag;
+// These structures are just data holders and will
+// not be used directly by outside users.  This is for internal use
+//
+class OSSIM_DLL ossimNitfImageOffsetInformation : public ossimObject
+{
+public:
+   virtual std::ostream& print(std::ostream& out) const;
+
+   ossimNitfImageOffsetInformation(long headerOffset,
+                                   long dataOffset)
+      :theImageHeaderOffset(headerOffset),
+       theImageDataOffset(dataOffset)
+      {
+      }
+   
+   long theImageHeaderOffset;
+   long theImageDataOffset;
+};
+
+
+class OSSIMDLLEXPORT ossimNitfSymbolOffsetInformation : public ossimObject
+{
+public:
+   ossimNitfSymbolOffsetInformation(long headerOffset,
+                                    long dataOffset)
+      :theSymbolHeaderOffset(headerOffset),
+       theSymbolDataOffset(dataOffset)
+      {
+      }
+   
+   long theSymbolHeaderOffset;
+   long theSymbolDataOffset;
+};
+
+class OSSIMDLLEXPORT ossimNitfLabelOffsetInformation : public ossimObject
+{
+public:
+   ossimNitfLabelOffsetInformation(long headerOffset,
+                                   long dataOffset)
+      :theLabelHeaderOffset(headerOffset),
+       theLabelDataOffset(dataOffset)
+      {
+      }
+   
+   long theLabelHeaderOffset;
+   long theLabelDataOffset;
+};
+
+class OSSIMDLLEXPORT ossimNitfTextOffsetInformation : public ossimObject
+{
+public:
+   ossimNitfTextOffsetInformation(long headerOffset,
+                                  long dataOffset)
+      :theTextHeaderOffset(headerOffset),
+       theTextDataOffset(dataOffset)
+      {
+      }
+   
+   long theTextHeaderOffset;
+   long theTextDataOffset;
+   
+};
+
+class OSSIMDLLEXPORT ossimNitfDataExtSegOffsetInformation : public ossimObject
+{
+public:
+   ossimNitfDataExtSegOffsetInformation(long headerOffset,
+                                        long dataOffset)
+      :theDataExtSegHeaderOffset(headerOffset),
+       theDataExtSegDataOffset(dataOffset)
+      {
+      }
+   
+   long theDataExtSegHeaderOffset;
+   long theDataExtSegDataOffset;   
+};
+
+class OSSIM_DLL ossimNitfFileHeader : public ossimObject,
+                                      public ossimPropertyInterface
+{
+public:
+   friend class ossimNitfFile;
+
+   ossimNitfFileHeader();
+   virtual ~ossimNitfFileHeader();
+
+   virtual void parseStream(std::istream &in)= 0;
+   virtual void writeStream(std::ostream &out)=0;
+   
+   virtual bool isEncrypted()const=0;
+   virtual long getNumberOfImages()const=0;
+   virtual long getNumberOfLabels()const=0;
+   virtual long getNumberOfSymbols()const=0;
+   virtual long getNumberOfGraphics()const=0;
+   virtual long getNumberOfTextSegments()const=0;
+   virtual long getNumberOfDataExtSegments()const=0;
+   virtual long getHeaderSize()const=0;
+   
+   virtual bool  getTagInformation(ossimNitfTagInformation& tag,
+                                   int idx)const;
+
+   virtual int getNumberOfTags()const;
+
+   virtual bool getTag(ossimNitfTagInformation& tagInfo,
+                       const ossimString& tagName)const;
+   
+   virtual long getFileSize()const=0;
+   virtual const char* getVersion()const=0;
+   virtual const char* getDateTime()const=0;
+   virtual ossimDrect getImageRect()const=0;
+   virtual ossimString getSecurityClassification()const=0;
+   
+   bool hasImages()const;
+   bool hasSymbols()const;
+   bool hasGraphics()const;
+   bool hasText()const;
+   bool hasLabels()const;
+   bool hasDataExtSegments()const;
+   virtual ossimNitfImageHeader* getNewImageHeader(long imageNumber,
+                                                   std::istream& in)const=0;
+   virtual ossimNitfSymbolHeader* getNewSymbolHeader(long symbolNumber,
+                                                    std::istream& in)const=0;
+   virtual ossimNitfLabelHeader* getNewLabelHeader(long labelNumber,
+                                                   std::istream& in)const=0;
+   virtual ossimNitfTextHeader* getNewTextHeader(long textNumber,
+                                                std::istream& in)const=0;
+   virtual ossimNitfDataExtensionSegment* getNewDataExtensionSegment(long dataExtNumber,
+                                                                     std::istream& in)const=0;
+   virtual ossimNitfImageHeader*    allocateImageHeader()const=0;
+   virtual ossimNitfSymbolHeader*   allocateSymbolHeader()const=0;
+   virtual ossimNitfLabelHeader*    allocateLabelHeader()const=0;
+   virtual ossimNitfTextHeader*     allocateTextHeader()const=0;
+   virtual ossimNitfDataExtensionSegment *allocateDataExtSegment()const=0;
+
+   virtual ossim_uint32 getTotalTagLength()const;
+
+
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   
+protected:
+   std::vector<ossimNitfTagInformation> theTagList;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_0.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_0.cpp
new file mode 100644
index 0000000000..ebee8980ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_0.cpp
@@ -0,0 +1,837 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfFileHeaderV2_0.cpp,v 1.9 2005/08/24 12:02:47 gpotts Exp $
+#include <support_data/nitf/ossimNitfFileHeaderV2_0.h>
+#include <support_data/nitf/ossimNitfImageHeaderV2_0.h>
+#include <support_data/nitf/ossimNitfSymbolHeaderV2_0.h>
+#include <support_data/nitf/ossimNitfLabelHeaderV2_0.h>
+#include <support_data/nitf/ossimNitfTextHeaderV2_0.h>
+#include <support_data/nitf/ossimNitfTagFactoryRegistry.h>
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+#include <support_data/nitf/ossimNitfDataExtensionSegmentV2_0.h>
+
+#include <cstring> // for memset
+#include <base/data_types/ossimString.h>
+#include <base/common/ossimTrace.h>
+
+
+static const ossimTrace traceDebug("ossimNitfFileHeaderV2_0:debug");
+
+RTTI_DEF1(ossimNitfFileHeaderV2_0, "ossimNitfFileHeaderV2_0", ossimNitfFileHeader)
+
+ostream& operator <<(ostream& out,
+                     const ossimNitfImageInfoRecordV2_0 &data)
+{
+   return out << "theImageSubheaderLength:       " << data.theImageSubheaderLength << endl
+              << "theImageLength:                " << data.theImageLength;
+}
+
+ostream& operator <<(ostream& out,
+                     const ossimNitfSymbolInfoRecordV2_0 &data)
+{
+   return out << "theSymbolSubheaderLength:       " << data.theSymbolSubheaderLength << endl
+              << "theSymbolLength:                " << data.theSymbolLength;
+}
+
+ostream& operator <<(ostream& out,
+                     const ossimNitfLabelInfoRecordV2_0 &data)
+{
+   return out << "theLabelSubheaderLength:       " << data.theLabelSubheaderLength << endl
+              << "theLabelLength:                " << data.theLabelLength;
+}
+
+ostream& operator <<(ostream& out,
+                     const ossimNitfTextInfoRecordV2_0 &data)
+{
+   return out << "theTextSubheaderLength:       " << data.theTextSubheaderLength << endl
+              << "theTextLength:                " << data.theTextLength;
+}
+
+ostream& operator <<(ostream& out,
+                     const ossimNitfDataExtSegInfoRecordV2_0 &data)
+{
+   return out << "theDataExtSegSubheaderLength:       " << data.theDataExtSegSubheaderLength << endl
+              << "theDataExtSegLength:                " << data.theDataExtSegLength;
+}
+
+ostream& operator <<(ostream& out,
+                     const ossimNitfResExtSegInfoRecordV2_0 &data)
+{
+   return out << "theResExtSegSubheaderLength:       " << data.theResExtSegSubheaderLength << endl
+              << "theResExtSegLength:                " << data.theResExtSegLength;
+}
+
+
+
+
+
+ossimNitfFileHeaderV2_0::ossimNitfFileHeaderV2_0()
+   :ossimNitfFileHeader()
+{
+   clearFields();
+}
+
+ossimNitfFileHeaderV2_0::~ossimNitfFileHeaderV2_0()
+{
+}
+
+
+void ossimNitfFileHeaderV2_0::parseStream(std::istream &in)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)<< "ossimNitfFileHeaderV2_0::parseStream:   entered ......." << std::endl;
+   }
+   
+   clearFields();
+   
+   // identification and origination group
+   in.read(theFileTypeVersion, 9);
+   theHeaderSize+=9;
+   in.read(theComplianceLevel, 2);
+   theHeaderSize+=2;
+   in.read(theSystemType, 4);
+   theHeaderSize+=4;
+   in.read(theOriginatingStationId, 10);
+   theHeaderSize+=10;
+   in.read(theDateTime, 14);
+   theHeaderSize+=14;
+   in.read(theFileTitle, 80);
+   theHeaderSize+=80;
+   
+   // read security group
+   in.read(theSecurityClassification, 1);
+   theHeaderSize++;
+   in.read(theCodewords, 40);
+   theHeaderSize+=40;
+   in.read(theControlAndHandling, 40);
+   theHeaderSize+=40;
+   in.read(theReleasingInstructions, 40);
+   theHeaderSize+=40;
+   in.read(theClassificationAuthority, 20);
+   theHeaderSize+=20;
+   in.read(theSecurityControlNumber, 20);
+   theHeaderSize+=20;
+   in.read(theSecurityDowngrade, 6);
+   theHeaderSize+=6;
+   if(ossimString(theSecurityDowngrade) == "999998")
+   {
+      in.read(theDowngradingEvent, 40);
+      theHeaderSize+=40;
+   }      
+   in.read(theMessageCopyNumber, 5);
+   theHeaderSize+=5;
+   in.read(theNumberOfCopies, 5);
+   theHeaderSize+=5;
+   in.read(theEncryption, 1);
+   theHeaderSize++;
+   in.read(theOriginatorsName, 27);
+   theHeaderSize+=27;
+   in.read(theOriginatorsPhone, 18);
+   theHeaderSize+=18;
+   
+   in.read(theNitfFileLength, 12);
+   theHeaderSize+=12;
+   in.read(theNitfHeaderLength, 6);
+   theHeaderSize+=6;
+   
+   // image description group
+   in.read(theNumberOfImageInfoRecords, 3);
+   theHeaderSize+=3;
+   readImageInfoRecords(in);
+
+   // symbol description group
+   in.read(theNumberOfSymbolInfoRecords, 3);
+   theHeaderSize+=3;
+   readSymbolInfoRecords(in);
+   
+   // label description group
+   in.read(theNumberOfLabelInfoRecords, 3);
+   theHeaderSize+=3;
+   readLabelInfoRecords(in);
+   
+   // text file information group
+   in.read(theNumberOfTextFileInfoRecords, 3);
+   theHeaderSize+=3;
+   readTextFileInfoRecords(in);
+   
+   // Data extension group
+   in.read(theNumberOfDataExtSegInfoRecords, 3);
+   theHeaderSize+=3;
+   readDataExtSegInfoRecords(in);
+   
+   // Reserve Extension Segment group
+   in.read(theNumberOfResExtSegInfoRecords, 3);
+   theHeaderSize+=3;
+   readResExtSegInfoRecords(in);
+   
+   in.read(theUserDefinedHeaderDataLength, 5);
+   theHeaderSize+=5;
+   
+   theTagList.clear();
+   // only get the header overflow if there even exists
+   // user defined data.
+   long userDefinedHeaderLength = ossimString(theUserDefinedHeaderDataLength).toLong();
+   ossimNitfTagInformation         headerTag;
+   
+   std::streampos start   = in.tellg();
+   std::streampos current = in.tellg();
+   theHeaderSize+=userDefinedHeaderLength;
+   if(userDefinedHeaderLength > 0)
+   {
+      in.read(theUserDefinedHeaderOverflow, 3);
+      
+      while((current - start) < userDefinedHeaderLength)
+      {
+         headerTag.parseStream(in);
+         theTagList.push_back(headerTag);
+         in.ignore(headerTag.getTagLength());
+         headerTag.clearFields();
+         current = in.tellg();
+      }
+   }
+   in.read(theExtendedHeaderDataLength, 5);
+   theHeaderSize+=5;
+   long extendedHeaderDataLength = ossimString(theExtendedHeaderDataLength).toLong();
+   theHeaderSize+=extendedHeaderDataLength;
+   
+   start   = in.tellg();
+   current = in.tellg();
+   // for now let's just ignore it
+   if(extendedHeaderDataLength > 0)
+   {
+      in.read(theExtendedHeaderOverflow, 3);
+      
+      while((current - start) < extendedHeaderDataLength)
+      {
+         headerTag.parseStream(in);
+         theTagList.push_back(headerTag);
+         in.ignore(headerTag.getTagLength());
+         headerTag.clearFields();
+         current = in.tellg();
+      }
+   }
+   
+   // this need to be re-thought
+   initializeAllOffsets();
+
+   if(traceDebug())
+   {
+      print(ossimNotify(ossimNotifyLevel_DEBUG)) << std::endl;
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)<< "ossimNitfFileHeaderV2_0::parseStream:   Leaving......." << std::endl;
+   }
+//      initializeDisplayLevels(in);
+
+}
+
+void ossimNitfFileHeaderV2_0::writeStream(std::ostream &out)
+{
+   
+}
+
+std::ostream& ossimNitfFileHeaderV2_0::print(std::ostream& out)const
+{
+   out << "theFileTypeVersion:         " << theFileTypeVersion << endl
+       << "theComplianceLevel:         " << theComplianceLevel << endl
+       << "theSystemType:              " << theSystemType      << endl
+       << "theOriginatingStationId:    " << theOriginatingStationId << endl
+       << "theDateTime:                " << theDateTime        << endl
+       << "theFileTitle:               " << theFileTitle       << endl
+       << "theSecurityClassification:  " << theSecurityClassification << endl
+       << "theCodewords:               " << theCodewords << endl
+       << "theControlAndHandling:      " << theControlAndHandling << endl
+       << "theReleasingInstructions:   " << theReleasingInstructions << endl
+       << "theClassificationAuthority: " << theClassificationAuthority << endl
+       << "theSecurityControlNumber:   " << theSecurityControlNumber << endl
+       << "theSecurityDowngrade:       " << theSecurityDowngrade << endl
+       << "theDowngradingEvent:        " << theDowngradingEvent << endl
+       << "theMessageCopyNumber:       " << theMessageCopyNumber << endl
+       << "theNumberOfCopies:          " << theNumberOfCopies << endl
+       << "theEncryption:              " << theEncryption << endl
+       << "theOriginatorsName:         " << theOriginatorsName<< endl
+       << "theOriginatorsPhone:        " << theOriginatorsPhone << endl
+       << "theNitfFileLength:          " << theNitfFileLength   << endl
+       << "theNitfHeaderLength:        " << theNitfHeaderLength << endl
+       << "theNumberOfImageInfoRecords: " << theNumberOfImageInfoRecords << endl;
+
+   copy(theNitfImageInfoRecords.begin(),
+        theNitfImageInfoRecords.end(),
+        ostream_iterator<ossimNitfImageInfoRecordV2_0>(out, "\n"));
+
+   out << "theNumberOfSymbolInfoRecords: " << theNumberOfSymbolInfoRecords << endl;
+   copy(theNitfSymbolInfoRecords.begin(),
+        theNitfSymbolInfoRecords.end(),
+        ostream_iterator<ossimNitfSymbolInfoRecordV2_0>(out, "\n"));
+
+   out << "theNumberOfLabelInfoRecords: " << theNumberOfLabelInfoRecords << endl;
+   copy(theNitfLabelInfoRecords.begin(),
+        theNitfLabelInfoRecords.end(),
+        ostream_iterator<ossimNitfLabelInfoRecordV2_0>(out, "\n"));
+
+   out << "theNumberOfTextFileInfoRecords: " << theNumberOfTextFileInfoRecords << endl;
+   copy(theNitfTextInfoRecords.begin(),
+        theNitfTextInfoRecords.end(),
+        ostream_iterator<ossimNitfTextInfoRecordV2_0>(out, "\n"));
+
+   out << "theNumberOfDataExtSegInfoRecords: " << theNumberOfDataExtSegInfoRecords << endl;
+   copy(theNitfDataExtSegInfoRecords.begin(),
+        theNitfDataExtSegInfoRecords.end(),
+        ostream_iterator<ossimNitfDataExtSegInfoRecordV2_0>(out, "\n"));
+
+   out << "theNumberOfResExtSegInfoRecords: " << theNumberOfResExtSegInfoRecords << endl;
+   copy(theNitfResExtSegInfoRecords.begin(),
+        theNitfResExtSegInfoRecords.end(),
+        ostream_iterator<ossimNitfResExtSegInfoRecordV2_0>(out, "\n"));
+
+   out << "theUserDefinedHeaderDataLength:  " << theUserDefinedHeaderDataLength << endl
+       << "theUserDefinedHeaderOverflow:    " << theUserDefinedHeaderOverflow << endl
+       << "theExtendedHeaderDataLength:     " << theExtendedHeaderDataLength << endl;
+
+   out << "TAGS:\n";
+   std::copy(theTagList.begin(),
+             theTagList.end(),
+             std::ostream_iterator<ossimNitfTagInformation>(out,"\n"));
+//   out << theHeaderTag;
+   return out;
+}
+
+ossimDrect ossimNitfFileHeaderV2_0::getImageRect()const
+{
+   return theImageRect;
+}
+
+ossimNitfImageHeader*
+ossimNitfFileHeaderV2_0::getNewImageHeader(long imageNumber,
+                                           std::istream& in)const
+{
+   ossimNitfImageHeader *result = 0;
+   
+   if((getNumberOfImages() > 0) &&
+      (imageNumber < (long)theImageOffsetList.size()) &&
+      (imageNumber >= 0))
+   {
+      result = allocateImageHeader();
+      in.seekg(theImageOffsetList[imageNumber].theImageHeaderOffset, ios::beg);
+      result->parseStream(in);
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "ossimNitfFileHeaderV2_0::getNewImageHeader ERROR:"
+                                          << "\nNo images in file or image number (" << imageNumber
+                                          << ") is out of range!\n";
+   }
+   
+   return result;
+}
+
+ossimNitfSymbolHeader *ossimNitfFileHeaderV2_0::getNewSymbolHeader(long symbolNumber,
+                                                                   std::istream& in)const
+{
+   ossimNitfSymbolHeader *result = 0;
+
+   if((getNumberOfSymbols() > 0) &&
+      (symbolNumber < (long)theSymbolOffsetList.size()) &&
+      (symbolNumber >= 0))
+   {
+      result = allocateSymbolHeader();
+      in.seekg(theSymbolOffsetList[symbolNumber].theSymbolHeaderOffset, ios::beg);
+      result->parseStream(in);
+   }
+   
+   return result;
+}
+
+ossimNitfLabelHeader *ossimNitfFileHeaderV2_0::getNewLabelHeader(long labelNumber,
+                                                                 std::istream& in)const
+{
+   ossimNitfLabelHeader *result = 0;
+
+   if((getNumberOfLabels() > 0) &&
+      (labelNumber < (long)theLabelOffsetList.size()) &&
+      (labelNumber >= 0))
+   {
+      result = allocateLabelHeader();
+      in.seekg(theLabelOffsetList[labelNumber].theLabelHeaderOffset, ios::beg);
+      result->parseStream(in);
+   }
+   
+   return result;
+}
+
+ossimNitfTextHeader *ossimNitfFileHeaderV2_0::getNewTextHeader(long textNumber,
+                                                               std::istream& in)const
+{
+   ossimNitfTextHeader *result = 0;
+
+   if((getNumberOfTextSegments() > 0) &&
+      (textNumber < (long)theTextOffsetList.size()) &&
+      (textNumber >= 0))
+   {
+      result = allocateTextHeader();
+      in.seekg(theTextOffsetList[textNumber].theTextHeaderOffset, ios::beg);
+      result->parseStream(in);
+   }
+   
+   return result;
+}
+
+ossimNitfDataExtensionSegment* ossimNitfFileHeaderV2_0::getNewDataExtensionSegment(long dataExtNumber,
+                                                                                   std::istream& in)const
+{
+   ossimNitfDataExtensionSegment *result = 0;
+
+   if((getNumberOfDataExtSegments() > 0) &&
+      (dataExtNumber < (long)theNitfDataExtSegInfoRecords.size()) &&
+      (dataExtNumber >= 0))
+   {
+      result = allocateDataExtSegment();
+      in.seekg(theDataExtSegOffsetList[dataExtNumber].theDataExtSegHeaderOffset, ios::beg);
+      result->parseStream(in);
+   }
+   
+   return result;
+}
+
+void ossimNitfFileHeaderV2_0::initializeDisplayLevels(std::istream& in)
+{
+   // we will need to temporarily save the get pointer since
+   // initializeDisplayLevels changes it.
+   long saveTheGetPointer = in.tellg();
+   
+   vector<ossimNitfImageOffsetInformation>::iterator imageOffsetList = theImageOffsetList.begin();
+
+   // allocate temporary space to store image headers
+   ossimNitfImageHeader* imageHeader = allocateImageHeader();
+
+   // clear the list
+   theDisplayInformationList.clear();
+   
+   theImageRect = ossimDrect(0,0,0,0);
+   if(!imageHeader)
+   {
+      return;
+   }
+   
+   long index = 0;
+   while(imageOffsetList != theImageOffsetList.end())
+   {
+      // position the get pointer in the input
+      // stream to the start of the image header
+      in.seekg((*imageOffsetList).theImageHeaderOffset, ios::beg);
+      // get the data
+      imageHeader->parseStream(in);
+      // create a union of rects.  The result should be the image rect.
+      ossimDrect tempRect = imageHeader->getImageRect();
+      if((tempRect.width() > 1) &&
+         (tempRect.height() > 1))
+      {
+         theImageRect = theImageRect.combine(tempRect);
+      }
+      
+      insertIntoDisplayInfoList(ossimNitfDisplayInfo(ossimString("IM"),
+                                                     imageHeader->getDisplayLevel(),
+                                                     index));
+      
+      ++imageOffsetList;
+      ++index;                                       
+   }
+   delete imageHeader;
+   imageHeader = 0;
+
+
+   
+   // finally we reset the saved get state back
+   // to its original position
+   in.seekg(saveTheGetPointer, ios::beg);
+}
+
+void ossimNitfFileHeaderV2_0::insertIntoDisplayInfoList(const ossimNitfDisplayInfo &displayInformation)
+{
+   vector<ossimNitfDisplayInfo>::iterator displayList = theDisplayInformationList.begin();
+
+   while(displayList != theDisplayInformationList.end())
+   {
+      if(displayInformation.theDisplayLevel < (*displayList).theDisplayLevel)
+      {
+         theDisplayInformationList.insert(displayList, displayInformation);
+         return;
+      }
+      ++displayList;
+   }
+
+   // If we get here it means it's larger than all others
+   // and we push onto the end
+   theDisplayInformationList.push_back(displayInformation);
+}
+
+void ossimNitfFileHeaderV2_0::initializeAllOffsets()
+{
+   // this will be a running tally 
+   long tally = theHeaderSize;
+   long index = 0;
+
+   // clear out all offset inforamtion and begin populating them
+   theImageOffsetList.clear();
+   theSymbolOffsetList.clear();
+   theLabelOffsetList.clear();
+   theLabelOffsetList.clear();
+   
+
+   for(index = 0; index < (long)theNitfImageInfoRecords.size(); index++)
+   {
+      theImageOffsetList.push_back(ossimNitfImageOffsetInformation(tally,
+                                                                   tally + theNitfImageInfoRecords[index].getTotalLength()));
+      tally += theNitfImageInfoRecords[index].getTotalLength();
+   }
+   for(index = 0; index < (long)theNitfSymbolInfoRecords.size(); index++)
+   {
+      theSymbolOffsetList.push_back(ossimNitfSymbolOffsetInformation(tally,
+                                                                     tally + theNitfSymbolInfoRecords[index].getTotalLength()));
+      tally += theNitfSymbolInfoRecords[index].getTotalLength();
+   }
+
+   for(index = 0; index < (long)theNitfLabelInfoRecords.size(); index++)
+   {
+      theLabelOffsetList.push_back(ossimNitfLabelOffsetInformation(tally,
+                                                                   tally + theNitfLabelInfoRecords[index].getTotalLength()));
+      tally += theNitfLabelInfoRecords[index].getTotalLength();
+   }
+
+   for(index = 0; index < (long)theNitfTextInfoRecords.size(); index++)
+   {
+      theTextOffsetList.push_back(ossimNitfTextOffsetInformation(tally,
+                                                                 tally + theNitfTextInfoRecords[index].getTotalLength()));
+      tally += theNitfTextInfoRecords[index].getTotalLength();
+   }
+
+   for(index = 0; index < (long)theNitfDataExtSegInfoRecords.size(); index++)
+   {
+      theDataExtSegOffsetList.push_back(ossimNitfDataExtSegOffsetInformation(tally,
+                                                                             tally + theNitfDataExtSegInfoRecords[index].getTotalLength()));
+      tally += theNitfDataExtSegInfoRecords[index].getTotalLength();
+   }
+}
+
+ossimNitfImageHeader *ossimNitfFileHeaderV2_0::allocateImageHeader()const
+{
+   return new ossimNitfImageHeaderV2_0;
+}
+
+ossimNitfSymbolHeader *ossimNitfFileHeaderV2_0::allocateSymbolHeader()const
+{
+   return new ossimNitfSymbolHeaderV2_0;
+}
+
+ossimNitfLabelHeader *ossimNitfFileHeaderV2_0::allocateLabelHeader()const
+{
+   return new ossimNitfLabelHeaderV2_0;
+}
+
+ossimNitfTextHeader *ossimNitfFileHeaderV2_0::allocateTextHeader()const
+{
+   return new ossimNitfTextHeaderV2_0;
+}
+
+ossimNitfDataExtensionSegment* ossimNitfFileHeaderV2_0::allocateDataExtSegment()const
+{
+   return new ossimNitfDataExtensionSegmentV2_0;
+}
+
+bool ossimNitfFileHeaderV2_0::isEncrypted()const
+{
+   return (theEncryption[0] == '1');
+}
+
+long ossimNitfFileHeaderV2_0::getNumberOfImages()const
+{
+   return theNitfImageInfoRecords.size();
+}
+
+long ossimNitfFileHeaderV2_0::getNumberOfLabels()const
+{
+   return (theNitfLabelInfoRecords.size());
+}
+
+long ossimNitfFileHeaderV2_0::getNumberOfSymbols()const
+{
+   return (theNitfSymbolInfoRecords.size());
+}
+
+long ossimNitfFileHeaderV2_0::getNumberOfGraphics()const
+{
+   return 0;
+}
+
+long ossimNitfFileHeaderV2_0::getNumberOfTextSegments()const
+{
+   return theNitfTextInfoRecords.size();
+}
+
+long ossimNitfFileHeaderV2_0::getNumberOfDataExtSegments()const
+{
+   return theNitfDataExtSegInfoRecords.size();
+}
+
+long ossimNitfFileHeaderV2_0::getHeaderSize()const
+{
+   return theHeaderSize;
+}
+
+long ossimNitfFileHeaderV2_0::getFileSize()const
+{
+   ossimString temp = theNitfFileLength;
+   if(temp == "999999999999")
+   {
+      return -1;
+   }
+   else
+   {
+      return temp.toLong();
+   }
+}
+
+const char* ossimNitfFileHeaderV2_0::getVersion()const
+{
+   return &theFileTypeVersion[4];
+}
+
+const char* ossimNitfFileHeaderV2_0::getDateTime()const
+{
+   return theDateTime;
+}
+
+ossimString ossimNitfFileHeaderV2_0::getSecurityClassification()const
+{
+   return theSecurityClassification;
+}
+
+void ossimNitfFileHeaderV2_0::clearFields()
+{
+   theDisplayInformationList.clear();
+   theImageOffsetList.clear();
+   theSymbolOffsetList.clear();
+   theLabelOffsetList.clear();
+   theTextOffsetList.clear();
+   theDataExtSegOffsetList.clear();
+   theNitfSymbolInfoRecords.clear();
+   theNitfLabelInfoRecords.clear();
+   theNitfTextInfoRecords.clear();
+   theNitfDataExtSegInfoRecords.clear();
+   theNitfResExtSegInfoRecords.clear();
+   
+   theFilename = "";
+   memset(theFileTypeVersion, ' ', 9);
+   memset(theComplianceLevel, ' ', 2);
+   memset(theSystemType, ' ', 4);
+   memset(theOriginatingStationId, ' ', 10);
+   memset(theDateTime, ' ', 14);
+   memset(theFileTitle, ' ', 80);
+   memset(theSecurityClassification, ' ', 1);
+   memset(theCodewords, ' ', 40);
+   memset(theControlAndHandling, ' ', 40);
+   memset(theReleasingInstructions, ' ', 40);
+   memset(theClassificationAuthority, ' ', 20);
+   memset(theSecurityControlNumber, ' ', 20);
+   memset(theSecurityDowngrade, ' ', 6);
+   memset(theDowngradingEvent, ' ', 40);
+   memset(theMessageCopyNumber, ' ', 5);
+   memset(theNumberOfCopies, ' ', 5);
+   memset(theEncryption, ' ', 1);
+   memset(theOriginatorsName, ' ', 27);
+   memset(theOriginatorsPhone, ' ', 18);
+   memset(theNitfFileLength, ' ', 12);
+   memset(theNitfHeaderLength, ' ', 6);
+   memset(theNumberOfImageInfoRecords, ' ', 3);
+   memset(theNumberOfSymbolInfoRecords, ' ', 3);
+   memset(theNumberOfLabelInfoRecords, ' ', 3);
+   memset(theNumberOfTextFileInfoRecords, ' ', 3);
+   memset(theNumberOfDataExtSegInfoRecords, ' ', 3);
+   memset(theNumberOfResExtSegInfoRecords, ' ', 3);
+   memset(theUserDefinedHeaderDataLength, ' ', 5);
+   memset(theUserDefinedHeaderOverflow, ' ', 3);
+   memset(theExtendedHeaderDataLength, ' ', 5);
+   memset(theExtendedHeaderOverflow, ' ', 3);
+   
+   theFileTypeVersion[9] = '\0';
+   theComplianceLevel[2] = '\0';
+   theSystemType[4]      = '\0';
+   theOriginatingStationId[10] = '\0';
+   theDateTime[14]       = '\0';
+   theFileTitle[80]      = '\0';
+   theSecurityClassification[1] = '\0';
+   theCodewords[40] = '\0';
+   theControlAndHandling[40] = '\0';
+   theReleasingInstructions[40] = '\0';
+   theClassificationAuthority[20] = '\0';
+   theSecurityControlNumber[20] = '\0';
+   theSecurityDowngrade[6] = '\0';
+   theDowngradingEvent[40] = '\0';
+   theMessageCopyNumber[5] = '\0';
+   theNumberOfCopies[5] = '\0';
+   theEncryption[1] = '\0';
+   theOriginatorsName[27] = '\0';
+   theOriginatorsPhone[18] = '\0';
+   theNitfFileLength[12]  = '\0';
+   theNitfHeaderLength[6] = '\0';
+   theNumberOfImageInfoRecords[3] = '\0';
+   theNumberOfSymbolInfoRecords[3] = '\0';
+   theNumberOfLabelInfoRecords[3] = '\0';
+   theNumberOfTextFileInfoRecords[3] = '\0';
+   theNumberOfDataExtSegInfoRecords[3] = '\0';
+   theNumberOfResExtSegInfoRecords[3] = '\0';
+   theUserDefinedHeaderDataLength[5] = '\0';
+   theUserDefinedHeaderOverflow[3] = '\0';
+   theExtendedHeaderDataLength[5] = '\0';
+   theExtendedHeaderOverflow[3] = '\0';
+   theHeaderSize = 0;
+}
+
+void ossimNitfFileHeaderV2_0::readImageInfoRecords(std::istream &in)
+{
+   long numberOfImages = ossimString(theNumberOfImageInfoRecords).toLong();
+   long index;
+
+   theNitfImageInfoRecords.clear();
+   for(index=0; index < numberOfImages; index++)
+   {
+      ossimNitfImageInfoRecordV2_0 temp;
+      
+      in.read(temp.theImageSubheaderLength, 6);
+      in.read(temp.theImageLength, 10);
+      theHeaderSize+=16;
+      temp.theImageSubheaderLength[6] = '\0';
+      temp.theImageLength[10] = '\0';
+
+      theNitfImageInfoRecords.push_back(temp);
+   }
+}
+
+void ossimNitfFileHeaderV2_0::readSymbolInfoRecords(std::istream &in)
+{
+   long numberOfSymbols = ossimString(theNumberOfSymbolInfoRecords).toLong();
+   long index;
+
+   theNitfSymbolInfoRecords.clear();
+   
+   for(index=0; index < numberOfSymbols; index++)
+   {
+      ossimNitfSymbolInfoRecordV2_0 temp;
+
+      
+      in.read(temp.theSymbolSubheaderLength, 4);
+      in.read(temp.theSymbolLength, 6);
+      theHeaderSize+=10;
+      
+      temp.theSymbolSubheaderLength[4] = '\0';
+      temp.theSymbolLength[6] = '\0';
+      
+      theNitfSymbolInfoRecords.push_back(temp);
+   }
+}
+
+void ossimNitfFileHeaderV2_0::readLabelInfoRecords(std::istream &in)
+{
+   long numberOfLabels = ossimString(theNumberOfLabelInfoRecords).toLong();
+   long index;
+
+   theNitfLabelInfoRecords.clear();
+   
+   for(index=0; index < numberOfLabels; index++)
+   {
+      ossimNitfLabelInfoRecordV2_0 temp;
+      
+      in.read(temp.theLabelSubheaderLength, 4);
+      in.read(temp.theLabelLength, 3);
+      theHeaderSize+=7;
+      temp.theLabelSubheaderLength[4] = '\0';
+      temp.theLabelLength[3]          = '\0';
+
+      theNitfLabelInfoRecords.push_back(temp);
+   }
+}
+
+void ossimNitfFileHeaderV2_0::readTextFileInfoRecords(std::istream &in)
+{
+   long numberOfTextFiles = ossimString(theNumberOfTextFileInfoRecords).toLong();
+   long index;
+
+   theNitfTextInfoRecords.clear();
+   for(index=0; index < numberOfTextFiles; index++)
+   {
+      ossimNitfTextInfoRecordV2_0 temp;
+      
+      in.read(temp.theTextSubheaderLength, 4);
+      in.read(temp.theTextLength, 5);
+      theHeaderSize+=9;
+      
+      temp.theTextSubheaderLength[4] = '\0';
+      temp.theTextLength[5] = '\0';
+      
+      theNitfTextInfoRecords.push_back(temp);
+   }
+}
+
+void ossimNitfFileHeaderV2_0::readDataExtSegInfoRecords(std::istream &in)
+{
+   long numberOfDataExtSegs = ossimString(theNumberOfDataExtSegInfoRecords).toLong();
+   long index;
+
+   theNitfDataExtSegInfoRecords.clear();
+   for(index=0; index < numberOfDataExtSegs; index++)
+   {
+      ossimNitfDataExtSegInfoRecordV2_0 temp;
+      
+      in.read(temp.theDataExtSegSubheaderLength, 4);
+      in.read(temp.theDataExtSegLength, 9);
+      theHeaderSize+=13;
+      
+      temp.theDataExtSegSubheaderLength[4] = '\0';
+      temp.theDataExtSegLength[9]          = '\0';
+
+      theNitfDataExtSegInfoRecords.push_back(temp);
+   }
+}
+
+void ossimNitfFileHeaderV2_0::readResExtSegInfoRecords(std::istream &in)
+{
+   long numberOfResExtSegs = ossimString(theNumberOfResExtSegInfoRecords).toLong();
+   long index;
+
+   theNitfResExtSegInfoRecords.clear();
+   for(index=0; index < numberOfResExtSegs; index++)
+   {
+      ossimNitfResExtSegInfoRecordV2_0 temp;
+
+      in.read(temp.theResExtSegSubheaderLength, 4);
+      in.read(temp.theResExtSegLength, 7);
+      theHeaderSize+=11;
+      
+      temp.theResExtSegSubheaderLength[4] = '\0';
+      temp.theResExtSegLength[7]          = '\0';
+      
+      theNitfResExtSegInfoRecords.push_back(temp);      
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_0.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_0.h
new file mode 100644
index 0000000000..af87ea1dd6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_0.h
@@ -0,0 +1,591 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfFileHeaderV2_0.h,v 1.7 2005/08/19 18:59:45 gpotts Exp $
+#ifndef ossimNitfFileHeaderV2_0_HEADER
+#define ossimNitfFileHeaderV2_0_HEADER
+#include "ossimNitfFileHeader.h"
+#include "base/data_types/ossimString.h"
+#include "ossimNitfTagInformation.h"
+
+class ossimNitfRegisteredTag;
+
+class ossimNitfImageInfoRecordV2_0
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimNitfImageInfoRecordV2_0 &data);
+
+   long getHeaderLength()const{return ossimString(theImageSubheaderLength).toLong();}
+   long getImageLength()const{return ossimString(theImageLength).toLong();}
+   long getTotalLength()const{return (getHeaderLength() + getImageLength()); }
+   /*!
+    * Is a 6 byte numeric 0-999999
+    */
+   char theImageSubheaderLength[7];
+
+   /*!
+    * Is a 10 byte numeric 0-999999999
+    */
+   char theImageLength[11];
+};
+
+struct ossimNitfSymbolInfoRecordV2_0
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimNitfSymbolInfoRecordV2_0 &data);
+
+   long getHeaderLength()const{return ossimString(theSymbolSubheaderLength).toLong();}
+   long getImageLength()const{return ossimString(theSymbolLength).toLong();}
+   long getTotalLength()const{return (getHeaderLength() + getImageLength()); }
+   /*!
+    * Is a 4 byte numeric 0-9999
+    */
+   char theSymbolSubheaderLength[5];
+
+   /*!
+    * Is a 6 byte numeric 0-999999
+    */
+   char theSymbolLength[7];
+};
+
+struct ossimNitfLabelInfoRecordV2_0
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimNitfLabelInfoRecordV2_0 &data);
+
+   long getHeaderLength()const{return ossimString(theLabelSubheaderLength).toLong();}
+   long getImageLength()const{return ossimString(theLabelLength).toLong();}
+   long getTotalLength()const{return (getHeaderLength() + getImageLength()); }
+   /*!
+    * Is a 4 byte numeric 0-9999
+    */
+   char theLabelSubheaderLength[5];
+
+   /*!
+    * Is a 3 byte numeric 0-320
+    */
+   char theLabelLength[4];
+};
+
+struct ossimNitfTextInfoRecordV2_0
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimNitfTextInfoRecordV2_0 &data);
+
+   long getHeaderLength()const{return ossimString(theTextSubheaderLength).toLong();}
+   long getImageLength()const{return ossimString(theTextLength).toLong();}
+   long getTotalLength()const{return (getHeaderLength() + getImageLength()); }
+   /*!
+    * Is a 4 byte numeric 0-9999
+    */
+   char theTextSubheaderLength[5];
+
+   /*!
+    * Is a 5 byte numeric 0-99999
+    */
+   char theTextLength[6];
+};
+
+struct ossimNitfDataExtSegInfoRecordV2_0
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimNitfDataExtSegInfoRecordV2_0 &data);
+
+   long getHeaderLength()const{return ossimString(theDataExtSegSubheaderLength).toLong();}
+   long getImageLength()const{return ossimString(theDataExtSegLength).toLong();}
+   long getTotalLength()const{return (getHeaderLength() + getImageLength()); }
+   /*!
+    * Is a 4 byte numeric 0-9999
+    */
+   char theDataExtSegSubheaderLength[5];
+
+   /*!
+    * Is a 9 byte numeric 0-999999999
+    */
+   char theDataExtSegLength[10];
+};
+
+struct ossimNitfResExtSegInfoRecordV2_0
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimNitfResExtSegInfoRecordV2_0 &data);
+
+   /*!
+    * Is a 4 byte numeric 0-9999
+    */
+   char theResExtSegSubheaderLength[5];
+
+   /*!
+    * Is a 7 byte numeric 0-9999999
+    */
+   char theResExtSegLength[8];
+};
+
+class OSSIMDLLEXPORT ossimNitfFileHeaderV2_0 : public ossimNitfFileHeader
+{
+public:
+   
+   ossimNitfFileHeaderV2_0();
+   virtual ~ossimNitfFileHeaderV2_0();
+   virtual void parseStream(std::istream &in);
+   virtual void writeStream(std::ostream &out);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual bool isEncrypted()const;
+   virtual long getNumberOfImages()const;
+   virtual long getNumberOfLabels()const;
+   virtual long getNumberOfSymbols()const;
+   virtual long getNumberOfGraphics()const;
+   virtual long getNumberOfTextSegments()const;
+   virtual long getNumberOfDataExtSegments()const;
+   virtual long getHeaderSize()const;
+   virtual long getFileSize()const;
+   virtual ossimString getSecurityClassification()const;
+   
+   virtual const char* getDateTime()const;
+   virtual const char* getVersion()const;
+
+   virtual ossimDrect getImageRect()const;
+
+   virtual ossimNitfImageHeader*  getNewImageHeader(long imageNumber,
+                                                    std::istream& in)const;
+   virtual ossimNitfSymbolHeader* getNewSymbolHeader(long symbolNumber,
+                                                     std::istream& in)const;
+   virtual ossimNitfLabelHeader* getNewLabelHeader(long labelNumber,
+                                                   std::istream& in)const;
+   virtual ossimNitfTextHeader*   getNewTextHeader(long textNumber,
+                                                   std::istream& in)const;
+   virtual ossimNitfDataExtensionSegment* getNewDataExtensionSegment(long dataExtNumber,
+                                                                     std::istream& in)const;
+   virtual ossimNitfImageHeader*  allocateImageHeader()const;
+   virtual ossimNitfSymbolHeader* allocateSymbolHeader()const;
+   virtual ossimNitfLabelHeader*  allocateLabelHeader()const;
+   virtual ossimNitfTextHeader*   allocateTextHeader()const;
+   virtual ossimNitfDataExtensionSegment *allocateDataExtSegment()const;
+
+TYPE_DATA
+private:
+
+   struct ossimNitfDisplayInfo
+   {
+   public:
+      ossimNitfDisplayInfo(const ossimString &filePartType,
+                           long displayLevel,
+                           long indexIntoList)
+         :theFilePartType(filePartType),
+          theDisplayLevel(displayLevel),
+          theIndex(indexIntoList)
+         {
+         }
+      
+      /*!
+       * Since NITF already has unique ids for the file
+       * part types we will just use them.
+       *
+       *  IM  indicates image part
+       *  LA  indicates a label part
+       *  SY   indicates a symbol part
+       */
+      ossimString theFilePartType;
+
+      /*!
+       * This is the display level of the renderable data.  Note the
+       * display level is like a painters algorithm.  The lowest level
+       * is drawn first followed by the next level.
+       */
+      long        theDisplayLevel;
+
+      /*!
+       * This is an index into the array that has all the offsets
+       * pre-computed.
+       */
+      long        theIndex;
+      
+   };
+
+   void clearFields();
+   
+   /*!
+    * This method will be used to setup information about the file.
+    * Example: NITF files have display levels where the lowest number is the
+    * back most image and the highes number is the front most image.  We
+    * are not guranteed that they will be in order in the file so we must
+    * parse the file and sort the images.  The images include image data,
+    * symbols and labels.  Each of these are renderable.  The lowest
+    * display level should have the larges rect and this will be used
+    * to send back to the user an image rect.  During rasterization we must
+    * know the order to draw the data.
+    */
+   void precomputeValues();
+   
+   void readImageInfoRecords(std::istream &in);
+   void readSymbolInfoRecords(std::istream &in);
+   void readLabelInfoRecords(std::istream &in);
+   void readTextFileInfoRecords(std::istream &in);
+   void readDataExtSegInfoRecords(std::istream &in);
+   void readResExtSegInfoRecords(std::istream &in);
+   /*!
+    * If the header was parsed this method will initialize the offsets
+    * to whare all data resides within the file.  Example:  NITF files
+    * have several sections (Image, Symbol, Labels, Text and Extended data) and
+    * each of these sections have subsections.  The offsets stored are just offsets
+    * from the start of the file to each major section and eqach subsection.
+    */
+   void initializeAllOffsets();
+
+   /*!
+    * This method will be called after the header is read
+    * in and the offsets have been initialized.  It will
+    * sort in order all renderable data based on their
+    * display level.
+    */
+   void initializeDisplayLevels(std::istream& in);
+
+   void insertIntoDisplayInfoList(const ossimNitfDisplayInfo &displayInformation);
+
+   
+   /*!
+    * This is the current file we are operating on.
+    */
+   ossimFilename theFilename;
+   
+   /*!
+    * This will be pre-computed when the header file is opened.  This is computed
+    * after we have found the display order.  We will use the rectangle of the
+    * smallest display number.
+    */
+   ossimDrect theImageRect;
+   
+   /*!
+    * This will hold some pre-computed information about the display
+    * order of the images.  It will be populated by scanning the
+    * file and sorting display levels.
+    */
+   vector<ossimNitfDisplayInfo>             theDisplayInformationList;
+   
+   /*!
+    * This will hold pre-computed offsets to the start of all image headers
+    * and start to their data.
+    */
+   vector<ossimNitfImageOffsetInformation>  theImageOffsetList;
+
+   /*!
+    * This will hold pre-computed offsets to the start of all symbol headers
+    * and start to their data.
+    */
+   vector<ossimNitfSymbolOffsetInformation> theSymbolOffsetList;
+
+   /*!
+    * This will hold pre-computed offsets to the start of all Label headers
+    * and start to their data.
+    */
+   vector<ossimNitfLabelOffsetInformation>  theLabelOffsetList;
+
+   /*!
+    * This will hold pre-computed offsets to the start of all text headers
+    * and start to their data.
+    */
+   vector<ossimNitfTextOffsetInformation>   theTextOffsetList;
+
+   /*!
+    * This will hold pre-coputed offsets to the start of all the data
+    * extension segments.
+    */
+   vector<ossimNitfDataExtSegOffsetInformation> theDataExtSegOffsetList;
+
+
+
+   
+   // Note: these are work variables and not part of the
+   // ossimNitf header.  These variables will be used to quickly
+   // access various parts of the file.
+   /*!
+    * This is not part of the NITF file header.  This will be
+    * computed since somethimes the header size will not be
+    * given in the header field.  This value will hold a count of
+    * all the bytes read for the header portion.  This can be used
+    * to skip past the header data.
+    */
+   long theHeaderSize;
+   
+   /*!
+    * Required field for NITF and is a 9 byte value
+    *
+    * format is NITFNN.NN where NN.NN is the version
+    * number. The valid version number for this class
+    * is NITF02.00
+    */
+   char  theFileTypeVersion[10]; // nine bytes
+
+   /*!
+    * Required field.  Value ranges from 1-99
+    */
+   char  theComplianceLevel[3];  // 2 bytes
+
+   /*!
+    * Not required.  Reserved for future use.
+    */
+   char  theSystemType[5];      // four bytes
+
+   /*!
+    * Reuqired field for NITF.  Is a 10 byte
+    * Alphanumeric
+    */
+   char  theOriginatingStationId[11]; // ten bytes
+
+   /*!
+    * Has the form DDHHMMSSZMONYY and is a required field
+    *
+    * where DD is the Day
+    *       HH is the hour
+    *       MM is the minute
+    *       SS is the seconds
+    *       Z  is just a required character
+    *       MON is first 3 chars of the month
+    *       YY  is the year
+    */
+   char  theDateTime[15];  // 14 bytes
+
+   /*!
+    * Is a required field and is an 80 byte
+    * Alphanumeric value
+    */
+   char  theFileTitle[81]; // 80 bytes
+
+   /*!
+    * This is a reqired field and is 1 byte long and
+    * can contain one of the following:
+    *
+    *  T      Top secret
+    *  S      Secret
+    *  C      Confidential
+    *  R      Restricted
+    *  U      Unclassified
+    */
+   char theSecurityClassification[2]; 
+
+   /*!
+    * This is a 40 byte Alphanumeric field
+    */
+   char theCodewords[41]; 
+
+   /*!
+    * This is a 40 byte Alphanumeric field.
+    */
+   char theControlAndHandling[41]; 
+
+   /*!
+    * This is a 40 byte Alphanumeric field.
+    */
+   char theReleasingInstructions[41]; 
+
+   /*!
+    * This is a 20 byte alphanumeric field.
+    */ 
+   char theClassificationAuthority[21];
+
+   /*!
+    * This is a 20 byte Alphanumeric field.
+    */
+   char theSecurityControlNumber[21]; 
+
+   /*!
+    * This is a 6 byte Alphanumeric.  If this field
+    * is not blank then it will have the form:
+    *
+    *   YYMMDD
+    *
+    *   Where YY is the last 2 chars of the year and will be
+    *            00 to 59 represents 2000 to 2059
+    *            60 to 99 represents 1960 to 1999
+    *
+    *
+    *   if the field is 999999 then the Originating agency field
+    *   is required. If te field is 999998 then the downgrade event
+    *   is required
+    */
+   char theSecurityDowngrade[7];
+
+   /*!
+    * This is a conditional field and is a 40 byte
+    * Alphanumeric field.  This field exists if the
+    * security downgrade is 999998.
+    */
+   char theDowngradingEvent[41];
+
+   /*!
+    * This is the copy number and is a 5 byte
+    * numeric of the form 0-99999
+    */
+   char theMessageCopyNumber[6];
+
+   /*!
+    * This is the total number of copies that exist.
+    * This is a 5 byte numeric of the form 0-99999.
+    */
+   char theNumberOfCopies[6];
+
+   /*!
+    * This is a reqired field and is a 1 byte numeric
+    * where 0 is not encrypted and 1 is encrypted.
+    */
+   char theEncryption[2];
+
+   /*!
+    * This is a 27 byte Alphanumeric number
+    */
+   char theOriginatorsName[28];
+
+   /*!
+    * This is an 18 byte Alphanumeric value. 
+    */
+   char theOriginatorsPhone[19]; 
+
+   /*!
+    * This is a required field.
+    *
+    * Is a 12 byte number of the form
+    * 000000000388-999999999998 indicates the
+    * file length and a value of 999999999999
+    * indicates that the file length was not
+    * available.
+    */
+   char theNitfFileLength[13];
+
+   /*!
+    * This is a reqired field.
+    *
+    * Will hold the header length. The values
+    * range up to 999998 and a value of
+    * 999999 indicates that the length of the
+    * header was not available upon creation.
+    */
+   char theNitfHeaderLength[7];
+
+   /*!
+    * This is a 3 byte field that specifies the number
+    * of images in the file.  0-999
+    */
+   char theNumberOfImageInfoRecords[4];
+
+   /*!
+    * This information is conditional on the number of image
+    * info records field.  If the field is greater than 0 then
+    * the record information is read in up to the indicated number
+    */
+   vector<ossimNitfImageInfoRecordV2_0> theNitfImageInfoRecords;
+
+   /*!
+    * This is a 3 byte numeric 0-999.
+    */
+
+   char theNumberOfSymbolInfoRecords[4];
+   /*!
+    * This information is conditional on the number of symbol
+    * info records field.  If the field is greater than 0 then
+    * the record information is read in up to the indicated number
+    */
+   vector<ossimNitfSymbolInfoRecordV2_0> theNitfSymbolInfoRecords;
+
+   /*!
+    * This is a 3 byte numeric 0-999.
+    */
+
+   char theNumberOfLabelInfoRecords[4];
+   
+   /*!
+    * This information is conditional on the number of label
+    * info records field.  If the field is greater than 0 then
+    * the record information is read in up to the indicated number
+    */
+   vector<ossimNitfLabelInfoRecordV2_0> theNitfLabelInfoRecords;
+
+   /*!
+    * This is a 3 byte numeric 0-999.
+    */
+   char theNumberOfTextFileInfoRecords[4];
+
+   /*!
+    * This information is conditional on the number of text file
+    * info records field.  If the field is greater than 0 then
+    * the record information is read in up to the indicated number
+    */
+   vector<ossimNitfTextInfoRecordV2_0> theNitfTextInfoRecords;
+
+   /*!
+    * This is a 3 byte numeric 0-999.
+    */
+   char theNumberOfDataExtSegInfoRecords[4];
+
+   /*!
+    * This information is conditional on the number of 
+    * info records field.  If the field is greater than 0 then
+    * the record information is read in up to the indicated number
+    */
+   vector<ossimNitfDataExtSegInfoRecordV2_0> theNitfDataExtSegInfoRecords;
+
+   /*!
+    * This is a 3 byte numeric 0-999. Reserved Extension Segments
+    */
+   char theNumberOfResExtSegInfoRecords[4];
+
+   /*!
+    * This information is conditional on the number of Res Ext Seg
+    * info records field.  If the field is greater than 0 then
+    * the record information is read in up to the indicated number
+    */
+   vector<ossimNitfResExtSegInfoRecordV2_0> theNitfResExtSegInfoRecords;
+
+   /*!
+    * This is a required field and is a 5 byte numeric ranging
+    * from 0-99999.  This is 0 if there is no data.
+    */
+   char theUserDefinedHeaderDataLength[6];
+
+   /*!
+    * This is a conditional field.  It will exist if the
+    * user defined header length is not 0.  If it exists
+    * then it may contain an overflow into one of the data
+    * extension segments above and will hold the number of that
+    * segment.
+    */
+   char theUserDefinedHeaderOverflow[4];
+
+   /*!
+    * This is a required field.  It is 5 bytes long and
+    * ranges from 0-99999.  0 means there is no data
+    */
+   char theExtendedHeaderDataLength[6];
+
+   /*!
+    * This is a required field.  It is 5 bytes long and
+    * ranges from 0-99999.  0 means there is no data
+    */
+   char theExtendedHeaderOverflow[4];
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_1.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_1.cpp
new file mode 100644
index 0000000000..152f43e94c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_1.cpp
@@ -0,0 +1,1852 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts 
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfFileHeaderV2_1.cpp,v 1.22 2005/11/17 18:12:23 dburken Exp $
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <cstring> // for memset
+
+#include <support_data/nitf/ossimNitfFileHeaderV2_1.h>
+#include <base/data_types/ossimString.h>
+#include <base/property/ossimColorProperty.h>
+#include <base/property/ossimDateProperty.h>
+#include <base/property/ossimStringProperty.h>
+#include <base/property/ossimNumericProperty.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <support_data/nitf/ossimNitfImageHeaderV2_1.h>
+
+#ifndef NULL
+#  include <cstddef>
+#endif
+
+RTTI_DEF1(ossimNitfFileHeaderV2_1,
+          "ossimNitfFileHeaderV2_1",
+          ossimNitfFileHeader)
+
+static const char* CLEVEL_KW  = "clevel";
+static const char* STYPE_KW   = "stype";
+static const char* OSTAID_KW  = "ostaid";
+static const char* FDT_KW     = "fdt";  
+static const char* FTITLE_KW  = "ftitle";
+static const char* FSCLAS_KW  = "fsclas";
+static const char* FSCLASY_KW = "fsclasy";
+static const char* FSCODE_KW  = "fscode";
+static const char* FSCTLH_KW  = "fsctlh";
+static const char* FSREL_KW   = "fsrel";
+static const char* FSDCTP_KW  = "fsdctp";
+static const char* FSDCDT_KW  = "fsdcdt";
+static const char* FSDCXM_KW  = "fsdcxm";
+static const char* FSDG_KW    = "fsdg";
+static const char* FSDGDT_KW  = "fsdgdt";
+static const char* FSCLTX_KW  = "fscltx";
+static const char* FSCATP_KW  = "fscatp";
+static const char* FSCAUT_KW  = "fscaut";
+static const char* FSCRSN_KW  = "fscrsn";
+static const char* FSSRDT_KW  = "fssrdt";
+static const char* FSCTLN_KW  = "fsctln";
+static const char* FSCOP_KW   = "fscop";
+static const char* FSCPYS_KW  = "fscpys";
+static const char* ENCRYP_KW  = "encryp";
+static const char* FBKGC_KW   = "fbkgc" ;
+static const char* ONAME_KW   = "oname";
+static const char* OPHONE_KW  = "ophone";
+
+static const
+ossimTrace traceDebug(ossimString("ossimNitfFileHeaderV2_1:debug"));
+   
+std::ostream& operator <<(std::ostream& out,
+                     const ossimNitfImageInfoRecordV2_1 &data)
+{
+   return out << "theImageSubheaderLength:       "
+              << data.theImageSubheaderLength
+              << "\ntheImageLength:                "
+              << data.theImageLength
+              << std::endl;
+}
+
+std::ostream& operator <<(std::ostream& out,
+                     const ossimNitfGraphicInfoRecordV2_1 &data)
+{
+   return out << "theGraphicSubheaderLength:     "
+              << data.theGraphicSubheaderLength
+              << "\ntheGraphicLength:              "
+              << data.theGraphicLength
+              << std::endl;
+}
+
+std::ostream& operator <<(std::ostream& out,
+                     const ossimNitfTextFileInfoRecordV2_1 &data)
+{
+   return out << "theTextFileSubheaderLength:    "
+              << data.theTextFileSubheaderLength
+              << "\ntheTextFileLength:             "
+              << data.theTextFileLength
+              << std::endl;
+}
+
+std::ostream& operator <<(std::ostream& out,
+                     const ossimNitfDataExtSegInfoRecordV2_1 &data)
+{
+   return out << "theDataExtSegSubheaderLength:  "
+              << data.theDataExtSegSubheaderLength
+              << "\ntheDataExtSegLength:           "
+              << data.theDataExtSegLength
+              << std::endl;
+}
+
+std::ostream& operator <<(std::ostream& out,
+                     const ossimNitfResExtSegInfoRecordV2_1 &data)
+{
+   return out << "theResExtSegSubheaderLength:   "
+              << data.theResExtSegSubheaderLength
+              << "\ntheResExtSegLength:            "
+              << data.theResExtSegLength
+              << std::endl;
+}
+
+
+void ossimNitfImageInfoRecordV2_1::setSubheaderLength(ossim_uint32 length)
+{
+   ostringstream out;
+
+   out << std::setw(6)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << length;
+
+   memcpy(theImageSubheaderLength, out.str().c_str(), 6);
+   theImageSubheaderLength[6] = '\0';
+}
+
+void ossimNitfImageInfoRecordV2_1::setImageLength(ossim_uint32 length)
+{
+   ostringstream out;
+
+   out << std::setw(10)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << length;
+   
+   memcpy(theImageLength, out.str().c_str(), 10);
+   theImageLength[10] = '\0';
+}
+
+
+
+ossimNitfFileHeaderV2_1::ossimNitfFileHeaderV2_1()
+   :ossimNitfFileHeader()
+{
+   clearFields();
+}
+
+ossimNitfFileHeaderV2_1::~ossimNitfFileHeaderV2_1()
+{
+}
+
+void ossimNitfFileHeaderV2_1::parseStream(std::istream& in)
+{
+   clearFields();
+
+   // identification and origination group
+   in.read(theFileTypeVersion, 9);
+   theHeaderSize += 9;
+   in.read(theComplexityLevel, 2);
+   theHeaderSize += 2;
+   in.read(theSystemType, 4);
+   theHeaderSize += 4;
+   in.read(theOriginatingStationId, 10);
+   theHeaderSize += 10;
+   in.read(theDateTime, 14);
+   theHeaderSize += 14;
+   in.read(theFileTitle, 80);
+   theHeaderSize += 80;
+
+   // read security group
+   in.read(theSecurityClassification, 1);
+   theHeaderSize ++;
+   in.read(theSecurityClassificationSys, 2);
+   theHeaderSize += 2;
+   in.read(theCodewords, 11);
+   theHeaderSize += 11;
+   in.read(theControlAndHandling, 2);
+   theHeaderSize += 2;
+   in.read(theReleasingInstructions, 20);
+   theHeaderSize += 20;
+   in.read(theDeclassificationType, 2);
+   theHeaderSize += 2;
+   in.read(theDeclassificationDate, 8);
+   theHeaderSize += 8;
+   in.read(theDeclassificationExemption, 4);
+   theHeaderSize += 4;
+      
+   in.read(theDowngrade, 1);
+   theHeaderSize ++;
+   in.read(theDowngradingDate, 8);
+   theHeaderSize += 8;
+   in.read(theClassificationText, 43);
+   theHeaderSize += 43;
+   in.read(theClassificationAuthorityType, 1);
+   theHeaderSize ++;
+   in.read(theClassificationAuthority, 40);
+   theHeaderSize += 40;
+   in.read(theClassificationReason, 1);
+   theHeaderSize ++;
+   in.read(theSecuritySourceDate, 8);
+   theHeaderSize += 8;
+   in.read(theSecurityControlNumber, 15);
+   theHeaderSize += 15;
+   in.read(theCopyNumber, 5);
+   theHeaderSize += 5;
+   in.read(theNumberOfCopies, 5);
+   theHeaderSize += 5;
+   in.read(theEncryption, 1);
+   theHeaderSize ++;
+   in.read((char*)theFileBackgroundColor, 3);
+   theHeaderSize += 3;
+   in.read(theOriginatorsName, 24);
+   theHeaderSize += 24;
+   in.read(theOriginatorsPhone, 18);
+   theHeaderSize += 18;
+   in.read(theFileLength, 12);
+   theHeaderSize += 12;
+   in.read(theHeaderLength, 6);
+   theHeaderSize += 6;
+   
+   // image description group
+   in.read(theNumberOfImageInfoRecords, 3); 
+   theHeaderSize += 3;
+   readImageInfoRecords(in); 
+
+   // symbol description group
+   in.read(theNumberOfGraphicInfoRecords, 3); 
+   theHeaderSize += 3;
+   readGraphicInfoRecords(in);
+
+   in.read(theReservedForFutureUse1, 3);
+   theHeaderSize += 3;
+      
+   // text file information group
+   in.read(theNumberOfTextFileInfoRecords, 3); 
+   theHeaderSize += 3;
+   readTextFileInfoRecords(in);
+
+   // Data extension group
+   in.read(theNumberOfDataExtSegInfoRecords, 3); 
+   theHeaderSize += 3;
+   readDataExtSegInfoRecords(in);
+
+   // Reserve Extension Segment group
+   in.read(theNumberOfResExtSegInfoRecords, 3); 
+   theHeaderSize += 3;
+   readResExtSegInfoRecords(in);
+
+   in.read(theUserDefinedHeaderDataLength, 5);
+   theHeaderSize += 5;
+
+   // only get the header overflow if there even exists
+   // user defined data.
+   std::streampos userDefinedHeaderLength = ossimString(theUserDefinedHeaderDataLength).toLong();
+   ossimNitfTagInformation         headerTag;
+   std::streampos start   = in.tellg();
+   std::streampos current = in.tellg();
+   if(userDefinedHeaderLength > 0)
+   {
+      in.read(theUserDefinedHeaderOverflow, 3);
+         
+      while((current - start) < userDefinedHeaderLength)
+      {
+         headerTag.parseStream(in);
+         theTagList.push_back(headerTag);
+         in.ignore(headerTag.getTagLength());
+         headerTag.clearFields();
+         current = in.tellg();
+      }
+      in.seekg(start + userDefinedHeaderLength);
+      theHeaderSize += (userDefinedHeaderLength);
+   }
+   in.read(theExtendedHeaderDataLength, 5);
+   theHeaderSize += 5;
+   std::streampos extendedHeaderDataLength = ossimString(theExtendedHeaderDataLength).toLong();
+
+   start   = in.tellg();
+   current = in.tellg();
+   // for now let's just ignore it
+   if(extendedHeaderDataLength > 0)
+   {
+      in.read(theExtendedHeaderDataOverflow, 3);
+      while((current - start) < extendedHeaderDataLength)
+      {
+         headerTag.parseStream(in);
+         theTagList.push_back(headerTag);
+         
+         in.ignore(headerTag.getTagLength());
+         headerTag.clearFields();
+         current = in.tellg();
+      }
+      theHeaderSize += extendedHeaderDataLength;
+      in.seekg(start + extendedHeaderDataLength);
+   }
+
+   // this need to be re-thought
+   initializeAllOffsets();
+}
+
+void ossimNitfFileHeaderV2_1::writeStream(std::ostream &out)
+{
+   out.write(theFileTypeVersion, 9);
+   out.write(theComplexityLevel, 2);
+   out.write(theSystemType, 4);
+   out.write(theOriginatingStationId, 10);
+   out.write(theDateTime, 14);
+   out.write(theFileTitle, 80);
+   out.write(theSecurityClassification, 1);
+   out.write(theSecurityClassificationSys, 2);
+   out.write(theCodewords, 11);
+   out.write(theControlAndHandling, 2);
+   out.write(theReleasingInstructions, 20);
+   out.write(theDeclassificationType, 2);
+   out.write(theDeclassificationDate, 8);
+   out.write(theDeclassificationExemption, 4);
+   out.write(theDowngrade, 1);
+   out.write(theDowngradingDate, 8);
+   out.write(theClassificationText, 43);
+   out.write(theClassificationAuthorityType, 1);
+   out.write(theClassificationAuthority, 40);
+   out.write(theClassificationReason, 1);
+   out.write(theSecuritySourceDate, 8);
+   out.write(theSecurityControlNumber, 15);
+   out.write(theCopyNumber, 5);
+   out.write(theNumberOfCopies, 5);
+   out.write(theEncryption, 1);
+   out.write((char*)theFileBackgroundColor, 3);
+   out.write(theOriginatorsName, 24);
+   out.write(theOriginatorsPhone, 18);
+   out.write(theFileLength, 12);
+   out.write(theHeaderLength, 6);
+   ossim_uint32 idx = 0;
+   {
+      ostringstream outString;
+      
+      
+      outString << std::setw(3)
+                << std::setfill('0')
+                << std::setiosflags(ios::right)
+                << theNitfImageInfoRecords.size();
+      
+      out.write(outString.str().c_str(), 3);
+      
+      for(idx = 0; idx < theNitfImageInfoRecords.size(); ++idx)
+      {
+         out.write(theNitfImageInfoRecords[idx].theImageSubheaderLength, 6);
+         out.write(theNitfImageInfoRecords[idx].theImageLength, 10);
+      }
+   }
+   {
+      ostringstream outString;
+      
+      
+      outString << std::setw(3)
+                << std::setfill('0')
+                << std::setiosflags(ios::right)
+                << theNitfGraphicInfoRecords.size();
+      
+      out.write(outString.str().c_str(), 3);
+      for(idx = 0; idx < theNitfGraphicInfoRecords.size(); ++idx)
+      {
+         out.write(theNitfGraphicInfoRecords[idx].theGraphicSubheaderLength, 4);
+         out.write(theNitfGraphicInfoRecords[idx].theGraphicLength, 6);
+      }
+   }
+   out.write(theReservedForFutureUse1, 3);
+   {
+      ostringstream outString;
+      
+      
+      outString << std::setw(3)
+                << std::setfill('0')
+                << std::setiosflags(ios::right)
+                << theNitfTextFileInfoRecords.size();
+      
+      out.write(outString.str().c_str(), 3);
+      for(idx = 0; idx < theNitfTextFileInfoRecords.size(); ++idx)
+      {
+         out.write(theNitfTextFileInfoRecords[idx].theTextFileSubheaderLength, 4);
+         out.write(theNitfTextFileInfoRecords[idx].theTextFileLength, 5);
+      }
+   }
+   {
+      ostringstream outString;
+      
+      
+      outString << std::setw(3)
+                << std::setfill('0')
+                << std::setiosflags(ios::right)
+                << theNitfDataExtSegInfoRecords.size();
+      
+      out.write(outString.str().c_str(), 3);
+      for(idx = 0; idx < theNitfDataExtSegInfoRecords.size(); ++idx)
+      {
+         out.write(theNitfDataExtSegInfoRecords[idx].theDataExtSegSubheaderLength, 4);
+         out.write(theNitfDataExtSegInfoRecords[idx].theDataExtSegLength, 9);
+      }
+   }
+   {
+      ostringstream outString;
+      
+      
+      outString << std::setw(3)
+                << std::setfill('0')
+                << std::setiosflags(ios::right)
+                << theNitfResExtSegInfoRecords.size();
+
+      out.write(outString.str().c_str(), 3);
+      for(idx = 0; idx < theNitfResExtSegInfoRecords.size(); ++idx)
+      {
+         out.write(theNitfResExtSegInfoRecords[idx].theResExtSegSubheaderLength, 4);
+         out.write(theNitfResExtSegInfoRecords[idx].theResExtSegLength, 7);
+      }
+   }
+   out.write(theUserDefinedHeaderDataLength, 5);
+   if(ossimString(theUserDefinedHeaderDataLength).toLong() > 0)
+   {
+      out.write(theUserDefinedHeaderOverflow, 3);
+   }
+
+   ossim_uint32 totalLength = getTotalTagLength();
+   if(totalLength <= 99999)
+   {
+      std::ostringstream tempOut;
+
+      tempOut << std::setw(5)
+              << std::setfill('0')
+	      << std::setiosflags(ios::right)
+              << totalLength;
+      
+      memcpy(theExtendedHeaderDataLength, tempOut.str().c_str(), 5);
+      
+      out.write(theExtendedHeaderDataLength, 5);
+
+      memset(theExtendedHeaderDataOverflow, '0', 3);
+
+      if(totalLength > 0)
+      {
+         out.write(theExtendedHeaderDataOverflow, 3);
+         ossim_uint32 i = 0;
+         
+         for(i = 0; i < theTagList.size(); ++i)
+         {
+            theTagList[i].writeStream(out);
+         }
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimNitfFileHeaderV2_1::writeStream: Only support writing of total tag length < 99999" << std::endl;
+   }
+}
+
+std::ostream& ossimNitfFileHeaderV2_1::print(std::ostream& out)const
+{
+   out << "theFileTypeVersion:           " << theFileTypeVersion
+       << "\ntheComplexityLevel:           " << theComplexityLevel
+       << "\ntheSystemType:                " << theSystemType     
+       << "\ntheOriginatingStationId:      " << theOriginatingStationId
+       << "\ntheDateTime:                  " << theDateTime       
+       << "\ntheFileTitle:                 " << theFileTitle      
+       << "\ntheSecurityClassification:    " << theSecurityClassification
+       << "\ntheSecurityClassificationSys: " << theSecurityClassificationSys
+       << "\ntheCodewords:                 " << theCodewords
+       << "\ntheControlAndHandling:        " << theControlAndHandling
+       << "\ntheReleasingInstructions:     " << theReleasingInstructions
+       << "\ntheDeclassificationType:      " << theDeclassificationType
+       << "\ntheDeclassificationDate:      " << theDeclassificationDate
+       << "\ntheDeclassificationExemption: " << theDeclassificationExemption
+       << "\ntheDowngrade:                 " << theDowngrade
+       << "\ntheDowngradingDate:           " << theDowngradingDate
+       << "\ntheClassificationText:        " << theClassificationText
+       << "\ntheClassificationAuthorityType: " << theClassificationAuthorityType
+       << "\ntheClassificationAuthority:   " << theClassificationAuthority
+       << "\ntheClassificationReason:      " << theClassificationReason
+       << "\ntheSecuritySourceDate:        " << theSecuritySourceDate
+       << "\ntheSecurityControlNumber:     " << theSecurityControlNumber
+       << "\ntheCopyNumber:                " << theCopyNumber
+       << "\ntheNumberOfCopies:            " << theNumberOfCopies
+       << "\ntheEncryption:                " << theEncryption
+       << "\ntheFileBackgroundColorRed:    " << (int)theFileBackgroundColor[0]
+       << "\ntheFileBackgroundColorGreen:  " << (int)theFileBackgroundColor[1]
+       << "\ntheFileBackgroundColorBlue:   " << (int)theFileBackgroundColor[2]
+       << "\ntheOriginatorsName:           " << theOriginatorsName
+       << "\ntheOriginatorsPhone:          " << theOriginatorsPhone
+       << "\ntheFileLength:                " << theFileLength  
+       << "\ntheHeaderLength:              " << theHeaderLength
+       << "\ntheNumberOfImageInfoRecords:  " << theNumberOfImageInfoRecords
+       << std::endl;
+   copy(theNitfImageInfoRecords.begin(),
+        theNitfImageInfoRecords.end(),
+        std::ostream_iterator<ossimNitfImageInfoRecordV2_1>(out, "\n"));
+
+   out << "theNumberOfGraphicInfoRecords: "
+       << theNumberOfGraphicInfoRecords << std::endl;
+   
+   copy(theNitfGraphicInfoRecords.begin(),
+        theNitfGraphicInfoRecords.end(),
+        std::ostream_iterator<ossimNitfGraphicInfoRecordV2_1>(out, "\n"));
+
+   out << "theNumberOfTextFileInfoRecords: "
+       << theNumberOfTextFileInfoRecords << std::endl;
+   
+   copy(theNitfTextFileInfoRecords.begin(),
+        theNitfTextFileInfoRecords.end(),
+        std::ostream_iterator<ossimNitfTextFileInfoRecordV2_1>(out, "\n"));
+
+   out << "theNumberOfDataExtSegInfoRecords: "
+       << theNumberOfDataExtSegInfoRecords << std::endl;
+
+   copy(theNitfDataExtSegInfoRecords.begin(),
+        theNitfDataExtSegInfoRecords.end(),
+        std::ostream_iterator<ossimNitfDataExtSegInfoRecordV2_1>(out, "\n"));
+
+   out << "theNumberOfResExtSegInfoRecords: "
+       << theNumberOfResExtSegInfoRecords << std::endl;
+   
+   copy(theNitfResExtSegInfoRecords.begin(),
+        theNitfResExtSegInfoRecords.end(),
+        std::ostream_iterator<ossimNitfResExtSegInfoRecordV2_1>(out, "\n"));
+   
+   out << "theUserDefinedHeaderDataLength:  " << theUserDefinedHeaderDataLength
+       << "\ntheUserDefinedHeaderOverflow:    " << theUserDefinedHeaderOverflow
+       << "\ntheExtendedHeaderDataLength:     " << theExtendedHeaderDataLength
+       << std::endl;
+   return out;
+}
+
+ossimNitfImageHeader* ossimNitfFileHeaderV2_1::allocateImageHeader()const
+{
+   return new ossimNitfImageHeaderV2_1;
+}
+
+ossimNitfTextHeader *ossimNitfFileHeaderV2_1::allocateTextHeader()const
+{
+   return NULL;
+}
+
+ossimNitfDataExtensionSegment*
+ossimNitfFileHeaderV2_1::allocateDataExtSegment()const
+{
+   return NULL;
+}
+
+bool ossimNitfFileHeaderV2_1::isEncrypted()const
+{
+   return (theEncryption[0]=='1');
+}
+
+long ossimNitfFileHeaderV2_1::getNumberOfImages()const
+{
+   return theNitfImageInfoRecords.size();
+}
+
+long ossimNitfFileHeaderV2_1::getNumberOfTextSegments()const
+{
+   return theNitfTextFileInfoRecords.size();
+}
+
+long ossimNitfFileHeaderV2_1::getHeaderSize()const
+{
+   return theHeaderSize;
+}
+
+long ossimNitfFileHeaderV2_1::getFileSize()const
+{
+   ossimString temp = theFileLength;
+
+   if(temp = "999999999999")
+   {
+      return -1;
+   }
+   else
+   {
+      return temp.toLong();
+   }
+}
+
+const char* ossimNitfFileHeaderV2_1::getVersion()const
+{
+   return &theFileTypeVersion[4];
+}
+
+
+void ossimNitfFileHeaderV2_1::clearFields()
+{
+   memcpy(theFileTypeVersion, "NITF02.10", 9);
+   memcpy(theComplexityLevel, "01", 2);
+   memcpy(theSystemType, "BF01", 4);
+   memset(theOriginatingStationId, ' ', 10);
+   memset(theDateTime, ' ', 14);
+   memset(theFileTitle, ' ', 80);
+   memset(theSecurityClassification, ' ', 1);
+   memset(theSecurityClassificationSys, ' ', 2);
+   memset(theCodewords, ' ', 11);
+   memset(theControlAndHandling, ' ', 2);
+   memset(theReleasingInstructions, ' ', 20);
+   memset(theDeclassificationType, ' ', 2);
+   memset(theDeclassificationDate, ' ', 8);
+   memset(theDeclassificationExemption, ' ', 4);
+   memset(theDowngrade, ' ', 1);
+   memset(theDowngradingDate, ' ', 8);
+   memset(theClassificationText, ' ', 43);
+   memset(theClassificationAuthorityType, ' ', 1);
+   memset(theClassificationAuthority, ' ', 40);
+   memset(theClassificationReason, ' ', 1);
+   memset(theSecuritySourceDate, ' ', 8);
+   memset(theSecurityControlNumber, ' ', 15);
+   memset(theCopyNumber, ' ', 5);
+   memset(theNumberOfCopies, ' ', 5);
+   memset(theEncryption, ' ', 1);
+   memset(theFileBackgroundColor, 0, 3);
+   memset(theOriginatorsName, ' ', 24);
+   memset(theOriginatorsPhone, ' ', 18);
+   memset(theFileLength, ' ', 12);
+   memset(theHeaderLength, ' ', 6);
+   memset(theNumberOfImageInfoRecords, '0', 3);
+   memset(theNumberOfGraphicInfoRecords, '0', 3);
+   memset(theReservedForFutureUse1, '0', 3);
+   memset(theNumberOfTextFileInfoRecords, '0', 3);
+   memset(theNumberOfDataExtSegInfoRecords, '0', 3);
+   memset(theNumberOfResExtSegInfoRecords, '0', 3);
+   memset(theUserDefinedHeaderDataLength, '0', 5);
+   memset(theUserDefinedHeaderOverflow, '0',3);
+   memset(theExtendedHeaderDataLength, '0',5);
+   theFileTypeVersion[9] = '\0';
+   theComplexityLevel[2] = '\0';
+   theSystemType[4] = '\0';
+   theOriginatingStationId[10] = '\0';
+   theDateTime[14] = '\0';
+   theFileTitle[80] = '\0';
+   theSecurityClassification[1] = '\0';
+   theSecurityClassificationSys[2] = '\0';
+   theCodewords[11] = '\0';
+   theControlAndHandling[2] = '\0';
+   theReleasingInstructions[20] = '\0';
+   theDeclassificationType[2] = '\0';
+   theDeclassificationDate[8] = '\0';
+   theDeclassificationExemption[4] = '\0';
+   theDowngrade[1] = '\0';
+   theDowngradingDate[8] = '\0';
+   theClassificationText[43] = '\0';
+   theClassificationAuthorityType[1] = '\0';
+   theClassificationAuthority[40] = '\0';
+   theClassificationReason[1] = '\0';
+   theSecuritySourceDate[8] = '\0';
+   theSecurityControlNumber[15] = '\0';
+   theCopyNumber[5] = '\0';
+   theNumberOfCopies[5] = '\0';
+   theEncryption[1] = '\0';
+   theOriginatorsName[24] = '\0';
+   theOriginatorsPhone[18] = '\0';
+   theFileLength[12] = '\0';
+   theHeaderLength[6] = '\0';
+   theNumberOfImageInfoRecords[3] = '\0';
+   theNumberOfGraphicInfoRecords[3] = '\0';
+   theNumberOfTextFileInfoRecords[3] = '\0';
+   theNumberOfDataExtSegInfoRecords[3] = '\0';
+   theNumberOfResExtSegInfoRecords[3] = '\0';
+   theUserDefinedHeaderDataLength[5] = '\0';
+   theUserDefinedHeaderOverflow[3] = '\0';
+   theExtendedHeaderDataLength[5] = '\0';
+   theExtendedHeaderDataOverflow[3] = '\0';
+
+   theHeaderSize = 0;
+}
+
+void ossimNitfFileHeaderV2_1::readImageInfoRecords(std::istream &in)
+{
+   long numberOfImages = ossimString(theNumberOfImageInfoRecords).toLong();
+   long index;
+
+   theNitfImageInfoRecords.clear();
+   for(index=0; index < numberOfImages; index++)
+   {
+      ossimNitfImageInfoRecordV2_1 temp;
+
+      
+      in.read(temp.theImageSubheaderLength, 6);
+      in.read(temp.theImageLength, 10);
+      theHeaderSize += 16;
+
+      temp.theImageSubheaderLength[6] = '\0';
+      temp.theImageLength[10] = '\0';
+      
+      theNitfImageInfoRecords.push_back(temp);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::readGraphicInfoRecords(std::istream &in)
+{
+   long numberOfGraphics = ossimString(theNumberOfGraphicInfoRecords).toLong();
+   long index;
+
+   theNitfGraphicInfoRecords.clear();
+   
+   for(index=0; index < numberOfGraphics; index++)
+   {
+      ossimNitfGraphicInfoRecordV2_1 temp;
+
+      
+      in.read(temp.theGraphicSubheaderLength, 4);
+      in.read(temp.theGraphicLength, 6);
+      theHeaderSize += 10;
+
+      temp.theGraphicSubheaderLength[4] = '\0';
+      temp.theGraphicLength[6] = '\0';
+      
+      theNitfGraphicInfoRecords.push_back(temp);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::readTextFileInfoRecords(std::istream &in)
+{
+   long numberOfTextFiles = ossimString(theNumberOfTextFileInfoRecords).toLong();
+   long index;
+
+   theNitfTextFileInfoRecords.clear();
+   for(index=0; index < numberOfTextFiles; index++)
+   {
+      ossimNitfTextFileInfoRecordV2_1 temp;
+      
+      in.read(temp.theTextFileSubheaderLength, 4);
+      in.read(temp.theTextFileLength, 5);
+      theHeaderSize += 9;
+      
+      temp.theTextFileSubheaderLength[4] = '\0';
+      temp.theTextFileLength[5] = '\0';
+      
+      theNitfTextFileInfoRecords.push_back(temp);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::readDataExtSegInfoRecords(std::istream &in)
+{
+   long numberOfDataExtSegs = ossimString(theNumberOfDataExtSegInfoRecords).toLong();
+   long index;
+
+   theNitfDataExtSegInfoRecords.clear();
+   for(index=0; index < numberOfDataExtSegs; index++)
+   {
+      ossimNitfDataExtSegInfoRecordV2_1 temp;
+      
+      in.read(temp.theDataExtSegSubheaderLength, 4);
+      in.read(temp.theDataExtSegLength, 9);
+      theHeaderSize += 13;
+
+      temp.theDataExtSegSubheaderLength[4] = '\0';
+      temp.theDataExtSegLength[9]          = '\0';
+
+      theNitfDataExtSegInfoRecords.push_back(temp);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::readResExtSegInfoRecords(std::istream &in)
+{
+   long numberOfResExtSegs = ossimString(theNumberOfResExtSegInfoRecords).toLong();
+   long index;
+
+   theNitfResExtSegInfoRecords.clear();
+   for(index=0; index < numberOfResExtSegs; index++)
+   {
+      ossimNitfResExtSegInfoRecordV2_1 temp;
+
+      in.read(temp.theResExtSegSubheaderLength, 4);
+      in.read(temp.theResExtSegLength, 7);
+      theHeaderSize += 11;
+
+      temp.theResExtSegSubheaderLength[4] = '\0';
+      temp.theResExtSegLength[7]          = '\0';
+      
+      theNitfResExtSegInfoRecords.push_back(temp);      
+   }
+}
+
+long ossimNitfFileHeaderV2_1::getNumberOfLabels()const
+{
+   return 0;
+}
+
+long ossimNitfFileHeaderV2_1::getNumberOfSymbols()const
+{
+   return 0;
+}
+
+long ossimNitfFileHeaderV2_1::getNumberOfGraphics()const
+{
+   return 0;
+}
+
+long ossimNitfFileHeaderV2_1::getNumberOfDataExtSegments()const
+{
+   return 0;
+}
+
+const char* ossimNitfFileHeaderV2_1::getDateTime()const
+{
+   return NULL;
+}
+
+ossimDrect ossimNitfFileHeaderV2_1::getImageRect()const
+{
+   return theImageRect;
+}
+
+void ossimNitfFileHeaderV2_1::addImageInfoRecord(const ossimNitfImageInfoRecordV2_1& recordInfo)
+{
+   theNitfImageInfoRecords.push_back(recordInfo);
+
+   setNumberOfImageInfoRecords(theNitfImageInfoRecords.size());
+}
+
+void ossimNitfFileHeaderV2_1::replaceImageInfoRecord(int i, const ossimNitfImageInfoRecordV2_1& recordInfo)
+{
+   theNitfImageInfoRecords[i]=recordInfo;
+}
+
+ossimNitfSymbolHeader *ossimNitfFileHeaderV2_1::allocateSymbolHeader()const
+{
+   return NULL;                      ;
+}
+
+ossimNitfLabelHeader *ossimNitfFileHeaderV2_1::allocateLabelHeader()const
+{
+   return NULL;                      ;
+}
+
+void ossimNitfFileHeaderV2_1::initializeAllOffsets()
+{
+   // this will be a running tally 
+   long tally = theHeaderSize;
+   long index = 0;
+
+   // clear out all offset inforamtion and begin populating them
+   theImageOffsetList.clear();
+
+   for(index = 0; index < (long)theNitfImageInfoRecords.size(); ++index)
+   {
+      theImageOffsetList.push_back(ossimNitfImageOffsetInformation(tally,
+                                                                   tally + theNitfImageInfoRecords[index].getTotalLength()));
+      tally += theNitfImageInfoRecords[index].getTotalLength();
+   }
+}
+
+ossimNitfImageHeader*
+ossimNitfFileHeaderV2_1::getNewImageHeader(long imageNumber,
+                                           std::istream& in)const
+{
+   ossimNitfImageHeader *result = NULL;
+   
+   if((getNumberOfImages() > 0) &&
+      (imageNumber < (long)theImageOffsetList.size()) &&
+      (imageNumber >= 0))
+   {
+      result = allocateImageHeader();
+      in.seekg(theImageOffsetList[imageNumber].theImageHeaderOffset, ios::beg);
+      result->parseStream(in);
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimNitfFileHeaderV2_1::getNewImageHeader: "
+                                          << "\nNo images in file or image number (" << imageNumber
+                                          << ") is out of range!\n";
+   }
+   
+   return result;
+}
+
+ossimNitfSymbolHeader*
+ossimNitfFileHeaderV2_1::getNewSymbolHeader(long symbolNumber,
+                                            std::istream& in)const
+{
+   // Currently not implemented...
+   
+   ossimNitfSymbolHeader *result = NULL;
+   
+   return result;
+}
+
+ossimNitfLabelHeader*
+ossimNitfFileHeaderV2_1::getNewLabelHeader(long labelNumber,
+                                           std::istream& in)const
+{
+   // Currently not implemented...
+   ossimNitfLabelHeader *result = NULL;
+   
+   return result;
+}
+
+ossimNitfTextHeader*
+ossimNitfFileHeaderV2_1::getNewTextHeader(long textNumber,
+                                          std::istream& in)const
+{
+   // Currently not implemented...
+   ossimNitfTextHeader *result = NULL;
+   
+   return result;
+}
+
+ossimNitfDataExtensionSegment*
+ossimNitfFileHeaderV2_1::getNewDataExtensionSegment(long dataExtNumber,
+                                                    std::istream& in)const
+{
+   // Currently not implemented...
+   ossimNitfDataExtensionSegment *result = NULL;
+   
+   return result;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getComplexityLevel()const
+{
+   return theComplexityLevel;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getSystemType()const
+{
+   return theSystemType;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getOriginatingStationId()const
+{
+   return theOriginatingStationId;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getDate()const
+{
+   return theDateTime;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getTitle()const
+{
+   return theFileTitle;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getSecurityClassification()const
+{
+   return theSecurityClassification;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getSecurityClassificationSys()const
+{
+   return theSecurityClassificationSys;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getCodeWords()const
+{
+   return theCodewords;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getControlAndHandling()const
+{
+   return theControlAndHandling;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getReleasingInstructions()const
+{
+   return theReleasingInstructions;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getDeclassificationType()const
+{
+   return theDeclassificationType;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getDeclassificationDate()const
+{
+   return theDeclassificationDate;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getDeclassificationExemption()const
+{
+   return theDeclassificationExemption;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getDowngrade()const
+{
+   return theDowngrade;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getDowngradingDate()const
+{
+   return theDowngradingDate;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getClassificationText()const
+{
+   return theClassificationText;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getClassificationAuthorityType()const
+{
+   return theClassificationAuthorityType;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getClassificationAuthority()const
+{
+   return theClassificationAuthority;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getClassificationReason()const
+{
+   return theClassificationReason;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getSecuritySourceDate()const
+{
+   return theSecuritySourceDate;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getSecurityControlNumber()const
+{
+   return theSecurityControlNumber;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getCopyNumber()const
+{
+   return theCopyNumber;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getNumberOfCopies()const
+{
+   return theNumberOfCopies;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getEncryption()const
+{
+   return theEncryption;
+}
+
+void ossimNitfFileHeaderV2_1::getBackgroundColor(ossim_uint8& r,
+                                                 ossim_uint8& g,
+                                                 ossim_uint8& b)const
+{
+   r = theFileBackgroundColor[0];
+   g = theFileBackgroundColor[1];
+   b = theFileBackgroundColor[2];
+}
+
+ossimString ossimNitfFileHeaderV2_1::getOriginatorsName()const
+{
+   return theOriginatorsName;
+}
+
+ossimString ossimNitfFileHeaderV2_1::getOriginatorsPhone()const
+{
+   return theOriginatorsPhone;
+}
+
+void ossimNitfFileHeaderV2_1::setFileLength(ossim_uint64 fileLength)
+{
+   ostringstream out;
+
+   out << std::setw(12)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << fileLength;
+
+   memcpy(theFileLength, out.str().c_str(), 12);
+}
+
+void ossimNitfFileHeaderV2_1::setNumberOfImageInfoRecords(ossim_uint64 num)
+   throw(std::out_of_range)
+{
+   if (num < 1000)
+   {
+      ostringstream out;
+      
+      out << std::setw(3)
+          << std::setfill('0')
+          << std::setiosflags(ios::right)
+          << num;
+      
+      memcpy(theNumberOfImageInfoRecords, out.str().c_str(), 3);
+   }
+   else
+   {
+      std::string s = "ossimNitfFileHeaderV2_1::setNumberOfImageInfoRecords:";
+      s += " ERROR\nExceeded max image info number of 999!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::setHeaderLength(ossim_uint64 headerLength)
+{
+   ostringstream out;
+
+   out << std::setw(6)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << headerLength;
+
+   memcpy(theHeaderLength, out.str().c_str(), 6);
+}
+
+void ossimNitfFileHeaderV2_1::setComplexityLevel(const ossimString& level)
+{
+   std::ostringstream out;
+
+   out << std::setw(2)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << level.c_str();
+
+   memcpy(theComplexityLevel, out.str().c_str(), 2);
+}
+
+void ossimNitfFileHeaderV2_1::setSystemType(const ossimString& systemType)
+{
+   std::ostringstream out;
+
+   out << std::setw(4)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << systemType.c_str();
+
+   memcpy(theSystemType, out.str().c_str(), 4);
+}
+
+void ossimNitfFileHeaderV2_1::setOriginatingStationId(const ossimString& originationId)
+{
+   std::ostringstream out;
+   
+   out << std::setw(10)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << ossimString(originationId).trim();
+
+   memcpy(theOriginatingStationId, out.str().c_str(), 10);
+}
+
+void ossimNitfFileHeaderV2_1::setDate(const ossimLocalTm& d)
+{
+   memcpy(theDateTime, formatDate(d).c_str(), 14);
+}
+
+void ossimNitfFileHeaderV2_1::setDate(const ossimString& d)
+{
+   if(d.size()==14)
+   {
+      memcpy(theDateTime, d.c_str(), 14);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::setTitle(const ossimString& title)
+{
+   std::ostringstream out;
+   
+   out << std::setw(80)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << ossimString(title).trim();
+
+   memcpy(theFileTitle, out.str().c_str(), 80);
+}
+
+void ossimNitfFileHeaderV2_1::setFileSecurityClassification(const ossimString& securityClassification)
+{
+   std::ostringstream out;
+   
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << ossimString(securityClassification).trim();
+
+   memcpy(theSecurityClassification, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setSecurityClassificationSys(const ossimString& value)
+{
+   std::ostringstream out;
+   
+   out << std::setw(2)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << ossimString(value).trim();
+
+   memcpy(theSecurityClassificationSys, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setCodeWords(const ossimString& codeWords)
+{
+   std::ostringstream out;
+   
+   out << std::setw(11)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << ossimString(codeWords).trim();
+
+   memcpy(theCodewords, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setControlAndHandling(const ossimString& controlAndHandling)
+{
+   std::ostringstream out;
+   
+   out << std::setw(2)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << ossimString(controlAndHandling).trim();
+
+   memcpy(theControlAndHandling, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setReleasingInstructions(const ossimString& releasingInstructions)
+{
+   std::ostringstream out;
+   
+   out << std::setw(2)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << ossimString(releasingInstructions).trim();
+
+   memcpy(theReleasingInstructions, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setDeclassificationType(const ossimString& declassType)
+{
+   std::ostringstream out;
+   
+   out << std::setw(2)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << declassType.trim();
+
+   memcpy(theDeclassificationType, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setDeclassificationDate(const ossimLocalTm& d)
+{
+   memcpy(theDeclassificationDate, formatDate(d).c_str(), 8);
+}
+
+void ossimNitfFileHeaderV2_1::setDeclassificationDate(const ossimString& d)
+{
+   if(d.size() >=8)
+   {
+      memcpy(theDeclassificationDate, d.c_str(), 8);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::setDeclassificationExemption(const ossimString& exemption)
+{
+   std::ostringstream out;
+   
+   out << std::setw(4)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << exemption.trim();
+
+   memcpy(theDeclassificationExemption, out.str().c_str(), 4);
+}
+
+void ossimNitfFileHeaderV2_1::setDowngrade(const ossimString& downgrade)
+{
+   std::ostringstream out;
+   
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << downgrade.trim();
+
+   memcpy(theDowngrade, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setDowngradingDate(const ossimLocalTm& d)
+{
+   memcpy(theDowngradingDate, formatDate(d).c_str(), 8);
+}
+
+void ossimNitfFileHeaderV2_1::setDowngradingDate(const ossimString& d)
+{
+   if(d.size() >=8)
+   {
+      memcpy(theDowngradingDate, d.c_str(), 8);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::setClassificationText(const ossimString& classificationText)
+{
+   std::ostringstream out;
+   
+   out << std::setw(43)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << classificationText.trim();
+
+   memcpy(theClassificationText, out.str().c_str(), 43);
+}
+
+void ossimNitfFileHeaderV2_1::setClassificationAuthorityType(const ossimString& authorityType)
+{
+   std::ostringstream out;
+   
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << authorityType.trim();
+
+   memcpy(theClassificationAuthorityType, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setClassificationAuthority(const ossimString& authority)
+{
+   std::ostringstream out;
+   
+   out << std::setw(40)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << authority.trim();
+
+   memcpy(theClassificationAuthority, out.str().c_str(), 40);
+}
+
+void ossimNitfFileHeaderV2_1::setClassificationReason(const ossimString& reason)
+{
+   std::ostringstream out;
+   
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << reason.trim();
+
+   memcpy(theClassificationReason, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setSecuritySourceDate(const ossimLocalTm& d)
+{
+   memcpy(theSecuritySourceDate, formatDate(d).c_str(), 8);
+}
+
+void ossimNitfFileHeaderV2_1::setSecuritySourceDate(const ossimString& d)
+{
+   if(d.size() >=8)
+   {
+      memcpy(theSecuritySourceDate, d.c_str(), 8);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::setSecurityControlNumber(const ossimString& number)
+{
+   std::ostringstream out;
+   
+   out << std::setw(15)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << number.trim();
+
+   memcpy(theSecurityControlNumber, out.str().c_str(), 15);
+}
+
+void ossimNitfFileHeaderV2_1::setCopyNumber(const ossimString& copyNumber)
+{
+   if(copyNumber.trim() == "")
+   {
+      memset(theCopyNumber, ' ', 5);
+   }
+   else
+   {
+      std::ostringstream out;
+      
+      out << std::setw(5)
+          << std::setfill('0')
+	  << std::setiosflags(ios::right)
+          << copyNumber.trim();
+      
+      memcpy(theCopyNumber, out.str().c_str(), 5);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::setNumberOfCopies(const ossimString& numberOfCopies)
+{
+   if(numberOfCopies.trim() == "")
+   {
+      memset(theNumberOfCopies, ' ', 5);
+   }
+   else
+   {
+      std::ostringstream out;
+      
+      out << std::setw(5)
+          << std::setfill('0')
+	  << std::setiosflags(ios::right)
+          << numberOfCopies.trim();
+      
+      memcpy(theNumberOfCopies, out.str().c_str(), 5);
+   }
+}
+
+void ossimNitfFileHeaderV2_1::setEncryption(const ossimString& encryption)
+{
+   std::ostringstream out;
+   
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << encryption.trim();
+   
+   memcpy(theEncryption, out.str().c_str(), 1);
+}
+
+void ossimNitfFileHeaderV2_1::setFileBackgroundColor(ossim_uint8 r,
+                                                     ossim_uint8 g,
+                                                     ossim_uint8 b)
+{
+   theFileBackgroundColor[0] = r;
+   theFileBackgroundColor[1] = g;
+   theFileBackgroundColor[2] = b;
+}
+
+void ossimNitfFileHeaderV2_1::setOriginatorsName(const ossimString& name)
+{
+   std::ostringstream out;
+   
+   out << std::setw(24)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << name.trim();
+   
+   memcpy(theOriginatorsName, out.str().c_str(), 24);
+}
+
+void ossimNitfFileHeaderV2_1::setOriginatorsPhone(const ossimString& phone)
+{
+   std::ostringstream out;
+   
+   out << std::setw(18)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << phone.trim();
+   
+   memcpy(theOriginatorsPhone, out.str().c_str(), 18);
+}
+
+ossimString ossimNitfFileHeaderV2_1::formatDate(const ossimLocalTm& d)
+{
+   ostringstream out;
+
+   out << std::setw(4)
+       << std::setfill('0')
+       << d.getYear()
+       << std::setw(2)
+       << std::setfill('0')
+       << d.getMonth()
+       << std::setw(2)
+       << std::setfill('0')
+       << d.getDay()
+       << std::setw(2)
+       << std::setfill('0')
+       << d.getHour()
+       << std::setw(2)
+       << std::setfill('0')
+       << d.getMin()
+       << std::setw(2)
+       << std::setfill('0')
+       << d.getSec();
+   
+   return out.str();
+}
+
+void ossimNitfFileHeaderV2_1::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   if(!property.valid()) return;
+   
+   ossimString name = property->getName();
+   if(name == "clevel")
+   {
+      setComplexityLevel(property->valueToString());
+   }
+   else if(name == STYPE_KW)
+   {
+      setSystemType(property->valueToString());
+   }
+   else if(name == OSTAID_KW)
+   {
+      setOriginatingStationId(property->valueToString());
+   }
+   else if(name == FDT_KW)
+   {
+      setDate(property->valueToString());
+   }
+   else if(name == FTITLE_KW)
+   {
+      setTitle(property->valueToString());
+   }
+   else if(name == FSCLAS_KW)
+   {
+      setFileSecurityClassification(property->valueToString());
+   }
+   else if(name == FSCLASY_KW)
+   {
+     setSecurityClassificationSys(property->valueToString()); 
+   }
+   else if(name == FSCODE_KW)
+   {
+     setCodeWords(property->valueToString()); 
+   }
+   else if(name == FSCTLH_KW)
+   {
+      setControlAndHandling(property->valueToString());
+   }
+   else if(name == FSREL_KW)
+   {
+      setReleasingInstructions(property->valueToString());
+   }
+   else if(name == FSDCTP_KW)
+   {
+      setDeclassificationType(property->valueToString());
+   }
+   else if(name == FSDCDT_KW)
+   {
+      setDeclassificationDate(property->valueToString());
+   }
+   else if(name == FSDCXM_KW)
+   {
+      setDeclassificationExemption(property->valueToString());
+   }
+   else if(name == FSDG_KW)
+   {
+      setDowngrade(property->valueToString());
+   }
+   else if(name == FSDGDT_KW)
+   {
+      setDowngradingDate(property->valueToString());
+   }
+   else if(name == FSCLTX_KW)
+   {
+      setClassificationText(property->valueToString());
+   }
+   else if(name == FSCATP_KW)
+   {
+      setClassificationAuthorityType(property->valueToString());
+   }
+   else if(name == FSCAUT_KW)
+   {
+      setClassificationAuthority(property->valueToString()); 
+   }
+   else if(name == FSCRSN_KW)
+   {
+      setClassificationReason(property->valueToString());
+   }
+   else if(name == FSSRDT_KW)
+   {
+      setSecuritySourceDate(property->valueToString());
+   }
+   else if(name == FSCTLN_KW)
+   {
+      setSecurityControlNumber(property->valueToString());
+   }
+   else if(name == FSCOP_KW)
+   {
+      setCopyNumber(property->valueToString());
+   }
+   else if(name == FSCPYS_KW)
+   {
+      setNumberOfCopies(property->valueToString());
+   }
+   else if(name == ENCRYP_KW)
+   {
+      setEncryption(property->valueToString());
+   }
+   else if(name == FBKGC_KW)
+   {
+      ossimString value = property->valueToString();
+      istringstream in(value);
+      ossim_uint8 r, g, b;
+
+      in >> r >> g >> b;
+      
+      setFileBackgroundColor(r, g, b);
+   }
+   else if(name == ONAME_KW)
+   {
+      setOriginatorsName(property->valueToString());
+   }
+   else if(name == OPHONE_KW)
+   {
+      setOriginatorsPhone(property->valueToString());
+   }
+   else
+   {
+      ossimNitfFileHeader::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimNitfFileHeaderV2_1::getProperty(const ossimString& name)const
+{
+   ossimProperty* property = NULL;
+   ossimStringProperty* stringProperty = NULL;
+   ossimColorProperty* colorProperty = NULL;
+   
+   if(name == CLEVEL_KW)
+   {
+      ossimNumericProperty* numericProperty = new ossimNumericProperty(name,
+                                                                       getComplexityLevel(),
+                                                                       1, 99);
+      numericProperty->setNumericType(ossimNumericProperty::ossimNumericPropertyType_INT);
+      property = numericProperty;
+      
+   }
+   else if(name == STYPE_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getSystemType().trim());
+   }
+   else if(name == OSTAID_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getOriginatingStationId().trim());
+   }
+   else if(name == FDT_KW)
+   {
+      property = new ossimDateProperty(name,
+                                        getDate());
+   }
+   else if(name == FTITLE_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getTitle().trim());
+   }
+   else if(name == FSCLAS_KW)
+   {
+      stringProperty = new ossimStringProperty(name,
+                                               getSecurityClassification().trim(),
+                                               false);
+      
+      stringProperty->addConstraint("");
+      stringProperty->addConstraint("T");
+      stringProperty->addConstraint("S");
+      stringProperty->addConstraint("C");
+      stringProperty->addConstraint("R");
+      stringProperty->addConstraint("U");
+      
+      property = stringProperty;
+   }
+   else if(name == FSCLASY_KW)
+   {
+      stringProperty = new ossimStringProperty(name,
+                                               getSecurityClassificationSys().trim());
+   }
+   else if(name == FSCODE_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getCodeWords().trim());
+   }
+   else if(name == FSCTLH_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getControlAndHandling().trim());
+   }
+   else if(name == FSREL_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getReleasingInstructions().trim());
+   }
+   else if(name == FSDCTP_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getDeclassificationType().trim());
+   }
+   else if(name == FSDCDT_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getDeclassificationDate().trim());
+   }
+   else if(name == FSDCXM_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getDeclassificationExemption().trim());
+   }
+   else if(name == FSDG_KW)
+   {
+      stringProperty = new ossimStringProperty(name,
+                                               getDowngrade().trim(),
+                                               false);
+      
+      stringProperty->addConstraint("");
+      stringProperty->addConstraint("S");
+      stringProperty->addConstraint("C");
+      stringProperty->addConstraint("R");
+
+      property = stringProperty;
+   }
+   else if(name == FSDGDT_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getDowngradingDate().trim());
+   }
+   else if(name == FSCLTX_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getClassificationText().trim());
+   }
+   else if(name == FSCATP_KW)
+   {
+      stringProperty = new ossimStringProperty(name,
+                                               getClassificationAuthorityType().trim(),
+                                               false);
+      
+      stringProperty->addConstraint("");
+      stringProperty->addConstraint("O");
+      stringProperty->addConstraint("D");
+      stringProperty->addConstraint("M");
+      
+      property = stringProperty;
+   }
+   else if(name == FSCAUT_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getClassificationAuthority().trim());
+   }
+   else if(name == FSCRSN_KW)
+   {
+      stringProperty = new ossimStringProperty(name,
+                                               getClassificationReason().trim(),
+                                               false);
+      
+      stringProperty->addConstraint("");
+      stringProperty->addConstraint("A");
+      stringProperty->addConstraint("B");
+      stringProperty->addConstraint("C");
+      stringProperty->addConstraint("D");
+      stringProperty->addConstraint("E");
+      stringProperty->addConstraint("F");
+      stringProperty->addConstraint("G");
+      
+      property = stringProperty;
+   }
+   else if(name == FSSRDT_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getSecuritySourceDate().trim());
+   }
+   else if(name == FSCTLN_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getSecurityControlNumber().trim());
+
+   }
+   else if(name == FSCOP_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getCopyNumber().trim());
+   }
+   else if(name == FSCPYS_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getNumberOfCopies().trim());
+   }
+   else if(name == ENCRYP_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         getEncryption().trim(),
+                                         false);
+   }
+   else if(name == FBKGC_KW)
+   {
+      ossim_uint8 r, g, b;
+      getBackgroundColor(r, g, b);
+      
+      colorProperty = new ossimColorProperty(name,
+                                             ossimRgbVector(r, g, b));
+
+      property = colorProperty;
+   }
+   else
+   {
+      return ossimNitfFileHeader::getProperty(name);
+   }
+   return property;
+}
+
+void ossimNitfFileHeaderV2_1::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   ossimNitfFileHeader::getPropertyNames(propertyNames);
+
+   propertyNames.push_back(CLEVEL_KW);
+   propertyNames.push_back(STYPE_KW);
+   propertyNames.push_back(OSTAID_KW);
+   propertyNames.push_back(FDT_KW);
+   propertyNames.push_back(FTITLE_KW);
+   propertyNames.push_back(FSCLAS_KW);
+   propertyNames.push_back(FSCLASY_KW);
+   propertyNames.push_back(FSCODE_KW);
+   propertyNames.push_back(FSCTLH_KW);
+   propertyNames.push_back(FSREL_KW);
+   propertyNames.push_back(FSDCTP_KW);
+   propertyNames.push_back(FSDCDT_KW);
+   propertyNames.push_back(FSDCXM_KW);
+   propertyNames.push_back(FSDG_KW);
+   propertyNames.push_back(FSDGDT_KW);
+   propertyNames.push_back(FSCLTX_KW);
+   propertyNames.push_back(FSCATP_KW);
+   propertyNames.push_back(FSCAUT_KW);
+   propertyNames.push_back(FSCRSN_KW);
+   propertyNames.push_back(FSSRDT_KW);
+   propertyNames.push_back(FSCTLN_KW);
+   propertyNames.push_back(FSCOP_KW);
+   propertyNames.push_back(FSCPYS_KW);
+   propertyNames.push_back(ENCRYP_KW);
+   propertyNames.push_back(FBKGC_KW);
+   propertyNames.push_back(ONAME_KW);
+   propertyNames.push_back(OPHONE_KW);
+}
+
+bool ossimNitfFileHeaderV2_1::setDefaults(const ossimKeywordlist& kwl,
+                                           const char* prefix)
+{
+#if 0	
+   const char* complexityLevel             = kwl.find(prefix, CLEVEL_KW);
+   const char* systemType                  = kwl.find(prefix, STYPE_KW);
+   const char* originatingStationId        = kwl.find(prefix, OSTAID_KW);
+   const char* dateTime                    = kwl.find(prefix, FDT_KW);
+   const char* title                       = kwl.find(prefix, FTITLE_KW);
+   const char* securityClassification      = kwl.find(prefix, FSCLAS_KW);
+   const char* securityClassificationSys   = kwl.find(prefix, FSCLASY_KW);
+   const char* codeWords                   = kwl.find(prefix, FSCODE_KW);
+   const char* controlAndHandling          = kwl.find(prefix, FSCTLH_KW);
+   const char* releasingInstructions       = kwl.find(prefix, FSREL_KW);
+   const char* declassificationType        = kwl.find(prefix, FSDCTP_KW);
+   const char* declassificationDate        = kwl.find(prefix, FSDCDT_KW);
+   const char* declassificationExemption   = kwl.find(prefix, FSDCXM_KW);
+   const char* downgrade                   = kwl.find(prefix, FSDG_KW);
+   const char* downgradingDate             = kwl.find(prefix, FSDGDT_KW);
+   const char* classificationText          = kwl.find(prefix, FSCLTX_KW);
+   const char* classificationAuthorityType = kwl.find(prefix, FSCATP_KW);
+   const char* classificationAuthority     = kwl.find(prefix, FSCAUT_KW);
+   const char* classificationReason        = kwl.find(prefix, FSCRSN_KW);
+   const char* securitySourceDate          = kwl.find(prefix, FSSRDT_KW);
+   const char* securityControlNumber       = kwl.find(prefix, FSCTLN_KW);
+   const char* copyNumber                  = kwl.find(prefix, FSCOP_KW);
+   const char* numberOfCopies              = kwl.find(prefix, FSCPYS_KW);
+   const char* encryption                  = kwl.find(prefix, ENCRYP_KW);
+   const char* fileBackgroundColor         = kwl.find(prefix, FBKGC_KW);
+   const char* originatorsName             = kwl.find(prefix, ONAME_KW);
+   const char* originatorsPhone            = kwl.find(prefix, OPHONE_KW);
+   if(complexityLevel)
+   {
+      setComplexityLevel(complexityLevel);
+   }
+#endif
+   return true;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_1.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_1.h
new file mode 100644
index 0000000000..bd1fab5a8c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfFileHeaderV2_1.h
@@ -0,0 +1,678 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level directory for more details.
+//
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfFileHeaderV2_1.h,v 1.14 2005/11/17 18:05:59 dburken Exp $
+#ifndef ossimNitfFileHeaderV2_1_HEADER
+#define ossimNitfFileHeaderV2_1_HEADER
+
+#include <stdexcept>
+
+#include <support_data/nitf/ossimNitfFileHeader.h>
+#include <base/common/ossimDate.h>
+#include <base/data_types/ossimKeywordlist.h>
+
+class OSSIMDLLEXPORT ossimNitfImageInfoRecordV2_1
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out,
+                                    const ossimNitfImageInfoRecordV2_1 &data);
+   
+   long getHeaderLength()const{return ossimString(theImageSubheaderLength).toLong();}
+   long getImageLength()const{return ossimString(theImageLength).toLong();}
+   long getTotalLength()const{return (getHeaderLength() + getImageLength()); }
+   
+   void setSubheaderLength(ossim_uint32 length);
+   void setImageLength(ossim_uint32 length);
+   
+   /**
+    * Is a 6 byte numeric 000439-999999
+    */
+   char theImageSubheaderLength[7];
+   
+   /**
+    * Is a 10 byte numeric 0000000001-9999999999
+    */
+   char theImageLength[11];
+};
+
+
+struct ossimNitfGraphicInfoRecordV2_1
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out,
+                                    const ossimNitfGraphicInfoRecordV2_1 &data);
+   
+   /**
+    * Is a 4 byte numeric 0258-9999
+    */
+   char theGraphicSubheaderLength[5];
+   
+   /**
+    * Is a 6 byte numeric 0000001-9999999
+    */
+   char theGraphicLength[7];
+};
+
+
+struct ossimNitfTextFileInfoRecordV2_1
+{
+public:
+   friend std::ostream& operator<<(std::ostream& out,
+                                   const ossimNitfTextFileInfoRecordV2_1 &data);
+
+   /**
+    * Is a 4 byte numeric 0282-9999
+    */
+   char theTextFileSubheaderLength[5];
+
+   /**
+    * Is a 5 byte numeric 0-99999
+    */
+   char theTextFileLength[6];
+};
+
+struct ossimNitfDataExtSegInfoRecordV2_1
+{
+public:
+   friend std::ostream& operator<<(std::ostream& out,
+                                   const ossimNitfDataExtSegInfoRecordV2_1 &data);
+
+   /**
+    * Is a 4 byte numeric 200-9999
+    */
+   char theDataExtSegSubheaderLength[5];
+
+   /**
+    * Is a 9 byte numeric 0-999999999
+    */
+   char theDataExtSegLength[10];
+};
+
+struct ossimNitfResExtSegInfoRecordV2_1
+{
+public:
+   friend std::ostream& operator<<(std::ostream& out,
+                                   const ossimNitfResExtSegInfoRecordV2_1 &data);
+
+   /**
+    * Is a 4 byte numeric 0-9999
+    */
+   char theResExtSegSubheaderLength[5];
+
+   /**
+    * Is a 7 byte numeric 0-9999999
+    */
+   char theResExtSegLength[8];
+};
+
+class OSSIMDLLEXPORT ossimNitfFileHeaderV2_1 : public ossimNitfFileHeader
+{
+public:
+   
+   ossimNitfFileHeaderV2_1();
+   virtual ~ossimNitfFileHeaderV2_1();
+   virtual void parseStream(std::istream &in);
+   virtual void writeStream(std::ostream &out);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual bool isEncrypted()const;
+   virtual long getNumberOfImages()const;
+   virtual long getNumberOfLabels()const;
+   virtual long getNumberOfSymbols()const;
+   virtual long getNumberOfGraphics()const;
+   virtual long getNumberOfTextSegments()const;
+   virtual long getNumberOfDataExtSegments()const;
+   virtual long getHeaderSize()const;
+   virtual long getFileSize()const;
+   virtual const char* getVersion()const;
+   virtual const char* getDateTime()const;
+   virtual ossimDrect getImageRect()const;
+
+   virtual void addImageInfoRecord(const ossimNitfImageInfoRecordV2_1& recordInfo);
+   virtual void replaceImageInfoRecord(int i, const ossimNitfImageInfoRecordV2_1& recordInfo);
+   
+   virtual ossimNitfImageHeader*  getNewImageHeader(long imageNumber,
+                                                    std::istream& in)const;
+   virtual ossimNitfSymbolHeader* getNewSymbolHeader(long symbolNumber,
+                                                     std::istream& in)const;
+   virtual ossimNitfLabelHeader* getNewLabelHeader(long labelNumber,
+                                                   std::istream& in)const;
+   virtual ossimNitfTextHeader* getNewTextHeader(long textNumber,
+                                                   std::istream& in)const;
+   virtual ossimNitfDataExtensionSegment*
+      getNewDataExtensionSegment(long dataExtNumber, std::istream& in)const;
+
+   virtual ossimNitfImageHeader*  allocateImageHeader()const;
+   virtual ossimNitfSymbolHeader* allocateSymbolHeader()const;
+   virtual ossimNitfLabelHeader*  allocateLabelHeader()const;
+   virtual ossimNitfTextHeader*   allocateTextHeader()const;
+   virtual ossimNitfDataExtensionSegment *allocateDataExtSegment()const;
+
+   virtual ossimString getComplexityLevel()const;
+   virtual ossimString getSystemType()const;
+   virtual ossimString getOriginatingStationId()const;
+   virtual ossimString getDate()const;
+   virtual ossimString getTitle()const;
+   virtual ossimString getSecurityClassification()const;
+   virtual ossimString getSecurityClassificationSys()const;
+   virtual ossimString getCodeWords()const;
+   virtual ossimString getControlAndHandling()const;
+   virtual ossimString getReleasingInstructions()const;
+   virtual ossimString getDeclassificationType()const;
+   virtual ossimString getDeclassificationDate()const;
+   virtual ossimString getDeclassificationExemption()const;
+   virtual ossimString getDowngrade()const;
+   virtual ossimString getDowngradingDate()const;
+   virtual ossimString getClassificationText()const;
+   virtual ossimString getClassificationAuthorityType()const;
+   virtual ossimString getClassificationAuthority()const;
+   virtual ossimString getClassificationReason()const;
+   virtual ossimString getSecuritySourceDate()const;
+   virtual ossimString getSecurityControlNumber()const;
+   virtual ossimString getCopyNumber()const;
+   virtual ossimString getNumberOfCopies()const;
+   virtual ossimString getEncryption()const;
+   virtual void getBackgroundColor(ossim_uint8& r,
+                                   ossim_uint8& g,
+                                   ossim_uint8& b)const;
+   virtual ossimString getOriginatorsName()const;
+   virtual ossimString getOriginatorsPhone()const;
+   
+   virtual void setFileLength(ossim_uint64 fileLength);
+   virtual void setHeaderLength(ossim_uint64 headerLength);
+   
+   virtual void setComplexityLevel(const ossimString& level);
+   virtual void setSystemType(const ossimString& systemType);
+   virtual void setOriginatingStationId(const ossimString& originationId);
+   virtual void setDate(const ossimLocalTm& date);
+   virtual void setDate(const ossimString& date);
+   virtual void setTitle(const ossimString& title);
+   virtual void setFileSecurityClassification(const ossimString& securityClassification);
+   virtual void setSecurityClassificationSys(const ossimString& value);
+   virtual void setCodeWords(const ossimString& codeWords);
+   virtual void setControlAndHandling(const ossimString& controlAndHandling);
+   virtual void setReleasingInstructions(const ossimString& releasingInstructions);
+   virtual void setDeclassificationType(const ossimString& declassType);
+   virtual void setDeclassificationDate(const ossimLocalTm& declassDate);
+   virtual void setDeclassificationDate(const ossimString& declassDate);
+   virtual void setDeclassificationExemption(const ossimString& exemption);
+   virtual void setDowngrade(const ossimString& downgrade);
+   virtual void setDowngradingDate(const ossimLocalTm& date);
+   virtual void setDowngradingDate(const ossimString& date);
+   virtual void setClassificationText(const ossimString& classificationText);
+   virtual void setClassificationAuthorityType(const ossimString& authorityType);
+   virtual void setClassificationAuthority(const ossimString& authorityType);
+   virtual void setClassificationReason(const ossimString& reason);
+   virtual void setSecuritySourceDate(const ossimLocalTm& date);
+   virtual void setSecuritySourceDate(const ossimString& date);
+   virtual void setSecurityControlNumber(const ossimString& number);
+   virtual void setCopyNumber(const ossimString& copyNumber);
+   virtual void setNumberOfCopies(const ossimString& numberOfCopies);
+   virtual void setEncryption(const ossimString& encryption);
+   virtual void setFileBackgroundColor(ossim_uint8 r,
+                                       ossim_uint8 g,
+                                       ossim_uint8 b);
+   virtual void setOriginatorsName(const ossimString& name);
+   virtual void setOriginatorsPhone(const ossimString& phone);
+   
+   virtual bool setDefaults(const ossimKeywordlist& kwl,
+                             const char* prefix=0);
+   
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   
+   void clearFields();
+   
+private:
+   void setNumberOfImageInfoRecords(ossim_uint64 num) throw(std::out_of_range);
+
+   void readImageInfoRecords(std::istream &in);
+   void readGraphicInfoRecords(std::istream &in);
+   void readTextFileInfoRecords(std::istream &in);
+   void readDataExtSegInfoRecords(std::istream &in);
+   void readResExtSegInfoRecords(std::istream &in);
+   static ossimString formatDate(const ossimLocalTm& d);
+   /**
+    * If the header was parsed this method will initialize the offsets
+    * to whare all data resides within the file.  Example:  NITF files
+    * have several sections (Image, Symbol, Labels, Text and Extended data) and
+    * each of these sections have subsections.  The offsets stored are just offsets
+    * from the start of the file to each major section and eqach subsection.
+    */
+   void initializeAllOffsets();
+   
+   // Note: these are work variables and not part of the
+   // Nitf header.  These variables will be used to quickly
+   // access various parts of the file.
+   /**
+    * This is not part of the NITF file header.  This will be
+    * computed since somethimes the header size will not be
+    * given in the header field.  This value will hold a count of
+    * all the bytes read for the header portion.  This can be used
+    * to skip past the header data.
+    */
+   long theHeaderSize;
+
+   /**
+    * This will be pre-computed when the header file is opened.  This is
+    * computed after we have found the display order.  We will use the
+    * rectangle of the smallest display number.
+    */
+   ossimDrect theImageRect;
+   
+   /**
+    * This will hold pre-computed offsets to the start of all image headers
+    * and start to their data.
+    */
+   vector<ossimNitfImageOffsetInformation>  theImageOffsetList;
+   
+   // START Of header variables
+
+   /**
+    * Field: FHDR
+    * Required field for NITF and is a 9 byte value
+    *
+    * format is NITFNN.NN where NN.NN is the version
+    * number. The valid version number for this class
+    * is NITF02.10.
+    *
+    * NOTE: This field may contain NSIF01.00 which is also the same as NITF02.10
+    * 
+    */
+   char  theFileTypeVersion[10]; // nine bytes
+
+   /**
+    * Field: CLEVEL
+    * 
+    * Required field. 2 byte field ranges from 01-99
+    */
+   char  theComplexityLevel[3];  // 2 bytes
+
+   /**
+    * Field: STYPE
+    * 
+    * Required field. 4 bytes
+    */
+   char  theSystemType[5];      // four bytes
+
+   /**
+    * Field: OSTAID
+    * 
+    * Is required 10 byte field and can't be blank
+    * 
+    */
+   char  theOriginatingStationId[11]; // ten bytes
+
+   /**
+    * Field: FDT
+    * 
+    * Has the form CCYYMMDDhhmmss and is a required field
+    *
+    * where CC is the first two digits of the year 00-99
+    *       YY is the last 2 digits of the year 00-99
+    *       MM is the month 01-12
+    *       DD is the day 01-31
+    *       hh is the hour 00-23
+    *       mm is the minutes 00-59
+    *       ss is the seconds 00-59
+    */
+   char  theDateTime[15];  // 14 bytes
+
+   /**
+    * Field: FTITLE
+    * 
+    * Is a required field and is an 80 byte
+    * Alphanumeric value this can be all BCS spaces.
+    */
+   char  theFileTitle[81]; // 80 bytes
+
+   /**
+    * Field: FSCLAS
+    * 
+    * This is a reqired field and is 1 byte long and
+    * can contain one of the following:
+    *
+    *  T      Top secret
+    *  S      Secret
+    *  C      Confidential
+    *  R      Restricted
+    *  U      Unclassified
+    */
+   char theSecurityClassification[2];
+
+   /**
+    * Field: FSCLASY
+    * 
+    * Is a 2 byte field.  Required but can be blank:
+    *
+    */
+   char theSecurityClassificationSys[3];
+
+   /**
+    * Field: FSCODE
+    * 
+    * This is a 11 byte Alphanumeric field
+    */
+   char theCodewords[12]; 
+
+   /**
+    * Field: FSCTLH
+    * 
+    * This is a 2 byte Alphanumeric field.
+    */
+   char theControlAndHandling[3]; 
+
+   /**
+    * Field: FSREL
+    * 
+    * This is a 20 byte Alphanumeric field.
+    */
+   char theReleasingInstructions[21]; 
+
+   /**
+    * Field: FSDCTP
+    * 
+    * This is a 2 byte alphanumeric field.
+    * 
+    * DD    declassify on a specific date
+    * DE    declassify upon occurrence of an event
+    * GD    downgrade to a specified level on a specific date)
+    * GE    downgrade to a specified level upon occurrence of an event)
+    * O     OADR
+    * X     exempt from automatic declassification
+    *
+    * NOTE: If this field is all BCS spaces (0x20), it shall imply that no
+    *       file security declassification or
+    */ 
+   char theDeclassificationType[3];
+
+   /**
+    * Field: FSDCDT
+    * 
+    * This is a 8 byte field and has the form
+    * CCYYMMDD where:
+    *
+    * CC is the firs 2 chars of the year 00-99
+    * YY is the second 2 chars of the year 00-99
+    * MM is the month 01-12
+    * DD is the day 01-31
+    */
+   char theDeclassificationDate[9]; 
+
+   /**
+    * Field: FSDCXM
+    * 
+    * Is a 4 byte field
+    */
+   char theDeclassificationExemption[5];
+   
+   /**
+    * Field: FSDG
+    * 
+    * Can be blank.  Is a 1 byte field valid
+    * values are:
+    *
+    * S = secret
+    * C = Confidential
+    * R = Restricted
+    * 0x20 or BCS spaces.
+    *
+    * if spaces then security downgrading does not apply.
+    */
+   char theDowngrade[2];
+
+   /**
+    * Field: FSDGDT
+    * 
+    * Is an 8 byte field of the form
+    * CCYYMMDD.
+    */
+   char theDowngradingDate[9];
+
+   /**
+    * Field: FSCLTX
+    * 
+    * Is a 43 byte field and can contain BCS spaces (0x20).
+    */
+   char theClassificationText[44];
+
+   /**
+    * Field: FSCATP
+    *
+    * Values can be:
+    * 
+    * O  Original classification authority
+    * D  derivative from a single source
+    * M  derivative from multiple sources
+    * 
+    * Is a 1 byte field and can contain BCS spaces (0x20).
+    */
+   char theClassificationAuthorityType[2];
+
+   /**
+    * Field: FSCAUT
+    * 
+    * Is a 40 byte field and can contain BCS spaces (0x20).
+    */
+   char theClassificationAuthority[41];
+
+   /**
+    * Field: FSCRSN
+    * 
+    * Is a 1 byte field and can contain BCS spaces (0x20).
+    *
+    * Valid values are A-G
+    */
+   char theClassificationReason[2];
+
+   /**
+    * Field: FSSRDT
+    * 
+    * Is a 8 byte field of the form CCYYMMDD and can be
+    * BCS space (0x20).
+    */
+   char theSecuritySourceDate[9];
+
+   /**
+    * Field: FSCTLN
+    * 
+    * Is a 15 byte field and can be blank (0x20)
+    */
+   char theSecurityControlNumber[16];
+   
+   /**
+    * Field: FSCOP
+    * 
+    * This is the copy number and is a 5 byte
+    * numeric of the form 00000-99999.  This field
+    * is required.
+    */
+   char theCopyNumber[6];
+
+   /**
+    * Field: FSCOPYS
+    * 
+    * This is the total number of copies that exist.
+    * This is a 5 byte numeric of the form 00000-99999.  This
+    * field is required.
+    */
+   char theNumberOfCopies[6];
+
+   /**
+    * Field: ENCRYP
+    * 
+    * This is a reqired field and is a 1 byte numeric
+    * where 0 is not encrypted and 1 is encrypted.  This field
+    * is reuqired.
+    */
+   char theEncryption[2];
+
+   /**
+    * Field: FBKGC
+    * 
+    * Required.  Is a 3 byte field and is reuqired.  Note:  This
+    * field is binary and has range
+    *
+    *      (0x00-0xff, 0x00-0xff, 0x00-0xff)
+    *
+    * each byte can range from 0 to 255 binary
+    */
+   ossim_uint8 theFileBackgroundColor[3];
+   
+   /**
+    * Field: ONAME
+    * 
+    * This is a 24 byte Alphanumeric number
+    */
+   char theOriginatorsName[25];
+
+   /**
+    * Field: OPHONE
+    * 
+    * This is an 18 byte Alphanumeric value. 
+    */
+   char theOriginatorsPhone[19]; 
+
+   /**
+    * Field: FL
+    * 
+    * This is a required field.
+    *
+    * Is a 12 byte number of the form
+    * 000000000388-999999999998 indicates the
+    * file length and a value of 999999999999
+    * indicates that the file length was not
+    * available.
+    */
+   char theFileLength[13];
+
+   /**
+    * Field: HL
+    * 
+    * This is a reqired field.
+    *
+    * ranges from 000388-999999.
+    */
+   char theHeaderLength[7];
+
+   /**
+    * Field: NUMI
+    * 
+    * This is a 3 byte field that specifies the number
+    * of images in the file.  0-999
+    */
+   char theNumberOfImageInfoRecords[4];
+
+   /**
+    * This information is conditional on the number of image
+    * info records field.  If the filed is greater than 0 then
+    * the record information is read in up t the indicated number
+    */
+   vector<ossimNitfImageInfoRecordV2_1> theNitfImageInfoRecords;
+
+   /**
+    * Field: NUMS
+    * 
+    * This info is required and ranges from 000-999.
+    */
+   char theNumberOfGraphicInfoRecords[4];
+
+   /**
+    * This is an optional field and will depend on
+    * theNumberOfGraphicInfoRecords.  If 0 then does not exist.
+    */
+   vector<ossimNitfGraphicInfoRecordV2_1> theNitfGraphicInfoRecords;
+
+   /**
+    * Field: NUMX
+    * 
+    * Is a 3 byte field and is reserved for future use.
+    */
+   char theReservedForFutureUse1[3];
+   
+   /**
+    * Field: NUMT
+    * 
+    * This is a 3 byte numeric 0-999.
+    */
+   char theNumberOfTextFileInfoRecords[4];
+
+   /**
+    * This information is conditional on the number of text file
+    * info records field.  If the filed is greater than 0 then
+    * the record information is read in up t the indicated number
+    */
+   vector<ossimNitfTextFileInfoRecordV2_1> theNitfTextFileInfoRecords;
+
+   /**
+    * Field: NUMDES
+    * 
+    * This is a 3 byte numeric 0-999.
+    */
+   char theNumberOfDataExtSegInfoRecords[4];
+
+   /**
+    * This information is conditional on the number of 
+    * info records field.  If the filed is greater than 0 then
+    * the record information is read in up t the indicated number
+    */
+   vector<ossimNitfDataExtSegInfoRecordV2_1> theNitfDataExtSegInfoRecords;
+
+   /**
+    * Field: NUMRES
+    * 
+    * This is a 3 byte numeric 0-999. Reserved Extension Segments
+    */
+   char theNumberOfResExtSegInfoRecords[4];
+
+   /**
+    * This information is conditional on the number of Res Ext Seg
+    * info records field.  If the filed is greater than 0 then
+    * the record information is read in up t the indicated number
+    */
+   vector<ossimNitfResExtSegInfoRecordV2_1> theNitfResExtSegInfoRecords;
+
+   /**
+    * Field: UDHDL
+    * 
+    * This is a required field and is a 5 byte numeric ranging
+    * from 0-99999.  This is 0 if there is no data.  Valid values
+    * are 00000 or 00003-99999
+    */
+   char theUserDefinedHeaderDataLength[6];
+
+   /**
+    * Field: UDHOFL
+    * 
+    * This exists if theUserDefinedHeaderDataLength is not 0.
+    */
+   char theUserDefinedHeaderOverflow[4];
+
+   /**
+    * Field: XHDL
+    * 
+    * This is a required field.  It is 5 bytes long and
+    * ranges from 0-99999.  0 means there is no data
+    */
+   char theExtendedHeaderDataLength[6];
+
+   /**
+    * Field: XHDLOFL
+    * 
+    * This is conditional on theExtendedHeaderDataLength.  If
+    * that field is 0 then this does not exist.  This is a 3
+    * byte field.
+    */
+   char theExtendedHeaderDataOverflow[4];
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfGeoPositioningTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfGeoPositioningTag.cpp
new file mode 100644
index 0000000000..d3948226f6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfGeoPositioningTag.cpp
@@ -0,0 +1,116 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfGeoPositioningTag.cpp,v 1.3 2004/09/28 19:16:40 gpotts Exp $
+#include <support_data/nitf/ossimNitfGeoPositioningTag.h>
+#include <cstring>
+
+RTTI_DEF1(ossimNitfGeoPositioningTag, "ossimNitfGeoPositioningTag", ossimNitfRegisteredTag);
+
+ossimNitfGeoPositioningTag::ossimNitfGeoPositioningTag()
+      :ossimNitfRegisteredTag()
+{
+   clearFields();
+}
+
+ossimNitfGeoPositioningTag::~ossimNitfGeoPositioningTag()
+{
+}
+
+ossimString ossimNitfGeoPositioningTag::getRegisterTagName()const
+{
+   return "GEOPSB";
+}
+
+void ossimNitfGeoPositioningTag::parseStream(std::istream& in)
+{
+   clearFields();
+   
+   in.read(theType, 3);
+   in.read(theCoordinateUnits, 3);
+   in.read(theGeodeticDatumName, 80);
+   in.read(theGeodeticDatumCode, 4);
+   in.read(theEllipsoidName, 80);
+   in.read(theEllipsoidCode, 3);
+   in.read(theVerticalDatumReference, 80);
+   in.read(theVerticalReferenceCode, 4);
+   in.read(theSoundingDatumName, 80);
+   in.read(theSoundingDatumCode, 4);
+   in.read(theZFalseOrigin, 15);
+   in.read(theGridCode, 3);
+   in.read(theGridDescription, 80);
+   in.read(theGridZoneNumber, 4);
+}
+
+void ossimNitfGeoPositioningTag::writeStream(std::ostream& out)
+{
+   out.write(theType, 3);
+   out.write(theCoordinateUnits, 3);
+   out.write(theGeodeticDatumName, 80);
+   out.write(theGeodeticDatumCode, 4);
+   out.write(theEllipsoidName, 80);
+   out.write(theEllipsoidCode, 3);
+   out.write(theVerticalDatumReference, 80);
+   out.write(theVerticalReferenceCode, 4);
+   out.write(theSoundingDatumName, 80);
+   out.write(theSoundingDatumCode, 4);
+   out.write(theZFalseOrigin, 15);
+   out.write(theGridCode, 3);
+   out.write(theGridDescription, 80);
+   out.write(theGridZoneNumber, 4);
+}
+
+ossim_uint32 ossimNitfGeoPositioningTag::getSizeInBytes()const
+{
+   return 443;
+}
+
+void ossimNitfGeoPositioningTag::clearFields()
+{
+   memset(theType, ' ', 3);
+   memset(theCoordinateUnits, ' ', 3);
+   memset(theGeodeticDatumName, ' ', 80);
+   memset(theGeodeticDatumCode, ' ', 4);
+   memset(theEllipsoidName, ' ', 80);
+   memset(theEllipsoidCode, ' ', 3);
+   memset(theVerticalDatumReference, ' ', 80);
+   memset(theVerticalReferenceCode, ' ', 4);
+   memset(theSoundingDatumName, ' ', 80);
+   memset(theZFalseOrigin, '0', 15);
+   memset(theGridCode, ' ', 3);
+   memset(theGridDescription, ' ', 80);
+   memset(theGridZoneNumber, '0',  4);
+   
+   memcpy(theType, "MAP", 3);
+   memcpy(theCoordinateUnits, "M  ", 3);
+   memcpy(theGeodeticDatumName, "World Geodetic System 1984", 26);
+   memcpy(theGeodeticDatumCode, "WGE", 3);
+   memcpy(theEllipsoidName, "World Geodetic System 1984", 26);
+   memcpy(theEllipsoidCode, "WE", 2);
+   memcpy(theVerticalDatumReference, "Geodetic", 8);
+   memcpy(theVerticalReferenceCode, "GEOD", 4);
+   memcpy(theSoundingDatumName, "Mean Sea", 8);
+
+   theType[3]                    = '\0';
+   theCoordinateUnits[3]         = '\0';
+   theGeodeticDatumName[80]      = '\0';
+   theGeodeticDatumCode[4]       = '\0';
+   theEllipsoidName[80]          = '\0';
+   theEllipsoidCode[3]           = '\0';
+   theVerticalDatumReference[80] = '\0';
+   theVerticalReferenceCode[4]   = '\0';
+   theSoundingDatumName[80]      = '\0';
+   theZFalseOrigin[15]           = '\0';
+   theGridCode[3]                = '\0';
+   theGridDescription[80]        = '\0';
+   theGridZoneNumber[4]          = '\0';
+   
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfGeoPositioningTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfGeoPositioningTag.h
new file mode 100644
index 0000000000..fd2672717d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfGeoPositioningTag.h
@@ -0,0 +1,218 @@
+//********************************************************************
+// Copyright (C) 2004 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author:      Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfGeoPositioningTag.h,v 1.3 2004/09/29 13:47:01 gpotts Exp $
+//
+#ifndef ossimNitfGeoPositioningTag_HEADER
+#define ossimNitfGeoPositioningTag_HEADER
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class OSSIM_DLL ossimNitfGeoPositioningTag : public ossimNitfRegisteredTag
+{
+public:
+   ossimNitfGeoPositioningTag();
+   virtual ~ossimNitfGeoPositioningTag();
+   virtual ossimString getRegisterTagName()const;
+   virtual void parseStream(std::istream& in);
+   virtual void writeStream(std::ostream& out);
+   virtual ossim_uint32 getSizeInBytes()const;
+   virtual void clearFields();
+
+   
+protected:
+   /**
+    * FIELD: TYP
+    *
+    * required 3 byte field.
+    * 
+    * Coordinate System Type
+    *
+    * This field shall contain the type of coordinate system to which the Image
+    * Segment refers.  Valid values are GEO for a geographic coordinate
+    * system (longitude & latitude), MAP for a cartographic (grid)
+    * coordinate system (easting & northing) and DIG for a geographic or
+    * cartographic coordinate system registered through location grids or
+    * registration points.
+    * See clause D1.2.2 for details.
+    * The default value is MAP.
+    *
+    *
+    * Values: MAP, GEO or DIG 
+    */
+   char theType[4];
+
+   /**
+    * FIELD: UNI
+    *
+    * required 3 byte field.
+    *
+    * Coordinate Units This field shall contain the units of measure to which
+    * the Image Segment refers.  Valid values are SEC (Decimal seconds of arc),
+    * DEG (Decimal degrees) and M (Metres).  The value must be consistent with
+    * the coordinate system type.  SEC and DEG are not allowed when the
+    * coordinate system type is MAP.  M is not allowed when the coordinate system
+    * type is GEO.  The PRJPS extension is expected when the value is M.
+    * The default value is M.
+    */
+   char theCoordinateUnits[4];
+
+
+   /**
+    * FIELD: DAG
+    * 
+    * required 80 byte field.
+    * 
+    * Geodetic Datum Name
+    *
+    * This field shall contain the name of the geodetic datum to which the
+    * Image Segment refers.
+    * The default value is World Geodetic System 1984.
+    * 
+    */
+   char theGeodeticDatumName[81];
+
+   /**
+    * FIELD: DCD
+    *
+    * required 4 byte field.
+    * 
+    * Geodetic Datum Code This field shall contain the code of the geodetic
+    * datum to which the Image Segment refers. The default value is WGE.
+    * 
+    */
+   char theGeodeticDatumCode[5];
+
+   /**
+    * FIELD: ELL
+    *
+    * required 80 byte field.
+    *
+    * Ellipsoid Name
+    *
+    * This field shall contain the name of the ellipsoid to which the
+    * Image Segment refers. The default value is World Geodetic System 1984.
+    * 
+    */
+   char theEllipsoidName[81];
+
+   /**
+    * FIELD: ELC
+    *
+    * required 3 byte field.
+    *
+    * Ellipsoid Code This field shall contain the code of the ellipsoid to
+    * which the Image Segment refers.
+    * The default value is WE.
+    * 
+    */
+   char theEllipsoidCode[4];
+
+   /**
+    * FIELD: DVR
+    *
+    * required 80 byte field.
+    *
+    * Vertical Datum Reference This field shall contain the name of the vertical
+    * datum reference to which the Image Segment refers, or BCS Spaces if no elevation value
+    * appears in the Image Segment. The default name is Geodetic. 
+    */
+   char theVerticalDatumReference[81];
+
+   /**
+    * FIELD: VDCDVR
+    *
+    * required 4 byte field.
+    * 
+    * Code (Category) of Vertical Reference This field shall contain the code
+    * (or category) of the vertical reference to which the Image Segment
+    * refers, or BCS Spaces if no elevation value appears in the Image Segment.
+    * The default code is GEOD.
+    * 
+    */
+   char theVerticalReferenceCode[5];
+
+   /**
+    * FIELD: SDA
+    *
+    * required 80 byte field.
+    * 
+    * Sounding Datum Name This field shall contain the name of the sounding datum
+    * to which the Image Segment refers, or BCS Spaces i
+    * f no sounding appears in the Image Segment.
+    * The default value is Mean Sea.
+    */
+   char theSoundingDatumName[81];
+
+   /**
+    * FIELD: VDCSDA
+    *
+    * required 4 byte field.
+    * 
+    * Code for  Sounding Datum This field shall contain the code of the
+    * sounding datum to which the Image Segment refers, or BCS Spaces
+    * if no sounding appears in the Image Segment.
+    * The default valid code is MSL. 4BCS-A See Part 3-6 <R> 
+    */
+   char theSoundingDatumCode[5];
+
+   /**
+    * FIELD ZOR
+    *
+    * required 15 byte field
+    *
+    * Z values False Origin
+    *
+    * This field shall contain the elevation and depth false origin for Z values
+    * to which the Image Segment refers. The default value is 000000000000000,
+    * which implies that there is no projection false Z origin. 15 BCS-N positive integer
+    * 
+    */
+   char theZFalseOrigin[16];
+
+   /**
+    * FIELD: GRD
+    *
+    * required 3 byte field.
+    * 
+    * Grid Code This field shall contain the identification code of the grid system
+    * to which the Image Segment refers, or BCS Spaces. The default value is
+    * BCS Spaces. 3BCS-A See Part 3-6 <R> 
+    */
+   char theGridCode[4];
+
+   /**
+    * FIELD: GRN
+    *
+    * required 80 byte field.
+    *
+    * Grid Description If the GRD Field value is not BCS Spaces, this field can
+    * contain a text description of the grid system.
+    * The default value is BCS Spaces. 80 BCS-A <R> 
+    */
+   char theGridDescription[81];
+
+   /**
+    * FIELD: ZNA
+    *
+    * required 4 byte field.
+    *
+    * Grid Zone number This field shall contain the zone number when the GRD
+    * Field contains a significant grid code and the corresponding grid system
+    * comprises more than one zone. Defaulted to 0000 otherwise.
+    * 4 BCS-N integer See Part 3-6 R 
+    */
+   char theGridZoneNumber[5];
+
+   
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBand.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBand.cpp
new file mode 100644
index 0000000000..2753615ddc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBand.cpp
@@ -0,0 +1,43 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageBand.cpp,v 1.2 2004/11/11 14:23:33 gpotts Exp $
+#include "ossimNitfImageBand.h"
+#include "ossimNitfImageLut.h"
+#include "base/data_types/ossimString.h"
+
+RTTI_DEF1(ossimNitfImageBand, "ossimNitfImageBand", ossimObject);
+ostream& operator <<(ostream& out,
+                     const ossimNitfImageBand &data)
+{
+   data.print(out);
+   return out;
+}
+
+ossimNitfImageBand::ossimNitfImageBand()
+{
+}
+
+ossimNitfImageBand::~ossimNitfImageBand()
+{
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBand.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBand.h
new file mode 100644
index 0000000000..cab0b9045b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBand.h
@@ -0,0 +1,50 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageBand.h,v 1.3 2004/11/11 14:23:33 gpotts Exp $
+#ifndef ossimNitfImageBand_HEADER
+#define ossimNitfImageBand_HEADER
+#include <iostream>
+#include "ossimNitfImageLut.h"
+#include <base/common/ossimObject.h>
+#include <base/common/ossimRefPtr.h>
+
+class ossimNitfImageBand : public ossimObject
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimNitfImageBand &data);
+   ossimNitfImageBand();
+   virtual ~ossimNitfImageBand();
+   virtual void parseStream(std::istream& in)=0;
+   virtual void writeStream(std::ostream& out)=0;
+   
+   virtual std::ostream& print(std::ostream& out)const=0;
+
+   virtual ossim_uint32 getNumberOfLuts()const=0;
+   virtual const ossimRefPtr<ossimNitfImageLut> getLut(ossim_uint32 idx)const=0;
+   virtual ossimRefPtr<ossimNitfImageLut> getLut(ossim_uint32 idx)=0;
+
+TYPE_DATA;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_0.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_0.cpp
new file mode 100644
index 0000000000..6c241ed817
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_0.cpp
@@ -0,0 +1,154 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageBandV2_0.cpp,v 1.5 2005/09/27 19:46:45 dburken Exp $
+#include <support_data/nitf/ossimNitfImageBandV2_0.h>
+#include <base/data_types/ossimString.h>
+
+ossimNitfImageBandV2_0::ossimNitfImageBandV2_0()
+{
+   clearFields();
+}
+
+ossimNitfImageBandV2_0::~ossimNitfImageBandV2_0()
+{
+}
+
+void ossimNitfImageBandV2_0::parseStream(std::istream& in)
+{
+   theLookupTables.clear();
+   if(in)
+   {      
+      theLookupTables.clear();
+      in.read(theBandRepresentation, 2);
+      in.read(theBandSignificance, 6);
+      in.read(theBandImageFilterCondition, 1);
+      in.read(theBandStandardImageFilterCode, 3);
+      in.read(theBandNumberOfLuts, 1);
+
+      long numberOfLuts = ossimString(theBandNumberOfLuts).toLong();
+
+      if(numberOfLuts > 0)
+      {
+         theLookupTables.resize(numberOfLuts);
+         in.read(theBandNumberOfLutEntries, 5);
+         
+         ossim_uint32 numberOfLutsIndex = numberOfLuts;
+         ossim_uint32 numberOfLutEntries = ossimString(theBandNumberOfLutEntries).toLong();
+         ossim_uint32 idx = 0;
+
+         while(idx < numberOfLutsIndex)
+         {
+            theLookupTables[idx] = new ossimNitfImageLutV2_0; 
+            theLookupTables[idx]->setNumberOfEntries(numberOfLutEntries);
+            theLookupTables[idx]->parseStream(in);
+            
+            ++idx;
+         }
+      }
+   }   
+}
+
+void ossimNitfImageBandV2_0::writeStream(std::ostream& out)
+{
+   out.write(theBandRepresentation, 2);
+   out.write(theBandSignificance, 6);
+   out.write(theBandImageFilterCondition, 1);
+   out.write(theBandStandardImageFilterCode, 3);
+   out.write(theBandNumberOfLuts, 1);
+
+   if(ossimString(theBandNumberOfLuts) > 0)
+   {
+      // lut output not supported currently
+   }
+}
+
+std::ostream& ossimNitfImageBandV2_0::print(std::ostream& out)const
+{
+   ossim_uint32 idx = 0;
+   out << "theBandRepresentation:          " << theBandRepresentation
+       << "\ntheBandSignificance:            " << theBandSignificance
+       << "\ntheBandImageFilterCondition:    " << theBandImageFilterCondition
+       << "\ntheBandStandardImageFilterCode: " << theBandStandardImageFilterCode
+       << "\ntheBandNumberOfLuts:            " << theBandNumberOfLuts
+       << "\ntheBandNumberOfLutEntries:      " << theBandNumberOfLutEntries
+       << endl;
+   
+   for(idx = 0; idx < theLookupTables.size(); ++idx)
+   {
+      out << *theLookupTables[idx] << std::endl;
+   }
+   
+   return out;
+}
+
+ossim_uint32 ossimNitfImageBandV2_0::getNumberOfLuts()const
+{
+   return theLookupTables.size();
+}
+
+const ossimRefPtr<ossimNitfImageLut> ossimNitfImageBandV2_0::getLut(ossim_uint32 idx)const
+{
+   if(idx < getNumberOfLuts())
+   {
+      return theLookupTables[idx];
+   }
+   
+   return NULL;
+}
+
+ossimRefPtr<ossimNitfImageLut> ossimNitfImageBandV2_0::getLut(ossim_uint32 idx)
+{
+   if(idx < getNumberOfLuts())
+   {
+      return theLookupTables[idx];
+   }
+   
+   return NULL;
+}
+
+void ossimNitfImageBandV2_0::clearFields()
+{
+   memset(theBandRepresentation, ' ', 2);
+   memset(theBandSignificance, ' ', 6);
+   memset(theBandImageFilterCondition, ' ', 1);
+   memset(theBandStandardImageFilterCode, ' ', 3);
+   memset(theBandNumberOfLuts, '0', 1);
+   memset(theBandNumberOfLutEntries, ' ', 5);
+   
+   theLookupTables.clear();
+   theBandRepresentation[2] = '\0';
+   theBandSignificance[6] = '\0';
+   theBandImageFilterCondition[1] = '\0';
+   theBandStandardImageFilterCode[3] = '\0';
+   theBandNumberOfLuts[1] = '\0';
+   theBandNumberOfLutEntries[5] = '\0';
+}
+
+void ossimNitfImageBandV2_0::printLookupTables(std::ostream& out)const
+{
+   std::vector<ossimRefPtr<ossimNitfImageLut> >::const_iterator tables;
+
+   tables = theLookupTables.begin();
+   while(tables != theLookupTables.end())
+   {
+      if((*tables).valid())
+      {
+         out << *((*tables).get());
+      }
+      ++tables;
+      if(tables != theLookupTables.end())
+      {
+         out << std::endl;
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_0.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_0.h
new file mode 100644
index 0000000000..52ea640666
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_0.h
@@ -0,0 +1,72 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageBandV2_0.h,v 1.5 2005/09/27 19:05:09 dburken Exp $
+#ifndef ossimNitfImageBandV2_0_HEADER
+#define ossimNitfImageBandV2_0_HEADER
+#include <iostream>
+#include <iterator>
+
+#include <support_data/nitf/ossimNitfImageBand.h>
+#include <support_data/nitf/ossimNitfImageLutV2_0.h>
+
+class ossimNitfImageBandV2_0 : public ossimNitfImageBand
+{
+public:
+   ossimNitfImageBandV2_0();
+   ~ossimNitfImageBandV2_0();
+   virtual void parseStream(std::istream& in);
+   virtual void writeStream(std::ostream& out);
+   
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual ossim_uint32 getNumberOfLuts()const;
+   virtual const ossimRefPtr<ossimNitfImageLut> getLut(ossim_uint32 idx)const;
+   virtual ossimRefPtr<ossimNitfImageLut> getLut(ossim_uint32 idx);
+  
+protected:
+   void clearFields();
+   void printLookupTables(std::ostream& out)const;
+   /*!
+    * Is a required 2 byte field.  When theNumberOfBands is
+    * 1 this field will contain all spaces.
+    */
+   char theBandRepresentation[3];
+
+   /*!
+    * Is a required 6 byte field.
+    */
+   char theBandSignificance[7];
+
+   /*!
+    * Is an required 1 byte field.  Will be N
+    */
+   char theBandImageFilterCondition[2];
+
+   /*!
+    * is a required 3 byte field.  This is a reserved field
+    */
+   char theBandStandardImageFilterCode[4];
+
+   /*!
+    * This is a required 1 byte field.  Has value 0-4
+    */
+   char theBandNumberOfLuts[2];
+
+   /*!
+    * This is a conditional field.
+    */
+   char theBandNumberOfLutEntries[6];
+
+   vector<ossimRefPtr<ossimNitfImageLut> > theLookupTables;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_1.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_1.cpp
new file mode 100644
index 0000000000..37dccbdfb2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_1.cpp
@@ -0,0 +1,47 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken <dburken@imagelinks.com>
+//
+// Description: Nitf support class.  Copied from ossimNitfImageBandV2_0.
+// 
+//********************************************************************
+// $Id: ossimNitfImageBandV2_1.cpp,v 1.5 2004/11/11 14:23:33 gpotts Exp $
+#include <sstream>
+#include <support_data/nitf/ossimNitfImageBandV2_1.h>
+#include <base/data_types/ossimString.h>
+
+
+ossimNitfImageBandV2_1::ossimNitfImageBandV2_1()
+{
+}
+
+ossimNitfImageBandV2_1::~ossimNitfImageBandV2_1()
+{
+}
+
+void ossimNitfImageBandV2_1::setBandRepresentation(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(2)
+       << std::setfill(' ')
+       << value.c_str();
+
+   memcpy(theBandRepresentation, out.str().c_str(), 2);
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_1.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_1.h
new file mode 100644
index 0000000000..91f614dd13
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageBandV2_1.h
@@ -0,0 +1,31 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level directory for more details
+//
+// Author:  David Burken <dburken@imagelinks.com>
+//
+//********************************************************************
+// $Id: ossimNitfImageBandV2_1.h,v 1.5 2004/11/11 14:23:33 gpotts Exp $
+
+#ifndef ossimNitfImageBandV2_1_HEADER
+#define ossimNitfImageBandV2_1_HEADER
+#include <iostream>
+#include <iterator>
+#include <base/data_types/ossimString.h>
+
+#include <support_data/nitf/ossimNitfImageBandV2_0.h>
+#include <support_data/nitf/ossimNitfImageLutV2_1.h>
+
+class ossimNitfImageBandV2_1 : public ossimNitfImageBandV2_0
+{
+public:
+   ossimNitfImageBandV2_1();
+   ~ossimNitfImageBandV2_1();
+/*    virtual void parseStream(std::istream& in); */
+/*    virtual void writeStream(std::ostream& out); */
+/*    virtual void print(std::ostream& out)const; */
+   virtual void setBandRepresentation(const ossimString& value);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeader.cpp
new file mode 100644
index 0000000000..3ae367a244
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeader.cpp
@@ -0,0 +1,219 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level LICENSE.txt for more details
+//
+// Author: Garrett Potts
+//
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageHeader.cpp,v 1.10 2005/10/05 12:50:48 gpotts Exp $
+
+#include <cmath> /* for fmod */
+
+#include <support_data/nitf/ossimNitfImageHeader.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF2(ossimNitfImageHeader,
+          "ossimNitfImageHeader",
+          ossimObject,
+          ossimPropertyInterface)
+
+ossimNitfImageHeader::ossimNitfImageHeader()
+{
+}
+
+ossimNitfImageHeader::~ossimNitfImageHeader()
+{
+}
+
+void ossimNitfImageHeader::addTag(ossimNitfTagInformation tag)
+{
+   removeTag(tag.getTagName());
+   theTagList.push_back(tag);
+}
+
+bool ossimNitfImageHeader::getTag(ossimNitfTagInformation& tagInfo,
+                                  const ossimString& tagName)const
+{
+   ossim_uint32 idx = 0;
+   if(theTagList.size())
+   {
+      for(idx = 0; idx < theTagList.size(); ++idx)
+      {
+         if(theTagList[idx].getTagName() == tagName)
+         {
+            tagInfo = theTagList[idx];
+            return true;
+         }
+      }
+   }
+
+   return false;
+}
+
+void ossimNitfImageHeader::removeTag(const ossimString& tagName)
+{
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theTagList.size(); ++idx)
+   {
+      if(theTagList[idx].getTagName() == tagName)
+      {
+         theTagList.erase(theTagList.begin() + idx);
+         return;
+      }
+   }
+}
+
+bool ossimNitfImageHeader::isSameAs(const ossimNitfImageHeader* hdr) const
+{
+   if (!hdr) return false;
+   
+   return ( (isCompressed() == hdr->isCompressed()) &&
+            (getNumberOfRows() == hdr->getNumberOfRows()) &&
+            (getNumberOfBands() == hdr->getNumberOfBands()) &&
+            (getNumberOfCols() == hdr->getNumberOfCols()) &&
+            (getNumberOfBlocksPerRow() == hdr->getNumberOfBlocksPerRow()) &&
+            (getNumberOfBlocksPerCol() == hdr->getNumberOfBlocksPerCol()) &&
+            (getNumberOfPixelsPerBlockHoriz() ==
+             hdr->getNumberOfPixelsPerBlockHoriz()) &&
+            (getNumberOfPixelsPerBlockVert() ==
+             hdr->getNumberOfPixelsPerBlockVert()) &&
+            (getBitsPerPixelPerBand() == hdr->getBitsPerPixelPerBand()) &&
+            (getImageRect() == hdr->getImageRect()) &&
+            (getIMode() == hdr->getIMode()) &&
+            (getCoordinateSystem() == hdr->getCoordinateSystem()) &&
+            (getGeographicLocation() == hdr->getGeographicLocation()) );
+}
+
+bool ossimNitfImageHeader::getTagInformation(ossimNitfTagInformation& tag,
+                                             ossim_uint32 idx)const
+{
+   bool result = false;
+   
+   if(idx < theTagList.size())
+   {
+      tag = theTagList[idx];
+      result = true;
+   }
+   
+   return result;
+}
+
+int ossimNitfImageHeader::getNumberOfTags()const
+{
+   return theTagList.size();
+}
+
+void ossimNitfImageHeader::setProperty(ossimRefPtr<ossimProperty> property)
+{
+}
+
+ossimRefPtr<ossimProperty> ossimNitfImageHeader::getProperty(const ossimString& name)const
+{
+   return (ossimProperty*)NULL;
+}
+
+void ossimNitfImageHeader::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+}
+
+ossim_uint32 ossimNitfImageHeader::getTotalTagLength()const
+{
+   ossim_uint32 tagLength = 0;
+   
+   for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
+   {
+      tagLength += theTagList[i].getTotalTagLength();
+   }
+
+   return tagLength;
+}
+
+void ossimNitfImageHeader::printTags(std::ostream& out)const
+{
+   for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
+   {
+      out << "Tag name:   " << theTagList[i].getTagName() << std::endl;
+      if(i+1 < theTagList.size())
+      {
+         out << "Tag Length: " << theTagList[i].getTagLength() << std::endl;
+      }
+      else
+      {
+         out << "Tag Length: " << theTagList[i].getTagLength();
+      }
+   }
+}
+
+bool ossimNitfImageHeader::hasLut()const
+{
+   return true;
+}
+
+ossimRefPtr<ossimNBandLutDataObject> ossimNitfImageHeader::createLut(ossim_uint32 bandIdx)const
+{
+   ossimRefPtr<ossimNBandLutDataObject> result;
+   
+   if(bandIdx < (ossim_uint32)getNumberOfBands())
+   {
+      const ossimRefPtr<ossimNitfImageBand> band = getBandInformation(bandIdx);
+      if(band.valid())
+      {
+         ossim_uint32 bands = band->getNumberOfLuts();
+         if(bands > 0)
+         {
+            if(band->getLut(0).valid())
+            {
+               ossim_uint32 entries = band->getLut(0)->getNumberOfEntries();
+               
+               result = new ossimNBandLutDataObject();
+               result->create(entries, band->getNumberOfLuts());
+               ossim_uint32 bIdx;
+               ossim_uint32 entryIdx;
+
+               for(bIdx = 0; bIdx < bands; ++bIdx)
+               {
+                  const ossimRefPtr<ossimNitfImageLut> lut = band->getLut(bIdx);
+                  if(lut.valid())
+                  {
+                     for(entryIdx = 0; entryIdx < entries; ++entryIdx)
+                     {
+                        (*result)[entryIdx][bIdx] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(lut->getValue(entryIdx));
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   return result;
+}
+
+
+void ossimNitfImageHeader::checkForGeographicTiePointTruncation(
+   const ossimDpt& tie) const
+{
+   // One arc second in decimal degrees.
+   const ossim_float64 ARC_SECOND = 1.0/3600.0;
+
+   // Very small number.
+   const ossim_float64 FUDGE_FACTOR = 0.000000001;
+
+   // Remainder portion of latitude divided by an arc second.
+   ossim_float64 y = std::fmod(tie.y, ARC_SECOND);
+
+   // Remainder portion of longitue divided by an arc second.
+   ossim_float64 x = std::fmod(tie.x, ARC_SECOND);
+
+   if ( (std::fabs(y) > FUDGE_FACTOR) || (std::fabs(x) > FUDGE_FACTOR) )
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimNitfImageHeader WARNING:\n"
+         << "Tie point will be truncated in image header:  "
+         << tie
+         << std::endl;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeader.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeader.h
new file mode 100644
index 0000000000..438ca5df51
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeader.h
@@ -0,0 +1,118 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level LICENSE.txt for more details
+//
+// Author: Garrett Potts
+// 
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageHeader.h,v 1.22 2005/10/05 12:50:48 gpotts Exp $
+#ifndef ossimNitfImageHeader_HEADER
+#define ossimNitfImageHeader_HEADER
+#include <iostream>
+#include <vector>
+using namespace std;
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/common/ossimNBandLutDataObject.h>
+#include <base/common/ossimObject.h>
+#include <base/common/ossimPropertyInterface.h>
+#include "ossimNitfTagInformation.h"
+#include "ossimNitfCompressionHeader.h"
+#include "ossimNitfImageBand.h"
+
+class OSSIMDLLEXPORT ossimNitfImageHeader : public ossimObject,
+                                            public ossimPropertyInterface
+{
+public:
+   ossimNitfImageHeader();
+   virtual ~ossimNitfImageHeader();
+
+   virtual bool  getTagInformation(ossimNitfTagInformation& tag,
+                                   ossim_uint32 idx)const;
+
+   virtual int getNumberOfTags()const;
+
+   virtual bool getTag(ossimNitfTagInformation& tagInfo,
+                       const ossimString& tagName)const;
+   virtual void addTag(ossimNitfTagInformation tag);
+   virtual void removeTag(const ossimString& tagName);
+   
+   virtual void parseStream(std::istream &in)= 0;
+   virtual void writeStream(std::ostream &out)= 0;
+
+   virtual bool isCompressed()const=0;
+   virtual bool isEncrypted()const=0;
+
+   virtual ossimString getCompressionCode()const=0;
+   virtual long getDisplayLevel()const=0;
+   virtual long getAttachmentLevel()const=0;
+   
+   virtual long getNumberOfRows()const=0;
+   virtual long getNumberOfBands()const=0;
+   virtual long getNumberOfCols()const=0;
+   virtual long getNumberOfBlocksPerRow()const=0;
+   virtual long getNumberOfBlocksPerCol()const=0;
+   virtual long getNumberOfPixelsPerBlockHoriz()const=0;
+   virtual long getNumberOfPixelsPerBlockVert()const=0;
+   virtual ossimString getImageId()const=0;
+   virtual long        getActualBitsPerPixelPerBand()const=0;
+   virtual long        getBitsPerPixelPerBand()const=0;
+   virtual ossimDrect  getImageRect()const=0;
+   /**
+    * Blocks might not be the same size as the significant rows and cols used
+    * by the getImageRect.
+    */
+   virtual ossimDrect   getBlockImageRect()const=0;
+   virtual ossimString  getIMode()const=0;
+   virtual ossim_uint64 getDataLocation()const=0;
+   virtual ossimString  getAcquisitionDateMonthDayYear(ossim_uint8 separationChar='-')const=0;
+   virtual ossimString  getSecurityClassification()const=0;
+   virtual ossimString  getCategory()const=0;
+   virtual ossimString  getImageSource()const=0;
+   virtual ossimString  getRepresentation()const=0;
+   virtual ossimString  getCoordinateSystem()const=0;
+   virtual ossimString  getGeographicLocation()const=0;
+   virtual ossimString  getPixelValueType()const=0;
+   virtual bool hasBlockMaskRecords()const=0;
+   virtual bool hasPadPixelMaskRecords()const=0;
+   virtual bool hasTransparentCode()const=0;
+   virtual ossim_uint32 getTransparentCode()const=0;
+   virtual ossim_uint32 getBlockMaskRecordOffset(ossim_uint32 blockNumber,
+                                                 ossim_uint32 bandNumber)const=0;
+   
+   virtual ossim_uint32 getPadPixelMaskRecordOffset(ossim_uint32 blockNumber,
+                                                    ossim_uint32 bandNumber)const=0;
+   virtual const ossimRefPtr<ossimNitfCompressionHeader> getCompressionHeader()const=0;
+   virtual const ossimRefPtr<ossimNitfImageBand> getBandInformation(ossim_uint32 idx)const=0;
+   bool hasLut()const;
+   ossimRefPtr<ossimNBandLutDataObject> createLut(ossim_uint32 bandIdx)const;
+   virtual bool isSameAs(const ossimNitfImageHeader* hdr) const;
+   
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+
+   virtual ossim_uint32 getTotalTagLength()const;
+   void printTags(std::ostream& out)const;
+
+protected:
+
+   /**
+    * Method to check tie point to see if it will be truncated in field
+    * IGEOLO which has only arc second resolution.
+    * 
+    * Spits out warning if tie does not evenly divide by an arc second.
+    *
+    * @param tie Tie point to check.
+    */
+   void checkForGeographicTiePointTruncation(const ossimDpt& tie) const;
+   
+   std::vector<ossimNitfTagInformation> theTagList;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_0.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_0.cpp
new file mode 100644
index 0000000000..f08cb9933a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_0.cpp
@@ -0,0 +1,760 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+// 
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageHeaderV2_0.cpp,v 1.31 2005/10/05 12:50:48 gpotts Exp $
+#include <support_data/nitf/ossimNitfImageHeaderV2_0.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimIpt.h>
+#include <cstring> //for memset
+#include <base/misc/ossimEndian.h>
+#include "ossimNitfVqCompressionHeader.h"
+#include <base/common/ossimTrace.h>
+
+#ifndef NULL
+#include <cstddef>
+#endif
+
+// static const ossimTrace traceDebug("ossimNitfFileHeaderV2_0:debug");
+
+RTTI_DEF1(ossimNitfImageHeaderV2_0, "ossimNitfImageHeaderV2_0", ossimNitfImageHeader);
+
+ossimNitfImageHeaderV2_0::ossimNitfImageHeaderV2_0()
+{
+   clearFields();
+}
+
+ossimNitfImageHeaderV2_0::~ossimNitfImageHeaderV2_0()
+{
+}
+
+void ossimNitfImageHeaderV2_0::parseStream(std::istream &in)
+{
+   clearFields();
+   theImageBands.clear();
+      
+   in.read(theType, 2);
+   if(ossimString(theType) != "IM")
+   {
+      // error
+   }
+   in.read(theImageId, 10);
+   in.read(theDateTime, 14);
+   in.read(theTargetId, 17);
+   in.read(theTitle, 80);
+   in.read(theSecurityClassification, 1);
+   in.read(theCodewords, 40);
+   in.read(theControlAndHandling, 40);
+   in.read(theReleasingInstructions, 40);
+   in.read(theClassificationAuthority, 20);
+   in.read(theSecurityControlNumber, 20);
+   in.read(theSecurityDowngrade, 6);
+   if(ossimString(theSecurityDowngrade) == "999998")
+   {
+      in.read(theDowngradingEvent, 40);
+   }
+   in.read(theEncryption, 1);
+   in.read(theImageSource, 42);
+   in.read(theSignificantRows, 8);
+   in.read(theSignificantCols, 8);
+   in.read(thePixelValueType, 3);
+   in.read(theRepresentation, 8);
+   in.read(theCategory, 8);
+   in.read(theBitsPerPixelPerBand, 2);
+   in.read(theJustification, 1);
+   in.read(theCoordinateSystem, 1);
+   if(theCoordinateSystem[0] != 'N')
+   {
+      in.read(theGeographicLocation, 60);
+   }
+   in.read(theNumberOfComments, 1);
+   ossim_uint32 numberOfComments = ossimString(theNumberOfComments).toLong();
+   if(numberOfComments > 0)
+   {
+      // for now let's ignore the comments about the image
+      in.ignore(numberOfComments*80);
+   }
+   in.read(theCompression, 2);
+   // check to see if there is compression
+   ossimString temp = theCompression;
+   if((temp !=  "NC") &&
+      (temp != "NM"))
+   {
+      // get the rate if compression exists.
+      in.read(theCompressionRateCode, 4);
+   }
+   in.read(theNumberOfBands, 1);
+   ossim_uint32 numberOfBands = ossimString(theNumberOfBands).toUInt32();
+   theImageBands.resize(numberOfBands);
+   ossim_uint32 idx = 0;
+   while(idx < numberOfBands)
+   {
+      theImageBands[idx] = new ossimNitfImageBandV2_0;
+      theImageBands[idx]->parseStream(in);
+      ++idx;
+   }
+   in.read(theImageSyncCode, 1);
+   in.read(theImageMode, 1);
+   in.read(theNumberOfBlocksPerRow, 4);
+   in.read(theNumberOfBlocksPerCol, 4);
+   in.read(theNumberOfPixelsPerBlockHoriz, 4);
+   in.read(theNumberOfPixelsPerBlockVert, 4);
+   in.read(theNumberOfBitsPerPixelPerBand, 2);
+   in.read(theDisplayLevel, 3);
+   in.read(theAttachmentLevel, 3);
+   in.read(theImageLocation, 10);
+   in.read(theImageMagnification, 4);
+   in.read(theUserDefinedImageDataLength, 5);
+   std::streampos userDefinedDataLen = (std::streampos)ossimString(theUserDefinedImageDataLength).toUInt32();
+   theTagList.clear();
+   ossimNitfTagInformation         headerTag;
+   std::streampos start   = in.tellg();
+   std::streampos current = in.tellg();
+   if(userDefinedDataLen > 0)
+   {
+      in.read(theUserDefinedOverflow, 3);
+      
+      while((current - start) < userDefinedDataLen)
+      {
+         headerTag.parseStream(in);
+         theTagList.push_back(headerTag);
+         in.ignore(headerTag.getTagLength());
+         headerTag.clearFields();
+         current = in.tellg();
+      }
+   }
+
+   in.read(theExtendedSubheaderDataLen, 5);
+   std::streampos extSubHeadLen = (std::streampos)ossimString(theExtendedSubheaderDataLen).toUInt32();
+   start   = in.tellg();
+   current = in.tellg();
+   if(extSubHeadLen > 0)
+   {
+      in.read(theExtendedSubheaderOverflow, 3);
+
+      ossim_uint32 test = 0;
+      while((current - start) < extSubHeadLen)
+      {
+         headerTag.parseStream(in);
+         theTagList.push_back(headerTag);
+         test = headerTag.getTagLength()+in.tellg();
+         in.ignore(headerTag.getTagLength());
+         headerTag.clearFields();
+         current = in.tellg();
+      }
+   }
+   
+   ossimString compressionType = theCompression;
+   compressionType = compressionType.trim().upcase();
+   ossimEndian endian;
+   ossim_uint64 locationBefore = in.tellg();
+    if((compressionType == "NM")||
+       (compressionType == "M0")||
+       (compressionType == "M3")||
+       (compressionType == "M4"))
+   {
+      in.read((char*)(&theBlockedImageDataOffset), 4);
+      in.read((char*)(&theBlockMaskRecordLength),2);
+      in.read((char*)(&thePadPixelMaskRecordLength), 2);
+      in.read((char*)(&theTransparentOutputPixelCodeLength), 2);
+
+      
+      if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+      {
+         endian.swap(theBlockedImageDataOffset);
+         endian.swap(theBlockMaskRecordLength);
+         endian.swap(thePadPixelMaskRecordLength);
+         endian.swap(theTransparentOutputPixelCodeLength);
+      }
+      if(theTransparentOutputPixelCodeLength <9)
+      {
+         if(theTransparentOutputPixelCodeLength != 0)
+         {
+            ossim_uint8 padOutputPixelCode;
+            in.read((char*)(&padOutputPixelCode), 1);
+            thePadOutputPixelCode = padOutputPixelCode;
+         }
+      }
+      else
+      {
+         in.read((char*)(&thePadOutputPixelCode), 2);
+         if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+         {
+            endian.swap(thePadOutputPixelCode);
+         }
+         // I need to add code here to check for justification when its 2 bytes
+         // but the code length is less than 16 bits.
+         //
+      }
+      if(theBlockMaskRecordLength>0)
+      {
+         ossim_uint32 totalNumber = 0;
+         if((theImageMode[0] == 'S'))
+         {
+             totalNumber = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol()*getNumberOfBands();
+         }
+         else
+         {
+            totalNumber = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol();
+         }
+         ossim_uint32 *blockRead = new ossim_uint32[totalNumber];
+         ossim_uint32 idx = 0;
+         theBlockMaskRecords.resize(totalNumber);
+         in.read((char*)(blockRead), totalNumber*4);
+         for(idx = 0; idx < totalNumber; ++idx)
+         {
+            if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+            {
+               endian.swap(blockRead[idx]);
+            }
+            theBlockMaskRecords[idx] = blockRead[idx];
+         }
+      }
+      if((thePadPixelMaskRecordLength > 0)||
+         (( (getCompressionCode().upcase() == "M3"))&&
+          (thePadPixelMaskRecordLength == 0)))
+      {
+         ossim_uint32 totalNumber = 0;
+         if((theImageMode[0] == 'S'))
+         {
+            totalNumber = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol()*getNumberOfBands();
+         }
+         else
+         {
+            totalNumber = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol();
+         }
+         ossim_uint32 *blockRead = new ossim_uint32[totalNumber];
+         ossim_uint32 idx = 0;
+         thePadPixelMaskRecords.resize(totalNumber);
+         in.read((char*)(blockRead), totalNumber*4);
+         for(idx = 0; idx < totalNumber; ++idx)
+         {
+            if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+            {
+               endian.swap(blockRead[idx]);
+            }
+            thePadPixelMaskRecords[idx] = blockRead[idx];
+         }
+         delete [] blockRead;
+      }
+   }
+    theCompressionHeader = 0;
+    if((getCompressionCode() == "C4")||
+       (getCompressionCode() == "M4"))
+    {
+       ossimRefPtr<ossimNitfVqCompressionHeader> compressionHeader = new ossimNitfVqCompressionHeader;
+       compressionHeader->parseStream(in);
+       // do a check to see if the compression header is good
+       //
+       if(compressionHeader->getCompressionAlgorithmId()!= 1)
+       {
+          compressionHeader = 0;
+       }
+       theCompressionHeader = compressionHeader.get();
+    }
+    ossim_uint64 delta = (ossim_uint64)in.tellg() - locationBefore;
+    if(delta < theBlockedImageDataOffset)
+    {
+       in.ignore(theBlockedImageDataOffset-delta);
+    }
+    
+    //
+    // The stream should now be at the start of the data location so capture
+    // it.
+    //
+    theDataLocation = in.tellg();
+}
+
+void ossimNitfImageHeaderV2_0::writeStream(std::ostream &out)
+{
+}
+
+std::ostream& ossimNitfImageHeaderV2_0::print(std::ostream& out)const
+{
+   out << "theType:                        " << theType << endl
+       << "theImageId:                     " << theImageId << endl
+       << "theDateTime:                    " << theDateTime << endl
+       << "theTargetId:                    " << theTargetId << endl
+       << "theTitle:                       " << theTitle    << endl
+       << "theSecurityClassification:      " << theSecurityClassification << endl
+       << "theCodewords:                   " << theCodewords << endl
+       << "theControlAndHandling:          " << theControlAndHandling << endl
+       << "theReleasingInstructions:       " << theReleasingInstructions << endl
+       << "theClassificationAuthority:     " << theClassificationAuthority << endl
+       << "theSecurityControlNumber:       " << theSecurityControlNumber << endl
+       << "theSecurityDowngrade:           " << theSecurityDowngrade     << endl
+       << "theDowngradingEvent:            " << theDowngradingEvent << endl
+       << "theEncryption:                  " << theEncryption << endl
+       << "theImageSource:                 " << theImageSource << endl
+       << "theSignificantRows:             " << theSignificantRows << endl
+       << "theSignificantCols:             " << theSignificantCols << endl
+       << "thePixelValueType:              " << thePixelValueType << endl
+       << "theRepresentation:              " << theRepresentation << endl
+       << "theCategory:                    " << theCategory       << endl
+       << "theBitsPerPixelPerBand:         " << theBitsPerPixelPerBand << endl
+       << "theJustification:               " << theJustification << endl
+       << "theCoordinateSystem:            " << theCoordinateSystem << endl
+       << "theGeographicLocation:          " << theGeographicLocation << endl
+       << "theNumberOfComments:            " << theNumberOfComments << endl
+       << "theCompression:                 " << theCompression      << endl
+       << "theCompressionRateCode:         " << theCompressionRateCode << endl
+       << "theNumberOfBands:               " << theNumberOfBands << endl;
+
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theImageBands.size(); ++idx)
+   {
+      if(theImageBands[idx].valid())
+      {
+         out << *theImageBands[idx] << std::endl;
+      }
+   }
+//    copy(theImageBands.begin(),
+//         theImageBands.end(),
+//         ostream_iterator<ossimNitfImageBandV2_0>(out, "\n"));
+   
+   out << "theImageSyncCode:               " << theImageSyncCode << endl
+       << "theImageMode:                   " << theImageMode << endl
+       << "theNumberOfBlocksPerRow:        " << theNumberOfBlocksPerRow << endl
+       << "theNumberOfBlocksPerCol:        " << theNumberOfBlocksPerCol << endl
+       << "theNumberOfPixelsPerBlockHoriz: " << theNumberOfPixelsPerBlockHoriz << endl
+       << "theNumberOfPixelsPerBlockVert:  " << theNumberOfPixelsPerBlockVert << endl
+       << "theNumberOfBitsPerPixelPerBand: " << theNumberOfBitsPerPixelPerBand << endl
+       << "theDisplayLevel:                " << theDisplayLevel << endl
+       << "theAttachmentLevel:             " << theAttachmentLevel << endl
+       << "theImageLocation:               " << theImageLocation << endl
+       << "theImageMagnification:          " << theImageMagnification << endl
+       << "theUserDefinedImageDataLength:  " << theUserDefinedImageDataLength << endl
+       << "theUserDefinedOverflow:         " << theUserDefinedOverflow << endl
+       << "theExtendedSubheaderDataLen:    " << theExtendedSubheaderDataLen << endl
+       << "theExtendedSubheaderOverflow:   " << theExtendedSubheaderOverflow << endl
+       << "theDataLocation:                " << theDataLocation << endl;
+
+   out << "theBlockedImageDataOffset:           " << theBlockedImageDataOffset << std::endl
+       << "theBlockMaskRecordLength:            " << theBlockMaskRecordLength << std::endl
+       << "thePadPixelMaskRecordLength:         " << thePadPixelMaskRecordLength << std::endl
+       << "theTransparentOutputPixelCodeLength: " << theTransparentOutputPixelCodeLength << std::endl
+       << "thePadOutputPixelCode:               " << thePadOutputPixelCode << std::endl;
+
+   if(theCompressionHeader.valid())
+   {
+      theCompressionHeader->print(out);
+      out << std::endl;
+   }
+   
+   out << "TAGS:\n";
+   std::copy(theTagList.begin(),
+             theTagList.end(),
+             std::ostream_iterator<ossimNitfTagInformation>(out,"\n"));
+   return out;
+}
+
+ossimDrect ossimNitfImageHeaderV2_0::getImageRect()const
+{
+   ossimDpt ul(ossimString((char*)(&theImageLocation[5])).toDouble(),
+               ossimString((char*)theImageLocation, (char*)(&theImageLocation[5])).toDouble());
+   
+   double rows = ossimString(theSignificantRows).toDouble();
+   double cols = ossimString(theSignificantCols).toDouble();
+
+   ossimDpt lr(ul.x + cols-1,
+               ul.y + rows-1);
+   
+   return ossimDrect(ul, lr);
+}
+
+ossimDrect ossimNitfImageHeaderV2_0::getBlockImageRect()const
+{
+   ossimDpt ul(ossimString((char*)(&theImageLocation[5])).toDouble(),
+               ossimString((char*)theImageLocation, (char*)(&theImageLocation[5])).toDouble());
+   
+   double rows = getNumberOfPixelsPerBlockVert()*getNumberOfBlocksPerCol();
+   double cols = getNumberOfPixelsPerBlockHoriz()*getNumberOfBlocksPerRow();;
+
+   ossimDpt lr(ul.x + cols-1,
+               ul.y + rows-1);
+   
+   return ossimDrect(ul, lr);
+}
+
+bool ossimNitfImageHeaderV2_0::isCompressed()const
+{
+   ossimString temp = theCompression;
+   temp = temp.trim();
+   return ((temp != "NC") &&
+           (temp != "NM"));
+}
+
+bool ossimNitfImageHeaderV2_0::isEncrypted()const
+{
+   return (theEncryption[0] == '1');
+}
+
+ossimString ossimNitfImageHeaderV2_0::getCompressionCode()const
+{
+   return ossimString(theCompression).trim();
+}
+
+long ossimNitfImageHeaderV2_0::getDisplayLevel()const
+{
+   return ossimString(theDisplayLevel).toLong();
+}
+
+long ossimNitfImageHeaderV2_0::getAttachmentLevel()const
+{
+   return ossimString(theAttachmentLevel).toLong();
+}
+
+
+long ossimNitfImageHeaderV2_0::getNumberOfBands()const
+{
+   return ossimString(theNumberOfBands).toLong();
+}
+
+long ossimNitfImageHeaderV2_0::getNumberOfRows()const
+{
+   return ossimString(theSignificantRows).toLong();
+}
+
+long ossimNitfImageHeaderV2_0::getNumberOfCols()const
+{
+   return ossimString(theSignificantCols).toLong();
+}
+
+long ossimNitfImageHeaderV2_0::getNumberOfBlocksPerRow()const
+{
+   return ossimString(theNumberOfBlocksPerRow).toLong();
+}
+
+long ossimNitfImageHeaderV2_0::getNumberOfBlocksPerCol()const
+{
+   return ossimString(theNumberOfBlocksPerCol).toLong();
+}
+
+long ossimNitfImageHeaderV2_0::getNumberOfPixelsPerBlockHoriz()const
+{
+   return ossimString(theNumberOfPixelsPerBlockHoriz).toLong();
+}
+
+long ossimNitfImageHeaderV2_0::getNumberOfPixelsPerBlockVert()const
+{
+   return ossimString(theNumberOfPixelsPerBlockVert).toLong();
+}
+
+ossimString ossimNitfImageHeaderV2_0::getImageId()const
+{
+   return theImageId;
+}
+
+long ossimNitfImageHeaderV2_0::getBitsPerPixelPerBand()const
+{
+   return ossimString(theNumberOfBitsPerPixelPerBand).toLong();
+}
+
+long ossimNitfImageHeaderV2_0::getActualBitsPerPixelPerBand()const
+{
+   return ossimString(theBitsPerPixelPerBand).toLong();
+}
+
+ossimString ossimNitfImageHeaderV2_0::getIMode() const
+{
+   return ossimString(theImageMode).trim();
+}
+
+ossim_uint64 ossimNitfImageHeaderV2_0::getDataLocation() const
+{
+   return theDataLocation;
+}
+
+ossimString ossimNitfImageHeaderV2_0::getSecurityClassification()const
+{
+   return ossimString(theSecurityClassification);
+}
+
+ossimString ossimNitfImageHeaderV2_0::getAcquisitionDateMonthDayYear(ossim_uint8 separationChar)const
+{
+   ossimString result;
+   ossimString month(theDateTime+9,
+                     theDateTime+12);
+   month = month.downcase();
+   if(month == "jan")
+   {
+      result += "01";
+   }
+   else if(month == "feb")
+   {
+      result += "02";
+   }
+   else if(month == "mar")
+   {
+      result += "03";
+   }
+   else if(month == "apr")
+   {
+      result += "04";
+   }
+   else if(month == "may")
+   {
+      result += "05";
+   }
+   else if(month == "jun")
+   {
+      result += "06";
+   }
+   else if(month == "jul")
+   {
+      result += "07";
+   }
+   else if(month == "aug")
+   {
+      result += "08";
+   }
+   else if(month == "sep")
+   {
+      result += "09";
+   }
+   else if(month == "oct")
+   {
+      result += "10";
+   }
+   else if(month == "nov")
+   {
+      result += "11";
+   }
+   else if(month == "dec")
+   {
+      result += "12";
+   }
+   result += ossimString(separationChar);
+   result += ossimString(theDateTime,
+                         theDateTime + 2);
+   result += ossimString(separationChar);
+   result += ossimString(theDateTime+12,
+                         theDateTime+14);
+
+   return result;
+}
+
+ossimString ossimNitfImageHeaderV2_0::getCategory()const
+{
+   return theCategory;
+}
+
+ossimString ossimNitfImageHeaderV2_0::getImageSource()const
+{
+   return theImageSource;
+}
+
+ossimString ossimNitfImageHeaderV2_0::getRepresentation()const
+{
+   return theRepresentation;
+}
+
+ossimString ossimNitfImageHeaderV2_0::getCoordinateSystem()const
+{
+	return theCoordinateSystem;
+}
+
+ossimString ossimNitfImageHeaderV2_0::getGeographicLocation()const
+{
+	return theGeographicLocation;
+}
+
+ossimString ossimNitfImageHeaderV2_0::getPixelValueType()const
+{
+   return ossimString(thePixelValueType).trim();
+}
+
+bool ossimNitfImageHeaderV2_0::hasBlockMaskRecords()const
+{
+   return (theBlockMaskRecords.size() > 0);
+}
+
+bool ossimNitfImageHeaderV2_0::hasPadPixelMaskRecords()const
+{
+   return (thePadPixelMaskRecords.size() > 0);
+}
+
+bool ossimNitfImageHeaderV2_0::hasTransparentCode()const
+{
+   return (theTransparentOutputPixelCodeLength > 0);
+}
+
+ossim_uint32 ossimNitfImageHeaderV2_0::getTransparentCode()const
+{
+   return thePadOutputPixelCode;
+}
+
+ossim_uint32 ossimNitfImageHeaderV2_0::getBlockMaskRecordOffset(ossim_uint32 blockNumber,
+                                                                ossim_uint32 bandNumber)const
+{
+   ossim_uint32 maxBlock = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol();
+   ossim_uint32 result = 0xffffffff;
+   
+   if((hasBlockMaskRecords())&&
+      (blockNumber < maxBlock))
+   {
+      if(theImageMode[0] == 'S')
+      {
+         if(bandNumber < (ossim_uint32)getNumberOfBands())
+         {
+            result = theBlockMaskRecords[bandNumber*maxBlock + blockNumber];
+         }
+      }
+      else
+      {
+         result = theBlockMaskRecords[blockNumber];
+      }
+   }
+
+   return result;
+}
+ossim_uint32 ossimNitfImageHeaderV2_0::getPadPixelMaskRecordOffset(ossim_uint32 blockNumber,
+                                                                   ossim_uint32 bandNumber)const
+{
+   ossim_uint32 maxBlock = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol();
+   ossim_uint32 result = 0xffffffff;
+   
+   if((hasPadPixelMaskRecords())&&
+      (blockNumber < maxBlock))
+   {
+      if(theImageMode[0] == 'S')
+      {
+         if(bandNumber < (ossim_uint32)getNumberOfBands())
+         {
+            result = thePadPixelMaskRecords[bandNumber*maxBlock + blockNumber];
+         }
+      }
+      else
+      {
+         result = thePadPixelMaskRecords[blockNumber];
+      }
+   }
+
+   return result;
+}
+
+void ossimNitfImageHeaderV2_0::clearFields()
+{
+   theTagList.clear();
+   
+   memset(theType, ' ', 2);
+   memset(theImageId, ' ', 10);
+   memset(theDateTime, ' ', 14);
+   memset(theTargetId, ' ', 17);
+   memset(theTitle, ' ', 80);
+   memset(theSecurityClassification, ' ', 1);
+   memset(theCodewords, ' ', 40);
+   memset(theControlAndHandling, ' ', 40);
+   memset(theReleasingInstructions, ' ', 40);
+   memset(theClassificationAuthority, ' ', 20);
+   memset(theSecurityControlNumber, ' ', 20);
+   memset(theSecurityDowngrade, ' ', 6);
+   memset(theDowngradingEvent, ' ', 40);
+   memset(theEncryption, ' ', 1);
+   memset(theImageSource, ' ', 42);
+   memset(theSignificantRows, ' ', 8);
+   memset(theSignificantCols, ' ', 8);
+   memset(thePixelValueType, ' ', 3);
+   memset(theRepresentation, ' ', 8);
+   memset(theCategory, ' ', 8);
+   memset(theBitsPerPixelPerBand, ' ', 2);
+   memset(theJustification, ' ', 1);
+   memset(theCoordinateSystem, ' ', 1);
+   memset(theGeographicLocation, ' ', 60);
+   memset(theNumberOfComments, ' ', 1);
+   memset(theCompression, ' ', 2);
+   memset(theCompressionRateCode, ' ', 4);
+   memset(theNumberOfBands, ' ', 1);
+   memset(theImageSyncCode, ' ', 1);
+   memset(theImageMode, ' ', 1);
+   memset(theNumberOfBlocksPerRow, ' ', 4);
+   memset(theNumberOfBlocksPerCol, ' ', 4);
+   memset(theNumberOfPixelsPerBlockHoriz, ' ', 4);
+   memset(theNumberOfPixelsPerBlockVert, ' ', 4);
+   memset(theNumberOfBitsPerPixelPerBand, ' ', 2);
+   memset(theDisplayLevel, ' ', 3);
+   memset(theAttachmentLevel, ' ', 3);
+   memset(theImageLocation, ' ', 10);
+   memset(theImageMagnification, ' ', 4);
+   memset(theUserDefinedImageDataLength, ' ', 5);
+   memset(theUserDefinedOverflow, ' ', 3);
+   memset(theExtendedSubheaderDataLen, ' ', 5);
+   memset(theExtendedSubheaderOverflow, ' ', 3);
+   
+   theBlockMaskRecords.clear();
+   thePadPixelMaskRecords.clear();
+
+   theBlockedImageDataOffset = 0;
+   theBlockMaskRecordLength = 0;
+   thePadPixelMaskRecordLength = 0;
+   theTransparentOutputPixelCodeLength = 0;
+   thePadOutputPixelCode = 0;
+   theCompressionHeader  = 0;
+   theType[2] = '\0';
+   theImageId[10] = '\0';
+   theDateTime[14] = '\0';
+   theTargetId[17] = '\0';
+   theTitle[80] = '\0';
+   theSecurityClassification[1] = '\0';
+   theCodewords[40] = '\0';
+   theControlAndHandling[40] = '\0';
+   theReleasingInstructions[40] = '\0';
+   theClassificationAuthority[20] = '\0';
+   theSecurityControlNumber[20] = '\0';
+   theSecurityDowngrade[6] = '\0';
+   theDowngradingEvent[40] = '\0';
+   theEncryption[1] = '\0';
+   theImageSource[42] = '\0';
+   theSignificantRows[8] = '\0';
+   theSignificantCols[8] = '\0';
+   thePixelValueType[3] = '\0';
+   theRepresentation[8] = '\0';
+   theCategory[8] = '\0';
+   theBitsPerPixelPerBand[2] = '\0';
+   theJustification[1] = '\0';
+   theCoordinateSystem[1] = '\0';
+   theGeographicLocation[60] = '\0';
+   theNumberOfComments[1] = '\0';
+   theCompression[2] = '\0';
+   theCompressionRateCode[4] = '\0';
+   theNumberOfBands[1] = '\0';
+   theImageSyncCode[1] = '\0';
+   theImageMode[1] = '\0';
+   theNumberOfBlocksPerRow[4] = '\0';
+   theNumberOfBlocksPerCol[4] = '\0';
+   theNumberOfPixelsPerBlockHoriz[4] = '\0';
+   theNumberOfPixelsPerBlockVert[4] = '\0';
+   theNumberOfBitsPerPixelPerBand[2] = '\0';
+   theDisplayLevel[3] = '\0';
+   theAttachmentLevel[3] = '\0';
+   theImageLocation[10] = '\0';
+   theImageMagnification[4] = '\0';
+   theUserDefinedImageDataLength[5] = '\0';
+   theUserDefinedOverflow[3] = '\0';
+   theExtendedSubheaderDataLen[5] = '\0';
+   theExtendedSubheaderOverflow[3] = '\0'; 
+   theDataLocation = 0;
+}
+
+const ossimRefPtr<ossimNitfCompressionHeader> ossimNitfImageHeaderV2_0::getCompressionHeader()const
+{
+   return theCompressionHeader;
+}
+
+const ossimRefPtr<ossimNitfImageBand> ossimNitfImageHeaderV2_0::getBandInformation(ossim_uint32 idx)const
+{
+   if(idx < theImageBands.size())
+   {
+      return (ossimNitfImageBand*)theImageBands[idx].get();
+   }
+   
+   return NULL;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_0.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_0.h
new file mode 100644
index 0000000000..f2a0b1c313
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_0.h
@@ -0,0 +1,540 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageHeaderV2_0.h,v 1.15 2005/10/04 17:26:26 gpotts Exp $
+#ifndef ossimNitfImageHeaderV2_0_HEADER
+#define ossimNitfImageHeaderV2_0_HEADER
+#include "ossimNitfImageHeader.h"
+#include "ossimNitfImageBandV2_0.h"
+#include "ossimNitfCompressionHeader.h"
+#include <iterator>
+
+class OSSIMDLLEXPORT ossimNitfImageHeaderV2_0 : public ossimNitfImageHeader
+{
+public:
+   ossimNitfImageHeaderV2_0();
+   virtual ~ossimNitfImageHeaderV2_0();
+
+   virtual void parseStream(std::istream &in);
+   virtual void writeStream(std::ostream &out);
+   
+   virtual std::ostream& print(std::ostream &out)const;
+   
+   virtual ossimDrect getImageRect()const;
+   virtual ossimDrect getBlockImageRect()const;
+   virtual bool isCompressed()const;
+   virtual bool isEncrypted()const;
+   virtual ossimString getCompressionCode()const;
+
+   virtual long getDisplayLevel()const;
+   virtual long getAttachmentLevel()const;
+   
+   virtual long getNumberOfBands()const;
+   virtual long getNumberOfRows()const;
+   virtual long getNumberOfCols()const;
+   virtual long getNumberOfBlocksPerRow()const;
+   virtual long getNumberOfBlocksPerCol()const;
+   virtual long getNumberOfPixelsPerBlockHoriz()const;
+   virtual long getNumberOfPixelsPerBlockVert()const;
+   virtual ossimString getImageId()const;
+   virtual long        getBitsPerPixelPerBand()const;
+   virtual long        getActualBitsPerPixelPerBand()const;
+   virtual ossimString getIMode()const;
+   virtual ossim_uint64 getDataLocation()const;
+   virtual ossimString getSecurityClassification()const;
+   virtual ossimString getAcquisitionDateMonthDayYear(ossim_uint8 separationChar='-')const;
+   virtual ossimString getCategory()const;
+   virtual ossimString getImageSource()const;
+   virtual ossimString getRepresentation()const;
+   virtual ossimString getCoordinateSystem()const;
+   virtual ossimString getGeographicLocation()const;
+   virtual ossimString getPixelValueType()const;
+   virtual bool hasBlockMaskRecords()const;
+   virtual bool hasPadPixelMaskRecords()const;
+   virtual bool hasTransparentCode()const;
+   virtual ossim_uint32 getTransparentCode()const;
+   virtual ossim_uint32 getBlockMaskRecordOffset(ossim_uint32 blockNumber,
+                                                 ossim_uint32 bandNumber)const;
+   virtual ossim_uint32 getPadPixelMaskRecordOffset(ossim_uint32 blockNumber,
+                                                    ossim_uint32 bandNumber)const;
+   
+   virtual const ossimRefPtr<ossimNitfCompressionHeader> getCompressionHeader()const;
+   virtual const ossimRefPtr<ossimNitfImageBand> getBandInformation(ossim_uint32 idx)const;
+
+TYPE_DATA
+private:
+   //
+   
+   void clearFields();
+   /*!
+    * Is a required 2 byte value and is IM.
+    */
+   char theType[3];
+
+   /*!
+    * Is a required 10 Alphanumeric value.
+    */
+   char theImageId[11];
+
+   /*!
+    * Contains the time of acquisition of the image.
+    * this is a 14 byte field and has the format:
+    *
+    * DDHHMMSSZMONYY
+    *
+    * DD   is the day of the month
+    * HH   is the Hour
+    * MM   is the minutes
+    * SS   is the seconds
+    * Z    is fixed (Zulu time)
+    * MON  is the first 3 chars of the month
+    * YY   is the year
+    */
+   char theDateTime[15];
+
+   /*!
+    * is a 17 byte field.  Has the form
+    *
+    * BBBBBBBBBBFFFFFCC
+    *
+    * where:
+    *
+    * B     is the encyclopedia id
+    * F     is the functional category code
+    * C     is the country code.
+    */
+   char theTargetId[18];
+
+   /*!
+    * Is 80 bytes and contains the title
+    */
+   char theTitle[81];
+
+   /*!
+    * Is a required 1 byte field and has value:
+    *
+    * T    = Top secret
+    * S    = Secrect
+    * C    = confidential
+    * R    = Restricted
+    * U    = Unclassified
+    */
+   char theSecurityClassification[2];
+
+   /*!
+    * is a 40 byte field
+    */
+   char theCodewords[41];
+
+   /*!
+    * is a 40 byte field
+    */
+   char theControlAndHandling[41];
+
+   /*!
+    * Is a 40 byte field.
+    */
+   char theReleasingInstructions[41];
+
+   /*!
+    * Is a 20 byte field
+    */
+   char theClassificationAuthority[21];
+
+   /*!
+    *
+    */
+   char theSecurityControlNumber[21];
+
+   /*!
+    * Is a 6 byte field with form:
+    *
+    *  YYMMDD.  Year month day
+    *
+    * 999999 indicates that he Originating
+    *        agencies determination is required
+    *        (OADR)
+    * 999998 downgrade event will specify at what
+    *        point and time the declassification
+    *        or downgrading is to take place.
+    */
+   char theSecurityDowngrade[7];
+
+   /*!
+    * This is a conditional field and is present
+    * if the Security downgrade is 999998.
+    */
+   char theDowngradingEvent[41];
+
+   /*!
+    * Is arequired 1 byte field.
+    *
+    * 0  = no encryption
+    * 1  = encryption
+    */
+   char theEncryption[2];
+
+   /*!
+    * Is a 42 byte optional field.
+    */
+   char theImageSource[43];
+
+   /*!
+    * Required 8 byte number 0-99999999
+    */
+   char theSignificantRows[9];
+
+   /*!
+    * Required 8 byte number 0-99999999
+    */
+   char theSignificantCols[9];
+
+   /*!
+    * Required 3 byte value.
+    * Values:
+    *
+    * INT   integer 16 bits
+    * SI    singend 16 bit integer
+    * R     32 bit float
+    * C     for complex (32 bit float real part, 32 bit float imag part)
+    * B     for bitmapped image represented as single bits 1 or 0
+    * U     for user defined.
+    */
+   char thePixelValueType[4];
+
+   /*!
+    * This is required 8 byte field.
+    *
+    * Values:
+    *
+    * MONO    indicates monochrome
+    * RGB     indicates true color red green blue
+    * RGB/LUT indicates RGB lookup table.
+    * MULTI   indicates multiband imgery
+    * YCbCr601 indicates compressed in CCIR 601
+    *          color space using JPEG (field IC=C3)
+    */
+   char theRepresentation[9];
+
+   /*!
+    * This is a required 8 byte field.  Contains info
+    * about the specific category of the image.
+    *
+    * VIS    indicates visible imagery
+    * MAP    indicates maps
+    * SAR    indicates Synthetic Aperture Radar
+    * IR     indicates infrared.
+    * MS     indicates multispectral
+    * FP     indicates fingerprints
+    * MRI    indicates Magnetic Resonance imagery
+    * XRAY   indicates x-rays
+    * CAT    indicates cat scans
+    *
+    * default value is VIS
+    */
+   char theCategory[9];
+
+   /*!
+    * Is optional and indicates the number of
+    * bits per band 01-64
+    */
+   char theBitsPerPixelPerBand[3];
+
+   /*!
+    * Is 1 byte optional field.  Can have
+    * values L (left) or R (right).  Any other value
+    * is to interpreted as right justified.
+    *
+    * This indicates how the significant bits are justified
+    * in the field
+    */
+   char theJustification[2];
+
+   /*!
+    * Is a 1 byte required field and can have
+    * values U, G, C, or N
+    *
+    * U indicates UTM
+    * G indicates Geodetic (Geographic)
+    * C indicates Geocentric
+    * N indicates None
+    */
+   char theCoordinateSystem[2];
+
+   /*!
+    * This is a conditional field.  If theCoordinateSystem
+    * is N then it does not exist.  If it's any other
+    * value then it's given in image coordinate order
+    *
+    * (0,0) (0,MaxCol) (MaxRow, MaxCol) (MaxRow, 0)
+    *
+    * if its geodetic or geocentric it will have a lat lon coordinate
+    * with each coordinate as:
+    * Lat = ddmmssX
+    *       where d is degrees and m is minutes
+    *       and s is seconds and X is either N (North) or S (South).
+    * Lon = dddmmssX
+    *       where d is degrees and m is minutes
+    *       and s is seconds and X is either N (North) or S (South).
+    * if its a U the the coordinates are expressed in a UTM grid coord
+    * which is also known as (Military Grid Reference System).
+    */
+   char theGeographicLocation[61];
+
+   /*!
+    * this is a required 1 byte field and indicates the number of comments.
+    */
+   char theNumberOfComments[2];
+
+   /*!
+    * Dynamic buffer for the comments.  Each comment is 80 bytes
+    */
+   char *theImageComments;
+
+   /*!
+    * This is a required 2 byte field and indicates the compression
+    * type of the image.
+    *
+    * C1  indicates bi-level
+    * C2  indicates ARIDPCM
+    * C3  inidates JPEG
+    * C4  inidcates Vector Quantization
+    * NC  indicates not compressed
+    * M0  indicates compressed images
+    * M3  indicates compressed images
+    * M4  indicates compressed images
+    * NM  indicates uncompressed
+    *
+    * The M's and NM are blocked images that contain
+    * block mask and/or transparent pixel mask.  There
+    * will be an Image Data Mask Subheader at the beginning
+    * of the image data area.
+    *
+    * Compression C1 and C2 will not exist if the Number of bands
+    * is > 1 or NBLOCKS > 1
+    *
+    */
+   char theCompression[3];
+
+   /*!
+    * This is a conditional field.  if theCompression is
+    * not equal to NC then this field exists.
+    */
+   char theCompressionRateCode[5];
+
+   /*!
+    * Is required 1 byte field  and will have value 1-9
+    *
+    * If theRepresentation is MONO this should be 1
+    * if theRepresentation is RGB  this should be 3
+    * if theRepresentation is RGB/LUT this should be 1
+    * if theRepresentation YCbCr601 this should be 3
+    * if theRepresentation is MULTI this should be 2-9
+    */
+   char theNumberOfBands[2];
+
+   std::vector<ossimRefPtr<ossimNitfImageBandV2_0> > theImageBands;
+
+   /*!
+    * Required 1 byte field.  Has value 0 or 4
+    */
+   char theImageSyncCode[2];
+
+   /*!
+    * Required 1 byte field. Has value B, P, or S
+    * For uncompressed images:
+    * B = Interleaved by block
+    * P = Interleaved by pixel
+    * S = Band sequential
+    */
+   char theImageMode[2];
+
+   /*!
+    * Required 4 byte value.  ranges from
+    * 1-9999
+    */
+    char theNumberOfBlocksPerRow[5];
+
+   /*!
+    * Required 4 byte value. Ranges from
+    * 1-9999
+    */
+   char theNumberOfBlocksPerCol[5];
+
+   /*!
+    * Reuqired 4 byte field
+    */
+   char theNumberOfPixelsPerBlockHoriz[5];
+
+   /*!
+    * Reuqired 4 byte field
+    */
+   char theNumberOfPixelsPerBlockVert[5];
+
+   /*!
+    * Required 2 byte field.
+    */
+   char theNumberOfBitsPerPixelPerBand[3];
+
+   /*!
+    * Required 3 byte field.
+    */
+   char theDisplayLevel[4];
+
+   /*!
+    * Required 3 byte field
+    */
+   char theAttachmentLevel[4];
+
+   /*!
+    * Required 10 byte field. Has the form
+    * rrrrrccccc  where r is row and c is column
+    */
+   char theImageLocation[11];
+
+   /*!
+    * Required 4 byte field
+    */
+   char theImageMagnification[5];
+
+   /*!
+    * Required 5 byte field.
+    */
+   char theUserDefinedImageDataLength[6];
+
+   /*!
+    * conditional 3 byte field. if theUserDefinedImageDataLength
+    * is not 0 
+    */
+   char theUserDefinedOverflow[4];
+
+   /*!
+    * Is a required 5 byte field. 0-99999
+    */
+   char theExtendedSubheaderDataLen[6];
+
+   /*!
+    * Is a conditional 3 byte field.  This depends on
+    * theExtendedSubheaderDataLen not being 0.
+    */
+   char theExtendedSubheaderOverflow[4];
+
+   /*******************************************************************************
+    *                    THIS IS THE MASK TABLE IF PRESENT
+    *
+    */
+   
+   /**
+    * FIELD NAME: IMDATOFF
+    * 
+    * Blocked Image Data Offset.
+    * 
+    * 4 byte Binary integer: 0x00000000 to 0xFFFFFFFF
+    * 
+    * This field is included if the IC value equals NM, M0, M3, or M4.
+    * It identifies the offset from the beginning of the Image Data Mask Subheader
+    * to the first byte of the blocked image data. This offset, when used in combination
+    * with the offsets provided in the BMR fields, can provide random access to any recorded
+    * image block in any image band.
+    * 
+    */
+   ossim_uint32 theBlockedImageDataOffset;
+
+   /**
+    * FIELD NAME: BMRLNTH
+    *
+    * Block Mask Record Length.
+    *
+    * 2 byte Unsigned binary integer
+    * 0x0000=No Block mask record; 0x0004=Block mask
+    * records (4 bytes each) are present  
+    * 
+    * This field is included if the IC value equals NM, M0, M3, or M4.
+    * It identifies the length of each Block Mask Record in bytes. The total
+    * length of the Block Mask Records is equal to BMRLNTH x NBPR x NBPC x NBANDS if the IMODE is S and
+    * BMRLNTH x NBPR x NBPC otherwise. If all of the image blocks are recorded,
+    * this value is set to 0, and the conditional BMR fields are not recorded/transmitted.
+    * If this field is present, but coded as 0, then a transparent pixel mask is included. 
+    *
+    */
+   ossim_uint16 theBlockMaskRecordLength;
+
+   /**
+    * FIELD: TMRLNTH
+    *
+    * Pad Pixel Mask Record Length.
+    *
+    * 2 byte Unsigned binary integer a value of
+    * 0x0000=No Pad pixel mask records and 
+    * 0x0004=Pad pixel mask records (4 bytes each) are present
+    * 
+    * This field is included if the IC value equals NM, M0, M3, or M4.
+    * It identifies the length of each Transparent Pixel Mask Record in bytes.
+    * The total length of the Transparent Pixel Mask Records is equal to
+    * TMRLNTH x NBPR x NBPC x NBANDS when IMODE is S and TMRLNTH x NBPR x NBPC otherwise.
+    * If none of the image blocks contain transparent pixels, this value is set to 0,
+    * and the conditional TMR fields are not recorded/transmitted. For IC value of M3,
+    * the value is set to 0. If this field is present, but coded as 0, then a Block Mask is included.
+    */
+   ossim_uint16 thePadPixelMaskRecordLength;
+   
+   /**
+    *  FIELD: TPXCDLNTH
+    *
+    *  Transparent Output Pixel Code Length.
+    *
+    *  2 byte Unsigned binary integer;
+    *  0x0000=No pad pixels; 0x0001 to 0x0010=pad pixel code length in bits
+    *  
+    *  This field is included if the IC value equals NM, M0, M3, or M4.
+    *  It identifies the length in bits of the Transparent Output Pixel Code.
+    *  If coded as 0, then no transparent pixels are present,
+    *  and the TPXCD field is not recorded. For IC value of M3, the value is set to 0.
+    */
+   ossim_uint16 theTransparentOutputPixelCodeLength;
+
+
+   /**
+    * FIELD: TPXCD
+    *
+    * Pad Output Pixel Code.
+    *
+    * This field is included if the IC value equals NM, M0, or M4, and
+    * TPXCDLNTH is not 0. It contains the output pixel code
+    * that represents a transparent pixel in the image. This
+    * value is unique within the image, and allows the user to
+    * identify transparent pixels. The transparent pixel output code
+    * length is determined by TPXCDLNTH, but the value is stored in two bytes.
+    * If the number of bits used by TPXCD is less than the number of
+    * bits available for storage, the value shall be justified in
+    * accordance with the PJUST field in the image subheader.
+    */
+   ossim_uint16 thePadOutputPixelCode;
+   std::vector<ossim_uint32> theBlockMaskRecords;
+   std::vector<ossim_uint32> thePadPixelMaskRecords;
+
+   ossimRefPtr<ossimNitfCompressionHeader> theCompressionHeader;
+   ossim_uint64 theDataLocation;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_1.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_1.cpp
new file mode 100644
index 0000000000..b0b8fd6c30
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_1.cpp
@@ -0,0 +1,2222 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL
+//
+// See top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// 
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageHeaderV2_1.cpp,v 1.44 2005/11/19 00:34:14 dburken Exp $
+#include <sstream>
+#include <iomanip>
+#include <support_data/nitf/ossimNitfImageHeaderV2_1.h>
+#include <base/common/ossimTrace.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimDms.h>
+#include <base/property/ossimStringProperty.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/misc/ossimEndian.h>
+#include <cstring> //for memset
+#include <support_data/nitf/ossimNitfVqCompressionHeader.h>
+
+#ifndef NULL
+#include <cstddef>
+#endif
+
+RTTI_DEF1(ossimNitfImageHeaderV2_1,
+          "ossimNitfImageHeaderV2_1",
+          ossimNitfImageHeader)
+
+static const char* IID1_KW = "iid1";
+static const char* IDATIM_KW = "idatim";
+static const char* TGTID_KW = "tgtid";
+static const char* IID2_KW = "iid2";
+static const char* ISCLAS_KW = "isclas";
+static const char* ISCLSY_KW = "isclsy";
+static const char* ISCODE_KW = "iscode";
+static const char* ISCTLH_KW = "isctlh";
+static const char* ISREL_KW = "isrel";
+static const char* ISDCTP_KW = "isdctp";
+static const char* ISDCDT_KW = "isdcdt";
+static const char* ISDCXM_KW = "isdcxm";
+static const char* ISDG_KW = "isdg";
+static const char* ISDGDT_KW = "isdgdt";
+static const char* ISCLTX_KW = "iscltx";
+static const char* ISCATP_KW = "iscatp";
+static const char* ISCAUT_KW = "iscaut";
+static const char* ISCRSN_KW = "iscrsn";
+static const char* ISSRDT_KW = "issrdt";
+static const char* ISCTLN_KW = "isctln";
+static const char* ENCRYP_KW = "encryp";
+static const char* ISORCE_KW = "isorce";
+// static const char* NROWS_KW = "nrows";
+// static const char* NCOLS_KW = "ncols";
+static const char* PVTYPE_KW = "pvtype";
+static const char* IREP_KW = "irep";
+static const char* ICAT_KW = "icat";
+static const char* ABPP_KW = "abpp";
+static const char* PJUST_KW = "pjust";
+static const char* ICORDS_KW = "icords";
+static const char* IGEOLO_KW = "igeolo";
+static const char* NICOM_KW = "nicom";
+static const char* IC_KW = "ic";
+static const char* COMRAT_KW = "comrat";
+static const char* NBANDS_KW = "nbands";
+static const char* XBANDS_KW = "xbands";
+static const char* ISYNC_KW = "isync";
+static const char* IMODE_KW = "imode";
+static const char* NBPR_KW = "nbpr";
+static const char* NBPC_KW = "nbpc";
+static const char* NPPBH_KW = "nppbh";
+static const char* NPPBV_KW = "nppbv";
+static const char* NBPP_KW = "nbpp";
+static const char* IDLVL_KW = "idlvl";
+static const char* IALVL_KW = "ialvl";
+static const char* ILOC_KW = "iloc";
+static const char* IMAG_KW = "imag";
+// static const char* UDIDL_KW = "udidl";
+
+static const
+ossimTrace traceDebug(ossimString("ossimNitfImageHeaderV2_1:debug"));
+
+ossimNitfImageHeaderV2_1::ossimNitfImageHeaderV2_1()
+{
+   clearFields();
+}
+ossimNitfImageHeaderV2_1::~ossimNitfImageHeaderV2_1()
+{
+}
+
+void ossimNitfImageHeaderV2_1::parseStream(std::istream &in)
+{
+   if (!in)
+   {
+      return;
+   }
+   clearFields();
+   theTagList.clear();
+   in.read(theType, 2);
+   in.read(theImageId, 10);
+   in.read(theDateTime,14);
+   in.read(theTargetId, 17);
+   in.read(theTitle, 80);
+   in.read(theSecurityClassification, 1);
+   in.read(theSecurityClassificationSys, 2);
+   in.read(theCodewords, 11);
+   in.read(theControlAndHandling, 2);
+   in.read(theReleasingInstructions, 20);
+   in.read(theDeclassificationType, 2);
+   in.read(theDeclassificationDate, 8);
+   in.read(theDeclassificationExempt, 4);
+   in.read(theDowngrade, 1);
+   in.read(theDowngradeDate, 8);
+   in.read(theClassificationText, 43);
+   in.read(theClassificationAuthType, 1);
+   in.read(theClassificationAuthority, 40);
+   in.read(theClassificationReason, 1);
+   in.read(theSecuritySourceDate, 8);
+   in.read(theSecurityControlNumber, 15);
+   in.read(theEncryption, 1);
+   in.read(theImageSource, 42);
+   in.read(theSignificantRows, 8);
+   in.read(theSignificantCols, 8);
+   in.read(thePixelValueType, 3);
+   in.read(theRepresentation, 8);
+   in.read(theCategory, 8);
+   in.read(theActualBitsPerPixelPerBand, 2);
+   in.read(theJustification, 1);
+   in.read(theCoordinateSystem, 1);
+   // if it's not blank then read coordinates
+   if(theCoordinateSystem[0] != ' ')
+   {
+      in.read(theGeographicLocation, 60);
+   }
+   in.read(theNumberOfComments, 1);
+   long numberOfComments = ossimString(theNumberOfComments).toLong();
+   
+   // for now just ignore the comments
+   if(numberOfComments > 0)
+   {
+      in.ignore(numberOfComments*80);
+   }
+   in.read(theCompression, 2);
+   
+   // only need the Rate code if its not
+   // NC (No compression)
+   ossimString temp = theCompression;
+   if((temp != "NC") &&
+      (temp != "NM"))
+   {
+      in.read(theCompressionRateCode, 4);
+   }
+   in.read(theNumberOfBands, 1);
+   // check to see if multi spectral bands
+   // exceed 9.  A value of 0 indicates this
+   long numberOfBands = ossimString(theNumberOfBands).toLong();
+   if (numberOfBands == 0)
+   {
+      in.read(theNumberOfMultispectralBands, 5);
+      numberOfBands = ossimString(theNumberOfMultispectralBands).toLong();
+   }
+   theImageBands.clear();
+   theImageBands.resize(numberOfBands);
+   for (long band = 0; band < numberOfBands; ++band)
+   {
+      theImageBands[band] = new ossimNitfImageBandV2_1;
+      theImageBands[band]->parseStream(in);
+   }
+   in.read(theImageSyncCode, 1);
+   in.read(theImageMode, 1);
+   in.read(theNumberOfBlocksPerRow, 4);
+   in.read(theNumberOfBlocksPerCol, 4);
+   in.read(theNumberOfPixelsPerBlockHoriz, 4);
+   in.read(theNumberOfPixelsPerBlockVert, 4);
+   in.read(theNumberOfBitsPerPixelPerBand, 2);
+   in.read(theDisplayLevel, 3);
+   in.read(theAttachmentLevel, 3);
+   in.read(theImageLocation, 10);
+   in.read(theImageMagnification, 4);
+   in.read(theUserDefinedImageDataLength, 5);
+   
+   ossimNitfTagInformation         headerTag;
+   std::streampos start   = in.tellg();
+   std::streampos current = in.tellg();
+   
+   std::streampos userDefinedDataLen
+      = ossimString(theUserDefinedImageDataLength).toLong();
+   if(userDefinedDataLen > 0)
+   {
+      in.read(theUserDefinedOverflow, 3);
+      while((current - start) < userDefinedDataLen)
+      {
+         headerTag.parseStream(in);
+         theTagList.push_back(headerTag);
+         in.ignore(headerTag.getTagLength());
+         headerTag.clearFields();
+         current = in.tellg();
+      }
+      in.seekg(start + userDefinedDataLen);
+   }
+   in.read(theExtendedSubheaderDataLen, 5);
+   std::streampos extSubHeadLen = ossimString(theExtendedSubheaderDataLen).toLong();
+   start   = in.tellg();
+   current = in.tellg();
+   if(extSubHeadLen > 0)
+   {
+      in.read(theExtendedSubheaderOverflow, 3);
+      while((current - start) < extSubHeadLen)
+      {
+         headerTag.parseStream(in);
+         theTagList.push_back(headerTag);
+         
+         in.ignore(headerTag.getTagLength());
+         headerTag.clearFields();
+         current = in.tellg();
+      }
+      in.seekg(start + extSubHeadLen);
+   }
+   ossimString compressionType = theCompression;
+   compressionType = compressionType.trim().upcase();
+   ossimEndian endian;
+   if((compressionType == "NM")||
+      (compressionType == "M1")||
+      (compressionType == "M3")||
+      (compressionType == "M4")||
+      (compressionType == "M5"))
+   {
+      ossim_uint64 locationBefore = in.tellg();
+      in.read((char*)(&theBlockedImageDataOffset), 4);
+      in.read((char*)(&theBlockMaskRecordLength),2);
+      in.read((char*)(&thePadPixelMaskRecordLength), 2);
+      in.read((char*)(&theTransparentOutputPixelCodeLength), 2);
+
+      
+      if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+      {
+         endian.swap(theBlockedImageDataOffset);
+         endian.swap(theBlockMaskRecordLength);
+         endian.swap(thePadPixelMaskRecordLength);
+         endian.swap(theTransparentOutputPixelCodeLength);
+      }
+      if(theTransparentOutputPixelCodeLength <9)
+      {
+         if(theTransparentOutputPixelCodeLength != 0)
+         {
+            ossim_uint8 padOutputPixelCode;
+            in.read((char*)(&padOutputPixelCode), 1);
+            thePadOutputPixelCode = padOutputPixelCode;
+         }
+      }
+      else
+      {
+         in.read((char*)(&thePadOutputPixelCode), 2);
+         if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+         {
+            endian.swap(thePadOutputPixelCode);
+         }
+         // I need to add code here to check for justification when its 2 bytes
+         // but the code length is less than 16 bits.
+         //
+      }
+      if(theBlockMaskRecordLength>0)
+      {
+         ossim_uint32 totalNumber = 0;
+         if((theImageMode[0] == 'S'))
+         {
+             totalNumber = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol()*getNumberOfBands();
+         }
+         else
+         {
+            totalNumber = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol();
+         }
+         ossim_uint32 *blockRead = new ossim_uint32[totalNumber];
+         ossim_uint32 idx = 0;
+         theBlockMaskRecords.resize(totalNumber);
+         in.read((char*)(blockRead), totalNumber*4);
+         for(idx = 0; idx < totalNumber; ++idx)
+         {
+            if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+            {
+               endian.swap(blockRead[idx]);
+            }
+            theBlockMaskRecords[idx] = blockRead[idx];
+         }
+      }
+      if((thePadPixelMaskRecordLength > 0)||
+         (( (getCompressionCode().upcase() == "M3"))&&
+          (thePadPixelMaskRecordLength == 0)))
+      {
+         ossim_uint32 totalNumber = 0;
+         if((theImageMode[0] == 'S'))
+         {
+            totalNumber = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol()*getNumberOfBands();
+         }
+         else
+         {
+            totalNumber = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol();
+         }
+         ossim_uint32 *blockRead = new ossim_uint32[totalNumber];
+         ossim_uint32 idx = 0;
+         thePadPixelMaskRecords.resize(totalNumber);
+         in.read((char*)(blockRead), totalNumber*4);
+         for(idx = 0; idx < totalNumber; ++idx)
+         {
+            if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+            {
+               endian.swap(blockRead[idx]);
+            }
+            thePadPixelMaskRecords[idx] = blockRead[idx];
+         }
+         delete [] blockRead;
+      }
+      theCompressionHeader = 0;
+      if((getCompressionCode() == "C4")||
+         (getCompressionCode() == "M4"))
+      {
+         ossimRefPtr<ossimNitfVqCompressionHeader> compressionHeader = new ossimNitfVqCompressionHeader;
+         compressionHeader->parseStream(in);
+         // do a check to see if the compression header is good
+         //
+         if(compressionHeader->getCompressionAlgorithmId()!= 1)
+         {
+            compressionHeader = 0;
+         }
+         theCompressionHeader = compressionHeader.get();
+      }
+      
+      ossim_uint64 delta = (ossim_uint64)in.tellg() - locationBefore;
+      if(delta < theBlockedImageDataOffset)
+      {
+         in.ignore(theBlockedImageDataOffset-delta);
+      }
+   }
+   //***
+   // The stream should now be at the start of the data location so capture
+   // it.
+   //***
+   theDataLocation = in.tellg();
+}
+
+void ossimNitfImageHeaderV2_1::writeStream(std::ostream &out)
+{
+   out.write(theType, 2);
+   out.write(theImageId, 10);
+   out.write(theDateTime,14);
+   out.write(theTargetId, 17);
+   out.write(theTitle, 80);
+   out.write(theSecurityClassification, 1);
+   out.write(theSecurityClassificationSys, 2);
+   out.write(theCodewords, 11);
+   out.write(theControlAndHandling, 2);
+   out.write(theReleasingInstructions, 20);
+   out.write(theDeclassificationType, 2);
+   out.write(theDeclassificationDate, 8);
+   out.write(theDeclassificationExempt, 4);
+   out.write(theDowngrade, 1);
+   out.write(theDowngradeDate, 8);
+   out.write(theClassificationText, 43);
+   out.write(theClassificationAuthType, 1);
+   out.write(theClassificationAuthority, 40);
+   out.write(theClassificationReason, 1);
+   out.write(theSecuritySourceDate, 8);
+   out.write(theSecurityControlNumber, 15);
+   out.write(theEncryption, 1);
+   out.write(theImageSource, 42);
+   out.write(theSignificantRows, 8);
+   out.write(theSignificantCols, 8);
+   out.write(thePixelValueType, 3);
+   out.write(theRepresentation, 8);
+   out.write(theCategory, 8);
+   out.write(theActualBitsPerPixelPerBand, 2);
+   out.write(theJustification, 1);
+   out.write(theCoordinateSystem, 1);
+   
+   if(theCoordinateSystem[0] != ' ')
+   {
+      out.write(theGeographicLocation, 60);
+   }
+   // for now force the number of comments to be 0
+//   out.write(theNumberOfComments, 1);
+   out.write("0", 1);
+   
+   out.write(theCompression, 2);
+   ossimString compressionTest = theCompression;
+   if(compressionTest != "NC" &&
+      compressionTest != "NM")
+     {
+      out.write(theCompressionRateCode, 4);
+     }
+
+   out.write(theNumberOfBands, 1);
+
+   if(ossimString(theNumberOfBands).toLong() == 0)
+   {
+      out.write(theNumberOfMultispectralBands, 5);
+   }
+
+   if(theImageBands.size())
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < theImageBands.size(); ++idx)
+      {
+         theImageBands[idx]->writeStream(out);
+      }
+   }
+
+   out.write(theImageSyncCode, 1);
+   out.write(theImageMode, 1);
+   out.write(theNumberOfBlocksPerRow, 4);
+   out.write(theNumberOfBlocksPerCol, 4);
+   out.write(theNumberOfPixelsPerBlockHoriz, 4);
+   out.write(theNumberOfPixelsPerBlockVert, 4);
+   out.write(theNumberOfBitsPerPixelPerBand, 2);
+   out.write(theDisplayLevel, 3);
+   out.write(theAttachmentLevel, 3);
+   out.write(theImageLocation, 10);
+   out.write(theImageMagnification, 4);
+   out.write(theUserDefinedImageDataLength, 5);
+
+   if(ossimString(theUserDefinedImageDataLength).toLong() > 0)
+   {
+      out.write(theUserDefinedOverflow, 3);
+   }
+
+   // need to ouput tagged data
+   // here
+   //
+   ossim_uint32 totalLength = getTotalTagLength();
+
+   totalLength += 3; // per Table A-3 of MIL-STD-2500B
+
+   if(totalLength <= 99999)
+   {
+      std::ostringstream tempOut;
+
+      tempOut << std::setw(5)
+              << std::setfill('0')
+              << std::setiosflags(ios::right)
+              << totalLength;
+      
+      memcpy(theExtendedSubheaderDataLen, tempOut.str().c_str(), 5);
+
+      out.write(theExtendedSubheaderDataLen, 5);
+      memset(theExtendedSubheaderOverflow, '0', 3);
+
+      if(totalLength > 0)
+      {
+         out.write(theExtendedSubheaderOverflow, 3);
+         
+         ossim_uint32 i = 0;
+         
+         for(i = 0; i < theTagList.size(); ++i)
+         {
+            theTagList[i].writeStream(out);
+         }
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimNitfFileHeaderV2_1::writeStream: Only support writing of total tag length < 99999" << std::endl;
+   }
+}
+
+std::ostream& ossimNitfImageHeaderV2_1::print(std::ostream& out)const
+{
+   out << "theType:                       " << theType
+       << "\ntheImageId:                    " << theImageId
+       << "\ntheDateTime:                   " << theDateTime
+       << "\ntheTargetId:                   " << theTargetId
+       << "\ntheTitle:                      " << theTitle
+       << "\ntheSecurityClassification:     " << theSecurityClassification
+       << "\ntheSecurityClassificationSys:  " << theSecurityClassificationSys
+       << "\ntheCodewords:                  " << theCodewords
+       << "\ntheControlAndHandling:         " << theControlAndHandling
+       << "\ntheReleasingInstructions:      " << theReleasingInstructions
+       << "\ntheDeclassificationType:       " << theDeclassificationType
+       << "\ntheDeclassificationDate:       " << theDeclassificationDate
+       << "\ntheDeclassificationExempt:     " << theDeclassificationExempt
+       << "\ntheDowngrade:                  " << theDowngrade
+       << "\ntheDowngradeDate:              " << theDowngradeDate
+       << "\ntheClassificationText:         " << theClassificationText
+       << "\ntheClassificationAuthType:     " << theClassificationAuthType
+       << "\ntheClassificationAuthority:    " << theClassificationAuthority
+       << "\ntheClassificationReason:       " << theClassificationReason
+       << "\ntheSecuritySourceDate:         " << theSecuritySourceDate
+       << "\ntheSecurityControlNumber:      " << theSecurityControlNumber
+       << "\ntheEncryption:                 " << theEncryption
+       << "\ntheImageSource:                " << theImageSource
+       << "\ntheSignificantRows:            " << theSignificantRows
+       << "\ntheSignificantCols:            " << theSignificantCols
+       << "\nthePixelValueType:             " << thePixelValueType
+       << "\ntheRepresentation:             " << theRepresentation
+       << "\ntheCategory:                   " << theCategory
+       << "\ntheActualBitsPerPixelPerBand:        " << theActualBitsPerPixelPerBand
+       << "\ntheJustification:              " << theJustification
+       << "\ntheCoordinateSystem:           " << theCoordinateSystem
+       << "\ntheGeographicLocation:         " << theGeographicLocation
+       << "\ntheNumberOfComments:           " << theNumberOfComments
+       << "\ntheCompression:                " << theCompression
+       << "\ntheCompressionRateCode:        " << theCompressionRateCode
+       << "\ntheNumberOfBands:              " << theNumberOfBands
+       << "\ntheNumberOfMultispectralBands: " << theNumberOfMultispectralBands
+       << endl;
+   
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theImageBands.size(); ++idx)
+   {
+      if(theImageBands[idx].valid())
+      {
+         out << *theImageBands[idx] << std::endl;
+      }
+   }
+   if(theImageBands.size() < 2)
+   {
+      out << endl;
+   }
+
+   out << "theImageSyncCode:               " << theImageSyncCode
+       << "\ntheImageMode:                   " << theImageMode
+       << "\ntheNumberOfBlocksPerRow:        " << theNumberOfBlocksPerRow
+       << "\ntheNumberOfBlocksPerCol:        " << theNumberOfBlocksPerCol
+       << "\ntheNumberOfPixelsPerBlockHoriz: "
+       << theNumberOfPixelsPerBlockHoriz
+       << "\ntheNumberOfPixelsPerBlockVert:  "
+       << theNumberOfPixelsPerBlockVert
+       << "\ntheNumberOfBitsPerPixelPerBand: "
+       << theNumberOfBitsPerPixelPerBand
+       << "\ntheDisplayLevel:                " << theDisplayLevel
+       << "\ntheAttachmentLevel:             " << theAttachmentLevel
+       << "\ntheImageLocation:               " << theImageLocation
+       << "\ntheImageMagnification:          " << theImageMagnification
+       << "\ntheUserDefinedImageDataLength:  " << theUserDefinedImageDataLength
+       << "\ntheUserDefinedOverflow:         " << theUserDefinedOverflow
+       << "\ntheExtendedSubheaderDataLen:    " << theExtendedSubheaderDataLen
+       << "\ntheExtendedSubheaderOverflow:   " << theExtendedSubheaderOverflow
+       << "\ntheDataLocation:                " << theDataLocation
+       << endl;
+
+   out << "theBlockedImageDataOffset:           "
+       << theBlockedImageDataOffset << std::endl
+       << "theBlockMaskRecordLength:            "
+       << theBlockMaskRecordLength << std::endl
+       << "thePadPixelMaskRecordLength:         "
+       << thePadPixelMaskRecordLength << std::endl
+       << "theTransparentOutputPixelCodeLength: "
+       << theTransparentOutputPixelCodeLength << std::endl
+       << "thePadOutputPixelCode:               "
+       << thePadOutputPixelCode << std::endl;
+      
+   printTags(out);
+   
+   return out;
+}
+
+bool ossimNitfImageHeaderV2_1::isCompressed()const
+{
+   ossimString temp = theCompression;
+   temp = temp.trim();
+   return ((temp != "NC") && (temp != "NM"));
+}
+
+bool ossimNitfImageHeaderV2_1::isEncrypted()const
+{
+   return (theEncryption[0] == '1');
+}
+
+
+ossimString ossimNitfImageHeaderV2_1::getCompressionCode()const
+{
+   return ossimString(theCompression).trim();
+}
+
+long ossimNitfImageHeaderV2_1::getDisplayLevel()const
+{
+   return ossimString(theDisplayLevel).toLong();
+}
+
+long ossimNitfImageHeaderV2_1::getAttachmentLevel()const
+{
+   return ossimString(theAttachmentLevel).toLong();
+}
+
+long ossimNitfImageHeaderV2_1::getNumberOfBands()const
+{
+   if(theNumberOfBands[0] == '0')
+   {
+      return ossimString(theNumberOfMultispectralBands).toLong();
+   }
+   else
+   {
+      return ossimString(theNumberOfBands).toLong();
+   }
+}
+
+long ossimNitfImageHeaderV2_1::getNumberOfRows()const
+{
+   return ossimString(theSignificantRows).toLong();
+}
+
+long ossimNitfImageHeaderV2_1::getNumberOfCols()const
+{
+   return ossimString(theSignificantCols).toLong();
+}
+
+ossimString ossimNitfImageHeaderV2_1::getImageId()const
+{
+   return theImageId;
+}
+
+long ossimNitfImageHeaderV2_1::getBitsPerPixelPerBand()const
+{
+   return ossimString(theNumberOfBitsPerPixelPerBand).toLong();
+}
+
+long ossimNitfImageHeaderV2_1::getActualBitsPerPixelPerBand()const
+{
+   return ossimString(theActualBitsPerPixelPerBand).toLong();
+}
+
+ossimString ossimNitfImageHeaderV2_1::getIMode() const
+{
+   return ossimString(theImageMode).trim();
+}
+
+ossimString ossimNitfImageHeaderV2_1::getSecurityClassification()const
+{
+   return theSecurityClassification;
+}
+
+ossimString ossimNitfImageHeaderV2_1::getAcquisitionDateMonthDayYear(ossim_uint8 separationChar)const
+{
+   ossimString result;
+
+   result += ossimString(theDateTime + 4,
+                         theDateTime + 6);
+   result += ossimString(separationChar);
+   result += ossimString(theDateTime + 6,
+                         theDateTime + 8);
+   result += ossimString(separationChar);
+   result += ossimString(theDateTime,
+                         theDateTime + 4);
+   
+   return result;
+}
+
+ossimString ossimNitfImageHeaderV2_1::getCategory()const
+{
+   return theCategory;
+}
+
+ossimString ossimNitfImageHeaderV2_1::getImageSource()const
+{
+   return theImageSource;
+}
+
+ossimString ossimNitfImageHeaderV2_1::getRepresentation()const
+{
+   return theRepresentation;
+}
+
+ossimString ossimNitfImageHeaderV2_1::getCoordinateSystem()const
+{
+	return theCoordinateSystem;
+}
+
+ossimString ossimNitfImageHeaderV2_1::getGeographicLocation()const
+{
+	return theGeographicLocation;
+}
+
+bool ossimNitfImageHeaderV2_1::hasBlockMaskRecords()const
+{
+   return (theBlockMaskRecords.size() > 0);
+}
+
+bool ossimNitfImageHeaderV2_1::hasPadPixelMaskRecords()const
+{
+   return (thePadPixelMaskRecords.size()>0);
+}
+
+bool ossimNitfImageHeaderV2_1::hasTransparentCode()const
+{
+   return (theTransparentOutputPixelCodeLength > 0);
+}
+
+ossim_uint32 ossimNitfImageHeaderV2_1::getTransparentCode()const
+{
+   return thePadOutputPixelCode;
+}
+
+ossim_uint32 ossimNitfImageHeaderV2_1::getBlockMaskRecordOffset(ossim_uint32 blockNumber,
+                                                                ossim_uint32 bandNumber)const
+{
+   ossim_uint32 maxBlock = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol();
+   ossim_uint32 result = 0xffffffff;
+   
+   if((hasBlockMaskRecords())&&
+      (blockNumber < maxBlock))
+   {
+      if(theImageMode[0] == 'S')
+      {
+         if(bandNumber < (ossim_uint32)getNumberOfBands())
+         {
+            result = theBlockMaskRecords[bandNumber*maxBlock + blockNumber];
+         }
+      }
+      else
+      {
+         result = theBlockMaskRecords[blockNumber];
+      }
+   }
+
+   return result;
+}
+
+ossim_uint32 ossimNitfImageHeaderV2_1::getPadPixelMaskRecordOffset(ossim_uint32 blockNumber,
+                                                                   ossim_uint32 bandNumber)const
+{
+   ossim_uint32 maxBlock = getNumberOfBlocksPerRow()*getNumberOfBlocksPerCol();
+   ossim_uint32 result = 0xffffffff;
+   
+   if((hasPadPixelMaskRecords())&&
+      (blockNumber < maxBlock))
+   {
+      if(theImageMode[0] == 'S')
+      {
+         if(bandNumber < (ossim_uint32)getNumberOfBands())
+         {
+            result = thePadPixelMaskRecords[bandNumber*maxBlock + blockNumber];
+         }
+      }
+      else
+      {
+         result = thePadPixelMaskRecords[blockNumber];
+      }
+   }
+
+   return result;
+}
+
+
+void ossimNitfImageHeaderV2_1::clearFields()
+{
+   memcpy(theType, "IM", 2);
+   memset(theImageId, ' ',10);
+   memset(theDateTime, ' ',14);
+   memset(theTargetId, ' ',17);
+   memset(theTitle, ' ',80);
+   memset(theSecurityClassification, ' ',1);
+   memset(theSecurityClassificationSys, ' ',2);
+   memset(theCodewords, ' ',11);
+   memset(theControlAndHandling, ' ',2);
+   memset(theReleasingInstructions, ' ',20);
+   memset(theDeclassificationType, ' ',2);
+   memset(theDeclassificationDate, ' ',8);
+   memset(theDeclassificationExempt, ' ',4);
+   memset(theDowngrade, ' ',1);
+   memset(theDowngradeDate, ' ',8);
+   memset(theClassificationText, ' ',43);
+   memset(theClassificationAuthType, ' ',1);
+   memset(theClassificationAuthority, ' ',40);
+   memset(theClassificationReason, ' ',1);
+   memset(theSecuritySourceDate, ' ',8);
+   memset(theSecurityControlNumber, ' ',15);
+   memset(theEncryption, '0',1);
+   memset(theImageSource, ' ',42);
+   memset(theSignificantRows, '0',8);
+   memset(theSignificantCols, '0',8);
+   memset(thePixelValueType, ' ',3);
+   memset(theRepresentation, ' ',8);
+   memset(theCategory, ' ',8);
+   memset(theActualBitsPerPixelPerBand, ' ',2);
+   memset(theJustification, ' ',1);
+   memset(theCoordinateSystem, ' ',1);
+   memset(theGeographicLocation, ' ',60);
+   memset(theNumberOfComments, '0', 1);
+   memcpy(theCompression, "NC",2);
+   memset(theCompressionRateCode, ' ',4);
+   memset(theNumberOfBands, '0',1);
+   memset(theNumberOfMultispectralBands, ' ',5);
+   memset(theImageSyncCode, '0', 1);
+   memset(theImageMode, 'B', 1);
+   memset(theNumberOfBlocksPerRow, '0', 4);
+   memset(theNumberOfBlocksPerCol, '0', 4);
+   memset(theNumberOfPixelsPerBlockHoriz, '0', 4);
+   memset(theNumberOfPixelsPerBlockVert, '0', 4);
+   memset(theNumberOfBitsPerPixelPerBand, '0', 2);
+   memcpy(theDisplayLevel, "001", 3);
+   memset(theAttachmentLevel, '0', 3);
+   memset(theImageLocation, '0', 10);
+   memcpy(theImageMagnification, "01.0", 4);
+   
+   memset(theUserDefinedImageDataLength,'0', 5);
+   memset(theUserDefinedOverflow, '0', 3);
+   memset(theExtendedSubheaderDataLen, '0', 5);
+   memset(theExtendedSubheaderOverflow, ' ', 3);
+   theBlockMaskRecords.clear();
+   thePadPixelMaskRecords.clear();
+
+   theBlockedImageDataOffset = 0;
+   theBlockMaskRecordLength = 0;
+   thePadPixelMaskRecordLength = 0;
+   theTransparentOutputPixelCodeLength = 0;
+   thePadOutputPixelCode = 0;
+   
+   theCompressionHeader = 0;
+   
+   theType[2] = '\0';
+   theImageId[10] = '\0';
+   theDateTime[14] = '\0';
+   theTargetId[17] = '\0';
+   theTitle[80] = '\0';
+   theSecurityClassification[1] = '\0';
+   theSecurityClassificationSys[2] = '\0';
+   theCodewords[11] = '\0';
+   theControlAndHandling[2] = '\0';
+   theReleasingInstructions[20] = '\0';
+   theDeclassificationType[2] = '\0';
+   theDeclassificationDate[8] = '\0';
+   theDeclassificationExempt[4] = '\0';
+   theDowngrade[1] = '\0';
+   theDowngradeDate[8] = '\0';
+   theClassificationText[43] = '\0';
+   theClassificationAuthType[1] = '\0';
+   theClassificationAuthority[40] = '\0';
+   theClassificationReason[1] = '\0';
+   theSecuritySourceDate[8] = '\0';
+   theSecurityControlNumber[15] = '\0';
+   theEncryption[1] = '\0';
+   theImageSource[42] = '\0';
+   theSignificantRows[8] = '\0';
+   theSignificantCols[8] = '\0';
+   thePixelValueType[3] = '\0';
+   theRepresentation[8] = '\0';
+   theCategory[8] = '\0';
+   theActualBitsPerPixelPerBand[2] = '\0';
+   theJustification[1] = '\0';
+   theCoordinateSystem[1] = '\0';
+   theGeographicLocation[60] = '\0';
+   theNumberOfComments[1] = '\0';
+   theCompression[2] = '\0';
+   theCompressionRateCode[4] = '\0';
+   theNumberOfBands[1] = '\0';
+   theNumberOfMultispectralBands[5] = '\0';
+   theImageSyncCode[1] = '\0';
+   theImageMode[1] = '\0';
+   theNumberOfBlocksPerRow[4] = '\0';
+   theNumberOfBlocksPerCol[4] = '\0';
+   theNumberOfPixelsPerBlockHoriz[4] = '\0';
+   theNumberOfPixelsPerBlockVert[4] = '\0';
+   theNumberOfBitsPerPixelPerBand[2] = '\0';
+   theDisplayLevel[3] = '\0';
+   theAttachmentLevel[3] = '\0';
+   theImageLocation[10] = '\0';
+   theImageMagnification[4] = '\0';
+   theUserDefinedImageDataLength[5] = '\0';
+   theUserDefinedOverflow[3] = '\0';
+   theExtendedSubheaderDataLen[5] = '\0';
+   theExtendedSubheaderOverflow[3] = '\0';
+   
+   theDataLocation = 0;
+}
+
+long ossimNitfImageHeaderV2_1::getNumberOfBlocksPerRow()const
+{
+   return ossimString(theNumberOfBlocksPerRow).toLong();
+}
+
+long ossimNitfImageHeaderV2_1::getNumberOfBlocksPerCol()const
+{
+   return ossimString(theNumberOfBlocksPerCol).toLong();
+}
+
+long ossimNitfImageHeaderV2_1::getNumberOfPixelsPerBlockHoriz()const
+{
+   return ossimString(theNumberOfPixelsPerBlockHoriz).toLong();
+}
+
+long ossimNitfImageHeaderV2_1::getNumberOfPixelsPerBlockVert()const
+{
+   return ossimString(theNumberOfPixelsPerBlockVert).toLong();
+}
+
+ossimDrect ossimNitfImageHeaderV2_1::getImageRect()const
+{
+   ossimDpt ul(ossimString((char*)(&theImageLocation[5])).toDouble(),
+               ossimString((char*)theImageLocation,
+                           (char*)(&theImageLocation[5])).toDouble());
+   
+    double rows = ossimString(theSignificantRows).toDouble();
+    double cols = ossimString(theSignificantCols).toDouble();
+
+    ossimDpt lr(ul.x + cols-1,
+                ul.y + rows-1);
+   
+    return ossimDrect(ul, lr);
+}
+
+ossimDrect ossimNitfImageHeaderV2_1::getBlockImageRect()const
+{
+   ossimDpt ul(ossimString((char*)(&theImageLocation[5])).toDouble(),
+               ossimString((char*)theImageLocation,
+                           (char*)(&theImageLocation[5])).toDouble());
+   
+   double rows = getNumberOfPixelsPerBlockVert()*getNumberOfBlocksPerCol();
+   double cols = getNumberOfPixelsPerBlockHoriz()*getNumberOfBlocksPerRow();;
+   
+   ossimDpt lr(ul.x + cols-1,
+               ul.y + rows-1);
+   
+    return ossimDrect(ul, lr);
+}
+
+ossimString ossimNitfImageHeaderV2_1::getPixelValueType()const
+{
+   return ossimString(thePixelValueType).trim();
+}
+
+void ossimNitfImageHeaderV2_1::setNumberOfBands(ossim_uint32 nbands)
+{
+   std::ostringstream out;
+
+   if(nbands > 9)
+   {
+      out << std::setw(5)
+          << std::setfill('0')
+          << std::setiosflags(ios::right)
+          << nbands;
+
+      theNumberOfBands[0] = '0';
+      memcpy(theNumberOfMultispectralBands, out.str().c_str(), 5);
+   }
+   else
+   {
+      out << nbands;
+      theNumberOfBands[0] = out.str().c_str()[0];
+   }
+
+   theImageBands.resize(getNumberOfBands());
+}
+
+void ossimNitfImageHeaderV2_1::setBandInfo(ossim_uint32 idx,
+                                           const ossimNitfImageBandV2_1& info)
+{
+   if(idx < theImageBands.size())
+   {
+      if(!theImageBands[idx].valid())
+      {
+         theImageBands[idx] = new ossimNitfImageBandV2_1;
+      }
+      (*theImageBands[idx]) = info;
+   }
+}
+
+void ossimNitfImageHeaderV2_1::setNumberOfRows(ossim_uint32 rows)
+{
+   std::ostringstream out;
+   if(rows > 99999999) rows = 99999999;
+   
+   out << std::setw(8)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << rows;
+
+   memcpy(theSignificantRows, out.str().c_str(), 8);
+}
+
+void ossimNitfImageHeaderV2_1::setNumberOfCols(ossim_uint32 cols)
+{
+   std::ostringstream out;
+   if(cols > 99999999) cols = 99999999;
+   
+   out << std::setw(8)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << cols;
+
+   memcpy(theSignificantCols, out.str().c_str(), 8);
+}
+
+void ossimNitfImageHeaderV2_1::setPixelType(const ossimString& pixelType)
+{
+   std::ostringstream out;
+   
+   out << std::setw(3)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << pixelType.c_str();
+
+   memcpy(thePixelValueType , out.str().c_str(), 3);
+}
+
+void ossimNitfImageHeaderV2_1::setBitsPerPixel(ossim_uint32 bitsPerPixel)
+{
+   std::ostringstream out;
+   
+   out << std::setw(2)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << bitsPerPixel;
+
+   memcpy(theNumberOfBitsPerPixelPerBand, out.str().c_str(), 2);
+}
+
+void ossimNitfImageHeaderV2_1::setActualBitsPerPixel(ossim_uint32 bitsPerPixel)
+{
+   std::ostringstream out;
+   
+   out << std::setw(2)
+       << std::setfill('0')
+       << std::setiosflags(ios::right) 
+       << bitsPerPixel;
+
+   memcpy(theActualBitsPerPixelPerBand, out.str().c_str(), 2);
+   
+}
+
+void ossimNitfImageHeaderV2_1::setImageMode(char mode)
+{
+   theImageMode[0] = mode;
+}
+
+void ossimNitfImageHeaderV2_1::setCategory(const ossimString& category)
+{
+   std::ostringstream out;
+   
+   out << std::setw(8)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << category.c_str();
+
+   memcpy(theCategory, out.str().c_str(), 8); 
+}
+
+void ossimNitfImageHeaderV2_1::setRepresentation(const ossimString& rep)
+{
+   std::ostringstream out;
+   
+   out << std::setw(8)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << rep.c_str();
+
+   memcpy(theRepresentation, out.str().c_str(), 8); 
+}
+
+void ossimNitfImageHeaderV2_1::setBlocksPerRow(ossim_uint32 blocks)
+{
+   std::ostringstream out;
+   
+   out << std::setw(4)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << blocks;
+
+   memcpy(theNumberOfBlocksPerRow, out.str().c_str(), 4);
+}
+
+void ossimNitfImageHeaderV2_1::setBlocksPerCol(ossim_uint32 blocks)
+{
+   std::ostringstream out;
+   
+   out << std::setw(4)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << blocks;
+   
+   memcpy(theNumberOfBlocksPerCol, out.str().c_str(), 4);
+}
+
+void ossimNitfImageHeaderV2_1::setNumberOfPixelsPerBlockRow(ossim_uint32 pixels)
+{
+   std::ostringstream out;
+   
+   out << std::setw(4)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << pixels;
+   
+   memcpy(theNumberOfPixelsPerBlockHoriz, out.str().c_str(), 4);
+}
+
+void ossimNitfImageHeaderV2_1::setNumberOfPixelsPerBlockCol(ossim_uint32 pixels)
+{
+   std::ostringstream out;
+   
+   out << std::setw(4)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << pixels;
+   
+   memcpy(theNumberOfPixelsPerBlockVert, out.str().c_str(), 4);
+}
+
+ossim_uint64 ossimNitfImageHeaderV2_1::getDataLocation() const
+{
+   return theDataLocation;
+}
+
+void ossimNitfImageHeaderV2_1::setGeographicLocationDms(const ossimDpt& ul,
+                                                        const ossimDpt& ur,
+                                                        const ossimDpt& lr,
+                                                        const ossimDpt& ll)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << ossimDms(ul.y, true).toString("ddmmss.ssssC").c_str()
+         << ossimDms(ul.x, false).toString("dddmmss.ssssC").c_str()
+         << ossimDms(ur.y, true).toString("ddmmss.ssssC").c_str()
+         << ossimDms(ur.x, false).toString("dddmmss.ssssC").c_str()
+         << ossimDms(lr.y, true).toString("ddmmss.ssssC").c_str()
+         << ossimDms(lr.x, false).toString("dddmmss.ssssC").c_str()
+         << ossimDms(ll.y, true).toString("ddmmss.ssssC").c_str()
+         << ossimDms(ll.x, false).toString("dddmmss.ssssC").c_str()
+         << std::endl;
+
+      checkForGeographicTiePointTruncation(ul);
+      checkForGeographicTiePointTruncation(ur);
+      checkForGeographicTiePointTruncation(lr);
+      checkForGeographicTiePointTruncation(ll);
+   }
+      
+   theCoordinateSystem[0] = 'G';
+   std::ostringstream out;
+
+   out << ossimDms(ul.y, true).toString("ddmmssC").c_str();
+   out << ossimDms(ul.x, false).toString("dddmmssC").c_str();
+   out << ossimDms(ur.y, true).toString("ddmmssC").c_str();
+   out << ossimDms(ur.x, false).toString("dddmmssC").c_str();
+   out << ossimDms(lr.y, true).toString("ddmmssC").c_str();
+   out << ossimDms(lr.x, false).toString("dddmmssC").c_str();
+   out << ossimDms(ll.y, true).toString("ddmmssC").c_str();
+   out << ossimDms(ll.x, false).toString("dddmmssC").c_str();
+
+   memcpy(theGeographicLocation, out.str().c_str(), 60);
+}
+
+void ossimNitfImageHeaderV2_1::setGeographicLocationDecimalDegrees(
+   const ossimDpt& ul,
+   const ossimDpt& ur,
+   const ossimDpt& lr,
+   const ossimDpt& ll)
+{
+   theCoordinateSystem[0] = 'D';
+   ostringstream out;
+
+   out << (ul.lat >= 0.0?"+":"")
+       << std::setw(6)
+       << std::setfill('0')
+       << std::setprecision(3)
+       << std::setiosflags(std::ios::fixed)
+       << ul.lat
+       << (ul.lon >= 0.0?"+":"")
+       << std::setw(7)
+       << std::setfill('0')
+       << std::setprecision(3)
+       << std::setiosflags(std::ios::fixed)
+       << ul.lon;
+   out << (ur.lat >= 0.0?"+":"")
+       << std::setw(6)
+       << std::setfill('0')
+       << std::setprecision(3)
+       << std::setiosflags(std::ios::fixed)
+       << ur.lat
+       << (ur.lon >= 0.0?"+":"")
+       << std::setw(7)
+       << std::setfill('0')
+       << std::setprecision(3)
+       << std::setiosflags(std::ios::fixed)
+       << ur.lon;
+   out << (lr.lat >= 0.0?"+":"")
+       << std::setw(6)
+       << std::setfill('0')
+       << std::setprecision(3)
+       << std::setiosflags(std::ios::fixed)
+       << lr.lat
+       << (lr.lon >= 0.0?"+":"")
+       << std::setw(7)
+       << std::setfill('0')
+       << std::setprecision(3)
+       << std::setiosflags(std::ios::fixed)
+       << lr.lon;
+   out << (ll.lat >= 0.0?"+":"")
+       << std::setw(6)
+       << std::setfill('0')
+       << std::setprecision(3)
+       << std::setiosflags(std::ios::fixed)
+       << ll.lat
+       << (ll.lon >= 0.0?"+":"")
+       << std::setw(7)
+       << std::setfill('0')
+       << std::setprecision(3)
+       << std::setiosflags(std::ios::fixed)
+       << ll.lon;
+
+   memcpy(theGeographicLocation, out.str().c_str(), 60);
+}
+
+void ossimNitfImageHeaderV2_1::setUtmNorth(ossim_uint32 zone,
+                                           const ossimDpt& ul,
+                                           const ossimDpt& ur,
+                                           const ossimDpt& lr,
+                                           const ossimDpt& ll)
+{
+   theCoordinateSystem[0] = 'N';
+   
+   memcpy(theGeographicLocation,
+          encodeUtm(zone, ul, ur, lr, ll).c_str(), 60);
+}
+
+void ossimNitfImageHeaderV2_1::setUtmSouth(ossim_uint32 zone,
+                                           const ossimDpt& ul,
+                                           const ossimDpt& ur,
+                                           const ossimDpt& lr,
+                                           const ossimDpt& ll)
+{
+   theCoordinateSystem[0] = 'S';
+   
+   memcpy(theGeographicLocation,
+          encodeUtm(zone, ul, ur, lr, ll).c_str(), 60);
+}
+
+void ossimNitfImageHeaderV2_1::setImageId(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(10)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theImageId, out.str().c_str(), 10);
+}
+
+void ossimNitfImageHeaderV2_1::setAquisitionDateTime(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(14)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theDateTime, out.str().c_str(), 14);
+}
+
+void ossimNitfImageHeaderV2_1::setTargetId(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(17)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theTargetId, out.str().c_str(), 17);
+   
+}
+
+void ossimNitfImageHeaderV2_1::setTitle(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(80)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theTitle, out.str().c_str(), 80);
+}
+
+void ossimNitfImageHeaderV2_1::setSecurityClassification(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(1)
+       << std::setfill(' ')
+      
+       << value.trim().c_str();
+   
+   memcpy(theSecurityClassification, out.str().c_str(), 1);
+}
+
+void ossimNitfImageHeaderV2_1::setSecurityClassificationSystem(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(2)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theSecurityClassificationSys, out.str().c_str(), 2);
+}
+
+void ossimNitfImageHeaderV2_1::setCodewords(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(11)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theCodewords, out.str().c_str(), 11);
+}
+
+void ossimNitfImageHeaderV2_1::setControlAndHandling(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(2)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theControlAndHandling, out.str().c_str(), 2);
+}
+
+void ossimNitfImageHeaderV2_1::setReleasingInstructions(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(20)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theReleasingInstructions, out.str().c_str(), 20);
+}
+
+void ossimNitfImageHeaderV2_1::setDeclassificationType(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(2)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theDeclassificationType, out.str().c_str(), 2);
+}
+
+void ossimNitfImageHeaderV2_1::setDeclassificationDate(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(8)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theDeclassificationDate, out.str().c_str(), 8);
+}
+
+void ossimNitfImageHeaderV2_1::setDeclassificationExempt(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(4)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theDeclassificationExempt, out.str().c_str(), 4);
+}
+
+void ossimNitfImageHeaderV2_1::setDowngrade(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theDowngrade, out.str().c_str(), 1);
+}
+
+void ossimNitfImageHeaderV2_1::setDowngradeDate(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(8)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theDowngradeDate, out.str().c_str(), 8);
+}
+
+void ossimNitfImageHeaderV2_1::setClassificationText(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(43)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theClassificationText, out.str().c_str(), 43);
+}
+
+void ossimNitfImageHeaderV2_1::setClassificationAuthorityType(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theClassificationAuthType, out.str().c_str(), 1);
+}
+
+void ossimNitfImageHeaderV2_1::setClassificationAuthority(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(40)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theClassificationAuthority, out.str().c_str(), 40);
+}
+
+void ossimNitfImageHeaderV2_1::setClassificationReason(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theClassificationReason, out.str().c_str(), 1);
+}
+
+void ossimNitfImageHeaderV2_1::setSecuritySourceDate(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(8)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theSecuritySourceDate, out.str().c_str(), 8);
+}
+
+
+void ossimNitfImageHeaderV2_1::setSecurityControlNumber(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(15)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theSecurityControlNumber, out.str().c_str(), 15);
+}
+
+void ossimNitfImageHeaderV2_1::setEncryption(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theEncryption, out.str().c_str(), 1);
+}
+
+void ossimNitfImageHeaderV2_1::setImageSource(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(42)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theImageSource, out.str().c_str(), 42);
+}
+
+void ossimNitfImageHeaderV2_1::setJustification(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theJustification, out.str().c_str(), 1);
+}
+
+void ossimNitfImageHeaderV2_1::setCoordinateSystem(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theCoordinateSystem, out.str().c_str(), 1);
+}
+
+void ossimNitfImageHeaderV2_1::setGeographicLocation(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(60)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theGeographicLocation, out.str().c_str(), 60);
+}
+
+void ossimNitfImageHeaderV2_1::setNumberOfComments(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(1)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theNumberOfComments, out.str().c_str(), 1);
+}
+
+void ossimNitfImageHeaderV2_1::setCompression(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(2)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theCompression, out.str().c_str(), 2);
+}
+
+void ossimNitfImageHeaderV2_1::setCompressionRateCode(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(4)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theCompressionRateCode, out.str().c_str(), 4);
+}
+void ossimNitfImageHeaderV2_1::setDisplayLevel(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(3)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << value.trim().c_str();
+   
+   memcpy(theDisplayLevel, out.str().c_str(), 3);
+}
+
+void ossimNitfImageHeaderV2_1::setAttachmentLevel(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(3)
+       << std::setfill('0')
+       << std::setiosflags(ios::right)
+       << value.trim().c_str();
+   
+   memcpy(theAttachmentLevel, out.str().c_str(), 3);
+}
+
+void ossimNitfImageHeaderV2_1::setImageMagnification(const ossimString& value)
+{
+   std::ostringstream out;
+
+   out << std::setw(4)
+       << std::setfill(' ')
+       << std::setiosflags(ios::left)
+       << value.trim().c_str();
+   
+   memcpy(theImageMagnification, out.str().c_str(), 4);
+}
+
+void ossimNitfImageHeaderV2_1::setProperty(ossimRefPtr<ossimProperty> property)
+{
+   ossimString name = property->getName();
+   std::ostringstream out;
+   
+   if(!property) return;
+   
+   if(name.contains(IID1_KW))
+   {
+      setImageId(property->valueToString());
+   }
+   else if(name.contains(IDATIM_KW))
+   {
+      setAquisitionDateTime(property->valueToString());
+   }
+   else if(name.contains(TGTID_KW))
+   {
+      setTargetId(property->valueToString());
+   }
+   else if(name.contains(IID2_KW))
+   {
+      setTitle(property->valueToString());
+   }
+   else if(name.contains(ISCLAS_KW))
+   {
+      setSecurityClassification(property->valueToString());
+   }
+   else if(name.contains(ISCLSY_KW))
+   {
+      setSecurityClassificationSystem(property->valueToString());
+   }
+   else if(name.contains(ISCODE_KW))
+   {
+      setCodewords(property->valueToString());
+   }
+   else if(name.contains(ISCTLH_KW))
+   {
+      setControlAndHandling(property->valueToString());
+   }
+   else if(name.contains(ISREL_KW))
+   {
+      setReleasingInstructions(property->valueToString());
+   }
+   else if(name.contains(ISDCTP_KW))
+   {
+      setDeclassificationType(property->valueToString());
+   }
+   else if(name.contains(ISDCDT_KW))
+   {
+      setDeclassificationDate(property->valueToString());
+   }
+   else if(name.contains(ISDCXM_KW))
+   {
+      setDeclassificationExempt(property->valueToString());
+   }
+   else if(name.contains(ISDG_KW))
+   {
+      setDowngrade(property->valueToString());
+   }
+   else if(name.contains(ISDGDT_KW))
+   {
+      setDowngradeDate(property->valueToString());
+   }
+   else if(name.contains(ISCLTX_KW))
+   {
+      setClassificationText(property->valueToString());
+   }
+   else if(name.contains(ISCATP_KW))
+   {
+      setClassificationAuthorityType(property->valueToString());
+   }
+   else if(name.contains(ISCAUT_KW))
+   {
+      setClassificationAuthority(property->valueToString());
+   }
+   else if(name.contains(ISCRSN_KW))
+   {
+      setClassificationReason(property->valueToString());
+   }
+   else if(name.contains(ISSRDT_KW))
+   {
+      setSecuritySourceDate(property->valueToString());
+   }
+   else if(name.contains(ISCTLN_KW))
+   {
+      setSecurityControlNumber(property->valueToString());
+   }
+   else if(name.contains(ENCRYP_KW))
+   {
+      setEncryption(property->valueToString());
+   }
+   else if(name.contains(ISORCE_KW))
+   {
+      setImageSource(property->valueToString());
+   }
+   else if(name.contains(PVTYPE_KW))
+   {
+      setPixelType(property->valueToString());
+   }
+   else if(name.contains(IREP_KW))
+   {
+      setRepresentation(property->valueToString());
+   }
+   else if(name.contains(ICAT_KW))
+   {
+      setCategory(property->valueToString());
+   }
+   else if(name.contains(ABPP_KW))
+   {
+      setActualBitsPerPixel(property->valueToString().toUInt32());
+   }
+   else if(name.contains(PJUST_KW))
+   {
+      setJustification(property->valueToString());
+   }
+   else if(name.contains(ICORDS_KW))
+   {
+      setCoordinateSystem(property->valueToString());
+   }
+   else if(name.contains(IGEOLO_KW))
+   {
+      setGeographicLocation(property->valueToString());
+   }
+   else if(name.contains(NICOM_KW))
+   {
+      setNumberOfComments(property->valueToString());
+   }
+   else if(name.contains(IC_KW))
+   {
+      setCompression(property->valueToString());
+   }
+   else if(name.contains(COMRAT_KW))
+   {
+      setCompressionRateCode(property->valueToString());
+   }
+   else if(name.contains(ISYNC_KW))
+   {
+   }
+   else if(name.contains(IMODE_KW))
+   {
+      setImageMode(*(property->valueToString().trim().begin()));
+   }
+   else if(name.contains(NBPR_KW))
+   {
+      setBlocksPerRow(property->valueToString().toUInt32());
+   }
+   else if(name.contains(NBPC_KW))
+   {
+      setBlocksPerCol(property->valueToString().toUInt32());
+   }
+   else if(name.contains(NPPBH_KW))
+   {
+      setNumberOfPixelsPerBlockRow(property->valueToString().toUInt32());
+   }
+   else if(name.contains(NPPBV_KW))
+   {
+      setNumberOfPixelsPerBlockCol(property->valueToString().toUInt32());
+   }
+   else if(name.contains(NBPP_KW))
+   {
+      setBitsPerPixel(property->valueToString().toUInt32());
+   }
+   else if(name.contains(IDLVL_KW))
+   {
+      setDisplayLevel(property->valueToString());
+   }
+   else if(name.contains(IALVL_KW))
+   {
+      setAttachmentLevel(property->valueToString());
+   }
+   else if(name.contains(ILOC_KW))
+   {
+   }
+   else if(name.contains(IMAG_KW))
+   {
+      (property->valueToString());
+   }
+   else
+   {
+      ossimNitfImageHeader::setProperty(property);
+   }
+}
+
+ossimRefPtr<ossimProperty> ossimNitfImageHeaderV2_1::getProperty(const ossimString& name)const
+{
+   ossimProperty* property = NULL;
+
+   if(name == IID1_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theImageId).trim());
+   }
+   else if(name == IDATIM_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theDateTime).trim());
+   }
+   else if(name == TGTID_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theTargetId).trim());
+   }
+   else if(name == IID2_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theTitle).trim());
+   }
+   else if(name == ISCLAS_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theSecurityClassification).trim());
+   }
+   else if(name == ISCLSY_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theSecurityClassificationSys).trim());
+   }
+   else if(name == ISCODE_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theCodewords).trim());
+   }
+   else if(name == ISCTLH_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theControlAndHandling).trim());
+   }
+   else if(name == ISREL_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theReleasingInstructions).trim());
+   }
+   else if(name == ISDCTP_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theDeclassificationType).trim());
+   }
+   else if(name == ISDCDT_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theDeclassificationDate).trim());
+   }
+   else if(name == ISDCXM_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theDeclassificationExempt).trim());
+   }
+   else if(name == ISDG_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theDowngrade).trim());
+   }
+   else if(name == ISDGDT_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theDowngradeDate).trim());
+   }
+   else if(name == ISCLTX_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theClassificationText).trim());
+   }
+   else if(name == ISCATP_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theClassificationAuthType).trim());
+   }
+   else if(name == ISCRSN_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theClassificationAuthority).trim());
+   }
+   else if(name == ISSRDT_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theSecuritySourceDate).trim());
+   }
+   else if(name == ISCTLN_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theSecurityControlNumber).trim());
+   }
+   else if(name == ENCRYP_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theEncryption).trim());
+   }
+   else if(name == ISORCE_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theImageSource).trim());
+   }
+   else if(name == PVTYPE_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(thePixelValueType).trim());
+   }
+   else if(name == IREP_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theRepresentation).trim());
+   }
+   else if(name == ICAT_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theCategory).trim());
+   }
+   else if(name == ABPP_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theActualBitsPerPixelPerBand).trim());
+   }
+   else if(name == PJUST_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theJustification).trim());
+   }
+   else if(name == ICORDS_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theCoordinateSystem).trim());
+   }
+   else if(name == IGEOLO_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theGeographicLocation).trim());
+   }
+   else if(name == NICOM_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theNumberOfComments).trim());
+   }
+   else if(name == IC_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theCompression).trim());
+   }
+   else if(name == COMRAT_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theCompressionRateCode).trim());
+   }
+   else if(name == ISYNC_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theImageSyncCode).trim());
+   }
+   else if(name == IMODE_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theImageMode).trim());
+   }
+   else if(name == NBPR_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theNumberOfBlocksPerRow).trim());
+   }
+   else if(name == NBPC_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theNumberOfBlocksPerCol).trim());
+   }
+   else if(name == NPPBH_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theNumberOfPixelsPerBlockHoriz).trim());
+   }
+   else if(name == NPPBV_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theNumberOfPixelsPerBlockVert).trim());
+   }
+   else if(name == NBPP_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theNumberOfBitsPerPixelPerBand).trim());
+   }
+   else if(name == IDLVL_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theDisplayLevel).trim());
+   }
+   else if(name == IALVL_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theAttachmentLevel).trim());
+   }
+   else if(name == ILOC_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theImageLocation).trim());
+   }
+   else if(name == IMAG_KW)
+   {
+      property = new ossimStringProperty(name,
+                                         ossimString(theImageMagnification).trim());
+   }
+   else
+   {
+      return ossimNitfImageHeader::getProperty(name);
+   }
+   
+   return property;
+}
+
+void ossimNitfImageHeaderV2_1::getPropertyNames(std::vector<ossimString>& propertyNames)const
+{
+   propertyNames.push_back(IID1_KW);
+   propertyNames.push_back(IDATIM_KW);
+   propertyNames.push_back(TGTID_KW);
+   propertyNames.push_back(IID2_KW);
+   propertyNames.push_back(ISCLAS_KW);
+   propertyNames.push_back(ISCLSY_KW);
+   propertyNames.push_back(ISCODE_KW);
+   propertyNames.push_back(ISCTLH_KW);
+   propertyNames.push_back(ISREL_KW);
+   propertyNames.push_back(ISDCTP_KW);
+   propertyNames.push_back(ISDCDT_KW);
+   propertyNames.push_back(ISDCXM_KW);
+   propertyNames.push_back(ISDG_KW);
+   propertyNames.push_back(ISDGDT_KW);
+   propertyNames.push_back(ISCLTX_KW);
+   propertyNames.push_back(ISCATP_KW);
+   propertyNames.push_back(ISCAUT_KW);
+   propertyNames.push_back(ISCRSN_KW);
+   propertyNames.push_back(ISSRDT_KW);
+   propertyNames.push_back(ISCTLN_KW);
+   propertyNames.push_back(ENCRYP_KW);
+   propertyNames.push_back(ISORCE_KW);
+   propertyNames.push_back(PVTYPE_KW);
+   propertyNames.push_back(IREP_KW);
+   propertyNames.push_back(ICAT_KW);
+   propertyNames.push_back(ABPP_KW);
+   propertyNames.push_back(PJUST_KW);
+   propertyNames.push_back(ICORDS_KW);
+   propertyNames.push_back(IGEOLO_KW);
+   propertyNames.push_back(NICOM_KW);
+   propertyNames.push_back(IC_KW);
+   propertyNames.push_back(COMRAT_KW);
+   propertyNames.push_back(NBANDS_KW);
+   propertyNames.push_back(XBANDS_KW);
+   propertyNames.push_back(ISYNC_KW);
+   propertyNames.push_back(IMODE_KW);
+   propertyNames.push_back(NBPR_KW);
+   propertyNames.push_back(NBPC_KW);
+   propertyNames.push_back(NPPBH_KW);
+   propertyNames.push_back(NPPBV_KW);
+   propertyNames.push_back(NBPP_KW);
+   propertyNames.push_back(IDLVL_KW);
+   propertyNames.push_back(IALVL_KW);
+   propertyNames.push_back(ILOC_KW);
+   propertyNames.push_back(IMAG_KW);
+   
+}
+
+ossimString ossimNitfImageHeaderV2_1::encodeUtm(
+   ossim_uint32 zone,
+   const ossimDpt& ul,
+   const ossimDpt& ur,
+   const ossimDpt& lr,
+   const ossimDpt& ll)const throw(std::out_of_range)
+{
+   ostringstream out;
+
+   if(zone > 60)
+   {
+      std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUTM zone greate than 60!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }
+   
+   ossim_float64 east  = ul.x;
+   ossim_float64 north = ul.y;
+   
+   if((ossim_uint32)(east+.5) > 999999)
+   {
+      std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper left easting too large for NITF field!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }
+   
+   if((ossim_uint32)(north+.5) > 9999999)
+   {
+      std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper left northing too large for NITF field!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }
+
+   out << setw(2)
+       << setfill('0')
+       << zone
+       << setw(6)
+       << setfill('0')
+       <<(ossim_uint32)(east+.5)
+       << setw(7)
+          << setfill('0')
+       <<(ossim_uint32)(north+.5);
+
+   
+   east  = ur.x;
+   north = ur.y;
+   
+   if((ossim_uint32)(east+.5) > 999999)
+   {
+      std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper right easting too large for NITF field!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }
+   
+   if((ossim_uint32)(north+.5) > 9999999)
+   {
+      std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper right northing too large for NITF field!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }
+   
+   out << setw(2)
+       << setfill('0')
+       << zone
+       << setw(6)
+       << setfill('0')
+       <<(ossim_uint32)(east+.5)
+       << setw(7)
+       << setfill('0')
+       <<(ossim_uint32)(north+.5);
+   east  = lr.x;
+   north = lr.y;
+
+   if((ossim_uint32)(east+.5) > 999999)
+   {
+      std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower right easting too large for NITF field!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }
+   
+   if((ossim_uint32)(north+.5) > 9999999)
+   {
+      std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower right northing too large for NITF field!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }   
+
+   out << setw(2)
+       << setfill('0')
+       << zone
+       << setw(6)
+       << setfill('0')
+       <<(ossim_uint32)(east+.5)
+       << setw(7)
+       << setfill('0')
+       <<(ossim_uint32)(north+.5);
+   
+   east  = ll.x;
+   north = ll.y;
+
+   if((ossim_uint32)(east+.5) > 999999)
+   {
+      std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower left easting too large for NITF field!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }
+   
+   if((ossim_uint32)(north+.5) > 9999999)
+   {
+      std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower left northing too large for NITF field!";
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
+      }
+      throw std::out_of_range(s);
+   }
+   
+   out << setw(2)
+       << setfill('0')
+       << zone
+       << setw(6)
+       << setfill('0')
+       <<(ossim_uint32)(east+.5)
+       << setw(7)
+       << setfill('0')
+       <<(ossim_uint32)(north+.5);
+   
+   return out.str().c_str();
+}
+
+const ossimRefPtr<ossimNitfCompressionHeader> ossimNitfImageHeaderV2_1::getCompressionHeader()const
+{
+   return theCompressionHeader;
+}
+
+const ossimRefPtr<ossimNitfImageBand> ossimNitfImageHeaderV2_1::getBandInformation(ossim_uint32 idx)const
+{
+   if(idx < theImageBands.size())
+   {
+      return (ossimNitfImageBand*)theImageBands[idx].get();
+   }
+   
+   return NULL;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_1.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_1.h
new file mode 100644
index 0000000000..0dda18282d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageHeaderV2_1.h
@@ -0,0 +1,1097 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level directory for more details
+// 
+// Author: Garrett Potts
+// 
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageHeaderV2_1.h,v 1.22 2005/11/19 00:34:14 dburken Exp $
+
+#ifndef ossimNitfImageHeaderV2_1_HEADER
+#define ossimNitfImageHeaderV2_1_HEADER
+
+#include <stdexcept>
+
+#include <support_data/nitf/ossimNitfImageHeader.h>
+#include <support_data/nitf/ossimNitfImageBandV2_1.h>
+
+class OSSIMDLLEXPORT ossimNitfImageHeaderV2_1 : public ossimNitfImageHeader
+{
+public:
+   ossimNitfImageHeaderV2_1();
+   virtual ~ossimNitfImageHeaderV2_1();
+
+   virtual void parseStream(std::istream &in);
+   virtual void writeStream(std::ostream &out);
+
+   virtual std::ostream& print(std::ostream &out)const;
+
+   virtual ossimDrect getImageRect()const;   
+   virtual ossimDrect getBlockImageRect()const;   
+   virtual bool isCompressed()const;
+   virtual bool isEncrypted()const;
+   virtual ossimString getCompressionCode()const;
+
+   virtual long getDisplayLevel()const;
+   virtual long getAttachmentLevel()const;
+
+   virtual long getNumberOfBands()const;
+   virtual long getNumberOfRows()const;
+   virtual long getNumberOfCols()const;
+   virtual long getNumberOfBlocksPerRow()const;
+   virtual long getNumberOfBlocksPerCol()const;
+   virtual long getNumberOfPixelsPerBlockHoriz()const;
+   virtual long getNumberOfPixelsPerBlockVert()const;
+   virtual ossimString getImageId()const;
+   virtual long        getBitsPerPixelPerBand()const;
+   virtual long        getActualBitsPerPixelPerBand()const;
+   virtual ossimString getIMode()const;
+   virtual ossim_uint64 getDataLocation()const;
+
+   virtual ossimString getAcquisitionDateMonthDayYear(ossim_uint8 separationChar='-')const;
+   virtual ossimString getSecurityClassification()const;
+   virtual ossimString getCategory()const;
+   virtual ossimString getRepresentation()const;
+   virtual ossimString getCoordinateSystem()const;
+   virtual ossimString getGeographicLocation()const;
+   virtual ossimString getPixelValueType()const;
+
+
+   virtual bool hasBlockMaskRecords()const;
+   virtual bool hasPadPixelMaskRecords()const;
+   virtual bool hasTransparentCode()const;
+   virtual ossim_uint32 getTransparentCode()const;
+   virtual ossim_uint32 getBlockMaskRecordOffset(ossim_uint32 blockNumber,
+                                                 ossim_uint32 bandNumber)const;
+   virtual ossim_uint32 getPadPixelMaskRecordOffset(ossim_uint32 blockNumber,
+                                                    ossim_uint32 bandNumber)const;
+   
+   virtual void setNumberOfBands(ossim_uint32 nbands);
+   virtual void setBandInfo(ossim_uint32 idx,
+                            const ossimNitfImageBandV2_1& info);
+   
+   virtual void setNumberOfRows(ossim_uint32 rows);
+   virtual void setNumberOfCols(ossim_uint32 cols);
+   virtual void setPixelType(const ossimString& pixelType = ossimString("INT"));
+   virtual void setBitsPerPixel(ossim_uint32 bitsPerPixel);
+   virtual void setActualBitsPerPixel(ossim_uint32 bitsPerPixel);
+   virtual void setImageMode(char mode);
+   virtual void setCategory(const ossimString& category);
+   virtual void setRepresentation(const ossimString& rep);
+   virtual void setBlocksPerRow(ossim_uint32 blocks);
+   virtual void setBlocksPerCol(ossim_uint32 blocks);
+   virtual void setNumberOfPixelsPerBlockRow(ossim_uint32 pixels);
+   virtual void setNumberOfPixelsPerBlockCol(ossim_uint32 pixels);
+
+   virtual void setGeographicLocationDms(const ossimDpt& ul,
+                                         const ossimDpt& ur,
+                                         const ossimDpt& lr,
+                                         const ossimDpt& ll);
+   
+   virtual void setGeographicLocationDecimalDegrees(const ossimDpt& ul,
+                                                    const ossimDpt& ur,
+                                                    const ossimDpt& lr,
+                                                    const ossimDpt& ll);
+   virtual void setUtmNorth(ossim_uint32 zone,
+                            const ossimDpt& ul,
+                            const ossimDpt& ur,
+                            const ossimDpt& lr,
+                            const ossimDpt& ll);
+   virtual void setUtmSouth(ossim_uint32 zone,
+                            const ossimDpt& ul,
+                            const ossimDpt& ur,
+                            const ossimDpt& lr,
+                            const ossimDpt& ll);
+                            
+   virtual void setImageId(const ossimString& value);
+   virtual void setAquisitionDateTime(const ossimString& value);
+   virtual void setTargetId(const ossimString& value);
+   virtual void setTitle(const ossimString& value);
+   virtual void setSecurityClassification(const ossimString& value);
+   virtual void setSecurityClassificationSystem(const ossimString& value);
+   virtual void setCodewords(const ossimString& value);
+   virtual void setControlAndHandling(const ossimString& value);
+   virtual void setReleasingInstructions(const ossimString& value);
+   virtual void setDeclassificationType(const ossimString& value);
+   virtual void setDeclassificationDate(const ossimString& value);
+   virtual void setDeclassificationExempt(const ossimString& value);
+   virtual void setDowngrade(const ossimString& value);
+   virtual void setDowngradeDate(const ossimString& value);
+   virtual void setClassificationText(const ossimString& value);
+   virtual void setClassificationAuthorityType(const ossimString& value);
+   virtual void setClassificationAuthority(const ossimString& value);
+   virtual void setClassificationReason(const ossimString& value);
+   virtual void setSecuritySourceDate(const ossimString& value);
+   virtual void setSecurityControlNumber(const ossimString& value);
+   virtual void setEncryption(const ossimString& value);
+   virtual void setImageSource(const ossimString& value);
+   virtual void setJustification(const ossimString& value);
+   virtual void setCoordinateSystem(const ossimString& value);
+   virtual void setGeographicLocation(const ossimString& value);
+   virtual void setNumberOfComments(const ossimString& value);
+   virtual void setCompression(const ossimString& value);
+   virtual void setCompressionRateCode(const ossimString& value);
+   virtual void setDisplayLevel(const ossimString& value);
+   virtual void setAttachmentLevel(const ossimString& value);
+   virtual void setImageMagnification(const ossimString& value);
+   
+   virtual ossimString getImageSource()const; 
+   
+   virtual const ossimRefPtr<ossimNitfCompressionHeader> getCompressionHeader()const;
+   virtual const ossimRefPtr<ossimNitfImageBand> getBandInformation(ossim_uint32 idx)const;
+   
+   virtual void setProperty(ossimRefPtr<ossimProperty> property);
+   virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const;
+   virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const;
+private:
+   void clearFields();
+
+   
+   ossimString encodeUtm(ossim_uint32 zone,
+                         const ossimDpt& ul,
+                         const ossimDpt& ur,
+                         const ossimDpt& lr,
+                         const ossimDpt& ll)const throw(std::out_of_range);
+
+   /**
+    * Is a required 2 byte value and is IM.
+    */
+   char theType[3];
+
+   /**
+    * FIELD: IID1
+    * Is a required 10 Alphanumeric value.
+    */
+   char theImageId[11];
+
+   /**
+    * FIELD: IDATIM
+    * 
+    * Contains the time of acquisition of the image.
+    * this is a 14 byte field and has the format:
+    *
+    * CCYYMMDDhhmmss
+    *
+    * CC   is the first 2 chars of the year 00-99
+    * YY   is the second 2 chars of the year 00-99
+    * MM   is the month 01-12
+    * DD   is the day 00-31
+    * hh   is the hour 00-23
+    * mm   is the minutes 00-59
+    * ss   is the seconds 00-59
+    */
+   char theDateTime[15];
+
+   /**
+    * FIELD: TGTID
+    * 
+    * is a 17 byte field.  Has the form
+    *
+    * BBBBBBBBBBFFFFFCC
+    *
+    * where:
+    *
+    * B     is the encyclopedia id
+    * F     is the functional category code
+    * C     is the country code.
+    */
+   char theTargetId[18];
+
+   /**
+    * FIELD: IID2
+    * 
+    * Is 80 bytes and contains the title
+    */
+   char theTitle[81];
+
+   /**
+    * FIELD: ISCLAS
+    * 
+    * Is a required 1 byte field and has value:
+    *
+    * T    = Top secret
+    * S    = Secrect
+    * C    = confidential
+    * R    = Restricted
+    * U    = Unclassified
+    */
+   char theSecurityClassification[2];
+
+   /**
+    * FIELD: ISCLSY
+    * 
+    * Is a required 2 byte field.
+    *
+    * Image Security Classification System.
+    *
+    * This field shall contain valid values indicating the
+    * national or multinational security system used to classify the image. Country Codes per
+    * FIPS 10-4 shall be used to indicate national security systems; codes found in DIAM 65-19
+    * shall be used to indicate multinational security systems.
+    * If this field is all BCS spaces (0x20), it shall imply that no security
+    * classification system applies to the image. 
+    */
+   char theSecurityClassificationSys[3];
+
+   /**
+    * FIELD: ISCODE
+    * 
+    * is a 11 byte field
+    *
+    * Image Codewords.
+    *
+    * This field shall contain a valid indicator of the security compartments
+    * associated with the image. Values include one or more of the tri/digraphs found
+    * in DIAM 65-19 and/or Table A-4. Multiple entries shall be separated by single
+    * BCS spaces (0x20): The selection of a relevant set of codewords is application
+    * specific.  If this field is all BCS spaces (0x20), it shall imply that no
+    * codewords apply to the image.
+    */
+   char theCodewords[12];
+
+   /**
+    * FIELD: ISCTLH
+    * 
+    * is a 2 byte field.
+    *
+    * Image Control and Handling.  This field shall contain valid additional
+    * security control and/or handling instructions (caveats) associated with the image.
+    * Values include digraphs found in DIAM 65-19 and/or Table A4.
+    * The digraph may indicate single or multiple caveats. The selection of a
+    * relevant caveat(s) is application specific.  If this field is all BCS spaces (0x20),
+    * it shall imply that no additional control and handling instructions
+    * apply to the image. 
+    */
+   char theControlAndHandling[3];
+
+   /**
+    * FIELD: ISREL
+    * 
+    * Is a 20 byte field.
+    *
+    * Image Releasing Instructions.  This field shall contain a valid list of
+    * country and/or multilateral entity codes to which countries and/or multilateral
+    * entities the image is authorized for release.  Valid items in the list are one or
+    * more country codes as found in FIPS 10-4 and/or codes identifying multilateral
+    * entities as found in DIAM 65-19. If this field is all BCS spaces (0x20),
+    * it shall imply that no image release instructions apply.
+    */
+   char theReleasingInstructions[21];
+
+
+   /**
+    * FIELD: ISDCTP
+    * 
+    * Is a required 2 byte field.  The valid
+    * values are
+    * DD = declassify on a specific date
+    * DE = Declassify upon occurence of an event
+    * GD = downgrade to a specified level upon
+    *      occurence of an event
+    * O  = OADR
+    * X  = exempt from automatic declassification
+    * spaces = no image security declassification or
+    *          downgrade instruction apply.
+    */
+   char theDeclassificationType[3];
+   
+
+   /**
+    * FIELD: ISDCDT
+    * 
+    * Is a required 8 byte field.
+    *  CCYYMMDD
+    *
+    * CC   is the first 2 chars of the year 00-99
+    * YY   is the second 2 chars of the year 00-99
+    * MM   is the month 01-12
+    * DD   is the day 00-31
+    */
+   char theDeclassificationDate[9];
+
+   /**
+    * FIELD: ISDCXM
+    * 
+    * is a required 4 byte field.
+    * 
+    * Image Declassification Exemption.
+    *
+    * This field shall indicate the reason the image is exempt from automatic
+    * declassification if the value in Image Declassification Type is X. Valid
+    * values are X1 through X8 and X251 through X259. X1 through X8 correspond
+    * to the declassification exemptions found in DOD 5200.1-R, paragraphs
+    * 4-202b(1) through (8) for material exempt from the 10-year rule.
+    * X251 through X259 correspond to the declassification exemptions found in
+    * DOD 5200.1-R, paragraphs 4-301a(1) through (9) for permanently valuable
+    * material exempt from the 25-year declassification system. If this field is
+    * all BCS spaces (0x20), it shall imply that a image declassification exemption
+    * does not apply. 
+    */
+   char theDeclassificationExempt[5];
+   
+   /**
+    * FIELD: ISDG
+    * 
+    * Is a required 1 byte field with form:
+    *
+    *
+    * Image Downgrade.  This field shall indicate the classification level
+    * to which a image is to be downgraded if the values in Image Declassification Type
+    * are GD or GE.
+    *
+    * Valid values are
+    *    S (=Secret),
+    *    C (=Confidential),
+    *    R (= Restricted).
+    *
+    * If this field is all BCS spaces (0x20), it shall imply that image security
+    * downgrading does not apply.  
+    */
+   char theDowngrade[2];
+
+   /**
+    * FIELD: ISDGDT
+    * 
+    * is a required 8 byte field
+    *
+    * CCYYMMDD
+    *
+    * CC   is the first 2 chars of the year 00-99
+    * YY   is the second 2 chars of the year 00-99
+    * MM   is the month 01-12
+    * DD   is the day 00-31
+    */
+   char theDowngradeDate[9];
+
+   /**
+    * FIELD: ISCLTX
+    * 
+    * is a required 43 byte field.
+    *
+    * Image Classification Text.
+    *
+    * This field shall be used to provide additional information
+    * about image classification to include identification of a declassification or downgrading
+    * event if the values in Image Declassification Type are DE or GE.. It may also be used
+    * to identify multiple classification sources and/or any other special handling rules.
+    * Values are user defined free text. If this field is all BCS spaces (0x20), it shall
+    * imply that additional information about image classification does not apply. 
+    */
+   char theClassificationText[44];
+
+   /**
+    * FIELD: ISCATP
+    * 
+    * Is a required 1 byte field.
+    *
+    * O  = original classification Authority
+    * D  = derivative from a single source
+    * M  = derivative from multiple sources
+    * 
+    */
+   char theClassificationAuthType[2];
+
+   /**
+    * FIELD: ISCAUT
+    * 
+    * Is a required 40 byte field.
+    *
+    * Image Classification Authority.
+    *
+    * This field shall identify the classification authority for the image dependent upon the
+    * value in Image Classification Authority Type. Values are user defined free text which
+    * should contain the following information: original classification authority name and
+    * position or personal identifier if the value in Image Classification Authority Type is O;
+    * title of the document or security classification guide used to classify the image
+    * if the value in Image Classification Authority Type is D;
+    * and Derive-Multiple if the image classification was derived from multiple sources.
+    * In the latter case, the image originator will maintain a record of the sources used
+    * in accordance with existing security directives. One of the multiple sources may also
+    * be identified in Image Classification Text if desired. If this field is all BCS spaces
+    * (0x20), it shall imply that no image classification authority applies.
+    */
+   char theClassificationAuthority[41];
+
+   /**
+    * FIELD: ISCRSN
+    * 
+    * This is a required 1 byte field and indicates
+    * the classification reason.
+    *
+    * Image Classification Reason.
+    *
+    * This field shall contain values indicating the reason for classifying the image.
+    * Valid values are A through G. These correspond to the reasons for
+    * original classification per E.O. 12958, Section 1.5.(a) through (g).
+    * If this field is all BCS spaces (0x20), it shall imply that no image classification
+    * reason applies. 
+    */
+   char theClassificationReason[2];
+
+   /**
+    * FIELD: ISSRDT
+    * 
+    * This is a required 8 byte field.
+    *
+    * CCYYMMDD
+    *
+    * CC   is the first 2 chars of the year 00-99
+    * YY   is the second 2 chars of the year 00-99
+    * MM   is the month 01-12
+    * DD   is the day 00-31
+    *
+    */
+   char theSecuritySourceDate[9];
+
+   /**
+    * FIELD: ISCTLN
+    * 
+    * is a required 15 byte field.
+    */
+   char theSecurityControlNumber[16];
+
+   /**
+    * FIELD: ENCRYP
+    * 
+    * Is arequired 1 byte field.  This field should
+    * be 0.
+    */
+   char theEncryption[2];
+
+   /**
+    * FIELD: ISORCE
+    * 
+    * Is a 42 byte optional field.
+    */
+   char theImageSource[43];
+
+   /**
+    * FIELD: NROWS
+    * 
+    * Required 8 byte number 00000002-99999999
+    */
+   char theSignificantRows[9];
+
+   /**
+    * FIELD: NCOLS
+    * 
+    * Required 8 byte number 00000002-99999999
+    */
+   char theSignificantCols[9];
+
+   /**
+    * FIELD: PVTYPE
+    * 
+    * Required 3 byte value.
+    * Values:
+    *
+    * INT   integer 16 bits
+    * B     for bi-level represented as single bits 1 or 0
+    * SI    signend 16 bit integer
+    * R     32 bit float
+    * C     for complex (32 bit float real part, 32 bit float imag part)
+    *       Adjacent 4 byte blocks
+    * U     for user defined.
+    */
+   char thePixelValueType[4];
+
+   /**
+    * FIELD: IREP
+    * 
+    * This is required 8 byte field.
+    *
+    * Values:
+    *
+    * MONO    indicates monnochrome
+    * RGB     indicates true color red green blue
+    * RGB/LUT indicates RGB lookup table.
+    * 1D      indicates monoband data.
+    * 2D      indicates for 2 dimensional data
+    * NM      indicates multidimensional data
+    * MULTI   indicates multiband imgery
+    * YCbCr601 indicates compressed in CCIR 601
+    *          color space using JPEG (field IC=C3)
+    *
+    *
+    * MORE INFO:
+    *
+    *
+    * 
+    */
+   char theRepresentation[9];
+
+   /**
+    * FIELD: ICAT
+    *
+    * This is a required 8 byte field.  Contains info
+    * about the specific category of the image.
+    *
+    * VIS    visible imagery
+    * SL     side looking infrared
+    * TI     thermal infrared
+    * FL     forward looking infrared
+    * RD     radar
+    * EO     elctro-optical
+    * OP     optical
+    * HR     high resolution radar
+    * HS     hyperspectral
+    * CP     color frame photography
+    * BP     black/white frame photography
+    * SAR    Synthetic Aperture Radar
+    * SARIQ  SAR radio hologram
+    * IR     infrared.
+    * MS     multispectral
+    * FP     fingerprints
+    * MRI    Magnetic Resonance imagery
+    * XRAY   x-rays
+    * CAT    cat scans
+    * MAP    maps
+    * PAT    patch
+    * LEG    legends
+    * DTEM   elevation models
+    * MATR   matrix data
+    * LOCG   location grids
+    * VD     video
+    * 
+    *
+    * default value is VIS
+    */
+   char theCategory[9];
+
+   /**
+    * FIELD: ABPP
+    * 
+    * Is optional and indicates the number of
+    * bits per band 01-96
+    */
+   char theActualBitsPerPixelPerBand[3];
+
+   /**
+    * FIELD: PJUST
+    * 
+    * Is 1 byte optional field.  Can have
+    * values L (left) or R (right).  Any other value
+    * is to interpreted as right justified.
+    *
+    * This indicates how the significant bits are justified
+    * in the field
+    */
+   char theJustification[2];
+
+   /**
+    * FIELD: ICORDS
+    * 
+    * Is a 1 byte required field and can have
+    * values 
+    *
+    * U indicates UTM MGRS format
+    * G indicates Geodetic (Geographic)
+    * N indicates UTM Northern hemisphere
+    * S indicates UTM SOuthern hemisphere
+    * D Decimal degrees
+    *
+    * spaces means no coordinate system
+    *
+    * Geodetic reference system is WGS84.
+    */
+   char theCoordinateSystem[2];
+
+   /**
+    * FIELD: IGEOLO
+    * 
+    * This is a conditional field.  If theCoordinateSystem
+    * is blank then it does not exist.  If it's any other
+    * value then it's given in image coordinate order
+    *
+    * (0, 0) (0, MaxCol) (MaxRow, MaxCol) (MaxRow, 0)
+    *
+    * if its geodetic or geocentric it will have a lat lon coordinate
+    * with each coordinate as:
+    * Lat = ddmmssX
+    *       where d is degrees and m is minutes
+    *       and s is seconds and X is either N (North) or S (South).
+    * Lon = dddmmssX
+    *       where d is degrees and m is minutes
+    *       and s is seconds and X is either N (North) or S (South).
+    *
+    *       
+    * if its UTM then zzeeeeeennnnnnn where
+    *
+    * z is the zone number
+    * e is the easting
+    * n is the northing
+    *
+    * if its decimal degrees then +-dd.ddd +-dd.ddd four times where
+    * + is northern hemispher and - is souther hemisphere for lat
+    * and longitude + is easting and - is westing.
+    *
+    */
+   char theGeographicLocation[61];
+
+   /**
+    * FIELD: NICOM
+    * 
+    * this is a required 1 byte field and indicates the number of comments.
+    *
+    * Values are 0-9 and the default is 0
+    */
+   char theNumberOfComments[2];
+
+   
+   /**
+    * FIELD: IC
+    * 
+    * This is a required 2 byte field and indicates the compression
+    * type of the image.
+    *
+    * NC  indicates not compressed
+    * C1  indicates bi-level
+    * C2  indicates ARIDPCM
+    * C3  inidates JPEG
+    * C4  inidcates Vector Quantization
+    * C5  indicates lossless jpeg
+    * I1  indicates a downsampled jpeg
+    * M0  indicates compressed images
+    * M3  indicates compressed images
+    * M4  indicates compressed images
+    * M5  indicates compression
+    * NM  indicates uncompressed
+    *
+    * The M's and NM are blocked images that contain
+    * block mask and/or transparent pixel mask.  There
+    * will be an Image Data Mask Subheader ath the beginning
+    * of the image data area.
+    *
+    */
+   char theCompression[3];
+
+   /**
+    * FIELD COMRAT
+    * 
+    * This is a conditional 4 byte  field.  if theCompression is
+    * not equal to NC then this field exists.
+    *
+    * Compression Rate Code.
+    *
+    * If the Image Compression (IC) field contains, C1, C4, M1, or M4,
+    * this field shall be present and contain a code indicating the compression rate for the image.
+    * If the value in IC is C1 or M1, the valid codes are 1D, 2DS, and 2DH,
+    * where: 1D represents One-dimensional Coding
+    *        2DS represents Two-dimensional Coding Standard Vertical Resolution (K=2)
+    *        2DH represents Two-dimensional Coding High Vertical Resolution (K=4)
+    *        
+    * A BCS zero (0x30) will be used for the Y value when custom Q-Tables are used.
+    * Explanation of these codes can be found in ITU-T T-4, AMD2 08/95.
+    *
+    * If the value in IC is C3, C5, I1, or M5, the value of this field shall be 00.0.
+    * The value 00.0 represents embedded tables and is required by JPEG.
+    * Explanation of embedded tables can be found in MIL-STD-188-198A and NIMA N0105-97.
+    * If the value in IC is C4 or M4, this field shall contain a value given in the
+    * form nn.n representing the number of bits-per-pixel for the compressed image.
+    * Explanation of the compression rate for vector quantization can be found in MIL-STD-188-199.
+    * This field is omitted if the value in IC is NC or NM. If IC = I1, value = 00.0.
+    * 4 BCS-A See description for constraints C 
+    */
+   char theCompressionRateCode[5];
+
+   /**
+    * FIELD: NBANDS
+    * 
+    * Is required 1 byte field  and will have value 1-9
+    *
+    * If theRepresentation is MONO this should be 1
+    * if theRepresentation is RGB  this should be 3
+    * if theRepresentation is RGB/LUT this should be 1
+    * if theRepresentation YCbCr601 this should be 3
+    * if theRepresentation is MULTI this should be 2-9
+    *
+    * if this field is 0 then it's multi spectral data
+    * larger than 9
+    */
+   char theNumberOfBands[2];
+
+   /**
+    * FIELD: XBANDS
+    * 
+    * This is a conditional 5 byte field and ranges from
+    * 00010-99999.  This exists if theNumberOfBands is 0.
+    */
+   char theNumberOfMultispectralBands[6];
+
+   vector<ossimRefPtr<ossimNitfImageBandV2_1> > theImageBands;
+
+   /**
+    * FIELD: ISYNC
+    * 
+    * Required 1 byte field.  Has value 0 or 4
+    */
+   char theImageSyncCode[2];
+
+   /**
+    * FIELD: IMODE
+    * 
+    *
+    * Required 1 byte field.
+    *
+    *
+    * Image Mode.  This field shall contain an indicator of whether the image bands are stored in the
+    * file sequentially or band interleaved by block or band interleaved by pixel format or
+    * band interleaved by row.
+    *
+    * Valid values are B, P, R, and S.  The significance of the IMODE value must be interpreted
+    * with the knowledge of whether the image is:
+    *     JPEG compressed (IC=C3, C5, M3, or M5),
+    *     VQ compressed (IC=C4, or M4),
+    *     or uncompressed (IC=NC or NM).
+    * When IC=C1 or M1, the use of IMODE defaults to B.  When IC=I1, IMODE is B.
+    *
+    * For the uncompressed case:  The value R represents band interleaved by row,
+    * where the ordering mechanism stores the pixel values of each band in row sequential order.
+    * Within each block, all pixel values of the first row of the first band are followed by
+    * pixel values of the first row of the second band continuing until all values of the
+    * first row are stored.  The remaining rows are stored in a similar fashion until the last
+    * row of values has been stored.  Each block shall be zero filled to the next octet boundary
+    * when necessary.  The value S represents band sequential, where all blocks for the first band
+    * are followed by all blocks for the second band, and so on:
+    * [(block1, band1), (block2, band1), ... (blockM, band1)],
+    * [(block1, band2), (block2, band 2), ... (blockM, band2)] ...
+    * [(block1, bandN), (block2, bandN), ... (blockM, bandN)].
+    *
+    * The values B and P indicate variations on block sequential where all data from all bands
+    * for the first block is followed by all data from all bands for the second block, and so on.
+    * The variations are based on the way the bands are organized within each block.
+    * B represents band interleaved by block.
+    *
+    * This means that within each block, the bands follow one 1 BCS-A B, P, R, S R
+    *
+    *
+    * another:  [(block1, band1), (block1, band2), ...
+    *           (block1, bandN)],
+    *           [(block2, band1),
+    *           (block2, band2), ...
+    *           (block2, bandN)], ...
+    *           [(blockM, band1),
+    *           (blockM, band2), ...
+    *           (blockM, bandN)].
+    *
+    * P represents band interleaved by pixel within each block:  such as, for each block,
+    * one after the other, the full pixel vector (all band values) appears for every pixel in
+    * the block, one pixel after another, the block column index varying faster than the block
+    * row index.  If the NBANDS field is 1, the cases B and S coincide.
+    * In this case, this field shall contain B.  If the Number of Blocks is 1(NBPR = NBPC = 1),
+    * this field shall contain B for non-interleaved by pixel, and P for interleaved by pixel.
+    * The value S is only valid for images with multiple blocks and multiple bands.
+    * For the JPEG-compressed case:  The presence of B, P, or S implies specific ordering of
+    * data within the JPEG image data representation.  The interpretation of the values of IMODE
+    * for this case is specified in MIL-STD188-198A.
+    *
+    * For the Vector Quantization compressed case:  VQ compressed images are normally either RGB with a
+    * color look-up table or monochromatic.  In either case, the image is single band, and the IMODE
+    * field defaults to B.  However, it is possible to have a multiband VQ compressed image in band sequential,
+    * band interleaved by block, or band interleaved by pixel format.
+    * 
+    */
+   char theImageMode[2];
+   
+   /**
+    * FIELD: NBPR
+    * 
+    * Required 4 byte value.  ranges from
+    * 0001-9999
+    */
+   char theNumberOfBlocksPerRow[5];
+   
+   /**
+    * FIELD: NBPC
+    * 
+    * Required 4 byte value. Ranges from
+    * 0001-9999
+    */
+   char theNumberOfBlocksPerCol[5];
+
+   /**
+    * FIELD: NPPBH
+    * 
+    * Reuqired 4 byte field
+    */
+   char theNumberOfPixelsPerBlockHoriz[5];
+
+   /**
+    * FIELD: NPPBV
+    * 
+    * Reuqired 4 byte field
+    */
+   char theNumberOfPixelsPerBlockVert[5];
+
+   /**
+    * FIELD: NBPP
+    * 
+    * Required 2 byte field.
+    *
+    * Number of Bits Per Pixel Per Band.  If IC contains NC, NM, C4, or M4,
+    * this field shall contain the number of storage bits used for the value
+    * from each component of a pixel vector.  The value in this field always
+    * shall be greater than or equal to Actual Bits Per Pixel (ABPP).
+    * For example, if 11-bit pixels are stored in 16 bits,
+    * this field shall contain 16 and Actual Bits Per Pixel shall contain 11.
+    * If IC = C3, M3, C5, M5, or I1 this field shall contain the value 8 or the value 12.
+    * If IC = C1, this field shall contain the value 1. 2 BCS-N 01-96 R 
+    */
+   char theNumberOfBitsPerPixelPerBand[3];
+
+   /**
+    * FIELD: IDLVL
+    *
+    * Display Level.
+    * 
+    * Required 3 byte field.  Ranges from 001-999
+    *
+    * This field shall contain a valid value that indicates the graphic display
+    * level of the image relative to other displayed file components in a composite
+    * display.  The display level of each displayable file component (image or graphic)
+    * within a file shall be unique; that is, each number from 001 to 999 is the display
+    * level of, at most, one item.  The meaning of display level is fully discussed in
+    * paragraph 5.3.3.  The image or graphic component in the file having the minimum
+    * display level shall have attachment level 0.
+    * 
+    */
+   char theDisplayLevel[4];
+
+   /**
+    * FIELD: IALVL
+    *
+    * Attachment Level
+    * 
+    * Required 3 byte field.  Ranges from 000-998
+    *
+    * This field shall contain a valid value that indicates the attachment level of the image.
+    * Valid values for this field are 0, and the display level value of any other image or
+    * graphic in the file.  The meaning of attachment level is fully discussed in
+    * paragraph 5.3.4. The image, graphic, or text component in the file having the
+    * minimum display level shall have attachment level 0.
+    * 
+    */
+   char theAttachmentLevel[4];
+
+   /**
+    * FIELD: ILOC
+    * 
+    * Required 10 byte field.
+    *
+    * Image Location.  The image location is the location of the first pixel of the first line of
+    * the image.  This field shall contain the image location represented as
+    * rrrrrccccc, where rrrrr and ccccc are the row and column offset from the
+    * ILOC or SLOC value of the item to which the image is attached.  A row or column
+    * value of 00000 indicates no offset.  Positive row and column values indicate offsets down
+    * and to the right and range from 00001 to 99999, while negative row and column
+    * values indicate offsets up and to the left and must be within the range -0001 to -9999.
+    * The location in the common coordinate system of all displayable graphic
+    * components can be computed from the offsets given in the ILOC and SLOC fields. 10 BCS-N -9999
+    * 
+    */
+   char theImageLocation[11];
+
+   /**
+    * FIELD: IMAG
+    * 
+    * Required 4 byte field
+    *
+    * Image Magnification.
+    *
+    * This field shall contain the magnification (or reduction) factor of the image
+    * relative to the original source image.  Decimal values are used to indicate magnification,
+    * and decimal fraction values indicate reduction.
+    * For example, 2.30 indicates the original image has been magnified by a factor of
+    * Ò2.30,Ó while Ò0.5Ó indicates the original image has been reduced by a factor of 2.
+    * The default value is 1.0, indicating no magnification or reduction.
+    * In addition, the following values shall be used for reductions that are reciprocals of
+    * nonnegative powers of 2: /2 (for 1/2), /4 (for 1/4), /8 (for 1/8), /16 (for 1/16), /32 (for 1/32),
+    * /64 (for 1/64), /128 (for 1/128). 4 BCS-A /2, /4, /8, /16, /32, /64, /128 or
+    * decimal value (Default is 1.0 followed by BCS space (0x20)) R
+    * 
+    */
+   char theImageMagnification[5];
+
+   /**
+    * FIELD: UDIDL
+    * 
+    * Required 5 byte field. 00000 or 00003-99999
+    *
+    * User Defined Image Data Length.  A value of 0 shall represent that no tagged record extensions
+    * are included in the UDID field.  If a tagged record extension exists, the field shall contain
+    * the sum of the length of all the tagged record extensions (see paragraph 5.7.l.l) appearing in
+    * the UDID field plus 3 bytes (length of UDOFL field).  If a tagged record extension is too long
+    * to fit in the UDID field, it may be put in a data extension segment (see paragraph 5.8.1.3.1.)
+    *
+    */
+   char theUserDefinedImageDataLength[6];
+
+   /**
+    * FIELD: UDOFL
+    * 
+    * conditional 3 byte field. if theUserDefinedImageDataLength
+    * is not 0
+    *
+    * User Defined Overflow.  If present, this field shall contain 000 if the tagged record extensions
+    * in UDID do not overflow into a DES, or shall contain the sequence number of the DES into which
+    * they do overflow.  This field shall be omitted if the field UDIDL contains BCS zeros (0x30).
+    *
+    * 
+    */
+   char theUserDefinedOverflow[4];
+
+   /**
+    * FIELD: IXSHDL
+    * 
+    * Is a required 5 byte field. 00000 or 00003-99999
+    *
+    * Extended Subheader Data Length.  This field shall contain the length in bytes in
+    * IXSHD plus 3 (length of IXSOFL).  The length is 3 plus sum of the lengths of all the
+    * tagged record extensions (see paragraph 5.7.1.2) appearing in the IXSHD field.  A value of
+    * BCS zeros (0x30) shall represent that no tagged record extensions are included in the IXSHD field.
+    * If a tagged record extension exists, the field shall contain the sum of the length of all the tagged
+    * record extensions (see paragraph 5.7.1.2) appearing in the IXSHD field plus 3 bytes (length of
+    * IXSOFL field).  If a tagged record extension is too long to fit in the IXSHD field, it shall may
+    * be put in a data extension segment (see paragraph 5.7.1.4). 
+    */
+   char theExtendedSubheaderDataLen[6];
+
+   /**
+    * FIELD: IXSOFL
+    * 
+    * Is a conditional 3 byte field.  This depends on
+    * theExtendedSubheaderDataLen not being 0.
+    *
+    * Extended Subheader Data.  If present, this field shall contain tagged record
+    * extensions (see paragraph 5.8.1.2) approved and under configuration management by the ISMC.
+    * The length of this field shall be the length specified by the field IXSHDL minus 3.  Tagged
+    * record extensions in this field for an image shall contain information pertaining specifically
+    * to the image.  Tagged record extensions shall appear one after the other in this field with no
+    * intervening bytes.  The first byte of this field shall be the first byte of the  first tagged record
+    * extension appearing in the field.  The last byte of this field shall be the last byte of the last
+    * tagged record extension to appear in the field.  This field shall be omitted if the field IXSHDL
+    * contains 0.
+    */
+   char theExtendedSubheaderOverflow[4];
+
+
+   /*******************************************************************************
+    *                    THIS IS THE MASK TABLE IF PRESENT
+    *
+    */
+   
+   /**
+    * FIELD NAME: IMDATOFF
+    * 
+    * Blocked Image Data Offset.
+    * 
+    * 4 byte Binary integer: 0x00000000 to 0xFFFFFFFF
+    * 
+    * This field is included if the IC value equals NM, M1, M3, M4, or M5.
+    * It identifies the offset from the beginning of the Image Data Mask to the first byte of the blocked image data.
+    * This offset, when used in combination with the offsets provided in the BMR fields,
+    * can provide random access to any recorded image block in any image band.
+    * 
+    */
+   ossim_uint32 theBlockedImageDataOffset;
+
+   /**
+    * FIELD NAME: BMRLNTH
+    *
+    * Block Mask Record Length.
+    *
+    * 2 byte Unsigned binary integer
+    * 0x0000=No Block mask record; 0x0004=Block mask
+    * records (4 bytes each) are present  
+    * 
+    * This field is included if the IC value equals NM, M1, M3, M4, or M5.
+    * It identifies the length of each Block Mask Record in bytes.
+    * When present, the length of each Block Mask Record is 4 bytes.
+    * The total length of all the block Mask Records is equal to
+    *
+    * For S mode BMRLNTH x NBPR x NBPC x NBANDS  (one 4 byte record for each block of each band in the image).
+    * and for all other modes BMRLNTH x NBPR x NBPC
+    * 
+    * If all of the image blocks are recorded,
+    * this value may be set to 0, and the conditional BMR fields are not recorded/transmitted.
+    * Otherwise, the value may be set to 4, and the conditional BMR fields are
+    * recorded/transmitted and can be used as an off-set index for each
+    * image block in each band of the image.
+    * If this field is present, but coded as 0, then only a pad pixel mask is included.
+    *
+    *
+    */
+   ossim_uint16 theBlockMaskRecordLength;
+
+   /**
+    * FIELD: TMRLNTH
+    *
+    * Pad Pixel Mask Record Length.
+    *
+    * 2 byte Unsigned binary integer a value of
+    * 0x0000=No Pad pixel mask records and 
+    * 0x0004=Pad pixel mask records (4 bytes each) are present
+    * 
+    * This field is included if the IC value equals NM, M1, M3, M4, or M5 
+    * It identifies the length of each Pad Pixel Mask Record in bytes.
+    * When present, the length of each Pad Pixel Mask Record is 4 bytes.
+    * The total length of the Pad Pixel Mask Records is equal to
+    * 
+    * For image mode S then TMRLNTH x NBPR x NBPC x NBANDS (one 4 byte record for each block for each band in the image).
+    * else for all other modes TMRLNTH x NBPR x NBPC
+    * 
+    * If none of the image blocks contain pad pixels, this value is set to 0,
+    * and the conditional TMR fields are not recorded/transmitted.
+    * For IC value of M3, the value shall be set to 0.
+    * If this field is present, but coded as 0, then a Block Mask is included.
+    */
+   ossim_uint16 thePadPixelMaskRecordLength;
+   
+   /**
+    *  FIELD: TPXCDLNTH
+    *
+    *  Transparent Output Pixel Code Length.
+    *
+    *  2 byte Unsigned binary integer;
+    *  0x0000=No pad pixels; 0x0001 to 0x0010=pad pixel code length in bits
+    *  
+    *  This field is included if the IC value equals NM, M1, M3, M4, M5.
+    *  It identifies the length in bits of the Transparent Output Pixel Code.
+    *  If coded as 0, then no transparent pixels are present,
+    *  and the TPXCD field is not recorded.  For IC value of M3, the
+    *  value shall be set to 0..
+    *  
+    */
+   ossim_uint16 theTransparentOutputPixelCodeLength;
+
+
+   /**
+    * FIELD: TPXCD
+    *
+    * Pad Output Pixel Code.
+    *
+    * This field is included if the IC value equals NM, M1, M3, M4, M5, M0 and
+    * TPXCDLNTH is not 0.  It contains the output pixel code that represents a
+    * pad pixel in the image.  This value is unique within the image, and allows
+    * the user to identify pad pixels.  The pad output pixel code length is determined by
+    * TPXCDLNTH, but the value is stored in a maximum of 2 bytes.
+    * If the number of bits used by TPXCD is less than the number of bits available for storage,
+    * the value shall be justified in accordance with the PJUST field in the image subheader.  
+    * 3A Binary integer; 0 to 2^n -1 where n=TPXCDLNTH
+    */
+   ossim_uint16 thePadOutputPixelCode;
+
+
+   std::vector<ossim_uint32> theBlockMaskRecords;
+   std::vector<ossim_uint32> thePadPixelMaskRecords;
+   ossimRefPtr<ossimNitfCompressionHeader> theCompressionHeader;
+   
+   ossim_uint64 theDataLocation;
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLut.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLut.cpp
new file mode 100644
index 0000000000..b43acfe086
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLut.cpp
@@ -0,0 +1,47 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageLut.cpp,v 1.2 2004/11/11 14:23:34 gpotts Exp $
+#include "ossimNitfImageLut.h"
+#include <string.h> // memcpy
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+ostream& operator <<(ostream& out,
+                     const ossimNitfImageLut &data)
+{
+   data.print(out);
+
+   return out;
+}
+
+RTTI_DEF1(ossimNitfImageLut, "ossimNitfImageLut", ossimObject);
+ossimNitfImageLut::ossimNitfImageLut()
+{
+}
+
+ossimNitfImageLut::~ossimNitfImageLut()
+{
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLut.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLut.h
new file mode 100644
index 0000000000..8fd817165f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLut.h
@@ -0,0 +1,48 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageLut.h,v 1.2 2004/11/11 14:23:34 gpotts Exp $
+#ifndef ossimNitfImageLut_HEADER
+#define ossimNitfImageLut_HEADER
+#include <vector>
+#include <iostream>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimObject.h>
+
+using namespace std;
+
+class ossimNitfImageLut : public ossimObject
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimNitfImageLut &data);
+   ossimNitfImageLut();
+   virtual ~ossimNitfImageLut();
+   virtual void parseStream(std::istream &in)=0;
+   virtual std::ostream& print(std::ostream& out)const=0;
+   virtual ossim_uint32 getNumberOfEntries()const=0;
+   virtual void setNumberOfEntries(ossim_uint32 numberOfEntries)=0;
+   virtual ossim_uint8 getValue(ossim_uint32 idx)const=0;
+
+TYPE_DATA;
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_0.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_0.cpp
new file mode 100644
index 0000000000..bba97ae988
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_0.cpp
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageLutV2_0.cpp,v 1.2 2004/11/11 14:23:34 gpotts Exp $
+#include "ossimNitfImageLutV2_0.h"
+#include <string.h> // memcpy
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+ossimNitfImageLutV2_0::ossimNitfImageLutV2_0()
+{
+}
+
+ossimNitfImageLutV2_0::~ossimNitfImageLutV2_0()
+{
+}
+
+void ossimNitfImageLutV2_0::parseStream(std::istream &in)
+{
+   if(in)
+   {
+      ossim_uint32 count = 0;
+      while(count < theNumberOfEntries)
+      {
+         in.read((char*)&theData[count], 1);
+
+         ++count;
+      }
+   }
+}
+
+std::ostream& ossimNitfImageLutV2_0::print(ostream& out)const
+{
+   out << "theNumberOfEntries:          " << theNumberOfEntries;
+
+   return out;
+}
+
+ossim_uint32 ossimNitfImageLutV2_0::getNumberOfEntries()const
+{
+   return theNumberOfEntries;
+}
+
+void ossimNitfImageLutV2_0::setNumberOfEntries(ossim_uint32 numberOfEntries)
+{
+   theData.resize(numberOfEntries);
+   theNumberOfEntries = numberOfEntries;
+}
+
+ossim_uint8 ossimNitfImageLutV2_0::getValue(ossim_uint32 index)const
+{
+   return theData[index];
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_0.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_0.h
new file mode 100644
index 0000000000..1c49c47ae0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_0.h
@@ -0,0 +1,48 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfImageLutV2_0.h,v 1.2 2004/11/11 14:23:34 gpotts Exp $
+#ifndef ossimNitfImageLutV2_0_HEADER
+#define ossimNitfImageLutV2_0_HEADER
+#include "ossimNitfImageLut.h"
+
+#include <vector>
+#include <iostream>
+using namespace std;
+
+
+class ossimNitfImageLutV2_0 : public ossimNitfImageLut
+{
+public:
+   ossimNitfImageLutV2_0();
+   virtual ~ossimNitfImageLutV2_0();
+   virtual void parseStream(std::istream &in);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual ossim_uint32 getNumberOfEntries()const;
+   virtual void setNumberOfEntries(ossim_uint32 numberOfEntries);
+   virtual ossim_uint8 getValue(ossim_uint32 idx)const;
+   
+protected:
+   vector<ossim_uint8> theData;
+   ossim_uint32 theNumberOfEntries;
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_1.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_1.cpp
new file mode 100644
index 0000000000..eeecfa9769
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_1.cpp
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken <dburken@imagelinks.com>
+// 
+// Description: Nitf support class.  Copied from ossimNitfImageLutV2_0.
+// 
+//********************************************************************
+// $Id: ossimNitfImageLutV2_1.cpp,v 1.2 2004/11/11 14:23:34 gpotts Exp $
+
+#include "ossimNitfImageLutV2_1.h"
+#include <string.h> // memcpy
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+ossimNitfImageLutV2_1::ossimNitfImageLutV2_1()
+{
+}
+
+ossimNitfImageLutV2_1::~ossimNitfImageLutV2_1()
+{
+}
+
+// void ossimNitfImageLutV2_1::parseStream(istream &in)
+// {
+//    if(in)
+//    {
+//       long count = 0;
+//       while(count < theNumberOfEntries)
+//       {
+//          in.read((char*)&theData[count], 1);
+
+//          ++count;
+//       }
+//    }
+// }
+
+// void ossimNitfImageLutV2_1::print(ostream& out)const
+// {
+//    out << "theNumberOfEntries:          " << theNumberOfEntries;
+// }
+
+// long ossimNitfImageLutV2_1::getNumberOfEntries()const
+// {
+//    return theNumberOfEntries;
+// }
+
+// void ossimNitfImageLutV2_1::setNumberOfEntries(long numberOfEntries)
+// {
+//    theData.resize(numberOfEntries);
+//    theNumberOfEntries = numberOfEntries;
+// }
+
+// unsigned char ossimNitfImageLutV2_1::getValue(long index)
+// {
+//    return theData[index];
+// }
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_1.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_1.h
new file mode 100644
index 0000000000..0c91af8edb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfImageLutV2_1.h
@@ -0,0 +1,41 @@
+//*******************************************************************
+// Copyright (C) 2002 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  David Burken <dburken@imagelinks.com>
+// 
+// Description: Nitf support class.  Copied from ossimNitfImageLutV2_0.
+// 
+//********************************************************************
+// $Id: ossimNitfImageLutV2_1.h,v 1.2 2004/11/11 14:23:34 gpotts Exp $
+
+#ifndef ossimNitfImageLutV2_1_HEADER
+#define ossimNitfImageLutV2_1_HEADER
+#include "ossimNitfImageLutV2_0.h"
+
+#include <vector>
+#include <iostream>
+using namespace std;
+
+class ossimNitfImageLutV2_1 : public ossimNitfImageLutV2_0
+{
+public:
+   ossimNitfImageLutV2_1();
+   virtual ~ossimNitfImageLutV2_1();
+   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeader.cpp
new file mode 100644
index 0000000000..781adab2c1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeader.cpp
@@ -0,0 +1,26 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfLabelHeader.cpp,v 1.2 2004/05/23 18:42:33 dburken Exp $
+#include "ossimNitfLabelHeader.h"
+
+RTTI_DEF1(ossimNitfLabelHeader, "ossimNitfLabelHeader", ossimObject)
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeader.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeader.h
new file mode 100644
index 0000000000..a0c690f140
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeader.h
@@ -0,0 +1,44 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfLabelHeader.h,v 1.2 2004/05/23 18:42:33 dburken Exp $
+#ifndef ossimNitfLabelHeader_HEADER
+#define ossimNitfLabelHeader_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimObject.h"
+#include "base/data_types/ossimDrect.h"
+
+class OSSIMDLLEXPORT ossimNitfLabelHeader : public ossimObject
+{
+public:
+   ossimNitfLabelHeader(){}
+   virtual ~ossimNitfLabelHeader(){}
+   
+   virtual void parseStream(istream &in)=0;
+   virtual long getDisplayLevel()const=0;
+   virtual ossimDrect getImageRect()const=0;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeaderV2_0.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeaderV2_0.cpp
new file mode 100644
index 0000000000..53c5540739
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeaderV2_0.cpp
@@ -0,0 +1,164 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfLabelHeaderV2_0.cpp,v 1.3 2004/05/23 18:42:33 dburken Exp $
+#include <support_data/nitf/ossimNitfLabelHeaderV2_0.h>
+#include <base/data_types/ossimString.h>
+#include <string.h> // for memset
+
+RTTI_DEF1(ossimNitfLabelHeaderV2_0, "ossimNitfLabelHeaderV2_0", ossimNitfLabelHeader)
+
+ossimNitfLabelHeaderV2_0::ossimNitfLabelHeaderV2_0()
+{
+   clearFields();
+}
+
+void ossimNitfLabelHeaderV2_0::parseStream(istream &in)
+{
+   if(in)
+   {
+      clearFields();
+      
+      in.read(theFilePartType, 2);
+      in.read(theLabelId, 10);
+      in.read(theLabelSecurityClassification, 1);
+      in.read(theLabelCodewords, 40);
+      in.read(theLabelControlAndHandling, 40);
+      in.read(theLabelReleasingInstructions, 40);
+      in.read(theLabelClassificationAuthority, 20);
+      in.read(theLabelSecurityControlNumber, 20);
+      in.read(theLabelSecurityDowngrade, 6);
+      if(ossimString(theLabelSecurityDowngrade) == "999998")
+      {
+         in.read(theLabelDowngradingEvent, 40);
+      }
+      in.read(theLabelEncryption, 1);
+      in.read(theLabelFontStyle, 1);
+      in.read(theLabelCellWidth, 2);
+      in.read(theLabelCellHeight, 2);
+      in.read(theLabelDisplayLevel, 3);
+      in.read(theLabelAttachmentLevel, 3);
+      in.read(theLabelLocation, 10);
+      in.read(theLabelTextColor, 3);
+      in.read(theLabelBackgroundColor, 3);
+      in.read(theExtendedHeaderDataLength, 5);
+      
+      long dataLength = ossimString(theExtendedHeaderDataLength).toLong();
+      if(dataLength > 0)
+      {
+         in.read(theExtendedSubheaderOverflow, 3);
+
+         // for now just ignore the extended header data
+         in.ignore(dataLength-3);
+      }
+   }
+}
+
+std::ostream& ossimNitfLabelHeaderV2_0::print(std::ostream &out)const
+{
+   out << "theFilePartType:                  " << theFilePartType << std::endl
+       << "theLabelId:                       " << theLabelId << std::endl
+       << "theLabelSecurityClassification:   " << theLabelSecurityClassification << std::endl
+       << "theLabelCodewords:                " << theLabelCodewords << std::endl
+       << "theLabelControlAndHandling:       " << theLabelControlAndHandling << std::endl
+       << "theLabelReleasingInstructions:    " << theLabelReleasingInstructions << std::endl
+       << "theLabelClassificationAuthority:  " << theLabelClassificationAuthority << std::endl
+       << "theLabelSecurityControlNumber:    " << theLabelSecurityControlNumber << std::endl
+       << "theLabelSecurityDowngrade:        " << theLabelSecurityDowngrade << std::endl
+       << "theLabelEncryption:               " << theLabelEncryption << std::endl
+       << "theLabelFontStyle:                " << theLabelFontStyle << std::endl
+       << "theLabelCellWidth:                " << theLabelCellWidth << std::endl
+       << "theLabelCellHeight:               " << theLabelCellHeight << std::endl
+       << "theLabelDisplayLevel:             " << theLabelDisplayLevel << std::endl
+       << "theLabelAttachmentLevel:          " << theLabelAttachmentLevel << std::endl
+       << "theLabelLocation:                 " << theLabelLocation << std::endl
+       << "theLabelTextColor:                " << theLabelTextColor << std::endl
+       << "theLabelBackgroundColor:          " << theLabelBackgroundColor << std::endl
+       << "theExtendedHeaderDataLength:      " << theExtendedHeaderDataLength << std::endl
+       << "theExtendedSubheaderOverflow:     " << theExtendedSubheaderOverflow;
+   return out;
+}
+
+long ossimNitfLabelHeaderV2_0::getDisplayLevel()const
+{
+   return ossimString(theLabelDisplayLevel).toLong();
+}
+
+ossimDrect ossimNitfLabelHeaderV2_0::getImageRect()const
+{
+   double ulx = ossimString((const char*)(&theLabelLocation[5]),
+                            (const char*)(&theLabelLocation[10])).toDouble();
+   double uly = ossimString((const char*)theLabelLocation,
+                            (const char*)(&theLabelLocation[5])).toDouble();
+
+   return ossimDrect(ulx,
+                     uly,
+                     ulx + ossimString(theLabelCellWidth).toDouble(),
+                     uly + ossimString(theLabelCellHeight).toDouble());
+}
+
+void ossimNitfLabelHeaderV2_0::clearFields()
+{
+   memset(theFilePartType, ' ', 2);
+   memset(theLabelId, ' ', 10);
+   memset(theLabelSecurityClassification, ' ', 1);
+   memset(theLabelCodewords, ' ', 40);
+   memset(theLabelControlAndHandling, ' ', 40);
+   memset(theLabelReleasingInstructions, ' ', 40);
+   memset(theLabelClassificationAuthority, ' ', 20);
+   memset(theLabelSecurityControlNumber, ' ', 20);
+   memset(theLabelSecurityDowngrade, ' ', 6);
+   memset(theLabelDowngradingEvent, ' ', 40);
+   memset(theLabelEncryption, ' ', 1);
+   memset(theLabelFontStyle, ' ', 1);
+   memset(theLabelCellWidth, ' ', 2);
+   memset(theLabelCellHeight, ' ', 2);
+   memset(theLabelDisplayLevel, ' ', 3);
+   memset(theLabelAttachmentLevel, ' ', 3);
+   memset(theLabelLocation, ' ', 10);
+   memset(theLabelTextColor, ' ', 3);
+   memset(theLabelBackgroundColor, ' ', 3);
+   memset(theExtendedHeaderDataLength, ' ', 5);
+   memset(theExtendedSubheaderOverflow, ' ', 3);
+
+   theFilePartType[2] = '\0';
+   theLabelId[10] = '\0';
+   theLabelSecurityClassification[1] = '\0';
+   theLabelCodewords[40] = '\0';
+   theLabelControlAndHandling[40] = '\0';
+   theLabelReleasingInstructions[40] = '\0';
+   theLabelClassificationAuthority[20] = '\0';
+   theLabelSecurityControlNumber[20] = '\0';
+   theLabelSecurityDowngrade[6] = '\0';
+   theLabelDowngradingEvent[40] = '\0';
+   theLabelEncryption[1] = '\0';
+   theLabelFontStyle[1] = '\0';
+   theLabelCellWidth[2] = '\0';
+   theLabelCellHeight[2] = '\0';
+   theLabelDisplayLevel[3] = '\0';
+   theLabelAttachmentLevel[3] = '\0';
+   theLabelLocation[10] = '\0';
+   theLabelTextColor[3] = '\0';
+   theLabelBackgroundColor[3] = '\0';
+   theExtendedHeaderDataLength[5] = '\0';
+   theExtendedSubheaderOverflow[3] = '\0';
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeaderV2_0.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeaderV2_0.h
new file mode 100644
index 0000000000..7ba48df186
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLabelHeaderV2_0.h
@@ -0,0 +1,173 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfLabelHeaderV2_0.h,v 1.3 2004/05/23 18:42:33 dburken Exp $
+
+#ifndef ossimNitfLabelHeaderV2_0_HEADER
+#define ossimNitfLabelHeaderV2_0_HEADER
+#include <support_data/nitf/ossimNitfLabelHeader.h>
+
+class OSSIMDLLEXPORT ossimNitfLabelHeaderV2_0 : public ossimNitfLabelHeader
+{
+public:
+   ossimNitfLabelHeaderV2_0();
+   virtual ~ossimNitfLabelHeaderV2_0(){}
+   
+   virtual void parseStream(istream &in);
+   virtual std::ostream& print(std::ostream &out)const;
+   virtual long getDisplayLevel()const;
+   virtual ossimDrect getImageRect()const;
+
+TYPE_DATA
+private:
+   void clearFields();
+
+   /*!
+    * This is a required 2 byte field and has the value
+    * LA
+    */
+   char theFilePartType[3];
+
+   /*!
+    * This is a required 10 byte field.
+    */
+   char theLabelId[11];
+
+   /*!
+    * This is a required 1 byte field and will have
+    * a value of either:
+    *
+    * T    Top secret
+    * S    Secret
+    * C    Confidential
+    * R    Restricted
+    * U    Unclassified
+    */
+   char theLabelSecurityClassification[2];
+
+   /*!
+    * optional 40 byte field
+    */
+   char theLabelCodewords[41];
+
+   /*!
+    * optional 40 byte field
+    */
+   char theLabelControlAndHandling[41];
+
+   /*!
+    * optional 40 byte field
+    */
+   char theLabelReleasingInstructions[41];
+
+   /*!
+    * optional 20 byte field
+    */
+   char theLabelClassificationAuthority[21];
+
+   /*!
+    * optional 20 byte field
+    */
+   char theLabelSecurityControlNumber[21];
+
+   /*!
+    * optional 6 byte field
+    */
+   char theLabelSecurityDowngrade[7];
+
+   /*!
+    * conditional 40 byte field.  It exists only if
+    * theLabelSecurityDowngrade is = 999998
+    */
+   char theLabelDowngradingEvent[41];
+
+   /*!
+    * required 1 byte field and can have value
+    * 0  = not encrypted
+    * 1  = encrypted
+    */
+   char theLabelEncryption[2];
+
+   /*!
+    * required 1 byte field.  Is reserved for future
+    * use.  Will contain 1 blank.
+    */
+   char theLabelFontStyle[2];
+
+   /*!
+    * optional 2 byte field.  Ranges from 1-99 
+    */
+   char theLabelCellWidth[3];
+
+   /*!
+    * optional 2 byte field. Ranges from 1-99
+    */
+   char theLabelCellHeight[3];
+
+   /*!
+    * Required 3 byte field.  Ranges from 1-999.
+    */
+   char theLabelDisplayLevel[4];
+
+   /*!
+    * Required 3 byte field.  Ranges from 1-998.
+    */
+   char theLabelAttachmentLevel[4];
+
+   /*!
+    * Required 10 byte field. Has format:
+    *
+    * rrrrrccccc  the first five chars is the row
+    *             location and the second is the
+    *             column location.
+    */
+   char theLabelLocation[11];
+
+   /*!
+    * Required 3 byte field.  Has format:
+    *
+    * RGB   First byte is red, second is blue, and
+    *       third is green
+    */
+   char theLabelTextColor[4];
+
+   /*!
+    * Required 3 byte field.  Has format:
+    *
+    * RGB   First byte is red, second is blue, and
+    *       third is green
+    */
+   char theLabelBackgroundColor[4];
+
+   /*!
+    * Required 5 byte field.  Ranges from 0-09747
+    */
+   char theExtendedHeaderDataLength[6];
+
+   /*!
+    * Conditional 3 byte field.  Will exist if
+    * theExtendedHeaderDataLength is not 0
+    */
+   char theExtendedSubheaderOverflow[4];
+   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalCartographicTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalCartographicTag.cpp
new file mode 100644
index 0000000000..57eb474b3a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalCartographicTag.cpp
@@ -0,0 +1,146 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfLocalCartographicTag.cpp,v 1.3 2004/09/29 11:51:56 gpotts Exp $
+#include <support_data/nitf/ossimNitfLocalCartographicTag.h>
+#include <sstream>
+#include <iomanip>
+
+RTTI_DEF1(ossimNitfLocalCartographicTag, "ossimNitfLocalCartographicTag", ossimNitfRegisteredTag);
+
+ossimNitfLocalCartographicTag::ossimNitfLocalCartographicTag()
+{
+}
+
+ossimNitfLocalCartographicTag::~ossimNitfLocalCartographicTag()
+{
+}
+
+ossimString ossimNitfLocalCartographicTag::getRegisterTagName()const
+{
+   return "MAPLOB";
+}
+
+void ossimNitfLocalCartographicTag::parseStream(std::istream& in)
+{
+   clearFields();
+   
+   in.read(theLengthUnits, 3);
+   in.read(theEastingInterval, 5);
+   in.read(theNorthingInterval, 5);
+   in.read(theEastingReferenceOrigin, 15);
+   in.read(theNorthingReferenceOrigin, 15);
+}
+
+void ossimNitfLocalCartographicTag::writeStream(std::ostream& out)
+{
+   out.write(theLengthUnits, 3);
+   out.write(theEastingInterval, 5);
+   out.write(theNorthingInterval, 5);
+   out.write(theEastingReferenceOrigin, 15);
+   out.write(theNorthingReferenceOrigin, 15);
+}
+
+
+ossim_uint32 ossimNitfLocalCartographicTag::getSizeInBytes()const
+{
+   return 43;
+}
+
+void ossimNitfLocalCartographicTag::clearFields()
+{
+   memset(theLengthUnits, ' ', 3);
+   memset(theEastingInterval, '0', 5);
+   memset(theNorthingInterval, '0', 5);
+   memset(theEastingReferenceOrigin, '0', 15);
+   memset(theNorthingReferenceOrigin, '0', 15);
+
+   theLengthUnits[3]              = '\0';
+   theEastingInterval[5]          = '\0';
+   theNorthingInterval[5]         = '\0';
+   theEastingReferenceOrigin[15]  = '\0';
+   theNorthingReferenceOrigin[15] = '\0';
+}
+
+void ossimNitfLocalCartographicTag::setLengthUnits(const ossimString& units)
+{
+   ossimString temp = ossimString(units).trim().upcase();
+   std::ostringstream out;
+
+   out << std::setw(3)
+       << std::setfill(' ')
+       << temp.c_str();
+   
+   memcpy(theLengthUnits, out.str().c_str(), 3);
+}
+
+void ossimNitfLocalCartographicTag::setEastingInterval(ossim_uint32 eastingInterval)
+{
+   ossim_uint32 temp = eastingInterval;
+
+   if(temp > 99999)
+   {
+      temp = 99999;
+   }
+   
+   std::ostringstream out;
+
+   out << std::setw(5)
+       << std::setfill('0')
+       << temp;
+   
+   memcpy(theEastingInterval, out.str().c_str(), 5);
+}
+
+void ossimNitfLocalCartographicTag::setNorthingInterval(ossim_uint32 northingInterval)
+{
+   ossim_uint32 temp = northingInterval;
+
+   if(temp > 99999)
+   {
+      temp = 99999;
+   }
+   
+   std::ostringstream out;
+
+   out << std::setw(5)
+       << std::setfill('0')
+       << temp;
+   
+   memcpy(theNorthingInterval, out.str().c_str(), 5);
+}
+
+void ossimNitfLocalCartographicTag::setEastingReferenceOrigin(ossim_float64 east)
+{
+   std::ostringstream out;
+
+   out << std::setw(15)
+       << std::setfill(' ')
+       << std::setprecision(1)
+       << std::setiosflags(ios::fixed)
+       << east;
+   
+   memcpy(theEastingReferenceOrigin, out.str().c_str(), 15);
+   
+}
+
+void ossimNitfLocalCartographicTag::setNorthingReferenceOrigin(ossim_float64 north)
+{
+   std::ostringstream out;
+
+   out << std::setw(15)
+       << std::setfill(' ')
+       << std::setprecision(1)
+       << std::setiosflags(ios::fixed)
+       << north;
+   
+   memcpy(theNorthingReferenceOrigin, out.str().c_str(), 15);
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalCartographicTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalCartographicTag.h
new file mode 100644
index 0000000000..7354f6a618
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalCartographicTag.h
@@ -0,0 +1,92 @@
+#ifndef ossimNitfLocalCartographicTag_HEADER
+#define ossimNitfLocalCartographicTag_HEADER
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class ossimNitfLocalCartographicTag : public ossimNitfRegisteredTag
+{
+public:
+   ossimNitfLocalCartographicTag();
+   virtual ~ossimNitfLocalCartographicTag();
+   virtual ossimString getRegisterTagName()const;
+   virtual void parseStream(std::istream& in);
+   virtual void writeStream(std::ostream& out);
+   virtual ossim_uint32 getSizeInBytes()const;
+   virtual void clearFields();
+
+
+   void setLengthUnits(const ossimString& units);
+   void setEastingInterval(ossim_uint32 eastingInterval);
+   void setNorthingInterval(ossim_uint32 northingInterval);
+   void setEastingReferenceOrigin(ossim_float64 east);
+   void setNorthingReferenceOrigin(ossim_float64 north);
+   
+protected:
+   /**
+    * FIELD: UNILOA
+    *
+    * required 3 byte field
+    *
+    * Length units
+    *
+    * This field shall contain the unit of measure used for
+    * easting (LOD) and northing (LAD) intervals. The default value is M.
+    * 3BCS-A See Part 3- 7 R 
+    */
+   char theLengthUnits[4];
+
+   /**
+    * FIELD: LOD
+    *
+    * required 5 byte field
+    * 
+    * Easting interval
+    *
+    * This field shall contain the data density in E-W direction
+    * that is the column width of an image pixel.
+    * 5 BCS-N positive integer 00001 to 99999 R
+    */
+   char theEastingInterval[6];
+
+   /**
+    * FIELD: LAD
+    *
+    * required 5 byte field
+    * 
+    * Northing interval
+    *
+    * This field shall contain the data density in E-W direction
+    * that is the column width of an image pixel.
+    * 5 BCS-N positive integer 00001 to 99999 R
+    */
+   char theNorthingInterval[6];
+
+   /**
+    * FIELD: LSO
+    *
+    * required 15 byte field
+    * 
+    * Easting of Reference Origin
+    *
+    * This field shall contain the easting of the
+    * origin pixel (row number 0, column number 0) in the absolute coordinate system.
+    * 15 BCS-N ±mmmmmmmmmmmm.m
+    */
+   char theEastingReferenceOrigin[16];
+   
+   /**
+    * FIELD: PSO
+    *
+    * required 15 byte field
+    * 
+    * Northing of Reference Origin
+    *
+    * This field shall contain the northing of the
+    * origin pixel (row number 0, column number 0) in the absolute coordinate system.
+    * 15 BCS-N ±mmmmmmmmmmmm.m
+    */
+   char theNorthingReferenceOrigin[16];
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalGeographicTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalGeographicTag.cpp
new file mode 100644
index 0000000000..20acdea4bd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalGeographicTag.cpp
@@ -0,0 +1,119 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfLocalGeographicTag.cpp,v 1.3 2004/09/28 19:16:40 gpotts Exp $
+#include <support_data/nitf/ossimNitfLocalGeographicTag.h>
+#include <iomanip>
+#include <sstream>
+
+RTTI_DEF1(ossimNitfLocalGeographicTag, "ossimNitfLocalGeographicTag", ossimNitfRegisteredTag);
+
+ossimNitfLocalGeographicTag::ossimNitfLocalGeographicTag()
+{
+   clearFields();
+}
+
+ossimNitfLocalGeographicTag::~ossimNitfLocalGeographicTag()
+{
+}
+
+ossimString ossimNitfLocalGeographicTag::getRegisterTagName()const
+{
+   return "GEOLOB";
+}
+
+void ossimNitfLocalGeographicTag::parseStream(std::istream& in)
+{
+   in.read(theLonDensity, 9);
+   in.read(theLatDensity, 9);
+   in.read(theLonOrigin, 15);
+   in.read(theLatOrigin, 15);
+}
+
+void ossimNitfLocalGeographicTag::writeStream(std::ostream& out)
+{
+   out.write(theLonDensity, 9);
+   out.write(theLatDensity, 9);
+   out.write(theLonOrigin, 15);
+   out.write(theLatOrigin, 15);
+}
+
+ossim_uint32 ossimNitfLocalGeographicTag::getSizeInBytes()const
+{
+   return 48;
+}
+
+void ossimNitfLocalGeographicTag::clearFields()
+{
+   memset(theLonDensity, ' ', 9);
+   memset(theLatDensity, ' ', 9);
+   memset(theLonOrigin, '0', 15);
+   memset(theLatOrigin, '0', 15);
+
+   
+   
+   theLonDensity[9] = '\0';
+   theLatDensity[9] = '\0';
+   theLonOrigin[15] = '\0';
+   theLatOrigin[15] = '\0';
+}
+
+void ossimNitfLocalGeographicTag::setDegreesPerPixelLat(double deltaLat)
+{
+   ossim_uint32 pixels = 0;
+   if(deltaLat > 0.0)
+   {
+      pixels = (ossim_uint32)((1.0/deltaLat)*360.0 + .5);
+   }
+   ostringstream out;
+
+   out << std::setw(9)
+       << std::setfill('0')
+       << pixels;
+
+   memcpy(theLatDensity, out.str().c_str(), 9);
+}
+
+void ossimNitfLocalGeographicTag::setDegreesPerPixelLon(double deltaLon)
+{
+   ossim_uint32 pixels = 0;
+   if(deltaLon > 0.0)
+   {
+      pixels = (ossim_uint32)((1.0/deltaLon)*360.0 + .5);
+   }
+   ostringstream out;
+
+   out << std::setw(9)
+       << std::setfill('0')
+       << pixels;
+
+   memcpy(theLonDensity, out.str().c_str(), 9);
+}
+
+void ossimNitfLocalGeographicTag::setLatOrigin(double origin)
+{
+   ostringstream out;
+
+   out << std::setw(15)
+       << std::setfill('0')
+       << origin;
+   memcpy(theLatOrigin, out.str().c_str(), 15);
+}
+
+void ossimNitfLocalGeographicTag::setLonOrigin(double origin)
+{
+   ostringstream out;
+
+   out << std::setw(15)
+       << std::setfill('0')
+       << origin;
+   memcpy(theLonOrigin, out.str().c_str(), 15);
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalGeographicTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalGeographicTag.h
new file mode 100644
index 0000000000..a6803f3d14
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfLocalGeographicTag.h
@@ -0,0 +1,82 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfLocalGeographicTag.h,v 1.3 2004/09/28 19:16:40 gpotts Exp $
+#ifndef ossimNitfLocalGeographicTag_HEADER
+#define ossimNitfLocalGeographicTag_HEADER
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class OSSIM_DLL ossimNitfLocalGeographicTag : public ossimNitfRegisteredTag
+{
+public:
+   ossimNitfLocalGeographicTag();
+   virtual ~ossimNitfLocalGeographicTag();
+   virtual ossimString getRegisterTagName()const;
+   virtual void parseStream(std::istream& in);
+   virtual void writeStream(std::ostream& out);
+   virtual ossim_uint32 getSizeInBytes()const;
+
+   virtual void clearFields();
+
+   virtual void setDegreesPerPixelLat(double deltaLat);
+   virtual void setDegreesPerPixelLon(double deltaLon);
+   virtual void setLatOrigin(double origin);
+   virtual void setLonOrigin(double origin);
+   
+protected:
+   /**
+    * FIELD: ARV
+    *
+    * required 9 byte field
+    *
+    * Longitude density
+    *
+    * This field shall contain the pixel ground spacing in E/W direction that is
+    * the number of pixels or elements intervals in 360 degrees.
+    * 9 BCS-N positive integer 000000002 to 999999999. 
+    */
+   char theLonDensity[10];
+
+   /**
+    * FIELD: BRV
+    *
+    * required 9 byte field
+    *
+    * Latitude density
+    *
+    * This field shall contain the pixel ground spacing in N/S direction that is the number of
+    * pixels or elements intervals in 360 degrees. 9 BCS-N positive integer 000000002 to 999999999 R 
+    */ 
+   char theLatDensity[10];
+
+   /**
+    * FIELD: LSO
+    * 
+    * required 15 byte field
+    *
+    * Longitude of Reference Origin This field shall contain the longitude of the origin pixel
+    * (row number 0, column number 0) in the absolute coordinate system. 15 BCS-N R 
+    */
+   char theLonOrigin[16];
+
+   /**
+    * FIELD: PSO
+    *
+    * required 15 byte field
+    *
+    * Latitude of Reference Origin This field shall contain the latitude of the origin
+    * pixel (row number 0, column number 0) in the absolute coordinate system. 15 BCS-N R 
+    */
+   char theLatOrigin[15];
+
+TYPE_DATA   
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfNameConversionTables.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfNameConversionTables.cpp
new file mode 100644
index 0000000000..ca4da14b8b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfNameConversionTables.cpp
@@ -0,0 +1,161 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimNitfNameConversionTables.cpp,v 1.4 2004/10/29 13:36:48 gpotts Exp $
+#include "ossimNitfNameConversionTables.h"
+
+
+struct ossimNitfMapProjectionCodeToOssimName
+{
+   char* nitfProjCode; // nitf code name
+   char* projectionName; // ossim projection name
+};
+
+struct ossimNitfMapProjectionCodeToNitfName
+{
+   char* nitfProjCode; // nitf code name
+   char* projectionName; // ossim projection name
+};
+
+static const ossimNitfMapProjectionCodeToOssimName mapProjectiontable[]=
+{
+   {"AC", "ossimAlbersProjection"},
+   {"AL", "ossimAzimEquDistProjection"},
+   {"BF", "ossimBonneProjection"},
+   {"CP", "ossimEquDistCylProjection"},
+   {"CP", "ossimLlxyProjection"},
+   {"CS", "ossimCassiniProjection"},
+   {"ED", "ossimEckert6Projection"},
+   {"EF", "ossimEckert4Projection"},
+   {"GN", "ossimGnomonicProjection"},
+   {"LE", "ossimLambertConformalConicProjection"},
+   {"LI", "ossimCylEquAreaProjection"},
+   {"MC", "ossimMercatorProjection"},
+   {"MH", "ossimMillerProjection"},
+   {"MP", "ossimMollweidProjection"},
+   {"NT", "ossimNewZealandMapGridProjection"},
+   {"OD", "ossimOrthoGraphicProjection"},
+   {"PG", "ossimPolarStereoProjection"},
+   {"PH", "ossimPolyconicProjection"},
+   {"SA", "ossimSinusoidalProjection"},
+   {"SX", "ossimSpaceObliqueMercatorProjection"},
+   {"TC", "ossimTransMercatorProjection"},
+   {"TX", "ossimTransCylEquAreaProjection"},
+   {"VA", "ossimVanDerGrintenProjection"},
+   {(char*)NULL, (char*)NULL}
+};
+
+static const ossimNitfMapProjectionCodeToNitfName nitfMapProjectiontable[]=
+{
+   {"AC", "Albers Equal-Area Conic"},
+   {"AK", "(Lambert) Azimuthal Equal-Area"},
+   {"AL", "Azimuthal Equidistant"},
+   {"BF", "Bonne"},
+   {"CC", "Equidistant Conic with 1 Standard Parallel"},
+   {"CP", "Equirectangular"},
+   {"CS", "Cassini-Soldner"},
+   {"ED", "Eckert VI"},
+   {"EF", "Eckert IV"},
+   {"GN", "Gnomonic"},
+   {"HX", "Hotine Oblique Mercator based on 2 Points"},
+   {"KA", " Equidistant Conic with 2 Standard Parallels"},
+   {"LA", "Laborde"},
+   {"LE", "Lambert Conformal Conic"},
+   {"LI", "Cylindrical Equal Area"},
+   {"LJ", " Lambert Equal-Area Meridional"},
+   {"MC", "Mercator"},
+   {"MH", "Miller Cylindrical"},
+   {"MJ", "French Lambert"},
+   {"MP", "Mollweide"},
+   {"NT", "New Zealand Map Grid"},
+   {"OC", "Oblique Mercator"},
+   {"OD", "Orthographic"},
+   {"PG", "Polar Stereographic"},
+   {"PH", "Polyconic"},
+   {"RS", "Hotine Oblique Mercator (Rectified Skew Orthomorphic)"},
+   {"RB", "Hotine Oblique Mercator (Rectified Skew Orthomorphic)"},
+   {"RX", "Robinson"},
+   {"SA", "Sinusoidal"},
+   {"SD", "Oblique Stereographic"},
+   {"SX", "Space Oblique Mercator"},
+   {"TC", " Transverse Mercator"},
+   {"TX", "Transverse Cylindrical Equal Area"},
+   {"VA", "Van der Grinten"},
+   {"VX", "General Vertical NearSide Perspective"},
+   {(char*)NULL, (char*)NULL}
+};
+
+ossimNitfNameConversionTables::ossimNitfNameConversionTables()
+{
+}
+
+ossimString ossimNitfNameConversionTables::convertMapProjectionNameToNitfCode(const ossimString& mapProjectionName)const
+{
+   ossim_uint32 idx = 0;
+
+   while(mapProjectiontable[idx].nitfProjCode)
+   {
+      if(mapProjectionName == mapProjectiontable[idx].projectionName)
+      {
+         return mapProjectiontable[idx].nitfProjCode;
+      }
+      ++idx;
+   }
+
+   return "";
+}
+
+ossimString ossimNitfNameConversionTables::convertNitfCodeToOssimProjectionName(const ossimString& nitfProjectionCode)const
+{
+   ossim_uint32 idx = 0;
+
+   while(mapProjectiontable[idx].nitfProjCode)
+   {
+      if(nitfProjectionCode == mapProjectiontable[idx].nitfProjCode)
+      {
+         return mapProjectiontable[idx].projectionName;
+      }
+      ++idx;
+   }
+
+   return "";
+}
+
+ossimString ossimNitfNameConversionTables::convertNitfCodeToNitfProjectionName(const ossimString& nitfProjectionCode)const
+{
+   ossim_uint32 idx = 0;
+
+   while(nitfMapProjectiontable[idx].nitfProjCode)
+   {
+      if(nitfProjectionCode == nitfMapProjectiontable[idx].nitfProjCode)
+      {
+         return nitfMapProjectiontable[idx].projectionName;
+      }
+      ++idx;
+   }
+
+   return "";
+}
+
+ossimString ossimNitfNameConversionTables::convertNitfProjectionNameToNitfCode(const ossimString& nitfProjectionName)const
+{
+   ossim_uint32 idx = 0;
+
+   while(nitfMapProjectiontable[idx].nitfProjCode)
+   {
+      if(nitfProjectionName ==  nitfMapProjectiontable[idx].projectionName)
+      {
+         return nitfMapProjectiontable[idx].nitfProjCode;
+      }
+      ++idx;
+   }
+
+   return "";
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfNameConversionTables.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfNameConversionTables.h
new file mode 100644
index 0000000000..05393e61b4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfNameConversionTables.h
@@ -0,0 +1,28 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimNitfNameConversionTables.h,v 1.3 2004/10/29 12:40:12 gpotts Exp $
+#ifndef ossimNitfNameConversionTables_HEADER
+#define ossimNitfNameConversionTables_HEADER
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimString.h>
+
+class OSSIM_DLL ossimNitfNameConversionTables
+{
+public:
+   ossimNitfNameConversionTables();
+
+   ossimString convertMapProjectionNameToNitfCode(const ossimString& mapProjectionName)const;
+   ossimString convertNitfCodeToOssimProjectionName(const ossimString& nitfProjectionCode)const;
+   ossimString convertNitfCodeToNitfProjectionName(const ossimString& nitfProjectionCode)const;
+   ossimString convertNitfProjectionNameToNitfCode(const ossimString& nitfProjectionName)const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfPackedBits.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfPackedBits.cpp
new file mode 100644
index 0000000000..7433a963d8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfPackedBits.cpp
@@ -0,0 +1,58 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class definition for ossimNitfTileSource.
+//*******************************************************************
+//  $Id: ossimNitfPackedBits.cpp,v 1.4 2004/11/11 20:17:25 gpotts Exp $
+#include "ossimNitfPackedBits.h"
+#include <iostream>
+
+ossimNitfPackedBits::ossimNitfPackedBits(ossim_uint8* packedBits, ossim_uint16 bits)
+      :thePackedBits(packedBits),
+       theBits(bits)
+{
+   theBytes    = theBits>>3;
+   theBitsLeft = theBits%8;
+}
+
+ossim_uint32 ossimNitfPackedBits::getValueAsUint32(ossim_uint32 idx)const
+{
+   ossim_uint32 value              = 0;
+   ossim_uint32 tempBits     = (theBitsLeft*idx);
+   ossim_uint32 tempBitShift = tempBits%8;
+   ossim_uint32 byteOffset = ( (idx*theBytes) +
+                               (tempBits>>3) );
+   ossim_uint32 bitCount = 0;
+   ossim_uint32 bitsSeen = tempBitShift;
+   ossim_uint8 bitmask = 1 << (7-tempBitShift);
+   while(bitCount < theBits)
+   {
+      value |= (ossim_uint8)((bool)(thePackedBits[byteOffset]&bitmask));
+      ++bitCount;
+      ++bitsSeen;
+      if(bitsSeen >= 8)
+      {
+         bitsSeen = 0;
+         bitmask = 0x80; // binary pattern 10000000
+         ++byteOffset;
+      }
+      else
+      {
+         bitmask>>=1;
+      }
+      if(bitCount < theBits)
+      {
+         value <<=1;
+      }
+   }
+   
+   return value;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfPackedBits.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfPackedBits.h
new file mode 100644
index 0000000000..2120475482
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfPackedBits.h
@@ -0,0 +1,41 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+// Description:
+//
+// Contains class definition for ossimNitfTileSource.
+//*******************************************************************
+//  $Id: ossimNitfPackedBits.h,v 1.2 2004/11/11 14:23:34 gpotts Exp $
+#ifndef ossimNitfPackedBits_HEADER
+#define ossimNitfPackedBits_HEADER
+#include <base/common/ossimConstants.h>
+/**
+ * This class will allow access to individual packed pixels given an offset and
+ * return as an ossim_uint32 type.
+ */
+class OSSIM_DLL ossimNitfPackedBits
+{
+public:
+   ossimNitfPackedBits(ossim_uint8* packedBits, ossim_uint16 bits);
+   /**
+    * Extract out the value at offset indicated by idx and convert the
+    * the vale to an ossim_uint32.  This class only supports packed bits
+    * less than 32.
+    */
+   ossim_uint32 getValueAsUint32(ossim_uint32 idx)const;
+   
+protected:
+   ossim_uint8* thePackedBits;
+   ossim_uint16 theBits;
+   ossim_uint16 theBytes;
+   ossim_uint16 theBitsLeft;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfProjectionParameterTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfProjectionParameterTag.cpp
new file mode 100644
index 0000000000..497c57b80f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfProjectionParameterTag.cpp
@@ -0,0 +1,188 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfProjectionParameterTag.cpp,v 1.4 2004/10/29 13:36:48 gpotts Exp $
+#include <support_data/nitf/ossimNitfProjectionParameterTag.h>
+#include <sstream>
+#include <iomanip>
+
+ossimNitfProjectionParameterTag::ossimNitfProjectionParameterTag()
+      :ossimNitfRegisteredTag()
+{
+   clearFields();
+}
+
+ossimNitfProjectionParameterTag::~ossimNitfProjectionParameterTag()
+{
+}
+
+ossimString ossimNitfProjectionParameterTag::getRegisterTagName()const
+{
+   return "PRJPSB";
+}
+
+void ossimNitfProjectionParameterTag::parseStream(std::istream& in)
+{
+   clearFields();
+   
+   in.read(theProjectionName, 80);
+   in.read(theProjectionCode, 2);
+   in.read(theNumberOfParameters, 1);
+
+   ossim_uint32 numberOfParameters = ossimString(theNumberOfParameters).toUInt32();
+
+   for(ossim_uint32 i = 0; i < numberOfParameters; ++i)
+   {
+      char param[15];
+
+      in.read(param, 15);
+      theProjectionParameters.push_back(ossimString(param,
+                                                    param + 15));
+   }
+   in.read(theFalseXOrigin, 15);
+   in.read(theFalseYOrigin, 15);
+}
+
+void ossimNitfProjectionParameterTag::writeStream(std::ostream& out)
+{
+   out.write(theProjectionName, 80);
+   out.write(theProjectionCode, 2);
+
+   {
+      ostringstream tempOut;
+
+      tempOut << std::setw(1)
+              << theProjectionParameters.size();
+      theNumberOfParameters[0] = *(tempOut.str().c_str());
+   }
+   out.write(theNumberOfParameters, 1);
+   ossim_uint32 numberOfParameters = ossimString(theNumberOfParameters).toUInt32();
+
+   for(ossim_uint32 i = 0; i < numberOfParameters; ++i)
+   {
+      out.write(theProjectionParameters[i].c_str(), 15);
+   }
+   out.write(theFalseXOrigin, 15);
+   out.write(theFalseYOrigin, 15);
+}
+
+ossim_uint32 ossimNitfProjectionParameterTag::getSizeInBytes()const
+{
+   return (113 + theProjectionParameters.size()*15);
+}
+
+std::ostream& ossimNitfProjectionParameterTag::print(std::ostream& out)const
+{
+   return out;   
+}
+    
+void ossimNitfProjectionParameterTag::clearFields()
+{
+   theProjectionParameters.clear();
+   
+   memset(theProjectionName, ' ', 80);
+   memset(theProjectionCode, ' ', 2);
+   memset(theNumberOfParameters, '0', 1);
+   memset(theFalseXOrigin, '0', 15);
+   memset(theFalseYOrigin, '0', 15);
+
+   theProjectionName[80] = '\0';
+   theProjectionCode[2] = '\0';
+   theNumberOfParameters[1] = '\0';
+   theFalseXOrigin[15] = '\0';
+   theFalseYOrigin[15] = '\0';
+}
+
+void ossimNitfProjectionParameterTag::clearParameters()
+{
+   theProjectionParameters.clear();
+   theNumberOfParameters[0] = '0';
+}
+
+void ossimNitfProjectionParameterTag::addParameter(const ossimString& param)
+{
+   std::ostringstream out;
+
+   out << std::setw(15)
+       << std::setfill('0')
+       << param.c_str();
+
+   theProjectionParameters.push_back(out.str());
+}
+
+void ossimNitfProjectionParameterTag::addParameter(const ossim_float64& param)
+{
+   addParameter(ossimString::toString(param));
+}
+
+void ossimNitfProjectionParameterTag::setName(const ossimString& name)
+{
+   std::ostringstream out;
+
+   out << std::setw(80)
+       << std::setfill(' ')
+       << name.c_str();
+
+   memcpy(theProjectionName, out.str().c_str(), 80);
+}
+
+void ossimNitfProjectionParameterTag::setCode(const ossimString& code)
+{
+   std::ostringstream out;
+
+   out << std::setw(2)
+       << std::setfill(' ')
+       << code.c_str();
+
+   memcpy(theProjectionCode, out.str().c_str(), 2);
+}
+
+ossimString ossimNitfProjectionParameterTag::getName()const
+{
+   return ossimString(theProjectionName).trim();
+}
+
+ossimString ossimNitfProjectionParameterTag::getCode()const
+{
+   return ossimString(theProjectionCode).trim();
+}
+
+void ossimNitfProjectionParameterTag::setFalseX(double falseX)
+{
+   std::ostringstream out;
+   out << std::setw(15)
+       << std::setprecision(15)
+       << std::setfill('0')
+       << falseX;
+   
+   memcpy(theFalseXOrigin, out.str().c_str(), 15);
+}
+
+void ossimNitfProjectionParameterTag::setFalseY(double falseY)
+{
+   std::ostringstream out;
+   out << std::setw(15)
+       << std::setprecision(15)
+       << std::setfill('0')
+       << falseY;
+   
+   memcpy(theFalseYOrigin, out.str().c_str(), 15);
+}
+
+double ossimNitfProjectionParameterTag::getFalseX()const
+{
+   return ossimString(theFalseXOrigin).toDouble();
+}
+
+double ossimNitfProjectionParameterTag::getFalseY()const
+{
+   return ossimString(theFalseYOrigin).toDouble();
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfProjectionParameterTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfProjectionParameterTag.h
new file mode 100644
index 0000000000..36ff29c8e6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfProjectionParameterTag.h
@@ -0,0 +1,324 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfProjectionParameterTag.h,v 1.4 2004/10/29 13:36:48 gpotts Exp $
+
+#ifndef ossimNitfProjectionParameterTag_HEADER
+#define ossimNitfProjectionParameterTag_HEADER
+#include <vector>
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class OSSIM_DLL ossimNitfProjectionParameterTag : public ossimNitfRegisteredTag
+{
+public:
+   ossimNitfProjectionParameterTag();
+   virtual ~ossimNitfProjectionParameterTag();
+   virtual ossimString getRegisterTagName()const;
+   virtual void parseStream(std::istream& in);
+   virtual void writeStream(std::ostream& out);
+   virtual std::ostream& print(std::ostream& out)const;
+   virtual ossim_uint32 getSizeInBytes()const;
+   virtual void clearFields();
+   virtual void clearParameters();
+   virtual void addParameter(const ossimString& param);
+   virtual void addParameter(const ossim_float64& param);
+   void setName(const ossimString& name);
+   void setCode(const ossimString& code);
+   ossimString getName()const;
+   ossimString getCode()const;
+   void setFalseX(double falseX);
+   void setFalseY(double falseY);
+   double getFalseX()const;
+   double getFalseY()const;
+   
+protected:
+   /**
+    * FIELD: PRN
+    *
+    * required 80 byte field.
+    * 
+    * Projection Name
+    *
+    * This field shall contain the name of the projection to which the Image Segment refers.
+    * The default value is Transverse Mercator.
+    */
+   char theProjectionName[81];
+
+   /**
+    *
+    * FIELD: PCO
+    *
+    * required 2 byte field.
+    * 
+    * Projection Code
+    *
+    * This field shall contain the code of the projection to which the Image Segment refers.
+    * The default value is TC.
+    *
+    * Code values:
+    *
+    * AC           Albers Equal-Area Conic
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. std. parallel nearer to equator
+    *                3. std parallel farther from equator
+    *                4. latitude of origin
+    *              
+    * AK           (Lambert) Azimuthal Equal-Area
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *              
+    * AL           Azimuthal Equidistant
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    * 
+    * BF           Bonne
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                3. Scale factor at projection origin
+    *                
+    * CC           Equidistant Conic with 1 Standard Parallel
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                3. Latitude of Std. Parallel
+    *                
+    * CP           Equirectangular
+    *              Parameters:
+    *                1. Longitude of central meridian 
+    *                2. Latitude of true scale
+    *                3. Radius of sphere
+    *                
+    * CS           Cassini-Soldner
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *            
+    * ED           Eckert VI
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Radius of sphere
+    * 
+    * EF           Eckert IV
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Radius of sphere
+    * 
+    * GN           Gnomonic
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    * 
+    * HX           Hotine Oblique Mercator based on 2 Points 
+    *              Parameters:
+    *                1. Scale factor at projection origin
+    *                2. latitude of projection origin
+    *                3. longitude of first point defining center line
+    *                4. latitude of fist point defining center line
+    *                
+    * KA           Equidistant Conic with 2 Standard Parallels 
+    *              Parameters:
+    *                1. Longitude of central meridian
+    *                2. Latitude of origin
+    *                3. Latitude of standard parallel Nearer to equator
+    *                4. Latitude of standard parallel farther from equator
+    *
+    * LA           Laborde
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                3. Scale factor at proj origin
+    *                4. Azimuth at origin of axis of constant scale
+    * 
+    * LE           Lambert Conformal Conic
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. std. parallel nearer to equator
+    *                3. std. parallel farther from equator
+    *                4. Latitude of origin
+    * 
+    * LI           Cylindrical Equal Area
+    *              Parameters:
+    *                1. Longitude of central meridian
+    *                2. Latitude of origin
+    *                
+    * LJ           Lambert Equal-Area Meridional
+    *              Parameters:
+    *                1. Longitude of central meridian
+    *                2. Latitude of origin
+    *                
+    * MC           Mercator
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of true scale
+    *                3. Latitude of reference origin
+    *                
+    * MH           Miller Cylindrical
+    *              Parameters:
+    *                1. Longitude of central meridian
+    *                2. Radius of sphere
+    *                
+    * MJ           French Lambert
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                3. Scale factor at proj origin
+    *                
+    * MP           Mollweide
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Radius of sphere
+    *                
+    * NT           New Zealand Map Grid
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                
+    * OC           Oblique Mercator
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                3. Azimuth
+    *                4. radius of sphere
+    *                
+    * OD           Orthographic
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                3. Radius of sphere
+    *                
+    * PG           Polar Stereographic
+    *              Parameters:
+    *                1. Latitude of true scale
+    *                
+    * PH           Polyconic
+    *              Parameters:
+    *                1. Longitude of central meridian
+    *                2. Latitude of origin
+    *                
+    * RS or RB     Hotine Oblique Mercator (Rectified Skew Orthomorphic)
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                3. Azimuth East of North for Central Line (Skew X-Axis at Proj. origin)
+    *                4. Scale factor at proj origin
+    *                
+    * RX           Robinson
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Radius of sphere
+    *                
+    * SA           Sinusoidal
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Radius of sphere
+    *               
+    * SD           Oblique Stereographic
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                3. Scale factor at origin
+    *                
+    * SX           Space Oblique Mercator
+    *              Parameters:
+    *                1. Application code:
+    *                     1 = Landsat, USGS equations
+    *                     2 = Landsat, EOSAT equations
+    *                2. Vehicle number
+    *                3. Orbital path number
+    *                
+    * TC           Transverse Mercator
+    *              Parameters:
+    *                1. Longitude of central meridian
+    *                2. Central Scale Factor
+    *                3. Latitude of origin
+    *                
+    * TX           Transverse Cylindrical Equal Area
+    *              Parameters:
+    *                1. Longitude of central meridian
+    *                2. Latitude of origin
+    *                3. Scale factor along central meridian
+    *                
+    * VA           Van der Grinten
+    *              Parameters:
+    *                1. Longitude of central meridian
+    *                2. Radius of sphere
+    * 
+    * VX           General Vertical NearSide Perspective
+    *              Parameters:
+    *                1. Longitude of origin
+    *                2. Latitude of origin
+    *                3. Heigh of perspective map above surface
+    *
+    * ZY           Other Known Projection
+    */
+   char theProjectionCode[3];
+
+   /**
+    * FIELD: NUM_PRJ
+    *
+    * required 1 byte field ranging from 0-9
+    * 
+    * Number of Projection Parameters
+    *
+    * This field shall contain the number of projection parameters.
+    * The PRJ Field should be repeated as necessary depending on the
+    * projection code (see Part 3-6).  If the number of projection parameters
+    * provided is lower than specified in Part 3-6, the
+    * missing parameters value is 0.
+    *
+    */
+   char              theNumberOfParameters[2];
+   
+   /**
+    * FIELD(S): PRJn
+    *
+    * Conditional 15 byte field each.
+    *
+    * Projection Parameter Each occurrence of this field provides an appropriate
+    * parameter to accurately describe the projection.  See Part 3-6 to know the
+    * kind of parameters needed for each projection code. 15 BCS-N C 
+    */
+   std::vector<ossimString> theProjectionParameters;
+   
+   /**
+    * FIELD: XOR
+    *
+    * required  15 byte field.
+    * 
+    * Projection False X (Easting) Origin
+    *
+    * This field shall contain the projection false X (easting) origin.
+    * The default value is 000000000000000, which implies that there is no projection false X origin.
+    * 
+    */
+   char theFalseXOrigin[16];
+
+
+   /**
+    * FIELD: YOR
+    *
+    * required 15 byte field.
+    *
+    * Projection False Y (Northing) Origin
+    *
+    * This field shall contain the projection false Y (northing) origin.
+    * The default value is 000000000000000, which implies that there is
+    * no projection false Y origin.
+    * 
+    */
+   char theFalseYOrigin[16];
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTag.cpp
new file mode 100644
index 0000000000..50b7d1ffdc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTag.cpp
@@ -0,0 +1,27 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfRegisteredTag.cpp,v 1.3 2004/09/28 13:29:09 gpotts Exp $
+#include "ossimNitfRegisteredTag.h"
+
+RTTI_DEF2(ossimNitfRegisteredTag, "ossimNitfRegisteredTag", ossimObject, ossimPropertyInterface)
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTag.h
new file mode 100644
index 0000000000..7ff5908b0b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTag.h
@@ -0,0 +1,51 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfRegisteredTag.h,v 1.8 2005/05/24 11:11:50 gpotts Exp $
+#ifndef ossimNitfRegisteredTag_HEADER
+#define ossimNitfRegisteredTag_HEADER
+#include <iostream>
+using namespace std;
+#include <base/common/ossimObject.h>
+#include <base/common/ossimPropertyInterface.h>
+
+class OSSIM_DLL ossimNitfRegisteredTag : public ossimObject ,
+                                         public ossimPropertyInterface
+{
+public:
+   ossimNitfRegisteredTag(){}
+   virtual ~ossimNitfRegisteredTag(){}
+   
+   /**
+    * 
+    * This will return the name of the registered tag for this
+    * user defined header.
+    * 
+    */
+   virtual ossimString getRegisterTagName()const=0;
+   
+   /**
+    * 
+    * This will allow the user defined data to parse the stream.
+    * 
+    */
+   virtual void parseStream(std::istream& in)=0;
+   virtual void writeStream(std::ostream& out)=0;
+
+   virtual ossim_uint32 getSizeInBytes()const=0;
+
+protected:
+   ossimString theRegisteredTagName;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTagFactory.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTagFactory.cpp
new file mode 100644
index 0000000000..941387fcd4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTagFactory.cpp
@@ -0,0 +1,103 @@
+//*******************************************************************
+// Copyright (C) 2004 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+//
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfRegisteredTagFactory.cpp,v 1.9 2005/10/13 21:20:02 dburken Exp $
+#include <support_data/nitf/ossimNitfRegisteredTagFactory.h>
+#include <support_data/nitf/ossimNitfBlockaTag.h>
+#include <support_data/nitf/ossimNitfGeoPositioningTag.h>
+#include <support_data/nitf/ossimNitfLocalGeographicTag.h>
+#include <support_data/nitf/ossimNitfLocalCartographicTag.h>
+#include <support_data/nitf/ossimNitfProjectionParameterTag.h>
+#include <support_data/nitf/ossimNitfRpcBTag.h>
+#include <support_data/nitf/ossimNitfRpcATag.h>
+#include <support_data/nitf/ossimNitfStdidcTag.h>
+#include <support_data/nitf/ossimNitfUse00aTag.h>
+
+
+RTTI_DEF1(ossimNitfRegisteredTagFactory, "ossimNitfRegisteredTagFactory", ossimNitfTagFactory);
+
+ossimNitfRegisteredTagFactory* ossimNitfRegisteredTagFactory::theInstance = NULL;
+
+static const char BLOCKA_TAG[]               = "BLOCKA";
+static const char GEO_POSITIONING_TAG[]      = "GEOPSB";
+static const char LOCAL_GEOGRAPHIC_TAG[]     = "GEOLOB";
+static const char LOCAL_CARTOGRAPHIC_TAG[]   = "MAPLOB";
+static const char PROJECTION_PARAMETER_TAG[] = "PRJPSB";
+static const char RPCB_TAG[]                 = "RPC00B";
+static const char RPCA_TAG[]                 = "RPC00A";
+static const char STDIDC_TAG[]               = "STDIDC";
+static const char USE00A_TAG[]               = "USE00A";
+
+ossimNitfRegisteredTagFactory::ossimNitfRegisteredTagFactory()
+{
+   theInstance = this;
+}
+
+ossimNitfRegisteredTagFactory::~ossimNitfRegisteredTagFactory()
+{
+   theInstance = NULL;
+}
+
+ossimNitfRegisteredTagFactory* ossimNitfRegisteredTagFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimNitfRegisteredTagFactory;
+   }
+
+   return theInstance;
+}
+
+ossimRefPtr<ossimNitfRegisteredTag> ossimNitfRegisteredTagFactory::create(
+   const ossimString& tagName)const
+{
+   ossimString name = ossimString(tagName).trim().upcase();
+   
+   if(tagName == BLOCKA_TAG)
+   {
+      return new ossimNitfBlockaTag;
+   }
+   else if(tagName == GEO_POSITIONING_TAG)
+   {
+      return new ossimNitfGeoPositioningTag;
+   }
+   else if(tagName == LOCAL_GEOGRAPHIC_TAG)
+   {
+      return new ossimNitfLocalGeographicTag;
+   }
+   else if(tagName == LOCAL_CARTOGRAPHIC_TAG)
+   {
+      return new ossimNitfLocalCartographicTag;
+   }
+   else if(tagName == PROJECTION_PARAMETER_TAG)
+   {
+      return new ossimNitfProjectionParameterTag;
+   }
+   else if(tagName == RPCB_TAG)
+   {
+      return new ossimNitfRpcBTag;
+   }
+   else if(tagName == RPCA_TAG)
+   {
+      return new ossimNitfRpcATag;
+   }
+   else if (tagName == STDIDC_TAG)
+   {
+      return new ossimNitfStdidcTag;
+   }
+   else if (tagName == USE00A_TAG)
+   {
+      return new ossimNitfUse00aTag;
+   }
+   
+   return NULL;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTagFactory.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTagFactory.h
new file mode 100644
index 0000000000..ec101e12ae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRegisteredTagFactory.h
@@ -0,0 +1,29 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level LICENSE.txt
+// 
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfRegisteredTagFactory.h,v 1.1 2004/09/28 19:37:23 gpotts Exp $
+#ifndef ossimNitfRegisteredTagFactory_HEADER
+#define ossimNitfRegisteredTagFactory_HEADER
+#include <support_data/nitf/ossimNitfTagFactory.h>
+
+class ossimNitfRegisteredTagFactory : public ossimNitfTagFactory
+{
+public:
+   ossimNitfRegisteredTagFactory();
+   virtual ~ossimNitfRegisteredTagFactory();
+   static ossimNitfRegisteredTagFactory* instance();
+   
+   virtual ossimRefPtr<ossimNitfRegisteredTag> create(const ossimString &tagName)const;
+
+protected:
+   static ossimNitfRegisteredTagFactory* theInstance;
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcATag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcATag.cpp
new file mode 100644
index 0000000000..58967af3de
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcATag.cpp
@@ -0,0 +1,28 @@
+//*******************************************************************
+// Copyright (C) 2000 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+//
+// Description: Nitf support class for RPC00A -
+// Rational Polynomial Coefficient extension.
+//
+//********************************************************************
+// $Id: ossimNitfRpcATag.cpp,v 1.4 2005/09/30 20:21:11 dburken Exp $
+
+#include <support_data/nitf/ossimNitfRpcATag.h>
+
+RTTI_DEF1(ossimNitfRpcATag, "ossimNitfRpcATag", ossimNitfRpcBase);
+
+ossimNitfRpcATag::ossimNitfRpcATag()
+   : ossimNitfRpcBase()
+{
+}
+
+ossimString ossimNitfRpcATag::getRegisterTagName() const
+{
+   return ossimString("RPC00A");
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcATag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcATag.h
new file mode 100644
index 0000000000..1ac07ad545
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcATag.h
@@ -0,0 +1,38 @@
+//*******************************************************************
+// Copyright (C) 2000 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+//
+// Description: Nitf support class for RPC00A -
+// Rational Polynomial Coefficient extension.
+//
+//********************************************************************
+// $Id: ossimNitfRpcATag.h,v 1.3 2005/09/28 18:29:29 dburken Exp $
+#ifndef ossimNitfRpcATag_HEADER
+#define ossimNitfRpcATag_HEADER
+
+#include <support_data/nitf/ossimNitfRpcBase.h>
+
+/**
+ * The layout of RPC00B is the same as RPC00A.  The difference is how the
+ * coefficients are used; hence, all the code is in the ossimNitfRpcBase class.
+ */
+class OSSIM_DLL ossimNitfRpcATag : public ossimNitfRpcBase
+{
+public:
+   
+   ossimNitfRpcATag();
+
+   /** @return "RPC00A" as an ossimString. */
+   virtual ossimString getRegisterTagName() const;
+   
+protected:
+   
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBTag.cpp
new file mode 100644
index 0000000000..221e5fc540
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBTag.cpp
@@ -0,0 +1,26 @@
+//*******************************************************************
+// Copyright (C) 2000 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfRpcBTag.cpp,v 1.3 2005/09/28 18:29:29 dburken Exp $
+
+#include <support_data/nitf/ossimNitfRpcBTag.h>
+
+RTTI_DEF1(ossimNitfRpcBTag, "ossimNitfRpcBTag", ossimNitfRpcBase);
+
+ossimNitfRpcBTag::ossimNitfRpcBTag()
+   : ossimNitfRpcBase()
+{
+}
+
+ossimString ossimNitfRpcBTag::getRegisterTagName() const
+{
+   return ossimString("RPC00B");
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBTag.h
new file mode 100644
index 0000000000..6c368bf0c8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBTag.h
@@ -0,0 +1,33 @@
+//*******************************************************************
+// Copyright (C) 2000 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfRpcBTag.h,v 1.4 2005/09/28 18:29:29 dburken Exp $
+#ifndef ossimNitfRpcBTag_HEADER
+#define ossimNitfRpcBTag_HEADER
+
+#include <support_data/nitf/ossimNitfRpcBase.h>
+
+/**
+ * The layout of RPC00B is the same as RPC00A.  The difference is how the
+ * coefficients are used; hence, all the code is in the ossimNitfRpcBase class.
+ */
+class OSSIM_DLL ossimNitfRpcBTag : public ossimNitfRpcBase
+{
+public:
+   ossimNitfRpcBTag();
+
+   /** @return "RPC00B" as an ossimString. */
+   virtual ossimString getRegisterTagName() const;
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBase.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBase.cpp
new file mode 100644
index 0000000000..6b19d32eeb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBase.cpp
@@ -0,0 +1,741 @@
+//*******************************************************************
+// Copyright (C) 2000 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+//
+// Description: Nitf support class for RPC00A -
+// Rational Polynomial Coefficient extension.
+//
+//********************************************************************
+// $Id: ossimNitfRpcBase.cpp,v 1.6 2005/10/12 10:47:03 dburken Exp $
+
+#include <support_data/nitf/ossimNitfRpcBase.h>
+#include <support_data/nitf/ossimNitfCommon.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/common/ossimTrace.h>
+
+static const ossimTrace traceDebug(ossimString("ossimNitfRpcBase:debug"));
+
+RTTI_DEF1(ossimNitfRpcBase, "ossimNitfRpcBase", ossimNitfRegisteredTag);
+
+#ifndef MIN
+#  define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+ossimNitfRpcBase::ossimNitfRpcBase()
+{
+   clearFields();
+}
+
+void ossimNitfRpcBase::parseStream(std::istream& in)
+{
+   clearFields();
+   
+   in.read(theSuccess, SUCCESS_SIZE);
+   in.read(theErrorBias, ERROR_BIAS_SIZE);
+   in.read(theErrRand, ERR_RAND_SIZE);
+   in.read(theLineOffset, LINE_OFFSET_SIZE);
+   in.read(theSampleOffset, SAMPLE_OFFSET_SIZE);
+   in.read(theGeodeticLatOffset, GEODETIC_LAT_OFFSET_SIZE);
+   in.read(theGeodeticLonOffset, GEODETIC_LON_OFFSET_SIZE);
+   in.read(theGeodeticHeightOffset, GEODETIC_HEIGHT_OFFSET_SIZE);
+   in.read(theLineScale, LINE_SCALE_SIZE);
+   in.read(theSampleScale, SAMPLE_SCALE_SIZE);
+   in.read(theGeodeticLatScale, GEODETIC_LAT_SCALE_SIZE);
+   in.read(theGeodeticLonScale, GEODETIC_LON_SCALE_SIZE);
+   in.read(theGeodeticHeightScale, GEODETIC_HEIGHT_SCALE_SIZE);
+   
+   ossim_uint32 idx = 0;
+   
+   char temp1[LINE_NUMERATOR_COEFFICIENT_SIZE+1];
+   temp1[LINE_NUMERATOR_COEFFICIENT_SIZE+1] = '\0';
+   for(idx = 0; idx < LINE_NUMERATOR_COEFFICIENT_COUNT; ++idx)
+   {
+      in.read(temp1, LINE_NUMERATOR_COEFFICIENT_SIZE);
+      theLineNumeratorCoefficient[idx] = temp1;
+   }
+   
+   char temp2[LINE_DENOMINATOR_COEFFICIENT_SIZE+1];
+   temp2[LINE_DENOMINATOR_COEFFICIENT_SIZE+1] = '\0';
+   for(idx = 0; idx < LINE_DENOMINATOR_COEFFICIENT_COUNT; ++idx)
+   {
+      in.read(temp2, LINE_DENOMINATOR_COEFFICIENT_SIZE);
+      theLineDenominatorCoefficient[idx] = temp2;
+   }
+   
+   char temp3[SAMPLE_NUMERATOR_COEFFICIENT_SIZE+1];
+   temp3[SAMPLE_NUMERATOR_COEFFICIENT_SIZE+1] = '\0';
+   for(idx = 0; idx < SAMPLE_NUMERATOR_COEFFICIENT_COUNT; ++idx)
+   {
+      in.read(temp3, SAMPLE_NUMERATOR_COEFFICIENT_SIZE);
+      theSampleNumeratorCoefficient[idx] = temp3;
+   }
+   
+   char temp4[SAMPLE_DENOMINATOR_COEFFICIENT_SIZE+1];
+   temp4[SAMPLE_DENOMINATOR_COEFFICIENT_SIZE+1] = '\0';
+   for(idx = 0; idx < SAMPLE_DENOMINATOR_COEFFICIENT_COUNT; ++idx)
+   {
+      in.read(temp4, SAMPLE_DENOMINATOR_COEFFICIENT_SIZE);
+      theSampleDenominatorCoefficient[idx] = temp4;
+   }
+}
+
+void ossimNitfRpcBase::writeStream(std::ostream& out)
+{
+   ossim_uint32 idx = 0;
+   
+   out.write(theSuccess, SUCCESS_SIZE);
+   out.write(theErrorBias, ERROR_BIAS_SIZE);
+   out.write(theErrRand, ERR_RAND_SIZE);
+   out.write(theLineOffset, LINE_OFFSET_SIZE);
+   out.write(theSampleOffset, SAMPLE_OFFSET_SIZE);
+   out.write(theGeodeticLatOffset, GEODETIC_LAT_OFFSET_SIZE);
+   out.write(theGeodeticLonOffset, GEODETIC_LON_OFFSET_SIZE);
+   out.write(theGeodeticHeightOffset, GEODETIC_HEIGHT_OFFSET_SIZE);
+   out.write(theLineScale, LINE_SCALE_SIZE);
+   out.write(theSampleScale, SAMPLE_SCALE_SIZE);
+   out.write(theGeodeticLatScale, GEODETIC_LAT_SCALE_SIZE);
+   out.write(theGeodeticLonScale, GEODETIC_LON_SCALE_SIZE);
+   out.write(theGeodeticHeightScale, GEODETIC_HEIGHT_SCALE_SIZE);
+   for(idx = 0; idx < LINE_NUMERATOR_COEFFICIENT_COUNT; ++idx)
+   {
+      out.write(theLineNumeratorCoefficient[idx].c_str(),
+                LINE_NUMERATOR_COEFFICIENT_SIZE);
+   }
+   for(idx = 0; idx < LINE_DENOMINATOR_COEFFICIENT_COUNT; ++idx)
+   {
+      out.write(theLineDenominatorCoefficient[idx].c_str(),
+                LINE_DENOMINATOR_COEFFICIENT_SIZE);
+   }
+   for(idx = 0; idx < SAMPLE_NUMERATOR_COEFFICIENT_COUNT; ++idx)
+   {
+      out.write(theSampleNumeratorCoefficient[idx].c_str(),
+                SAMPLE_NUMERATOR_COEFFICIENT_SIZE);
+   }
+   for(idx = 0; idx < SAMPLE_DENOMINATOR_COEFFICIENT_COUNT; ++idx)
+   {
+      out.write(theSampleDenominatorCoefficient[idx].c_str(),
+                SAMPLE_DENOMINATOR_COEFFICIENT_SIZE);
+   }
+}
+
+ossim_uint32 ossimNitfRpcBase::getSizeInBytes()const
+{
+   return 1041;
+}
+
+void ossimNitfRpcBase::clearFields()
+{
+   theSuccess[0] = '1';
+   memcpy(theErrorBias, "0000.00", 7);
+   memcpy(theErrRand, "0000.00", 7);
+   memcpy(theLineOffset, "000000", 6);
+   memcpy(theSampleOffset, "00000", 5);
+   memcpy(theGeodeticLatOffset, "+00.0000", 8);
+   memcpy(theGeodeticLonOffset, "+000.0000", 9);
+   memcpy(theGeodeticHeightOffset, "+0000", 5);
+   memcpy(theLineScale, "000001", 6);
+   memcpy(theSampleScale, "00001", 5);
+   memcpy(theGeodeticLatScale, "+00.0000", 8);
+   memcpy(theGeodeticLonScale, "+000.0000", 9);
+   memcpy(theGeodeticHeightScale, "+0000", 5);
+   
+   theSuccess[1] = '\0';
+   theErrorBias[7] = '\0';
+   theErrRand[7] = '\0';
+   theLineOffset[6] = '\0';
+   theSampleOffset[5] = '\0';
+   theGeodeticLatOffset[8]='\0';
+   theGeodeticLonOffset[9]='\0';
+   theGeodeticHeightOffset[5]='\0';
+   theLineScale[6]='\0';
+   theSampleScale[5]='\0';
+   theGeodeticLatScale[8]='\0';
+   theGeodeticLonScale[9]='\0';
+   theGeodeticHeightScale[5]='\0';
+   
+   theLineNumeratorCoefficient.resize(20);
+   theLineDenominatorCoefficient.resize(20);
+   theSampleNumeratorCoefficient.resize(20);
+   theSampleDenominatorCoefficient.resize(20);
+   
+   std::fill(theLineNumeratorCoefficient.begin(),
+             theLineNumeratorCoefficient.end(),
+             '0');
+   std::fill(theLineDenominatorCoefficient.begin(),
+             theLineDenominatorCoefficient.end(),
+             '0');
+   std::fill(theSampleNumeratorCoefficient.begin(),
+             theSampleNumeratorCoefficient.end(),
+             '0');
+   std::fill(theSampleDenominatorCoefficient.begin(),
+             theSampleDenominatorCoefficient.end(),
+             '0');
+}
+
+bool ossimNitfRpcBase::getSuccess()const
+{
+   return (theSuccess[0] == '1');
+}
+
+void ossimNitfRpcBase::setSuccess(bool success)
+{
+   theSuccess[0] = success?'1':'0';
+}
+
+ossimString ossimNitfRpcBase::getErrorBias()const
+{
+   return theErrorBias;
+}
+
+void ossimNitfRpcBase::setErrorBias(const ossim_float64& errorBias)
+{
+   ossimString os = ossimNitfCommon::convertToDoubleString(errorBias,
+                                                           2,
+                                                           ERROR_BIAS_SIZE);
+   setErrorBias(os);
+}
+
+void ossimNitfRpcBase::setErrorBias(const ossimString& errorBias)
+{
+   memset(theErrorBias, ' ', ERROR_BIAS_SIZE);
+   memcpy(theErrorBias, errorBias.c_str(), MIN(ERROR_BIAS_SIZE, errorBias.length()));
+}
+
+ossimString ossimNitfRpcBase::getErrorRand()const
+{
+   return theErrRand;
+}
+
+void ossimNitfRpcBase::setErrorRand(const ossim_float64& errorRand)
+{
+   ossimString os = ossimNitfCommon::convertToDoubleString(errorRand,
+                                                           2,
+                                                           ERROR_BIAS_SIZE);
+   setErrorRand(os);
+}
+
+void ossimNitfRpcBase::setErrorRand(const ossimString& errorRand)
+{
+   memset(theErrRand, ' ', ERR_RAND_SIZE);
+   memcpy(theErrRand, errorRand.c_str(), MIN(ERR_RAND_SIZE, errorRand.length()));
+}
+
+ossimString ossimNitfRpcBase::getLineOffset()const
+{
+   return theLineOffset;
+}
+
+void ossimNitfRpcBase::setLineOffset(ossim_uint32 lineOffset)
+{
+   ossimString os = ossimNitfCommon::convertToUIntString(lineOffset,
+                                                         LINE_OFFSET_SIZE);
+   setLineOffset(os);
+}
+
+void ossimNitfRpcBase::setLineOffset(const ossimString& lineOffset)
+{
+   memset(theLineOffset, ' ', LINE_OFFSET_SIZE);
+   memcpy(theLineOffset, lineOffset.c_str(), MIN(LINE_OFFSET_SIZE, lineOffset.length()));
+}
+
+ossimString ossimNitfRpcBase::getSampleOffset()const
+{
+   return theSampleOffset;
+}
+
+void ossimNitfRpcBase::setSampleOffset(ossim_uint32 sampleOffset)
+{
+   ossimString os = ossimNitfCommon::convertToUIntString(sampleOffset,
+                                                         SAMPLE_OFFSET_SIZE);
+   setSampleOffset(os);
+}
+
+void ossimNitfRpcBase::setSampleOffset(const ossimString& sampleOffset)
+{
+   memset(theSampleOffset, ' ', SAMPLE_OFFSET_SIZE);
+   memcpy(theSampleOffset, sampleOffset.c_str(), MIN(SAMPLE_OFFSET_SIZE, sampleOffset.length()));
+}
+
+ossimString ossimNitfRpcBase::getGeodeticLatOffset()const
+{
+   return theGeodeticLatOffset;
+}
+
+void ossimNitfRpcBase::setGeodeticLatOffset(
+   const ossim_float64& geodeticLatOffset)
+{
+   if ( (geodeticLatOffset >= -90.0) && (geodeticLatOffset <= 90.0) )
+   {
+      ossimString os =
+         ossimNitfCommon::convertToDoubleString(geodeticLatOffset,
+                                                4,
+                                                GEODETIC_LAT_OFFSET_SIZE);
+      setGeodeticLatOffset(os);
+   }
+}
+
+void ossimNitfRpcBase::setGeodeticLatOffset(
+   const ossimString& geodeticLatOffset)
+{
+   memset(theGeodeticLatOffset, ' ', GEODETIC_LAT_OFFSET_SIZE);
+   memcpy(theGeodeticLatOffset, geodeticLatOffset.c_str(), MIN(GEODETIC_LAT_OFFSET_SIZE, geodeticLatOffset.length()));
+}
+
+ossimString ossimNitfRpcBase::getGeodeticLonOffset()const
+{
+   return theGeodeticLonOffset;
+}
+
+void ossimNitfRpcBase::setGeodeticLonOffset(
+   const ossim_float64& geodeticLonOffset)
+{
+   if ( (geodeticLonOffset >= -180.0) && (geodeticLonOffset <= 180.0) )
+   {
+      ossimString os =
+         ossimNitfCommon::convertToDoubleString(geodeticLonOffset,
+                                                4,
+                                                GEODETIC_LON_OFFSET_SIZE);
+      setGeodeticLonOffset(os);
+   }
+}
+
+void ossimNitfRpcBase::setGeodeticLonOffset(const ossimString& geodeticLonOffset)
+{
+   memset(theGeodeticLonOffset, ' ', GEODETIC_LON_OFFSET_SIZE);
+   memcpy(theGeodeticLonOffset, geodeticLonOffset.c_str(), MIN(GEODETIC_LON_OFFSET_SIZE, geodeticLonOffset.length()));
+}
+
+ossimString ossimNitfRpcBase::getGeodeticHeightOffset()const
+{
+   return theGeodeticHeightOffset;
+}
+
+void ossimNitfRpcBase::setGeodeticHeightOffset(
+   ossim_int32 geodeticHeightOffset)
+{
+   ossimString os =
+      ossimNitfCommon::convertToIntString(geodeticHeightOffset,
+                                          GEODETIC_HEIGHT_OFFSET_SIZE);
+   setGeodeticHeightOffset(os);
+}
+
+void ossimNitfRpcBase::setGeodeticHeightOffset(const ossimString& geodeticHeightOffset)
+{
+   memset(theGeodeticHeightOffset, ' ', GEODETIC_HEIGHT_OFFSET_SIZE);
+   memcpy(theGeodeticHeightOffset, geodeticHeightOffset.c_str(), MIN(GEODETIC_HEIGHT_OFFSET_SIZE, geodeticHeightOffset.length()));
+}
+
+ossimString ossimNitfRpcBase::getLineScale()const
+{
+   return theLineScale;
+}
+
+void ossimNitfRpcBase::setLineScale(ossim_uint32 lineScale)
+{
+   ossimString os = ossimNitfCommon::convertToUIntString(lineScale,
+                                                         LINE_SCALE_SIZE);
+   setLineScale(os);
+}
+
+void ossimNitfRpcBase::setLineScale(const ossimString& lineScale)
+{
+   memset(theLineScale, ' ', LINE_SCALE_SIZE);
+   memcpy(theLineScale, lineScale.c_str(), MIN(LINE_SCALE_SIZE, lineScale.length()));
+}
+
+ossimString ossimNitfRpcBase::getSampleScale()const
+{
+   return theSampleScale;
+}
+
+void ossimNitfRpcBase::setSampleScale(ossim_uint32 sampleScale)
+{
+   ossimString os = ossimNitfCommon::convertToUIntString(sampleScale,
+                                       SAMPLE_SCALE_SIZE);
+   setSampleScale(os);
+}
+
+void ossimNitfRpcBase::setSampleScale(const ossimString& sampleScale)
+{
+   memset(theSampleScale, ' ', SAMPLE_SCALE_SIZE);
+   memcpy(theSampleScale, sampleScale.c_str(), MIN(SAMPLE_SCALE_SIZE, sampleScale.length()));
+}
+
+ossimString ossimNitfRpcBase::getGeodeticLatScale()const
+{
+   return theGeodeticLatScale;
+}
+
+void ossimNitfRpcBase::setGeodeticLatScale(
+   const ossim_float64& geodeticLatScale)
+{
+   if (geodeticLatScale == 0.0)
+   {
+      // Error scale cannot be zero.
+      return;
+   }
+   
+   if ( (geodeticLatScale >= -90.0) && (geodeticLatScale <= 90.0) )
+   {
+      ossimString os = ossimNitfCommon::convertToDoubleString(geodeticLatScale,
+                                             4,
+                                             GEODETIC_LAT_SCALE_SIZE);
+      setGeodeticLatScale(os);
+   }
+}
+
+void ossimNitfRpcBase::setGeodeticLatScale(const ossimString& geodeticLatScale)
+{
+   memset(theGeodeticLatScale, ' ', GEODETIC_LAT_SCALE_SIZE);
+   memcpy(theGeodeticLatScale, geodeticLatScale.c_str(), MIN(GEODETIC_LAT_SCALE_SIZE, geodeticLatScale.length()));
+}
+
+ossimString ossimNitfRpcBase::getGeodeticLonScale()const
+{
+   return theGeodeticLonScale;
+}
+
+void ossimNitfRpcBase::setGeodeticLonScale(
+   const ossim_float64& geodeticLonScale)
+{
+   if (geodeticLonScale == 0.0)
+   {
+      // Error scale cannot be zero.
+      return;
+   }
+   
+   if ( (geodeticLonScale >= -180.0) && (geodeticLonScale <= 180.0) )
+   {
+      ossimString os = ossimNitfCommon::convertToDoubleString(geodeticLonScale,
+                                             4,
+                                             GEODETIC_LON_SCALE_SIZE);
+      setGeodeticLonScale(os);
+   }
+}
+
+void ossimNitfRpcBase::setGeodeticLonScale(const ossimString& geodeticLonScale)
+{
+   memset(theGeodeticLonScale, ' ', GEODETIC_LON_SCALE_SIZE);
+   memcpy(theGeodeticLonScale, geodeticLonScale.c_str(), MIN(GEODETIC_LON_SCALE_SIZE, geodeticLonScale.length()));
+}
+
+ossimString ossimNitfRpcBase::getGeodeticHeightScale()const
+{
+   return theGeodeticHeightScale;
+}
+
+void ossimNitfRpcBase::setGeodeticHeightScale(ossim_int32 geodeticHeightScale)
+{
+   ossimString os =
+      ossimNitfCommon::convertToIntString(geodeticHeightScale,
+                                          GEODETIC_HEIGHT_SCALE_SIZE);
+   setGeodeticHeightScale(os);
+}
+
+void ossimNitfRpcBase::setGeodeticHeightScale(
+   const ossimString& geodeticHeightScale)
+{
+   memset(theGeodeticHeightScale, ' ', GEODETIC_HEIGHT_SCALE_SIZE);
+   memcpy(theGeodeticHeightScale, geodeticHeightScale.c_str(), MIN(GEODETIC_HEIGHT_SCALE_SIZE, geodeticHeightScale.length()));
+}
+
+/* Temp comment out until range error handling is decided.*/
+#if 0
+// The assert here will be ignored when compiled with -DNDEBUG so ossimSetError and fix the index
+#define ASSERT_ARRAY_CONSTRAINT(expression, idx, correctedValue, module) \
+   assert(expression);                                                  \
+   ossimSetError(getClassName().c_str(), ossimErrorCodes::OSSIM_ERROR,  \
+                 "File %s line %d Module %s Error:\nArray index constraint error.\n", \
+                 __FILE__, __LINE__, module);                           \
+   if (! (expression) ) idx = correctedValue;
+
+#endif
+   
+ossimString ossimNitfRpcBase::getLineNumeratorCoeff(ossim_uint32 idx)const
+{
+//ASSERT_ARRAY_CONSTRAINT(idx >= 0 && idx < LINE_NUMERATOR_COEFFICIENT_COUNT,idx,0,"ossimNitfRpcBase::getLineNumeratorCoeff");
+
+   if (idx >= LINE_NUMERATOR_COEFFICIENT_COUNT)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << "ossimNitfRpcBase::getLineNumeratorCoeff range error!"
+            << endl;
+      }
+      return ossimString();
+   }
+   
+   return theLineNumeratorCoefficient[idx];
+}
+
+void ossimNitfRpcBase::setLineNumeratorCoeff(
+   const vector<ossim_float64>& coeff)
+{
+   if (coeff.size() != LINE_NUMERATOR_COEFFICIENT_COUNT)
+   {
+      // Error...
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfRpcBase::setLineNumeratorCoeff WARNING:"
+            << "\nArray not of correct size!"
+            << endl;
+      }
+      return;
+   }
+
+   for (ossim_uint32 i = 0; i < LINE_NUMERATOR_COEFFICIENT_COUNT; ++i)
+   {
+      ossimString os = ossimNitfCommon::convertToScientificString(
+         coeff[i], LINE_NUMERATOR_COEFFICIENT_SIZE);
+      setLineNumeratorCoeff(i, os);
+   }
+}
+
+void ossimNitfRpcBase::setLineNumeratorCoeff(ossim_uint32 idx,
+                                             const ossimString& coeff)
+{
+   // ASSERT_ARRAY_CONSTRAINT(idx >= 0 && idx < LINE_NUMERATOR_COEFFICIENT_COUNT,idx,0,"ossimNitfRpcBase::setLineNumeratorCoeff");
+
+   if (idx >= LINE_NUMERATOR_COEFFICIENT_COUNT)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimNitfRpcBase::setLineNumeratorCoeff range error!"
+         << endl;
+      return;
+   } 
+
+   string s(coeff, 0, LINE_NUMERATOR_COEFFICIENT_SIZE);
+   theLineNumeratorCoefficient[idx] = s;  
+}
+
+ossimString ossimNitfRpcBase::getLineDenominatorCoeff(ossim_uint32 idx)const
+{
+   // ASSERT_ARRAY_CONSTRAINT(idx >= 0 && idx < LINE_DENOMINATOR_COEFFICIENT_COUNT,idx,0,"ossimNitfRpcBase::getLineDenominatorCoeff");
+
+   if (idx >= LINE_DENOMINATOR_COEFFICIENT_COUNT)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimNitfRpcBase::getLineDenominatorCoeff range error!"
+         << endl;
+      return ossimString();
+   }  
+   
+   return theLineDenominatorCoefficient[idx];
+}
+
+void ossimNitfRpcBase::setLineDenominatorCoeff(
+   const vector<ossim_float64>& coeff)
+{
+   if (coeff.size() != LINE_DENOMINATOR_COEFFICIENT_COUNT)
+   {
+      // Error...
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfRpcBase::setLineDenominatorCoeff WARNING:"
+            << "\nArray not of correct size!"
+            << endl;
+      }
+      return;
+   }
+
+   for (ossim_uint32 i = 0; i < LINE_DENOMINATOR_COEFFICIENT_COUNT; ++i)
+   {
+      ossimString os = ossimNitfCommon::convertToScientificString(
+         coeff[i], LINE_DENOMINATOR_COEFFICIENT_SIZE);
+      setLineDenominatorCoeff(i, os);
+   }
+}
+
+void ossimNitfRpcBase::setLineDenominatorCoeff(ossim_uint32 idx,
+                                               const ossimString& coeff)
+{
+   // ASSERT_ARRAY_CONSTRAINT(idx >= 0 && idx < LINE_DENOMINATOR_COEFFICIENT_COUNT,idx,0,"ossimNitfRpcBase::setLineDenominatorCoeff");
+
+   if (idx >= LINE_DENOMINATOR_COEFFICIENT_COUNT)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimNitfRpcBase::setLineDenominatorCoeff range error!"
+         << endl;
+      return;
+   } 
+   
+   string s(coeff, 0, LINE_DENOMINATOR_COEFFICIENT_SIZE);
+   theLineDenominatorCoefficient[idx] = s;  
+}
+
+ossimString ossimNitfRpcBase::getSampleNumeratorCoeff(ossim_uint32 idx)const
+{
+   // ASSERT_ARRAY_CONSTRAINT(idx >= 0 && idx < SAMPLE_NUMERATOR_COEFFICIENT_COUNT,idx,0,"ossimNitfRpcBase::getSampleNumeratorCoeff");
+
+   if (idx >= SAMPLE_NUMERATOR_COEFFICIENT_COUNT)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimNitfRpcBase::getSampleNumeratorCoeff range error!"
+         << endl;
+      return ossimString();
+   } 
+   return theSampleNumeratorCoefficient[idx];
+}
+
+void ossimNitfRpcBase::setSampleNumeratorCoeff(
+   const vector<ossim_float64>& coeff)
+{
+   if (coeff.size() != SAMPLE_NUMERATOR_COEFFICIENT_COUNT)
+   {
+      // Error...
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfRpcBase::setSampleNumeratorCoeff WARNING:"
+            << "\nArray not of correct size!"
+            << endl;
+      }
+      return;
+   }
+
+   for (ossim_uint32 i = 0; i < SAMPLE_NUMERATOR_COEFFICIENT_COUNT; ++i)
+   {
+      ossimString os = ossimNitfCommon::convertToScientificString(
+         coeff[i], SAMPLE_NUMERATOR_COEFFICIENT_SIZE);
+      setSampleNumeratorCoeff(i, os);
+   }
+}
+
+void ossimNitfRpcBase::setSampleNumeratorCoeff(ossim_uint32 idx,
+                                               const ossimString& coeff)
+{
+   // ASSERT_ARRAY_CONSTRAINT(idx >= 0 && idx < SAMPLE_NUMERATOR_COEFFICIENT_COUNT,idx,0,"ossimNitfRpcBase::setSampleNumeratorCoeff");
+
+   if (idx >= SAMPLE_NUMERATOR_COEFFICIENT_COUNT)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimNitfRpcBase::setSampleNumeratorCoeff range error!"
+         << endl;
+      return;
+   } 
+   
+   string s(coeff, 0, SAMPLE_NUMERATOR_COEFFICIENT_SIZE);
+   theSampleNumeratorCoefficient[idx] = s;  
+}
+
+ossimString ossimNitfRpcBase::getSampleDenominatorCoeff(ossim_uint32 idx)const
+{
+   // ASSERT_ARRAY_CONSTRAINT(idx >= 0 && idx < SAMPLE_DENOMINATOR_COEFFICIENT_COUNT,idx,0,"ossimNitfRpcBase::getSampleDenominatorCoeff");
+
+   if (idx >= SAMPLE_DENOMINATOR_COEFFICIENT_COUNT)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimNitfRpcBase::getSampleDenominatorCoeff range error!"
+         << endl;
+      return ossimString();
+   } 
+   
+   return theSampleDenominatorCoefficient[idx];
+}
+
+void ossimNitfRpcBase::setSampleDenominatorCoeff(
+   const vector<ossim_float64>& coeff)
+{
+   if (coeff.size() != SAMPLE_DENOMINATOR_COEFFICIENT_COUNT)
+   {
+      // Error...
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "ossimNitfRpcBase::setSampleDenominatorCoeff WARNING:"
+            << "\nArray not of correct size!"
+            << endl;
+      }
+      return;
+   }
+
+   for (ossim_uint32 i = 0; i < SAMPLE_DENOMINATOR_COEFFICIENT_COUNT; ++i)
+   {
+      ossimString os = ossimNitfCommon::convertToScientificString(
+         coeff[i], SAMPLE_DENOMINATOR_COEFFICIENT_SIZE);
+      setSampleDenominatorCoeff(i, os);
+   }
+}
+
+void ossimNitfRpcBase::setSampleDenominatorCoeff(
+   ossim_uint32 idx, const ossimString& coeff)
+{
+   // ASSERT_ARRAY_CONSTRAINT(idx >= 0 && idx < SAMPLE_DENOMINATOR_COEFFICIENT_COUNT,idx,0,"ossimNitfRpcBase::setSampleDenominatorCoeff");
+
+   if (idx >= SAMPLE_DENOMINATOR_COEFFICIENT_COUNT)
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "ossimNitfRpcBase::setSampleDenominatorCoeff range error!"
+         << endl;
+      return;
+   }
+   
+  string s(coeff, 0, SAMPLE_DENOMINATOR_COEFFICIENT_SIZE);
+  s.resize(SAMPLE_DENOMINATOR_COEFFICIENT_SIZE, ' ');
+  theSampleDenominatorCoefficient[idx] = s;  
+}
+
+std::ostream& ossimNitfRpcBase::print(std::ostream& out) const
+{
+   out << "ossimNitfRpcBase::print"
+       << "\ntheSuccess:               " << theSuccess
+       << "\ntheErrorBias:             " << theErrorBias
+       << "\ntheErrRand:               " << theErrRand
+       << "\ntheLineOffset:            " << theLineOffset
+       << "\ntheSampleOffset:          " << theSampleOffset
+       << "\ntheGeodeticLatOffset:     " << theGeodeticLatOffset
+       << "\ntheGeodeticLonOffset:     " << theGeodeticLonOffset
+       << "\ntheGeodeticHeightOffset:  " << theGeodeticHeightOffset
+       << "\ntheLineScale:             " <<theLineScale
+       << "\ntheSampleScale:           " << theSampleScale
+       << "\ntheGeodeticLatScale:      " << theGeodeticLatScale
+       << "\ntheGeodeticLonScale:      " << theGeodeticLonScale
+       << "\ntheGeodeticHeightScale:   " << theGeodeticHeightScale
+       << std::endl;
+
+   ossim_int32 i;
+   
+   for (i=0; i<LINE_NUMERATOR_COEFFICIENT_COUNT; ++i)
+   {
+      out << "\ntheLineNumeratorCoefficient[" << i << "]: "
+          << theLineNumeratorCoefficient[i];
+   }
+
+   out << std::endl;
+   
+   for (i=0; i<LINE_DENOMINATOR_COEFFICIENT_COUNT; ++i)
+   {
+      out << "\ntheLineDenominatorCoefficient[" << i << "]: "
+          << theLineDenominatorCoefficient[i];
+   }
+
+   out << std::endl;
+   
+
+   for (i=0; i<SAMPLE_NUMERATOR_COEFFICIENT_COUNT; ++i)
+   {
+      out << "\ntheSampleNumeratorCoefficient[" << i << "]: "
+          << theSampleNumeratorCoefficient[i];
+   }
+
+   out << std::endl;
+   
+
+   for (i=0; i<SAMPLE_DENOMINATOR_COEFFICIENT_COUNT; ++i)
+   {
+      out << "\ntheSampleDenominatorCoefficient[" << i << "]: "
+          << theSampleDenominatorCoefficient[i];
+   }
+
+   out << std::endl;
+      
+   return out;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBase.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBase.h
new file mode 100644
index 0000000000..72040c865a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpcBase.h
@@ -0,0 +1,546 @@
+//*******************************************************************
+// Copyright (C) 2000 Intelligence Data Systems. 
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Garrett Potts
+//
+// Description: Nitf base support data class for RPC tags.
+// 
+// Rational Polynomial Coefficient extension.
+//
+// See: http://164.214.2.51/ntb/baseline/docs/stdi0002/final.pdf
+//
+//********************************************************************
+// $Id: ossimNitfRpcBase.h,v 1.6 2005/10/12 10:47:03 dburken Exp $
+#ifndef ossimNitfRpcBase_HEADER
+#define ossimNitfRpcBase_HEADER
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class OSSIM_DLL ossimNitfRpcBase : public ossimNitfRegisteredTag
+{
+ public:
+  enum 
+  {
+    SUCCESS_SIZE                         = 1,
+    ERROR_BIAS_SIZE                      = 7,
+    ERR_RAND_SIZE                        = 7,
+    LINE_OFFSET_SIZE                     = 6,
+    SAMPLE_OFFSET_SIZE                   = 5,
+    GEODETIC_LAT_OFFSET_SIZE             = 8,
+    GEODETIC_LON_OFFSET_SIZE             = 9,
+    GEODETIC_HEIGHT_OFFSET_SIZE          = 5,
+    LINE_SCALE_SIZE                      = 6,
+    SAMPLE_SCALE_SIZE                    = 5,
+    GEODETIC_LAT_SCALE_SIZE              = 8,
+    GEODETIC_LON_SCALE_SIZE              = 9,
+    GEODETIC_HEIGHT_SCALE_SIZE           = 5,
+    LINE_NUMERATOR_COEFFICIENT_SIZE      = 12,
+    LINE_NUMERATOR_COEFFICIENT_COUNT     = 20,
+    LINE_DENOMINATOR_COEFFICIENT_SIZE    = 12,
+    LINE_DENOMINATOR_COEFFICIENT_COUNT   = 20,
+    SAMPLE_NUMERATOR_COEFFICIENT_SIZE    = 12,
+    SAMPLE_NUMERATOR_COEFFICIENT_COUNT   = 20,
+    SAMPLE_DENOMINATOR_COEFFICIENT_SIZE  = 12,
+    SAMPLE_DENOMINATOR_COEFFICIENT_COUNT = 20
+    //                                  -----
+    //                                   1041
+  };
+
+  /** default constructor */
+  ossimNitfRpcBase();
+
+  /**
+   * Parse method.
+   *
+   * @param in Stream to parse.
+   */
+  virtual void parseStream(std::istream& in);
+
+  /**
+   * Write method.
+   *
+   * @param out Stream to write to.
+   */
+  virtual void writeStream(std::ostream& out);
+
+  /** @return The size of this record in bytes (1041) within a nitf file. */
+  virtual ossim_uint32 getSizeInBytes()const;
+
+  /**
+   * Clears all string fields within the record to some default nothingness.
+   */
+  virtual void clearFields();
+
+  /**
+   * @return The success record as a boolean.
+   *
+   * @note Per spec always true.
+   */
+  bool getSuccess()const;
+
+  /** @param success Sets data member theSuccess to success. */
+  void setSuccess(bool success);
+
+  /** @return theErrorBias as a string. */
+  ossimString getErrorBias()const;
+
+  //---
+  // The set methods below taking ossimString args will truncate and
+  // pad with spaces, as necessary, to match enumed size.
+  //---
+
+  /**
+   * @param errorBias Error bias to set theErrorBias to.  This will be
+   * converted to a string with two digit precision.
+   */
+  void setErrorBias(const ossim_float64& errorBias);
+
+  /** @param errorBias bias string to set theErrorBias to. */
+  void setErrorBias(const ossimString& errorBias);
+
+  /** @return theErrorBias as a string. */
+  ossimString getErrorRand()const;
+
+  /**
+   * @param errorRand The random error to set theErrRand to.  This will be
+   * converted to a string with two digit precision.
+   */
+  void setErrorRand(const ossim_float64& errorRand);
+
+  
+  /** @param errorRand error random  string to set theErrorRand to. */
+  void setErrorRand(const ossimString& errorRand);
+
+  /** @return The line offset as a string. */
+  ossimString getLineOffset()const;
+
+  /**
+   * @param lineOffset Sets the line offset to a string truncated to an int.
+   */
+  void setLineOffset(ossim_uint32 lineOffset);
+
+  /**
+   * @param lineOffset Sets theLineOffset to lineOffset string.
+   */
+  void setLineOffset(const ossimString& lineOffset);
+
+  /** @return The sample offset as a string. */
+  ossimString getSampleOffset()const;
+
+  /**
+   * @param sampleOffset Sets the sample offset to a string truncated to an
+   * int.
+   */
+  void setSampleOffset(ossim_uint32 sampleOffset);
+
+  /** @param sampleOffset Sets the sample offset to a string. */
+  void setSampleOffset(const ossimString& sampleOffset);
+
+  /** @return Geodetic latitude offset as a string. */
+  ossimString getGeodeticLatOffset()const;
+
+  /**
+   * @param geodeticLatOffset Value to Set the geodedic latitude offset to.
+   * Converted to a string with four digit precision.
+   */
+  void setGeodeticLatOffset(const ossim_float64& geodeticLatOffset);
+
+  /**
+   * @param geodeticLatOffset geodedic latitude offset string to set
+   * theGeodeticLatOffset to.
+   */
+  void setGeodeticLatOffset(const ossimString& geodeticLatOffset);
+
+  /** @return Geodetic longitude offset as a string. */
+  ossimString getGeodeticLonOffset()const;
+
+  /**
+   * @param geodeticLonOffset Value to Set the geodedic longitude offset to.
+   * Converted to a string with four digit precision.
+   */
+  void setGeodeticLonOffset(const ossim_float64& geodeticLonOffset);
+
+  /**
+   * @param geodeticLonOffset Value to Set the geodedic longitude offset to.
+   */
+  void setGeodeticLonOffset(const ossimString& geodeticLonOffset);
+
+  /** @return Geodetic height offset as a string. */
+  ossimString getGeodeticHeightOffset()const;
+
+  /**
+   * @param geodeticHeightOffset value to Set the height offset to.
+   * Converted to a string truncated to an int.
+   */
+  void setGeodeticHeightOffset(ossim_int32 geodeticHeightOffset);
+  
+  /** @param geodeticHeightOffset value to Set the height offset to. */
+  void setGeodeticHeightOffset(const ossimString& geodeticHeightOffset);
+
+  /** @return The line scale as a string. */
+  ossimString getLineScale()const;
+  
+  /**
+   * @param lineScale The value to set the line scale to.
+   * Converted to a string.
+   */
+  void setLineScale(ossim_uint32 lineScale);
+
+  /**
+   * @param lineScale The value to set the line scale to.
+   */
+  void setLineScale(const ossimString& lineScale);
+
+  /**
+   * @return the sample scale as a string.
+   */
+  ossimString getSampleScale()const;
+
+  /**
+   * @param sampleScale The value to set the sample scale to.
+   * Converted to a string truncated to an int.
+   */
+  void setSampleScale(ossim_uint32 sampleScale);
+
+  /**
+   * @param sampleScale The value to set the sample scale to.
+   */
+  void setSampleScale(const ossimString& sampleScale);
+
+  /** @return The Geodetic latitude scale as a string. */
+  ossimString getGeodeticLatScale()const;
+
+  /**
+   * @param geodeticLatScale The value to set the geodedic latitude scale to.
+   * Converted to a string with four digit precision.
+   */
+  void setGeodeticLatScale(const ossim_float64& geodeticLatScale);
+
+  /**
+   * @param geodeticLatScale The value to set the geodedic latitude scale to.
+   */
+  void setGeodeticLatScale(const ossimString& geodeticLatScale);
+
+  /** @return Geodetic longitude scale as a string. */
+  ossimString getGeodeticLonScale()const;
+
+  /**
+   * @param geodeticLonScale The value to set the geodedic longitude scale to.
+   * Converted to a string with four digit precision.
+   */
+  void setGeodeticLonScale(const ossim_float64& geodeticLonScale);
+
+  /**
+   * @param geodeticLonScale The value to set the geodedic longitude scale to.
+   */
+  void setGeodeticLonScale(const ossimString& geodeticLonScale);
+
+  /** @return The geodetic height scale as a string. */
+  ossimString getGeodeticHeightScale()const;
+
+  /**
+   * @param geodeticHeightScale The value to set the height scale to.
+   * Converted to a string truncated to an int.
+   */
+  void setGeodeticHeightScale(ossim_int32 geodeticHeightScale);
+  
+  /**
+   * @param geodeticHeightScale The value to set the height scale to.
+   */
+  void setGeodeticHeightScale(const ossimString& geodeticHeightScale);
+
+  /**
+   * @param idx Index of line numerator coefficient to get.
+   * Range: 0 - 19
+   *
+   * @return The line numerator coefficient as a string.
+   */
+  ossimString getLineNumeratorCoeff(ossim_uint32 idx)const;
+
+  /**
+   * @param coeff This should be an array of 20 line numerator coefficients.
+   * Coefficients will be converted to a scientific string to conform to
+   * specification.
+   *
+   * @note if (coeff.size() != 20) no action is taken.
+   */  
+  void setLineNumeratorCoeff(const vector<ossim_float64>& coeff);
+  
+  /**
+   * @param idx index of line numerator coefficient to set.
+   * Range: 0 - 19
+   *
+   * @param coeff Value to set line numerator coefficient to for
+   * idx or index.
+   */  
+  void setLineNumeratorCoeff(ossim_uint32 idx,
+                             const ossimString& coeff);
+
+  /**
+   * @param idx index of line denominator coefficient to get.
+   * Range: 0 - 19
+   *
+   * @return line  denominator coefficient as a string.
+   */
+  ossimString getLineDenominatorCoeff(ossim_uint32 idx)const;
+  
+  /**
+   * @param coeff This should be an array of 20 line denominator coefficients.
+   * Coefficients will be converted to a scientific string to conform to
+   * specification.
+   *
+   * @note if (coeff.size() != 20) no action is taken.
+   */  
+  void setLineDenominatorCoeff(const vector<ossim_float64>& coeff);
+  
+  /**
+   * @param idx index of line denominator coefficient to set.
+   * Range: 0 - 19
+   *
+   * @param lineDenominatorCoeff Value to set line denominator coefficient
+   * to for idx or index.
+   */  
+  void setLineDenominatorCoeff(ossim_uint32 idx,
+                               const ossimString& coeff);
+
+  /**
+   * @param idx Index of sample numerator coefficient to get.
+   * Range: 0 - 19
+   *
+   * @return The sample numerator coefficient as a string.
+   */
+  ossimString getSampleNumeratorCoeff(ossim_uint32 idx)const;
+
+  /**
+   * @param coeff This should be an array of 20 sample numerator coefficients.
+   * Coefficients will be converted to a scientific string to conform to
+   * specification.
+   *
+   * @note if (coeff.size() != 20) no action is taken.
+   */  
+  void setSampleNumeratorCoeff(const vector<ossim_float64>& coeff);
+  
+  /**
+   * @param idx index of sample numerator coefficient to set.
+   * Range: 0 - 19
+   *
+   * @param coeff Value to set sample numerator coefficient to for
+   * idx or index.
+   */  
+  void setSampleNumeratorCoeff(ossim_uint32 idx,
+                             const ossimString& coeff);
+
+  /**
+   * @param idx index of sample denominator coefficient to get.
+   * Range: 0 - 19
+   *
+   * @return sample  denominator coefficient as a string.
+   */
+  ossimString getSampleDenominatorCoeff(ossim_uint32 idx)const;
+  
+  /**
+   * @param coeff This should be an array of 20 sample denominator coefficients.
+   * Coefficients will be converted to a scientific string to conform to
+   * specification.
+   *
+   * @note if (coeff.size() != 20) no action is taken.
+   */  
+  void setSampleDenominatorCoeff(const vector<ossim_float64>& coeff);
+  
+  /**
+   * @param idx index of sample denominator coefficient to set.
+   * Range: 0 - 19
+   *
+   * @param sampleDenominatorCoeff Value to set sample denominator coefficient
+   * to for idx or index.
+   */  
+  void setSampleDenominatorCoeff(ossim_uint32 idx,
+                               const ossimString& coeff);
+
+
+  /**
+   * Print method.
+   *
+   * @param out Stream to print to.
+   * 
+   * @return std::ostream&
+   */
+  virtual std::ostream& print(std::ostream& out) const;
+
+protected:
+
+  /**
+   * FIELD: SUCCESS
+   *
+   * Required 1 byte field.
+   * 
+   * Value is 1
+   * 
+   */
+  char theSuccess[SUCCESS_SIZE+1];
+   
+  /**
+   * FIELD: ERR_BIAS
+   *
+   * required 7 byte field
+   * 
+   * Error - Bias. 68% non time-varying error estimate assumes
+   * correlated images.
+   *
+   * Values range from 0000.00 to 9999.99 meters
+   */
+  char theErrorBias[ERROR_BIAS_SIZE+1];
+
+  /**
+   * FIELD ERR_RAND
+   *
+   * Required 7 byte field
+   * 
+   * Error - Random. 68% time-varying error estimate assumes
+   * correlated images. 0000.00 to 9999.99 meters
+   */
+  char theErrRand[ERR_RAND_SIZE+1];
+
+  /**
+   * FIELD: LINE_OFF
+   *
+   * required 6 byte field.
+   * 
+   * value is in pixels and ranges from 000000-999999
+   */
+  char theLineOffset[LINE_OFFSET_SIZE+1];
+
+  /**
+   * FIELD: SAMP_OFF
+   *
+   * required 5 byte field.
+   *
+   * value is in pixels and ranges from 00000-99999
+   */
+  char theSampleOffset[SAMPLE_OFFSET_SIZE+1];
+
+  /**
+   * FIELD: LAT_OFF
+   *
+   * required 8 byte field.
+   *
+   * Holds the lat offset in degrees and ranges from +-90.0000
+   */
+  char theGeodeticLatOffset[GEODETIC_LAT_OFFSET_SIZE+1];
+
+  /**
+   * FIELD: LONG_OFF
+   *
+   * required 9 byte field.
+   *
+   * holds the lon offset in degrees and ranges from +-180.0000
+   */
+  char theGeodeticLonOffset[GEODETIC_LON_OFFSET_SIZE+1];
+
+  /**
+   * FIELD: HEIGHT_OFF
+   *
+   * required 5 byte field.
+   *
+   * holds the height offset in meters and ranges from +-9999
+   */
+  char theGeodeticHeightOffset[GEODETIC_HEIGHT_OFFSET_SIZE+1];
+
+  /**
+   * FIELD: LINE_SCALE
+   *
+   * required 6 byte field.
+   *
+   * holds the line scale in pixels and ranges from 000001-999999
+   * 
+   */
+  char theLineScale[LINE_SCALE_SIZE+1];
+
+  /**
+   * FIELD: SAMP_SCALE
+   *
+   * required 5 byte field.
+   *
+   * holds the line scale in pixels and ranges from 00001-99999
+   * 
+   */
+  char theSampleScale[SAMPLE_SCALE_SIZE+1];
+
+  /**
+   * FIELD: LAT_SCALE
+   *
+   * required 8 byte field
+   *
+   * holds the lat scale in degrees and ranges from +-90.0000 degrees
+   */
+  char theGeodeticLatScale[GEODETIC_LAT_SCALE_SIZE+1];
+
+  /**
+   * FIELD: LON_SCALE
+   *
+   * required 9 byte field
+   *
+   * holds the lon scale in degrees and ranges from +-180.0000 degrees
+   */
+  char theGeodeticLonScale[GEODETIC_LON_SCALE_SIZE+1];
+
+  /**
+   * FIELD: HEIGHT_SCALE
+   *
+   * required 5 byte field
+   *
+   * holds the geodetic height scale and ranges from +-9999 meters.
+   */
+  char theGeodeticHeightScale[GEODETIC_HEIGHT_SCALE_SIZE+1];
+
+  /**
+   * FIELD: LINE_NUM_COEFF_1 through LINE_NUM_COEFF_20
+   *
+   * Line Numerator Coefficients.
+   *
+   * required 12 byte field ranging ±0.999999E±9 Twenty coefficients for the
+   * polynomial
+   *
+   */     
+  std::vector<ossimString> theLineNumeratorCoefficient;
+
+  /**
+   * FIELD: LINE_DEN_COEFF_1 through LINE_DEN_COEFF_20
+   *
+   * Line Denominato Coefficients.
+   *
+   * required 12 byte field ranging ±0.999999E±9 Twenty coefficients for the
+   * polynomial
+   *
+   */     
+  std::vector<ossimString> theLineDenominatorCoefficient;
+
+  /**
+   * FIELD: SAMP_NUM_COEFF_1 through SAMP_NUM_COEFF_20
+   *
+   * samp Numerator Coefficients.
+   *
+   * required 12 byte field ranging ±0.999999E±9 Twenty coefficients for the
+   * polynomial
+   *
+   */     
+  std::vector<ossimString> theSampleNumeratorCoefficient;
+
+  /**
+   * FIELD: SAMP_DEN_COEFF_1 through SAMP_DEN_COEFF_20
+   *
+   * samp Denominator Coefficients.
+   *
+   * required 12 byte field ranging ±0.999999E±9 Twenty coefficients for the
+   * polynomial
+   *
+   */     
+  std::vector<ossimString> theSampleDenominatorCoefficient;
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpfTagFactory.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpfTagFactory.cpp
new file mode 100644
index 0000000000..7d9b818d53
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpfTagFactory.cpp
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL  see top level LICENSE.txt
+// 
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfRpfTagFactory.cpp,v 1.3 2004/09/28 15:35:30 gpotts Exp $
+#include <support_data/nitf/ossimNitfRpfTagFactory.h>
+#include <support_data/nitf/ossimNitfEmbeddedRpfHeader.h>
+#include <base/context/ossimNotifyContext.h>
+
+RTTI_DEF1(ossimNitfRpfTagFactory, "ossimNitfRpfTagFactory", ossimNitfTagFactory);
+
+ossimNitfRpfTagFactory*   ossimNitfRpfTagFactory::theInstance = NULL;
+
+static const ossimString REGISTERED_RPF_HEADER_TAG = "RPFHDR";
+static const ossimString REGISTERED_RPF_DES_TAG    = "RPFDES";
+
+ossimNitfRpfTagFactory::ossimNitfRpfTagFactory()
+{
+   theInstance = this;
+}
+
+ossimNitfRpfTagFactory::~ossimNitfRpfTagFactory()
+{
+   theInstance = NULL;
+}
+
+ossimNitfRpfTagFactory* ossimNitfRpfTagFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimNitfRpfTagFactory;
+   }
+   
+   return theInstance;
+}
+
+
+ossimRefPtr<ossimNitfRegisteredTag> ossimNitfRpfTagFactory::create(const ossimString &tagName)const
+{
+   ossimString temp(ossimString(tagName).trim().upcase());
+   
+   if(temp == REGISTERED_RPF_HEADER_TAG)
+   {
+      return new ossimNitfEmbeddedRpfHeader;
+   }
+   if(temp == REGISTERED_RPF_DES_TAG)
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "WARNING  ossimNitfRpfTagFactory::create: Reader for REGISTERED_RPF_DES_TAG not implemented yet" << std::endl;
+   }
+   
+   return NULL;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpfTagFactory.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpfTagFactory.h
new file mode 100644
index 0000000000..e5dd0e9e4b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfRpfTagFactory.h
@@ -0,0 +1,39 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL  see top level LICENSE.txt
+// 
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfRpfTagFactory.h,v 1.3 2004/09/28 15:35:30 gpotts Exp $
+#ifndef ossimNitfRpfTagFactory_HEADER
+#define ossimNitfRpfTagFactory_HEADER
+#include <support_data/nitf/ossimNitfTagFactory.h>
+class ossimNitfRegisteredTag;
+
+class ossimNitfRpfTagFactory : public ossimNitfTagFactory
+{
+public:
+   virtual ~ossimNitfRpfTagFactory();
+   static ossimNitfRpfTagFactory* instance();
+   virtual ossimRefPtr<ossimNitfRegisteredTag> create(const ossimString &tagName)const;
+   
+protected:
+   ossimNitfRpfTagFactory();
+
+private:
+   static ossimNitfRpfTagFactory* theInstance;
+   /*!
+    * Hide this.
+    */
+   ossimNitfRpfTagFactory(const ossimNitfRpfTagFactory &rhs){}
+
+   /*!
+    * Hide this.
+    */ 
+   ossimNitfRpfTagFactory& operator =(const ossimNitfRpfTagFactory &rhs){return *this;}
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSensraTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSensraTag.cpp
new file mode 100644
index 0000000000..31d40079c6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSensraTag.cpp
@@ -0,0 +1,414 @@
+//*******************************************************************
+
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Walt Bunch
+//
+// Description: Nitf support class for SENSRA - Sensor parameters extension.
+// 
+//********************************************************************
+// $Id: ossimNitfSensraTag.cpp,v 1.3 2005/08/09 11:32:21 gpotts Exp $
+#include <support_data/nitf/ossimNitfSensraTag.h>
+
+RTTI_DEF1(ossimNitfSensraTag, "ossimNitfSensraTag", ossimNitfRegisteredTag);
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+ossimNitfSensraTag::ossimNitfSensraTag()
+{
+   clearFields();
+}
+
+ossimNitfSensraTag::~ossimNitfSensraTag()
+{
+}
+
+ossimString ossimNitfSensraTag::getRegisterTagName()const
+{
+   return "SENSRA";
+}
+
+void ossimNitfSensraTag::parseStream(std::istream& in)
+{
+   clearFields();
+   
+   in.read(theRefRow, REF_ROW_SIZE);
+   in.read(theRefCol, REF_COL_SIZE);
+   in.read(theSensorModel, SENSOR_MODEL_SIZE);
+   in.read(theSensorMount, SENSOR_MOUNT_SIZE);
+   in.read(theSensorLoc, SENSOR_LOC_SIZE);
+   in.read(theSensorAltSrc, SENSOR_ALT_SRC_SIZE);
+   in.read(theSensorAlt, SENSOR_ALT_SIZE);
+   in.read(theSensorAltUnit, SENSOR_ALT_UNIT_SIZE);
+   in.read(theSensorAgl, SENSOR_AGL_SIZE);
+   in.read(theSensorPitch, SENSOR_PITCH_SIZE);
+   in.read(theSensorRoll, SENSOR_ROLL_SIZE);
+   in.read(theSensorYaw, SENSOR_YAW_SIZE);
+   in.read(thePlatformPitch, PLATFORM_PITCH_SIZE);
+   in.read(thePlatformRoll, PLATFORM_ROLL_SIZE);
+   in.read(thePlatformHdg, PLATFORM_HDG_SIZE);
+   in.read(theGroundSpdSrc, GROUND_SPD_SRC_SIZE);
+   in.read(theGroundSpeed, GROUND_SPEED_SIZE);
+   in.read(theGroundSpdUnit, GROUND_SPD_UNIT_SIZE);
+   in.read(theGroundTrack, GROUND_TRACK_SIZE);
+   in.read(theVerticalVel, VERTICAL_VEL_SIZE);
+   in.read(theVertVelUnit, VERT_VEL_UNIT_SIZE);
+   in.read(theSwathFrames, SWATH_FRAMES_SIZE);
+   in.read(theNSwaths, N_SWATHS_SIZE);
+   in.read(theSpotNum, SPOT_NUM_SIZE);
+}
+
+void ossimNitfSensraTag::writeStream(std::ostream& out)
+{
+   out.write(theRefRow, REF_ROW_SIZE);
+   out.write(theRefCol, REF_COL_SIZE);
+   out.write(theSensorModel, SENSOR_MODEL_SIZE);
+   out.write(theSensorMount, SENSOR_MOUNT_SIZE);
+   out.write(theSensorLoc, SENSOR_LOC_SIZE);
+   out.write(theSensorAltSrc, SENSOR_ALT_SRC_SIZE);
+   out.write(theSensorAlt, SENSOR_ALT_SIZE);
+   out.write(theSensorAltUnit, SENSOR_ALT_UNIT_SIZE);
+   out.write(theSensorAgl, SENSOR_AGL_SIZE);
+   out.write(theSensorPitch, SENSOR_PITCH_SIZE);
+   out.write(theSensorRoll, SENSOR_ROLL_SIZE);
+   out.write(theSensorYaw, SENSOR_YAW_SIZE);
+   out.write(thePlatformPitch, PLATFORM_PITCH_SIZE);
+   out.write(thePlatformRoll, PLATFORM_ROLL_SIZE);
+   out.write(thePlatformHdg, PLATFORM_HDG_SIZE);
+   out.write(theGroundSpdSrc, GROUND_SPD_SRC_SIZE);
+   out.write(theGroundSpeed, GROUND_SPEED_SIZE);
+   out.write(theGroundSpdUnit, GROUND_SPD_UNIT_SIZE);
+   out.write(theGroundTrack, GROUND_TRACK_SIZE);
+   out.write(theVerticalVel, VERTICAL_VEL_SIZE);
+   out.write(theVertVelUnit, VERT_VEL_UNIT_SIZE);
+   out.write(theSwathFrames, SWATH_FRAMES_SIZE);
+   out.write(theNSwaths, N_SWATHS_SIZE);
+   out.write(theSpotNum, SPOT_NUM_SIZE);
+}
+
+ossim_uint32 ossimNitfSensraTag::getSizeInBytes()const
+{
+   return 132;
+}
+
+void ossimNitfSensraTag::clearFields()
+{
+   memset(theRefRow, ' ', REF_ROW_SIZE);
+   memset(theRefCol, ' ', REF_COL_SIZE);
+   memset(theSensorModel, ' ', SENSOR_MODEL_SIZE);
+   memset(theSensorMount, ' ', SENSOR_MOUNT_SIZE);
+   memset(theSensorLoc, ' ', SENSOR_LOC_SIZE);
+   memset(theSensorAltSrc, ' ', SENSOR_ALT_SRC_SIZE);
+   memset(theSensorAlt, ' ', SENSOR_ALT_SIZE);
+   memset(theSensorAltUnit, ' ', SENSOR_ALT_UNIT_SIZE);
+   memset(theSensorAgl, ' ', SENSOR_AGL_SIZE);
+   memset(theSensorPitch, ' ', SENSOR_PITCH_SIZE);
+   memset(theSensorRoll, ' ', SENSOR_ROLL_SIZE);
+   memset(theSensorYaw, ' ', SENSOR_YAW_SIZE);
+   memset(thePlatformPitch, ' ', PLATFORM_PITCH_SIZE);
+   memset(thePlatformRoll, ' ', PLATFORM_ROLL_SIZE);
+   memset(thePlatformHdg, ' ', PLATFORM_HDG_SIZE);
+   memset(theGroundSpdSrc, ' ', GROUND_SPD_SRC_SIZE);
+   memset(theGroundSpeed, ' ', GROUND_SPEED_SIZE);
+   memset(theGroundSpdUnit, ' ', GROUND_SPD_UNIT_SIZE);
+   memset(theGroundTrack, ' ', GROUND_TRACK_SIZE);
+   memset(theVerticalVel, ' ', VERTICAL_VEL_SIZE);
+   memset(theVertVelUnit, ' ', VERT_VEL_UNIT_SIZE);
+   memset(theSwathFrames, ' ', SWATH_FRAMES_SIZE);
+   memset(theNSwaths, ' ', N_SWATHS_SIZE);
+   memset(theSpotNum, ' ', SPOT_NUM_SIZE);
+
+   theRefRow[REF_ROW_SIZE] = '\0';
+   theRefCol[REF_COL_SIZE] = '\0';
+   theSensorModel[SENSOR_MODEL_SIZE] = '\0';
+   theSensorMount[SENSOR_MOUNT_SIZE] = '\0';
+   theSensorLoc[SENSOR_LOC_SIZE] = '\0';
+   theSensorAltSrc[SENSOR_ALT_SRC_SIZE] = '\0';
+   theSensorAlt[SENSOR_ALT_SIZE] = '\0';
+   theSensorAltUnit[SENSOR_ALT_UNIT_SIZE] = '\0';
+   theSensorAgl[SENSOR_AGL_SIZE] = '\0';
+   theSensorPitch[SENSOR_PITCH_SIZE] = '\0';
+   theSensorRoll[SENSOR_ROLL_SIZE] = '\0';
+   theSensorYaw[SENSOR_YAW_SIZE] = '\0';
+   thePlatformPitch[PLATFORM_PITCH_SIZE] = '\0';
+   thePlatformRoll[PLATFORM_ROLL_SIZE] = '\0';
+   thePlatformHdg[PLATFORM_HDG_SIZE] = '\0';
+   theGroundSpdSrc[GROUND_SPD_SRC_SIZE] = '\0';
+   theGroundSpeed[GROUND_SPEED_SIZE] = '\0';
+   theGroundSpdUnit[GROUND_SPD_UNIT_SIZE] = '\0';
+   theGroundTrack[GROUND_TRACK_SIZE] = '\0';
+   theVerticalVel[VERTICAL_VEL_SIZE] = '\0';
+   theVertVelUnit[VERT_VEL_UNIT_SIZE] = '\0';
+   theSwathFrames[SWATH_FRAMES_SIZE] = '\0';
+   theNSwaths[N_SWATHS_SIZE] = '\0';
+   theSpotNum[SPOT_NUM_SIZE] = '\0';
+}
+
+ossimString ossimNitfSensraTag::getRefRow()const
+{
+   return theRefRow;
+}
+
+void ossimNitfSensraTag::setRefRow(ossimString refRow)
+{
+   memset(theRefRow, ' ', REF_ROW_SIZE);
+   memcpy(theRefRow, refRow.c_str(), MIN(REF_ROW_SIZE, refRow.length()));
+}
+
+ossimString ossimNitfSensraTag::getRefCol()const
+{
+   return theRefCol;
+}
+
+void ossimNitfSensraTag::setRefCol(ossimString refCol)
+{
+   memset(theRefCol, ' ', REF_COL_SIZE);
+   memcpy(theRefCol, refCol.c_str(), MIN(REF_COL_SIZE, refCol.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorModel()const
+{
+   return theSensorModel;
+}
+
+void ossimNitfSensraTag::setSensorModel(ossimString sensorModel)
+{
+   memset(theSensorModel, ' ', SENSOR_MODEL_SIZE);
+   memcpy(theSensorModel, sensorModel.c_str(), MIN(SENSOR_MODEL_SIZE, sensorModel.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorMount()const
+{
+   return theSensorMount;
+}
+
+void ossimNitfSensraTag::setSensorMount(ossimString sensorMount)
+{
+   memset(theSensorMount, ' ', SENSOR_MOUNT_SIZE);
+   memcpy(theSensorMount, sensorMount.c_str(), MIN(SENSOR_MOUNT_SIZE, sensorMount.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorLoc()const
+{
+   return theSensorLoc;
+}
+
+void ossimNitfSensraTag::setSensorLoc(ossimString sensorLoc)
+{
+   memset(theSensorLoc, ' ', SENSOR_LOC_SIZE);
+   memcpy(theSensorLoc, sensorLoc.c_str(), MIN(SENSOR_LOC_SIZE, sensorLoc.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorAltSrc()const
+{
+   return theSensorAltSrc;
+}
+
+void ossimNitfSensraTag::setSensorAltSrc(ossimString sensorAltSrc)
+{
+   memset(theSensorAltSrc, ' ', SENSOR_ALT_SRC_SIZE);
+   memcpy(theSensorAltSrc, sensorAltSrc.c_str(), MIN(SENSOR_ALT_SRC_SIZE, sensorAltSrc.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorAlt()const
+{
+   return theSensorAlt;
+}
+
+void ossimNitfSensraTag::setSensorAlt(ossimString sensorAlt)
+{
+   memset(theSensorAlt, ' ', SENSOR_ALT_SIZE);
+   memcpy(theSensorAlt, sensorAlt.c_str(), MIN(SENSOR_ALT_SIZE, sensorAlt.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorAltUnit()const
+{
+   return theSensorAltUnit;
+}
+
+void ossimNitfSensraTag::setSensorAltUnit(ossimString sensorAltUnit)
+{
+   memset(theSensorAltUnit, ' ', SENSOR_ALT_UNIT_SIZE);
+   memcpy(theSensorAltUnit, sensorAltUnit.c_str(), MIN(SENSOR_ALT_UNIT_SIZE, sensorAltUnit.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorAgl()const
+{
+   return theSensorAgl;
+}
+
+void ossimNitfSensraTag::setSensorAgl(ossimString sensorAgl)
+{
+   memset(theSensorAgl, ' ', SENSOR_AGL_SIZE);
+   memcpy(theSensorAgl, sensorAgl.c_str(), MIN(SENSOR_AGL_SIZE, sensorAgl.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorPitch()const
+{
+   return theSensorPitch;
+}
+
+void ossimNitfSensraTag::setSensorPitch(ossimString sensorPitch)
+{
+   memset(theSensorPitch, ' ', SENSOR_PITCH_SIZE);
+   memcpy(theSensorPitch, sensorPitch.c_str(), MIN(SENSOR_PITCH_SIZE, sensorPitch.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorRoll()const
+{
+   return theSensorRoll;
+}
+
+void ossimNitfSensraTag::setSensorRoll(ossimString sensorRoll)
+{
+   memset(theSensorRoll, ' ', SENSOR_ROLL_SIZE);
+   memcpy(theSensorRoll, sensorRoll.c_str(), MIN(SENSOR_ROLL_SIZE, sensorRoll.length()));
+}
+
+ossimString ossimNitfSensraTag::getSensorYaw()const
+{
+   return theSensorYaw;
+}
+
+void ossimNitfSensraTag::setSensorYaw(ossimString sensorYaw)
+{
+   memset(theSensorYaw, ' ', SENSOR_YAW_SIZE);
+   memcpy(theSensorYaw, sensorYaw.c_str(), MIN(SENSOR_YAW_SIZE, sensorYaw.length()));
+}
+
+ossimString ossimNitfSensraTag::getPlatformPitch()const
+{
+   return thePlatformPitch;
+}
+
+void ossimNitfSensraTag::setPlatformPitch(ossimString platformPitch)
+{
+   memset(thePlatformPitch, ' ', PLATFORM_PITCH_SIZE);
+   memcpy(thePlatformPitch, platformPitch.c_str(), MIN(PLATFORM_PITCH_SIZE, platformPitch.length()));
+}
+
+ossimString ossimNitfSensraTag::getPlatformRoll()const
+{
+   return thePlatformRoll;
+}
+
+void ossimNitfSensraTag::setPlatformRoll(ossimString platformRoll)
+{
+   memset(thePlatformRoll, ' ', PLATFORM_ROLL_SIZE);
+   memcpy(thePlatformRoll, platformRoll.c_str(), MIN(PLATFORM_ROLL_SIZE, platformRoll.length()));
+}
+
+ossimString ossimNitfSensraTag::getPlatformHdg()const
+{
+   return thePlatformHdg;
+}
+
+void ossimNitfSensraTag::setPlatformHdg(ossimString platformHdg)
+{
+   memset(thePlatformHdg, ' ', PLATFORM_HDG_SIZE);
+   memcpy(thePlatformHdg, platformHdg.c_str(), MIN(PLATFORM_HDG_SIZE, platformHdg.length()));
+}
+
+ossimString ossimNitfSensraTag::getGroundSpdSrc()const
+{
+   return theGroundSpdSrc;
+}
+
+void ossimNitfSensraTag::setGroundSpdSrc(ossimString groundSpdSrc)
+{
+   memset(theGroundSpdSrc, ' ', GROUND_SPD_SRC_SIZE);
+   memcpy(theGroundSpdSrc, groundSpdSrc.c_str(), MIN(GROUND_SPD_SRC_SIZE, groundSpdSrc.length()));
+}
+
+ossimString ossimNitfSensraTag::getGroundSpeed()const
+{
+   return theGroundSpeed;
+}
+
+void ossimNitfSensraTag::setGroundSpeed(ossimString groundSpeed)
+{
+   memset(theGroundSpeed, ' ', GROUND_SPEED_SIZE);
+   memcpy(theGroundSpeed, groundSpeed.c_str(), MIN(GROUND_SPEED_SIZE, groundSpeed.length()));
+}
+
+ossimString ossimNitfSensraTag::getGroundSpdUnit()const
+{
+   return theGroundSpdUnit;
+}
+
+void ossimNitfSensraTag::setGroundSpdUnit(ossimString groundSpdUnit)
+{
+   memset(theGroundSpdUnit, ' ', GROUND_SPD_UNIT_SIZE);
+   memcpy(theGroundSpdUnit, groundSpdUnit.c_str(), MIN(GROUND_SPD_UNIT_SIZE, groundSpdUnit.length()));
+}
+
+ossimString ossimNitfSensraTag::getGroundTrack()const
+{
+   return theGroundTrack;
+}
+
+void ossimNitfSensraTag::setGroundTrack(ossimString groundTrack)
+{
+   memset(theGroundTrack, ' ', GROUND_TRACK_SIZE);
+   memcpy(theGroundTrack, groundTrack.c_str(), MIN(GROUND_TRACK_SIZE, groundTrack.length()));
+}
+
+ossimString ossimNitfSensraTag::getVerticalVel()const
+{
+   return theVerticalVel;
+}
+
+void ossimNitfSensraTag::setVerticalVel(ossimString verticalVel)
+{
+   memset(theVerticalVel, ' ', VERTICAL_VEL_SIZE);
+   memcpy(theVerticalVel, verticalVel.c_str(), MIN(VERTICAL_VEL_SIZE, verticalVel.length()));
+}
+
+ossimString ossimNitfSensraTag::getVertVelUnit()const
+{
+   return theVertVelUnit;
+}
+
+void ossimNitfSensraTag::setVertVelUnit(ossimString vertVelUnit)
+{
+   memset(theVertVelUnit, ' ', VERT_VEL_UNIT_SIZE);
+   memcpy(theVertVelUnit, vertVelUnit.c_str(), MIN(VERT_VEL_UNIT_SIZE, vertVelUnit.length()));
+}
+
+ossimString ossimNitfSensraTag::getSwathFrames()const
+{
+   return theSwathFrames;
+}
+
+void ossimNitfSensraTag::setSwathFrames(ossimString swathFrames)
+{
+   memset(theSwathFrames, ' ', SWATH_FRAMES_SIZE);
+   memcpy(theSwathFrames, swathFrames.c_str(), MIN(SWATH_FRAMES_SIZE, swathFrames.length()));
+}
+
+ossimString ossimNitfSensraTag::getNSwaths()const
+{
+   return theNSwaths;
+}
+
+void ossimNitfSensraTag::setNSwaths(ossimString nSwaths)
+{
+   memset(theNSwaths, ' ', N_SWATHS_SIZE);
+   memcpy(theNSwaths, nSwaths.c_str(), MIN(N_SWATHS_SIZE, nSwaths.length()));
+}
+
+ossimString ossimNitfSensraTag::getSpotNum()const
+{
+   return theSpotNum;
+}
+
+void ossimNitfSensraTag::setSpotNum(ossimString spotNum)
+{
+   memset(theSpotNum, ' ', SPOT_NUM_SIZE);
+   memcpy(theSpotNum, spotNum.c_str(), MIN(SPOT_NUM_SIZE, spotNum.length()));
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSensraTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSensraTag.h
new file mode 100644
index 0000000000..cd3a944b48
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSensraTag.h
@@ -0,0 +1,259 @@
+//*******************************************************************
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Walt Bunch
+//
+// Description: Nitf support class for SENSRA - Sensor parameters extension.
+// 
+//********************************************************************
+// $Id: ossimNitfSensraTag.h,v 1.3 2005/08/09 11:32:21 gpotts Exp $
+#ifndef ossimNitfSensraTag_HEADER
+#define ossimNitfSensraTag_HEADER
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class OSSIM_DLL ossimNitfSensraTag : public ossimNitfRegisteredTag
+{
+public:
+
+   enum
+   {
+      REF_ROW_SIZE         = 8,
+      REF_COL_SIZE         = 8,
+      SENSOR_MODEL_SIZE    = 6,
+      SENSOR_MOUNT_SIZE    = 3,
+      SENSOR_LOC_SIZE      = 21,
+      SENSOR_ALT_SRC_SIZE  = 1,
+      SENSOR_ALT_SIZE      = 6,
+      SENSOR_ALT_UNIT_SIZE = 1,
+      SENSOR_AGL_SIZE      = 5,
+      SENSOR_PITCH_SIZE    = 7,
+      SENSOR_ROLL_SIZE     = 8,
+      SENSOR_YAW_SIZE      = 8,
+      PLATFORM_PITCH_SIZE  = 7,
+      PLATFORM_ROLL_SIZE   = 8,
+      PLATFORM_HDG_SIZE    = 5,
+      GROUND_SPD_SRC_SIZE  = 1,
+      GROUND_SPEED_SIZE    = 6,
+      GROUND_SPD_UNIT_SIZE = 1,
+      GROUND_TRACK_SIZE    = 5,
+      VERTICAL_VEL_SIZE    = 5,
+      VERT_VEL_UNIT_SIZE   = 1,
+      SWATH_FRAMES_SIZE    = 4,
+      N_SWATHS_SIZE        = 4,
+      SPOT_NUM_SIZE        = 3
+      //                  -----
+      //                   132
+   };
+
+   ossimNitfSensraTag();
+   virtual ~ossimNitfSensraTag();
+   virtual ossimString getRegisterTagName()const;
+   virtual void parseStream(std::istream& in);
+   virtual void writeStream(std::ostream& out);
+   virtual ossim_uint32 getSizeInBytes()const;
+   virtual void clearFields();
+
+  // The set methods below taking ossimString args will truncate and
+  // pad with spaces, as necessary, to match enumed size
+   void setRefRow(ossimString refRow);
+   ossimString getRefRow()const;
+   void setRefCol(ossimString refCol);
+   ossimString getRefCol()const;
+   void setSensorModel(ossimString sensorModel);
+   ossimString getSensorModel()const;
+   void setSensorMount(ossimString sensorMount);
+   ossimString getSensorMount()const;
+   void setSensorLoc(ossimString sensorLoc);
+   ossimString getSensorLoc()const;
+   void setSensorAltSrc(ossimString sensorAltSrc);
+   ossimString getSensorAltSrc()const;
+   void setSensorAlt(ossimString sensorAlt);
+   ossimString getSensorAlt()const;
+   void setSensorAltUnit(ossimString sensorAltUnit);
+   ossimString getSensorAltUnit()const;
+   void setSensorAgl(ossimString sensorAgl);
+   ossimString getSensorAgl()const;
+   void setSensorPitch(ossimString sensorPitch);
+   ossimString getSensorPitch()const;
+   void setSensorRoll(ossimString sensorRoll);
+   ossimString getSensorRoll()const;
+   void setSensorYaw(ossimString sensorYaw);
+   ossimString getSensorYaw()const;
+   void setPlatformPitch(ossimString platformPitch);
+   ossimString getPlatformPitch()const;
+   void setPlatformRoll(ossimString platformRoll);
+   ossimString getPlatformRoll()const;
+   void setPlatformHdg(ossimString platformHdg);
+   ossimString getPlatformHdg()const;
+   void setGroundSpdSrc(ossimString groundSpdSrc);
+   ossimString getGroundSpdSrc()const;
+   void setGroundSpeed(ossimString groundSpeed);
+   ossimString getGroundSpeed()const;
+   void setGroundSpdUnit(ossimString groundSpdUnit);
+   ossimString getGroundSpdUnit()const;
+   void setGroundTrack(ossimString groundTrack);
+   ossimString getGroundTrack()const;
+   void setVerticalVel(ossimString verticalVel);
+   ossimString getVerticalVel()const;
+   void setVertVelUnit(ossimString vertVelUnit);
+   ossimString getVertVelUnit()const;
+   void setSwathFrames(ossimString swathFrames);
+   ossimString getSwathFrames()const;
+   void setNSwaths(ossimString nSwaths);
+   ossimString getNSwaths()const;
+   void setSpotNum(ossimString spotNum);
+   ossimString getSpotNum()const;
+
+protected:
+
+   /**
+    * FIELD: REFROW
+    *
+    */
+   char theRefRow[REF_ROW_SIZE+1];
+
+   /**
+    * FIELD: REFCOL
+    *
+    */
+   char theRefCol[REF_COL_SIZE+1];
+
+   /**
+    * FIELD: SENSORMODEL
+    *
+    */
+   char theSensorModel[SENSOR_MODEL_SIZE+1];
+
+   /**
+    * FIELD: SENSORMOUNT
+    *
+    */
+   char theSensorMount[SENSOR_MOUNT_SIZE+1];
+
+   /**
+    * FIELD: SENSORLOC
+    *
+    */
+   char theSensorLoc[SENSOR_LOC_SIZE+1];
+
+   /**
+    * FIELD: SENSORALTSRC
+    *
+    */
+   char theSensorAltSrc[SENSOR_ALT_SRC_SIZE+1];
+
+   /**
+    * FIELD: SENSORALT
+    *
+    */
+   char theSensorAlt[SENSOR_ALT_SIZE+1];
+
+   /**
+    * FIELD: SENSORALTUNIT
+    *
+    */
+   char theSensorAltUnit[SENSOR_ALT_UNIT_SIZE+1];
+
+   /**
+    * FIELD: SENSORAGL
+    *
+    */
+   char theSensorAgl[SENSOR_AGL_SIZE+1];
+
+   /**
+    * FIELD: SENSORPITCH
+    *
+    */
+   char theSensorPitch[SENSOR_PITCH_SIZE+1];
+
+   /**
+    * FIELD: SENSORROLL
+    *
+    */
+   char theSensorRoll[SENSOR_ROLL_SIZE+1];
+
+   /**
+    * FIELD: SENSORYAW
+    *
+    */
+   char theSensorYaw[SENSOR_YAW_SIZE+1];
+
+   /**
+    * FIELD: PLATFORMPITCH
+    *
+    */
+   char thePlatformPitch[PLATFORM_PITCH_SIZE+1];
+
+   /**
+    * FIELD: PLATFORMROLL
+    *
+    */
+   char thePlatformRoll[PLATFORM_ROLL_SIZE+1];
+
+   /**
+    * FIELD: PLATFORMHDG
+    *
+    */
+   char thePlatformHdg[PLATFORM_HDG_SIZE+1];
+
+   /**
+    * FIELD: GROUNDSPDSRC
+    *
+    */
+   char theGroundSpdSrc[GROUND_SPD_SRC_SIZE+1];
+
+   /**
+    * FIELD: GROUNDSPEED
+    *
+    */
+   char theGroundSpeed[GROUND_SPEED_SIZE+1];
+
+   /**
+    * FIELD: GROUNDSPDUNIT
+    *
+    */
+   char theGroundSpdUnit[GROUND_SPD_UNIT_SIZE+1];
+
+   /**
+    * FIELD: GROUNDTRACK
+    *
+    */
+   char theGroundTrack[GROUND_TRACK_SIZE+1];
+
+   /**
+    * FIELD: VERTICALVEL
+    *
+    */
+   char theVerticalVel[VERTICAL_VEL_SIZE+1];
+
+   /**
+    * FIELD: VERTVELUNIT
+    *
+    */
+   char theVertVelUnit[VERT_VEL_UNIT_SIZE+1];
+
+   /**
+    * FIELD: SWATHFRAMES
+    *
+    */
+   char theSwathFrames[SWATH_FRAMES_SIZE+1];
+
+   /**
+    * FIELD: NSWATHS
+    *
+    */
+   char theNSwaths[N_SWATHS_SIZE+1];
+
+   /**
+    * FIELD: SPOTNUM
+    *
+    */
+   char theSpotNum[SPOT_NUM_SIZE+1];
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfStdidcTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfStdidcTag.cpp
new file mode 100644
index 0000000000..2146d03a1c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfStdidcTag.cpp
@@ -0,0 +1,326 @@
+//*******************************************************************
+//
+// LICENSE: LGPL
+//
+// See top level LICENSE.txt
+// 
+// Author:  Walt Bunch
+// 
+// Description:   NITF support data class for STDIDC - Standard ID extension.
+//
+// See:  STDI-000_v2.1 Table 7-3 for detailed description.
+// 
+//********************************************************************
+// $Id: ossimNitfStdidcTag.cpp,v 1.3 2005/08/09 11:32:21 gpotts Exp $
+#include <support_data/nitf/ossimNitfStdidcTag.h>
+
+RTTI_DEF1(ossimNitfStdidcTag, "ossimNitfStdidcTag", ossimNitfRegisteredTag);
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+ossimNitfStdidcTag::ossimNitfStdidcTag()
+{
+   clearFields();
+}
+
+ossimNitfStdidcTag::~ossimNitfStdidcTag()
+{
+}
+
+ossimString ossimNitfStdidcTag::getRegisterTagName()const
+{
+   return "STDIDC";
+}
+
+void ossimNitfStdidcTag::parseStream(std::istream& in)
+{
+   clearFields();
+   
+   in.read(theAcqDate,      ACQ_DATE_SIZE);
+   in.read(theMission,      MISSION_SIZE);
+   in.read(thePass,         PASS_SIZE);
+   in.read(theOpNum,        OP_NUM_SIZE);
+   in.read(theStartSegment, START_SEGMENT_SIZE);
+   in.read(theReproNum,     REPRO_NUM_SIZE);
+   in.read(theReplayRegen,  REPLAY_REGEN_SIZE);
+   in.read(theBlankFill,    BLANK_FILL_SIZE);
+   in.read(theStartColumn,  START_COLUMN_SIZE);
+   in.read(theStartRow,     START_ROW_SIZE);
+   in.read(theEndSegment,   END_SEGMENT_SIZE);
+   in.read(theEndColumn,    END_COLUMN_SIZE);
+   in.read(theEndRow,       END_ROW_SIZE);
+   in.read(theCountry,      COUNTRY_SIZE);
+   in.read(theWac,          WAC_SIZE);
+   in.read(theLocation,     LOCATION_SIZE);
+   in.read(theField17,      FIELD17_SIZE);
+   in.read(theField18,      FIELD18_SIZE);
+}
+
+void ossimNitfStdidcTag::writeStream(std::ostream& out)
+{
+   out.write(theAcqDate,      ACQ_DATE_SIZE);
+   out.write(theMission,      MISSION_SIZE);
+   out.write(thePass,         PASS_SIZE);
+   out.write(theOpNum,        OP_NUM_SIZE);
+   out.write(theStartSegment, START_SEGMENT_SIZE);
+   out.write(theReproNum,     REPRO_NUM_SIZE);
+   out.write(theReplayRegen,  REPLAY_REGEN_SIZE);
+   out.write(theBlankFill,    BLANK_FILL_SIZE);
+   out.write(theStartColumn,  START_COLUMN_SIZE);
+   out.write(theStartRow,     START_ROW_SIZE);
+   out.write(theEndSegment,   END_SEGMENT_SIZE);
+   out.write(theEndColumn,    END_COLUMN_SIZE);
+   out.write(theEndRow,       END_ROW_SIZE);
+   out.write(theCountry,      COUNTRY_SIZE);
+   out.write(theWac,          WAC_SIZE);
+   out.write(theLocation,     LOCATION_SIZE);
+   out.write(theField17,      FIELD17_SIZE);
+   out.write(theField18,      FIELD18_SIZE);
+}
+
+ossim_uint32 ossimNitfStdidcTag::getSizeInBytes()const
+{
+   return 89;
+}
+
+void ossimNitfStdidcTag::clearFields()
+{
+   memset(theAcqDate,      ' ', ACQ_DATE_SIZE);
+   memset(theMission,      ' ', MISSION_SIZE);
+   memset(thePass,         ' ', PASS_SIZE);
+   memset(theOpNum,        ' ', OP_NUM_SIZE);
+   memset(theStartSegment, ' ', START_SEGMENT_SIZE);
+   memset(theReproNum,     ' ', REPRO_NUM_SIZE);
+   memset(theReplayRegen,  ' ', REPLAY_REGEN_SIZE);
+   memset(theBlankFill,    ' ', BLANK_FILL_SIZE);
+   memset(theStartColumn,  ' ', START_COLUMN_SIZE);
+   memset(theStartRow,     ' ', START_ROW_SIZE);
+   memset(theEndSegment,   ' ', END_SEGMENT_SIZE);
+   memset(theEndColumn,    ' ', END_COLUMN_SIZE);
+   memset(theEndRow,       ' ', END_ROW_SIZE);
+   memset(theCountry,      ' ', COUNTRY_SIZE);
+   memset(theWac,          ' ', WAC_SIZE);
+   memset(theLocation,     ' ', LOCATION_SIZE);
+   memset(theField17,      ' ', FIELD17_SIZE);
+   memset(theField18,      ' ', FIELD18_SIZE);
+
+   theAcqDate[ACQ_DATE_SIZE]           = '\0';
+   theMission[MISSION_SIZE]            = '\0';
+   thePass[PASS_SIZE]                  = '\0';
+   theOpNum[OP_NUM_SIZE]               = '\0';
+   theStartSegment[START_SEGMENT_SIZE] = '\0';
+   theReproNum[REPRO_NUM_SIZE]         = '\0';
+   theReplayRegen[REPLAY_REGEN_SIZE]   = '\0';
+   theBlankFill[BLANK_FILL_SIZE]       = '\0';
+   theStartColumn[START_COLUMN_SIZE]   = '\0';
+   theStartRow[START_ROW_SIZE]         = '\0';
+   theEndSegment[END_SEGMENT_SIZE]     = '\0';
+   theEndColumn[END_COLUMN_SIZE]       = '\0';
+   theEndRow[END_ROW_SIZE]             = '\0';
+   theCountry[COUNTRY_SIZE]            = '\0';
+   theWac[WAC_SIZE]                    = '\0';
+   theLocation[LOCATION_SIZE]          = '\0';
+   theField17[FIELD17_SIZE]            = '\0';
+   theField18[FIELD18_SIZE]            = '\0';
+}
+
+ossimString ossimNitfStdidcTag::getAcqDate()const
+{
+  return ossimString(theAcqDate);
+}
+
+void ossimNitfStdidcTag::setAcqDate(ossimString acqDate)
+{
+   memset(theAcqDate, ' ', ACQ_DATE_SIZE);
+   memcpy(theAcqDate, acqDate.c_str(), MIN(ACQ_DATE_SIZE, acqDate.length()));
+}
+
+ossimString ossimNitfStdidcTag::getMission()const
+{
+  return ossimString(theMission);
+}
+
+void ossimNitfStdidcTag::setMission(ossimString mission)
+{
+   memset(theMission, ' ', MISSION_SIZE);
+   memcpy(theMission, mission.c_str(), MIN(MISSION_SIZE, mission.length()));
+}
+
+ossimString ossimNitfStdidcTag::getPass()const
+{
+  return ossimString(thePass);
+}
+
+void ossimNitfStdidcTag::setPass(ossimString pass)
+{
+   memset(thePass, ' ', PASS_SIZE);
+   memcpy(thePass, pass.c_str(), MIN(PASS_SIZE, pass.length()));
+}
+
+ossimString ossimNitfStdidcTag::getOpNum()const
+{
+  return ossimString(theOpNum);
+}
+
+void ossimNitfStdidcTag::setOpNum(ossimString opNum) 
+{
+   memset(theOpNum, ' ', OP_NUM_SIZE);
+   memcpy(theOpNum, opNum.c_str(), MIN(OP_NUM_SIZE, opNum.length()));
+}
+
+ossimString ossimNitfStdidcTag::getStartSegment()const
+{
+  return ossimString(theStartSegment);
+}
+
+void ossimNitfStdidcTag::setStartSegment(ossimString startSegment) 
+{
+   memset(theStartSegment, ' ', START_SEGMENT_SIZE);
+   memcpy(theStartSegment, startSegment.c_str(), MIN(START_SEGMENT_SIZE, startSegment.length()));
+}
+
+ossimString ossimNitfStdidcTag::getReproNum()const
+{
+  return ossimString(theReproNum);
+}
+
+void ossimNitfStdidcTag::setReproNum(ossimString reproNum) 
+{
+   memset(theReproNum, ' ', REPRO_NUM_SIZE);
+   memcpy(theReproNum, reproNum.c_str(), MIN(REPRO_NUM_SIZE, reproNum.length()));
+}
+
+ossimString ossimNitfStdidcTag::getReplayRegen()const
+{
+  return ossimString(theReplayRegen);
+}
+
+void ossimNitfStdidcTag::setReplayRegen(ossimString replayRegen) 
+{
+   memset(theReplayRegen, ' ', REPLAY_REGEN_SIZE);
+   memcpy(theReplayRegen, replayRegen.c_str(), MIN(REPLAY_REGEN_SIZE, replayRegen.length()));
+}
+
+ossimString ossimNitfStdidcTag::getBlankFill()const
+{
+  return ossimString(theBlankFill);
+}
+
+void ossimNitfStdidcTag::setBlankFill(ossimString blankFill) 
+{
+   memset(theBlankFill, ' ', BLANK_FILL_SIZE);
+   memcpy(theBlankFill, blankFill.c_str(), MIN(BLANK_FILL_SIZE, blankFill.length()));
+}
+
+ossimString ossimNitfStdidcTag::getStartColumn()const
+{
+  return ossimString(theStartColumn);
+}
+
+void ossimNitfStdidcTag::setStartColumn(ossimString startColumn) 
+{
+   memset(theStartColumn, ' ', START_COLUMN_SIZE);
+   memcpy(theStartColumn, startColumn.c_str(), MIN(START_COLUMN_SIZE, startColumn.length()));
+}
+
+ossimString ossimNitfStdidcTag::getStartRow()const
+{
+  return ossimString(theStartRow);
+}
+
+void ossimNitfStdidcTag::setStartRow(ossimString startRow) 
+{
+   memset(theStartRow, ' ', START_ROW_SIZE);
+   memcpy(theStartRow, startRow.c_str(), MIN(START_ROW_SIZE, startRow.length()));
+}
+
+ossimString ossimNitfStdidcTag::getEndSegment()const
+{
+  return ossimString(theEndSegment);
+}
+
+void ossimNitfStdidcTag::setEndSegment(ossimString endSegment) 
+{
+   memset(theEndSegment, ' ', END_SEGMENT_SIZE);
+   memcpy(theEndSegment, endSegment.c_str(), MIN(END_SEGMENT_SIZE, endSegment.length()));
+}
+
+ossimString ossimNitfStdidcTag::getEndColumn()const
+{
+  return ossimString(theEndColumn);
+}
+
+void ossimNitfStdidcTag::setEndColumn(ossimString endColumn) 
+{
+   memset(theEndColumn, ' ', END_COLUMN_SIZE);
+   memcpy(theEndColumn, endColumn.c_str(), MIN(END_COLUMN_SIZE, endColumn.length()));
+}
+
+ossimString ossimNitfStdidcTag::getEndRow()const
+{
+  return ossimString(theEndRow);
+}
+
+void ossimNitfStdidcTag::setEndRow(ossimString endRow) 
+{
+   memset(theEndRow, ' ', END_ROW_SIZE);
+   memcpy(theEndRow, endRow.c_str(), MIN(END_ROW_SIZE, endRow.length()));
+}
+
+ossimString ossimNitfStdidcTag::getCountry()const
+{
+  return ossimString(theCountry);
+}
+
+void ossimNitfStdidcTag::setCountry(ossimString country) 
+{
+   memset(theCountry, ' ', COUNTRY_SIZE);
+   memcpy(theCountry, country.c_str(), MIN(COUNTRY_SIZE, country.length()));
+}
+
+ossimString ossimNitfStdidcTag::getWac()const
+{
+  return ossimString(theWac);
+}
+
+void ossimNitfStdidcTag::setWac(ossimString wac) 
+{
+   memset(theWac, ' ', WAC_SIZE);
+   memcpy(theWac, wac.c_str(), MIN(WAC_SIZE, wac.length()));
+}
+
+ossimString ossimNitfStdidcTag::getLocation()const
+{
+  return ossimString(theLocation);
+}
+
+void ossimNitfStdidcTag::setLocation(ossimString location) 
+{
+   memset(theLocation, ' ', LOCATION_SIZE);
+   memcpy(theLocation, location.c_str(), MIN(LOCATION_SIZE, location.length()));
+}
+
+ossimString ossimNitfStdidcTag::getField17()const
+{
+  return ossimString(theField17);
+}
+
+void ossimNitfStdidcTag::setField17(ossimString field17) 
+{
+   memset(theField17, ' ', FIELD17_SIZE);
+   memcpy(theField17, field17.c_str(), MIN(FIELD17_SIZE, field17.length()));
+}
+
+ossimString ossimNitfStdidcTag::getField18()const
+{
+  return ossimString(theField18);
+}
+
+void ossimNitfStdidcTag::setField18(ossimString field18) 
+{
+   memset(theField18, ' ', FIELD18_SIZE);
+   memcpy(theField18, field18.c_str(), MIN(FIELD18_SIZE, field18.length()));
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfStdidcTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfStdidcTag.h
new file mode 100644
index 0000000000..6be92d07d8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfStdidcTag.h
@@ -0,0 +1,189 @@
+//*******************************************************************
+//
+// LICENSE: LGPL
+//
+// See top level LICENSE.txt
+// 
+// Author:  Walt Bunch
+// 
+// Description:   NITF support data class for STDIDC - Standard ID extension.
+//
+// See:  STDI-000_v2.1 Table 7-3 for detailed description.
+// 
+//********************************************************************
+// $Id: ossimNitfStdidcTag.h,v 1.3 2005/08/09 11:32:21 gpotts Exp $
+#ifndef ossimNitfStdidcTag_HEADER
+#define ossimNitfStdidcTag_HEADER
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class OSSIM_DLL ossimNitfStdidcTag : public ossimNitfRegisteredTag
+{
+public:
+
+   enum
+   {
+      ACQ_DATE_SIZE         = 14,
+      MISSION_SIZE          = 14,
+      PASS_SIZE             = 2,
+      OP_NUM_SIZE           = 3,
+      START_SEGMENT_SIZE    = 2,
+      REPRO_NUM_SIZE        = 2,
+      REPLAY_REGEN_SIZE     = 3,
+      BLANK_FILL_SIZE       = 1,
+      START_COLUMN_SIZE     = 3,
+      START_ROW_SIZE        = 5,
+      END_SEGMENT_SIZE      = 2,
+      END_COLUMN_SIZE       = 3,
+      END_ROW_SIZE          = 5,
+      COUNTRY_SIZE          = 2,
+      WAC_SIZE              = 4,
+      LOCATION_SIZE         = 11,
+      FIELD17_SIZE          = 5,
+      FIELD18_SIZE          = 8
+      //                   -----
+      //                     89 bytes
+   };
+      
+   ossimNitfStdidcTag();
+   virtual ~ossimNitfStdidcTag();
+   virtual ossimString getRegisterTagName()const;
+   virtual void parseStream(std::istream& in);
+   virtual void writeStream(std::ostream& out);
+   virtual ossim_uint32 getSizeInBytes()const;
+   virtual void clearFields();
+
+  // The set methods below taking ossimString args will truncate and
+  // pad with spaces, as necessary, to match enumed size
+   void setAcqDate(ossimString acqDate);
+   ossimString getAcqDate()const;
+   void setMission(ossimString mission);
+   ossimString getMission()const;
+   void setPass(ossimString pass);
+   ossimString getPass()const;
+   void setOpNum(ossimString opNum);
+   ossimString getOpNum()const;
+   void setStartSegment(ossimString startSegment);
+   ossimString getStartSegment()const;
+   void setReproNum(ossimString reproNum);
+   ossimString getReproNum()const;
+   void setReplayRegen(ossimString replayRegen);
+   ossimString getReplayRegen()const;
+   void setBlankFill(ossimString blankFill);
+   ossimString getBlankFill()const;
+   void setStartColumn(ossimString startColumn);
+   ossimString getStartColumn()const;
+   void setStartRow(ossimString startRow);
+   ossimString getStartRow()const;
+   void setEndSegment(ossimString endSegment);
+   ossimString getEndSegment()const;
+   void setEndColumn(ossimString endColumn);
+   ossimString getEndColumn()const;
+   void setEndRow(ossimString endRow);
+   ossimString getEndRow()const;
+   void setCountry(ossimString country);
+   ossimString getCountry()const;
+   void setWac(ossimString wac);
+   ossimString getWac()const;
+   void setLocation(ossimString location);
+   ossimString getLocation()const;
+   void setField17(ossimString field17);
+   ossimString getField17()const;
+   void setField18(ossimString field18);
+   ossimString getField18()const;
+
+protected:
+
+   /**
+    * FIELD: ACQDATE
+    */
+   char theAcqDate[ACQ_DATE_SIZE+1];
+   
+   /**
+    * FIELD: MISSION
+    */
+   char theMission[MISSION_SIZE+1];
+   
+   /**
+    * FIELD: PASS
+    */
+   char thePass[PASS_SIZE+1];
+   
+   /**
+    * FIELD: OPNUM
+    */
+   char theOpNum[OP_NUM_SIZE+1];
+   
+   /**
+    * FIELD: STARTSEGMENT
+    */
+   char theStartSegment[START_SEGMENT_SIZE+1];
+   
+   /**
+    * FIELD: REPRONUM
+    */
+   char theReproNum[REPRO_NUM_SIZE+1];
+   
+   /**
+    * FIELD: REPLAYREGEN
+    */
+   char theReplayRegen[REPLAY_REGEN_SIZE+1];
+   
+   /**
+    * FIELD: BLANKFILL
+    */
+   char theBlankFill[BLANK_FILL_SIZE+1];
+   
+   /**
+    * FIELD: STARTCOLUMN
+    */
+   char theStartColumn[START_COLUMN_SIZE+1];
+   
+   /**
+    * FIELD: STARTROW
+    */
+   char theStartRow[START_ROW_SIZE+1];
+   
+   /**
+    * FIELD: ENDSEGMENT
+    */
+   char theEndSegment[END_SEGMENT_SIZE+1];
+   
+   /**
+    * FIELD: ENDCOLUMN
+    */
+   char theEndColumn[END_COLUMN_SIZE+1];
+   
+   /**
+    * FIELD: ENDROW
+    */
+   char theEndRow[END_ROW_SIZE+1];
+   
+   /**
+    * FIELD: COUNTRY
+    */
+   char theCountry[COUNTRY_SIZE+1];
+   
+   /**
+    * FIELD: WAC
+    */
+   char theWac[WAC_SIZE+1];
+   
+   /**
+    * FIELD: LOCATION
+    */
+   char theLocation[LOCATION_SIZE+1];
+   
+   /**
+    * FIELD: FIELD17
+    */
+   char theField17[FIELD17_SIZE+1];
+   
+   /**
+    * FIELD: FIELD18
+    */
+   char theField18[FIELD18_SIZE+1];
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeader.cpp
new file mode 100644
index 0000000000..30ca48b064
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeader.cpp
@@ -0,0 +1,26 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfSymbolHeader.cpp,v 1.2 2004/05/23 14:48:58 dburken Exp $
+#include "ossimNitfSymbolHeader.h"
+
+RTTI_DEF1(ossimNitfSymbolHeader, "ossimNitfSymbolHeader", ossimObject)
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeader.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeader.h
new file mode 100644
index 0000000000..3db970a73e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeader.h
@@ -0,0 +1,44 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfSymbolHeader.h,v 1.2 2004/05/23 14:48:58 dburken Exp $
+#ifndef ossimNitfSymbolHeader_HEADER
+#define ossimNitfSymbolHeader_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimObject.h"
+#include "base/data_types/ossimDrect.h"
+
+class OSSIMDLLEXPORT ossimNitfSymbolHeader : public ossimObject
+{
+public:
+   ossimNitfSymbolHeader(){}
+   virtual ~ossimNitfSymbolHeader(){}
+
+   virtual void parseStream(istream &in)=0;
+   virtual long getDisplayLevel()const=0;
+   virtual ossimDrect getImageRect()const=0;
+
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeaderV2_0.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeaderV2_0.cpp
new file mode 100644
index 0000000000..3608ac1297
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeaderV2_0.cpp
@@ -0,0 +1,185 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfSymbolHeaderV2_0.cpp,v 1.3 2004/05/23 18:42:33 dburken Exp $
+#include <support_data/nitf/ossimNitfSymbolHeaderV2_0.h>
+#include <base/data_types/ossimString.h>
+#include <cstring> // for memset
+
+RTTI_DEF1(ossimNitfSymbolHeaderV2_0, "ossimNitfSymbolHeaderV2_0", ossimNitfSymbolHeader)
+
+ossimNitfSymbolHeaderV2_0::ossimNitfSymbolHeaderV2_0()
+{
+   clearFields();
+}
+
+void ossimNitfSymbolHeaderV2_0::parseStream(istream &in)
+{
+   if(in)
+   {
+      clearFields();
+      
+      in.read(theFilePartType, 2); 
+      in.read(theSymbolId, 10);    
+      in.read(theSymbolName, 20); 
+      in.read(theSymbolSecurityClass, 1);
+      in.read(theSymbolCodewords, 40);
+      in.read(theSymbolControlAndHandling, 40);
+      in.read(theSymbolReleasingInstructions, 40);
+      in.read(theSymbolClassificationAuthority, 20);
+      in.read(theSymbolSecurityControlNum, 20);
+      in.read(theSymbolSecurityDowngrade, 6);
+      if(ossimString(theSymbolSecurityDowngrade) == "999998")
+      {
+         in.read(theSymbolDowngradingEvent, 40);
+      }
+      in.read(theSymbolEncryption, 1);
+      in.read(theSymbolType, 1);
+      in.read(theNumberLinesPerSymbol, 4);
+      in.read(theSymbolNumberPixelsPerLine, 4);
+      in.read(theSymbolLineWidth, 4);
+      in.read(theSymbolNumberBitsPerPixel, 1);
+      in.read(theSymbolDisplayLevel, 3);
+      in.read(theSymbolAttachmentLevel, 3);
+      in.read(theSymbolLocation, 10);
+      in.read(theSecondSymbolLocation, 10);
+      in.read(theSymbolColor, 1);
+      in.read(theSymbolNumber, 6);
+      in.read(theSymbolRotation, 3);
+      in.read(theSymbolNumberOfLutEntries, 3);
+
+      // do lut here.  we will temporarily ignore
+      in.ignore(ossimString(theSymbolNumberOfLutEntries).toLong());
+      
+      in.read(theSymbolExtendedSubheaderDataLength, 5);
+      in.read(theSymbolSubheaderOverflow, 3);
+      
+   }
+}
+
+std::ostream& ossimNitfSymbolHeaderV2_0::print(std::ostream &out)const
+{
+   
+   out << "theFilePartType:                   " << theFilePartType << std::endl
+       << "theSymbolId:                       " << theSymbolId << std::endl
+       << "theSymbolName:                     " << theSymbolName << std::endl
+       << "theSymbolSecurityClass:            " << theSymbolSecurityClass << std::endl
+       << "theSymbolCodewords:                " << theSymbolCodewords << std::endl
+       << "theSymbolControlAndHandling:       " << theSymbolControlAndHandling << std::endl
+       << "theSymbolReleasingInstructions:    " << theSymbolReleasingInstructions << std::endl
+       << "theSymbolClassificationAuthority:  " << theSymbolClassificationAuthority << std::endl
+       << "theSymbolSecurityControlNum:       " << theSymbolSecurityControlNum << std::endl
+       << "theSymbolSecurityDowngrade:        " << theSymbolSecurityDowngrade << std::endl
+       << "theSymbolDowngradingEvent:         " << theSymbolDowngradingEvent << std::endl
+       << "theSymbolEncryption:               " << theSymbolEncryption << std::endl
+       << "theSymbolType:                     " << theSymbolType << std::endl
+       << "theNumberLinesPerSymbol:           " << theNumberLinesPerSymbol << std::endl
+       << "theSymbolNumberPixelsPerLine:      " << theSymbolNumberPixelsPerLine << std::endl
+       << "theSymbolLineWidth:                " << theSymbolLineWidth << std::endl
+       << "theSymbolNumberBitsPerPixel:       " << theSymbolNumberBitsPerPixel << std::endl
+       << "theSymbolDisplayLevel:             " << theSymbolDisplayLevel << std::endl
+       << "theSymbolAttachmentLevel:          " << theSymbolAttachmentLevel << std::endl
+       << "theSymbolLocation:                 " << theSymbolLocation << std::endl
+       << "theSecondSymbolLocation:           " << theSecondSymbolLocation << std::endl
+       << "theSymbolColor:                    " << theSymbolColor << std::endl
+       << "theSymbolNumber:                   " << theSymbolNumber << std::endl
+       << "theSymbolRotation:                 " << theSymbolRotation << std::endl
+       << "theSymbolNumberOfLutEntries:       " << theSymbolNumberOfLutEntries << std::endl
+       << "theSymbolExtendedSubheaderDataLength:  " << theSymbolExtendedSubheaderDataLength << std::endl
+       << "theSymbolSubheaderOverflow:        " << theSymbolSubheaderOverflow << std::endl;
+   return out;
+}
+
+long ossimNitfSymbolHeaderV2_0::getDisplayLevel()const
+{
+   return ossimString(theSymbolDisplayLevel).toLong();
+}
+
+ossimDrect ossimNitfSymbolHeaderV2_0::getImageRect()const
+{
+   // for now we will return an empty rect.  This will be more
+   // complicated to compute a symbol bound.  The origin depends
+   // on the symbol and is different for different symbols.
+   // We will implement this one last.
+   return ossimDrect(0,0,0,0);
+}
+
+
+void ossimNitfSymbolHeaderV2_0::clearFields()
+{   
+   memset(theFilePartType, ' ', 2);
+   memset(theSymbolId, ' ', 10);
+   memset(theSymbolName, ' ', 20);
+   memset(theSymbolSecurityClass, ' ', 1);
+   memset(theSymbolCodewords, ' ', 40);
+   memset(theSymbolControlAndHandling, ' ', 40);
+   memset(theSymbolReleasingInstructions, ' ', 40);
+   memset(theSymbolClassificationAuthority, ' ', 20);
+   memset(theSymbolSecurityControlNum, ' ', 20);
+   memset(theSymbolSecurityDowngrade, ' ', 6);
+   memset(theSymbolDowngradingEvent, ' ', 40);
+   memset(theSymbolEncryption, ' ', 1);
+   memset(theSymbolType, ' ', 1);
+   memset(theNumberLinesPerSymbol, ' ', 4);
+   memset(theSymbolNumberPixelsPerLine, ' ', 4);
+   memset(theSymbolLineWidth, ' ', 4);
+   memset(theSymbolNumberBitsPerPixel, ' ', 1);
+   memset(theSymbolDisplayLevel, ' ', 3);
+   memset(theSymbolAttachmentLevel, ' ', 3);
+   memset(theSymbolLocation, ' ', 10);
+   memset(theSecondSymbolLocation, ' ', 10);
+   memset(theSymbolColor, ' ', 1);
+   memset(theSymbolNumber, ' ', 6);
+   memset(theSymbolRotation, ' ', 3);
+   memset(theSymbolNumberOfLutEntries, ' ', 3);
+   memset(theSymbolExtendedSubheaderDataLength, ' ', 5);
+   memset(theSymbolSubheaderOverflow, ' ', 3);
+
+
+   theFilePartType[2]                  = '\0';
+   theSymbolId[10]                     = '\0';
+   theSymbolName[20]                   = '\0';
+   theSymbolSecurityClass[1]           = '\0';
+   theSymbolCodewords[40]              = '\0';
+   theSymbolControlAndHandling[40]     = '\0';
+   theSymbolReleasingInstructions[40]  = '\0';
+   theSymbolClassificationAuthority[20] = '\0';
+   theSymbolSecurityControlNum[20]     = '\0';
+   theSymbolSecurityDowngrade[6]       = '\0';
+   theSymbolDowngradingEvent[40]       = '\0';
+   theSymbolEncryption[1]              = '\0';
+   theSymbolType[1]                    = '\0';
+   theNumberLinesPerSymbol[4]          = '\0';
+   theSymbolNumberPixelsPerLine[4]     = '\0';
+   theSymbolLineWidth[4]               = '\0';
+   theSymbolNumberBitsPerPixel[1]      = '\0';
+   theSymbolDisplayLevel[3]            = '\0';
+   theSymbolAttachmentLevel[3]         = '\0';
+   theSymbolLocation[10]               = '\0';
+   theSecondSymbolLocation[10]         = '\0';
+   theSymbolColor[1]                   = '\0';
+   theSymbolNumber[6]                  = '\0';
+   theSymbolRotation[3]                = '\0';
+   theSymbolNumberOfLutEntries[3]      = '\0';
+   theSymbolExtendedSubheaderDataLength[5] = '\0';
+   theSymbolSubheaderOverflow[3]       ='\0';
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeaderV2_0.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeaderV2_0.h
new file mode 100644
index 0000000000..0c588e3851
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfSymbolHeaderV2_0.h
@@ -0,0 +1,236 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfSymbolHeaderV2_0.h,v 1.2 2004/05/23 18:42:33 dburken Exp $
+#ifndef ossimNitfSymbolHeaderV2_0_HEADER
+#define ossimNitfSymbolHeaderV2_0_HEADER
+#include "ossimNitfSymbolHeader.h"
+#include "ossimNitfImageLutV2_0.h"
+
+class ossimNitfSymbolHeaderV2_0 : public ossimNitfSymbolHeader
+{
+public:
+   ossimNitfSymbolHeaderV2_0();
+   virtual ~ossimNitfSymbolHeaderV2_0(){}
+   
+   virtual void parseStream(istream &in);
+   virtual std::ostream& print(std::ostream &out)const;
+   virtual long getDisplayLevel()const;
+   virtual ossimDrect getImageRect()const;
+
+TYPE_DATA
+private:
+   void clearFields();
+   
+   /*!
+    * Is a required 2 byte field.  The expected value
+    * is SY.
+    */
+   char theFilePartType[3];
+
+   /*!
+    * is a 10 byte required alphanumeric field.
+    */
+   char theSymbolId[11];
+
+   /*!
+    * is an optional 20 byte alphanumeric field
+    */
+   char theSymbolName[21];
+
+   /*!
+    * Security classification is a required 1 byte field.
+    * Expected values can
+    * either be:
+    *
+    * T  Top secret
+    * S  Secret
+    * C  Confidential
+    * R  Restricted
+    * U  UnClassified
+    */
+   char theSymbolSecurityClass[2];
+
+   /*!
+    * 40 byte optional field
+    */
+   char theSymbolCodewords[41];
+
+   /*!
+    * 40 byte optional field.
+    */
+   char theSymbolControlAndHandling[41];
+
+   /*!
+    * 40 byte optional field.
+    */
+   char theSymbolReleasingInstructions[41];
+
+   /*!
+    * optional 20 byte field.
+    */
+   char theSymbolClassificationAuthority[21];
+
+   /*!
+    * optional 20 byte field.
+    */
+   char theSymbolSecurityControlNum[21];
+
+   /*!
+    * optional 6 byte value.
+    */
+   char theSymbolSecurityDowngrade[7];
+
+   /*!
+    * Conditional field.  This field exists if
+    * theSymbolSecurityDowngrade has the value of
+    * 999998.  If it exists it will be a 40 byte
+    * field.
+    */
+   char theSymbolDowngradingEvent[41];
+
+   /*!
+    * This is a required 1 byte field and can have
+    * a value of:
+    *
+    * 0    Not encrypted
+    * 1    Encrytped
+    *
+    */
+   char theSymbolEncryption[2];
+
+   /*!
+    * This is a required one byte field and can have the value
+    * of either:
+    *
+    * B    Bit-mapped
+    * C    for CGM
+    * O    for object
+    *
+    *
+    * if it's O then theSymbolNumber will hold a number to the symbol
+    * object to draw.  See field theSymbolNumber for object
+    * numbers and object types.
+    */
+   char theSymbolType[2];
+
+   /*!
+    * This is a required 4 byte field. Ranges from 0-9999.
+    *
+    * if theSymbolType is B or O this field will contain
+    * the number of rows (lines) in the symbol image. This
+    * field shall contain 0 if theSymbolType is C
+    */
+   char theNumberLinesPerSymbol[5];
+
+   /*!
+    * This is a required 4 byte field. Ranges from 0-9999
+    *
+    * if theSymbolType is B or O this field will contain
+    * the number of pixels in each row. This
+    * field shall contain 0 if theSymbolType is C
+    */
+   char theSymbolNumberPixelsPerLine[5];
+
+   /*!
+    * This is a required 4 byte field.  Ranges from 0-9999
+    *
+    * if theSymbolType is O this field will contain
+    * the line width for the object symbol in pixels.
+    *
+    * if this field equals theNumberLinesPerSymbol then the
+    * symbol should be drawn solid and filled in.
+    */
+   char theSymbolLineWidth[5];
+
+   /*!
+    * This is a required 1 byte field.  Ranges from 0-8
+    */
+   char theSymbolNumberBitsPerPixel[2];
+
+   /*!
+    * This is a required 3 byte field. Ranges from 1-999
+    */
+   char theSymbolDisplayLevel[4];
+
+   /*!
+    * This is a required 3 byte field. Ranges from 0-998
+    */
+   char theSymbolAttachmentLevel[4];
+
+   /*!
+    * This is a required 10 byte field.  This indicates the location
+    * in image space.
+    *
+    *  rrrrrccccc five characters for r followed by five for the column
+    */
+   char theSymbolLocation[11];
+
+   /*!
+    * This is an optional 10 byte field.  Has format
+    * rrrrrccccc  where r is row c is column.
+    */
+   char theSecondSymbolLocation[11];
+
+   /*!
+    * This is a required 1 byte field.
+    */
+   char theSymbolColor[2];
+
+   /*!
+    * This is an optional 6 byte field.
+    *
+    * 
+    */
+   char theSymbolNumber[7];
+
+   /*!
+    * This is a required 3 byte field. Ranges from 0-359
+    */
+   char theSymbolRotation[4];
+
+   /*!
+    * This is a required 3 byte field.  Ranges from 0-256
+    */
+   char theSymbolNumberOfLutEntries[4];
+
+   /*!
+    * This will hold the lookup table values for
+    * the pixel data.  This is a conditional field and will
+    * exist if theSymbolNumberOfLutEntries is not 0.
+    */
+   ossimNitfImageLutV2_0 theSymbolLutData;
+
+   /*!
+    * This is is a required 5 byte field.
+    * Will range from 0-08833.
+    */
+   char theSymbolExtendedSubheaderDataLength[6];
+
+   /*!
+    * This is a conditional 3 byte field that ranges from
+    * 0-999.  This field will depend on theSymbolExtendedSubheaderDataLength
+    * not being 0.
+    */
+   char theSymbolSubheaderOverflow[4];
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactory.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactory.cpp
new file mode 100644
index 0000000000..61deb9b7ac
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactory.cpp
@@ -0,0 +1,35 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTagFactory.cpp,v 1.1 2003/04/02 20:27:35 gpotts Exp $
+#include "ossimNitfTagFactory.h"
+
+RTTI_DEF1(ossimNitfTagFactory, "ossimNitfTagFactory", ossimObject)
+
+ossimNitfTagFactory::~ossimNitfTagFactory()
+{
+}
+
+ossimNitfTagFactory::ossimNitfTagFactory()
+{
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactory.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactory.h
new file mode 100644
index 0000000000..2478575980
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactory.h
@@ -0,0 +1,36 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see top level LICENSE.txt
+// 
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTagFactory.h,v 1.2 2004/09/28 15:35:30 gpotts Exp $
+#ifndef ossimNitfTagFactory_HEADER
+#define ossimNitfTagFactory_HEADER
+#include <base/common/ossimObject.h>
+#include <base/common/ossimRefPtr.h>
+
+class ossimNitfRegisteredTag;
+
+class ossimNitfTagFactory : public ossimObject
+{
+public:
+   ossimNitfTagFactory();
+   virtual ~ossimNitfTagFactory();
+   virtual ossimRefPtr<ossimNitfRegisteredTag> create(const ossimString &tagName)const=0;
+private:
+   /*!
+    * Hide this.
+    */
+   ossimNitfTagFactory(const ossimNitfTagFactory &rhs){}
+
+   /*!
+    * Hide this.
+    */ 
+   ossimNitfTagFactory& operator =(const ossimNitfTagFactory &rhs){return *this;}
+TYPE_DATA
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactoryRegistry.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactoryRegistry.cpp
new file mode 100644
index 0000000000..edb3e81a8f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactoryRegistry.cpp
@@ -0,0 +1,89 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL see LICENSE.txt
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTagFactoryRegistry.cpp,v 1.2 2004/09/28 15:35:30 gpotts Exp $
+#include <support_data/nitf/ossimNitfTagFactoryRegistry.h>
+#include <support_data/nitf/ossimNitfRpfTagFactory.h>
+#include <support_data/nitf/ossimNitfRegisteredTagFactory.h>
+#ifndef NULL
+#include <stddef.h>
+#endif
+#include <algorithm>
+
+ossimNitfTagFactoryRegistry* ossimNitfTagFactoryRegistry::theInstance=NULL;
+
+ossimNitfTagFactoryRegistry::ossimNitfTagFactoryRegistry()
+{
+}
+
+ossimNitfTagFactoryRegistry::~ossimNitfTagFactoryRegistry()
+{
+   theInstance = NULL;
+}
+
+
+void ossimNitfTagFactoryRegistry::registerFactory(ossimNitfTagFactory* aFactory)
+{
+   if(aFactory&&!exists(aFactory))
+   {
+      theFactoryList.push_back(aFactory);
+   }
+}
+
+
+ossimNitfTagFactoryRegistry* ossimNitfTagFactoryRegistry::instance()
+{
+   if(theInstance)
+   {
+      return theInstance;
+   }
+   else
+   {
+      theInstance = new ossimNitfTagFactoryRegistry;
+      theInstance->initializeDefaults();
+   }
+   
+   return theInstance;
+}
+
+ossimRefPtr<ossimNitfRegisteredTag> ossimNitfTagFactoryRegistry::create(const ossimString &tagName)const
+{
+   std::vector<ossimNitfTagFactory*>::const_iterator factory;
+   ossimRefPtr<ossimNitfRegisteredTag> result = NULL;
+
+   factory = theFactoryList.begin();
+   while(factory != theFactoryList.end())
+   {
+      result = (*factory)->create(tagName);
+
+      if(result.valid())
+      {
+         return result;
+      }
+      ++factory;
+   }
+   
+   return NULL;
+}
+
+void ossimNitfTagFactoryRegistry::initializeDefaults()
+{
+   theFactoryList.push_back(ossimNitfRegisteredTagFactory::instance());
+   theFactoryList.push_back(ossimNitfRpfTagFactory::instance());
+}
+
+bool ossimNitfTagFactoryRegistry::exists(ossimNitfTagFactory* factory)const
+{
+   std::vector<ossimNitfTagFactory*>::const_iterator iter = std::find(theFactoryList.begin(),
+                                                                      theFactoryList.end(),
+                                                                      factory);
+
+   return (iter != theFactoryList.end());
+   
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactoryRegistry.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactoryRegistry.h
new file mode 100644
index 0000000000..06f5f3363c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagFactoryRegistry.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTagFactoryRegistry.h,v 1.2 2004/09/28 15:35:30 gpotts Exp $
+#ifndef ossimNitfTagFactoryRegistry_HEADER
+#define ossimNitfTagFactoryRegistry_HEADER
+#include <vector>
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+class ossimString;
+class ossimNitfTagFactory;
+
+class ossimNitfTagFactoryRegistry
+{
+public:
+   virtual ~ossimNitfTagFactoryRegistry();
+   void registerFactory(ossimNitfTagFactory* aFactory);
+   void unregisterFactory(ossimNitfTagFactory* aFactory);
+   
+   static ossimNitfTagFactoryRegistry* instance();
+   
+   ossimRefPtr<ossimNitfRegisteredTag> create(const ossimString &tagName)const;
+   bool exists(ossimNitfTagFactory* factory)const;
+   
+protected:
+   ossimNitfTagFactoryRegistry();
+
+private:
+   ossimNitfTagFactoryRegistry(const ossimNitfTagFactoryRegistry &){} // hide
+   const ossimNitfTagFactoryRegistry & operator =(const ossimNitfTagFactoryRegistry &){return *this;} // hide
+
+   void initializeDefaults();
+
+   static ossimNitfTagFactoryRegistry* theInstance;
+   
+   std::vector<ossimNitfTagFactory*> theFactoryList;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagInformation.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagInformation.cpp
new file mode 100644
index 0000000000..4266ce27e7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagInformation.cpp
@@ -0,0 +1,158 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// LICENSE: LGPL  see top level LICENSE.txt
+//
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTagInformation.cpp,v 1.7 2004/11/18 17:09:27 gpotts Exp $
+#include "ossimNitfTagInformation.h"
+#include <base/common/ossimCommon.h>
+#include <sstream>
+#include <iomanip>
+#include <string.h> // for memset
+
+ossimNitfTagInformation::ossimNitfTagInformation(ossimRefPtr<ossimNitfRegisteredTag> tagData)
+{
+   clearFields();
+   setTagData(tagData);
+}
+
+ossimNitfTagInformation::~ossimNitfTagInformation()
+{
+}
+
+void ossimNitfTagInformation::parseStream(std::istream &in)
+{
+   if(in)
+   {
+      theTagOffset = in.tellg();
+      in.read(theTagName, 6);
+      in.read(theTagLength, 5);
+      theTagDataOffset = in.tellg();
+      
+      // we will not read tag information in here.
+      // This is for speed.  No need to read tags if not used.
+      // But we will save offsets so they can be read later.
+      //
+      theTagData = (ossimNitfRegisteredTag*)NULL;
+   }
+   else
+   {
+      //ERROR
+   }
+}
+
+
+void ossimNitfTagInformation::writeStream(std::ostream &out)
+{
+   out.write(theTagName, 6);
+   out.write(theTagLength, 5);
+   if(theTagData.valid())
+   {
+      theTagData->writeStream(out);
+   }
+}
+
+ossim_uint32 ossimNitfTagInformation::getTotalTagLength()const
+{
+   return (getTagLength() + (ossim_uint32)11);
+}
+
+ossim_uint32 ossimNitfTagInformation::getTagLength()const
+{
+   return ossimString(theTagLength).toUInt32();
+}
+
+ossim_uint64 ossimNitfTagInformation::getTagOffset()const
+{
+   return theTagOffset;
+}
+
+ossim_uint64 ossimNitfTagInformation::getTagDataOffset()const
+{
+   return theTagDataOffset;
+}
+
+ossimString ossimNitfTagInformation::getTagName()const
+{
+   return ossimString(theTagName).trim();
+}
+
+std::ostream& ossimNitfTagInformation::print(std::ostream& out)const
+{
+   out << "theTagName:          " << theTagName   << endl
+       << "theTagLength:        " << theTagLength << endl
+       << "theTagOffset:        " << theTagOffset << endl
+       << "theTagDataOffset:    " << theTagDataOffset;
+
+   return out;
+}
+
+void ossimNitfTagInformation::clearFields()
+{
+   memset(theTagName, ' ', 6);
+   memset(theTagLength, '0', 5);
+
+   theTagName[6]    = '\0';
+   theTagLength[5]  = '\0';
+   
+   theTagOffset     = 0;
+   theTagDataOffset = 0;
+}
+
+void ossimNitfTagInformation::setTagName(const ossimString& tagName)
+{
+   memset(theTagName, ' ', 6);
+
+   std::ostringstream out;
+
+   out << std::setw(6)
+       << std::setfill(' ')
+       << tagName;
+   memcpy(theTagName, out.str().c_str(), 6);
+}
+
+void ossimNitfTagInformation::setTagLength(ossim_uint32 tagLength)
+{
+   memset(theTagLength, '0', 5);
+   
+   if(tagLength > 99999)
+   {
+      tagLength = 99999;
+   }
+
+   std::ostringstream out;
+
+   out << std::setw(5)
+       << std::setfill('0')
+       << tagLength;
+   
+   memcpy(theTagLength, out.str().c_str(), 5);
+}
+
+ossimRefPtr<ossimNitfRegisteredTag> ossimNitfTagInformation::getTagData()
+{
+   return theTagData;
+}
+
+const ossimRefPtr<ossimNitfRegisteredTag> ossimNitfTagInformation::getTagData()const
+{
+   return theTagData;
+}
+
+void ossimNitfTagInformation::setTagData(ossimRefPtr<ossimNitfRegisteredTag> tagData)
+{
+   theTagData = tagData;
+
+   memset(theTagName, ' ', 6);
+   memset(theTagLength, ' ', 5);
+   
+   if(theTagData.valid())
+   {
+      setTagName(theTagData->getRegisterTagName());
+      setTagLength(theTagData->getSizeInBytes());
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagInformation.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagInformation.h
new file mode 100644
index 0000000000..9ede415d99
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTagInformation.h
@@ -0,0 +1,100 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTagInformation.h,v 1.6 2004/09/29 11:17:46 gpotts Exp $
+#ifndef ossimNitfTagInformation_HEADER
+#define ossimNitfTagInformation_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimObject.h"
+#include "base/data_types/ossimString.h"
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class OSSIMDLLEXPORT ossimNitfTagInformation : public ossimObject
+{
+public:
+   ossimNitfTagInformation(ossimRefPtr<ossimNitfRegisteredTag> tagData = NULL);
+   ~ossimNitfTagInformation();
+   
+   virtual void parseStream(std::istream& in);
+   virtual void writeStream(std::ostream& out);
+
+   void setTagName(const ossimString& tagName);
+   void setTagLength(ossim_uint32 tagLength);
+
+   /**
+    * Length of the 5 byte tag length the 6 byte tag name and
+    * the data length.
+    * So we have Data length + 11 bytes.
+    */
+   ossim_uint32 getTotalTagLength()const;
+
+   /**
+    * Should return the value of theTagLength which is the length of
+    * the data in bytes.
+    */
+   ossim_uint32 getTagLength()const;
+   ossim_uint64 getTagOffset()const;
+   ossim_uint64 getTagDataOffset()const;
+   
+   ossimString   getTagName()const;
+   virtual std::ostream& print(std::ostream& out)const;
+   void clearFields();
+   
+   ossimRefPtr<ossimNitfRegisteredTag> getTagData();
+   const ossimRefPtr<ossimNitfRegisteredTag> getTagData()const;
+   void setTagData(ossimRefPtr<ossimNitfRegisteredTag> tagData);
+
+   
+private:
+
+   /**
+    * This is a 6 byte field
+    */
+   char          theTagName[7];
+
+   /**
+    * This is a 5 byte field
+    */
+   char           theTagLength[6];
+
+   /**
+    * This will hold the offset to the start of the above information
+    * This is just a work variable.
+    */
+   ossim_uint64 theTagOffset;
+
+   /**
+    * This will hold the start to the data.  This is just the
+    * position in the file just past the tag length field.
+    * This is just a work variable
+    */
+   ossim_uint64 theTagDataOffset;
+
+   /**
+    * Used to hold the tag data.
+    */
+   ossimRefPtr<ossimNitfRegisteredTag> theTagData;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeader.cpp
new file mode 100644
index 0000000000..54787d18a0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeader.cpp
@@ -0,0 +1,26 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTextHeader.cpp,v 1.2 2004/05/23 14:48:58 dburken Exp $
+#include "ossimNitfTextHeader.h"
+
+RTTI_DEF1(ossimNitfTextHeader, "ossimNitfTextHeader", ossimObject)
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeader.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeader.h
new file mode 100644
index 0000000000..79a86c97d2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeader.h
@@ -0,0 +1,41 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTextHeader.h,v 1.2 2004/05/23 14:48:58 dburken Exp $
+#ifndef ossimNitfTextHeader_HEADER
+#define ossimNitfTextHeader_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimObject.h"
+
+class OSSIMDLLEXPORT ossimNitfTextHeader : public ossimObject
+{
+public:
+   ossimNitfTextHeader(){}
+   virtual ~ossimNitfTextHeader(){}
+   
+   virtual void parseStream(istream &in)=0;
+   
+TYPE_DATA
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeaderV2_0.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeaderV2_0.cpp
new file mode 100644
index 0000000000..69dc670af4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeaderV2_0.cpp
@@ -0,0 +1,127 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTextHeaderV2_0.cpp,v 1.2 2004/05/23 18:42:33 dburken Exp $
+#include "ossimNitfTextHeaderV2_0.h"
+#include "base/data_types/ossimString.h"
+#include <string.h> // for memset
+
+RTTI_DEF1(ossimNitfTextHeaderV2_0, "ossimNitfTextHeaderV2_0", ossimNitfTextHeader)
+   
+ossimNitfTextHeaderV2_0::ossimNitfTextHeaderV2_0()
+{
+   clearFields();
+}
+
+void ossimNitfTextHeaderV2_0::parseStream(istream &in)
+{
+   if(in)
+   {
+      clearFields();
+      
+      in.read(theFilePartType, 2);
+      in.read(theTextId, 10);
+      in.read(theDataAndTime, 14);
+      in.read(theTextTitle, 80);
+      in.read(theTextSecurityClassification, 1);
+      in.read(theTextCodewords, 40);
+      in.read(theTextControlAndHandling, 40);
+      in.read(theTextReleasingInstructions, 40);
+      in.read(theTextClassificationAuthority, 20);
+      in.read(theTextSecurityControlNumber, 20);
+      in.read(theTextSecurityDowngrade, 6);
+      if(ossimString(theTextSecurityDowngrade) == "999998")
+      {
+         in.read(theTextSecurityDowngradeEvent, 40);
+      }
+      in.read(theTextEncyption, 1);
+      in.read(theTextFormat, 3);
+      in.read(theExtSubheaderDataLength, 5);
+      long dataLength = ossimString(theExtSubheaderDataLength).toLong();
+      if(dataLength > 0)
+      {
+         in.read(theExtSubheaderOverflow, 3);
+
+         // ignore the data for now
+         in.ignore(dataLength - 3);
+      }
+   }
+}
+
+std::ostream& ossimNitfTextHeaderV2_0::print(std::ostream &out)const
+{
+   out << "theFilePartType:                 " << theFilePartType << endl
+       << "theTextId:                       " << theTextId << endl
+       << "theDataAndTime:                  " << theDataAndTime << endl
+       << "theTextTitle:                    " << theTextTitle << endl
+       << "theTextSecurityClassification:   " << theTextSecurityClassification << endl
+       << "theTextCodewords:                " << theTextCodewords << endl
+       << "theTextControlAndHandling:       " << theTextControlAndHandling << endl
+       << "theTextReleasingInstructions:    " << theTextReleasingInstructions << endl
+       << "theTextClassificationAuthority:  " << theTextClassificationAuthority << endl
+       << "theTextSecurityControlNumber:    " << theTextSecurityControlNumber << endl
+       << "theTextSecurityDowngrade:        " << theTextSecurityDowngrade << endl
+       << "theTextSecurityDowngradeEvent:   " << theTextSecurityDowngradeEvent << endl
+       << "theTextEncyption:                " << theTextEncyption << endl
+       << "theTextFormat:                   " << theTextFormat << endl
+       << "theExtSubheaderDataLength:       " << theExtSubheaderDataLength << endl
+       << "theExtSubheaderOverflow:         " << theExtSubheaderOverflow;
+   return out;
+}
+
+void ossimNitfTextHeaderV2_0::clearFields()
+{
+   
+   memset(theFilePartType, ' ', 2);
+   memset(theTextId, ' ', 10);
+   memset(theDataAndTime, ' ', 14);
+   memset(theTextTitle, ' ', 80);
+   memset(theTextSecurityClassification, ' ', 1);
+   memset(theTextCodewords, ' ', 40);
+   memset(theTextControlAndHandling, ' ', 40);
+   memset(theTextReleasingInstructions, ' ', 40);
+   memset(theTextClassificationAuthority, ' ', 20);
+   memset(theTextSecurityControlNumber, ' ', 20);
+   memset(theTextSecurityDowngrade, ' ', 6);
+   memset(theTextSecurityDowngradeEvent, ' ', 40);
+   memset(theTextEncyption, ' ', 1);
+   memset(theTextFormat, ' ', 3);
+   memset(theExtSubheaderDataLength, ' ', 5);
+   memset(theExtSubheaderOverflow, ' ', 3);
+
+   theFilePartType[2] = '\0';
+   theTextId[10] = '\0';
+   theDataAndTime[14] = '\0';
+   theTextTitle[80] = '\0';
+   theTextSecurityClassification[1] = '\0';
+   theTextCodewords[40] = '\0';
+   theTextControlAndHandling[40] = '\0';
+   theTextReleasingInstructions[40] = '\0';
+   theTextClassificationAuthority[20] = '\0';
+   theTextSecurityControlNumber[20] = '\0';
+   theTextSecurityDowngrade[6] = '\0';
+   theTextSecurityDowngradeEvent[40] = '\0';
+   theTextEncyption[1] = '\0';
+   theTextFormat[3] = '\0';
+   theExtSubheaderDataLength[5] = '\0';
+   theExtSubheaderOverflow[3] = '\0';
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeaderV2_0.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeaderV2_0.h
new file mode 100644
index 0000000000..9b18377801
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfTextHeaderV2_0.h
@@ -0,0 +1,155 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfTextHeaderV2_0.h,v 1.2 2004/05/23 18:42:33 dburken Exp $
+
+#ifndef ossimNitfTextHeaderV2_0_HEADER
+#define ossimNitfTextHeaderV2_0_HEADER
+#include "ossimNitfTextHeader.h"
+
+class OSSIMDLLEXPORT ossimNitfTextHeaderV2_0 : public ossimNitfTextHeader
+{
+public:
+   ossimNitfTextHeaderV2_0();
+   virtual ~ossimNitfTextHeaderV2_0(){}
+   
+   virtual void parseStream(istream &in);
+   virtual std::ostream& print(std::ostream &out)const;
+
+TYPE_DATA
+private:
+   void clearFields();
+
+   /*!
+    * This is a required 2 byte fields and has
+    * a value of TE.
+    */
+   char theFilePartType[3];
+
+   /*!
+    * This is a required 10 byte field.
+    */
+   char theTextId[11];
+
+   /*!
+    * This is a required 14 byte field.  It has the
+    * format of:
+    *
+    *  DDHHMMSSZMONYY
+    *
+    * DD   2 character day
+    * HH   2 characters for the Hour
+    * MM   2 characters for the minute
+    * SS   2 characters for the seconds
+    * Z    required
+    * MON  3 characters of the month
+    * YY   2 characters for the year
+    */
+   char theDataAndTime[15];
+
+   /*!
+    * is an optional 80 byte field
+    */
+   char theTextTitle[81];
+
+   /*!
+    * This is a required 1 byte field. Can have
+    * of either:
+    *
+    * T   Top secret
+    * S   Secret
+    * C   Confidential
+    * R   Restricted
+    * U   Unclassified
+    */
+   char theTextSecurityClassification[2];
+
+   /*!
+    * This is an optional 40 byte field.
+    */
+   char theTextCodewords[41];
+
+   /*!
+    * This is an optional 40 yte field.
+    */
+   char theTextControlAndHandling[41];
+
+   /*!
+    * This is an optional 40 yte field.
+    */
+   char theTextReleasingInstructions[41];
+
+   /*!
+    * optional 20 byte field
+    */
+   char theTextClassificationAuthority[21];
+
+   /*!
+    * optional 20 byte field
+    */
+   char theTextSecurityControlNumber[21];
+
+   /*!
+    * optional 6 byte field
+    */
+   char theTextSecurityDowngrade[7];
+
+   /*
+    * This is a conditional 40 byte field.  if 
+    * theSecurityDowngrade = 999998 then this field
+    * exists.
+    */
+   char theTextSecurityDowngradeEvent[41];
+
+   /*!
+    * This is the encription type and is a
+    * required 1 byte field.  It can have values
+    *
+    * 0  Not encrypted
+    * 1  Encrypted
+    */
+   char theTextEncyption[2];
+
+   /*!
+    * This is a required 3 byte field and will hold
+    * either:
+    *
+    * MTF  indicates USMTF ( refer to JCS PUB 6-04
+    *      for examples
+    * STA  indicates NITF ASCII
+    * OTH  indicates other or user defined
+    */
+   char theTextFormat[4];
+
+   /*!
+    * is a required 5 byute field.
+    */
+   char theExtSubheaderDataLength[6];
+
+   /*!
+    * is a conditional 3 byte field.  It exists if
+    * theExtSubheaderDataLength is not 0
+    */
+   char theExtSubheaderOverflow[4];
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfUse00aTag.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfUse00aTag.cpp
new file mode 100644
index 0000000000..a5ae87e561
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfUse00aTag.cpp
@@ -0,0 +1,415 @@
+//*******************************************************************
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Walt Bunch
+//
+// Description: Nitf support class for USE00A -
+// Exploitation Usability extension.
+// 
+//********************************************************************
+// $Id: ossimNitfUse00aTag.cpp,v 1.4 2005/08/09 11:32:21 gpotts Exp $
+#include <support_data/nitf/ossimNitfUse00aTag.h>
+
+RTTI_DEF1(ossimNitfUse00aTag, "ossimNitfUse00aTag", ossimNitfRegisteredTag);
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+ossimNitfUse00aTag::ossimNitfUse00aTag()
+{
+   clearFields();
+}
+
+ossimNitfUse00aTag::~ossimNitfUse00aTag()
+{
+}
+
+ossimString ossimNitfUse00aTag::getRegisterTagName()const
+{
+   return "USE00A";
+}
+
+void ossimNitfUse00aTag::parseStream(std::istream& in)
+{
+   clearFields();
+   
+   in.read(theAngleToNorth, ANGLE_TO_NORTH_SIZE);
+   in.read(theMeanGsd, MEAN_GSD_SIZE);
+   in.read(theField3, FIELD3_SIZE);
+   in.read(theDynamicRange, DYNAMIC_RANGE_SIZE);
+   in.read(theField5, FIELD5_SIZE);
+   in.read(theField6, FIELD6_SIZE);
+   in.read(theField7, FIELD7_SIZE);
+   in.read(theOblAng, OBL_ANG_SIZE);
+   in.read(theRollAng, ROLL_ANG_SIZE);
+   in.read(theField10, FIELD10_SIZE);
+   in.read(theField11, FIELD11_SIZE);
+   in.read(theField12, FIELD12_SIZE);
+   in.read(theField13, FIELD13_SIZE);
+   in.read(theField14, FIELD14_SIZE);
+   in.read(theField15, FIELD15_SIZE);
+   in.read(theField16, FIELD16_SIZE);
+   in.read(theNRef, N_REF_SIZE);
+   in.read(theRevNum, REV_NUM_SIZE);
+   in.read(theNSeg, N_SEG_SIZE);
+   in.read(theMaxLpSeg, MAX_LP_SEG_SIZE);
+   in.read(theField20, FIELD20_SIZE);
+   in.read(theField21, FIELD21_SIZE);
+   in.read(theSunEl, SUN_EL_SIZE);
+   in.read(theSunAz, SUN_AZ_SIZE);
+}
+
+void ossimNitfUse00aTag::writeStream(std::ostream& out)
+{
+   out.write(theAngleToNorth, ANGLE_TO_NORTH_SIZE);
+   out.write(theMeanGsd, MEAN_GSD_SIZE);
+   out.write(theField3, FIELD3_SIZE);
+   out.write(theDynamicRange, DYNAMIC_RANGE_SIZE);
+   out.write(theField5, FIELD5_SIZE);
+   out.write(theField6, FIELD6_SIZE);
+   out.write(theField7, FIELD7_SIZE);
+   out.write(theOblAng, OBL_ANG_SIZE);
+   out.write(theRollAng, ROLL_ANG_SIZE);
+   out.write(theField10, FIELD10_SIZE);
+   out.write(theField11, FIELD11_SIZE);
+   out.write(theField12, FIELD12_SIZE);
+   out.write(theField13, FIELD13_SIZE);
+   out.write(theField14, FIELD14_SIZE);
+   out.write(theField15, FIELD15_SIZE);
+   out.write(theField16, FIELD16_SIZE);
+   out.write(theNRef, N_REF_SIZE);
+   out.write(theRevNum, REV_NUM_SIZE);
+   out.write(theNSeg, N_SEG_SIZE);
+   out.write(theMaxLpSeg, MAX_LP_SEG_SIZE);
+   out.write(theField20, FIELD20_SIZE);
+   out.write(theField21, FIELD21_SIZE);
+   out.write(theSunEl, SUN_EL_SIZE);
+   out.write(theSunAz, SUN_AZ_SIZE);
+}
+
+ossim_uint32 ossimNitfUse00aTag::getSizeInBytes()const
+{
+   return 107;
+}
+
+void ossimNitfUse00aTag::clearFields()
+{
+   memset(theAngleToNorth, ' ', ANGLE_TO_NORTH_SIZE);
+   memset(theMeanGsd, ' ', MEAN_GSD_SIZE);
+   memset(theField3, ' ', FIELD3_SIZE);
+   memset(theDynamicRange, ' ', DYNAMIC_RANGE_SIZE);
+   memset(theField5, ' ', FIELD5_SIZE);
+   memset(theField6, ' ', FIELD6_SIZE);
+   memset(theField7, ' ', FIELD7_SIZE);
+   memset(theOblAng, ' ', OBL_ANG_SIZE);
+   memset(theRollAng, ' ', ROLL_ANG_SIZE);
+   memset(theField10, ' ', FIELD10_SIZE);
+   memset(theField11, ' ', FIELD11_SIZE);
+   memset(theField12, ' ', FIELD12_SIZE);
+   memset(theField13, ' ', FIELD13_SIZE);
+   memset(theField14, ' ', FIELD14_SIZE);
+   memset(theField15, ' ', FIELD15_SIZE);
+   memset(theField16, ' ', FIELD16_SIZE);
+   memset(theNRef, ' ', N_REF_SIZE);
+   memset(theRevNum, ' ', REV_NUM_SIZE);
+   memset(theNSeg, ' ', N_SEG_SIZE);
+   memset(theMaxLpSeg, ' ', MAX_LP_SEG_SIZE);
+   memset(theField20, ' ', FIELD20_SIZE);
+   memset(theField21, ' ', FIELD21_SIZE);
+   memset(theSunEl, ' ', SUN_EL_SIZE);
+   memset(theSunAz, ' ', SUN_AZ_SIZE);
+
+   theAngleToNorth[ANGLE_TO_NORTH_SIZE] = '\0';
+   theMeanGsd[MEAN_GSD_SIZE] = '\0';
+   theField3[FIELD3_SIZE] = '\0';
+   theDynamicRange[DYNAMIC_RANGE_SIZE] = '\0';
+   theField5[FIELD5_SIZE] = '\0';
+   theField6[FIELD6_SIZE] = '\0';
+   theField7[FIELD7_SIZE] = '\0';
+   theOblAng[OBL_ANG_SIZE] = '\0';
+   theRollAng[ROLL_ANG_SIZE] = '\0';
+   theField10[FIELD10_SIZE] = '\0';
+   theField11[FIELD11_SIZE] = '\0';
+   theField12[FIELD12_SIZE] = '\0';
+   theField13[FIELD13_SIZE] = '\0';
+   theField14[FIELD14_SIZE] = '\0';
+   theField15[FIELD15_SIZE] = '\0';
+   theField16[FIELD16_SIZE] = '\0';
+   theNRef[N_REF_SIZE] = '\0';
+   theRevNum[REV_NUM_SIZE] = '\0';
+   theNSeg[N_SEG_SIZE] = '\0';
+   theMaxLpSeg[MAX_LP_SEG_SIZE] = '\0';
+   theField20[FIELD20_SIZE] = '\0';
+   theField21[FIELD21_SIZE] = '\0';
+   theSunEl[SUN_EL_SIZE] = '\0';
+   theSunAz[SUN_AZ_SIZE] = '\0';
+}
+
+ossimString ossimNitfUse00aTag::getAngleToNorth()const
+{
+   return theAngleToNorth;
+}
+
+void ossimNitfUse00aTag::setAngleToNorth(ossimString angleToNorth)
+{
+   memset(theAngleToNorth, ' ', ANGLE_TO_NORTH_SIZE);
+   memcpy(theAngleToNorth, angleToNorth.c_str(), MIN(ANGLE_TO_NORTH_SIZE, angleToNorth.length()));
+}
+
+ossimString ossimNitfUse00aTag::getMeanGsd()const
+{
+   return theMeanGsd;
+}
+
+void ossimNitfUse00aTag::setMeanGsd(ossimString meanGsd)
+{
+   memset(theMeanGsd, ' ', MEAN_GSD_SIZE);
+   memcpy(theMeanGsd, meanGsd.c_str(), MIN(MEAN_GSD_SIZE, meanGsd.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField3()const
+{
+   return theField3;
+}
+
+void ossimNitfUse00aTag::setField3(ossimString field3)
+{
+   memset(theField3, ' ', FIELD3_SIZE);
+   memcpy(theField3, field3.c_str(), MIN(FIELD3_SIZE, field3.length()));
+}
+
+ossimString ossimNitfUse00aTag::getDynamicRange()const
+{
+   return theDynamicRange;
+}
+
+void ossimNitfUse00aTag::setDynamicRange(ossimString dynamicRange)
+{
+   memset(theDynamicRange, ' ', DYNAMIC_RANGE_SIZE);
+   memcpy(theDynamicRange, dynamicRange.c_str(), MIN(DYNAMIC_RANGE_SIZE, dynamicRange.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField5()const
+{
+   return theField5;
+}
+
+void ossimNitfUse00aTag::setField5(ossimString field5)
+{
+   memset(theField5, ' ', FIELD5_SIZE);
+   memcpy(theField5, field5.c_str(), MIN(FIELD5_SIZE, field5.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField6()const
+{
+   return theField6;
+}
+
+void ossimNitfUse00aTag::setField6(ossimString field6)
+{
+   memset(theField6, ' ', FIELD6_SIZE);
+   memcpy(theField6, field6.c_str(), MIN(FIELD6_SIZE, field6.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField7()const
+{
+   return theField7;
+}
+
+void ossimNitfUse00aTag::setField7(ossimString field7)
+{
+   memset(theField7, ' ', FIELD7_SIZE);
+   memcpy(theField7, field7.c_str(), MIN(FIELD7_SIZE, field7.length()));
+}
+
+ossimString ossimNitfUse00aTag::getOblAng()const
+{
+   return theOblAng;
+}
+
+void ossimNitfUse00aTag::setOblAng(ossimString oblAng)
+{
+   memset(theOblAng, ' ', OBL_ANG_SIZE);
+   memcpy(theOblAng, oblAng.c_str(), MIN(OBL_ANG_SIZE, oblAng.length()));
+}
+
+ossimString ossimNitfUse00aTag::getRollAng()const
+{
+   return theRollAng;
+}
+
+void ossimNitfUse00aTag::setRollAng(ossimString rollAng)
+{
+   memset(theRollAng, ' ', ROLL_ANG_SIZE);
+   memcpy(theRollAng, rollAng.c_str(), MIN(ROLL_ANG_SIZE, rollAng.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField10()const
+{
+   return theField10;
+}
+
+void ossimNitfUse00aTag::setField10(ossimString field10)
+{
+   memset(theField10, ' ', FIELD10_SIZE);
+   memcpy(theField10, field10.c_str(), MIN(FIELD10_SIZE, field10.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField11()const
+{
+   return theField11;
+}
+
+void ossimNitfUse00aTag::setField11(ossimString field11)
+{
+   memset(theField11, ' ', FIELD11_SIZE);
+   memcpy(theField11, field11.c_str(), MIN(FIELD11_SIZE, field11.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField12()const
+{
+   return theField12;
+}
+
+void ossimNitfUse00aTag::setField12(ossimString field12)
+{
+   memset(theField12, ' ', FIELD12_SIZE);
+   memcpy(theField12, field12.c_str(), MIN(FIELD12_SIZE, field12.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField13()const
+{
+   return theField13;
+}
+
+void ossimNitfUse00aTag::setField13(ossimString field13)
+{
+   memset(theField13, ' ', FIELD13_SIZE);
+   memcpy(theField13, field13.c_str(), MIN(FIELD13_SIZE, field13.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField14()const
+{
+   return theField14;
+}
+
+void ossimNitfUse00aTag::setField14(ossimString field14)
+{
+   memset(theField14, ' ', FIELD14_SIZE);
+   memcpy(theField14, field14.c_str(), MIN(FIELD14_SIZE, field14.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField15()const
+{
+   return theField15;
+}
+
+void ossimNitfUse00aTag::setField15(ossimString field15)
+{
+   memset(theField15, ' ', FIELD15_SIZE);
+   memcpy(theField15, field15.c_str(), MIN(FIELD15_SIZE, field15.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField16()const
+{
+   return theField16;
+}
+
+void ossimNitfUse00aTag::setField16(ossimString field16)
+{
+   memset(theField16, ' ', FIELD16_SIZE);
+   memcpy(theField16, field16.c_str(), MIN(FIELD16_SIZE, field16.length()));
+}
+
+ossimString ossimNitfUse00aTag::getNRef()const
+{
+   return theNRef;
+}
+
+void ossimNitfUse00aTag::setNRef(ossimString nRef)
+{
+   memset(theNRef, ' ', N_REF_SIZE);
+   memcpy(theNRef, nRef.c_str(), MIN(N_REF_SIZE, nRef.length()));
+}
+
+ossimString ossimNitfUse00aTag::getRevNum()const
+{
+   return theRevNum;
+}
+
+void ossimNitfUse00aTag::setRevNum(ossimString revNum)
+{
+   memset(theRevNum, ' ', REV_NUM_SIZE);
+   memcpy(theRevNum, revNum.c_str(), MIN(REV_NUM_SIZE, revNum.length()));
+}
+
+ossimString ossimNitfUse00aTag::getNSeg()const
+{
+   return theNSeg;
+}
+
+void ossimNitfUse00aTag::setNSeg(ossimString nSeg)
+{
+   memset(theNSeg, ' ', N_SEG_SIZE);
+   memcpy(theNSeg, nSeg.c_str(), MIN(N_SEG_SIZE, nSeg.length()));
+}
+
+ossimString ossimNitfUse00aTag::getMaxLpSeg()const
+{
+   return theMaxLpSeg;
+}
+
+void ossimNitfUse00aTag::setMaxLpSeg(ossimString maxLpSeg)
+{
+   memset(theMaxLpSeg, ' ', MAX_LP_SEG_SIZE);
+   memcpy(theMaxLpSeg, maxLpSeg.c_str(), MIN(MAX_LP_SEG_SIZE, maxLpSeg.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField20()const
+{
+   return theField20;
+}
+
+void ossimNitfUse00aTag::setField20(ossimString field20)
+{
+   memset(theField20, ' ', FIELD20_SIZE);
+   memcpy(theField20, field20.c_str(), MIN(FIELD20_SIZE, field20.length()));
+}
+
+ossimString ossimNitfUse00aTag::getField21()const
+{
+   return theField21;
+}
+
+void ossimNitfUse00aTag::setField21(ossimString field21)
+{
+   memset(theField21, ' ', FIELD21_SIZE);
+   memcpy(theField21, field21.c_str(), MIN(FIELD21_SIZE, field21.length()));
+}
+
+ossimString ossimNitfUse00aTag::getSunEl()const
+{
+   return theSunEl;
+}
+
+void ossimNitfUse00aTag::setSunEl(ossimString sunEl)
+{
+   memset(theSunEl, ' ', SUN_EL_SIZE);
+   memcpy(theSunEl, sunEl.c_str(), MIN(SUN_EL_SIZE, sunEl.length()));
+}
+
+ossimString ossimNitfUse00aTag::getSunAz()const
+{
+   return theSunAz;
+}
+
+void ossimNitfUse00aTag::setSunAz(ossimString sunAz)
+{
+   memset(theSunAz, ' ', SUN_AZ_SIZE);
+   memcpy(theSunAz, sunAz.c_str(), MIN(SUN_AZ_SIZE, sunAz.length()));
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfUse00aTag.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfUse00aTag.h
new file mode 100644
index 0000000000..d04634585f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfUse00aTag.h
@@ -0,0 +1,260 @@
+//*******************************************************************
+//
+// LICENSE: LGPL
+//
+// see top level LICENSE.txt
+// 
+// Author: Walt Bunch
+//
+// Description: Nitf support class for USE00A -
+// Exploitation Usability extension.
+// 
+//********************************************************************
+// $Id: ossimNitfUse00aTag.h,v 1.4 2005/08/09 11:32:21 gpotts Exp $
+#ifndef ossimNitfUse00aTag_HEADER
+#define ossimNitfUse00aTag_HEADER
+#include <support_data/nitf/ossimNitfRegisteredTag.h>
+
+class OSSIM_DLL ossimNitfUse00aTag : public ossimNitfRegisteredTag
+{
+public:
+   
+   enum
+   {
+      ANGLE_TO_NORTH_SIZE  = 3,
+      MEAN_GSD_SIZE        = 5,
+      FIELD3_SIZE          = 1,
+      DYNAMIC_RANGE_SIZE   = 5,
+      FIELD5_SIZE          = 3,
+      FIELD6_SIZE          = 1,
+      FIELD7_SIZE          = 3,
+      OBL_ANG_SIZE         = 5,
+      ROLL_ANG_SIZE        = 6,
+      FIELD10_SIZE         = 12,
+      FIELD11_SIZE         = 15,
+      FIELD12_SIZE         = 4,
+      FIELD13_SIZE         = 1,
+      FIELD14_SIZE         = 3,
+      FIELD15_SIZE         = 1,
+      FIELD16_SIZE         = 1,
+      N_REF_SIZE           = 2,
+      REV_NUM_SIZE         = 5,
+      N_SEG_SIZE           = 3,
+      MAX_LP_SEG_SIZE      = 6,
+      FIELD20_SIZE         = 6,
+      FIELD21_SIZE         = 6,
+      SUN_EL_SIZE          = 5,
+      SUN_AZ_SIZE          = 5
+      //                  -----
+      //                  107 bytes
+   };
+   
+   ossimNitfUse00aTag();
+   virtual ~ossimNitfUse00aTag();
+   virtual ossimString getRegisterTagName()const;
+   virtual void parseStream(std::istream& in);
+   virtual void writeStream(std::ostream& out);
+   virtual ossim_uint32 getSizeInBytes()const;
+   virtual void clearFields();
+   
+  // The set methods below taking ossimString args will truncate and
+  // pad with spaces, as necessary, to match enumed size
+   void setAngleToNorth(ossimString angleToNorth);
+   ossimString getAngleToNorth()const;
+   void setMeanGsd(ossimString meanGsd);
+   ossimString getMeanGsd()const;
+   void setField3(ossimString field3);
+   ossimString getField3()const;
+   void setDynamicRange(ossimString dynamicRange);
+   ossimString getDynamicRange()const;
+   void setField5(ossimString field5);
+   ossimString getField5()const;
+   void setField6(ossimString field6);
+   ossimString getField6()const;
+   void setField7(ossimString field7);
+   ossimString getField7()const;
+   void setOblAng(ossimString oblAng);
+   ossimString getOblAng()const;
+   void setRollAng(ossimString rollAng);
+   ossimString getRollAng()const;
+   void setField10(ossimString field10);
+   ossimString getField10()const;
+   void setField11(ossimString field11);
+   ossimString getField11()const;
+   void setField12(ossimString field12);
+   ossimString getField12()const;
+   void setField13(ossimString field13);
+   ossimString getField13()const;
+   void setField14(ossimString field14);
+   ossimString getField14()const;
+   void setField15(ossimString field15);
+   ossimString getField15()const;
+   void setField16(ossimString field16);
+   ossimString getField16()const;
+   void setNRef(ossimString nRef);
+   ossimString getNRef()const;
+   void setRevNum(ossimString revNum);
+   ossimString getRevNum()const;
+   void setNSeg(ossimString nSeg);
+   ossimString getNSeg()const;
+   void setMaxLpSeg(ossimString maxLpSeg);
+   ossimString getMaxLpSeg()const;
+   void setField20(ossimString field20);
+   ossimString getField20()const;
+   void setField21(ossimString field21);
+   ossimString getField21()const;
+   void setSunEl(ossimString sunEl);
+   ossimString getSunEl()const;
+   void setSunAz(ossimString sunAz);
+   ossimString getSunAz()const;
+   
+protected:
+   
+   /**
+    * FIELD: ANGLETONORTH
+    *
+    */
+   char theAngleToNorth[ANGLE_TO_NORTH_SIZE+1];
+   
+   /**
+    * FIELD: MEANGSD
+    *
+    */
+   char theMeanGsd[MEAN_GSD_SIZE+1];
+   
+   /**
+    * FIELD: FIELD3
+    *
+    */
+   char theField3[FIELD3_SIZE+1];
+
+   /**
+    * FIELD: DYNAMICRANGE
+    *
+    */
+   char theDynamicRange[DYNAMIC_RANGE_SIZE+1];
+
+   /**
+    * FIELD: FIELD5
+    *
+    */
+   char theField5[FIELD5_SIZE+1];
+
+   /**
+    * FIELD: FIELD6
+    *
+    */
+   char theField6[FIELD6_SIZE+1];
+
+   /**
+    * FIELD: FIELD7
+    *
+    */
+   char theField7[FIELD7_SIZE+1];
+
+   /**
+    * FIELD: OBLANG
+    *
+    */
+   char theOblAng[OBL_ANG_SIZE+1];
+
+   /**
+    * FIELD: ROLLANG
+    *
+    */
+   char theRollAng[ROLL_ANG_SIZE+1];
+
+   /**
+    * FIELD: FIELD10
+    *
+    */
+   char theField10[FIELD10_SIZE+1];
+
+   /**
+    * FIELD: FIELD11
+    *
+    */
+   char theField11[FIELD11_SIZE+1];
+
+   /**
+    * FIELD: FIELD12
+    *
+    */
+   char theField12[FIELD12_SIZE+1];
+
+   /**
+    * FIELD: FIELD13
+    *
+    */
+   char theField13[FIELD13_SIZE+1];
+
+   /**
+    * FIELD: FIELD14
+    *
+    */
+   char theField14[FIELD14_SIZE+1];
+
+   /**
+    * FIELD: FIELD15
+    *
+    */
+   char theField15[FIELD15_SIZE+1];
+
+   /**
+    * FIELD: FIELD16
+    *
+    */
+   char theField16[FIELD16_SIZE+1];
+
+   /**
+    * FIELD: NREF
+    *
+    */
+   char theNRef[N_REF_SIZE+1];
+
+   /**
+    * FIELD: REVNUM
+    *
+    */
+   char theRevNum[REV_NUM_SIZE+1];
+
+   /**
+    * FIELD: NSEG
+    *
+    */
+   char theNSeg[N_SEG_SIZE+1];
+
+   /**
+    * FIELD: MAXLPSEG
+    *
+    */
+   char theMaxLpSeg[MAX_LP_SEG_SIZE+1];
+
+   /**
+    * FIELD: FIELD20
+    *
+    */
+   char theField20[FIELD20_SIZE+1];
+
+   /**
+    * FIELD: FIELD21
+    *
+    */
+   char theField21[FIELD21_SIZE+1];
+
+   /**
+    * FIELD: SUNEL
+    *
+    */
+   char theSunEl[SUN_EL_SIZE+1];
+
+   /**
+    * FIELD: SUNAZ
+    *
+    */
+   char theSunAz[SUN_AZ_SIZE+1];
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfVqCompressionHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfVqCompressionHeader.cpp
new file mode 100644
index 0000000000..82749236a7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfVqCompressionHeader.cpp
@@ -0,0 +1,267 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts
+//
+// LICENSE: LGPL see top level LICENSE.txt for more details
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfVqCompressionHeader.cpp,v 1.7 2005/10/05 12:50:48 gpotts Exp $
+#include "ossimNitfVqCompressionHeader.h"
+#include <base/misc/ossimEndian.h>
+RTTI_DEF1(ossimNitfVqCompressionHeader, "ossimNitfVqCompressionHeader", ossimNitfCompressionHeader);
+
+ostream& operator<<(ostream& out,
+                    const ossimNitfVqCompressionOffsetTableData& data)
+{
+   out << "theTableId:                              " << data.theTableId << std::endl
+       << "theNumberOfCompressionLookupRecords:     " << data.theNumberOfCompressionLookupRecords << std::endl
+       << "theNumberOfValuesPerCompressionLookup:   " << data.theNumberOfValuesPerCompressionLookup << std::endl
+       << "theCompressionLookupValueBitLength:      " << data.theCompressionLookupValueBitLength<< std::endl
+       << "theCompressionLookupTableOffset:         " << data.theCompressionLookupTableOffset;
+
+   return out;
+}
+
+
+ossimNitfVqCompressionOffsetTableData::ossimNitfVqCompressionOffsetTableData()
+      :theData(NULL)
+{
+   clearFields();
+}
+
+ossimNitfVqCompressionOffsetTableData::ossimNitfVqCompressionOffsetTableData(const ossimNitfVqCompressionOffsetTableData& rhs)
+      :theTableId(rhs.theTableId),
+       theNumberOfCompressionLookupRecords(rhs.theNumberOfCompressionLookupRecords),
+       theNumberOfValuesPerCompressionLookup(rhs.theNumberOfValuesPerCompressionLookup),
+       theCompressionLookupValueBitLength(rhs.theCompressionLookupValueBitLength),
+       theCompressionLookupTableOffset(rhs.theCompressionLookupTableOffset),
+       theData(NULL)
+
+{
+   ossim_uint32 size = (theNumberOfValuesPerCompressionLookup*
+                        theNumberOfCompressionLookupRecords*
+                        theCompressionLookupValueBitLength)/8;
+   if(size > 0)
+   {
+      theData = new unsigned char[size];
+      if(rhs.theData)
+      {
+         memcpy(theData, rhs.theData, size);
+      }
+   }
+}
+
+ossimNitfVqCompressionOffsetTableData::~ossimNitfVqCompressionOffsetTableData()
+{
+   if(theData)
+   {
+      delete [] theData;
+      theData = NULL;
+   }
+}
+
+const ossimNitfVqCompressionOffsetTableData& ossimNitfVqCompressionOffsetTableData::operator =(const ossimNitfVqCompressionOffsetTableData& rhs)
+{
+   if(this != &rhs)
+   {
+      if(theData)
+      {
+         delete [] theData;
+         theData = NULL;
+      }
+
+      theTableId                            = rhs.theTableId;
+      theNumberOfCompressionLookupRecords   = rhs.theNumberOfCompressionLookupRecords;
+      theCompressionLookupValueBitLength    = rhs.theCompressionLookupValueBitLength;
+      theNumberOfValuesPerCompressionLookup = rhs.theNumberOfValuesPerCompressionLookup;
+      theCompressionLookupTableOffset       = rhs.theCompressionLookupTableOffset;
+      
+      if(rhs.theData)
+      {
+         ossim_uint32 size = (theNumberOfValuesPerCompressionLookup*
+                              theNumberOfCompressionLookupRecords*
+                              theCompressionLookupValueBitLength)/8;
+         if(size > 0)
+         {
+            theData = new unsigned char[size];
+            memcpy(theData, rhs.theData, size);
+         }
+      }
+   }
+   
+   return *this;
+   
+}
+ossim_uint32 ossimNitfVqCompressionOffsetTableData::getDataLengthInBytes()const
+{
+   return (theNumberOfValuesPerCompressionLookup*
+           theNumberOfCompressionLookupRecords*
+           theCompressionLookupValueBitLength)/8;
+}
+
+void ossimNitfVqCompressionOffsetTableData::parseStream(std::istream& in)
+{
+   ossimEndian endian;
+   in.read((char*)(&theTableId), 2);
+   in.read((char*)(&theNumberOfCompressionLookupRecords),4);
+   in.read((char*)(&theNumberOfValuesPerCompressionLookup), 2);
+   in.read((char*)(&theCompressionLookupValueBitLength),2);
+   in.read((char*)(&theCompressionLookupTableOffset), 4);
+
+   if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+   {
+      endian.swap(theTableId);
+      endian.swap(theNumberOfCompressionLookupRecords);
+      endian.swap(theNumberOfValuesPerCompressionLookup);
+      endian.swap(theCompressionLookupValueBitLength);
+      endian.swap(theCompressionLookupTableOffset);
+   }
+}
+
+void ossimNitfVqCompressionOffsetTableData::clearFields()
+{
+   theTableId = 0;
+   theNumberOfCompressionLookupRecords = 0;
+   theNumberOfValuesPerCompressionLookup = 0;
+   theCompressionLookupValueBitLength = 0;
+   theCompressionLookupTableOffset = 0;
+
+   if(theData)
+   {
+      delete [] theData;
+      theData = NULL;
+   }
+}
+
+ossimNitfVqCompressionHeader::ossimNitfVqCompressionHeader()
+{
+   clearFields();
+}
+
+void ossimNitfVqCompressionHeader::parseStream(std::istream &in)
+{
+   ossimEndian endian;
+
+   in.read((char*)(&theNumberOfImageRows), 4);
+   in.read((char*)(&theNumberOfImageCodesPerRow), 4);
+   in.read((char*)(&theImageCodeBitLength), 1);
+   in.read((char*)(&theCompressionAlgorithmId), 2);
+
+   in.read((char*)(&theNumberOfCompressionLookupOffsetRecords), 2);
+   in.read((char*)(&theNumberOfCompressionParameterOffsetRecords), 2);
+   in.read((char*)(&theCompressionLookupOffsetTableOffset), 4);
+   in.read((char*)(&theCompressionLookupTableOffsetRecordLength), 2);
+   
+   if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN)
+   {
+      endian.swap(theNumberOfImageRows);
+      endian.swap(theNumberOfImageCodesPerRow);
+      endian.swap(theCompressionAlgorithmId);
+      endian.swap(theNumberOfCompressionLookupOffsetRecords);
+      endian.swap(theNumberOfCompressionParameterOffsetRecords);
+      endian.swap(theCompressionLookupOffsetTableOffset);
+      endian.swap(theCompressionLookupTableOffsetRecordLength);
+   }
+   
+   if((theNumberOfCompressionLookupOffsetRecords > 0)&&
+      (theCompressionAlgorithmId == 1)) 
+   {
+      theTable.clear();
+      theTable.resize(theNumberOfCompressionLookupOffsetRecords);
+
+      ossim_uint32 idx = 0;
+
+      for(idx = 0; idx < theNumberOfCompressionLookupOffsetRecords; ++idx)
+      {
+         theTable[idx].parseStream(in);
+      }
+      for(idx = 0; idx < theTable.size(); ++idx)
+      {
+         if(theTable[idx].theData)
+         {
+            delete [] theTable[idx].theData;
+            theTable[idx].theData = 0;
+         }
+         if(theTable[idx].getDataLengthInBytes()>0)
+         {
+            theTable[idx].theData = new ossim_uint8[theTable[idx].getDataLengthInBytes()];
+            in.read((char*)(theTable[idx].theData), theTable[idx].getDataLengthInBytes());
+         }
+      }
+   }
+}
+
+std::ostream& ossimNitfVqCompressionHeader::print(std::ostream& out) const
+{
+   out << "VQ COMPRESSION HEADER" << std::endl
+       << "theNumberOfImageRows:                           " << theNumberOfImageRows << std::endl
+       << "theNumberOfImageCodesPerRow:                    " << theNumberOfImageCodesPerRow << std::endl
+       << "theImageCodeBitLength:                          " << (ossim_uint32)theImageCodeBitLength << std::endl
+       << "theCompressionAlgorithmId:                      " << theCompressionAlgorithmId << std::endl
+       << "theNumberOfCompressionLookupOffsetRecords:      " << theNumberOfCompressionLookupOffsetRecords << std::endl
+       << "theCompressionLookupTableOffsetRecordLength:    " << theCompressionLookupTableOffsetRecordLength;
+
+   if(theTable.size() > 0)
+   {
+      ossim_uint32 idx = 0;
+      out << std::endl;
+
+      for(idx = 0; idx < theTable.size()-1; ++idx)
+      {
+         out << theTable[idx] << std::endl;
+      }
+      out << theTable[idx];
+   }
+
+   return out;
+}
+
+ossim_uint32 ossimNitfVqCompressionHeader::getBlockSizeInBytes()const
+{
+   return (getNumberOfImageRows()*
+           getNumberOfImageCodesPerRow()*
+           getImageCodeBitLength())/8;
+}
+
+ossim_uint32 ossimNitfVqCompressionHeader::getNumberOfImageRows()const
+{
+   return theNumberOfImageRows;
+}
+
+ossim_uint32 ossimNitfVqCompressionHeader::getNumberOfImageCodesPerRow()const
+{
+   return theNumberOfImageCodesPerRow;
+}
+
+ossim_uint32 ossimNitfVqCompressionHeader::getCompressionAlgorithmId()const
+{
+   return theCompressionAlgorithmId;
+}
+
+ossim_uint32 ossimNitfVqCompressionHeader::getImageCodeBitLength()const
+{
+   return theImageCodeBitLength;
+}
+
+ossim_uint32 ossimNitfVqCompressionHeader::getNumberOfTables()const
+{
+   return theTable.size();
+}
+
+const std::vector<ossimNitfVqCompressionOffsetTableData>& ossimNitfVqCompressionHeader::getTable()const
+{
+   return theTable;
+}
+
+void ossimNitfVqCompressionHeader::clearFields()
+{
+   theNumberOfImageRows                        = 0;
+   theNumberOfImageCodesPerRow                 = 0;
+   theImageCodeBitLength                       = 0;
+   theCompressionAlgorithmId                   = 0;
+   theNumberOfCompressionLookupOffsetRecords   = 0;
+   theCompressionLookupTableOffsetRecordLength = 0;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfVqCompressionHeader.h b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfVqCompressionHeader.h
new file mode 100644
index 0000000000..f5be50407a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/nitf/ossimNitfVqCompressionHeader.h
@@ -0,0 +1,69 @@
+//*******************************************************************
+// Copyright (C) 2004 Garrett Potts
+//
+// LICENSE: LGPL see top level LICENSE.txt for more details
+// 
+// Author: Garrett Potts
+// Description: Nitf support class
+// 
+//********************************************************************
+// $Id: ossimNitfVqCompressionHeader.h,v 1.3 2005/10/17 18:42:27 gpotts Exp $
+#ifndef ossimNitfVqCompressionHeader_HEADER
+#define ossimNitfVqCompressionHeader_HEADER
+#include "ossimNitfCompressionHeader.h"
+
+class OSSIM_DLL ossimNitfVqCompressionOffsetTableData
+{
+public:
+   friend OSSIM_DLL std::ostream& operator<<(std::ostream& out,
+                              const ossimNitfVqCompressionOffsetTableData& data);
+   ossimNitfVqCompressionOffsetTableData();
+   ossimNitfVqCompressionOffsetTableData(const ossimNitfVqCompressionOffsetTableData& rhs);
+   ~ossimNitfVqCompressionOffsetTableData();
+   const ossimNitfVqCompressionOffsetTableData& operator =(const ossimNitfVqCompressionOffsetTableData& rhs);
+   ossim_uint32 getDataLengthInBytes()const;
+   void clearFields();
+   void parseStream(std::istream& in);
+   
+   ossim_uint16 theTableId;
+   ossim_uint32 theNumberOfCompressionLookupRecords;
+   ossim_uint16 theNumberOfValuesPerCompressionLookup;
+   ossim_uint16 theCompressionLookupValueBitLength;
+   ossim_uint32 theCompressionLookupTableOffset;
+   ossim_uint8* theData;
+};
+
+class OSSIM_DLL ossimNitfVqCompressionHeader : public ossimNitfCompressionHeader
+{
+public:
+   ossimNitfVqCompressionHeader();
+   virtual void parseStream(std::istream &in);
+   virtual std::ostream& print(std::ostream& out) const;
+
+   virtual ossim_uint32 getBlockSizeInBytes()const;
+   virtual ossim_uint32 getNumberOfImageRows()const;
+   virtual ossim_uint32 getNumberOfImageCodesPerRow()const;
+   virtual ossim_uint32 getCompressionAlgorithmId()const;
+   virtual ossim_uint32 getImageCodeBitLength()const;
+   virtual ossim_uint32 getNumberOfTables()const;
+   const std::vector<ossimNitfVqCompressionOffsetTableData>& getTable()const;
+   
+protected:
+   ossim_uint32 theNumberOfImageRows;
+   ossim_uint32 theNumberOfImageCodesPerRow;
+   ossim_uint8  theImageCodeBitLength;
+
+   ossim_uint16 theCompressionAlgorithmId;
+   ossim_uint16 theNumberOfCompressionLookupOffsetRecords;
+   ossim_uint16 theNumberOfCompressionParameterOffsetRecords;
+
+   ossim_uint32 theCompressionLookupOffsetTableOffset;
+   ossim_uint16 theCompressionLookupTableOffsetRecordLength;
+
+   std::vector<ossimNitfVqCompressionOffsetTableData> theTable;
+   void clearFields();
+
+TYPE_DATA   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/qb/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/qb/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/qb/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdRpcHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdRpcHeader.cpp
new file mode 100644
index 0000000000..502979d624
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdRpcHeader.cpp
@@ -0,0 +1,246 @@
+//----------------------------------------------------------------------------
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimQuickbirdRpcHeader.cpp,v 1.5 2005/10/28 19:49:05 dburken Exp $
+
+#include <support_data/qb/ossimQuickbirdRpcHeader.h>
+#include <iostream>
+#include <fstream>
+#include <algorithm>
+#include <iterator>
+
+std::ostream& operator << (std::ostream& out,
+		      const ossimQuickbirdRpcHeader& data)
+{
+   out << "theSatId      = " << data.theSatId << std::endl
+       << "theBandId     = " << data.theBandId << std::endl
+       << "theSpecId     = " << data.theSpecId << std::endl
+       << "theErrBias    = " << data.theErrBias << std::endl
+       << "theLineOffset = " << data.theLineOffset << std::endl
+       << "theSampOffset = " << data.theSampOffset << std::endl
+       << "theLatOffset  = " << data.theLatOffset << std::endl
+       << "theLonOffset  = " << data.theLonOffset << std::endl
+       << "theHeightOffset  = " << data.theHeightOffset << std::endl
+       << "theLineScale  = " << data.theLineScale << std::endl
+       << "theSampScale  = " << data.theSampScale << std::endl
+       << "theLatScale  = " << data.theLatScale << std::endl
+       << "theLonScale  = " << data.theLonScale << std::endl
+       << "theHeightScale  = " << data.theHeightScale << std::endl;
+   
+   out << "lineNumCoef = " << std::endl;
+   std::copy(data.theLineNumCoeff.begin(),
+             data.theLineNumCoeff.end(),
+             std::ostream_iterator<double>(out, "\n"));
+   out << "lineDenCoef = " << std::endl;
+   std::copy(data.theLineDenCoeff.begin(),
+             data.theLineDenCoeff.end(),
+             std::ostream_iterator<double>(out, "\n"));
+   out << "sampNumCoef = " << std::endl;
+   std::copy(data.theSampNumCoeff.begin(),
+             data.theSampNumCoeff.end(),
+             std::ostream_iterator<double>(out, "\n"));
+   out << "sampDenCoef = " << std::endl;
+   std::copy(data.theSampDenCoeff.begin(),
+             data.theSampDenCoeff.end(),
+             std::ostream_iterator<double>(out, "\n"));
+   
+   return out;
+}
+
+
+ossimQuickbirdRpcHeader::ossimQuickbirdRpcHeader()
+{
+}
+
+bool ossimQuickbirdRpcHeader::open(const ossimFilename& file)
+{
+   theFilename = file;
+   std::ifstream in(file.c_str(), std::ios::in|std::ios::binary);
+   
+   char test[64];
+   
+   in.read((char*)test, 63);
+   test[63] = '\0';
+   in.seekg(0);
+   ossimString line = test;
+   line = line.upcase();
+   
+   if(parseNameValue(line))
+   {
+      theErrorStatus = ossimErrorCodes::OSSIM_OK;
+      getline(in,
+              line);
+      while((in)&&(theErrorStatus == ossimErrorCodes::OSSIM_OK))
+      {
+         line = line.upcase();
+         if(line.contains("LINENUMCOEF"))
+         {
+            if(!readCoeff(in, theLineNumCoeff))
+            {
+               setErrorStatus();
+               break;
+            }
+         }
+         else if(line.contains("LINEDENCOEF"))
+         {
+            if(!readCoeff(in, theLineDenCoeff))
+            {
+               setErrorStatus();
+               break;
+            }
+         }
+         else if(line.contains("SAMPNUMCOEF"))
+         {
+            if(!readCoeff(in, theSampNumCoeff))
+            {
+               setErrorStatus();
+               break;
+            }
+         }
+         else if(line.contains("SAMPDENCOEF"))
+         {
+            if(!readCoeff(in, theSampDenCoeff))
+            {
+               setErrorStatus();
+               break;
+            }
+         }
+         else if(!parseNameValue(line))
+         {
+            setErrorStatus();
+            break;
+         }
+         getline(in,
+                 line);
+      }
+   }
+   else
+   {
+      setErrorStatus();
+   }
+   return (theErrorStatus == ossimErrorCodes::OSSIM_OK);
+}
+
+bool ossimQuickbirdRpcHeader::readCoeff(std::istream& in,
+					std::vector<double>& coeff)
+{
+   coeff.clear();
+   bool done = false;
+   ossimString line;
+   while(!in.eof()&&!in.bad()&&!done)
+   {
+      getline(in,
+	      line);
+      line.trim();
+      line.trim(',');
+      if(line.contains(");"))
+      {
+         done = true;
+         line.trim(';');
+         line.trim(')');
+      }
+      coeff.push_back(line.toDouble());
+   }
+   return done;
+}
+
+bool ossimQuickbirdRpcHeader::parseNameValue(const ossimString& line)
+{
+   bool result = true;
+   ossimString lineCopy = line;
+   
+   if(lineCopy.contains("SATID"))
+   {
+      theSatId = lineCopy.after("\"");
+      theSatId = theSatId.before("\"");
+   }
+   else if(lineCopy.contains("BANDID"))
+   {
+      theBandId = lineCopy.after("\"");
+      theBandId = theBandId.before("\"");
+   }
+   else if(lineCopy.contains("SPECID"))
+   {
+      theSpecId = lineCopy.after("\"");
+      theSpecId = theSpecId.before("\"");
+   }
+   else if(lineCopy.contains("BEGIN_GROUP"))
+   {
+   }
+   else if(lineCopy.contains("ERRBIAS"))
+   {
+      lineCopy = lineCopy.after("=");
+      theErrBias = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("ERRRAND"))
+   {
+      lineCopy = lineCopy.after("=");
+      theErrRand = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("LINEOFFSET"))
+   {
+      lineCopy = lineCopy.after("=");
+      theLineOffset = lineCopy.before(";").toInt();
+   }
+   else if(lineCopy.contains("SAMPOFFSET"))
+   {
+      lineCopy = lineCopy.after("=");
+      theSampOffset = lineCopy.before(";").toInt();
+   }
+   else if(lineCopy.contains("LATOFFSET"))
+   {
+      lineCopy = lineCopy.after("=");
+      theLatOffset = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("LONGOFFSET"))
+   {
+      lineCopy = lineCopy.after("=");
+      theLonOffset = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("HEIGHTOFFSET"))
+   {
+      lineCopy = lineCopy.after("=");
+      theHeightOffset = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("LINESCALE"))
+   {
+      lineCopy = lineCopy.after("=");
+      theLineScale = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("SAMPSCALE"))
+   {
+      lineCopy = lineCopy.after("=");
+      theSampScale = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("LATSCALE"))
+   {
+      lineCopy = lineCopy.after("=");
+      theLatScale = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("LONGSCALE"))
+   {
+      lineCopy = lineCopy.after("=");
+      theLonScale = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("HEIGHTSCALE"))
+   {
+      lineCopy = lineCopy.after("=");
+      theHeightScale = lineCopy.before(";").toDouble();
+   }
+   else if(lineCopy.contains("END_GROUP"))
+   {
+   }
+   else if(lineCopy.contains("END"))
+   {
+   }
+   else
+   {
+      result = false;
+   }
+
+   return result;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdRpcHeader.h b/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdRpcHeader.h
new file mode 100644
index 0000000000..2d3ff64de1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdRpcHeader.h
@@ -0,0 +1,55 @@
+#ifndef ossimQuickbirdRpcHeader_HEADER
+#define ossimQuickbirdRpcHeader_HEADER
+#include <iostream>
+
+#include "base/common/ossimErrorStatusInterface.h"
+
+#include "base/data_types/ossimFilename.h"
+class OSSIM_DLL ossimQuickbirdRpcHeader : public ossimErrorStatusInterface
+{
+public:
+  friend OSSIM_DLL std::ostream& operator << (std::ostream& out,
+			       const ossimQuickbirdRpcHeader& data);
+  ossimQuickbirdRpcHeader();
+
+  bool open(const ossimFilename& file);
+
+  bool isAPolynomial()const
+  {
+    return theSpecId.contains("A");
+  }
+  bool isBPolynomial()const
+  {
+    return theSpecId.contains("B");
+  }
+  ossimString theFilename;
+
+  ossimString theSatId;
+  ossimString theBandId;
+  ossimString theSpecId;
+  double    theErrBias;
+  double    theErrRand;
+  ossim_int32 theLineOffset;
+  ossim_int32 theSampOffset;
+  double    theLatOffset;
+  double    theLonOffset;
+  double    theHeightOffset;
+  double    theLineScale;
+  double    theSampScale;
+  double    theLatScale;
+  double    theLonScale;
+  double    theHeightScale;
+ 
+  std::vector<double> theLineNumCoeff;
+  std::vector<double> theLineDenCoeff;
+  std::vector<double> theSampNumCoeff;
+  std::vector<double> theSampDenCoeff;
+
+
+  bool readCoeff(std::istream& in,
+		 std::vector<double>& coeff);
+  bool parseNameValue(const ossimString& line);
+		     
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdTile.cpp b/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdTile.cpp
new file mode 100644
index 0000000000..6e773d9859
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdTile.cpp
@@ -0,0 +1,365 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Garrett Potts
+//
+//*******************************************************************
+//  $Id: ossimQuickbirdTile.cpp,v 1.7 2005/11/20 19:47:46 dburken Exp $
+
+#include <support_data/qb/ossimQuickbirdTile.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+
+static const ossimTrace traceDebug(ossimString("ossimQuickbirdTile:debug"));
+
+ossimQuickbirdTile::ossimQuickbirdTile()
+{
+}
+
+bool ossimQuickbirdTile::open(const ossimFilename tileFile)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimQuickbirdTile::open entered:"
+         << "\ntileFile:  " << tileFile
+         << std::endl;
+   }
+   
+   std::ifstream in(tileFile, std::ios::in|std::ios::binary);
+
+   if(!in)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Could not open!"
+            << std::endl;
+      }
+      return false;
+   }
+
+   char testBuf[512];
+   in.read((char*)testBuf, 50);
+   testBuf[511] = '\0';
+   ossimString testString =  testBuf;
+   testString = testString.upcase();
+   if(testString.contains("BEGIN_GROUP")||
+      testString.contains("BANDID"))
+   {
+      in.seekg(0);
+      ossimString line;
+      ossimString name;
+      ossimString value;
+      std::getline(in,
+                   line);
+
+      while(!in.eof()&&!in.bad()&&(in.good())&&
+            (theErrorStatus==ossimErrorCodes::OSSIM_OK))
+      {
+         parseNameValue(name,
+                        value,
+                        line);
+
+         name = name.upcase();
+         name = name.trim();
+         if(name == "BEGIN_GROUP")
+         {
+            parseTileGroup(in, value);
+         }
+         else if(name == "BANDID")
+         {
+            theBandId = value.after("\"").before("\"");
+         }
+         else if(name == "NUMTILES")
+         {
+            theNumberOfTiles = value.before(";").toInt32();
+         }
+         else if(name == "TILESIZE")
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "Key " << name << " not parsed!"
+                  << std::endl;
+            }
+         }
+         else if(name == "TILEOVERLAP")
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "Key " << name << " not parsed!"
+                  << std::endl;
+            }
+         }
+         else if(name == "TILEUNITS")
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "Key " << name << " not parsed!"
+                  << std::endl;
+            }
+         }
+         else if (name == "END;")
+         {
+            break;
+         }
+         else
+         {
+            if (traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "key " << name << " not parsed! Exiting with error..."
+                  << std::endl;
+            }
+            setErrorStatus();
+         }
+         std::getline(in, line);
+      }
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimQuickbirdTile::open return value:"
+         << ((theErrorStatus == ossimErrorCodes::OSSIM_OK)?"true":"false")
+         << std::endl;
+   }
+   
+   return (theErrorStatus == ossimErrorCodes::OSSIM_OK);
+}
+
+void ossimQuickbirdTile::parseTileGroup(std::istream& in,
+                                        const ossimString& tileName)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimQuickbirdTile::parseTileGroup entered:"
+         << std::endl;
+   }
+   
+   ossimQuickbirdTileInfo info;
+   ossimString line;
+   ossimString name;
+   ossimString value;
+   info.theTileGroup = tileName;
+   while(!in.eof()&&!in.bad()&&
+         (theErrorStatus==ossimErrorCodes::OSSIM_OK)&&
+         (name != "END_GROUP"))
+   {
+      line = "";
+      std::getline(in,
+                   line);
+
+      parseNameValue(name, value, line);
+      name = name.upcase();
+
+      if(name == "FILENAME")
+      {
+         ossimString filename = value.after("\"").before("\"");
+         
+         info.theFilename = filename.upcase();
+      }
+      else if(name == "COLOFFSET")
+      {
+         info.theUlXOffset = value.before(";").toInt32();
+      }
+      else if(name == "ROWOFFSET")
+      {
+         info.theUlYOffset = value.before(";").toInt32();
+      }
+      else if(name == "ULCOLOFFSET")
+      {
+         info.theUlXOffset = value.before(";").toInt32();
+      }
+      else if(name == "ULROWOFFSET")
+      {
+         info.theUlYOffset = value.before(";").toInt32();
+      }
+      else if(name == "URCOLOFFSET")
+      {
+         info.theUrXOffset = value.before(";").toInt32();
+      }
+      else if(name == "URROWOFFSET")
+      {
+         info.theUrYOffset = value.before(";").toInt32();
+      }
+      else if(name == "LRCOLOFFSET")
+      {
+         info.theLrXOffset = value.before(";").toInt32();
+      }
+      else if(name == "LRROWOFFSET")
+      {
+         info.theLrYOffset = value.before(";").toInt32();
+      }
+      else if(name == "LLCOLOFFSET")
+      {
+         info.theLlXOffset = value.before(";").toInt32();
+      }
+      else if(name == "LLROWOFFSET")
+      {
+         info.theLlYOffset = value.before(";").toInt32();
+      }
+      else if(name == "ULLON")
+      {
+         info.theUlLon = value.before(";").toDouble();
+      }
+      else if(name == "ULLAT")
+      {
+         info.theUlLat = value.before(";").toDouble();
+      }
+      else if(name == "URLON")
+      {
+         info.theUrLon = value.before(";").toDouble();
+      }
+      else if(name == "URLAT")
+      {
+         info.theUrLat = value.before(";").toDouble();
+      }
+      else if(name == "LRLON")
+      {
+         info.theLrLon = value.before(";").toDouble();
+      }
+      else if(name == "LRLAT")
+      {
+         info.theLrLat = value.before(";").toDouble();
+      }
+      else if(name == "LLLON")
+      {
+         info.theLlLon = value.before(";").toDouble();
+      }
+      else if(name == "LLLAT")
+      {
+         info.theLlLat = value.before(";").toDouble();
+      }
+      else if(name == "END_GROUP")
+      {
+         break;
+      }
+      else if (name == "ULX")
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "key " << name << " not parsed!"
+               << std::endl;
+         }
+      }
+      else if (name == "ULY")
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "key " << name << " not parsed!"
+               << std::endl;
+         }
+      }
+      else if (name == "URX")
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "key " << name << " not parsed!"
+               << std::endl;
+         }
+      }
+      else if (name == "URY")
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "key " << name << " not parsed!"
+               << std::endl;
+         }
+      }
+      else if (name == "LRX")
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "key " << name << " not parsed!"
+               << std::endl;
+         }
+      }
+      else if (name == "LRY")
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "key " << name << " not parsed!"
+               << std::endl;
+         }
+      }
+      else if (name == "LLX")
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "key " << name << " not parsed!"
+               << std::endl;
+         }
+      }
+      else if (name == "LLY")
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "key " << name << " not parsed!"
+               << std::endl;
+         }
+      }
+      else if(name == "END;")
+      {
+         break;
+      }
+      else
+      {
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "key " << name << " not parsed! Exiting with error..."
+               << std::endl;
+         }
+
+         setErrorStatus();
+         break;
+      }
+   }
+   
+   if(theErrorStatus == ossimErrorCodes::OSSIM_OK)
+   {
+      theTileMap.insert(make_pair(info.theFilename,
+                                  info));
+   }
+}
+
+void ossimQuickbirdTile::parseNameValue(ossimString& name,
+                                        ossimString& value,
+                                        const ossimString& line)const
+{
+   name  = ossimString(line).before("=");
+   name  = name.trim();
+   value = ossimString(line).after("=");
+   value = value.trim();
+}
+
+bool ossimQuickbirdTile::getInfo(ossimQuickbirdTileInfo& result,
+                                 const ossimFilename& filename)const
+{
+   std::map<ossimString,ossimQuickbirdTileInfo>::const_iterator iter =  theTileMap.find(filename);
+
+   if(iter != theTileMap.end())
+   {
+      result = (*iter).second;
+      return true;
+   }
+
+   return false;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdTile.h b/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdTile.h
new file mode 100644
index 0000000000..4fa744b3e5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/qb/ossimQuickbirdTile.h
@@ -0,0 +1,135 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author:  Garrett Potts (gpotts@imagelinks.com)
+//
+// Description:
+//
+//*******************************************************************
+//  $Id: ossimQuickbirdTile.h,v 1.3 2004/05/06 17:56:21 gpotts Exp $
+#ifndef ossimQuickbirdTil_HEADER
+#define ossimQuickbirdTil_HEADER
+#include <map>
+#include <fstream>
+#include "base/common/ossimErrorStatusInterface.h"
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimFilename.h"
+
+class ossimQuickbirdTileInfo
+{
+public:
+   friend std::ostream& operator << (std::ostream& out, const ossimQuickbirdTileInfo& rhs)
+      {
+		return out;
+      }
+   bool operator ==(const ossimString& rhs)const
+      {
+         return theFilename == rhs;
+      }
+   bool operator <(const ossimString& rhs)const
+      {
+         return theFilename < rhs;
+      }
+   bool operator >(const ossimString& rhs)const
+      {
+         return theFilename > rhs;
+      }
+   bool operator ==(const ossimQuickbirdTileInfo& rhs)const
+      {
+         return theFilename == rhs.theFilename;
+      }
+   bool operator <(const ossimQuickbirdTileInfo& rhs)const
+      {
+         return theFilename < rhs.theFilename;
+      }
+   bool operator >(const ossimQuickbirdTileInfo& rhs)const
+      {
+         return theFilename > rhs.theFilename;
+      }
+
+   ossimQuickbirdTileInfo()
+      {
+         initialize();
+      }
+   
+   void initialize()
+      {
+         theTileGroup = "";
+         theFilename  = "";
+         theUlXOffset = OSSIM_INT_NAN;
+         theUlYOffset = OSSIM_INT_NAN;
+         theUrXOffset = OSSIM_INT_NAN;
+         theUrYOffset = OSSIM_INT_NAN;
+         theLrXOffset = OSSIM_INT_NAN;
+         theLrYOffset = OSSIM_INT_NAN;
+         theLlXOffset = OSSIM_INT_NAN;
+         theLlYOffset = OSSIM_INT_NAN;
+
+         theUlLon     = OSSIM_DBL_NAN;
+         theUlLat     = OSSIM_DBL_NAN;
+         theUrLon     = OSSIM_DBL_NAN;
+         theUrLat     = OSSIM_DBL_NAN;
+         theLrLon     = OSSIM_DBL_NAN;
+         theLrLat     = OSSIM_DBL_NAN;
+         theLlLon     = OSSIM_DBL_NAN;
+         theLlLat     = OSSIM_DBL_NAN;
+      }
+   ossimString    theTileGroup;
+   ossimFilename  theFilename;
+   ossim_int32    theUlXOffset;
+   ossim_int32    theUlYOffset;
+   ossim_int32    theUrXOffset;
+   ossim_int32    theUrYOffset;
+   ossim_int32    theLrXOffset;
+   ossim_int32    theLrYOffset;
+   ossim_int32    theLlXOffset;
+   ossim_int32    theLlYOffset;
+   ossim_float64  theUlLon;
+   ossim_float64  theUlLat;
+   ossim_float64  theUrLon;
+   ossim_float64  theUrLat;
+   ossim_float64  theLrLon;
+   ossim_float64  theLrLat;
+   ossim_float64  theLlLon;
+   ossim_float64  theLlLat;
+};
+
+class ossimQuickbirdTile : public ossimErrorStatusInterface
+{
+public:
+   ossimQuickbirdTile();
+   bool open(const ossimFilename tileFile);
+
+   bool getInfo(ossimQuickbirdTileInfo& result,
+                const ossimFilename& filename)const;
+   
+protected:
+   std::map<ossimString, ossimQuickbirdTileInfo> theTileMap;
+   ossim_int32 theNumberOfTiles;
+   ossimString theBandId;
+   
+   void parseTileGroup(std::istream& in,
+                       const ossimString& tileName);
+   void parseNameValue(ossimString& name,
+                       ossimString& value,
+                       const ossimString& line)const;
+
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/rpf/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeOffsetRecord.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeOffsetRecord.cpp
new file mode 100644
index 0000000000..97f1cb81c9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeOffsetRecord.cpp
@@ -0,0 +1,58 @@
+#include "ossimRpfAttributeOffsetRecord.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfAttributeOffsetRecord& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfAttributeOffsetRecord::ossimRpfAttributeOffsetRecord()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfAttributeOffsetRecord::parseStream(istream& in,
+                                                          ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      in.read((char*)&theAttributeId, 2);
+      in.read((char*)&theParameterId, 1);
+      in.read((char*)&theArealCoverageSequenceNumber, 1);
+      in.read((char*)&theAttributeRecordOffset, 4);
+
+      ossimEndian anEndian;
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theAttributeId);
+         anEndian.swap(theAttributeRecordOffset);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfAttributeOffsetRecord::print(ostream& out)const
+{
+   out << "theAttributeId:                  " << theAttributeId << endl
+       << "theParameterId:                  " << theParameterId << endl
+       << "theArealCoverageSequenceNumber:  " << theArealCoverageSequenceNumber << endl
+       << "theAttributeRecordOffset:        " << theAttributeRecordOffset;
+}
+
+void ossimRpfAttributeOffsetRecord::clearFields()
+{
+   theAttributeId                 = 0;
+   theParameterId                 = 0;
+   theArealCoverageSequenceNumber = 0;
+   theAttributeRecordOffset       = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeOffsetRecord.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeOffsetRecord.h
new file mode 100644
index 0000000000..98a020dd91
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeOffsetRecord.h
@@ -0,0 +1,275 @@
+#ifndef ossimRpfAttributeOffsetRecord_HEADER
+#define ossimRpfAttributeOffsetRecord_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h"     // for the RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimRpfAttributeOffsetRecord
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfAttributeOffsetRecord& data);
+
+   ossimRpfAttributeOffsetRecord();
+   virtual ~ossimRpfAttributeOffsetRecord(){}
+
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   void print(ostream& out)const;
+   ossim_uint16  getAttributeId()const{return theAttributeId;}
+   ossim_uint8   getParamterId()const{return theParameterId;}
+   ossim_uint32  getAttributeRecordOffset()const{return theAttributeRecordOffset;}
+   
+private:
+   void clearFields();
+   /*!
+    * The attribute Id.  The Id and descriptions are taken from
+    * MIL-STD-2411-1 and can have one of the following values:
+    *
+    * ID     Description
+    * _________________________________________________________________
+    * 1      Currency Date, 1 parameter:
+    *          1. Date of most recent revision to the RPF
+    *             YYYYMMDD
+    *             8 byte ascii value
+    *
+    * 2      Production Date, 1 parameter:
+    *          1. Date the source data was transformed to RPF format
+    *             YYYYMMDD
+    *             8 byte ascii value
+    *  
+    * 3      Significant Date, 1 parameter:
+    *          1. Most accurately describes the date of
+    *             the source data.
+    *             YYYYMMDD
+    *             8 byte ascii value
+    *
+    * 4      Map/Chart source, 4 parameters:
+    *          1. Short title for the id of a group of
+    *             products.  ex: JOG 1501A ...
+    *             10 byte ascii value
+    *          2. The designation of the hardcopy source
+    *             8 byte ascii value
+    *          3. Old horizontal datum code.  Original
+    *             horizontal datum of the hardcopy product
+    *             4 byte ascii value
+    *          4. Edition number of the source graphic
+    *             7 byte ascii value.
+    *
+    * 5      Projection Systemd, 5 parameters: p. 38 of MIL-STD-2411-1
+    *          1. Projection Code. 2 byte ascii value
+    *             AC    Albers Equal area
+    *                   Requires Parameters A B C D
+    *             AL    Azimuthal Equal Dist.
+    *                   Requires Parameters A B
+    *             RB    Hotline Oblique Mercator
+    *                   Requires Parameters A B C 
+    *             LE    Lambert Conformal Conic
+    *                   Requires Parameters A B C D
+    *             MC    Mercator
+    *                   Requires Parameters A B
+    *             OC    Oblique Mercator
+    *                   Requires Parameters A B C
+    *             OD    Orthographic
+    *                   Requires Parameters A B
+    *             PG    Polar Stereo-graphic
+    *                   Requires Parameters A B C D
+    *             PH    Poly conic
+    *                   Requires Parameters A B
+    *             TC    Transverse Mercator
+    *                   Requires Parameters A B C
+    *             UT    Universal Transverse Mercator
+    *                   Requires Parameters A
+    *          2. Projection Param A: real 4 byte value
+    *          3. Projeciton Param B: real 4 byte value
+    *          4. Projection Param C: real 4 byte value
+    *          5. Projection Param D: real 4 byte value
+    * 6      Vertical Datum (1 parameter) p. 37 MIL-STD-2411-1
+    *         4 byte ascii
+    *
+    *          MSL     Mean Sea Level.  All elevations in th data set
+    *                  are referenced to the geoid of the specified datum
+    *          GEOD    Geodetic (All elevations in the data set
+    *                  are referenced to the ellipsoid of the specified
+    *                  datum
+    * 7      Horizontal Datum (1 parameter)
+    *        4 byte ascii
+    *
+    *            Look on p.33 of MIL-STD-2411-1.  Too big to list
+    *            we will need a translation table for these
+    *            codes
+    * 8      Vertical Absolute Accurracy (2 parameters)
+    *        1. vertical absolute accuracy: 4 byte unsigned int
+    *        2. Accuracy units of measure:  2 byte value 
+    *             0   unknown
+    *             1   meters (Length area Volume)
+    *             2   Kilopounds
+    *             3   Seconds (of time)
+    *             4   Meters/Second (speed)
+    *             5   Cubic Meters per second (Flow)
+    *             6   Volt (Electrical potential)
+    *             7   Watt (Ten to 6 electirical power)
+    *             8   Hertz
+    *             9   +- DD MM SS.S (Angular)
+    *             10  +- HH MM SS.S (Time)
+    *             11  International Nautical Mile (1852 meters)
+    *             12  knot
+    *             13  Nautical mile per day
+    *             14  Feet
+    *             15  Fathom
+    *             16  Micrometers (microns)
+    *             17  Mils
+    *             18  Seconds of Arc
+    *             19  Minutes of Arc
+    *             20  Degrees of arc
+    *             999 Other
+    *
+    * 9      Horizontal Absolute Accuracy (2 parameters)
+    *        1. Horizontal absolute accuracy: 4 byte unsigned int
+    *        2. Accuracy units of measure:  2 byte value 
+    *             0   unknown
+    *             1   meters (Length area Volume)
+    *             2   Kilopounds
+    *             3   Seconds (of time)
+    *             4   Meters/Second (speed)
+    *             5   Cubic Meters per second (Flow)
+    *             6   Volt (Electrical potential)
+    *             7   Watt (Ten to 6 electirical power)
+    *             8   Hertz
+    *             9   +- DD MM SS.S (Angular)
+    *             10  +- HH MM SS.S (Time)
+    *             11  International Nautical Mile (1852 meters)
+    *             12  knot
+    *             13  Nautical mile per day
+    *             14  Feet
+    *             15  Fathom
+    *             16  Micrometers (microns)
+    *             17  Mils
+    *             18  Seconds of Arc
+    *             19  Minutes of Arc
+    *             20  Degrees of arc
+    *             999 Other
+    *
+    * 10     Vertical Relative Accuracy (2 parameters)
+    *        1. Vertical relative accuracy: 4 byte unsigned int
+    *        2. Accuracy units of measure:  2 byte value 
+    *             0   unknown
+    *             1   meters (Length area Volume)
+    *             2   Kilopounds
+    *             3   Seconds (of time)
+    *             4   Meters/Second (speed)
+    *             5   Cubic Meters per second (Flow)
+    *             6   Volt (Electrical potential)
+    *             7   Watt (Ten to 6 electirical power)
+    *             8   Hertz
+    *             9   +- DD MM SS.S (Angular)
+    *             10  +- HH MM SS.S (Time)
+    *             11  International Nautical Mile (1852 meters)
+    *             12  knot
+    *             13  Nautical mile per day
+    *             14  Feet
+    *             15  Fathom
+    *             16  Micrometers (microns)
+    *             17  Mils
+    *             18  Seconds of Arc
+    *             19  Minutes of Arc
+    *             20  Degrees of arc
+    *             999 Other
+    *
+    * 11     Horizontal Relative Accuracy (2 parameters)
+    *        1. Horizontal relative accuracy: 4 byte unsigned int
+    *        2. Accuracy units of measure:  2 byte value 
+    *             0   unknown
+    *             1   meters (Length area Volume)
+    *             2   Kilopounds
+    *             3   Seconds (of time)
+    *             4   Meters/Second (speed)
+    *             5   Cubic Meters per second (Flow)
+    *             6   Volt (Electrical potential)
+    *             7   Watt (Ten to 6 electirical power)
+    *             8   Hertz
+    *             9   +- DD MM SS.S (Angular)
+    *             10  +- HH MM SS.S (Time)
+    *             11  International Nautical Mile (1852 meters)
+    *             12  knot
+    *             13  Nautical mile per day
+    *             14  Feet
+    *             15  Fathom
+    *             16  Micrometers (microns)
+    *             17  Mils
+    *             18  Seconds of Arc
+    *             19  Minutes of Arc
+    *             20  Degrees of arc
+    *             999 Other
+    *
+    * 12     Ellipsoid, 1 parameter:
+    *        1. Ellipsoid code.  3 byte ascii
+    *           See p. 40 of MIL-STD-2411-1
+    * 13     Sounding Datumm, 1 parameter: 4 byte ascii
+    *        See p. 33 MIL-STD-2411-1 5.3.2.2
+    * 14     Navigation System, 1 parameter: 
+    *        1. Navigation code. 2 byte unsigned int
+    *           See MIL-STD-2411-1 5.3.2.4
+    * 15     Grid, 1 parameter:
+    *        1. Grid code. 2 byte ascii
+    *           See MIL-STD-2411-1 5.3.2.7
+    * 16     Easterly Annual Magnetic Change, 2 parameters:
+    *        1. Easterly annual magnetic change. 4 byte real
+    *        2. Units of the change.  See 5.3.2.6 of MIL-STD-2411-1
+    * 17     Westerly Annual Magnetic Change, 2 parameters:
+    *        1. Westerly annual magnetic change. 4 byte real
+    *        2. Units of the change.  See 5.3.2.6 of MIL-STD-2411-1
+    * 18     Grid North Magnetic North ANgle, 2 paramters:
+    *        1. Grid North - Magnetic North.  4 byte real
+    *        2. Units of angle. 2 byte unsigned int
+    *           see 5.3.2.6
+    * 19     Grid convergence angle, 2 parameters:
+    *        1. Grid convergence angle.  4 byte Real
+    *        2. Units of angle. 2 byte unsigned int 5.3.2.6
+    * 20     Highest known elevation (4 parameters)
+    *        1. Highest known elevation: 8 byte real
+    *        2. Units of elevation: See 5.3.2.6 of MIL-STD-2411-1
+    *        3. Lat of elevation: 8 byte real in decimal degrees
+    *        4. Lon of elevation: 8 byte real in decimal degrees
+    * 21     Multiple legend, 1 paraemter:
+    *        1. Name of legend file that applies to this
+    *           12 byte ascii
+    * 22     Image source, 2 parameters:
+    *        1. Source of data from which this
+    *           RPF was derived. ex: SPOT. Landsat7, Landsat4.
+    *           for CDTED: "imagery, "carto"
+    *           12 byte ascii
+    *        2. GSD.  Ground sample or post distance.
+    *           4 byte unsigned int
+    * 23     Data Level, 1 parameter:
+    *        1. The level of the source.  For example:
+    *           if this is a DTED or CDTED it would
+    *           distinguish between level 1 and 2
+    */
+   ossim_uint16 theAttributeId;
+
+   /*!
+    * This defines which parameter number for theAttrributeId
+    */
+   ossim_uint8  theParameterId;
+
+   /*!
+    * This is a 1 byte field.  If the value is 0 then
+    * the attribute applies to the entire geographic coverage
+    * of this frame.  If it's > 0 then the areal coverage
+    * where the given attribute applies is defined in the corresponding
+    * explicit areal coverage record in the explicit areal
+    * coverage table.
+    */
+    ossim_uint8 theArealCoverageSequenceNumber;
+
+   /*!
+    * a 4-byte unsigned integer.  displacement in bytes measured
+    * from the beginning of the [attribute subsection] and the first
+    * byte of the [attribute record].
+    */
+   ossim_uint32 theAttributeRecordOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeSectionSubheader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeSectionSubheader.cpp
new file mode 100644
index 0000000000..0164a5b828
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeSectionSubheader.cpp
@@ -0,0 +1,99 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfAttributeSectionSubheader.cpp,v 1.3 2005/08/22 14:58:35 gpotts Exp $
+#include "ossimRpfAttributeSectionSubheader.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfAttributeSectionSubheader& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfAttributeSectionSubheader::ossimRpfAttributeSectionSubheader()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfAttributeSectionSubheader::parseStream(istream& in,
+                                                              ossimByteOrder byteOrder)
+{
+   theAttributeSectionSubheaderStart = 0;
+   theAttributeSectionSubheaderEnd = 0;
+   if(in)
+   {
+      theAttributeSectionSubheaderStart = in.tellg();
+      in.read((char*)&theNumberOfAttributeOffsetRecords, 2);
+      in.read((char*)&theNumberOfExplicitArealCoverageRecords, 2);
+      in.read((char*)&theAttributeOffsetTableOffset, 4);
+      in.read((char*)&theAttribteOffsetRecordLength, 2);
+      ossimEndian anEndian;
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theNumberOfAttributeOffsetRecords);
+         anEndian.swap(theNumberOfExplicitArealCoverageRecords);
+         anEndian.swap(theAttributeOffsetTableOffset);
+         anEndian.swap(theAttribteOffsetRecordLength);
+      }
+      theAttributeSectionSubheaderEnd = in.tellg();
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfAttributeSectionSubheader::print(ostream& out)const
+{
+   out << "theNumberOfAttributeOffsetRecords:         " << theNumberOfAttributeOffsetRecords << endl
+       << "theNumberOfExplicitArealCoverageRecords:   " << theNumberOfExplicitArealCoverageRecords << endl
+       << "theAttributeOffsetTableOffset:             " << theAttributeOffsetTableOffset << endl
+       << "theAttribteOffsetRecordLength:             " << theAttribteOffsetRecordLength;
+}
+
+void ossimRpfAttributeSectionSubheader::clearFields()
+{
+   theNumberOfAttributeOffsetRecords       = 0;
+   theNumberOfExplicitArealCoverageRecords = 0;
+   theAttributeOffsetTableOffset           = 0;
+   theAttribteOffsetRecordLength           = 0;
+   
+   theAttributeSectionSubheaderStart       = 0;
+   theAttributeSectionSubheaderEnd         = 0;
+}
+
+ossim_uint64 ossimRpfAttributeSectionSubheader::getSubheaderStart()const
+{
+   return theAttributeSectionSubheaderStart;
+}
+
+ossim_uint64 ossimRpfAttributeSectionSubheader::getSubheaderEnd()const
+{
+   return theAttributeSectionSubheaderEnd;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeSectionSubheader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeSectionSubheader.h
new file mode 100644
index 0000000000..42fbda8a13
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributeSectionSubheader.h
@@ -0,0 +1,67 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfAttributeSectionSubheader.h,v 1.4 2005/08/22 14:58:35 gpotts Exp $
+#ifndef ossimRpfAttributeSectionSubheader_HEADER
+#define ossimRpfAttributeSectionSubheader_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimRpfAttributeSectionSubheader
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfAttributeSectionSubheader& data);
+   ossimRpfAttributeSectionSubheader();
+
+   virtual ~ossimRpfAttributeSectionSubheader(){}
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   virtual void print(ostream& out)const;
+   ossim_uint16 getNumberOfAttributeOffsetRecords()const
+      {
+         return theNumberOfAttributeOffsetRecords;
+      }
+   ossim_uint16 getAttributeOffsetTableOffset()const
+      {
+         return theAttributeOffsetTableOffset;
+      }
+
+   ossim_uint64 getSubheaderStart()const;
+   ossim_uint64 getSubheaderEnd()const;
+   
+private:
+   void clearFields();
+   
+   ossim_uint16 theNumberOfAttributeOffsetRecords;
+   ossim_uint16 theNumberOfExplicitArealCoverageRecords;
+   ossim_uint32 theAttributeOffsetTableOffset;
+   ossim_uint16 theAttribteOffsetRecordLength;
+
+
+   mutable ossim_uint64 theAttributeSectionSubheaderStart;
+   mutable ossim_uint64 theAttributeSectionSubheaderEnd;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributes.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributes.cpp
new file mode 100644
index 0000000000..578822495c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributes.cpp
@@ -0,0 +1,157 @@
+#include "ossimRpfAttributes.h"
+
+std::ostream& operator<<(std::ostream& out,
+                    const ossimRpfAttributes& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfAttributes::ossimRpfAttributes()
+{
+   clearFields();
+}
+ossimRpfAttributes::~ossimRpfAttributes()
+{
+}
+
+void ossimRpfAttributes::print(std::ostream& out)const
+{
+	out << "theCurrencyDate:                     " << theCurrencyDate << std::endl;
+   out << "theProductionDate:                   " << theProductionDate << std::endl;
+   out << "theSignificantDate:                  " << theSignificantDate << std::endl;
+   out << "theChartSeriesCode:                  " << theChartSeriesCode << std::endl;
+   out << "theMapDesignationCode:               " << theMapDesignationCode << std::endl;
+   out << "theOldHorDatum:                      " << theOldHorDatum << std::endl;
+   out << "theEdition:                          " << theEdition << std::endl;
+   out << "theProjectionCode:                   " << theProjectionCode << std::endl;
+   out << "theProjectionA:                      " << theProjectionA << std::endl;
+   out << "theProjectionB:                      " << theProjectionB << std::endl;
+   out << "theProjectionC:                      " << theProjectionC << std::endl;
+   out << "theProjectionD:                      " << theProjectionD << std::endl;
+   out << "theVertDatumCode:                    " << theVertDatumCode<< std::endl;
+   out << "theHorDatumCode:                     " << theHorDatumCode << std::endl;
+   out << "theVertAbsAccuracy:                  " << theVertAbsAccuracy << std::endl;
+   out << "theVertAbsUnits:                     " << theVertAbsUnits << std::endl;
+   out << "theHorAbsAccuracy:                   " << theHorAbsAccuracy << std::endl;
+   out << "theHorAbsUnits:                      " << theHorAbsUnits << std::endl;
+   out << "theVertRelAccuracy:                  " << theVertRelAccuracy << std::endl;
+   out << "theVertRelUnits:                     " << theVertRelUnits << std::endl;
+   out << "theHorRelAccuracy:                   " << theHorRelAccuracy << std::endl;
+   out << "theHorRelUnits:                      " << theHorRelUnits << std::endl;
+   out << "ellipsoidCode:                       " << ellipsoidCode << std::endl;
+   out << "theSoundingDatumCode:                " << theSoundingDatumCode << std::endl;
+   out << "theNavSystemCode:                    " << theNavSystemCode << std::endl;
+   out << "theGridCode:                         " << theGridCode << std::endl;
+   out << "theEeasterlyMagChange:               " << theEeasterlyMagChange << std::endl;
+   out << "theEasterlyMagChangeUnits:           " << theEasterlyMagChangeUnits << std::endl;
+   out << "theWesterlyMagChange:                " << theWesterlyMagChange << std::endl;
+   out << "theWesterlyMagChangeUnits:           " << theWesterlyMagChangeUnits << std::endl;
+   out << "theMagAngle:                         " << theMagAngle << std::endl;
+   out << "theGridConver:                       " << theGridConver << std::endl;
+   out << "theGridConverUnits:                  " << theGridConverUnits << std::endl;
+   out << "theHighElevation:                    " << theHighElevation << std::endl;
+   out << "theHighElevationUnits:               " << theHighElevationUnits << std::endl;
+   out << "theHighLat:                          " << theHighLat << std::endl;
+   out << "theHighLon:                          " << theHighLon << std::endl;
+   out << "theLegendFileName:                   " << theLegendFileName << std::endl;
+   out << "theDataSource:                       " << theDataSource << std::endl;
+   out << "theGsd:                              " << theGsd << std::endl;
+   out << "theDataLevel:                        " << theDataLevel << std::endl;
+}
+
+bool ossimRpfAttributes::isEmpty()const
+{
+   for(std::map<ossim_uint32, bool>::const_iterator iter= theAttributeIdBoolMap.begin();
+       iter != theAttributeIdBoolMap.end();++iter)
+   {
+      if(iter->second!=false)
+      {
+         return false;
+      }
+   }
+   return true;
+}
+
+void ossimRpfAttributes::clearFields()
+{
+   theCurrencyDate    = "";
+   theProductionDate  = "";
+   theSignificantDate = "";
+   theChartSeriesCode = "";
+   theMapDesignationCode = "";
+   theOldHorDatum = "";
+   theEdition = "";
+   theProjectionCode = "";
+   theProjectionA = 0.0;
+   theProjectionB = 0.0;
+   theProjectionC = 0.0;
+   theProjectionD = 0.0;
+   theVertDatumCode = "";
+   theHorDatumCode = "";
+   theVertAbsAccuracy = 0;
+   theVertAbsUnits = 0;
+   theHorAbsAccuracy = 0;
+   theHorAbsUnits    = 0;
+   theVertRelAccuracy = 0;
+   theVertRelUnits = 0;
+   theHorRelAccuracy = 0;
+   theHorRelUnits = 0;
+   ellipsoidCode = "";
+   theSoundingDatumCode = "";
+   theNavSystemCode = 0;
+   theGridCode = "";
+   theEeasterlyMagChange = 0.0;
+   theEasterlyMagChangeUnits = 0;
+   theWesterlyMagChange = 0.0;
+   theWesterlyMagChangeUnits = 0;
+   theMagAngle = 0.0;
+   theMagAngleUnits = 0;
+   theGridConver = 0.0;
+   theGridConverUnits = 0;
+   theHighElevation = 0.0;
+   theHighElevationUnits = 0;
+   theHighLat = 0.0;
+   theHighLon = 0.0;
+   theLegendFileName = "";
+   theDataSource = "";
+   theGsd = 0;
+   theDataLevel = 0;
+
+   theAttributeIdBoolMap.clear();
+}
+
+void ossimRpfAttributes::setAttributeFlag(ossim_uint32 id,
+                                          bool flag)
+{
+   std::map<ossim_uint32, bool>::iterator iter = theAttributeIdBoolMap.find(id);
+
+   if(iter != theAttributeIdBoolMap.end())
+   {
+      if(flag)
+      {
+         iter->second = flag;
+      }
+      else
+      {
+         theAttributeIdBoolMap.erase(iter); 
+      }
+   }
+   else if(flag)
+   {
+	   theAttributeIdBoolMap.insert(std::make_pair(id, flag));
+   }
+}
+
+bool ossimRpfAttributes::getAttributeFlag(ossim_uint32 id)const
+{
+   std::map<ossim_uint32, bool>::const_iterator iter = theAttributeIdBoolMap.find(id);
+
+   if(iter != theAttributeIdBoolMap.end())
+   {
+      return iter->second;
+   }
+
+   return false;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributes.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributes.h
new file mode 100644
index 0000000000..caf7c85b3e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfAttributes.h
@@ -0,0 +1,350 @@
+#ifndef ossimRpfAttributes_HEADER
+#define ossimRpfAttributes_HEADER
+#include <map>
+
+#include "base/data_types/ossimString.h"
+
+class OSSIM_DLL ossimRpfAttributes
+{
+
+public:
+	friend OSSIM_DLL std::ostream& operator<<(std::ostream& out,
+                              const ossimRpfAttributes& data);
+   ossimRpfAttributes();
+   ~ossimRpfAttributes();
+
+   void setAttributeFlag(ossim_uint32 id,
+                         bool flag);
+   bool getAttributeFlag(ossim_uint32 id)const;
+   void print(std::ostream& out)const;
+   bool isEmpty()const;
+   void clearFields();
+
+   
+   /*!
+    * The attribute Id.  The Id and descriptions are taken from
+    * MIL-STD-2411-1 and can have one of the following values:
+    * _________________________________________________________________
+    * 1      Currency Date, 1 parameter:
+    *          1. Date of most recent revision to the RPF
+    *             YYYYMMDD
+    *             8 byte ascii value
+    */
+   ossimString theCurrencyDate;
+
+   /*! 2      Production Date, 1 parameter:
+    *          1. Date the source data was transformed to RPF format
+    *             YYYYMMDD
+    *             8 byte ascii value
+    */
+   ossimString theProductionDate;
+   
+   /*! 3      Significant Date, 1 parameter:
+    *          1. Most accurately describes the date of
+    *             the source data.
+    *             YYYYMMDD
+    *             8 byte ascii value
+    */
+   ossimString theSignificantDate;
+   
+   /*!
+    * 4      Map/Chart source, 4 parameters:
+    *          1. Short title for the id of a group of
+    *             products.  ex: JOG 1501A ...
+    *             10 byte ascii value
+    *          2. The designation of the hardcopy source
+    *             8 byte ascii value
+    *          3. Old horizontal datum code.  Original
+    *             horizontal datum of the hardcopy product
+    *             4 byte ascii value
+    *          4. Edition number of the source graphic
+    *             7 byte ascii value.
+    */
+   ossimString theChartSeriesCode; 
+   ossimString theMapDesignationCode; 
+   ossimString theOldHorDatum;   
+   ossimString theEdition;
+   
+   /*!
+    * 5      Projection Systemd, 5 parameters: p. 38 of MIL-STD-2411-1
+    *          1. Projection Code. 2 byte ascii value
+    *             AC    Albers Equal area
+    *                   Requires Parameters A B C D
+    *             AL    Azimuthal Equal Dist.
+    *                   Requires Parameters A B
+    *             RB    Hotline Oblique Mercator
+    *                   Requires Parameters A B C 
+    *             LE    Lambert Conformal Conic
+    *                   Requires Parameters A B C D
+    *             MC    Mercator
+    *                   Requires Parameters A B
+    *             OC    Oblique Mercator
+    *                   Requires Parameters A B C
+    *             OD    Orthographic
+    *                   Requires Parameters A B
+    *             PG    Polar Stereo-graphic
+    *                   Requires Parameters A B C D
+    *             PH    Poly conic
+    *                   Requires Parameters A B
+    *             TC    Transverse Mercator
+    *                   Requires Parameters A B C
+    *             UT    Universal Transverse Mercator
+    *                   Requires Parameters A
+    *          2. Projection Param A: real 4 byte value
+    *          3. Projeciton Param B: real 4 byte value
+    *          4. Projection Param C: real 4 byte value
+    *          5. Projection Param D: real 4 byte value
+    */
+   ossimString theProjectionCode;
+   float theProjectionA;
+   float theProjectionB;
+   float theProjectionC;
+   float theProjectionD;
+
+   /*!
+    * 6      Vertical Datum (1 parameter) p. 37 MIL-STD-2411-1
+    *         4 byte ascii
+    *
+    *          MSL     Mean Sea Level.  All elevations in th data set
+    *                  are referenced to the geoid of the specified datum
+    *          GEOD    Geodetic (All elevations in the data set
+    *                  are referenced to the ellipsoid of the specified
+    *                  datum
+    */
+   ossimString theVertDatumCode;
+
+   /*!
+    * 7      Horizontal Datum (1 parameter)
+    *        4 byte ascii
+    *
+    *            Look on p.33 of MIL-STD-2411-1.  Too big to list
+    *            we will need a translation table for these
+    *            codes
+    */
+   ossimString theHorDatumCode;
+   
+   /*!
+    * 8      Vertical Absolute Accurracy (2 parameters)
+    *        1. vertical absolute accuracy: 4 byte unsigned int
+    *        2. Accuracy units of measure:  2 byte value 
+    *             0   unknown
+    *             1   meters (Length area Volume)
+    *             2   Kilopounds
+    *             3   Seconds (of time)
+    *             4   Meters/Second (speed)
+    *             5   Cubic Meters per second (Flow)
+    *             6   Volt (Electrical potential)
+    *             7   Watt (Ten to 6 electirical power)
+    *             8   Hertz
+    *             9   +- DD MM SS.S (Angular)
+    *             10  +- HH MM SS.S (Time)
+    *             11  International Nautical Mile (1852 meters)
+    *             12  knot
+    *             13  Nautical mile per day
+    *             14  Feet
+    *             15  Fathom
+    *             16  Micrometers (microns)
+    *             17  Mils
+    *             18  Seconds of Arc
+    *             19  Minutes of Arc
+    *             20  Degrees of arc
+    *             999 Other
+    */
+   ossim_uint32  theVertAbsAccuracy;
+   ossim_uint16 theVertAbsUnits;
+   
+   /*!
+    * 9      Horizontal Absolute Accuracy (2 parameters)
+    *        1. Horizontal absolute accuracy: 4 byte unsigned int
+    *        2. Accuracy units of measure:  2 byte value 
+    *             0   unknown
+    *             1   meters (Length area Volume)
+    *             2   Kilopounds
+    *             3   Seconds (of time)
+    *             4   Meters/Second (speed)
+    *             5   Cubic Meters per second (Flow)
+    *             6   Volt (Electrical potential)
+    *             7   Watt (Ten to 6 electirical power)
+    *             8   Hertz
+    *             9   +- DD MM SS.S (Angular)
+    *             10  +- HH MM SS.S (Time)
+    *             11  International Nautical Mile (1852 meters)
+    *             12  knot
+    *             13  Nautical mile per day
+    *             14  Feet
+    *             15  Fathom
+    *             16  Micrometers (microns)
+    *             17  Mils
+    *             18  Seconds of Arc
+    *             19  Minutes of Arc
+    *             20  Degrees of arc
+    *             999 Other
+    */
+   ossim_uint32  theHorAbsAccuracy;
+   ossim_uint16 theHorAbsUnits;
+   
+   /*!
+    * 10     Vertical Relative Accuracy (2 parameters)
+    *        1. Vertical relative accuracy: 4 byte unsigned int
+    *        2. Accuracy units of measure:  2 byte value 
+    *             0   unknown
+    *             1   meters (Length area Volume)
+    *             2   Kilopounds
+    *             3   Seconds (of time)
+    *             4   Meters/Second (speed)
+    *             5   Cubic Meters per second (Flow)
+    *             6   Volt (Electrical potential)
+    *             7   Watt (Ten to 6 electirical power)
+    *             8   Hertz
+    *             9   +- DD MM SS.S (Angular)
+    *             10  +- HH MM SS.S (Time)
+    *             11  International Nautical Mile (1852 meters)
+    *             12  knot
+    *             13  Nautical mile per day
+    *             14  Feet
+    *             15  Fathom
+    *             16  Micrometers (microns)
+    *             17  Mils
+    *             18  Seconds of Arc
+    *             19  Minutes of Arc
+    *             20  Degrees of arc
+    *             999 Other
+    */
+   ossim_uint32  theVertRelAccuracy;
+   ossim_uint16 theVertRelUnits;
+   
+   /*!
+    * 11     Horizontal Relative Accuracy (2 parameters)
+    *        1. Horizontal relative accuracy: 4 byte unsigned int
+    *        2. Accuracy units of measure:  2 byte value 
+    *             0   unknown
+    *             1   meters (Length area Volume)
+    *             2   Kilopounds
+    *             3   Seconds (of time)
+    *             4   Meters/Second (speed)
+    *             5   Cubic Meters per second (Flow)
+    *             6   Volt (Electrical potential)
+    *             7   Watt (Ten to 6 electirical power)
+    *             8   Hertz
+    *             9   +- DD MM SS.S (Angular)
+    *             10  +- HH MM SS.S (Time)
+    *             11  International Nautical Mile (1852 meters)
+    *             12  knot
+    *             13  Nautical mile per day
+    *             14  Feet
+    *             15  Fathom
+    *             16  Micrometers (microns)
+    *             17  Mils
+    *             18  Seconds of Arc
+    *             19  Minutes of Arc
+    *             20  Degrees of arc
+    *             999 Other
+    */
+   ossim_uint32  theHorRelAccuracy;
+   ossim_uint16 theHorRelUnits; 
+
+   /*!
+    * 12     Ellipsoid, 1 parameter:
+    *        1. Ellipsoid code.  3 byte ascii
+    *           See p. 40 of MIL-STD-2411-1
+    */
+   ossimString ellipsoidCode;
+
+   /*!
+    * 13     Sounding Datumm, 1 parameter: 4 byte ascii
+    *        See p. 33 MIL-STD-2411-1 5.3.2.2
+    */
+   ossimString theSoundingDatumCode;
+   
+   /*!
+    * 14     Navigation System, 1 parameter: 
+    *        1. Navigation code. 2 byte unsigned int
+    *           See MIL-STD-2411-1 5.3.2.4
+    */
+   ossim_uint16 theNavSystemCode; 
+
+   /*!
+    * 15     Grid, 1 parameter:
+    *        1. Grid code. 2 byte ascii
+    *           See MIL-STD-2411-1 5.3.2.7
+    */
+   ossimString theGridCode;
+
+   /*!
+    * 16     Easterly Annual Magnetic Change, 2 parameters:
+    *        1. Easterly annual magnetic change. 4 byte real
+    *        2. Units of the change.  See 5.3.2.6 of MIL-STD-2411-1
+    */
+   float          theEeasterlyMagChange; 
+   ossim_uint16 theEasterlyMagChangeUnits;
+
+   /*!
+    * 17     Westerly Annual Magnetic Change, 2 parameters:
+    *        1. Westerly annual magnetic change. 4 byte real
+    *        2. Units of the change.  See 5.3.2.6 of MIL-STD-2411-1
+    */
+   float          theWesterlyMagChange;
+   ossim_uint16 theWesterlyMagChangeUnits;
+
+   /*!
+    * 18     Grid North Magnetic North ANgle, 2 paramters:
+    *        1. Grid North - Magnetic North.  4 byte real
+    *        2. Units of angle. 2 byte unsigned int
+    *           see 5.3.2.6
+    */
+   float          theMagAngle; 
+   ossim_uint16 theMagAngleUnits;
+
+   /*!
+    * 19     Grid convergence angle, 2 parameters:
+    *        1. Grid convergence angle.  4 byte Real
+    *        2. Units of angle. 2 byte unsigned int 5.3.2.6
+    */
+   float          theGridConver; 
+   ossim_uint16 theGridConverUnits;
+
+   /*!
+    * 20     Highest known elevation (4 parameters)
+    *        1. Highest known elevation: 8 byte real
+    *        2. Units of elevation: See 5.3.2.6 of MIL-STD-2411-1
+    *        3. Lat of elevation: 8 byte real in decimal degrees
+    *        4. Lon of elevation: 8 byte real in decimal degrees
+    */
+   double         theHighElevation;
+   ossim_uint16   theHighElevationUnits;
+   double         theHighLat;
+   double         theHighLon;
+
+   /*! 21     Multiple legend, 1 paraemter:
+    *        1. Name of legend file that applies to this
+    *           12 byte ascii
+    */
+   ossimString theLegendFileName;
+   
+   /*!
+    * 22     Image source, 2 parameters:
+    *        1. Source of data from which this
+    *           RPF was derived. ex: SPOT. Landsat7, Landsat4.
+    *           for CDTED: "imagery, "carto"
+    *           12 byte ascii
+    *
+    *        2. GSD.  Ground sample or post distance.
+    *           4 byte unsigned int
+    */
+    ossimString theDataSource; // [12];
+    ossim_uint32 theGsd; // uint
+
+   /*!
+    * 23     Data Level, 1 parameter:
+    *        1. The level of the source.  For example:
+    *           if this is a DTED or CDTED it would
+    *           distinguish between level 1 and 2
+    */
+   ossim_uint16 theDataLevel; // ushort
+
+protected:
+   std::map<ossim_uint32, bool> theAttributeIdBoolMap;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectRecord.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectRecord.cpp
new file mode 100644
index 0000000000..b7f63aac67
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectRecord.cpp
@@ -0,0 +1,93 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfBoundaryRectRecord.cpp,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#include "ossimRpfBoundaryRectRecord.h"
+#include <string.h> // for memset
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfBoundaryRectRecord& data)
+{
+   out << setiosflags(ios::fixed)
+       << setprecision(12)
+       << "theProductDataType:             " << data.theProductDataType << endl
+       << "theCompressionRatio:            " << data.theCompressionRatio << endl
+       << "theScale:                       " << data.theScale << endl
+       << "theZone:                        " << data.theZone << endl
+       << "theProducer:                    " << data.theProducer << endl
+       << data.theCoverage << endl
+       << "theNumberOfFramesNorthSouth:    " << data.theNumberOfFramesNorthSouth << endl
+       << "theNumberOfFramesEastWest:      " << data.theNumberOfFramesEastWest;
+      
+   return out;
+}
+
+ossimErrorCode ossimRpfBoundaryRectRecord::parseStream(istream& in, ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      ossimEndian anEndian;
+      clearFields();
+      
+      in.read((char*)&theProductDataType, 5);
+      in.read((char*)&theCompressionRatio, 5);
+      in.read((char*)&theScale, 12);
+      in.read((char*)&theZone, 1);
+      in.read((char*)&theProducer, 5);
+      
+      theCoverage.parseStream(in, byteOrder);
+      
+      in.read((char*)&theNumberOfFramesNorthSouth, 4);
+      in.read((char*)&theNumberOfFramesEastWest, 4);
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theNumberOfFramesNorthSouth);
+         anEndian.swap(theNumberOfFramesEastWest);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfBoundaryRectRecord::clearFields()
+{
+   memset(theProductDataType, ' ', 5);
+   memset(theCompressionRatio, ' ', 5);
+   memset(theScale, ' ', 12);
+   memset(theProducer, ' ', 5);
+   theNumberOfFramesNorthSouth = 0;
+   theNumberOfFramesEastWest = 0;
+   theCoverage.clearFields();
+
+   theProductDataType[5] = '\0';
+   theCompressionRatio[5] = '\0';
+   theScale[12] = '\0';
+   theProducer[5] = '\0';
+   theZone = ' ';
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectRecord.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectRecord.h
new file mode 100644
index 0000000000..0cb82a6593
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectRecord.h
@@ -0,0 +1,92 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfBoundaryRectRecord.h,v 1.2 2003/06/15 19:01:34 dburken Exp $
+#ifndef ossimRpfBoundaryRectRecord_HEADER
+#define ossimRpfBoundaryRectRecord_HEADER
+#include <iostream>
+#include <iomanip>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+#include "base/data_types/ossimString.h"
+#include "ossimRpfCoverageSection.h"
+
+class ossimRpfBoundaryRectRecord
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfBoundaryRectRecord& data);
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   void clearFields();
+
+   ossimString getProductType()const{return ossimString(theProductDataType);}
+   ossimString getScale()const{return ossimString(theScale);}
+   ossimString getCompressionRatio()const{return ossimString(theCompressionRatio);}
+   
+   ossim_uint32 getNumberOfFramesVertical()const{ return theNumberOfFramesNorthSouth;}
+   ossim_uint32 getNumberOfFramesHorizontal()const{ return theNumberOfFramesEastWest;}
+
+   const ossimRpfCoverageSection& getCoverage()const{return theCoverage;}
+   char getZone()const{return theZone;}
+
+private:
+   /*!
+    * a five byte asci field
+    */
+   char theProductDataType[6];
+
+   /*!
+    * five byte asci field
+    */
+   char theCompressionRatio[6];
+
+   /*!
+    * 12 byte asci field.
+    */
+   char theScale[13];
+
+   /*!
+    *
+    */
+   char theZone;
+
+   /*!
+    * is a 5 byte asci field.
+    */
+   char theProducer[6];
+
+   ossimRpfCoverageSection theCoverage;
+
+   /*!
+    * Four byte fields.
+    */
+   ossim_uint32 theNumberOfFramesNorthSouth;
+
+   /*!
+    * Four byte fields.
+    */
+   ossim_uint32 theNumberOfFramesEastWest;   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectSectionSubheader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectSectionSubheader.cpp
new file mode 100644
index 0000000000..cdd050de27
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectSectionSubheader.cpp
@@ -0,0 +1,81 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfBoundaryRectSectionSubheader.cpp,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#include "ossimRpfBoundaryRectSectionSubheader.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfBoundaryRectSectionSubheader &data)
+{
+   data.print(out);
+
+   return out;
+}
+
+ossimRpfBoundaryRectSectionSubheader::ossimRpfBoundaryRectSectionSubheader()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfBoundaryRectSectionSubheader::parseStream(istream& in,
+                                                                 ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      ossimEndian anEndian;
+
+      clearFields();
+      
+      in.read((char*)&theRectangleTableOffset, 4);
+      in.read((char*)&theNumberOfEntries, 2);
+      in.read((char*)&theLengthOfEachEntry, 2);
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theRectangleTableOffset);
+         anEndian.swap(theNumberOfEntries);
+         anEndian.swap(theLengthOfEachEntry);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfBoundaryRectSectionSubheader::print(ostream& out)const
+{
+   out << "theRectangleTableOffset:      " << theRectangleTableOffset << endl
+       << "theNumberOfEntries:           " << theNumberOfEntries << endl
+       << "theLengthOfEachEntry:         " << theLengthOfEachEntry;
+}
+
+void ossimRpfBoundaryRectSectionSubheader::clearFields()
+{
+   theRectangleTableOffset = 0;
+   theNumberOfEntries      = 0;
+   theLengthOfEachEntry    = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectSectionSubheader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectSectionSubheader.h
new file mode 100644
index 0000000000..09ecfcc281
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectSectionSubheader.h
@@ -0,0 +1,53 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfBoundaryRectSectionSubheader.h,v 1.2 2003/06/15 19:01:34 dburken Exp $
+#ifndef ossimRpfBoundaryRectSectionSubheader_HEADER
+#define ossimRpfBoundaryRectSectionSubheader_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimRpfBoundaryRectSectionSubheader
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfBoundaryRectSectionSubheader &data);
+   ossimRpfBoundaryRectSectionSubheader();
+   virtual ~ossimRpfBoundaryRectSectionSubheader(){}
+
+   ossimErrorCode parseStream(istream& in, ossimByteOrder);
+   virtual void print(ostream& out)const;
+   ossim_uint16 getNumberOfEntries()const{return theNumberOfEntries;}
+   ossim_uint32 getTableOffset()const{return theRectangleTableOffset;}
+   ossim_uint16 getLengthOfEachEntry()const{return theLengthOfEachEntry;}
+
+   void clearFields();
+private:   
+   ossim_uint32 theRectangleTableOffset;
+   ossim_uint16 theNumberOfEntries;
+   ossim_uint16 theLengthOfEachEntry;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectTable.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectTable.cpp
new file mode 100644
index 0000000000..4481bbd9b0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectTable.cpp
@@ -0,0 +1,76 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfBoundaryRectTable.cpp,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#include "ossimRpfBoundaryRectTable.h"
+#include <iomanip>
+using namespace std;
+
+#include <string.h> // for memset
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfBoundaryRectTable& data)
+{
+   data.print(out);
+
+   return out;
+}
+
+ossimRpfBoundaryRectTable::ossimRpfBoundaryRectTable(unsigned long numberOfEntries)
+{
+   theTable.resize(numberOfEntries);  
+}
+
+ossimErrorCode ossimRpfBoundaryRectTable::parseStream(istream& in,
+                                                      ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      vector<ossimRpfBoundaryRectRecord>::iterator entry = theTable.begin();
+      
+      while(entry != theTable.end())
+      {
+         (*entry).parseStream(in, byteOrder);
+         ++entry;
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfBoundaryRectTable::setNumberOfEntries(unsigned long numberOfEntries)
+{
+   theTable.resize(numberOfEntries);
+}
+
+void ossimRpfBoundaryRectTable::print(ostream& out)const
+{
+   copy(theTable.begin(),
+        theTable.end(),
+        ostream_iterator<ossimRpfBoundaryRectRecord>(out, "\n"));
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectTable.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectTable.h
new file mode 100644
index 0000000000..abb04f0a9a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfBoundaryRectTable.h
@@ -0,0 +1,50 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfBoundaryRectTable.h,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#ifndef ossimRpfBoundaryRectTable_HEADER
+#define ossimRpfBoundaryRectTable_HEADER
+#include <iostream>
+#include <vector>
+#include <iterator>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+#include "ossimRpfBoundaryRectRecord.h"
+
+class ossimRpfBoundaryRectTable
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfBoundaryRectTable& data);
+   
+   ossimRpfBoundaryRectTable(unsigned long numberOfEntries=0);
+   virtual ~ossimRpfBoundaryRectTable(){}
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   void setNumberOfEntries(unsigned long numberOfEntries);
+   virtual void print(ostream& out)const;
+   
+private:
+   vector<ossimRpfBoundaryRectRecord> theTable;
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterOffsetRecord.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterOffsetRecord.cpp
new file mode 100644
index 0000000000..8bc2e49e56
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterOffsetRecord.cpp
@@ -0,0 +1,60 @@
+#include "ossimRpfColorConverterOffsetRecord.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfColorConverterOffsetRecord& data)
+{
+   out << "theColorConverterTableId:                 " << data.theColorConverterTableId << endl
+       << "theNumberOfColorConverterRecords:         " << data.theNumberOfColorConverterRecords << endl
+       << "theColorConverterTableOffset:             " << data.theColorConverterTableOffset << endl
+       << "theSourceColorGrayscaleOffsetTableOffset: " << data.theSourceColorGrayscaleOffsetTableOffset << endl
+       << "theTargetColorGrayscaleOffsetTableOffset: " << data.theTargetColorGrayscaleOffsetTableOffset;
+
+   return out;
+}
+
+ossimRpfColorConverterOffsetRecord::ossimRpfColorConverterOffsetRecord()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfColorConverterOffsetRecord::parseStream(istream& in,
+                                                               ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      in.read((char*)&theColorConverterTableId, 2);
+      in.read((char*)&theNumberOfColorConverterRecords, 4);
+      in.read((char*)&theColorConverterTableOffset, 4);
+      in.read((char*)&theSourceColorGrayscaleOffsetTableOffset, 4);
+      in.read((char*)&theTargetColorGrayscaleOffsetTableOffset, 4);
+      
+      ossimEndian anEndian;
+      
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theColorConverterTableId);
+         anEndian.swap(theNumberOfColorConverterRecords);
+         anEndian.swap(theColorConverterTableOffset);
+         anEndian.swap(theSourceColorGrayscaleOffsetTableOffset);
+         anEndian.swap(theTargetColorGrayscaleOffsetTableOffset);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfColorConverterOffsetRecord::clearFields()
+{
+   theColorConverterTableId                 = 0;
+   theNumberOfColorConverterRecords         = 0;
+   theColorConverterTableOffset             = 0;
+   theSourceColorGrayscaleOffsetTableOffset = 0;
+   theTargetColorGrayscaleOffsetTableOffset = 0;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterOffsetRecord.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterOffsetRecord.h
new file mode 100644
index 0000000000..674e64ccce
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterOffsetRecord.h
@@ -0,0 +1,61 @@
+#ifndef ossimRpfColorConverterOffsetRecord_HEADER
+#define ossimRpfColorConverterOffsetRecord_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimConstants.h"
+#include "base/context/ossimErrorContext.h"
+
+
+class ossimRpfColorConverterOffsetRecord
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfColorConverterOffsetRecord& data);
+   ossimRpfColorConverterOffsetRecord();
+   
+   ossimErrorCode parseStream(istream& in,
+                              ossimByteOrder byteOrder);
+
+   void clearFields();
+   /*!
+    * Is a two byte field as is described in Mil-STD-2411-1.
+    * The id can be one of:
+    *
+    * 1       CCT/1--->1
+    * 2       CCT/1--->2
+    * 3       CCT/1--->3
+    * 4       CCT/1--->4
+    * 5       CCT/2--->2
+    * 6       CCT/2--->3
+    * 7       CCT/2--->4
+    * 8       CCT/3--->3
+    *
+    * where CCT stands for Color Converter Table
+    */
+   ossim_uint16 theColorConverterTableId;
+
+   /*!
+    * Is a 4 byte field.
+    */
+   ossim_uint32  theNumberOfColorConverterRecords;
+
+   /*!
+    * Is a 4 byte field indicating the offset from the start of
+    * the color converter subsection to the color converter table.
+    */
+   ossim_uint32  theColorConverterTableOffset;
+
+   /*!
+    * Is a 4 byte field indicating the offset from the colormap
+    * subsection to the source color/grayscale offset table.
+    */
+   ossim_uint32  theSourceColorGrayscaleOffsetTableOffset;
+
+   /*!
+    * Is a 4 byte field indicating the offset from the colormap
+    * subsection to the color/graysscale offset table.
+    */
+   ossim_uint32  theTargetColorGrayscaleOffsetTableOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterSubsection.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterSubsection.cpp
new file mode 100644
index 0000000000..0e3a9cddda
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterSubsection.cpp
@@ -0,0 +1,130 @@
+//*******************************************************************
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//********************************************************************
+// $Id: ossimRpfColorConverterSubsection.cpp,v 1.3 2004/12/29 14:39:06 dburken Exp $
+
+#include "ossimRpfColorConverterSubsection.h"
+#include "ossimRpfColorConverterOffsetRecord.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfColorConverterSubsection& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfColorConverterSubsection::ossimRpfColorConverterSubsection()
+{
+   theNumberOfColorConverterOffsetRecords = 0;
+   clearFields();
+}
+
+void ossimRpfColorConverterSubsection::clearFields()
+{
+   theColorConverterOffsetTableOffset     = 0;
+   theColorConverterOffsetRecordLength    = 0;
+   theConverterRecordLength               = 0;
+
+   theTableList.clear();
+}
+
+const ossimRpfColorConverterTable* ossimRpfColorConverterSubsection::getColorConversionTable(ossim_uint32 givenThisNumberOfEntires)const
+{
+   vector<ossimRpfColorConverterTable>::const_iterator listElement = theTableList.begin();
+
+   while(listElement != theTableList.end())
+   {
+      if((*listElement).getNumberOfEntries() == givenThisNumberOfEntires)
+      {
+         return &(*listElement);
+      }
+   }
+
+   return NULL;
+}
+
+ossimErrorCode ossimRpfColorConverterSubsection::parseStream(istream& in,
+                                                             ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      clearFields();
+
+      // this is the start of the subsection
+      theStartOffset = in.tellg();
+      in.read((char*)&theColorConverterOffsetTableOffset, 4);
+      in.read((char*)&theColorConverterOffsetRecordLength, 2);
+      in.read((char*)&theConverterRecordLength, 2);
+
+      // this grabs the end of the subsection
+      theEndOffset   = in.tellg();
+
+      ossimEndian anEndian;
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theColorConverterOffsetTableOffset);
+         anEndian.swap(theColorConverterOffsetRecordLength);
+         anEndian.swap(theConverterRecordLength);
+
+      }
+      theTableList.resize(theNumberOfColorConverterOffsetRecords);
+      for(unsigned long index = 0;
+          index < theNumberOfColorConverterOffsetRecords;
+          ++index)
+      {
+         ossimRpfColorConverterOffsetRecord recordInfo;
+         
+         if(recordInfo.parseStream(in, byteOrder) ==
+            ossimErrorCodes::OSSIM_OK)
+         {
+            unsigned long rememberGet = in.tellg();
+
+            theTableList[index].setNumberOfEntries(recordInfo.theNumberOfColorConverterRecords);
+            theTableList[index].setTableId(recordInfo.theColorConverterTableId);
+            in.seekg(theStartOffset + recordInfo.theColorConverterTableOffset, ios::beg);
+            theTableList[index].parseStream(in, byteOrder);
+            
+            in.seekg(rememberGet, ios::beg);
+         }
+         else
+         {
+            return ossimErrorCodes::OSSIM_ERROR;
+         }
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfColorConverterSubsection::setNumberOfColorConverterOffsetRecords(ossim_uint16 numberOfRecords)
+{
+   theNumberOfColorConverterOffsetRecords = numberOfRecords;
+}
+
+void ossimRpfColorConverterSubsection::print(ostream& out)const
+{
+   out << "theColorConverterOffsetTableOffset:      "
+       << theColorConverterOffsetTableOffset << endl
+       << "theColorConverterOffsetRecordLength:     "
+       << theColorConverterOffsetRecordLength << endl
+       << "theConverterRecordLength:                "
+       << theConverterRecordLength << endl;
+
+   copy(theTableList.begin(),
+        theTableList.end(),
+        ostream_iterator<ossimRpfColorConverterTable>(out, "\n"));
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterSubsection.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterSubsection.h
new file mode 100644
index 0000000000..cf94766821
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterSubsection.h
@@ -0,0 +1,52 @@
+#ifndef ossimRpfColorConverterSubsection_HEADER
+#define ossimRpfColorConverterSubsection_HEADER
+#include <iostream>
+#include <vector>
+#include <iterator>
+using namespace std;
+#include "base/common/ossimConstants.h"
+#include "base/context/ossimErrorContext.h"
+#include "ossimRpfColorConverterTable.h"
+
+class ossimRpfColorConverterSubsection
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfColorConverterSubsection& data);
+   ossimRpfColorConverterSubsection();
+   virtual ~ossimRpfColorConverterSubsection(){}
+
+   ossimErrorCode parseStream(istream& in,
+                              ossimByteOrder byteOrder);
+   
+   ossim_uint32 getStartOffset()const{return theStartOffset;}
+   ossim_uint32 getEndOffset()const{return theEndOffset;}
+
+   const vector<ossimRpfColorConverterTable>& getColorConversionTable()const
+      {
+         return theTableList;
+      }
+   const ossimRpfColorConverterTable* getColorConversionTable(ossim_uint32 givenThisNumberOfEntires)const;
+   
+   void setNumberOfColorConverterOffsetRecords(ossim_uint16 numberOfRecords);
+   void print(ostream& out)const;
+
+   void clearFields();
+   
+private:
+   ossimRpfColorConverterSubsection(const ossimRpfColorConverterSubsection&){}//hide
+   void operator =(const ossimRpfColorConverterSubsection&){}//hide
+
+   ossim_uint32  theStartOffset;
+   ossim_uint32  theEndOffset;
+   
+   ossim_uint16  theNumberOfColorConverterOffsetRecords;
+   
+   ossim_uint32  theColorConverterOffsetTableOffset;
+   ossim_uint16  theColorConverterOffsetRecordLength;
+   ossim_uint16  theConverterRecordLength;
+
+   vector<ossimRpfColorConverterTable> theTableList;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterTable.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterTable.cpp
new file mode 100644
index 0000000000..0c3c00524b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterTable.cpp
@@ -0,0 +1,93 @@
+#include "ossimRpfColorConverterTable.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfColorConverterTable& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfColorConverterTable::ossimRpfColorConverterTable()
+{
+   theTableId                      = 0;
+   theNumberOfEntries              = 0;
+   theColorGrayscaleTableEntryList = NULL;
+}
+
+ossimRpfColorConverterTable::~ossimRpfColorConverterTable()
+{
+   if(theColorGrayscaleTableEntryList)
+   {
+      delete theColorGrayscaleTableEntryList;
+      theColorGrayscaleTableEntryList = NULL;
+   }
+}
+ossimErrorCode ossimRpfColorConverterTable::parseStream(istream& in,
+                                                        ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      if(theNumberOfEntries > 0)
+      {
+         in.read((char*)theColorGrayscaleTableEntryList, 4*theNumberOfEntries);
+
+         ossimEndian anEndian;
+         if(anEndian.getSystemEndianType() != byteOrder)
+         {
+            for(ossim_uint32 index = 0;
+                index < theNumberOfEntries;
+                ++index)
+            {
+               anEndian.swap(theColorGrayscaleTableEntryList[index]);
+            }
+         }
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfColorConverterTable::print(ostream& out)const
+{
+   out << "theTableId:                   " << theTableId << endl
+       << "theNumberOfEntries:           " << theNumberOfEntries << endl;
+
+   if(theColorGrayscaleTableEntryList)
+   {
+      out << "Values: " << endl;
+      for(ossim_uint32 index=0; index < theNumberOfEntries; index++)
+      {
+         out<< theColorGrayscaleTableEntryList[index] << endl;
+      }
+   }
+   
+}
+
+void ossimRpfColorConverterTable::setNumberOfEntries(ossim_uint32 entries)
+{
+   if(theColorGrayscaleTableEntryList)
+   {
+      delete theColorGrayscaleTableEntryList;
+      theColorGrayscaleTableEntryList = NULL;
+   }
+   theColorGrayscaleTableEntryList = new ossim_uint32[entries];
+   theNumberOfEntries = entries;
+   
+   for(ossim_uint32 index=0;
+       index < theNumberOfEntries;
+       ++index)
+   {
+      theColorGrayscaleTableEntryList[index] = 0;
+   }
+}
+void ossimRpfColorConverterTable::setTableId(ossim_uint16 id)
+{
+   theTableId = id;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterTable.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterTable.h
new file mode 100644
index 0000000000..cfed4b6f90
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorConverterTable.h
@@ -0,0 +1,45 @@
+#ifndef ossimRpfColorConverterTable_HEADER
+#define ossimRpfColorConverterTable_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h"
+#include "base/context/ossimErrorContext.h"
+
+class ossimRpfColorConverterTable
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfColorConverterTable& data);
+   
+   ossimRpfColorConverterTable();
+   virtual ~ossimRpfColorConverterTable();
+
+   ossimErrorCode parseStream(istream& in,
+                              ossimByteOrder byteOrder);
+   void print(ostream& out)const;
+   ossim_uint32 getEntry(ossim_uint32 entry){return theColorGrayscaleTableEntryList[entry];}
+   void setNumberOfEntries(ossim_uint32 entries);
+   void setTableId(ossim_uint16 id);
+   const ossim_uint32* getEntryList()const{return theColorGrayscaleTableEntryList;}
+   ossim_uint32 getNumberOfEntries()const{return theNumberOfEntries;}
+   
+private:
+   /*!
+    * This will not be a field read from the stream this is
+    * the value in the color converter offset table.
+    */
+   ossim_uint16 theTableId;
+
+   /*!
+    * Holds the number of entries
+    */ 
+   ossim_uint32  theNumberOfEntries;
+
+   /*!
+    * This will hold the lookup table values.
+    */
+   ossim_uint32* theColorGrayscaleTableEntryList;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleOffsetRecord.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleOffsetRecord.cpp
new file mode 100644
index 0000000000..bbc184b5bc
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleOffsetRecord.cpp
@@ -0,0 +1,69 @@
+#include "ossimRpfColorGrayscaleOffsetRecord.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfColorGrayscaleOffsetRecord& data)
+{
+   data.print(out);
+   
+   return out;
+}
+   
+ossimRpfColorGrayscaleOffsetRecord::ossimRpfColorGrayscaleOffsetRecord()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfColorGrayscaleOffsetRecord::parseStream(istream& in,
+                                                               ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      clearFields();
+      
+      in.read((char*)&theColorGrayscaleTableId, 2);
+      in.read((char*)&theNumberOfColorGrayscaleRecords, 4);
+      in.read((char*)&theColorGrayscaleElementLength, 1);
+      in.read((char*)&theHistogramRecordLength, 2);
+      in.read((char*)&theColorGrayscaleTableOffset, 4);
+      in.read((char*)&theHistogramTableOffset, 4);
+
+      ossimEndian anEndian;
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theColorGrayscaleTableId);
+         anEndian.swap(theNumberOfColorGrayscaleRecords);
+         anEndian.swap(theHistogramRecordLength);
+         anEndian.swap(theColorGrayscaleTableOffset);
+         anEndian.swap(theHistogramTableOffset);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfColorGrayscaleOffsetRecord::print(ostream& out)const
+{
+   out << "theColorGrayscaleTableId:                 " << theColorGrayscaleTableId << endl
+       << "theNumberOfColorGrayscaleRecords:         " << theNumberOfColorGrayscaleRecords << endl
+       << "theColorGrayscaleElementLength:           " << (unsigned long)theColorGrayscaleElementLength << endl
+       << "theHistogramRecordLength:                 " << theHistogramRecordLength << endl
+       << "theColorGrayscaleTableOffset:             " << theColorGrayscaleTableOffset << endl
+       << "theHistogramTableOffset:                  " << theHistogramTableOffset;
+}
+
+void ossimRpfColorGrayscaleOffsetRecord::clearFields()
+{
+   theColorGrayscaleTableId         = 0;
+   theNumberOfColorGrayscaleRecords = 0;
+   theColorGrayscaleElementLength   = 0;
+   theHistogramRecordLength         = 0;
+   theColorGrayscaleTableOffset     = 0;
+   theHistogramTableOffset          = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleOffsetRecord.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleOffsetRecord.h
new file mode 100644
index 0000000000..60cfeaa90d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleOffsetRecord.h
@@ -0,0 +1,44 @@
+#ifndef ossimRpfColorGrayscaleOffsetRecord_HEADER
+#define ossimRpfColorGrayscaleOffsetRecord_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h"
+#include "base/context/ossimErrorContext.h"
+
+class ossimRpfColorGrayscaleOffsetRecord
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfColorGrayscaleOffsetRecord& data);
+   
+   ossimRpfColorGrayscaleOffsetRecord();
+
+   ossimErrorCode parseStream(istream& in,
+                              ossimByteOrder byteOrder);
+   
+   void print(ostream& out)const;
+
+   void clearFields();
+   ossim_uint16 getColorGrayscaleTableId()const
+      {
+         return theColorGrayscaleTableId;
+      }
+   ossim_uint32 getNumberOfColorGrayscaleRecords()const
+      {
+         return theNumberOfColorGrayscaleRecords;
+      }
+   ossim_uint32 getColorGrayscaleTableOffset()const
+      {
+         return theColorGrayscaleTableOffset;
+      }
+private:
+   ossim_uint16  theColorGrayscaleTableId;
+   ossim_uint32  theNumberOfColorGrayscaleRecords;
+   unsigned char theColorGrayscaleElementLength;
+   ossim_uint16  theHistogramRecordLength;
+   ossim_uint32  theColorGrayscaleTableOffset;
+   ossim_uint32  theHistogramTableOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleSubheader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleSubheader.cpp
new file mode 100644
index 0000000000..1067b101b4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleSubheader.cpp
@@ -0,0 +1,59 @@
+#include "ossimRpfColorGrayscaleSubheader.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfColorGrayscaleSubheader& data)
+{
+   data.print(out);
+
+   return out;
+}
+
+ossimRpfColorGrayscaleSubheader::ossimRpfColorGrayscaleSubheader()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfColorGrayscaleSubheader::parseStream(istream& in,
+                                                            ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      clearFields();
+      
+      theStartOffset = in.tellg();
+      in.read((char*)&theNumberOfColorGreyscaleOffsetRecords, 1);
+      in.read((char*)&theNumberOfColorConverterOffsetRecords, 1);
+
+      char tempString[12];
+      in.read(tempString, 12);
+      theColorGrayscaleFilename = ossimString(tempString,
+                                              (char*)(&tempString[12]));
+      theEndOffset = in.tellg();
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfColorGrayscaleSubheader::print(ostream& out)const
+{
+   out << "theNumberOfColorGreyscaleOffsetRecords:    " << (int)theNumberOfColorGreyscaleOffsetRecords << endl
+       << "theNumberOfColorConverterOffsetRecords:    " << (int)theNumberOfColorConverterOffsetRecords << endl
+       << "theColorGrayscaleFilename:                 " << theColorGrayscaleFilename;
+   
+}
+
+void ossimRpfColorGrayscaleSubheader::clearFields()
+{
+   theStartOffset = 0;
+   theEndOffset   = 0;
+   
+   theNumberOfColorGreyscaleOffsetRecords = 0;
+   theNumberOfColorConverterOffsetRecords = 0;
+   theColorGrayscaleFilename              = "";
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleSubheader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleSubheader.h
new file mode 100644
index 0000000000..18f44feb8f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleSubheader.h
@@ -0,0 +1,52 @@
+#ifndef ossimRpfColorGrayscaleSubheader_HEADER
+#define ossimRpfColorGrayscaleSubheader_HEADER
+#include <iostream>
+using namespace std;
+#include "base/context/ossimErrorContext.h"
+#include "base/common/ossimConstants.h"
+
+class ossimRpfColorGrayscaleSubheader
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfColorGrayscaleSubheader& data);
+   
+   ossimRpfColorGrayscaleSubheader();
+   ~ossimRpfColorGrayscaleSubheader(){}
+   
+   ossimErrorCode parseStream(istream& in,
+                            ossimByteOrder byteOrder);
+   void print(ostream& out)const;
+   unsigned long getStartOffset()const
+      {
+         return theStartOffset;
+      }
+   unsigned long getEndOffset()const
+      {
+         return theEndOffset;
+      }
+   unsigned long getNumberOfColorGreyscaleOffsetRecords()const
+      {
+         return theNumberOfColorGreyscaleOffsetRecords;
+      }
+   unsigned long getNumberOfColorConverterOffsetRecords()const
+      {
+         return theNumberOfColorConverterOffsetRecords;
+      }
+   
+private:
+   void clearFields();
+
+   unsigned long theStartOffset;
+   unsigned long theEndOffset;
+   
+   unsigned char theNumberOfColorGreyscaleOffsetRecords;
+   unsigned char theNumberOfColorConverterOffsetRecords;
+
+   /*!
+    * 12 byte field.
+    */
+   ossimString         theColorGrayscaleFilename;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleTable.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleTable.cpp
new file mode 100644
index 0000000000..bc4c3c5aea
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleTable.cpp
@@ -0,0 +1,152 @@
+#include "ossimRpfColorGrayscaleTable.h"
+#include <string.h> // for memcpy
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfColorGrayscaleTable& data)
+{
+   out << "theNumberOfElements:                   " << data.theNumberOfElements << endl
+       << "theTotalNumberOfBytes:                 " << data.theTotalNumberOfBytes << endl
+       << "theTableId:                            " << data.theTableId;
+
+   return out;
+}
+
+ossimRpfColorGrayscaleTable::ossimRpfColorGrayscaleTable()
+   :theNumberOfElements(0),
+    theTotalNumberOfBytes(0),
+    theTableId(0),
+    theData(NULL)
+{
+}
+
+ossimRpfColorGrayscaleTable::ossimRpfColorGrayscaleTable(const ossimRpfColorGrayscaleTable& rhs)
+   :theNumberOfElements(0),
+    theTotalNumberOfBytes(0),
+    theTableId(0),
+    theData(NULL)
+{
+   *this = rhs;
+}
+
+
+ossimRpfColorGrayscaleTable::~ossimRpfColorGrayscaleTable()
+{
+   if(theData)
+   {
+      delete theData;
+      theData = NULL;
+   }
+}
+
+ossimErrorCode ossimRpfColorGrayscaleTable::parseStream(istream& in,
+                                                        ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      if((theTotalNumberOfBytes > 0)&&theData)
+      {
+         in.read((char*)theData, theTotalNumberOfBytes);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+const unsigned char* ossimRpfColorGrayscaleTable::getStartOfData(unsigned long entry)const
+{
+   unsigned long offset = 0;
+
+   switch(theTableId)
+   {
+   case 1: // this is in format RGB
+   {
+      offset = 3*entry;
+      break;
+   }
+   case 2: // format RGBM
+   case 4: // format CMYK
+   {
+      offset = 4*entry;
+      break;
+   }
+   case 3: // format M
+   {
+      offset = entry;
+      break;
+   }
+   }
+
+   return (const unsigned char*)(theData + offset);
+}
+
+void ossimRpfColorGrayscaleTable::setTableData(unsigned short id,
+                                               unsigned long  numberOfElements)
+{
+   if(theData)
+   {
+      delete theData;
+      theData = NULL;
+   }
+
+   unsigned long totalBytes = 0;
+   
+   switch(id)
+   {
+   case 1: // this is in format RGB
+   {
+      totalBytes = 3*numberOfElements;
+      break;
+   }
+   case 2: // format RGBM
+   case 4: // format CMYK
+   {
+      totalBytes = 4*numberOfElements;
+      break;
+   }
+   case 3: // format M
+   {
+      totalBytes = numberOfElements;
+      break;
+   }
+   }
+
+   if(totalBytes > 0)
+   {
+      theTableId            = id;
+      theNumberOfElements   = numberOfElements;
+      theTotalNumberOfBytes = totalBytes;
+
+      theData = new unsigned char[totalBytes];
+   }
+}
+
+
+
+const ossimRpfColorGrayscaleTable& ossimRpfColorGrayscaleTable::operator =(const ossimRpfColorGrayscaleTable& rhs)
+{
+   
+   if(&rhs != this)
+   {
+      theNumberOfElements   = rhs.theNumberOfElements;
+      theTotalNumberOfBytes = rhs.theTotalNumberOfBytes;
+      theTableId            = rhs.theTableId;
+      if(theData)
+      {
+         delete theData;
+         theData = NULL;
+      }
+      if(theTotalNumberOfBytes&&rhs.theData)
+      {
+         theData = new unsigned char[theTotalNumberOfBytes];
+         
+         memcpy(theData, rhs.theData, theTotalNumberOfBytes);
+      }
+   }
+   
+   return *this;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleTable.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleTable.h
new file mode 100644
index 0000000000..dabff21000
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfColorGrayscaleTable.h
@@ -0,0 +1,51 @@
+#ifndef ossimRpfColorGrayscaleTable_HEADER
+#define ossimRpfColorGrayscaleTable_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimConstants.h"
+#include "base/context/ossimErrorContext.h"
+
+class ossimRpfColorGrayscaleTable
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfColorGrayscaleTable& data);
+   ossimRpfColorGrayscaleTable();
+   ossimRpfColorGrayscaleTable(const ossimRpfColorGrayscaleTable& rhs);
+   virtual ~ossimRpfColorGrayscaleTable();
+
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   
+   void setTableData(unsigned short id,
+                     unsigned long  numberOfElements);
+   
+   const ossimRpfColorGrayscaleTable& operator =(const ossimRpfColorGrayscaleTable&);
+
+   const unsigned char* getData()const{return theData;}
+   const unsigned char* getStartOfData(unsigned long entry)const;
+   unsigned short getTableId()const{return theTableId;}
+   unsigned long getNumberOfElements()const{return theNumberOfElements;}
+   
+private:   
+   unsigned long theNumberOfElements;
+
+   unsigned long theTotalNumberOfBytes;
+   
+   /*!
+    * This will not be parsed from the stream.  This is set when
+    * reading the offset record for this table.  The id defines
+    * the format of the data buffer. if the id is :
+    *
+    * 1           then the buffer is in the format of RGB
+    * 2                     ""                        RGBM
+    * 3                     ""                        M
+    * 4                     ""                        CMYK
+    */
+   unsigned short theTableId;
+
+   
+
+   unsigned char* theData;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionLookupOffsetRecord.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionLookupOffsetRecord.cpp
new file mode 100644
index 0000000000..ce58b936ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionLookupOffsetRecord.cpp
@@ -0,0 +1,64 @@
+#include "ossimRpfCompressionLookupOffsetRecord.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream &out,
+                     const ossimRpfCompressionLookupOffsetRecord& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfCompressionLookupOffsetRecord::ossimRpfCompressionLookupOffsetRecord()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfCompressionLookupOffsetRecord::parseStream(istream& in,
+                                                                  ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      ossimEndian anEndian;
+
+      in.read((char*)&theCompressionLookupTableId, 2);
+      in.read((char*)&theNumberOfCompressionLookupRecords, 4);
+      in.read((char*)&theNumberOfValuesPerCompressionLookupRecord, 2);
+      in.read((char*)&theCompressionLookupValueBitLength, 2);
+      in.read((char*)&theCompressionLookupTableOffset, 4);
+      
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theCompressionLookupTableId);
+         anEndian.swap(theNumberOfCompressionLookupRecords);
+         anEndian.swap(theNumberOfValuesPerCompressionLookupRecord);
+         anEndian.swap(theCompressionLookupValueBitLength);
+         anEndian.swap(theCompressionLookupTableOffset);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfCompressionLookupOffsetRecord::print(ostream& out)const
+{
+   out << "theCompressionLookupTableId:                 " << theCompressionLookupTableId << endl
+       << "theNumberOfCompressionLookupRecords:         " << theNumberOfCompressionLookupRecords << endl
+       << "theNumberOfValuesPerCompressionLookupRecord: " << theNumberOfValuesPerCompressionLookupRecord << endl
+       << "theCompressionLookupValueBitLength:          " << theCompressionLookupValueBitLength << endl
+       << "theCompressionLookupTableOffset:             " << theCompressionLookupTableOffset;
+}
+
+void ossimRpfCompressionLookupOffsetRecord::clearFields()
+{
+   theCompressionLookupTableId                  = 0;
+   theNumberOfCompressionLookupRecords          = 0;
+   theNumberOfValuesPerCompressionLookupRecord  = 0;
+   theCompressionLookupValueBitLength           = 0;
+   theCompressionLookupTableOffset              = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionLookupOffsetRecord.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionLookupOffsetRecord.h
new file mode 100644
index 0000000000..5230b33eae
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionLookupOffsetRecord.h
@@ -0,0 +1,48 @@
+#ifndef ossimRpfCompressionLookupOffsetRecord_HEADER
+#define ossimRpfCompressionLookupOffsetRecord_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimConstants.h"
+#include "base/context/ossimErrorContext.h"
+
+class ossimRpfCompressionLookupOffsetRecord
+{
+public:
+   friend ostream& operator <<(ostream &out,
+                               const ossimRpfCompressionLookupOffsetRecord& data);
+   ossimRpfCompressionLookupOffsetRecord();
+   ossimErrorCode parseStream(istream& in,
+                              ossimByteOrder byteOrder);
+   void print(ostream& out)const;
+   ossim_uint16 getCompressionLookupTableId()const
+      {
+         return theCompressionLookupTableId;
+      }
+   ossim_uint32 getNumberOfCompressionLookupRecords()const
+      {
+         return theNumberOfCompressionLookupRecords;
+      }
+   ossim_uint16 getNumberOfValuesPerCompressionLookupRecord()const
+      {
+         return theNumberOfValuesPerCompressionLookupRecord;
+      }
+   ossim_uint16 getCompressionLookupValueBitLength()const
+      {
+         return theCompressionLookupValueBitLength;
+      }
+   ossim_uint32 getCompressionLookupTableOffset()const
+      {
+         return theCompressionLookupTableOffset;
+      }
+   
+private:
+   void clearFields();
+   
+   ossim_uint16 theCompressionLookupTableId;
+   ossim_uint32 theNumberOfCompressionLookupRecords;
+   ossim_uint16 theNumberOfValuesPerCompressionLookupRecord;
+   ossim_uint16 theCompressionLookupValueBitLength;
+   ossim_uint32 theCompressionLookupTableOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSection.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSection.cpp
new file mode 100644
index 0000000000..4670fb02d7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSection.cpp
@@ -0,0 +1,202 @@
+#include "ossimRpfCompressionSection.h"
+#include "ossimRpfCompressionSectionSubheader.h"
+#include "ossimRpfCompressionLookupOffsetRecord.h"
+#include <string.h> // for memset
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+ostream& operator<<(ostream& out,
+                    const ossimRpfCompressionOffsetTableData& data)
+{
+   unsigned long size = (data.theNumberOfValuesPerLookup*data.theNumberOfLookupValues*
+                         data.theCompressionLookupValueBitLength)/8;
+   
+   out << "theTableId:                         " << data.theTableId << endl
+       << "theNumberOfLookupValues:            " << data.theNumberOfLookupValues << endl
+       << "theCompressionLookupValueBitLength: " << data.theCompressionLookupValueBitLength << endl
+       << "theNumberOfValuesPerLookup:         " << data.theNumberOfValuesPerLookup << endl
+       << "Data Size in bytes:                 "
+       << size;
+
+   return out;
+}
+
+
+ossimRpfCompressionOffsetTableData::ossimRpfCompressionOffsetTableData()
+   :theTableId(0),
+    theNumberOfLookupValues(0),
+    theCompressionLookupValueBitLength(0),
+    theNumberOfValuesPerLookup(0),
+    theData(NULL)
+{
+}
+
+ossimRpfCompressionOffsetTableData::ossimRpfCompressionOffsetTableData(
+   const ossimRpfCompressionOffsetTableData& rhs)
+   :theNumberOfLookupValues(0),
+    theCompressionLookupValueBitLength(0),
+    theNumberOfValuesPerLookup(0),
+    theData(NULL)
+{
+   *this = rhs;
+}
+
+const ossimRpfCompressionOffsetTableData& ossimRpfCompressionOffsetTableData::operator = (
+   const ossimRpfCompressionOffsetTableData& rhs)
+{
+   if(this != &rhs)
+   {
+      if(theData)
+      {
+         delete theData;
+         theData = NULL;
+      }
+
+      if(rhs.theData)
+      {
+         theTableId                         = rhs.theTableId;
+         theNumberOfLookupValues            = rhs.theNumberOfLookupValues;
+         theCompressionLookupValueBitLength = rhs.theCompressionLookupValueBitLength;
+         theNumberOfValuesPerLookup         = rhs.theNumberOfValuesPerLookup;
+         
+         unsigned long size = (theNumberOfValuesPerLookup*
+                               theNumberOfLookupValues*
+                               theCompressionLookupValueBitLength)/8;
+         if(size > 0)
+         {
+            theData = new unsigned char[size];
+            memcpy(theData, rhs.theData, size);
+         }
+      }
+      else
+      {
+         theTableId = 0;
+         theNumberOfLookupValues = 0;
+         theCompressionLookupValueBitLength = 0;
+         theNumberOfValuesPerLookup = 0;
+      }
+   }
+   
+   return *this;
+}
+
+ossimRpfCompressionOffsetTableData::~ossimRpfCompressionOffsetTableData()
+{
+   if(theData)
+   {
+      delete theData;
+      theData = NULL;
+   }
+}
+
+
+ostream& operator << (ostream& out,
+                      const ossimRpfCompressionSection& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfCompressionSection::ossimRpfCompressionSection()
+   :theSubheader(NULL)
+{
+   theSubheader = new ossimRpfCompressionSectionSubheader;
+}
+
+ossimRpfCompressionSection::~ossimRpfCompressionSection()
+{
+   if(theSubheader)
+   {
+      delete theSubheader;
+      theSubheader = NULL;
+   }
+}
+
+ossimErrorCode ossimRpfCompressionSection::parseStream(istream& in,
+                                                       ossimByteOrder byteOrder)
+{
+   ossimErrorCode result = ossimErrorCodes::OSSIM_OK;
+   
+   if(in&&theSubheader)
+   {
+      result = theSubheader->parseStream(in, byteOrder);
+
+      if(result == ossimErrorCodes::OSSIM_OK)
+      {
+         ossimEndian anEndian;
+         ossimRpfCompressionLookupOffsetRecord record;
+         
+         in.read((char*)&theCompressionLookupOffsetTableOffset, 4);
+         in.read((char*)&theCompressionLookupTableOffsetRecordLength, 2);
+         
+         if(byteOrder != anEndian.getSystemEndianType())
+         {
+            anEndian.swap(theCompressionLookupOffsetTableOffset);
+            anEndian.swap(theCompressionLookupTableOffsetRecordLength);
+         }
+
+         if(theSubheader->getNumberOfCompressionLookupOffsetRecords() > 0)
+         {
+            // clear the table
+            theTable.clear();
+
+            // resize it
+            theTable.resize(theSubheader->getNumberOfCompressionLookupOffsetRecords());
+            
+            // now populate it
+            for(long index = 0;
+                index < theSubheader->getNumberOfCompressionLookupOffsetRecords();
+                ++index)
+            {
+               record.parseStream(in, byteOrder);
+               unsigned long rememberLocation = in.tellg();
+               in.seekg(record.getCompressionLookupTableOffset()+
+                        theSubheader->getEndOffset(), ios::beg);
+
+               theTable[index].theTableId                            = record.getCompressionLookupTableId();
+               theTable[index].theNumberOfLookupValues               = record.getNumberOfCompressionLookupRecords();
+               theTable[index].theCompressionLookupValueBitLength    = record.getCompressionLookupValueBitLength();
+               theTable[index].theNumberOfValuesPerLookup            = record.getNumberOfValuesPerCompressionLookupRecord();
+               
+               // store the information about this compress/decompress algorithm
+               // I am not sure but I will assume that the bit length can be
+               // arbitrary.  In other words if someone says that the bit length of
+               // the lookup value is 12 this should be handled ok.
+               //
+               unsigned long size = (theTable[index].theNumberOfValuesPerLookup*
+                                     theTable[index].theNumberOfLookupValues*
+                                     theTable[index].theCompressionLookupValueBitLength)/8;
+               
+               theTable[index].theData = new unsigned char[size];
+
+               in.read( (char*)theTable[index].theData, size);
+               
+               in.seekg(rememberLocation, ios::beg);
+            }
+         }
+      }
+   }
+   else
+   {
+      result = ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return result;
+}
+
+void ossimRpfCompressionSection::print(ostream& out)const
+{
+   if(theSubheader)
+   {
+      out << *theSubheader << endl;
+      copy(theTable.begin(),
+           theTable.end(),
+           ostream_iterator<ossimRpfCompressionOffsetTableData>(out, "\n"));
+   }
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSection.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSection.h
new file mode 100644
index 0000000000..6cc08facdd
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSection.h
@@ -0,0 +1,57 @@
+#ifndef ossimRpfCompressionSection_HEADER
+#define ossimRpfCompressionSection_HEADER
+#include <iostream>
+#include <vector>
+#include <iterator>
+using namespace std;
+#include "base/context/ossimErrorContext.h"
+#include "base/common/ossimConstants.h"
+
+class ossimRpfCompressionSectionSubheader;
+
+struct ossimRpfCompressionOffsetTableData
+{
+   friend ostream& operator<<(ostream& out,
+                              const ossimRpfCompressionOffsetTableData& data);
+   ossimRpfCompressionOffsetTableData();
+   ossimRpfCompressionOffsetTableData(const ossimRpfCompressionOffsetTableData& rhs);
+   ~ossimRpfCompressionOffsetTableData();
+   const ossimRpfCompressionOffsetTableData& operator =(const ossimRpfCompressionOffsetTableData& rhs);
+   
+   ossim_uint16 theTableId;
+   ossim_uint32 theNumberOfLookupValues;
+   ossim_uint16 theCompressionLookupValueBitLength;
+   ossim_uint16 theNumberOfValuesPerLookup;
+   ossim_uint8* theData;
+};
+
+class ossimRpfCompressionSection
+{
+public:
+   friend ostream& operator << (ostream& out,
+                                const ossimRpfCompressionSection& data);
+   ossimRpfCompressionSection();
+   virtual ~ossimRpfCompressionSection();
+   ossimErrorCode parseStream(istream& in,
+                              ossimByteOrder byteOrder);
+   void print(ostream& out)const;
+   const vector<ossimRpfCompressionOffsetTableData>& getTable()const
+      {
+         return theTable;
+      }
+   const ossimRpfCompressionSectionSubheader* getSubheader()const
+   {
+      return theSubheader;
+   }
+private:
+   void clearTable();
+   
+   ossimRpfCompressionSectionSubheader* theSubheader;
+   
+   ossim_uint32 theCompressionLookupOffsetTableOffset;
+   ossim_uint16 theCompressionLookupTableOffsetRecordLength;
+
+   vector<ossimRpfCompressionOffsetTableData> theTable;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSectionSubheader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSectionSubheader.cpp
new file mode 100644
index 0000000000..a354ecc8c8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSectionSubheader.cpp
@@ -0,0 +1,62 @@
+#include "ossimRpfCompressionSectionSubheader.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ossimRpfCompressionSectionSubheader::ossimRpfCompressionSectionSubheader()
+{
+   clearFields();
+}
+
+ostream& operator<<(ostream& out,
+                    const ossimRpfCompressionSectionSubheader& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimErrorCode ossimRpfCompressionSectionSubheader::parseStream(istream& in,
+                                                                ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      theStartOffset = in.tellg();
+      
+      in.read((char*)&theCompressionAlgorithmId, 2);
+      in.read((char*)&theNumberOfCompressionLookupOffsetRecords, 2);
+      in.read((char*)&theNumberOfCompressionParameterOffsetRecords, 2);
+
+      theEndOffset = in.tellg();
+      
+      ossimEndian anEndian;
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theCompressionAlgorithmId);
+         anEndian.swap(theNumberOfCompressionLookupOffsetRecords);
+         anEndian.swap(theNumberOfCompressionParameterOffsetRecords);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+   
+void ossimRpfCompressionSectionSubheader::print(ostream& out)const
+{
+   out << "theCompressionAlgorithmId:                    " << theCompressionAlgorithmId << endl
+       << "theNumberOfCompressionLookupOffsetRecords:    " << theNumberOfCompressionLookupOffsetRecords << endl
+       << "theNumberOfCompressionParameterOffsetRecords: " << theNumberOfCompressionParameterOffsetRecords;
+}
+
+void ossimRpfCompressionSectionSubheader::clearFields()
+{
+   theStartOffset                               = 0;
+   theEndOffset                                 = 0;
+   theCompressionAlgorithmId                    = 0;
+   theNumberOfCompressionLookupOffsetRecords    = 0;
+   theNumberOfCompressionParameterOffsetRecords = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSectionSubheader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSectionSubheader.h
new file mode 100644
index 0000000000..b7f5a2cec6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCompressionSectionSubheader.h
@@ -0,0 +1,63 @@
+#ifndef ossimRpfCompressionSectionSubheader_HEADER
+#define ossimRpfCompressionSectionSubheader_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimRpfCompressionSectionSubheader
+{
+public:
+   friend ostream& operator<<(ostream& out,
+                              const ossimRpfCompressionSectionSubheader& data);
+   ossimRpfCompressionSectionSubheader();
+   virtual ~ossimRpfCompressionSectionSubheader(){}
+
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+
+   unsigned long getStartOffset()const{return theStartOffset;}
+   unsigned long getEndOffset()const{return theEndOffset;}
+   unsigned short getCompressionAlgorithmId()const
+      {
+         return theCompressionAlgorithmId;
+      }
+   unsigned short getNumberOfCompressionLookupOffsetRecords()const
+      {
+         return theNumberOfCompressionLookupOffsetRecords;
+      }
+   unsigned short getNumberOfCompressionParameterOffsetRecords()const
+      {
+         return theNumberOfCompressionParameterOffsetRecords;
+      }
+   void print(ostream& out)const;
+   
+private:
+   void clearFields();
+
+   /*!
+    * helper varible that holds the starting absolute
+    * offset to the start of the this data.
+    */
+   unsigned long theStartOffset;
+
+   /*!
+    * helper varible that holds the starting absolute
+    * offset to the end of the this data.
+    */
+   unsigned long theEndOffset;
+   /*!
+    * Current ids are:
+    *
+    * 1  VQ
+    * 2 Jpeg Lossless
+    */
+   unsigned short theCompressionAlgorithmId;
+
+   unsigned short theNumberOfCompressionLookupOffsetRecords;
+
+   unsigned short theNumberOfCompressionParameterOffsetRecords;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfConstants.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfConstants.h
new file mode 100644
index 0000000000..065f92103c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfConstants.h
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// 
+//********************************************************************
+// $Id: ossimRpfConstants.h,v 1.1 2003/05/08 15:39:23 gpotts Exp $
+//
+#ifndef ossimRpfComponentId_HEADER
+#define ossimRpfComponentId_HEADER
+
+const unsigned long OSSIM_RPF_ULONG_NULL = 0xFFFFFFFF;
+
+enum ossimRpfComponentId
+{
+   OSSIM_RPF_HEADER_COMPONENT   = 128,
+   OSSIM_RPF_LOCATION_COMPONENT = 129,
+   OSSIM_RPF_COVERAGE_SECTION_SUBHEADER = 130,
+   OSSIM_RPF_COMPRESSION_SECTION_SUBHEADER = 131,
+   OSSIM_RPF_COMPRESION_LOOKUP_SUBSECTION = 132,
+   OSSIM_RPF_COMPRESION_PARAMETER_SUBSECTION = 133,
+   OSSIM_RPF_COLOR_GRAYSCALE_SECTION_SUBHEADER = 134,
+   OSSIM_RPF_COLORMAP_SUBSECTION = 135,
+   OSSIM_RPF_IMAGE_DESCRIPTION_SUBHEADER = 136,
+   OSSIM_RPF_IMAGE_DISPLAY_PARAMETERS_SUBHEADER = 137,
+   OSSIM_RPF_MASK_SUBSECTION = 138,
+   OSSIM_RPF_COLOR_CONVERTER_SUBSECTION = 139,
+   OSSIM_RPF_SPATIAL_DATA_SUBSECTION = 140,
+   OSSIM_RPF_ATTRIBUTE_SECTION_SUBHEADER = 141,
+   OSSIM_RPF_ATTRIBUTE_SUBSECTION = 142,
+   OSSIM_RPF_EXPLICIT_AREAL_COVERAGE_TABLE = 143,
+   OSSIM_RPF_RELATED_IMAGES_SECTION_SUBHEADER = 144,
+   OSSIM_RPF_RELATED_IMAGES_SUBSECTION = 145,
+   OSSIM_RPF_REPLACE_UPDATE_SECTION_SUBHEADER = 146,
+   OSSIM_RPF_REPLACE_UPDATE_TABLE = 147,
+   OSSIM_RPF_BOUNDARY_RECT_SECTION_SUBHEADER = 148,
+   OSSIM_RPF_BOUNDARY_RECT_TABLE = 149,
+   OSSIM_RPF_FRAME_FILE_INDEX_SECTION_SUBHEADER = 150,
+   OSSIM_RPF_FRAME_FILE_INDEX_SUBSECTION = 151,
+   OSSIM_RPF_COLOR_TABLE_INDEX_SECTION_SUBHEADER = 152,
+   OSSIM_RPF_COLOR_TABLE_INDEX_RECORD = 153
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCoverageSection.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCoverageSection.cpp
new file mode 100644
index 0000000000..aa5d903149
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCoverageSection.cpp
@@ -0,0 +1,115 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfCoverageSection.cpp,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#include "ossimRpfCoverageSection.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream &out,
+                     const ossimRpfCoverageSection &data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfCoverageSection::ossimRpfCoverageSection()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfCoverageSection::parseStream(istream &in, ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      ossimEndian anEndian;
+
+
+      in.read((char*)&theUpperLeftLat,  8);
+      in.read((char*)&theUpperLeftLon,  8);
+      in.read((char*)&theLowerLeftLat,  8);
+      in.read((char*)&theLowerLeftLon,  8);
+      in.read((char*)&theUpperRightLat, 8);
+      in.read((char*)&theUpperRightLon, 8);
+      in.read((char*)&theLowerRightLat, 8);
+      in.read((char*)&theLowerRightLon, 8);
+      in.read((char*)&theVerticalResolution,   8);
+      in.read((char*)&theHorizontalResolution, 8);
+      in.read((char*)&theVerticalInterval,     8);
+      in.read((char*)&theHorizontalInterval,   8);
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theUpperLeftLat);
+         anEndian.swap(theUpperLeftLon);
+         anEndian.swap(theLowerLeftLat);
+         anEndian.swap(theLowerLeftLon);
+         anEndian.swap(theUpperRightLat);
+         anEndian.swap(theUpperRightLon);
+         anEndian.swap(theLowerRightLat);
+         anEndian.swap(theLowerRightLon);
+         anEndian.swap(theVerticalResolution);
+         anEndian.swap(theHorizontalResolution);
+         anEndian.swap(theVerticalInterval);
+         anEndian.swap(theHorizontalInterval);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfCoverageSection::print(ostream &out)const
+{
+   out << "theUpperLeftLat:         " << theUpperLeftLat << endl
+       << "theUpperLeftLon:         " << theUpperLeftLon << endl
+       << "theLowerLeftLat:         " << theLowerLeftLat << endl
+       << "theLowerLeftLon:         " << theLowerLeftLon << endl
+       << "theUpperRightLat:        " << theUpperRightLat << endl
+       << "theUpperRightLon:        " << theUpperRightLon << endl
+       << "theLowerRightLat:        " << theLowerRightLat << endl
+       << "theLowerRightLon:        " << theLowerRightLon << endl
+       << "theVerticalResolution:   " << theVerticalResolution << endl
+       << "theHorizontalResolution: " << theHorizontalResolution << endl
+       << "theVerticalInterval:     " << theVerticalInterval << endl
+       << "theHorizontalInterval:   " << theHorizontalInterval;
+}
+
+void ossimRpfCoverageSection::clearFields()
+{
+   theUpperLeftLat  = 0.0;
+   theUpperLeftLon  = 0.0;
+   theLowerLeftLat  = 0.0;
+   theLowerLeftLon  = 0.0;
+   theUpperRightLat = 0.0;
+   theUpperRightLon = 0.0;
+   theLowerRightLat = 0.0;
+   theLowerRightLon = 0.0;
+   theVerticalResolution   = 0.0;
+   theHorizontalResolution = 0.0;
+   theVerticalInterval     = 0.0;
+   theHorizontalInterval   = 0.0;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCoverageSection.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCoverageSection.h
new file mode 100644
index 0000000000..b82356706e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfCoverageSection.h
@@ -0,0 +1,118 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfCoverageSection.h,v 1.3 2003/05/13 11:31:10 dburken Exp $
+#ifndef ossimRpfCoverageSection_HEADER
+#define ossimRpfCoverageSection_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "ossimRpfConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimRpfCoverageSection
+{
+public:
+   friend ostream& operator <<(ostream &out,
+                               const ossimRpfCoverageSection &data);
+   
+   ossimRpfCoverageSection();
+   virtual ~ossimRpfCoverageSection(){}
+   ossim_int32 parseStream(istream &in, ossimByteOrder byteOrder);
+   virtual void print(ostream &out)const;
+   void clearFields();
+
+   bool isGeographicRectNull()const
+      {
+         return ((theUpperLeftLat  == OSSIM_RPF_ULONG_NULL) &&
+                 (theUpperLeftLon  == OSSIM_RPF_ULONG_NULL) &&
+                 (theLowerLeftLat  == OSSIM_RPF_ULONG_NULL) &&
+                 (theLowerLeftLon  == OSSIM_RPF_ULONG_NULL) &&
+                 (theLowerRightLat == OSSIM_RPF_ULONG_NULL) &&
+                 (theLowerRightLon == OSSIM_RPF_ULONG_NULL) &&
+                 (theUpperRightLat == OSSIM_RPF_ULONG_NULL) &&
+                 (theUpperRightLon == OSSIM_RPF_ULONG_NULL));
+      }
+   bool isIntervalNull()const
+      {
+         return ((theVerticalInterval   == OSSIM_RPF_ULONG_NULL)&&
+                 (theHorizontalInterval == OSSIM_RPF_ULONG_NULL));
+      }
+   double getUlLat()const{return theUpperLeftLat;}
+   double getUlLon()const{return theUpperLeftLon;}
+   double getLlLat()const{return theLowerLeftLat;}
+   double getLlLon()const{return theLowerLeftLon;}
+   double getLrLat()const{return theLowerRightLat;}
+   double getLrLon()const{return theLowerRightLon;}
+   double getUrLat()const{return theUpperRightLat;}
+   double getUrLon()const{return theUpperRightLon;}
+
+   double getVerticalResolution()const{return theVerticalResolution;}
+   double getHorizontalResolution()const{return theHorizontalResolution;}
+
+   /*!
+    * This indicates the lat increment per pixel in degrees.
+    */
+   double getVerticalInterval()const{return theVerticalInterval;}
+
+   /*!
+    * This indicates the lon increment per pixel in degrees.
+    */
+   double getHorizontalInterval()const{return theHorizontalInterval;}
+   
+private:   
+   /*!
+    * 8 byte double and is the upper left lat or
+    * North West portion of the image.
+    */
+   double theUpperLeftLat;
+
+   /*!
+    * 8 byte double and is the upper left lon
+    * (North west)
+    */
+   double theUpperLeftLon;
+
+   double theLowerLeftLat;
+   double theLowerLeftLon;
+
+   double theUpperRightLat;
+   double theUpperRightLon;
+
+   double theLowerRightLat;
+   double theLowerRightLon;
+
+   /*!
+    *
+    */
+   double theVerticalResolution;
+
+   double theHorizontalResolution;
+
+   double theVerticalInterval;
+
+   double theHorizontalInterval;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrame.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrame.cpp
new file mode 100644
index 0000000000..651dfbc56c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrame.cpp
@@ -0,0 +1,1022 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              rpf file.
+//
+//********************************************************************
+// $Id: ossimRpfFrame.cpp,v 1.9 2005/08/22 14:58:35 gpotts Exp $
+#include <support_data/rpf/ossimRpfFrame.h>
+#include <support_data/rpf/ossimRpfHeader.h>
+#include <support_data/rpf/ossimRpfAttributes.h>
+#include <support_data/rpf/ossimRpfAttributeOffsetRecord.h>
+#include <support_data/rpf/ossimRpfAttributeSectionSubheader.h>
+#include <support_data/rpf/ossimRpfCoverageSection.h>
+#include <support_data/rpf/ossimRpfImageDescriptionSubheader.h>
+#include <support_data/rpf/ossimRpfImageDisplayParameterSubheader.h>
+#include <support_data/rpf/ossimRpfMaskSubheader.h>
+#include <support_data/rpf/ossimRpfCompressionSection.h>
+#include <support_data/rpf/ossimRpfColorGrayscaleSubheader.h>
+#include <support_data/rpf/ossimRpfColorGrayscaleOffsetRecord.h>
+#include <support_data/rpf/ossimRpfColorConverterSubsection.h>
+#include <support_data/rpf/ossimRpfColorConverterTable.h>
+#include <support_data/rpf/ossimRpfColorGrayscaleTable.h>
+#include <support_data/rpf/ossimRpfLocationSection.h>
+#include <support_data/rpf/ossimRpfColorConverterSubsection.h>
+#include <support_data/rpf/ossimRpfConstants.h>
+#include <support_data/nitf/ossimNitfFile.h>
+#include <support_data/nitf/ossimNitfFileHeader.h>
+#include <support_data/nitf/ossimNitfTagInformation.h>
+#include <base/misc/ossimEndian.h>
+#include <base/common/ossimErrorCodes.h>
+#include <base/common/ossimTrace.h>
+
+static const ossimTrace traceDebug("ossimRpfFrame:debug");
+
+ostream& operator <<(std::ostream& out,
+                     const ossimRpfFrame& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfFrame::ossimRpfFrame()
+   :theHeader(NULL),
+    theFilename(""),
+    theCoverage(NULL),
+    theAttributes(NULL),
+    theImageDescriptionSubheader(NULL),
+    theMaskSubheader(NULL),
+    theImageDisplayParameterSubheader(NULL),
+    theCompressionSection(NULL),
+    theColorGrayscaleSubheader(NULL),
+    theColorConverterSubsection(NULL)
+{
+}
+
+ossimRpfFrame::~ossimRpfFrame()
+{
+   deleteAll();
+}
+
+void ossimRpfFrame::print(ostream& out)const
+{
+   if(theHeader)
+   {
+      out << *theHeader << endl;
+   }
+
+   if(theAttributes)
+   {
+      out << *theAttributes << endl;
+   }
+   if(theCoverage)
+   {
+      out << *theCoverage << endl;
+   }
+   if(theImageDescriptionSubheader)
+   {
+      out << *theImageDescriptionSubheader << endl;
+   }
+   if(theMaskSubheader)
+   {
+      out << *theMaskSubheader << endl;
+   }
+   if(theImageDisplayParameterSubheader)
+   {
+      out << *theImageDisplayParameterSubheader << endl;
+   }
+   if(theCompressionSection)
+   {
+      out << *theCompressionSection << endl;
+   }
+   if(theColorGrayscaleSubheader)
+   {
+      out << *theColorGrayscaleSubheader << endl;
+   }
+   if(theColorConverterSubsection)
+   {
+      out << *theColorConverterSubsection << endl;
+   }
+
+   copy(theColorGrayscaleTable.begin(),
+        theColorGrayscaleTable.end(),
+        ostream_iterator<ossimRpfColorGrayscaleTable>(out, "\n"));
+
+   if(theImageDescriptionSubheader&&
+      !(theImageDescriptionSubheader->isSubframeMaskTableOffsetNull()))
+   {
+      out << "Subframe Mask Table:" << endl;
+      unsigned long spectralIndex;
+      unsigned long rowIndex;
+      unsigned long colIndex;
+      // first loop through the Mask table and allocate while we do it
+      for(spectralIndex = 0;
+          spectralIndex < theImageDescriptionSubheader->getNumberOfSpectralGroups();
+          ++spectralIndex)
+      {
+         for(rowIndex = 0;
+             rowIndex < theImageDescriptionSubheader->getNumberOfSubframesVertical();
+             ++rowIndex)
+         {
+            for(colIndex = 0;
+                colIndex < theImageDescriptionSubheader->getNumberOfSubframesHorizontal();
+                ++colIndex)
+            {
+               if( theSubframeMaskTable[spectralIndex][rowIndex][colIndex] == OSSIM_RPF_ULONG_NULL)
+               {
+                  out << "NULL ";
+               }
+               else
+               {
+                  out << theSubframeMaskTable[spectralIndex][rowIndex][colIndex] << " ";
+               }
+            }
+            out << endl;
+         }
+      }
+   }
+
+   if(theImageDescriptionSubheader&&
+      !(theImageDescriptionSubheader->isTransparencyMaskTableOffsetNull()))
+   {
+      out << "Transparency Mask Table:" << endl;
+      unsigned long spectralIndex;
+      unsigned long rowIndex;
+      unsigned long colIndex;
+      // first loop through the Mask table and allocate while we do it
+      for(spectralIndex = 0;
+          spectralIndex < theImageDescriptionSubheader->getNumberOfSpectralGroups();
+          ++spectralIndex)
+      {
+         for(rowIndex = 0;
+             rowIndex < theImageDescriptionSubheader->getNumberOfSubframesVertical();
+             ++rowIndex)
+         {
+            for(colIndex = 0;
+                colIndex < theImageDescriptionSubheader->getNumberOfSubframesHorizontal();
+                ++colIndex)
+            {
+               if( theSubframeTransparencyMaskTable[spectralIndex][rowIndex][colIndex] == OSSIM_RPF_ULONG_NULL)
+               {
+                  out << "NULL ";
+               }
+               else
+               {
+                  out << theSubframeTransparencyMaskTable[spectralIndex][rowIndex][colIndex] << " ";
+               }
+            }
+            out << endl;
+         }
+      }
+   }
+
+}
+
+
+ossimErrorCode ossimRpfFrame::parseFile(const ossimFilename& filename)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfFrame::parseFile: entered......" << std::endl;
+   }
+   ossimErrorCode result = ossimErrorCodes::OSSIM_OK;
+
+   //Make sure any fileds have beend cleared
+   clearFields();
+
+   // Make sure all data is deleted.  The initialize call the
+   // populate methods.  These methods will re-allocate the information
+   deleteAll();
+
+
+   ossimNitfFile *nitfFile = new ossimNitfFile;
+   nitfFile->parseFile(filename);
+   
+   const ossimNitfFileHeader* nitfFileHeader = nitfFile->getHeader();
+      
+   if(!nitfFileHeader)
+   {
+      delete nitfFile;
+      nitfFile = NULL;
+      
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   ossimNitfTagInformation info;
+   nitfFileHeader->getTag(info, "RPFHDR");
+      
+   // we no longer need access to the nitf header.  We got what we needed
+   delete nitfFile;
+   nitfFile = NULL;
+   
+   theFilename = filename;
+   if(info.getTagName() == "RPFHDR")
+   {
+      ifstream in(filename.c_str(), ios::in|ios::binary);
+      // set the get pointer for the stream to the start
+      // of the Rpf header data
+      in.seekg(info.getTagDataOffset(), ios::beg);
+
+      if(theHeader) delete theHeader;
+      theHeader = new ossimRpfHeader;
+      
+      if(theHeader->parseStream(in) != ossimErrorCodes::OSSIM_OK)
+      {
+         deleteAll();
+         
+         return ossimErrorCodes::OSSIM_ERROR;
+      }
+      
+      if(!in.fail()&&theHeader)
+      {
+         result = populateAttributeSection(in);
+         if(!in.fail()&&(result == ossimErrorCodes::OSSIM_OK))
+         {
+            populateCompressionSection(in);
+         }
+         if(!in.fail()&&(result == ossimErrorCodes::OSSIM_OK))
+         {
+            result = populateCoverageSection(in);
+         }
+         if(!in.fail()&&(result == ossimErrorCodes::OSSIM_OK))
+         {
+            result = populateImageSection(in);
+         }
+         if(!in.fail()&&(result == ossimErrorCodes::OSSIM_OK))
+         {
+            result = populateColorGrayscaleSection(in);
+         }
+         if(!in.fail()&&(result == ossimErrorCodes::OSSIM_OK))
+         {
+            result = populateMasks(in);
+         }
+      }
+      else
+      {
+         return ossimErrorCodes::OSSIM_ERROR;
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+bool ossimRpfFrame::hasSubframeMaskTable()const
+{
+   if(theImageDescriptionSubheader)
+   {
+      return (!theImageDescriptionSubheader->isSubframeMaskTableOffsetNull());
+   }
+
+   return false;
+          
+}
+
+bool ossimRpfFrame::fillSubFrameBuffer(ossim_uint8* buffer,
+                                       ossim_uint32 spectralGroup,
+                                       ossim_uint32 row,
+                                       ossim_uint32 col)const
+{
+   if(theImageDescriptionSubheader &&
+      theImageDisplayParameterSubheader&&
+      theHeader&&
+      (col < theImageDescriptionSubheader->getNumberOfSubframesHorizontal()) &&
+      (row < theImageDescriptionSubheader->getNumberOfSubframesVertical()))
+   {
+      ossimRpfComponentLocationRecord info;
+      
+      if(!theHeader->getLocationSection().getComponent(OSSIM_RPF_SPATIAL_DATA_SUBSECTION, info))
+      {
+         return false;
+      }
+      
+      ossim_uint32 offset = info.theComponentLocation;
+      ossim_uint32 bytesPerSubframe = 0;
+
+      // note that the code length is bit encoded so we must devide by 8
+      // in order to get the byte offset instead of the bit offset.  We
+      // then add that to the start of the spatial data section which is
+      // the current value of offset.
+      bytesPerSubframe = (theImageDisplayParameterSubheader->getNumberOfImageRows()*
+                          theImageDisplayParameterSubheader->getNumberOfImageCodesPerRow()*
+                          theImageDisplayParameterSubheader->getImageCodeLength())/8;
+      
+         
+      if(hasSubframeMaskTable())
+      {
+         // check to see if the offset is NULL.  If it is
+         // then just return false to let the caller know that the
+         // buffer did not exist.
+         if(theSubframeMaskTable[0][row][col] != OSSIM_RPF_ULONG_NULL)
+         {
+            offset += theSubframeMaskTable[0][row][col];
+         }
+         else
+         {
+            return false;
+         }
+      }
+      else
+      {
+         ossim_uint32 bytes = bytesPerSubframe*(row*theImageDescriptionSubheader->getNumberOfSubframesHorizontal()+
+                                                col);
+         offset += bytes;
+      }
+      
+      // now since we have the adjustment and we got to this point then
+      // we can read in the data into the destination buffer.
+      ifstream in(theFilename.c_str(), ios::in|ios::binary);
+      if(!in.fail())
+      {
+         in.seekg(offset, ios::beg);
+         in.read((char*)buffer, bytesPerSubframe);
+         if(in.fail())
+         {
+            return false;
+         }
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      // this is if it was not within the rows and cols of
+      // the subframe or if the image description header didn't exist
+      return false;
+   }
+
+   return true;
+}
+
+void ossimRpfFrame::clearFields()
+{   
+   theFilename = "";
+}
+
+void ossimRpfFrame::deleteAll()
+{
+   if(theHeader)
+   {
+      delete theHeader;
+      theHeader = NULL;
+   }
+   if(theAttributes)
+   {
+      delete theAttributes;
+      theAttributes = NULL;
+   }
+   if(theCoverage)
+   {
+      delete theCoverage;
+      theCoverage = NULL;
+   }
+   if(theImageDescriptionSubheader)
+   {
+      delete theImageDescriptionSubheader;
+      theImageDescriptionSubheader = NULL;
+   }
+   if(theMaskSubheader)
+   {
+      delete theMaskSubheader;
+      theMaskSubheader = NULL;
+   }
+   if(theImageDisplayParameterSubheader)
+   {
+      delete theImageDisplayParameterSubheader;
+      theImageDisplayParameterSubheader = NULL;
+   }
+   if(theCompressionSection)
+   {
+      delete theCompressionSection;
+      theCompressionSection = NULL;
+   }
+   if(theColorGrayscaleSubheader)
+   {
+      delete theColorGrayscaleSubheader;
+      theColorGrayscaleSubheader = NULL;
+   }
+   if(theColorConverterSubsection)
+   {
+      delete theColorConverterSubsection;
+      theColorConverterSubsection = NULL;
+   }
+}
+
+ossimErrorCode ossimRpfFrame::populateCoverageSection(istream& in)
+{
+   if(theCoverage) delete theCoverage;
+   theCoverage = 0;
+   if(theHeader)
+   {
+      theCoverage = theHeader->getNewCoverageSection(in);
+   }
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+ossimErrorCode ossimRpfFrame::populateCompressionSection(istream& in)
+{
+   if(theCompressionSection) delete theCompressionSection;
+   theCompressionSection = 0;
+   if(theHeader)
+   {
+      theCompressionSection = theHeader->getNewCompressionSection(in);
+   }
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+ossimErrorCode ossimRpfFrame::populateColorGrayscaleSection(istream& in)
+{
+   ossimErrorCode resultError = ossimErrorCodes::OSSIM_OK;
+   if(theColorGrayscaleSubheader) delete theColorGrayscaleSubheader;
+   theColorGrayscaleSubheader = 0;
+   if(theHeader)
+   {
+      theColorGrayscaleSubheader  = theHeader->getNewColorGrayscaleSubheader(in);
+
+      if(theColorGrayscaleSubheader)
+      {
+         const ossimRpfLocationSection& location = theHeader->getLocationSection();
+         if(&location)
+         {
+            ossimRpfComponentLocationRecord component;
+            
+            if(location.getComponent(OSSIM_RPF_COLOR_CONVERTER_SUBSECTION,
+                                     component))
+            {
+               in.seekg(component.theComponentLocation,ios::beg);
+               if(theColorConverterSubsection) delete theColorConverterSubsection;
+               theColorConverterSubsection = new ossimRpfColorConverterSubsection;
+               theColorConverterSubsection->setNumberOfColorConverterOffsetRecords(
+                  theColorGrayscaleSubheader->getNumberOfColorConverterOffsetRecords());
+               resultError = theColorConverterSubsection->parseStream(in, theHeader->getByteOrder());
+            }
+            if(location.getComponent(OSSIM_RPF_COLORMAP_SUBSECTION,
+                                     component))
+            {
+               in.seekg(component.theComponentLocation, ios::beg);
+               
+               theColorGrayscaleTable.clear();
+               theColorGrayscaleTable.resize(theColorGrayscaleSubheader->getNumberOfColorGreyscaleOffsetRecords());
+
+               // we will ignore the offset table offset which is a 4 byte value
+               // and ignore the offset record length which is a 2 byte value.
+               // This is suppose to put us at the beginning of the
+               // [color/grayscale offset record].  The total number of
+               // these offset records is found in the [color/grayscale section
+               // subheader.
+               in.ignore(6);
+               for(ossim_uint32 index = 0;
+                   index < theColorGrayscaleSubheader->getNumberOfColorGreyscaleOffsetRecords();
+                   ++index)
+               {
+                  
+                  ossimRpfColorGrayscaleOffsetRecord grayscaleOffsetRecord;
+
+                  if(grayscaleOffsetRecord.parseStream(in, theHeader->getByteOrder()) == ossimErrorCodes::OSSIM_OK)
+                  {
+                     ossim_uint32 rememberLocation = in.tellg();
+                     in.seekg(grayscaleOffsetRecord.getColorGrayscaleTableOffset()+component.theComponentLocation, ios::beg);
+                     theColorGrayscaleTable[index].setTableData(grayscaleOffsetRecord.getColorGrayscaleTableId(),
+                                                                grayscaleOffsetRecord.getNumberOfColorGrayscaleRecords());
+                     theColorGrayscaleTable[index].parseStream(in, theHeader->getByteOrder());
+                     in.seekg(rememberLocation, ios::beg);
+                  }
+                  else
+                  {
+                     return ossimErrorCodes::OSSIM_ERROR;
+                  }
+               }
+            }
+         }
+      }
+   }
+   
+   return resultError;
+}
+
+ossimErrorCode ossimRpfFrame::populateImageSection(istream& in)
+{
+   ossimErrorCode result = ossimErrorCodes::OSSIM_OK;
+   if(theImageDescriptionSubheader) delete theImageDescriptionSubheader;
+   theImageDescriptionSubheader = 0;
+   if(theHeader&&in)
+   {
+      // get the subheader information.
+      theImageDescriptionSubheader = theHeader->getNewImageDescriptionSubheader(in);
+
+      
+      // need to do something with the table before going to the display.
+      if(theImageDescriptionSubheader &&(!theImageDescriptionSubheader->isSubframeMaskTableOffsetNull()))
+      {
+         if(theMaskSubheader) delete theMaskSubheader;
+         // need to get the mask subheader
+         theMaskSubheader = new ossimRpfMaskSubheader;
+
+         // seek to the start of the subheader
+         in.seekg(theImageDescriptionSubheader->getEndOffset() +
+                  theImageDescriptionSubheader->getSubframeMaskTableOffset(), ios::beg);
+
+         // get the information
+         result = theMaskSubheader->parseStream(in, theHeader->getByteOrder());
+      }
+
+      if(theImageDisplayParameterSubheader) delete theImageDisplayParameterSubheader;
+      // Get the display parameter header
+      theImageDisplayParameterSubheader = theHeader->getNewImageDisplayParameterSubheader(in);
+   }
+   return result;
+}
+
+ossimErrorCode ossimRpfFrame::populateAttributeSection(istream& in)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfFrame::populateAttributeSection:  entered ..." << std::endl;
+   }
+   ossimRpfAttributeSectionSubheader* temp = 0;
+   
+   const ossimRpfLocationSection& location = theHeader->getLocationSection();
+   if(&location)
+   {
+      ossimRpfComponentLocationRecord component;
+      
+      if(location.getComponent(OSSIM_RPF_ATTRIBUTE_SECTION_SUBHEADER,
+                               component))
+      {
+         temp = new ossimRpfAttributeSectionSubheader;
+         in.seekg(component.theComponentLocation, std::ios::beg);
+         if(temp->parseStream(in, theHeader->getByteOrder()) != ossimErrorCodes::OSSIM_OK)
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfFrame::populateAttributeSection:  leaving 1 ..." << std::endl;
+            }
+            return ossimErrorCodes::OSSIM_ERROR;
+         }
+      }
+   }
+   if(!in.fail()&&temp)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: Has attribute section" << std::endl;
+      }
+      if(theAttributes) delete theAttributes;
+      theAttributes = new ossimRpfAttributes;
+      ossimRpfAttributeOffsetRecord record;
+      ossim_uint64 locationAttributeSubsection = in.tellg();
+      ossim_uint64 absoluteAddresToTable = locationAttributeSubsection + temp->getAttributeOffsetTableOffset();
+      ossimEndian anEndian;
+
+      
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: Number of attributes = "
+                                             <<  temp->getNumberOfAttributeOffsetRecords()
+                                             << std::endl;
+      }
+      in.seekg(absoluteAddresToTable, ios::beg);
+      for(ossim_uint32 index = 0;
+          index < temp->getNumberOfAttributeOffsetRecords();
+          index++)
+      {
+         if((!in.fail())&&
+            record.parseStream(in, theHeader->getByteOrder()) ==
+            ossimErrorCodes::OSSIM_OK)
+         {
+            // make sure we save the current position.  The attribute
+            // parser in the switch/case will change the location and
+            // we must come back to the start of the next record.
+            ossim_uint64 currentLocation = in.tellg();
+
+            // go to the location of the start of the attribute.               
+            in.seekg(locationAttributeSubsection + record.getAttributeRecordOffset(), ios::beg);
+
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: Parsing attribute number  " << index
+                                                   << " with id = " << record.getAttributeId()
+                                                   << std::endl;
+            }
+            // allocate some temporary space for the string type
+            // attributes.
+            char tempString[50];
+            if(!theAttributes->getAttributeFlag(record.getAttributeId()))
+            {
+               theAttributes->setAttributeFlag(record.getAttributeId(), true);
+               switch(record.getAttributeId())
+               {
+               case 1:
+               {
+                  in.read((char*)tempString, 8);
+                  tempString[8] = '\0';
+                  theAttributes->theCurrencyDate = tempString;
+                  break;
+               }
+               case 2:
+               {
+                  in.read((char*)tempString, 8);
+                  tempString[8] = '\0';
+                  theAttributes->theProductionDate = tempString;
+                  break;
+               }
+               case 3:
+               {
+                  in.read((char*)tempString, 8);
+                  tempString[8] = '\0';
+                  theAttributes->theSignificantDate = tempString;
+                  break;
+               }
+               case 4:
+               {
+                  in.read((char*)tempString, 10);
+                  theAttributes->theChartSeriesCode = ossimString(tempString,
+                                                                  &tempString[10]);
+                  in.read((char*)tempString, 8);
+                  theAttributes->theMapDesignationCode = ossimString(tempString,
+                                                                     &tempString[8]);
+                  in.read((char*)tempString, 4);
+                  theAttributes->theOldHorDatum = ossimString(tempString,
+                                                              &tempString[4]);
+                  in.read((char*)tempString, 7);
+                  theAttributes->theEdition = ossimString(tempString,
+                                                          &tempString[7]);
+                  break;
+               }
+               case 5:
+               {
+                  in.read((char*)tempString, 2);
+                  theAttributes->theProjectionCode = ossimString(tempString,
+                                                                 &tempString[2]);
+                  theAttributes->theProjectionCode = theAttributes->theProjectionCode.upcase();
+                  if((theAttributes->theProjectionCode == "AC") ||
+                     (theAttributes->theProjectionCode == "LE") ||
+                     (theAttributes->theProjectionCode == "PG"))
+                  {
+                     in.read((char*)&(theAttributes->theProjectionA), 4);
+                     in.read((char*)&(theAttributes->theProjectionB), 4);
+                     in.read((char*)&(theAttributes->theProjectionC), 4);
+                     in.read((char*)&(theAttributes->theProjectionD), 4);
+                  }
+                  else if((theAttributes->theProjectionCode == "RB") ||
+                          (theAttributes->theProjectionCode == "OC") ||
+                          (theAttributes->theProjectionCode == "TC"))
+                  {
+                     in.read((char*)&(theAttributes->theProjectionA), 4);
+                     in.read((char*)&(theAttributes->theProjectionB), 4);
+                     in.read((char*)&(theAttributes->theProjectionC), 4);
+                  }
+                  else if((theAttributes->theProjectionCode == "AL") ||
+                          (theAttributes->theProjectionCode == "MC") ||
+                          (theAttributes->theProjectionCode == "OD") ||
+                          (theAttributes->theProjectionCode == "PH"))
+                  {
+                     in.read((char*)&(theAttributes->theProjectionA), 4);
+                     in.read((char*)&(theAttributes->theProjectionB), 4);
+                  }
+                  else if((theAttributes->theProjectionCode == "UT"))
+                  {
+                     in.read((char*)&(theAttributes->theProjectionA), 4);
+                  }
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theProjectionA);
+                     anEndian.swap(theAttributes->theProjectionB);
+                     anEndian.swap(theAttributes->theProjectionC);
+                     anEndian.swap(theAttributes->theProjectionD);
+                  }
+                  break;
+               }
+               case 6:
+               {
+                  in.read((char*)tempString, 4);
+                  theAttributes->theVertDatumCode = ossimString(tempString,
+                                                                &tempString[4]);
+                  break;
+               }
+               case 7:
+               {
+                  in.read((char*)tempString, 4);
+                  theAttributes->theHorDatumCode = ossimString(tempString,
+                                                               &tempString[4]);
+                  break;
+               }
+               case 8:
+               {
+                  in.read((char*)&(theAttributes->theVertAbsAccuracy), 4);
+                  in.read((char*)&(theAttributes->theVertAbsUnits), 2);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theVertAbsAccuracy);
+                     anEndian.swap(theAttributes->theVertAbsUnits);
+                  }
+                  break;
+               }
+               case 9:
+               {
+                  in.read((char*)&(theAttributes->theHorAbsAccuracy), 4);
+                  in.read((char*)&(theAttributes->theHorAbsUnits), 2);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theHorAbsAccuracy);
+                     anEndian.swap(theAttributes->theHorAbsUnits);
+                  }
+                  break;
+               }
+               case 10:
+               {
+                  in.read((char*)&(theAttributes->theVertRelAccuracy), 4);
+                  in.read((char*)&(theAttributes->theVertRelUnits), 2);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theVertRelAccuracy);
+                     anEndian.swap(theAttributes->theVertRelUnits);
+                  }
+                  break;
+               }
+               case 11:
+               {
+                  in.read((char*)&(theAttributes->theHorRelAccuracy), 4);
+                  in.read((char*)&(theAttributes->theHorRelUnits), 2);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theHorRelAccuracy);
+                     anEndian.swap(theAttributes->theHorRelUnits);
+                  }
+                  break;
+               }            
+               case 12:
+               {
+                  in.read((char*)tempString, 3);
+                  theAttributes->ellipsoidCode = ossimString(tempString,
+                                                             &tempString[3]);
+                  break;
+               }            
+               case 13:
+               {
+                  in.read((char*)tempString, 4);
+                  theAttributes->theSoundingDatumCode = ossimString(tempString,
+                                                                    &tempString[4]);
+                  break;
+               }            
+               case 14:
+               {
+                  in.read((char*)&(theAttributes->theNavSystemCode), 2);
+                  
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theNavSystemCode);
+                  }
+                  break;
+               }            
+               case 15:
+               {
+                  in.read((char*)tempString, 2);
+                  theAttributes->theGridCode = ossimString(tempString,
+                                                           &tempString[2]);
+                  break;
+               }            
+               case 16:
+               {
+                  in.read((char*)&(theAttributes->theEeasterlyMagChange), 4);
+                  in.read((char*)&(theAttributes->theEasterlyMagChangeUnits), 2);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theEeasterlyMagChange);
+                     anEndian.swap(theAttributes->theEasterlyMagChangeUnits);
+                  }
+                  break;
+               }
+               case 17:
+               {
+                  in.read((char*)&(theAttributes->theWesterlyMagChange), 4);
+                  in.read((char*)&(theAttributes->theWesterlyMagChangeUnits), 2);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theWesterlyMagChange);
+                     anEndian.swap(theAttributes->theWesterlyMagChangeUnits);
+                  }
+                  break;
+               }
+               case 18:
+               {
+                  in.read((char*)&(theAttributes->theMagAngle), 4);
+                  in.read((char*)&(theAttributes->theMagAngleUnits), 2);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theMagAngle);
+                     anEndian.swap(theAttributes->theMagAngleUnits);
+                  }
+                  break;
+               }
+               case 19:
+               {
+                  in.read((char*)&(theAttributes->theGridConver), 4);
+                  in.read((char*)&(theAttributes->theGridConverUnits), 2);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theGridConver);
+                     anEndian.swap(theAttributes->theGridConverUnits);
+                  }
+                  break;
+               }
+               case 20:
+               {
+                  in.read((char*)&(theAttributes->theHighElevation), 8);
+                  in.read((char*)&(theAttributes->theHighElevationUnits), 2);
+                  in.read((char*)&(theAttributes->theHighLat), 8);
+                  in.read((char*)&(theAttributes->theHighLon), 8);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theHighElevation);
+                     anEndian.swap(theAttributes->theHighElevationUnits);
+                     anEndian.swap(theAttributes->theHighLat);
+                     anEndian.swap(theAttributes->theHighLon);
+                  }
+                  break;
+               }
+               case 21:
+               {
+                  in.read((char*)tempString, 12);
+                  theAttributes->theLegendFileName = ossimString(tempString,
+                                                                 &tempString[12]);
+                  break;
+               }
+               case 22:
+               {
+                  in.read((char*)tempString, 12);
+                  tempString[12] = '\0';
+                  theAttributes->theDataSource = tempString;
+                  in.read((char*)&(theAttributes->theGsd), 4);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theGsd);
+                  }
+                  break;
+               }
+               case 23:
+               {
+                  in.read((char*)&(theAttributes->theDataLevel), 2);
+                  if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                  {
+                     anEndian.swap(theAttributes->theDataLevel);
+                  }
+                  break;
+               }
+               }
+            }
+            in.seekg(currentLocation, ios::beg);
+         }
+         else
+         {
+            delete temp;
+            temp = 0;
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfFrame::populateAttributeSection:  leaving 2 ..." << std::endl;
+            }
+            return ossimErrorCodes::OSSIM_ERROR;
+         }
+      }
+   }
+   if(temp) delete temp;
+   temp = 0;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfFrame::populateAttributeSection:  leaving OK ..." << std::endl;
+   }
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+ossimErrorCode ossimRpfFrame::populateMasks(istream& in)
+{
+   theSubframeMaskTable.clear();
+   theSubframeTransparencyMaskTable.clear();
+
+   if(!in)
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   if(theImageDescriptionSubheader)
+   {
+      const ossimRpfLocationSection& location = theHeader->getLocationSection();
+      if(&location)
+      {
+         ossimRpfComponentLocationRecord component;
+         
+         if(location.getComponent(OSSIM_RPF_MASK_SUBSECTION,
+                                  component))
+         {
+            
+            // now allocate the space we need and then reader the table in
+            
+            theSubframeMaskTable.resize(theImageDescriptionSubheader->getNumberOfSpectralGroups());
+            theSubframeTransparencyMaskTable.resize(theImageDescriptionSubheader->getNumberOfSpectralGroups());
+            
+            ossim_uint32 spectralIndex;
+            ossim_uint32 rowIndex;
+            ossim_uint32 colIndex;
+            
+            if(!theImageDescriptionSubheader->isSubframeMaskTableOffsetNull())
+            {
+               // move get to the first byte of the Mask table.  This is the offset from the
+               // start of the maskSubsection. 
+               in.seekg(component.theComponentLocation +
+                        theImageDescriptionSubheader->getSubframeMaskTableOffset(), ios::beg);
+               // first loop through the Mask table and allocate while we do it
+               for(spectralIndex = 0;
+                   spectralIndex < theImageDescriptionSubheader->getNumberOfSpectralGroups();
+                   ++spectralIndex)
+               {
+                  // reserve space for the number of rows
+                  theSubframeMaskTable[spectralIndex].resize(theImageDescriptionSubheader->getNumberOfSubframesVertical());
+                  for(rowIndex = 0;
+                      rowIndex < theImageDescriptionSubheader->getNumberOfSubframesVertical();
+                      ++rowIndex)
+                  {
+                     // allocate the columns
+                     theSubframeMaskTable[spectralIndex][rowIndex].resize(theImageDescriptionSubheader->getNumberOfSubframesHorizontal());
+                     for(colIndex = 0;
+                         colIndex < theImageDescriptionSubheader->getNumberOfSubframesHorizontal();
+                         ++colIndex)
+                     {
+                        ossim_uint32 value;
+                        
+                        in.read((char*)&value, 4);
+                        ossimEndian anEndian;
+                        
+                        if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                        {
+                           anEndian.swap(value);
+                        }
+                        theSubframeMaskTable[spectralIndex][rowIndex][colIndex] = value;
+                     }
+                  }
+               }
+            }
+            if(!theImageDescriptionSubheader->isTransparencyMaskTableOffsetNull())
+            {
+               // move get to the first byte of the Mask table.  This is the offset from the
+               // start of the maskSubsection. 
+               in.seekg(component.theComponentLocation +
+                        theImageDescriptionSubheader->getTransparencyMaskTableOffset(),ios::beg);
+               for(spectralIndex = 0;
+                   spectralIndex < theImageDescriptionSubheader->getNumberOfSpectralGroups();
+                   ++spectralIndex)
+               {
+                  // reserve space for the number of rows
+                  theSubframeTransparencyMaskTable[spectralIndex].resize(theImageDescriptionSubheader->getNumberOfSubframesVertical());
+                  for(rowIndex = 0;
+                      rowIndex < theImageDescriptionSubheader->getNumberOfSubframesVertical();
+                      ++rowIndex)
+                  {
+                     // allocate the columns
+                     theSubframeTransparencyMaskTable[spectralIndex][rowIndex].resize(theImageDescriptionSubheader->getNumberOfSubframesHorizontal());
+                     for(colIndex = 0;
+                         colIndex < theImageDescriptionSubheader->getNumberOfSubframesHorizontal();
+                         ++colIndex)
+                     {
+                        ossim_uint32 value;
+                        
+                        in.read((char*)&value, 4);
+                        ossimEndian anEndian;
+                        
+                        if(anEndian.getSystemEndianType() != theHeader->getByteOrder())
+                        {
+                           anEndian.swap(value);
+                        }
+                        theSubframeTransparencyMaskTable[spectralIndex][rowIndex][colIndex] = value;
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+   
+   return ossimErrorCodes::OSSIM_OK;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrame.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrame.h
new file mode 100644
index 0000000000..9aceaca25b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrame.h
@@ -0,0 +1,176 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              rpf file.
+//
+//********************************************************************
+// $Id: ossimRpfFrame.h,v 1.3 2003/06/15 19:01:34 dburken Exp $
+#ifndef ossimRpfFrame_HEADER
+#define ossimRpfFrame_HEADER
+#include <vector>
+using namespace std;
+
+#include "base/data_types/ossimFilename.h"
+#include "base/context/ossimErrorContext.h"
+#include "ossimRpfColorGrayscaleTable.h"
+#include "ossimRpfConstants.h"
+
+class ossimRpfHeader;
+class ossimRpfAttributes;
+class ossimRpfCoverageSection;
+class ossimRpfImageDescriptionSubheader;
+class ossimRpfImageDisplayParameterSubheader;
+class ossimRpfMaskSubheader;
+class ossimRpfCompressionSection;
+class ossimRpfColorGrayscaleSubheader;
+class ossimRpfColorConverterSubsection;
+
+class ossimRpfFrame
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfFrame& data);
+   ossimRpfFrame();
+   virtual ~ossimRpfFrame();
+   
+   void print(ostream& out)const;
+
+   ossimErrorCode parseFile(const ossimFilename& filename);
+   const ossimRpfHeader* getRpfHeader()const{return theHeader;}
+
+   bool hasSubframeMaskTable()const;
+
+   const vector< vector<ossim_uint32> >& getSubFrameMask(ossim_uint32 spectralGroup)
+      {
+         return theSubframeMaskTable[spectralGroup];
+      }
+   
+   bool fillSubFrameBuffer(ossim_uint8* buffer,
+                           ossim_uint32 spectralGroup,
+                           ossim_uint32 row,
+                           ossim_uint32 col)const;
+   
+   const ossimRpfCompressionSection* getCompressionSection()const
+      {
+         return theCompressionSection;
+      }
+   const vector<ossimRpfColorGrayscaleTable>& getColorGrayscaleTable()const
+      {
+         return theColorGrayscaleTable;
+      }
+   const ossimRpfColorConverterSubsection* getColorConverterSubsection()const
+      {
+         return theColorConverterSubsection;
+      }
+private:
+   void clearFields();
+   void deleteAll();
+   ossimErrorCode populateCoverageSection(istream& in);
+   ossimErrorCode populateCompressionSection(istream& in);
+   ossimErrorCode populateImageSection(istream& in);
+   ossimErrorCode populateAttributeSection(istream& in);
+   ossimErrorCode populateColorGrayscaleSection(istream& in);
+   ossimErrorCode populateMasks(istream& in);
+
+   /*!
+    * The header will be instantiated during the opening of the
+    * frame file.
+    */
+   ossimRpfHeader *theHeader;
+
+   /*!
+    * The filename is set if its a successful open.
+    */
+   ossimFilename   theFilename;
+
+   /*!
+    * This will hold the coverage.
+    */
+   ossimRpfCoverageSection* theCoverage;
+
+   /*!
+    * This will hold the attributes of this frame.
+    */
+   ossimRpfAttributes *theAttributes;
+
+   /*!
+    * This is the subheader for the image.  It will have
+    * some general information about the image.
+    */
+   ossimRpfImageDescriptionSubheader* theImageDescriptionSubheader;
+
+   /*!
+    * This is the mask subheader.
+    */
+   ossimRpfMaskSubheader* theMaskSubheader;
+   
+   /*!
+    * This is the subheader for the display parameters
+    * for this frame.
+    */
+   ossimRpfImageDisplayParameterSubheader* theImageDisplayParameterSubheader;
+
+   /*!
+    * Will hold a pointer to the compression information section.
+    */
+   ossimRpfCompressionSection*             theCompressionSection;
+   
+   /*!
+    * If present, it will hold the color grayscale subheader.
+    */
+   ossimRpfColorGrayscaleSubheader*        theColorGrayscaleSubheader;
+
+   /*!
+    * 
+    */
+   ossimRpfColorConverterSubsection*       theColorConverterSubsection;
+
+   /*!
+    * 
+    */
+   vector<ossimRpfColorGrayscaleTable>     theColorGrayscaleTable;
+
+
+   /*!
+    * We have a 3-D array.  For the most part the numberof spectral groups
+    * should be one.  The indexes are as follows:
+    *
+    * theSubframeMasKTable[spectralGroup][row][col]
+    *
+    *  It will hold RPF_NULL(0xffffffff) if the subframe does not exist
+    *  and it will hold an offset value from the start of the
+    * [spatial data section] to the first byte of the subframe table.
+    */
+   vector< vector< vector< ossim_uint32> > > theSubframeMaskTable;
+
+   /*!
+    * We have a 3-D array.  For the most part the numberof spectral groups
+    * should be one.  The indexes are as follows:
+    *
+    * theSubframeTransparencyMaskTable[spectralGroup][row][col]
+    *
+    *  It will hold RPF_NULL(0xffffffff) if the subframe does not exist
+    *  and it will hold an offset value from the start of the
+    * [spatial data section] to the first byte of the subframe table.
+    */
+   vector< vector< vector< ossim_uint32> > > theSubframeTransparencyMaskTable;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameEntry.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameEntry.cpp
new file mode 100644
index 0000000000..2158fa9721
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameEntry.cpp
@@ -0,0 +1,73 @@
+#include "ossimRpfFrameEntry.h"
+
+ostream& operator<<(ostream& out,
+                    const ossimRpfFrameEntry& data)
+{
+   data.print(out);
+
+   return out;
+}
+
+
+ossimRpfFrameEntry::ossimRpfFrameEntry(const ossimString& rootDirectory,
+                                       const ossimString& pathToFrameFileFromRoot)
+   :theRootDirectory(rootDirectory),
+    thePathToFrameFileFromRoot(pathToFrameFileFromRoot)
+{
+   setEntry(rootDirectory,
+            pathToFrameFileFromRoot);
+}
+
+ossimRpfFrameEntry::ossimRpfFrameEntry(const ossimRpfFrameEntry& rhs)
+   :theExists(rhs.theExists),
+    theRootDirectory(rhs.theRootDirectory),
+    thePathToFrameFileFromRoot(rhs.thePathToFrameFileFromRoot),
+    theFullValidPath(rhs.theFullValidPath)
+{}
+
+void ossimRpfFrameEntry::setEntry(const ossimString& rootDirectory,
+                                  const ossimString& pathToFrameFileFromRoot)
+{
+   ossimFilename temp(rootDirectory + pathToFrameFileFromRoot);
+   
+   theRootDirectory           = rootDirectory;
+   thePathToFrameFileFromRoot = pathToFrameFileFromRoot;
+   
+   if(temp.exists())
+   {
+      theFullValidPath = temp;
+      theExists        = true;
+   }
+   else // it might be upper cases( upper/lower) may be different. check it
+   {
+      thePathToFrameFileFromRoot = thePathToFrameFileFromRoot.downcase();
+      temp = ossimFilename(theRootDirectory + thePathToFrameFileFromRoot);
+      if(temp.exists())
+      {
+         theFullValidPath = temp;
+         theExists        = true;
+      }
+      else
+      {
+         thePathToFrameFileFromRoot = thePathToFrameFileFromRoot.upcase();
+         temp = ossimFilename(theRootDirectory + thePathToFrameFileFromRoot);
+         if(temp.exists())
+         {
+            theFullValidPath = temp;
+            theExists = true;
+         }
+         else
+         {
+            thePathToFrameFileFromRoot = pathToFrameFileFromRoot;
+            theFullValidPath = ossimFilename(rootDirectory + pathToFrameFileFromRoot);
+            theExists = false;
+         }
+      }
+   }
+}
+
+void ossimRpfFrameEntry::print(ostream& out)const
+{
+   out << "exists:          " << theExists    << endl
+       << "theFilename:     " << theFullValidPath;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameEntry.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameEntry.h
new file mode 100644
index 0000000000..48c877d21b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameEntry.h
@@ -0,0 +1,59 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfFrameEntry.h,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#ifndef ossimRpfFrameEntry_HEADER
+#define ossimRpfFrameEntry_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/data_types/ossimFilename.h"
+class ossimRpfFrameEntry
+{
+public:
+   friend ostream& operator<<(ostream& out,
+                              const ossimRpfFrameEntry& data);
+   ossimRpfFrameEntry(const ossimString& rootDirectory=ossimString(""),
+                      const ossimString& pathToFrameFileFromRoot=ossimString(""));
+   ossimRpfFrameEntry(const ossimRpfFrameEntry& rhs);
+   void print(ostream& out)const;
+   bool exists()const{return theExists;}
+   void setEntry(const ossimString& rootDirectory,
+                 const ossimString& pathToFrameFileFromRoot);
+   const ossimFilename& getFullPath()const{return theFullValidPath;}
+   const ossimString&   getRootDirectory()const{return theRootDirectory;}
+   const ossimString    getPathToFrameFileFromRoot()const
+      {
+         return thePathToFrameFileFromRoot;
+      }
+   
+private:
+   bool theExists;
+
+   ossimString theRootDirectory;
+
+   ossimString thePathToFrameFileFromRoot;
+
+   ossimFilename theFullValidPath;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexRecord.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexRecord.cpp
new file mode 100644
index 0000000000..c8ac4028ed
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexRecord.cpp
@@ -0,0 +1,106 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfFrameFileIndexRecord.cpp,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#include "ossimRpfFrameFileIndexRecord.h"
+#include "base/misc/ossimEndian.h"
+#include <string.h> // for memset
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfFrameFileIndexRecord& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfFrameFileIndexRecord::ossimRpfFrameFileIndexRecord()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfFrameFileIndexRecord::parseStream(istream& in, ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      ossimEndian anEndian;
+
+      clearFields();
+            
+      in.read((char*)&theBoundaryRectRecordNumber, 2);
+      in.read((char*)&theLocationRowNumber, 2);
+      in.read((char*)&theLocationColumnNumber, 2);
+      in.read((char*)&thePathnameRecordOffset, 4);
+      in.read((char*)theFilename, 12);
+      in.read((char*)theGeographicLocation, 6);
+      in.read((char*)&theSecurityClassification, 1);
+      in.read((char*)theFileSecurityCountryCode, 2);
+      in.read((char*)theFileSecurityReleaseMarking, 2);
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theBoundaryRectRecordNumber);
+         anEndian.swap(theLocationRowNumber);
+         anEndian.swap(theLocationColumnNumber);
+         anEndian.swap(thePathnameRecordOffset);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfFrameFileIndexRecord::print(ostream& out)const
+{
+   out << "theBoundaryRectRecordNumber:      " << theBoundaryRectRecordNumber << endl
+       << "theLocationRowNumber:             " << theLocationRowNumber << endl
+       << "theLocationColumnNumber:          " << theLocationColumnNumber << endl
+       << "thePathnameRecordOffset:          " << thePathnameRecordOffset << endl
+       << "theFilename:                      " << theFilename << endl
+       << "theGeographicLocation:            " << theGeographicLocation << endl
+       << "theSecurityClassification:        " << theSecurityClassification << endl
+       << "theFileSecurityCountryCode:       " << theFileSecurityCountryCode << endl
+       << "theFileSecurityReleaseMarking:    " << theFileSecurityReleaseMarking;
+}
+
+void ossimRpfFrameFileIndexRecord::clearFields()
+{
+   theBoundaryRectRecordNumber = 0;
+   theLocationRowNumber = 0;
+   theLocationColumnNumber= 0;
+   thePathnameRecordOffset = 0;
+   memset(theFilename, ' ', 12);
+   memset(theGeographicLocation, ' ', 6);
+   theSecurityClassification = ' ';;
+   memset(theFileSecurityCountryCode, ' ', 2);
+   memset(theFileSecurityReleaseMarking, ' ', 2);
+
+   theFilename[12] = '\0';
+   theGeographicLocation[6] = '\0';
+   theFileSecurityCountryCode[2] = '\0';
+   theFileSecurityReleaseMarking[2] = '\0';
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexRecord.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexRecord.h
new file mode 100644
index 0000000000..7655bf658e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexRecord.h
@@ -0,0 +1,78 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfFrameFileIndexRecord.h,v 1.3 2004/03/19 18:31:47 gpotts Exp $
+#ifndef ossimRpfFrameFileIndexRecord_HEADER
+#define ossimRpfFrameFileIndexRecord_HEADER
+#include <iostream>
+using namespace std;
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+#include "base/data_types/ossimFilename.h"
+
+class ossimRpfFrameFileIndexRecord
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfFrameFileIndexRecord& data);
+   
+   ossimRpfFrameFileIndexRecord();
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   void clearFields();
+   void print(ostream& out)const;
+   
+   ossim_uint16 getBoundaryRecNumber()const{return theBoundaryRectRecordNumber;}
+   ossim_uint16  getLocationRowNumber()const{return theLocationRowNumber;}
+   ossim_uint16  getLocationColNumber()const{return theLocationColumnNumber;}
+   ossim_uint32  getPathnameRecordOffset()const{return thePathnameRecordOffset;}
+   ossimFilename getFilename()const{return ossimFilename(theFilename);}
+   
+private:
+   ossim_uint16 theBoundaryRectRecordNumber;
+   ossim_uint16 theLocationRowNumber;
+   ossim_uint16 theLocationColumnNumber;
+   ossim_uint32 thePathnameRecordOffset;
+
+   /*!
+    * This is a 12 byte asci field.
+    */
+   char           theFilename[13];
+
+   /*!
+    * this is a 6 byte asci field.
+    */
+   char           theGeographicLocation[7];
+
+   char           theSecurityClassification;
+
+   /*!
+    * is a 2 byte field.
+    */
+   char           theFileSecurityCountryCode[3];
+
+   /*!
+    * This is a 2 byte field.
+    */
+   char           theFileSecurityReleaseMarking[3];
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSectionSubheader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSectionSubheader.cpp
new file mode 100644
index 0000000000..2e6d5a12b3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSectionSubheader.cpp
@@ -0,0 +1,85 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfFrameFileIndexSectionSubheader.cpp,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#include "ossimRpfFrameFileIndexSectionSubheader.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfFrameFileIndexSectionSubheader& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfFrameFileIndexSectionSubheader::ossimRpfFrameFileIndexSectionSubheader()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfFrameFileIndexSectionSubheader::parseStream(istream& in, ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      ossimEndian anEndian;
+
+      in.read((char*)&theHighestSecurityClassification, 1);
+      in.read((char*)&theIndexTableOffset, 4);
+      in.read((char*)&theNumberOfIndexRecords, 4);
+      in.read((char*)&theNumberOfPathnameRecords, 2);
+      in.read((char*)&theIndexRecordLength, 2);
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theIndexTableOffset);
+         anEndian.swap(theNumberOfIndexRecords);
+         anEndian.swap(theNumberOfPathnameRecords);
+         anEndian.swap(theIndexRecordLength);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfFrameFileIndexSectionSubheader::print(ostream& out)const
+{
+   out << "theHighestSecurityClassification:  " << theHighestSecurityClassification << endl
+       << "theIndexTableOffset:               " << theIndexTableOffset << endl
+       << "theNumberOfIndexRecords:           " << theNumberOfIndexRecords << endl
+       << "theNumberOfPathnameRecords:        " << theNumberOfPathnameRecords << endl
+       << "theIndexRecordLength:              " << theIndexRecordLength;
+}
+
+void ossimRpfFrameFileIndexSectionSubheader::clearFields()
+{
+   theHighestSecurityClassification = ' ';
+   theIndexTableOffset              = 0;
+   theNumberOfIndexRecords          = 0;
+   theNumberOfPathnameRecords       = 0;
+   theIndexRecordLength             = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSectionSubheader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSectionSubheader.h
new file mode 100644
index 0000000000..7f701ee88c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSectionSubheader.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfFrameFileIndexSectionSubheader.h,v 1.2 2003/06/15 19:01:34 dburken Exp $
+#ifndef ossimRpfFrameFileIndexSectionSubheader_HEADER
+#define ossimRpfFrameFileIndexSectionSubheader_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimRpfFrameFileIndexSectionSubheader
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfFrameFileIndexSectionSubheader& data);
+   ossimRpfFrameFileIndexSectionSubheader();
+   virtual ~ossimRpfFrameFileIndexSectionSubheader(){}
+
+   ossimErrorCode parseStream(istream& in,
+                              ossimByteOrder byteOrder);
+   virtual void print(ostream& out)const;
+   ossim_uint32 getOffset()const{return theIndexTableOffset;}
+   ossim_uint32 getNumberOfIndexRecords()const{return theNumberOfIndexRecords;}
+   ossim_uint16 getNumberOfPathnameRecords()const{return theNumberOfPathnameRecords;}
+   ossim_uint16 getIndexRecordLength()const{return theIndexRecordLength;}
+
+   void clearFields();
+private:
+   char          theHighestSecurityClassification;
+   ossim_uint32  theIndexTableOffset;
+   ossim_uint32  theNumberOfIndexRecords;
+   ossim_uint16  theNumberOfPathnameRecords;
+   ossim_uint16  theIndexRecordLength;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSubsection.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSubsection.cpp
new file mode 100644
index 0000000000..04854abd67
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSubsection.cpp
@@ -0,0 +1,98 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfFrameFileIndexSubsection.cpp,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#include "ossimRpfFrameFileIndexSubsection.h"
+#include <string.h> // for memset
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfFrameFileIndexSubsection& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfFrameFileIndexSubsection::ossimRpfFrameFileIndexSubsection()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfFrameFileIndexSubsection::parseStream(istream &in,
+                                                             ossimByteOrder byteOrder)
+{
+   ossimErrorCode result = ossimErrorCodes::OSSIM_OK;
+   
+   if(in && (theIndexTable.size()>0))
+   {
+      unsigned long index;
+      for(index = 0;
+          (index < theIndexTable.size())&&(result ==
+                                           ossimErrorCodes::OSSIM_OK);
+          index++)
+      {
+         result = theIndexTable[index].parseStream(in, byteOrder);
+      }
+      for(index = 0;
+          (index < thePathnameTable.size())&&(result ==
+                                              ossimErrorCodes::OSSIM_OK);
+          index++)
+      {
+         result = thePathnameTable[index].parseStream(in, byteOrder);
+      }
+   }
+   else
+   {
+      result = ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return result;
+}
+
+void ossimRpfFrameFileIndexSubsection::clearFields()
+{
+   theIndexTable.clear();
+   thePathnameTable.clear();
+}
+
+void ossimRpfFrameFileIndexSubsection::print(ostream& out)const
+{
+   copy(theIndexTable.begin(),
+        theIndexTable.end(),
+        ostream_iterator<ossimRpfFrameFileIndexRecord>(out, "\n"));
+   copy(thePathnameTable.begin(),
+        thePathnameTable.end(),
+        ostream_iterator<ossimRpfPathnameRecord>(out, "\n"));
+}
+
+
+void ossimRpfFrameFileIndexSubsection::setNumberOfFileIndexRecords(unsigned long numberOfIndexRecords)
+{
+   theIndexTable.resize(numberOfIndexRecords);
+}
+
+void ossimRpfFrameFileIndexSubsection::setNumberOfPathnames(unsigned long numberOfPathnames)
+{
+   thePathnameTable.resize(numberOfPathnames);
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSubsection.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSubsection.h
new file mode 100644
index 0000000000..c8f7c409df
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileIndexSubsection.h
@@ -0,0 +1,54 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfFrameFileIndexSubsection.h,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#ifndef ossimRpfFrameFileIndexSubsection_HEADER
+#define ossimRpfFrameFileIndexSubsection_HEADER
+#include <iostream>
+#include <vector>
+#include <iterator>
+using namespace std;
+#include "base/data_types/ossimString.h"
+#include "base/common/ossimConstants.h"
+#include "ossimRpfFrameFileIndexRecord.h"
+#include "ossimRpfPathnameRecord.h"
+
+class ossimRpfFrameFileIndexSubsection
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfFrameFileIndexSubsection& data);
+   ossimRpfFrameFileIndexSubsection();
+   ossimErrorCode parseStream(istream &in, ossimByteOrder byteOrder);
+   void clearFields();
+   void print(ostream& out)const;
+   void setNumberOfFileIndexRecords(unsigned long numberOfIndexRecords);
+   void setNumberOfPathnames(unsigned long numberOfPathnames);
+   const vector<ossimRpfFrameFileIndexRecord>& getIndexTable()const{return theIndexTable;}
+   
+private:
+   vector<ossimRpfFrameFileIndexRecord> theIndexTable;
+
+   vector<ossimRpfPathnameRecord> thePathnameTable;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileReader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileReader.cpp
new file mode 100644
index 0000000000..d0cd89a38a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileReader.cpp
@@ -0,0 +1,140 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfFrameFileReader.cpp,v 1.3 2003/06/05 14:40:06 gpotts Exp $
+#include "ossimRpfFrameFileReader.h"
+#include "ossimRpfHeader.h"
+#include "ossimRpfImageDescriptionSubheader.h"
+#include "ossimRpfMaskSubsection.h"
+#include "ossimRpfCompressionSectionSubheader.h"
+#include "ossimRpfAttributeSectionSubheader.h"
+#include "support_data/nitf/ossimNitfFile.h"
+#include "support_data/nitf/ossimNitfTagInformation.h"
+#include "support_data/nitf/ossimNitfFileHeader.h"
+#include "base/common/ossimErrorCodes.h"
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+ostream& operator<<(ostream& out,
+                    const ossimRpfFrameFileReader& data)
+{
+   data.print(out);
+
+   return out;
+}
+
+
+ossimRpfFrameFileReader::ossimRpfFrameFileReader()
+   :theRpfHeader(NULL),
+    theFilename("")
+{
+}
+
+ossimRpfFrameFileReader::~ossimRpfFrameFileReader()
+{
+   if(theRpfHeader)
+   {
+      delete theRpfHeader;
+      theRpfHeader = NULL;
+   }
+}
+
+
+ossimErrorCode ossimRpfFrameFileReader::parseFile(const ossimFilename& fileName)
+{
+   ifstream in(fileName, ios::in | ios::binary);
+   ossimNitfFile *nitfFile = new ossimNitfFile;
+
+   if(!in)
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   clearAll();
+   nitfFile->parseFile(fileName);
+   const ossimNitfFileHeader* nitfFileHeader = nitfFile->getHeader();
+   if(!nitfFileHeader)
+   {
+      delete nitfFile;
+      nitfFile = NULL;
+      
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   if(theRpfHeader)
+   {
+      delete theRpfHeader;
+      theRpfHeader = NULL;
+   }
+   ossimNitfTagInformation info; 
+   nitfFileHeader->getTag(info, "RPFHDR");
+   // we no longer need access to the nitf header.  We got what we needed
+   delete nitfFile;
+   nitfFile = NULL;
+   theFilename = fileName;
+   if(info.getTagName() == "RPFHDR")
+   {      
+      theRpfHeader = new ossimRpfHeader;
+      
+      // set the get pointer for the stream to the start
+      // of the Rpf header data
+      in.seekg(info.getTagDataOffset());
+      
+      // now get the header data.  We do not need to pass in the byte order.
+      // this is grabbed from the first byte of the stream.  To see this,
+      // Look at the RpfHeader implementation.
+      if(theRpfHeader->parseStream(in)==ossimErrorCodes::OSSIM_OK)
+      {
+      }
+      else
+      {
+         delete theRpfHeader;
+         theRpfHeader = NULL;
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   if(theRpfHeader)
+   {
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfFrameFileReader::print(ostream& out)const
+{
+   if(theRpfHeader)
+   {
+      out << *theRpfHeader << endl;
+   }
+}
+
+void ossimRpfFrameFileReader::clearAll()
+{
+   theFilename = "";
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileReader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileReader.h
new file mode 100644
index 0000000000..4054d68996
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfFrameFileReader.h
@@ -0,0 +1,39 @@
+#ifndef ossimRpfFrameFileReader_HEADER
+#define ossimRpfFrameFileReader_HEADER
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+#include "base/data_types/ossimFilename.h"
+
+class ossimRpfHeader;
+class ossimRpfImageDescriptionSubheader;
+class ossimRpfMaskSubsection;
+class ossimRpfCompressionSectionSubheader;
+class ossimRpfAttributeSectionSubheader;
+
+class ossimRpfFrameFileReader
+{
+public:
+   friend ostream& operator<<(ostream& out,
+                              const ossimRpfFrameFileReader& data);
+   
+   ossimRpfFrameFileReader();
+   virtual ~ossimRpfFrameFileReader();
+   
+   ossimErrorCode parseFile(const ossimFilename& fileName);
+   void print(ostream& out)const;
+   const ossimRpfHeader* getRpfHeader()const{return theRpfHeader;}
+   
+private:
+   void clearAll();
+   
+   ossimRpfHeader* theRpfHeader;
+      
+   ossimFilename   theFilename;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfHeader.cpp
new file mode 100644
index 0000000000..7feb5f8b7b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfHeader.cpp
@@ -0,0 +1,641 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfHeader.cpp,v 1.8 2004/06/17 17:40:29 gpotts Exp $
+#include "ossimRpfHeader.h"
+#include <string.h>
+#include "base/misc/ossimEndian.h"
+#include "base/data_types/ossimString.h"
+#include "base/common/ossimErrorCodes.h"
+#include "ossimRpfLocationSection.h"
+#include "ossimRpfCoverageSection.h"
+#include "ossimRpfBoundaryRectSectionSubheader.h"
+#include "ossimRpfBoundaryRectTable.h"
+#include "ossimRpfFrameFileIndexSectionSubheader.h"
+#include "ossimRpfFrameFileIndexSubsection.h"
+#include "ossimRpfImageDescriptionSubheader.h"
+#include "ossimRpfMaskSubsection.h"
+#include "ossimRpfAttributeSectionSubheader.h"
+#include "ossimRpfImageDisplayParameterSubheader.h"
+#include "ossimRpfCompressionSectionSubheader.h"
+#include "ossimRpfCompressionSection.h"
+#include "ossimRpfColorGrayscaleSubheader.h"
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+ostream& operator <<(ostream &out, const ossimRpfHeader &data)
+{
+   data.print(out);
+
+   return out;
+}
+
+ossimRpfHeader::~ossimRpfHeader()
+{
+   if(theLocationSection)
+   {
+      delete theLocationSection;
+      theLocationSection = NULL;
+   }
+}
+ossimRpfHeader::ossimRpfHeader()
+   :theLittleBigEndianIndicator(true),
+    theHeaderSectionLength(0),
+    theNewRepUpIndicator(0),
+    theLocSectionLoc(0),
+    theLocationSection(NULL)
+{
+   theLocationSection = new ossimRpfLocationSection;
+   
+   memset(theFileName, ' ' , 12);
+   memset(theGovSpecNumber, ' ', 15);
+   memset(theGovSpecDate, ' ', 8);
+   memset(theSecurityClassification, ' ', 1);
+   memset(theCountryCode, ' ', 2);
+   memset(theSecurityReleaseMarking, ' ', 2);
+
+   theFileName[12] = '\0';
+   theGovSpecNumber[15] = '\0';
+   theGovSpecDate[8] = '\0';
+   theSecurityClassification[1] = '\0';
+   theCountryCode[2] = '\0';
+   theSecurityReleaseMarking[2] = '\0';
+}
+
+ossimErrorCode ossimRpfHeader::parseStream(istream& in)
+{   
+   if(in)
+   {      
+      ossimEndian anEndian;
+
+      in.read((char*)&theLittleBigEndianIndicator, 1);
+
+      in.read((char*)&theHeaderSectionLength, 2);
+      in.read((char*)theFileName, 12);
+      in.read((char*)&theNewRepUpIndicator, 1);
+      in.read((char*)theGovSpecNumber, 15);
+      in.read((char*)theGovSpecDate, 8);
+      in.read((char*)theSecurityClassification, 1);
+      in.read((char*)theCountryCode, 2);
+      in.read((char*)theSecurityReleaseMarking, 2);
+      in.read((char*)&theLocSectionLoc, 4);
+
+      theFileName[12] = '\0';
+      theGovSpecNumber[15] = '\0';
+      theGovSpecDate[8] = '\0';
+      theSecurityClassification[1] = '\0';
+      theCountryCode[2] = '\0';
+      theSecurityReleaseMarking[2] = '\0';
+
+      ossimByteOrder dataByteOrder = ((theLittleBigEndianIndicator==0xff)?OSSIM_LITTLE_ENDIAN:OSSIM_BIG_ENDIAN);
+
+      if(anEndian.getSystemEndianType() != dataByteOrder)
+      {
+
+         anEndian.swap(theHeaderSectionLength);
+         anEndian.swap(theLocSectionLoc);
+      }
+
+      long saveGet = in.tellg();
+      in.seekg(theLocSectionLoc, ios::beg);
+      theLocationSection->parseStream(in,
+                                      dataByteOrder);
+      in.seekg(saveGet, ios::beg);
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfHeader::print(ostream &out)const
+{
+   out << "theLittleBigEndianIndicator:               " << theLittleBigEndianIndicator << endl
+       << "theHeaderSectionLength:                   " << theHeaderSectionLength     << endl
+       << "theFileName:                              " << theFileName                << endl
+       << "theNewRepUpIndicator:                     " << theNewRepUpIndicator       << endl
+       << "theGovSpecNumber:                         " << theGovSpecNumber           << endl
+       << "theSecurityClassification:                " << theSecurityClassification  << endl
+       << "theCountryCode:                           " << theCountryCode             << endl
+       << "theSecurityReleaseMarking:                " << theSecurityReleaseMarking  << endl
+       << "theLocSectionLoc:                         " << theLocSectionLoc           << endl
+       << (*theLocationSection) << endl;
+}
+
+bool ossimRpfHeader::hasComponent(ossimRpfComponentId componentId)const
+{
+   if(theLocationSection)
+   {
+      return theLocationSection->hasComponent(componentId);
+   }
+   
+   return false;
+}
+
+ossimString ossimRpfHeader::getSecurityClassification()const
+{
+   return theSecurityClassification;
+}
+
+ossimRpfCoverageSection* ossimRpfHeader::getNewCoverageSection(istream& in)const
+{
+   ossimRpfCoverageSection* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      if(theLocationSection->getComponent(OSSIM_RPF_COVERAGE_SECTION_SUBHEADER,
+                                          component))
+      {
+         result = new ossimRpfCoverageSection;
+
+         in.seekg(component.theComponentLocation, ios::beg);
+         
+         if(in)
+         {
+            result->parseStream(in, getByteOrder());
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }
+   return result;
+}
+
+ossimRpfMaskSubsection*  ossimRpfHeader::getNewMaskSubsection(istream& in)const
+{
+   ossimRpfMaskSubsection* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      if(theLocationSection->getComponent(OSSIM_RPF_MASK_SUBSECTION,
+                                          component))
+      {
+         result = new ossimRpfMaskSubsection;
+
+         in.seekg(component.theComponentLocation, ios::beg);
+         
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }
+   
+   return result;   
+}
+
+
+ossimRpfAttributeSectionSubheader* ossimRpfHeader::getNewAttributeSectionSubheader(istream& in)const
+{
+   ossimRpfAttributeSectionSubheader* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      if(theLocationSection->getComponent(OSSIM_RPF_ATTRIBUTE_SECTION_SUBHEADER,
+                                          component))
+      {
+         result = new ossimRpfAttributeSectionSubheader;
+
+         in.seekg(component.theComponentLocation, ios::beg);
+         
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }
+   
+   return result;
+}
+
+ossimRpfColorGrayscaleSubheader* ossimRpfHeader::getNewColorGrayscaleSubheader(istream& in)const
+{
+   ossimRpfColorGrayscaleSubheader* result = NULL;
+   
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      if(theLocationSection->getComponent(OSSIM_RPF_COLOR_GRAYSCALE_SECTION_SUBHEADER,
+                                          component))
+      {
+         result = new ossimRpfColorGrayscaleSubheader;
+
+         in.seekg(component.theComponentLocation, ios::beg);
+         
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }      
+   }
+
+   return result;
+}
+
+ossimRpfCompressionSection* ossimRpfHeader::getNewCompressionSection(istream& in)const
+{   
+   ossimRpfCompressionSection* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      if(theLocationSection->getComponent(OSSIM_RPF_COMPRESSION_SECTION_SUBHEADER,
+                                          component))
+      {
+         result = new ossimRpfCompressionSection;
+         
+         in.seekg(component.theComponentLocation, ios::beg);
+         
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }
+   
+   return result;   
+}
+
+ossimRpfCompressionSectionSubheader* ossimRpfHeader::getNewCompressionSectionSubheader(istream& in)const
+{
+   ossimRpfCompressionSectionSubheader* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      if(theLocationSection->getComponent(OSSIM_RPF_COMPRESSION_SECTION_SUBHEADER,
+                                          component))
+      {
+         result = new ossimRpfCompressionSectionSubheader;
+
+         in.seekg(component.theComponentLocation, ios::beg);
+         
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }
+   
+   return result;   
+}
+
+   
+
+ossimRpfImageDisplayParameterSubheader* ossimRpfHeader::getNewImageDisplayParameterSubheader(istream& in)const
+{
+   ossimRpfImageDisplayParameterSubheader* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      if(theLocationSection->getComponent(OSSIM_RPF_IMAGE_DISPLAY_PARAMETERS_SUBHEADER,
+                                          component))
+      {
+         result = new ossimRpfImageDisplayParameterSubheader;
+
+         in.seekg(component.theComponentLocation, ios::beg);
+         
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }
+   
+   return result;
+}
+
+ossimRpfImageDescriptionSubheader* ossimRpfHeader::getNewImageDescriptionSubheader(istream& in)const
+{
+   ossimRpfImageDescriptionSubheader* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      if(theLocationSection->getComponent(OSSIM_RPF_IMAGE_DESCRIPTION_SUBHEADER,
+                                          component))
+      {
+         result = new ossimRpfImageDescriptionSubheader;
+
+         in.seekg(component.theComponentLocation, ios::beg);
+         
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }
+   
+   return result;
+}
+
+
+ossimRpfBoundaryRectTable* ossimRpfHeader::getNewBoundaryRectTable(istream &in)const
+{
+   ossimRpfBoundaryRectTable* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      ossimRpfBoundaryRectSectionSubheader* tempSubheader = getNewBoundaryRectSectSubheader(in);
+
+      if(tempSubheader)
+      {
+         if(theLocationSection->getComponent(OSSIM_RPF_BOUNDARY_RECT_TABLE,
+                                             component))
+         {
+            result = new ossimRpfBoundaryRectTable;
+            
+            result->setNumberOfEntries(tempSubheader->getNumberOfEntries());
+            in.seekg(component.theComponentLocation, ios::beg);
+            if(in)
+            {
+               if(result->parseStream(in, getByteOrder()) !=
+                  ossimErrorCodes::OSSIM_OK)
+               {
+                  delete result;
+                  result = NULL;
+               }
+            }
+            else
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+
+         delete tempSubheader;
+         tempSubheader = NULL;
+      }
+   }   
+
+   return result;
+}
+
+ossimRpfBoundaryRectSectionSubheader* ossimRpfHeader::getNewBoundaryRectSectSubheader(istream &in)const
+{
+   ossimRpfBoundaryRectSectionSubheader* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+      
+      if(theLocationSection->getComponent(OSSIM_RPF_BOUNDARY_RECT_SECTION_SUBHEADER,
+                                          component))
+      {
+         result = new ossimRpfBoundaryRectSectionSubheader;
+
+         in.seekg(component.theComponentLocation, ios::beg);
+         
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }   
+
+   return result;
+   
+}
+
+ossimRpfFrameFileIndexSectionSubheader* ossimRpfHeader::getNewFrameFileIndexSectionSubheader(istream &in)const
+{
+   ossimRpfFrameFileIndexSectionSubheader* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+
+      if(theLocationSection->getComponent(OSSIM_RPF_FRAME_FILE_INDEX_SECTION_SUBHEADER,
+                                          component))
+      {
+         result = new ossimRpfFrameFileIndexSectionSubheader;
+
+         in.seekg(component.theComponentLocation, ios::beg);
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+   }   
+
+   return result;   
+}
+
+ossimRpfFrameFileIndexSubsection* ossimRpfHeader::getNewFileIndexSubsection(istream& in)const
+{
+   ossimRpfFrameFileIndexSubsection* result = NULL;
+
+   if(in&&theLocationSection)
+   {
+      ossimRpfComponentLocationRecord component;
+      ossimRpfFrameFileIndexSectionSubheader* tempSubheader = getNewFrameFileIndexSectionSubheader(in);
+
+      if(theLocationSection->getComponent(OSSIM_RPF_FRAME_FILE_INDEX_SUBSECTION,
+                                          component))
+      {
+         result = new ossimRpfFrameFileIndexSubsection;
+
+         result->setNumberOfFileIndexRecords(tempSubheader->getNumberOfIndexRecords());
+         result->setNumberOfPathnames(tempSubheader->getNumberOfPathnameRecords());
+         in.seekg(component.theComponentLocation, ios::beg);
+         if(in)
+         {
+            if(result->parseStream(in, getByteOrder()) !=
+               ossimErrorCodes::OSSIM_OK)
+            {
+               delete result;
+               result = NULL;
+            }
+         }
+         else
+         {
+            delete result;
+            result = NULL;
+         }
+      }
+      if(tempSubheader)
+      {
+         delete tempSubheader;
+         tempSubheader = NULL;
+      }
+   }   
+
+   return result;      
+}
+
+ossimRpfCompressionSection* ossimRpfHeader::getNewCompressionSection(const ossimFilename& file)const
+{
+   ifstream in(file.c_str(), ios::in|ios::binary);
+
+   return getNewCompressionSection(in);
+}
+
+ossimRpfCoverageSection* ossimRpfHeader::getNewCoverageSection(const ossimFilename& file)const
+{
+   ifstream in(file.c_str(), ios::in|ios::binary);
+   
+   return getNewCoverageSection(in);
+}
+
+ossimRpfBoundaryRectTable* ossimRpfHeader::getNewBoundaryRectTable(const ossimFilename &file)const
+{
+   ifstream in(file.c_str(), ios::in|ios::binary);
+   
+   return getNewBoundaryRectTable(in);
+}
+
+ossimRpfBoundaryRectSectionSubheader* ossimRpfHeader::getNewBoundaryRectSectSubheader(const ossimFilename &file)const
+{
+   ifstream in(file.c_str(), ios::in|ios::binary);
+
+   return getNewBoundaryRectSectSubheader(in);
+}
+
+ossimRpfFrameFileIndexSectionSubheader* ossimRpfHeader::getNewFrameFileIndexSectionSubheader(const ossimFilename &file)const
+{
+   ifstream in(file.c_str(), ios::in|ios::binary);
+
+   return getNewFrameFileIndexSectionSubheader(in);
+}
+
+ossimRpfFrameFileIndexSubsection* ossimRpfHeader::getNewFileIndexSubsection(const ossimFilename& file)const
+{
+   ifstream in(file.c_str(), ios::in|ios::binary);
+
+   return getNewFileIndexSubsection(in);
+}
+
+ossimString ossimRpfHeader::getDate()const
+{
+   return theGovSpecDate;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfHeader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfHeader.h
new file mode 100644
index 0000000000..382aced8f1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfHeader.h
@@ -0,0 +1,121 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfHeader.h,v 1.8 2005/07/22 12:46:46 gpotts Exp $
+#ifndef ossimRpfHeader_HEADER
+#define ossimRpfHeader_HEADER
+#include <iostream>
+#include <fstream>
+using namespace std;
+#include "base/common/ossimConstants.h" // ossiByteOrder
+#include "ossimRpfConstants.h" 
+#include "base/data_types/ossimFilename.h"
+
+class ossimRpfLocationSection;
+class ossimRpfCoverageSection;
+class ossimRpfBoundaryRectTable;
+class ossimRpfBoundaryRectSectionSubheader;
+class ossimRpfFrameFileIndexSectionSubheader;
+class ossimRpfFrameFileIndexSubsection;
+class ossimRpfColorTableIndexSectionSubheader;
+class ossimRpfImageDescriptionSubheader;
+class ossimRpfMaskSubsection;
+class ossimRpfAttributeSectionSubheader;
+class ossimRpfImageDisplayParameterSubheader;
+class ossimRpfCompressionSection;
+class ossimRpfCompressionSectionSubheader;
+class ossimRpfMaskSubsection;
+class ossimRpfImageDisplayParameterSubheader;
+class ossimRpfColorGrayscaleSubheader;
+class ossimRpfHeader
+{
+public:
+   friend ostream &operator<<(ostream& out, const ossimRpfHeader &data);
+   
+   ossimRpfHeader();
+   virtual ~ossimRpfHeader();
+   ossim_int32 parseStream(istream& in);
+   
+   virtual void print(ostream &out)const;
+   virtual ossimByteOrder getByteOrder()const
+      {
+         return ((theLittleBigEndianIndicator==0xFF)?OSSIM_LITTLE_ENDIAN:OSSIM_BIG_ENDIAN);
+      }
+   const ossimRpfLocationSection& getLocationSection()const{return *theLocationSection;}
+
+   bool hasComponent(ossimRpfComponentId componentId)const;
+   ossimString getSecurityClassification()const;
+   
+   /*!
+    * This will return a new coverage section.  It will return NULL if
+    * one does not exist.
+    */
+   ossimRpfCoverageSection* getNewCoverageSection(const ossimFilename& file)const;
+   ossimRpfCoverageSection* getNewCoverageSection(istream& in)const;
+
+   ossimRpfColorGrayscaleSubheader*     getNewColorGrayscaleSubheader(istream& in)const;
+   ossimRpfCompressionSection*          getNewCompressionSection(istream& in)const;
+   ossimRpfCompressionSectionSubheader* getNewCompressionSectionSubheader(istream& in)const;
+   ossimRpfImageDisplayParameterSubheader* getNewImageDisplayParameterSubheader(istream& in)const;
+   ossimRpfAttributeSectionSubheader* getNewAttributeSectionSubheader(istream& in)const;
+   ossimRpfImageDescriptionSubheader* getNewImageDescriptionSubheader(istream& in)const;
+   ossimRpfMaskSubsection* getNewMaskSubsection(istream& in)const;
+   ossimRpfBoundaryRectSectionSubheader* getNewBoundaryRectSectSubheader(istream& in)const;
+   ossimRpfBoundaryRectTable* getNewBoundaryRectTable(istream& in)const;
+   ossimRpfFrameFileIndexSectionSubheader* getNewFrameFileIndexSectionSubheader(istream& in)const;
+   ossimRpfFrameFileIndexSubsection* getNewFileIndexSubsection(istream& in)const;
+   ossimRpfColorTableIndexSectionSubheader* getNewColorTableIndexSectionSubheader(istream& in)const;
+
+   ossimRpfCompressionSection*          getNewCompressionSection(const ossimFilename& file)const;
+   ossimRpfBoundaryRectSectionSubheader* getNewBoundaryRectSectSubheader(const ossimFilename& file)const;
+   ossimRpfBoundaryRectTable* getNewBoundaryRectTable(const ossimFilename& file)const;
+   ossimRpfFrameFileIndexSectionSubheader* getNewFrameFileIndexSectionSubheader(const ossimFilename& file)const;
+   ossimRpfFrameFileIndexSubsection* getNewFileIndexSubsection(const ossimFilename& file)const;
+   ossimRpfColorTableIndexSectionSubheader* getNewColorTableIndexSectionSubheader(const ossimFilename& file)const;
+
+   ossimString getDate()const;
+private:
+   ossim_uint8    theLittleBigEndianIndicator; // 1 byte bool
+   ossim_uint16 theHeaderSectionLength;     // 2 bytes uint
+   char         theFileName[13];            // 12 byte ascii
+   unsigned char theNewRepUpIndicator;       // 1 byte unsigned int
+   char         theGovSpecNumber[16];       // 15 byte ascii
+   char         theGovSpecDate[9];          // 8 byte ascii
+   /**
+    * 1 byte field that can have the values
+    *
+    * U   Unclassified
+    * R   Restricted
+    * C   Confidential
+    * S   Secret
+    * T   Top Secret
+    */ 
+   char         theSecurityClassification[2];// 1 byte ascii
+   char         theCountryCode[3];          // 2 byte ascii
+   char         theSecurityReleaseMarking[3]; // 2 byte ascii
+   ossim_uint32 theLocSectionLoc;           // 4 byte unsigned int
+   
+   ossimRpfLocationSection *theLocationSection;
+};
+
+#endif
+ 
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDescriptionSubheader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDescriptionSubheader.cpp
new file mode 100644
index 0000000000..d948f5396d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDescriptionSubheader.cpp
@@ -0,0 +1,111 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfImageDescriptionSubheader.cpp,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#include "ossimRpfImageDescriptionSubheader.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfImageDescriptionSubheader& data)
+{
+   data.print(out);
+
+   return out;
+}
+
+ossimRpfImageDescriptionSubheader::ossimRpfImageDescriptionSubheader()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfImageDescriptionSubheader::parseStream(istream& in, ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      theStartOffset = in.tellg();
+      in.read((char*)&theNumberOfSpectralGroups, 2);
+      in.read((char*)&theNumberOfSubframeTables, 2);
+      in.read((char*)&theNumberOfSpectralBandTables, 2);
+      in.read((char*)&theNumberOfSpectralBandLinesPerImageRow, 2);
+      in.read((char*)&theNumberOfSubframesHorizontal, 2);
+      in.read((char*)&theNumberOfSubframesVertical, 2);
+      in.read((char*)&theNumberOfOutputColumnsPerSubframe, 4);
+      in.read((char*)&theNumberOfOutputRowsPerSubframe, 4);
+      in.read((char*)&theSubframeMaskTableOffset, 4);
+      in.read((char*)&theTransparencyMaskTableOffset, 4);
+
+      theEndOffset = in.tellg();
+      ossimEndian anEndian;
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theNumberOfSpectralGroups);
+         anEndian.swap(theNumberOfSubframeTables);
+         anEndian.swap(theNumberOfSpectralBandTables);
+         anEndian.swap(theNumberOfSpectralBandLinesPerImageRow);
+         anEndian.swap(theNumberOfSubframesHorizontal);
+         anEndian.swap(theNumberOfSubframesVertical);
+         anEndian.swap(theNumberOfOutputColumnsPerSubframe);
+         anEndian.swap(theNumberOfOutputRowsPerSubframe);
+         anEndian.swap(theSubframeMaskTableOffset);
+         anEndian.swap(theTransparencyMaskTableOffset);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfImageDescriptionSubheader::print(ostream& out)const
+{
+   out << "theNumberOfSpectralGroups:               " << theNumberOfSpectralGroups << endl
+       << "theNumberOfSubframeTables:               " << theNumberOfSubframeTables << endl
+       << "theNumberOfSpectralBandTables:           " << theNumberOfSpectralBandTables << endl
+       << "theNumberOfSpectralBandLinesPerImageRow: " << theNumberOfSpectralBandLinesPerImageRow << endl
+       << "theNumberOfSubframesHorizontal:          " << theNumberOfSubframesHorizontal << endl
+       << "theNumberOfSubframesVertical:            " << theNumberOfSubframesVertical << endl
+       << "theNumberOfOutputColumnsPerSubframe:     " << theNumberOfOutputColumnsPerSubframe << endl
+       << "theNumberOfOutputRowsPerSubframe:        " << theNumberOfOutputRowsPerSubframe << endl
+       << "theSubframeMaskTableOffset:              " << theSubframeMaskTableOffset << endl
+       << "theTransparencyMaskTableOffset:          " << theTransparencyMaskTableOffset;
+}
+
+void ossimRpfImageDescriptionSubheader::clearFields()
+{
+   theStartOffset                          = 0;
+   theEndOffset                            = 0;
+   
+   theNumberOfSpectralGroups               = 0;
+   theNumberOfSubframeTables               = 0;
+   theNumberOfSpectralBandTables           = 0;
+   theNumberOfSpectralBandLinesPerImageRow = 0;
+   theNumberOfSubframesHorizontal          = 0;
+   theNumberOfSubframesVertical            = 0;
+   theNumberOfOutputColumnsPerSubframe     = 0;
+   theNumberOfOutputRowsPerSubframe        = 0;
+   theSubframeMaskTableOffset              = 0;
+   theTransparencyMaskTableOffset          = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDescriptionSubheader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDescriptionSubheader.h
new file mode 100644
index 0000000000..ad9d8646e4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDescriptionSubheader.h
@@ -0,0 +1,126 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfImageDescriptionSubheader.h,v 1.3 2003/06/15 19:01:34 dburken Exp $
+#ifndef ossimRpfImageDescriptionSubheader_HEADER
+#define ossimRpfImageDescriptionSubheader_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder
+#include "ossimRpfConstants.h" 
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimRpfImageDescriptionSubheader
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfImageDescriptionSubheader& data);
+   ossimRpfImageDescriptionSubheader();
+   virtual ~ossimRpfImageDescriptionSubheader(){}
+
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   
+   ossim_uint32 getStartOffset()const{return theStartOffset;}
+   ossim_uint32 getEndOffset()const{return theEndOffset;}
+
+   bool isSubframeMaskTableOffsetNull()const
+      {
+         return (theSubframeMaskTableOffset == OSSIM_RPF_ULONG_NULL);
+      }
+   bool isTransparencyMaskTableOffsetNull()const
+      {
+         return (theTransparencyMaskTableOffset == OSSIM_RPF_ULONG_NULL);
+      }
+   ossim_uint16 getNumberOfSpectralGroups()const
+      {
+         return theNumberOfSpectralGroups;
+      }
+   ossim_uint16 getNumberOfSubframeTables()const
+      {
+         return theNumberOfSubframeTables;
+      }
+   ossim_uint16 getNumberOfSpectralBandTables()const
+      {
+         return theNumberOfSpectralBandTables;
+      }
+   ossim_uint16 getNumberOfSpectralBandLinesPerImageRow()const
+      {
+         return theNumberOfSpectralBandLinesPerImageRow;
+      }
+   ossim_uint16 getNumberOfSubframesHorizontal()const
+      {
+         return theNumberOfSubframesHorizontal;
+      }
+   ossim_uint16 getNumberOfSubframesVertical()const
+      {
+         return theNumberOfSubframesVertical;
+      }
+   ossim_uint32  getNumberOfOutputColumnsPerSubframe()const
+      {
+         return theNumberOfOutputColumnsPerSubframe;
+      }
+   ossim_uint32  getNumberOfOutputRowsPerSubframe()const
+      {
+         return theNumberOfOutputRowsPerSubframe;
+      }
+   ossim_uint32  getSubframeMaskTableOffset()const
+      {
+         return theSubframeMaskTableOffset;
+      }
+   ossim_uint32  getTransparencyMaskTableOffset()const
+      {
+         return theTransparencyMaskTableOffset;
+      }
+   virtual void print(ostream& out)const;
+   
+private:
+   void clearFields();
+   // work variables to store useful information.
+   ossim_uint32 theStartOffset;
+   ossim_uint32 theEndOffset;
+
+   ossim_uint16 theNumberOfSpectralGroups;
+   ossim_uint16 theNumberOfSubframeTables;
+   ossim_uint16 theNumberOfSpectralBandTables;
+   ossim_uint16 theNumberOfSpectralBandLinesPerImageRow;
+
+   /*!
+    * Each frame file could be divided into sub frames.
+    * This identifies the number of subframes in the
+    * horizontal direction.
+    */
+   ossim_uint16 theNumberOfSubframesHorizontal;
+
+   /*!
+    * Each frame file could be divided into sub frames.
+    * This identifies the number of subframes in the
+    * vertical direction.
+    */
+   ossim_uint16 theNumberOfSubframesVertical;
+   ossim_uint32 theNumberOfOutputColumnsPerSubframe;
+   ossim_uint32 theNumberOfOutputRowsPerSubframe;
+   ossim_uint32 theSubframeMaskTableOffset;
+   ossim_uint32 theTransparencyMaskTableOffset;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDisplayParameterSubheader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDisplayParameterSubheader.cpp
new file mode 100644
index 0000000000..ec796a64be
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDisplayParameterSubheader.cpp
@@ -0,0 +1,81 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfImageDisplayParameterSubheader.cpp,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#include "ossimRpfImageDisplayParameterSubheader.h"
+
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator<<(ostream& out,
+                    const ossimRpfImageDisplayParameterSubheader& data)
+{
+   data.print(out);
+
+   return out;
+}
+
+ossimRpfImageDisplayParameterSubheader::ossimRpfImageDisplayParameterSubheader()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfImageDisplayParameterSubheader::parseStream(istream& in,
+                                                         ossimByteOrder byteOrder)
+{
+   clearFields();
+   if(in)
+   {
+      theStartOffset = in.tellg();
+      in.read((char*)&theNumberOfImageRows, 4);
+      in.read((char*)&theNumberOfImageCodesPerRow, 4);
+      in.read((char*)&theImageCodeBitLength, 1);
+      theEndOffset = in.tellg();
+
+      ossimEndian anEndian;
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theNumberOfImageRows);
+         anEndian.swap(theNumberOfImageCodesPerRow);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   return ossimErrorCodes::OSSIM_OK;
+}
+   
+void ossimRpfImageDisplayParameterSubheader::print(ostream& out)const
+{
+   out << "theNumberOfImageRows:          " << theNumberOfImageRows << endl
+       << "theNumberOfImageCodesPerRow:   " << theNumberOfImageCodesPerRow << endl
+       << "theImageCodeBitLength:         " << (unsigned long)theImageCodeBitLength;
+}
+
+void ossimRpfImageDisplayParameterSubheader::clearFields()
+{
+   theNumberOfImageRows        = 0;
+   theNumberOfImageCodesPerRow = 0;
+   theImageCodeBitLength       = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDisplayParameterSubheader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDisplayParameterSubheader.h
new file mode 100644
index 0000000000..55a92ae1ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfImageDisplayParameterSubheader.h
@@ -0,0 +1,74 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfImageDisplayParameterSubheader.h,v 1.2 2003/06/15 19:01:34 dburken Exp $
+#ifndef ossimRpfImageDisplayParameterSubheader_HEADER
+#define ossimRpfImageDisplayParameterSubheader_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimRpfImageDisplayParameterSubheader
+{
+public:
+   friend ostream& operator<<(ostream& out,
+                              const ossimRpfImageDisplayParameterSubheader& data);
+   ossimRpfImageDisplayParameterSubheader();
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   
+   void print(ostream& out)const;
+
+   ossim_uint32 getStartOffset()const
+      {
+         return theStartOffset;
+      }
+   ossim_uint32 getEndOffset()const
+      {
+         return theEndOffset;
+      }
+   ossim_uint32 getNumberOfImageRows()const
+      {
+         return theNumberOfImageRows;
+      }
+   ossim_uint32 getNumberOfImageCodesPerRow()const
+      {
+         return theNumberOfImageCodesPerRow;
+      }
+   ossim_uint32 getImageCodeLength()const
+      {
+         return theImageCodeBitLength;
+      }
+   
+private:
+   void clearFields();
+
+   ossim_uint32 theStartOffset;
+   ossim_uint32 theEndOffset;
+   
+   ossim_uint32 theNumberOfImageRows;
+   ossim_uint32 theNumberOfImageCodesPerRow;
+   ossim_uint8  theImageCodeBitLength;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfLocationSection.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfLocationSection.cpp
new file mode 100644
index 0000000000..546d9f586d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfLocationSection.cpp
@@ -0,0 +1,185 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfLocationSection.cpp,v 1.2 2005/08/24 12:02:47 gpotts Exp $
+#include "ossimRpfLocationSection.h"
+#include <base/misc/ossimEndian.h>
+#include <base/common/ossimErrorCodes.h>
+#include <base/common/ossimTrace.h>
+
+static const ossimTrace traceDebug("ossimRpfLocationSection:debug");
+
+ostream& operator<<(ostream& out,
+                    const ossimRpfComponentLocationRecord& data)
+{
+   data.print(out);
+
+   return out;
+}
+
+void ossimRpfComponentLocationRecord::print(ostream& out)const
+{
+   out << "theComponentId:             " << theComponentId       << endl
+       << "theComponentLength:         " << theComponentLength   << endl
+       << "theComponentLocation:       " << theComponentLocation;
+}
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfLocationSection &data)
+{
+   data.print(out);
+
+   return out;
+}
+
+ossimErrorCode ossimRpfComponentLocationRecord::parseStream(istream& in,
+                                                            ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      ossimEndian anEndian;
+
+      
+      in.read((char*)&theComponentId, 2);
+      in.read((char*)&theComponentLength, 4);
+      in.read((char*)&theComponentLocation, 4);
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theComponentId);
+         anEndian.swap(theComponentLength);
+         anEndian.swap(theComponentLocation);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return  ossimErrorCodes::OSSIM_OK;
+}
+
+
+ossimRpfLocationSection::ossimRpfLocationSection()
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfLocationSection::parseStream(istream& in,
+                                                    ossimByteOrder byteOrder)
+{
+   ossimErrorCode result = ossimErrorCodes::OSSIM_OK;
+   
+   if(in)
+   {
+      clearFields();
+      ossimEndian anEndian;
+
+      in.read((char*)&theLocationSectionLength, 2);
+      in.read((char*)&theLocationTableOffset, 4);
+      in.read((char*)&theNumberOfComponentLocationRecords, 2);
+      in.read((char*)&theLocationRecordLength, 2);
+      in.read((char*)&theComponentAggregateLength, 4);
+      
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+          anEndian.swap(theLocationSectionLength);
+          anEndian.swap(theLocationTableOffset);
+          anEndian.swap(theNumberOfComponentLocationRecords);
+          anEndian.swap(theLocationRecordLength);
+          anEndian.swap(theComponentAggregateLength);
+      }
+      if(traceDebug())
+      {
+         print(ossimNotify(ossimNotifyLevel_DEBUG));
+         ossimNotify(ossimNotifyLevel_DEBUG) << std::endl;
+      }
+      theComponentLocationList.resize(theNumberOfComponentLocationRecords);
+      for(unsigned long index = 0;
+          (index < theComponentLocationList.size())&&
+                      (result == ossimErrorCodes::OSSIM_OK);
+          index++)
+      {        
+         result = theComponentLocationList[index].parseStream(in, byteOrder);
+      }
+   }
+   else
+   {
+      result = ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return result;
+}
+
+void ossimRpfLocationSection::print(ostream& out) const
+{
+   out << "theLocationSectionLength:            " << theLocationSectionLength << endl
+       << "theLocationTableOffset:              " << theLocationTableOffset << endl
+       << "theNumberOfComponentLocationRecords: " << theNumberOfComponentLocationRecords << endl
+       << "theLocationRecordLength:             " << theLocationRecordLength << endl
+       << "theComponentAggregateLength:         " << theComponentAggregateLength;
+   
+   if(theNumberOfComponentLocationRecords > 0)
+   {
+      out << endl;
+      copy(theComponentLocationList.begin(),
+           theComponentLocationList.end(),
+           ostream_iterator<ossimRpfComponentLocationRecord>(out, "\n"));
+   }
+}
+
+bool ossimRpfLocationSection::hasComponent(ossimRpfComponentId componentId)const
+{
+   ossimRpfComponentLocationRecord result;
+   
+   return getComponent(componentId, result);
+}
+
+bool ossimRpfLocationSection::getComponent(ossimRpfComponentId componentId,
+                                           ossimRpfComponentLocationRecord &result)const
+{
+   vector<ossimRpfComponentLocationRecord>::const_iterator component = theComponentLocationList.begin();
+   
+   while(component != theComponentLocationList.end())
+   {
+      if((*component).theComponentId == static_cast<unsigned short>(componentId))
+      {
+         result = *component;
+
+         return true;
+      }      
+      ++component;
+   }
+   
+   return false;
+}
+
+void ossimRpfLocationSection::clearFields()
+{
+   theLocationSectionLength            = 0;
+   theLocationTableOffset              = 0;
+   theNumberOfComponentLocationRecords = 0;
+   theLocationRecordLength             = 0;
+   theComponentAggregateLength         = 0;
+
+   theComponentLocationList.clear();
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfLocationSection.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfLocationSection.h
new file mode 100644
index 0000000000..e2d3c8e9e0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfLocationSection.h
@@ -0,0 +1,115 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfLocationSection.h,v 1.3 2003/06/15 19:01:34 dburken Exp $
+#ifndef ossimRpfLocationSection_HEADER
+#define ossimRpfLocationSection_HEADER
+#include <iostream>
+#include <vector>
+#include <iterator>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder
+#include "ossimRpfConstants.h"
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+struct ossimRpfComponentLocationRecord
+{
+public:
+   friend ostream& operator<<(ostream& out,
+                              const ossimRpfComponentLocationRecord& data);
+   void print(ostream& out)const;
+   ossimErrorCode parseStream(istream& in, ossimByteOrder endianOrder);
+
+   /*!
+    * The component is a 2-Byte unsigned value which
+    * identitfies a level-2 component.  The table can be
+    * found in MIL-STD-2411-1 in section 5.1.1
+    */
+   ossim_uint16 theComponentId;
+
+   /*!
+    * Is a 4 byte unsigned integer indicating the length in
+    * bytes of the component.
+    */
+   ossim_uint32  theComponentLength;
+
+   /*!
+    * Is a 4 byte value defining the absolute address (byte number)
+    * of the first byte of the component measured
+    * from the beginning of the RPF Frame file.
+    */ 
+   ossim_uint32  theComponentLocation;
+};
+
+class ossimRpfLocationSection
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfLocationSection &data);
+   ossimRpfLocationSection();
+   virtual ~ossimRpfLocationSection(){}
+
+   virtual ossimErrorCode parseStream(istream& in,
+                            ossimByteOrder endianOrder);
+   virtual void print(ostream& out)const;
+
+   /*!
+    * Will let you know if a component exists within the location section.
+    * these component Ids' are defined in the MIL-STD-2411-1 standards doc.
+    * the ossimRpfComponentId is in ossimConstants.h
+    */
+   bool hasComponent(ossimRpfComponentId componentId)const;
+
+   bool getComponent(ossimRpfComponentId componentId,
+                     ossimRpfComponentLocationRecord& result)const;
+
+   
+   ossim_uint32 getOffset()const;
+   
+private:
+   void clearFields();
+
+   /*!
+    * This is a 2 byte unsigned short >= 34 indicatin
+    * the length in bytes of the entire location section
+    */
+   ossim_uint16 theLocationSectionLength;
+
+   ossim_uint32  theLocationTableOffset;
+
+   ossim_uint16 theNumberOfComponentLocationRecords;
+
+   ossim_uint16 theLocationRecordLength;
+
+   ossim_uint32  theComponentAggregateLength;
+
+   /*!
+    * Since there are not very many components within an Rpf file
+    * it would be overkill to sort these components into an stl
+    * map.  We will just use an array (stl vector) and do linear searches
+    * for components when we need to.
+    */
+   vector<ossimRpfComponentLocationRecord> theComponentLocationList;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubheader.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubheader.cpp
new file mode 100644
index 0000000000..351205133d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubheader.cpp
@@ -0,0 +1,90 @@
+#include "ossimRpfMaskSubheader.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+#include <cmath>
+ostream& operator <<(ostream& out,
+                     const ossimRpfMaskSubheader& data)
+{
+   data.print(out);
+
+   return out;
+}
+
+ossimRpfMaskSubheader::ossimRpfMaskSubheader()
+   :theOutputPixelCodeBitString(NULL)
+{
+   clearFields();
+}
+
+ossimErrorCode ossimRpfMaskSubheader::parseStream(istream& in,
+                                        ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      clearFields();
+
+      in.read((char*)&theSubframeSequenceRecordLength, 2);
+      in.read((char*)&theTransparencySequenceRecordLength, 2);
+      in.read((char*)&theTransparentOutputPixelCodeLength, 2);
+      ossimEndian anEndian;
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theSubframeSequenceRecordLength);
+         anEndian.swap(theTransparencySequenceRecordLength);
+         anEndian.swap(theTransparentOutputPixelCodeLength);
+
+      }
+      if(theTransparentOutputPixelCodeLength>0)
+      {
+         theNumberOfBytes = (long)std::ceil(theTransparentOutputPixelCodeLength/8.0);
+         theOutputPixelCodeBitString = new unsigned char[theNumberOfBytes];
+         in.read((char*)theOutputPixelCodeBitString, theNumberOfBytes);
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfMaskSubheader::print(ostream& out)const
+{
+   out << "theSubframeSequenceRecordLength:     " << theSubframeSequenceRecordLength << endl
+       << "theTransparencySequenceRecordLength: " << theTransparencySequenceRecordLength << endl
+       << "theTransparentOutputPixelCodeLength: " << theTransparentOutputPixelCodeLength << endl
+       << "theNumberOfBytes:                    " << theNumberOfBytes << endl
+       << "theOutputPixelCodeBitString:         ";
+
+   // display the pixel code as a bit pattern.
+   for(long index = theNumberOfBytes-1;
+       index >=0;
+       --index)
+   {
+      unsigned long temp = theOutputPixelCodeBitString[index];
+      out << ((temp>>7)&1)
+          << ((temp>>6)&1)
+          << ((temp>>5)&1)
+          << ((temp>>4)&1)
+          << ((temp>>3)&1)
+          << ((temp>>2)&1)
+          << ((temp>>1)&1)
+          << (temp&1);
+   }
+}
+
+void ossimRpfMaskSubheader::clearFields()
+{
+   theSubframeSequenceRecordLength     = 0;
+   theTransparencySequenceRecordLength = 0;
+   theTransparentOutputPixelCodeLength = 0;
+   theNumberOfBytes                    = 0;
+
+   if(theOutputPixelCodeBitString)
+   {
+      delete [] theOutputPixelCodeBitString;
+      theOutputPixelCodeBitString = NULL;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubheader.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubheader.h
new file mode 100644
index 0000000000..3039111167
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubheader.h
@@ -0,0 +1,39 @@
+#ifndef ossimRpfMaskSubheader_HEADER
+#define ossimRpfMaskSubheader_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+#include "base/data_types/ossimString.h"
+
+class ossimRpfMaskSubheader
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfMaskSubheader& data);
+   ossimRpfMaskSubheader();
+   virtual ~ossimRpfMaskSubheader(){}
+
+   ossimErrorCode parseStream(istream& in,
+                              ossimByteOrder byteOrder);
+   void print(ostream& out)const;
+   
+private:
+   void clearFields();
+
+   unsigned short theSubframeSequenceRecordLength;
+   unsigned short theTransparencySequenceRecordLength;
+   unsigned short theTransparentOutputPixelCodeLength;
+   unsigned char* theOutputPixelCodeBitString;
+
+   /*!
+    * This is just a working variable and is not
+    * part of the Rpf fields. this is the number of bytes
+    * of the output pixel code length.  It divides by
+    * 8 and then does the ceiling of the
+    * theTransparentOutputPixelCodeLength.
+    */
+   long theNumberOfBytes;
+};
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubsection.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubsection.cpp
new file mode 100644
index 0000000000..67d5e85e5c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubsection.cpp
@@ -0,0 +1,56 @@
+#include "ossimRpfMaskSubsection.h"
+#include "ossimRpfMaskSubheader.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfMaskSubsection& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfMaskSubsection::ossimRpfMaskSubsection()
+   :theMaskSubheader(NULL)
+{
+   theMaskSubheader = new ossimRpfMaskSubheader;
+}
+
+ossimRpfMaskSubsection::~ossimRpfMaskSubsection()
+{
+   deleteAll();
+}
+
+ossimErrorCode ossimRpfMaskSubsection::parseStream(istream& in,
+                                                   ossimByteOrder byteOrder)
+{
+   ossimErrorCode result = ossimErrorCodes::OSSIM_OK;
+   
+   if(in&&theMaskSubheader)
+   {
+      result = theMaskSubheader->parseStream(in, byteOrder);
+   }
+   else
+   {
+      result = ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   return result;
+}
+
+void ossimRpfMaskSubsection::print(ostream& out)const
+{
+   if(theMaskSubheader)
+   {
+      out << *theMaskSubheader;
+   }
+}
+
+void ossimRpfMaskSubsection::deleteAll()
+{
+   if(theMaskSubheader)
+   {
+      delete theMaskSubheader;
+      theMaskSubheader = NULL;
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubsection.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubsection.h
new file mode 100644
index 0000000000..f278b64f96
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfMaskSubsection.h
@@ -0,0 +1,51 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfMaskSubsection.h,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#ifndef ossimRpfMaskSubsection_HEADER
+#define ossimRpfMaskSubsection_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimRpfMaskSubheader;
+class ossimRpfImageDescriptionSubheader;
+
+class ossimRpfMaskSubsection
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfMaskSubsection& data);
+   ossimRpfMaskSubsection();
+   virtual ~ossimRpfMaskSubsection();
+
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   virtual void print(ostream& out)const;
+   
+private:
+   void deleteAll();
+   ossimRpfMaskSubheader *theMaskSubheader;   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfPathnameRecord.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfPathnameRecord.cpp
new file mode 100644
index 0000000000..1eca0945f2
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfPathnameRecord.cpp
@@ -0,0 +1,81 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfPathnameRecord.cpp,v 1.2 2004/03/19 18:31:47 gpotts Exp $
+#include "ossimRpfPathnameRecord.h"
+#include "base/misc/ossimEndian.h"
+#include "base/common/ossimErrorCodes.h"
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfPathnameRecord& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+
+ossimRpfPathnameRecord::ossimRpfPathnameRecord()
+{   
+   clearFields();
+}
+
+void ossimRpfPathnameRecord::clearFields()
+{
+   theLength   = 0;
+   thePathname = "";
+}
+
+ossimErrorCode ossimRpfPathnameRecord::parseStream(istream& in, ossimByteOrder byteOrder)
+{
+   if(in)
+   {
+      ossimEndian anEndian;
+      
+      clearFields();
+      in.read((char*)&theLength, 2);
+
+      if(anEndian.getSystemEndianType() != byteOrder)
+      {
+         anEndian.swap(theLength);
+      }
+
+      char *temp = new char[theLength+1];
+      in.read((char*)temp, theLength);
+      temp[theLength] = '\0';
+      thePathname = temp;
+      
+      delete [] temp;
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfPathnameRecord::print(ostream& out)const
+{
+   out << "theLength:        " << theLength   << endl
+       << "thePathname:      " << thePathname;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfPathnameRecord.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfPathnameRecord.h
new file mode 100644
index 0000000000..47a2e6dc7c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfPathnameRecord.h
@@ -0,0 +1,49 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfPathnameRecord.h,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#ifndef ossimRpfPathnameRecord_HEADER
+#define ossimRpfPathnameRecord_HEADER
+#include <iostream>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+#include "base/data_types/ossimString.h"
+
+class ossimRpfPathnameRecord
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfPathnameRecord& data);
+   ossimRpfPathnameRecord();
+   void clearFields();
+   ossimErrorCode parseStream(istream& in, ossimByteOrder byteOrder);
+   void print(ostream& out)const;
+   ossimString getPathname()const{return thePathname;}
+   
+private:   
+   unsigned short theLength;
+   ossimString thePathname;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfToc.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfToc.cpp
new file mode 100644
index 0000000000..4a4edba26e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfToc.cpp
@@ -0,0 +1,338 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfToc.cpp,v 1.6 2005/08/24 12:02:47 gpotts Exp $
+
+#include "ossimRpfToc.h"
+#include "base/common/ossimErrorCodes.h"
+#include "base/context/ossimErrorContext.h"
+#include "ossimRpfHeader.h"
+#include "ossimRpfFrameFileIndexSectionSubheader.h"
+#include "ossimRpfFrameFileIndexSubsection.h"
+#include "ossimRpfBoundaryRectTable.h"
+#include "ossimRpfTocEntry.h"
+#include "ossimRpfFrameFileIndexRecord.h"
+#include "ossimRpfBoundaryRectSectionSubheader.h"
+#include "ossimRpfPathnameRecord.h"
+#include "support_data/nitf/ossimNitfFile.h"
+#include "support_data/nitf/ossimNitfFileHeader.h"
+#include "support_data/nitf/ossimNitfEmbeddedRpfHeader.h"
+#include <base/common/ossimTrace.h>
+
+static ossimTrace traceDebug("ossimRpfToc:debug");
+
+ostream& operator <<(std::ostream& out,
+                     const ossimRpfToc& data)
+{
+   data.print(out);
+   
+   return out;
+}
+
+ossimRpfToc::ossimRpfToc()
+   :theRpfHeader(NULL)
+{
+}
+
+ossimRpfToc::~ossimRpfToc()
+{
+   deleteAll();
+}
+
+ossimErrorCode ossimRpfToc::parseFile(const ossimFilename &fileName)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfToc::parseFile: entered....." << std::endl;
+   }
+   ossimNitfFile *nitfFile = new ossimNitfFile;
+
+   clearAll();
+
+   nitfFile->parseFile(fileName);
+
+   const ossimNitfFileHeader* nitfFileHeader = nitfFile->getHeader();
+   
+   if(theRpfHeader)
+   {
+      delete theRpfHeader;
+      theRpfHeader = NULL;
+   }
+   
+   if(!nitfFileHeader)
+   {
+      delete nitfFile;
+      nitfFile = NULL;
+      
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfToc::parseFile: leaving with no nitf header found....." << std::endl;
+      }
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   ossimNitfTagInformation info; 
+   nitfFileHeader->getTag(info, "RPFHDR");
+   
+   // we no longer need access to the nitf header.  We got what we needed
+   delete nitfFile;
+   nitfFile = NULL;
+   theFilename = fileName;
+
+   if(info.getTagName() == "RPFHDR")
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: Found RPF HEADER tag" << std::endl;
+      }
+      theRpfHeader = new ossimRpfHeader;
+
+      ifstream in(theFilename.c_str(), ios::in|ios::binary);
+      
+      // set the get pointer for the stream to the start
+      // of the Rpf header data
+      in.seekg(info.getTagDataOffset(), ios::beg);
+      
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: parsing  RPFHDR tag" << std::endl;
+      }
+      // now get the header data.  We do not need to pass in the byte order.
+      // this is grabbed from the first byte of the stream.  To see this,
+      // Look at the RpfHeader implementation.
+      theRpfHeader->parseStream(in);
+   }
+   else
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfToc::parseFile: Leaving No RPFHDR tag found" << std::endl;
+      }
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+   if(theRpfHeader)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: Building toc list" << std::endl;
+      }
+      buildTocEntryList(theRpfHeader);
+   }
+   else
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfToc::parseFile: Leaving no RPFHDR " << __LINE__ << std::endl;
+      }
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+   
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfToc::parseFile: Returning with OK." << std::endl;
+      }
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+void ossimRpfToc::print(ostream& out)const
+{
+   if(theRpfHeader)
+   {
+      out << *theRpfHeader << endl;
+
+      vector< ossimRpfTocEntry*>::const_iterator tocEntry = theTocEntryList.begin();
+      while(tocEntry != theTocEntryList.end())
+      {
+         out << *(*tocEntry) << endl;
+         ++tocEntry;
+      }
+      
+   }
+}
+
+const ossimRpfTocEntry* ossimRpfToc::getTocEntry(unsigned long index)const
+{
+   if(index < theTocEntryList.size())
+   {
+      return theTocEntryList[index];
+   }
+   return NULL;
+}
+
+ossim_int32 ossimRpfToc::getTocEntryIndex(const ossimRpfTocEntry* entry)
+
+{
+   for(ossim_int32 i = 0; i < (ossim_int32)theTocEntryList.size(); ++i)
+   {
+      if(theTocEntryList[i] == entry)
+      {
+         return i;
+      }
+   }
+
+   return -1;
+}
+
+void ossimRpfToc::deleteAll()
+{
+   if(theRpfHeader)
+   {
+      delete theRpfHeader;
+      theRpfHeader = NULL;
+   }
+
+   deleteTocEntryList();
+}
+
+void ossimRpfToc::clearAll()
+{
+   deleteTocEntryList();
+   theFilename = "";
+}
+
+void ossimRpfToc::deleteTocEntryList()
+{
+   vector< ossimRpfTocEntry*>::iterator tocEntry = theTocEntryList.begin();
+   while(tocEntry != theTocEntryList.end())
+   {
+      if(*tocEntry)
+      {
+         delete (*tocEntry);
+         *tocEntry = NULL;
+      }
+      ++tocEntry;
+   }
+   theTocEntryList.clear();
+}
+
+void ossimRpfToc::buildTocEntryList(ossimRpfHeader* rpfHeader)
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfToc::buildTocEntryList: entered....." << std::endl;
+   }
+   ifstream in(theFilename.c_str(), ios::in | ios::binary);
+
+   if(!in)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfToc::buildTocEntryList: invalid input leaving..... " << std::endl;
+      }
+      return;
+   }
+   
+   if(rpfHeader)
+   {
+      deleteTocEntryList();
+      ossimRpfBoundaryRectSectionSubheader *boundaryRect = rpfHeader->getNewBoundaryRectSectSubheader(in);
+      
+      if(boundaryRect)
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: Got boundary rect " << std::endl;
+         }
+         long current = in.tellg();
+
+         // they give the offset from the
+         // end of the boundary subheader to the start of the 
+         // entry table.  We have to create an absolute
+         // offset.
+         current += boundaryRect->getTableOffset();
+
+         // take to the start of the table entries
+         in.seekg(current, ios::beg);
+         allocateTocEntryList(boundaryRect->getNumberOfEntries());
+
+         // now we can read the entries
+         if(theTocEntryList.size() > 0)
+         {
+            for(unsigned long index = 0; index < theTocEntryList.size(); index++)
+            {
+               theTocEntryList[index]->parseStream(in, rpfHeader->getByteOrder());
+            }
+         }
+         
+         ossimRpfFrameFileIndexSectionSubheader     *frameFileIndexHead = rpfHeader->getNewFrameFileIndexSectionSubheader(in);
+         // get the offset to the table
+         long offsetToIndexSubsection = in.tellg();
+         if(frameFileIndexHead)
+         {
+            ossimRpfFrameFileIndexRecord tempIndexRec;
+            ossimRpfPathnameRecord       tempPathNameRec;
+            
+            long count = frameFileIndexHead->getNumberOfIndexRecords();
+            while(count > 0)
+            {
+               tempIndexRec.parseStream(in, rpfHeader->getByteOrder() );
+
+               // get the path information.  we must seek to a different location
+               // within the file.  So we must remember where we currently are at
+               long currentPosition = in.tellg();
+               
+               in.seekg(offsetToIndexSubsection + tempIndexRec.getPathnameRecordOffset(), ios::beg);
+               tempPathNameRec.parseStream(in, rpfHeader->getByteOrder());
+
+               // We have the root directory where all frame files are subfiles of
+               ossimString rootDirectory(ossimFilename(theFilename.path())+
+                                           ossimFilename(ossimFilename::thePathSeparator));
+
+               // we have the actual path from the root directory to the frame file.  We must
+               // separate the two.  There have been occurrences where the path in the A.TOC file
+               // is upper case but the path in the directory on the file system is lower case.  This
+               // will fool the system in thinking the file doesnot exist when it actually does.
+               ossimString pathToFrameFile( ossimFilename(tempPathNameRec.getPathname()) +
+                                              tempIndexRec.getFilename());
+               ossimRpfFrameEntry entry(rootDirectory,
+                                        pathToFrameFile);
+               theTocEntryList[tempIndexRec.getBoundaryRecNumber()]->setEntry(entry,
+                                                                              tempIndexRec.getLocationRowNumber(),
+                                                                              tempIndexRec.getLocationColNumber());
+               // now go back to where we were
+               in.seekg(currentPosition, ios::beg);
+               
+               --count;
+            }
+         }
+      }
+      delete boundaryRect;
+      boundaryRect = NULL;
+   }
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfToc::buildTocEntryList: leaving..... " << std::endl;
+   }
+}
+
+void ossimRpfToc::allocateTocEntryList(unsigned long numberOfEntries)
+{
+   if(theTocEntryList.size() > 0)
+   {
+      deleteTocEntryList();
+   }
+   for(unsigned long index = 0; index < numberOfEntries; index++)
+   {
+      theTocEntryList.push_back(new ossimRpfTocEntry);
+   }   
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfToc.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfToc.h
new file mode 100644
index 0000000000..65e7d30336
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfToc.h
@@ -0,0 +1,81 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description: 
+//
+//*************************************************************************
+// $Id: ossimRpfToc.h,v 1.2 2003/05/13 11:31:10 dburken Exp $
+#ifndef osimRpfToc_HEADER
+#define osimRpfToc_HEADER
+#include <vector>
+using namespace std;
+
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+#include "base/data_types/ossimFilename.h"
+
+class ossimRpfHeader;
+class ossimRpfBoundaryRectTable;
+class ossimRpfTocEntry;
+
+class ossimRpfToc
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfToc& data);
+   ossimRpfToc();
+   virtual ~ossimRpfToc();
+
+   ossimErrorCode parseFile(const ossimFilename &fileName);
+   void print(ostream& out)const;
+   
+   unsigned long getNumberOfEntries()const{return theTocEntryList.size();}
+   const ossimRpfTocEntry* getTocEntry(unsigned long index)const;
+   /*!
+    * Returns -1 if not found.
+    */
+   ossim_int32 getTocEntryIndex(const ossimRpfTocEntry* entry);
+   
+   const ossimRpfHeader* getRpfHeader()const{return theRpfHeader;}
+   
+private:
+   void deleteAll();
+   void clearAll();
+   void deleteTocEntryList();
+   void buildTocEntryList(ossimRpfHeader* rpfHeader);
+   void allocateTocEntryList(unsigned long numberOfEntries);
+
+   /*!
+    * This will hold a list of table of content entries.  There is one entry
+    * per directory.  Each entry will have its geographic coverage.
+    * Each directory is then divided into frames.  There could be 30 or
+    * more frame images that make up an entire image.
+    */
+   vector<ossimRpfTocEntry*> theTocEntryList;
+   
+   /*!
+    * We will remember the file that we opened
+    */
+   ossimFilename theFilename;
+
+   ossimRpfHeader*                          theRpfHeader;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfTocEntry.cpp b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfTocEntry.cpp
new file mode 100644
index 0000000000..a6dda52b02
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfTocEntry.cpp
@@ -0,0 +1,133 @@
+#include "ossimRpfTocEntry.h"
+#include "base/common/ossimCommon.h"
+#include "base/common/ossimErrorCodes.h"
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+ostream& operator <<(ostream& out,
+                     const ossimRpfTocEntry& data)
+{
+   data.print(out);
+
+   return out;
+}
+
+
+ossimRpfTocEntry::ossimRpfTocEntry()
+{
+   
+}
+
+ossimErrorCode ossimRpfTocEntry::parseStream(istream &in, ossimByteOrder byteOrder)
+{
+   ossimErrorCode result = ossimErrorCodes::OSSIM_OK;
+   
+   result = theBoundaryInformation.parseStream(in, byteOrder);
+   if(result == ossimErrorCodes::OSSIM_OK)
+   {
+      allocateFrameEntryArray();
+   }
+
+   return result;
+}
+
+void ossimRpfTocEntry::print(ostream& out)const
+{
+   out << theBoundaryInformation << endl;
+
+   vector< vector<ossimRpfFrameEntry> >::const_iterator frameEntry =
+                                          theFrameEntryArray.begin();
+
+   while(frameEntry != theFrameEntryArray.end())
+   {
+      copy((*frameEntry).begin(),
+           (*frameEntry).end(),
+           ostream_iterator<ossimRpfFrameEntry>(out, "\n"));
+      
+      ++frameEntry;
+   }
+}
+
+unsigned long ossimRpfTocEntry::getNumberOfFramesHorizontal()const
+{
+   return theBoundaryInformation.getNumberOfFramesHorizontal();
+}
+
+unsigned long ossimRpfTocEntry::getNumberOfFramesVertical()const
+{
+   return theBoundaryInformation.getNumberOfFramesVertical();
+}
+
+void ossimRpfTocEntry::setEntry(const ossimRpfFrameEntry& entry,
+                                long row,
+                                long col)
+{
+   if(row < (long)theFrameEntryArray.size())
+   {
+      if(col < (long)theFrameEntryArray[row].size())
+      {
+         theFrameEntryArray[row][col] = entry;
+      }
+   }
+}
+
+bool ossimRpfTocEntry::getEntry(long row,
+                                long col,
+                                ossimRpfFrameEntry& result)const
+{
+   if(row < (long)theFrameEntryArray.size())
+   {
+      if(col < (long)theFrameEntryArray[row].size())
+      {
+         result = theFrameEntryArray[row][col];
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   return true;
+}
+
+/*!
+ * If there is an entry and all the files don't exist we will return
+ * true.
+ */
+bool ossimRpfTocEntry::isEmpty()const
+{
+   long rows = theFrameEntryArray.size();
+   long cols = 0;
+   if(rows > 0)
+   {
+      cols = theFrameEntryArray[0].size();
+      for(long rowIndex = 0; rowIndex < rows; ++ rowIndex)
+      {
+         for(long colIndex = 0; colIndex < cols; ++colIndex)
+         {
+            if(theFrameEntryArray[rowIndex][colIndex].exists())
+            {
+               return false;
+            }
+         }
+      }
+   }
+
+   return true;
+}
+
+void ossimRpfTocEntry::allocateFrameEntryArray()
+{
+   theFrameEntryArray.resize(theBoundaryInformation.getNumberOfFramesVertical());
+   unsigned long horizontalSize = theBoundaryInformation.getNumberOfFramesHorizontal();
+
+   for(unsigned long index = 0; index < theFrameEntryArray.size(); index++)
+   {
+      theFrameEntryArray[index].resize(horizontalSize);
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfTocEntry.h b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfTocEntry.h
new file mode 100644
index 0000000000..b6405836df
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/rpf/ossimRpfTocEntry.h
@@ -0,0 +1,83 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: Rpf support class
+// 
+//********************************************************************
+// $Id: ossimRpfTocEntry.h,v 1.1 2003/04/02 20:45:00 gpotts Exp $
+#ifndef ossimRpfTocEntry_HEADER
+#define ossimRpfTocEntry_HEADER
+#include <vector>
+#include <iostream>
+#include <iterator>
+using namespace std;
+
+#include "ossimRpfBoundaryRectRecord.h"
+#include "base/common/ossimConstants.h" // ossiByteOrder and RPF constants
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+#include "ossimRpfFrameEntry.h"
+
+class ossimRpfTocEntry
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimRpfTocEntry& data);
+   ossimRpfTocEntry();
+   ossimErrorCode parseStream(istream &in, ossimByteOrder byteOrder);
+   void print(ostream& out)const;
+   void setEntry(const ossimRpfFrameEntry& entry,
+                 long row,
+                 long col);
+
+   bool getEntry(long row,
+                 long col,
+                 ossimRpfFrameEntry& result)const;
+
+   ossimString getProductType()const{return theBoundaryInformation.getProductType();}
+   /*!
+    * returns how many subimges or frames exist in the horizontal
+    * direction.
+    */
+   unsigned long getNumberOfFramesHorizontal()const;
+
+   /*!
+    * returns how many subimges or frames exist in the vertical
+    * direction.
+    */
+   unsigned long getNumberOfFramesVertical()const;
+
+   
+   const ossimRpfBoundaryRectRecord& getBoundaryInformation()const
+      {
+         return theBoundaryInformation;
+      }
+   /*!
+    * If there is an entry and all the files don't exist we will return
+    * true.
+    */
+   bool isEmpty()const;
+   
+private:
+   void allocateFrameEntryArray();
+   
+   ossimRpfBoundaryRectRecord           theBoundaryInformation;
+   vector< vector<ossimRpfFrameEntry> > theFrameEntryArray;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/spot/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/spot/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/spot/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/support_data/spot/ossimSpotDimapSupportData.cpp b/Utilities/OSSIM/ossim_core/support_data/spot/ossimSpotDimapSupportData.cpp
new file mode 100644
index 0000000000..1e5954d7f8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/spot/ossimSpotDimapSupportData.cpp
@@ -0,0 +1,2073 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  Oscar Kramer (ossim port by D. Burken)
+//
+// Description:
+//
+// Contains definition of class ossimSpotDimapSupportData.
+//
+//*****************************************************************************
+// $Id: ossimSpotDimapSupportData.cpp,v 1.16 2006/01/06 14:19:57 gpotts Exp $
+
+  // #include <cstdio>
+#include <iostream>
+#include <iterator>
+#include <support_data/spot/ossimSpotDimapSupportData.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimXmlDocument.h>
+#include <base/data_types/ossimXmlAttribute.h>
+#include <base/data_types/ossimXmlNode.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/common/ossimTrace.h>
+#include <base/context/ossimNotifyContext.h>
+#include <sstream>
+
+// Define Trace flags for use within this file:
+static ossimTrace traceDebug ("ossimSpotDimapSupportData:debug");
+
+static const ossim_uint32  LAGRANGE_FILTER_SIZE = 8; // num samples considered
+static const ossim_float64 NULL_DOUBLE = 0.0;
+static const ossimDpt3d    NULL_VECTOR (0.0, 0.0, 0.0);
+
+ossimSpotDimapSupportData::ossimSpotDimapSupportData ()
+   :
+   ossimErrorStatusInterface(),
+   theImageID(),
+   theMetadataFile(),
+   theSunAzimuth(0.0),
+   theSunElevation(0.0),
+   theImageSize(0.0, 0.0),
+   theRefGroundPoint(0.0, 0.0, 0.0),
+   theRefImagePoint(0.0, 0.0),
+   theSubImageOffset(0.0, 0.0),
+   theRefLineTime(0.0),
+   theLineSamplingPeriod(0.0),
+   thePixelLookAngleX(),
+   thePixelLookAngleY(),
+   theAttitudeSamples(),
+   theAttSampTimes(),
+   thePosEcfSamples(),
+   theVelEcfSamples(),
+   theEphSampTimes(),
+   theStarTrackerUsed(false),
+   theSwirDataFlag(false),
+   theNumBands(0),
+   theAcquisitionDate(),
+   theIncidenceAngle(0.0),
+   theUlCorner(),
+   theUrCorner(),
+   theLrCorner(),
+   theLlCorner(),
+   theGeoPosImagePoints(),
+   theGeoPosGroundPoints()
+{
+}
+ossimSpotDimapSupportData::ossimSpotDimapSupportData(const ossimSpotDimapSupportData& rhs)
+   :ossimErrorStatusInterface(rhs),
+    theImageID(rhs.theImageID),
+    theMetadataFile (rhs.theMetadataFile),
+    theSunAzimuth(rhs.theSunAzimuth),
+    theSunElevation(rhs.theSunElevation),
+    theImageSize(rhs.theImageSize),
+    theRefGroundPoint(rhs.theRefGroundPoint),
+    theRefImagePoint(rhs.theRefImagePoint),
+    theSubImageOffset(rhs.theSubImageOffset),
+    theRefLineTime(rhs.theRefLineTime),
+    theLineSamplingPeriod(rhs.theLineSamplingPeriod),
+    thePixelLookAngleX(rhs.thePixelLookAngleX),
+    thePixelLookAngleY(rhs.thePixelLookAngleY),
+    theAttitudeSamples(rhs.theAttitudeSamples),
+    theAttSampTimes(rhs.theAttSampTimes),
+    thePosEcfSamples(rhs.thePosEcfSamples),
+    theVelEcfSamples(rhs.theVelEcfSamples),
+    theEphSampTimes(rhs.theEphSampTimes),
+    theStarTrackerUsed(rhs.theStarTrackerUsed),
+    theSwirDataFlag (rhs.theSwirDataFlag),
+    theNumBands(rhs.theNumBands),
+    theAcquisitionDate(rhs.theAcquisitionDate),
+    theIncidenceAngle(rhs.theIncidenceAngle),
+    theUlCorner(rhs.theUlCorner),
+    theUrCorner(rhs.theUrCorner),
+    theLrCorner(rhs.theLrCorner),
+    theLlCorner(rhs.theLlCorner),
+    theGeoPosImagePoints(rhs.theGeoPosImagePoints),
+    theGeoPosGroundPoints(rhs.theGeoPosGroundPoints)
+{
+}
+
+ossimSpotDimapSupportData::ossimSpotDimapSupportData (const ossimFilename& dimapFile, bool  processSwir)
+   :
+   ossimErrorStatusInterface(),
+   theImageID(),
+   theMetadataFile (dimapFile),
+   theSunAzimuth(0.0),
+   theSunElevation(0.0),
+   theImageSize(0.0, 0.0),
+   theRefGroundPoint(0.0, 0.0, 0.0),
+   theRefImagePoint(0.0, 0.0),
+   theSubImageOffset(0.0, 0.0),
+   theRefLineTime(0.0),
+   theLineSamplingPeriod(0.0),
+   thePixelLookAngleX(),
+   thePixelLookAngleY(),
+   theAttitudeSamples(),
+   theAttSampTimes(),
+   thePosEcfSamples(),
+   theVelEcfSamples(),
+   theEphSampTimes(),
+   theStarTrackerUsed(false),
+   theSwirDataFlag (processSwir),
+   theNumBands(0),
+   theAcquisitionDate(),
+   theIncidenceAngle(0.0),
+   theUlCorner(),
+   theUrCorner(),
+   theLrCorner(),
+   theLlCorner(),
+   theGeoPosImagePoints(),
+   theGeoPosGroundPoints()
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimSpotDimapSupportData::ossimSpotDimapSupportData: entering..."
+         << std::endl;
+   }
+      
+   loadXmlFile(dimapFile, processSwir);
+   
+   // Finished successful parse:
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "ossimSpotDimapSupportData::ossimSpotDimapSupportData: leaving..."
+         << std::endl;
+   }
+}
+
+ossimSpotDimapSupportData::~ossimSpotDimapSupportData ()
+{
+}
+
+ossimObject* ossimSpotDimapSupportData::dup()const
+{
+   return new ossimSpotDimapSupportData(*this);
+}
+
+void ossimSpotDimapSupportData::clearFields()
+{
+   clearErrorStatus();
+
+   theImageID = "";
+   theMetadataFile = "";
+   theSunAzimuth = 0.0;
+   theSunElevation = 0.0;
+   theImageSize = ossimDpt();
+   theRefGroundPoint = ossimGpt();
+   theRefImagePoint = ossimDpt();
+   theSubImageOffset = ossimDpt();
+   theRefLineTime = 0.0;
+   theLineSamplingPeriod = 0.0;
+   thePixelLookAngleX.clear();
+   thePixelLookAngleY.clear();
+   theAttitudeSamples.clear(); // x=pitch, y=roll, z=yaw
+   theAttSampTimes.clear();
+   thePosEcfSamples.clear();
+   theVelEcfSamples.clear();
+   theEphSampTimes.clear();
+   theStarTrackerUsed = false;
+   theSwirDataFlag = false;
+   theNumBands = 0;
+   theAcquisitionDate = "";
+   theIncidenceAngle = 0;
+
+   //---
+   // Corner points:
+   //---
+   theUlCorner = ossimGpt();
+   theUrCorner = ossimGpt();
+   theLrCorner = ossimGpt();
+   theLlCorner = ossimGpt();
+
+   //---
+   // Geoposition Points:
+   //---
+   theGeoPosImagePoints.clear();
+   theGeoPosGroundPoints.clear();
+
+}
+
+bool ossimSpotDimapSupportData::loadXmlFile(const ossimFilename& file,
+                                            bool processSwir)
+{
+   static const char MODULE[] = "ossimSpotDimapSupportData::loadXmlFile";
+   
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " DEBUG:"
+         << "\nFile: " << file << endl;
+   }
+   
+   clearFields();
+   theSwirDataFlag = processSwir;
+   theMetadataFile = file;
+
+   //---
+   // Instantiate the XML parser:
+   //---
+   ossimRefPtr<ossimXmlDocument> xmlDocument = new ossimXmlDocument(file);
+   if (xmlDocument->getErrorStatus())
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << MODULE << " DEBUG:"
+            << "ossimSpotDimapSupportData::loadXmlFile:"
+            << "\nUnable to parse xml file" << std::endl;
+      }
+      setErrorStatus();
+      return false;
+   }
+   
+   if (parsePart1(xmlDocument) == false)
+   {
+      return false;
+   }
+   
+   if (parsePart2(xmlDocument) == false)
+   {
+      return false;
+   }
+
+   bool status = parsePart3(xmlDocument);
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " DEBUG: exited..."
+         << endl;
+   }
+   
+   return status;
+}
+
+void ossimSpotDimapSupportData::getPositionEcf(ossim_uint32 sample,
+                                               ossimEcefPoint& pe)  const
+{
+   pe = NULL_VECTOR;
+
+   if (thePosEcfSamples.size() < theImageSize.samp)
+   {
+      if(theImageSize.samp > 0)
+      {
+         double t = 0.0;
+         double tempIdx = 0.0;
+         double tempIdxFraction = 0.0;
+         t = (double)sample/(double)(theImageSize.samp-1);
+         tempIdx = (thePosEcfSamples.size()-1)*t;
+         tempIdxFraction = tempIdx - (ossim_int32)tempIdx;
+         ossim_uint32 idxStart = (ossim_uint32)tempIdx;
+         ossim_uint32 idxEnd = (ossim_uint32)ceil(tempIdx);
+         if(idxEnd >= thePosEcfSamples.size())
+         {
+            idxEnd = thePosEcfSamples.size()-1;
+         }
+         if(idxStart > idxEnd)
+         {
+            idxStart = idxEnd;
+         }
+         pe = ossimEcefPoint(thePosEcfSamples[idxStart].x +tempIdxFraction*( thePosEcfSamples[idxEnd].x - thePosEcfSamples[idxStart].x),
+                             thePosEcfSamples[idxStart].y +tempIdxFraction*( thePosEcfSamples[idxEnd].y - thePosEcfSamples[idxStart].y),
+                             thePosEcfSamples[idxStart].z +tempIdxFraction*( thePosEcfSamples[idxEnd].z - thePosEcfSamples[idxStart].z));
+         
+      }
+   }
+   else if(thePosEcfSamples.size() == theImageSize.samp)
+   {
+      pe = ossimEcefPoint(thePosEcfSamples[sample].x,
+                          thePosEcfSamples[sample].y,
+                          thePosEcfSamples[sample].z);
+   }
+}
+
+void ossimSpotDimapSupportData::getPositionEcf(const ossim_float64& time,
+                                               ossimEcefPoint& pe)  const
+{
+   ossimDpt3d tempPt;
+   
+   if((thePosEcfSamples.size() < 8)||
+      (theEphSampTimes.size() < 8))
+   {
+      getBilinearInterpolation(time, thePosEcfSamples, theEphSampTimes, tempPt);
+   }
+   else
+   {
+      getLagrangeInterpolation(time, thePosEcfSamples, theEphSampTimes, tempPt);
+   }
+
+   pe = ossimEcefPoint(tempPt.x,
+                       tempPt.y,
+                       tempPt.z);
+}
+
+void ossimSpotDimapSupportData::getVelocityEcf(ossim_uint32 sample, ossimEcefPoint& ve)  const
+{
+   ve = NULL_VECTOR;
+   
+   if (theVelEcfSamples.size() < theImageSize.samp)
+   {
+      if(theImageSize.samp > 0)
+      {
+         double t = 0.0;
+         double tempIdx = 0.0;
+         double tempIdxFraction = 0.0;
+         t = (double)sample/(double)(theImageSize.samp-1);
+         tempIdx = (theVelEcfSamples.size()-1)*t;
+         tempIdxFraction = tempIdx - (ossim_int32)tempIdx;
+          ossim_uint32 idxStart = (ossim_uint32)tempIdx;
+         ossim_uint32 idxEnd = (ossim_uint32)ceil(tempIdx);
+         if(idxEnd >= theVelEcfSamples.size())
+         {
+            idxEnd = theVelEcfSamples.size()-1;
+         }
+         if(idxStart > idxEnd)
+         {
+            idxStart = idxEnd;
+         }
+         ve = ossimEcefPoint(theVelEcfSamples[idxStart].x +tempIdxFraction*( theVelEcfSamples[idxEnd].x - theVelEcfSamples[idxStart].x),
+                             theVelEcfSamples[idxStart].y +tempIdxFraction*( theVelEcfSamples[idxEnd].y - theVelEcfSamples[idxStart].y),
+                             theVelEcfSamples[idxStart].z +tempIdxFraction*( theVelEcfSamples[idxEnd].z - theVelEcfSamples[idxStart].z));
+       
+      }
+
+   }
+   else if(theVelEcfSamples.size() == theImageSize.samp)
+   {
+      ve = ossimEcefPoint(theVelEcfSamples[sample].x,
+                          theVelEcfSamples[sample].y,
+                          theVelEcfSamples[sample].z);
+   }
+}
+
+void ossimSpotDimapSupportData::getVelocityEcf(const ossim_float64& time,
+                                               ossimEcefPoint& ve)  const
+{
+   ossimDpt3d tempPt;
+
+   if((theVelEcfSamples.size() < 8) ||
+      (theEphSampTimes.size() < 8))
+   {
+      getBilinearInterpolation (time, theVelEcfSamples, theEphSampTimes, tempPt);
+   }
+   else
+   {
+      getLagrangeInterpolation (time, theVelEcfSamples, theEphSampTimes, tempPt);
+   }
+
+   ve = ossimEcefPoint(tempPt.x,
+                       tempPt.y,
+                       tempPt.z);
+}
+
+void ossimSpotDimapSupportData::getEphSampTime(ossim_uint32 sample,
+                                               ossim_float64& et)  const
+{
+   et = NULL_DOUBLE;
+   if(theEphSampTimes.size() < theImageSize.samp)
+   {
+      if(theImageSize.samp > 0)
+      {
+         double t = 0.0;
+         double tempIdx = 0.0;
+         double tempIdxFraction = 0.0;
+         t = (double)sample/(double)(theImageSize.samp-1);
+         tempIdx = (theEphSampTimes.size()-1)*t;
+         tempIdxFraction = tempIdx - (ossim_int32)tempIdx;
+         ossim_uint32 idxStart = (ossim_uint32)tempIdx;
+         ossim_uint32 idxEnd = (ossim_uint32)ceil(tempIdx);
+         if(idxEnd >= theEphSampTimes.size())
+         {
+            idxEnd = theEphSampTimes.size()-1;
+         }
+         if(idxStart > idxEnd)
+         {
+            idxStart = idxEnd;
+         }
+         et = (theEphSampTimes[idxStart] +tempIdxFraction*(theEphSampTimes[idxEnd] -
+                                                           theEphSampTimes[idxStart]));
+      }
+   }
+   else if(theEphSampTimes.size() == theImageSize.samp)
+   {
+      et = theEphSampTimes[sample];
+   }
+}
+
+void ossimSpotDimapSupportData::getAttitude(ossim_uint32 sample,
+                                            ossimDpt3d& at)  const
+{
+   if (sample >= theAttitudeSamples.size())
+   {
+      at = NULL_VECTOR;
+      return;
+   }
+
+   at = theAttitudeSamples[sample];
+}
+
+void ossimSpotDimapSupportData::getAttitude(const ossim_float64& time,
+                                            ossimDpt3d& at)  const
+{
+   if ((time <  theAttSampTimes.front()) ||
+       (time >= theAttSampTimes.back() ))
+   {
+      at = NULL_VECTOR;
+      return;
+   }
+
+   //***
+   // Search the attitude sampling time array for surrounding samples:
+   //***
+   int i=0;
+   while ((i < (int)theAttSampTimes.size()) &&
+          (theAttSampTimes[i] < time)) ++i;
+   --i;
+
+   //***
+   // Linearly interpolate attitudes angles:
+   //***
+   ossim_float64 dt1   = time - theAttSampTimes[i];
+   ossim_float64 dt0   = theAttSampTimes[i+1] - time;
+   ossim_float64 dt    = theAttSampTimes[i+1] - theAttSampTimes[i];
+
+   at = (theAttitudeSamples[i+1]*dt1 + theAttitudeSamples[i]*dt0)/dt;
+}
+
+void ossimSpotDimapSupportData::getAttSampTime(ossim_uint32 sample, ossim_float64& at)  const
+{
+   if (sample >= theAttSampTimes.size())
+   {
+      at = NULL_DOUBLE;
+      return;
+   }
+
+   at = theAttSampTimes[sample];
+}
+
+void ossimSpotDimapSupportData::getPixelLookAngleX(ossim_uint32 sample,
+                                                   ossim_float64& pa) const
+{
+   if (sample >= thePixelLookAngleX.size())
+   {
+      setErrorStatus();
+      pa = NULL_DOUBLE;
+
+      return;
+   }
+
+   pa = thePixelLookAngleX[sample];
+}
+
+void ossimSpotDimapSupportData::getPixelLookAngleX(const ossim_float64& sample,
+                                                   ossim_float64& pa) const
+{
+   ossim_uint32 s = static_cast<ossim_uint32>(sample);
+   getInterpolatedLookAngle(s, thePixelLookAngleX, pa);
+}
+
+void ossimSpotDimapSupportData::getPixelLookAngleY(ossim_uint32 sample,
+                                                   ossim_float64& pa) const
+{
+   if (sample >= thePixelLookAngleY.size())
+   {
+      setErrorStatus();
+      pa = NULL_DOUBLE;
+      return;
+   }
+
+   pa = thePixelLookAngleY[sample];
+}
+
+void ossimSpotDimapSupportData::getPixelLookAngleY(const ossim_float64& sample,
+                                                   ossim_float64& pa) const
+{
+   ossim_uint32 s = static_cast<ossim_uint32>(sample);
+   getInterpolatedLookAngle(s, thePixelLookAngleY, pa);
+}
+
+void ossimSpotDimapSupportData::getInterpolatedLookAngle(const ossim_float64& p, const vector<ossim_float64>& angles, ossim_float64& la) const
+{
+   if ((p < 0.0) || (p >= (ossim_float64) angles.size()))
+   {
+      setErrorStatus();
+      la = NULL_DOUBLE;
+      return;
+   }
+
+   ossim_float64 p0 = floor(p);
+   ossim_float64 p1 = ceil (p);
+
+   if (p0 == p1)
+   {
+      la = angles[(int) p0];
+   }
+   else
+   {
+      ossim_float64 angle_0 = angles[(int) p0];
+      ossim_float64 angle_1 = angles[(int) p1];
+
+      la = (angle_0*(p1-p) + angle_1*(p-p0))/(p1-p0);
+   }
+}
+
+void ossimSpotDimapSupportData::getBilinearInterpolation(const ossim_float64& time, const vector<ossimDpt3d>& V, const vector<ossim_float64>& T, ossimDpt3d& li) const
+{
+   ossim_uint32 samp0 = 0;
+   while ((samp0 < T.size()) && (T[samp0] < time)) ++samp0;
+
+   if(samp0==0)
+   {
+      li = V[0];
+   }
+   else if(samp0 == T.size())
+   {
+      li = V[1];
+   }
+   else
+   {
+      double t = (T[samp0-1]-time)/(T[samp0-1] - T[samp0]);
+      
+      li = V[samp0-1] + (V[samp0]-V[samp0-1])*t;
+   }
+}
+
+void ossimSpotDimapSupportData::getLagrangeInterpolation(const ossim_float64& time, const vector<ossimDpt3d>& V, const vector<ossim_float64>& T, ossimDpt3d& li) const
+
+{
+//    std::cout << "V size = " << V.size() << std::endl
+//              << "T size = " << T.size() << std::endl;
+   
+   ossim_uint32 filter_size = 8;
+   //
+   // Verify that t is within allowable range:
+   //
+   ossim_uint32 lagrange_half_filter = 4;
+
+   if(T.size() <= filter_size)
+   {
+      filter_size = T.size()/2;
+      lagrange_half_filter = filter_size/2;
+   }
+   if ((time <  T[lagrange_half_filter]) ||
+       (time >= T[T.size()-lagrange_half_filter] ))
+   {
+      setErrorStatus();
+      li = NULL_VECTOR;
+
+      return;
+   }
+
+   //***
+   // Search the sampling time array for surrounding samples:
+   //***
+   ossim_uint32 samp0 = lagrange_half_filter;
+   while ((samp0 < T.size()) && (T[samp0] < time)) ++samp0;
+
+   //***
+   // Do not use sample if it falls in neighborhood of desired time:
+   //***
+   ossim_uint32 bump = 0;
+   if (fabs(T[samp0] - time) < theLineSamplingPeriod/2.0)
+      bump = 1;
+
+   samp0 -= lagrange_half_filter; // adjust to first sample in window
+
+   //***
+   // Outer summation loop:
+   //***
+   ossimDpt3d S (0, 0, 0);
+   for (ossim_uint32 j=samp0; j<(samp0+filter_size+bump); ++j)
+   {
+      ossim_float64 numerator   = 1.0;
+      ossim_float64 denominator = 1.0;
+
+      //***
+      // Skip this sample if too close to desired time:
+      //***
+      if (bump && (j == (samp0+lagrange_half_filter) ))
+         ++j;
+
+      //***
+      // Inner loop for product series:
+      //***
+      for (ossim_uint32 i=samp0; i<(samp0+filter_size+bump); ++i)
+      {
+         //***
+         // Skip this sample if too close to desired time:
+         //***
+         if (bump && (i == (samp0+lagrange_half_filter) ))
+            ++i;
+
+         if (i != j)
+         {
+            numerator   *= time - T[i];
+            denominator *= T[j] - T[i];
+         }
+      }
+
+      ossimDpt3d p = V[j];
+      p = p * numerator;
+      p = p / denominator;
+      S += p;
+   }
+
+   li = S;
+}
+
+ossim_float64 ossimSpotDimapSupportData::convertTimeStamp(const ossimString& time_stamp) const
+{
+   double ti;
+   convertTimeStamp(time_stamp, ti);
+   return ti;
+}
+
+void ossimSpotDimapSupportData::convertTimeStamp(const ossimString& time_stamp,
+                                                 ossim_float64& ti) const
+{
+   int    year, month, day, hour, minute;
+   double second;
+
+   //***
+   // Time stamps are in the format: "yyyy-mm-ddThh:mm:ss.ssssss"
+   //***
+   int converted = sscanf(time_stamp,
+                          "%4d-%2d-%2dT%2d:%2d:%9lf",
+                          &year, &month, &day,
+                          &hour, &minute, &second);
+
+   if (converted != 6)
+   {
+      setErrorStatus();
+      ti = OSSIM_DBL_NAN;
+   }
+   else
+   {
+      ti = (((((year-2002.0)*12.0 + month - 1.0)*365.0 + day - 1.0)*24.0
+             + hour)*60.0 + minute)*60.0 + second;
+   }
+}
+
+void ossimSpotDimapSupportData::getGeoPosPoint (ossim_uint32 point,
+                                                ossimDpt& ip,
+                                                ossimGpt& gp) const
+{
+   if ((point >= 0) && point < theGeoPosImagePoints.size())
+   {
+      ip = theGeoPosImagePoints [point];
+      gp = theGeoPosGroundPoints[point];
+   }
+}
+
+void ossimSpotDimapSupportData::printInfo(ostream& os) const
+{
+   ossimString corr_att = "NO";
+   if (theStarTrackerUsed)
+      corr_att = "YES";
+
+   os << "\n----------------- Info on SPOT5 Image -------------------"
+      << "\n  "
+      << "\n  Job Number (ID):    " << theImageID
+      << "\n  Acquisition Date:   " << theAcquisitionDate
+      << "\n  Number of Bands:    " << theNumBands
+      << "\n  Geo Center Point:   " << theRefGroundPoint
+      << "\n  Image Size:         " << theImageSize
+      << "\n  Incidence Angle:    " << theIncidenceAngle
+      << "\n  Corrected Attitude: " << corr_att
+      << "\n  Sun Azimuth:        " << theSunAzimuth
+      << "\n  Sun Elevation:      " << theSunElevation
+      << "\n  Sub image offset    " << theSubImageOffset
+      << "\n  "
+      << "\n  Corner Points:"
+      << "\n     UL: " << theUlCorner
+      << "\n     UR: " << theUrCorner
+      << "\n     LR: " << theLrCorner
+      << "\n     LL: " << theLlCorner
+      << "\n"
+      << "\n---------------------------------------------------------"
+      << "\n  " << endl;
+}
+
+ossimString ossimSpotDimapSupportData::getAcquisitionDate() const
+{
+   return theAcquisitionDate;
+}
+
+ossimString ossimSpotDimapSupportData::getImageID() const
+{
+   return theImageID;
+}
+
+ossimFilename ossimSpotDimapSupportData::getMetadataFile() const
+{
+   return theMetadataFile;
+}
+
+void ossimSpotDimapSupportData::getSunAzimuth(ossim_float64& az) const
+{
+   az = theSunAzimuth;
+}
+
+void ossimSpotDimapSupportData::getSunElevation(ossim_float64& el) const
+{
+   el = theSunElevation;
+}
+
+void ossimSpotDimapSupportData::getImageSize(ossimDpt& sz) const
+{
+   sz = theImageSize;
+}
+
+void ossimSpotDimapSupportData::getLineSamplingPeriod(ossim_float64& pe) const
+{
+   pe = theLineSamplingPeriod;
+}
+
+bool ossimSpotDimapSupportData::isStarTrackerUsed() const
+{
+   return theStarTrackerUsed;
+}
+
+bool ossimSpotDimapSupportData::isSwirDataUsed() const
+{
+   return theSwirDataFlag;
+}
+
+ossim_uint32 ossimSpotDimapSupportData::getNumberOfBands() const
+{
+   return theNumBands;
+}
+
+void ossimSpotDimapSupportData::getIncidenceAngle(ossim_float64& ia) const
+{
+   ia = theIncidenceAngle;
+}
+
+void ossimSpotDimapSupportData::getRefGroundPoint(ossimGpt& gp) const
+{
+   gp = theRefGroundPoint;
+}
+
+void ossimSpotDimapSupportData::getRefImagePoint(ossimDpt& rp) const
+{
+   rp = theRefImagePoint;
+}
+
+void ossimSpotDimapSupportData::getRefLineTime(ossim_float64& rt) const
+{
+   rt = theRefLineTime;
+}
+
+ossim_uint32 ossimSpotDimapSupportData::getNumEphSamples() const
+{
+   return theEphSampTimes.size();
+}
+
+ossim_uint32 ossimSpotDimapSupportData::getNumAttSamples() const
+{
+   return theAttSampTimes.size();
+}
+
+ossim_uint32 ossimSpotDimapSupportData::getNumGeoPosPoints() const
+{
+   return theGeoPosImagePoints.size();
+}
+
+void ossimSpotDimapSupportData::getUlCorner(ossimGpt& pt) const
+{
+   pt = theUlCorner;
+}
+
+void ossimSpotDimapSupportData::getUrCorner(ossimGpt& pt) const
+{
+   pt = theUrCorner;
+}
+
+void ossimSpotDimapSupportData::getLrCorner(ossimGpt& pt) const
+{
+   pt = theLrCorner;
+}
+
+void ossimSpotDimapSupportData::getLlCorner(ossimGpt& pt) const
+{
+   pt = theLlCorner;
+}
+
+ossimDrect ossimSpotDimapSupportData::getImageRect()const
+{
+   return ossimDrect(theSubImageOffset.x,
+                     theSubImageOffset.y,
+                     theSubImageOffset.x + (theImageSize.x -1),
+                     theSubImageOffset.y + (theImageSize.y -1));
+}
+
+void ossimSpotDimapSupportData::getSubImageOffset(ossimDpt& offset) const
+{
+   offset = theSubImageOffset;
+}
+
+bool ossimSpotDimapSupportData::saveState(ossimKeywordlist& kwl,
+                                          const char* prefix)const
+{
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           "ossimSpotDimapSupportData",
+           true);
+
+   kwl.add(prefix,
+           "metadata_file",
+           theMetadataFile,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::AZIMUTH_ANGLE_KW,
+           theSunAzimuth,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::ELEVATION_ANGLE_KW,
+           theSunElevation,
+           true);
+
+   kwl.add(prefix,
+           "image_size",
+           ossimString::toString(theImageSize.x) + " " +
+           ossimString::toString(theImageSize.y),
+           true);
+
+   kwl.add(prefix,
+           "reference_ground_point",
+           ossimString::toString(theRefGroundPoint.latd()) + " " +
+           ossimString::toString(theRefGroundPoint.lond()) + " " +
+           ossimString::toString(theRefGroundPoint.height()) + " " +
+           theRefGroundPoint.datum()->code(),
+           true);
+
+   kwl.add(prefix,
+           "reference_image_point",
+           ossimString::toString(theRefImagePoint.x) + " " +
+           ossimString::toString(theRefImagePoint.y),
+           true);
+
+   kwl.add(prefix,
+           "sub_image_offset",
+           ossimString::toString(theSubImageOffset.x) + " " +
+           ossimString::toString(theSubImageOffset.y),
+           true);
+
+   kwl.add(prefix,
+           "reference_line_time",
+           theRefLineTime,
+           true);
+
+   kwl.add(prefix,
+           "line_sampling_period",
+           theLineSamplingPeriod,
+           true);
+
+   ossimString tempString;
+   ossim_int32 idx = 0;
+
+   tempString = "";
+   for(idx = 0; idx < (ossim_int32)thePixelLookAngleX.size(); ++idx)
+   {
+      tempString += (ossimString::toString(thePixelLookAngleX[idx]) + " ");
+   }
+
+   kwl.add(prefix,
+           "pixel_lookat_angle_x",
+           tempString,
+           true);
+
+   kwl.add(prefix,
+           "number_of_pixel_lookat_angle_x",
+           thePixelLookAngleX.size(),
+           true);
+
+   tempString = "";
+   for(idx = 0; idx < (ossim_int32)thePixelLookAngleY.size(); ++idx)
+   {
+      tempString += (ossimString::toString(thePixelLookAngleY[idx]) + " ");
+   }
+   kwl.add(prefix,
+           "pixel_lookat_angle_y",
+           tempString,
+           true);
+   kwl.add(prefix,
+           "number_of_pixel_lookat_angle_y",
+           thePixelLookAngleY.size(),
+           true);
+
+
+   tempString = "";
+   for(idx = 0; idx < (ossim_int32)theAttitudeSamples.size(); ++idx)
+   {
+      tempString += (ossimString::toString(theAttitudeSamples[idx].x) + " " +
+                     ossimString::toString(theAttitudeSamples[idx].y) + " " +
+                     ossimString::toString(theAttitudeSamples[idx].z) + " ");
+   }
+   kwl.add(prefix,
+           "attitude_samples",
+           tempString,
+           true);
+   kwl.add(prefix,
+           "number_of_attitude_samples",
+           theAttitudeSamples.size(),
+           true);
+
+   tempString = "";
+   for(idx = 0; idx < (ossim_int32)theAttSampTimes.size(); ++idx)
+   {
+      tempString += (ossimString::toString(theAttSampTimes[idx]) + " ");
+   }
+   kwl.add(prefix,
+           "attitude_sample_times",
+           tempString,
+           true);
+   kwl.add(prefix,
+           "number_of_attitude_sample_times",
+           theAttSampTimes.size(),
+           true);
+
+   tempString = "";
+   for(idx = 0; idx < (ossim_int32)thePosEcfSamples.size(); ++idx)
+   {
+      tempString += (ossimString::toString(thePosEcfSamples[idx].x) + " " +
+                     ossimString::toString(thePosEcfSamples[idx].y) + " " +
+                     ossimString::toString(thePosEcfSamples[idx].z) + " ");
+   }
+   kwl.add(prefix,
+           "position_ecf_samples",
+           tempString,
+           true);
+   kwl.add(prefix,
+           "number_of_position_ecf_samples",
+           thePosEcfSamples.size(),
+           true);
+
+   tempString = "";
+   for(idx = 0; idx < (ossim_int32)theVelEcfSamples.size(); ++idx)
+   {
+      tempString += (ossimString::toString(theVelEcfSamples[idx].x) + " " +
+                     ossimString::toString(theVelEcfSamples[idx].y) + " " +
+                     ossimString::toString(theVelEcfSamples[idx].z) + " ");
+   }
+   kwl.add(prefix,
+           "velocity_ecf_samples",
+           tempString,
+           true);
+   kwl.add(prefix,
+           "number_of_velocity_ecf_samples",
+           thePosEcfSamples.size(),
+           true);
+
+   tempString = "";
+   for(idx = 0; idx < (ossim_int32)theEphSampTimes.size(); ++idx)
+   {
+      tempString += (ossimString::toString(theEphSampTimes[idx]) + " ");
+   }
+
+   kwl.add(prefix,
+           "ephemeris_sample_times",
+           tempString,
+           true);
+   kwl.add(prefix,
+           "number_of_ephemeris_sample_times",
+           theEphSampTimes.size(),
+           true);
+
+   kwl.add(prefix,
+           "star_tracker_used_flag",
+           (ossim_uint32)theStarTrackerUsed,
+           true);
+
+   kwl.add(prefix,
+           "swir_data_flag",
+           (ossim_uint32)theSwirDataFlag,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_BANDS_KW,
+           theNumBands,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::IMAGE_DATE_KW,
+           theAcquisitionDate,
+           true);
+
+   kwl.add(prefix,
+           "incident_angle",
+           theIncidenceAngle,
+           true);
+
+   kwl.add(prefix,
+           "ul_ground_point",
+           ossimString::toString(theUlCorner.latd()) + " " +
+           ossimString::toString(theUlCorner.lond()) + " " +
+           ossimString::toString(theUlCorner.height()) + " " +
+           theUlCorner.datum()->code(),
+           true);
+
+   kwl.add(prefix,
+           "ur_ground_point",
+           ossimString::toString(theUrCorner.latd()) + " " +
+           ossimString::toString(theUrCorner.lond()) + " " +
+           ossimString::toString(theUrCorner.height()) + " " +
+           theUrCorner.datum()->code(),
+           true);
+
+   kwl.add(prefix,
+           "lr_ground_point",
+           ossimString::toString(theLrCorner.latd()) + " " +
+           ossimString::toString(theLrCorner.lond()) + " " +
+           ossimString::toString(theLrCorner.height()) + " " +
+           theLrCorner.datum()->code(),
+           true);
+
+   kwl.add(prefix,
+           "ll_ground_point",
+           ossimString::toString(theLlCorner.latd()) + " " +
+           ossimString::toString(theLlCorner.lond()) + " " +
+           ossimString::toString(theLlCorner.height()) + " " +
+           theLlCorner.datum()->code(),
+           true);
+
+   return true;
+}
+
+bool ossimSpotDimapSupportData::loadState(const ossimKeywordlist& kwl,
+                                          const char* prefix)
+{
+   clearFields();
+
+   ossimString type = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
+
+   if(type != "ossimSpotDimapSupportData")
+   {
+      return false;
+   }
+   theMetadataFile = kwl.find(prefix, "metadata_file");
+
+   theSunAzimuth   = ossimString(kwl.find(prefix, ossimKeywordNames::AZIMUTH_ANGLE_KW)).toDouble();
+   theSunElevation = ossimString(kwl.find(prefix, ossimKeywordNames::ELEVATION_ANGLE_KW)).toDouble();
+
+   theImageSize      = createDpt(kwl.find(prefix, "image_size"));
+   theRefGroundPoint = createGround(kwl.find(prefix, "reference_ground_point"));
+   theRefImagePoint  = createDpt(kwl.find(prefix, "reference_image_point"));
+   theSubImageOffset = createDpt(kwl.find(prefix, "sub_image_offset"));
+
+   theRefLineTime    = ossimString(kwl.find(prefix, "reference_line_time")).toDouble();
+   theLineSamplingPeriod = ossimString(kwl.find(prefix, "line_sampling_period")).toDouble();
+
+
+   ossim_uint32 idx = 0;
+   ossim_uint32 total =  ossimString(kwl.find(prefix,"number_of_pixel_lookat_angle_x")).toUInt32();
+   ossimString tempString;
+
+   thePixelLookAngleX.resize(total);
+   tempString = kwl.find(prefix,"pixel_lookat_angle_x");
+   if(tempString != "")
+   {
+      std::istringstream in(tempString);
+      double tempValue = 0.0;
+      for(idx = 0; idx < thePixelLookAngleX.size();++idx)
+      {
+         in >> tempValue;
+         thePixelLookAngleX[idx] = tempValue;
+      }
+   }
+
+   total =  ossimString(kwl.find(prefix,"number_of_pixel_lookat_angle_y")).toUInt32();
+   thePixelLookAngleY.resize(total);
+   tempString = kwl.find(prefix,"pixel_lookat_angle_y");
+   if(tempString != "")
+   {
+      std::istringstream in(tempString);
+      double tempValue = 0.0;
+      for(idx = 0; idx < thePixelLookAngleY.size();++idx)
+      {
+         in >> tempValue;
+         thePixelLookAngleY[idx] = tempValue;
+      }
+   }
+
+
+   total =  ossimString(kwl.find(prefix,"number_of_attitude_samples")).toUInt32();
+   theAttitudeSamples.resize(total);
+   tempString = kwl.find(prefix,"attitude_samples");
+   if(tempString != "")
+   {
+      std::istringstream in(tempString);
+      double x, y, z = 0.0;
+      for(idx = 0; idx < theAttitudeSamples.size();++idx)
+      {
+         in >> x >> y >> z;
+         theAttitudeSamples[idx] =ossimDpt3d(x, y, z);
+      }
+   }
+
+   total =  ossimString(kwl.find(prefix,"number_of_attitude_sample_times")).toUInt32();
+   theAttSampTimes.resize(total);
+   tempString = kwl.find(prefix,"attitude_sample_times");
+   if(tempString != "")
+   {
+      std::istringstream in(tempString);
+      double tempValue = 0.0;
+      for(idx = 0; idx < theAttSampTimes.size();++idx)
+      {
+         in >> tempValue;
+         theAttSampTimes[idx] = tempValue;
+      }
+   }
+
+   total =  ossimString(kwl.find(prefix,"number_of_position_ecf_samples")).toUInt32();
+   thePosEcfSamples.resize(total);
+   tempString = kwl.find(prefix,"position_ecf_samples");
+   if(tempString != "")
+   {
+      std::istringstream in(tempString);
+      double x, y, z = 0.0;
+      for(idx = 0; idx < thePosEcfSamples.size();++idx)
+      {
+         in >> x >> y >> z;
+         thePosEcfSamples[idx] = ossimDpt3d(x, y, z);
+      }
+   }
+
+   total =  ossimString(kwl.find(prefix,"number_of_velocity_ecf_samples")).toUInt32();
+   theVelEcfSamples.resize(total);
+   tempString = kwl.find(prefix,"velocity_ecf_samples");
+   if(tempString != "")
+   {
+      std::istringstream in(tempString);
+      double x, y, z = 0.0;
+      for(idx = 0; idx < theVelEcfSamples.size();++idx)
+      {
+         in >> x >> y >> z;
+         theVelEcfSamples[idx] = ossimDpt3d(x, y, z);
+      }
+   }
+
+   total =  ossimString(kwl.find(prefix,"number_of_ephemeris_sample_times")).toUInt32();
+   theEphSampTimes.resize(total);
+   tempString = kwl.find(prefix,"ephemeris_sample_times");
+   if(tempString != "")
+   {
+      std::istringstream in(tempString);
+      double tempValue = 0.0;
+      for(idx = 0; idx < theEphSampTimes.size();++idx)
+      {
+         in >> tempValue;
+         theEphSampTimes[idx] = tempValue;
+      }
+   }
+
+   tempString = "";
+   for(idx = 0; idx < theEphSampTimes.size(); ++idx)
+   {
+      tempString += (ossimString::toString(theEphSampTimes[idx]) + " ");
+   }
+
+   theStarTrackerUsed = ossimString(kwl.find(prefix, "star_tracker_used_flag")).toBool();
+   theSwirDataFlag    = ossimString(kwl.find(prefix, "swir_data_flag")).toBool();
+   theNumBands        = ossimString(kwl.find(prefix, ossimKeywordNames::NUMBER_BANDS_KW)).toUInt32();
+   theAcquisitionDate = kwl.find(prefix, ossimKeywordNames::IMAGE_DATE_KW);
+   theIncidenceAngle  = ossimString(kwl.find(prefix, "incident_angle")).toDouble();
+
+   theUlCorner =createGround( kwl.find(prefix, "ul_ground_point"));
+   theUrCorner =createGround( kwl.find(prefix, "ur_ground_point"));
+   theLrCorner =createGround( kwl.find(prefix, "lr_ground_point"));
+   theLlCorner =createGround( kwl.find(prefix, "ll_ground_point"));
+
+
+   return true;
+}
+
+ossimGpt ossimSpotDimapSupportData::createGround(const ossimString& s)const
+{
+   std::istringstream in(s);
+   double lat, lon, height;
+   ossimString code;
+
+   in >> lat >> lon >> height >> code;
+
+   return ossimGpt(lat,
+                   lon,
+                   height,
+                   ossimDatumFactory::instance()->create(code));
+
+}
+
+ossimDpt ossimSpotDimapSupportData::createDpt(const ossimString& s)const
+{
+   std::istringstream in(s);
+   double x, y;
+   ossimString code;
+
+   in >> x >> y;
+
+   return ossimDpt(x,y);
+
+}
+
+bool ossimSpotDimapSupportData::parsePart1(
+   ossimRefPtr<ossimXmlDocument> xmlDocument)
+{
+   static const char MODULE[] = "ossimSpotDimapSupportData::parsePart1";
+   
+   ossimString xpath;
+   vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
+   vector<ossimRefPtr<ossimXmlNode> > sub_nodes;
+   vector<ossimRefPtr<ossimXmlNode> >::iterator node;
+
+   //---
+   // Fetch the Image ID:
+   //---
+   xpath = "/Dimap_Document/Production/JOB_ID";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }
+      return false;
+   }
+   theImageID = xml_nodes[0]->getText();
+
+   //---
+   // Fetch the Sun Azimuth:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source"
+      "/SUN_AZIMUTH";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }      
+      return false;
+   }
+   theSunAzimuth = xml_nodes[0]->getText().toDouble();
+
+   //---
+   // Fetch the Sun Elevation:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source"
+      "/SUN_ELEVATION";
+    xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }      
+      return false;
+   }
+   theSunElevation = xml_nodes[0]->getText().toDouble();
+
+   //---
+   // Fetch the ImageSize:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Raster_Dimensions/NCOLS";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }      
+      return false;
+   }
+   theImageSize.samp = xml_nodes[0]->getText().toDouble();
+
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Raster_Dimensions/NROWS";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }      
+      return false;
+   }
+   theImageSize.line = xml_nodes[0]->getText().toDouble();
+
+   if (theSwirDataFlag)
+   {
+      theImageSize.line /= 2.0;
+      theImageSize.samp /= 2.0;
+   }
+
+   //---
+   // Fetch the RefGroundPoint:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Dataset_Sources/Source_Frame/Scene_Center/FRAME_LAT";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      // Search for alternate path...
+      xpath = "/Dimap_Document/Dataset_Frame/Scene_Center/FRAME_LAT";
+      xmlDocument->findNodes(xpath, xml_nodes);
+      if (xml_nodes.size() == 0)
+      {
+         setErrorStatus();
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << MODULE << " DEBUG:"
+               << "\nCould not find: " << xpath
+               << endl;
+         }      
+         return false;
+      }
+   }
+   theRefGroundPoint.lat = xml_nodes[0]->getText().toDouble();
+
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Dataset_Sources/Source_Frame/Scene_Center/FRAME_LON";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      // Search for alternate path...
+      xpath = "/Dimap_Document/Dataset_Frame/Scene_Center/FRAME_LON";
+      xmlDocument->findNodes(xpath, xml_nodes);
+      if (xml_nodes.size() == 0)
+      {
+         setErrorStatus();
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << MODULE << " DEBUG:"
+               << "\nCould not find: " << xpath
+               << endl;
+         }
+         return false;
+      }
+   }
+   theRefGroundPoint.lon = xml_nodes[0]->getText().toDouble();
+   theRefGroundPoint.hgt = 0.0; // needs to be looked up
+
+   //---
+   // Fetch the RefImagePoint:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Strip/Sensor_Configuration/Time_Stamp/SCENE_CENTER_LINE";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }
+      return false;
+   }
+   theRefImagePoint.line = xml_nodes[0]->getText().toDouble() - 1.0;
+
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Strip/Sensor_Configuration/Time_Stamp/SCENE_CENTER_COL";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }
+      return false;
+   }
+   theRefImagePoint.samp = xml_nodes[0]->getText().toDouble() - 1.0;
+
+   // See if there's a sub image offset...
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Processing/Regions_Of_Interest/Region_Of_Interest/COL_MIN";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      theSubImageOffset.samp = 0.0;
+   }
+   else
+   {
+      theSubImageOffset.samp = xml_nodes[0]->getText().toDouble() - 1.0;
+   }
+
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Processing/Regions_Of_Interest/Region_Of_Interest/ROW_MIN";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      theSubImageOffset.line = 0.0;
+   }
+   else
+   {
+      theSubImageOffset.line = xml_nodes[0]->getText().toDouble() - 1.0;
+   }
+
+
+   if (theSwirDataFlag)
+   {
+      theRefImagePoint.line /= 2.0;
+      theRefImagePoint.samp /= 2.0;
+   }
+
+   //---
+   // Fetch the RefLineTime:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Strip/Sensor_Configuration/Time_Stamp/SCENE_CENTER_TIME";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }
+      return false;
+   }
+   theAcquisitionDate = xml_nodes[0]->getText();
+   convertTimeStamp(theAcquisitionDate, theRefLineTime);
+
+   return true;
+}
+
+bool ossimSpotDimapSupportData::parsePart2(
+   ossimRefPtr<ossimXmlDocument> xmlDocument)
+{
+   static const char MODULE[] = "ossimSpotDimapSupportData::parsePart2";
+   
+   ossimString xpath;
+   vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
+   vector<ossimRefPtr<ossimXmlNode> > sub_nodes;
+   vector<ossimRefPtr<ossimXmlNode> >::iterator node;
+   unsigned int band_index;
+
+   //---
+   // Fetch the LineSamplingPeriod:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Strip/Sensor_Configuration/Time_Stamp/LINE_PERIOD";
+   
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }
+      return false;
+   }
+   theLineSamplingPeriod = xml_nodes[0]->getText().toDouble();
+
+   if (theSwirDataFlag)
+   {
+      theLineSamplingPeriod *= 2.0;
+   }
+
+   //---
+   // Fetch number of bands
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Raster_Dimensions/NBANDS";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)   
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nCould not find: " << xpath
+            << endl;
+      }
+      return false;
+   }
+   theNumBands = atoi(xml_nodes[0]->getText());
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << MODULE << " DEBUG:"
+         << "\nNumber of bands: " << theNumBands
+         << std::endl;
+
+   }
+   
+   if (theNumBands == 1)
+   {
+      if (theSwirDataFlag)
+      {
+         setErrorStatus();
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << MODULE << " DEBUG:"
+               << "\nSWIR band error..."
+               << endl;
+         }
+         return false;
+      }
+      band_index = 0;
+   }
+   else if (theNumBands == 3)
+   {
+      band_index = 0; // using green band for PSI angles
+   }
+   else if (theNumBands == 4)
+   {
+      if (theSwirDataFlag)
+      {
+         band_index = 3;
+      }
+      else
+      {
+         band_index = 1; // using green band for PSI angles
+      }
+   }
+   else
+   {
+      setErrorStatus();
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << MODULE << " DEBUG:"
+            << "\nBand ERROR!"
+            << endl;
+      }
+      return false;
+   }
+
+   //---
+   // Fetch the PixelLookAngleX and PixelLookAngleY arrays. If MS, then the
+   // green band PSI angles are used unless SWIR requested:
+   //---
+   thePixelLookAngleX.clear();
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Strip/Sensor_Configuration/"
+      "Instrument_Look_Angles_List/Instrument_Look_Angles/";
+   xmlDocument->findNodes(xpath, xml_nodes);
+//   if (xml_nodes.size() != theNumBands)
+//   {
+      if(xml_nodes.size() == 0)
+      {
+         setErrorStatus();
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << MODULE << " DEBUG:"
+               << "\nCould not find: " << xpath
+               << endl;
+         }
+         return false;
+      }
+//       else
+//       {
+//       }
+
+//   }
+   
+   xpath = "Look_Angles_List/Look_Angles/PSI_X";
+   sub_nodes.clear();
+   xml_nodes[band_index]->findChildNodes(xpath, sub_nodes);
+
+   if (sub_nodes.size() != theImageSize.samp)
+   {
+      std::vector<double> tempV(sub_nodes.size());
+      double t = 0.0;
+      double tempIdx = 0.0;
+      double tempIdxFraction = 0.0;
+      ossim_int32 idxStart = 0;
+      ossim_int32 idxEnd = 0;
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < sub_nodes.size();++idx)
+      {
+         tempV[idx] = sub_nodes[idx]->getText().toDouble();
+      }
+      for(idx = 0; idx < theImageSize.samp; ++idx)
+      {
+         t = (double)idx/(double)(theImageSize.samp);
+         tempIdx = (sub_nodes.size()-1)*t;
+         tempIdxFraction = tempIdx - (ossim_int32)tempIdx;
+         idxStart = (ossim_int32)tempIdx;
+         idxEnd = (ossim_int32)ceil(tempIdx);
+         if(idxEnd >= (ossim_int32)sub_nodes.size())
+         {
+            idxEnd = sub_nodes.size()-1;
+         }
+         
+         thePixelLookAngleX.push_back(tempV[idxStart] + tempIdxFraction*(tempV[idxEnd] - tempV[idxStart]));
+      }
+   }
+   else
+   {
+      for (ossim_uint32 i=0; i<theImageSize.samp; ++i)
+      {
+         thePixelLookAngleX.push_back(sub_nodes[i]->getText().toDouble());
+      }
+   }
+
+   thePixelLookAngleY.clear();
+   xpath = "Look_Angles_List/Look_Angles/PSI_Y";
+   sub_nodes.clear();
+   xml_nodes[band_index]->findChildNodes(xpath, sub_nodes);
+
+   if (sub_nodes.size() != theImageSize.samp)
+   {
+      std::vector<double> tempV(sub_nodes.size());
+      double t = 0.0;
+      double tempIdx = 0.0;
+      double tempIdxFraction = 0.0;
+      ossim_int32 idxStart = 0;
+      ossim_int32 idxEnd = 0;
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < sub_nodes.size();++idx)
+      {
+         tempV[idx] = sub_nodes[idx]->getText().toDouble();
+      }
+      for(idx = 0; idx < theImageSize.samp; ++idx)
+      {
+         t = (double)idx/(double)(theImageSize.samp-1);
+         tempIdx = (sub_nodes.size()-1)*t;
+         tempIdxFraction = tempIdx - (ossim_int32)tempIdx;
+         idxStart = (ossim_int32)tempIdx;
+         idxEnd = (ossim_int32)ceil(tempIdx);
+         if(idxEnd >= (ossim_int32)sub_nodes.size())
+         {
+            idxEnd = sub_nodes.size()-1;
+         }
+         if(idxStart > idxEnd)
+         {
+            idxStart = idxEnd;
+         }
+         thePixelLookAngleY.push_back(tempV[idxStart] + tempIdxFraction*(tempV[idxEnd] - tempV[idxStart]));
+      }
+   }
+   else
+   {
+      for (ossim_uint32 i=0; i<theImageSize.samp; ++i)
+      {
+         thePixelLookAngleY.push_back(sub_nodes[i]->getText().toDouble());
+      }
+   }
+
+   //---
+   // Fetch the Attitude Samples:
+   //---
+   theAttitudeSamples.clear();
+   theAttSampTimes.clear();
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Strip/Satellite_Attitudes/Corrected_Attitudes/"
+      "Corrected_Attitude/Angles";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      xpath = "/Dimap_Document/Data_Strip/Satellite_Attitudes/Raw_Attitudes/Aocs_Attitude/Angles_List/Angles";
+      
+      xmlDocument->findNodes(xpath, xml_nodes);
+      if (xml_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+   }
+   node = xml_nodes.begin();
+   while (node != xml_nodes.end())
+   {
+      ossimDpt3d V;
+      sub_nodes.clear();
+      xpath = "OUT_OF_RANGE";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      if (sub_nodes[0]->getText() == "N")
+      {
+         sub_nodes.clear();
+         xpath = "PITCH";
+         (*node)->findChildNodes(xpath, sub_nodes);
+         if (sub_nodes.size() == 0)
+         {
+            setErrorStatus();
+            return false;
+         }
+         V.x = sub_nodes[0]->getText().toDouble();
+
+         sub_nodes.clear();
+         xpath = "ROLL";
+         (*node)->findChildNodes(xpath, sub_nodes);
+         if (sub_nodes.size() == 0)
+         {
+            setErrorStatus();
+            return false;
+         }
+         V.y = sub_nodes[0]->getText().toDouble();
+
+         sub_nodes.clear();
+         xpath = "YAW";
+         (*node)->findChildNodes(xpath, sub_nodes);
+         if (sub_nodes.size() == 0)
+         {
+            setErrorStatus();
+            return false;
+         }
+         V.z = sub_nodes[0]->getText().toDouble();
+
+         theAttitudeSamples.push_back(V);
+
+         sub_nodes.clear();
+         xpath = "TIME";
+         (*node)->findChildNodes(xpath, sub_nodes);
+         if (sub_nodes.size() == 0)
+         {
+            setErrorStatus();
+            return false;
+         }
+         theAttSampTimes.push_back(convertTimeStamp(sub_nodes[0]->getText()));
+      }
+      ++node;
+   }
+
+   return true;
+}
+
+bool ossimSpotDimapSupportData::parsePart3(
+   ossimRefPtr<ossimXmlDocument> xmlDocument)
+{
+   ossimString xpath;
+   vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
+   vector<ossimRefPtr<ossimXmlNode> > sub_nodes;
+   vector<ossimRefPtr<ossimXmlNode> >::iterator node;
+
+   //---
+   // Fetch the ephemeris samples:
+   //---
+   thePosEcfSamples.clear();
+   theVelEcfSamples.clear();
+   theEphSampTimes.clear();
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Strip/Ephemeris/Points/Point";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      return false;
+   }
+   node = xml_nodes.begin();
+   while (node != xml_nodes.end())
+   {
+      ossimDpt3d VP;
+      sub_nodes.clear();
+      xpath  = "Location/X";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      VP.x = sub_nodes[0]->getText().toDouble();
+
+      sub_nodes.clear();
+      xpath  = "Location/Y";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      VP.y = sub_nodes[0]->getText().toDouble();
+
+      sub_nodes.clear();
+      xpath  = "Location/Z";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      VP.z = sub_nodes[0]->getText().toDouble();
+
+      thePosEcfSamples.push_back(VP);
+
+      ossimDpt3d VV;
+      sub_nodes.clear();
+      xpath = "Velocity/X";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      VV.x = sub_nodes[0]->getText().toDouble();
+
+      sub_nodes.clear();
+      xpath = "Velocity/Y";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      VV.y = sub_nodes[0]->getText().toDouble();
+
+      sub_nodes.clear();
+      xpath = "Velocity/Z";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      VV.z = sub_nodes[0]->getText().toDouble();
+
+      theVelEcfSamples.push_back(VV);
+
+      sub_nodes.clear();
+      xpath  = "TIME";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      theEphSampTimes.push_back(convertTimeStamp(sub_nodes[0]->getText()));
+
+      ++node;
+   }
+
+   //---
+   // Fetch the star tracker flag:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Data_Strip/Satellite_Attitudes/Corrected_Attitudes/"
+      "STAR_TRACKER_USED";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+         theStarTrackerUsed = false;
+//       setErrorStatus();
+//       return false;
+   }
+   else
+   {
+      if (xml_nodes[0]->getText() == "Y")
+         theStarTrackerUsed = true;
+      else
+         theStarTrackerUsed = false;
+   }
+
+   //---
+   // Corner points:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Dataset_Frame/Vertex";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() != 4)
+   {
+      setErrorStatus();
+      return false;
+   }
+   node = xml_nodes.begin();
+   while (node != xml_nodes.end())
+   {
+      ossimGpt gpt;
+      ossimDpt ipt;
+
+      sub_nodes.clear();
+      xpath = "FRAME_LAT";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      gpt.lat = sub_nodes[0]->getText().toDouble();
+
+      sub_nodes.clear();
+      xpath = "FRAME_LON";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      gpt.lon = sub_nodes[0]->getText().toDouble();
+      gpt.hgt = 0.0; // assumed
+
+      sub_nodes.clear();
+      xpath = "FRAME_ROW";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      ipt.line = sub_nodes[0]->getText().toDouble() - 1.0;
+
+      sub_nodes.clear();
+      xpath = "FRAME_COL";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      ipt.samp = sub_nodes[0]->getText().toDouble() - 1.0;
+
+      if (ipt.line < 1.0)
+         if (ipt.samp < 1.0)
+            theUlCorner = gpt;
+         else
+            theUrCorner = gpt;
+      else
+         if (ipt.samp < 1.0)
+            theLlCorner = gpt;
+         else
+            theLrCorner = gpt;
+
+      ++node;
+   }
+
+   //---
+   // Geoposition points:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Geoposition/Geoposition_Points/Tie_Point";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   node = xml_nodes.begin();
+   while (node != xml_nodes.end())
+   {
+      ossimGpt gpt;
+      ossimDpt  ipt;
+
+      sub_nodes.clear();
+      xpath = "TIE_POINT_DATA_Y";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      ipt.line = sub_nodes[0]->getText().toDouble() - 1.0;
+
+      sub_nodes.clear();
+      xpath = "TIE_POINT_DATA_X";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      ipt.samp = sub_nodes[0]->getText().toDouble() - 1.0;
+
+      sub_nodes.clear();
+      xpath = "TIE_POINT_CRS_Y";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      gpt.lat = sub_nodes[0]->getText().toDouble();
+
+      sub_nodes.clear();
+      xpath = "TIE_POINT_CRS_X";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      gpt.lon = sub_nodes[0]->getText().toDouble();
+
+      sub_nodes.clear();
+      xpath = "TIE_POINT_CRS_Z";
+      (*node)->findChildNodes(xpath, sub_nodes);
+      if (sub_nodes.size() == 0)
+      {
+         setErrorStatus();
+         return false;
+      }
+      gpt.hgt = sub_nodes[0]->getText().toDouble();
+
+      theGeoPosImagePoints.push_back(ipt);
+      theGeoPosGroundPoints.push_back(gpt);
+
+      ++node;
+   }
+
+   //---
+   // Fetch incidence angle:
+   //---
+   xml_nodes.clear();
+   xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/"
+      "INCIDENCE_ANGLE";
+   xmlDocument->findNodes(xpath, xml_nodes);
+   if (xml_nodes.size() == 0)
+   {
+      setErrorStatus();
+      return false;
+   }
+   theIncidenceAngle = xml_nodes[0]->getText().toDouble();
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/spot/ossimSpotDimapSupportData.h b/Utilities/OSSIM/ossim_core/support_data/spot/ossimSpotDimapSupportData.h
new file mode 100644
index 0000000000..37fef25347
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/spot/ossimSpotDimapSupportData.h
@@ -0,0 +1,207 @@
+//*******************************************************************
+// Copyright (C) 2003 ImageLinks Inc.  All rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+//
+// Author:  Oscar Kramer (ossim port by D. Burken)
+//
+// Description:  
+//
+// Contains declaration of class ossimSpotDimapSupportData.
+// 
+//*****************************************************************************
+// $Id: ossimSpotDimapSupportData.h,v 1.8 2005/10/21 11:37:58 gpotts Exp $
+#ifndef ossimSpotDimapSupportData_HEADER
+#define ossimSpotDimapSupportData_HEADER
+
+#include <vector>
+#include <iostream>
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimObject.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/common/ossimErrorStatusInterface.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimDpt.h>
+#include <base/data_types/ossimDpt3d.h>
+#include <base/data_types/ossimDrect.h>
+#include <base/data_types/ossimGpt.h>
+#include <base/data_types/ossimEcefPoint.h>
+
+class ossimKeywordlist;
+// class ossimRefPtr;
+class ossimXmlDocument;
+
+class ossimSpotDimapSupportData : public ossimObject,
+                                  public ossimErrorStatusInterface
+{
+public:
+   ossimSpotDimapSupportData();
+   ossimSpotDimapSupportData(const ossimSpotDimapSupportData& rhs);
+   ossimSpotDimapSupportData(const ossimFilename& dimapFile,
+                             bool  processSwir=false);
+
+   virtual ossimObject* dup()const;
+   virtual ~ossimSpotDimapSupportData();
+
+   void clearFields();
+   bool loadXmlFile(const ossimFilename& file,
+                    bool processSwir=false);
+
+   ossimString   getAcquisitionDate()                     const;
+   ossimString   getImageID()                             const;
+   ossimFilename getMetadataFile()                        const;
+   void          getSunAzimuth(ossim_float64& az)         const;
+   void          getSunElevation(ossim_float64& el)       const;
+   void          getImageSize(ossimDpt& sz)               const; 
+   void          getLineSamplingPeriod(ossim_float64& pe) const;
+   void          getIncidenceAngle(ossim_float64& ia)     const;
+   ossim_uint32  getNumberOfBands()                       const;
+   bool          isStarTrackerUsed()                      const;
+   bool          isSwirDataUsed()                         const;
+   
+   //---
+   // Image center point:
+   //---
+   void getRefGroundPoint(ossimGpt& gp)     const;
+   void getRefImagePoint(ossimDpt& rp)      const;
+   void getRefLineTime(ossim_float64& rt)   const;
+
+   ossimDrect getImageRect()const;
+   //---
+   // Sub image offset:
+   //---
+   void getSubImageOffset(ossimDpt& offset) const;
+
+   //---
+   // Ephemeris (m & m/s):
+   //---
+   void getPositionEcf(ossim_uint32 sample, ossimEcefPoint& pe) const;
+   void getPositionEcf(const ossim_float64& time, ossimEcefPoint& pe) const;
+   void getVelocityEcf(ossim_uint32 sample, ossimEcefPoint& ve) const;
+   void getVelocityEcf(const ossim_float64& time, ossimEcefPoint& ve) const;
+   void getEphSampTime(ossim_uint32 sample, ossim_float64& et) const;
+   
+   ossim_uint32 getNumEphSamples() const;
+   
+   //---
+   // Attitude Angles in RADIANS:
+   //---
+   void getAttitude(ossim_uint32 sample, ossimDpt3d& at)  const;
+   void getAttitude(const ossim_float64& time, ossimDpt3d& at) const;
+   void getAttSampTime(ossim_uint32 sample, ossim_float64& at)  const;
+   ossim_uint32 getNumAttSamples() const;
+   
+   //---
+   // Pixel Pointing/Mirror tilt  Angles in RADIANS:
+   //---
+   void getPixelLookAngleX (ossim_uint32 sample, ossim_float64& pa) const;
+   void getPixelLookAngleX (const ossim_float64& sample,
+                            ossim_float64& pa) const;
+   void getPixelLookAngleY (ossim_uint32 sample, ossim_float64& pa) const;
+   void getPixelLookAngleY (const ossim_float64& sample,
+                            ossim_float64& pa) const;
+   
+   //---
+   // Geoposition points provided in the file (most likely just corner points):
+   //---
+   ossim_uint32 getNumGeoPosPoints() const;
+   void getGeoPosPoint (ossim_uint32 point, ossimDpt& ip, ossimGpt& gp) const;
+
+   //---
+   // Corner points:
+   //---
+   void getUlCorner(ossimGpt& pt) const;
+   void getUrCorner(ossimGpt& pt) const;
+   void getLrCorner(ossimGpt& pt) const;
+   void getLlCorner(ossimGpt& pt) const;
+
+   //---
+   // Convenient method to print important image info:
+   //---
+   void  printInfo (ostream& os) const;
+
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix = 0)const;
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix = 0);
+private:
+   void getLagrangeInterpolation(const ossim_float64& t,
+                                 const vector<ossimDpt3d>& V,
+                                 const vector<ossim_float64>& T,
+                                 ossimDpt3d& li )const;
+
+   void getBilinearInterpolation(const ossim_float64& t,
+                                 const vector<ossimDpt3d>& V,
+                                 const vector<ossim_float64>& T,
+                                 ossimDpt3d& li )const;
+
+   void getInterpolatedLookAngle(const ossim_float64& p,
+                                 const vector<ossim_float64>& angles,
+                                 ossim_float64& la) const;
+   
+   ossim_float64 convertTimeStamp(const ossimString& time_stamp) const;
+
+   void convertTimeStamp(const ossimString& time_stamp,
+                         ossim_float64& ti) const;
+   
+   ossimString                 theImageID;
+   ossimFilename               theMetadataFile;
+   ossim_float64               theSunAzimuth;  
+   ossim_float64               theSunElevation;
+   ossimDpt                    theImageSize;
+   ossimGpt                    theRefGroundPoint;
+   ossimDpt                    theRefImagePoint;
+   ossimDpt                    theSubImageOffset;
+   ossim_float64               theRefLineTime;
+   ossim_float64               theLineSamplingPeriod;
+   vector<ossim_float64>       thePixelLookAngleX;
+   vector<ossim_float64>       thePixelLookAngleY;
+   vector<ossimDpt3d>          theAttitudeSamples; // x=pitch, y=roll, z=yaw
+   vector<ossim_float64>       theAttSampTimes;
+   vector<ossimDpt3d>          thePosEcfSamples;
+   vector<ossimDpt3d>          theVelEcfSamples;
+   vector<ossim_float64>       theEphSampTimes;
+   bool                        theStarTrackerUsed;
+   bool                        theSwirDataFlag;
+   ossim_uint32                theNumBands;
+   ossimString                 theAcquisitionDate;
+   ossim_float64               theIncidenceAngle;
+
+   //---
+   // Corner points:
+   //---
+   ossimGpt theUlCorner;
+   ossimGpt theUrCorner;
+   ossimGpt theLrCorner;
+   ossimGpt theLlCorner;
+
+   //---
+   // Geoposition Points:
+   //---
+   vector <ossimDpt> theGeoPosImagePoints;
+   vector <ossimGpt> theGeoPosGroundPoints;
+
+   ossimGpt createGround(const ossimString& s)const;
+   ossimDpt createDpt(const ossimString& s)const;
+
+   /**
+    * Private parse methods called by loadXml.
+    * 
+    * These "parse" methods were made simply to split the loadXmlMethod
+    * into pieces.  This was an attempt to troubleshoot what was thought to
+    * be a compiler issue, which turned out to be changed metadata and bad
+    * error handling within this code.  Since there were lots of debug
+    * statements added I am committing this to cvs.
+    * DRB 16 Oct. 2005
+    */
+   bool parsePart1(ossimRefPtr<ossimXmlDocument> xmlDocument);
+   bool parsePart2(ossimRefPtr<ossimXmlDocument> xmlDocument);
+   bool parsePart3(ossimRefPtr<ossimXmlDocument> xmlDocument);
+};
+
+#endif /* #ifndef ossimSpotDimapSupportData_HEADER */
diff --git a/Utilities/OSSIM/ossim_core/support_data/srtm/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/srtm/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/srtm/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmFilename.cpp b/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmFilename.cpp
new file mode 100644
index 0000000000..2f2924d056
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmFilename.cpp
@@ -0,0 +1,184 @@
+#include "ossimSrtmFilename.h"
+#include <base/data_types/ossimRegExp.h>
+
+ossimSrtmFilename::ossimSrtmFilename(const ossimFilename& srtmFilename)
+{
+   setFilename(srtmFilename);
+}
+
+ossimGpt ossimSrtmFilename::ul()const
+{
+   ossimGpt result;
+   
+   if((theSouthwestLongitude==OSSIM_DBL_NAN)||
+      (theSouthwestLatitude==OSSIM_DBL_NAN))
+   {
+      result.makeNan();
+   }
+   else
+   {
+      result.latd(theSouthwestLatitude+1.0);
+      result.lond(theSouthwestLongitude);
+   }
+   
+   return result;
+}
+
+ossimGpt ossimSrtmFilename::ur()const
+{
+   ossimGpt result;
+   
+   if((theSouthwestLongitude==OSSIM_DBL_NAN)||
+      (theSouthwestLatitude==OSSIM_DBL_NAN))
+   {
+      result.makeNan();
+   }
+   else
+   {
+      result.latd(theSouthwestLatitude+1.0);
+      result.lond(theSouthwestLongitude+1.0);
+   }
+   
+   return result;
+}
+
+ossimGpt ossimSrtmFilename::lr()const
+{
+   ossimGpt result;
+   
+   if((theSouthwestLongitude==OSSIM_DBL_NAN)||
+      (theSouthwestLatitude==OSSIM_DBL_NAN))
+   {
+      result.makeNan();
+   }
+   else
+   {
+      result.latd(theSouthwestLatitude);
+      result.lond(theSouthwestLongitude+1.0);
+   }
+   
+   return result;
+}
+
+ossimGpt ossimSrtmFilename::ll()const
+{
+   ossimGpt result;
+   
+   if((theSouthwestLongitude==OSSIM_DBL_NAN)||
+      (theSouthwestLatitude==OSSIM_DBL_NAN))
+   {
+      result.makeNan();
+   }
+   else
+   {
+      result.latd(theSouthwestLatitude);
+      result.lond(theSouthwestLongitude);
+   }
+   
+   return result;
+}
+
+
+bool ossimSrtmFilename::setFilename(const ossimFilename& srtmFilename)
+{
+   theFilename = srtmFilename;
+   theSouthwestLongitude = OSSIM_DBL_NAN;
+   theSouthwestLatitude  = OSSIM_DBL_NAN;
+
+   if(srtmFilename == "") return false;
+
+   ossimFilename f = theFilename.fileNoExtension();
+   ossimString regularExp1 = "[N|S][0-9][0-9][E|W][0-9][0-9][0-9]";
+   ossimString regularExp2 = "[E|W][0-9][0-9][0-9][N|S][0-9][0-9]";
+   ossimRegExp regEx;
+   bool latLonOrderFlag = true;
+   bool foundFlag = false;
+   f = f.upcase();
+
+   regEx.compile(regularExp1.c_str());
+   foundFlag = regEx.find(f.c_str());
+   if(!foundFlag)
+   {
+      regEx.compile(regularExp2.c_str());
+      foundFlag = regEx.find(f.c_str());
+      if(foundFlag)
+      {
+         latLonOrderFlag = false;
+         f = ossimFilename(ossimString(f.begin()+regEx.start(),
+                                       f.begin()+regEx.end()));
+      }
+   }
+   if(foundFlag)
+   {
+      f = ossimFilename(ossimString(f.begin()+regEx.start(),
+                                    f.begin()+regEx.end()));
+   }
+   if (f.size() != 7)
+   {
+      return false;
+   }
+   ossimString s;
+
+   if(latLonOrderFlag)
+   {
+      s.push_back(f[1]);
+      s.push_back(f[2]);
+      theSouthwestLatitude = s.toDouble();
+      // Get the latitude.
+      if (f[0] == 'S')
+      {
+         theSouthwestLatitude *= -1;
+      }
+      else if (f[0] != 'N')
+      {
+         return false; // Must be either 's' or 'n'.
+      }
+      // Get the longitude.
+      s.clear();
+      s.push_back(f[4]);
+      s.push_back(f[5]);
+      s.push_back(f[6]);
+      theSouthwestLongitude = s.toDouble();
+      if (f[3] == 'W')
+      {
+      theSouthwestLongitude *= -1;
+      }
+      else if (f[3] != 'E')
+      {
+         return false; // Must be either 'e' or 'w'.
+      }
+   }
+   else
+   {
+      // Get the longitude.
+      s.clear();
+      s.push_back(f[1]);
+      s.push_back(f[2]);
+      s.push_back(f[3]);
+      theSouthwestLongitude = s.toDouble();
+      if (f[0] == 'W')
+      {
+      theSouthwestLongitude *= -1;
+      }
+      else if (f[0] != 'E')
+      {
+         return false; // Must be either 'e' or 'w'.
+      }
+      s.clear();
+      
+      s.push_back(f[5]);
+      s.push_back(f[6]);
+      theSouthwestLatitude = s.toDouble();
+      // Get the latitude.
+      if (f[4] == 'S')
+      {
+         theSouthwestLatitude *= -1;
+      }
+      else if (f[4] != 'N')
+      {
+         return false; // Must be either 's' or 'n'.
+      }
+   }
+   
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmFilename.h b/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmFilename.h
new file mode 100644
index 0000000000..4f475cf111
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmFilename.h
@@ -0,0 +1,25 @@
+#ifndef ossimSrtmFilename_HEADER
+#define ossimSrtmFilename_HEADER
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimGpt.h>
+
+class ossimSrtmFilename
+{
+public:
+   ossimSrtmFilename(const ossimFilename& srtmFilename="");
+
+   bool setFilename(const ossimFilename& srtmFilename);
+   ossimGpt ul()const;
+   ossimGpt ur()const;
+   ossimGpt lr()const;
+   ossimGpt ll()const;
+   
+protected:
+   ossimFilename theFilename;
+
+   ossim_float64 theSouthwestLongitude;
+   ossim_float64 theSouthwestLatitude;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmSupportData.cpp b/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmSupportData.cpp
new file mode 100644
index 0000000000..69f602ea88
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmSupportData.cpp
@@ -0,0 +1,807 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Support data class for a Shuttle Radar Topography Mission (SRTM) file.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimSrtmSupportData.cpp,v 1.11 2005/11/10 19:51:41 gpotts Exp $
+
+#include <cmath>
+#include <fstream>
+
+#include <support_data/srtm/ossimSrtmSupportData.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/datum/ossimDatum.h>
+#include <base/factory/ossimDatumFactory.h>
+#include <base/misc/ossimEndian.h>
+#include <base/data_types/ossimRegExp.h>
+#include <base/misc/lookup_tables/ossimScalarTypeLut.h>
+#include <base/factory/ossimStreamFactoryRegistry.h>
+
+// Static trace for debugging
+static ossimTrace traceDebug("ossimSrtmSupportData:debug");
+
+ossimSrtmSupportData::ossimSrtmSupportData()
+   :
+   theFile(),
+   theNumberOfLines(OSSIM_UINT_NAN),
+   theNumberOfSamples(OSSIM_UINT_NAN),
+   theSouthwestLatitude(OSSIM_DBL_NAN),
+   theSouthwestLongitude(OSSIM_DBL_NAN),
+   theLatSpacing(OSSIM_DBL_NAN),
+   theLonSpacing(OSSIM_DBL_NAN),
+   theMinPixelValue(OSSIM_SSHORT_NAN),
+   theMaxPixelValue(OSSIM_SSHORT_NAN),
+   theScalarType(OSSIM_SCALAR_UNKNOWN)
+{
+}
+
+ossimSrtmSupportData::~ossimSrtmSupportData()
+{
+}
+
+bool ossimSrtmSupportData::setFilename(const ossimFilename& srtmFile,
+                                       bool scanForMinMax)
+{
+   theFile = srtmFile;
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimSrtmSupportData::setFilename: entered..." << std::endl;
+   }
+   
+   theFileStream =  ossimStreamFactoryRegistry::instance()->createNewInputStream(theFile,
+                                                                                 ios::in | ios::binary);
+   if (theFileStream.valid())
+   {
+      if(theFileStream->fail())
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << theFile << " does not exist: leaving ..." << std::endl;
+         }
+         clear();
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+   // See if we have an ossim metadata file to initialize from.
+   bool loadedFromOmd = false;
+   
+   ossimFilename omdFile = theFile;
+   omdFile.setExtension(ossimString("omd"));
+   if (omdFile.exists())
+   {
+      ossimKeywordlist kwl(omdFile);
+      loadedFromOmd = loadState(kwl);
+   }
+
+   if (!loadedFromOmd)
+   {
+      if (!setCornerPoints())
+      {
+         clear();
+         return false;
+      }
+
+      if (!setSize())
+      {
+         clear();
+         return false;
+      }
+   }
+
+   if (scanForMinMax)
+   {
+      // These could have been picked up in the loadState.
+      if ( (theMinPixelValue == OSSIM_SSHORT_NAN) ||
+           (theMaxPixelValue == OSSIM_SSHORT_NAN) )
+      {
+         if (!computeMinMax())
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "Unable to compute min max: leaving ..." << std::endl;
+            }
+            clear();
+            return false;
+         }
+      }
+   }
+
+   if (!loadedFromOmd)
+   {
+      ossimKeywordlist kwl;
+      saveState(kwl);
+      kwl.write(omdFile);
+   }
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << *this << endl;
+   }
+   
+   return true;
+}
+
+ossimFilename ossimSrtmSupportData::getFilename() const
+{
+   return theFile;
+}
+
+ossim_uint32 ossimSrtmSupportData::getNumberOfLines() const
+{
+   return theNumberOfLines;
+}
+
+ossim_uint32 ossimSrtmSupportData::getNumberOfSamples() const
+{
+   return theNumberOfSamples;
+}
+
+bool ossimSrtmSupportData::getImageGeometry(ossimKeywordlist& kwl,
+                                            const char* prefix)
+{
+   if (theFile == ossimFilename::NIL)
+   {
+      return false;
+   }
+   
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           "ossimEquDistCylProjection",
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::ORIGIN_LATITUDE_KW,
+           0.0,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+           theSouthwestLongitude,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LAT_KW,
+           (theSouthwestLatitude+1.0),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LON_KW,
+           theSouthwestLongitude,
+           true);
+
+   // Add the pixel scale.
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+           theLatSpacing,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+           theLonSpacing,
+           true);
+
+   // Add the datum.  (always WGS-84 per spec)
+   kwl.add(prefix,
+           ossimKeywordNames::DATUM_KW,
+           ossimDatumFactory::instance()->wgs84()->code(),
+           true);
+
+   // Add the number of lines and samples.
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_LINES_KW,
+           theNumberOfLines,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_SAMPLES_KW,
+           theNumberOfSamples,
+           true);
+   
+   return true;
+}
+
+bool ossimSrtmSupportData::saveState(ossimKeywordlist& kwl,
+                                     const char* prefix) const
+{
+   if (theFile == ossimFilename::NIL)
+   {
+      return false;
+   }
+   
+   ossimString bandPrefix;
+   if (prefix)
+   {
+      bandPrefix = prefix;
+   }
+   bandPrefix += "band1.";
+   
+   kwl.add(prefix,
+           ossimKeywordNames::FILENAME_KW,
+           theFile.c_str(),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_LINES_KW,
+           theNumberOfLines,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::NUMBER_SAMPLES_KW,
+           theNumberOfSamples,
+           true);
+
+   //---
+   // Special case, store the tie point as the upper left lat so add one.
+   //---
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LAT_KW,
+           (theSouthwestLatitude + 1.0),
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::TIE_POINT_LON_KW,
+           theSouthwestLongitude,
+           true);
+
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+           theLatSpacing,
+           true);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+           theLonSpacing,
+           true);
+
+   // User can opt out of scanning for this so don't save if it is still nan.
+   if (theMinPixelValue != OSSIM_SSHORT_NAN)
+   {
+      kwl.add(bandPrefix,
+              ossimKeywordNames::MIN_VALUE_KW,
+              theMinPixelValue,
+              true);
+   }
+
+   // User can opt out of scanning for this so don't save if it is still nan.
+   if (theMaxPixelValue != OSSIM_SSHORT_NAN)
+   {
+      kwl.add(bandPrefix.c_str(),
+              ossimKeywordNames::MAX_VALUE_KW,
+              theMaxPixelValue,
+              true);
+   }
+
+   // constant
+   kwl.add(bandPrefix,
+           ossimKeywordNames::NULL_VALUE_KW,
+           "-32768",
+           true);
+
+   // constant
+   kwl.add(prefix,
+           ossimKeywordNames::BYTE_ORDER_KW,
+           "big_endian",
+           true);
+
+   // constant
+   kwl.add(prefix,
+           ossimKeywordNames::SCALAR_TYPE_KW,
+           ossimScalarTypeLut::instance()->getEntryString(theScalarType),
+           true);
+
+   return true;
+}
+   
+bool ossimSrtmSupportData::loadState(const ossimKeywordlist& kwl,
+                                     const char* prefix)
+{
+   ossimString bandPrefix;
+   if (prefix)
+   {
+      bandPrefix = prefix;
+   }
+   bandPrefix += "band1.";
+   
+   ossimString s; // For numeric conversions.
+   
+   const char* lookup;
+
+   // Look for "filename" then look for deprecated "image_file" next.
+   lookup = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
+   if (lookup)
+   {
+      theFile = lookup;
+   }
+   else
+   {
+      // Deprecated...
+      lookup = kwl.find(prefix, ossimKeywordNames::IMAGE_FILE_KW);
+      if (lookup)
+      {
+         theFile = lookup;
+      }
+      else
+      {
+         return false;
+      }
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_LINES_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theNumberOfLines = s.toUInt32();
+   }
+   else
+   {
+      return false;
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::NUMBER_SAMPLES_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theNumberOfSamples = s.toUInt32();
+   }
+   else
+   {
+      return false;
+   }
+
+   //---
+   // Special case the tie point was stored as the upper left so we must
+   // subtract one.
+   //---
+   lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LAT_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theSouthwestLatitude = s.toDouble() - 1.0;
+   }
+   else
+   {
+      return false;
+   }
+
+   lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LON_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theSouthwestLongitude = s.toDouble();
+   }
+   else
+   {
+      return false;
+   }
+
+   lookup = kwl.find(prefix,
+                     ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT);
+   if (lookup)
+   {
+      s = lookup;
+      theLatSpacing = s.toDouble();
+   }
+   else
+   {
+      return false;
+   }
+   
+   int scalar = ossimScalarTypeLut::instance()->getEntryNumber(kwl, prefix);
+   
+   if (scalar != ossimLookUpTable::NOT_FOUND)
+   {
+      theScalarType = (ossimScalarType)scalar;
+      if((theScalarType != OSSIM_FLOAT32)&&
+         (theScalarType != OSSIM_SINT16))
+      {
+         return false;
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   lookup = kwl.find(prefix,
+                     ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON);
+   if (lookup)
+   {
+      s = lookup;
+      theLonSpacing = s.toDouble();
+   }
+   else
+   {
+      return false;
+   }
+
+   // Not an error if not present.
+   lookup = kwl.find(bandPrefix, ossimKeywordNames::MIN_VALUE_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theMinPixelValue = static_cast<ossim_sint16>(s.toInt());
+   }
+
+   // Not an error if not present.
+   lookup = kwl.find(bandPrefix.c_str(), ossimKeywordNames::MAX_VALUE_KW);
+   if (lookup)
+   {
+      s = lookup;
+      theMaxPixelValue = static_cast<ossim_sint16>(s.toInt());
+   }
+   
+   return true;
+}
+
+ossim_float64 ossimSrtmSupportData::getSouthwestLatitude() const
+{
+   return theSouthwestLatitude;
+}
+
+ossim_float64 ossimSrtmSupportData::getSouthwestLongitude() const
+{
+   return theSouthwestLongitude;
+}
+ossim_float64 ossimSrtmSupportData::getLatitudeSpacing() const
+{
+   return theLatSpacing;
+}
+
+ossim_float64 ossimSrtmSupportData::getLongitudeSpacing() const
+{
+   return theLonSpacing;
+}
+
+void ossimSrtmSupportData::clear()
+{
+   theFile               = ossimFilename::NIL;
+   theNumberOfLines      = OSSIM_UINT_NAN;
+   theNumberOfSamples    = OSSIM_UINT_NAN;
+   theSouthwestLatitude  = OSSIM_DBL_NAN;
+   theSouthwestLongitude = OSSIM_DBL_NAN;
+   theLatSpacing         = OSSIM_DBL_NAN;
+   theLonSpacing         = OSSIM_DBL_NAN;
+   theMinPixelValue      = OSSIM_SSHORT_NAN;
+   theMaxPixelValue      = OSSIM_SSHORT_NAN;
+}
+
+bool ossimSrtmSupportData::setCornerPoints()
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimSrtmSupportData::setCornerPoints(): entered..." << std::endl;
+   }
+   ossimFilename f = theFile.fileNoExtension();
+   ossimString regularExp1 = "[N|S][0-9][0-9][E|W][0-9][0-9][0-9]";
+   ossimString regularExp2 = "[E|W][0-9][0-9][0-9][N|S][0-9][0-9]";
+   ossimRegExp regEx;
+   bool latLonOrderFlag = true;
+   bool foundFlag = false;
+   f = f.upcase();
+
+   regEx.compile(regularExp1.c_str());
+   foundFlag = regEx.find(f.c_str());
+   if(!foundFlag)
+   {
+      regEx.compile(regularExp2.c_str());
+      foundFlag = regEx.find(f.c_str());
+      if(foundFlag)
+      {
+         latLonOrderFlag = false;
+         f = ossimFilename(ossimString(f.begin()+regEx.start(),
+                                       f.begin()+regEx.end()));
+      }
+   }
+   if(foundFlag)
+   {
+      f = ossimFilename(ossimString(f.begin()+regEx.start(),
+                                    f.begin()+regEx.end()));
+   }
+   if (f.size() != 7)
+   {
+      return false;
+   }
+   ossimString s;
+
+   if(latLonOrderFlag)
+   {
+      s.push_back(f[1]);
+      s.push_back(f[2]);
+      theSouthwestLatitude = s.toDouble();
+      // Get the latitude.
+      if (f[0] == 'S')
+      {
+         theSouthwestLatitude *= -1;
+      }
+      else if (f[0] != 'N')
+      {
+         return false; // Must be either 's' or 'n'.
+      }
+      // Get the longitude.
+      s.clear();
+      s.push_back(f[4]);
+      s.push_back(f[5]);
+      s.push_back(f[6]);
+      theSouthwestLongitude = s.toDouble();
+      if (f[3] == 'W')
+      {
+      theSouthwestLongitude *= -1;
+      }
+      else if (f[3] != 'E')
+      {
+         return false; // Must be either 'e' or 'w'.
+      }
+   }
+   else
+   {
+      // Get the longitude.
+      s.clear();
+      s.push_back(f[1]);
+      s.push_back(f[2]);
+      s.push_back(f[3]);
+      theSouthwestLongitude = s.toDouble();
+      if (f[0] == 'W')
+      {
+      theSouthwestLongitude *= -1;
+      }
+      else if (f[0] != 'E')
+      {
+         return false; // Must be either 'e' or 'w'.
+      }
+      s.clear();
+      
+      s.push_back(f[5]);
+      s.push_back(f[6]);
+      theSouthwestLatitude = s.toDouble();
+      // Get the latitude.
+      if (f[4] == 'S')
+      {
+         theSouthwestLatitude *= -1;
+      }
+      else if (f[4] != 'N')
+      {
+         return false; // Must be either 's' or 'n'.
+      }
+   }
+   
+
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimSrtmSupportData::setCornerPoints(): leaving with true..." << std::endl;
+   }
+   return true;
+}
+
+bool ossimSrtmSupportData::setSize()
+{
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimSrtmSupportData::setSize(): entered..." << std::endl;
+   }
+   
+   ossim_float64 size = 0.0;
+   theFileStream->seekg(0, std::ios::beg);
+   if(theFileStream->isCompressed())
+   {
+      ossimFilename tmp = theFile;
+      tmp.setExtension("hgt");
+      if(!tmp.exists())
+      {
+         ossimOFStream out(tmp.c_str(),
+                           std::ios::out|std::ios::binary);
+
+         if(!out.fail())
+         {
+            bool done = false;
+            char buf[1024];
+            while(!done&&!theFileStream->fail())
+            {
+               theFileStream->read(buf, 1024);
+               if(theFileStream->gcount() < 1024)
+               {
+                  done = true;
+               }
+               if(theFileStream->gcount() > 0)
+               {
+                  out.write(buf, theFileStream->gcount());
+               }
+            }
+            out.close();
+            size = tmp.fileSize();
+            tmp.remove();
+         }
+      }
+   }
+   else
+   {
+      size = theFile.fileSize();
+   }
+   if (!size)
+   {
+      if(traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG) << "ossimSrtmSupportData::setSize(): leaving with false at line " << __LINE__ << std::endl;
+      }
+      return false;
+   }
+
+   theScalarType = OSSIM_SCALAR_UNKNOWN;
+   
+   //---
+   // Assuming square for now.  Have to check the spec for this.
+   //---
+   if (size == 25934402) // 2 * 3601 * 3601 three arc second
+   {
+      theNumberOfLines     = 3601;
+      theNumberOfSamples   = 3601;
+      theScalarType = OSSIM_SINT16;
+   }
+   else if(size == 51868804) // 4*3601*3601
+   {
+      theNumberOfLines   = 3601;
+      theNumberOfSamples = 3601;
+      theScalarType = OSSIM_FLOAT32;
+   }
+   else if (size == 2884802) // 2 * 1201 * 1201 one arc second
+   {
+      theNumberOfLines   = 1201;
+      theNumberOfSamples = 1201;
+      theScalarType = OSSIM_SINT16;
+   }
+   else if (size == 5769604)
+   {
+      theNumberOfLines   = 1201;
+      theNumberOfSamples = 1201;
+      theScalarType = OSSIM_FLOAT32;
+   }
+   else // try to get a square width and height
+   {
+      ossim_uint64 lines   = (ossim_uint64)sqrt((ossim_float64)(size / 2));
+      ossim_uint64 samples = (ossim_uint64)sqrt((ossim_float64)(size / 2));
+      // check square
+      if(lines*samples*2 == size)
+      {
+         theNumberOfLines   = lines;
+         theNumberOfSamples = samples;
+         theScalarType = OSSIM_SINT16;
+         
+      }
+      else
+      {
+         ossim_uint64 lines   = (ossim_uint64)sqrt((ossim_float64)(size / 4));
+         ossim_uint64 samples = (ossim_uint64)sqrt((ossim_float64)(size / 4));
+         // check square
+         if(lines*samples*4 == size)
+         {
+            theNumberOfLines   = lines;
+            theNumberOfSamples = samples;
+            theScalarType = OSSIM_FLOAT32;
+         }
+         else
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG) << "ossimSrtmSupportData::setSize(): leaving with false at line " << __LINE__ << std::endl;
+            }
+            return false;
+         }
+      }
+   }
+      
+   theLatSpacing      = 1.0 / (theNumberOfLines   - 1);
+   theLonSpacing      = 1.0 / (theNumberOfSamples - 1);
+   if(traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG) << "ossimSrtmSupportData::setSize(): leaving with true..." << std::endl;
+   }
+   return true;
+}
+
+bool ossimSrtmSupportData::computeMinMax()
+{
+   if(theScalarType == OSSIM_FLOAT32)
+   {
+      return computeMinMaxTemplate((ossim_float32)0,
+                                   -32768.0);
+   }
+   return computeMinMaxTemplate((ossim_sint16)0,
+                                -32768.0);
+   
+   return true;
+}
+
+template <class T>
+bool ossimSrtmSupportData::computeMinMaxTemplate(T dummy,
+                                                 double defaultNull)
+{
+   ossimRefPtr<ossimIStream> is =  ossimStreamFactoryRegistry::instance()->createNewInputStream(theFile,
+                                                                                                ios::in | ios::binary);
+   if (!is.valid())
+   {
+      return false;
+   }
+
+   if(is->fail())
+   {
+      return false;
+   }
+   const size_t BYTES_IN_LINE = theNumberOfSamples * 2;
+   const T NULL_PIX = (T)defaultNull;
+
+   double minValue = 1.0/FLT_EPSILON;
+   double maxValue = -1.0/FLT_EPSILON;
+   T* line_buf = new T[theNumberOfSamples];
+   char* char_buf = (char*)line_buf;
+   ossimEndian swapper;
+
+   ossimByteOrder endianType = ossimGetByteOrder();
+   for (ossim_uint32 line = 0; line < theNumberOfLines; ++line)
+   {
+      is->read(char_buf, BYTES_IN_LINE);
+      if(endianType == OSSIM_LITTLE_ENDIAN)
+      {
+         swapper.swap(line_buf, theNumberOfSamples);
+      }
+      for (ossim_uint32 sample = 0; sample < theNumberOfSamples; ++sample)
+      {
+         if (line_buf[sample] == NULL_PIX) continue;
+         if (line_buf[sample] > maxValue) maxValue = line_buf[sample];
+         if (line_buf[sample] < minValue) minValue = line_buf[sample];
+      }
+   }
+   delete [] line_buf;
+   theMinPixelValue = minValue;
+   theMaxPixelValue = maxValue;
+
+   return true;
+}
+
+ossim_float64 ossimSrtmSupportData::getMinPixelValue() const
+{
+   return theMinPixelValue;
+}
+
+ossim_float64 ossimSrtmSupportData::getMaxPixelValue() const
+{
+   return theMaxPixelValue;
+}
+
+ossimScalarType ossimSrtmSupportData::getScalarType()const
+{
+   return theScalarType;
+}
+
+std::ostream& ossimSrtmSupportData::print(std::ostream& out) const
+{
+   out << setprecision(15) << "ossimSrtmSupportData data members:"
+       << "\nFile:                  " << theFile
+       << "\nLines:                 " << theNumberOfLines
+       << "\nSamples:               " << theNumberOfSamples
+       << "\nSouth West Latitude:   " << theSouthwestLatitude
+       << "\nSouth West Longitude:  " << theSouthwestLongitude
+       << "\nLatitude spacing:      " << theLatSpacing
+       << "\nLongitude spacing:     " << theLonSpacing
+       << "\nMin post value:        " << theMinPixelValue
+       << "\nMax post value:        " << theMaxPixelValue
+       << endl;
+   return out;
+}
+
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmSupportData.h b/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmSupportData.h
new file mode 100644
index 0000000000..6cc78bc22b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/srtm/ossimSrtmSupportData.h
@@ -0,0 +1,191 @@
+//----------------------------------------------------------------------------
+// Copyright (c) 2005, David Burken, all rights reserved.
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// 
+// Support data class for a Shuttle Radar Topography Mission (SRTM) file.
+//
+//----------------------------------------------------------------------------
+// $Id: ossimSrtmSupportData.h,v 1.6 2005/11/10 19:51:41 gpotts Exp $
+#ifndef ossimSrtmSupportData_HEADER
+#define ossimSrtmSupportData_HEADER
+
+#include <base/common/ossimObject.h>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/common/ossimRefPtr.h>
+#include <base/common/ossimIoStream.h>
+
+/**
+ * @class ossimStrmSupportData
+ * Support data class for a Shuttle Radar Topography Mission (SRTM) file.
+ * Provides lines, samples, post spacing and geometry info given a valid
+ * srtm file.  This class will set an error if the file is not deemed to
+ * be valid.
+ */
+class OSSIMDLLEXPORT ossimSrtmSupportData : public ossimObject
+{
+public:
+   /** default constructor */
+   ossimSrtmSupportData();
+
+   /** destructor */
+   virtual ~ossimSrtmSupportData();
+
+   /**
+    * Initializes object from file.  File is expected to be in a format like
+    * N27W081.hgt or n27w081.hgt where "N27" is the South West latitude of
+    * the cell and "W081" is the South West longitude of the cell.
+    *
+    * @param srtmFile File to set.
+    *
+    * @param scanForMinMax If true and there is no ossim meta data file with
+    * the min and max keywords in it, this will call computeMinMax which will
+    * scan the file for min and max.
+    *
+    * @return Returns true if file is deemed to be an srtm, false if not.
+    *
+    * @note This will write an ossim meta data (.omd) if one does not exists.
+    */
+   bool setFilename(const ossimFilename& srtmFile,
+                    bool scanForMinMax = false);
+
+   /** @return Returns the srtm file name. */
+   ossimFilename getFilename() const;
+
+   /**
+    * @return Returns the number of lines or rows.  Returns  OSSIM_UINT_NAN
+    * if not initialized or file was invalid.
+    */
+   ossim_uint32 getNumberOfLines() const;
+   
+   /**
+    * @return Returns the number of samples or columns. Returns
+    * OSSIM_UINT_NAN if not initialized or file was invalid.
+    */
+   ossim_uint32 getNumberOfSamples() const;
+
+   /**
+    *  Populates the keyword list with image geometry information.  This
+    *  method is used to relay projection information to users.
+    *
+    *  @param kwl Keyword list that will be initialized with geometry info.
+    *  Returns true if geometry info is present, false if not.
+    *
+    *  @param prefix The prefix is added to the resulting keyword list
+    *  keywords.  So is you if you pass in a prefix of "image01.", the
+    *  keyword ul_lat will be like:  "image01.ul_lat:  -40.00000"
+    */
+   virtual bool getImageGeometry(ossimKeywordlist& kwl, const char* prefix=0);
+
+   /**
+    * Method to save the state of the object to a keyword list.
+    * Return true if ok or false on error.
+    */
+   virtual bool saveState(ossimKeywordlist& kwl,
+                          const char* prefix=0) const;
+   
+   /**
+    * Method to the load (recreate) the state of the object from a keyword
+    * list.  Return true if ok or false on error.
+    */
+   virtual bool loadState(const ossimKeywordlist& kwl,
+                          const char* prefix=0);
+   
+   /**
+    * @return Returns the Southwest latitude in decimal degrees. Returns
+    * OSSIM_DBL_NAN if not initialized or file was invalid.
+    */
+   ossim_float64 getSouthwestLatitude() const;
+
+   /**
+    * @return Returns the Southwest longitude in decimal degrees.  Returns
+    * OSSIM_DBL_NAN if not initialized or file was invalid.
+    */
+   ossim_float64 getSouthwestLongitude() const;
+   
+   /**
+    * @return Returns the latitude spacing in decimal degrees. Returns
+    * OSSIM_DBL_NAN if not initialized or file was invalid.
+    */
+   ossim_float64 getLatitudeSpacing() const;
+
+   /**
+    * @return Returns the longitude spacing in decimal degrees.  Returns
+    * OSSIM_DBL_NAN if not initialized or file was invalid.
+    */
+   ossim_float64 getLongitudeSpacing() const;
+
+   /**
+    * @return Returns the minimum pixel value.  This is also
+    * the minimum height above sea level.  Returns
+    * OSSIM_SSHORT_NAN if not initialized or file was invalid.
+    */
+   ossim_float64 getMinPixelValue() const;
+
+   /**
+    * @return Returns the maximum pixel value.  This is also
+    * the minimum height above sea level.  Returns
+    * OSSIM_SSHORT_NAN if not initialized or file was invalid.
+    */
+   ossim_float64 getMaxPixelValue() const;
+
+   ossimScalarType getScalarType()const;
+   /**
+    * Prints data members for debug.
+    * 
+    * @return std::ostream&
+    */
+   virtual std::ostream& print(std::ostream& out) const;
+
+private:
+
+   /** Sets all data members to an unitialized state. */
+   void clear();
+
+   /**
+    * Sets corner points from "theFile".
+    *
+    * @return true on success, false on error.
+    */
+   bool setCornerPoints();
+   
+   /**
+    * Sets lines and samples from "theFile" size.
+    *
+    * @return true on success, false on error.
+    */
+   bool setSize();
+
+   /**
+    * Scans file for min and max pixels.
+    *
+    * @retun true on success, false on error.
+    */
+   bool computeMinMax();
+  
+   ossimFilename theFile;
+   ossim_uint32  theNumberOfLines;
+   ossim_uint32  theNumberOfSamples;
+   ossim_float64 theSouthwestLatitude;  //< decimal degrees
+   ossim_float64 theSouthwestLongitude; //< decimal degrees
+   ossim_float64 theLatSpacing;         //< decimal degrees
+   ossim_float64 theLonSpacing;         //< decimal degrees
+   ossim_float64 theMinPixelValue;      //< meters
+   ossim_float64 theMaxPixelValue;      //< meters
+
+   ossimScalarType theScalarType;
+
+   mutable ossimRefPtr<ossimIStream> theFileStream;
+   template <class T>
+   bool computeMinMaxTemplate(T dummy,
+                              double defaultNull);
+};
+
+#endif /* #ifndef ossimSrtmSupportData */
diff --git a/Utilities/OSSIM/ossim_core/support_data/tiff/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/tiff/.cvsignore
new file mode 100644
index 0000000000..3ccb77a586
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/tiff/.cvsignore
@@ -0,0 +1,4 @@
+*.d
+*.o
+*.~*
+Makefile
diff --git a/Utilities/OSSIM/ossim_core/support_data/tiff/ossimGeoTiff.cpp b/Utilities/OSSIM/ossim_core/support_data/tiff/ossimGeoTiff.cpp
new file mode 100644
index 0000000000..e37f1ec4ad
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/tiff/ossimGeoTiff.cpp
@@ -0,0 +1,2146 @@
+//***************************************************************************
+// FILE: ossimGeoTiff
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// Class definition for ossimGeoTiff which is designed to read and hold tag
+// information.
+//
+//***************************************************************************
+// $Id: ossimGeoTiff.cpp,v 1.34 2005/09/01 14:34:01 gpotts Exp $
+
+
+#include <tiffio.h>
+#include <string.h>
+#include <fstream>
+#include <iomanip>
+using namespace std;
+
+#include <support_data/tiff/ossimGeoTiff.h>
+#include <base/common/ossimTrace.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/misc/lookup_tables/ossimGeoTiffCoordTransformsLut.h>
+#include <base/misc/lookup_tables/ossimGeoTiffDatumLut.h>
+#include <base/context/ossimNotifyContext.h>
+#include <base/context/ossimNotifyContext.h>
+
+static const ossimGeoTiffCoordTransformsLut COORD_TRANS_LUT;
+static const ossimGeoTiffDatumLut DATUM_LUT;
+
+#ifdef OSSIM_ID_ENABLED
+static const char OSSIM_ID[] = "$Id: ossimGeoTiff.cpp,v 1.34 2005/09/01 14:34:01 gpotts Exp $";
+#endif
+
+//---
+// Static trace for debugging
+//---
+static ossimTrace traceDebug("ossimGeoTiff:debug");
+
+ossimGeoTiff::ossimGeoTiff(const ossimFilename& file)
+   :
+      theGeoKeyOffset(0),
+      theGeoKeyLength(0),
+      theTiffByteOrder(OSSIM_LITTLE_ENDIAN),
+      theEndian(),
+      theGeoKeysPresentFlag(false),
+      theZone(0),
+      theHemisphere("N"),
+      theDoubleParamLength(0),
+      theAsciiParamLength(0),
+      theProjectionName("unknown"),
+      theDatumName("unknown"),
+      
+      theScale(),
+      theTiePoint(),
+      theModelTransformation(),
+      theDoubleParam(0),
+      theAsciiParam(0),
+      
+      theWidth(0),
+      theLength(0),
+      theBitsPerSample(),
+      theCompresionType(NOT_COMPRESSED),
+      thePhotoInterpretation(PHOTO_MINISBLACK),
+      theImageDescriptionString(),
+      theSamplesPerPixel(0),
+      thePlanarConfig(PLANARCONFIG_CONTIG),
+      theSoftwareDescriptionString(),
+      theDateDescriptionString(),
+      theTileWidth(0),
+      theTileLength(0),
+      
+      theModelType(UNKNOWN),
+      theRasterType(UNDEFINED),
+      theGcsCode(0),
+      theDatumCode(0),
+      theAngularUnits(0),
+      thePcsCode(0),
+      theSavePcsCodeFlag(false),
+      thePcsCitation(),
+      theProjGeoCode(0),
+      theCoorTransGeoCode(0),
+      theLinearUnitsCode(UNDEFINED),
+      theStdPar1(0.0),
+      theStdPar2(0.0),
+      theOriginLon(0.0),
+      theOriginLat(0.0),
+      theFalseEasting(0.0),
+      theFalseNorthing(0.0),
+      theCenterLon(0.0),
+      theCenterLat(0.0),
+      theScaleFactor(0.0)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::ossimGeoTiff: Entered..." << std::endl;
+#ifdef OSSIM_ID_ENABLED
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::ossimGeoTiff: OSSIM_ID =  "
+         << OSSIM_ID << endl;
+#endif      
+   }
+   
+   if(readTags(file) == false)
+   {
+      if (traceDebug())
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimGeoTiff::ossimGeoTiff: "
+            << "Unable to reade tags."
+            << std::endl;
+      }
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimGeoTiff::ossimGeoTiff: "
+         << "Unable to reade tags."
+         << std::endl;
+   }
+}
+
+ossimGeoTiff::~ossimGeoTiff()
+{
+   if (theAsciiParam)
+   {
+      delete [] theAsciiParam;
+      theAsciiParam = 0;
+   }
+   if (theDoubleParam)
+   {
+      delete [] theDoubleParam;
+      theDoubleParam = 0;
+   }
+}
+
+bool ossimGeoTiff::readTags(const ossimFilename& file)
+{
+   theCenterLon = OSSIM_DBL_NAN;
+   theCenterLat = OSSIM_DBL_NAN;
+   theOriginLon = OSSIM_DBL_NAN;
+   theOriginLat = OSSIM_DBL_NAN;
+   
+   theSavePcsCodeFlag = false;
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::readTags: Entered...\n";
+   }
+
+   //---
+   // Open the tif file.
+   //---
+   ifstream str(file.c_str(), ios::binary|ios::in);
+   if (!str) 
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimGeoTiff::readTags: "
+         << "Cannot open file:  " << file
+         << std::endl;
+      
+      return false;
+   }
+   
+   //---
+   // Get the byte order.  The data member "theTiffByteOrder" was set to
+   // BIG_END in the initialization list.  This will be changed if
+   // byte order is LITTLE_END(IBM, DEC).
+   //---
+   char byteOrder[3];
+   str.read(byteOrder, 2); // Read the byte order.
+   byteOrder[2] = '\0';  // Null terminate.
+
+   //---
+   // Change the byte order if it was not default of little endian.
+   //---   
+   if (byteOrder[0] == 'M')
+   {
+      theTiffByteOrder = OSSIM_BIG_ENDIAN;
+   }
+   
+   ossim_uint16 version;
+   readShort(version, str);
+   
+   if (byteOrder[0] != 'I' &&
+       byteOrder[0] != 'M' &&
+       version      != 42)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimGeoTiff::readTags:  Unacceptable image format."
+         << "\nByte Order:  " << byteOrder
+         << "\nversion:     " << dec << version << std::endl;
+      str.close();
+      return false;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << " DEBUG ossimGeoTiff::readTags: "
+         << "version:  " << dec << version << "\n";
+      
+      if (theTiffByteOrder == OSSIM_BIG_ENDIAN)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Byte Order:  BIG_ENDIAN" << std::endl;
+      }
+      else // OSSIM_LITTLE_ENDIAN
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "Byte Order:  LITTLE_ENDIAN" << std::endl;
+      }
+
+      if (theEndian.getSystemEndianType() == OSSIM_BIG_ENDIAN)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "System Byte Order:  BIG_ENDIAN" << std::endl;
+      }
+      else // OSSIM_LITTLE_ENDIAN
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "System Byte Order:  LITTLE_ENDIAN" << std::endl;
+      }   
+   }
+
+   //---
+   // Variables used within the loop.
+   //---
+   ossim_uint32  ifdOffset   = 0; // Image File Directory.
+   ossim_uint16  ndirs       = 0; // Number of directory entries.
+   
+   //---
+   // Get the offset to the first Image File Directory (IFD).
+   //---
+   readLong(ifdOffset, str);
+   if (!str)
+   {
+      ossimNotify(ossimNotifyLevel_FATAL)
+         << "FATAL ossimGeoTiff::readTags: "
+         << "No offset to an image file directory found.\n"
+         << "Returning with error."
+         << std::endl;
+      str.close();
+      return false;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::readTags: "
+         << "Offset to first ifd:  " << dec << ifdOffset
+         << "\n";
+   }
+
+   while(ifdOffset)
+   {
+      
+      str.seekg(ifdOffset, ios::beg);  // Seek to the image file directory.
+
+      //---
+      // Get the number of directories within the IFD.
+      //---
+      readShort(ndirs, str);
+      if (!str)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATAL ossimGeoTiff::readTags: "
+            << "Error reading number of direcories."
+            << std::endl;
+         str.close();
+         return false;
+      }
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimGeoTiff::readTags:\n"
+            << "ifd:  " << dec << ifdOffset
+            << "\nndirs:  " << dec << ndirs << std::endl;
+      }
+
+      for (short dir = 0; dir < ndirs; ++dir)
+      {
+         // Variables used within the loop.
+         ossim_uint16   tag         = 0; // Tag number
+         ossim_uint16   type        = 0; // Type(short, long...)
+         ossim_int32    length      = 0;
+         ossim_uint32   offset      = 0; // Value or Offset to data.
+         ossim_uint8    byteValue   = 0;
+         ossim_uint16   shortValue  = 0;
+         ossim_uint32   longValue   = 0;
+         ossim_float32  floatValue  = 0.0;
+         ossim_float64  doubleValue = 0.0;
+         ossim_uint8*   byteArray   = 0;
+         ossim_int8*    asciiArray  = 0;
+         ossim_uint16*  shortArray  = 0;
+         ossim_uint32*  longArray   = 0;
+         ossim_float32* floatArray  = 0;
+         ossim_float64* doubleArray = 0;
+         
+         //---
+         // Get the tag.
+         //---
+         readShort(tag, str);
+         if (!str)
+         {
+            ossimNotify(ossimNotifyLevel_FATAL)
+               << "FATAL ossimGeoTiff::readTags: "
+               << "Error reading tag number."
+               << std::endl;
+            str.close();
+            return false;
+         }
+
+         //---
+         // Get the type (byte, ascii, short...)
+         //---
+         readShort(type, str);
+         if (!str)
+         {
+            ossimNotify(ossimNotifyLevel_FATAL)
+               << "FATAL ossimGeoTiff::readTags: "
+               << "Error reading type number."
+               << std::endl;
+            str.close();
+            return false;
+         }
+
+         //---
+         // Get the count.  This is not in bytes.  It is based on the
+         // type.  So if the type is a short and the count is one then
+         // read "sizeof(short"(2) bytes.
+         //---
+         readLong(length, str);
+         if (!str)
+         {
+            ossimNotify(ossimNotifyLevel_FATAL)
+               << "FATAL ossimGeoTiff::readTags: "
+               << "Error reading length."
+               << std::endl;
+            str.close();
+            return false;
+         }
+         if(traceDebug())
+	 {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "DEBUG ossimGeoTiff::readTags:"
+               << "\nDirectory index:  " << dir
+               << "\ntag:              " << tag
+               << "\ntype:             " << type
+               << "\nlength:           " << length << std::endl;
+
+	 }
+         //---
+         // Info is stored in the next four bytes if it will fit.  If not
+         // the 4 bytes is an offset to the data.  Need to determine
+         // if the data fits in next four bytes based on the type and count.
+         //---
+         switch (type)
+         {
+            case TIFF_BYTE:
+            {
+               if (length > 1) // Need the array.
+               {
+                  if (byteArray) delete [] byteArray;
+                  byteArray = new unsigned char[length];
+               }
+            
+               if (length == 1)
+               {
+                  str.read((char*)&byteValue, length);
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        << "FATAL ossimGeoTiff::readTags: "
+                        << "Error reading data." << std::endl;
+                     str.close();
+                     return false;
+                  }
+               }
+               else if (length < 5)
+               {
+                  str.read((char*)byteArray, length);
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        << "FATAL ossimGeoTiff::readTags:"
+                        << "Error reading data." << std::endl;
+                     str.close();
+                     return false;
+                  }
+               }
+               else if (length > 4)
+               {
+                  // Get the offset to the data.
+                  readLong(offset, str);
+               
+                  streampos pos = str.tellg(); // Capture position
+               
+                  str.seekg(offset, ios::beg); // Seek to the string.
+
+                  str.read((char*)byteArray, length);
+               
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        << "FATAL ossimGeoTiff::readTags:"
+                        << "Unable to read byte array." << std::endl;
+                     str.close();
+                     return false;
+                  }
+               
+                  str.seekg(pos, ios::beg); // Seek back.
+               }
+            
+               if (length < 4) // Seek to the end of the directory entry.
+               {
+                  str.seekg(4 - length, ios::cur);
+               }
+            
+               break;
+            
+            }  // End of case TIFF_BYTE
+            
+            case TIFF_ASCII:
+            {
+               if (asciiArray) delete [] asciiArray;
+               asciiArray = new char[length];
+            
+               if (length < 5)
+               {
+                  str.read(asciiArray, length);
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        << "FATAL ossimGeoTiff::readTags: "
+                        << "Unable to read data." << std::endl;
+                     str.close();
+                     return false;
+                  }
+               }
+               else if (length > 4)
+               {
+                  // Get the offset to the data.
+                  readLong(offset, str);
+               
+                  streampos pos = str.tellg(); // Capture position
+               
+                  str.seekg(offset, ios::beg); // Seek to the string.
+                  
+                  str.read(asciiArray, length);
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        << "FATAL ossimGeoTiff::readTags: "
+                        << "Unable to read ascii array." << std::endl;
+                     str.close();
+                     return false;
+                  }
+               
+                  str.seekg(pos, ios::beg); // Seek back.
+               }
+            
+               if (length < 4) // Seek to the end of the directory entry.
+               {
+                  str.seekg(4 - length, ios::cur);
+               }
+            
+               asciiArray[length-1] = '\0'; // Null terminate to be safe.
+            
+               break;
+            
+            }  // End of case TIFF_ASCII
+         
+            case TIFF_SHORT:
+            {
+               if (length > 1)
+               {
+                  if (shortArray) delete [] shortArray;
+                  shortArray = new unsigned short[length];
+               }
+            
+               if (length == 1)
+               {
+                  readShort(shortValue, str);
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        << "FATAL ossimGeoTiff::readTags: "
+                        << "Unable to read SHORT data" << endl;
+                     str.close();
+                     return false;
+                  }
+
+		  str.ignore(2);
+                  // Seek to next direcory entry.
+		  //                  str.seekg(2, ios::cur);
+               }
+               else if (length == 2)
+               {
+                  // Get the first short.
+                  readShort(shortArray[0], str);
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        << "FATAL ossimGeoTiff::readTags: "
+                        << "Unable to read SHORT data" << std::endl;
+                     str.close();
+                     return false;
+                  }
+               
+                  // Get the second short.
+                  readShort(shortArray[1], str);
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        <<"FATAL ossimGeoTiff::readTags: "
+                        << "Unalbe to read SHORT data" << std::endl;
+                     str.close();
+                     return false;
+                  }
+               }
+               else
+               {
+                  // Get the offset to the data.
+                  readLong(offset, str);
+               
+                  streampos pos = str.tellg(); // Capture position
+                  str.seekg(offset, ios::beg); // Seek to the array.
+               
+		  for (int i=0; i<length; ++i)
+		  {
+                     readShort(shortArray[i], str);
+                     if (!str)
+                     {
+                        ossimNotify(ossimNotifyLevel_FATAL)
+                           << "FATAL ossimGeoTiff::readTags: "
+                           << "Unable to read short array." << endl;
+                        str.close();
+                        return false;
+                     }
+                   }
+               
+                  str.seekg(pos, ios::beg); // Seek back.
+               }
+            
+               break;
+            
+            }  // End of case TIFF_SHORT
+            
+            case TIFF_LONG:
+            {
+               if (length > 1)
+               {
+                  if (longArray) delete [] longArray;
+                  longArray = new ossim_uint32[length];
+               }
+            
+               if (length == 1)
+               {
+                  readLong(longValue, str);
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        << "FATAL ossimGeoTiff::readTags: "
+                        << "Unable to read LONG data." << std::endl;
+                     str.close();
+                     return false;
+                  }
+               }
+               else
+               {
+                  // Get the offset to the data.
+                  readLong(offset, str);
+                  streampos pos = str.tellg(); // Capture position
+                  
+                  str.seekg(offset, ios::beg); // Seek to the array.
+
+                  for (int i=0; i<length; ++i)
+                  {
+                     readLong(longArray[i], str);
+                     if (!str)
+                     {
+                        ossimNotify(ossimNotifyLevel_FATAL)
+                           << "FATAL ossimGeoTiff::readTags: "
+                           << "Unable to read long array." << std::endl;
+                        str.close();
+                        return false;
+                     }
+                  }
+                  
+                  str.seekg(pos, ios::beg); // Seek back.
+               }
+               
+               break;
+
+            } // End of case TIFF_LONG
+
+            case TIFF_DOUBLE:
+            {
+               if (doubleArray) delete [] doubleArray;
+               doubleArray = new double[length];
+
+               // Get the offset to the data.
+               readLong(offset, str);
+               
+               streampos pos = str.tellg(); // Capture position
+               
+               str.seekg(offset, ios::beg); // Seek to the array.
+               
+               for (int i=0; i<length; ++i)
+               {
+                  readDouble(doubleArray[i], str);
+                  if (!str)
+                  {
+                     ossimNotify(ossimNotifyLevel_FATAL)
+                        << "FATAL ossimGeoTiff::readTags: "
+                        << "Error reading double array." << std::endl;
+                     str.close();
+                     return false;
+                  }
+               }
+                  
+               str.seekg(pos, ios::beg); // Seek back.
+               
+               break;
+            }
+
+            case TIFF_RATIONAL:
+            case TIFF_SBYTE:
+            case TIFF_UNDEFINED:
+            case TIFF_SSHORT:
+            case TIFF_SLONG:
+            case TIFF_SRATIONAL:
+            case TIFF_FLOAT:
+            {
+               if (traceDebug())
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG)
+                     << "DEBUG ossimGeoTiff::readTags:"
+                     << " Type currently not handled "
+                     << " type = " << dec << type
+                     << std::endl;
+               }
+            }
+            default:
+            {
+               // Get the offset to the data.
+               readLong(offset, str);
+               if (!str)
+               {
+                  ossimNotify(ossimNotifyLevel_FATAL)
+                     << "FATAL ossimGeoTiff::readTags: "
+                     << "Unable to read offset to next directory."
+                     << std::endl;
+                  str.close();
+                  return false;
+               }
+               break;
+            }
+            
+         } // End of switch on type.
+         if (traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG)
+               << "\nbyteValue:        " << int(byteValue)
+               << "\nshortValue:       " << shortValue
+               << "\nlongValue:        " << longValue
+               << "\nfloatValue:       " << floatValue
+               << "\ndoubleValue:      " << doubleValue
+               << "\noffset:           " << offset
+               << std::endl;
+
+//#if 0 /* Very serious debug only... */
+            if (byteArray)
+            {
+               for (int i = 0; i < length; ++i)
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG)
+                     << "byteArray[" << i << "]:  " << byteArray[i]
+                     << std::endl;
+               }
+            }
+            if (asciiArray)
+            {
+               ossimNotify(ossimNotifyLevel_DEBUG)
+                  << "asciiArray:    " << asciiArray << std::endl;
+            }
+            if (shortArray)
+            {
+               for (int i = 0; i < length; ++i)
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG)
+                     << "shortArray[" << i << "]:  " << shortArray[i]
+                     << std::endl;
+               }
+            }
+            if (longArray)
+            {
+               for (int i = 0; i < length; ++i)
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG)
+                     << "longArray[" << i << "]:  " << longArray[i]
+                     << std::endl;
+               }
+            }
+            if (doubleArray)
+            {
+               for (int i = 0; i < length; ++i)
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG)
+                     << setiosflags(ios::fixed) << setprecision(15)
+                     << "doubleArray[" << i << "]:  " << doubleArray[i]
+                     << std::endl;
+               }
+            }
+            
+// #endif  /* #if 0 */
+            
+         } // End of "if traceDebug()"
+         
+
+         switch(tag)
+         {
+            case TIFFTAG_IMAGEWIDTH: // tag 256
+               if (type == TIFF_SHORT)
+               {
+                  theWidth = shortValue;
+               }
+               else if (type == TIFF_LONG)
+               {
+                  theWidth = longValue;
+               }
+               else
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << "WARNING: "
+                     << "Invalid type [ " << type << " ] for image width."
+                     << std::endl;
+               }
+               break;
+         
+            case TIFFTAG_IMAGELENGTH: // tag 257
+               if (type == TIFF_SHORT)
+               {
+                  theLength = shortValue;
+               }
+               else if (type == TIFF_LONG)
+               {
+                  theLength = longValue;
+               }
+               else
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << "WARNING:\n"
+                     << "Invalid type [ " << type << " ] for image length."
+                     << std::endl;
+               }
+               break;
+            
+            case TIFFTAG_BITSPERSAMPLE: // tag 258
+               // Clear out any old points.
+               theBitsPerSample.clear();
+               
+               if (length == 1)
+               {
+                  theBitsPerSample.push_back(shortValue);
+               }
+               else if (shortArray)
+               {
+                  for (int i=0; i<length; ++i)
+                  {
+                     theBitsPerSample.push_back(shortArray[i]);
+                  }
+               }
+               break;
+         
+            case TIFFTAG_COMPRESSION: // tag 259
+               if (shortValue == 1)
+               {
+                  theCompresionType = NOT_COMPRESSED;
+               }
+               else
+               {
+                  theCompresionType = COMPRESSED;
+               }
+               break;
+
+            case TIFFTAG_PHOTOMETRIC: // tag 262
+               thePhotoInterpretation = (PhotoInterpretation)shortValue;
+               break;
+         
+            case TIFFTAG_IMAGEDESCRIPTION: // tag 270
+               if (asciiArray)
+               {
+                  theImageDescriptionString = asciiArray;
+               }
+               break;
+
+            case TIFFTAG_SAMPLESPERPIXEL: // tag 277
+               theSamplesPerPixel = shortValue;
+               break;
+
+            case TIFFTAG_PLANARCONFIG: // tag 284
+               thePlanarConfig = shortValue;
+               break;
+
+            case TIFFTAG_SOFTWARE: // tag 305
+               if (asciiArray)
+               {
+                  theSoftwareDescriptionString = asciiArray;
+               }
+               break;
+
+            case TIFFTAG_DATETIME: // tag 306
+               if (asciiArray)
+               {
+                  theDateDescriptionString = asciiArray;
+               }
+               break;
+
+            case TIFFTAG_TILEWIDTH: // tag 322
+               if (type == TIFF_SHORT)
+               {
+                  theTileWidth = shortValue;
+               }
+               else if (type == TIFF_LONG)
+               {
+                  theTileWidth = longValue;
+               }
+               else
+               {
+                  ossimNotify(ossimNotifyLevel_WARN)
+                     << "WARNING:\n"
+                     << "Invalid type [ " << type << " ] for tile width."
+                     << std::endl;
+               }
+               break;
+
+            case TIFFTAG_TILELENGTH: // tag 323
+               if (type == TIFF_SHORT)
+               {
+                  theTileLength = shortValue;
+               }
+               else if (type == TIFF_LONG)
+               {
+                  theTileLength = longValue;
+               }
+               else
+               {
+                  ossimNotify(ossimNotifyLevel_DEBUG)
+                     << "WARNING:\n"
+                     << "Invalid type [ " << type << " ] for tile length."
+                     << std::endl;
+               }
+               
+               break;
+
+            case MODEL_PIXEL_SCALE_TAG: // tag 33550
+               if ( doubleArray )
+               {
+                  // Clear out any old points.
+                  theScale.clear();
+
+                  for (int i = 0; i < length; ++i)
+                  {
+                     theScale.push_back(doubleArray[i]);
+                  }
+               }
+
+               break;
+
+            case MODEL_TIE_POINT_TAG: // tag 33922
+               if ( doubleArray )
+               {
+                  // Clear out any old points.
+                  theTiePoint.clear();
+
+                  for (int i=0; i<length; ++i)
+                  {
+                     theTiePoint.push_back(doubleArray[i]);
+                  }
+               }
+               
+               break;
+
+            case MODEL_TRANSFORM_TAG: // tag 34264
+               if ( doubleArray )
+               {
+                  // Clear out any old points.
+                  theModelTransformation.clear();
+
+                  for (int i=0; i<length; ++i)
+                  {
+                     theModelTransformation.push_back(doubleArray[i]);
+                  }
+               }
+               break;
+
+            case GEO_KEY_DIRECTORY_TAG: // tag 34735
+               theGeoKeysPresentFlag = 1;
+
+               // Store the offset and length for later.
+               theGeoKeyOffset = offset;
+               theGeoKeyLength = length;
+               
+               break;
+         
+            case GEO_DOUBLE_PARAMS_TAG: // tag 34736
+               if ( doubleArray )
+               {
+                  //---
+                  // This can contain multiple key values.  This
+                  // will grap them all.  They will be sorted out in the method
+                  // readGeoKeys.
+                  //---
+                  theDoubleParamLength = length;
+
+                  if (theDoubleParam) delete [] theDoubleParam;
+            
+                  theDoubleParam = new double[theDoubleParamLength];
+
+                  for (int i=0; i<length; ++i)
+                  {
+                     theDoubleParam[i] = doubleArray[i];
+                  }
+               }
+               break;
+
+            case GEO_ASCII_PARAMS_TAG: // tag 34737
+               if ( asciiArray )
+               {
+                  //---
+                  // This can contain multiple strings.  This
+                  // will grap them all.  They will be sorted out in the method
+                  // readGeoKeys.
+                  //---
+                  theAsciiParamLength = length;
+            
+                  if (theAsciiParam) delete [] theAsciiParam;
+                  
+                  theAsciiParam = new char[length];
+
+                  for (int i=0; i<length; ++i)
+                  {
+                     theAsciiParam[i] = asciiArray[i];
+                  }
+               }
+               break;
+         
+            default:
+               break;
+         } // End of switch.
+
+         // Free memory if allocated...
+         if (byteArray)
+         {
+            delete [] byteArray;
+            asciiArray = 0;
+         }
+         if (asciiArray)
+         {
+            delete [] asciiArray;
+            asciiArray = 0;
+         }
+         if (shortArray)
+         {
+            delete [] shortArray;
+            shortArray = 0;
+         }
+         if (longArray)
+         {
+            delete [] longArray;
+            longArray = 0;
+         }
+         if (floatArray)
+         {
+            delete [] floatArray;
+            floatArray = 0;
+         }
+         if (doubleArray)
+         {
+            delete [] doubleArray;
+            doubleArray = 0;
+         }
+         
+      } // End of loop through directories
+
+      //---
+      // Get the next IFD offset.  Continue this loop until the offset is
+      // zero.
+      //---
+      readLong(ifdOffset, str);
+      if (!str)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "FATAL ossimGeoTiff::readTags: "
+            << "No offset to an image file directory found.\n"
+            << "Returning with error."
+            << std::endl;
+         str.close();
+         return false;
+      }
+      
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimGeoTiff::readTags: "
+            << "Next Image File Directory(IFD) offset = "
+            << dec << ifdOffset << std::endl;
+      }
+
+      //---
+      // Break out of the loop here so we only read the first image directory.
+      //---
+      break;
+      
+   } // End of loop through the IFD's.
+
+   //---
+   // If Geotiff Keys read them.  This had to done last since the keys could
+   // have references to tags GEO_DOUBLE_PARAMS_TAG and GEO_ASCII_PARAMS_TAG.
+   //---
+   if (theGeoKeysPresentFlag)
+   {      
+      if (readGeoKeys(str, theGeoKeyOffset, theGeoKeyLength) == false)
+      {
+         theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATALossimGeoTiff::readTags: "
+            << "Unable to read geotiff keys."
+            << std::endl;
+         str.close();
+         return false;
+      }
+
+      setOssimProjectionName();  // Initialize the ossim projection name.
+      setOssimDatumName();       // Initialize the ossim datum name.
+   }
+   
+   str.close();
+   
+   if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG)
+      << "DEBUG ossimGeoTiff::readTags: Exited..." << std::endl;
+   
+   return true;
+}
+
+void ossimGeoTiff::readShort(ossim_uint16& s, ifstream& str)
+{
+   str.read((char*)&s, sizeof(s));
+   if (theTiffByteOrder != theEndian.getSystemEndianType())
+   {
+      theEndian.swap(s);
+   }
+}
+
+void ossimGeoTiff::readLong(ossim_int32& l, ifstream& str)
+{
+   str.read((char*)&l, sizeof(l));
+   if (theTiffByteOrder != theEndian.getSystemEndianType())
+   {
+      theEndian.swap(l);
+   }
+}
+
+void ossimGeoTiff::readLong(ossim_uint32& l, ifstream& str)
+{
+   str.read((char*)&l, sizeof(l));
+   if (theTiffByteOrder != theEndian.getSystemEndianType())
+   {
+      theEndian.swap(l);
+   }
+}
+
+void ossimGeoTiff::readDouble(ossim_float64& d, ifstream& str)
+{
+   str.read((char*)&d, sizeof(d));
+   if (theTiffByteOrder != theEndian.getSystemEndianType())
+   {
+      theEndian.swap(d);
+   }
+}
+
+bool ossimGeoTiff::readGeoKeys(ifstream& str, streampos offset, int length)
+{
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::readGeoKeys: Entered..." << std::endl;
+   }
+
+   //---
+   // Each key contains four unsigned shorts:
+   // GeoKey ID
+   // TIFF Tag ID or 0
+   // GeoKey value count
+   // value or tag offset
+   //---
+   unsigned short key;
+   unsigned short tag;
+   unsigned short count;
+   unsigned short code;
+
+   //---
+   // Save the original file position.
+   //---
+   streampos pos = str.tellg();
+
+   str.seekg(offset, ios::beg);  // Seek to the Key directory.
+
+   //---
+   // Length passed in is the total number of shorts in the geo key directory.
+   // Each key has four short values; hence, "length/4".
+   //---
+   for (int i = 0; i < length/4; i++)
+   {
+      //---
+      // Get the key.
+      //---
+      readShort(key, str);
+      if (!str)
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "FATAL ossimGeoTiff::readGeoKeys: "
+            << "Unable to read tag number."
+            << std::endl;
+         str.close();
+         return false;
+      }
+
+      //---
+      // Get the tiff tag.  This will either be a tag of zero.
+      //---
+      readShort(tag, str);
+      if (!str)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATAL ossimGeoTiff::readGeoKeys: "
+            << "Unalbe to read type number."
+            << std::endl;
+         str.close();
+         return false;
+      }
+
+      //---
+      // Get the count.  
+      //---
+      readShort(count, str);
+      if (!str)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATAL  ossimGeoTiff::readGeoKeys: "
+            << "Unable to read length."
+            << std::endl;
+         str.close();
+         return false;
+      }
+
+      //---
+      // Get the value.
+      //---
+      readShort(code, str);
+      if (!str)
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATAL ossimGeoTiff::readGeoKeys: "
+            << "Unable to read length."
+            << std::endl;
+         str.close();
+         return false;
+      }
+
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG  ossimGeoTiff::readGeoKeys"
+            << "\nKey index:  " << i
+            << "\ngeo key:  " << key
+            << "\ntag:      " << tag
+            << "\ncount:    " << count
+            << "\ncode:     " << code
+            << std::endl;
+      }
+
+      switch (key)
+      {
+         case GT_MODEL_TYPE_GEO_KEY:  // key 1024 Section 6.3.1.1 Codes
+            theModelType = (ModelType)code;
+            break;
+         
+         case GT_RASTER_TYPE_GEO_KEY:  // key 1025 Section 6.3.1.2 Code
+            theRasterType = code;
+            break;
+         
+         case GEOGRAPHIC_TYPE_GEO_KEY:  // key 2048  Section 6.3.2.1 Codes
+            theGcsCode = code;
+            break;
+
+         case GEOG_GEODETIC_DATUM_GEO_KEY:  // key 2050  Section 6.3.2.2 Codes
+            theDatumCode = code;
+            break;
+         
+         case GEOG_ANGULAR_UNITS_GEO_KEY:  // key 2054  Section 6.3.1.4 Codes
+            theAngularUnits = code;
+            break;
+         
+         case PROJECTED_CS_TYPE_GEO_KEY: // key 3072 Section 6.3.3.1 codes
+            thePcsCode = code;
+            parsePcsCode(thePcsCode);
+            break;
+         
+         case PCS_CITATION_GEO_KEY: // key 3073 ascii
+         {
+            if(theAsciiParamLength)
+            {
+               //---
+               // Ensure the code + count does not bust the string length.
+               //---
+               if( (code + count) > theAsciiParamLength)
+               {
+                  ossimNotify(ossimNotifyLevel_FATAL)
+                     << "FATAL ossimGeoTiff::readGeoKeys: "
+                     << "Attempting to copy past the end of string."
+                     << "\nString will not be copied." << std::endl;
+               }
+               else
+               {
+                  // Limit the scope of tmp.
+                  char* tmp = new char[count];
+                  strncpy(tmp, &theAsciiParam[code], count);
+                  tmp[count-1] = '\0'; // Null terminate.
+                  thePcsCitation = tmp;
+                  delete [] tmp;
+               }
+            }
+         }
+         break;
+      
+         case PROJECTION_GEO_KEY: // key 3074 Section 6.3.3.2 codes
+            theProjGeoCode = code;
+            parseProjGeoCode(theProjGeoCode);
+            break;
+         
+         case PROJ_COORD_TRANS_GEO_KEY:  // key 3075 Section 6.3.3.3 codes
+            theCoorTransGeoCode = code;
+            break;
+         
+         case LINEAR_UNITS_GEO_KEY:  // key 3076 Section 6.3.1.3 codes
+            theLinearUnitsCode = code;
+            break;
+         
+         case PROJ_STD_PARALLEL1_GEO_KEY:  // key 3078 GeogAngularUnit
+            if( (tag == GEO_DOUBLE_PARAMS_TAG) &&
+                (code <= (theDoubleParamLength - 1)) )
+            {
+               //---
+               // Grab the value from the theDoubleParam
+               //---
+               theStdPar1 = theDoubleParam[code];
+            }
+         
+            break;
+         
+         case PROJ_STD_PARALLEL2_GEO_KEY:  // key 3079 GeogAngularUnit
+            if( (tag == GEO_DOUBLE_PARAMS_TAG) &&
+                (code <= (theDoubleParamLength - 1)) )
+            {
+               //---
+               // Grab the value from the theDoubleParam
+               //---
+               theStdPar2 = theDoubleParam[code];
+            }
+         
+            break;
+         
+         case PROJ_NAT_ORIGIN_LONG_GEO_KEY:  // key 3080 GeogAngularUnit
+            if( (tag == GEO_DOUBLE_PARAMS_TAG) &&
+                (code <= (theDoubleParamLength - 1)) )
+            {
+               //---
+               // Grab the value from the theDoubleParam
+               //---
+               theOriginLon = theDoubleParam[code];
+            }
+         
+            break;
+         case PROJ_NAT_ORIGIN_LAT_GEO_KEY:  // key 3081 GeogAngularUnit
+            if( (tag == GEO_DOUBLE_PARAMS_TAG) &&
+                (code <= (theDoubleParamLength - 1)) )
+            {
+               //---
+               // Grab the value from the theDoubleParam
+               //---
+               theOriginLat = theDoubleParam[code];
+            }
+         
+            break;
+
+         case PROJ_FALSE_EASTING_GEO_KEY:  // key 3082 GeogAngularUnit
+            if( (tag == GEO_DOUBLE_PARAMS_TAG) &&
+                (code <= (theDoubleParamLength - 1)) )
+            {
+               //---
+               // Grab the value from the theDoubleParam
+               //---
+               theFalseEasting = theDoubleParam[code];
+            }
+         
+            break;
+
+         case PROJ_FALSE_NORTHING_GEO_KEY:  // key 3083 GeogAngularUnit
+            if( (tag == GEO_DOUBLE_PARAMS_TAG) &&
+                (code <= (theDoubleParamLength - 1)) )
+            {
+               //---
+               // Grab the value from the theDoubleParam
+               //---
+               theFalseNorthing = theDoubleParam[code];
+            }
+         
+            break;
+
+         case PROJ_CENTER_LONG_GEO_KEY:  // key 3088 GeogAngularUnit
+            if( (tag == GEO_DOUBLE_PARAMS_TAG) &&
+                (code <= (theDoubleParamLength - 1)) )
+            {
+               //---
+               // Grab the value from the theDoubleParam
+               //---
+               theCenterLon = theDoubleParam[code];
+            }
+         
+            break;
+
+         case PROJ_CENTER_LAT_GEO_KEY:  // key 3089 GeogAngularUnit
+            if( (tag == GEO_DOUBLE_PARAMS_TAG) &&
+                (code <= (theDoubleParamLength - 1)) )
+            {
+               //---
+               // Grab the value from the theDoubleParam
+               //---
+               theCenterLat = theDoubleParam[code];
+            }
+         
+            break;
+
+         case PROJ_SCALE_AT_NAT_ORIGIN_GEO_KEY:  // key 3092 ratio 
+            if( (tag == GEO_DOUBLE_PARAMS_TAG) &&
+                (code <= (theDoubleParamLength - 1)) )
+            {
+               //---
+               // Grab the value from the theDoubleParam
+               //---
+               theScaleFactor = theDoubleParam[code];
+            }
+         
+            break;
+
+         default:
+         {
+            break;
+            
+         }
+      }
+   }
+
+   str.seekg(pos, ios::beg); // Seek back to next directory entry.
+
+   return true;
+}
+
+bool ossimGeoTiff::addImageGeometry(ossimKeywordlist& kwl,
+                                    const char* prefix) const
+{
+   // Sanity check...
+   if (getTiePoint().size() < 5 || getScale().size() < 2 )
+   {
+      return false;
+   }
+
+   ossimString copyPrefix = prefix;
+
+   //---
+   // Shift the tie point to the (0, 0) position if it's not already.
+   //
+   // Note:
+   // Some geotiff writers like ERDAS IMAGINE set the "GTRasterTypeGeoKey"
+   // key to RasterPixelIsArea, then set the tie point to (0.5, 0.5).
+   // This really means "RasterPixelIsPoint" with a tie point of (0.0, 0.0).
+   // Anyway we will check for this blunder and attempt to do the right
+   // thing...
+   //---
+   double x_tie_point = getTiePoint()[3] - getScale()[0]*getTiePoint()[0];
+   double y_tie_point = getTiePoint()[4] + getScale()[1]*getTiePoint()[1];
+   
+   if (theRasterType == OSSIM_PIXEL_IS_AREA)
+   {
+      //---
+      // Since the internal pixel representation is "point", shift the
+      // tie point to be relative to the center of the pixel.
+      //---
+      x_tie_point += (getScale()[0])/2.0;
+      y_tie_point -= (getScale()[1])/2.0;
+   }
+
+   if(theSavePcsCodeFlag)
+   {
+      kwl.add(prefix,
+              "pcs_code",
+              thePcsCode,
+              true);
+
+      // tie point
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::TIE_POINT_EASTING_KW,
+              convert2meters(x_tie_point));
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::TIE_POINT_NORTHING_KW,
+              convert2meters(y_tie_point));
+
+      // scale or gsd
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+              convert2meters(getScale()[0]));
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+              convert2meters(getScale()[1]));
+      
+      return true;
+   }
+
+   //---
+   // Get the projection type.  If unknown no point going on, so get out.
+   //---
+   if (getOssimProjectionName() == "unknown")
+   {
+      return false;
+   }
+
+   // Add these for all projections.
+   kwl.add(copyPrefix.c_str(),
+           ossimKeywordNames::TYPE_KW,
+           getOssimProjectionName().c_str());
+   
+   kwl.add(copyPrefix.c_str(),
+           ossimKeywordNames::DATUM_KW,
+           getOssimDatumName().c_str());
+
+   //---
+   // Add the tie point and scale.  Convert to either meters or decimal
+   // degrees if needed.
+   //---
+   if (theModelType == MODEL_TYPE_GEOGRAPHIC)
+   {
+      if (!theAngularUnits && traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_WARN)
+            << " WARNING ossimGeoTiff::addImageGeometry:"
+            << "The GeogAngularUnitsGeoKey (key 2054) is not set!"
+            << "\nAssuming \"Angular_Degree\"..." << std::endl;
+      }
+      
+      switch (theAngularUnits)
+      {
+         case ANGULAR_ARC_MINUTE:
+         case ANGULAR_ARC_SECOND:
+         case ANGULAR_GRAD:
+         case ANGULAR_GON:
+         case ANGULAR_DMS:
+         case ANGULAR_DMS_HEMISPHERE:
+         {
+            ossimNotify(ossimNotifyLevel_WARN)
+               << "WARNING ossimGeoTiff::addImageGeometry:"
+               << "\nNot coded yet for unit type:  "
+               << theAngularUnits << endl;
+            return false;
+         }
+         case ANGULAR_DEGREE:
+         default:
+         {
+            kwl.add(copyPrefix.c_str(),
+                    ossimKeywordNames::TIE_POINT_LON_KW,
+                    x_tie_point);
+            kwl.add(copyPrefix.c_str(),
+                    ossimKeywordNames::TIE_POINT_LAT_KW,
+                    y_tie_point);
+            kwl.add(copyPrefix.c_str(),
+                    ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+                    getScale()[0]);
+            kwl.add(copyPrefix.c_str(),
+                    ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+                    getScale()[1]);
+
+            if(theOriginLat == OSSIM_DBL_NAN)
+            {
+               theOriginLat = 0.0;
+            }
+            if(theOriginLon == OSSIM_DBL_NAN)
+            {
+               theOriginLon = 0.0;
+            }
+            double olat = theOriginLat;
+            double olon = theOriginLon;
+            if((theOriginLat == 0.0)&&
+               (theOriginLon == 0.0)&&
+               (getScale()[0] !=
+                getScale()[1] ))
+            {
+               double centerX = theWidth/2.0;
+               double centerY = theLength/2.0;
+               
+               olat = getScale()[1]*centerY + y_tie_point;
+               olon = getScale()[0]*centerX + x_tie_point;
+               
+            }
+            // origin
+            kwl.add(copyPrefix.c_str(),
+                    ossimKeywordNames::ORIGIN_LATITUDE_KW,
+                    olat,
+                    true);
+            
+            kwl.add(copyPrefix.c_str(),
+                    ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+                    olon,
+                    true);
+         }
+      }  // End of switch on theAngularUnits.
+   }
+   else if (theModelType == MODEL_TYPE_PROJECTED)
+   {
+      // tie point
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::TIE_POINT_EASTING_KW,
+              convert2meters(x_tie_point));
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::TIE_POINT_NORTHING_KW,
+              convert2meters(y_tie_point));
+
+      // scale or gsd
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+              convert2meters(getScale()[0]));
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+              convert2meters(getScale()[1]));
+
+      if(theOriginLat != OSSIM_DBL_NAN)
+      {
+         // origin
+         kwl.add(copyPrefix.c_str(),
+                 ossimKeywordNames::ORIGIN_LATITUDE_KW,
+                 theOriginLat);
+      }
+      else if(theCenterLat != OSSIM_DBL_NAN)
+      {
+         // origin
+         kwl.add(copyPrefix.c_str(),
+                 ossimKeywordNames::ORIGIN_LATITUDE_KW,
+                 theCenterLat);
+      }
+
+      if(theOriginLon != OSSIM_DBL_NAN)
+      {
+         kwl.add(copyPrefix.c_str(),
+                 ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+                 theOriginLon);
+      }
+      if(theCenterLon != OSSIM_DBL_NAN)
+      {
+         kwl.add(copyPrefix.c_str(),
+                 ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+                 theCenterLon);
+      }
+
+      // std paralles for conical projections
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::STD_PARALLEL_1_KW,
+              theStdPar1);
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::STD_PARALLEL_2_KW,
+              theStdPar2);
+
+      // false easting and northing.
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::FALSE_EASTING_KW,
+              convert2meters(theFalseEasting));
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::FALSE_NORTHING_KW,
+              convert2meters(theFalseNorthing));
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN)
+         << "WARNING ossimGeoTiff::addImageGeometry:"
+         << " Unsupported model type..." << std::endl;
+      return false;
+   }
+
+   //---
+   // Based on projection type, override/add the appropriate info.
+   //---
+   if (getOssimProjectionName() == "ossimUtmProjection")
+   {
+      // Check the zone before adding...
+      if (theZone > 0 && theZone < 61)
+      {
+         kwl.add(copyPrefix.c_str(),
+                 ossimKeywordNames::ZONE_KW,
+                 theZone);
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATAL ossimGeoTiff::addImageGeometry: "
+            << "UTM zone " << theZone << " out of range!\n"
+            << "Valid range:  1 to 60" << endl;
+         return false;
+      }
+
+      // Check the hemisphere before adding.
+      if (theHemisphere == "N" || theHemisphere == "S")
+      {
+         kwl.add(copyPrefix.c_str(),
+                 ossimKeywordNames::HEMISPHERE_KW,
+                 theHemisphere);
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_FATAL)
+            << "FATAL ossimGeoTiff::addImageGeometry: "
+            << "UTM hemisphere " << theHemisphere << " is invalid!\n"
+            << "Valid hemisphere:  N or S" << std::endl;
+         return false;
+      }
+
+      //---
+      // Must set the central meridian even though the zone should do it.
+      // (in decimal degrees)
+      //---
+      double central_meridian = ( 6.0 * abs(theZone) ) - 183.0;
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::CENTRAL_MERIDIAN_KW,
+              central_meridian,
+              true);  // overwrite keyword if previously added...
+      
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::ORIGIN_LATITUDE_KW,
+              0.0,
+              true);  // overwrite keyword if previously added...
+ 
+   } // End of "if (UTM)"
+
+   else if (getOssimProjectionName() == "ossimUtmProjection")
+   {
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::SCALE_FACTOR_KW,
+              theScaleFactor,
+              true);  // overwrite keyword if previously added...
+   }
+   
+   //---
+   // Get the model transformation info if it's present.
+   //---
+   if (getModelTransformation().size() == 16)
+   {
+      vector<double> v = getModelTransformation();
+      kwl.add(copyPrefix.c_str(),
+              "m11",
+              v[0], 
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m12",
+              v[1],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m13",
+              v[2],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m14",
+              v[3],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m21",
+              v[4],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m22",
+              v[5],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m23",
+              v[6],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m24",
+              v[7],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m31",
+              v[8],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m32",
+              v[9],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m33",
+              v[10],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m34",
+              v[11],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m41",
+              v[12],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m42",
+              v[13],
+              true);
+      kwl.add(copyPrefix.c_str(),
+              "m43",
+              v[14]);
+      kwl.add(copyPrefix.c_str(),
+              "m44",
+              v[15],
+              true);
+   } // End of "if (gt.getModelTransformation().size() == 16)"
+
+   if(theScaleFactor > 0.0)
+   {
+      kwl.add(copyPrefix.c_str(),
+              ossimKeywordNames::SCALE_FACTOR_KW,
+              theScaleFactor,
+              true);
+   }      
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::addImageGeometry: Keyword list dump:\n"
+         << kwl << std::endl;
+   }
+   
+   return true;
+}
+
+double ossimGeoTiff::convert2meters(double d) const
+{
+   switch(theLinearUnitsCode)
+   {
+   case LINEAR_METER:
+      return d;
+   case LINEAR_FOOT:
+      return ft2mtrs(d);
+   case LINEAR_FOOT_US_SURVEY:
+      return usft2mtrs(d);
+   default:
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimGeoTiff::convert2meters: " 
+            << "Linear units code was undefined!\n"
+            << "No conversion was performed." << std::endl;
+      }
+      break;
+   }
+   
+   return d;
+}
+
+ossimString ossimGeoTiff::getOssimProjectionName() const
+{
+   return theProjectionName;
+}
+
+void ossimGeoTiff::setOssimProjectionName()
+{
+   //---
+   // The "parsePcsCode" method can also set the projection name.  So check
+   // it prior to looking in the lookup table.
+   //---
+   if (theProjectionName == "unknown")
+   {
+      ossimString name =  COORD_TRANS_LUT.getEntryString(theCoorTransGeoCode);
+      
+      if (name.size())
+      {
+         theProjectionName = name;
+      }
+   }
+
+   // If still unknown check for the model type.
+   if (theProjectionName == "unknown")
+   {
+      if (theModelType == MODEL_TYPE_GEOGRAPHIC)
+      {
+         theProjectionName = "ossimEquDistCylProjection";
+      }
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::setOssimProjectionName: "
+         << "theProjectionName:  "
+         << theProjectionName
+         << std::endl;
+   }
+}
+
+ossimString ossimGeoTiff::getOssimDatumName() const
+{
+   return theDatumName;
+}
+
+void ossimGeoTiff::setOssimDatumName()
+{
+   //---
+   // The "parsePcsCode" method can also set the datum name.  So check
+   // it prior to trying to assign.
+   //---
+   if (theDatumName == "unknown")
+   {
+      ossimString name = DATUM_LUT.getEntryString(theDatumCode);
+      
+      if (name.size())
+      {
+         theDatumName = name;
+      }
+      else
+      {
+         // Try the GCS code.
+         name = DATUM_LUT.getEntryString(theGcsCode);
+         if (name.size())
+         {
+            theDatumName = name;
+         }
+      }
+   }
+   
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::setOssimDatumName: "
+         << "theDatumName:  "
+         << theDatumName
+         << std::endl;
+   } 
+}
+
+void ossimGeoTiff::parsePcsCode(int code)
+{
+   // key 3072 Section 6.3.3.1 codes
+   
+   if (code == USER_DEFINED)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimGeoTiff::parsePcsCode: "
+            << "Projection coordinate system is user defined."
+            << std::endl;
+      }
+      return;
+   }
+
+   if(code == PCS_BRITISH_NATIONAL_GRID)
+   {
+      theProjectionName = "ossimBngProjection";
+      theDatumName = "OGB-M";
+      theFalseEasting = 400000.0;
+      theFalseNorthing = -100000.0;
+      theScaleFactor   = .9996012717;
+      theOriginLat     = 49.0;
+      theOriginLon     = -2.0;
+      theHemisphere    = "N";
+      return;
+   }
+
+   //---
+   // Divide the code by 100. Then check for a known type.  If it is a
+   // utm projection the last two digits represent the zone.
+   //---
+   int type = code/100;
+   int zone = code%100;
+
+   switch (type)
+   {
+      case 322:
+         //---
+         // utm, WGS72 (WGD), northern hemisphere
+         // All 60 zones handled.
+         //---
+         theProjectionName = "ossimUtmProjection";
+         theZone           = zone;
+         theHemisphere     = "N";
+         theDatumName      = "WGD";
+         break;
+         
+      case 323:
+         //---
+         // utm, WGS72 (WGD), southern hemisphere
+         // All 60 zones handled.
+         //---
+         theProjectionName = "ossimUtmProjection";
+         theZone           = zone;
+         theHemisphere     = "S";
+         theDatumName      = "WGD";
+         break;
+         
+      case 326:
+         //---
+         // utm, WGS84 (WGE), northern hemisphere
+         // All 60 zones hadled.
+         //---
+         theProjectionName = "ossimUtmProjection";
+         theZone           = zone;
+         theHemisphere     = "N";
+         theDatumName      = "WGE";
+         break;
+         
+      case 327:
+         //---
+         // utm, WGS84 (WGE), southern hemisphere
+         // All 60 zones handled.
+         //---
+         theProjectionName = "ossimUtmProjection";
+         theZone           = zone;
+         theHemisphere     = "S";
+         theDatumName      = "WGE";
+         break;
+         
+      case 267:
+         //---
+         // utm, "NAS-C", northern hemisphere
+         // Only UTM NAD27 North zones 3 to 22 are in the 267xx range...
+         // 26729 through 26803 handled by state plane factory.
+         //---
+         if ( (code > 26702) && (code < 26723) )
+         {
+            theProjectionName = "ossimUtmProjection";
+            theZone           = zone;
+            theHemisphere     = "N";
+            theDatumName      = "NAS-C";
+         }
+         break;
+         
+      case 269: // utm, "NAR-C", northern hemisphere
+         //---
+         // Only UTM NAD83 North zones 3 to 23 are in the 269xx range...
+         // 26929 through 26998 handled by state plane factory.
+         //---
+         if ( (code > 26902) && (code < 26924) )
+         {
+            theProjectionName = "ossimUtmProjection";
+            theZone           = zone;
+            theHemisphere     = "N";
+            theDatumName      = "NAR-C";
+         }
+         break;
+         
+      case 248:
+         //---
+         // Provisional S. American 1956
+         // 24818 through 24880
+         //---
+         if ( (code > 24817) && (code < 24881) )
+         {
+            theProjectionName = "ossimUtmProjection";
+            if (zone > 60)
+            {
+               theZone = (zone - 60);
+               theHemisphere     = "S";
+            }
+            else
+            {
+               theZone = zone;
+               theHemisphere     = "N";
+            }
+            theDatumName = "PRP-M";
+         }
+         break;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::parsePcsCode:"
+         << "\nprojection type:  " << theProjectionName
+         << "\nzone number:      " << theZone
+         << "\nhemisphere:       " << theHemisphere
+         << "\ndatum:            " << theDatumName
+         << std::endl;
+   }
+
+   //---
+   // Check for codes that the ossimStatePlaneProjectionFactory can create a
+   // projection from. This probably should be moved to a method in 
+   // ossimStatePlaneProjectionFactory.
+   //---
+   if(((code >= 26929) && (code <= 26998)) ||
+      ((code >= 32100) && (code <= 32158)) ||
+      ((code >= 32001) && (code <= 32060)) ||
+      ((code >= 26729) && (code <= 26803)) ||
+      (code == 32161)
+      )
+   {
+      theSavePcsCodeFlag = true;
+   }
+
+   if ( (theSavePcsCodeFlag == true) &&
+        (theProjectionName == "ossimUtmProjection") )
+   {
+      //---
+      // Setting theSavePcsCodeFlag to true causes the getImageGeometry to
+      // return just the pcs code and the tie point.  Since the
+      // ossimStatePlaneProjectionFactory is used to return a projection
+      // from the pcs code and it does NOT handle utm, set the 
+      // theSavePcsCodeFlag back to false to avoid this.
+      //---
+      theSavePcsCodeFlag = false;
+   }
+}
+
+void ossimGeoTiff::parseProjGeoCode(int code)
+{
+   //---
+   // Currently only handles UTM 160xx and 161xx.
+   // Note: No datum with this!
+   //---
+   
+   if (code == USER_DEFINED)
+   {
+      if (traceDebug())
+      {
+         ossimNotify(ossimNotifyLevel_DEBUG)
+            << "DEBUG ossimGeoTiff::parseProjGeoCode: "
+            << "Projection Geo Key is user defined."
+            << std::endl;
+      }
+      return;
+   }
+
+   //---
+   // Divide the code by 100. Then check for a known type.  If it is a
+   // utm projection the last two digits represent the zone.
+   //---
+   int type = code/100;
+   int zone = code%100;
+
+   switch (type)
+   {
+      case 160: // utm, northern hemisphere
+         theProjectionName = "ossimUtmProjection";
+         theZone           = zone;
+         theHemisphere     = "N";
+         break;
+         
+      case 161: // utm, "WGD", southern hemisphere
+         theProjectionName = "ossimUtmProjection";
+         theZone           = zone;
+         theHemisphere     = "S";
+         break;
+
+      default:
+         break;
+   }
+
+   if (traceDebug())
+   {
+      ossimNotify(ossimNotifyLevel_DEBUG)
+         << "DEBUG ossimGeoTiff::parseProjGeoCode:"
+         << "\nprojection type:  " << theProjectionName
+         << "\nzone number:      " << theZone
+         << "\nhemisphere:       " << theHemisphere
+         << std::endl;
+   }
+}
+
+int ossimGeoTiff::mapZone() const
+{
+   return theZone;
+}
+
+ossimByteOrder ossimGeoTiff::getByteOrder() const
+{
+   return theTiffByteOrder;
+}
+
+void ossimGeoTiff::getScale(vector<double>& scale) const
+{
+   scale = theScale;
+}
+
+void ossimGeoTiff::getTiePoint(vector<double>& tie_point) const
+{
+   tie_point = theTiePoint;
+}
+
+void ossimGeoTiff::getModelTransformation(vector<double>& transform) const
+{
+   transform = theModelTransformation;
+}
+
+const vector<double>& ossimGeoTiff::getScale() const
+{
+   return theScale;
+}
+
+const vector<double>& ossimGeoTiff::getTiePoint() const
+{
+   return theTiePoint;
+}
+
+const vector<double>& ossimGeoTiff::getModelTransformation() const
+{
+   return theModelTransformation;
+}
+
+int ossimGeoTiff::getWidth() const
+{
+   return theWidth;
+}
+
+int ossimGeoTiff::getLength() const
+{
+   return theLength;
+}
+
+int ossimGeoTiff::getSamplesPerPixel() const
+{
+   return theSamplesPerPixel;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/tiff/ossimGeoTiff.h b/Utilities/OSSIM/ossim_core/support_data/tiff/ossimGeoTiff.h
new file mode 100644
index 0000000000..bacae76f9b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/tiff/ossimGeoTiff.h
@@ -0,0 +1,272 @@
+//***************************************************************************
+// FILE: ossimGeoTiff.h
+//
+// Copyright (C) 2001 ImageLinks, Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+// Class definition for ossimGeoTiff which is designed to read and hold tag
+// information.
+//
+//***************************************************************************
+// $Id: ossimGeoTiff.h,v 1.12 2005/09/01 14:34:02 gpotts Exp $
+
+#ifndef ossimGeoTiff_HEADER
+#define ossimGeoTiff_HEADER
+
+#include <stdio.h>
+#include <vector>
+using namespace std;
+
+#include "base/common/ossimErrorStatusInterface.h"
+#include "base/misc/ossimEndian.h"
+#include "base/data_types/ossimString.h"
+
+class ossimFilename;
+class ossimKeywordlist;
+
+
+class ossimGeoTiff : public ossimErrorStatusInterface
+{
+public:
+   ossimGeoTiff(const ossimFilename& file);
+   ~ossimGeoTiff();
+  
+   enum
+   {
+      UNDEFINED                        = 0,
+      PIXEL_IS_AREA                    = 1,
+      PIXEL_IS_POINT                   = 2,
+      GT_MODEL_TYPE_GEO_KEY            = 1024,
+      GT_RASTER_TYPE_GEO_KEY           = 1025,
+      GEOGRAPHIC_TYPE_GEO_KEY          = 2048,
+      GEOG_GEODETIC_DATUM_GEO_KEY      = 2050,
+      GEOG_ANGULAR_UNITS_GEO_KEY       = 2054,
+      PROJECTED_CS_TYPE_GEO_KEY        = 3072,
+      PCS_CITATION_GEO_KEY             = 3073,
+      PROJECTION_GEO_KEY               = 3074,
+      PROJ_COORD_TRANS_GEO_KEY         = 3075,
+      LINEAR_UNITS_GEO_KEY             = 3076,
+      PROJ_STD_PARALLEL1_GEO_KEY       = 3078,
+      PROJ_STD_PARALLEL2_GEO_KEY       = 3079,
+      PROJ_NAT_ORIGIN_LONG_GEO_KEY     = 3080,
+      PROJ_NAT_ORIGIN_LAT_GEO_KEY      = 3081,
+      PROJ_FALSE_EASTING_GEO_KEY       = 3082,
+      PROJ_FALSE_NORTHING_GEO_KEY      = 3083,
+      PROJ_CENTER_LONG_GEO_KEY         = 3088,
+      PROJ_CENTER_LAT_GEO_KEY          = 3089,
+      PROJ_SCALE_AT_NAT_ORIGIN_GEO_KEY = 3092,
+      LINEAR_METER                     = 9001,
+      LINEAR_FOOT                      = 9002,
+      LINEAR_FOOT_US_SURVEY            = 9003,
+      ANGULAR_DEGREE                   = 9102,
+      ANGULAR_ARC_MINUTE               = 9103,
+      ANGULAR_ARC_SECOND               = 9104,
+      ANGULAR_GRAD                     = 9105,
+      ANGULAR_GON                      = 9106,
+      ANGULAR_DMS                      = 9107,
+      ANGULAR_DMS_HEMISPHERE           = 9108,
+      PCS_BRITISH_NATIONAL_GRID        = 27700,
+      USER_DEFINED                     = 32767,
+      MODEL_PIXEL_SCALE_TAG            = 33550,
+      MODEL_TIE_POINT_TAG              = 33922,
+      MODEL_TRANSFORM_TAG              = 34264,
+      GEO_KEY_DIRECTORY_TAG            = 34735,
+      GEO_DOUBLE_PARAMS_TAG            = 34736,
+      GEO_ASCII_PARAMS_TAG             = 34737,
+   };
+
+   enum CompressType
+   {
+      NOT_COMPRESSED = 0,
+      COMPRESSED     = 1
+   };
+ 
+   enum PhotoInterpretation
+   {
+      PHOTO_MINISWHITE  = 0,   // min value is white 
+      PHOTO_MINISBLACK  = 1,   // min value is black 
+      PHOTO_RGB         = 2,   // RGB color model 
+      PHOTO_PALETTE     = 3,   // color map indexed 
+      PHOTO_MASK        = 4,   // $holdout mask 
+      PHOTO_SEPARATED   = 5,   // !color separations 
+      PHOTO_YCBCR       = 6,   // !CCIR 601 
+      PHOTO_CIELAB      = 8    // !1976 CIE L*a*b*
+   };
+
+   enum ModelType
+   {
+      UNKNOWN               = 0,
+      MODEL_TYPE_PROJECTED  = 1,  // Projection Coordinate System
+      MODEL_TYPE_GEOGRAPHIC = 2,  // Geographic latitude-longitude System 
+      MODEL_TYPE_GEOCENTRIC = 3
+   };
+
+
+   /**
+    *  Reads tags.
+    *  Returns true on success, false on error.
+    */
+   bool readTags(const ossimFilename& file);
+
+   /**
+    *  Returns the map zone as an interger.
+    */
+   int mapZone() const;
+
+   /**
+    *  Add geometry info from tags to keword list.
+    *  Returns true on success, false on error.
+    */
+   bool addImageGeometry(ossimKeywordlist& kwl,
+                         const char* prefix=0) const;
+
+   /**
+    *  Returns an ossimString representing the ossim projection name.
+    *  Returns "unknown" if it can't find a match.
+    */
+   ossimString getOssimProjectionName() const;
+
+   /**
+    *  Attempts to set the ossim projection name from keys read.
+    */
+   void setOssimProjectionName();
+
+   /**
+    *  Returns an ossimString representing the ossim datum name code.
+    *  Returns "unknown" if it can't find a match.
+    */
+   ossimString getOssimDatumName() const;
+
+   /**
+    *  Attempts to set the ossim datum code.
+    */
+   void setOssimDatumName();
+
+   /**
+    * Returns enumerated byte order of the tiff file.
+    * Either OSSIM_LITTLE_ENDIAN or OSSIM_BIG_ENDIAN.
+    * See ossimConstants.h
+    */
+   ossimByteOrder getByteOrder() const;
+
+   void getScale(vector<double>& scale) const;
+   void getTiePoint(vector<double>& tie_point) const;
+   void getModelTransformation(vector<double>& transform) const;
+
+   const vector<double>& getTiePoint() const;
+   const vector<double>& getModelTransformation() const;
+   const vector<double>& getScale() const;
+
+   int getWidth() const;
+   int getLength() const;
+   int getSamplesPerPixel() const;
+   
+private:
+
+   // Disallow ...
+   ossimGeoTiff(const ossimGeoTiff* rhs) {}
+   ossimGeoTiff& operator=(const ossimGeoTiff& rhs) { return *this; }
+   
+   /**
+    *  Reads geo keys.
+    *  Returns true on success, false on error.
+    */
+   bool readGeoKeys(ifstream& str, std::streampos offset, int length);
+
+   /**
+    *  Initializes s reference.  Does byte swapping as needed.
+    */
+   void readShort(ossim_uint16& s, ifstream& str);
+   
+   /**
+    *  Initializes l reference.  Does byte swapping as needed.
+    */
+   void readLong(ossim_int32& l, ifstream& str);   
+   
+
+   /**
+    *  Initializes l reference.  Does byte swapping as needed.
+    */
+   void readLong(ossim_uint32& l, ifstream& str);
+      
+   /**
+    *  Initializes l reference.  Does byte swapping as needed.
+    */
+   void readDouble(ossim_float64& d, ifstream& str);   
+
+   /**
+    *  Attempts to parse the pcs code (3072).
+    */
+   void parsePcsCode(int code);
+
+   /**
+    *  Attempts to parse the projection geo key (3074).
+    */
+   void parseProjGeoCode(int code);
+
+   /**
+    *  Converts double passed in to meters if needed.  The conversion is
+    *  base on "theLiniarUnitsCode".
+    */
+   double convert2meters(double d) const;
+      
+   ossim_uint32          theGeoKeyOffset;
+   int                   theGeoKeyLength;
+   ossimByteOrder        theTiffByteOrder;
+   ossimEndian           theEndian;
+   bool                  theGeoKeysPresentFlag;
+   int                   theZone;
+   ossimString           theHemisphere;
+   int                   theDoubleParamLength;
+   int                   theAsciiParamLength;
+   ossimString           theProjectionName;
+   ossimString           theDatumName;
+   
+   vector<double>        theScale;                         // tag 33550
+   vector<double>        theTiePoint;                      // tag 33922
+   vector<double>        theModelTransformation;           // tag 34264
+   double*               theDoubleParam;                   // tag 34736
+   char*                 theAsciiParam;                    // tag 34737
+   
+   int                   theWidth;                         // tag 256
+   int                   theLength;                        // tag 257
+   vector<ossim_uint16>  theBitsPerSample;                 // tag 258
+   CompressType          theCompresionType;                // tag 259
+   PhotoInterpretation   thePhotoInterpretation;           // tag 262
+   ossimString           theImageDescriptionString;        // tag 270
+   int                   theSamplesPerPixel;               // tag 277
+   int                   thePlanarConfig;                  // tag 284
+   ossimString           theSoftwareDescriptionString;     // tag 305
+   ossimString           theDateDescriptionString;         // tag 306
+   int                   theTileWidth;                     // tag 322
+   int                   theTileLength;                    // tag 323
+
+   ModelType             theModelType;                     // key 1024
+   int                   theRasterType;                    // key 1025
+   int                   theGcsCode;                       // key 2048
+   int                   theDatumCode;                     // key 2050
+   int                   theAngularUnits;                  // key 2054
+   int                   thePcsCode;                       // key 3072
+   bool                  theSavePcsCodeFlag;
+   ossimString           thePcsCitation;                   // key 3073
+   int                   theProjGeoCode;                   // key 3074
+   int                   theCoorTransGeoCode;              // key 3075
+   int                   theLinearUnitsCode;               // key 3076
+   double                theStdPar1;                       // key 3078 
+   double                theStdPar2;                       // key 3079
+   mutable double        theOriginLon;                     // key 3080
+   mutable double        theOriginLat;                     // key 3081
+   double                theFalseEasting;                  // key 3082
+   double                theFalseNorthing;                 // key 3083
+   mutable double        theCenterLon;                     // key 3088
+   mutable double        theCenterLat;                     // key 3099
+   double                theScaleFactor;                   // key 3092
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/tiff/ossimTiffWorld.cpp b/Utilities/OSSIM/ossim_core/support_data/tiff/ossimTiffWorld.cpp
new file mode 100644
index 0000000000..fdb3437917
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/tiff/ossimTiffWorld.cpp
@@ -0,0 +1,200 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description: Container class for a tiff world file data.
+//
+//********************************************************************
+// $Id: ossimTiffWorld.cpp,v 1.7 2004/12/20 11:44:54 dburken Exp $
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+using namespace std;
+
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimKeywordNames.h>
+#include <base/misc/ossimUnitConversionTool.h>
+#include <support_data/tiff/ossimTiffWorld.h>
+
+//**************************************************************************
+// ossimTiffWorld::ossimTiffWorld()
+//***************************************************************************
+ossimTiffWorld::ossimTiffWorld()
+   :
+      theXScale(1.0),
+      the2ndValue(0.0),
+      the3rdValue(0.0),
+      theYScale(1.0),
+      theTranslateX(0.0),
+      theTranslateY(0.0),
+      thePixelType(OSSIM_PIXEL_IS_AREA),
+      theUnit(OSSIM_METERS)
+{}
+
+//**************************************************************************
+// ossimTiffWorld::ossimTiffWorld(const char* file, PixelType ptype)
+//***************************************************************************
+ossimTiffWorld::ossimTiffWorld(const char* file, 
+			       ossimPixelType ptype,
+			       ossimUnitType  scaleUnits)
+   :
+      theXScale(1.0),
+      the2ndValue(0.0),
+      the3rdValue(0.0),
+      theYScale(-1.0),
+      theTranslateX(0.0),
+      theTranslateY(0.0),
+      thePixelType(ptype),
+      theUnit(scaleUnits)
+{
+   ifstream is;
+   is.open(file);
+
+   if(!is)
+   {
+      return;
+   }
+
+   is >> theXScale
+      >> the2ndValue
+      >> the3rdValue
+      >> theYScale
+      >> theTranslateX
+      >> theTranslateY;
+
+   is.close();
+}
+
+ossimTiffWorld::~ossimTiffWorld()
+{
+}
+
+void ossimTiffWorld::forward(const ossimDpt& imagePoint,
+                             ossimDpt& transformedPoint)
+{
+   transformedPoint.x =
+      imagePoint.x*theXScale   + imagePoint.y*the3rdValue + theTranslateX;
+   transformedPoint.y =
+      imagePoint.x*the2ndValue + imagePoint.y*theYScale   + theTranslateY;
+}
+
+
+bool ossimTiffWorld::saveToOssimGeom(ossimKeywordlist& kwl, 
+				     const char* prefix)const
+{
+   double xScale = fabs(theXScale);
+   double yScale = fabs(theYScale);
+   double transX = theTranslateX;
+   double transY = theTranslateY;
+
+   if ( (theUnit == OSSIM_FEET) || (theUnit == OSSIM_US_SURVEY_FEET) )
+   {
+      // Convert to meters.
+      xScale = ossimUnitConversionTool(xScale, theUnit).getMeters();
+      yScale = ossimUnitConversionTool(yScale, theUnit).getMeters();
+      transX = ossimUnitConversionTool(transX, theUnit).getMeters();
+      transY = ossimUnitConversionTool(transY, theUnit).getMeters();
+   }
+   
+   // Shift the tie point to be relative to the center of the pixel.
+   if(thePixelType == OSSIM_PIXEL_IS_AREA)
+   {
+      transX += (xScale/2.0);
+      transY -= (yScale/2.0);
+
+      // Adjust the keyword list to reflect pixel is point.
+      kwl.add(prefix,
+              ossimKeywordNames::PIXEL_TYPE_KW,
+              "pixel_is_point",
+              true);
+   }
+   
+   if(theUnit == OSSIM_DEGREES)
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LON_KW,
+              transX,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LAT_KW,
+              transY,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+              xScale,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+              yScale,
+              true);
+   }
+   else
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_EASTING_KW,
+              transX,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_NORTHING_KW,
+              transY,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+              xScale,
+              true);
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+              yScale,
+              true);
+   }
+   
+   return true;
+}
+
+bool ossimTiffWorld::loadFromOssimGeom(const ossimKeywordlist& kwl, 
+				       const char* prefix)
+{
+   the2ndValue = 0.0;
+   the3rdValue = 0.0;
+   
+   ossimString xscale   =
+      kwl.find(prefix, ossimKeywordNames::METERS_PER_PIXEL_X_KW);
+   ossimString yscale   =
+      kwl.find(prefix, ossimKeywordNames::METERS_PER_PIXEL_Y_KW);
+   ossimString easting  =
+      kwl.find(prefix, ossimKeywordNames::TIE_POINT_EASTING_KW);
+   ossimString northing =
+      kwl.find(prefix, ossimKeywordNames::TIE_POINT_NORTHING_KW);
+   
+   theXScale      = xscale.toDouble();
+   theYScale      = -(yscale.toDouble());
+   theTranslateX  = easting.toDouble();
+   theTranslateY  = northing.toDouble();
+   
+   return true;
+}
+
+std::ostream& ossimTiffWorld::print(std::ostream& out) const
+{
+   out << setiosflags(ios::fixed) << setprecision(15)
+       << theXScale     << "\n"
+       << the2ndValue   << "\n"
+       << the3rdValue   << "\n"
+       << theYScale     << "\n"
+       << theTranslateX << "\n"
+       << theTranslateY
+       << endl;
+   return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const ossimTiffWorld& obj)
+{
+   return obj.print(out);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/tiff/ossimTiffWorld.h b/Utilities/OSSIM/ossim_core/support_data/tiff/ossimTiffWorld.h
new file mode 100644
index 0000000000..51f8655aa9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/tiff/ossimTiffWorld.h
@@ -0,0 +1,66 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+// 
+// Description: Container class for a tiff world file data.
+//
+//********************************************************************
+// $Id: ossimTiffWorld.h,v 1.4 2004/12/20 00:14:04 dburken Exp $
+#ifndef ossimTiffWorld_HEADER
+#define ossimTiffWorld_HEADER
+
+#include <iostream>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/data_types/ossimDpt.h>
+using namespace std;
+
+//***************************************************************************
+// CLASS:  ossimTiffWorld
+//***************************************************************************
+class OSSIMDLLEXPORT ossimTiffWorld
+{
+public:
+   ossimTiffWorld();
+   ossimTiffWorld(const char* source, 
+		  ossimPixelType ptype = OSSIM_PIXEL_IS_POINT,
+		  ossimUnitType  unit = OSSIM_METERS);
+   
+   ~ossimTiffWorld();
+
+  bool saveToOssimGeom(ossimKeywordlist& kwl, const char* prefix=NULL)const;
+  bool loadFromOssimGeom(const ossimKeywordlist& kwl, const char* prefix=NULL);
+
+  std::ostream& print(std::ostream& out) const;
+
+  friend OSSIMDLLEXPORT std::ostream& operator<<(std::ostream& out,
+                                                 const ossimTiffWorld& obj);
+
+   /*!
+    * transformed.x =
+    * imagePoint.x*theX_scale + imagePoint.y*the3rdValue + theTranslateX
+    * 
+    * transformed.y =
+    * imagePoint.x*the2ndValue + imagePoint.y*theY_scale + theTranslateY
+    */
+   void forward(const ossimDpt& imagePoint,
+                ossimDpt& transformedPoint);
+   
+   double theXScale;     // xscale
+   double the2ndValue;   // rotation term
+   double the3rdValue;   // rotaion term
+   double theYScale;     // yscale
+   double theTranslateX; // 
+   double theTranslateY; //
+
+protected:
+   ossimPixelType thePixelType;
+   ossimUnitType  theUnit;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/.cvsignore b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/.cvsignore
new file mode 100644
index 0000000000..6885d9a115
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.d
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemGrid.cpp b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemGrid.cpp
new file mode 100644
index 0000000000..fdeb8c9c8d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemGrid.cpp
@@ -0,0 +1,235 @@
+//*******************************************************************
+//
+// License:  See top level LICENSE.txt file.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class defines a DEM grid.
+//
+//********************************************************************
+// $Id: ossimDemGrid.cpp,v 1.7 2005/12/20 21:29:05 dburken Exp $
+
+#include <support_data/usgs_dem/ossimDemGrid.h>
+#include <support_data/usgs_dem/ossimDemPoint.h>
+#include <support_data/usgs_dem/ossimDemUtil.h>
+#include <base/context/ossimNotifyContext.h>
+
+ossimDemGrid::ossimDemGrid(ossim_float32 missingDataValue)
+   : _missDataVal(missingDataValue),
+     _width(0),
+     _height(0),
+     _grid(0),
+     _firstTime(true),
+     _curProfile(0)
+{        
+}
+
+ossimDemGrid::~ossimDemGrid()
+{
+   if(_grid) delete [] _grid; _grid =0;
+}
+
+long
+ossimDemGrid::read(std::istream& dem, bool incrementalRead)
+{
+   if (_firstTime)
+   {
+      dem >> _header;
+   }
+
+   long retval;
+   if (_header.getGroundRefSysCode() == 0)  // Geographic
+      retval = fillGeographic(dem,incrementalRead);
+   else
+      retval = fillUTM(dem,incrementalRead);   // This may not work if it's 
+                                               // really in State Plane.
+
+   if (_firstTime)
+      _firstTime = false;
+
+   return retval;
+}
+
+ossimDemHeader const&
+ossimDemGrid::getHeader() const
+{
+   return _header;
+}
+
+long
+ossimDemGrid::getWidth() const
+{
+   return _width;
+}
+
+long
+ossimDemGrid::getHeight() const
+{
+   return _height;
+}
+
+ossim_float32 ossimDemGrid::getElevation(long x, long y) const
+{
+   if (_grid == 0)
+      return _missDataVal;
+
+   if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
+      return _missDataVal;
+
+   return _grid[(y * _width) + x];
+}
+
+ossim_float32 ossimDemGrid::getMissingDataValue() const
+{
+   return _missDataVal;
+}
+
+long ossimDemGrid::fillGeographic(std::istream& dem,bool incrementalRead)
+{
+   if (_firstTime) {
+      _curProfile = 0;
+      _width = _header.getProfileColumns();
+   }
+
+   while (_curProfile < _width)
+   {
+      _profiles.push_back(ossimDemProfile());
+      dem >> _profiles.back();
+      _curProfile++;
+      if (incrementalRead)
+         return _width - _curProfile + 1;
+   }
+
+   // Assume all profiles have as many elevations as the first.
+   _height = _profiles[0].getNumberOfElevations();
+   if(_grid) delete [] _grid; _grid =0;
+   _grid = new ossim_float32[_width * _height];
+
+   ossimDemPoint sw_corner = _profiles[0].getProfileLocation();
+   _northwest_x = sw_corner.getX();
+   _northwest_y = sw_corner.getY() 
+                  + ((_profiles[0].getNumberOfElevations() - 1) * _header.getSpatialResY());
+
+
+   unsigned int i,j;
+   for (i = 0; (int)i < _width; i++)
+   {
+      ossimDemElevationVector const& elev = _profiles[i].getElevations();
+      for (j = 0; j < elev.size(); j++)
+      {
+         setElevation(i, _height - j - 1, elev[j]);
+      }
+   }
+
+   _profiles.erase(_profiles.begin(), _profiles.end());
+
+   return 0;
+}
+
+long
+ossimDemGrid::fillUTM(std::istream& dem, bool incrementalRead)
+{
+   // 7.5 UTM DEMs are small enough we can get away with doing this stupid...
+
+   unsigned int i;
+   unsigned int x,y;
+
+   if (_firstTime)
+   {
+      _curProfile = 0;
+      _width = _header.getProfileColumns();
+   }
+
+
+   while (_curProfile < _width)
+   {
+      _profiles.push_back(ossimDemProfile());
+      dem >> _profiles.back();
+      _curProfile++;
+      if (incrementalRead)
+         return _width - _curProfile + 1;
+   }
+
+   double dy = _header.getSpatialResY();
+
+   // Determine min and max Y values.
+   // Some DEMs can have profiles which do not have any
+   // elevations, and erroneous (x,y) values. I suspect
+   // these are probably illegal DEMs, but we'll try to
+   // do the right thing anyway.
+   ossimDemPoint curpoint;
+   i = 0;
+   while ((_profiles[i].getNumberOfElevations() == 0) &&
+          (i < _profiles.size()))
+      i++;
+   if (i < _profiles.size())
+      curpoint = _profiles[i].getProfileLocation();
+   else
+   {
+      // XXX This isn't the best way to handle this...
+      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimDemGrid::fillUTM: Yikes! All profiles have zero elevations!\n";
+      return(1);
+   }
+ 
+   double miny, maxy;
+   miny = curpoint.getY();
+   maxy = miny;
+   double profymin, profymax;  // Min and max y values for current profile.
+   for (i = 0; i < _profiles.size(); i++)
+   {
+      if (_profiles[i].getNumberOfElevations() > 0)
+      {
+         curpoint = _profiles[i].getProfileLocation();
+         profymin = curpoint.getY();
+         profymax = profymin + ((_profiles[i].getNumberOfElevations() - 1) * dy);
+
+         if (profymin < miny)
+            miny = profymin;
+         if (profymax > maxy)
+            maxy = profymax;
+      }
+   }
+
+   // We now have minimum and maximum y values over all profiles in the DEM.
+   // Allocate a rectangular array large enough to hold them.
+
+   _height = static_cast<long>(((maxy - miny) / dy) + 1);
+   if(_grid) delete [] _grid; _grid =0;
+   _grid = new ossim_float32[_width * _height];
+
+   // Fill grid with the "missing data" value.
+   for (i = 0; (int)i < _width * _height; i++)
+      _grid[i] = _missDataVal;
+
+   ossimDemPoint sw_corner = _profiles[0].getProfileLocation();
+   _northwest_x = sw_corner.getX();
+   _northwest_y = maxy;
+
+
+   // Now, insert the elevations in the profiles in the appropriate place in the grid.
+
+   long startpos;
+   for (x = 0; (int)x < _width; x++)
+   {
+      ossimDemElevationVector const& elev = _profiles[x].getElevations();
+      curpoint = _profiles[x].getProfileLocation();
+      startpos = static_cast<long>((curpoint.getY() - miny) / dy);
+      for (y = 0; y < elev.size(); y++)
+      {
+         setElevation(x, _height - startpos - y - 1, elev[y]);
+      }
+   }
+
+   _profiles.erase(_profiles.begin(), _profiles.end());
+
+   return 0;
+}
+
+void
+ossimDemGrid::getGroundCoords(long x, long y, double& ground_x,
+                              double& ground_y)
+{
+   ground_x = _northwest_x + (x * _header.getSpatialResX());
+   ground_y = _northwest_y - (y * _header.getSpatialResY());
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemGrid.h b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemGrid.h
new file mode 100644
index 0000000000..a8978c3b46
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemGrid.h
@@ -0,0 +1,110 @@
+//*******************************************************************
+//
+// License:  See top level LICENSE.txt.
+//
+// Author: Ken Melero
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class defines a DEM grid.
+//
+//********************************************************************
+// $Id: ossimDemGrid.h,v 1.7 2005/12/20 21:29:05 dburken Exp $
+
+#ifndef ossimDemGrid_HEADER
+#define ossimDemGrid_HEADER
+
+#include <iostream>
+#include <vector>
+
+#include <base/common/ossimConstants.h>
+#include <support_data/usgs_dem/ossimDemHeader.h>
+#include <support_data/usgs_dem/ossimDemProfile.h>
+
+/*!
+ *  class ossimDemGrid
+ *  This class uses the DEM library to read a DEM and construct a rectangular
+ *  grid of signed 16 bit point values.
+ */
+class ossimDemGrid
+{
+public:
+
+   /*!
+    *  Missing or void data is replaced with missingDataValue.
+    */
+   ossimDemGrid(ossim_float32 missingDataValue = -32767.0);
+
+   ~ossimDemGrid();
+
+   /*!
+    *  Convertes a DEM to a rectangular grid.
+    *
+    *  If incrementalRead is false, the entire DEM will be converted
+    *  with just one call to read. 0 (zero) is returned if successful, -1
+    *  if error.
+    *
+    *  If incrementalRead is true, multiple calls to read are
+    *  required, and the return value is as follows:
+    *     >0  --  Number of calls remaining until conversion is complete.
+    *    ==0  --  Conversion was successful. No more calls to read required.
+    *     -1  --  Error during conversion.
+    */
+   long read(std::istream& dem, bool incrementalRead = false);
+
+   // Accessors
+   ossimDemHeader const& getHeader() const;
+
+   /*!
+    *  Returns the number of columns in the grid.
+    */
+   long getWidth() const;
+
+   /*!
+    *  Returns the number of rows in the grid.
+    */
+   long getHeight() const;
+
+   /*!
+    *  Returns the elevation value at (x,y). (0,0) is in the upper left
+    *  corner, x is positive to the right, y is positive down.
+    */
+   ossim_float32 getElevation(long x, long y) const;
+
+   /*!
+    *  Returns the value used to indicate missing data.
+    */
+   ossim_float32 getMissingDataValue() const;
+
+   /*!
+    *  (x,y) are the coordinates of a elevation value in the dem.
+    *  (ground_x, ground_y) are the coordinates of that value in the
+    *  units of the horizontal projection system used by the dem.
+    */
+   void getGroundCoords(long x, long y, double& ground_x, double& ground_y);
+
+private:
+
+   ossim_float32   _missDataVal;
+   ossimDemHeader  _header;
+   long            _width;
+   long            _height;
+   ossim_float32*  _grid;
+   bool            _firstTime; // Whether or not we've started reading the DEM.
+   long            _curProfile;
+   std::vector<ossimDemProfile> _profiles;  // Used by fillUTM()
+   double _northwest_x, _northwest_y;
+
+   void setElevation(long x, long y, ossim_float32 val);
+   long fillGeographic(std::istream& dem, bool incrementalRead);
+   long fillUTM(std::istream& dem, bool incrementalRead);
+};
+
+inline void ossimDemGrid::setElevation(long x, long y, ossim_float32 val)
+{
+   if (_grid == 0)
+      return;
+
+   _grid[(_width * y) + x] = val;
+}
+
+#endif  // #ifndef ossimDemGrid_HEADER
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemHeader.cpp b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemHeader.cpp
new file mode 100644
index 0000000000..2febbb6c9d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemHeader.cpp
@@ -0,0 +1,699 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class parses a DEM header.
+//
+//********************************************************************
+// $Id: ossimDemHeader.cpp,v 1.6 2005/05/16 18:58:15 dburken Exp $
+
+#include <cstdlib>
+#include <iomanip>
+#include <support_data/usgs_dem/ossimDemHeader.h>
+#include <support_data/usgs_dem/ossimDemUtil.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimKeywordlist.h>
+#include <base/common/ossimConstants.h>
+#include <base/common/ossimCommon.h>
+#include <base/common/ossimKeywordNames.h>
+
+static const char* PROCESS_CODE[]
+= { "Autocorrelation resample simple bilinear",
+    "Manual profile GRIDEM simple bilinear",
+    "DLG/hypsography CTOG 8-direction bilinear",
+    "Interpolation from photogrammetic system contours DCASS",
+    "direction bilinear",
+    "DLG/hypsography LINETRACE, LT4X complex linear",
+    "DLG/hypsography CPS-3, ANUDEM, GRASS complex polynomial",
+    "Electronic imaging (non-photogrammetric), active or passive",
+    "sensor systems" };
+
+static const int MAX_PROCESS_CODE_INDEX = 8;
+
+static const char* GROUND_REF_SYSTEM[]
+= { "Geographic",
+    "UTM",
+    "State Plane" };
+
+static const int MAX_GROUND_REF_SYSTEM_INDEX = 2;
+
+static const char* GROUND_REF_SYSTEM_UNITS[]
+= { "Radians",
+    "Feet",
+    "Meters",
+    "Arc Seconds" };
+
+static const int MAX_GROUND_REF_SYSTEM_UNITS_INDEX = 3;
+
+
+static const char* VERTICAL_DATUM[]
+= { "local mean sea level",
+    "National Geodetic Vertical Datum 1929",
+    "North American Vertical Datum 1988" };
+
+static const int MAX_VERTICAL_DATUM_INDEX = 2;
+
+static const char* HORIZONTAL_DATUM[]
+= { "North Amercian Datum 1927 (NAD 27)",
+    "World Geoditic System 1972 (WGS 72)",
+    "WGS 84",
+    "NAD 83",
+    "Old Hawaii Datum",
+    "Puerto Rico Datum" };
+
+static const int MAX_HORIZONTAL_DATUM_INDEX = 5;
+
+
+ossimDemHeader::ossimDemHeader()
+   : _seGeoCornerX(0.0),
+     _seGeoCornerY(0.0),
+     _processCode(0),
+     _levelCode(0),
+     _elevPattern(0),
+     _groundRefSysCode(0),
+     _groundRefSysZone(0),
+     _groundRefSysUnits(0),
+     _elevUnits(0),
+     _numPolySides(0),
+     _counterclockAngle(0.0),
+     _elevAccuracyCode(0),
+     _minElevation(0),
+     _maxElevation(0),
+     _spatialResX(0.0),
+     _spatialResY(0.0),
+     _spatialResZ(0.0),
+     _profileRows(0),
+     _profileColumns(0),
+     _largeContInt(0),
+     _maxSourceUnits(0),
+     _smallContInt(0),
+     _minSourceUnits(0),
+     _sourceDate(0),
+     _inspRevDate(0),
+     _valFlag(0),
+     _suspectVoidFlg(0),
+     _vertDatum(0),
+     _horizDatum(0),
+     _dataEdition(0),
+     _perctVoid(0),
+     _westEdgeFlag(0),
+     _northEdgeFlag(0),
+     _eastEdgeFlag(0),
+     _southEdgeFlag(0),
+     _vertDatumShift(0.0)
+{
+}
+   
+string const&
+ossimDemHeader::getQuadName() const
+{
+   return _quadName;
+}
+
+string const&
+ossimDemHeader::getProcessInfo() const
+{
+   return _processInfo;
+}
+
+double
+ossimDemHeader::getSEGeoCornerX() const
+{
+   return _seGeoCornerX;
+}
+
+double
+ossimDemHeader::getSEGeoCornerY() const
+{
+   return _seGeoCornerY;
+}
+
+long
+ossimDemHeader::getProcessCode() const
+{
+   return _processCode;
+}
+
+string const&
+ossimDemHeader::getSectionIndicator() const
+{
+   return _sectionIndicator;
+}
+
+string const&
+ossimDemHeader::getMappingCenterCode() const
+{
+   return _mapCenterCode;
+}
+
+long
+ossimDemHeader::getLevelCode() const
+{
+   return _levelCode;
+}
+         
+long
+ossimDemHeader::getElevPattern() const
+{
+   return _elevPattern;
+}
+
+long
+ossimDemHeader::getGroundRefSysCode() const
+{
+   return _groundRefSysCode;
+}
+    
+long
+ossimDemHeader::getGroundRefSysZone() const
+{
+   return _groundRefSysZone;
+}
+
+long
+ossimDemHeader::getGroundRefSysUnits() const
+{
+   return _groundRefSysUnits;
+}
+
+long
+ossimDemHeader::getElevationUnits() const
+{
+   return _elevUnits;
+}
+
+long
+ossimDemHeader::getNumPolySides() const
+{
+   return _numPolySides;
+}
+
+ossimDemPointVector const&
+ossimDemHeader::getDEMCorners() const
+{
+   return _demCorners;
+}
+
+double
+ossimDemHeader::getCounterclockAngle() const
+{
+   return _counterclockAngle;
+}
+
+long
+ossimDemHeader::getElevAccuracyCode() const
+{
+   return _elevAccuracyCode;
+}
+
+double
+ossimDemHeader::getMinimumElev() const
+{
+   return _minElevation;
+}
+
+double
+ossimDemHeader::getMaximumElev() const
+{
+   return _maxElevation;
+}
+
+double
+ossimDemHeader::getSpatialResX() const
+{
+   return _spatialResX;
+}
+
+double
+ossimDemHeader::getSpatialResY() const
+{
+   return _spatialResY;
+}
+
+double
+ossimDemHeader::getSpatialResZ() const
+{
+   return _spatialResZ;
+}
+
+long
+ossimDemHeader::getProfileRows() const
+{
+   return _profileRows;
+}
+
+long
+ossimDemHeader::getProfileColumns() const
+{
+   return _profileColumns;
+}
+
+long
+ossimDemHeader::getLargeContInt() const
+{
+   return _largeContInt;
+}
+
+long
+ossimDemHeader::getMaxSourceUnits() const
+{
+   return _maxSourceUnits;
+}
+
+long
+ossimDemHeader::getSmallContInt() const
+{
+   return _smallContInt;
+}
+
+long
+ossimDemHeader::getMinSourceUnits() const
+{
+   return _minSourceUnits;
+}
+
+long
+ossimDemHeader::getSourceDate() const
+{
+   return _sourceDate;
+}
+
+long
+ossimDemHeader::getInspRevDate() const
+{
+   return _inspRevDate;
+}
+
+string const&
+ossimDemHeader::getInspFlag() const
+{
+   return _inspFlag;
+}
+
+long
+ossimDemHeader::getDataValFlag() const
+{
+   return _valFlag;
+}
+
+long
+ossimDemHeader::getSuspectVoidFlag() const
+{
+   return _suspectVoidFlg;
+}
+
+long
+ossimDemHeader::getVertDatum () const
+{
+   return _vertDatum;
+}
+
+long
+ossimDemHeader::getHorizDatum() const
+{
+   return _horizDatum;
+}
+
+long
+ossimDemHeader::getDataEdition() const
+{
+   return _dataEdition;
+}
+
+long
+ossimDemHeader::getPerctVoid() const
+{
+   return _perctVoid;
+}
+
+long
+ossimDemHeader::getWestEdgeFlag() const
+{
+   return _westEdgeFlag;
+}
+
+long
+ossimDemHeader::getNorthEdgeFlag() const
+{
+   return _northEdgeFlag;
+}
+
+long
+ossimDemHeader::getEastEdgeFlag() const
+{
+   return _eastEdgeFlag;
+}
+
+long
+ossimDemHeader::getSouthEdgeFlag() const
+{
+   return _southEdgeFlag;
+}
+
+double
+ossimDemHeader::getVertDatumShift() const
+{
+   return _vertDatumShift;
+}
+
+ostream&
+operator<<(ostream& s, const ossimDemHeader& header)
+{
+   return header.print(s);
+}
+
+ostream& ossimDemHeader::print(ostream& s) const
+{
+   // Note:  This is only a partial print for now...
+   
+   s << setiosflags(ios::fixed) << setprecision(10)
+     << "USGS DEM Header Info:"
+     << "\nQuadrangle name:                " << getQuadName().c_str()
+     << "\nProcess info:                   " << getProcessInfo().c_str()
+     << "\nSE Geo Corner X(SDDMMSS.SSSS):  " << getSEGeoCornerX()
+     << "\nSE Geo Corner Y(SDDMMSS.SSSS):  " << getSEGeoCornerY()
+     << "\nProcess code:                   ";
+
+   long tmpl = getProcessCode() - 1;
+   if ( tmpl >= 0 && tmpl <= MAX_PROCESS_CODE_INDEX)
+   {
+      s << PROCESS_CODE[tmpl];
+   }
+   else
+   {
+      s << "Unknown";
+   }
+
+   s << "\nSection Indicator:       " << getSectionIndicator().c_str()
+     << "\nMapping Center Code:     " << getMappingCenterCode().c_str()
+     << "\nLevel Code:              " << getLevelCode()
+     << "\nElev Pattern:            " << getElevPattern()
+     << "\nGround Ref Sys:          ";
+
+   tmpl = getGroundRefSysCode();
+   if ( tmpl >= 0 && tmpl <= MAX_GROUND_REF_SYSTEM_INDEX)
+   {
+      s << GROUND_REF_SYSTEM[tmpl];
+   }
+   else
+   {
+      s << "Unknown";
+   }
+
+   s << "\nGround Ref Sys Zone:     " << getGroundRefSysZone()
+
+     << "\nGround Ref Sys Units:    ";
+   tmpl = getGroundRefSysUnits();
+   if ( tmpl >= 0 && tmpl <= MAX_GROUND_REF_SYSTEM_UNITS_INDEX)
+   {
+      s << GROUND_REF_SYSTEM_UNITS[tmpl];
+   }
+   else
+   {
+      s << "Unknown";
+   }
+         
+   s << "\nElevation Units:         ";
+   tmpl = getElevationUnits();
+   if ( tmpl >= 0 && tmpl <= MAX_GROUND_REF_SYSTEM_UNITS_INDEX)
+   {
+      s << GROUND_REF_SYSTEM_UNITS[tmpl];
+   }
+   else
+   {
+      s << "Unknown";
+   }
+
+   s << "\nNumber Poly Sides:       " << getNumPolySides()
+     << "\nCounterclock Angle:      " << getCounterclockAngle()
+     << "\nElev Accuracy Code:      " << getElevAccuracyCode()
+     << "\nMinimum Elevation:       " << getMinimumElev()
+     << "\nMaximum Elevation:       " << getMaximumElev()
+     << "\nSpatial Res X:           " << getSpatialResX()
+     << "\nSpatial Res Y:           " << getSpatialResY()
+     << "\nSpatial Res Z:           " << getSpatialResZ()
+     << "\nProfile Rows:            " << getProfileRows()
+     << "\nProfile Columns:         " << getProfileColumns()
+     << "\nVertical datum:          ";
+
+   tmpl = getVertDatum() - 1;
+   if ( tmpl >= 0 && tmpl <= MAX_VERTICAL_DATUM_INDEX)
+   {
+      s << VERTICAL_DATUM[tmpl];
+   }
+   else
+   {
+      s << "Unknown";
+   }
+
+   s << "\nVertical datum shift:    " << getVertDatumShift()
+     << "\nHorizontal datum:        ";
+   tmpl = getHorizDatum() - 1;
+   if ( tmpl >= 0 && tmpl <= MAX_HORIZONTAL_DATUM_INDEX)
+   {
+      s << HORIZONTAL_DATUM[tmpl];
+   }
+   else
+   {
+      s << "Unknown";
+   }
+
+   const ossimDemPointVector CORNERS = getDEMCorners();
+   for (unsigned int i=0; i < CORNERS.size(); ++i)
+   {
+      s << "Corner[" << i << "].x:  " << CORNERS[i].getX()
+        << "\nCorner[" << i << "].y:  " << CORNERS[i].getY()
+        << endl;
+         
+   }
+
+   s << endl;
+   
+   return s;
+}
+
+istream&
+operator>>(istream& s, ossimDemHeader& header)
+{
+   char bufstr[1024];
+   char temp[1024];
+   long i;
+
+   ossimDemUtil::getRecord(s,bufstr);
+
+   strncpy(temp, bufstr, 40);
+   temp[40] = '\0';
+   header._quadName = temp;
+
+   strncpy(temp,bufstr+40,40);
+   temp[40] = '\0';
+   header._processInfo = temp;
+   
+   ossimDemUtil::getDouble(bufstr, 109, 13, header._seGeoCornerX);
+   ossimDemUtil::getDouble(bufstr, 122, 13, header._seGeoCornerY);
+   header._processCode = ossimDemUtil::getLong(bufstr, 135, 1);
+
+   strncpy(temp,bufstr+137,3);
+   temp[3] = '\0';
+   header._sectionIndicator = temp;
+
+   strncpy(temp,bufstr+140,4);
+   temp[4] = '\0';
+   header._mapCenterCode = temp;
+    
+   header._levelCode = ossimDemUtil::getLong(bufstr, 144, 6);
+   header._elevPattern = ossimDemUtil::getLong(bufstr, 150, 6);
+   header._groundRefSysCode = ossimDemUtil::getLong(bufstr, 156, 6);
+   header._groundRefSysZone = ossimDemUtil::getLong(bufstr, 162, 6);
+   header._groundRefSysUnits = ossimDemUtil::getLong(bufstr, 528, 6);
+   header._elevUnits = ossimDemUtil::getLong(bufstr, 534, 6);
+   header._numPolySides = ossimDemUtil::getLong(bufstr, 540, 6);
+
+   for (i = 0; i < 4; i++)
+   {
+      double x,y;
+      long pos = 546 + (i * 48);
+      ossimDemUtil::getDouble(bufstr, pos, 24, x);
+      ossimDemUtil::getDouble(bufstr, pos + 24, 24, y);
+      header._demCorners.push_back(ossimDemPoint(x,y));
+   }
+
+   ossimDemUtil::getDouble(bufstr, 738, 24, header._minElevation);
+   ossimDemUtil::getDouble(bufstr, 762, 24, header._maxElevation);
+   ossimDemUtil::getDouble(bufstr, 786, 24, header._counterclockAngle );
+   header._elevAccuracyCode = ossimDemUtil::getLong(bufstr, 810, 6);
+   ossimDemUtil::getDouble(bufstr, 816, 12, header._spatialResX);
+   ossimDemUtil::getDouble(bufstr, 828, 12, header._spatialResY);
+   ossimDemUtil::getDouble(bufstr, 840, 12, header._spatialResZ);
+   header._profileRows = ossimDemUtil::getLong(bufstr, 852, 6);
+   header._profileColumns = ossimDemUtil::getLong(bufstr, 858, 6);
+   header._largeContInt = ossimDemUtil::getLong(bufstr, 864, 5);
+   header._maxSourceUnits = ossimDemUtil::getLong(bufstr, 869, 1);
+   header._smallContInt = ossimDemUtil::getLong(bufstr, 870, 5);
+   header._minSourceUnits = ossimDemUtil::getLong(bufstr, 875, 1);
+   header._sourceDate = ossimDemUtil::getLong(bufstr, 876, 4);
+   header._inspRevDate = ossimDemUtil::getLong(bufstr, 880, 4);
+   
+   strncpy(temp, bufstr+884,1);
+   temp[1]='\0';
+   header._inspFlag = temp;
+
+   header._valFlag = ossimDemUtil::getLong(bufstr, 885, 1);
+   header._suspectVoidFlg = ossimDemUtil::getLong(bufstr, 886, 2);
+   header._vertDatum = ossimDemUtil::getLong(bufstr, 888, 2);
+   header._horizDatum = ossimDemUtil::getLong(bufstr, 890, 2);
+   if (header._horizDatum == 0)
+      header._horizDatum = 1;   // Default to NAD27
+
+   header._dataEdition = ossimDemUtil::getLong(bufstr, 892, 4);
+   header._perctVoid = ossimDemUtil::getLong(bufstr, 896, 4);
+   header._westEdgeFlag = ossimDemUtil::getLong(bufstr, 900, 2);
+   header._northEdgeFlag = ossimDemUtil::getLong(bufstr, 902, 2);
+   header._eastEdgeFlag = ossimDemUtil::getLong(bufstr, 904, 2);
+   header._southEdgeFlag = ossimDemUtil::getLong(bufstr, 906, 2);
+   ossimDemUtil::getDouble(bufstr, 908, 7, header._vertDatumShift);
+
+   return s;  
+}
+
+bool ossimDemHeader::getImageGeometry(ossimKeywordlist& kwl,
+                                      const char* prefix) const
+{
+   ossimString type = getProjectionType();
+   ossimString datum = getHorizDatumCode();
+   if ( (type == "unknown") || (datum == "unknown") )
+   {
+      return false;
+   }
+
+   if (_demCorners.size() != 4)
+   {
+      return false;
+   }
+
+   double tieX   = _demCorners[1].getX();
+   double tieY   = _demCorners[1].getY();
+   double scaleX = getSpatialResX();
+   double scaleY = getSpatialResX();
+   
+   // Add these for all projections.
+   kwl.add(prefix,
+           ossimKeywordNames::TYPE_KW,
+           type);
+   
+   kwl.add(prefix,
+           ossimKeywordNames::DATUM_KW,
+           datum);
+
+   if (getGroundRefSysCode() == 0) // Geographic.
+   {
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LON_KW,
+              tieX);
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_LAT_KW,
+              tieY);
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
+              scaleX);
+      kwl.add(prefix,
+              ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
+              scaleY);
+   }
+   else if (getGroundRefSysCode() == 1) // UTM
+   {
+      // Get the zone.
+      kwl.add(prefix,
+              ossimKeywordNames::ZONE_KW,
+              abs(getGroundRefSysZone()));
+
+      // Set the hemisphere.
+      kwl.add(prefix,
+              ossimKeywordNames::HEMISPHERE_KW,
+              (getGroundRefSysZone()<0?"S":"N"));
+
+      // Set the tie.
+      if (getGroundRefSysUnits() == 1) // Feet...
+      {
+         tieX = usft2mtrs(tieX);
+         tieY = usft2mtrs(tieY);
+         scaleX = usft2mtrs(scaleX);
+         scaleY = usft2mtrs(scaleY);
+         
+      }
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_EASTING_KW,
+              tieX);
+      kwl.add(prefix,
+              ossimKeywordNames::TIE_POINT_NORTHING_KW,
+              tieY);
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_X_KW,
+              scaleX);
+      kwl.add(prefix,
+              ossimKeywordNames::METERS_PER_PIXEL_Y_KW,
+              scaleY);
+   }
+   else if (getGroundRefSysCode() == 2) // State Plane
+   {
+      return false; // Need to code...
+   }
+
+   
+   return true;
+}
+
+ossimString ossimDemHeader::getHorizDatumCode() const
+{
+   ossimString code;
+   switch(getHorizDatum())
+   {
+      case 1:
+         code = "NAS-C";
+         break;
+      case 2:
+         code = "WGD";
+         break;
+      case 3:
+         code = "WGE";
+        break;         
+      case 4:
+         code = "NAR-C";
+        break;         
+      case 5:
+         code = "OHA-M";
+        break;         
+      case 6:
+         code = "PUR";
+         break;
+      default:
+         code = "unknown";
+        break;         
+   }
+   return code;
+}
+         
+ossimString ossimDemHeader::getProjectionType() const
+{
+   ossimString type;
+   switch(getGroundRefSysCode())
+   {
+      case 0:
+         type = "ossimEquDistCylProjection";
+         break;
+      case 1:
+         type = "ossimUtmProjection";
+         break;
+      case 2:
+      default:
+         type = "unknown";
+         break;
+   }
+   return type;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemHeader.h b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemHeader.h
new file mode 100644
index 0000000000..0c81ea4f54
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemHeader.h
@@ -0,0 +1,356 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class parses a DEM header.
+//
+//********************************************************************
+// $Id: ossimDemHeader.h,v 1.7 2005/05/16 18:58:15 dburken Exp $
+
+#ifndef ossimDemHeader_HEADER
+#define ossimDemHeader_HEADER
+
+#include <string>
+#include <iostream>
+using namespace std;
+
+#include <support_data/usgs_dem/ossimDemPoint.h>
+
+class ossimString;
+class ossimKeywordlist;
+
+class ossimDemHeader
+{
+public:
+   
+   ossimDemHeader();
+   friend ostream& operator<<(ostream& s, const ossimDemHeader& header);
+   friend istream& operator>>(istream& s, ossimDemHeader& header);
+   
+   ostream& print(ostream& s) const;
+   
+   
+   // Accessors
+
+   /*! Quadrangle name. */
+   string const& getQuadName() const;
+
+   /*! Free format desciptor field containing process information. */
+   string const& getProcessInfo () const;
+
+   /*!
+    *  SE geographic corner orderd as:
+    *  x == Longitude == SDDDMMSS.SSSS
+    *  (neg sign (s) right justified, no leading zeros,
+    *  plus sign (s) implied
+    */
+   double getSEGeoCornerX () const;
+
+   /*!
+    *  SE geographic corner orderd as:
+    *  y == Latitude == SDDMMSS.SSSS
+    *  (neg sign (s) right justified, no leading zeros,
+    *  plus sign (s) implied
+    */
+   double getSEGeoCornerY () const;
+
+   /*!
+    *  1 == Autocorrelation resample simple bilinear
+    *  2 == Manual profile GRIDEM simple bilinear
+    *  3 == DLG/hypsography CTOG 8-direction bilinear
+    *  4 == Interpolation from photogrammetic system contours DCASS 
+    *  4-direction bilinear
+    *  5 == DLG/hypsography LINETRACE, LT4X complex linear
+    *  6 == DLG/hypsography CPS-3, ANUDEM, GRASS complex polynomial
+    *  7 == Electronic imaging (non-photogrammetric), active or passive
+    *  sensor systems
+    */
+   long getProcessCode () const;
+
+   /*!
+    *  Used for 30 minute DEMs - Identifies 1:100,000 scale sections
+    *  Formatted as XNN, wher X is "S" == 7.5 min. & "F" == 15 min.
+    *  NN is a two digit sequence number
+    */
+   string const& getSectionIndicator() const;
+
+   /*!
+    *  Mapping Center origin code. "EMC","WMC","MCMC","RMMC","FS" and "GPM2"
+    */
+   string const& getMappingCenterCode() const;
+
+   /*!
+    *  1 == DEM-1
+    *  2 == DEM-2
+    *  3 == DEM-3
+    */
+   long getLevelCode() const;
+
+   /*!
+    *  1 == Regular
+    *  2 == Random (reserved for future use).
+    */
+   long getElevPattern() const;
+
+   /*!
+    *  Code defining ground planimetric reference system.
+    *  0 == Geographic
+    *  1 == UTM
+    *  2 == State Plane
+    */
+   long getGroundRefSysCode() const;
+
+   /*!
+    * @return The projection type as a string.
+    */
+   ossimString getProjectionType() const;
+
+   /*!
+    *  Code defining zone in ground planimetric reference system.
+    */
+   long getGroundRefSysZone() const;
+
+   /*!
+    *  Code defining unit of measure for ground planimetric coordinates
+    *  used throughout the file.
+    *  0 == Radians
+    *  1 == Feet
+    *  2 == Meters
+    *  3 == Arc Seconds
+    */
+   long getGroundRefSysUnits() const;
+
+   /*!
+    *  Code defining unit of measure for elevation coordinates used
+    *  throughout the file.
+    *  1 == Feet
+    *  2 == Meters
+    */
+   long getElevationUnits() const;
+
+   /*!
+    *  Set n == 4
+    */
+   long getNumPolySides() const;
+
+   /*!
+    *  The coordinates of the quadrangle corners are ordered in a clockwise
+    *  direction beginning with the southwest corner.
+    */
+   const ossimDemPointVector& getDEMCorners() const;
+
+   /*!
+    *  In Radians the counterclockwise angle from the primary axis of ground
+    *  planimetric reference to the primary axis of the DEM local reference
+    *  system. Set to 0 to align with the coordinate system
+    */
+   double getCounterclockAngle() const;
+
+   /*!
+    *  0 == unknown accuracy
+    *  1 == accuracy info is given in logical record type C
+    */
+   long getElevAccuracyCode() const;
+
+   /*!
+    *  Minimum elevation in the DEM.
+    */
+   double getMinimumElev() const;
+
+   /*!
+    *  Maximum elevation in the DEM.
+    */
+   double getMaximumElev() const;
+
+   double getSpatialResX() const;
+   double getSpatialResY() const;
+   double getSpatialResZ() const;
+
+   /*!
+    *  The number of rows and columns in profiles in the DEM. 
+    *  NOTE: When profile rows == 1, profile columns is the number of profiles
+    *  in the DEM.
+    */
+   long getProfileRows() const;
+   long getProfileColumns() const;      
+
+   /*!
+    *  Present only if two or more primary intervals exist (level 2 DEM's only)
+    */
+   long getLargeContInt() const;
+
+   /*!
+    *  0 == NA
+    *  1 == feet
+    *  2 == meters
+    *  (level two DEM's only)
+    */
+   long getMaxSourceUnits() const;
+
+   /*!
+    *  Smallest or only primary contour interval (level 2 DEM's only)
+    */
+   long getSmallContInt() const;
+
+   /*!
+    *  1 == feet
+    *  2 == meters
+    */
+   long getMinSourceUnits() const;
+
+   /*!
+    *  YYY
+    */
+   long getSourceDate() const;
+
+   /*!
+    *  YYY
+    */
+   long getInspRevDate() const;
+
+   /*!
+    *  "I" indicates all processes of part3, Quality Control have been
+    *  performed.
+    */
+   string const& getInspFlag() const;
+
+   /*!
+    *  0 == No Validation
+    *  1 == RSME computed from test points, no quantative test or interactive
+    *       editing/review
+    *  2 == Batch process water body edit and RSME computed from test points
+    *  3 == Review and edit, including water edit. No RSME computed from test
+    *       points
+    *  4 == Level 1 DEM's reviewed & edited. RSME computed from test points
+    *  5 == Level 2 & 3 DEM's reviewed & edited. RSME computed from test points
+    */
+   long getDataValFlag() const;
+
+   /*!
+    *  0 == none
+    *  1 == suspect areas
+    *  2 == void areas
+    *  3 == suspect & void areas
+    */
+   long getSuspectVoidFlag() const;
+
+   /*!
+    *  1 == local mean sea level
+    *  2 == National Geodetic Vertical Datum 1929
+    *  3 == North American Vertical Datum 1988
+    */
+   long getVertDatum() const;
+
+   /*!
+    *  1 == North Amercian Datum 1927 (NAD 27)
+    *  2 == World Geoditic System 1972 (WGS 72)
+    *  3 == WGS 84
+    *  4 == NAD 83
+    *  5 == Old Hawaii Datum
+    *  6 == Puerto Rico Datum
+    */
+   long getHorizDatum() const;
+
+   /**
+    * @return The ossim datum code as a string.
+    */
+   ossimString getHorizDatumCode() const;
+
+   /*!
+    *  01-99 Primarily a DMA specfic field. (For USGS use set to 01)
+    */
+   long getDataEdition() const;
+
+   /*!
+    *  Contains the percentage of nodes in the file set to void
+    */
+   long getPerctVoid() const;
+
+   /*!
+    *  West edge match status flag
+    */
+   long getWestEdgeFlag() const;
+
+   /*!
+    *  North edge match status flag
+    */
+   long getNorthEdgeFlag() const;
+
+   /*!
+    *  East edge match staus flag
+    */
+   long getEastEdgeFlag() const;
+
+   /*!
+    *  South edge match status flag
+    */
+   long getSouthEdgeFlag() const;
+
+   /*!
+    *  Vertical datum shift - value is in the form of SFFF.DD Value is
+    *  the average shift value for the four quadrangle corners obtained
+    *  from program VERTCOM.
+    */
+   double getVertDatumShift() const;
+
+   /*!
+    * Populates keyword list with geometry info.
+    * 
+    * @return true on success, false on error.
+    */
+   bool getImageGeometry(ossimKeywordlist& kwl,
+                         const char* prefix=NULL) const;
+	 
+private:
+
+   string _quadName;
+   string _processInfo;
+   double _seGeoCornerX;
+   double _seGeoCornerY;
+   long _processCode;
+   string _sectionIndicator;
+   string _mapCenterCode;
+   long _levelCode;
+   long _elevPattern;
+   long _groundRefSysCode;
+   long _groundRefSysZone;
+   long _groundRefSysUnits;
+   long _elevUnits;
+   long _numPolySides;
+   ossimDemPointVector _demCorners;
+   double _counterclockAngle;
+   long _elevAccuracyCode;
+   double _minElevation;
+   double _maxElevation;
+   double _spatialResX;
+   double _spatialResY;
+   double _spatialResZ;
+   long _profileRows;
+   long _profileColumns;
+   long _largeContInt;
+   long _maxSourceUnits;
+   long _smallContInt;
+   long _minSourceUnits;
+   long _sourceDate;
+   long _inspRevDate;
+   string _inspFlag;
+   long _valFlag;
+   long _suspectVoidFlg;
+   long _vertDatum;
+   long _horizDatum;
+   long _dataEdition;
+   long _perctVoid;
+   long _westEdgeFlag;
+   long _northEdgeFlag;
+   long _eastEdgeFlag;
+   long _southEdgeFlag;
+   double _vertDatumShift;
+};
+
+#endif  // #ifndef ossimDemHeader_HEADER
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemPoint.cpp b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemPoint.cpp
new file mode 100644
index 0000000000..3794e15d1f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemPoint.cpp
@@ -0,0 +1,16 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author:  David Burken
+//
+// Description:
+//
+// Contains class definition for DEMPoint.
+//*******************************************************************
+//  $Id: ossimDemPoint.cpp,v 1.2 2005/01/11 18:10:38 dburken Exp $
+
+#include <support_data/usgs_dem/ossimDemPoint.h>
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemPoint.h b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemPoint.h
new file mode 100644
index 0000000000..d9004d8827
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemPoint.h
@@ -0,0 +1,111 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Ken Melero (kmelero@imagelinks.com)
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class defines a DEM point.
+//
+//********************************************************************
+// $Id: ossimDemPoint.h,v 1.4 2002/01/12 16:11:24 dburken Exp $
+
+#ifndef ossimDemPoint_HEADER
+#define ossimDemPoint_HEADER
+
+#include <vector>
+
+class ossimDemPoint
+{
+public:
+
+   ossimDemPoint(double x = 0.0, double y = 0.0);
+     
+   // Accessors
+   double getX() const;
+   double getY() const;
+   void getXY(double& x, double& y) const;
+
+   // Modifiers
+   void setX(double x);
+   void setY(double y);
+   void setXY(double x, double y);
+   bool operator<(ossimDemPoint const& rhs) const {return false;}
+   bool operator==(ossimDemPoint const& rhs) const {return false;}
+
+private:
+
+   double _x;
+   double _y;
+};
+
+// Inline Methods for class ossimDemPoint
+
+inline
+ossimDemPoint::ossimDemPoint(double x, double y)
+{
+   _x = x;
+   _y = y;
+}
+
+inline
+double
+ossimDemPoint::getX() const
+{
+   return _x;
+}
+
+inline
+double
+ossimDemPoint::getY() const
+{
+   return _y;
+}
+
+inline
+void
+ossimDemPoint::getXY(double& x, double& y) const
+{
+   x = _x;
+   y = _y;
+}
+
+inline
+void
+ossimDemPoint::setX(double x)
+{
+   _x = x;
+}
+
+inline
+void
+ossimDemPoint::setY(double y)
+{
+   _y = y;
+}
+
+inline
+void
+ossimDemPoint::setXY(double x, double y)
+{
+   _x = x;
+   _y = y;
+}
+
+typedef std::vector<ossimDemPoint> ossimDemPointVector;
+
+#endif  // #ifndef ossimDemPoint_HEADER
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemProfile.cpp b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemProfile.cpp
new file mode 100644
index 0000000000..60b9dde341
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemProfile.cpp
@@ -0,0 +1,158 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class defines a DEM profile.
+//
+//********************************************************************
+// $Id: ossimDemProfile.cpp,v 1.5 2005/01/11 18:10:38 dburken Exp $
+
+#include <stdlib.h>
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+#include "ossimDemProfile.h"
+#include "ossimDemUtil.h"
+
+ossimDemProfile::ossimDemProfile()
+   : _row(0),
+     _column(0),
+     _numberElevations(0),
+     _locDatumElev(0.0),
+     _minElev(0.0),
+     _maxElev(0.0)
+{
+}
+
+ossimDemProfile::ossimDemProfile(ossimDemProfile const& right)
+{
+   operator=(right);
+}
+
+ossimDemProfile const&
+ossimDemProfile::operator=(ossimDemProfile const& right)
+{
+   if (this == &right)
+      return *this;
+
+   _row = right._row;
+   _column = right._column;
+   _numberElevations = right._numberElevations;
+   _profileLocation = right._profileLocation;
+   _locDatumElev = right._locDatumElev;
+   _minElev = right._minElev;
+   _maxElev = right._maxElev;
+   _elevations = right._elevations;
+
+   return *this;
+}
+
+long
+ossimDemProfile::getRowNumber() const
+{
+   return _row;
+}
+
+long
+ossimDemProfile::getColumnNumber() const
+{
+   return _column;
+}
+
+long
+ossimDemProfile::getNumberOfElevations() const
+{
+   return _numberElevations;
+}
+
+ossimDemPoint const&
+ossimDemProfile::getProfileLocation() const
+{
+   return _profileLocation;
+}
+
+double
+ossimDemProfile::getLocalDatumElevation() const
+{
+   return _locDatumElev;
+}
+
+double
+ossimDemProfile::getMinimumElev() const
+{
+   return _minElev;
+}
+
+double
+ossimDemProfile::getMaximumElev() const
+{
+   return _maxElev;
+}
+
+ossimDemElevationVector const&
+ossimDemProfile::getElevations() const
+{
+   return _elevations;
+}
+
+istream&
+operator>>(istream& s, ossimDemProfile& demp)
+{
+   //   string bufstr;
+   char bufstr[1024];
+
+   ossimDemUtil::getRecord(s,bufstr);
+
+   demp._row = ossimDemUtil::getLong(bufstr, 0, 6);
+   demp._column = ossimDemUtil::getLong(bufstr, 6, 6);
+   demp._numberElevations = ossimDemUtil::getLong(bufstr, 12, 6);
+
+   double x,y;
+   ossimDemUtil::getDouble(bufstr, 24, 24, x);
+   ossimDemUtil::getDouble(bufstr, 48, 24, y);
+   demp._profileLocation.setXY(x,y);
+
+   ossimDemUtil::getDouble(bufstr, 72, 24, demp._locDatumElev);
+   ossimDemUtil::getDouble(bufstr, 96, 24, demp._minElev);
+   ossimDemUtil::getDouble(bufstr, 120, 24, demp._maxElev);
+
+   demp._elevations.erase(demp._elevations.begin(), demp._elevations.end());   
+   demp._elevations.reserve(demp._numberElevations);
+
+   // Extract elevations in this record.
+   long count = 0;
+   while ((count < 146) && (count < demp._numberElevations))
+   {
+      demp._elevations.push_back(ossimDemUtil::getLong(bufstr, 144+(count*6), 6));
+      count++;
+   }
+   
+   long t;
+   while (count < demp._numberElevations)
+   {
+      t = (count - 146) % 170;
+      if (t == 0)
+         ossimDemUtil::getRecord(s,bufstr);
+      demp._elevations.push_back(ossimDemUtil::getLong(bufstr, t*6, 6));
+      count++;
+   }
+
+   return s;
+}
+
+
+ostream&
+operator<<(ostream& s, ossimDemProfile& demp)
+{
+   return s;
+}
+
+
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemProfile.h b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemProfile.h
new file mode 100644
index 0000000000..59b6efc43b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemProfile.h
@@ -0,0 +1,96 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class defines a DEM profile.
+//
+//********************************************************************
+// $Id: ossimDemProfile.h,v 1.4 2005/01/11 18:10:38 dburken Exp $
+
+#ifndef ossimDemProfile_HEADER
+#define ossimDemProfile_HEADER
+
+#include "ossimDemPoint.h"
+
+#include <vector>
+
+typedef std::vector<long> ossimDemElevationVector;
+
+class ossimDemProfile
+{
+public:
+
+   ossimDemProfile();
+   ossimDemProfile(ossimDemProfile const& right);
+   ossimDemProfile const& operator=(ossimDemProfile const& right);
+
+   friend ostream& operator<<(ostream& s, ossimDemProfile& demp);
+   friend istream& operator>>(istream& s, ossimDemProfile& demp);
+
+   // Accessors
+
+   /*!
+    *  Row identification number. Typically set to 1.
+    */
+   long getRowNumber() const;
+
+   /*!
+    *  Column identification number. This is the profile sequence number.
+    */
+   long getColumnNumber() const;
+
+   /*!
+    *  Number of elevations in this profile.
+    */
+   long getNumberOfElevations() const;
+
+   /*!
+    *  Location (in ground planimetric coordinates) of the first
+    */
+   ossimDemPoint const& getProfileLocation() const;
+
+   /*!
+    *  Elevation of local datum for the profile.
+    *  Value is in units of measure given by the Elevation Units field
+    *  found in the DEM header.
+    */
+   double getLocalDatumElevation() const;
+
+   /*!
+    *  Minimum elevation for this profile.
+    */
+   double getMinimumElev() const;
+
+   /*!
+    *  Maximum elevation for this profile.
+    */
+   double getMaximumElev() const;
+
+   /*!
+   *  Elevation values.
+   *  From the DEM standard:
+   *  "A value in this array would be multiplied by the spatial resolution
+   *  value and added to the elevation of the local elevation datum for the
+   *  element profile to obtain the elevation for the point."
+   */
+   ossimDemElevationVector const& getElevations() const;
+
+private:
+
+   long _row;
+   long _column;
+   long _numberElevations;
+   ossimDemPoint _profileLocation;
+   double _locDatumElev;
+   double _minElev;
+   double _maxElev;
+   ossimDemElevationVector _elevations;
+};
+
+#endif  // #ifndef ossimDemProfile_HEADER
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemStats.cpp b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemStats.cpp
new file mode 100644
index 0000000000..547bbf4a14
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemStats.cpp
@@ -0,0 +1,126 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class provides some statistics for DEMs.
+//
+//********************************************************************
+// $Id: ossimDemStats.cpp,v 1.5 2005/01/11 18:10:38 dburken Exp $
+
+#include <stdlib.h>
+
+#include "ossimDemStats.h"
+#include "ossimDemUtil.h"
+using namespace std;
+
+ossimDemStats::ossimDemStats()
+   : _availCodeDE2(0),
+     _rsmeDE2x(0),
+     _rsmeDE2y(0),
+     _rsmeDE2z(0),
+     _sampleSizeDE2(0),
+     _availCodeDE5(0),
+     _rsmeDE5x(0),
+     _rsmeDE5y(0),
+     _rsmeDE5z(0),
+     _sampleSizeDE5(0)
+
+{
+}
+
+ossimDemStats::~ossimDemStats()
+{
+}
+
+long
+ossimDemStats::getAvailCodeDE2() const
+{
+   return _availCodeDE2;
+}
+
+long
+ossimDemStats::getRSMEDE2x() const
+{
+   return _rsmeDE2x;
+}
+
+long
+ossimDemStats::getRSMEDE2y() const
+{
+   return _rsmeDE2y;
+}
+
+long
+ossimDemStats::getRSMEDE2z() const
+{
+   return _rsmeDE2z;
+}
+
+long
+ossimDemStats::getSampleSizeDE2() const
+{
+   return _sampleSizeDE2;
+}
+
+long
+ossimDemStats::getAvailCodeDE5() const
+{
+   return _availCodeDE5;
+}
+
+long
+ossimDemStats::getRSMEDE5x() const
+{
+   return _rsmeDE5x;
+}
+
+long
+ossimDemStats::getRSMEDE5y() const
+{
+   return _rsmeDE5y;
+}
+
+long
+ossimDemStats::getRSMEDE5z() const
+{
+   return _rsmeDE5z;
+}
+
+long
+ossimDemStats::getSampleSizeDE5() const
+{
+   return _sampleSizeDE5;
+}
+
+ostream&
+operator<<(ostream& s,  ossimDemStats const& stats)
+{
+   return s;
+}
+
+istream&
+operator>>(istream& s, ossimDemStats& stats)
+{
+   char bufstr[1024];
+
+   ossimDemUtil::getRecord(s, bufstr);
+
+   stats._availCodeDE2 = ossimDemUtil::getLong(bufstr, 0, 6);
+   stats._rsmeDE2x = ossimDemUtil::getLong(bufstr, 6, 6);
+   stats._rsmeDE2y = ossimDemUtil::getLong(bufstr, 12, 6);
+   stats._rsmeDE2z = ossimDemUtil::getLong(bufstr, 18, 6);
+   stats._sampleSizeDE2 = ossimDemUtil::getLong(bufstr, 24, 6);
+   stats._availCodeDE5 = ossimDemUtil::getLong(bufstr, 30, 6);
+   stats._rsmeDE5x = ossimDemUtil::getLong(bufstr, 36, 6);
+   stats._rsmeDE5y = ossimDemUtil::getLong(bufstr, 42, 6);
+   stats._rsmeDE5z = ossimDemUtil::getLong(bufstr, 48, 6);
+   stats._sampleSizeDE5 = ossimDemUtil::getLong(bufstr, 54, 6);
+
+   return s;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemStats.h b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemStats.h
new file mode 100644
index 0000000000..e919390ada
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemStats.h
@@ -0,0 +1,88 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class provides some statistics for DEMs.
+//
+//********************************************************************
+// $Id: ossimDemStats.h,v 1.6 2005/01/11 18:10:38 dburken Exp $
+
+#ifndef ossimDemStats_HEADER
+#define ossimDemStats_HEADER
+
+#include <iostream>
+
+class ossimDemStats
+{
+public:
+
+   ossimDemStats();
+   ~ossimDemStats();
+
+   friend std::ostream& operator<<(std::ostream& s,
+                                   ossimDemStats const& stats);
+   friend std::istream& operator>>(std::istream& s, ossimDemStats& stats);
+
+   //Accessors
+
+   /*!
+    *  1 = available
+    *  2 = unavailable
+    *  The code defines the availability of statics
+    */
+   long getAvailCodeDE2() const;
+
+   long getRSMEDE2x () const;
+
+   long getRSMEDE2y () const;
+
+   long getRSMEDE2z () const;
+
+   /*!
+    *  This code defines the sample size use
+    *  to compute the accuracy, if 0 then the
+    *  accuracy is estimated.
+    */
+   long getSampleSizeDE2() const;
+
+   /*!
+    *  1 = available
+    *  2 = unavailable
+    *  The code defines the availability of statics
+    */
+   long getAvailCodeDE5() const;
+
+   long getRSMEDE5x () const;
+
+   long getRSMEDE5y () const;
+
+   long getRSMEDE5z () const;
+	
+   /*!
+    *  This code defines the sample size use
+    *  to compute the accuracy, if 0 then the
+    *  accuracy is estimated.
+    */
+   long getSampleSizeDE5() const;
+
+private:
+
+   long _availCodeDE2;
+   long _rsmeDE2x;
+   long _rsmeDE2y;
+   long _rsmeDE2z;
+   long _sampleSizeDE2;
+   long _availCodeDE5;
+   long _rsmeDE5x;
+   long _rsmeDE5y;
+   long _rsmeDE5z;
+   long _sampleSizeDE5;
+};
+
+#endif // #ifndef ossimDemStats_HEADER
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemUtil.cpp b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemUtil.cpp
new file mode 100644
index 0000000000..b93fade13f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemUtil.cpp
@@ -0,0 +1,80 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class provides some simple utilities for DEMs.
+//
+//********************************************************************
+// $Id: ossimDemUtil.cpp,v 1.4 2005/01/11 18:10:38 dburken Exp $
+
+#include <stdlib.h>
+#include <iostream>
+
+#include "ossimDemUtil.h"
+
+using namespace std;
+
+bool
+ossimDemUtil::getRecord(istream& s, string& strbuf, long reclength)
+{
+   char* buf = new char[reclength + 1];
+
+   bool flag = ossimDemUtil::getRecord(s,buf,reclength);
+   if (flag == true)
+      strbuf = buf;
+
+   delete [] buf;
+
+   return flag;
+}
+
+bool
+ossimDemUtil::getRecord(istream& s, char* buf, long reclength)
+{
+   // buf is assumed to be at least reclength+1 in size.
+
+   if (!s)
+      return false;
+
+   long curpos = 0;
+   buf[curpos] = s.get();
+   while ((buf[curpos] != EOF) && 
+          (buf[curpos] != '\n') &&
+          (curpos < reclength-1))
+   {
+      curpos++;
+      buf[curpos] = s.get();
+   }
+   buf[curpos] = '\0';
+
+   if (s.peek() == '\n')
+      s.get();
+
+   return true;
+
+}
+
+bool
+ossimDemUtil::getDouble(string const& strbuf,
+                   long const startpos,
+                   long const width,
+                   double& val)
+{
+   if ((startpos + width - 1) > (long)(strbuf.length()))
+      return false;
+
+   // Convert FORTRAN 'D' exponent indicator to 'E'.
+   string tempbuf(strbuf.substr(startpos,width));
+   for (unsigned int i = 0; i < tempbuf.length(); i++)
+      if (tempbuf[i] == 'D')
+         tempbuf[i] = 'E';
+
+   val = atof(tempbuf.c_str());
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemUtil.h b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemUtil.h
new file mode 100644
index 0000000000..63a8819f94
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/support_data/usgs_dem/ossimDemUtil.h
@@ -0,0 +1,57 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Ken Melero
+//         Orginally written by Jamie Moyers (jmoyers@geeks.com)
+//         Adapted from the package KDEM.
+// Description: This class provides some simple utilities for DEMs.
+//
+//********************************************************************
+// $Id: ossimDemUtil.h,v 1.7 2005/01/11 18:10:38 dburken Exp $
+
+#ifndef ossimDemUtil_HEADER
+#define ossimDemUtil_HEADER
+
+#include <string>
+#include <iostream>
+
+class ossimDemUtil
+{
+public:
+
+   /**
+    *  Reads a single record from a DEM.
+    *  Returns true if succesful. Returns false if EOF or error.
+    */
+   static bool getRecord(std::istream& s, std::string& strbuf, long reclength = 1024);
+
+   /**
+    *  Same as getRecord above. buf should be at least reclength+1 in size.
+    */
+   static bool getRecord(std::istream& s, char* buf, long reclength = 1024);
+
+   static long getLong(char* const strbuf, // string to extract long from
+                       long const startpos,  // starting position of field
+                       long const width)     // width of field
+      {
+         char temp[1024];
+         strncpy(temp,strbuf+startpos,width);
+         temp[width] = '\0';
+         return atol(temp);
+      }
+
+   static bool getDouble(std::string const& strbuf, // string to extract double from
+                         long const startpos,  // starting position of field
+                         long const width,     // width of field
+                         double& val);         // value extracted from field.
+
+private:
+
+   ossimDemUtil();
+};
+
+#endif  // #ifndef ossimDemUtil_HEADER
diff --git a/Utilities/OSSIM/ossim_core/vec/CMakeLists.txt b/Utilities/OSSIM/ossim_core/vec/CMakeLists.txt
new file mode 100644
index 0000000000..bae352525a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_vec_SRCS "*.cpp")
+FILE(GLOB_RECURSE ossim_vec_HDRS "*.h")
+ADD_LIBRARY(ossim_vec ${ossim_vec_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_vec)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_vec_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/vec/shape/.cvsignore b/Utilities/OSSIM/ossim_core/vec/shape/.cvsignore
new file mode 100644
index 0000000000..6142305dc1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/shape/.cvsignore
@@ -0,0 +1,2 @@
+*.o
+*.d
diff --git a/Utilities/OSSIM/ossim_core/vec/shape/dbfopen.c b/Utilities/OSSIM/ossim_core/vec/shape/dbfopen.c
new file mode 100644
index 0000000000..a3131a1e89
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/shape/dbfopen.c
@@ -0,0 +1,1549 @@
+/******************************************************************************
+ * $Id: dbfopen.c,v 1.5 2005/10/08 12:57:26 gpotts Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Implementation of .dbf access API documented in dbf_api.html.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: dbfopen.c,v $
+ * Revision 1.5  2005/10/08 12:57:26  gpotts
+ * Added adiitional patches
+ *
+ * Revision 1.59  2005/03/14 15:20:28  fwarmerdam
+ * Fixed last change.
+ *
+ * Revision 1.58  2005/03/14 15:18:54  fwarmerdam
+ * Treat very wide fields with no decimals as double.  This is
+ * more than 32bit integer fields.
+ *
+ * Revision 1.57  2005/02/10 20:16:54  fwarmerdam
+ * Make the pszStringField buffer for DBFReadAttribute() static char [256]
+ * as per bug 306.
+ *
+ * Revision 1.56  2005/02/10 20:07:56  fwarmerdam
+ * Fixed bug 305 in DBFCloneEmpty() - header length problem.
+ *
+ * Revision 1.55  2004/09/26 20:23:46  fwarmerdam
+ * avoid warnings with rcsid and signed/unsigned stuff
+ *
+ * Revision 1.54  2004/09/15 16:26:10  fwarmerdam
+ * Treat all blank numeric fields as null too.
+ *
+ * Revision 1.53  2003/12/29 00:00:30  fwarmerdam
+ * mark DBFWriteAttributeDirectly as SHPAPI_CALL
+ *
+ * Revision 1.52  2003/07/08 15:20:03  warmerda
+ * avoid warnings about downcasting to unsigned char
+ *
+ * Revision 1.51  2003/07/08 13:50:15  warmerda
+ * DBFIsAttributeNULL check for pszValue==NULL - bug 360
+ *
+ * Revision 1.50  2003/04/21 18:58:25  warmerda
+ * ensure current record is flushed at same time as header is updated
+ *
+ * Revision 1.49  2003/04/21 18:30:37  warmerda
+ * added header write/update public methods
+ *
+ * Revision 1.48  2003/03/10 14:51:27  warmerda
+ * DBFWrite* calls now return FALSE if they have to truncate
+ *
+ * Revision 1.47  2002/11/20 03:32:22  warmerda
+ * Ensure field name in DBFGetFieldIndex() is properly terminated.
+ *
+ * Revision 1.46  2002/10/09 13:10:21  warmerda
+ * Added check that width is positive.
+ *
+ * Revision 1.45  2002/09/29 00:00:08  warmerda
+ * added FTLogical and logical attribute read/write calls
+ *
+ * Revision 1.44  2002/05/07 13:46:11  warmerda
+ * Added DBFWriteAttributeDirectly().
+ *
+ * Revision 1.43  2002/02/13 19:39:21  warmerda
+ * Fix casting issues in DBFCloneEmpty().
+ *
+ * Revision 1.42  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.41  2002/01/15 14:31:49  warmerda
+ * compute rather than copying nHeaderLength in DBFCloneEmpty()
+ *
+ * Revision 1.40  2002/01/09 04:32:35  warmerda
+ * fixed to read correct amount of header
+ *
+ * Revision 1.39  2001/12/11 22:41:03  warmerda
+ * improve io related error checking when reading header
+ *
+ * Revision 1.38  2001/11/28 16:07:31  warmerda
+ * Cleanup to avoid compiler warnings as suggested by Richard Hash.
+ *
+ * Revision 1.37  2001/07/04 05:18:09  warmerda
+ * do last fix properly
+ *
+ * Revision 1.36  2001/07/04 05:16:09  warmerda
+ * fixed fieldname comparison in DBFGetFieldIndex
+ *
+ * Revision 1.35  2001/06/22 02:10:06  warmerda
+ * fixed NULL shape support with help from Jim Matthews
+ *
+ * Revision 1.33  2001/05/31 19:20:13  warmerda
+ * added DBFGetFieldIndex()
+ *
+ * Revision 1.32  2001/05/31 18:15:40  warmerda
+ * Added support for NULL fields in DBF files
+ *
+ * Revision 1.31  2001/05/23 13:36:52  warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.30  2000/12/05 14:43:38  warmerda
+ * DBReadAttribute() white space trimming bug fix
+ *
+ * Revision 1.29  2000/10/05 14:36:44  warmerda
+ * fix bug with writing very wide numeric fields
+ *
+ * Revision 1.28  2000/09/25 14:18:07  warmerda
+ * Added some casts of strlen() return result to fix warnings on some
+ * systems, as submitted by Daniel.
+ *
+ * Revision 1.27  2000/09/25 14:15:51  warmerda
+ * added DBFGetNativeFieldType()
+ *
+ * Revision 1.26  2000/07/07 13:39:45  warmerda
+ * removed unused variables, and added system include files
+ *
+ * Revision 1.25  2000/05/29 18:19:13  warmerda
+ * avoid use of uchar, and adding casting fix
+ *
+ * Revision 1.24  2000/05/23 13:38:27  warmerda
+ * Added error checks on return results of fread() and fseek().
+ *
+ * Revision 1.23  2000/05/23 13:25:49  warmerda
+ * Avoid crashing if field or record are out of range in dbfread*attribute().
+ *
+ * Revision 1.22  1999/12/15 13:47:24  warmerda
+ * Added stdlib.h to ensure that atof() is prototyped.
+ *
+ * Revision 1.21  1999/12/13 17:25:46  warmerda
+ * Added support for upper case .DBF extention.
+ *
+ * Revision 1.20  1999/11/30 16:32:11  warmerda
+ * Use atof() instead of sscanf().
+ *
+ * Revision 1.19  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.18  1999/07/27 00:53:28  warmerda
+ * ensure that whole old field value clear on write of string
+ *
+ * Revision 1.1  1999/07/05 18:58:07  warmerda
+ * New
+ *
+ * Revision 1.17  1999/06/11 19:14:12  warmerda
+ * Fixed some memory leaks.
+ *
+ * Revision 1.16  1999/06/11 19:04:11  warmerda
+ * Remoted some unused variables.
+ *
+ * Revision 1.15  1999/05/11 03:19:28  warmerda
+ * added new Tuple api, and improved extension handling - add from candrsn
+ *
+ * Revision 1.14  1999/05/04 15:01:48  warmerda
+ * Added 'F' support.
+ *
+ * Revision 1.13  1999/03/23 17:38:59  warmerda
+ * DBFAddField() now actually does return the new field number, or -1 if
+ * it fails.
+ *
+ * Revision 1.12  1999/03/06 02:54:46  warmerda
+ * Added logic to convert shapefile name to dbf filename in DBFOpen()
+ * for convenience.
+ *
+ * Revision 1.11  1998/12/31 15:30:34  warmerda
+ * Improved the interchangability of numeric and string attributes.  Add
+ * white space trimming option for attributes.
+ *
+ * Revision 1.10  1998/12/03 16:36:44  warmerda
+ * Use r+b instead of rb+ for binary access.
+ *
+ * Revision 1.9  1998/12/03 15:34:23  warmerda
+ * Updated copyright message.
+ *
+ * Revision 1.8  1997/12/04 15:40:15  warmerda
+ * Added newline character after field definitions.
+ *
+ * Revision 1.7  1997/03/06 14:02:10  warmerda
+ * Ensure bUpdated is initialized.
+ *
+ * Revision 1.6  1996/02/12 04:54:41  warmerda
+ * Ensure that DBFWriteAttribute() returns TRUE if it succeeds.
+ *
+ * Revision 1.5  1995/10/21  03:15:12  warmerda
+ * Changed to use binary file access, and ensure that the
+ * field name field is zero filled, and limited to 10 chars.
+ *
+ * Revision 1.4  1995/08/24  18:10:42  warmerda
+ * Added use of SfRealloc() to avoid pre-ANSI realloc() functions such
+ * as on the Sun.
+ *
+ * Revision 1.3  1995/08/04  03:15:16  warmerda
+ * Fixed up header.
+ *
+ * Revision 1.2  1995/08/04  03:14:43  warmerda
+ * Added header.
+ */
+
+#include "shapefil.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+SHP_CVSID("$Id: dbfopen.c,v 1.5 2005/10/08 12:57:26 gpotts Exp $")
+
+#ifndef FALSE
+#  define FALSE		0
+#  define TRUE		1
+#endif
+
+/************************************************************************/
+/*                             SfRealloc()                              */
+/*                                                                      */
+/*      A realloc cover function that will access a NULL pointer as     */
+/*      a valid input.                                                  */
+/************************************************************************/
+
+static void * SfRealloc( void * pMem, int nNewSize )
+
+{
+    if( pMem == NULL )
+        return( (void *) malloc(nNewSize) );
+    else
+        return( (void *) realloc(pMem,nNewSize) );
+}
+
+/************************************************************************/
+/*                           DBFWriteHeader()                           */
+/*                                                                      */
+/*      This is called to write out the file header, and field          */
+/*      descriptions before writing any actual data records.  This      */
+/*      also computes all the DBFDataSet field offset/size/decimals     */
+/*      and so forth values.                                            */
+/************************************************************************/
+
+static void DBFWriteHeader(DBFHandle psDBF)
+
+{
+    unsigned char	abyHeader[XBASE_FLDHDR_SZ];
+    int		i;
+
+    if( !psDBF->bNoHeader )
+        return;
+
+    psDBF->bNoHeader = FALSE;
+
+/* -------------------------------------------------------------------- */
+/*	Initialize the file header information.				*/
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < XBASE_FLDHDR_SZ; i++ )
+        abyHeader[i] = 0;
+
+    abyHeader[0] = 0x03;		/* memo field? - just copying 	*/
+
+    /* write out a dummy date */
+    abyHeader[1] = 95;			/* YY */
+    abyHeader[2] = 7;			/* MM */
+    abyHeader[3] = 26;			/* DD */
+
+    /* record count preset at zero */
+
+    abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
+    abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
+    
+    abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
+    abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
+
+/* -------------------------------------------------------------------- */
+/*      Write the initial 32 byte file header, and all the field        */
+/*      descriptions.                                     		*/
+/* -------------------------------------------------------------------- */
+    fseek( psDBF->fp, 0, 0 );
+    fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
+    fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp );
+
+/* -------------------------------------------------------------------- */
+/*      Write out the newline character if there is room for it.        */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 )
+    {
+        char	cNewline;
+
+        cNewline = 0x0d;
+        fwrite( &cNewline, 1, 1, psDBF->fp );
+    }
+}
+
+/************************************************************************/
+/*                           DBFFlushRecord()                           */
+/*                                                                      */
+/*      Write out the current record if there is one.                   */
+/************************************************************************/
+
+static void DBFFlushRecord( DBFHandle psDBF )
+
+{
+    int		nRecordOffset;
+
+    if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
+    {
+	psDBF->bCurrentRecordModified = FALSE;
+
+	nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord 
+	                                             + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+    }
+}
+
+/************************************************************************/
+/*                          DBFUpdateHeader()                           */
+/************************************************************************/
+
+void SHPAPI_CALL
+DBFUpdateHeader( DBFHandle psDBF )
+
+{
+    unsigned char		abyFileHeader[32];
+
+    if( psDBF->bNoHeader )
+        DBFWriteHeader( psDBF );
+
+    DBFFlushRecord( psDBF );
+
+    fseek( psDBF->fp, 0, 0 );
+    fread( abyFileHeader, 32, 1, psDBF->fp );
+    
+    abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
+    abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256);
+    abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256);
+    abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
+    
+    fseek( psDBF->fp, 0, 0 );
+    fwrite( abyFileHeader, 32, 1, psDBF->fp );
+
+    fflush( psDBF->fp );
+}
+
+/************************************************************************/
+/*                              DBFOpen()                               */
+/*                                                                      */
+/*      Open a .dbf file.                                               */
+/************************************************************************/
+   
+DBFHandle SHPAPI_CALL
+DBFOpen( const char * pszFilename, const char * pszAccess )
+
+{
+    DBFHandle		psDBF;
+    unsigned char		*pabyBuf;
+    int			nFields, nHeadLen, nRecLen, iField, i;
+    char		*pszBasename, *pszFullname;
+
+/* -------------------------------------------------------------------- */
+/*      We only allow the access strings "rb" and "r+".                  */
+/* -------------------------------------------------------------------- */
+    if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0 
+        && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0
+        && strcmp(pszAccess,"r+b") != 0 )
+        return( NULL );
+
+    if( strcmp(pszAccess,"r") == 0 )
+        pszAccess = "rb";
+ 
+    if( strcmp(pszAccess,"r+") == 0 )
+        pszAccess = "rb+";
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (char *) malloc(strlen(pszFilename)+5);
+    strcpy( pszBasename, pszFilename );
+    for( i = strlen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+	       && pszBasename[i] != '\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == '.' )
+        pszBasename[i] = '\0';
+
+    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
+    sprintf( pszFullname, "%s.dbf", pszBasename );
+        
+    psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
+    psDBF->fp = fopen( pszFullname, pszAccess );
+
+    if( psDBF->fp == NULL )
+    {
+        sprintf( pszFullname, "%s.DBF", pszBasename );
+        psDBF->fp = fopen(pszFullname, pszAccess );
+    }
+    
+    free( pszBasename );
+    free( pszFullname );
+    
+    if( psDBF->fp == NULL )
+    {
+        free( psDBF );
+        return( NULL );
+    }
+
+    psDBF->bNoHeader = FALSE;
+    psDBF->nCurrentRecord = -1;
+    psDBF->bCurrentRecordModified = FALSE;
+
+/* -------------------------------------------------------------------- */
+/*  Read Table Header info                                              */
+/* -------------------------------------------------------------------- */
+    pabyBuf = (unsigned char *) malloc(500);
+    if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
+    {
+        fclose( psDBF->fp );
+        free( pabyBuf );
+        free( psDBF );
+        return NULL;
+    }
+
+    psDBF->nRecords = 
+     pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
+
+    psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
+    psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
+    
+    psDBF->nFields = nFields = (nHeadLen - 32) / 32;
+
+    psDBF->pszCurrentRecord = (char *) malloc(nRecLen);
+
+/* -------------------------------------------------------------------- */
+/*  Read in Field Definitions                                           */
+/* -------------------------------------------------------------------- */
+    
+    pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
+    psDBF->pszHeader = (char *) pabyBuf;
+
+    fseek( psDBF->fp, 32, 0 );
+    if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
+    {
+        fclose( psDBF->fp );
+        free( pabyBuf );
+        free( psDBF );
+        return NULL;
+    }
+
+    psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields);
+    psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields);
+    psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields);
+    psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields);
+
+    for( iField = 0; iField < nFields; iField++ )
+    {
+	unsigned char		*pabyFInfo;
+
+	pabyFInfo = pabyBuf+iField*32;
+
+	if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
+	{
+	    psDBF->panFieldSize[iField] = pabyFInfo[16];
+	    psDBF->panFieldDecimals[iField] = pabyFInfo[17];
+	}
+	else
+	{
+	    psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
+	    psDBF->panFieldDecimals[iField] = 0;
+	}
+
+	psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
+	if( iField == 0 )
+	    psDBF->panFieldOffset[iField] = 1;
+	else
+	    psDBF->panFieldOffset[iField] = 
+	      psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
+    }
+
+    return( psDBF );
+}
+
+/************************************************************************/
+/*                              DBFClose()                              */
+/************************************************************************/
+
+void SHPAPI_CALL
+DBFClose(DBFHandle psDBF)
+{
+/* -------------------------------------------------------------------- */
+/*      Write out header if not already written.                        */
+/* -------------------------------------------------------------------- */
+    if( psDBF->bNoHeader )
+        DBFWriteHeader( psDBF );
+
+    DBFFlushRecord( psDBF );
+
+/* -------------------------------------------------------------------- */
+/*      Update last access date, and number of records if we have	*/
+/*	write access.                					*/
+/* -------------------------------------------------------------------- */
+    if( psDBF->bUpdated )
+        DBFUpdateHeader( psDBF );
+
+/* -------------------------------------------------------------------- */
+/*      Close, and free resources.                                      */
+/* -------------------------------------------------------------------- */
+    fclose( psDBF->fp );
+
+    if( psDBF->panFieldOffset != NULL )
+    {
+        free( psDBF->panFieldOffset );
+        free( psDBF->panFieldSize );
+        free( psDBF->panFieldDecimals );
+        free( psDBF->pachFieldType );
+    }
+
+    free( psDBF->pszHeader );
+    free( psDBF->pszCurrentRecord );
+
+    free( psDBF );
+}
+
+/************************************************************************/
+/*                             DBFCreate()                              */
+/*                                                                      */
+/*      Create a new .dbf file.                                         */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCreate( const char * pszFilename )
+
+{
+    DBFHandle	psDBF;
+    FILE	*fp;
+    char	*pszFullname, *pszBasename;
+    int		i;
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (char *) malloc(strlen(pszFilename)+5);
+    strcpy( pszBasename, pszFilename );
+    for( i = strlen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+	       && pszBasename[i] != '\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == '.' )
+        pszBasename[i] = '\0';
+
+    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
+    sprintf( pszFullname, "%s.dbf", pszBasename );
+    free( pszBasename );
+
+/* -------------------------------------------------------------------- */
+/*      Create the file.                                                */
+/* -------------------------------------------------------------------- */
+    fp = fopen( pszFullname, "wb" );
+    if( fp == NULL )
+        return( NULL );
+
+    fputc( 0, fp );
+    fclose( fp );
+
+    fp = fopen( pszFullname, "rb+" );
+    if( fp == NULL )
+        return( NULL );
+
+    free( pszFullname );
+
+/* -------------------------------------------------------------------- */
+/*	Create the info structure.					*/
+/* -------------------------------------------------------------------- */
+    psDBF = (DBFHandle) malloc(sizeof(DBFInfo));
+
+    psDBF->fp = fp;
+    psDBF->nRecords = 0;
+    psDBF->nFields = 0;
+    psDBF->nRecordLength = 1;
+    psDBF->nHeaderLength = 33;
+    
+    psDBF->panFieldOffset = NULL;
+    psDBF->panFieldSize = NULL;
+    psDBF->panFieldDecimals = NULL;
+    psDBF->pachFieldType = NULL;
+    psDBF->pszHeader = NULL;
+
+    psDBF->nCurrentRecord = -1;
+    psDBF->bCurrentRecordModified = FALSE;
+    psDBF->pszCurrentRecord = NULL;
+
+    psDBF->bNoHeader = TRUE;
+
+    return( psDBF );
+}
+
+/************************************************************************/
+/*                            DBFAddField()                             */
+/*                                                                      */
+/*      Add a field to a newly created .dbf file before any records     */
+/*      are written.                                                    */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFAddField(DBFHandle psDBF, const char * pszFieldName, 
+            DBFFieldType eType, int nWidth, int nDecimals )
+
+{
+    char	*pszFInfo;
+    int		i;
+
+/* -------------------------------------------------------------------- */
+/*      Do some checking to ensure we can add records to this file.     */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nRecords > 0 )
+        return( -1 );
+
+    if( !psDBF->bNoHeader )
+        return( -1 );
+
+    if( eType != FTDouble && nDecimals != 0 )
+        return( -1 );
+
+    if( nWidth < 1 )
+        return -1;
+
+/* -------------------------------------------------------------------- */
+/*      SfRealloc all the arrays larger to hold the additional field      */
+/*      information.                                                    */
+/* -------------------------------------------------------------------- */
+    psDBF->nFields++;
+
+    psDBF->panFieldOffset = (int *) 
+      SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
+
+    psDBF->panFieldSize = (int *) 
+      SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
+
+    psDBF->panFieldDecimals = (int *) 
+      SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
+
+    psDBF->pachFieldType = (char *) 
+      SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
+
+/* -------------------------------------------------------------------- */
+/*      Assign the new field information fields.                        */
+/* -------------------------------------------------------------------- */
+    psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
+    psDBF->nRecordLength += nWidth;
+    psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
+    psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
+
+    if( eType == FTLogical )
+        psDBF->pachFieldType[psDBF->nFields-1] = 'L';
+    else if( eType == FTString )
+        psDBF->pachFieldType[psDBF->nFields-1] = 'C';
+    else
+        psDBF->pachFieldType[psDBF->nFields-1] = 'N';
+
+/* -------------------------------------------------------------------- */
+/*      Extend the required header information.                         */
+/* -------------------------------------------------------------------- */
+    psDBF->nHeaderLength += 32;
+    psDBF->bUpdated = FALSE;
+
+    psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
+
+    pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1);
+
+    for( i = 0; i < 32; i++ )
+        pszFInfo[i] = '\0';
+
+    if( (int) strlen(pszFieldName) < 10 )
+        strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
+    else
+        strncpy( pszFInfo, pszFieldName, 10);
+
+    pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
+
+    if( eType == FTString )
+    {
+        pszFInfo[16] = (unsigned char) (nWidth % 256);
+        pszFInfo[17] = (unsigned char) (nWidth / 256);
+    }
+    else
+    {
+        pszFInfo[16] = (unsigned char) nWidth;
+        pszFInfo[17] = (unsigned char) nDecimals;
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      Make the current record buffer appropriately larger.            */
+/* -------------------------------------------------------------------- */
+    psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
+					       psDBF->nRecordLength);
+
+    return( psDBF->nFields-1 );
+}
+
+/************************************************************************/
+/*                          DBFReadAttribute()                          */
+/*                                                                      */
+/*      Read one of the attribute fields of a record.                   */
+/************************************************************************/
+
+static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
+                              char chReqType )
+
+{
+    int	       	nRecordOffset;
+    unsigned char	*pabyRec;
+    void	*pReturnField = NULL;
+
+    static double dDoubleField;
+    static char szStringField[257];
+
+/* -------------------------------------------------------------------- */
+/*      Verify selection.                                               */
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity >= psDBF->nRecords )
+        return( NULL );
+
+    if( iField < 0 || iField >= psDBF->nFields )
+        return( NULL );
+
+/* -------------------------------------------------------------------- */
+/*	Have we read the record?					*/
+/* -------------------------------------------------------------------- */
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
+        {
+            fprintf( stderr, "fseek(%d) failed on DBF file.\n",
+                     nRecordOffset );
+            return NULL;
+        }
+
+	if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 
+                   1, psDBF->fp ) != 1 )
+        {
+            fprintf( stderr, "fread(%d) failed on DBF file.\n",
+                     psDBF->nRecordLength );
+            return NULL;
+        }
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+/* -------------------------------------------------------------------- */
+/*	Extract the requested field.					*/
+/* -------------------------------------------------------------------- */
+    strncpy( szStringField, 
+	     ((const char *) pabyRec) + psDBF->panFieldOffset[iField],
+	     psDBF->panFieldSize[iField] );
+    szStringField[psDBF->panFieldSize[iField]] = '\0';
+
+    pReturnField = szStringField;
+
+/* -------------------------------------------------------------------- */
+/*      Decode the field.                                               */
+/* -------------------------------------------------------------------- */
+    if( chReqType == 'N' )
+    {
+        dDoubleField = atof(szStringField);
+
+	pReturnField = &dDoubleField;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Should we trim white space off the string attribute value?      */
+/* -------------------------------------------------------------------- */
+#ifdef TRIM_DBF_WHITESPACE
+    else
+    {
+        char	*pchSrc, *pchDst;
+
+        pchDst = pchSrc = szStringField;
+        while( *pchSrc == ' ' )
+            pchSrc++;
+
+        while( *pchSrc != '\0' )
+            *(pchDst++) = *(pchSrc++);
+        *pchDst = '\0';
+
+        while( pchDst != szStringField && *(--pchDst) == ' ' )
+            *pchDst = '\0';
+    }
+#endif
+    
+    return( pReturnField );
+}
+
+/************************************************************************/
+/*                        DBFReadIntAttribute()                         */
+/*                                                                      */
+/*      Read an integer attribute.                                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    double	*pdValue;
+
+    pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
+
+    if( pdValue == NULL )
+        return 0;
+    else
+        return( (int) *pdValue );
+}
+
+/************************************************************************/
+/*                        DBFReadDoubleAttribute()                      */
+/*                                                                      */
+/*      Read a double attribute.                                        */
+/************************************************************************/
+
+double SHPAPI_CALL
+DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    double	*pdValue;
+
+    pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
+
+    if( pdValue == NULL )
+        return 0.0;
+    else
+        return( *pdValue );
+}
+
+/************************************************************************/
+/*                        DBFReadStringAttribute()                      */
+/*                                                                      */
+/*      Read a string attribute.                                        */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) );
+}
+
+/************************************************************************/
+/*                        DBFReadLogicalAttribute()                     */
+/*                                                                      */
+/*      Read a logical attribute.                                       */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) );
+}
+
+/************************************************************************/
+/*                         DBFIsAttributeNULL()                         */
+/*                                                                      */
+/*      Return TRUE if value for field is NULL.                         */
+/*                                                                      */
+/*      Contributed by Jim Matthews.                                    */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    const char	*pszValue;
+    int i;
+
+    pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
+
+    if( pszValue == NULL )
+        return TRUE;
+
+    switch(psDBF->pachFieldType[iField])
+    {
+      case 'N':
+      case 'F':
+        /*
+        ** We accept all asterisks or all blanks as NULL 
+        ** though according to the spec I think it should be all 
+        ** asterisks. 
+        */
+        if( pszValue[0] == '*' )
+            return TRUE;
+
+        for( i = 0; pszValue[i] != '\0'; i++ )
+        {
+            if( pszValue[i] != ' ' )
+                return FALSE;
+        }
+        return TRUE;
+
+      case 'D':
+        /* NULL date fields have value "00000000" */
+        return strncmp(pszValue,"00000000",8) == 0;
+
+      case 'L':
+        /* NULL boolean fields have value "?" */ 
+        return pszValue[0] == '?';
+
+      default:
+        /* empty string fields are considered NULL */
+        return strlen(pszValue) == 0;
+    }
+}
+
+/************************************************************************/
+/*                          DBFGetFieldCount()                          */
+/*                                                                      */
+/*      Return the number of fields in this table.                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFGetFieldCount( DBFHandle psDBF )
+
+{
+    return( psDBF->nFields );
+}
+
+/************************************************************************/
+/*                         DBFGetRecordCount()                          */
+/*                                                                      */
+/*      Return the number of records in this table.                     */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFGetRecordCount( DBFHandle psDBF )
+
+{
+    return( psDBF->nRecords );
+}
+
+/************************************************************************/
+/*                          DBFGetFieldInfo()                           */
+/*                                                                      */
+/*      Return any requested information about the field.               */
+/************************************************************************/
+
+DBFFieldType SHPAPI_CALL
+DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName,
+                 int * pnWidth, int * pnDecimals )
+
+{
+    if( iField < 0 || iField >= psDBF->nFields )
+        return( FTInvalid );
+
+    if( pnWidth != NULL )
+        *pnWidth = psDBF->panFieldSize[iField];
+
+    if( pnDecimals != NULL )
+        *pnDecimals = psDBF->panFieldDecimals[iField];
+
+    if( pszFieldName != NULL )
+    {
+	int	i;
+
+	strncpy( pszFieldName, (char *) psDBF->pszHeader+iField*32, 11 );
+	pszFieldName[11] = '\0';
+	for( i = 10; i > 0 && pszFieldName[i] == ' '; i-- )
+	    pszFieldName[i] = '\0';
+    }
+
+    if ( psDBF->pachFieldType[iField] == 'L' )
+	return( FTLogical);
+
+    else if( psDBF->pachFieldType[iField] == 'N' 
+             || psDBF->pachFieldType[iField] == 'F'
+             || psDBF->pachFieldType[iField] == 'D' )
+    {
+	if( psDBF->panFieldDecimals[iField] > 0 
+            || psDBF->panFieldSize[iField] > 10 )
+	    return( FTDouble );
+	else
+	    return( FTInteger );
+    }
+    else
+    {
+	return( FTString );
+    }
+}
+
+/************************************************************************/
+/*                         DBFWriteAttribute()                          */
+/*									*/
+/*	Write an attribute record to the file.				*/
+/************************************************************************/
+
+static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
+			     void * pValue )
+
+{
+    int	       	nRecordOffset, i, j, nRetResult = TRUE;
+    unsigned char	*pabyRec;
+    char	szSField[400], szFormat[20];
+
+/* -------------------------------------------------------------------- */
+/*	Is this a valid record?						*/
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity > psDBF->nRecords )
+        return( FALSE );
+
+    if( psDBF->bNoHeader )
+        DBFWriteHeader(psDBF);
+
+/* -------------------------------------------------------------------- */
+/*      Is this a brand new record?                                     */
+/* -------------------------------------------------------------------- */
+    if( hEntity == psDBF->nRecords )
+    {
+	DBFFlushRecord( psDBF );
+
+	psDBF->nRecords++;
+	for( i = 0; i < psDBF->nRecordLength; i++ )
+	    psDBF->pszCurrentRecord[i] = ' ';
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Is this an existing record, but different than the last one     */
+/*      we accessed?                                                    */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+    psDBF->bCurrentRecordModified = TRUE;
+    psDBF->bUpdated = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*      Translate NULL value to valid DBF file representation.          */
+/*                                                                      */
+/*      Contributed by Jim Matthews.                                    */
+/* -------------------------------------------------------------------- */
+    if( pValue == NULL )
+    {
+        switch(psDBF->pachFieldType[iField])
+        {
+          case 'N':
+          case 'F':
+	    /* NULL numeric fields have value "****************" */
+            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*', 
+                    psDBF->panFieldSize[iField] );
+            break;
+
+          case 'D':
+	    /* NULL date fields have value "00000000" */
+            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0', 
+                    psDBF->panFieldSize[iField] );
+            break;
+
+          case 'L':
+	    /* NULL boolean fields have value "?" */ 
+            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?', 
+                    psDBF->panFieldSize[iField] );
+            break;
+
+          default:
+            /* empty string fields are considered NULL */
+            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0', 
+                    psDBF->panFieldSize[iField] );
+            break;
+        }
+        return TRUE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Assign all the record fields.                                   */
+/* -------------------------------------------------------------------- */
+    switch( psDBF->pachFieldType[iField] )
+    {
+      case 'D':
+      case 'N':
+      case 'F':
+	if( psDBF->panFieldDecimals[iField] == 0 )
+	{
+            int		nWidth = psDBF->panFieldSize[iField];
+
+            if( (int) sizeof(szSField)-2 < nWidth )
+                nWidth = sizeof(szSField)-2;
+
+	    sprintf( szFormat, "%%%dd", nWidth );
+	    sprintf(szSField, szFormat, (int) *((double *) pValue) );
+	    if( (int)strlen(szSField) > psDBF->panFieldSize[iField] )
+            {
+	        szSField[psDBF->panFieldSize[iField]] = '\0';
+                nRetResult = FALSE;
+            }
+
+	    strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
+		    szSField, strlen(szSField) );
+	}
+	else
+	{
+            int		nWidth = psDBF->panFieldSize[iField];
+
+            if( (int) sizeof(szSField)-2 < nWidth )
+                nWidth = sizeof(szSField)-2;
+
+	    sprintf( szFormat, "%%%d.%df", 
+                     nWidth, psDBF->panFieldDecimals[iField] );
+	    sprintf(szSField, szFormat, *((double *) pValue) );
+	    if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
+            {
+	        szSField[psDBF->panFieldSize[iField]] = '\0';
+                nRetResult = FALSE;
+            }
+	    strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
+		    szSField, strlen(szSField) );
+	}
+	break;
+
+      case 'L':
+        if (psDBF->panFieldSize[iField] >= 1  && 
+            (*(char*)pValue == 'F' || *(char*)pValue == 'T'))
+            *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue;
+        break;
+
+      default:
+	if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
+        {
+	    j = psDBF->panFieldSize[iField];
+            nRetResult = FALSE;
+        }
+	else
+        {
+            memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
+                    psDBF->panFieldSize[iField] );
+	    j = strlen((char *) pValue);
+        }
+
+	strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
+		(char *) pValue, j );
+	break;
+    }
+
+    return( nRetResult );
+}
+
+/************************************************************************/
+/*                     DBFWriteAttributeDirectly()                      */
+/*                                                                      */
+/*      Write an attribute record to the file, but without any          */
+/*      reformatting based on type.  The provided buffer is written     */
+/*      as is to the field position in the record.                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
+                              void * pValue )
+
+{
+    int	       	nRecordOffset, i, j;
+    unsigned char	*pabyRec;
+
+/* -------------------------------------------------------------------- */
+/*	Is this a valid record?						*/
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity > psDBF->nRecords )
+        return( FALSE );
+
+    if( psDBF->bNoHeader )
+        DBFWriteHeader(psDBF);
+
+/* -------------------------------------------------------------------- */
+/*      Is this a brand new record?                                     */
+/* -------------------------------------------------------------------- */
+    if( hEntity == psDBF->nRecords )
+    {
+	DBFFlushRecord( psDBF );
+
+	psDBF->nRecords++;
+	for( i = 0; i < psDBF->nRecordLength; i++ )
+	    psDBF->pszCurrentRecord[i] = ' ';
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Is this an existing record, but different than the last one     */
+/*      we accessed?                                                    */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+/* -------------------------------------------------------------------- */
+/*      Assign all the record fields.                                   */
+/* -------------------------------------------------------------------- */
+    if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] )
+        j = psDBF->panFieldSize[iField];
+    else
+    {
+        memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
+                psDBF->panFieldSize[iField] );
+        j = strlen((char *) pValue);
+    }
+
+    strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
+            (char *) pValue, j );
+
+    psDBF->bCurrentRecordModified = TRUE;
+    psDBF->bUpdated = TRUE;
+
+    return( TRUE );
+}
+
+/************************************************************************/
+/*                      DBFWriteDoubleAttribute()                       */
+/*                                                                      */
+/*      Write a double attribute.                                       */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField,
+                         double dValue )
+
+{
+    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
+}
+
+/************************************************************************/
+/*                      DBFWriteIntegerAttribute()                      */
+/*                                                                      */
+/*      Write a integer attribute.                                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField,
+                          int nValue )
+
+{
+    double	dValue = nValue;
+
+    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
+}
+
+/************************************************************************/
+/*                      DBFWriteStringAttribute()                       */
+/*                                                                      */
+/*      Write a string attribute.                                       */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField,
+                         const char * pszValue )
+
+{
+    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) pszValue ) );
+}
+
+/************************************************************************/
+/*                      DBFWriteNULLAttribute()                         */
+/*                                                                      */
+/*      Write a string attribute.                                       */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    return( DBFWriteAttribute( psDBF, iRecord, iField, NULL ) );
+}
+
+/************************************************************************/
+/*                      DBFWriteLogicalAttribute()                      */
+/*                                                                      */
+/*      Write a logical attribute.                                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField,
+		       const char lValue)
+
+{
+    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) );
+}
+
+/************************************************************************/
+/*                         DBFWriteTuple()                              */
+/*									*/
+/*	Write an attribute record to the file.				*/
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
+
+{
+    int	       	nRecordOffset, i;
+    unsigned char	*pabyRec;
+
+/* -------------------------------------------------------------------- */
+/*	Is this a valid record?						*/
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity > psDBF->nRecords )
+        return( FALSE );
+
+    if( psDBF->bNoHeader )
+        DBFWriteHeader(psDBF);
+
+/* -------------------------------------------------------------------- */
+/*      Is this a brand new record?                                     */
+/* -------------------------------------------------------------------- */
+    if( hEntity == psDBF->nRecords )
+    {
+	DBFFlushRecord( psDBF );
+
+	psDBF->nRecords++;
+	for( i = 0; i < psDBF->nRecordLength; i++ )
+	    psDBF->pszCurrentRecord[i] = ' ';
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Is this an existing record, but different than the last one     */
+/*      we accessed?                                                    */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+    memcpy ( pabyRec, pRawTuple,  psDBF->nRecordLength );
+
+    psDBF->bCurrentRecordModified = TRUE;
+    psDBF->bUpdated = TRUE;
+
+    return( TRUE );
+}
+
+/************************************************************************/
+/*                          DBFReadTuple()                              */
+/*                                                                      */
+/*      Read one of the attribute fields of a record.                   */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+DBFReadTuple(DBFHandle psDBF, int hEntity )
+
+{
+    int	       	nRecordOffset;
+    unsigned char	*pabyRec;
+    static char	*pReturnTuple = NULL;
+
+    static int	nTupleLen = 0;
+
+/* -------------------------------------------------------------------- */
+/*	Have we read the record?					*/
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity >= psDBF->nRecords )
+        return( NULL );
+
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+    if ( nTupleLen < psDBF->nRecordLength) {
+      nTupleLen = psDBF->nRecordLength;
+      pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength);
+    }
+    
+    memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength );
+        
+    return( pReturnTuple );
+}
+
+/************************************************************************/
+/*                          DBFCloneEmpty()                              */
+/*                                                                      */
+/*      Read one of the attribute fields of a record.                   */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ) 
+{
+    DBFHandle	newDBF;
+
+   newDBF = DBFCreate ( pszFilename );
+   if ( newDBF == NULL ) return ( NULL ); 
+   
+   newDBF->nFields = psDBF->nFields;
+   newDBF->nRecordLength = psDBF->nRecordLength;
+   newDBF->nHeaderLength = psDBF->nHeaderLength;
+    
+   newDBF->pszHeader = (char *) malloc ( newDBF->nHeaderLength );
+   memcpy ( newDBF->pszHeader, psDBF->pszHeader, newDBF->nHeaderLength );
+   
+   newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields ); 
+   memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
+   newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields );
+   memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
+   newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields );
+   memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
+   newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields );
+   memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields );
+
+   newDBF->bNoHeader = TRUE;
+   newDBF->bUpdated = TRUE;
+   
+   DBFWriteHeader ( newDBF );
+   DBFClose ( newDBF );
+   
+   newDBF = DBFOpen ( pszFilename, "rb+" );
+
+   return ( newDBF );
+}
+
+/************************************************************************/
+/*                       DBFGetNativeFieldType()                        */
+/*                                                                      */
+/*      Return the DBase field type for the specified field.            */
+/*                                                                      */
+/*      Value can be one of: 'C' (String), 'D' (Date), 'F' (Float),     */
+/*                           'N' (Numeric, with or without decimal),    */
+/*                           'L' (Logical),                             */
+/*                           'M' (Memo: 10 digits .DBT block ptr)       */
+/************************************************************************/
+
+char SHPAPI_CALL
+DBFGetNativeFieldType( DBFHandle psDBF, int iField )
+
+{
+    if( iField >=0 && iField < psDBF->nFields )
+        return psDBF->pachFieldType[iField];
+
+    return  ' ';
+}
+
+/************************************************************************/
+/*                            str_to_upper()                            */
+/************************************************************************/
+
+static void str_to_upper (char *string)
+{
+    int len;
+    short i = -1;
+
+    len = strlen (string);
+
+    while (++i < len)
+        if (isalpha(string[i]) && islower(string[i]))
+            string[i] = (char) toupper ((int)string[i]);
+}
+
+/************************************************************************/
+/*                          DBFGetFieldIndex()                          */
+/*                                                                      */
+/*      Get the index number for a field in a .dbf file.                */
+/*                                                                      */
+/*      Contributed by Jim Matthews.                                    */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
+
+{
+    char          name[12], name1[12], name2[12];
+    int           i;
+
+    strncpy(name1, pszFieldName,11);
+    name1[11] = '\0';
+    str_to_upper(name1);
+
+    for( i = 0; i < DBFGetFieldCount(psDBF); i++ )
+    {
+        DBFGetFieldInfo( psDBF, i, name, NULL, NULL );
+        strncpy(name2,name,11);
+        str_to_upper(name2);
+
+        if(!strncmp(name1,name2,10))
+            return(i);
+    }
+    return(-1);
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeDatabase.cpp b/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeDatabase.cpp
new file mode 100644
index 0000000000..6cd3bd232f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeDatabase.cpp
@@ -0,0 +1,265 @@
+#include "ossimShapeDatabase.h"
+#include "ossimShapeFile.h"
+
+
+
+ossimString ossimShapeDatabaseField::fieldTypeAsString()const
+{
+   switch(theFieldType)
+   {
+   case FTString:
+   {
+      return "String";
+   }
+   case FTInteger:
+   {
+      return "Integer";
+   }
+   case FTDouble:
+   {
+      return "Double";
+   }
+   default:
+   {
+      return "Unknown";
+   }
+   };
+
+   return "";
+   
+}
+
+
+ossim_int32 ossimShapeDatabaseRecord::getFieldIdx(const ossimString& name,
+                                                  bool caseInsensitive)const
+{
+   ossimString searchString = name;
+   if(caseInsensitive) searchString = searchString.downcase();
+   ossim_int32 idx = 0;
+   for(idx = 0; idx < (int)theFieldArray.size(); ++idx)
+   {
+      if(caseInsensitive)
+      {
+         if(ossimString(theFieldArray[idx].theName).downcase() == searchString)
+         {
+            return idx;
+         }
+      }
+      else
+      {
+         if(theFieldArray[idx].theName == searchString)
+         {
+            return idx;
+         }
+      }
+   }
+   return -1;
+}
+
+ossimShapeDatabase::ossimShapeDatabase()
+   :theHandle(NULL),
+    theFilename("")
+{
+   theRecordNumber = -1;
+}
+
+ossimShapeDatabase::~ossimShapeDatabase()
+{
+   close();
+}
+
+bool ossimShapeDatabase::open(const ossimFilename& file,
+                              const ossimString& flags)
+{
+   if(isOpen()) close();
+
+   theHandle = DBFOpen(file.c_str(), flags.c_str());
+   if(theHandle)
+   {
+      theFilename = file;
+      theRecordNumber = -1;
+   }
+
+   return (theHandle != NULL);
+}
+
+void ossimShapeDatabase::close()
+{
+   if(isOpen())
+   {
+      DBFClose(theHandle);
+      theHandle = NULL;
+      theRecordNumber = -1;
+   }
+}
+int ossimShapeDatabase::getNumberOfRecords()const
+{
+   if(isOpen())
+   {
+      return theHandle->nRecords;
+   }
+
+   return 0;
+}
+bool ossimShapeDatabase::getRecord(ossimShapeDatabaseRecord& result)
+{
+   if(isOpen()&&( (theRecordNumber < theHandle->nRecords) ))
+   {
+      if(result.getNumberOfFields() != theHandle->nFields)
+      {
+         result.setNumberOfFields(theHandle->nFields);
+      }
+      
+      char name[1024] = {'\0'};
+      int width       = 0;
+      int decimals    = 0;
+      int iField      = 0;
+      vector<int>         fieldWidths;
+      
+      for(iField = 0; iField < theHandle->nFields; ++iField)
+      {   
+         DBFFieldType fieldType = DBFGetFieldInfo(theHandle,
+                                                  iField,
+                                                  name,
+                                                  &width,
+                                                  &decimals);
+         ossimShapeDatabaseField field;
+         field.theName = name;
+         field.theWidth = width;
+         field.theDecimals = decimals;
+         field.theFieldType = fieldType;
+            
+         ossimString key = "field";
+         key+=ossimString::toString(iField+1);
+         key+=(ossimString(".")+name+":");
+         
+         switch(fieldType)
+         {
+         case FTString:
+         {
+            field.theValue = DBFReadStringAttribute(theHandle, theRecordNumber, iField);
+            break;
+         }
+         case FTInteger:
+         {
+            field.theValue = ossimString::toString(DBFReadIntegerAttribute(theHandle, theRecordNumber, iField));
+            break;
+         }
+         case FTDouble:
+         {
+            field.theValue = ossimString::toString(DBFReadDoubleAttribute(theHandle, theRecordNumber, iField));
+            break;
+         }
+		 case FTLogical:
+		 {
+			 break;
+		 }
+		 case FTInvalid:
+		 {
+			 break;
+		 }
+         }
+
+         result.setField(field,
+                         iField);
+      }
+      return true;
+   }
+
+   return false;
+}
+
+void ossimShapeDatabase::print(std::ostream& out)const
+{
+   if(isOpen())
+   {
+      out << setw(15)<<setiosflags(ios::left)
+          <<"DB filename:" << theFilename << endl
+          << setw(15)<<setiosflags(ios::left)
+          <<"records:" << theHandle->nRecords << endl
+          << setw(15)<<setiosflags(ios::left)
+          <<"fields:" << theHandle->nFields << endl;
+
+      char name[1024] = {'\0'};
+      int width       = 0;
+      int decimals    = 0;
+      int iField      = 0;
+      vector<int>         fieldWidths;
+
+      
+      for(iField = 0; iField < theHandle->nFields; ++iField)
+      {
+         DBFFieldType fieldType = DBFGetFieldInfo(theHandle,
+                                                  iField,
+                                                  name,
+                                                  &width,
+                                                  &decimals);
+         ossimString s = "field " + ossimString::toString(iField+1) + " name:";
+         switch(fieldType)
+         {
+         case FTString:
+         case FTInteger:
+         case FTDouble:
+         {
+            out << setw(15) << setiosflags(ios::left) << s.c_str() << name << endl;
+            break;
+         }
+         default:
+         {
+            out << setw(15) << setiosflags(ios::left) << s.c_str() << "INVALID"<<endl;
+            break;
+         }
+         }
+      }
+      for(int iShape = 0; iShape < theHandle->nRecords; ++iShape)
+      {
+         for(iField = 0; iField < theHandle->nFields; ++iField)
+         {   
+            DBFFieldType fieldType = DBFGetFieldInfo(theHandle,
+                                                     iField,
+                                                     name,
+                                                     &width,
+                                                     &decimals);
+            
+            ossimString key = "field";
+            key+=ossimString::toString(iField+1);
+            key+=(ossimString(".")+name+":");
+            
+            switch(fieldType)
+            {
+            case FTString:
+            {
+               
+               out << setw(25) << setiosflags(ios::left) << key.c_str()
+                   << DBFReadStringAttribute(theHandle, iShape, iField) <<endl;
+               
+               break;
+            }
+            case FTInteger:
+            {
+               out << setw(25) << setiosflags(ios::left) << key.c_str()
+                   << DBFReadIntegerAttribute(theHandle, iShape, iField) << endl;
+               
+               break;
+            }
+            case FTDouble:
+            {
+               out << setw(25) << setiosflags(ios::left) << key.c_str()
+                   << DBFReadDoubleAttribute(theHandle, iShape, iField) << endl;
+               
+               break;
+            }
+			case FTLogical:
+			{
+				break;
+			}
+			case FTInvalid:
+			{
+				break;
+			}
+            }
+         }
+         out << "_________________________________"<<endl;
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeDatabase.h b/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeDatabase.h
new file mode 100644
index 0000000000..9854996423
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeDatabase.h
@@ -0,0 +1,136 @@
+#ifndef ossimShapeDatabase_HEADER
+#define ossimShapeDatabase_HEADER
+#include <iostream>
+#include "shapefil.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimString.h"
+
+
+class ossimShapeDatabaseField
+{
+public:
+   ossimString fieldTypeAsString()const;
+   
+   ossimString  theName;
+   int         theWidth;
+   int         theDecimals;
+   DBFFieldType theFieldType;
+   ossimString  theValue;
+};
+
+class ossimShapeDatabaseRecord
+{
+   
+public:
+   bool getField(ossimShapeDatabaseField& result,
+                 ossim_uint32 i)
+      {
+         if(i < theFieldArray.size())
+         {
+            result = theFieldArray[i];
+            return true;
+         }
+         return false;
+      }
+   bool setField(const ossimShapeDatabaseField& field,
+                 ossim_uint32 i)
+      {
+         if(i < theFieldArray.size())
+         {
+            theFieldArray[i] = field;
+            return true;
+         }
+         return false;
+      }
+   int getNumberOfFields()const
+      {
+         return theFieldArray.size();
+      }
+   void setNumberOfFields(int n)
+      {
+         if(n)
+         {
+            theFieldArray.resize(n);
+         }
+         else
+         {
+            theFieldArray.clear();
+         }
+      }
+   ossim_int32 getFieldIdx(const ossimString& name,
+                           bool caseInsensitive=true)const;
+protected:
+	std::vector<ossimShapeDatabaseField> theFieldArray;
+};
+
+class ossimShapeDatabase
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimShapeDatabase& rhs)
+      {
+         rhs.print(out);
+         
+         return out;
+      }
+   
+   ossimShapeDatabase();
+   virtual ~ossimShapeDatabase();
+   
+   virtual bool open(const ossimFilename& file,
+                     const ossimString& flags=ossimString("rb"));
+   
+   virtual void close();
+   
+   bool getRecord(ossimShapeDatabaseRecord& result);
+   
+   bool getRecord(ossimShapeDatabaseRecord& result,
+                  int recordNumber)
+      {
+         if(isOpen())
+         {
+            if(recordNumber < getNumberOfRecords())
+            {
+               theRecordNumber = recordNumber;
+               return getRecord(result);
+            }
+         }
+
+         return false;
+      }
+   
+   bool getNextRecord(ossimShapeDatabaseRecord& result)
+      {
+         if(isOpen() && ((theRecordNumber+1) < getNumberOfRecords()))
+         {
+            ++theRecordNumber;
+            return getRecord(result);
+         }
+
+         return false;
+      }
+
+   int getNumberOfRecords()const;
+   bool isOpen()const
+      {
+         return (theHandle!=NULL);
+      }
+   virtual DBFHandle getHandle()
+      {
+         return theHandle;
+      }
+
+   virtual const DBFHandle getHandle()const
+      {
+         return theHandle;
+      }
+   
+   virtual void print(std::ostream& out)const;
+
+protected:
+   DBFHandle theHandle;
+   ossimFilename theFilename;
+
+   int theRecordNumber;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeFile.cpp b/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeFile.cpp
new file mode 100644
index 0000000000..91ce833fd3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeFile.cpp
@@ -0,0 +1,232 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimShapeFile.cpp,v 1.7 2004/04/08 13:49:55 gpotts Exp $
+//
+#include <vec/shape/ossimShapeFile.h>
+
+
+
+ostream& operator<<(ostream& out,
+                    const ossimShapeObject& rhs)
+{
+   if(rhs.isLoaded())
+   {
+      double minx, miny, minz, minm;
+      double maxx, maxy, maxz, maxm;
+      ossim_uint32 i = 0;
+      
+      rhs.getBounds(minx, miny, minz, minm,
+                    maxx, maxy, maxz, maxm);
+      
+      out << setw(15) << setiosflags(ios::left)<<"type:"<<rhs.getTypeByName() << endl
+          << setw(15) << setiosflags(ios::left)<<"id:"<<rhs.getId()<<endl
+          << setw(15) << setiosflags(ios::left)<<"minx:"<<minx <<endl
+          << setw(15) << setiosflags(ios::left)<<"miny:"<<miny <<endl
+          << setw(15) << setiosflags(ios::left)<<"minz:"<<minz <<endl
+          << setw(15) << setiosflags(ios::left)<<"minm:"<<minm <<endl
+          << setw(15) << setiosflags(ios::left)<<"maxx:"<<maxx <<endl
+          << setw(15) << setiosflags(ios::left)<<"maxy:"<<maxy <<endl
+          << setw(15) << setiosflags(ios::left)<<"maxz:"<<maxz <<endl
+          << setw(15) << setiosflags(ios::left)<<"maxm:"<<maxm <<endl
+          << setw(15) << setiosflags(ios::left)<<"parts:"<<rhs.getNumberOfParts()<<endl
+          << setw(15) << setiosflags(ios::left)<<"vertices:"<<rhs.getNumberOfVertices();
+
+      if(rhs.getNumberOfParts())
+      {
+         out << endl;
+         for(i = 0; i < rhs.getNumberOfParts()-1; ++i)
+         {
+            ossimString s1 = "part start ";
+            ossimString s2 = "part type ";
+            s1 += (ossimString::toString(i+1)+":");
+            s2 += (ossimString::toString(i+1)+":");
+            
+            out << setw(15) << setiosflags(ios::left) << s1.c_str() << rhs.theShape->panPartStart[i]<<endl;
+            out << setw(15) << setiosflags(ios::left) << s2.c_str() <<  SHPPartTypeName(rhs.theShape->panPartType[i])<<endl;
+         }
+         ossimString s1 = "part start ";
+         ossimString s2 = "part type ";
+         
+         s1 += (ossimString::toString(rhs.getNumberOfParts())+":");
+         out << setw(15) << setiosflags(ios::left) << s1.c_str() <<  rhs.theShape->panPartStart[i]<<endl;
+         out << setw(15) << setiosflags(ios::left) << s2.c_str() <<  SHPPartTypeName(rhs.theShape->panPartType[i]);
+      }
+
+      out << setw(0);
+      
+   }
+   return out;   
+}
+
+void ossimShapeObject::getBoundingRect(ossimDrect& result,
+                                       ossimCoordSysOrientMode orient)const
+{
+   double minx, miny, maxx, maxy;
+
+   if(theShape)
+   {
+      getBounds(minx, miny, maxx, maxy);
+      
+      if(orient == OSSIM_RIGHT_HANDED)
+      {
+         result = ossimDrect(minx, maxy, maxx, miny, orient);
+      }
+      else
+      {
+         result = ossimDrect(minx, miny, maxx, maxy, orient);         
+      }
+   }
+   else
+   {
+      result = ossimDrect(0,0,0,0,orient);
+      result.makeNan();
+   }
+}
+
+void ossimShapeObject::setShape(SHPObject* obj)
+{
+   if(theShape)
+   {
+      SHPDestroyObject(theShape);
+      theShape = NULL;            
+   }
+   
+   theShape = obj;
+}
+
+bool ossimShapeObject::loadShape(const ossimShapeFile& shapeFile,
+                                 long shapeRecord)
+{
+   if(theShape)
+   {
+      SHPDestroyObject(theShape);
+      theShape = NULL;            
+   }
+   if(shapeFile.isOpen())
+   {
+      theShape = SHPReadObject(shapeFile.getHandle(),
+                               shapeRecord);
+      theIndex = shapeRecord;
+   }
+   else
+   {
+      theIndex = -1;
+   }
+   return (theShape != (SHPObject*)NULL);
+}
+
+
+ossimShapeFile::ossimShapeFile()
+   :theHandle(NULL)
+{
+}
+
+ossimShapeFile::~ossimShapeFile()
+{
+   close();
+}
+
+void ossimShapeFile::close()
+{
+   if(theHandle)
+   {
+      SHPClose(theHandle);
+      theHandle = NULL;
+   }
+}
+
+bool ossimShapeFile::open(const ossimFilename& file,
+                          const ossimString& flags)
+{
+   if(isOpen()) close();
+   
+   theHandle = SHPOpen( file.c_str(),
+                        flags.c_str());
+   if(isOpen())
+   {
+      theFilename = file;
+   }
+   
+   return (theHandle != NULL);
+}
+
+
+
+void ossimShapeFile::print(std::ostream& out)const
+{
+   if(isOpen())
+   {
+      out << setw(15) << setiosflags(ios::left)<<"Shp filename:" << theFilename << endl;
+      out << setw(15) << setiosflags(ios::left)<<"Record count:" << theHandle->nRecords << endl;
+      out << setw(15) << setiosflags(ios::left)<<"File type:" << getShapeTypeString().c_str() << endl;
+      out << setw(15) << setiosflags(ios::left)<<"minx:" << theHandle->adBoundsMin[0] << endl;
+      out << setw(15) << setiosflags(ios::left)<<"miny:" << theHandle->adBoundsMin[1] << endl;
+      out << setw(15) << setiosflags(ios::left)<<"minz:" << theHandle->adBoundsMin[2] << endl;
+      out << setw(15) << setiosflags(ios::left)<<"minm:" << theHandle->adBoundsMin[3] << endl;
+      out << setw(15) << setiosflags(ios::left)<<"maxx:" << theHandle->adBoundsMax[0] << endl;
+      out << setw(15) << setiosflags(ios::left)<<"maxy:" << theHandle->adBoundsMax[1] << endl;
+      out << setw(15) << setiosflags(ios::left)<<"maxz:" << theHandle->adBoundsMax[2] << endl;
+      out << setw(15) << setiosflags(ios::left)<<"maxm:" << theHandle->adBoundsMax[3] << endl;
+
+      ossimShapeObject shape;
+
+      if(theHandle->nRecords)
+      {
+         out << setw(30) << setfill('_') << "" << setfill(' ')<<endl;
+      }
+      for(int i=0; i < theHandle->nRecords; ++i)
+      {
+         if(shape.loadShape(*this, i))
+         {
+            out << shape << endl;
+            out << setw(30) << setfill('_') << ""<<setfill(' ')<<endl;
+         }
+      }
+   }
+}
+
+
+ossimString ossimShapeFile::getShapeTypeString()const
+{
+   if(theHandle)
+   {
+      return SHPTypeName(theHandle->nShapeType);
+   }
+   return "";
+}
+
+void ossimShapeFile::getBoundingRect(ossimDrect& result,
+                                     ossimCoordSysOrientMode orient)const
+{
+   double minx, miny, maxx, maxy;
+   
+   getBounds(minx, miny, maxx, maxy);
+   if(orient == OSSIM_RIGHT_HANDED)
+   {
+      result = ossimDrect(minx, maxy, maxx, miny, orient);
+   }
+   else
+   {
+      result = ossimDrect(minx, miny, maxx, maxy, orient);         
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeFile.h b/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeFile.h
new file mode 100644
index 0000000000..09baca0251
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/shape/ossimShapeFile.h
@@ -0,0 +1,327 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks)
+// Description:
+//
+//*************************************************************************
+// $Id: ossimShapeFile.h,v 1.12 2004/04/08 13:49:55 gpotts Exp $
+
+#ifndef ossimShapeFile_HEADER
+#define ossimShapeFile_HEADER
+#include <iostream>
+#include <base/common/ossimConstants.h>
+#include <base/data_types/ossimFilename.h>
+#include <base/data_types/ossimString.h>
+#include <base/data_types/ossimDrect.h>
+
+#include "shapefil.h"
+
+class ossimShapeFile;
+class ossimAnnotationObject;
+
+class OSSIMDLLEXPORT ossimShapeObject
+{
+public:
+   friend ostream& operator<<(ostream& out,
+                              const ossimShapeObject& rhs);
+   
+   ossimShapeObject()
+      :theShape((SHPObject*)NULL),
+       theIndex(-1)
+      {
+      }
+
+   ~ossimShapeObject()
+      {
+         if(theShape)
+         {
+            SHPDestroyObject(theShape);
+            theShape = NULL;
+         }
+      }
+   void setShape(SHPObject* obj);
+   bool isLoaded()const
+      {
+         return (theShape!=NULL);
+      }
+   long getIndex()const
+      {
+         return theIndex;
+      }
+   long getId()const
+      {
+         if(theShape)
+         {
+            return theShape->nShapeId;
+         }
+         
+         return -1;
+      }
+   
+   bool loadShape(const ossimShapeFile& shapeFile,
+                  long shapeRecord);
+   
+   ossim_uint32 getNumberOfParts()const
+      {
+         if(theShape)
+         {
+            return theShape->nParts;
+         }
+
+         return 0;
+      }
+   ossim_uint32 getNumberOfVertices()const
+      {
+         if(theShape)
+         {
+            return theShape->nVertices;
+         }
+         
+         return 0;
+      }
+
+   void getBounds(double& minX, double& minY, double& minZ, double& minM,
+                  double& maxX, double& maxY, double& maxZ, double& maxM)const
+      {
+         if(theShape)
+         {
+            minX = theShape->dfXMin;
+            minY = theShape->dfYMin;
+            minZ = theShape->dfZMin;
+            minM = theShape->dfMMin;
+            maxX = theShape->dfXMax;
+            maxY = theShape->dfYMax;
+            maxZ = theShape->dfZMax;
+            maxM = theShape->dfMMax;
+         }
+         else
+         {
+            minX = minY = minZ = minM =
+            maxX = maxY = maxZ = maxM = OSSIM_DBL_NAN;
+         }
+      }
+
+   void getBounds(double& minX, double& minY,
+                  double& maxX, double& maxY)const
+      {
+         if(theShape)
+         {
+            minX = theShape->dfXMin;
+            minY = theShape->dfYMin;
+            maxX = theShape->dfXMax;
+            maxY = theShape->dfYMax;
+         }
+         else
+         {
+            minX = minY = 
+            maxX = maxY = OSSIM_DBL_NAN;
+         }
+      }
+
+   void getBoundingRect(ossimDrect& result,
+                        ossimCoordSysOrientMode orient = OSSIM_RIGHT_HANDED)const;
+
+   ossimDrect getBoundingRect(ossimCoordSysOrientMode orient = OSSIM_RIGHT_HANDED)const
+      {
+         ossimDrect result;
+         
+         getBoundingRect(result, orient);
+
+         return result;
+      }
+
+   int getType()const
+      {
+         if(theShape)
+         {
+            return theShape->nSHPType;
+         }
+         return SHPT_NULL;
+      }
+   ossimString getTypeByName()const
+      {
+         if(theShape)
+         {
+            return ossimString(SHPTypeName(theShape->nSHPType));
+         }
+         return "unknown";
+      }
+   int getPartType(ossim_uint32 partIndex)const
+      {
+         if((partIndex > getNumberOfParts())||
+            (!theShape))
+         {
+            return -1;
+         }
+
+         return theShape->panPartType[partIndex];
+      }
+   ossimString getPartByName(ossim_uint32 partIndex)const
+      {
+         if((partIndex > getNumberOfParts())||
+            (!theShape))
+         {
+         }
+         switch(theShape->panPartType[partIndex])
+         {
+         case SHPP_TRISTRIP:
+         {
+            ossimString("tristrip");
+            break;
+         }
+         case SHPP_TRIFAN:
+         {
+            ossimString("trifan");
+            break;
+         }
+         case SHPP_OUTERRING:
+         {
+            ossimString("outerring");
+            break;
+         }
+         case SHPP_INNERRING:
+         {
+            ossimString("innerring");
+            break;
+         }
+         case SHPP_RING:
+         {
+            ossimString("ring");
+            break;
+         }
+         }
+         return ossimString("unknown");
+      }
+   SHPObject* getShapeObject()
+      {
+         return theShape;
+      }
+   const SHPObject* getShapeObject()const
+      {
+         return theShape;
+      }
+
+   
+protected:
+   SHPObject* theShape;
+   long       theIndex;
+};
+
+class OSSIMDLLEXPORT ossimShapeFile
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimShapeFile& rhs)
+      {
+         rhs.print(out);
+         
+         return out;
+      }
+   
+   ossimShapeFile();
+   virtual ~ossimShapeFile();
+   
+   virtual bool open(const ossimFilename& file,
+                     const ossimString& flags=ossimString("rb"));
+   
+   virtual void close();
+   bool isOpen()const
+      {
+         return (theHandle!=NULL);
+      }
+   virtual SHPHandle getHandle()
+      {
+         return theHandle;
+      }
+
+   virtual const SHPHandle getHandle()const
+      {
+         return theHandle;
+      }
+   
+   virtual void print(std::ostream& out)const;
+   virtual ossimString getShapeTypeString()const;
+
+   
+   virtual long getNumberOfShapes()const
+      {
+         if(theHandle)
+         {
+            return theHandle->nRecords;
+         }
+         return 0;
+      }
+   void getBounds(double& minX, double& minY, double& minZ, double& minM,
+                  double& maxX, double& maxY, double& maxZ, double& maxM)const
+      {
+         if(theHandle)
+         {
+            minX = theHandle->adBoundsMin[0];
+            minY = theHandle->adBoundsMin[1];
+            minZ = theHandle->adBoundsMin[2];
+            minM = theHandle->adBoundsMin[3];
+            maxX = theHandle->adBoundsMax[0];
+            maxY = theHandle->adBoundsMax[1];
+            maxZ = theHandle->adBoundsMax[2];
+            maxM = theHandle->adBoundsMax[3];
+         }
+         else
+         {
+            minX = minY = minZ = minM =
+            maxX = maxY = maxZ = maxM = OSSIM_DBL_NAN;
+         }
+      }
+   
+   void getBounds(double& minX, double& minY,
+                  double& maxX, double& maxY)const
+      {
+         if(theHandle)
+         {
+            minX = theHandle->adBoundsMin[0];
+            minY = theHandle->adBoundsMin[1];
+            maxX = theHandle->adBoundsMax[0];
+            maxY = theHandle->adBoundsMax[1];
+         }
+         else
+         {
+            minX = minY = maxX = maxY = OSSIM_DBL_NAN;
+         }
+      }
+
+   void getBoundingRect(ossimDrect& result,
+                        ossimCoordSysOrientMode orient = OSSIM_RIGHT_HANDED)const;
+   
+   ossimDrect getBoundingRect(ossimCoordSysOrientMode orient = OSSIM_RIGHT_HANDED)const
+      {
+         ossimDrect result;
+         
+         getBoundingRect(result, orient);
+         
+         return result;
+      }
+   const ossimFilename& getFilename()const
+      {
+         return theFilename;
+      }
+protected:
+   SHPHandle	 theHandle;
+   ossimFilename theFilename;
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/shape/shapefil.h b/Utilities/OSSIM/ossim_core/vec/shape/shapefil.h
new file mode 100644
index 0000000000..e5d99be6ee
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/shape/shapefil.h
@@ -0,0 +1,528 @@
+#ifndef _SHAPEFILE_H_INCLUDED
+#define _SHAPEFILE_H_INCLUDED
+
+/******************************************************************************
+ * $Id: shapefil.h,v 1.5 2005/10/08 12:57:26 gpotts Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Primary include file for Shapelib.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shapefil.h,v $
+ * Revision 1.5  2005/10/08 12:57:26  gpotts
+ * Added adiitional patches
+ *
+ * Revision 1.14  2005/03/14 15:21:29  fwarmerdam
+ * updated
+ *
+ * Revision 1.30  2005/01/03 22:30:13  fwarmerdam
+ * added support for saved quadtrees
+ *
+ * Revision 1.29  2004/09/26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
+ * Revision 1.28  2003/12/29 06:02:18  fwarmerdam
+ * added cpl_error.h option
+ *
+ * Revision 1.27  2003/04/21 18:30:37  warmerda
+ * added header write/update public methods
+ *
+ * Revision 1.26  2002/09/29 00:00:08  warmerda
+ * added FTLogical and logical attribute read/write calls
+ *
+ * Revision 1.25  2002/05/07 13:46:30  warmerda
+ * added DBFWriteAttributeDirectly().
+ *
+ * Revision 1.24  2002/04/10 16:59:54  warmerda
+ * added SHPRewindObject
+ *
+ * Revision 1.23  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.22  2002/01/15 14:32:00  warmerda
+ * try to improve SHPAPI_CALL docs
+ *
+ * Revision 1.21  2001/11/01 16:29:55  warmerda
+ * move pabyRec into SHPInfo for thread safety
+ *
+ * Revision 1.20  2001/07/20 13:06:02  warmerda
+ * fixed SHPAPI attribute for SHPTreeFindLikelyShapes
+ *
+ * Revision 1.19  2001/05/31 19:20:13  warmerda
+ * added DBFGetFieldIndex()
+ *
+ * Revision 1.18  2001/05/31 18:15:40  warmerda
+ * Added support for NULL fields in DBF files
+ *
+ * Revision 1.17  2001/05/23 13:36:52  warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.16  2000/09/25 14:15:59  warmerda
+ * added DBFGetNativeFieldType()
+ *
+ * Revision 1.15  2000/02/16 16:03:51  warmerda
+ * added null shape support
+ *
+ * Revision 1.14  1999/11/05 14:12:05  warmerda
+ * updated license terms
+ *
+ * Revision 1.13  1999/06/02 18:24:21  warmerda
+ * added trimming code
+ *
+ * Revision 1.12  1999/06/02 17:56:12  warmerda
+ * added quad'' subnode support for trees
+ *
+ * Revision 1.11  1999/05/18 19:11:11  warmerda
+ * Added example searching capability
+ *
+ * Revision 1.10  1999/05/18 17:49:38  warmerda
+ * added initial quadtree support
+ *
+ * Revision 1.9  1999/05/11 03:19:28  warmerda
+ * added new Tuple api, and improved extension handling - add from candrsn
+ *
+ * Revision 1.8  1999/03/23 17:22:27  warmerda
+ * Added extern "C" protection for C++ users of shapefil.h.
+ *
+ * Revision 1.7  1998/12/31 15:31:07  warmerda
+ * Added the TRIM_DBF_WHITESPACE and DISABLE_MULTIPATCH_MEASURE options.
+ *
+ * Revision 1.6  1998/12/03 15:48:15  warmerda
+ * Added SHPCalculateExtents().
+ *
+ * Revision 1.5  1998/11/09 20:57:16  warmerda
+ * Altered SHPGetInfo() call.
+ *
+ * Revision 1.4  1998/11/09 20:19:33  warmerda
+ * Added 3D support, and use of SHPObject.
+ *
+ * Revision 1.3  1995/08/23 02:24:05  warmerda
+ * Added support for reading bounds.
+ *
+ * Revision 1.2  1995/08/04  03:17:39  warmerda
+ * Added header.
+ *
+ */
+
+#include <stdio.h>
+
+#ifdef USE_DBMALLOC
+#include <dbmalloc.h>
+#endif
+
+#ifdef USE_CPL
+#include "cpl_error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************************************************************/
+/*                        Configuration options.                        */
+/************************************************************************/
+
+/* -------------------------------------------------------------------- */
+/*      Should the DBFReadStringAttribute() strip leading and           */
+/*      trailing white space?                                           */
+/* -------------------------------------------------------------------- */
+#define TRIM_DBF_WHITESPACE
+
+/* -------------------------------------------------------------------- */
+/*      Should we write measure values to the Multipatch object?        */
+/*      Reportedly ArcView crashes if we do write it, so for now it     */
+/*      is disabled.                                                    */
+/* -------------------------------------------------------------------- */
+#define DISABLE_MULTIPATCH_MEASURE
+
+/* -------------------------------------------------------------------- */
+/*      SHPAPI_CALL                                                     */
+/*                                                                      */
+/*      The following two macros are present to allow forcing           */
+/*      various calling conventions on the Shapelib API.                */
+/*                                                                      */
+/*      To force __stdcall conventions (needed to call Shapelib         */
+/*      from Visual Basic and/or Dephi I believe) the makefile could    */
+/*      be modified to define:                                          */
+/*                                                                      */
+/*        /DSHPAPI_CALL=__stdcall                                       */
+/*                                                                      */
+/*      If it is desired to force export of the Shapelib API without    */
+/*      using the shapelib.def file, use the following definition.      */
+/*                                                                      */
+/*        /DSHAPELIB_DLLEXPORT                                          */
+/*                                                                      */
+/*      To get both at once it will be necessary to hack this           */
+/*      include file to define:                                         */
+/*                                                                      */
+/*        #define SHPAPI_CALL __declspec(dllexport) __stdcall           */
+/*        #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall        */
+/*                                                                      */
+/*      The complexity of the situtation is partly caused by the        */
+/*      peculiar requirement of Visual C++ that __stdcall appear        */
+/*      after any "*"'s in the return value of a function while the     */
+/*      __declspec(dllexport) must appear before them.                  */
+/* -------------------------------------------------------------------- */
+
+#ifdef SHAPELIB_DLLEXPORT
+#  define SHPAPI_CALL __declspec(dllexport)
+#  define SHPAPI_CALL1(x)  __declspec(dllexport) x
+#endif
+
+#ifndef SHPAPI_CALL
+#  define SHPAPI_CALL
+#endif
+
+#ifndef SHPAPI_CALL1
+#  define SHPAPI_CALL1(x)      x SHPAPI_CALL
+#endif
+    
+/* -------------------------------------------------------------------- */
+/*      Macros for controlling CVSID and ensuring they don't appear     */
+/*      as unreferenced variables resulting in lots of warnings.        */
+/* -------------------------------------------------------------------- */
+#ifndef DISABLE_CVSID
+#  define SHP_CVSID(string)     static char cpl_cvsid[] = string; \
+static char *cvsid_aw() { return( cvsid_aw() ? ((char *) NULL) : cpl_cvsid ); }
+#else
+#  define SHP_CVSID(string)
+#endif
+
+/************************************************************************/
+/*                             SHP Support.                             */
+/************************************************************************/
+typedef	struct
+{
+    FILE        *fpSHP;
+    FILE	*fpSHX;
+
+    int		nShapeType;				/* SHPT_* */
+    
+    int		nFileSize;				/* SHP file */
+
+    int         nRecords;
+    int		nMaxRecords;
+    int		*panRecOffset;
+    int		*panRecSize;
+
+    double	adBoundsMin[4];
+    double	adBoundsMax[4];
+
+    int		bUpdated;
+
+    unsigned char *pabyRec;
+    int         nBufSize;
+} SHPInfo;
+
+typedef SHPInfo * SHPHandle;
+
+/* -------------------------------------------------------------------- */
+/*      Shape types (nSHPType)                                          */
+/* -------------------------------------------------------------------- */
+#define SHPT_NULL	0
+#define SHPT_POINT	1
+#define SHPT_ARC	3
+#define SHPT_POLYGON	5
+#define SHPT_MULTIPOINT	8
+#define SHPT_POINTZ	11
+#define SHPT_ARCZ	13
+#define SHPT_POLYGONZ	15
+#define SHPT_MULTIPOINTZ 18
+#define SHPT_POINTM	21
+#define SHPT_ARCM	23
+#define SHPT_POLYGONM	25
+#define SHPT_MULTIPOINTM 28
+#define SHPT_MULTIPATCH 31
+
+
+/* -------------------------------------------------------------------- */
+/*      Part types - everything but SHPT_MULTIPATCH just uses           */
+/*      SHPP_RING.                                                      */
+/* -------------------------------------------------------------------- */
+
+#define SHPP_TRISTRIP	0
+#define SHPP_TRIFAN	1
+#define SHPP_OUTERRING	2
+#define SHPP_INNERRING	3
+#define SHPP_FIRSTRING	4
+#define SHPP_RING	5
+
+/* -------------------------------------------------------------------- */
+/*      SHPObject - represents on shape (without attributes) read       */
+/*      from the .shp file.                                             */
+/* -------------------------------------------------------------------- */
+typedef struct
+{
+    int		nSHPType;
+
+    int		nShapeId; /* -1 is unknown/unassigned */
+
+    int		nParts;
+    int		*panPartStart;
+    int		*panPartType;
+    
+    int		nVertices;
+    double	*padfX;
+    double	*padfY;
+    double	*padfZ;
+    double	*padfM;
+
+    double	dfXMin;
+    double	dfYMin;
+    double	dfZMin;
+    double	dfMMin;
+
+    double	dfXMax;
+    double	dfYMax;
+    double	dfZMax;
+    double	dfMMax;
+} SHPObject;
+
+/* -------------------------------------------------------------------- */
+/*      SHP API Prototypes                                              */
+/* -------------------------------------------------------------------- */
+SHPHandle SHPAPI_CALL
+      SHPOpen( const char * pszShapeFile, const char * pszAccess );
+SHPHandle SHPAPI_CALL
+      SHPCreate( const char * pszShapeFile, int nShapeType );
+void SHPAPI_CALL
+      SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
+                  double * padfMinBound, double * padfMaxBound );
+
+SHPObject SHPAPI_CALL1(*)
+      SHPReadObject( SHPHandle hSHP, int iShape );
+int SHPAPI_CALL
+      SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
+
+void SHPAPI_CALL
+      SHPDestroyObject( SHPObject * psObject );
+void SHPAPI_CALL
+      SHPComputeExtents( SHPObject * psObject );
+SHPObject SHPAPI_CALL1(*)
+      SHPCreateObject( int nSHPType, int nShapeId, int nParts, 
+                       const int * panPartStart, const int * panPartType,
+                       int nVertices, 
+                       const double * padfX, const double * padfY,
+                       const double * padfZ, const double * padfM );
+SHPObject SHPAPI_CALL1(*)
+      SHPCreateSimpleObject( int nSHPType, int nVertices,
+                             const double * padfX, 
+                             const double * padfY, 
+                             const double * padfZ );
+
+int SHPAPI_CALL
+      SHPRewindObject( SHPHandle hSHP, SHPObject * psObject );
+
+void SHPAPI_CALL SHPClose( SHPHandle hSHP );
+void SHPAPI_CALL SHPWriteHeader( SHPHandle hSHP );
+
+const char SHPAPI_CALL1(*)
+      SHPTypeName( int nSHPType );
+const char SHPAPI_CALL1(*)
+      SHPPartTypeName( int nPartType );
+
+/* -------------------------------------------------------------------- */
+/*      Shape quadtree indexing API.                                    */
+/* -------------------------------------------------------------------- */
+
+/* this can be two or four for binary or quad tree */
+#define MAX_SUBNODE	4
+
+typedef struct shape_tree_node
+{
+    /* region covered by this node */
+    double	adfBoundsMin[4];
+    double	adfBoundsMax[4];
+
+    /* list of shapes stored at this node.  The papsShapeObj pointers
+       or the whole list can be NULL */
+    int		nShapeCount;
+    int		*panShapeIds;
+    SHPObject   **papsShapeObj;
+
+    int		nSubNodes;
+    struct shape_tree_node *apsSubNode[MAX_SUBNODE];
+    
+} SHPTreeNode;
+
+typedef struct
+{
+    SHPHandle   hSHP;
+    
+    int		nMaxDepth;
+    int		nDimension;
+    int         nTotalCount;
+    
+    SHPTreeNode	*psRoot;
+} SHPTree;
+
+SHPTree SHPAPI_CALL1(*)
+      SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
+                     double *padfBoundsMin, double *padfBoundsMax );
+void    SHPAPI_CALL
+      SHPDestroyTree( SHPTree * hTree );
+
+int	SHPAPI_CALL
+      SHPWriteTree( SHPTree *hTree, const char * pszFilename );
+SHPTree SHPAPI_CALL
+      SHPReadTree( const char * pszFilename );
+
+int	SHPAPI_CALL
+      SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject );
+int	SHPAPI_CALL
+      SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject );
+int	SHPAPI_CALL
+      SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId );
+
+void 	SHPAPI_CALL
+      SHPTreeTrimExtraNodes( SHPTree * hTree );
+
+int    SHPAPI_CALL1(*)
+      SHPTreeFindLikelyShapes( SHPTree * hTree,
+                               double * padfBoundsMin,
+                               double * padfBoundsMax,
+                               int * );
+int     SHPAPI_CALL
+      SHPCheckBoundsOverlap( double *, double *, double *, double *, int );
+
+int SHPAPI_CALL1(*) 
+SHPSearchDiskTree( FILE *fp, 
+                   double *padfBoundsMin, double *padfBoundsMax,
+                   int *pnShapeCount );
+
+/************************************************************************/
+/*                             DBF Support.                             */
+/************************************************************************/
+typedef	struct
+{
+    FILE	*fp;
+
+    int         nRecords;
+
+    int		nRecordLength;
+    int		nHeaderLength;
+    int		nFields;
+    int		*panFieldOffset;
+    int		*panFieldSize;
+    int		*panFieldDecimals;
+    char	*pachFieldType;
+
+    char	*pszHeader;
+
+    int		nCurrentRecord;
+    int		bCurrentRecordModified;
+    char	*pszCurrentRecord;
+    
+    int		bNoHeader;
+    int		bUpdated;
+} DBFInfo;
+
+typedef DBFInfo * DBFHandle;
+
+typedef enum {
+  FTString,
+  FTInteger,
+  FTDouble,
+  FTLogical,
+  FTInvalid
+} DBFFieldType;
+
+#define XBASE_FLDHDR_SZ       32
+
+DBFHandle SHPAPI_CALL
+      DBFOpen( const char * pszDBFFile, const char * pszAccess );
+DBFHandle SHPAPI_CALL
+      DBFCreate( const char * pszDBFFile );
+
+int	SHPAPI_CALL
+      DBFGetFieldCount( DBFHandle psDBF );
+int	SHPAPI_CALL
+      DBFGetRecordCount( DBFHandle psDBF );
+int	SHPAPI_CALL
+      DBFAddField( DBFHandle hDBF, const char * pszFieldName,
+                   DBFFieldType eType, int nWidth, int nDecimals );
+
+DBFFieldType SHPAPI_CALL
+      DBFGetFieldInfo( DBFHandle psDBF, int iField, 
+                       char * pszFieldName, int * pnWidth, int * pnDecimals );
+
+int SHPAPI_CALL
+      DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName);
+
+int 	SHPAPI_CALL
+      DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
+double 	SHPAPI_CALL
+      DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
+const char SHPAPI_CALL1(*)
+      DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
+const char SHPAPI_CALL1(*)
+      DBFReadLogicalAttribute( DBFHandle hDBF, int iShape, int iField );
+int     SHPAPI_CALL
+      DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
+
+int SHPAPI_CALL
+      DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField, 
+                                int nFieldValue );
+int SHPAPI_CALL
+      DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
+                               double dFieldValue );
+int SHPAPI_CALL
+      DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
+                               const char * pszFieldValue );
+int SHPAPI_CALL
+     DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );
+
+int SHPAPI_CALL
+     DBFWriteLogicalAttribute( DBFHandle hDBF, int iShape, int iField,
+			       const char lFieldValue);
+int SHPAPI_CALL
+     DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
+                               void * pValue );
+const char SHPAPI_CALL1(*)
+      DBFReadTuple(DBFHandle psDBF, int hEntity );
+int SHPAPI_CALL
+      DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple );
+
+DBFHandle SHPAPI_CALL
+      DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );
+ 
+void	SHPAPI_CALL
+      DBFClose( DBFHandle hDBF );
+void    SHPAPI_CALL
+      DBFUpdateHeader( DBFHandle hDBF );
+char    SHPAPI_CALL
+      DBFGetNativeFieldType( DBFHandle hDBF, int iField );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ndef _SHAPEFILE_H_INCLUDED */
diff --git a/Utilities/OSSIM/ossim_core/vec/shape/shpopen.c b/Utilities/OSSIM/ossim_core/vec/shape/shpopen.c
new file mode 100644
index 0000000000..a5a9d5d381
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/shape/shpopen.c
@@ -0,0 +1,2018 @@
+/******************************************************************************
+ * $Id: shpopen.c,v 1.5 2005/10/08 12:57:26 gpotts Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Implementation of core Shapefile read/write functions.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, 2001, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shpopen.c,v $
+ * Revision 1.5  2005/10/08 12:57:26  gpotts
+ * Added adiitional patches
+ *
+ * Revision 1.46  2005/02/11 17:17:46  fwarmerdam
+ * added panPartStart[0] validation
+ *
+ * Revision 1.45  2004/09/26 20:09:48  fwarmerdam
+ * const correctness changes
+ *
+ * Revision 1.44  2003/12/29 00:18:39  fwarmerdam
+ * added error checking for failed IO and optional CPL error reporting
+ *
+ * Revision 1.43  2003/12/01 16:20:08  warmerda
+ * be careful of zero vertex shapes
+ *
+ * Revision 1.42  2003/12/01 14:58:27  warmerda
+ * added degenerate object check in SHPRewindObject()
+ *
+ * Revision 1.41  2003/07/08 15:22:43  warmerda
+ * avoid warning
+ *
+ * Revision 1.40  2003/04/21 18:30:37  warmerda
+ * added header write/update public methods
+ *
+ * Revision 1.39  2002/08/26 06:46:56  warmerda
+ * avoid c++ comments
+ *
+ * Revision 1.38  2002/05/07 16:43:39  warmerda
+ * Removed debugging printf.
+ *
+ * Revision 1.37  2002/04/10 17:35:22  warmerda
+ * fixed bug in ring reversal code
+ *
+ * Revision 1.36  2002/04/10 16:59:54  warmerda
+ * added SHPRewindObject
+ *
+ * Revision 1.35  2001/12/07 15:10:44  warmerda
+ * fix if .shx fails to open
+ *
+ * Revision 1.34  2001/11/01 16:29:55  warmerda
+ * move pabyRec into SHPInfo for thread safety
+ *
+ * Revision 1.33  2001/07/03 12:18:15  warmerda
+ * Improved cleanup if SHX not found, provied by Riccardo Cohen.
+ *
+ * Revision 1.32  2001/06/22 01:58:07  warmerda
+ * be more careful about establishing initial bounds in face of NULL shapes
+ *
+ * Revision 1.31  2001/05/31 19:35:29  warmerda
+ * added support for writing null shapes
+ *
+ * Revision 1.30  2001/05/28 12:46:29  warmerda
+ * Add some checking on reasonableness of record count when opening.
+ *
+ * Revision 1.29  2001/05/23 13:36:52  warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.28  2001/02/06 22:25:06  warmerda
+ * fixed memory leaks when SHPOpen() fails
+ *
+ * Revision 1.27  2000/07/18 15:21:33  warmerda
+ * added better enforcement of -1 for append in SHPWriteObject
+ *
+ * Revision 1.26  2000/02/16 16:03:51  warmerda
+ * added null shape support
+ *
+ * Revision 1.25  1999/12/15 13:47:07  warmerda
+ * Fixed record size settings in .shp file (was 4 words too long)
+ * Added stdlib.h.
+ *
+ * Revision 1.24  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.23  1999/07/27 00:53:46  warmerda
+ * added support for rewriting shapes
+ *
+ * Revision 1.22  1999/06/11 19:19:11  warmerda
+ * Cleanup pabyRec static buffer on SHPClose().
+ *
+ * Revision 1.21  1999/06/02 14:57:56  kshih
+ * Remove unused variables
+ *
+ * Revision 1.20  1999/04/19 21:04:17  warmerda
+ * Fixed syntax error.
+ *
+ * Revision 1.19  1999/04/19 21:01:57  warmerda
+ * Force access string to binary in SHPOpen().
+ *
+ * Revision 1.18  1999/04/01 18:48:07  warmerda
+ * Try upper case extensions if lower case doesn't work.
+ *
+ * Revision 1.17  1998/12/31 15:29:39  warmerda
+ * Disable writing measure values to multipatch objects if
+ * DISABLE_MULTIPATCH_MEASURE is defined.
+ *
+ * Revision 1.16  1998/12/16 05:14:33  warmerda
+ * Added support to write MULTIPATCH.  Fixed reading Z coordinate of
+ * MULTIPATCH. Fixed record size written for all feature types.
+ *
+ * Revision 1.15  1998/12/03 16:35:29  warmerda
+ * r+b is proper binary access string, not rb+.
+ *
+ * Revision 1.14  1998/12/03 15:47:56  warmerda
+ * Fixed setting of nVertices in SHPCreateObject().
+ *
+ * Revision 1.13  1998/12/03 15:33:54  warmerda
+ * Made SHPCalculateExtents() separately callable.
+ *
+ * Revision 1.12  1998/11/11 20:01:50  warmerda
+ * Fixed bug writing ArcM/Z, and PolygonM/Z for big endian machines.
+ *
+ * Revision 1.11  1998/11/09 20:56:44  warmerda
+ * Fixed up handling of file wide bounds.
+ *
+ * Revision 1.10  1998/11/09 20:18:51  warmerda
+ * Converted to support 3D shapefiles, and use of SHPObject.
+ *
+ * Revision 1.9  1998/02/24 15:09:05  warmerda
+ * Fixed memory leak.
+ *
+ * Revision 1.8  1997/12/04 15:40:29  warmerda
+ * Fixed byte swapping of record number, and record length fields in the
+ * .shp file.
+ *
+ * Revision 1.7  1995/10/21 03:15:58  warmerda
+ * Added support for binary file access, the magic cookie 9997
+ * and tried to improve the int32 selection logic for 16bit systems.
+ *
+ * Revision 1.6  1995/09/04  04:19:41  warmerda
+ * Added fix for file bounds.
+ *
+ * Revision 1.5  1995/08/25  15:16:44  warmerda
+ * Fixed a couple of problems with big endian systems ... one with bounds
+ * and the other with multipart polygons.
+ *
+ * Revision 1.4  1995/08/24  18:10:17  warmerda
+ * Switch to use SfRealloc() to avoid problems with pre-ANSI realloc()
+ * functions (such as on the Sun).
+ *
+ * Revision 1.3  1995/08/23  02:23:15  warmerda
+ * Added support for reading bounds, and fixed up problems in setting the
+ * file wide bounds.
+ *
+ * Revision 1.2  1995/08/04  03:16:57  warmerda
+ * Added header.
+ *
+ */
+
+#include "shapefil.h"
+
+#include <math.h>
+#include <limits.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+SHP_CVSID("$Id: shpopen.c,v 1.5 2005/10/08 12:57:26 gpotts Exp $")
+
+typedef unsigned char uchar;
+
+#if UINT_MAX == 65535
+typedef long	      int32;
+#else
+typedef int	      int32;
+#endif
+
+#ifndef FALSE
+#  define FALSE		0
+#  define TRUE		1
+#endif
+
+#define ByteCopy( a, b, c )	memcpy( b, a, c )
+#ifndef MAX
+#  define MIN(a,b)      ((a<b) ? a : b)
+#  define MAX(a,b)      ((a>b) ? a : b)
+#endif
+
+static int 	bBigEndian;
+
+
+/************************************************************************/
+/*                              SwapWord()                              */
+/*                                                                      */
+/*      Swap a 2, 4 or 8 byte word.                                     */
+/************************************************************************/
+
+static void	SwapWord( int length, void * wordP )
+
+{
+    int		i;
+    uchar	temp;
+
+    for( i=0; i < length/2; i++ )
+    {
+	temp = ((uchar *) wordP)[i];
+	((uchar *)wordP)[i] = ((uchar *) wordP)[length-i-1];
+	((uchar *) wordP)[length-i-1] = temp;
+    }
+}
+
+/************************************************************************/
+/*                             SfRealloc()                              */
+/*                                                                      */
+/*      A realloc cover function that will access a NULL pointer as     */
+/*      a valid input.                                                  */
+/************************************************************************/
+
+static void * SfRealloc( void * pMem, int nNewSize )
+
+{
+    if( pMem == NULL )
+        return( (void *) malloc(nNewSize) );
+    else
+        return( (void *) realloc(pMem,nNewSize) );
+}
+
+/************************************************************************/
+/*                          SHPWriteHeader()                            */
+/*                                                                      */
+/*      Write out a header for the .shp and .shx files as well as the	*/
+/*	contents of the index (.shx) file.				*/
+/************************************************************************/
+
+void SHPWriteHeader( SHPHandle psSHP )
+
+{
+    uchar     	abyHeader[100];
+    int		i;
+    int32	i32;
+    double	dValue;
+    int32	*panSHX;
+
+/* -------------------------------------------------------------------- */
+/*      Prepare header block for .shp file.                             */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < 100; i++ )
+      abyHeader[i] = 0;
+
+    abyHeader[2] = 0x27;				/* magic cookie */
+    abyHeader[3] = 0x0a;
+
+    i32 = psSHP->nFileSize/2;				/* file size */
+    ByteCopy( &i32, abyHeader+24, 4 );
+    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
+    
+    i32 = 1000;						/* version */
+    ByteCopy( &i32, abyHeader+28, 4 );
+    if( bBigEndian ) SwapWord( 4, abyHeader+28 );
+    
+    i32 = psSHP->nShapeType;				/* shape type */
+    ByteCopy( &i32, abyHeader+32, 4 );
+    if( bBigEndian ) SwapWord( 4, abyHeader+32 );
+
+    dValue = psSHP->adBoundsMin[0];			/* set bounds */
+    ByteCopy( &dValue, abyHeader+36, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+36 );
+
+    dValue = psSHP->adBoundsMin[1];
+    ByteCopy( &dValue, abyHeader+44, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+44 );
+
+    dValue = psSHP->adBoundsMax[0];
+    ByteCopy( &dValue, abyHeader+52, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+52 );
+
+    dValue = psSHP->adBoundsMax[1];
+    ByteCopy( &dValue, abyHeader+60, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+60 );
+
+    dValue = psSHP->adBoundsMin[2];			/* z */
+    ByteCopy( &dValue, abyHeader+68, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+68 );
+
+    dValue = psSHP->adBoundsMax[2];
+    ByteCopy( &dValue, abyHeader+76, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+76 );
+
+    dValue = psSHP->adBoundsMin[3];			/* m */
+    ByteCopy( &dValue, abyHeader+84, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+84 );
+
+    dValue = psSHP->adBoundsMax[3];
+    ByteCopy( &dValue, abyHeader+92, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+92 );
+
+/* -------------------------------------------------------------------- */
+/*      Write .shp file header.                                         */
+/* -------------------------------------------------------------------- */
+    if( fseek( psSHP->fpSHP, 0, 0 ) != 0 
+        || fwrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_OpenFailed, 
+                  "Failure writing .shp header." );
+#endif
+        return;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Prepare, and write .shx file header.                            */
+/* -------------------------------------------------------------------- */
+    i32 = (psSHP->nRecords * 2 * sizeof(int32) + 100)/2;   /* file size */
+    ByteCopy( &i32, abyHeader+24, 4 );
+    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
+    
+    if( fseek( psSHP->fpSHX, 0, 0 ) != 0 
+        || fwrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_OpenFailed, 
+                  "Failure writing .shx header." );
+#endif
+        return;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Write out the .shx contents.                                    */
+/* -------------------------------------------------------------------- */
+    panSHX = (int32 *) malloc(sizeof(int32) * 2 * psSHP->nRecords);
+
+    for( i = 0; i < psSHP->nRecords; i++ )
+    {
+	panSHX[i*2  ] = psSHP->panRecOffset[i]/2;
+	panSHX[i*2+1] = psSHP->panRecSize[i]/2;
+	if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
+	if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
+    }
+
+    if( (int)fwrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX ) 
+        != psSHP->nRecords )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_OpenFailed, 
+                  "Failure writing .shx contents." );
+#endif
+    }
+
+    free( panSHX );
+
+/* -------------------------------------------------------------------- */
+/*      Flush to disk.                                                  */
+/* -------------------------------------------------------------------- */
+    fflush( psSHP->fpSHP );
+    fflush( psSHP->fpSHX );
+}
+
+/************************************************************************/
+/*                              shpopen()                               */
+/*                                                                      */
+/*      Open the .shp and .shx files based on the basename of the       */
+/*      files or either file name.                                      */
+/************************************************************************/
+   
+SHPHandle SHPAPI_CALL
+SHPOpen( const char * pszLayer, const char * pszAccess )
+
+{
+    char		*pszFullname, *pszBasename;
+    SHPHandle		psSHP;
+    
+    uchar		*pabyBuf;
+    int			i;
+    double		dValue;
+    
+/* -------------------------------------------------------------------- */
+/*      Ensure the access string is one of the legal ones.  We          */
+/*      ensure the result string indicates binary to avoid common       */
+/*      problems on Windows.                                            */
+/* -------------------------------------------------------------------- */
+    if( strcmp(pszAccess,"rb+") == 0 || strcmp(pszAccess,"r+b") == 0
+        || strcmp(pszAccess,"r+") == 0 )
+        pszAccess = "r+b";
+    else
+        pszAccess = "rb";
+    
+/* -------------------------------------------------------------------- */
+/*	Establish the byte order on this machine.			*/
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((uchar *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*	Initialize the info structure.					*/
+/* -------------------------------------------------------------------- */
+    psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
+
+    psSHP->bUpdated = FALSE;
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (char *) malloc(strlen(pszLayer)+5);
+    strcpy( pszBasename, pszLayer );
+    for( i = strlen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+	       && pszBasename[i] != '\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == '.' )
+        pszBasename[i] = '\0';
+
+/* -------------------------------------------------------------------- */
+/*	Open the .shp and .shx files.  Note that files pulled from	*/
+/*	a PC to Unix with upper case filenames won't work!		*/
+/* -------------------------------------------------------------------- */
+    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
+    sprintf( pszFullname, "%s.shp", pszBasename );
+    psSHP->fpSHP = fopen(pszFullname, pszAccess );
+    if( psSHP->fpSHP == NULL )
+    {
+        sprintf( pszFullname, "%s.SHP", pszBasename );
+        psSHP->fpSHP = fopen(pszFullname, pszAccess );
+    }
+    
+    if( psSHP->fpSHP == NULL )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_OpenFailed, 
+                  "Unable to open %s.shp or %s.SHP.", 
+                  pszBasename, pszBasename );
+#endif
+        free( psSHP );
+        free( pszBasename );
+        free( pszFullname );
+        return( NULL );
+    }
+
+    sprintf( pszFullname, "%s.shx", pszBasename );
+    psSHP->fpSHX = fopen(pszFullname, pszAccess );
+    if( psSHP->fpSHX == NULL )
+    {
+        sprintf( pszFullname, "%s.SHX", pszBasename );
+        psSHP->fpSHX = fopen(pszFullname, pszAccess );
+    }
+    
+    if( psSHP->fpSHX == NULL )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_OpenFailed, 
+                  "Unable to open %s.shx or %s.SHX.", 
+                  pszBasename, pszBasename );
+#endif
+        fclose( psSHP->fpSHP );
+        free( psSHP );
+        free( pszBasename );
+        free( pszFullname );
+        return( NULL );
+    }
+
+    free( pszFullname );
+    free( pszBasename );
+
+/* -------------------------------------------------------------------- */
+/*  Read the file size from the SHP file.				*/
+/* -------------------------------------------------------------------- */
+    pabyBuf = (uchar *) malloc(100);
+    fread( pabyBuf, 100, 1, psSHP->fpSHP );
+
+    psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256
+			+ pabyBuf[25] * 256 * 256
+			+ pabyBuf[26] * 256
+			+ pabyBuf[27]) * 2;
+
+/* -------------------------------------------------------------------- */
+/*  Read SHX file Header info                                           */
+/* -------------------------------------------------------------------- */
+    if( fread( pabyBuf, 100, 1, psSHP->fpSHX ) != 1 
+        || pabyBuf[0] != 0 
+        || pabyBuf[1] != 0 
+        || pabyBuf[2] != 0x27 
+        || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  ".shx file is unreadable, or corrupt." );
+#endif
+	fclose( psSHP->fpSHP );
+	fclose( psSHP->fpSHX );
+	free( psSHP );
+
+	return( NULL );
+    }
+
+    psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256
+      + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
+    psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8;
+
+    psSHP->nShapeType = pabyBuf[32];
+
+    if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  "Record count in .shp header is %d, which seems\n"
+                  "unreasonable.  Assuming header is corrupt.",
+                  psSHP->nRecords );
+#endif
+	fclose( psSHP->fpSHP );
+	fclose( psSHP->fpSHX );
+	free( psSHP );
+
+	return( NULL );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Read the bounds.                                                */
+/* -------------------------------------------------------------------- */
+    if( bBigEndian ) SwapWord( 8, pabyBuf+36 );
+    memcpy( &dValue, pabyBuf+36, 8 );
+    psSHP->adBoundsMin[0] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+44 );
+    memcpy( &dValue, pabyBuf+44, 8 );
+    psSHP->adBoundsMin[1] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+52 );
+    memcpy( &dValue, pabyBuf+52, 8 );
+    psSHP->adBoundsMax[0] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+60 );
+    memcpy( &dValue, pabyBuf+60, 8 );
+    psSHP->adBoundsMax[1] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+68 );		/* z */
+    memcpy( &dValue, pabyBuf+68, 8 );
+    psSHP->adBoundsMin[2] = dValue;
+    
+    if( bBigEndian ) SwapWord( 8, pabyBuf+76 );
+    memcpy( &dValue, pabyBuf+76, 8 );
+    psSHP->adBoundsMax[2] = dValue;
+    
+    if( bBigEndian ) SwapWord( 8, pabyBuf+84 );		/* z */
+    memcpy( &dValue, pabyBuf+84, 8 );
+    psSHP->adBoundsMin[3] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+92 );
+    memcpy( &dValue, pabyBuf+92, 8 );
+    psSHP->adBoundsMax[3] = dValue;
+
+    free( pabyBuf );
+
+/* -------------------------------------------------------------------- */
+/*	Read the .shx file to get the offsets to each record in 	*/
+/*	the .shp file.							*/
+/* -------------------------------------------------------------------- */
+    psSHP->nMaxRecords = psSHP->nRecords;
+
+    psSHP->panRecOffset =
+        (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
+    psSHP->panRecSize =
+        (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
+
+    pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
+    if( (int) fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) 
+			!= psSHP->nRecords )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  "Failed to read all values for %d records in .shx file.",
+                  psSHP->nRecords );
+#endif
+        /* SHX is short or unreadable for some reason. */
+	fclose( psSHP->fpSHP );
+	fclose( psSHP->fpSHX );
+        free( psSHP->panRecOffset );
+        free( psSHP->panRecSize );
+	free( psSHP );
+
+	return( NULL );
+    }
+
+    for( i = 0; i < psSHP->nRecords; i++ )
+    {
+	int32		nOffset, nLength;
+
+	memcpy( &nOffset, pabyBuf + i * 8, 4 );
+	if( !bBigEndian ) SwapWord( 4, &nOffset );
+
+	memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
+	if( !bBigEndian ) SwapWord( 4, &nLength );
+
+	psSHP->panRecOffset[i] = nOffset*2;
+	psSHP->panRecSize[i] = nLength*2;
+    }
+    free( pabyBuf );
+
+    return( psSHP );
+}
+
+/************************************************************************/
+/*                              SHPClose()                              */
+/*								       	*/
+/*	Close the .shp and .shx files.					*/
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPClose(SHPHandle psSHP )
+
+{
+    if( psSHP == NULL )
+        return;
+
+/* -------------------------------------------------------------------- */
+/*	Update the header if we have modified anything.			*/
+/* -------------------------------------------------------------------- */
+    if( psSHP->bUpdated )
+	SHPWriteHeader( psSHP );
+
+/* -------------------------------------------------------------------- */
+/*      Free all resources, and close files.                            */
+/* -------------------------------------------------------------------- */
+    free( psSHP->panRecOffset );
+    free( psSHP->panRecSize );
+
+    fclose( psSHP->fpSHX );
+    fclose( psSHP->fpSHP );
+
+    if( psSHP->pabyRec != NULL )
+    {
+        free( psSHP->pabyRec );
+    }
+    
+    free( psSHP );
+}
+
+/************************************************************************/
+/*                             SHPGetInfo()                             */
+/*                                                                      */
+/*      Fetch general information about the shape file.                 */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType,
+           double * padfMinBound, double * padfMaxBound )
+
+{
+    int		i;
+
+    if( psSHP == NULL )
+        return;
+    
+    if( pnEntities != NULL )
+        *pnEntities = psSHP->nRecords;
+
+    if( pnShapeType != NULL )
+        *pnShapeType = psSHP->nShapeType;
+
+    for( i = 0; i < 4; i++ )
+    {
+        if( padfMinBound != NULL )
+            padfMinBound[i] = psSHP->adBoundsMin[i];
+        if( padfMaxBound != NULL )
+            padfMaxBound[i] = psSHP->adBoundsMax[i];
+    }
+}
+
+/************************************************************************/
+/*                             SHPCreate()                              */
+/*                                                                      */
+/*      Create a new shape file and return a handle to the open         */
+/*      shape file with read/write access.                              */
+/************************************************************************/
+
+SHPHandle SHPAPI_CALL
+SHPCreate( const char * pszLayer, int nShapeType )
+
+{
+    char	*pszBasename, *pszFullname;
+    int		i;
+    FILE	*fpSHP, *fpSHX;
+    uchar     	abyHeader[100];
+    int32	i32;
+    double	dValue;
+    
+/* -------------------------------------------------------------------- */
+/*      Establish the byte order on this system.                        */
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((uchar *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (char *) malloc(strlen(pszLayer)+5);
+    strcpy( pszBasename, pszLayer );
+    for( i = strlen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+	       && pszBasename[i] != '\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == '.' )
+        pszBasename[i] = '\0';
+
+/* -------------------------------------------------------------------- */
+/*      Open the two files so we can write their headers.               */
+/* -------------------------------------------------------------------- */
+    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
+    sprintf( pszFullname, "%s.shp", pszBasename );
+    fpSHP = fopen(pszFullname, "wb" );
+    if( fpSHP == NULL )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  "Failed to create file %s.",
+                  pszFullname );
+#endif
+        return( NULL );
+    }
+
+    sprintf( pszFullname, "%s.shx", pszBasename );
+    fpSHX = fopen(pszFullname, "wb" );
+    if( fpSHX == NULL )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  "Failed to create file %s.",
+                  pszFullname );
+#endif
+        return( NULL );
+    }
+
+    free( pszFullname );
+    free( pszBasename );
+
+/* -------------------------------------------------------------------- */
+/*      Prepare header block for .shp file.                             */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < 100; i++ )
+      abyHeader[i] = 0;
+
+    abyHeader[2] = 0x27;				/* magic cookie */
+    abyHeader[3] = 0x0a;
+
+    i32 = 50;						/* file size */
+    ByteCopy( &i32, abyHeader+24, 4 );
+    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
+    
+    i32 = 1000;						/* version */
+    ByteCopy( &i32, abyHeader+28, 4 );
+    if( bBigEndian ) SwapWord( 4, abyHeader+28 );
+    
+    i32 = nShapeType;					/* shape type */
+    ByteCopy( &i32, abyHeader+32, 4 );
+    if( bBigEndian ) SwapWord( 4, abyHeader+32 );
+
+    dValue = 0.0;					/* set bounds */
+    ByteCopy( &dValue, abyHeader+36, 8 );
+    ByteCopy( &dValue, abyHeader+44, 8 );
+    ByteCopy( &dValue, abyHeader+52, 8 );
+    ByteCopy( &dValue, abyHeader+60, 8 );
+
+/* -------------------------------------------------------------------- */
+/*      Write .shp file header.                                         */
+/* -------------------------------------------------------------------- */
+    if( fwrite( abyHeader, 100, 1, fpSHP ) != 1 )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  "Failed to write .shp header." );
+#endif
+        return NULL;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Prepare, and write .shx file header.                            */
+/* -------------------------------------------------------------------- */
+    i32 = 50;						/* file size */
+    ByteCopy( &i32, abyHeader+24, 4 );
+    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
+    
+    if( fwrite( abyHeader, 100, 1, fpSHX ) != 1 )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_AppDefined, 
+                  "Failed to write .shx header." );
+#endif
+        return NULL;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Close the files, and then open them as regular existing files.  */
+/* -------------------------------------------------------------------- */
+    fclose( fpSHP );
+    fclose( fpSHX );
+
+    return( SHPOpen( pszLayer, "r+b" ) );
+}
+
+/************************************************************************/
+/*                           _SHPSetBounds()                            */
+/*                                                                      */
+/*      Compute a bounds rectangle for a shape, and set it into the     */
+/*      indicated location in the record.                               */
+/************************************************************************/
+
+static void	_SHPSetBounds( uchar * pabyRec, SHPObject * psShape )
+
+{
+    ByteCopy( &(psShape->dfXMin), pabyRec +  0, 8 );
+    ByteCopy( &(psShape->dfYMin), pabyRec +  8, 8 );
+    ByteCopy( &(psShape->dfXMax), pabyRec + 16, 8 );
+    ByteCopy( &(psShape->dfYMax), pabyRec + 24, 8 );
+
+    if( bBigEndian )
+    {
+        SwapWord( 8, pabyRec + 0 );
+        SwapWord( 8, pabyRec + 8 );
+        SwapWord( 8, pabyRec + 16 );
+        SwapWord( 8, pabyRec + 24 );
+    }
+}
+
+/************************************************************************/
+/*                         SHPComputeExtents()                          */
+/*                                                                      */
+/*      Recompute the extents of a shape.  Automatically done by        */
+/*      SHPCreateObject().                                              */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPComputeExtents( SHPObject * psObject )
+
+{
+    int		i;
+    
+/* -------------------------------------------------------------------- */
+/*      Build extents for this object.                                  */
+/* -------------------------------------------------------------------- */
+    if( psObject->nVertices > 0 )
+    {
+        psObject->dfXMin = psObject->dfXMax = psObject->padfX[0];
+        psObject->dfYMin = psObject->dfYMax = psObject->padfY[0];
+        psObject->dfZMin = psObject->dfZMax = psObject->padfZ[0];
+        psObject->dfMMin = psObject->dfMMax = psObject->padfM[0];
+    }
+    
+    for( i = 0; i < psObject->nVertices; i++ )
+    {
+        psObject->dfXMin = MIN(psObject->dfXMin, psObject->padfX[i]);
+        psObject->dfYMin = MIN(psObject->dfYMin, psObject->padfY[i]);
+        psObject->dfZMin = MIN(psObject->dfZMin, psObject->padfZ[i]);
+        psObject->dfMMin = MIN(psObject->dfMMin, psObject->padfM[i]);
+
+        psObject->dfXMax = MAX(psObject->dfXMax, psObject->padfX[i]);
+        psObject->dfYMax = MAX(psObject->dfYMax, psObject->padfY[i]);
+        psObject->dfZMax = MAX(psObject->dfZMax, psObject->padfZ[i]);
+        psObject->dfMMax = MAX(psObject->dfMMax, psObject->padfM[i]);
+    }
+}
+
+/************************************************************************/
+/*                          SHPCreateObject()                           */
+/*                                                                      */
+/*      Create a shape object.  It should be freed with                 */
+/*      SHPDestroyObject().                                             */
+/************************************************************************/
+
+SHPObject SHPAPI_CALL1(*)
+SHPCreateObject( int nSHPType, int nShapeId, int nParts,
+                 const int * panPartStart, const int * panPartType,
+                 int nVertices, const double *padfX, const double *padfY,
+                 const double * padfZ, const double * padfM )
+
+{
+    SHPObject	*psObject;
+    int		i, bHasM, bHasZ;
+
+    psObject = (SHPObject *) calloc(1,sizeof(SHPObject));
+    psObject->nSHPType = nSHPType;
+    psObject->nShapeId = nShapeId;
+
+/* -------------------------------------------------------------------- */
+/*	Establish whether this shape type has M, and Z values.		*/
+/* -------------------------------------------------------------------- */
+    if( nSHPType == SHPT_ARCM
+        || nSHPType == SHPT_POINTM
+        || nSHPType == SHPT_POLYGONM
+        || nSHPType == SHPT_MULTIPOINTM )
+    {
+        bHasM = TRUE;
+        bHasZ = FALSE;
+    }
+    else if( nSHPType == SHPT_ARCZ
+             || nSHPType == SHPT_POINTZ
+             || nSHPType == SHPT_POLYGONZ
+             || nSHPType == SHPT_MULTIPOINTZ
+             || nSHPType == SHPT_MULTIPATCH )
+    {
+        bHasM = TRUE;
+        bHasZ = TRUE;
+    }
+    else
+    {
+        bHasM = FALSE;
+        bHasZ = FALSE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Capture parts.  Note that part type is optional, and            */
+/*      defaults to ring.                                               */
+/* -------------------------------------------------------------------- */
+    if( nSHPType == SHPT_ARC || nSHPType == SHPT_POLYGON
+        || nSHPType == SHPT_ARCM || nSHPType == SHPT_POLYGONM
+        || nSHPType == SHPT_ARCZ || nSHPType == SHPT_POLYGONZ
+        || nSHPType == SHPT_MULTIPATCH )
+    {
+        psObject->nParts = MAX(1,nParts);
+
+        psObject->panPartStart = (int *)
+            malloc(sizeof(int) * psObject->nParts);
+        psObject->panPartType = (int *)
+            malloc(sizeof(int) * psObject->nParts);
+
+        psObject->panPartStart[0] = 0;
+        psObject->panPartType[0] = SHPP_RING;
+        
+        for( i = 0; i < nParts; i++ )
+        {
+            psObject->panPartStart[i] = panPartStart[i];
+
+            if( panPartType != NULL )
+                psObject->panPartType[i] = panPartType[i];
+            else
+                psObject->panPartType[i] = SHPP_RING;
+        }
+
+        if( psObject->panPartStart[0] != 0 )
+        {
+#ifdef USE_CPL
+            CPLError( CE_Failure, CPLE_AppDefined,
+                      "panPartStart[0] != 0, patching internally.  Please fix your code!\n" );
+#else
+            fprintf( stderr, "panPartStart[0] != 0, patching internally.  Please fix your code!\n" );
+#endif
+            psObject->panPartStart[0] = 0;
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Capture vertices.  Note that Z and M are optional, but X and    */
+/*      Y are not.                                                      */
+/* -------------------------------------------------------------------- */
+    if( nVertices > 0 )
+    {
+        psObject->padfX = (double *) calloc(sizeof(double),nVertices);
+        psObject->padfY = (double *) calloc(sizeof(double),nVertices);
+        psObject->padfZ = (double *) calloc(sizeof(double),nVertices);
+        psObject->padfM = (double *) calloc(sizeof(double),nVertices);
+
+        assert( padfX != NULL );
+        assert( padfY != NULL );
+    
+        for( i = 0; i < nVertices; i++ )
+        {
+            psObject->padfX[i] = padfX[i];
+            psObject->padfY[i] = padfY[i];
+            if( padfZ != NULL && bHasZ )
+                psObject->padfZ[i] = padfZ[i];
+            if( padfM != NULL && bHasM )
+                psObject->padfM[i] = padfM[i];
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Compute the extents.                                            */
+/* -------------------------------------------------------------------- */
+    psObject->nVertices = nVertices;
+    SHPComputeExtents( psObject );
+
+    return( psObject );
+}
+
+/************************************************************************/
+/*                       SHPCreateSimpleObject()                        */
+/*                                                                      */
+/*      Create a simple (common) shape object.  Destroy with            */
+/*      SHPDestroyObject().                                             */
+/************************************************************************/
+
+SHPObject SHPAPI_CALL1(*)
+SHPCreateSimpleObject( int nSHPType, int nVertices,
+                       const double * padfX, const double * padfY,
+                       const double * padfZ )
+
+{
+    return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
+                             nVertices, padfX, padfY, padfZ, NULL ) );
+}
+                                  
+/************************************************************************/
+/*                           SHPWriteObject()                           */
+/*                                                                      */
+/*      Write out the vertices of a new structure.  Note that it is     */
+/*      only possible to write vertices at the end of the file.         */
+/************************************************************************/
+
+int SHPAPI_CALL
+SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
+		      
+{
+    int	       	nRecordOffset, i, nRecordSize=0;
+    uchar	*pabyRec;
+    int32	i32;
+
+    psSHP->bUpdated = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*      Ensure that shape object matches the type of the file it is     */
+/*      being written to.                                               */
+/* -------------------------------------------------------------------- */
+    assert( psObject->nSHPType == psSHP->nShapeType 
+            || psObject->nSHPType == SHPT_NULL );
+
+/* -------------------------------------------------------------------- */
+/*      Ensure that -1 is used for appends.  Either blow an             */
+/*      assertion, or if they are disabled, set the shapeid to -1       */
+/*      for appends.                                                    */
+/* -------------------------------------------------------------------- */
+    assert( nShapeId == -1 
+            || (nShapeId >= 0 && nShapeId < psSHP->nRecords) );
+
+    if( nShapeId != -1 && nShapeId >= psSHP->nRecords )
+        nShapeId = -1;
+
+/* -------------------------------------------------------------------- */
+/*      Add the new entity to the in memory index.                      */
+/* -------------------------------------------------------------------- */
+    if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords )
+    {
+	psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
+
+	psSHP->panRecOffset = (int *) 
+            SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords );
+	psSHP->panRecSize = (int *) 
+            SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Initialize record.                                              */
+/* -------------------------------------------------------------------- */
+    pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double) 
+			       + psObject->nParts * 8 + 128);
+    
+/* -------------------------------------------------------------------- */
+/*  Extract vertices for a Polygon or Arc.				*/
+/* -------------------------------------------------------------------- */
+    if( psObject->nSHPType == SHPT_POLYGON
+        || psObject->nSHPType == SHPT_POLYGONZ
+        || psObject->nSHPType == SHPT_POLYGONM
+        || psObject->nSHPType == SHPT_ARC 
+        || psObject->nSHPType == SHPT_ARCZ
+        || psObject->nSHPType == SHPT_ARCM
+        || psObject->nSHPType == SHPT_MULTIPATCH )
+    {
+	int32		nPoints, nParts;
+	int    		i;
+
+	nPoints = psObject->nVertices;
+	nParts = psObject->nParts;
+
+	_SHPSetBounds( pabyRec + 12, psObject );
+
+	if( bBigEndian ) SwapWord( 4, &nPoints );
+	if( bBigEndian ) SwapWord( 4, &nParts );
+
+	ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
+	ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
+
+        nRecordSize = 52;
+
+        /*
+         * Write part start positions.
+         */
+	ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
+                  4 * psObject->nParts );
+	for( i = 0; i < psObject->nParts; i++ )
+	{
+	    if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
+            nRecordSize += 4;
+	}
+
+        /*
+         * Write multipatch part types if needed.
+         */
+        if( psObject->nSHPType == SHPT_MULTIPATCH )
+        {
+            memcpy( pabyRec + nRecordSize, psObject->panPartType,
+                    4*psObject->nParts );
+            for( i = 0; i < psObject->nParts; i++ )
+            {
+                if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize );
+                nRecordSize += 4;
+            }
+        }
+
+        /*
+         * Write the (x,y) vertex values.
+         */
+	for( i = 0; i < psObject->nVertices; i++ )
+	{
+	    ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
+	    ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
+
+	    if( bBigEndian )
+                SwapWord( 8, pabyRec + nRecordSize );
+            
+	    if( bBigEndian )
+                SwapWord( 8, pabyRec + nRecordSize + 8 );
+
+            nRecordSize += 2 * 8;
+	}
+
+        /*
+         * Write the Z coordinates (if any).
+         */
+        if( psObject->nSHPType == SHPT_POLYGONZ
+            || psObject->nSHPType == SHPT_ARCZ
+            || psObject->nSHPType == SHPT_MULTIPATCH )
+        {
+            ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+            
+            ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+
+            for( i = 0; i < psObject->nVertices; i++ )
+            {
+                ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 );
+                if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+                nRecordSize += 8;
+            }
+        }
+
+        /*
+         * Write the M values, if any.
+         */
+        if( psObject->nSHPType == SHPT_POLYGONM
+            || psObject->nSHPType == SHPT_ARCM
+#ifndef DISABLE_MULTIPATCH_MEASURE            
+            || psObject->nSHPType == SHPT_MULTIPATCH
+#endif            
+            || psObject->nSHPType == SHPT_POLYGONZ
+            || psObject->nSHPType == SHPT_ARCZ )
+        {
+            ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+            
+            ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+
+            for( i = 0; i < psObject->nVertices; i++ )
+            {
+                ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 );
+                if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+                nRecordSize += 8;
+            }
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*  Extract vertices for a MultiPoint.					*/
+/* -------------------------------------------------------------------- */
+    else if( psObject->nSHPType == SHPT_MULTIPOINT
+             || psObject->nSHPType == SHPT_MULTIPOINTZ
+             || psObject->nSHPType == SHPT_MULTIPOINTM )
+    {
+	int32		nPoints;
+	int    		i;
+
+	nPoints = psObject->nVertices;
+
+        _SHPSetBounds( pabyRec + 12, psObject );
+
+	if( bBigEndian ) SwapWord( 4, &nPoints );
+	ByteCopy( &nPoints, pabyRec + 44, 4 );
+	
+	for( i = 0; i < psObject->nVertices; i++ )
+	{
+	    ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
+	    ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
+
+	    if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
+	    if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
+	}
+
+	nRecordSize = 48 + 16 * psObject->nVertices;
+
+        if( psObject->nSHPType == SHPT_MULTIPOINTZ )
+        {
+            ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+
+            ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+            
+            for( i = 0; i < psObject->nVertices; i++ )
+            {
+                ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 );
+                if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+                nRecordSize += 8;
+            }
+        }
+
+        if( psObject->nSHPType == SHPT_MULTIPOINTZ
+            || psObject->nSHPType == SHPT_MULTIPOINTM )
+        {
+            ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+
+            ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+            
+            for( i = 0; i < psObject->nVertices; i++ )
+            {
+                ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 );
+                if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+                nRecordSize += 8;
+            }
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Write point.							*/
+/* -------------------------------------------------------------------- */
+    else if( psObject->nSHPType == SHPT_POINT
+             || psObject->nSHPType == SHPT_POINTZ
+             || psObject->nSHPType == SHPT_POINTM )
+    {
+	ByteCopy( psObject->padfX, pabyRec + 12, 8 );
+	ByteCopy( psObject->padfY, pabyRec + 20, 8 );
+
+	if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
+	if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
+
+        nRecordSize = 28;
+        
+        if( psObject->nSHPType == SHPT_POINTZ )
+        {
+            ByteCopy( psObject->padfZ, pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+        }
+        
+        if( psObject->nSHPType == SHPT_POINTZ
+            || psObject->nSHPType == SHPT_POINTM )
+        {
+            ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Not much to do for null geometries.                             */
+/* -------------------------------------------------------------------- */
+    else if( psObject->nSHPType == SHPT_NULL )
+    {
+        nRecordSize = 12;
+    }
+
+    else
+    {
+        /* unknown type */
+        assert( FALSE );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Establish where we are going to put this record. If we are      */
+/*      rewriting and existing record, and it will fit, then put it     */
+/*      back where the original came from.  Otherwise write at the end. */
+/* -------------------------------------------------------------------- */
+    if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 )
+    {
+        if( nShapeId == -1 )
+            nShapeId = psSHP->nRecords++;
+
+        psSHP->panRecOffset[nShapeId] = nRecordOffset = psSHP->nFileSize;
+        psSHP->panRecSize[nShapeId] = nRecordSize-8;
+        psSHP->nFileSize += nRecordSize;
+    }
+    else
+    {
+        nRecordOffset = psSHP->panRecOffset[nShapeId];
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      Set the shape type, record number, and record size.             */
+/* -------------------------------------------------------------------- */
+    i32 = nShapeId+1;					/* record # */
+    if( !bBigEndian ) SwapWord( 4, &i32 );
+    ByteCopy( &i32, pabyRec, 4 );
+
+    i32 = (nRecordSize-8)/2;				/* record size */
+    if( !bBigEndian ) SwapWord( 4, &i32 );
+    ByteCopy( &i32, pabyRec + 4, 4 );
+
+    i32 = psObject->nSHPType;				/* shape type */
+    if( bBigEndian ) SwapWord( 4, &i32 );
+    ByteCopy( &i32, pabyRec + 8, 4 );
+
+/* -------------------------------------------------------------------- */
+/*      Write out record.                                               */
+/* -------------------------------------------------------------------- */
+    if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
+        || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_FileIO, 
+                "Error in fseek() or fwrite() writing object to .shp file." );
+#endif
+        free( pabyRec );
+        return -1;
+    }
+    
+    free( pabyRec );
+
+/* -------------------------------------------------------------------- */
+/*	Expand file wide bounds based on this shape.			*/
+/* -------------------------------------------------------------------- */
+    if( psSHP->adBoundsMin[0] == 0.0
+        && psSHP->adBoundsMax[0] == 0.0
+        && psSHP->adBoundsMin[1] == 0.0
+        && psSHP->adBoundsMax[1] == 0.0 )
+    {
+        if( psObject->nSHPType == SHPT_NULL || psObject->nVertices == 0 )
+        {
+            psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = 0.0;
+            psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = 0.0;
+            psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = 0.0;
+            psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = 0.0;
+        }
+        else
+        {
+            psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
+            psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
+            psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
+            psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
+        }
+    }
+
+    for( i = 0; i < psObject->nVertices; i++ )
+    {
+	psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
+	psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
+	psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
+	psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
+	psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
+	psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
+	psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
+	psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
+    }
+
+    return( nShapeId  );
+}
+
+/************************************************************************/
+/*                          SHPReadObject()                             */
+/*                                                                      */
+/*      Read the vertices, parts, and other non-attribute information	*/
+/*	for one shape.							*/
+/************************************************************************/
+
+SHPObject SHPAPI_CALL1(*)
+SHPReadObject( SHPHandle psSHP, int hEntity )
+
+{
+    SHPObject		*psShape;
+
+/* -------------------------------------------------------------------- */
+/*      Validate the record/entity number.                              */
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity >= psSHP->nRecords )
+        return( NULL );
+
+/* -------------------------------------------------------------------- */
+/*      Ensure our record buffer is large enough.                       */
+/* -------------------------------------------------------------------- */
+    if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize )
+    {
+	psSHP->nBufSize = psSHP->panRecSize[hEntity]+8;
+	psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize);
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Read the record.                                                */
+/* -------------------------------------------------------------------- */
+    if( fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 
+        || fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, 
+                  psSHP->fpSHP ) != 1 )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Failure, CPLE_FileIO, 
+                "Error in fseek() or fread() reading object from .shp file." );
+#endif
+        return NULL;
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Allocate and minimally initialize the object.			*/
+/* -------------------------------------------------------------------- */
+    psShape = (SHPObject *) calloc(1,sizeof(SHPObject));
+    psShape->nShapeId = hEntity;
+
+    memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 );
+    if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
+
+/* ==================================================================== */
+/*  Extract vertices for a Polygon or Arc.				*/
+/* ==================================================================== */
+    if( psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_ARC
+        || psShape->nSHPType == SHPT_POLYGONZ
+        || psShape->nSHPType == SHPT_POLYGONM
+        || psShape->nSHPType == SHPT_ARCZ
+        || psShape->nSHPType == SHPT_ARCM
+        || psShape->nSHPType == SHPT_MULTIPATCH )
+    {
+	int32		nPoints, nParts;
+	int    		i, nOffset;
+
+/* -------------------------------------------------------------------- */
+/*	Get the X/Y bounds.						*/
+/* -------------------------------------------------------------------- */
+        memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 +  4, 8 );
+        memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
+        memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
+        memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
+
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
+
+/* -------------------------------------------------------------------- */
+/*      Extract part/point count, and build vertex and part arrays      */
+/*      to proper size.                                                 */
+/* -------------------------------------------------------------------- */
+	memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
+	memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
+
+	if( bBigEndian ) SwapWord( 4, &nPoints );
+	if( bBigEndian ) SwapWord( 4, &nParts );
+
+	psShape->nVertices = nPoints;
+        psShape->padfX = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfY = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfM = (double *) calloc(nPoints,sizeof(double));
+
+	psShape->nParts = nParts;
+        psShape->panPartStart = (int *) calloc(nParts,sizeof(int));
+        psShape->panPartType = (int *) calloc(nParts,sizeof(int));
+
+        for( i = 0; i < nParts; i++ )
+            psShape->panPartType[i] = SHPP_RING;
+
+/* -------------------------------------------------------------------- */
+/*      Copy out the part array from the record.                        */
+/* -------------------------------------------------------------------- */
+	memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
+	for( i = 0; i < nParts; i++ )
+	{
+	    if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
+	}
+
+	nOffset = 44 + 8 + 4*nParts;
+
+/* -------------------------------------------------------------------- */
+/*      If this is a multipatch, we will also have parts types.         */
+/* -------------------------------------------------------------------- */
+        if( psShape->nSHPType == SHPT_MULTIPATCH )
+        {
+            memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts );
+            for( i = 0; i < nParts; i++ )
+            {
+                if( bBigEndian ) SwapWord( 4, psShape->panPartType+i );
+            }
+
+            nOffset += 4*nParts;
+        }
+        
+/* -------------------------------------------------------------------- */
+/*      Copy out the vertices from the record.                          */
+/* -------------------------------------------------------------------- */
+	for( i = 0; i < nPoints; i++ )
+	{
+	    memcpy(psShape->padfX + i,
+		   psSHP->pabyRec + nOffset + i * 16,
+		   8 );
+
+	    memcpy(psShape->padfY + i,
+		   psSHP->pabyRec + nOffset + i * 16 + 8,
+		   8 );
+
+	    if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
+	    if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
+	}
+
+        nOffset += 16*nPoints;
+        
+/* -------------------------------------------------------------------- */
+/*      If we have a Z coordinate, collect that now.                    */
+/* -------------------------------------------------------------------- */
+        if( psShape->nSHPType == SHPT_POLYGONZ
+            || psShape->nSHPType == SHPT_ARCZ
+            || psShape->nSHPType == SHPT_MULTIPATCH )
+        {
+            memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
+            memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
+            
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
+            
+            for( i = 0; i < nPoints; i++ )
+            {
+                memcpy( psShape->padfZ + i,
+                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
+                if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
+            }
+
+            nOffset += 16 + 8*nPoints;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a M measure value, then read it now.  We assume      */
+/*      that the measure can be present for any shape if the size is    */
+/*      big enough, but really it will only occur for the Z shapes      */
+/*      (options), and the M shapes.                                    */
+/* -------------------------------------------------------------------- */
+        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+        {
+            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
+            memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
+            
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
+            
+            for( i = 0; i < nPoints; i++ )
+            {
+                memcpy( psShape->padfM + i,
+                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
+                if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
+            }
+        }
+        
+    }
+
+/* ==================================================================== */
+/*  Extract vertices for a MultiPoint.					*/
+/* ==================================================================== */
+    else if( psShape->nSHPType == SHPT_MULTIPOINT
+             || psShape->nSHPType == SHPT_MULTIPOINTM
+             || psShape->nSHPType == SHPT_MULTIPOINTZ )
+    {
+	int32		nPoints;
+	int    		i, nOffset;
+
+	memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
+	if( bBigEndian ) SwapWord( 4, &nPoints );
+
+	psShape->nVertices = nPoints;
+        psShape->padfX = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfY = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfM = (double *) calloc(nPoints,sizeof(double));
+
+	for( i = 0; i < nPoints; i++ )
+	{
+	    memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
+	    memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
+
+	    if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
+	    if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
+	}
+
+        nOffset = 48 + 16*nPoints;
+        
+/* -------------------------------------------------------------------- */
+/*	Get the X/Y bounds.						*/
+/* -------------------------------------------------------------------- */
+        memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 +  4, 8 );
+        memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
+        memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
+        memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
+
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
+
+/* -------------------------------------------------------------------- */
+/*      If we have a Z coordinate, collect that now.                    */
+/* -------------------------------------------------------------------- */
+        if( psShape->nSHPType == SHPT_MULTIPOINTZ )
+        {
+            memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
+            memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
+            
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
+            
+            for( i = 0; i < nPoints; i++ )
+            {
+                memcpy( psShape->padfZ + i,
+                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
+                if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
+            }
+
+            nOffset += 16 + 8*nPoints;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a M measure value, then read it now.  We assume      */
+/*      that the measure can be present for any shape if the size is    */
+/*      big enough, but really it will only occur for the Z shapes      */
+/*      (options), and the M shapes.                                    */
+/* -------------------------------------------------------------------- */
+        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+        {
+            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
+            memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
+            
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
+            
+            for( i = 0; i < nPoints; i++ )
+            {
+                memcpy( psShape->padfM + i,
+                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
+                if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
+            }
+        }
+    }
+
+/* ==================================================================== */
+/*      Extract vertices for a point.                                   */
+/* ==================================================================== */
+    else if( psShape->nSHPType == SHPT_POINT
+             || psShape->nSHPType == SHPT_POINTM
+             || psShape->nSHPType == SHPT_POINTZ )
+    {
+        int	nOffset;
+        
+	psShape->nVertices = 1;
+        psShape->padfX = (double *) calloc(1,sizeof(double));
+        psShape->padfY = (double *) calloc(1,sizeof(double));
+        psShape->padfZ = (double *) calloc(1,sizeof(double));
+        psShape->padfM = (double *) calloc(1,sizeof(double));
+
+	memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
+	memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
+
+	if( bBigEndian ) SwapWord( 8, psShape->padfX );
+	if( bBigEndian ) SwapWord( 8, psShape->padfY );
+
+        nOffset = 20 + 8;
+        
+/* -------------------------------------------------------------------- */
+/*      If we have a Z coordinate, collect that now.                    */
+/* -------------------------------------------------------------------- */
+        if( psShape->nSHPType == SHPT_POINTZ )
+        {
+            memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 );
+        
+            if( bBigEndian ) SwapWord( 8, psShape->padfZ );
+            
+            nOffset += 8;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a M measure value, then read it now.  We assume      */
+/*      that the measure can be present for any shape if the size is    */
+/*      big enough, but really it will only occur for the Z shapes      */
+/*      (options), and the M shapes.                                    */
+/* -------------------------------------------------------------------- */
+        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 )
+        {
+            memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 );
+        
+            if( bBigEndian ) SwapWord( 8, psShape->padfM );
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Since no extents are supplied in the record, we will apply      */
+/*      them from the single vertex.                                    */
+/* -------------------------------------------------------------------- */
+        psShape->dfXMin = psShape->dfXMax = psShape->padfX[0];
+        psShape->dfYMin = psShape->dfYMax = psShape->padfY[0];
+        psShape->dfZMin = psShape->dfZMax = psShape->padfZ[0];
+        psShape->dfMMin = psShape->dfMMax = psShape->padfM[0];
+    }
+
+    return( psShape );
+}
+
+/************************************************************************/
+/*                            SHPTypeName()                             */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+SHPTypeName( int nSHPType )
+
+{
+    switch( nSHPType )
+    {
+      case SHPT_NULL:
+        return "NullShape";
+
+      case SHPT_POINT:
+        return "Point";
+
+      case SHPT_ARC:
+        return "Arc";
+
+      case SHPT_POLYGON:
+        return "Polygon";
+
+      case SHPT_MULTIPOINT:
+        return "MultiPoint";
+        
+      case SHPT_POINTZ:
+        return "PointZ";
+
+      case SHPT_ARCZ:
+        return "ArcZ";
+
+      case SHPT_POLYGONZ:
+        return "PolygonZ";
+
+      case SHPT_MULTIPOINTZ:
+        return "MultiPointZ";
+        
+      case SHPT_POINTM:
+        return "PointM";
+
+      case SHPT_ARCM:
+        return "ArcM";
+
+      case SHPT_POLYGONM:
+        return "PolygonM";
+
+      case SHPT_MULTIPOINTM:
+        return "MultiPointM";
+
+      case SHPT_MULTIPATCH:
+        return "MultiPatch";
+
+      default:
+        return "UnknownShapeType";
+    }
+}
+
+/************************************************************************/
+/*                          SHPPartTypeName()                           */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+SHPPartTypeName( int nPartType )
+
+{
+    switch( nPartType )
+    {
+      case SHPP_TRISTRIP:
+        return "TriangleStrip";
+        
+      case SHPP_TRIFAN:
+        return "TriangleFan";
+
+      case SHPP_OUTERRING:
+        return "OuterRing";
+
+      case SHPP_INNERRING:
+        return "InnerRing";
+
+      case SHPP_FIRSTRING:
+        return "FirstRing";
+
+      case SHPP_RING:
+        return "Ring";
+
+      default:
+        return "UnknownPartType";
+    }
+}
+
+/************************************************************************/
+/*                          SHPDestroyObject()                          */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPDestroyObject( SHPObject * psShape )
+
+{
+    if( psShape == NULL )
+        return;
+    
+    if( psShape->padfX != NULL )
+        free( psShape->padfX );
+    if( psShape->padfY != NULL )
+        free( psShape->padfY );
+    if( psShape->padfZ != NULL )
+        free( psShape->padfZ );
+    if( psShape->padfM != NULL )
+        free( psShape->padfM );
+
+    if( psShape->panPartStart != NULL )
+        free( psShape->panPartStart );
+    if( psShape->panPartType != NULL )
+        free( psShape->panPartType );
+
+    free( psShape );
+}
+
+/************************************************************************/
+/*                          SHPRewindObject()                           */
+/*                                                                      */
+/*      Reset the winding of polygon objects to adhere to the           */
+/*      specification.                                                  */
+/************************************************************************/
+
+int SHPAPI_CALL
+SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
+
+{
+    int  iOpRing, bAltered = 0;
+
+/* -------------------------------------------------------------------- */
+/*      Do nothing if this is not a polygon object.                     */
+/* -------------------------------------------------------------------- */
+    if( psObject->nSHPType != SHPT_POLYGON
+        && psObject->nSHPType != SHPT_POLYGONZ
+        && psObject->nSHPType != SHPT_POLYGONM )
+        return 0;
+
+    if( psObject->nVertices == 0 || psObject->nParts == 0 )
+        return 0;
+
+/* -------------------------------------------------------------------- */
+/*      Process each of the rings.                                      */
+/* -------------------------------------------------------------------- */
+    for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ )
+    {
+        int      bInner, iVert, nVertCount, nVertStart, iCheckRing;
+        double   dfSum, dfTestX, dfTestY;
+
+/* -------------------------------------------------------------------- */
+/*      Determine if this ring is an inner ring or an outer ring        */
+/*      relative to all the other rings.  For now we assume the         */
+/*      first ring is outer and all others are inner, but eventually    */
+/*      we need to fix this to handle multiple island polygons and      */
+/*      unordered sets of rings.                                        */
+/* -------------------------------------------------------------------- */
+        dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]];
+        dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]];
+
+        bInner = FALSE;
+        for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ )
+        {
+            int iEdge;
+
+            if( iCheckRing == iOpRing )
+                continue;
+            
+            nVertStart = psObject->panPartStart[iCheckRing];
+
+            if( iCheckRing == psObject->nParts-1 )
+                nVertCount = psObject->nVertices 
+                    - psObject->panPartStart[iCheckRing];
+            else
+                nVertCount = psObject->panPartStart[iCheckRing+1] 
+                    - psObject->panPartStart[iCheckRing];
+
+            for( iEdge = 0; iEdge < nVertCount; iEdge++ )
+            {
+                int iNext;
+
+                if( iEdge < nVertCount-1 )
+                    iNext = iEdge+1;
+                else
+                    iNext = 0;
+
+                if( (psObject->padfY[iEdge+nVertStart] < dfTestY 
+                     && psObject->padfY[iNext+nVertStart] >= dfTestY)
+                    || (psObject->padfY[iNext+nVertStart] < dfTestY 
+                        && psObject->padfY[iEdge+nVertStart] >= dfTestY) )
+                {
+                    if( psObject->padfX[iEdge+nVertStart] 
+                        + (dfTestY - psObject->padfY[iEdge+nVertStart])
+                           / (psObject->padfY[iNext+nVertStart]
+                              - psObject->padfY[iEdge+nVertStart])
+                           * (psObject->padfX[iNext+nVertStart]
+                              - psObject->padfX[iEdge+nVertStart]) < dfTestX )
+                        bInner = !bInner;
+                }
+            }
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Determine the current order of this ring so we will know if     */
+/*      it has to be reversed.                                          */
+/* -------------------------------------------------------------------- */
+        nVertStart = psObject->panPartStart[iOpRing];
+
+        if( iOpRing == psObject->nParts-1 )
+            nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing];
+        else
+            nVertCount = psObject->panPartStart[iOpRing+1] 
+                - psObject->panPartStart[iOpRing];
+
+        dfSum = 0.0;
+        for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ )
+        {
+            dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1]
+                - psObject->padfY[iVert] * psObject->padfX[iVert+1];
+        }
+
+        dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart]
+               - psObject->padfY[iVert] * psObject->padfX[nVertStart];
+
+/* -------------------------------------------------------------------- */
+/*      Reverse if necessary.                                           */
+/* -------------------------------------------------------------------- */
+        if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) )
+        {
+            int   i;
+
+            bAltered++;
+            for( i = 0; i < nVertCount/2; i++ )
+            {
+                double dfSaved;
+
+                /* Swap X */
+                dfSaved = psObject->padfX[nVertStart+i];
+                psObject->padfX[nVertStart+i] = 
+                    psObject->padfX[nVertStart+nVertCount-i-1];
+                psObject->padfX[nVertStart+nVertCount-i-1] = dfSaved;
+
+                /* Swap Y */
+                dfSaved = psObject->padfY[nVertStart+i];
+                psObject->padfY[nVertStart+i] = 
+                    psObject->padfY[nVertStart+nVertCount-i-1];
+                psObject->padfY[nVertStart+nVertCount-i-1] = dfSaved;
+
+                /* Swap Z */
+                if( psObject->padfZ )
+                {
+                    dfSaved = psObject->padfZ[nVertStart+i];
+                    psObject->padfZ[nVertStart+i] = 
+                        psObject->padfZ[nVertStart+nVertCount-i-1];
+                    psObject->padfZ[nVertStart+nVertCount-i-1] = dfSaved;
+                }
+
+                /* Swap M */
+                if( psObject->padfM )
+                {
+                    dfSaved = psObject->padfM[nVertStart+i];
+                    psObject->padfM[nVertStart+i] = 
+                        psObject->padfM[nVertStart+nVertCount-i-1];
+                    psObject->padfM[nVertStart+nVertCount-i-1] = dfSaved;
+                }
+            }
+        }
+    }
+
+    return bAltered;
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/shape/shptree.c b/Utilities/OSSIM/ossim_core/vec/shape/shptree.c
new file mode 100644
index 0000000000..4060e9c597
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/shape/shptree.c
@@ -0,0 +1,983 @@
+/******************************************************************************
+ * $Id: shptree.c,v 1.5 2005/10/08 12:57:26 gpotts Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Implementation of quadtree building and searching functions.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shptree.c,v $
+ * Revision 1.5  2005/10/08 12:57:26  gpotts
+ * Added adiitional patches
+ *
+ * Revision 1.10  2005/01/03 22:30:13  fwarmerdam
+ * added support for saved quadtrees
+ *
+ * Revision 1.9  2003/01/28 15:53:41  warmerda
+ * Avoid build warnings.
+ *
+ * Revision 1.8  2002/05/07 13:07:45  warmerda
+ * use qsort() - patch from Bernhard Herzog
+ *
+ * Revision 1.7  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.6  2001/05/23 13:36:52  warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.5  1999/11/05 14:12:05  warmerda
+ * updated license terms
+ *
+ * Revision 1.4  1999/06/02 18:24:21  warmerda
+ * added trimming code
+ *
+ * Revision 1.3  1999/06/02 17:56:12  warmerda
+ * added quad'' subnode support for trees
+ *
+ * Revision 1.2  1999/05/18 19:11:11  warmerda
+ * Added example searching capability
+ *
+ * Revision 1.1  1999/05/18 17:49:20  warmerda
+ * New
+ *
+ */
+
+#include "shapefil.h"
+
+#include <math.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+SHP_CVSID("$Id: shptree.c,v 1.5 2005/10/08 12:57:26 gpotts Exp $")
+
+#ifndef TRUE
+#  define TRUE 1
+#  define FALSE 0
+#endif
+
+static int bBigEndian = 0;
+
+
+/* -------------------------------------------------------------------- */
+/*      If the following is 0.5, nodes will be split in half.  If it    */
+/*      is 0.6 then each subnode will contain 60% of the parent         */
+/*      node, with 20% representing overlap.  This can be help to       */
+/*      prevent small objects on a boundary from shifting too high      */
+/*      up the tree.                                                    */
+/* -------------------------------------------------------------------- */
+
+#define SHP_SPLIT_RATIO	0.55
+
+/************************************************************************/
+/*                             SfRealloc()                              */
+/*                                                                      */
+/*      A realloc cover function that will access a NULL pointer as     */
+/*      a valid input.                                                  */
+/************************************************************************/
+
+static void * SfRealloc( void * pMem, int nNewSize )
+
+{
+    if( pMem == NULL )
+        return( (void *) malloc(nNewSize) );
+    else
+        return( (void *) realloc(pMem,nNewSize) );
+}
+
+/************************************************************************/
+/*                          SHPTreeNodeInit()                           */
+/*                                                                      */
+/*      Initialize a tree node.                                         */
+/************************************************************************/
+
+static SHPTreeNode *SHPTreeNodeCreate( double * padfBoundsMin,
+                                       double * padfBoundsMax )
+
+{
+    SHPTreeNode	*psTreeNode;
+
+    psTreeNode = (SHPTreeNode *) malloc(sizeof(SHPTreeNode));
+
+    psTreeNode->nShapeCount = 0;
+    psTreeNode->panShapeIds = NULL;
+    psTreeNode->papsShapeObj = NULL;
+
+    psTreeNode->nSubNodes = 0;
+
+    if( padfBoundsMin != NULL )
+        memcpy( psTreeNode->adfBoundsMin, padfBoundsMin, sizeof(double) * 4 );
+
+    if( padfBoundsMax != NULL )
+        memcpy( psTreeNode->adfBoundsMax, padfBoundsMax, sizeof(double) * 4 );
+
+    return psTreeNode;
+}
+
+
+/************************************************************************/
+/*                           SHPCreateTree()                            */
+/************************************************************************/
+
+SHPTree SHPAPI_CALL1(*)
+SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
+               double *padfBoundsMin, double *padfBoundsMax )
+
+{
+    SHPTree	*psTree;
+
+    if( padfBoundsMin == NULL && hSHP == NULL )
+        return NULL;
+
+/* -------------------------------------------------------------------- */
+/*      Allocate the tree object                                        */
+/* -------------------------------------------------------------------- */
+    psTree = (SHPTree *) malloc(sizeof(SHPTree));
+
+    psTree->hSHP = hSHP;
+    psTree->nMaxDepth = nMaxDepth;
+    psTree->nDimension = nDimension;
+    psTree->nTotalCount = 0;
+
+/* -------------------------------------------------------------------- */
+/*      If no max depth was defined, try to select a reasonable one     */
+/*      that implies approximately 8 shapes per node.                   */
+/* -------------------------------------------------------------------- */
+    if( psTree->nMaxDepth == 0 && hSHP != NULL )
+    {
+        int	nMaxNodeCount = 1;
+        int	nShapeCount;
+
+        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );
+        while( nMaxNodeCount*4 < nShapeCount )
+        {
+            psTree->nMaxDepth += 1;
+            nMaxNodeCount = nMaxNodeCount * 2;
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Allocate the root node.                                         */
+/* -------------------------------------------------------------------- */
+    psTree->psRoot = SHPTreeNodeCreate( padfBoundsMin, padfBoundsMax );
+
+/* -------------------------------------------------------------------- */
+/*      Assign the bounds to the root node.  If none are passed in,     */
+/*      use the bounds of the provided file otherwise the create        */
+/*      function will have already set the bounds.                      */
+/* -------------------------------------------------------------------- */
+    if( padfBoundsMin == NULL )
+    {
+        SHPGetInfo( hSHP, NULL, NULL,
+                    psTree->psRoot->adfBoundsMin, 
+                    psTree->psRoot->adfBoundsMax );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a file, insert all it's shapes into the tree.        */
+/* -------------------------------------------------------------------- */
+    if( hSHP != NULL )
+    {
+        int	iShape, nShapeCount;
+        
+        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );
+
+        for( iShape = 0; iShape < nShapeCount; iShape++ )
+        {
+            SHPObject	*psShape;
+            
+            psShape = SHPReadObject( hSHP, iShape );
+            SHPTreeAddShapeId( psTree, psShape );
+            SHPDestroyObject( psShape );
+        }
+    }        
+
+    return psTree;
+}
+
+/************************************************************************/
+/*                         SHPDestroyTreeNode()                         */
+/************************************************************************/
+
+static void SHPDestroyTreeNode( SHPTreeNode * psTreeNode )
+
+{
+    int		i;
+    
+    for( i = 0; i < psTreeNode->nSubNodes; i++ )
+    {
+        if( psTreeNode->apsSubNode[i] != NULL )
+            SHPDestroyTreeNode( psTreeNode->apsSubNode[i] );
+    }
+    
+    if( psTreeNode->panShapeIds != NULL )
+        free( psTreeNode->panShapeIds );
+
+    if( psTreeNode->papsShapeObj != NULL )
+    {
+        for( i = 0; i < psTreeNode->nShapeCount; i++ )
+        {
+            if( psTreeNode->papsShapeObj[i] != NULL )
+                SHPDestroyObject( psTreeNode->papsShapeObj[i] );
+        }
+
+        free( psTreeNode->papsShapeObj );
+    }
+
+    free( psTreeNode );
+}
+
+/************************************************************************/
+/*                           SHPDestroyTree()                           */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPDestroyTree( SHPTree * psTree )
+
+{
+    SHPDestroyTreeNode( psTree->psRoot );
+    free( psTree );
+}
+
+/************************************************************************/
+/*                       SHPCheckBoundsOverlap()                        */
+/*                                                                      */
+/*      Do the given boxes overlap at all?                              */
+/************************************************************************/
+
+int SHPAPI_CALL
+SHPCheckBoundsOverlap( double * padfBox1Min, double * padfBox1Max,
+                       double * padfBox2Min, double * padfBox2Max,
+                       int nDimension )
+
+{
+    int		iDim;
+
+    for( iDim = 0; iDim < nDimension; iDim++ )
+    {
+        if( padfBox2Max[iDim] < padfBox1Min[iDim] )
+            return FALSE;
+        
+        if( padfBox1Max[iDim] < padfBox2Min[iDim] )
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                      SHPCheckObjectContained()                       */
+/*                                                                      */
+/*      Does the given shape fit within the indicated extents?          */
+/************************************************************************/
+
+static int SHPCheckObjectContained( SHPObject * psObject, int nDimension,
+                           double * padfBoundsMin, double * padfBoundsMax )
+
+{
+    if( psObject->dfXMin < padfBoundsMin[0]
+        || psObject->dfXMax > padfBoundsMax[0] )
+        return FALSE;
+    
+    if( psObject->dfYMin < padfBoundsMin[1]
+        || psObject->dfYMax > padfBoundsMax[1] )
+        return FALSE;
+
+    if( nDimension == 2 )
+        return TRUE;
+    
+    if( psObject->dfZMin < padfBoundsMin[2]
+        || psObject->dfZMax < padfBoundsMax[2] )
+        return FALSE;
+        
+    if( nDimension == 3 )
+        return TRUE;
+
+    if( psObject->dfMMin < padfBoundsMin[3]
+        || psObject->dfMMax < padfBoundsMax[3] )
+        return FALSE;
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                         SHPTreeSplitBounds()                         */
+/*                                                                      */
+/*      Split a region into two subregion evenly, cutting along the     */
+/*      longest dimension.                                              */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPTreeSplitBounds( double *padfBoundsMinIn, double *padfBoundsMaxIn,
+                    double *padfBoundsMin1, double * padfBoundsMax1,
+                    double *padfBoundsMin2, double * padfBoundsMax2 )
+
+{
+/* -------------------------------------------------------------------- */
+/*      The output bounds will be very similar to the input bounds,     */
+/*      so just copy over to start.                                     */
+/* -------------------------------------------------------------------- */
+    memcpy( padfBoundsMin1, padfBoundsMinIn, sizeof(double) * 4 );
+    memcpy( padfBoundsMax1, padfBoundsMaxIn, sizeof(double) * 4 );
+    memcpy( padfBoundsMin2, padfBoundsMinIn, sizeof(double) * 4 );
+    memcpy( padfBoundsMax2, padfBoundsMaxIn, sizeof(double) * 4 );
+    
+/* -------------------------------------------------------------------- */
+/*      Split in X direction.                                           */
+/* -------------------------------------------------------------------- */
+    if( (padfBoundsMaxIn[0] - padfBoundsMinIn[0])
+        			> (padfBoundsMaxIn[1] - padfBoundsMinIn[1]) )
+    {
+        double	dfRange = padfBoundsMaxIn[0] - padfBoundsMinIn[0];
+
+        padfBoundsMax1[0] = padfBoundsMinIn[0] + dfRange * SHP_SPLIT_RATIO;
+        padfBoundsMin2[0] = padfBoundsMaxIn[0] - dfRange * SHP_SPLIT_RATIO;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Otherwise split in Y direction.                                 */
+/* -------------------------------------------------------------------- */
+    else
+    {
+        double	dfRange = padfBoundsMaxIn[1] - padfBoundsMinIn[1];
+
+        padfBoundsMax1[1] = padfBoundsMinIn[1] + dfRange * SHP_SPLIT_RATIO;
+        padfBoundsMin2[1] = padfBoundsMaxIn[1] - dfRange * SHP_SPLIT_RATIO;
+    }
+}
+
+/************************************************************************/
+/*                       SHPTreeNodeAddShapeId()                        */
+/************************************************************************/
+
+static int
+SHPTreeNodeAddShapeId( SHPTreeNode * psTreeNode, SHPObject * psObject,
+                       int nMaxDepth, int nDimension )
+
+{
+    int		i;
+    
+/* -------------------------------------------------------------------- */
+/*      If there are subnodes, then consider wiether this object        */
+/*      will fit in them.                                               */
+/* -------------------------------------------------------------------- */
+    if( nMaxDepth > 1 && psTreeNode->nSubNodes > 0 )
+    {
+        for( i = 0; i < psTreeNode->nSubNodes; i++ )
+        {
+            if( SHPCheckObjectContained(psObject, nDimension,
+                                      psTreeNode->apsSubNode[i]->adfBoundsMin,
+                                      psTreeNode->apsSubNode[i]->adfBoundsMax))
+            {
+                return SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[i],
+                                              psObject, nMaxDepth-1,
+                                              nDimension );
+            }
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Otherwise, consider creating four subnodes if could fit into    */
+/*      them, and adding to the appropriate subnode.                    */
+/* -------------------------------------------------------------------- */
+#if MAX_SUBNODE == 4
+    else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 )
+    {
+        double	adfBoundsMinH1[4], adfBoundsMaxH1[4];
+        double	adfBoundsMinH2[4], adfBoundsMaxH2[4];
+        double	adfBoundsMin1[4], adfBoundsMax1[4];
+        double	adfBoundsMin2[4], adfBoundsMax2[4];
+        double	adfBoundsMin3[4], adfBoundsMax3[4];
+        double	adfBoundsMin4[4], adfBoundsMax4[4];
+
+        SHPTreeSplitBounds( psTreeNode->adfBoundsMin,
+                            psTreeNode->adfBoundsMax,
+                            adfBoundsMinH1, adfBoundsMaxH1,
+                            adfBoundsMinH2, adfBoundsMaxH2 );
+
+        SHPTreeSplitBounds( adfBoundsMinH1, adfBoundsMaxH1,
+                            adfBoundsMin1, adfBoundsMax1,
+                            adfBoundsMin2, adfBoundsMax2 );
+
+        SHPTreeSplitBounds( adfBoundsMinH2, adfBoundsMaxH2,
+                            adfBoundsMin3, adfBoundsMax3,
+                            adfBoundsMin4, adfBoundsMax4 );
+
+        if( SHPCheckObjectContained(psObject, nDimension,
+                                    adfBoundsMin1, adfBoundsMax1)
+            || SHPCheckObjectContained(psObject, nDimension,
+                                    adfBoundsMin2, adfBoundsMax2)
+            || SHPCheckObjectContained(psObject, nDimension,
+                                    adfBoundsMin3, adfBoundsMax3)
+            || SHPCheckObjectContained(psObject, nDimension,
+                                    adfBoundsMin4, adfBoundsMax4) )
+        {
+            psTreeNode->nSubNodes = 4;
+            psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1,
+                                                           adfBoundsMax1 );
+            psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2,
+                                                           adfBoundsMax2 );
+            psTreeNode->apsSubNode[2] = SHPTreeNodeCreate( adfBoundsMin3,
+                                                           adfBoundsMax3 );
+            psTreeNode->apsSubNode[3] = SHPTreeNodeCreate( adfBoundsMin4,
+                                                           adfBoundsMax4 );
+
+            /* recurse back on this node now that it has subnodes */
+            return( SHPTreeNodeAddShapeId( psTreeNode, psObject,
+                                           nMaxDepth, nDimension ) );
+        }
+    }
+#endif /* MAX_SUBNODE == 4 */
+
+/* -------------------------------------------------------------------- */
+/*      Otherwise, consider creating two subnodes if could fit into     */
+/*      them, and adding to the appropriate subnode.                    */
+/* -------------------------------------------------------------------- */
+#if MAX_SUBNODE == 2
+    else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 )
+    {
+        double	adfBoundsMin1[4], adfBoundsMax1[4];
+        double	adfBoundsMin2[4], adfBoundsMax2[4];
+
+        SHPTreeSplitBounds( psTreeNode->adfBoundsMin, psTreeNode->adfBoundsMax,
+                            adfBoundsMin1, adfBoundsMax1,
+                            adfBoundsMin2, adfBoundsMax2 );
+
+        if( SHPCheckObjectContained(psObject, nDimension,
+                                 adfBoundsMin1, adfBoundsMax1))
+        {
+            psTreeNode->nSubNodes = 2;
+            psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1,
+                                                           adfBoundsMax1 );
+            psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2,
+                                                           adfBoundsMax2 );
+
+            return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[0], psObject,
+                                           nMaxDepth - 1, nDimension ) );
+        }
+        else if( SHPCheckObjectContained(psObject, nDimension,
+                                         adfBoundsMin2, adfBoundsMax2) )
+        {
+            psTreeNode->nSubNodes = 2;
+            psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1,
+                                                           adfBoundsMax1 );
+            psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2,
+                                                           adfBoundsMax2 );
+
+            return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[1], psObject,
+                                           nMaxDepth - 1, nDimension ) );
+        }
+    }
+#endif /* MAX_SUBNODE == 2 */
+
+/* -------------------------------------------------------------------- */
+/*      If none of that worked, just add it to this nodes list.         */
+/* -------------------------------------------------------------------- */
+    psTreeNode->nShapeCount++;
+
+    psTreeNode->panShapeIds = (int *) 
+        SfRealloc( psTreeNode->panShapeIds,
+                   sizeof(int) * psTreeNode->nShapeCount );
+    psTreeNode->panShapeIds[psTreeNode->nShapeCount-1] = psObject->nShapeId;
+
+    if( psTreeNode->papsShapeObj != NULL )
+    {
+        psTreeNode->papsShapeObj = (SHPObject **)
+            SfRealloc( psTreeNode->papsShapeObj,
+                       sizeof(void *) * psTreeNode->nShapeCount );
+        psTreeNode->papsShapeObj[psTreeNode->nShapeCount-1] = NULL;
+    }
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                         SHPTreeAddShapeId()                          */
+/*                                                                      */
+/*      Add a shape to the tree, but don't keep a pointer to the        */
+/*      object data, just keep the shapeid.                             */
+/************************************************************************/
+
+int SHPAPI_CALL
+SHPTreeAddShapeId( SHPTree * psTree, SHPObject * psObject )
+
+{
+    psTree->nTotalCount++;
+
+    return( SHPTreeNodeAddShapeId( psTree->psRoot, psObject,
+                                   psTree->nMaxDepth, psTree->nDimension ) );
+}
+
+/************************************************************************/
+/*                      SHPTreeCollectShapesIds()                       */
+/*                                                                      */
+/*      Work function implementing SHPTreeFindLikelyShapes() on a       */
+/*      tree node by tree node basis.                                   */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPTreeCollectShapeIds( SHPTree *hTree, SHPTreeNode * psTreeNode,
+                        double * padfBoundsMin, double * padfBoundsMax,
+                        int * pnShapeCount, int * pnMaxShapes,
+                        int ** ppanShapeList )
+
+{
+    int		i;
+    
+/* -------------------------------------------------------------------- */
+/*      Does this node overlap the area of interest at all?  If not,    */
+/*      return without adding to the list at all.                       */
+/* -------------------------------------------------------------------- */
+    if( !SHPCheckBoundsOverlap( psTreeNode->adfBoundsMin,
+                                psTreeNode->adfBoundsMax,
+                                padfBoundsMin,
+                                padfBoundsMax,
+                                hTree->nDimension ) )
+        return;
+
+/* -------------------------------------------------------------------- */
+/*      Grow the list to hold the shapes on this node.                  */
+/* -------------------------------------------------------------------- */
+    if( *pnShapeCount + psTreeNode->nShapeCount > *pnMaxShapes )
+    {
+        *pnMaxShapes = (*pnShapeCount + psTreeNode->nShapeCount) * 2 + 20;
+        *ppanShapeList = (int *)
+            SfRealloc(*ppanShapeList,sizeof(int) * *pnMaxShapes);
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Add the local nodes shapeids to the list.                       */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < psTreeNode->nShapeCount; i++ )
+    {
+        (*ppanShapeList)[(*pnShapeCount)++] = psTreeNode->panShapeIds[i];
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      Recurse to subnodes if they exist.                              */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < psTreeNode->nSubNodes; i++ )
+    {
+        if( psTreeNode->apsSubNode[i] != NULL )
+            SHPTreeCollectShapeIds( hTree, psTreeNode->apsSubNode[i],
+                                    padfBoundsMin, padfBoundsMax,
+                                    pnShapeCount, pnMaxShapes,
+                                    ppanShapeList );
+    }
+}
+
+/************************************************************************/
+/*                      SHPTreeFindLikelyShapes()                       */
+/*                                                                      */
+/*      Find all shapes within tree nodes for which the tree node       */
+/*      bounding box overlaps the search box.  The return value is      */
+/*      an array of shapeids terminated by a -1.  The shapeids will     */
+/*      be in order, as hopefully this will result in faster (more      */
+/*      sequential) reading from the file.                              */
+/************************************************************************/
+
+/* helper for qsort */
+static int
+compare_ints( const void * a, const void * b)
+{
+    return (*(int*)a) - (*(int*)b);
+}
+
+int SHPAPI_CALL1(*)
+SHPTreeFindLikelyShapes( SHPTree * hTree,
+                         double * padfBoundsMin, double * padfBoundsMax,
+                         int * pnShapeCount )
+
+{
+    int	*panShapeList=NULL, nMaxShapes = 0;
+
+/* -------------------------------------------------------------------- */
+/*      Perform the search by recursive descent.                        */
+/* -------------------------------------------------------------------- */
+    *pnShapeCount = 0;
+
+    SHPTreeCollectShapeIds( hTree, hTree->psRoot,
+                            padfBoundsMin, padfBoundsMax,
+                            pnShapeCount, &nMaxShapes,
+                            &panShapeList );
+
+/* -------------------------------------------------------------------- */
+/*      Sort the id array                                               */
+/* -------------------------------------------------------------------- */
+
+    qsort(panShapeList, *pnShapeCount, sizeof(int), compare_ints);
+
+    return panShapeList;
+}
+
+/************************************************************************/
+/*                          SHPTreeNodeTrim()                           */
+/*                                                                      */
+/*      This is the recurve version of SHPTreeTrimExtraNodes() that     */
+/*      walks the tree cleaning it up.                                  */
+/************************************************************************/
+
+static int SHPTreeNodeTrim( SHPTreeNode * psTreeNode )
+
+{
+    int		i;
+
+/* -------------------------------------------------------------------- */
+/*      Trim subtrees, and free subnodes that come back empty.          */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < psTreeNode->nSubNodes; i++ )
+    {
+        if( SHPTreeNodeTrim( psTreeNode->apsSubNode[i] ) )
+        {
+            SHPDestroyTreeNode( psTreeNode->apsSubNode[i] );
+
+            psTreeNode->apsSubNode[i] =
+                psTreeNode->apsSubNode[psTreeNode->nSubNodes-1];
+
+            psTreeNode->nSubNodes--;
+
+            i--; /* process the new occupant of this subnode entry */
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      We should be trimmed if we have no subnodes, and no shapes.     */
+/* -------------------------------------------------------------------- */
+    return( psTreeNode->nSubNodes == 0 && psTreeNode->nShapeCount == 0 );
+}
+
+/************************************************************************/
+/*                       SHPTreeTrimExtraNodes()                        */
+/*                                                                      */
+/*      Trim empty nodes from the tree.  Note that we never trim an     */
+/*      empty root node.                                                */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPTreeTrimExtraNodes( SHPTree * hTree )
+
+{
+    SHPTreeNodeTrim( hTree->psRoot );
+}
+
+/************************************************************************/
+/*                              SwapWord()                              */
+/*                                                                      */
+/*      Swap a 2, 4 or 8 byte word.                                     */
+/************************************************************************/
+
+static void SwapWord( int length, void * wordP )
+
+{
+    int		i;
+    unsigned char	temp;
+
+    for( i=0; i < length/2; i++ )
+    {
+	temp = ((unsigned char *) wordP)[i];
+	((unsigned char *)wordP)[i] = ((unsigned char *) wordP)[length-i-1];
+	((unsigned char *) wordP)[length-i-1] = temp;
+    }
+}
+
+/************************************************************************/
+/*                       SHPSearchDiskTreeNode()                        */
+/************************************************************************/
+
+static int
+SHPSearchDiskTreeNode( FILE *fp, double *padfBoundsMin, double *padfBoundsMax,
+                       int **ppanResultBuffer, int *pnBufferMax, 
+                       int *pnResultCount, int bNeedSwap )
+
+{
+    int i;
+    int offset;
+    int numshapes, numsubnodes;
+    double adfNodeBoundsMin[2], adfNodeBoundsMax[2];
+
+/* -------------------------------------------------------------------- */
+/*      Read and unswap first part of node info.                        */
+/* -------------------------------------------------------------------- */
+    fread( &offset, 4, 1, fp );
+    if ( bNeedSwap ) SwapWord ( 4, &offset );
+
+    fread( adfNodeBoundsMin, sizeof(double), 2, fp );
+    fread( adfNodeBoundsMax, sizeof(double), 2, fp );
+    if ( bNeedSwap )
+    {
+        SwapWord( 8, adfNodeBoundsMin + 0 );
+        SwapWord( 8, adfNodeBoundsMin + 1 );
+        SwapWord( 8, adfNodeBoundsMax + 0 );
+        SwapWord( 8, adfNodeBoundsMax + 1 );
+    }
+      
+    fread( &numshapes, 4, 1, fp );
+    if ( bNeedSwap ) SwapWord ( 4, &numshapes );
+
+/* -------------------------------------------------------------------- */
+/*      If we don't overlap this node at all, we can just fseek()       */
+/*      pass this node info and all subnodes.                           */
+/* -------------------------------------------------------------------- */
+    if( !SHPCheckBoundsOverlap( adfNodeBoundsMin, adfNodeBoundsMax, 
+                                padfBoundsMin, padfBoundsMax, 2 ) )
+    {
+        offset += numshapes*sizeof(int) + sizeof(int);
+        fseek(fp, offset, SEEK_CUR);
+        return TRUE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Add all the shapeids at this node to our list.                  */
+/* -------------------------------------------------------------------- */
+    if(numshapes > 0) 
+    {
+        if( *pnResultCount + numshapes > *pnBufferMax )
+        {
+            *pnBufferMax = (int) ((*pnResultCount + numshapes + 100) * 1.25);
+            *ppanResultBuffer = (int *) 
+                SfRealloc( *ppanResultBuffer, *pnBufferMax * sizeof(int) );
+        }
+
+        fread( *ppanResultBuffer + *pnResultCount, 
+               sizeof(int), numshapes, fp );
+
+        if (bNeedSwap )
+        {
+            for( i=0; i<numshapes; i++ )
+                SwapWord( 4, *ppanResultBuffer + *pnResultCount + i );
+        }
+
+        *pnResultCount += numshapes; 
+    } 
+
+/* -------------------------------------------------------------------- */
+/*      Process the subnodes.                                           */
+/* -------------------------------------------------------------------- */
+    fread( &numsubnodes, 4, 1, fp );
+    if ( bNeedSwap  ) SwapWord ( 4, &numsubnodes );
+
+    for(i=0; i<numsubnodes; i++)
+    {
+        if( !SHPSearchDiskTreeNode( fp, padfBoundsMin, padfBoundsMax, 
+                                    ppanResultBuffer, pnBufferMax, 
+                                    pnResultCount, bNeedSwap ) )
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                         SHPSearchDiskTree()                          */
+/************************************************************************/
+
+int SHPAPI_CALL1(*) 
+SHPSearchDiskTree( FILE *fp, 
+                   double *padfBoundsMin, double *padfBoundsMax,
+                   int *pnShapeCount )
+
+{
+    int i, bNeedSwap, nBufferMax = 0;
+    unsigned char abyBuf[16];
+    int *panResultBuffer = NULL;
+
+    *pnShapeCount = 0;
+
+/* -------------------------------------------------------------------- */
+/*	Establish the byte order on this machine.	  	        */
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((unsigned char *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*      Read the header.                                                */
+/* -------------------------------------------------------------------- */
+    fseek( fp, 0, SEEK_SET );
+    fread( abyBuf, 16, 1, fp );
+
+    if( memcmp( abyBuf, "SQT", 3 ) != 0 )
+        return NULL;
+
+    if( (abyBuf[3] == 2 && bBigEndian)
+        || (abyBuf[3] == 1 && !bBigEndian) )
+        bNeedSwap = FALSE;
+    else
+        bNeedSwap = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*      Search through root node and it's decendents.                   */
+/* -------------------------------------------------------------------- */
+    if( !SHPSearchDiskTreeNode( fp, padfBoundsMin, padfBoundsMax, 
+                                &panResultBuffer, &nBufferMax, 
+                                pnShapeCount, bNeedSwap ) )
+    {
+        if( panResultBuffer != NULL )
+            free( panResultBuffer );
+        *pnShapeCount = 0;
+        return NULL;
+    }
+/* -------------------------------------------------------------------- */
+/*      Sort the id array                                               */
+/* -------------------------------------------------------------------- */
+    qsort(panResultBuffer, *pnShapeCount, sizeof(int), compare_ints);
+    
+    return panResultBuffer;
+}
+
+/************************************************************************/
+/*                        SHPGetSubNodeOffset()                         */
+/*                                                                      */
+/*      Determine how big all the subnodes of this node (and their      */
+/*      children) will be.  This will allow disk based searchers to     */
+/*      seek past them all efficiently.                                 */
+/************************************************************************/
+
+static int SHPGetSubNodeOffset( SHPTreeNode *node) 
+{
+    int i;
+    long offset=0;
+
+    for(i=0; i<node->nSubNodes; i++ ) 
+    {
+        if(node->apsSubNode[i]) 
+        {
+            offset += 4*sizeof(double) 
+                + (node->apsSubNode[i]->nShapeCount+3)*sizeof(int);
+            offset += SHPGetSubNodeOffset(node->apsSubNode[i]);
+        }
+    }
+
+    return(offset);
+}
+
+/************************************************************************/
+/*                          SHPWriteTreeNode()                          */
+/************************************************************************/
+
+static void SHPWriteTreeNode( FILE *fp, SHPTreeNode *node) 
+{
+    int i,j;
+    int offset;
+    unsigned char *pabyRec = NULL;
+
+    offset = SHPGetSubNodeOffset(node);
+  
+    pabyRec = (unsigned char *) 
+        malloc(sizeof(double) * 4
+               + (3 * sizeof(int)) + (node->nShapeCount * sizeof(int)) );
+
+    memcpy( pabyRec, &offset, 4);
+
+    /* minx, miny, maxx, maxy */
+    memcpy( pabyRec+ 4, node->adfBoundsMin+0, sizeof(double) );
+    memcpy( pabyRec+12, node->adfBoundsMin+1, sizeof(double) );
+    memcpy( pabyRec+20, node->adfBoundsMax+0, sizeof(double) );
+    memcpy( pabyRec+28, node->adfBoundsMax+1, sizeof(double) );
+
+    memcpy( pabyRec+36, &node->nShapeCount, 4);
+    j = node->nShapeCount * sizeof(int);
+    memcpy( pabyRec+40, node->panShapeIds, j);
+    memcpy( pabyRec+j+40, &node->nSubNodes, 4);
+
+    fwrite( pabyRec, 44+j, 1, fp );
+    free (pabyRec);
+  
+    for(i=0; i<node->nSubNodes; i++ ) 
+    {
+        if(node->apsSubNode[i])
+            SHPWriteTreeNode( fp, node->apsSubNode[i]);
+    }
+}
+
+/************************************************************************/
+/*                            SHPWriteTree()                            */
+/************************************************************************/
+
+int SHPWriteTree(SHPTree *tree, const char *filename )
+{
+    char		signature[4] = "SQT";
+    int		        i;
+    char		abyBuf[32];
+    FILE                *fp;
+  
+/* -------------------------------------------------------------------- */
+/*      Open the output file.                                           */
+/* -------------------------------------------------------------------- */
+    fp = fopen(filename, "wb");
+    if( fp == NULL ) 
+    {
+        return FALSE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Establish the byte order on this machine.	  	        */
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((unsigned char *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+  
+/* -------------------------------------------------------------------- */
+/*      Write the header.                                               */
+/* -------------------------------------------------------------------- */
+    memcpy( abyBuf+0, signature, 3 );
+    
+    if( bBigEndian )
+        abyBuf[3] = 2; /* New MSB */
+    else
+        abyBuf[3] = 1; /* New LSB */
+
+    abyBuf[4] = 1; /* version */
+    abyBuf[5] = 0; /* next 3 reserved */
+    abyBuf[6] = 0;
+    abyBuf[7] = 0;
+
+    fwrite( abyBuf, 8, 1, fp );
+
+    fwrite( &(tree->nTotalCount), 4, 1, fp );
+
+    /* write maxdepth */
+
+    fwrite( &(tree->nMaxDepth), 4, 1, fp );
+
+/* -------------------------------------------------------------------- */
+/*      Write all the nodes "in order".                                 */
+/* -------------------------------------------------------------------- */
+
+    SHPWriteTreeNode( fp, tree->psRoot );  
+    
+    fclose( fp );
+
+    return TRUE;
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/.cvsignore b/Utilities/OSSIM/ossim_core/vec/vpf/.cvsignore
new file mode 100644
index 0000000000..c6c5cc35c9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/.cvsignore
@@ -0,0 +1,3 @@
+*.d
+*.o
+*.*~
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfBoundingRecordTable.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfBoundingRecordTable.cpp
new file mode 100644
index 0000000000..665cd2df0d
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfBoundingRecordTable.cpp
@@ -0,0 +1,105 @@
+#include "ossimVpfBoundingRecordTable.h"
+
+ossimVpfBoundingRecordTable::ossimVpfBoundingRecordTable()
+   :ossimVpfTable()
+{
+}
+
+bool ossimVpfBoundingRecordTable::openTable(const ossimFilename& tableName)
+{
+   bool result = false;
+   theExtent = ossimVpfExtent(0,0,0,0);
+   bool firstOneSetFlag = false;
+   
+   if(ossimVpfTable::openTable(tableName))
+   {
+      ossim_int32 xminIdx = getColumnPosition("XMIN");
+      ossim_int32 yminIdx = getColumnPosition("YMIN");
+      ossim_int32 xmaxIdx = getColumnPosition("XMAX");
+      ossim_int32 ymaxIdx = getColumnPosition("YMAX");
+      
+      if((xminIdx < 0)||
+         (yminIdx < 0)||
+         (xmaxIdx < 0)||
+         (ymaxIdx < 0))
+      {
+         closeTable();
+      }
+      else
+      {
+         if(getNumberOfRows() > 0)
+         {
+            result = true;
+            reset();
+            long n = 1;
+            
+            float xmin;
+            float ymin;
+            float xmax;
+            float ymax;
+            
+            row_type row;
+            for(int rowIdx = 1; rowIdx < getNumberOfRows(); ++rowIdx)
+            {
+               if(rowIdx == 1)
+               {
+                  row = read_row(rowIdx,
+                                 *theTableInformation);
+               }
+               else
+               {
+                  row = read_next_row(*theTableInformation);
+               }
+               get_table_element(xminIdx,
+                                 row,
+                                 *theTableInformation,
+                                 &xmin,
+                                 &n);
+               get_table_element(yminIdx,
+                                 row,
+                                 *theTableInformation,
+                                 &ymin,
+                                 &n);
+               get_table_element(xmaxIdx,
+                                 row,
+                                 *theTableInformation,
+                                 &xmax,
+                                 &n);
+               get_table_element(ymaxIdx,
+                                 row,
+                                 *theTableInformation,
+                                 &ymax,
+                                 &n);
+               if(!is_vpf_null_float(xmin)&&
+                  !is_vpf_null_float(ymin)&&
+                  !is_vpf_null_float(xmax)&&
+                  !is_vpf_null_float(ymax))
+               {
+                  if(!firstOneSetFlag)
+                  {
+                     theExtent = ossimVpfExtent(xmin,
+                                                ymin,
+                                                xmax,
+                                                ymax);
+                     firstOneSetFlag = true;
+                  }
+                  else
+                  {
+                     theExtent = theExtent + ossimVpfExtent(xmin,
+                                                            ymin,
+                                                            xmax,
+                                                            ymax);
+                  }                  
+               }
+               free_row(row, *theTableInformation);
+            }
+         }
+      }
+   }
+   return result;
+}
+
+void ossimVpfBoundingRecordTable::getExtent(ossimVpfExtent& extent)const
+{
+   extent = theExtent;
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfBoundingRecordTable.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfBoundingRecordTable.h
new file mode 100644
index 0000000000..f5e1705d51
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfBoundingRecordTable.h
@@ -0,0 +1,18 @@
+#ifndef ossimVpfBoundingRecordTable_HEADER
+#define ossimVpfBoundingRecordTable_HEADER
+#include "ossimVpfTable.h"
+#include "ossimVpfExtent.h"
+
+class ossimVpfBoundingRecordTable : public ossimVpfTable
+{
+public:
+   ossimVpfBoundingRecordTable();
+   virtual bool openTable(const ossimFilename& tableName);
+
+   void getExtent(ossimVpfExtent& extent)const;
+
+protected:
+   ossimVpfExtent theExtent;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfCoverage.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfCoverage.cpp
new file mode 100644
index 0000000000..138c1132fe
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfCoverage.cpp
@@ -0,0 +1,211 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfCoverage.cpp,v 1.6 2003/12/01 22:11:38 gpotts Exp $
+#include <algorithm>
+using namespace std;
+
+#include "ossimVpfCoverage.h"
+#include "ossimVpfLibrary.h"
+#include "ossimVpfFeatureClassSchema.h"
+#include "ossimVpfBoundingRecordTable.h"
+#include "base/common/ossimErrorCodes.h"
+
+ossimVpfCoverage::ossimVpfCoverage()
+   :theLibrary(NULL),
+    theCoverageName(""),
+    theCoverageNameFullPath("")
+{
+}
+
+ossimVpfCoverage::~ossimVpfCoverage()
+{
+   theLibrary = NULL;
+}
+
+bool ossimVpfCoverage::openCoverage(ossimVpfLibrary* library,
+                                    const ossimString& name,
+                                    const ossimFilename& fullPath)
+{
+   bool result = true;
+   theCoverageName         = name;
+   theCoverageNameFullPath = fullPath;
+   theLibrary = library;
+
+   if(!theCoverageNameFullPath.dirCat("fcs").exists())
+   {
+      result = false;
+   }
+   
+   return result;
+}
+
+const ossimFilename& ossimVpfCoverage::getPath()const
+{
+   return theCoverageNameFullPath;
+}
+
+const ossimString& ossimVpfCoverage::getName()const
+{
+   return theCoverageName;
+}
+
+void ossimVpfCoverage::print(ostream& out)const
+{
+  ossimVpfTable table;
+  if(table.openTable(theCoverageNameFullPath.dirCat("fcs")))
+  {
+     table.print(out);
+  }
+}
+
+bool ossimVpfCoverage::getExtent(ossimVpfExtent& extent)const
+{
+   bool result = false;
+   bool firstOneSetFlag = false;
+   ossimVpfExtent resultExtent;
+   ossimVpfExtent tempExtent;
+   if(theLibrary)
+   {
+      if(theCoverageNameFullPath.dirCat("ebr").exists())
+      {
+         ossimVpfBoundingRecordTable boundingRecord;
+         
+         if(boundingRecord.openTable(theCoverageNameFullPath.dirCat("ebr")))
+         {
+            boundingRecord.getExtent(tempExtent);
+
+            if(!firstOneSetFlag)
+            {
+               resultExtent = tempExtent;
+               firstOneSetFlag = true;
+            }
+            else
+            {
+               resultExtent = resultExtent + tempExtent;
+            }
+            
+            result = true;
+         }
+      }
+      if(theCoverageNameFullPath.dirCat("fbr").exists())
+      {
+         ossimVpfBoundingRecordTable boundingRecord;
+         
+         if(boundingRecord.openTable(theCoverageNameFullPath.dirCat("fbr")))
+         {
+            boundingRecord.getExtent(tempExtent);
+            
+            if(!firstOneSetFlag)
+            {
+               resultExtent = tempExtent;
+               firstOneSetFlag = true;
+            }
+            else
+            {
+               resultExtent = resultExtent + tempExtent;
+            }
+            
+            result = true;
+         }
+      }
+      std::vector<ossimString> tileNames;
+      
+      theLibrary->getTileNames(tileNames);
+      
+      for(int i = 0; i < (int)tileNames.size(); ++i)
+      {
+         ossimFilename tileName = tileNames[0];
+         ossimFilename tileDir;
+         if(theCoverageNameFullPath.dirCat(tileName).exists())
+         {
+            tileDir = theCoverageNameFullPath.dirCat(tileName);
+         }
+         else if(theCoverageNameFullPath.dirCat(tileName.downcase()).exists())
+         {
+            tileDir = theCoverageNameFullPath.dirCat(tileName.downcase());
+         }
+         if(tileDir != "")
+         {
+            if(tileDir.dirCat("ebr").exists())
+            {
+               ossimVpfBoundingRecordTable boundingRecord;
+               
+               if(boundingRecord.openTable(tileDir.dirCat("ebr")))
+               {
+                  boundingRecord.getExtent(tempExtent);
+                  
+                  if(!firstOneSetFlag)
+                  {
+                     resultExtent = tempExtent;
+                     firstOneSetFlag = true;
+                  }
+                  else
+                  {
+                     resultExtent = resultExtent + tempExtent;
+                  }
+                  
+                  result = true;
+               }
+            }
+            if(tileDir.dirCat("fbr").exists())
+            {
+               ossimVpfBoundingRecordTable boundingRecord;
+               
+               if(boundingRecord.openTable(tileDir.dirCat("fbr")))
+               {
+                  boundingRecord.getExtent(tempExtent);
+                  
+                  if(!firstOneSetFlag)
+                  {
+                     resultExtent = tempExtent;
+                     firstOneSetFlag = true;
+                  }
+                  else
+                  {
+                     resultExtent = resultExtent + tempExtent;
+                  }
+                  
+                  result = true;
+               }
+            }
+         }
+      }
+   }
+
+   extent = resultExtent;
+   
+   return result;
+}
+
+ossimVpfLibrary* ossimVpfCoverage::getLibrary()
+{
+   return theLibrary;
+}
+
+bool ossimVpfCoverage::openFeatureClassSchema(ossimVpfFeatureClassSchema& schema)
+{
+   if(!schema.isClosed()) schema.closeTable();
+
+   return schema.openSchema(this);
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfCoverage.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfCoverage.h
new file mode 100644
index 0000000000..3dfca73849
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfCoverage.h
@@ -0,0 +1,67 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfCoverage.h,v 1.5 2004/05/21 21:38:51 dburken Exp $
+#ifndef ossimVpfCoverage_HEADER
+#define ossimVpfCoverage_HEADER
+#include <map>
+#include <vector>
+#include "base/data_types/ossimFilename.h"
+#include "base/context/ossimErrorContext.h"
+#include "ossimVpfTable.h"
+#include "ossimVpfFeatureClass.h"
+#include "ossimVpfExtent.h"
+
+class ossimVpfLibrary;
+class ossimVpfFeatureClassSchema;
+class OSSIMDLLEXPORT ossimVpfCoverage
+{
+public:
+   ossimVpfCoverage ();
+   virtual ~ossimVpfCoverage();
+   
+   bool openCoverage(ossimVpfLibrary* library,
+                     const ossimString& name,
+                     const ossimFilename& fileName);
+   const ossimFilename& getPath()const;
+   const ossimString& getName()const;
+   
+   ossim_uint32 getNumberOfFeatureClasses()const;
+   void print(ostream& out)const;
+
+   bool getExtent(ossimVpfExtent& extent)const;
+   ossimVpfLibrary* getLibrary();
+   bool openFeatureClassSchema(ossimVpfFeatureClassSchema& schema);
+   
+private:
+   ossimVpfLibrary* theLibrary;
+   ossimString      theCoverageName;
+
+   /*!
+    * will hold the full path to this coverage.
+    */
+   ossimFilename theCoverageNameFullPath;
+   
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabase.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabase.cpp
new file mode 100644
index 0000000000..7267872d2c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabase.cpp
@@ -0,0 +1,205 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfDatabase.cpp,v 1.2 2003/09/03 17:30:14 gpotts Exp $
+#include "ossimVpfDatabase.h"
+#include "ossimVpfDatabaseHeader.h"
+#include "ossimVpfDatabaseHeaderTableValidator.h"
+#include "ossimVpfLibraryAttributeTableValidator.h"
+#include "ossimVpfTable.h"
+#include "ossimVpfLibrary.h"
+#include "base/common/ossimErrorCodes.h"
+
+ossimVpfDatabase::ossimVpfDatabase()
+   :theDatabaseHeaderTable(""),
+    theLibraryAttributeTable(""),
+    theOpenedFlag(false)
+{
+}
+
+ossimVpfDatabase::~ossimVpfDatabase()
+{
+   deleteLibraryList();
+   
+   closeDatabase();
+}
+
+bool ossimVpfDatabase::openDatabase(const ossimFilename& filename)
+{
+   bool result = true;
+
+   ossimFilename tempFilename = filename;
+
+   tempFilename.convertBackToForwardSlashes();
+
+   // we should have two table to look at for the database.
+   // 1) database header (dht) 2) and the Library attribute (lat)
+   theDatabaseHeaderTable   = ossimFilename(tempFilename.path()).dirCat("/dht");
+   theLibraryAttributeTable = ossimFilename(tempFilename.path()).dirCat("/lat");
+
+   if(theDatabaseHeaderTable.exists() &&
+      theLibraryAttributeTable.exists())
+   {
+      ossimVpfTable table;
+      // now lets see if they are valid tables
+      result = table.openTable(theDatabaseHeaderTable);
+      
+      if(result&&
+         !ossimVpfDatabaseHeaderTableValidator().isValid(table))
+      {
+         result =  false;
+      }
+      
+      result = table.openTable(theLibraryAttributeTable);
+      if((result) &&!ossimVpfLibraryAttributeTableValidator().isValid(table))
+      {
+         result = false;
+      }
+   }
+   else
+   {
+      result = false;
+   }
+
+   if(result)
+   {
+      theOpenedFlag = true;
+      initializeLibraryList();
+   }
+   
+   return result;
+}
+
+void ossimVpfDatabase::closeDatabase()
+{
+   theLibraryAttributeTable = "";
+   theDatabaseHeaderTable   = "";
+   theOpenedFlag = false;
+   deleteLibraryList();
+}
+
+
+ossimFilename ossimVpfDatabase::getPath()const
+{
+   // we can use either table name since all we need is the path
+   return theLibraryAttributeTable.path();
+}
+
+long ossimVpfDatabase::getNumberOfLibraries()const
+{
+   return (long)theVpfLibraryList.size();
+}
+
+ossimVpfLibrary* ossimVpfDatabase::getLibrary(unsigned long libraryNumber)
+{
+
+   if(libraryNumber < theVpfLibraryList.size())
+   {
+      return theVpfLibraryList[libraryNumber];
+   }
+   
+   return NULL;
+}
+
+ossimVpfLibrary* ossimVpfDatabase::getLibrary(const ossimString& name)
+{
+   for(long index = 0; index < (long)theVpfLibraryList.size(); ++index)
+   {
+      if(theVpfLibraryList[index]->getName() == name)
+      {
+         return theVpfLibraryList[index];
+      }
+   }
+   
+   return NULL;
+}
+
+
+bool ossimVpfDatabase::isOpened()const
+{
+   return theOpenedFlag;
+}
+
+vector<ossimString> ossimVpfDatabase::getLibraryNames()const
+{
+
+   ossimVpfTable table;
+
+   if(table.openTable(theLibraryAttributeTable))
+   {
+      return table.getColumnValues("LIBRARY_NAME");
+   }
+   
+   return vector<ossimString>();
+}
+
+vector<ossimString> ossimVpfDatabase::getLibraryNamesFullPath()const
+{
+   vector<ossimString> result;
+   
+   ossimVpfTable table;
+
+   if(table.openTable(theLibraryAttributeTable))
+   {
+      result = table.getColumnValues("LIBRARY_NAME");
+   }
+
+   for(long index=0; index < (long)result.size();index++)
+   {
+      result[index] = ossimString(theLibraryAttributeTable.path()) +
+                      ossimString("/") +
+                      result[index];
+   }
+   
+   return result;
+}
+
+ossimFilename ossimVpfDatabase::getLibraryAttributeTable()const
+{
+   return theLibraryAttributeTable;
+}
+
+void ossimVpfDatabase::initializeLibraryList()
+{
+   // make sure the library list is deleted
+   deleteLibraryList();
+   vector<ossimString> libraryNames = getLibraryNames();
+   for(long index = 0; index < (long)libraryNames.size(); index++)
+   {
+      ossimVpfLibrary *library = new ossimVpfLibrary;
+      library->openLibrary(this,
+                           libraryNames[index],
+                           getPath().dirCat(libraryNames[index]));
+      theVpfLibraryList.push_back(library);
+   }
+}
+
+void ossimVpfDatabase::deleteLibraryList()
+{
+   for(long index = 0; index <(long)theVpfLibraryList.size(); index++)
+   {
+      delete theVpfLibraryList[index];
+   }
+
+   theVpfLibraryList.clear();
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabase.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabase.h
new file mode 100644
index 0000000000..00a5ab5b8e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabase.h
@@ -0,0 +1,103 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfDatabase.h,v 1.2 2003/09/03 17:30:14 gpotts Exp $
+#ifndef ossimVpfDatabase_HEADER
+#define ossimVpfDatabase_HEADER
+#include <vector>
+using namespace std;
+
+#include "base/context/ossimErrorContext.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/data_types/ossimString.h"
+
+class ossimVpfLibrary;
+
+class ossimVpfDatabase
+{
+public:
+   /*!
+    * Initializes everything to null;
+    */
+   ossimVpfDatabase();
+
+   /*!
+    * Destroys any allocated space.
+    */
+   virtual ~ossimVpfDatabase();
+
+   /*!
+    * This will open a database.  This will either
+    * be a dht(database header table) table or a
+    * library attribut table (lat) file.  Both of these
+    * files should exist in a vpf database.
+    */
+   virtual bool openDatabase(const ossimFilename& filename);
+
+   void closeDatabase();
+   ossimFilename getPath()const;
+
+   long getNumberOfLibraries()const;
+   /*!
+    *
+    */
+   ossimVpfLibrary* getLibrary(unsigned long libraryNumber);
+
+   /*!
+    *
+    */
+   ossimVpfLibrary* getLibrary(const ossimString& name);
+
+   bool isOpened()const;
+   
+   vector<ossimString> getLibraryNames()const;
+   vector<ossimString> getLibraryNamesFullPath()const;
+
+   ossimFilename getLibraryAttributeTable()const;
+protected:
+
+   void initializeLibraryList();
+   void deleteLibraryList();
+   
+   /*!
+    * This is the complete path to the Database Header Table (dht file).
+    */
+   ossimFilename theDatabaseHeaderTable;
+
+   /*!
+    * This is the complete path to the library attribute table (lat file).
+    */
+   ossimFilename theLibraryAttributeTable;
+
+   /*!
+    * Will hold a constructed set of libraries.
+    */
+   vector<ossimVpfLibrary*> theVpfLibraryList;
+
+   /*!
+    * This jhust specifies whether the database has been opened or not.
+    */
+   bool  theOpenedFlag;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeader.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeader.cpp
new file mode 100644
index 0000000000..9cb6a33a15
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeader.cpp
@@ -0,0 +1,67 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfDatabaseHeader.cpp,v 1.2 2002/06/19 16:05:00 gpotts Exp $
+#include "ossimVpfDatabaseHeader.h"
+#include "base/common/ossimErrorCodes.h"
+#include "vpf_util/vpftable.h"
+ossimVpfDatabaseHeader::ossimVpfDatabaseHeader()
+{
+}
+
+
+ossimVpfDatabaseHeader::~ossimVpfDatabaseHeader()
+{
+}
+
+ossimErrorCode ossimVpfDatabaseHeader::open(const ossimFilename& databaseHeaderTable)
+{
+   vpf_table_type tableTypeData;
+
+   if(is_vpf_table(const_cast<char*>(databaseHeaderTable.c_str())))
+   {
+      tableTypeData = vpf_open_table(const_cast<char*>(databaseHeaderTable.c_str()),
+                                     (storage_type)DISK,
+                                     "rb",
+                                     NULL);
+      if(isDatabaseHeaderTable(tableTypeData))
+      {
+         
+      }
+      else
+      {
+         return ossimErrorCodes::OSSIM_ERROR;
+      }
+   }
+   else
+   {
+      return ossimErrorCodes::OSSIM_ERROR;
+   }
+
+   return ossimErrorCodes::OSSIM_OK;
+}
+
+bool ossimVpfDatabaseHeader::isDatabaseHeaderTable(vpf_table_type& tableType)
+{
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeader.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeader.h
new file mode 100644
index 0000000000..d921da4c48
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeader.h
@@ -0,0 +1,43 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfDatabaseHeader.h,v 1.3 2002/09/05 16:46:56 gpotts Exp $
+#ifndef ossimVpfDatabaseHeader_HEADER
+#define ossimVpfDatabaseHeader_HEADER
+#include "base/data_types/ossimFilename.h"
+#include "base/context/ossimErrorContext.h"
+
+
+#include "vpf_util/vpftable.h"
+
+class ossimVpfDatabaseHeader
+{
+public:
+   ossimVpfDatabaseHeader();
+   virtual ~ossimVpfDatabaseHeader();
+   virtual ossimErrorCode open(const ossimFilename& databaseHeaderTable);
+private:
+   bool isDatabaseHeaderTable(vpf_table_type& tableType);
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeaderTableValidator.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeaderTableValidator.cpp
new file mode 100644
index 0000000000..3c13251de9
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeaderTableValidator.cpp
@@ -0,0 +1,132 @@
+//-----------------------------------------------------------------
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//-----------------------------------------------------------------
+#include "ossimVpfDatabaseHeaderTableValidator.h"
+#include "ossimVpfTable.h"
+
+ossimVpfDatabaseHeaderTableValidator::~ossimVpfDatabaseHeaderTableValidator()
+{
+}
+
+bool ossimVpfDatabaseHeaderTableValidator::isValid(ossimVpfTable& aTable)const
+{
+   // make sure the table is not null
+   if(&aTable == NULL)
+   {
+      return false;
+   }
+
+   // and make sure that the table is not closed
+   if(aTable.isClosed())
+   {
+      return false;
+   }
+
+   // get the table data defined in vpf_util/vpftable.h"
+   const vpf_table_type* data = aTable.getVpfTableData();
+
+   if(!data)
+   {
+      return false;
+   }
+   
+   // if the file is not open then we can't validate
+   if(!data->fp)
+   {
+      return false;
+   }
+
+   // The way that we will validate is to see if the columns of a dht
+   // exist.  if the column didn't exist then the position
+   // will be negative
+   long column = table_pos("ID", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("VPF_VERSION", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("DATABASE_NAME", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("DATABASE_DESC", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("MEDIA_STANDARD", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("ORIGINATOR", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("ADDRESSEE", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("MEDIA_VOLUMES", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("SEQ_NUMBERS", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("NUM_DATA_SETS", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("SECURITY_CLASS", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("DOWNGRADING", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("DOWNGRADE_DATE", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("RELEASABILITY", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("TRANSMITTAL_ID", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("EDITION_NUMBER", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("EDITION_DATE", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   
+   return true;
+
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeaderTableValidator.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeaderTableValidator.h
new file mode 100644
index 0000000000..537d7bbc14
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfDatabaseHeaderTableValidator.h
@@ -0,0 +1,17 @@
+//-----------------------------------------------------------------
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//-----------------------------------------------------------------
+#ifndef ossimVpfDatabaseHeaderTableValidator_HEADER
+#define ossimVpfDatabaseHeaderTableValidator_HEADER
+#include "ossimVpfTableValidator.h"
+class ossimVpfTable;
+class ossimVpfDatabaseHeaderTableValidator : public ossimVpfTableValidator
+{
+public:
+   virtual ~ossimVpfDatabaseHeaderTableValidator();
+   virtual bool isValid(ossimVpfTable& aTable)const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfExtent.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfExtent.cpp
new file mode 100644
index 0000000000..a2c03c17f3
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfExtent.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1994, 1995 Vectaport Inc., Cartoactive Systems
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ */
+
+#include "ossimVpfExtent.h"
+#include "base/common/ossimCommon.h"
+#include "vpf.h"
+
+#ifndef min
+#define min(a,b) (a < b ? a : b)
+#endif
+#ifndef max
+#define max(a,b) (a > b ? a : b)
+#endif
+
+/*****************************************************************************/
+
+ostream& operator <<(ostream& out,
+                     const ossimVpfExtent& data)
+{
+   out << "x1: " << data.theExtentType.x1 << endl
+       << "y1: " << data.theExtentType.y1 << endl
+       << "x2: " << data.theExtentType.x2 << endl
+       << "y2: " << data.theExtentType.y2;
+
+   return out;
+}
+
+
+ossimVpfExtent::ossimVpfExtent (double x1, double y1, double x2, double y2)
+{
+    this->theExtentType.x1 = x1;
+    this->theExtentType.y1 = y1;
+    this->theExtentType.x2 = x2;
+    this->theExtentType.y2 = y2;
+}
+
+ossimVpfExtent::ossimVpfExtent ()
+{
+   theExtentType.x1 = 0.0;
+   theExtentType.y1 = 0.0;
+   theExtentType.x2 = 0.0;
+   theExtentType.y2 = 0.0;
+}
+
+ossimVpfExtent::ossimVpfExtent(const extent_type& etype)
+{
+   theExtentType.x1 = etype.x1;
+   theExtentType.y1 = etype.y1;
+   theExtentType.x2 = etype.x2;
+   theExtentType.y2 = etype.y2;
+}
+
+int ossimVpfExtent::contained (ossimVpfExtent& extent2) {
+    return ::contained( theExtentType, extent2.theExtentType );
+}
+
+int ossimVpfExtent::completely_within (ossimVpfExtent& extent2) {
+    return ::completely_within( theExtentType, extent2.theExtentType );
+}
+
+int ossimVpfExtent::within (double x, double y) {
+    return ::fwithin( x, y, theExtentType );
+}
+
+ossimVpfExtent ossimVpfExtent::operator+ (const ossimVpfExtent& b)const
+{
+    ossimVpfExtent m;
+    
+    m.theExtentType.x1 = ossimMin(theExtentType.x1, b.theExtentType.x1);
+    m.theExtentType.y1 = ossimMin(theExtentType.y1, b.theExtentType.y1);
+    m.theExtentType.x2 = ossimMax(theExtentType.x2, b.theExtentType.x2);
+    m.theExtentType.y2 = ossimMax(theExtentType.y2, b.theExtentType.y2);
+    
+    return m;
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfExtent.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfExtent.h
new file mode 100644
index 0000000000..18148a4c44
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfExtent.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1994, 1995 Vectaport Inc., Cartoactive Systems
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ */
+#ifndef ossimVpfExtent_HEADER
+#define ossimVpfExtent_HEADER
+#include <iostream>
+using namespace std;
+#include "vpf.h"
+
+
+class ossimVpfExtent
+{
+public:
+   friend ostream& operator <<(ostream& out,
+                               const ossimVpfExtent& data);
+   
+   ossimVpfExtent (double x1, double y1, double x2, double y2);
+   ossimVpfExtent();
+   ossimVpfExtent(const extent_type& etype);
+   
+   int contained (ossimVpfExtent& extent2);
+   int completely_within (ossimVpfExtent& extent2);
+   int within (double x, double y);
+   ossimVpfExtent operator+ (const ossimVpfExtent& b)const;
+protected:
+   extent_type theExtentType;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClass.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClass.cpp
new file mode 100644
index 0000000000..c4475d5b36
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClass.cpp
@@ -0,0 +1,151 @@
+#include <algorithm>
+using namespace std;
+
+#include "ossimVpfFeatureClass.h"
+#include "base/data_types/ossimFilename.h"
+#include "ossimVpfCoverage.h"
+#include "base/common/ossimErrorCodes.h"
+#include "ossimVpfTable.h"
+
+#include <string.h> 
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+ossimVpfFeatureClass::ossimVpfFeatureClass()
+{
+}
+
+
+bool ossimVpfFeatureClass::openFeatureClass(const ossimString& featureClassName,
+                                            const ossimFilename& featureClassFullPath,
+                                            const ossimFilename& table1,
+                                            const ossimString&   columnNameIdTable1,
+                                            const ossimFilename& table2,
+                                            const ossimString&   columnNameIdTable2)
+{
+   theFeatureClassFullPath = featureClassFullPath;
+   theFeatureClassName     = featureClassName;
+   theTableName1           = table1;
+   theColumnNameId1        = columnNameIdTable1;
+   theTableName2           = table2;
+   theColumnNameId2        = columnNameIdTable2;
+   
+   ossimVpfTable t1;
+   ossimVpfTable t2;
+
+   ossimFilename t1Name = getTable1();
+   ossimFilename t2Name = getTable2();
+
+   if((!t1.openTable(t1Name))||
+      (!t2.openTable(t2Name)))
+     {
+       
+       return false;
+     }
+   
+   return true;
+}
+
+const ossimString& ossimVpfFeatureClass::getName()const
+{
+  return theFeatureClassName;
+  
+}
+
+bool ossimVpfFeatureClass::isPrimitive(const ossimString& featureName)
+{
+   // make sure we have forward slashes
+   ossimFilename filename(featureName.trim());   
+   filename.convertBackToForwardSlashes();
+   
+   ossimString copyOfFeature = filename;
+
+   // find
+   char* temp = strrchr(copyOfFeature.c_str(), '/');
+
+   ossimString value;
+   if(temp)
+   {
+      ++temp;
+      value = temp;
+   }
+   else
+   {
+      
+      value = copyOfFeature;
+   }
+
+   value = value.downcase();
+   return( (value == "end") ||
+           (value == "cnd") ||
+           (value == "edg") ||
+           (value == "fac") ||
+           (value == "txt") );
+}
+
+bool ossimVpfFeatureClass::isSimpleFeature(const ossimString& featureName)
+{
+   // find the suffix
+   ossimString value = strrchr(featureName.trim().c_str(), '.');
+
+   // the suffix will be null or empty string if not found.
+   if(value == "")
+   {
+      return false;
+   }
+   // make case insensitive
+   value = value.downcase();
+
+   return ( (value == ".pft")||
+            (value == ".lft")||
+            (value == ".aft")||
+            (value == ".tft"));
+}
+
+bool ossimVpfFeatureClass::isComplexFeature(const ossimString& featureName)
+{
+   const char* suffix = strrchr(featureName.trim(), '.');
+   
+   if (!suffix)
+   {
+      return false;
+   }
+
+   ossimString value = ossimString(suffix).downcase();
+   
+   return (value == ".cft");
+}
+
+bool ossimVpfFeatureClass::isFeature(const ossimString& featureName)
+{
+   return (isSimpleFeature(featureName) || isComplexFeature(featureName));
+}
+
+bool ossimVpfFeatureClass::isJoin(const ossimString& featureName)
+{
+   ossimString value = strrchr(featureName.c_str(), '.');
+   if(value == "")
+   {
+      return false;
+   }
+   
+   value = value.downcase();
+   
+   return ( (value == ".cjt")||
+            (value == ".pjt")||
+            (value == ".ljt")||
+            (value == ".ajt")||
+            (value == ".tjt"));
+}
+
+ossimFilename ossimVpfFeatureClass::getTable1()const
+{
+  return theFeatureClassFullPath.dirCat(theTableName1);
+}
+
+ossimFilename ossimVpfFeatureClass::getTable2()const
+{
+  return theFeatureClassFullPath.dirCat(theTableName2);
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClass.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClass.h
new file mode 100644
index 0000000000..0eaf77ac11
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClass.h
@@ -0,0 +1,92 @@
+#ifndef ossimVpfFeatureClass_HEADER
+#define ossimVpfFeatureClass_HEADER
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/context/ossimErrorContext.h"
+
+class ossimVpfCoverage;
+
+class ossimVpfFeatureClass
+{
+public:
+   ossimVpfFeatureClass();
+
+   /*!
+    * Will initialize the feature class for this
+    * coverage and do some validation.
+    */
+   bool openFeatureClass(const ossimString& featureClassName,
+                         const ossimFilename& featureClassFullPath,
+                         const ossimFilename& table1,
+                         const ossimString&   columnNameIdTable1,
+                         const ossimFilename& table2,
+                         const ossimString&   columnNameIdTable2);
+
+  const ossimString& getName()const;
+  
+  /*!
+   * This will specify if this feature is a primitive.
+   * the names of certain primitives are:
+   *
+   * end   Entity node primitive
+   * cnd   Connected node primitive
+   * edg   Edge Primitive
+   * fac   Face Primitive
+   * txt   Text primitive
+   */
+  static bool isPrimitive(const ossimString& featureName);
+  
+   /*!
+    * This just specifies if the input is a simple feature.
+    *
+    * Some of the simple features are:
+    *
+    * .pft  Point feature table
+    * .lft  Line feature table
+    * .aft  area feature table
+    * .tft  text feature table
+    */
+   static bool isSimpleFeature(const ossimString& featureName);
+
+   /*!
+    * This just specifies if the input is a comples feature.
+    *
+    * .cft  Complex feature table.
+    * 
+    */
+   static bool isComplexFeature(const ossimString& featureName);
+
+   /*!
+    * Will use the isComplexFeature and isSimpleFeature to
+    * determine if the input is a feature
+    */
+   static bool isFeature(const ossimString& featureName);
+
+   /*!
+    * Will specifiy if it is a join table.
+    *
+    * Some of the join table type are:
+    *
+    * .cjt  Complex join table
+    * .pjt  Point join table
+    * .ljt  Line join table
+    * .ajt  area join table
+    * .tjt  text join table
+    */
+   static bool isJoin(const ossimString& featureName);
+
+  ossimFilename getTable1()const;
+  ossimFilename getTable2()const;
+
+private:
+
+  ossimFilename     theFeatureClassFullPath;
+  ossimString       theFeatureClassName;
+  ossimFilename     theTableName1;
+  ossimString       theColumnNameId1;
+  ossimFilename     theTableName2;
+  ossimString       theColumnNameId2;
+
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClassSchema.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClassSchema.cpp
new file mode 100644
index 0000000000..b7a4c428ed
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClassSchema.cpp
@@ -0,0 +1,148 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//********************************************************************
+// $Id: ossimVpfFeatureClassSchema.cpp,v 1.4 2004/11/25 22:49:45 dburken Exp $
+#include "ossimVpfLibrary.h"
+#include "ossimVpfCoverage.h"
+#include "ossimVpfFeatureClassSchema.h"
+#include "ossimVpfFeatureClass.h"
+
+ossimVpfFeatureClassSchema::ossimVpfFeatureClassSchema()
+   :theCoverage(NULL)
+{
+}
+
+bool ossimVpfFeatureClassSchema::openSchema(ossimVpfCoverage* coverage)
+{
+   theCoverage = coverage;
+   bool result = false;
+
+   if(theCoverage)
+   {
+      theSchemaTableName = theCoverage->getPath().dirCat("fcs");
+
+      if(theSchemaTableName.exists())
+      {
+         result = openTable(theSchemaTableName);
+
+         if(result)
+         {
+            result = validateColumnNames();
+         }
+         if(result)
+         {
+            setFeatureClassMapping();
+         }
+      }
+   }
+   
+   return result;
+}
+
+void ossimVpfFeatureClassSchema::closeTable()
+{
+   ossimVpfTable::closeTable();
+   theFeatureClassMap.clear();
+}
+
+void ossimVpfFeatureClassSchema::getFeatureClasses(std::vector<ossimString>& featureClassArray)const
+{
+   featureClassArray.clear();
+   std::map<ossimString, ossimVpfFeatureClassSchemaNode>::const_iterator featureClassIter = theFeatureClassMap.begin();
+
+   while(featureClassIter != theFeatureClassMap.end())
+   {
+      featureClassArray.push_back((*featureClassIter).first);
+      ++featureClassIter;
+   }
+}
+
+bool ossimVpfFeatureClassSchema::getFeatureClassNode(const ossimString& featureClass,
+                                                     ossimVpfFeatureClassSchemaNode& featureClassNode)const
+{
+   std::map<ossimString, ossimVpfFeatureClassSchemaNode>::const_iterator fIter = theFeatureClassMap.find(featureClass);
+
+   if(fIter != theFeatureClassMap.end())
+   {
+      featureClassNode = (*fIter).second;
+      return true;
+   }
+
+   return false;
+}
+
+ossim_int32 ossimVpfFeatureClassSchema::getNumberOfFeatureClasses()const
+{
+   return (ossim_int32)theFeatureClassMap.size();
+}
+
+bool ossimVpfFeatureClassSchema::validateColumnNames()const
+{
+   if(isClosed()) return false;
+   return ((getColumnPosition("feature_class")>=0)&&
+           (getColumnPosition("table1")>=0)&&
+           (getColumnPosition("table1_key")>=0)&&
+           (getColumnPosition("table2")>=0)&&
+           (getColumnPosition("table2_key")>=0));
+}
+
+void ossimVpfFeatureClassSchema::setFeatureClassMapping()
+{
+   if(!isClosed())
+   {
+      ossim_int32 featureIdx = getColumnPosition("feature_class");
+      ossim_int32 table1Idx = getColumnPosition("table1");
+      ossim_int32 table1KeyIdx = getColumnPosition("table1_key");
+      ossim_int32 table2Idx = getColumnPosition("table2");
+      ossim_int32 table2KeyIdx = getColumnPosition("table2_key");
+      reset();
+      if(getNumberOfRows() > 0)
+      {
+         row_type row;
+         const int ROWS = getNumberOfRows();
+         for(int rowIdx = 1; rowIdx <= ROWS; ++rowIdx)
+         {
+            if(rowIdx == 1)
+            {
+               row = read_row(rowIdx,
+                              *theTableInformation);
+            }
+            else
+            {
+               row = read_next_row(*theTableInformation);
+            }
+            ossimFilename primitiveTable =  getColumnValueAsString(row,
+                                                                   table2Idx);
+            if(ossimVpfFeatureClass::isPrimitive(primitiveTable))
+            {
+               ossimString primitiveTableKey = getColumnValueAsString(row,
+                                                                      table2KeyIdx);
+               ossimFilename table = getColumnValueAsString(row,
+                                                            table1Idx);
+               ossimString tableKey = getColumnValueAsString(row,
+                                                             table1KeyIdx);
+               ossimString featureClass = getColumnValueAsString(row,
+                                                                 featureIdx);
+               ossimVpfFeatureClassSchemaNode node(table,
+                                                   tableKey,
+                                                   primitiveTable,
+                                                   primitiveTableKey);
+               
+               theFeatureClassMap.insert(make_pair(featureClass,
+                                                   node));
+            }
+            
+            free_row(row, *theTableInformation);
+         }
+      }
+   }
+}
+
+
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClassSchema.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClassSchema.h
new file mode 100644
index 0000000000..732944035f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfFeatureClassSchema.h
@@ -0,0 +1,83 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+//
+//********************************************************************
+// $Id: ossimVpfFeatureClassSchema.h,v 1.5 2003/09/22 00:14:20 dburken Exp $
+#ifndef ossimVpfFeatureClassSchema_HEADER
+#define ossimVpfFeatureClassSchema_HEADER
+#include <iostream>
+#include <map>
+#include <vector>
+#include "ossimVpfTable.h"
+
+class ossimVpfLibrary;
+
+class ossimVpfFeatureClassSchemaNode
+{
+ public:
+   friend ostream& operator <<(std::ostream& out,
+                               const ossimVpfFeatureClassSchemaNode& data)
+      {
+         out << "table    :     " << data.theTable << endl
+             << "key      :     " << data.theTableKey << endl
+             << "primitive:     " << data.thePrimitiveTable << endl
+             << "primitive key: " << data.thePrimitiveTableKey << endl;
+         return out;
+      }
+   
+   ossimVpfFeatureClassSchemaNode(const ossimFilename& table=ossimFilename(""),
+                                  const ossimString& tableKey=ossimString(""),
+                                  const ossimFilename& primitiveTable=ossimFilename(""),
+                                  const ossimString& primitiveTableKey=ossimString(""))
+      :theTable(table),
+      theTableKey(tableKey),
+      thePrimitiveTable(primitiveTable),
+      thePrimitiveTableKey(primitiveTableKey)
+   {
+   }
+   
+   ossimFilename theTable;
+   ossimString   theTableKey;
+   ossimFilename thePrimitiveTable;
+   ossimString   thePrimitiveTableKey;
+};
+
+class ossimVpfFeatureClassSchema : public ossimVpfTable
+{
+public:
+   ossimVpfFeatureClassSchema();
+
+   bool openSchema(ossimVpfCoverage* coverage);
+   virtual void closeTable();
+   
+   void getFeatureClasses(std::vector<ossimString>& featureClassArray)const;
+   bool getFeatureClassNode(const ossimString& featureClass,
+                            ossimVpfFeatureClassSchemaNode& featureClassNode)const;
+   ossim_int32 getNumberOfFeatureClasses()const;
+protected:
+   ossimVpfCoverage* theCoverage;
+   ossimFilename     theSchemaTableName;
+   std::map<ossimString, ossimVpfFeatureClassSchemaNode> theFeatureClassMap;
+   
+   bool validateColumnNames()const;
+   void setFeatureClassMapping();
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibrary.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibrary.cpp
new file mode 100644
index 0000000000..008225b58e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibrary.cpp
@@ -0,0 +1,283 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfLibrary.cpp,v 1.5 2004/11/25 22:46:23 dburken Exp $
+#include <algorithm>
+
+#include "ossimVpfLibrary.h"
+#include "ossimVpfDatabase.h"
+#include "ossimVpfTable.h"
+#include "ossimVpfDatabase.h"
+#include "ossimVpfExtent.h"
+#include "ossimVpfCoverage.h"
+#include "base/common/ossimErrorCodes.h"
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+ossimVpfLibrary::ossimVpfLibrary()
+   :theDatabase(NULL),
+    theLibraryName(""),
+    theLibraryNameFullPath(""),
+    theNumberOfCoverages(0)
+{
+}
+
+ossimVpfLibrary::~ossimVpfLibrary()
+{
+   theDatabase = NULL;
+}
+
+bool ossimVpfLibrary::openLibrary(ossimVpfDatabase* database,
+                                  const ossimString& name,
+                                  const ossimFilename& libraryPath)
+{
+   bool returnCode = true;
+
+   theNumberOfCoverages = 0;
+   theLibraryName = "";
+   theLibraryNameFullPath = "";
+   
+   
+   theLibraryName         = name;
+   theLibraryNameFullPath =  libraryPath;
+   theDatabase            = database;
+   
+   if(!ossimFilename(theLibraryNameFullPath).exists())
+   {
+      returnCode = false;
+   }
+   if(returnCode)
+   {
+      setCoverageNames();
+      
+      ossimVpfTable table;
+      
+      theNumberOfCoverages = theCoverageNames.size();
+      returnCode = (theNumberOfCoverages> 0);
+   }
+   
+   return returnCode;
+}
+
+bool ossimVpfLibrary::getCoverage(long coverageNumber,
+                                  ossimVpfCoverage& coverage)
+{
+   
+   bool result = false;
+   
+   if((coverageNumber >=0) && (coverageNumber < (int)theCoverageNames.size()))
+   {
+      result = coverage.openCoverage(this,
+                                     theCoverageNames[coverageNumber],
+                                     theLibraryNameFullPath.dirCat(theCoverageNames[coverageNumber]));
+   }
+   
+   return result;
+}
+
+bool ossimVpfLibrary::getCoverage(const ossimString& name,
+                                  ossimVpfCoverage& coverage)
+{
+  for(int idx = 0; idx < (int)theCoverageNames.size(); ++idx)
+    {
+      if(theCoverageNames[idx] == name)
+	{
+	  return getCoverage(idx,
+			     coverage);
+	}
+    }
+
+  return false;
+}
+
+bool ossimVpfLibrary::getExtent(ossimVpfExtent& extent)const
+{
+   bool result = false;
+   ossimVpfTable tempTable;
+
+
+   // this code was basically cut paste from vhcl with just
+   // a couple modifications.
+   
+    /* Get library extent from Library Attribute Table (LAT) */
+/*    char* buf;*/
+/*    long int n;*/
+/*    double xmin,ymin,xmax,ymax;*/
+    int libraryNamePosition, xminPosition, yminPosition;
+    int xmaxPosition, ymaxPosition;
+    int i;
+    bool found;
+    row_type row;
+    extent_type libextent;
+
+    if(!theDatabase)
+    {
+       return false;
+    }
+    ossimFilename file(theDatabase->getLibraryAttributeTable());
+    if(!tempTable.openTable(file))
+    {
+       return result;
+    }
+    vpf_table_type *table = tempTable.getVpfTableData();
+       
+    libraryNamePosition = table_pos( "LIBRARY_NAME", *table );
+    found = false;
+    for (i=1;(i<=tempTable.getNumberOfRows())&&(!found);i++)
+    {
+       row = read_row( i, *table );
+       ossimString libraryName = tempTable.getColumnValueAsString(row, libraryNamePosition);
+       libraryName = libraryName.trim();
+       if (libraryName == theLibraryName)
+       {
+          xminPosition = table_pos( "XMIN", *table );
+          yminPosition = table_pos( "YMIN", *table );
+          xmaxPosition = table_pos( "XMAX", *table );
+          ymaxPosition = table_pos( "YMAX", *table );
+
+          libextent.x1 = tempTable.getColumnValueAsString(row, xminPosition).toDouble();
+          libextent.y1 = tempTable.getColumnValueAsString(row, yminPosition).toDouble();
+          libextent.x2 = tempTable.getColumnValueAsString(row, xmaxPosition).toDouble();
+          libextent.y2 = tempTable.getColumnValueAsString(row, ymaxPosition).toDouble();
+          found = true;
+       }
+       else
+       {
+          result = false;
+       }
+       free_row( row, *table );
+    }
+    
+    extent =  ossimVpfExtent(libextent);
+    return result;
+}
+
+ossimFilename ossimVpfLibrary::getPath()const
+{
+   return theLibraryNameFullPath;
+}
+
+ossimString ossimVpfLibrary::getName()const
+{
+   return theLibraryName;
+}
+
+
+bool ossimVpfLibrary::getCoverageNames(std::vector<ossimString>& coverageNames)const
+{
+   bool result = true;
+
+   coverageNames = theCoverageNames;
+   
+   return result;
+}
+
+int ossimVpfLibrary::getNumberOfCoverages()const
+{
+   return theNumberOfCoverages;
+}
+
+bool ossimVpfLibrary::hasCoverage(const ossimString& coverageName)const
+{
+   return (std::find(theCoverageNames.begin(),
+                    theCoverageNames.end(),
+                    coverageName)!=theCoverageNames.end());
+}
+
+ossimString ossimVpfLibrary::getTileName(ossim_int32 id)const
+{
+   ossimString result;
+   if(theLibraryNameFullPath.dirCat("tileref").exists())
+   {
+      if(theTileNameMap.size() <1)
+      {
+         setTileNames();
+      }
+      std::map<ossim_int32, ossimString>::iterator tileNameIter = theTileNameMap.find(id);
+
+      if(tileNameIter != theTileNameMap.end())
+      {
+         result = (*tileNameIter).second;
+      }
+   }
+
+   return result;
+}
+
+void ossimVpfLibrary::getTileNames(std::vector<ossimString>& tileNames)const
+{
+   if(theLibraryNameFullPath.dirCat("tileref").exists())
+   {
+      if(theTileNameMap.size() <1)
+      {
+         setTileNames();
+      }
+      std::map<ossim_int32, ossimString>::iterator tileNameIter = theTileNameMap.begin();
+      while(tileNameIter != theTileNameMap.end())
+      {
+         tileNames.push_back((*tileNameIter).second);
+         ++tileNameIter;
+      }
+   }   
+}
+
+void ossimVpfLibrary::setCoverageNames()
+{
+   ossimVpfTable table;
+   theCoverageNames.clear();
+   // open up the coverage attribute table for this library
+   if(table.openTable(theLibraryNameFullPath.dirCat("cat")))
+   {
+      // we need to have a coverage attribute table validator before
+      // we proceed but for now assume that it is a good table.
+      //
+      theCoverageNames = table.getColumnValues("COVERAGE_NAME");
+   }
+}
+
+void ossimVpfLibrary::setTileNames()const
+{
+   ossimVpfTable table;
+   theTileNameMap.clear();
+   row_type row;
+   if(table.openTable(theLibraryNameFullPath.dirCat("tileref").dirCat("tileref.aft")))
+   {
+      table.reset();
+      const int ROWS = table.getNumberOfRows();
+      for (int rowIdx = 1; rowIdx <= ROWS; ++rowIdx)
+      {
+         // Note:  read_row takes a "one based" index.
+         row = read_row( rowIdx, *(table.getVpfTableData()) );
+         ossim_int32 namePosition   = table.getColumnPosition("TILE_NAME");
+         ossim_int32 tileIdPosition = table.getColumnPosition("ID");
+         
+         ossimString tileName = table.getColumnValueAsString(row,
+                                                             namePosition);;
+         ossimString tileId   = table.getColumnValueAsString(row,
+                                                             tileIdPosition);
+         theTileNameMap.insert(make_pair(tileId.toUInt32(), tileName.trim()));
+         free_row( row, *(table.getVpfTableData()) );
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibrary.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibrary.h
new file mode 100644
index 0000000000..770c166578
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibrary.h
@@ -0,0 +1,73 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfLibrary.h,v 1.3 2004/05/21 21:38:51 dburken Exp $
+#ifndef ossimVpfLibrary_HEADER
+#define ossimVpfLibrary_HEADER
+#include <vector>
+#include <map>
+#include "base/data_types/ossimString.h"
+#include "base/data_types/ossimFilename.h"
+#include "base/context/ossimErrorContext.h" // for ossimErrorCode
+
+class ossimVpfCoverage;
+class ossimVpfDatabase;
+class ossimVpfExtent;
+
+class OSSIMDLLEXPORT ossimVpfLibrary
+{
+public:
+   ossimVpfLibrary();
+   virtual ~ossimVpfLibrary();
+   bool openLibrary(ossimVpfDatabase* database,
+                    const ossimString& name,
+                    const ossimFilename& libraryPath);
+   void              setDatabase(ossimVpfDatabase* database);
+   ossimVpfDatabase* getDatabase()const;
+   bool getCoverage(long coverageNumber, ossimVpfCoverage& coverage);
+   bool getCoverage(const ossimString& name, ossimVpfCoverage& coverage);
+
+   bool                getExtent(ossimVpfExtent& result)const;
+   bool                hasGazette()const;
+
+   ossimFilename       getPath()const;
+   ossimString         getName()const;
+   bool getCoverageNames(std::vector<ossimString>& coverageNames)const;
+   int getNumberOfCoverages()const;
+
+   bool hasCoverage(const ossimString& coverageName)const;
+   ossimString getTileName(ossim_int32 id)const;
+   void getTileNames(std::vector<ossimString>& tileNames)const;
+
+private:
+   ossimVpfDatabase*        theDatabase;
+   ossimString              theLibraryName;
+   ossimFilename            theLibraryNameFullPath;
+   ossim_uint32             theNumberOfCoverages;
+   std::vector<ossimString> theCoverageNames;
+   mutable std::map<ossim_int32, ossimString> theTileNameMap;
+   void setCoverageNames();
+   void setTileNames()const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibraryAttributeTableValidator.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibraryAttributeTableValidator.cpp
new file mode 100644
index 0000000000..f30ba7eab5
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibraryAttributeTableValidator.cpp
@@ -0,0 +1,66 @@
+#include "ossimVpfLibraryAttributeTableValidator.h"
+#include "ossimVpfTable.h"
+
+bool ossimVpfLibraryAttributeTableValidator::isValid(ossimVpfTable& aTable)const
+{
+   // make sure the table is not null
+   if(&aTable == NULL)
+   {
+      return false;
+   }
+
+   // and make sure that the table is not closed
+   if(aTable.isClosed())
+   {
+      return false;
+   }
+
+   // get the table data defined in vpf_util/vpftable.h"
+   const vpf_table_type* data = aTable.getVpfTableData();
+
+   if(!data)
+   {
+      return false;
+   }
+   // if the file is not open then we can't validate
+   if(!data->fp)
+   {
+      return false;
+   }
+
+   // The way that we will validate is to see if the columns of a dht
+   // exist.  if the column didn't exist then the position
+   // will be negative
+   long column = table_pos("ID", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("LIBRARY_NAME", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("XMIN", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("YMIN", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("XMAX", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+   column = table_pos("YMAX", *data);
+   if(column < 0)
+   {
+      return false;
+   }
+
+   return true;
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibraryAttributeTableValidator.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibraryAttributeTableValidator.h
new file mode 100644
index 0000000000..1d5f5f10fb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfLibraryAttributeTableValidator.h
@@ -0,0 +1,12 @@
+#ifndef ossimVpfLibraryAttributeTableValidator_HEADER
+#define ossimVpfLibraryAttributeTableValidator_HEADER
+#include "ossimVpfTableValidator.h"
+
+class ossimVpfTable;
+class ossimVpfLibraryAttributeTableValidator :public ossimVpfTableValidator
+{
+public:
+   virtual bool isValid(ossimVpfTable& aTable)const;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTable.cpp b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTable.cpp
new file mode 100644
index 0000000000..5935a5a5ef
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTable.cpp
@@ -0,0 +1,898 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc.
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfTable.cpp,v 1.12 2005/10/17 18:42:27 gpotts Exp $
+#include <vec/vpf/ossimVpfTable.h>
+#include <vec/vpf/vpf.h>
+#include <base/common/ossimErrorCodes.h>
+
+std::ostream& operator <<(std::ostream& out,
+                     const ossimVpfTable& data)
+{
+   data.print(out);
+   return out;
+}
+
+ossimVpfTable::ossimVpfTable()
+   :theTableInformation(NULL)
+{
+}
+
+ossimVpfTable::~ossimVpfTable()
+{
+   if(theTableInformation)
+   {
+      closeTable();
+      delete theTableInformation;
+      theTableInformation = NULL;
+   }
+}
+
+bool ossimVpfTable::openTable(const ossimFilename& tableName)
+{
+   closeTable();
+
+   if(is_vpf_table(const_cast<char*>(tableName.c_str())))
+   {
+      if(theTableInformation)
+      {
+         delete theTableInformation;
+         theTableInformation = NULL;
+      }
+      theTableInformation = new vpf_table_type;
+      memset(theTableInformation, 0, sizeof(vpf_table_type));
+
+      theTableName = tableName;
+      *theTableInformation = vpf_open_table(const_cast<char*>(tableName.c_str()),
+                                            disk,
+                                            "rb",
+                                            NULL);
+   }
+   else
+   {
+      delete theTableInformation;
+      theTableInformation = NULL;
+
+      return false;
+   }
+
+   return true;
+}
+
+void ossimVpfTable::closeTable()
+{
+   if(theTableInformation&&(theTableInformation->status!=CLOSED))
+   {
+      vpf_close_table(theTableInformation);
+   }
+}
+
+int ossimVpfTable::getNumberOfRows()const
+{
+  if(theTableInformation) return theTableInformation->nrows;
+
+  return 0;
+}
+
+int ossimVpfTable::getNumberOfColumns()const
+{
+  if(theTableInformation) return theTableInformation->nfields;
+
+  return 0;
+}
+
+ossimString ossimVpfTable::getColumnName(int idx)const
+{
+  if((idx < 0) || idx > getNumberOfColumns())
+    {
+      return ossimString("");
+    }
+  return ossimString(theTableInformation->header[idx].name);
+}
+
+bool ossimVpfTable::isClosed()const
+{
+   return (theTableInformation &&
+           (theTableInformation->status==CLOSED));
+}
+
+void ossimVpfTable::reset()const
+{
+   if(theTableInformation &&
+      (theTableInformation->status!=CLOSED))
+   {
+      long fpos;
+
+      fpos = index_pos(0, *theTableInformation);
+      fseek(theTableInformation->fp, fpos, SEEK_SET);
+   }
+}
+
+bool ossimVpfTable::goToRow(long row)const
+{
+   if(theTableInformation &&
+      (theTableInformation->status!=CLOSED))
+   {
+      long fpos;
+
+      fpos = index_pos(row, *theTableInformation);
+      if(fpos < 0)
+      {
+         return false;
+      }
+      fseek(theTableInformation->fp, fpos, SEEK_SET);
+   }
+
+   return true;
+}
+
+std::vector<ossimString> ossimVpfTable::getColumnValues(const ossimString& columnName)const
+{
+	std::vector<ossimString> result;
+
+   if(theTableInformation &&
+      theTableInformation->status == OPENED)
+   {
+      long int columnNumber = table_pos(const_cast<char*>(columnName.c_str()), *theTableInformation);
+
+      if(columnNumber >=0 &&
+         (columnNumber < theTableInformation->nfields))
+      {
+         row_type row;
+         // start at the first row of the table
+         reset();
+         for (int rowIndex = 1;
+              rowIndex <= theTableInformation->nrows;
+              ++rowIndex)
+         {
+            row = read_next_row(*theTableInformation);
+            ossimString value = getColumnValueAsString(row,
+                                                       columnNumber);
+	    value.trim();
+            result.push_back(value);
+            free_row(row, *theTableInformation);
+         }
+      }
+   }
+
+   return result;
+}
+
+std::vector<ossimString> ossimVpfTable::getColumnValues(long columnNumber)const
+{
+	std::vector<ossimString> result;
+
+   if(theTableInformation &&
+      theTableInformation->status == OPENED)
+   {
+      if(columnNumber >=0 &&
+         (columnNumber < theTableInformation->nfields))
+      {
+         row_type row;
+         // start at the first row of the table
+         reset();
+         for (int rowIndex = 0;
+              rowIndex < theTableInformation->nrows;
+              ++rowIndex)
+         {
+            row = read_next_row(*theTableInformation);
+            ossimString value = getColumnValueAsString(row,
+                                                       columnNumber);
+//            value = value.downcase();
+            value = value.trim();
+            result.push_back(value);
+            free_row(row, *theTableInformation);
+         }
+      }
+   }
+
+   return result;
+}
+
+
+
+ossimString ossimVpfTable::getColumnValueAsString(row_type& row,
+                                                  long columnNumber)const
+{
+   ossimString result;
+   long n=1;
+   switch(theTableInformation->header[columnNumber].type)
+   {
+   case 'T': // it's of type text so
+   {
+      char c;
+      char *buf = (char *)get_table_element(columnNumber,
+                                            row,
+                                            *theTableInformation,
+                                            &c,
+                                            &n);
+      if(buf)
+      {
+         result = buf;
+         free(buf);
+      }
+      else
+      {
+         result = c;
+      }
+      break;
+   }
+   case 'I':
+   {
+      long value;
+      long* v = (long*)get_table_element(columnNumber,
+                                         row,
+                                         *theTableInformation,
+                                         &value,
+                                         &n);
+      if(v)
+      {
+         result = ossimString::toString(v[0]);
+
+         free(v);
+      }
+      else
+      {
+         result = ossimString::toString(value);
+      }
+      break;
+   }
+   case 'S':
+   {
+      short int value;
+      short int* v = (short int*)get_table_element(columnNumber,
+                                                   row,
+                                                   *theTableInformation,
+                                                   &value,
+                                                   &n);
+      if(v)
+      {
+         result = ossimString::toString(v[0]);
+
+         free(v);
+      }
+      else
+      {
+         result = ossimString::toString(value);
+      }
+      break;
+   }
+   case 'F':
+   {
+      float value;
+      float* v = (float*)get_table_element(columnNumber,
+                                           row,
+                                           *theTableInformation,
+                                           &value,
+                                           &n);
+      if(v)
+      {
+         value = v[0];
+         free(v);
+      }
+      if (!is_vpf_null_float(value))
+      {
+         result = ossimString::toString(value);
+      }
+      else
+      {
+         result = "nan";
+      }
+      break;
+   }
+   case 'B':
+   {
+      double value;
+      double* tempBuf = (double*)get_table_element(columnNumber,
+                                                 row,
+                                                 *theTableInformation,
+                                                 &value,
+                                                 &n);
+      if(tempBuf)
+      {
+         value = tempBuf[0];
+         free(tempBuf);
+      }
+      if (!is_vpf_null_double(value))
+      {
+         result = ossimString::toString(value);
+      }
+      else
+      {
+         result = "nan";
+      }
+
+      break;
+   }
+   case 'C':
+   {
+      coordinate_type coordType;
+      coordinate_type* temp = (coordinate_type*)get_table_element(columnNumber,
+                                                                  row,
+                                                                  *theTableInformation,
+                                                                  &coordType,
+                                                                  &n);
+      if(temp)
+      {
+         coordType = temp[0];
+         free(temp);
+      }
+      result = ossimString::toString(coordType.x)+
+               ossimString(" ") +
+               ossimString::toString(coordType.y);
+      break;
+   }
+   case 'K':
+   {
+      id_triplet_type idTripletType;
+      id_triplet_type* tempType = (id_triplet_type*)get_table_element(columnNumber,
+                                                                      row,
+                                                                      *theTableInformation,
+                                                                      &idTripletType,
+                                                                      &n);
+      if(tempType)
+      {
+         idTripletType = tempType[0];
+         free (tempType);
+      }
+      result = ossimString(idTripletType.type) +
+               ossimString(" ") +
+               ossimString::toString(idTripletType.id) +
+               ossimString(" ") +
+               ossimString::toString(idTripletType.tile)+
+               ossimString(" ") +
+               ossimString::toString(idTripletType.exid);
+      break;
+   }
+   case 'D':
+   {
+      date_type date, formatDate;
+      date_type* temp = (date_type*)get_table_element(columnNumber,
+                                                      row,
+                                                      *theTableInformation,
+                                                      &date,
+                                                      &n);
+      if(temp)
+      {
+         free(temp);
+      }
+      format_date(date, formatDate);
+      result = formatDate;
+   }
+   }
+   result.trim();
+   return result;
+}
+
+ossimString ossimVpfTable::getColumnValueAsString(ossim_int32 rowNumber,
+                                                  long columnNumber)const
+{
+   row_type row = read_row( rowNumber, *theTableInformation);
+   ossimString result = getColumnValueAsString(row,
+                                               columnNumber);
+   free_row(row, *theTableInformation);
+
+   return result;
+}
+
+ossimString ossimVpfTable::getColumnValueAsString(const ossimString& columnName)
+{
+   if(theTableInformation &&
+      (theTableInformation->status!=CLOSED))
+   {
+      long int columnNumber = table_pos(const_cast<char*>(columnName.c_str()),
+                                        *theTableInformation);
+      row_type row = read_next_row(*theTableInformation);
+      ossimString result = getColumnValueAsString(row,
+                                                  columnNumber);
+      free_row(row, *theTableInformation);
+      return result;
+   }
+
+   return "";
+}
+
+ossim_int32 ossimVpfTable::getColumnPosition(const ossimString& columnName)const
+{
+   return ((ossim_int32)table_pos(const_cast<char*>(columnName.c_str()), *theTableInformation));
+}
+
+void ossimVpfTable::print(std::ostream& out)const
+{
+   if(theTableInformation &&
+      (theTableInformation->status!=CLOSED))
+   {
+      // make sure we are at the beginning of the table.
+      this->reset();
+
+
+      // the rest of this code is from the vpfutil.  The vpfutil
+      // was grabbed from the vhcl map server software.
+      vpf_table_type& table = *theTableInformation;
+
+      long       i,j,k,n;
+      short int  ival=0,*iptr=NULL;
+      long       lval=0,*lptr=NULL;
+      float      fval=0,*fptr=NULL;
+      date_type  dval,*dptr=NULL;
+      id_triplet_type kval={0,0,0}, *kptr=NULL;
+      coordinate_type cval={0,0}, *cptr=NULL;
+      char       *buf,  ch, date[40];
+      row_type   row;
+
+
+	  out << "table name:        " << theTableName << std::endl
+		  << "desciption:        " << table.description << std::endl
+		  << std::endl;
+
+	  out << "Definition:" << std::endl;
+      for (i=0;i<table.nfields;i++) {
+         if (table.header[i].count < 0)
+         {
+
+            out << table.header[i].name << " ("
+                << table.header[i].type << ",*)  "
+				<< table.header[i].description << std::endl;
+         }
+         else
+         {
+            out << table.header[i].name << " ("
+                << table.header[i].type << ","
+                << table.header[i].count << ")  "
+				<< table.header[i].description << std::endl;
+         }
+      }
+
+	  out << "\nContents:" << std::endl;
+      for (i=1;i<=table.nrows;i++)
+      {
+         row = read_next_row(table);
+         for (j=0;j<table.nfields;j++)
+         {
+            out << table.header[j].name << ": ";
+            switch (table.header[j].type) {
+	    case 'T':
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&ch,&n);
+
+		  out << ch << std::endl;
+	       }
+               else
+               {
+		  buf = (char *)get_table_element(j,row,table,NULL,&n);
+		  n = strlen(table.header[j].name) + 2;
+		  for (k=0;k<(long)strlen(buf);k++)
+                  {
+                     out << buf[k];
+		     n++;
+		     if (n>80)
+                     {
+						 out << std::endl;
+			n = 0;
+		     }
+		  }
+				  out << std::endl;
+		  free(buf);
+	       }
+	       break;
+	    case 'I': // long
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&lval,&n);
+		  if (!is_vpf_null_float(lval))
+                  {
+					  out << lval << std::endl;
+                  }
+		  else
+                  {
+					  out << "null" << std::endl;
+                  }
+	       }
+               else
+               {
+		  lptr = (long*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+		     if (!is_vpf_null_float(lptr[k]))
+                     {
+                        out << lptr[k];
+                     }
+		     else
+                     {
+                        out << "null";
+                     }
+		  }
+				  out << std::endl;
+		  free(lptr);
+	       }
+	       break;
+            case 'R': // for double
+            {
+               double *dptr=NULL;
+               double value = 0;
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&value,&n);
+                  if(!is_vpf_null_double(value))
+                  {
+					  out << "null" << std::endl;
+                  }
+                  else
+                  {
+					  out << value << std::endl;
+                  }
+               }
+               else
+               {
+		  dptr = (double*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+		     if (!is_vpf_null_double(dptr[k]))
+                     {
+                        out << dptr[k];
+                     }
+		     else
+                     {
+                        out << "null ";
+                     }
+		  }
+				  out << std::endl;
+		  free(dptr);
+               }
+            }
+	    case 'S': // integer
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&ival,&n);
+		  if (ival != (short int)INT_MAX)
+                  {
+					  out << ival << std::endl;
+                  }
+		  else
+                  {
+					  out << "null" << std::endl;
+                  }
+	       }
+               else
+               {
+		  iptr = (short int*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+		     if (iptr[k] != (short int)INT_MAX)
+                     {
+                        out << iptr[k];
+                     }
+		     else
+                     {
+                        out << "null ";
+                     }
+		  }
+				  out << std::endl;
+		  free(iptr);
+	       }
+	       break;
+	    case 'F': // float type
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&fval,&n);
+		  if (!is_vpf_null_float(fval))
+                  {
+					  out << fval << std::endl;
+                  }
+		  else
+                  {
+					  out << "null" << std::endl;
+                  }
+	       }
+               else
+               {
+		  fptr = (float*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+		     if (!is_vpf_null_float(fptr[k]))
+                     {
+                        out << fptr[k] << " ";
+                     }
+		     else
+                     {
+                        out << "null ";
+                     }
+		  }
+				  out << std::endl;
+		  free(fptr);
+	       }
+	       break;
+            case 'Y':
+            {
+               double_tri_coordinate_type dtctValue, *dtctPtr;
+	       if (table.header[j].count==1)
+               {
+                  get_table_element(j,row,table,&dtctValue,&n);
+                  out << "(";
+                  if(is_vpf_null_double(dtctValue.x))
+                  {
+                     out << "null, ";
+                  }
+                  else
+                  {
+                     out << dtctValue.x << ", ";
+                  }
+                  if(is_vpf_null_double(dtctValue.y))
+                  {
+                     out << "null, ";
+                  }
+                  else
+                  {
+                     out << dtctValue.y << ", ";
+                  }
+                  if(is_vpf_null_double(dtctValue.z))
+                  {
+                     out << "null, ";
+                  }
+                  else
+                  {
+                     out << dtctValue.z << ", ";
+                  }
+               }
+               else
+               {
+		  dtctPtr = (double_tri_coordinate_type*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+                     out << "(";
+                     if(is_vpf_null_double(dtctPtr[k].x))
+                     {
+                        out << "null, ";
+                     }
+                     else
+                     {
+                        out << dtctPtr[k].x  << ", ";
+                     }
+                     if(is_vpf_null_double(dtctPtr[k].y))
+                     {
+                        out << "null, ";
+                     }
+                     else
+                     {
+                        out << dtctPtr[k].y  << ", ";
+                     }
+                     if(is_vpf_null_double(dtctPtr[k].z))
+                     {
+                        out << "null, ";
+                     }
+                     else
+                     {
+                        out << dtctPtr[k].z  << ", ";
+                     }
+                  }
+                  free(dtctPtr);
+               }
+               break;
+            }
+            case 'Z': // tri coordinate types x, y, z
+            {
+               tri_coordinate_type tcval={0,0,0}, *tcptr=NULL;
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&tcval,&n);
+                  out << "(";
+                  if(is_vpf_null_float(tcval.x))
+                  {
+                     out << "null" << ",";
+                  }
+                  else
+                  {
+                     out << tcval.x << ", ";
+                  }
+                  if(is_vpf_null_float(tcval.y))
+                  {
+                     out << "null" << ", ";
+                  }
+                  else
+                  {
+                     out << tcval.y << ", ";
+                  }
+                  if(is_vpf_null_float(tcval.z))
+                  {
+					  out << "null)" << std::endl;
+                  }
+                  else
+                  {
+					  out << tcval.z << ")" << std::endl;
+                  }
+	       }
+               else
+               {
+		  tcptr = (tri_coordinate_type*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+                     out << "(";
+                     if(is_vpf_null_float(tcptr[k].x))
+                     {
+                        out << "null, ";
+                     }
+                     else
+                     {
+                        out << tcptr[k].x << ", ";
+                     }
+                     if(is_vpf_null_float(tcptr[k].y))
+                     {
+                        out << "null, ";
+                     }
+                     else
+                     {
+                        out << tcptr[k].y << ", ";
+                     }
+                     if(is_vpf_null_float(tcptr[k].z))
+                     {
+                        out << "null)";
+                     }
+                     else
+                     {
+                        out << tcptr[k].z << ")";
+                     }
+                  }
+				  out << std::endl;
+		  free(cptr);
+	       }
+	       break;
+            }
+	    case 'C': // coordinate type  x, y
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&cval,&n);
+                  out << "(";
+                  if(is_vpf_null_float(cval.x))
+                  {
+                     out << "null, ";
+                  }
+                  else
+                  {
+                     out << cval.x << ", ";
+                  }
+                  if(is_vpf_null_float(cval.y))
+                  {
+                     out << "null, ";
+                  }
+                  else
+                  {
+                     out << cval.y << ")";
+                  }
+	       }
+               else
+               {
+		  cptr = (coordinate_type*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+
+                     out << "(" << cptr[k].x << "," << cptr[k].y << ") ";
+                  }
+				  out << std::endl;
+		  free(cptr);
+	       }
+	       break;
+            case 'B': // double coordinate type
+            {
+               double_coordinate_type dct, *dctPtr;
+
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&dct,&n);
+
+                  out << "(";
+                  if(is_vpf_null_double(dct.x))
+                  {
+                     out << "null, ";
+                  }
+                  else
+                  {
+                     out << dct.x << ", ";
+                  }
+                  if(is_vpf_null_double(dct.y))
+                  {
+                     out << "null, ";
+                  }
+                  else
+                  {
+                     out << dct.y << ")";
+                  }
+	       }
+               else
+               {
+		  dctPtr = (double_coordinate_type*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+                     out << "(";
+                     if(is_vpf_null_double(dctPtr[k].x))
+                     {
+                        out << "null,";
+                     }
+                     else
+                     {
+                        out << dctPtr[k].x << ", ";
+                     }
+                     if(is_vpf_null_double(dctPtr[k].y))
+                     {
+                        out << "null,";
+                     }
+                     else
+                     {
+                        out << dctPtr[k].y << ", ";
+                     }
+                  }
+				  out << std::endl;
+		  free(dctPtr);
+	       }
+
+            }
+	    case 'K': //id triplet
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&kval,&n);
+                  out <<  "(" << kval.id
+                      << ", " << kval.tile
+                      << ", " << kval.exid
+					  << ")" << std::endl;
+	       }
+               else
+               {
+		  kptr = (id_triplet_type*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+                     out <<  "(" << kptr[k].id
+                         << ", " << kptr[k].tile
+                         << ", " << kptr[k].exid
+						 << ")  " << std::endl;
+
+                  }
+				  out << std::endl;
+		  free(kptr);
+	       }
+	       break;
+	    case 'D':   /* Date */
+	       if (table.header[j].count==1)
+               {
+		  get_table_element(j,row,table,&dval,&n);
+		  format_date(dval,date);
+		  out << date << std::endl;
+	       }
+               else
+               {
+		  dptr = (date_type*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+                  {
+		     format_date((char*)(&dptr[k]),date);
+                     out << dptr[k] << " ";
+		  }
+				  out << std::endl;
+		  free(dptr);
+	       }
+	       break;
+            }
+         }
+		 out << std::endl;
+         free_row( row, table );
+      }
+   }
+}
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTable.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTable.h
new file mode 100644
index 0000000000..069117ba98
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTable.h
@@ -0,0 +1,103 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// OSSIM is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License 
+// as published by the Free Software Foundation.
+//
+// This software is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+//
+// You should have received a copy of the GNU General Public License
+// along with this software. If not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-
+// 1307, USA.
+//
+// See the GPL in the COPYING.GPL file for more details.
+//
+// Author: Garrett Potts (gpotts@imagelinks.com)
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: ossimVpfTable.h,v 1.7 2005/10/17 18:42:27 gpotts Exp $
+#ifndef ossimVpfTable_HEADER
+#define ossimVpfTable_HEADER
+#include <iostream>
+#include <vector>
+
+
+#include <base/data_types/ossimString.h>
+#include <base/context/ossimErrorContext.h>
+#include <base/data_types/ossimFilename.h>
+#include <vec/vpf/vpf.h>
+
+class OSSIM_DLL ossimVpfTable
+{
+public:
+	friend OSSIM_DLL std::ostream& operator <<(std::ostream& out,
+                               const ossimVpfTable& data);
+   
+   ossimVpfTable();
+   virtual ~ossimVpfTable();
+
+   /*!
+    * Will open the table.  Will return OSSIM_OK if it was successful
+    * or OSSIM_ERROR if unsuccessful.
+    */
+   virtual bool openTable(const ossimFilename& tableName);
+
+   /*!
+    * Closes the table.
+    */
+   virtual void closeTable();
+
+   /*!
+    * This code is going to be cut paste from the vpf_dump_table
+    * found in vpf_util/vpf_dump_table.c.  This function only allows
+    * you to output to a file.  We need to re-write it to go to a stream.
+    * the best way to do this is to cut and paste the code.
+    */
+   virtual void print(std::ostream& out)const;
+
+  int getNumberOfRows()const;
+  int getNumberOfColumns()const;
+  ossimString getColumnName(int idx)const;
+   virtual bool isClosed()const;
+   /*!
+    * This method will set the row pointer back to
+    * the start of the table.
+    */
+   virtual void reset()const;
+
+   virtual bool goToRow(long row)const;
+   vpf_table_type* getVpfTableData()
+      {
+         return theTableInformation;
+      }
+
+	  std::vector<ossimString> getColumnValues(const ossimString& columnName)const;
+	  std::vector<ossimString> getColumnValues(long columnNumber)const;
+   
+   ossimString getColumnValueAsString(row_type& row,
+                                      long columnNumber)const;
+   ossimString getColumnValueAsString(ossim_int32 rowNumber,
+                                      long columnNumber)const;
+   ossimString getColumnValueAsString(const ossimString& columnName);
+   ossim_int32 getColumnPosition(const ossimString& columnName)const;
+
+protected:
+   /*!
+    * this structure is in vpf_util/vpftable.h file.
+    * it holds all the access information to the table.
+    */
+   vpf_table_type* theTableInformation;
+
+   /*!
+    * Will hold the complete path and name to this table.
+    */
+   ossimFilename   theTableName;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTableValidator.h b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTableValidator.h
new file mode 100644
index 0000000000..6b7270522c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/ossimVpfTableValidator.h
@@ -0,0 +1,18 @@
+//-----------------------------------------------------------------
+// License:  LGPL
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//-----------------------------------------------------------------
+#ifndef ossimVpfTableValidator_HEADER
+#define ossimVpfTableValidator_HEADER
+
+class ossimVpfTable;
+
+class ossimVpfTableValidator
+{
+public:
+   virtual ~ossimVpfTableValidator(){}
+   virtual bool isValid(ossimVpfTable& aTable)const=0;
+};
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vec/vpf/vpf.h b/Utilities/OSSIM/ossim_core/vec/vpf/vpf.h
new file mode 100644
index 0000000000..19c29b1e5f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vec/vpf/vpf.h
@@ -0,0 +1,34 @@
+//*******************************************************************
+// Copyright (C) 2000 ImageLinks Inc. 
+//
+// License:  LGPL
+//
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+// Description: This class give the capability to access tiles from an
+//              vpf file.
+//
+//********************************************************************
+// $Id: vpf.h,v 1.4 2004/11/10 17:44:32 dburken Exp $
+#ifndef VPF_HEADER
+#define VPF_HEADER
+
+#include <ossimConfig.h>
+
+#if __OSSIM_CARBON__
+#define MAXINT INT_MAX
+#endif
+
+extern "C"
+{
+#include "vpf_util/vpfview.h"   
+#include "vpf_util/vpfselec.h"
+#include "vpf_util/vpftable.h"
+#include "vpf_util/vpfprim.h"
+#include "vpf_util/vpfmisc.h"
+#include "vpf_util/vpfdisp.h"
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/.cvsignore b/Utilities/OSSIM/ossim_core/vpf_util/.cvsignore
new file mode 100644
index 0000000000..a4383358ec
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/.cvsignore
@@ -0,0 +1 @@
+*.d
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/CMakeLists.txt b/Utilities/OSSIM/ossim_core/vpf_util/CMakeLists.txt
new file mode 100644
index 0000000000..f7bd0e5490
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB_RECURSE ossim_vpf_SRCS "*.c")
+FILE(GLOB_RECURSE ossim_vpf_HDRS "*.h")
+ADD_LIBRARY(ossim_vpf ${ossim_vpf_SRCS})
+
+INSTALL_TARGETS(/lib/otb/ ossim_vpf)
+INSTALL_FILES(/include/otb/Utilities/OSSIM/ossim_core/ "\\.h$" ${ossim_vpf_HRDS})
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/bitarray.c b/Utilities/OSSIM/ossim_core/vpf_util/bitarray.c
new file mode 100644
index 0000000000..b92ab1b42f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/bitarray.c
@@ -0,0 +1,1085 @@
+/******************************************************************************
+ *
+ *N  Module BITARRAY.C
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Bit manipulation of virtual 2-dimensional arrays.  These arrays are
+ *    stored in a 1-dimensional bit array (MAP).
+ *    Some notes on problems with this code:
+ *     1. all bit mapping must be with your mapextents-2.  ie, if you
+ *        declare a bitarray 200 by 200, only 198 by 198 is usable.
+ *     2. when drawing/manipulating lines, you must use a delta of 0 for
+ *        the x or y.  If you do not, the line will not be straight.  In
+ *        other words, use coordinate geometry.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October, 1990, Kernighan/Richie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions:
+ *F
+ *    void SETROW( ArrayOfBits MAP, int XMIN, int XMAX, int Y );
+ *    void CLEARROW( ArrayOfBits MAP, int XMIN, int XMAX, int Y );
+ *    void TOGGLEROW( ArrayOfBits MAP, int XMIN, int XMAX, int Y );
+ *    void SETCOLUMN( ArrayOfBits MAP, int X, in YMIN, int YMAX );
+ *    void CLEARCOLUMN( ArrayOfBits MAP, int X, int YMIN, int YMAX );
+ *    void TOGGLECOLUMN(ArrayOfBits MAP, int X, int YMIN, int YMAX );
+ *    ArrayOfBits MakeArrayOfBits( int deltaX, int deltaY );
+ *    int FreeArrayOfBits( ArrayOfBits map );
+ *    int PointGetBit( ArrayOfBits map, IPoint point );
+ *    int PointSetBit( ArrayOfBits map, IPoint at, int value );
+ *    int LineSetBit( ArrayOfBits map, ISegment seg, int value );
+ *    int LineXorBit( ArrayOfBits map, ISegment seg, int value );
+ *    int TrapezoidXorBit( ArrayOfBits map, Isegment seg, int value );
+ *****************************************************************************/
+
+#ifndef __MSDOS__
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#endif
+#include "xmemory.h"
+#include "polygrf.h"
+#include <stdlib.h>
+
+
+/******************************************************************************
+ *
+ *N  SETROW
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Set bits in row Y of 2-d array MAP from XMIN to XMAX.
+ *    This procedure sets bits in MAP based on XMIN, XMAX, and Y.  If XMIN and
+ *    XMAX are equal, it is assumed that there is a 1bit array in MAP, and this
+ *    bit is set to ~(255>>(8-(XMIN MOD 8))) && ~(255<<(1+(XMAX MOD 8))).
+ *    The index is calculated by: Y*MAP.rowcount+ (XMAX >> 3) or
+ *    Y*MAP.rowcount +(XMIN >> 3).  Note that >> is rightshift the bits,
+ *    no carry.
+ *    If XMAX and XMIN are different values, a for loop is used to go from
+ *    the above index values, moving a string of 1's into each location,
+ *    except for the first location, which gets ~(255>>8-(XMIN MOD 8)) and the
+ *    last location, which gets ~(255<<1+(XMAX MOD 8)).  As the name suggests
+ *    a row is set referenced by y.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    MAP <in/out>  == (ArrayOfBits) 2-d array to be modified
+ *    XMIN <input>  == (int) bottom of refence
+ *    XMAX <input>  == (int) top of reference
+ *    Y    <input>  == (int) row to be modified
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990, Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Macros Called:
+ *M
+ *    LEFTBITS(INDEX)   BITARRAY.C
+ *    RIGHTBITS(INDEX)  BITARRAY.C
+ *E
+ *****************************************************************************/
+
+void  SETROW( ArrayOfBits MAP,
+             int         XMIN,
+             int         XMAX,
+             int         Y )
+{
+  register int start /*= (((Y)*(MAP.rowcount))+((XMIN)>>3))*/;
+  register int end   /*= (((Y)*(MAP.rowcount))+((XMAX)>>3))*/;
+  register int sbit  /*= ((XMIN)%8)*/;
+  register int ebit  /*= ((XMAX)%8)*/;
+
+  if (XMIN < 0) XMIN = 0;
+  start = (((Y)*(MAP.rowcount))+((XMIN)>>3));
+  if (XMAX > MAP.bounding.x) XMAX = MAP.bounding.x-1;
+  end = (((Y)*(MAP.rowcount))+((XMAX)>>3));
+  sbit = ((XMIN) % 8);
+  ebit = ((XMAX) % 8);
+  if ((0 > Y) || (Y > MAP.bounding.y) || (MAP.array == NULL) || (XMAX < XMIN)) return;
+
+  if (start == end)
+    MAP.array[start] |= ((RIGHTBITS(sbit))&LEFTBITS(ebit));
+  else
+    {
+      MAP.array[start] |= (RIGHTBITS(sbit));
+      for(start++;start<end;start++)
+	MAP.array[start] |= LEFTBITS(7);
+      MAP.array[start] |= LEFTBITS(ebit);
+    }
+}
+
+/*****************************************************************************
+ *
+ *N  CLEARROW
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Erases bits in row Y of 2-d array MAP from XMIN to XMAX.
+ *    This procedure clears bits in MAP based on XMIN, XMAX, and Y.  If XMIN
+ *    and XMAX are equal, it is assumed that there is a 1 bit array in MAP,
+ *    and this bit is set to:
+ *    ~(~(255>>(8-(XMIN MOD 8))) && ~(255<<(1+(XMAX MOD 8)))).  The index is
+ *    calculated as in the previous procedure.
+ *    If XMAX and XMIN are different values, a for loop is used to go from
+ *    the above index values, moving a string of 0's into each location.  The
+ *    first location gets ~(~(255>>(8-(XMIN MOD 8)))) and the last location
+ *    gets ~(~(255<<1+(XMAX MOD 8))).  As the name suggest, a row is erased
+ *    referenced by y.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    MAP <in/out>  == (ArrayOfBits) 2-d array of bits to be modified
+ *    XMIN <input>  == (int) bottom of reference
+ *    XMAX <input>  == (int) top of reference
+ *    Y    <input>  == (int) row to be modified in the 2 d array
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990, Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Macros Called:
+ *M
+ *    LEFTBITS(INDEX)   BITARRAY.C
+ *    RIGHTBITS(INDEX)  BITARRAY.C
+ *E
+ ****************************************************************************/
+void  CLEARROW( ArrayOfBits MAP,
+               int         XMIN,
+               int  	   XMAX,
+	       int 	   Y )
+{
+  register int start /*= (((Y)*(MAP.rowcount))+((XMIN)>>3))*/;
+  register int end   /*= (((Y)*(MAP.rowcount))+((XMAX)>>3))*/;
+  register int sbit  /*= ((XMIN)%8)*/;
+  register int ebit  /*= ((XMAX)%8)*/;
+
+  if (XMIN < 0) XMIN=0;
+  start = (((Y)*(MAP.rowcount))+((XMIN)>>3));
+  if (XMAX > MAP.bounding.x) XMAX = MAP.bounding.x-1;
+  end = (((Y)*(MAP.rowcount))+((XMAX)>>3));
+  sbit = ((XMIN)%8);
+  ebit = ((XMAX)%8);
+  if ((0 > Y) || (Y > MAP.bounding.y) || (MAP.array == NULL) || (XMAX < XMIN)) return;
+
+  if (start == end)
+    MAP.array[start] &= ~((RIGHTBITS(sbit))&LEFTBITS(ebit));
+  else
+    {
+      MAP.array[start] &= ~(RIGHTBITS(sbit));
+      for(start++;start<end;start++)
+	MAP.array[start] &= ~LEFTBITS(7);
+      MAP.array[start] &= ~LEFTBITS(ebit);
+    }
+}
+
+/*****************************************************************************
+ *
+ *N  TOGGLEROW
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose
+ *P
+ *    This procedure is used for the exclusive or-ing (XOR) of the input MAP
+ *    vs the mask of 1's.   Specifically, row Y is modified from bits XMIN to
+ *    YMAX.
+ *    The index is created as in the previous 2 procedures.  The mask is MAP
+ *    XOR a string of 1's.
+ *    Essentially, this turns on every bit that was turned off, and turns off
+ *    every bit that was turned on.  As the name suggests, the index is a row
+ *    referenced by y.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    MAP <in/out>  == (ArrayOfBits) 2 dimensional array of bits to be modified
+ *    XMIN <input>  == (int) low bit to begin modification
+ *    XMAX <input>  == (int) high bit to end modification
+ *    Y    <input>  == (int) row to be modified in the 2-d array
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October, 1990, Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Macros Called:
+ *M
+ *    LEFTBITS(INDEX)  BITARRAY.C
+ *    RIGHTBITS(INDEX) BITARRAY.C
+ *E
+ ****************************************************************************/
+void TOGGLEROW( ArrayOfBits MAP,
+	       int         XMIN,
+	       int         XMAX,
+	       int         Y )
+{
+  register int start /*= (((Y)*(MAP.rowcount))+((XMIN)>>3))*/;
+  register int end   /*= (((Y)*(MAP.rowcount))+((XMAX)>>3))*/;
+  register int sbit  /*= ((XMIN)%8)*/;
+  register int ebit  /*= ((XMAX)%8)*/;
+
+  if (XMIN <= 0) XMIN = 0;
+  start = (((Y)*(MAP.rowcount))+((XMIN)>>3));
+  if (XMAX > MAP.bounding.x) XMAX = MAP.bounding.x-1;
+  end = (((Y)*(MAP.rowcount))+((XMAX)>>3));
+  sbit = ((XMIN)%8);
+  ebit = ((XMAX)%8);
+  if ((0 > Y) || (Y > MAP.bounding.y) || (MAP.array == NULL) || (XMAX < XMIN)) return;
+
+  if (start == end)
+    MAP.array[start] ^= ((RIGHTBITS(sbit))&LEFTBITS(ebit));
+  else                                                      
+    {                                             
+      MAP.array[start] ^= (RIGHTBITS(sbit));   
+      for(start++;start<end;start++)              
+	MAP.array[start] ^= LEFTBITS(7);
+      MAP.array[start] ^= LEFTBITS(ebit);         
+    }                                             
+}
+
+/*****************************************************************************
+ *
+ *N  SETCOLUMN
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Sets bits in a column from MAP referenced by X, from bits YMIN to YMAX.
+ *    More detailed:
+ *    A mask is ORed with each bit from YMIN to YMAX, using the same indexing
+ *    calculations as above.  The mask is generated as: (1<(X MOD 8)).
+ *    As the name suggests, the index is a column referenced by X.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    MAP  <inout> == (ArrayOfBits) two dimensional array of bits to be modified
+ *    X    <input> == (int) column to be modified in the 2-d array
+ *    YMIN <input> == (int) low bit to begin modification
+ *    YMAX <input> == (int) high bit to end modification
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *   History:
+ *H
+ *    Thomas Wood  October 1990, Original Version Kernghan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ ****************************************************************************/
+void SETCOLUMN( ArrayOfBits MAP,
+	       int         X,
+	       int         YMIN,
+	       int 	   YMAX )
+{
+  register int yymax  /*= YMAX*/;
+  register int yymin  /*= YMIN*/;
+  register int start  /*= (((yymin)*(MAP.rowcount))+((X)>>3))*/;
+  register int mask   = (1 << ((X) % 8));
+
+  if (YMIN < 0) YMIN = 0;
+  yymin = YMIN;
+  start = (((yymin)*(MAP.rowcount))+((X)>>3));
+  if (YMAX > MAP.bounding.y) YMAX = MAP.bounding.y;
+  yymax = YMAX;
+  if ((0 > X) || (X > MAP.bounding.x) || (MAP.array == NULL) || (YMAX < YMIN)) return;
+
+  MAP.array[start] |= mask;
+  start += MAP.rowcount;                          
+                                                  
+  for(;yymin<yymax; yymin++,start += MAP.rowcount)             
+    MAP.array[start] |= mask;
+  /* this for statement executes YMAX-YMIN times (thats how many bits there
+     are).  The index for the 2-d array is MAP.rowcount * 1,2,3,... YMAX-YMIN.
+     This is only a virtual 2-d array, it is actually a 1-d array        */
+}
+
+/*****************************************************************************
+ *
+ *N  CLEARCOLUMN
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Ands a mask with the column referenced by x, between bit YMIN and YMAX.
+ *    The mask is ~(1<<(X MOD 8)).  Basically, this erases whatever was there.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    MAP  <inout> == (ArrayOfBits) 2-d array to be modified
+ *    X    <input> == (int) column to be modified
+ *    YMIN <input> == (int) starting bit
+ *    YMAX <input> == (int) ending bit
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990  Original Version Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions/Macros Called:
+ *FM
+ *    None
+ *E
+ ****************************************************************************/
+void CLEARCOLUMN( ArrayOfBits MAP,
+		 int 	     X,
+		 int 	     YMIN,
+		 int 	     YMAX ) 
+{                                                 
+  register int yymax /*= YMAX*/;
+  register int yymin /*= YMIN*/;
+  register int start /*= (((yymin)*(MAP.rowcount))+((X)>>3))*/;
+  register int mask  = ~(1<<((X)%8));
+
+  if (YMIN < 0) YMIN = 0;
+  yymin = YMIN;
+  start = (((yymin) * (MAP.rowcount)) + ((X) >> 3));
+  if (YMAX > MAP.bounding.y) YMAX = MAP.bounding.y;
+  yymax = YMAX;
+  if ((0 > X) || (X > MAP.bounding.x) || (MAP.array == NULL) || (YMAX < YMIN)) return;
+
+  MAP.array[start] &= mask;
+  start += MAP.rowcount;                          
+                                                  
+  for(;yymin<yymax; yymin++,start += MAP.rowcount)             
+    MAP.array[start] &= mask;                     
+}
+
+/******************************************************************************
+ *
+ *N  TOGGLECOLUMN
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    MAP  <inout> == (ArrayOfBits) 2-d array to be modified
+ *    X    <input> == (int) column to be modified
+ *    YMIN <input> == (int) starting bit
+ *    YMAX <input> == (int) ending bit
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    XORs bits in column X of 2-d array MAP from bits YMIN to YMAX.
+ *    Mask is 1's, index is YMIN through YMAX.
+ *E
+ *****************************************************************************/
+void TOGGLECOLUMN( ArrayOfBits MAP,
+		  int 	      X,
+		  int 	      YMIN,
+		  int 	      YMAX )
+{
+  register int yymax /*= YMAX*/;
+  register int yymin /*= YMIN*/;
+  register int start /*= (((yymin)*(MAP.rowcount))+((X)>>3))*/;
+  register int mask  = (1<<((X)%8));
+
+  if (YMIN < 0) YMIN = 1;
+  yymin = YMIN;
+  start = (((yymin) * (MAP.rowcount)) + ((X) >> 3));
+  if (YMAX > MAP.bounding.y) YMAX = MAP.bounding.y;
+  yymax = YMAX;
+  if ((0 > X) || (X > MAP.bounding.x) || (MAP.array == NULL) || (YMAX < YMIN)) return;
+
+  MAP.array[start] ^= mask;
+  start += MAP.rowcount;
+                                                  
+  for(;yymin<yymax; yymin++,start += MAP.rowcount)
+    MAP.array[start] ^= mask;                     
+}
+
+/******************************************************************************
+ *
+ *N  MakeArrayOfBits
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Defines a MAP based on deltaX and deltaY.  The rowcount is:
+ *    (deltaX+8) >> 3.  The array allocation is:
+ *    (unsigned char *) calloc((deltaY+1), rowcount).
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    deltaX          <input>  == (int) x width of 2-d bit array
+ *    deltaY          <input>  == (int) y width of 2-d bit array
+ *    MakeArrayOfBits <output> == (ArrayOfBits) empty 2-d bit array
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990  Original Version Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions/Macros Called:
+ *FM
+ *    Xmark()     XMEMORY.H
+ *    Xclear()    XMEMORY.H
+ *    Xcalloc(nelem, elsize)
+ *E
+ *****************************************************************************/
+ArrayOfBits MakeArrayOfBits( int deltaX,
+			     int deltaY )
+{
+  ArrayOfBits value;
+  int temp;
+
+  temp = deltaX + 1;
+  temp += 7;
+
+  value.rowcount = temp >> 3;
+
+  value.bounding.x = deltaX;
+  value.bounding.y = deltaY;
+
+  Xmark();
+
+  value.array = (unsigned char *)Xcalloc( (deltaY + 1), value.rowcount);
+
+  Xclear();
+
+  return value;
+}
+
+/******************************************************************************
+ *
+ *N  FreeArrayOfBits
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Erases a map, then returns 0.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    map             <input>  == (ArrayOfBits) map to be erased
+ *    FreeArrayOfBits <output> == (int) value of map
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990, Original Version Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Macros Called:
+ *FM
+ *    Xfree
+ *E
+ *****************************************************************************/
+int FreeArrayOfBits ( ArrayOfBits map )
+{
+  Xfree(map.array);
+  return 0;
+}
+
+
+/******************************************************************************
+ *
+ *N  PointGetBit
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Tells the user whether the bit at point(x,y) is set to 0 or 1.(error
+ *    checking: will return 0 if the point sent is outside of the range of
+ *    the map).
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    map         <input>  == (ArrayOfBits) 2-d array to be checked
+ *    point       <input>  == (IPoint) coordinated to check
+ *    PointGetBit <output> == (int) results of check
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990,  Original Version Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions/Modules Called:
+ *FM
+ *    OUTISDE(MAP,POINT)    BITARRAY.C
+ *    GETBIT(MAP,POINT)     BITARRAY.C
+ *E
+ *****************************************************************************/
+int PointGetBit ( ArrayOfBits map,
+		  IPoint      point )
+{
+  if (map.array == NULL) return 0;
+  if (OUTSIDE(map,point)) return 0;
+  return GETBIT(map,point);
+}
+
+/*****************************************************************************
+ *
+ *N  PointSetBit
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Sets a bit to value at point at in map.  value must be 1 or 0
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    map         <input>  == (ArrayOfBits) 2-d array to be modified
+ *    at          <input>  == (IPoint) coordinates to set set
+ *    value       <input>  == (int) value to set coordinates to
+ *    PointSetBit <output> == (int) value that coordinates were set to
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990, Original Version Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions/Modules Called:
+ *FM
+ *    OUTSIDE(MAP,POINT)     BITARRAY.C
+ *    SETBIT(MAP,POINT)      BITARRAY.C
+ *    CLEARBIT(MAP,POINT)    BITARRAY.C
+ *E
+ *****************************************************************************/
+int PointSetBit ( ArrayOfBits map,
+		  IPoint      at,
+		  int         value)
+{
+  if (map.array == NULL) return 0;
+  if (OUTSIDE(map,at)) return 0;
+  if (value)
+    return SETBIT(map,at);
+  return CLEARBIT(map,at);
+}
+
+
+/******************************************************************************
+ *
+ *N  LineSetBit
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Sets bit in a line with coordinates from set in map.  Lines can be
+ *    sloping, vertical, or horizontal, but the beginning coordinates
+ *    must be less than the ending coordinates, and all coordinates should
+ *    be within map (there is error checking for this, basically nothing is
+ *    done).  Sets the bits for value=1, clears the bits for value=0.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    map        <inout>  == (ArrayOfBits) 2-d array to be modified
+ *    seg        <input>  == (ISegment) line coordinates(to,from) for the line
+ *    value      <input>  == (int) 0 to clear bits, 1 to set bits
+ *    LineSetBit <output> == (int) value that bits were set to
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990, Original Version Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions/Macros Called:
+ *FM
+ *    OUTSIDE(MAP,POINT)        BITARRAY.C
+ *    SETBIT(MAP,POINT)         BITARRAY.C
+ *    CLEARBIT(MAP,POINT)       BITARRAY.C
+ *    MAXIMUM(X,Y)	        BITARRAY.C
+ *    MINIMUM(X,Y)		BITARRAY.C
+ *    OUTSIDE_X(MAP,Value)      BITARRAY.C
+ *    OUTSIDE_Y(MAP,Value)      BITARRAY.C
+ *    FILLBRESSEG(bseg,seg)	BITARRAY.C
+ *    STEP(bseg)    		BITARRAY.C
+ *    SETROW(ArrayOfBits MAP, int XMIN, int XMAX, int Y )   BITARRAY.C
+ *    CLEARROW(ArrayOfBits MAP, int XMIN, int XMAX, int Y ) BITARRAY.C
+ *    SETCOLUMN(ArrayOfBits MAP, int X, int YMIN, int YMAX ) BITARRAY.C
+ *    CLEARCOLUMN(ArrayOfBits MAP, int X, int YMIN, int YMAX ) BITARRAY.C
+ *E
+ ******************************************************************************/
+int LineSetBit ( ArrayOfBits map,
+		 ISegment    seg,
+		 int         value )
+{
+  BresSegment bseg;
+  unsigned int from,to;
+
+  if (map.array == NULL) return 0;
+  if ((!seg.delta.x)&&(!seg.delta.y))
+    {
+      if (OUTSIDE(map,seg.origin)) return 0;
+      if (value) SETBIT(map,seg.origin); else CLEARBIT(map,seg.origin);
+      return 0;
+    }
+  /* horizontal line */
+  if (seg.delta.y == 0)
+    {
+      if (OUTSIDE_Y(map,seg.origin.y)) return 0;
+      if (seg.delta.x < 0)
+	{
+	  from = MAXIMUM(seg.origin.x + seg.delta.x, 0);
+	  to   = MINIMUM(seg.origin.x, map.bounding.x);
+	}
+      else
+	{
+	  from = MAXIMUM(seg.origin.x, 0);
+	  to   = MINIMUM(seg.origin.x + seg.delta.x, map.bounding.x);
+	}
+      if (from > to) return 0;
+      if (from == to)
+      {
+	if (value) { seg.origin.x = from; SETBIT(map,seg.origin); }
+	else     { seg.origin.x = from; CLEARBIT(map,seg.origin); }
+      }
+      if (value) 
+      { 
+         SETROW(map,from,to,seg.origin.y); 
+      }
+      else     
+      { 
+         CLEARROW(map,from,to,seg.origin.y); 
+      }
+      return 0;
+    }
+  /* vertical line */
+  if (seg.delta.x == 0)
+    {
+      if (OUTSIDE_X(map,seg.origin.x)) return 0;
+      if (seg.delta.y < 0)
+	{
+	  from = MAXIMUM(seg.origin.y + seg.delta.y ,0);
+	  to   = MINIMUM(seg.origin.y, map.bounding.y);
+	}
+      else
+	{
+	  from = MAXIMUM(seg.origin.y, 0);
+	  to   = MINIMUM(seg.origin.y + seg.delta.y, map.bounding.y);
+	}
+      if (from > to) return 0;
+      if (from == to)
+      {
+         if (value) { seg.origin.y = from; SETBIT(map,seg.origin); }
+         else     { seg.origin.y = from; CLEARBIT(map,seg.origin); }
+      }
+      if (value) { SETCOLUMN(map,seg.origin.x,from,to); }
+      else    {  CLEARCOLUMN(map,seg.origin.x,from,to); }
+      return 0;
+    }
+
+  /* sloping line */
+
+  FILLBRESSEG(bseg,seg);
+  for(;bseg.maximum;)
+    {
+      if (!OUTSIDE(map,bseg.at))
+      {
+	if (value)
+        { 
+           SETBIT(map,bseg.at); 
+        }
+        else
+        {
+           CLEARBIT(map,bseg.at);
+        }
+      }
+      STEP(bseg);
+    }
+  if (!OUTSIDE(map,bseg.at))
+  {
+     if (value) SETBIT(map,bseg.at); 
+     else CLEARBIT(map,bseg.at);
+  }
+  return 0;
+}
+
+
+/******************************************************************************
+ *
+ *N  LineXorBit
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    If value=1, an XOR is done on all bits(actually, just a toggle of off bits
+ *    to on and on bits to off.  If value=0, nothing is done
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    map        <inout>  == (ArrayOfBits) 2-d array to be modified
+ *    seg        <input>  == (ISegment) line coords for modification
+ *    value      <input>  == (int) tell whether to XOR or not
+ *    LineXorBit <output> == (int) tell whether XORed or not
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990, Kernighan&Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions/Macros Called:
+ *FM
+ *    OUTSIDE(MAP,POINT)                BITARRAY.C
+ *    SETBIT(MAP,POINT)                 BITARRAY.C
+ *    MAXIMUM(x,y)                      BITARRAY.C
+ *    MINIMUM(x,y)                      BITARRAY.C
+ *    OUTSIDE_Y(MAP,value)              BITARRAY.C
+ *    OUTSIDE_X(MAP,value)              BITARRAY.C
+ *    FILLBRESSEG(bseg,seg)             BITARRAY.C
+ *    STEP(bseg)                        BITARRAY.C
+ *    SETROW(ArrayOfBits MAP, int XMIN, int XMAX, int Y)   BITARRAY.C
+ *    SETCOLUMN(ArrayOfBits MAP, int X, int YMIN, int YMAX) BITARRAY.C
+ *E
+ ******************************************************************************/
+int LineXorBit ( ArrayOfBits map,
+		 ISegment    seg,
+		 int         value )
+{
+  BresSegment bseg;
+  unsigned int from,to;
+
+  if (!value) return 0;
+  if (map.array == NULL) return 0;
+  if ((!seg.delta.x)&&(!seg.delta.y))
+    {
+      if (OUTSIDE(map,seg.origin)) return 0;
+      TOGGLEBIT(map,seg.origin);
+      return 0;
+    }
+
+  if (seg.delta.y == 0)
+    {
+      if (OUTSIDE_Y(map,seg.origin.y)) return 0;
+      if (seg.delta.x < 0)
+	{
+	  from = MAXIMUM(seg.origin.x + seg.delta.x, 0);
+	  to   = MINIMUM(seg.origin.x, map.bounding.x);
+	}
+      else
+	{
+	  from = MAXIMUM(seg.origin.x, 0);
+	  to   = MINIMUM(seg.origin.x + seg.delta.x, map.bounding.x);
+	}
+      if (from > to) return 0;
+      if (from == to) { seg.origin.x = from; TOGGLEBIT(map,seg.origin); }
+      TOGGLEROW(map,from,to,seg.origin.y);
+      return 0;
+    }
+
+  if (seg.delta.x == 0)
+    {
+      if (OUTSIDE_X(map,seg.origin.x)) return 0;
+      if (seg.delta.y < 0)
+	{
+	  from = MAXIMUM(seg.origin.y + seg.delta.y ,0);
+	  to   = MINIMUM(seg.origin.y, map.bounding.y);
+	}
+      else
+	{
+	  from = MAXIMUM(seg.origin.y, 0);
+	  to   = MINIMUM(seg.origin.y + seg.delta.y, map.bounding.y);
+	}
+      if (from > to) return 0;
+      if (from == to) { seg.origin.y = from; TOGGLEBIT(map,seg.origin); }
+      TOGGLECOLUMN(map,seg.origin.x,from,to);
+      return 0;
+    }
+
+  /* sloping line */
+  
+  FILLBRESSEG(bseg,seg);
+  for(;bseg.maximum;)
+    {
+      if (!OUTSIDE(map,bseg.at))
+	TOGGLEBIT(map,bseg.at);
+      STEP(bseg);
+    }
+  if (!OUTSIDE(map,bseg.at))
+    TOGGLEBIT(map,bseg.at);
+  return 0;
+}
+
+
+/******************************************************************************
+ *
+ *N  TrapezoidXorBit
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Turns off any bit that was on, turns on any bit that was of in the line
+ *    designated by coordinates in seg.  This is only done if value=1, else
+ *    0 is returned and nothing is done
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    map             <inout>  == (ArrayOfBits) 2-d array to be modified
+ *    seg             <input>  == (ISegment) line designated by 2 coords
+ *    value           <input>  == (int) if 0, returns 0, else swaps bits
+ *    TrapezoidXorBit <output> == (int) returns 0
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October 1990  Original Version Kernighan&Ritchie C
+ *    Updated August 1991 ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions/Macros Called:
+ *FM
+ *    OUTSIDE_X(MAP,value)		BITARRAY.C
+ *    MINUMUM(x,y)			BITARRAY.C
+ *    MAXIMUM(x,y)			BITARRAY.C
+ *    FILLBRESSEG(bseg,seg)		BITARRAY.C
+ *    TOGGLEROW(ArrayOfBits MAP,int XMIN,int XMAX,int Y)  BITARRAY.C
+ *    TOGGLECOLUMN(ArrayOfBits MAP,int X,int YMIN,int YMAX)  BITARRAY.C
+ *E
+ *****************************************************************************/
+int TrapezoidXorBit( ArrayOfBits map,
+                     ISegment    seg,
+                     int         value )
+{
+  BresSegment bseg;
+  int xmin,xmax,to /*,temp*/;
+
+  if (map.array == NULL) return 0;
+  if (!value) return 0;
+
+  if (seg.delta.x == 0)
+    {
+      if (OUTSIDE_X(map,seg.origin.x)) return 0;
+      if (seg.delta.y < 0)
+	to = MINIMUM(seg.origin.y, map.bounding.y);
+      else
+	to = MINIMUM(seg.origin.y + seg.delta.y, map.bounding.y);
+      if  (0 > to) return 0;
+      TOGGLECOLUMN(map,seg.origin.x,0,to);
+      return 0;
+    }
+
+  if (seg.delta.y == 0)
+    {
+      if (seg.origin.y < 0) return 0;
+      if (seg.origin.y > map.bounding.y)
+	to = map.bounding.y;
+      else
+	to = seg.origin.y;
+      if (seg.delta.x < 0)
+	{
+	  xmin = MAXIMUM(seg.origin.x + seg.delta.x, 0);
+	  xmax = MINIMUM(seg.origin.x, map.bounding.x);
+	}
+      else
+	{
+/*	  temp = seg.origin.x + seg.delta.x;*/
+	  xmin = MAXIMUM(seg.origin.x, 0);
+	  xmax = MINIMUM(seg.origin.x + seg.delta.x, map.bounding.x);
+	}
+      if (xmin > xmax) return 0;
+      for(; 0 <= to; to--)
+	{ TOGGLEROW(map,xmin,xmax,to); }
+      return 0;
+    }
+  
+  /* sloping line */
+  FILLBRESSEG(bseg,seg);
+
+  for(;bseg.maximum;)
+    {
+      if (bseg.toggle)
+	{
+	  if ((bseg.Eprim>=0) &&
+	      ((bseg.at.y>=0) &&
+	       ((bseg.at.x>=0) &&(bseg.at.x<=map.bounding.x))))
+	    {
+	      to = MINIMUM(bseg.at.y, map.bounding.y);
+	      { TOGGLECOLUMN(map,bseg.at.x,0,to); }
+	    }
+	}
+      else
+	if ((bseg.at.y>=0) &&
+	    ((bseg.at.x>=0)&&(bseg.at.x<=map.bounding.x)))
+	  {
+	    to = MINIMUM(bseg.at.y, map.bounding.y);
+	    { TOGGLECOLUMN(map,bseg.at.x,0,to); }
+	  }
+
+      STEP(bseg);
+    }
+  if ((bseg.at.y>=0) &&
+      ((bseg.at.x>=0)&&(bseg.at.x<=map.bounding.x)))
+    {
+      to = MINIMUM(bseg.at.y, map.bounding.y);
+      { TOGGLECOLUMN(map,bseg.at.x,0,to); }
+    }
+  return 0;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/distance.c b/Utilities/OSSIM/ossim_core/vpf_util/distance.c
new file mode 100644
index 0000000000..853ecaea2c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/distance.c
@@ -0,0 +1,86 @@
+#include <math.h>
+/*************************************************************************
+ *
+ *N  distance
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function computes the distance between two points on the
+ *    surface of the (spherical) earth.  The points are specified in
+ *    geographic coordinates (lat1,lon1) and (lat2,lon2).  The algorithm
+ *    used here is taken directly from ELEMENTS OF CARTOGRAPHY, 4e. -
+ *    Robinson, Sale, Morrison - John Wiley & Sons, Inc. - pp. 44-45.
+ *    Geometrically, the function computes the arc distance dtheta on
+ *    the sphere between two points A and B by the following formula:
+ *
+ *              cos dtheta = (sin a sin b) + (cos a cos b cos p)
+ *
+ *              where:
+ *
+ *                 dtheta = arc distance between A and B
+ *                 a = latitude of A
+ *                 b = latitude of B
+ *                 p = degrees of longitude between A and B
+ *
+ *    Once the arc distance is determined, it is converted into miles by
+ *    taking the ratio between the circumference of the earth (2*PI*R) and
+ *    the number of degrees in a circle (360):
+ *
+ *        distance in miles (d)            arc distance in degrees (dtheta)
+ *   ------------------------------   =    --------------------------------
+ *   earth's circumference in miles        earth's circumference in degrees
+ *
+ *                                    or
+ *
+ *    d = (dtheta * (2*PI*R)) / 360  =>
+ *    d = (dtheta*PI*R)/180
+ *
+ *   The calculated distance is also referred to as the Great Circle.
+ *
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    lat1  <input> == (double) latitude of point A.
+ *    lon1  <input> == (double) longitude of point A.
+ *    lat2  <input> == (double) latitude of point B.
+ *    lon2  <input> == (double) longitude of point B.
+ *    units <input> == (int) flag to indicate output distance units.
+ *                          0 -> Miles, 1 -> Kilometers
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   November 1990   Original Version   DOS Turbo C
+ *    Added kilometers option - May 1991 - BJM
+ *E
+ *************************************************************************/
+float distance( double lat1, double lon1, double lat2, double lon2,
+		int units )
+{
+   double a,b,p,dtheta,d;
+   double R[2] = { 3958.754, 6370.997 }
+#ifndef PI
+, PI=3.141592654
+#endif
+   ;
+   double DEG2RAD=(PI/180.0), RAD2DEG=(180.0/PI);
+
+   if ((units<0)||(units>1)) units = 0;
+
+   if (lat1 > 90.0) lat1 -= 180.0;
+   if (lat2 > 90.0) lat2 -= 180.0;
+
+   a = lat1*DEG2RAD;  /* Degrees must be converted to radians */
+   b = lat2*DEG2RAD;
+   p = fabs(lon1-lon2)*DEG2RAD;
+   dtheta = (sin(a)*sin(b)) + (cos(a)*cos(b)*cos(p));
+   dtheta = acos(dtheta)*RAD2DEG;   /* Compute arc distance in degrees */
+   d = (dtheta*PI*R[units])/180.0;  /* Compute distance in miles or km */
+   return (float)d;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/linklist.c b/Utilities/OSSIM/ossim_core/vpf_util/linklist.c
new file mode 100644
index 0000000000..5a92ab66cf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/linklist.c
@@ -0,0 +1,710 @@
+/*************************************************************************
+ *
+ *N  Module LINKLIST.C
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions that make up a singly linked list
+ *     data structure.  It is generic in the sense that it can hold any
+ *     type of data, including user-defined types and structures.  That
+ *     is why you must treat the data element as a void pointer and pass
+ *     in its size when inserting into the list.  These routines are
+ *     assured of working with "non-pointer" types of data elements.
+ *     If you try storing other lists, or structures with pointers hanging
+ *     off of them, the results will become unpredictable.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    linked_list_type ll_init();
+ *    int ll_empty( linked_list_type list );
+ *    position_type ll_first( linked_list_type list );
+ *    position_type ll_last( linked_list_type list );
+ *    position_type ll_next( position_type position );
+ *    position_type ll_previous( position_type position, linked_list_type
+ *                  list );
+ *    int ll_end( position_type position );
+ *    void ll_element( position_type position, void *element );
+ *    void ll_insert( void *element, unsigned size, position_type position );
+ *    void ll_delete( position_type position );
+ *    void ll_reset( linked_list_type list );
+ *    position_type ll_locate( void *element, linked_list_type list );
+ *    void ll_replace( void *element, position_type position );
+ *E
+ *************************************************************************/
+#ifdef __MSDOS__
+#include <alloc.h>
+#include <mem.h>
+#else
+#ifdef MACOSX 
+#include <sys/types.h>
+#include <sys/malloc.h>
+#else
+#include <malloc.h>
+#include <string.h>
+#endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "linklist.h"
+#include <string.h>
+
+#ifndef __MSDOS__
+#define farmalloc malloc
+#define farfree free
+#define movmem(a,b,c) memmove(b,a,c)
+#endif
+
+/*************************************************************************
+ *
+ *N  ll_init
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function allocates and initializes a new linked list structure.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    ll_init <output> == (linked_list_type) initialized head of the list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+linked_list_type ll_init()
+{
+   linked_list_type list;
+
+   if ((list = (linked_list_type) farmalloc( sizeof(cell_type) ))==NULL) {
+      printf("Out of memory in ll_init()\n");
+      exit(1);
+   }
+   list->element = NULL;
+   list->element_size = 0;
+   list->next = NULL;
+   return list;
+}
+
+
+/*************************************************************************
+ *
+ *N  ll_empty
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function TRUE if the list is empty and FALSE if it is not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    list      <input> == (linked_list_type) linked list being checked.
+ *    ll_empty <output> == (int) boolean function result.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+int ll_empty( linked_list_type list )
+{
+   if (list == NULL) return TRUE;
+   if (list->next == NULL)
+      return TRUE;
+   else
+      return FALSE;
+}
+
+
+/*************************************************************************
+ *
+ *N  ll_first
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the head of the list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    list      <input> == (linked_list_type) linked list.
+ *    ll_first <output> == (position_type) head of the list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+position_type ll_first( linked_list_type list )
+{
+   return ((position_type) list);
+}
+
+
+/*************************************************************************
+ *
+ *N  ll_last
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns *THE* last position in the list, which is
+ *     not useable.  Use ll_previous to get to the las USEABLE link in
+ *     the list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    list     <input> == (linked_list_type) linked list.
+ *    ll_last <output> == (position_type) tail of the list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+position_type ll_last( linked_list_type list )
+{
+   position_type p;
+
+   p = (position_type) list;
+   while (p->next != NULL)
+      p = p->next;
+   return p;
+}
+
+
+/*************************************************************************
+ *
+ *N  ll_next
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the next position in the list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    position <input> == (position_type) current position in the list.
+ *    ll_next <output> == (position_type) next position in the list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+position_type ll_next( position_type position )
+{
+   return(position->next);
+}
+
+
+/*************************************************************************
+ *
+ *N  ll_previous
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the previous position in the list.  Note:
+ *     This is a singly linked list -> no backward pointer -> this
+ *     operation is relatively inefficient.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    position     <input> == (position_type) current position.
+ *    list         <input> == (linked_list_type) linked list.
+ *    ll_previous <output> == (position_type) previous position in the list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+position_type ll_previous( position_type    position,
+			   linked_list_type list )
+{
+   position_type p;
+
+   if (position==list) return(position);
+   p = list;
+   while (p->next != position)
+      p = p->next;
+   return(p);
+}
+
+
+/*************************************************************************
+ *
+ *N  ll_end
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines if the given position is at the end of the
+ *     list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    position <input> == (position_type) current position in the list.
+ *    ll_end  <output> == (int) TRUE  -- if position is the end of the list.
+ *                              FALSE -- if not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+int ll_end( position_type position )
+{
+   if (position == NULL)
+      return(TRUE);
+   else {
+      if (position->next == NULL)
+	 return(TRUE);
+      else
+	 return(FALSE);
+   }
+}
+
+
+/*************************************************************************
+ *
+ *N  ll_element
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function copies the element at position in the list into the
+ *     contents of element.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    position <input> == (position_type) position in the list.
+ *    element <output> == (void *) pointer to the element data.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+void ll_element( position_type position,
+		 void         *element )
+{
+   movmem(position->next->element,element,position->next->element_size);
+}
+
+/*************************************************************************
+ *
+ *N  ll_insert
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function inserts a new cell into the list at position that will
+ *     contain the data pointed to by element.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    element  <input> == (void *) pointer to the data element to insert.
+ *    size     <input> == (unsigned) size of the data element.
+ *    position <input> == (position_type) position to insert the new cell.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+void ll_insert( void          *element,
+		unsigned      size,
+		position_type position )
+{
+   position_type temp;
+
+   if ((temp = (position_type) farmalloc( sizeof(cell_type) )) == NULL) {
+      printf("out of memory\n");
+      abort();
+   }
+   temp->next = position->next;
+   position->next = temp;
+   temp->element_size = size;
+   if ((temp->element = farmalloc( size ))==NULL) {
+      printf("out of memory\n");
+      abort();
+   }
+   movmem(element,temp->element,size);
+
+}
+
+
+/*************************************************************************
+ *
+ *N  ll_delete
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function deletes and disposes of a cell from the linked list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    position <input> == (position_type) position in the list to delete.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+void ll_delete( position_type position )
+{
+   position_type    p;
+
+   if (position != NULL) {  /* Cut the element out of the chain */
+      p = position->next;
+      position->next = p->next;
+      farfree( p->element );
+      farfree( p );
+   }
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  ll_reset
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function empties out a linked list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    list <inout> == (linked_list_type) linked list to be emptied.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void ll_delete( position_type position );
+ *    int ll_empty( linked_list_type list );
+ *E
+ *************************************************************************/
+void ll_reset( linked_list_type list )
+{
+   while (! ll_empty(list))
+      ll_delete(ll_first(list));
+   farfree(list);
+   list = NULL;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  ll_locate
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function locates a position in the list by comparing data.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    element <input> == (void *) pointer to the data element to locate.
+ *    list    <input> == (linked_list_type) linked list.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+position_type ll_locate( void             *element,
+			 linked_list_type list )
+{
+   position_type p;
+
+   p = list;
+   while (p->next != NULL) {
+      if ( memcmp(p->next->element,element,p->next->element_size) == 0 )
+	 return p;
+      else
+	 p = p->next;
+   }
+   return NULL;
+}
+
+
+/*************************************************************************
+ *
+ *N  ll_replace
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function replaces an element in the linked list at the given
+ *     position.  WARNING:  The new data element must be the same size as
+ *     the previous data element or you will get some rather INTERESTING
+ *     results.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    element  <input> == (void *) data element to replace existing data.
+ *    position <input> == (position_type) position in the list to replace
+ *                        the data.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb. 1990                      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+void ll_replace( void          *element,
+		 position_type position )
+{
+   movmem(element,position->next->element,position->next->element_size);
+}
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/linklist.h b/Utilities/OSSIM/ossim_core/vpf_util/linklist.h
new file mode 100644
index 0000000000..b38aa1137e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/linklist.h
@@ -0,0 +1,69 @@
+
+/* LINKLIST.H */
+
+#ifndef __LINKLIST_H__
+
+#define __LINKLIST_H__   1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Linked list structure */
+typedef struct linked_list_cell {
+   void      	           *element;
+   unsigned                element_size;
+   struct linked_list_cell *next;
+} cell_type, *linked_list_type, *position_type;
+
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* Functions: */
+
+linked_list_type ll_init();
+
+int ll_empty( linked_list_type list );
+
+position_type ll_first( linked_list_type list );
+
+#define LL_FIRST(list) (position_type)list
+
+position_type ll_last( linked_list_type list );
+
+position_type ll_next( position_type position );
+
+#define LL_NEXT(position) position->next
+
+position_type ll_previous( position_type    position,
+			   linked_list_type list );
+
+int ll_end( position_type position );
+
+void ll_element( position_type position,
+		 void         *element );
+
+void ll_insert( void          *element,
+		unsigned      size,
+		position_type position );
+
+void ll_delete( position_type position );
+
+void ll_reset( linked_list_type list );
+
+position_type ll_locate( void             *element,
+			 linked_list_type list );
+
+void ll_replace( void          *element,
+		 position_type position );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/machine.h b/Utilities/OSSIM/ossim_core/vpf_util/machine.h
new file mode 100644
index 0000000000..0af1b107c8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/machine.h
@@ -0,0 +1,14 @@
+/* ================ SCCS_ID[] = "@(#) machine.h 1.1 7/26/91"  =================
+
+   Environmental Systems Research Institute (ESRI) Applications Programming
+
+       Project: 		Conversion from ARC/INFO to VPF
+       Original Coding:		David Flinn   	July 1991  (UNIX)
+       Modifications:		Barry Michaels  July 1991  (DOS)
+
+   ======================================================================== */
+#ifndef _MACHINE_
+#define _MACHINE_ 	1
+/* #define DOS  		1*/
+#define  UNIX           1  
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/mapgraph.h b/Utilities/OSSIM/ossim_core/vpf_util/mapgraph.h
new file mode 100644
index 0000000000..09dcbc553c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/mapgraph.h
@@ -0,0 +1,56 @@
+
+/* MAPGRAPH.H */
+#ifndef __MAPGRAPH_H__
+#define __MAPGRAPH_H__ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LONGITUDE(lon)  {\
+   if (lon < -180.0) lon += 360.0; \
+   if (lon > 180.0) lon -= 360.0; \
+}
+
+#define LATITUDE(lat)  {\
+   if (lat < -90.0) lat += 180.0; \
+   if (lat > 90.0) lat -= 180.0; \
+}
+
+
+/* Map Drawing Functions: */
+
+#ifndef __MSDOS__
+#define far
+#endif
+
+void mapinit( double xmn,
+	      double ymn,
+	      double xmx,
+	      double ymx,
+	      int width,
+	      int height,
+	      void far (*fwdproj)(),
+	      void far (*invproj)() );
+
+void screenxy( double xmap, double ymap,
+	       int *xscreen, int *yscreen );
+
+void mapxy( int xscreen, int yscreen, double *xmap, double *ymap );
+
+
+void draw_graticule( double xstart,
+		     double ystart,
+		     double xstep,
+		     double ystep,
+		     int    ninterm_pts,
+		     int    color,
+		     int    style,
+		     int    thickness );
+
+
+#ifdef __cplusplus
+}
+#endif
+   
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/polygrf.c b/Utilities/OSSIM/ossim_core/vpf_util/polygrf.c
new file mode 100644
index 0000000000..66ef70d140
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/polygrf.c
@@ -0,0 +1,358 @@
+/******************************************************************************
+ *
+ *N  Module POLYGRF.C
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Coordinate transformations of points.  Can create and manipulate
+ *    sets of x,y coords
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October, 1990, Kurnigan/Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions:
+ *F
+ *    ISegment MakeISegment( IPoint from, IPoint to );
+ *    ITransform MakeITransform( IBox from, IBox to );
+ *    IPoint TranslateIPoint( ITransform transform, IPoint a, int flag );
+ *    IBox AndIBox( IBox a, IBox b );
+ *E
+ *****************************************************************************/
+
+#include "xmemory.h"
+#include "polygrf.h"
+
+/******************************************************************************
+ *
+ *N  MakeISegment
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Called with two sets of xy coordinates, from and to.  Returns from and
+ *    the delta of from and to.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    from         <input>  == (IPoint) originating xy coordinates.
+ *    to           <input>  == (IPoint) ending xy coordinates.
+ *    MakeISegment <output> == (ISegement) origin and delta
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood October 1990 Original Kurnigan/Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *****************************************************************************/
+ISegment MakeISegment( IPoint from,
+		       IPoint to )
+{
+  ISegment current;
+
+  current.origin = from;
+  current.delta.x = to.x - from.x;
+  current.delta.y = to.y - from.y;
+
+  return current;
+}
+
+
+/*****************************************************************************
+ *
+ *N  MakeITransform
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Inputs two sets of origin coordinates plus their delta coordinates.
+ *    Calculates and returns offset of the origins and if the deltas are
+ *    different, the new scale. (if deltas are the same, scale is 1.0).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    from        <input>  == (IBox) originating coordinates & delta
+ *    to          <input>  == (IBOX) ending coordinates and delta
+ *    MakeITransform <output> == (ITransform) offset and scale
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood, October 1990, Original version Kurnigan/Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ ****************************************************************************/
+ITransform  MakeITransform( IBox from,
+                            IBox to )
+{
+  ITransform current;
+  register float temp;
+
+  current.scale.x = current.scale.y = 1.0;
+
+  if ((to.delta.x == 0.0)||
+      (from.delta.x == 0.0))
+    to.delta.x = from.delta.x = 1;
+
+  if ((to.delta.y == 0.0)||
+      (from.delta.y == 0.0))
+    to.delta.y = from.delta.y = 1;
+
+  if (to.delta.x == from.delta.x)
+      current.offset.x = to.origin.x - from.origin.x;
+  else
+    {
+      current.scale.x =
+	    (float)to.delta.x / (float)from.delta.x;
+      temp = (float)(to.origin.x * from.delta.x);
+      temp = temp / to.delta.x;
+      temp += (float)((temp < 0)? -.05: 0.5);
+      current.offset.x = (int)(temp - from.origin.x);
+    }
+
+  if (to.delta.y == from.delta.y)
+      current.offset.y = to.origin.y - from.origin.y;
+  else
+    {
+      current.scale.y =
+	    (float)to.delta.y / (float)from.delta.y;
+      temp = (float)(to.origin.y * from.delta.y);
+      temp = temp / to.delta.y;
+      temp += (float)((temp < 0)? -.05: 0.5);
+      current.offset.y = (int)(temp - from.origin.y);
+    }
+
+  return current;
+}
+
+/*****************************************************************************
+ *
+ *N  TranslateIPoint
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Rescales 'a' based on flag and transform.  If flag is 1, scales down,
+ *    else up.  Scaling factor based on transform.scale and transform.offset
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    transform       <input>  == (ITransform) tranformation index/ratio
+ *    a               <input>  == (IPoint) coordinates to be transformed
+ *    flag            <input>  == (int) scale index (up=0,down=1)
+ *    TranslateIPoint <output> == (IPoint) scaled coordinates
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood, October 1990, Original Version Kurnigan/Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ ****************************************************************************/
+IPoint TranslateIPoint( ITransform transform,
+                        IPoint 	   a,
+			int        flag )
+{
+  IPoint output;
+  register float temp;
+
+  output = a;
+  if ((transform.scale.x == 1.0)||(transform.scale.x == 0.0))
+    output.x += ((flag)? -1: 1) * transform.offset.x;
+  else
+    {
+      if (flag)
+	{
+	  temp = (float)output.x;
+	  temp /= transform.scale.x;
+	  temp += (float)((temp < 0)?  -.05: 0.5);
+	  temp -= transform.offset.x;
+	  output.x = (int)temp;
+	}
+      else
+	{
+	  temp = (float)(output.x + transform.offset.x);
+	  temp *= transform.scale.x;
+	  temp += (float)((temp < 0)?  -.05: 0.5);
+	  output.x = (int)temp;
+	}
+    }
+
+  if ((transform.scale.y == 1)||(transform.scale.y == 0.0))
+    output.y += ((flag)? -1: 1) * transform.offset.y;
+  else
+    {
+      if (flag)
+	{
+	  temp = (float)output.y;
+	  temp /= transform.scale.y;
+	  temp += (float)((temp < 0)?  -.05: 0.5);
+	  temp -= transform.offset.y;
+	  output.y = (int)temp;
+	}
+      else
+	{
+	  temp = (float)(output.y + transform.offset.y);
+	  temp *= transform.scale.y;
+	  temp += (float)((temp < 0)?  -.05: 0.5);
+	  output.y = (int)temp;
+	}
+    }
+  return output;
+}
+
+
+/*****************************************************************************
+ *
+ *N AndIBox
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Inputs two sets of coordinates and deltas, checks if coords are proper.
+ *    If not, returns IBox=-1.  Calculates origin values plus delta.  IF  'a'
+ *    origin values < 'b' origin values, returns -1.  Finally, the higher origin
+ *    values and lower delta values are calculated and returned
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    a       <input>  == (IBox) set of coords plus deltas
+ *    b       <input>  == (IBox) set of coords plus deltas
+ *    AndIBox <output> == (IBox) set of highest values of above
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Thomas Wood  October, 1990, Kurnigan/Ritchie C
+ *    Updated August 1991, ANSI C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    isBox
+ *E
+ ****************************************************************************/
+IBox AndIBox( IBox a,
+              IBox b )
+{
+  IBox output;
+  IPoint acorner,bcorner;
+
+  output.origin.x = output.delta.x = 
+    output.origin.y = output.delta.y = -1; 
+  
+  if (!isBox(a)) return output;
+  if (!isBox(b)) return output;
+
+  acorner.x = a.origin.x + a.delta.x;
+  acorner.y = a.origin.y + a.delta.y;
+
+  bcorner.x = b.origin.x + b.delta.x;
+  bcorner.y = b.origin.y + b.delta.y;
+
+  if (acorner.x < b.origin.x) return output;
+  if (acorner.y < b.origin.y) return output;
+  if (bcorner.x < a.origin.x) return output;
+  if (bcorner.y < a.origin.y) return output;
+
+  if (a.origin.x < b.origin.x)
+    output.origin.x = b.origin.x;
+  else
+    output.origin.x = a.origin.x;
+
+  if (a.origin.y < b.origin.y)
+    output.origin.y = b.origin.y;
+  else
+    output.origin.y = a.origin.y;
+
+  if (acorner.x < bcorner.x)
+    output.delta.x = acorner.x - output.origin.x;
+  else
+    output.delta.x = bcorner.x - output.origin.x;
+
+  if (acorner.y < bcorner.y)
+    output.delta.y = acorner.y - output.origin.y;
+  else
+    output.delta.y = bcorner.y - output.origin.y;
+
+  return output;
+}
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/polygrf.h b/Utilities/OSSIM/ossim_core/vpf_util/polygrf.h
new file mode 100644
index 0000000000..9e38ead96f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/polygrf.h
@@ -0,0 +1,435 @@
+
+/* POLYGRF.H */
+
+#ifndef POLYGRF_H
+
+#define POLYGRF_H
+
+
+#include "protomas.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+  int x,y;
+} IPoint;
+
+typedef struct
+{
+  IPoint origin;
+  IPoint delta;
+} ISegment;
+
+typedef struct
+{
+  IPoint at;
+  int    Eprim,toggle,maximum;
+  IPoint signs;
+  struct {
+    int inc,step;
+    } errors;
+} BresSegment;
+
+typedef struct {
+  IPoint origin;
+  IPoint delta;
+} IBox;
+
+typedef struct
+{
+  struct
+    {
+      float x,y;
+    } scale;
+  IPoint offset;
+} ITransform;
+
+#define TRANSFORMSPACE 0
+#define USERSPACE      1
+
+typedef unsigned char Color;
+
+typedef struct
+{
+  unsigned char type,width,height;
+  union {
+    long pad;
+    unsigned char *list;
+    struct {
+      unsigned char ll,lr,ul,ur;
+    } vpfPatternSmall;
+  } vpfPatterData;
+} vpfPattern;
+
+typedef struct {
+  IBox bounding;
+  int depth;
+  int rowcount;
+  unsigned char *array;
+} BitArray;
+
+typedef struct {
+  IPoint bounding;
+  int rowcount;
+  unsigned char *array;
+} ArrayOfBits;
+
+typedef struct
+{
+  ArrayOfBits  Bordermap,Maskmap;
+  ITransform   transform;
+  int          pointcount;
+  IPoint       first;
+  int          secx;
+  int          llx;
+  IPoint       turnpoint;
+  IPoint       prev;
+  Color        line;
+  vpfPattern      fill;
+
+  IBox         bounding;   /* Original bounding box on the screen */
+
+} Shademap;
+
+#define isBox(BOX) ((BOX.delta.x >= 0)&&(BOX.delta.y >= 0))
+
+
+
+/********************************************************
+ *  POLYGRF.C Definitions
+ *******************************************************/
+ISegment MakeISegment( IPoint from,
+		       IPoint to );
+
+IBox MakeIBox( IPoint from,
+	       IPoint to );
+
+ITransform MakeITransform( IBox from,
+			   IBox to );
+
+
+IPoint TranslateIPoint( ITransform transform,
+		        IPoint a,
+		        int flag );
+
+ISegment TranslateISegment( ITransform transform,
+			    ISegment a,
+			    int flay );
+
+IBox TranslateIBox( ITransform transform,
+		    IBox a,
+		    int flag );
+/* _UNUSED_
+IPoint Iintersect ( ISegment, ISegment );
+float  Iturn      ( ISegment, IPoint );
+*/
+
+IBox AndIBox( IBox a,
+	      IBox b );
+
+
+
+/* OTHER DEFS. CANT FIND WHERE THEY ARE USED
+ISegment ISegmentClipIBox ( IBox, ISegment );
+BitArray MakeBitArray EXT3( int, int, int );
+
+int FreeBitArray  EXT1( BitArray );
+
+int GetBitPoint   EXT2( BitArray, ipoint );
+
+int ClearBitArray EXT1( BitArray );
+int SetBitArray   EXT2( BitArray, int );
+int AndBitArray   EXT2( BitArray, int );
+int OrBitArray    EXT2( BitArray, int );
+int XorBitArray   EXT2( BitArray, int );
+
+int SetBitPoint   EXT3( BitArray, IPoint, int );
+int AndBitPoint   EXT3( BitArray, IPoint, int );
+int OrBitPoint    EXT3( BitArray, IPoint, int );
+int XorBitPoint   EXT3( BitArray, IPoint, int );
+
+int SetBitLine    EXT3( BitArray, ISegment, int );
+int AndBitLine    EXT3( BitArray, ISegment, int );
+int OrBitLine     EXT3( BitArray, ISegment, int );
+int XorBitLine    EXT3( BitArray, ISegment, int );
+
+int SetBitWedge   EXT4( BitArray, ISegment, IPoint, int );
+int AndBitWedge   EXT4( BitArray, ISegment, IPoint, int );
+int OrBitWedge    EXT4( BitArray, ISegment, IPoint, int );
+int XorBitWedge   EXT4( BitArray, ISegment, IPoint, int );
+
+int SetBitBox     EXT3( BitArray, IBox, int );
+int AndBitBox     EXT3( BitArray, IBox, int );
+int OrBitBox      EXT3( BitArray, IBox, int );
+int XorBitBox     EXT3( BitArray, IBox, int );
+
+int SetBitMask    EXT4( BitArray, BitArray, IPoint, int );
+int AndBitMask    EXT4( BitArray, BitArray, IPoint, int );
+int OrBitMask     EXT4( BitArray, BitArray, IPoint, int );
+int XorBitMask    EXT4( BitArray, BitArray, IPoint, int );
+*/
+/***********************************************************************
+ *   end polygrf.c definitions
+ **********************************************************************/
+
+
+/***********************************************************************
+ *   BITARRAY.C TYPES
+ **********************************************************************/
+#include "xmemory.h"
+
+#define MINIMUM(x,y) (((x) > (y))? (y) : (x))
+#define MAXIMUM(x,y) (((x) < (y))? (y) : (x))
+
+#define OUTSIDE(MAP,VPF_POINT_STRUCT)\
+  ((VPF_POINT_STRUCT.x < 0)||                      \
+    (VPF_POINT_STRUCT.y < 0)||                      \
+    (VPF_POINT_STRUCT.x > MAP.bounding.x)||   \
+    (VPF_POINT_STRUCT.y > MAP.bounding.y))
+
+#define OUTSIDE_X(MAP,value)  (((value)< 0)||((value)> MAP.bounding.x))
+#define OUTSIDE_Y(MAP,value)  (((value)< 0)||((value)> MAP.bounding.y))
+
+#define GETBIT(MAP,VPF_POINT_STRUCT) \
+   (((MAP.array[(((VPF_POINT_STRUCT.y)*(MAP.rowcount))+((VPF_POINT_STRUCT.x)>>3))])&(1<<((VPF_POINT_STRUCT.x)%8)))? 1: 0)
+
+#define SETBIT(MAP,VPF_POINT_STRUCT) \
+   ((MAP.array[(((VPF_POINT_STRUCT.y)*(MAP.rowcount))+((VPF_POINT_STRUCT.x)>>3))]) |= (1<<((VPF_POINT_STRUCT.x)%8)))
+
+#define CLEARBIT(MAP,VPF_POINT_STRUCT) \
+   ((MAP.array[(((VPF_POINT_STRUCT.y)*(MAP.rowcount))+((VPF_POINT_STRUCT.x)>>3))]) &= ~(1<<((VPF_POINT_STRUCT.x)%8)))
+
+#define TOGGLEBIT(MAP,VPF_POINT_STRUCT) \
+   ((MAP.array[(((VPF_POINT_STRUCT.y)*(MAP.rowcount))+((VPF_POINT_STRUCT.x)>>3))]) ^= (1<<((VPF_POINT_STRUCT.x)%8)))
+
+#define LEFTBITS(INDEX)  (255&(~(255<<(1+(INDEX)))))
+#define RIGHTBITS(INDEX) (255&(~(255>>(8-(INDEX)))))
+
+#define FILLBRESSEG(bseg,seg) \
+{                                                  \
+  int tempx,tempy;                                 \
+  bseg.signs.x = (seg.delta.x < 0) ? -1: 1;        \
+  bseg.signs.y = (seg.delta.y < 0) ? -1: 1;        \
+  tempx = seg.delta.x * bseg.signs.x;              \
+  tempy = seg.delta.y * bseg.signs.y;              \
+  bseg.at = seg.origin;                            \
+                                                   \
+  if (tempy > tempx)                               \
+    {                                              \
+      bseg.Eprim        = (tempx<<1) - tempy;      \
+      bseg.errors.inc   = (tempx<<1);              \
+      bseg.errors.step  = (tempx<<1) - (tempy<<1); \
+      bseg.maximum      = tempy;                   \
+      bseg.toggle       = 1;                       \
+    }                                              \
+  else                                             \
+    {                                              \
+      bseg.Eprim        = (tempy<<1) - tempx;      \
+      bseg.errors.inc   = (tempy<<1);              \
+      bseg.errors.step  = (tempy<<1) - (tempx<<1); \
+      bseg.maximum      = tempx;                   \
+      bseg.toggle       = 0;                       \
+    }                                              \
+}
+
+
+#define STEP(bseg) \
+ if (bseg.maximum){                     \
+   if(bseg.Eprim<0)                    \
+     {                                 \
+       bseg.Eprim += bseg.errors.inc;  \
+       if (bseg.toggle)                \
+         bseg.at.y  += bseg.signs.y;   \
+       else                            \
+         bseg.at.x  += bseg.signs.x;   \
+       bseg.maximum--;                 \
+     }                                 \
+   else                                \
+     {                                 \
+       bseg.Eprim += bseg.errors.step; \
+       bseg.at.x  += bseg.signs.x;     \
+       bseg.at.y  += bseg.signs.y;     \
+       bseg.maximum--;                 \
+     }                                 \
+   }
+
+
+
+
+
+/***********************************************************************
+ *   BITARRAY.C DEFINITIONS
+ **********************************************************************/
+void SETROW( ArrayOfBits MAP,
+	     int	 XMIN,
+	     int	 XMAX,
+	     int	 Y );
+
+void CLEARROW( ArrayOfBits MAP,
+	       int	   XMIN,
+	       int	   XMAX,
+	       int	   Y );
+
+void TOGGLEROW( ArrayOfBits MAP,
+	        int	    XMIN,
+	        int	    XMAX,
+	        int	    Y );
+
+void SETCOLUMN( ArrayOfBits MAP,
+	        int	    X,
+	        int 	    YMIN,
+	        int	    YMAX );
+
+void CLEARCOLUMN( ArrayOfBits MAP,
+		  int	      X,
+		  int 	      YMIN,
+		  int	      YMAX );
+
+void TOGGLECOLUMN( ArrayOfBits MAP,
+		   int	       X,
+		   int	       YMIN,
+		   int	       YMAX );
+
+ArrayOfBits MakeArrayOfBits( int deltaX,
+			     int deltaY );
+
+int FreeArrayOfBits( ArrayOfBits map );
+
+int ClearArrayOfBits( ArrayOfBits map );
+
+int PointGetBit( ArrayOfBits map,
+		 IPoint point );
+
+int PointSetBit( ArrayOfBits map,
+                 IPoint      at,
+		 int  	     value );
+
+int PointAndBit( ArrayOfBits map,
+		 IPoint	     at,
+		 int 	     value );
+
+int PointOrBit( ArrayOfBits map,
+	        IPoint      at,
+	        int	    value );
+
+int PointXorBit( ArrayOfBits map,
+		 IPoint      at,
+		 int 	     value );
+
+int LineSetBit( ArrayOfBits map,
+	        ISegment    seg,
+	        int 	    value );
+
+int LineAndBit( ArrayOfBits map,
+	        ISegment    seg,
+	        int         value );
+
+int LineOrBit( ArrayOfBits map,
+	       ISegment    seg,
+	       int 	   value );
+
+int LineXorBit( ArrayOfBits map,
+	        ISegment    seg,
+	        int 	    value );
+
+/* THESE PROCEDURES NOT DEFINED
+int WedgeSetBit       EXT4( ArrayOfBits, ISegment, IPoint, int );
+int WedgeAndBit       EXT4( ArrayOfBits, ISegment, IPoint, int );
+int WedgeOrBit        EXT4( ArrayOfBits, ISegment, IPoint, int );
+int WedgeXorBit       EXT4( ArrayOfBits, ISegment, IPoint, int );
+*/
+
+int BoxSetBit( ArrayOfBits map,
+	       IBox        box,
+	       int 	   value );
+
+int BoxAndBit( ArrayOfBits map,
+	       IBox        box,
+	       int 	   value );
+
+int BoxOrBit( ArrayOfBits map,
+	      IBox	  box,
+	      int 	  value );
+
+int BoxXorBit( ArrayOfBits map,
+	       IBox	   box,
+	       int	   value );
+
+int TrapezoidSetBit( ArrayOfBits map,
+		     ISegment	 seg,
+		     int	 value );
+
+int TrapezoidAndBit( ArrayOfBits map,
+		     ISegment	 seg,
+		     int	 value );
+
+int TrapezoidOrBit( ArrayOfBits map,
+		    ISegment	seg,
+		    int 	value );
+
+int TrapezoidXorBit( ArrayOfBits map,
+		     ISegment	 seg,
+		     int	 value );
+
+int SetArrayOfBits( ArrayOfBits map,
+		    int 	value );
+
+int AndArrayOfBits( ArrayOfBits map,
+		    int		value );
+
+int OrArrayOfBits( ArrayOfBits map,
+		   ISegment    seg,
+		   int	       value );
+
+int XorArrayOfBits( ArrayOfBits map,
+		    ISegment	seg,
+		    int 	value);
+/***********************************************************************
+ * end of bitarray.c definitions
+ **********************************************************************/
+
+
+/***********************************************************************
+ * Shademap.c definitions
+ **********************************************************************/
+
+#define SOLID   0
+#define STRIPS  1
+#define STRIPES 1
+#define SIMPLE  2
+/* #define COMPLEX_FEATURE 3 */
+
+Shademap *OpenShade( IBox    bounding,
+		     IBox    window,
+		     Color   line,
+		     vpfPattern fill );
+
+int ModifyShade( Shademap *smap,
+		 Color	  line,
+		 vpfPattern  fill );
+
+int WriteShade( Shademap *smap,
+	        IPoint	 point );
+
+int CloseLoop( Shademap *smap );
+
+int CloseShade( Shademap *smap );
+
+int OutShade( Shademap *smap );
+
+vpfPattern MakePattern( int ll,
+		     int lr,
+		     int ul,
+		     int ur );
+
+/***************************************************************************
+ * end shademap.c definitions
+ **************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/projectn.h b/Utilities/OSSIM/ossim_core/vpf_util/projectn.h
new file mode 100644
index 0000000000..26fb829683
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/projectn.h
@@ -0,0 +1,41 @@
+/* PROJECTN.H */
+
+#ifndef __PROJECTN_H__
+
+#define __PROJECTN_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PLATE_CARREE        0
+#define TRANSVERSE_MERCATOR 1
+#define LAMBERT_EQUAL_AREA  2
+#define GNOMONIC            3
+#define NO_PROJECTION       4
+
+void set_projection_parameters( double cm, double origin, double r,
+				int projection );
+
+double central_meridian( double xmin, double xmax );
+
+void set_plate_carree_parameters( double cm, double origin, double r );
+void pcarree_xy( double *x, double *y );
+void pcarree_latlon( double *x, double *y );
+
+void set_tm_parameters( double cm, double origin, double r );
+void tm_xy( double *x, double *y );
+void tm_latlon( double *x, double *y );
+
+void set_lambert_parameters( double cm, double origin, double r );
+void lambert_xy( double *x, double *y );
+void lambert_latlon( double *x, double *y );
+
+void set_gnomonic_parameters( double cm, double origin, double r );
+void gnomonic_xy( double *x, double *y );
+void gnomonic_latlon( double *x, double *y );
+
+#ifdef __cplusplus
+}
+#endif
+   
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/protomas.h b/Utilities/OSSIM/ossim_core/vpf_util/protomas.h
new file mode 100644
index 0000000000..681feebf3b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/protomas.h
@@ -0,0 +1,123 @@
+
+/* PROTOMAS.H */
+
+#ifndef PROTOMASKS_H
+
+#define PROTOMASKS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __STDC__
+#define var_start(x,y) va_start(x,y)
+
+/* These macros expand into ANSI prototypes */
+#define FUN0()		(void)
+#define EXT0()		(void)
+
+#define FUN1(t1,a1)	(t1 a1)
+#define EXT1(t1)	(t1)
+#define FUN1N(t1,a1)	(t1 a1, ...)
+#define EXT1N(t1)	(t1, ...)
+
+#define FUN2(t1,a1,t2,a2)	(t1 a1,t2 a2)
+#define EXT2(t1, t2)		(t1, t2)
+#define FUN2N(t1,a1,t2,a2)	(t1 a1,t2 a2, ...)
+#define EXT2N(t1, t2)		(t1, t2, ...)
+
+#define FUN3(t1,a1,t2,a2,t3,a3)	(t1 a1, t2 a2, t3 a3)
+#define EXT3(t1, t2, t3)	(t1, t2, t3)
+#define FUN3N(t1,a1,t2,a2,t3,a3)(t1 a1, t2 a2, t3 a3, ...)
+#define EXT3N(t1, t2, t3)	(t1, t2, t3, ...)
+
+#define FUN4(t1,a1,t2,a2,t3,a3,t4,a4)	(t1 a1, t2 a2, t3 a3, t4 a4)
+#define EXT4(t1, t2, t3, t4)		(t1, t2, t3, t4)
+
+#define FUN5(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5)	(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5)
+#define EXT5(t1, t2, t3, t4, t5)		(t1, t2, t3, t4, t5)
+
+#define FUN6(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6)	(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6)
+#define EXT6(t1, t2, t3, t4, t5, t6)			(t1, t2, t3, t4, t5, t6)
+
+#define FUN7(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7)	(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7)
+#define EXT7(t1, t2, t3, t4, t5, t6, t7)		(t1, t2, t3, t4, t5, t6, t7)
+
+#define FUN8(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8)	(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8)
+#define EXT8(t1, t2, t3, t4, t5, t6, t7, t8)			(t1, t2, t3, t4, t5, t6, t7, t8)
+
+#define FUN9(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9)	(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9)
+#define EXT9(t1, t2, t3, t4, t5, t6, t7, t8, t9)			(t1, t2, t3, t4, t5, t6, t7, t8, t9)
+
+#define FUN10(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10)	(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9, t10 a10)
+#define EXT10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)				(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)
+
+#define FUN11(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11)	(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9, t10 a10, t11 a11)
+#define EXT11(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11)				(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11)
+
+#define FUN12(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12)	(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9, t10 a10, t11 a11, t12 a12)
+#define EXT12(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12)				(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12)
+
+#define FUN13(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13)	(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9, t10 a10, t11 a11, t12 a12, t13 a13)
+#define EXT13(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13)				(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13)
+
+
+#else
+/* Non-ANSI */
+#define var_start(x,y) va_start(x)
+
+/* These macros expand into old-style function definitions */
+
+#define FUN0()	()
+#define EXT0()	()
+
+#define FUN1(t1,a1)	(a1) t1 a1;
+#define EXT1(t1)	()
+#define FUN1N(t1,a1)	(a1,va_alist) t1 a1; va_dcl
+#define EXT1N(t1)	()
+
+#define FUN2(t1,a1,t2,a2)	(a1, a2) t1 a1; t2 a2;
+#define EXT2(t1, t2)		()
+#define FUN2N(t1,a1,t2,a2,va_alist) (a1, a2) t1 a1; t2 a2; va_dcl
+#define EXT2N(t1, t2)		()
+
+#define FUN3(t1,a1,t2,a2,t3,a3) (a1, a2, a3) t1 a1; t2 a2; t3 a3;
+#define EXT3(t1, t2, t3)	()
+#define FUN3N(t1,a1,t2,a2,t3,a3) (a1, a2, a3, va_alist) t1 a1; t2 a2; t3 a3; va_dcl
+#define EXT3N(t1, t2, t3)	()
+
+#define FUN4(t1,a1,t2,a2,t3,a3,t4,a4)	(a1, a2, a3, a4) t1 a1; t2 a2; t3 a3; t4 a4;
+#define EXT4(t1, t2, t3, t4)		()
+
+#define FUN5(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5) (a1, a2, a3, a4, a5) t1 a1; t2 a2; t3 a3; t4 a4; t5 a5;
+#define EXT5(t1, t2, t3, t4, t5)	()
+
+#define FUN6(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6) (a1, a2, a3, a4, a5, a6) t1 a1; t2 a2; t3 a3; t4 a4; t5 a5; t6 a6;
+#define EXT6(t1, t2, t3, t4, t5, t6)	()
+
+#define FUN7(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7) (a1, a2, a3, a4, a5, a6, a7) t1 a1; t2 a2; t3 a3; t4 a4; t5 a5; t6 a6; t7 a7;
+#define EXT7(t1, t2, t3, t4, t5, t6, t7)	()
+
+#define FUN8(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8) (a1, a2, a3, a4, a5, a6, a7, a8) t1 a1; t2 a2; t3 a3; t4 a4; t5 a5; t6 a6; t7 a7; t8 a8;
+#define EXT8(t1, t2, t3, t4, t5, t6, t7, t8)	()
+
+#define FUN9(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9) (a1, a2, a3, a4, a5, a6, a7, a8, a9) t1 a1; t2 a2; t3 a3; t4 a4; t5 a5; t6 a6; t7 a7; t8 a8; t9 a9;
+#define EXT9(t1, t2, t3, t4, t5, t6, t7, t8, t9)	()
+
+#define FUN10(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10) (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) t1 a1; t2 a2; t3 a3; t4 a4; t5 a5; t6 a6; t7 a7; t8 a8; t9 a9; t10 a10;
+#define EXT10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)	()
+
+#define FUN11(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11) (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) t1 a1; t2 a2; t3 a3; t4 a4; t5 a5; t6 a6; t7 a7; t8 a8; t9 a9; t10 a10; t11 a11;
+#define EXT11(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11)	()
+
+#define FUN12(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12) (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) t1 a1; t2 a2; t3 a3; t4 a4; t5 a5; t6 a6; t7 a7; t8 a8; t9 a9; t10 a10; t11 a11; t12 a12;
+#define EXT12(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12)	()
+
+#define FUN13(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13) (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) t1 a1; t2 a2; t3 a3; t4 a4; t5 a5; t6 a6; t7 a7; t8 a8; t9 a9; t10 a10; t11 a11; t12 a12; t13 a13;
+#define EXT13(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13)	()
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ProtoMasks_h */
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/set.c b/Utilities/OSSIM/ossim_core/vpf_util/set.c
new file mode 100644
index 0000000000..d6dce1b6ed
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/set.c
@@ -0,0 +1,1303 @@
+/*************************************************************************
+ *
+ *N  Module SET.C
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions that make up an abstract data type
+ *     "set".  The data structures and algorithms herein allow programs
+ *     to perform basic manipulations defined in the mathematics of set
+ *     theory.  These operations are fundamental to relational database
+ *     theory, as well.
+ *
+ *     This version allows sets too large to fit in memory to be swapped
+ *     out to disk.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                       DOS Turbo C
+ *    Nov 1991 - Embedded bit manipulation routines instead of using a
+ *               separate module (speed & size).
+ *    Nov 1991 - Added disk swapping capabilities.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    set_type set_init( long int n );
+ *    int  set_empty( set_type set );
+ *    void set_insert( long int element, set_type set );
+ *    void set_delete( long int element, set_type set );
+ *    int set_member( long int element, set_type set );
+ *    long int set_min( set_type set );
+ *    long int set_max( set_type set );
+ *    int  num_in_set( set_type set );
+ *    void set_on( set_type set );
+ *    void set_off( set_type set );
+ *    int  set_equal( set_type a, set_type b );
+ *    void set_assign( set_type *a, set_type b );
+ *    set_type set_union( set_type a, set_type b );
+ *    set_type set_intersection( set_type a, set_type b );
+ *    set_type set_difference( set_type a, set_type b );
+ *    void set_nuke( set_type *set );
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    These functions are all ANSI C compatible.
+ *E
+ *************************************************************************/
+#if defined(__MSDOS__) || defined(__MINGW32__)
+#    include <dirent.h>
+#    include <malloc.h>
+#    include <mem.h>
+#    include <dos.h>
+#else
+#ifndef _WIN32
+
+#include <unistd.h>
+
+#endif
+
+#endif
+
+#include <stdlib.h>
+#include "set.h"
+
+#include <stdio.h>
+#include <string.h>
+#ifndef TRUE
+#define TRUE  1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+static char chkmask[] = {254,253,251,247,239,223,191,127};
+static char setmask[] = {1,2,4,8,16,32,64,128};
+
+#define BITSET(bit,byte)  ((byte | chkmask[bit]) ^ chkmask[bit])
+#define SET_BIT(bit,byte)  (byte | setmask[bit])
+#define UNSET_BIT(bit,byte)  (byte ^ setmask[bit])
+
+#define NBYTES(set)  ((set.size>>3L) + 1L)
+
+/* #define BOUNDSCHECK 1 */
+
+
+static char set_byte( long int nbyte, set_type set )
+{
+   char byte;
+
+   if ( (nbyte < 0) || (nbyte > NBYTES(set)) ) return 0;
+
+   if (set.diskstorage) {
+      fseek(set.fp,nbyte,SEEK_SET);
+      fread(&byte,1,1,set.fp);
+   } else {
+      byte = set.buf[nbyte];
+   }
+   return byte;
+}
+
+#define SET_BYTE( nbyte, set, byte )\
+   if ( (nbyte < 0) || (nbyte > NBYTES(set)) ) byte = 0;        \
+   if (set.diskstorage) {					\
+      fseek(set.fp,nbyte,SEEK_SET);                             \
+      fread(&byte,1,1,set.fp);                                  \
+   } else {                                                     \
+      byte = set.buf[nbyte];                                    \
+   }
+
+
+/*************************************************************************
+ *
+ *N  set_off
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Turns each element in the set 'off'.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    set <inout> == (set_type) set to be acted upon.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Nov 1991                   DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+void set_off( set_type set )
+{
+   register long int nbytes, nbyte, bufsize;
+   char byte=0, *buf;
+
+   if (set.diskstorage) {
+      rewind(set.fp);
+      nbytes = NBYTES(set);
+      /* Use buffered reads and writes to set blocks of bits at a time */
+      nbyte = 0;
+      while (nbyte < nbytes) {
+#ifdef __MSDOS__
+	 bufsize = (long int)min(nbytes-nbyte,farcoreleft()/2L);
+#else
+	 bufsize = (long int)(nbytes-nbyte);
+#endif
+	 buf = (char *)malloc(bufsize);
+	 memset(buf,byte,bufsize);
+	 fwrite(buf,bufsize,1,set.fp);
+	 free(buf);
+	 nbyte += bufsize;
+      }
+
+      rewind(set.fp);
+
+   } else {
+      SET_OFF(set);
+   }
+}
+
+/*************************************************************************
+ *
+ *N  set_on
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Turns each element in the set 'on'.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    set <inout> == (set_type) set to be acted upon.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Nov 1991                   DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+void set_on( set_type set )
+{
+   register long int nbytes,i, bufsize, nbyte;
+#if !defined(__MSDOS__)
+   unsigned
+#endif
+   char byte=255, *buf;
+
+   if (set.diskstorage) {
+      rewind(set.fp);
+      nbytes = NBYTES(set);
+      /* Use buffered reads and writes to set blocks of bits */
+      nbyte = 0;
+      while (nbyte < nbytes) {
+#ifdef __MSDOS__
+	 bufsize = (long int)min(nbytes-nbyte,farcoreleft()/2L);
+ 	buf = (char*)malloc(bufsize);
+#else
+	 bufsize = (long int)(nbytes-nbyte);
+	buf = (unsigned char*)malloc(bufsize);
+#endif
+	 memset(buf,byte,bufsize);
+	 fwrite(buf,bufsize,1,set.fp);
+	 free(buf);
+	 nbyte += bufsize;
+      }
+
+   } else {
+      /* Turn on all bits up through set.size. */
+      /* All but the last byte. */
+      memset(set.buf,byte,set.size>>3L);
+      /* The valid bits of the last byte. */
+      for (i=(set.size>>3L)*8L;i<=set.size;i++)
+	 set_insert(i,set);
+   }
+}
+
+#if __MSDOS__
+static long int available_space( char *drive )
+{
+   struct dfree disktable;
+   int disknum;
+
+   if (!drive) return 0;
+   disknum=toupper(drive[0])-'A'+1;
+   getdfree(disknum,&disktable);
+   return (long int) disktable.df_avail *
+	  (long int) disktable.df_sclus *
+	  (long int) disktable.df_bsec;
+}
+#endif
+
+/*************************************************************************
+ *
+ *N  set_init
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Initialize the set for 'n' elements.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    n       <input> == (long int) maximum number of elements in the set.
+ *    return <output> == (set_type) initialized set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+set_type set_init( long int n )
+{
+   set_type s;
+   long int nbytes;
+
+   s.size = n;
+   nbytes = NBYTES(s);
+#ifdef __MSDOS__
+   if (nbytes < (farcoreleft()/2L)-4096L) {
+#endif
+      s.buf = (char *)malloc(nbytes);
+      s.diskstorage = 0;
+#ifdef __MSDOS__
+   } else {
+      s.diskstorage = 1;
+      s.buf = (char *)malloc(20);
+      /* If the user has specified a RAM disk, use it (faster) */
+      if (getenv("TMP")  &&  nbytes < available_space(getenv("TMP")))
+	 sprintf(s.buf,"%s\\%s",getenv("TMP"),tmpnam(NULL));
+      else
+	 tmpnam(s.buf);
+      s.fp = fopen(s.buf,"w+b");
+      if (!s.fp) {
+	 perror("set_init: ");
+	 exit(1);
+      }
+   }
+#endif
+   set_off(s);
+   return s;
+}
+
+/*************************************************************************
+ *
+ *N  set_empty
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns TRUE if the given set is empty; else it
+ *     returns FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    set     <input> == (set_type) set.
+ *    return <output> == (int) TRUE[1] or FALSE[0].
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+int set_empty( set_type set )
+{
+   register long int i, nbytes;
+
+   nbytes = NBYTES(set);
+   for (i=0;i<nbytes;i++) {
+      if (set_byte(i,set)) {
+	 return FALSE;
+      }
+   }
+   return TRUE;
+}
+
+/*************************************************************************
+ *
+ *N  set_insert
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function inserts the given element into the specified set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    element <input> == (long int) element to insert into the set.
+ *    set     <inout> == (set_type) set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+void set_insert( long int element,
+		 set_type set )
+{
+   long int nbyte,bit;
+   char byte;
+
+   if ((element<0)||(element>set.size)) {
+#ifdef BOUNDSCHECK
+printf("Invalid call to set_insert! (%ld, %ld)\n",
+       element,set.size);
+exit(1);
+#endif
+      return;
+   }
+   nbyte = element>>3L; /* element/8 */
+   bit = element%8L;
+   SET_BYTE(nbyte,set,byte);
+   byte = SET_BIT(bit,byte);
+   if (set.diskstorage) {
+      fseek(set.fp,nbyte,SEEK_SET);
+      fwrite(&byte,1,1,set.fp);
+   } else {
+      set.buf[nbyte] = byte;
+   }
+}
+
+/*************************************************************************
+ *
+ *N  set_delete
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function deletes the given element from the specified set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    element <input> == (long int) element to delete from the set.
+ *    set     <inout> == (set_type) set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void unset_bit()    BITSTUFF.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+void set_delete( long int element,
+		 set_type set )
+{
+   long int nbyte,bit;
+   char byte;
+
+   if ((element<0)||(element>set.size)) {
+#ifdef BOUNDSCHECK
+printf("Invalid call to set_delete!\n");
+exit(1);
+#endif
+      return;
+   }
+   nbyte = element>>3L;  /* element/8 */
+   bit = element%8L;
+   SET_BYTE(nbyte,set,byte);
+   if (!BITSET(bit,byte)) return;
+   byte = UNSET_BIT(bit,byte);
+   if (set.diskstorage) {
+      fseek(set.fp,nbyte,SEEK_SET);
+      fwrite(&byte,1,1,set.fp);
+   } else {
+      set.buf[nbyte] = byte;
+   }
+}
+
+/*************************************************************************
+ *
+ *N  set_member
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether a given element is a member of
+ *     the specified set.  It returns either TRUE or FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    element <input> == (long int) element to check in the set.
+ *    set     <input> == (set_type) set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void bitset()    BITSTUFF.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+int set_member( long int element,
+		set_type set )
+{
+   long int nbyte,bit;
+   char byte;
+
+   if ((element < 0)||(element > set.size)) return FALSE;
+   nbyte = element>>3L;  /* element/8L */
+   bit = element%8L;
+   SET_BYTE(nbyte,set,byte);
+   return BITSET(bit,byte);
+}
+
+/*************************************************************************
+ *
+ *N  set_min
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the minimum element in the given set.
+ *     If the set is empty, the return value is -1.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    set     <input> == (set_type) set.
+ *    return <output> == (long int) minimum element in the set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void bitset()    BITSTUFF.C
+ *    int set_empty( set_type set )     SET.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+long int set_min( set_type set )
+{
+   register long int nbyte, bit, element, nbytes, bufsize, i;
+   char byte='\0', *buf, on;
+
+   /* Find the first byte with a bit set */
+   nbytes = NBYTES(set);
+
+   if (set.diskstorage) {
+
+      /* Set is stored on disk, use block reads to get set into */
+      /* memory one chunk at a time */
+      nbyte = 0;
+      on = 0;
+      rewind(set.fp);
+      while (nbyte < nbytes) {
+#ifdef __MSDOS__
+	 bufsize = (long int)min(nbytes-nbyte,farcoreleft()/2L);
+#else
+	 bufsize = (long int)(nbytes-nbyte);
+#endif
+	 buf = (char *)malloc(bufsize);
+	 fread(buf,bufsize,1,set.fp);
+	 for (i=0;i<bufsize;i++,nbyte++) {
+	    if (buf[i]) {
+	       on = 1;
+	       byte = buf[i];
+	       break;
+	    }
+	 }
+	 free(buf);
+	 if (on) break;
+      }
+
+   } else {
+      for (nbyte=0;nbyte<nbytes;nbyte++)
+	 if (set.buf[nbyte]) {
+	    byte = set.buf[nbyte];
+	    break;
+	 }
+   }
+
+   /* Now find the first bit set in the byte */
+   element = nbyte*8L;
+   for (bit=0; bit<8; bit++,element++) {
+      if (element > set.size) return -1;
+      if (BITSET(bit,byte)) return element;
+   }
+   return -1;
+}
+
+/*************************************************************************
+ *
+ *N  set_max
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the maximum element in the given set.
+ *     If the set is empty, the return value is 0.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    set     <input> == (set_type) set.
+ *    return <output> == (long int) maximum element in the set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+long int set_max( set_type set )
+{
+   register long int nbyte, bit, element, nbytes, bufsize, i;
+   char byte='\0', *buf=0, on='\0';
+
+   /* Find the last byte with a bit set */
+   nbytes = NBYTES(set);
+
+   if (set.diskstorage) {
+
+      /* Set is stored on disk, use block reads to get set into */
+      /* memory one chunk at a time */
+      nbyte = nbytes-1L;
+      on = 0;
+      while (nbyte > 0) {
+#ifdef __MSDOS__
+	 bufsize = (long int)min(nbyte+1L,farcoreleft()/2L);
+#else
+	 bufsize = (long int)(nbyte+1L);
+#endif
+	 buf = (char *)malloc(bufsize);
+	 fseek(set.fp,nbyte-bufsize+1L,SEEK_SET);
+	 fread(buf,bufsize,1,set.fp);
+	 for (i=bufsize-1L;i>0;i--,nbyte--) {
+	    if (buf[i]) {
+	       on = 1;
+	       byte = buf[i];
+	       break;
+	    }
+	 }
+	 free(buf);
+	 if (on) break;
+      }
+   } else {
+
+      for (nbyte = nbytes-1; nbyte >= 0; nbyte--) {
+	 if (set.buf[nbyte]) {
+	    byte = set.buf[nbyte];
+	    break;
+	 }
+      }
+      if (nbyte < 0) return 0L;
+
+   }
+
+   /* Now find last bit set in the byte */
+   element = nbyte*8L + 7L;
+   for (bit=7; bit >= 0; bit--,element--) {
+      if (BITSET(bit,byte)) {
+	 return element;
+      }
+   }
+
+   return 0L;
+}
+
+/*************************************************************************
+ *
+ *N  num_in_set
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the number of elements in the given set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    set     <input> == (set_type) set.
+ *    return <output> == (long int) number of elements in the set.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void bitset()    BITSTUFF.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+long int num_in_set( set_type set )
+{
+   register long int nbyte,bit,n=0, nbytes;
+   char byte;
+
+   nbytes = NBYTES(set);
+   for (nbyte=0;nbyte<nbytes;nbyte++) {
+      byte = set_byte(nbyte,set);
+      if (byte) {
+	 for (bit=0;bit<8;bit++)
+	    if (BITSET(bit,byte)) n++;
+      }
+   }
+   return n;
+}
+
+#if 0
+/*************************************************************************
+ *
+ *N  set_equal
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether two sets are equal to each other.
+ *     It returns TRUE or FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    a       <input> == (set_type) first set to compare.
+ *    b       <input> == (set_type) second set to compare.
+ *    return <output> == (int) TRUE if (a==b) or FALSE if (a!=b).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+int  set_equal( set_type a,
+		set_type b )
+{
+   long int i, nbytes;
+
+   if (a.size != b.size) return FALSE;
+   if ((!a.diskstorage)&&(!b.diskstorage)) {
+      if (memcmp(a.buf,b.buf,NBYTES(a))==0)
+	 return TRUE;
+      else
+	 return FALSE;
+   } else {
+      nbytes = NBYTES(a);
+      for (i=0;i<nbytes;i++) {
+	 if (set_byte(i,a) != set_byte(i,b)) return FALSE;
+      }
+      return TRUE;
+   }
+}
+#endif
+
+/*************************************************************************
+ *
+ *N  set_assign
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function assigns set a to be equal to set b.  If a and b are
+ *     different sizes, the function will reallocate a to match b.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    a       <input> == (set_type *) set to be assigned.
+ *    b       <input> == (set_type) set to assign to a.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+void set_assign( set_type *a,
+		 set_type b )
+{
+   register long int nbytes, nbyte, bufsize;
+   char *buf;
+
+   nbytes = NBYTES(b);
+
+   if (!a->diskstorage && !b.diskstorage) {
+      if (a->size == b.size) {
+	 memcpy(a->buf,b.buf,nbytes);
+      } else {    /* a and b are different sizes */
+	 a->buf = (char *)realloc(a->buf,nbytes);
+	 if (a->buf==NULL) {
+	    a->diskstorage = 1;
+	    a->fp = tmpfile();
+	    fwrite(b.buf,1,nbytes,a->fp);
+	 } else {
+	    memcpy(a->buf,b.buf,nbytes);
+	 }
+	 a->size = b.size;
+      }
+   } else {
+      /* Either a or b or both are stored on disk */
+      if (a->diskstorage && !b.diskstorage) {
+	 rewind(a->fp);
+	 fwrite(b.buf,1,nbytes,a->fp);
+	 a->size = b.size;
+      } else {
+	 /* b.diskstorage must be true to get here */
+	 if (!a->diskstorage) {
+	    /* Force a->diskstorage */
+	    a->diskstorage = 1;
+	    if (a->size > 0) free(a->buf);
+	    a->fp = tmpfile();
+	 }
+
+	 /* Block copy file from b.fp to a->fp */
+	 nbyte = 0;
+	 rewind(b.fp);
+	 rewind(a->fp);
+	 while (nbyte < nbytes) {
+#ifdef __MSDOS__
+	    bufsize = (long int)min(nbytes-nbyte,farcoreleft()/2L);
+#else
+	    bufsize = (long int)(nbytes-nbyte);
+#endif
+	    buf = (char *)malloc(bufsize);
+	    fread(buf,bufsize,1,b.fp);
+	    fwrite(buf,bufsize,1,a->fp);
+	    free(buf);
+	    nbyte += bufsize;
+	 }
+
+	 a->size = b.size;
+      }
+   }
+}
+
+#if 0
+/*************************************************************************
+ *
+ *N  set_union
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Return the set C such that C = (A U B).  C is initialized within
+ *     this function, and should be nuked when no longer needed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    a       <input> == (set_type) set to be unioned.
+ *    b       <input> == (set_type) set to be unioned.
+ *    return <output> == (set_type) (A U B).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    set_type set_init()   SET.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+set_type set_union( set_type a,
+		    set_type b )
+{
+   register long int i, nbytes;
+   set_type c;
+   char byte;
+
+   c = set_init( (long int)max(a.size,b.size) );
+
+   nbytes = NBYTES(c);
+
+   for (i=0;i<nbytes;i++) {
+
+      byte = set_byte(i,a) | set_byte(i,b);
+
+      if (c.diskstorage) {
+	 if (byte) {
+	    fseek(c.fp,i,SEEK_SET);
+	    fwrite(&byte,1,1,c.fp);
+	 }
+      } else {
+	 c.buf[i] = byte;
+      }
+
+   }
+
+   return c;
+}
+#endif
+
+
+/*************************************************************************
+ *
+ *N  set_intersection
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Return the set C such that C = (A o B).  C is initialized within
+ *     this function, and should be nuked when no longer needed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    a       <input> == (set_type) set to be intersectioned.
+ *    b       <input> == (set_type) set to be intersectioned.
+ *    return <output> == (set_type) (A o B).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    set_type set_init()   SET.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+set_type set_intersection( set_type a,
+			   set_type b )
+{
+   register long int i, nbytes;
+   set_type c;
+   char byte;
+#ifdef __MSDOS__
+   c = set_init( (long int)max(a.size,b.size) );
+#else
+   c = set_init( a.size > b.size ? a.size : b.size );
+#endif
+
+   if (c.diskstorage) rewind(c.fp);
+
+   nbytes = NBYTES(c);
+   for (i=0;i<nbytes;i++) {
+      byte = set_byte(i,a) & set_byte(i,b);
+      if (c.diskstorage)
+	 fwrite(&byte,1,1,c.fp);
+      else
+	 c.buf[i] = byte;
+   }
+
+   return c;
+}
+
+#if 0
+/*************************************************************************
+ *
+ *N  set_difference
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Return the set C such that C = (A - B).  C is initialized within
+ *     this function, and should be nuked when no longer needed.
+ *
+ *     NOTE:  This function can be sped up, if necessary, by direct
+ *     manipulation of the bytes and bits rather than the abstract
+ *     set function calls used presently.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    a       <input> == (set_type) set to subtract from.
+ *    b       <input> == (set_type) set to be subtracted.
+ *    return <output> == (set_type) (A - B).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    set_type set_init()   SET.C
+ *    int set_member()      SET.C
+ *    void set_insert()     SET.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+set_type set_difference( set_type a,
+			 set_type b )
+{
+   register long int i;
+   set_type c;
+
+   c = set_init( a.size );
+
+   for (i=0;i<=a.size;i++) {
+      if ( i > b.size ) {
+	 if (set_member(i,a)) set_insert( i, c );
+      } else {
+	 if ((set_member(i,a)) && (!set_member(i,b))) set_insert(i,c);
+      }
+   }
+
+   return c;
+}
+#endif
+
+/*************************************************************************
+ *
+ *N  set_nuke
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Nucleate a set from existence.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    set     <inout> == (set_type *) set to be nuked.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990                  DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This function conforms to ANSI C standards.
+ *E
+ *************************************************************************/
+void set_nuke( set_type *set )
+{
+   if (set->diskstorage) {
+      fclose(set->fp);
+      unlink(set->buf);
+   }
+   free( set->buf );
+   set->size = -1;
+   set->diskstorage = 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/set.h b/Utilities/OSSIM/ossim_core/vpf_util/set.h
new file mode 100644
index 0000000000..d21e2c41bb
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/set.h
@@ -0,0 +1,73 @@
+#if !defined(__SET__)
+
+#define __SET__
+
+/* SET.H */
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* A set is represented as an array of characters with each character */
+/* holding 8 bits of the set. */
+typedef struct {
+   char *buf;
+   long int size;
+   char diskstorage;
+   FILE *fp;
+} set_type;
+
+
+/* Functions: */
+
+set_type set_init( long int n );
+
+int  set_empty( set_type set );
+
+void set_insert( long int element,
+		 set_type set );
+
+void set_delete( long int element,
+		 set_type set );
+
+int set_member( long int element,
+		set_type set );
+
+long int set_min( set_type set );
+
+long int set_max( set_type set );
+
+long int  num_in_set( set_type set );
+
+/* SET_ON and SET_OFF are only valid if the set is in memory */
+#define SET_ON(set) memset(set.buf,255,(set.size>>3L)+1L)
+#define SET_OFF(set) memset(set.buf,0,(set.size>>3L)+1L)
+
+/* set_on and set_off are valid for all sets */
+void set_on( set_type set );
+
+void set_off( set_type set );
+
+int  set_equal( set_type a,
+		set_type b );
+
+void set_assign( set_type *a,
+		 set_type b );
+
+set_type set_union( set_type a,
+		    set_type b );
+
+set_type set_intersection( set_type a,
+			   set_type b );
+
+set_type set_difference( set_type a,
+			 set_type b );
+
+void set_nuke( set_type *set );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/system.h b/Utilities/OSSIM/ossim_core/vpf_util/system.h
new file mode 100644
index 0000000000..be7f6d07e6
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/system.h
@@ -0,0 +1,59 @@
+#ifndef system_HEADER
+#define system_HEADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* SYSTEM.H */
+
+int getfilename( char *filename );
+
+int get_input_string( char *prompt, char *string );
+
+int verify( char **text,
+	    int  n );
+
+char *pickfile( char *path,
+		char attrib,
+		char *title );
+
+void displayinfo( char *text[],
+		  int  nlines );
+
+char *currentdir( void );
+
+void showdir( void );
+
+void listdirs( void );
+
+void changedir( void );
+
+void createdir( void );
+
+void deletedir( void );
+
+void viewfile( char *filespec, int height );
+
+void listfiles( char *filespec );
+
+void deletefile( void );
+
+void movefile( void );
+
+void filecopy( char *from, char *to );
+
+void copyfile( void );
+
+void diskspace( void );
+
+void changedrive( void );
+
+void showdrive( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+   
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/values.h b/Utilities/OSSIM/ossim_core/vpf_util/values.h
new file mode 100644
index 0000000000..e12ee63ce4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/values.h
@@ -0,0 +1,92 @@
+/* Old compatibility names for <limits.h> and <float.h> constants.
+   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This interface is obsolete.  New programs should use
+   <limits.h> and/or <float.h> instead of <values.h>.  */
+
+#ifndef	_VALUES_H
+#define	_VALUES_H	1
+
+#include <limits.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef MAXSHORT
+#undef MAXSHORT
+#endif
+#ifdef MAXFLOAT
+#undef MAXFLOAT
+#endif 
+
+#define _TYPEBITS(type)	(sizeof (type) * CHAR_BIT)
+
+#define CHARBITS	_TYPEBITS (char)
+#define SHORTBITS	_TYPEBITS (short int)
+#define INTBITS		_TYPEBITS (int)
+#define LONGBITS	_TYPEBITS (long int)
+#define PTRBITS		_TYPEBITS (char *)
+#define DOUBLEBITS	_TYPEBITS (double)
+#define FLOATBITS	_TYPEBITS (float)
+
+#ifndef MINSHORT
+#  define   MINSHORT	SHRT_MIN
+#endif
+#ifndef MININT
+#  define	MININT		INT_MIN
+#endif
+#ifndef MINLONG
+#  define	MINLONG		LONG_MIN
+#endif
+
+#ifndef MAXSHORT
+#  define	MAXSHORT	SHRT_MAX
+#endif
+#ifndef MAXINT
+#  define	MAXINT		INT_MAX
+#endif
+#ifndef MAXLONG
+#  define	MAXLONG		LONG_MAX
+#endif
+
+#define HIBITS		MINSHORT
+#define HIBITL		MINLONG
+
+
+#include <float.h>
+
+#define	MAXDOUBLE	DBL_MAX
+#define	MAXFLOAT	FLT_MAX
+#define	MINDOUBLE	DBL_MIN
+#define	MINFLOAT	FLT_MIN
+#define	DMINEXP		DBL_MIN_EXP
+#define	FMINEXP		FLT_MIN_EXP
+#define	DMAXEXP		DBL_MAX_EXP
+#define	FMAXEXP		FLT_MAX_EXP
+
+
+#ifdef __USE_MISC
+/* Some systems define this name instead of CHAR_BIT or CHARBITS.  */
+# define BITSPERBYTE	CHAR_BIT
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* values.h */
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfclip.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfclip.c
new file mode 100644
index 0000000000..cfdbff7d08
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfclip.c
@@ -0,0 +1,285 @@
+/*************************************************************************
+ *
+ *N  Module VPFCLIP
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module geometrically clips an edge table to a given map
+ *     extent and creates a new edge table.  It does not attempt to
+ *     maintain topology, nor does it maintain its relationship to
+ *     any feature tables associated with it.  Its intent is to be
+ *     used only for the Library Reference coverage.  It may also serve
+ *     as a basic starting point for a complete GIS clipping algorithm.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    Dec 1991                     DOS Turbo C
+ *E
+ *************************************************************************/
+
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+#if defined(__MSDOS__) || defined(__MINGW32__)
+#  include <malloc.h>
+#  include <mem.h>
+#else
+#  ifdef MACOSX 
+#    include <sys/types.h>
+#    include <sys/malloc.h>
+#  else
+#    include <malloc.h>
+#    include <string.h>
+#  endif
+#endif
+
+#include "vpftable.h"
+#include "vpfview.h"
+#include "vpfprim.h"
+
+typedef struct {
+   float x1, y1, x2, y2;
+} line_segment_type;
+
+/* Defined in VPFPTPLY.C */
+int intersect( line_segment_type l1, line_segment_type l2,
+	       float *xint, float *yint );
+
+edge_rec_type create_edge_rec( row_type row, vpf_table_type edge_table );
+
+/* Determine if a line segment intersects a box. 		   */
+/* If so return the intersection coordinate in the parameter list. */
+static int box_intersection( line_segment_type lseg,
+			     extent_type extent,
+			     coordinate_type *coord )
+{
+   line_segment_type boxseg;
+   float xint, yint;
+
+   boxseg.x1 = extent.x1;
+   boxseg.y1 = extent.y1;
+   boxseg.x2 = extent.x2;
+   boxseg.y2 = extent.y1;
+   if (intersect(lseg,boxseg,&xint,&yint)) {
+      coord->x = xint;
+      coord->y = yint;
+      return TRUE;
+   }
+
+   boxseg.x1 = extent.x2;
+   boxseg.y1 = extent.y1;
+   boxseg.x2 = extent.x2;
+   boxseg.y2 = extent.y2;
+   if (intersect(lseg,boxseg,&xint,&yint)) {
+      coord->x = xint;
+      coord->y = yint;
+      return TRUE;
+   }
+
+   boxseg.x1 = extent.x2;
+   boxseg.y1 = extent.y2;
+   boxseg.x2 = extent.x1;
+   boxseg.y2 = extent.y2;
+   if (intersect(lseg,boxseg,&xint,&yint)) {
+      coord->x = xint;
+      coord->y = yint;
+      return TRUE;
+   }
+
+   boxseg.x1 = extent.x1;
+   boxseg.y1 = extent.y2;
+   boxseg.x2 = extent.x1;
+   boxseg.y2 = extent.y1;
+   if (intersect(lseg,boxseg,&xint,&yint)) {
+      coord->x = xint;
+      coord->y = yint;
+      return TRUE;
+   }
+   return FALSE;
+}
+
+/* Replace the given coordinate string into the given edge row */
+/* and write the new row to the specified edge table.	       */
+static void write_edge_record( long int id, coordinate_type *coord,
+			       long int ncoord, row_type row,
+			       vpf_table_type *table )
+{
+   int ID_, COORD_;
+
+   ID_ = table_pos("ID",*table);
+   COORD_ = table_pos("COORDINATES",*table);
+
+   put_table_element(ID_, row, *table, &id, 1);
+   put_table_element(COORD_, row, *table, coord, ncoord);
+   write_next_row(row,table);
+
+}
+
+
+
+#define WITHIN(x,y,ext) ((x>=ext.x1)&&(x<=ext.x2)&&(y>=ext.y1)&&(y<=ext.y2))
+
+/*************************************************************************
+ *
+ *N  vpf_edge_clip
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function clips an edge table to the given extent and writes
+ *     the clipped table to the specified output path.
+ *     NOTE: If a segment of an edge in the EDG table has both a beginning
+ *     point and ending point outside of the given extent, and the line
+ *     segment passes through the extent, the segment will not be written
+ *     out to the new edge table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    covpath <input> == (char *) path to the coverage of the edge table.
+ *    extent  <input> == (extent_type) clipping extent.
+ *    outpath <input> == (char *) output path for the clipped edge table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    Dec 1991      Original Version    DOS Turbo C
+ *E
+ *************************************************************************/
+void vpf_edge_clip( char *covpath, extent_type extent, char *outpath )
+{
+   vpf_table_type in, out;
+   row_type row;
+   edge_rec_type inedge, outedge;
+   long int i,j,n,id;
+   line_segment_type lseg;
+   coordinate_type coord;
+   char path[255], *def;
+   float xmin, xmax, ymin, ymax;
+
+   /* Standardize extent, Lower Left, Upper Right */
+   xmin = (float)min(extent.x1,extent.x2);
+   xmax = (float)max(extent.x1,extent.x2);
+   ymin = (float)min(extent.y1,extent.y2);
+   ymax = (float)max(extent.y1,extent.y2);
+   extent.x1 = xmin;
+   extent.y1 = ymin;
+   extent.x2 = xmax;
+   extent.y2 = ymax;
+
+   sprintf(path,"%sedg",covpath);
+   in = vpf_open_table(path,disk,"rb",NULL);
+
+   rewind(in.fp);
+   fread(&n,sizeof(n),1,in.fp);
+   def = (char *)vpfmalloc((n+1)*sizeof(char));
+   fread(def,sizeof(char),n,in.fp);
+   def[n] = '\0';
+   sprintf(path,"%sedg",outpath);
+   out = vpf_open_table(path,disk,"wb",def);
+
+   for (i=1,id=1;i<=in.nrows;i++) {
+      row = get_row( i, in );
+      inedge = create_edge_rec( row, in );
+      if (!inedge.coord) {
+	 free_row(row,in);
+	 continue;
+      }
+      outedge.coord = (coordinate_type *)malloc(inedge.npts*sizeof(
+						coordinate_type));
+      if (!outedge.coord) {
+	 free(inedge.coord);
+	 free_row(row,in);
+	 continue;
+      }
+
+      n = 0;
+
+      for (j=0;j<inedge.npts;j++) {
+
+	 if (WITHIN(inedge.coord[j].x,inedge.coord[j].y,extent)) {
+	    /* Current coordinate within extent */
+
+	    if (j > 0) {
+	       if (!WITHIN(inedge.coord[j-1].x,inedge.coord[j-1].y,
+			    extent)) {
+		  /* Previous coordinate was not in the extent - */
+		  /* create an intersection vertex */
+
+		  lseg.x1 = inedge.coord[j-1].x;
+		  lseg.y1 = inedge.coord[j-1].y;
+		  lseg.x2 = inedge.coord[j].x;
+		  lseg.y2 = inedge.coord[j].y;
+		  if (box_intersection(lseg,extent,&coord)) {
+		     outedge.coord[n].x = coord.x;
+		     outedge.coord[n].y = coord.y;
+		  } else {
+		     outedge.coord[n].x = lseg.x1;
+		     outedge.coord[n].y = lseg.y1;
+		  }
+		  n++;
+	       }
+	    }
+	    outedge.coord[n].x = inedge.coord[j].x;
+	    outedge.coord[n].y = inedge.coord[j].y;
+	    n++;
+	 } else {
+	    if (j > 0) {
+	       if (WITHIN(inedge.coord[j-1].x,inedge.coord[j-1].y,extent)) {
+
+		  /* The coordinate is not within the extent and     */
+		  /* the previous one was - Create an intersection   */
+		  /* vertex point and write the current edge record. */
+
+		  lseg.x1 = inedge.coord[j-1].x;
+		  lseg.y1 = inedge.coord[j-1].y;
+		  lseg.x2 = inedge.coord[j].x;
+		  lseg.y2 = inedge.coord[j].y;
+		  if (box_intersection(lseg,extent,&coord)) {
+		     outedge.coord[n].x = coord.x;
+		     outedge.coord[n].y = coord.y;
+		  } else {
+		     outedge.coord[n].x = lseg.x2;
+                     outedge.coord[n].y = lseg.y2;
+		  }
+
+		  /* Break the edge in (at least) two */
+		  n++;
+		  write_edge_record( id, outedge.coord, n, row, &out );
+		  id++;
+		  n=0;
+
+	       }
+	    }
+	 }
+      }
+      free(inedge.coord);
+
+      if (n > 0) {
+	 write_edge_record( id, outedge.coord, n, row, &out );
+	 id++;
+      }
+
+      free(outedge.coord);
+      free_row(row,in);
+   }
+
+   vpf_close_table(&in);
+   vpf_close_table(&out);
+}
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfcntnt.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfcntnt.c
new file mode 100644
index 0000000000..a65de92fb8
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfcntnt.c
@@ -0,0 +1,510 @@
+/***************************************************************************
+ *
+ *N  VPFCNTNT.C  - VPF Contents
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This module contains functions to display the contents of VPF tables
+ *    and VPF databases and libraries.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels      November 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ **************************************************************************/
+#if defined(__CYGWIN__) || defined(MACOSX)|| defined(_WIN32)
+#  include "./values.h"
+#else
+#  include <values.h>
+#endif
+
+#include <stdlib.h>
+
+#ifdef __MSDOS__
+#  include <graphics.h>
+#  include <dir.h>
+#  include <dos.h>
+#  include <alloc.h>
+#else
+#  ifndef _WIN32
+#    include <unistd.h>
+#  endif
+#  ifdef MACOSX
+#    include <sys/types.h>
+#    include <sys/malloc.h>
+#    define MAXINT INT_MAX
+#    ifndef MAXSHORT
+#        define MAXSHORT SHORT_MAX
+#    endif
+#    define MAXLONG  LONG_MAX
+#  else
+#    include <malloc.h>
+#  endif
+#endif
+#ifdef _MSC_VER
+#  include <io.h>
+#endif
+
+#include <string.h>
+#include "vpftable.h"
+#include "vpfview.h"
+#include "system.h"
+#include "vpfmisc.h"
+#include "vpfdisp.h"
+
+
+
+
+/**************************************************************************
+ *
+ *N  vpf_dump_table
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Dump the contents of a VPF table into an ASCII file
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    tablename <input> == (char *) VPF table to dump.
+ *    outname   <input> == (char *) name of ASCII dump file.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+void vpf_dump_table( char *tablename, char *outname )
+{
+   vpf_table_type table;
+   long int   i,j,k,n;
+   int        ival,*iptr;
+   long int   lval,*lptr;
+   float      fval,*fptr;
+   date_type  dval,*dptr;
+   id_triplet_type kval, *kptr;
+   coordinate_type cval, *cptr;
+   char       *buf,  ch, date[40];
+   row_type   row;
+   FILE       *fp;
+
+   fp = fopen(outname,"w");
+
+   table = vpf_open_table(tablename,disk,"rb",NULL);
+
+   fprintf(fp,"%s\n%s\n\n",tablename,table.description);
+
+   fprintf(fp,"Definition:\n");
+   for (i=0;i<table.nfields;i++) {
+      if (table.header[i].count < 0)
+	 fprintf(fp,"%s (%c,*)  %s\n",
+		 table.header[i].name,table.header[i].type,
+		 table.header[i].description);
+      else
+	 fprintf(fp,"%s (%c,%ld)  %s\n",
+		 table.header[i].name,table.header[i].type,
+		 table.header[i].count,table.header[i].description);
+   }
+
+   fprintf(fp,"\nContents:\n");
+   for (i=1;i<=table.nrows;i++) {
+      row = read_next_row(table);
+      for (j=0;j<table.nfields;j++) {
+	 fprintf(fp,"%s: ",table.header[j].name);
+	 switch (table.header[j].type) {
+	    case 'T':
+	       if (table.header[j].count==1) {
+		  get_table_element(j,row,table,&ch,&n);
+		  fprintf(fp,"%c\n",ch);
+	       } else {
+		  buf = (char *)get_table_element(j,row,table,NULL,&n);
+		  n = strlen(table.header[j].name) + 2;
+		  for (k=0;(unsigned int)k<strlen(buf);k++) {
+		     fprintf(fp,"%c",buf[k]);
+		     n++;
+		     if (n>80) {
+			fprintf(fp,"\n");
+			n = 0;
+		     }
+		  }
+		  fprintf(fp,"\n");
+		  free(buf);
+	       }
+	       break;
+	    case 'I':
+	       if (table.header[j].count==1) {
+		  get_table_element(j,row,table,&lval,&n);
+		  if (lval != MAXFLOAT)
+		     fprintf(fp,"%ld\n",lval);
+		  else
+		     fprintf(fp,"(null)\n");
+	       } else {
+		  lptr = (long int*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++) {
+		     if (lptr[k] != MAXFLOAT)
+			fprintf(fp,"%ld ",lptr[k]);
+		     else
+			fprintf(fp,"(null) ");
+		  }
+		  fprintf(fp,"\n");
+		  free(lptr);
+	       }
+	       break;
+	    case 'S':
+	       if (table.header[j].count==1) {
+		  get_table_element(j,row,table,&ival,&n);
+		  if (ival != MAXINT)
+		     fprintf(fp,"%d\n",ival);
+		  else
+		     fprintf(fp,"(null)\n");
+	       } else {
+		  iptr = (int*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++) {
+		     if (iptr[k] != MAXINT)
+			fprintf(fp,"%d ",iptr[k]);
+		     else
+			fprintf(fp,"(null) ");
+		  }
+		  fprintf(fp,"\n");
+		  free(iptr);
+	       }
+	       break;
+	    case 'F':
+	       if (table.header[j].count==1) {
+		  get_table_element(j,row,table,&fval,&n);
+		  if (fval != MAXFLOAT)
+		     fprintf(fp,"%f\n",fval);
+		  else
+		     fprintf(fp,"(null)\n");
+	       } else {
+		  fptr = (float*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++) {
+		     if (fptr[k] != MAXFLOAT)
+			fprintf(fp,"%f ",fptr[k]);
+		     else
+			fprintf(fp,"(null) ");
+		  }
+		  fprintf(fp,"\n");
+		  free(fptr);
+	       }
+	       break;
+	    case 'C':
+	       if (table.header[j].count==1) {
+		  get_table_element(j,row,table,&cval,&n);
+		  fprintf(fp,"(%f,%f)\n",cval.x,cval.y);
+	       } else {
+		  cptr = (coordinate_type*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+		     fprintf(fp,"(%f,%f) ",cptr[k].x,cptr[k].y);
+		  fprintf(fp,"\n");
+		  free(cptr);
+	       }
+	       break;
+	    case 'K':
+	       if (table.header[j].count==1) {
+		  get_table_element(j,row,table,&kval,&n);
+		  fprintf(fp,"(%ld,%ld,%ld)\n",
+			  kval.id,kval.tile,kval.exid);
+	       } else {
+		  kptr = (id_triplet_type*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++)
+		     fprintf(fp,"(%ld,%ld,%ld)  ",
+			     kptr[k].id,kptr[k].tile,kptr[k].exid);
+		  fprintf(fp,"\n");
+		  free(kptr);
+	       }
+	       break;
+	    case 'D':   /* Date */
+	       if (table.header[j].count==1) {
+		  get_table_element(j,row,table,&dval,&n);
+		  format_date(dval,date);
+		  fprintf(fp,"%s\n",date);
+	       } else {
+		  dptr = (date_type*)get_table_element(j,row,table,NULL,&n);
+		  for (k=0;k<n;k++) {
+		     format_date((char*)(&dptr[k]),date);
+		     fprintf(fp,"%s ",date);
+		  }
+		  fprintf(fp,"\n");
+		  free(dptr);
+	       }
+	       break;
+	 }
+      }
+      fprintf(fp,"\n");
+      free_row( row, table );
+   }
+
+   fclose(fp);
+   vpf_close_table( &table );
+}
+
+
+/* Dump a Narrative-style .DOC VPF table to an ASCII file */
+/**************************************************************************
+ *
+ *N  vpf_dump_doc_table
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Dump the contents of a narrative-style .DOC VPF table into an
+ *    ASCII file as a series of text strings.  This function checks
+ *    to make sure that the given table is a real narrative file
+ *    (two fields: ID and TEXT).  If not, it displays it as a normal
+ *    VPF table.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    tablename <input> == (char *) narrative-style .DOC VPF table to dump.
+ *    outname   <input> == (char *) name of ASCII dump file.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+void vpf_dump_doc_table( char *tablename, char *outname )
+{
+   vpf_table_type table;
+   long int   i,n;
+   char       *buf;
+   row_type   row;
+   FILE       *fp;
+
+   fp = fopen(outname,"w");
+
+   table = vpf_open_table(tablename,disk,"rb",NULL);
+
+   /* Check header to make sure the table is a narrative table */
+   if ((ossim_strcasecmp(table.header[1].name,"TEXT") != 0) ||
+       (table.nfields != 2)) {
+      /* Not a real narrative table -> normal VPF table dump */
+      vpf_close_table(&table);
+      vpf_dump_table(tablename,outname);
+      return;
+   }
+
+   fprintf(fp,"%s\n%s\n\n",tablename,table.description);
+
+   for (i=1;i<=table.nrows;i++) {
+      row = read_next_row(table);
+      buf = (char *)get_table_element(1,row,table,NULL,&n);
+      fprintf(fp,"%s\n",buf);
+      free(buf);
+      free_row(row,table);
+   }
+
+   fclose(fp);
+   vpf_close_table( &table );
+}
+
+#if 0
+static void not_a_vpf_table( char *path )
+{
+   char *buf,*filename,*tempstr,ch;
+
+   buf = (char *)vpfmalloc(255);
+   filename = (char *)vpfmalloc(255);
+
+   /* Not a VPF table - try to determine what type of file it is */
+   if (strstr(path,"\\asi") ||
+       strstr(path,"\\lsi") ||
+       strstr(path,"\\nsi") ||
+       strstr(path,"\\csi") ||
+       strstr(path,"\\tsi")) {
+      sprintf(filename,"%s is a spatial index file.",path);
+      displaymessage(filename,
+	   "It is not a VPF table and cannot be viewed directly",
+	   NULL);
+   } else if (strstr(path,".ati") ||
+	      strstr(path,".lti") ||
+	      strstr(path,".pti") ||
+	      strstr(path,".tti")) {
+      sprintf(filename,"%s is a thematic index file.",path);
+      displaymessage(filename,
+	       "It is not a VPF table and cannot be viewed directly",
+	       NULL);
+   } else if (path[strlen(path)-1] == 'x') {
+      /* Need to determine what file it is the index for */
+      sprintf(buf,"%s is a variable-length index file",path);
+      strcpy(filename,path);
+      for (ch='a';ch <= 'z';ch++) {
+	 if (ch=='x') continue;
+	 filename[strlen(path)-1] = ch;
+	 if (access(filename,0) == 0) {
+	    tempstr = strdup(filename);
+	    sprintf(filename,"for %s.",tempstr);
+	    free(tempstr);
+	    break;
+	 }
+      }
+      if (strcmp(path,filename)==0) {
+	 displaymessage(buf,
+	       "It is not a VPF table and cannot be viewed directly.",
+	       NULL);
+      } else {
+	    displaymessage(buf, filename,
+	       "It is not a VPF table and cannot be viewed directly.",
+	       NULL);
+      }
+   } else {
+      /* Not a VPF type of file */
+      sprintf(filename,"%s: Not a VPF table",path);
+      display_message(filename);
+   }
+
+   free(filename);
+   free(buf);
+}
+#endif
+
+#if 0
+/**************************************************************************
+ *
+ *N  display_database_contents
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    List the tables in the Database level directory and display their
+ *    contents if selected.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    database <input> == (database_type) VPF database.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+void display_database_contents( database_type database )
+{
+   char *filename, *dbpath, *path, *dbstr;
+
+   dbstr = (char *)vpfmalloc(128);
+   dbpath = (char *)vpfmalloc(255);
+   filename = (char *)vpfmalloc(128);
+   path = (char *)vpfmalloc(255);
+
+   strcpy( dbstr, "Database: " );
+   strcat( dbstr, database.name );
+
+   strcpy(dbpath,database.path);
+   strcat(dbpath,"*.*");
+   do {
+      strcpy(filename,pickfile(dbpath,0,dbstr));
+      if (strcmp(filename,"")==0) break;
+      strcpy( path, database.path );
+      strcat( path, filename );
+      rightjust(path);
+      strlwr(path);
+      if (is_vpf_table(path)) {
+	 if (strstr(path,".doc"))
+	    vpf_dump_doc_table(path,"temp.out");
+	 else
+	    vpf_dump_table(path,"temp.out");
+	 viewfile("temp.out", getmaxy()/3);
+	 unlink("temp.out");
+      } else {
+	 not_a_vpf_table(path);
+      }
+   } while (strcmp(filename,"") != 0);
+
+   free(path);
+   free(filename);
+   free(dbpath);
+   free(dbstr);
+}
+
+/**************************************************************************
+ *
+ *N  display_library_contents
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    List the tables in the Library level directory and display their
+ *    contents if selected.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    library   <input> == (library_type) VPF library structure.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+void display_library_contents( library_type library )
+{
+   char *filename, *libpath, *path, *libstr;
+
+   libstr = (char *)vpfmalloc(128);
+   libpath = (char *)vpfmalloc(255);
+   filename = (char *)vpfmalloc(128);
+   path = (char *)vpfmalloc(255);
+
+   strcpy( libstr, "Library: " );
+   strcat( libstr, library.name );
+
+   strcpy(libpath,library.path);
+   strcat(libpath,"*.*");
+   do {
+      strcpy(filename,pickfile(libpath,0,libstr));
+      if (strcmp(filename,"")==0) break;
+      strcpy( path, library.path );
+      strcat( path, filename );
+      rightjust(path);
+      leftjust(path);
+      strlwr(path);
+      if (is_vpf_table(path)) {
+	 strlwr(path);
+	 if (strstr(path,".doc"))
+	    vpf_dump_doc_table(path,"temp.out");
+	 else
+	    vpf_dump_table(path,"temp.out");
+	 viewfile("temp.out", getmaxy()/3);
+	 unlink("temp.out");
+      } else {
+	 not_a_vpf_table(path);
+      }
+   } while (strcmp(filename,"") != 0);
+
+   free(path);
+   free(filename);
+   free(libpath);
+   free(libstr);
+}
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfdict.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfdict.c
new file mode 100644
index 0000000000..0de629ab32
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfdict.c
@@ -0,0 +1,236 @@
+#include <stdio.h>
+#include <string.h>
+#ifdef __MSDOS__
+#include <graphics.h>
+#endif
+
+#ifdef __MSDOS__
+#include <alloc.h>
+#include <mem.h>
+#else
+#ifdef MACOSX 
+#include <sys/types.h>
+#include <sys/malloc.h>
+#else
+#include <malloc.h>
+#include <string.h>
+#endif
+#endif
+
+
+#include "vpftable.h"
+#include "vpfview.h"
+#include "vpfinit.h"
+
+extern color_type menutextcolor,menubordercolor,menucolor;
+#if 0
+/*************************************************************************
+ *
+ *N  feature_class_dictionary
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays the data dictionary for a feature class.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    fc  <input> == (int) feature class number.
+ *    lib <input> == (library_type) VPF library structure.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Mody Buchbinder  May 1991   Original Version   DOS Turbo C
+ *    Barry Michaels July 1991 - Separated into two routines
+ *    Barry Michaels  Oct 1991 - Modified narrative table read
+ *E
+ *************************************************************************/
+void feature_class_dictionary( int fc, library_type lib )
+{
+   int                i,j,k,
+		      it_pos,val_pos,des_pos,att_pos;
+   char               *outfile,*line,temp[128],temp2[128],
+		      *item_buf, *att_buf, *des_buf, *tval;
+   vpf_table_type     ft,table,nar;
+   storage_type       stor = disk;
+   FILE               *out;
+   row_type           row;
+   float              fval;
+   long int           ival,n;
+
+   hidemousecursor();
+   time_cursor();
+   showmousecursor();
+
+   /** prepare temporary display file **/
+   outfile = (char *)malloc(L_tmpnam + 2);
+   outfile = tmpnam(outfile);
+   out = fopen(outfile,"w");
+
+   /** start to write to display file **/
+   fprintf(out,"FEATURE CLASS: %s \n",lib.fc[fc].description);
+   fprintf(out,"COVERAGE     : %s \n",
+	   lib.cover[lib.fc[fc].coverage].description);
+
+   ft = vpf_open_table(lib.fc[fc].table,stor,"rb",NULL);
+
+   fprintf(out,"ATTRIBUTES:\n");
+
+   for(i=0;i<ft.nfields;i++) {
+     fprintf(out,"   %s - %s \n",ft.header[i].name,ft.header[i].description);
+     if(ft.header[i].vdt[0] != '\0')
+
+	 /** create table name **/
+      { strcpy(temp,lib.fc[fc].table);
+	 /** cut temp to path and name **/
+	for(j=strlen(temp);temp[j] != '\\';j--);
+	temp[j] = '\0';
+
+	rightjust(temp);
+
+	 /** add to the path the new table name **/
+	strcpy(temp2,temp);
+	strcat(temp2,"\\");
+	strcat(temp2,ft.header[i].vdt);
+	if(access(temp2,0) == 0)
+	  {
+	    table   = vpf_open_table(temp2,stor,"rb",NULL);
+	    it_pos  = table_pos("TABLE",table);
+	    val_pos = table_pos("VALUE",table);
+	    des_pos = table_pos("DESCRIPTION",table);
+	    att_pos = table_pos("ATTRIBUTE",table);
+
+	    for(k=1;k<=table.nrows;k++)
+	      {
+		if (stor == disk)
+		   row = read_next_row(table);
+		else
+		   row = get_row(k,table);
+		item_buf = (char *)get_table_element( it_pos
+						,row,table,NULL,&n);
+
+		rightjust(item_buf);
+
+		att_buf  = (char *)get_table_element(att_pos
+						,row,table,NULL,&n);
+
+		rightjust(att_buf);
+
+		if(ossim_strcasecmp(item_buf,&temp[j+1]) == 0 &&
+                   ossim_strcasecmp(att_buf,ft.header[i].name) == 0)
+		   { des_buf  = (char *)get_table_element(des_pos
+						,row,table,NULL,&n);
+		     switch (ft.header[i].type) {
+			case 'T':
+		     tval = (char *)get_table_element(val_pos
+						,row,table,NULL,&n);
+		     fprintf(out,"    %s =  %s  \n",tval,des_buf);
+		     free(tval);break;
+			case 'I':
+		     get_table_element(val_pos,row,table,&ival,&n);
+		     fprintf(out,"    %12ld =  %s  \n",ival,des_buf);
+		     break;
+			case 'F':
+		     get_table_element(val_pos,row,table,&fval,&n);
+		     fprintf(out,"    %12f =  %s  \n",fval,des_buf);
+		     break;
+		     } /** switch **/
+		     free(des_buf);
+		   }  /** if strcmp **/
+
+		free(item_buf);
+		free(att_buf);
+		free_row(row,table);
+	      }  /** for k on table.nrows **/
+	    vpf_close_table(&table);
+	  } /** if access **/
+      } /** if there is vdt **/
+   }  /** for fields **/
+
+   /** get information from narrative file if it exists **/
+   if(ft.narrative[0] != '\0') {
+      sprintf(temp,"%s%s",ft.path,ft.narrative);
+      if (access(temp,0)==0) {
+	 fprintf(out,"\n\n");
+	 nar = vpf_open_table(temp,disk,"rb",NULL);
+	 for (i=1;i<=nar.nrows;i++) {
+	    row = read_next_row(nar);
+	    line = (char *)get_table_element(1,row,nar,NULL,&n);
+	    rightjust(line);
+	    fprintf(out,"%s\n",line);
+	    free(line);
+	    free_row(row,nar);
+	 }
+	 vpf_close_table(&nar);
+      }
+   }
+
+   /** clean up **/
+   vpf_close_table(&ft);
+   fclose(out);
+
+   arrow_cursor();
+
+   viewfile(outfile,getmaxy()/3);
+   remove(outfile);
+   free(outfile);
+}
+
+/*************************************************************************
+ *
+ *N  display_data_dictionary
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function shows a feature class menu, lets the user select
+ *     a feature class and print the information from the data dictionary
+ *     for this feature class
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    lib <in> == (library_type) VPF library structure.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Mody Buchbinder  May 1991   Original Version   DOS Turbo C
+ *    Barry Michaels  June 1991 - Separated into two routines.
+ *    Barry Michaels   Oct 1991 - Feature class selection from a panel.
+ *    Barry Michaels   Jan 1992 - Select FCs by coverage first.
+ *E
+ *************************************************************************/
+void display_data_dictionary(library_type lib)
+{
+   int       fc,cov;
+   view_type dummyview;
+   char      title[80];
+
+   dummyview.nthemes = 0;
+
+   cov = 0;
+   while (cov >= 0) {
+      sprintf(title,"%s COVERAGES",lib.name);
+      cov = select_coverage(&dummyview,&lib,title);
+      if (cov < 0) break;
+      fc = 0;
+      while (fc >= 0) {
+	 sprintf(title,"%s Feature Classes",lib.cover[cov].description);
+	 fc = select_feature_class(&dummyview,&lib,title,cov);
+	 if (fc < 0) break;
+	 feature_class_dictionary( fc, lib );
+      }
+   }
+
+}
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.c
new file mode 100644
index 0000000000..85f6734351
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.c
@@ -0,0 +1,505 @@
+/*************************************************************************
+ *
+ *N  Module VPFDISP - Display VPF records
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions used to display VPF records in
+ *     human readable format.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(__MINGW32__)
+#  include <dirent.h>
+#  include <malloc.h>
+#  include <mem.h>
+#  include <dos.h>
+#  ifdef __MSDOS__
+#    include <graphics.h>
+#    include <conio.h>
+#    include <dos.h>
+#    include <alloc.h>
+#    include <mem.h>
+#  endif
+#  ifdef _MSC_VER
+#    include <io.h>
+#  endif
+#  ifndef _WIN32
+#    include <unistd.h>
+#  endif
+#  ifdef MACOSX
+#    include <sys/types.h>
+#    include <sys/malloc.h>
+#    define MAXSHORT 255
+#    define MAXLONG  LONG_MAX
+#  else
+#    include <malloc.h>
+#  endif
+#endif
+
+
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#if defined(__CYGWIN__) || defined(MACOSX)|| defined(_WIN32)
+#include "values.h"
+#else
+#include <values.h>
+#endif
+#include "vpftable.h"
+#include "vpfview.h"
+
+#ifdef HAVE_UNISTD_H
+#  if HAVE_UNISTD_H
+#    include <unistd.h>  /* For "access" function. */
+#  endif
+#endif
+
+extern color_type menucolor, menubordercolor, menutextcolor;
+
+#ifndef __MSDOS__
+void strupr2(char* str) {
+  char* s = str;
+  while (*s)
+  {
+	  *s = toupper(*s);
+	  ++s;
+  }
+}
+#endif
+
+
+/*************************************************************************
+ *
+ *N  format_date
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function converts a VPF date value into a string of the
+ *     form  mm/dd/yyyy with time displayed as hh:mm:ss if non-zero.
+ *     'fmtdate' must be a character string with at least 18 bytes
+ *     allocated.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     date     <input>==(date_type) VPF date type value.
+ *     fmtdate <output>==(char *) output formatted date string.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    Sept 1991                     DOS Turbo C
+ *E
+ *************************************************************************/
+void format_date( date_type date, char *fmtdate )
+{
+   char year[8], month[8], day[8], hour[8], min[8], sec[8];
+
+   date[20]='\0';
+   strncpy(year, date, 4);
+   year[4]='\0';
+   strncpy(month, &date[4], 2);
+   month[2]='\0';
+   strncpy(day, &date[6], 2);
+   day[2]='\0';
+   strncpy(hour, &date[8], 2);
+   hour[2]='\0';
+   strncpy(min, &date[10], 2);
+   min[2]='\0';
+   strncpy(sec, &date[12], 2);
+   sec[2]='\0';
+   if ( (strcmp(hour,"00") == 0) && (strcmp(min,"00")==0) &&
+	(strcmp(sec,"00") == 0) )
+      sprintf(fmtdate,"%s/%s/%s",month,day,year);
+   else
+      sprintf(fmtdate,"%s/%s/%s %s:%s:%s",month,day,year,hour,min,sec);
+}
+
+/*************************************************************************
+ *
+ *N  vpf_display_record
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays all of the fields of a particular VPF
+ *     record, including the descriptions of the fields and their
+ *     values.  It accesses the online data dictionary metadata
+ *     contained in the specified Value Description Tables.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    row     <input> == (row_type) vpf table row structure.
+ *    table   <input> == (vpf_table_type) vpf table.
+ *    fp      <input> == (FILE *) pointer to the output file.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    Sept 1991                     DOS Turbo C
+ *E
+ *************************************************************************/
+void vpf_display_record( row_type row,
+			 vpf_table_type table,
+			 FILE *fp )
+{
+   register int i,j;
+   char *buf,*num, path[128], *tablename;
+   char *attr,*val,*descr, vdtpath[128], fmtdate[40];
+   vpf_table_type vdt;
+   row_type vdtrow;
+   int found;
+   long int l, lval, count, *lptr;
+   short int s,sval,*sptr;
+   float f,*fptr;
+   date_type date;
+   int TABLE_ = 1, ATTR_ = 2, VAL_ = 3, DESCR_ = 4;
+
+   num = (char *)vpfmalloc(20*sizeof(char));
+
+   strcpy( vdtpath, "" );
+
+   /* Display all secondary attributes */
+   for (i=0;i<table.nfields;i++) {
+      switch (table.header[i].type) {
+	 case 'T':
+	    buf = (char *)get_table_element(i,row,table,
+					    NULL,&count);
+	    rightjust(buf);
+	    if (strcmp( buf, "" ) != 0) {
+	       fputs(table.header[i].name,fp);
+	       fputs(" - ",fp);
+	       fputs(table.header[i].description,fp);
+	       fputs(": ",fp);
+	       fputs(buf,fp);
+
+
+	       strcpy( path, table.path );
+	       strcat( path, table.header[i].vdt );
+	       if ( (access(path,4)==0) &&
+		    (strcmp(table.header[i].vdt,"") != 0) ) {
+
+		  if (strcmp(vdtpath,path) != 0) {
+		     if (strcmp(vdtpath,"") != 0) {
+			vpf_close_table(&vdt);
+		     }
+		     vdt = vpf_open_table( path, disk, "rb", NULL );
+		  }
+
+		  strcpy( vdtpath, path );
+		  for (j=1;j<=vdt.nrows;j++) {
+		     vdtrow = read_row( j, vdt );
+		     tablename = (char *)get_table_element( TABLE_, vdtrow,
+							 vdt, NULL, &count );
+		     rightjust(tablename);
+		     strupr2(tablename);
+		     attr = (char *)get_table_element( ATTR_, vdtrow, vdt,
+						       NULL, &count );
+		     rightjust(attr);
+		     val = (char *)get_table_element( VAL_, vdtrow, vdt,
+						      NULL, &count );
+		     rightjust(val);
+
+		     found = FALSE;
+		     if ( (strstr(table.name,tablename)) &&
+			  (ossim_strcasecmp(attr,table.header[i].name)==0) &&
+			  (ossim_strcasecmp(val,buf)==0) ) {
+			descr = (char *)get_table_element(DESCR_,vdtrow,vdt,
+							  NULL, &count);
+			rightjust(descr);
+			fputs(" (",fp);
+			fputs(descr,fp);
+			fputs(")",fp);
+
+			free(descr);
+			found = TRUE;
+		     }
+		     free(tablename);
+		     free(attr);
+		     free(val);
+		     free_row( vdtrow, vdt );
+		     if (found) break;
+		  }
+	       }
+
+
+	       fputc('\n',fp);
+	    }
+	    free(buf);
+	    break;
+	 case 'I':
+	    if (table.header[i].count==1) {
+	       get_table_element(i,row,table,&l,&count);
+	       if (l != NULLINT) {
+		  fputs(table.header[i].name,fp);
+		  fputs(" - ",fp);
+		  fputs(table.header[i].description,fp);
+		  fputs(": ",fp);
+		  ltoa((int)l,num,10);
+		  fputs(num,fp);
+
+		  strcpy( path, table.path );
+		  strcat( path, table.header[i].vdt );
+		  if ( (access(path,4)==0) &&
+		     (strcmp(table.header[i].vdt,"") != 0) ) {
+
+		     if (strcmp(vdtpath,path) != 0) {
+			if (strcmp(vdtpath,"") != 0) {
+			   vpf_close_table(&vdt);
+			}
+			vdt = vpf_open_table( path, disk, "rb", NULL );
+		     }
+		     strcpy( vdtpath, path );
+
+		     for (j=1;j<=vdt.nrows;j++) {
+			vdtrow = read_row( j, vdt );
+			tablename = (char *)get_table_element( TABLE_,
+					      vdtrow, vdt, NULL, &count );
+			rightjust(tablename);
+			strupr2(tablename);
+			attr = (char *)get_table_element( ATTR_, vdtrow, vdt,
+							  NULL, &count );
+			rightjust(attr);
+			get_table_element( VAL_, vdtrow, vdt,
+					   &lval, &count );
+
+			found = FALSE;
+			if ( (strstr(table.name,tablename)) &&
+			   (ossim_strcasecmp(attr,table.header[i].name)==0) &&
+			   (lval==l) ) {
+			   descr = (char *)get_table_element(DESCR_,vdtrow,
+							 vdt, NULL, &count);
+			   rightjust(descr);
+			   fputs(" (",fp);
+			   fputs(descr,fp);
+			   fputs(")",fp);
+
+			   free(descr);
+			   found = TRUE;
+			}
+			free(tablename);
+			free(attr);
+			free_row( vdtrow, vdt );
+			if (found) break;
+		     }
+		  }
+
+		  fputc('\n',fp);
+	       }
+	    } else {
+	       get_table_element(i,row,table,&lptr,&count);
+	       fputs(table.header[i].name,fp);
+	       fputs(" - ",fp);
+	       fputs(table.header[i].description,fp);
+	       fputs(": (",fp);
+	       for (j=0;j<count;j++) {
+		  ltoa((int)lptr[j],num,10);
+		  fputs(num,fp);
+		  if (j<count-1) fputs(", ",fp);
+	       }
+	       fputs(")\n",fp);
+	    }
+	    break;
+	 case 'S':
+	    if (table.header[i].count==1) {
+	       get_table_element(i,row,table,&s,&count);
+	       if (s != NULLSHORT) {
+		  fputs(table.header[i].name,fp);
+		  fputs(" - ",fp);
+		  fputs(table.header[i].description,fp);
+		  fputs(": ",fp);
+		  itoa(s,num,10);
+		  fputs(num,fp);
+
+		  strcpy( path, table.path );
+		  strcat( path, table.header[i].vdt );
+		  if ( (access(path,4)==0) &&
+		     (strcmp(table.header[i].vdt,"") != 0) ) {
+
+		     if (strcmp(vdtpath,path) != 0) {
+			if (strcmp(vdtpath,"") != 0) {
+			   vpf_close_table(&vdt);
+			}
+			vdt = vpf_open_table( path, disk, "rb", NULL );
+		     }
+		     strcpy( vdtpath, path );
+
+		     for (j=1;j<=vdt.nrows;j++) {
+			vdtrow = read_row( j, vdt );
+			tablename = (char *)get_table_element( TABLE_,
+					      vdtrow, vdt, NULL, &count );
+			rightjust(tablename);
+			strupr2(tablename);
+			attr = (char *)get_table_element( ATTR_, vdtrow, vdt,
+							  NULL, &count );
+			rightjust(attr);
+			get_table_element( VAL_, vdtrow, vdt,
+					   &sval, &count );
+
+			found = FALSE;
+			if ( (strstr(table.name,tablename)) &&
+			   (ossim_strcasecmp(attr,table.header[i].name)==0) &&
+			   (sval==s) ) {
+			   descr = (char *)get_table_element(DESCR_,vdtrow,
+							 vdt, NULL, &count);
+			   rightjust(descr);
+			   fputs(" (",fp);
+			   fputs(descr,fp);
+			   fputs(")",fp);
+
+			   free(descr);
+			   found = TRUE;
+			}
+			free(tablename);
+			free(attr);
+			free_row( vdtrow, vdt );
+			if (found) break;
+		     }
+		  }
+
+		  fputc('\n',fp);
+	       }
+	    } else {
+	       get_table_element(i,row,table,&sptr,&count);
+	       fputs(table.header[i].name,fp);
+	       fputs(" - ",fp);
+	       fputs(table.header[i].description,fp);
+	       fputs(": (",fp);
+	       for (j=0;j<count;j++) {
+		  itoa(sptr[j],num,10);
+		  fputs(num,fp);
+		  if (j<count-1) fputs(", ",fp);
+	       }
+	       fputs(")\n",fp);
+	    }
+	    break;
+	 case 'F':
+	    if (table.header[i].count==1) {
+	       get_table_element(i,row,table,&f,&count);
+	       if (!is_vpf_null_float(f)) {
+		  fputs(table.header[i].name,fp);
+		  fputs(" - ",fp);
+		  fputs(table.header[i].description,fp);
+		  fputs(": ",fp);
+#if !defined(MACOSX)
+		  gcvt(f,6,num);
+#endif
+		  fputs(num,fp);
+		  fputc('\n',fp);
+	       }
+	    } else {
+	       get_table_element(i,row,table,&fptr,&count);
+	       fputs(table.header[i].name,fp);
+	       fputs(" - ",fp);
+	       fputs(table.header[i].description,fp);
+	       fputs(": (",fp);
+	       for (j=0;j<count;j++) {
+		  if (is_vpf_null_float(fptr[j])) {
+		     fputs("(null)",fp);
+		  } else {
+#if !defined(MACOSX)
+		     gcvt(fptr[j],6,num);
+#endif
+		     fputs(num,fp);
+		  }
+		  if (j<count-1) fputs(", ",fp);
+	       }
+	       fputs(")\n",fp);
+	    }
+	    break;
+	 case 'D':
+	    if (table.header[i].count==1) {
+	       get_table_element(i,row,table,date,&count);
+	       fputs(table.header[i].name,fp);
+	       fputs(" - ",fp);
+	       fputs(table.header[i].description,fp);
+	       fputs(": ",fp);
+	       format_date(date,fmtdate);
+	       fputs(fmtdate,fp);
+	       fputc('\n',fp);
+	    }
+	    break;
+      }
+   }
+
+   if (strcmp(vdtpath,"") != 0)
+      vpf_close_table( &vdt );
+
+   free(num);
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  display_attributes
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays all of the attributes of a particular
+ *     feature, including the descriptions of the fields and their
+ *     values.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    fc      <input> == (int) feature class number.
+ *    row     <input> == (long int) row of the attribute table.
+ *    library <input> == (library_type *) VPF library structure.
+ *    fp      <input> == (FILE *) pointer to the output file.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+void display_attributes( int fc,
+			 long int row,
+			 library_type *library,
+			 FILE *fp )
+{
+   vpf_table_type feature_table;
+   row_type vpfrow;
+
+   feature_table = vpf_open_table(library->fc[fc].table,disk,"rb",NULL);
+
+   vpfrow = read_row( row, feature_table );
+
+   vpf_display_record( vpfrow, feature_table, fp );
+
+   free_row(vpfrow,feature_table);
+
+   vpf_close_table(&feature_table);
+}
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.h b/Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.h
new file mode 100644
index 0000000000..696565545a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfdisp.h
@@ -0,0 +1,31 @@
+
+/*******************/
+/*   vpfdispl.h    */
+/*******************/
+
+#ifndef __vpfdisp_h__
+#define __vpfdisp_h__
+
+#include "vpfview.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void vpf_display_record( row_type row,
+			 vpf_table_type table,
+			 FILE *fp );
+
+
+void display_attributes( int fc,
+			 long int row,
+			 library_type *library,
+			 FILE *fp );
+
+
+void format_date( date_type date, char *fmtdate );
+
+#ifdef __cplusplus
+}
+#endif
+#endif   /* #ifndef __vpfdisp_h__  */
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.c
new file mode 100644
index 0000000000..5e98ed22ac
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.c
@@ -0,0 +1,1620 @@
+/*************************************************************************
+ *
+ *N  Module VPFDRAW - DRAW VPF FEATURES
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions for drawing selected VPF
+ *     features.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Nov 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+
+#include <stdio.h>
+#ifdef __MSDOS__
+#include <io.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#ifdef __MSDOS__
+#include <alloc.h>
+#include <mem.h>
+#endif
+#include <math.h>
+#if defined(__CYGWIN__) || defined(MACOSX) || defined(_WIN32)
+#include "values.h"
+#else
+#include <values.h>
+#endif
+#ifdef __MSDOS__
+#include <graphics.h>
+#endif
+#include "vpftable.h"
+#include "vpfprim.h"
+#include "vpfview.h"
+#ifdef __MSDOS__
+#include "mapgraph.h"
+#include "projectn.h"
+#endif
+#include "polygrf.h"
+#ifdef __MSDOS__
+#include "grprim.h"
+#endif
+#include "vpfrelat.h"
+#include "vpfdraw.h"
+
+
+extern char home[255];
+
+
+typedef struct {
+   float x1,y1,x2,y2;
+} line_segment_type;
+#ifdef __MSDOS__
+/*************************************************************************
+ *
+ *N  draw_edge_coordinates
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws the coordinates of an edge record.
+ *     It tries its darndest to detect and get rid of projection
+ *     "zingers" - lines that dart across the screen because of
+ *     lines projected onto the map that wrap around behind the
+ *     globe or change hemispheres.  The ability to handle these
+ *     projection artifacts is what turns what should be a very
+ *     simple function into a very ugly piece of code.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     edge_rec <input>==(edge_rec_type *) pointer to an edge record.
+ *     return  <output>==(int) 0 if the user escapes, 1 upon successful
+ *                          completion.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Feb 1992                           DOS Turbo C
+ *E
+ *************************************************************************/
+int draw_edge_coordinates( edge_rec_type *edge_rec )
+{
+   int xscr,yscr, xprev,yprev, x1,y1,x2,y2, mbrx2, wrap;
+   register long int i;
+   extent_type mbr;
+   coordinate_type coord;
+
+/* First compute the MBR from the coordinates. */
+   coord = first_edge_coordinate(edge_rec);
+   mbr.x1 = coord.x;
+   mbr.y1 = coord.y;
+   mbr.x2 = coord.x;
+   mbr.y2 = coord.y;
+   for (i=1;i<edge_rec->npts;i++) {
+      coord = next_edge_coordinate(edge_rec);
+      if (coord.x < mbr.x1) mbr.x1 = coord.x;
+      if (coord.y < mbr.y1) mbr.y1 = coord.y;
+      if (coord.x > mbr.x2) mbr.x2 = coord.x;
+      if (coord.y > mbr.y2) mbr.y2 = coord.y;
+   }
+   screen_bounds(mbr.x1,mbr.y1,mbr.x2,mbr.y2,&x1,&y1,&x2,&y2);
+
+   if ( (x1 < 0 && x2 < 0) || (x1 > gpgetmaxx() && x2 > gpgetmaxx()) ||
+	(y1 < 0 && y2 < 0) || (y1 > gpgetmaxy() && y2 > gpgetmaxy()) )
+      return 1;
+   if (x1 > gpgetmaxx() && x2 < 0) return 1;
+
+   wrap = 0;
+   mbrx2 = x2;
+   if (x2 < x1) {
+      /* The box wraps around the screen */
+      /* (or at least wraps off the edge of the screen) */
+      wrap = gpgetmaxx();
+      if (x2 < 0) wrap -= x2;
+      /* Adjust the maximum screen value */
+      x2 += wrap;
+   }
+
+   coord = first_edge_coordinate(edge_rec);
+   screenxy(coord.x,coord.y,&xscr,&yscr);
+   if (wrap && xscr < x1) xscr += wrap;
+   gpmoveto(xscr,yscr);
+   xprev = xscr;
+   yprev = yscr;
+   for (i=1;i<edge_rec->npts;i++) {
+      coord = next_edge_coordinate(edge_rec);
+      screenxy(coord.x,coord.y,&xscr,&yscr);
+      if (xscr == MAXINT || yscr == MAXINT) {
+	 xprev = xscr;
+	 yprev = yscr;
+	 continue;
+      }
+
+      if (wrap && xscr < x1) xscr += wrap;
+
+      if (xscr==xprev && yscr==yprev) continue;
+
+      if (xprev == MAXINT || yprev == MAXINT) gpmoveto(xscr,yscr);
+
+      hidemousecursor();
+      gplineto( xscr, yscr );
+      showmousecursor();
+
+      xprev = xscr;
+      yprev = yscr;
+
+      while (kbhit()) {
+	 if (getch()==27) {
+	    return 0;
+	 }
+      }
+
+   }
+
+   if (wrap && mbrx2 > 0) {
+      /* The edge wraps around and is displayed on the other */
+      /* edge of the screen. */
+      x2 -= wrap;
+
+      coord = first_edge_coordinate(edge_rec);
+      screenxy(coord.x,coord.y,&xscr,&yscr);
+      if (xscr > x2) xscr -= wrap;
+      gpmoveto(xscr,yscr);
+      xprev = xscr;
+      yprev = yscr;
+      for (i=1;i<edge_rec->npts;i++) {
+	 coord = next_edge_coordinate(edge_rec);
+	 screenxy(coord.x,coord.y,&xscr,&yscr);
+	 if (xscr == MAXINT || yscr == MAXINT) {
+	    xprev = xscr;
+	    yprev = yscr;
+	    continue;
+	 }
+
+	 if (xscr > x2) xscr -= wrap;
+
+	 if (xscr==xprev && yscr==yprev) continue;
+
+	 if (xprev == MAXINT || yprev == MAXINT) gpmoveto(xscr,yscr);
+
+	 hidemousecursor();
+	 gplineto( xscr, yscr );
+	 showmousecursor();
+
+	 xprev = xscr;
+	 yprev = yscr;
+
+	 while (kbhit()) {
+	    if (getch()==27) {
+	       return 0;
+	    }
+	 }
+      }
+   }
+
+   return 1;
+}
+
+
+/*************************************************************************
+ *
+ *N  draw_edge_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws the selected edge for a given row in
+ *     the edge primitive table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     row      <input>==(row_type)row in the edge primitive table.
+ *     table    <input>==(vpf_table_type) edge table.
+ *     return  <output>==(int) 0 if the user escapes, 1 upon successful
+ *                          completion.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   August 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int draw_edge_row( row_type row, vpf_table_type table )
+{
+   edge_rec_type edge_rec;
+   int stat;
+
+   edge_rec = create_edge_rec(row,table);
+
+   stat = draw_edge_coordinates(&edge_rec);
+
+   if (edge_rec.coord) free(edge_rec.coord);
+
+   gpstroke();
+
+   while (kbhit()) {
+      if (getch()==27) {
+	 return 0;
+      }
+   }
+
+   return stat;
+}
+
+
+/*************************************************************************
+ *
+ *N  draw_edge
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws the selected edge for a given row number in
+ *     the edge primitive table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     rownum   <input>==(long int)row number of the edge primitive table.
+ *     table    <input>==(vpf_table_type) edge table.
+ *     return  <output>==(int) 0 if the user escapes, 1 upon successful
+ *                          completion.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   August 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int draw_edge( long int rownum, vpf_table_type table )
+{
+   int stat;
+   row_type row;
+
+   row = get_row( rownum, table );
+   stat = draw_edge_row(row,table);
+   free_row(row,table);
+   return stat;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  draw_point_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws an entity node for the row in the given
+ *     entity node primitive table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     row         <input>==(row_type) row of the entity node
+ *                          primitive table.
+ *     table       <input>==(vpf_table_type) entity node primitive table.
+ *     return     <output>==(int) 0 if the user escapes, 1 upon successful
+ *                          completion.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   August 1991                        DOS Turbo C
+ *E
+ *************************************************************************/
+int draw_point_row( row_type row, vpf_table_type table )
+{
+   int xscr,yscr, coord_pos;
+   long int n;
+   coordinate_type pnt;
+
+   coord_pos = table_pos("COORDINATE",table);
+   get_table_element(coord_pos,row,table,&pnt,&n);
+
+   screenxy(pnt.x,pnt.y,&xscr,&yscr);
+   hidemousecursor();
+   gpmarker(xscr,yscr);
+   showmousecursor();
+
+   while (kbhit()) {
+      if (getch()==27) {
+	 return 0;
+      }
+   }
+
+   return 1;
+}
+
+/*************************************************************************
+ *
+ *N  draw_point
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws an entity node for the row number of the given
+ *     entity node primitive table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     rownum      <input>==(long int) row number of the entity node
+ *                          primitive table.
+ *     table       <input>==(vpf_table_type) entity noe primitive table.
+ *     return     <output>==(int) 0 if the user escapes, 1 upon successful
+ *                          completion.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   August 1991                        DOS Turbo C
+ *E
+ *************************************************************************/
+int draw_point( long int rownum, vpf_table_type table )
+{
+   int stat;
+   row_type row;
+
+   row = get_row( rownum, table );
+   stat = draw_point_row(row,table);
+   free_row(row,table);
+   return stat;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  draw_text_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws annotation for a given row in the text
+ *     pseudo-primitive table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     row         <input>==(row_type) row of the text table.
+ *     table       <input>==(vpf_table_type) text primitive table.
+ *     return     <output>==(int) 0 if the user escapes, 1 upon successful
+ *                          completion.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   August 1991                        DOS Turbo C
+ *E
+ *************************************************************************/
+int draw_text_row( row_type row, vpf_table_type table )
+{
+   int xscr,yscr, shape_pos, text_pos;
+   long int n, nshape;
+   coordinate_type *shape_line;
+   char *text;
+   struct viewporttype vp;
+
+   shape_pos = table_pos("SHAPE_LINE",table);
+/**** MUST CHECK FOR 'Z', 'B', AND 'Y' TYPES - SEE VPFPRIM.C ****/
+   shape_line = (coordinate_type *)get_table_element(shape_pos,row,table,
+						     NULL,&nshape);
+   text_pos = table_pos("STRING",table);
+   text = (char *)get_table_element(text_pos,row,table,NULL,&n);
+
+   screenxy(shape_line[0].x,shape_line[0].y,&xscr,&yscr);
+
+   getviewsettings(&vp);
+   if ((gpgetfont() != DEFAULT_FONT) || (yscr > gptextheight(text))) {
+      hidemousecursor();
+      gptext(xscr,yscr,text);
+      showmousecursor();
+   }
+
+   free(shape_line);
+   free(text);
+
+   while (kbhit()) {
+      if (getch()==27) {
+	 return 0;
+      }
+   }
+
+   return 1;
+}
+
+/*************************************************************************
+ *
+ *N  draw_text
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws annotation for a given row number in the text
+ *     pseudo-primitive table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     rownum      <input>==(long int) row number of the text table.
+ *     table       <input>==(vpf_table_type) text primitive table.
+ *     return     <output>==(int) 0 if the user escapes, 1 upon successful
+ *                          completion.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   August 1991                        DOS Turbo C
+ *E
+ *************************************************************************/
+int draw_text( long int rownum, vpf_table_type table )
+{
+   int stat;
+   row_type row;
+
+   row = get_row( rownum, table );
+   stat = draw_text_row(row,table);
+   free_row(row,table);
+   return stat;
+}
+
+
+
+static IPoint make_ipoint( int x, int y )
+{
+   IPoint point;
+
+   point.x = x;
+   point.y = y;
+   return point;
+}
+
+static IBox make_ibox( int x1, int y1, int x2, int y2 )
+{
+   IBox box;
+
+   if (x1 < x2)
+      box.origin.x = x1;
+   else
+      box.origin.x = x2;
+   if (y1 < y2)
+      box.origin.y = y1;
+   else
+      box.origin.y = y2;
+   box.delta.x = abs(x2-x1);
+   box.delta.y = abs(y2-y1);
+   return box;
+}
+
+
+/*************************************************************************
+ *
+ *N  screen_bounds
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines the screen bounds of a rectangular
+ *     map area, independent of any projection that may distort the
+ *     boundaries.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     x1    <input>==(double) lower left x map coordinate.
+ *     y1    <input>==(double) lower left y map coordinate.
+ *     x2    <input>==(double) upper right x map coordinate.
+ *     y2    <input>==(double) upper right y map coordinate.
+ *     xmin <output>==(int *) lower left x screen coordinate.
+ *     ymin <output>==(int *) lower left y screen coordinate.
+ *     xmax <output>==(int *) upper right x screen coordinate.
+ *     ymax <output>==(int *) upper right y screen coordinate.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void screen_bounds( double x1, double y1, double x2, double y2,
+		    int *xmin, int *ymin, int *xmax, int *ymax )
+{
+   int xscr,yscr;
+   double xc,yc;        /* x center and y center */
+
+   xc = (x1+x2)/2.0;
+   yc = (y1+y2)/2.0;
+
+   /* Find xmin from x1 */
+   screenxy(x1,y1,&xscr,&yscr);
+   *xmin = xscr;
+   screenxy(x1,yc,&xscr,&yscr);
+   if (xscr < (*xmin)) *xmin = xscr;
+   screenxy(x1,y2,&xscr,&yscr);
+   if (xscr < (*xmin)) *xmin = xscr;
+
+   /* Find xmax from x2 */
+   screenxy(x2,y2,&xscr,&yscr);
+   *xmax = xscr;
+   screenxy(x2,yc,&xscr,&yscr);
+   if (xscr > (*xmax)) *xmax = xscr;
+   screenxy(x2,y1,&xscr,&yscr);
+   if (xscr > (*xmax)) *xmax = xscr;
+
+   /* Find ymin from y2 (seems backwards - but so is the screen) */
+   screenxy(x1,y2,&xscr,&yscr);
+   *ymin = yscr;
+   screenxy(xc,y2,&xscr,&yscr);
+   if (yscr < (*ymin)) *ymin = yscr;
+   screenxy(x2,y2,&xscr,&yscr);
+   if (yscr < (*ymin)) *ymin = yscr;
+
+   /* Find ymax from y1 */
+   screenxy(x1,y1,&xscr,&yscr);
+   *ymax = yscr;
+   screenxy(xc,y1,&xscr,&yscr);
+   if (yscr > (*ymax)) *ymax = yscr;
+   screenxy(x2,y1,&xscr,&yscr);
+   if (yscr > (*ymax)) *ymax = yscr;
+
+}
+
+
+/*************************************************************************
+ *
+ *N  gen_polygon_edge
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function generates a polygon edge in the Shademap structure
+ *     given an edge record structure.
+ *     It is complicated by having to check whether this polygon
+ *     has wrapped around the screen from the projection and adjusting
+ *     the coordinates, if so.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     edge_rec <input>==(edge_rec_type) input edge record.
+ *     poly     <inout>==(Shademap *) polygon structure being updated.
+ *     wrap     <input>==(int) amount of wrap around if the polygon
+ *                        wraps around the screen.  If this number
+ *                        is positive, the coordinates will be
+ *                        adjusted out to the right.  If negative,
+ *                        they will adjusted to the left.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void gen_polygon_edge( edge_rec_type edge_rec,
+		       Shademap *poly,
+		       int wrap )
+{
+   register long int i,start,end,inc;
+   int xscr,yscr;
+   IPoint pnt, make_ipoint();
+   coordinate_type coord;
+
+   if (edge_rec.left == edge_rec.right) return;
+
+   if (edge_rec.dir == '-') {
+      start = edge_rec.npts-1;
+      end = 0;
+      inc = -1;
+   } else {
+      start = 0;
+      end = edge_rec.npts-1;
+      inc = 1;
+   }
+   for (i=start;i!=end;i+=inc) {
+      coord = get_edge_coordinate(i,&edge_rec);
+      screenxy(coord.x,coord.y,&xscr,&yscr);
+
+      if (wrap > 0 && xscr < poly->bounding.origin.x)
+	 xscr += wrap;
+
+      if (wrap < 0 &&
+	  xscr > poly->bounding.origin.x+poly->bounding.delta.x)
+	 xscr += wrap;
+
+      pnt = make_ipoint(xscr,yscr);
+      gpwriteshade( poly, pnt );
+   }
+   coord = get_edge_coordinate(i,&edge_rec);
+   screenxy(coord.x,coord.y,&xscr,&yscr);
+
+   if (wrap > 0 && xscr < poly->bounding.origin.x)
+      xscr += wrap;
+
+   if (wrap < 0 &&
+       xscr > poly->bounding.origin.x+poly->bounding.delta.x)
+      xscr += wrap;
+
+   pnt = make_ipoint(xscr,yscr);
+   gpwriteshade( poly, pnt );
+}
+
+
+/*************************************************************************
+ *
+ *N  draw_polygon_edge
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws an edge of a polygon.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     edge_rec <input>==(edge_rec_type) input edge record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void draw_polygon_edge( edge_rec_type edge_rec )
+{
+   if (edge_rec.left == edge_rec.right) return;
+   draw_edge_coordinates(&edge_rec);
+}
+
+
+
+#ifdef TRACE
+/*************************************************************************
+ *
+ *N  trace_polygon_loop
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function traces a loop (or ring) of a polygon by chaining
+ *     through the right and/or left edges of the edge table, including
+ *     tracing through all dangles.  This is winged-edge topology in action.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     face_id    <input>==(long int) row id of the specified face.
+ *     start_edge <input>==(long int) row id of the edge that starts the
+ *                         loop.
+ *     edgetable  <input>==(vpf_table_type) VPF edge primitive table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void trace_polygon_loop(long int face_id,
+			long int start_edge,
+			vpf_table_type edgetable )
+{
+  edge_rec_type edge_rec;
+  long int next, prevnode;
+  boolean done=FALSE;
+  IPoint make_ipoint();
+
+  edge_rec = read_edge( start_edge, edgetable );
+
+#ifdef WATCH
+   gotoxy(1,17);
+   printf("edge: %5ld  left: %5ld  edge:%5ld  right: %5ld  edge: %5ld",
+	  edge_rec.id,edge_rec.left,edge_rec.leftfwd,edge_rec.right,
+	  edge_rec.rightfwd);
+#endif
+#ifdef STEP
+   getch();
+#endif
+
+  edge_rec.dir = '+';
+
+  prevnode = edge_rec.start;
+
+  if (edge_rec.start != edge_rec.end) {
+
+     if ( (edge_rec.right == face_id) && (edge_rec.left == face_id) ) {
+	/* Dangle */
+	if (prevnode == edge_rec.start) {
+	   edge_rec.dir = '+';
+	   next = edge_rec.rightfwd;
+	   prevnode = edge_rec.end;
+	} else if (prevnode == edge_rec.end) {
+	   edge_rec.dir = '-';
+	   next = edge_rec.leftfwd;
+	   prevnode = edge_rec.start;
+	} else next = -1;
+     } else if (edge_rec.right == face_id) {
+	next = edge_rec.rightfwd;
+	edge_rec.dir = '+';
+	prevnode = edge_rec.end;
+     } else if (edge_rec.left == face_id) {
+	next = edge_rec.leftfwd;
+	edge_rec.dir = '-';
+	prevnode = edge_rec.start;
+     } else next = -1;
+
+  } else {
+
+     done = TRUE;
+
+  }
+
+  draw_polygon_edge( edge_rec );
+
+  if (edge_rec.coord) free(edge_rec.coord);
+
+  while (!done) {
+
+     if (next < 0) {
+#ifdef WATCH
+	gotoxy(1,18);
+	printf(" Aaargh(r)! Edge: %ld   face: %ld   left: %ld   right: %ld",
+		edge_rec.id,face_id,edge_rec.left,edge_rec.right);
+	getch();
+	gotoxy(1,18);
+	printf("                                                                                ");
+#endif
+	done = TRUE;
+     }
+
+     if (next==0) {
+#ifdef WATCH
+	gotoxy(1,19);
+	printf("Next edge(%d) = 0  ",edge_rec.id);
+#endif
+	done = TRUE;
+     }
+
+     if (next == start_edge) done = TRUE;
+
+     if (!done) {
+
+	edge_rec = read_edge( next, edgetable );
+
+#ifdef WATCH
+	gotoxy(1,17);
+	printf("edge: %5ld  left: %5ld  edge:%5ld  right: %5ld  edge: %5ld",
+	       next,edge_rec.left,edge_rec.leftfwd,edge_rec.right,
+	       edge_rec.rightfwd);
+	gotoxy(1,18);
+	printf("node: %5ld  start: %5ld  end: %5ld",
+	prevnode,edge_rec.start,edge_rec.end);
+#endif
+#ifdef STEP
+	getch();
+#endif
+
+	if ( (edge_rec.right == face_id) && (edge_rec.left == face_id) ) {
+	   /* Dangle */
+	   if (prevnode == edge_rec.start) {
+	      edge_rec.dir = '+';
+	      next = edge_rec.rightfwd;
+	      prevnode = edge_rec.end;
+	   } else if (prevnode == edge_rec.end) {
+	      edge_rec.dir = '-';
+	      next = edge_rec.leftfwd;
+	      prevnode = edge_rec.start;
+	   } else next = -1;
+	} else if (edge_rec.right == face_id) {
+	   edge_rec.dir = '+';
+	   next = edge_rec.rightfwd;
+	   prevnode = edge_rec.end;
+	} else if (edge_rec.left == face_id) {
+	   edge_rec.dir = '-';
+	   next = edge_rec.leftfwd;
+	   prevnode = edge_rec.start;
+	} else next = -1;
+
+	draw_polygon_edge( edge_rec );
+	if (edge_rec.coord) free(edge_rec.coord);
+
+     }
+  }
+
+}
+#endif
+
+#endif
+/*************************************************************************
+ *
+ *N  next_polygon_edge
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines the next polygon edge id for a specified
+ *     face from the given edge record and face id.  It follows the rules
+ *     of winged-edge topology.  It does not follow the network through
+ *     dangles (see trace_polygon_loop above).  It skips over them to
+ *     stay along the ring boundary.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     edge_rec   <input>==(edge_rec_type *) VPF edge record.
+ *     prev_node  <inout>==(long int *) the previous node visited.  This
+ *                         value is updated by this function.
+ *     face_id    <input>==(long int) row id of the specified face.
+ *     next_polygon_edge <output>==(long int) the next edge id.  A value of -1
+ *                         indicates a topology error.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+long int next_polygon_edge( edge_rec_type *edge_rec, long int *prevnode,
+			    long int face_id )
+{
+   long int next;
+
+   if ( (edge_rec->right == face_id) && (edge_rec->left == face_id) ) {
+      /* Dangle - go the opposite direction to continue along the boundary */
+      if (*prevnode == edge_rec->start) {
+	 edge_rec->dir = '-';
+	 next = edge_rec->leftfwd;
+	 *prevnode = edge_rec->start;
+      } else if (*prevnode == edge_rec->end) {
+	 edge_rec->dir = '+';
+	 next = edge_rec->rightfwd;
+	 *prevnode = edge_rec->end;
+      } else next = -1;
+   } else if (edge_rec->right == face_id) {
+      /* The face is on the right - take the right forward edge */
+      next = edge_rec->rightfwd;
+      edge_rec->dir = '+';
+      *prevnode = edge_rec->end;
+   } else if (edge_rec->left == face_id) {
+      /* The face is on the left - take the left forward edge */
+      next = edge_rec->leftfwd;
+      edge_rec->dir = '-';
+      *prevnode = edge_rec->start;
+   } else next = -1;
+
+   return next;
+}
+
+#ifdef __MSDOS__
+/*************************************************************************
+ *
+ *N  draw_polygon_loop
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws a loop (or ring) of a polygon by chaining
+ *     through the right and/or left edges of the edge table.  Dangles
+ *     are skipped to stay along the outer boundary.
+ *     This is a good example of winged-edge topology.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     face_id    <input>==(long int) row id of the specified face.
+ *     start_edge <input>==(long int) row id of the edge that starts the
+ *                         loop.
+ *     edgetable  <input>==(vpf_table_type) VPF edge primitive table.
+ *     poly       <inout>==(Shademap *) polygon shade structure.
+ *     wrap       <input>==(int) wrap around if the polygon wraps
+ *                         around the screen.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void draw_polygon_loop(long int face_id,
+		       long int start_edge,
+		       vpf_table_type edgetable,
+		       Shademap *poly,
+		       int wrap )
+{
+  edge_rec_type edge_rec;
+  long int next, prevnode;
+  boolean done=FALSE;
+  IPoint make_ipoint();
+  int xscr,yscr, color;
+  coordinate_type coord;
+
+  edge_rec = read_edge( start_edge, edgetable );
+
+  edge_rec.dir = '+';
+
+  prevnode = edge_rec.start;
+
+  if (edge_rec.start != edge_rec.end) {
+
+     next = next_polygon_edge( &edge_rec, &prevnode, face_id );
+
+  } else {
+
+     done = TRUE;
+
+  }
+
+  gpgetlinecolor(&color);
+  if (gpgetdevice()==SCREEN && color>=0)
+     draw_polygon_edge( edge_rec );
+
+  if (edge_rec.dir == '-')
+     coord = get_edge_coordinate(edge_rec.npts-1,&edge_rec);
+  else
+     coord = get_edge_coordinate(0,&edge_rec);
+  screenxy(coord.x,coord.y,&xscr,&yscr);
+  gpmoveto(xscr,yscr);
+
+  gen_polygon_edge( edge_rec, poly, wrap );
+
+  if (edge_rec.coord) free(edge_rec.coord);
+
+  while (!done) {
+
+     if (next < 0) {
+	gotoxy(1,18);
+	printf(" VPF topology error! Edge: %ld   face: %ld   left: %ld   right: %ld",
+		edge_rec.id,face_id,edge_rec.left,edge_rec.right);
+	getch();
+	gotoxy(1,18);
+	printf("                                                                                ");
+	done = TRUE;
+     }
+
+     if (next==0) {
+	gotoxy(1,19);
+	printf("Next edge(%d) = 0  ",edge_rec.id);
+	done = TRUE;
+     }
+
+     if (next == start_edge) done = TRUE;
+
+     if (!done) {
+
+	edge_rec = read_edge( next, edgetable );
+
+	next = next_polygon_edge( &edge_rec, &prevnode, face_id );
+
+	if (gpgetdevice() == SCREEN && color>=0)
+	   draw_polygon_edge( edge_rec );
+
+	gen_polygon_edge( edge_rec, poly, wrap );
+	if (edge_rec.coord) free(edge_rec.coord);
+
+     }
+  }
+
+}
+
+
+
+/*************************************************************************
+ *
+ *N  draw_polygon
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws a polygon for VPF face structure tables.
+ *     It is complicated by the fact that it checks to see whether
+ *     enough memory is available to draw the entire polygon in a
+ *     Shademap structure, or whether the face must be broken up into
+ *     smaller chunks so the bit arrays can fit into memory.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    mbrx1      <input> == (int) mbr corner 1 x coordinate.
+ *    mbry1      <input> == (int) mbr corner 1 y coordinate.
+ *    mbrx2      <input> == (int) mbr corner 2 x coordinate.
+ *    mbry2      <input> == (int) mbr corner 2 y coordinate.
+ *    face_rec   <input> == (face_rec_type)
+ *    ringtable  <input> == (vpf_table_type) VPF ring table.
+ *    edgetable  <input> == (vpf_table_type) VPF edge table.
+ *    outline    <input> == (color_type) polygon outline color.
+ *    pattern    <input> == (Pattern) polygon fill pattern.
+ *    wrap       <input> == (int) wrap around if the polygon wraps around
+ *                          the screen.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void draw_polygon( int mbrx1, int mbry1, int mbrx2, int mbry2,
+		   face_rec_type face_rec,
+		   vpf_table_type ringtable,
+		   vpf_table_type edgetable,
+		   color_type outline,
+		   Pattern pattern,
+		   int wrap )
+{
+   int  x1,y1,x2,y2,  nchunks,chunk,delta, ok, k;
+   Shademap *poly;
+   IBox     bounding,wdw,make_ibox();
+   ring_rec_type ring_rec;
+
+   x1 = mbrx1-2; y1 = mbry1-2; x2 = mbrx2+2; y2 = mbry2+2;
+   delta = x2-x1;
+
+   nchunks=1;
+
+   wdw = make_ibox(0,0,gpgetmaxx()+1,gpgetmaxy());
+   bounding = make_ibox(x1,y1,x2,y2);
+   poly = OpenShade( bounding, wdw, outline, pattern);
+   if (!poly) return;
+
+   if (gpgetdevice() == SCREEN) {
+/*      wdw = make_ibox(0,0,getmaxx()+1,getmaxy());
+      bounding = make_ibox(x1,y1,x2,y2);
+      poly = OpenShade( bounding, wdw, outline, pattern);
+      if (!poly) return;  */
+      ok = TRUE;
+      if (!poly->Bordermap.array || !poly->Maskmap.array) {
+	 /* Not enough memory - Split polygon up */
+	 if (poly->Bordermap.array) FreeArrayOfBits(poly->Bordermap);
+	 if (poly->Maskmap.array) FreeArrayOfBits(poly->Maskmap);
+	 free(poly);
+	 poly = (Shademap *)NULL;
+	 k = 2;
+	 delta = gpgetmaxx()/k;
+	 nchunks = (mbrx2-mbrx1)/delta + 1;
+	 ok = FALSE;
+	 while (!ok) {
+	    ok = TRUE;
+	    bounding = make_ibox(0,y1,delta,y2);
+	    poly = OpenShade( bounding, wdw, outline, pattern);
+	    if (!poly) return;
+	    if (!poly->Bordermap.array || !poly->Maskmap.array) {
+	       ok = FALSE;
+	       if (poly->Bordermap.array) FreeArrayOfBits(poly->Bordermap);
+	       if (poly->Maskmap.array) FreeArrayOfBits(poly->Maskmap);
+	       free(poly);
+	       k++;
+	       delta = gpgetmaxx()/k;
+	       if (delta < 5) return;
+	       nchunks = (mbrx2-mbrx1)/delta + 1;
+	    } else {
+	       FreeArrayOfBits(poly->Bordermap);
+	       FreeArrayOfBits(poly->Maskmap);
+	       free(poly);
+	       poly = (Shademap *)NULL;
+	    }
+	 }
+	 x2 = x1 + delta;
+	 bounding = make_ibox(x1,y1,x2,y2);
+	 poly = OpenShade(bounding,wdw,outline,pattern);
+      }
+   }
+
+   for (chunk=0;chunk<nchunks;chunk++) {
+
+      ring_rec = read_ring( face_rec.ring, ringtable );
+
+      draw_polygon_loop( face_rec.id, ring_rec.edge, edgetable, poly,
+			 wrap );
+      gpcloseloop(poly);
+
+      while (ring_rec.face == face_rec.id ) {
+	 ring_rec = read_next_ring( ringtable );
+
+	 if (feof(ringtable.fp)) {
+	    gpcloseloop(poly);
+	    break;
+	 }
+
+	 if (ring_rec.face == face_rec.id) {
+
+	    draw_polygon_loop( face_rec.id, ring_rec.edge, edgetable,
+			       poly, wrap );
+	    gpcloseloop(poly);
+
+	 }
+      }
+      hidemousecursor();
+      gpfillpoly(poly);
+      showmousecursor();
+
+      if (gpgetdevice()==SCREEN) {
+	 poly = (Shademap *)NULL;
+	 if (x2 < mbrx2 && chunk < (nchunks)) {
+	    x1 = x2;
+	    x2 += delta;
+	    bounding = make_ibox(x1,y1,x2,y2);
+	    poly = OpenShade(bounding,wdw,outline,pattern);
+	 }
+      }
+   }
+
+   if (poly) {
+      if (gpgetdevice()==SCREEN)
+	 CloseShade(poly);
+      else {
+	 FreeArrayOfBits(poly->Bordermap);
+	 FreeArrayOfBits(poly->Maskmap);
+	 free(poly);
+      }
+   }
+
+}
+
+/*************************************************************************
+ *
+ *N  draw_face_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws the specified face from the given row of
+ *     the given face table.
+ *     It is complicated by the fact that it checks to see whether a
+ *     face has wrapped around the screen due to projection effects.
+ *     If so, it first adjusts the coordinates off the right edge of the
+ *     screen to fill that portion of the face.  Then, if the face
+ *     wraps around to the other edge of the screen, it adjusts the
+ *     coordinates to the left edge of the screen and refills to
+ *     display that portion of the face.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     row       <input>==(row_type) row of the specified face table.
+ *     facetable <input>==(vpf_table_type) VPF face primitive table.
+ *     ringtable <input>==(vpf_table_type) VPF ring primitive table.
+ *     edgetable <input>==(vpf_table_type) VPF edge primitive table.
+ *     fbr       <input>==(vpf_table_type) VPF face bounding rectangle table.
+ *     outline   <input>==(color_type) outline color.
+ *     c1        <input>==(color_type) 1st color in the fill pattern.
+ *     c2        <input>==(color_type) 2nd color in the fill pattern.
+ *     c3        <input>==(color_type) 3rd color in the fill pattern.
+ *     c4        <input>==(color_type) 4th color in the fill pattern.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void draw_face_row( row_type row,
+		vpf_table_type facetable,
+		vpf_table_type ringtable,
+		vpf_table_type edgetable,
+		vpf_table_type fbr,
+		color_type outline,
+		color_type c1,
+		color_type c2,
+		color_type c3,
+		color_type c4 )
+{
+   long int count;
+   int  spx1,spy1,spx2,spy2,  rowid,ring;
+   extent_type shade_box;
+   Pattern  pattern;
+   face_rec_type face_rec;
+   int wrap, mbrx2;
+   row_type fbrrow;
+   int XMIN_,YMIN_,XMAX_,YMAX_;
+
+   rowid = table_pos( "ID", facetable );
+   ring = table_pos( "RING_PTR", facetable );
+   get_table_element( rowid, row, facetable, &(face_rec.id), &count );
+   get_table_element( ring, row, facetable, &(face_rec.ring), &count );
+
+   gpsetlinecolor(outline);
+   gpsetlinestyle(SOLID_LINE);
+   gpsetlinewidth(NORM_WIDTH);
+
+   wrap = 0;
+
+   if (gpgetdevice()==SCREEN) {
+      pattern = MakePattern(c1,c2,c3,c4);
+
+      /* Read bounding box */
+      fbrrow = read_row( face_rec.id, fbr );
+      XMIN_ = table_pos( "XMIN", fbr );
+      YMIN_ = table_pos( "YMIN", fbr );
+      XMAX_ = table_pos( "XMAX", fbr );
+      YMAX_ = table_pos( "YMAX", fbr );
+      get_table_element(XMIN_,fbrrow,fbr,&shade_box.x1,&count);
+      get_table_element(YMIN_,fbrrow,fbr,&shade_box.y1,&count);
+      get_table_element(XMAX_,fbrrow,fbr,&shade_box.x2,&count);
+      get_table_element(YMAX_,fbrrow,fbr,&shade_box.y2,&count);
+      free_row(fbrrow,fbr);
+
+      screen_bounds(shade_box.x1,shade_box.y1,
+		 shade_box.x2,shade_box.y2,
+		 &spx1,&spy1,&spx2,&spy2);
+      mbrx2 = spx2;
+      if (spx2<spx1) {
+	 /* The face wraps around the screen */
+	 /* (or at least wraps off the edge of the screen) */
+	 wrap = gpgetmaxx();
+	 if (spx2 < 0) wrap -= spx2;
+	 /* Adjust the maximum screen value */
+	 spx2 += wrap;
+      }
+
+   } else {
+      gpstartpoly();
+   }
+
+   draw_polygon( spx1,spy1,spx2,spy2, face_rec, ringtable,
+		 edgetable, outline, pattern, wrap );
+
+   if (wrap && mbrx2 > 0) {
+      /* The polygon has wrapped around to the other side of the */
+      /* screen.  Must redraw the part left off on the first pass. */
+
+      if (gpgetdevice()==SCREEN) {
+
+	 spx1 -= wrap;
+	 spx2 -= wrap;
+
+      } else {
+	 gpstartpoly();
+      }
+
+      wrap *= -1;
+      draw_polygon( spx1,spy1,spx2,spy2, face_rec, ringtable,
+		    edgetable, outline, pattern, wrap );
+
+   }
+
+}
+
+
+/*************************************************************************
+ *
+ *N  draw_face
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function draws the specified face from the given face table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     row_num   <input>==(long int) row id of the specified face.
+ *     facetable <input>==(vpf_table_type) VPF face primitive table.
+ *     ringtable <input>==(vpf_table_type) VPF ring primitive table.
+ *     edgetable <input>==(vpf_table_type) VPF edge primitive table.
+ *     fbr       <input>==(vpf_table_type) VPF face bounding rectangle table.
+ *     outline   <input>==(color_type) outline color.
+ *     c1        <input>==(color_type) 1st color in the fill pattern.
+ *     c2        <input>==(color_type) 2nd color in the fill pattern.
+ *     c3        <input>==(color_type) 3rd color in the fill pattern.
+ *     c4        <input>==(color_type) 4th color in the fill pattern.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void draw_face( long int rownum,
+		vpf_table_type facetable,
+		vpf_table_type ringtable,
+		vpf_table_type edgetable,
+		vpf_table_type fbr,
+		color_type outline,
+		color_type c1,
+		color_type c2,
+		color_type c3,
+		color_type c4 )
+{
+   row_type row;
+
+   row = get_row( rownum, facetable );
+   draw_face_row(row,facetable, ringtable, edgetable, fbr,
+		 outline,c1,c2,c3,c4);
+   free_row(row,facetable);
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  outline_polygon_loop
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function outlines a loop (or ring) of a polygon by chaining
+ *     through the right forward and/or left forward edges of the edge
+ *     table.  It does not fill a polygon.
+ *
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     face_id    <input>==(long int) row id of the specified face.
+ *     start_edge <input>==(long int) row id of the edge that starts the
+ *                         loop.
+ *     edgetable <input>==(vpf_table_type) VPF edge primitive table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void outline_polygon_loop(long int face_id,
+			  long int start_edge,
+			  vpf_table_type edgetable)
+{
+  edge_rec_type edge_rec;
+  long int next, prevnode;
+  boolean done=FALSE;
+  IPoint make_ipoint();
+
+  edge_rec = read_edge( start_edge, edgetable );
+
+  edge_rec.dir = '+';
+
+  prevnode = edge_rec.start;
+
+  if (edge_rec.start != edge_rec.end) {
+
+     next = next_polygon_edge( &edge_rec, &prevnode, face_id );
+
+  } else {
+
+     done = TRUE;
+
+  }
+
+  draw_polygon_edge( edge_rec );
+
+  if (edge_rec.coord) free(edge_rec.coord);
+
+  while (!done) {
+
+     if (next < 0) {
+	gotoxy(1,18);
+	printf(" VPF topology error! Edge: %ld   face: %ld   left: %ld   right: %ld",
+		edge_rec.id,face_id,edge_rec.left,edge_rec.right);
+	getch();
+	gotoxy(1,18);
+	printf("                                                                                ");
+	done = TRUE;
+     }
+
+     if (next==0) {
+	gotoxy(1,19);
+	printf("Next edge(%d) = 0  ",edge_rec.id);
+	done = TRUE;
+     }
+
+     if (next == start_edge) done = TRUE;
+
+     if (!done) {
+
+	edge_rec = read_edge( next, edgetable );
+
+	next = next_polygon_edge( &edge_rec, &prevnode, face_id );
+
+	draw_polygon_edge( edge_rec );
+
+	if (edge_rec.coord) free(edge_rec.coord);
+
+     }
+  }
+
+}
+
+
+
+/*************************************************************************
+ *
+ *N  outline_face
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function outlines (without filling) the specified face from
+ *     the given face table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     face_id   <input>==(long int) row id of the specified face.
+ *     facetable <input>==(vpf_table_type) VPF facemitive table.
+ *     ringtable <input>==(vpf_table_type) VPF ringmitive table.
+ *     edgetable <input>==(vpf_table_type) VPF edge primitive table.
+ *     outline   <input>==(color_type) outline color.
+ *     inner     <input>==(int) if TRUE, draw inner rings;
+ *                              if FALSE, only draw outer ring.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void outline_face( long int face_id,
+		   vpf_table_type facetable,
+		   vpf_table_type ringtable,
+		   vpf_table_type edgetable,
+		   color_type outline,
+		   int inner )
+{
+   face_rec_type face_rec;
+   ring_rec_type ring_rec;
+
+   gpsetlinecolor(outline);
+   gpsetlinestyle(SOLID_LINE);
+   gpsetlinewidth(NORM_WIDTH);
+
+   face_rec = read_face( face_id, facetable );
+   ring_rec = read_ring( face_rec.ring, ringtable );
+   outline_polygon_loop( face_id, ring_rec.edge, edgetable );
+
+   if (!inner) return;
+
+   while (ring_rec.face == face_id ) {
+      ring_rec = read_next_ring( ringtable );
+
+      if (feof(ringtable.fp)) {
+	 break;
+      }
+
+      if (ring_rec.face == face_id) {
+
+	 outline_polygon_loop( face_id, ring_rec.edge, edgetable );
+
+      }
+   }
+}
+
+
+
+/*************************************************************************
+ *
+ *N  outline_face_table
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function outlines the specified face from a previously unopened
+ *     face primitive table in the given color.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     face_id  <input>==(long int) id of the face to be outlined.
+ *     fname    <input>==(char *) file name of the face primitive table.
+ *     color    <input>==(int) color to outline the face.
+ *     inner    <input>==(int) if TRUE, draw inner rings;
+ *                             if FALSE, only draw outer ring.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void outline_face_table( long int face_id, char *fname,
+			 int color, int inner )
+{
+   vpf_table_type facetable, ringtable, edgetable;
+   char *name;
+
+   name = (char *)vpfmalloc( 255*sizeof(char) );
+
+   gpsetlinecolor( color );
+
+   facetable = vpf_open_table(fname,disk, "rb", (char *)NULL);
+
+   strupr(fname);
+
+   strcpy( name, facetable.path );
+   strcat( name, "RNG" );
+   ringtable = vpf_open_table( name, disk, "rb", (char *)NULL );
+
+   strcpy( name, facetable.path );
+   strcat( name, "EDG" );
+   edgetable = vpf_open_table( name, disk, "rb", (char *)NULL );
+
+   free( name );
+
+   hidemousecursor();
+
+   outline_face( face_id, facetable, ringtable, edgetable, color,
+		 inner );
+
+   showmousecursor();
+
+   vpf_close_table(&facetable);
+   vpf_close_table(&ringtable);
+   vpf_close_table(&edgetable);
+
+}
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.h b/Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.h
new file mode 100644
index 0000000000..1e5ad3a6e4
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfdraw.h
@@ -0,0 +1,64 @@
+/* VPFDRAW.H - DRAW FEATURES */
+
+#ifndef __VPFDRAW_H__
+
+#define __VPFDRAW_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int draw_edge_row( row_type row, vpf_table_type table );
+int draw_edge( long int rownum, vpf_table_type table );
+
+int draw_point_row( row_type row, vpf_table_type table );
+int draw_point( long int rownum, vpf_table_type table );
+
+int draw_text_row( row_type row, vpf_table_type table );
+int draw_text( long int rownum, vpf_table_type table );
+
+void screen_bounds( double x1, double y1, double x2, double y2,
+		    int *xmin, int *ymin, int *xmax, int *ymax );
+
+void draw_face_row( row_type row,
+		    vpf_table_type facetable,
+		    vpf_table_type ringtable,
+		    vpf_table_type edgetable,
+		    vpf_table_type spx,
+		    color_type outline,
+		    color_type c1,
+		    color_type c2,
+		    color_type c3,
+		    color_type c4 );
+void draw_face( long int face_id,
+		vpf_table_type facetable,
+		vpf_table_type ringtable,
+		vpf_table_type edgetable,
+		vpf_table_type spx,
+		color_type outline,
+		color_type c1,
+		color_type c2,
+		color_type c3,
+		color_type c4 );
+
+long int next_polygon_edge( edge_rec_type *edge_rec,
+			    long int *prevnode,
+			    long int face_id );
+
+void outline_face( long int face_id,
+		   vpf_table_type facetable,
+		   vpf_table_type ringtable,
+		   vpf_table_type edgetable,
+		   color_type outline,
+		   int inner );
+
+
+void outline_face_table( long int face_id,
+			 char *fname,
+			 int color,
+			 int inner );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfinit.h b/Utilities/OSSIM/ossim_core/vpf_util/vpfinit.h
new file mode 100644
index 0000000000..beef6a4a7e
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfinit.h
@@ -0,0 +1,44 @@
+#ifndef vpfinit_HEADER
+#define vpfinit_HEADER
+/* VPFINIT.H */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void vpfinit( database_type *database, library_type *library,
+	      view_type *view, map_environment_type *mapenv );
+
+void free_database( database_type *database );
+
+void free_library( library_type *library );
+
+void free_view( view_type *view );
+
+void vpfreset( database_type *database, library_type *library,
+	       view_type *view, map_environment_type *mapenv );
+
+void vpfexit( database_type *database, library_type *library,
+	      view_type *view, map_environment_type *mapenv );
+
+database_type init_database( char *dbpath, VPF_BOOLEAN *ok );
+
+int pick_library( database_type database, char *name );
+
+library_type init_library( database_type database, char *libname,
+			   VPF_BOOLEAN *ok );
+
+view_type init_view( char *viewname, library_type library );
+
+void set_viewing_area( library_type *library,
+		       map_environment_type *mapenv,
+		       extent_type extent );
+
+void set_default_area( library_type *library,
+		       map_environment_type *mapenv,
+		       float x, float y );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfio.h b/Utilities/OSSIM/ossim_core/vpf_util/vpfio.h
new file mode 100644
index 0000000000..560169f009
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfio.h
@@ -0,0 +1,203 @@
+/* SCCS_ID[] = @(#) vpfio.h 1.6 8/13/91  */
+
+/* ========================================================================
+
+   Environmental Systems Research Institute (ESRI) Applications Programming
+
+       Project: 		Conversion from ARC/INFO to VPF 
+       Original Coding:		David Flinn     July 1991
+       Modifications:	      
+
+   ======================================================================== */
+
+#ifndef _VPF_IO_
+#define _VPF_IO_
+
+#include <stdio.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These are all the metacharacters used to parse out input text files */
+
+#define	 	COMPONENT_SEPERATOR	';'
+#define		LINE_CONTINUE		'\\'
+#define		SPACE			' '
+#define		TEXT_NULL		"-"
+#define		COMMENT_CHAR		'"'
+#define		FIELD_COUNT		'='
+#define		FIELD_SEPERATOR		','
+#define		END_OF_FIELD		':'
+#define		FIELD_PARTITION		'^'
+#define		NEXT_ELEMENT		'|'
+#define		COMMENT			'#'
+#define		NEW_LINE		'\n'
+#define		VARIABLE_COUNT		'*'
+#define		TAB			'\t'
+
+/* Now set up the macros to read in data from disk and to write */
+
+/* #if __MSDOS__ */
+#if 0
+
+#define   Read_Vpf_Char(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(char),count,fromtable)
+
+#define   Read_Vpf_Short(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(short int),count,fromtable)
+
+#define   Read_Vpf_Int(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(long int),count,fromtable)
+
+#define   Read_Vpf_Float(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(float),count,fromtable)
+
+#define   Read_Vpf_Double(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(double),count,fromtable)
+
+#define   Read_Vpf_Date(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(date_type)-1,count,fromtable)
+
+#define   Read_Vpf_Coordinate(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(coordinate_type),count,fromtable)
+
+#define   Read_Vpf_CoordinateZ(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(tri_coordinate_type),count,fromtable)
+
+#define   Read_Vpf_DoubleCoordinate(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(double_coordinate_type),count,fromtable)
+
+#define   Read_Vpf_DoubleCoordinateZ(tobuffer,fromtable,count)\
+	     fread(tobuffer,sizeof(double_tri_coordinate_type), \
+	     count,fromtable)
+
+#define   Write_Vpf_Char(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(char),count,fromfile)
+
+#define   Write_Vpf_Short(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(short int),count,fromfile)
+
+#define   Write_Vpf_Int(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(long int),count,fromfile)
+
+#define   Write_Vpf_Float(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(float),count,fromfile)
+
+#define   Write_Vpf_Double(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(double),count,fromfile)
+
+#define   Write_Vpf_Date(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(char)*20,count,fromfile)
+
+#define   Write_Vpf_Coordinate(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(float)*2,count,fromfile)
+
+#define   Write_Vpf_CoordinateZ(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(float)*3,count,fromfile)
+
+#define   Write_Vpf_DoubleCoordinate(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(double)*2,count,fromfile)
+
+#define   Write_Vpf_DoubleCoordinateZ(tobuffer,fromfile,count)\
+	     fwrite(tobuffer,sizeof(double)*3,count,fromfile)
+
+#else   /* Now the UNIX subroutine calls */
+
+
+/* types */
+typedef enum {
+  VpfNull,
+  VpfChar,
+  VpfShort,
+  VpfInteger,
+  VpfFloat,
+  VpfDouble,
+  VpfDate,
+  VpfKey,
+  VpfCoordinate,
+  VpfTriCoordinate,
+  VpfDoubleCoordinate,
+  VpfDoubleTriCoordinate,
+  VpfUndefined
+} VpfDataType ;
+
+#define   Read_Vpf_Char(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfChar,count,fromfile)
+
+#define   Read_Vpf_Short(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfShort,count,fromfile)
+
+#define   Read_Vpf_Int(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfInteger,count,fromfile)
+
+#define   Read_Vpf_Float(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfFloat,count,fromfile)
+
+#define   Read_Vpf_Double(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfDouble,count,fromfile)
+
+#define   Read_Vpf_Date(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfDate,count,fromfile)
+
+#define   Read_Vpf_Coordinate(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfCoordinate,count,fromfile)
+
+#define   Read_Vpf_CoordinateZ(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfTriCoordinate,count,fromfile)
+
+#define   Read_Vpf_DoubleCoordinate(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfDoubleCoordinate,count,fromfile)
+
+#define   Read_Vpf_DoubleCoordinateZ(tobuffer,fromfile,count)\
+	     VpfRead(tobuffer,VpfDoubleTriCoordinate,count,fromfile)
+
+#define   Write_Vpf_Char(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfChar,count,fromfile)
+
+#define   Write_Vpf_Short(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfShort,count,fromfile)
+
+#define   Write_Vpf_Int(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfInteger,count,fromfile)
+
+#define   Write_Vpf_Float(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfFloat,count,fromfile)
+
+#define   Write_Vpf_Double(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfDouble,count,fromfile)
+
+#define   Write_Vpf_Date(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfDate,count,fromfile)
+
+#define   Write_Vpf_Coordinate(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfCoordinate,count,fromfile)
+
+#define   Write_Vpf_CoordinateZ(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfTriCoordinate,count,fromfile)
+
+#define   Write_Vpf_DoubleCoordinate(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfDoubleCoordinate,count,fromfile)
+
+#define   Write_Vpf_DoubleCoordinateZ(tobuffer,fromfile,count)\
+	     VpfWrite(tobuffer,VpfDoubleTriCoordinate,count,fromfile)
+
+/*  subroutines */
+
+long int VpfRead ( void *to, VpfDataType type, long int count, FILE *from ) ;
+
+long int VpfWrite( void *from, VpfDataType type, long int count, FILE *to );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif          /* if __MSDOS__    */
+#endif		/* ifndef _VPF_IO_ */
+
+
+
+
+
+
+
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.c
new file mode 100644
index 0000000000..2c88b9e5d7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.c
@@ -0,0 +1,1835 @@
+/*************************************************************************
+ *
+ *N  Module VPFMISC
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains miscellaneous routines used (potentially) by
+ *     several other VPF modules.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                     DOS Turbo C
+ *E
+ *************************************************************************/
+
+#ifdef __MSDOS__
+#  include <graphics.h>
+#  include <alloc.h>
+#else
+#  ifdef MACOSX 
+#    include <sys/types.h>
+#    include <sys/malloc.h>
+#  else
+#    include <malloc.h>
+#    include <string.h>
+#  endif
+#endif
+
+
+#include <ctype.h> /* For toupper function. */
+
+#include "vpftidx.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <fcntl.h>
+#ifdef __MSDOS__
+#  include <sys\stat.h>
+#  include <io.h>
+#  include <conio.h>
+#  include <dos.h>
+#  include <dir.h>
+#else
+#  include <sys/stat.h>
+#endif
+#include <math.h>
+#include <errno.h>
+#include <stdarg.h>
+#ifdef __MSDOS__
+#  include <process.h>
+#  include <bios.h>
+#  include "gui.h"
+#endif
+#include "vpfmisc.h"
+#include "vpftable.h"
+#include "vpfview.h"
+
+
+#ifdef __MSDOS__
+  extern color_type menucolor, menubordercolor, menutextcolor;
+#endif
+
+#if !defined(__MSDOS__) && !defined(_MSC_VER)
+char* strrev(char* str)
+{
+  register int i,len;
+  char *copy;
+
+  len = strlen(str);
+  copy = (char *) malloc(sizeof(char)*(len+1));
+  (void) strcpy(copy,str);
+  for(i=0;i<len;i++)
+    str[i]=copy[(len-1)-i];
+  free(copy);
+  return str;
+}
+
+char* strupr(char* str)
+{
+  char* s = str;
+  while (*s)
+  {
+	  *s = toupper(*s);
+	  ++s;
+  }
+  return str;
+}
+#endif /* #ifndef __MSDOS__ */
+
+/*************************************************************************
+ *
+ *N  vpfmalloc
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function allocates memory off of the heap and checks for
+ *     success.  If not enough memory is available, this routine will abort
+ *     the program with an error message.  Can be in graphics mode to call
+ *     this procedure, not a necessity.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    size    <input> == (unsigned long) number of bytes to allocate.
+ *    return <output> == (void *) pointer to the allocated memory.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1990    Original Version    DOS Turbo C
+ *    Ronald Rozensky   Sept 1991 check for no memory, graphics mode
+ *E
+ *************************************************************************/
+void *vpfmalloc( unsigned long size )
+{
+   void *p;
+#ifdef __MSDOS__
+   p = farmalloc( size );
+   if (!p)
+   {
+      printf("Out of memory  %ld  %ld\n",size,farcoreleft());
+      getch();
+
+      if (graphic_mode())
+	 closegraph();
+      exit(1);
+   }
+#else
+   p = malloc(size);
+   if (!p)
+   {
+     printf("Out of memory %ld\n", size);
+     exit(1);
+   }
+#endif
+   return p;
+}
+#ifdef __MSDOS__
+/*************************************************************************
+ *
+ *N  get_display_position
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function finds a suitable position to display a new window on
+ *     the screen.  If the window fits, its upper left hand corner will be
+ *     the current mouse position.  If not, it will be adjusted so that it
+ *     will fit on the screen.  Should be in graphics mode to call this
+ *     function.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    x     <output> == (int *) pointer to the x display position.
+ *    y     <output> == (int *) pointer to the y display position.
+ *    window <input> == (window_type) window to be displayed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1990    Original Version    DOS Turbo C
+ *E
+ *************************************************************************/
+void get_display_position( int *x, int *y, window_type window )
+{
+   int mbutton, delta;
+
+   getmouseposition( x, y, &mbutton );
+   delta = window.x2 - window.x1;
+   if ((*x) + delta > getmaxx()-2)
+      (*x) = getmaxx()-delta-10;
+   if ((*x) < 2)
+      (*x) = 2;
+   delta = window.y2 - window.y1;
+   if ((*y) + delta > getmaxy()-2)
+      (*y) = getmaxy()-delta-10;
+   if ((*y) < 2)
+      (*y) = 2;
+}
+
+
+/*************************************************************************
+ *
+ *N  displayinfo
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays an array of text strings in a
+ *     popup text window.  Must be in graphics mode to call this function.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    text[] <input> == (char *) array of text strings to be displayed.
+ *    nlines <input> == (int) number of text lines.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    June 1990    Original Version    DOS Turbo C
+ *E
+ *************************************************************************/
+void displayinfo( char *text[],
+		  int  nlines )
+{
+   int         i,maxw,height,x,y,pad;
+   panel_type  panel;
+
+   arrow_cursor();
+   settextstyle( SMALL_FONT, HORIZ_DIR, 4 );
+   maxw = 0;
+   height = 0;
+   for (i=0;i<nlines;i++) {
+      if (textwidth(text[i]) > maxw) maxw = textwidth(text[i]);
+      height = height + textheight(text[i]) + 5;
+   }
+   if (maxw < (textwidth("Continue") + 10))
+      maxw = textwidth("Continue") + 10;
+   pad = (maxw*10)/100;
+   maxw = maxw + (2*pad);
+   if (maxw > getmaxx())
+     maxw = getmaxx() - 8;
+   height = height + 2*(textheight("Continue") + 10);
+
+   create_panel( &panel, maxw, height, menucolor, menubordercolor );
+   x = pad;
+   y = 0;
+   for (i=0;i<nlines;i++) {
+      y = y + textheight(text[i]) + 3;
+      create_label( text[i], x, y, SMALL_FONT, 4, menutextcolor, &panel );
+   }
+   y = height - (textheight("Continue") + 6);
+   x = (maxw - (textwidth("Continue") + 10))/2;
+   create_button( 27, "Continue", x, y, SMALL_FONT, 4,
+		  menutextcolor, menucolor, menubordercolor, RELIEVED,
+		  &panel );
+
+   get_display_position( &x, &y, panel.window );
+
+   display_panel( &panel, x, y );
+   i = process_panel( &panel, i );
+
+   destroy_panel( &panel );
+   close_panel( &panel );
+}
+
+
+
+/*************************************************************************
+ *
+ *N  displaymessage
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays a list of text strings in a
+ *     popup text window.  The list must be NULL-terminated.  Must be in
+ *     graphics mode to call this function.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    string <input> == (char *) first text string to be displayed.
+ *    ... <input> == (char *) variable list of text strings to be displayed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    August 1991                        DOS Turbo C
+ *E
+ *************************************************************************/
+void displaymessage( char *string, ... )
+{
+   int         i,maxw,height,x,y,pad, nlines;
+   panel_type  panel;
+   char **text;
+   va_list arglist;
+
+   va_start(arglist,string);
+   nlines = 1;
+   while (va_arg(arglist,char *)) nlines++;
+   va_end(arglist);
+
+   text = (char **)vpfmalloc((nlines+1)*sizeof(char *));
+   text[0] = string;
+   va_start(arglist,string);
+   for (i=1;i<nlines;i++) {
+      text[i] = va_arg(arglist,char *);
+   }
+   va_end(arglist);
+
+   settextstyle( SMALL_FONT, HORIZ_DIR, 4 );
+   maxw = 0;
+   height = 0;
+   for (i=0;i<nlines;i++) {
+      if (textwidth(text[i]) > maxw) maxw = textwidth(text[i]);
+      height = height + textheight(text[i]) + 5;
+
+   }
+   if (maxw < (textwidth("Continue") + 10))
+      maxw = textwidth("Continue") + 10;
+   pad = (maxw*10)/100;
+   maxw = maxw + (2*pad);
+   if (maxw > getmaxx())
+     maxw = getmaxx() - 8;
+   height = height + 2*(textheight("Continue") + 5) + 5;
+
+   create_panel( &panel, maxw, height, menucolor, menubordercolor );
+   x = pad;
+   y = 0;
+   for (i=0;i<nlines;i++) {
+      y = y + textheight(text[i]) + 5;
+      create_label( text[i], x, y, SMALL_FONT, 4, menutextcolor, &panel );
+   }
+   y = height - (textheight("Continue") + 6);
+   x = (maxw - (textwidth("Continue") + 10))/2;
+   create_button( 27, "Continue", x, y, SMALL_FONT, 4,
+		  menutextcolor, menucolor, menubordercolor, RELIEVED,
+		  &panel );
+
+   get_display_position( &x, &y, panel.window );
+
+   display_panel( &panel, x, y );
+   i = process_panel( &panel, i );
+
+   destroy_panel( &panel );
+   close_panel( &panel );
+
+   free(text);
+}
+
+
+
+/*************************************************************************
+ *
+ *N  display_message
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays a one-line informational message to the
+ *     screen and waits for the user to continue.  Must be in graphics mode
+ *     to call this function.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    str <input> == (char *) message to be displayed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    July 1990    Original Version    DOS Turbo C
+ *E
+ *************************************************************************/
+void display_message(char *str)
+{
+   char **txt;
+
+   txt = (char **)vpfmalloc( (unsigned long)(1*sizeof(char **)) );
+   txt[0] = strdup(str);
+   displayinfo( txt, 1 );
+   free(txt[0]);
+   free(txt);
+}
+
+#else
+
+void displaymessage( char *string, ... )
+{
+   int         i, nlines;
+   char **text;
+   va_list arglist;
+
+   va_start(arglist,string);
+   nlines = 1;
+   while (va_arg(arglist,char *)) nlines++;
+   va_end(arglist);
+
+   text = (char **)vpfmalloc((nlines+1)*sizeof(char *));
+   text[0] = string;
+   va_start(arglist,string);
+   for (i=1;i<nlines;i++) {
+      text[i] = va_arg(arglist,char *);
+   }
+   va_end(arglist);
+   for (i=0;i<nlines;i++) {
+       fprintf(stderr, text[i]);
+   }
+   free(text);
+}
+
+void display_message(char *str)
+{
+    fprintf(stderr, str);
+}
+
+
+#endif
+
+
+/*************************************************************************
+ *
+ *N  float_to_dms
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function converts a floating point lat lon coordinate to
+ *     degrees-minutes-seconds format.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    coord   <input> == (double) floating point lat lon coordinate.
+ *    return <output> == (dms_type) degrees-minutes-seconds coordinate.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1990    Original Version    DOS Turbo C
+ *E
+ *************************************************************************/
+dms_type float_to_dms( double coord )
+{
+   dms_type dms_coord;
+
+   dms_coord.degrees = (int)coord;
+   dms_coord.minutes = (int)((double)(coord-(int)coord)*60.0);
+   dms_coord.seconds = (float)((((double)(coord-(int)coord)* 60.0) -
+			(double)dms_coord.minutes) * 60.0);
+   dms_coord.minutes = abs(dms_coord.minutes);
+   dms_coord.seconds = (float)(fabs(dms_coord.seconds));
+
+   if (dms_coord.minutes == 60) {
+      if (dms_coord.degrees > 0)
+	 dms_coord.degrees++;
+      else
+	 dms_coord.degrees--;
+      dms_coord.minutes = 0;
+   }
+
+   if ((dms_coord.degrees == 0)&&(coord < 0.0)) dms_coord.minutes *= -1;
+
+   return dms_coord;
+}
+
+
+/*************************************************************************
+ *
+ *N  dms_to_float
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function converts a coordinate in degrees-minutes-seconds format
+ *     to a floating point coordinate.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    coord   <input> == (dms_type) degrees-minutes-seconds coordinate.
+ *    return <output> == (double) floating point lat lon coordinate.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1990    Original Version    DOS Turbo C
+ *E
+ *************************************************************************/
+double dms_to_float( dms_type coord )
+{
+   return ( (double)coord.degrees +
+	    ((double)coord.minutes / 60.0) +
+	    (coord.seconds/3600.0) );
+}
+
+
+
+/*************************************************************************
+ *
+ *N  dms_string
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function converts a coordinate in degrees-minutes-seconds format
+ *     to a character string.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    coord   <input> == (dms_type) degrees-minutes-seconds coordinate.
+ *    seconds <input> == (int) flag to indicate if seconds are to be
+ *                       displayed.
+ *    return <output> == (char *) character string.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1990    Original Version    DOS Turbo C
+ *E
+ *************************************************************************/
+char *dms_string( dms_type coord, int seconds )
+{
+   char *str,deg[5],min[3],sec[3];
+
+   str = (char *)vpfmalloc( (20*sizeof(char))+
+			    sizeof(deg)+sizeof(min)+sizeof(sec) );
+
+   itoa( coord.degrees, deg, 10 );
+   itoa( abs(coord.minutes), min, 10 );
+   if (seconds) itoa( ((int)floor(coord.seconds)), sec, 10 );
+   if ((coord.degrees==0)&&(coord.minutes < 0)) {
+      strcpy(str,"-0");
+      coord.minutes *= -1;
+   } else {
+      strcpy(str,deg);
+   }
+   strcat(str," deg ");
+   strcat(str,min);
+   strcat(str," min ");
+   if (seconds) {
+      strcat(str,sec);
+      strcat(str," sec");
+   }
+
+   return(str);
+}
+#ifdef __MSDOS__
+/*************************************************************************
+ *
+ *N  out_dms
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays the given degree-minutes-seconds coordinate
+ *     at the specified location on the screen.  The direction is given
+ *     for placement along the edges of the screen.  Must be in graphics
+ *     mode to call this function.  User must make sure that all text will
+ *     fit on the screen; this program will not adjust size, but will adjust
+ *     location to make sure that all text that CAN fit on the screen WILL
+ *     fit on the screen.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    coord   <input> == (dms_type) degrees-minutes-seconds coordinate.
+ *    x       <input> == (int) x location.
+ *    y       <input> == (int) y location.
+ *    dir     <input> == (int) dir.  HORIZ_DIR=0, VERT_DIR=1
+ *    seconds <input> == (int) flag indicating whether to display seconds.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    October 1990    Original Version    DOS Turbo C
+ *    Ronald Rozensky   Sept 1991 x,y adjustments to make text fit on screen
+ *E
+ *************************************************************************/
+void out_dms( dms_type coord, int x, int y, int dir, int seconds )
+{
+   char deg[8],min[8],sec[8];
+   int x1,x2,y1,y2, width, adjust, minutes;
+
+   settextjustify(LEFT_TEXT,BOTTOM_TEXT);
+
+   itoa( coord.degrees, deg, 10 );
+   if ((coord.seconds >= 30.0)&&(!seconds)) {
+      /* Round up */
+      minutes = abs(coord.minutes)+1;
+      if (minutes == 60) {
+	 /* Rounded up to next degree */
+	 strcpy(min,"0");
+	 if (coord.degrees > 0)
+	    coord.degrees++;
+	 else if (coord.degrees < 0)
+	    coord.degrees--;
+	 else {
+	    if (coord.minutes < 0 || coord.seconds < 0.0)
+	       coord.degrees++;
+	    else
+	       coord.degrees--;
+	 }
+      } else {
+	 itoa( minutes, min, 10 );
+      }
+      itoa( coord.degrees, deg, 10 );
+   } else {
+      itoa( abs(coord.minutes), min, 10 );
+   }
+   if (seconds) itoa( floor(abs(coord.seconds+0.5)), sec, 10 );
+   if ((coord.degrees==0)&&(coord.minutes < 0)) {
+      strcpy(deg,"-0");
+   }
+   if ((coord.degrees==0)&&(coord.minutes==0)&&(coord.seconds<0)) {
+      strcpy(deg,"-0");
+   }
+   strcat(min,"'");
+   if (seconds) strcat(sec,"''");
+
+   if (dir==HORIZ_DIR) {
+      width = textwidth(deg)+3;
+      if ((coord.minutes > 0)||(seconds)) {
+	 width += textwidth(min)+3;
+      }
+      if (seconds) {
+	 width += textwidth(sec)+3;
+      }
+      x1 = x - width/2;
+      x2 = x1 + width;
+      y1 = y-textheight(deg)-1;
+      y2 = y+1;
+   } else {
+      width = textwidth(deg)+3;
+      if ((coord.minutes > 0)||(seconds)) {
+	 width += textwidth(min)+3;
+      }
+      if (seconds) {
+	 width += textwidth(sec)+3;
+      }
+      x1 = x;
+      x2 = x1 + width;
+      y1 = y - (textheight(deg)+4)/2;
+      y2 = y + (textheight(deg)+4)/2;
+   }
+
+   setfillstyle(SOLID_FILL,DARKGRAY);
+   if (x1 <0)
+     {
+     adjust = 0-x1;
+     x1 = 0;
+     x2 = x2 += adjust;
+     }
+   if (y1 <0)
+     {
+     adjust = 0-y1;
+     y1 = 0;
+     y2 = y2 += adjust;
+     }
+   if ((y1-y2 < getmaxy()) && (y2 > getmaxy()))
+     {
+     adjust = y2-getmaxy();
+     y2 = getmaxy();
+     y1 -= adjust;
+     }
+   if ((x1-x2 < getmaxx()) && (x2 > getmaxx()))
+     {
+     adjust = x2-getmaxx();
+     x2 = getmaxx();
+     x1 -= adjust;
+     }
+   bar(x1,y1,x2,y2);
+   outtextxy(x1,y2,deg);
+   circle(x1+textwidth(deg)+1, y2-textheight(deg), 2);
+   if ((coord.minutes > 0)||(seconds))
+      outtextxy(x1+textwidth(deg)+5,y2-1,min);
+   if (seconds)
+      outtextxy(x1+textwidth(deg)+3+textwidth(min)+3,y2-1,sec);
+
+}
+#endif
+
+
+/*************************************************************************
+ *
+ *N  strpos
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the character array position of the first
+ *     occurrence of the given character. (-1 if not present)
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    str     <input> == (char *) character string to be searched.
+ *    ch      <input> == (char) character to search for.
+ *    return <output> == (int) position of character (-1 if not present).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1990    Original Version    DOS Turbo C
+ *E
+ *************************************************************************/
+int strpos( char *str, char ch )
+{
+   register int i;
+
+   for (i=0;(unsigned int)i<strlen(str);i++)
+      if (str[i] == ch) return i;
+   return -1;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  fwithin
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether the input (x,y) coordinate lies
+ *     within the given rectangular extent.  It returns either TRUE or FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    x        <input> == (float) x coordinate of the test point.
+ *    y        <input> == (float) y coordinate of the test point.
+ *    extent   <input> == (extent_type) rectangular area to be tested.
+ *    fwithin <output> == (VPF_BOOLEAN) VPF_BOOLEAN:
+ *                               TRUE if (x,y) lies within area
+ *                               FALSE if (x,y) lies outside of area
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1990   Original Version   DOS Turbo C
+ *E
+ *************************************************************************/
+VPF_BOOLEAN fwithin( float x,
+		 float y,
+		 extent_type extent )
+{
+   if ((x >= extent.x1) && (x <= extent.x2) &&
+      (y >= extent.y1) && (y <= extent.y2))
+      return TRUE;
+   else
+      return FALSE;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  contained
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether an input rectangular 'extent1' is
+ *     contained within another rectangular 'extent2'.  It returns either
+ *     TRUE or FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    extent1 <input> == (extent_type) rectangular area to be tested within.
+ *    extent2 <input> == (extent_type) rectangular area to be tested against.
+ *    contained <output> == (VPF_BOOLEAN) VPF_BOOLEAN:
+ *                               TRUE if extent2 contains extent1
+ *                               FALSE if extent2 does not contain extent1
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1990   Original Version   DOS Turbo C
+ *E
+ *************************************************************************/
+VPF_BOOLEAN contained( extent_type extent1,
+		   extent_type extent2 )
+{
+   /* Test each of the four corners of extent1 */
+   /*   	  ____________
+		  |          |
+		  |  2       |
+		  |    ______+___
+		  |    |     |
+		  |    |     |
+		  |    |  1  |
+		  |    |     |
+		  ------------
+		       |
+		       |
+   */
+   if ((extent1.x1 >= extent2.x1) && (extent1.x1 <= extent2.x2) &&
+      (extent1.y1 >= extent2.y1) && (extent1.y1 <= extent2.y2))
+      return TRUE;
+   /*             ____________
+		  |          |
+		  |  2       |
+		  |          |
+	       ---+------    |
+		  |     |    |
+		  |  1  |    |
+		  |     |    |
+		  ------------
+			|
+			|
+   */
+   if ((extent1.x2 >= extent2.x1) && (extent1.x2 <= extent2.x2) &&
+      (extent1.y1 >= extent2.y1) && (extent1.y1 <= extent2.y2))
+      return TRUE;
+   /*
+		       |
+		  _____|______
+		  |    |     |
+		  |  1 |     |
+		  |    |     |
+		--+-----     |
+		  |          |
+		  |    2     |
+		  |__________|
+   */
+   if ((extent1.x2 >= extent2.x1) && (extent1.x2 <= extent2.x2) &&
+      (extent1.y2 >= extent2.y1) && (extent1.y2 <= extent2.y2))
+      return TRUE;
+   /*			|
+			|
+		  ______|_____
+		  |     |    |
+		  |     | 1  |
+		  |     |    |
+		  | 2   -----+--
+		  |          |
+		  |          |
+		  ------------
+   */
+   if ((extent1.x1 >= extent2.x1) && (extent1.x1 <= extent2.x2) &&
+      (extent1.y2 >= extent2.y1) && (extent1.y2 <= extent2.y2))
+      return TRUE;
+
+
+   /* Test for overlaps */
+   /*	 ________             --------------
+	 |      |             |     2      |
+	 |  1   |             | ---------- |
+     ----+------+----         | |        | |
+     | 2 |      |   |         | |        | |
+     |   |      |   |         | |   1    | |
+     ----+------+----         | |        | |
+	 |      |             | |        | |
+	 |      |             | ---------- |
+	 --------             |            |
+			      --------------
+   */
+   if ((extent1.y1 >= extent2.y1) && (extent1.y2 <= extent2.y2) &&
+       (extent1.x1 <= extent2.x2) && (extent1.x2 >= extent2.x1))
+      return TRUE;
+   /*	 ________             --------------
+	 |      |             |     1      |
+	 |  2   |             | ---------- |
+     ----+------+----         | |        | |
+     | 1 |      |   |         | |        | |
+     |   |      |   |         | |   2    | |
+     ----+------+----         | |        | |
+	 |      |             | |        | |
+	 |      |             | ---------- |
+	 --------             |            |
+			      --------------
+   */
+   if ((extent1.x1 >= extent2.x1) && (extent1.x2 <= extent2.x2) &&
+       (extent1.y1 <= extent2.y2) && (extent1.y2 >= extent2.y1))
+      return TRUE;
+   return FALSE;
+}
+
+
+#ifdef __MSDOS__
+/*************************************************************************
+ *
+ *N  info_window
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays a temporary window to the screen with a
+ *     single string of text.  Must be in graphics mode to call this
+ *     function.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    text    <input> == (char *)message to display.
+ *    return <output> == (window_type) window created and displayed.
+ *                       [Will need to be deleted]
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1990   Original Version   DOS Turbo C
+ *E
+ *************************************************************************/
+window_type info_window( char *text )
+{
+   window_type w;
+   int x,y;
+
+   settextstyle(SMALL_FONT,HORIZ_DIR,4);
+   settextjustify(LEFT_TEXT,BOTTOM_TEXT);
+   if (textwidth(text) > getmaxx())
+     x = getmaxx()-20;
+    else
+     x = textwidth(text) + 20;
+   create_window( &w, x, textheight(text)+10,
+		  menucolor,menubordercolor );
+   get_display_position( &x, &y, w );
+   open_window( &w, x,y );
+   setcolor(menutextcolor);
+   hidemousecursor();
+   outtextxy( 10,textheight(text)+5,text );
+   showmousecursor();
+   return w;
+}
+#endif
+
+
+/*************************************************************************
+ *
+ *N  rightjust
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function right justifies the given string and removes the
+ *     trailing newline character (if one exists).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    str <inout> == (char *) string to be justified.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   November 1990   Original Version   DOS Turbo C
+ *E
+ *************************************************************************/
+char *rightjust( char *str )
+{
+   return strrev(leftjust(strrev(str)));
+}
+
+/*************************************************************************
+ *
+ *N  leftjust
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function left justifies the given string and removes the
+ *     trailing newline character (if one exists)
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    str <inout> == (char *) string to be justified.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   November 1990   Original Version   DOS Turbo C
+ *E
+ *************************************************************************/
+char *leftjust(char * str)
+{
+   register char * eol;
+
+   strcpy(str, str + strspn(str, " \t\n\b"));
+
+   if ((eol = strchr(str, '\n')) != NULL)
+     *eol = 0;
+
+   return str;
+}
+
+#ifdef __MSDOS__
+/*************************************************************************
+ *
+ *N  displayerror
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays an error message when a disk error is detected.
+ *     It displays the given lines of text in a popup panel and waits for
+ *     the user to click on either retry or cancel.  It returns 1 for retry
+ *     and 0 for cancel.  Must be in graphics mode to call this function.
+ *
+ *     text strings may contain embedded newlines, in which case text to the
+ *     right of the newline will be displayed on (what else?) a new line.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    text[]  <input> == (char *) array of text strings to be displayed.
+ *    nlines  <input> == (int) number of lines of text (this count ignores
+ *                             newline characters embedded in the text
+ *                             strings
+ *    return <output> == (VPF_BOOLEAN) 1 => retry,
+ *                                 0 => cancel.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    July 1990    Prototype 3    DOS Turbo C
+ *E
+ *************************************************************************/
+VPF_BOOLEAN displayerror( char *text[],
+		      int  nlines )
+{
+   register int i;
+   int          maxw,
+		height,
+		x,
+		y,
+		pad,
+		choice,
+		n_real_lines;
+   panel_type   panel;
+   int          retry_button  = 'r',
+		cancel_button = 'c',
+		msg_ar_sz     = 10;
+   char       * walker,
+	     ** msgs;
+   struct viewporttype view;
+
+   getviewsettings( &view );
+   setviewport(0,0,getmaxx(),getmaxy(),1);
+
+
+   settextstyle( SMALL_FONT, HORIZ_DIR, 4 );
+   msgs = (char **) vpfmalloc(msg_ar_sz * sizeof(char *));
+   maxw = height = 0;
+
+   for (n_real_lines = i = 0; i < nlines; i++) {
+     walker = text[i];
+     while (1) {
+	size_t substr_len = strcspn(walker, "\n");
+	char   plug;
+
+	maxw                 = max(maxw, textwidth(walker));
+	height               = height + textheight(walker) + 5;
+	plug                 = walker[substr_len];
+	walker[substr_len]   = '\0';
+	msgs[n_real_lines++] = strdup(walker);
+
+	if (n_real_lines == msg_ar_sz)
+	  msgs = (char **) realloc(msgs, (msg_ar_sz += 5) * sizeof(char *));
+	if (plug == 0)
+	  break;
+
+	walker[substr_len] = plug;
+	walker            += substr_len + 1;
+     }
+   }
+
+   if (maxw < (textwidth("Retry") + textwidth("Cancel") + 20))
+      maxw = textwidth("Retry") + textwidth("Cancel") + 20;
+
+   pad    = (maxw*10)/100;
+   maxw   = maxw + (2*pad);
+   height = height + 2*(textheight("Retry") + 5) + 1;
+   maxw   = min(getmaxx(), maxw);
+   height = min(getmaxy()-10, height);
+
+   create_panel( &panel, maxw, height, menucolor, menubordercolor );
+
+   for (y = i = 0; i < n_real_lines; i++) {
+     create_label(msgs[i], pad, y, SMALL_FONT, 4, menutextcolor, &panel );
+     y += textheight(msgs[i]) + 3;
+   }
+
+   y = height-15;
+
+   create_button( retry_button,
+		  "Retry",
+		  3,
+		  y,
+		  SMALL_FONT,
+		  4,
+		  menutextcolor,
+		  menucolor,
+		  menubordercolor,
+		  RELIEVED,
+		  &panel );
+   create_button( cancel_button,
+		  "Cancel",
+		  maxw - (textwidth("Cancel") + 13),
+		  y,
+		  SMALL_FONT,
+		  4,
+		  menutextcolor,
+		  menucolor,
+		  menubordercolor,
+		  RELIEVED,
+		  &panel );
+
+   get_display_position( &x, &y, panel.window );
+
+   display_panel( &panel, x,y );
+   showmousecursor();
+   arrow_cursor();
+   choice = process_panel( &panel, 0 );
+   hidemousecursor();
+
+   destroy_panel( &panel );
+   close_panel( &panel );
+
+   setviewport(view.left,view.top,view.right,view.bottom,view.clip);
+
+   for (i = 0; i < n_real_lines; i++)
+     free(msgs[i]);
+   free(msgs);
+
+   return (choice == retry_button) ? 1 : 0;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  getcursorposition
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the cursor position when either the mouse
+ *     has been moved or an arrow key has been pressed.  Must have called
+ *     showmousecursor() before calling this routine.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    x       <inout> == (int *) x position of the cursor.
+ *    y       <inout> == (int *) y position of the cursor.
+ *    button  <inout> == (int *) mouse button pressed (or simulated with
+ *                               the keyboard).
+ *    return <output> == (int) escape status:
+ *                             FALSE -> escape pressed
+ *                             TRUE  -> escape not pressed
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   November 1990   Original Version   DOS Turbo C
+ *E
+ *************************************************************************/
+int getcursorposition( int *x,
+		       int *y,
+		       int *button )
+{
+   char ch,ch2;
+   int  xpos,ypos, ok = TRUE;
+
+   if (kbhit()) {
+      xpos = *x;
+      ypos = *y;
+      ch = getch();
+      switch (ch) {
+	 case 13:                         /* Enter key */
+	    *button = LEFT_BUTTON_DOWN;
+	    break;
+	 case '8':
+	    ypos -= 10;
+	    break;
+	 case '2':
+	    ypos += 10;
+	    break;
+	 case '4':
+	    xpos -= 10;
+	    break;
+	 case '6':
+	    xpos += 10;
+	    break;
+	 case 27:
+	    ok = FALSE;
+	    break;
+      }
+      if (ch==0) {
+	 ch2 = getch();
+	 switch (ch2) {
+	    case 72:
+	       ypos--;
+	       break;
+	    case 80:
+	       ypos++;
+	       break;
+	    case 75:
+	       xpos--;
+	       break;
+	    case 77:
+	       xpos++;
+	       break;
+	    case 59: /* F1 key */
+	       *button = RIGHT_BUTTON_DOWN;
+	       break;
+	 }
+      }
+      setmouseposition(xpos,ypos);
+      *x = xpos;
+      *y = ypos;
+   } else getmouseposition(x,y,button);
+   return ok;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  yes_no
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function displays a panel asking the user a yes or no
+ *     question and returns the response.  Must be in graphics mode to call
+ *     this function.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    text     <input>==(char *) question string.
+ *    return  <output>==(int) yes (TRUE) or no (FALSE).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                    DOS Turbo C
+ *E
+ *************************************************************************/
+int yes_no( char *text )
+{
+   panel_type  panel;
+   int         no_id = 27;
+   int         yes_id = 13;
+   int         x,y,width,height,maxheight,id=0;
+
+   settextstyle( SMALL_FONT, HORIZ_DIR, 4 );
+
+   width = 0;
+   maxheight = 0;
+   width = textwidth(text);
+   maxheight = textheight(text);
+
+   width = width + 50;
+   if (width > getmaxx())
+      width = getmaxx()-10;
+   height = maxheight * 5;
+
+   create_panel( &panel,width,height,menucolor,menubordercolor );
+
+   y = maxheight;
+   create_label( text,CENTER,y,SMALL_FONT,4,menutextcolor,&panel );
+   y += maxheight;
+
+   create_button( yes_id, "Yes",
+		  3, height-textheight("Y")-6,
+		  SMALL_FONT, 4,
+		  menutextcolor, menucolor, menubordercolor, RELIEVED,
+		  &panel );
+   create_button( no_id, "No",
+		  width-textwidth("No")-13,
+		  height-textheight("No")-6,
+		  SMALL_FONT, 4,
+		  menutextcolor, menucolor, menubordercolor, RELIEVED,
+		  &panel );
+
+   get_display_position( &x, &y, panel.window );
+
+   display_panel( &panel, x,y );
+
+   id = process_panel(&panel, id);
+
+   destroy_panel( &panel );
+   close_panel( &panel );
+
+   if (id == yes_id)
+      return TRUE;
+   else
+      return FALSE;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  printer_ready
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether or not the attached
+ *     printer is ready.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    return <output> == (int) TRUE if ready, FALSE if not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   November 1990   Original Version   DOS Turbo C
+ *E
+ *************************************************************************/
+int printer_ready( void )
+{
+   union REGS reg;
+
+   reg.h.ah = 2;
+   reg.x.dx = 0;
+   int86(0x17, &reg, &reg);
+
+   /* this is not busy           not an io error      not out of paper */
+   return (reg.h.ah & 0x80) && (!(reg.h.ah & 8)) && (!(reg.h.ah & 32));
+}
+
+
+/*************************************************************************
+ *
+ *N  printer_ok
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether the printer is ready and allows
+ *     the user to keep retrying or cancel.  Must be in graphics mode to call
+ *     this function.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    return <output> == (int) TRUE if ready, FALSE if cancel.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   November 1990   Original Version   DOS Turbo C
+ *E
+ *************************************************************************/
+int printer_ok( void )
+{
+   int retry;
+   char *msg[] = {"Printer not ready"};
+
+   while (!printer_ready()) {
+      hidemousecursor();
+      retry = displayerror(msg,1);
+      showmousecursor();
+      if (!retry) return FALSE;
+   }
+   return TRUE;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  coprocessor_present
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether a math coprocessor chip is present
+ *     on the current computer configuration.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    return <output> == (int) TRUE if present, FALSE if not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   July 1991                          DOS Turbo C
+ *E
+ *************************************************************************/
+int coprocessor_present( void )
+{
+   int stat;
+
+   stat = biosequip();
+
+   /* If bit 1 of stat is on, a coprocessor is present */
+   if (stat & 2)
+      return TRUE;
+   else
+      return FALSE;
+}
+#endif
+
+
+
+
+/*************************************************************************
+ *
+ *N  is_primitive
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether the given file name specifies a
+ *     VPF primitive table (Edge, Face, Entity Node, or Text).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    name    <input> == (char *) file name to be tested.
+ *    return <output> == (int) TRUE if primitive, FALSE if not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int is_primitive( char *name )
+{
+   strupr(name);
+   if (strstr(name,"END")) return TRUE;
+   if (strstr(name,"CND")) return TRUE;
+   if (strstr(name,"EDG")) return TRUE;
+   if (strstr(name,"FAC")) return TRUE;
+   if (strstr(name,"TXT")) return TRUE;
+   return FALSE;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  is_simple_feature
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether the given file name specifies a
+ *     VPF simple feature table (Point, Line, or Area feature table).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    name    <input> == (char *) file name to be tested.
+ *    return <output> == (int) TRUE if simple feature, FALSE if not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int is_simple_feature( char *name )
+{
+   strupr(name);
+   if (strstr(name,"PFT")) return TRUE;
+   if (strstr(name,"LFT")) return TRUE;
+   if (strstr(name,"AFT")) return TRUE;
+   return FALSE;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  is_complex_feature
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether the given file name specifies a
+ *     VPF complex feature table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    name    <input> == (char *) file name to be tested.
+ *    return <output> == (int) TRUE if complex feature, FALSE if not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int is_complex_feature( char *name )
+{
+   strupr(name);
+   if (strstr(name,"CFT")) return TRUE;
+   return FALSE;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  is_feature
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether the given file name specifies a
+ *     VPF feature table (Point, Line, Area, or Complex feature table).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    name    <input> == (char *) file name to be tested.
+ *    return <output> == (int) TRUE if feature, FALSE if not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int is_feature( char *name )
+{
+   strupr(name);
+   if (strstr(name,"PFT")) return TRUE;
+   if (strstr(name,"LFT")) return TRUE;
+   if (strstr(name,"AFT")) return TRUE;
+   if (strstr(name,"TFT")) return TRUE;
+   if (strstr(name,"CFT")) return TRUE;
+   return FALSE;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  feature_type
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the type of feature the given table name
+ *     refers to (POINT, LINE, AREA, ANNO, or COMPLEX_FEATURE).  If the table
+ *     name does not specify a feature type, the function returns FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    name    <input> == (char *) file name to be tested.
+ *    return <output> == (int) feature type (FALSE if invalid name).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int feature_type( char *name )
+{
+   strupr(name);
+   if (strstr(name,"PFT")) return VPF_POINT;
+   if (strstr(name,"LFT")) return VPF_LINE;
+   if (strstr(name,"AFT")) return VPF_AREA;
+   if (strstr(name,"TXT")) return VPF_ANNO;
+   if (strstr(name,"TFT")) return VPF_ANNO;
+   if (strstr(name,"CFT")) return VPF_COMPLEX_FEATURE;
+   return FALSE;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  is_join
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function determines whether the given file name specifies a
+ *     VPF join table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    name    <input> == (char *) file name to be tested.
+ *    return <output> == (int) TRUE if join, FALSE if not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int is_join( char *name )
+{
+   char *ptr;
+
+   strupr(name);
+   ptr = strstr(name,".");
+   if (strstr(ptr,"JT")) return TRUE;
+   return FALSE;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  primitive_class
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the feature type the given primitive table
+ *     name refers to (POINT, LINE, AREA, or ANNO).  If the table
+ *     name is not a valid primitive table name, the function returns NULL.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    name    <input> == (char *) file name to be tested.
+ *    return <output> == (int) feature type (NULL if invalid primitive
+ *                             name).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int primitive_class( char *name )
+{
+   strupr(name);
+   if (strstr(name,"END")) return VPF_ENTITY_NODE;
+   if (strstr(name,"CND")) return VPF_CONNECTED_NODE;
+   if (strstr(name,"EDG")) return VPF_EDGE;
+   if (strstr(name,"FAC")) return VPF_FACE;
+   if (strstr(name,"TXT")) return VPF_TEXT;
+#ifdef __MSDOS__
+   return NULL;
+#else
+   return 0;
+#endif
+}
+
+int ossim_strcasecmp(const char *s1, const char *s2)
+{
+   size_t s1_size;
+   size_t s2_size;
+   unsigned int i;
+
+   /* Check for one string being null, one not. */
+   if (!s1 && s2)
+   {
+      return -1;
+   }
+   else if (s1 && !s2)
+   {
+      return 1;
+   }
+
+   /* Check for both strings being null.  Consider this equal? */
+   if (!s1 && !s2)
+   {
+      return 0;
+   }
+
+   /* Check for size differences. */
+   s1_size = strlen(s1);
+   s2_size = strlen(s2);
+   if (s1_size < s2_size)
+   {
+      return -1;
+   }
+   else if (s1_size > s2_size)
+   {
+      return 1;
+   }
+
+   /* Check the strings. */
+   for (i=0; i<s1_size; i++)
+   {
+      if ( toupper(s1[i]) != toupper(s2[i]) )
+      {
+         return ( (toupper(s1[i]) < toupper(s2[i]) ) ? -1 : 1);
+      }
+   }
+
+      /* Equal */   
+   return 0;
+}
+
+int ossim_strncasecmp(const char *s1, const char *s2, unsigned int n)
+{
+   size_t s1_size;
+   size_t s2_size;
+   unsigned int i;
+
+   /* Check for one string being null, one not. */
+   if (!s1 && s2)
+   {
+      return -1;
+   }
+   else if (s1 && !s2)
+   {
+      return 1;
+   }
+
+   /* Check for both strings being null.  Consider this equal? */
+   if (!s1 && !s2)
+   {
+      return 0;
+   }
+
+   /* Check for size. */
+   if (n == 0)
+   {
+      return 0;
+   }
+   
+   s1_size = strlen(s1);
+   s2_size = strlen(s2);
+   if (n > s1_size)
+   {
+      return -1;
+   }
+   else if (n > s2_size )
+   {
+      return 1;
+   }
+
+   /* Check the strings. */
+   for (i=0; i<n; i++)
+   {
+      if ( toupper(s1[i]) != toupper(s2[i]) )
+      {
+         return ( (toupper(s1[i]) < toupper(s2[i]) ) ? -1 : 1);
+      }
+   }
+
+      /* Equal */   
+   return 0;
+}
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.h b/Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.h
new file mode 100644
index 0000000000..2615392a17
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfmisc.h
@@ -0,0 +1,108 @@
+#ifndef _VPFMISC_
+#define _VPFMISC_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define graphic_mode()\
+	( (getgraphmode() < 0) ? 0 : 1)
+
+#include "vpfview.h"
+
+void *vpfmalloc( unsigned long size );
+
+void vpffree( void *ptr );
+void displaymessage(char*, ...);
+
+#ifdef __MSDOS__
+void get_display_position( int *x, int *y, window_type window );
+#endif
+
+void displayinfo( char *text[],
+		  int  nlines );
+
+void no_study_area(void);
+
+void no_map_displayed(void);
+
+void display_message(char *str);
+
+dms_type float_to_dms( double coord );
+
+double dms_to_float( dms_type coord );
+
+char *dms_string( dms_type coord, int seconds );
+
+void out_dms( dms_type coord, int x, int y, int dir, int seconds );
+
+int strpos( char *str, char ch );
+
+VPF_BOOLEAN fwithin( float x,
+	     float y,
+	     extent_type extent );
+
+VPF_BOOLEAN contained( extent_type extent1,
+	       extent_type extent2 );
+
+void memleft(void);
+
+#ifdef __MSDOS__
+window_type info_window( char *text );
+#endif
+
+#if !defined(__MSDOS__) && !defined(_MSC_VER) && !defined(__BORLANDC__)
+#  ifndef _MSC_VER
+char* strupr(char* str);
+#  endif
+#endif
+
+float distance( double lat1, double lon1, double lat2, double lon2,
+		int units );
+
+char *rightjust( char *str );
+
+char *leftjust( char *str );
+
+VPF_BOOLEAN displayerror( char *text[],
+		      int  nlines );
+
+int printer_ready(void);
+
+int printer_ok(void);
+
+int is_primitive( char *name );
+
+int is_simple_feature( char *name );
+
+int is_complex_feature( char *name );
+
+int is_feature( char *name );
+
+int feature_type( char *name );
+
+int is_join( char *name );
+
+int primitive_class( char *name );
+
+/**
+ * Written to replace non-portable "strcasecmp".
+ *
+ * @return An integer -1, 0, or 1 if s1 is found, respectively, to be less
+ * than, to match, or be greater than s2.
+ */
+int ossim_strcasecmp(const char *s1, const char *s2);
+
+/**
+ * Written to replace non-portable "strncasecmp".  Similar to
+ * ossim_strcasecmp,  except  it  only  compares  the first n characters.
+ *
+ * @return An integer -1, 0, or 1 if s1 is found, respectively, to be less
+ * than, to match, or be greater than s2.
+ */
+int ossim_strncasecmp(const char *s1, const char *s2, unsigned int n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfnear.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfnear.c
new file mode 100644
index 0000000000..f96281737b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfnear.c
@@ -0,0 +1,350 @@
+/***************************************************************************
+ *
+ *N  VPFNEAR.C
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This module contains functions to determine the nearest distance
+ *    from a given point to a specified edge.  The algorithm is to find
+ *    the perpendicular bisector from each segment of the edge to the
+ *    test point, if it exists, and calculate the distance.  If a
+ *    perpendicular from the line to the test point does not exist,
+ *    it computes the  distance to both the start and end node and takes
+ *    the minimum.  The minimum distance found is the closest distance to
+ *    the edge.
+ *    There are two main calling interfaces in this module:
+ *       distance_to_edge() if your edge table is already open.
+ *       distance_to_edge_table() to open the edge table, calculate,
+ *                                and then close the table when finished.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    Nov 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ **************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef __MSDOS__
+#include <conio.h>
+#endif
+#include <math.h>
+#if defined(__CYGWIN__) || defined(MACOSX)|| defined(_WIN32)
+#include "values.h"
+#else
+#include <values.h>
+#endif
+#ifdef __MSDOS__
+#include <graphics.h>
+#endif
+#include "vpftable.h"
+#include "vpfprim.h"
+#include "vpfview.h"
+#include "mapgraph.h"
+
+typedef struct {
+   float x1;
+   float y1;
+   float x2;
+   float y2;
+} line_segment_type;
+
+
+/**************************************************************************
+ *
+ *N  perpendicular_intersection
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Test whether a perpendicular to a line segment intersects a search
+ *    point.  lseg must be of a type similar to line_segment_type.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    lseg      <input> == (line_segment_type) line segment.
+ *    xsearch   <input> == (float) search point x coordinate.
+ *    ysearch   <input> == (float) search point y coordinate.
+ *    xint      <inout> == (float *) intersection point x coordinate.
+ *    yint      <inout> == (float *) intersection point y coordinate.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels, DOS Turbo C   1991
+ *    Ronald Rozensky, vertical and horizontal line handlers.
+ *E
+ *************************************************************************/
+int perpendicular_intersection( line_segment_type lseg,
+				float xsearch, float ysearch,
+				float *xint, float *yint )
+{
+   float m1=0,mp=0,b1=0,bp=0; /* m's are for slopes, b's are for y intersections */
+		      /* for the old y=mx+b point slope formula.         */
+
+   if (lseg.y1 == lseg.y2)
+      if (((lseg.x1 <= xsearch) && (xsearch <= lseg.x2)) ||
+	  ((lseg.x2 <= xsearch) && (xsearch <= lseg.x1)))
+	 {
+	 *xint = xsearch;
+	 *yint = lseg.y1;
+	 return 1;
+	 }
+
+   if (lseg.x1 == lseg.x2)
+
+      if (((lseg.y1 <= ysearch) && (ysearch <= lseg.y2)) ||
+	  ((lseg.y2 <= ysearch) && (ysearch <= lseg.y1)))
+	 {
+	 *xint = lseg.x1;
+	 *yint = ysearch;
+	 return 1;
+	 }
+
+   if ( (lseg.x1==xsearch) && (lseg.y1==ysearch) ) {
+      *xint = xsearch;
+      *yint = ysearch;
+      return 1;
+   }
+   if ( (lseg.x2==xsearch) && (lseg.y2==ysearch) ) {
+      *xint = xsearch;
+      *yint = ysearch;
+      return 1;
+   }
+
+   if (lseg.x1 != lseg.x2) {
+      m1 = (lseg.y2-lseg.y1)/(lseg.x2-lseg.x1);
+      b1 = -1*m1*lseg.x1 + lseg.y1;
+      if (m1 != 0.0) {
+	 mp = (float)(-1.0/m1);       /* perpendicular */
+      } else {
+	 mp = MAXFLOAT;
+      }
+   } else {
+      m1 = MAXFLOAT;
+      mp = 0.0;
+   }
+
+   if (fabs(mp) < 1000000.0) {
+      bp = ysearch - mp*xsearch;
+   } else {
+      bp = MAXFLOAT;
+   }
+
+   /* Find intersection point of lseg and its perpendicular */
+
+   if ( (m1 != MAXFLOAT) && (mp != MAXFLOAT) ) {
+      *xint = (bp-b1)/(m1-mp);
+      *yint = m1*(*xint)+b1;
+   } else {                   /* At least one vertical line */
+      if (m1==MAXFLOAT) {          /* lseg is vertical */
+	 *yint = ysearch;
+	 *xint = lseg.x1;
+      } else {                     /* perp is vertical */
+	 *yint = lseg.y1;
+	 *xint = xsearch;
+      }
+   }
+
+   /* See if intersection point lies on both line segments */
+   return ( (*xint >= (float)min(lseg.x1,lseg.x2)) &&
+	    (*xint <= (float)max(lseg.x1,lseg.x2)) &&
+	    (*yint >= (float)min(lseg.y1,lseg.y2)) &&
+	    (*yint <= (float)max(lseg.y1,lseg.y2)) );
+}
+
+
+/* In VPFMISC.C for the VPFVIEW application */
+float distance( double lat1, double lon1, double lat2, double lon2,
+		int units );
+
+
+/**************************************************************************
+ *
+ *N  distance_to_edge_rec
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function computes the minimum distance from the given point
+ *    to the given edge record by looking at each segment in the line.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    x           <input> == (float) given point x coordinate.
+ *    y           <input> == (float) given point y coordinate
+ *    edge_rec    <input> == (edge_rec_type) given edge record.
+ *    dec_degrees <inout> == (int) flag to indicate if coordinates are
+ *                                 in decimal degrees.
+ *    distance_to_edge_rec <output> == (float) minimum distance to the
+ *                                     edge record.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels, DOS Turbo C   1991
+ *E
+ *************************************************************************/
+float distance_to_edge_rec( float x, float y, edge_rec_type edge_rec,
+			    int dec_degrees )
+{
+   register long int i;
+   line_segment_type lseg;
+   float xint,yint, d, dseg, d1, d2;
+   coordinate_type coord1, coord2;
+
+   d = MAXFLOAT;
+
+   coord1 = first_edge_coordinate(&edge_rec);
+   for (i=1;i<edge_rec.npts;i++) {
+      coord2 = next_edge_coordinate(&edge_rec);
+      lseg.x1 = coord1.x;
+      lseg.y1 = coord1.y;
+      lseg.x2 = coord2.x;
+      lseg.y2 = coord2.y;
+
+      if (perpendicular_intersection(lseg,x,y,&xint,&yint)) {
+	 if (dec_degrees)
+	    dseg = distance( y, x, yint, xint, 0 );
+	 else
+	    dseg = (float)(sqrt( (xint-x)*(xint-x) + (yint-y)*(yint-y) ));
+      } else {
+	 if (dec_degrees) {
+	    dseg = (float)min( distance( y, x, lseg.y1, lseg.x1, 0 ),
+			       distance( y, x, lseg.y2, lseg.x2, 0 ) );
+	 } else {
+	    d1 = (float)(sqrt( (lseg.x1-x)*(lseg.x1-x) + (lseg.y1-y)*(lseg.y1-y) ));
+	    d2 = (float)(sqrt( (lseg.x2-x)*(lseg.x2-x) + (lseg.y2-y)*(lseg.y2-y) ));
+	    dseg = (float)min(d1,d2);
+	 }
+      }
+
+      d = (float)min(d,dseg);
+
+      coord1 = coord2;
+   }
+
+   return d;
+}
+
+
+
+/**************************************************************************
+ *
+ *N  distance_to_edge
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function reads the specified edge from the given edge table
+ *    and computes the minimum distance from the given point to the
+ *    specified edge.  'edge_id' must be contained in the edge table.
+ *    edge_table must have been successfully opened with storage = DISK.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    x           <input> == (float) given point x coordinate.
+ *    y           <input> == (float) given point y coordinate
+ *    edge_id     <input> == (long int) specified edge.
+ *    edgetable   <input> == (vpf_table_type) given edge table.
+ *    dec_degrees <input> == (float) flag to indicate if coordinates are
+ *                                   in decimal degrees.
+ *    distance_to_edge <output> == (float) minimum distance to the given
+ *                                         edge from the given point.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels, DOS Turbo C   1991
+ *E
+ *************************************************************************/
+float distance_to_edge( float x, float y,
+			long int edge_id,
+			vpf_table_type edgetable,
+			int dec_degrees )
+{
+   edge_rec_type edge_rec;
+   float result;
+
+   edge_rec = read_edge( edge_id, edgetable );
+
+   result = distance_to_edge_rec( x, y, edge_rec, dec_degrees );
+
+   if (edge_rec.coord) free( edge_rec.coord );
+
+   return result;
+}
+
+
+
+/**************************************************************************
+ *
+ *N  distance_to_edge_table
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function reads the specified edge from the named edge table
+ *    and computes the minimum distance from the given point to the
+ *    specified edge.  'edge_id' must be contained in the edge table.
+ *    'fname' must be a valid path to a VPF edge table.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    x           <input> == (float) given point x coordinate.
+ *    y           <input> == (float) given point y coordinate
+ *    edge_id    <input> == (long int) specified edge id.
+ *    fname      <input> == (char *) path to valid VPF edge table.
+ *    dec_degrees <output> == (int) flag to indicate if coordinates are
+ *                                  in decimal degrees.
+ *    distance_to_edge_table <output> == (float) distance from the given
+ *                                       point to the specified edge.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels, DOS Turbo C   1991
+ *E
+ *************************************************************************/
+float distance_to_edge_table( float x, float y,
+			      long int edge_id,
+			      char *fname, int dec_degrees )
+{
+   vpf_table_type edgetable;
+   float result;
+   char *defstr=" ";
+
+   edgetable = vpf_open_table(fname,disk, "rb", defstr);
+
+   result = distance_to_edge( x, y, edge_id, edgetable, dec_degrees );
+
+   vpf_close_table(&edgetable);
+
+   return result;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfprim.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfprim.c
new file mode 100644
index 0000000000..fc88820a14
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfprim.c
@@ -0,0 +1,1135 @@
+/*************************************************************************
+ *
+ *N  Module VPFPRIM  -  VPF Primitives
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions for handling VPF primitives
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   April 1991                  DOS Turbo C
+ *E
+ *************************************************************************/
+
+#include <stdio.h>
+#ifdef __MSDOS__
+#include <io.h>
+#include <dos.h>
+#include <graphics.h>
+#else
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#if defined(__CYGWIN__) || defined(MACOSX)|| defined(_WIN32)
+#include "values.h"
+#else
+#include <values.h>
+#endif
+#ifdef __MSDOS__
+#include <alloc.h>
+#else
+#ifdef MACOSX 
+#include <sys/types.h>
+#include <sys/malloc.h>
+#else
+#include <malloc.h>
+#include <string.h>
+#endif
+#endif
+#include <stdlib.h>
+
+
+#include "vpftable.h"
+#include "vpfprim.h"
+
+/* Compute the offset from the start of the row to the given field */
+static long int row_offset( int field, row_type row, vpf_table_type table) 
+{
+   long int offset,n,size;
+   int i;
+   id_triplet_type key;
+   int keysize[] = {0,sizeof(char),sizeof(short int),sizeof(long int)};
+
+   if (field < 0 || field >= table.nfields) return -1;
+
+   offset = 0L;
+   for (i=0;i<field;i++) {
+      switch (table.header[i].type) {
+	 case 'I':
+	    offset += sizeof(long int)*row[i].count;
+	    break;
+	 case 'S':
+	    offset += sizeof(short int)*row[i].count;
+	    break;
+	 case 'T':
+	    offset += sizeof(char)*row[i].count;
+	    break;
+	 case 'F':
+	    offset += sizeof(float)*row[i].count;
+	    break;
+	 case 'D':
+	    offset += sizeof(date_type)*row[i].count;
+	    break;
+	 case 'K':
+	    get_table_element(i,row,table,&key,&n);
+	    size = sizeof(char) +
+		   keysize[TYPE0(key.type)] +
+		   keysize[TYPE1(key.type)] +
+		   keysize[TYPE2(key.type)];
+	    offset += size*row[i].count;
+	    break;
+	 case 'R':
+	    offset += sizeof(double)*row[i].count;
+	    break;
+	 case 'C':
+	    offset += sizeof(coordinate_type)*row[i].count;
+	    break;
+	 case 'B':
+	    offset += sizeof(double_coordinate_type)*row[i].count;
+	    break;
+	 case 'Z':
+	    offset += sizeof(tri_coordinate_type)*row[i].count;
+	    break;
+	 case 'Y':
+	    offset += sizeof(double_tri_coordinate_type)*row[i].count;
+	    break;
+      }
+   }
+   return offset;
+}
+
+
+/*************************************************************************
+ *
+ *N  create_edge_rec
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function creates an edge record internal structure from a
+ *     row of a VPF edge table.   NOTE:  This function allocates memory
+ *     for "edge_rec.coord". This array should be freed when no longer
+ *     needed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    row        <input> == (row_type) VPF table row.
+ *    edge_table <input> == (vpf_table_type) opened VPF table to read.
+ *    return    <output> == (edge_rec_type) returned edge record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+edge_rec_type create_edge_rec( row_type row, vpf_table_type edge_table )
+{
+   edge_rec_type edge;
+   long int count,i;
+   int rowid,start,end,right,left,rightfwd,leftfwd,coord;
+   id_triplet_type key;
+   tri_coordinate_type *Zcoord;
+   double_coordinate_type *Bcoord;
+   double_tri_coordinate_type *Ycoord;
+
+   rowid = table_pos( "ID", edge_table );
+   start = table_pos( "START_NODE", edge_table );
+   end = table_pos( "END_NODE", edge_table );
+   right = table_pos( "RIGHT_FACE", edge_table );
+   left = table_pos( "LEFT_FACE", edge_table );
+   rightfwd = table_pos( "RIGHT_EDGE", edge_table );
+   leftfwd = table_pos( "LEFT_EDGE", edge_table );
+   coord = table_pos( "COORDINATES", edge_table );
+
+   get_table_element( rowid, row, edge_table, &(edge.id), &count );
+
+   if (start >= 0)
+      get_table_element( start, row, edge_table, &(edge.start), &count );
+   else
+      edge.start = 0;
+
+   if (end >= 0)
+      get_table_element( end, row, edge_table, &(edge.end), &count );
+   else
+      edge.end = 0;
+
+   if (right >= 0) {
+      if (edge_table.header[right].type=='K') {
+	 get_table_element( right, row, edge_table, &key, &count );
+	 edge.right = key.id;
+      } else if (edge_table.header[right].type=='I') {
+	 get_table_element( right, row, edge_table, &(edge.right),
+			    &count );
+      } else {
+	 edge.right=1;
+      }
+   } else {
+      edge.right = 1;
+   }
+
+   if (left >= 0) {
+      if (edge_table.header[right].type=='K') {
+	 get_table_element( left, row, edge_table, &key, &count );
+	 edge.left = key.id;
+      } else if (edge_table.header[left].type=='I') {
+	 get_table_element( right, row, edge_table, &(edge.left),
+			    &count );
+      } else {
+	 edge.left=1;
+      }
+   } else {
+      edge.left = 1;
+   }
+
+   if (edge_table.header[rightfwd].type=='K') {
+      get_table_element( rightfwd, row, edge_table, &key, &count );
+      edge.rightfwd = key.id;
+   } else if (edge_table.header[rightfwd].type=='I') {
+      get_table_element( rightfwd, row, edge_table, &(edge.rightfwd),
+			 &count );
+   } else {
+      edge.rightfwd=0;
+   }
+
+   if (edge_table.header[leftfwd].type=='K') {
+      get_table_element( leftfwd, row, edge_table, &key, &count );
+      edge.leftfwd = key.id;
+   } else if (edge_table.header[leftfwd].type=='I') {
+      get_table_element( leftfwd, row, edge_table, &(edge.leftfwd),
+			 &count );
+   } else {
+      edge.leftfwd=0;
+   }
+
+   switch (edge_table.header[coord].type) {
+      case 'C':
+	 edge.coord = (coordinate_type *)get_table_element( coord,
+						      row, edge_table,
+						      NULL, &count );
+	 break;
+      case 'Z':
+	 Zcoord = (tri_coordinate_type *)get_table_element( coord,
+						      row, edge_table,
+						      NULL, &count );
+	 edge.coord = (coordinate_type *)malloc(count*
+					  sizeof(coordinate_type));
+	 if (edge.coord) {
+	    for (i=0;i<count;i++) {
+	       edge.coord[i].x = Zcoord[i].x;
+	       edge.coord[i].y = Zcoord[i].y;
+	    }
+	 }
+	 free(Zcoord);
+	 break;
+      case 'B':
+	 Bcoord = (double_coordinate_type *)get_table_element( coord,
+						      row, edge_table,
+						      NULL, &count );
+	 edge.coord = (coordinate_type *)malloc(count*
+					  sizeof(coordinate_type));
+	 if (edge.coord) {
+	    for (i=0;i<count;i++) {
+	       edge.coord[i].x = (float)Bcoord[i].x;
+	       edge.coord[i].y = (float)Bcoord[i].y;
+	    }
+	 }
+	 free(Bcoord);
+	 break;
+      case 'Y':
+	 Ycoord = (double_tri_coordinate_type *)get_table_element( coord,
+						      row, edge_table,
+						      NULL, &count );
+	 edge.coord = (coordinate_type *)malloc(count*
+					  sizeof(coordinate_type));
+	 if (edge.coord) {
+	    for (i=0;i<count;i++) {
+	       edge.coord[i].x = (float)Ycoord[i].x;
+	       edge.coord[i].y = (float)Ycoord[i].y;
+	    }
+	 }
+	 free(Ycoord);
+	 break;
+      default:
+	 count = 0;
+	 break;
+   }
+   edge.coord_type = edge_table.header[coord].type;
+   edge.npts = count;
+
+   edge.fp = NULL;
+   if (!edge.coord) {
+      edge.fp = edge_table.fp;
+      edge.startpos = index_pos(edge.id,edge_table) +
+		      row_offset(coord,row,edge_table) +
+		      (long int)sizeof(long int);
+      edge.pos = -1;
+   }
+
+   edge.current_coordinate = -1;
+
+   edge.dir = ' ';
+
+   return edge;
+}
+
+
+/*************************************************************************
+ *
+ *N  read_edge
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads a VPF edge record from the input VPF table.
+ *     It performs a search for the specified line number, and, if found,
+ *     allocates, reads, and returns the edge record.   NOTE:  This function
+ *     allocates memory for "edge_rec.coord". This array should be freed
+ *     when no longer needed.  If an invalid row id is passed in, this
+ *     function will have unpredictable results.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    id         <input> == (long int) edge id number.
+ *    edge_table <input> == (vpf_table_type) opened VPF table to read.
+ *    return    <output> == (edge_rec_type) returned edge record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+edge_rec_type read_edge( long int  id,
+			 vpf_table_type edge_table )
+{
+   edge_rec_type edge;
+   row_type row;
+
+   row = get_row( id, edge_table );
+   edge = create_edge_rec( row, edge_table );
+   free_row( row, edge_table );
+   return edge;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  read_next_edge
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads the next VPF edge record from the input VPF table.
+ *     NOTE:  This function allocates memory for "edge_rec.coord".
+ *     This array should be freed when no longer needed.
+ *     Must have called vpf_open_table with DISK as the storage type,
+ *     since this function accesses the disk to read the next row.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    edge_table  <input> == (vpf_table_type) opened VPF table to read.
+ *    return     <output> == (edge_rec_type) returned edge record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+edge_rec_type read_next_edge( vpf_table_type edge_table )
+{
+   edge_rec_type edge;
+   row_type row;
+
+   row = read_next_row( edge_table );
+   edge = create_edge_rec( row, edge_table );
+   free_row( row, edge_table );
+
+   return edge;
+}
+
+coordinate_type first_edge_coordinate( edge_rec_type *edge_rec )
+{
+   coordinate_type coord;
+   tri_coordinate_type Zcoord;
+   double_coordinate_type Bcoord;
+   double_tri_coordinate_type Ycoord;
+   int size;
+
+   edge_rec->current_coordinate = 0;
+
+   if (edge_rec->coord) {
+      /* Coordinate array is in memory */
+      return edge_rec->coord[0];
+   }
+
+   /* Read coordinate from table */
+   fseek(edge_rec->fp,edge_rec->startpos,SEEK_SET);
+   switch (edge_rec->coord_type) {
+      case 'C':
+	 fread(&coord,sizeof(coord),1,edge_rec->fp);
+	 size = sizeof(coord);
+	 break;
+      case 'Z':
+	 fread(&Zcoord,sizeof(Zcoord),1,edge_rec->fp);
+	 coord.x = Zcoord.x;
+	 coord.y = Zcoord.y;
+	 size = sizeof(Zcoord);
+	 break;
+      case 'B':
+	 fread(&Bcoord,sizeof(Bcoord),1,edge_rec->fp);
+	 coord.x = (float)Bcoord.x;
+	 coord.y = (float)Bcoord.y;
+	 size = sizeof(Bcoord);
+	 break;
+      case 'Y':
+	 fread(&Ycoord,sizeof(Ycoord),1,edge_rec->fp);
+	 coord.x = (float)Ycoord.x;
+	 coord.y = (float)Ycoord.y;
+	 size = sizeof(Ycoord);
+	 break;
+      default:
+	 coord.x = MAXFLOAT/2.0;
+	 coord.y = MAXFLOAT/2.0;
+	 size = 0;
+	 break;
+   }
+   edge_rec->pos = edge_rec->startpos + size;
+
+   return coord;
+}
+
+coordinate_type next_edge_coordinate( edge_rec_type *edge_rec )
+{
+   coordinate_type coord;
+   tri_coordinate_type Zcoord;
+   double_coordinate_type Bcoord;
+   double_tri_coordinate_type Ycoord;
+   int size;
+
+   if (edge_rec->current_coordinate < 0)
+      return first_edge_coordinate(edge_rec);
+
+   edge_rec->current_coordinate++;
+
+   if (edge_rec->current_coordinate >= edge_rec->npts) {
+      edge_rec->current_coordinate = edge_rec->npts-1L;
+      if (!edge_rec->coord)
+	 fseek(edge_rec->fp,edge_rec->startpos +
+			    (edge_rec->npts-1L)*sizeof(coord),
+	       SEEK_SET);
+   }
+
+   if (edge_rec->coord) {
+      /* Coordinate array is in memory */
+      return edge_rec->coord[edge_rec->current_coordinate];
+   }
+
+   /* Read coordinate from table */
+   switch (edge_rec->coord_type) {
+      case 'C':
+	 fread(&coord,sizeof(coord),1,edge_rec->fp);
+	 size = sizeof(coord);
+	 break;
+      case 'Z':
+	 fread(&Zcoord,sizeof(Zcoord),1,edge_rec->fp);
+	 coord.x = Zcoord.x;
+	 coord.y = Zcoord.y;
+	 size = sizeof(Zcoord);
+	 break;
+      case 'B':
+	 fread(&Bcoord,sizeof(Bcoord),1,edge_rec->fp);
+	 coord.x = (float)Bcoord.x;
+	 coord.y = (float)Bcoord.y;
+	 size = sizeof(Bcoord);
+	 break;
+      case 'Y':
+	 fread(&Ycoord,sizeof(Ycoord),1,edge_rec->fp);
+	 coord.x = (float)Ycoord.x;
+	 coord.y = (float)Ycoord.y;
+	 size = sizeof(Ycoord);
+	 break;
+      default:
+	 coord.x = MAXFLOAT/2.0;
+	 coord.y = MAXFLOAT/2.0;
+	 size = 0;
+	 break;
+   }
+   edge_rec->pos = edge_rec->startpos + size;
+
+   return coord;
+}
+
+coordinate_type get_edge_coordinate( long int n,
+				     edge_rec_type *edge_rec )
+{
+   coordinate_type coord;
+   tri_coordinate_type Zcoord;
+   double_coordinate_type Bcoord;
+   double_tri_coordinate_type Ycoord;
+   long int size;
+
+   if (n < 0)
+      return first_edge_coordinate(edge_rec);
+
+   if (n >= edge_rec->npts) n = edge_rec->npts-1L;
+
+   edge_rec->current_coordinate = n;
+
+   if (edge_rec->coord) {
+      /* Coordinate array is in memory */
+      return edge_rec->coord[n];
+   }
+
+   /* Read coordinate from table */
+   switch (edge_rec->coord_type) {
+      case 'C':
+	 size = sizeof(coord);
+	 break;
+      case 'Z':
+	 size = sizeof(Zcoord);
+	 break;
+      case 'B':
+	 size = sizeof(Bcoord);
+	 break;
+      case 'Y':
+	 size = sizeof(Ycoord);
+	 break;
+      default:
+	 size = 0;
+	 break;
+   }
+   edge_rec->pos = edge_rec->startpos + (n*size);
+   fseek(edge_rec->fp,edge_rec->pos,SEEK_SET);
+   switch (edge_rec->coord_type) {
+      case 'C':
+	 fread(&coord,sizeof(coord),1,edge_rec->fp);
+	 break;
+      case 'Z':
+	 fread(&Zcoord,sizeof(Zcoord),1,edge_rec->fp);
+	 coord.x = Zcoord.x;
+	 coord.y = Zcoord.y;
+	 break;
+      case 'B':
+	 fread(&Bcoord,sizeof(Bcoord),1,edge_rec->fp);
+	 coord.x = (float)Bcoord.x;
+	 coord.y = (float)Bcoord.y;
+	 break;
+      case 'Y':
+	 fread(&Ycoord,sizeof(Ycoord),1,edge_rec->fp);
+	 coord.x = (float)Ycoord.x;
+	 coord.y = (float)Ycoord.y;
+	 break;
+      default:
+	 coord.x = MAXFLOAT/2.0;
+	 coord.y = MAXFLOAT/2.0;
+	 break;
+   }
+
+   return coord;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  read_face
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads a VPF face record from the input VPF table.
+ *     It performs a search for the specified face number, and, if found,
+ *     reads and returns the face record.  If id is out of range,
+ *     either the lowest or highest id numbered face record type will be
+ *     returned.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    id           <input> == (long int) face id number.
+ *    face_table   <input> == (vpf_table_type) opened VPF table to read.
+ *    return      <output> == (face_rec_type) returned face record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+face_rec_type read_face( long int  id,
+			 vpf_table_type face_table )
+{
+   face_rec_type face;
+   int rowid,ring;
+   long int count;
+   row_type row;
+
+   rowid = table_pos( "ID", face_table );
+   ring = table_pos( "RING_PTR", face_table );
+
+   row = get_row( id, face_table );
+
+   get_table_element( rowid, row, face_table, &(face.id), &count );
+
+   get_table_element( ring, row, face_table, &(face.ring), &count );
+
+   free_row( row, face_table );
+
+   return face;
+}
+
+
+
+
+
+/*************************************************************************
+ *
+ *N  read_next_face
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads the next VPF face record from the input VPF
+ *     table.  Must have used vpf_open_table with DISK as the storage type.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    face_table   <input> == (vpf_table_type) opened VPF table to read.
+ *    return      <output> == (face_rec_type) returned face record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+face_rec_type read_next_face( vpf_table_type face_table )
+{
+   face_rec_type face;
+   int rowid,ring;
+   long int count;
+   row_type row;
+
+   rowid = table_pos( "ID", face_table );
+   ring = table_pos( "RING_PTR", face_table );
+
+   row = read_next_row( face_table );
+
+   get_table_element( rowid, row, face_table, &(face.id), &count );
+
+   get_table_element( ring, row, face_table, &(face.ring), &count );
+
+   free_row( row, face_table );
+
+   return face;
+}
+
+
+
+
+
+/*************************************************************************
+ *
+ *N  read_ring
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads a VPF ring record from the input VPF table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    id           <input> == (long int) ring id number.
+ *    ring_table   <input> == (vpf_table_type) opened VPF table to read.
+ *    return      <output> == (ring_rec_type) returned ring record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+ring_rec_type read_ring( long int  id,
+			 vpf_table_type ring_table )
+{
+   ring_rec_type ring;
+   int rowid,face,edge;
+   long int count;
+   row_type row;
+
+   rowid = table_pos( "ID", ring_table );
+   face = table_pos( "FACE_ID", ring_table );
+   edge = table_pos( "START_EDGE", ring_table );
+
+   row = get_row( id, ring_table );
+
+   get_table_element( rowid, row, ring_table, &(ring.id), &count );
+
+   get_table_element( face, row, ring_table, &(ring.face), &count );
+
+   get_table_element( edge, row, ring_table, &(ring.edge), &count );
+
+   free_row( row, ring_table );
+
+   return ring;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  read_next_ring
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads the next VPF ring record from the input VPF table.
+ *     If read_next_ring goes past the end of the vpftable, ring_rec_type
+ *     id will be a garbage number.  The programmer must ensure that this
+ *     does NOT happen.  Must have called vpf_open_table with DISK as the
+ *     storage type.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    ring_table   <input> == (vpf_table_type) opened VPF table to read.
+ *    return      <output> == (ring_rec_type) returned ring record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+ring_rec_type read_next_ring( vpf_table_type ring_table )
+{
+   ring_rec_type ring;
+   int rowid,face,edge;
+   long int count;
+   row_type row;
+
+   rowid = table_pos( "ID", ring_table );
+   face = table_pos( "FACE_ID", ring_table );
+   edge = table_pos( "START_EDGE", ring_table );
+
+   row = read_next_row( ring_table );
+
+   get_table_element( rowid, row, ring_table, &(ring.id), &count );
+
+   get_table_element( face, row, ring_table, &(ring.face), &count );
+
+   get_table_element( edge, row, ring_table, &(ring.edge), &count );
+
+   free_row( row, ring_table );
+
+   return ring;
+}
+
+
+
+
+
+
+/*************************************************************************
+ *
+ *N  read_point
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads a VPF point record from the input VPF table.
+ *     It performs a search for the specified point number, and, if found,
+ *     reads and returns the point record.  If read_point is given an
+ *     invalid id (eg 1000000) it will return garbage.  It is the programmers
+ *     responsibility to ensure that this does NOT happen.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    id            <input> == (long int) point id number.
+ *    point_table   <input> == (vpf_table_type) opened VPF table to read.
+ *    return       <output> == (point_rec_type) returned point record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+point_rec_type read_point( long int  id,
+			   vpf_table_type point_table )
+{
+   point_rec_type point;
+   int rowid,face,coord;
+   long int count;
+   coordinate_type c;
+   tri_coordinate_type Zcoord;
+   double_coordinate_type Bcoord;
+   double_tri_coordinate_type Ycoord;
+   row_type row;
+
+   rowid = table_pos( "ID", point_table );
+   face = table_pos( "CONTAINING_FACE", point_table );
+   coord = table_pos( "COORDINATE", point_table );
+
+   row = get_row( id, point_table );
+
+   get_table_element( rowid, row, point_table, &(point.id), &count );
+
+   if (face == -1)
+     point.face = -1;
+   else
+     get_table_element( face, row, point_table, &(point.face), &count );
+
+   switch (point_table.header[coord].type) {
+      case 'C':
+	 get_table_element( coord, row, point_table, &c, &count );
+	 point.x = c.x;
+	 point.y = c.y;
+	 break;
+      case 'Z':
+	 get_table_element( coord, row, point_table, &Zcoord, &count );
+	 point.x = Zcoord.x;
+	 point.y = Zcoord.y;
+	 break;
+      case 'B':
+	 get_table_element( coord, row, point_table, &Bcoord, &count );
+	 point.x = (float)Bcoord.x;
+	 point.y = (float)Bcoord.y;
+	 break;
+      case 'Y':
+	 get_table_element( coord, row, point_table, &Ycoord, &count );
+	 point.x = (float)Ycoord.x;
+	 point.y = (float)Ycoord.y;
+	 break;
+      default:
+	 point.x = MAXFLOAT/2.0;
+	 point.y = MAXFLOAT/2.0;
+	 break;
+   }
+
+   free_row( row, point_table );
+
+   return point;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  read_next_point
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads the next VPF point record from the input
+ *     VPF table.  Must have called vpf_open_table with DISK as the
+ *     storage type.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    point_table   <input> == (vpf_table_type) opened VPF table to read.
+ *    return       <output> == (point_rec_type) returned point record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+point_rec_type read_next_point( vpf_table_type point_table )
+{
+   point_rec_type point;
+   int rowid,face,coord;
+   long int count;
+   coordinate_type c;
+   tri_coordinate_type Zcoord;
+   double_coordinate_type Bcoord;
+   double_tri_coordinate_type Ycoord;
+   row_type row;
+
+   rowid = table_pos( "ID", point_table );
+   face = table_pos( "CONTAINING_FACE", point_table );
+   coord = table_pos( "COORDINATE", point_table );
+
+   row = read_next_row( point_table );
+
+   get_table_element( rowid, row, point_table, &(point.id), &count );
+
+   get_table_element( face, row, point_table, &(point.face), &count );
+
+   switch (point_table.header[coord].type) {
+      case 'C':
+	 get_table_element( coord, row, point_table, &c, &count );
+	 point.x = c.x;
+	 point.y = c.y;
+	 break;
+      case 'Z':
+	 get_table_element( coord, row, point_table, &Zcoord, &count );
+	 point.x = Zcoord.x;
+	 point.y = Zcoord.y;
+	 break;
+      case 'B':
+	 get_table_element( coord, row, point_table, &Bcoord, &count );
+	 point.x = (float)Bcoord.x;
+	 point.y = (float)Bcoord.y;
+	 break;
+      case 'Y':
+	 get_table_element( coord, row, point_table, &Ycoord, &count );
+	 point.x = (float)Ycoord.x;
+	 point.y = (float)Ycoord.y;
+	 break;
+      default:
+	 point.x = MAXFLOAT/2.0;
+	 point.y = MAXFLOAT/2.0;
+	 break;
+   }
+
+   free_row( row, point_table );
+
+   return point;
+}
+
+
+
+
+
+
+/*************************************************************************
+ *
+ *N  read_anno
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads a VPF annotation record from the input VPF table.
+ *     It performs a search for the specified annotation id, and, if
+ *     found, reads and returns the annotation record.  NOTE: This function
+ *     allocates memory for "anno.text".  This must be freed when no
+ *     longer needed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    id           <input> == (long int) annotation id.
+ *    anno_table   <input> == (vpf_table_type) opened VPF table to read.
+ *    return      <output> == (anno_rec_type) returned annotation record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+anno_rec_type read_anno( long int id,
+			 vpf_table_type anno_table )
+{
+   anno_rec_type anno;
+   int rowid,text,coord;
+   long int count;
+   coordinate_type *c;
+   tri_coordinate_type *Zcoord;
+   double_coordinate_type *Bcoord;
+   double_tri_coordinate_type *Ycoord;
+   row_type row;
+
+   rowid = table_pos( "ID", anno_table );
+   text = table_pos( "STRING", anno_table );
+   coord = table_pos( "SHAPE_LINE", anno_table );
+
+   row = get_row( id, anno_table );
+
+   get_table_element( rowid, row, anno_table, &(anno.id), &count );
+
+   anno.text = (char*)get_table_element( text, row, anno_table, NULL, &count );
+
+   switch (anno_table.header[coord].type) {
+      case 'C':
+	 c = (coordinate_type *)get_table_element( coord, row,
+					  anno_table, NULL, &count );
+	 anno.x = c[0].x;
+	 anno.y = c[0].y;
+	 free(c);
+	 break;
+      case 'Z':
+	 Zcoord = (tri_coordinate_type *)get_table_element( coord, row,
+					       anno_table, NULL, &count );
+	 anno.x = Zcoord[0].x;
+	 anno.y = Zcoord[0].y;
+	 free(Zcoord);
+	 break;
+      case 'B':
+	 Bcoord = (double_coordinate_type *)get_table_element( coord, row,
+					       anno_table, NULL, &count );
+	 anno.x = (float)Bcoord[0].x;
+	 anno.y = (float)Bcoord[0].y;
+	 free(Bcoord);
+	 break;
+      case 'Y':
+	 Ycoord = (double_tri_coordinate_type *)get_table_element( coord,
+					 row, anno_table, NULL, &count );
+	 anno.x = (float)Ycoord[0].x;
+	 anno.y = (float)Ycoord[0].y;
+	 free(Ycoord);
+	 break;
+      default:
+	 anno.x = MAXFLOAT/2.0;
+	 anno.y = MAXFLOAT/2.0;
+	 break;
+   }
+
+   free_row( row, anno_table );
+
+   return anno;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  read_next_anno
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads the next VPF annotation record from the input
+ *     VPF table.  Must have called vpf_open_table with DISK as the storage
+ *     type.  NOTE: This function allocates memory for "anno.text".  This
+ *     must be freed when no longer needed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    anno_table   <input> == (vpf_table_type) opened VPF table to read.
+ *    return      <output> == (anno_rec_type) returned annotation record.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    April 1991                      DOS Turbo C
+ *E
+ *************************************************************************/
+anno_rec_type read_next_anno( vpf_table_type anno_table )
+{
+   anno_rec_type anno;
+   int rowid,text,coord;
+   long int count;
+   coordinate_type *c;
+   tri_coordinate_type *Zcoord;
+   double_coordinate_type *Bcoord;
+   double_tri_coordinate_type *Ycoord;
+   row_type row;
+
+   rowid = table_pos( "ID", anno_table );
+   text = table_pos( "STRING", anno_table );
+   coord = table_pos( "SHAPE_LINE", anno_table );
+
+   row = read_next_row( anno_table );
+
+   get_table_element( rowid, row, anno_table, &(anno.id), &count );
+
+   anno.text = (char*)get_table_element( text, row, anno_table, NULL, &count );
+
+   switch (anno_table.header[coord].type) {
+      case 'C':
+	 c = (coordinate_type *)get_table_element( coord, row,
+					  anno_table, NULL, &count );
+	 anno.x = c[0].x;
+	 anno.y = c[0].y;
+	 free(c);
+	 break;
+      case 'Z':
+	 Zcoord = (tri_coordinate_type *)get_table_element( coord, row,
+					       anno_table, NULL, &count );
+	 anno.x = Zcoord[0].x;
+	 anno.y = Zcoord[0].y;
+	 free(Zcoord);
+	 break;
+      case 'B':
+	 Bcoord = (double_coordinate_type *)get_table_element( coord, row,
+					       anno_table, NULL, &count );
+	 anno.x = (float)Bcoord[0].x;
+	 anno.y = (float)Bcoord[0].y;
+	 free(Bcoord);
+	 break;
+      case 'Y':
+	 Ycoord = (double_tri_coordinate_type *)get_table_element( coord,
+					 row, anno_table, NULL, &count );
+	 anno.x = (float)Ycoord[0].x;
+	 anno.y = (float)Ycoord[0].y;
+	 free(Ycoord);
+	 break;
+      default:
+	 anno.x = MAXFLOAT/2.0;
+	 anno.y = MAXFLOAT/2.0;
+	 break;
+   }
+
+   free_row( row, anno_table );
+
+   return anno;
+}
+
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfprim.h b/Utilities/OSSIM/ossim_core/vpf_util/vpfprim.h
new file mode 100644
index 0000000000..20424aa0d0
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfprim.h
@@ -0,0 +1,122 @@
+#ifndef VPFPRIM_HEADER
+#define VPFPRIM_HEADER
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/********************************************************************/
+/*                           VPFPRIM.H                              */
+/********************************************************************/
+
+/* Must include "vpftable.h" */
+
+
+/* VPF edge record internal structure */
+typedef struct {
+   long int id;
+   long int start;
+   long int end;
+   long int right;
+   long int left;
+   long int rightfwd;
+   long int leftfwd;
+   char dir;
+   long int npts;
+   coordinate_type *coord;
+   /* New as of 2/18/92 for coordinate arrays too large for memory */
+   FILE *fp;
+   long int startpos, pos, current_coordinate;
+   char coord_type;
+} edge_rec_type;
+
+
+/* "static" part of the edge record (non-variable) */
+typedef struct {
+   long int id;
+   long int start;
+   long int end;
+   long int right;
+   long int left;
+   long int rightfwd;
+   long int leftfwd;
+   char dir;
+   long int npts;
+} edge_static_type;
+
+
+/* VPF face record structure */
+typedef struct {
+   long int id;
+   long int ring;
+} face_rec_type;
+
+
+/* VPF ring record structure */
+typedef struct {
+   long int id;
+   long int face;
+   long int edge;
+} ring_rec_type;
+
+
+/* VPF entity node record internal structure */
+typedef struct {
+   long int id;
+   long int face;
+   float x;
+   float y;
+} point_rec_type;
+
+
+/* VPF annotation record internal structure */
+typedef struct {
+   long  int id;
+   float height;
+   char  *text;
+   float x;
+   float y;
+} anno_rec_type;
+
+
+/* Functions: */
+
+edge_rec_type create_edge_rec( row_type row, vpf_table_type edge_table );
+
+edge_rec_type read_edge( long int id,
+			 vpf_table_type edge_table );
+
+edge_rec_type read_next_edge( vpf_table_type edge_table );
+
+/* New as of 2/18/92 for coordinate arrays too large for memory */
+coordinate_type first_edge_coordinate( edge_rec_type *edge_rec );
+coordinate_type next_edge_coordinate( edge_rec_type *edge_rec );
+coordinate_type get_edge_coordinate( long int n,
+				     edge_rec_type *edge_rec );
+/***/
+
+face_rec_type read_face( long int id,
+			 vpf_table_type face_table );
+
+face_rec_type read_next_face( vpf_table_type face_table );
+
+ring_rec_type read_ring( long int id,
+			 vpf_table_type ring_table );
+
+ring_rec_type read_next_ring( vpf_table_type ring_table );
+
+point_rec_type read_point( long int id,
+			   vpf_table_type point_table );
+
+point_rec_type read_next_point( vpf_table_type point_table );
+
+anno_rec_type read_anno( long int id,
+			 vpf_table_type anno_table );
+
+anno_rec_type read_next_anno( vpf_table_type anno_table );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfptply.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfptply.c
new file mode 100644
index 0000000000..c0d069057c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfptply.c
@@ -0,0 +1,499 @@
+/***************************************************************************
+ *
+ *N  VPFPTPLY.C
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This module contains functions to test whether a given point lies
+ *    inside of a VPF representation of a face (or polygon, geometrically).
+ *    The method used is to create a plum line from the given test point
+ *    out to basically infinity and count the number of intersections
+ *    with all of the line segements of the outer and inner rings of the
+ *    face.  An odd count indicates that the test point is inside of
+ *    the face; an even count (0 is even) indicates that the point lies
+ *    outside of the polygon (including inside of a hole).
+ *    There are two main interface routines:
+ *      point_in_face() if you already have the Face primitive tables open.
+ *      point_in_face_table() if you want to just specify the path.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions:
+ *F
+ *    int intersect( line_segment_type l1, line_segment_type l2,
+ *        float *xint, float *yint );
+ *    int intersect_polygon_edge( float x, float y, edge_rec_type edge_rec );
+ *    int intersect_polygon_loop( float x, float y,
+ *        int face_id, long int start_edge,
+ *        vpf_table_type edgetable );
+ *    int point_in_face( float x, float y,
+ *	  long int face_id,
+ *        vpf_table_type facetable,
+ *        vpf_table_type ringtable,
+ *        vpf_table_type edgetable );
+ *    int point_in_face_table( float x, float y,
+ *	  long int face_id,
+ *        char *fname );
+ *E
+ **************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef __MSDOS__
+#include <conio.h>
+#endif
+#include <math.h>
+#if defined(__CYGWIN__)||defined(MACOSX)|| defined(_WIN32)
+#include "values.h"
+#else
+#include <values.h>
+#endif
+#ifdef __MSDOS__
+#include <graphics.h>
+#endif
+#include "vpftable.h"
+#include "vpfprim.h"
+#include "vpfview.h"
+#include "mapgraph.h"
+#include "vpfdraw.h"
+#include "vpftidx.h"
+
+typedef struct {
+   float x1;
+   float y1;
+   float x2;
+   float y2;
+} line_segment_type;
+/**************************************************************************
+ *
+ *N  intersect
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Test whether line segment l1 intersects line segment l2
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    l1   <input> == (line_segment_type) line segment one.
+ *    l2   <input> == (line_segment_type) line segment two.
+ *    xint <inout> == (float *) intersection point x coordinate.
+ *    yint <inout> == (float *) intersection point y coordinate.
+ *    intersect <output> == (int) VPF_BOOLEAN:
+ *                                1 --> line segments intersect
+ *                                0 --> line segments do not intersect
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+int intersect( line_segment_type l1, line_segment_type l2,
+	       float *xint, float *yint )
+{
+   double m1,m2,b1=0,b2=0;
+   float tempy1,tempy2;
+
+   if ( (l1.x1==l1.x2) && (l2.y1==l2.y2) )
+   {
+      /* l1 is vertical and l2 is horizontal */
+      
+      if ( ( ((l2.x1 <= l1.x1) && (l1.x1 <= l2.x2)) ||    /* X coordinate */
+             ((l2.x2 <= l1.x1) && (l1.x1 <= l2.x1)) ) &&  /*  intersects  */
+           ( ((l1.y1 <= l2.y1) && (l2.y1 <= l1.y2)) ||    /* Y coordinate */
+             ((l1.y2 <= l2.y1) && (l2.y1 <= l1.y1)) ) )   /*  intersects  */
+      {
+         *xint = l1.x1;
+         *yint = l2.y1;
+         return 1;
+      }
+      else
+      {
+         return 0;
+      }
+   }
+
+   if ( (l2.x1==l2.x2) && (l1.y1==l1.y2) )
+   {
+      /* l2 is vertical and l1 is horizontal */
+
+      if ( ( ((l1.x1 <= l2.x1) && (l2.x1 <= l1.x2)) ||    /* X coordinate */
+             ((l1.x2 <= l2.x1) && (l2.x1 <= l1.x1)) ) &&  /*  intersects  */
+           ( ((l2.y1 <= l1.y1) && (l1.y1 <= l2.y2)) ||    /* Y coordinate */
+             ((l2.y2 <= l1.y1) && (l1.y1 <= l2.y1)) ) )   /*  intersects  */
+      {
+         *xint = l2.x1;
+         *yint = l1.y1;
+         return 1;
+      }
+      else
+      {
+         return 0;
+      }
+   }
+
+   if ( (l1.x1==l2.x1) && (l1.y1==l2.y1) ) {
+      *xint = l1.x1;
+      *yint = l1.y1;
+      return 1;
+   }
+   if ( (l1.x2==l2.x2) && (l1.y2==l2.y2) ) {
+      *xint = l1.x2;
+      *yint = l1.y2;
+      return 1;
+   }
+   if ( (l1.x1==l2.x2) && (l1.y1==l2.y2) ) {
+      *xint = l1.x1;
+      *yint = l1.y1;
+      return 1;
+   }
+   if ( (l1.x2==l2.x1) && (l1.y2==l2.y1) ) {
+      *xint = l1.x2;
+      *yint = l1.y2;
+      return 1;
+   }
+
+   if (l1.x1 != l1.x2) {
+      m1 = (l1.y2-l1.y1)/(l1.x2-l1.x1);
+      b1 = -1.0*m1*l1.x1 + l1.y1;
+   } else {  /* l1 is a vertical line */
+      m1 = MAXFLOAT;
+   }
+
+   if (l2.x1 != l2.x2) {
+      m2 = (l2.y2-l2.y1)/(l2.x2-l2.x1);
+      b2 = -1.0*m2*l2.x1 + l2.y1;
+   } else {  /* l2 is a vertical line */
+      m2 = MAXFLOAT;
+   }
+
+
+   /* Find intersection point of lines */
+
+   if ((m1 == m2) && (m1 != MAXFLOAT)) return 0;
+
+   if ( (m1 != MAXFLOAT) && (m2 != MAXFLOAT) ) {
+   /* neither line is a vertical line */
+      *xint = (float)((b2-b1)/(m1-m2));
+      if (m1 == 0)            /* if l1 is a horizontal line */
+       *yint = l1.y1;
+      else
+      {
+       if (m2 == 0)       /* if l2 is a horizontal line */
+	*yint = l2.y1;
+       else
+	*yint = (float)(m1*(*xint)+b1);
+      }
+
+   } else {                   /* At least one vertical line */
+      if (m1==m2) {           /* Both vertical lines */
+	 if (l1.x1==l2.x1) {  /* Coincident vertical lines */
+	    *xint = l1.x1;
+            tempy1 = (float) min( l1.y1, l1.y2 );
+            tempy2 = (float) min( l2.y1, l2.y2 );
+	    *yint = (float) max( tempy1, tempy2 );
+	 } else {             /* Non-coincident vertical lines */
+	    return 0;
+	 }
+      } else if (m1==MAXFLOAT) {   /* l1 is vertical */
+         if ( ((l2.x1 <= l1.x1) && (l2.x2 >= l1.x1)) ||
+              ((l2.x2 <= l1.x1) && (l2.x1 >= l1.x1)) )
+         {
+	  *yint = (float)(m2*l1.x1 + b2);  /* l2 intersects l1 */
+	  *xint = l1.x1;
+         }
+         else
+          return 0;       /* l2 does not intersect l1 */
+
+      } else {                     /* l2 is vertical */
+         if ( ((l1.x1 <= l2.x1) && (l1.x2 >= l2.x1)) ||
+              ((l1.x2 <= l2.x1) && (l1.x1 >= l2.x1)) )
+         {
+          *yint = (float)(m1*l2.x1 + b1);  /* l1 intersects l2 */
+	  *xint = l2.x1;
+         }
+         else
+          return 0;       /* l1 does not intersect l2 */
+
+      }
+   }
+
+   /* See if intersection point lies on both line segments */
+   return ( (*xint >= (float)min(l1.x1,l1.x2)) &&
+	    (*xint <= (float)max(l1.x1,l1.x2)) &&
+	    (*yint >= (float)min(l1.y1,l1.y2)) &&
+	    (*yint <= (float)max(l1.y1,l1.y2)) &&
+	    (*xint >= (float)min(l2.x1,l2.x2)) &&
+	    (*xint <= (float)max(l2.x1,l2.x2)) &&
+	    (*yint >= (float)min(l2.y1,l2.y2)) &&
+	    (*yint <= (float)max(l2.y1,l2.y2)) );
+
+}
+
+
+
+/***************************************************************************
+ *
+ *N  intersect_polygon_edge
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Count the number of intersections between a plum line from the
+ *    test point and infinity and the vertices of the given edge.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    x   <input> == (float) test point x coordinate.
+ *    y   <input> == (float) test point y coordinate.
+ *    edge_rec <input> == (edge_rec_type) given edge.
+ *    intersect_polygon_edge <output> == (int) number of intersection points.
+ *E
+ **************************************************************************/
+int intersect_polygon_edge( float x, float y, edge_rec_type edge_rec )
+{
+   register long int i;
+   line_segment_type lseg, pseg;
+   int n;
+   float xint,yint;
+   coordinate_type coord1,coord2;
+
+   lseg.x1 = x;
+   lseg.y1 = y;
+   lseg.x2 = MAXFLOAT/2.0;
+   lseg.y2 = y;
+
+   n = 0;
+
+   coord1 = first_edge_coordinate(&edge_rec);
+   for (i=1;i<edge_rec.npts;i++) {
+      coord2 = next_edge_coordinate(&edge_rec);
+      pseg.x1 = coord1.x;
+      pseg.y1 = coord1.y;
+      pseg.x2 = coord2.x;
+      pseg.y2 = coord2.y;
+
+      if (intersect(lseg,pseg,&xint,&yint)) {
+	 n++;
+      }
+
+      coord1 = coord2;
+   }
+   return n;
+}
+
+/***************************************************************************
+ *
+ *N  intersect_polygon_loop
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Count the number of intersections of a plum line from the test
+ *    point to infinity and each of the edges in a polygon loop (ring).
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    x  <input> == (float) test point x coordinate.
+ *    y  <input> == (float) test point y coordinate.
+ *    face_id <input> == (int) given polygon loop.
+ *    start_edge <input> == (long int) one edge of the polygon loop.
+ *    edge_table <input> == (vpf_table_type) VPF edge table.
+ *    intersect_polygon_loop <output> == (int) number of intersections.
+ *E
+ **************************************************************************/
+int intersect_polygon_loop( float x, float y,
+			    int face_id, long int start_edge,
+			    vpf_table_type edgetable )
+{
+   edge_rec_type edge_rec;
+   long int next, prevnode;
+   VPF_BOOLEAN done = FALSE;
+   int n;
+
+   edge_rec = read_edge( start_edge, edgetable );
+
+   edge_rec.dir = '+';
+
+   n = intersect_polygon_edge( x, y, edge_rec );
+
+   prevnode = edge_rec.start;
+
+   next = next_polygon_edge(&edge_rec,&prevnode,face_id);
+
+   if (edge_rec.coord) free(edge_rec.coord);
+
+   while (!done) {
+      if (next <= 0) done = TRUE;
+      if (next == start_edge) done = TRUE;
+      if (!done) {
+	 edge_rec = read_edge( next, edgetable );
+
+	 next = next_polygon_edge(&edge_rec,&prevnode,face_id);
+
+	 n += intersect_polygon_edge( x, y, edge_rec );
+
+	 if (edge_rec.coord) free(edge_rec.coord);
+      }
+   }
+
+   return n;
+}
+
+/***************************************************************************
+ *
+ *N  point_in_face
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Test whether a line (x,y through infinity) intersects a face (which
+ *    itself is multiple polygon_loop or ring structures).  Returns a 0
+ *    if outside, 1 if inside.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    x         <input> == (float) x coordinate of given point.
+ *    y         <input> == (float) y coordinate of given point.
+ *    face_id   <input> == (long int) given face.
+ *    facetable <input> == (vpf_table_type) VPF face table.
+ *    ringtable <input> == (vpf_table_type) VPF ring table.
+ *    edgetable <input> == (vpf_table_type) VPF edge table.
+ *    point_in_face <output> == (int) VPF_BOOLEAN:
+ *                                            1 --> inside
+ *                                            0 --> outside
+ *E
+ **************************************************************************/
+int point_in_face( float x, float y,
+		   long int face_id,
+		   vpf_table_type facetable,
+		   vpf_table_type ringtable,
+		   vpf_table_type edgetable )
+{
+   face_rec_type face_rec;
+   ring_rec_type ring_rec;
+   int n;
+
+   face_rec = read_face( face_id, facetable );
+   ring_rec = read_ring( face_rec.ring, ringtable );
+   n = intersect_polygon_loop( x, y, face_id, ring_rec.edge, edgetable );
+
+   while (ring_rec.face == face_id ) {
+      ring_rec = read_next_ring( ringtable );
+
+      if (feof(ringtable.fp)) {
+	 break;
+      }
+
+      if (ring_rec.face == face_id) {
+	 n += intersect_polygon_loop( x, y, face_id,
+				      ring_rec.edge, edgetable );
+      }
+   }
+
+   if (n%2 == 0)   /* Even number of intersections */
+      return 0;    /*   Not inside polygon         */
+   else            /* Odd number of intersections  */
+      return 1;    /*    Inside polygon            */
+}
+
+
+
+static void dirpath( char *path )
+{
+   register unsigned int i;
+
+   i = strlen(path)-1;
+   while ( (i>0) && (path[i] != '\\') ) i--;
+   if (i<(strlen(path)-1)) i++;
+   path[i] = '\0';
+}
+
+/***************************************************************************
+ *
+ *N  point_in_face_table
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Test whether a point is inside a face or not.  Must have a valid path-
+ *   name to a valid VPF Face file, or else be in graphics mode for the error
+ *   message that will result.  Filename must have all directory seperators
+ *   escapes; eg. c:\\vpf    NOT c:\vpf
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *   Parameters:
+ *A
+ *    x        <input> == (float) given point x coordinate.
+ *    y        <input> == (float) given point y coordinate.
+ *    face_id  <input> == (long int) face.
+ *    fname    <input> == (char *) pathname to VPF face file.
+ *    point_in_face_table <output> == VPF_BOOLEAN:
+ *                                            1 --> point is inside
+ *                                            0 --> point is not inside
+ *E
+ **************************************************************************/
+int point_in_face_table( float x, float y,
+			 long int face_id,
+			 char *fname )
+{
+   vpf_table_type facetable, ringtable, edgetable;
+   char *name;
+   int result;
+
+   name = (char *)vpfmalloc( 255*sizeof(char) );
+
+   facetable = vpf_open_table(fname,disk, "rb", NULL );
+
+   strupr(fname);
+
+   strcpy( name, fname );
+   dirpath( name );
+   strcat( name, "RNG" );
+   ringtable = vpf_open_table( name, disk , "rb", NULL );
+
+   strcpy( name, fname );
+   dirpath( name );
+   strcat( name, "EDG" );
+   edgetable = vpf_open_table( name, disk , "rb", NULL );
+
+   free( name );
+
+   result = point_in_face( x, y, face_id, facetable, ringtable, edgetable );
+
+   vpf_close_table(&facetable);
+   vpf_close_table(&ringtable);
+   vpf_close_table(&edgetable);
+
+   return result;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfquery.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfquery.c
new file mode 100644
index 0000000000..2d0aab8eb1
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfquery.c
@@ -0,0 +1,970 @@
+/*************************************************************************
+ *
+ *N  Module VPFQUERY
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions for querying a VPF table with a
+ *     selection expression.  It has one main entry point - query_table().
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                          DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions:
+ *F
+ *    set_type query_table( char *expression, vpf_table_type table );
+ *E
+*************************************************************************/
+
+#include <string.h>
+#include <stdlib.h>
+#if defined(__MSDOS__)
+#include <alloc.h>
+#include <mem.h>
+#include <conio.h>
+#else
+#ifdef MACOSX 
+#include <sys/types.h>
+#include <sys/malloc.h>
+#else
+#include <malloc.h>
+#include <string.h>
+#endif
+#endif
+
+
+#ifndef __MSDOS__
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#endif
+#include <stdio.h>
+#include "linklist.h"
+#include "vpftable.h"
+#include "vpfview.h"
+#include "vpftidx.h"
+#include "set.h"
+
+
+/* Delimiter tokens */
+typedef enum { EQ, NE, LE, GE, LT, GT, AND, OR, QUOTE } delim_type;
+/*static delim_type delim;*/
+
+/* Valid delimeter strings */
+char *delimstr[] = { "=", "<>", "<=", ">=", "<", ">", " AND ",
+		     " OR ", "\"" };
+int ndelim = 9;
+
+char **fieldname;
+int *fieldcol;
+int nfields;
+
+/* Token types */
+#define DELIMETER  1
+#define FIELD      2
+#define VALUE      3
+#define QUOTE      4
+#define STRING     5
+#define EOL        6
+#define FINISHED   7
+#define LOP        8   /* Logical Operator */
+#define JOIN       9
+#define ERROR     10
+
+#ifndef TRUE
+#define TRUE  1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+typedef struct {
+   int field;
+   char op;
+   char value[255];
+   char join;
+} expr_type;
+
+
+static void *memalloc( unsigned long int size )
+{
+   void *ptr;
+
+   ptr = malloc(size);
+   if (!ptr) {
+#ifdef __MSDOS__
+      printf("Memory allocation error in VPFQUERY  (%d)(%d)\n",size,
+	     farcoreleft());
+#else
+      printf("Memory allocation error in VPFQUERY  (%d)\n",(int)size);
+#endif
+      exit(1);
+   }
+   return ptr;
+}
+
+int is_white( char c )
+{
+   if (c==' ' || c=='\t') return 1;
+   return 0;
+}
+
+
+/*************************************************************************
+ *
+ *N  return_token
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the first token string found in the
+ *     expression string.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    expr   <input>==(char *) selection expression string.
+ *    token <output>==(char *) first token in the string.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                          DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+*************************************************************************/
+static void return_token( char *expr, char *token )
+{
+   register int i,j,n,found=0,stopflag;
+
+   n = 0;
+   stopflag=0;
+   while (expr[0] == ' ') {
+      for (i=0;i<ndelim;i++)
+	 if (ossim_strncasecmp(expr,delimstr[i],strlen(delimstr[i])) == 0) {
+	    stopflag=1;
+	    break;
+	 }
+      if (stopflag) break;
+      expr++;
+   }
+   strcpy(token,expr);
+   for (i=0;(unsigned int)i<strlen(token);i++) {
+      for (j=0;j<ndelim;j++) {
+	 if (ossim_strncasecmp(expr,delimstr[j],strlen(delimstr[j]))==0) {
+	    if (n>0)
+	       token[i] = (char)NULL;
+	    else
+	       token[strlen(delimstr[j])] = (char)NULL;
+	    found = 1;
+	    break;
+	 }
+      }
+      if ((found) || (!is_white(*expr))) n++;
+      if ((!found)&&(*expr)) expr++;
+/*      if (!is_white(*expr)) n++;  */
+/*      if ((found) || (!is_white(*expr))) n++; */
+      if (found) break;
+   }
+}
+
+
+
+
+/*************************************************************************
+ *
+ *N  get_token
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function gets the first token, token type, and token value of
+ *     the expression string, and then advances the expression string
+ *     past the token.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    expression   <input>==(char *) selection expression string.
+ *    token       <output>==(char *) first token in the string.
+ *    token_type  <output>==(int *) token type.
+ *    token_value <output>==(int *) token_value.
+ *    return      <output>==(char *) new selection expression.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                          DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    static void return_token( char *expr, char *token ) VPFQUERY.C
+ *E
+ *************************************************************************/
+static char *get_token( char *expression,
+		 char *token, int *token_type, int *token_value )
+{
+   register int i, stopflag;
+
+   *token_type = (int)NULL;
+
+   if (*expression == (char)NULL) {
+      *token_type = FINISHED;
+      *token_value = (int)NULL;
+      return expression;
+   }
+
+   if (*expression=='\r') {  /* crlf */
+      ++expression; ++expression;
+      *token = '\r';
+      token[1] = '\n';
+      token[2] = 0;
+      *token_type = DELIMETER;
+   }
+
+   stopflag = 0;
+   while ((expression[0] == '\"') || (expression[0] == ' ')) {
+      for (i=0;i<ndelim;i++)
+	 if (ossim_strncasecmp(expression,delimstr[i],strlen(delimstr[i]))==0) {
+	    stopflag=1;
+	    break;
+	 }
+      if (stopflag) break;
+      expression++;
+   }
+
+   return_token( expression, token );
+   expression += strlen(token);
+
+   if (*token == (char)NULL) {
+      *token_type = FINISHED;
+      *expression = (char)NULL;
+      return expression;
+   }
+
+   leftjust(token);
+   rightjust(token);
+
+   if (ossim_strcasecmp(token,"AND")==0) {
+      strupr(token);
+      *token_type = JOIN;
+      *token_value = AND;
+      while ((expression[0] == '\"') || (expression[0] == ' ')) expression++;
+      return expression;
+   }
+
+   if (ossim_strcasecmp(token,"OR")==0) {
+      strupr(token);
+      *token_type = JOIN;
+      *token_value = OR;
+      while ((expression[0] == '\"') || (expression[0] == ' ')) expression++;
+      return expression;
+   }
+
+   if (token[0] == '"') {   /* quoted string */
+      if (*expression) expression++;
+      i = 0;
+      while (*expression != '"') {
+	 token[i] = *expression;
+	 i++;
+	 expression++;
+	 if (*expression == (char)NULL) {
+	    *token_type = ERROR;
+	    *token_value = ERROR;
+	    return expression;
+	 }
+      }
+
+      while ((expression[0] == '\"') || (expression[0] == ' '))
+	 expression++;
+      token[i] = '\0';
+      *token_type = STRING;
+      *token_value = strlen(token);
+      return expression;
+   }
+
+   for (i=0;i<ndelim;i++) {
+      if (ossim_strcasecmp(token,delimstr[i])==0) {
+	 *token_type = LOP;
+	 *token_value = i;
+	 return expression;
+      }
+   }
+
+   for (i=0;i<nfields;i++) {
+      if (ossim_strcasecmp(token,fieldname[i])==0) {
+	 strupr(token);
+	 *token_type = FIELD;
+	 *token_value = i;
+	 return expression;
+      }
+   }
+
+   *token_type = VALUE;
+   *token_value = (int)NULL;
+   return expression;
+}
+
+
+/*************************************************************************
+ *
+ *N  parse_expression
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns a list of selection expression clause
+ *     structures.  This list forms the internal structure of the query
+ *     expression.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    expression   <input>==(char *) selection expression string.
+ *    table        <input>==(vpf_table_type) VPF table structure.
+ *    return      <output>==(linked_list_type) list of expression clauses.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                          DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    char *get_token( char *expression, char *token, int *token_type,
+ *    int *token_value) VPFQUERY.C
+ *    void display_message( char *input) USER DEFINED
+ *    linked_list_type ll_init() LINKLIST.C
+ *    void ll_reset( linked_list_type list ) LINKLIST.C
+ *    void ll_insert( void *element, unsigned size,
+ *    position_type position ) LINKLIST.C
+ *E
+ *************************************************************************/
+static linked_list_type parse_expression( char *expression, vpf_table_type table )
+{
+   linked_list_type exprlist;
+   position_type pos;
+   expr_type expr;
+   int i, token_type, token_value;
+   char token[260];
+
+   exprlist = ll_init();
+   pos = exprlist;
+
+   /* Set up static globals */
+
+   nfields = table.nfields;
+
+   fieldname = (char **)memalloc( (nfields+2) * sizeof(char *) );
+   fieldcol = (int *)memalloc( (nfields+2) * sizeof(int) );
+
+   for (i=0;i<table.nfields;i++) {
+      fieldname[i] = (char *)memalloc(40*sizeof(char));
+      strcpy(fieldname[i], table.header[i].name);
+      fieldcol[i] = i;
+   }
+
+   /*****/
+
+   expression = get_token( expression, token, &token_type, &token_value );
+   while (token_type != FINISHED) {
+      if (token_type != FIELD) {
+	 display_message("Expression syntax error -- Invalid field name");
+	 ll_reset(exprlist);
+	 exprlist = NULL;
+	 break;
+      }
+      expr.field = token_value;
+
+      expression = get_token( expression, token, &token_type, &token_value );
+      if (token_type != LOP) {
+	 display_message("Expression syntax error");
+	 ll_reset(exprlist);
+	 exprlist = NULL;
+	 break;
+      }
+      expr.op = (char)token_value;
+
+      expression = get_token( expression, token, &token_type, &token_value );
+      if (token_type == ERROR) {
+	 display_message("Expression syntax error");
+	 ll_reset(exprlist);
+	 exprlist = NULL;
+	 break;
+      }
+      strcpy(expr.value,token);
+
+      expression = get_token( expression, token, &token_type, &token_value );
+      if (token_type == JOIN) {
+	 expr.join = (char)token_value;
+	 ll_insert( &expr, sizeof(expr), pos );
+	 pos = pos->next;
+	 expression = get_token( expression, token, &token_type,
+				 &token_value );
+      } else if (token_type == FINISHED) {
+	 expr.join = (char)NULL;
+	 ll_insert( &expr, sizeof(expr), pos );
+      } else {
+	 display_message("Expression syntax error");
+	 ll_reset(exprlist);
+	 exprlist = NULL;
+	 break;
+      }
+   }
+
+   for (i=0;i<nfields;i++) free(fieldname[i]);
+   free(fieldname);
+   free(fieldcol);
+
+   return exprlist;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  comp
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function is a general comparison function for comparing two
+ *     buffers.  NOTE:  This function compares the bytes of the buffers
+ *     as unsigned characters.  Numeric values > 255 should not be
+ *     compared with this function.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    val1    <input>==(void *) first buffer to compare.
+ *    val2    <input>==(void *) second buffer to compare.
+ *    size    <input>==(int) number of bytes to compare.
+ *    op      <input>==(char) logical operator.
+ *    return <output>==(int) TRUE or FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                          DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+static int comp( void *val1, void *val2, int size, char op )
+{
+   int result;
+
+   result = memcmp(val1,val2,size);
+
+   switch (op) {
+      case EQ:
+	 result = !result;
+	 break;
+      case NE:
+	 break;
+      case LT:
+	 if (result < 0)
+	    result = TRUE;
+	 else
+	    result = FALSE;
+	 break;
+      case LE:
+	 if (result <= 0)
+	    result = TRUE;
+	 else
+	    result = FALSE;
+	 break;
+      case GT:
+	 if (result > 0)
+	    result = TRUE;
+	 else
+	    result = FALSE;
+	 break;
+      case GE:
+	 if (result >= 0)
+	    result = TRUE;
+	 else
+	    result = FALSE;
+	 break;
+      default:
+	 printf("Invalid logical operator (%d)\n",op);
+	 result = FALSE;
+	 break;
+   }
+   return result;
+}
+
+
+/*************************************************************************
+ *
+ *N  strcompare
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function compares two strings with the given logical operator.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    val1    <input>==(char *) first buffer to compare.
+ *    val2    <input>==(char *) second buffer to compare.
+ *    op      <input>==(char) logical operator.
+ *    return <output>==(int) TRUE or FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                          DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+static int strcompare( char *val1, char *val2, char op )
+{
+   int result;
+   char str1[300], str2[300];
+
+   strcpy(str1,val1);
+   rightjust(str1);
+   strcpy(str2,val2);
+   rightjust(val2);
+
+   result = ossim_strcasecmp(str1,str2);
+
+   switch (op) {
+      case EQ:
+	 result = !result;
+	 break;
+      case NE:
+	 break;
+      case LT:
+	 if (result < 0)
+	    result = TRUE;
+	 else
+	    result = FALSE;
+	 break;
+      case LE:
+	 if (result <= 0)
+	    result = TRUE;
+	 else
+	    result = FALSE;
+	 break;
+      case GT:
+	 if (result > 0)
+	    result = TRUE;
+	 else
+	    result = FALSE;
+	 break;
+      case GE:
+	 if (result >= 0)
+	    result = TRUE;
+	 else
+	    result = FALSE;
+	 break;
+      default:
+	 printf("Invalid logical operator (%d)\n",op);
+	 result = FALSE;
+	 break;
+   }
+   return result;
+}
+
+
+/*************************************************************************
+ *
+ *N  icompare
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function compares two long integers with the given logical
+ *     operator.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    val1    <input>==(long int) first buffer to compare.
+ *    val2    <input>==(long int) second buffer to compare.
+ *    op      <input>==(char) logical operator.
+ *    return <output>==(int) TRUE or FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                          DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+static int icompare( long int val1, long int val2, char op )
+{
+   int result;
+
+   switch (op) {
+      case EQ:
+	 result = (val1 == val2);
+	 break;
+      case NE:
+	 result = (val1 != val2);
+	 break;
+      case LT:
+	 result = (val1 < val2);
+	 break;
+      case LE:
+	 result = (val1 <= val2);
+	 break;
+      case GT:
+	 result = (val1 > val2);
+	 break;
+      case GE:
+	 result = (val1 >= val2);
+	 break;
+      default:
+	 printf("Invalid logical operator (%d)\n",op);
+	 result = FALSE;
+	 break;
+   }
+   return result;
+}
+
+
+/*************************************************************************
+ *
+ *N  fcompare
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function compares two floating point numbers with the given
+ *     logical operator.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    val1    <input>==(long int) first buffer to compare.
+ *    val2    <input>==(long int) second buffer to compare.
+ *    op      <input>==(char) logical operator.
+ *    return <output>==(int) TRUE or FALSE.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                          DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *************************************************************************/
+static int fcompare( float val1, float val2, char op )
+{
+   int result;
+
+   switch (op) {
+      case EQ:
+	 result = (val1 == val2);
+	 break;
+      case NE:
+	 result = (val1 != val2);
+	 break;
+      case LT:
+	 result = (val1 < val2);
+	 break;
+      case LE:
+	 result = (val1 <= val2);
+	 break;
+      case GT:
+	 result = (val1 > val2);
+	 break;
+      case GE:
+	 result = (val1 >= val2);
+	 break;
+      default:
+	 printf("Invalid logical operator (%d)\n",op);
+	 result = FALSE;
+	 break;
+   }
+   return result;
+}
+
+
+/*************************************************************************
+ *
+ *N  query_table
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the set of selected rows of a VPF table
+ *     based upon the evaluation of the given selection expression string.
+ *
+ *     The expression is strictly evaluated left to right.  No nesting
+ *     is supported, so parentheses are not allowed.  The expression
+ *     must match the form:
+ *        <field><log op><value> [ <join> <field><log op><value>]
+ *     where,
+ *        <field> is a valid field name of the table.
+ *        <log op> is one of the following: =, <, >, <=, >=, <> (not equal).
+ *        <value> is a valid value for the field.
+ *        <join> is either " AND " or " OR ".
+ *     Any number of clauses (<field><log op><value>) may be joined
+ *     together with AND or OR to form the expression.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    expression <input>==(char *) selection expression string.
+ *    table      <input>==(vpf_table_type) VPF table structure.
+ *    return    <output>==(set_type) set of selected rows.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                          DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    set_type set_init( long int n ) SET.C
+ *    void set_insert( long int element, set_type set ) SET.C
+ *    linked_list_type parse_expression( char *expression,
+ *                     vpf_table_type table ) VPFQUERY.C
+ *    row_type read_next_row( vpf_table_type table ) VPFREAD.C
+ *    position_type ll_first( linked_list_type list ) LINKLIST.C
+ *    int ll_end( position_type position ) LINKLIST.C
+ *    void ll_element( position_type position, void *element ) LINKLIST.C
+ *    void *get_table_element( long int field_number,
+ * 			 row_type row,
+ *			 vpf_table_type table,
+ *			 void *value,
+ *			 long int  *count ) VPFREAD.C
+ *    void display_message( char *info ) USER DEFINED
+ *    static int strcompare( char *val1, char *val2, char op ) VPFQUERY.C
+ *    static int icompare( long int val1, long int val2, char op ) VPFQUERY.C
+ *    static int fcompare( float val1, float val2, char op ) VPFQUERY.C
+ *    void ll_reset( linked_list_type list ) LINKLIST.C
+      void free_row( row_type row, vpf_table_type table) VPFREAD.C
+ *E
+ *************************************************************************/
+set_type query_table( char *expression, vpf_table_type table )
+{
+   row_type row;
+   position_type pos;
+   expr_type expr;
+   register long int i;
+   int boolval=FALSE, booltemp=0, join = OR;
+   long int lval, lval2, count;
+   float fval, fval2;
+   char tval, tval2, *tptr;
+   linked_list_type exprlist;
+   set_type select_set;
+
+   select_set = set_init(table.nrows+1);
+
+   if (strcmp(expression,"*")==0) {
+      set_on(select_set);
+      return select_set;
+   }
+
+   exprlist = parse_expression( expression, table );
+
+   if (!exprlist) return select_set;
+
+   if (table.storage == DISK)
+      fseek( table.fp, index_pos(1,table), SEEK_SET );
+
+   for (i=1;i<=table.nrows;i++) {
+
+      if (table.storage == DISK)
+	 row = read_next_row(table);
+      else
+	 row = get_row( i, table );
+
+      pos = ll_first(exprlist);
+      while (!ll_end(pos)) {
+	 ll_element( pos, &expr );
+	 switch (table.header[expr.field].type) {
+	    case 'I':
+	       if (table.header[expr.field].count == 1) {
+		  get_table_element( expr.field, row, table, &lval, &count );
+		  lval2 = atol(expr.value);
+		  booltemp = icompare( lval, lval2, expr.op );
+	       } else {
+		  display_message(
+		     "Selection may not be performed upon arrays");
+		  i=table.nrows+1;
+	       }
+	       break;
+	    case 'T':
+	       if (table.header[expr.field].count == 1) {
+		  get_table_element( expr.field, row, table, &tval, &count );
+		  tval2 = expr.value[0];
+		  booltemp = comp( &tval, &tval2, sizeof(tval), expr.op );
+	       } else {
+		  tptr = (char *)get_table_element( expr.field, row, table,
+				   NULL, &count );
+		  booltemp = strcompare( tptr, expr.value, expr.op );
+		  free(tptr);
+	       }
+	       break;
+	    case 'F':
+	       if (table.header[expr.field].count == 1) {
+		  get_table_element( expr.field, row, table, &fval, &count );
+		  if (!is_vpf_null_float(fval)) {
+		     fval2 = (float)atof(expr.value);
+		     booltemp = fcompare( fval, fval2, expr.op );
+		  } else booltemp = FALSE;
+	       } else {
+		  display_message(
+		     "Selection may not be performed upon arrays");
+		  i=table.nrows+3;
+	       }
+	       break;
+	    default:
+	       display_message("Field type not supported for query");
+	       i=table.nrows+3;
+	       break;
+	 }
+
+	 if (i>table.nrows) break;
+
+	 if (join==OR)
+	    boolval = boolval || booltemp;
+	 else
+	    boolval = boolval && booltemp;
+
+	 join = expr.join;
+
+	 pos = pos->next;
+      }
+      free_row( row, table );
+      if (boolval) set_insert(i,select_set);
+      boolval = FALSE;
+      join = OR;
+
+      if (i==table.nrows+3) break;
+
+   }
+
+   ll_reset(exprlist);
+
+   return select_set;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfread.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfread.c
new file mode 100644
index 0000000000..fce8a7ce87
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfread.c
@@ -0,0 +1,1641 @@
+/*************************************************************************
+ *
+ *N  Module VPFREAD.C
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions for reading VPF tables.  It, along
+ *     with VPFTABLE.C and VPFWRITE.C (and VPFIO.C for UNIX), comprises a
+ *     fairly extensive set of functions for handling VPF tables.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991  Original Version   DOS Turbo C
+ *    David Flinn      Jul 1991	 Merged with Barry & Mody's code for UNIX
+ *    Jim TenBrink     Oct 1991  Split this module off from vpftable and
+ *                               merged converter and vpfview branches
+ *                               for the functions included here..
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.  It includes #ifdefs for
+ *    all system dependencies, so that it will work efficiently with
+ *    either Turbo C in DOS or (at least) GNU C in UNIX.
+ *E
+ *
+ *************************************************************************/
+
+#include "machine.h"
+
+#ifdef __MSDOS__
+#include <mem.h>
+#include <io.h>
+#include <alloc.h>
+#include <dos.h>
+#include <graphics.h>
+#else
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#endif
+
+#if UNIX
+#include <sys/stat.h>
+#define   SEEK_SET    0         /* Turbo C fseek value */
+#define   SEEK_CUR    1
+#define   farmalloc   malloc    /* no farmallocs on UNIX */
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "vpftable.h"
+#include "vpfmisc.h"
+
+extern int STORAGE_BYTE_ORDER;
+
+
+/* Repeat functions statically to reduce external module dependencies */
+
+/*
+ * currently being used by the converter routines, not by the vpfview
+ * routines
+ */
+static char * get_line (FILE *fp)
+{
+  long int CurrentChar,   /* This is an int because fgetc returns an int */
+      count ,
+      NextBlock = 256 ,
+      LineAllocation = 0 ;
+  char *CurrentLine = (char *) NULL ;
+
+/* This forever loop searches past all lines beginning with #,
+   indicating comments. */
+
+  for (;;) {
+      CurrentChar = fgetc(fp);
+      if ( CurrentChar == COMMENT )             /* skip past comment line */
+        for (;CurrentChar != NEW_LINE; ) {
+          if (CurrentChar == EOF) return (char *) NULL ;
+          CurrentChar = fgetc (fp) ;
+        }
+      else
+        break ;
+    }  /* end of forever loop */
+
+  if (CurrentChar == EOF ) return (char *) NULL ;
+
+  for(count = 0; CurrentChar != EOF; CurrentChar = fgetc(fp), count++) {
+
+    /* Allocate space for output line, if needed */
+ 
+    if (! ( count < LineAllocation )) {
+      LineAllocation += NextBlock ;
+      if ( CurrentLine )
+        CurrentLine = (char *) realloc ( CurrentLine, LineAllocation );
+      else
+        CurrentLine = (char *) vpfmalloc ( LineAllocation );
+      if (!CurrentLine) {
+        return (char *) NULL ;
+      }
+    }  
+    if ( ( CurrentChar == (long int) LINE_CONTINUE ) ) {
+      CurrentChar = fgetc(fp ) ;        /* read character after backslash */
+      /* A newline will be ignored and thus skipped over */
+      if ( CurrentChar == (long int) SPACE )  /* Assume line continue error */
+        while ( fgetc (fp) != (long int) SPACE ) ;
+      else if (CurrentChar != (long int) NEW_LINE ) {
+        /* copy it if not new line */
+        CurrentLine[count++] = (char) LINE_CONTINUE ;
+        CurrentLine[count] = (char) CurrentChar ;
+      } else
+        count -- ;      /* Decrement the counter on a newline character */
+    } else if (CurrentChar == (long int) NEW_LINE )     /* We're done */
+        break;
+    else
+      CurrentLine[count] = (char)CurrentChar;
+
+  }  /* end of for count */
+
+  CurrentLine[count] = (char) NULL ;  /* terminate string */
+  return CurrentLine ;
+
+}
+
+
+/* #if UNIX */
+
+long int VpfRead ( void *to, VpfDataType type, long int count, FILE *from )
+{
+  long int retval=0 , i ;
+
+  switch ( type ) {
+  case VpfChar:
+    retval = fread ( to, sizeof (char), count, from ) ;
+    break ;
+  case VpfShort:
+    {
+      short int stemp ,
+                *sptr = (short *) to ;
+      for ( i=0; i < count; i++ ) {
+	retval = fread ( &stemp, sizeof (short), 1, from ) ;
+	if (STORAGE_BYTE_ORDER != MACHINE_BYTE_ORDER)
+	   swap_two ( (char*)&stemp, (char*)sptr ) ;
+	else
+	   *sptr = stemp;
+        sptr++ ;
+      }
+    }  
+    break ;
+  case VpfInteger:
+    {
+      if (STORAGE_BYTE_ORDER != MACHINE_BYTE_ORDER) {
+	long int itemp,
+	  *iptr = (long int *) to ;
+	for ( i=0; i < count; i++ ) {
+	  retval = fread ( &itemp, sizeof (long int), 1, from ) ;
+	  swap_four ( (char*)&itemp, (char*)iptr ) ;
+	  iptr++ ;
+	}
+      } else {
+	retval = fread ( to, sizeof (long int), count, from ) ;
+      }
+    }  
+    break ;
+  case VpfFloat:
+    {
+      float ftemp ,
+            *fptr = (float *) to ;
+      for ( i=0; i < count; i++ ) {
+        retval = fread ( &ftemp, sizeof (float), 1, from ) ;
+	if (STORAGE_BYTE_ORDER != MACHINE_BYTE_ORDER)
+	   swap_four ( (char*)&ftemp, (char*)fptr ) ;
+	else
+	   *fptr = ftemp;
+	fptr++ ;
+      }
+    }
+    break ;
+  case VpfDouble:
+    {
+      double dtemp ,
+             *dptr = (double *) to ;
+      for ( i=0; i < count; i++ ) {
+        retval = fread ( &dtemp, sizeof (double), 1, from ) ;
+	if (STORAGE_BYTE_ORDER != MACHINE_BYTE_ORDER)
+	   swap_eight ( (char*)&dtemp, (char*)dptr ) ;
+	else
+	   *dptr = dtemp;
+	dptr++ ;
+      }
+    }
+    break ;
+  case VpfDate:
+    {
+      date_type *dp = (date_type *) to ;
+      retval = fread(dp,sizeof(date_type)-1,count,from);
+    }
+    break ;
+  case VpfCoordinate:
+    {
+      if (STORAGE_BYTE_ORDER != MACHINE_BYTE_ORDER) {
+	 coordinate_type ctemp ,
+		      *cptr = (coordinate_type *) to ;
+	 for ( i=0; i < count; i++ ) {
+	   retval = fread ( &ctemp, sizeof (coordinate_type), 1, from ) ;
+	   swap_four ( (char*)&ctemp.x, (char*)&cptr->x ) ;
+	   swap_four ( (char*)&ctemp.y, (char*)&cptr->y ) ;
+	   cptr++ ;
+	 }
+      } else {
+	 retval = fread ( to, sizeof (coordinate_type), count, from ) ;
+      }
+    }  
+    break ;
+  case VpfDoubleCoordinate:
+    {
+      double_coordinate_type dctemp ,
+                             *dcptr = (double_coordinate_type *) to ;
+      for ( i=0; i < count; i++ ) {
+        retval = fread ( &dctemp, sizeof (double_coordinate_type), 1, from ) ;
+	if (STORAGE_BYTE_ORDER != MACHINE_BYTE_ORDER) {
+	   swap_eight ( (char*)&dctemp.x, (char*)&dcptr->x ) ;
+	   swap_eight ( (char*)&dctemp.y, (char*)&dcptr->y ) ;
+	} else {
+	   dcptr->x = dctemp.x;
+	   dcptr->y = dctemp.y;
+	}
+	dcptr++ ;
+      }
+    }
+    break ;
+  case VpfTriCoordinate:
+    {
+      tri_coordinate_type ttemp ,
+                          *tptr = (tri_coordinate_type *) to ;
+      for ( i=0; i < count; i++ ) {
+        retval = fread ( &ttemp, sizeof (tri_coordinate_type), 1, from ) ;
+	if (STORAGE_BYTE_ORDER != MACHINE_BYTE_ORDER) {
+	   swap_four ( (char*)&ttemp.x, (char*)&tptr->x ) ;
+	   swap_four ( (char*)&ttemp.y, (char*)&tptr->y ) ;
+	   swap_four ( (char*)&ttemp.z, (char*)&tptr->z ) ;
+	} else {
+	   tptr->x = ttemp.x;
+	   tptr->y = ttemp.y;
+	   tptr->z = ttemp.z;
+	}
+	tptr++ ;
+      }
+    }
+    break ;
+  case VpfDoubleTriCoordinate:
+    {
+      double_tri_coordinate_type dttemp ,
+                                 *dtptr = (double_tri_coordinate_type *) to ;
+      for ( i=0; i < count; i++ ) {
+        retval = fread ( &dttemp,sizeof (double_tri_coordinate_type), 1, from);
+	if (STORAGE_BYTE_ORDER != MACHINE_BYTE_ORDER) {
+	   swap_eight ( (char*)&dttemp.x, (char*)&dtptr->x ) ;
+	   swap_eight ( (char*)&dttemp.y, (char*)&dtptr->y ) ;
+	   swap_eight ( (char*)&dttemp.z, (char*)&dtptr->z ) ;
+	} else {
+	   dtptr->x = dttemp.x;
+	   dtptr->y = dttemp.y;
+	   dtptr->z = dttemp.z;
+	}
+	dtptr++ ;
+      }
+    }  
+    break ;
+  case VpfNull:
+    /* Do Nothing */
+    break ;
+  default:
+    break ;
+  }   /* end of switch */
+
+  return retval ;       /* whatever fread returns */
+
+}
+
+/* #endif */
+
+
+
+/*************************************************************************
+ *
+ *N  read_text_defstr
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads the definition string from an input file for
+ *     creating a VPF table.
+ *     Currently being used by converter routines, not by vpfview routines.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    infile  <input> == (FILE *) file pointer to the input file.
+ *    outerr  <input> == (FILE *) file pointer to the error file.
+ *    return <output> == (char *) definition string of the file.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       July 1991      Original version developed for UNIX
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    get_line()
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+char *read_text_defstr ( FILE *infile, FILE *outerr )
+{
+  char *definition ;
+
+  rewind ( infile );
+
+  if (( (definition = get_line (infile )) == NULL ) ||
+      ( definition[strlen(definition)-1] != ';' )) {
+    return (char *) NULL ;
+  }
+
+  return definition ;
+
+}
+
+#if UNIX
+/*
+ * currently being used by converter routines, not by vpfview
+ * routines
+ */
+int add_null_values ( char *name, vpf_table_type table, FILE *fpout )
+{
+  FILE *nullfp;
+  long int  i , ptr ;
+  char *cval, *line, *field ;
+ 
+  nullfp = fopen( name, "r");
+  if ( !nullfp )
+    return 0;
+ 
+  /* Now read nulls from file and populate table structure */
+
+  while ( (line = get_line ( nullfp )) ) {
+ 
+    ptr = 0 ;
+    field = get_string ( &ptr, line, FIELD_SEPERATOR ) ;
+    i = table_pos ( field, table ) ;
+ 
+    switch ( table.header[i].type ) {
+    case 'T':
+      cval = get_string ( &ptr, line, FIELD_SEPERATOR ) ;
+      free ( table.header[i].nullval.Char ) ;   /* get rid of default */
+      table.header[i].nullval.Char = (char *) vpfmalloc ( strlen (cval)+1) ;
+      strcpy ( table.header[i].nullval.Char, cval ) ;
+      free (cval) ;
+      break ;
+    case 'I':
+      table.header[i].nullval.Int = get_number ( &ptr, line, FIELD_SEPERATOR );
+      break ;
+    case 'S':
+      table.header[i].nullval.Short =
+        (short int) get_number ( &ptr, line, FIELD_SEPERATOR );
+      break ;
+    case 'R':
+      cval = get_string ( &ptr, line, FIELD_SEPERATOR ) ;
+      table.header[i].nullval.Double = atof ( cval ) ;
+      free ( cval ) ;
+      break ;
+    case 'F':
+      cval = get_string ( &ptr, line, FIELD_SEPERATOR ) ;
+      table.header[i].nullval.Float = (float) atof ( cval ) ;
+      free ( cval ) ;
+      break ;
+    default:
+      return 0 ;
+      break ;
+    }
+  }
+
+  return 1 ;
+}
+#endif
+
+/*************************************************************************
+ *
+ *N  index_length
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the length of a specified row from the table
+ *     index.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    row_number <input> == (long int) row number in the table.
+ *    table      <input> == (vpf_table_type) VPF table structure.
+ *    return    <output> == (long int) length of the table row or 0 on error.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991       Original Version   DOS Turbo C
+ *    Dave Flinn       July 1991      UNIX extensions
+ *    JTB              10/91          removed aborts()
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+long int index_length( long int row_number,
+		       vpf_table_type table )
+{
+   long int   recsize,len=0;
+   unsigned long int ulen;
+   long  int pos;
+
+   STORAGE_BYTE_ORDER = table.byte_order;
+
+   if (row_number < 1) row_number = 1;
+   if (row_number > table.nrows) row_number = table.nrows;
+
+   switch (table.xstorage) {
+      case COMPUTE:
+	 len = table.reclen;
+	 break;
+      case DISK:
+	 recsize = sizeof(index_cell);
+	 fseek( table.xfp, (long int)(row_number*recsize), SEEK_SET );
+
+	 if ( ! Read_Vpf_Int(&pos,table.xfp,1) ) {
+	   len = (long int)NULL ;
+	 }
+
+	 if ( ! Read_Vpf_Int(&ulen,table.xfp,1) ) {
+	   return (long int)NULL ;
+	 }
+	 len = ulen;
+	 break;
+      case RAM:
+	 len = table.index[row_number-1].length;
+	 break;
+      default:
+	if ( table.mode == Write && table.nrows != row_number ) {
+	   /* Just an error check, should never get here in writing */
+	   fprintf(stderr,"\nindex_length: error trying to access row %d",
+		   (int)row_number ) ;
+	   len = (long int)NULL ;
+	}
+	break;
+   }
+   return len;
+}
+
+/*************************************************************************
+ *
+ *N  index_pos
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the position of a specified row from the table
+ *     index.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    row_number <input> == (long int) row number in the table.
+ *    table      <input> == (vpf_table_type) VPF table structure.
+ *    return    <output> == (long int) position of the table row 
+ *                          or zero on error.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991       Original Version   DOS Turbo C
+ *    Dave Flinn       July 1991      Updated for UNIX
+ *    JTB              10/91          removed aborts()
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+long int index_pos( long int row_number,
+		    vpf_table_type table )
+{
+   long int   recsize;
+   unsigned long int pos;
+
+   STORAGE_BYTE_ORDER = table.byte_order;
+
+   if (row_number < 1) row_number = 1;
+   if (row_number > table.nrows) row_number = table.nrows;
+
+   switch (table.xstorage) {
+      case COMPUTE:
+	 pos = table.ddlen + ((row_number-1) * table.reclen);
+	 break;
+      case DISK:
+	 recsize = sizeof(index_cell);
+	 fseek( table.xfp, (long int)(row_number*recsize), SEEK_SET );
+	 if ( ! Read_Vpf_Int(&pos,table.xfp,1) ) {
+	   pos = (unsigned long int)NULL ;
+	 }
+	 break;
+      case RAM:
+	 pos = table.index[row_number-1].pos;
+	 break;
+      default:
+	 if ( table.mode == Write && table.nrows != row_number ) {
+	   /* Just an error check, should never get here in writing */
+	   fprintf(stderr,"\nindex_length: error trying to access row %d",
+		   (int)row_number ) ;
+	   pos = (unsigned long int)NULL;
+	 }
+	 break;
+   }
+   return pos;
+}
+
+#if 0
+/* Compute the offset from the start of the row to the given field */
+static long int row_offset( int field, row_type row, vpf_table_type table)
+{
+   long int offset,n,size;
+   int i;
+   id_triplet_type key;
+   int keysize[] = {0,sizeof(char),sizeof(short int),sizeof(long int)};
+
+   if (field < 0 || field >= table.nfields) return -1;
+
+   offset = 0L;
+   for (i=0;i<field;i++) {
+      switch (table.header[i].type) {
+	 case 'I':
+	    offset += sizeof(long int)*row[i].count;
+	    break;
+	 case 'S':
+	    offset += sizeof(short int)*row[i].count;
+	    break;
+	 case 'T':
+	    offset += sizeof(char)*row[i].count;
+	    break;
+	 case 'F':
+	    offset += sizeof(float)*row[i].count;
+	    break;
+	 case 'D':
+	    offset += sizeof(date_type)*row[i].count;
+	    break;
+	 case 'K':
+	    get_table_element(i,row,table,&key,&n);
+	    size = sizeof(char) +
+		   keysize[TYPE0(key.type)] +
+		   keysize[TYPE1(key.type)] +
+		   keysize[TYPE2(key.type)];
+	    offset += size*row[i].count;
+	    break;
+	 case 'R':
+	    offset += sizeof(double)*row[i].count;
+	    break;
+	 case 'C':
+	    offset += sizeof(coordinate_type)*row[i].count;
+	    break;
+	 case 'B':
+	    offset += sizeof(double_coordinate_type)*row[i].count;
+	    break;
+	 case 'Z':
+	    offset += sizeof(tri_coordinate_type)*row[i].count;
+	    break;
+	 case 'Y':
+	    offset += sizeof(double_tri_coordinate_type)*row[i].count;
+	    break;
+      }
+   }
+   return offset;
+}
+#endif
+
+/*************************************************************************
+ *
+ *N  read_key
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads an id triplet key from a VPF table.
+ *     The table must be open for read.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    table    <input>  == (vpf_table_type) VPF table.
+ *    read_key <output> == (id_triplet_type) id triplet key.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991       Original Version   DOS Turbo C
+ *    Dave Flinn       July 1991      Updated for UNIX
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+id_triplet_type read_key( vpf_table_type table )
+{
+   id_triplet_type key;
+   unsigned char ucval;
+   unsigned short int uival;
+
+   STORAGE_BYTE_ORDER = table.byte_order;
+
+   key.id = 0L;
+   key.tile = 0L;
+   key.exid = 0L;
+
+   /* just doing this to be consistent */
+   Read_Vpf_Char (&(key.type),table.fp,1);
+
+   switch (TYPE0(key.type)) {
+      case 0:
+	 break;
+      case 1:
+
+	 Read_Vpf_Char (&ucval, table.fp, 1 ) ;
+	 key.id = (long int)ucval;
+	 break;
+      case 2:
+
+	 Read_Vpf_Short (&uival, table.fp, 1 ) ;
+	 key.id = (long int)uival;
+	 break;
+      case 3:
+
+	 Read_Vpf_Int (&(key.id), table.fp, 1 ) ;
+	 break;
+   }
+   switch (TYPE1(key.type)) {
+   case 0:
+     break;
+   case 1:
+     Read_Vpf_Char (&ucval, table.fp, 1 ) ;
+     key.tile = (long int)ucval;
+     break;
+   case 2:
+     Read_Vpf_Short (&uival, table.fp, 1 ) ;
+     key.tile = (long int)uival;
+     break;
+   case 3:
+     Read_Vpf_Int (&(key.tile), table.fp, 1 ) ;
+     break;
+   }
+
+   switch (TYPE2(key.type)) {
+   case 0:
+     break;
+   case 1:
+     Read_Vpf_Char (&ucval, table.fp, 1 ) ;
+     key.exid = (long int)ucval;
+     break;
+   case 2:
+     Read_Vpf_Short (&uival, table.fp, 1 ) ;
+     key.exid = (long int)uival;
+     break;
+   case 3:
+     Read_Vpf_Int (&(key.exid), table.fp, 1 ) ;
+     break;
+   }
+
+   return key;
+ }
+
+/*************************************************************************
+ *
+ *N  read_next_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads the next row of the table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    table      <input> == (vpf_table_type) vpf table structure.
+ *    return    <output> == (row_type) the next row in the table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991       Original Version   DOS Turbo C
+ *    Dave Flinn       July 1991      Updated for UNIX
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void *vpfmalloc()
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+row_type read_next_row( vpf_table_type table )
+{
+   register long int i,j;
+   long int      status;
+   char     *tptr;
+   long int size,count;
+   row_type row;
+   id_triplet_type * keys;
+   coordinate_type dummycoord;
+
+   if (feof(table.fp)) {
+      return NULL;
+   }
+
+   STORAGE_BYTE_ORDER = table.byte_order;
+
+   row = (row_type)vpfmalloc((table.nfields+1) * sizeof(column_type));
+
+   for (i=0;i<table.nfields;i++) row[i].ptr = NULL;
+
+   for (i=0;i<table.nfields;i++) {
+      if (table.header[i].count < 0) {
+
+	 Read_Vpf_Int (&count,table.fp,1) ;
+
+      } else {
+	 count = table.header[i].count;
+      }
+      row[i].count = count;
+
+      status = 0;
+      switch (table.header[i].type) {
+	 case 'T':
+	    if (count == 1) {
+	       row[i].ptr = (char *)vpfmalloc(sizeof(char));
+	       Read_Vpf_Char(row[i].ptr, table.fp, 1) ;
+	    } else {
+	       size = count*sizeof(char);
+	       row[i].ptr = (char *)vpfmalloc(size+2);
+	       tptr = (char *)vpfmalloc(size+2);
+	       Read_Vpf_Char(tptr,table.fp,count) ;
+	       tptr[count] = '\0';
+	       strcpy((char*)row[i].ptr,(char*)tptr);
+	       free(tptr);
+	    }
+	    break;
+	 case 'I':
+	    row[i].ptr = (long int *)vpfmalloc(count*sizeof(long int));
+	    Read_Vpf_Int (row[i].ptr, table.fp, count ) ;
+	    break;
+	 case 'S':
+	    row[i].ptr = (short int *)vpfmalloc(count*sizeof(short int));
+	    Read_Vpf_Short (row[i].ptr, table.fp, count ) ;
+	    break;
+	 case 'F':
+	    row[i].ptr = (float *)vpfmalloc(count*sizeof(float));
+	    Read_Vpf_Float (row[i].ptr, table.fp, count ) ;
+	    break;
+	 case 'R':
+	    row[i].ptr = (double *)vpfmalloc(count*sizeof(double));
+	    Read_Vpf_Double (row[i].ptr, table.fp, count ) ;
+	    break;
+	 case 'D':
+	    row[i].ptr = (date_type *)vpfmalloc(count*sizeof(date_type));
+	    Read_Vpf_Date (row[i].ptr, table.fp, count ) ;
+	    break;
+	 case 'C':
+	    /* Coordinate strings may be quite large.          */
+	    /* Allow for null coordinate string pointer if     */
+	    /* not enough memory that can be handled one       */
+	    /* coordinate at a time in higher level functions. */
+	    row[i].ptr = (coordinate_type *)malloc(count*
+			 sizeof(coordinate_type));
+	    if (row[i].ptr)
+	       Read_Vpf_Coordinate(row[i].ptr,table.fp,count);
+	    else
+	       for (j=0;j<count;j++)
+		  Read_Vpf_Coordinate(&dummycoord,table.fp,1);
+	    break;
+	 case 'Z':
+	    row[i].ptr = (tri_coordinate_type *)vpfmalloc(count*
+			 sizeof(tri_coordinate_type));
+	    Read_Vpf_CoordinateZ(row[i].ptr,table.fp,count);
+	    break;
+	 case 'B':
+	    row[i].ptr = (double_coordinate_type *)vpfmalloc(count*
+			 sizeof(double_coordinate_type));
+	    Read_Vpf_DoubleCoordinate(row[i].ptr,table.fp,count);
+	    break;
+	 case 'Y':
+	    row[i].ptr = (double_tri_coordinate_type *)vpfmalloc(count*
+			 sizeof(double_tri_coordinate_type));
+	    Read_Vpf_DoubleCoordinateZ(row[i].ptr,table.fp,count);
+	    break;
+	 case 'K':   /* ID Triplet */
+	    row[i].ptr = (id_triplet_type *)vpfmalloc(count*
+			 sizeof(id_triplet_type));
+	    keys = (id_triplet_type *)vpfmalloc(count*
+		   sizeof(id_triplet_type));
+	    for (j=0;j<count;j++) {
+	       keys[j] = read_key(table);
+	    }
+	    memcpy(row[i].ptr,keys,count*sizeof(id_triplet_type));
+	    free(keys);
+	    break;
+	 case 'X':
+	    row[i].ptr = NULL;
+	    break;
+	  default:
+	    fprintf(stderr,"\n%s%s >>> read_next_row: no such type < %c >",
+		table.path,table.name,table.header[i].type ) ;
+	    status = 1;
+	    break ;
+	  }   /* end of switch */
+      if (status == 1) {
+	 free_row ( row, table ) ;
+	 return (row_type) NULL;
+      }
+   }
+   return row;
+}
+
+/*************************************************************************
+ *
+ *N  rowcpy
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns a copy of the specified row.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    origrow    <input> == (row_type) row to copy.
+ *    table      <input> == (vpf_table_type) vpf table structure.
+ *    return    <output> == (row_type) copy of the row.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                     DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void *vpfmalloc()                            VPFMISC.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+row_type rowcpy( row_type origrow,
+		 vpf_table_type table )
+{
+   register long int i;
+   long int      count;
+   long int size;
+   row_type row;
+
+   row = (row_type)vpfmalloc(table.nfields * sizeof(column_type));
+   for (i=0;i<table.nfields;i++) {
+      count = origrow[i].count;
+      row[i].count = count;
+      switch (table.header[i].type) {
+	 case 'T':
+	    if (count==1) {
+	       row[i].ptr = (char *)vpfmalloc(1);
+	       memcpy(row[i].ptr,origrow[i].ptr,sizeof(char));
+	    } else {
+	       size = count*sizeof(char);
+	       row[i].ptr = (char *)vpfmalloc(size+1);
+	       strcpy((char*)row[i].ptr,(char*)origrow[i].ptr);
+	    }
+	    break;
+	 case 'I':
+	    size = count*sizeof(long int);
+	    row[i].ptr = (long int *)vpfmalloc(size);
+	    memcpy(row[i].ptr,origrow[i].ptr,size);
+	    break;
+	 case 'S':
+	    size = count*sizeof(short int);
+	    row[i].ptr = (short int *)vpfmalloc(size);
+	    memcpy(row[i].ptr,origrow[i].ptr,size);
+	    break;
+	 case 'F':
+	    size = count*sizeof(float);
+	    row[i].ptr = (float *)vpfmalloc(size);
+	    memcpy(row[i].ptr,origrow[i].ptr,size);
+	    break;
+	 case 'R':
+	    size = count*sizeof(double);
+	    row[i].ptr = (double *)vpfmalloc(size);
+	    memcpy(row[i].ptr,origrow[i].ptr,size);
+	    break;
+	 case 'C':
+	    size = count*sizeof(coordinate_type);
+	    row[i].ptr = (coordinate_type *)malloc(size);
+	    if (row[i].ptr && origrow[i].ptr)
+	       memcpy(row[i].ptr,origrow[i].ptr,size);
+	    else
+	       row[i].ptr = NULL;
+	    break;
+	 case 'Z':
+	    size = count*sizeof(tri_coordinate_type);
+	    row[i].ptr = (tri_coordinate_type *)vpfmalloc(size);
+	    memcpy(row[i].ptr,origrow[i].ptr,size);
+	    break;
+	 case 'B':
+	    size = count*sizeof(double_coordinate_type);
+	    row[i].ptr = (double_coordinate_type *)vpfmalloc(size);
+	    memcpy(row[i].ptr,origrow[i].ptr,size);
+	    break;
+	 case 'Y':
+	    size = count*sizeof(double_tri_coordinate_type);
+	    row[i].ptr = (double_tri_coordinate_type *)vpfmalloc(size);
+	    memcpy(row[i].ptr,origrow[i].ptr,size);
+	    break;
+	 case 'D':  /* Date */
+	    size = count*sizeof(date_type);
+	    row[i].ptr = (date_type *)vpfmalloc(size);
+	    memcpy(row[i].ptr,origrow[i].ptr,size);
+	    break;
+	 case 'K':  /* ID Triplet */
+	    size = count*sizeof(id_triplet_type);
+	    row[i].ptr = (id_triplet_type *)vpfmalloc(size);
+	    memcpy(row[i].ptr,origrow[i].ptr,size);
+	    break;
+	 case 'X':
+	    row[i].ptr = NULL;
+	    break;
+	  default:
+	    fprintf (stderr,"\nrow_cpy: error in data type < %c >",
+		     table.header[i].type ) ;
+	    abort () ;
+	    break ;
+	  }   	/* end of switch */
+    }    	/* end of table.nfields */
+   return row;
+}
+
+/*************************************************************************
+ *
+ *N  read_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function reads a specified row from the table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    row_number <input> == (long int) row number.
+ *    table      <input> == (vpf_table_type) vpf table structure.
+ *    return    <output> == (row_type) row that was read in.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    long int index_pos()                             VPFTABLE.C
+ *    row_type read_next_row()                         VPFTABLE.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+row_type read_row( long int row_number,
+		   vpf_table_type table )
+{
+   long int fpos;
+
+   fpos = index_pos(row_number,table);
+
+   fseek(table.fp,fpos,SEEK_SET);
+
+   return read_next_row(table);
+}
+
+/*************************************************************************
+ *
+ *N  free_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function frees the memory that was dynamically allocated for the
+ *     specified row.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    row   <input> == (row_type) row to be freed.
+ *    table <input> == (vpf_table_type) vpf table structure.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                     DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+void free_row( row_type row,
+	       vpf_table_type table)
+{
+   register long int i;
+
+   if (!row) return;
+   for (i=0;i<table.nfields;i++)
+      if (row[i].ptr) free(row[i].ptr);
+   free(row);
+}
+
+/*************************************************************************
+ *
+ *N  get_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the specified row of the table.  If the table
+ *     is stored in memory, the row is copied from there.  If it is on disk,
+ *     it is read and returned.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    row_number <input> == (long int) row number in range [1 .. table.nrows].
+ *    table      <input> == (vpf_table_type) vpf table structure.
+ *    return    <output> == (row_type) returned row.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991      DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    row_type rowcpy                VPFREAD.C
+ *    row_type read_row              VPFREAD.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+row_type get_row( long int row_number,
+		  vpf_table_type table )
+{
+   row_type row;
+
+   row_number = max(min(row_number, table.nrows), 1);
+
+   if (table.storage == RAM) {
+      row = rowcpy(table.row[row_number-1],table);
+      return row;
+   } else {
+      return read_row( row_number, table );
+   }
+}
+
+/*************************************************************************
+ *
+ *N  table_pos
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the column offset of the specified field name
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    field_name <input> == (char *) field name.
+ *    table      <input> == (vpf_table_type) VPF table structure.
+ *    table_pos  <output> == (long int) returned column number.
+ *                          UNIX returns -1 if not exists
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                     DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+long int table_pos( char           * field_name,
+		    vpf_table_type   table )
+{
+   register long int i;
+   long int col;
+   char altfn[256];
+
+   col = -1;
+   for (i = 0; i < table.nfields; i++) {
+      strcpy(altfn, ",:");
+      strcat(altfn, field_name);
+      if (ossim_strcasecmp(field_name,table.header[i].name) == 0
+	  || ossim_strcasecmp(altfn,table.header[i].name) == 0) {
+	 col = i;
+	 break;
+      }
+   }
+   return col;
+}
+
+/*************************************************************************
+ *
+ *N  get_table_element
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the element in the given row in the given
+ *     column.  If the element is a single element (count=1), the value
+ *     is passed back via the void pointer *value; otherwise, an array
+ *     is allocated and passed back as the return value.
+ *     NOTE: If an array is allocated in this function, it should be freed
+ *     when no longer needed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    field_number <input> == (long int) field column number.
+ *    row          <input> == (row_type) vpf table row.
+ *    table        <input> == (vpf_table_type) VPF table structure.
+ *    value       <output> == (void *) pointer to a single element value.
+ *    count       <output> == (long int *) pointer to the array size for a
+ *                                    multiple element value.
+ *    return      <output> == (void *) returned multiple element value.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991             DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void *vpfmalloc()
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+void *get_table_element( long int field_number,
+			 row_type row,
+			 vpf_table_type table,
+			 void *value,
+			 long int  *count )
+{
+   long int   col;
+   char     * tptr;
+   void     * retvalue;
+
+   retvalue = NULL;
+   col = field_number;
+   if ((col < 0) || (col >= table.nfields)) {
+      fprintf(stderr,"%s: Invalid field number %d\n",
+	      table.name,(int)field_number);
+      return NULL;
+   }
+
+   if (!row) return NULL;
+
+   switch (table.header[col].type) {
+      case 'X':
+	 retvalue = NULL;
+	 break;
+      case 'T':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(char));
+	 } else {
+	    retvalue = (char *)vpfmalloc((row[col].count+1)*sizeof(char));
+	    tptr = (char *)vpfmalloc((row[col].count+1)*sizeof(char));
+	    memcpy(tptr,row[col].ptr,row[col].count*sizeof(char));
+	    tptr[row[col].count] = '\0';
+	    strcpy((char *)retvalue,tptr);
+	    free(tptr);
+	 }
+	 break;
+      case 'I':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(long int));
+	 } else {
+	    retvalue = (long int *)vpfmalloc(row[col].count*
+					     sizeof(long int));
+	    memcpy(retvalue,row[col].ptr,row[col].count*sizeof(long int));
+	 }
+	 break;
+      case 'S':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(short int));
+	 } else {
+	    retvalue = (short int *)vpfmalloc(row[col].count*
+					     sizeof(short int));
+	    memcpy(retvalue,row[col].ptr,row[col].count*sizeof(short int));
+	 }
+	 break;
+      case 'F':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(float));
+	 } else {
+	    retvalue = (float *)vpfmalloc(row[col].count*sizeof(float));
+	    memcpy(retvalue,row[col].ptr,row[col].count*sizeof(float));
+	 }
+	 break;
+      case 'R':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(double));
+	 } else {
+	    retvalue = (double *)vpfmalloc(row[col].count*sizeof(double));
+	    memcpy(retvalue,row[col].ptr,row[col].count*sizeof(double));
+	 }
+	 break;
+      case 'C':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(coordinate_type));
+	 } else {
+	    if (row[col].ptr) {
+	       retvalue = (coordinate_type *)malloc(row[col].count*
+			  sizeof(coordinate_type));
+	       if (retvalue)
+		  memcpy(retvalue,row[col].ptr,row[col].count*
+			 sizeof(coordinate_type));
+	    } else {
+	       retvalue = NULL;
+	    }
+	 }
+	 break;
+      case 'Z':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(tri_coordinate_type));
+	 } else {
+	    retvalue = (tri_coordinate_type *)vpfmalloc(row[col].count*
+			sizeof(tri_coordinate_type));
+	    memcpy(retvalue,row[col].ptr,row[col].count*
+		    sizeof(tri_coordinate_type));
+	 }
+	 break;
+      case 'B':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(double_coordinate_type));
+	 } else {
+	    retvalue = (double_coordinate_type *)vpfmalloc(row[col].count*
+			sizeof(double_coordinate_type));
+	    memcpy(retvalue,row[col].ptr,row[col].count*
+		    sizeof(double_coordinate_type));
+	 }
+	 break;
+      case 'Y':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(double_tri_coordinate_type));
+	 } else {
+	    retvalue = (double_tri_coordinate_type *)vpfmalloc(row[col].count*
+			sizeof(double_tri_coordinate_type));
+	    memcpy(retvalue,row[col].ptr,row[col].count*
+		    sizeof(double_tri_coordinate_type));
+	 }
+	 break ;
+      case 'D':
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(date_type));
+	 } else {
+	    retvalue = (date_type *)vpfmalloc(row[col].count*
+					      sizeof(date_type));
+	    memcpy(retvalue,row[col].ptr,row[col].count*
+					  sizeof(date_type));
+	 }
+	 break;
+      case 'K':  /* ID Triplet */
+	 if (table.header[col].count == 1) {
+	    memcpy(value,row[col].ptr,sizeof(id_triplet_type));
+	 } else {
+	    retvalue = (id_triplet_type *)vpfmalloc(row[col].count*
+					      sizeof(id_triplet_type));
+	    memcpy(retvalue,row[col].ptr,row[col].count*
+					  sizeof(id_triplet_type));
+	 }
+	 break;
+   }
+   *count = row[col].count;
+
+   return retvalue;
+}
+
+/*************************************************************************
+ *
+ *N  named_table_element
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the element in the specified row in the column
+ *     matching the given field name.  If the element is a single element
+ *     (count=1), the value is passed back via the void pointer *value;
+ *     otherwise, an array is allocated and passed back as the return value.
+ *     NOTE: If an array is allocated in this function, it should be freed
+ *     when no longer needed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    field_name <input> == (char *) field name.
+ *    row_number <input> == (long int) row_number.
+ *    table      <input> == (vpf_table_type) VPF table structure.
+ *    value     <output> == (void *) pointer to a single element value.
+ *    count     <output> == (long int *) pointer to the array size for a multiple
+ *                                  element value.
+ *    return    <output> == (void *) returned multiple element value.
+ *                          or NULL if field_name could not be found
+ *                          as a column
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                     DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void *vpfmalloc()                    VPFREAD.C
+ *    row_type get_row()                   VPFREAD.C
+ *    void free_row()                      VPFREAD.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+void *named_table_element( char           * field_name,
+			   long int         row_number,
+			   vpf_table_type   table,
+			   void           * value,
+			   long int       * count )
+{
+   long int     col;
+   row_type     row;
+   void       * retvalue;
+
+   col = table_pos(field_name, table);
+
+   if (col < 0) {
+      fprintf(stderr,"%s: Invalid field name <%s>\n",table.name,field_name);
+      return NULL;
+   }
+   row = get_row(row_number,table);
+
+   retvalue = get_table_element( col, row, table, value, count );
+
+   free_row(row, table);
+
+   return retvalue;
+}
+
+/*************************************************************************
+ *
+ *N  table_element
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function returns the element in the specified row in the column
+ *     matching the given field number.  If the element is a single element
+ *     (count=1), the value is passed back via the void pointer *value;
+ *     otherwise, an array is allocated and passed back as the return value.
+ *     NOTE: If an array is allocated in this function, it should be freed
+ *     when no longer needed.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    field_number <input> == (long int) field number (offset from
+ *                                   first field in table).
+ *    row_number <input> == (long int) row_number.
+ *    table      <input> == (vpf_table_type) VPF table structure.
+ *    value     <output> == (void *) pointer to a single element value.
+ *    count     <output> == (long int *) pointer to the array size for a multiple
+ *                                  element value.
+ *    return    <output> == (void *) returned multiple element value or
+ *                          NULL of the field number is invalid
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                     DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    row_type get_row()                   VPFREAD.C
+ *    void free_row()                      VPFREAD.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+void *table_element( long int         field_number,
+		     long int         row_number,
+		     vpf_table_type   table,
+		     void           * value,
+		     long int       * count )
+{
+   row_type    row;
+   void      * retvalue;
+
+   row      = get_row(row_number, table);
+   retvalue = get_table_element(field_number, row, table, value, count);
+   free_row(row,table);
+
+   return retvalue;
+}
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfrelat.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfrelat.c
new file mode 100644
index 0000000000..c42370be95
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfrelat.c
@@ -0,0 +1,902 @@
+/***************************************************************************
+ *
+ *N  Module VPFRELAT.C
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This module contains functions supporting relates between VPF
+ *    feature classes and primitives (and vice versa).  It relies
+ *    upon the information provided by the Feature Class Schema table.
+ *    This table is used to generate a feature class relationship (fcrel)
+ *    data structure for a feature class.  This structure contains all
+ *    of the tables and their primary and foreign keys for the
+ *    relationships between a feature table and its primitive, or
+ *    from a primitive to its feature table (each relate chain is one way).
+ *    This module tries to be as much of a black box as it can to
+ *    enable a programmer to simply return the corresponding primitive
+ *    row of a feature record, or the corresponding feature row of a
+ *    primitive record.
+ *
+ *    This is one of the most difficult modules required to support
+ *    a truly 'generic' VPF application, since VPF allows so many
+ *    variations of feature-primitive relationships.  The final version
+ *    of this module must support every allowed relationship.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels
+ *
+ *    Added one-to-many relates 3/2/92 - BJM
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ **************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __MSDOS__
+#include <alloc.h>
+#include <mem.h>
+#else
+#ifdef MACOSX 
+#include <sys/types.h>
+#include <sys/malloc.h>
+#else
+#include <malloc.h>
+#include <string.h>
+#endif
+#endif
+
+
+#if defined(__CYGWIN__)||defined(MACOSX)|| defined(_WIN32)
+#include "values.h"
+#else
+#include <values.h>
+#endif
+#include <string.h>
+#include <stdarg.h>
+#include "vpftable.h"
+#include "vpfview.h"
+#include "vpfrelat.h"
+#include "vpftidx.h"
+
+/* Determine if the given table name is in the given list of */
+/* vpf relate structures.				     */
+static int table_in_list( char *tablename, linked_list_type rlist )
+{
+   position_type p;
+   vpf_relate_struct rcell;
+
+   p = ll_first(rlist);
+   while (!ll_end(p)) {
+      ll_element(p,&rcell);
+      if (strcmp(rcell.table1,tablename)==0) return 1;
+      p = ll_next(p);
+   }
+   return 0;
+}
+
+/**************************************************************************
+ *
+ *N  fcs_relate_list
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Read the feature class schema table and create the list of
+ *    tables to chain through.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    fcname       <input> == (char *) feature class name.
+ *    start_table  <input> == (char *) table to start from.
+ *    end_table    <input> == (char *) table to end with.
+ *    fcs          <input> == (vpf_table_type) feature class schema table.
+ *    fcs_relate_list <output> == (linked_list_type) list of tables to
+ *                                chain through.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+linked_list_type fcs_relate_list( char *fcname, char *start_table,
+				  char *end_table, vpf_table_type fcs )
+{
+   linked_list_type rlist;
+   vpf_relate_struct rstruct;
+   set_type fcset, set1, set2;
+   char tablename[255], *buf, expr[255];
+   row_type row;
+   long int rownum,n;
+   int TABLE1_, KEY1_, TABLE2_, KEY2_;
+
+   rlist = ll_init();
+
+   sprintf(expr,"FEATURE_CLASS = %s",fcname);
+
+   fcset = query_table(expr,fcs);
+
+   if (set_empty(fcset)) {
+      set_nuke(&fcset);
+      return rlist;
+   }
+
+   TABLE1_ = table_pos("TABLE1",fcs);
+   KEY1_ = table_pos("FOREIGN_KEY",fcs);
+   if (KEY1_ < 0) KEY1_ = table_pos("TABLE1_KEY",fcs);
+   TABLE2_ = table_pos("TABLE2",fcs);
+   KEY2_ = table_pos("PRIMARY_KEY",fcs);
+   if (KEY2_ < 0) KEY2_ = table_pos("TABLE2_KEY",fcs);
+
+   strcpy( tablename, start_table );
+   while (1) {
+      sprintf(expr,"TABLE1 = %s",tablename);
+
+      set1 = query_table(expr,fcs);
+      set2 = set_intersection(set1,fcset);
+      set_nuke(&set1);
+      if (set_empty(set2)) {
+	 set_nuke(&fcset);
+	 set_nuke(&set2);
+	 return rlist;
+      }
+      rownum = set_min(set2);
+
+      set_nuke(&set2);
+
+      row = get_row(rownum,fcs);
+
+      buf = (char *)get_table_element(TABLE1_,row,fcs,NULL,&n);
+      strcpy(rstruct.table1,buf);
+      rightjust(rstruct.table1);
+      free(buf);
+
+      buf = (char *)get_table_element(KEY1_,row,fcs,NULL,&n);
+      strcpy(rstruct.key1,buf);
+      rightjust(rstruct.key1);
+      free(buf);
+
+      buf = (char *)get_table_element(TABLE2_,row,fcs,NULL,&n);
+      strcpy(rstruct.table2,buf);
+      rightjust(rstruct.table2);
+      free(buf);
+
+      buf = (char *)get_table_element(KEY2_,row,fcs,NULL,&n);
+      strcpy(rstruct.key2,buf);
+      rightjust(rstruct.key2);
+      free(buf);
+
+      rstruct.degree = R_ONE;  /* Default */
+
+      free_row( row, fcs );
+
+      if (table_in_list(rstruct.table1, rlist)) break;
+
+      ll_insert( &rstruct, sizeof(rstruct), ll_last(rlist) );
+
+      strcpy( tablename, rstruct.table2 );
+
+      if (ossim_strcasecmp(tablename,end_table)==0) break;
+   }
+
+   set_nuke(&fcset);
+
+   return rlist;
+}
+
+
+/**************************************************************************
+ *
+ *N  vpf_binary_search
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function performs a binary search on a VPF table for the
+ *    specified integer value.  Only VPF data type 'I' is supported.
+ *    The table must be sorted on the specified field, or this function
+ *    will give unpredictable results.  The table must have been
+ *    successfully opened.  If more than one row matches the search
+ *    value, only the first encountered will be returned.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    srchval <input> == (long int) specified search value.
+ *    field   <input> == (int) table sort field.
+ *    table   <input> == (vpf_table_type) VPF table.
+ *    vpf_binary_search <output> == (long int) first matching row.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+long int vpf_binary_search( long int srchval,
+			    int field,
+			    vpf_table_type table )
+{
+   long int left,right, ival, rowid, n;
+   row_type row;
+
+   left = 1;
+   right = table.nrows;
+
+   do {
+      rowid = (left+right)/2;
+      row = get_row(rowid,table);
+      get_table_element(field,row,table,&ival,&n);
+      free_row(row,table);
+      if (ival < srchval)
+	 right = rowid-1;
+      else
+	 left = rowid+1;
+   } while ((srchval != ival) && (left <= right));
+
+   if (srchval != ival) rowid = 0;
+
+   return rowid;
+}
+
+
+/**************************************************************************
+ *
+ *N  related_row
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Return the related row of table2 based upon the value of table 1's key
+ *    Table 2 must be the '1' side of an n:1 relationship  --  If it isn't,
+ *    use 'related_rows()'.
+ *    Supported data types - I and T<n>.
+ *    Binary search supported only for data type I. (column must be sorted)
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+long int related_row( void *keyval1,
+		      vpf_table_type table2, char *key2,
+		      int sort_flag )
+{
+   long int rowid, i, ival, kval, n;
+   row_type row;
+   int KEY2_;
+   char cval, *tval;
+
+   if (ossim_strcasecmp(key2,"ID")==0) {
+      memcpy( &rowid, keyval1, sizeof(rowid) );
+      return rowid;
+   }
+
+   rowid = 0;
+
+   KEY2_ = table_pos(key2,table2);
+
+   if ((table2.header[KEY2_].type != 'I')&&
+       (table2.header[KEY2_].type != 'T')) return rowid;
+
+   if ((table2.header[KEY2_].type == 'I')&&
+       (table2.header[KEY2_].count != 1)) return rowid;
+
+   if ((table2.header[KEY2_].type == 'T')&&(sort_flag)) sort_flag = 0;
+
+   if (table2.header[KEY2_].type == 'I') memcpy(&kval,keyval1,sizeof(kval));
+
+   if (!sort_flag) {   /* Sequential search */
+
+      for (i=1;i<=table2.nrows;i++) {
+	 row = get_row(i,table2);
+	 if (table2.header[KEY2_].type == 'I') {
+	    get_table_element(KEY2_,row,table2,&ival,&n);
+	    if (ival == kval) rowid = i;
+	 } else {
+	    if (table2.header[KEY2_].count==1) {
+	       get_table_element(KEY2_,row,table2,&cval,&n);
+	       if (memcmp(&cval,keyval1,sizeof(ival))==0) rowid = i;
+	    } else {
+	       tval = (char*)get_table_element(KEY2_,row,table2,NULL,&n);
+	       if (strcmp(tval,(char *)keyval1)==0) rowid = i;
+	    }
+	 }
+	 free_row(row,table2);
+	 if (rowid > 0) break;
+      }
+
+   } else {   /* Binary search */
+
+      memcpy(&kval,keyval1,sizeof(kval));
+      rowid = vpf_binary_search( kval, KEY2_, table2 );
+
+   }
+
+   return rowid;
+}
+
+
+/**************************************************************************
+ *
+ *N  related_rows
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Return the list of related rows of table2 based upon the value of
+ *    table 1's key.
+ *    Supported data types - I and T<n>.
+ *    Binary search supported only for data type I. (column must be sorted)
+ *    Thematic index used, if present on key column.
+ *    NOTE: A sequential search operation will search the entire
+ *          table ...zzz...
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+linked_list_type related_rows( void *keyval1,
+		       vpf_table_type table2, char *key2,
+		       int sort_flag,
+		       ThematicIndex *idx )
+{
+   linked_list_type rowlist;
+   set_type rowset;
+   long int rowid, i, ival, kval, n, start,end;
+   row_type row = 0;
+   int KEY2_;
+   char cval, *tval;
+
+   rowlist = ll_init();
+
+   if (ossim_strcasecmp(key2,"ID")==0) {
+      memcpy( &rowid, keyval1, sizeof(rowid) );
+      ll_insert(&rowid,sizeof(rowid),rowlist);
+      return rowlist;
+   }
+
+   KEY2_ = table_pos(key2,table2);
+
+   if ((table2.header[KEY2_].type != 'I')&&
+       (table2.header[KEY2_].type != 'T')) return rowlist;
+
+   if ((table2.header[KEY2_].type == 'I')&&
+       (table2.header[KEY2_].count != 1)) return rowlist;
+
+   if ((table2.header[KEY2_].type == 'T')&&(sort_flag)) sort_flag = 0;
+
+   if (idx) {
+      if (idx->fp) {
+	 rowset = search_thematic_index(idx,(char *)keyval1);
+	 start = set_min(rowset);
+	 end = set_max(rowset);
+	 for (i=start;i<=end;i++)
+	    if (set_member(i,rowset)) {
+	       ll_insert(&i,sizeof(i),ll_last(rowlist));
+	    }
+	 set_nuke(&rowset);
+	 return rowlist;
+      }
+   }
+
+   if (!sort_flag) {   /* Sequential search */
+
+      for (i=1;i<=table2.nrows;i++) {
+	 row = get_row(i,table2);
+	 if (table2.header[KEY2_].type == 'I') {
+	    get_table_element(KEY2_,row,table2,&ival,&n);
+	    if (memcmp(&ival,keyval1,sizeof(ival))==0)
+	       ll_insert(&i,sizeof(i),ll_last(rowlist));
+	 } else {
+	    if (table2.header[KEY2_].count==1) {
+	       get_table_element(KEY2_,row,table2,&cval,&n);
+	       if (memcmp(&cval,keyval1,sizeof(ival))==0)
+		  ll_insert(&i,sizeof(i),ll_last(rowlist));
+	    } else {
+	       tval = (char*)get_table_element(KEY2_,row,table2,NULL,&n);
+	       if (strcmp(tval,(char *)keyval1)==0)
+		  ll_insert(&i,sizeof(i),ll_last(rowlist));
+	    }
+	 }
+	 free_row(row,table2);
+      }
+
+   } else {   /* Binary search */
+
+      memcpy(&kval,keyval1,sizeof(kval));
+      rowid = vpf_binary_search( kval, KEY2_, table2 );
+
+      if (rowid > 0) {
+	 ll_insert(&rowid,sizeof(rowid),ll_last(rowlist));
+	 i = rowid-1L;
+	 do {
+	    get_row(i,table2);
+	    get_table_element(KEY2_,row,table2,&ival,&n);
+	    if (ival == kval)
+	       ll_insert(&i,sizeof(i),ll_last(rowlist));
+	    i--;
+	 } while ((ival==kval)&&(i>0));
+	 i = rowid+1L;
+	 do {
+	    get_row(i,table2);
+	    get_table_element(KEY2_,row,table2,&ival,&n);
+	    if (ival == kval)
+	       ll_insert(&i,sizeof(i),ll_last(rowlist));
+	    i++;
+	 } while ((ival==kval)&&(i<=table2.nrows));
+      }
+
+   }
+
+   return rowlist;
+}
+
+
+/**************************************************************************
+ *
+ *N  vpf_nullify_table
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Nullify the given VPF table structure.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+void vpf_nullify_table( vpf_table_type *table )
+{
+   strcpy(table->name,"");
+   table->path = NULL;
+   table->nfields = 0;
+   strcpy(table->description,"");
+   strcpy(table->narrative,"");
+   table->header = NULL;
+   table->xfp = NULL;
+   table->index = NULL;
+   table->xstorage = (storage_type)0;
+   table->fp = NULL;
+   table->nrows = 0;
+   table->row = NULL;
+   table->reclen = 0;
+   table->ddlen = 0;
+   table->defstr = NULL;
+   table->storage = (storage_type)0;
+   table->mode = (file_mode)0;
+   table->status = CLOSED;
+}
+
+
+/**************************************************************************
+ *
+ *N  select_feature_class_relate
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Set up the relationships between features and primitives or between
+ *    primitives and features (one way only) for a specified feature class.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+fcrel_type select_feature_class_relate( int fcnum,
+					library_type *library,
+					char *start_table,
+					char *end_table )
+{
+   int storage, cov;
+   vpf_table_type fcs;
+   long int i;
+   char path[255], covpath[255];
+   position_type p;
+   vpf_relate_struct rcell;
+   fcrel_type fcrel;
+
+   fcrel.nchain = 0;
+   fcrel.table = NULL;
+   fcrel.relate_list = NULL;
+
+   cov = library->fc[fcnum].coverage;
+   strcpy(covpath,library->cover[cov].path);
+   rightjust(covpath);
+   sprintf( path, "%sfcs", covpath );
+
+   /* Feature Class Schema table */
+   fcs = vpf_open_table( path, disk, "rb", NULL );
+
+   fcrel.relate_list = fcs_relate_list( library->fc[fcnum].name,
+					start_table,end_table,
+					fcs );
+
+   if (ll_empty(fcrel.relate_list)) {
+      ll_reset(fcrel.relate_list);
+      displaymessage("ERROR in feature class relationship!",
+		     start_table,end_table,NULL);
+      return fcrel;
+   }
+
+   /* Find the number of tables in the relate chain */
+   p = ll_first(fcrel.relate_list);
+   fcrel.nchain = 0;
+   while (!ll_end(p)) {
+      fcrel.nchain++;
+      p = ll_next(p);
+   }
+   /* Allow for last table2 */
+   fcrel.nchain++;
+
+   fcrel.table = (vpf_table_type *)
+		  vpfmalloc((fcrel.nchain+1)*
+			     sizeof(vpf_table_type));
+
+   for (i=0;i<fcrel.nchain+1;i++)
+      vpf_nullify_table( &(fcrel.table[i]) );
+
+
+   p = ll_first(fcrel.relate_list);
+   for (i=0;i<fcrel.nchain-1;i++) {
+
+      ll_element(p,&rcell);
+
+      /** Can't open primitive table - may be several under tile **/
+      /** directories.  Open all others **/
+      if (!is_primitive(rcell.table1)) {
+
+	 sprintf(path,"%s%s",covpath,rcell.table1);
+	 if (is_join(rcell.table1))
+	    storage = ram;
+	 else
+	    storage = disk;
+
+	 fcrel.table[i] = vpf_open_table(path,(storage_type)storage,"rb",NULL);
+
+      }
+
+      if (!ll_end(p)) p = ll_next(p);
+   }
+
+   /* End of relate chain */
+   i = fcrel.nchain-1;
+   if (!is_primitive(rcell.table2)) {
+
+      sprintf(path,"%s%s",covpath,rcell.table2);
+      storage = disk;
+
+      fcrel.table[i] = vpf_open_table(path,(storage_type)storage,"rb",NULL);
+
+   }
+
+
+   vpf_close_table( &fcs );
+
+   return fcrel;
+}
+
+
+/**************************************************************************
+ *
+ *N  fc_row_number
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Given the starting row of a feature class relationship, return the
+ *    row number of the table at the end of the feature class relate
+ *    chain.
+ *    If your relate goes from the feature to the primitive, this will
+ *    return the primitive id for the given feature row.
+ *    If your relate goes from the primitive to the feature, this will
+ *    return the feature id of the given primitive row.
+ *
+ *    Currently only supports relates on 'I' or 'K' fields.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+long int fc_row_number( row_type row, fcrel_type fcrel, long int tile )
+{
+   row_type relrow;
+   long int count;
+   long int i, rownum, keyval;
+   id_triplet_type triplet_keyval;
+   int KEY1_, KEY_;
+   position_type p;
+   vpf_relate_struct rcell;
+
+   p = ll_first(fcrel.relate_list);
+   ll_element(p,&rcell);
+   KEY1_ = table_pos(rcell.key1,fcrel.table[0]);
+
+   get_table_element(0,row,fcrel.table[0],&rownum,&count);
+
+   if (KEY1_ == 0) {     /* "ID" */
+      keyval = rownum;
+   } else {
+      switch (fcrel.table[0].header[KEY1_].type) {
+	 case 'I':
+	    get_table_element(KEY1_,row,fcrel.table[0],&keyval,&count);
+	    break;
+	 case 'K':
+	    get_table_element(KEY1_,row,fcrel.table[0],&triplet_keyval,
+			      &count);
+	    keyval = triplet_keyval.exid;
+	    if (tile != triplet_keyval.tile) {
+	       return -2;
+	    }
+	    break;
+	 default:
+	    keyval = 0;
+	    break;
+      }
+   }
+
+   p = ll_first(fcrel.relate_list);
+   for (i=1;i<(fcrel.nchain-1);i++) {
+      /* Relate through Join table(s) */
+      rownum = related_row(&keyval,fcrel.table[i],rcell.key2,0);
+      relrow = get_row(rownum,fcrel.table[i]);
+
+      p = ll_next(p);
+      ll_element(p,&rcell);
+      KEY_ = table_pos(rcell.key1,fcrel.table[i]);
+
+      if (KEY_ == 0) {     /* "ID" */
+	 keyval = rownum;
+      } else {
+	 switch (fcrel.table[i].header[KEY_].type) {
+	 case 'I':
+	    get_table_element(KEY_,relrow,fcrel.table[i],&keyval,&count);
+	    break;
+	 case 'K':
+	    get_table_element(KEY_,relrow,fcrel.table[i],&triplet_keyval,
+			      &count);
+	    keyval = triplet_keyval.exid;
+	    if (tile != triplet_keyval.tile) {
+	       return -2;
+	    }
+	    break;
+	 default:
+	    keyval = 0;
+	    break;
+	 }
+      }
+
+      free_row(relrow,fcrel.table[i]);
+   }
+
+   if (ossim_strcasecmp(rcell.key2,"ID")==0)
+      rownum = keyval;
+   else
+      rownum = related_row(&keyval,fcrel.table[i],rcell.key2,0);
+
+   return rownum;
+}
+
+
+/**************************************************************************
+ *
+ *N  fc_row_numbers
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Given the starting row of a feature class relationship, return the
+ *    list of row numbers of the table at the end of the feature class
+ *    relate chain.
+ *    If your relate goes from the feature to the primitive, this will
+ *    return the primitive ids for the given feature row.
+ *    If your relate goes from the primitive to the feature, this will
+ *    return the feature ids of the given primitive row.
+ *
+ *    Currently only supports relates on 'I' or 'K' fields.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+linked_list_type fc_row_numbers( row_type row,
+				 fcrel_type fcrel,
+				 long int tile,
+				 ThematicIndex *idx )
+{
+   row_type relrow;
+   long int count;
+   long int n, rownum, keyval;
+   id_triplet_type triplet_keyval;
+   int KEY1_, KEY_;
+   position_type p, prow, pkey;
+   vpf_relate_struct rcell;
+   linked_list_type rowlist, keylist, templist;
+
+   p = ll_first(fcrel.relate_list);
+   ll_element(p,&rcell);
+   KEY1_ = table_pos(rcell.key1,fcrel.table[0]);
+
+   get_table_element(0,row,fcrel.table[0],&rownum,&count);
+
+   if (KEY1_ == 0) {     /* "ID" */
+      keyval = rownum;
+   } else {
+      switch (fcrel.table[0].header[KEY1_].type) {
+	 case 'I':
+	    get_table_element(KEY1_,row,fcrel.table[0],&keyval,&count);
+	    break;
+	 case 'K':
+	    get_table_element(KEY1_,row,fcrel.table[0],&triplet_keyval,
+			      &count);
+	    keyval = triplet_keyval.exid;
+	    if (tile != triplet_keyval.tile) {
+	       keyval = -2;
+	    }
+	    break;
+	 default:
+	    keyval = 0;
+	    break;
+      }
+   }
+
+   keylist = ll_init();
+   ll_insert(&keyval,sizeof(keyval),keylist);
+
+   n = 0;
+
+   p = ll_first(fcrel.relate_list);
+   for (n=1;n<(fcrel.nchain-1);n++) {
+
+      /* Relate through Join table(s) */
+
+      rowlist = ll_init();
+      pkey = ll_first(keylist);
+      while (!ll_end(pkey)) {
+	 ll_element(pkey,&keyval);
+	 templist = related_rows(&keyval,fcrel.table[n],rcell.key2,0,NULL);
+	 prow = ll_first(templist);
+	 while (!ll_end(prow)) {
+	    ll_element(prow,&rownum);
+	    if (!ll_locate(&rownum,rowlist))
+	       ll_insert(&rownum,sizeof(rownum),ll_last(rowlist));
+	    prow = ll_next(prow);
+	 }
+	 ll_reset(templist);
+	 pkey = ll_next(pkey);
+      }
+      ll_reset(keylist);
+
+      p = ll_next(p);
+      ll_element(p,&rcell);
+      KEY_ = table_pos(rcell.key1,fcrel.table[n]);
+
+      keylist = ll_init();
+      prow = ll_first(rowlist);
+      while (!ll_end(prow)) {
+	 ll_element(prow,&rownum);
+	 relrow = get_row(rownum,fcrel.table[n]);
+
+	 if (KEY_ == 0) {     /* "ID" */
+	    keyval = rownum;
+	 } else {
+	    switch (fcrel.table[n].header[KEY_].type) {
+	    case 'I':
+	       get_table_element(KEY_,relrow,fcrel.table[n],&keyval,&count);
+	       break;
+	    case 'K':
+	       get_table_element(KEY_,relrow,fcrel.table[n],&triplet_keyval,
+				 &count);
+	       keyval = triplet_keyval.exid;
+	       if (tile != triplet_keyval.tile) {
+		  keyval = -2;
+	       }
+	       break;
+	    default:
+	       keyval = 0;
+	       break;
+	    }
+	 }
+	 if (keyval > 0)
+	    ll_insert(&keyval,sizeof(keyval),ll_last(keylist));
+	 prow = ll_next(prow);
+	 free_row(relrow,fcrel.table[n]);
+      }
+      ll_reset(rowlist);
+   }
+
+   rowlist = ll_init();
+   p = ll_first(keylist);
+   while (!ll_end(p)) {
+      ll_element(p,&keyval);
+      templist = related_rows(&keyval,fcrel.table[n],rcell.key2,0,idx);
+      prow = ll_first(templist);
+      while (!ll_end(prow)) {
+	 ll_element(prow,&rownum);
+	 if (!ll_locate(&rownum,rowlist))
+	    ll_insert(&rownum,sizeof(rownum),ll_last(rowlist));
+	 prow = ll_next(prow);
+      }
+      ll_reset(templist);
+      p = ll_next(p);
+   }
+   ll_reset(keylist);
+
+   return rowlist;
+}
+
+
+/**************************************************************************
+ *
+ *N  deselect_feature_class_relate
+ *
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Clear out a previously allocated feature class relate structure
+ *    from memory.
+ *E
+ *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels  DOS Turbo C
+ *E
+ *************************************************************************/
+void deselect_feature_class_relate( fcrel_type *fcrel )
+{
+   register int i;
+
+   if (fcrel->nchain > 0) {
+      for (i=0;i<fcrel->nchain;i++) {
+	 if (fcrel->table[i].status == OPENED) {
+	    vpf_close_table(&(fcrel->table[i]));
+	 }
+      }
+      free(fcrel->table);
+      ll_reset(fcrel->relate_list);
+   }
+   fcrel->nchain = 0;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfrelat.h b/Utilities/OSSIM/ossim_core/vpf_util/vpfrelat.h
new file mode 100644
index 0000000000..27196290cf
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfrelat.h
@@ -0,0 +1,58 @@
+
+/* VPFRELATE.H   -   Functions supporting relates between VPF tables */
+		     /* One to many relates */
+#ifndef vpfrelat_HEADER
+#define vpfrelat_HEADER
+#include "vpftidx.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define R_ONE 1
+#define R_MANY 2
+
+typedef struct {
+   char table1[40];
+   char key1[40];
+   char table2[40];
+   char key2[40];
+   int degree;
+} vpf_relate_struct;
+
+typedef struct {
+   int nchain;
+   vpf_table_type *table;
+   linked_list_type relate_list;
+} feature_class_relate_type, fcrel_type;
+
+
+linked_list_type fcs_relate_list( char *fcname, char *start_table,
+				  char *end_table, vpf_table_type fcs );
+
+long int related_row( void *keyval1,
+		      vpf_table_type table2, char *key2,
+		      int sort_flag );
+
+linked_list_type related_rows( void *keyval1,
+		       vpf_table_type table2, char *key2,
+		       int sort_flag,
+		       ThematicIndex *idx );
+
+
+fcrel_type select_feature_class_relate( int fcnum, library_type *library,
+					char *start_table, char *end_table );
+
+long int fc_row_number( row_type row, fcrel_type fcrel, long int tile );
+
+linked_list_type fc_row_numbers( row_type row,
+				 fcrel_type fcrel,
+				 long int tile,
+				 ThematicIndex *idx );
+
+void deselect_feature_class_relate( fcrel_type *fcrel );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfselec.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfselec.c
new file mode 100644
index 0000000000..650fadf95f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfselec.c
@@ -0,0 +1,1318 @@
+/*************************************************************************
+ *
+ *N  Module VPFSELEC - VPF SELECTED FEATURES
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions for selecting VPF features and
+ *     primitives.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   Nov 1991                           DOS Turbo C
+ *                     Feb 1992 - Optimized for CD-ROM performance.
+ *E
+ *************************************************************************/
+
+#ifdef __MSDOS__
+#include <alloc.h>
+#include <mem.h>
+#else
+#ifdef MACOSX 
+#include <sys/types.h>
+#include <sys/malloc.h>
+#else
+#include <malloc.h>
+#include <string.h>
+#endif
+#endif
+
+
+#ifdef __MSDOS__
+#include <graphics.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef __MSDOS__
+#include <sys\stat.h>
+#include <dos.h>
+#else
+#include <sys/stat.h>
+#include <limits.h>
+#endif
+#include "vpfview.h"
+#include "vpfprim.h"
+#include "vpfrelat.h"
+#include "mapgraph.h"
+#include "projectn.h"
+#include "vpftidx.h"
+#include "vpfselec.h"
+#include "vpfdraw.h"
+
+
+extern char home[255];
+
+/* Defined in VPFSPX.C */
+set_type spatial_index_search( char *fname,
+			       float x1, float y1, float x2, float y2 );
+
+
+#ifdef __MSDOS__
+/*************************************************************************
+ *
+ *N  read_selected_features
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function reads a saved selection set for a given theme of the
+ *    specified view.
+ *
+ *    NOTE:  This function has "special knowledge" about the structure of
+ *    a set.  If that structure is changed, this function must account
+ *    for those changes.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     view       <input>==(view_type *) view structure.
+ *     themenum   <input>==(int) theme number.
+ *     return    <output>==(set_type) set of selected features.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+set_type read_selected_features( view_type *view, int themenum )
+{
+   set_type selset;
+   char path[255], *num = "          ", byte;
+   FILE *fp;
+   register int i;
+
+   /* Determine path name from theme number */
+   strcpy(path,home);
+   strcat(path,view->name);
+   strcat(path,"\\sel");
+   num = itoa(themenum,num,10);
+   for (i=0;i<(4-strlen(num));i++)
+      strcat(path,"0");
+   strcat(path,num);
+
+   if (access(path,0) != 0) {
+      selset.size = 0;
+      selset.buf = NULL;
+      return selset;
+   }
+
+   /* Read the set */
+   if ((fp = fopen(path,"rb")) == NULL) {
+      selset.size = 0;
+      selset.buf = NULL;
+      return selset;
+   }
+   fread( &selset.size, sizeof(long int), 1, fp );
+   selset.buf = (char *)malloc( ((selset.size/8L)+1L) * sizeof(char) );
+   if (selset.buf) {
+      fread( selset.buf, sizeof(char), (selset.size/8L)+1L, fp );
+      selset.diskstorage = 0;
+   } else {
+      selset.diskstorage = 1;
+      /* Can speed this up by buffering */
+      selset.fp = tmpfile();
+      if (!selset.fp) {
+	 selset.diskstorage=0;
+	 selset.size=0;
+	 selset.buf=NULL;
+	 return selset;
+      }
+      fread(&byte,1,1,selset.fp);
+      while (!feof(fp)) {
+	 fwrite(&byte,1,1,selset.fp);
+	 fread(&byte,1,1,fp);
+      }
+   }
+   fclose(fp);
+
+
+   return selset;
+}
+
+
+/*************************************************************************
+ *
+ *N  save_selected_features
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function saves the selection set for a given theme of the
+ *    specified view to a file in the view directory.
+ *
+ *    NOTE:  This function has "special knowledge" about the structure of
+ *    a set.  If that structure is changed, this function must account
+ *    for those changes.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     view     <input>==(view_type *) view structure.
+ *     themenum <input>==(int) theme number.
+ *     selset   <input>==(set_type) set of selected features.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void save_selected_features( view_type *view, int themenum,
+			     set_type selset )
+{
+   char path[80], *num="    ", byte;
+   FILE *fp;
+   register int i;
+
+   /* Determine the path name from the theme number */
+   strcpy(path,home);
+   strcat(path,view->name);
+   strcat(path,"\\sel");
+   num = itoa(themenum,num,10);
+   for (i=0;i<(4-strlen(num));i++)
+      strcat(path,"0");
+   strcat(path,num);
+
+   /* Write the set */
+   fp = fopen(path,"wb");
+   if (!fp) return;
+   fwrite( &(selset.size), sizeof(long int), 1, fp );
+   if (!selset.diskstorage) {
+      fwrite( selset.buf, sizeof(char), (selset.size/8L)+1L, fp );
+   } else {
+      rewind(selset.fp);
+      fread(&byte,1,1,selset.fp);
+      while (!feof(selset.fp)) {
+	 fwrite(&byte,1,1,fp);
+	 fread(&byte,1,1,selset.fp);
+      }
+   }
+   fclose(fp);
+}
+
+
+/*************************************************************************
+ *
+ *N  get_selected_features
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function gets the selection set for a given theme of the
+ *    specified view, either by querying the table, or by reading a
+ *    previously saved selection set file.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     view     <input>==(view_type *) view structure.
+ *     themenum <input>==(int) theme number.
+ *     library  <input>==(library-type) VPF library structure.
+ *     return  <output>==(set_type) set of selected features.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+set_type get_selected_features( view_type *view, int themenum,
+				library_type library )
+{
+   set_type selset;
+   vpf_table_type ft;
+   register int i;
+
+   /* Read a selection set, if present */
+   if (strcmp(view->name,"") != 0) {
+      selset = read_selected_features( view, themenum );
+      if (selset.size > 0) return selset;
+   }
+
+   /* No selection set... */
+
+   /* Find the feature class for the theme */
+   for (i=0;i<library.nfc;i++)
+      if (strcasecmp(library.fc[i].name,view->theme[themenum].fc)==0) break;
+   if (i>=library.nfc) {
+      display_message("Invalid theme in view");
+      return selset;
+   }
+
+   /* Query the feature table */
+   ft = vpf_open_table( library.fc[i].table, disk, "rb", NULL );
+   selset = query_table( view->theme[themenum].expression, ft );
+   vpf_close_table( &ft );
+
+   /* Save the selection set so we don't have to query again */
+   if (strcmp(view->name,"") != 0) {
+      save_selected_features( view, themenum, selset );
+   }
+
+   return selset;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  bounding_select
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function reads the bounding rectangle table to weed out the
+ *    local primitives.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    path      <input> == (char *) path to the bounding rectangle table.
+ *    mapextent <input> == (extent_type) map extent to compare.
+ *    dec_degrees <input> == (int) flag to indicate if data is in decimal
+ *                                 degrees.
+ *    bounding_select <output> == (set_type) set of bounding rectangle ids.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+set_type bounding_select( char *path, extent_type mapextent,
+			  int dec_degrees )
+{
+   vpf_table_type table;
+   set_type set;
+   long int i, count;
+   extent_type box, pextent;
+   double x1,y1,x2,y2;
+   row_type row;
+   int XMIN_,YMIN_,XMAX_,YMAX_;
+
+   /* Project all extents to plate-carree for cartesian comparisons */
+   /* (decimal degree coordinate systems) */
+
+   x1 = mapextent.x1; y1 = mapextent.y1;
+   x2 = mapextent.x2; y2 = mapextent.y2;
+   if (dec_degrees) {
+      set_plate_carree_parameters( central_meridian(x1,x2), 0.0, 1.0 );
+      pcarree_xy(&x1,&y1);
+      pcarree_xy(&x2,&y2);
+   }
+   pextent.x1 = x1; pextent.y1 = y1;
+   pextent.x2 = x2; pextent.y2 = y2;
+
+   table = vpf_open_table(path,disk,"rb",NULL);
+   XMIN_ = table_pos("XMIN",table);
+   YMIN_ = table_pos("YMIN",table);
+   XMAX_ = table_pos("XMAX",table);
+   YMAX_ = table_pos("YMAX",table);
+   set = set_init(table.nrows+1);
+   for (i=1;i<=table.nrows;i++) {
+      row = read_next_row(table);
+      get_table_element(XMIN_,row,table,&box.x1,&count);
+      get_table_element(YMIN_,row,table,&box.y1,&count);
+      get_table_element(XMAX_,row,table,&box.x2,&count);
+      get_table_element(YMAX_,row,table,&box.y2,&count);
+      free_row(row,table);
+
+      x1 = box.x1; y1 = box.y1;
+      x2 = box.x2; y2 = box.y2;
+      if (dec_degrees) {
+	 pcarree_xy(&x1,&y1);
+	 pcarree_xy(&x2,&y2);
+      }
+      box.x1 = x1; box.y1 = y1;
+      box.x2 = x2; box.y2 = y2;
+
+      if ( contained(box,pextent) || contained(pextent,box) ) {
+	 set_insert(i,set);
+      }
+   }
+   vpf_close_table(&table);
+
+   return set;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  tile_thematic_index_name
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function determines the name of the tile thematic index for
+ *    the given table.  If the table does not have a "TILE_ID" field,
+ *    the name is set to null.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     table    <input>==(vpf_table_type) opened VPF table.
+ *     path    <output>==(char *) name of the thematic index file.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+void tile_thematic_index_name( vpf_table_type table,
+			       char *path )
+{
+   int i;
+
+   i = table_pos("TILE_ID",table);
+   if (i<0) {
+      strcpy(path,"");
+   } else {
+      /* Thematic index name from the table header */
+      sprintf(path,"%s%s",table.path,table.header[i].tdx);
+   }
+}
+#endif
+/*************************************************************************
+ *
+ *N  completely_within
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function determines whether extent1 is completely within
+ *    extent2.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     extent1 <input>==(extent_type) first extent to compare.
+ *     extent2 <input>==(extent_type) second extent to compare.
+ *     return  <output>==(int) 1 if extent1 is completely within extent2,
+ *                             0 if not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+int completely_within( extent_type extent1, extent_type extent2 )
+{
+   if (extent1.x1 < extent2.x1) return 0;
+   if (extent1.y1 < extent2.y1) return 0;
+   if (extent1.x2 > extent2.x2) return 0;
+   if (extent1.y2 > extent2.y2) return 0;
+   return 1;
+}
+
+#ifdef __MSDOS__
+/*************************************************************************
+ *
+ *N  get_selected_primitives
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function determines all of the selected primitive rows from
+ *    the selected features.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     view     <input> == (view_type *) view structure.
+ *     themenum <input> == (int) theme number.
+ *     library  <input> == (library_type *) VPF library structure.
+ *     mapenv   <input> == (map_environment_type *) map environment.
+ *     status  <output> == (int *) status of the function:
+ *                         1 if completed, 0 if user escape.
+ *     get_selected_primitives <output> == (set_type *) array of sets, each position
+ *                         representing the set of primitives for the
+ *                         corresponding tile in the tileref.aft table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+set_type *get_selected_primitives( view_type *view,
+				   int themenum,
+				   library_type *library,
+				   map_environment_type *mapenv,
+				   int *status )
+{
+   int fcnum, finished, found, cov, tilecover, TILEPATH_, degree;
+   int feature, prim;
+   vpf_table_type tile_table;
+   row_type row;
+   char *ptable[] = {"","edg","fac","txt","end","cnd"};
+   char *spxname[] = {"","esi","fsi","tsi","nsi","csi"};
+   char *brname[] = {"","ebr","fbr","tbr","nbr","cbr"};
+   set_type feature_rows, primitive_rows, tile_features;
+   set_type *primitives;
+   long int prim_rownum, count, tile;
+   register long int i,j, pclass, start,end;
+   char path[255], covpath[255], tiledir[255], *buf, str[255];
+   fcrel_type fcrel;
+   linked_list_type primlist;
+   position_type p;
+   vpf_relate_struct rcell;
+   ThematicIndex idx;
+
+   primitives = (set_type *)vpfmalloc((library->ntiles+1)*sizeof(set_type));
+   for (i=0;i<=library->ntiles;i++) {
+      primitives[i].size = 0;
+      primitives[i].buf = NULL;
+   }
+
+   fcnum = view->theme[themenum].fcnum;
+
+   feature_rows = get_selected_features( view, themenum, *library );
+
+   /* Open the tile reference table, if present */
+   sprintf(path,"%stileref\\tileref.aft",library->path);
+   if (access(path,0) != 0) {
+      tilecover = FALSE;
+   } else {
+      tile_table = vpf_open_table(path,disk,"rb",NULL);
+      TILEPATH_ = table_pos("TILE_NAME",tile_table);
+      tilecover = TRUE;
+   }
+
+   for (pclass=EDGE;pclass<=CONNECTED_NODE;pclass++) {
+
+      if ((pclass != library->fc[fcnum].primclass) &&
+	  (library->fc[fcnum].primclass != COMPLEX_FEATURE)) continue;
+
+      /* Set up the feature class table relate chain.        */
+      /* The feature table is fcrel.table[0].                */
+      /* The primitive table is the last table in the chain: */
+      /*    fcrel.table[ fcrel.nchain-1 ].                   */
+
+      j = 0;
+      for (i=0;i<strlen(library->fc[fcnum].table);i++)
+	 if (library->fc[fcnum].table[i] == '\\') j = i+1;
+      strcpy( str, &(library->fc[fcnum].table[j]));
+      fcrel = select_feature_class_relate(fcnum, library, str,
+					  ptable[pclass]);
+      feature = 0;
+      prim = fcrel.nchain-1;
+
+      p = ll_previous(ll_last(fcrel.relate_list),fcrel.relate_list);
+      ll_element(p,&rcell);
+      degree = rcell.degree;
+
+      /*** 'Tile' number 1 is the universe polygon for the tileref cover ***/
+      for (tile = 2; tile <= library->ntiles; tile++ ) {
+
+	 if (!set_member(tile,library->tile_set)) continue;
+
+	 if (tilecover) {
+	    row = get_row(tile,tile_table);
+	    buf = (char *)get_table_element(TILEPATH_,row,tile_table,
+					     NULL,&count);
+	    free_row(row,tile_table);
+	    strcpy(tiledir,buf);
+	    rightjust(tiledir);
+	    strcat(tiledir,"\\");
+	    free(buf);
+	 } else {
+	    strcpy(tiledir,"");
+	 }
+
+	 cov = library->fc[fcnum].coverage;
+	 strcpy( covpath, library->cover[cov].path );
+
+	 finished = 1;
+	 found = 0;
+
+	 /* Open primitive table in tile */
+	 sprintf(path,"%s%s%s",covpath,tiledir,ptable[pclass]);
+	 if (access(path,0) != 0) continue;
+	 found = 1;
+	 fcrel.table[prim] = vpf_open_table(path,disk,"rb",NULL);
+
+	 if (primitives[tile].size > 0) {
+	    printf("Oops!  size = %ld\n",primitives[tile].size);
+	    exit(1);
+	 }
+	 primitives[tile] = set_init(fcrel.table[prim].nrows+1);
+
+	 /* Get the set of primitive rows within the map extent */
+
+	 /* Look for spatial index file */
+	 primitive_rows.size = 0;
+	 if (mapenv->projection == PLATE_CARREE &&
+	     mapenv->mapextent.x1 < mapenv->mapextent.x2) {
+	    sprintf(path,"%s%s%s",covpath,tiledir,spxname[pclass]);
+	    if ((access(path,0)==0)&&(fcrel.table[prim].nrows > 20)) {
+
+	       primitive_rows = spatial_index_search(path,
+			  mapenv->mapextent.x1,mapenv->mapextent.y1,
+			  mapenv->mapextent.x2,mapenv->mapextent.y2);
+
+	    } else {
+	       /* Next best thing - bounding rectangle table */
+	       sprintf(path,"%s%s%s",covpath,tiledir,brname[pclass]);
+	       if (access(path,0)==0) {
+		  primitive_rows = bounding_select(path,mapenv->mapextent,
+						   library->dec_degrees);
+	       }
+	    }
+	 } /* projection check */
+
+	 if (primitive_rows.size == 0) {
+	    /* Search through all the primitives */
+	    primitive_rows=set_init(fcrel.table[prim].nrows+1);
+	    set_on(primitive_rows);
+	 }
+
+	 tile_thematic_index_name(fcrel.table[feature], path);
+	 if ( (strcmp(path,"") != 0) && (access(path,4)==0) ) {
+	    /* Tile thematic index for feature table present, */
+	    tile_features = read_thematic_index( path, (char *)&tile );
+	 } else {
+	    tile_features = set_init(fcrel.table[feature].nrows+1);
+	    set_on(tile_features);
+	 }
+
+	 idx.fp = NULL;
+	 i = table_pos(rcell.key2,fcrel.table[prim]);
+	 if (i >= 0) {
+	    if (fcrel.table[prim].header[i].tdx) {
+	       sprintf(path,"%s%s",fcrel.table[prim].path,
+				fcrel.table[prim].header[i].tdx);
+	       if (access(path,0)==0)
+		  idx = open_thematic_index(path);
+	    }
+	    if (fcrel.table[prim].header[i].keytype == 'U') degree = R_ONE;
+	    if (fcrel.table[prim].header[i].keytype == 'N') degree = R_MANY;
+	    if (fcrel.table[prim].header[i].keytype == 'P') degree = R_ONE;
+	 }
+
+	 finished = 1;
+
+	 start = set_min(tile_features);
+	 end = set_max(tile_features);
+
+	 fseek(fcrel.table[feature].fp,
+	       index_pos(start,fcrel.table[feature]),
+	       SEEK_SET);
+
+	 for (i=start;i<=end;i++) {
+
+	    row = read_next_row(fcrel.table[feature]);
+
+	    if (!set_member( i, feature_rows )) {
+	       free_row(row,fcrel.table[feature]);
+	       continue;
+	    }
+
+	    if (!set_member( i, tile_features )) {
+	       free_row(row,fcrel.table[feature]);
+	       continue;
+	    }
+
+	    if (degree == R_ONE) {
+	       prim_rownum = fc_row_number( row, fcrel, tile );
+	       primlist = NULL;
+	       p = NULL;
+	    } else {
+	       primlist = fc_row_numbers( row, fcrel, tile, &idx );
+	    }
+
+	    free_row( row, fcrel.table[feature] );
+
+	    if (!primlist) {
+	       if ((prim_rownum<1)||
+		   (prim_rownum>fcrel.table[prim].nrows))
+		  continue;
+	       if (set_member( prim_rownum, primitive_rows )) {
+		  set_insert(prim_rownum,primitives[tile]);
+	       }
+	    } else {
+	       p = ll_first(primlist);
+	       while (!ll_end(p)) {
+		  ll_element(p,&prim_rownum);
+		  if ((prim_rownum<1)||
+		      (prim_rownum>fcrel.table[prim].nrows))
+		     continue;
+		  if (set_member( prim_rownum, primitive_rows )) {
+		     set_insert(prim_rownum,primitives[tile]);
+		  }
+		  p = ll_next(p);
+	       }
+	    }
+
+	    if (kbhit()) {
+	       if (getch()==27) {
+		  *status = 0;
+		  finished = 0;
+		  break;
+	       }
+	    }
+	 }
+
+	 if (idx.fp) close_thematic_index(&idx);
+
+	 vpf_close_table(&(fcrel.table[prim]));
+
+	 set_nuke(&primitive_rows);
+
+	 set_nuke(&tile_features);
+
+	 if (set_empty(primitives[tile])) {
+	    set_nuke(&primitives[tile]);
+	    primitives[tile].size = 0;
+	    primitives[tile].buf = NULL;
+	 }
+
+	 if (!finished) {
+	    *status = 0;
+	    break;
+	 }
+
+      }
+
+      if (!finished) {
+	 *status = 0;
+	 deselect_feature_class_relate( &fcrel );
+	 break;
+      }
+
+      if (found) *status = 1;
+
+      if (kbhit()) {
+	 if (getch()==27) {
+	    *status = 0;
+	    deselect_feature_class_relate( &fcrel );
+	    break;
+	 }
+      }
+
+      deselect_feature_class_relate( &fcrel );
+   }
+
+   set_nuke(&feature_rows);
+
+   if (tilecover) {
+      vpf_close_table(&tile_table);
+   }
+
+   return primitives;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  get_selected_tile_primitives
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function determines all of the selected primitive rows from
+ *    the selected features of a given tile.
+ *
+ *    This function expects a feature class relationship structure that
+ *    has been successfully created with select_feature_class_relate()
+ *    from the feature table to the primitive.  The primitive table in
+ *    the feature class relate structure must have been successfully
+ *    opened for the given tile.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     library   <input>==(library_type *) VPF library structure.
+ *     fcnum     <input>==(int) feature class number of the feature table.
+ *     fcrel     <input>==(fcrel_type) feature class relate structure.
+ *     feature_rows <input>==(set_type) set of selected features.
+ *     mapenv    <input>==(map_environment_type *) map environment.
+ *     tile      <input>==(long int) tile number.
+ *     tiledir   <input>==(char *) path to the tile directory.
+ *     status   <output>==(int *) status of the function:
+ *                         1 if completed, 0 if user escape.
+ *     return   <output>==(set_type) set of primitives for the features
+ *                         in the corresponding tile.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                           DOS Turbo C
+ *E
+ *************************************************************************/
+set_type get_selected_tile_primitives( library_type *library,
+				       int fcnum,
+				       fcrel_type fcrel,
+				       set_type feature_rows,
+				       map_environment_type *mapenv,
+				       long int tile,
+				       char *tiledir,
+				       int *status )
+{
+   int cov, degree;
+   int feature, prim;
+   row_type row;
+   char *spxname[] = {"","esi","fsi","tsi","nsi","csi"};
+   char *brname[] = {"","ebr","fbr","tbr","nbr","cbr"};
+   set_type primitive_rows, tile_features;
+   set_type primitives;
+   long int prim_rownum;
+   register long int i,pclass, start,end;
+   char path[255], covpath[255];
+   linked_list_type primlist;
+   position_type p;
+   vpf_relate_struct rcell;
+   ThematicIndex idx;
+
+   feature = 0;
+   prim = fcrel.nchain-1;
+
+   /* Assume that fcrel.table[prim] has been opened */
+
+   primitives.size = 0;
+   primitives.buf = NULL;
+
+   cov = library->fc[fcnum].coverage;
+   strcpy( covpath, library->cover[cov].path );
+
+   p = ll_previous(ll_last(fcrel.relate_list),fcrel.relate_list);
+   ll_element(p,&rcell);
+   degree = rcell.degree;
+
+   for (pclass=EDGE;pclass<=CONNECTED_NODE;pclass++) {
+
+      if ((pclass != library->fc[fcnum].primclass) &&
+	  (library->fc[fcnum].primclass != COMPLEX_FEATURE)) continue;
+
+      primitives = set_init(fcrel.table[prim].nrows+1);
+
+      /* Get the set of primitive rows within the map extent */
+
+      /* Look for the spatial index file to weed out primitives in the */
+      /* given tile but outside of the viewing area.  If a projection  */
+      /* other than plate-carree (rectangular) is on, or if the extent */
+      /* crosses the meridian, the quick check is no longer valid.     */
+
+      primitive_rows.size = 0;
+
+      if (mapenv->projection == PLATE_CARREE &&
+	  mapenv->mapextent.x1 < mapenv->mapextent.x2) {
+	 sprintf(path,"%s%s%s",covpath,tiledir,spxname[pclass]);
+	 /* 20 (below) is a fairly arbitrary cutoff of the number of */
+	 /* primitives that make a spatial index search worth while. */
+	 if ((access(path,0)==0)&&(fcrel.table[prim].nrows > 20)) {
+	    primitive_rows = spatial_index_search(path,
+			  mapenv->mapextent.x1,mapenv->mapextent.y1,
+			  mapenv->mapextent.x2,mapenv->mapextent.y2);
+	 } else {
+	    /* Next best thing - bounding rectangle table */
+	    sprintf(path,"%s%s%s",covpath,tiledir,brname[pclass]);
+	    if ((access(path,0)==0)&&(fcrel.table[prim].nrows > 20)) {
+	       primitive_rows = bounding_select(path,mapenv->mapextent,
+						library->dec_degrees);
+	    }
+	 }
+      }
+      if (primitive_rows.size == 0) {
+	 /* Search through all the primitives */
+	 primitive_rows=set_init(fcrel.table[prim].nrows+1);
+	 set_on(primitive_rows);
+      }
+
+      if (strcmp(tiledir,"") != 0) {
+	 tile_thematic_index_name(fcrel.table[feature], path);
+	 if ((strcmp(path,"")!=0) && (access(path,4)==0)) {
+	    /* Tile thematic index for feature table present, */
+	    tile_features = read_thematic_index( path, (char *)&tile );
+	 } else {
+	    tile_features = set_init(fcrel.table[feature].nrows+1);
+	    set_on(tile_features);
+	 }
+      } else {
+	 tile_features = set_init(fcrel.table[feature].nrows+1);
+	 set_on(tile_features);
+      }
+      set_delete(0,tile_features);
+
+      idx.fp = NULL;
+      i = table_pos(rcell.key2,fcrel.table[prim]);
+      if (i >= 0) {
+	 if (fcrel.table[prim].header[i].tdx) {
+	    sprintf(path,"%s%s",fcrel.table[prim].path,
+				fcrel.table[prim].header[i].tdx);
+	    if (access(path,0)==0)
+	       idx = open_thematic_index(path);
+	 }
+	 if (fcrel.table[prim].header[i].keytype == 'U') degree = R_ONE;
+	 if (fcrel.table[prim].header[i].keytype == 'N') degree = R_MANY;
+	 if (fcrel.table[prim].header[i].keytype == 'P') degree = R_ONE;
+      }
+
+      start = set_min(tile_features);
+      end = set_max(tile_features);
+
+      /* It turns out to be MUCH faster off of a CD-ROM to */
+      /* read each row and discard unwanted ones than to   */
+      /* forward seek past them.  It's about the same off  */
+      /* of a hard disk.				      */
+
+      fseek(fcrel.table[feature].fp,index_pos(start,fcrel.table[feature]),
+	    SEEK_SET);
+
+      for (i=start;i<=end;i++) {
+
+	 row = read_next_row(fcrel.table[feature]);
+
+	 if (!set_member( i, feature_rows )) {
+	    free_row(row,fcrel.table[feature]);
+	    continue;
+	 }
+	 if (!set_member( i, tile_features )) {
+	    free_row(row,fcrel.table[feature]);
+	    continue;
+	 }
+
+	 if (degree == R_ONE) {
+	    prim_rownum = fc_row_number( row, fcrel, tile );
+	    primlist = NULL;
+	    p = NULL;
+	 } else {
+	    primlist = fc_row_numbers( row, fcrel, tile, &idx );
+	 }
+
+	 free_row( row, fcrel.table[feature] );
+
+	 if (!primlist) {
+	    if ((prim_rownum<1)||(prim_rownum>fcrel.table[prim].nrows))
+	       continue;
+	    if (set_member( prim_rownum, primitive_rows )) {
+	       set_insert(prim_rownum,primitives);
+	    }
+	 } else {
+	    p = ll_first(primlist);
+	    while (!ll_end(p)) {
+	       ll_element(p,&prim_rownum);
+	       if ((prim_rownum<1)||
+		   (prim_rownum>fcrel.table[prim].nrows))
+		  continue;
+	       if (set_member( prim_rownum, primitive_rows )) {
+		  set_insert(prim_rownum,primitives);
+	       }
+	       p = ll_next(p);
+	    }
+	 }
+
+	 if (primlist) ll_reset(primlist);
+
+	 if (kbhit()) {
+	    if (getch()==27) {
+	       *status = 0;
+	       break;
+	    }
+	 }
+      }
+
+      set_nuke(&primitive_rows);
+
+      set_nuke(&tile_features);
+
+      if (idx.fp) close_thematic_index(&idx);
+
+      *status = 1;
+
+      if (kbhit()) {
+	 if (getch()==27) {
+	    *status = 0;
+	    break;
+	 }
+      }
+   }
+
+   return primitives;
+}
+#endif
+
+#if __MSDOS__
+static long int filesize( char *file )
+{
+   struct stat s;
+   stat(file,&s);
+   return (long int)s.st_size;
+}
+
+static long int available_space( char *drive )
+{
+   struct dfree disktable;
+   int disknum;
+
+   if (!drive) return 0;
+
+   disknum=toupper(drive[0])-'A'+1;
+   getdfree(disknum,&disktable);
+   return (long int) disktable.df_avail *
+	  (long int) disktable.df_sclus *
+	  (long int) disktable.df_bsec;
+}
+#endif
+
+#ifdef __MSDOS__
+/*************************************************************************
+ *
+ *N  draw_selected_features
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    This function draws the selected features from a specified feature
+ *    class based upon a query (either an expression or the pre-compiled
+ *    results of an expression).
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     view     <inout>==(view_type *) view structure.
+ *     themenum <input>==(int) theme number.
+ *     library  <input>==(library_type *) VPF library structure.
+ *     mapenv   <input>==(map_environment_type *) map environment structure.
+ *     return  <output>==(int) completion status:
+ *                                1 if completed successfully,
+ *                                0 if an error occurred.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   August 1991                        DOS Turbo C
+ *E
+ *************************************************************************/
+int draw_selected_features( view_type *view,
+			    int themenum,
+			    library_type *library,
+			    map_environment_type *mapenv )
+{
+   int status, fcnum, finished, cov, tilecover, TILEPATH_, prim;
+   int outline, color1, color2, color3, color4;
+   vpf_table_type rngtable,edgtable,fbrtable, tile_table;
+   row_type row;
+   char *ptable[] = {"","edg","fac","txt","end","cnd"};
+   register long int i, j, p, pclass, tile;
+   int display_order[] = {FACE,EDGE,ENTITY_NODE,CONNECTED_NODE,TEXT};
+   register long int starttile, endtile, startprim, endprim;
+   long int count;
+   char path[255], covpath[255], tiledir[255], *buf, str[255];
+   char *drive, rngpath[255],edgpath[255],edxpath[255],fbrpath[255];
+   boolean rng_rdisk,edg_rdisk,fbr_rdisk;
+   set_type primitives, feature_rows;
+   fcrel_type fcrel;
+   window_type info;
+   struct viewporttype vp;
+
+   getviewsettings(&vp);
+
+   fcnum = view->theme[themenum].fcnum;
+
+   sprintf(path,"%stileref\\tileref.aft",library->path);
+   if (access(path,0) != 0) {
+      tilecover = FALSE;
+   } else {
+      tile_table = vpf_open_table(path,disk,"rb",NULL);
+      TILEPATH_ = table_pos("TILE_NAME",tile_table);
+      tilecover = TRUE;
+   }
+
+   feature_rows = get_selected_features( view, themenum, *library );
+
+   for (p=0;p<5;p++) {
+      pclass = display_order[p];
+
+      if ((pclass != library->fc[fcnum].primclass) &&
+	  (library->fc[fcnum].primclass != COMPLEX_FEATURE)) continue;
+
+      if ((library->fc[fcnum].primclass == COMPLEX_FEATURE) &&
+	  (!library->fc[fcnum].cprim[pclass])) continue;
+
+      /* Set up the feature class table relate chain.        */
+      /* The feature table is fcrel.table[0].                */
+      /* The primitive table is the last table in the chain: */
+      /*    fcrel.table[ fcrel.nchain-1 ].                   */
+
+      j = 0;
+      for (i=0;i<strlen(library->fc[fcnum].table);i++)
+	 if (library->fc[fcnum].table[i] == '\\') j = i+1;
+      strcpy( str, &(library->fc[fcnum].table[j]));
+      fcrel = select_feature_class_relate(fcnum, library, str,
+					  ptable[pclass]);
+      prim = fcrel.nchain-1;
+
+      /*** 'Tile' number 1 is the universe polygon for
+	   the tileref cover ***/
+      starttile = set_min(library->tile_set);
+      if (starttile < 2) starttile = 2;
+      endtile = set_max(library->tile_set);
+      if (endtile < 2) endtile = 2;
+
+      for (tile = starttile; tile <= endtile; tile++ ) {
+
+	 if (!set_member(tile,library->tile_set)) continue;
+
+	 if (tilecover) {
+	    row = get_row(tile,tile_table);
+	    buf = (char *)get_table_element(TILEPATH_,row,tile_table,
+					     NULL,&count);
+	    free_row(row,tile_table);
+	    strcpy(tiledir,buf);
+	    rightjust(tiledir);
+	    strcat(tiledir,"\\");
+	    free(buf);
+	 } else {
+	    strcpy(tiledir,"");
+	 }
+
+	 cov = library->fc[fcnum].coverage;
+	 strcpy( covpath, library->cover[cov].path );
+
+	 finished = TRUE;
+
+	 sprintf(path,"%s%s%s",covpath,tiledir,ptable[pclass]);
+
+	 if (access(path,0) != 0) continue;
+	 fcrel.table[prim] = vpf_open_table(path,disk,"rb",NULL);
+
+	 info = info_window("Searching...");
+
+	 primitives = get_selected_tile_primitives( library,
+						    fcnum, fcrel,
+						    feature_rows,
+						    mapenv,
+						    tile, tiledir,
+						    &status );
+	 delete_window(&info);
+	 setviewport(vp.left,vp.top,vp.right,vp.bottom,vp.clip);
+
+	 /* Reset plate-carree parameters (changed in  */
+	 /* get_selected_tile_primitives() )           */
+	 if (mapenv->projection == PLATE_CARREE)
+	    set_plate_carree_parameters( central_meridian(
+					 mapenv->mapextent.x1,
+					 mapenv->mapextent.x2),
+					 0.0, 1.0 );
+
+	 if (primitives.size < 1) {
+	    vpf_close_table(&fcrel.table[prim]);
+	    continue;
+	 }
+
+	 if (!status) {
+	    set_nuke(&primitives);
+	    vpf_close_table(&fcrel.table[prim]);
+	    break;
+	 }
+
+	 if (pclass == FACE) {
+	    /* Must also open RNG, EDG, and FBR for drawing faces. */
+	    /* If a RAM disk is specified, copy these to it and open */
+	    /* them there. */
+	    rng_rdisk = FALSE;
+	    edg_rdisk = FALSE;
+	    fbr_rdisk = FALSE;
+	    drive = getenv("TMP");
+	    buf = (char *)vpfmalloc(255);
+
+	    sprintf(path,"%s%srng",covpath,tiledir);
+	    strcpy(rngpath,path);
+	    if (drive && filesize(path) < available_space(drive)) {
+	       sprintf(rngpath,"%s\\RNG",drive);
+	       sprintf(buf,"COPY %s %s > NUL",path,rngpath);
+	       system(buf);
+	       rng_rdisk = TRUE;
+	    }
+	    rngtable = vpf_open_table(rngpath,disk,"rb",NULL);
+
+	    sprintf(path,"%s%sedg",covpath,tiledir);
+	    strcpy(edgpath,path);
+            sprintf(edxpath,"%s%sedx",covpath,tiledir);
+	    if (drive &&
+	       (filesize(path)+filesize(edxpath))<available_space(drive)) {
+	       sprintf(edgpath,"%s\\EDG",drive);
+	       sprintf(buf,"COPY %s %s > NUL",path,edgpath);
+	       system(buf);
+	       sprintf(edxpath,"%s\\EDX",drive);
+	       sprintf(buf,"COPY %s%sedx %s > NUL",covpath,tiledir,edxpath);
+	       system(buf);
+	       edg_rdisk = TRUE;
+	    }
+	    edgtable = vpf_open_table(edgpath,disk,"rb",NULL);
+
+	    sprintf(path,"%s%sfbr",covpath,tiledir);
+	    strcpy(fbrpath,path);
+	    if (drive && filesize(path) < available_space(drive)) {
+	       sprintf(fbrpath,"%s\\FBR",drive);
+	       sprintf(buf,"COPY %s %s > NUL",path,fbrpath);
+	       system(buf);
+	       fbr_rdisk = TRUE;
+	    }
+	    fbrtable = vpf_open_table(fbrpath,disk,"rb",NULL);
+
+	    free(buf);
+	 }
+
+	 finished = 1;
+
+	 startprim = set_min(primitives);
+	 endprim = set_max(primitives);
+
+	 /* It turns out to be MUCH faster off of a CD-ROM to */
+	 /* read each row and discard unwanted ones than to   */
+	 /* forward seek past them.  It's about the same off  */
+	 /* of a hard disk.				      */
+
+	 fseek(fcrel.table[prim].fp,
+	       index_pos(startprim,fcrel.table[prim]),
+	       SEEK_SET);
+
+	 for (i=startprim;i<=endprim;i++) {
+
+	    row = read_next_row(fcrel.table[prim]);
+
+	    if (set_member( i, primitives )) {
+	       /* Draw the primitive */
+	       switch (pclass) {
+		  case EDGE:
+		     finished = draw_edge_row(row,fcrel.table[prim]);
+		     break;
+		  case ENTITY_NODE:
+		  case CONNECTED_NODE:
+		     finished = draw_point_row(row,fcrel.table[prim]);
+		     break;
+		  case FACE:
+		     gpgetlinecolor( &outline );
+		     gpgetpattern( &color1, &color2, &color3, &color4 );
+		     hidemousecursor();
+		     draw_face_row( row,fcrel.table[prim],
+				    rngtable, edgtable, fbrtable,
+				    outline,
+				    color1, color2, color3, color4 );
+		     showmousecursor();
+		     finished = 1;
+		     if (kbhit()) {
+			if (getch()==27) finished = 0;
+		     }
+		     break;
+		  case TEXT:
+		     finished = draw_text_row(row,fcrel.table[prim]);
+		     break;
+	       }
+	    }
+
+	    free_row(row,fcrel.table[prim]);
+
+	    if (!finished) {
+	       status = 0;
+	       break;
+	    }
+	 }
+
+	 if (pclass == FACE) {
+	    vpf_close_table(&rngtable);
+	    if (rng_rdisk) remove(rngpath);
+	    vpf_close_table(&edgtable);
+	    if (edg_rdisk) {
+	       remove(edgpath);
+	       remove(edxpath);
+	    }
+	    vpf_close_table(&fbrtable);
+	    if (fbr_rdisk) remove(fbrpath);
+	 }
+
+	 vpf_close_table(&fcrel.table[prim]);
+
+	 set_nuke(&primitives);
+
+	 if (!finished) {
+	    status = 0;
+	    break;
+	 }
+
+      }
+
+      if (!finished) {
+	 status = 0;
+	 deselect_feature_class_relate( &fcrel );
+	 break;
+      }
+
+      status = 1;
+
+      if (kbhit()) {
+	 if (getch()==27) {
+	    status = 0;
+	    deselect_feature_class_relate( &fcrel );
+	    break;
+	 }
+      }
+
+      deselect_feature_class_relate(&fcrel);
+   }
+
+   if (tilecover) {
+      vpf_close_table(&tile_table);
+   }
+
+   set_nuke(&feature_rows);
+
+   return status;
+}
+#endif
+
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfselec.h b/Utilities/OSSIM/ossim_core/vpf_util/vpfselec.h
new file mode 100644
index 0000000000..f8f31e42c7
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfselec.h
@@ -0,0 +1,41 @@
+/* VPFSELEC.H - SELECT VPF FEATURES */
+
+#ifndef __VPFSELEC_H__
+
+#define __VPFSELEC_H__ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+set_type read_selected_features( view_type *view, int themenum );
+
+void save_selected_features( view_type *view, int themenum,
+			     set_type selset );
+
+set_type get_selected_features( view_type *view, int themenum,
+				library_type library );
+
+set_type bounding_select( char *path, extent_type mapextent,
+			  int dec_degrees );
+
+#ifndef __MSDOS__
+int completely_within( extent_type extent1, extent_type extent2 );
+#endif
+
+set_type *get_selected_primitives( view_type *view, int themenum,
+				   library_type *library,
+				   map_environment_type *mapenv,
+				   int *status );
+
+int draw_selected_features( view_type *view,
+			    int themenum,
+			    library_type *library,
+			    map_environment_type *mapenv );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfspx.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfspx.c
new file mode 100644
index 0000000000..f570d8eb9c
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfspx.c
@@ -0,0 +1,359 @@
+/*************************************************************************
+ *
+ *N  Module VPFSPX.C
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions for reading the VPF spatial index
+ *     file.  A VPF spatial index is a modified quad-tree index with a
+ *     cross-over bin for features spanning more than one spatial cell.
+ *     There is one interface function in this module -
+ *     spatial_index_search().  The spatial index creation function is
+ *     not included.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Mody Buchbinder  Jul 1991   Original coding
+ *    Barry Michaels   Aug 1991   Customized for VPFVIEW
+ *E
+ *************************************************************************/
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+#include <fcntl.h>
+#ifdef __MSDOS__
+#  include <mem.h>
+#  include <conio.h>
+#  include <sys\stat.h>
+#  include <dos.h> 
+#else
+#  include <sys/stat.h>
+#endif
+#include <stdlib.h>
+#ifdef __MSDOS__
+#  include <io.h>
+#endif
+#ifdef _MSC_VER
+#  include <io.h>
+#endif
+#ifndef _MSDOS__
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#endif
+#include "set.h"
+
+/******* cellmap definitions **/
+#define  START     0
+#define  NUMFEAT   1
+
+#define OUT        0
+#define IN         1
+
+#define ID         1
+#define BOUND      0
+
+#define TOTAL_NUMBER 0
+#define BOUND_START  1
+#define CELLMAP_SIZE 5
+
+#define XMIN 0
+#define YMIN 1
+#define XMAX 2
+#define YMAX 3
+
+typedef struct {
+   int fd;                     /* File descriptor */
+   long int maplen;            /* Number of cells in the tree */
+   long int cellmap[1023][2];  /* The tree of cells */
+   long int buf[1023][2];      /* Buffer for one cell */
+   long int shift;             /* Size of data before real cell records */
+   unsigned char box[4];       /* Search box */
+} spx_type;
+
+
+/*************************************************************************
+ *
+ *N  is_over
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Determine if two boxes overlap.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    box1    <input>==(unsigned char[4]) first box to check.
+ *    box2    <input>==(unsigned char[4]) second box to check.
+ *    return <output>==(int) 1 if the boxes overlap,
+ *                             0 if the boxes do not.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Mody Buchbinder  Jul 1991
+ *E
+ *************************************************************************/
+static int is_over( unsigned char box1[4], unsigned char box2[4] )
+{
+   int xmin,xmax,ymin,ymax;
+
+   if(box2[XMIN] >= box1[XMIN] && box2[XMIN] <= box1[XMAX])
+      xmin = IN;
+   else
+      xmin = OUT;
+   if(box2[XMAX] >= box1[XMIN] && box2[XMAX] <= box1[XMAX])
+      xmax = IN;
+   else
+      xmax = OUT;
+   if(box2[YMIN] >= box1[YMIN] && box2[YMIN] <= box1[YMAX])
+      ymin = IN;
+   else
+      ymin = OUT;
+   if(box2[YMAX] >= box1[YMIN] && box2[YMAX] <= box1[YMAX])
+      ymax = IN;
+   else
+      ymax = OUT;
+   /* complete overlap */
+   if(xmin == OUT && xmax == OUT && box2[XMIN] <= box1[XMIN] &&
+      box2[XMAX] >= box1[XMAX])
+      xmin = IN;
+   if(ymin == OUT && ymax == OUT && box2[YMIN] <= box1[YMIN] &&
+      box2[YMAX] >= box1[YMAX])
+      ymin = IN;
+
+   if((xmin == IN || xmax == IN) && (ymin == IN || ymax == IN)) return 1;
+
+   return 0;
+}
+
+
+/*************************************************************************
+ *
+ *N  get_record
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Read spatial index record 'num'.  Insert the record into the search
+ *    set if it falls within the search box.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    num  <input>==(long int) record number.
+ *    spx  <input>==(spx_type *) spatial index record structure.
+ *    set <output>==(set_type) search set to be updated.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Mody Buchbinder  Jul 1991
+ *E
+ *************************************************************************/
+static void get_record(long int num, spx_type *spx, set_type set )
+{
+   long offset;
+   int j,index;
+   unsigned char box[4];
+
+   index  = num -1;
+   offset = spx->cellmap[index][0] + spx->shift;
+   lseek(spx->fd,offset,SEEK_SET);
+   read(spx->fd,spx->buf,2*spx->cellmap[index][NUMFEAT]*sizeof(long int));
+
+   for(j=0;j<spx->cellmap[index][NUMFEAT];j++) {
+      memcpy(&box,&(spx->buf[j][BOUND]),4*sizeof(unsigned char));
+      if (is_over(box,spx->box)) {
+	 set_insert(spx->buf[j][ID],set);
+      }
+   }
+
+}
+
+
+/*************************************************************************
+ *
+ *N  search_cell
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Search the current cell for local records and, if the box is in the
+ *    search area, search the cell's children.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    record <input>==(long int) record number.
+ *    level  <input>==(int) level of the index tree.
+ *    bnd    <input>==(unsigned char[4]) bounding box.
+ *    spx    <input>==(spx_type *) spatial index record structure.
+ *    set   <output>==(set_type) search set to be updated.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Mody Buchbinder  Jul 1991
+ *E
+ *************************************************************************/
+static void search_cell( long int record, int level, unsigned char bnd[4],
+			 spx_type *spx, set_type set )
+{
+   int i;
+   unsigned char locbnd[4],cut;
+
+  for(i=0;i<4;i++) locbnd[i] = bnd[i];
+  if(level != 0)
+    { /* level even -> cut on x , level odd -> cut on y */
+      if(level%2 == 1) cut = bnd[0] + ((bnd[2] - bnd[0]) >> 1);
+      else             cut = bnd[1] + ((bnd[3] - bnd[1]) >> 1);
+      /* cut on x right cell */
+      if(level%2 == 1 && record%2 == 0) locbnd[0] = cut;
+      /* cut on x left cell */
+      if(level%2 == 1 && record%2 == 1) locbnd[2] = cut;
+      /* cut on y upper cell */
+      if(level%2 == 0 && record%2 == 0) locbnd[1] = cut;
+      /* cut on y lower cell */
+      if(level%2 == 0 && record%2 == 1) locbnd[3] = cut;
+     }
+  if(is_over(locbnd,spx->box) == 1)
+    { get_record(record,spx,set);
+      if(record*2 <= spx->maplen)
+       { search_cell(record*2,  level+1,locbnd, spx, set);
+	 search_cell(record*2+1,level+1,locbnd, spx, set);
+       }
+    }
+}
+
+
+/*************************************************************************
+ *
+ *N  spatial_index_search
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *    Search the named spatial index file to find all records falling
+ *    within the specified extent.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    fname <input>==(char *) path name to a VPF spatial index file.
+ *    x1    <input>==(float) left coordinate of the search box.
+ *    y1    <input>==(float) bottom coordinate of the search box.
+ *    x2    <input>==(float) right coordinate of the search box.
+ *    y2    <input>==(float) top coordinate of the search box.
+ *    set  <output>==(set_type) search set to be filled.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Mody Buchbinder  Jul 1991
+ *E
+ *************************************************************************/
+set_type spatial_index_search( char *fname,
+			       float x1, float y1, float x2, float y2 )
+{
+   long head[6];
+   float bnd[4],xf,yf;
+   unsigned char tempbox[4];
+   set_type set;
+   spx_type spx;
+
+#ifdef __MSDOS__
+   spx.fd = open(fname,O_RDONLY | O_BINARY);
+#else
+   spx.fd = open(fname,O_RDONLY);
+#endif
+   if(spx.fd == -1) {
+      printf("Cannot open spatial index file (%s) \n",fname);
+      perror("spatial_index_search: ");
+      set.size = 0;
+      set.buf = NULL;
+      set.diskstorage = 0;
+      return set;
+   }
+
+/*   read basic header - int  0 -> number of features in coverage */
+/*                       int  1 - 4 -> boundaries of coverage     */
+/*                       int  5 -> size of tree in records - each */
+/*                                 record = 2 integers (8 byte)   */
+   read(spx.fd,head,6*sizeof(long int));
+   spx.shift = 6*sizeof(long int);
+   spx.maplen = head[CELLMAP_SIZE];
+
+   set = set_init(head[TOTAL_NUMBER]+1L);
+
+   memcpy(&bnd[0],&head[BOUND_START],4*sizeof(float));
+
+   /* If the boundaries of the cellmap are completely within the */
+   /* search area, all features are on */
+   if ( (x1 <= bnd[XMIN]) && (x2 >= bnd[XMAX]) &&
+	(y1 <= bnd[YMIN]) && (y2 >= bnd[YMAX]) ) {
+      set_on(set);
+      close(spx.fd);
+      return set;
+   }
+
+/* read the cell tree */
+
+   if(read(spx.fd,spx.cellmap,2*spx.maplen*sizeof(long int)) !=
+      2*spx.maplen*sizeof(long int)) {
+      close(spx.fd);
+      return set;
+   }
+
+   spx.shift += 2*spx.maplen*sizeof(long int);
+
+/* translate search box to 1 byte numbers */
+   xf = (float)(255.0 / (bnd[XMAX] - bnd[XMIN]));
+   yf = (float)(255.0 / (bnd[YMAX] - bnd[YMIN]));
+   spx.box[XMIN] = (char)((x1 - bnd[XMIN]) * xf);
+   if (x1 <= bnd[XMIN]) spx.box[XMIN] = 0;
+   if (x1 >= bnd[XMAX]) spx.box[XMIN] = 255;
+   spx.box[YMIN] = (char)((y1 - bnd[YMIN]) * yf);
+   if (y1 <= bnd[YMIN]) spx.box[YMIN] = 0;
+   if (y1 >= bnd[YMAX]) spx.box[YMIN] = 255;
+   spx.box[XMAX] = (char)(((x2 - bnd[XMIN]) * xf) + 1);
+   if (x2 <= bnd[XMIN]) spx.box[XMAX] = 0;
+   if (x2 >= bnd[XMAX]) spx.box[XMAX] = 255;
+   spx.box[YMAX] = (char)(((y2 - bnd[YMIN]) * yf) + 1);
+   if (y2 <= bnd[YMIN]) spx.box[YMAX] = 0;
+   if (y2 >= bnd[YMAX]) spx.box[YMAX] = 255;
+
+/** start search **/
+   tempbox[XMIN] = 0;
+   tempbox[YMIN] = 0;
+   tempbox[XMAX] = 0xff;
+   tempbox[YMAX] = 0xff;
+   search_cell(1,0,tempbox,&spx,set);
+
+   close(spx.fd);
+
+   return set;
+}
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpftable.c b/Utilities/OSSIM/ossim_core/vpf_util/vpftable.c
new file mode 100644
index 0000000000..a5536a2955
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpftable.c
@@ -0,0 +1,1058 @@
+/*************************************************************************
+ *
+ * Environmental Systems Research Institute (ESRI) Applications Programming
+ *
+ *N  Module VPFTABLE.C
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This module contains functions to open, close and parse VPF relational
+ *     tables.  VPF tables are defined as being a set of rows and columns.
+ *     Each column may contain a single value, a fixed array of values,
+ *     or a variable number of values.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   April 1991  - DOS Turbo C.
+ *    Mody Buchbinder  May 1991    - Modified parse_data_def for new table
+ *                                   header structure.
+ *    Dave Flinn       July 1991   - Updated file for UNIX.
+ *    JTB              10/91       - split off read routines into vpfread.c
+ *                                   merged view and converter branches of
+ *                                   this module; replaced various aborts()
+ *                                   and exits with return codes
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    (function) displayerror(char *text[], int nlines) - function
+ *       specified by the application to display a message to the user.
+ *       It should return an integer indicating whether to retry (1) or
+ *       not (0).
+ *    FILE *errorfp - file pointer to error file.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *    Updated to port to UNIX platforms with big-endian architectures
+ *E
+ *************************************************************************/
+
+#include "machine.h"
+#ifdef CARBON
+#define MACHINE_BYTE_ORDER 0
+#endif
+
+#ifdef __MSDOS__
+#include <mem.h>
+#include <io.h>
+#include <alloc.h>
+#include <dos.h>
+#include <graphics.h>
+#else
+#ifndef _WIN32
+#define UNIX 1
+#include <unistd.h>
+#endif
+#endif
+
+#if UNIX
+#include <sys/stat.h>
+#include <sys/types.h>
+#define   getch()               /* Make this a null function */
+#define   farcoreleft()	" "
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "./values.h"
+#include "vpftable.h"
+#include "vpftidx.h"
+#include "vpfmisc.h"
+
+#ifndef __64K
+#define __64K 65536
+#endif
+
+/*
+ * per heap block byte overhead
+ */
+#define HEAP_OVERHEAD 4
+
+/* Global variable shared by VPFTABLE.C, VPFREAD.C, and VPFWRITE.C  */
+/* The above modules are logically one, only separated by file size */
+/* constraints. */
+int STORAGE_BYTE_ORDER = LEAST_SIGNIFICANT;  /* default */
+
+
+/* Include these to decrease external module dependencies */
+
+#if 0 /* Defined in vpfmisc??? (drb) */
+static char *rightjust( char *str )
+{
+   register int  len,i;
+
+   len = strlen(str);
+   i = len - 1;
+   while ((i>0) && ((str[i]==0) || (str[i]==' '))) i--;
+   if (i < (len-1)) str[i+1] = '\0';
+   for (i=0;i<strlen(str);i++) if (str[i]=='\n') str[i] = '\0';
+   return str;
+}
+#endif
+
+
+
+void swap_two ( char *in, char *out )
+{
+  out[0] = in[1] ;
+  out[1] = in[0] ;
+}
+
+void swap_four ( char *in, char *out )
+{
+  out[0] = in[3] ;
+  out[1] = in[2] ;
+  out[2] = in[1] ;
+  out[3] = in[0] ;
+}
+
+void swap_eight ( char *in, char *out )
+{
+  out[0] = in[7] ;
+  out[1] = in[6] ;
+  out[2] = in[5] ;
+  out[3] = in[4] ;
+  out[4] = in[3] ;
+  out[5] = in[2] ;
+  out[6] = in[1] ;
+  out[7] = in[0] ;
+}
+
+/* Return floating point Not a Number (for NULL values) */
+double quiet_nan( int unused )
+{
+   char nanstr[8] = {-1,-1,-1,-1,-1,-1,-1,127};
+   double n;
+   memcpy(&n,&nanstr[0],sizeof(n));
+   if (unused) return n;
+   return n;
+}
+
+int is_vpf_null_float( float num )
+{
+   float nan;
+   nan = (float)quiet_nan(0);
+   if (memcmp(&nan,&num,sizeof(float))==0) return 1;
+   return 0;
+}
+
+int is_vpf_null_double( double num )
+{
+   double nan;
+   nan = (double)quiet_nan(0);
+   if (memcmp(&nan,&num,sizeof(double))==0) return 1;
+   return 0;
+}
+
+
+/***********Mody B**********/
+/* get string until delimeter */
+static char *cpy_del(char *src, char delimiter, long int *ind )
+{
+  long int i, skipchar ;
+  char *temp, *tempstr ;
+
+  /* remove all blanks ahead of good data */
+
+  skipchar = 0 ;
+  while ( src[skipchar] == SPACE || src[skipchar] == TAB )
+    skipchar++ ;
+
+  temp = &src[skipchar];
+
+  /* If the first character is a COMMENT, goto LINE_CONTINUE */
+
+  if ( *temp == COMMENT ) {
+    while ( *temp != LINE_CONTINUE && *temp != END_OF_FIELD && *temp != '\0'){
+      temp++ ;
+      skipchar ++ ;
+    }
+    skipchar++ ;
+    temp++ ;		/* skip past LC, EOF, or NULL */
+  }
+
+  /* Start with temporary string value */
+
+  tempstr = (char *)vpfmalloc ( strlen ( temp ) + 10 ) ;
+
+  if ( *temp == '"' ) {	/* If field is quoted, do no error checks */
+
+    temp++ ; 	  /* skip past quote character */
+    skipchar++ ;  /* update the position pointer */
+
+    for ( i=0 ; *temp != '\0'; temp++,i++) {
+      if ( *temp == LINE_CONTINUE || *temp == TAB ) {
+	temp++ ;
+	skipchar++ ;
+      } else if ( *temp == '"' )
+	break ;
+      /* Now copy the char into the output string */
+      tempstr[i] = *temp ;
+    }
+    tempstr[i] = (char) NULL ;		/* terminate string */
+    *ind += ( i + skipchar + 2) ;	/* Increment position locate past */
+    return tempstr ;			/* quote and semicolon */
+  }
+
+  /* search for delimiter to end, or end of string */
+
+  i=0 ;	/* initialize */
+
+  if ( *temp != END_OF_FIELD ) {	/* backward compatability check */
+
+    for ( i=0; *temp != '\0';temp++,i++){/* Stop on NULL*/
+
+      if ( ( *temp == LINE_CONTINUE && *(temp+1) == '\n') ||  *temp == TAB ) {
+	temp++ ;
+	skipchar++ ;
+      } else if ( *temp == delimiter )
+	break ;					/* break for delimiter  */
+      /* Now copy the char into the output string */
+      tempstr[i] = *temp ;
+    }
+                             /* Eat the delimiter from ind also */
+    *ind += ( i + skipchar + 1) ;	/* Increment position locate */
+  }	
+  tempstr[i] = (char) NULL ;		/* terminate string */   
+  return tempstr;
+}
+/***********Mody B*********/
+char *get_string(long int *ind,char *src,char delimeter )
+{ char *temp;
+  temp  = cpy_del(&src[*ind],delimeter, ind);
+  if( ! strcmp ( temp, TEXT_NULL ))
+    strcpy ( temp, "" ) ;
+  return temp;
+}
+/**********Mody B*************/
+char vpf_get_char(long int *ind, char *src)
+{  char temp;
+   while ( src[*ind] == SPACE || src[*ind] == TAB ) (*ind)++ ;
+   temp  = src[*ind];
+   *ind += 2;
+   return temp;
+}
+/***********Mody B***********/
+long int get_number(long int *ind, char *src,char delimeter)
+{  char *temp;
+   long int  num;
+   temp  = cpy_del(&src[*ind],delimeter, ind);
+   if (strchr(temp, VARIABLE_COUNT ) == NULL)
+      num = atoi(temp);
+   else
+      num = -1;
+   free(temp);
+   return num;
+}
+
+
+/*************************************************************************
+ *
+ *N  parse_data_def
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function parses a table's data definition and creates a header
+ *     in memory that is associated with the table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    table <inout> == (vpf_table_type *) vpf table structure.
+ *    ddlen <input> == (long int) length of the table's data definition.
+ *
+ *    return value is the record length if all items are fixed length, or
+ *    -1 if the record contains variable length items
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   April 1991                        DOS Turbo C
+ *    Mody Buchbinder  May 1991 - Modified for new table header.
+ *    Dave Flinn       July 1991 - updated for UNIX
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void *vpfmalloc()                                  VPFMISC.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+long int parse_data_def( vpf_table_type *table )
+{
+   register long int n,i;
+   long int p, k;
+   char *buf,*des,*nar,*vdt, *tdx, *doc, byte ;/*temporary storage */
+   char end_of_rec;
+   int status;
+   long int ddlen;
+   long int reclen = 0;
+#if UNIX
+   /* just for backward compat check */
+   long int bkcompat = 1 ;
+#endif
+
+   if ( table->mode == Read ) {
+     fread(&ddlen,sizeof(ddlen),1,table->fp);
+
+     /* Check the next byte to see if the byte order is specified */
+     fread(&byte,1,1,table->fp);
+     p=0;
+     table->byte_order = LEAST_SIGNIFICANT; /* default */
+     switch (toupper(byte)) {
+	case 'L':
+	   p++;
+	   break;
+	case 'M':
+	   table->byte_order = MOST_SIGNIFICANT;
+	   p++;
+	   break;
+     }
+     if (MACHINE_BYTE_ORDER != table->byte_order) {
+	k = ddlen;
+	swap_four((char *)&k,(char *)&ddlen);
+     }
+     if ( ddlen < 0 ) {
+       return (long int)NULL ;
+     }
+
+     STORAGE_BYTE_ORDER = table->byte_order;
+
+     /* header without first 4 bytes */
+     table->ddlen = ddlen + sizeof (long int) ;
+     buf = (char *)vpfmalloc((ddlen+3)*sizeof(char));
+     buf[0] = byte; /* already have the first byte of the buffer */
+     Read_Vpf_Char(&buf[1],table->fp,ddlen-1) ;
+   } else {
+     table->ddlen = strlen ( table->defstr ) ;
+     ddlen = table->ddlen ;
+     buf = (char *)vpfmalloc((ddlen+3)*sizeof(char));
+     strncpy ( buf, table->defstr, ddlen ) ;
+     p=0;
+     table->byte_order = LEAST_SIGNIFICANT; /* default */
+     byte = buf[0];
+     switch (toupper(byte)) {
+	case 'L':
+	   p++;
+	   break;
+	case 'M':
+	   table->byte_order = MOST_SIGNIFICANT;
+	   p++;
+	   break;
+     }
+     STORAGE_BYTE_ORDER = table->byte_order;
+   }
+
+   buf[ddlen-1] = '\0'; /* mark end of string for reading functions */
+   if ( buf[p] == ';' )
+     p++; /* buf[p] is semi-colon */
+   des = get_string(&p,buf,COMPONENT_SEPERATOR );
+   strncpy(table->description,des,80);
+   free(des);
+   nar = get_string(&p,buf,COMPONENT_SEPERATOR );
+   strncpy(table->narrative ,nar,12);
+   free(nar);
+   n = 0 ;
+   /* get number of fields */
+   for (i=p; i < ddlen;i++)
+     if ( buf[i] == LINE_CONTINUE )
+       i++ ;	/* skip past line continue, and next character */
+     else if (buf[i] == END_OF_FIELD ) 		/* Found end of field */
+	n++;					/* increment nfields */
+     else if (buf[i] == COMMENT )		/* skip past comments */
+       while ( buf[i] != LINE_CONTINUE &&
+	       buf[i] != END_OF_FIELD &&
+	       buf[i] != '\0')
+	 i++ ;					/* increment i */
+
+   table->nfields = n ;
+   table->header = (header_type)vpfmalloc((n+1)*sizeof(header_cell));
+
+   for(i=0;i<n;i++) {
+     end_of_rec = FALSE;
+     table->header[i].name  = get_string(&p,buf, FIELD_COUNT);  /*****/
+     rightjust(table->header[i].name);
+     table->header[i].type  = toupper(vpf_get_char  (&p,buf));
+     table->header[i].count = get_number(&p,buf,FIELD_SEPERATOR );
+
+     if ( i == 0 )
+       if ( ossim_strcasecmp ( table->header[0].name, "ID" ) ) {
+	 return (long int)NULL ;
+       }
+
+     if(table->header[i].count == -1)
+       reclen = -1;			/* set reclen to variable len flag */
+
+     /* Now set null values and add up record length, if fixed length */
+
+     status = 0;
+
+     switch (table->header[i].type) {
+     case 'I':
+       if ( reclen >= 0 )
+	 reclen += (sizeof(long int)*table->header[i].count);
+       table->header[i].nullval.Int = NULLINT ;
+       break;
+     case 'S':
+       if ( reclen >= 0 )
+	 reclen += (sizeof(short int)*table->header[i].count);
+       table->header[i].nullval.Short = NULLSHORT ;
+       break;
+     case 'F':
+       if ( reclen >= 0 )
+	 reclen += (sizeof(float)*table->header[i].count);
+       table->header[i].nullval.Float = NULLFLOAT ;
+       break;
+     case 'R':
+       if ( reclen >= 0 )
+	 reclen += (sizeof(double)*table->header[i].count);
+       table->header[i].nullval.Double = NULLDOUBLE ;
+       break;
+     case 'T':
+       if ( reclen >= 0 ) { 		/* if fixed length */
+	 reclen += (sizeof(char)*table->header[i].count);
+	 table->header[i].nullval.Char =
+	   (char *) vpfmalloc ( table->header[i].count + 1 ) ;
+	 for ( k=0; k < table->header[i].count; k++ )
+	   table->header[i].nullval.Char[k] = NULLCHAR ;
+	 table->header[i].nullval.Char[k] = (char) NULL ;
+       } else {			/* variable length */
+	 table->header[i].nullval.Char =
+	   (char *) vpfmalloc ( VARIABLE_STRING_NULL_LENGTH + 1 ) ;
+	 for ( k=0; k < VARIABLE_STRING_NULL_LENGTH ; k++ )
+	   table->header[i].nullval.Char[k] = NULLCHAR ;
+	 table->header[i].nullval.Char[k] = (char) NULL ;
+       }
+       break;
+     case 'C':
+       if ( reclen >= 0 )
+	 reclen += (sizeof(coordinate_type)*table->header[i].count);
+       table->header[i].nullval.Other = (char) NULL ;
+       break;
+     case 'Z':
+       if ( reclen >= 0 )
+	 reclen += (sizeof(tri_coordinate_type)*table->header[i].count);
+       table->header[i].nullval.Other = (char) NULL ;
+       break;
+     case 'B':
+       if ( reclen >= 0 )
+	 reclen += (sizeof(double_coordinate_type)*table->header[i].count);
+       table->header[i].nullval.Other = (char) NULL ;
+       break;
+     case 'Y':
+       if ( reclen >= 0 )
+	 reclen +=
+	   (sizeof(double_tri_coordinate_type)*table->header[i].count);
+       table->header[i].nullval.Other =(char) NULL;
+       break;
+     case 'D':
+       if ( reclen >= 0 )
+	 reclen += ((sizeof(date_type)-1)*table->header[i].count);
+       strcpy ( table->header[i].nullval.Date, NULLDATE ) ;
+       break;
+     case 'K':
+       reclen = -1;
+       table->header[i].nullval.Other = (char) NULL ;
+       break;
+     case 'X':
+       /* do nothing */
+       table->header[i].nullval.Other = (char) NULL ;
+       break ;
+     default:
+       status = 1;
+       break ;
+     } /** switch type **/
+
+     if (status) return (long int)NULL;
+
+     table->header[i].keytype     = vpf_get_char  (&p,buf);
+     des = get_string(&p,buf, FIELD_SEPERATOR );
+     rightjust(des);
+     strncpy(table->header[i].description,des,80);
+     free(des);
+     vdt = get_string(&p,buf, FIELD_SEPERATOR );
+     strncpy(table->header[i].vdt,vdt,12);
+     free(vdt);
+#if UNIX
+     /* This is for backward compatability qc checking */
+     if ( bkcompat && buf[p] == END_OF_FIELD ) {
+       bkcompat= 0 ;
+     }
+#endif
+     tdx = get_string(&p,buf, FIELD_SEPERATOR ) ;
+     if ( ! strcmp ( tdx, "" ) ) {
+       table->header[i].tdx = (char *) NULL ;
+       if (buf[p] == ':')
+	 end_of_rec = TRUE;
+     } else {
+       if (strcmp(tdx,"-") != 0) {
+	  table->header[i].tdx =(char*) vpfmalloc ( strlen ( tdx ) +1 ) ;
+	  strcpy (table->header[i].tdx, tdx );
+       } else table->header[i].tdx = (char *)NULL;
+     }
+     free(tdx);
+     if (!end_of_rec) {
+	doc = get_string(&p,buf, FIELD_SEPERATOR ) ;
+	if ( ! strcmp ( doc, "" ) ) {
+	  table->header[i].narrative = (char *) NULL ;
+	  end_of_rec = TRUE;
+	} else {
+	  if (strcmp(doc,"-") != 0) {
+	     table->header[i].narrative = (char*)vpfmalloc ( strlen(doc) +1) ;
+	     strcpy (table->header[i].narrative, doc );
+	  } else table->header[i].narrative = (char *)NULL;
+	}
+	free(doc);
+     } else table->header[i].narrative = (char *)NULL;
+     p += 1; /** eat semicolon **/
+    }
+   free(buf);
+   return reclen;
+}
+
+
+/*************************************************************************
+ *
+ *N  vpfhandler
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function temporarily takes the place of the DOS hard error
+ *     handler.  It is needed when 'vpfopencheck' replaces the DOS error
+ *     handler for disk operations, so that the disk errors may be handled
+ *     more suitably for our environment.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                       DOS Turbo C
+ *    Dave Flinn        July 1991  Updated for UNIX, basically commented
+ *                                 the subroutine out
+ *E
+ *************************************************************************/
+/*static int disk_error;*/
+#define IGNORE 0
+#define RETRY  1
+#define ABORT  2
+#define DISPLAY_STRING 0x09
+
+#ifdef __MSDOS__
+static int vpfhandler(long int errval, long int ax, long int bp, long int si)
+{
+   if (ax < 0) {
+      bdosptr(DISPLAY_STRING,"device error$", 0);
+      hardretn(-1);
+   }
+   disk_error = errval;
+
+   si++; bp++;  /* get rid of compiler warning */
+   return(IGNORE);
+}
+#endif
+
+
+/*************************************************************************
+ *
+ *N  vpfopencheck
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function tries its darndest to open a file.  It initially calls
+ *     fopen with the given filename and mode.  If that doesn't work and
+ *     the file is not on the hard disk, it displays a message asking the
+ *     user to enter the correct disk in the drive, waits for either a retry
+ *     or a cancel response, and, if told to retry, tries again.  This
+ *     process is repeated until either the file is opened or the user
+ *     requests cancel.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    filename <input> == (char *) full path name of the file to be opened.
+ *    mode     <input> == (char *) mode of the file.
+ *    diskname <input> == (char *) descriptive name of the disk the file is
+ *                                 on.
+ *    return  <output> == (FILE *) file pointer newly associated with
+ *                                 filename.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    May 1991                       DOS Turbo C
+ *    Dave Flinn        July 1991     Updated for UNIX
+ *E
+ *************************************************************************/
+FILE *vpfopencheck( char *filename,
+		    char *mode,
+		    char *diskname )
+{
+   FILE *fp;
+/*
+   char *text[] = {"Please insert",
+		   "                                        ",
+		   "in data drive",
+		   "                                                      "};
+*/
+   long int retry = 0;
+#ifdef __MSDOS__
+   extern char home[255];
+   void interrupt (*doshandler)();
+
+   doshandler = getvect(36);
+   harderr(vpfhandler);
+
+   strncpy(text[1],diskname,strlen(text[1]));
+   strcpy(text[3],filename);
+#endif
+   fp = NULL;
+   while (fp == NULL) {
+      fp = fopen(filename,mode);
+      if (fp == NULL) {
+#ifdef __MSDOS__
+	 if ( toupper(home[0]) != toupper(filename[0]) )
+	    retry = displayerror(text,   4);
+	 else
+#else
+	     /* give names ending in dot another chance without the dot */
+	     if (filename[strlen(filename)-1] == '.') {
+		 filename[strlen(filename)-1] = '\0';
+		 retry = TRUE;
+	     }
+	 else
+#endif
+	    retry = FALSE;
+	 if (!retry) break;
+      }
+   }
+#ifdef __MSDOS__
+   setvect(36,doshandler);
+#endif
+   return fp;
+}
+
+
+/*************************************************************************
+ *
+ *N  vpf_open_table
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function opens a vpf table and either loads it into RAM or sets
+ *     up the structure to read off of disk.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    tablename <input> == (char *) file name of the table.
+ *    storage   <input> == (storage_type) table storage mode -
+ *                                        either ram or disk.
+ *    mode      <input> == (char *) file mode for opening the table -
+ *                                  same as fopen() mode in C.
+ *    defstr    <input> == (char *) table definition string used for
+ *                                  creating a writable table.
+ *    vpf_open_table <output> == (vpf_table_type) VPF table structure.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   April 1991                   DOS Turbo C
+ *    Dave Flinn       July 1991                    UNIX compatable
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+vpf_table_type vpf_open_table( char         * tablename,
+			       storage_type   storage ,
+			       char         * mode,
+			       char         * defstr )
+{
+   vpf_table_type   table;
+   char             tablepath[255],
+		  * idxname;
+   long int         i,
+		    j;
+   long int         tablesize,
+		    idxsize,
+		    memsize;
+   unsigned long int ulval;
+   char            * diskname = "VPF data disc";
+
+   strcpy(tablepath,tablename);
+   rightjust(tablepath);
+
+   /* Parse out name and path */
+   j = -1;
+   i=strlen(tablepath);
+   while (i>0) {
+#ifdef __MSDOS__
+      if (tablepath[i] == '\\') {
+#else
+      if (tablepath[i] == '/') {
+#endif
+	 j = i;
+	 break;
+      }
+      i--;
+   }
+   strncpy(table.name,&(tablepath[j+1]),12);
+   rightjust(table.name);
+   strupr(table.name);
+   table.path = (char *)vpfmalloc((strlen(tablepath)+5)*sizeof(char));
+   strcpy(table.path, tablepath);
+   table.path[j+1] = '\0';
+
+ /* Establish a read or write table operation */
+
+   if ( mode[0] == 'r' )
+     table.mode = Read ;
+   else
+     table.mode = Write ;
+
+   /*fprintf(stderr, "vpf_open_table opening %s\n", tablepath);*/
+   table.fp = vpfopencheck(tablepath,mode,diskname);
+   if (table.fp == NULL) {
+      perror(tablepath);
+/*
+#if __MSDOS__
+      perror(tablepath);
+      getch();
+      if (getgraphmode() >= 0) closegraph();
+      exit(0);
+#endif
+*/
+      free(table.path);
+      if (table.fp) {
+	fclose(table.fp);
+	table.fp = NULL;
+      } 
+      return table;
+   }
+
+   /* If file is to be created, copy the def string ptr into header for now */
+
+   if ( table.mode == Write )
+     table.defstr = defstr ;
+
+#ifdef __MSDOS__
+   tablesize = (filelength(fileno(table.fp)));
+#else
+   {  /* UNIX doesn't have a filelength function, so this is the best */
+     struct stat statbuf ;
+     if ( stat ( tablepath, &statbuf ) < 0 ) {
+       fprintf (stderr, "vpf_open_table: can't stat file\n" ) ;
+       free(table.path);
+       fclose(table.fp);
+       table.fp = NULL;
+       return table;
+     }
+     tablesize = statbuf.st_size ;
+   }
+#endif
+
+   /* Populate table structure with correct data, either for read or write */
+
+   table.reclen = parse_data_def(&table);
+
+   if ( table.mode == Write ) {   /* write out header */
+     rewind ( table.fp ) ;
+     Write_Vpf_Int ( &table.ddlen, table.fp, 1 ) ;
+     Write_Vpf_Char ( table.defstr, table.fp, table.ddlen ) ;
+     free ( table.defstr ) ;
+     table.defstr = (char *) NULL ;
+     table.nrows = 0 ;
+   }
+
+   if (table.reclen > 0) {      /* Index file */
+      table.xstorage = (storage_type)COMPUTE;
+      if (table.mode != Write)
+	 table.nrows = (tablesize - table.ddlen)/table.reclen;
+      table.xfp = (FILE *) NULL ;
+   } else {
+      idxname = strdup( tablepath );
+#ifdef __MSDOS__
+      idxname[strlen(tablepath)-1] = 'x';
+#else
+      if (idxname[strlen(tablepath)-1] == '.')
+	idxname[strlen(tablepath)-2] = 'x';
+      else
+	idxname[strlen(tablepath)-1] = 'x';
+#endif
+      table.xfp = fopen(idxname, mode);
+
+      if ((!table.xfp) && (table.mode == Read)) {
+	 perror(idxname);
+         fprintf(stderr, "hit RETURN to continue...");
+	 i=getc(stdin);
+	 free(idxname);
+	 for (i = 0; i < table.nfields; i++)
+	   free(table.header[i].name);
+	 free(table.header);
+	 free(table.path);
+         fclose(table.fp);
+         table.fp = NULL;
+         return table;
+      }
+
+      free(idxname);
+
+/*#ifdef __MSDOS__*/
+      table.xstorage = (storage_type)DISK;   /* Worst case default */
+/*#endif*/
+
+   /* Only read in index if file is read only */
+
+      if (table.xfp && ( table.mode == Read ) ) {
+	Read_Vpf_Int (&(table.nrows), table.xfp, 1 ) ;
+	Read_Vpf_Int (&ulval, table.xfp, 1 ) ;
+	idxsize = table.nrows*sizeof(index_cell) + 10L;
+
+#ifdef __MSDOS__
+	if ( (idxsize < (farcoreleft()/2)) && (idxsize < __64K) )
+#else
+	if (0)
+#endif
+	  {
+	    table.xstorage = (storage_type)RAM;
+	    table.index = (index_type)vpfmalloc(idxsize);
+	    for (i=0;i<table.nrows;i++) {
+	      Read_Vpf_Int (&(table.index[i].pos), table.xfp, 1) ;
+	      Read_Vpf_Int (&(table.index[i].length),table.xfp,1 ) ;
+	    }
+	    fclose(table.xfp);
+	  }
+      } else if (table.mode == Write) {
+
+     /* Write out dummy header record for index file. vpf_close_table finishes
+	the job. */
+
+	 Write_Vpf_Int ( &(table.ddlen), table.xfp, 1 ) ;
+	 Write_Vpf_Int ( &(table.ddlen), table.xfp, 1 ) ;
+	 table.xstorage = (storage_type)DISK;
+	 table.index = (index_type) NULL ;
+
+      }
+   }  /* end of if table .reclen */
+
+    table.storage = (storage_type)DISK;
+#ifdef __MSDOS__
+   memsize = (long int)min(farcoreleft(),__64K);
+#else
+   memsize = MAXINT;
+#endif
+
+   if ( (storage != disk) && ( table.mode == Read ) ) {
+      if (tablesize + table.nrows * table.nfields * HEAP_OVERHEAD < memsize) {
+	 fseek(table.fp,index_pos(1,table),SEEK_SET);
+	 table.row = (row_type *)vpfmalloc((table.nrows+1)*sizeof(row_type));
+	 for (i=0;i<table.nrows;i++) {
+	    table.row[i] = read_next_row(table);
+	 }
+	 fclose(table.fp);
+	 table.storage = (storage_type)RAM;
+      }
+   }
+   table.status = OPENED;
+   return table;
+ }
+
+/*************************************************************************
+ *
+ *N  vpf_close_table
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function frees an entire table from memory.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    table       <inout> == (vpf_table_type) VPF table structure.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels   May 1991                     DOS Turbo C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+void vpf_close_table( vpf_table_type *table )
+{
+   register long int i;
+
+   if (table->status != OPENED) {
+      return;
+   }
+   /*fprintf(stderr, "vpf_close_table closing %s%s\n", table->path, table->name);*/
+
+   /* If the table is writable, write out the final record count */
+
+   if ( table->mode == Write && table->xfp ) {
+     rewind ( table->xfp ) ;
+     Write_Vpf_Int ( &table->nrows, table->xfp, 1 ) ;
+     Write_Vpf_Int ( &table->ddlen, table->xfp, 1 ) ;
+   }
+
+   for (i=0;i<table->nfields;i++) {
+      free(table->header[i].name);
+      /* free up null text string */
+      if ( table->header[i].type == 'T')
+	 free(table->header[i].nullval.Char);
+      /* free up index file string */
+      if (table->header[i].tdx!=(char *)NULL)
+	free ( table->header[i].tdx ) ;
+      /* free up narrative table string */
+      if (table->header[i].narrative!=(char *)NULL) {
+	free ( table->header[i].narrative ) ;
+      }
+   }
+   free(table->header);
+
+   switch (table->storage) {
+      case RAM:
+	 for (i=0;i<table->nrows;i++) free_row(table->row[i],*table);
+	 free(table->row);
+	 break;
+      case DISK:
+	 fclose(table->fp);
+	 break;
+      default:
+	 printf("%s%s: unknown storage flag: %d\n",table->path,table->name,
+		table->storage);
+	 break;
+   }
+
+   switch (table->xstorage) {
+      case RAM:
+	 free(table->index);
+	 break;
+      case DISK:
+	 fclose(table->xfp);
+	 break;
+      case COMPUTE:
+	 break;
+      default:
+	 printf("%s%s: unknown index storage flag: %d\n",
+		table->path,table->name,table->storage);
+	 break;
+   }
+   table->nfields = 0;
+   free(table->path);
+   table->status = CLOSED;
+}
+
+
+
+long int is_vpf_table( char *fname )
+{
+   FILE *fp;
+   long int n, ok;
+
+   fp = fopen( fname, "rb" );
+   if (!fp) {
+      return FALSE;
+   }
+   Read_Vpf_Int ( &n, fp, 1 ) ;
+   fseek( fp, n-1, SEEK_CUR );
+   if (fgetc(fp) == ';')
+      ok = TRUE;
+   else
+      ok = FALSE;
+   fclose(fp);
+   return ok;
+}
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpftable.h b/Utilities/OSSIM/ossim_core/vpf_util/vpftable.h
new file mode 100644
index 0000000000..8700b5e836
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpftable.h
@@ -0,0 +1,320 @@
+/* ================ SCCS_ID[] = "@(#) vpftable.h 2.2 10/29/91"  =================
+
+   Environmental Systems Research Institute (ESRI) Applications Programming
+
+       Project: 		Conversion from ARC/INFO to VPF
+       Original Coding:		Barry Michaels	April 1991
+       Modifications:		David Flinn	April 1991
+                                Barry           June 1991
+                                Dave            October 1991
+   ======================================================================== */
+
+/* VPFTABLE.H */
+
+#ifndef _VPF_TABLE_H_
+
+#define _VPF_TABLE_H_
+
+#include <stdio.h>
+/* #include "machine.h" */
+
+#include <ossimConfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TRUE
+#define TRUE  1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* Possible byte ordering of the data */
+#define LEAST_SIGNIFICANT 0
+#define MOST_SIGNIFICANT  1
+
+/* The next definition is machine-specific and may need to be changed */
+/* before recompiling on a different machine */
+#if (__MSDOS__ || __LINUX__ || __OSSIM_DOS__ || __OSSIM_LINUX__)
+#define MACHINE_BYTE_ORDER LEAST_SIGNIFICANT
+
+#elif ((__OSSIM_UNIX__ && ! __OSSIM_LINUX__) || defined(MACOSX) || __OSSIM_DARWIN__)
+#define MACHINE_BYTE_ORDER MOST_SIGNIFICANT
+#else
+#define MACHINE_BYTE_ORDER LEAST_SIGNIFICANT   
+#endif
+
+
+#include "vpfio.h"
+
+/* This should be the ISO definition of date */
+
+typedef char date_type[21] ;	/* Include null end of string */
+
+/* NULL valuse type */
+
+typedef union {
+   char 	  *Char ;
+   short int	  Short ;
+   long int       Int ;
+   float	  Float ;
+   double	  Double ;
+   date_type	  Date ;
+   char		  Other ;
+} null_field;
+
+/* The basic information carried for each field in the table */
+typedef struct {
+   char *name;           /* Name of the field */
+   char description[81]; /* Field description */
+   char keytype;         /* Type of key - (P)rimary, (F)oreign, (N)onkey */
+   char vdt[13];         /* Value description table name */
+   char *tdx;	 	 /* Thematic index file name */
+   char type;            /* Data type - T,I,F,K,D */
+   long int  count;      /* Number of items in this column (-1 =>variable)*/
+   null_field nullval ;  /* This is used for the converter */
+   char *narrative;      /* Name of a narrative table describing the field*/
+} header_cell, *header_type;
+
+typedef enum { ram, disk, either, compute } storage_type;
+#define RAM 0
+#define DISK 1
+#define EITHER 2
+#define COMPUTE 3
+
+typedef enum { Read, Write } file_mode ;
+
+#define CLOSED 0
+#define OPENED 1
+
+/* Each column in a table row has a count and a pointer to the data */
+/*      and a null value default */
+typedef struct {
+   long int count;
+   void *ptr;
+} column_type;
+
+/* A table row is an array of columns */
+typedef column_type *row_type;
+
+/* Index for variable width tables.          */
+/* One index cell for each row in the table. */
+typedef struct {
+   unsigned long int pos;
+   unsigned long int length;
+} index_cell, *index_type;
+
+/* VPF table structure: */
+typedef struct {
+   char           name[13];        /* Name of the VPF table */
+   char           *path;           /* Directory path to the table */
+   long int       nfields;         /* Number of fields */
+   char           description[81]; /* Table description */
+   char           narrative[13];   /* Table narrative file name */
+   header_type    header;          /* Table header structure */
+   FILE           *xfp;            /* Index file pointer */
+   index_type     index;           /* Index structure */
+   storage_type   xstorage;        /* Flag indicating where index stored */
+   FILE           *fp;             /* Table file pointer */
+   long int       nrows;           /* Number of rows in the table */
+   row_type       *row;            /* Array of table rows */
+   long int       reclen;          /* Table record length (-1 => variable */
+   long int       ddlen;           /* Data definition string length */
+   char           *defstr ;        /* rdf, definition string */
+   storage_type   storage;         /* Flag indicating table storage method */
+   file_mode	  mode ;	   /* Table is either reading or writing */
+   unsigned char  status;          /* VPF table status - OPENED or CLOSED */
+   unsigned char  byte_order;      /* Byte order of the table's data */
+} vpf_table_type;
+
+typedef struct {
+   float x,y;
+} coordinate_type;
+
+typedef struct {
+   double x,y;
+} double_coordinate_type;
+
+typedef struct {
+   float x,y,z;
+} tri_coordinate_type;
+
+typedef struct {
+   double x,y, z;
+} double_tri_coordinate_type;
+
+/* These macros help determine the type in the key datatype */
+
+#define TYPE0(cell) ((cell>>6)&(3))
+#define TYPE1(cell) ((cell>>4)&(3))
+#define TYPE2(cell) ((cell>>2)&(3))
+#define TYPE3(cell) ((cell)&(3))
+
+/* These macros set the value in the key datatype */
+
+#define SETTYPE0(cell,value) cell = (((cell)&(~(3<<6)))|(((3)&(value))<<6))
+#define SETTYPE1(cell,value) cell = (((cell)&(~(3<<4)))|(((3)&(value))<<4))
+#define SETTYPE2(cell,value) cell = (((cell)&(~(3<<2)))|(((3)&(value))<<2))
+#define SETTYPE3(cell,value) cell = (((cell)&(~(3)))|(((3)&(value))))
+
+/* This macro helps to write out a key */
+
+#define ASSIGN_KEY(tYPE,kEY,loc,val)\
+{ \
+   if (val < 1) \
+   {  \
+      tYPE(kEY.type,0);  \
+   } else if (val < (1<<8)) \
+   {  \
+      tYPE(kEY.type,1);  \
+      kEY.loc = val ;  \
+   } else if ( val < (1<<16)) \
+   {  \
+      tYPE(kEY.type,2);  \
+      kEY.loc = val;  \
+   } else \
+   {  \
+      tYPE(kEY.type,3);  \
+      kEY.loc = val; \
+   } \
+}
+
+/* define NULL values */
+#if defined(__CYGWIN__) || defined(MACOSX) || defined(USING_VISUALAGE) || defined(_WIN32)
+#include "vpf_util/values.h"
+#else
+#include <values.h>
+#endif
+
+#include <math.h>
+
+#ifdef __MSDOS__
+double quiet_nan(int unused);
+#endif
+
+int is_vpf_null_float( float num );
+int is_vpf_null_double( double num );
+
+#define		VARIABLE_STRING_NULL_LENGTH	10
+#define 	NULLCHAR	' '
+#define		NULLTEXT	" "
+#define		NULLSHORT	-MAXSHORT
+#define         NULLINT         -MAXLONG
+#define		NULLDATE	"                    "
+/* #if UNIX */
+#define		NULLFLOAT	((float) quiet_nan (0))
+#define		NULLDOUBLE	((double) quiet_nan (0))
+/* #else
+#define		NULLFLOAT	((float) MAXFLOAT)
+#define		NULLDOUBLE	((double) MAXFLOAT)
+#endif  */
+
+typedef union {
+   unsigned char f1;
+   unsigned short int f2;
+   unsigned long int f3;
+} key_field;
+
+/* id triplet internal storage type */
+typedef struct {
+   unsigned char type;
+   long int id, tile, exid;
+} id_triplet_type;
+
+typedef enum { idle_state, name_state, type_state,
+	       tuple_state, count_state } ddef_state_type;
+
+/* Functions: */
+
+char *get_string(long int *ind,char *src,char delimit);
+char  get_char  (long int *ind,char *src);
+long int   get_number(long int *ind,char *src,char delemit);
+
+long int   parse_data_def( vpf_table_type *table );
+
+char      *read_text_defstr( FILE *infile, FILE *outerr );
+
+long int  index_length( long int row_number,
+		        vpf_table_type table );
+
+long int  index_pos( long int row_number,
+		     vpf_table_type table );
+#if 0
+long int row_offset( int field,
+		     row_type row,
+		     vpf_table_type table);
+#endif
+
+row_type  read_next_row( vpf_table_type table );
+
+row_type  read_row( long int row_number,
+		    vpf_table_type table );
+
+vpf_table_type vpf_open_table( char *tablename,
+			       storage_type storage,
+			       char *mode,
+			       char *defstr );   /* rdf added */
+
+row_type get_row( long int row_number,
+		  vpf_table_type table );
+
+void free_row( row_type row, vpf_table_type table );
+
+long int table_pos( char *field_name,
+	       vpf_table_type table );
+
+void *get_table_element( long int field_number,
+			 row_type row,
+			 vpf_table_type table,
+			 void *value,
+			 long int  *count );
+
+void *named_table_element( char *field_name,
+			   long int  row_number,
+			   vpf_table_type table,
+			   void *value,
+			   long int  *count );
+
+void *table_element( long int field_number,
+		     long int  row_number,
+		     vpf_table_type table,
+		     void *value,
+		     long int  *count );
+
+void vpf_close_table( vpf_table_type *table );
+
+void vpf_dump_table( char *tablename, char *outname );
+
+long int is_vpf_table( char *fname );
+
+/* Write functions */
+
+long int write_next_row( row_type row, vpf_table_type *table );
+
+row_type create_row( vpf_table_type table );
+
+void nullify_table_element( long int field, row_type row,
+			    vpf_table_type table );
+
+long int put_table_element( long int field, row_type row,
+			    vpf_table_type table,
+			    void *value, long int count );
+
+void swap_two(char*, char*);
+void swap_four(char*, char*);
+void swap_eight(char*, char*);
+
+#if MAIN
+  FILE * errorfp = stderr;
+#else
+  extern FILE * errorfp;
+#endif
+#if defined(__cplusplus)
+}
+#endif
+
+#endif     /* #ifndef _VPF_TABLE_H_  */
+
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpftidx.c b/Utilities/OSSIM/ossim_core/vpf_util/vpftidx.c
new file mode 100644
index 0000000000..5901c23f8a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpftidx.c
@@ -0,0 +1,1959 @@
+/*************************************************************************
+ *
+ * Environmental Systems Research Institute (ESRI) Applications Programming
+ *
+ *N  Module VPFTIDX
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *P
+ *   Purpose: Subroutines to create and read both the thematic index
+ *	      or a gazeteer index on a VPF table column.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       September/October 1991
+ *    Barry Michaels   January 1992   A few adjustments for DOS.
+ *                                    Added sets to create function to
+ *                                    take advantage of SET's disk-
+ *				      swapping ability when low on memory.
+ *E
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions:
+ *F
+ *
+ *    set_type read_thematic_index ( char *tablename,
+ *				     char *value ) ;
+ *
+ *    ThematicIndex open_thematic_index ( char *tablename );
+ *
+ *    set_type search_thematic_index ( ThematicIndex *themindex,
+ *				       char *value ) ;
+ *
+ *    void close_thematic_index ( ThematicIndex *themindex );
+ *
+ *    set_type read_gazetteer_index (char * vpfname, char * query_str ) ;
+ *
+ *    set_type search_gazetteer_index (ThematicIndex *idx,
+ *				       char * query_str ) ;
+ *
+ *    long int read_gazetteer_index_directory (
+ *					ThematicIndexDirectory ** gid,
+ *					ThematicIndexHeader     * gi,
+ *					FILE * idx_fp);
+ *
+ *    long int write_thematic_index_header ( ThematicIndexHeader h ,
+ *					     FILE *fp ) ;
+ *
+ *    long int read_thematic_index_header ( ThematicIndexHeader *h ,
+ *					    FILE *fp ) ;
+ *
+ *    long int write_thematic_index_directory (
+ *				       ThematicIndexHeader h ,
+ *				       ThematicIndexDirectory *d,
+ *				       long int size,
+ *				       FILE *fp ) ;
+ *
+ *    long int write_gazetteer_index_directory (
+ *				       ThematicIndexHeader h ,
+ *				       ThematicIndexDirectory *d,
+ *				       long int size,
+ *				       FILE *fp ) ;
+ *
+ *    long int create_thematic_index ( char indextype,
+ *				       char *tablename,
+ *				       char *idxname ,
+ *				       char *columnname,
+ *				       char *idx_set );
+ *
+ *    long int create_gazetteer_index (char *tablename,
+ *				       char *idx_fname ,
+ *				       char *columnname,
+ *				       char *idx_set);
+ *
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible. Created on UNIX first
+ *E
+ *************************************************************************/
+
+#include <ctype.h>
+#include "machine.h"
+#include "vpfmisc.h"
+#include "vpftable.h"
+#include "vpftidx.h"		/* Thematic index include file */
+#include <string.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#ifndef __MSDOS__ 
+#  ifndef _WIN32
+#    include <unistd.h>
+#  endif
+#endif
+
+void *vpfmalloc(unsigned long size);
+
+#define Whimper(str) {\
+      return ((long int)NULL) ; }
+
+#define SWhimper(str) {\
+      set_type err; err = set_init (1) ;\
+      printf("\nvpftidx: < %s >\n", str ) ;\
+      return err ; }
+
+#define OWhimper(str) {\
+      printf("\nvpftidx: < %s >\n", str ) ;\
+      return idx ; }
+
+
+/*
+ * an index file directory entry takes up a different amount
+ * of space in memory than it does on disk; the following constant
+ * should be used to calculate the starting offset for
+ * index data
+ *
+ * example: if the number of items to be indexed is t, and each item is
+ *          s bytes long, then use
+ *
+ *          sizeof(ThematicIndexHeader) + t * (s + DIR_ON_DISK_INCR)
+ *
+ * to find out where the first byte of indexing data will be placed.
+ *
+ * That first byte is what must be stored as the value of Header.nbytes
+ */
+
+#define DIR_ON_DISK_INCR (2 * sizeof(long int))
+
+/*************************************************************************
+ *
+ *N  create_thematic_index
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *
+ *      Create a thematic index file on a given vpf table.
+ *P
+ *
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    indextype  <input> == (char) either 'T' for thematic index or
+ *					  'G' for gazetteer.
+ *    tablename  <input> == (char *) path name of the vpf table.
+ *    idxname    <input> == (char *) name of the index file to be created.
+ *    columnname <input> == (char *) name of column to create index on
+ *			    if the column is a triplet id, the columnname
+ *			    should be as such: EDG_ID\ID
+ *					       EDG_ID\TILE_ID
+ *					       EDG_ID\EXT_ID
+ *    idxset     <input> == (char *) array of character values to index on
+ *                          if the index type is gazetteer.  Not used for
+ *                          index type = 'T'.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October	 1991 
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    void *vpfmalloc                                    VPFMISC.C
+ *    vpf_open_table					 VPFTABLE.C
+ *    table_pos
+ *    table_element
+ *    vpf_close_table
+ *    write_thematic_index_header			see below
+ *    write_thematic_index_directory			see below
+ *    Vpf_Write_* macros
+ *    set_init						SET.C
+ *    set_insert
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.  developed on UNIX
+ *E
+ *************************************************************************/
+long int create_thematic_index ( char indextype,
+		 	         char *tablename,
+				 char *idxname ,
+				 char *columnname,
+				 char *idx_set ) 
+{
+   unsigned int i;
+   unsigned int column_length;
+   FILE           *ifp ;
+   long int	 j,tablepos,k,
+      keycolumn = 0 ,	/* 1 if key column */
+      itemp , n,
+      idsize ,		/* either 2 or 4 bytes */
+      datasize ;		/* Directory value data size */
+   char           *buf ,
+      hack[80] ;
+   vpf_table_type table ;
+   ThematicIndexHeader		h ;
+   ThematicIndexDirectory	*d ;
+   short int			stemp ;
+   float				ftemp ;
+   double			dtemp ;
+   id_triplet_type		key ;
+   
+   if ( indextype == 'G' )
+   {
+      return ( create_gazetteer_index ( tablename, idxname,columnname,idx_set)) ;
+   }
+   
+   /* convert columnname to uppercase and check for id triplet */
+   column_length = (unsigned int)strlen(columnname);
+   for ( i=0 ; i < column_length; i++ )
+   {
+      /* copy into header structure */
+      h.vpf_column_name[i] = toupper ( columnname[i] ) ;
+   }
+   
+   h.vpf_column_name[i] = '\0';
+   
+   h.index_type = 'T' ;		/* default */
+   h.type_count = 1 ;
+
+   for (i=0 ; i < column_length; i++ )
+   {
+      columnname[i] = toupper ( columnname[i] ) ;
+
+#if 0
+    /* check if request is on a triplet id field */
+
+    if ( columnname[i] == '\\' ) {
+
+      columnname[i+1] = toupper ( columnname[i+1] ) ;
+      
+      switch ( columnname[i+1] ) {	/* locate sub-column key */
+      case 'I':	/* ID of triplet id */
+	keycolumn = 1 ; break ;
+      case 'T':	/* TILE_ID of triplet id */
+	keycolumn = 2 ; break ;
+      case 'E':	/* EXT_ID of triplet id */
+	keycolumn = 3 ; break ;
+      default:
+	Whimper ("error in key column request") ;
+	/* break ; Whimper contains a return */
+      }	/* end of switch */
+      strcpy( h.vpf_column_name, strupr ( columnname )) ;
+      columnname[i] = (char) NULL ;
+    }     /* end of if columnname == \ */
+#endif
+  }	/* end of for loop */
+
+  table = vpf_open_table ( tablename, disk, "rb", (char) NULL ) ;
+
+
+  /* Determine the id_data_size. This will save 50% of file size  */
+
+  if ( table.nrows > MAX_ID ) {
+    h.id_data_type = 'I' ;		/* long ints */
+    idsize = sizeof ( long int ) ;
+  } else {
+    h.id_data_type = 'S' ;		/* long ints */
+    idsize = sizeof ( short int ) ;
+  }
+
+  /* Find position of column in input table */
+
+  tablepos = table_pos ( columnname, table ) ;
+
+  /* Now check data type */
+
+  switch (table.header[tablepos].type) {
+  case 'X':
+    Whimper ("Cannot make index on Null Column") ;
+    /* A return is in Whimper - break statement cannot be reached */
+  case 'T':
+    /* Don't bother with variable length, it's too hard for now */
+    if ( table.header[tablepos].count <= 0 )
+      Whimper ("Cannot make index on variable length text column") ;
+    datasize = table.header[tablepos].count ;
+    h.type_count = datasize ;		/* the special case */
+    break;
+  case 'D': 
+    datasize = sizeof ( date_type ) ;
+    Whimper ("Not implemented yet") ;
+  case 'I':
+    datasize = sizeof ( long int ) ;
+    break ;
+  case 'K':				/* treat keys like integers */
+    Whimper ("Cannot make index on key column") ;
+  case 'S':
+    datasize = sizeof ( short int ) ;
+    break ;
+  case 'F':
+    datasize = sizeof ( float ) ;
+    break ;
+  case 'R':
+    datasize = sizeof ( double ) ;
+    break ;
+  case 'C':
+  case 'Z':
+  case 'B':
+  case 'Y':
+    Whimper ("Cannot make index on Coordinate Column") ;
+  default:
+    sprintf (hack,"No such type < %c >", table.header[tablepos].type ) ;
+    Whimper ( hack ) ;
+  }  /* end of switch */
+
+  /* open output index file */
+
+  if (( ifp = fopen ( idxname, "wb" )) == NULL )
+    Whimper ( idxname ) ;
+
+  /* Create directory size as big as table, for worst case */
+
+  d = (ThematicIndexDirectory *)
+    vpfmalloc(sizeof(ThematicIndexDirectory)) ;
+  h.nbins = 0 ;		/* initialize the directory counter */
+
+#define REALLOC_DIRECTORY(loc) {\
+  if ((d = (ThematicIndexDirectory *) \
+       realloc(d,sizeof(ThematicIndexDirectory) * (loc+1))) == NULL )\
+    Whimper ("error in reallocing directory") ; \
+  d[loc].num_items = 0 ;\
+  d[loc].idset = set_init(table.nrows+1); }
+
+#define INSERT_ID(loc,val) {\
+  d[loc].num_items++ ; \
+  set_insert(val,d[loc].idset); }
+
+/* Fill up id sets */
+
+  switch ( table.header[tablepos].type ) {
+  case 'I':
+
+    for ( i=1; (int)i <= table.nrows; i++ ) {
+      /* read in record from disk */
+      table_element ( tablepos,i,table,&itemp,&n);
+      for ( k=0; k < h.nbins; k++ )	/* Search directory for value*/
+	if ( d[k].value.ival == itemp )
+	  break ;/* Found a match */
+      if ( k == h.nbins ) { 		/* New value in column */
+	REALLOC_DIRECTORY ( k ) ;
+	d[k].value.ival = itemp ;
+	h.nbins++ ;
+      }
+      INSERT_ID(k,i) ;
+    }   /* end of for i loop */ 
+
+    break ;
+  case 'T':
+
+    /* initialize */
+    buf = (char *) table_element (tablepos,1,table,NULL,&n);
+    REALLOC_DIRECTORY ( 0 ) ;
+    d[0].value.strval = (char *) vpfmalloc ( strlen ( buf ) +1) ;
+    memcpy( d[0].value.strval, buf, strlen(buf) ) ;
+    free (buf) ;
+    h.nbins++ ;
+
+    for ( i=1; (int)i <= table.nrows; i++ ) {
+      /* read in record from disk */
+      buf = (char *) table_element (tablepos,i,table,NULL,&n);
+
+      /* strlen ( buf ) should equal datasize */
+
+      for ( k=0; k < h.nbins; k++ )	/* Search directory for value*/
+	if ( ! strcmp ( d[k].value.strval, buf ) )
+	  break ;/* Found a match */
+
+      if ( k == h.nbins ) { 		/* New value in column */
+	REALLOC_DIRECTORY ( k ) ;
+	d[k].value.strval = (char *) vpfmalloc ( strlen ( buf ) +1) ;
+	memcpy( d[0].value.strval, buf, strlen(buf) ) ;
+	h.nbins++ ;
+      }
+      INSERT_ID(k,i) ;
+      free(buf);
+    }   /* end of for i loop */
+
+    break ;
+  case 'S':
+
+    for ( i=1; (int)i <= table.nrows; i++ ) {
+      /* read in record from disk */
+      table_element ( tablepos,i,table,&stemp,&n);
+      for ( k=0; k < h.nbins; k++ )	/* Search directory for value*/
+	if ( d[k].value.sval == stemp ) 
+	  break ;/* Found a match */
+      if ( k == h.nbins ) { 		/* New value in column */
+	REALLOC_DIRECTORY ( k ) ;
+	d[k].value.sval = stemp ;
+	h.nbins++ ;
+      }
+      INSERT_ID (k,i) ;
+    }   /* end of for i loop */
+
+    break ;
+  case 'F':
+
+    for ( i=1; (int)i <= table.nrows; i++ ) {
+      /* read in record from disk */
+      table_element ( tablepos,i,table,&ftemp,&n);
+      for ( k=0; k < h.nbins; k++ )	/* Search directory for value*/
+	if ( d[k].value.fval == ftemp ) 
+	  break ;/* Found a match */
+      if ( k == h.nbins ) { 		/* New value in column */
+	REALLOC_DIRECTORY ( k ) ;
+	d[k].value.fval = ftemp ;
+	h.nbins++ ;
+      }
+      INSERT_ID (k,i) ;
+    }   /* end of for i loop */
+
+    break ;
+  case 'R':
+    for ( i=1; (int)i <= table.nrows; i++ ) {
+      /* read in record from disk */
+      table_element ( tablepos,i,table,&dtemp,&n);
+      for ( k=0; k < h.nbins; k++ )	/* Search directory for value*/
+	if ( d[k].value.dval == dtemp )
+	  break ;/* Found a match */
+      if ( k == h.nbins ) { 		/* New value in column */
+	REALLOC_DIRECTORY ( k ) ;
+	d[k].value.dval = dtemp ;
+	h.nbins++ ;
+      }
+      INSERT_ID (k,i) ;
+    }   /* end of for i loop */
+
+    break ;
+  case 'K':
+
+    for ( i=1; (int)i <= table.nrows; i++ ) {
+      /* read in record from disk */
+      table_element ( tablepos,i,table,&key,&n);
+
+      if ( keycolumn == 1 ) 
+	itemp = key.id ;
+      else if ( keycolumn == 2 ) 
+	itemp = key.tile ;
+      else 
+	itemp = key.exid ;
+
+      for ( k=0; k < h.nbins; k++ )	/* Search directory for value*/
+	if ( d[k].value.ival == itemp ) 
+	  break ;/* Found a match */
+      if ( k == h.nbins ) { 		/* New value in column */
+	REALLOC_DIRECTORY ( k ) ;
+	d[k].value.ival = itemp ;
+	h.nbins++ ;
+      }
+      INSERT_ID (k,i) ;
+    }   /* end of for i loop */ 
+
+    break ;
+  default:
+    Whimper ("error in table reading switch, no such type") ;
+  } /* end of switch */
+
+  /* set up header and write it out */
+  /* h.id_data_size and columnname set up above */
+  /* h.type_count set above */
+
+  h.nbytes = THEMATIC_INDEX_HEADER_SIZE +
+             h.nbins * ( datasize + DIRECTORY_SIZE ) ;
+
+  h.column_type = table.header[tablepos].type ;
+  if ( h.column_type == 'K' )		/* It's really an I */
+    h.column_type = 'I' ;
+  for ( i=0; i < 4; i++ )
+    h.padding[i] = (char) NULL ;
+
+  /* only write the table name, no pathname */
+
+  for ( i = strlen ( tablename ); i > 0; i-- )
+    if ( tablename[i] == '/' ) break ;
+  if ( i && i < strlen (tablename) )
+    strcpy ( h.vpf_table_name, strupr ( &tablename[i+1] ) ) ;
+  else
+    strcpy( h.vpf_table_name, strupr ( tablename) );
+  
+  for ( i=strlen(h.vpf_table_name); i < 12 ; i++ )
+    h.vpf_table_name[i] = ' ' ;
+  h.vpf_table_name[11] = '\0';
+
+  /* columname setup above */
+
+  h.table_nrows = table.nrows ;
+
+  if ( write_thematic_index_header ( h, ifp ) == (long int)NULL )
+    Whimper ( "error writing index header" ) ;
+
+  /* Now write out the rest of the header directory */
+
+  if ( write_thematic_index_directory ( h, d, idsize, ifp ) == (long int)NULL )
+    Whimper ( "error writing index directory" ) ;
+
+  /* now write the data */
+  if ( h.id_data_type == 'I' ) {
+    for ( i=0; (int)i < h.nbins; i++ )
+      for ( j=1; j <= table.nrows; j++ )
+	if (set_member(j,d[i].idset))
+	  Write_Vpf_Int ( &j, ifp, 1 ) ;
+  } else {
+    for ( i=0; (int)i < h.nbins; i++ )
+      for ( j=1; j <= table.nrows; j++ )
+	if (set_member(j,d[i].idset)) {
+	  stemp = (short int)j;
+	  Write_Vpf_Short ( &stemp, ifp, 1 ) ;
+	}
+  }
+
+  /* close up shop and exit */
+
+  vpf_close_table ( &table );
+  fclose ( ifp ) ;
+  for ( i=0; (int)i < h.nbins; i++ )
+    set_nuke(&d[i].idset);
+  free ( d ) ;
+  return ( h.nbins ) ;
+
+}
+
+
+/*************************************************************************
+ *
+ *N  read_thematic_index
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To read an index file, regardless of its type ( T or G ) and 
+ *	return a set type array
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    idxname <input> == (char *) name of index file
+ *    value   <input> == (char *) address of value to search on. 
+ *			 THE PROGRAMMER MUST INSURE THAT THIS ADDRESS
+ *			 CORRESPONDS TO THE TABLE COLUMN AND INDEX FILE.
+ *
+ *   Returns:
+ *
+ *    set_type		a set corresponding to the vpf table, where each
+ *			bit relates to the ID in the table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	read_thematic_index_header		see below
+ *	set_init				SET.C
+ *	set_insert
+ *	Vpf_Read_*                              VPFREAD.C
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+set_type read_thematic_index ( char *idxname,
+			       char *value )
+{
+  long int 			i , ival = 0, Match = -1;
+  short int			sval = 0;
+  float				fval = 0.0 ;
+  double			dval = 0.0 , atof () ;
+  FILE				*ifp ;
+  char				hack[80] , *buf = (char *) NULL, bufalloc=0 ;
+  ThematicIndexHeader		h ;
+  ThematicIndexDirectory	d ;
+  set_type			s ;
+
+  /* open output index file */
+
+  if (( ifp = fopen ( idxname, "rb" )) == NULL ) {
+    sprintf ( hack, "No such index < %s >", idxname ) ;
+    SWhimper ( hack ) ;
+  }
+
+  if ( read_thematic_index_header ( &h, ifp ) == (long int)NULL )
+    SWhimper ( "error reading index header" ) ;
+
+  if ( h.index_type == 'G' ) {
+    fclose ( ifp ) ;
+    s = read_gazetteer_index ( idxname, value ) ;
+    return s ;
+  }
+
+  if ( value ) 		/* search for pattern */
+    switch ( h.column_type ) {			/* using address */
+    case	'I':
+      memcpy ( &ival, value, sizeof (long int)) ;
+      break ;
+    case	'S':
+      memcpy ( &sval, value, sizeof (short int)) ;
+      break ;
+    case	'F':
+      memcpy ( &fval, value, sizeof (float)) ;
+      break ;
+    case	'R':
+      memcpy ( &dval, value, sizeof (double)) ;
+      break ;
+    case	'T':
+      buf = (char *) vpfmalloc ( h.type_count ) ;
+      /* leave value as is */
+      bufalloc = 1;
+      break ;
+    }
+  else
+    SWhimper ( "require a value to search on.") ;
+
+  /* create set */
+
+  s = set_init ( h.table_nrows ) ;
+
+  /* Look for a matching directory entry */
+
+  for ( i=0; i < h.nbins; i++ ) {
+
+    switch ( h.column_type ) {
+    case 	'I':
+      Read_Vpf_Int ( &d.value.ival, ifp, 1) ;
+      if ( ival == d.value.ival ) {
+	/* found the match */
+	Match = i ;
+	i = h.nbins ;	/* exit */
+      }
+      break ;
+    case 	'S':         
+      Read_Vpf_Short ( &d.value.sval, ifp, 1) ;
+      if ( sval == d.value.sval ) {
+	/* found the match */
+	Match = i ;
+	i = h.nbins ;	/* exit */
+      }
+      break ;
+    case 	'F':
+      Read_Vpf_Float ( &d.value.fval, ifp, 1) ;
+      if ( fval == d.value.fval ) {
+	/* found the match */
+	Match = i ;
+	i = h.nbins ;	/* exit */
+      }
+      break ;
+    case 	'R':         
+      Read_Vpf_Float ( &d.value.dval, ifp, 1) ;
+      if ( dval == d.value.dval ) {
+	/* found the match */
+	Match = i ;
+	i = h.nbins ;	/* exit */
+      }
+      break ;
+    case 	'T':
+      Read_Vpf_Char ( buf, ifp, h.type_count ) ;
+      bufalloc = 1;
+      if ( ! strcmp ( value, buf ) ) {
+	/* found the match */
+	Match = i ;
+	i = h.nbins ;	/* exit */
+      }
+      break ;
+    } /* end of switch */
+
+    Read_Vpf_Int ( &d.start_offset, ifp, 1) ;
+    Read_Vpf_Int ( &d.num_items, ifp, 1) ;
+
+  }  /* end of i loop */
+
+  if ( bufalloc ) free ( buf ) ;
+
+  if ( Match < 0 ) {
+     fclose(ifp);
+     return s;
+  }
+
+  /* We've got a match, so now read the ids in */
+
+  if ( fseek ( ifp, d.start_offset, 0 ) != 0 )
+    SWhimper ( "error in fseek") ;
+
+  /* read data into user-defined pointer.  User must free this pointer */
+
+  if ( h.id_data_type == 'I' )
+    for ( i=0 ; i < d.num_items; i++ ) {
+      Read_Vpf_Int ( &ival, ifp, 1 ) ;
+      set_insert ( ival, s ) ;			/* set the id in the set */
+    }
+  else
+    for ( i=0 ; i < d.num_items; i++ ) {
+      Read_Vpf_Short ( &sval, ifp, 1 ) ;
+      set_insert ( (long int) sval, s ) ;
+    }
+
+  fclose ( ifp ) ;
+
+  return s ;					/* also return set */
+
+}   /*end of read_index */
+
+
+/*************************************************************************
+ *
+ *N  open_thematic_index
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Open and initialize a thematic index.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    idxname <input> == (char *) name of index file
+ *
+ *   Returns:
+ *
+ *    ThematicIndex     Thematic index structure.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	read_thematic_index_header		see below
+ *	set_init				SET.C
+ *	set_insert
+ *	Vpf_Read_* macros
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+ThematicIndex open_thematic_index ( char *idxname )
+{
+  char				hack[80];
+  ThematicIndex		        idx ;
+
+  idx.d = NULL;
+  idx.gid = NULL;
+
+  /* open output index file */
+
+  if (( idx.fp = fopen ( idxname, "rb" )) == NULL ) {
+    sprintf ( hack, "No such index < %s >", idxname ) ;
+    OWhimper ( hack ) ;
+  }
+
+  if ( read_thematic_index_header ( &idx.h, idx.fp ) == (long int)NULL )
+    OWhimper ( "error reading index header" ) ;
+
+  if ( idx.h.index_type == 'G' ) {
+    /* gazetteer_index  */
+     if (read_gazetteer_index_directory(&idx.gid,&idx.h,idx.fp)
+	 ==(long int)NULL) {
+	fclose(idx.fp);
+	idx.fp = NULL;
+     }
+  }
+
+  return idx;
+}
+
+/*************************************************************************
+ *
+ *N  search_thematic_index
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To search an index file, regardless of its type ( T or G ) and
+ *	return a set type array
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    idx     <input> == (ThematicIndex) thematic index
+ *    value   <input> == (char *) address of value to search on.
+ *			 THE PROGRAMMER MUST INSURE THAT THIS ADDRESS
+ *			 CORRESPONDS TO THE TABLE COLUMN AND INDEX FILE.
+ *
+ *   Returns:
+ *
+ *    set_type		a set corresponding to the vpf table, where each
+ *			bit relates to the ID in the table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	read_thematic_index_header		see below
+ *	set_init				SET.C
+ *	set_insert
+ *	Vpf_Read_* macros
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+set_type search_thematic_index ( ThematicIndex *idx,
+				 char *value )
+{
+  long int 			i , ival = 0, Match = -1;
+  short int			sval = 0;
+  float				fval = 0.0 ;
+  double			dval = 0.0 , atof () ;
+  char				*buf = (char *) NULL, bufalloc=0 ;
+  ThematicIndexDirectory	d ;
+  set_type			s ;
+
+  /* open output index file */
+
+  if (!idx->fp) {
+     s = set_init(1);
+     return s;
+  }
+
+  if ( idx->h.index_type == 'G' ) {
+    s = search_gazetteer_index ( idx, value ) ;
+    return s ;
+  }
+
+  if ( value ) 		/* search for pattern */
+    switch ( idx->h.column_type ) {			/* using address */
+    case	'I':
+      memcpy ( &ival, value, sizeof (long int)) ;
+      break ;
+    case	'S':
+      memcpy ( &sval, value, sizeof (short int)) ;
+      break ;
+    case	'F':
+      memcpy ( &fval, value, sizeof (float)) ;
+      break ;
+    case	'R':
+      memcpy ( &dval, value, sizeof (double)) ;
+      break ;
+    case	'T':
+      buf = (char *) vpfmalloc ( idx->h.type_count ) ;
+      /* leave value as is */
+      bufalloc = 1;
+      break ;
+    }
+  else
+    SWhimper ( "require a value to search on.") ;
+
+  /* create set */
+
+  s = set_init ( idx->h.table_nrows ) ;
+
+  /* Look for a matching directory entry */
+
+  fseek(idx->fp,THEMATIC_INDEX_HEADER_SIZE,SEEK_SET);
+
+  for ( i=0; i < idx->h.nbins; i++ ) {
+
+    switch ( idx->h.column_type ) {
+    case 	'I':
+      Read_Vpf_Int ( &d.value.ival, idx->fp, 1) ;
+      if ( ival == d.value.ival ) {
+	/* found the match */
+	Match = i ;
+	i = idx->h.nbins ;	/* exit */
+      }
+      break ;
+    case 	'S':         
+      Read_Vpf_Short ( &d.value.sval, idx->fp, 1) ;
+      if ( sval == d.value.sval ) {
+	/* found the match */
+	Match = i ;
+	i = idx->h.nbins ;	/* exit */
+      }
+      break ;
+    case 	'F':
+      Read_Vpf_Float ( &d.value.fval, idx->fp, 1) ;
+      if ( fval == d.value.fval ) {
+	/* found the match */
+	Match = i ;
+	i = idx->h.nbins ;	/* exit */
+      }
+      break ;
+    case 	'R':         
+      Read_Vpf_Float ( &d.value.dval, idx->fp, 1) ;
+      if ( dval == d.value.dval ) {
+	/* found the match */
+	Match = i ;
+	i = idx->h.nbins ;	/* exit */
+      }
+      break ;
+    case 	'T':
+      Read_Vpf_Char ( buf, idx->fp, idx->h.type_count ) ;
+      bufalloc = 1;
+      if ( ! strcmp ( value, buf ) ) {
+	/* found the match */
+	Match = i ;
+	i = idx->h.nbins ;	/* exit */
+      }
+      break ;
+    } /* end of switch */
+
+    Read_Vpf_Int ( &d.start_offset, idx->fp, 1) ;
+    Read_Vpf_Int ( &d.num_items, idx->fp, 1) ;
+
+  }  /* end of i loop */
+
+  if ( bufalloc ) free ( buf ) ;
+
+  if ( Match < 0 ) {
+     return s;
+  }
+
+  /* We've got a match, so now read the ids in */
+
+  if ( fseek ( idx->fp, d.start_offset, 0 ) != 0 )
+    SWhimper ( "error in fseek") ;
+
+  /* read data into user-defined pointer.  User must free this pointer */
+
+  if ( idx->h.id_data_type == 'I' )
+    for ( i=0 ; i < d.num_items; i++ ) {
+      Read_Vpf_Int ( &ival, idx->fp, 1 ) ;
+      set_insert ( ival, s ) ;			/* set the id in the set */
+    }
+  else
+    for ( i=0 ; i < d.num_items; i++ ) {
+      Read_Vpf_Short ( &sval, idx->fp, 1 ) ;
+      set_insert ( (long int) sval, s ) ;
+    }
+
+  return s ;					/* also return set */
+
+}   /*end of search_index */
+
+
+/*************************************************************************
+ *
+ *N  close_thematic_index
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	Close a thematic index.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    idx <input> == (ThematicIndex *) thematic index
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	read_thematic_index_header		see below
+ *	set_init				SET.C
+ *	set_insert
+ *	Vpf_Read_* macros
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+void close_thematic_index ( ThematicIndex *idx )
+{
+  fclose ( idx->fp ) ;
+  if (idx->d) free(idx->d);
+  if (idx->gid) free(idx->gid);
+}
+
+/*************************************************************************
+ *
+ *N  create_gazetteer_index
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To create a gazetteer file
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *
+ *    tablename  <input> == (char *) the name of an existing file
+ *					<= 11 chars long
+ *    idx_fname  <input> == (char *) name of index file
+ *    columnname <input> == (char *) is a column existing in tablename
+ *				        <= 24 chars long
+ *
+ *    idx_set <input> == (char *) is an array of printable ASCII characters 
+ *				with no duplicates
+ *
+ *    return value < 0
+ *
+ *  	  -1 some OS error, check errno for something more exact
+ *        -2 tablename is not a vpf table
+ *        -3 columnname is not in the vpf table 
+ *        -4 column type not text
+ *
+ *    return value = 0
+ *         an index record for each character in index_set has been created
+ *
+ *         the index file name is the same as tablename but with .?ti
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    	Jim Tenbrink
+ *	Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	read_thematic_index_header		see below
+ *	set_init				SET.C
+ *	set_insert
+ *	Vpf_Read_* macros
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+
+long int create_gazetteer_index (char *tablename,
+				 char *idx_fname ,
+				 char *columnname,
+				 char *idx_set)
+{
+  vpf_table_type t;
+  row_type       r;
+  long int       c;
+  FILE         * idx_fp;
+  ThematicIndexHeader
+                 gi;
+  ThematicIndexDirectory
+               * gid;
+  set_type     * idx_bit_sets;
+  register long int   i,
+                      j;
+  unsigned long int l,
+                    set_byte_size;
+
+  t = vpf_open_table(tablename, disk, "rb", (char) NULL);
+  c = table_pos(strupr(columnname), t);
+
+  if (t.header[c].type != 'T') {
+    vpf_close_table(&t);
+    return -4;
+  }
+
+  idx_fp = fopen(idx_fname, "wb");
+
+  if (idx_fp == NULL)
+    return -1;
+
+  /* only write out the table name, not the rest */
+
+  for ( i = strlen ( tablename ); i > 0; i-- )
+    if ( tablename[i] == '/' ) break ;
+  if ( i && (unsigned int)i < strlen (tablename) )
+    strcpy ( gi.vpf_table_name, strupr ( &tablename[i+1] ) ) ;
+  else
+    strcpy(gi.vpf_table_name, strupr ( tablename) );
+  strcpy(gi.vpf_column_name, columnname);
+
+  gi.column_type = 'T';
+  gi.index_type  = 'G';
+  gi.type_count = 1 ;
+  gi.id_data_type = 'S' ;
+  gi.nbins       = strlen(idx_set);
+  gi.table_nrows = t.nrows;
+  set_byte_size  = (unsigned int)ceil(t.nrows/8.0);
+
+  /* force input string to lower case , rdf */
+
+  for ( i=0; i < gi.nbins; i++ )
+    idx_set[i] = tolower ( idx_set[i] ) ;
+
+  /*
+   * ti.nbytes is the offset into the index file at which the
+   * bit arrays start
+   */
+
+  gi.nbytes = THEMATIC_INDEX_HEADER_SIZE +
+              gi.nbins * ( sizeof (char) + DIRECTORY_SIZE ) ;
+
+  gid = (ThematicIndexDirectory *) malloc(sizeof(ThematicIndexDirectory)
+					  * gi.nbins);
+  idx_bit_sets = (set_type *) malloc(sizeof(set_type) * gi.nbins);
+
+  for (i = 0; i < gi.nbins; i++) {
+    idx_bit_sets[i]   = set_init(t.nrows);
+    gid[i].value.cval = idx_set[i];
+    gid[i].num_items  = 1;
+  }
+
+  /*
+   * lets suck up some CPU cycles here
+   */
+  for (l = 0; (int)l < t.nrows; l++) {
+
+    r = get_row(l+1, t);
+
+    for (i = 0; i < gi.nbins; i++)
+      for (j = 0; j < r[c].count; j++)
+	/* No matter the input character, make it lower case , rdf added */
+        if ( tolower (*((char *) r[c].ptr + j)) == idx_set[i]) {
+          set_insert(l, idx_bit_sets[i]);
+          break;
+        }
+
+    free_row(r, t);
+
+  }
+
+  vpf_close_table(&t);
+
+  if (write_thematic_index_header(gi, idx_fp) == (long int)NULL) {
+    fclose(idx_fp);
+    for (i = 0; i < gi.nbins; i++)
+      set_nuke(&idx_bit_sets[i]);
+    return -1;
+  }
+
+  if (write_gazetteer_index_directory(gi,
+                                     gid,
+                                     set_byte_size,
+                                     idx_fp) == 0         ) {
+    fclose(idx_fp);
+    for (i = 0; i < gi.nbins; i++)
+      set_nuke(&idx_bit_sets[i]);
+    return -1;
+  }
+
+  for (i = 0; i < gi.nbins; i++) {
+    if ( ! Write_Vpf_Char(idx_bit_sets[i].buf, idx_fp, set_byte_size) ) {
+      fclose(idx_fp);
+      for (i = 0; i < gi.nbins; i++)
+        set_nuke(&idx_bit_sets[i]);
+      return -1;
+    }
+  }
+
+  fclose(idx_fp);
+  for (i = 0; i < gi.nbins; i++)
+    set_nuke(&idx_bit_sets[i]);
+  free(idx_bit_sets);
+
+  return 0;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  read_gazetteer_index
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To read an gazeeteer index file, and return a set type array
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    idx_fname <input> == (char *) the name of a vpf gazetteer index
+ *                         created with a call to to create_gaz_index.
+ *
+ *    query_str <input> == (char *) string that contains only characters
+ *                         which form a subset of the characters passed
+ *                         to create_gaz_index when idx_fname was created.
+ *
+ *      the vpf table from which the file idx_fname was derived must
+ *      exist in the same directory as idx_fname
+ *
+ * out: case the returned set size > 0
+ *        a bit array which can be used as a rough filter for the
+ *        vpf table from which the index file idx_fname was derived.
+ *    
+ *      bits which are set in the array are the record numbers in the vpf table
+ *        (from which idx_fname was derived) which may contain query_string
+ *
+ *      case the returned set size = 0
+ *        some system error occurred
+ *        most likely the indexed vpf table couldn't be found in the
+ *        same directory
+ *
+ * note: query_str is treated as a set, so duplicate occurrences
+ *       of the same character are ignored. I need a way of flagging
+ *       those duplicate occurrences. Instead of sorting the string
+ *       and removing duplicates, I use the num_items field in each
+ *       element of the directory array.
+ *
+ *   Returns:
+ *
+ *    set_type		a set corresponding to the vpf table, where each
+ *			bit relates to the ID in the table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    	Jim Tenbrink
+ * 	Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	read_thematic_index_header		see below
+ *	set_init				SET.C
+ *	set_insert
+ *	Vpf_Read_* macros
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+set_type read_gazetteer_index (char *idx_fname, char *query_str )
+{
+  ThematicIndexHeader gi;
+  ThematicIndexDirectory
+                    * gid;
+  FILE              * idx_fp;
+  set_type            query_set = {0, 0},
+		      xsect_set,
+                      result_set;
+  register int        query_len = strlen(query_str),
+                      i,
+                      j;
+  unsigned long       set_byte_size;
+  char                query_char;
+
+  idx_fp = fopen(idx_fname, "rb");
+
+  if (idx_fp == NULL)
+    return query_set;
+
+  if (read_thematic_index_header (&gi, idx_fp) == (long int)NULL) {
+    fclose(idx_fp);
+    return query_set;
+  }
+
+  if (read_gazetteer_index_directory (&gid, &gi, idx_fp) == (long int)NULL) {
+    fclose(idx_fp);
+    return query_set;
+  }
+
+  for (j = 0; j < gi.nbins; j++)
+    gid[j].num_items = 0;
+
+  query_set = set_init(gi.table_nrows);
+  xsect_set = set_init(gi.table_nrows);
+
+  set_on(query_set);
+  set_byte_size = (unsigned int)ceil(gi.table_nrows/8.0);
+
+  for (i = 0; i < query_len; i++) {
+
+    query_char = tolower(query_str[i]);
+
+    for (j = 0; j < gi.nbins; j++)
+      if (gid[j].value.cval == query_char)  {
+        gid[j].num_items++;
+        break;
+      }
+    if (gid[j].num_items > 1)
+      continue;
+
+    fseek(idx_fp, gid[j].start_offset, 0);
+    if ( ! Read_Vpf_Char(xsect_set.buf, idx_fp, set_byte_size) ) {
+      set_type err = set_init ( 0 ) ;
+      return err ;
+    }
+
+    result_set = set_intersection(query_set, xsect_set);
+    set_assign(&query_set, result_set);
+    set_nuke(&result_set);
+
+  }
+
+  fclose(idx_fp);
+  free(gid);
+  set_nuke(&xsect_set);
+
+  return query_set;
+}
+
+/*************************************************************************
+ *
+ *N  search_gazetteer_index
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To search an gazeeteer index file, and return a set type array
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ * in : idx is the gazetteer index opened with open_thematic_index
+ *
+ *      query_str contains only characters which form a subset of
+ *      the characters passed to create_gaz_index when idx_fname
+ *      was created
+ *
+ *      the vpf table from which the file idx_fname was derived must
+ *      exist in the same directory as idx_fname
+ *
+ * out: case the returned set size > 0
+ *        a bit array which can be used as a rough filter for the
+ *        vpf table from which the index file idx_fname was derived.
+ *    
+ *      bits which are set in the array are the record numbers in the vpf table
+ *        (from which idx_fname was derived) which may contain query_string
+ *
+ *      case the returned set size = 0
+ *        some system error occurred
+ *        most likely the indexed vpf table couldn't be found in the
+ *        same directory
+ *
+ * note: query_str is treated as a set, so duplicate occurrences
+ *       of the same character are ignored. I need a way of flagging
+ *       those duplicate occurrences. Instead of sorting the string
+ *       and removing duplicates, I use the num_items field in each
+ *       element of the directory array.
+ *
+ *   Returns:
+ *
+ *    set_type		a set corresponding to the vpf table, where each
+ *			bit relates to the ID in the table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    	Jim Tenbrink
+ * 	Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	read_thematic_index_header		see below
+ *	set_init				SET.C
+ *	set_insert
+ *	Vpf_Read_* macros
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+set_type search_gazetteer_index (ThematicIndex *idx, char *query_str )
+{
+  set_type            query_set = {0, 0, 0, 0},
+		      xsect_set,
+                      result_set;
+  register int        query_len = strlen(query_str),
+                      i,
+                      j;
+  unsigned long       set_byte_size;
+  char                query_char;
+
+  if (idx->fp == NULL)
+    return query_set;
+
+  for (j = 0; j < idx->h.nbins; j++)
+    idx->gid[j].num_items = 0;
+
+  query_set = set_init(idx->h.table_nrows);
+  xsect_set = set_init(idx->h.table_nrows);
+
+  set_on(query_set);
+  set_byte_size = (unsigned int)ceil(idx->h.table_nrows/8.0);
+
+  for (i = 0; i < query_len; i++) {
+
+    query_char = tolower(query_str[i]);
+
+    for (j = 0; j < idx->h.nbins; j++)
+      if (idx->gid[j].value.cval == query_char)  {
+	idx->gid[j].num_items++;
+	break;
+      }
+    if (idx->gid[j].num_items > 1)
+      continue;
+
+    fseek(idx->fp, idx->gid[j].start_offset, 0);
+    if ( ! Read_Vpf_Char(xsect_set.buf, idx->fp, set_byte_size) ) {
+      set_type err = set_init ( 1 ) ;
+      return err ;
+    }
+
+    result_set = set_intersection(query_set, xsect_set);
+    set_assign(&query_set, result_set);
+    set_nuke(&result_set);
+
+  }
+
+  set_nuke(&xsect_set);
+
+  return query_set;
+}
+
+/*************************************************************************
+ *
+ *N  read_gazetteer_index_directory
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To read an index file, regardless of its type ( T or G ) and
+ *	return a set type array
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ * in : *gid is undefined
+ *
+ *      *gi is the gazetteer index header for the open index file
+ *      referenced by idx_fp
+ *
+ * out: case return value is one
+ *        *gid is an array of directory entries with gi->nbin elements
+ *
+ *        the sval member of the value union contains the indexed character
+ *
+ *        the start_offset member of the directory structure contains the
+ *        disk offset for the start of the indexed characters bit array
+ *
+ *      case zero return value
+ *        an error was probably encountered during the read
+ *        *gid is undefined
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	read_thematic_index_header		see below
+ *	set_init				SET.C
+ *	set_insert
+ *	Vpf_Read_* macros
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+long int read_gazetteer_index_directory(
+				   ThematicIndexDirectory **gid,
+				   ThematicIndexHeader     *gi,
+				   FILE                    *idx_fp)
+{
+  int i;
+
+#if UNIX
+  if ( fseek ( idx_fp,sizeof (ThematicIndexHeader)-sizeof(long int), 0 )!= 0 )
+#else
+  if (fseek(idx_fp, sizeof (ThematicIndexHeader), 0) != 0)
+#endif
+    return 0 ;
+
+  *gid = (ThematicIndexDirectory *) malloc(sizeof(ThematicIndexDirectory)
+                                           * gi->nbins);
+  if (*gid == NULL)
+    return 0;
+
+  for (i = 0; i < gi->nbins; i++) {
+    if ( ( ! Read_Vpf_Char(  &( (*gid)[i].value.cval ),   idx_fp, 1) ) ||
+	 ( ! Read_Vpf_Int(   &( (*gid)[i].start_offset ), idx_fp, 1) ) ||
+	 ( ! Read_Vpf_Int(   &( (*gid)[i].num_items ),    idx_fp, 1) )) {
+      return (long int)NULL ;
+    }
+  }
+  return 1;
+}
+
+/*************************************************************************
+ *
+ *N  read_thematic_index_header
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To read the thematic index header in a standard way
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *	h < in/out > == (ThematicIndexHeader *) header structure to be filled
+ *	ifp <input>  == ( FILE *ifp ) index file pointer
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	Read_Vpf_Int
+ *	Read_Vpf_Char
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+
+#define RWhimper() {\
+   return (long int)NULL ; }
+
+long int read_thematic_index_header ( ThematicIndexHeader *h, FILE *ifp ) 
+{
+  if ( fseek ( ifp, 0, 0 ) != 0 ) 	/* rewind, just in case */
+    return 0 ;				/* error */
+  if ( ! Read_Vpf_Int ( &h->nbytes, ifp, 1 ) )
+    RWhimper();
+  if ( ! Read_Vpf_Int ( &h->nbins, ifp, 1 ) )
+    RWhimper() ;
+  if ( ! Read_Vpf_Int ( &h->table_nrows, ifp, 1 ) )
+    RWhimper() ;
+  if ( ! Read_Vpf_Char ( &h->index_type, ifp, 1 ) )
+    RWhimper() ;
+  if ( ! Read_Vpf_Char ( &h->column_type, ifp, 1 ) )
+    RWhimper() ;
+  if ( ! Read_Vpf_Int ( &h->type_count, ifp, 1 ) )
+    RWhimper() ;
+  if ( ! Read_Vpf_Char ( &h->id_data_type, ifp, 1 ) )
+    RWhimper() ;
+  if ( ! Read_Vpf_Char ( &h->vpf_table_name, ifp, 12 ) )
+    RWhimper() ;
+  if ( ! Read_Vpf_Char ( &h->vpf_column_name, ifp, 25 ) )
+    RWhimper() ;
+  if ( ! Read_Vpf_Char ( &h->padding, ifp, 4 ) )
+    RWhimper() ;
+  return 1 ;
+}
+
+/*************************************************************************
+ *
+ *N  write_thematic_index_header
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To write the thematic index header in a standard way
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *	h < input > == (ThematicIndexHeader) header structure to write from
+ *	ifp <input>  == ( FILE *ifp ) index file pointer
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	Write_Vpf_Int
+ *	Write_Vpf_Char
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+
+#define WWhimper() {\
+   return (long int)NULL ; }
+
+long int write_thematic_index_header ( ThematicIndexHeader h, FILE *ifp ) 
+{
+  if ( fseek ( ifp, 0, 0 ) != 0 ) 	/* rewind, just in case */
+    WWhimper() ;				/* error */
+  if ( ! Write_Vpf_Int ( &h.nbytes, ifp, 1 ) )
+    WWhimper() ;
+  if ( ! Write_Vpf_Int ( &h.nbins, ifp, 1 ) )
+    WWhimper() ;
+  if ( ! Write_Vpf_Int ( &h.table_nrows, ifp, 1 ) )
+    WWhimper() ;
+  if ( ! Write_Vpf_Char ( &h.index_type, ifp, 1 ) )
+    WWhimper() ;
+  if ( ! Write_Vpf_Char ( &h.column_type, ifp, 1 ) )
+    WWhimper() ;
+  if ( ! Write_Vpf_Int ( &h.type_count, ifp, 1 ) )
+    WWhimper() ;
+  if ( ! Write_Vpf_Char ( &h.id_data_type, ifp, 1 ) )
+    WWhimper() ;
+  if ( ! Write_Vpf_Char ( &h.vpf_table_name, ifp, 12 ) )
+    WWhimper() ;
+  if ( ! Write_Vpf_Char ( &h.vpf_column_name, ifp, 25 ) )
+    WWhimper() ;
+  if ( ! Write_Vpf_Char ( &h.padding, ifp, 4 ) )
+    WWhimper() ;
+  return 1 ;
+}
+
+
+/*************************************************************************
+ *
+ *N  write_thematic_index_directory
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To write the thematic index header in a standard way
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *	h < input > == (ThematicIndexHeader) header structure
+ *	d < input > == (ThematicIndexDirectory *) directory array structure
+ *	idsize < input > == (long int) size of each data element.
+ *		for T indexes, this is either 2 bytes or 4 bytes
+ *		for G indexes, it will be num_in_set (set) 
+ *			       or the size of the bit array.
+ *	ifp <input>  == ( FILE *ifp ) index file pointer
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	Vpf_Write_*
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+
+#define WTWhimper() {\
+   return (long int)NULL ; }
+
+long int write_thematic_index_directory ( ThematicIndexHeader h, 
+					  ThematicIndexDirectory *d,
+					  long int idsize , /* size of data */
+					  FILE *ifp )
+{
+  long	int	offset = h.nbytes ,
+                i ;
+
+  /* rewind, just in case */
+#if UNIX
+  if ( fseek ( ifp, sizeof (ThematicIndexHeader)-sizeof(long int), 0 ) != 0 )
+#else
+  if ( fseek ( ifp, sizeof (ThematicIndexHeader), 0 ) != 0 )
+#endif
+    WTWhimper() ;
+
+  for ( i=0; i < h.nbins; i++ ) {
+    
+    switch ( h.column_type ) {
+    case 'I':
+      if ( ! Write_Vpf_Int ( &d[i].value.ival, ifp, 1 ) )
+	WTWhimper() ;
+      break ;
+    case 'T':
+      /* Not tested for text strings */
+      if ( ! Write_Vpf_Char ( &d[i].value.strval, ifp, h.type_count ) )
+	WTWhimper() ;
+      break ;
+    case 'S':
+      if ( ! Write_Vpf_Short ( &d[i].value.sval, ifp, 1 ) )
+	WTWhimper() ;				
+      break ;
+    case 'F':
+      if ( ! Write_Vpf_Float ( &d[i].value.fval, ifp, 1 ) )
+	WTWhimper() ;				
+      break ;
+    case 'R':
+      if ( ! Write_Vpf_Double ( &d[i].value.dval, ifp, 1 ) )
+	WTWhimper() ;				
+      break ;
+    }	/* end of switch */
+
+    if ( ! Write_Vpf_Int ( &offset, ifp, 1 ) )
+	WTWhimper() ;				
+    if ( ! Write_Vpf_Int ( &d[i].num_items, ifp, 1 ) )
+	WTWhimper() ;				
+    
+    /* this offset is constant, no matter the data type */
+
+    offset += ( idsize * d[i].num_items ) ;
+
+  }  /* end of i loop */
+
+  return 1 ;
+
+}    /* end of write_directory */
+
+
+/*************************************************************************
+ *
+ *N  write_gazetteer_index_directory
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *	To write the gazetteer thematic index header in a standard way
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *	h < input > == (ThematicIndexHeader) header structure 
+ *	d < input > == (ThematicIndexDirectory *) directory array structure
+ *	idsize < input > == (long int) size of each data element.
+ *		for T indexes, this is either 2 bytes or 4 bytes
+ *		for G indexes, it will be num_in_set (set) 
+ *			       or the size of the bit array.
+ *	ifp <input>  == ( FILE *ifp ) index file pointer
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       October 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *	Vpf_Write_*
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+
+#define WTGWhimper() {\
+  return (long int)NULL ; }
+
+long int write_gazetteer_index_directory ( ThematicIndexHeader h, 
+					  ThematicIndexDirectory *d, 
+					  long int idsize , /* size of data */
+					  FILE *ifp )
+{
+  long	int	offset = h.nbytes ,
+                i ;
+
+  /* rewind, just in case */
+
+  if ( fseek ( ifp, THEMATIC_INDEX_HEADER_SIZE, 0 )!= 0 )
+    WTWhimper() ;				
+
+  for ( i=0; i < h.nbins; i++ ) {
+    
+    if ( ! Write_Vpf_Char ( &d[i].value.cval, ifp, 1 ) )
+      WTGWhimper() ;
+
+    if ( ! Write_Vpf_Int ( &offset, ifp, 1 ) )
+	WTGWhimper() ;				
+    if ( ! Write_Vpf_Int ( &d[i].num_items, ifp, 1 ) )
+	WTGWhimper() ;				
+    
+    /* this offset is constant, no matter the data type */
+
+    offset += ( idsize * d[i].num_items ) ;
+
+  }  /* end of i loop */
+
+  return 1 ;
+
+}    /* end of write_directory */
+
+
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpftidx.h b/Utilities/OSSIM/ossim_core/vpf_util/vpftidx.h
new file mode 100644
index 0000000000..bfbdbefc99
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpftidx.h
@@ -0,0 +1,145 @@
+/*       static char SCCS_ID[] = "@(#) vpftidx.h 1.5 10/9/91" ;            */
+/*************************************************************************
+ *
+ * Environmental Systems Research Institute (ESRI) Applications Programming
+ *
+ *N  Module VPFTIDX
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *P
+ *   Purpose: To create a thematic index on a VPF table column.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       September 1991  
+ *E
+  *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible
+ *E
+ *************************************************************************/
+
+#ifndef _VPFTIDX_
+#define _VPFTIDX_
+#ifdef __cplusplus
+extern "C" {
+#endif
+   
+#include "set.h"
+
+typedef struct {			/* Total of 40 bytes */
+  long int	nbytes ,		/* 40 + directory length */
+                nbins ,			/* Directory size */
+                table_nrows ;		/* Num rows in original table */
+  char		index_type ,		/* T = thematic, G = gazetteer */
+        	column_type ;		/* T, I, R, S, F, K */
+  long int      type_count ;		/* usually 1, but more for T */
+  char 		id_data_type ,		/* I if > 32767, else S */
+                vpf_table_name[12] ,
+                vpf_column_name[25] ,	/* 16 bytes + 9 for TILE_ID */
+                padding[4] ;		/* To make it a nice 60 bytes */
+} ThematicIndexHeader ;
+
+#define         THEMATIC_INDEX_HEADER_SIZE    60
+
+#define         DIRECTORY_SIZE                (sizeof(long int)*2)
+
+#define		MAX_ID		32767	/* Threshold between S and I ids */
+
+typedef struct {			/* length = sizeof (datatype) + */
+  union {				/* 	    8 * nbins           */
+    char	cval ,
+                *strval ;
+    long int	ival ;
+    short int	sval ;
+    float	fval ;
+    double 	dval ;
+  } value ;
+  long int	start_offset ,
+                num_items ;		/* For each value, count the ids */
+  /* Store the row ids here */
+/*  char    	*ids ;*/			/* depending on id_data_type, this */
+  set_type idset;
+} ThematicIndexDirectory ;
+
+typedef struct {
+   ThematicIndexHeader h;
+   ThematicIndexDirectory *d, *gid;
+   FILE *fp;
+} ThematicIndex;
+
+/* PROTOTYPES */
+
+/*char* strupr(char*);*/
+
+set_type	read_thematic_index ( char *tablename,
+				       char *value ) ;
+
+ThematicIndex	open_thematic_index ( char *tablename );
+
+set_type	search_thematic_index ( ThematicIndex *themindex,
+					char *value ) ;
+
+void	        close_thematic_index ( ThematicIndex *themindex );
+
+set_type 	read_gazetteer_index (char * vpfname, char * query_str ) ;
+
+set_type 	search_gazetteer_index (ThematicIndex *idx,
+					char * query_str ) ;
+
+long int 	read_gazetteer_index_directory (
+						ThematicIndexDirectory ** gid,
+						ThematicIndexHeader     * gi,
+						FILE * idx_fp);
+
+
+
+long int	write_thematic_index_header ( ThematicIndexHeader h ,
+					      FILE *fp ) ;
+
+long int	read_thematic_index_header ( ThematicIndexHeader *h ,
+					     FILE *fp ) ;
+
+long int	write_thematic_index_directory ( 
+				       ThematicIndexHeader h ,
+				       ThematicIndexDirectory *d,
+				       long int size,
+				       FILE *fp ) ;
+
+long int	write_gazetteer_index_directory ( 
+				       ThematicIndexHeader h ,
+				       ThematicIndexDirectory *d,
+				       long int size,
+				       FILE *fp ) ;
+
+
+
+long int        create_thematic_index ( char indextype,
+		 	                char *tablename,
+                                        char *idxname ,
+				        char *columnname,
+				        char *idx_set );
+
+long int        create_gazetteer_index (char *tablename,
+				        char *idx_fname ,
+				        char *columnname,
+				        char *idx_set);
+
+#ifdef __cplusplus
+}
+#endif
+   
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfview.h b/Utilities/OSSIM/ossim_core/vpf_util/vpfview.h
new file mode 100644
index 0000000000..e148fa8a5f
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfview.h
@@ -0,0 +1,206 @@
+/* VPFVIEW.H */
+
+#ifndef __VPFVIEW_H__
+#define __VPFVIEW_H__
+
+#include <stdlib.h> /* to pick up min/max... */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+   
+#include "set.h"
+#ifdef __MSDOS__
+#  include "gui.h"
+#endif
+#include "vpftable.h"
+#include "linklist.h"
+
+#ifdef __MSDOS__
+typedef unsigned char VPF_BOOLEAN;
+#else
+typedef unsigned VPF_BOOLEAN;
+#  ifndef min
+#    define min(a,b) ((a) <= (b) ? (a) : (b))
+#  endif
+#  ifndef max
+#    define max(a,b) ((a) <= (b) ? (b) : (a))
+#  endif
+#if (!defined(_MSC_VER))
+#  ifndef stricmp
+#    define stricmp(a,b) ossim_strcasecmp(a,b)
+#  endif
+#  ifndef strcmpi
+#    define strcmpi(a,b) ossim_strcasecmp(a, b)
+#  endif
+#  ifndef strncmpi
+#    define strncmpi(a,b,c) ossim_strncasecmp(a,b,c)
+#  endif
+#  ifndef ltoa
+#    define ltoa(l,s,len) sprintf(s,"%d",l)
+#  endif
+#  ifndef itoa
+#    define itoa(i,s,len) sprintf(s,"%d",i)
+#  endif 
+#endif
+   
+#endif
+
+typedef char color_type;
+
+
+/* Degree-minutes-seconds type */
+typedef struct {
+   int   degrees;
+   int   minutes;
+   float seconds;
+} dms_type;
+
+
+/* Geographic extent */
+typedef struct {
+   float x1, y1, x2, y2;
+} extent_type;
+
+/* Currently supported VPF versions */
+typedef enum { VPF_0_7, VPF_0_8 } vpf_version_type;
+
+
+/* VPF database internal structure */
+typedef struct {
+   char name[9];      /* Name of the VPF database */
+   char *path;        /* DOS path name to the database */
+   char **library;    /* Array of library names within the database */
+   int  nlibraries;   /* Number of libraries in the database */
+   char *producer;    /* Producer of the database - from header table */
+   vpf_version_type version; /* VPF Version of the database */
+   int byte_order;    /* Byte order of the database */
+} database_type;
+
+
+/* VPF coverage internal structure */
+typedef struct {
+   char name[9];        /* Name of the coverage */
+   char *description;   /* Description of the coverage */
+   char *path;          /* DOS path name to the coverage */
+   int  topolevel;      /* Topology level of the coverage */
+} coverage_type;
+
+
+/* VPF feature types */
+typedef enum { VPF_LINE=1, VPF_AREA, VPF_ANNO, VPF_POINT, VPF_COMPLEX_FEATURE=6 } vpf_feature_type;
+
+/* VPF primitive types */
+typedef enum { VPF_EDGE=1, VPF_FACE, VPF_TEXT, VPF_ENTITY_NODE, VPF_CONNECTED_NODE }
+   vpf_primitive_type;
+
+
+/* Units of measure */
+typedef enum { VPF_UNKNOWN_UNITS, VPF_METERS, VPF_SECONDS, VPF_FEET, VPF_INCHES,
+	       VPF_KILOMETERS, VPF_OTHER_UNITS, VPF_DEC_DEGREES } units_type;
+
+
+/* VPF feature class internal structure */
+typedef struct {
+   char name[40];       /* Name of the feature class */
+   char *description;   /* Description of the feature class */
+   int  coverage;       /* Containing coverage number */
+   char *table;         /* Feature table name */
+   vpf_primitive_type primclass; /* Primitive class */
+   char cprim[6];       /* Array of primclasses if primclass=COMPLEX */
+   set_type view_set;   /* Themes of the view in this feature class */
+} feature_class_type;
+
+
+/* VPF library internal structure */
+typedef struct {
+   char name[9];            /* Name of the library */
+   char database[9];        /* Name of the containing database */
+   char *path;              /* DOS path name to the library */
+   char *description;       /* Library description */
+   extent_type extent;      /* Map extent of the library */
+   char security[15];       /* Security classification of the library */
+   coverage_type *cover;    /* Coverages within the library */
+   int ncover;              /* Number of coverages in the library */
+   feature_class_type *fc;  /* Feature classes within the library */
+   int nfc;                 /* Number of feature classes in the library */
+   long int ntiles;         /* Number of tiles in the library */
+   set_type tile_set;       /* Set of 'active' tiles in the library */
+   double tileheight;       /* 'Height' of tile 1 in the library */
+   VPF_BOOLEAN dec_degrees;     /* Coordinates in decimal degrees? */
+   char *prjname;           /* Projection name (if not dec_degrees) */
+   units_type units;        /* Units of measure (if not dec_degrees) */
+   vpf_version_type version; /* VPF Version of the database */
+} library_type;
+
+
+/* A theme is a single entry for a view of the database.  It can be */
+/* thought of as a stored query with a description and symbology.   */
+/* Each theme is associated with a feature class.                   */
+typedef struct {
+   char *description;              /* Description of the theme */
+   char *fc;                       /* Feature class name for the theme */
+   int  fcnum;                     /* Theme's feature class number */
+   int  primclass;                 /* Primitive class of the theme */
+   char *text_col;                 /* Column to be displayed as text */
+   char *expression;               /* Query expression */
+   int  point_color, point_symbol; /* Point color and symbol */
+   int  line_color, line_symbol;   /* Line color and symbol */
+   int  area_color, area_symbol;   /* Area color and symbol */
+   int  text_color, text_symbol;   /* Text color and symbol */
+} theme_type;
+
+
+/* View structure.  Each view is associated with a particular database */
+/* and a particular library within that datbase.                       */
+typedef struct {
+   char database[9];         /* Database name */
+   char library[9];          /* Library name */
+   char name[9];             /* View name */
+   int  nthemes;             /* Number of themes in the view */
+   theme_type *theme;        /* Array of themes */
+   set_type selected;        /* Set of themes selected for display */
+   set_type displayed;       /* Set of displayed themes */
+   linked_list_type sellist; /* List of selected themes (ordered) */
+} view_type;
+
+
+/* Map environment information */
+typedef struct {
+   extent_type mapextent;           /* Current map extent */
+   VPF_BOOLEAN     mapchanged;          /* Flag - has anything changed? */
+   VPF_BOOLEAN     mapdisplayed;        /* Flag - has the map been displayed? */
+   VPF_BOOLEAN     user_escape;         /* Flag - has the user hit escape? */
+   VPF_BOOLEAN     study_area_selected; /* Flag - study area selected? */
+   VPF_BOOLEAN     latlongrid;          /* Flag - lat-lon grid to be displayed?*/
+   VPF_BOOLEAN     scale_bar;           /* Flag - scale bar to be displayed? */
+#ifdef __MSDOS__
+   window_type scale_bar_window;    /* Window containing the scale bar */
+#endif
+   int         maptop;              /* Top y location of the map */
+   int         mapbottom;           /* Bottom y location of the map */
+   int         projection;          /* Current projection number */
+#ifdef __MSDOS__
+   void far    (*forward_proj)();   /* Forward projection function pointer*/
+   void far    (*inverse_proj)();   /* Inverse projection function pointer*/
+#endif
+} map_environment_type;
+
+
+/* Output devices */
+#define SCREEN     1
+#define POSTSCRIPT 2  /* Black and white */
+#define COLORPS    3
+#define PRINTER    4
+
+
+/* Functions: */
+
+#include "vpfmisc.h"
+
+set_type query_table( char *query, vpf_table_type table );
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/vpfwrite.c b/Utilities/OSSIM/ossim_core/vpf_util/vpfwrite.c
new file mode 100644
index 0000000000..93fff5aa4a
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/vpfwrite.c
@@ -0,0 +1,835 @@
+/*************************************************************************
+ *
+ *N  Module VPFWRITE.C
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This contains functions for writing data to VPF tables.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     N/A
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *     Original Coding:  Tom Wood	Fall 1990
+ *       Modifications:	 David Flinn	January 1991
+ *					July 1991
+ *		         Barry Michaels  October 1991
+ *					Modified from converter
+ *					software (UNIX) for
+ *					VPFVIEW software (DOS).
+ *			 Jim TenBrink   October 1991
+ *					Made vpfread.c and vpfwrite.c
+ *					disjoint
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+#include "machine.h"
+
+#ifdef CARBON
+#define MACHINE_BYTE_ORDER 0
+#endif
+
+#if __MSDOS__
+#include <io.h>
+#include <alloc.h>
+#include <dos.h>
+#include <graphics.h>
+#else
+	#ifndef _WIN32
+#include <unistd.h>
+	#endif
+#endif
+
+#if UNIX
+#include <sys/stat.h>
+#define   SEEK_SET    0         /* Turbo C fseek value */
+#define   SEEK_CUR    1
+#define   farmalloc   malloc    /* no farmallocs on UNIX */
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <memory.h>
+#include "vpftable.h"
+#include "vpfview.h"
+
+extern int STORAGE_BYTE_ORDER;
+
+/* Include statically to reduce external module dependencies */
+
+
+/*************************************************************************
+ *
+ *N  write_key
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function writes an id triplet key from the specified file.
+ *     It is assumed that there is enough free disk space to write to the
+ *     file. It is also assumed that the file pointer (fp) is already opened
+ *     for writing.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    key     <input> == (id_triplet_type) id triplet key.
+ *    fp      <input> == (FILE *) input file pointer.
+ *    return <output> == (long int) size of the key.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       July 1991      Based on read_key in vpftable.c
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+long int write_key( id_triplet_type key, FILE *fp )
+{
+  long int size = 0 ;	/* to count size of key write */
+  unsigned char tint ;
+  short int tshort ;
+
+   /* Assume that any count value has been written before this */
+   /* Only write one key in this subroutine, do not write more */
+
+  Write_Vpf_Char (&(key.type),fp,1);
+  size += sizeof ( char ) ;
+
+   switch (TYPE0(key.type)) {
+   case 0:
+     break;
+   case 1:
+     tint = (unsigned char) key.id ;
+     Write_Vpf_Char ( &tint, fp, 1 ) ;
+     size += sizeof ( char ) ;
+     break;
+   case 2:
+     tshort = (short) key.id ;
+     Write_Vpf_Short ( &tshort, fp, 1 ) ;
+     size += sizeof ( short int ) ;
+     break;
+   case 3:
+     Write_Vpf_Int (&(key.id), fp, 1 ) ;
+     size += sizeof ( long int ) ;
+     break;
+   }
+
+   switch (TYPE1(key.type)) {
+   case 0:
+     break;
+   case 1:
+     tint = (unsigned char) key.tile ;
+     Write_Vpf_Char ( &tint, fp, 1 ) ;
+     size += sizeof ( char ) ;
+     break;
+   case 2:
+     tshort = (short) key.tile ;
+     Write_Vpf_Short ( &tshort, fp, 1 ) ;
+     size += sizeof ( short int ) ;
+     break;
+   case 3:
+     Write_Vpf_Int (&(key.tile), fp, 1 ) ;
+     size += sizeof ( long int ) ;
+     break;
+   }
+
+   switch (TYPE2(key.type)) {
+   case 0:
+     break;
+   case 1:
+     tint = (unsigned char) key.exid ;
+     Write_Vpf_Char ( &tint, fp, 1 ) ;
+     size += sizeof ( char ) ;
+     break;
+   case 2:
+     tshort = (short) key.exid ;
+     Write_Vpf_Short ( &tshort, fp, 1 ) ;
+     size += sizeof ( short int ) ;
+     break;
+   case 3:
+     Write_Vpf_Int (&(key.exid), fp, 1 ) ;
+     size += sizeof ( long int ) ;
+     break;
+   }
+  return size ;
+}
+
+/*************************************************************************
+ *
+ *N  write_next_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function writes the next row of the table.
+ *     The parameter row must be initialized prior to this functional, either
+ *     by being read in from an existing table or set to valid values.
+ *     A row with any empty columns should not be written out.
+ *     The parameter table must be a valid table and initialized prior to
+ *     this function, by vpf_open_table.  It is assumed that there is
+ *     enough free disk space to write to the file. It is also assumed that
+ *     the file pointer (table->fp) is already opened for writing. The
+ *     variable count, set to the values in row, must be greater than 0,
+ *     otherwise, if count is -1 the vpf_write functions will lock up
+ *     (row[].count should never have a value of 0). Note that if errorfp
+ *     is used, it must be opened prior to this function.
+ *
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    row        <input> == (row_type) the row to write to the table.
+ *    table      <input> == (vpf_table_type *) vpf table structure.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Dave Flinn       July 1991      Based on read_next_row.
+ *    Barry Michaels    Oct 1991      Added row as a parameter.
+ *    JTB              10/91          guaranteed function always
+ *                                    returns a value:
+ *                                     0: record written
+ *                                    -1: unknown field type
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *   None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+long int write_next_row(row_type row, vpf_table_type * table )
+{
+   register long int i,
+		     j;
+   char            * tptr,
+		   * output ;
+   long int          recordsize = 0;
+   long int	     count;
+   id_triplet_type * keys;
+   unsigned long int pos_for_ndx,
+		     length;
+   int               retn_val = 0;
+   coordinate_type   dummycoord = {0.0,0.0};
+
+   STORAGE_BYTE_ORDER = table->byte_order;
+
+   table->nrows++;
+   fseek(table->fp, 0L, SEEK_END);
+   pos_for_ndx = ftell(table->fp); /* begining of new row */
+
+   for (i = 0; i < table->nfields; i++) {   /* for each column */
+
+     count = row[i].count ;          /* Retrieve count from row.  Should
+					be 0 if variable length null */
+
+     /* In case this column is variable length, write out count */
+
+     if (count == 0) count = 1;
+
+     if ( table->header[i].count < 0 ) {
+       Write_Vpf_Int ( &count, table->fp, 1 ) ;
+       recordsize += sizeof ( long int ) ;
+     }
+
+     /* Now write out the data type */
+
+     switch (table->header[i].type) {
+
+     case 'T':
+       if ( count == 0 ) 	/* Assume this is variable length text
+				   and don't do anything */
+	 break ;
+
+       /* This loop insures that the exact number of characters are written
+	  out to disk. */
+
+       output = (char *) vpfmalloc ( count + 1 ) ;  /* include null byte */
+       for (j = 0, tptr = (char*)row[i].ptr; j < count; j++, tptr++)
+	 if ( *tptr )
+	   output[j] = *tptr ;
+	 else
+	   output[j] = SPACE ;
+       output[count] = '\0' ;
+       Write_Vpf_Char( output ,table->fp, count) ;
+       free ( output ) ;
+       recordsize += sizeof ( char ) * count ;
+       break;
+
+     case 'I':
+       Write_Vpf_Int (row[i].ptr, table->fp, count ) ;
+       recordsize += sizeof ( long int ) * count ;
+       break;
+
+     case 'S':
+       Write_Vpf_Short (row[i].ptr, table->fp, count ) ;
+       recordsize += sizeof ( short int ) * count ;
+       break;
+
+     case 'F':
+       Write_Vpf_Float (row[i].ptr, table->fp, count ) ;
+       recordsize += sizeof ( float ) * count ;
+       break;
+
+     case 'R':
+       Write_Vpf_Double (row[i].ptr, table->fp, count ) ;
+       recordsize += sizeof ( double ) * count ;
+       break;
+
+     case 'D':	/* date has 21 chars in memory, not on disk */
+       Write_Vpf_Date (row[i].ptr, table->fp, count ) ;
+       recordsize += ( sizeof ( date_type ) - 1 ) * count ;
+       break;
+
+     case 'C':
+       if (row[i].ptr) {
+	  Write_Vpf_Coordinate(row[i].ptr,table->fp,count);
+       } else {
+	  for (j=0;j<count;j++)
+	     Write_Vpf_Coordinate(&dummycoord,table->fp,count);
+       }
+       recordsize += sizeof ( coordinate_type ) * count ;
+       break;
+
+     case 'B':
+       Write_Vpf_DoubleCoordinate(row[i].ptr,table->fp,count);
+       recordsize += sizeof ( double_coordinate_type ) * count ;
+       break;
+
+     case 'Z':
+       Write_Vpf_CoordinateZ(row[i].ptr,table->fp,count);
+       recordsize += sizeof ( tri_coordinate_type ) * count ;
+       break;
+
+     case 'Y':
+       Write_Vpf_DoubleCoordinateZ(row[i].ptr,table->fp,count);
+       recordsize += sizeof ( double_tri_coordinate_type ) * count ;
+       break;
+
+     case 'K':
+       keys = (id_triplet_type *) vpfmalloc (count*sizeof(id_triplet_type)) ;
+       memcpy ( keys, row[i].ptr, count*sizeof(id_triplet_type) ) ;
+       for (j=0;j<count;j++)
+	 recordsize += write_key ( keys[j], table->fp);
+       free ( keys ) ;
+       break;
+
+     case 'X':
+       /* do nothing */
+       break;
+
+     default:
+       return(-1);
+     }
+   }
+
+   if ( table->xfp ) {  /* only for variable length columns */
+     length = recordsize ;
+     fseek( table->xfp, 0, SEEK_END );
+
+     Write_Vpf_Int ( &pos_for_ndx, table->xfp, 1 ) ;
+     Write_Vpf_Int ( &length, table->xfp, 1 ) ;
+   }
+
+   return retn_val;
+}
+
+
+/*************************************************************************
+ *
+ *N  create_row
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     This function creates a null row for the given table.
+ *     The parameter table must be a valid table and initialized prior to
+ *     this function, by vpf_open_table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *    table      <input> == (vpf_table_type) vpf table structure.
+ *    return    <output> == (row_type) row of the table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *    Barry Michaels    Oct 1991
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   External Variables:
+ *X
+ *    None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Functions Called:
+ *F
+ *   None
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Portability:
+ *O
+ *    This module should be ANSI C compatible.
+ *E
+ *************************************************************************/
+row_type create_row( vpf_table_type table )
+{
+   long int i;
+   row_type row;
+
+   row = (row_type)vpfmalloc(table.nfields*sizeof(column_type));
+   for (i=0;i<table.nfields;i++) {
+      row[i].count = table.header[i].count;
+      row[i].ptr = NULL;
+   }
+   return row;
+}
+
+
+
+/*************************************************************************
+ *
+ *N  nullify_table_element
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Frees one field element - no action is taken if the
+ *     field index is invalid.
+ *     The parameter row must be initialized prior to this functional, either
+ *     buy being read in from an existing table or set to valid values. The
+ *     parameter table must be a valid table and initialized prior to this
+ *     function, by vpf_open_table.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     field <input>  == (long int) column offset.
+ *     row   <inout> == (row_type) row containing element to be removed.
+ *     table <inout> == (vpf_table_type) VPF table owning row.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *   RDF  7/91  original
+ *   JTB  10/91 removed call to exit();
+ *E
+ *************************************************************************/
+void nullify_table_element( long int            field,
+			    row_type       row,
+			    vpf_table_type table )
+{
+   if (field < 0 || field >= table.nfields)
+     return;
+
+   if (row[field].ptr)
+   {
+     free(row[field].ptr);
+     row[field].ptr = NULL;
+     row[field].count = table.header[field].count;
+   }
+}
+
+/*************************************************************************
+ *
+ *N  put_table_element
+ *
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Purpose:
+ *P
+ *     Copies one element into the designated field.
+ *     The parameter row must be initialized prior to this functional, either
+ *     buy being read in from an existing table or set to valid values. The
+ *     parameter table must be a valid table and initialized prior to this
+ *     function, by vpf_open_table. Note that if errorfp is used, it must
+ *     be opened prior to this function.
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   Parameters:
+ *A
+ *     field <input>  == (long int) column offset.
+ *     row   <in-out> == (row_type) row containing target field.
+ *     table <in-out> == (vpf_table_type) VPF table owning row.
+ *     value <in>     == (void *) source field element.
+ *     count <in>     == (long int) number of items in value.
+ *     put_table_element <output> == (long int)
+ *                                    0 --> element write succeeded
+ *                                    1 --> unknown element type or
+ *                                          invalid column offset
+ *E
+ *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+ *
+ *   History:
+ *H
+ *   RDF  7/91  original
+ *   JTB  10/91 removed call to exit();
+ *              guaranteed function always returns value
+ *              0: element write succeeded
+ *             -1: unknown element type or invalid column (field) offset
+ *E
+ *************************************************************************/
+long int put_table_element( long int              field,
+		       row_type         row,
+		       vpf_table_type   table,
+		       void           * value,
+		       long int         count )
+{
+   long int i, len, stat;
+   char *str;
+
+   stat=0;
+
+   if ((count != table.header[field].count) &&
+       (table.header[field].count > 0)) {
+      printf("Invalid element count! (%ld, %ld)\n",
+	     count,table.header[field].count);
+      return -1;
+   }
+
+   if (field < 0 || field >= table.nfields)
+     return -1;
+
+   row[field].count = count;
+
+   if (row[field].ptr) {
+      free(row[field].ptr);
+      row[field].ptr = NULL;
+   }
+
+   switch ( table.header[field].type ) {
+      case 'T':
+	len = (long int)max(count,table.header[field].count);
+	str = (char *) vpfmalloc( len + 1 );
+	row[field].ptr = (char *) vpfmalloc ( len + 1 ) ;
+	strcpy( (char*)str, (char*)value );
+	for ( i = strlen((char*)value) ; i < table.header[field].count; i++ )
+	   str[i] = SPACE ;
+	str[len] = '\0';
+	memcpy(row[field].ptr, str, len+1);
+	free(str);
+	break ;
+
+      case 'D':
+	row[field].ptr = (date_type *) vpfmalloc (count*sizeof(date_type));
+	memcpy ( row[field].ptr, value, sizeof (date_type) * count ) ;
+	break;
+
+      case 'I' :
+	row[field].ptr = (long int *) vpfmalloc (count*sizeof(long int));
+	memcpy ( row[field].ptr, value, sizeof (long int) * count ) ;
+	break;
+
+      case 'S' :
+	row[field].ptr = (short int *) vpfmalloc (count*sizeof(short int));
+	memcpy ( row[field].ptr, value, sizeof (short int) * count ) ;
+	break;
+
+      case 'F':
+	row[field].ptr = (float *) vpfmalloc (count*sizeof(float));
+	memcpy ( row[field].ptr, value, sizeof (float) * count ) ;
+	break;
+
+      case 'R':
+	row[field].ptr = (double *) vpfmalloc (count*sizeof(double));
+	memcpy ( row[field].ptr, value, sizeof (double) * count ) ;
+	break;
+
+      case 'K':
+	row[field].ptr =
+	  (id_triplet_type *) vpfmalloc ( count*sizeof(id_triplet_type ));
+	memcpy ( row[field].ptr, value, sizeof(id_triplet_type)*count ) ;
+	break;
+
+      case 'C':
+	if (value) {
+	   row[field].ptr = (coordinate_type *)
+	       malloc ( count * sizeof( coordinate_type ));
+	   if (row[field].ptr)
+	      memcpy ( row[field].ptr, value,
+		       sizeof(coordinate_type)*count ) ;
+	} else {
+	   row[field].ptr = NULL;
+	}
+	break;
+
+      case 'Z':
+	if (value) {
+	  row[field].ptr = (tri_coordinate_type *)
+	     malloc ( count * sizeof( tri_coordinate_type ));
+	  if (row[field].ptr)
+	     memcpy ( row[field].ptr, value,
+		      sizeof(tri_coordinate_type)*count ) ;
+	} else {
+	   row[field].ptr = NULL;
+	}
+	break;
+
+      case 'B':
+	if (value) {
+	   row[field].ptr = (double_coordinate_type *)
+	     malloc ( count * sizeof( double_coordinate_type ));
+	   if (row[field].ptr)
+	      memcpy ( row[field].ptr, value,
+		       sizeof(double_coordinate_type)*count ) ;
+	} else {
+	   row[field].ptr = NULL;
+	}
+	break;
+
+      case 'Y':
+	if (value) {
+	   row[field].ptr = (double_tri_coordinate_type *)
+	     malloc ( count * sizeof( double_tri_coordinate_type ));
+	   if (row[field].ptr)
+	      memcpy( row[field].ptr, value,
+		      sizeof(double_tri_coordinate_type)*count);
+	} else {
+	   row[field].ptr = NULL;
+	}
+	break;
+
+      default:
+	stat = -1;
+	break ;
+   }
+
+   return stat;
+}
+
+
+
+/* ========================================================================
+
+   Environmental Systems Research Institute (ESRI) Applications Programming
+
+       Project: 		Conversion from ARC/INFO to VPF
+       Original Coding:		Tom Wood	Fall 1990
+       Modifications:		David Flinn	January 1991
+						July 1991
+				JTB             10/91
+
+   The following functions are used when writing from a big-endian machine.
+   VPF requires little-endian words, so byte-swapping must be performed.
+
+   ======================================================================== */
+
+/* #ifdef UNIX */
+
+long int VpfWrite ( void *from, VpfDataType type, long int count, FILE *to )
+{
+  long int retval=0 , i ;
+
+  switch ( type ) {
+  case VpfChar:
+    retval = fwrite ( from, sizeof (char), count, to ) ;
+    break ;
+  case VpfShort:
+    {
+      if (MACHINE_BYTE_ORDER != STORAGE_BYTE_ORDER) {
+	short int stemp ,
+		*sptr = (short *) from ;
+	for ( i=0; i < count; i++, sptr++ ) {
+	   swap_two ( (char*)sptr, (char*)&stemp ) ;
+	   retval = fwrite ( &stemp, sizeof (short), 1, to ) ;
+	}
+      } else {
+	retval = fwrite ( from, sizeof (short), count, to ) ;
+      }
+    }
+    break ;
+  case VpfInteger:
+    {
+      if (MACHINE_BYTE_ORDER != STORAGE_BYTE_ORDER) {
+	 long int itemp,
+	   *iptr = (long int *) from ;
+	 for ( i=0; i < count; i++, iptr++ ) {
+	   swap_four ( (char*)iptr, (char*)&itemp ) ;
+	   retval = fwrite ( &itemp, sizeof (long int), 1, to ) ;
+	 }
+      } else {
+	 retval = fwrite ( from, sizeof (long int), count, to ) ;
+      }
+    }
+    break ;
+  case VpfFloat:
+    {
+      if (MACHINE_BYTE_ORDER != STORAGE_BYTE_ORDER) {
+	 float ftemp ,
+	    *fptr = (float *) from ;
+	 for ( i=0; i < count; i++, fptr++ ) {
+	   swap_four ( (char*)fptr, (char*)&ftemp ) ;
+	   retval = fwrite ( &ftemp, sizeof (float), 1, to ) ;
+	 }
+      } else {
+	 retval = fwrite ( from, sizeof (long int), count, to ) ;
+      }
+    }
+    break ;
+  case VpfDouble:
+    {
+      if (MACHINE_BYTE_ORDER != STORAGE_BYTE_ORDER) {
+	 double dtemp ,
+	     *dptr = (double *) from ;
+	 for ( i=0; i < count; i++, dptr++ ) {
+	   swap_eight ( (char*)dptr, (char*)&dtemp ) ;
+	   retval = fwrite ( &dtemp, sizeof (double), 1, to ) ;
+	 }
+      } else {
+	 retval = fwrite ( from, sizeof (double), count, to ) ;
+      }
+    }
+    break ;
+  case VpfDate:	/* only write out 20, not 21 chars */
+    retval = fwrite ( from, sizeof ( date_type ) - 1, count, to ) ;
+    break ;
+  case VpfCoordinate:
+    {
+      if (MACHINE_BYTE_ORDER != STORAGE_BYTE_ORDER) {
+	 coordinate_type ctemp ,
+		      *cptr = (coordinate_type *) from ;
+	 for ( i=0; i < count; i++, cptr++ ) {
+	   swap_four ( (char*)&cptr->x, (char*)&ctemp.x ) ;
+	   swap_four ( (char*)&cptr->y, (char*)&ctemp.y ) ;
+	   retval = fwrite ( &ctemp, sizeof (coordinate_type), 1, to ) ;
+	 }
+      } else {
+	 retval = fwrite ( from, sizeof (coordinate_type), count, to ) ;
+      }
+    }
+    break ;
+  case VpfDoubleCoordinate:
+    {
+      if (MACHINE_BYTE_ORDER != STORAGE_BYTE_ORDER) {
+	 double_coordinate_type dctemp ,
+			     *dcptr = (double_coordinate_type *) from ;
+	 for ( i=0; i < count; i++, dcptr++ ) {
+	   swap_eight ( (char*)&dcptr->x, (char*)&dctemp.x ) ;
+	   swap_eight ( (char*)&dcptr->y, (char*)&dctemp.y ) ;
+	   retval = fwrite ( &dctemp, sizeof (double_coordinate_type),
+	                     1, to ) ;
+	 }
+      } else {
+	 retval = fwrite ( from, sizeof (double_coordinate_type),
+			   count, to ) ;
+      }
+    }
+    break ;
+  case VpfTriCoordinate:
+    {
+      if (MACHINE_BYTE_ORDER != STORAGE_BYTE_ORDER) {
+	tri_coordinate_type ttemp ,
+			  *tptr = (tri_coordinate_type *) from ;
+	for ( i=0; i < count; i++, tptr++ ) {
+	   swap_four ( (char*)&tptr->x, (char*)&ttemp.x ) ;
+	   swap_four ( (char*)&tptr->y, (char*)&ttemp.y ) ;
+	   swap_four ( (char*)&tptr->z, (char*)&ttemp.z ) ;
+	   retval = fwrite ( &ttemp, sizeof (tri_coordinate_type), 1, to ) ;
+	}
+      } else {
+	retval = fwrite ( from, sizeof (tri_coordinate_type), count, to ) ;
+      }
+    }
+    break ;
+  case VpfDoubleTriCoordinate:
+    {
+      if (MACHINE_BYTE_ORDER != STORAGE_BYTE_ORDER) {
+	double_tri_coordinate_type dttemp ,
+		    *dtptr = (double_tri_coordinate_type *) from ;
+	for ( i=0; i < count; i++, dtptr++ ) {
+	   swap_eight ( (char*)&dtptr->x, (char*)&dttemp.x ) ;
+	   swap_eight ( (char*)&dtptr->y, (char*)&dttemp.y ) ;
+	   swap_eight ( (char*)&dtptr->z, (char*)&dttemp.z ) ;
+	   retval = fwrite ( &dttemp,sizeof (double_tri_coordinate_type),
+			     1, to);
+	}
+      } else {
+	retval = fwrite ( from,sizeof (double_tri_coordinate_type),
+			  count, to);
+      }
+    }
+    break ;
+  case VpfNull:
+    /* Do Nothing */
+    break ;
+  default:
+    break ;
+  }
+
+  return retval;
+}
+
+/* #endif */
diff --git a/Utilities/OSSIM/ossim_core/vpf_util/xmemory.h b/Utilities/OSSIM/ossim_core/vpf_util/xmemory.h
new file mode 100644
index 0000000000..1a3eb69b3b
--- /dev/null
+++ b/Utilities/OSSIM/ossim_core/vpf_util/xmemory.h
@@ -0,0 +1,37 @@
+
+/* XMEMORY.H */
+
+#ifndef XMEMORY_DEFINED
+
+#define XMEMORY_DEFINED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ossimConfig.h>
+
+#if __OSSIM_DOS__
+#include <alloc.h>
+#else
+#if __OSSIM_CARBON__
+#include <sys/types.h>
+#include <sys/malloc.h>
+#else
+/*  #include <malloc.h> */
+#endif
+#endif
+
+
+#define Xmark()
+#define Xclear()
+
+#define Xmalloc(size) malloc(size)
+#define Xcalloc(nelem, elsize) calloc(nelem, elsize)
+#define Xfree(pointer) free(pointer)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/otbIncludeDirectories.cmake b/otbIncludeDirectories.cmake
index e152bb3a6f..b7d1bd6e5f 100644
--- a/otbIncludeDirectories.cmake
+++ b/otbIncludeDirectories.cmake
@@ -23,6 +23,8 @@ SET(OTB_INCLUDE_DIRS_BUILD_TREE ${OTB_INCLUDE_DIRS_BUILD_TREE}
   ${OTB_SOURCE_DIR}/Utilities/BGL
   ${OTB_SOURCE_DIR}/Utilities/BGL/boost
   ${OTB_SOURCE_DIR}/Utilities/otbsvm
+  ${OTB_SOURCE_DIR}/Utilities/OSSIM
+  ${OTB_SOURCE_DIR}/Utilities/OSSIM/ossim_core
 )
 
 #-----------------------------------------------------------------------------
-- 
GitLab